Search in sources :

Example 1 with VerseIdentifier

use of biblemulticonverter.format.paratext.model.VerseIdentifier in project BibleMultiConverter by schierlm.

the class AbstractParatextFormat method exportToParatextBook.

protected ParatextBook exportToParatextBook(Book bk, String bibleName) {
    ParatextID pid = ParatextID.fromBookID(bk.getId());
    if (pid == null) {
        System.out.println("WARNING: Skipping unsupported book " + bk.getId());
        return null;
    }
    ParatextBook book = new ParatextBook(pid, bibleName);
    book.getAttributes().put("toc1", bk.getLongName());
    book.getAttributes().put("toc2", bk.getShortName());
    book.getAttributes().put("toc3", bk.getAbbr());
    ParatextExportContext ctx = new ParatextExportContext(book);
    for (int cnum = 1; cnum <= bk.getChapters().size(); cnum++) {
        Chapter ch = bk.getChapters().get(cnum - 1);
        if (cnum > 1)
            ctx.startChapter(cnum);
        if (ch.getProlog() != null) {
            ch.getProlog().accept(new ParatextExportVisitor("in prolog", bk.getId().isNT(), ctx, null, cnum == 1 ? ParagraphKind.INTRO_PARAGRAPH_P : ParagraphKind.CHAPTER_DESCRIPTION, null));
        }
        if (cnum == 1)
            ctx.startChapter(cnum);
        for (Verse v : ch.getVerses()) {
            String verseNumber = internalVerseNumberToParatextVerseNumber(v.getNumber());
            if (verseNumber == null) {
                throw new IllegalArgumentException("Could not export verse " + ctx.book.getId().getIdentifier() + " " + cnum + ":" + v.getNumber() + " because the verse number could not be transformed to a valid Paratext verse number");
            }
            VerseIdentifier location = VerseIdentifier.fromVerseNumberRangeOrThrow(pid, cnum, verseNumber);
            v.accept(new ParatextExportVisitor("in verse", bk.getId().isNT(), ctx, null, ParagraphKind.PARAGRAPH_P, location));
        }
        ctx.endChapter(cnum);
    }
    return book;
}
Also used : ParatextID(biblemulticonverter.format.paratext.ParatextBook.ParatextID) Chapter(biblemulticonverter.data.Chapter) Verse(biblemulticonverter.data.Verse) VerseIdentifier(biblemulticonverter.format.paratext.model.VerseIdentifier)

Example 2 with VerseIdentifier

use of biblemulticonverter.format.paratext.model.VerseIdentifier in project BibleMultiConverter by schierlm.

the class USFX method parseElement.

private void parseElement(ParatextBook result, List<ParatextCharacterContentContainer> containerStack, JAXBElement<?> element, ImportBookContext context) {
    String localName = element.getName().getLocalPart();
    if (localName.equals("rem") || localName.equals("cl")) {
        result.getAttributes().put(localName, TextUtilities.whitespaceNormalization((String) element.getValue()).trim());
    } else if (localName.equals("h")) {
        Usfx.Book.H h = (Usfx.Book.H) element.getValue();
        result.getAttributes().put("h" + (h.getLevel() == null ? "" : h.getLevel()), TextUtilities.whitespaceNormalization(h.getValue()).trim());
    } else if (localName.equals("b") && element.getValue() instanceof Usfx.Book.B) {
        Usfx.Book.B b = (Usfx.Book.B) element.getValue();
        String tag = (b.getSfm() == null ? localName : b.getSfm());
        ParagraphKind kind = USFM.PARAGRAPH_TAGS.get(tag);
        if (kind == null) {
            System.out.println("WARNING: Unsupported paragraph kind: " + kind);
            kind = ParagraphKind.PARAGRAPH_P;
        }
        result.getContent().add(new ParagraphStart(kind));
        containerStack.clear();
    } else if (Arrays.asList("p", "q", "d", "s", "mt", "b").contains(localName)) {
        PType pt = (PType) element.getValue();
        String tag = (pt.getSfm() == null ? localName : pt.getSfm()) + (pt.getLevel() == null ? "" : "" + pt.getLevel());
        ParagraphKind kind = USFM.PARAGRAPH_TAGS.get(tag);
        if (kind == null) {
            System.out.println("WARNING: Unsupported paragraph kind: " + kind);
            kind = ParagraphKind.PARAGRAPH_P;
        }
        result.getContent().add(new ParagraphStart(kind));
        containerStack.clear();
        parseElements(result, containerStack, pt.getContent(), context);
    } else if (Arrays.asList("sectionBoundary", "ca", "milestone", "va", "fm", "fig", "gw", "cs", "wr").contains(localName)) {
        System.out.println("WARNING: Skipping unsupported tag: " + localName);
    } else if (Arrays.asList("generated", "cp", "vp", "wtp", "da", "fs").contains(localName)) {
    // to be skipped
    } else if (localName.equals("c")) {
        ImportUtilities.closeOpenChapter(result, context.openChapter);
        String id;
        if (element.getValue() instanceof Usfx.Book.C) {
            Usfx.Book.C c = (Usfx.Book.C) element.getValue();
            id = c.getId();
        } else if (element.getValue() instanceof PType.C) {
            PType.C c = (PType.C) element.getValue();
            id = c.getId();
        } else {
            throw new IllegalStateException(element.getValue().getClass().getName());
        }
        context.openChapter = new ChapterStart(new ChapterIdentifier(result.getId(), Integer.parseInt(id)));
        result.getContent().add(context.openChapter);
        containerStack.clear();
    } else if (localName.equals("toc")) {
        StyledString ss = (StyledString) element.getValue();
        result.getAttributes().put("toc" + ss.getLevel(), TextUtilities.whitespaceNormalization(ss.getContent().stream().filter(c -> c instanceof String).map(Serializable::toString).collect(Collectors.joining())).trim());
    } else if (localName.equals("table") && element.getValue() instanceof Usfx.Book.Table) {
        Usfx.Book.Table table = (Usfx.Book.Table) element.getValue();
        for (Usfx.Book.Table.Tr tr : table.getTr()) {
            result.getContent().add(new ParagraphStart(ParagraphKind.TABLE_ROW));
            for (JAXBElement<PType> cell : tr.getThOrThrOrTc()) {
                result.getContent().add(new TableCellStart(cell.getName().getLocalPart() + cell.getValue().getLevel()));
                containerStack.clear();
                parseElements(result, containerStack, cell.getValue().getContent(), context);
            }
        }
    } else if (localName.equals("table") && element.getValue() instanceof PType.Table) {
        PType.Table table = (PType.Table) element.getValue();
        for (PType.Table.Tr tr : table.getTr()) {
            result.getContent().add(new ParagraphStart(ParagraphKind.TABLE_ROW));
            for (JAXBElement<PType> cell : tr.getThOrThrOrTc()) {
                result.getContent().add(new TableCellStart(cell.getName().getLocalPart() + cell.getValue().getLevel()));
                containerStack.clear();
                parseElements(result, containerStack, cell.getValue().getContent(), context);
            }
        }
    } else if (localName.equals("periph")) {
        result.getContent().add(new ParagraphStart(ParagraphKind.PERIPHERALS));
        containerStack.clear();
        ParatextCharacterContent container = new ParatextCharacterContent();
        Text text = Text.from((String) element.getValue());
        if (text != null) {
            container.getContent().add(text);
        }
        containerStack.add(container);
        result.getContent().add(container);
    } else if (localName.equals("v")) {
        String id;
        if (element.getValue() instanceof Usfx.Book.V) {
            Usfx.Book.V v = (Usfx.Book.V) element.getValue();
            id = v.getId();
        } else if (element.getValue() instanceof PType.V) {
            PType.V v = (PType.V) element.getValue();
            id = v.getId();
        } else {
            throw new IllegalStateException(element.getValue().getClass().getName());
        }
        if (containerStack.isEmpty()) {
            ParatextCharacterContent container = new ParatextCharacterContent();
            containerStack.add(container);
            result.getContent().add(container);
        }
        ChapterStart chapter = result.findLastBookContent(ChapterStart.class);
        if (chapter == null) {
            throw new IllegalStateException("Verse found before chapter start: " + id);
        }
        VerseIdentifier location = new VerseIdentifier(result.getId(), chapter.getChapter(), id);
        containerStack.get(containerStack.size() - 1).getContent().add(new VerseStart(location, id));
    } else if (localName.equals("ve")) {
        VerseStart start = result.findLastCharacterContent(VerseStart.class);
        if (start == null) {
            throw new IllegalStateException("Verse end found before verse start!");
        }
        if (containerStack.isEmpty()) {
            ParatextCharacterContent container = new ParatextCharacterContent();
            containerStack.add(container);
            result.getContent().add(container);
        }
        containerStack.get(containerStack.size() - 1).getContent().add(new ParatextCharacterContent.VerseEnd(start.getLocation()));
    } else if (Arrays.asList("f", "x", "fe").contains(localName)) {
        NoteContents nc = (NoteContents) element.getValue();
        String sfm = nc.getSfm();
        if (sfm == null || sfm.isEmpty())
            sfm = localName;
        String caller = nc.getCaller();
        if (caller == null || caller.isEmpty())
            caller = "+";
        FootnoteXref nextContainer = new FootnoteXref(USFM.FOOTNOTE_XREF_TAGS.get(sfm), caller);
        if (containerStack.isEmpty()) {
            ParatextCharacterContent container = new ParatextCharacterContent();
            containerStack.add(container);
            result.getContent().add(container);
        }
        containerStack.get(containerStack.size() - 1).getContent().add(nextContainer);
        containerStack.add(nextContainer);
        parseElements(result, containerStack, nc.getContent(), context);
        containerStack.remove(nextContainer);
    } else if (Arrays.asList("fp", "fr", "fk", "fq", "fqa", "fl", "fdc", "fv", "ft", "fm", "xo", "xk", "xq", "xt", "xot", "xnt", "xdc").contains(localName) || (Arrays.asList("nd", "c", "tl", "it", "qt", "sls", "dc", "bdit", "bk", "pn", "k", "ord", "add", "bd", "sc", "wh", "wg", "wr", "wj", "cs", "em").contains(localName) && element.getValue() instanceof NoteContents)) {
        NoteContents nc = (NoteContents) element.getValue();
        String sfm = nc.getSfm();
        if (sfm == null || sfm.isEmpty())
            sfm = localName;
        if (containerStack.isEmpty()) {
            ParatextCharacterContent container = new ParatextCharacterContent();
            containerStack.add(container);
            result.getContent().add(container);
        }
        AutoClosingFormatting nextContainer = new AutoClosingFormatting(USFM.AUTO_CLOSING_TAGS.get(sfm), false);
        containerStack.get(containerStack.size() - 1).getContent().add(nextContainer);
        containerStack.add(nextContainer);
        parseElements(result, containerStack, nc.getContent(), context);
        containerStack.remove(nextContainer);
    } else if (localName.equals("optionalLineBreak")) {
        System.out.println("WARNING: Skipping optional line break");
    } else if (localName.equals("ref")) {
        RefType rt = (RefType) element.getValue();
        ParatextCharacterContentPart ref = Text.from(rt.getContent());
        // This code does not allow for a second book, as in: ISA.7.14-ISA.7.15.
        if (rt.getTgt() == null || !rt.getTgt().matches("[A-Z1-4]{3}\\.[0-9]+\\.[0-9]+(-[0-9]+(\\.[0-9]+)?)?")) {
            System.out.println("WARNING: Unsupported structured reference format - replaced by plain text: " + rt.getTgt());
        } else {
            String[] parts = rt.getTgt().split("[ .-]");
            ParatextID id = ParatextID.fromIdentifier(parts[0]);
            if (id == null) {
                System.out.println("WARNING: Unsupported book in structured reference - replaced by plain text: " + parts[0]);
            } else {
                int c1 = Integer.parseInt(parts[1]);
                String v1 = parts[2];
                if (parts.length > 3) {
                    // second verse
                    String v2 = parts[parts.length - 1];
                    if (parts.length == 5) {
                        // second chapter
                        int c2 = Integer.parseInt(parts[3]);
                        ref = Reference.verseRange(id, c1, v1, c2, v2, rt.getContent());
                    } else {
                        // No second chapter, but we do have a second verse, use first chapter as second chapter.
                        ref = Reference.verseRange(id, c1, v1, c1, v2, rt.getContent());
                    }
                } else {
                    ref = Reference.verse(id, c1, v1, rt.getContent());
                }
            }
        }
        if (ref != null) {
            if (containerStack.isEmpty()) {
                ParatextCharacterContent container = new ParatextCharacterContent();
                containerStack.add(container);
                result.getContent().add(container);
            }
            containerStack.get(containerStack.size() - 1).getContent().add(ref);
        }
    } else if (localName.equals("w")) {
        PType.W w = (PType.W) element.getValue();
        String sfm = w.getSfm();
        if (sfm == null || sfm.isEmpty())
            sfm = localName;
        AutoClosingFormatting nextContainer = new AutoClosingFormatting(USFM.AUTO_CLOSING_TAGS.get(sfm), false);
        if (w.getL() != null && !w.getL().isEmpty())
            nextContainer.getAttributes().put("lemma", w.getL());
        if (w.getS() != null && !w.getS().isEmpty())
            nextContainer.getAttributes().put("strong", w.getS());
        if (w.getM() != null && !w.getM().isEmpty())
            nextContainer.getAttributes().put("x-morph", w.getM());
        if (w.getSrcloc() != null && !w.getSrcloc().isEmpty())
            nextContainer.getAttributes().put("x-srcloc", w.getSrcloc());
        if (w.isPlural() != null)
            nextContainer.getAttributes().put("x-plural", "" + w.isPlural());
        containerStack.get(containerStack.size() - 1).getContent().add(nextContainer);
        containerStack.add(nextContainer);
        parseElements(result, containerStack, w.getContent(), context);
        containerStack.remove(nextContainer);
    } else if (localName.equals("quoteStart")) {
        PType.QuoteStart qs = (PType.QuoteStart) element.getValue();
        Text text = Text.from(qs.getValue());
        if (text != null) {
            if (containerStack.isEmpty()) {
                ParatextCharacterContent container = new ParatextCharacterContent();
                containerStack.add(container);
                result.getContent().add(container);
            }
            containerStack.get(containerStack.size() - 1).getContent().add(text);
        }
    } else if (localName.equals("quoteRemind") || localName.equals("quoteEnd")) {
        Text text = Text.from((String) element.getValue());
        if (text != null) {
            if (containerStack.isEmpty()) {
                ParatextCharacterContent container = new ParatextCharacterContent();
                containerStack.add(container);
                result.getContent().add(container);
            }
            containerStack.get(containerStack.size() - 1).getContent().add(text);
        }
    } else if (Arrays.asList("rq", "em", "qt", "nd", "tl", "qs", "qac", "sls", "dc", "bk", "k", "add", "sig", "bd", "it", "bdit", "sc", "wj").contains(localName)) {
        PType v = (PType) element.getValue();
        String sfm = v.getSfm();
        if (sfm == null || sfm.isEmpty())
            sfm = localName;
        AutoClosingFormatting nextContainer = new AutoClosingFormatting(USFM.AUTO_CLOSING_TAGS.get(sfm), false);
        if (containerStack.isEmpty()) {
            ParatextCharacterContent container = new ParatextCharacterContent();
            containerStack.add(container);
            result.getContent().add(container);
        }
        containerStack.get(containerStack.size() - 1).getContent().add(nextContainer);
        containerStack.add(nextContainer);
        parseElements(result, containerStack, v.getContent(), context);
        containerStack.remove(nextContainer);
    } else if (Arrays.asList("pn", "ord", "no", "ndx", "wh", "wg", "ior").contains(localName)) {
        AutoClosingFormatting nextContainer = new AutoClosingFormatting(USFM.AUTO_CLOSING_TAGS.get(localName), false);
        if (containerStack.isEmpty()) {
            ParatextCharacterContent container = new ParatextCharacterContent();
            containerStack.add(container);
            result.getContent().add(container);
        }
        containerStack.get(containerStack.size() - 1).getContent().add(nextContainer);
        Text text = Text.from((String) element.getValue());
        if (text != null) {
            nextContainer.getContent().add(text);
        }
    } else {
        System.out.println("WARNING: Unexpected tag: " + localName);
    }
}
Also used : TableCellStart(biblemulticonverter.format.paratext.ParatextBook.TableCellStart) StyledString(biblemulticonverter.schema.usfx.StyledString) RefType(biblemulticonverter.schema.usfx.RefType) ParatextID(biblemulticonverter.format.paratext.ParatextBook.ParatextID) Book(biblemulticonverter.schema.usfx.Usfx.Book) NoteContents(biblemulticonverter.schema.usfx.NoteContents) AutoClosingFormatting(biblemulticonverter.format.paratext.ParatextCharacterContent.AutoClosingFormatting) PType(biblemulticonverter.schema.usfx.PType) Text(biblemulticonverter.format.paratext.ParatextCharacterContent.Text) StyledString(biblemulticonverter.schema.usfx.StyledString) JAXBElement(javax.xml.bind.JAXBElement) ChapterStart(biblemulticonverter.format.paratext.ParatextBook.ChapterStart) FootnoteXref(biblemulticonverter.format.paratext.ParatextCharacterContent.FootnoteXref) VerseIdentifier(biblemulticonverter.format.paratext.model.VerseIdentifier) VerseStart(biblemulticonverter.format.paratext.ParatextCharacterContent.VerseStart) ParatextCharacterContentPart(biblemulticonverter.format.paratext.ParatextCharacterContent.ParatextCharacterContentPart) ParagraphKind(biblemulticonverter.format.paratext.ParatextBook.ParagraphKind) Usfx(biblemulticonverter.schema.usfx.Usfx) ChapterIdentifier(biblemulticonverter.format.paratext.model.ChapterIdentifier) ParagraphStart(biblemulticonverter.format.paratext.ParatextBook.ParagraphStart)

Example 3 with VerseIdentifier

use of biblemulticonverter.format.paratext.model.VerseIdentifier in project BibleMultiConverter by schierlm.

the class USX method handleVerse.

private VerseStart handleVerse(ParatextBook result, Verse verse) throws IOException {
    ChapterStart chapter = result.findLastBookContent(ChapterStart.class);
    if (chapter == null) {
        throw new IllegalStateException("Verse found before chapter start: " + verse.getNumber());
    }
    // A verse number in USX 2 may be in the format 6-7, 6a or even 6-7a.
    // Attempt to parse these numbers by first adding the book and chapter and then parsing it as a whole.
    VerseIdentifier location = VerseIdentifier.fromStringOrThrow(chapter.getLocation() + ":" + verse.getNumber());
    return new VerseStart(location, verse.getNumber());
}
Also used : VerseStart(biblemulticonverter.format.paratext.ParatextCharacterContent.VerseStart) ChapterStart(biblemulticonverter.format.paratext.ParatextBook.ChapterStart) VerseIdentifier(biblemulticonverter.format.paratext.model.VerseIdentifier)

Example 4 with VerseIdentifier

use of biblemulticonverter.format.paratext.model.VerseIdentifier in project BibleMultiConverter by schierlm.

the class USFM method doImportBook.

private ParatextBook doImportBook(File inputFile, Charset charset) throws Exception {
    KNOWN_CHARACTER_TAGS.addAll(AUTO_CLOSING_TAGS.keySet());
    if (!inputFile.getName().toLowerCase().endsWith(".usfm") && !inputFile.getName().toLowerCase().endsWith(".sfm"))
        return null;
    String data = TextUtilities.usfmWhitespaceNormalization(new String(Files.readAllBytes(inputFile.toPath()), charset), preserveSpacesAtEndOfLines) + "\\$EOF$";
    if (!data.startsWith("\\id ")) {
        System.out.println("WARNING: Skipping malformed file " + inputFile);
        return null;
    }
    int startPos = data.indexOf("\\", 2);
    int finalPos = data.length() - "\\$EOF$".length();
    String[] idParts = data.substring(4, startPos).trim().split(" ", 2);
    ParatextID id = ParatextID.fromIdentifier(idParts[0].toUpperCase());
    if (id == null) {
        System.out.println("WARNING: Skipping book with unknown ID: " + idParts[0]);
        return null;
    }
    ParatextBook result = new ParatextBook(id, idParts.length == 1 ? "" : idParts[1]);
    List<ParatextCharacterContentContainer> containerStack = new ArrayList<>();
    boolean ignoreAutoClosingTags = Boolean.getBoolean("biblemulticonverter.usfm.ignoreautoclosingtags");
    VerseStart openVerse = null;
    ChapterStart openChapter = null;
    while (startPos < finalPos) {
        if (data.charAt(startPos) != '\\')
            throw new IllegalStateException();
        int pos = data.indexOf('\\', startPos + 1);
        String textPart = data.substring(startPos + 1, pos);
        startPos = pos;
        pos = Math.min(textPart.length(), 1 + Math.min((textPart + " ").indexOf(' '), (textPart + "*").indexOf('*')));
        String tag = textPart.substring(0, pos).trim().toLowerCase();
        textPart = textPart.substring(pos);
        if (textPart.endsWith(" ")) {
            String nextTag = data.substring(startPos + 1, Math.min(data.length(), startPos + 10)) + " *\\";
            pos = Math.min(nextTag.indexOf('\\'), Math.min(nextTag.indexOf(' '), nextTag.indexOf('*')));
            if (!KNOWN_CHARACTER_TAGS.contains(nextTag.substring(0, pos))) {
                textPart = textPart.substring(0, textPart.length() - 1);
            }
        }
        if (containerStack.isEmpty() && (AUTO_CLOSING_TAGS.containsKey(tag) || tag.equals("v") || FOOTNOTE_XREF_TAGS.containsKey(tag))) {
            ParatextCharacterContent container = new ParatextCharacterContent();
            result.getContent().add(container);
            containerStack.add(container);
        }
        boolean closeCharacterAttributes = false;
        if (PARAGRAPH_TAGS.containsKey(tag)) {
            ParagraphKind kind = PARAGRAPH_TAGS.get(tag);
            // if (kind.getCategory() != ParatextBook.ParagraphKindCategory.TEXT) {
            // Close any open verse
            // openVerse = closeOpenVerse(result, openVerse, false);
            // }
            result.getContent().add(new ParagraphStart(kind));
            closeCharacterAttributes = true;
        } else if (tag.endsWith("*")) {
            String rawTag = tag.substring(0, tag.length() - 1);
            while (!containerStack.isEmpty() && containerStack.get(containerStack.size() - 1) instanceof AutoClosingFormatting) {
                AutoClosingFormatting acc = (AutoClosingFormatting) containerStack.get(containerStack.size() - 1);
                if (acc.getUsedTag().equals(rawTag))
                    break;
                containerStack.remove(containerStack.size() - 1);
            }
            boolean found = false;
            if (AUTO_CLOSING_TAGS.containsKey(rawTag)) {
                if (!containerStack.isEmpty() && containerStack.get(containerStack.size() - 1) instanceof AutoClosingFormatting) {
                    AutoClosingFormatting acc = (AutoClosingFormatting) containerStack.get(containerStack.size() - 1);
                    found = acc.getUsedTag().equals(rawTag);
                }
            } else if (FOOTNOTE_XREF_TAGS.containsKey(rawTag)) {
                if (!containerStack.isEmpty() && containerStack.get(containerStack.size() - 1) instanceof FootnoteXref) {
                    FootnoteXref fx = (FootnoteXref) containerStack.get(containerStack.size() - 1);
                    found = fx.getKind().getTag().equals(rawTag);
                }
            } else {
                System.out.println("WARNING: Skipping unknown end tag \\" + tag);
            }
            if (found) {
                containerStack.remove(containerStack.size() - 1);
            } else {
                System.out.println("WARNING: Skipping mismatched end tag \\" + tag);
            }
        } else if (AUTO_CLOSING_TAGS.containsKey(tag)) {
            if (!tag.startsWith("+") && !ignoreAutoClosingTags) {
                while (!containerStack.isEmpty() && containerStack.get(containerStack.size() - 1) instanceof AutoClosingFormatting) {
                    containerStack.remove(containerStack.size() - 1);
                }
            }
            AutoClosingFormatting nextContainer = new AutoClosingFormatting(AUTO_CLOSING_TAGS.get(tag), tag.startsWith("+"));
            containerStack.get(containerStack.size() - 1).getContent().add(nextContainer);
            containerStack.add(nextContainer);
            if (nextContainer.getKind().getDefaultAttributes() != null && data.startsWith("\\" + tag + "*", startPos) && textPart.contains("|")) {
                String[] defaultAttributes = nextContainer.getKind().getDefaultAttributes();
                String[] parts = textPart.split("\\|");
                for (int i = 1; i < parts.length; i++) {
                    if (parts[i].contains("=")) {
                        String attList = parts[i];
                        while (attList.contains("=")) {
                            pos = attList.indexOf('=');
                            String key = attList.substring(0, pos).trim();
                            attList = attList.substring(pos + 1).trim();
                            if (attList.startsWith("\"")) {
                                pos = attList.indexOf('"', 1);
                                nextContainer.getAttributes().put(key, attList.substring(1, pos));
                                attList = attList.substring(pos + 1).trim();
                            } else {
                                nextContainer.getAttributes().put(key, attList);
                                attList = "";
                            }
                        }
                    } else if (i - 1 < defaultAttributes.length) {
                        nextContainer.getAttributes().put(defaultAttributes[i - 1], parts[i]);
                    }
                }
                textPart = parts[0];
                if (textPart.endsWith(" ")) {
                    textPart = textPart.substring(0, textPart.length() - 1);
                }
            }
        } else if (tag.equals("v")) {
            ImportUtilities.closeOpenVerse(result, openVerse);
            String[] parts = textPart.split(" ", 2);
            ChapterStart chapter = result.findLastBookContent(ChapterStart.class);
            if (chapter == null) {
                throw new IllegalStateException("Verse \\v found before chapter start milestone");
            }
            // A verse number in USFM 2 may be in the format 6-7, 6a or even 6-7a.
            // Attempt to parse these numbers by first adding the book and chapter and then parsing it as a whole.
            VerseIdentifier location = VerseIdentifier.fromStringOrThrow(openChapter.getLocation() + ":" + parts[0]);
            openVerse = new VerseStart(location, parts[0]);
            containerStack.get(containerStack.size() - 1).getContent().add(openVerse);
            textPart = parts.length == 1 ? "" : parts[1];
        } else if (tag.equals("c")) {
            ImportUtilities.closeOpenVerse(result, openVerse);
            openVerse = null;
            // There is not really a good way to accurately determine where the end of a chapter should be placed
            // based on USFM 2 content. Maybe a title above this chapter marker was already intended to be part of
            // this chapter. This is basically a best guess. This should not really matter when converting from
            // USFM 2 to USX 2 or USFX (which is based on USFM 2), however when up-converting to USX 3 this might
            // lead to unexpected results.
            ImportUtilities.closeOpenChapter(result, openChapter);
            String[] parts = textPart.split(" ", 2);
            if (!parts[0].matches("[0-9]+"))
                throw new NumberFormatException("Invalid chapter number in \\c " + textPart);
            openChapter = new ChapterStart(new ChapterIdentifier(id, Integer.parseInt(parts[0])));
            result.getContent().add(openChapter);
            closeCharacterAttributes = true;
            textPart = parts.length == 1 ? "" : parts[1];
        } else if (tag.matches("t[hc]r?[0-9]+")) {
            result.getContent().add(new TableCellStart(tag));
            closeCharacterAttributes = true;
        } else if (FOOTNOTE_XREF_TAGS.containsKey(tag)) {
            String[] parts = textPart.split(" ", 2);
            FootnoteXref nextContainer = new FootnoteXref(FOOTNOTE_XREF_TAGS.get(tag), parts[0]);
            containerStack.get(containerStack.size() - 1).getContent().add(nextContainer);
            containerStack.add(nextContainer);
            textPart = parts.length == 1 ? "" : parts[1];
        } else if (tag.equals("id")) {
            System.out.println("WARNING: Skipping duplicate \\id tag");
            textPart = "";
        } else if (tag.equals("ide")) {
            Charset correctCharset;
            try {
                if (textPart.matches("[0-9]+ - .*")) {
                    int codepage = Integer.parseInt(textPart.replaceAll(" - .*", ""));
                    correctCharset = codepage == 65001 ? StandardCharsets.UTF_8 : Charset.forName("windows-" + codepage);
                } else {
                    correctCharset = Charset.forName(textPart);
                }
            } catch (UnsupportedCharsetException | IllegalCharsetNameException ex) {
                System.out.println("WARNING: Unknown charset " + textPart + " specified, falling back to ISO-8859-1");
                correctCharset = StandardCharsets.ISO_8859_1;
            }
            if (!correctCharset.equals(charset)) {
                if (!charset.equals(StandardCharsets.UTF_8)) {
                    throw new IOException("Two charsets specified: " + charset + " and " + correctCharset);
                }
                return doImportBook(inputFile, correctCharset);
            } else {
                result.getAttributes().put(tag, textPart);
            }
            textPart = "";
        } else if (BOOK_HEADER_ATTRIBUTE_TAGS.contains(tag)) {
            result.getAttributes().put(tag, textPart);
            textPart = "";
        } else {
            System.out.println("WARNING: Skipping unknown tag \\" + tag);
        }
        if (closeCharacterAttributes) {
            containerStack.clear();
        }
        textPart = textPart.replace(" // ", " ").replace("~", "\u00A0");
        ParatextCharacterContent.Text text = ParatextCharacterContent.Text.from(textPart);
        if (text != null) {
            if (containerStack.isEmpty()) {
                ParatextCharacterContent container = new ParatextCharacterContent();
                containerStack.add(container);
                result.getContent().add(container);
            }
            containerStack.get(containerStack.size() - 1).getContent().add(text);
        }
    }
    ImportUtilities.closeOpenVerse(result, openVerse);
    ImportUtilities.closeOpenChapter(result, openChapter);
    return result;
}
Also used : TableCellStart(biblemulticonverter.format.paratext.ParatextBook.TableCellStart) ArrayList(java.util.ArrayList) IllegalCharsetNameException(java.nio.charset.IllegalCharsetNameException) ParatextID(biblemulticonverter.format.paratext.ParatextBook.ParatextID) AutoClosingFormatting(biblemulticonverter.format.paratext.ParatextCharacterContent.AutoClosingFormatting) Charset(java.nio.charset.Charset) IOException(java.io.IOException) ChapterStart(biblemulticonverter.format.paratext.ParatextBook.ChapterStart) FootnoteXref(biblemulticonverter.format.paratext.ParatextCharacterContent.FootnoteXref) VerseIdentifier(biblemulticonverter.format.paratext.model.VerseIdentifier) VerseStart(biblemulticonverter.format.paratext.ParatextCharacterContent.VerseStart) ParatextCharacterContentContainer(biblemulticonverter.format.paratext.ParatextBook.ParatextCharacterContentContainer) ParagraphKind(biblemulticonverter.format.paratext.ParatextBook.ParagraphKind) UnsupportedCharsetException(java.nio.charset.UnsupportedCharsetException) ChapterIdentifier(biblemulticonverter.format.paratext.model.ChapterIdentifier) ParagraphStart(biblemulticonverter.format.paratext.ParatextBook.ParagraphStart)

Example 5 with VerseIdentifier

use of biblemulticonverter.format.paratext.model.VerseIdentifier in project BibleMultiConverter by schierlm.

the class AbstractParatextFormatTest method test_on_import_paratext_verse_numbers_are_transformed_to_internal_verse_numbers.

@Test
public void test_on_import_paratext_verse_numbers_are_transformed_to_internal_verse_numbers() {
    // Dummy paratext book
    ParatextBook paratextBook = new ParatextBook(ParatextBook.ParatextID.ID_1CO, null);
    paratextBook.getContent().add(new ParatextBook.ChapterStart(new ChapterIdentifier(paratextBook.getId(), 1)));
    paratextBook.getContent().add(new ParatextBook.ParagraphStart(ParatextBook.ParagraphKind.PARAGRAPH_P));
    ParatextCharacterContent characterContent = new ParatextCharacterContent();
    paratextBook.getContent().add(characterContent);
    // Normal verse number
    addDummyVerse(characterContent, new VerseIdentifier(paratextBook.getId(), 1, "5", null), "5");
    // Paratext only supported verse number
    addDummyVerse(characterContent, new VerseIdentifier(paratextBook.getId(), 1, "6b", "7a"), "6b-7a");
    paratextBook.getContent().add(new ParatextBook.ChapterEnd(new ChapterIdentifier(paratextBook.getId(), 1)));
    AbstractParatextFormat format = new TestParatextFormat();
    Map<ParatextBook.ParatextID, String> abbrs = new EnumMap<>(ParatextBook.ParatextID.class);
    abbrs.put(ParatextBook.ParatextID.ID_1CO, "1co");
    Book book = format.importParatextBook(paratextBook, abbrs);
    Chapter chapter = book.getChapters().get(0);
    assertEquals("5", chapter.getVerses().get(0).getNumber());
    assertEquals("6b", chapter.getVerses().get(1).getNumber());
}
Also used : Chapter(biblemulticonverter.data.Chapter) VerseIdentifier(biblemulticonverter.format.paratext.model.VerseIdentifier) Book(biblemulticonverter.data.Book) ChapterIdentifier(biblemulticonverter.format.paratext.model.ChapterIdentifier) EnumMap(java.util.EnumMap) Test(org.junit.Test)

Aggregations

VerseIdentifier (biblemulticonverter.format.paratext.model.VerseIdentifier)5 ChapterStart (biblemulticonverter.format.paratext.ParatextBook.ChapterStart)3 ParatextID (biblemulticonverter.format.paratext.ParatextBook.ParatextID)3 VerseStart (biblemulticonverter.format.paratext.ParatextCharacterContent.VerseStart)3 ChapterIdentifier (biblemulticonverter.format.paratext.model.ChapterIdentifier)3 Chapter (biblemulticonverter.data.Chapter)2 ParagraphKind (biblemulticonverter.format.paratext.ParatextBook.ParagraphKind)2 ParagraphStart (biblemulticonverter.format.paratext.ParatextBook.ParagraphStart)2 TableCellStart (biblemulticonverter.format.paratext.ParatextBook.TableCellStart)2 AutoClosingFormatting (biblemulticonverter.format.paratext.ParatextCharacterContent.AutoClosingFormatting)2 FootnoteXref (biblemulticonverter.format.paratext.ParatextCharacterContent.FootnoteXref)2 Book (biblemulticonverter.data.Book)1 Verse (biblemulticonverter.data.Verse)1 ParatextCharacterContentContainer (biblemulticonverter.format.paratext.ParatextBook.ParatextCharacterContentContainer)1 ParatextCharacterContentPart (biblemulticonverter.format.paratext.ParatextCharacterContent.ParatextCharacterContentPart)1 Text (biblemulticonverter.format.paratext.ParatextCharacterContent.Text)1 NoteContents (biblemulticonverter.schema.usfx.NoteContents)1 PType (biblemulticonverter.schema.usfx.PType)1 RefType (biblemulticonverter.schema.usfx.RefType)1 StyledString (biblemulticonverter.schema.usfx.StyledString)1