diff options
-rw-r--r-- | src/docparser.cpp | 2 | ||||
-rw-r--r-- | src/htmlhelp.cpp | 2 | ||||
-rw-r--r-- | src/rtfstyle.cpp | 211 | ||||
-rw-r--r-- | src/rtfstyle.h | 4 |
4 files changed, 94 insertions, 125 deletions
diff --git a/src/docparser.cpp b/src/docparser.cpp index 6c10bdb..725cee0 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -876,7 +876,7 @@ static int handleStyleArgument(DocNode *parent,DocNodeList &children, { static std::regex specialChar("[.,|()\\[\\]:;\\?]"); if (tok==TK_WORD && g_token->name.length()==1 && - std::regex_match(g_token->name.str(),specialChar)) + std::regex_search(g_token->name.str(),specialChar)) { // special character that ends the markup command return tok; diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp index 1d7f888..b020bb0 100644 --- a/src/htmlhelp.cpp +++ b/src/htmlhelp.cpp @@ -157,7 +157,7 @@ void HtmlHelpIndex::addItem(const char *level1,const char *level2, static std::regex re("@[[:digit:]]+"); std::string key = level1; if (level2) key+= std::string("?") + level2; - if (std::regex_match(key,re)) // skip anonymous stuff + if (std::regex_search(key,re)) // skip anonymous stuff { return; } diff --git a/src/rtfstyle.cpp b/src/rtfstyle.cpp index 4b01002..e8643fb 100644 --- a/src/rtfstyle.cpp +++ b/src/rtfstyle.cpp @@ -1,9 +1,6 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2021 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby @@ -16,15 +13,13 @@ * */ -#include <stdlib.h> -#include <qfile.h> -#include <qregexp.h> -#include <qtextstream.h> +#include <regex> +#include <string> +#include <fstream> #include "rtfstyle.h" #include "message.h" - RTFListItemInfo rtf_listItemInfo[rtf_maxIndentLevels]; QCString rtf_title; @@ -38,6 +33,21 @@ QCString rtf_documentType; QCString rtf_documentId; QCString rtf_keywords; +static std::map<std::string,QCString &> g_styleMap = +{ + { "Title", rtf_title }, + { "Subject", rtf_subject }, + { "Comments", rtf_comments }, + { "Company", rtf_company }, + { "LogoFilename", rtf_logoFilename }, + { "Author", rtf_author }, + { "Manager", rtf_manager }, + { "DocumentType", rtf_documentType }, + { "DocumentId", rtf_documentId }, + { "Keywords", rtf_keywords } +}; + + char rtf_Style_Reset[] = "\\pard\\plain "; #define RTF_LatexToc(lvl,nest,nxt,pos,twps) \ @@ -224,116 +234,80 @@ Rtf_Style_Default rtf_Style_Default[] = } }; -static const QRegExp s_clause("\\\\s[0-9]+\\s*"); +static const std::regex s_clause("\\\\s([[:digit:]]+)[[:space:]]*"); -StyleData::StyleData(const char* reference, const char* definition) +StyleData::StyleData(const std::string &reference, const std::string &definition) { - const char *ref = reference; - - int start = s_clause.match(ref); ASSERT(start >= 0); - ref += start; - m_index = (int)atol(ref + 2); ASSERT(m_index > 0); - - m_reference = ref; + std::smatch match; + if (regex_search(reference,match,s_clause)) + { + m_index = static_cast<int>(std::stoul(match[1].str())); + } + else // error + { + m_index = 0; + } + m_reference = reference; m_definition = definition; } -bool StyleData::setStyle(const char* s, const char* styleName) +bool StyleData::setStyle(const std::string &command, const std::string &styleName) { - static const QRegExp subgroup("^{[^}]*}\\s*"); - static const QRegExp any_clause("^\\\\[a-z][a-z0-9-]*\\s*"); - - int len = 0; // length of a particular RTF formatting control - int ref_len = 0; // length of the whole formatting section of a style - int start = s_clause.match(s, 0, &len); - if (start < 0) + std::smatch match; + if (!regex_search(command,match,s_clause)) { - err("Style sheet '%s' contains no '\\s' clause.\n{%s}\n", styleName, s); - return FALSE; - } - s += start; - m_index = (int)atol(s + 2); ASSERT(m_index > 0); - - // search for the end of pure formatting codes - const char* end = s + len; - ref_len = len; - bool haveNewDefinition = TRUE; - for(;;) - { - if (*end == '{') - { - // subgroups are used for \\additive - if (0 != subgroup.match(end, 0, &len)) - break; - else - { - end += len; - ref_len += len; - } - } - else if (*end == '\\') - { - if (0 == qstrncmp(end, "\\snext", 6)) - break; - if (0 == qstrncmp(end, "\\sbasedon", 9)) - break; - if (0 != any_clause.match(end, 0, &len)) - break; - end += len; - ref_len += len; - } - else if (*end == 0) - { // no style-definition part, keep default value - haveNewDefinition = FALSE; - break; - } - else // plain name without leading \\snext - break; + err("Style sheet '%s' contains no '\\s' clause.\n{%s}", styleName.c_str(), command.c_str()); + return false; } - m_reference = s; - if (haveNewDefinition) + m_index = static_cast<int>(std::stoul(match[1].str())); + + static std::regex definition_splitter("^(.*)(\\\\sbasedon[[:digit:]]+.*)$"); + if (regex_match(command,match,definition_splitter)) { - m_definition = end; + m_reference = match[1].str(); + m_definition = match[2].str(); } - return TRUE; + + return true; } + void loadStylesheet(const char *name, StyleDataMap& map) { - QFile file(name); - if (!file.open(IO_ReadOnly)) + std::ifstream file(name); + if (!file.is_open()) { - err("Can't open RTF style sheet file %s. Using defaults.\n",name); + err("Can't open RTF style sheet file %s. Using defaults.",name); return; } msg("Loading RTF style sheet %s...\n",name); - static const QRegExp separator("[ \t]*=[ \t]*"); uint lineNr=1; - QTextStream t(&file); - while (!t.eof()) + for (std::string line ; getline(file,line) ; ) // for each line { - QCString s(4096); // string buffer of max line length - s = t.readLine().stripWhiteSpace().utf8(); - if (s.isEmpty() || s.at(0)=='#') continue; // skip blanks & comments - int sepLength; - int sepStart = separator.match(s,0,&sepLength); - if (sepStart<=0) // no valid assignment statement + if (line.empty() || line[0]=='#') continue; // skip blanks & comments + static std::regex assignment_splitter("[[:space:]]*=[[:space:]]*"); + std::smatch match; + if (std::regex_search(line,match,assignment_splitter)) { - warn(name,lineNr,"Assignment of style sheet name expected!\n"); - continue; + std::string key = match.prefix(); + std::string value = match.suffix(); + auto it = map.find(key); + if (it!=map.end()) + { + StyleData& styleData = it->second; + styleData.setStyle(value,key); + } + else + { + warn(name,lineNr,"Unknown style sheet name %s ignored.",key.data()); + } } - QCString key=s.left(sepStart); - auto it = map.find(key.str()); - if (it==map.end()) // not a valid style sheet name + else { - warn(name,lineNr,"Unknown style sheet name %s ignored.\n",key.data()); - continue; + warn(name,lineNr,"Assignment of style sheet name expected line='%s'!",line.c_str()); } - StyleData& styleData = it->second; - s+=" "; // add command separator - styleData.setStyle(s.data() + sepStart + sepLength, key.data()); lineNr++; } } @@ -342,44 +316,39 @@ StyleDataMap rtf_Style; void loadExtensions(const char *name) { - QFile file(name); - if (!file.open(IO_ReadOnly)) + std::ifstream file(name); + if (!file.is_open()) { - err("Can't open RTF extensions file %s. Using defaults.\n",name); + err("Can't open RTF extensions file %s. Using defaults.",name); return; } msg("Loading RTF extensions %s...\n",name); - static const QRegExp separator("[ \t]*=[ \t]*"); uint lineNr=1; - QTextStream t(&file); - t.setEncoding(QTextStream::UnicodeUTF8); - while (!t.eof()) + for (std::string line ; getline(file,line) ; ) // for each line { - QCString s(4096); // string buffer of max line length - s = t.readLine().stripWhiteSpace().utf8(); - if (s.length()==0 || s.at(0)=='#') continue; // skip blanks & comments - int sepLength; - int sepStart = separator.match(s,0,&sepLength); - if (sepStart<=0) // no valid assignment statement + if (line.empty() || line[0]=='#') continue; // skip blanks & comments + std::smatch match; + static std::regex assignment_splitter("[[:space:]]*=[[:space:]]*"); + if (std::regex_search(line,match,assignment_splitter)) + { + std::string key = match.prefix(); + std::string value = match.suffix(); + auto it = g_styleMap.find(key); + if (it!=g_styleMap.end()) + { + it->second = value; + } + else + { + warn(name,lineNr,"Ignoring unknown extension key '%s'...",key.c_str()); + } + } + else { - warn(name,lineNr,"Assignment of extension field expected!\n"); - continue; + warn(name,lineNr,"Assignment of style sheet name expected!"); } - QCString key=s.left(sepStart); - QCString data=s.data() + sepStart + sepLength; - - if (key == "Title") rtf_title = data.data(); - if (key == "Subject") rtf_subject = data.data(); - if (key == "Comments") rtf_comments = data.data(); - if (key == "Company") rtf_company = data.data(); - if (key == "LogoFilename") rtf_logoFilename = data.data(); - if (key == "Author") rtf_author = data.data(); - if (key == "Manager") rtf_manager = data.data(); - if (key == "DocumentType") rtf_documentType = data.data(); - if (key == "DocumentId") rtf_documentId = data.data(); - if (key == "Keywords") rtf_keywords = data.data(); lineNr++; } } diff --git a/src/rtfstyle.h b/src/rtfstyle.h index b3d04bd..140d31f 100644 --- a/src/rtfstyle.h +++ b/src/rtfstyle.h @@ -63,8 +63,8 @@ struct StyleData public: StyleData() = default; - StyleData(const char* reference, const char* definition); - bool setStyle(const char* s, const char* styleName); + StyleData(const std::string &reference, const std::string &definition); + bool setStyle(const std::string &command, const std::string &styleName); const char *reference() const { return m_reference.c_str(); } const char *definition() const { return m_definition.c_str(); } uint index() const { return m_index; } |