flexmark-java で Markdown を HTML に変換する

## 概要

- Java の Markdown ライブラリである flexmark-java を使って Markdown 文書を HTML 文書に変換する

## サンプルプログラム

### ファイル一覧

```
├── build.gradle
└── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           └── App.java
        └── resources
            └── markdown.md
```

### App.java

```java
package com.example;

import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension;
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension;
import com.vladsch.flexmark.ext.tables.TablesExtension;
import com.vladsch.flexmark.ext.toc.TocExtension;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.util.data.MutableDataSet;

import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

public class App {

  public static void main(String[] args) throws IOException {

    // Markdown のさまざまな記法に対応するためのオプションを設定
    MutableDataSet options = new MutableDataSet();
    options.set(Parser.EXTENSIONS,
      Arrays.asList(
        AnchorLinkExtension.create(), // 見出しにアンカーを付ける
        StrikethroughExtension.create(), // 打ち消し線に対応
        TablesExtension.create(), // テーブルに対応
        TocExtension.create() // [TOC] の部分に目次を生成する
      ));

    // Markdown パーサーと HTML レンダラーを用意
    Parser parser = Parser.builder(options).build();
    HtmlRenderer renderer = HtmlRenderer.builder(options).build();

    // Markdown ファイルを読み込む
    URL url = App.class.getClassLoader().getResource("markdown.md");
    List<String> lines = Files.readAllLines(Paths.get(url.getPath()), StandardCharsets.UTF_8);
    String markdown = String.join("\n", lines);

    // Markdown を HTML に変換して出力
    Node document = parser.parse(markdown);
    String html = renderer.render(document);
    System.out.println(html);
  }
}
```

## build.gradle

flexmark-java を導入するための設定を記述する。

```build.gradle
plugins {
  id 'java'
  id 'application'
}

group 'com.example'
version '0.0.1'

sourceCompatibility = 1.8

repositories {
  mavenCentral()
}

dependencies {
  // flexmark-java 0.50.42 を導入する
  implementation 'com.vladsch.flexmark:flexmark-all:0.50.42'
}

application {
    mainClassName = 'com.example.App'
}
```

### Markdown ファイル

変換元に使う Markdown 文書。

```md
[TOC levels=1-2]

# Markdown

## Paragraphs

Hello, world.

Goodbye, world.

## Emphasis

*Hello, world.*

**Goodbye, world.**

~~Hello, Goodbye.~~

## Bullet List

- Hello
- World
- Goodbye

## Numbered list

1. Hello
2. World
3. Goodbye

## Table

| Left align | Right align | Center align |
|:-----------|------------:|:------------:|
| A          | B           | C            |
| Hello      | world       | Goodbye      |

## URL

http://example.com/

[example.com](http://example.com/)

<a href="http://example.com/">example.com</a>

## Image

![Image](image.png "image")

## Quote

> Hello, world.
> Goorbye, world.

## Source Code

```java
public class A {
  public static void main(String[] args) {
    System.out.println("Hello, world");
  }
}
```　
```

### 変換出力した HTML 文書

```html
<ul>
<li><a href="#markdown">Markdown</a>
<ul>
<li><a href="#paragraphs">Paragraphs</a></li>
<li><a href="#emphasis">Emphasis</a></li>
<li><a href="#bullet-list">Bullet List</a></li>
<li><a href="#numbered-list">Numbered list</a></li>
<li><a href="#table">Table</a></li>
<li><a href="#url">URL</a></li>
<li><a href="#image">Image</a></li>
<li><a href="#quote">Quote</a></li>
<li><a href="#source-code">Source Code</a></li>
</ul>
</li>
</ul>
<h1 id="markdown"><a href="#markdown" id="markdown">Markdown</a></h1>
<h2 id="paragraphs"><a href="#paragraphs" id="paragraphs">Paragraphs</a></h2>
<p>Hello, world.</p>
<p>Goodbye, world.</p>
<h2 id="emphasis"><a href="#emphasis" id="emphasis">Emphasis</a></h2>
<p><em>Hello, world.</em></p>
<p><strong>Goodbye, world.</strong></p>
<p><del>Hello, Goodbye.</del></p>
<h2 id="bullet-list"><a href="#bullet-list" id="bullet-list">Bullet List</a></h2>
<ul>
<li>Hello</li>
<li>World</li>
<li>Goodbye</li>
</ul>
<h2 id="numbered-list"><a href="#numbered-list" id="numbered-list">Numbered list</a></h2>
<ol>
<li>Hello</li>
<li>World</li>
<li>Goodbye</li>
</ol>
<h2 id="table"><a href="#table" id="table">Table</a></h2>
<table>
<thead>
<tr><th align="left">Left align</th><th align="right">Right align</th><th align="center">Center align</th></tr>
</thead>
<tbody>
<tr><td align="left">A</td><td align="right">B</td><td align="center">C</td></tr>
<tr><td align="left">Hello</td><td align="right">world</td><td align="center">Goodbye</td></tr>
</tbody>
</table>
<h2 id="url"><a href="#url" id="url">URL</a></h2>
<p>http://example.com/</p>
<p><a href="http://example.com/">example.com</a></p>
<p><a href="http://example.com/">example.com</a></p>
<h2 id="image"><a href="#image" id="image">Image</a></h2>
<p><img src="image.png" alt="Image" title="image" /></p>
<h2 id="quote"><a href="#quote" id="quote">Quote</a></h2>
<blockquote>
<p>Hello, world.
Goorbye, world.</p>
</blockquote>
<h2 id="source-code"><a href="#source-code" id="source-code">Source Code</a></h2>
<pre><code class="language-java">public class A {
  public static void main(String[] args) {
    System.out.println(&quot;Hello, world&quot;);
  }
}
</code></pre>
```

### 今回の動作確認環境

- Gradle 5.6.3
- Java 1.8.0_222 (AdoptOpenJDK 25.222-b10)

## 参考資料
- [vsch/flexmark\-java: CommonMark/Markdown Java parser with source level AST\. CommonMark 0\.28, emulation of: pegdown, kramdown, markdown\.pl, MultiMarkdown\. With HTML to MD, MD to PDF, MD to DOCX conversion modules\.](https://github.com/vsch/flexmark-java)
- [Extensions · vsch/flexmark\-java Wiki](https://github.com/vsch/flexmark-java/wiki/Extensions)