Skip to content

Commit 10a8623

Browse files
committed
issue #11658 Support for auto linking to #defines identifiers within markdown code spans
1 parent 20d19d9 commit 10a8623

File tree

5 files changed

+181
-4
lines changed

5 files changed

+181
-4
lines changed

src/docnode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,7 @@ static Token skipSpacesForTable(DocParser *parser)
19581958
{
19591959
if (tok.is(TokenRetval::TK_HTMLTAG))
19601960
{
1961-
AUTO_TRACE_ADD("html_tag={}",parse->context.token->name);
1961+
AUTO_TRACE_ADD("html_tag={}",parser->context.token->name);
19621962
HtmlTagType tagId=Mappers::htmlTagMapper->map(parser->context.token->name);
19631963
// skip over tbody, thead, tfoot tags
19641964
if (tagId==HtmlTagType::HTML_TBODY ||

src/docparser.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,7 @@ void DocParser::handleStyleEnter(DocNodeVariant *parent,DocNodeList &children,
626626
children.append<DocStyleChange>(this,parent,context.nodeStack.size(),s,tagName,TRUE,
627627
context.fileName,tokenizer.getLineNr(),attribs);
628628
context.styleStack.push(&children.back());
629+
context.inCodeStyle = s==DocStyleChange::Style::Typewriter;
629630
}
630631

631632
/*! Called when a style change ends. For instance a \</b\> command is
@@ -671,6 +672,10 @@ void DocParser::handleStyleLeave(DocNodeVariant *parent,DocNodeList &children,
671672
topStyleChange(context.styleStack).tagName(),FALSE);
672673
context.styleStack.pop();
673674
}
675+
if (s==DocStyleChange::Style::Typewriter)
676+
{
677+
context.inCodeStyle = false;
678+
}
674679
}
675680

676681
/*! Called at the end of a paragraph to close all open style changes
@@ -800,11 +805,12 @@ void DocParser::handleLinkedWord(DocNodeVariant *parent,DocNodeList &children,bo
800805
bool ambig = false;
801806
FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,context.fileName,ambig);
802807
auto lang = context.lang;
808+
bool inSeeBlock = context.inSeeBlock || context.inCodeStyle;
803809
//printf("handleLinkedWord(%s) context.context=%s\n",qPrint(context.token->name),qPrint(context.context));
804810
if (!context.insideHtmlLink &&
805-
(resolveRef(context.context,context.token->name,context.inSeeBlock,&compound,&member,lang,TRUE,fd,TRUE)
811+
(resolveRef(context.context,context.token->name,inSeeBlock,&compound,&member,lang,TRUE,fd,TRUE)
806812
|| (!context.context.isEmpty() && // also try with global scope
807-
resolveRef(QCString(),context.token->name,context.inSeeBlock,&compound,&member,lang,FALSE,nullptr,TRUE))
813+
resolveRef(QCString(),context.token->name,inSeeBlock,&compound,&member,lang,FALSE,nullptr,TRUE))
808814
)
809815
)
810816
{
@@ -815,7 +821,7 @@ void DocParser::handleLinkedWord(DocNodeVariant *parent,DocNodeList &children,bo
815821
if (member->isObjCMethod())
816822
{
817823
bool localLink = context.memberDef ? member->getClassDef()==context.memberDef->getClassDef() : FALSE;
818-
name = member->objCMethodName(localLink,context.inSeeBlock);
824+
name = member->objCMethodName(localLink,inSeeBlock);
819825
}
820826
children.append<DocLinkedWord>(
821827
this,parent,name,
@@ -1999,6 +2005,7 @@ IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf,
19992005
while (!parser->context.styleStack.empty()) parser->context.styleStack.pop();
20002006
while (!parser->context.initialStyleStack.empty()) parser->context.initialStyleStack.pop();
20012007
parser->context.inSeeBlock = FALSE;
2008+
parser->context.inCodeStyle = FALSE;
20022009
parser->context.xmlComment = FALSE;
20032010
parser->context.insideHtmlLink = FALSE;
20042011
parser->context.includeFileText = "";
@@ -2069,6 +2076,7 @@ IDocNodeASTPtr validatingParseTitle(IDocParser &parserIntf,const QCString &fileN
20692076
while (!parser->context.styleStack.empty()) parser->context.styleStack.pop();
20702077
while (!parser->context.initialStyleStack.empty()) parser->context.initialStyleStack.pop();
20712078
parser->context.inSeeBlock = FALSE;
2079+
parser->context.inCodeStyle = FALSE;
20722080
parser->context.xmlComment = FALSE;
20732081
parser->context.insideHtmlLink = FALSE;
20742082
parser->context.includeFileText = "";
@@ -2122,6 +2130,7 @@ IDocNodeASTPtr validatingParseText(IDocParser &parserIntf,const QCString &input)
21222130
while (!parser->context.styleStack.empty()) parser->context.styleStack.pop();
21232131
while (!parser->context.initialStyleStack.empty()) parser->context.initialStyleStack.pop();
21242132
parser->context.inSeeBlock = FALSE;
2133+
parser->context.inCodeStyle = FALSE;
21252134
parser->context.xmlComment = FALSE;
21262135
parser->context.insideHtmlLink = FALSE;
21272136
parser->context.includeFileText = "";

src/docparser_p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct DocParserContext
6161
const Definition *scope = nullptr;
6262
QCString context;
6363
bool inSeeBlock = false;
64+
bool inCodeStyle = false;
6465
bool xmlComment = false;
6566
bool insideHtmlLink = false;
6667
DocNodeStack nodeStack;

testing/111/111__autolink_8cpp.xml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="" xml:lang="en-US">
3+
<compounddef id="111__autolink_8cpp" kind="file" language="C++">
4+
<compoundname>111_autolink.cpp</compoundname>
5+
<innerclass refid="structmy__struct__t" prot="public">my_struct_t</innerclass>
6+
<sectiondef kind="define">
7+
<memberdef kind="define" id="111__autolink_8cpp_1a8ef4ab1db0ae388e9407f08fa3a95421" prot="public" static="no">
8+
<name>MY_DEFINE</name>
9+
<initializer>1</initializer>
10+
<briefdescription>
11+
<para>My define. </para>
12+
</briefdescription>
13+
<detaileddescription>
14+
</detaileddescription>
15+
<inbodydescription>
16+
</inbodydescription>
17+
<location file="111_autolink.cpp" line="10" column="9" bodyfile="111_autolink.cpp" bodystart="10" bodyend="-1"/>
18+
</memberdef>
19+
</sectiondef>
20+
<sectiondef kind="enum">
21+
<memberdef kind="enum" id="111__autolink_8cpp_1abf13918d7284a1bed5d7a3b739f4f7da" prot="public" static="no" strong="no">
22+
<type/>
23+
<name>my_enum_t</name>
24+
<enumvalue id="111__autolink_8cpp_1abf13918d7284a1bed5d7a3b739f4f7daaca5528c86ab6f398979a03e811731e42" prot="public">
25+
<name>ENUM_A</name>
26+
<briefdescription>
27+
<para>A. </para>
28+
</briefdescription>
29+
<detaileddescription>
30+
</detaileddescription>
31+
</enumvalue>
32+
<briefdescription>
33+
<para>My enum. </para>
34+
</briefdescription>
35+
<detaileddescription>
36+
</detaileddescription>
37+
<inbodydescription>
38+
</inbodydescription>
39+
<location file="111_autolink.cpp" line="28" column="1" bodyfile="111_autolink.cpp" bodystart="29" bodyend="31"/>
40+
</memberdef>
41+
</sectiondef>
42+
<sectiondef kind="var">
43+
<memberdef kind="variable" id="111__autolink_8cpp_1ab16669b1a4a2c5dc4f8d41107e1295dc" prot="public" static="no" mutable="no">
44+
<type>int</type>
45+
<definition>int my_int</definition>
46+
<argsstring/>
47+
<name>my_int</name>
48+
<briefdescription>
49+
<para>My int. </para>
50+
</briefdescription>
51+
<detaileddescription>
52+
</detaileddescription>
53+
<inbodydescription>
54+
</inbodydescription>
55+
<location file="111_autolink.cpp" line="15" column="5" bodyfile="111_autolink.cpp" bodystart="15" bodyend="-1"/>
56+
</memberdef>
57+
</sectiondef>
58+
<sectiondef kind="func">
59+
<memberdef kind="function" id="111__autolink_8cpp_1ac07863d69ae41a4e395b31f73b35fbcd" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
60+
<type>void</type>
61+
<definition>void foo</definition>
62+
<argsstring>()</argsstring>
63+
<name>foo</name>
64+
<briefdescription>
65+
<para>My foo funciton. </para>
66+
</briefdescription>
67+
<detaileddescription>
68+
</detaileddescription>
69+
<inbodydescription>
70+
</inbodydescription>
71+
<location file="111_autolink.cpp" line="36" column="6" declfile="111_autolink.cpp" declline="36" declcolumn="6"/>
72+
</memberdef>
73+
<memberdef kind="function" id="111__autolink_8cpp_1ae1a3968e7947464bee7714f6d43b7002" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
74+
<type>void</type>
75+
<definition>void test</definition>
76+
<argsstring>()</argsstring>
77+
<name>test</name>
78+
<briefdescription>
79+
<para>test function </para>
80+
</briefdescription>
81+
<detaileddescription>
82+
<para>Inline code links everything: <computeroutput><ref refid="111__autolink_8cpp_1ac07863d69ae41a4e395b31f73b35fbcd" kindref="member">foo()</ref>, <ref refid="111__autolink_8cpp_1abf13918d7284a1bed5d7a3b739f4f7da" kindref="member">my_enum_t</ref>, <ref refid="structmy__struct__t" kindref="compound">my_struct_t</ref>, <ref refid="111__autolink_8cpp_1a8ef4ab1db0ae388e9407f08fa3a95421" kindref="member">MY_DEFINE</ref>, <ref refid="111__autolink_8cpp_1abf13918d7284a1bed5d7a3b739f4f7daaca5528c86ab6f398979a03e811731e42" kindref="member">ENUM_A</ref>, <ref refid="111__autolink_8cpp_1ab16669b1a4a2c5dc4f8d41107e1295dc" kindref="member">my_int</ref></computeroutput></para>
83+
<para>Normal text only links to functions and types: <ref refid="111__autolink_8cpp_1ac07863d69ae41a4e395b31f73b35fbcd" kindref="member">foo()</ref>, <ref refid="111__autolink_8cpp_1abf13918d7284a1bed5d7a3b739f4f7da" kindref="member">my_enum_t</ref>, <ref refid="structmy__struct__t" kindref="compound">my_struct_t</ref>, MY_DEFINE, ENUM_A, my_int</para>
84+
<para>
85+
<programlisting filename=".c">
86+
<codeline>
87+
<highlight class="comment">//<sp/>code<sp/>block<sp/>links<sp/>everything:</highlight>
88+
<highlight class="normal"/>
89+
</codeline>
90+
<codeline>
91+
<highlight class="normal"><ref refid="111__autolink_8cpp_1ac07863d69ae41a4e395b31f73b35fbcd" kindref="member">foo</ref>(),<sp/><ref refid="111__autolink_8cpp_1abf13918d7284a1bed5d7a3b739f4f7da" kindref="member">my_enum_t</ref>,<sp/><ref refid="structmy__struct__t" kindref="compound">my_struct_t</ref>,<sp/><ref refid="111__autolink_8cpp_1a8ef4ab1db0ae388e9407f08fa3a95421" kindref="member">MY_DEFINE</ref>,<sp/><ref refid="111__autolink_8cpp_1abf13918d7284a1bed5d7a3b739f4f7daaca5528c86ab6f398979a03e811731e42" kindref="member">ENUM_A</ref>,<sp/><ref refid="111__autolink_8cpp_1ab16669b1a4a2c5dc4f8d41107e1295dc" kindref="member">my_int</ref></highlight>
92+
</codeline>
93+
</programlisting>
94+
</para>
95+
<para>
96+
<simplesect kind="see">
97+
<para>Inside see section also everything is linked: <ref refid="111__autolink_8cpp_1ac07863d69ae41a4e395b31f73b35fbcd" kindref="member">foo()</ref>, <ref refid="111__autolink_8cpp_1abf13918d7284a1bed5d7a3b739f4f7da" kindref="member">my_enum_t</ref>, <ref refid="structmy__struct__t" kindref="compound">my_struct_t</ref>, <ref refid="111__autolink_8cpp_1a8ef4ab1db0ae388e9407f08fa3a95421" kindref="member">MY_DEFINE</ref>, <ref refid="111__autolink_8cpp_1abf13918d7284a1bed5d7a3b739f4f7daaca5528c86ab6f398979a03e811731e42" kindref="member">ENUM_A</ref>, <ref refid="111__autolink_8cpp_1ab16669b1a4a2c5dc4f8d41107e1295dc" kindref="member">my_int</ref> </para>
98+
</simplesect>
99+
</para>
100+
</detaileddescription>
101+
<inbodydescription>
102+
</inbodydescription>
103+
<location file="111_autolink.cpp" line="55" column="6" declfile="111_autolink.cpp" declline="55" declcolumn="6"/>
104+
</memberdef>
105+
</sectiondef>
106+
<briefdescription>
107+
</briefdescription>
108+
<detaileddescription>
109+
</detaileddescription>
110+
<location file="111_autolink.cpp"/>
111+
</compounddef>
112+
</doxygen>

testing/111_autolink.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// objective: test autolink in various environments
2+
// check: 111__autolink_8cpp.xml
3+
/**
4+
* @file
5+
*/
6+
7+
/**
8+
* @brief My define
9+
*/
10+
#define MY_DEFINE 1
11+
12+
/**
13+
* @brief My int
14+
*/
15+
int my_int;
16+
17+
/**
18+
* @brief My struct
19+
*/
20+
typedef struct
21+
{
22+
int a; ///< a
23+
} my_struct_t;
24+
25+
/**
26+
* @brief My enum
27+
*/
28+
typedef enum
29+
{
30+
ENUM_A ///< A
31+
} my_enum_t;
32+
33+
/**
34+
* @brief My foo funciton
35+
*/
36+
void foo();
37+
38+
/**
39+
* @brief test function
40+
*
41+
* Inline code links everything:
42+
* `foo(), my_enum_t, my_struct_t, MY_DEFINE, ENUM_A, my_int`
43+
*
44+
* Normal text only links to functions and types:
45+
* foo(), my_enum_t, my_struct_t, MY_DEFINE, ENUM_A, my_int
46+
*
47+
* ```c
48+
* // code block links everything:
49+
* foo(), my_enum_t, my_struct_t, MY_DEFINE, ENUM_A, my_int
50+
* ```
51+
*
52+
* @see Inside see section also everything is linked:
53+
* foo(), my_enum_t, my_struct_t, MY_DEFINE, ENUM_A, my_int
54+
*/
55+
void test();

0 commit comments

Comments
 (0)