redsnow 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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