redsnow 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -1
  3. data/README.md +12 -0
  4. data/ext/snowcrash/bin/snowcrash +0 -0
  5. data/ext/snowcrash/ext/markdown-parser/ext/sundown/src/markdown.c +5 -2
  6. data/ext/snowcrash/snowcrash.gyp +7 -2
  7. data/ext/snowcrash/src/ActionParser.h +141 -81
  8. data/ext/snowcrash/src/AssetParser.h +19 -11
  9. data/ext/snowcrash/src/Blueprint.h +44 -14
  10. data/ext/snowcrash/src/BlueprintParser.h +65 -51
  11. data/ext/snowcrash/src/BlueprintSourcemap.h +254 -0
  12. data/ext/snowcrash/src/BlueprintUtility.h +3 -24
  13. data/ext/snowcrash/src/CBlueprint.cc +40 -31
  14. data/ext/snowcrash/src/CBlueprint.h +54 -58
  15. data/ext/snowcrash/src/CBlueprintSourcemap.cc +620 -0
  16. data/ext/snowcrash/src/CBlueprintSourcemap.h +342 -0
  17. data/ext/snowcrash/src/CSourceAnnotation.cc +14 -0
  18. data/ext/snowcrash/src/CodeBlockUtility.h +42 -5
  19. data/ext/snowcrash/src/HeadersParser.h +84 -42
  20. data/ext/snowcrash/src/ParameterParser.h +110 -68
  21. data/ext/snowcrash/src/ParametersParser.h +26 -28
  22. data/ext/snowcrash/src/PayloadParser.h +164 -83
  23. data/ext/snowcrash/src/ResourceGroupParser.h +35 -41
  24. data/ext/snowcrash/src/ResourceParser.h +142 -97
  25. data/ext/snowcrash/src/SectionParser.h +15 -14
  26. data/ext/snowcrash/src/SectionParserData.h +11 -2
  27. data/ext/snowcrash/src/SectionProcessor.h +42 -18
  28. data/ext/snowcrash/src/Serialize.cc +2 -0
  29. data/ext/snowcrash/src/Serialize.h +3 -1
  30. data/ext/snowcrash/src/SerializeJSON.cc +608 -16
  31. data/ext/snowcrash/src/SerializeJSON.h +4 -1
  32. data/ext/snowcrash/src/SerializeYAML.cc +367 -19
  33. data/ext/snowcrash/src/SerializeYAML.h +4 -1
  34. data/ext/snowcrash/src/SymbolTable.h +12 -1
  35. data/ext/snowcrash/src/ValuesParser.h +12 -11
  36. data/ext/snowcrash/src/Version.h +1 -1
  37. data/ext/snowcrash/src/csnowcrash.cc +7 -3
  38. data/ext/snowcrash/src/csnowcrash.h +4 -2
  39. data/ext/snowcrash/src/snowcrash.cc +10 -11
  40. data/ext/snowcrash/src/snowcrash.h +3 -3
  41. data/ext/snowcrash/src/snowcrash/snowcrash.cc +38 -8
  42. data/ext/snowcrash/tools/homebrew/snowcrash.rb +1 -1
  43. data/lib/redsnow.rb +41 -2
  44. data/lib/redsnow/binding.rb +93 -8
  45. data/lib/redsnow/blueprint.rb +48 -25
  46. data/lib/redsnow/parseresult.rb +9 -2
  47. data/lib/redsnow/sourcemap.rb +369 -0
  48. data/lib/redsnow/version.rb +1 -1
  49. data/test/fixtures/sample-api-ast.json +1 -1
  50. data/test/fixtures/sample-api-sourcemap.json +169 -0
  51. data/test/redsnow_binding_test.rb +19 -2
  52. data/test/redsnow_options_test.rb +42 -0
  53. data/test/redsnow_parseresult_test.rb +5 -1
  54. data/test/redsnow_test.rb +5 -0
  55. metadata +11 -2
@@ -20,9 +20,6 @@ namespace snowcrash {
20
20
  /** Headers matching regex */
21
21
  const char* const HeadersRegex = "^[[:blank:]]*[Hh]eaders?[[:blank:]]*$";
22
22
 
23
- /** Internal type alias for collection of HTTP headers */
24
- typedef Collection<Header>::type Headers;
25
-
26
23
  /** Header Iterator in its containment group */
27
24
  typedef Collection<Header>::const_iterator HeaderIterator;
28
25
 
@@ -36,13 +33,12 @@ namespace snowcrash {
36
33
  const MarkdownNodes& siblings,
37
34
  SectionParserData& pd,
38
35
  SectionLayout& layout,
39
- Report& report,
40
- Headers& out) {
36
+ ParseResult<Headers>& out) {
41
37
 
42
38
  mdp::ByteBuffer content;
43
- CodeBlockUtility::signatureContentAsCodeBlock(node, pd, report, content);
39
+ CodeBlockUtility::signatureContentAsCodeBlock(node, pd, out.report, content);
44
40
 
45
- headersFromContent(node, content, pd, report, out);
41
+ headersFromContent(node, content, pd, out);
46
42
 
47
43
  return ++MarkdownNodeIterator(node);
48
44
  }
@@ -50,21 +46,20 @@ namespace snowcrash {
50
46
  static MarkdownNodeIterator processDescription(const MarkdownNodeIterator& node,
51
47
  const MarkdownNodes& siblings,
52
48
  SectionParserData& pd,
53
- Report& report,
54
- Headers& out) {
49
+ ParseResult<Headers>& out) {
50
+
55
51
  return node;
56
52
  }
57
53
 
58
54
  static MarkdownNodeIterator processContent(const MarkdownNodeIterator& node,
59
55
  const MarkdownNodes& siblings,
60
56
  SectionParserData& pd,
61
- Report& report,
62
- Headers& out) {
57
+ ParseResult<Headers>& out) {
63
58
 
64
59
  mdp::ByteBuffer content;
65
- CodeBlockUtility::contentAsCodeBlock(node, pd, report, content);
60
+ CodeBlockUtility::contentAsCodeBlock(node, pd, out.report, content);
66
61
 
67
- headersFromContent(node, content, pd, report, out);
62
+ headersFromContent(node, content, pd, out);
68
63
 
69
64
  return ++MarkdownNodeIterator(node);
70
65
  }
@@ -101,16 +96,15 @@ namespace snowcrash {
101
96
 
102
97
  static void finalize(const MarkdownNodeIterator& node,
103
98
  SectionParserData& pd,
104
- Report& report,
105
- Headers& out) {
99
+ ParseResult<Headers>& out) {
106
100
 
107
- if (out.empty()) {
101
+ if (out.node.empty()) {
108
102
 
109
103
  // WARN: No headers defined
110
104
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
111
- report.warnings.push_back(Warning("no headers specified",
112
- FormattingWarning,
113
- sourceMap));
105
+ out.report.warnings.push_back(Warning("no headers specified",
106
+ FormattingWarning,
107
+ sourceMap));
114
108
  }
115
109
  }
116
110
 
@@ -118,13 +112,14 @@ namespace snowcrash {
118
112
  static void headersFromContent(const MarkdownNodeIterator& node,
119
113
  const mdp::ByteBuffer& content,
120
114
  SectionParserData& pd,
121
- Report& report,
122
- Headers& headers) {
115
+ ParseResult<Headers>& out) {
116
+
123
117
  std::vector<std::string> lines = Split(content, '\n');
124
118
 
125
119
  for (std::vector<std::string>::iterator line = lines.begin();
126
120
  line != lines.end();
127
121
  ++line) {
122
+
128
123
  if (TrimString(*line).empty()) {
129
124
  continue;
130
125
  }
@@ -132,51 +127,97 @@ namespace snowcrash {
132
127
  Header header;
133
128
 
134
129
  if (CodeBlockUtility::keyValueFromLine(*line, header)) {
135
- if (findHeader(headers, header) != headers.end()) {
130
+ if (findHeader(out.node, header) != out.node.end()) {
136
131
  // WARN: duplicate header on this level
137
132
  std::stringstream ss;
138
133
 
139
134
  ss << "duplicate definition of '" << header.first << "' header";
140
135
 
141
136
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
142
- report.warnings.push_back(Warning(ss.str(),
143
- DuplicateWarning,
144
- sourceMap));
137
+ out.report.warnings.push_back(Warning(ss.str(),
138
+ DuplicateWarning,
139
+ sourceMap));
145
140
  }
146
141
 
147
- headers.push_back(header);
142
+ out.node.push_back(header);
143
+
144
+ if (pd.exportSourceMap()) {
145
+ SourceMap<Header> headerSM;
146
+ headerSM.sourceMap = node->sourceMap;
147
+ out.sourceMap.collection.push_back(headerSM);
148
+ }
148
149
  } else {
149
150
  // WARN: unable to parse header
150
151
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
151
- report.warnings.push_back(Warning("unable to parse HTTP header, expected '<header name> : <header value>', one header per line",
152
- FormattingWarning,
153
- sourceMap));
152
+ out.report.warnings.push_back(Warning("unable to parse HTTP header, expected '<header name> : <header value>', one header per line",
153
+ FormattingWarning,
154
+ sourceMap));
154
155
  }
155
156
  }
156
157
  }
157
158
 
158
159
  /** Inject headers into transaction examples requests and responses */
159
- static void injectDeprecatedHeaders(const Headers& headers,
160
- Collection<TransactionExample>::type& examples) {
160
+ static void injectDeprecatedHeaders(SectionParserData& pd,
161
+ const Headers& headers,
162
+ const SourceMap<Headers>& headersSM,
163
+ TransactionExamples& examples,
164
+ SourceMap<TransactionExamples>& examplesSM) {
165
+
166
+ Collection<TransactionExample>::iterator exampleIt = examples.begin();
167
+ Collection<SourceMap<TransactionExample> >::iterator exampleSourceMapIt;
168
+
169
+ if (pd.exportSourceMap()) {
170
+ exampleSourceMapIt = examplesSM.collection.begin();
171
+ }
172
+
173
+ while (exampleIt != examples.end()) {
161
174
 
162
- for (Collection<TransactionExample>::iterator exampleIt = examples.begin();
163
- exampleIt != examples.end();
164
- ++exampleIt) {
175
+ Collection<Request>::iterator requestIt = exampleIt->requests.begin();
176
+ Collection<SourceMap<Request> >::iterator requestSourceMapIt;
177
+
178
+ if (pd.exportSourceMap()) {
179
+ requestSourceMapIt = exampleSourceMapIt->requests.collection.begin();
180
+ }
165
181
 
166
182
  // Requests
167
- for (Collection<Request>::iterator reqIt = exampleIt->requests.begin();
168
- reqIt != exampleIt->requests.end();
169
- ++reqIt) {
183
+ while (requestIt != exampleIt->requests.end()) {
184
+
185
+ requestIt->headers.insert(requestIt->headers.begin(), headers.begin(), headers.end());
186
+ ++requestIt;
187
+
188
+ if (pd.exportSourceMap()) {
189
+ requestSourceMapIt->headers.collection.insert(requestSourceMapIt->headers.collection.begin(),
190
+ headersSM.collection.begin(),
191
+ headersSM.collection.end());
192
+ ++requestSourceMapIt;
193
+ }
194
+ }
170
195
 
171
- reqIt->headers.insert(reqIt->headers.begin(), headers.begin(), headers.end());
196
+ Collection<Response>::iterator responseIt = exampleIt->responses.begin();
197
+ Collection<SourceMap<Response> >::iterator responseSourceMapIt;
198
+
199
+ if (pd.exportSourceMap()) {
200
+ responseSourceMapIt = exampleSourceMapIt->responses.collection.begin();
172
201
  }
173
202
 
174
203
  // Responses
175
- for (Collection<Response>::iterator resIt = exampleIt->responses.begin();
176
- resIt != exampleIt->responses.end();
177
- ++resIt) {
204
+ while(responseIt != exampleIt->responses.end()) {
205
+
206
+ responseIt->headers.insert(responseIt->headers.begin(), headers.begin(), headers.end());
207
+ ++responseIt;
178
208
 
179
- resIt->headers.insert(resIt->headers.begin(), headers.begin(), headers.end());
209
+ if (pd.exportSourceMap()) {
210
+ responseSourceMapIt->headers.collection.insert(responseSourceMapIt->headers.collection.begin(),
211
+ headersSM.collection.begin(),
212
+ headersSM.collection.end());
213
+ ++responseSourceMapIt;
214
+ }
215
+ }
216
+
217
+ ++exampleIt;
218
+
219
+ if (pd.exportSourceMap()) {
220
+ ++exampleSourceMapIt;
180
221
  }
181
222
  }
182
223
  }
@@ -184,6 +225,7 @@ namespace snowcrash {
184
225
  /** Finds a header in its containment group by its key (first) */
185
226
  static HeaderIterator findHeader(const Headers& headers,
186
227
  const Header& header) {
228
+
187
229
  return std::find_if(headers.begin(),
188
230
  headers.end(),
189
231
  std::bind2nd(MatchFirsts<Header>(), header));
@@ -59,16 +59,19 @@ namespace snowcrash {
59
59
  const MarkdownNodes& siblings,
60
60
  SectionParserData& pd,
61
61
  SectionLayout& layout,
62
- Report& report,
63
- Parameter& out) {
62
+ ParseResult<Parameter>& out) {
64
63
 
65
64
  mdp::ByteBuffer signature, remainingContent;
66
65
  signature = GetFirstLine(node->text, remainingContent);
67
66
 
68
- parseSignature(node, pd, signature, report, out);
67
+ parseSignature(node, pd, signature, out);
69
68
 
70
69
  if (!remainingContent.empty()) {
71
- out.description += "\n" + remainingContent + "\n";
70
+ out.node.description += "\n" + remainingContent + "\n";
71
+
72
+ if (pd.exportSourceMap()) {
73
+ out.sourceMap.description.sourceMap.append(node->sourceMap);
74
+ }
72
75
  }
73
76
 
74
77
  return ++MarkdownNodeIterator(node);
@@ -78,46 +81,50 @@ namespace snowcrash {
78
81
  static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
79
82
  const MarkdownNodes& siblings,
80
83
  SectionParserData& pd,
81
- Report& report,
82
- Parameter& out) {
84
+ ParseResult<Parameter>& out) {
83
85
 
84
86
  if (pd.sectionContext() != ValuesSectionType) {
85
87
  return node;
86
88
  }
87
89
 
88
90
  // Check redefinition
89
- if (!out.values.empty()) {
91
+ if (!out.node.values.empty()) {
90
92
  // WARN: parameter values are already defined
91
93
  std::stringstream ss;
92
94
  ss << "overshadowing previous 'values' definition";
93
- ss << " for parameter '" << out.name << "'";
95
+ ss << " for parameter '" << out.node.name << "'";
94
96
 
95
97
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
96
- report.warnings.push_back(Warning(ss.str(),
97
- RedefinitionWarning,
98
- sourceMap));
98
+ out.report.warnings.push_back(Warning(ss.str(),
99
+ RedefinitionWarning,
100
+ sourceMap));
99
101
  }
100
102
 
101
103
  // Clear any previous values
102
- out.values.clear();
104
+ out.node.values.clear();
105
+
106
+ if (pd.exportSourceMap()) {
107
+ out.sourceMap.values.collection.clear();
108
+ }
103
109
 
104
- ValuesParser::parse(node, siblings, pd, report, out.values);
110
+ ParseResult<Values> values(out.report, out.node.values, out.sourceMap.values);
111
+ ValuesParser::parse(node, siblings, pd, values);
105
112
 
106
- if (out.values.empty()) {
113
+ if (out.node.values.empty()) {
107
114
  // WARN: empty definition
108
115
  std::stringstream ss;
109
- ss << "no possible values specified for parameter '" << out.name << "'";
116
+ ss << "no possible values specified for parameter '" << out.node.name << "'";
110
117
 
111
118
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
112
- report.warnings.push_back(Warning(ss.str(),
113
- EmptyDefinitionWarning,
114
- sourceMap));
119
+ out.report.warnings.push_back(Warning(ss.str(),
120
+ EmptyDefinitionWarning,
121
+ sourceMap));
115
122
  }
116
123
 
117
- if ((!out.exampleValue.empty() || !out.defaultValue.empty()) &&
118
- !out.values.empty()) {
124
+ if ((!out.node.exampleValue.empty() || !out.node.defaultValue.empty()) &&
125
+ !out.node.values.empty()) {
119
126
 
120
- checkExampleAndDefaultValue(node, pd, report, out);
127
+ checkExampleAndDefaultValue(node, pd, out);
121
128
  }
122
129
 
123
130
  return ++MarkdownNodeIterator(node);
@@ -156,10 +163,9 @@ namespace snowcrash {
156
163
  static void parseSignature(const mdp::MarkdownNodeIterator& node,
157
164
  SectionParserData& pd,
158
165
  mdp::ByteBuffer& signature,
159
- Report& report,
160
- Parameter& parameter) {
166
+ ParseResult<Parameter>& out) {
161
167
 
162
- parameter.use = UndefinedParameterUse;
168
+ out.node.use = UndefinedParameterUse;
163
169
 
164
170
  TrimString(signature);
165
171
 
@@ -174,17 +180,19 @@ namespace snowcrash {
174
180
 
175
181
  if (firstSpace == std::string::npos) {
176
182
  // Name
177
- parameter.name = signature;
183
+ out.node.name = signature;
178
184
  }
179
185
  else {
180
- parameter.name = innerSignature.substr(0, firstSpace);
186
+ out.node.name = innerSignature.substr(0, firstSpace);
181
187
  innerSignature = innerSignature.substr(firstSpace + 1);
188
+
182
189
  size_t descriptionPos = innerSignature.find(snowcrash::DescriptionIdentifier);
183
190
 
184
191
  if (descriptionPos != std::string::npos) {
185
192
  // Description
186
- parameter.description = innerSignature.substr(descriptionPos);
187
- parameter.description = TrimString(parameter.description.replace(0, snowcrash::DescriptionIdentifier.length(), ""));
193
+ out.node.description = innerSignature.substr(descriptionPos);
194
+ out.node.description = TrimString(out.node.description.replace(0, snowcrash::DescriptionIdentifier.length(), ""));
195
+
188
196
  innerSignature = innerSignature.substr(0, descriptionPos);
189
197
  innerSignature = TrimString(innerSignature);
190
198
  }
@@ -197,7 +205,9 @@ namespace snowcrash {
197
205
  if (endOfAttributesPos - attributesPos > 1) {
198
206
  std::string attributes = innerSignature.substr(attributesPos, endOfAttributesPos - attributesPos);
199
207
  attributes = attributes.substr(1);
200
- parseAdditionalTraits(node, pd, attributes, report, parameter);
208
+
209
+ parseAdditionalTraits(node, pd, attributes, out);
210
+
201
211
  innerSignature = innerSignature.substr(0, attributesPos);
202
212
  innerSignature = TrimString(innerSignature);
203
213
  }
@@ -205,41 +215,56 @@ namespace snowcrash {
205
215
 
206
216
  if (innerSignature.length() > 0) {
207
217
  // Remove =
208
- parameter.defaultValue = innerSignature;
209
- parameter.defaultValue.erase(std::remove(parameter.defaultValue.begin(), parameter.defaultValue.end(), '='), parameter.defaultValue.end());
210
- parameter.defaultValue.erase(std::remove(parameter.defaultValue.begin(), parameter.defaultValue.end(), '`'), parameter.defaultValue.end());
211
- parameter.defaultValue = TrimString(parameter.defaultValue);
218
+ out.node.defaultValue = innerSignature;
219
+
220
+ out.node.defaultValue.erase(std::remove(out.node.defaultValue.begin(), out.node.defaultValue.end(), '='), out.node.defaultValue.end());
221
+ out.node.defaultValue.erase(std::remove(out.node.defaultValue.begin(), out.node.defaultValue.end(), '`'), out.node.defaultValue.end());
222
+
223
+ out.node.defaultValue = TrimString(out.node.defaultValue);
224
+ }
225
+ }
226
+
227
+ if (pd.exportSourceMap()) {
228
+ if (!out.node.name.empty()) {
229
+ out.sourceMap.name.sourceMap = node->sourceMap;
230
+ }
231
+
232
+ if (!out.node.description.empty()) {
233
+ out.sourceMap.description.sourceMap = node->sourceMap;
234
+ }
235
+
236
+ if (!out.node.defaultValue.empty()) {
237
+ out.sourceMap.defaultValue.sourceMap = node->sourceMap;
212
238
  }
213
239
  }
214
240
 
215
241
  // Check possible required vs default clash
216
- if (parameter.use != OptionalParameterUse &&
217
- !parameter.defaultValue.empty()) {
218
-
242
+ if (out.node.use != OptionalParameterUse &&
243
+ !out.node.defaultValue.empty()) {
244
+
219
245
  // WARN: Required vs default clash
220
246
  std::stringstream ss;
221
- ss << "specifying parameter '" << parameter.name << "' as required supersedes its default value"\
247
+ ss << "specifying parameter '" << out.node.name << "' as required supersedes its default value"\
222
248
  ", declare the parameter as 'optional' to specify its default value";
223
249
 
224
250
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
225
- report.warnings.push_back(Warning(ss.str(),
226
- LogicalErrorWarning,
227
- sourceMap));
251
+ out.report.warnings.push_back(Warning(ss.str(),
252
+ LogicalErrorWarning,
253
+ sourceMap));
228
254
  }
229
255
  } else {
230
256
  // ERR: unable to parse
231
257
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
232
- report.error = Error("unable to parse parameter specification",
233
- BusinessError,
234
- sourceMap);
258
+ out.report.error = Error("unable to parse parameter specification",
259
+ BusinessError,
260
+ sourceMap);
235
261
  }
236
262
  }
237
263
 
238
264
  static void parseAdditionalTraits(const mdp::MarkdownNodeIterator& node,
239
265
  SectionParserData& pd,
240
266
  mdp::ByteBuffer& traits,
241
- Report& report,
242
- Parameter& parameter) {
267
+ ParseResult<Parameter>& out) {
243
268
 
244
269
  TrimString(traits);
245
270
 
@@ -249,13 +274,17 @@ namespace snowcrash {
249
274
  if (RegexCapture(traits, AdditionalTraitsExampleRegex, captureGroups) &&
250
275
  captureGroups.size() > 1) {
251
276
 
252
- parameter.exampleValue = captureGroups[1];
277
+ out.node.exampleValue = captureGroups[1];
253
278
  std::string::size_type pos = traits.find(captureGroups[0]);
254
279
 
255
280
  if (pos != std::string::npos) {
256
281
  traits.replace(pos, captureGroups[0].length(), std::string());
257
282
  }
258
- }
283
+
284
+ if (pd.exportSourceMap()) {
285
+ out.sourceMap.exampleValue.sourceMap = node->sourceMap;
286
+ }
287
+ }
259
288
 
260
289
  captureGroups.clear();
261
290
 
@@ -263,12 +292,16 @@ namespace snowcrash {
263
292
  if (RegexCapture(traits, AdditionalTraitsUseRegex, captureGroups) &&
264
293
  captureGroups.size() > 1) {
265
294
 
266
- parameter.use = RegexMatch(captureGroups[1], ParameterOptionalRegex) ? OptionalParameterUse : RequiredParameterUse;
295
+ out.node.use = RegexMatch(captureGroups[1], ParameterOptionalRegex) ? OptionalParameterUse : RequiredParameterUse;
267
296
  std::string::size_type pos = traits.find(captureGroups[0]);
268
297
 
269
298
  if (pos != std::string::npos) {
270
299
  traits.replace(pos, captureGroups[0].length(), std::string());
271
300
  }
301
+
302
+ if (pd.exportSourceMap()) {
303
+ out.sourceMap.use.sourceMap = node->sourceMap;
304
+ }
272
305
  }
273
306
 
274
307
  captureGroups.clear();
@@ -277,12 +310,16 @@ namespace snowcrash {
277
310
  if (RegexCapture(traits, AdditionalTraitsTypeRegex, captureGroups) &&
278
311
  captureGroups.size() > 1) {
279
312
 
280
- parameter.type = captureGroups[1];
313
+ out.node.type = captureGroups[1];
281
314
  std::string::size_type pos = traits.find(captureGroups[0]);
282
315
 
283
316
  if (pos != std::string::npos) {
284
317
  traits.replace(pos, captureGroups[0].length(), std::string());
285
318
  }
319
+
320
+ if (pd.exportSourceMap()) {
321
+ out.sourceMap.type.sourceMap = node->sourceMap;
322
+ }
286
323
  }
287
324
 
288
325
  // Check what is left
@@ -296,20 +333,25 @@ namespace snowcrash {
296
333
  ss << ", e.g. '(optional, string, `Hello World`)'";
297
334
 
298
335
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
299
- report.warnings.push_back(Warning(ss.str(),
300
- FormattingWarning,
301
- sourceMap));
336
+ out.report.warnings.push_back(Warning(ss.str(),
337
+ FormattingWarning,
338
+ sourceMap));
302
339
 
303
- parameter.type.clear();
304
- parameter.exampleValue.clear();
305
- parameter.use = UndefinedParameterUse;
340
+ out.node.type.clear();
341
+ out.node.exampleValue.clear();
342
+ out.node.use = UndefinedParameterUse;
343
+
344
+ if (pd.exportSourceMap()) {
345
+ out.sourceMap.type.sourceMap.clear();
346
+ out.sourceMap.exampleValue.sourceMap.clear();
347
+ out.sourceMap.use.sourceMap.clear();
348
+ }
306
349
  }
307
350
  }
308
351
 
309
352
  static void checkExampleAndDefaultValue(const mdp::MarkdownNodeIterator& node,
310
353
  SectionParserData& pd,
311
- Report& report,
312
- Parameter& parameter) {
354
+ ParseResult<Parameter>& out) {
313
355
 
314
356
  bool isExampleFound = false;
315
357
  bool isDefaultFound = false;
@@ -317,40 +359,40 @@ namespace snowcrash {
317
359
  std::stringstream ss;
318
360
  bool printWarning = false;
319
361
 
320
- for (Collection<Value>::iterator it = parameter.values.begin();
321
- it != parameter.values.end();
362
+ for (Collection<Value>::iterator it = out.node.values.begin();
363
+ it != out.node.values.end();
322
364
  ++it) {
323
365
 
324
- if (parameter.exampleValue == *it) {
366
+ if (out.node.exampleValue == *it) {
325
367
  isExampleFound = true;
326
368
  }
327
369
 
328
- if (parameter.defaultValue == *it) {
370
+ if (out.node.defaultValue == *it) {
329
371
  isDefaultFound = true;
330
372
  }
331
373
  }
332
374
 
333
- if(!parameter.exampleValue.empty() &&
375
+ if(!out.node.exampleValue.empty() &&
334
376
  !isExampleFound) {
335
377
 
336
378
  // WARN: missing example in values.
337
- ss << "the example value '" << parameter.exampleValue << "' of parameter '"<< parameter.name <<"' is not in its list of expected values";
379
+ ss << "the example value '" << out.node.exampleValue << "' of parameter '"<< out.node.name <<"' is not in its list of expected values";
338
380
  printWarning = true;
339
381
  }
340
382
 
341
- if(!parameter.defaultValue.empty() &&
383
+ if(!out.node.defaultValue.empty() &&
342
384
  !isDefaultFound) {
343
385
 
344
386
  // WARN: missing default in values.
345
- ss << "the default value '" << parameter.defaultValue << "' of parameter '"<< parameter.name <<"' is not in its list of expected values";
387
+ ss << "the default value '" << out.node.defaultValue << "' of parameter '"<< out.node.name <<"' is not in its list of expected values";
346
388
  printWarning = true;
347
389
  }
348
390
 
349
391
  if (printWarning) {
350
392
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
351
- report.warnings.push_back(Warning(ss.str(),
352
- LogicalErrorWarning,
353
- sourceMap));
393
+ out.report.warnings.push_back(Warning(ss.str(),
394
+ LogicalErrorWarning,
395
+ sourceMap));
354
396
  }
355
397
  }
356
398