Skip to content

fix(parser/render): [[image]] が含まれる paragraph の <p> wrap を Wikidot 本家挙動に合わせる#51

Merged
r74tech merged 3 commits into
developfrom
fix/image-paragraph-wrap
Jun 13, 2026
Merged

fix(parser/render): [[image]] が含まれる paragraph の <p> wrap を Wikidot 本家挙動に合わせる#51
r74tech merged 3 commits into
developfrom
fix/image-paragraph-wrap

Conversation

@r74tech

@r74tech r74tech commented Jun 12, 2026

Copy link
Copy Markdown
Owner

背景

Wikidot 本家の Paragraph.php (lib/Text_Wiki/Text/Wiki/Parse/Default/Paragraph.php) は $skip リストに 'image' を含み、<img> を含む行を含む paragraph を <p> で wrap しない。さらに aligned image ([[<image]] / [[>image]] / [[=image]] / [[f<image]] / [[f>image]]) は block-level の <div class="image-container ..."> を出力するため、surrounding text を別 <p> に切り出して <div> を兄弟要素として並べる。

wdpr は [[image]] を全て inline 扱いし、結果として <div><p><img class="image" /></p></div> のように余計な <p> で wrap していた。SCP テーマ系の .scp-image-block で画像と caption の間に隙間が出る不具合の根本原因。

変更点

1. paragraph rule の image 扱い

KNOWN_BLOCK_NAMES から "image" を除外。inline parser が行頭 [[image]] で paragraph を break しなくなり、[[image]]\ntext\n[[image]]\n[[image]]\n が同一 paragraph 内の <br /> 連結として扱われる (本家 <img><br>text / <img><br><img> に対応)。

2. splitAlignedImageParagraphs (新規)

paragraph 内に aligned image (alignment !== null) があった場合、その paragraph を text 部分と aligned image 部分に分割する。text 部分は paragraph として残り (<p>...</p>)、aligned image は独立 sibling になる (<div class="image-container ...">)。

3. unwrapImageParagraphs (新規)

plain image (alignment === null) を含む paragraph 全体から <p> を取り除き、子要素を親コンテナの直下に並べる。本家の \$skip リスト挙動を再現。

(2) と (3) は共通の mapElementChildren ヘルパで再帰するため、list / table / definition-list / tab-view 内にネストされた image 段落も同じく扱われる。

4. render: [[f=image]] の class 生成

本家 Image.phpf< / f> / < / > / = のみを class マッピングし、f= (float + center) には class を追加しない。wdpr は floatcenter を付けていたので、空文字に変更し <div class=\"image-container\"> のバニラを出力するよう修正。

Test plan

  • bun test (1317 pass / 0 fail)
  • bun run lint (10 warnings, 0 errors — 既存箇所のみ)
  • bun run format
  • bun run typecheck
  • tests/fixtures/image/{basic,fail}/expected.json & output.html を本家挙動準拠で再生成
  • tests/unit/parser/parser.test.tsgetImageFromParagraph ヘルパを「image 直結 / paragraph container 内」両対応に拡張
  • tests/integration/fixture-roundtrip.test.tsimage/basicSKIP_ROUNDTRIP 登録 (decompiler 側の paragraph 構造復元は別 PR)

既知の残課題

  • image/basic の roundtrip skip: decompiler が「paragraph 外に置かれた image」を 1:1 で serialize 復元できない。別 PR で扱う。
  • [[file]] は本家でも paragraph 化されるため本件のスコープ外。wdpr 側で [[file]] が未対応 (生テキスト化) なのは別 issue。

r74tech added 3 commits June 12, 2026 10:23
Wikidot の Paragraph rule は $skip リストに `'image'` を含み、`<img>` を
含む行を含む paragraph を `<p>` で wrap しない。さらに aligned image
(`[[<image]]` / `[[>image]]` / `[[=image]]` / `[[f<image]]` /
`[[f>image]]`) は block-level の `<div class="image-container ...">` を
出力するため、surrounding text を別 `<p>` に切り出して `<div>` を兄弟
要素として並べる。

この挙動を再現する 3 点:

1. KNOWN_BLOCK_NAMES から `"image"` を除外。行頭 [[image]] で paragraph
   を break しなくなり、隣接行と同一 paragraph に統合される。
2. splitAlignedImageParagraphs postprocess を追加。aligned image を含む
   paragraph を text 部分 (<p> で wrap) と aligned image (独立 sibling)
   に分割する。
3. unwrapImageParagraphs postprocess を追加。plain image を含む
   paragraph 全体から <p> を取り除き、子要素を親コンテナの直下に並べる。

どちらの pass も mapElementChildren 経由で再帰するため、list / table /
definition-list / tab-view の中にネストされた image 段落も同じく扱われる。
Wikidot 本家の Image.php は align トークン `f<` / `f>` / `<` / `>` / `=`
のみを class マッピングし、`f=` (float + center) はどの分岐にも該当しない
ため class を追加しない。

その結果 wrapper は `<div class="image-container">` のバニラとなる。
wdpr は `floatcenter` を付けてしまっていたので、本家挙動に合わせて空文字を
返すよう getAlignmentClass を修正し、呼び出し側で空文字時は trailing
space なしの `<div class="image-container">` を出力する。
- image/basic, image/fail の expected.json / output.html を本家挙動準拠で
  再生成
- parser.test.ts の getImageFromParagraph ヘルパを「image element 直結
  / paragraph container 内」両対応に拡張
- image/basic を SKIP_ROUNDTRIP に追加。decompiler 側の paragraph 構造
  復元は別タスクで対応する。
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
wdpr-demo-v1 b4215e2 Commit Preview URL

Branch Preview URL
Jun 12 2026, 01:24 AM

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
wdpr-demo-v1-files b4215e2 Commit Preview URL

Branch Preview URL
Jun 12 2026, 01:24 AM

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
decompiler-preview b4215e2 Commit Preview URL

Branch Preview URL
Jun 12 2026, 01:24 AM

@r74tech
r74tech merged commit 043030d into develop Jun 13, 2026
7 of 9 checks passed
@r74tech
r74tech deleted the fix/image-paragraph-wrap branch June 13, 2026 06:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant