redsnow 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/.gitmodules +3 -0
- data/.travis.yml +20 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +62 -0
- data/Rakefile +36 -0
- data/Vagrantfile +20 -0
- data/ext/snowcrash/Makefile +64 -0
- data/ext/snowcrash/Vagrantfile +20 -0
- data/ext/snowcrash/bin/snowcrash +0 -0
- data/ext/snowcrash/common.gypi +163 -0
- data/ext/snowcrash/config.gypi +10 -0
- data/ext/snowcrash/config.mk +5 -0
- data/ext/snowcrash/configure +213 -0
- data/ext/snowcrash/provisioning.sh +15 -0
- data/ext/snowcrash/snowcrash.gyp +141 -0
- data/ext/snowcrash/src/ActionParser.h +503 -0
- data/ext/snowcrash/src/AssetParser.h +215 -0
- data/ext/snowcrash/src/BlockUtility.h +186 -0
- data/ext/snowcrash/src/Blueprint.h +283 -0
- data/ext/snowcrash/src/BlueprintParser.h +347 -0
- data/ext/snowcrash/src/BlueprintParserCore.h +190 -0
- data/ext/snowcrash/src/BlueprintSection.h +140 -0
- data/ext/snowcrash/src/BlueprintUtility.h +126 -0
- data/ext/snowcrash/src/CBlueprint.cc +600 -0
- data/ext/snowcrash/src/CBlueprint.h +354 -0
- data/ext/snowcrash/src/CSourceAnnotation.cc +140 -0
- data/ext/snowcrash/src/CSourceAnnotation.h +106 -0
- data/ext/snowcrash/src/CodeBlockUtility.h +189 -0
- data/ext/snowcrash/src/DescriptionSectionUtility.h +156 -0
- data/ext/snowcrash/src/HTTP.cc +46 -0
- data/ext/snowcrash/src/HTTP.h +105 -0
- data/ext/snowcrash/src/HeaderParser.h +289 -0
- data/ext/snowcrash/src/ListBlockUtility.h +273 -0
- data/ext/snowcrash/src/ListUtility.h +95 -0
- data/ext/snowcrash/src/MarkdownBlock.cc +176 -0
- data/ext/snowcrash/src/MarkdownBlock.h +93 -0
- data/ext/snowcrash/src/MarkdownParser.cc +266 -0
- data/ext/snowcrash/src/MarkdownParser.h +88 -0
- data/ext/snowcrash/src/ParameterDefinitonParser.h +570 -0
- data/ext/snowcrash/src/ParametersParser.h +252 -0
- data/ext/snowcrash/src/Parser.cc +71 -0
- data/ext/snowcrash/src/Parser.h +29 -0
- data/ext/snowcrash/src/ParserCore.cc +120 -0
- data/ext/snowcrash/src/ParserCore.h +82 -0
- data/ext/snowcrash/src/PayloadParser.h +672 -0
- data/ext/snowcrash/src/Platform.h +54 -0
- data/ext/snowcrash/src/RegexMatch.h +32 -0
- data/ext/snowcrash/src/ResourceGroupParser.h +195 -0
- data/ext/snowcrash/src/ResourceParser.h +584 -0
- data/ext/snowcrash/src/SectionUtility.h +142 -0
- data/ext/snowcrash/src/Serialize.cc +52 -0
- data/ext/snowcrash/src/Serialize.h +69 -0
- data/ext/snowcrash/src/SerializeJSON.cc +601 -0
- data/ext/snowcrash/src/SerializeJSON.h +21 -0
- data/ext/snowcrash/src/SerializeYAML.cc +336 -0
- data/ext/snowcrash/src/SerializeYAML.h +21 -0
- data/ext/snowcrash/src/SourceAnnotation.h +177 -0
- data/ext/snowcrash/src/StringUtility.h +109 -0
- data/ext/snowcrash/src/SymbolTable.h +83 -0
- data/ext/snowcrash/src/UriTemplateParser.cc +195 -0
- data/ext/snowcrash/src/UriTemplateParser.h +243 -0
- data/ext/snowcrash/src/Version.h +39 -0
- data/ext/snowcrash/src/csnowcrash.cc +23 -0
- data/ext/snowcrash/src/csnowcrash.h +38 -0
- data/ext/snowcrash/src/posix/RegexMatch.cc +99 -0
- data/ext/snowcrash/src/snowcrash.cc +18 -0
- data/ext/snowcrash/src/snowcrash.h +41 -0
- data/ext/snowcrash/src/snowcrash/snowcrash.cc +170 -0
- data/ext/snowcrash/src/win/RegexMatch.cc +78 -0
- data/ext/snowcrash/sundown/CONTRIBUTING.md +10 -0
- data/ext/snowcrash/sundown/Makefile +83 -0
- data/ext/snowcrash/sundown/Makefile.win +33 -0
- data/ext/snowcrash/sundown/examples/smartypants.c +72 -0
- data/ext/snowcrash/sundown/examples/sundown.c +80 -0
- data/ext/snowcrash/sundown/html/houdini.h +37 -0
- data/ext/snowcrash/sundown/html/houdini_href_e.c +108 -0
- data/ext/snowcrash/sundown/html/houdini_html_e.c +84 -0
- data/ext/snowcrash/sundown/html/html.c +647 -0
- data/ext/snowcrash/sundown/html/html.h +77 -0
- data/ext/snowcrash/sundown/html/html_smartypants.c +389 -0
- data/ext/snowcrash/sundown/html_block_names.txt +25 -0
- data/ext/snowcrash/sundown/src/autolink.c +297 -0
- data/ext/snowcrash/sundown/src/autolink.h +51 -0
- data/ext/snowcrash/sundown/src/buffer.c +225 -0
- data/ext/snowcrash/sundown/src/buffer.h +96 -0
- data/ext/snowcrash/sundown/src/html_blocks.h +206 -0
- data/ext/snowcrash/sundown/src/markdown.c +2701 -0
- data/ext/snowcrash/sundown/src/markdown.h +147 -0
- data/ext/snowcrash/sundown/src/src_map.c +200 -0
- data/ext/snowcrash/sundown/src/src_map.h +58 -0
- data/ext/snowcrash/sundown/src/stack.c +81 -0
- data/ext/snowcrash/sundown/src/stack.h +29 -0
- data/ext/snowcrash/sundown/sundown.def +20 -0
- data/ext/snowcrash/tools/gyp/AUTHORS +11 -0
- data/ext/snowcrash/tools/gyp/DEPS +24 -0
- data/ext/snowcrash/tools/gyp/OWNERS +1 -0
- data/ext/snowcrash/tools/gyp/PRESUBMIT.py +120 -0
- data/ext/snowcrash/tools/gyp/buildbot/buildbot_run.py +190 -0
- data/ext/snowcrash/tools/gyp/codereview.settings +10 -0
- data/ext/snowcrash/tools/gyp/data/win/large-pdb-shim.cc +12 -0
- data/ext/snowcrash/tools/gyp/gyp +8 -0
- data/ext/snowcrash/tools/gyp/gyp.bat +5 -0
- data/ext/snowcrash/tools/gyp/gyp_main.py +18 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSNew.py +340 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSProject.py +208 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSSettings.py +1063 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSToolFile.py +58 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUserFile.py +147 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUtil.py +267 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSVersion.py +409 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.py +537 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/common.py +521 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/common.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/easy_xml.py +157 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/flock_tool.py +49 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.py +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/android.py +1069 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/cmake.py +1143 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/dump_dependency_json.py +81 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/eclipse.py +335 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypd.py +87 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypsh.py +56 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.py +2181 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/msvs.py +3335 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/ninja.py +2156 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.py +1224 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/input.py +2809 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/input.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/mac_tool.py +510 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/msvs_emulation.py +972 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/ninja_syntax.py +160 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/ordered_dict.py +289 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/win_tool.py +292 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.py +1440 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.py +2889 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyc +0 -0
- data/ext/snowcrash/tools/gyp/pylib/gyp/xml_fix.py +69 -0
- data/ext/snowcrash/tools/gyp/pylintrc +307 -0
- data/ext/snowcrash/tools/gyp/samples/samples +81 -0
- data/ext/snowcrash/tools/gyp/samples/samples.bat +5 -0
- data/ext/snowcrash/tools/gyp/setup.py +19 -0
- data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.pbfilespec +27 -0
- data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.xclangspec +226 -0
- data/ext/snowcrash/tools/gyp/tools/emacs/gyp.el +252 -0
- data/ext/snowcrash/tools/gyp/tools/graphviz.py +100 -0
- data/ext/snowcrash/tools/gyp/tools/pretty_gyp.py +155 -0
- data/ext/snowcrash/tools/gyp/tools/pretty_sln.py +168 -0
- data/ext/snowcrash/tools/gyp/tools/pretty_vcproj.py +329 -0
- data/ext/snowcrash/tools/homebrew/snowcrash.rb +11 -0
- data/ext/snowcrash/vcbuild.bat +184 -0
- data/lib/redsnow.rb +31 -0
- data/lib/redsnow/binding.rb +132 -0
- data/lib/redsnow/blueprint.rb +365 -0
- data/lib/redsnow/object.rb +18 -0
- data/lib/redsnow/parseresult.rb +107 -0
- data/lib/redsnow/version.rb +4 -0
- data/provisioning.sh +20 -0
- data/redsnow.gemspec +35 -0
- data/test/_helper.rb +15 -0
- data/test/fixtures/sample-api-ast.json +97 -0
- data/test/fixtures/sample-api.apib +20 -0
- data/test/redsnow_binding_test.rb +35 -0
- data/test/redsnow_parseresult_test.rb +50 -0
- data/test/redsnow_test.rb +285 -0
- metadata +358 -0
@@ -0,0 +1,215 @@
|
|
1
|
+
//
|
2
|
+
// AssetParser.h
|
3
|
+
// snowcrash
|
4
|
+
//
|
5
|
+
// Created by Zdenek Nemec on 5/17/13.
|
6
|
+
// Copyright (c) 2013 Apiary Inc. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
#ifndef SNOWCRASH_ASSETPARSER_H
|
10
|
+
#define SNOWCRASH_ASSETPARSER_H
|
11
|
+
|
12
|
+
#include <sstream>
|
13
|
+
#include "BlueprintParserCore.h"
|
14
|
+
#include "Blueprint.h"
|
15
|
+
#include "RegexMatch.h"
|
16
|
+
#include "StringUtility.h"
|
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
|
+
}
|
27
|
+
|
28
|
+
namespace snowcrash {
|
29
|
+
|
30
|
+
/// Asset signature
|
31
|
+
enum AssetSignature {
|
32
|
+
UndefinedAssetSignature,
|
33
|
+
NoAssetSignature,
|
34
|
+
BodyAssetSignature, /// < Explicit body asset
|
35
|
+
PayloadBodyAssetSignature, /// < Body asset using abbreviated syntax
|
36
|
+
SchemaAssetSignature, /// < Explicit Schema asset
|
37
|
+
GenericAssetSignature
|
38
|
+
};
|
39
|
+
|
40
|
+
// Query asset signature a of given block
|
41
|
+
FORCEINLINE AssetSignature GetAssetSignature(const BlockIterator& begin,
|
42
|
+
const BlockIterator& end) {
|
43
|
+
|
44
|
+
if (begin->type == ListBlockBeginType || begin->type == ListItemBlockBeginType) {
|
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;
|
57
|
+
|
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
|
+
/**
|
84
|
+
* Block Classifier, asset context.
|
85
|
+
*/
|
86
|
+
template <>
|
87
|
+
FORCEINLINE SectionType ClassifyBlock<Asset>(const BlockIterator& begin,
|
88
|
+
const BlockIterator& end,
|
89
|
+
const SectionType& context) {
|
90
|
+
|
91
|
+
if (context == UndefinedSectionType) {
|
92
|
+
AssetSignature asset = GetAssetSignature(begin, end);
|
93
|
+
if (asset == BodyAssetSignature || asset == PayloadBodyAssetSignature)
|
94
|
+
return BodySectionType;
|
95
|
+
if (asset == SchemaAssetSignature)
|
96
|
+
return SchemaSectionType;
|
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
|
+
}
|
115
|
+
|
116
|
+
// Adjacent list item
|
117
|
+
if (begin->type == ListItemBlockBeginType) {
|
118
|
+
return UndefinedSectionType;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
else if (context == DanglingBodySectionType ||
|
122
|
+
context == DanglingSchemaSectionType) {
|
123
|
+
|
124
|
+
if (begin->type == ListItemBlockEndType ||
|
125
|
+
begin->type == ListBlockEndType)
|
126
|
+
return UndefinedSectionType;
|
127
|
+
|
128
|
+
if (!IsDanglingBlock(begin, end))
|
129
|
+
return UndefinedSectionType;
|
130
|
+
}
|
131
|
+
|
132
|
+
return (context == BodySectionType ||
|
133
|
+
context == SchemaSectionType ||
|
134
|
+
context == DanglingBodySectionType ||
|
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;
|
171
|
+
}
|
172
|
+
|
173
|
+
static void Finalize(const SectionBounds& bounds,
|
174
|
+
BlueprintParserCore& parser,
|
175
|
+
Asset& asset,
|
176
|
+
Result& result) {}
|
177
|
+
|
178
|
+
static ParseSectionResult HandleAssetSectionBlock(const BlueprintSection& section,
|
179
|
+
const BlockIterator& cur,
|
180
|
+
BlueprintParserCore& parser,
|
181
|
+
Asset& asset) {
|
182
|
+
|
183
|
+
SourceData data;
|
184
|
+
SourceDataBlock sourceMap;
|
185
|
+
// NOTE: Use `Payload` traits for parsing pre-formatted list block.
|
186
|
+
ParseSectionResult result = ParseListPreformattedBlock<Payload>(section,
|
187
|
+
cur,
|
188
|
+
parser,
|
189
|
+
data,
|
190
|
+
sourceMap);
|
191
|
+
if (result.first.error.code != Error::OK ||
|
192
|
+
parser.sourceData.empty())
|
193
|
+
return result;
|
194
|
+
|
195
|
+
asset += data;
|
196
|
+
return result;
|
197
|
+
}
|
198
|
+
|
199
|
+
static ParseSectionResult HandleDanglingAssetSectionBlock(const BlueprintSection& section,
|
200
|
+
const BlockIterator& cur,
|
201
|
+
BlueprintParserCore& parser,
|
202
|
+
Asset& asset) {
|
203
|
+
|
204
|
+
// Skip any closing list blocks
|
205
|
+
BlockIterator sectionCur = CloseNestedList(cur, section.bounds.second);
|
206
|
+
return HandleAssetSectionBlock(section, sectionCur, parser, asset);
|
207
|
+
}
|
208
|
+
|
209
|
+
};
|
210
|
+
|
211
|
+
typedef BlockParser<Asset, SectionParser<Asset> > AssetParser;
|
212
|
+
|
213
|
+
}
|
214
|
+
|
215
|
+
#endif
|
@@ -0,0 +1,186 @@
|
|
1
|
+
//
|
2
|
+
// BlockUtility.h
|
3
|
+
// snowcrash
|
4
|
+
//
|
5
|
+
// Created by Zdenek Nemec on 11/11/13.
|
6
|
+
// Copyright (c) 2013 Apiary Inc. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
#ifndef SNOWCRASH_BLOCKUTILITY_H
|
10
|
+
#define SNOWCRASH_BLOCKUTILITY_H
|
11
|
+
|
12
|
+
#include "BlueprintSection.h"
|
13
|
+
#include "StringUtility.h"
|
14
|
+
|
15
|
+
namespace snowcrash {
|
16
|
+
|
17
|
+
/**
|
18
|
+
* \brief Skip to the matching closing block.
|
19
|
+
* \param begin Begin of the section inside a block buffer.
|
20
|
+
* \param end End of the block buffer.
|
21
|
+
* \param sectionBegin A %MarkdownBlockType of the beginning.
|
22
|
+
* \param sectionEnd A %MarkdownBlockType of the end.
|
23
|
+
* \return An iterator pointing to the end of the section.
|
24
|
+
*
|
25
|
+
* Advances iterator from the begin of a section to the end
|
26
|
+
* of a section at the same nesting level.
|
27
|
+
*/
|
28
|
+
FORCEINLINE BlockIterator SkipToClosingBlock(const BlockIterator& begin,
|
29
|
+
const BlockIterator& end,
|
30
|
+
MarkdownBlockType sectionBegin,
|
31
|
+
MarkdownBlockType sectionEnd) {
|
32
|
+
|
33
|
+
BlockIterator currentBlock = begin;
|
34
|
+
if (currentBlock->type == sectionBegin) {
|
35
|
+
int level = 1;
|
36
|
+
++currentBlock;
|
37
|
+
while (currentBlock != end && level) {
|
38
|
+
if (currentBlock->type == sectionBegin)
|
39
|
+
++level;
|
40
|
+
|
41
|
+
if (currentBlock->type == sectionEnd)
|
42
|
+
--level;
|
43
|
+
|
44
|
+
if (level)
|
45
|
+
++currentBlock;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
return currentBlock;
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* \brief Parse one line of raw `key:value` data.
|
54
|
+
* \param line A line to parse.
|
55
|
+
* \param keyValuePair The output buffer to place the parsed data into.
|
56
|
+
* \return True on success, false otherwise.
|
57
|
+
*/
|
58
|
+
FORCEINLINE bool KeyValueFromLine(const std::string& line,
|
59
|
+
KeyValuePair& keyValuePair) {
|
60
|
+
|
61
|
+
std::vector<std::string> rawMetadata = SplitOnFirst(line, ':');
|
62
|
+
if (rawMetadata.size() != 2)
|
63
|
+
return false;
|
64
|
+
|
65
|
+
keyValuePair = std::make_pair(rawMetadata[0], rawMetadata[1]);
|
66
|
+
TrimString(keyValuePair.first);
|
67
|
+
TrimString(keyValuePair.second);
|
68
|
+
|
69
|
+
return (!keyValuePair.first.empty() && !keyValuePair.second.empty());
|
70
|
+
}
|
71
|
+
|
72
|
+
/**
|
73
|
+
* \brief Construct unexpected block error message for given block.
|
74
|
+
* \param section A section being parsed.
|
75
|
+
* \param cue Cursor to the unexpected markdown block.
|
76
|
+
* \param sourceData Source data byte buffer.
|
77
|
+
* \return An Error with description relevant to the type of the unexpected block.
|
78
|
+
*
|
79
|
+
* This function
|
80
|
+
*/
|
81
|
+
FORCEINLINE Error UnexpectedBlockError(const BlueprintSection& section,
|
82
|
+
const BlockIterator& cur,
|
83
|
+
const SourceData& sourceData) {
|
84
|
+
|
85
|
+
|
86
|
+
std::stringstream ss;
|
87
|
+
ss << "unexpected " << BlockName(cur->type) << " block";
|
88
|
+
|
89
|
+
if (section.hasParent()) {
|
90
|
+
|
91
|
+
switch (section.parent().type) {
|
92
|
+
|
93
|
+
// Top-level section
|
94
|
+
case UndefinedSectionType:
|
95
|
+
ss << ", expected a group, resource or an action definition, e.g. ";
|
96
|
+
ss << "'# Group <name>', '# <resource name> [<URI>]' or '# <HTTP method> <URI>'";
|
97
|
+
break;
|
98
|
+
|
99
|
+
// TODO: other sections
|
100
|
+
|
101
|
+
default:
|
102
|
+
break;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
return Error(ss.str(),
|
107
|
+
BusinessError,
|
108
|
+
MapSourceDataBlock(cur->sourceMap, sourceData));
|
109
|
+
}
|
110
|
+
|
111
|
+
|
112
|
+
/**
|
113
|
+
* \brief Retrieves source code character map for a markdown block.
|
114
|
+
* \param cur A block to retrieve the characters map for.
|
115
|
+
* \param fallback Alternative block if %cur map source does not exists.
|
116
|
+
* \param bounds Boundaries of the %cur and %fallback container.
|
117
|
+
* \param sourceData Source data to map.
|
118
|
+
* \returns Character map for given markdown block or its alternative block,
|
119
|
+
* if exists. Empty source character map otherwise.
|
120
|
+
*/
|
121
|
+
FORCEINLINE SourceCharactersBlock CharacterMapForBlock(const BlockIterator& cur,
|
122
|
+
const BlockIterator& fallback,
|
123
|
+
const SectionBounds& bounds,
|
124
|
+
const SourceData& sourceData)
|
125
|
+
{
|
126
|
+
// Try to use cursor's source map
|
127
|
+
if (cur != bounds.second &&
|
128
|
+
!cur->sourceMap.empty()) {
|
129
|
+
return MapSourceDataBlock(cur->sourceMap, sourceData);
|
130
|
+
}
|
131
|
+
|
132
|
+
// Fallback to alternative (previous) block
|
133
|
+
if (fallback != bounds.second &&
|
134
|
+
!fallback->sourceMap.empty()) {
|
135
|
+
return MapSourceDataBlock(fallback->sourceMap, sourceData);
|
136
|
+
}
|
137
|
+
|
138
|
+
return SourceCharactersBlock();
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* \brief Checks cursor validity within its container.
|
143
|
+
* \param section A section to check against.
|
144
|
+
* \param cur An iterator to be checked.
|
145
|
+
* \param sourceData Source data byte buffer.
|
146
|
+
* \param result Error result output, an error object is added in case of failed check.
|
147
|
+
* \returns True if cursor appears to be valid, false otherwise.
|
148
|
+
*/
|
149
|
+
FORCEINLINE bool CheckCursor(const BlueprintSection& section,
|
150
|
+
const BlockIterator& cur,
|
151
|
+
const SourceData& sourceData,
|
152
|
+
Result& result) {
|
153
|
+
if (cur != section.bounds.second)
|
154
|
+
return true;
|
155
|
+
|
156
|
+
if (!section.hasParent() ||
|
157
|
+
section.parent().bounds.first->sourceMap.empty())
|
158
|
+
return false;
|
159
|
+
|
160
|
+
// ERR: Sanity check
|
161
|
+
SourceCharactersBlock sourceBlock = CharacterMapForBlock(section.parent().bounds.first,
|
162
|
+
section.parent().bounds.second,
|
163
|
+
section.parent().bounds,
|
164
|
+
sourceData);
|
165
|
+
result.error = Error("unexpected markdown closure",
|
166
|
+
ApplicationError,
|
167
|
+
sourceBlock);
|
168
|
+
return false;
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* \brief Check header block for an potential ambiguous signature
|
173
|
+
* \return True if a header does not contain potential ambiguous signature, false otherwise.
|
174
|
+
*/
|
175
|
+
template <class T>
|
176
|
+
FORCEINLINE bool CheckHeaderBlock(const BlueprintSection& section,
|
177
|
+
const BlockIterator& cur,
|
178
|
+
const SourceData& sourceData,
|
179
|
+
Result& result) {
|
180
|
+
|
181
|
+
return false;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
|
186
|
+
#endif
|
@@ -0,0 +1,283 @@
|
|
1
|
+
//
|
2
|
+
// Blueprint.h
|
3
|
+
// snowcrash
|
4
|
+
//
|
5
|
+
// Created by Zdenek Nemec on 4/3/13.
|
6
|
+
// Copyright (c) 2013 Apiary Inc. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
#ifndef SNOWCRASH_BLUEPRINT_H
|
10
|
+
#define SNOWCRASH_BLUEPRINT_H
|
11
|
+
|
12
|
+
#include <vector>
|
13
|
+
#include <string>
|
14
|
+
#include <utility>
|
15
|
+
#include "Platform.h"
|
16
|
+
|
17
|
+
/**
|
18
|
+
* API Blueprint Abstract Syntax Tree
|
19
|
+
* -----------------------------------
|
20
|
+
*
|
21
|
+
* Data types in this documents define the API Blueprint AST.
|
22
|
+
*/
|
23
|
+
|
24
|
+
namespace snowcrash {
|
25
|
+
|
26
|
+
/** Name of a an API Blueprint entity. */
|
27
|
+
typedef std::string Name;
|
28
|
+
|
29
|
+
/**
|
30
|
+
* \brief An API Blueprint entity Description.
|
31
|
+
*
|
32
|
+
* Depending on parser setting the description might be
|
33
|
+
* rendered HTML from Markdown or raw Markdown.
|
34
|
+
*/
|
35
|
+
typedef std::string Description;
|
36
|
+
|
37
|
+
/** URI */
|
38
|
+
typedef std::string URI;
|
39
|
+
|
40
|
+
/** URI template */
|
41
|
+
typedef std::string URITemplate;
|
42
|
+
|
43
|
+
/** HTTP Method */
|
44
|
+
typedef std::string HTTPMethod;
|
45
|
+
|
46
|
+
/** Parameter Type */
|
47
|
+
typedef std::string Type;
|
48
|
+
|
49
|
+
/** Parameter Value */
|
50
|
+
typedef std::string Value;
|
51
|
+
|
52
|
+
/** A generic key - value pair */
|
53
|
+
typedef std::pair<std::string, std::string> KeyValuePair;
|
54
|
+
|
55
|
+
/**
|
56
|
+
* Default Container for collections.
|
57
|
+
*
|
58
|
+
* FIXME: Use C++11 template aliases when migrating to C++11.
|
59
|
+
*/
|
60
|
+
template<typename T>
|
61
|
+
struct Collection {
|
62
|
+
typedef std::vector<T> type;
|
63
|
+
typedef typename std::vector<T>::iterator iterator;
|
64
|
+
typedef typename std::vector<T>::const_iterator const_iterator;
|
65
|
+
};
|
66
|
+
|
67
|
+
/** An asset data */
|
68
|
+
typedef std::string Asset;
|
69
|
+
|
70
|
+
/**
|
71
|
+
* \brief Metadata key-value pair,
|
72
|
+
*
|
73
|
+
* E.g. "HOST: http://acme.com"
|
74
|
+
*/
|
75
|
+
typedef KeyValuePair Metadata;
|
76
|
+
|
77
|
+
/**
|
78
|
+
* \brief Header key-value pair.
|
79
|
+
*
|
80
|
+
* E.g. "Content-Type: application/json"
|
81
|
+
*/
|
82
|
+
typedef KeyValuePair Header;
|
83
|
+
|
84
|
+
/** Parameter Use flag */
|
85
|
+
enum ParameterUse {
|
86
|
+
UndefinedParameterUse,
|
87
|
+
OptionalParameterUse,
|
88
|
+
RequiredParameterUse
|
89
|
+
};
|
90
|
+
|
91
|
+
/** Parameter */
|
92
|
+
struct Parameter {
|
93
|
+
|
94
|
+
/** Parameter Name */
|
95
|
+
Name name;
|
96
|
+
|
97
|
+
/** Parameter Description */
|
98
|
+
Description description;
|
99
|
+
|
100
|
+
/** Type */
|
101
|
+
Type type;
|
102
|
+
|
103
|
+
/** Required flag */
|
104
|
+
ParameterUse use;
|
105
|
+
|
106
|
+
/** Default Value, applicable only when `required == false` */
|
107
|
+
Value defaultValue;
|
108
|
+
|
109
|
+
/** Example Value */
|
110
|
+
Value exampleValue;
|
111
|
+
|
112
|
+
/** Enumeration of possible values */
|
113
|
+
Collection<Value>::type values;
|
114
|
+
};
|
115
|
+
|
116
|
+
|
117
|
+
/**
|
118
|
+
* Payload
|
119
|
+
*/
|
120
|
+
struct Payload {
|
121
|
+
|
122
|
+
/** A Payload Name */
|
123
|
+
Name name;
|
124
|
+
|
125
|
+
/** Payload Description */
|
126
|
+
Description description;
|
127
|
+
|
128
|
+
/** Payload-specific Parameters */
|
129
|
+
Collection<Parameter>::type parameters;
|
130
|
+
|
131
|
+
/** Payload-specific Headers */
|
132
|
+
Collection<Header>::type headers;
|
133
|
+
|
134
|
+
/** Body */
|
135
|
+
Asset body;
|
136
|
+
|
137
|
+
/** Schema */
|
138
|
+
Asset schema;
|
139
|
+
};
|
140
|
+
|
141
|
+
/** Resource Model */
|
142
|
+
typedef Payload ResourceModel;
|
143
|
+
|
144
|
+
/** Request */
|
145
|
+
typedef Payload Request;
|
146
|
+
|
147
|
+
/**
|
148
|
+
* \brief Response
|
149
|
+
*
|
150
|
+
* A payload returned in a response to an action.
|
151
|
+
* Payload's name represents the HTTP status code.
|
152
|
+
*/
|
153
|
+
typedef Payload Response;
|
154
|
+
|
155
|
+
/**
|
156
|
+
* An HTTP transaction example.
|
157
|
+
*/
|
158
|
+
struct TransactionExample {
|
159
|
+
|
160
|
+
/** An example name */
|
161
|
+
Name name;
|
162
|
+
|
163
|
+
/** Description */
|
164
|
+
Description description;
|
165
|
+
|
166
|
+
/** Requests */
|
167
|
+
Collection<Request>::type requests;
|
168
|
+
|
169
|
+
/** Responses */
|
170
|
+
Collection<Response>::type responses;
|
171
|
+
};
|
172
|
+
|
173
|
+
/**
|
174
|
+
* Action
|
175
|
+
*/
|
176
|
+
struct Action {
|
177
|
+
|
178
|
+
/** HTTP method */
|
179
|
+
HTTPMethod method;
|
180
|
+
|
181
|
+
/** An Action name */
|
182
|
+
Name name;
|
183
|
+
|
184
|
+
/** Description */
|
185
|
+
Description description;
|
186
|
+
|
187
|
+
/** Action-specific Parameters */
|
188
|
+
Collection<Parameter>::type parameters;
|
189
|
+
|
190
|
+
/**
|
191
|
+
* \brief Action-specific HTTP headers
|
192
|
+
*
|
193
|
+
* DEPRECATION WARNING:
|
194
|
+
* --------------------
|
195
|
+
*
|
196
|
+
* This AST node is build for deprecated API Blueprint syntax
|
197
|
+
* and as such it will be removed in a future version of
|
198
|
+
* Snow Crash.
|
199
|
+
*
|
200
|
+
* Use respective payload's header collection instead.
|
201
|
+
*/
|
202
|
+
DEPRECATED Collection<Header>::type headers;
|
203
|
+
|
204
|
+
/** Transactions examples */
|
205
|
+
Collection<TransactionExample>::type examples;
|
206
|
+
};
|
207
|
+
|
208
|
+
/**
|
209
|
+
* API Resource
|
210
|
+
*/
|
211
|
+
struct Resource {
|
212
|
+
|
213
|
+
/** URI template */
|
214
|
+
URITemplate uriTemplate;
|
215
|
+
|
216
|
+
/** A Resource Name */
|
217
|
+
Name name;
|
218
|
+
|
219
|
+
/** Description of the resource */
|
220
|
+
Description description;
|
221
|
+
|
222
|
+
/** Model representing this Resource */
|
223
|
+
ResourceModel model;
|
224
|
+
|
225
|
+
/** Parameters */
|
226
|
+
Collection<Parameter>::type parameters;
|
227
|
+
|
228
|
+
/**
|
229
|
+
* \brief Resource-specific HTTP Headers
|
230
|
+
*
|
231
|
+
* DEPRECATION WARNING:
|
232
|
+
* --------------------
|
233
|
+
*
|
234
|
+
* This AST node is build for deprecated API Blueprint syntax
|
235
|
+
* and as such it will be removed in a future version of
|
236
|
+
* Snow Crash.
|
237
|
+
*
|
238
|
+
* Use respective payload's header collection instead.
|
239
|
+
*/
|
240
|
+
DEPRECATED Collection<Header>::type headers;
|
241
|
+
|
242
|
+
/** A set of Actions specified for this Resource */
|
243
|
+
Collection<Action>::type actions;
|
244
|
+
};
|
245
|
+
|
246
|
+
/**
|
247
|
+
* Group of API Resources
|
248
|
+
*/
|
249
|
+
struct ResourceGroup {
|
250
|
+
|
251
|
+
/** A Group Name */
|
252
|
+
Name name;
|
253
|
+
|
254
|
+
/** Group description */
|
255
|
+
Description description;
|
256
|
+
|
257
|
+
/** Resources */
|
258
|
+
Collection<Resource>::type resources;
|
259
|
+
};
|
260
|
+
|
261
|
+
/**
|
262
|
+
* \brief API Blueprint AST
|
263
|
+
*
|
264
|
+
* This is top-level (or root if you prefer) of API Blueprint abstract syntax tree.
|
265
|
+
* Start reading a parsed API here.
|
266
|
+
*/
|
267
|
+
struct Blueprint {
|
268
|
+
|
269
|
+
/** Metadata */
|
270
|
+
Collection<Metadata>::type metadata;
|
271
|
+
|
272
|
+
/** The API Name */
|
273
|
+
Name name;
|
274
|
+
|
275
|
+
/** An API Overview description */
|
276
|
+
Description description;
|
277
|
+
|
278
|
+
/** The set of API Resource Groups */
|
279
|
+
Collection<ResourceGroup>::type resourceGroups;
|
280
|
+
};
|
281
|
+
}
|
282
|
+
|
283
|
+
#endif
|