diff --git a/lib/wiki.py b/lib/wiki.py
index 7af3a6f..1448bc4 100644
--- a/lib/wiki.py
+++ b/lib/wiki.py
@@ -15,6 +15,20 @@ AUTO_BANNER_PREFIX = "{{Auto-generated"
_COLUMNS_BLOCK_RE = re.compile(r'
(.*?)
', re.DOTALL)
_COLUMN_SEP_RE = re.compile(r"^\s*===\s*$", re.MULTILINE)
+# Minimal Markdown emphasis → wikitext, for use inside a verbatim columns block
+# (Pandoc doesn't process Markdown there). Asterisk style only, single line.
+# Order matters: bold-italic (***) before bold (**) before italic (*).
+_BOLD_ITALIC_RE = re.compile(r"\*\*\*(.+?)\*\*\*")
+_BOLD_RE = re.compile(r"\*\*(.+?)\*\*")
+_ITALIC_RE = re.compile(r"\*(.+?)\*")
+
+
+def _md_emphasis_to_wikitext(text: str) -> str:
+ text = _BOLD_ITALIC_RE.sub(r"'''''\1'''''", text)
+ text = _BOLD_RE.sub(r"'''\1'''", text)
+ text = _ITALIC_RE.sub(r"''\1''", text)
+ return text
+
def strip_first_h1(text: str) -> str:
"""Remove the first '# Heading' line and any immediately following blank line."""
@@ -35,13 +49,15 @@ def expand_columns(wikitext: str) -> str:
through verbatim as ``…
`` (line breaks and blank
lines preserved, inline markup entity-escaped). Columns within the block are
separated by a line containing only ``===``. Each column is wrapped in
- so its line breaks survive MediaWiki parsing, and content is
- HTML-unescaped so inline markup written in the fence (e.g. …) renders
- rather than appearing as literal text.
+ so its line breaks survive MediaWiki parsing. Content is
+ HTML-unescaped (so inline markup such as … renders rather than
+ appearing as literal text) and Markdown emphasis (``*italic*``, ``**bold**``,
+ ``***bold-italic***``) is converted to wikitext, since Pandoc does not
+ process Markdown inside the verbatim block.
"""
def render(match: re.Match) -> str:
- body = html.unescape(match.group(1))
+ body = _md_emphasis_to_wikitext(html.unescape(match.group(1)))
columns = _COLUMN_SEP_RE.split(body)
poems = "".join("\n" + col.strip("\n") + "\n" for col in columns)
return '' + poems + "
"
diff --git a/pipelines/songs/SCHEMA.md b/pipelines/songs/SCHEMA.md
index e44ac66..a42efa0 100644
--- a/pipelines/songs/SCHEMA.md
+++ b/pipelines/songs/SCHEMA.md
@@ -136,12 +136,12 @@ For parallel content — e.g. an original and its translation — write a fenced
````markdown
```columns
-原題
+**原題**
一行目
二行目
===
-Title
+**Title**
first line
second line
@@ -152,7 +152,7 @@ The renderer turns this into a flexbox row of `` columns (one per `===`-de
- **Line breaks and blank lines are preserved verbatim** — that's the point of using a fenced block; Pandoc passes the body through untouched, and each column is wrapped in `` so MediaWiki keeps the line breaks.
- **N columns**: use N−1 `===` separators. Two is the common case (original / translation).
-- **Inline markup is allowed**: HTML such as `…` or `
` written inside the block is HTML-unescaped on the way out, so it renders rather than showing as literal text.
+- **Emphasis in Markdown**: write `*italic*`, `**bold**`, or `***bold-italic***` (asterisk style, single line) — these are converted to wikitext. Raw inline HTML such as `…` or `
` also still works (it's HTML-unescaped on the way out), but you shouldn't need it.
- This is a shared transform (`lib/wiki.py`), so it works for any pipeline, not just songs. Column width/gap styling currently lives in that transform.
## Renderer behaviour