diff --git a/packages/parser/src/index.ts b/packages/parser/src/index.ts index fd3d918..260ded8 100644 --- a/packages/parser/src/index.ts +++ b/packages/parser/src/index.ts @@ -1,7 +1,7 @@ import type Token from 'markdown-it/lib/token' import MarkdownIt from 'markdown-it' -import type { ISectionOptions, IStylesOptions, Table, TableOfContents } from 'docx' -import { AlignmentType, BorderStyle, Document, Footer, Header, LevelFormat, Packer, PageNumber, Paragraph, SectionType, TextRun, convertInchesToTwip } from 'docx' +import type { ISectionOptions, IStylesOptions, Table } from 'docx' +import { AlignmentType, BorderStyle, Document, Footer, Header, LevelFormat, Packer, PageNumber, Paragraph, SectionType, StyleLevel, TableOfContents, TextRun, convertInchesToTwip } from 'docx' import type { IMarkdownReportConfig } from '@md-report/types' import { StyleId } from '@md-report/types' import { sliceParagraph, sliceSection } from './utils' @@ -27,7 +27,80 @@ export function parse(props: { markdown: string; config: IMarkdownReportConfig } export function parseDocument(tokens: Token[], styles: IStylesOptions): Document { // Variables. let pos = 0 - const sections: ISectionOptions[] = [] + const sections: ISectionOptions[] = [{ + properties: { + type: SectionType.NEXT_PAGE, + page: { + margin: { + top: convertInchesToTwip(1), + bottom: convertInchesToTwip(1), + left: convertInchesToTwip(1.25), + right: convertInchesToTwip(1.25), + }, + }, + }, + headers: { + default: new Header({ + children: [new Paragraph({ + style: StyleId.header, + border: { + bottom: { + color: 'auto', + style: BorderStyle.SINGLE, + size: 6, + }, + }, + text: '111', + })], + }), + even: new Header({ + children: [new Paragraph({ + style: StyleId.header, + border: { + bottom: { + color: 'auto', + style: BorderStyle.SINGLE, + size: 6, + }, + }, + text: '222', + })], + }), + }, + footers: { + default: new Footer({ + children: [new Paragraph({ + style: StyleId.footer, + children: [new TextRun({ + children: [PageNumber.CURRENT], + })], + })], + }), + even: new Footer({ + children: [new Paragraph({ + style: StyleId.footer, + children: [new TextRun({ + children: [PageNumber.CURRENT], + })], + })], + }), + }, + children: [ + new TableOfContents('TOC', { + stylesWithLevels: [ + new StyleLevel(StyleId.h1, 1), + new StyleLevel(StyleId.h2, 2), + new StyleLevel(StyleId.h3, 3), + new StyleLevel(StyleId.h4, 4), + new StyleLevel(StyleId.h5, 5), + new StyleLevel(StyleId.h6, 6), + ], + useAppliedParagraphOutlineLevel: true, + hyperlink: true, + headingStyleRange: '1-3', + }), + ], + }] // Split and parse sections. while (pos < tokens.length) { const { tokens: section, offset } = sliceSection(tokens.slice(pos)) @@ -148,6 +221,9 @@ export function parseDocument(tokens: Token[], styles: IStylesOptions): Document }, ], }, + features: { + updateFields: true, + }, evenAndOddHeaderAndFooters: true, styles, sections, diff --git a/packages/parser/src/inline.ts b/packages/parser/src/inline.ts index 1fb146e..74bb58a 100644 --- a/packages/parser/src/inline.ts +++ b/packages/parser/src/inline.ts @@ -9,7 +9,7 @@ import { sliceInlineText } from './utils' export function parseInline(props: { tokens: Token[]; style?: StyleId; headingLevel?: number; isUL?: boolean; isOL?: boolean }): Paragraph { // Props. - const { tokens, style = StyleId.normal, headingLevel = 0, isOL = false, isUL = false } = props + const { tokens, style = StyleId.p, headingLevel = 0, isOL = false, isUL = false } = props const { children: childrenTokens, level } = tokens[0] if (!childrenTokens) return new Paragraph({}) diff --git a/packages/parser/src/paragraph.ts b/packages/parser/src/paragraph.ts index 75b3030..19b54c8 100644 --- a/packages/parser/src/paragraph.ts +++ b/packages/parser/src/paragraph.ts @@ -1,6 +1,6 @@ import type Token from 'markdown-it/lib/token' import type { IBorderOptions } from 'docx' -import { BorderStyle, Math, MathRun, Paragraph, Table, TableCell, TableRow, TextRun } from 'docx' +import { BorderStyle, Math, MathRun, Paragraph, Table, TableCell, TableRow, TextRun, WidthType } from 'docx' import { StyleId } from '@md-report/types' import { MathBlockRegExp, sliceTableRow } from './utils' import { parseInline } from './inline' @@ -44,6 +44,10 @@ export function parseTable(tokens: Token[]): Table { export function parseTableRow(tokens: Token[]): TableRow { const cells: Token[] = tokens.filter(token => token.type === 'inline') const children: TableCell[] = cells.map(cell => new TableCell({ + width: { + size: 1 / cells.length, + type: WidthType.PERCENTAGE, + }, children: [parseInline({ tokens: [cell], style: StyleId.table, diff --git a/packages/parser/src/utils.ts b/packages/parser/src/utils.ts index 319425b..c15365a 100644 --- a/packages/parser/src/utils.ts +++ b/packages/parser/src/utils.ts @@ -36,9 +36,12 @@ export function sliceParagraph(tokens: Token[]): SliceResult { } export function sliceTableRow(tokens: Token[]): SliceResult { - let offset = 0 - while (tokens[offset]?.type !== 'tr_open') + let offset = 1 + while (offset < tokens.length) { + if (tokens[offset].type === 'tr_open') + break offset++ + } return { tokens: tokens.slice(0, offset), offset,