Skip to content

Commit 8ac72d9

Browse files
committed
Further improve quote handling
1 parent b3b06bd commit 8ac72d9

File tree

7 files changed

+72
-4
lines changed

7 files changed

+72
-4
lines changed

doc/markdown.dox

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,10 @@ added for backward compatibility reasons.
693693
In case you want to have single quotes inside a code span, don't use
694694
one backtick but two backticks around the code span.
695695

696+
Double backticks are also ended by double quotes in the same way.
697+
698+
A ``cool'' word in a ``nice'' sentence.
699+
696700
\subsection mddox_lists Lists Extensions
697701

698702
With Markdown two lists separated by an empty line are joined together into

src/commentcnv.l

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,14 @@ SLASHopt [/]*
760760
}
761761
}
762762
}
763+
<VerbatimCode>"''" {
764+
copyToOutput(yyscanner,yytext,yyleng);
765+
if (yyextra->blockName=="``") // support for ``text''
766+
{
767+
yyextra->inVerbatim=false;
768+
BEGIN(yyextra->lastCommentContext);
769+
}
770+
}
763771
<VerbatimCode>"'" {
764772
copyToOutput(yyscanner,yytext,yyleng);
765773
if (yyextra->blockName=="`") // support for `text'

src/markdown.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,14 +1638,44 @@ int Markdown::Private::processCodeSpan(std::string_view data,size_t offset)
16381638
nb++;
16391639
}
16401640

1641-
/* finding the next delimiter */
1641+
/* finding the next delimiter with the same amount of backticks */
16421642
size_t i = 0;
16431643
char pc = '`';
1644-
for (end=nb; end<size && i<nb; end++)
1644+
for (end=nb; end<size; end++)
16451645
{
1646+
//AUTO_TRACE_ADD("c={} nb={} i={} size={}",data[end],nb,i,size);
16461647
if (data[end]=='`')
16471648
{
16481649
i++;
1650+
if (nb==1) // `...`
1651+
{
1652+
if (end<size && data[end+1]=='`') // skip over `` inside `...`
1653+
{
1654+
AUTO_TRACE_ADD("case1.1");
1655+
// skip
1656+
end++;
1657+
i=0;
1658+
}
1659+
else // normal end of `...`
1660+
{
1661+
AUTO_TRACE_ADD("case1.2");
1662+
break;
1663+
}
1664+
}
1665+
else if (i==nb) // ``...``
1666+
{
1667+
if (end<size && data[end+1]=='`') // do greedy match
1668+
{
1669+
// skip this quote and use the next one to terminate the sequence, e.g. ``X`Y```
1670+
i--;
1671+
AUTO_TRACE_ADD("case2.1");
1672+
}
1673+
else // normal end of ``...``
1674+
{
1675+
AUTO_TRACE_ADD("case2.2");
1676+
break;
1677+
}
1678+
}
16491679
}
16501680
else if (data[end]=='\n')
16511681
{
@@ -1658,14 +1688,22 @@ int Markdown::Private::processCodeSpan(std::string_view data,size_t offset)
16581688
pc = '\n';
16591689
i = 0;
16601690
}
1661-
else if (data[end]=='\'' && nb==1 && (end==size-1 || (end+1<size && !isIdChar(data[end+1]))))
1691+
else if (data[end]=='\'' && nb==1 && (end==size-1 || (end+1<size && data[end+1]!='\'' && !isIdChar(data[end+1]))))
16621692
{ // look for quoted strings like 'some word', but skip strings like `it's cool`
16631693
out+="&lsquo;";
16641694
out+=data.substr(nb,end-nb);
16651695
out+="&rsquo;";
16661696
AUTO_TRACE_EXIT("quoted end={}",end+1);
16671697
return static_cast<int>(end+1);
16681698
}
1699+
else if (data[end]=='\'' && nb==2 && end<size-1 && data[end+1]=='\'')
1700+
{ // look for '' to match a ``
1701+
out+="&ldquo;";
1702+
out+=data.substr(nb,end-nb);
1703+
out+="&rdquo;";
1704+
AUTO_TRACE_EXIT("double quoted end={}",end+1);
1705+
return static_cast<int>(end+2);
1706+
}
16691707
else
16701708
{
16711709
if (data[end]!=' ') pc = data[end];

src/scanner.l

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7338,7 +7338,14 @@ NONLopt [^\n]*
73387338
yyextra->docBlock << yytext;
73397339
}
73407340
}
7341-
<DocCopyBlock>"'"/[^a-z_A-Z0-9-] {
7341+
<DocCopyBlock>"''"/[^a-z_A-Z0-9-] {
7342+
if (endVerbatimBlock(yyscanner,"``",2))
7343+
{
7344+
BEGIN(DocBlock);
7345+
}
7346+
yyextra->docBlock << yytext;
7347+
}
7348+
<DocCopyBlock>"'"/[^'a-z_A-Z0-9-] {
73427349
if (endVerbatimBlock(yyscanner,"`",1))
73437350
{
73447351
BEGIN(DocBlock);

templates/html/doxygen.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ pre.fragment {
338338
span.tt {
339339
white-space: pre;
340340
font-family: var(--font-family-monospace);
341+
background-color: var(--fragment-background-color);
341342
}
342343

343344
.clipboard {

testing/110/indexpage.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,13 @@
1212
Text with <computeroutput>double</computeroutput> backtick. <linebreak/>
1313
Text with <computeroutput>double and `single` form</computeroutput> of backticks. <linebreak/>
1414
Text with <computeroutput>double backtick `ending`</computeroutput> in triple backtick. <linebreak/>
15+
Text with <computeroutput>double backtick `` inside single</computeroutput> backtick. <linebreak/>
1516
Text with `escaped` backticks. <linebreak/>
1617
Text with triple ``` backtick not at the start of the line. <linebreak/>
18+
Text with <computeroutput>X``Y</computeroutput> embedded double backticks inside backticks. <linebreak/>
19+
Text in double quotes <ldquo/>left`right<rdquo/> with embedded backtick. <linebreak/>
20+
Text in double quotes <ldquo/>left'right<rdquo/> with embedded single quote. <linebreak/>
21+
Text in single quotes <lsquo/>left''right<rsquo/> with embedded double quote. <linebreak/>
1722
<programlisting><codeline><highlight class="normal">Text<sp/>inside<sp/>triple<sp/>backticks</highlight></codeline><codeline><highlight class="normal">Nested<sp/>`single`<sp/>backtick</highlight></codeline><codeline><highlight class="normal">Nested<sp/>``</highlight><highlight class="keywordtype">double</highlight><highlight class="normal">``<sp/>backtick</highlight></codeline></programlisting> More text after triple backtick section. </para>
1823
</detaileddescription>
1924
<location file="110_backticks.dox"/>

testing/110_backticks.dox

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ Text `it's cool`. with embedded '
77
Text with ``double`` backtick.
88
Text with ``double and `single` form`` of backticks.
99
Text with ``double backtick `ending``` in triple backtick.
10+
Text with `double backtick `` inside single` backtick.
1011
Text with \`escaped\` backticks.
1112
Text with triple ``` backtick not at the start of the line.
13+
Text with `X``Y` embedded double backticks inside backticks.
14+
Text in double quotes ``left`right'' with embedded backtick.
15+
Text in double quotes ``left'right'' with embedded single quote.
16+
Text in single quotes `left''right' with embedded double quote.
1217
```
1318
Text inside triple backticks
1419
Nested `single` backtick

0 commit comments

Comments
 (0)