diff --git a/include/mrdocs/Metadata/Javadoc.hpp b/include/mrdocs/Metadata/Javadoc.hpp index bd64a50c0b..4f63407485 100644 --- a/include/mrdocs/Metadata/Javadoc.hpp +++ b/include/mrdocs/Metadata/Javadoc.hpp @@ -116,6 +116,7 @@ enum class Kind heading, link, list_item, + unordered_list, paragraph, param, returns, @@ -178,6 +179,12 @@ enum class Parts //-------------------------------------------- /** This is a variant-like list element. + + There are two types of nodes: text and block. + + - The javadoc is a list of blocks. + - A block contains a list of text elements. + - A text element contains a string. */ struct MRDOCS_DECL Node @@ -367,6 +374,8 @@ struct Copied : Reference /** A piece of block content The top level is a list of blocks. + + There are two types of blocks: headings and paragraphs */ struct MRDOCS_DECL Block : Node @@ -447,7 +456,7 @@ struct Heading : Block bool equals(const Node& other) const noexcept override { return kind == other.kind && - *this == static_cast(other); + *this == dynamic_cast(other); } }; @@ -494,7 +503,7 @@ struct Brief : Paragraph bool equals(const Node& other) const noexcept override { return kind == other.kind && - *this == static_cast(other); + *this == dynamic_cast(other); } }; @@ -520,7 +529,7 @@ struct Admonition : Paragraph bool equals(const Node& other) const noexcept override { return kind == other.kind && - *this == static_cast(other); + *this == dynamic_cast(other); } }; @@ -542,7 +551,7 @@ struct Code : Paragraph bool equals(const Node& other) const noexcept override { return kind == other.kind && - *this == static_cast(other); + *this == dynamic_cast(other); } }; @@ -563,7 +572,31 @@ struct ListItem : Paragraph bool equals(const Node& other) const noexcept override { return kind == other.kind && - *this == static_cast(other); + *this == dynamic_cast(other); + } +}; + +/** A list of list items +*/ +struct UnorderedList : Paragraph +{ + static constexpr Kind static_kind = Kind::unordered_list; + + // Vector of list items + List items; + + UnorderedList() + : Paragraph(Kind::unordered_list) + { + } + + bool operator==(const UnorderedList&) + const noexcept = default; + + bool equals(const Node& other) const noexcept override + { + return kind == other.kind && + *this == dynamic_cast(other); } }; @@ -784,6 +817,8 @@ visit( return f.template operator()(std::forward(args)...); case Kind::list_item: return f.template operator()(std::forward(args)...); + case Kind::unordered_list: + return f.template operator()(std::forward(args)...); case Kind::paragraph: return f.template operator()(std::forward(args)...); case Kind::param: @@ -851,6 +886,8 @@ visit( return visitor.template visit(); case Kind::list_item: return visitor.template visit(); + case Kind::unordered_list: + return visitor.template visit(); case Kind::param: return visitor.template visit(); case Kind::returns: @@ -917,12 +954,11 @@ class Corpus; /** A processed Doxygen-style comment attached to a declaration. */ -class MRDOCS_DECL +struct MRDOCS_DECL Javadoc { doc::List blocks_; -public: /** Constructor. */ MRDOCS_DECL diff --git a/include/mrdocs/MetadataFwd.hpp b/include/mrdocs/MetadataFwd.hpp index f0ee169ee7..e5799250af 100644 --- a/include/mrdocs/MetadataFwd.hpp +++ b/include/mrdocs/MetadataFwd.hpp @@ -41,7 +41,7 @@ struct Type##Info; struct BaseInfo; struct Info; -class Javadoc; +struct Javadoc; struct Location; struct NameInfo; struct Param; diff --git a/mrdocs.rnc b/mrdocs.rnc index 74256dbac3..baa8e5974e 100644 --- a/mrdocs.rnc +++ b/mrdocs.rnc @@ -386,14 +386,15 @@ grammar BlockNode = ( Admonition | Brief | Code | Heading | ListItem | - Paragraph | Param | Returns | TParam | Throws | - See | Precondition | Postcondition | Details) + UnorderedList | Paragraph | Param | Returns | TParam | + Throws | See | Precondition | Postcondition | Details) Admonition = Paragraph Brief = element brief { TextNode * } Code = element code { TextNode* } Heading = element head { text } ListItem = element listitem { TextNode* } + UnorderedList = element unorderedlist { ListItem * } Paragraph = element para { attribute class { text } ?, TextNode * } diff --git a/src/lib/AST/ParseJavadoc.cpp b/src/lib/AST/ParseJavadoc.cpp index fcb800c902..7fabf90d74 100644 --- a/src/lib/AST/ParseJavadoc.cpp +++ b/src/lib/AST/ParseJavadoc.cpp @@ -39,7 +39,7 @@ #define MRDOCS_COMMENT_TRACE(D, C) #else -# define MRDOCS_COMMENT_TRACE_MERGE_(a, b) a##b +# define MRDOCS_COMMENT_TRACE_MERGE_(a, b) a## b # define MRDOCS_COMMENT_TRACE_LABEL_(a) MRDOCS_COMMENT_TRACE_MERGE_(comment_content_, a) # define MRDOCS_COMMENT_TRACE_UNIQUE_NAME MRDOCS_COMMENT_TRACE_LABEL_(__LINE__) @@ -564,7 +564,7 @@ visitChildren( { MRDOCS_COMMENT_TRACE(*it_, ctx_); visit(*it_); - ++it_; // must happen after + ++it_; } if (!block_) @@ -649,6 +649,35 @@ build() { MRDOCS_COMMENT_TRACE(FC_, ctx_); visit(FC_); + + // Merge ListItems into UnorderedList + auto& blocks = jd_.getBlocks(); + for (auto it = blocks.begin(); it != blocks.end(); ) { + if ((*it)->kind == doc::Kind::list_item) { + doc::UnorderedList ul; + // Find last list item + auto const begin = it; + auto last = it; + while (last != blocks.end() && (*last)->kind == doc::Kind::list_item) { + ++last; + } + // Move list items to ul.items + ul.items.reserve(std::distance(it, last)); + for (auto li_it = begin; li_it != last; ++li_it) { + std::unique_ptr block = std::move(*li_it); + MRDOCS_ASSERT(dynamic_cast(block.get())); + doc::Block* raw_block_ptr = block.release(); + auto const raw_li_ptr = static_cast(raw_block_ptr); + auto li = std::make_unique(std::move(*raw_li_ptr)); + ul.items.emplace_back(std::move(li)); + } + // Remove the list items and insert the ul + it = blocks.erase(begin, last); + it = blocks.insert(it, std::make_unique(std::move(ul))); + } + ++it; + } + return std::move(jd_); } diff --git a/src/lib/Gen/adoc/DocVisitor.cpp b/src/lib/Gen/adoc/DocVisitor.cpp index 00f601c8c3..fb11232b4e 100644 --- a/src/lib/Gen/adoc/DocVisitor.cpp +++ b/src/lib/Gen/adoc/DocVisitor.cpp @@ -170,9 +170,11 @@ operator()( doc::ListItem const& I) const { std::span children = I.children; - if(children.empty()) + if (children.empty()) + { return; - dest_.append("\n* "); + } + dest_.append("* "); bool non_empty = write(*children.front(), *this); for(auto const& child : children.subspan(1)) { @@ -185,6 +187,22 @@ operator()( dest_.push_back('\n'); } +void +DocVisitor:: +operator()( + doc::UnorderedList const& I) const +{ + if (I.items.empty()) + { + return; + } + for(auto const& child : I.items) + { + operator()(*child); + } + dest_.push_back('\n'); +} + void DocVisitor:: operator()(doc::Param const& I) const diff --git a/src/lib/Gen/adoc/DocVisitor.hpp b/src/lib/Gen/adoc/DocVisitor.hpp index c8acfc13e6..1e15e8b292 100644 --- a/src/lib/Gen/adoc/DocVisitor.hpp +++ b/src/lib/Gen/adoc/DocVisitor.hpp @@ -68,6 +68,9 @@ class DocVisitor void operator()(doc::ListItem const& I) const; + void + operator()(doc::UnorderedList const& I) const; + void operator()(doc::Param const& I) const; diff --git a/src/lib/Gen/html/DocVisitor.cpp b/src/lib/Gen/html/DocVisitor.cpp index 547dd8d759..72c078d356 100644 --- a/src/lib/Gen/html/DocVisitor.cpp +++ b/src/lib/Gen/html/DocVisitor.cpp @@ -211,6 +211,23 @@ operator()( dest_.append("\n"); } +void +DocVisitor:: +operator()( + doc::UnorderedList const& I) const +{ + if (I.items.empty()) + { + return; + } + dest_.append("
    \n"); + for(auto const& child : I.items) + { + operator()(*child); + } + dest_.append("
\n"); +} + void DocVisitor:: operator()(doc::Param const& I) const diff --git a/src/lib/Gen/html/DocVisitor.hpp b/src/lib/Gen/html/DocVisitor.hpp index 8f7548b468..a64ec9c375 100644 --- a/src/lib/Gen/html/DocVisitor.hpp +++ b/src/lib/Gen/html/DocVisitor.hpp @@ -68,6 +68,9 @@ class DocVisitor void operator()(doc::ListItem const& I) const; + void + operator()(doc::UnorderedList const& I) const; + void operator()(doc::Param const& I) const; diff --git a/src/lib/Gen/xml/XMLWriter.cpp b/src/lib/Gen/xml/XMLWriter.cpp index fe0671228d..fa6f2c068c 100644 --- a/src/lib/Gen/xml/XMLWriter.cpp +++ b/src/lib/Gen/xml/XMLWriter.cpp @@ -747,6 +747,9 @@ writeNode( case doc::Kind::list_item: writeListItem(dynamic_cast(node)); break; + case doc::Kind::unordered_list: + writeUnorderedList(dynamic_cast(node)); + break; case doc::Kind::brief: writeBrief(dynamic_cast(node)); break; @@ -847,6 +850,16 @@ writeListItem( tags_.close("listitem"); } +void +XMLWriter:: +writeUnorderedList( + doc::UnorderedList const& node) +{ + tags_.open("unorderedlist"); + writeNodes(node.items); + tags_.close("unorderedlist"); +} + void XMLWriter:: writeBrief( diff --git a/src/lib/Gen/xml/XMLWriter.hpp b/src/lib/Gen/xml/XMLWriter.hpp index f113da6549..f210f4002f 100644 --- a/src/lib/Gen/xml/XMLWriter.hpp +++ b/src/lib/Gen/xml/XMLWriter.hpp @@ -81,6 +81,7 @@ class XMLWriter void writeHeading(doc::Heading const& node); void writeLink(doc::Link const& node); void writeListItem(doc::ListItem const& node); + void writeUnorderedList(doc::UnorderedList const& node); void writeParagraph(doc::Paragraph const& node, llvm::StringRef tag = ""); void writeJParam(doc::Param const& node); void writeReturns(doc::Returns const& node); diff --git a/test-files/golden-tests/javadoc/li.adoc b/test-files/golden-tests/javadoc/li.adoc new file mode 100644 index 0000000000..ca9ebcc135 --- /dev/null +++ b/test-files/golden-tests/javadoc/li.adoc @@ -0,0 +1,50 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + + +=== Functions + +[cols=2] +|=== +| Name | Description + +| <> +| A function + +|=== + +[#f] +== f + + +A function + +=== Synopsis + + +Declared in `<li.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f(); +---- + +=== Description + + +Description: + +* Point 1 +* Point 2 + +Another paragraph. + + + + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/javadoc/li.cpp b/test-files/golden-tests/javadoc/li.cpp new file mode 100644 index 0000000000..d18881aafa --- /dev/null +++ b/test-files/golden-tests/javadoc/li.cpp @@ -0,0 +1,10 @@ +/** +* \brief A function + * \details Description: + * + * \li Point 1 + * \li Point 2 + * + * Another paragraph. + */ +void f(); diff --git a/test-files/golden-tests/javadoc/li.html b/test-files/golden-tests/javadoc/li.html new file mode 100644 index 0000000000..3f3b5689b9 --- /dev/null +++ b/test-files/golden-tests/javadoc/li.html @@ -0,0 +1,65 @@ + + +Reference + + +
+

Reference

+
+
+

Global namespace

+
+

Functions

+ + + + + + + + + + +
NameDescription
f A function + +
+
+
+
+

f

+
+A function + + +
+
+
+

Synopsis

+
+Declared in <li.cpp>
+
+
+void
+f();
+
+
+
+
+

Description

+

Description:

+
    +
  • Point 1
  • +
  • Point 2
  • +
+

Another paragraph.

+ + +
+
+ +
+
+

Created with MrDocs

+
+ + \ No newline at end of file diff --git a/test-files/golden-tests/javadoc/li.xml b/test-files/golden-tests/javadoc/li.xml new file mode 100644 index 0000000000..b0a3cb83f3 --- /dev/null +++ b/test-files/golden-tests/javadoc/li.xml @@ -0,0 +1,28 @@ + + + + + + + + A function + +
+ Description: +
+ + + Point 1 + + + Point 2 + + + + Another paragraph. + +
+
+
+