jsreport / jsreport-docx

jsreport recipe rendering word docx
MIT License
10 stars 3 forks source link

Support shapes with textbox in if blocks #27

Closed pdecat closed 3 years ago

pdecat commented 3 years ago

This PR intends to fix #26 by adding a comment right after closing </w:p> block helper tags to avoid matching nested </w:p> closing tags.

pdecat commented 3 years ago

This resolves the issue I reported in #26 but other tests are currently failing:

  97 passing (10s)
  8 failing

  1) docx
       list:
     AssertionError: expected 'This is title Some prefix: Jan And some postfix ' to contain 'Boris'
      at Assertion.fail (node_modules/should/cjs/should.js:275:17)
      at Assertion.value [as containEql] (node_modules/should/cjs/should.js:356:19)
      at Context.<anonymous> (test/test.js:569:17)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  2) docx
       list and links:
     AssertionError: expected 'jsreport ' to contain 'github'
      at Assertion.fail (node_modules/should/cjs/should.js:275:17)
      at Assertion.value [as containEql] (node_modules/should/cjs/should.js:356:19)
      at Context.<anonymous> (test/test.js:603:17)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  3) docx
       list nested:
     AssertionError: expected 'Boris item1 ' to contain 'Junior'
      at Assertion.fail (node_modules/should/cjs/should.js:275:17)
      at Assertion.value [as containEql] (node_modules/should/cjs/should.js:356:19)
      at Context.<anonymous> (test/test.js:716:17)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  4) docx
       table rows, columns (block):
     AssertionError: expected ' Name ' to contain 'Email'
      at Assertion.fail (node_modules/should/cjs/should.js:275:17)
      at Assertion.value [as containEql] (node_modules/should/cjs/should.js:356:19)
      at Context.<anonymous> (test/test.js:1135:17)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  5) docx
       table rows, columns (block and data index):
     AssertionError: expected ' 0-0 ' to contain '0-1'
      at Assertion.fail (node_modules/should/cjs/should.js:275:17)
      at Assertion.value [as containEql] (node_modules/should/cjs/should.js:356:19)
      at Context.<anonymous> (test/test.js:1168:17)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  6) docx
       table rows, columns (block and access to parent context):
     AssertionError: expected ' My Table - Name ' to contain 'My Table - Email'
      at Assertion.fail (node_modules/should/cjs/should.js:275:17)
      at Assertion.value [as containEql] (node_modules/should/cjs/should.js:356:19)
      at Context.<anonymous> (test/test.js:1202:17)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  7) docx
       text nodes with xml:space="preserve" should continue to exists when needed:
     AssertionError: expected ' My Table - Name ' to contain 'My Table - Email'
      at Assertion.fail (node_modules/should/cjs/should.js:275:17)
      at Assertion.value [as containEql] (node_modules/should/cjs/should.js:356:19)
      at Context.<anonymous> (test/test.js:4129:17)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  8) docx
       remove nodes that were just containing block helper definition calls:
     AssertionError: expected ' My Table - Name ' to contain 'My Table - Email'
      at Assertion.fail (node_modules/should/cjs/should.js:275:17)
      at Assertion.value [as containEql] (node_modules/should/cjs/should.js:356:19)
      at Context.<anonymous> (test/test.js:4179:17)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

npm ERR! Test failed.  See above for more details.
pdecat commented 3 years ago

Adding the block helper comment inside the <w:p/> block helper tags ensures the comment is not moved around.

All tests are now passing:

npm test

> jsreport-docx@2.9.1 test /home/patrick/workspaces/js/jsreport/jsreport-docx
> mocha test --timeout 8000 && standard

  docx
    ✓ condition-with-helper-call (836ms)
    ✓ condition with docProps/thumbnail.jpeg in docx (109ms)
    ✓ variable-replace (88ms)
    ✓ variable-replace-multi (73ms)
    ✓ variable-replace-syntax-error
    ✓ invoice (169ms)
    ✓ endnote (79ms)
    ✓ footnote (59ms)
    ✓ link (57ms)
    ✓ link in header (149ms)
    ✓ link in footer (143ms)
    ✓ link in header, footer (149ms)
    ✓ link to bookmark should not break (133ms)
    ✓ watermark (58ms)
    ✓ list (62ms)
    ✓ list and links (76ms)
    ✓ list and endnotes (60ms)
    ✓ list and footnotes (68ms)
    ✓ list nested (74ms)
    ✓ variable-replace-and-list-after (51ms)
    ✓ variable-replace-and-list-after2 (79ms)
    ✓ variable-replace-and-list-after-syntax-error
    ✓ table (60ms)
    ✓ table and links (106ms)
    ✓ table and endnotes (89ms)
    ✓ table and footnotes (101ms)
    ✓ table nested (63ms)
    ✓ table vertical (58ms)
    ✓ table rows, columns (58ms)
    ✓ table rows, columns (block) (58ms)
    ✓ table rows, columns (block and data index) (58ms)
    ✓ table rows, columns (block and access to parent context) (56ms)
    ✓ style (47ms)
    ✓ image (51ms)
    ✓ image with placeholder size (usePlaceholderSize) (62ms)
    ✓ image with hyperlink inside (51ms)
    ✓ image error message when no src provided (42ms)
    ✓ image can render from url (52ms)
    ✓ image error message when src not valid param
    ✓ image error message when width not valid param (53ms)
    ✓ image error message when height not valid param
    ✓ image loop (59ms)
    ✓ image loop and hyperlink inside (56ms)
    ✓ image loop with bookmarks (138ms)
    ✓ loop (58ms)
    ✓ complex (687ms)
    ✓ input form control (70ms)
    ✓ checkbox form control (42ms)
    ✓ combobox form control (53ms)
    ✓ combobox form control with constant value (60ms)
    ✓ combobox form control with dynamic items (53ms)
    ✓ combobox form control with dynamic items in strings (55ms)
    ✓ combobox form control with dynamic items in strings and special character (51ms)
    ✓ chart (59ms)
    ✓ chart should allow adding more data series than the ones defined in template (67ms)
    ✓ chart should allow adding less data series than the ones defined in template (61ms)
    ✓ chart should allow producing chart with serie with empty values (63ms)
    ✓ chart should allow axis configuration for display (61ms)
    ✓ chart should allow axis configuration for min value (66ms)
    ✓ chart should allow axis configuration for max value (52ms)
    ✓ chart should allow axis configuration for min, max values (49ms)
    ✓ chart should allow axis configuration for stepSize value (49ms)
    ✓ chart should allow setting datalabels (52ms)
    ✓ chart without style, color xml files (52ms)
    ✓ chart with title (51ms)
    ✓ chart with dynamic title (51ms)
    ✓ scatter chart (47ms)
    ✓ bubble chart (48ms)
    ✓ stock chart (58ms)
    ✓ combo chart (chart that uses a different chart type per data serie) (67ms)
    ✓ waterfall chart (chartex) (64ms)
    ✓ funnel chart (chartex) (59ms)
    ✓ treemap chart (chartex) (74ms)
    ✓ sunburst chart (chartex) (89ms)
    ✓ clusteredColumn (chartex) (59ms)
    ✓ chart error message when no data (38ms)
    ✓ chart error message when no data.labels
    ✓ chart error message when no data.datasets
    ✓ chart loop (87ms)
    ✓ chart should keep style defined in serie (57ms)
    ✓ chart should keep number format defined in serie (57ms)
    ✓ should not duplicate drawing object id in loop (63ms)
    ✓ page break in single paragraph
    ✓ page break in single paragraph with condition (41ms)
    ✓ page break in single paragraph with condition #2
    ✓ page break in single paragraph (sharing text nodes)
    ✓ page break between paragraphs (41ms)
    ✓ should be able to reference stored asset (54ms)
    ✓ preview request should return html (132ms)
    ✓ text nodes with xml:space="preserve" should continue to exists when needed (63ms)
    ✓ remove nodes that were just containing block helper definition calls (70ms)
    ✓ raw
    ✓ raw error no parameter
    ✓ raw error no xml parameter
    ✓ raw error no replaceParentElement parameter
    ✓ raw error invalid replaceParentElement value
    ✓ raw error invalid wtc location
    ✓ shape with textbox enclosed in if block
    image size in cm
      ✓ image with custom size (width, height) (44ms)
      ✓ image with custom size (width set and height automatic - keep aspect ratio) (50ms)
      ✓ image with custom size (height set and width automatic - keep aspect ratio) (49ms)
    image size in px
      ✓ image with custom size (width, height) (45ms)
      ✓ image with custom size (width set and height automatic - keep aspect ratio) (45ms)
      ✓ image with custom size (height set and width automatic - keep aspect ratio) (47ms)

  docx with extensions.docx.previewInWordOnline === false
    ✓ preview request should not return html

  105 passing (11s)
pdecat commented 3 years ago

Note: the <!--__block_helper_container__--> comments are still left in the output document.xml right now, some cleanup is probably desired:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid wp14">
  <w:body>
    <w:p w14:paraId="31FADCAC" w14:textId="071F5917" w:rsidR="0091351E" w:rsidRDefault="00734BC3" w:rsidP="00734BC3">
      <w:pPr>
        <w:pStyle w:val="Prrafodelista"/>
        <w:numPr>
          <w:ilvl w:val="0"/>
          <w:numId w:val="1"/>
        </w:numPr>
      </w:pPr>
      <w:bookmarkStart w:id="0" w:name="_GoBack"/>
      <w:bookmarkEnd w:id="0"/>
      <w:hyperlink w:history="1" r:id="rId8">
        <w:r w:rsidRPr="00734BC3">
          <w:rPr>
            <w:rStyle w:val="Hipervnculo"/>
            <w:lang w:val="es-ES"/>
          </w:rPr>
          <w:t>jsreport</w:t>
        </w:r>
      </w:hyperlink>
      <!--__block_helper_container__-->
      <!--__block_helper_container__-->
    </w:p>
    <w:p w14:paraId="31FADCAC" w14:textId="071F5917" w:rsidR="0091351E" w:rsidRDefault="00734BC3" w:rsidP="00734BC3">
      <w:pPr>
        <w:pStyle w:val="Prrafodelista"/>
        <w:numPr>
          <w:ilvl w:val="0"/>
          <w:numId w:val="1"/>
        </w:numPr>
      </w:pPr>
      <w:bookmarkStart w:id="1" w:name="_GoBack_c1"/>
      <w:bookmarkEnd w:id="1"/>
      <w:hyperlink w:history="1" r:id="rId9">
        <w:r w:rsidRPr="00734BC3">
          <w:rPr>
            <w:rStyle w:val="Hipervnculo"/>
            <w:lang w:val="es-ES"/>
          </w:rPr>
          <w:t>github</w:t>
        </w:r>
      </w:hyperlink>
      <!--__block_helper_container__-->
      <!--__block_helper_container__-->
    </w:p>
    <w:sectPr w:rsidR="0091351E">
      <w:pgSz w:w="12240" w:h="15840"/>
      <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/>
      <w:cols w:space="720"/>
      <w:docGrid w:linePitch="360"/>
    </w:sectPr>
  </w:body>
</w:document>
bjrmatos commented 3 years ago

thanks! fantastic work here, and a good idea about the comment node to make the match more precise

bjrmatos commented 3 years ago

i have added the cleanup for the comment nodes on master, just FYI. thanks again!

pdecat commented 3 years ago

Hi @bjrmatos, thanks!

I just thought this could be made even more robust by adding IDs to the block helpers to support them nested, e.g.:

<w:p __block_helper_container__="1">
  ...
  <w:p __block_helper_container__="2">
  ...
  <!--__block_helper_container__="2"--></w:p>
  ...
<!--__block_helper_container__="1"--></w:p>

That would require much more changes to the recursiveStringReplaceAsync() function to support back references in its right parameter from groups in its left parameter:

  documentFile.data = await recursiveStringReplaceAsync(
    documentFile.data.toString(),
    '<w:p[^>]*__block_helper_container__="(\\d+)"[^>]*>',
    '<!--__block_helper_container__="\\1"--></w:p>',
    'g',
    async (val, content, hasNestedMatch) => {
    ...
    }

WDYT?

bjrmatos commented 3 years ago

yes, what you are describing sounds like the final solution for the strict matching, I will open a new issue to keep track of that, so we can find some time to work on it. but if you want to work on it the contribution is always welcome.