zenn-markdown-html 0.2.11-alpha.5 → 0.2.12-alpha.0
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/lib/index.d.ts +12 -1
- package/lib/index.js +37 -5
- package/lib/sanitizer.js +2 -2
- package/lib/utils/highlight.d.ts +48 -1
- package/lib/utils/highlight.js +244 -321
- package/lib/utils/md-renderer-fence.d.ts +89 -1
- package/lib/utils/md-renderer-fence.js +176 -20
- package/package.json +4 -6
- package/lib/prism-plugins/prism-diff-highlight.d.ts +0 -7
- package/lib/prism-plugins/prism-diff-highlight.js +0 -403
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { MarkdownOptions } from './types';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Markdown を HTML に変換する(非同期)
|
|
4
|
+
*
|
|
5
|
+
* Shiki によるシンタックスハイライトを使用。
|
|
6
|
+
* 詳細なアーキテクチャについては md-renderer-fence.ts のコメントを参照。
|
|
7
|
+
*
|
|
8
|
+
* 処理フロー:
|
|
9
|
+
* 1. [Phase 1] md.render() - Markdown を HTML に変換(コードブロックはプレースホルダーに)
|
|
10
|
+
* 2. [Phase 2 & 3] applyHighlighting() - プレースホルダーをハイライト済み HTML に置換
|
|
11
|
+
* 3. sanitize() - XSS 対策のためサニタイズ
|
|
12
|
+
*/
|
|
13
|
+
declare const markdownToHtml: (text: string, options?: MarkdownOptions) => Promise<string>;
|
|
3
14
|
export default markdownToHtml;
|
|
4
15
|
export { markdownToSimpleHtml } from './markdown-to-simple-html';
|
package/lib/index.js
CHANGED
|
@@ -27,13 +27,25 @@ var _mdImage = require("./utils/md-image");
|
|
|
27
27
|
var _mdContainer = require("./utils/md-container");
|
|
28
28
|
var _markdownToSimpleHtml = require("./markdown-to-simple-html");
|
|
29
29
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
30
|
-
//
|
|
30
|
+
// plugins
|
|
31
31
|
|
|
32
32
|
const mdContainer = require('markdown-it-container');
|
|
33
33
|
const mdFootnote = require('markdown-it-footnote');
|
|
34
34
|
const mdTaskLists = require('markdown-it-task-lists');
|
|
35
35
|
const mdInlineComments = require('markdown-it-inline-comments');
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Markdown を HTML に変換する(非同期)
|
|
39
|
+
*
|
|
40
|
+
* Shiki によるシンタックスハイライトを使用。
|
|
41
|
+
* 詳細なアーキテクチャについては md-renderer-fence.ts のコメントを参照。
|
|
42
|
+
*
|
|
43
|
+
* 処理フロー:
|
|
44
|
+
* 1. [Phase 1] md.render() - Markdown を HTML に変換(コードブロックはプレースホルダーに)
|
|
45
|
+
* 2. [Phase 2 & 3] applyHighlighting() - プレースホルダーをハイライト済み HTML に置換
|
|
46
|
+
* 3. sanitize() - XSS 対策のためサニタイズ
|
|
47
|
+
*/
|
|
48
|
+
const markdownToHtml = async (text, options) => {
|
|
37
49
|
if (!(text && text.length)) return '';
|
|
38
50
|
const markdownOptions = {
|
|
39
51
|
...options,
|
|
@@ -53,7 +65,10 @@ const markdownToHtml = (text, options) => {
|
|
|
53
65
|
fuzzyEmail: false
|
|
54
66
|
}); // refs: https://github.com/markdown-it/linkify-it
|
|
55
67
|
|
|
56
|
-
|
|
68
|
+
// コードブロック情報を保存する配列
|
|
69
|
+
// Phase 1 で mdRendererFence によって追加され、Phase 2 でハイライト処理に使用される
|
|
70
|
+
const codeBlocks = [];
|
|
71
|
+
md.use(_mdBr.mdBr).use(_mdKatex.mdKatex).use(mdFootnote).use(mdInlineComments).use(_markdownItImsize.default).use(_mdLinkAttributes.mdLinkAttributes).use(_mdCustomBlock.mdCustomBlock, markdownOptions).use(_mdRendererFence.mdRendererFence, markdownOptions, codeBlocks).use(_mdLinkifyToCard.mdLinkifyToCard, markdownOptions).use(mdTaskLists, {
|
|
57
72
|
enabled: true
|
|
58
73
|
}).use(mdContainer, 'details', _mdContainer.containerDetailsOptions).use(mdContainer, 'message', _mdContainer.containerMessageOptions).use(_markdownItAnchor.default, {
|
|
59
74
|
level: [1, 2, 3, 4],
|
|
@@ -73,8 +88,25 @@ const markdownToHtml = (text, options) => {
|
|
|
73
88
|
// - https://github.com/zenn-dev/zenn-community/issues/356
|
|
74
89
|
// - https://github.com/markdown-it/markdown-it-footnote/pull/8
|
|
75
90
|
const docId = _crypto.default.randomBytes(2).toString('hex');
|
|
76
|
-
|
|
91
|
+
|
|
92
|
+
// ============================================================
|
|
93
|
+
// Phase 1: Markdown → HTML 変換(同期)
|
|
94
|
+
// ============================================================
|
|
95
|
+
// markdown-it がコードブロックを検出すると mdRendererFence が呼ばれ、
|
|
96
|
+
// コードブロック情報が codeBlocks 配列に保存され、
|
|
97
|
+
// HTML にはプレースホルダー(<!--SHIKI_CODE_BLOCK_xxxxxxxx-->)が挿入される
|
|
98
|
+
const rawHtml = md.render(text, {
|
|
77
99
|
docId
|
|
78
|
-
})
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// ============================================================
|
|
103
|
+
// Phase 2 & 3: シンタックスハイライト適用(非同期)
|
|
104
|
+
// ============================================================
|
|
105
|
+
// - Phase 2: 全コードブロックを Shiki で並列ハイライト
|
|
106
|
+
// - Phase 3: プレースホルダーをハイライト済み HTML に置換
|
|
107
|
+
const highlightedHtml = await (0, _mdRendererFence.applyHighlighting)(rawHtml, codeBlocks);
|
|
108
|
+
|
|
109
|
+
// サニタイズして返す(XSS 対策)
|
|
110
|
+
return (0, _sanitizer.sanitize)(highlightedHtml);
|
|
79
111
|
};
|
|
80
112
|
var _default = exports.default = markdownToHtml;
|
package/lib/sanitizer.js
CHANGED
|
@@ -33,10 +33,10 @@ const attributes = {
|
|
|
33
33
|
li: ['class', 'id', 'data-line'],
|
|
34
34
|
ol: ['class', 'start', 'data-line'],
|
|
35
35
|
p: ['class', 'data-line'],
|
|
36
|
-
pre: ['class'],
|
|
36
|
+
pre: ['class', 'style'],
|
|
37
37
|
s: [],
|
|
38
38
|
section: ['class', 'data-line'],
|
|
39
|
-
span: ['class', 'title'],
|
|
39
|
+
span: ['class', 'style', 'title'],
|
|
40
40
|
strong: [],
|
|
41
41
|
summary: [],
|
|
42
42
|
sup: ['class'],
|
package/lib/utils/highlight.d.ts
CHANGED
|
@@ -1 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Shiki によるシンタックスハイライト処理
|
|
3
|
+
*
|
|
4
|
+
* このモジュールは Phase 2(applyHighlighting)から呼び出され、
|
|
5
|
+
* 個々のコードブロックをハイライトする役割を持つ。
|
|
6
|
+
*
|
|
7
|
+
* ## 特徴
|
|
8
|
+
*
|
|
9
|
+
* - シングルトン: ハイライターインスタンスは1つだけ作成され再利用される
|
|
10
|
+
* - 遅延ロード: 言語定義は初回使用時にのみロードされる
|
|
11
|
+
* - diff サポート: ベース言語のハイライト + diff 背景色の両方を適用
|
|
12
|
+
* - transformers: Shiki の transformers API で AST レベルの変換を実行
|
|
13
|
+
*
|
|
14
|
+
* ## 関連ファイル
|
|
15
|
+
*
|
|
16
|
+
* - `md-renderer-fence.ts`: Phase 1(収集)と Phase 3(置換)
|
|
17
|
+
* - `index.ts`: 全体の統合
|
|
18
|
+
*/
|
|
19
|
+
import { Highlighter } from 'shiki';
|
|
20
|
+
/**
|
|
21
|
+
* Shiki ハイライターを初期化する
|
|
22
|
+
* 最初は最低限のセットで初期化し、必要に応じて言語をロードする
|
|
23
|
+
*/
|
|
24
|
+
export declare function getHighlighter(): Promise<Highlighter>;
|
|
25
|
+
/**
|
|
26
|
+
* ハイライトオプション
|
|
27
|
+
*/
|
|
28
|
+
export interface HighlightOptions {
|
|
29
|
+
/** diff モードかどうか */
|
|
30
|
+
hasDiff: boolean;
|
|
31
|
+
/** 追加するクラス名 */
|
|
32
|
+
className: string;
|
|
33
|
+
/** Markdown ソースの行番号(ソースマップ用) */
|
|
34
|
+
line?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* [Phase 2 の実処理] コードをハイライトする
|
|
38
|
+
*
|
|
39
|
+
* applyHighlighting() から各コードブロックに対して呼び出される。
|
|
40
|
+
* 言語が未ロードの場合は自動的にロードする(遅延ロード)。
|
|
41
|
+
* Shiki の transformers API を使用して AST レベルで変換を行う。
|
|
42
|
+
*
|
|
43
|
+
* @param text - ハイライト対象のコード文字列
|
|
44
|
+
* @param langName - 言語名(例: "javascript", "python")
|
|
45
|
+
* @param options - ハイライトオプション
|
|
46
|
+
* @returns ハイライト済み HTML(常に <pre><code> 構造)
|
|
47
|
+
*/
|
|
48
|
+
export declare function highlight(text: string, langName: string, options: HighlightOptions): Promise<string>;
|