高機能軽量マークアップ言語をサポートするperl modulino：wini.pmの2022年

[Qiita Advent Calendar 2022](https://qiita.com/advent-calendar/2022) の 17日目の記事です。

拙作Wini.pmの紹介です。
**Wini.pmは、 HTML live standard準拠の軽量高性能マークアップ言語Markgaabのサポートツールです。Markgaabとは、HTML(WHATWG Living Standard)出力に特化した高性能かつ軽量なマークアップ言語です。** 名称は"Markup Going Above And Beyond"に由来しています。どちらも筆者により開発されたものです。
Wini.pmのversion 0は2019年に公開されました。二年後の今日、大幅に機能拡張したversion 1を発表します。
# はじめに

昨年の[Perl Advent Calendar 2021](https://qiita.com/advent-calendar/2021/perl)にて、私は次のように書きました。

[高機能軽量マークアップ言語をサポートするperl modulino：wini.pmの2021年 - Qiita](https://qiita.com/doikoji/items/d438ad26971d2f75d3e4)
> それから2年たったこの2021年末、大きな改修を施し、wini.pmをver.0からver.1にバージョンアップすることにしました。新たに二つの概念を導入し、それを基盤とした幾つかの重要機能を追加します。
> 
> 当初の計画では11月末までに作業を完了し、

この時点では年明け2022年の正月休みぐらいにはアップデート完了させver1.0の正式リリースを宣言するつもりだったんですよ。

しかしまあいろいろあってですね… それが2022年12月、というか、本日12月17日に伸びた次第。いやあ、一年も引っ張るとは。

# こいつらがあると何が嬉しいのか?

軽量マークアップ言語といえばmarkdownがすっかりデファクトスタンダードの地位を確立しているように見えるなか、なぜまた車輪の再発明なのでしょうか? markgaab開発には具体的には次のようなモチベーションがありました。

* **複雑な表を書きたい** -- 日本人好みの、罫線が複雑に入り組んだ複雑な表。これを素のHTMLで書こうとすると確実に死ねます。何とか簡便に処理できないものかというのが最初の動機でした。この解決はver. 0の段階でもかなりのレベルまで達成できてはいましたが、ver. 1.0では細部をだいぶん改良しています。

* **セマンティックwebに対応したマークアップ言語が欲しい** -- ver. 1.0では「セクション」が導入され、`<section><header><footer><aside><nav>`などのタグに直接的に対応できるようになっています。またセクションには独自の「変数空間」が設定でき、多国語の文章が混在するようなHTMLテキストも合理的に書ける配慮をしました。

ツールとしてのWini.pmについては、とにかく簡単にHTMLファイルを作れるようにしたいという一念で開発を続けてきました。

後述するように、Wini.pmというたった一つのファイルに必要な機能は全部持たせており、他のライブラリや支援ツールの類に依存しません。これ単体でフィルタコマンドとしてもSSGとしてもperlライブラリとしても機能します。オールインワン三位一体スクリプトです。

これまで私はPC上の作業のためにしばしば何かツールを導入することを余儀なくされ、そのたびに環境整備を強いられ、既存の環境との共存にややこしく気を遣ってきました。その状況にほとほとうんざりしていました。だからこそのシングルファイル構成です。繰り返しますが、perlとWini.pmさえあれば、HTMLコンテンツ作成の大半に片を付けることができます。

# Getting started

## Wini setup

Wini.pmはperlスクリプトです。したがってperlがインストールされていることが使用の要件です。perlと標準ライブラリさえインストールされていれば、他のライブラリの追加インストールは全く不要です。

したがって、linuxやMacOSをお使いであれば、ファイルWini.pmただひとつを適切なディレクトリに置けば準備完了です。すなわち、PATHの通ったディレクトリと、`perl -le 'print for @INC'`でリストアップされるディレクトリのいずれかです。

windowsを使っていてまだperlを使っていない方は、[WSL のインストール](https://learn.microsoft.com/ja-jp/windows/wsl/install)と[Windows Terminalのインストール](https://chigusa-web.com/blog/wsl2-win11/#toc10)をすませましょう。これでperlだけでなく数々の有用なツールが使えるようになります。以前はそれなりに手数が必要だったインストール作業ですが、日々改善が進み、最近はほとんど手間いらずです。よほど特別な理由がない限り、もうcygwinやMTSYS、StrawberryPerlを選択する意義は乏しくなったように思われます。

perlが使えることが確認出来たら、Wini.pmのセットアップです。gitコマンドが使える方は、

```
git clone 'https://github.com/Koji-Doi/wini.git'
```

さもなければ[githubのアーカイブ](https://github.com/Koji-Doi/wini/archive/refs/heads/master.zip)をダウンロードして展開してください。続いて、Wini.pmをPATHをひいたディレクトリにコピー。とりあえずコマンドラインでWini.pmが利用できるようになります。

# markgaabの基本

markgaabはウィキメディアマークアップやmarkdownに触発された私が、HTML特化型の、より高機能な軽量マークアップ言語を欲してデザインしたものです。

文法自体はversion0から基本的に同じです。
* [WINI ━ WIKIやMARKDOWNを超えた新しいマークアップ言語処理システム - Qiita](https://qiita.com/doikoji/items/f6139b7d91b48e50dcef)
以前の記事では「winiマークアップ」として案内していました。

また、version1.0からは、簡単なチートシートをオンラインヘルプとして表示できるようにしました。
```
Wini.pm -h mg
```
 
# 簡単な使用例

ごくごく単純なmarkgaabテキストをHTMLに変換してみましょう。

```
$ echo 'Hello, {{b|markaab}} world!' | ./Wini.pm  --outcssfile 2>/dev/null

<p>
Hello, <span style="font-weight:bold;">markaab</span> world!
</p>
```

このように、Wini.pmをフィルタコマンドとして使い、簡単にHTMLコードが生成できます。markgaabの個々の書法をその場で気軽に確認できるので、習得はあっという間にできます。

もちろんファイル単位での処理も簡単。markgaabファイル`input.mg`を作成しておき、次のようにコマンドラインに打ち込めば、あっという間にHTMLファイルの完成です。

```
$ Wini.pm --whole < input.mg > output.html
````

#  一歩進んだ使い方

## テンプレートモード

Wini.pm ver. 1.0 は、静的サイトジェネレーター（ＳＳＧ）と呼ばれるソフトと同様に利用することもできます。

すなわち、HTMLファイルの「テンプレート」に、データファイルから読み取ったテキストを流し込み、成熟HTMLファイルを生成します。ウィキペディアやブログのように定型フォーマットの多数のページから構成されるサイトをバッチ処理で一括で作り出すことができます。

### テンプレートファイル

データを突っ込む先となるもの。基本的にHTMLファイルです。

ただし、可変テキスト部分を「変数」として扱い、`[[変数]]`のように表現します。`[[_]]`はちょっと特殊で、パラメーター部分の「本文」に対応します。

```
<!DOCTYPE html>
<html lang="[[lang]]">
<head>
<meta charset="UTF-8">
<!-- link rel="stylesheet" type="text/css" href="https://unpkg.com/mvp.css" -->
<style>
  h1, h2{
    text-align: center;
  }
  td{
    text-align: center;
  }
  .right{
    text-align: right;
  }
</style>
<title>[[pagetitle]]</title>
</head>
<body>

<header>
<h1>[[sitetitle]]</h1>
<h2>[[pagetitle]]</h2>
<div class="right">First Published: [[firstdate]]</div>
<div class="right">Last Updated: [[lastdate]]</div>
</header>
<hr>

<section id="introduction">
[[introduction]]
</section>

<section id="main">
<h3>[[maintitle]]</h3>

[[_]]
</section>

<section id="conclusion">
[[conclusion]]
</section>

<footer>
Copyright &copy; John Doe, 2022, All right reserved.
</footer>
</body>
</html>
```

### パラメーターファイルの例

次のようなファイルを用意します。変数定義と本文の二つのパートから構成されます。

`===`で挟まれた部分が変数定義パートです。変数定義は`変数名: 値`の形で、一行に一変数の定義を書いていきます。値が文字列の場合は引用符で挟まなければなりません。数値の場合はそのまま書いて大丈夫です。

変数定義パートの外に書かれているのが「本文」パートです。この中には`?#セクション名`で始まる「セクション」を置くことができます。このセクションも変数の値として利用できます。ここで示した例では`introduction`や`conclusion`がそれに該当します。またセクションが明示されていない部分（下の例では`Main text here`以下）はセクション`_`として扱われます。上に示したパラメータファイル内の`[[_]]`はこれに対応しているわけです。

どちらのパートに書かれたデータも、テンプレートに突っ込まれるのは同じ。しかし、本文パートはmarkgaabテキストとして扱われ、テンプレートに突っ込まれる前にHTMLに変換される点が変数定義パートとは違います。


```
===
lang: 'en'
pagetitle: 'Sample page'
sitetitle: 'Sample site'
firstdate: '14 Nov. 2022'
lastdate: '15 Nov. 2022'
===

Main text here.

We can use [https://github.com/Koji-Doi/wini markgaab] typesetting as shown below.

|- Table   | @@1                 |
|!!        | column 1 | column 2 | column 3 |
|!!! row 1 | a        | b        | c        |
|    row 2 | d        |-         |^         |

* list item 1
* list item 2
*# ordered list item 2-1
*# ordered list item 2-2

?#introduction

Introduction here.

?#conclusion

Conclusion here.
```

### 出力（テンプレート＋パラメータ＝成熟HTML）

コマンドラインに、以下のような感じでコマンドを打ち込みます。

```
./Wini.pm --whole --template template.html -i sample.par -o output.html
```

結果、次のようなoutput.htmlが生成されます。

![capture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/a68324dc-6d0f-cfee-0335-f445dbf92926.png)

## その他

出典の管理や言語設定など、他にもいろいろ拡張した部分がありますが、締め切り（12月16日）に間に合いそうもないので、後日改めてご案内することにします。またしても中途半端な記事立項で面目次第もございません。