-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add common subpackage without libdparse
adds ddoc.unhighlight and ddoc.types modules for more useful usage. Unhighlight can be used to emit embedded D code as-is, instead of parsing it and (potentially) causing issues as well as needing a dependency on libdparse. The ddoc.types module now contains the Comment struct that was in ddoc.comments and has a new parseUnexpanded call, which puts the split sections directly into the comment, without expanding, which is commonly used for example in D-Scanner to just check if a comment is `ditto` or contains some section with a given name.
- Loading branch information
1 parent
9cf851e
commit c8b945f
Showing
9 changed files
with
231 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
name "common" |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
module ddoc.types; | ||
|
||
import ddoc.lexer; | ||
import ddoc.sections; | ||
|
||
struct Comment | ||
{ | ||
bool isDitto() const @property | ||
{ | ||
import std.string : strip, toLower; | ||
|
||
return sections.length == 2 && sections[0].content.strip().toLower() == "ditto"; | ||
} | ||
|
||
Section[] sections; | ||
|
||
/** | ||
* Creates a Comment object without expanding the sections. | ||
* | ||
* Use $(LREF parse) with a function pointer to $(REF highlight, ddoc,highlight) | ||
* or $(REF parseComment, ddoc,comments) to parse a comment while also | ||
* expanding sections. | ||
*/ | ||
static Comment parseUnexpanded(string text) | ||
{ | ||
import ddoc.unhighlight : unhighlight; | ||
|
||
return parse(text, null, false, &unhighlight); | ||
} | ||
|
||
static Comment parse(string text, string[string] macros, bool removeUnknown, | ||
string function(string) highlightFn) | ||
{ | ||
import std.functional : toDelegate; | ||
|
||
return parse(text, macros, removeUnknown, toDelegate(highlightFn)); | ||
} | ||
|
||
static Comment parse(string text, string[string] macros, bool removeUnknown, | ||
string delegate(string) highlightFn) | ||
out(retVal) | ||
{ | ||
assert(retVal.sections.length >= 2); | ||
} | ||
do | ||
{ | ||
import std.algorithm : find; | ||
import ddoc.macros : expand; | ||
|
||
auto sections = splitSections(text); | ||
string[string] sMacros = macros; | ||
auto m = sections.find!(p => p.name == "Macros"); | ||
const e = sections.find!(p => p.name == "Escapes"); | ||
auto p = sections.find!(p => p.name == "Params"); | ||
if (m.length) | ||
{ | ||
if (!doMapping(m[0])) | ||
throw new DdocParseException("Unable to parse Key/Value pairs", m[0].content); | ||
foreach (kv; m[0].mapping) | ||
sMacros[kv[0]] = kv[1]; | ||
} | ||
if (e.length) | ||
{ | ||
assert(0, "Escapes not handled yet"); | ||
} | ||
if (p.length) | ||
{ | ||
if (!doMapping(p[0])) | ||
throw new DdocParseException("Unable to parse Key/Value pairs", p[0].content); | ||
foreach (ref kv; p[0].mapping) | ||
kv[1] = expand(Lexer(highlightFn(kv[1])), sMacros, removeUnknown); | ||
} | ||
|
||
foreach (ref Section sec; sections) | ||
{ | ||
if (sec.name != "Macros" && sec.name != "Escapes" && sec.name != "Params") | ||
sec.content = expand(Lexer(highlightFn(sec.content)), sMacros, removeUnknown); | ||
} | ||
return Comment(sections); | ||
} | ||
} | ||
|
||
private: | ||
bool doMapping(ref Section s) | ||
{ | ||
import ddoc.macros : KeyValuePair, parseKeyValuePair; | ||
|
||
auto lex = Lexer(s.content); | ||
KeyValuePair[] pairs; | ||
if (parseKeyValuePair(lex, pairs)) | ||
{ | ||
foreach (idx, kv; pairs) | ||
s.mapping ~= kv; | ||
return true; | ||
} | ||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/** | ||
* Converts embedded code sections to plain text inside `(D_CODE)` without any | ||
* syntax highlighting applied. This can be used as lightweight alternative to | ||
* ddoc.highlight when syntax highlighting the code is not actually needed. | ||
* | ||
* Copyright: © 2014 Economic Modeling Specialists, Intl. | ||
* Authors: Brian Schott, Mathias 'Geod24' Lang, Jan Jurzitza | ||
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) | ||
*/ | ||
module ddoc.unhighlight; | ||
|
||
import std.array; | ||
|
||
/** | ||
* Parses a string and replace embedded code (code between at least 3 '-') with | ||
* plaintext. | ||
* | ||
* Params: | ||
* str = A string that might contain embedded code. Only code will be modified. | ||
* If the string doesn't contain any embedded code, it will be returned as is. | ||
* | ||
* Returns: | ||
* A (possibly new) string containing the embedded code inside `D_CODE` macros. | ||
*/ | ||
string unhighlight(string str) | ||
{ | ||
return highlightBase(str, (code, ref o) { o.put(code); }); | ||
} | ||
|
||
/** | ||
* Base code for highlight and unhighlight, calling the $(LREF highlightCode) | ||
* callback parameter on all embedded sections to handle how it is emitted. | ||
* | ||
* Params: | ||
* str = A string that might contain embedded code. Only code will be modified. | ||
* If the string doesn't contain any embedded code, it will be returned as is. | ||
* highlightCode = The callback to call for embedded and inlined code sections. | ||
* `D_CODE` macross will be automatically prefixed and suffixed before/after | ||
* the call to this function. | ||
*/ | ||
string highlightBase(string str, void delegate(string code, ref Appender!string output) highlightCode) | ||
{ | ||
import ddoc.lexer; | ||
import ddoc.macros : tokOffset; | ||
|
||
auto lex = Lexer(str, true); | ||
auto output = appender!string; | ||
size_t start; | ||
// We need this because there's no way to tell how many dashes precede | ||
// an embedded. | ||
size_t end; | ||
while (!lex.empty) | ||
{ | ||
if (lex.front.type == Type.embedded) | ||
{ | ||
if (start != end) | ||
output.put(lex.text[start .. end]); | ||
output.put("$(D_CODE "); | ||
highlightCode(lex.front.text, output); | ||
output.put(")"); | ||
start = lex.offset; | ||
} | ||
else if (lex.front.type == Type.inlined) | ||
{ | ||
if (start != end) | ||
output.put(lex.text[start .. end]); | ||
output.put("$(DDOC_BACKQUOTED "); | ||
highlightCode(lex.front.text, output); | ||
output.put(")"); | ||
start = lex.offset; | ||
} | ||
end = lex.offset; | ||
lex.popFront(); | ||
} | ||
|
||
if (start) | ||
{ | ||
output.put(lex.text[start .. end]); | ||
return output.data; | ||
} | ||
else | ||
{ | ||
return str; | ||
} | ||
} | ||
|
||
unittest | ||
{ | ||
import ddoc.lexer; | ||
import ddoc.macros; | ||
|
||
string[string] macros = null; | ||
|
||
string text = `description | ||
Something else | ||
--- | ||
// an example | ||
--- | ||
Throws: a fit | ||
--- | ||
/// another example | ||
---`; | ||
text = unhighlight(text); | ||
auto lexer = Lexer(text, true); | ||
assert(expand(lexer, macros, false) == `description | ||
Something else | ||
<pre class="d_code">// an example</pre> | ||
Throws: a fit | ||
<pre class="d_code">/// another example</pre>`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters