Skip to content

Commit ac3e545

Browse files
committed
issue #10466 Markdown: inline statements in page headings are escaped and render as text
1 parent 4f12e50 commit ac3e545

File tree

12 files changed

+100
-56
lines changed

12 files changed

+100
-56
lines changed

addon/doxmlparser/doxmlparser/compound.py

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8434,8 +8434,7 @@ def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='',
84348434
eol_ = ''
84358435
if self.title is not None:
84368436
namespaceprefix_ = self.title_nsprefix_ + ':' if (UseCapturedNS_ and self.title_nsprefix_) else ''
8437-
showIndent(outfile, level, pretty_print)
8438-
outfile.write('<%stitle>%s</%stitle>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.title), input_name='title')), namespaceprefix_ , eol_))
8437+
self.title.export(outfile, level, namespaceprefix_, namespacedef_='', name_='title', pretty_print=pretty_print)
84398438
for para_ in self.para:
84408439
namespaceprefix_ = self.para_nsprefix_ + ':' if (UseCapturedNS_ and self.para_nsprefix_) else ''
84418440
para_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='para', pretty_print=pretty_print)
@@ -8467,14 +8466,16 @@ def buildAttributes(self, node, attrs, already_processed):
84678466
already_processed.add('id')
84688467
self.id = value
84698468
def buildChildren(self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None):
8470-
if nodeName_ == 'title' and child_.text is not None:
8471-
valuestr_ = child_.text
8472-
valuestr_ = self.gds_parse_string(valuestr_, node, 'title')
8473-
valuestr_ = self.gds_validate_string(valuestr_, node, 'title')
8474-
obj_ = self.mixedclass_(MixedContainer.CategorySimple,
8475-
MixedContainer.TypeString, 'title', valuestr_)
8469+
if nodeName_ == 'title':
8470+
obj_ = docTitleType.factory(parent_object_=self)
8471+
obj_.build(child_, gds_collector_=gds_collector_)
8472+
obj_ = self.mixedclass_(MixedContainer.CategoryComplex,
8473+
MixedContainer.TypeNone, 'title', obj_)
84768474
self.content_.append(obj_)
8477-
self.title_nsprefix_ = child_.prefix
8475+
if hasattr(self, 'add_title'):
8476+
self.add_title(obj_.value)
8477+
elif hasattr(self, 'set_title'):
8478+
self.set_title(obj_.value)
84788479
elif nodeName_ == 'para':
84798480
obj_ = docParaType.factory(parent_object_=self)
84808481
obj_.build(child_, gds_collector_=gds_collector_)
@@ -8655,8 +8656,7 @@ def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='',
86558656
eol_ = ''
86568657
if self.title is not None:
86578658
namespaceprefix_ = self.title_nsprefix_ + ':' if (UseCapturedNS_ and self.title_nsprefix_) else ''
8658-
showIndent(outfile, level, pretty_print)
8659-
outfile.write('<%stitle>%s</%stitle>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.title), input_name='title')), namespaceprefix_ , eol_))
8659+
self.title.export(outfile, level, namespaceprefix_, namespacedef_='', name_='title', pretty_print=pretty_print)
86608660
for para_ in self.para:
86618661
namespaceprefix_ = self.para_nsprefix_ + ':' if (UseCapturedNS_ and self.para_nsprefix_) else ''
86628662
para_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='para', pretty_print=pretty_print)
@@ -8688,14 +8688,16 @@ def buildAttributes(self, node, attrs, already_processed):
86888688
already_processed.add('id')
86898689
self.id = value
86908690
def buildChildren(self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None):
8691-
if nodeName_ == 'title' and child_.text is not None:
8692-
valuestr_ = child_.text
8693-
valuestr_ = self.gds_parse_string(valuestr_, node, 'title')
8694-
valuestr_ = self.gds_validate_string(valuestr_, node, 'title')
8695-
obj_ = self.mixedclass_(MixedContainer.CategorySimple,
8696-
MixedContainer.TypeString, 'title', valuestr_)
8691+
if nodeName_ == 'title':
8692+
obj_ = docTitleType.factory(parent_object_=self)
8693+
obj_.build(child_, gds_collector_=gds_collector_)
8694+
obj_ = self.mixedclass_(MixedContainer.CategoryComplex,
8695+
MixedContainer.TypeNone, 'title', obj_)
86978696
self.content_.append(obj_)
8698-
self.title_nsprefix_ = child_.prefix
8697+
if hasattr(self, 'add_title'):
8698+
self.add_title(obj_.value)
8699+
elif hasattr(self, 'set_title'):
8700+
self.set_title(obj_.value)
86998701
elif nodeName_ == 'para':
87008702
obj_ = docParaType.factory(parent_object_=self)
87018703
obj_.build(child_, gds_collector_=gds_collector_)
@@ -8876,8 +8878,7 @@ def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='',
88768878
eol_ = ''
88778879
if self.title is not None:
88788880
namespaceprefix_ = self.title_nsprefix_ + ':' if (UseCapturedNS_ and self.title_nsprefix_) else ''
8879-
showIndent(outfile, level, pretty_print)
8880-
outfile.write('<%stitle>%s</%stitle>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.title), input_name='title')), namespaceprefix_ , eol_))
8881+
self.title.export(outfile, level, namespaceprefix_, namespacedef_='', name_='title', pretty_print=pretty_print)
88818882
for para_ in self.para:
88828883
namespaceprefix_ = self.para_nsprefix_ + ':' if (UseCapturedNS_ and self.para_nsprefix_) else ''
88838884
para_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='para', pretty_print=pretty_print)
@@ -8909,14 +8910,16 @@ def buildAttributes(self, node, attrs, already_processed):
89098910
already_processed.add('id')
89108911
self.id = value
89118912
def buildChildren(self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None):
8912-
if nodeName_ == 'title' and child_.text is not None:
8913-
valuestr_ = child_.text
8914-
valuestr_ = self.gds_parse_string(valuestr_, node, 'title')
8915-
valuestr_ = self.gds_validate_string(valuestr_, node, 'title')
8916-
obj_ = self.mixedclass_(MixedContainer.CategorySimple,
8917-
MixedContainer.TypeString, 'title', valuestr_)
8913+
if nodeName_ == 'title':
8914+
obj_ = docTitleType.factory(parent_object_=self)
8915+
obj_.build(child_, gds_collector_=gds_collector_)
8916+
obj_ = self.mixedclass_(MixedContainer.CategoryComplex,
8917+
MixedContainer.TypeNone, 'title', obj_)
89188918
self.content_.append(obj_)
8919-
self.title_nsprefix_ = child_.prefix
8919+
if hasattr(self, 'add_title'):
8920+
self.add_title(obj_.value)
8921+
elif hasattr(self, 'set_title'):
8922+
self.set_title(obj_.value)
89208923
elif nodeName_ == 'para':
89218924
obj_ = docParaType.factory(parent_object_=self)
89228925
obj_.build(child_, gds_collector_=gds_collector_)
@@ -9081,8 +9084,7 @@ def exportChildren(self, outfile, level, namespaceprefix_='', namespacedef_='',
90819084
eol_ = ''
90829085
if self.title is not None:
90839086
namespaceprefix_ = self.title_nsprefix_ + ':' if (UseCapturedNS_ and self.title_nsprefix_) else ''
9084-
showIndent(outfile, level, pretty_print)
9085-
outfile.write('<%stitle>%s</%stitle>%s' % (namespaceprefix_ , self.gds_encode(self.gds_format_string(quote_xml(self.title), input_name='title')), namespaceprefix_ , eol_))
9087+
self.title.export(outfile, level, namespaceprefix_, namespacedef_='', name_='title', pretty_print=pretty_print)
90869088
for para_ in self.para:
90879089
namespaceprefix_ = self.para_nsprefix_ + ':' if (UseCapturedNS_ and self.para_nsprefix_) else ''
90889090
para_.export(outfile, level, namespaceprefix_, namespacedef_='', name_='para', pretty_print=pretty_print)
@@ -9111,14 +9113,16 @@ def buildAttributes(self, node, attrs, already_processed):
91119113
already_processed.add('id')
91129114
self.id = value
91139115
def buildChildren(self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None):
9114-
if nodeName_ == 'title' and child_.text is not None:
9115-
valuestr_ = child_.text
9116-
valuestr_ = self.gds_parse_string(valuestr_, node, 'title')
9117-
valuestr_ = self.gds_validate_string(valuestr_, node, 'title')
9118-
obj_ = self.mixedclass_(MixedContainer.CategorySimple,
9119-
MixedContainer.TypeString, 'title', valuestr_)
9116+
if nodeName_ == 'title':
9117+
obj_ = docTitleType.factory(parent_object_=self)
9118+
obj_.build(child_, gds_collector_=gds_collector_)
9119+
obj_ = self.mixedclass_(MixedContainer.CategoryComplex,
9120+
MixedContainer.TypeNone, 'title', obj_)
91209121
self.content_.append(obj_)
9121-
self.title_nsprefix_ = child_.prefix
9122+
if hasattr(self, 'add_title'):
9123+
self.add_title(obj_.value)
9124+
elif hasattr(self, 'set_title'):
9125+
self.set_title(obj_.value)
91229126
elif nodeName_ == 'para':
91239127
obj_ = docParaType.factory(parent_object_=self)
91249128
obj_.build(child_, gds_collector_=gds_collector_)

src/docbookvisitor.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,10 @@ DB_VIS_C
877877
if (!s.anchor().isEmpty()) m_t << "_1" << s.anchor();
878878
m_t << "\">\n";
879879
m_t << "<title>";
880-
filter(s.title());
880+
if (s.title())
881+
{
882+
std::visit(*this,*s.title());
883+
}
881884
m_t << "</title>\n";
882885
visitChildren(s);
883886
m_t << "</section>\n";

src/docnode.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,7 +2746,12 @@ void DocTitle::parse()
27462746

27472747
void DocTitle::parseFromString(DocNodeVariant *parent,const QCString &text)
27482748
{
2749-
children().append<DocWord>(parser(),parent,text);
2749+
parser()->context.insideHtmlLink=TRUE;
2750+
parser()->pushContext(); // this will create a new parser->context.token
2751+
parser()->internalValidatingParseDoc(thisVariant(),children(),text);
2752+
parser()->popContext(); // this will restore the old parser->context.token
2753+
parser()->context.insideHtmlLink=FALSE;
2754+
flattenParagraphs(thisVariant(),children());
27502755
}
27512756

27522757
//--------------------------------------------------------------------------
@@ -5460,8 +5465,11 @@ int DocSection::parse()
54605465
{
54615466
m_file = sec->fileName();
54625467
m_anchor = sec->label();
5463-
m_title = sec->title();
5464-
if (m_title.isEmpty()) m_title = sec->label();
5468+
QCString titleStr = sec->title();
5469+
if (titleStr.isEmpty()) titleStr = sec->label();
5470+
m_title = createDocNode<DocTitle>(parser(),thisVariant());
5471+
DocTitle *title = &std::get<DocTitle>(*m_title);
5472+
title->parseFromString(thisVariant(),titleStr);
54655473
}
54665474
}
54675475

src/docnode.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ class DocSection : public DocCompoundNode
878878
DocSection(DocParser *parser,DocNodeVariant *parent,int level,const QCString &id) :
879879
DocCompoundNode(parser,parent), m_level(level), m_id(id) {}
880880
int level() const { return m_level; }
881-
QCString title() const { return m_title; }
881+
const DocNodeVariant *title() const { return m_title.get(); }
882882
QCString anchor() const { return m_anchor; }
883883
QCString id() const { return m_id; }
884884
QCString file() const { return m_file; }
@@ -887,7 +887,7 @@ class DocSection : public DocCompoundNode
887887
private:
888888
int m_level = 0;
889889
QCString m_id;
890-
QCString m_title;
890+
std::unique_ptr<DocNodeVariant> m_title;
891891
QCString m_anchor;
892892
QCString m_file;
893893
};

src/htmldocvisitor.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1440,7 +1440,10 @@ void HtmlDocVisitor::operator()(const DocSection &s)
14401440
m_t << "<h" << s.level() << ">";
14411441
m_t << "<a class=\"anchor\" id=\"" << s.anchor();
14421442
m_t << "\"></a>\n";
1443-
filter(convertCharEntitiesToUTF8(s.title()));
1443+
if (s.title())
1444+
{
1445+
std::visit(*this,*s.title());
1446+
}
14441447
m_t << "</h" << s.level() << ">\n";
14451448
visitChildren(s);
14461449
forceStartParagraph(s);

src/latexdocvisitor.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -951,10 +951,18 @@ void LatexDocVisitor::operator()(const DocSection &s)
951951
{
952952
m_t << "\\texorpdfstring{";
953953
}
954-
filter(convertCharEntitiesToUTF8(s.title()));
954+
if (s.title())
955+
{
956+
std::visit(*this,*s.title());
957+
}
955958
if (pdfHyperlinks)
956959
{
957-
m_t << "}{" << latexEscapePDFString(convertCharEntitiesToUTF8(s.title())) << "}";
960+
m_t << "}{";
961+
if (s.title())
962+
{
963+
std::visit(*this,*s.title());
964+
}
965+
m_t << "}";
958966
}
959967
m_t << "}\\label{" << stripPath(s.file()) << "_" << s.anchor() << "}\n";
960968
visitChildren(s);

src/mandocvisitor.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,10 @@ void ManDocVisitor::operator()(const DocSection &s)
594594
if (!m_firstCol) m_t << "\n";
595595
if (s.level()==1) m_t << ".SH"; else m_t << ".SS";
596596
m_t << " \"";
597-
filter(s.title());
597+
if (s.title())
598+
{
599+
std::visit(*this,*s.title());
600+
}
598601
m_t << "\"\n";
599602
if (s.level()==1) m_t << ".PP\n";
600603
m_firstCol=TRUE;

src/perlmodgen.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,11 @@ void PerlModDocVisitor::operator()(const DocSection &s)
864864
{
865865
QCString sect = QCString().sprintf("sect%d",s.level());
866866
openItem(sect);
867-
m_output.addFieldQuotedString("title", s.title());
867+
//m_output.addFieldQuotedString("title", s.title());
868+
if (s.title())
869+
{
870+
std::visit(*this,*s.title());
871+
}
868872
openSubBlock("content");
869873
visitChildren(s);
870874
closeSubBlock();

src/printdocvisitor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,10 @@ class PrintDocVisitor
381381
{
382382
indent_pre();
383383
printf("<sect%d>\n",s.level());
384+
if (s.title())
385+
{
386+
std::visit(*this, *s.title());
387+
}
384388
visitChildren(s);
385389
indent_post();
386390
printf("</sect%d>\n",s.level());

src/rtfdocvisitor.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -837,10 +837,16 @@ void RTFDocVisitor::operator()(const DocSection &s)
837837
// set style
838838
m_t << rtf_Style[heading.str()].reference() << "\n";
839839
// make table of contents entry
840-
filter(s.title());
840+
if (s.title())
841+
{
842+
std::visit(*this,*s.title());
843+
}
841844
m_t << "\n\\par" << "}\n";
842845
m_t << "{\\tc\\tcl" << level << " \\v ";
843-
filter(s.title());
846+
if (s.title())
847+
{
848+
std::visit(*this,*s.title());
849+
}
844850
m_t << "}\n";
845851
m_lastIsPara=TRUE;
846852
visitChildren(s);

0 commit comments

Comments
 (0)