• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yunnysunny / bookforge / 20639889242

01 Jan 2026 02:03PM UTC coverage: 55.087% (-36.6%) from 91.667%
20639889242

push

github

web-flow
feat: add notion support

27 of 51 branches covered (52.94%)

Branch coverage included in aggregate %.

75 of 221 new or added lines in 12 files covered. (33.94%)

195 of 352 relevant lines covered (55.4%)

23.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

20.59
/src/core/marked-plugins/gitbook.plugin.ts
1
import { marked, type MarkedExtension, type Tokens } from 'marked';
2

3
// ========================
4
// 1. GitBook 标签渲染器
5
// ========================
6
const gitbookTagRenderers: Record<
7
  string,
8
  (text: string, params: Record<string, string>) => string
9
> = {
12✔
10
  // Callout
NEW
11
  note: (text) => `<div class="gb-note">${marked.parse(text)}</div>`,
×
NEW
12
  warning: (text) => `<div class="gb-warning">${marked.parse(text)}</div>`,
×
NEW
13
  tip: (text) => `<div class="gb-tip">${marked.parse(text)}</div>`,
×
NEW
14
  info: (text) => `<div class="gb-info">${marked.parse(text)}</div>`,
×
NEW
15
  danger: (text) => `<div class="gb-danger">${marked.parse(text)}</div>`,
×
NEW
16
  success: (text) => `<div class="gb-success">${marked.parse(text)}</div>`,
×
17

18
  // code block
19
  codeblock: (text, params) =>
NEW
20
    `<pre><code class="language-${params.lang || ''}">${text}</code></pre>`,
×
21

22
  // tabs / tab
23
  tab: (text, params) =>
NEW
24
    `<div class="gb-tab" data-title="${params.title || ''}">${marked.parse(
×
25
      text,
26
    )}</div>`,
NEW
27
  tabs: (text) => `<div class="gb-tabs">${marked.parse(text)}</div>`,
×
28
};
29

30
// ========================
31
// 2. 解析参数 key="value"
32
// ========================
33
/** 解析 GitBook 参数,如 style="info" lang="ts" */
34
function parseParams(str: string) {
NEW
35
  const params: Record<string, string> = {};
×
NEW
36
  const re = /(\w+)="(.*?)"/g;
×
NEW
37
  let m: RegExpExecArray | null = null;
×
NEW
38
  while (true) {
×
NEW
39
    m = re.exec(str);
×
NEW
40
    if (!m) break;
×
NEW
41
    params[m[1]] = m[2];
×
42
  }
NEW
43
  return params;
×
44
}
45
interface GitbookTagToken extends Tokens.Generic {
46
  tag: string;
47
  params: Record<string, string>;
48
  text: string;
49
  raw: string;
50
  type: 'gb-tag';
51
}
52
export const gitbookExtension: MarkedExtension = {
12✔
53
  extensions: [
54
    {
55
      name: 'gb-tag',
56
      level: 'block',
57
      start(src: string) {
58
        return src.match(/\{%/)?.index;
42✔
59
      },
60
      tokenizer(src: string): GitbookTagToken | undefined {
61
        const rule = /^\{% (\w+)(.*?) %\}([\s\S]*?)\{% end\1 %\}/;
99✔
62
        const match = rule.exec(src);
99✔
63
        if (!match) return;
99✔
64

NEW
65
        const [, tag, paramStr, content] = match;
×
NEW
66
        return {
×
67
          type: 'gb-tag',
68
          raw: match[0],
69
          tag,
70
          params: parseParams(paramStr),
71
          text: content.trim(),
72
        };
73
      },
74
      renderer(token: Tokens.Generic) {
NEW
75
        const _token = token as GitbookTagToken;
×
NEW
76
        const fn = gitbookTagRenderers[_token.tag];
×
NEW
77
        if (fn) return fn(_token.text, _token.params);
×
NEW
78
        return _token.raw; // 未知标签原样输出
×
79
      },
80
    },
81
  ],
82
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc