@@ -33,28 +33,53 @@ class Parser {
33
33
/**
34
34
* Given an input string, parses out the body sections from the tag sections.
35
35
*
36
- * @param input the raw input string
36
+ * @param rawInput the raw input string
37
37
* @param body called for every chunk of text outside a tag
38
38
* @param tag called for every chunk of text inside a tag
39
39
*/
40
- void bodyAndTags (String input , Consumer <String > body , Consumer <String > tag ) {
41
- Matcher matcher = pattern .matcher (input );
40
+ protected void bodyAndTags (String rawInput , Consumer <String > body , Consumer <String > tag ) {
41
+ Matcher matcher = pattern .matcher (rawInput );
42
42
int last = 0 ;
43
43
while (matcher .find ()) {
44
44
if (matcher .start () > last ) {
45
- body .accept (input .substring (last , matcher .start ()));
45
+ body .accept (rawInput .substring (last , matcher .start ()));
46
46
}
47
47
tag .accept (matcher .group (1 ));
48
48
last = matcher .end ();
49
49
}
50
- if (last < input .length ()) {
51
- body .accept (input .substring (last ));
50
+ if (last < rawInput .length ()) {
51
+ body .accept (rawInput .substring (last ));
52
52
}
53
53
}
54
54
55
+ /**
56
+ * Reassembles a section/script/output chunk back into
57
+ * the full file.
58
+ *
59
+ * @param section
60
+ * @param script
61
+ * @param output
62
+ * @return
63
+ */
64
+ protected String reassemble (String section , String script , String output ) {
65
+ // make sure that the compiled output starts and ends with a newline,
66
+ // so that the tags stay separated separated nicely
67
+ if (!output .startsWith ("\n " )) {
68
+ output = "\n " + output ;
69
+ }
70
+ if (!output .endsWith ("\n " )) {
71
+ output = output + "\n " ;
72
+ }
73
+ return intron + " " + section + "\n " +
74
+ script +
75
+ exon +
76
+ output +
77
+ intron + " /" + section + " " + exon ;
78
+ }
79
+
55
80
/** Interface which can compile a single section of a FreshMark document. */
56
81
@ FunctionalInterface
57
- interface Compiler {
82
+ public interface SectionCompiler {
58
83
String compileSection (String section , String program , String in );
59
84
}
60
85
@@ -65,7 +90,7 @@ interface Compiler {
65
90
* @param compiler used to compile each section
66
91
* @return the compiled output string
67
92
*/
68
- String compile (String fullInput , Compiler compiler ) {
93
+ public String compile (String fullInput , SectionCompiler compiler ) {
69
94
StringBuilder result = new StringBuilder (fullInput .length () * 3 / 2 );
70
95
/** Associates errors with the part of the input that caused it. */
71
96
class ErrorFormatter {
@@ -102,37 +127,37 @@ private int countNewlines(String str) {
102
127
class State {
103
128
/** The section for which we're looking for a close tag. */
104
129
String section ;
105
- /** The program for that section. */
106
- String program ;
107
- /** The raw input which will be passed to the program . */
130
+ /** The script for that section. */
131
+ String script ;
132
+ /** The raw input which will be passed to the script . */
108
133
String input ;
109
134
110
135
void body (String body ) {
111
136
assert (input == null );
112
137
if (section == null ) {
113
- assert (program == null );
138
+ assert (script == null );
114
139
result .append (body );
115
140
} else {
116
- assert (program != null );
141
+ assert (script != null );
117
142
input = body ;
118
143
}
119
144
}
120
145
121
146
void tag (String tag ) {
122
147
if (section == null ) {
123
- assert (program == null );
148
+ assert (script == null );
124
149
assert (input == null );
125
150
// we were looking for an open tag, and now we've got one
126
151
int firstLine = tag .indexOf ('\n' );
127
152
if (firstLine < 0 || tag .length () <= firstLine ) {
128
- throw new IllegalArgumentException ("Section doesn't contain a program ." );
153
+ throw new IllegalArgumentException ("Section doesn't contain a script ." );
129
154
}
130
155
// the section name is the first line (trimmed)
131
156
section = tag .substring (0 , firstLine ).trim ();
132
- // the program is the second line
133
- program = tag .substring (firstLine + 1 );
157
+ // the script is the second line
158
+ script = tag .substring (firstLine + 1 );
134
159
} else {
135
- assert (program != null );
160
+ assert (script != null );
136
161
assert (input != null );
137
162
// we were looking for a close tag
138
163
String closing = tag .trim ();
@@ -141,11 +166,12 @@ void tag(String tag) {
141
166
throw new IllegalArgumentException ("Expecting '/" + section + "'" );
142
167
}
143
168
// and we found one! compile it and accumulate the result
144
- String chunk = compiler .compileSection (section , program , input );
145
- result .append (chunk );
169
+ String compiled = compiler .compileSection (section , script , input );
170
+ String reassembled = reassemble (section , script , compiled );
171
+ result .append (reassembled );
146
172
// wipe the state
147
173
section = null ;
148
- program = null ;
174
+ script = null ;
149
175
input = null ;
150
176
}
151
177
}
0 commit comments