## Extracting Citations from ODT and DOCX Files
Word processor documents that use citation managers embed bibliographic data as structured fields or reference marks directly in the document XML. This section documents the formats used by each major citation manager, which is useful context when building tools that extract or convert such citations.
This document covers two aspects of citation data:
1. **Bibliographic data**: The full metadata for each reference (author, title, year, etc.)
2. **Citation item metadata**: Per-citation modifiers such as page numbers (locators), prefixes, suffixes, and author suppression flags
**Observe:** This is work in progress and we do not have access to many of these formats, so it is based on what users are saying about these formats in forums. Some of it may therefore be wrong.
We hope that this document will also be useful to other projects with similar goals. Please help to improve it by submitting corrections or adding missing information.
### Background: DOCX field codes
DOCX files are ZIP archives. Citations are stored inside `word/document.xml` using Word field codes. A field consists of:
- `` — opens the field
- One or more `` elements holding the field instruction
- `` — separates instruction from rendered text
- `` elements containing the rendered display text
- `` — closes the field
**Important for parsers:** To reconstruct the full field instruction, all `` elements between the `begin` and `separate` markers must be concatenated — regardless of run boundaries or intervening `` formatting. Word splits field instruction text into multiple runs whenever the character formatting changes. For example, a special character like `∼` (rendered in Cambria Math font) in a title embedded in an `ADDIN EN.CITE` payload will cause the `instrText` to be split across three runs:
```xml
...<title>Article title (
∼
660 BC)</title>...
```
A parser must collect all `` content within a field (from `begin` to `separate`) before attempting to parse it.
### Background: ODT reference marks
ODT files are also ZIP archives. The document content is in `content.xml`. Citations are stored as named **reference marks** spanning a range:
```xml
displayed citation text
```
The `text:name` attribute carries the citation metadata. Both the start and end tags must use the exact same name. Note that ODT reference marks are not preserved when converting an ODT to DOCX through LibreOffice.
---
### Native bibliography support
Both DOCX and ODT have built-in bibliography features that do not require any citation manager plugin. JabRef's Word integration uses the DOCX native format. These formats may also appear in documents that were never touched by a citation manager.
**Citation item metadata**: Word's native `CITATION` field has limited support for citation-specific metadata. The field instruction may include switches:
- **`\l`**: Locale identifier (e.g., `\l 1033` for en-US)
- **`\s`**: Suppress author names (exact usage unknown)
- **`\y`**: Suppress year (exact usage unknown)
- **`\n`**: Suppress title (exact usage unknown)
Locators (page numbers), prefixes, and suffixes are **not supported** in Word's native citation system. These must be added manually to the document text outside the citation field.
Research is needed to confirm the exact behavior of the `\s`, `\y`, and `\n` switches and whether other switches exist for citation customization.
#### DOCX native bibliography
Word's built-in bibliography uses the `CITATION` field for inline citations:
```xml
CITATION Smith2020 \l 1033
```
The citation key (`Smith2020`) corresponds to the `` in the source data. The `\l 1033` switch specifies the locale (1033 = en-US).
The bibliography list uses a `BIBLIOGRAPHY` field:
```xml
BIBLIOGRAPHY
```
All source data is stored in `customXml/item1.xml` inside the DOCX ZIP, using the MS Office Bibliography XML schema (namespace `http://schemas.microsoft.com/office/word/2004/10/bibliography`):
```xml
Smith2020
Book
SmithJohn
Introduction to Testing
2020
New York
Test Press
```
#### ODT native bibliography
LibreOffice Writer's built-in bibliography uses `` for inline citations. Unlike citation manager reference marks, all bibliographic data is stored directly as attributes on the element — the ODT is fully self-contained with no external data file.
**Citation item metadata**: LibreOffice's native bibliography system does **not support** locators (page numbers), prefixes, suffixes, or author suppression at the citation level. The `` element only stores bibliographic metadata. Any page numbers or other citation-specific text must be added manually to the surrounding document text.
```xml
Jones2019
```
The element's text content is the displayed citation label. The `text:bibliography-type` attribute is required; all others are optional. Supported types (from the ODF 1.2 spec): `article`, `book`, `booklet`, `conference`, `inbook`, `incollection`, `inproceedings`, `journal`, `manual`, `mastersthesis`, `misc`, `phdthesis`, `proceedings`, `techreport`, `unpublished`, `www`, `email`, `custom1`–`custom5`.
The bibliography section uses a `` element containing a `` (formatting templates) and a `` (rendered output):
```xml
:
.
,
Bibliography
Jones, Alice: Research Methods. Science Journal, 2019
```
The `text:index-body` is regenerated by LibreOffice when the bibliography is updated; the source of truth is the attributes on each `text:bibliography-mark` element in the document body.
---
### Zotero
Zotero uses CSL-JSON format for storing citation data. Each citation contains a `citationItems` array where each item can include the following **citation-specific metadata** in addition to the bibliographic `itemData`:
- **`locator`**: Page number or other pinpoint location (e.g., `"123"`, `"45-67"`)
- **`label`**: Type of locator (e.g., `"page"`, `"chapter"`, `"section"`, `"figure"`). Valid labels are defined in the CSL specification (see Appendix II - Locators).
- **`prefix`**: Text to appear before the citation (e.g., `"see "`, `"cf. "`)
- **`suffix`**: Text to appear after the citation (e.g., `" (arguing that X is Y)"`)
- **`suppress-author`**: Boolean; if `true`, author names are omitted from the citation output
- **`author-only`**: Boolean; if `true`, only the author name is rendered (used in some demanding styles)
These fields are part of the CSL cite-item specification and appear alongside `id` and `itemData` in each object within the `citationItems` array.
**Example with citation metadata:**
```json
{
"citationID": "abc123",
"properties": {"noteIndex": 0},
"citationItems": [{
"id": "ITEM-1",
"locator": "123",
"label": "page",
"prefix": "See ",
"suffix": " for more details",
"suppress-author": false,
"itemData": {
"id": "ITEM-1",
"type": "book",
"title": "Example Book",
"author": [{"family": "Smith", "given": "John"}],
"issued": {"date-parts": [[2020]]}
}
}]
}
```
#### Zotero (DOCX)
Inline citations use a field instruction beginning with `ADDIN ZOTERO_ITEM CSL_CITATION` followed immediately (no space) by the CSL-JSON object. The `w:fldChar begin` and `w:instrText` share a single `` run, as do `w:fldChar end` and any immediately following text or the next field's `w:fldChar begin`. Field boundaries therefore do **not** align with paragraph boundaries — a field can end in a different paragraph from where it began, and multiple fields can start and end within the same paragraph.
The following is the complete body of a real Zotero DOCX with three citations in one paragraph and two more in a second paragraph, followed by the bibliography:
```xml
Hers is an example file.
ADDIN ZOTERO_ITEM CSL_CITATION{"citationID":"3knmy8ihjs2","schema":"https://raw.githubusercontent.com/citation-style-language/schema/master/schemas/input/csl-citation.json","properties":{"plainCitation":"[1], [2], [3]"},"citationItems":[{"id":"KKN4UIC2","itemData":{"id":"KKN4UIC2","type":"article-journal","language":"spanish","author":[{"family":"Pantoja","given":"Ary"}],"accessed":{"date-parts":[["2011",6,4]]},"issued":{"date-parts":[["2007",11,21]]},"container-title":"El Nuevo Diario","title":"CPC fuera de la ley","URL":"http://impreso.elnuevodiario.com.ni/2007/11/21/nacionales","custom":{"userID":0}},"uris":["http://zotero.org/users/8727/items/KKN4UIC2"]},{"id":"42QSNSR9","itemData":{"id":"42QSNSR9","type":"webpage","language":"english","author":[{"literal":"Organisation for Economic Co-operation and Development"}],"accessed":{"date-parts":[["2008",1,15]]},"issued":{"literal":"200X"},"title":"Nicaragua","URL":"http://www.oecd.org/dataoecd/38/34/1888464.gif","custom":{"userID":0}},"uris":["http://zotero.org/users/8727/items/42QSNSR9"]},{"id":"PFEHEXUN","itemData":{"id":"PFEHEXUN","type":"chapter","language":"english","author":[{"family":"Ortega Saavedra","given":"José Daniel"}],"editor":[{"family":"Marcus","given":"Bruce"}],"translator":[{"literal":"Intercontinental Press"}],"issued":{"date-parts":[["1979"]]},"container-title":"Sandinistas Speak","publisher":"Pathfinder Press","publisher-place":"New York","title":"Nothing Will Hold Back Our Struggle for Liberation","custom":{"userID":0}},"uris":["http://zotero.org/users/8727/items/PFEHEXUN"]}]}
[1], [2], [3]
But let me try what happens if things are on the same line
ADDIN ZOTERO_ITEM CSL_CITATION{"citationID":"ovaj28idbqm","schema":"https://raw.githubusercontent.com/citation-style-language/schema/master/schemas/input/csl-citation.json","properties":{"plainCitation":"[1], [2]"},"citationItems":[{"id":"MF8IX2G2","itemData":{"id":"MF8IX2G2","type":"article-journal","language":"spanish","author":[{"family":"Rodríguez","given":"Heberto"}],"accessed":{"date-parts":[["2011",6,4]]},"issued":{"date-parts":[["2007",1,11]]},"container-title":"El Nuevo Diario","title":"Ya somos ALBA","URL":"http://archivo.elnuevodiario.com.ni/2007/01/11/nacionales/38486","custom":{"userID":0}},"uris":["http://zotero.org/users/8727/items/MF8IX2G2"]},{"id":"JDBRBTK4","itemData":{"id":"JDBRBTK4","type":"post-weblog","author":[{"family":"Hirst","given":"Joel D."}],"issued":{"date-parts":[["2010"]]},"title":"A Guide to ALBA","URL":"http://www.americasquarterly.org/hirst/article","custom":{"userID":0}},"uris":["http://zotero.org/users/8727/items/JDBRBTK4"]}]}
[4], [5]
. Can I not cite here also
ADDIN ZOTERO_ITEM CSL_CITATION{"citationID":"nyuey7a8rq","schema":"https://raw.githubusercontent.com/citation-style-language/schema/master/schemas/input/csl-citation.json","properties":{"plainCitation":"[3]"},"citationItems":[{"id":"DIK88XBT","itemData":{"id":"DIK88XBT","type":"post-weblog","author":[{"family":"Capelán","given":"Jorge"}],"issued":{"date-parts":[["2010",5,30]]},"container-title":"Tortilla con Sal","title":"Nicaragua y el ALBA","URL":"http://tortillaconsal.com/tortilla/es/node/6078","custom":{"userID":0}},"uris":["http://zotero.org/users/8727/items/DIK88XBT"]}]}
[6]
?
ADDIN ZOTERO_BIBL CSL_BIBLIOGRAPHY
[1]A. Pantoja, "CPC fuera de la ley," El Nuevo Diario, Nov. 2007, ...
[2]Organisation for Economic Co-operation and Development, "Nicaragua." ...
[3]J. D. Ortega Saavedra, "Nothing Will Hold Back Our Struggle for Liberation," ...
[4]H. Rodríguez, "Ya somos ALBA," El Nuevo Diario, Jan. 2007, ...
[5]J. D. Hirst, "A Guide to ALBA." ...
[6]J. Capelán, "Nicaragua y el ALBA," Tortilla con Sal. ...
```
In ONLYOFFICE 9.3.0.140, the bibliography appears in a single paragraph instead, like this:
```xml
ADDIN ZOTERO_BIBL CSL_BIBLIOGRAPHY
[1]A. Pantoja, "CPC fuera de la ley," El Nuevo Diario, Nov. 2007, ...
[2]Organisation for Economic Co-operation and Development, "Nicaragua." ...
[3]J. D. Ortega Saavedra, "Nothing Will Hold Back Our Struggle for Liberation," ...
[4]H. Rodríguez, "Ya somos ALBA," El Nuevo Diario, Jan. 2007, ...
[5]J. D. Hirst, "A Guide to ALBA." ...
[6]J. Capelán, "Nicaragua y el ALBA," Tortilla con Sal. ...
```
Indentation at the beginning of the line is handled throuhg the bibliography paragraph style in Word, whereas in ONLYOFFICE, it is handled by adding spaces.
Key observations from the real-world DOCX:
- The JSON object follows `CSL_CITATION` **directly** with no separating space.
- `w:fldChar begin` and `w:instrText` share a single ``. Similarly, `w:fldChar end` may share a `` with the text that immediately follows the citation, or with nothing.
- Field boundaries do **not** align with paragraph boundaries. The `w:fldChar end` for a field that began in one paragraph can appear at the start of the next paragraph. Multiple fields can start and end within the same paragraph.
- `citationItems[].id` is a **string**, not an integer.
- `citationItems[].uris` is present alongside `itemData`.
- `properties` contains only `plainCitation` (no `formattedCitation`, no `noteIndex`) in this example; other fields may or may not appear depending on Zotero version and citation style.
- `itemData` may include a `language` field (plain language name such as `"spanish"` or `"english"`, not a BCP-47 tag) and a `custom` object — both should be treated gracefully and are not required for import.
- Author entries may use `literal` instead of `family`/`given` for institutional authors.
- **No trailing random ID in DOCX**: Zotero does not append a trailing random ID in DOCX field instructions. The JSON object ends immediately after the closing `}`.
- The bibliography field (`ADDIN ZOTERO_BIBL CSL_BIBLIOGRAPHY`) is in its own separate paragraph. Its `begin` and `instrText` share a single ``. The rendered entries appear as multiple `` + `` nodes inside a single `` between `separate` and `end`.
> **RTF escape sequences in `formattedCitation`**: When `properties.formattedCitation`
> is present it may contain RTF Unicode escapes such as `\\uc0\\u8211{}` (RTF for the
> en-dash U+2013, where `8211` is a **decimal** code point). These appear only in the
> display string inside `properties` and do not affect the importable
> `citationItems[].itemData` records, so they do not need to be decoded during import.
> **Note on the bibliography instruction**: In this real-world file the instruction is
> simply `ADDIN ZOTERO_BIBL CSL_BIBLIOGRAPHY` with no JSON between the two tokens.
> Earlier Zotero versions or different export options may include a JSON object between
> them (e.g. `ADDIN ZOTERO_BIBL {"uncited":[],"custom":[]} CSL_BIBLIOGRAPHY`). Parsers
> should handle both forms.
> **Zotero metadata in `docProps/custom.xml`**: In addition to the field codes in the
> document body, Zotero DOCX files contain a metadata entry in `docProps/custom.xml`.
> This file stores custom document properties that Zotero uses to persist session and
> style information across document editing sessions. A typical entry looks like:
>
> ```xml
<data data-version="3" zotero-version="5.0.96.3"><session id="RYC4roRa"/><style id="http://www.zotero.org/styles/apa" locale="en-US" hasBibliography="1" bibliographyStyleHasBeenSet="1"/><prefs><pref name="fieldType" value="Field"/></prefs></data>
```
>
> Note that the inner `` element is **serialized XML** stored as text inside the
> `` element. The angle brackets are escaped as `<` and `>`. To parse
> the metadata, you must first extract the text content of ``, then decode
> the XML entities, and finally parse the resulting XML string.
> ```
>
> The `` element (after unescaping from ``) contains:
>
> - `data-version` — the internal Zotero data format version (currently `3`).
> - `zotero-version` — the Zotero version that created the document (e.g. `5.0.96.3`).
> - `` — a unique session identifier generated when the document was
> first linked to a Zotero library.
> - `` — the CSL style URI used for formatting citations and the
> bibliography. The `locale` attribute specifies the citation locale (e.g. `en-US`).
> The `hasBibliography` attribute indicates whether the style includes a bibliography,
> and `bibliographyStyleHasBeenSet` tracks whether the user has confirmed the style
> choice.
> - `` — a list of preference key-value pairs. The `fieldType` preference
> indicates whether Zotero uses Word field codes (`Field`) or bookmarks (`Bookmark`)
> to store citations in this document.
>
> Multiple `ZOTERO_PREF_N` properties may exist (numbered `ZOTERO_PREF_1`,
> `ZOTERO_PREF_2`, etc.) when the serialized XML exceeds the character limit (255) for a
> single property value. In this case, the XML string is split across multiple
> properties that must be concatenated in order before parsing. The `fmtid` attribute
> is the standard Windows FMTID for custom properties
> (`{D5CDD505-2E9C-101B-9397-08002B2CF9AE}`), and `pid` is the property index within
> that format.
>
> **Note**: ONLYOFFICE 9.3.0.140 omits the `docProps/custom.xml` file entirely when
> saving Zotero DOCX files. Parsers should not rely on the presence of this metadata.
#### Zotero (ODT)
In ODT, Zotero uses the same CSL-JSON structure as in DOCX, with the same **citation item metadata** support (`locator`, `label`, `prefix`, `suffix`, `suppress-author`, `author-only`). The JSON is embedded in reference mark names instead of field instructions.
In ODT files, Zotero stores session and style metadata in `meta.xml` using
`` elements. Like the DOCX format, the inner XML is serialized
(escaped) and may be split across multiple properties due to character limits:
```xml
<data data-version="3" zotero-version="8.0.2"><session id="sqSj43VZ"/><style id="http://www.zotero.org/styles/chicago-author-date" locale="en-US" hasBibliography="1" bibliographyStyleHasBeenSet="1"/><prefs><pref name="fieldType" value="ReferenceMark"/><pref name="automaticJournalAbbreviations" value="true"/></prefs></data>
```
> **Split across properties**: The `` element may be split across multiple
> `ZOTERO_PREF_N` properties when the serialized XML exceeds the character limit (378?) for
> a single property value. In the example above, `ZOTERO_PREF_1` ends mid-tag
> (`...<pr`) and `ZOTERO_PREF_2` continues (`ef name=...`). Parsers must concatenate
> all `ZOTERO_PREF_N` values in order before decoding entities and parsing the XML.
>
> The structure of the `` element (after unescaping) is identical to the DOCX
> format: `data-version`, `zotero-version`, ``, `