Markdown記法

概要

adiaryでは本家Markdown記法を忠実に再現しています。

また拡張として「さつき記法タグ[tag:xxxx]」や目次記法([*toc]関連のみ)*1が使えます。

*1 : [*toc2]は使えますが、今のところ[*toc1]と同等です。

Markdown記法に対する拡張

URL自動リンクが必要な場合は、ブログ設定画面の自動リンクをonにしてください。

オリジナルの拡張

その他の調整

  • 見出し記法の最高位を<H3>に設定しました。
  • <section>タグによるセクショニングを行い、最高位の見出し記法を使った地点でセクションを分割するようにしました。
  • 通常の文章ブロック中で改行する際、行末も次の行頭もASCII文字以外ならば、改行コードを除去するように仕様変更しました。*5
  • HTMLブロックとして認識するタグは「p div h[1-6] blockquote pre table dl ol ul script noscript form fieldset iframe math ins del」のみでしたが、「style article section nav aside header footer details audio video figure canvas map address aside base hr option source」を追加しました。

*2 : 生成されるHTMLはadiary準拠のものになります。

*3 : インラインは非対応

*4 : Markdownのリンク記法と重複した場合は、リンク記法が優先されます。

*5 : 日本語を改行しつつ記述する際に、HTMLの仕様上、改行位置にスペースが1つ入ってしまうため、それを防止するための措置。

仕様書にはないMarkdownの仕様と準拠状況

  • HTMLコメントは退避してその中はいじらない。
  • 行末スペース2個以上を改行に置き換える際、例えスペースがいくつあっても、スペース1つと<br />に置き換える。
  • リンク記法は、リンクテキストが空文字でもリンクを生成する。
  • 下線「==」「--」による見出し記法は、2個以上の連続した記号であって、文末にスペース以外の文字を含まないときのみ有効。
  • 参照リンク記法の定義は、参照名が空文字の場合、無効となる(そのまま出力)。
  • 参照リンク記法は、参照名が定義されてない場合、無効となる(そのまま出力)。
  • 引用ブロック中で更にHTMLブロックや見出しなどあらゆる記法が使える(無限に入れ子できる)。
  • 引用ブロック(>)の手前には3つまでスペースを置くことができる。
  • TABはタブ幅4としてスペースに置換される。
  • コードブロックの手前は空行でなくてはならない。
  • コードブロックの途中に空行を挟んでも良い。
  • リストブロック中に空白行があると、リスト要素に対して段落処理をする。
  • リストブロックのネストインデントは、1段目が0~3つ、それ以降が「段数×4 + 3個」まで有効。
  • 【Ver3.20】空行後の先頭スペースの行は、リストの項目が続いているとみなす。
  • 【Ver3.20】リスト中も、行末スペース2つ以上は<br />に置換する。
  • 【Ver3.30/GFM】テーブル記法の"-"(ダッシュ)は最低3つ必要。*6

非準拠の挙動

  • 段落ブロック中の改行(行連結)時に、文末と次の行頭がマルチバイト文字ならば改行を除去するよう変更。*7
  • コメント内に空白行を含むとき、コメント中の文字列をパースする。
    • コメント内はいかなる場合でもパースしないよう変更しました。
  • 自動リンク記法でメールアドレスを書いた場合、@より左側は「[\w\.\-]+」のみ使用可能。
    • @より左側に「+」記号も記述できるよう変更しました。
  • タグ中の **強調** 等でも、タグが2行にわたる場合は処理してしまう。*8
  • 【Ver3.20】途中空行を挟むリストがあった場合、リスト記号が異なれば違うリストと扱う。

*6 : Atomでは1個以上ですが、GFMの仕様によれば3つ必要と書かれているのでそれに準拠します。

*7 : こうしないと日本語の文章中に空白が入り違和感のある表示になります。

*8 : 対応は可能ですが、実用性に対して中の処理が汚くなってしまうので今のところ対応見送りです。

要望受け付けます

拡張部分は個別にオフにできます。skel/_parser/markdown.html を skel.local/_parser/markdown.html にコピーして編集してください。

Markdown記法はあまり使用していないので、使ってみて要望がある方は気軽にご連絡ください。

  • 要望例
    • 実装(仕様)を変更してほしい。
    • 実装してほしい拡張がある場合。
    • Markdownの仕様に準拠してない挙動を見つけた。
    • 拡張した部分が邪魔である。

記事の入力方法

adiaryは記事の入力方法を個別に選択できることができます。

編集画面にあるパーサから選択しますが、基本的には3種類です。

  • さつき記法(はてな記法互換。標準の記法)
  • Markdown記法
  • HTML直接入力

非公開ディレクトリの変更

一部のサーバでは .htaccess が無効になっており、本来ネット上からアクセスできない __cache/ ディレクトリや data/ ディレクトリにネット上からアクセスできてしまうことがあります。その状態で運用するとセキュリティホールとなるため、ここではその対策を述べます。

もしwebサーバの設定が変更可能ならば、そちらで対応しても構いません。

非公開ディレクトリの場所を変更する

# http://example.com/<uid>/adiary/adiary.cgi
+ public_html
  + adiary
     + __chche/
     + data/
     + info/
     + js/
     + lib/
     + plugin/
     + pub/
     + pub-dist/
     + skel/
     + skel.local/
     + theme/
     - adiary.cgi
     - adiary.conf.cgi
     - (略)

このようなディレクトリ構成のとき、http://example.com/<uid>/adiary/data/index.html がアクセス可能であると、致命的なセキュリティホールとなります。

この場合、public_htmlの外に __cahce/, data/ ディレクトリを移動します。

+ public_html
  + adiary
     + __chche/
     - (略)
+ __cache/
+ data/

移動後に、元の場所(public_html/adiary/)に __cache/ ディレクトリを再度作成し、Apacheから書き込めるようパーミッションを設定してください。

adiary.conf.cgi を開き、次の設定を変更します*1。公開ディレクトリと異なり、絶対パスで指定しても構いません。

# 非公開のデータディレクトリ
<$constant(data_dir) = '../../data/'>

adiary.env.cgi を adiary.env.cgi.sample から作り次を設定します。

# キャッシュディレクトリの変更
<$__cache_dir = get_filepath('../../__cache/')>

この状態で動作を確認します。

問題なく動作したら、public_html/adiary/__cache/ ディレクトリを消さずに中にあるファイルをすべて削除してください。ディレクトリを消してはいけません。このディレクトリは書き込み可能なまま残してください。

補足

一連の作業は shell上ならば次のように行います。chmodは必要な環境でのみ実行してください。

$ cd public_html/adiary/
$ chmod 777 __cache/ data/
$ mv __cache/ data/ ../../
$ mkdir __cahce/
$ chmod 777 __cahce/
$ vi adiary.conf.cgi
$ cp adiary.env.cgi.sample adiary.conf.cgi
$ vi adiary.env.cgi
(ここで動作確認)
$ cd __cache/
$ rm -f *

*1 : info/やskel/ディレクトリ等も移動しても構いませんが、アップデート作業がとても面倒になります。

解説

dataディレクトリにはユーザー情報などあらゆるデータが入るので秘匿する必要性は分かるかと思います。

__cache/ には、スケルトンをコンパイルしたキャッシュが入ります。この中には、adiary.conf.cgiのコンパイル結果が含まれます。外部DB接続を行っていた場合、IPや接続パスワードが漏れることになりますので、__cache/ ディレクトリは公開すべきではありません。

__cache/ ディレクトリは環境変数で簡単に変更することができますが、そもそも .htaccess が無効な環境では、環境変数が任意に設定可能だとは思えません。

adiary.env.cgiは、adiary(Satsuki-system)が環境を初期化する前に解析・実行するスケルトンファイルです。.conf.cgiよりも前に処理されるため、このファイルでキャッシュディレクトリを変更することでadiary.env.cgi以外のキャッシュファイルを外部に置くことが可能になります。

しかし、adiary.env.cgi実行時点ではキャッシュディレクトリは変更されていませんので、このファイルのキャッシュ置き場として、元々の __cache/ ディレクトリは残す必要があります。

環境変数の設定

.htaccess 等を使い環境変数を設定することで adiary の動作を変更できます。

以下の環境変数名はVer3.10以降対応です。

SatsukiTimer

SetENV SatsukiTimer	1

時間計測のon/offを設定します。on=1, off=0です。設定しない場合のデフォルトは以下です。*1

  • CGI動作時はoffです。
  • Perlキャッシュ環境ではonです。

off設定については、adiary.conf.cgi(.env.cgi)等で指定しても有効です。

<$ENV.SatsukiTimer=0>

*1 : オフ設定が有効になるのはVer3.10以降です。

SatsukiCacheDir

SetENV SatsukiCacheDir	<dir>

キャッシュディレクトリ(標準 __chace/)を変更します。

adiary.env.cgiで設定する方法もあります。この場合、adiary.env.cgiのキャッシュだけは__cache/に作されます。

SatsukiReloadStop

SetENV SatsukiReloadStop	1

Perlキャッシュ環境でのライブラリの更新チェックを省略します。

起動時に毎回行うライブラリチェックがなくなることで無駄な処理が減りますが、アップデート時に adiary.fcgi 等の再起動が必要になります。

ModRewrite

SetENV ModRewrite	1

mod_rewrite の設定状況を「0」か「1」で強制的に設定します。設定しない場合は、他の環境変数から自動検出します。Nginxでの設定で使用します。

※Ver3.34以前は「Mod_rewrite」という名前です。

MySQL/MariaDBでの運用

以下を踏まえた上でご利用ください。

  • 外部DB運用はDBモジュールロードに時間がかかります。先に高速動作を設定してください。
  • 標準のText-DBは、よほど多くの記事を扱わない限り十分なパフォーマンスがあります。
  • DBエンジンは InnoDB をご利用ください(MyISAMは非推奨です)。

DebianのMySQLがMariaDBに置き換わったので、現在はMariaDBでのみ動作確認を行っています。

準備

adiaryをインストールするサーバに、MySQLのクライアントライブラリ(DBD::mysql)をインストールしてください。

# apt-get install libdbd-mysql-perl

設定

まずMySQLに、adiary用のアカウントと、そのアカウントからフルアクセス可能なデータベースを作成してください。

その際、データベースの文字コード(やクライアントコード)はutf8で統一してください

次に adiary.conf.cgiを設定します。

# テキストDBの場合
#<$DB = loadpm('DB_text', "<@data_dir>db/")>	←コメントアウト

# MySQL の場合(データベース名、ユーザー名、パスワード)
<$DB = loadpm('DB_mysql', 'database=adiary', 'adiary', 'test', {Pool=>1})>

ローカル以外のMySQLサーバに接続する場合のサンプル。

<$DB = loadpm('DB_mysql', 'database=adiary;host=mysql.example.com', (略))>
<$DB = loadpm('DB_mysql', 'database=adiary;port=12345',(略))>
<$DB = loadpm('DB_mysql', 'database=adiary;host=10.45.67.89;port=12345',(略))>

サーバの環境構築メモ

  1. MySQL をインストールする。
    # apt-get install mysql-server
    
  2. my.confを設定する(最近は設定しなくてもInnoDBがデフォルトになっているようです)。
    [mysqld]
    character-set-server  = utf8mb4
    collation-server      = utf8mb4_general_ci
    
    default-storage-engine=InnoDB
    
  3. MySQL デーモンを起動する。
    # /etc/init.d/mysqld start
    
  4. MySQL に接続する。
    # mysql -u root
    # mysql -u root -p	←パスワード指定あり
    
  5. MySQLコンソールで rootパスワード を設定する
    mysql> use mysql;
    mysql> select host,user,password from user;			←確認
    mysql> select host,user,authentication_string from user;	←MySQL 8
    mysql> ALTER USER root@localhost IDENTIFIED BY 'ROOT-PASS';
    
  6. adiary用のデータベース、ユーザーを作成
    mysql> CREATE DATABASE adiary DEFAULT CHARSET=utf8mb4;
    mysql> CREATE USER adiary@localhost IDENTIFIED BY 'ADIARY-PASS';
    mysql> GRANT all privileges ON adiary.* TO adiary@localhost;
    

メモ

mysql> show tables;
mysql> show databases;
mysql> show variables like 'char%';
mysql> show create table TABLE_NAME;
mysql> show indexes from TABLE_NAME;
mysql> SELECT table_name,engine FROM information_schema.tables WHERE table_schema = 'DB NAME';
mysql> SELECT user,host,password FROM mysql.user;