From e874d39878309e456c7ffe8d5fc6a91be571b50c Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sun, 14 Aug 2022 03:00:41 +0000 Subject: CTAN sync 202208140300 --- dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp | 174 +++----------------------- 1 file changed, 15 insertions(+), 159 deletions(-) (limited to 'dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp') diff --git a/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp b/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp index 077e030776..1acef64f0e 100644 --- a/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp +++ b/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp @@ -153,19 +153,19 @@ bool DvisvgmSpecialHandler::process (const string &prefix, istream &is, SpecialA static void expand_constants (string &str, SpecialActions &actions) { bool repl_bbox = true; while (repl_bbox) { - size_t pos = str.find("{?bbox "); + const auto pos = str.find("{?bbox "); if (pos == string::npos) repl_bbox = false; else { - size_t endpos = pos+7; + auto endpos = pos+7; while (endpos < str.length() && isalnum(str[endpos])) ++endpos; - if (str[endpos] == '}') { - BoundingBox &box=actions.bbox(str.substr(pos+7, endpos-pos-7)); + if (str[endpos] != '}') + repl_bbox = false; + else { + BoundingBox &box = actions.bbox(str.substr(pos+7, endpos-pos-7)); str.replace(pos, endpos-pos+1, box.svgViewBoxString()); } - else - repl_bbox = false; } } struct Constant { @@ -181,7 +181,7 @@ static void expand_constants (string &str, SpecialActions &actions) { }}; for (const Constant &constant : constants) { const string pattern = string("{?")+constant.name+"}"; - size_t pos = str.find(pattern); + auto pos = str.find(pattern); while (pos != string::npos) { str.replace(pos, strlen(constant.name)+3, constant.val); pos = str.find(pattern, pos+constant.val.length()); // look for further matches @@ -194,9 +194,9 @@ static void expand_constants (string &str, SpecialActions &actions) { * and replaces the substring by the computed value. * @param[in,out] str string to scan for expressions */ static void evaluate_expressions (string &str, const SpecialActions &actions) { - size_t left = str.find("{?("); // start position of expression macro + auto left = str.find("{?("); // start position of expression macro while (left != string::npos) { - size_t right = str.find(")}", left+2); // end position of expression macro + auto right = str.find(")}", left+2); // end position of expression macro if (right == string::npos) break; Calculator calc; @@ -232,7 +232,7 @@ void DvisvgmSpecialHandler::processRaw (InputReader &ir, SpecialActions &actions if (!xml.empty()) { evaluate_expressions(xml, actions); expand_constants(xml, actions); - _pageParser.parse(xml, actions); + _pageParser.parse(xml, actions.svgTree()); } } } @@ -244,7 +244,7 @@ void DvisvgmSpecialHandler::processRawDef (InputReader &ir, SpecialActions &acti if (!xml.empty()) { evaluate_expressions(xml, actions); expand_constants(xml, actions); - _defsParser.parse(xml, actions); + _defsParser.parse(xml, actions.svgTree()); } } } @@ -276,9 +276,9 @@ void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions &acti if ((type == 'P' || type == 'D') && !def.empty()) { expand_constants(def, actions); if (type == 'P') - _pageParser.parse(def, actions); + _pageParser.parse(def, actions.svgTree()); else { // type == 'D' - _defsParser.parse(def, actions); + _defsParser.parse(def, actions.svgTree()); type = 'L'; // locked } } @@ -414,8 +414,8 @@ void DvisvgmSpecialHandler::dviPreprocessingFinished () { void DvisvgmSpecialHandler::dviEndPage (unsigned, SpecialActions &actions) { - _defsParser.finish(actions); - _pageParser.finish(actions); + _defsParser.finish(actions.svgTree()); + _pageParser.finish(actions.svgTree()); actions.bbox().unlock(); for (auto &strvecpair : _macros) { StringVector &vec = strvecpair.second; @@ -432,147 +432,3 @@ vector DvisvgmSpecialHandler::prefixes() const { vector pfx {"dvisvgm:"}; return pfx; } - -//////////////////////////////////////////////////////////////////////////////// - -/** Parses a fragment of XML code, creates corresponding XML nodes and adds them - * to the SVG tree. The code may be split and processed by several calls of this - * function. Incomplete chunks that can't be processed yet are stored and picked - * up again together with the next incoming XML fragment. If a call of this function - * is supposed to finish the parsing of an XML subtree, parameter 'finish' must be set. - * @param[in] xml XML fragment to parse - * @param[in] actions object providing the SVG tree functions - * @param[in] finish if true, no more XML is expected and parsing is finished */ -void DvisvgmSpecialHandler::XMLParser::parse (const string &xml, SpecialActions &actions, bool finish) { - // collect/extract an XML fragment that only contains complete tags - // incomplete tags are held back - _xmlbuf += xml; - size_t left=0; - try { - while (left != string::npos) { - size_t right = _xmlbuf.find('<', left); - if (left < right && left < _xmlbuf.length()) // plain text found? - (actions.svgTree().*_append)(util::make_unique(_xmlbuf.substr(left, right-left))); - if (right != string::npos) { - left = right; - if (_xmlbuf.compare(left, 9, "", left+9); - if (right == string::npos) { - if (finish) throw SpecialException("expected ']]>' at end of CDATA block"); - break; - } - (actions.svgTree().*_append)(util::make_unique(_xmlbuf.substr(left+9, right-left-9))); - right += 2; - } - else if (_xmlbuf.compare(left, 4, "", left+4); - if (right == string::npos) { - if (finish) throw SpecialException("expected '-->' at end of comment"); - break; - } - (actions.svgTree().*_append)(util::make_unique(_xmlbuf.substr(left+4, right-left-4))); - right += 2; - } - else if (_xmlbuf.compare(left, 2, "", left+2); - if (right == string::npos) { - if (finish) throw SpecialException("expected '?>' at end of processing instruction"); - break; - } - (actions.svgTree().*_append)(util::make_unique(_xmlbuf.substr(left, right-left+2))); - right++; - } - else if (_xmlbuf.compare(left, 2, "', left+2); - if (right == string::npos) { - if (finish) throw SpecialException("missing '>' at end of closing XML tag"); - break; - } - closeElement(_xmlbuf.substr(left+2, right-left-2), actions); - } - else { - right = _xmlbuf.find('>', left+1); - if (right == string::npos) { - if (finish) throw SpecialException("missing '>' or '/>' at end of opening XML tag"); - break; - } - openElement(_xmlbuf.substr(left+1, right-left-1), actions); - } - } - left = right; - if (right != string::npos) - left++; - } - } - catch (const SpecialException &e) { - _error = true; - throw; - } - if (left == string::npos) - _xmlbuf.clear(); - else - _xmlbuf.erase(0, left); -} - - -/** Processes an opening element tag. - * @param[in] tag tag without leading and trailing angle brackets */ -void DvisvgmSpecialHandler::XMLParser::openElement (const string &tag, SpecialActions &actions) { - StringInputBuffer ib(tag); - BufferInputReader ir(ib); - string name = ir.getString("/ \t\n\r"); - ir.skipSpace(); - auto elemNode = util::make_unique(name); - map attribs; - if (ir.parseAttributes(attribs, true, "\"'")) { - for (const auto &attrpair : attribs) - elemNode->addAttribute(attrpair.first, attrpair.second); - } - ir.skipSpace(); - if (ir.peek() == '/') // end of empty element tag - (actions.svgTree().*_append)(std::move(elemNode)); - else if (ir.peek() < 0) { // end of opening tag - _nameStack.push_back(name); - (actions.svgTree().*_pushContext)(std::move(elemNode)); - } - else - throw SpecialException("'>' or '/>' expected at end of opening tag <"+name); -} - - -/** Processes a closing element tag. - * @param[in] tag tag without leading and trailing angle brackets */ -void DvisvgmSpecialHandler::XMLParser::closeElement (const string &tag, SpecialActions &actions) { - StringInputBuffer ib(tag); - BufferInputReader ir(ib); - string name = ir.getString(" \t\n\r"); - ir.skipSpace(); - if (ir.peek() >= 0) - throw SpecialException("'>' expected at end of closing tag "); - if (_nameStack.back() != name) - throw SpecialException("expected but found "); - (actions.svgTree().*_popContext)(); - _nameStack.pop_back(); -} - - -/** Processes any remaining XML fragments, checks for missing closing tags, - * and resets the parser state. */ -void DvisvgmSpecialHandler::XMLParser::finish (SpecialActions &actions) { - if (!_xmlbuf.empty()) { - if (!_error) - parse("", actions, true); - _xmlbuf.clear(); - } - string tags; - while (!_nameStack.empty()) { - tags += ", "; - _nameStack.pop_back(); - } - if (!tags.empty() && !_error) { - tags.resize(tags.length()-2); - throw SpecialException("missing closing tag(s): "+tags); - } -} -- cgit v1.2.3