uniorg-rehype
Advanced tools
Comparing version 0.4.7 to 0.4.8
@@ -0,1 +1,2 @@ | ||
import { Node } from 'hast'; | ||
import { OrgData } from 'uniorg'; | ||
@@ -9,4 +10,18 @@ declare type Hast = any; | ||
useSections: boolean; | ||
/** | ||
* A function to wrap footnotes. First argument of the function is | ||
* an array of all footnote definitions and the function should | ||
* return a new Hast node to be appended to the document. | ||
* | ||
* Roughly corresponds to `org-html-footnotes-section`. | ||
* | ||
* Default is: | ||
* ``` | ||
* <h1>Footnotes:</h1> | ||
* {...footnotes} | ||
* ``` | ||
*/ | ||
footnotesSection: (footnotes: Node[]) => Node[]; | ||
} | ||
export declare function orgToHast(org: OrgData, opts?: Partial<OrgToHastOptions>): Hast; | ||
export {}; |
@@ -26,2 +26,6 @@ "use strict"; | ||
useSections: false, | ||
footnotesSection: (footnotes) => [ | ||
h(null, 'h1', {}, 'Footnotes:'), | ||
...footnotes, | ||
], | ||
}; | ||
@@ -63,2 +67,6 @@ // `org-html-html5-elements` | ||
const options = Object.assign(Object.assign({}, defaultOptions), opts); | ||
const ctx = { | ||
footnotesOrder: [], | ||
footnotes: {}, | ||
}; | ||
return toHast(org); | ||
@@ -79,3 +87,30 @@ function toHast(node) { | ||
case 'org-data': | ||
return { type: 'root', children: toHast(org.children) }; | ||
const children = toHast(org.children); | ||
const footnotes = ctx.footnotesOrder | ||
.map((name, i) => { | ||
const def = ctx.footnotes[name]; | ||
if (!def) { | ||
// missing footnote definition | ||
return null; | ||
} | ||
return h(org, 'div', { className: 'footnote-definition' }, [ | ||
h(null, 'sup', {}, h(null, 'a', { | ||
className: 'footnum', | ||
id: `fn.${i + 1}`, | ||
href: `#fnr.${i + 1}`, | ||
role: 'doc-backlink', | ||
}, String(i + 1))), | ||
h(org, 'div', { className: 'footdef', role: 'doc-footnote' }, toHast(def.children)), | ||
]); | ||
}) | ||
.filter((x) => x !== null); | ||
if (footnotes.length !== 0) { | ||
if (opts.useSections) { | ||
children.push(h(null, 'section', {}, options.footnotesSection(footnotes))); | ||
} | ||
else { | ||
children.push(...options.footnotesSection(footnotes)); | ||
} | ||
} | ||
return { type: 'root', children }; | ||
case 'section': { | ||
@@ -178,4 +213,33 @@ const headline = org.children[0]; | ||
case 'footnote-reference': | ||
// index of footnote in ctx.footnotesOrder | ||
let idx = 0; | ||
let id = ''; | ||
if (org.footnoteType === 'inline') { | ||
idx = ctx.footnotesOrder.length; | ||
ctx.footnotesOrder.push(idx); | ||
ctx.footnotes[idx] = org; | ||
id = `fnr.${idx + 1}`; | ||
} | ||
else if (org.footnoteType === 'standard') { | ||
idx = ctx.footnotesOrder.findIndex((label) => label === org.label); | ||
if (idx === -1) { | ||
idx = ctx.footnotesOrder.length; | ||
ctx.footnotesOrder.push(org.label); | ||
id = `fnr.${idx + 1}`; | ||
// We do not set id in the else branch because that’s a | ||
// second reference to this footnote—another reference | ||
// with this id exists. | ||
} | ||
} | ||
else { | ||
throw new Error(`unknown footnoteType: ${org.footnoteType}`); | ||
} | ||
return h(null, 'sup', {}, h(org, 'a', { | ||
href: `#fn.${idx + 1}`, | ||
className: ['footref'], | ||
id, | ||
role: 'doc-backlink', | ||
}, String(idx + 1))); | ||
case 'footnote-definition': | ||
// TODO: serialize footnotes and footnote definitions. | ||
ctx.footnotes[org.label] = org; | ||
return null; | ||
@@ -182,0 +246,0 @@ case 'paragraph': |
@@ -199,2 +199,27 @@ "use strict"; | ||
hastTest('diary sexp', `%%(diary-anniversary 10 31 1948) Arthur's birthday (%d years old)`); | ||
describe('footnotes', () => { | ||
hastTest('footnote-reference', `Some text with a footnote.[fn:1] | ||
[fn:1] A very important footnote.`); | ||
hastTest('footnote-definition', `Some text with a footnote.[fn:1] | ||
Another footnote [fn:2] | ||
[fn:1] A very important footnote. | ||
[fn:2] Another stellar footnote.`); | ||
hastTest('inline footnote', 'some text[fn:1: footnote definition]'); | ||
hastTest('maintains footnotes order', | ||
// Note that footnotes are emmitted in order of reference | ||
`footnote 2[fn:2] | ||
footnote 1[fn:1] | ||
[fn:1] second footnote | ||
[fn:2] first footnote`); | ||
hastTest('does not emit unreferenced footnotes', `footnote[fn:1] | ||
[fn:1] hello | ||
[fn:2] unreferenced`); | ||
hastTest('handles missing footnotes', 'footnote[fn:missing]'); | ||
hastTest('inline footnote', 'footnotes[fn:label: inline footnote definition]'); | ||
hastTest('anonymous inline footnote', 'footnotes[fn:: inline footnote definition]'); | ||
}); | ||
hastTest('latex-fragment', `If $a^2=b$ and \\( b=2 \\), then the solution must be | ||
@@ -201,0 +226,0 @@ either $$ a=+\\sqrt{2} $$ or \\[ a=-\\sqrt{2} \\].`); |
{ | ||
"name": "uniorg-rehype", | ||
"version": "0.4.7", | ||
"version": "0.4.8", | ||
"description": "uniorg plugin to transform to rehype", | ||
@@ -55,3 +55,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "12f12fe6abb923fbbfff280db2aa7bf398d08785" | ||
"gitHead": "14f804eaedebff32e74004498baa4c7c30a823b4" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
80107
15
635