@concordance-wiki/plugin-reader-office
v1.0.0
Published
Metadata reader for docx, pptx, xlsx and pdf files: properties, dates, counts and slide titles.
Readme
Why
Half of what a team knows sits in office documents next to the markdown, and a wiki that ignores them is half a wiki. This plugin reads the metadata of .docx, .pptx, .xlsx and .pdf files in your repositories, title, author, subject, keywords, dates, page, word and slide counts, so that every document gets a page with what the file states about itself, is filed with the notes and shows up in the to-do list when nobody has summarised it. It is carried by @concordance-wiki/concordance; install it on its own next to @concordance-wiki/cli. No system dependency.
Quick start
npm install --save-dev @concordance-wiki/plugin-reader-officeThen declare it in concordance.yaml, with the conversion plugin next to it when LibreOffice is available, for the preview and the text of every page:
plugins:
- "@concordance-wiki/plugin-reader-office"
- "@concordance-wiki/plugin-convert-libreoffice"Every .docx, .pptx, .xlsx and .pdf file of a source becomes a document entity whose properties come from the file. Of a package, only the two property parts and the slide parts are inflated, none above 8 MB: media, fonts and sheets stay compressed, and an archive whose entries inflate to gigabytes never fills the memory of the build; a part that declares a DOCTYPE is refused, so that no entity is expanded.
What you get
- A page per document, with the properties the file carries: title, author, subject, keywords, creation and modification dates, application.
- Counts that mean something: the pages and words an office file declares, the page count of a PDF, the slides of a deck with their titles in order.
- The document's own dates, created and modified as the file says, kept apart from the git commit date of the file.
- Only the bytes: the reader never touches git, the file system or the clock; a corrupted file is a finding, not a failed build.
- Twins reconciled: the build matches a document with the note that describes it, and the page of that note offers the file for download; a document nobody wrote about is listed on the to-do page.
- Usable alone:
readOoxml(bytes, kind)andreadPdf(bytes)read the two families without the pipeline.
Documentation
- Plugins, the reader contribution point
- Configuration reference,
privacy.pseudonymizefor the authors a file names - Home page, the demo wiki and the changelog
Part of Concordance, MIT licence.
read({ path, payload: { bytes } }) returns { metadata, text: "" }. The text stays empty: extraction belongs to the conversion plugin, which reads it from the PDF. The metadata carries what the file states about itself:
| Property | docx, pptx, xlsx | pdf |
|---|---|---|
| title, author, subject, keywords (list) | docProps/core.xml | Info dictionary |
| created, modified (ISO 8601) | dcterms:created, dcterms:modified | CreationDate, ModDate, converted from D:YYYYMMDDHHmmSS |
| lastModifiedBy | cp:lastModifiedBy | — |
| pages, words | docProps/app.xml | pages: number of page objects; a PDF over 64 MB is read from its last 16 MB alone, where an updated file keeps its trailer and its Info object, and gets no page count |
| slides, slideTitles | pptx only: Slides and the title placeholder of every ppt/slides/slideN.xml, in slide order; an empty string when a slide has no title | — |
| application | docProps/app.xml | — |
An absent property is absent from the record. A package without docProps yields empty metadata; a corrupted archive, a file without the PDF header or an unknown extension throws a plain error naming the file, which the pipeline turns into a finding.
The dates are the document's own and are kept apart from the git commit date the ingested file carries: the reader reads nothing but the bytes it is given, never git, the file system or the clock. Authors are returned raw; pseudonymisation applies downstream, on the model, when it is enabled.
PDF objects stored in compressed object streams are not scanned: the page count is then a lower bound and an Info dictionary hidden there is not seen. The conversion plugin, which parses the whole PDF for its text, does not depend on that count.
