Skip to content

Commit c526c57

Browse files
committed
feat: asciidoc universal escaping
Replace escaping based on passthroughs without universal escaping based on character substitutions: https://docs.asciidoctor.org/asciidoc/latest/subs/replacements/ fix cppalliance#763
1 parent be64902 commit c526c57

File tree

110 files changed

+3751
-2655
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+3751
-2655
lines changed

share/mrdocs/addons/generator/adoc/partials/markup/code-block.adoc.hbs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[source,cpp,subs="verbatim,macros,-callouts"]
1+
[source,cpp,subs="verbatim,replacements,macros,-callouts"]
22
----
33
{{> @partial-block }}
44
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{{#if id}}[#{{{id}}}]
22
{{/if}}
3-
={{select level (repeat "=" level) (select @root.config.multipage "==" "=")}} {{> @partial-block }}
3+
={{{select level (repeat "=" level) (select @root.config.multipage "==" "=")}}} {{> @partial-block }}

share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
{{>location/source dcl=(primary_location symbol)}}
3030

31+
3132
{{> symbol/signatures symbol }}
3233
{{/unless}}
3334
{{! Tranches }}

share/mrdocs/addons/generator/html/partials/symbol.html.hbs

+9-9
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@
133133
{{#each symbol.doc.exceptions}}
134134
<tr>
135135
<td><code>{{exception}}</code></td>
136-
<td>{{description}}</td>
136+
<td>{{{description}}}</td>
137137
</tr>
138138
{{/each}}
139139
</tbody>
@@ -156,7 +156,7 @@
156156
{{#each allExceptions as |exception|}}
157157
<tr>
158158
<td><code>{{exception}}</code></td>
159-
<td>{{description}}</td>
159+
<td>{{{description}}}</td>
160160
</tr>
161161
{{/each}}
162162
</tbody>
@@ -188,7 +188,7 @@
188188
{{#each symbol.doc.tparams}}
189189
<tr>
190190
<td><strong>{{name}}</strong></td>
191-
<td>{{description}}</td>
191+
<td>{{{description}}}</td>
192192
</tr>
193193
{{/each}}
194194
</tbody>
@@ -211,7 +211,7 @@
211211
{{#each allTParams as |param|}}
212212
<tr>
213213
<td><strong>{{param.name}}</strong></td>
214-
<td>{{param.description}}</td>
214+
<td>{{{param.description}}}</td>
215215
</tr>
216216
{{/each}}
217217
</tbody>
@@ -236,7 +236,7 @@
236236
{{#each symbol.doc.params}}
237237
<tr>
238238
<td><strong>{{name}}</strong></td>
239-
<td>{{description}}</td>
239+
<td>{{{description}}}</td>
240240
</tr>
241241
{{/each}}
242242
</tbody>
@@ -259,7 +259,7 @@
259259
{{#each allParams as |param|}}
260260
<tr>
261261
<td><strong>{{param.name}}</strong></td>
262-
<td>{{param.description}}</td>
262+
<td>{{{param.description}}}</td>
263263
</tr>
264264
{{/each}}
265265
</tbody>
@@ -273,7 +273,7 @@
273273
<div>
274274
{{#> markup/dynamic-level-h level=2 }}Preconditions{{/markup/dynamic-level-h}}
275275
{{#each symbol.doc.preconditions}}
276-
<p>{{.}}</p>
276+
<p>{{{.}}}</p>
277277
{{/each}}
278278
</div>
279279
{{/if}}
@@ -282,7 +282,7 @@
282282
<div>
283283
{{#> markup/dynamic-level-h level=2 }}Postconditions{{/markup/dynamic-level-h}}
284284
{{#each symbol.doc.postconditions}}
285-
<p>{{.}}</p>
285+
<p>{{{.}}}</p>
286286
{{/each}}
287287
</div>
288288
{{/if}}
@@ -291,7 +291,7 @@
291291
<div>
292292
{{#> markup/dynamic-level-h level=2 }}See Also{{/markup/dynamic-level-h}}
293293
{{#each symbol.doc.see}}
294-
<p>{{.}}</p>
294+
<p>{{{.}}}</p>
295295
{{/each}}
296296
</div>
297297
{{/if}}

src/lib/Gen/adoc/AdocEscape.cpp

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//
2+
// This is a derivative work. originally part of the LLVM Project.
3+
// Licensed under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
// Copyright (c) 2023 Vinnie Falco ([email protected])
8+
//
9+
// Official repository: https://github.com/cppalliance/mrdocs
10+
//
11+
12+
#include "AdocEscape.hpp"
13+
#include <mrdocs/Support/Handlebars.hpp>
14+
15+
namespace clang::mrdocs::adoc {
16+
17+
namespace {
18+
19+
constexpr
20+
std::optional<std::string_view>
21+
HTMLNamedEntity(char const c)
22+
{
23+
// If c has a named entity, we use it
24+
// Otherwise, we return std::nullopt
25+
switch (c)
26+
{
27+
case '~': return "&tilde;";
28+
case '^': return "&circ;";
29+
case '_': return "&lowbar;";
30+
case '*': return "&ast;";
31+
case '`': return "&grave;";
32+
case '#': return "&num;";
33+
case '[': return "&lsqb;";
34+
case ']': return "&rsqb;";
35+
case '{': return "&lcub;";
36+
case '}': return "&rcub;";
37+
case '<': return "&lt;";
38+
case '>': return "&gt;";
39+
case '\\': return "&bsol;";
40+
case '|': return "&verbar;";
41+
case '-': return "&hyphen;";
42+
case '=': return "&equals;";
43+
case '&': return "&amp;";
44+
case ';': return "&semi;";
45+
case '+': return "&plus;";
46+
case ':': return "&colon;";
47+
case '.': return "&period;";
48+
case '"': return "&quot;";
49+
case '\'': return "&apos;";
50+
case '/': return "&sol;";
51+
default:
52+
break;
53+
}
54+
return {};
55+
}
56+
57+
} // (anon)
58+
59+
void
60+
AdocEscape(OutputRef& os, std::string_view str)
61+
{
62+
static constexpr char reserved[] = R"(~^_*`#[]{}<>\|-=&;+:."\'/)";
63+
for (char c: str)
64+
{
65+
if (std::ranges::find(reserved, c) != std::end(reserved))
66+
{
67+
// https://docs.asciidoctor.org/asciidoc/latest/subs/replacements/
68+
if (auto e = HTMLNamedEntity(c))
69+
{
70+
os << *e;
71+
}
72+
else
73+
{
74+
os << "&#" << static_cast<int>(c) << ';';
75+
}
76+
}
77+
else
78+
{
79+
os << c;
80+
}
81+
}
82+
}
83+
84+
std::string
85+
AdocEscape(std::string_view str) {
86+
std::string res;
87+
OutputRef os(res);
88+
AdocEscape(os, str);
89+
return res;
90+
}
91+
92+
93+
} // clang::mrdocs::adoc

src/lib/Gen/adoc/AdocEscape.hpp

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// This is a derivative work. originally part of the LLVM Project.
3+
// Licensed under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
// Copyright (c) 2023 Vinnie Falco ([email protected])
8+
// Copyright (c) 2024 Alan de Freitas ([email protected])
9+
//
10+
// Official repository: https://github.com/cppalliance/mrdocs
11+
//
12+
13+
#ifndef MRDOCS_LIB_GEN_ADOC_ADOCESCAPE_HPP
14+
#define MRDOCS_LIB_GEN_ADOC_ADOCESCAPE_HPP
15+
16+
#include <mrdocs/Support/Handlebars.hpp>
17+
#include <string>
18+
#include <string_view>
19+
20+
namespace clang::mrdocs::adoc {
21+
22+
/** Escape a string for use in AsciiDoc
23+
*/
24+
MRDOCS_DECL
25+
void
26+
AdocEscape(OutputRef& os, std::string_view str);
27+
28+
MRDOCS_DECL
29+
std::string
30+
AdocEscape(std::string_view str);
31+
32+
} // clang::mrdocs::adoc
33+
34+
#endif

src/lib/Gen/adoc/AdocGenerator.cpp

+5-24
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
//
1111

1212
#include "AdocGenerator.hpp"
13+
#include "AdocEscape.hpp"
1314
#include "DocVisitor.hpp"
1415
#include <mrdocs/Support/Handlebars.hpp>
1516

16-
namespace clang {
17-
namespace mrdocs {
17+
namespace clang::mrdocs {
1818
namespace adoc {
1919

2020
AdocGenerator::
@@ -34,27 +34,9 @@ toString(hbs::HandlebarsCorpus const& c, doc::Node const& I) const
3434

3535
void
3636
AdocGenerator::
37-
escape(OutputRef& os, std::string_view str) const
37+
escape(OutputRef& os, std::string_view const str) const
3838
{
39-
static constexpr std::string_view formattingChars = "\\`*_{}[]()#+-.!|";
40-
bool const needsEscape = str.find_first_of(formattingChars) != std::string_view::npos;
41-
if (needsEscape)
42-
{
43-
os << "pass:[";
44-
// Using passthroughs to pass content (without substitutions) can couple
45-
// your content to a specific output format, such as HTML.
46-
// In these cases, you should use conditional preprocessor directives
47-
// to route passthrough content for different output formats based on
48-
// the current backend.
49-
// If we would like to couple passthrough content to an HTML format,
50-
// then we'd use `HTMLEscape(os, str)` instead of `os << str`.
51-
os << str;
52-
os << "]";
53-
}
54-
else
55-
{
56-
os << str;
57-
}
39+
AdocEscape(os, str);
5840
}
5941

6042
} // adoc
@@ -65,5 +47,4 @@ makeAdocGenerator()
6547
return std::make_unique<adoc::AdocGenerator>();
6648
}
6749

68-
} // mrdocs
69-
} // clang
50+
} // clang::mrdocs

0 commit comments

Comments
 (0)