ブログの記事数もそれなりになり、過去書いた記事を修正して再投稿することも多くなりました。

ブログの記事は Markdown 形式で記載していて、文書校正ツールとして RedPen を使用しているのですが、投稿のたびに真面目に修正しているわけではなく、面倒になってそのまま投稿することもよくあります。
また、途中導入しているため導入以前の記事は大量の警告が出力されており、記事の品質にムラがあります。

記事の品質のムラは、RedPen の<wbr>警告数 / 文字数 = 警告率可視化できるかなと思いましたので、実際に試してみました。
実施したことを記載します。


実施する目的

ブログ記事 の 品質のムラを可視化する 目的を記載します。

  • 警告率 の高い文書の修正を実施することで、サイト全体の文書品質を効率良く上げたい。
  • サイト全体の文書品質が上がれば、Google の評価も上がる (と思う)。
  • Google の評価が上がれば、PageView が増えて広告収入が増える。

過去文書を活かして効率良く収入を得たいという思いは多少あり、そのあたりの足しになるかなと考えております。


実施したこと

以下、説明を記載します。

  • RedPen の警告情報の収集

    • 前提情報と 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平文(文ごとのエラーを出力)
xmlxml フォーマット
jsonjson フォーマット
json2json フォーマット(文ごとのエラーを出力)
  • 設定ファイル
    以下 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 ファイルも格納されています。
スクリプトは、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 ファイルにする

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 で可視化した結果を幾つか貼り付けます。

  • 警告ごとの合計
    "警告数の<wbr>合計"
    SpaceBetweenAlphabeticalWordInvalidSymbolSuggestExpression数が多いです。
    よく出る警告なのかと思われます。

  • エラーレベルごとの集計
    "エラーレベルごとの<wbr>集計"
    WarnErrorレベルごとの集計です。文書ごとのエラー数はまちまちで、エラーが多い文書は要修正文書かと思います。

  • 句読点数と警告の散布図
    "句読点数、<wbr>警告の<wbr>散布図"
    句読点数と警告の散布図です。句読点数が増えると、警告数は増えているようです。
    句読点が多い文書を修正するのと、誤差が大きい文書は何かありそうなので、確認してみようかと思います。

  • 警告率と文字数の散布図
    横長で若干見づらいですが、縦軸が警告率で、横軸が文字数の散布図です。
    文字数が多いからといって警告が多いわけではなさそうです。
    "警告率と<wbr>文字数の<wbr>散布図"
    一部、文字数の割に警告が多い文書があることがわかるので対象文書は見直したほうがいいように思いました。


実施後の感想

以下、実施後の感想になります。

  • 結構手作業が入るので、もう少しツールで自動化できないか検討する。CI に組み込みたい。

  • ステップカウントと、静的解析ツールの組み合わせに学びがあるように、文章量と、文章の解析結果にも学びがあった。しかし、このアウトプットだとブログを見ている人には伝わらないかもしれない。

  • 思いのほか、偏りがあった。外れ値っぽい文書は何かあるので修正する。

  • 直にスプレッドシート への書き込みは時間がかかって使いものにならなかった。gspread が遅いのかもしれない。別のライブラリだと上手くいく?

  • 可視化して終わりではないので、きちんと修正する。そしてまた可視化する。


参考

以下、参考にした記事のリンクです。

以上です。

コメント