mdv-live 0.5.0 → 0.5.2

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,14 @@ 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.1] - 2026-03-20
9
+
10
+ ### Fixed
11
+
12
+ - Edit mode + PDF export bug: exporting PDF while in edit mode produced raw markdown text instead of rendered slides
13
+ - Now auto-exits edit mode before PDF generation
14
+ - Uses `tab.isMarp` fallback for Marp detection when DOM is not yet rendered
15
+
8
16
  ## [0.4.3] - 2026-02-15
9
17
 
10
18
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdv-live",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Markdown Viewer - File tree + Live preview + Marp support + Hot reload",
5
5
  "main": "src/server.js",
6
6
  "bin": {
@@ -5,6 +5,73 @@
5
5
  import MarkdownIt from 'markdown-it';
6
6
  import taskLists from 'markdown-it-task-lists';
7
7
 
8
+ /**
9
+ * markdown-it plugin: CJK + Unicode句読点で emphasis が壊れる問題を修正。
10
+ *
11
+ * 根本原因: CommonMark の flanking delimiter 判定は、delimiter の隣が
12
+ * Unicode句読点のとき、反対側も空白か句読点でないと flanking と認めない。
13
+ * right_flanking = !isLastWS && (!isLastPunct || isNextWS || isNextPunct)
14
+ * left_flanking = !isNextWS && (!isNextPunct || isLastWS || isLastPunct)
15
+ *
16
+ * ラテン文字圏では妥当だが、CJK文字(漢字・ひらがな・カタカナ)は
17
+ * 空白でも句読点でもないため、「)**を」のような配置で flanking 判定が
18
+ * 不当に失敗する。
19
+ *
20
+ * 修正方針: flanking 判定の条件式に「反対側がCJKテキスト文字なら、
21
+ * 句読点の隣接制限を免除する」条件を追加する。
22
+ * CJKは語境界を空白で示さないため、句読点の隣にCJKがあっても
23
+ * delimiter は flanking と見なすのが自然。
24
+ *
25
+ * isWhiteSpace / isPunct の分類は変えない。flanking 条件式だけを拡張する。
26
+ */
27
+ function cjkEmphasisFix(md) {
28
+ const StateInline = md.inline.State;
29
+ const origScanDelims = StateInline.prototype.scanDelims;
30
+
31
+ // CJKテキスト文字(句読点・記号は含めない)
32
+ // Hiragana, Katakana, CJK Unified Ideographs, CJK Ext-A,
33
+ // Hangul Syllables, CJK Compatibility Ideographs
34
+ const CJK_TEXT_RE = /[\u3040-\u30FF\u3400-\u4DBF\u4E00-\u9FFF\uAC00-\uD7AF\uF900-\uFAFF]/;
35
+
36
+ StateInline.prototype.scanDelims = function (start, canSplitWord) {
37
+ const result = origScanDelims.call(this, start, canSplitWord);
38
+
39
+ // 元の判定で OK なら何もしない
40
+ if (result.can_open && result.can_close) return result;
41
+
42
+ // delimiter の前後の文字を取得
43
+ const max = this.posMax;
44
+ const marker = this.src.charCodeAt(start);
45
+ let pos = start;
46
+ while (pos < max && this.src.charCodeAt(pos) === marker) { pos++; }
47
+
48
+ const lastChar = start > 0 ? this.src.charAt(start - 1) : '';
49
+ const nextChar = pos < max ? this.src.charAt(pos) : '';
50
+
51
+ const lastIsCJK = CJK_TEXT_RE.test(lastChar);
52
+ const nextIsCJK = CJK_TEXT_RE.test(nextChar);
53
+
54
+ // CJKテキスト文字が delimiter の反対側にあるなら、
55
+ // 句読点隣接による flanking 拒否を解除する。
56
+ //
57
+ // can_close が false になるケース:
58
+ // lastChar=句読点, nextChar=CJK → right_flanking が false
59
+ // → nextIsCJK なら can_close = true に補正
60
+ //
61
+ // can_open が false になるケース:
62
+ // lastChar=CJK, nextChar=句読点 → left_flanking が false
63
+ // → lastIsCJK なら can_open = true に補正
64
+ if (!result.can_close && nextIsCJK) {
65
+ result.can_close = true;
66
+ }
67
+ if (!result.can_open && lastIsCJK) {
68
+ result.can_open = true;
69
+ }
70
+
71
+ return result;
72
+ };
73
+ }
74
+
8
75
  // Initialize markdown-it with options
9
76
  const md = new MarkdownIt({
10
77
  html: true,
@@ -13,6 +80,9 @@ const md = new MarkdownIt({
13
80
  linkify: true
14
81
  });
15
82
 
83
+ // Fix CJK emphasis issues before other plugins
84
+ md.use(cjkEmphasisFix);
85
+
16
86
  // Enable tables and strikethrough
17
87
  md.enable('table');
18
88
  md.enable('strikethrough');
package/src/static/app.js CHANGED
@@ -1329,7 +1329,12 @@
1329
1329
 
1330
1330
  const tab = state.tabs[state.activeTabIndex];
1331
1331
 
1332
- if (this.isMarpPresentation()) {
1332
+ // editモード中は閉じてからPDF生成
1333
+ if (state.isEditMode) {
1334
+ await EditorManager.toggle();
1335
+ }
1336
+
1337
+ if (tab.isMarp || this.isMarpPresentation()) {
1333
1338
  await this.exportMarpPdf(tab.path);
1334
1339
  } else if (this.isHtmlPreview()) {
1335
1340
  this.printHtmlPreview(tab.name);