Skip to content

Commit 4ac0bdc

Browse files
authored
Merge pull request #419 from bruntib/doc_commend_markdown
Cpp documentation comments in markdown format
2 parents c1e89d9 + 6ea97d5 commit 4ac0bdc

6 files changed

Lines changed: 55 additions & 120 deletions

File tree

plugins/cpp/model/include/model/cppdoccomment.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct CppDocComment
2626
unsigned long long contentHash;
2727

2828
#pragma db not_null
29-
std::string contentHTML;
29+
std::string content;
3030

3131
#pragma db not_null index
3232
unsigned long long mangledNameHash;

plugins/cpp/parser/src/doccommentcollector.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ class DocCommentCollector :
5757
DocCommentFormatter dcFmt;
5858

5959
model::CppDocCommentPtr pc(new model::CppDocComment);
60-
pc->contentHTML = dcFmt.format(fc, _astContext);
61-
pc->contentHash = util::fnvHash(pc->contentHTML);
60+
pc->content = dcFmt.format(fc, _astContext);
61+
pc->contentHash = util::fnvHash(pc->content);
6262
pc->mangledNameHash = _mangledNameCache.at(it->second);
6363
_docComments.insert(std::make_pair(
6464
std::make_pair(pc->mangledNameHash, pc->contentHash), pc));

plugins/cpp/parser/src/doccommentformatter.cpp

Lines changed: 46 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,11 @@ FullCommentParts::FullCommentParts(
146146
}
147147

148148
// https://llvm.org/svn/llvm-project/cfe/trunk/lib/Index/CommentToXML.cpp
149-
class CommentToHTMLConverter
150-
: public ConstCommentVisitor<CommentToHTMLConverter>
149+
class CommentToMarkdownConverter
150+
: public ConstCommentVisitor<CommentToMarkdownConverter>
151151
{
152152
public:
153-
CommentToHTMLConverter(
153+
CommentToMarkdownConverter(
154154
const FullComment* fullComment_,
155155
const CommandTraits& traits_,
156156
std::stringstream& res_)
@@ -225,12 +225,6 @@ class CommentToHTMLConverter
225225
*/
226226
void visitNonStandaloneParagraphComment(const ParagraphComment* c_);
227227

228-
/**
229-
* This function escapes html elements from parameter and appends the escaped
230-
* string to the result.
231-
*/
232-
void appendToResultWithHTMLEscaping(const clang::StringRef& str_);
233-
234228
private:
235229
const FullComment* _fullComment;
236230
const CommandTraits& _traits;
@@ -239,33 +233,12 @@ class CommentToHTMLConverter
239233

240234
}
241235

242-
void CommentToHTMLConverter::appendToResultWithHTMLEscaping(
243-
const clang::StringRef& str_)
236+
void CommentToMarkdownConverter::visitTextComment(const TextComment* c_)
244237
{
245-
for (clang::StringRef::iterator it = str_.begin(), end = str_.end();
246-
it != end; ++it)
247-
{
248-
switch (*it)
249-
{
250-
case '&': _res << "&amp;"; break;
251-
case '<': _res << "&lt;"; break;
252-
case '>': _res << "&gt;"; break;
253-
case '"': _res << "&quot;"; break;
254-
case '\'': _res << "&#39;"; break;
255-
case '/': _res << "&#47;"; break;
256-
default: _res << *it; break;
257-
}
258-
}
238+
_res << c_->getText().ltrim().str() << ' ';
259239
}
260240

261-
void CommentToHTMLConverter::visitTextComment(const TextComment* c_)
262-
{
263-
_res << "<div class=\"comment\">";
264-
appendToResultWithHTMLEscaping(c_->getText());
265-
_res << "</div>";
266-
}
267-
268-
void CommentToHTMLConverter::visitInlineCommandComment(
241+
void CommentToMarkdownConverter::visitInlineCommandComment(
269242
const InlineCommandComment* c_)
270243
{
271244
// Nothing to render if argument is empty.
@@ -280,166 +253,135 @@ void CommentToHTMLConverter::visitInlineCommandComment(
280253
{
281254
case InlineCommandComment::RenderNormal:
282255
for (unsigned i = 0, e = c_->getNumArgs(); i != e; ++i)
283-
{
284-
appendToResultWithHTMLEscaping(c_->getArgText(i));
285-
_res << " ";
286-
}
256+
_res << c_->getArgText(i).str() << ' ';
287257
return;
288258

289259
case InlineCommandComment::RenderBold:
290260
assert(c_->getNumArgs() == 1);
291-
_res << "<b>";
292-
appendToResultWithHTMLEscaping(arg0);
293-
_res << "</b>";
261+
_res << "**" << arg0.str() << "**";
294262
return;
295263

296264
case InlineCommandComment::RenderMonospaced:
297265
assert(c_->getNumArgs() == 1);
298-
_res << "<tt>";
299-
appendToResultWithHTMLEscaping(arg0);
300-
_res<< "</tt>";
266+
_res << '`' << arg0.str() << '`';
301267
return;
302268

303269
case InlineCommandComment::RenderEmphasized:
304270
assert(c_->getNumArgs() == 1);
305-
_res << "<em>";
306-
appendToResultWithHTMLEscaping(arg0);
307-
_res << "</em>";
271+
_res << '*' << arg0.str() << '*';
308272
return;
309273
}
310274
}
311275

312-
void CommentToHTMLConverter::visitHTMLStartTagComment(
276+
void CommentToMarkdownConverter::visitHTMLStartTagComment(
313277
const HTMLStartTagComment* c_)
314278
{
315-
_res << "<" << c_->getTagName().str();
279+
_res << '<' << c_->getTagName().str();
316280

317281
if (c_->getNumAttrs())
318282
for (unsigned i = 0, e = c_->getNumAttrs(); i != e; i++)
319283
{
320-
_res << " ";
284+
_res << ' ';
321285
const HTMLStartTagComment::Attribute &Attr = c_->getAttr(i);
322286
_res << Attr.Name.str();
323287
if (!Attr.Value.empty())
324-
_res << "=\"" << Attr.Value.str() << "\"";
288+
_res << "=\"" << Attr.Value.str() << '"';
325289
}
326290

327291
if (!c_->isSelfClosing())
328-
_res << ">";
292+
_res << '>';
329293
else
330294
_res << "/>";
331295
}
332296

333-
void CommentToHTMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment* c_)
297+
void CommentToMarkdownConverter::visitHTMLEndTagComment(
298+
const HTMLEndTagComment* c_)
334299
{
335-
_res << "</" << c_->getTagName().str() << ">";
300+
_res << "</" << c_->getTagName().str() << '>';
336301
}
337302

338-
void CommentToHTMLConverter::visitParagraphComment(const ParagraphComment* c_)
303+
void CommentToMarkdownConverter::visitParagraphComment(
304+
const ParagraphComment* c_)
339305
{
340306
if (c_->isWhitespace())
341307
return;
342308

343-
_res << "<div>";
344309
for (Comment::child_iterator it = c_->child_begin(), end = c_->child_end();
345310
it != end; ++it)
346311
visit(*it);
347-
348-
_res << "</div>";
349312
}
350313

351-
void CommentToHTMLConverter::visitBlockCommandComment(
314+
void CommentToMarkdownConverter::visitBlockCommandComment(
352315
const BlockCommandComment* c_)
353316
{
354317
const CommandInfo *info = _traits.getCommandInfo(c_->getCommandID());
355318
if (info->IsBriefCommand)
356319
{
357-
_res << "<div class=\"para-brief\">";
358320
visitNonStandaloneParagraphComment(c_->getParagraph());
359-
_res << "</div>";
360-
361321
return;
362322
}
363323

364324
if (info->IsReturnsCommand)
365325
{
366-
_res << "<div class=\"para-returns\">"
367-
"<span class=\"word-returns\">Returns</span> ";
368326
visitNonStandaloneParagraphComment(c_->getParagraph());
369-
_res << "</div>";
370-
371327
return;
372328
}
373329

374330
// We don't know anything about this command. Just render the paragraph.
375331
visit(c_->getParagraph());
376332
}
377333

378-
void CommentToHTMLConverter::visitParamCommandComment(
334+
void CommentToMarkdownConverter::visitParamCommandComment(
379335
const ParamCommandComment* c_)
380336
{
381-
_res << "<dl class=\"param\"><dt>Parameter</dt><dd>";
382-
_res << "<div class=\"dir\">";
383-
384337
switch (c_->getDirection())
385338
{
386-
case ParamCommandComment::In: _res << "in"; break;
387-
case ParamCommandComment::Out: _res << "out"; break;
388-
case ParamCommandComment::InOut: _res << "in,out"; break;
339+
case ParamCommandComment::In: _res << "- *in*: "; break;
340+
case ParamCommandComment::Out: _res << "- *out*: "; break;
341+
case ParamCommandComment::InOut: _res << "- *in,out*: "; break;
389342
}
390343

391-
_res << "</div><div class=\"name\">";
392-
393-
appendToResultWithHTMLEscaping(c_->isParamIndexValid()
344+
_res << "**" << (c_->isParamIndexValid()
394345
? c_->getParamName(_fullComment)
395-
: c_->getParamNameAsWritten());
396-
397-
_res << "</div>";
346+
: c_->getParamNameAsWritten()).str() << "** ";
398347

399348
visit(c_->getParagraph());
400-
401-
_res << "</dd></dl>";
349+
_res << '\n';
402350
}
403351

404-
void CommentToHTMLConverter::visitTParamCommandComment(
352+
void CommentToMarkdownConverter::visitTParamCommandComment(
405353
const TParamCommandComment* c_)
406354
{
407-
_res << "<dl class=\"tparam\"><dt>Template parameter</dt><dd>";
408-
_res << "<div class=\"name\">";
409-
appendToResultWithHTMLEscaping(c_->getParamNameAsWritten());
410-
_res << "</div>";
411-
355+
_res << "- **" << c_->getParamNameAsWritten().str() << "**: ";
412356
visitNonStandaloneParagraphComment(c_->getParagraph());
413-
_res << "</dd></dl>";
357+
_res << '\n';
414358
}
415359

416-
void CommentToHTMLConverter::visitVerbatimBlockComment(
360+
void CommentToMarkdownConverter::visitVerbatimBlockComment(
417361
const VerbatimBlockComment* c_)
418362
{
419363
unsigned numLines = c_->getNumLines();
420364

421365
if (!numLines)
422366
return;
423367

424-
_res << "<pre>";
368+
_res << "```\n";
425369
for (unsigned i = 0; i != numLines; ++i)
426370
{
427-
appendToResultWithHTMLEscaping(c_->getText(i));
371+
_res << c_->getText(i).str();
428372
if (i + 1 != numLines)
429373
_res << '\n';
430374
}
431-
_res << "</pre>";
375+
_res << "\n```";
432376
}
433377

434-
void CommentToHTMLConverter::visitVerbatimLineComment(
378+
void CommentToMarkdownConverter::visitVerbatimLineComment(
435379
const VerbatimLineComment* c_)
436380
{
437-
_res << "<pre>";
438-
appendToResultWithHTMLEscaping(c_->getText());
439-
_res << "</pre>";
381+
_res << '`' << c_->getText().str() << '`';
440382
}
441383

442-
void CommentToHTMLConverter::visitFullComment(const FullComment* c_)
384+
void CommentToMarkdownConverter::visitFullComment(const FullComment* c_)
443385
{
444386
FullCommentParts parts(c_, _traits);
445387

@@ -450,13 +392,11 @@ void CommentToHTMLConverter::visitFullComment(const FullComment* c_)
450392

451393
if (parts._brief)
452394
visit(parts._brief);
453-
454395
else if (parts._firstParagraph)
455396
{
456-
_res << "<div class=\"para-_brief\">";
457397
visitNonStandaloneParagraphComment(parts._firstParagraph);
458-
_res << "</div>";
459398
_firstParagraphIsBrief = true;
399+
_res << "\n\n";
460400
}
461401

462402
for (unsigned i = 0, e = parts._miscBlocks.size(); i != e; ++i)
@@ -467,40 +407,35 @@ void CommentToHTMLConverter::visitFullComment(const FullComment* c_)
467407
continue;
468408

469409
visit(C);
410+
_res << "\n\n";
470411
}
471412

472413
if (parts._tParams.size() != 0)
473414
{
474-
_res << "<dl>";
415+
_res << "\n**Template parameters:**\n";
475416

476417
for (unsigned i = 0, e = parts._tParams.size(); i != e; ++i)
477418
visit(parts._tParams[i]);
478-
479-
_res << "</dl>";
480419
}
481420

482421
if (parts._params.size() != 0)
483422
{
484-
_res << "<dl>";
423+
_res << "\n**Parameters:**\n";
485424

486425
for (unsigned i = 0, e = parts._params.size(); i != e; ++i)
487426
visit(parts._params[i]);
488-
489-
_res << "</dl>";
490427
}
491428

492429
if (parts._returns.size() != 0)
493430
{
494-
_res << "<div class=\"result-discussion\">";
431+
_res << "\n**Return:**\n";
495432

496433
for (unsigned i = 0, e = parts._returns.size(); i != e; ++i)
497434
visit(parts._returns[i]);
498-
499-
_res << "</div>";
500435
}
501436
}
502437

503-
void CommentToHTMLConverter::visitNonStandaloneParagraphComment(
438+
void CommentToMarkdownConverter::visitNonStandaloneParagraphComment(
504439
const ParagraphComment* c_)
505440
{
506441
if (!c_)
@@ -522,9 +457,9 @@ std::string DocCommentFormatter::format(
522457
const clang::ASTContext& ctx_)
523458
{
524459
std::stringstream res;
525-
CommentToHTMLConverter htmlConverter(
460+
CommentToMarkdownConverter markdownConverter(
526461
fc_, ctx_.getCommentCommandTraits(), res);
527-
htmlConverter.visit(fc_);
462+
markdownConverter.visit(fc_);
528463

529464
return res.str();
530465
}

plugins/cpp/parser/src/doccommentformatter.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ namespace parser
99
{
1010

1111
/**
12-
* Converts a clang::comments::FullComment into an HTML text.
12+
* Converts a clang::comments::FullComment into a Markdown text.
1313
*/
1414
class DocCommentFormatter
1515
{
1616
public:
1717

1818
/**
19-
* Converts a clang::comments::FullComment into an HTML text.
19+
* Converts a clang::comments::FullComment into a Markdown text.
2020
*
2121
* @param fc The comment to be formatted.
22-
* @return the HTML-formatted string.
22+
* @return the Markdown-formatted string.
2323
*/
2424
std::string format(
2525
clang::comments::FullComment* fc,

plugins/cpp/service/src/cppservice.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ void CppServiceHandler::getDocumentation(
169169
DocCommentQuery::mangledNameHash == node.mangledNameHash);
170170

171171
if (!docComment.empty())
172-
return_ = "<div class=\"main-doc\">" + docComment.begin()->contentHTML
172+
return_ = "<div class=\"main-doc\">" + docComment.begin()->content
173173
+ "</div>";
174174

175175
switch (node.symbolType)
@@ -212,7 +212,7 @@ void CppServiceHandler::getDocumentation(
212212
DocCommentQuery::mangledNameHash == method.mangledNameHash);
213213

214214
if (!doc.empty())
215-
return_ += doc.begin()->contentHTML;
215+
return_ += doc.begin()->content;
216216

217217
return_ += "</div>";
218218
}

0 commit comments

Comments
 (0)