ブログの記事数もそれなりになり、過去書いた記事を修正して再投稿することも多くなりました。
ブログの記事は Markdown 形式で記載していて、文書校正ツールとして RedPen を使用しているのですが、投稿のたびに真面目に修正しているわけではなく、面倒になってそのまま投稿することもよくあります。
また、途中導入しているため導入以前の記事は大量の警告が出力されており、記事の品質にムラがあります。
記事の品質のムラは、RedPen の警告数 / 文字数 = 警告率
で可視化できるかなと思いましたので、実際に試してみました。
実施したことを記載します。
実施する目的
ブログ記事 の 品質のムラを可視化する 目的を記載します。
- 警告率 の高い文書の修正を実施することで、サイト全体の文書品質を効率良く上げたい。
- サイト全体の文書品質が上がれば、Google の評価も上がる (と思う)。
- Google の評価が上がれば、PageView が増えて広告収入が増える。
過去文書を活かして効率良く収入を得たいという思いは多少あり、そのあたりの足しになるかなと考えております。
実施したこと
以下、説明を記載します。
-
- 前提情報と RedPen の設定について
- Markdown ファイル のファイルリストを作成する
- ファイルリストをもとに、RedPen コマンドを実行し、json 形式で出力する
- json 形式のファイルを csv ファイルにする
- csv ファイル を Google Spread Sheet に インポートする
-
- Markdown ファイルの文書統計量を Python スクリプトで収集、csv 出力する
- csv を Google Spread Sheet に インポートする
-
警告率
の計算- データ可視化
RedPen の警告情報の収集
前提情報と RedPen の設定について
-
OS の Version
% sw_vers ProductName: Mac OS X ProductVersion: 10.13.6 BuildVersion: 17G65
-
RedPen の Vesion
% redpen -v 1.10.1
-
出力形式の設定
RedPen をコマンドラインで実行する場合、出力形式 を 以下から選択ができます。
Google Spread Sheet にデータを インポートしたかったので、json
で出力しています。
値 | 解説 |
---|---|
plain | 平文 |
plain2 | 平文(文ごとのエラーを出力) |
xml | xml フォーマット |
json | json フォーマット |
json2 | json フォーマット(文ごとのエラーを出力) |
- 設定ファイル
以下 Gist にアップロードした 設定ファイルを使用しています。特に変わった設定はしていないです。
RedPen の設定ファイル
Markdown ファイル のファイルリストを作成する
私の環境では Markdown ファイルを 特定のディレクトリ 配下に置いております。
ディレクトリ構成の抜粋を以下に記載します。
.
├── jupyter // jupyter notebook の格納先ディレクトリ
├── blogs // blog に投稿した Markdwon ファイルの格納先ディレクトリ
├── gists // gists に投稿した ファイルの格納先ディレクトリ
├── redpen_configration // RedPen の辞書ファイルの格納先ディレクトリ
├── check_results // 集計ファイルの格納先ディレクトリ
├── redpen-conf-ja.xml // RedPen の設定ファイル
├── redpen_json_to_csv.py // json を csv に変換するスクリプト
├── calc_markdown_statistics.py // markdown の文書統計情報を計算するスクリプト
スクリプトは、Markdown ファイルの格納先パスを記載したテキストファイルをインプットに動作するように作成しているので、まずこのファイルを以下のコマンドで作成します。
find . -name "*.md" > markdown_list.txt
more markdown_list.txt
------------------------------
./blogs/2015/201512/wicketとdropwizardを連携する.md
./blogs/2015/201512/EclipseLinkのDDLにsemicolonを付与する.md
./blogs/2015/201512/Apache Wicket 6でRestAPIを使う.md
./blogs/2015/201512/djangoのsettings.py内で、LogHandler StreamHandlerのログ出力先を指定する.md
./blogs/2015/201512/Mezzanine HTML に Google Adsense の広告を組み込む.md
./blogs/2015/201512/java.lang.IllegalArgumentException- Invalid BSON field name java.runtime.name.md
./blogs/2015/201512/java URL文字列からクエリストリングを取得.md
./blogs/2015/201512/EclipseLink at org.eclipse.persistence.exceptions.QueryException.incorrectClassForObjectComparison(QueryException.java-601).md
./blogs/2015/201512/dropwizard Application<Configuration>の型指定を忘れる.md
./blogs/2015/201512/Java Batch Framework EasyBatch について.md
./blogs/2015/201512/morphia CompoundでUniqueなIndexを作成する.md
./blogs/2015/201512/Wicket A child with id 'xxx' already exists エラーについて.md
./blogs/2015/201512/wicketでページ内遷移を実装する.md
./blogs/2015/201512/PyGraphvizをOS X (Yosemite)のvirtualenv環境にインストールする.md
./blogs/2015/201512/wicket bodyタグのcssを切り替える.md
------------------------------
ファイルパス記載は、絶対パスであっても問題ありません。
ファイルリストをもとに、RedPen コマンドを実行し、json 形式で出力する
ファイルリストを読み込み、対象の Markdwon に RedPen のチェックを実行するスクリプトです。
- exec_check_redpen.sh
#!/bin/sh MARKDOWN_LIST="markdown_list.txt" CHECK_RESULT="./check_results/redpen_results.json" # 前回記録を削除 rm -f $CHECK_RESULT cat $MARKDOWN_LIST | while read line do redpen -t info -c redpen-conf-ja.xml -f markdown "$line" --r json >> $CHECK_RESULT done
ファイルリストの作成後に、以下のように、スクリプトを実行します。
sh exec_check_redpen.sh
スクリプトを実行すると、以下のような形式のファイルが出力されます。
1行単位では正しい形式の JSON です。後述する Python スクリプトでファイルを1行ごとに読み取って csv ファイルにします。
[{"document":"wicketとdropwizardを連携する.md","errors":[{"sentence":"wicket guice glassfish の組み合わせでアプリ構築をしていたのですが、 glassfishだとデプロイが遅い(ような気がした)ため、 組み込みTomcatで動かしたくなり、Spring BootがDropwizardか迷ったあげく、 wicket guice dropwizard の組み合わせで動くようにしてみました。","level":"Error","validator":"SentenceLength","lineNum":5,"sentenceStartColumnNum":0,"message":"The length of the sentence (173) exceeds the maximum of 150."},{"sentence":"wicket guice glassfish の組み合わせでアプリ構築をしていたのですが、 glassfishだとデプロイが遅い(ような気がした)ため、 組み込みTomcatで動かしたくなり、Spring BootがDropwizardか迷ったあげく、 wicket guice dropwizard の組み合わせで動くようにしてみました。","level":"Error","validator":"CommaNumber","lineNum":5,"sentenceStartColumnNum":0,"message":"The number of commas (4) exceeds the maximum of 3."},{"sentence":"wicket guice glassfish の組み合わせでアプリ構築をしていたのですが、 glassfishだとデプロイが遅い(ような気がした)ため、 組み込みTomcatで動かしたくなり、Spring BootがDropwizardか迷ったあげく、 wicket guice dropwizard の組み合わせで動くようにしてみました。","level":"Warn","endPosition":{"offset":10,"lineNum":6},"validator":"SpaceBetweenAlphabeticalWord","lineNum":5,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":9,"lineNum":6}},{"sentence":"wicket guice glassfish の組み合わせでアプリ構築をしていたのですが、 glassfishだとデプロイが遅い(ような気がした)ため、 組み込みTomcatで動かしたくなり、Spring BootがDropwizardか迷ったあげく、 wicket guice dropwizard の組み合わせで動くようにしてみました。","level":"Warn","endPosition":{"offset":5,"lineNum":7},"validator":"SpaceBetweenAlphabeticalWord","lineNum":5,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":4,"lineNum":7}},{"sentence":"wicket guice glassfish の組み合わせでアプリ構築をしていたのですが、 glassfishだとデプロイが遅い(ような気がした)ため、 組み込みTomcatで動かしたくなり、Spring BootがDropwizardか迷ったあげく、 wicket guice dropwizard の組み合わせで動くようにしてみました。","level":"Warn","endPosition":{"offset":11,"lineNum":7},"validator":"SpaceBetweenAlphabeticalWord","lineNum":5,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":10,"lineNum":7}},{"sentence":"wicket guice glassfish の組み合わせでアプリ構築をしていたのですが、 glassfishだとデプロイが遅い(ような気がした)ため、 組み込みTomcatで動かしたくなり、Spring BootがDropwizardか迷ったあげく、 wicket guice dropwizard の組み合わせで動くようにしてみました。","level":"Warn","endPosition":{"offset":31,"lineNum":7},"validator":"SpaceBetweenAlphabeticalWord","lineNum":5,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":30,"lineNum":7}},{"sentence":"wicket guice glassfish の組み合わせでアプリ構築をしていたのですが、 glassfishだとデプロイが遅い(ような気がした)ため、 組み込みTomcatで動かしたくなり、Spring BootがDropwizardか迷ったあげく、 wicket guice dropwizard の組み合わせで動くようにしてみました。","level":"Warn","endPosition":{"offset":32,"lineNum":7},"validator":"SpaceBetweenAlphabeticalWord","lineNum":5,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":31,"lineNum":7}},{"sentence":"wicket guice glassfish の組み合わせでアプリ構築をしていたのですが、 glassfishだとデプロイが遅い(ような気がした)ため、 組み込みTomcatで動かしたくなり、Spring BootがDropwizardか迷ったあげく、 wicket guice dropwizard の組み合わせで動くようにしてみました。","level":"Warn","endPosition":{"offset":42,"lineNum":7},"validator":"SpaceBetweenAlphabeticalWord","lineNum":5,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":41,"lineNum":7}},{"sentence":"作成したコード一式は、Githubに置きました。","level":"Warn","endPosition":{"offset":18,"lineNum":10},"validator":"SpaceBetweenAlphabeticalWord","lineNum":10,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":17,"lineNum":10}},{"sentence":"wicketとdropwizard,guiceを連携する","level":"Warn","endPosition":{"offset":9,"lineNum":3},"validator":"SpaceBetweenAlphabeticalWord","lineNum":3,"sentenceStartColumnNum":2,"message":"Space not present after an alphabetical word.","startPosition":{"offset":8,"lineNum":3}},{"sentence":"wicketとdropwizard,guiceを連携する","level":"Warn","endPosition":{"offset":10,"lineNum":3},"validator":"SpaceBetweenAlphabeticalWord","lineNum":3,"sentenceStartColumnNum":2,"message":"Space not present before an alphabetical word.","startPosition":{"offset":9,"lineNum":3}},{"sentence":"wicketとdropwizard,guiceを連携する","level":"Warn","endPosition":{"offset":26,"lineNum":3},"validator":"SpaceBetweenAlphabeticalWord","lineNum":3,"sentenceStartColumnNum":2,"message":"Space not present after an alphabetical word.","startPosition":{"offset":25,"lineNum":3}},{"sentence":"wicketとdropwizard,guiceを連携する","level":"Error","endPosition":{"offset":20,"lineNum":3},"validator":"InvalidSymbol","lineNum":3,"sentenceStartColumnNum":2,"message":"Found invalid symbol \",\".","startPosition":{"offset":19,"lineNum":3}},{"sentence":"wicketとdropwizard,guiceを連携する","level":"Error","endPosition":{"offset":20,"lineNum":3},"validator":"InvalidSymbol","lineNum":3,"sentenceStartColumnNum":2,"message":"Found invalid symbol \",\".","startPosition":{"offset":19,"lineNum":3}},{"sentence":"gradleでDropwizard ","level":"Warn","endPosition":{"offset":11,"lineNum":20},"validator":"SpaceBetweenAlphabeticalWord","lineNum":20,"sentenceStartColumnNum":4,"message":"Space not present after an alphabetical word.","startPosition":{"offset":10,"lineNum":20}},{"sentence":"gradleでDropwizard ","level":"Warn","endPosition":{"offset":12,"lineNum":20},"validator":"SpaceBetweenAlphabeticalWord","lineNum":20,"sentenceStartColumnNum":4,"message":"Space not present before an alphabetical word.","startPosition":{"offset":11,"lineNum":20}},{"sentence":"Wicketのquickstartプロジェクト(Maven)をGradleに移行する ","level":"Warn","endPosition":{"offset":11,"lineNum":22},"validator":"SpaceBetweenAlphabeticalWord","lineNum":22,"sentenceStartColumnNum":4,"message":"Space not present after an alphabetical word.","startPosition":{"offset":10,"lineNum":22}},{"sentence":"Wicketのquickstartプロジェクト(Maven)をGradleに移行する ","level":"Warn","endPosition":{"offset":12,"lineNum":22},"validator":"SpaceBetweenAlphabeticalWord","lineNum":22,"sentenceStartColumnNum":4,"message":"Space not present before an alphabetical word.","startPosition":{"offset":11,"lineNum":22}},{"sentence":"Wicketのquickstartプロジェクト(Maven)をGradleに移行する ","level":"Warn","endPosition":{"offset":22,"lineNum":22},"validator":"SpaceBetweenAlphabeticalWord","lineNum":22,"sentenceStartColumnNum":4,"message":"Space not present after an alphabetical word.","startPosition":{"offset":21,"lineNum":22}},{"sentence":"Wicketのquickstartプロジェクト(Maven)をGradleに移行する ","level":"Warn","endPosition":{"offset":36,"lineNum":22},"validator":"SpaceBetweenAlphabeticalWord","lineNum":22,"sentenceStartColumnNum":4,"message":"Space not present before an alphabetical word.","startPosition":{"offset":35,"lineNum":22}},{"sentence":"Wicketのquickstartプロジェクト(Maven)をGradleに移行する ","level":"Warn","endPosition":{"offset":42,"lineNum":22},"validator":"SpaceBetweenAlphabeticalWord","lineNum":22,"sentenceStartColumnNum":4,"message":"Space not present after an alphabetical word.","startPosition":{"offset":41,"lineNum":22}},{"sentence":"3. dropwizard-wicketのFolk後に実施したこと","level":"Warn","endPosition":{"offset":76,"lineNum":30},"validator":"SpaceBetweenAlphabeticalWord","lineNum":30,"sentenceStartColumnNum":5,"message":"Space not present after an alphabetical word.","startPosition":{"offset":75,"lineNum":30}},{"sentence":"3. dropwizard-wicketのFolk後に実施したこと","level":"Warn","endPosition":{"offset":77,"lineNum":30},"validator":"SpaceBetweenAlphabeticalWord","lineNum":30,"sentenceStartColumnNum":5,"message":"Space not present before an alphabetical word.","startPosition":{"offset":76,"lineNum":30}},{"sentence":"3. dropwizard-wicketのFolk後に実施したこと","level":"Warn","endPosition":{"offset":81,"lineNum":30},"validator":"SpaceBetweenAlphabeticalWord","lineNum":30,"sentenceStartColumnNum":5,"message":"Space not present after an alphabetical word.","startPosition":{"offset":80,"lineNum":30}},{"sentence":"3.1. build.gradleの設定、編集","level":"Warn","endPosition":{"offset":23,"lineNum":32},"validator":"SpaceBetweenAlphabeticalWord","lineNum":32,"sentenceStartColumnNum":5,"message":"Space not present after an alphabetical word.","startPosition":{"offset":22,"lineNum":32}},{"sentence":"Folk元のプロジェクトがMavenプロジェクトのため、Gradleプロジェクトへ変換を行いました。","level":"Warn","endPosition":{"offset":5,"lineNum":36},"validator":"SpaceBetweenAlphabeticalWord","lineNum":36,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":4,"lineNum":36}},{"sentence":"Folk元のプロジェクトがMavenプロジェクトのため、Gradleプロジェクトへ変換を行いました。","level":"Warn","endPosition":{"offset":14,"lineNum":36},"validator":"SpaceBetweenAlphabeticalWord","lineNum":36,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":13,"lineNum":36}},{"sentence":"Folk元のプロジェクトがMavenプロジェクトのため、Gradleプロジェクトへ変換を行いました。","level":"Warn","endPosition":{"offset":19,"lineNum":36},"validator":"SpaceBetweenAlphabeticalWord","lineNum":36,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":18,"lineNum":36}},{"sentence":"Folk元のプロジェクトがMavenプロジェクトのため、Gradleプロジェクトへ変換を行いました。","level":"Warn","endPosition":{"offset":35,"lineNum":36},"validator":"SpaceBetweenAlphabeticalWord","lineNum":36,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":34,"lineNum":36}},{"sentence":"3.1.1. MavenプロジェクトをGradleプロジェクトに変換","level":"Warn","endPosition":{"offset":19,"lineNum":34},"validator":"SpaceBetweenAlphabeticalWord","lineNum":34,"sentenceStartColumnNum":6,"message":"Space not present after an alphabetical word.","startPosition":{"offset":18,"lineNum":34}},{"sentence":"3.1.1. MavenプロジェクトをGradleプロジェクトに変換","level":"Warn","endPosition":{"offset":26,"lineNum":34},"validator":"SpaceBetweenAlphabeticalWord","lineNum":34,"sentenceStartColumnNum":6,"message":"Space not present before an alphabetical word.","startPosition":{"offset":25,"lineNum":34}},{"sentence":"3.1.1. MavenプロジェクトをGradleプロジェクトに変換","level":"Warn","endPosition":{"offset":32,"lineNum":34},"validator":"SpaceBetweenAlphabeticalWord","lineNum":34,"sentenceStartColumnNum":6,"message":"Space not present after an alphabetical word.","startPosition":{"offset":31,"lineNum":34}},{"sentence":"dropwizardとwicketのversionは新しいものに変更し、 guiceと、guice-servlet,wicket-guiceを依存関係に追加しました。","level":"Warn","endPosition":{"offset":11,"lineNum":46},"validator":"SpaceBetweenAlphabeticalWord","lineNum":46,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":10,"lineNum":46}},{"sentence":"dropwizardとwicketのversionは新しいものに変更し、 guiceと、guice-servlet,wicket-guiceを依存関係に追加しました。","level":"Warn","endPosition":{"offset":12,"lineNum":46},"validator":"SpaceBetweenAlphabeticalWord","lineNum":46,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":11,"lineNum":46}},{"sentence":"dropwizardとwicketのversionは新しいものに変更し、 guiceと、guice-servlet,wicket-guiceを依存関係に追加しました。","level":"Warn","endPosition":{"offset":18,"lineNum":46},"validator":"SpaceBetweenAlphabeticalWord","lineNum":46,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":17,"lineNum":46}},{"sentence":"dropwizardとwicketのversionは新しいものに変更し、 guiceと、guice-servlet,wicket-guiceを依存関係に追加しました。","level":"Warn","endPosition":{"offset":19,"lineNum":46},"validator":"SpaceBetweenAlphabeticalWord","lineNum":46,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":18,"lineNum":46}},{"sentence":"dropwizardとwicketのversionは新しいものに変更し、 guiceと、guice-servlet,wicket-guiceを依存関係に追加しました。","level":"Warn","endPosition":{"offset":26,"lineNum":46},"validator":"SpaceBetweenAlphabeticalWord","lineNum":46,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":25,"lineNum":46}},{"sentence":"dropwizardとwicketのversionは新しいものに変更し、 guiceと、guice-servlet,wicket-guiceを依存関係に追加しました。","level":"Warn","endPosition":{"offset":6,"lineNum":47},"validator":"SpaceBetweenAlphabeticalWord","lineNum":46,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":5,"lineNum":47}},{"sentence":"dropwizardとwicketのversionは新しいものに変更し、 guiceと、guice-servlet,wicket-guiceを依存関係に追加しました。","level":"Warn","endPosition":{"offset":34,"lineNum":47},"validator":"SpaceBetweenAlphabeticalWord","lineNum":46,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":33,"lineNum":47}},{"sentence":"dropwizardとwicketのversionは新しいものに変更し、 guiceと、guice-servlet,wicket-guiceを依存関係に追加しました。","level":"Error","endPosition":{"offset":21,"lineNum":47},"validator":"InvalidSymbol","lineNum":46,"sentenceStartColumnNum":0,"message":"Found invalid symbol \",\".","startPosition":{"offset":20,"lineNum":47}},{"sentence":"dropwizardとwicketのversionは新しいものに変更し、 guiceと、guice-servlet,wicket-guiceを依存関係に追加しました。","level":"Error","endPosition":{"offset":21,"lineNum":47},"validator":"InvalidSymbol","lineNum":46,"sentenceStartColumnNum":0,"message":"Found invalid symbol \",\".","startPosition":{"offset":20,"lineNum":47}},{"sentence":"3.1.2. build.gradleのdependenciesの記述を以下の記述に変更","level":"Warn","validator":"JapaneseAmbiguousNounConjunction","lineNum":43,"sentenceStartColumnNum":6,"message":"Found ambiguous noun conjunction: \"...3のdependenciesの記述...\""},{"sentence":"3.1.2. build.gradleのdependenciesの記述を以下の記述に変更","level":"Warn","endPosition":{"offset":26,"lineNum":43},"validator":"SpaceBetweenAlphabeticalWord","lineNum":43,"sentenceStartColumnNum":6,"message":"Space not present after an alphabetical word.","startPosition":{"offset":25,"lineNum":43}},{"sentence":"3.1.2. build.gradleのdependenciesの記述を以下の記述に変更","level":"Warn","endPosition":{"offset":27,"lineNum":43},"validator":"SpaceBetweenAlphabeticalWord","lineNum":43,"sentenceStartColumnNum":6,"message":"Space not present before an alphabetical word.","startPosition":{"offset":26,"lineNum":43}},{"sentence":"3.1.2. build.gradleのdependenciesの記述を以下の記述に変更","level":"Warn","endPosition":{"offset":39,"lineNum":43},"validator":"SpaceBetweenAlphabeticalWord","lineNum":43,"sentenceStartColumnNum":6,"message":"Space not present after an alphabetical word.","startPosition":{"offset":38,"lineNum":43}},{"sentence":"pluginの記述","level":"Warn","endPosition":{"offset":7,"lineNum":62},"validator":"SpaceBetweenAlphabeticalWord","lineNum":62,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":6,"lineNum":62}},{"sentence":"shadowJarタスクの記述 ","level":"Warn","endPosition":{"offset":10,"lineNum":70},"validator":"SpaceBetweenAlphabeticalWord","lineNum":70,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":9,"lineNum":70}},{"sentence":"3.1.3. plugin記述にshadowを追加して、shadowjarタスクを使用可能にする。","level":"Warn","endPosition":{"offset":20,"lineNum":60},"validator":"SpaceBetweenAlphabeticalWord","lineNum":60,"sentenceStartColumnNum":6,"message":"Space not present after an alphabetical word.","startPosition":{"offset":19,"lineNum":60}},{"sentence":"3.1.3. plugin記述にshadowを追加して、shadowjarタスクを使用可能にする。","level":"Warn","endPosition":{"offset":23,"lineNum":60},"validator":"SpaceBetweenAlphabeticalWord","lineNum":60,"sentenceStartColumnNum":6,"message":"Space not present before an alphabetical word.","startPosition":{"offset":22,"lineNum":60}},{"sentence":"3.1.3. plugin記述にshadowを追加して、shadowjarタスクを使用可能にする。","level":"Warn","endPosition":{"offset":29,"lineNum":60},"validator":"SpaceBetweenAlphabeticalWord","lineNum":60,"sentenceStartColumnNum":6,"message":"Space not present after an alphabetical word.","startPosition":{"offset":28,"lineNum":60}},{"sentence":"3.1.3. plugin記述にshadowを追加して、shadowjarタスクを使用可能にする。","level":"Warn","endPosition":{"offset":44,"lineNum":60},"validator":"SpaceBetweenAlphabeticalWord","lineNum":60,"sentenceStartColumnNum":6,"message":"Space not present after an alphabetical word.","startPosition":{"offset":43,"lineNum":60}},{"sentence":"3.2. Folk元のプログラムの変更点","level":"Warn","endPosition":{"offset":15,"lineNum":83},"validator":"SpaceBetweenAlphabeticalWord","lineNum":83,"sentenceStartColumnNum":5,"message":"Space not present after an alphabetical word.","startPosition":{"offset":14,"lineNum":83}},{"sentence":"Folk元のクラスは、Guiceを使用しない実装だったので、 WicketBundle.javaの以下の点を修正しました。","level":"Warn","endPosition":{"offset":27,"lineNum":86},"validator":"JapaneseStyle","lineNum":86,"sentenceStartColumnNum":0,"message":"Found invalid Japanese Style \"だった\"","startPosition":{"offset":24,"lineNum":86}},{"sentence":"Folk元のクラスは、Guiceを使用しない実装だったので、 WicketBundle.javaの以下の点を修正しました。","level":"Warn","validator":"JapaneseAmbiguousNounConjunction","lineNum":86,"sentenceStartColumnNum":0,"message":"Found ambiguous noun conjunction: \"...Guiceの以下の点...\""},{"sentence":"Folk元のクラスは、Guiceを使用しない実装だったので、 WicketBundle.javaの以下の点を修正しました。","level":"Warn","endPosition":{"offset":5,"lineNum":86},"validator":"SpaceBetweenAlphabeticalWord","lineNum":86,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":4,"lineNum":86}},{"sentence":"Folk元のクラスは、Guiceを使用しない実装だったので、 WicketBundle.javaの以下の点を修正しました。","level":"Warn","endPosition":{"offset":17,"lineNum":86},"validator":"SpaceBetweenAlphabeticalWord","lineNum":86,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":16,"lineNum":86}},{"sentence":"Folk元のクラスは、Guiceを使用しない実装だったので、 WicketBundle.javaの以下の点を修正しました。","level":"Warn","endPosition":{"offset":18,"lineNum":87},"validator":"SpaceBetweenAlphabeticalWord","lineNum":86,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":17,"lineNum":87}},{"sentence":"SessionHandlerは設定しないと、","level":"Warn","endPosition":{"offset":15,"lineNum":94},"validator":"SpaceBetweenAlphabeticalWord","lineNum":94,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":14,"lineNum":94}},{"sentence":"3.2.1. WicketBundleの記述を変更","level":"Warn","endPosition":{"offset":26,"lineNum":85},"validator":"SpaceBetweenAlphabeticalWord","lineNum":85,"sentenceStartColumnNum":6,"message":"Space not present after an alphabetical word.","startPosition":{"offset":25,"lineNum":85}},{"sentence":"FilterHolderに設定するFilterクラスをGuiceFilterに変更。","level":"Warn","endPosition":{"offset":16,"lineNum":89},"validator":"SpaceBetweenAlphabeticalWord","lineNum":89,"sentenceStartColumnNum":3,"message":"Space not present after an alphabetical word.","startPosition":{"offset":15,"lineNum":89}},{"sentence":"FilterHolderに設定するFilterクラスをGuiceFilterに変更。","level":"Warn","endPosition":{"offset":21,"lineNum":89},"validator":"SpaceBetweenAlphabeticalWord","lineNum":89,"sentenceStartColumnNum":3,"message":"Space not present before an alphabetical word.","startPosition":{"offset":20,"lineNum":89}},{"sentence":"FilterHolderに設定するFilterクラスをGuiceFilterに変更。","level":"Warn","endPosition":{"offset":27,"lineNum":89},"validator":"SpaceBetweenAlphabeticalWord","lineNum":89,"sentenceStartColumnNum":3,"message":"Space not present after an alphabetical word.","startPosition":{"offset":26,"lineNum":89}},{"sentence":"FilterHolderに設定するFilterクラスをGuiceFilterに変更。","level":"Warn","endPosition":{"offset":31,"lineNum":89},"validator":"SpaceBetweenAlphabeticalWord","lineNum":89,"sentenceStartColumnNum":3,"message":"Space not present before an alphabetical word.","startPosition":{"offset":30,"lineNum":89}},{"sentence":"FilterHolderに設定するFilterクラスをGuiceFilterに変更。","level":"Warn","endPosition":{"offset":42,"lineNum":89},"validator":"SpaceBetweenAlphabeticalWord","lineNum":89,"sentenceStartColumnNum":3,"message":"Space not present after an alphabetical word.","startPosition":{"offset":41,"lineNum":89}},{"sentence":"contextにGuiceServletConfigの設定する処理を追加。","level":"Warn","endPosition":{"offset":11,"lineNum":90},"validator":"SpaceBetweenAlphabeticalWord","lineNum":90,"sentenceStartColumnNum":3,"message":"Space not present after an alphabetical word.","startPosition":{"offset":10,"lineNum":90}},{"sentence":"contextにGuiceServletConfigの設定する処理を追加。","level":"Warn","endPosition":{"offset":12,"lineNum":90},"validator":"SpaceBetweenAlphabeticalWord","lineNum":90,"sentenceStartColumnNum":3,"message":"Space not present before an alphabetical word.","startPosition":{"offset":11,"lineNum":90}},{"sentence":"contextにGuiceServletConfigの設定する処理を追加。","level":"Warn","endPosition":{"offset":30,"lineNum":90},"validator":"SpaceBetweenAlphabeticalWord","lineNum":90,"sentenceStartColumnNum":3,"message":"Space not present after an alphabetical word.","startPosition":{"offset":29,"lineNum":90}},{"sentence":"SessionHandlerの設定処理を追加。","level":"Warn","endPosition":{"offset":18,"lineNum":91},"validator":"SpaceBetweenAlphabeticalWord","lineNum":91,"sentenceStartColumnNum":3,"message":"Space not present after an alphabetical word.","startPosition":{"offset":17,"lineNum":91}},{"sentence":"3.2.2. SampleApplicationの追加","level":"Warn","endPosition":{"offset":31,"lineNum":103},"validator":"SpaceBetweenAlphabeticalWord","lineNum":103,"sentenceStartColumnNum":6,"message":"Space not present after an alphabetical word.","startPosition":{"offset":30,"lineNum":103}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Error","validator":"SentenceLength","lineNum":110,"sentenceStartColumnNum":29,"message":"The length of the sentence (157) exceeds the maximum of 150."},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Error","validator":"CommaNumber","lineNum":110,"sentenceStartColumnNum":29,"message":"The number of commas (6) exceeds the maximum of 3."},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","validator":"DoubledConjunctiveParticleGa","lineNum":110,"sentenceStartColumnNum":29,"message":"Found multiple conjunctive particle: \"が\""},{"sentence":"-----------------------------------------------------GuiceFilter経由で、WicketFilterの設定?","level":"Warn","endPosition":{"offset":12,"lineNum":109},"validator":"SpaceBetweenAlphabeticalWord","lineNum":108,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":11,"lineNum":109}},{"sentence":"-----------------------------------------------------GuiceFilter経由で、WicketFilterの設定?","level":"Warn","endPosition":{"offset":28,"lineNum":109},"validator":"SpaceBetweenAlphabeticalWord","lineNum":108,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":27,"lineNum":109}},{"sentence":"とInjectorの取得しているのが、 結構面倒くさく、意味がぱっと見でわかりにくい気がしました。","level":"Warn","endPosition":{"offset":33,"lineNum":109},"validator":"SpaceBetweenAlphabeticalWord","lineNum":109,"sentenceStartColumnNum":31,"message":"Space not present before an alphabetical word.","startPosition":{"offset":32,"lineNum":109}},{"sentence":"とInjectorの取得しているのが、 結構面倒くさく、意味がぱっと見でわかりにくい気がしました。","level":"Warn","endPosition":{"offset":41,"lineNum":109},"validator":"SpaceBetweenAlphabeticalWord","lineNum":109,"sentenceStartColumnNum":31,"message":"Space not present after an alphabetical word.","startPosition":{"offset":40,"lineNum":109}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","endPosition":{"offset":5,"lineNum":111},"validator":"SpaceBetweenAlphabeticalWord","lineNum":110,"sentenceStartColumnNum":29,"message":"Space not present after an alphabetical word.","startPosition":{"offset":4,"lineNum":111}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","endPosition":{"offset":21,"lineNum":111},"validator":"SpaceBetweenAlphabeticalWord","lineNum":110,"sentenceStartColumnNum":29,"message":"Space not present after an alphabetical word.","startPosition":{"offset":20,"lineNum":111}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","endPosition":{"offset":22,"lineNum":111},"validator":"SpaceBetweenAlphabeticalWord","lineNum":110,"sentenceStartColumnNum":29,"message":"Space not present before an alphabetical word.","startPosition":{"offset":21,"lineNum":111}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","endPosition":{"offset":28,"lineNum":111},"validator":"SpaceBetweenAlphabeticalWord","lineNum":110,"sentenceStartColumnNum":29,"message":"Space not present after an alphabetical word.","startPosition":{"offset":27,"lineNum":111}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","endPosition":{"offset":29,"lineNum":111},"validator":"SpaceBetweenAlphabeticalWord","lineNum":110,"sentenceStartColumnNum":29,"message":"Space not present before an alphabetical word.","startPosition":{"offset":28,"lineNum":111}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","endPosition":{"offset":40,"lineNum":111},"validator":"SpaceBetweenAlphabeticalWord","lineNum":110,"sentenceStartColumnNum":29,"message":"Space not present after an alphabetical word.","startPosition":{"offset":39,"lineNum":111}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","endPosition":{"offset":28,"lineNum":112},"validator":"SpaceBetweenAlphabeticalWord","lineNum":110,"sentenceStartColumnNum":29,"message":"Space not present before an alphabetical word.","startPosition":{"offset":27,"lineNum":112}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","endPosition":{"offset":36,"lineNum":112},"validator":"SpaceBetweenAlphabeticalWord","lineNum":110,"sentenceStartColumnNum":29,"message":"Space not present after an alphabetical word.","startPosition":{"offset":35,"lineNum":112}},{"sentence":" Folk元だと、WicketBundleにWicketのApplicationクラスを設定して、インスタンス生成する作りになっていましたが、そのへんをInjector経由での生成にすると、 GuiceFilter使わなくても、やりたいことは実現できそうな気がしますが、 そこは思っただけで実現していません。","level":"Warn","endPosition":{"offset":12,"lineNum":113},"validator":"SpaceBetweenAlphabeticalWord","lineNum":110,"sentenceStartColumnNum":29,"message":"Space not present after an alphabetical word.","startPosition":{"offset":11,"lineNum":113}},{"sentence":"wicket guicecomponentinjectorはcustominjectionsを無視する","level":"Warn","endPosition":{"offset":31,"lineNum":118},"validator":"SpaceBetweenAlphabeticalWord","lineNum":118,"sentenceStartColumnNum":1,"message":"Space not present after an alphabetical word.","startPosition":{"offset":30,"lineNum":118}},{"sentence":"wicket guicecomponentinjectorはcustominjectionsを無視する","level":"Warn","endPosition":{"offset":32,"lineNum":118},"validator":"SpaceBetweenAlphabeticalWord","lineNum":118,"sentenceStartColumnNum":1,"message":"Space not present before an alphabetical word.","startPosition":{"offset":31,"lineNum":118}},{"sentence":"wicket guicecomponentinjectorはcustominjectionsを無視する","level":"Warn","endPosition":{"offset":48,"lineNum":118},"validator":"SpaceBetweenAlphabeticalWord","lineNum":118,"sentenceStartColumnNum":1,"message":"Space not present after an alphabetical word.","startPosition":{"offset":47,"lineNum":118}}]}]
[{"document":"EclipseLinkのDDLにsemicolonを付与する.md","errors":[{"sentence":"","level":"Error","validator":"DuplicatedSection","lineNum":0,"sentenceStartColumnNum":0,"message":"Found duplicated section (starts from line 8)."},{"sentence":"notebook: 03.blog","level":"Error","validator":"VoidSection","lineNum":4,"sentenceStartColumnNum":0,"message":"The section is void."},{"sentence":"記事情報","level":"Error","validator":"DuplicatedSection","lineNum":8,"sentenceStartColumnNum":2,"message":"Found duplicated section (starts from line 0)."},{"sentence":"status:pubic","level":"Error","validator":"VoidSection","lineNum":12,"sentenceStartColumnNum":0,"message":"The section is void."},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":19,"lineNum":2},"validator":"SpaceBetweenAlphabeticalWord","lineNum":1,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":18,"lineNum":2}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":20,"lineNum":2},"validator":"SpaceBetweenAlphabeticalWord","lineNum":1,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":19,"lineNum":2}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":23,"lineNum":2},"validator":"SpaceBetweenAlphabeticalWord","lineNum":1,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":22,"lineNum":2}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":24,"lineNum":2},"validator":"SpaceBetweenAlphabeticalWord","lineNum":1,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":23,"lineNum":2}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":33,"lineNum":2},"validator":"SpaceBetweenAlphabeticalWord","lineNum":1,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":32,"lineNum":2}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":1,"lineNum":3},"validator":"SpaceBetweenAlphabeticalWord","lineNum":1,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":0,"lineNum":3}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":19,"lineNum":10},"validator":"SpaceBetweenAlphabeticalWord","lineNum":9,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":18,"lineNum":10}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":20,"lineNum":10},"validator":"SpaceBetweenAlphabeticalWord","lineNum":9,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":19,"lineNum":10}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":23,"lineNum":10},"validator":"SpaceBetweenAlphabeticalWord","lineNum":9,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":22,"lineNum":10}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":24,"lineNum":10},"validator":"SpaceBetweenAlphabeticalWord","lineNum":9,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":23,"lineNum":10}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":33,"lineNum":10},"validator":"SpaceBetweenAlphabeticalWord","lineNum":9,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":32,"lineNum":10}},{"sentence":"---title: EclipseLinkのDDLにsemicolonを付与するtags: []","level":"Warn","endPosition":{"offset":1,"lineNum":11},"validator":"SpaceBetweenAlphabeticalWord","lineNum":9,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":0,"lineNum":11}},{"sentence":"EclipseLinkでEntityクラスから、DDLを生成したところ、DDLの行末に;(セミコロン)が付与されないので、どうしたら付与されるか調べました。","level":"Warn","endPosition":{"offset":12,"lineNum":18},"validator":"SpaceBetweenAlphabeticalWord","lineNum":18,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":11,"lineNum":18}},{"sentence":"EclipseLinkでEntityクラスから、DDLを生成したところ、DDLの行末に;(セミコロン)が付与されないので、どうしたら付与されるか調べました。","level":"Warn","endPosition":{"offset":13,"lineNum":18},"validator":"SpaceBetweenAlphabeticalWord","lineNum":18,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":12,"lineNum":18}},{"sentence":"EclipseLinkでEntityクラスから、DDLを生成したところ、DDLの行末に;(セミコロン)が付与されないので、どうしたら付与されるか調べました。","level":"Warn","endPosition":{"offset":19,"lineNum":18},"validator":"SpaceBetweenAlphabeticalWord","lineNum":18,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":18,"lineNum":18}},{"sentence":"EclipseLinkでEntityクラスから、DDLを生成したところ、DDLの行末に;(セミコロン)が付与されないので、どうしたら付与されるか調べました。","level":"Warn","endPosition":{"offset":28,"lineNum":18},"validator":"SpaceBetweenAlphabeticalWord","lineNum":18,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":27,"lineNum":18}},{"sentence":"EclipseLinkでEntityクラスから、DDLを生成したところ、DDLの行末に;(セミコロン)が付与されないので、どうしたら付与されるか調べました。","level":"Warn","endPosition":{"offset":40,"lineNum":18},"validator":"SpaceBetweenAlphabeticalWord","lineNum":18,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":39,"lineNum":18}},{"sentence":"-----------------------------META-INF/persistence.xmlに、","level":"Warn","endPosition":{"offset":25,"lineNum":22},"validator":"SpaceBetweenAlphabeticalWord","lineNum":21,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":24,"lineNum":22}},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Error","validator":"SentenceLength","lineNum":32,"sentenceStartColumnNum":0,"message":"The length of the sentence (224) exceeds the maximum of 150."},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Error","validator":"CommaNumber","lineNum":32,"sentenceStartColumnNum":0,"message":"The number of commas (6) exceeds the maximum of 3."},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Warn","validator":"JapaneseAmbiguousNounConjunction","lineNum":32,"sentenceStartColumnNum":0,"message":"Found ambiguous noun conjunction: \"...記事のクラスのサブクラス...\""},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Warn","validator":"JapaneseAmbiguousNounConjunction","lineNum":32,"sentenceStartColumnNum":0,"message":"Found ambiguous noun conjunction: \"...記事のクラスのサブクラスpersistenceのバグのため...\""},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Warn","endPosition":{"offset":31,"lineNum":33},"validator":"SpaceBetweenAlphabeticalWord","lineNum":32,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":30,"lineNum":33}},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Warn","endPosition":{"offset":151,"lineNum":33},"validator":"SpaceBetweenAlphabeticalWord","lineNum":32,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":150,"lineNum":33}},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Warn","endPosition":{"offset":192,"lineNum":33},"validator":"SpaceBetweenAlphabeticalWord","lineNum":32,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":191,"lineNum":33}},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Warn","endPosition":{"offset":224,"lineNum":33},"validator":"SpaceBetweenAlphabeticalWord","lineNum":32,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":223,"lineNum":33}},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Warn","endPosition":{"offset":225,"lineNum":33},"validator":"SpaceBetweenAlphabeticalWord","lineNum":32,"sentenceStartColumnNum":0,"message":"Space not present before an alphabetical word.","startPosition":{"offset":224,"lineNum":33}},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Warn","endPosition":{"offset":252,"lineNum":33},"validator":"SpaceBetweenAlphabeticalWord","lineNum":32,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":251,"lineNum":33}},{"sentence":"-----------------------------最初、付与する方法を調べていて、stackoverflowのこの記事を見つけ、 「org.eclipse.persistence.platform.database配下のクラスのサブクラスを作って、persistence.xmlにeclipselink.target-databaseを追加して読み込ませれば、付与できる」かと思ったのですが、おそらく eclipselinkのバグのため?","level":"Warn","endPosition":{"offset":13,"lineNum":34},"validator":"SpaceBetweenAlphabeticalWord","lineNum":32,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":12,"lineNum":34}},{"sentence":"、サブクラスを作ったところで付与できず、あきらめてEclipseLinkをversionUpしました。","level":"Warn","endPosition":{"offset":92,"lineNum":34},"validator":"SpaceBetweenAlphabeticalWord","lineNum":34,"sentenceStartColumnNum":66,"message":"Space not present before an alphabetical word.","startPosition":{"offset":91,"lineNum":34}},{"sentence":"、サブクラスを作ったところで付与できず、あきらめてEclipseLinkをversionUpしました。","level":"Warn","endPosition":{"offset":103,"lineNum":34},"validator":"SpaceBetweenAlphabeticalWord","lineNum":34,"sentenceStartColumnNum":66,"message":"Space not present after an alphabetical word.","startPosition":{"offset":102,"lineNum":34}},{"sentence":"、サブクラスを作ったところで付与できず、あきらめてEclipseLinkをversionUpしました。","level":"Warn","endPosition":{"offset":104,"lineNum":34},"validator":"SpaceBetweenAlphabeticalWord","lineNum":34,"sentenceStartColumnNum":66,"message":"Space not present before an alphabetical word.","startPosition":{"offset":103,"lineNum":34}},{"sentence":"、サブクラスを作ったところで付与できず、あきらめてEclipseLinkをversionUpしました。","level":"Warn","endPosition":{"offset":113,"lineNum":34},"validator":"SpaceBetweenAlphabeticalWord","lineNum":34,"sentenceStartColumnNum":66,"message":"Space not present after an alphabetical word.","startPosition":{"offset":112,"lineNum":34}},{"sentence":"-----------------------------DDL生成に使用しているコードもついでに貼り付けます。","level":"Warn","endPosition":{"offset":4,"lineNum":38},"validator":"SpaceBetweenAlphabeticalWord","lineNum":37,"sentenceStartColumnNum":0,"message":"Space not present after an alphabetical word.","startPosition":{"offset":3,"lineNum":38}},{"sentence":"Javaからddl生成を行う","level":"Warn","endPosition":{"offset":9,"lineNum":36},"validator":"SpaceBetweenAlphabeticalWord","lineNum":36,"sentenceStartColumnNum":4,"message":"Space not present after an alphabetical word.","startPosition":{"offset":8,"lineNum":36}},{"sentence":"Javaからddl生成を行う","level":"Warn","endPosition":{"offset":11,"lineNum":36},"validator":"SpaceBetweenAlphabeticalWord","lineNum":36,"sentenceStartColumnNum":4,"message":"Space not present before an alphabetical word.","startPosition":{"offset":10,"lineNum":36}},{"sentence":"Javaからddl生成を行う","level":"Warn","endPosition":{"offset":14,"lineNum":36},"validator":"SpaceBetweenAlphabeticalWord","lineNum":36,"sentenceStartColumnNum":4,"message":"Space not present after an alphabetical word.","startPosition":{"offset":13,"lineNum":36}},{"sentence":"補足 DB接続情報はMETA-INF/persistence.xmlに書きつけてあります。","level":"Warn","endPosition":{"offset":3,"lineNum":73},"validator":"SpaceBetweenAlphabeticalWord","lineNum":72,"sentenceStartColumnNum":2,"message":"Space not present after an alphabetical word.","startPosition":{"offset":2,"lineNum":73}},{"sentence":"補足 DB接続情報はMETA-INF/persistence.xmlに書きつけてあります。","level":"Warn","endPosition":{"offset":8,"lineNum":73},"validator":"SpaceBetweenAlphabeticalWord","lineNum":72,"sentenceStartColumnNum":2,"message":"Space not present before an alphabetical word.","startPosition":{"offset":7,"lineNum":73}},{"sentence":"補足 DB接続情報はMETA-INF/persistence.xmlに書きつけてあります。","level":"Warn","endPosition":{"offset":32,"lineNum":73},"validator":"SpaceBetweenAlphabeticalWord","lineNum":72,"sentenceStartColumnNum":2,"message":"Space not present after an alphabetical word.","startPosition":{"offset":31,"lineNum":73}}]}]
...
json 形式のファイルを csv ファイルにする
- redpen_json_to_csv.py
以下 Gist にアップロード に作成したスクリプトをアップロードしました。
RedPen の Json 形式の出力ファイルをCSVに変換するスクリプト
スクリプトは、以下のように実行します。
実行後は、以下のような csv ファイルが出力されます。python3.6 redpen_json_to_csv.py
redpen_results.csv
csv ファイル を Google Spread Sheet に インポートする
作成した csv ファイルを Google Spread Sheet にインポートします。
当初 json ファイルを Google Spread Sheet API で 直接登録を実施したのですが、セルの更新上限に引っかかったのか上手く更新処理が実施できず、csv でインポートするようにしました。特に触っていれば操作方法はわかりそうですが、手順記載している記事がありましたので、リンクを記載します。
Google シートで CSV ファイルを開く方法 - Loyverse
文書の統計量の収集
Markdown ファイルの文書統計量を Python スクリプトで収集、csv 出力する
Markdown ファイルの文書の統計量と呼んでいるのは、文書の文字数等の情報です。プログラムのステップカウンタで取得するような情報がとれればいいかと思い取得可能なツールを探したのですが、見つからず、以下の指標を取得する Python スクリプトを作成しました。
- 取得する指標
- 文字数
- 句読点数
- h1の数
- h2の数
- h3の数
- h4の数
- h5の数
- h6の数
- tableの数
- liの数
- dtの数
- imgの数
- aの数
スクリプトは 以下 Gist に アップロードしました。
Markdown を HTML 変換するために、markdown
と 変換した HTML を解析するために、BeautifulSoup4
を使っています。
使用する場合は、それらをインストールしてください。
Markdown 文書の統計量を計算するスクリプト
以下のコマンドで実行可能です。
python3.6 calc_markdown_statistics.py
実行後には 以下のような csv ファイルが出力されます。
markdown_stats.csv
csv を Google Spread Sheet に インポートする
上記で作成した csv を Google Spread Sheet に インポートします。
収集結果の可視化
作成した 2つの csv ファイルを使って、Google Data Studio で可視化します。
警告率
の計算
-
QUERY 関数で集計
新規でシートを作り、redpen_results.csv
を スプレッドシート 上で、以下の、QUERY 関数で集計します。
A列 は、ファイル名で、H列は、sentenceStartColumnNum
です。
=QUERY(report!A1:K16438,"select A, count(H) group by A order by A",true)
-
**VLOOKUPで、文字数を取得。警告数を、文字数で割って、100をかける **
markdown_stats.csv
から VLOOKUP で行数を取得します。
警告数を、文字数で割って、100をかけると、1文字あたりの警告の発生率が取得できます。 -
警告率の集計結果
警告率の集計結果は以下の通りです。
警告率の高い文書が幾つか存在して、平均値が上振れています。
統計量 | 数値 |
---|---|
合計 | 478.89 |
第三四分位 | 1.20 |
平均 | 0.99 |
中央値 | 0.71 |
第一四分位 | 0.43 |
最小値 | 0.03 |
最大値 | 8.21 |
データの数 | 487 |
データ可視化
Google Data Studio で可視化した結果を幾つか貼り付けます。
-
警告ごとの合計
SpaceBetweenAlphabeticalWord
、InvalidSymbol
、SuggestExpression
の数が多いです。
よく出る警告なのかと思われます。 -
エラーレベルごとの集計
Warn
、Error
レベルごとの集計です。文書ごとのエラー数はまちまちで、エラーが多い文書は要修正文書かと思います。 -
句読点数と警告の散布図
句読点数と警告の散布図です。句読点数が増えると、警告数は増えているようです。
句読点が多い文書を修正するのと、誤差が大きい文書は何かありそうなので、確認してみようかと思います。 -
警告率と文字数の散布図
横長で若干見づらいですが、縦軸が警告率で、横軸が文字数の散布図です。
文字数が多いからといって警告が多いわけではなさそうです。
一部、文字数の割に警告が多い文書があることがわかるので対象文書は見直したほうがいいように思いました。
実施後の感想
以下、実施後の感想になります。
-
結構手作業が入るので、もう少しツールで自動化できないか検討する。CI に組み込みたい。
-
ステップカウントと、静的解析ツールの組み合わせに学びがあるように、文章量と、文章の解析結果にも学びがあった。しかし、このアウトプットだとブログを見ている人には伝わらないかもしれない。
-
思いのほか、偏りがあった。外れ値っぽい文書は何かあるので修正する。
-
直にスプレッドシート への書き込みは時間がかかって使いものにならなかった。gspread が遅いのかもしれない。別のライブラリだと上手くいく?
-
可視化して終わりではないので、きちんと修正する。そしてまた可視化する。
参考
以下、参考にした記事のリンクです。
- alvinwan/md2py: converts markdown into a Python parse tree
- PythonでGoogleスプレッドシートに書き込みをする方法
- gspreadライブラリの使い方まとめ!Pythonでスプレッドシートを操作する | たぬハック
- Office Space : Microsoft Word ドキュメントの統計情報を取得する
- QUERY - ドキュメント エディタ ヘルプ
- RedPen 1.10 ドキュメント
以上です。
コメント