Markdownの見出しにアウトライン番号を付ける独自仕様を追加する。(独自仕様のMarkdownファイルを通常のMarkdownファイルに変換するperlスクリプトを作成する)


## 内容
Markdownの見出しにアウトライン番号を付けたいと思った。
手動で直接書けば良いのだが、メンテナンスを考えると自動化したい。
例えば、

``` markdown
#1. title1
#1. title2
##1. title2-1
##1. title2-2
```

と記載すると以下のように表示されるようにしたい。


▼ ----- サンプル開始 ----- ▼

# 1. title1
# 2. title2
## 2.1. title2-1
## 2.2. title2-2

▲ ----- サンプル終了 ----- ▲


そこで、上記記述で作成した「独自仕様Markdownファイル」を「通常のMarkdownファイル」に変換するperlスクリプトを作成することで実現することにした。
あまり時間をかけたくないため、また、個人でしか使用しないため、エラー処理や細かい仕様などは完全無視する。

## スクリプト

仕様などはコメントに記載したので、そちらを参照してください。

``` perl:
#!/usr/bin/perl
# -------------------------------------------------------------------------
# Name     : convmd.pl
# Purpose  : 
#     アウトライン番号付き見出し(下記Note参照)を通常のMarkdownで使用できる
#     文字列に変換し、結果を標準出力に出力する。
# Usage    : convmd.pl  <独自仕様Markdownファイル> 
# Output   : 通常のMarkdown文字列
# Example  : convmd test.md > output.md
# Note     : 
#     アウトライン番号付き見出しについて
#     アウトライン番号付き見出しとは、独自に拡張したMarkdown書式で、
#     "#1. " ... "######1. "で始まる。
#     通常のMarkdownで使用するには、以下のように変換する必要がある。
#     変換仕様1：見出しレベル別に、以下のように変換する。
#         "#1. str"        → "# 1. str"
#         "##1. str"       → "## 1.1. str"
#         "###1. str"      → "### 1.1.1. str"
#         "####1. str"     → "#### 1.1.1.1. str"
#         "#####1. str"    → "##### 1.1.1.1.1. str"
#         "######1. str"   → "###### 1.1.1.1.1.1. str"
#     変換仕様2：以下の通り、連番を付ける。
#         "#1. str1"       → "# 1. str1"
#         "#1. str2"       → "# 2. str2"
#         "#1. str3"       → "# 3. str3"
#     変換仕様3：見出しレベルに合わせて連番を付ける。
#         "#1. str1"       → "# 1. str1"
#         "##1. str1-1"    → "## 1.1. str1-1"
#         "##1. str1-2"    → "## 1.2. str1-2"
#         "###1. str1-2-1" → "### 1.2.1 str1-2-1"
#         "###1. str1-2-2" → "### 1.2.2 str1-2-2"
#         "##1. str1-3"    → "## 1.3. str1-3"
#     変換仕様4：見出しレベル6まで対応する。
# Remarks : 
#     作成時間を短縮するため、また、個人でしか使用しないため、エラー処理や
#     細かい仕様などは完全無視。
#     問題が発生したら、その都度対応。
# -------------------------------------------------------------------------

# 初期設定
@outlineNums=(0, 0, 0, 0, 0, 0, 0); # $levels[0]は使用しない。
$maxLevel=6;                        # "#1. "〜"######1. "まで対応。

# Markdownファイルの読み込み
open(IN,$ARGV[0]);
@fileData=<IN>;
close(IN);

# 変換処理
foreach my $line (@fileData) {
  if ($line =~ /^(#+)1\. (.+)/) {
    # アウトライン番号付き見出しの場合の処理

    # レベル数(#の数)の取得
    my $level=length($1);
    
    if ($level<=$maxLevel){
      # 該当するレベルのアウトライン番号を加算
      $outlineNums[$level]++;
  
      # 該当するレベル以下のアウトライン番号をリセット
      for (my $i=($level+1); $i<=$maxLevel; $i++) {
        $outlineNums[$i]=0;
      }
      
      # アウトライン番号文字列作成
      $outlineNumsStr="";
      for (my $i=1; $i<=$level; $i++) {
        $outlineNumsStr.="$outlineNums[$i].";
      }
      
      # 通常のMarkdownで使用できる文字列を生成
      $line=sprintf("%s %s %s\n", $1, $outlineNumsStr ,$2);
    }
  }
  
  # 結果を出力
  print "$line";
}

exit 0;
```


## 実行例


▼ 独自仕様Markdownファイル(sample.org.md)

``` markdown:sample.org.md
#1. aaa
#1. bbb:
##1. bbb-1
##1. bbb-2
#1. ccc:
##1. ccc-1
##1. ccc-2
###1. ccc-2-1
###1. ccc-2-2
#1. ddd
```

▼ 実行

``` bash:
convmd.pl sample.org.md > sample.md
```


▼ 実行後 (sample.md)

``` markdown:sample.md
# 1. aaa
# 2. bbb:
## 2.1. bbb-1
## 2.2. bbb-2
# 3. ccc:
## 3.1. ccc-1
## 3.2. ccc-2
### 3.2.1. ccc-2-1
### 3.2.2. ccc-2-2
# 4. ddd
```

## メモ
### perl

▼ マッチした文字列の取り出し

``` perl:
$str="##1. title text";
if ($str =~ /^(#+)1\. (.+)/) {
  print "1-> $1\n";   # ##
  print "2-> $2\n";   # title text
}
```

▼ 同じ文字列を繰り返して連結

``` perl:
# aを5個連結
print "a" x 5;
# aaaaa
```


▼ 引数の取り出し

``` perl:
print $ARGV[0];
print "\n";
print $ARGV[1];
print "\n";
print $ARGV[2];
print "\n";

if (@ARGV != 1){
  print "ERROR!\n";    
}
```

▼ ファイルの読み込み

``` perl:
if (@ARGV != 1){
  print "ERROR!\n";
  exit 1;
}

open(IN,$ARGV[0]);
@data = <IN>;
close(IN);

foreach (@data) {
    print;
}
```