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
|
const parseSourceFile = raw => {
const frontMatterRegex = /(^---$[\s\S]*?^---$)/m;
const preGroupedRegex = /([\s\S]*?)(^---$[\s\S]*?^---$)(\s*)([\s\S]*)/m; // preFrontMatter, frontMatter, spacing, and content
let initial;
let editable;
const hasFrontMatter = source => frontMatterRegex.test(source);
const buildPayload = (source, header, spacing, body) => {
return { raw: source, header, spacing, body };
};
const parse = source => {
if (hasFrontMatter(source)) {
const match = source.match(preGroupedRegex);
const [, preFrontMatter, frontMatter, spacing, content] = match;
const header = preFrontMatter + frontMatter;
return buildPayload(source, header, spacing, content);
}
return buildPayload(source, '', '', source);
};
const syncEditable = () => {
/*
We re-parse as markdown editing could have added non-body changes (preFrontMatter, frontMatter, or spacing).
Re-parsing additionally gets us the desired body that was extracted from the potentially mutated editable.raw
*/
editable = parse(editable.raw);
};
const syncBodyToRaw = () => {
editable.raw = `${editable.header}${editable.spacing}${editable.body}`;
};
const sync = (newVal, isBodyToRaw) => {
const editableKey = isBodyToRaw ? 'body' : 'raw';
editable[editableKey] = newVal;
if (isBodyToRaw) {
syncBodyToRaw();
}
syncEditable();
};
const content = (isBody = false) => {
const editableKey = isBody ? 'body' : 'raw';
return editable[editableKey];
};
const isModified = () => initial.raw !== editable.raw;
initial = parse(raw);
editable = parse(raw);
return {
content,
isModified,
sync,
};
};
export default parseSourceFile;
|