redsnow 0.0.8
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 +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
|