最近はマークダウンを使って原稿を書くことが多いです。マークダウンはHTMLを簡略化したようなテキストベースのドキュメントの書き方です。

Aptenodytes forsteri -Snow Hill Island, Antarctica -juvenile-8b
 いろいろな機能がありますが、今日は見出しに注目します。
 行頭から「# 」(ポンド記号1つ+空白)と書くと、その行はレベル1の見出しになります。これを今後「見出し1」と呼びます。
 同様に、行頭から「## 」(ポンド記号2つ+空白)と書くと見出し2に、「### 」(ポンド記号3つ+空白)と書くと見出し3になります。
 ぼくは見出し1は本全体のタイトル、見出し2は章、見出し3は節、見出し4は項としています。こんな感じです。

# カレーの作り方
## まえがき
 本書では、インド生まれの日本人の国民食、カレーの作り方について述べます。
## 第1章 材料の買い出し
 まず、材料を買い出しに行きます。ここではすべてを買いに行く前提で書きますが、家の冷蔵庫に余り物がある場合はそっちを優先的に使ってください。
### 1-1 肉を買う
 肉は具材であると同時に出汁が出るのでカレーの味を決定します。ビーフ入りのカレーはビーフカレー、ポーク入りのカレーはポークカレーと言います。
#### 1-1-1 ビーフ
 牛肉は値段が張ります。
#### 1-1-2 ポーク
#### 1-1-3 チキン
#### 1-1-4 シーフード
### 1-2 野菜を買う
### 1-3 ルーを買う
### 1-4 他に買うもの
## 第2章 包丁で切る
## 第3章 油で炒める
## 第4章 鍋で煮込む
## 第5章 ルーを入れる
## 第6章 皿に盛る
## あとがき

 ここで「## 第1章」が章、「### 1-1-1 ビーフ」が節とします。

 正式には

# 第1章 材料の買い出し #

のように行末も「空白+行頭と同じ数のポンド記号」で囲みますが、行末の方は省略できるようになっています。

 マークダウンが便利なのは、Emacsのmarkdownモードのようなアウトライン機能のついたエディターを使うと章の折り畳みが出来ることです。

# カレーの作り方
## まえがき
−−−−−−−−
## 第1章 材料の買い出し
−−−−−−−−
## 第2章 包丁で切る
 では買ってきた材料を包丁で切ります。
## 第3章 油で炒める
## 第4章 鍋で煮込む
## 第5章 ルーを入れる
## 第6章 皿に盛る
## あとがき

のように、第2章を書いている時はまえがき、第1章を非表示にできます。

 さて、順調に最後の方まで書いていたら、「第2章 包丁で切る」の前に「第2章 ご飯を炊く」を挿入したくなったとします。アウトライン機能がついたエディターでは、これも簡単です。

# カレーの作り方
## まえがき
−−−−−−
## 第1章 材料の買い出し
−−−−−−
## 第2章 ごはんを炊く
−−−−−−
## 第2章 包丁で切る
−−−−−−
## 第3章 油で炒める
−−−−−−
## 第4章 鍋で煮込む
−−−−−−
## 第5章 ルーを入れる
−−−−−−
## 第6章 皿に盛る
−−−−−−
## あとがき
−−−−−−

 問題は、旧・第2章の「包丁で切る」を第3章に、第3章の「油で炒める」を第4章に、通し番号をシフトしてやらないといけないことです。
 章の下の項、節といった枝(ノード)の通し番号もみな加算(インクリメント)してやらなければなりません。
 逆に、章を削除した場合は、それ以降の通し番号をすべて減算(デクリメント)する必要があります。章の入れ替えも起こります。
 他にも、項、節レベルで挿入や削除や入れ替えが起こります。そのたびに通し番号を手動で付け替えていたら便利さ半減です。

 これは、通し番号を手動で振っているから起こる問題で、エディターにもともとその機能を持たせるとか、見出しにプレースホルダー的な変数を入れるとかも考えられますが、ここでは簡単に、Perlのスクリプトを使って番号を振ることを考えてみます。

#! /usr/local/bin/perl
#
# numberMD.pl -- マークダウンに番号を振る

use strict;
use warnings;
use 5.010;
use utf8;

my $shou = 0;
my $setsu = 0;
my $kou = 0;
my $infile = "curry.md";
my $tmpfile = "tmptmptmptmp"; # このような名前のファイルはないとする

open IN, "<:encoding(UTF-8)", $infile;
open TMP, ">:encoding(UTF-8)", $tmpfile;

my $i = 0;
while (<IN>) {
 if (/^## 第[0-9]*章 (.*)$/) {
  ++$shou;
  $setsu = 0;
  $kou = 0;
  $_ = '## 第'.&hanzen($shou).'章 '.$1."\n";
 } elsif (/^### [0-9]*-[0-9]* (.*)$/) {
  ++$setsu;
  $kou = 0;
  $_ = '### '.&hanzen($shou.'-'.$setsu).' '.$1."\n";
 } elsif (/^#### .-.-. (.*)$/) {
  ++$kou;
  $_ = '#### '.&hanzen($shou.'-'.$setsu.'-'.$kou).' '.$1."\n";
 }
 print TMP;
}

close IN;
close TMP;

rename ($tmpfile, $infile);

sub hanzen {
 my $str = shift;
 my @char = split //, $str;
 my $out = "";
 for my $char (@char) {
  $char =~ tr/0-9\-/0-9-/;
  $out .= $char;
 }
 return $out;
}

 入力ファイルを以下のようとします。

# カレーの作り方
## まえがき
 本書では、インド生まれの日本人の国民食、カレーの作り方について述べます。
## 第1章 材料の買い出し
 まず、材料を買い出しに行きます。ここではすべてを買いに行く前提で書きますが、家の冷蔵庫に余り物がある場合はそっちを優先的に使ってください。
### 1-1 肉を買う
 肉は具材であると同時に出汁が出るのでカレーの味を決定します。ビーフ入りのカレーはビーフカレー、ポーク入りのカレーはポークカレーと言います。
#### 1-1-1 ビーフ
 牛肉は値段が張ります。
#### 1-1-3 ポーク
#### 1-1-4 チキン
#### 1-1-5 シーフード
### 1-2 野菜を買う
### 1-3 ルーを買う
### 1-4 他に買うもの
## 第2章 ごはんを炊く
## 第2章 包丁で切る
## 第4章 鍋で煮込む
## 第5章 ルーを入れる
## 第6章 皿に盛る
## あとがき

 第2章がダブっています。あと「第3章 油で炒める」を削除してみました。あと「1-1-1」の次が「1-1-3」に飛んでいます。
 では、プログラムを実行してみます。

[sample]$ ./numberMD.pl
[sample]$

 何の挨拶もありません。そりゃそうか。出力ファイル(入力と同じcurry.md)はこうなります。

# カレーの作り方
## まえがき
 本書では、インド生まれの日本人の国民食、カレーの作り方について述べます。
## 第1章 材料の買い出し
 まず、材料を買い出しに行きます。ここではすべてを買いに行く前提で書きますが、家の冷蔵庫に余り物がある場合はそっちを優先的に使ってください。
### 1-1 肉を買う
 肉は具材であると同時に出汁が出るのでカレーの味を決定します。ビーフ入りのカレーはビーフカレー、ポーク入りのカレーはポークカレーと言います。
#### 1-1-1 ビーフ
 牛肉は値段が張ります。
#### 1-1-2 ポーク
#### 1-1-3 チキン
#### 1-1-4 シーフード
### 1-2 野菜を買う
### 1-3 ルーを買う
### 1-4 他に買うもの
## 第2章 ごはんを炊く
## 第3章 包丁で切る
## 第4章 鍋で煮込む
## 第5章 ルーを入れる
## 第6章 皿に盛る
## あとがき

 ちゃんとリナンバーされましたね。