@remigius42/morg 0.4.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.
Files changed (67) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +267 -0
  3. package/dist/cli/args.d.ts +15 -0
  4. package/dist/cli/args.js +105 -0
  5. package/dist/cli/configFile.d.ts +2 -0
  6. package/dist/cli/configFile.js +18 -0
  7. package/dist/cli/conversion.d.ts +11 -0
  8. package/dist/cli/conversion.js +50 -0
  9. package/dist/cli/error.d.ts +2 -0
  10. package/dist/cli/error.js +4 -0
  11. package/dist/cli/formats.d.ts +3 -0
  12. package/dist/cli/formats.js +46 -0
  13. package/dist/cli/presets.d.ts +2 -0
  14. package/dist/cli/presets.js +10 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.js +54 -0
  17. package/dist/config.d.ts +20 -0
  18. package/dist/config.js +22 -0
  19. package/dist/conversionOptions.d.ts +32 -0
  20. package/dist/conversionOptions.js +34 -0
  21. package/dist/core/markdownStyle.d.ts +27 -0
  22. package/dist/core/markdownStyle.js +108 -0
  23. package/dist/core/mdastToUniorg/blocks.d.ts +20 -0
  24. package/dist/core/mdastToUniorg/blocks.js +211 -0
  25. package/dist/core/mdastToUniorg/context.d.ts +15 -0
  26. package/dist/core/mdastToUniorg/context.js +7 -0
  27. package/dist/core/mdastToUniorg/index.d.ts +13 -0
  28. package/dist/core/mdastToUniorg/index.js +95 -0
  29. package/dist/core/mdastToUniorg/lists.d.ts +4 -0
  30. package/dist/core/mdastToUniorg/lists.js +45 -0
  31. package/dist/core/mdastToUniorg/phrasing.d.ts +4 -0
  32. package/dist/core/mdastToUniorg/phrasing.js +176 -0
  33. package/dist/core/uniorgToMdast/elements.d.ts +4 -0
  34. package/dist/core/uniorgToMdast/elements.js +278 -0
  35. package/dist/core/uniorgToMdast/footnotes.d.ts +10 -0
  36. package/dist/core/uniorgToMdast/footnotes.js +54 -0
  37. package/dist/core/uniorgToMdast/index.d.ts +11 -0
  38. package/dist/core/uniorgToMdast/index.js +84 -0
  39. package/dist/core/uniorgToMdast/lists.d.ts +4 -0
  40. package/dist/core/uniorgToMdast/lists.js +94 -0
  41. package/dist/core/uniorgToMdast/objects.d.ts +4 -0
  42. package/dist/core/uniorgToMdast/objects.js +152 -0
  43. package/dist/core/uniorgToMdast/shared.d.ts +25 -0
  44. package/dist/core/uniorgToMdast/shared.js +55 -0
  45. package/dist/core/uniorgToMdast/tables.d.ts +6 -0
  46. package/dist/core/uniorgToMdast/tables.js +66 -0
  47. package/dist/fileNames.d.ts +16 -0
  48. package/dist/fileNames.js +34 -0
  49. package/dist/index.d.ts +13 -0
  50. package/dist/index.js +8 -0
  51. package/dist/markdownToOrg.d.ts +8 -0
  52. package/dist/markdownToOrg.js +194 -0
  53. package/dist/normalize.d.ts +26 -0
  54. package/dist/normalize.js +24 -0
  55. package/dist/options.d.ts +102 -0
  56. package/dist/options.js +9 -0
  57. package/dist/orgToMarkdown.d.ts +8 -0
  58. package/dist/orgToMarkdown.js +61 -0
  59. package/dist/presets/logseq.d.ts +25 -0
  60. package/dist/presets/logseq.js +298 -0
  61. package/dist/presets/obsidian.d.ts +6 -0
  62. package/dist/presets/obsidian.js +40 -0
  63. package/dist/presets/registry.d.ts +8 -0
  64. package/dist/presets/registry.js +25 -0
  65. package/dist/presets/types.d.ts +12 -0
  66. package/dist/presets/types.js +1 -0
  67. package/package.json +112 -0
@@ -0,0 +1,194 @@
1
+ import { unified } from "unified";
2
+ import remarkParse from "remark-parse";
3
+ import remarkGfm from "remark-gfm";
4
+ import remarkFrontmatter from "remark-frontmatter";
5
+ import remarkMath from "remark-math";
6
+ import { uniorgStringify } from "uniorg-stringify";
7
+ import { visit } from "unist-util-visit";
8
+ import { transformMdastToUniorgAst } from "./core/mdastToUniorg/index.js";
9
+ import { detectMarkdownStyle, STYLE_KEYWORD } from "./core/markdownStyle.js";
10
+ /**
11
+ * Converts a Markdown string to an Org-mode string.
12
+ * @param markdown The Markdown string to convert.
13
+ * @param options Conversion options (md-ism preservation, dialect preset).
14
+ * @returns The converted Org-mode string.
15
+ */
16
+ export function convertMarkdownToOrg(markdown, options = {}) {
17
+ // Phase 1: Parse Markdown to mdast
18
+ const mdast = unified()
19
+ .use(remarkParse)
20
+ .use(remarkGfm)
21
+ .use(remarkFrontmatter)
22
+ .use(remarkMath)
23
+ .parse(markdown);
24
+ // Phase 2: Generic mdast to uniorg-ast transformation
25
+ let uniorgAst = transformMdastToUniorgAst(mdast, {
26
+ ...(options.preserveMdisms !== undefined && {
27
+ preserveMdisms: options.preserveMdisms
28
+ }),
29
+ ...(options.interpretHtml !== undefined && {
30
+ interpretHtml: options.interpretHtml
31
+ }),
32
+ ...(options.onWarning !== undefined && { onWarning: options.onWarning })
33
+ });
34
+ // Phase 2b: restore key:: value lines below headings to native org
35
+ // syntax (see ADR 0002): known keys become TODO keywords, priorities,
36
+ // tags and planning; unknown keys become property drawer entries.
37
+ // orgismKeys maps custom names back to canonical (per-config).
38
+ const canonicalKeys = new Map(Object.entries(options.orgismKeys ?? {}).map(([canonical, custom]) => [
39
+ custom,
40
+ canonical
41
+ ]));
42
+ restoreOrgisms(uniorgAst, canonicalKeys);
43
+ // Phase 2c: formatting-as-structure — adjacent lists need two blank
44
+ // lines between them, or org's parser merges them into one list.
45
+ separateAdjacentLists(uniorgAst);
46
+ // Phase 2d: record the source's own style markers, so the return trip
47
+ // can reproduce them instead of morg's canonical ones (ADR 0004)
48
+ if (options.recordStyle) {
49
+ recordStyleKeyword(uniorgAst, detectMarkdownStyle(mdast, markdown, options.onWarning));
50
+ }
51
+ // Phase 3: Apply dialect preset, if any
52
+ if (options.preset?.applyToUniorg) {
53
+ uniorgAst = options.preset.applyToUniorg(uniorgAst);
54
+ }
55
+ // Phase 4: Render uniorg-ast to Org-mode string
56
+ const processor = unified().use(uniorgStringify);
57
+ const orgContent = processor.stringify(uniorgAst);
58
+ return orgContent;
59
+ }
60
+ // leads the document so it survives the frontmatter keywords following it
61
+ function recordStyleKeyword(uniorgAst, style) {
62
+ if (!Object.keys(style).length) {
63
+ return;
64
+ }
65
+ uniorgAst.children.unshift({
66
+ type: "keyword",
67
+ key: STYLE_KEYWORD,
68
+ value: JSON.stringify(style)
69
+ });
70
+ }
71
+ const KEY_VALUE_LINE_RE = /^([\w-]+):: (.*)$/;
72
+ function parseKeyValueParagraph(node) {
73
+ if (node?.type !== "paragraph" || !node.children?.length) {
74
+ return null;
75
+ }
76
+ if (!node.children.every(child => child.type === "text")) {
77
+ return null;
78
+ }
79
+ const lines = node.children
80
+ .map(child => child.value ?? "")
81
+ .join("")
82
+ .split("\n");
83
+ const entries = [];
84
+ for (const line of lines) {
85
+ const match = KEY_VALUE_LINE_RE.exec(line);
86
+ if (!match) {
87
+ return null;
88
+ }
89
+ entries.push([match[1], match[2]]);
90
+ }
91
+ return entries;
92
+ }
93
+ function makeTimestamp(rawValue) {
94
+ return { type: "timestamp", rawValue };
95
+ }
96
+ // the headline slots have a syntax of their own: a value org could not
97
+ // carry there (a drawer property that merely shares the name, a
98
+ // hand-written line) stays a property instead of corrupting the title
99
+ const TODO_KEYWORD_RE = /^[A-Z][A-Z0-9_-]*$/;
100
+ const PRIORITY_RE = /^[A-Z]$/;
101
+ const TAG_LIST_RE = /^[\w@#%]+(?:,\s*[\w@#%]+)*$/;
102
+ const TIMESTAMP_RE = /^[<[].*[>\]]$/;
103
+ function applyOrgismEntry(headline, planning, properties, key, value) {
104
+ switch (key) {
105
+ case "todo":
106
+ if (!TODO_KEYWORD_RE.test(value)) {
107
+ break;
108
+ }
109
+ headline.todoKeyword = value;
110
+ return;
111
+ case "priority":
112
+ if (!PRIORITY_RE.test(value)) {
113
+ break;
114
+ }
115
+ headline.priority = value;
116
+ return;
117
+ case "tags":
118
+ if (!TAG_LIST_RE.test(value)) {
119
+ break;
120
+ }
121
+ headline.tags = value.split(/,\s*/);
122
+ return;
123
+ case "scheduled":
124
+ case "deadline":
125
+ case "closed":
126
+ if (!TIMESTAMP_RE.test(value)) {
127
+ break;
128
+ }
129
+ planning[key] = makeTimestamp(value);
130
+ return;
131
+ default:
132
+ break;
133
+ }
134
+ properties.push({ type: "node-property", key, value });
135
+ }
136
+ function consumeOrgismParagraphs(children, i, canonicalKeys) {
137
+ const headline = children[i];
138
+ const planning = {};
139
+ const properties = [];
140
+ let consumed = 0;
141
+ let entries;
142
+ while ((entries = parseKeyValueParagraph(children[i + 1 + consumed]))) {
143
+ for (const [rawKey, value] of entries) {
144
+ const key = canonicalKeys.get(rawKey) ?? rawKey;
145
+ applyOrgismEntry(headline, planning, properties, key, value);
146
+ }
147
+ consumed++;
148
+ }
149
+ return { planning, properties, consumed };
150
+ }
151
+ function buildOrgismReplacements(planning, properties) {
152
+ const replacements = [];
153
+ if (Object.keys(planning).length) {
154
+ replacements.push({
155
+ type: "planning",
156
+ scheduled: planning.scheduled ?? null,
157
+ deadline: planning.deadline ?? null,
158
+ closed: planning.closed ?? null
159
+ });
160
+ }
161
+ if (properties.length) {
162
+ replacements.push({
163
+ type: "property-drawer",
164
+ children: properties,
165
+ contentsBegin: 0,
166
+ contentsEnd: 0
167
+ });
168
+ }
169
+ return replacements;
170
+ }
171
+ function restoreOrgisms(uniorgAst, canonicalKeys) {
172
+ const children = uniorgAst.children;
173
+ for (let i = 0; i < children.length; i++) {
174
+ if (children[i]?.type !== "headline") {
175
+ continue;
176
+ }
177
+ const { planning, properties, consumed } = consumeOrgismParagraphs(children, i, canonicalKeys);
178
+ if (!consumed) {
179
+ continue;
180
+ }
181
+ const replacements = buildOrgismReplacements(planning, properties);
182
+ children.splice(i + 1, consumed, ...replacements);
183
+ }
184
+ }
185
+ function separateAdjacentLists(uniorgAst) {
186
+ visit(uniorgAst, "plain-list", (_node, index, parent) => {
187
+ if (parent.children[index + 1]?.type === "plain-list") {
188
+ const separator = { type: "text", value: "\n\n" };
189
+ parent.children.splice(index + 1, 0, separator);
190
+ return index + 2;
191
+ }
192
+ return undefined;
193
+ });
194
+ }
@@ -0,0 +1,26 @@
1
+ import type { MarkdownToOrgOptions, OrgToMarkdownOptions } from "./options.js";
2
+ /**
3
+ * The full option set of both directions: normalization uses the same
4
+ * configuration as conversion — Convergence is per-config (see ADR
5
+ * 0002), so a file must be normalized with the exact config (preset,
6
+ * style, key names, toggles) it will be converted with.
7
+ */
8
+ export type NormalizeOptions = MarkdownToOrgOptions & OrgToMarkdownOptions;
9
+ /**
10
+ * Normalizes a Markdown string to morg's canonical form: one full round
11
+ * trip (`md → org → md`), whose output is a fixed point (see ADR 0001).
12
+ * This canonicalizes, it does not just re-style — org-isms and md-isms
13
+ * are rewritten the same way a conversion would rewrite them.
14
+ * @param markdown The Markdown string to normalize.
15
+ * @param options Warning callback and dialect preset.
16
+ * @returns The canonical-form Markdown string.
17
+ */
18
+ export declare function normalizeMarkdown(markdown: string, options?: NormalizeOptions): string;
19
+ /**
20
+ * Normalizes an Org string to morg's canonical form: one full round trip
21
+ * (`org → md → org`), whose output is a fixed point (see ADR 0001).
22
+ * @param org The Org string to normalize.
23
+ * @param options Warning callback and dialect preset.
24
+ * @returns The canonical-form Org string.
25
+ */
26
+ export declare function normalizeOrg(org: string, options?: NormalizeOptions): string;
@@ -0,0 +1,24 @@
1
+ import { convertMarkdownToOrg } from "./markdownToOrg.js";
2
+ import { convertOrgToMarkdown } from "./orgToMarkdown.js";
3
+ /**
4
+ * Normalizes a Markdown string to morg's canonical form: one full round
5
+ * trip (`md → org → md`), whose output is a fixed point (see ADR 0001).
6
+ * This canonicalizes, it does not just re-style — org-isms and md-isms
7
+ * are rewritten the same way a conversion would rewrite them.
8
+ * @param markdown The Markdown string to normalize.
9
+ * @param options Warning callback and dialect preset.
10
+ * @returns The canonical-form Markdown string.
11
+ */
12
+ export function normalizeMarkdown(markdown, options = {}) {
13
+ return convertOrgToMarkdown(convertMarkdownToOrg(markdown, options), options);
14
+ }
15
+ /**
16
+ * Normalizes an Org string to morg's canonical form: one full round trip
17
+ * (`org → md → org`), whose output is a fixed point (see ADR 0001).
18
+ * @param org The Org string to normalize.
19
+ * @param options Warning callback and dialect preset.
20
+ * @returns The canonical-form Org string.
21
+ */
22
+ export function normalizeOrg(org, options = {}) {
23
+ return convertMarkdownToOrg(convertOrgToMarkdown(org, options), options);
24
+ }
@@ -0,0 +1,102 @@
1
+ import type { Preset } from "./presets/types.js";
2
+ /**
3
+ * A feature toggle: `true`/`false` switches everything on/off, a record
4
+ * toggles individual constructs by name. Unlisted keys fall back to the
5
+ * flag's default. Mirrors the shape of the (planned) TOML config entries.
6
+ */
7
+ export type Toggle = boolean | Record<string, boolean>;
8
+ export declare function toggleEnabled(toggle: Toggle | undefined, key: string, defaultValue?: boolean): boolean;
9
+ export interface MarkdownToOrgOptions {
10
+ /**
11
+ * Preserve Markdown constructs without a native Org equivalent (e.g.
12
+ * raw HTML as export blocks/snippets, see ADR 0002). Default: `true`.
13
+ */
14
+ preserveMdisms?: Toggle;
15
+ /**
16
+ * Interpret the HTML vocabulary morg itself emits under `useHtml`
17
+ * (bare `<u>`, `<sup>`, `<sub>`, `<dl>/<dt>/<dd>` without attributes)
18
+ * as native Org constructs instead of preserving it as an md-ism.
19
+ * The inverse of `useHtml`; with both enabled the round trip is
20
+ * lossless. Any other HTML still preserves per `preserveMdisms`.
21
+ * Default: `false`.
22
+ */
23
+ interpretHtml?: boolean;
24
+ /**
25
+ * Record the Markdown style knobs detected in the source as a
26
+ * `#+MORG_MARKDOWN_STYLE:` keyword, so the return trip restores the source's own
27
+ * markers instead of morg's canonical ones (ADR 0004). Widens the set
28
+ * of inputs the Round Trip leaves untouched; it does not replace
29
+ * Convergence. Knobs used inconsistently are not recorded and warn.
30
+ * Default: `false`.
31
+ */
32
+ recordStyle?: boolean;
33
+ /**
34
+ * Custom names for org-ism `key::` lines, canonical → custom (e.g.
35
+ * `{ todo: "state" }`). Must match the mapping the file was written
36
+ * with — Convergence is per-config (ADR 0002).
37
+ */
38
+ orgismKeys?: Record<string, string>;
39
+ /** Called for each construct dropped without an equivalent. */
40
+ onWarning?: (message: string) => void;
41
+ /** Dialect preset applied on top of the generic conversion. */
42
+ preset?: Preset;
43
+ }
44
+ /**
45
+ * Markdown stringifier style knobs (subset of remark-stringify options).
46
+ * Canonical form is parameterized by these (see ADR 0001): round trips
47
+ * must use the same style, and files formatted under one style are not
48
+ * a fixed point under another. Defaults: `-` bullet, `*` emphasis /
49
+ * `*` strong (i.e. `**bold**`), backtick fences, `-` rule — prettier's
50
+ * choices except emphasis (`emphasis: "_"` aligns with prettier).
51
+ */
52
+ export interface MarkdownStyleOptions {
53
+ /** Unordered list marker. Default: `"-"`. */
54
+ bullet?: "-" | "*" | "+";
55
+ /** Emphasis (italic) marker. Default: `"*"`. */
56
+ emphasis?: "*" | "_";
57
+ /** Strong (bold) marker, doubled in output. Default: `"*"`. */
58
+ strong?: "*" | "_";
59
+ /** Code fence marker. Default: `` "`" ``. */
60
+ fence?: "`" | "~";
61
+ /** Thematic break marker, tripled in output. Default: `"-"`. */
62
+ rule?: "-" | "*" | "_";
63
+ /**
64
+ * How often to repeat the thematic break marker (minimum 3).
65
+ * Default: `3`. mdformat writes 70 underscores (`rule: "_"`,
66
+ * `ruleRepetition: 70`).
67
+ */
68
+ ruleRepetition?: number;
69
+ }
70
+ export interface OrgToMarkdownOptions {
71
+ /**
72
+ * Serialize Org constructs without a native Markdown equivalent as
73
+ * `key:: value` lines and verbatim passthroughs (see ADR 0002).
74
+ * Default: `true`.
75
+ */
76
+ preserveOrgisms?: Toggle;
77
+ /**
78
+ * Render Org constructs without a Markdown equivalent as raw HTML
79
+ * (`<u>`, `<sup>`, `<sub>`, `<dl>`) instead of keeping their org markup
80
+ * verbatim. HTML round-trips as a preserved md-ism (export blocks and
81
+ * snippets), not back to native org markup — a one-way door unless
82
+ * the return trip enables its inverse, `interpretHtml`.
83
+ * Default: `false`.
84
+ */
85
+ useHtml?: Toggle;
86
+ /**
87
+ * Map bare `TODO`/`DONE` leaf headlines (no priority, tags or content)
88
+ * to GFM task items (`- [ ]` / `- [x]`). Documented lossy export mode:
89
+ * headings become list items and do not restore to TODO headlines on
90
+ * the return trip; unmappable states keep the heading and warn.
91
+ * Default: `false`.
92
+ */
93
+ taskCheckboxes?: boolean;
94
+ /** Markdown output style; canonical form is per-config (ADR 0001). */
95
+ markdownStyle?: MarkdownStyleOptions;
96
+ /** Custom names for org-ism `key::` lines, canonical → custom. */
97
+ orgismKeys?: Record<string, string>;
98
+ /** Called for each construct dropped without an equivalent. */
99
+ onWarning?: (message: string) => void;
100
+ /** Dialect preset extracted before the generic conversion. */
101
+ preset?: Preset;
102
+ }
@@ -0,0 +1,9 @@
1
+ export function toggleEnabled(toggle, key, defaultValue = true) {
2
+ if (toggle === undefined) {
3
+ return defaultValue;
4
+ }
5
+ if (typeof toggle === "boolean") {
6
+ return toggle;
7
+ }
8
+ return toggle[key] ?? defaultValue;
9
+ }
@@ -0,0 +1,8 @@
1
+ import type { OrgToMarkdownOptions } from "./options.js";
2
+ /**
3
+ * Converts an Org-mode string to a Markdown string.
4
+ * @param org The Org-mode string to convert.
5
+ * @param options Conversion options (org-ism serialization, dialect preset).
6
+ * @returns The converted Markdown string.
7
+ */
8
+ export declare function convertOrgToMarkdown(org: string, options?: OrgToMarkdownOptions): string;
@@ -0,0 +1,61 @@
1
+ import { unified } from "unified";
2
+ import uniorgParse from "uniorg-parse";
3
+ import remarkStringify from "remark-stringify";
4
+ import remarkGfm from "remark-gfm";
5
+ import remarkFrontmatter from "remark-frontmatter";
6
+ import remarkMath from "remark-math";
7
+ import { transformUniorgAstToMdast } from "./core/uniorgToMdast/index.js";
8
+ import { takeRecordedStyle } from "./core/markdownStyle.js";
9
+ /**
10
+ * Converts an Org-mode string to a Markdown string.
11
+ * @param org The Org-mode string to convert.
12
+ * @param options Conversion options (org-ism serialization, dialect preset).
13
+ * @returns The converted Markdown string.
14
+ */
15
+ export function convertOrgToMarkdown(org, options = {}) {
16
+ // Phase 1: Parse Org-mode to uniorg-ast
17
+ let uniorgAst = unified().use(uniorgParse).parse(org);
18
+ // Phase 1b: a recorded style is morg's own (ADR 0004) — consume it so
19
+ // it does not travel on as frontmatter; explicit options still win
20
+ const recordedStyle = takeRecordedStyle(uniorgAst);
21
+ // Phase 2: Extract dialect preset conventions, if any
22
+ if (options.preset?.extractFromUniorg) {
23
+ uniorgAst = options.preset.extractFromUniorg(uniorgAst);
24
+ }
25
+ // Phase 3: Generic uniorg-ast to mdast transformation
26
+ const mdast = transformUniorgAstToMdast(uniorgAst, {
27
+ ...(options.preserveOrgisms !== undefined && {
28
+ preserveOrgisms: options.preserveOrgisms
29
+ }),
30
+ ...(options.useHtml !== undefined && { useHtml: options.useHtml }),
31
+ ...(options.taskCheckboxes !== undefined && {
32
+ taskCheckboxes: options.taskCheckboxes
33
+ }),
34
+ ...(options.orgismKeys !== undefined && {
35
+ orgismKeys: options.orgismKeys
36
+ }),
37
+ ...(options.onWarning !== undefined && { onWarning: options.onWarning })
38
+ });
39
+ // Phase 4: Render mdast to Markdown string
40
+ // bullet and rule "-" (not remark's default "*") are morg's canonical
41
+ // Markdown form; markdownStyle knobs override it (canonical form is
42
+ // then per-config, see ADR 0001)
43
+ const markdownContent = unified()
44
+ .use(remarkStringify, {
45
+ bullet: "-",
46
+ rule: "-",
47
+ ...recordedStyle,
48
+ ...options.markdownStyle,
49
+ handlers: {
50
+ // key:: value blocks and preset inline passthroughs (e.g.
51
+ // wikilinks) are emitted verbatim, unescaped
52
+ keyValue: (node) => node.value,
53
+ verbatimInline: (node) => node.value
54
+ }
55
+ })
56
+ .use(remarkGfm)
57
+ .use(remarkFrontmatter)
58
+ .use(remarkMath)
59
+ .stringify(mdast);
60
+ return markdownContent;
61
+ }
@@ -0,0 +1,25 @@
1
+ import type { OrgData } from "uniorg";
2
+ 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
+ /**
13
+ * Logseq dialect preset: `heading::` properties and outline nesting.
14
+ */
15
+ export declare function logseq(options?: LogseqPresetOptions): Preset;
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;