remark-speech 0.0.1
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/README.md +32 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/logic/from-markdown.d.ts +3 -0
- package/dist/logic/from-markdown.d.ts.map +1 -0
- package/dist/logic/from-markdown.js +30 -0
- package/dist/logic/from-markdown.js.map +1 -0
- package/dist/logic/syntax.d.ts +4 -0
- package/dist/logic/syntax.d.ts.map +1 -0
- package/dist/logic/syntax.js +113 -0
- package/dist/logic/syntax.js.map +1 -0
- package/dist/logic/to-markdown.d.ts +4 -0
- package/dist/logic/to-markdown.d.ts.map +1 -0
- package/dist/logic/to-markdown.js +37 -0
- package/dist/logic/to-markdown.js.map +1 -0
- package/dist/logic/types.d.ts +74 -0
- package/dist/logic/types.d.ts.map +1 -0
- package/dist/logic/types.js +2 -0
- package/dist/logic/types.js.map +1 -0
- package/package.json +97 -0
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# remark-speech
|
|
2
|
+
|
|
3
|
+
`remark-speech` is a remark plugin that adds direct-speech syntax with speaker metadata to Markdown. It includes parsing and serialization support so speech blocks can be read from and written back to Markdown consistently.
|
|
4
|
+
|
|
5
|
+
## Sample
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install remark-speech remark-parse remark-stringify unified
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { unified } from "unified";
|
|
13
|
+
import remarkParse from "remark-parse";
|
|
14
|
+
import remarkStringify from "remark-stringify";
|
|
15
|
+
import { remarkDirectSpeech } from "remark-speech";
|
|
16
|
+
|
|
17
|
+
const input = `
|
|
18
|
+
|
|
19
|
+
[[Fay]]"Es ist *Zeit*", säuselte eine helle Stimme, um sich
|
|
20
|
+
selbst dazu zu bringen, sich zu rühren.
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const file = await unified()
|
|
24
|
+
.use(remarkParse)
|
|
25
|
+
.use(remarkDirectSpeech)
|
|
26
|
+
.use(remarkStringify)
|
|
27
|
+
.process(input);
|
|
28
|
+
|
|
29
|
+
console.log(String(file));
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Input and output keep the same direct-speech block syntax, while the plugin adds AST support for working with speaker metadata.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Plugin } from "unified";
|
|
2
|
+
import "remark-stringify";
|
|
3
|
+
import "remark-parse";
|
|
4
|
+
import { directSpeechFromMarkdown } from "./logic/from-markdown.js";
|
|
5
|
+
import { directSpeech } from "./logic/syntax.js";
|
|
6
|
+
import { directSpeechToMarkdown } from "./logic/to-markdown.js";
|
|
7
|
+
import type { DirectSpeechOptions } from "./logic/types.js";
|
|
8
|
+
export declare const remarkDirectSpeech: Plugin<[
|
|
9
|
+
(DirectSpeechOptions | null | undefined)?
|
|
10
|
+
]>;
|
|
11
|
+
export { directSpeechFromMarkdown };
|
|
12
|
+
export { directSpeech };
|
|
13
|
+
export { directSpeechToMarkdown };
|
|
14
|
+
export type { DirectSpeechInline, DirectSpeechOptions } from "./logic/types.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,kBAAkB,CAAC;AAC1B,OAAO,cAAc,CAAC;AAEtB,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,eAAO,MAAM,kBAAkB,EAAE,MAAM,CACrC;IAAC,CAAC,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAAC,CAU5C,CAAC;AAEF,OAAO,EAAE,wBAAwB,EAAE,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAElC,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "remark-stringify";
|
|
2
|
+
import "remark-parse";
|
|
3
|
+
import { directSpeechFromMarkdown } from "./logic/from-markdown.js";
|
|
4
|
+
import { directSpeech } from "./logic/syntax.js";
|
|
5
|
+
import { directSpeechToMarkdown } from "./logic/to-markdown.js";
|
|
6
|
+
export const remarkDirectSpeech = function remarkDirectSpeech(options = {}) {
|
|
7
|
+
const data = this.data();
|
|
8
|
+
data.micromarkExtensions = data.micromarkExtensions ?? [];
|
|
9
|
+
data.fromMarkdownExtensions = data.fromMarkdownExtensions ?? [];
|
|
10
|
+
data.toMarkdownExtensions = data.toMarkdownExtensions ?? [];
|
|
11
|
+
data.micromarkExtensions.push(directSpeech(options ?? {}));
|
|
12
|
+
data.fromMarkdownExtensions.push(directSpeechFromMarkdown());
|
|
13
|
+
data.toMarkdownExtensions.push(directSpeechToMarkdown(options ?? {}));
|
|
14
|
+
};
|
|
15
|
+
export { directSpeechFromMarkdown };
|
|
16
|
+
export { directSpeech };
|
|
17
|
+
export { directSpeechToMarkdown };
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,cAAc,CAAC;AAEtB,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,MAAM,CAAC,MAAM,kBAAkB,GAE3B,SAAS,kBAAkB,CAAC,OAAO,GAAG,EAAE;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,IAAI,EAAE,CAAC;IAC1D,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,sBAAsB,IAAI,EAAE,CAAC;IAChE,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAC;IAE5D,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAC7D,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,sBAAsB,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF,OAAO,EAAE,wBAAwB,EAAE,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-markdown.d.ts","sourceRoot":"","sources":["../../src/logic/from-markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,IAAI,qBAAqB,EAEnC,MAAM,0BAA0B,CAAC;AAIlC,wBAAgB,wBAAwB,IAAI,qBAAqB,CAWhE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function directSpeechFromMarkdown() {
|
|
2
|
+
return {
|
|
3
|
+
canContainEols: ["directSpeechInline"],
|
|
4
|
+
enter: {
|
|
5
|
+
directSpeech: enterDirectSpeech,
|
|
6
|
+
},
|
|
7
|
+
exit: {
|
|
8
|
+
directSpeech: exitDirectSpeech,
|
|
9
|
+
directSpeechSpeaker: exitDirectSpeechSpeaker,
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const enterDirectSpeech = function enterDirectSpeech(token) {
|
|
14
|
+
this.enter({
|
|
15
|
+
type: "directSpeechInline",
|
|
16
|
+
speaker: "",
|
|
17
|
+
children: [],
|
|
18
|
+
}, token);
|
|
19
|
+
};
|
|
20
|
+
const exitDirectSpeech = function exitDirectSpeech(token) {
|
|
21
|
+
this.exit(token);
|
|
22
|
+
};
|
|
23
|
+
const exitDirectSpeechSpeaker = function exitDirectSpeechSpeaker(token) {
|
|
24
|
+
const speaker = this.sliceSerialize(token);
|
|
25
|
+
const node = this.stack[this.stack.length - 1];
|
|
26
|
+
if (node.type === "directSpeechInline") {
|
|
27
|
+
node.speaker = speaker;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=from-markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-markdown.js","sourceRoot":"","sources":["../../src/logic/from-markdown.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,cAAc,EAAE,CAAC,oBAAoB,CAAC;QACtC,KAAK,EAAE;YACL,YAAY,EAAE,iBAAiB;SAChC;QACD,IAAI,EAAE;YACJ,YAAY,EAAE,gBAAgB;YAC9B,mBAAmB,EAAE,uBAAuB;SAC7C;KACF,CAAC;AACJ,CAAC;AAED,MAAM,iBAAiB,GAAuB,SAAS,iBAAiB,CACtE,KAAK;IAEL,IAAI,CAAC,KAAK,CACR;QACE,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,EAAE;KACS,EACvB,KAAK,CACN,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAuB,SAAS,gBAAgB,CAAC,KAAK;IAC1E,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAC3B,SAAS,uBAAuB,CAAC,KAAK;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE/C,IAAI,IAAI,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntax.d.ts","sourceRoot":"","sources":["../../src/logic/syntax.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAQ,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAE9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMtD,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,SAAS,CAgBzE"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { markdownLineEndingOrSpace } from "micromark-util-character";
|
|
2
|
+
const leftSquareBracket = 91;
|
|
3
|
+
const rightSquareBracket = 93;
|
|
4
|
+
const doubleQuote = 34;
|
|
5
|
+
export function directSpeech(options = {}) {
|
|
6
|
+
const quote = getSingleCodePoint(options.quote, '"');
|
|
7
|
+
const closingQuote = getSingleCodePoint(options.closingQuote, String.fromCodePoint(quote));
|
|
8
|
+
return {
|
|
9
|
+
text: {
|
|
10
|
+
[leftSquareBracket]: {
|
|
11
|
+
add: "before",
|
|
12
|
+
name: "directSpeech",
|
|
13
|
+
tokenize: createDirectSpeechTokenizer(quote, closingQuote),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function createDirectSpeechTokenizer(quote, closingQuote) {
|
|
19
|
+
return function tokenizeDirectSpeech(effects, ok, nok) {
|
|
20
|
+
let hasSpeakerContent = false;
|
|
21
|
+
return start;
|
|
22
|
+
function start(code) {
|
|
23
|
+
if (code !== leftSquareBracket) {
|
|
24
|
+
/* v8 ignore next */
|
|
25
|
+
return nok(code);
|
|
26
|
+
}
|
|
27
|
+
effects.enter("directSpeech");
|
|
28
|
+
effects.enter("directSpeechSpeakerMarkerStart");
|
|
29
|
+
effects.consume(code);
|
|
30
|
+
return openSpeakerMarker;
|
|
31
|
+
}
|
|
32
|
+
function openSpeakerMarker(code) {
|
|
33
|
+
if (code !== leftSquareBracket) {
|
|
34
|
+
return nok(code);
|
|
35
|
+
}
|
|
36
|
+
effects.consume(code);
|
|
37
|
+
effects.exit("directSpeechSpeakerMarkerStart");
|
|
38
|
+
effects.enter("directSpeechSpeaker");
|
|
39
|
+
return speaker;
|
|
40
|
+
}
|
|
41
|
+
function speaker(code) {
|
|
42
|
+
if (code === null || markdownLineEndingOrSpace(code)) {
|
|
43
|
+
return nok(code);
|
|
44
|
+
}
|
|
45
|
+
if (code === rightSquareBracket) {
|
|
46
|
+
if (!hasSpeakerContent) {
|
|
47
|
+
return nok(code);
|
|
48
|
+
}
|
|
49
|
+
effects.exit("directSpeechSpeaker");
|
|
50
|
+
effects.enter("directSpeechSpeakerMarkerEnd");
|
|
51
|
+
effects.consume(code);
|
|
52
|
+
return closeSpeakerMarker;
|
|
53
|
+
}
|
|
54
|
+
hasSpeakerContent = true;
|
|
55
|
+
effects.consume(code);
|
|
56
|
+
return speaker;
|
|
57
|
+
}
|
|
58
|
+
function closeSpeakerMarker(code) {
|
|
59
|
+
if (code !== rightSquareBracket) {
|
|
60
|
+
return nok(code);
|
|
61
|
+
}
|
|
62
|
+
effects.consume(code);
|
|
63
|
+
effects.exit("directSpeechSpeakerMarkerEnd");
|
|
64
|
+
return beforeQuote;
|
|
65
|
+
}
|
|
66
|
+
function beforeQuote(code) {
|
|
67
|
+
if (code === null) {
|
|
68
|
+
/* v8 ignore next */
|
|
69
|
+
return nok(code);
|
|
70
|
+
}
|
|
71
|
+
if (markdownLineEndingOrSpace(code)) {
|
|
72
|
+
effects.enter("whitespace");
|
|
73
|
+
effects.consume(code);
|
|
74
|
+
effects.exit("whitespace");
|
|
75
|
+
return beforeQuote;
|
|
76
|
+
}
|
|
77
|
+
if (code !== quote) {
|
|
78
|
+
return nok(code);
|
|
79
|
+
}
|
|
80
|
+
effects.enter("directSpeechQuoteMarkerStart");
|
|
81
|
+
effects.consume(code);
|
|
82
|
+
effects.exit("directSpeechQuoteMarkerStart");
|
|
83
|
+
effects.enter("directSpeechContent", {
|
|
84
|
+
contentType: "text",
|
|
85
|
+
});
|
|
86
|
+
return content;
|
|
87
|
+
}
|
|
88
|
+
function content(code) {
|
|
89
|
+
if (code === null) {
|
|
90
|
+
return nok(code);
|
|
91
|
+
}
|
|
92
|
+
if (code === closingQuote) {
|
|
93
|
+
effects.exit("directSpeechContent");
|
|
94
|
+
effects.enter("directSpeechQuoteMarkerEnd");
|
|
95
|
+
effects.consume(code);
|
|
96
|
+
effects.exit("directSpeechQuoteMarkerEnd");
|
|
97
|
+
effects.exit("directSpeech");
|
|
98
|
+
return ok;
|
|
99
|
+
}
|
|
100
|
+
effects.consume(code);
|
|
101
|
+
return content;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function getSingleCodePoint(value, fallback) {
|
|
106
|
+
const resolved = value ?? fallback;
|
|
107
|
+
const symbols = Array.from(resolved);
|
|
108
|
+
if (symbols.length !== 1) {
|
|
109
|
+
throw new Error(`Direct speech quotes must be a single character, received ${JSON.stringify(resolved)}.`);
|
|
110
|
+
}
|
|
111
|
+
return symbols[0].codePointAt(0) ?? doubleQuote;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=syntax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntax.js","sourceRoot":"","sources":["../../src/logic/syntax.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Options as ToMarkdownExtension } from "mdast-util-to-markdown";
|
|
2
|
+
import type { DirectSpeechOptions } from "./types.js";
|
|
3
|
+
export declare function directSpeechToMarkdown(options?: DirectSpeechOptions): ToMarkdownExtension;
|
|
4
|
+
//# sourceMappingURL=to-markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"to-markdown.d.ts","sourceRoot":"","sources":["../../src/logic/to-markdown.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,OAAO,IAAI,mBAAmB,EAE/B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,mBAAmB,EAAsB,MAAM,YAAY,CAAC;AAE1E,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,mBAAwB,GAChC,mBAAmB,CAwBrB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function directSpeechToMarkdown(options = {}) {
|
|
2
|
+
const quote = getSingleCharacter(options.quote, '"');
|
|
3
|
+
const closingQuote = getSingleCharacter(options.closingQuote, quote);
|
|
4
|
+
return {
|
|
5
|
+
unsafe: [
|
|
6
|
+
{
|
|
7
|
+
character: "[",
|
|
8
|
+
inConstruct: "phrasing",
|
|
9
|
+
},
|
|
10
|
+
],
|
|
11
|
+
handlers: {
|
|
12
|
+
directSpeechInline(node, parent, state, info) {
|
|
13
|
+
return handleDirectSpeechInline(node, parent, state, info, quote, closingQuote);
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function handleDirectSpeechInline(node, _parent, state, info, quote, closingQuote) {
|
|
19
|
+
const tracker = state.createTracker(info);
|
|
20
|
+
let value = tracker.move(`[[${node.speaker}]]${quote}`);
|
|
21
|
+
value += state.containerPhrasing(node, {
|
|
22
|
+
...tracker.current(),
|
|
23
|
+
before: value,
|
|
24
|
+
after: closingQuote,
|
|
25
|
+
});
|
|
26
|
+
value += tracker.move(closingQuote);
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
function getSingleCharacter(value, fallback) {
|
|
30
|
+
const resolved = value ?? fallback;
|
|
31
|
+
if (Array.from(resolved).length !== 1) {
|
|
32
|
+
/* v8 ignore next */
|
|
33
|
+
throw new Error(`Direct speech quotes must be a single character, received ${JSON.stringify(resolved)}.`);
|
|
34
|
+
}
|
|
35
|
+
return resolved;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=to-markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"to-markdown.js","sourceRoot":"","sources":["../../src/logic/to-markdown.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,sBAAsB,CACpC,UAA+B,EAAE;IAEjC,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,kBAAkB,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAErE,OAAO;QACL,MAAM,EAAE;YACN;gBACE,SAAS,EAAE,GAAG;gBACd,WAAW,EAAE,UAAU;aACxB;SACF;QACD,QAAQ,EAAE;YACR,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI;gBAC1C,OAAO,wBAAwB,CAC7B,IAA0B,EAC1B,MAAM,EACN,KAAK,EACL,IAAI,EACJ,KAAK,EACL,YAAY,CACb,CAAC;YACJ,CAAC;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAC/B,IAAwB,EACxB,OAA4B,EAC5B,KAAY,EACZ,IAAU,EACV,KAAa,EACb,YAAoB;IAEpB,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC;IAExD,KAAK,IAAI,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE;QACrC,GAAG,OAAO,CAAC,OAAO,EAAE;QACpB,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,YAAY;KACpB,CAAC,CAAC;IAEH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEpC,OAAO,KAAK,CAAC;AACf,CAAC;AACD,SAAS,kBAAkB,CACzB,KAAyB,EACzB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,KAAK,IAAI,QAAQ,CAAC;IAEnC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,oBAAoB;QACpB,MAAM,IAAI,KAAK,CACb,6DAA6D,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CACzF,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Parent, PhrasingContent } from "mdast";
|
|
2
|
+
/**
|
|
3
|
+
* mdast node
|
|
4
|
+
*
|
|
5
|
+
* [[Fay]]"Hallo **Welt**"
|
|
6
|
+
*/
|
|
7
|
+
export interface DirectSpeechInline extends Parent {
|
|
8
|
+
type: "directSpeechInline";
|
|
9
|
+
/**
|
|
10
|
+
* Name of the speaker within [[...]]
|
|
11
|
+
*/
|
|
12
|
+
speaker: string;
|
|
13
|
+
children: PhrasingContent[];
|
|
14
|
+
}
|
|
15
|
+
declare module "mdast" {
|
|
16
|
+
interface PhrasingContentMap {
|
|
17
|
+
directSpeechInline: DirectSpeechInline;
|
|
18
|
+
}
|
|
19
|
+
interface RootContentMap {
|
|
20
|
+
directSpeechInline: DirectSpeechInline;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Options of the micromark Extension
|
|
25
|
+
*/
|
|
26
|
+
export interface DirectSpeechOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Character that opens the speech.
|
|
29
|
+
*
|
|
30
|
+
* Example:
|
|
31
|
+
*
|
|
32
|
+
* [[Fay]]"Hello"
|
|
33
|
+
* ^
|
|
34
|
+
*/
|
|
35
|
+
quote?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Character that closes the speech. If not provided, the opening quote will be used.
|
|
38
|
+
*/
|
|
39
|
+
closingQuote?: string;
|
|
40
|
+
/**
|
|
41
|
+
* The type of DirectSpeech, might be thought, spoken, or other.
|
|
42
|
+
*/
|
|
43
|
+
type?: string;
|
|
44
|
+
}
|
|
45
|
+
declare module "micromark-util-types" {
|
|
46
|
+
interface TokenTypeMap {
|
|
47
|
+
directSpeech: "directSpeech";
|
|
48
|
+
/**
|
|
49
|
+
* [[Fay]]
|
|
50
|
+
*/
|
|
51
|
+
directSpeechSpeaker: "directSpeechSpeaker";
|
|
52
|
+
/**
|
|
53
|
+
* Content between the quotes.
|
|
54
|
+
*/
|
|
55
|
+
directSpeechContent: "directSpeechContent";
|
|
56
|
+
/**
|
|
57
|
+
* [[
|
|
58
|
+
*/
|
|
59
|
+
directSpeechSpeakerMarkerStart: "directSpeechSpeakerMarkerStart";
|
|
60
|
+
/**
|
|
61
|
+
* ]]
|
|
62
|
+
*/
|
|
63
|
+
directSpeechSpeakerMarkerEnd: "directSpeechSpeakerMarkerEnd";
|
|
64
|
+
/**
|
|
65
|
+
* "
|
|
66
|
+
*/
|
|
67
|
+
directSpeechQuoteMarkerStart: "directSpeechQuoteMarkerStart";
|
|
68
|
+
/**
|
|
69
|
+
* "
|
|
70
|
+
*/
|
|
71
|
+
directSpeechQuoteMarkerEnd: "directSpeechQuoteMarkerEnd";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/logic/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,kBAAmB,SAAQ,MAAM;IAChD,IAAI,EAAE,oBAAoB,CAAC;IAE3B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,OAAO,QAAQ,OAAO,CAAC;IACrB,UAAU,kBAAkB;QAC1B,kBAAkB,EAAE,kBAAkB,CAAC;KACxC;IAED,UAAU,cAAc;QACtB,kBAAkB,EAAE,kBAAkB,CAAC;KACxC;CACF;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,OAAO,QAAQ,sBAAsB,CAAC;IACpC,UAAU,YAAY;QACpB,YAAY,EAAE,cAAc,CAAC;QAE7B;;WAEG;QACH,mBAAmB,EAAE,qBAAqB,CAAC;QAE3C;;WAEG;QACH,mBAAmB,EAAE,qBAAqB,CAAC;QAE3C;;WAEG;QACH,8BAA8B,EAAE,gCAAgC,CAAC;QAEjE;;WAEG;QACH,4BAA4B,EAAE,8BAA8B,CAAC;QAE7D;;WAEG;QACH,4BAA4B,EAAE,8BAA8B,CAAC;QAE7D;;WAEG;QACH,0BAA0B,EAAE,4BAA4B,CAAC;KAC1D;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/logic/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "remark-speech",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Remark plugin to add direct speech with metadata for speaker element in markdown",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "rimraf dist && tsc --build tsconfig.build.json && type-coverage",
|
|
17
|
+
"format": "npm run prettier",
|
|
18
|
+
"prettier": "prettier --write .",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"test:file": "vitest test.plugin.spec.ts",
|
|
22
|
+
"test-coverage": "vitest run --coverage",
|
|
23
|
+
"prepack": "npm run build",
|
|
24
|
+
"prepublishOnly": "npm run format && npm run test-coverage"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist/",
|
|
28
|
+
"LICENSE",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://codeberg.org/lokimidgard/remark-speech.git"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"unified",
|
|
37
|
+
"mdast",
|
|
38
|
+
"markdown",
|
|
39
|
+
"MDX",
|
|
40
|
+
"remark",
|
|
41
|
+
"plugin",
|
|
42
|
+
"remark plugin",
|
|
43
|
+
"remark speech",
|
|
44
|
+
"html speech",
|
|
45
|
+
"remark speech text"
|
|
46
|
+
],
|
|
47
|
+
"author": "Patrick Kranz<patrick-kranz@live.de>",
|
|
48
|
+
"license": "UNLICENSED",
|
|
49
|
+
"homepage": "https://codeberg.org/lokimidgard/remark-speech#readme",
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://codeberg.org/lokimidgard/remark-speech/issues"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/node": "^24.12.4",
|
|
55
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
56
|
+
"dedent": "^1.7.2",
|
|
57
|
+
"globals": "^17.6.0",
|
|
58
|
+
"prettier": "^3.8.3",
|
|
59
|
+
"rehype-format": "^5.0.1",
|
|
60
|
+
"remark-stringify": "11.0.0",
|
|
61
|
+
"rehype-stringify": "^10.0.1",
|
|
62
|
+
"remark-gfm": "^4.0.1",
|
|
63
|
+
"remark-parse": "^11.0.0",
|
|
64
|
+
"remark-rehype": "^11.1.2",
|
|
65
|
+
"rimraf": "^6.1.3",
|
|
66
|
+
"type-coverage": "^2.29.7",
|
|
67
|
+
"typescript": "^5.9.3",
|
|
68
|
+
"unified": "^11.0.5",
|
|
69
|
+
"vfile": "^6.0.3",
|
|
70
|
+
"vitest": "^4.1.7"
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@types/mdast": "^4.0.4",
|
|
74
|
+
"mdast-util-from-markdown": "^2.0.3",
|
|
75
|
+
"mdast-util-to-markdown": "^2.1.2",
|
|
76
|
+
"micromark-util-character": "^2.1.1",
|
|
77
|
+
"micromark-util-types": "^2.0.2",
|
|
78
|
+
"unist-builder": "^4.0.0",
|
|
79
|
+
"unist-util-find-after": "^5.0.0",
|
|
80
|
+
"unist-util-find-all-after": "^5.0.0",
|
|
81
|
+
"unist-util-find-all-before": "^5.0.0",
|
|
82
|
+
"unist-util-find-between": "^1.2.1",
|
|
83
|
+
"unist-util-visit": "^5.1.0"
|
|
84
|
+
},
|
|
85
|
+
"peerDependencies": {
|
|
86
|
+
"unified": "^11"
|
|
87
|
+
},
|
|
88
|
+
"sideEffects": false,
|
|
89
|
+
"typeCoverage": {
|
|
90
|
+
"atLeast": 99,
|
|
91
|
+
"detail": true,
|
|
92
|
+
"ignoreAsAssertion": true,
|
|
93
|
+
"ignoreNonNullAssertion": true,
|
|
94
|
+
"ignoreCatch": true,
|
|
95
|
+
"strict": true
|
|
96
|
+
}
|
|
97
|
+
}
|