redsnow 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +34 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +20 -0
  5. data/CHANGELOG.md +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +21 -0
  8. data/README.md +62 -0
  9. data/Rakefile +36 -0
  10. data/Vagrantfile +20 -0
  11. data/ext/snowcrash/Makefile +64 -0
  12. data/ext/snowcrash/Vagrantfile +20 -0
  13. data/ext/snowcrash/bin/snowcrash +0 -0
  14. data/ext/snowcrash/common.gypi +163 -0
  15. data/ext/snowcrash/config.gypi +10 -0
  16. data/ext/snowcrash/config.mk +5 -0
  17. data/ext/snowcrash/configure +213 -0
  18. data/ext/snowcrash/provisioning.sh +15 -0
  19. data/ext/snowcrash/snowcrash.gyp +141 -0
  20. data/ext/snowcrash/src/ActionParser.h +503 -0
  21. data/ext/snowcrash/src/AssetParser.h +215 -0
  22. data/ext/snowcrash/src/BlockUtility.h +186 -0
  23. data/ext/snowcrash/src/Blueprint.h +283 -0
  24. data/ext/snowcrash/src/BlueprintParser.h +347 -0
  25. data/ext/snowcrash/src/BlueprintParserCore.h +190 -0
  26. data/ext/snowcrash/src/BlueprintSection.h +140 -0
  27. data/ext/snowcrash/src/BlueprintUtility.h +126 -0
  28. data/ext/snowcrash/src/CBlueprint.cc +600 -0
  29. data/ext/snowcrash/src/CBlueprint.h +354 -0
  30. data/ext/snowcrash/src/CSourceAnnotation.cc +140 -0
  31. data/ext/snowcrash/src/CSourceAnnotation.h +106 -0
  32. data/ext/snowcrash/src/CodeBlockUtility.h +189 -0
  33. data/ext/snowcrash/src/DescriptionSectionUtility.h +156 -0
  34. data/ext/snowcrash/src/HTTP.cc +46 -0
  35. data/ext/snowcrash/src/HTTP.h +105 -0
  36. data/ext/snowcrash/src/HeaderParser.h +289 -0
  37. data/ext/snowcrash/src/ListBlockUtility.h +273 -0
  38. data/ext/snowcrash/src/ListUtility.h +95 -0
  39. data/ext/snowcrash/src/MarkdownBlock.cc +176 -0
  40. data/ext/snowcrash/src/MarkdownBlock.h +93 -0
  41. data/ext/snowcrash/src/MarkdownParser.cc +266 -0
  42. data/ext/snowcrash/src/MarkdownParser.h +88 -0
  43. data/ext/snowcrash/src/ParameterDefinitonParser.h +570 -0
  44. data/ext/snowcrash/src/ParametersParser.h +252 -0
  45. data/ext/snowcrash/src/Parser.cc +71 -0
  46. data/ext/snowcrash/src/Parser.h +29 -0
  47. data/ext/snowcrash/src/ParserCore.cc +120 -0
  48. data/ext/snowcrash/src/ParserCore.h +82 -0
  49. data/ext/snowcrash/src/PayloadParser.h +672 -0
  50. data/ext/snowcrash/src/Platform.h +54 -0
  51. data/ext/snowcrash/src/RegexMatch.h +32 -0
  52. data/ext/snowcrash/src/ResourceGroupParser.h +195 -0
  53. data/ext/snowcrash/src/ResourceParser.h +584 -0
  54. data/ext/snowcrash/src/SectionUtility.h +142 -0
  55. data/ext/snowcrash/src/Serialize.cc +52 -0
  56. data/ext/snowcrash/src/Serialize.h +69 -0
  57. data/ext/snowcrash/src/SerializeJSON.cc +601 -0
  58. data/ext/snowcrash/src/SerializeJSON.h +21 -0
  59. data/ext/snowcrash/src/SerializeYAML.cc +336 -0
  60. data/ext/snowcrash/src/SerializeYAML.h +21 -0
  61. data/ext/snowcrash/src/SourceAnnotation.h +177 -0
  62. data/ext/snowcrash/src/StringUtility.h +109 -0
  63. data/ext/snowcrash/src/SymbolTable.h +83 -0
  64. data/ext/snowcrash/src/UriTemplateParser.cc +195 -0
  65. data/ext/snowcrash/src/UriTemplateParser.h +243 -0
  66. data/ext/snowcrash/src/Version.h +39 -0
  67. data/ext/snowcrash/src/csnowcrash.cc +23 -0
  68. data/ext/snowcrash/src/csnowcrash.h +38 -0
  69. data/ext/snowcrash/src/posix/RegexMatch.cc +99 -0
  70. data/ext/snowcrash/src/snowcrash.cc +18 -0
  71. data/ext/snowcrash/src/snowcrash.h +41 -0
  72. data/ext/snowcrash/src/snowcrash/snowcrash.cc +170 -0
  73. data/ext/snowcrash/src/win/RegexMatch.cc +78 -0
  74. data/ext/snowcrash/sundown/CONTRIBUTING.md +10 -0
  75. data/ext/snowcrash/sundown/Makefile +83 -0
  76. data/ext/snowcrash/sundown/Makefile.win +33 -0
  77. data/ext/snowcrash/sundown/examples/smartypants.c +72 -0
  78. data/ext/snowcrash/sundown/examples/sundown.c +80 -0
  79. data/ext/snowcrash/sundown/html/houdini.h +37 -0
  80. data/ext/snowcrash/sundown/html/houdini_href_e.c +108 -0
  81. data/ext/snowcrash/sundown/html/houdini_html_e.c +84 -0
  82. data/ext/snowcrash/sundown/html/html.c +647 -0
  83. data/ext/snowcrash/sundown/html/html.h +77 -0
  84. data/ext/snowcrash/sundown/html/html_smartypants.c +389 -0
  85. data/ext/snowcrash/sundown/html_block_names.txt +25 -0
  86. data/ext/snowcrash/sundown/src/autolink.c +297 -0
  87. data/ext/snowcrash/sundown/src/autolink.h +51 -0
  88. data/ext/snowcrash/sundown/src/buffer.c +225 -0
  89. data/ext/snowcrash/sundown/src/buffer.h +96 -0
  90. data/ext/snowcrash/sundown/src/html_blocks.h +206 -0
  91. data/ext/snowcrash/sundown/src/markdown.c +2701 -0
  92. data/ext/snowcrash/sundown/src/markdown.h +147 -0
  93. data/ext/snowcrash/sundown/src/src_map.c +200 -0
  94. data/ext/snowcrash/sundown/src/src_map.h +58 -0
  95. data/ext/snowcrash/sundown/src/stack.c +81 -0
  96. data/ext/snowcrash/sundown/src/stack.h +29 -0
  97. data/ext/snowcrash/sundown/sundown.def +20 -0
  98. data/ext/snowcrash/tools/gyp/AUTHORS +11 -0
  99. data/ext/snowcrash/tools/gyp/DEPS +24 -0
  100. data/ext/snowcrash/tools/gyp/OWNERS +1 -0
  101. data/ext/snowcrash/tools/gyp/PRESUBMIT.py +120 -0
  102. data/ext/snowcrash/tools/gyp/buildbot/buildbot_run.py +190 -0
  103. data/ext/snowcrash/tools/gyp/codereview.settings +10 -0
  104. data/ext/snowcrash/tools/gyp/data/win/large-pdb-shim.cc +12 -0
  105. data/ext/snowcrash/tools/gyp/gyp +8 -0
  106. data/ext/snowcrash/tools/gyp/gyp.bat +5 -0
  107. data/ext/snowcrash/tools/gyp/gyp_main.py +18 -0
  108. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSNew.py +340 -0
  109. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSProject.py +208 -0
  110. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSSettings.py +1063 -0
  111. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSToolFile.py +58 -0
  112. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUserFile.py +147 -0
  113. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUtil.py +267 -0
  114. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSVersion.py +409 -0
  115. data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.py +537 -0
  116. data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.pyc +0 -0
  117. data/ext/snowcrash/tools/gyp/pylib/gyp/common.py +521 -0
  118. data/ext/snowcrash/tools/gyp/pylib/gyp/common.pyc +0 -0
  119. data/ext/snowcrash/tools/gyp/pylib/gyp/easy_xml.py +157 -0
  120. data/ext/snowcrash/tools/gyp/pylib/gyp/flock_tool.py +49 -0
  121. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.py +0 -0
  122. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.pyc +0 -0
  123. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/android.py +1069 -0
  124. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/cmake.py +1143 -0
  125. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/dump_dependency_json.py +81 -0
  126. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/eclipse.py +335 -0
  127. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypd.py +87 -0
  128. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypsh.py +56 -0
  129. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.py +2181 -0
  130. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.pyc +0 -0
  131. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/msvs.py +3335 -0
  132. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/ninja.py +2156 -0
  133. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.py +1224 -0
  134. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.pyc +0 -0
  135. data/ext/snowcrash/tools/gyp/pylib/gyp/input.py +2809 -0
  136. data/ext/snowcrash/tools/gyp/pylib/gyp/input.pyc +0 -0
  137. data/ext/snowcrash/tools/gyp/pylib/gyp/mac_tool.py +510 -0
  138. data/ext/snowcrash/tools/gyp/pylib/gyp/msvs_emulation.py +972 -0
  139. data/ext/snowcrash/tools/gyp/pylib/gyp/ninja_syntax.py +160 -0
  140. data/ext/snowcrash/tools/gyp/pylib/gyp/ordered_dict.py +289 -0
  141. data/ext/snowcrash/tools/gyp/pylib/gyp/win_tool.py +292 -0
  142. data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.py +1440 -0
  143. data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.pyc +0 -0
  144. data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.py +2889 -0
  145. data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyc +0 -0
  146. data/ext/snowcrash/tools/gyp/pylib/gyp/xml_fix.py +69 -0
  147. data/ext/snowcrash/tools/gyp/pylintrc +307 -0
  148. data/ext/snowcrash/tools/gyp/samples/samples +81 -0
  149. data/ext/snowcrash/tools/gyp/samples/samples.bat +5 -0
  150. data/ext/snowcrash/tools/gyp/setup.py +19 -0
  151. data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.pbfilespec +27 -0
  152. data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.xclangspec +226 -0
  153. data/ext/snowcrash/tools/gyp/tools/emacs/gyp.el +252 -0
  154. data/ext/snowcrash/tools/gyp/tools/graphviz.py +100 -0
  155. data/ext/snowcrash/tools/gyp/tools/pretty_gyp.py +155 -0
  156. data/ext/snowcrash/tools/gyp/tools/pretty_sln.py +168 -0
  157. data/ext/snowcrash/tools/gyp/tools/pretty_vcproj.py +329 -0
  158. data/ext/snowcrash/tools/homebrew/snowcrash.rb +11 -0
  159. data/ext/snowcrash/vcbuild.bat +184 -0
  160. data/lib/redsnow.rb +31 -0
  161. data/lib/redsnow/binding.rb +132 -0
  162. data/lib/redsnow/blueprint.rb +365 -0
  163. data/lib/redsnow/object.rb +18 -0
  164. data/lib/redsnow/parseresult.rb +107 -0
  165. data/lib/redsnow/version.rb +4 -0
  166. data/provisioning.sh +20 -0
  167. data/redsnow.gemspec +35 -0
  168. data/test/_helper.rb +15 -0
  169. data/test/fixtures/sample-api-ast.json +97 -0
  170. data/test/fixtures/sample-api.apib +20 -0
  171. data/test/redsnow_binding_test.rb +35 -0
  172. data/test/redsnow_parseresult_test.rb +50 -0
  173. data/test/redsnow_test.rb +285 -0
  174. metadata +358 -0
@@ -0,0 +1,106 @@
1
+ //
2
+ // CSourceAnnotation.h
3
+ // snowcrash
4
+ // C Implementation of SourceAnnotation.h for binding purposes
5
+ //
6
+ // Created by Ali Khoramshahi on 13/6/14.
7
+ // Copyright (c) 2014 Apiary Inc. All rights reserved.
8
+ //
9
+
10
+ #ifndef SC_C_SOURCEANNOTATION_H
11
+ #define SC_C_SOURCEANNOTATION_H
12
+
13
+ #include "Platform.h"
14
+ #include "stdlib.h"
15
+
16
+ #ifdef __cplusplus
17
+ extern "C" {
18
+ #endif
19
+
20
+ /** Class Result wrapper */
21
+ struct sc_result_s;
22
+ typedef struct sc_result_s sc_result_t;
23
+
24
+ /** Array warnings wrapper */
25
+ struct sc_warnings_s;
26
+ typedef struct sc_warnings_s sc_warnings_t;
27
+
28
+ /** Class warning wrapper */
29
+ struct sc_warning_s;
30
+ typedef struct sc_warning_s sc_warning_t;
31
+
32
+ /** Class error wrapper */
33
+ struct sc_error_s;
34
+ typedef struct sc_error_s sc_error_t;
35
+
36
+ /** Class location wrapper */
37
+ struct sc_location_s;
38
+ typedef struct sc_location_s sc_location_t;
39
+
40
+ /** Class SourceAnnotation wrapper */
41
+ struct sc_source_annotation_s;
42
+ typedef struct sc_source_annotation_s sc_source_annotation_t;
43
+
44
+ /*----------------------------------------------------------------------*/
45
+
46
+ /** \returns pointer to allocated Result*/
47
+ SC_API sc_result_t* sc_result_new();
48
+
49
+ /** \deallocate Result from pointer*/
50
+ SC_API void sc_result_free(sc_result_t* result);
51
+
52
+ /*----------------------------------------------------------------------*/
53
+
54
+ /** \returns location handler*/
55
+ SC_API const sc_location_t* sc_location_handler(const sc_source_annotation_t* source);
56
+
57
+ /** \returns location array size*/
58
+ SC_API size_t sc_location_size(const sc_location_t* location);
59
+
60
+ /** \returns location at `index` length*/
61
+ SC_API size_t sc_location_length(const sc_location_t* location, size_t index);
62
+
63
+ /** \returns location at `index` location*/
64
+ SC_API size_t sc_location_location(const sc_location_t* location, size_t index);
65
+
66
+ /*----------------------------------------------------------------------*/
67
+
68
+ /** \returns error handler*/
69
+ SC_API const sc_error_t* sc_error_handler(const sc_result_t* result);
70
+
71
+ /** \returns error message*/
72
+ SC_API const char* sc_error_message(const sc_error_t* error);
73
+
74
+ /** \returns error code*/
75
+ SC_API int sc_error_code(const sc_error_t* error);
76
+
77
+ /** \returns error OK*/
78
+ SC_API int sc_error_ok(const sc_error_t* error);
79
+
80
+ /*----------------------------------------------------------------------*/
81
+
82
+ /** \returns warnings handler*/
83
+ SC_API const sc_warnings_t* sc_warnings_handler(const sc_result_t* result);
84
+
85
+ /** \returns warnings array size*/
86
+ SC_API size_t sc_warnings_size(const sc_warnings_t* warning);
87
+
88
+ /*----------------------------------------------------------------------*/
89
+
90
+ /** \returns warning at `index` handle*/
91
+ SC_API const sc_warning_t* sc_warning_handler(const sc_warnings_t* warning, size_t index);
92
+
93
+ /** \returns warning message*/
94
+ SC_API const char* sc_warning_message(const sc_warning_t* warning);
95
+
96
+ /** \returns warning code*/
97
+ SC_API int sc_warning_code(const sc_warning_t* warning);
98
+
99
+ /** \returns warning OK*/
100
+ SC_API int sc_warning_ok(const sc_warning_t* warning);
101
+
102
+ #ifdef __cplusplus
103
+ }
104
+ #endif
105
+
106
+ #endif
@@ -0,0 +1,189 @@
1
+ //
2
+ // CodeBlockUtility.h
3
+ // snowcrash
4
+ //
5
+ // Created by Zdenek Nemec on 11/10/13.
6
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
7
+ //
8
+
9
+ #ifndef SNOWCRASH_CODEBLOCKUTILITY_H
10
+ #define SNOWCRASH_CODEBLOCKUTILITY_H
11
+
12
+ #include <sstream>
13
+ #include "BlockUtility.h"
14
+
15
+ namespace snowcrash {
16
+
17
+ /**
18
+ * Compute expected indentation level of a code block.
19
+ * \param section A section to compute indentation level for
20
+ * \return Indentation level (number of tabs) for a block to be
21
+ * considered a pre-formatted code block in given section.
22
+ */
23
+ FORCEINLINE size_t CodeBlockIndentationLevel(const BlueprintSection& section)
24
+ {
25
+ if (!section.hasParent() ||
26
+ section.parent().type == BlueprintSectionType ||
27
+ section.parent().type == ResourceGroupSectionType ||
28
+ section.parent().type == ResourceSectionType ||
29
+ section.parent().type == ResourceMethodSectionType ||
30
+ section.parent().type == ActionSectionType) {
31
+
32
+ return 1;
33
+ }
34
+ else if (section.parent().type == RequestBodySectionType ||
35
+ section.parent().type == ResponseBodySectionType ||
36
+ section.parent().type == ObjectBodySectionType ||
37
+ section.parent().type == ModelBodySectionType) {
38
+
39
+ return 2;
40
+ }
41
+ else {
42
+
43
+ return 3;
44
+ }
45
+ }
46
+
47
+ /**
48
+ * \brief Check code block for potential excessive indentation of a list item.
49
+ * \return True if code block does not contain potential recognized list, false otherwise.
50
+ */
51
+ template <class T>
52
+ FORCEINLINE bool CheckCodeBlockListItem(const BlueprintSection& section,
53
+ const BlockIterator& cur,
54
+ const SourceData& sourceData,
55
+ Result& result)
56
+ {
57
+
58
+ // Check for possible superfluous indentation of a recognized list items.
59
+ std::string line = GetFirstLine(cur->content);
60
+ TrimStringStart(line);
61
+
62
+ // If line appears to be a Markdown list construct a dummy list item
63
+ // with the first line of code block as its content.
64
+ // Check the list item with respective internal classifier.
65
+ if (line.empty() ||
66
+ (line[0] != '-' && line[0] != '+' && line[0] != '*'))
67
+ return true;
68
+
69
+ // Skip leading Markdown list item mark
70
+ std::string listItemContent = line.substr(1, std::string::npos);
71
+ TrimStringStart(listItemContent);
72
+ MarkdownBlock::Stack dummyList;
73
+
74
+ dummyList.push_back(MarkdownBlock(ListItemBlockBeginType, SourceData(), 0, SourceDataBlock()));
75
+ dummyList.push_back(MarkdownBlock(ListItemBlockEndType, listItemContent, 0, MakeSourceDataBlock(0, 0)));
76
+
77
+ SectionType type = ClassifyInternaListBlock<T>(dummyList.begin(), dummyList.end());
78
+ if (type != UndefinedSectionType) {
79
+
80
+ size_t level = CodeBlockIndentationLevel(section);
81
+ --level;
82
+
83
+ // WARN: Superfluous indentation
84
+ std::stringstream ss;
85
+ ss << "excessive indentation, ";
86
+ ss << SectionName(type) << " ";
87
+ if (level) {
88
+ ss << "section is expected to be indented by just ";
89
+ ss << level * 4 << " spaces or " << level << " tab";
90
+ if (level > 1)
91
+ ss << "s";
92
+ }
93
+ else {
94
+ ss << "section is not expected to be indented";
95
+ }
96
+
97
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(cur,
98
+ cur,
99
+ section.bounds,
100
+ sourceData);
101
+ result.warnings.push_back(Warning(ss.str(),
102
+ IndentationWarning,
103
+ sourceBlock));
104
+
105
+ return false;
106
+ }
107
+
108
+ return true;
109
+ }
110
+
111
+ /**
112
+ * \brief Parses given block as a preformatted code block.
113
+ * \param section Actual section being parsed.
114
+ * \param cur Cursor within the section boundaries.
115
+ * \param parser Parser instance.
116
+ * \param action An output data buffer.
117
+ * \param sourceMap An output source map buffer.
118
+ * \return A block parser section result, pointing at the last block parsed.
119
+ */
120
+ template <class T>
121
+ FORCEINLINE ParseSectionResult ParsePreformattedBlock(const BlueprintSection& section,
122
+ const BlockIterator& cur,
123
+ BlueprintParserCore& parser,
124
+ SourceData& data,
125
+ SourceDataBlock& sourceMap) {
126
+
127
+ ParseSectionResult result = std::make_pair(Result(), cur);
128
+ BlockIterator sectionCur = cur;
129
+ std::stringstream dataStream;
130
+
131
+ if (sectionCur->type == CodeBlockType) {
132
+ // Well formatted content, stream it up
133
+ dataStream << sectionCur->content;
134
+
135
+ // Check for excessive indentation
136
+ CheckCodeBlockListItem<T>(section, sectionCur, parser.sourceData, result.first);
137
+ }
138
+ else {
139
+ // Other blocks, process & warn
140
+ if (sectionCur->type == QuoteBlockBeginType) {
141
+ sectionCur = SkipToClosingBlock(sectionCur, section.bounds.second, QuoteBlockBeginType, QuoteBlockEndType);
142
+ }
143
+ else if (sectionCur->type == ListBlockBeginType) {
144
+ sectionCur = SkipToClosingBlock(sectionCur, section.bounds.second, ListBlockBeginType, ListBlockEndType);
145
+ }
146
+ else if (sectionCur->type == ListItemBlockBeginType) {
147
+ sectionCur = SkipToClosingBlock(sectionCur, section.bounds.second, ListItemBlockBeginType, ListItemBlockEndType);
148
+ }
149
+
150
+ if (!CheckCursor(section, sectionCur, parser.sourceData, result.first))
151
+ return result;
152
+ dataStream << MapSourceData(parser.sourceData, sectionCur->sourceMap);
153
+
154
+ // WARN: Not a preformatted code block
155
+ std::stringstream ss;
156
+
157
+ // Build the warning message
158
+ size_t level = CodeBlockIndentationLevel(section);
159
+ if (section.type == DanglingBodySectionType ||
160
+ section.type == DanglingSchemaSectionType) {
161
+
162
+ ss << "dangling " << SectionName(section.type) << " asset, ";
163
+ ss << "expected a pre-formatted code block, indent every of its line by ";
164
+ ss << level * 4 << " spaces or " << level << " tabs";
165
+ }
166
+ else {
167
+
168
+ ss << SectionName(section.type) << " asset ";
169
+ ss << "is expected to be a pre-formatted code block, every of its line indented by exactly ";
170
+ ss << level * 4 << " spaces or " << level << " tabs";
171
+ }
172
+
173
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(sectionCur, cur, section.bounds, parser.sourceData);
174
+ result.first.warnings.push_back(Warning(ss.str(),
175
+ IndentationWarning,
176
+ sourceBlock));
177
+ }
178
+
179
+ data = dataStream.str();
180
+ sourceMap = sectionCur->sourceMap;
181
+
182
+ if (sectionCur != section.bounds.second)
183
+ result.second = ++sectionCur;
184
+
185
+ return result;
186
+ }
187
+ }
188
+
189
+ #endif
@@ -0,0 +1,156 @@
1
+ //
2
+ // DescriptionSectionUtility.h
3
+ // snowcrash
4
+ //
5
+ // Created by Zdenek Nemec on 11/10/13.
6
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
7
+ //
8
+
9
+ #ifndef SNOWCRASH_DESCRIPTIONSECTIONUTILITY_H
10
+ #define SNOWCRASH_DESCRIPTIONSECTIONUTILITY_H
11
+
12
+ #include <sstream>
13
+ #include "MarkdownBlock.h"
14
+ #include "BlueprintParserCore.h"
15
+ #include "CodeBlockUtility.h"
16
+
17
+ namespace snowcrash {
18
+
19
+
20
+ /**
21
+ * \brief Skips to the end of the description list.
22
+ * \param begin Begin of the description list.
23
+ * \param end End of the block buffer.
24
+ * \param descriptionMap Output buffer containing skipped source map.
25
+ * \return An iterator pointing to the last block of a description list.
26
+ * Or, if one of description list items is recognized as a section, iterator
27
+ * pointing to this section.
28
+ *
29
+ * This functions checks any skipped list items for a section signature.
30
+ * If a section signature is found this function returns the first block
31
+ * of the recognized section. If no signature is found this function returns
32
+ * the last (closing) block of the description list.
33
+ */
34
+ template <class T>
35
+ static BlockIterator SkipToDescriptionListEnd(const BlockIterator& begin,
36
+ const BlockIterator& end,
37
+ SourceDataBlock& descriptionMap) {
38
+ BlockIterator cur(begin);
39
+ if (++cur == end) // Skip leading ListBlockBeginType
40
+ return cur;
41
+
42
+ std::vector<SourceDataBlock> listItemMaps;
43
+ SectionType listItemSection = UndefinedSectionType;
44
+ BlockIterator recognizedCur = end;
45
+
46
+ while (cur != end &&
47
+ cur->type == ListItemBlockBeginType) {
48
+
49
+ // Classify list item
50
+ listItemSection = ClassifyInternaListBlock<T>(cur, end);
51
+ if (listItemSection != UndefinedSectionType) {
52
+ // Found a recognized section, record & skip to the end of the list.
53
+ recognizedCur = cur;
54
+ cur = SkipToClosingBlock(begin, end, ListBlockBeginType, ListBlockEndType);
55
+ }
56
+ else {
57
+ // Skip one list item & take note of its source map
58
+ cur = SkipToClosingBlock(cur, end, ListItemBlockBeginType, ListItemBlockEndType);
59
+ listItemMaps.push_back(cur->sourceMap);
60
+
61
+ if (cur != end)
62
+ ++cur;
63
+ }
64
+ }
65
+
66
+ // Resolve
67
+ if (listItemSection == UndefinedSectionType) {
68
+ descriptionMap = cur->sourceMap;
69
+ return cur;
70
+ }
71
+ else {
72
+ // Resolve correct description source map
73
+ descriptionMap.clear();
74
+ if (!cur->sourceMap.empty() &&
75
+ !listItemMaps.empty() &&
76
+ !listItemMaps.front().empty()) {
77
+
78
+ SourceDataRange r;
79
+ r.location = cur->sourceMap.front().location;
80
+ r.length = listItemMaps.front().front().location - r.location;
81
+ descriptionMap.push_back(r);
82
+
83
+ for (std::vector<SourceDataBlock>::iterator it = listItemMaps.begin();
84
+ it != listItemMaps.end();
85
+ ++it) {
86
+
87
+ SourceDataRange gap;
88
+ gap.location = descriptionMap.back().location + descriptionMap.back().length;
89
+ gap.length = it->front().location - gap.location;
90
+ if (gap.length) {
91
+ SourceDataBlock gapBlock(1, gap);
92
+ AppendSourceDataBlock(descriptionMap, gapBlock);
93
+ }
94
+
95
+ AppendSourceDataBlock(descriptionMap, *it);
96
+ }
97
+ }
98
+
99
+ return recognizedCur;
100
+ }
101
+ }
102
+
103
+ /**
104
+ * \brief Process a description block retrieving its content.
105
+ * \param section A section its block is being processed.
106
+ * \param cur Cursor to the block to process.
107
+ * \param sourceData Source data stream.
108
+ * \param output Output object to APPEND retrieved description into.
109
+ * \return Standard parser section result poinitng at the last block parsed.
110
+ */
111
+ template <class T>
112
+ FORCEINLINE ParseSectionResult ParseDescriptionBlock(const BlueprintSection& section,
113
+ const BlockIterator& cur,
114
+ const SourceData& sourceData,
115
+ T& output) {
116
+
117
+ ParseSectionResult result = std::make_pair(Result(), cur);
118
+ BlockIterator sectionCur(cur);
119
+
120
+ if (sectionCur->type == QuoteBlockBeginType) {
121
+ sectionCur = SkipToClosingBlock(sectionCur, section.bounds.second, QuoteBlockBeginType, QuoteBlockEndType);
122
+ }
123
+ else if (sectionCur->type == ListBlockBeginType) {
124
+
125
+ SourceDataBlock descriptionMap;
126
+ sectionCur = SkipToDescriptionListEnd<T>(sectionCur, section.bounds.second, descriptionMap);
127
+
128
+ if (sectionCur->type != ListBlockEndType) {
129
+ // Found recognized lists in the list block
130
+ if (!descriptionMap.empty())
131
+ output.description += MapSourceData(sourceData, descriptionMap);
132
+
133
+ result.second = sectionCur;
134
+ return result;
135
+ }
136
+ }
137
+ else if (sectionCur->type == CodeBlockType) {
138
+ // Check code block for potential excessive indentation of a list item
139
+ CheckCodeBlockListItem<T>(section, sectionCur, sourceData, result.first);
140
+ }
141
+ else if (sectionCur->type == HeaderBlockType) {
142
+ // Check headers for potential keywords
143
+ CheckHeaderBlock<T>(section, sectionCur, sourceData, result.first);
144
+ }
145
+
146
+ if (!CheckCursor(section, sectionCur, sourceData, result.first))
147
+ return result;
148
+
149
+ output.description += MapSourceData(sourceData, sectionCur->sourceMap);
150
+ result.second = ++sectionCur;
151
+
152
+ return result;
153
+ }
154
+ }
155
+
156
+ #endif