mdv-live 0.5.18 → 0.5.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.5.19] - 2026-05-16
9
+
10
+ ### Fixed — Marp `![bg]` background images
11
+
12
+ Marp の `![bg](画像)` 背景画像構文を含むスライドが mdv で真っ白になっていた
13
+ バグを修正。NotebookLM 製の図解 13 枚を `![bg]` で全面配置したプレゼンが mdv
14
+ で全スライド空白になり発覚(157_イディアコーポレーション案件)。
15
+
16
+ - 原因: marp-core は `![bg]` を `<img>` ではなく
17
+ `<figure style="background-image:url(&quot;パス&quot;)">` として出力する。
18
+ `rewriteMediaPaths` は `<img>/<video>/<audio>/<source>` の `src` 属性しか
19
+ `/raw/` に書き換えず、CSS の `background-image:url(...)` を素通ししていた。
20
+ 結果、相対パスが SPA の現在 URL 基準で誤解決され 404 → CSS 背景画像のため
21
+ コンソールエラーも出ず真っ白になっていた
22
+ - `rewriteMediaPaths` に `background-image:url(...)` 書き換えルールを追加。
23
+ marp-core が HTML エンコードするクォート(`&quot;`)に対応
24
+ - quoted URL は **対応する閉じクォートまで** を URL として読む。最初の `)` で
25
+ 切らないため、`cover (1).png` のような括弧入りファイル名
26
+ (Marp 出力 `url(&quot;cover%20(1).png&quot;)`)も壊れない
27
+ - 絶対 URL・data URI・空 URL は書き換えない
28
+ - 既知の制約: 1 つの `background-image:` 宣言に複数 `url()` がある場合は先頭
29
+ のみ書き換わる。`![bg]` は 1 枚ごとに別 `<figure>` になるため影響なし。
30
+ カンマ区切りの `backgroundImage:` ディレクティブのみのエッジケース
31
+
32
+ ### Verified
33
+
34
+ - 278 テスト 全 PASS(既存 272 + 新規 6: `![bg]` 相対/サブディレクトリ/括弧/
35
+ エンコード空白/空/絶対 URL)
36
+ - Playwright dogfood(`docs/dogfood_20260516/`): 全面 bg / bg fit / split bg /
37
+ インライン画像 / 絶対 URL bg / サブディレクトリ解決の 6 ケースを実機目視、
38
+ コンソールエラー 0
39
+ - Codex review 3 round(codex-loop)で収束。round 1 [P2] 括弧切れ修正、
40
+ round 2 [P3] 空 URL ガード、round 3 [P3] 複数 url 制約を文書化
41
+
8
42
  ## [0.5.18] - 2026-05-12
9
43
 
10
44
  ### Fixed — Offline operation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdv-live",
3
- "version": "0.5.18",
3
+ "version": "0.5.19",
4
4
  "description": "Markdown Viewer - File tree + Live preview + Marp support + Hot reload",
5
5
  "main": "src/server.js",
6
6
  "bin": {
@@ -54,7 +54,7 @@ function renderText(content) {
54
54
  */
55
55
  function rewriteMediaPaths(html, relativeDir) {
56
56
  // Match src="..." that are not absolute URLs or data URIs
57
- return html.replace(
57
+ let out = html.replace(
58
58
  /(<(?:img|video|audio|source)\s[^>]*?\bsrc=")([^"]+)(")/gi,
59
59
  (match, before, src, after) => {
60
60
  if (/^(https?:\/\/|data:|\/raw\/|\/)/.test(src)) return match;
@@ -62,6 +62,34 @@ function rewriteMediaPaths(html, relativeDir) {
62
62
  return `${before}/raw/${resolved}${after}`;
63
63
  }
64
64
  );
65
+
66
+ // Marp `![bg](...)` renders as <figure style="background-image:url(...)">,
67
+ // never as an <img>, so the rule above never sees it. marp-core HTML-encodes
68
+ // the surrounding quotes (&quot;). For the quoted form the URL runs to the
69
+ // matching closing quote — not the first `)` — so filenames containing
70
+ // parentheses (e.g. "cover (1).png", which Marp emits as
71
+ // url(&quot;cover%20(1).png&quot;)) survive intact.
72
+ //
73
+ // Known limitation: only the first url() of a `background-image:` declaration
74
+ // is rewritten. Every `![bg]` produces its own <figure> with a single-url
75
+ // declaration, so this never affects `![bg]`; it only leaves later urls of a
76
+ // comma-separated `backgroundImage:` directive (a rare hand-authored case)
77
+ // SPA-relative. Bounding the declaration is unreliable because the encoded
78
+ // quote `&quot;` itself contains the `;` that would delimit it.
79
+ out = out.replace(
80
+ /background-image:\s*url\(\s*(?:(&quot;|"|')([\s\S]*?)\1|([^)\s'"]+))\s*\)/gi,
81
+ (match, quote, quotedSrc, bareSrc) => {
82
+ const src = quote ? quotedSrc : bareSrc;
83
+ // Empty quoted URL (url(&quot;&quot;)) — leave it alone, as the old
84
+ // pattern did; rewriting it to /raw/ would invent a bogus request.
85
+ if (!src || /^(https?:\/\/|data:|\/raw\/|\/)/.test(src)) return match;
86
+ const resolved = relativeDir ? `${relativeDir}/${src}` : src;
87
+ const q = quote || '';
88
+ return `background-image:url(${q}/raw/${resolved}${q})`;
89
+ }
90
+ );
91
+
92
+ return out;
65
93
  }
66
94
 
67
95
  /**