Skip to content

Instantly share code, notes, and snippets.

@kalda341
Created November 27, 2019 03:46
Show Gist options
  • Save kalda341/b102c6f030f62a576e761c0ed8315242 to your computer and use it in GitHub Desktop.
Save kalda341/b102c6f030f62a576e761c0ed8315242 to your computer and use it in GitHub Desktop.
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