@sillsdev/docu-notion 1.0.0-alpha.4 → 1.0.0-alpha.5
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/dist/transform.js +18 -8
- package/dist/transform.spec.d.ts +1 -0
- package/dist/transform.spec.js +63 -0
- package/package.json +1 -1
package/dist/transform.js
CHANGED
|
@@ -113,13 +113,19 @@ function doTransformsOnMarkdown(context, config, input) {
|
|
|
113
113
|
let body = input;
|
|
114
114
|
//console.log("body before regex: " + body);
|
|
115
115
|
let match;
|
|
116
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
117
116
|
for (const mod of regexMods) {
|
|
118
|
-
let replacement = undefined;
|
|
119
117
|
// regex.exec is stateful, so we don't want to mess up the plugin's use of its own regex, so we clone it.
|
|
120
118
|
// we also add the "g" flag to make sure we get all matches
|
|
121
119
|
const regex = new RegExp(`${codeBlocks.source}|(${mod.regex.source})`, "g");
|
|
122
|
-
|
|
120
|
+
// We match against `source` (a snapshot of the current body) and build up a
|
|
121
|
+
// fresh `result`. Mutating the string we're iterating over would invalidate
|
|
122
|
+
// `match.index` for every subsequent match once a replacement changes the
|
|
123
|
+
// length, so instead we copy the spans between matches using indices that
|
|
124
|
+
// always refer to the unchanged `source`.
|
|
125
|
+
const source = body;
|
|
126
|
+
let result = "";
|
|
127
|
+
let lastIndex = 0;
|
|
128
|
+
while ((match = regex.exec(source)) !== null) {
|
|
123
129
|
if (match[0]) {
|
|
124
130
|
const original = match[0];
|
|
125
131
|
if (original.startsWith("```") &&
|
|
@@ -127,6 +133,7 @@ function doTransformsOnMarkdown(context, config, input) {
|
|
|
127
133
|
!mod.includeCodeBlocks) {
|
|
128
134
|
continue; // code block, and they didn't say to include them
|
|
129
135
|
}
|
|
136
|
+
let replacement = undefined;
|
|
130
137
|
if (mod.getReplacement) {
|
|
131
138
|
// our match here has an extra group, which is an implementation detail
|
|
132
139
|
// that shouldn't be made visible to the plugin
|
|
@@ -138,11 +145,11 @@ function doTransformsOnMarkdown(context, config, input) {
|
|
|
138
145
|
}
|
|
139
146
|
if (replacement !== undefined) {
|
|
140
147
|
(0, log_1.verbose)(`[${mod.name}] ${original} --> ${replacement}`);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
148
|
+
// copy everything since the last match, then the replacement (the
|
|
149
|
+
// replacement is appended literally, so `$` sequences in it are not
|
|
150
|
+
// given any special meaning)
|
|
151
|
+
result += source.substring(lastIndex, match.index) + replacement;
|
|
152
|
+
lastIndex = match.index + original.length;
|
|
146
153
|
// add any library imports
|
|
147
154
|
if (!context.imports)
|
|
148
155
|
context.imports = [];
|
|
@@ -150,6 +157,9 @@ function doTransformsOnMarkdown(context, config, input) {
|
|
|
150
157
|
}
|
|
151
158
|
}
|
|
152
159
|
}
|
|
160
|
+
// copy whatever follows the last replacement (including any skipped code blocks)
|
|
161
|
+
result += source.substring(lastIndex);
|
|
162
|
+
body = result;
|
|
153
163
|
}
|
|
154
164
|
(0, log_1.logDebug)("doTransformsOnMarkdown", "body after regex: " + body);
|
|
155
165
|
return body;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const log_1 = require("./log");
|
|
13
|
+
const pluginTestRun_1 = require("./plugins/pluginTestRun");
|
|
14
|
+
function paragraph(text) {
|
|
15
|
+
return {
|
|
16
|
+
type: "paragraph",
|
|
17
|
+
paragraph: {
|
|
18
|
+
rich_text: [
|
|
19
|
+
{
|
|
20
|
+
type: "text",
|
|
21
|
+
text: { content: text, link: null },
|
|
22
|
+
annotations: {
|
|
23
|
+
bold: false,
|
|
24
|
+
italic: false,
|
|
25
|
+
strikethrough: false,
|
|
26
|
+
underline: false,
|
|
27
|
+
code: false,
|
|
28
|
+
color: "default",
|
|
29
|
+
},
|
|
30
|
+
plain_text: text,
|
|
31
|
+
href: null,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Regression test for the bug where doTransformsOnMarkdown matched against the
|
|
38
|
+
// original `input` but sliced/replaced the mutating `body`. Once the first
|
|
39
|
+
// replacement changes the string length, every subsequent match.index is wrong.
|
|
40
|
+
// We make the first replacement SHRINK the text so the second match.index lands
|
|
41
|
+
// past the real match, and the inner .replace silently drops the transformation.
|
|
42
|
+
test("applies every match even after a length-changing replacement", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
(0, log_1.setLogLevel)("verbose");
|
|
44
|
+
const p = {
|
|
45
|
+
name: "test",
|
|
46
|
+
regexMarkdownModifications: [
|
|
47
|
+
{
|
|
48
|
+
regex: /REMOVE/,
|
|
49
|
+
replacementPattern: `X`, // shorter than the match, so the body shrinks
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
const config = { plugins: [p] };
|
|
54
|
+
// Produces markdown: "REMOVE\n\nREMOVE keep"
|
|
55
|
+
const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
|
|
56
|
+
paragraph("REMOVE"),
|
|
57
|
+
paragraph("REMOVE keep"),
|
|
58
|
+
]);
|
|
59
|
+
// Both occurrences must be transformed; none should survive.
|
|
60
|
+
expect(result).not.toContain("REMOVE");
|
|
61
|
+
expect((result.match(/X/g) || []).length).toBe(2);
|
|
62
|
+
expect(result).toContain("keep");
|
|
63
|
+
}));
|
package/package.json
CHANGED