docks_app 0.0.1

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.
Files changed (313) hide show
  1. data/.editorconfig +8 -0
  2. data/.gitignore +22 -0
  3. data/.rubocop.yml +20 -0
  4. data/.travis.yml +10 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +35 -0
  8. data/Rakefile +3 -0
  9. data/bin/docks +5 -0
  10. data/config/json/docks_config.json +71 -0
  11. data/config/ruby/docks_config.rb +127 -0
  12. data/config/yaml/docks_config.yml +70 -0
  13. data/docks.gemspec +38 -0
  14. data/lib/docks/build.rb +300 -0
  15. data/lib/docks/cache.rb +143 -0
  16. data/lib/docks/command_line.rb +65 -0
  17. data/lib/docks/configuration.rb +217 -0
  18. data/lib/docks/containers/base_container.rb +103 -0
  19. data/lib/docks/containers/class_container.rb +39 -0
  20. data/lib/docks/containers/component_container.rb +92 -0
  21. data/lib/docks/containers/demo_container.rb +105 -0
  22. data/lib/docks/containers/factory_container.rb +12 -0
  23. data/lib/docks/containers/function_container.rb +46 -0
  24. data/lib/docks/containers/mixin_container.rb +19 -0
  25. data/lib/docks/containers/pattern_container.rb +168 -0
  26. data/lib/docks/containers/pattern_library_container.rb +77 -0
  27. data/lib/docks/containers/state_container.rb +9 -0
  28. data/lib/docks/containers/symbol_container.rb +77 -0
  29. data/lib/docks/containers/variable_container.rb +47 -0
  30. data/lib/docks/containers/variant_container.rb +9 -0
  31. data/lib/docks/containers/variation_container.rb +38 -0
  32. data/lib/docks/containers.rb +25 -0
  33. data/lib/docks/descriptor.rb +60 -0
  34. data/lib/docks/errors.rb +5 -0
  35. data/lib/docks/group.rb +66 -0
  36. data/lib/docks/helpers/github_helper.rb +29 -0
  37. data/lib/docks/helpers/path_helper.rb +94 -0
  38. data/lib/docks/helpers/render_helper.rb +87 -0
  39. data/lib/docks/helpers.rb +19 -0
  40. data/lib/docks/languages/base_language.rb +17 -0
  41. data/lib/docks/languages/coffeescript_language.rb +30 -0
  42. data/lib/docks/languages/common_types/markup_language.rb +71 -0
  43. data/lib/docks/languages/css_language.rb +13 -0
  44. data/lib/docks/languages/erb_language.rb +21 -0
  45. data/lib/docks/languages/haml_language.rb +21 -0
  46. data/lib/docks/languages/html_language.rb +10 -0
  47. data/lib/docks/languages/javascript_language.rb +42 -0
  48. data/lib/docks/languages/json_language.rb +18 -0
  49. data/lib/docks/languages/less_language.rb +33 -0
  50. data/lib/docks/languages/markdown_language.rb +10 -0
  51. data/lib/docks/languages/sass_language.rb +36 -0
  52. data/lib/docks/languages/slim_language.rb +21 -0
  53. data/lib/docks/languages/stylus_language.rb +26 -0
  54. data/lib/docks/languages/yaml_language.rb +18 -0
  55. data/lib/docks/languages.rb +103 -0
  56. data/lib/docks/markdown.rb +18 -0
  57. data/lib/docks/messenger.rb +69 -0
  58. data/lib/docks/naming_conventions/base_naming_convention.rb +9 -0
  59. data/lib/docks/naming_conventions/bem_naming_convention.rb +45 -0
  60. data/lib/docks/naming_conventions/suit_naming_convention.rb +45 -0
  61. data/lib/docks/naming_conventions.rb +21 -0
  62. data/lib/docks/ostruct.rb +17 -0
  63. data/lib/docks/parser.rb +86 -0
  64. data/lib/docks/parsers/base_parser.rb +128 -0
  65. data/lib/docks/parsers/coffeescript_parser.rb +30 -0
  66. data/lib/docks/parsers/css_parser.rb +27 -0
  67. data/lib/docks/parsers/javascript_parser.rb +30 -0
  68. data/lib/docks/parsers/less_parser.rb +22 -0
  69. data/lib/docks/parsers/sass_parser.rb +31 -0
  70. data/lib/docks/parsers/stylus_parser.rb +28 -0
  71. data/lib/docks/process.rb +60 -0
  72. data/lib/docks/processors.rb +416 -0
  73. data/lib/docks/renderers/base_renderer.rb +64 -0
  74. data/lib/docks/renderers/common_features/capturable.rb +69 -0
  75. data/lib/docks/renderers/common_features/helperable.rb +23 -0
  76. data/lib/docks/renderers/erb_renderer.rb +68 -0
  77. data/lib/docks/renderers/haml_renderer.rb +37 -0
  78. data/lib/docks/renderers/slim_renderer.rb +33 -0
  79. data/lib/docks/symbol_sources/base_symbol_source.rb +12 -0
  80. data/lib/docks/symbol_sources/jquery_symbol_source.rb +17 -0
  81. data/lib/docks/symbol_sources/mdn_symbol_source.rb +35 -0
  82. data/lib/docks/symbol_sources/sass_symbol_source.rb +27 -0
  83. data/lib/docks/symbol_sources.rb +28 -0
  84. data/lib/docks/tags/access_tag.rb +27 -0
  85. data/lib/docks/tags/activate_with_tag.rb +17 -0
  86. data/lib/docks/tags/active_tag.rb +14 -0
  87. data/lib/docks/tags/alias_tag.rb +17 -0
  88. data/lib/docks/tags/author_tag.rb +19 -0
  89. data/lib/docks/tags/base_tag.rb +52 -0
  90. data/lib/docks/tags/beta_tag.rb +26 -0
  91. data/lib/docks/tags/class_tag.rb +16 -0
  92. data/lib/docks/tags/compatibility_tag.rb +19 -0
  93. data/lib/docks/tags/demo_type_tag.rb +14 -0
  94. data/lib/docks/tags/deprecated_tag.rb +26 -0
  95. data/lib/docks/tags/description_tag.rb +99 -0
  96. data/lib/docks/tags/example_tag.rb +20 -0
  97. data/lib/docks/tags/factory_tag.rb +16 -0
  98. data/lib/docks/tags/for_tag.rb +23 -0
  99. data/lib/docks/tags/group_tag.rb +10 -0
  100. data/lib/docks/tags/helper_tag.rb +13 -0
  101. data/lib/docks/tags/include_with_tag.rb +57 -0
  102. data/lib/docks/tags/javascript_action_tag.rb +10 -0
  103. data/lib/docks/tags/link_tag.rb +18 -0
  104. data/lib/docks/tags/markup_tag.rb +106 -0
  105. data/lib/docks/tags/member_tag.rb +37 -0
  106. data/lib/docks/tags/method_tag.rb +18 -0
  107. data/lib/docks/tags/name_tag.rb +10 -0
  108. data/lib/docks/tags/object_tag.rb +15 -0
  109. data/lib/docks/tags/param_tag.rb +94 -0
  110. data/lib/docks/tags/pattern_tag.rb +21 -0
  111. data/lib/docks/tags/preclude_tag.rb +17 -0
  112. data/lib/docks/tags/private_tag.rb +15 -0
  113. data/lib/docks/tags/property_tag.rb +18 -0
  114. data/lib/docks/tags/public_tag.rb +15 -0
  115. data/lib/docks/tags/require_tag.rb +47 -0
  116. data/lib/docks/tags/returns_tag.rb +31 -0
  117. data/lib/docks/tags/set_by_tag.rb +18 -0
  118. data/lib/docks/tags/signature_tag.rb +35 -0
  119. data/lib/docks/tags/since_tag.rb +26 -0
  120. data/lib/docks/tags/source_tag.rb +12 -0
  121. data/lib/docks/tags/state_tag.rb +21 -0
  122. data/lib/docks/tags/static_tag.rb +14 -0
  123. data/lib/docks/tags/subcomponent_tag.rb +68 -0
  124. data/lib/docks/tags/subtitle_tag.rb +11 -0
  125. data/lib/docks/tags/symbol_type_tag.rb +10 -0
  126. data/lib/docks/tags/throws_tag.rb +30 -0
  127. data/lib/docks/tags/title_tag.rb +10 -0
  128. data/lib/docks/tags/type_tag.rb +10 -0
  129. data/lib/docks/tags/value_tag.rb +10 -0
  130. data/lib/docks/tags/variant_tag.rb +21 -0
  131. data/lib/docks/tags/variation_tag.rb +136 -0
  132. data/lib/docks/tags.rb +103 -0
  133. data/lib/docks/templates.rb +122 -0
  134. data/lib/docks/themes.rb +19 -0
  135. data/lib/docks/types.rb +26 -0
  136. data/lib/docks/version.rb +3 -0
  137. data/lib/docks.rb +37 -0
  138. data/spec/fixtures/build/scripts/bar/bar_2.js +1 -0
  139. data/spec/fixtures/build/scripts/bar.js +1 -0
  140. data/spec/fixtures/build/styles/foo/foo-2.css +1 -0
  141. data/spec/fixtures/build/styles/foo.css +1 -0
  142. data/spec/fixtures/build/templates/baz/baz_2.erb +1 -0
  143. data/spec/fixtures/build/templates/baz.erb +1 -0
  144. data/spec/fixtures/grouper/components/button/button.coffee +0 -0
  145. data/spec/fixtures/grouper/components/button/button.haml +0 -0
  146. data/spec/fixtures/grouper/components/button/button.scss +0 -0
  147. data/spec/fixtures/grouper/components/checkbox/_checkbox.haml +0 -0
  148. data/spec/fixtures/grouper/components/checkbox/_checkbox.scss +0 -0
  149. data/spec/fixtures/grouper/components/checkbox/checkbox.coffee +0 -0
  150. data/spec/fixtures/grouper/components/form/form.coffee +0 -0
  151. data/spec/fixtures/grouper/components/form/form.m +0 -0
  152. data/spec/fixtures/grouper/components/form/form.scss +0 -0
  153. data/spec/fixtures/grouper/components/next-expanding-textarea/_next-expanding-textarea.scss +0 -0
  154. data/spec/fixtures/grouper/components/next-expanding-textarea/_next_expanding_textarea.coffee +0 -0
  155. data/spec/fixtures/grouper/components/next-expanding-textarea/next-expanding-textarea.haml +0 -0
  156. data/spec/fixtures/grouper/components/next-tab/next-tab.coffee +0 -0
  157. data/spec/fixtures/grouper/components/next-tab/next-tab.haml +0 -0
  158. data/spec/fixtures/grouper/components/next-tab/next-tab.scss +0 -0
  159. data/spec/fixtures/grouper/components/segmented control/segmented control.coffee +0 -0
  160. data/spec/fixtures/grouper/components/segmented control/segmented control.haml +0 -0
  161. data/spec/fixtures/grouper/components/segmented control/segmented control.min.html +0 -0
  162. data/spec/fixtures/grouper/components/segmented control/segmented control.scss +0 -0
  163. data/spec/fixtures/grouper/markup/list-view.haml +0 -0
  164. data/spec/fixtures/grouper/markup/resizable/resizable.haml +0 -0
  165. data/spec/fixtures/grouper/markup/toggle.haml +0 -0
  166. data/spec/fixtures/grouper/scripts/resizable/resizable.coffee +0 -0
  167. data/spec/fixtures/grouper/scripts/toggle.coffee +0 -0
  168. data/spec/fixtures/grouper/style/_list-view.scss +0 -0
  169. data/spec/fixtures/grouper/style/_toggle.scss +0 -0
  170. data/spec/fixtures/languages/stub.json +3 -0
  171. data/spec/fixtures/languages/stub.yml +2 -0
  172. data/spec/fixtures/parsers/coffeescript_parser_fixture_basic.coffee +20 -0
  173. data/spec/fixtures/parsers/coffeescript_parser_fixture_complex.coffee +80 -0
  174. data/spec/fixtures/parsers/css_parser_fixture_basic.css +44 -0
  175. data/spec/fixtures/parsers/css_parser_fixture_complex.css +120 -0
  176. data/spec/fixtures/parsers/javascript_parser_fixture_basic.js +27 -0
  177. data/spec/fixtures/parsers/javascript_parser_fixture_complex.js +85 -0
  178. data/spec/fixtures/parsers/sass_parser_fixture_basic.scss +39 -0
  179. data/spec/fixtures/parsers/sass_parser_fixture_complex.scss +149 -0
  180. data/spec/fixtures/parsers/stylus_parser_fixture_basic.styl +34 -0
  181. data/spec/fixtures/parsers/stylus_parser_fixture_complex.styl +113 -0
  182. data/spec/fixtures/processors/join_with_smart_line_breaks/code_blocks.txt +10 -0
  183. data/spec/fixtures/processors/join_with_smart_line_breaks/headings.txt +15 -0
  184. data/spec/fixtures/processors/join_with_smart_line_breaks/lists.txt +21 -0
  185. data/spec/fixtures/processors/join_with_smart_line_breaks/lists_with_nesting.txt +13 -0
  186. data/spec/fixtures/processors/join_with_smart_line_breaks/multiple_paragraphs.txt +11 -0
  187. data/spec/fixtures/renderers/helpers.rb +37 -0
  188. data/spec/fixtures/renderers/html_output.html +7 -0
  189. data/spec/fixtures/renderers/templates/layouts/application.html.erb +0 -0
  190. data/spec/fixtures/renderers/templates/layouts/more/subdirectory.html.erb +0 -0
  191. data/spec/fixtures/renderers/templates/partials/_leading_underscore.html.erb +1 -0
  192. data/spec/fixtures/renderers/templates/partials/more/_subdirectory.html.erb +1 -0
  193. data/spec/fixtures/renderers/templates/partials/partial.html.erb +0 -0
  194. data/spec/fixtures/renderers/templates/partials/template.html.erb +1 -0
  195. data/spec/fixtures/renderers/templates/template.html.erb +1 -0
  196. data/spec/fixtures/tags/description/button.md +24 -0
  197. data/spec/fixtures/tags/description/class.md +27 -0
  198. data/spec/fixtures/tags/description/component.md +23 -0
  199. data/spec/fixtures/tags/description/function.md +30 -0
  200. data/spec/lib/build_spec.rb +467 -0
  201. data/spec/lib/cache_spec.rb +175 -0
  202. data/spec/lib/command_line_spec.rb +77 -0
  203. data/spec/lib/configuration_spec.rb +180 -0
  204. data/spec/lib/containers/base_container_spec.rb +214 -0
  205. data/spec/lib/containers/class_container_spec.rb +209 -0
  206. data/spec/lib/containers/component_container_spec.rb +158 -0
  207. data/spec/lib/containers/demo_container_spec.rb +113 -0
  208. data/spec/lib/containers/function_container_spec.rb +116 -0
  209. data/spec/lib/containers/mixin_container_spec.rb +4 -0
  210. data/spec/lib/containers/pattern_container_spec.rb +291 -0
  211. data/spec/lib/containers/pattern_library_container_spec.rb +130 -0
  212. data/spec/lib/containers/symbol_container_spec.rb +216 -0
  213. data/spec/lib/containers/variable_container_spec.rb +116 -0
  214. data/spec/lib/containers/variation_container_spec.rb +52 -0
  215. data/spec/lib/containers_spec.rb +22 -0
  216. data/spec/lib/descriptor_spec.rb +73 -0
  217. data/spec/lib/group_spec.rb +151 -0
  218. data/spec/lib/helpers/path_helper_spec.rb +202 -0
  219. data/spec/lib/helpers/render_helper_spec.rb +159 -0
  220. data/spec/lib/helpers_spec.rb +35 -0
  221. data/spec/lib/languages/base_language_spec.rb +32 -0
  222. data/spec/lib/languages/coffeescript_language_spec.rb +52 -0
  223. data/spec/lib/languages/css_language_spec.rb +13 -0
  224. data/spec/lib/languages/erb_language_spec.rb +33 -0
  225. data/spec/lib/languages/haml_language_spec.rb +32 -0
  226. data/spec/lib/languages/javascript_language_spec.rb +54 -0
  227. data/spec/lib/languages/json_language_spec.rb +24 -0
  228. data/spec/lib/languages/less_language_spec.rb +39 -0
  229. data/spec/lib/languages/markup_language_spec.rb +95 -0
  230. data/spec/lib/languages/sass_language_spec.rb +53 -0
  231. data/spec/lib/languages/slim_language_spec.rb +32 -0
  232. data/spec/lib/languages/stylus_language_spec.rb +34 -0
  233. data/spec/lib/languages/yaml_language_spec.rb +24 -0
  234. data/spec/lib/languages_spec.rb +127 -0
  235. data/spec/lib/markdown_spec.rb +63 -0
  236. data/spec/lib/messenger_spec.rb +1 -0
  237. data/spec/lib/naming_conventions/bem_naming_convention_spec.rb +112 -0
  238. data/spec/lib/naming_conventions/suit_naming_convention_spec.rb +107 -0
  239. data/spec/lib/naming_conventions_spec.rb +28 -0
  240. data/spec/lib/ostruct_spec.rb +15 -0
  241. data/spec/lib/parser_spec.rb +93 -0
  242. data/spec/lib/parsers/base_parser_spec.rb +128 -0
  243. data/spec/lib/parsers/coffeescript_parser_spec.rb +184 -0
  244. data/spec/lib/parsers/css_parser_spec.rb +136 -0
  245. data/spec/lib/parsers/javascript_parser_spec.rb +216 -0
  246. data/spec/lib/parsers/less_parser_spec.rb +111 -0
  247. data/spec/lib/parsers/sass_parser_spec.rb +233 -0
  248. data/spec/lib/parsers/stylus_parser_spec.rb +212 -0
  249. data/spec/lib/process_spec.rb +96 -0
  250. data/spec/lib/processors_spec.rb +555 -0
  251. data/spec/lib/renderers/base_renderer_spec.rb +122 -0
  252. data/spec/lib/renderers/common_features/helperable_spec.rb +30 -0
  253. data/spec/lib/renderers/erb_renderer_spec.rb +119 -0
  254. data/spec/lib/renderers/haml_renderer_spec.rb +103 -0
  255. data/spec/lib/renderers/slim_renderer_spec.rb +103 -0
  256. data/spec/lib/symbol_sources/jquery_symbol_source_spec.rb +25 -0
  257. data/spec/lib/symbol_sources/mdn_symbol_source_spec.rb +40 -0
  258. data/spec/lib/symbol_sources/sass_symbol_source_spec.rb +39 -0
  259. data/spec/lib/symbol_sources_spec.rb +19 -0
  260. data/spec/lib/tags/access_tag_spec.rb +32 -0
  261. data/spec/lib/tags/activate_with_tag_spec.rb +31 -0
  262. data/spec/lib/tags/active_tag_spec.rb +24 -0
  263. data/spec/lib/tags/alias_tag_spec.rb +31 -0
  264. data/spec/lib/tags/author_tag_spec.rb +172 -0
  265. data/spec/lib/tags/base_tag_spec.rb +21 -0
  266. data/spec/lib/tags/beta_tag_spec.rb +52 -0
  267. data/spec/lib/tags/class_tag_spec.rb +29 -0
  268. data/spec/lib/tags/compatibility_tag_spec.rb +159 -0
  269. data/spec/lib/tags/demo_type_tag_spec.rb +24 -0
  270. data/spec/lib/tags/deprecated_tag_spec.rb +50 -0
  271. data/spec/lib/tags/description_tag_spec.rb +242 -0
  272. data/spec/lib/tags/example_tag_spec.rb +37 -0
  273. data/spec/lib/tags/factory_tag_spec.rb +29 -0
  274. data/spec/lib/tags/for_tag_spec.rb +45 -0
  275. data/spec/lib/tags/group_tag_spec.rb +20 -0
  276. data/spec/lib/tags/helper_tag_spec.rb +22 -0
  277. data/spec/lib/tags/include_with_tag_spec.rb +74 -0
  278. data/spec/lib/tags/javascript_action_tag_spec.rb +20 -0
  279. data/spec/lib/tags/link_tag_spec.rb +49 -0
  280. data/spec/lib/tags/markup_tag_spec.rb +255 -0
  281. data/spec/lib/tags/member_tag_spec.rb +167 -0
  282. data/spec/lib/tags/method_tag_spec.rb +27 -0
  283. data/spec/lib/tags/name_tag_spec.rb +20 -0
  284. data/spec/lib/tags/object_tag_spec.rb +24 -0
  285. data/spec/lib/tags/param_tag_spec.rb +261 -0
  286. data/spec/lib/tags/pattern_tag_spec.rb +49 -0
  287. data/spec/lib/tags/preclude_tag_spec.rb +31 -0
  288. data/spec/lib/tags/private_tag_spec.rb +31 -0
  289. data/spec/lib/tags/property_tag_spec.rb +27 -0
  290. data/spec/lib/tags/public_tag_spec.rb +29 -0
  291. data/spec/lib/tags/require_tag_spec.rb +133 -0
  292. data/spec/lib/tags/returns_tag_spec.rb +85 -0
  293. data/spec/lib/tags/set_by_tag_spec.rb +92 -0
  294. data/spec/lib/tags/signature_tag_spec.rb +125 -0
  295. data/spec/lib/tags/since_tag_spec.rb +48 -0
  296. data/spec/lib/tags/state_tag_spec.rb +199 -0
  297. data/spec/lib/tags/static_tag_spec.rb +27 -0
  298. data/spec/lib/tags/subcomponent_tag_spec.rb +78 -0
  299. data/spec/lib/tags/subtitle_tag_spec.rb +13 -0
  300. data/spec/lib/tags/symbol_type_tag_spec.rb +20 -0
  301. data/spec/lib/tags/throws_tag_spec.rb +49 -0
  302. data/spec/lib/tags/title_tag_spec.rb +20 -0
  303. data/spec/lib/tags/type_tag_spec.rb +20 -0
  304. data/spec/lib/tags/value_tag_spec.rb +20 -0
  305. data/spec/lib/tags/variant_tag_spec.rb +13 -0
  306. data/spec/lib/tags/variation_tag_spec.rb +154 -0
  307. data/spec/lib/tags_spec.rb +264 -0
  308. data/spec/lib/templates_spec.rb +185 -0
  309. data/spec/lib/themes_spec.rb +32 -0
  310. data/spec/spec_helper.rb +34 -0
  311. data/tasks/rspec.rake +7 -0
  312. data/tasks/rubocop.rake +8 -0
  313. metadata +740 -0
@@ -0,0 +1,28 @@
1
+ require_relative "base_parser.rb"
2
+
3
+ module Docks
4
+ module Parsers
5
+ class Stylus < Sass
6
+ def initialize
7
+ @comment_pattern = /(?:\/\/|\/\*!?|\*\/?)/
8
+ @first_non_code_line_pattern = /[=+\.#\w\[&@]/
9
+ setup_regexes
10
+ end
11
+
12
+ def symbol_details_from_first_line(first_code_line)
13
+ first_code_line.strip!
14
+
15
+ type = case first_code_line
16
+ when /^[^:\(]*\([^\)]*\)$/ then Docks::Types::Symbol::MIXIN
17
+ when /\=/ then Docks::Types::Symbol::VARIABLE
18
+ when /(\.|\-\-)?(?:is|js)\-/ then Docks::Types::Symbol::STATE
19
+ when /\-\-(?:[a-zA-Z][\-_]?)*/ then Docks::Types::Symbol::VARIANT
20
+ else Docks::Types::Symbol::COMPONENT
21
+ end
22
+
23
+ name = first_code_line.match(/^\s*&?[@\.#]?\s*([^\s\(\:]*)/).captures.first
24
+ { name: name, symbol_type: type }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,60 @@
1
+ module Docks
2
+ class Process
3
+ @@pattern_processors = { early: [], middle: [], late: [] }
4
+ @@pattern_library_processors = { early: [], middle: [], late: [] }
5
+
6
+ def self.process(item)
7
+ case item
8
+ when Containers::Symbol then item = process_symbol(item)
9
+ when Containers::Pattern then process_pattern(item)
10
+ when Containers::PatternLibrary then process_pattern_library(item)
11
+ end
12
+
13
+ item
14
+ end
15
+
16
+ def self.register_pattern_processor(hook = :middle, &block)
17
+ @@pattern_processors[hook] << block unless @@pattern_processors[hook].include?(block)
18
+ end
19
+
20
+ def self.register_pattern_library_processor(hook = :middle, &block)
21
+ @@pattern_library_processors[hook] << block unless @@pattern_library_processors[hook].include?(block)
22
+ end
23
+
24
+ private
25
+
26
+ def self.clean
27
+ @@pattern_processors = { early: [], middle: [], late: [] }
28
+ @@pattern_library_processors = { early: [], middle: [], late: [] }
29
+ end
30
+
31
+ def self.process_symbol(symbol)
32
+ # For when the initial symbol type was overwritten
33
+ if symbol.symbol_type != symbol.class.type
34
+ symbol = Containers.container_for(symbol.symbol_type).new(symbol.to_h)
35
+ end
36
+
37
+ # Allow tags to change the symbol's type
38
+ tags = symbol.tags
39
+ tags.each do |tag|
40
+ next unless tag.respond_to?(:process)
41
+ new_symbol = tag.process(symbol)
42
+ symbol = new_symbol if new_symbol.kind_of?(Containers::Symbol)
43
+ end
44
+
45
+ symbol
46
+ end
47
+
48
+ def self.process_pattern(pattern)
49
+ [:early, :middle, :late].each do |hook|
50
+ @@pattern_processors[hook].each { |processor| processor.call(pattern) }
51
+ end
52
+ end
53
+
54
+ def self.process_pattern_library(pattern_library)
55
+ [:early, :middle, :late].each do |hook|
56
+ @@pattern_library_processors[hook].each { |processor| processor.call(pattern_library) }
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,416 @@
1
+ module Docks
2
+ module Processors
3
+ extend self
4
+
5
+ # Public: Processes the passed content by splitting it on commas,
6
+ # spaces, and pipes (and removing associated whitespace).
7
+ #
8
+ # content - An Array or String representing the parsed result.
9
+ #
10
+ # Examples
11
+ #
12
+ # split_on_commas_spaces_and_pipes("String, Array | Object")
13
+ # # => ["String", "Array", "Object"]
14
+ #
15
+ # Returns an Array of the split results.
16
+
17
+ def split_on_commas_spaces_and_pipes(content)
18
+ split_on_characters(content, [",", "|", "\s"])
19
+ end
20
+
21
+ def split_on_top_level_parens_commas_and_pipes(content)
22
+ return content unless content.kind_of?(String)
23
+
24
+ indexes = []
25
+ depth = 0
26
+
27
+ split_on = /[\|,]/
28
+ content.chars.each_with_index do |char, index|
29
+ if char == "("
30
+ depth += 1
31
+ elsif char == ")"
32
+ new_depth = [0, depth - 1].max
33
+
34
+ if new_depth == 0 && depth != 0
35
+ indexes << index
36
+ end
37
+
38
+ depth = new_depth
39
+ elsif split_on =~ char && depth == 0
40
+ indexes << index
41
+ end
42
+ end
43
+
44
+
45
+ result = []
46
+ start_index = 0
47
+
48
+ start_strip = /^\s*[,\|]*\s*/
49
+ end_strip = /\s*[,\|]*\s*$/
50
+ indexes.each do |index|
51
+ if index > start_index
52
+ item = content[start_index..index].gsub(start_strip, "").gsub(end_strip, "")
53
+ result << item if item.length > 0
54
+ end
55
+
56
+ start_index = index + 1
57
+ end
58
+
59
+ if start_index < content.length
60
+ result << content[start_index..-1].gsub(start_strip, "").gsub(end_strip, "")
61
+ end
62
+
63
+ result
64
+ end
65
+
66
+ # Public: Processes the passed content by splitting it on type-delimitting
67
+ # symbols ({/} to declare the type, ,/|/\s to separate them).
68
+ #
69
+ # content - An Array or String representing the parsed result.
70
+ #
71
+ # Examples
72
+ #
73
+ # split_types("{String, Number |Object[]}")
74
+ # # => [
75
+ # OpenStruct.new(name: "String", array: false),
76
+ # OpenStruct.new(name: "Number", array: false),
77
+ # OpenStruct.new(name: "Object", array: true)
78
+ # ]
79
+ #
80
+ # Returns an Array of types.
81
+
82
+ def split_types(content)
83
+ split_on_commas_spaces_and_pipes(content.gsub(/[\{\}]/, "").strip).map do |type|
84
+ array, type = if /\[\]/ =~ type
85
+ [true, type.split("[").first]
86
+ else
87
+ [false, type]
88
+ end
89
+
90
+ type = "Anything" if type == "*"
91
+
92
+ OpenStruct.new(name: type, array: array)
93
+ end
94
+ end
95
+
96
+ # Public: Processes the passed content splitting it on type-delimitting
97
+ # symbols ({/} to declare the type, ,/|/\s to separate them).
98
+ #
99
+ # content - The String to break apart.
100
+ # split_on - The characters, passed as a single String or an Array of Strings,
101
+ # on which the content string should be split. Defaults to "\,\s".
102
+ #
103
+ # Examples
104
+ #
105
+ # split_on_characters("String, Array", "\s\,")
106
+ # # => ["String", "Array"]
107
+ #
108
+ # Returns an Array with the split pieces.
109
+
110
+ def split_on_characters(content, split_on="\,\s")
111
+ return content unless content.kind_of?(String)
112
+
113
+ split_on = split_on.join("") if split_on.kind_of?(Array)
114
+ return content unless split_on.kind_of?(String)
115
+
116
+ content.split(/[#{split_on}]/).select { |piece| piece.length > 0 }
117
+ end
118
+
119
+ # Public: Processes the passed String by converting it to a
120
+ # boolean where any string other than one matching /false/
121
+ # will be considered true.
122
+ #
123
+ # content - A String representing the parsed result.
124
+ #
125
+ # Examples
126
+ #
127
+ # stringy_boolean(" false ")
128
+ # # => false
129
+ #
130
+ # stringy_boolean("foo")
131
+ # # => true
132
+ #
133
+ # Returns a boolean version of the content.
134
+
135
+ def stringy_boolean(content)
136
+ return false if content.nil?
137
+ return content unless content.kind_of?(String)
138
+ !content.include?("false")
139
+ end
140
+
141
+ CODE_BLOCK_INDICATOR = "```"
142
+ LIST_ITEM_INDICATOR = /^(?:\*|\-|\d+\.)/
143
+ HEADING_INDICATOR = /^#+/
144
+ HEADING_UNDERLINE_INDICATOR = /^[=\-]+/
145
+
146
+ # Public: Processes the passed content by joining it with line breaks as required.
147
+ # to create markdown-parsable paragraphs and code blocks.
148
+ #
149
+ # content - An Array representing the parsed result.
150
+ # join - The string with which to join two different paragraphs together.
151
+ #
152
+ # Examples
153
+ #
154
+ # join_with_smart_line_breaks(["One paragraph that", "spans two lines.", "And another!"])
155
+ # # => "One paragraph that spans two lines.\n\nAnd another!"
156
+ #
157
+ # join_with_smart_line_breaks(["One paragraph", "```html", "<p>A code block</p>", "```", "another paragraph."])
158
+ # # => "One paragraph.\n\n```html\n<p>A code block</p>\n```\n\nanother paragraph"
159
+ #
160
+ # Returns the processed string.
161
+
162
+ def join_with_smart_line_breaks(content, join = "\n\n")
163
+ return content unless content.kind_of?(Array)
164
+
165
+ text = ""
166
+ in_code_block = false
167
+ in_list = false
168
+ at_start_of_paragraph = true
169
+
170
+ content.each_with_index do |line, index|
171
+ stripped_line = line.strip
172
+
173
+ if stripped_line.start_with?(CODE_BLOCK_INDICATOR)
174
+ # Either the start or end of a code block
175
+ if in_code_block
176
+ in_code_block = false
177
+ at_start_of_paragraph = true
178
+
179
+ text << "\n#{line}#{join}"
180
+ else
181
+ in_code_block = true
182
+ text << "#{join}#{line}"
183
+ end
184
+
185
+ elsif in_code_block || (in_list && stripped_line =~ LIST_ITEM_INDICATOR)
186
+ # Either:
187
+ # 1. In a code block — just keep appending lines, or
188
+ # 2. Last item was a list item and this item is directly below it,
189
+ # so just add that line below.
190
+ text << "\n#{line}"
191
+
192
+ elsif stripped_line.length == 0
193
+ # Empty line — new paragraph
194
+ at_start_of_paragraph = true
195
+
196
+ text << join
197
+
198
+ elsif stripped_line =~ LIST_ITEM_INDICATOR && at_start_of_paragraph
199
+ # Line that looks like a list item and we're ready for a new paragraph
200
+ in_list = true
201
+ at_start_of_paragraph = false
202
+
203
+ text << line
204
+
205
+ elsif stripped_line =~ HEADING_INDICATOR
206
+ # Starts and ends a "## Header"-style heading
207
+ at_start_of_paragraph = true
208
+ text << "\n#{line}\n"
209
+
210
+ elsif stripped_line =~ HEADING_UNDERLINE_INDICATOR
211
+ # Ends a "Header\n======"-style heading
212
+ at_start_of_paragraph = true
213
+ text << "#{line}#{join}"
214
+
215
+ elsif content[index + 1] && content[index + 1].strip =~ HEADING_UNDERLINE_INDICATOR
216
+ # Start of a "Header\n======"-style heading
217
+ text << "\n#{line}\n"
218
+
219
+ elsif at_start_of_paragraph
220
+ # New line at the start of a regular paragraph
221
+ at_start_of_paragraph = false
222
+ in_list = false
223
+
224
+ text << line
225
+
226
+ else
227
+ # Line that isn't at the start of a paragraph — pin it to the previous line.
228
+ text << " #{stripped_line}"
229
+ end
230
+ end
231
+
232
+ text.strip!
233
+ text.gsub!(/\n{3,}/, "\n\n")
234
+ text.length > 0 ? text : nil
235
+ end
236
+
237
+ # Public: parses a string with names and optional parentheticals into an
238
+ # array of hashes with the name as the `name_key` and the parsed
239
+ # parenthetical options using the optional `default_for_parenthetical`.
240
+ #
241
+ # content - The string with the name and optional parenthetical.
242
+ # name_key - An optional Symbol representing the key that should be
243
+ # used for the non-parenthetical portion. Defaults to :name.
244
+ # default_key - An optional Symbol to be used as the default key for an
245
+ # unpaired item in the parentheses.
246
+ #
247
+ # Examples
248
+ #
249
+ # name_and_parenthetical(':matches?', :setter)
250
+ # # => [{setter: ':matches?'}]
251
+ #
252
+ # name_and_parenthetical(':size (SIZE::LARGE)', :setter, :constant)
253
+ # # => [{setter: ':size', constant: 'SIZE::LARGE'}]
254
+ #
255
+ # name_and_parenthetical([':size (SIZE::LARGE)', ':checked?'], :setter, :constant)
256
+ # # => [{setter: ':size', constant: 'SIZE::LARGE'}, {setter: ':checked?'}]
257
+ #
258
+ # Returns the parsed hash.
259
+
260
+ def name_and_parenthetical(content, name_key=:name, default_for_parenthetical=nil)
261
+ result = {}
262
+ match = content.match(/\s*(?<name>[^\(]*)(?:\s*\((?<paren>[^\)]*)\))?/)
263
+ result[name_key] = match[:name].strip
264
+
265
+ if (parenthetical = match[:paren]).nil?
266
+ result
267
+ else
268
+ result.merge(parenthetical_options(parenthetical, default_for_parenthetical))
269
+ end
270
+ end
271
+
272
+ # Public:
273
+ #
274
+ # content - A String of the parenthetical.
275
+ # default - An optional Symbol representing the key that should be used if
276
+ # an un-paired value is provided.
277
+ #
278
+ # Examples
279
+ #
280
+ # parenthetical_options('Activate with : foo , active : false')
281
+ # # => {activate_with: 'foo', active: 'false'}
282
+ #
283
+ # parenthetical_options('select, active : false, javascript action: $(this).text(1 + 1)', :demo_type)
284
+ # # => {demo_type: 'select', active: 'false', javascript_action: '$(this).text(1 + 1)'}
285
+ #
286
+ # Returns the processed Hash.
287
+
288
+ def parenthetical_options(content, default=nil)
289
+ return content unless content.kind_of?(String)
290
+ result, default_only = {}, true
291
+ default = default.to_sym unless default.nil?
292
+ # Strip leading and trailing parentheses
293
+ content = content.strip.sub(/^\(/, '').sub(/\)$/, '')
294
+
295
+ # Get a leading, un-keyed value. This will be set to the default
296
+ # key (`default`), if it was passed
297
+ content.sub!(/\s*([^,]*),?\s*/) do |match|
298
+ if match.index(': ').nil?
299
+ result[default] = $1.strip unless default.nil?
300
+ ''
301
+ else
302
+ match
303
+ end
304
+ end
305
+
306
+ # Cycle over key value pairs and add to the return Hash
307
+ content.scan(/\s*(?<attribute>[^:]*):\s+(?<value>[^,]*),?\s*/).each do |match|
308
+ default_only = false
309
+ # Ensure that the key looks like a regular symbol
310
+ result[match[0].strip.downcase.gsub(/\s+/, '_').to_sym] = match[1].strip
311
+ end
312
+
313
+ result
314
+ end
315
+
316
+ # Public: Processes the passed content by yielding to the passed
317
+ # block in order to create a base hash, then adding any subsequent
318
+ # lines to the description (which can start on the first line — just
319
+ # set the description part as the returned hash's :description key.
320
+ # The description is then joined with smart line breaks.
321
+ #
322
+ # Yields the first line (item) of content.
323
+ #
324
+ # content - An Array of Strings representing the multiline description.
325
+ #
326
+ # Examples
327
+ #
328
+ # multiline_description(['bar', 'baz']) { |first_line| { foo: first_line } }
329
+ # # => { foo: 'bar', description: 'baz' }
330
+ #
331
+ # multiline_description(['bar', 'Baz']) { |first_line| { foo: first_line, description: 'Already started!' } }
332
+ # # => { foo: 'bar', description: "Already started!\n\nBaz" }
333
+ #
334
+ # Returns the processed Hash.
335
+
336
+ def multiline_description(content)
337
+
338
+ content = Array(content)
339
+ description = []
340
+ item = nil
341
+
342
+ content.each do |line|
343
+ if item.nil?
344
+ item = yield(line) if block_given?
345
+
346
+ if !item.kind_of?(Hash)
347
+ item = Hash.new
348
+ description << line
349
+ elsif !item[:description].nil?
350
+ description << item.delete(:description)
351
+ end
352
+ else
353
+ description << line
354
+ end
355
+ end
356
+
357
+ unless item.nil?
358
+ item[:description] = join_with_smart_line_breaks(description)
359
+ item
360
+ end
361
+ end
362
+
363
+ # Public: Processes the passed content by returning it if it's a valid
364
+ # demo type, and otherwise returning the default demo type.
365
+ #
366
+ # content - A string representing the desired demo type.
367
+ #
368
+ # Examples
369
+ #
370
+ # ensure_valid_demo_type(Docks::Types::Demo::SELECT)
371
+ # # => "select"
372
+ #
373
+ # ensure_valid_demo_type("foo")
374
+ # # => "none"
375
+ #
376
+ # Returns the processed string.
377
+
378
+ def ensure_valid_demo_type(content)
379
+ @demo_types ||= Docks::Types::Demo.constants.map { |const| Docks::Types::Demo.const_get(const) }
380
+ @demo_types.include?(content) ? content : Docks::Types::Demo::DEFAULT
381
+ end
382
+
383
+ # Public: Processes the passed content by splitting it on commas,
384
+ # spaces, and pipes (and removing associated whitespace).
385
+ #
386
+ # content - An Array or String representing the parsed result.
387
+ #
388
+ # Examples
389
+ #
390
+ # CodeBlockWithLanguage.process([ "html - The markup.",
391
+ # "<div class="foo">Bar</div>",
392
+ # "<div class="bar">Baz</div>" ])
393
+ # # => {language: "html", description: "The markup", code: "<div class=\"foo\">Bar</div>\n<div class=\"foo\">Bar</div>"}
394
+ #
395
+ # CodeBlockWithLanguage.process([ "<div class="foo">Bar</div>",
396
+ # "<div class="bar">Baz</div>" ])
397
+ # # => {code: "<div class=\"foo\">Bar</div>\n<div class=\"foo\">Bar</div>"}
398
+ #
399
+ # Returns a Hash containing the language, description, and code block.
400
+
401
+ def code_block_with_language_and_description(content)
402
+ result = {}
403
+ content = Array(content)
404
+ possible_line_details = content.first.strip.split(/\s*\-\s*/, 2)
405
+
406
+ if Docks::Languages.extensions.include?(possible_line_details.first)
407
+ result[:language] = possible_line_details.first
408
+ result[:description] = possible_line_details.last if possible_line_details.length > 1
409
+ content.shift
410
+ end
411
+
412
+ result[:code] = content.join("\n")
413
+ result
414
+ end
415
+ end
416
+ end
@@ -0,0 +1,64 @@
1
+ module Docks
2
+ module Renderers
3
+ class Base
4
+ def initialize; @cache = {} end
5
+
6
+ def render(template, locals = {})
7
+ raise NotImplementedError.new("You must provide a `render` method.")
8
+ end
9
+
10
+ def ivars=(ivars)
11
+ ivars.each do |ivar, value|
12
+ instance_variable_set("@#{ivar}".to_sym, value)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def normalize_content_and_locals(template, locals = {})
19
+ content = nil
20
+ layout = nil
21
+ must_be_partial = false
22
+
23
+ if template.kind_of?(Hash)
24
+ locals = template.fetch(:locals, {})
25
+ content = template.fetch(:inline, nil)
26
+ layout = template.fetch(:layout, nil) || nil # guard against false layouts
27
+
28
+ if template[:partial].nil?
29
+ template = template[:template]
30
+ else
31
+ template = template[:partial]
32
+ must_be_partial = true
33
+ end
34
+ else
35
+ layout = locals.delete(:layout)
36
+ layout = nil unless layout
37
+ locals = locals.delete(:locals) if locals.key?(:locals)
38
+ end
39
+
40
+ if content.nil?
41
+ options = {}
42
+ options[:must_be] = :partial if must_be_partial
43
+
44
+ found_template = Templates.search_for_template(template, options)
45
+ content = @cache[found_template] || File.read(found_template)
46
+ @cache[found_template] = content
47
+ end
48
+
49
+ if layout
50
+ found_layout = Templates.search_for_template(layout, must_be: :layout)
51
+ layout = @cache[found_layout] || File.read(found_layout)
52
+ @cache[found_layout] = layout
53
+ end
54
+
55
+ return content, layout, locals
56
+ end
57
+
58
+ def clean; @cache = {} end
59
+ end
60
+ end
61
+
62
+ def self.current_renderer; @current_renderer end
63
+ def self.current_renderer=(renderer); @current_renderer = renderer end
64
+ end
@@ -0,0 +1,69 @@
1
+ module Docks
2
+ module Renderers
3
+ module Common
4
+
5
+ # Public: adds the required methods for template languages that support
6
+ # capturing and reusing blocks of content in the template.
7
+
8
+ module Capturable
9
+ @content_blocks = Hash.new
10
+
11
+ # Public: captures a block. Inclusions of this Mixin must override
12
+ # this method.
13
+ #
14
+ # block - The block of content to capture.
15
+ #
16
+ # Returns a String of the captured content.
17
+
18
+ def capture(&block)
19
+ raise NotImplementedError.new("You must implement a `capture` method.")
20
+ end
21
+
22
+ # Concatenates the `content` to the output buffer.
23
+ #
24
+ # content - The content to append.
25
+ #
26
+ # Returns the String of content passed.
27
+
28
+ def concat(content)
29
+ content
30
+ end
31
+
32
+ # Provides a named block to be reused later or, if only a name is
33
+ # provided, retrieves the captured content.
34
+ #
35
+ # name - The name of the captured block
36
+ # block - The block of content to capture and store. If not provided,
37
+ # the method will instead retrieve and return a previously
38
+ # captured block named `name`, if one exists.
39
+ #
40
+ # Returns nothing (in the case of a block being provided) or the
41
+ # previously-captured block by the passed `name`.
42
+
43
+ def content_for(name, value = nil, &block)
44
+ @content_blocks ||= Hash.new
45
+
46
+ if block_given?
47
+ @content_blocks[name] = capture(&block)
48
+ nil
49
+ elsif !value.nil?
50
+ @content_blocks[name] = value
51
+ nil
52
+ else
53
+ @content_blocks[name]
54
+ end
55
+ end
56
+
57
+ # Checks whether a block named `name` has been captured.
58
+ #
59
+ # name - The block to check for.
60
+ #
61
+ # Returns a Boolean indicating whether the named block has been captured.
62
+
63
+ def content_for?(name)
64
+ !@content_blocks[name].nil?
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,23 @@
1
+ module Docks
2
+ module Renderers
3
+ module Common
4
+ module Helperable
5
+ def helpers(*helpers)
6
+ load_helpers = Module.new
7
+
8
+ helpers.each do |helper|
9
+ if helper.kind_of?(Module)
10
+ self.send(:extend, helper)
11
+ elsif File.exists?(helper)
12
+ load_helpers.module_eval(File.read(helper))
13
+ end
14
+ end
15
+
16
+ load_helpers.constants.each do |constant|
17
+ self.send(:extend, load_helpers.const_get(constant))
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end