{"_id":"@anoch/docx-preview","_rev":"5-ec7bfbaa269f132e01ddbf8dfd8cf4fa","name":"@anoch/docx-preview","dist-tags":{"latest":"0.4.6-anoch.2"},"versions":{"0.4.6-anoch.0":{"name":"@anoch/docx-preview","version":"0.4.6-anoch.0","keywords":["word","docx","docx-preview","office","document","viewer"],"author":{"name":"Anoch Jeyakanthan"},"license":"Apache-2.0","_id":"@anoch/docx-preview@0.4.6-anoch.0","maintainers":[{"name":"saddev","email":"anochj5@gmail.com"}],"homepage":"https://github.com/ItsAnoch/docxjs#readme","bugs":{"url":"https://github.com/ItsAnoch/docxjs/issues"},"dist":{"shasum":"4f7f5f9fe1b99f6011a741f795c0ff6c182748bd","tarball":"https://registry.npmjs.org/@anoch/docx-preview/-/docx-preview-0.4.6-anoch.0.tgz","fileCount":12,"integrity":"sha512-SfQpBeoIBW6p4a/NUtNgf7INY7+qpnC4b2SYX1wjvTnGdRrrLR5k37iADkJqkk2raBNpyiW260UW3/J1g068Mw==","signatures":[{"sig":"MEUCIB52Ty4rowN3P/vSc8lsSAyGl+OKwfjc+V5uehpiEN1WAiEAuq0YBUcTK1eBVJwHpZDwAfkGp1Wms5MX5YxQ9jk9aKk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3077498},"types":"dist/docx-preview.d.ts","exports":{".":{"types":"./dist/docx-preview.d.ts","import":"./dist/docx-preview.mjs","require":"./dist/docx-preview.js"}},"gitHead":"1f4a0652b6478fb4844f0c79ae2747f6ed105403","scripts":{"e2e":"karma start karma.conf.cjs --single-run","build":"rollup --config rollup.config.mjs","watch":"rollup --config rollup.config.mjs --watch","e2e-watch":"karma start karma.conf.cjs","build-prod":"rollup --config rollup.config.mjs --environment BUILD:production"},"_npmUser":{"name":"saddev","email":"anochj5@gmail.com"},"repository":{"url":"git+https://github.com/ItsAnoch/docxjs.git","type":"git"},"_npmVersion":"10.9.0","description":"Fork of docx-preview with additional fixes and maintenance. Original work by Volodymyr Baydalka.","directories":{},"_nodeVersion":"21.0.0","dependencies":{"jszip":">=3.0.0","omml2mathml":"^1.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"diff":"^5.0.0","karma":"^6.3.9","tslib":"^2.4.0","rollup":"^4.9.1","typescript":"^5.0.3","jasmine-core":"^5.1.0","karma-jasmine":"^5.0.0","@rollup/plugin-terser":"^0.4.4","karma-chrome-launcher":"^3.1.0","karma-firefox-launcher":"^2.1.2","@rollup/plugin-commonjs":"^28.0.6","@rollup/plugin-typescript":"^11.1.5","@rollup/plugin-node-resolve":"^16.0.1"},"_npmOperationalInternal":{"tmp":"tmp/docx-preview_0.4.6-anoch.0_1756265888871_0.3725173680375353","host":"s3://npm-registry-packages-npm-production"}},"0.4.6-anoch.1":{"name":"@anoch/docx-preview","version":"0.4.6-anoch.1","keywords":["word","docx","docx-preview","office","document","viewer"],"author":{"name":"Anoch Jeyakanthan"},"license":"Apache-2.0","_id":"@anoch/docx-preview@0.4.6-anoch.1","maintainers":[{"name":"saddev","email":"anochj5@gmail.com"}],"homepage":"https://github.com/ItsAnoch/docxjs#readme","bugs":{"url":"https://github.com/ItsAnoch/docxjs/issues"},"dist":{"shasum":"7caca70e54bb63547b73189d39a7607d853c8a2c","tarball":"https://registry.npmjs.org/@anoch/docx-preview/-/docx-preview-0.4.6-anoch.1.tgz","fileCount":12,"integrity":"sha512-6ckJ+J9Dtb9vyZgFY1edFKe+fulmVvteD5R7Vg2iSr4dXUG3MyGA7zGRWQ7I5YRVZQ2e8MrBt+SxD2Xt/ILdqg==","signatures":[{"sig":"MEQCIBroE9fASOZlHjsyWRfQNnIK9K5yo7mIsOWGWfARo3+RAiAS69D/u4Hstte82gTYF/qrehhETO5cINbtQRo//a3O8w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3081767},"types":"dist/docx-preview.d.ts","exports":{".":{"types":"./dist/docx-preview.d.ts","import":"./dist/docx-preview.mjs","require":"./dist/docx-preview.js"}},"gitHead":"21d0d3d21e464acf184498be2f19aa6356effb41","scripts":{"e2e":"karma start karma.conf.cjs --single-run","build":"rollup --config rollup.config.mjs","watch":"rollup --config rollup.config.mjs --watch","e2e-watch":"karma start karma.conf.cjs","build-prod":"rollup --config rollup.config.mjs --environment BUILD:production"},"_npmUser":{"name":"saddev","email":"anochj5@gmail.com"},"repository":{"url":"git+https://github.com/ItsAnoch/docxjs.git","type":"git"},"_npmVersion":"10.9.0","description":"Fork of docx-preview with additional fixes and maintenance. Original work by Volodymyr Baydalka.","directories":{},"_nodeVersion":"21.0.0","dependencies":{"jszip":">=3.0.0","omml2mathml":"^1.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"diff":"^5.0.0","karma":"^6.3.9","tslib":"^2.4.0","rollup":"^4.9.1","typescript":"^5.0.3","jasmine-core":"^5.1.0","karma-jasmine":"^5.0.0","@rollup/plugin-terser":"^0.4.4","karma-chrome-launcher":"^3.1.0","karma-firefox-launcher":"^2.1.2","@rollup/plugin-commonjs":"^28.0.6","@rollup/plugin-typescript":"^11.1.5","@rollup/plugin-node-resolve":"^16.0.1"},"_npmOperationalInternal":{"tmp":"tmp/docx-preview_0.4.6-anoch.1_1756270287735_0.1530211945787956","host":"s3://npm-registry-packages-npm-production"}},"0.4.6-anoch.2":{"name":"@anoch/docx-preview","version":"0.4.6-anoch.2","keywords":["word","docx","docx-preview","office","document","viewer"],"author":{"name":"Anoch Jeyakanthan"},"license":"Apache-2.0","_id":"@anoch/docx-preview@0.4.6-anoch.2","maintainers":[{"name":"saddev","email":"anochj5@gmail.com"}],"homepage":"https://github.com/ItsAnoch/docxjs#readme","bugs":{"url":"https://github.com/ItsAnoch/docxjs/issues"},"dist":{"shasum":"7f2644171baf3a5423e9c7eb48df57150a2e255d","tarball":"https://registry.npmjs.org/@anoch/docx-preview/-/docx-preview-0.4.6-anoch.2.tgz","fileCount":12,"integrity":"sha512-1xU4GLsWWwGZcqEMibna+rCdYNbuhw0ZZBDnQzW/yIUOgzu+6Cg75yG82ufmlTZ4w58S2QFlD3W9j3SwN121Sw==","signatures":[{"sig":"MEUCIBVIxCfiWUYuiLItXukZ6POLL5RHSJuB5ty7jnqPs9wSAiEAw1yvrC9C4mhcZclMK58gtmg+rFCLcjkwZ0V90PyHWkQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3095113},"types":"dist/docx-preview.d.ts","exports":{".":{"types":"./dist/docx-preview.d.ts","import":"./dist/docx-preview.mjs","require":"./dist/docx-preview.js"}},"gitHead":"6c8f2e8bcc574924bfc8ac9c451d2a1c745bac07","scripts":{"e2e":"karma start karma.conf.cjs --single-run","build":"rollup --config rollup.config.mjs","watch":"rollup --config rollup.config.mjs --watch","e2e-watch":"karma start karma.conf.cjs","build-prod":"rollup --config rollup.config.mjs --environment BUILD:production"},"_npmUser":{"name":"saddev","email":"anochj5@gmail.com"},"repository":{"url":"git+https://github.com/ItsAnoch/docxjs.git","type":"git"},"_npmVersion":"10.9.0","description":"Fork of docx-preview with additional fixes and maintenance. Original work by Volodymyr Baydalka.","directories":{},"_nodeVersion":"21.0.0","dependencies":{"jszip":">=3.0.0","omml2mathml":"^1.3.0","@anoch/docx-preview":"."},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"diff":"^5.0.0","karma":"^6.3.9","tslib":"^2.4.0","rollup":"^4.9.1","typescript":"^5.0.3","jasmine-core":"^5.1.0","karma-jasmine":"^5.0.0","@rollup/plugin-terser":"^0.4.4","karma-chrome-launcher":"^3.1.0","karma-firefox-launcher":"^2.1.2","@rollup/plugin-commonjs":"^28.0.6","@rollup/plugin-typescript":"^11.1.5","@rollup/plugin-node-resolve":"^16.0.1"},"_npmOperationalInternal":{"tmp":"tmp/docx-preview_0.4.6-anoch.2_1756271872070_0.5071189714104525","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-08-27T03:38:08.816Z","modified":"2025-08-27T19:44:24.137Z","0.4.6-anoch.0":"2025-08-27T03:38:09.179Z","0.4.6-anoch.1":"2025-08-27T04:51:27.966Z","0.4.6-anoch.2":"2025-08-27T05:17:52.316Z"},"bugs":{"url":"https://github.com/ItsAnoch/docxjs/issues"},"author":{"name":"Anoch Jeyakanthan"},"license":"Apache-2.0","homepage":"https://github.com/ItsAnoch/docxjs#readme","keywords":["word","docx","docx-preview","office","document","viewer"],"repository":{"url":"git+https://github.com/ItsAnoch/docxjs.git","type":"git"},"description":"Fork of docx-preview with additional fixes and maintenance. Original work by Volodymyr Baydalka.","maintainers":[{"email":"anochj5@gmail.com","name":"anochj"}],"readme":"[![npm version](https://badge.fury.io/js/docx-preview.svg)](https://www.npmjs.com/package/docx-preview)\r\n\r\n# docxjs\r\nDocx rendering library\r\n\r\nDemo - https://volodymyrbaydalka.github.io/docxjs/\r\n\r\n## Fork and credits\r\n\r\nThis repository is a fork of the original docxjs project by Volodymyr Baydalka.\r\n\r\n- Original repository: https://github.com/VolodymyrBaydalka/docxjs\r\n- All credit for the original design and most of the implementation goes to the upstream author and contributors.\r\n\r\nGoal\r\n----\r\nGoal of this project is to render/convert DOCX document into HTML document with keeping HTML semantic as much as possible. \r\nThat means library is limited by HTML capabilities (for example Google Docs renders *.docx document on canvas as an image).\r\n\r\nInstallation\r\n-----\r\n```\r\nnpm install docx-preview\r\n```\r\n\r\nUsage\r\n-----\r\n```html\r\n<!--lib uses jszip-->\r\n<script src=\"https://unpkg.com/jszip/dist/jszip.min.js\"></script>\r\n<script src=\"docx-preview.min.js\"></script>\r\n<script>\r\n    var docData = <document Blob>;\r\n\r\n    docx.renderAsync(docData, document.getElementById(\"container\"))\r\n        .then(x => console.log(\"docx: finished\"));\r\n</script>\r\n<body>\r\n    ...\r\n    <div id=\"container\"></div>\r\n    ...\r\n</body>\r\n```\r\nAPI\r\n---\r\n```ts\r\n// renders document into specified element\r\nrenderAsync(\r\n    document: Blob | ArrayBuffer | Uint8Array, // could be any type that supported by JSZip.loadAsync\r\n    bodyContainer: HTMLElement, //element to render document content,\r\n    styleContainer: HTMLElement, //element to render document styles, numbeings, fonts. If null, bodyContainer will be used.\r\n    options: {\r\n        className: string = \"docx\", //class name/prefix for default and document style classes\r\n        inWrapper: boolean = true, //enables rendering of wrapper around document content\r\n        hideWrapperOnPrint: boolean = false, //disable wrapper styles on print\r\n        ignoreWidth: boolean = false, //disables rendering width of page\r\n        ignoreHeight: boolean = false, //disables rendering height of page\r\n        ignoreFonts: boolean = false, //disables fonts rendering\r\n        breakPages: boolean = true, //enables page breaking on page breaks\r\n        ignoreLastRenderedPageBreak: boolean = true, //disables page breaking on lastRenderedPageBreak elements\r\n        experimental: boolean = false, //enables experimental features (tab stops calculation)\r\n        trimXmlDeclaration: boolean = true, //if true, xml declaration will be removed from xml documents before parsing\r\n        useBase64URL: boolean = false, //if true, images, fonts, etc. will be converted to base 64 URL, otherwise URL.createObjectURL is used\r\n        renderChanges: false, //enables experimental rendering of document changes (inserions/deletions)\r\n        renderHeaders: true, //enables headers rendering\r\n        renderFooters: true, //enables footers rendering\r\n        renderFootnotes: true, //enables footnotes rendering\r\n        renderEndnotes: true, //enables endnotes rendering\r\n        renderComments: false, //enables experimental comments rendering\r\n        renderAltChunks: true, //enables altChunks (html parts) rendering\r\n        debug: boolean = false, //enables additional logging\r\n    }): Promise<WordDocument>\r\n\r\n/// ==== experimental / internal API ===\r\n// this API could be used to modify document before rendering\r\n// renderAsync = parseAsync + renderDocument\r\n\r\n// parse document and return internal document object\r\nparseAsync(\r\n    document: Blob | ArrayBuffer | Uint8Array,\r\n    options: Options\r\n): Promise<WordDocument>\r\n\r\n// render internal document object into specified container\r\nrenderDocument(\r\n    wordDocument: WordDocument,\r\n    bodyContainer: HTMLElement,\r\n    styleContainer: HTMLElement,\r\n    options: Options\r\n): Promise<void>\r\n```\r\n\r\nThumbnails, TOC and etc.\r\n------\r\nThumbnails is added only for example and it's not part of library. Library renders DOCX into HTML, so it can't be efficiently used for thumbnails. \r\n\r\nTable of contents is built using the TOC fields and there is no efficient way to get table of contents at this point, since fields is not supported yet (http://officeopenxml.com/WPtableOfContents.php)\r\n\r\nBreaks\r\n------\r\nCurrently library does break pages:\r\n- if user/manual page break `<w:br w:type=\"page\"/>` is inserted - when user insert page break\r\n- if application page break `<w:lastRenderedPageBreak/>` is inserted - could be inserted by editor application like MS word (`ignoreLastRenderedPageBreak` should be set to false)\r\n- if page settings for paragraph is changed - ex: user change settings from portrait to landscape page\r\n\r\nRealtime page breaking is not implemented because it's requires re-calculation of sizes on each insertion and that could affect performance a lot. \r\n\r\nIf page breaking is crutual for you, I would recommend:\r\n- try to insert manual break point as much as you could\r\n- try use editors like MS Word, that inserts `<w:lastRenderedPageBreak/>` break points\r\n\r\nNOTE: by default `ignoreLastRenderedPageBreak` is set to `true`. You may need to set it to `false`, to make library break by `<w:lastRenderedPageBreak/>` break points\r\n\r\nStatus and stability\r\n------\r\nSo far I can't come up with final approach of parsing documents and final structure of API. Only **renderAsync** function is stable and definition shouldn't be changed in future. Inner implementation of parsing and rendering may be changed at any point of time.\r\n\r\nContributing\r\n------\r\nPlease do not include contents of `./dist` folder in your PR's. Otherwise I most likely will reject it due to stability and security concerns.\r\n\r\n## Math equations (OMML → MathML) rendering\r\n\r\nWhat was broken\r\n----------------\r\nModern browsers, especially Chromium-based, implement MathML Core, which removes or ignores a number of legacy/deprecated MathML features. Our previous OMML→Math rendering path could emit deprecated MathML like `<mfenced>` for parentheses/brackets and separators. As a result, equations sometimes rendered without fences/separators or with inconsistent spacing.\r\n\r\nWhat we changed\r\n----------------\r\n- Replaced the entire equation rendering pipeline: we now convert OMML to MathML using `omml2mathml`, and then run a normalization pass in `src/omml-renderer.ts`.\r\n- The normalizer rewrites deprecated `<mfenced>` nodes to standard MathML Core-friendly structure using `<mrow>` with explicit `<mo>` operators for:\r\n    - opening fence (e.g., `(`, `[`, `|`)\r\n    - separators between arguments (e.g., `,`)\r\n    - closing fence (e.g., `)`, `]`, `|`)\r\n\r\nPreviously, only some equations would render; now they all properly render. This makes generated MathML more robust across engines that don’t support `<mfenced>`.\r\n\r\nKnown edge cases and limitations\r\n--------------------------------\r\nThe normalization focuses on the most common breakage (fences/separators). Some MathML constructs emitted by converters are partially or not supported in MathML Core and may still need special handling:\r\n\r\n- mtable/mtr/mtd (matrices, cases)\r\n    - Support varies in Core. Rich alignment/lines can fail. We currently don’t rewrite tables; very complex matrices/cases may render inconsistently.\r\n\r\n- mstyle and presentational attributes (mathcolor, mathbackground, mathsize, displaystyle, scriptlevel, etc.)\r\n    - Not part of MathML Core; may be ignored by some engines. Styling could appear lost unless mirrored in CSS. Future work: unwrap `mstyle` and move styling to CSS.\r\n\r\n- semantics/annotation-xml\r\n    - `annotation-xml` is not widely supported. If present, it can interfere with rendering. Future work: unwrap to the first renderable child.\r\n\r\n- mfrac with bevelled=\"true\"\r\n    - Bevelled fractions are not in Core. Future work: linearize as `mrow <numerator> <mo>/</mo> <denominator>`.\r\n\r\n- mathvariant for special alphabets (double‑struck, fraktur, script)\r\n    - Not reliably supported without fonts. Consider using Unicode code points or CSS/webfonts.\r\n\r\n- mmultiscripts (general tensor indices)\r\n    - Not in Core and hard to rewrite generically. Future work: map simple cases to `msubsup` where possible.\r\n\r\n- Operator attributes (largeop, movablelimits, lspace/rspace, linebreak, form, fence/separator flags)\r\n    - Many are ignored in Core; spacing/limits behavior may differ. Prefer structural elements (`munderover`, `msubsup`) and CSS spacing.\r\n\r\nTroubleshooting tips\r\n--------------------\r\n- If equations appear without parentheses/separators, ensure you’re using a build including `src/omml-renderer.ts` normalization (version ≥ the commit that mentions “equation rendering”).\r\n- For matrices/cases that look off, consider rendering to HTML tables or opening an issue with a minimal DOCX.\r\n- If stylistic differences show up (colors/sizes), mirror styles via CSS on the MathML elements.\r\n\r\nNotes\r\n-----\r\n- The core fix is safe: converting `<mfenced>` to `<mrow>` with explicit `<mo>` mirrors standard MathML examples and avoids deprecated constructs.\r\n- We’ll iterate on additional normalizations as needed; feel free to file issues with sample documents.\r\n","readmeFilename":"README.md"}