UNPKG

org-meta-filter

Version:

pandoc filter to use org-mode custom keywords as metadata

82 lines (68 loc) 2 kB
#!/usr/bin/env node const getStdin = require('get-stdin') const { complement, equals, filter, head, ifElse, join, map, mergeAll, nth, pipe, prop, replace, splitWhen, tail, // tap, trim, where, } = require('ramda') /* const { writeFileSync } = require('fs') const debug = (subject, chunk) => writeFileSync(`debug-${subject}.json`, JSON.stringify(chunk)) const debugPipe = subject => tap(chunk => debug(subject, chunk)) */ const beforeChar = char => pipe(splitWhen(equals(char)), head, join('')) const afterChar = char => pipe(splitWhen(equals(char)), nth(1), tail, join('')) const getPandocValue = prop('c') const getPandocRawBlockValue = pipe(getPandocValue, nth(1)) // '#+key:value' => ['key', 'value'] const getOrgMetadata = rawMetadata => { const key = pipe(beforeChar(':'), replace('#+', ''))(rawMetadata) const value = pipe(afterChar(':'), trim)(rawMetadata) return [key, value] } const toPandocStr = str => [{ t: 'Str', c: str }] const toPandocMetaInlines = str => ({ t: 'MetaInlines', c: toPandocStr(str) }) const toPandocMetaBool = bool => ({ t: 'MetaBool', c: Boolean(bool) }) const isBoolString = str => ['true', 'false'].includes(str) const toPandocMetaValue = ifElse( isBoolString, toPandocMetaBool, toPandocMetaInlines ) const toPandocMeta = ([key, value]) => ({ [key]: toPandocMetaValue(value) }) const isMetadata = where({ t: equals('RawBlock'), c: pipe(head, equals('org')), }) const removeMetadata = filter(complement(isMetadata)) const main = async () => { let ast = JSON.parse(await getStdin()) const rawMetadata = filter(isMetadata, ast.blocks) if (rawMetadata.length > 0) { // extract keywords ast.blocks = removeMetadata(ast.blocks) const metadata = pipe( map(pipe(getPandocRawBlockValue, getOrgMetadata, toPandocMeta)), mergeAll )(rawMetadata) // and add as metadata ast.meta = mergeAll([metadata, ast.meta]) } process.stdout.write(JSON.stringify(ast)) } main()