|
1 | | -/** |
| 1 | +/** |
2 | 2 | DietDoc/DDOC support routines |
3 | 3 |
|
4 | 4 | Copyright: © 2012-2016 RejectedSoftware e.K. |
@@ -191,6 +191,14 @@ class DdocComment { |
191 | 191 | /// The macros contained in the "Macros" section (if any) |
192 | 192 | @property const(string[string]) macros() const { return m_macros; } |
193 | 193 |
|
| 194 | + /** All sections of the comment that contain visible text in original order |
| 195 | +
|
| 196 | + Note that any "Macro" section is not included, whereas the special |
| 197 | + sections "$Short", "$Long" and "Params" are included, just as any |
| 198 | + user defined sections. |
| 199 | + */ |
| 200 | + @property const(Section)[] sections() const { return m_sections; } |
| 201 | + |
194 | 202 | bool hasSection(string name) const { return m_sections.canFind!(s => s.name == name); } |
195 | 203 |
|
196 | 204 | void renderSectionR(R)(ref R dst, DdocContext context, string name, int hlevel = 2) |
@@ -224,6 +232,26 @@ class DdocComment { |
224 | 232 | renderSectionsR(dst, context, display_section, hlevel); |
225 | 233 | return dst.data; |
226 | 234 | } |
| 235 | + |
| 236 | + /** Renders each parameter's description in the "Params" section individually. |
| 237 | +
|
| 238 | + While `renderSection` and the related overloads will render the whole |
| 239 | + parameter section as an HTML table, this method allows to customize |
| 240 | + the structure of the section. |
| 241 | +
|
| 242 | + Params: |
| 243 | + context = Context implementation used to control the render process |
| 244 | + on_parameter = Callback that gets invoked with the name and the |
| 245 | + rendered description for each parameter |
| 246 | + */ |
| 247 | + void renderParameters(DdocContext context, |
| 248 | + void delegate(string, string) @safe on_parameter) |
| 249 | + { |
| 250 | + auto idx = m_sections.countUntil!(s => s.name == "Params"); |
| 251 | + if (idx < 0) return; |
| 252 | + |
| 253 | + .renderParameters(context, m_sections[idx], on_parameter); |
| 254 | + } |
227 | 255 | } |
228 | 256 |
|
229 | 257 | enum DdocRenderOptions { |
@@ -270,8 +298,14 @@ private enum { |
270 | 298 | SECTION |
271 | 299 | } |
272 | 300 |
|
273 | | -private struct Section { |
| 301 | + |
| 302 | +/// Represents a single section within a Ddoc comment |
| 303 | +struct Section { |
| 304 | + /// Name of the section as specified in the Ddoc comment |
274 | 305 | string name; |
| 306 | + |
| 307 | + /** Raw text contents of the section. |
| 308 | + */ |
275 | 309 | string[] lines; |
276 | 310 |
|
277 | 311 | this(string name, string[] lines...) |
@@ -423,6 +457,39 @@ private void parseSection(R)(ref R dst, string sect, string[] lines, DdocContext |
423 | 457 | } |
424 | 458 | } |
425 | 459 |
|
| 460 | +private void renderParameters(DdocContext context, Section parms_section, |
| 461 | + void delegate(string, string) @safe del) |
| 462 | +{ |
| 463 | + string paramname; |
| 464 | + string desc; |
| 465 | + |
| 466 | + foreach (string ln; parms_section.lines) { |
| 467 | + // check if the line starts a parameter documentation |
| 468 | + string name; |
| 469 | + auto eidx = ln.indexOf("="); |
| 470 | + if (eidx > 0) name = ln[0 .. eidx].strip(); |
| 471 | + if (!isIdent(name)) name = null; |
| 472 | + |
| 473 | + // if it does, start a new row |
| 474 | + if (name.length) { |
| 475 | + if (paramname !is null) { |
| 476 | + auto dst = appender!string; |
| 477 | + renderTextLine(dst, desc, context); |
| 478 | + del(paramname, dst.data); |
| 479 | + } |
| 480 | + |
| 481 | + desc = ln[eidx+1 .. $]; |
| 482 | + paramname = name; |
| 483 | + } else if (paramname !is null) desc ~= "\n" ~ ln; |
| 484 | + } |
| 485 | + |
| 486 | + if (paramname !is null) { |
| 487 | + auto dst = appender!string; |
| 488 | + renderTextLine(dst, desc, context); |
| 489 | + del(paramname, dst.data); |
| 490 | + } |
| 491 | +} |
| 492 | + |
426 | 493 | private string highlightAndCrossLink(string line, DdocContext context) |
427 | 494 | { |
428 | 495 | auto dst = appender!string; |
|
0 commit comments