SHOYAN BLOG

Rdiscountからkramdownへmarkdownのparserを変更した

数式を扱うために前回の記事で、markdownをkramdownに変更したのですが、コードのシンタックスハイライトが効かなくなってしまいました。

kramdownのparserをGFMにしてやるとうまくいきました。

_config.yml

1
2
kramdown:
  input: GFM

GFMを使わない場合は、プラグインがあるのでそちらでも対応できます。

kramdown-with-pygments

使い方ですが、pluginsディレクトリにkramdown_pygments.rbを置きます。
そして、_config.ymlのmarkdownを以下のように修正します。

1
markdown: KramdownPygments

また、parserにkramdownを使う場合はRdiscountとkramdownでcodeのmarkdownのフォーマットが違うのでgenerate時にエラーがでるかもしれません。

自分は以下のワンライナーで書き換えました。

1
2
find source/_posts -type f -name "*.markdown" | xargs sed -i '' -e 's/\`\`\`/\
~~~/g'

また、URLに自動でリンクを付与してくれる機能がRdiscountにはあったのですが、kramdownでは明示的に指定する必要があります。
Rdiscountのように自動的にリンクを付与するプラグインを作成しました。

使い方はkramdown_easy_link.rbplugins/ディレクトリに置いて、_config.ymlを以下のように修正します。

1
2
3
markdown: kramdown
kramdown:
  input: KramdownEasyLink

Jekyllで数式を表示する方法

Jekyllで数式を使いたい場合は、markdownにkramdownを使うのがおすすめです。
というのも、redcarpet はワンライナーの書式しか使えません。
rdiscount は自分が試したところ、動作しませんでした。

次にMathjax.jsを読み込みます。

1
<script type="text/javascript" src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

これで準備は整いました。

Kramdown のドキュメントに書かれているサンプルを表示します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$$
\begin{align*}
  & \phi(x,y) = \phi \left(\sum_{i=1}^n x_ie_i, \sum_{j=1}^n y_je_j \right)
  = \sum_{i=1}^n \sum_{j=1}^n x_i y_j \phi(e_i, e_j) = \\
  & (x_1, \ldots, x_n) \left( \begin{array}{ccc}
      \phi(e_1, e_1) & \cdots & \phi(e_1, e_n) \\
      \vdots & \ddots & \vdots \\
      \phi(e_n, e_1) & \cdots & \phi(e_n, e_n)
    \end{array} \right)
  \left( \begin{array}{c}
      y_1 \\
      \vdots \\
      y_n
    \end{array} \right)
\end{align*}
$$

基本的な書式は以下のようになります。

1
2
3
4
5
6
7
$$
\begin{align*}

LaTexの数式

\end{align*}
$$

また$$を使ってワンライナーで書くことも可能です。

1
$$ 5 + 5 $$

インラインにしたいときは\$$を使います。

1
\$$ 5 + 5 $$

このように文字中に数式を埋め込むことができます。

光は真空中を1秒間に約 メートル進む。 光速を で表す

1
光は真空中を1秒間に約 $$ 3.0 × 10^8  $$メートル進む。 光速を $$ cc $$ で表す

表記の確認にはMathJax checker を使うと便利です。
LaTeX 書式の数式をリアルタイムで確認することができます。

LaTexの書式に関しては以下を参考にしてください。

http://www.onemathematicalcat.org/MathJaxDocumentation/TeXSyntax.htm

参考リンク

レガシーコード向けに修正した部分だけPHP構文チェックをする仕組みを作った

修正した部分だけPHPの構文チェックをする仕組みを作ってみました。
構文に問題があればGithubのPull Requestにコメントされます。

2016-06-23_php-syntax-check

この方法のよいところは既存のソースを変えることなくPHPの構文チェックの仕組みを導入できることです。
規約に沿っていないコードが大量にあり、かつテストコードがないような環境(レガシー環境)にも導入することができます。

使用したツールは以下です。

また、packsaddleのツールはRuby製ですので、Rubyが動作する環境が必要です。

サンプルとしてGithubにphp-syntax-checkというリポジトリを作成しているので参考にしてください。

以下のスクリプトをCircleCIで実行しています。

check_syntax.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

echo "Start"
LIST=`git diff --name-only origin/master | grep -e '.php$'`

if [ -z "$LIST" ]; then
    echo "PHP file not changed."
    exit 0
fi

if [ -n "$CI_PULL_REQUEST" ]; then
    git diff --name-only origin/master \
        | grep -e '.php$' \
        | xargs vendor/bin/phpcs -n --standard=PSR2 --report=checkstyle \
        | bundle exec checkstyle_filter-git diff origin/master \
        | bundle exec saddler report \
        --require saddler/reporter/github \
        --reporter Saddler::Reporter::Github::PullRequestReviewComment
fi

仕組み

以下の3つのセクションに分類されます。

  • 対象のファイルを抽出
  • 構文チェック
  • 結果をレポート

1. 対象のファイルを抽出

以下のコマンドでmasterと差分のあるファイル名を取得します。

1
git diff --name-only origin/master

さらに grepで拡張子が .phpのファイルのみ対象にします。

1
git diff --name-only origin/master | grep -e ‘.php$'

2. 構文チェック

構文チェックツールは好きなものを使えます(CheckStyleフォーマットで出力できるものに限りますが)。
今回はPHP_CodeSnifferを使いました。

1
xargs vendor/bin/phpcs -n --standard=PSR2 --report=checkstyle

xargsは前のコマンドを引数でとるために必要です。

以下のコマンドでmasterとブランチの差分をチェックして、差分があるところのエラーを検知対象のエラーとしています。

1
bundle exec checkstyle_filter-git diff origin/master

エラーの差分の抽出にcheckstyle_filter-gitというツールを使っています。
これは、入力として渡したCheckStyle formatの文字列から、変更した内容の部分のエラーを抽出するツールです。
例えばファイルの10行目〜15行目を変更した場合、その行で発生したエラーのみを抽出します。

3. 結果をレポート

saddlerを使って結果をGithubに通知します。

1
2
3
bundle exec saddler report \
        --require saddler/reporter/github \
        --reporter Saddler::Reporter::Github::PullRequestReviewComment

注意点としては、PRを作っていないと通知でエラーとなります。

ですので、Pull Requestがあるかどうかをチェックするif文をいれています。
$CI_PULL_REQUEST はCIrcleCIの変数で、Pull Requestが作られていればこの変数にURLが格納されています。

1
2
3
if [ -n "$CI_PULL_REQUESTS" ]; then

fi

また、通知にはGITHUB_ACCESS_TOKENを発行して環境変数に登録しておく必要があります。

CircleCIの環境変数の設定については、以下を参照ください。

また、通知ではなく単に結果を出力する場合は、saddler/reporter/textを指定します。

1
2
3
bundle exec saddler report \
  --require saddler/reporter/text \
  --reporter Saddler::Reporter::Text

以下は、出力があった場合はエラーにする例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
RESULT=`git diff --name-only origin/master \
    | grep -e '.php$' \
    | xargs vendor/bin/phpcs -n --standard=custom_ruleset.xml --report=checkstyle \
    | bundle exec checkstyle_filter-git diff origin/master \
    | bundle exec saddler report \
      --require saddler/reporter/text \
      --reporter Saddler::Reporter::Text`

if [ -n "$RESULT" ]; then
    echo ""
    echo "An error has been detected,this following:"
    echo "$RESULT"
    exit 1
fi

その他

ファイルのエンコードがEUC-JPのソースコードに適用したところエラーとなりました。 リポジトリをフォークして対応しました。
1.1.0より使えるようになりました!

以下のように設定します。

Gemfile

1
gem "checkstyle_filter-git", git: "https://github.com/shoyan/ruby-checkstyle_filter-git.git", branch: "implement-exec"

iconvでgit diffの出力結果の文字コードをEUC-JP->UTF-8に変換して渡せるようにしました。

1
2
3
4
git diff --name-only origin/master \
  | grep -e '.php$' \
  | xargs phpcs -n --standard=custom_ruleset.xml --report=checkstyle \
  | bundle exec checkstyle_filter-git exec "git diff origin/master | iconv -f EUCJP -t UTF8"

PRもしているので直ることに期待です。
Mergeいただきました。

サンプルとしてGithubにphp-syntax-checkというリポジトリを作成しているので参考にしてください。

関連記事

参考リンク

ShellのTipsてきなやつ

ShellスクリプトのTipsです。

シェル変数の初期化をする

変数に値が設定されていない場合は、指定された値を返します。

1
: ${VAR:=初期化する値}

パラメーターを取得する

$@ にパラメーターが格納されています。

例えば以下の記述をした for.sh ファイルを作成します。

1
2
3
for role in "$@"; do
  echo $role
done

以下のように出力されます。

1
2
3
$ ./for.sh hoge moge
=> hoge
moge

評価結果を変数に格納する

"$()" で囲めば、評価結果を変数に格納することができます。

1
2
3
4
5
6
7
8
9
$ name="$(hostname)"
$ echo $name
=> shoyan-pc

# 以下も同じです。

$ name=`hostname`
$ echo $name
=> shoyan-pc

if と test コマンドの合わせ技

ifとtestコマンドを使う場合はtestコマンドを省略した[]がよく使われます。

[ 文字列1 = 文字列2 ]
[ 数値1 オプション 数値2 ]
[ オプション 評価対象 ]

[ の直後と ] の直前には必ず半角スペースが必要です (無いと正常に動作しません)。

ちなみに比較は == でなくて =です。

シェルの比較は文字列の比較と数値の比較があり、それぞれに対応するオペレーターがあります。
そのせいで複雑になっている印象があります。

数値の比較

数値1と数値2が等しいかどうか

-eq、もしくは =を使います。

1
2
3
4
$  [ 1 -eq 1 ]; echo $?
0
$  [ 1 = 1 ]; echo $?
0

数値1と数値2が等しくないかどうか

-ne を使います。

1
2
$  [ 1 -ne 2 ]; echo $?
0

!= でも動作しますが、慣習的にあまり使わないようです。

文字列の比較

文字列1と文字列2が等しいかどうか

同じ場合にtrueを返す=と その否定である != を使います。

1
2
$  [ "hey" = "hey" ]; echo $?
0

ちなみに数値の比較に使う -eq で比較したところエラーとなりました。

1
2
3
$  [ "hey" -eq "hey" ]; echo $?
[: integer expression expected: hey
2

文字列1と文字列2が等しくないかどうか

文字列比較のNOT条件
!=を使用します。

1
[ "$hoge" != "fuga" ]

数値比較のNOT条件

数値の比較の場合は -ne オプションを使うのが慣習のようです。

1
[ 1 -ne 2 ]

変数が空かどうか

1
[ -z "$hoge" ]

空でないかを判定する場合は -n を使います。

1
[ -n "$hoge" ]

findで抽出したファイルをreadコマンドで1行ずつ処理する

1
find application -type f -name "*.ini" | while read LINE; do wc -l ${LINE}; done;

実行ファイルのあるパスを取得する

1
echo "$(cd $(dirname $0);pwd)"

1つ上のディレクトリは以下のように取得する

1
echo "$(cd $(dirname $0);cd ..;pwd)"

参考リンク

Treant.jsでツリーダイアグラムを描画する

Treant.jsとはツリーダイアグラムを描画するためのJavaScriptライブラリです。
Treant.jsでツリーダイアグラムを描画してみました。

http://codepen.io/shoyan/details/MeaqzN/

簡単なサンプルを作ってみる

まずは簡単なサンプルを作ってみましょう。

http://codepen.io/shoyan/pen/qNOMoN

codepen.ioを使うと簡単にサンプルが作成できるので便利です。

Treant.jsを利用するには、いくつか必要なモジュールがあります。

JS

CSS

BaseとなるHTMLのテンプレート

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!doctype html>
<html lang="ja">
<head>
    <meta charset="utf-8"/>
    <title></title>

    <!-- stylesheets -->
    <link rel="stylesheet" href="http://fperucic.github.io/treant-js/Treant.js" type="text/css"/>
     <style>
         body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { margin:0; padding:0; }
         body { background: #fff; }
         /* optional Container STYLES */
         .chart { height: 159px; width: 332px; margin: 5px; margin: 5px auto; border: 3px solid #DDD; border-radius: 3px; }
         .node { color: #9CB5ED; border: 2px solid #C8C8C8; border-radius: 3px; }
         .node p { font-size: 20px; line-height: 20px; height: 20px; font-weight: bold; padding: 3px; margin: 0; }
    </style>
</head>
<body>
    <div id="tree-simple" style="width:335px; height: 160px" </div>

    <!-- javascript -->
    <script src="http://fperucic.github.io/treant-js/vendor/raphael.js"></script>
    <script src="http://fperucic.github.io/treant-js/Treant.js"></script>
</body>
</html>

JS

JavaScriptファイルです。設定をJSONで定義して、コンストラクタに渡しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
simple_chart_config = {
    # chartの設定をします
    chart: {
        container: "#tree-simple"
    },
    # ノードを定義します
    nodeStructure: {
        text: { name: "Parent node" },
        children: [
            {
                text: { name: "First child" }
            },
            {
                text: { name: "Second child" }
            }
        ]
    }
};
# コンストラクタ
var my_chart = new Treant(simple_chart_config);

基本的には、nodeStructureに必要なノードを定義して、CSSで見た目を調整するという感じです。
アニメーションにも対応していて、その場合はjQueryが必要だったりするようです。
サンプルも色々あるので参考にしてみるとよいと思います。
http://fperucic.github.io/treant-js/