@p-buddy/parkdown 0.0.1 → 0.0.3
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/cli.js +14 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +396 -0
- package/dist/index.umd.cjs +15 -0
- package/package.json +9 -1
- package/.assets/api-note.md +0 -3
- package/.assets/api.md +0 -34
- package/.assets/authoring.md +0 -69
- package/.assets/code/depopulate.ts +0 -6
- package/.assets/code/inclusions.ts +0 -6
- package/.assets/depopulated.md +0 -25
- package/.assets/invocation.md +0 -16
- package/.assets/populated/block.md +0 -9
- package/.assets/populated/inline.multi.md +0 -5
- package/.assets/populated/inline.single.md +0 -3
- package/.assets/query.md +0 -73
- package/.assets/remap-imports.md +0 -0
- package/.assets/unpopulated/block.md +0 -5
- package/.assets/unpopulated/inline.multi.md +0 -3
- package/.assets/unpopulated/inline.single.md +0 -1
- package/.devcontainer/Dockerfile +0 -16
- package/.devcontainer/devcontainer.json +0 -35
- package/src/api/index.test.ts +0 -32
- package/src/api/index.ts +0 -8
- package/src/api/types.ts +0 -78
- package/src/api/utils.test.ts +0 -132
- package/src/api/utils.ts +0 -161
- package/src/cli.ts +0 -31
- package/src/include.test.ts +0 -369
- package/src/include.ts +0 -252
- package/src/index.ts +0 -35
- package/src/region.test.ts +0 -145
- package/src/region.ts +0 -138
- package/src/remap.test.ts +0 -37
- package/src/remap.ts +0 -72
- package/src/utils.test.ts +0 -238
- package/src/utils.ts +0 -184
- package/src/wrap.ts +0 -61
- package/tsconfig.json +0 -5
- package/vite.cli.config.ts +0 -23
- package/vite.config.ts +0 -20
package/src/utils.ts
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { unified, type Plugin } from 'unified';
|
|
2
|
-
import remarkParse from 'remark-parse';
|
|
3
|
-
import { visit } from 'unist-util-visit';
|
|
4
|
-
import hash from 'stable-hash';
|
|
5
|
-
|
|
6
|
-
export type AstRoot = typeof remarkParse extends Plugin<any, any, infer Root>
|
|
7
|
-
/**/ ? Root
|
|
8
|
-
/**/ : never;
|
|
9
|
-
|
|
10
|
-
export type MarkdownNode = AstRoot["children"][number];
|
|
11
|
-
export type NodeType = MarkdownNode["type"];
|
|
12
|
-
export type SpecificNode<T extends NodeType> = MarkdownNode & { type: T };
|
|
13
|
-
|
|
14
|
-
type RequiredDeep<T> = {
|
|
15
|
-
[P in keyof T]-?: T[P] extends object | undefined ? RequiredDeep<T[P]> : T[P];
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export type HasPosition = RequiredDeep<Pick<MarkdownNode, "position">>;
|
|
19
|
-
export type Position = HasPosition['position'];
|
|
20
|
-
export type Point = Position['start' | 'end'];
|
|
21
|
-
|
|
22
|
-
export const nodeSort = (a: HasPosition, b: HasPosition) => a.position.start.offset - b.position.start.offset;
|
|
23
|
-
|
|
24
|
-
nodeSort.reverse = (a: HasPosition, b: HasPosition) => nodeSort(b, a);
|
|
25
|
-
|
|
26
|
-
export const hasPosition = <T extends MarkdownNode>(node: T): node is T & HasPosition =>
|
|
27
|
-
node.position !== undefined && node.position.start.offset !== undefined && node.position.end.offset !== undefined;
|
|
28
|
-
|
|
29
|
-
const processor = unified().use(remarkParse);
|
|
30
|
-
|
|
31
|
-
export const parse = {
|
|
32
|
-
md: (markdown: string) => processor.parse(markdown) satisfies AstRoot
|
|
33
|
-
} as const;
|
|
34
|
-
|
|
35
|
-
export const getAllPositionNodes = <T extends NodeType>(ast: AstRoot, type?: T) => {
|
|
36
|
-
type Node = SpecificNode<T> & HasPosition & { parentID: string; siblingIndex: number; siblingCount: number };
|
|
37
|
-
const nodes: Node[] = [];
|
|
38
|
-
visit(ast, (node, siblingIndex, parent) => {
|
|
39
|
-
if (node.type === "root") return;
|
|
40
|
-
else if (type && node.type !== type) return;
|
|
41
|
-
else if (hasPosition(node)) {
|
|
42
|
-
const parentID = hash(parent);
|
|
43
|
-
const siblingCount = (parent?.children.length ?? 0) - 1;
|
|
44
|
-
nodes.push({ ...node, parentID, siblingIndex, siblingCount } as Node);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
return nodes;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export type PositionNode<T extends NodeType> = ReturnType<typeof getAllPositionNodes<T>>[number];
|
|
51
|
-
|
|
52
|
-
export type Link = PositionNode<"link">;
|
|
53
|
-
export type Html = PositionNode<"html">;
|
|
54
|
-
|
|
55
|
-
export const linkHasNoText = (node: Link) => node.children.length === 0;
|
|
56
|
-
|
|
57
|
-
export const extractContent = (markdown: string, ...nodes: HasPosition[]) => {
|
|
58
|
-
if (nodes.length === 0) throw new Error("No nodes to extract content from");
|
|
59
|
-
nodes.sort(nodeSort);
|
|
60
|
-
const head = nodes.at(0)!;
|
|
61
|
-
const tail = nodes.at(-1)!;
|
|
62
|
-
return markdown.slice(head.position.start.offset, tail.position.end.offset);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export const replaceWithContent = (markdown: string, content: string, ...nodes: HasPosition[]) => {
|
|
66
|
-
if (nodes.length === 0) throw new Error("No nodes to replace content from");
|
|
67
|
-
nodes.sort(nodeSort);
|
|
68
|
-
const head = nodes.at(0)!;
|
|
69
|
-
const tail = nodes.at(-1)!;
|
|
70
|
-
return markdown.slice(0, head.position.start.offset) + content + markdown.slice(tail.position.end.offset);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export const getContentInBetween = (markdown: string, a: HasPosition, b: HasPosition) => {
|
|
74
|
-
const head = Math.min(a.position.end.offset, b.position.end.offset);
|
|
75
|
-
const tail = Math.max(a.position.start.offset, b.position.start.offset);
|
|
76
|
-
return markdown.slice(head, tail);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
type Join<T extends string[], D extends string> =
|
|
80
|
-
T extends []
|
|
81
|
-
/**/ ? ''
|
|
82
|
-
/**/ : T extends [infer F extends string]
|
|
83
|
-
/**/ ? F
|
|
84
|
-
/**/ : T extends [infer F extends string, ...infer R extends string[]]
|
|
85
|
-
/**/ ? `${F}${D}${Join<R, D>}`
|
|
86
|
-
/**/ : string;
|
|
87
|
-
|
|
88
|
-
export const spaced = <T extends string[]>(...args: T) => args.join(" ") as Join<T, " ">;
|
|
89
|
-
export const lined = <T extends string[]>(...args: T) => args.join("\n") as Join<T, "\n">;
|
|
90
|
-
|
|
91
|
-
export const start = ({ position: { start } }: HasPosition) => start;
|
|
92
|
-
|
|
93
|
-
const offsetIndex = ({ start, end }: Position, offset: number) =>
|
|
94
|
-
({ start: { line: start.line + offset, column: start.column + offset }, end: { line: end.line + offset, column: end.column + offset } });
|
|
95
|
-
|
|
96
|
-
export const zeroIndexed = (position: Position) => offsetIndex(position, -1);
|
|
97
|
-
export const oneIndexed = (position: Position) => offsetIndex(position, 1);
|
|
98
|
-
|
|
99
|
-
export const seperateQueryParams = (path: string): [lhs: string, query: string] => {
|
|
100
|
-
const parts = path.split("?");
|
|
101
|
-
return parts.length > 1 ? [parts.slice(0, -1).join("?"), parts.at(-1)!] : [path, ""];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export const getQueryParams = (path: string) => seperateQueryParams(path)[1];
|
|
105
|
-
|
|
106
|
-
export const removeQueryParams = (path: string) => seperateQueryParams(path)[0];
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
export class Intervals {
|
|
110
|
-
private intervals: Array<[number, number]> = [];
|
|
111
|
-
|
|
112
|
-
push(start: number, end: number) {
|
|
113
|
-
this.intervals.push([Math.min(start, end), Math.max(start, end)]);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
combine(rhs: Intervals) {
|
|
117
|
-
this.intervals.push(...rhs.intervals);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
collapse() {
|
|
121
|
-
const { intervals } = this;
|
|
122
|
-
if (!intervals.length) return (this.intervals = []);
|
|
123
|
-
|
|
124
|
-
intervals.sort((a, b) => a[0] - b[0]);
|
|
125
|
-
|
|
126
|
-
const result: typeof this.intervals = [];
|
|
127
|
-
let [currStart, currEnd] = intervals[0];
|
|
128
|
-
|
|
129
|
-
for (let i = 1; i < intervals.length; i++) {
|
|
130
|
-
const [start, end] = intervals[i];
|
|
131
|
-
if (start <= currEnd) currEnd = Math.max(currEnd, end);
|
|
132
|
-
else {
|
|
133
|
-
result.push([currStart, currEnd]);
|
|
134
|
-
currStart = start;
|
|
135
|
-
currEnd = end;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
result.push([currStart, currEnd]);
|
|
139
|
-
|
|
140
|
-
return (this.intervals = result);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
subtract(rhs: Intervals) {
|
|
144
|
-
const { intervals } = this;
|
|
145
|
-
const { intervals: remove } = rhs;
|
|
146
|
-
|
|
147
|
-
if (!intervals.length || !remove.length) return intervals;
|
|
148
|
-
|
|
149
|
-
let result = [...intervals];
|
|
150
|
-
for (const [removeStart, removeEnd] of remove) {
|
|
151
|
-
const updated: typeof this.intervals = [];
|
|
152
|
-
|
|
153
|
-
for (const [start, end] of result) {
|
|
154
|
-
if (removeEnd <= start || removeStart >= end) {
|
|
155
|
-
updated.push([start, end]);
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (removeStart > start) updated.push([start, removeStart]);
|
|
160
|
-
if (removeEnd < end) updated.push([removeEnd, end]);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
result = updated;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return (this.intervals = result);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export const COMMA_NOT_IN_PARENTHESIS = /,\s*(?![^()]*\))/;
|
|
171
|
-
|
|
172
|
-
/** p▼: sanitize */
|
|
173
|
-
const sanitizations: [from: RegExp | string, to: string][] = [
|
|
174
|
-
[/'''/g, `"`],
|
|
175
|
-
[/''/g, `'`],
|
|
176
|
-
[/parkdown:\s+/g, ``],
|
|
177
|
-
[/p▼:\s+/g, ``],
|
|
178
|
-
]
|
|
179
|
-
|
|
180
|
-
export const sanitize = (replacement: string, space: string = "-") => {
|
|
181
|
-
const sanitized = sanitizations.reduce((acc, [from, to]) => acc.replaceAll(from, to), replacement)
|
|
182
|
-
return space ? sanitized.replaceAll(space, " ") : sanitized;
|
|
183
|
-
}
|
|
184
|
-
/** p▼: sanitize */
|
package/src/wrap.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { createParser, type MethodDefinition } from "./api/";
|
|
2
|
-
|
|
3
|
-
/** p▼: definition */
|
|
4
|
-
const definitions = [
|
|
5
|
-
/**
|
|
6
|
-
* Wraps the content in a markdown-formatted code block.
|
|
7
|
-
* @param lang The language of the code block (defaults to the file extension).
|
|
8
|
-
* @param meta Additional metadata to include in the top line of the code block (i.e. to the right of the `lang`).
|
|
9
|
-
* @example [](<url>?wrap=code)
|
|
10
|
-
* @example [](<url>?wrap=code())
|
|
11
|
-
* @example [](<url>?wrap=code(ts))
|
|
12
|
-
* @example [](<url>?wrap=code(,some-meta))
|
|
13
|
-
*/
|
|
14
|
-
"code(lang?: string, meta?: string)",
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Wraps the content in a markdown-formatted blockquote
|
|
18
|
-
* (using the `>` character if the content is a single line,
|
|
19
|
-
* or the `<blockquote>` tag if the content is a multi-line block).
|
|
20
|
-
* @example [](<url>?wrap=quote)
|
|
21
|
-
* @example [](<url>?wrap=quote())
|
|
22
|
-
* @example [](<url>?wrap=quote(,))
|
|
23
|
-
*/
|
|
24
|
-
"quote()",
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Wraps the content in a markdown-formatted dropdown (using the `<details>` and `<summary>` tags).
|
|
28
|
-
* @param summary The summary text of the dropdown.
|
|
29
|
-
* @param open Whether the dropdown should be open by default.
|
|
30
|
-
* @param space The space character to use between words in the summary (defaults to `-`).
|
|
31
|
-
* @example [](<url>?wrap=dropdown(hello-world))
|
|
32
|
-
* @example [](<url>?wrap=dropdown('hello,-world',true))
|
|
33
|
-
* @example [](<url>?wrap=dropdown(hello_world,,_))
|
|
34
|
-
*/
|
|
35
|
-
"dropdown(summary: string, open?: boolean, space?: string)",
|
|
36
|
-
|
|
37
|
-
] /** p▼: definition */ satisfies (MethodDefinition)[];
|
|
38
|
-
|
|
39
|
-
/** p▼: Default-Space */
|
|
40
|
-
const DEFAULT_SPACE = "-";
|
|
41
|
-
/** p▼: Default-Space */
|
|
42
|
-
|
|
43
|
-
const parse = createParser(definitions);
|
|
44
|
-
|
|
45
|
-
export const wrap = (content: string, query: string, details?: { extension: string, inline: boolean }): string => {
|
|
46
|
-
const parsed = parse(query);
|
|
47
|
-
const isSingleLine = details?.inline && !content.includes("\n\n");
|
|
48
|
-
|
|
49
|
-
switch (parsed.name) {
|
|
50
|
-
case "code":
|
|
51
|
-
const lang = parsed.lang ?? details?.extension ?? "";
|
|
52
|
-
const meta = parsed.meta ? ` ${parsed.meta}` : "";
|
|
53
|
-
return `\`\`\`${lang}${meta}\n${content}\n\`\`\``;
|
|
54
|
-
case "quote":
|
|
55
|
-
return isSingleLine ? `> ${content}` : `<blockquote>\n\n${content}\n\n</blockquote>\n`;
|
|
56
|
-
case "dropdown":
|
|
57
|
-
const head = `<details${parsed.open ? " open" : ""}>`;
|
|
58
|
-
const summary = `<summary>${parsed.summary.split(parsed.space ?? DEFAULT_SPACE).join(" ")}</summary>`;
|
|
59
|
-
return ["", head, summary, "", content, "</details>", ""].join("\n");
|
|
60
|
-
}
|
|
61
|
-
}
|
package/tsconfig.json
DELETED
package/vite.cli.config.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
import { externalizeDeps } from 'vite-plugin-externalize-deps'
|
|
4
|
-
import { name as packageName } from './package.json';
|
|
5
|
-
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
resolve: {
|
|
8
|
-
alias: {
|
|
9
|
-
'.': packageName,
|
|
10
|
-
'./': packageName,
|
|
11
|
-
'./index': packageName,
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
plugins: [externalizeDeps({ nodeBuiltins: true, include: [packageName] })],
|
|
15
|
-
build: {
|
|
16
|
-
lib: {
|
|
17
|
-
fileName: 'cli',
|
|
18
|
-
entry: resolve(__dirname, 'src/cli.ts'),
|
|
19
|
-
formats: ['es']
|
|
20
|
-
},
|
|
21
|
-
emptyOutDir: false,
|
|
22
|
-
}
|
|
23
|
-
});
|
package/vite.config.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
import { defineConfig } from 'vitest/config';
|
|
3
|
-
import dts from 'vite-plugin-dts';
|
|
4
|
-
import { externalizeDeps } from 'vite-plugin-externalize-deps';
|
|
5
|
-
|
|
6
|
-
const testPattern = "src/**/*.{test,spec}.{js,ts}"
|
|
7
|
-
|
|
8
|
-
export default defineConfig({
|
|
9
|
-
plugins: [dts({ exclude: testPattern, rollupTypes: true }), externalizeDeps({ nodeBuiltins: true })],
|
|
10
|
-
build: {
|
|
11
|
-
lib: {
|
|
12
|
-
name: 'index',
|
|
13
|
-
fileName: 'index',
|
|
14
|
-
entry: resolve(__dirname, 'src/index.ts'),
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
test: {
|
|
18
|
-
include: [testPattern],
|
|
19
|
-
},
|
|
20
|
-
})
|