redsnow 0.1.6 → 0.2.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -0
- data/ext/snowcrash/Makefile +1 -1
- data/ext/snowcrash/bin/snowcrash +0 -0
- data/ext/snowcrash/configure +9 -9
- data/ext/snowcrash/ext/markdown-parser/Makefile +87 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/CONTRIBUTING.md +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/Makefile +2 -1
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/Makefile.win +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/examples/smartypants.c +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/examples/sundown.c +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/html/houdini.h +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/html/houdini_href_e.c +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/html/houdini_html_e.c +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/html/html.c +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/html/html.h +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/html/html_smartypants.c +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/html_block_names.txt +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/autolink.c +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/autolink.h +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/buffer.c +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/buffer.h +1 -1
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/html_blocks.h +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/markdown.c +9 -3
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/markdown.h +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/src_map.c +11 -7
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/src_map.h +1 -1
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/stack.c +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/src/stack.h +0 -0
- data/ext/snowcrash/{sundown → ext/markdown-parser/ext/sundown}/sundown.def +0 -0
- data/ext/snowcrash/ext/markdown-parser/msvc/markdown/markdown.vcproj +188 -0
- data/ext/snowcrash/ext/markdown-parser/msvc/msvc.sln +38 -0
- data/ext/snowcrash/ext/markdown-parser/msvc/sundown/sundown.vcproj +206 -0
- data/ext/snowcrash/ext/markdown-parser/src/ByteBuffer.cc +92 -0
- data/ext/snowcrash/ext/markdown-parser/src/ByteBuffer.h +82 -0
- data/ext/snowcrash/ext/markdown-parser/src/MarkdownNode.cc +152 -0
- data/ext/snowcrash/ext/markdown-parser/src/MarkdownNode.h +103 -0
- data/ext/snowcrash/ext/markdown-parser/src/MarkdownParser.cc +388 -0
- data/ext/snowcrash/{src → ext/markdown-parser/src}/MarkdownParser.h +43 -33
- data/ext/snowcrash/snowcrash.gyp +114 -63
- data/ext/snowcrash/src/ActionParser.h +334 -398
- data/ext/snowcrash/src/AssetParser.h +82 -171
- data/ext/snowcrash/src/Blueprint.h +7 -2
- data/ext/snowcrash/src/BlueprintParser.h +212 -286
- data/ext/snowcrash/src/BlueprintUtility.h +2 -2
- data/ext/snowcrash/src/CBlueprint.h +1 -1
- data/ext/snowcrash/src/CSourceAnnotation.cc +11 -11
- data/ext/snowcrash/src/CSourceAnnotation.h +9 -9
- data/ext/snowcrash/src/CodeBlockUtility.h +199 -149
- data/ext/snowcrash/src/HeadersParser.h +197 -0
- data/ext/snowcrash/src/ParameterParser.h +429 -0
- data/ext/snowcrash/src/ParametersParser.h +136 -211
- data/ext/snowcrash/src/PayloadParser.h +458 -562
- data/ext/snowcrash/src/Platform.h +0 -3
- data/ext/snowcrash/src/ResourceGroupParser.h +183 -164
- data/ext/snowcrash/src/ResourceParser.h +325 -493
- data/ext/snowcrash/src/Section.cc +42 -0
- data/ext/snowcrash/src/Section.h +47 -0
- data/ext/snowcrash/src/SectionParser.h +229 -0
- data/ext/snowcrash/src/SectionParserData.h +81 -0
- data/ext/snowcrash/src/SectionProcessor.h +211 -0
- data/ext/snowcrash/src/Signature.cc +74 -0
- data/ext/snowcrash/src/Signature.h +32 -0
- data/ext/snowcrash/src/SourceAnnotation.h +7 -20
- data/ext/snowcrash/src/StringUtility.h +30 -10
- data/ext/snowcrash/src/SymbolTable.h +7 -7
- data/ext/snowcrash/src/UriTemplateParser.cc +10 -10
- data/ext/snowcrash/src/UriTemplateParser.h +11 -14
- data/ext/snowcrash/src/ValuesParser.h +122 -0
- data/ext/snowcrash/src/Version.h +2 -2
- data/ext/snowcrash/src/csnowcrash.cc +5 -5
- data/ext/snowcrash/src/csnowcrash.h +3 -3
- data/ext/snowcrash/src/snowcrash.cc +74 -4
- data/ext/snowcrash/src/snowcrash.h +9 -4
- data/ext/snowcrash/src/snowcrash/snowcrash.cc +16 -16
- data/ext/snowcrash/tools/homebrew/snowcrash.rb +3 -2
- data/ext/snowcrash/vcbuild.bat +13 -4
- data/lib/redsnow.rb +5 -5
- data/lib/redsnow/binding.rb +1 -1
- data/lib/redsnow/blueprint.rb +33 -2
- data/lib/redsnow/parseresult.rb +7 -4
- data/lib/redsnow/version.rb +1 -1
- data/test/redsnow_binding_test.rb +6 -6
- data/test/redsnow_parseresult_test.rb +1 -1
- metadata +62 -42
- data/ext/snowcrash/src/BlockUtility.h +0 -186
- data/ext/snowcrash/src/BlueprintParserCore.h +0 -190
- data/ext/snowcrash/src/BlueprintSection.h +0 -140
- data/ext/snowcrash/src/DescriptionSectionUtility.h +0 -156
- data/ext/snowcrash/src/HeaderParser.h +0 -289
- data/ext/snowcrash/src/ListBlockUtility.h +0 -273
- data/ext/snowcrash/src/ListUtility.h +0 -95
- data/ext/snowcrash/src/MarkdownBlock.cc +0 -176
- data/ext/snowcrash/src/MarkdownBlock.h +0 -93
- data/ext/snowcrash/src/MarkdownParser.cc +0 -266
- data/ext/snowcrash/src/ParameterDefinitonParser.h +0 -645
- data/ext/snowcrash/src/Parser.cc +0 -71
- data/ext/snowcrash/src/Parser.h +0 -29
- data/ext/snowcrash/src/ParserCore.cc +0 -120
- data/ext/snowcrash/src/ParserCore.h +0 -82
- data/ext/snowcrash/src/SectionUtility.h +0 -142
|
@@ -9,207 +9,118 @@
|
|
|
9
9
|
#ifndef SNOWCRASH_ASSETPARSER_H
|
|
10
10
|
#define SNOWCRASH_ASSETPARSER_H
|
|
11
11
|
|
|
12
|
-
#include
|
|
13
|
-
#include "BlueprintParserCore.h"
|
|
14
|
-
#include "Blueprint.h"
|
|
12
|
+
#include "SectionParser.h"
|
|
15
13
|
#include "RegexMatch.h"
|
|
16
|
-
#include "
|
|
17
|
-
#include "SectionUtility.h"
|
|
18
|
-
|
|
19
|
-
namespace snowcrashconst {
|
|
20
|
-
|
|
21
|
-
/** Body matching regex */
|
|
22
|
-
const char* const BodyRegex("^[[:blank:]]*[Bb]ody[[:blank:]]*$");
|
|
23
|
-
|
|
24
|
-
/** Schema matching regex */
|
|
25
|
-
const char* const SchemaRegex("^[[:blank:]]*[Ss]chema[[:blank:]]*$");
|
|
26
|
-
}
|
|
14
|
+
#include "CodeBlockUtility.h"
|
|
27
15
|
|
|
28
16
|
namespace snowcrash {
|
|
29
17
|
|
|
30
18
|
/// Asset signature
|
|
31
19
|
enum AssetSignature {
|
|
32
|
-
|
|
33
|
-
NoAssetSignature,
|
|
20
|
+
NoAssetSignature = 0,
|
|
34
21
|
BodyAssetSignature, /// < Explicit body asset
|
|
35
|
-
|
|
22
|
+
ImplicitBodyAssetSignature, /// < Body asset using abbreviated syntax
|
|
36
23
|
SchemaAssetSignature, /// < Explicit Schema asset
|
|
37
|
-
|
|
24
|
+
UndefinedAssetSignature = -1
|
|
38
25
|
};
|
|
39
26
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
BlockIterator cur = ListItemNameBlock(begin, end);
|
|
47
|
-
if (cur == end)
|
|
48
|
-
return NoAssetSignature;
|
|
49
|
-
|
|
50
|
-
if (cur->type != ParagraphBlockType &&
|
|
51
|
-
cur->type != ListItemBlockEndType)
|
|
52
|
-
return NoAssetSignature;
|
|
53
|
-
|
|
54
|
-
std::string content = GetFirstLine(cur->content);
|
|
55
|
-
if (RegexMatch(content, snowcrashconst::BodyRegex))
|
|
56
|
-
return BodyAssetSignature;
|
|
27
|
+
/** Body matching regex */
|
|
28
|
+
const char* const BodyRegex = "^[[:blank:]]*[Bb]ody[[:blank:]]*$";
|
|
29
|
+
|
|
30
|
+
/** Schema matching regex */
|
|
31
|
+
const char* const SchemaRegex = "^[[:blank:]]*[Ss]chema[[:blank:]]*$";
|
|
57
32
|
|
|
58
|
-
if (RegexMatch(content, snowcrashconst::SchemaRegex))
|
|
59
|
-
return SchemaAssetSignature;
|
|
60
|
-
|
|
61
|
-
if (HasPayloadAssetSignature(begin, end))
|
|
62
|
-
return PayloadBodyAssetSignature;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return NoAssetSignature;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
FORCEINLINE bool HasAssetSignature(const BlockIterator& begin,
|
|
69
|
-
const BlockIterator& end) {
|
|
70
|
-
AssetSignature signature = GetAssetSignature(begin, end);
|
|
71
|
-
return (signature != NoAssetSignature);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Return true if given block might be a dangling asset block,
|
|
76
|
-
* false otherwise.
|
|
77
|
-
*/
|
|
78
|
-
FORCEINLINE bool IsDanglingBlock(const BlockIterator& begin, const BlockIterator& end) {
|
|
79
|
-
return (begin->type == ParagraphBlockType
|
|
80
|
-
|| begin->type == CodeBlockType);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
33
|
/**
|
|
84
|
-
*
|
|
34
|
+
* Asset Section Processor
|
|
85
35
|
*/
|
|
86
|
-
template
|
|
87
|
-
|
|
88
|
-
const BlockIterator& end,
|
|
89
|
-
const SectionType& context) {
|
|
36
|
+
template<>
|
|
37
|
+
struct SectionProcessor<Asset> : public SectionProcessorBase<Asset> {
|
|
90
38
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
else if (context == BodySectionType ||
|
|
99
|
-
context == SchemaSectionType) {
|
|
100
|
-
|
|
101
|
-
// SectionType closure
|
|
102
|
-
if (begin->type == ListItemBlockEndType ||
|
|
103
|
-
begin->type == ListBlockEndType) {
|
|
104
|
-
|
|
105
|
-
// Look ahead for a dangling asset
|
|
106
|
-
BlockIterator cur = CloseNestedList(begin, end);
|
|
107
|
-
if (cur == end)
|
|
108
|
-
return UndefinedSectionType;
|
|
109
|
-
|
|
110
|
-
if (IsDanglingBlock(cur, end))
|
|
111
|
-
return (context == BodySectionType) ? DanglingBodySectionType : DanglingSchemaSectionType;
|
|
112
|
-
else
|
|
113
|
-
return UndefinedSectionType;
|
|
114
|
-
}
|
|
39
|
+
static MarkdownNodeIterator processSignature(const MarkdownNodeIterator& node,
|
|
40
|
+
const MarkdownNodes& siblings,
|
|
41
|
+
SectionParserData& pd,
|
|
42
|
+
SectionLayout& layout,
|
|
43
|
+
Report& report,
|
|
44
|
+
Asset& out) {
|
|
115
45
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
46
|
+
out = "";
|
|
47
|
+
CodeBlockUtility::signatureContentAsCodeBlock(node, pd, report, out);
|
|
48
|
+
return ++MarkdownNodeIterator(node);
|
|
120
49
|
}
|
|
121
|
-
|
|
122
|
-
|
|
50
|
+
|
|
51
|
+
static MarkdownNodeIterator processDescription(const MarkdownNodeIterator& node,
|
|
52
|
+
const MarkdownNodes& siblings,
|
|
53
|
+
SectionParserData& pd,
|
|
54
|
+
Report& report,
|
|
55
|
+
Asset& out) {
|
|
56
|
+
return node;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static MarkdownNodeIterator processContent(const MarkdownNodeIterator& node,
|
|
60
|
+
const MarkdownNodes& siblings,
|
|
61
|
+
SectionParserData& pd,
|
|
62
|
+
Report& report,
|
|
63
|
+
Asset& out) {
|
|
123
64
|
|
|
124
|
-
if (begin->type == ListItemBlockEndType ||
|
|
125
|
-
begin->type == ListBlockEndType)
|
|
126
|
-
return UndefinedSectionType;
|
|
127
65
|
|
|
128
|
-
|
|
129
|
-
|
|
66
|
+
mdp::ByteBuffer content;
|
|
67
|
+
CodeBlockUtility::contentAsCodeBlock(node, pd, report, content);
|
|
68
|
+
out += content;
|
|
69
|
+
return ++MarkdownNodeIterator(node);
|
|
130
70
|
}
|
|
131
71
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
context == DanglingSchemaSectionType) ? context : UndefinedSectionType;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
//
|
|
139
|
-
// Asset SectionType Parser
|
|
140
|
-
//
|
|
141
|
-
template<>
|
|
142
|
-
struct SectionParser<Asset> {
|
|
143
|
-
|
|
144
|
-
static ParseSectionResult ParseSection(const BlueprintSection& section,
|
|
145
|
-
const BlockIterator& cur,
|
|
146
|
-
BlueprintParserCore& parser,
|
|
147
|
-
Asset& asset) {
|
|
148
|
-
|
|
149
|
-
ParseSectionResult result = std::make_pair(Result(), cur);
|
|
150
|
-
switch (section.type) {
|
|
151
|
-
case BodySectionType:
|
|
152
|
-
case SchemaSectionType:
|
|
153
|
-
result = HandleAssetSectionBlock(section, cur, parser, asset);
|
|
154
|
-
break;
|
|
155
|
-
|
|
156
|
-
case DanglingBodySectionType:
|
|
157
|
-
case DanglingSchemaSectionType:
|
|
158
|
-
result = HandleDanglingAssetSectionBlock(section, cur, parser, asset);
|
|
159
|
-
break;
|
|
160
|
-
|
|
161
|
-
case UndefinedSectionType:
|
|
162
|
-
result.second = CloseList(cur, section.bounds.second);
|
|
163
|
-
break;
|
|
164
|
-
|
|
165
|
-
default:
|
|
166
|
-
result.first.error = UnexpectedBlockError(section, cur, parser.sourceData);
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return result;
|
|
72
|
+
static bool isDescriptionNode(const MarkdownNodeIterator& node,
|
|
73
|
+
SectionType sectionType) {
|
|
74
|
+
return false;
|
|
171
75
|
}
|
|
172
76
|
|
|
173
|
-
static
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
77
|
+
static bool isContentNode(const MarkdownNodeIterator& node,
|
|
78
|
+
SectionType sectionType) {
|
|
79
|
+
|
|
80
|
+
return (SectionKeywordSignature(node) == UndefinedSectionType);
|
|
81
|
+
}
|
|
177
82
|
|
|
178
|
-
static
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
Asset& asset) {
|
|
83
|
+
static SectionType sectionType(const MarkdownNodeIterator& node) {
|
|
84
|
+
if (node->type == mdp::ListItemMarkdownNodeType
|
|
85
|
+
&& !node->children().empty()) {
|
|
182
86
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
87
|
+
AssetSignature signature = assetSignature(node);
|
|
88
|
+
|
|
89
|
+
switch (signature) {
|
|
90
|
+
case BodyAssetSignature:
|
|
91
|
+
case ImplicitBodyAssetSignature:
|
|
92
|
+
return BodySectionType;
|
|
93
|
+
|
|
94
|
+
case SchemaAssetSignature:
|
|
95
|
+
return SchemaSectionType;
|
|
96
|
+
|
|
97
|
+
default:
|
|
98
|
+
return UndefinedSectionType;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return UndefinedSectionType;
|
|
197
103
|
}
|
|
198
104
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
105
|
+
/** Resolve asset signature */
|
|
106
|
+
static AssetSignature assetSignature(const MarkdownNodeIterator& node) {
|
|
107
|
+
|
|
108
|
+
mdp::ByteBuffer remaining, subject = node->children().front().text;
|
|
109
|
+
subject = GetFirstLine(subject, remaining);
|
|
110
|
+
TrimString(subject);
|
|
203
111
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return HandleAssetSectionBlock(section, sectionCur, parser, asset);
|
|
207
|
-
}
|
|
112
|
+
if (RegexMatch(subject, BodyRegex))
|
|
113
|
+
return BodyAssetSignature;
|
|
208
114
|
|
|
115
|
+
if (RegexMatch(subject, SchemaRegex))
|
|
116
|
+
return SchemaAssetSignature;
|
|
117
|
+
|
|
118
|
+
return NoAssetSignature;
|
|
119
|
+
}
|
|
209
120
|
};
|
|
210
121
|
|
|
211
|
-
|
|
212
|
-
|
|
122
|
+
/** Asset Section Parser */
|
|
123
|
+
typedef SectionParser<Asset, ListSectionAdapter> AssetParser;
|
|
213
124
|
}
|
|
214
125
|
|
|
215
126
|
#endif
|
|
@@ -48,7 +48,7 @@ namespace snowcrash {
|
|
|
48
48
|
|
|
49
49
|
/** Parameter Value */
|
|
50
50
|
typedef std::string Value;
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
/** A generic key - value pair */
|
|
53
53
|
typedef std::pair<std::string, std::string> KeyValuePair;
|
|
54
54
|
|
|
@@ -113,6 +113,8 @@ namespace snowcrash {
|
|
|
113
113
|
Collection<Value>::type values;
|
|
114
114
|
};
|
|
115
115
|
|
|
116
|
+
/** Name of a symbol */
|
|
117
|
+
typedef std::string SymbolName;
|
|
116
118
|
|
|
117
119
|
/**
|
|
118
120
|
* Payload
|
|
@@ -136,6 +138,9 @@ namespace snowcrash {
|
|
|
136
138
|
|
|
137
139
|
/** Schema */
|
|
138
140
|
Asset schema;
|
|
141
|
+
|
|
142
|
+
/** Symbol */
|
|
143
|
+
SymbolName symbol;
|
|
139
144
|
};
|
|
140
145
|
|
|
141
146
|
/** Resource Model */
|
|
@@ -257,7 +262,7 @@ namespace snowcrash {
|
|
|
257
262
|
/** Resources */
|
|
258
263
|
Collection<Resource>::type resources;
|
|
259
264
|
};
|
|
260
|
-
|
|
265
|
+
|
|
261
266
|
/**
|
|
262
267
|
* \brief API Blueprint AST
|
|
263
268
|
*
|
|
@@ -9,339 +9,265 @@
|
|
|
9
9
|
#ifndef SNOWCRASH_BLUEPRINTPARSER_H
|
|
10
10
|
#define SNOWCRASH_BLUEPRINTPARSER_H
|
|
11
11
|
|
|
12
|
-
#include <functional>
|
|
13
|
-
#include <sstream>
|
|
14
|
-
#include <iterator>
|
|
15
|
-
#include "Blueprint.h"
|
|
16
|
-
#include "BlueprintParserCore.h"
|
|
17
12
|
#include "ResourceParser.h"
|
|
18
13
|
#include "ResourceGroupParser.h"
|
|
14
|
+
#include "SectionParser.h"
|
|
15
|
+
#include "RegexMatch.h"
|
|
16
|
+
#include "CodeBlockUtility.h"
|
|
17
|
+
|
|
18
|
+
namespace snowcrash {
|
|
19
19
|
|
|
20
|
-
namespace snowcrashconst {
|
|
21
|
-
|
|
22
20
|
const char* const ExpectedAPINameMessage = "expected API name, e.g. '# <API Name>'";
|
|
23
|
-
}
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
/** Internal type alias for Collection of Metadata */
|
|
23
|
+
typedef Collection<Metadata>::type MetadataCollection;
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** Block Classifier, Blueprint Context */
|
|
35
|
-
template <>
|
|
36
|
-
FORCEINLINE SectionType ClassifyBlock<Blueprint>(const BlockIterator& begin,
|
|
37
|
-
const BlockIterator& end,
|
|
38
|
-
const SectionType& context) {
|
|
39
|
-
|
|
40
|
-
if (HasResourceGroupSignature(*begin) ||
|
|
41
|
-
HasResourceSignature(*begin))
|
|
42
|
-
return ResourceGroupSectionType; // Treat Resource as anonymous resource group
|
|
43
|
-
|
|
44
|
-
return (context == ResourceGroupSectionType) ? UndefinedSectionType : BlueprintSectionType;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
/** Blueprint SectionType Parser */
|
|
25
|
+
typedef Collection<Metadata>::iterator MetadataCollectionIterator;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Blueprint processor
|
|
29
|
+
*/
|
|
49
30
|
template<>
|
|
50
|
-
struct
|
|
51
|
-
|
|
52
|
-
static
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
31
|
+
struct SectionProcessor<Blueprint> : public SectionProcessorBase<Blueprint> {
|
|
32
|
+
|
|
33
|
+
static MarkdownNodeIterator processSignature(const MarkdownNodeIterator& node,
|
|
34
|
+
const MarkdownNodes& siblings,
|
|
35
|
+
SectionParserData& pd,
|
|
36
|
+
SectionLayout& layout,
|
|
37
|
+
Report& report,
|
|
38
|
+
Blueprint& out) {
|
|
39
|
+
|
|
40
|
+
MarkdownNodeIterator cur = node;
|
|
41
|
+
|
|
42
|
+
while (cur != siblings.end() &&
|
|
43
|
+
cur->type == mdp::ParagraphMarkdownNodeType) {
|
|
44
|
+
|
|
45
|
+
MetadataCollection metadata;
|
|
46
|
+
parseMetadata(cur, pd, report, metadata);
|
|
47
|
+
|
|
48
|
+
// First block is paragraph and is not metadata (no API name)
|
|
49
|
+
if (metadata.empty()) {
|
|
50
|
+
return processDescription(cur, siblings, pd, report, out);
|
|
51
|
+
} else {
|
|
52
|
+
out.metadata.insert(out.metadata.end(), metadata.begin(), metadata.end());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
cur++;
|
|
72
56
|
}
|
|
73
57
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (!blueprint.name.empty())
|
|
96
|
-
return true;
|
|
97
|
-
|
|
98
|
-
if (parser.options & RequireBlueprintNameOption) {
|
|
99
|
-
|
|
100
|
-
// ERR: No API name specified
|
|
101
|
-
result.error = Error(snowcrashconst::ExpectedAPINameMessage,
|
|
102
|
-
BusinessError,
|
|
103
|
-
MapSourceDataBlock(cur->sourceMap, parser.sourceData));
|
|
104
|
-
return false;
|
|
58
|
+
// Ideally this parsing metadata should be handled by separate parser
|
|
59
|
+
// that way the following check would be covered in SectionParser::parse()
|
|
60
|
+
if (cur == siblings.end())
|
|
61
|
+
return cur;
|
|
62
|
+
|
|
63
|
+
if (cur->type == mdp::HeaderMarkdownNodeType) {
|
|
64
|
+
|
|
65
|
+
SectionType nestedType = nestedSectionType(cur);
|
|
66
|
+
|
|
67
|
+
// Resources Groups only, parse as exclusive nested sections
|
|
68
|
+
if (nestedType != UndefinedSectionType) {
|
|
69
|
+
layout = ExclusiveNestedSectionLayout;
|
|
70
|
+
return cur;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
out.name = cur->text;
|
|
74
|
+
TrimString(out.name);
|
|
75
|
+
} else {
|
|
76
|
+
|
|
77
|
+
// Any other type of block, add to description
|
|
78
|
+
return processDescription(cur, siblings, pd, report, out);
|
|
105
79
|
}
|
|
106
80
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
APINameWarning,
|
|
110
|
-
MapSourceDataBlock(cur->sourceMap, parser.sourceData)));
|
|
81
|
+
return ++MarkdownNodeIterator(cur);
|
|
82
|
+
}
|
|
111
83
|
|
|
112
|
-
|
|
84
|
+
static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
|
|
85
|
+
const MarkdownNodes& siblings,
|
|
86
|
+
SectionParserData& pd,
|
|
87
|
+
Report& report,
|
|
88
|
+
Blueprint& out) {
|
|
89
|
+
|
|
90
|
+
if (pd.sectionContext() == ResourceGroupSectionType ||
|
|
91
|
+
pd.sectionContext() == ResourceSectionType) {
|
|
92
|
+
|
|
93
|
+
ResourceGroup resourceGroup;
|
|
94
|
+
MarkdownNodeIterator cur = ResourceGroupParser::parse(node, siblings, pd, report, resourceGroup);
|
|
95
|
+
|
|
96
|
+
ResourceGroupIterator duplicate = findResourceGroup(out.resourceGroups, resourceGroup);
|
|
97
|
+
|
|
98
|
+
if (duplicate != out.resourceGroups.end()) {
|
|
99
|
+
|
|
100
|
+
// WARN: duplicate resource group
|
|
101
|
+
std::stringstream ss;
|
|
102
|
+
|
|
103
|
+
if (resourceGroup.name.empty()) {
|
|
104
|
+
ss << "anonymous group";
|
|
105
|
+
} else {
|
|
106
|
+
ss << "group '" << resourceGroup.name << "'";
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
ss << " is already defined";
|
|
110
|
+
|
|
111
|
+
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
|
112
|
+
report.warnings.push_back(Warning(ss.str(),
|
|
113
|
+
DuplicateWarning,
|
|
114
|
+
sourceMap));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
out.resourceGroups.push_back(resourceGroup);
|
|
118
|
+
|
|
119
|
+
return cur;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return node;
|
|
113
123
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const SectionBounds& bounds,
|
|
119
|
-
const Blueprint& blueprint) {
|
|
120
|
-
|
|
121
|
-
if (blueprint.metadata.empty())
|
|
122
|
-
return cur == bounds.first;
|
|
123
|
-
|
|
124
|
-
return std::distance(bounds.first, cur) == 1;
|
|
124
|
+
|
|
125
|
+
static SectionType sectionType(const MarkdownNodeIterator& node) {
|
|
126
|
+
|
|
127
|
+
return BlueprintSectionType;
|
|
125
128
|
}
|
|
126
129
|
|
|
127
|
-
static
|
|
128
|
-
const BlockIterator& cur,
|
|
129
|
-
BlueprintParserCore& parser,
|
|
130
|
-
Blueprint& output) {
|
|
131
|
-
|
|
132
|
-
ParseSectionResult result = std::make_pair(Result(), cur);
|
|
133
|
-
BlockIterator sectionCur(cur);
|
|
130
|
+
static SectionType nestedSectionType(const MarkdownNodeIterator& node) {
|
|
134
131
|
|
|
135
|
-
|
|
136
|
-
bool isFirstBlock = IsFirstBlock(cur, section.bounds, output);
|
|
137
|
-
if (isFirstBlock &&
|
|
138
|
-
sectionCur->type == HeaderBlockType) {
|
|
139
|
-
|
|
140
|
-
output.name = cur->content;
|
|
141
|
-
|
|
142
|
-
// Check ambiguity
|
|
143
|
-
CheckHeaderBlock<Blueprint>(section, sectionCur, parser.sourceData, result.first);
|
|
132
|
+
SectionType nestedType = UndefinedSectionType;
|
|
144
133
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return result;
|
|
134
|
+
// Check if Resource section
|
|
135
|
+
nestedType = SectionProcessor<Resource>::sectionType(node);
|
|
136
|
+
|
|
137
|
+
if (nestedType != UndefinedSectionType) {
|
|
138
|
+
return nestedType;
|
|
151
139
|
}
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (result.second != sectionCur)
|
|
159
|
-
return result;
|
|
140
|
+
|
|
141
|
+
// Check if ResourceGroup section
|
|
142
|
+
nestedType = SectionProcessor<ResourceGroup>::sectionType(node);
|
|
143
|
+
|
|
144
|
+
if (nestedType != UndefinedSectionType) {
|
|
145
|
+
return nestedType;
|
|
160
146
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
result = ParseDescriptionBlock<Blueprint>(section, sectionCur, parser.sourceData, output);
|
|
164
|
-
|
|
165
|
-
// Check Name
|
|
166
|
-
if (isFirstBlock)
|
|
167
|
-
CheckBlueprintName(sectionCur, output, parser, result.first);
|
|
168
|
-
|
|
169
|
-
return result;
|
|
147
|
+
|
|
148
|
+
return UndefinedSectionType;
|
|
170
149
|
}
|
|
171
|
-
|
|
172
|
-
static
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
section.bounds.second,
|
|
188
|
-
section,
|
|
189
|
-
parser,
|
|
190
|
-
resourceGroup);
|
|
191
|
-
|
|
192
|
-
if (result.first.error.code != Error::OK)
|
|
193
|
-
return result;
|
|
150
|
+
|
|
151
|
+
static SectionTypes nestedSectionTypes() {
|
|
152
|
+
SectionTypes nested;
|
|
153
|
+
|
|
154
|
+
// Resource Group & descendants
|
|
155
|
+
nested.push_back(ResourceGroupSectionType);
|
|
156
|
+
SectionTypes types = SectionProcessor<ResourceGroup>::nestedSectionTypes();
|
|
157
|
+
nested.insert(nested.end(), types.begin(), types.end());
|
|
158
|
+
|
|
159
|
+
return nested;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static void finalize(const MarkdownNodeIterator& node,
|
|
163
|
+
SectionParserData& pd,
|
|
164
|
+
Report& report,
|
|
165
|
+
Blueprint& out) {
|
|
194
166
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
ss << " is already defined";
|
|
167
|
+
if (!out.name.empty())
|
|
168
|
+
return;
|
|
169
|
+
|
|
170
|
+
if (pd.options & RequireBlueprintNameOption) {
|
|
171
|
+
|
|
172
|
+
// ERR: No API name specified
|
|
173
|
+
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
|
174
|
+
report.error = Error(ExpectedAPINameMessage,
|
|
175
|
+
BusinessError,
|
|
176
|
+
sourceMap);
|
|
207
177
|
|
|
208
|
-
SourceCharactersBlock sourceBlock = CharacterMapForBlock(cur, section.bounds.second, section.bounds, parser.sourceData);
|
|
209
|
-
result.first.warnings.push_back(Warning(ss.str(),
|
|
210
|
-
DuplicateWarning,
|
|
211
|
-
sourceBlock));
|
|
212
178
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
179
|
+
else if (!out.description.empty()) {
|
|
180
|
+
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
|
181
|
+
report.warnings.push_back(Warning(ExpectedAPINameMessage,
|
|
182
|
+
APINameWarning,
|
|
183
|
+
sourceMap));
|
|
184
|
+
}
|
|
216
185
|
}
|
|
217
|
-
|
|
218
186
|
|
|
219
|
-
static
|
|
220
|
-
|
|
221
|
-
BlueprintParserCore& parser,
|
|
222
|
-
Blueprint& output) {
|
|
223
|
-
|
|
224
|
-
typedef Collection<Metadata>::type MetadataCollection;
|
|
225
|
-
typedef Collection<Metadata>::iterator MetadataCollectionIterator;
|
|
226
|
-
MetadataCollection metadataCollection;
|
|
187
|
+
static bool isUnexpectedNode(const MarkdownNodeIterator& node,
|
|
188
|
+
SectionType sectionType) {
|
|
227
189
|
|
|
228
|
-
|
|
229
|
-
|
|
190
|
+
// Since Blueprint is currently top-level node any unprocessed node should be reported
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
static void parseMetadata(const MarkdownNodeIterator& node,
|
|
196
|
+
SectionParserData& pd,
|
|
197
|
+
Report& report,
|
|
198
|
+
MetadataCollection& out) {
|
|
199
|
+
|
|
200
|
+
mdp::ByteBuffer content = node->text;
|
|
230
201
|
TrimStringEnd(content);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
202
|
+
|
|
203
|
+
std::vector<mdp::ByteBuffer> lines = Split(content, '\n');
|
|
204
|
+
|
|
205
|
+
for (std::vector<mdp::ByteBuffer>::iterator it = lines.begin();
|
|
206
|
+
it != lines.end();
|
|
207
|
+
++it) {
|
|
208
|
+
|
|
236
209
|
Metadata metadata;
|
|
237
|
-
|
|
238
|
-
|
|
210
|
+
|
|
211
|
+
if (CodeBlockUtility::keyValueFromLine(*it, metadata)) {
|
|
212
|
+
out.push_back(metadata);
|
|
213
|
+
}
|
|
239
214
|
}
|
|
240
|
-
|
|
241
|
-
if (lines.size() ==
|
|
242
|
-
|
|
215
|
+
|
|
216
|
+
if (lines.size() == out.size()) {
|
|
217
|
+
|
|
243
218
|
// Check duplicates
|
|
244
|
-
std::vector<
|
|
245
|
-
|
|
246
|
-
|
|
219
|
+
std::vector<mdp::ByteBuffer> duplicateKeys;
|
|
220
|
+
|
|
221
|
+
for (MetadataCollectionIterator it = out.begin();
|
|
222
|
+
it != out.end();
|
|
247
223
|
++it) {
|
|
248
|
-
|
|
224
|
+
|
|
249
225
|
MetadataCollectionIterator from = it;
|
|
250
|
-
if (++from ==
|
|
226
|
+
if (++from == out.end())
|
|
251
227
|
break;
|
|
252
|
-
|
|
228
|
+
|
|
253
229
|
MetadataCollectionIterator duplicate = std::find_if(from,
|
|
254
|
-
|
|
230
|
+
out.end(),
|
|
255
231
|
std::bind2nd(MatchFirsts<Metadata>(), *it));
|
|
256
|
-
|
|
257
|
-
if (duplicate !=
|
|
232
|
+
|
|
233
|
+
if (duplicate != out.end() &&
|
|
258
234
|
std::find(duplicateKeys.begin(), duplicateKeys.end(), it->first) == duplicateKeys.end()) {
|
|
259
|
-
|
|
235
|
+
|
|
260
236
|
duplicateKeys.push_back(it->first);
|
|
261
|
-
|
|
262
|
-
// WARN: duplicate
|
|
237
|
+
|
|
238
|
+
// WARN: duplicate metadata definition
|
|
263
239
|
std::stringstream ss;
|
|
264
240
|
ss << "duplicate definition of '" << it->first << "'";
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
241
|
+
|
|
242
|
+
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
|
243
|
+
report.warnings.push_back(Warning(ss.str(),
|
|
244
|
+
DuplicateWarning,
|
|
245
|
+
sourceMap));
|
|
270
246
|
}
|
|
271
247
|
}
|
|
272
|
-
|
|
273
|
-
// Insert parsed metadata into output
|
|
274
|
-
output.metadata.insert(output.metadata.end(),
|
|
275
|
-
metadataCollection.begin(),
|
|
276
|
-
metadataCollection.end());
|
|
277
|
-
|
|
278
|
-
++result.second;
|
|
279
248
|
}
|
|
280
|
-
else if (!
|
|
249
|
+
else if (!out.empty()) {
|
|
250
|
+
|
|
281
251
|
// WARN: malformed metadata block
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
sourceBlock));
|
|
252
|
+
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
|
253
|
+
report.warnings.push_back(Warning("ignoring possible metadata, expected '<key> : <value>', one one per line",
|
|
254
|
+
FormattingWarning,
|
|
255
|
+
sourceMap));
|
|
287
256
|
}
|
|
288
|
-
|
|
289
|
-
return result;
|
|
290
257
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
class BlueprintParser {
|
|
300
|
-
public:
|
|
301
|
-
// Parse Markdown AST into API Blueprint AST
|
|
302
|
-
static void Parse(const SourceData& sourceData,
|
|
303
|
-
const MarkdownBlock::Stack& source,
|
|
304
|
-
BlueprintParserOptions options,
|
|
305
|
-
Result& result,
|
|
306
|
-
Blueprint& blueprint) {
|
|
307
|
-
|
|
308
|
-
BlueprintParserCore parser(options, sourceData, blueprint);
|
|
309
|
-
BlueprintSection rootSection(std::make_pair(source.begin(), source.end()));
|
|
310
|
-
ParseSectionResult sectionResult = BlueprintParserInner::Parse(source.begin(),
|
|
311
|
-
source.end(),
|
|
312
|
-
rootSection,
|
|
313
|
-
parser,
|
|
314
|
-
blueprint);
|
|
315
|
-
result += sectionResult.first;
|
|
316
|
-
|
|
317
|
-
#ifdef DEBUG
|
|
318
|
-
PrintSymbolTable(parser.symbolTable);
|
|
319
|
-
#endif
|
|
320
|
-
if (result.error.code != Error::OK)
|
|
321
|
-
return;
|
|
322
|
-
|
|
323
|
-
PostParseCheck(sourceData, source, parser, result);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Perform additional post-parsing result checks.
|
|
328
|
-
* Mainly to focused on running checking when top-level parser is not executed.
|
|
329
|
-
*/
|
|
330
|
-
static void PostParseCheck(const SourceData& sourceData,
|
|
331
|
-
const MarkdownBlock::Stack& source,
|
|
332
|
-
BlueprintParserCore& parser,
|
|
333
|
-
Result& result) {
|
|
334
|
-
|
|
335
|
-
if ((parser.options & RequireBlueprintNameOption) &&
|
|
336
|
-
parser.blueprint.name.empty()){
|
|
337
|
-
|
|
338
|
-
// ERR: No API name specified
|
|
339
|
-
result.error = Error(snowcrashconst::ExpectedAPINameMessage,
|
|
340
|
-
BusinessError,
|
|
341
|
-
MapSourceDataBlock(MakeSourceDataBlock(0, 0), parser.sourceData));
|
|
342
|
-
}
|
|
258
|
+
|
|
259
|
+
/** Finds a resource group inside an resource groups collection */
|
|
260
|
+
static ResourceGroupIterator findResourceGroup(const ResourceGroups& resourceGroups,
|
|
261
|
+
const ResourceGroup& resourceGroup) {
|
|
262
|
+
|
|
263
|
+
return std::find_if(resourceGroups.begin(),
|
|
264
|
+
resourceGroups.end(),
|
|
265
|
+
std::bind2nd(MatchName<ResourceGroup>(), resourceGroup));
|
|
343
266
|
}
|
|
344
267
|
};
|
|
268
|
+
|
|
269
|
+
/** Blueprint Parser */
|
|
270
|
+
typedef SectionParser<Blueprint, BlueprintSectionAdapter> BlueprintParser;
|
|
345
271
|
}
|
|
346
272
|
|
|
347
273
|
#endif
|