@remigius42/morg 0.7.0 → 0.9.0
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 +35 -18
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.js +2 -0
- package/dist/cli/conversion.d.ts +3 -3
- package/dist/cli/conversion.js +4 -4
- package/dist/cli/flags.d.ts +1 -1
- package/dist/cli/flags.js +15 -1
- package/dist/cli/formats.d.ts +2 -1
- package/dist/cli/formats.js +1 -0
- package/dist/cli/presets.d.ts +13 -2
- package/dist/cli/presets.js +17 -3
- package/dist/cli.js +4 -5
- package/dist/config.d.ts +9 -4
- package/dist/config.js +2 -0
- package/dist/conversionOptions.d.ts +19 -3
- package/dist/conversionOptions.js +61 -0
- package/dist/core/bracedScripts.d.ts +7 -0
- package/dist/core/bracedScripts.js +10 -0
- package/dist/core/frontmatterBlock.d.ts +7 -0
- package/dist/core/frontmatterBlock.js +7 -2
- package/dist/core/lineSyntax.d.ts +13 -0
- package/dist/core/lineSyntax.js +16 -4
- package/dist/core/mdastToUniorg/blocks.js +4 -1
- package/dist/core/passthroughSource.d.ts +21 -0
- package/dist/core/passthroughSource.js +94 -0
- package/dist/core/uniorgToMdast/elements.js +5 -0
- package/dist/core/uniorgToMdast/shared.js +6 -1
- package/dist/index.d.ts +1 -2
- package/dist/markdownToOrg.js +19 -6
- package/dist/normalize.js +16 -2
- package/dist/options.d.ts +3 -7
- package/dist/orgToMarkdown.js +14 -4
- package/dist/presets/hooks.d.ts +49 -0
- package/dist/presets/hooks.js +72 -0
- package/dist/presets/logseq.d.ts +3 -22
- package/dist/presets/logseq.js +306 -195
- package/dist/presets/logseqOutline.d.ts +47 -0
- package/dist/presets/logseqOutline.js +428 -0
- package/dist/presets/logseqVanillaMarkdown.d.ts +9 -0
- package/dist/presets/logseqVanillaMarkdown.js +295 -0
- package/dist/presets/obsidian.js +4 -2
- package/dist/presets/registry.d.ts +1 -1
- package/dist/presets/registry.js +5 -3
- package/dist/presets/sides.d.ts +40 -0
- package/dist/presets/sides.js +42 -0
- package/dist/presets/types.d.ts +49 -8
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { readsAsPassthrough } from "./lineSyntax.js";
|
|
2
|
+
// the first line of an org block or drawer
|
|
3
|
+
const BLOCK_START_RE = /^#\+begin_(\S+)/i;
|
|
4
|
+
const DRAWER_START_RE = /^:[\w-]+:$/;
|
|
5
|
+
/** Whether a line opens an org block (`#+begin_name`). */
|
|
6
|
+
export function isOrgBlockStart(line) {
|
|
7
|
+
return BLOCK_START_RE.test(line);
|
|
8
|
+
}
|
|
9
|
+
/** Whether a line opens an org drawer (`:NAME:`). */
|
|
10
|
+
export function isDrawerStart(line) {
|
|
11
|
+
return DRAWER_START_RE.test(line);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The line that ends the org block or drawer a line opens.
|
|
15
|
+
* @param lines The lines.
|
|
16
|
+
* @param start The index of the opening line.
|
|
17
|
+
* @returns The index of the `#+end_name` or `:END:` line, or -1.
|
|
18
|
+
*/
|
|
19
|
+
export function orgElementEnd(lines, start) {
|
|
20
|
+
const end = endPattern(lines[start] ?? "");
|
|
21
|
+
return end ? lines.findIndex((other, i) => i > start && end.test(other)) : -1;
|
|
22
|
+
}
|
|
23
|
+
// the pattern of the line that ends the block or drawer `line` opens
|
|
24
|
+
function endPattern(line) {
|
|
25
|
+
const block = BLOCK_START_RE.exec(line)?.[1];
|
|
26
|
+
if (block) {
|
|
27
|
+
return new RegExp(`^#\\+end_${block.replace(/\W/g, "\\$&")}\\s*$`, "i");
|
|
28
|
+
}
|
|
29
|
+
return DRAWER_START_RE.test(line) ? /^:end:\s*$/i : null;
|
|
30
|
+
}
|
|
31
|
+
// the text from `offset` through the line that ends the block or
|
|
32
|
+
// drawer opening there, read line by line rather than splitting the
|
|
33
|
+
// rest of the document (a page may hold thousands of drawers)
|
|
34
|
+
function elementSource(markdown, offset) {
|
|
35
|
+
const lineEnd = (from) => {
|
|
36
|
+
const index = markdown.indexOf("\n", from);
|
|
37
|
+
return index === -1 ? markdown.length : index;
|
|
38
|
+
};
|
|
39
|
+
let end = lineEnd(offset);
|
|
40
|
+
const pattern = endPattern(markdown.slice(offset, end));
|
|
41
|
+
while (pattern && end < markdown.length) {
|
|
42
|
+
const next = lineEnd(end + 1);
|
|
43
|
+
if (pattern.test(markdown.slice(end + 1, next))) {
|
|
44
|
+
return markdown.slice(offset, next);
|
|
45
|
+
}
|
|
46
|
+
end = next;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
// the source offset where the passthrough element starting at a node
|
|
51
|
+
// ends, or -1
|
|
52
|
+
function passthroughEnd(node, markdown) {
|
|
53
|
+
const start = node.position?.start;
|
|
54
|
+
if (start?.column !== 1 || start.offset === undefined) {
|
|
55
|
+
return -1;
|
|
56
|
+
}
|
|
57
|
+
const source = elementSource(markdown, start.offset);
|
|
58
|
+
return source !== null && readsAsPassthrough(source)
|
|
59
|
+
? start.offset + source.length
|
|
60
|
+
: -1;
|
|
61
|
+
}
|
|
62
|
+
// the index of the last node ending at `end`, from `i` on, or -1
|
|
63
|
+
function lastNodeAt(nodes, i, end) {
|
|
64
|
+
let j = i;
|
|
65
|
+
while ((nodes[j]?.position?.end.offset ?? end) < end) {
|
|
66
|
+
j++;
|
|
67
|
+
}
|
|
68
|
+
return nodes[j]?.position?.end.offset === end ? j : -1;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* md→org: a passthrough element's org text may hold lines Markdown reads
|
|
72
|
+
* as syntax of its own (a blank line and an indented one, a `#`, `-`
|
|
73
|
+
* or `>` line); the top-level nodes it parsed into become one paragraph
|
|
74
|
+
* of the source text again, which goes back to org as it is.
|
|
75
|
+
* @param mdast The parsed Markdown.
|
|
76
|
+
* @param markdown Its source.
|
|
77
|
+
*/
|
|
78
|
+
export function keepPassthroughSource(mdast, markdown) {
|
|
79
|
+
const children = [];
|
|
80
|
+
const nodes = mdast.children;
|
|
81
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
82
|
+
const node = nodes[i];
|
|
83
|
+
const end = passthroughEnd(node, markdown);
|
|
84
|
+
const last = end === -1 ? -1 : lastNodeAt(nodes, i, end);
|
|
85
|
+
if (last === -1) {
|
|
86
|
+
children.push(node);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const value = markdown.slice(node.position?.start.offset, end);
|
|
90
|
+
children.push({ type: "paragraph", children: [{ type: "text", value }] });
|
|
91
|
+
i = last;
|
|
92
|
+
}
|
|
93
|
+
mdast.children = children;
|
|
94
|
+
}
|
|
@@ -253,9 +253,14 @@ function transformQuoteBlock(ctx, node) {
|
|
|
253
253
|
};
|
|
254
254
|
}
|
|
255
255
|
function transformSrcBlock(node) {
|
|
256
|
+
// switches and header arguments (`-n :results output`) are the
|
|
257
|
+
// fence's meta, after the language
|
|
258
|
+
const { switches, parameters } = node;
|
|
259
|
+
const meta = [switches, parameters].filter(Boolean).join(" ");
|
|
256
260
|
return {
|
|
257
261
|
type: "code",
|
|
258
262
|
lang: node.language || null,
|
|
263
|
+
meta: node.language && meta ? meta : null,
|
|
259
264
|
value: trimTrailingNewline(node.value)
|
|
260
265
|
};
|
|
261
266
|
}
|
|
@@ -24,7 +24,12 @@ export function keyValueParagraph(lines) {
|
|
|
24
24
|
// trailing newline), for verbatim passthrough of org-only constructs
|
|
25
25
|
export function orgNodeToText(node) {
|
|
26
26
|
const orgText = unified()
|
|
27
|
-
|
|
27
|
+
// a preset's verbatim-inline text is org text already
|
|
28
|
+
.use(uniorgStringify, {
|
|
29
|
+
handlers: {
|
|
30
|
+
"verbatim-inline": (inline) => inline.value
|
|
31
|
+
}
|
|
32
|
+
})
|
|
28
33
|
.stringify({
|
|
29
34
|
type: "org-data",
|
|
30
35
|
children: [node],
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,5 @@ export { transformMdastToUniorgAst } from "./core/mdastToUniorg/index.js";
|
|
|
8
8
|
export { transformUniorgAstToMdast } from "./core/uniorgToMdast/index.js";
|
|
9
9
|
export { logseq } from "./presets/logseq.js";
|
|
10
10
|
export { obsidian } from "./presets/obsidian.js";
|
|
11
|
-
export type { Preset } from "./presets/types.js";
|
|
12
|
-
export type { LogseqPresetOptions } from "./presets/logseq.js";
|
|
11
|
+
export type { ConversionContext, FragmentConverter, MarkdownDialect, OrgDialect, Preset } from "./presets/types.js";
|
|
13
12
|
export type { Toggle, MarkdownToOrgOptions, OrgToMarkdownOptions, MarkdownStyleOptions } from "./options.js";
|
package/dist/markdownToOrg.js
CHANGED
|
@@ -14,6 +14,9 @@ import { escapeFootnoteReferences } from "./core/footnoteReferences.js";
|
|
|
14
14
|
import { escapeBackslashCommands } from "./core/backslashCommands.js";
|
|
15
15
|
import { escapeTablePipes } from "./core/tablePipes.js";
|
|
16
16
|
import { requireBracedScripts } from "./core/bracedScripts.js";
|
|
17
|
+
import { keepPassthroughSource } from "./core/passthroughSource.js";
|
|
18
|
+
import { conversionContext, fragmentSides, readMarkdownWriteOrg, takeOver } from "./presets/hooks.js";
|
|
19
|
+
import { resolveSides } from "./presets/sides.js";
|
|
17
20
|
import { keyValueEntries } from "./core/keyValueLines.js";
|
|
18
21
|
/**
|
|
19
22
|
* Converts a Markdown string to an Org-mode string.
|
|
@@ -22,8 +25,18 @@ import { keyValueEntries } from "./core/keyValueLines.js";
|
|
|
22
25
|
* @returns The converted Org-mode string.
|
|
23
26
|
*/
|
|
24
27
|
export function convertMarkdownToOrg(markdown, options = {}) {
|
|
28
|
+
return convertMarkdownSides(markdown, options, resolveSides(options, "markdown", "org"));
|
|
29
|
+
}
|
|
30
|
+
function convertMarkdownSides(markdown, options, sides) {
|
|
31
|
+
const over = takeOver(sides, "convertMarkdown");
|
|
32
|
+
return over
|
|
33
|
+
? // a fragment's style is the preset's, not one to record
|
|
34
|
+
over.preset.convertMarkdown(markdown, (fragment, preset, carried) => convertMarkdownSides(fragment, { ...options, recordStyle: false }, fragmentSides(sides, over.side, preset, carried)), conversionContext(over, options))
|
|
35
|
+
: convertMarkdownDocument(markdown, options, sides);
|
|
36
|
+
}
|
|
37
|
+
function convertMarkdownDocument(markdown, options, sides) {
|
|
25
38
|
// Phase 1: Parse Markdown to mdast
|
|
26
|
-
const mdast = parseMarkdown(markdown,
|
|
39
|
+
const mdast = parseMarkdown(markdown, sides.input);
|
|
27
40
|
// Phase 2: Generic mdast to uniorg-ast transformation
|
|
28
41
|
let uniorgAst = transformMdastToUniorgDraft(mdast, {
|
|
29
42
|
...(options.preserveMdisms !== undefined && {
|
|
@@ -51,10 +64,9 @@ export function convertMarkdownToOrg(markdown, options = {}) {
|
|
|
51
64
|
if (options.recordStyle) {
|
|
52
65
|
recordStyleKeyword(uniorgAst, detectMarkdownStyle(mdast, markdown, options.onWarning));
|
|
53
66
|
}
|
|
54
|
-
// Phase 3: Apply dialect preset, if any
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
67
|
+
// Phase 3: Apply dialect preset, if any: read the md dialect, then
|
|
68
|
+
// write the org dialect
|
|
69
|
+
uniorgAst = readMarkdownWriteOrg(uniorgAst, sides);
|
|
58
70
|
// Phase 3b: literal footnote references, paragraph lines org would
|
|
59
71
|
// read as line syntax, literal markers org would read as markup, and
|
|
60
72
|
// markup touching a word character, need a zero-width space escape;
|
|
@@ -88,7 +100,8 @@ function parseMarkdown(markdown, preset) {
|
|
|
88
100
|
.use(remarkFrontmatter)
|
|
89
101
|
.use(remarkMath)
|
|
90
102
|
.parse(markdown);
|
|
91
|
-
|
|
103
|
+
keepPassthroughSource(mdast, markdown);
|
|
104
|
+
preset?.markdown?.read?.mdast?.(mdast, markdown);
|
|
92
105
|
return mdast;
|
|
93
106
|
}
|
|
94
107
|
// leads the document, ahead of restored keywords and the frontmatter block
|
package/dist/normalize.js
CHANGED
|
@@ -10,7 +10,8 @@ import { convertOrgToMarkdown } from "./orgToMarkdown.js";
|
|
|
10
10
|
* @returns The canonical-form Markdown string.
|
|
11
11
|
*/
|
|
12
12
|
export function normalizeMarkdown(markdown, options = {}) {
|
|
13
|
-
|
|
13
|
+
const single = onePreset(options);
|
|
14
|
+
return convertOrgToMarkdown(convertMarkdownToOrg(markdown, single), single);
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
17
|
* Normalizes an Org string to morg's canonical form: one full round trip
|
|
@@ -20,5 +21,18 @@ export function normalizeMarkdown(markdown, options = {}) {
|
|
|
20
21
|
* @returns The canonical-form Org string.
|
|
21
22
|
*/
|
|
22
23
|
export function normalizeOrg(org, options = {}) {
|
|
23
|
-
|
|
24
|
+
const single = onePreset(options);
|
|
25
|
+
return convertMarkdownToOrg(convertOrgToMarkdown(org, single), single);
|
|
26
|
+
}
|
|
27
|
+
// normalizing canonicalizes within one dialect (ADR 0006), so both
|
|
28
|
+
// sides name the same preset, which then sets both ways of the trip
|
|
29
|
+
function onePreset(options) {
|
|
30
|
+
const { preset, inputPreset, outputPreset, ...rest } = options;
|
|
31
|
+
const input = inputPreset ?? preset;
|
|
32
|
+
const output = outputPreset ?? preset;
|
|
33
|
+
if (input?.name !== output?.name) {
|
|
34
|
+
const name = (key, side) => `${key} '${side?.name ?? "vanilla"}'`;
|
|
35
|
+
throw new Error(`normalize takes one preset; got ${name("inputPreset", input)} and ${name("outputPreset", output)}`);
|
|
36
|
+
}
|
|
37
|
+
return input ? { ...rest, preset: input } : rest;
|
|
24
38
|
}
|
package/dist/options.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PresetOptions } from "./presets/sides.js";
|
|
2
2
|
/**
|
|
3
3
|
* A feature toggle: `true`/`false` switches everything on/off, a record
|
|
4
4
|
* toggles individual constructs by name. Unlisted keys fall back to the
|
|
@@ -6,7 +6,7 @@ import type { Preset } from "./presets/types.js";
|
|
|
6
6
|
*/
|
|
7
7
|
export type Toggle = boolean | Record<string, boolean>;
|
|
8
8
|
export declare function toggleEnabled(toggle: Toggle | undefined, key: string, defaultValue?: boolean): boolean;
|
|
9
|
-
export interface MarkdownToOrgOptions {
|
|
9
|
+
export interface MarkdownToOrgOptions extends PresetOptions {
|
|
10
10
|
/**
|
|
11
11
|
* Preserve Markdown constructs without a native Org equivalent (e.g.
|
|
12
12
|
* raw HTML as export blocks/snippets, see ADR 0002). Default: `true`.
|
|
@@ -38,8 +38,6 @@ export interface MarkdownToOrgOptions {
|
|
|
38
38
|
orgismKeys?: Record<string, string>;
|
|
39
39
|
/** Called for each construct dropped without an equivalent. */
|
|
40
40
|
onWarning?: (message: string) => void;
|
|
41
|
-
/** Dialect preset applied on top of the generic conversion. */
|
|
42
|
-
preset?: Preset;
|
|
43
41
|
}
|
|
44
42
|
/**
|
|
45
43
|
* Markdown stringifier style knobs (subset of remark-stringify options).
|
|
@@ -67,7 +65,7 @@ export interface MarkdownStyleOptions {
|
|
|
67
65
|
*/
|
|
68
66
|
ruleRepetition?: number;
|
|
69
67
|
}
|
|
70
|
-
export interface OrgToMarkdownOptions {
|
|
68
|
+
export interface OrgToMarkdownOptions extends PresetOptions {
|
|
71
69
|
/**
|
|
72
70
|
* Serialize Org constructs without a native Markdown equivalent as
|
|
73
71
|
* `key:: value` lines and verbatim passthroughs (see ADR 0002).
|
|
@@ -97,6 +95,4 @@ export interface OrgToMarkdownOptions {
|
|
|
97
95
|
orgismKeys?: Record<string, string>;
|
|
98
96
|
/** Called for each construct dropped without an equivalent. */
|
|
99
97
|
onWarning?: (message: string) => void;
|
|
100
|
-
/** Dialect preset extracted before the generic conversion. */
|
|
101
|
-
preset?: Preset;
|
|
102
98
|
}
|
package/dist/orgToMarkdown.js
CHANGED
|
@@ -13,6 +13,8 @@ import { unescapeBackslashCommands } from "./core/backslashCommands.js";
|
|
|
13
13
|
import { unescapeTablePipes } from "./core/tablePipes.js";
|
|
14
14
|
import { parseOrg } from "./core/bracedScripts.js";
|
|
15
15
|
import { dropUnderscoreBulletGuards, guardUnderscoreBullets } from "./core/underscoreBullets.js";
|
|
16
|
+
import { conversionContext, fragmentSides, readOrgWriteMarkdown, takeOver } from "./presets/hooks.js";
|
|
17
|
+
import { resolveSides } from "./presets/sides.js";
|
|
16
18
|
// a list item's paragraph after its nested list needs a blank line, or
|
|
17
19
|
// md reads it as a lazy continuation of the nested list's last item
|
|
18
20
|
function separateTextAfterNestedList(left, right, parent) {
|
|
@@ -29,6 +31,15 @@ function separateTextAfterNestedList(left, right, parent) {
|
|
|
29
31
|
* @returns The converted Markdown string.
|
|
30
32
|
*/
|
|
31
33
|
export function convertOrgToMarkdown(org, options = {}) {
|
|
34
|
+
return convertOrgSides(org, options, resolveSides(options, "org", "markdown"));
|
|
35
|
+
}
|
|
36
|
+
function convertOrgSides(org, options, sides) {
|
|
37
|
+
const over = takeOver(sides, "convertOrg");
|
|
38
|
+
return over
|
|
39
|
+
? over.preset.convertOrg(org, (fragment, preset, carried) => convertOrgSides(fragment, options, fragmentSides(sides, over.side, preset, carried)), conversionContext(over, options))
|
|
40
|
+
: convertOrgDocument(org, options, sides);
|
|
41
|
+
}
|
|
42
|
+
function convertOrgDocument(org, options, sides) {
|
|
32
43
|
// Phase 1: Parse Org-mode to uniorg-ast
|
|
33
44
|
// md text has no scripts, so ^:{} is implied there and consumed here
|
|
34
45
|
// (see markdownToOrg); uniorg misreads `_.` lines (see underscoreBullets)
|
|
@@ -47,10 +58,9 @@ export function convertOrgToMarkdown(org, options = {}) {
|
|
|
47
58
|
unescapeFootnoteReferences(uniorgAst);
|
|
48
59
|
unescapeBackslashCommands(uniorgAst);
|
|
49
60
|
unescapeTablePipes(uniorgAst);
|
|
50
|
-
// Phase 2: Extract dialect preset conventions, if any
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
61
|
+
// Phase 2: Extract dialect preset conventions, if any: read the org
|
|
62
|
+
// dialect, then write the md dialect
|
|
63
|
+
uniorgAst = readOrgWriteMarkdown(uniorgAst, sides);
|
|
54
64
|
// Phase 3: Generic uniorg-ast to mdast transformation
|
|
55
65
|
const mdast = transformUniorgAstToMdast(uniorgAst, {
|
|
56
66
|
...(options.preserveOrgisms !== undefined && {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { OrgData } from "uniorg";
|
|
2
|
+
import type { Sides } from "./sides.js";
|
|
3
|
+
import type { ConversionContext, Preset } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* md→org's dialect step: reads the Markdown dialect out of the generic
|
|
6
|
+
* tree, then writes the org dialect into it.
|
|
7
|
+
* @param uniorgAst The tree the generic transform produced.
|
|
8
|
+
* @param sides The preset per side.
|
|
9
|
+
* @returns The tree in the org dialect.
|
|
10
|
+
*/
|
|
11
|
+
export declare function readMarkdownWriteOrg(uniorgAst: OrgData, { input, output }: Sides): OrgData;
|
|
12
|
+
/**
|
|
13
|
+
* org→md's dialect step: reads the org dialect out of the parsed tree,
|
|
14
|
+
* then writes the Markdown dialect into it.
|
|
15
|
+
* @param uniorgAst The parsed org tree.
|
|
16
|
+
* @param sides The preset per side.
|
|
17
|
+
* @returns The tree, ready for the generic transform.
|
|
18
|
+
*/
|
|
19
|
+
export declare function readOrgWriteMarkdown(uniorgAst: OrgData, { input, output }: Sides): OrgData;
|
|
20
|
+
/** A preset that takes a whole conversion over, and the side it is on. */
|
|
21
|
+
export interface TakeOver {
|
|
22
|
+
preset: Preset;
|
|
23
|
+
side: ConversionContext["side"];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Finds the preset that takes the conversion over, if any: the input's,
|
|
27
|
+
* else the output's.
|
|
28
|
+
* @param sides The preset per side.
|
|
29
|
+
* @param hook The hook that takes this direction over.
|
|
30
|
+
* @returns The preset and its side, or `undefined` for none.
|
|
31
|
+
*/
|
|
32
|
+
export declare function takeOver({ input, output }: Sides, hook: "convertOrg" | "convertMarkdown"): TakeOver | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* The sides a fragment converts with: the fragment's preset on the
|
|
35
|
+
* taking-over preset's side or sides, the other side as it was.
|
|
36
|
+
* @param sides The conversion's preset per side.
|
|
37
|
+
* @param side The taking-over preset's side.
|
|
38
|
+
* @param preset The fragment's preset.
|
|
39
|
+
* @param carried The preset for the other side where it is Vanilla.
|
|
40
|
+
* @returns The fragment's preset per side.
|
|
41
|
+
*/
|
|
42
|
+
export declare function fragmentSides(sides: Sides, side: ConversionContext["side"], preset: Preset | undefined, carried?: Preset): Sides;
|
|
43
|
+
/**
|
|
44
|
+
* The context a taking-over preset converts in.
|
|
45
|
+
* @param over The taking-over preset and its side.
|
|
46
|
+
* @param options The conversion's options.
|
|
47
|
+
* @returns The context.
|
|
48
|
+
*/
|
|
49
|
+
export declare function conversionContext(over: TakeOver, options: Pick<ConversionContext, "onWarning" | "orgismKeys">): ConversionContext;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* md→org's dialect step: reads the Markdown dialect out of the generic
|
|
3
|
+
* tree, then writes the org dialect into it.
|
|
4
|
+
* @param uniorgAst The tree the generic transform produced.
|
|
5
|
+
* @param sides The preset per side.
|
|
6
|
+
* @returns The tree in the org dialect.
|
|
7
|
+
*/
|
|
8
|
+
export function readMarkdownWriteOrg(uniorgAst, { input, output }) {
|
|
9
|
+
const read = input?.markdown?.read?.org ?? same;
|
|
10
|
+
const write = output?.org?.write ?? same;
|
|
11
|
+
return write(read(uniorgAst));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* org→md's dialect step: reads the org dialect out of the parsed tree,
|
|
15
|
+
* then writes the Markdown dialect into it.
|
|
16
|
+
* @param uniorgAst The parsed org tree.
|
|
17
|
+
* @param sides The preset per side.
|
|
18
|
+
* @returns The tree, ready for the generic transform.
|
|
19
|
+
*/
|
|
20
|
+
export function readOrgWriteMarkdown(uniorgAst, { input, output }) {
|
|
21
|
+
const read = input?.org?.read ?? same;
|
|
22
|
+
const write = output?.markdown?.write ?? same;
|
|
23
|
+
return write(read(uniorgAst));
|
|
24
|
+
}
|
|
25
|
+
function same(uniorgAst) {
|
|
26
|
+
return uniorgAst;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Finds the preset that takes the conversion over, if any: the input's,
|
|
30
|
+
* else the output's.
|
|
31
|
+
* @param sides The preset per side.
|
|
32
|
+
* @param hook The hook that takes this direction over.
|
|
33
|
+
* @returns The preset and its side, or `undefined` for none.
|
|
34
|
+
*/
|
|
35
|
+
export function takeOver({ input, output }, hook) {
|
|
36
|
+
if (input?.[hook]) {
|
|
37
|
+
return {
|
|
38
|
+
preset: input,
|
|
39
|
+
side: input.name === output?.name ? "both" : "input"
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return output?.[hook] ? { preset: output, side: "output" } : undefined;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The sides a fragment converts with: the fragment's preset on the
|
|
46
|
+
* taking-over preset's side or sides, the other side as it was.
|
|
47
|
+
* @param sides The conversion's preset per side.
|
|
48
|
+
* @param side The taking-over preset's side.
|
|
49
|
+
* @param preset The fragment's preset.
|
|
50
|
+
* @param carried The preset for the other side where it is Vanilla.
|
|
51
|
+
* @returns The fragment's preset per side.
|
|
52
|
+
*/
|
|
53
|
+
export function fragmentSides(sides, side, preset, carried) {
|
|
54
|
+
// only a Vanilla side carries another preset's syntax
|
|
55
|
+
return {
|
|
56
|
+
input: side === "output" ? (sides.input ?? carried) : preset,
|
|
57
|
+
output: side === "input" ? (sides.output ?? carried) : preset
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The context a taking-over preset converts in.
|
|
62
|
+
* @param over The taking-over preset and its side.
|
|
63
|
+
* @param options The conversion's options.
|
|
64
|
+
* @returns The context.
|
|
65
|
+
*/
|
|
66
|
+
export function conversionContext(over, options) {
|
|
67
|
+
return {
|
|
68
|
+
side: over.side,
|
|
69
|
+
...(options.onWarning && { onWarning: options.onWarning }),
|
|
70
|
+
...(options.orgismKeys && { orgismKeys: options.orgismKeys })
|
|
71
|
+
};
|
|
72
|
+
}
|
package/dist/presets/logseq.d.ts
CHANGED
|
@@ -1,25 +1,6 @@
|
|
|
1
|
-
import type { OrgData } from "uniorg";
|
|
2
1
|
import type { Preset } from "./types.js";
|
|
3
|
-
export interface LogseqPresetOptions {
|
|
4
|
-
/**
|
|
5
|
-
* Content following a heading becomes children of that heading's block
|
|
6
|
-
* in Logseq's outline: paragraphs turn into child block headlines one
|
|
7
|
-
* level deeper; other constructs stay in the preceding block's body.
|
|
8
|
-
* Default: `true`.
|
|
9
|
-
*/
|
|
10
|
-
nestUnderHeadings?: boolean;
|
|
11
|
-
}
|
|
12
2
|
/**
|
|
13
|
-
* Logseq dialect preset:
|
|
3
|
+
* Logseq dialect preset: the outline of blocks, page properties, page
|
|
4
|
+
* and block references, highlights and hiccup.
|
|
14
5
|
*/
|
|
15
|
-
export declare function logseq(
|
|
16
|
-
/**
|
|
17
|
-
* Applies Logseq-specific conventions to a uniorg AST: every heading gets
|
|
18
|
-
* a `:heading:` property drawer, and with `nestUnderHeadings` following
|
|
19
|
-
* paragraphs become child block headlines (in Logseq's org format every
|
|
20
|
-
* outline block is a headline).
|
|
21
|
-
* @param uniorgAst The uniorg AST to transform.
|
|
22
|
-
* @param nestUnderHeadings Nest content as child blocks. Default: `true`.
|
|
23
|
-
* @returns The Logseq-flavored uniorg AST.
|
|
24
|
-
*/
|
|
25
|
-
export declare function applyLogseqSpecificsToUniorgAst(uniorgAst: OrgData, nestUnderHeadings?: boolean): OrgData;
|
|
6
|
+
export declare function logseq(): Preset;
|