Search in sources :

Example 1 with ExtraAttributePriority

use of biblemulticonverter.data.FormattedText.ExtraAttributePriority 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 2 with ExtraAttributePriority

use of biblemulticonverter.data.FormattedText.ExtraAttributePriority 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 3 with ExtraAttributePriority

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

the class RoundtripHTML method parseLine.

private int parseLine(Visitor<RuntimeException> visitor, String line, int pos, List<Visitor<RuntimeException>> footnotes) throws IOException {
    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).replace("&gt;", ">").replace("&lt;", "<").replace("&amp;", "&"));
            pos = endPos;
            continue;
        }
        if (line.startsWith("</", pos))
            return pos;
        int endPos = line.indexOf('>', pos);
        if (endPos == -1)
            throw new IOException(line.substring(pos));
        int spacePos = line.indexOf(' ', pos);
        if (spacePos == -1 || spacePos > endPos)
            spacePos = endPos;
        Visitor<RuntimeException> childVisitor;
        String tag = line.substring(pos + 1, spacePos);
        switch(tag) {
            case "b":
            case "i":
            case "u":
                childVisitor = visitor.visitFormattingInstruction(FormattingInstructionKind.fromChar(tag.charAt(0)));
                pos = parseLine(childVisitor, line, endPos + 1, footnotes);
                if (!line.startsWith("</" + tag + ">", pos))
                    throw new IOException(line.substring(pos));
                pos += 4;
                break;
            case "br":
                visitor.visitLineBreak(LineBreakKind.NEWLINE);
                pos += 4;
                break;
            case "h2":
            case "h3":
            case "h4":
            case "h5":
                childVisitor = visitor.visitHeadline(tag.charAt(1) - '1');
                pos = parseLine(childVisitor, line, endPos + 1, footnotes);
                if (!line.startsWith("</" + tag + ">", pos))
                    throw new IOException(line.substring(pos));
                pos += 5;
                break;
            case "h6":
                if (!line.startsWith("<h6 class=\"depth-", pos))
                    throw new IOException(line.substring(pos));
                childVisitor = visitor.visitHeadline(line.charAt(pos + 17) - '0');
                pos = parseLine(childVisitor, line, endPos + 1, footnotes);
                if (!line.startsWith("</h6>", pos))
                    throw new IOException(line.substring(pos));
                pos += 5;
                break;
            case "!--raw":
                String[] parts = line.substring(spacePos + 1, endPos).split(" ");
                String marker = parts[0];
                RawHTMLMode mode;
                switch(parts[1]) {
                    case "of":
                        mode = RawHTMLMode.OFFLINE;
                        break;
                    case "on":
                        mode = RawHTMLMode.ONLINE;
                        break;
                    case "bo":
                        mode = RawHTMLMode.BOTH;
                        break;
                    default:
                        throw new IOException(parts[1]);
                }
                int rawEnd = line.indexOf("endraw " + marker + "-->", pos);
                String content;
                if (mode == RawHTMLMode.OFFLINE) {
                    content = line.substring(endPos + 1, rawEnd - 2).replace("-d", "-");
                } else {
                    content = line.substring(endPos + 1, rawEnd - 4);
                }
                visitor.visitRawHTML(mode, content);
                pos = rawEnd + 10 + marker.length();
                break;
            case "sub":
                childVisitor = visitor.visitFormattingInstruction(FormattingInstructionKind.SUBSCRIPT);
                pos = parseLine(childVisitor, line, endPos + 1, footnotes);
                if (!line.startsWith("</sub>", pos))
                    throw new IOException(line.substring(pos));
                pos += 6;
                break;
            case "sup":
                if (spacePos == endPos) {
                    childVisitor = visitor.visitFormattingInstruction(FormattingInstructionKind.SUPERSCRIPT);
                    pos = parseLine(childVisitor, line, endPos + 1, footnotes);
                    if (!line.startsWith("</sup>", pos))
                        throw new IOException(line.substring(pos));
                    pos += 6;
                } else if (line.startsWith("<sup class=\"fnm\"><a name=\"fnm", pos)) {
                    footnotes.add(visitor.visitFootnote());
                    int cnt = footnotes.size();
                    String value = "<sup class=\"fnm\"><a name=\"fnm" + cnt + "\" href=\"#fn" + cnt + "\">" + cnt + "</a></sup>";
                    if (!line.startsWith(value, pos))
                        throw new IOException(line.substring(pos));
                    pos += value.length();
                } else {
                    throw new IOException(line.substring(pos));
                }
                break;
            case "a":
                if (line.startsWith("<a class=\"footnote-link\" href=\"", pos)) {
                    childVisitor = visitor.visitFormattingInstruction(FormattingInstructionKind.FOOTNOTE_LINK);
                } else if (line.startsWith("<a class=\"xr\" href=\"", pos)) {
                    String params = line.substring(spacePos, endPos - 1);
                    params = params.substring(params.indexOf("\"-bmc-xr: ") + 10);
                    String[] fields = params.split(" ");
                    if (fields.length != 6)
                        throw new IOException(params);
                    childVisitor = visitor.visitCrossReference(fields[0], BookID.fromOsisId(fields[1]), Integer.parseInt(fields[2]), fields[3], Integer.parseInt(fields[4]), fields[5]);
                } else if (line.startsWith("<a class=\"dict\" href=\"../../", pos)) {
                    String[] params = line.substring(spacePos + 26, endPos - 8).split("/dict/");
                    if (params.length != 2)
                        throw new IOException(line.substring(pos));
                    childVisitor = visitor.visitDictionaryEntry(params[0], params[1]);
                } else {
                    throw new IOException(line.substring(pos));
                }
                pos = parseLine(childVisitor, line, endPos + 1, footnotes);
                if (!line.startsWith("</a>", pos))
                    throw new IOException(line.substring(pos));
                pos += 4;
                break;
            case "span":
                if (line.startsWith("<span class=\"vn\">", pos)) {
                    // skip explicit verse numbers
                    pos = line.indexOf("</span> ", pos) + 8;
                } else if (line.startsWith("<span class=\"vsep\">/</span>", pos)) {
                    pos += 27;
                    visitor.visitVerseSeparator();
                } else if (line.startsWith("<span class=\"br-ind\"><br><span class=\"indent\">&nbsp;</span></span>", pos)) {
                    pos += 66;
                    visitor.visitLineBreak(LineBreakKind.NEWLINE_WITH_INDENT);
                } else if (line.startsWith("<span class=\"br-p\"><br><br></span>", pos)) {
                    pos += 34;
                    visitor.visitLineBreak(LineBreakKind.PARAGRAPH);
                } else {
                    if (line.startsWith("<span class=\"css\" style=\"", pos)) {
                        childVisitor = visitor.visitCSSFormatting(line.substring(pos + 25, endPos - 1));
                    } else if (line.startsWith("<span class=\"fmt-", pos)) {
                        childVisitor = visitor.visitFormattingInstruction(FormattingInstructionKind.valueOf(line.substring(pos + 17, endPos - 1).replace('-', '_').toUpperCase()));
                    } else if (line.startsWith("<span class=\"var", pos)) {
                        childVisitor = visitor.visitVariationText(line.substring(pos + 21, endPos - 1).split(" var-"));
                    } else if (line.startsWith("<span class=\"xa xa-", pos)) {
                        String tagContent = line.substring(pos, endPos + 1);
                        Matcher m = Utils.compilePattern("<span class=\"xa xa-([eks])\" style=\"-bmc-xa-([a-z0-9]+)-([a-z0-9-]+): ([A-Za-z0-9-]+);\">").matcher(tagContent);
                        if (!m.matches())
                            throw new IOException(tagContent);
                        char prioChar = m.group(1).charAt(0);
                        ExtraAttributePriority prio = prioChar == 'e' ? ExtraAttributePriority.ERROR : prioChar == 'k' ? ExtraAttributePriority.KEEP_CONTENT : prioChar == 's' ? ExtraAttributePriority.SKIP : null;
                        childVisitor = visitor.visitExtraAttribute(prio, m.group(2), m.group(3), m.group(4));
                    } else if (line.startsWith("<span class=\"g ", pos)) {
                        List<Integer> strongL = new ArrayList<Integer>();
                        List<String> rmacL = new ArrayList<String>();
                        List<Integer> sourceIndexL = new ArrayList<Integer>();
                        for (String part : line.substring(pos + 15, endPos - 1).split(" ")) {
                            if (part.startsWith("gs")) {
                                strongL.add(Integer.parseInt(part.substring(2)));
                            } else if (part.startsWith("gr-")) {
                                rmacL.add(part.substring(3).toUpperCase());
                            } else if (part.startsWith("gi")) {
                                sourceIndexL.add(Integer.parseInt(part.substring(2)));
                            } else {
                                throw new IOException(part);
                            }
                        }
                        int[] strongs = strongL.size() == 0 ? null : new int[strongL.size()];
                        if (strongs != null) {
                            for (int i = 0; i < strongs.length; i++) {
                                strongs[i] = strongL.get(i);
                            }
                        }
                        String[] rmacs = rmacL.size() == 0 ? null : (String[]) rmacL.toArray(new String[rmacL.size()]);
                        int[] sourceIndices = sourceIndexL.size() == 0 ? null : new int[sourceIndexL.size()];
                        if (sourceIndices != null) {
                            for (int i = 0; i < sourceIndices.length; i++) {
                                sourceIndices[i] = sourceIndexL.get(i);
                            }
                        }
                        childVisitor = visitor.visitGrammarInformation(strongs, rmacs, sourceIndices);
                    } else {
                        throw new IOException(line.substring(pos));
                    }
                    pos = parseLine(childVisitor, line, endPos + 1, footnotes);
                    if (!line.startsWith("</span>", pos))
                        throw new IOException(line.substring(pos));
                    pos += 7;
                }
                break;
            default:
                throw new IOException(tag);
        }
    }
    return pos;
}
Also used : ExtraAttributePriority(biblemulticonverter.data.FormattedText.ExtraAttributePriority) Matcher(java.util.regex.Matcher) IOException(java.io.IOException) RawHTMLMode(biblemulticonverter.data.FormattedText.RawHTMLMode) ArrayList(java.util.ArrayList) List(java.util.List)

Example 4 with ExtraAttributePriority

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

the class MyBibleZone method doExport.

@Override
public void doExport(Bible bible, String... exportArgs) throws Exception {
    String outfile = exportArgs[0];
    if (!outfile.endsWith(".SQLite3"))
        outfile += ".SQLite3";
    boolean hasFootnotes = false, hasStrongs = false;
    for (Book bk : bible.getBooks()) {
        for (Chapter ch : bk.getChapters()) {
            for (Verse vv : ch.getVerses()) {
                String elementTypes = vv.getElementTypes(Integer.MAX_VALUE);
                if (elementTypes.contains("f")) {
                    hasFootnotes = true;
                }
                if (elementTypes.contains("g")) {
                    hasStrongs = true;
                }
            }
        }
    }
    new File(outfile).delete();
    SqlJetDb db = SqlJetDb.open(new File(outfile), true);
    db.getOptions().setAutovacuum(true);
    db.beginTransaction(SqlJetTransactionMode.WRITE);
    db.getOptions().setUserVersion(0);
    db.createTable("CREATE TABLE info (name TEXT, value TEXT)");
    db.createTable("CREATE TABLE books (book_number NUMERIC, book_color TEXT, short_name TEXT, long_name TEXT)");
    db.createTable("CREATE TABLE introductions (book_number NUMERIC, introduction TEXT)");
    db.createIndex("CREATE UNIQUE INDEX introductions_index on introductions(book_number)");
    db.createTable("CREATE TABLE verses (book_number INTEGER, chapter INTEGER, verse INTEGER, text TEXT)");
    db.createIndex("CREATE UNIQUE INDEX verses_index on verses (book_number, chapter, verse)");
    db.createTable("CREATE TABLE stories (book_number NUMERIC, chapter NUMERIC, verse NUMERIC, order_if_several NUMERIC, title TEXT)");
    db.createIndex("CREATE UNIQUE INDEX stories_index on stories(book_number, chapter, verse, order_if_several)");
    Map<String, String> infoValues = new LinkedHashMap<>();
    MetadataBook mb = bible.getMetadataBook();
    if (mb == null)
        mb = new MetadataBook();
    infoValues.put("language", "xx");
    infoValues.put("description", bible.getName());
    infoValues.put("detailed_info", "");
    infoValues.put("russian_numbering", "false");
    infoValues.put("chapter_string", "Chapter");
    infoValues.put("introduction_string", "Introduction");
    infoValues.put("strong_numbers", hasStrongs ? "true" : "false");
    infoValues.put("right_to_left", "false");
    infoValues.put("digits0-9", "0123456789");
    infoValues.put("swaps_non_localized_words_in_mixed_language_line", "false");
    infoValues.put("localized_book_abbreviations", "false");
    infoValues.put("font_scale", "1.0");
    infoValues.put("contains_accents", "true");
    for (String mbkey : mb.getKeys()) {
        if (mbkey.startsWith("MyBible.zone@")) {
            infoValues.put(mbkey.substring(13).replace('.', '_'), mb.getValue(mbkey));
        } else {
            infoValues.put("detailed_info", infoValues.get("detailed_info") + "\r\n<br><b>" + mbkey + ":</b>" + mb.getValue(mbkey));
        }
    }
    String bibleIntro = null, singleFootnoteMarker = null, singleXrefMarker = null;
    if (exportArgs.length > 1) {
        Properties props = new Properties();
        FileInputStream in = new FileInputStream(exportArgs[1]);
        props.load(in);
        in.close();
        bibleIntro = (String) props.remove("__INTRODUCTION__");
        singleFootnoteMarker = (String) props.remove("__FOOTNOTE_MARKER__");
        singleXrefMarker = (String) props.remove("__XREF_MARKER__");
        for (Object key : props.keySet()) {
            String template = props.getProperty(key.toString());
            template = template.replace("${name}", bible.getName());
            for (String mbkey : mb.getKeys()) template = template.replace("${" + mbkey + "}", mb.getValue(mbkey));
            infoValues.put(key.toString(), template);
        }
    }
    ISqlJetTable infoTable = db.getTable("info");
    ISqlJetTable booksTable = db.getTable("books");
    ISqlJetTable introductionsTable = db.getTable("introductions");
    ISqlJetTable versesTable = db.getTable("verses");
    ISqlJetTable storiesTable = db.getTable("stories");
    for (Map.Entry<String, String> entry : infoValues.entrySet()) {
        infoTable.insert(entry.getKey(), entry.getValue());
    }
    SqlJetDb cdb = null;
    ISqlJetTable footnotesTable = null;
    if (hasFootnotes) {
        String commentaryfile = outfile.replace(".SQLite3", ".commentaries.SQLite3");
        new File(commentaryfile).delete();
        cdb = SqlJetDb.open(new File(commentaryfile), true);
        cdb.getOptions().setAutovacuum(true);
        cdb.beginTransaction(SqlJetTransactionMode.WRITE);
        cdb.getOptions().setUserVersion(0);
        cdb.createTable("CREATE TABLE info (name TEXT, value TEXT)");
        cdb.createTable("CREATE TABLE commentaries (book_number NUMERIC, chapter_number_from NUMERIC, verse_number_from NUMERIC, chapter_number_to NUMERIC, verse_number_to NUMERIC, marker TEXT, text TEXT )");
        cdb.createIndex("CREATE INDEX commentaries_index on commentaries(book_number, chapter_number_from, verse_number_from)");
        ISqlJetTable cInfoTable = cdb.getTable("info");
        for (String key : Arrays.asList("language", "description", "russian_numbering")) {
            cInfoTable.insert(key, infoValues.get(key));
        }
        cInfoTable.insert("is_footnotes", "true");
        footnotesTable = cdb.getTable("commentaries");
    }
    final Set<String> unsupportedFeatures = new HashSet<>();
    FormattedText introProlog = null;
    for (Book bk : bible.getBooks()) {
        if (bk.getId() == BookID.INTRODUCTION || bk.getId() == BookID.INTRODUCTION_OT || bk.getId() == BookID.INTRODUCTION_NT || bk.getId() == BookID.APPENDIX) {
            if (introProlog == null)
                introProlog = new FormattedText();
            introProlog.getAppendVisitor().visitHeadline(1).visitText(bk.getLongName());
            bk.getChapters().get(0).getProlog().accept(introProlog.getAppendVisitor());
            continue;
        }
        MyBibleZoneBook info = null;
        for (MyBibleZoneBook bi : BOOK_INFO) {
            if (bi.bookID == bk.getId())
                info = bi;
        }
        if (info == null) {
            System.out.println("WARNING: Skipping unsupported book " + bk.getId());
            continue;
        }
        booksTable.insert(info.bookNumber, info.bookColor, bk.getAbbr(), bk.getShortName());
        FormattedText prologs = null;
        for (int cn = 1; cn <= bk.getChapters().size(); cn++) {
            Chapter ch = bk.getChapters().get(cn - 1);
            if (ch.getProlog() != null) {
                if (prologs == null)
                    prologs = new FormattedText();
                prologs.getAppendVisitor().visitHeadline(1).visitText(cn == 1 ? bk.getLongName() : "" + cn);
                ch.getProlog().accept(prologs.getAppendVisitor());
            }
            int vn = 0;
            for (VirtualVerse vv : ch.createVirtualVerses()) {
                vn++;
                while (vn < vv.getNumber()) versesTable.insert(info.bookNumber, cn, vn++, "");
                if (vn != vv.getNumber())
                    throw new RuntimeException(vn + " != " + vv.getNumber());
                for (int hl = 0; hl < vv.getHeadlines().size(); hl++) {
                    final StringBuilder sb = new StringBuilder();
                    final Map<StringBuilder, String> xrefTags = new HashMap<>();
                    vv.getHeadlines().get(hl).accept(new VisitorAdapter<RuntimeException>(null) {

                        @Override
                        protected Visitor<RuntimeException> wrapChildVisitor(Visitor<RuntimeException> childVisitor) throws RuntimeException {
                            return this;
                        }

                        @Override
                        protected void beforeVisit() throws RuntimeException {
                            unsupportedFeatures.add("markup in headline");
                        }

                        @Override
                        public void visitText(String text) throws RuntimeException {
                            sb.append(text.replace('<', '〈').replace('>', '〉'));
                        }

                        @Override
                        public Visitor<RuntimeException> visitFootnote() throws RuntimeException {
                            // handle this separately; we do not like
                            // footnote text inside the headline!
                            unsupportedFeatures.add("footnote in headline");
                            return new VisitorAdapter<RuntimeException>(null) {

                                @Override
                                protected Visitor<RuntimeException> wrapChildVisitor(Visitor<RuntimeException> childVisitor) throws RuntimeException {
                                    return this;
                                }

                                @Override
                                public Visitor<RuntimeException> visitCrossReference(String bookAbbr, BookID book, int firstChapter, String firstVerse, int lastChapter, String lastVerse) throws RuntimeException {
                                    if (!BOOK_NUMBERS.containsKey(book))
                                        return null;
                                    final StringBuilder innerBuilder = new StringBuilder();
                                    String endVerse = firstChapter != lastChapter ? "-" + lastChapter + ":" + lastVerse : !firstVerse.equals(lastVerse) ? "-" + lastVerse : "";
                                    xrefTags.put(innerBuilder, "<x>" + BOOK_NUMBERS.get(book) + " " + firstChapter + ":" + firstVerse + endVerse + "</x>");
                                    return new VisitorAdapter<RuntimeException>(null) {

                                        @Override
                                        protected void beforeVisit() throws RuntimeException {
                                            throw new RuntimeException("Unsupported content inside headline xref");
                                        }

                                        @Override
                                        public void visitText(String text) throws RuntimeException {
                                            innerBuilder.append(text.replace('<', '〈').replace('>', '〉'));
                                        }
                                    };
                                }
                            };
                        }

                        @Override
                        public Visitor<RuntimeException> visitExtraAttribute(ExtraAttributePriority prio, String category, String key, String value) throws RuntimeException {
                            unsupportedFeatures.add("extra atrribute in headline");
                            return prio.handleVisitor(category, this);
                        }
                    });
                    String headline = sb.toString();
                    for (Map.Entry<StringBuilder, String> xrefTag : xrefTags.entrySet()) {
                        headline = headline.replace(xrefTag.getKey().toString(), xrefTag.getValue());
                    }
                    storiesTable.insert(info.bookNumber, cn, vn, hl, headline);
                }
                StringBuilder vb = new StringBuilder();
                Map<String, MyBibleHTMLVisitor> footnotes = new HashMap<>();
                MyBibleVerseVisitor mbvv = new MyBibleVerseVisitor(vb, footnotes, unsupportedFeatures);
                for (Verse v : vv.getVerses()) {
                    if (!v.getNumber().equals("" + vv.getNumber())) {
                        vb.append(" <e>(" + v.getNumber() + ")</e> ");
                    }
                    mbvv.reset();
                    v.accept(mbvv);
                }
                if (singleXrefMarker != null || singleFootnoteMarker != null) {
                    String singleXref = null, singleFootnote = null;
                    for (Map.Entry<String, MyBibleHTMLVisitor> fn : footnotes.entrySet()) {
                        if (!fn.getKey().matches("\\[[0-9]+\\]"))
                            continue;
                        if (fn.getValue().getResult().startsWith(FormattedText.XREF_MARKER) && singleXrefMarker != null) {
                            if (singleXref == null) {
                                singleXref = fn.getKey();
                            } else {
                                System.out.println("WARNING: More than one XREF footnote in verse " + info.bookID + " " + cn + ":" + vn);
                                singleXref = "-";
                            }
                        } else if (singleFootnoteMarker != null) {
                            if (singleFootnote == null) {
                                singleFootnote = fn.getKey();
                            } else {
                                System.out.println("WARNING: More than one normal footnote in verse " + info.bookID + " " + cn + ":" + vn);
                                singleFootnote = "-";
                            }
                        }
                    }
                    if (singleXref != null && !singleXref.equals("-")) {
                        MyBibleHTMLVisitor xfn = footnotes.remove(singleXref);
                        if (xfn == null)
                            throw new RuntimeException();
                        footnotes.put(singleXrefMarker, xfn);
                        String verse = vb.toString();
                        vb.setLength(0);
                        vb.append(verse.replace("<f>" + singleXref + "</f>", "<f>" + singleXrefMarker + "</f>"));
                    }
                    if (singleFootnote != null && !singleFootnote.equals("-")) {
                        MyBibleHTMLVisitor sfn = footnotes.remove(singleFootnote);
                        if (sfn == null)
                            throw new RuntimeException();
                        footnotes.put(singleFootnoteMarker, sfn);
                        String verse = vb.toString();
                        vb.setLength(0);
                        vb.append(verse.replace("<f>" + singleFootnote + "</f>", "<f>" + singleFootnoteMarker + "</f>"));
                    }
                }
                for (Map.Entry<String, MyBibleHTMLVisitor> fn : footnotes.entrySet()) {
                    footnotesTable.insert(info.bookNumber, cn, vn, cn, vn, fn.getKey(), fn.getValue().getResult());
                }
                versesTable.insert(info.bookNumber, cn, vn, vb.toString().trim());
            }
        }
        if (prologs != null) {
            MyBibleHTMLVisitor v = new MyBibleHTMLVisitor(unsupportedFeatures, "in introduction");
            prologs.accept(v);
            introductionsTable.insert(info.bookNumber, v.getResult());
        }
    }
    if (bibleIntro != null) {
        introductionsTable.insert(0, bibleIntro);
    } else if (introProlog != null) {
        MyBibleHTMLVisitor v = new MyBibleHTMLVisitor(unsupportedFeatures, "in introduction");
        introProlog.accept(v);
        introductionsTable.insert(0, v.getResult());
    }
    if (!unsupportedFeatures.isEmpty()) {
        System.out.println("WARNING: Skipped unsupported features: " + unsupportedFeatures);
    }
    db.commit();
    db.close();
    if (cdb != null) {
        cdb.commit();
        cdb.close();
    }
}
Also used : ExtraAttributePriority(biblemulticonverter.data.FormattedText.ExtraAttributePriority) VirtualVerse(biblemulticonverter.data.VirtualVerse) AbstractHTMLVisitor(biblemulticonverter.format.AbstractHTMLVisitor) Visitor(biblemulticonverter.data.FormattedText.Visitor) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) SqlJetDb(org.tmatesoft.sqljet.core.table.SqlJetDb) Properties(java.util.Properties) LinkedHashMap(java.util.LinkedHashMap) BookID(biblemulticonverter.data.BookID) MetadataBook(biblemulticonverter.data.MetadataBook) Book(biblemulticonverter.data.Book) ISqlJetTable(org.tmatesoft.sqljet.core.table.ISqlJetTable) HashSet(java.util.HashSet) MetadataBook(biblemulticonverter.data.MetadataBook) Chapter(biblemulticonverter.data.Chapter) FormattedText(biblemulticonverter.data.FormattedText) FileInputStream(java.io.FileInputStream) File(java.io.File) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) EnumMap(java.util.EnumMap) VirtualVerse(biblemulticonverter.data.VirtualVerse) Verse(biblemulticonverter.data.Verse)

Aggregations

ExtraAttributePriority (biblemulticonverter.data.FormattedText.ExtraAttributePriority)4 Book (biblemulticonverter.data.Book)3 BookID (biblemulticonverter.data.BookID)3 FormattedText (biblemulticonverter.data.FormattedText)3 RawHTMLMode (biblemulticonverter.data.FormattedText.RawHTMLMode)3 Visitor (biblemulticonverter.data.FormattedText.Visitor)3 MetadataBook (biblemulticonverter.data.MetadataBook)3 List (java.util.List)3 Chapter (biblemulticonverter.data.Chapter)2 FormattingInstructionKind (biblemulticonverter.data.FormattedText.FormattingInstructionKind)2 LineBreakKind (biblemulticonverter.data.FormattedText.LineBreakKind)2 Verse (biblemulticonverter.data.Verse)2 VirtualVerse (biblemulticonverter.data.VirtualVerse)2 JAXBElement (javax.xml.bind.JAXBElement)2 QName (javax.xml.namespace.QName)2 Headline (biblemulticonverter.data.FormattedText.Headline)1 MetadataBookKey (biblemulticonverter.data.MetadataBook.MetadataBookKey)1 AbstractHTMLVisitor (biblemulticonverter.format.AbstractHTMLVisitor)1 BIBLEBOOK (biblemulticonverter.schema.zef2005.BIBLEBOOK)1 BR (biblemulticonverter.schema.zef2005.BR)1