redsnow 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,289 +0,0 @@
|
|
1
|
-
//
|
2
|
-
// HeaderParser.h
|
3
|
-
// snowcrash
|
4
|
-
//
|
5
|
-
// Created by Zdenek Nemec on 5/22/13.
|
6
|
-
// Copyright (c) 2013 Apiary Inc. All rights reserved.
|
7
|
-
//
|
8
|
-
|
9
|
-
#ifndef SNOWCRASH_HEADERPARSER_H
|
10
|
-
#define SNOWCRASH_HEADERPARSER_H
|
11
|
-
|
12
|
-
#include <sstream>
|
13
|
-
#include "BlueprintParserCore.h"
|
14
|
-
#include "Blueprint.h"
|
15
|
-
#include "RegexMatch.h"
|
16
|
-
#include "StringUtility.h"
|
17
|
-
#include "ListBlockUtility.h"
|
18
|
-
|
19
|
-
namespace snowcrashconst {
|
20
|
-
|
21
|
-
/** Headers matching regex */
|
22
|
-
const char* const HeadersRegex = "^[[:blank:]]*[Hh]eaders?[[:blank:]]*$";
|
23
|
-
}
|
24
|
-
|
25
|
-
namespace snowcrash {
|
26
|
-
|
27
|
-
// Internal type alias for Collection of Headers
|
28
|
-
typedef Collection<Header>::type HeaderCollection;
|
29
|
-
|
30
|
-
// Query header signature a of given block
|
31
|
-
FORCEINLINE bool HasHeaderSignature(const BlockIterator& begin,
|
32
|
-
const BlockIterator& end) {
|
33
|
-
|
34
|
-
if (begin->type == ListBlockBeginType || begin->type == ListItemBlockBeginType) {
|
35
|
-
|
36
|
-
BlockIterator cur = ListItemNameBlock(begin, end);
|
37
|
-
if (cur == end)
|
38
|
-
return false;
|
39
|
-
|
40
|
-
if (cur->type != ParagraphBlockType &&
|
41
|
-
cur->type != ListItemBlockEndType)
|
42
|
-
return false;
|
43
|
-
|
44
|
-
std::string content = GetFirstLine(cur->content);
|
45
|
-
return RegexMatch(content, snowcrashconst::HeadersRegex);
|
46
|
-
}
|
47
|
-
|
48
|
-
return false;
|
49
|
-
}
|
50
|
-
|
51
|
-
// Header iterator in its containment group
|
52
|
-
typedef Collection<Header>::const_iterator HeaderIterator;
|
53
|
-
|
54
|
-
// Finds a header in its containment group by its key (first)
|
55
|
-
FORCEINLINE HeaderIterator FindHeader(const HeaderCollection& headers,
|
56
|
-
const Header& header) {
|
57
|
-
|
58
|
-
return std::find_if(headers.begin(),
|
59
|
-
headers.end(),
|
60
|
-
std::bind2nd(MatchFirsts<Header>(), header));
|
61
|
-
}
|
62
|
-
|
63
|
-
/** Internal list items classifier, Headers Context */
|
64
|
-
template <>
|
65
|
-
FORCEINLINE SectionType ClassifyInternaListBlock<HeaderCollection>(const BlockIterator& begin,
|
66
|
-
const BlockIterator& end) {
|
67
|
-
return UndefinedSectionType;
|
68
|
-
}
|
69
|
-
|
70
|
-
/** Children List Block Classifier, HeaderCollection context. */
|
71
|
-
template <>
|
72
|
-
FORCEINLINE SectionType ClassifyChildrenListBlock<HeaderCollection>(const BlockIterator& begin,
|
73
|
-
const BlockIterator& end){
|
74
|
-
return UndefinedSectionType;
|
75
|
-
}
|
76
|
-
|
77
|
-
/** Block Classifier, Headers Context */
|
78
|
-
template <>
|
79
|
-
FORCEINLINE SectionType ClassifyBlock<HeaderCollection>(const BlockIterator& begin,
|
80
|
-
const BlockIterator& end,
|
81
|
-
const SectionType& context) {
|
82
|
-
|
83
|
-
if (context == UndefinedSectionType &&
|
84
|
-
HasHeaderSignature(begin, end)) {
|
85
|
-
return HeadersSectionType;
|
86
|
-
}
|
87
|
-
else if (context == HeadersSectionType) {
|
88
|
-
|
89
|
-
// SectionType closure
|
90
|
-
if (begin->type == ListItemBlockEndType ||
|
91
|
-
begin->type == ListBlockEndType)
|
92
|
-
return UndefinedSectionType;
|
93
|
-
|
94
|
-
// Adjacent list item
|
95
|
-
if (begin->type == ListItemBlockBeginType)
|
96
|
-
return UndefinedSectionType;
|
97
|
-
}
|
98
|
-
|
99
|
-
return (context == HeadersSectionType) ? context : UndefinedSectionType;
|
100
|
-
}
|
101
|
-
|
102
|
-
//
|
103
|
-
// Headers SectionType Parser
|
104
|
-
//
|
105
|
-
template<>
|
106
|
-
struct SectionParser<HeaderCollection> {
|
107
|
-
|
108
|
-
static ParseSectionResult ParseSection(const BlueprintSection& section,
|
109
|
-
const BlockIterator& cur,
|
110
|
-
BlueprintParserCore& parser,
|
111
|
-
HeaderCollection& headers) {
|
112
|
-
|
113
|
-
ParseSectionResult result = std::make_pair(Result(), cur);
|
114
|
-
switch (section.type) {
|
115
|
-
case HeadersSectionType:
|
116
|
-
result = HandleHeadersSectionBlock(section, cur, parser, headers);
|
117
|
-
break;
|
118
|
-
|
119
|
-
case UndefinedSectionType:
|
120
|
-
result.second = CloseList(cur, section.bounds.second);
|
121
|
-
break;
|
122
|
-
|
123
|
-
default:
|
124
|
-
result.first.error = UnexpectedBlockError(section, cur, parser.sourceData);
|
125
|
-
break;
|
126
|
-
}
|
127
|
-
|
128
|
-
return result;
|
129
|
-
}
|
130
|
-
|
131
|
-
static void Finalize(const SectionBounds& bounds,
|
132
|
-
BlueprintParserCore& parser,
|
133
|
-
HeaderCollection& headers,
|
134
|
-
Result& result) {}
|
135
|
-
|
136
|
-
static ParseSectionResult HandleHeadersSectionBlock(const BlueprintSection& section,
|
137
|
-
const BlockIterator& cur,
|
138
|
-
BlueprintParserCore& parser,
|
139
|
-
HeaderCollection& headers) {
|
140
|
-
|
141
|
-
SourceData data;
|
142
|
-
SourceDataBlock sourceMap;
|
143
|
-
ParseSectionResult result = ParseListPreformattedBlock<HeaderCollection>(section,
|
144
|
-
cur,
|
145
|
-
parser,
|
146
|
-
data,
|
147
|
-
sourceMap);
|
148
|
-
if (result.first.error.code != Error::OK ||
|
149
|
-
parser.sourceData.empty())
|
150
|
-
return result;
|
151
|
-
|
152
|
-
// Proces raw data
|
153
|
-
std::vector<std::string> lines = Split(data, '\n');
|
154
|
-
for (std::vector<std::string>::iterator line = lines.begin();
|
155
|
-
line != lines.end();
|
156
|
-
++line) {
|
157
|
-
|
158
|
-
Header header;
|
159
|
-
if (KeyValueFromLine(*line, header)) {
|
160
|
-
|
161
|
-
if (FindHeader(headers, header) != headers.end()) {
|
162
|
-
// WARN: duplicate header on this level
|
163
|
-
std::stringstream ss;
|
164
|
-
ss << "duplicate definition of '" << header.first << "' header";
|
165
|
-
|
166
|
-
result.first.warnings.push_back(Warning(ss.str(),
|
167
|
-
DuplicateWarning,
|
168
|
-
MapSourceDataBlock(sourceMap, parser.sourceData)));
|
169
|
-
|
170
|
-
}
|
171
|
-
|
172
|
-
headers.push_back(header);
|
173
|
-
}
|
174
|
-
else {
|
175
|
-
// WARN: unable to parse header
|
176
|
-
result.first.warnings.push_back(Warning("unable to parse HTTP header, expected"
|
177
|
-
" '<header name> : <header value>', one header per line",
|
178
|
-
FormattingWarning,
|
179
|
-
MapSourceDataBlock(sourceMap, parser.sourceData)));
|
180
|
-
}
|
181
|
-
}
|
182
|
-
|
183
|
-
return result;
|
184
|
-
}
|
185
|
-
};
|
186
|
-
|
187
|
-
typedef BlockParser<HeaderCollection, SectionParser<HeaderCollection> > HeadersParser;
|
188
|
-
|
189
|
-
/**
|
190
|
-
* Generic HeaderSection parser handler
|
191
|
-
*/
|
192
|
-
template <class T>
|
193
|
-
ParseSectionResult HandleHeaders(const BlueprintSection& section,
|
194
|
-
const BlockIterator& cur,
|
195
|
-
BlueprintParserCore& parser,
|
196
|
-
T& t)
|
197
|
-
{
|
198
|
-
size_t headerCount = t.headers.size();
|
199
|
-
ParseSectionResult result = HeadersParser::Parse(cur,
|
200
|
-
section.bounds.second,
|
201
|
-
section,
|
202
|
-
parser,
|
203
|
-
t.headers);
|
204
|
-
if (result.first.error.code != Error::OK)
|
205
|
-
return result;
|
206
|
-
|
207
|
-
if (t.headers.size() == headerCount) {
|
208
|
-
BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
|
209
|
-
SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, parser.sourceData);
|
210
|
-
result.first.warnings.push_back(Warning("no headers specified",
|
211
|
-
FormattingWarning,
|
212
|
-
sourceBlock));
|
213
|
-
}
|
214
|
-
return result;
|
215
|
-
}
|
216
|
-
|
217
|
-
|
218
|
-
/** Helper for handling parsing of deprecated header sections */
|
219
|
-
template <typename T>
|
220
|
-
ParseSectionResult HandleDeprecatedHeaders(const BlueprintSection& section,
|
221
|
-
const BlockIterator& cur,
|
222
|
-
BlueprintParserCore& parser,
|
223
|
-
T& t) {
|
224
|
-
|
225
|
-
ParseSectionResult result = HandleHeaders<T>(section, cur, parser, t);
|
226
|
-
|
227
|
-
// WARN: Deprecated header sections
|
228
|
-
std::stringstream ss;
|
229
|
-
ss << "the 'headers' section at this level is deprecated and will be removed in a future, use respective payload header section(s) instead";
|
230
|
-
BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
|
231
|
-
SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, parser.sourceData);
|
232
|
-
result.first.warnings.push_back(Warning(ss.str(),
|
233
|
-
DeprecatedWarning,
|
234
|
-
sourceBlock));
|
235
|
-
return result;
|
236
|
-
}
|
237
|
-
|
238
|
-
/** \brief Copy headers into example paylods headers. */
|
239
|
-
FORCEINLINE void InjectDeprecatedHeaders(const Collection<Header>::type& headers,
|
240
|
-
Collection<TransactionExample>::type& examples)
|
241
|
-
{
|
242
|
-
for (Collection<TransactionExample>::iterator exampleIt = examples.begin();
|
243
|
-
exampleIt != examples.end();
|
244
|
-
++exampleIt) {
|
245
|
-
|
246
|
-
// Requests
|
247
|
-
for (Collection<Request>::iterator reqIt = exampleIt->requests.begin();
|
248
|
-
reqIt != exampleIt->requests.end();
|
249
|
-
++reqIt) {
|
250
|
-
|
251
|
-
reqIt->headers.insert(reqIt->headers.begin(),
|
252
|
-
headers.begin(),
|
253
|
-
headers.end());
|
254
|
-
}
|
255
|
-
|
256
|
-
// Responses
|
257
|
-
for (Collection<Response>::iterator resIt = exampleIt->responses.begin();
|
258
|
-
resIt != exampleIt->responses.end();
|
259
|
-
++resIt) {
|
260
|
-
|
261
|
-
resIt->headers.insert(resIt->headers.begin(),
|
262
|
-
headers.begin(),
|
263
|
-
headers.end());
|
264
|
-
}
|
265
|
-
}
|
266
|
-
}
|
267
|
-
|
268
|
-
// Checks T's headers for occurence of R's headers, warns if a match is found.
|
269
|
-
template <class T, class R>
|
270
|
-
void CheckHeaderDuplicates(const T& left,
|
271
|
-
const R& right,
|
272
|
-
const SourceDataBlock& rightSourceMap,
|
273
|
-
const SourceData& sourceData,
|
274
|
-
Result& result) {
|
275
|
-
|
276
|
-
for (HeaderIterator it = right.headers.begin(); it != right.headers.end(); ++it) {
|
277
|
-
if (FindHeader(left.headers, *it) != left.headers.end()) {
|
278
|
-
// WARN: overshadowing header definition
|
279
|
-
std::stringstream ss;
|
280
|
-
ss << "overshadowing previous '" << it->first << "' header definition";
|
281
|
-
result.warnings.push_back(Warning(ss.str(),
|
282
|
-
RedefinitionWarning,
|
283
|
-
MapSourceDataBlock(rightSourceMap, sourceData)));
|
284
|
-
}
|
285
|
-
}
|
286
|
-
}
|
287
|
-
}
|
288
|
-
|
289
|
-
#endif
|
@@ -1,273 +0,0 @@
|
|
1
|
-
//
|
2
|
-
// ListBlockUtility.h
|
3
|
-
// snowcrash
|
4
|
-
//
|
5
|
-
// All the cool kids from ListUtility.h live here.
|
6
|
-
//
|
7
|
-
// Created by Zdenek Nemec on 11/11/13.
|
8
|
-
// Copyright (c) 2013 Apiary Inc. All rights reserved.
|
9
|
-
//
|
10
|
-
|
11
|
-
#ifndef SNOWCRASH_LISTBLOCKUTILITY_H
|
12
|
-
#define SNOWCRASH_LISTBLOCKUTILITY_H
|
13
|
-
|
14
|
-
#include "ListUtility.h"
|
15
|
-
|
16
|
-
namespace snowcrash {
|
17
|
-
|
18
|
-
/**
|
19
|
-
* \brief Return a first non-signature content block of a list(item).
|
20
|
-
* \param begin Begin of the block buffer to examine.
|
21
|
-
* \param end End of the block buffer.
|
22
|
-
* \return First non-signature content block or begin.
|
23
|
-
*
|
24
|
-
* Returns first block with the actual content of a list or list item.
|
25
|
-
*/
|
26
|
-
FORCEINLINE BlockIterator ContentBlock(const BlockIterator& begin,
|
27
|
-
const BlockIterator& end) {
|
28
|
-
|
29
|
-
BlockIterator cur = begin;
|
30
|
-
if (cur->type == ListBlockBeginType) {
|
31
|
-
if (++cur == end)
|
32
|
-
return end;
|
33
|
-
|
34
|
-
return cur;
|
35
|
-
}
|
36
|
-
|
37
|
-
if (cur->type == ListItemBlockBeginType) {
|
38
|
-
if (++cur == end)
|
39
|
-
return end;
|
40
|
-
|
41
|
-
if (cur->type == ListItemBlockEndType)
|
42
|
-
return begin;
|
43
|
-
|
44
|
-
if (cur->type == ParagraphBlockType)
|
45
|
-
if (++cur == end)
|
46
|
-
return end;
|
47
|
-
}
|
48
|
-
|
49
|
-
return cur;
|
50
|
-
}
|
51
|
-
|
52
|
-
/**
|
53
|
-
* \brief Skips first list item signature block.
|
54
|
-
*
|
55
|
-
* This function effectively returns the first content block of
|
56
|
-
* a list item that is not a signature block. If no such a block exists.
|
57
|
-
* a block following the list item is returned. If a list is provided it
|
58
|
-
* uses its first list item.
|
59
|
-
*/
|
60
|
-
FORCEINLINE BlockIterator SkipSignatureBlock(const BlockIterator& begin,
|
61
|
-
const BlockIterator& end) {
|
62
|
-
|
63
|
-
BlockIterator cur = begin;
|
64
|
-
|
65
|
-
// Skip to fist list item if appropriate
|
66
|
-
if (cur->type == ListBlockBeginType) {
|
67
|
-
cur = ContentBlock(cur, end);
|
68
|
-
}
|
69
|
-
|
70
|
-
// Skip to first list item content
|
71
|
-
if (cur->type == ListItemBlockBeginType) {
|
72
|
-
BlockIterator firstContent = ContentBlock(cur, end);
|
73
|
-
if (cur != firstContent) {
|
74
|
-
cur = firstContent;
|
75
|
-
}
|
76
|
-
else {
|
77
|
-
// No content, just move to the next block
|
78
|
-
++cur;
|
79
|
-
}
|
80
|
-
}
|
81
|
-
|
82
|
-
return cur;
|
83
|
-
}
|
84
|
-
|
85
|
-
// Return name block of list item; that is either FirstContentBlock() or
|
86
|
-
// matching closing item block for inline items
|
87
|
-
FORCEINLINE BlockIterator ListItemNameBlock(const BlockIterator& begin,
|
88
|
-
const BlockIterator& end) {
|
89
|
-
|
90
|
-
BlockIterator cur = FirstContentBlock(begin, end);
|
91
|
-
if (cur == end ||
|
92
|
-
cur->type != ListBlockBeginType)
|
93
|
-
return cur;
|
94
|
-
|
95
|
-
// Inline list block
|
96
|
-
cur = SkipToClosingBlock(cur, end, ListBlockBeginType, ListBlockEndType);
|
97
|
-
if (cur != end)
|
98
|
-
return ++cur;
|
99
|
-
|
100
|
-
return cur;
|
101
|
-
}
|
102
|
-
|
103
|
-
/**
|
104
|
-
* \brief Eats closing blocks of a list / list item block.
|
105
|
-
* \param begin Cursor to a list or list item closing block.
|
106
|
-
* \param end End of a block buffer.
|
107
|
-
* \return Block AFTER closed list / list item.
|
108
|
-
*
|
109
|
-
* Skips over subsequent ListItemBlockEndType and ListBlockEndType returning the fist
|
110
|
-
* other block after.
|
111
|
-
*/
|
112
|
-
FORCEINLINE BlockIterator CloseList(const BlockIterator& begin,
|
113
|
-
const BlockIterator& end) {
|
114
|
-
|
115
|
-
BlockIterator cur = begin;
|
116
|
-
if (cur != end &&
|
117
|
-
cur->type == ListItemBlockEndType) {
|
118
|
-
++cur; // eat list item end
|
119
|
-
}
|
120
|
-
|
121
|
-
if (cur != end &&
|
122
|
-
cur->type == ListBlockEndType) {
|
123
|
-
++cur; // eat list end
|
124
|
-
}
|
125
|
-
|
126
|
-
return cur;
|
127
|
-
}
|
128
|
-
|
129
|
-
/**
|
130
|
-
* \brief Skips COMPLETE consecutive (nested) closing elements of a list or a list item.
|
131
|
-
* \param begin The begin of a list or a list item.
|
132
|
-
* \param end End of markdown block buffer.
|
133
|
-
* \return An iterator pointing AFTER the last closing list / list item block.
|
134
|
-
*/
|
135
|
-
FORCEINLINE BlockIterator CloseNestedList(const BlockIterator& begin,
|
136
|
-
const BlockIterator& end) {
|
137
|
-
BlockIterator cur = begin;
|
138
|
-
while (cur != end &&
|
139
|
-
(cur->type == ListItemBlockEndType || cur->type == ListBlockEndType)) {
|
140
|
-
cur = CloseList(cur, end);
|
141
|
-
}
|
142
|
-
return cur;
|
143
|
-
}
|
144
|
-
|
145
|
-
/**
|
146
|
-
* \brief Extract the first line of a list item content - its signature
|
147
|
-
* \param cur The begining of the list item to get its signature.
|
148
|
-
* \param end The begining of a block buffer.
|
149
|
-
* \param remainingContent Any additonal content after the first line of signature.
|
150
|
-
* \return First line of the list item signature.
|
151
|
-
*/
|
152
|
-
FORCEINLINE SourceData GetListItemSignature(const BlockIterator& cur,
|
153
|
-
const BlockIterator& end,
|
154
|
-
SourceData& remainingContent) {
|
155
|
-
|
156
|
-
BlockIterator sectionCur = ListItemNameBlock(cur, end);
|
157
|
-
if (sectionCur == end)
|
158
|
-
return SourceData();
|
159
|
-
|
160
|
-
ContentParts content = ExtractFirstLine(*sectionCur);
|
161
|
-
if (content.empty() ||
|
162
|
-
content.front().empty())
|
163
|
-
return SourceData();
|
164
|
-
|
165
|
-
if (content.size() == 2)
|
166
|
-
remainingContent = content[1];
|
167
|
-
|
168
|
-
return content[0];
|
169
|
-
}
|
170
|
-
|
171
|
-
/**
|
172
|
-
* \brief Check List Item signature for an addtional content and issue a warning.
|
173
|
-
* \param section Current section to be checked.
|
174
|
-
* \param cur The begining of the list item to check.
|
175
|
-
* \param bounds Bounds within the block buffer.
|
176
|
-
* \param sourceData Source data byte buffer.
|
177
|
-
* \param placeHint A string explaining the possible place of failure. Might be empty.
|
178
|
-
* \param expectedHint A string defining expected content. Might be empty.
|
179
|
-
* \param result Result to append the possible warning into.
|
180
|
-
* \return True if signagure contains no additional content, false otherwise.
|
181
|
-
*/
|
182
|
-
FORCEINLINE bool CheckSignatureAdditionalContent(const BlueprintSection& section,
|
183
|
-
const BlockIterator& cur,
|
184
|
-
const SourceData& sourceData,
|
185
|
-
const std::string& placeHint,
|
186
|
-
const std::string& expectedHint,
|
187
|
-
Result& result)
|
188
|
-
{
|
189
|
-
SourceData remainingContent;
|
190
|
-
SourceData signature = GetListItemSignature(cur, section.bounds.second, remainingContent);
|
191
|
-
|
192
|
-
if (!remainingContent.empty()) {
|
193
|
-
// WARN: Superfluous content in signature
|
194
|
-
|
195
|
-
std::stringstream ss;
|
196
|
-
ss << "ignoring additional content";
|
197
|
-
|
198
|
-
if (!placeHint.empty())
|
199
|
-
ss << " after " << placeHint;
|
200
|
-
|
201
|
-
if (!expectedHint.empty())
|
202
|
-
ss << ", expected " << expectedHint;
|
203
|
-
|
204
|
-
BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
|
205
|
-
SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, sourceData);
|
206
|
-
result.warnings.push_back(Warning(ss.str(),
|
207
|
-
IgnoringWarning,
|
208
|
-
sourceBlock));
|
209
|
-
}
|
210
|
-
|
211
|
-
return remainingContent.empty();
|
212
|
-
}
|
213
|
-
|
214
|
-
/**
|
215
|
-
* \brief Parses list (item) block as a preformatted code block.
|
216
|
-
* \param section Actual section being parsed.
|
217
|
-
* \param cur Cursor within the section boundaries.
|
218
|
-
* \param parser Parser instance.
|
219
|
-
* \param action An output data buffer.
|
220
|
-
* \param sourceMap An output source map buffer.
|
221
|
-
* \return A block parser section result, pointing AFTER the last block parsed.
|
222
|
-
*/
|
223
|
-
template <class T>
|
224
|
-
FORCEINLINE ParseSectionResult ParseListPreformattedBlock(const BlueprintSection& section,
|
225
|
-
const BlockIterator& cur,
|
226
|
-
BlueprintParserCore& parser,
|
227
|
-
SourceData& data,
|
228
|
-
SourceDataBlock& sourceMap) {
|
229
|
-
|
230
|
-
ParseSectionResult result = std::make_pair(Result(), cur);
|
231
|
-
BlockIterator sectionCur = cur;
|
232
|
-
|
233
|
-
if (sectionCur != section.bounds.first) {
|
234
|
-
// Parse subsequent blocks as standalone pre blocks.
|
235
|
-
return ParsePreformattedBlock<T>(section, sectionCur, parser, data, sourceMap);
|
236
|
-
}
|
237
|
-
|
238
|
-
// Parse first block of list, throwing away its first line (signature)
|
239
|
-
SourceData content;
|
240
|
-
SourceData signature = GetListItemSignature(cur, section.bounds.second, content);
|
241
|
-
|
242
|
-
// Retrieve any extra lines after signature & warn
|
243
|
-
if (!content.empty()) {
|
244
|
-
|
245
|
-
data = content;
|
246
|
-
|
247
|
-
// WARN: not a preformatted code block
|
248
|
-
std::stringstream ss;
|
249
|
-
|
250
|
-
size_t level = CodeBlockIndentationLevel(section);
|
251
|
-
ss << SectionName(section.type) << " asset ";
|
252
|
-
ss << "is expected to be a pre-formatted code block, separate it by a newline and ";
|
253
|
-
ss << "indent every of its line by ";
|
254
|
-
ss << level * 4 << " spaces or " << level << " tabs";
|
255
|
-
|
256
|
-
BlockIterator nameBlock = ListItemNameBlock(sectionCur, section.bounds.second);
|
257
|
-
SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, parser.sourceData);
|
258
|
-
result.first.warnings.push_back(Warning(ss.str(),
|
259
|
-
IndentationWarning,
|
260
|
-
sourceBlock));
|
261
|
-
}
|
262
|
-
|
263
|
-
sectionCur = FirstContentBlock(cur, section.bounds.second);
|
264
|
-
sourceMap = sectionCur->sourceMap;
|
265
|
-
|
266
|
-
if (sectionCur != section.bounds.second)
|
267
|
-
result.second = ++sectionCur;
|
268
|
-
|
269
|
-
return result;
|
270
|
-
}
|
271
|
-
}
|
272
|
-
|
273
|
-
#endif
|