Skip to content

Commit dab6332

Browse files
committed
fix(html-format): collapsed span breaks obsidian parser
1 parent a53e32e commit dab6332

11 files changed

Lines changed: 113 additions & 142 deletions
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { level } from 'src/lib/data-conversion/helpers/html-comment-marker/create-html-comment-marker';
2+
3+
export const collapsedSpanMarker = (parentNumber: string, index: number) =>
4+
`<span data-section="${level(parentNumber, index)}"/>`;
5+
6+
export const expandedSpanMarker = (parentNumber: string, index: number) =>
7+
`<span data-section="${level(parentNumber, index)}"></span>`;

src/lib/data-conversion/helpers/html-element-marker/create-html-element-marker.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/lib/data-conversion/helpers/html-element-marker/parse-html-element-marker.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { describe, expect, it } from 'vitest';
2-
import { createHtmlElementMarker } from 'src/lib/data-conversion/helpers/html-element-marker/create-html-element-marker';
2+
import { collapsedSpanMarker } from 'src/lib/data-conversion/helpers/html-element-marker/collapsed-span-marker';
33
import { parseHtmlElementMarker } from 'src/lib/data-conversion/helpers/html-element-marker/parse-html-element-marker';
44

55
describe('parseHtmlElementMarker', () => {
66
it('case 1', () => {
7-
const input = createHtmlElementMarker('3.2', 2);
7+
const input = collapsedSpanMarker('3.2', 2);
88
const output = ['3.2', '2', '3.2.2'];
99
expect(parseHtmlElementMarker(input)).toEqual(output);
1010
});
1111
it('case 2', () => {
12-
const input = createHtmlElementMarker('3.2.1.1', 2);
12+
const input = collapsedSpanMarker('3.2.1.1', 2);
1313
const output = ['3.2.1.1', '2', '3.2.1.1.2'];
1414
expect(parseHtmlElementMarker(input)).toEqual(output);
1515
});

src/lib/data-conversion/helpers/html-element-marker/parse-html-element-marker.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
export const htmlCommentRegex = /<span data-section="((\d\.?)*(\d))"\s*\/>/;
1+
export const htmlElementRegex =
2+
/<span data-section="((\d\.?)*(\d))"\s*(\/>|><\/span>)/;
23
export const parseHtmlElementMarker = (line: string) => {
3-
const results = htmlCommentRegex.exec(line);
4+
const results = htmlElementRegex.exec(line);
45
if (results) {
56
const result = results[1];
67
const split = result.split('.');

src/lib/data-conversion/json-to-x/json-to-html-element.spec.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { describe, expect, it } from 'vitest';
22
import { TreeNode } from 'src/lib/data-conversion/x-to-json/columns-to-json';
3-
import { createHtmlElementMarker } from 'src/lib/data-conversion/helpers/html-element-marker/create-html-element-marker';
3+
import {
4+
collapsedSpanMarker,
5+
expandedSpanMarker,
6+
} from 'src/lib/data-conversion/helpers/html-element-marker/collapsed-span-marker';
47
import { jsonToHtmlElement } from 'src/lib/data-conversion/json-to-x/json-to-html-element';
58
import { ginkgo_welcome } from 'src/lib/data-conversion/test-data/ginkgo_welcome';
69
import { ginkgo_academic_paper } from 'src/lib/data-conversion/test-data/ginkgo_acedemic_paper';
@@ -18,9 +21,9 @@ describe('json to html element', () => {
1821
},
1922
];
2023
const output = [
21-
createHtmlElementMarker('', 1) + 'one',
24+
collapsedSpanMarker('', 1) + 'one',
2225
'',
23-
createHtmlElementMarker('1', 1) + 'one > one',
26+
collapsedSpanMarker('1', 1) + 'one > one',
2427
];
2528
expect(jsonToHtmlElement(input)).toEqual(output.join('\n'));
2629
});
@@ -50,17 +53,17 @@ describe('json to html element', () => {
5053
},
5154
];
5255
const output = [
53-
createHtmlElementMarker('', 1) + 'one',
56+
collapsedSpanMarker('', 1) + 'one',
5457
'',
55-
createHtmlElementMarker('1', 1) + 'one > one',
58+
collapsedSpanMarker('1', 1) + 'one > one',
5659
'',
57-
createHtmlElementMarker('1.1', 1) + 'one > one > one',
60+
collapsedSpanMarker('1.1', 1) + 'one > one > one',
5861
'',
59-
createHtmlElementMarker('', 2) + 'two',
62+
collapsedSpanMarker('', 2) + 'two',
6063
'',
61-
createHtmlElementMarker('2', 1) + 'two > one',
64+
collapsedSpanMarker('2', 1) + 'two > one',
6265
'',
63-
createHtmlElementMarker('2.1', 1) + 'two > one > one',
66+
collapsedSpanMarker('2.1', 1) + 'two > one > one',
6467
];
6568
expect(jsonToHtmlElement(input)).toEqual(output.join('\n'));
6669
});
@@ -76,16 +79,16 @@ describe('json to html element', () => {
7679
];
7780

7881
const output = [
79-
createHtmlElementMarker('', 1) + '1a',
82+
collapsedSpanMarker('', 1) + '1a',
8083
'1b',
8184
'',
82-
createHtmlElementMarker('1', 1) + '1.1a',
85+
collapsedSpanMarker('1', 1) + '1.1a',
8386
'1.1b',
8487
'',
85-
createHtmlElementMarker('', 2) + '2a',
88+
collapsedSpanMarker('', 2) + '2a',
8689
'2b',
8790
'',
88-
createHtmlElementMarker('', 3) + '3',
91+
collapsedSpanMarker('', 3) + '3',
8992
];
9093
expect(jsonToHtmlElement(input)).toEqual(output.join('\n'));
9194
});
@@ -130,13 +133,17 @@ describe('json to html element', () => {
130133
];
131134

132135
const output = [
133-
'- [x] ' + createHtmlElementMarker('', 1) + 'task',
136+
expandedSpanMarker('', 1),
137+
'- [x] task',
134138
'',
135-
'- [ ] ' + createHtmlElementMarker('1', 1) + 'sub task',
139+
expandedSpanMarker('1', 1),
140+
'- [ ] sub task',
136141
'',
137-
'* [x] ' + createHtmlElementMarker('', 2) + '[[task]]',
142+
expandedSpanMarker('', 2),
143+
'* [x] [[task]]',
138144
'',
139-
'+ [/] ' + createHtmlElementMarker('', 3) + '[[task]]',
145+
expandedSpanMarker('', 3),
146+
'+ [/] [[task]]',
140147
];
141148
expect(jsonToHtmlElement(input)).toEqual(output.join('\n'));
142149
});
@@ -149,7 +156,7 @@ describe('json to html element', () => {
149156
},
150157
];
151158

152-
const output = ['#🙄' + createHtmlElementMarker('', 1) + ' text'];
159+
const output = [expandedSpanMarker('', 1), '#🙄 text'];
153160
expect(jsonToHtmlElement(input)).toEqual(output.join('\n'));
154161
});
155162

src/lib/data-conversion/json-to-x/json-to-html-element.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { TreeNode } from 'src/lib/data-conversion/x-to-json/columns-to-json';
22
import { level } from 'src/lib/data-conversion/helpers/html-comment-marker/create-html-comment-marker';
3-
import { createHtmlElementMarker } from 'src/lib/data-conversion/helpers/html-element-marker/create-html-element-marker';
3+
import {
4+
collapsedSpanMarker,
5+
expandedSpanMarker,
6+
} from 'src/lib/data-conversion/helpers/html-element-marker/collapsed-span-marker';
47

58
export const jsonToHtmlElement = (
69
tree: TreeNode[],
@@ -15,34 +18,33 @@ export const jsonToHtmlElement = (
1518

1619
let content = node.content.trimStart();
1720

18-
const marker = createHtmlElementMarker(parentNumber, index);
21+
const expandedSpan = expandedSpanMarker(parentNumber, index);
1922
if (content.match(/^#+ /)) {
2023
// an additional '\n' is needed as a workaround for a bug in obsidian
21-
content = `${marker}\n\n${content}`;
24+
content = `${expandedSpan}\n${content}`;
2225
} else if (content.match(/^#[^\s#\uFEFF\u200B]+/)) {
23-
// BOM (\uFEFF) and zero-width spaces (\u200B) are matched to avoid issues with emojis
24-
const tag = content.match(/^#[^\s#\uFEFF\u200B]+/)?.[0];
25-
content = `${tag}${marker}${content.slice(tag!.length)}`;
26+
content = `${expandedSpan}\n${content}`;
2627
} else if (content.startsWith('>')) {
27-
content = `${marker}\n${content}`;
28+
content = `${expandedSpan}\n${content}`;
2829
} else if (content.match(/^[-*+]\s\[.\]\s/)) {
2930
// tasks
30-
const taskPrefix = content.match(/^[-*+]\s\[.\]\s/)?.[0];
31-
content = `${taskPrefix}${marker}${content.slice(taskPrefix!.length).trim()}`;
31+
content = `${expandedSpan}\n${content}`;
3232
} else if (content.match(/^[-*+]\s/)) {
33-
const bullet = content.match(/^[-*+]\s/)?.[0];
34-
content = `${bullet}${marker}${content.slice(bullet!.length).trim()}`;
33+
content = `${expandedSpan}\n${content}`;
3534
} else if (content.match(/^\d+\.\s/)) {
3635
// numbered list
37-
const number = content.match(/^\d+\.\s/)?.[0];
38-
content = `${number} ${marker}${content.slice(number!.length).trim()}`;
36+
content = `${expandedSpan}\n${content}`;
3937
} else if (content.startsWith('```')) {
40-
content = `${marker}\n${content}`;
38+
content = `${expandedSpan}\n${content}`;
4139
} else if (content.startsWith('|')) {
4240
// table
43-
content = `${marker}\n\n${content}`;
41+
content = `${expandedSpan}\n\n${content}`;
42+
} else if (content.startsWith('[[')) {
43+
// wikilink
44+
content = `${expandedSpan}\n${content}`;
4445
} else {
45-
content = `${marker}${content}`;
46+
const collapsedSpan = collapsedSpanMarker(parentNumber, index);
47+
content = `${collapsedSpan}${content}`;
4648
}
4749

4850
text += content;

0 commit comments

Comments
 (0)