This repository was archived by the owner on May 29, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 75
Expand file tree
/
Copy pathindex.ts
More file actions
96 lines (81 loc) 路 3.05 KB
/
Copy pathindex.ts
File metadata and controls
96 lines (81 loc) 路 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import type Format from '../block/base/format';
import type ParagraphContent from '../block/content/paragraphContent';
import type { Muya } from '../muya';
import logger from '../utils/logger';
import type { ICursor } from '../selection/types';
import type { IParagraphState, TContainerState, TState } from '../state/types';
import { tokenizer } from './lexer';
import Renderer from './renderer';
import { beginRules } from './rules';
import type { IHighlight, Labels } from './types';
const debug = logger('inlineRenderer:');
class InlineRenderer {
public labels: Labels = new Map();
public renderer: Renderer;
constructor(public muya: Muya) {
this.renderer = new Renderer(muya, this);
}
tokenizer(block: Format, highlights: IHighlight[]) {
const { options } = this.muya;
const { text } = block;
const { labels } = this;
// TODO: different content block should have different rules.
// eg: atxheading.content has no soft|hard line break
// setextheading.content has no heading rules.
const hasBeginRules
= /thematicbreak\.content|paragraph\.content|atxheading\.content/.test(
block.blockName,
);
return tokenizer(text, { hasBeginRules, labels, options, highlights });
}
patch(block: Format, cursor?: ICursor, highlights: IHighlight[] = []) {
this.collectReferenceDefinitions();
const { domNode } = block;
if (block.isParent())
debug.error('Patch can only handle content block');
const tokens = this.tokenizer(block, highlights);
const html = this.renderer.output(
tokens,
block,
cursor && cursor.block === block ? cursor : {},
);
if (domNode!.innerHTML !== html) {
domNode!.innerHTML = html;
}
}
collectReferenceDefinitions() {
const state = this.muya.editor.jsonState.getState();
const labels = new Map();
const travel = (sts: TState[]) => {
if (Array.isArray(sts) && sts.length) {
for (const st of sts) {
if (st.name === 'paragraph') {
const { label, info } = this.getLabelInfo(st);
if (label && info)
labels.set(label, info);
}
else if ((st as TContainerState).children) {
travel((st as TContainerState).children);
}
}
}
};
travel(state);
this.labels = labels;
}
getLabelInfo(blockOrState: ParagraphContent | IParagraphState) {
const { text } = blockOrState;
const tokens = beginRules.reference_definition.exec(text);
let label = null;
let info = null;
if (tokens) {
label = (tokens[2] + tokens[3]).toLowerCase();
info = {
href: tokens[6],
title: tokens[10] || '',
};
}
return { label, info };
}
}
export default InlineRenderer;