@@ -26,6 +26,56 @@ struct Config {
26
26
}
27
27
Config config;
28
28
29
+ // a range until the next ')', nested () are ignored
30
+ auto untilClosingParentheses (R)(R rs)
31
+ {
32
+ struct State
33
+ {
34
+ size_t rightParensCount = 1 ;
35
+ bool inCodeBlock;
36
+ size_t dashCount;
37
+ }
38
+ return rs.cumulativeFold! ((state, r){
39
+ if (r == ' -' )
40
+ {
41
+ state.dashCount++ ;
42
+ }
43
+ else
44
+ {
45
+ if (state.dashCount >= 3 )
46
+ state.inCodeBlock = ! state.inCodeBlock;
47
+
48
+ state.dashCount = 0 ;
49
+ }
50
+ switch (r)
51
+ {
52
+ case ' -' :
53
+ break ;
54
+ case ' (' :
55
+ if (! state.inCodeBlock)
56
+ state.rightParensCount++ ;
57
+ break ;
58
+ case ' )' :
59
+ if (! state.inCodeBlock)
60
+ state.rightParensCount-- ;
61
+ break ;
62
+ default :
63
+ }
64
+ return state;
65
+ })(State()).zip(rs).until! (e => e[0 ].rightParensCount == 0 ).map! (e => e[1 ]);
66
+ }
67
+
68
+ unittest
69
+ {
70
+ import std.algorithm.comparison : equal;
71
+ assert (" aa $(foo $(bar)foobar)" .untilClosingParentheses.equal(" aa $(foo $(bar)foobar)" ));
72
+ }
73
+
74
+ auto findDdocMacro (string text, string ddocKey)
75
+ {
76
+ return text.splitter(ddocKey).map! untilClosingParentheses.dropOne;
77
+ }
78
+
29
79
int main (string [] args)
30
80
{
31
81
import std.conv , std.file , std.getopt , std.path ;
@@ -50,16 +100,14 @@ int main(string[] args)
50
100
}
51
101
52
102
// Find all examples in the specification
53
- auto r = regex(` SPEC_RUNNABLE_EXAMPLE\n\s*---+\n[^-]*---+\n\s*\)` , " s" );
54
103
foreach (file; specDir.dirEntries(" *.dd" , SpanMode.depth).parallel(1 ))
55
104
{
56
105
import std.ascii : newline;
57
106
import std.uni : isWhite;
58
107
auto allTests =
59
108
file
60
109
.readText
61
- .matchAll(r)
62
- .map! (a => a[0 ])
110
+ .findDdocMacro(" $(SPEC_RUNNABLE_EXAMPLE" )
63
111
.map! (a => a
64
112
.find(" ---" )
65
113
.findSplitAfter(newline)[1 ]
0 commit comments