Search in sources :

Example 1 with FormattingInstructionKind

use of biblemulticonverter.data.FormattedText.FormattingInstructionKind in project BibleMultiConverter by schierlm.

the class TheWord method parseLine.

private int parseLine(Visitor<RuntimeException> visitor, String line, int pos, String endTag) {
    Visitor<RuntimeException> garbageVisitor = new FormattedText().getAppendVisitor();
    while (pos < line.length()) {
        if (line.charAt(pos) != '<') {
            int endPos = line.indexOf('<', pos);
            if (endPos == -1)
                endPos = line.length();
            visitor.visitText(line.substring(pos, endPos).replaceAll("[\r\n\t ]+", " "));
            pos = endPos;
            continue;
        }
        if (endTag != null && line.startsWith(endTag, pos))
            break;
        if (pos + 2 < line.length() && line.charAt(pos + 2) == '>' && "bius".indexOf(line.charAt(pos + 1)) != -1) {
            String newEndTag = "</" + line.charAt(pos + 1) + ">";
            if (parseLine(garbageVisitor, line, pos + 3, newEndTag) != -1) {
                FormattingInstructionKind kind;
                switch(line.charAt(pos + 1)) {
                    case 'b':
                        kind = FormattingInstructionKind.BOLD;
                        break;
                    case 'i':
                        kind = FormattingInstructionKind.ITALIC;
                        break;
                    case 'u':
                        kind = FormattingInstructionKind.UNDERLINE;
                        break;
                    case 's':
                        kind = FormattingInstructionKind.STRIKE_THROUGH;
                        break;
                    default:
                        throw new RuntimeException("Cannot happen");
                }
                pos = parseLine(visitor.visitFormattingInstruction(kind), line, pos + 3, newEndTag);
                continue;
            }
        } else if (line.startsWith("<sub>", pos) || line.startsWith("<sup>", pos)) {
            String newEndTag = "</" + line.substring(pos + 1, pos + 5);
            if (parseLine(garbageVisitor, line, pos + 5, newEndTag) != -1) {
                FormattingInstructionKind kind = line.charAt(pos + 3) == 'p' ? FormattingInstructionKind.SUPERSCRIPT : FormattingInstructionKind.SUBSCRIPT;
                pos = parseLine(visitor.visitFormattingInstruction(kind), line, pos + 5, newEndTag);
                continue;
            }
        } else if (line.startsWith("<FR>", pos)) {
            if (parseLine(garbageVisitor, line, pos + 4, "<Fr>") != -1) {
                pos = parseLine(visitor.visitFormattingInstruction(FormattingInstructionKind.WORDS_OF_JESUS), line, pos + 4, "<Fr>");
                continue;
            }
        } else if (line.startsWith("<FO>", pos)) {
            if (parseLine(garbageVisitor, line, pos + 4, "<Fo>") != -1) {
                pos = parseLine(visitor.visitFormattingInstruction(FormattingInstructionKind.LINK), line, pos + 4, "<Fo>");
                continue;
            }
        } else if (line.startsWith("<font color=\"gray\">/</font>", pos)) {
            visitor.visitVerseSeparator();
            pos += 27;
            continue;
        } else if (line.startsWith("<CL>", pos)) {
            visitor.visitLineBreak(LineBreakKind.NEWLINE);
            pos += 4;
            continue;
        } else if (line.startsWith("<CM>", pos)) {
            visitor.visitLineBreak(LineBreakKind.PARAGRAPH);
            pos += 4;
            continue;
        } else if (line.startsWith("<CI><PI>", pos)) {
            visitor.visitLineBreak(LineBreakKind.NEWLINE_WITH_INDENT);
            pos += 8;
            continue;
        } else if (line.startsWith("<TS", pos) && pos + 3 < line.length()) {
            char next = line.charAt(pos + 3);
            int depth, len;
            if (next == '>') {
                depth = 1;
                len = 4;
            } else if (pos + 4 < line.length() && line.charAt(pos + 4) == '>' && next >= '1' && next <= '3') {
                depth = next - '0';
                len = 5;
            } else {
                depth = len = 0;
            }
            String end = "<Ts>", altEnd = len == 5 ? "<Ts" + next + ">" : "<Ts>";
            if (line.indexOf(altEnd, pos) != -1 && (line.indexOf(end, pos) == -1 || line.indexOf(altEnd, pos) < line.indexOf(end, pos)))
                end = altEnd;
            if (len > 0 && parseLine(garbageVisitor, line, pos + len, end) != -1) {
                pos = parseLine(visitor.visitHeadline(depth), line, pos + len, end);
                continue;
            }
        } else if (line.startsWith("<RF", pos)) {
            int closePos = line.indexOf('>', pos);
            if (parseLine(garbageVisitor, line, closePos + 1, "<Rf>") != -1) {
                pos = parseLine(visitor.visitFootnote(), line, closePos + 1, "<Rf>");
                continue;
            }
        } else if (line.startsWith("<FI>", pos)) {
            if (parseLine(garbageVisitor, line, pos + 4, "<Fi>") != -1) {
                pos = parseLine(visitor.visitFormattingInstruction(FormattingInstructionKind.ITALIC), line, pos + 4, "<Fi>");
                continue;
            }
        } else if (line.startsWith("<S%", pos)) {
            int closePos = line.indexOf('>', pos);
            if (parseLine(garbageVisitor, line, closePos + 1, "<s%>") != -1) {
                String[] strongs = line.substring(pos + 3, closePos).split("%");
                int[] strongNumbers = new int[strongs.length];
                try {
                    for (int i = 0; i < strongs.length; i++) {
                        strongNumbers[i] = Integer.parseInt(strongs[i]);
                    }
                    pos = parseLine(visitor.visitGrammarInformation(strongNumbers, null, null), line, closePos + 1, "<s%>");
                    continue;
                } catch (NumberFormatException ex) {
                // malformed Strongs tag
                }
            }
        } else if (line.startsWith("<XWG", pos) || line.startsWith("<XWH", pos)) {
            int closePos = line.indexOf('>', pos);
            try {
                int number = Integer.parseInt(line.substring(pos + 4, closePos));
                visitor.visitGrammarInformation(new int[] { number }, null, null);
                pos = closePos + 1;
                continue;
            } catch (NumberFormatException ex) {
                System.out.println("WARNING: Invalid Strong number in tag " + line.substring(pos, closePos + 1));
                warningCount++;
            }
        } else if (line.startsWith("<WT", pos)) {
        // TODO parse morph information
        } else if (line.startsWith("<RX", pos)) {
        // TODO parse cross references
        } else if (line.startsWith("<CI>", pos) || line.startsWith("<PF", pos) || line.startsWith("<PI", pos)) {
        // extra formatting not supported by BMC
        } else if (warningCount < 100) {
            System.out.println("WARNING: Skipping unknown tag " + line.substring(pos, Math.min(pos + 20, line.length())));
            warningCount++;
        }
        // the tag is not supported (yet), skip the first character
        visitor.visitText("<");
        pos++;
    }
    if (endTag != null) {
        if (line.startsWith(endTag, pos))
            pos += endTag.length();
        else
            pos = -1;
    }
    return pos;
}
Also used : FormattingInstructionKind(biblemulticonverter.data.FormattedText.FormattingInstructionKind) FormattedText(biblemulticonverter.data.FormattedText)

Example 2 with FormattingInstructionKind

use of biblemulticonverter.data.FormattedText.FormattingInstructionKind in project BibleMultiConverter by schierlm.

the class ZefDic method createXMLBible.

protected Dictionary createXMLBible(Bible bible) throws Exception {
    final ObjectFactory of = new ObjectFactory();
    Dictionary doc = of.createDictionary();
    doc.setDicversion("1");
    doc.setRevision("1");
    doc.setRefbible("any");
    doc.setType(TEnumDicType.X_DICTIONARY);
    String title = null;
    if (bible.getName().matches("X_(DICTIONARY|COMMENTARY|STRONG|DAILY)@.*")) {
        String[] parts = bible.getName().split("@", 2);
        doc.setType(TEnumDicType.valueOf(parts[0]));
        doc.setRefbible(parts[1]);
    } else {
        title = bible.getName();
    }
    doc.setINFORMATION(of.createTINFORMATION());
    doc.getINFORMATION().getTitleOrCreatorOrDescription().add(new JAXBElement<String>(new QName("title"), String.class, title));
    MetadataBook metadata = bible.getMetadataBook();
    if (metadata != null) {
        for (String key : metadata.getKeys()) {
            String value = metadata.getValue(key);
            if (value.equals("-empty-"))
                value = "";
            if (key.equals(MetadataBookKey.version.toString())) {
                doc.setDicversion(value);
            } else if (key.equals(MetadataBookKey.revision.toString())) {
                doc.setRevision(value);
            } else if (Arrays.asList(INFORMATION_KEYS).contains(key)) {
                doc.getINFORMATION().getTitleOrCreatorOrDescription().add(new JAXBElement<String>(new QName(key), String.class, value));
            }
        }
    }
    for (Book bk : bible.getBooks()) {
        if (bk.getId().equals(BookID.METADATA))
            continue;
        if (!bk.getId().equals(BookID.DICTIONARY_ENTRY)) {
            System.out.println("WARNING: Unable to export book " + bk.getAbbr());
            continue;
        }
        final TItem item = of.createTItem();
        if (!bk.getLongName().equals(bk.getShortName())) {
            TItem itm = of.createTItem();
            itm.setId(bk.getShortName());
            appendTextElement(itm, "title", bk.getLongName());
            TParagraph para2 = of.createTParagraph();
            SeeType see = of.createSeeType();
            see.setContent(bk.getLongName());
            para2.getContent().add(new JAXBElement<SeeType>(new QName("see"), SeeType.class, see));
            itm.getContent().add(new JAXBElement<TParagraph>(new QName("description"), TParagraph.class, para2));
            doc.getItem().add(itm);
        }
        item.setId(bk.getLongName());
        doc.getItem().add(item);
        class ZefState {

            TParagraph para = of.createTParagraph();

            boolean eatParagraph = false;

            public void flushPara(TItem item) {
                item.getContent().add(new JAXBElement<TParagraph>(new QName("description"), TParagraph.class, para));
                para = of.createTParagraph();
            }
        }
        final ZefState state = new ZefState();
        FormattedText text = bk.getChapters().get(0).getProlog();
        class LevelVisitor implements Visitor<RuntimeException> {

            final List<Serializable> target;

            private LevelVisitor(ZefState state) {
                target = state.para.getContent();
            }

            private LevelVisitor(MyAnyType parent) {
                target = parent.getContent();
            }

            private LevelVisitor(TStyle parent) {
                target = parent.getContent();
            }

            @Override
            public int visitElementTypes(String elementTypes) throws RuntimeException {
                return 0;
            }

            @Override
            public Visitor<RuntimeException> visitHeadline(int depth) throws RuntimeException {
                System.out.println("WARNING: Nested headlines are not supported");
                return null;
            }

            @Override
            public void visitStart() throws RuntimeException {
            }

            @Override
            public void visitText(String text) throws RuntimeException {
                if (text.length() > 0)
                    target.add(text);
            }

            @Override
            public Visitor<RuntimeException> visitFootnote() throws RuntimeException {
                System.out.println("WARNING: footnotes are not supported");
                return null;
            }

            @Override
            public Visitor<RuntimeException> visitCrossReference(String bookAbbr, BookID book, int firstChapter, String firstVerse, int lastChapter, String lastVerse) throws RuntimeException {
                if (firstChapter != lastChapter || !firstVerse.equals(lastVerse))
                    System.out.println("WARNING: Cross references to verse ranges are not supported");
                BibLinkType b = of.createBibLinkType();
                b.setBn("" + book.getZefID());
                b.setCn1("" + firstChapter);
                b.setVn1(firstVerse);
                target.add(new JAXBElement<BibLinkType>(new QName("bib_link"), BibLinkType.class, b));
                return null;
            }

            @Override
            public Visitor<RuntimeException> visitFormattingInstruction(FormattingInstructionKind kind) throws RuntimeException {
                String tag;
                switch(kind) {
                    case BOLD:
                        tag = "strong";
                        break;
                    case ITALIC:
                        tag = "em";
                        break;
                    case SUPERSCRIPT:
                        tag = "sup";
                        break;
                    case SUBSCRIPT:
                        tag = "sub";
                        break;
                    default:
                        return visitCSSFormatting(kind.getCss());
                }
                MyAnyType mat = of.createMyAnyType();
                target.add(new JAXBElement<MyAnyType>(new QName(tag), MyAnyType.class, mat));
                return new LevelVisitor(mat);
            }

            @Override
            public Visitor<RuntimeException> visitCSSFormatting(String css) throws RuntimeException {
                TStyle style = of.createTStyle();
                style.setCss(css);
                target.add(of.createTStyleSTYLE(style));
                return new LevelVisitor(style);
            }

            @Override
            public void visitVerseSeparator() throws RuntimeException {
                System.out.println("WARNING: Verse separators are not supported");
            }

            @Override
            public void visitLineBreak(LineBreakKind kind) throws RuntimeException {
                System.out.println("WARNING: Nested line breaks are not supported");
            }

            @Override
            public Visitor<RuntimeException> visitGrammarInformation(int[] strongs, String[] rmac, int[] sourceIndices) throws RuntimeException {
                System.out.println("WARNING: Grammar information is not supported");
                return null;
            }

            @Override
            public Visitor<RuntimeException> visitDictionaryEntry(String dictionary, String entry) throws RuntimeException {
                if (dictionary.equals("reflink")) {
                    RefLinkType r = of.createRefLinkType();
                    r.setMscope(entry.substring(1).replace('-', ';'));
                    target.add(new JAXBElement<RefLinkType>(new QName("reflink"), RefLinkType.class, r));
                } else {
                    SeeType see = of.createSeeType();
                    see.setTarget(dictionary.equals("dict") ? "x-self" : dictionary);
                    see.setContent(entry);
                    target.add(new JAXBElement<SeeType>(new QName("see"), SeeType.class, see));
                }
                return null;
            }

            @Override
            public void visitRawHTML(RawHTMLMode mode, String raw) throws RuntimeException {
                System.out.println("WARNING: Raw html output not supported");
            }

            @Override
            public Visitor<RuntimeException> visitVariationText(String[] variations) throws RuntimeException {
                throw new IllegalStateException("Variations not supported");
            }

            @Override
            public Visitor<RuntimeException> visitExtraAttribute(ExtraAttributePriority prio, String category, String key, String value) throws RuntimeException {
                return prio.handleVisitor(category, this);
            }

            @Override
            public boolean visitEnd() throws RuntimeException {
                return false;
            }
        }
        ;
        text.accept(new Visitor<RuntimeException>() {

            @Override
            public int visitElementTypes(String elementTypes) throws RuntimeException {
                return 0;
            }

            @Override
            public Visitor<RuntimeException> visitHeadline(int depth) throws RuntimeException {
                MyAnyType mat = of.createMyAnyType();
                JAXBElement<MyAnyType> elem = new JAXBElement<>(new QName("title"), MyAnyType.class, mat);
                if (depth == 1) {
                    state.flushPara(item);
                    item.getContent().add(elem);
                } else {
                    state.para.getContent().add(elem);
                }
                return new LevelVisitor(mat);
            }

            @Override
            public void visitStart() throws RuntimeException {
            }

            @Override
            public void visitText(String text) throws RuntimeException {
                new LevelVisitor(state).visitText(text);
            }

            @Override
            public Visitor<RuntimeException> visitFootnote() throws RuntimeException {
                System.out.println("WARNING: footnotes are not supported");
                return null;
            }

            @Override
            public Visitor<RuntimeException> visitCrossReference(String bookAbbr, BookID book, int firstChapter, String firstVerse, int lastChapter, String lastVerse) throws RuntimeException {
                return new LevelVisitor(state).visitCrossReference(bookAbbr, book, firstChapter, firstVerse, lastChapter, lastVerse);
            }

            @Override
            public Visitor<RuntimeException> visitFormattingInstruction(FormattingInstructionKind kind) throws RuntimeException {
                return new LevelVisitor(state).visitFormattingInstruction(kind);
            }

            @Override
            public Visitor<RuntimeException> visitCSSFormatting(String css) throws RuntimeException {
                return new LevelVisitor(state).visitCSSFormatting(css);
            }

            @Override
            public void visitVerseSeparator() throws RuntimeException {
                System.out.println("WARNING: Verse separators are not supported");
            }

            @Override
            public void visitLineBreak(LineBreakKind kind) throws RuntimeException {
                if (state.eatParagraph) {
                    state.eatParagraph = false;
                } else {
                    state.flushPara(item);
                    state.para = of.createTParagraph();
                }
            }

            @Override
            public Visitor<RuntimeException> visitGrammarInformation(int[] strongs, String[] rmac, int[] sourceIndices) throws RuntimeException {
                System.out.println("WARNING: Grammar information is not supported");
                return null;
            }

            @Override
            public Visitor<RuntimeException> visitDictionaryEntry(String dictionary, String entry) throws RuntimeException {
                return new LevelVisitor(state).visitDictionaryEntry(dictionary, entry);
            }

            @Override
            public void visitRawHTML(RawHTMLMode mode, String raw) throws RuntimeException {
                System.out.println("WARNING: Raw html output not supported");
            }

            @Override
            public Visitor<RuntimeException> visitVariationText(String[] variations) throws RuntimeException {
                throw new IllegalStateException("Variations not supported");
            }

            @Override
            public Visitor<RuntimeException> visitExtraAttribute(ExtraAttributePriority prio, String category, String key, String value) throws RuntimeException {
                if (prio == ExtraAttributePriority.KEEP_CONTENT && category.equals("zefdic")) {
                    // "zefdic", "field", "pronunciation");
                    return null;
                } else {
                    return prio.handleVisitor(category, this);
                }
            }

            @Override
            public boolean visitEnd() throws RuntimeException {
                return false;
            }
        });
        state.flushPara(item);
    }
    return doc;
}
Also used : Dictionary(biblemulticonverter.schema.zefdic1.Dictionary) TParagraph(biblemulticonverter.schema.zefdic1.TParagraph) ExtraAttributePriority(biblemulticonverter.data.FormattedText.ExtraAttributePriority) Visitor(biblemulticonverter.data.FormattedText.Visitor) TItem(biblemulticonverter.schema.zefdic1.TItem) RawHTMLMode(biblemulticonverter.data.FormattedText.RawHTMLMode) ObjectFactory(biblemulticonverter.schema.zefdic1.ObjectFactory) BookID(biblemulticonverter.data.BookID) MetadataBook(biblemulticonverter.data.MetadataBook) Book(biblemulticonverter.data.Book) List(java.util.List) BibLinkType(biblemulticonverter.schema.zefdic1.BibLinkType) RefLinkType(biblemulticonverter.schema.zefdic1.RefLinkType) MetadataBook(biblemulticonverter.data.MetadataBook) TStyle(biblemulticonverter.schema.zefdic1.TStyle) MyAnyType(biblemulticonverter.schema.zefdic1.MyAnyType) QName(javax.xml.namespace.QName) FormattingInstructionKind(biblemulticonverter.data.FormattedText.FormattingInstructionKind) FormattedText(biblemulticonverter.data.FormattedText) JAXBElement(javax.xml.bind.JAXBElement) LineBreakKind(biblemulticonverter.data.FormattedText.LineBreakKind) SeeType(biblemulticonverter.schema.zefdic1.SeeType)

Example 3 with FormattingInstructionKind

use of biblemulticonverter.data.FormattedText.FormattingInstructionKind in project BibleMultiConverter by schierlm.

the class ZefaniaXMLMyBible method doExport.

@Override
public void doExport(Bible bible, String... exportArgs) throws Exception {
    new StrippedDiffable().mergeIntroductionPrologs(bible);
    final ObjectFactory f = new ObjectFactory();
    XMLBIBLE doc = f.createXMLBIBLE();
    doc.setBiblename(bible.getName());
    doc.setType(EnumModtyp.X_BIBLE);
    BigInteger revision = null;
    MetadataBook metadata = bible.getMetadataBook();
    if (metadata != null) {
        for (MetadataBookKey key : Arrays.asList(MetadataBookKey.revision, MetadataBookKey.version, MetadataBookKey.date, MetadataBookKey.title)) {
            String digits = metadata.getValue(key);
            if (digits == null)
                continue;
            digits = digits.replaceAll("[^0-9]+", "");
            if (!digits.isEmpty()) {
                revision = new BigInteger(digits);
                break;
            }
        }
    }
    if (revision == null) {
        String digits = bible.getName().replaceAll("[^0-9]+", "");
        if (!digits.isEmpty()) {
            revision = new BigInteger(digits);
        }
    }
    if (revision != null) {
        doc.setRevision(revision);
    }
    doc.setINFORMATION(f.createINFORMATION());
    List<DIV> prologs = new ArrayList<DIV>();
    for (Book bk : bible.getBooks()) {
        if (bk.getId().equals(BookID.METADATA))
            continue;
        int bsnumber = bk.getId().getZefID();
        final BIBLEBOOK book = f.createBIBLEBOOK();
        book.setBnumber(BigInteger.valueOf(bsnumber));
        book.setBname(bk.getShortName());
        book.setBsname(bk.getAbbr());
        doc.getBIBLEBOOK().add(book);
        int cnumber = 0;
        for (Chapter cch : bk.getChapters()) {
            cnumber++;
            if (cch.getProlog() != null) {
                DIV xx = f.createDIV();
                prologs.add(xx);
                NOTE xxx = f.createNOTE();
                xx.setNOTE(xxx);
                xxx.setType("x-studynote");
                NOTE prolog = xxx;
                DIV vers = f.createDIV();
                prolog.getContent().add("<p>");
                prolog.getContent().add(vers);
                prolog.getContent().add("</p>");
                vers.setNOTE(f.createNOTE());
                final List<List<Object>> targetStack = new ArrayList<List<Object>>();
                targetStack.add(vers.getNOTE().getContent());
                cch.getProlog().accept(new Visitor<IOException>() {

                    @Override
                    public Visitor<IOException> visitHeadline(int depth) throws IOException {
                        if (depth > 6)
                            depth = 6;
                        STYLE s = f.createSTYLE();
                        s.setCss("-zef-dummy: true");
                        targetStack.get(0).add("<h" + depth + ">");
                        targetStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, s));
                        targetStack.get(0).add("</h" + depth + ">");
                        targetStack.add(0, s.getContent());
                        return this;
                    }

                    @Override
                    public void visitVerseSeparator() throws IOException {
                        STYLE x = f.createSTYLE();
                        x.setCss("color:gray");
                        x.getContent().add("/");
                        targetStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, x));
                    }

                    @Override
                    public void visitText(String text) throws IOException {
                        targetStack.get(0).add(text);
                    }

                    @Override
                    public Visitor<IOException> visitFormattingInstruction(FormattedText.FormattingInstructionKind kind) throws IOException {
                        String startTag, endTag;
                        if (kind.getHtmlTag() != null) {
                            startTag = "<" + kind.getHtmlTag() + ">";
                            endTag = "</" + kind.getHtmlTag() + ">";
                        } else {
                            startTag = "<span style=\"" + kind.getCss() + "\">";
                            endTag = "</span>";
                        }
                        STYLE s = f.createSTYLE();
                        s.setCss("-zef-dummy: true");
                        targetStack.get(0).add(startTag);
                        targetStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, s));
                        targetStack.get(0).add(endTag);
                        targetStack.add(0, s.getContent());
                        return this;
                    }

                    @Override
                    public Visitor<IOException> visitFootnote() throws IOException {
                        System.out.println("WARNING: Footnotes in prolog are not supported");
                        return null;
                    }

                    @Override
                    public Visitor<IOException> visitCrossReference(String bookAbbr, BookID book, int firstChapter, String firstVerse, int lastChapter, String lastVerse) throws IOException {
                        System.out.println("WARNING: Cross references in prologs are not supported");
                        STYLE s = f.createSTYLE();
                        s.setCss("-zef-dummy: true");
                        targetStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, s));
                        targetStack.add(0, s.getContent());
                        return this;
                    }

                    @Override
                    public Visitor<IOException> visitVariationText(String[] variations) throws IOException {
                        throw new RuntimeException("Variations not supported");
                    }

                    @Override
                    public void visitLineBreak(LineBreakKind kind) throws IOException {
                        BR br = f.createBR();
                        br.setArt(kind == LineBreakKind.PARAGRAPH ? EnumBreak.X_P : EnumBreak.X_NL);
                        targetStack.get(0).add(" ");
                        targetStack.get(0).add(kind == LineBreakKind.PARAGRAPH ? "<p>" : "<br>");
                        targetStack.get(0).add(br);
                    }

                    @Override
                    public Visitor<IOException> visitGrammarInformation(int[] strongs, String[] rmac, int[] sourceIndices) throws IOException {
                        throw new RuntimeException("Grammar tags in prologs not supported");
                    }

                    @Override
                    public FormattedText.Visitor<IOException> visitDictionaryEntry(String dictionary, String entry) throws IOException {
                        throw new RuntimeException("Dictionary entries in prologs not supported");
                    }

                    @Override
                    public void visitRawHTML(RawHTMLMode mode, String raw) throws IOException {
                        throw new RuntimeException("Raw HTML in prologs not supported");
                    }

                    @Override
                    public Visitor<IOException> visitCSSFormatting(String css) throws IOException {
                        STYLE s = f.createSTYLE();
                        s.setCss("-zef-dummy: true");
                        targetStack.get(0).add("<span style=\"" + css + "\">");
                        targetStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, s));
                        targetStack.get(0).add("</span>");
                        targetStack.add(0, s.getContent());
                        return this;
                    }

                    @Override
                    public int visitElementTypes(String elementTypes) throws IOException {
                        return 0;
                    }

                    @Override
                    public Visitor<IOException> visitExtraAttribute(ExtraAttributePriority prio, String category, String key, String value) throws IOException {
                        if (prio == ExtraAttributePriority.KEEP_CONTENT)
                            return visitCSSFormatting("-zef-extra-attribute-" + category + "-" + key + ": " + value);
                        else if (prio == ExtraAttributePriority.SKIP)
                            return null;
                        throw new RuntimeException("Extra attributes not supported");
                    }

                    @Override
                    public void visitStart() throws IOException {
                    }

                    @Override
                    public boolean visitEnd() throws IOException {
                        targetStack.remove(0);
                        return false;
                    }
                });
                if (targetStack.size() != 0)
                    throw new RuntimeException();
            }
            if (cch.getVerses().size() == 0)
                continue;
            CHAPTER chapter = f.createCHAPTER();
            chapter.setCnumber(BigInteger.valueOf(cnumber));
            book.getCHAPTER().add(chapter);
            for (VirtualVerse vv : cch.createVirtualVerses()) {
                for (Headline h : vv.getHeadlines()) {
                    CAPTION caption = f.createCAPTION();
                    EnumCaptionType[] types = new EnumCaptionType[] { null, EnumCaptionType.X_H_1, EnumCaptionType.X_H_2, EnumCaptionType.X_H_3, EnumCaptionType.X_H_4, EnumCaptionType.X_H_5, EnumCaptionType.X_H_6, EnumCaptionType.X_H_6, EnumCaptionType.X_H_6, EnumCaptionType.X_H_6 };
                    caption.setType(types[h.getDepth()]);
                    caption.setVref(BigInteger.valueOf(vv.getNumber()));
                    final StringBuilder sb = new StringBuilder();
                    h.accept(new FormattedText.VisitorAdapter<RuntimeException>(null) {

                        @Override
                        protected void beforeVisit() throws RuntimeException {
                            throw new IllegalStateException();
                        }

                        @Override
                        public Visitor<RuntimeException> visitFormattingInstruction(FormattingInstructionKind kind) throws RuntimeException {
                            System.out.println("WARNING: Formatting instructions in captions are not supported (stripped)");
                            return this;
                        }

                        @Override
                        public Visitor<RuntimeException> visitFootnote() throws RuntimeException {
                            System.out.println("WARNING: Footnotes in captions are not supported (stripped)");
                            return null;
                        }

                        @Override
                        public Visitor<RuntimeException> visitCSSFormatting(String css) throws RuntimeException {
                            System.out.println("WARNING: CSS Formatting in captions are not supported (stripped)");
                            return this;
                        }

                        @Override
                        public Visitor<RuntimeException> visitExtraAttribute(ExtraAttributePriority prio, String category, String key, String value) throws RuntimeException {
                            return prio.handleVisitor(category, this);
                        }

                        public void visitText(String text) throws RuntimeException {
                            sb.append(text);
                        }
                    });
                    caption.getContent().add(sb.toString());
                    chapter.getPROLOGOrCAPTIONOrVERS().add(caption);
                }
                VERS vers = f.createVERS();
                vers.setVnumber(BigInteger.valueOf(vv.getNumber()));
                for (DIV prolog : prologs) {
                    vers.getContent().add(prolog);
                }
                prologs.clear();
                chapter.getPROLOGOrCAPTIONOrVERS().add(vers);
                boolean first = true;
                for (Verse v : vv.getVerses()) {
                    if (!first || !v.getNumber().equals("" + vv.getNumber())) {
                        STYLE x = f.createSTYLE();
                        x.setCss("font-weight: bold");
                        x.getContent().add("(" + v.getNumber() + ")");
                        vers.getContent().add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, x));
                        vers.getContent().add(" ");
                    }
                    first = false;
                    final List<List<Object>> targetStack = new ArrayList<List<Object>>();
                    targetStack.add(vers.getContent());
                    v.accept(new FormattedText.Visitor<IOException>() {

                        @Override
                        public void visitVerseSeparator() throws IOException {
                            STYLE x = f.createSTYLE();
                            x.setCss("color:gray");
                            x.getContent().add("/");
                            targetStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, x));
                        }

                        @Override
                        public void visitText(String text) throws IOException {
                            targetStack.get(0).add(text);
                        }

                        @Override
                        public FormattedText.Visitor<IOException> visitFormattingInstruction(biblemulticonverter.data.FormattedText.FormattingInstructionKind kind) throws IOException {
                            STYLE x = f.createSTYLE();
                            x.setCss(kind.getCss());
                            targetStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, x));
                            targetStack.add(0, x.getContent());
                            return this;
                        }

                        @Override
                        public Visitor<IOException> visitFootnote() throws IOException {
                            DIV x = f.createDIV();
                            targetStack.get(0).add(x);
                            NOTE n = f.createNOTE();
                            x.setNOTE(n);
                            n.setType("x-studynote");
                            final List<List<Object>> footnoteStack = new ArrayList<List<Object>>();
                            footnoteStack.add(n.getContent());
                            return new Visitor<IOException>() {

                                @Override
                                public void visitStart() throws IOException {
                                }

                                @Override
                                public void visitVerseSeparator() throws IOException {
                                    STYLE x = f.createSTYLE();
                                    x.setCss("color:gray");
                                    x.getContent().add("/");
                                    footnoteStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, x));
                                }

                                @Override
                                public void visitText(String text) throws IOException {
                                    footnoteStack.get(0).add(text);
                                }

                                @Override
                                public void visitLineBreak(LineBreakKind kind) throws IOException {
                                    BR br = f.createBR();
                                    br.setArt(kind == LineBreakKind.PARAGRAPH ? EnumBreak.X_P : EnumBreak.X_NL);
                                    footnoteStack.get(0).add(" ");
                                    footnoteStack.get(0).add(br);
                                }

                                @Override
                                public Visitor<IOException> visitFormattingInstruction(FormattedText.FormattingInstructionKind kind) throws IOException {
                                    String startTag, endTag;
                                    if (kind.getHtmlTag() != null) {
                                        startTag = "<" + kind.getHtmlTag() + ">";
                                        endTag = "</" + kind.getHtmlTag() + ">";
                                    } else {
                                        startTag = "<span style=\"" + kind.getCss() + "\">";
                                        endTag = "</span>";
                                    }
                                    STYLE s = f.createSTYLE();
                                    s.setCss("-zef-dummy: true");
                                    footnoteStack.get(0).add(startTag);
                                    footnoteStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, s));
                                    footnoteStack.get(0).add(endTag);
                                    footnoteStack.add(0, s.getContent());
                                    return this;
                                }

                                @Override
                                public Visitor<IOException> visitFootnote() throws IOException {
                                    throw new RuntimeException("Footnotes in footnotes are not supported");
                                }

                                @Override
                                public Visitor<IOException> visitGrammarInformation(int[] strongs, String[] rmac, int[] sourceIndices) throws IOException {
                                    GRAM gram = f.createGRAM();
                                    if (strongs != null) {
                                        StringBuilder entryBuilder = new StringBuilder();
                                        for (int i = 0; i < strongs.length; i++) {
                                            entryBuilder.append((i > 0 ? " " : "") + strongs[i]);
                                        }
                                        String entry = entryBuilder.toString();
                                        gram.setStr(entry);
                                    }
                                    if (rmac != null) {
                                        StringBuilder entryBuilder = new StringBuilder();
                                        for (int i = 0; i < rmac.length; i++) {
                                            if (i > 0)
                                                entryBuilder.append(' ');
                                            entryBuilder.append(rmac[i]);
                                        }
                                        gram.setRmac(entryBuilder.toString());
                                    }
                                    footnoteStack.get(0).add(new JAXBElement<GRAM>(new QName("gr"), GRAM.class, gram));
                                    footnoteStack.add(0, gram.getContent());
                                    return this;
                                }

                                @Override
                                public FormattedText.Visitor<IOException> visitDictionaryEntry(String dictionary, String entry) throws IOException {
                                    GRAM gram = f.createGRAM();
                                    gram.setStr(entry);
                                    footnoteStack.get(0).add(new JAXBElement<GRAM>(new QName("gr"), GRAM.class, gram));
                                    footnoteStack.add(0, gram.getContent());
                                    return this;
                                }

                                @Override
                                public void visitRawHTML(RawHTMLMode mode, String raw) throws IOException {
                                    if (mode != RawHTMLMode.ONLINE)
                                        footnoteStack.get(0).add(raw);
                                }

                                @Override
                                public Visitor<IOException> visitVariationText(String[] variations) throws IOException {
                                    throw new RuntimeException("Variations not supported");
                                }

                                @Override
                                public FormattedText.Visitor<IOException> visitCrossReference(String bookAbbr, BookID book, int firstChapter, String firstVerse, int lastChapter, String lastVerse) throws IOException {
                                    STYLE s = f.createSTYLE();
                                    s.setCss("-zef-dummy: true");
                                    int bookID = book.getZefID();
                                    String mscope, xmscope;
                                    try {
                                        int start = firstVerse.equals("^") ? 1 : Integer.parseInt(firstVerse.replaceAll("[a-zG]|[,/][0-9]*", ""));
                                        int end;
                                        if (firstChapter == lastChapter && !lastVerse.equals("$")) {
                                            end = Integer.parseInt(lastVerse.replaceAll("[a-z]|[,/][0-9]*", ""));
                                        } else {
                                            end = -1;
                                        }
                                        mscope = bookID + "," + firstChapter + "," + start + "," + end;
                                        xmscope = bookID + ";" + firstChapter + ";" + start + "-" + end;
                                    } catch (NumberFormatException ex) {
                                        ex.printStackTrace();
                                        mscope = bookID + ",1,1,999";
                                        xmscope = bookID + ";1;1-999";
                                    }
                                    if (footnoteStack.size() == 1) {
                                        List<Object> outerList = targetStack.get(0);
                                        XREF xref = new XREF();
                                        xref.setMscope(xmscope);
                                        outerList.add(outerList.size() - 1, xref);
                                    }
                                    footnoteStack.get(0).add("<a href=\"mybible:content=location&amp;locations=" + mscope + "\">");
                                    footnoteStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, s));
                                    footnoteStack.get(0).add("</a>");
                                    footnoteStack.add(0, s.getContent());
                                    return this;
                                }

                                public boolean visitEnd() throws IOException {
                                    footnoteStack.remove(0);
                                    return false;
                                }

                                @Override
                                public int visitElementTypes(String elementTypes) throws IOException {
                                    return 0;
                                }

                                @Override
                                public Visitor<IOException> visitHeadline(int depth) throws IOException {
                                    throw new RuntimeException("Headlines in footnotes not supported");
                                }

                                @Override
                                public Visitor<IOException> visitCSSFormatting(String css) throws IOException {
                                    STYLE s = f.createSTYLE();
                                    s.setCss("-zef-dummy: true");
                                    footnoteStack.get(0).add("<span style=\"" + css + "\">");
                                    footnoteStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, s));
                                    footnoteStack.get(0).add("</span>");
                                    footnoteStack.add(s.getContent());
                                    return this;
                                }

                                @Override
                                public Visitor<IOException> visitExtraAttribute(ExtraAttributePriority prio, String category, String key, String value) throws IOException {
                                    System.out.println("WARNING: Extra attributes not supported");
                                    Visitor<IOException> result = prio.handleVisitor(category, this);
                                    if (result != null)
                                        footnoteStack.add(0, footnoteStack.get(0));
                                    return result;
                                }
                            };
                        }

                        @Override
                        public FormattedText.Visitor<IOException> visitCrossReference(String bookAbbr, BookID book, int firstChapter, String firstVerse, int lastChapter, String lastVerse) throws IOException {
                            throw new RuntimeException("Xref outside of footnotes not supported!");
                        }

                        @Override
                        public void visitLineBreak(LineBreakKind kind) throws IOException {
                            BR br = f.createBR();
                            br.setArt(kind == LineBreakKind.PARAGRAPH ? EnumBreak.X_P : EnumBreak.X_NL);
                            targetStack.get(0).add(" ");
                            targetStack.get(0).add(br);
                        }

                        @Override
                        public Visitor<IOException> visitGrammarInformation(int[] strongs, String[] rmac, int[] sourceIndices) throws IOException {
                            GRAM gram = f.createGRAM();
                            if (strongs != null) {
                                StringBuilder entryBuilder = new StringBuilder();
                                for (int i = 0; i < strongs.length; i++) {
                                    entryBuilder.append((i > 0 ? " " : "") + strongs[i]);
                                }
                                String entry = entryBuilder.toString();
                                gram.setStr(entry);
                            }
                            if (rmac != null) {
                                StringBuilder entryBuilder = new StringBuilder();
                                for (int i = 0; i < rmac.length; i++) {
                                    if (i > 0)
                                        entryBuilder.append(' ');
                                    entryBuilder.append(rmac[i]);
                                }
                                gram.setRmac(entryBuilder.toString());
                            }
                            targetStack.get(0).add(new JAXBElement<GRAM>(new QName("gr"), GRAM.class, gram));
                            targetStack.add(0, gram.getContent());
                            return this;
                        }

                        @Override
                        public FormattedText.Visitor<IOException> visitDictionaryEntry(String dictionary, String entry) throws IOException {
                            GRAM gram = f.createGRAM();
                            gram.setStr(entry);
                            targetStack.get(0).add(new JAXBElement<GRAM>(new QName("gr"), GRAM.class, gram));
                            targetStack.add(0, gram.getContent());
                            return this;
                        }

                        @Override
                        public void visitRawHTML(RawHTMLMode mode, String raw) throws IOException {
                            throw new RuntimeException("Raw HTML is not supported");
                        }

                        @Override
                        public Visitor<IOException> visitVariationText(String[] variations) throws IOException {
                            throw new RuntimeException("Variations not supported");
                        }

                        @Override
                        public boolean visitEnd() throws IOException {
                            targetStack.remove(0);
                            return false;
                        }

                        @Override
                        public int visitElementTypes(String elementTypes) throws IOException {
                            return 0;
                        }

                        @Override
                        public Visitor<IOException> visitHeadline(int depth) throws IOException {
                            throw new RuntimeException("Headline in virtual verse is impossible");
                        }

                        @Override
                        public void visitStart() throws IOException {
                        }

                        @Override
                        public Visitor<IOException> visitCSSFormatting(String css) throws IOException {
                            STYLE x = f.createSTYLE();
                            x.setCss(css);
                            targetStack.get(0).add(new JAXBElement<STYLE>(new QName("STYLE"), STYLE.class, x));
                            targetStack.add(0, x.getContent());
                            return this;
                        }

                        @Override
                        public Visitor<IOException> visitExtraAttribute(ExtraAttributePriority prio, String category, String key, String value) throws IOException {
                            System.out.println("WARNING: Extra attributes not supported");
                            Visitor<IOException> result = prio.handleVisitor(category, this);
                            if (result != null)
                                targetStack.add(0, targetStack.get(0));
                            return result;
                        }
                    });
                    if (targetStack.size() != 0)
                        throw new RuntimeException();
                }
            }
        }
        if (book.getCHAPTER().size() == 0) {
            doc.getBIBLEBOOK().remove(book);
        }
    }
    final Document docc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
    JAXBContext.newInstance(ObjectFactory.class.getPackage().getName()).createMarshaller().marshal(doc, docc);
    docc.getDocumentElement().setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    docc.getDocumentElement().setAttribute("xsi:noNamespaceSchemaLocation", "zef2005.xsd");
    docc.normalize();
    maskWhitespaceNodes(docc.getDocumentElement());
    try (FileOutputStream fos = new FileOutputStream(exportArgs[0])) {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
        transformer.transform(new DOMSource(docc), new StreamResult(fos));
    }
}
Also used : DOMSource(javax.xml.transform.dom.DOMSource) VirtualVerse(biblemulticonverter.data.VirtualVerse) ArrayList(java.util.ArrayList) RawHTMLMode(biblemulticonverter.data.FormattedText.RawHTMLMode) Document(org.w3c.dom.Document) ObjectFactory(biblemulticonverter.schema.zef2005.ObjectFactory) BookID(biblemulticonverter.data.BookID) Book(biblemulticonverter.data.Book) MetadataBook(biblemulticonverter.data.MetadataBook) Headline(biblemulticonverter.data.FormattedText.Headline) VERS(biblemulticonverter.schema.zef2005.VERS) List(java.util.List) ArrayList(java.util.ArrayList) MetadataBook(biblemulticonverter.data.MetadataBook) StreamResult(javax.xml.transform.stream.StreamResult) STYLE(biblemulticonverter.schema.zef2005.STYLE) JAXBElement(javax.xml.bind.JAXBElement) FormattedText(biblemulticonverter.data.FormattedText) BIBLEBOOK(biblemulticonverter.schema.zef2005.BIBLEBOOK) LineBreakKind(biblemulticonverter.data.FormattedText.LineBreakKind) XREF(biblemulticonverter.schema.zef2005.XREF) FileOutputStream(java.io.FileOutputStream) BigInteger(java.math.BigInteger) FormattingInstructionKind(biblemulticonverter.data.FormattedText.FormattingInstructionKind) ExtraAttributePriority(biblemulticonverter.data.FormattedText.ExtraAttributePriority) Transformer(javax.xml.transform.Transformer) Visitor(biblemulticonverter.data.FormattedText.Visitor) BR(biblemulticonverter.schema.zef2005.BR) NOTE(biblemulticonverter.schema.zef2005.NOTE) MetadataBookKey(biblemulticonverter.data.MetadataBook.MetadataBookKey) FormattingInstructionKind(biblemulticonverter.data.FormattedText.FormattingInstructionKind) XMLBIBLE(biblemulticonverter.schema.zef2005.XMLBIBLE) QName(javax.xml.namespace.QName) Chapter(biblemulticonverter.data.Chapter) FormattingInstructionKind(biblemulticonverter.data.FormattedText.FormattingInstructionKind) IOException(java.io.IOException) DIV(biblemulticonverter.schema.zef2005.DIV) EnumCaptionType(biblemulticonverter.schema.zef2005.EnumCaptionType) CHAPTER(biblemulticonverter.schema.zef2005.CHAPTER) GRAM(biblemulticonverter.schema.zef2005.GRAM) CAPTION(biblemulticonverter.schema.zef2005.CAPTION) VirtualVerse(biblemulticonverter.data.VirtualVerse) Verse(biblemulticonverter.data.Verse)

Example 4 with FormattingInstructionKind

use of biblemulticonverter.data.FormattedText.FormattingInstructionKind in project BibleMultiConverter by schierlm.

the class OSIS method parseStructuredTextElement.

private void parseStructuredTextElement(Visitor<RuntimeException> vv, Element elem) {
    if (elem.getNodeName().equals("lb")) {
        vv.visitLineBreak(LineBreakKind.NEWLINE);
    } else if (elem.getNodeName().equals("brp")) {
        vv.visitLineBreak(LineBreakKind.PARAGRAPH);
    } else if (elem.getNodeName().equals("divineName")) {
        parseStructuredTextChildren(vv.visitFormattingInstruction(FormattingInstructionKind.DIVINE_NAME), elem);
    } else if (elem.getNodeName().equals("woj")) {
        parseStructuredTextChildren(vv.visitFormattingInstruction(FormattingInstructionKind.WORDS_OF_JESUS), elem);
    } else if (elem.getNodeName().equals("catchWord")) {
        parseStructuredTextChildren(vv.visitCSSFormatting("osis-style: catchWord; font-style:italic;"), elem);
    } else if (elem.getNodeName().equals("hi")) {
        FormattingInstructionKind kind;
        if (elem.getAttribute("type").equals("italic")) {
            kind = FormattingInstructionKind.ITALIC;
        } else if (elem.getAttribute("type").equals("bold")) {
            kind = FormattingInstructionKind.BOLD;
        } else {
            kind = null;
            printWarning("WARNING: Invalid hi type: " + elem.getAttribute("type"));
        }
        if (elem.getChildNodes().getLength() != 0) {
            Visitor<RuntimeException> vv1 = kind == null ? vv : vv.visitFormattingInstruction(kind);
            parseStructuredTextChildren(vv1, elem);
        }
    } else if (elem.getNodeName().equals("seg") || elem.getNodeName().equals("transChange") || elem.getNodeName().equals("rdg")) {
        String css;
        if (elem.getNodeName().equals("seg") && elem.getAttribute("type").equals("x-alternative")) {
            css = "osis-style: alternative; color: gray;";
        } else if (elem.getNodeName().equals("transChange") && elem.getAttribute("type").equals("added")) {
            css = "osis-style: added; font-style:italic;";
        } else if (elem.getNodeName().equals("transChange") && elem.getAttribute("type").equals("deleted")) {
            css = "osis-style: deleted; text-decoration: line-through; color: gray;";
        } else if (elem.getNodeName().equals("transChange") && elem.getAttribute("type").equals("amplified")) {
            css = "osis-style: amplified; font-style: italic;";
        } else if (elem.getNodeName().equals("transChange") && elem.getAttribute("type").isEmpty()) {
            css = "osis-style: trans-change;";
        } else if (elem.getNodeName().equals("rdg") && elem.getAttribute("type").equals("alternative")) {
            css = "osis-style: alternative-reading; color: gray;";
        } else if (elem.getNodeName().equals("rdg") && elem.getAttribute("type").equals("x-literal")) {
            css = "osis-style: literal-reading; color: gray;";
        } else if (elem.getNodeName().equals("rdg") && elem.getAttribute("type").equals("x-meaning")) {
            css = "osis-style: meaning-reading; color: gray;";
        } else if (elem.getNodeName().equals("rdg") && elem.getAttribute("type").equals("x-equivalent")) {
            css = "osis-style: equivalent-reading; color: gray;";
        } else if (elem.getNodeName().equals("rdg") && elem.getAttribute("type").equals("x-identity")) {
            css = "osis-style: identity-reading; color: gray;";
        } else if (elem.getNodeName().equals("rdg") && elem.getAttribute("type").isEmpty()) {
            css = "osis-style: reading; color: gray;";
        } else {
            css = null;
            printWarning("WARNING: Invalid " + elem.getNodeName() + " type: " + elem.getAttribute("type"));
        }
        if (elem.getChildNodes().getLength() != 0) {
            Visitor<RuntimeException> vv1 = css == null ? vv : vv.visitCSSFormatting(css);
            parseStructuredTextChildren(vv1, elem);
        }
    } else if (elem.getNodeName().equals("note")) {
        if (elem.getAttribute("type").equals("crossReference")) {
            Visitor<RuntimeException> fn = vv.visitFootnote();
            fn.visitText(FormattedText.XREF_MARKER);
            if (elem.getFirstChild() != null && elem.getFirstChild().getNodeName().equals("reference")) {
                for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
                    if (n instanceof Text) {
                        fn.visitText(n.getTextContent());
                        continue;
                    }
                    Element e = (Element) n;
                    String[] ref = e.getAttribute("osisRef").split("\\.");
                    if (ref.length != 3) {
                        printWarning("WARNING: Invalid reference target: " + e.getAttribute("osisRef"));
                        fn.visitText(e.getTextContent());
                        continue;
                    }
                    BookID bookID = BookID.fromOsisId(ref[0]);
                    int ch = Integer.parseInt(ref[1]);
                    String vs = ref[2];
                    fn.visitCrossReference(ref[0], bookID, ch, vs, ch, vs).visitText(e.getTextContent());
                }
            } else if (elem.getTextContent().length() > 0) {
                // OSIS converted from USFM contains a reference back to the verse itself
                for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
                    if (n instanceof Element && n.getNodeName().equals("reference")) {
                        if (((Element) n).getAttribute("osisRef").equals(((Element) elem).getAttribute("osisRef"))) {
                            n = n.getPreviousSibling();
                            n.getParentNode().removeChild(n.getNextSibling());
                        }
                    }
                }
                boolean first = true;
                for (String ref : elem.getTextContent().split("\\|")) {
                    Matcher m = XREF_PATTERN.matcher(ref);
                    if (!m.matches()) {
                        ref = ref.trim();
                        if (ref.startsWith("1 ") || ref.startsWith("2 ") || ref.startsWith("3 ")) {
                            ref = ref.substring(0, 1) + ref.substring(2);
                        }
                        m = XREF_PATTERN_2.matcher(ref);
                        if (m.matches()) {
                            try {
                                BookID.fromOsisId(m.group(1));
                            } catch (IllegalArgumentException ex) {
                                BookID bk = null;
                                for (BookID id : BookID.values()) {
                                    if (id.getThreeLetterCode().equalsIgnoreCase(m.group(1)))
                                        bk = id;
                                }
                                if (bk != null) {
                                    m = XREF_PATTERN_2.matcher(bk.getOsisID() + " " + m.group(2) + "." + m.group(3));
                                } else {
                                    m = XREF_PATTERN_2.matcher("");
                                }
                            }
                        }
                    }
                    if (!first)
                        fn.visitText("; ");
                    first = false;
                    if (m.matches()) {
                        String book = m.group(1);
                        BookID bookID = BookID.fromOsisId(book);
                        int ch = Integer.parseInt(m.group(2));
                        String vs = m.group(3);
                        fn.visitCrossReference(book, bookID, ch, vs, ch, vs).visitText(ref);
                    } else {
                        printWarning("WARNING: Malformed cross reference: " + ref);
                        fn.visitText(ref.replaceAll("[\r\n\t ]+", " ").trim());
                    }
                }
            } else {
                printWarning("WARNING: crossReference without content");
                fn.visitText("-");
            }
        } else if (elem.getFirstChild() != null) {
            Visitor<RuntimeException> v = vv.visitFootnote();
            parseStructuredTextChildren(v, elem);
        }
    } else if (elem.getNodeName().equals("w")) {
        if (elem.getFirstChild() == null)
            // skip empty w tags
            return;
        String src = elem.getAttribute("src");
        Visitor<RuntimeException> v = vv;
        int[] strong = null, idx = null;
        List<Integer> strongList = new ArrayList<Integer>();
        for (String lemma : elem.getAttribute("lemma").trim().split(" +")) {
            if (!lemma.startsWith("strong:G") && !lemma.startsWith("strong:H"))
                continue;
            String rawStrong = lemma.substring(8);
            if (!rawStrong.matches("0*[1-9][0-9]*(-0*[1-9][0-9]*)*")) {
                printWarning("WARNING: Invalid strong dictionary entry: " + rawStrong);
                continue;
            }
            String[] strs = rawStrong.split("-");
            for (String str : strs) {
                strongList.add(Integer.parseInt(str));
            }
        }
        if (!strongList.isEmpty())
            strong = strongList.stream().mapToInt(s -> s).toArray();
        List<String> rmac = new ArrayList<>();
        for (String morph : elem.getAttribute("morph").trim().split(" +")) {
            if (morph.startsWith("robinson:")) {
                String rmacCandidate = morph.substring(9);
                if (Utils.compilePattern(Utils.RMAC_REGEX).matcher(rmacCandidate).matches()) {
                    rmac.add(rmacCandidate);
                } else {
                    printWarning("WARNING: Invalid RMAC: " + rmacCandidate);
                }
            }
        }
        if (src.matches("[0-9]{2}( [0-9]{2})*")) {
            String[] strs = src.split(" ");
            idx = new int[strs.length];
            for (int i = 0; i < strs.length; i++) {
                idx[i] = Integer.parseInt(strs[i]);
            }
        }
        if (strong == null && rmac.isEmpty() && idx == null) {
            printWarning("INFO: Skipped <w> tag without any usable information");
        } else {
            v = v.visitGrammarInformation(strong, rmac.isEmpty() ? null : rmac.toArray(new String[rmac.size()]), idx);
        }
        parseStructuredTextChildren(v, elem);
    } else if (elem.getNodeName().equals("reference")) {
        String osisRef = elem.getAttribute("osisRef");
        if (osisRef.contains("\u00A0")) {
            printWarning("WARNING: osisRef contains Non-Breaking spaces: '" + osisRef + "'");
            osisRef = osisRef.replace('\u00A0', ' ');
        }
        if (!osisRef.equals(osisRef.trim())) {
            printWarning("WARNING: Removed whitespace from osisRef '" + osisRef + "' - replaced by '" + osisRef.trim() + "'");
            osisRef = osisRef.trim();
        }
        Matcher fixupMatcher = Utils.compilePattern("([A-Z0-9][A-Z0-9a-z]+\\.[0-9]+\\.)([0-9]+)((?:[+-][0-9]+)+)").matcher(osisRef);
        if (fixupMatcher.matches()) {
            osisRef = fixupMatcher.group(1) + fixupMatcher.group(2);
            for (String suffix : fixupMatcher.group(3).split("(?=[+-])")) {
                if (suffix.isEmpty())
                    continue;
                osisRef += suffix.substring(0, 1).replace('+', ' ') + fixupMatcher.group(1) + suffix.substring(1);
            }
            printWarning("INFO: Replaced osisRef " + elem.getAttribute("osisRef") + " by " + osisRef);
        }
        if (osisRefMap == null) {
            osisRefMap = new Properties();
            String path = System.getProperty("biblemulticonverter.osisrefmap", "");
            if (!path.isEmpty()) {
                try (FileInputStream fis = new FileInputStream(path)) {
                    osisRefMap.load(fis);
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
        String mappedOsisRef = osisRefMap.getProperty(osisRef);
        if (mappedOsisRef != null) {
            printWarning("INFO: Replaced osisRef " + osisRef + " by " + mappedOsisRef + " (based on osisRef map)");
            osisRef = mappedOsisRef;
        }
        if (osisRef.matches("[^ ]+ [^ ]+") && elem.getFirstChild() instanceof Text && elem.getFirstChild().getNextSibling() == null) {
            String value = elem.getTextContent();
            int lastPos = value.lastIndexOf('.');
            if (lastPos != -1) {
                Element newElem = elem.getOwnerDocument().createElement("reference");
                newElem.setAttribute("osisRef", osisRef.split(" ")[0]);
                newElem.appendChild(elem.getOwnerDocument().createTextNode(value.substring(0, lastPos)));
                parseStructuredTextElement(vv, newElem);
                vv.visitText(".");
                newElem = elem.getOwnerDocument().createElement("reference");
                newElem.setAttribute("osisRef", osisRef.split(" ")[1]);
                newElem.appendChild(elem.getOwnerDocument().createTextNode(value.substring(lastPos + 1)));
                parseStructuredTextElement(vv, newElem);
                return;
            }
        }
        Visitor<RuntimeException> v = vv;
        if (osisRef.matches("[A-Z0-9][A-Z0-9a-z]+\\.[0-9]+\\.[0-9]+")) {
            String[] osisRefParts = osisRef.split("\\.");
            int chapter = Integer.parseInt(osisRefParts[1]);
            try {
                v = v.visitCrossReference(osisRefParts[0], BookID.fromOsisId(osisRefParts[0]), chapter, osisRefParts[2], chapter, osisRefParts[2]);
            } catch (IllegalArgumentException ex) {
                printWarning("WARNING: " + ex.getMessage());
            }
        } else if (osisRef.matches("([A-Z0-9][A-Z0-9a-z]+)\\.[0-9]+\\.[0-9]+-\\1\\.[0-9]+\\.[0-9]+")) {
            String[] osisRefParts = osisRef.split("[.-]");
            int firstChapter = Integer.parseInt(osisRefParts[1]);
            int lastChapter = Integer.parseInt(osisRefParts[4]);
            try {
                v = v.visitCrossReference(osisRefParts[0], BookID.fromOsisId(osisRefParts[0]), firstChapter, osisRefParts[2], lastChapter, osisRefParts[5]);
            } catch (IllegalArgumentException ex) {
                printWarning("WARNING: " + ex.getMessage());
            }
        } else {
            printWarning("WARNING: Unsupported osisRef: " + osisRef);
        }
        parseStructuredTextChildren(v, elem);
    } else if (elem.getNodeName().equals("variation")) {
        parseStructuredTextChildren(vv.visitVariationText(new String[] { elem.getAttribute("name") }), elem);
    } else {
        printWarning("WARNING: invalid structured element level tag: " + elem.getNodeName());
    }
}
Also used : ObjectFactory(biblemulticonverter.schema.roundtripxml.ObjectFactory) DOMSource(javax.xml.transform.dom.DOMSource) Text(org.w3c.dom.Text) LineBreakKind(biblemulticonverter.data.FormattedText.LineBreakKind) Arrays(java.util.Arrays) XPath(javax.xml.xpath.XPath) XPathConstants(javax.xml.xpath.XPathConstants) StreamResult(javax.xml.transform.stream.StreamResult) Bible(biblemulticonverter.data.Bible) MetadataBook(biblemulticonverter.data.MetadataBook) MetadataBookKey(biblemulticonverter.data.MetadataBook.MetadataBookKey) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) FormattedText(biblemulticonverter.data.FormattedText) Matcher(java.util.regex.Matcher) ValidateXML(biblemulticonverter.tools.ValidateXML) Document(org.w3c.dom.Document) Node(org.w3c.dom.Node) Utils(biblemulticonverter.data.Utils) XMLConstants(javax.xml.XMLConstants) Book(biblemulticonverter.data.Book) VirtualVerse(biblemulticonverter.data.VirtualVerse) RawHTMLMode(biblemulticonverter.data.FormattedText.RawHTMLMode) Properties(java.util.Properties) SchemaFactory(javax.xml.validation.SchemaFactory) NodeList(org.w3c.dom.NodeList) FormattingInstructionKind(biblemulticonverter.data.FormattedText.FormattingInstructionKind) Verse(biblemulticonverter.data.Verse) Headline(biblemulticonverter.data.FormattedText.Headline) Set(java.util.Set) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) Comment(org.w3c.dom.Comment) File(java.io.File) BookID(biblemulticonverter.data.BookID) List(java.util.List) Element(org.w3c.dom.Element) DocumentBuilder(javax.xml.parsers.DocumentBuilder) Pattern(java.util.regex.Pattern) DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) TransformerFactory(javax.xml.transform.TransformerFactory) ExtraAttributePriority(biblemulticonverter.data.FormattedText.ExtraAttributePriority) Chapter(biblemulticonverter.data.Chapter) Visitor(biblemulticonverter.data.FormattedText.Visitor) Visitor(biblemulticonverter.data.FormattedText.Visitor) Matcher(java.util.regex.Matcher) Node(org.w3c.dom.Node) Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) FormattingInstructionKind(biblemulticonverter.data.FormattedText.FormattingInstructionKind) Text(org.w3c.dom.Text) FormattedText(biblemulticonverter.data.FormattedText) IOException(java.io.IOException) Properties(java.util.Properties) FileInputStream(java.io.FileInputStream) BookID(biblemulticonverter.data.BookID)

Example 5 with FormattingInstructionKind

use of biblemulticonverter.data.FormattedText.FormattingInstructionKind in project BibleMultiConverter by schierlm.

the class YCHPalmBible method doExport.

@Override
public void doExport(Bible bible, String... exportArgs) throws Exception {
    String filename = exportArgs[0];
    String description = bible.getName();
    MetadataBook metadata = bible.getMetadataBook();
    if (metadata != null) {
        String metaDescription = bible.getMetadataBook().getValue(MetadataBookKey.description);
        if (metaDescription != null)
            description = metaDescription;
    }
    try (final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), "windows-1252"))) {
        bw.write("<PARSERINFO ENCODE=\"Cp1252\" WORDTYPE=\"SPCSEP\">");
        bw.newLine();
        bw.write("<BIBLE NAME=\"" + bible.getName() + "\" INFO=\"" + description + "\">");
        bw.newLine();
        Visitor<IOException> contentVisitor = new FormattedText.VisitorAdapter<IOException>(null) {

            @Override
            public void visitVerseSeparator() throws IOException {
            // strip
            }

            @Override
            public void visitText(String text) throws IOException {
                bw.write(text);
            }

            @Override
            public Visitor<IOException> visitFormattingInstruction(FormattingInstructionKind kind) throws IOException {
                return this;
            }

            @Override
            public Visitor<IOException> visitCSSFormatting(String css) throws IOException {
                return this;
            }

            @Override
            public void visitLineBreak(LineBreakKind kind) throws IOException {
                bw.write(" ");
            }
        };
        for (Book bk : bible.getBooks()) {
            int zefID = bk.getId().getZefID();
            if (zefID < 1 || zefID >= PALM_BOOK_NUMBERS.length || PALM_BOOK_NUMBERS[zefID] == 0) {
                System.out.println("WARNING: Skipping unsupported book " + bk.getAbbr() + " (" + bk.getId().getOsisID() + ")");
                continue;
            }
            bw.write("<BOOK NAME=\"" + bk.getShortName() + "\" NUMBER=\"" + PALM_BOOK_NUMBERS[bk.getId().getZefID()] + "\" SHORTCUT=\"" + bk.getAbbr() + "\">");
            bw.newLine();
            String longtitle = bk.getLongName();
            int chapter = 0, verse;
            for (Chapter chap : bk.getChapters()) {
                chapter++;
                if (chap.getProlog() != null)
                    System.out.println("WARNING: Skipping prolog (prologs not supported)!");
                verse = 1;
                String chaptext = CHAPTER_NAME + " " + chapter;
                bw.write("<CHAPTER>");
                bw.newLine();
                for (VirtualVerse v : chap.createVirtualVerses()) {
                    while (v.getNumber() > verse) {
                        bw.write("<VERSE></VERSE>");
                        bw.newLine();
                        verse++;
                    }
                    if (v.getNumber() != verse)
                        throw new RuntimeException("Verse is " + v.getNumber() + ", should be " + verse);
                    boolean needVersText = false;
                    bw.write("<VERSE>");
                    if (longtitle != null) {
                        bw.write("<BOOKTEXT>" + longtitle);
                        longtitle = null;
                        needVersText = true;
                    }
                    if (chaptext != null) {
                        bw.write("<CHAPTEXT>" + chaptext);
                        chaptext = null;
                        needVersText = true;
                    }
                    for (Headline hl : v.getHeadlines()) {
                        bw.write("<DESCTEXT>");
                        hl.accept(contentVisitor);
                        needVersText = true;
                    }
                    if (needVersText)
                        bw.write("<VERSTEXT>");
                    for (Verse vv : v.getVerses()) {
                        if (!vv.getNumber().equals("" + v.getNumber())) {
                            bw.write("{" + vv.getNumber() + "} ");
                        }
                        vv.accept(contentVisitor);
                    }
                    bw.write("</VERSE>");
                    verse++;
                    bw.newLine();
                }
                bw.write("</CHAPTER>");
                bw.newLine();
            }
            bw.write("</BOOK>");
            bw.newLine();
        }
        bw.write("</BIBLE>");
        bw.newLine();
    }
}
Also used : MetadataBook(biblemulticonverter.data.MetadataBook) VirtualVerse(biblemulticonverter.data.VirtualVerse) Chapter(biblemulticonverter.data.Chapter) FormattingInstructionKind(biblemulticonverter.data.FormattedText.FormattingInstructionKind) IOException(java.io.IOException) BufferedWriter(java.io.BufferedWriter) LineBreakKind(biblemulticonverter.data.FormattedText.LineBreakKind) MetadataBook(biblemulticonverter.data.MetadataBook) Book(biblemulticonverter.data.Book) FileOutputStream(java.io.FileOutputStream) Headline(biblemulticonverter.data.FormattedText.Headline) OutputStreamWriter(java.io.OutputStreamWriter) VirtualVerse(biblemulticonverter.data.VirtualVerse) Verse(biblemulticonverter.data.Verse)

Aggregations

FormattingInstructionKind (biblemulticonverter.data.FormattedText.FormattingInstructionKind)8 Visitor (biblemulticonverter.data.FormattedText.Visitor)6 BookID (biblemulticonverter.data.BookID)5 IOException (java.io.IOException)5 List (java.util.List)5 JAXBElement (javax.xml.bind.JAXBElement)5 Book (biblemulticonverter.data.Book)4 FormattedText (biblemulticonverter.data.FormattedText)4 LineBreakKind (biblemulticonverter.data.FormattedText.LineBreakKind)4 MetadataBook (biblemulticonverter.data.MetadataBook)4 ArrayList (java.util.ArrayList)4 Chapter (biblemulticonverter.data.Chapter)3 ExtraAttributePriority (biblemulticonverter.data.FormattedText.ExtraAttributePriority)3 Headline (biblemulticonverter.data.FormattedText.Headline)3 RawHTMLMode (biblemulticonverter.data.FormattedText.RawHTMLMode)3 Verse (biblemulticonverter.data.Verse)3 VirtualVerse (biblemulticonverter.data.VirtualVerse)3 BR (biblemulticonverter.schema.zef2005.BR)3 DIV (biblemulticonverter.schema.zef2005.DIV)3 GRAM (biblemulticonverter.schema.zef2005.GRAM)3