Skip to content

Commit

Permalink
Throw MissingCloseDelimiterError when tag is split between paragraphs
Browse files Browse the repository at this point in the history
Related #90
Fixes #126
  • Loading branch information
alonrbar committed Jan 28, 2025
1 parent adbadb1 commit 03e8460
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/compilation/tagParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ export class TagParser {
let endTextNode = closeDelimiter.xmlTextNode;
const sameNode = (startTextNode === endTextNode);

if (!sameNode) {
const startParagraph = this.docParser.containingParagraphNode(startTextNode);
const endParagraph = this.docParser.containingParagraphNode(endTextNode);
if (startParagraph !== endParagraph) {
throw new MissingCloseDelimiterError(startTextNode.textContent);
}
}

// trim start
if (openDelimiter.index > 0) {
this.docParser.splitTextNode(startTextNode, openDelimiter.index, true);
Expand Down
37 changes: 36 additions & 1 deletion test/unit/compilation/tagParser.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { DelimiterMark } from 'src/compilation/delimiterMark';
import { TagDisposition } from 'src/compilation/tag';
import { TagParser } from 'src/compilation/tagParser';
import { Delimiters } from 'src/delimiters';
import { TagOptionsParseError } from 'src/errors';
import { MissingCloseDelimiterError, TagOptionsParseError } from 'src/errors';
import { DocxParser } from 'src/office';
import { XmlParser, XmlTextNode } from 'src/xml';
import { parseXml } from '../../testUtils';
Expand Down Expand Up @@ -338,6 +338,41 @@ describe(TagParser, () => {
expect(tags[2].rawText).toEqual('{/loop}');
});

test('close delimiter in different paragraph throws MissingCloseDelimiterError', () => {

const body = parseXml(`
<w:body>
<w:p><w:r><w:t>{my_simple_</w:t></w:r></w:p>
<w:p><w:r><w:t>tag}</w:t></w:r></w:p>
</w:body>
`, false);

const firstParagraph = body.childNodes.find(node => node.nodeName === 'w:p');
const secondParagraph = body.childNodes.findLast(node => node.nodeName === 'w:p');

const firstRun = firstParagraph.childNodes[0];
const secondRun = secondParagraph.childNodes[0];

const firstTextNode = firstRun.childNodes[0] as XmlTextNode;
const secondTextNode = secondRun.childNodes[0] as XmlTextNode;

const delimiters: DelimiterMark[] = [
{
isOpen: true,
index: 0,
xmlTextNode: firstTextNode
},
{
isOpen: false,
index: 4,
xmlTextNode: secondTextNode
}
];

const parser = createTagParser();
expect(() => parser.parse(delimiters)).toThrow(MissingCloseDelimiterError);
});

test('tag options - simple', () => {

const text = '{#loop [opt: "yes"]}{/loop}';
Expand Down

0 comments on commit 03e8460

Please sign in to comment.