/* * This file is part of TREB. * * TREB is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any * later version. * * TREB is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with TREB. If not, see . * * Copyright 2022-2026 trebco, llc. * info@treb.app * */ import * as OOXML from 'ooxml-types'; import { EnsureArray, IterateTags } from './ooxml'; export class SharedStrings { public strings: string[] = []; public reverse: Record = {}; /** read strings table from (pre-parsed) xml; removes any existing strings */ public FromXML(sst: OOXML.SharedStringTable) { // clear this.strings = []; this.reverse = {}; let index = 0; IterateTags(sst.si, si => { // simple string looks like // // // text here! // if (si.t !== undefined) { // seen recently in the wild, text with leading (or trailing) spaces // has an attribute xml:space=preserve (which makes sense, but was not // expecting it) // // // (Target portfolio lease rate based on internal estimate of average Canadian farmland rates) // // let base = ''; if (typeof si.t === 'string') { base = si.t; } else if (si.t.$text) { base = si.t.$text; } this.strings[index] = base; this.reverse[base] = index; } // complex string looks like // // // // (...style data...) // text part // // // // where there can be multiple r tags with different styling. // since we don't support that atm, let's drop style and just // collect text. else if (si.r) { // not sure what happens if there are multiple tags const r = EnsureArray(si.r)[0]; if (r) { const parts = EnsureArray(r.t); const composite = parts.map(part => part.$text || '').join(''); this.strings[index] = composite; this.reverse[composite] = index; } } else { console.warn(` ** unexpected shared string @ ${index}`); console.info(si); } index++; }); } /** return a string by index */ public Get(index: number): string|undefined { return this.strings[index]; } /** find existing string or insert, and return index */ public Ensure(text: string): number { if (text[0] === '\'') { text = text.substring(1); } let index = this.reverse[text]; if (typeof index === 'number') { return index; } index = this.strings.length; this.strings.push(text); this.reverse[text] = index; return index; } }