@@ -74,41 +74,50 @@ enum class ExplicitPageResult
7474// -----------
7575
7676// is character c part of an identifier?
77- #define isIdChar (c ) \
78- ((c>=' a' && c<=' z' ) || \
79- (c>=' A' && c<=' Z' ) || \
80- (c>=' 0' && c<=' 9' ) || \
81- (static_cast <unsigned char >(c)>=0x80 )) // unicode characters
77+ static constexpr bool isIdChar (char c)
78+ {
79+ return (c>=' a' && c<=' z' ) ||
80+ (c>=' A' && c<=' Z' ) ||
81+ (c>=' 0' && c<=' 9' ) ||
82+ (static_cast <unsigned char >(c)>=0x80 ); // unicode characters
83+ }
8284
8385// is character allowed right at the beginning of an emphasis section
84- # define extraChar (c ) \
85- (c== ' - ' || c== ' + ' || c== ' ! ' || \
86- c==' ?' || c==' $' || c==' @' || \
87- c==' &' || c==' *' || c==' _' || c==' %' || \
88- c==' [ ' || c==' ( ' || c==' . ' || \
89- c== ' > ' || c==' : ' || c==' , ' || \
90- c== ' ; ' || c== ' \' ' || c== ' " ' || c== ' ` ' )
86+ static constexpr bool extraChar (char c)
87+ {
88+ return c==' - ' || c== ' + ' || c== ' ! ' || c== ' ?' || c==' $' || c==' @' ||
89+ c==' &' || c==' *' || c==' _' || c==' %' || c== ' [ ' || c== ' ( ' ||
90+ c==' . ' || c==' > ' || c==' : ' || c== ' , ' || c== ' ; ' || c== ' \' ' ||
91+ c==' " ' || c==' ` ' ;
92+ }
9193
9294// is character c allowed before an emphasis section
93- #define isOpenEmphChar (c ) \
94- (c==' \n ' || c==' ' || c==' \' ' || c==' <' || \
95- c==' >' || c==' {' || c==' (' || c==' [' || \
96- c==' ,' || c==' :' || c==' ;' )
95+ static constexpr bool isOpenEmphChar (char c)
96+ {
97+ return c==' \n ' || c==' ' || c==' \' ' || c==' <' ||
98+ c==' >' || c==' {' || c==' (' || c==' [' ||
99+ c==' ,' || c==' :' || c==' ;' ;
100+ }
97101
98102// test for non breakable space (UTF-8)
99- #define isUtf8Nbsp (c1,c2 ) \
100- (c1==static_cast <char >(0xc2 ) && c2==static_cast <char >(0xa0 ))
101-
102- #define isAllowedEmphStr (data,offset ) \
103- ((offset>0 && !isOpenEmphChar(data.data()[-1 ])) && \
104- (offset>1 && !isUtf8Nbsp(data.data()[-2 ],data.data()[-1 ])))
105-
106- // is character at position i in data an escape that prevents ending an emphasis section
107- // so for example *bla (*.txt) is cool*
108- #define ignoreCloseEmphChar (c,cn ) \
109- (c==' (' || c==' {' || c==' [' || (c==' <' && cn!=' /' ) || \
110- c==' \\ ' || \
111- c==' @' )
103+ static constexpr bool isUtf8Nbsp (char c1,char c2)
104+ {
105+ return c1==static_cast <char >(0xc2 ) && c2==static_cast <char >(0xa0 );
106+ }
107+
108+ static constexpr bool isAllowedEmphStr (const std::string_view &data,size_t offset)
109+ {
110+ return ((offset>0 && !isOpenEmphChar (data.data ()[-1 ])) &&
111+ (offset>1 && !isUtf8Nbsp (data.data ()[-2 ],data.data ()[-1 ])));
112+ }
113+
114+ // is character c an escape that prevents ending an emphasis section
115+ // so for example *bla (*.txt) is cool*, the c=='(' prevents '*' from ending the emphasis section.
116+ static constexpr bool ignoreCloseEmphChar (char c,char cn)
117+ {
118+ return c==' (' || c==' {' || c==' [' || (c==' <' && cn!=' /' ) || c==' \\ ' || c==' @' ;
119+ }
120+
112121// ----------
113122
114123struct TableCell
@@ -120,22 +129,7 @@ struct TableCell
120129
121130struct Markdown ::Private
122131{
123- Private (const QCString &fn,int line,int indent)
124- : fileName(fn), lineNr(line), indentLevel(indent)
125- {
126- // setup callback table for special characters
127- actions[static_cast <unsigned int >(' _' )] = [this ](std::string_view data,size_t offset) { return processEmphasis (data,offset); };
128- actions[static_cast <unsigned int >(' *' )] = [this ](std::string_view data,size_t offset) { return processEmphasis (data,offset); };
129- actions[static_cast <unsigned int >(' ~' )] = [this ](std::string_view data,size_t offset) { return processEmphasis (data,offset); };
130- actions[static_cast <unsigned int >(' `' )] = [this ](std::string_view data,size_t offset) { return processCodeSpan (data,offset); };
131- actions[static_cast <unsigned int >(' \\ ' )]= [this ](std::string_view data,size_t offset) { return processSpecialCommand (data,offset); };
132- actions[static_cast <unsigned int >(' @' )] = [this ](std::string_view data,size_t offset) { return processSpecialCommand (data,offset); };
133- actions[static_cast <unsigned int >(' [' )] = [this ](std::string_view data,size_t offset) { return processLink (data,offset); };
134- actions[static_cast <unsigned int >(' !' )] = [this ](std::string_view data,size_t offset) { return processLink (data,offset); };
135- actions[static_cast <unsigned int >(' <' )] = [this ](std::string_view data,size_t offset) { return processHtmlTag (data,offset); };
136- actions[static_cast <unsigned int >(' -' )] = [this ](std::string_view data,size_t offset) { return processNmdash (data,offset); };
137- actions[static_cast <unsigned int >(' "' )] = [this ](std::string_view data,size_t offset) { return processQuoted (data,offset); };
138- }
132+ Private (const QCString &fn,int line,int indent) : fileName(fn), lineNr(line), indentLevel(indent) { }
139133
140134 QCString processQuotations (std::string_view data,size_t refIndent);
141135 QCString processBlocks (std::string_view data,size_t indent);
@@ -177,16 +171,33 @@ struct Markdown::Private
177171 QCString link;
178172 QCString title;
179173 };
180- using Action_t = std::function<int (std::string_view,size_t )>;
181174
182175 std::unordered_map<std::string,LinkRef> linkRefs;
183176 QCString fileName;
184177 int lineNr = 0 ;
185178 int indentLevel=0 ; // 0 is outside markdown, -1=page level
186179 QCString out;
187- std::array<Action_t,256 > actions;
188180};
189181
182+ Markdown::ActionTable_t Markdown::fill_table ()
183+ {
184+ Markdown::ActionTable_t a{};
185+ a[static_cast <unsigned int >(' _' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processEmphasis (data,offset); };
186+ a[static_cast <unsigned int >(' *' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processEmphasis (data,offset); };
187+ a[static_cast <unsigned int >(' ~' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processEmphasis (data,offset); };
188+ a[static_cast <unsigned int >(' `' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processCodeSpan (data,offset); };
189+ a[static_cast <unsigned int >(' \\ ' )]= [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processSpecialCommand (data,offset); };
190+ a[static_cast <unsigned int >(' @' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processSpecialCommand (data,offset); };
191+ a[static_cast <unsigned int >(' [' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processLink (data,offset); };
192+ a[static_cast <unsigned int >(' !' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processLink (data,offset); };
193+ a[static_cast <unsigned int >(' <' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processHtmlTag (data,offset); };
194+ a[static_cast <unsigned int >(' -' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processNmdash (data,offset); };
195+ a[static_cast <unsigned int >(' "' )] = [](Markdown::Private &obj,std::string_view data,size_t offset) { return obj.processQuoted (data,offset); };
196+ return a;
197+ }
198+ Markdown::ActionTable_t Markdown::actions = Markdown::fill_table();
199+
200+
190201Markdown::Markdown (const QCString &fileName,int lineNr,int indentLevel)
191202 : prv(std::make_unique<Private>(fileName,lineNr,indentLevel))
192203{
@@ -198,15 +209,14 @@ Markdown::~Markdown() = default;
198209
199210void Markdown::setIndentLevel (int level) { prv->indentLevel = level; }
200211
201-
202- enum Alignment { AlignNone, AlignLeft, AlignCenter, AlignRight };
212+ enum class Alignment { None, Left, Center, Right };
203213
204214
205215// ---------- constants -------
206216//
207- const char *g_utf8_nbsp = " \xc2\xa0 " ; // UTF-8 nbsp
208- const char *g_doxy_nbsp = " &_doxy_nbsp;" ; // doxygen escape command for UTF-8 nbsp
209- const size_t codeBlockIndent = 4 ;
217+ static const char *g_utf8_nbsp = " \xc2\xa0 " ; // UTF-8 nbsp
218+ static const char *g_doxy_nbsp = " &_doxy_nbsp;" ; // doxygen escape command for UTF-8 nbsp
219+ static const size_t codeBlockIndent = 4 ;
210220
211221// ---------- helpers -------
212222
@@ -307,23 +317,23 @@ static QCString escapeSpecialChars(const QCString &s)
307317/* * helper function to convert presence of left and/or right alignment markers
308318 * to an alignment value
309319 */
310- static Alignment markersToAlignment (bool leftMarker,bool rightMarker)
320+ static constexpr Alignment markersToAlignment (bool leftMarker,bool rightMarker)
311321{
312322 if (leftMarker && rightMarker)
313323 {
314- return AlignCenter ;
324+ return Alignment::Center ;
315325 }
316326 else if (leftMarker)
317327 {
318- return AlignLeft ;
328+ return Alignment::Left ;
319329 }
320330 else if (rightMarker)
321331 {
322- return AlignRight ;
332+ return Alignment::Right ;
323333 }
324334 else
325335 {
326- return AlignNone ;
336+ return Alignment::None ;
327337 }
328338}
329339
@@ -377,23 +387,24 @@ static QCString getFilteredImageAttributes(std::string_view fmt, const QCString
377387// \startuml..\enduml
378388QCString Markdown::Private::isBlockCommand (std::string_view data,size_t offset)
379389{
390+ QCString result;
380391 AUTO_TRACE (" data='{}' offset={}" ,Trace::trunc (data),offset);
381392
382393 using EndBlockFunc = QCString (*)(const std::string &,bool ,char );
383394
384- static const auto getEndBlock = [](const std::string &blockName,bool ,char ) -> QCString
395+ static constexpr auto getEndBlock = [](const std::string &blockName,bool ,char ) -> QCString
385396 {
386397 return " end" +blockName;
387398 };
388- static const auto getEndCode = [](const std::string &blockName,bool openBracket,char ) -> QCString
399+ static constexpr auto getEndCode = [](const std::string &blockName,bool openBracket,char ) -> QCString
389400 {
390401 return openBracket ? QCString (" }" ) : " end" +blockName;
391402 };
392- static const auto getEndUml = [](const std::string &/* blockName */ ,bool ,char ) -> QCString
403+ static constexpr auto getEndUml = [](const std::string &/* blockName */ ,bool ,char ) -> QCString
393404 {
394405 return " enduml" ;
395406 };
396- static const auto getEndFormula = [](const std::string &/* blockName */ ,bool ,char nextChar) -> QCString
407+ static constexpr auto getEndFormula = [](const std::string &/* blockName */ ,bool ,char nextChar) -> QCString
397408 {
398409 switch (nextChar)
399410 {
@@ -428,14 +439,13 @@ QCString Markdown::Private::isBlockCommand(std::string_view data,size_t offset)
428439 const size_t size = data.size ();
429440 bool openBracket = offset>0 && data.data ()[-1 ]==' {' ;
430441 bool isEscaped = offset>0 && (data.data ()[-1 ]==' \\ ' || data.data ()[-1 ]==' @' );
431- if (isEscaped) return QCString () ;
442+ if (isEscaped) return result ;
432443
433444 size_t end=1 ;
434445 while (end<size && (data[end]>=' a' && data[end]<=' z' )) end++;
435- if (end==1 ) return QCString () ;
446+ if (end==1 ) return result ;
436447 std::string blockName (data.substr (1 ,end-1 ));
437448 auto it = blockNames.find (blockName);
438- QCString result;
439449 if (it!=blockNames.end ()) // there is a function assigned
440450 {
441451 result = it->second (blockName, openBracket, end<size ? data[end] : 0 );
@@ -450,7 +460,7 @@ size_t Markdown::Private::isSpecialCommand(std::string_view data,size_t offset)
450460
451461 using EndCmdFunc = size_t (*)(std::string_view,size_t );
452462
453- static const auto endOfLine = [](std::string_view data_,size_t offset_) -> size_t
463+ static constexpr auto endOfLine = [](std::string_view data_,size_t offset_) -> size_t
454464 {
455465 // skip until the end of line (allowing line continuation characters)
456466 char lc = 0 ;
@@ -464,7 +474,7 @@ size_t Markdown::Private::isSpecialCommand(std::string_view data,size_t offset)
464474 return offset_;
465475 };
466476
467- static const auto endOfLabels = [](std::string_view data_,size_t offset_,bool multi_) -> size_t
477+ static constexpr auto endOfLabels = [](std::string_view data_,size_t offset_,bool multi_) -> size_t
468478 {
469479 if (offset_<data_.size () && data_[offset_]==' ' ) // we expect a space before the label
470480 {
@@ -510,12 +520,12 @@ size_t Markdown::Private::isSpecialCommand(std::string_view data,size_t offset)
510520 return 0 ;
511521 };
512522
513- static const auto endOfLabel = [](std::string_view data_,size_t offset_) -> size_t
523+ static constexpr auto endOfLabel = [](std::string_view data_,size_t offset_) -> size_t
514524 {
515525 return endOfLabels (data_,offset_,false );
516526 };
517527
518- static const auto endOfLabelOpt = [](std::string_view data_,size_t offset_) -> size_t
528+ static constexpr auto endOfLabelOpt = [](std::string_view data_,size_t offset_) -> size_t
519529 {
520530 size_t index=offset_;
521531 if (index<data_.size () && data_[index]==' ' ) // skip over optional spaces
@@ -534,7 +544,7 @@ size_t Markdown::Private::isSpecialCommand(std::string_view data,size_t offset)
534544 return endOfLabel (data_,offset_);
535545 };
536546
537- static const auto endOfParam = [](std::string_view data_,size_t offset_) -> size_t
547+ static constexpr auto endOfParam = [](std::string_view data_,size_t offset_) -> size_t
538548 {
539549 size_t index=offset_;
540550 if (index<data_.size () && data_[index]==' ' ) // skip over optional spaces
@@ -553,12 +563,12 @@ size_t Markdown::Private::isSpecialCommand(std::string_view data,size_t offset)
553563 return endOfLabels (data_,offset_,true );
554564 };
555565
556- static const auto endOfRetVal = [](std::string_view data_,size_t offset_) -> size_t
566+ static constexpr auto endOfRetVal = [](std::string_view data_,size_t offset_) -> size_t
557567 {
558568 return endOfLabels (data_,offset_,true );
559569 };
560570
561- static const auto endOfFuncLike = [](std::string_view data_,size_t offset_,bool allowSpaces) -> size_t
571+ static constexpr auto endOfFuncLike = [](std::string_view data_,size_t offset_,bool allowSpaces) -> size_t
562572 {
563573 if (offset_<data_.size () && data_[offset_]==' ' ) // we expect a space before the name
564574 {
@@ -591,12 +601,12 @@ size_t Markdown::Private::isSpecialCommand(std::string_view data,size_t offset)
591601 return 0 ;
592602 };
593603
594- static const auto endOfFunc = [](std::string_view data_,size_t offset_) -> size_t
604+ static constexpr auto endOfFunc = [](std::string_view data_,size_t offset_) -> size_t
595605 {
596606 return endOfFuncLike (data_,offset_,true );
597607 };
598608
599- static const auto endOfGuard = [](std::string_view data_,size_t offset_) -> size_t
609+ static constexpr auto endOfGuard = [](std::string_view data_,size_t offset_) -> size_t
600610 {
601611 return endOfFuncLike (data_,offset_,false );
602612 };
@@ -1854,13 +1864,13 @@ void Markdown::Private::processInline(std::string_view data)
18541864 while (i<size)
18551865 {
18561866 // skip over characters that do not trigger a specific action
1857- while (end<size && ((action=actions[static_cast <uint8_t >(data[end])])==nullptr )) end++;
1867+ while (end<size && ((action=Markdown:: actions[static_cast <uint8_t >(data[end])])==nullptr )) end++;
18581868 // and add them to the output
18591869 out+=data.substr (i,end-i);
18601870 if (end>=size) break ;
18611871 i=end;
18621872 // do the action matching a special character at i
1863- int iend = action (data.substr (i),i);
1873+ int iend = action (* this , data.substr (i),i);
18641874 if (iend<=0 ) // update end
18651875 {
18661876 end=i+1 -iend;
@@ -2562,7 +2572,7 @@ size_t Markdown::Private::writeTableBlock(std::string_view data)
25622572 size_t cc = 0 ;
25632573 size_t ret = findTableColumns (data.substr (i),start,end,cc);
25642574 size_t k=0 ;
2565- std::vector<int > columnAlignment (columns);
2575+ std::vector<Alignment > columnAlignment (columns);
25662576
25672577 bool leftMarker=false , rightMarker=false , startFound=false ;
25682578 size_t j=start+i;
@@ -2706,10 +2716,10 @@ size_t Markdown::Private::writeTableBlock(std::string_view data)
27062716 // use appropriate alignment style
27072717 switch (columnAlignment[c])
27082718 {
2709- case AlignLeft : out+=" Left\" " ; break ;
2710- case AlignRight : out+=" Right\" " ; break ;
2711- case AlignCenter : out+=" Center\" " ; break ;
2712- case AlignNone : out+=" None\" " ; break ;
2719+ case Alignment::Left : out+=" Left\" " ; break ;
2720+ case Alignment::Right : out+=" Right\" " ; break ;
2721+ case Alignment::Center : out+=" Center\" " ; break ;
2722+ case Alignment::None : out+=" None\" " ; break ;
27132723 }
27142724
27152725 if (rowSpan > 1 )
0 commit comments