Skip to content

Commit c9c24aa

Browse files
Enhance documentation for interlinear XML parsing
- Modified README to include detailed documentation on the Paratext 9 XML schema and its parsed output. - Adjusted comments in interlinearXmlParser.ts and interlinearXmlParser.test.ts to reference the new documentation for the 'Excluded' flag. - Changed parser configuration to ensure tag text is not trimmed during parsing. - Updated several package dependencies to their latest versions in package-lock.json.
1 parent 4756ca6 commit c9c24aa

6 files changed

Lines changed: 170 additions & 147 deletions

File tree

README.md

Lines changed: 1 addition & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ The general file structure for an extension is as follows:
9595
- `src/` contains the source code for the extension
9696
- `src/main.ts` is the main entry file for the extension (registers commands and wires interlinear XML)
9797
- `src/types/interlinearizer.d.ts` is this extension's types file that defines how other extensions can use this extension through the `papi`. It is copied into the build folder
98-
- `src/parsers/interlinearXmlParser.ts` parses interlinear XML into structured data (uses fast-xml-parser)
98+
- `src/parsers/interlinearXmlParser.ts` parses interlinear XML into structured data (uses fast-xml-parser). The PT9 XML schema and parsed output are documented in `src/parsers/pt9-xml.md`
9999
- `*.web-view.tsx` files will be treated as React WebViews
100100
- `*.web-view.scss` files provide styles for WebViews
101101
- `*.web-view.html` files are a conventional way to provide HTML WebViews (no special functionality)
@@ -116,125 +116,6 @@ The general file structure for an extension is as follows:
116116

117117
> See the [Extension Anatomy wiki page](https://github.com/paranext/paranext-extension-template/wiki/Extension-Anatomy) for more information about the various files that comprise an extension and their relationships to each other.
118118
119-
## Interlinear XML schema
120-
121-
The extension reads interlinear data from XML files (e.g. `Interlinear_<lang>_<book>.xml` in project data). The parser in `src/parsers/interlinearXmlParser.ts` expects the following structure. Sample files live in `test-data/` (e.g. `Interlinear_en_MAT.xml`).
122-
123-
### Document structure
124-
125-
- **Root element:** `InterlinearData`
126-
- **Attributes:**
127-
- `GlossLanguage` (required): Language code or name for glosses (e.g. `"en"`).
128-
- `BookId` (required): Book id (e.g. `"MAT"`, `"RUT"`).
129-
- `ScrTextName` (optional): Source text / project name.
130-
- **Child:** Exactly one `Verses` element.
131-
132-
- **Verses**
133-
- **Children:** Zero or more `item` elements. Each `item` represents one verse.
134-
- **`item`**
135-
- **`string`** (element text): Verse reference key (e.g. `"MAT 1:1"`, `"RUT 3:1"`). Must be unique in the document; duplicate references cause a parse error.
136-
- **`VerseData`** (optional): If absent, the verse is stored with empty `Hash`, `Clusters`, and `Punctuations`.
137-
138-
- **VerseData**
139-
- **Attributes:**
140-
- `Hash` (optional): Approval hash of the verse text when approved; empty if not approved.
141-
- **Children:**
142-
- **`Cluster`** (zero or more): Word/morpheme clusters with range and lexemes.
143-
- **`Punctuation`** (zero or more): Punctuation change records.
144-
145-
- **Cluster**
146-
- **Children:**
147-
- **`Range`** (required): Character range in the verse text.
148-
- **Attributes:** `Index` (start, 0-based), `Length` (number of characters). Both must be numeric; missing or non-numeric values cause a parse error.
149-
- **`Lexeme`** (zero or more): Lexemes in this cluster.
150-
- **Attributes:**
151-
- `Id` (required): Lexeme id (e.g. from a Lexicon).
152-
- `GlossId` (optional): Sense/gloss id; omitted or empty is treated as empty string.
153-
- **`Excluded`** (optional): Boolean flag indicating this instance of a phrase should be excluded from the interlinear display at this specific location. This is a very niche property that is included because it's possible to be present in the XML, even though it's rarely used. When `true`, the phrase is not displayed at this location but remains available elsewhere. The exclusion is location-specific (applies to this instance at this text range, not globally). Omitted or `false` means the phrase is included.
154-
155-
- **Punctuation**
156-
- **Children:**
157-
- **`Range`** (optional): If present, must have numeric `Index` and `Length`. Entries without a valid `Range` are skipped (not an error).
158-
- **`BeforeText`** (optional): Punctuation text before the change; omitted → empty string.
159-
- **`AfterText`** (optional): Punctuation text after the change; omitted → empty string.
160-
161-
### Parsed output (in-memory)
162-
163-
The parser produces objects conforming to the types in `src/types/interlinearizer.d.ts`:
164-
165-
- **InterlinearData:** `ScrTextName`, `GlossLanguage`, `BookId`, `Verses` (record of verse key → **VerseData**).
166-
- **VerseData:** `Hash`, `Clusters` (array of **ClusterData**), `Punctuations` (array of **PunctuationData**).
167-
- **ClusterData:** `TextRange` (`Index`, `Length`), `Lexemes` (array of `{ LexemeId, SenseId }`), `LexemesId` (slash-joined lexeme IDs), `Id` (cluster id: `LexemesId/Index-Length` or `Index-Length` when there are no lexemes), `Excluded` (boolean flag for location-specific exclusion).
168-
- **PunctuationData:** `TextRange`, `BeforeText`, `AfterText`.
169-
170-
### Example (minimal valid document)
171-
172-
```xml
173-
<InterlinearData GlossLanguage="en" BookId="MAT">
174-
<Verses>
175-
<item>
176-
<string>MAT 1:1</string>
177-
<VerseData>
178-
<Cluster>
179-
<Range Index="0" Length="4" />
180-
<Lexeme Id="Word:word" GlossId="sense1" />
181-
</Cluster>
182-
</VerseData>
183-
</item>
184-
</Verses>
185-
</InterlinearData>
186-
```
187-
188-
### Example (full document with optional attributes)
189-
190-
This example shows optional root attributes, verse `Hash`, multiple verses and clusters, multiple lexemes per cluster, lexemes with and without `GlossId`, a cluster with no lexemes, and punctuation entries (with and without `BeforeText`/`AfterText`).
191-
192-
```xml
193-
<?xml version="1.0" encoding="utf-8"?>
194-
<InterlinearData ScrTextName="MyProject" GlossLanguage="en" BookId="RUT">
195-
<Verses>
196-
<item>
197-
<string>RUT 1:1</string>
198-
<VerseData Hash="A1B2C3D4">
199-
<Cluster>
200-
<Range Index="0" Length="3" />
201-
<Lexeme Id="Word:Now" GlossId="sense-now" />
202-
</Cluster>
203-
<Cluster>
204-
<Range Index="4" Length="3" />
205-
<Lexeme Id="Stem:come" GlossId="sense-come" />
206-
<Lexeme Id="Suffix:ing" GlossId="sense-ing" />
207-
</Cluster>
208-
<Cluster>
209-
<Range Index="8" Length="2" />
210-
</Cluster>
211-
<Cluster>
212-
<Range Index="11" Length="4" />
213-
<Lexeme Id="Word:days" />
214-
</Cluster>
215-
<Punctuation>
216-
<Range Index="7" Length="1" />
217-
<BeforeText>,</BeforeText>
218-
<AfterText>;</AfterText>
219-
</Punctuation>
220-
<Punctuation>
221-
<Range Index="15" Length="1" />
222-
</Punctuation>
223-
</VerseData>
224-
</item>
225-
<item>
226-
<string>RUT 1:2</string>
227-
<VerseData>
228-
<Cluster>
229-
<Range Index="0" Length="4" />
230-
<Lexeme Id="Word:name" GlossId="sense-name" />
231-
</Cluster>
232-
</VerseData>
233-
</item>
234-
</Verses>
235-
</InterlinearData>
236-
```
237-
238119
## To install
239120

240121
### Install dependencies:

0 commit comments

Comments
 (0)