Search in sources :

Example 1 with Visitor

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

the class StrippedDiffable method extractFootnotes.

private FormattedText extractFootnotes(FormattedText text) {
    String types = text.getElementTypes(1);
    if (!types.contains("f"))
        return null;
    final FormattedText result = new FormattedText();
    if (types.matches("[^f]+f")) {
        List<FormattedText> parts = text.splitContent(false, true);
        parts.get(parts.size() - 1).accept(result.getAppendVisitor());
    } else {
        text.accept(new FormattedText.VisitorAdapter<RuntimeException>(null) {

            Visitor<RuntimeException> outerVisitor = result.getAppendVisitor();

            Visitor<RuntimeException> innerVisitor = null;

            @Override
            protected void beforeVisit() throws RuntimeException {
                if (innerVisitor == null) {
                    innerVisitor = outerVisitor.visitFormattingInstruction(FormattingInstructionKind.ITALIC);
                    innerVisitor.visitText("[");
                }
            }

            @Override
            protected Visitor<RuntimeException> getVisitor() throws RuntimeException {
                return innerVisitor;
            }

            @Override
            public Visitor<RuntimeException> visitHeadline(int depth) throws RuntimeException {
                return null;
            }

            @Override
            public Visitor<RuntimeException> visitFootnote() throws RuntimeException {
                if (innerVisitor != null) {
                    innerVisitor.visitText("]");
                    innerVisitor = null;
                }
                return outerVisitor;
            }

            @Override
            public boolean visitEnd() throws RuntimeException {
                if (innerVisitor != null) {
                    innerVisitor.visitText("]");
                    innerVisitor = null;
                }
                return false;
            }
        });
    }
    return result;
}
Also used : Visitor(biblemulticonverter.data.FormattedText.Visitor) FormattedText(biblemulticonverter.data.FormattedText)

Example 2 with Visitor

use of biblemulticonverter.data.FormattedText.Visitor 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 Visitor

use of biblemulticonverter.data.FormattedText.Visitor 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 Visitor

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

the class MobiPocket method writeVerse.

private void writeVerse(BufferedWriter bw, FormattedText v, final Bible bb, final String versePrefix, final String lexiconName) throws IOException {
    final String lineSeparator = System.getProperty("line.separator");
    v.accept(new AbstractHTMLVisitor(bw, "</p>" + lineSeparator) {

        @Override
        public Visitor<IOException> visitHeadline(int depth) throws IOException {
            int level = depth < 3 ? depth + 3 : 6;
            writer.write("<h" + level + ">");
            pushSuffix("</h" + level + ">" + lineSeparator);
            return this;
        }

        @Override
        public void visitStart() throws IOException {
            if (suffixStack.size() == 1) {
                writer.write("<p>" + versePrefix);
            }
        }

        @Override
        protected String getNextFootnoteTarget() {
            return "#" + chapref + "f" + (footNoteCount + 1);
        }

        @Override
        public Visitor<IOException> visitFootnote() throws IOException {
            final Writer outerWriter = writer;
            return new AbstractHTMLVisitor(new StringWriter(), "") {

                @Override
                public void visitLineBreak(LineBreakKind kind) throws IOException {
                    writer.append("<br>");
                }

                @Override
                public Visitor<IOException> visitFootnote() throws IOException {
                    throw new IllegalStateException("Footnote in footnote");
                }

                @Override
                public Visitor<IOException> visitGrammarInformation(int[] strongs, String[] rmac, int[] sourceIndices) throws IOException {
                    pushSuffix("");
                    return this;
                }

                @Override
                public FormattedText.Visitor<IOException> visitDictionaryEntry(String dictionary, String entry) throws IOException {
                    writer.write("<a href=\"oeb:redirect?title=" + lexiconName + "#" + entry + "\">");
                    pushSuffix("</a>");
                    return this;
                }

                @Override
                public void visitRawHTML(RawHTMLMode mode, String raw) throws IOException {
                    if (mode != RawHTMLMode.ONLINE)
                        writer.write(raw);
                }

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

                @Override
                public Visitor<IOException> visitCrossReference(String bookAbbr, BookID book, int firstChapter, String firstVerse, int lastChapter, String lastVerse) throws IOException {
                    if (checkBXR(bookRef(bookAbbr, book), lastChapter)) {
                        writer.write("<a href=\"oeb:redirect?title=BibleNavigation#b" + bookRef(bookAbbr, book) + "c" + firstChapter + "\">");
                        pushSuffix("</a>");
                    } else {
                        pushSuffix("");
                    }
                    return this;
                }

                @Override
                public boolean visitEnd() throws IOException {
                    super.visitEnd();
                    if (suffixStack.size() == 0) {
                        if (writer.toString().startsWith(FormattedText.XREF_MARKER)) {
                            // this is a cross reference!
                            if (crossRefs.length() > 0)
                                crossRefs.append("<br>");
                            String xref = writer.toString().substring(FormattedText.XREF_MARKER.length()).trim();
                            if (!xref.startsWith("<b>"))
                                xref = versePrefix + xref;
                            crossRefs.append(xref);
                        } else {
                            footNoteCount++;
                            outerWriter.write("<sup><a name=\"" + chapref + "ft" + footNoteCount + "\" href=\"#" + chapref + "f" + footNoteCount + "\">" + footNoteCount + "</a></sup>");
                            if (footNotes.length() > 0)
                                footNotes.append("<br>");
                            footNotes.append("<sup><a name=\"" + chapref + "f" + footNoteCount + "\" href=\"#" + chapref + "ft" + footNoteCount + "\">" + footNoteCount + "</a></sup> ");
                            footNotes.append(writer.toString());
                        }
                    }
                    return false;
                }

                @Override
                public Visitor<IOException> visitHeadline(int depth) throws IOException {
                    throw new IOException("Headline inside footnote");
                }
            };
        }

        @Override
        public FormattedText.Visitor<IOException> visitCrossReference(String bookAbbr, BookID book, int firstChapter, String firstVerse, int lastChapter, String lastVerse) throws IOException {
            if (checkBXR(bookRef(bookAbbr, book), lastChapter)) {
                writer.write("<a href=\"oeb:redirect?title=BibleNavigation#b" + bookRef(bookAbbr, book) + "c" + firstChapter + "\">");
                pushSuffix("</a>");
            } else {
                pushSuffix("");
            }
            return this;
        }

        @Override
        public void visitLineBreak(LineBreakKind kind) throws IOException {
            writer.write("<br>");
        }

        @Override
        public Visitor<IOException> visitGrammarInformation(int[] strongs, String[] rmac, int[] sourceIndices) throws IOException {
            pushSuffix("");
            return this;
        }

        @Override
        public FormattedText.Visitor<IOException> visitDictionaryEntry(String dictionary, String entry) throws IOException {
            writer.write("<a href=\"oeb:redirect?title=" + lexiconName + "#" + entry + "\">");
            pushSuffix("</a>");
            return this;
        }

        @Override
        public Visitor<IOException> visitVariationText(String[] variations) throws IOException {
            throw new UnsupportedOperationException("Variations not supported");
        }
    });
}
Also used : Visitor(biblemulticonverter.data.FormattedText.Visitor) IOException(java.io.IOException) RawHTMLMode(biblemulticonverter.data.FormattedText.RawHTMLMode) LineBreakKind(biblemulticonverter.data.FormattedText.LineBreakKind) StringWriter(java.io.StringWriter) BookID(biblemulticonverter.data.BookID) BufferedWriter(java.io.BufferedWriter) StringWriter(java.io.StringWriter) Writer(java.io.Writer) OutputStreamWriter(java.io.OutputStreamWriter)

Example 5 with Visitor

use of biblemulticonverter.data.FormattedText.Visitor 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)

Aggregations

Visitor (biblemulticonverter.data.FormattedText.Visitor)16 Book (biblemulticonverter.data.Book)8 BookID (biblemulticonverter.data.BookID)8 FormattedText (biblemulticonverter.data.FormattedText)8 IOException (java.io.IOException)8 ArrayList (java.util.ArrayList)8 Chapter (biblemulticonverter.data.Chapter)7 FormattingInstructionKind (biblemulticonverter.data.FormattedText.FormattingInstructionKind)6 MetadataBook (biblemulticonverter.data.MetadataBook)6 JAXBElement (javax.xml.bind.JAXBElement)6 Verse (biblemulticonverter.data.Verse)5 List (java.util.List)5 ExtraAttributePriority (biblemulticonverter.data.FormattedText.ExtraAttributePriority)4 Headline (biblemulticonverter.data.FormattedText.Headline)4 LineBreakKind (biblemulticonverter.data.FormattedText.LineBreakKind)4 RawHTMLMode (biblemulticonverter.data.FormattedText.RawHTMLMode)4 VirtualVerse (biblemulticonverter.data.VirtualVerse)4 File (java.io.File)4 Matcher (java.util.regex.Matcher)4 Bible (biblemulticonverter.data.Bible)3