Apply brand kit colors and fonts to DOCX export
Use antique gold accent, rich black text, Cormorant Garamond headings, and Lora body text. Remove fill backgrounds, keeping only the gold left-border scripture callout and section divider. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+49
-17
@@ -513,18 +513,21 @@ export function createParagraphsFromText(text) {
|
|||||||
.map((line) => new Paragraph({ children: [new TextRun({ text: line })] }));
|
.map((line) => new Paragraph({ children: [new TextRun({ text: line })] }));
|
||||||
}
|
}
|
||||||
|
|
||||||
const DOCX_ACCENT = '0F766E'; // teal-700
|
const DOCX_ACCENT = 'C9A84C'; // antique gold
|
||||||
|
const DOCX_HEADING_FONT = 'Cormorant Garamond';
|
||||||
|
const DOCX_BODY_FONT = 'Lora';
|
||||||
|
|
||||||
export function sectionLabel(text) {
|
export function sectionLabel(text) {
|
||||||
return new Paragraph({
|
return new Paragraph({
|
||||||
spacing: { before: 240, after: 80 },
|
spacing: { before: 240, after: 80 },
|
||||||
shading: { type: ShadingType.CLEAR, fill: 'F0FDFA' },
|
|
||||||
children: [
|
children: [
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: text.toUpperCase(),
|
text: text.toUpperCase(),
|
||||||
bold: true,
|
bold: true,
|
||||||
color: DOCX_ACCENT,
|
color: DOCX_ACCENT,
|
||||||
|
font: DOCX_BODY_FONT,
|
||||||
size: 20,
|
size: 20,
|
||||||
|
characterSpacing: 20,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -2195,7 +2198,7 @@ const App = () => {
|
|||||||
new TextRun({
|
new TextRun({
|
||||||
text: `${project.translation} — ${buildChapterSummary(project)}`,
|
text: `${project.translation} — ${buildChapterSummary(project)}`,
|
||||||
italics: true,
|
italics: true,
|
||||||
color: '64748B',
|
color: '7A7060',
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
spacing: { after: 300 },
|
spacing: { after: 300 },
|
||||||
@@ -2214,18 +2217,18 @@ const App = () => {
|
|||||||
ch.chunks.forEach((chunk) => {
|
ch.chunks.forEach((chunk) => {
|
||||||
const scriptureHeading = formatChunkReference(project, chapterIndex, chunk, '-');
|
const scriptureHeading = formatChunkReference(project, chapterIndex, chunk, '-');
|
||||||
|
|
||||||
const headingRuns = [new TextRun({ text: scriptureHeading, bold: true, size: 28, color: DOCX_ACCENT })];
|
const headingRuns = [new TextRun({ text: scriptureHeading, bold: true, size: 28, color: DOCX_ACCENT, font: DOCX_HEADING_FONT })];
|
||||||
if (chunk.episodeNumber || chunk.episodeTitle) {
|
if (chunk.episodeNumber || chunk.episodeTitle) {
|
||||||
headingRuns.push(new TextRun({
|
headingRuns.push(new TextRun({
|
||||||
text: ` (Ep. ${chunk.episodeNumber || '—'}${chunk.episodeTitle ? `: ${chunk.episodeTitle}` : ''})`,
|
text: ` (Ep. ${chunk.episodeNumber || '—'}${chunk.episodeTitle ? `: ${chunk.episodeTitle}` : ''})`,
|
||||||
italics: true,
|
italics: true,
|
||||||
size: 22,
|
size: 22,
|
||||||
color: '64748B',
|
color: '7A7060',
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
children.push(new Paragraph({ children: headingRuns, spacing: { before: 320, after: 120 } }));
|
children.push(new Paragraph({ children: headingRuns, spacing: { before: 320, after: 120 } }));
|
||||||
|
|
||||||
// Scripture text in a shaded, left-bordered table cell for a "callout" look
|
// Scripture text in a left-bordered table cell for a "callout" look (no fill)
|
||||||
const scriptureParas = getChunkVerseEntries(project, chapterIndex, chunk).map((verse) => new Paragraph({
|
const scriptureParas = getChunkVerseEntries(project, chapterIndex, chunk).map((verse) => new Paragraph({
|
||||||
children: [
|
children: [
|
||||||
new TextRun({ text: `${verse.chapter}:${verse.number} `, bold: true, color: DOCX_ACCENT }),
|
new TextRun({ text: `${verse.chapter}:${verse.number} `, bold: true, color: DOCX_ACCENT }),
|
||||||
@@ -2239,7 +2242,6 @@ const App = () => {
|
|||||||
new TableRow({
|
new TableRow({
|
||||||
children: [
|
children: [
|
||||||
new TableCell({
|
new TableCell({
|
||||||
shading: { type: ShadingType.CLEAR, fill: 'F8FAFC' },
|
|
||||||
margins: { top: 120, bottom: 120, left: 180, right: 180 },
|
margins: { top: 120, bottom: 120, left: 180, right: 180 },
|
||||||
borders: {
|
borders: {
|
||||||
...{ top: noBorder, right: noBorder, bottom: noBorder },
|
...{ top: noBorder, right: noBorder, bottom: noBorder },
|
||||||
@@ -2285,21 +2287,21 @@ const App = () => {
|
|||||||
children.push(sectionLabel('Word Studies'));
|
children.push(sectionLabel('Word Studies'));
|
||||||
const headerCellStyle = (label) => new TableCell({
|
const headerCellStyle = (label) => new TableCell({
|
||||||
width: { size: 20, type: WidthType.PERCENTAGE },
|
width: { size: 20, type: WidthType.PERCENTAGE },
|
||||||
shading: { type: ShadingType.CLEAR, fill: DOCX_ACCENT },
|
borders: { bottom: { style: BorderStyle.SINGLE, size: 8, color: DOCX_ACCENT } },
|
||||||
children: [new Paragraph({ children: [new TextRun({ text: label, bold: true, color: 'FFFFFF' })] })],
|
children: [new Paragraph({ children: [new TextRun({ text: label, bold: true, color: DOCX_ACCENT })] })],
|
||||||
});
|
});
|
||||||
const tableRows = [
|
const tableRows = [
|
||||||
new TableRow({
|
new TableRow({
|
||||||
tableHeader: true,
|
tableHeader: true,
|
||||||
children: ['Strong', 'Greek', 'Transliteration', 'Part of Speech', 'Short Definition'].map(headerCellStyle),
|
children: ['Strong', 'Greek', 'Transliteration', 'Part of Speech', 'Short Definition'].map(headerCellStyle),
|
||||||
}),
|
}),
|
||||||
...chunk.greekWords.map((word, i) => new TableRow({
|
...chunk.greekWords.map((word) => new TableRow({
|
||||||
children: [
|
children: [
|
||||||
new TableCell({ shading: i % 2 ? { type: ShadingType.CLEAR, fill: 'F8FAFC' } : undefined, children: [new Paragraph(word.strongNumber || '')] }),
|
new TableCell({ children: [new Paragraph(word.strongNumber || '')] }),
|
||||||
new TableCell({ shading: i % 2 ? { type: ShadingType.CLEAR, fill: 'F8FAFC' } : undefined, children: [new Paragraph(word.lexeme || '')] }),
|
new TableCell({ children: [new Paragraph(word.lexeme || '')] }),
|
||||||
new TableCell({ shading: i % 2 ? { type: ShadingType.CLEAR, fill: 'F8FAFC' } : undefined, children: [new Paragraph(word.transliteration || '')] }),
|
new TableCell({ children: [new Paragraph(word.transliteration || '')] }),
|
||||||
new TableCell({ shading: i % 2 ? { type: ShadingType.CLEAR, fill: 'F8FAFC' } : undefined, children: [new Paragraph(word.partOfSpeech || '')] }),
|
new TableCell({ children: [new Paragraph(word.partOfSpeech || '')] }),
|
||||||
new TableCell({ shading: i % 2 ? { type: ShadingType.CLEAR, fill: 'F8FAFC' } : undefined, children: [new Paragraph(word.shortDefinition || '')] }),
|
new TableCell({ children: [new Paragraph(word.shortDefinition || '')] }),
|
||||||
],
|
],
|
||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
@@ -2323,12 +2325,42 @@ const App = () => {
|
|||||||
children.push(new Paragraph({
|
children.push(new Paragraph({
|
||||||
text: '',
|
text: '',
|
||||||
spacing: { after: 200 },
|
spacing: { after: 200 },
|
||||||
border: { bottom: { style: BorderStyle.SINGLE, size: 4, color: 'E2E8F0', space: 8 } },
|
border: { bottom: { style: BorderStyle.SINGLE, size: 4, color: '2A2518', space: 8 } },
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const doc = new Document({ sections: [{ children }] });
|
const doc = new Document({
|
||||||
|
styles: {
|
||||||
|
default: {
|
||||||
|
document: { run: { font: DOCX_BODY_FONT, color: '0A0A08' } },
|
||||||
|
},
|
||||||
|
paragraphStyles: [
|
||||||
|
{
|
||||||
|
id: 'Title',
|
||||||
|
name: 'Title',
|
||||||
|
basedOn: 'Normal',
|
||||||
|
next: 'Normal',
|
||||||
|
run: { font: DOCX_HEADING_FONT, size: 56, bold: true, color: '0A0A08' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'Heading1',
|
||||||
|
name: 'Heading 1',
|
||||||
|
basedOn: 'Normal',
|
||||||
|
next: 'Normal',
|
||||||
|
run: { font: DOCX_HEADING_FONT, size: 36, bold: true, color: '0A0A08' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'Heading2',
|
||||||
|
name: 'Heading 2',
|
||||||
|
basedOn: 'Normal',
|
||||||
|
next: 'Normal',
|
||||||
|
run: { font: DOCX_HEADING_FONT, size: 30, bold: true, color: '0A0A08' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
sections: [{ children }],
|
||||||
|
});
|
||||||
const blob = await Packer.toBlob(doc);
|
const blob = await Packer.toBlob(doc);
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
|
|||||||
Reference in New Issue
Block a user