Skip to content

Commit a36c994

Browse files
albert-githubdoxygen
authored andcommitted
issue #8528 Markdown links to Markdown pages with explicit page command are broken
In case a `@page` command is the first line in a markdown file it is used as "label" but also to construct the name of the output file and hence the regular markdown reference (like `[...](..)`) does not work anymore as here an internal label and filename is used (`md_...`). To overcome this problem the `@page <label> (title)` is changed into `@page md_<filename> (title)\ilinebr @anchor <label>`.
1 parent e321a87 commit a36c994

File tree

1 file changed

+89
-30
lines changed

1 file changed

+89
-30
lines changed

src/markdown.cpp

Lines changed: 89 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@
5353
#include "fileinfo.h"
5454
#include "utf8.h"
5555

56+
enum class ExplicitPage
57+
{
58+
notExplicit,
59+
explicitPage,
60+
explicitMainPage
61+
};
62+
5663
#if !defined(NDEBUG)
5764
#define ENABLE_TRACING
5865
#endif
@@ -135,6 +142,11 @@ class Trace
135142
m_resultSet = true;
136143
m_resultValue = b ? "true" : "false";
137144
}
145+
void setResult(ExplicitPage ep)
146+
{
147+
m_resultSet = true;
148+
m_resultValue = QCString().setNum(static_cast<int>(ep));
149+
}
138150
void setResult(int i)
139151
{
140152
m_resultSet = true;
@@ -194,7 +206,6 @@ int Trace::s_indent = 0;
194206
(data[i]=='(' || data[i]=='{' || data[i]=='[' || (data[i]=='<' && data[i+1]!='/') || \
195207
data[i]=='\\' || \
196208
data[i]=='@')
197-
198209
//----------
199210

200211
struct TableCell
@@ -2852,8 +2863,11 @@ QCString Markdown::processBlocks(const QCString &s,const int indent)
28522863
return m_out.get();
28532864
}
28542865

2855-
/** returns TRUE if input string docs starts with \@page or \@mainpage command */
2856-
static bool isExplicitPage(const QCString &docs)
2866+
/** returns ExplicitPage::explicitPage in case input string docs starts with page command
2867+
* returns ExplicitPage::explicitMainPage in case input string docs starts with mainpage comand
2868+
* returns ExplicitPage::notExplicit otherwise
2869+
*/
2870+
static ExplicitPage isExplicitPage(const QCString &docs)
28572871
{
28582872
TRACE(docs);
28592873
int i=0;
@@ -2870,12 +2884,20 @@ static bool isExplicitPage(const QCString &docs)
28702884
(qstrncmp(&data[i+1],"page ",5)==0 || qstrncmp(&data[i+1],"mainpage",8)==0)
28712885
)
28722886
{
2873-
TRACE_RESULT(TRUE);
2874-
return TRUE;
2887+
if (qstrncmp(&data[i+1],"page ",5)==0)
2888+
{
2889+
TRACE_RESULT(ExplicitPage::explicitPage);
2890+
return ExplicitPage::explicitPage;
2891+
}
2892+
else
2893+
{
2894+
TRACE_RESULT(ExplicitPage::explicitMainPage);
2895+
return ExplicitPage::explicitMainPage;
2896+
}
28752897
}
28762898
}
2877-
TRACE_RESULT(FALSE);
2878-
return FALSE;
2899+
TRACE_RESULT(ExplicitPage::notExplicit);
2900+
return ExplicitPage::notExplicit;
28792901
}
28802902

28812903
QCString Markdown::extractPageTitle(QCString &docs,QCString &id, int &prepend)
@@ -3110,30 +3132,67 @@ void MarkdownOutlineParser::parseInput(const QCString &fileName,
31103132
QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
31113133
bool wasEmpty = id.isEmpty();
31123134
if (wasEmpty) id = markdownFileNameToId(fileName);
3113-
if (!isExplicitPage(docs))
3135+
switch (isExplicitPage(docs))
31143136
{
3115-
if (!mdfileAsMainPage.isEmpty() &&
3116-
(fn==mdfileAsMainPage || // name reference
3117-
FileInfo(fileName.str()).absFilePath()==
3118-
FileInfo(mdfileAsMainPage.str()).absFilePath()) // file reference with path
3119-
)
3120-
{
3121-
docs.prepend("@anchor " + id + "\\ilinebr ");
3122-
docs.prepend("@mainpage "+title+"\\ilinebr ");
3123-
}
3124-
else if (id=="mainpage" || id=="index")
3125-
{
3126-
if (title.isEmpty()) title = titleFn;
3127-
docs.prepend("@anchor " + id + "\\ilinebr ");
3128-
docs.prepend("@mainpage "+title+"\\ilinebr ");
3129-
}
3130-
else
3131-
{
3132-
if (title.isEmpty()) {title = titleFn;prepend=0;}
3133-
if (!wasEmpty) docs.prepend("@anchor " + markdownFileNameToId(fileName) + "\\ilinebr ");
3134-
docs.prepend("@page "+id+" "+title+"\\ilinebr ");
3135-
}
3136-
for (int i = 0; i < prepend; i++) docs.prepend("\n");
3137+
case ExplicitPage::notExplicit:
3138+
if (!mdfileAsMainPage.isEmpty() &&
3139+
(fn==mdfileAsMainPage || // name reference
3140+
FileInfo(fileName.str()).absFilePath()==
3141+
FileInfo(mdfileAsMainPage.str()).absFilePath()) // file reference with path
3142+
)
3143+
{
3144+
docs.prepend("@anchor " + id + "\\ilinebr ");
3145+
docs.prepend("@mainpage "+title+"\\ilinebr ");
3146+
}
3147+
else if (id=="mainpage" || id=="index")
3148+
{
3149+
if (title.isEmpty()) title = titleFn;
3150+
docs.prepend("@anchor " + id + "\\ilinebr ");
3151+
docs.prepend("@mainpage "+title+"\\ilinebr ");
3152+
}
3153+
else
3154+
{
3155+
if (title.isEmpty()) {title = titleFn;prepend=0;}
3156+
if (!wasEmpty) docs.prepend("@anchor " + markdownFileNameToId(fileName) + "\\ilinebr ");
3157+
docs.prepend("@page "+id+" "+title+"\\ilinebr ");
3158+
}
3159+
for (int i = 0; i < prepend; i++) docs.prepend("\n");
3160+
break;
3161+
case ExplicitPage::explicitPage:
3162+
{
3163+
static const reg::Ex re(R"([\\@]page[ \t]*)");
3164+
static const reg::Ex re0(R"(^[a-z_A-Z\x80-\xFF])"); // from LABELID, see commentscan.l
3165+
static const reg::Ex re1(R"([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]*)"); // LABELID, see commentscan.l
3166+
static const reg::Ex re2(R"(\n)");
3167+
reg::Match match;
3168+
reg::Match match1;
3169+
std::string t;
3170+
std::string t1;
3171+
t = docs.str();
3172+
reg::search(t,match,re);
3173+
t1 = match.suffix().str();
3174+
3175+
// check first character in [a-z_A-Z\x80-\xFF], so we have a potential label
3176+
if (reg::search(t1,match1,re0))
3177+
{
3178+
docs = match.prefix().str();
3179+
docs += match.str() + markdownFileNameToId(fileName);
3180+
t = match.suffix().str();
3181+
3182+
reg::search(t,match,re1);
3183+
QCString saveAnchor = match.str();
3184+
t = match.suffix().str();
3185+
reg::search(t,match,re2);
3186+
docs += match.prefix().str();
3187+
docs += "\\ilinebr @anchor ";
3188+
docs += saveAnchor;
3189+
docs += match.str();
3190+
docs += match.suffix().str();
3191+
}
3192+
}
3193+
break;
3194+
case ExplicitPage::explicitMainPage:
3195+
break;
31373196
}
31383197
int lineNr=1;
31393198

0 commit comments

Comments
 (0)