mirror of
https://github.com/pdfme/pdfme.git
synced 2026-06-16 18:29:17 -04:00
14 KiB
14 KiB
JSX / md2pdf ロードマップ
最終更新: 2026-05-07
目的
@pdfme/jsx で stacking layout を使った template authoring を整備し、その考え方を
converter package の md2pdf に応用する。md2pdf MVP では Markdown/GFM AST から通常の
pdfme Template と inputs を生成でき、default style も一段整った。次は examples / docs で
使い方と制約を説明し、その後に layout 品質と rich content の応用範囲を広げる。
基本方針
- Markdown 文書全体を 1 つの巨大な schema に押し込まない。
- GFM AST を layout tree に変換し、
text,multiVariableText,list,table,image,line,rectangleなど複数の schema に分解する。 @pdfme/jsxは、その layout tree を手で書く authoring DSL として扱う。md2pdfは Markdown AST から同じ方向の layout tree を作る別 frontend として扱う。@pdfme/jsxは generator の必須依存にしない。出力は通常の pdfmeTemplateとinputsにする。- AI が template を生成する時も、絶対座標 JSON を直接作るより、
Stack,Row,Box,Text,List,Tableなどの意味構造から template に変換する方が失敗しにくい。 - GFM 準拠だけにこだわりすぎない。PDF 生成として自然で便利な表現は pdfme の拡張として扱い、 GFM との差分は docs に明記する。
次に進めること
1. @pdfme/jsx examples / docs
- beta として試せる
/jsxplayground を追加する。左に JSX editor、右に pdfme Viewer preview を置く 2 カラム構成にする。 - JSX editor の出力は
renderToTemplateに渡し、通常の pdfmeTemplate + inputsとして preview する。 - 生成した template JSON を download できるようにする。必要なら PDF generation と render time 表示も
md2pdfplayground と揃える。 - 最初の examples は invoice / report / article / header-footer / absolute badge など、AI や人間が 真似しやすいものに絞る。
md2pdf/jsxplayground は、将来それぞれ複数の sample preset を切り替えられるようにする。Static,Header,Footer,Absolute, dynamic height,Text/MultiVariableText,Image/Svg/ visual schemas,List/Tableの使いどころを docs に整理する。- website docs に
@pdfme/jsxの beta ページを追加する。jsxImportSource,renderToTemplate,Template + inputs, current limitations, playground link を載せる。
2. playground editor の Monaco 統一
- Template JSON dialog、
md2pdfeditor、新しい JSX playground editor を共通の Monaco editor component に寄せる。 - language は JSON / Markdown / TypeScript-TSX を使い分ける。theme は Monaco の system/default に寄せる。
- Template JSON dialog の embedded asset placeholder 保護は維持する。Monaco 化しても Commit 前に
restoreEmbeddedAssetsFromPlaceholdersとcheckTemplateを通す。 @monaco-editor/react+monaco-editorを使う。Vite worker は明示し、必要な language contribution だけを読む。
3. JSX playground の TSX evaluation 方針
- beta では任意 import を実行する playground にしない。
Page,Stack,Row,Box,Text,MultiVariableText,List,Table,Image,Svg,Rectangle,Ellipse,Line,Header,Footer,Absoluteなどを評価スコープに渡す。 - editor の入力はまず
return (<Page>...</Page>);のような function body 形式を採用する。Sucrase で JSX をcreateElement(...)call に落とし、bare module import を browser runtime で解決する問題を避ける。 - evaluation は main thread ではなく Web Worker 側で行い、common browser globals は beta playground では ブロックする。完全な untrusted-code sandbox としては扱わない。
- 将来、copy-paste しやすい full module 形式 (
import ... from "@pdfme/jsx"; export default ...) を 受けたい場合は、import stripping / sandbox / Blob module resolution を別途設計する。 - preview 更新は debounce し、compile / render error を editor 下か viewer header に表示する。
4. playground / examples UX フォローアップ
- JSX playground は Viewer だけでなく Form preview も切り替えられるようにする。生成 template から Designer に遷移する導線も検討する。
- JSX static schema API は、
Header/Footer/Staticが後続Pageに暗黙反映される点と、 page margin の影響を受けない点が直感に反する。Documentcomponent をPageの上位に置き、Document内にHeader/Footer/Staticを宣言する API も含めて、react-pdf の component model を参考に再設計を検討する。 - Template 一覧は template type に応じて Designer / FormViewer /
md2pdf/jsxplayground へ 遷移する導線を検討する。ただし preset が増えた時に一覧性が落ちないかも検証する。 - playground の
localStorage保存運用は、preset / draft / imported template の扱いが混ざりやすい。 永続化スコープ、reset、共有可能 URL、保存済み template の見せ方を整理する。
5. md2pdf layout 品質フォローアップ
- heading 直後の keep-with-next、table / image / code block の keep-together、widow/orphan を検討する。
- 長い paragraph / list / table は generator dynamic layout に任せる方針を維持する。
- blockquote / code block / complex list item が既存 schema split で足りるかを検証する。
6. md2pdf assets / rich content 方針
- remote image は converter 内で fetch して data URI 化するか、引き続き link fallback とするかを決める。
Template + inputsAPI を崩さずに済むなら、まず converter 内 fetch + data URI 化を検討する。- table cell / list item 内の bold, italic, inline code, link を schema 拡張で保持するか、複数 schema に 分解するかを後で決める。完璧な GFM より PDF として破綻しないことを優先する。
7. @pdfme/jsx layout 品質フォローアップ
- CSS/Flexbox 互換を目指さず、flexbox の使いやすさだけを
Stack/Rowに取り込む。 flexWrap,flexShrink, media query, fullstyleprop, CSS parser は当面対象外。%width は将来検討でよい。まずはflex/flexGrowで比率指定を表現する。AbsoluteはPage, topStatic,Box内の小さな escape hatch として扱う。Stack/Row直下対応、anchor / top-right / bottom-right shorthand、z-index 的な描画順制御は必要性が出てから検討する。
仕様メモ
- リンクは文章中で使われることが多いため、
text/ rich text run の一部として扱う。独立linkschema は、画像全体・カード全体などクリック領域が必要になった時に再検討する。 - ページ内リンクは新しい
anchorIdfield を増やさず、schema.nameを anchor として使う。 JSX / Markdown 側でidを受ける場合も template へ落とす時点ではnameに寄せる。 overflow: "expand"は blank PDF 向けの dynamic layout。custombasePdfでは Designer で 選択不可にし、既存値も effectivevisibleとして扱う。overflow: "expand"とdynamicFontSizeは同時利用不可。expandでは通常のfontSizeで 高さを広げる。- split metadata は
__splitRange: { unit, start, end }に統一済み。通常の authoring API では 直接触らない。 textschema の inline-markdown split chunk は Form 上では read-only のまま。MVT は plain / inline-markdown ともに変数値だけ編集できる。- MVT split chunk の連続編集は、各 blur 後に reflow された最新 input を次の chunk が受け取る 前提で扱う。plain / inline-markdown ともに回帰テストで固定する。
@pdfme/jsxのTextcomponent は read-only authoring が主用途。editableTextにはtextFormat: "inline-markdown"を指定できないようにする。- MVT の static link は Form 上でも clickable。変数 span が link run に含まれる場合は入力を優先する。
- link の見た目はデフォルトで青 + 下線にする。将来的には theme / style でカスタマイズできるようにする。
- Designer の link 編集は、当面 inline-markdown 文字列を直接編集する前提にする。専用 UI は後回し。
md2pdfの初期 API はTemplate + inputsを返す形でよい。warnings / assets / anchors metadata は 必要になった時に追加検討する。Absoluteは flow に参加しない overlay。座標は親の layout frame 基準で、Pagebody 内では page margin 内、Static内では page 全体、Box内では box content frame。bottomStatic内では使えない。- text / MVT の
padding,borderWidth,borderColorは table cell と共通の box helper で扱う。overflow: "expand"で行分割される場合は、左右の padding / border は各 chunk に残し、上辺は最初の chunk、下辺は最後の chunk だけに残す。 - text / MVT の background / padding / border は schema box の装飾として扱う。content が空でも background / border は描画される。
GFM / md2pdf で足りないこと
Inline / Rich Text
- GFM link / autolink は linked rich text run に変換する。
- heading link は slug を作り、対応する heading schema の
nameにする。 inline-markdownは部分的な下線も表現できるようにしたい。これは GFM にはないが PDF では有用。- table cell / list item 内の bold, italic, inline code, link をどう保持するか決める。
- pdfme の
inline-markdownは Designer 上の軽量記法として残し、GFM 完全対応は converter 側の AST pipeline に寄せる。
Block Layout
- GFM list item は paragraph, nested list, code block, blockquote を含められる。MVP では
listschema のstring[] + tab indentに落とすが、複雑な list item は表現しきれない可能性がある。 - task list は MVP では
[x]/[ ]prefix に落とす。checkbox + text/list の組み合わせや list schema 拡張は後回し。 - GFM table の基本形は
tableschema に落とす。MVP では cell 内 rich inline content は plain text に落とし、装飾や link は保持しない。 - code block は
text+ background + padding + border で始める。等幅フォント、空白保持、長い行、 syntax highlight、ページ分割を考えると専用 layout が欲しい。 - blockquote は
text+ background + left border + padding で始める。中に paragraph / list / code / table を持てる点に 注意する。 - remote Markdown image と
[](url)は image fetch / link annotation の設計が必要。
Pagination
- Markdown paragraph は可変長なので、
overflow: "expand"と dynamic template reflow を自然に使う。 - 長文 text / MVT は行単位分割できる。code block / blockquote / 複雑な list item は既存 schema の split で足りるか、container 単位の分割が必要かを検証する。
- keep-together、widow/orphan、live pagination は layout 品質改善の中で扱う。
完了済み
- PR #1463: text inline-markdown link、PDF URI / GoTo annotation、basePdf 由来 URI link 保持。
- PR #1466:
@pdfme/jsxMVP、独自 JSX runtime、Page/Stack/Row/Box/Text/List/Table/PageBreak、page size 共通化、schema 型 export。 - PR #1467: text / MVT の
overflow: "expand"、grow-only dynamic height、行単位 split、expandとdynamicFontSizeの排他仕様。 - PR #1469:
__bodyRange/__itemRange/__textLineRangeを__splitRangeに統一。 - PR #1470: custom
basePdfでは text / MVT のoverflow: "expand"を選択不可にする。 - PR #1471: dynamic layout docs を追加。
- PR #1472: plain MVT split chunk の Form 変数編集。
- PR #1474: inline-markdown MVT split chunk の Form 変数編集、static link の clickable 表示。
- PR #1475:
@pdfme/jsxMultiVariableTextcomponent。 - PR #1476:
@pdfme/jsxImage,Svg,Rectangle,Ellipse,Linevisual components。 - PR #1477:
@pdfme/jsxeditableTextでtextFormat: "inline-markdown"を禁止。 - PR #1478: MVT split chunk の連続編集を plain / inline-markdown ともに回帰テストで固定。
- PR #1479:
@pdfme/jsxlayout にmarginとalignItemsを追加。 - PR #1480:
@pdfme/jsxlayout にjustifyContent,flexGrow,flexを追加。 - PR #1481:
@pdfme/jsxStatic placement="top" | "bottom"、Header/Footeralias、 blankbasePdf.staticSchemasupport を追加。 - PR #1482:
@pdfme/jsxAbsolutemanual placement helper を追加。 - PR #1483:
@pdfme/converter/md2pdfMVP。GFM paragraph / heading / list / table / code block / blockquote / horizontal rule / link / PNG-JPEG data URI image をTemplate + inputsに変換する subpath export を追加。pagination は generator dynamic layout に任せ、CJK / 日本語フォント導線も README とテストで固定。 - PR #1485:
md2pdfdefault style 品質改善。table grid、code block background + padding、 blockquote left rule、horizontal rule color などを調整し、text / MVT にpadding,borderWidth,borderColorを追加して table cell と共通の box helper に寄せた。
参考
- pdfme issue #319: HyperLink Schema の追加
- pdfme issue #239:
generateによってbasePdfのリンクが消える問題 - pdfme issue #851: text schema に padding / border options を追加する要望
- pdf-lib issue #555: 低レベルなリンク annotation 実装についての議論
- GFM spec