summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimír Vondruš <mosra@centrum.cz>2017-11-19 12:36:12 (GMT)
committerVladimír Vondruš <mosra@centrum.cz>2017-11-19 13:15:14 (GMT)
commiteaf8edbac7e6a1873aa5c4ff0df063cd367351d6 (patch)
tree4999e26ac9d19d631e120b73d64c949d3ba39538
parentebf75c1fe8a0ff2cc9235155b6d63367944d6342 (diff)
downloadDoxygen-eaf8edbac7e6a1873aa5c4ff0df063cd367351d6.zip
Doxygen-eaf8edbac7e6a1873aa5c4ff0df063cd367351d6.tar.gz
Doxygen-eaf8edbac7e6a1873aa5c4ff0df063cd367351d6.tar.bz2
Propagate language information to all <programlisting> XML elements.
This is based on work done in 141dbfd5a4f79c98da14a1b414c6db4e1b34618b through ed9acb6e1bb81a2eec334180f7b8c1bf0598b444 and makes a few behavioral changes to it. There's a new attribute called `filename` and the `language` was removed, because it could provide misleading information. This allows for more flexibility on the user side. In particular: * For historical reasons, `*.txt` files are marked by Doxygen as C++ (see https://bugzilla.gnome.org/show_bug.cgi?id=760836 for details). In particular, code snippet included from a CMakeLists.txt file would be marked and highlighted as C++. So in this case, the language attribute would be very misleading. * Doxygen is aware only of a very small subset of languages and thus a lot of information can be lost when relying on its extension-to-language-name conversion -- in particular, all extensions that are not recognized are assumed to be C++. On the other hand, putting more effort into its language detection algorithms is not worth the time, as there will always be new languages that fail to detect. So let's leave that on the user of the XML output instead. * Using just file extension is not enough, it has to be a full filename. For example, `*.txt` can be either a plain text file or a `CMakeLists.txt`. * The path is not stripped from the filename, as it also may contain additional information that helps to detect the language better. In addition to that, filenames of code snippets included via the \include command and related are propagated to the <programlisting> element as well. With this change, (1) code snippets using simply \code some code \endcode will not produce any `filename` attribute and it's up to the user what to do -- assume C++, detect language from contents or not highlight anything. <programlisting> some code </programlisting> (2) Code snippets using \code{.cmake} some code \endcode will produce the following: <programlisting filename=".cmake"> some code </programlisting> (3) And finally, \include, \dontinclude and related \skip, \skipline etc. commands \include path/to/some-file.py will produce <programlisting filename="path/to/some-file.py"> some code </programlisting> The tests were updated to check all three cases. On the user side, when using Pygments for example, it's then just a matter of calling pygments.lexers.find_lexer_class_for_filename() with value of the `filename` attribute value and optionally also the code snippet for additional language analysis.
-rw-r--r--src/docparser.cpp3
-rw-r--r--src/docparser.h2
-rw-r--r--src/xmldocvisitor.cpp16
-rw-r--r--templates/xml/compound.xsd2
-rw-r--r--testing/014/indexpage.xml11
-rw-r--r--testing/014_code.dox4
-rw-r--r--testing/021/indexpage.xml2
-rw-r--r--testing/025/example_test_8cpp-example.xml2
-rw-r--r--testing/032/indexpage.xml2
-rw-r--r--testing/049/indexpage.xml2
10 files changed, 33 insertions, 13 deletions
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 5bb28ea..eac6e97 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -104,6 +104,7 @@ static QCString g_exampleName;
static SectionDict * g_sectionDict;
static QCString g_searchUrl;
+static QCString g_includeFileName;
static QCString g_includeFileText;
static uint g_includeFileOffset;
static uint g_includeFileLength;
@@ -1917,6 +1918,7 @@ void DocInclude::parse()
// fall through
case DontInclude:
readTextFileByName(m_file,m_text);
+ g_includeFileName = m_file;
g_includeFileText = m_text;
g_includeFileOffset = 0;
g_includeFileLength = m_text.length();
@@ -1954,6 +1956,7 @@ void DocInclude::parse()
void DocIncOperator::parse()
{
+ m_includeFileName = g_includeFileName;
const char *p = g_includeFileText;
uint l = g_includeFileLength;
uint o = g_includeFileOffset;
diff --git a/src/docparser.h b/src/docparser.h
index f5167dc..02c727d 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -541,6 +541,7 @@ class DocIncOperator : public DocNode
void markLast(bool v=TRUE) { m_isLast = v; }
bool isExample() const { return m_isExample; }
QCString exampleFile() const { return m_exampleFile; }
+ QCString includeFileName() const { return m_includeFileName; }
void parse();
private:
@@ -552,6 +553,7 @@ class DocIncOperator : public DocNode
bool m_isLast;
bool m_isExample;
QCString m_exampleFile;
+ QCString m_includeFileName;
};
/** Node representing an item of a cross-referenced list */
diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp
index 5789283..55c2b38 100644
--- a/src/xmldocvisitor.cpp
+++ b/src/xmldocvisitor.cpp
@@ -211,7 +211,11 @@ void XmlDocVisitor::visit(DocVerbatim *s)
switch(s->type())
{
case DocVerbatim::Code: // fall though
- m_t << "<programlisting language=\"" << langToString(langExt) << "\">";
+ m_t << "<programlisting";
+ if (!s->language().isEmpty())
+ m_t << " filename=\"" << lang << "\">";
+ else
+ m_t << ">";
Doxygen::parserManager->getParser(lang)
->parseCode(m_ci,s->context(),s->text(),langExt,
s->isExample(),s->exampleFile());
@@ -264,7 +268,7 @@ void XmlDocVisitor::visit(DocInclude *inc)
{
case DocInclude::IncWithLines:
{
- m_t << "<programlisting>";
+ m_t << "<programlisting filename=\"" << inc->file() << "\">";
QFileInfo cfi( inc->file() );
FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
Doxygen::parserManager->getParser(inc->extension())
@@ -284,7 +288,7 @@ void XmlDocVisitor::visit(DocInclude *inc)
}
break;
case DocInclude::Include:
- m_t << "<programlisting>";
+ m_t << "<programlisting filename=\"" << inc->file() << "\">";
Doxygen::parserManager->getParser(inc->extension())
->parseCode(m_ci,inc->context(),
inc->text(),
@@ -318,7 +322,7 @@ void XmlDocVisitor::visit(DocInclude *inc)
m_t << "</verbatim>";
break;
case DocInclude::Snippet:
- m_t << "<programlisting>";
+ m_t << "<programlisting filename=\"" << inc->file() << "\">";
Doxygen::parserManager->getParser(inc->extension())
->parseCode(m_ci,
inc->context(),
@@ -331,7 +335,7 @@ void XmlDocVisitor::visit(DocInclude *inc)
break;
case DocInclude::SnipWithLines:
{
- m_t << "<programlisting>";
+ m_t << "<programlisting filename=\"" << inc->file() << "\">";
QFileInfo cfi( inc->file() );
FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
Doxygen::parserManager->getParser(inc->extension())
@@ -367,7 +371,7 @@ void XmlDocVisitor::visit(DocIncOperator *op)
{
if (!m_hide)
{
- m_t << "<programlisting>";
+ m_t << "<programlisting filename=\"" << op->includeFileName() << "\">";
}
pushEnabled();
m_hide = TRUE;
diff --git a/templates/xml/compound.xsd b/templates/xml/compound.xsd
index 43cc897..8affc20 100644
--- a/templates/xml/compound.xsd
+++ b/templates/xml/compound.xsd
@@ -264,7 +264,7 @@
<xsd:sequence>
<xsd:element name="codeline" type="codelineType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
- <xsd:attribute name="language" type="DoxLanguage" use="optional"/>
+ <xsd:attribute name="filename" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="codelineType">
diff --git a/testing/014/indexpage.xml b/testing/014/indexpage.xml
index ad35261..e677e24 100644
--- a/testing/014/indexpage.xml
+++ b/testing/014/indexpage.xml
@@ -5,7 +5,7 @@
<title>My Project</title>
<detaileddescription>
<para>
- <programlisting language="Python">
+ <programlisting filename=".py">
<codeline>
<highlight class="comment">#<sp/>comment<sp/>in<sp/>Python</highlight>
<highlight class="normal"/>
@@ -25,7 +25,7 @@
</programlisting>
</para>
<para>
- <programlisting language="C++">
+ <programlisting filename=".cpp">
<codeline>
<highlight class="comment">//<sp/>comment<sp/>in<sp/>a<sp/>code<sp/>block</highlight>
<highlight class="normal"/>
@@ -37,6 +37,13 @@
</codeline>
</programlisting>
</para>
+ <para>
+ <programlisting>
+ <codeline>
+ <highlight class="normal">//<sp />implicit<sp />code<sp />language</highlight>
+ </codeline>
+ </programlisting>
+ </para>
</detaileddescription>
</compounddef>
</doxygen>
diff --git a/testing/014_code.dox b/testing/014_code.dox
index 871a44c..56597cc 100644
--- a/testing/014_code.dox
+++ b/testing/014_code.dox
@@ -11,4 +11,8 @@
* // comment in a code block
* class Cpp {};
* \endcode
+ *
+ * \code
+ * // implicit code language
+ * \endcode
*/
diff --git a/testing/021/indexpage.xml b/testing/021/indexpage.xml
index 20e1ad2..9205dd6 100644
--- a/testing/021/indexpage.xml
+++ b/testing/021/indexpage.xml
@@ -4,7 +4,7 @@
<compoundname>index</compoundname>
<title>My Project</title>
<detaileddescription>
- <para> Our main function starts like this: <programlisting><codeline><highlight class="normal">void<sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline></programlisting> First we create a object <computeroutput>t</computeroutput> of the <ref refid="class_test" kindref="compound">Test</ref> class. <programlisting><codeline><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline></programlisting> Then we call the example member function <programlisting><codeline><highlight class="normal"><sp/><sp/>t.example();</highlight></codeline></programlisting> After that our little test routine ends. <programlisting><codeline><highlight class="normal">}</highlight></codeline></programlisting> </para>
+ <para> Our main function starts like this: <programlisting filename="example_test.cpp"><codeline><highlight class="normal">void<sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline></programlisting> First we create a object <computeroutput>t</computeroutput> of the <ref refid="class_test" kindref="compound">Test</ref> class. <programlisting filename="example_test.cpp"><codeline><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline></programlisting> Then we call the example member function <programlisting filename="example_test.cpp"><codeline><highlight class="normal"><sp/><sp/>t.example();</highlight></codeline></programlisting> After that our little test routine ends. <programlisting filename="example_test.cpp"><codeline><highlight class="normal">}</highlight></codeline></programlisting> </para>
</detaileddescription>
</compounddef>
</doxygen>
diff --git a/testing/025/example_test_8cpp-example.xml b/testing/025/example_test_8cpp-example.xml
index 6c0ce90..96a1cd7 100644
--- a/testing/025/example_test_8cpp-example.xml
+++ b/testing/025/example_test_8cpp-example.xml
@@ -4,7 +4,7 @@
<compoundname>example_test.cpp</compoundname>
<detaileddescription>
<para>This is an example of how to use the <ref refid="class_test" kindref="compound">Test</ref> class.</para>
- <para>More details about this example. <programlisting><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="class_test" kindref="compound">Test</ref><sp/>t;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>t.<ref refid="class_test_1a47b775f65718978f1ffcd96376f8ecfa" kindref="member">example</ref>();</highlight></codeline><codeline><highlight class="normal">}</highlight></codeline><codeline><highlight class="normal"/></codeline></programlisting> </para>
+ <para>More details about this example. <programlisting filename="example_test.cpp"><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="class_test" kindref="compound">Test</ref><sp/>t;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>t.<ref refid="class_test_1a47b775f65718978f1ffcd96376f8ecfa" kindref="member">example</ref>();</highlight></codeline><codeline><highlight class="normal">}</highlight></codeline><codeline><highlight class="normal"/></codeline></programlisting> </para>
</detaileddescription>
</compounddef>
</doxygen>
diff --git a/testing/032/indexpage.xml b/testing/032/indexpage.xml
index ba401c8..3a25272 100644
--- a/testing/032/indexpage.xml
+++ b/testing/032/indexpage.xml
@@ -4,7 +4,7 @@
<compoundname>index</compoundname>
<title>My Project</title>
<detaileddescription>
- <para>Some text. <programlisting><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>t.example();</highlight></codeline><codeline><highlight class="normal">}</highlight></codeline><codeline><highlight class="normal"/></codeline></programlisting> More text. <programlisting><codeline lineno="1"><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline lineno="2"><highlight class="normal">{</highlight></codeline><codeline lineno="3"><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline><codeline lineno="4"><highlight class="normal"><sp/><sp/>t.example();</highlight></codeline><codeline lineno="5"><highlight class="normal">}</highlight></codeline><codeline lineno="6"><highlight class="normal"/></codeline></programlisting> End. </para>
+ <para>Some text. <programlisting filename="example_test.cpp"><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>t.example();</highlight></codeline><codeline><highlight class="normal">}</highlight></codeline><codeline><highlight class="normal"/></codeline></programlisting> More text. <programlisting filename="example_test.cpp"><codeline lineno="1"><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline lineno="2"><highlight class="normal">{</highlight></codeline><codeline lineno="3"><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline><codeline lineno="4"><highlight class="normal"><sp/><sp/>t.example();</highlight></codeline><codeline lineno="5"><highlight class="normal">}</highlight></codeline><codeline lineno="6"><highlight class="normal"/></codeline></programlisting> End. </para>
</detaileddescription>
</compounddef>
</doxygen>
diff --git a/testing/049/indexpage.xml b/testing/049/indexpage.xml
index a6c9b97..461a174 100644
--- a/testing/049/indexpage.xml
+++ b/testing/049/indexpage.xml
@@ -4,7 +4,7 @@
<compoundname>index</compoundname>
<title>My Project</title>
<detaileddescription>
- <para>A bubble sort algorithm First get the inputs <programlisting><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i&lt;n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>printf(</highlight><highlight class="stringliteral">"<sp/>Array[%d]<sp/>=<sp/>"</highlight><highlight class="normal">,i);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>scanf(</highlight><highlight class="stringliteral">"%d"</highlight><highlight class="normal">,&amp;arr[i]);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline></programlisting>Then do the bubbling <programlisting><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i&lt;n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(j=0<sp/>;<sp/>j&lt;n-i-1<sp/>;<sp/>j++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal">(arr[j]&gt;arr[j+1])<sp/></highlight><highlight class="comment">//Swapping<sp/>Condition<sp/>is<sp/>Checked</highlight><highlight class="normal"/></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>temp=arr[j];</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>arr[j]=arr[j+1];</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>arr[j+1]=temp;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/>}</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline></programlisting>Then write the result <programlisting><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i&lt;n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>printf(</highlight><highlight class="stringliteral">"<sp/>%4d"</highlight><highlight class="normal">,arr[i]);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline></programlisting></para>
+ <para>A bubble sort algorithm First get the inputs <programlisting filename="snippet_test.cpp"><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i&lt;n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>printf(</highlight><highlight class="stringliteral">"<sp/>Array[%d]<sp/>=<sp/>"</highlight><highlight class="normal">,i);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>scanf(</highlight><highlight class="stringliteral">"%d"</highlight><highlight class="normal">,&amp;arr[i]);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline></programlisting>Then do the bubbling <programlisting filename="snippet_test.cpp"><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i&lt;n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(j=0<sp/>;<sp/>j&lt;n-i-1<sp/>;<sp/>j++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal">(arr[j]&gt;arr[j+1])<sp/></highlight><highlight class="comment">//Swapping<sp/>Condition<sp/>is<sp/>Checked</highlight><highlight class="normal"/></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>temp=arr[j];</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>arr[j]=arr[j+1];</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>arr[j+1]=temp;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/>}</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline></programlisting>Then write the result <programlisting filename="snippet_test.cpp"><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i&lt;n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>printf(</highlight><highlight class="stringliteral">"<sp/>%4d"</highlight><highlight class="normal">,arr[i]);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline></programlisting></para>
</detaileddescription>
</compounddef>
</doxygen>