/* * Copyright (C) 2004-2012 Geometer Plus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include #include #include #include #include "PmlBookReader.h" #include "../../bookmodel/BookModel.h" PmlBookReader::PmlBookReader(BookReader &bookReader, const PlainTextFormat&, const std::string &encoding) : PmlReader(encoding), myBookReader(bookReader) { } PmlBookReader::~PmlBookReader() { } bool PmlBookReader::readDocument(ZLInputStream& stream) { myBookReader.pushKind(REGULAR); myBookReader.beginParagraph(); myParagraphIsEmpty = true; bool code = PmlReader::readDocument(stream); myBookReader.endParagraph(); return code; } void PmlBookReader::addCharData(const char *data, std::size_t len, bool convert) { if (!myBookReader.paragraphIsOpen()) { myBookReader.beginParagraph(); } static std::string newString; if (len != 0) { if (!myConverter.isNull() && convert) { myConverter->convert(newString, data, data + len); } else { newString.append(data, len); } if (myState.SmallCaps) { myBookReader.addData(ZLUnicodeUtil::toUpper(newString)); } else { myBookReader.addData(newString); } newString.erase(); if (myParagraphIsEmpty) { myParagraphIsEmpty = false; } } } void PmlBookReader::switchFontProperty(FontProperty property) { if (!myBookReader.paragraphIsOpen()) { myBookReader.beginParagraph(); } switch (property) { case FONT_BOLD: if (myState.Bold) { myBookReader.pushKind(STRONG); } else { myBookReader.popKind(); } myBookReader.addControl(STRONG, myState.Bold); break; case FONT_ITALIC: if (myState.Italic) { if (!myState.Bold) { myBookReader.pushKind(EMPHASIS); myBookReader.addControl(EMPHASIS, true); } else { myBookReader.popKind(); myBookReader.addControl(STRONG, false); myBookReader.pushKind(EMPHASIS); myBookReader.addControl(EMPHASIS, true); myBookReader.pushKind(STRONG); myBookReader.addControl(STRONG, true); } } else { if (!myState.Bold) { myBookReader.addControl(EMPHASIS, false); myBookReader.popKind(); } else { myBookReader.addControl(STRONG, false); myBookReader.popKind(); myBookReader.addControl(EMPHASIS, false); myBookReader.popKind(); myBookReader.pushKind(STRONG); myBookReader.addControl(STRONG, true); } } break; case FONT_UNDERLINED: break; case FONT_SUBSCRIPT: //don't have to be mixed with other style tags if (myState.Subscript) { myBookReader.pushKind(SUB); } else { myBookReader.popKind(); } myBookReader.addControl(SUB, myState.Subscript); break; case FONT_SUPERSCRIPT: //Should not be mixed with other style tags if (myState.Superscript) { myBookReader.pushKind(SUP); } else { myBookReader.popKind(); } myBookReader.addControl(SUP, myState.Superscript); break; } } void PmlBookReader::newLine() { if (myBookReader.paragraphIsOpen()) { myBookReader.endParagraph(); } if (myParagraphIsEmpty) { myBookReader.beginParagraph(ZLTextParagraph::EMPTY_LINE_PARAGRAPH); myBookReader.endParagraph(); } else { myParagraphIsEmpty = true; } newParagraph(); } void PmlBookReader::newPage() { if (myBookReader.paragraphIsOpen()) { myBookReader.endParagraph(); } //newLine(); newParagraph(); } void PmlBookReader::newParagraph() { if (myBookReader.paragraphIsOpen()) { myBookReader.endParagraph(); } myBookReader.beginParagraph(); if (myState.Alignment != ALIGN_UNDEFINED) { setAlignment(); } if (myState.FontSize != NORMAL) { setFontSize(); } if (myState.IndentBlockOn && (myState.Indent != 0)) { setIndent(); } } void PmlBookReader::setAlignment() { ZLTextStyleEntry entry(ZLTextStyleEntry::STYLE_OTHER_ENTRY); entry.setAlignmentType(myState.Alignment); myBookReader.addStyleEntry(entry); } void PmlBookReader::setIndent() { ZLTextStyleEntry entry(ZLTextStyleEntry::STYLE_OTHER_ENTRY); entry.setLength(ZLTextStyleEntry::LENGTH_FIRST_LINE_INDENT_DELTA, 0, ZLTextStyleEntry::SIZE_UNIT_PERCENT); entry.setLength(ZLTextStyleEntry::LENGTH_LEFT_INDENT, (short)myState.Indent, ZLTextStyleEntry::SIZE_UNIT_PERCENT); myBookReader.addStyleEntry(entry); } void PmlBookReader::setFontSize() { if (!myBookReader.paragraphIsOpen()) { myBookReader.beginParagraph(); } ZLTextStyleEntry entry(ZLTextStyleEntry::STYLE_OTHER_ENTRY); switch(myState.FontSize) { case SMALLER: entry.setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_SMALLER, true); break; case LARGER: entry.setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_LARGER, true); break; default: break; } myBookReader.addStyleEntry(entry); } void PmlBookReader::addLink(FBTextKind kind, const std::string &id, bool on) { switch (kind) { case INTERNAL_HYPERLINK: case FOOTNOTE: //case EXTERNAL_HYPERLINK: //case BOOK_HYPERLINK: if (on) { myBookReader.addHyperlinkControl(kind, id); } else { myBookReader.addControl(kind, false); } break; default: break; } } void PmlBookReader::addLinkLabel(const std::string &label) { myBookReader.addHyperlinkLabel(label); } void PmlBookReader::addImageReference(const std::string &id) { const bool stopParagraph = myBookReader.paragraphIsOpen(); if (stopParagraph) { myBookReader.endParagraph(); } myBookReader.addImageReference(id); if (stopParagraph) { myBookReader.beginParagraph(); } }