Skip to content

Commit

Permalink
The ddoc compiler now takes a DdocContext that can be used to provide…
Browse files Browse the repository at this point in the history
… symbol links and additional macros.
  • Loading branch information
s-ludwig committed Oct 15, 2012
1 parent d53f5f6 commit 011aadf
Showing 1 changed file with 54 additions and 14 deletions.
68 changes: 54 additions & 14 deletions source/ddox/ddoc.d
Expand Up @@ -22,20 +22,26 @@ import std.conv;
By specifying a display_section callback it is also possible to output only certain sections.
*/
string formatDdocComment(string ddoc_, int hlevel = 2, bool delegate(string) display_section = null)
{
return formatDdocComment(new BareContext(ddoc_), hlevel, display_section);
}
/// ditto
string formatDdocComment(DdocContext context, int hlevel = 2, bool delegate(string) display_section = null)
{
auto dst = appender!string();
filterDdocComment(dst, cast(string)ddoc_, hlevel, display_section);
filterDdocComment(dst, context, hlevel, display_section);
return dst.data;
}
/// ditto
void filterDdocComment(R)(ref R dst, string ddoc, int hlevel = 2, bool delegate(string) display_section = null)
void filterDdocComment(R)(ref R dst, DdocContext context, int hlevel = 2, bool delegate(string) display_section = null)
{
auto lines = splitLines(ddoc);
auto lines = splitLines(context.docText);
if( !lines.length ) return;

string[string] macros;
parseMacros(macros, s_standardMacros);
parseMacros(macros, s_defaultMacros);
parseMacros(macros, context.defaultMacroDefinitions);

int getLineType(int i)
{
Expand Down Expand Up @@ -107,8 +113,8 @@ void filterDdocComment(R)(ref R dst, string ddoc, int hlevel = 2, bool delegate(

foreach( s; sections ){
if( display_section && !display_section(s.name) ) continue;
if( s.name == "$Short") renderTextLine(dst, s.lines[0], macros);
else parseSection(dst, s.name, s.lines, hlevel, macros);
if( s.name == "$Short") renderTextLine(dst, s.lines[0], context, macros);
else parseSection(dst, s.name, s.lines, context, hlevel, macros);
}
}

Expand All @@ -124,6 +130,34 @@ void setDefaultDdocMacroFile(string filename)
s_defaultMacros = splitLines(text);
}


/**
Provides context information about the documented element.
*/
interface DdocContext {
/// The DDOC text
@property string docText();

/// A line array with macro definitions
@property string[] defaultMacroDefinitions();

/// Looks up a symbol in the scope of the documented element and returns a link to it.
string lookupScopeSymbolLink(string name);
}

private class BareContext : DdocContext {
private string m_ddoc;

this(string ddoc)
{
m_ddoc = ddoc;
}

@property string docText() { return m_ddoc; }
@property string[] defaultMacroDefinitions() { return null; }
string lookupScopeSymbolLink(string name) { return null; }
}

private enum {
BLANK,
TEXT,
Expand All @@ -147,7 +181,7 @@ private {
}

/// private
private void parseSection(R)(ref R dst, string sect, string[] lines, int hlevel, string[string] macros)
private void parseSection(R)(ref R dst, string sect, string[] lines, DdocContext context, int hlevel, string[string] macros)
{
void putHeader(string hdr){
dst.put("<section>");
Expand Down Expand Up @@ -202,7 +236,7 @@ private void parseSection(R)(ref R dst, string sect, string[] lines, int hlevel,
case TEXT:
dst.put("<p>");
auto j = skipBlock(i);
renderTextLine(dst, lines[i .. j].join("\n"), macros);
renderTextLine(dst, lines[i .. j].join("\n"), context, macros);
dst.put("</p>\n");
i = j;
break;
Expand Down Expand Up @@ -252,7 +286,7 @@ private void parseSection(R)(ref R dst, string sect, string[] lines, int hlevel,
}

/// private
private void renderTextLine(R)(ref R dst, string line, string[string] macros, string[] params = null)
private void renderTextLine(R)(ref R dst, string line, DdocContext context, string[string] macros, string[] params = null)
{
while( line.length > 0 ){
switch( line[0] ){
Expand All @@ -270,18 +304,24 @@ private void renderTextLine(R)(ref R dst, string line, string[string] macros, st
case 'A': .. case 'Z':
assert(line[0] >= 'a' && line[0] <= 'z' || line[0] >= 'A' && line[0] <= 'Z');
auto ident = skipIdent(line);
// TODO: check for semantic correspondence
dst.put(ident);
auto link = context.lookupScopeSymbolLink(ident);
if( link.length ){
dst.put("<a href=\"");
dst.put(link);
dst.put("><code class=\"prettyprint lang-d\">");
dst.put(ident);
dst.put("</code></a>");
} else dst.put(ident);
break;
case '$':
renderMacro(dst, line, macros, params);
renderMacro(dst, line, context, macros, params);
break;
}
}
}

/// private
private void renderMacro(R)(ref R dst, ref string line, string[string] macros, string[] params = null)
private void renderMacro(R)(ref R dst, ref string line, DdocContext context, string[string] macros, string[] params = null)
{
line = line[1 .. $];
if( line.length < 1) return;
Expand Down Expand Up @@ -327,7 +367,7 @@ private void renderMacro(R)(ref R dst, ref string line, string[string] macros, s
auto rawargs = splitParams(line[mnameidx+1 .. cidx-1]);
foreach( arg; rawargs ){
auto argtext = appender!string();
renderTextLine(argtext, arg, macros, params);
renderTextLine(argtext, arg, context, macros, params);
args ~= argtext.data();
}
}
Expand All @@ -338,7 +378,7 @@ private void renderMacro(R)(ref R dst, ref string line, string[string] macros, s

if( auto pm = mname in macros ){
logTrace("MACRO %s: %s", mname, *pm);
renderTextLine(dst, *pm, macros, args);
renderTextLine(dst, *pm, context, macros, args);
} else {
logTrace("Macro '%s' not found.", mname);
if( args.length ) dst.put(args[0]);
Expand Down

0 comments on commit 011aadf

Please sign in to comment.