Created
November 27, 2019 03:46
-
-
Save kalda341/b102c6f030f62a576e761c0ed8315242 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Paragraph, PageBreak, TextRun } from 'docx'; | |
import { | |
curry, | |
compose, | |
reject, | |
assoc, | |
isNil, | |
merge, | |
map, | |
split, | |
when, | |
is | |
} from 'ramda'; | |
import { collectContents } from './util'; | |
export const TextGenerator = documentStyle => { | |
const runWithParams = curry( | |
(runParams, text) => | |
new TextRun( | |
assoc( | |
'text', | |
// We shouldn't have any newlines in a run, but replace them with spaces if they do exist | |
text.replace(/\n/g, ' '), | |
runParams | |
) | |
) | |
); | |
const collectRuns = compose( | |
// Ensure any strings become runs | |
map(when(is(String), runWithParams({}))), | |
collectContents | |
); | |
const pWithParams = curry( | |
(paraParams, runs) => | |
new Paragraph(assoc('children', collectRuns(runs), paraParams)) | |
); | |
const p = pWithParams({}); | |
const multilinePWithParams = curry((paraParams, text) => | |
compose( | |
map(pWithParams(paraParams)), | |
split('\n') | |
)(text) | |
); | |
const multilineP = multilinePWithParams({}); | |
const bullet = pWithParams({ | |
numbering: { | |
num: documentStyle.numbering.bulletNumbering, | |
level: 0, | |
custom: true | |
} | |
}); | |
const lineBreak = () => p(''); | |
const pageBreak = () => p(new PageBreak()); | |
const boldP = compose( | |
p, | |
runWithParams({ bold: true }) | |
); | |
const italicP = compose( | |
p, | |
runWithParams({ italics: true }) | |
); | |
const frameworkP = compose( | |
map( | |
pWithParams({ | |
style: documentStyle.paragraphStyles.frameworkStyle.id | |
}) | |
), | |
split('\n') | |
); | |
const italicFrameworkP = compose( | |
pWithParams({ style: documentStyle.paragraphStyles.frameworkStyle.id }), | |
runWithParams({ italics: true }) | |
); | |
const frameworkBullet = pWithParams({ | |
style: documentStyle.paragraphStyles.frameworkStyle.id, | |
numbering: { | |
num: documentStyle.numbering.bulletNumbering, | |
level: 0, | |
custom: true | |
} | |
}); | |
const todoP = pWithParams({ | |
style: documentStyle.paragraphStyles.todoStyle.id | |
}); | |
const styledParagraph = style => pWithParams({ heading: style.id }); | |
const numberedHeading = (style, numberingLevel) => | |
pWithParams({ | |
heading: style.id, | |
numbering: { | |
num: documentStyle.numbering.headingNumbering, | |
level: numberingLevel, | |
custom: true | |
} | |
}); | |
const title = styledParagraph(documentStyle.paragraphStyles.titleStyle); | |
const h1 = numberedHeading(documentStyle.paragraphStyles.h1Style, 0); | |
const h1NoToC = styledParagraph(documentStyle.paragraphStyles.h1NoTocStyle); | |
const h2 = numberedHeading(documentStyle.paragraphStyles.h2Style, 1); | |
const h2NoToC = styledParagraph(documentStyle.paragraphStyles.h2NoTocStyle); | |
const h3 = numberedHeading(documentStyle.paragraphStyles.h3Style, 2); | |
const h3NoToC = styledParagraph(documentStyle.paragraphStyles.h3NoTocStyle); | |
const h4 = styledParagraph(documentStyle.paragraphStyles.h4Style); | |
const caption = styledParagraph(documentStyle.paragraphStyles.captionStyle); | |
const preparedWith = styledParagraph( | |
documentStyle.paragraphStyles.preparedWithStyle | |
); | |
const tableHeading = styledParagraph( | |
documentStyle.paragraphStyles.tableHeadingStyle | |
); | |
const tableColumnHeading = styledParagraph( | |
documentStyle.paragraphStyles.tableColumnHeadingStyle | |
); | |
// Not numbered, but in ToC | |
const appendixTitle = styledParagraph(documentStyle.paragraphStyles.h1Style); | |
const keyValueWithParams = curry( | |
(params, key, value) => | |
new Paragraph( | |
merge( | |
{ | |
children: [ | |
new TextRun({ text: key + ': ', bold: true }), | |
new TextRun({ text: value }) | |
] | |
}, | |
params | |
) | |
) | |
); | |
const keyValue = keyValueWithParams({}); | |
const points = curry((key, values) => [ | |
p(`${key}:`), | |
...values.map(value => bullet(value)) | |
]); | |
// points but key is bold | |
const keyBulletedValues = curry((key, values) => [ | |
boldP(`${key}:`), | |
...values.map(value => bullet(value)) | |
]); | |
const pointsSubsection = curry((sectionTitle, points) => { | |
const filteredPoints = reject(isNil, points); | |
// Only include subsections if there are points | |
if (filteredPoints.length) { | |
return [h4(sectionTitle), points]; | |
} | |
}); | |
const pageNumber = () => new TextRun('').pageNumber(); | |
return { | |
// Formatting escape hatches | |
runWithParams, | |
pWithParams, | |
// Normal formatting | |
p, | |
multilineP, | |
bullet, | |
lineBreak, | |
pageBreak, | |
boldP, | |
italicP, | |
points, | |
keyValue, | |
keyBulletedValues, | |
pointsSubsection, | |
title, | |
h1, | |
h1NoToC, | |
h2, | |
h2NoToC, | |
h3, | |
h3NoToC, | |
h4, | |
caption, | |
preparedWith, | |
appendixTitle, | |
todoP, | |
tableHeading, | |
tableColumnHeading, | |
// Framework formatting | |
frameworkP, | |
italicFrameworkP, | |
frameworkBullet, | |
// Misc | |
pageNumber | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment