高機能軽量マークアップ言語をサポートするperl modulino：perlプログラマに向けての補遺

[Perlのカレンダー | Advent Calendar 2022 - Qiita](https://qiita.com/advent-calendar/2022/perl)の22日目の記事です。

# はじめに

Wini.pmは、拙作の高機能軽量マークアップ言語markgaabをサポートするperlスクリプトです。これについて、この17日にアドベントカレンダーへの投稿として[高機能軽量マークアップ言語をサポートするperl modulino：Wini.pmの2022年 - Qiita](https://qiita.com/doikoji/items/187364d2f87642064884)を公開しました。しかし、当該記事を読み返してみるに、あまりにperlと関係ない話に終始してしまってしまいました。そこで補遺という形でもう一本書かせていただきます。

Wini.pmを使ってスクリプトを組むとこんなことができるという話です。

# プログラマのためのWini.pm

[前記事](https://qiita.com/doikoji/items/187364d2f87642064884)で説明したとおり、Wini.pmは単体でフィルタコマンドとしても静的サイトジェネレーター(SSG)としてもperlモジュールとしても機能します。

本記事では、モジュールとしての使い方、すなわちスクリプト中でmarkgaabテキストを操作する方法を中心に紹介することにします。

## 入門編

markgaabテキストをHTMLテキストに変換する基本的な手続きは、次の通りです。

0. `use Wini`を宣言。
0. サブルーチンinit()を呼びだし、グローバル変数などの初期化。
0. to_html()を呼び出してmarkgaab→HTML変換。

以下にサンプルコードを示します。サブルーチンの呼び出しに際してpackageの指定が必要な点に注意してください。

```
use strict;
use warnings;
use utf8;
use Wini;

Text::Markup::Wini::init();
print Text::Markup::Wini::to_html(<<'EOD');

! はじめに

{{b|markgaab記法}}で書いてみる。

!! 箇条書き

* 項目1
* 項目2
* 項目3

; 定義リスト項目1
: 定義リスト項目1説明
; 定義リスト項目2
: 定義リスト項目2説明

!! 表

|- 簡単な表 | @@1 |
| aaaaaaaaaa | bbbbbbbbbbb |
| ccccccccccc |-           |

EOD
```

このような出力が得られます。

![testwini.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/f7e4da37-d065-d092-0ca1-d7e0eea816f4.png)

このように、Wini.pmとは、markdownチックなテキストからHTMLテキストを作れるというシステムを実現したものです。

# 基本編

## 完全体のHTMLファイル

上記の手順ではmarkgaabで書き置いた部分だけがHTML化され、ヘッダなどはつきません。そのままブラウザで表示しようとすると、文字化けなどの問題が発生することがあります。
Doctype宣言や`<html><head><body>`タグなどを含む完全な形のHTMLテキストを得るには、whole_html()を使います。

```
print Text::Markup::Wini::whole_html(Text::Markup::Wini::to_html(<<'EOD'));
以下略
```

## テンプレートモード

また、グローバル変数`$TEMPLATE`にテンプレート用HTMLファイルのパス名を設定しておくと、[テンプレートモード](https://qiita.com/doikoji/items/187364d2f87642064884#%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%83%A2%E3%83%BC%E3%83%89)での処理が実行されます。

```
use strict;
use warnings;
use utf8;
use Wini;

Text::Markup::Wini::init();

our $t = 'wini/sample/template.html';
(-f $t) or die "File $t not found.";
$Text::Markup::Wini::TEMPLATE = $t;

print Text::Markup::Wini::to_html(<<'EOD');

===
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 bellow.

?#introduction

Introdution here.

?#conclusion

Conclusion here.

EOD
```

テンプレートモードは、Wini.pmを使って独自CMSのようなものを作るなら特に有用と思われます。

# 拡張容易なシステム

Wini.pmの中では幾つかグローバル変数を利用し、全体的な設定に関わる情報を持たせています。そのうちのひとつが`%MACROS`で、markgaabテキストのマクロ部分をHTML化する関数のリファレンスを格納するためのハッシュです。スクリプト内でこのハッシュに要素を追加することにより、簡単にカスタムマクロを追加し自由に使えるようにできます。

以下は、よくwebページの末尾に見られる"All rights reserved"を出すためのマクロを作ってみた例です。

```
$MACROS{copyright} = sub{
  my($name, $firstyear, $lastyear) = @_;
  (defined $name)      or $name = 'Anonymous';
  (defined $firstyear) or $firstyear = localtime->year;
  (defined $lastyear)  or $lastyear  = localtime->year;
  my $period = ($firstyear eq $lastyear) ? $firstyear : "${firstyear}-${lastyear}";
  return(qq!<span>'&copy; ${period}, ${name}, All rights reserved.</span>!);
};
```

これをinit()の実行後に実行します。それによって`{{copyright|John Doe|2021|2022}}`のようなマクロが使えるようになり、これは以下のようなHTMLテキストに変換されます。

```
<span>'&copy; 2021-2022, John Doe, All rights reserved.</span>
```

こんな感じで、すこしのperlの知識があれば、機能の拡張・改変が容易。

CMS、Wikiシステム、ブログビルダーなどなどを独自仕様で作りたいという時に、Wini.pmを組み込めば、目覚ましい柔軟性を発揮してそのシステムを下支えしてくれることでしょう。

# おわりに

以上、プログラミングの素材としてのWini.pmを紹介しました。

作者としては、大規模スクリプトからコマンドラインでのワンライナーまでの幅広い形態で利用可能という間口の広さを持たせ、それでいて構造化HTMLや多言語対応HTMLにも積極的に対応する先進性をも重視した、なかなか良いツールに仕上がってきたと思っています。

ぜひともGithubからアーカイブを入手していただき、いろいろ試用していただければと願っています。