- 5.15.3Latest
- 5.15.2
- 5.15.1
- 5.15.0
- 5.14.1
- 5.14.0
- 5.13.3
- 5.13.2
- 5.13.1
- 5.13.0
- 5.12.2
- 5.12.1
- 5.12.0
- 5.11.4
- 5.11.3
- 5.11.2
- 5.11.1
- 5.11.0
- 5.10.1
- 5.10.0
- 5.9.0
- 5.8.1
- 5.8.0
- 5.7.2
- 5.7.1
- 5.7.0
- 5.6.0
- 5.5.6
- 5.5.5
- 5.5.4
- 5.5.3
- 5.5.2
- 5.5.1
- 5.5.0
- 5.4.0
- 5.3.8
- 5.3.7
- 5.3.6
- 5.3.5
- 5.3.4
- 5.3.3
- 5.3.2
- 5.3.1
- 5.3.0
- 5.2.1
- 5.2.0
- 5.1.1
- 5.1.0
- 5.0.2
- 5.0.1
- 5.0.0
- 4.0.8
- 4.0.7
- 4.0.6
- 4.0.5
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 3.2.0
- 3.1.1
- 3.1.0
- 3.0.1
- 3.0.0
- 2.4.3
- 2.4.2
- 2.4.1
- 2.2.0
- 2.1.0
- 2.0.1
- 2.0.0
- 1.6.0
- 1.5.1
- 1.5.0
- 1.4.0
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.0
- 1.1.0
- 1.0.0
- 0.0.4
- 0.0.3
- 0.0.2
- 0.0.1
This is a Deno library, for the following purposes;
- Transform XML into a DOCX
- Compile a standalone executable that does the above.
/**
* @file test.tsx
* @jsx Application.JSX
**/
import Application, {
Document,
Paragraph,
Section,
// Remember to point to a specific version of docxml:
} from 'https://deno.land/x/docxml/mod.ts';
await Application.writeAstToDocx(
'hello-world.docx',
<Document>
<Section>
<Paragraph>This is probably the simplest document you could make</Paragraph>
</Section>
</Document>,
);
// Hey presto, `hello-world.docx` is saved to disk
It relies heavily on the excellent slimdom, fontoxpath and provides syntactic sugar for the magnificent docx.
To use
Create a
deno.json
in your project directory, and give it the following contents to avoid conflicts withlib.dom.d.ts
;{ "compilerOptions": { "lib": ["deno.ns"] } }
Create a
.tsx
file, include the/** @jsx app.JSX */
and use the rest of the API as shown in the other code examples of this README.
Creating an executable
An instance of the default export class comes with some helper methods that makes it dead easy to
build an executable using Deno’s own deno compile
.
The following examples takes a couple of CLI arguments, and applies its rendering rules on the input XML;
/** @jsx app.JSX */
import Application, {
Document,
Section,
Text,
Paragraph,
// Remember to point to a specific version of docxml:
} from 'https://deno.land/x/docxml/mod.ts';
const app = new Application();
// Some catch-all rules for any XML node, any XML element, any text:
app.match('self::node()', () => null);
app.match('self::element()', ({ traverse }) => traverse('./*'));
app.match('self::text()', ({ node }) => node.nodeValue);
app.match('self::document-node()', ({ traverse }) => <Document>{traverse('./*')}</Document>);
// Some rules for specific HTML elements. Elements that have no specific configuration
// fall back to the catch-all ones.
app.match('self::html', ({ traverse }) => <Section>{traverse('./*')}</Section>);
app.match('self::p', ({ traverse }) => <Paragraph>{traverse()}</Paragraph>);
app.match('self::b', ({ traverse }) => <Text bold>{traverse()}</Text>);
await app.cli();
This could then be compiled into a self-contained executable:
deno compile -A -o my-executable my-script.tsx
When calling Application#cli()
, like in the earlier code example, the script will look for the
following command-line input;
-s , –source , specify the XML file that needs to be transformed.
-d , –destination , specify the location to which you would like the
.docx
file to be written.–debug, log more information about the document that is being output.
Alternatively, you can pipe in- and out of the executable;
cat my-source.xml | my-executable > my-destination.docx
Error codes
DXE001: The XML input cannot be empty.
: For some reason, the options with which you executed an application did not result in a string that could be processed as XML.DXE002: The transformation resulted in an empty document.
: The processing of your input XML went fine, but it resulted in an empty document. Verify that at least one element maps to the<Document />
component, and that the rendering rules traverse into meaningful content from there.DXE003: The transformation resulted in a string, which is not a valid document.
: The processing of your input XML did use any of the required components – at least<Document />
and<Section />
.DXE004: The root node was not a document.
: The processing of your input did not result in a<Document />
root AST. Any valid Word document must start with<Document />
.DXE005: Could not read the DOTX template file due to error "…"
DXE010: Cannot use styles without calling 'init' first.
: A content rendering rule is attempting to use a style (viaTemplate#style()
), but the template could not verify it exists. Run (andawait
)Template#init()
at an earlier time – for example when passing it to<Document />
’stemplate
prop.DXE011: Style "…" is not available in this template. The only available style names are: …
: You are referencing a style name that does not exist in the supplied.dotx
Word template. Please check the template and spelling.DXE020: Unrecognized CLI option "…"
: The user gave a command line argument or option that is not recognized. Please check your input.DXE021: The --source option should be followed by the location of an XML file
: The user attempted to use the--source
CLI option without giving it a value. Please use as--source <value>
instead. That value should be an XML file that exists on your disk.DXE022: The --destination option should be followed by the location to which a DOCX file will be written
: The user attempted to use the--destination
CLI option without giving it a value. Please use as--destination <value>
instead. The value does not have to exist on disk already, and using the.docx
file extension is recommended.DXE029: getPipedStdin unexpectedly finished without returning.
This error should never occur. It has to do with the way you piped XML into the application. Please submit an issue, and share anything you can about your command-line input and XML file.DXE030: Some AST nodes could not be given a valid position.
: The rendering rules resulted in invalid nesting of components, and after correction by the system some components could not be given a valid new place.
docx
facade
About the In all cases, the options on components are actually documented with the rest of docx. However, there are a few minor differences:
Unlike
docx
, paragraphs can contain text (strings) directly. The system will wrap them indocx.TextRun
automatically. It makes the thing a lot more convenient when transforming XML.When the system finds component nesting that is not supported by
docx
(eg. aParagraph
inside aTextRun
), it will try to split the ancestors of the invalid child until a valid position is reached. If the top-level is reached, there is no valid resolution, and the system throws an error.