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.
- data/.editorconfig +8 -0
- data/.gitignore +22 -0
- data/.rubocop.yml +20 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +35 -0
- data/Rakefile +3 -0
- data/bin/docks +5 -0
- data/config/json/docks_config.json +71 -0
- data/config/ruby/docks_config.rb +127 -0
- data/config/yaml/docks_config.yml +70 -0
- data/docks.gemspec +38 -0
- data/lib/docks/build.rb +300 -0
- data/lib/docks/cache.rb +143 -0
- data/lib/docks/command_line.rb +65 -0
- data/lib/docks/configuration.rb +217 -0
- data/lib/docks/containers/base_container.rb +103 -0
- data/lib/docks/containers/class_container.rb +39 -0
- data/lib/docks/containers/component_container.rb +92 -0
- data/lib/docks/containers/demo_container.rb +105 -0
- data/lib/docks/containers/factory_container.rb +12 -0
- data/lib/docks/containers/function_container.rb +46 -0
- data/lib/docks/containers/mixin_container.rb +19 -0
- data/lib/docks/containers/pattern_container.rb +168 -0
- data/lib/docks/containers/pattern_library_container.rb +77 -0
- data/lib/docks/containers/state_container.rb +9 -0
- data/lib/docks/containers/symbol_container.rb +77 -0
- data/lib/docks/containers/variable_container.rb +47 -0
- data/lib/docks/containers/variant_container.rb +9 -0
- data/lib/docks/containers/variation_container.rb +38 -0
- data/lib/docks/containers.rb +25 -0
- data/lib/docks/descriptor.rb +60 -0
- data/lib/docks/errors.rb +5 -0
- data/lib/docks/group.rb +66 -0
- data/lib/docks/helpers/github_helper.rb +29 -0
- data/lib/docks/helpers/path_helper.rb +94 -0
- data/lib/docks/helpers/render_helper.rb +87 -0
- data/lib/docks/helpers.rb +19 -0
- data/lib/docks/languages/base_language.rb +17 -0
- data/lib/docks/languages/coffeescript_language.rb +30 -0
- data/lib/docks/languages/common_types/markup_language.rb +71 -0
- data/lib/docks/languages/css_language.rb +13 -0
- data/lib/docks/languages/erb_language.rb +21 -0
- data/lib/docks/languages/haml_language.rb +21 -0
- data/lib/docks/languages/html_language.rb +10 -0
- data/lib/docks/languages/javascript_language.rb +42 -0
- data/lib/docks/languages/json_language.rb +18 -0
- data/lib/docks/languages/less_language.rb +33 -0
- data/lib/docks/languages/markdown_language.rb +10 -0
- data/lib/docks/languages/sass_language.rb +36 -0
- data/lib/docks/languages/slim_language.rb +21 -0
- data/lib/docks/languages/stylus_language.rb +26 -0
- data/lib/docks/languages/yaml_language.rb +18 -0
- data/lib/docks/languages.rb +103 -0
- data/lib/docks/markdown.rb +18 -0
- data/lib/docks/messenger.rb +69 -0
- data/lib/docks/naming_conventions/base_naming_convention.rb +9 -0
- data/lib/docks/naming_conventions/bem_naming_convention.rb +45 -0
- data/lib/docks/naming_conventions/suit_naming_convention.rb +45 -0
- data/lib/docks/naming_conventions.rb +21 -0
- data/lib/docks/ostruct.rb +17 -0
- data/lib/docks/parser.rb +86 -0
- data/lib/docks/parsers/base_parser.rb +128 -0
- data/lib/docks/parsers/coffeescript_parser.rb +30 -0
- data/lib/docks/parsers/css_parser.rb +27 -0
- data/lib/docks/parsers/javascript_parser.rb +30 -0
- data/lib/docks/parsers/less_parser.rb +22 -0
- data/lib/docks/parsers/sass_parser.rb +31 -0
- data/lib/docks/parsers/stylus_parser.rb +28 -0
- data/lib/docks/process.rb +60 -0
- data/lib/docks/processors.rb +416 -0
- data/lib/docks/renderers/base_renderer.rb +64 -0
- data/lib/docks/renderers/common_features/capturable.rb +69 -0
- data/lib/docks/renderers/common_features/helperable.rb +23 -0
- data/lib/docks/renderers/erb_renderer.rb +68 -0
- data/lib/docks/renderers/haml_renderer.rb +37 -0
- data/lib/docks/renderers/slim_renderer.rb +33 -0
- data/lib/docks/symbol_sources/base_symbol_source.rb +12 -0
- data/lib/docks/symbol_sources/jquery_symbol_source.rb +17 -0
- data/lib/docks/symbol_sources/mdn_symbol_source.rb +35 -0
- data/lib/docks/symbol_sources/sass_symbol_source.rb +27 -0
- data/lib/docks/symbol_sources.rb +28 -0
- data/lib/docks/tags/access_tag.rb +27 -0
- data/lib/docks/tags/activate_with_tag.rb +17 -0
- data/lib/docks/tags/active_tag.rb +14 -0
- data/lib/docks/tags/alias_tag.rb +17 -0
- data/lib/docks/tags/author_tag.rb +19 -0
- data/lib/docks/tags/base_tag.rb +52 -0
- data/lib/docks/tags/beta_tag.rb +26 -0
- data/lib/docks/tags/class_tag.rb +16 -0
- data/lib/docks/tags/compatibility_tag.rb +19 -0
- data/lib/docks/tags/demo_type_tag.rb +14 -0
- data/lib/docks/tags/deprecated_tag.rb +26 -0
- data/lib/docks/tags/description_tag.rb +99 -0
- data/lib/docks/tags/example_tag.rb +20 -0
- data/lib/docks/tags/factory_tag.rb +16 -0
- data/lib/docks/tags/for_tag.rb +23 -0
- data/lib/docks/tags/group_tag.rb +10 -0
- data/lib/docks/tags/helper_tag.rb +13 -0
- data/lib/docks/tags/include_with_tag.rb +57 -0
- data/lib/docks/tags/javascript_action_tag.rb +10 -0
- data/lib/docks/tags/link_tag.rb +18 -0
- data/lib/docks/tags/markup_tag.rb +106 -0
- data/lib/docks/tags/member_tag.rb +37 -0
- data/lib/docks/tags/method_tag.rb +18 -0
- data/lib/docks/tags/name_tag.rb +10 -0
- data/lib/docks/tags/object_tag.rb +15 -0
- data/lib/docks/tags/param_tag.rb +94 -0
- data/lib/docks/tags/pattern_tag.rb +21 -0
- data/lib/docks/tags/preclude_tag.rb +17 -0
- data/lib/docks/tags/private_tag.rb +15 -0
- data/lib/docks/tags/property_tag.rb +18 -0
- data/lib/docks/tags/public_tag.rb +15 -0
- data/lib/docks/tags/require_tag.rb +47 -0
- data/lib/docks/tags/returns_tag.rb +31 -0
- data/lib/docks/tags/set_by_tag.rb +18 -0
- data/lib/docks/tags/signature_tag.rb +35 -0
- data/lib/docks/tags/since_tag.rb +26 -0
- data/lib/docks/tags/source_tag.rb +12 -0
- data/lib/docks/tags/state_tag.rb +21 -0
- data/lib/docks/tags/static_tag.rb +14 -0
- data/lib/docks/tags/subcomponent_tag.rb +68 -0
- data/lib/docks/tags/subtitle_tag.rb +11 -0
- data/lib/docks/tags/symbol_type_tag.rb +10 -0
- data/lib/docks/tags/throws_tag.rb +30 -0
- data/lib/docks/tags/title_tag.rb +10 -0
- data/lib/docks/tags/type_tag.rb +10 -0
- data/lib/docks/tags/value_tag.rb +10 -0
- data/lib/docks/tags/variant_tag.rb +21 -0
- data/lib/docks/tags/variation_tag.rb +136 -0
- data/lib/docks/tags.rb +103 -0
- data/lib/docks/templates.rb +122 -0
- data/lib/docks/themes.rb +19 -0
- data/lib/docks/types.rb +26 -0
- data/lib/docks/version.rb +3 -0
- data/lib/docks.rb +37 -0
- data/spec/fixtures/build/scripts/bar/bar_2.js +1 -0
- data/spec/fixtures/build/scripts/bar.js +1 -0
- data/spec/fixtures/build/styles/foo/foo-2.css +1 -0
- data/spec/fixtures/build/styles/foo.css +1 -0
- data/spec/fixtures/build/templates/baz/baz_2.erb +1 -0
- data/spec/fixtures/build/templates/baz.erb +1 -0
- data/spec/fixtures/grouper/components/button/button.coffee +0 -0
- data/spec/fixtures/grouper/components/button/button.haml +0 -0
- data/spec/fixtures/grouper/components/button/button.scss +0 -0
- data/spec/fixtures/grouper/components/checkbox/_checkbox.haml +0 -0
- data/spec/fixtures/grouper/components/checkbox/_checkbox.scss +0 -0
- data/spec/fixtures/grouper/components/checkbox/checkbox.coffee +0 -0
- data/spec/fixtures/grouper/components/form/form.coffee +0 -0
- data/spec/fixtures/grouper/components/form/form.m +0 -0
- data/spec/fixtures/grouper/components/form/form.scss +0 -0
- data/spec/fixtures/grouper/components/next-expanding-textarea/_next-expanding-textarea.scss +0 -0
- data/spec/fixtures/grouper/components/next-expanding-textarea/_next_expanding_textarea.coffee +0 -0
- data/spec/fixtures/grouper/components/next-expanding-textarea/next-expanding-textarea.haml +0 -0
- data/spec/fixtures/grouper/components/next-tab/next-tab.coffee +0 -0
- data/spec/fixtures/grouper/components/next-tab/next-tab.haml +0 -0
- data/spec/fixtures/grouper/components/next-tab/next-tab.scss +0 -0
- data/spec/fixtures/grouper/components/segmented control/segmented control.coffee +0 -0
- data/spec/fixtures/grouper/components/segmented control/segmented control.haml +0 -0
- data/spec/fixtures/grouper/components/segmented control/segmented control.min.html +0 -0
- data/spec/fixtures/grouper/components/segmented control/segmented control.scss +0 -0
- data/spec/fixtures/grouper/markup/list-view.haml +0 -0
- data/spec/fixtures/grouper/markup/resizable/resizable.haml +0 -0
- data/spec/fixtures/grouper/markup/toggle.haml +0 -0
- data/spec/fixtures/grouper/scripts/resizable/resizable.coffee +0 -0
- data/spec/fixtures/grouper/scripts/toggle.coffee +0 -0
- data/spec/fixtures/grouper/style/_list-view.scss +0 -0
- data/spec/fixtures/grouper/style/_toggle.scss +0 -0
- data/spec/fixtures/languages/stub.json +3 -0
- data/spec/fixtures/languages/stub.yml +2 -0
- data/spec/fixtures/parsers/coffeescript_parser_fixture_basic.coffee +20 -0
- data/spec/fixtures/parsers/coffeescript_parser_fixture_complex.coffee +80 -0
- data/spec/fixtures/parsers/css_parser_fixture_basic.css +44 -0
- data/spec/fixtures/parsers/css_parser_fixture_complex.css +120 -0
- data/spec/fixtures/parsers/javascript_parser_fixture_basic.js +27 -0
- data/spec/fixtures/parsers/javascript_parser_fixture_complex.js +85 -0
- data/spec/fixtures/parsers/sass_parser_fixture_basic.scss +39 -0
- data/spec/fixtures/parsers/sass_parser_fixture_complex.scss +149 -0
- data/spec/fixtures/parsers/stylus_parser_fixture_basic.styl +34 -0
- data/spec/fixtures/parsers/stylus_parser_fixture_complex.styl +113 -0
- data/spec/fixtures/processors/join_with_smart_line_breaks/code_blocks.txt +10 -0
- data/spec/fixtures/processors/join_with_smart_line_breaks/headings.txt +15 -0
- data/spec/fixtures/processors/join_with_smart_line_breaks/lists.txt +21 -0
- data/spec/fixtures/processors/join_with_smart_line_breaks/lists_with_nesting.txt +13 -0
- data/spec/fixtures/processors/join_with_smart_line_breaks/multiple_paragraphs.txt +11 -0
- data/spec/fixtures/renderers/helpers.rb +37 -0
- data/spec/fixtures/renderers/html_output.html +7 -0
- data/spec/fixtures/renderers/templates/layouts/application.html.erb +0 -0
- data/spec/fixtures/renderers/templates/layouts/more/subdirectory.html.erb +0 -0
- data/spec/fixtures/renderers/templates/partials/_leading_underscore.html.erb +1 -0
- data/spec/fixtures/renderers/templates/partials/more/_subdirectory.html.erb +1 -0
- data/spec/fixtures/renderers/templates/partials/partial.html.erb +0 -0
- data/spec/fixtures/renderers/templates/partials/template.html.erb +1 -0
- data/spec/fixtures/renderers/templates/template.html.erb +1 -0
- data/spec/fixtures/tags/description/button.md +24 -0
- data/spec/fixtures/tags/description/class.md +27 -0
- data/spec/fixtures/tags/description/component.md +23 -0
- data/spec/fixtures/tags/description/function.md +30 -0
- data/spec/lib/build_spec.rb +467 -0
- data/spec/lib/cache_spec.rb +175 -0
- data/spec/lib/command_line_spec.rb +77 -0
- data/spec/lib/configuration_spec.rb +180 -0
- data/spec/lib/containers/base_container_spec.rb +214 -0
- data/spec/lib/containers/class_container_spec.rb +209 -0
- data/spec/lib/containers/component_container_spec.rb +158 -0
- data/spec/lib/containers/demo_container_spec.rb +113 -0
- data/spec/lib/containers/function_container_spec.rb +116 -0
- data/spec/lib/containers/mixin_container_spec.rb +4 -0
- data/spec/lib/containers/pattern_container_spec.rb +291 -0
- data/spec/lib/containers/pattern_library_container_spec.rb +130 -0
- data/spec/lib/containers/symbol_container_spec.rb +216 -0
- data/spec/lib/containers/variable_container_spec.rb +116 -0
- data/spec/lib/containers/variation_container_spec.rb +52 -0
- data/spec/lib/containers_spec.rb +22 -0
- data/spec/lib/descriptor_spec.rb +73 -0
- data/spec/lib/group_spec.rb +151 -0
- data/spec/lib/helpers/path_helper_spec.rb +202 -0
- data/spec/lib/helpers/render_helper_spec.rb +159 -0
- data/spec/lib/helpers_spec.rb +35 -0
- data/spec/lib/languages/base_language_spec.rb +32 -0
- data/spec/lib/languages/coffeescript_language_spec.rb +52 -0
- data/spec/lib/languages/css_language_spec.rb +13 -0
- data/spec/lib/languages/erb_language_spec.rb +33 -0
- data/spec/lib/languages/haml_language_spec.rb +32 -0
- data/spec/lib/languages/javascript_language_spec.rb +54 -0
- data/spec/lib/languages/json_language_spec.rb +24 -0
- data/spec/lib/languages/less_language_spec.rb +39 -0
- data/spec/lib/languages/markup_language_spec.rb +95 -0
- data/spec/lib/languages/sass_language_spec.rb +53 -0
- data/spec/lib/languages/slim_language_spec.rb +32 -0
- data/spec/lib/languages/stylus_language_spec.rb +34 -0
- data/spec/lib/languages/yaml_language_spec.rb +24 -0
- data/spec/lib/languages_spec.rb +127 -0
- data/spec/lib/markdown_spec.rb +63 -0
- data/spec/lib/messenger_spec.rb +1 -0
- data/spec/lib/naming_conventions/bem_naming_convention_spec.rb +112 -0
- data/spec/lib/naming_conventions/suit_naming_convention_spec.rb +107 -0
- data/spec/lib/naming_conventions_spec.rb +28 -0
- data/spec/lib/ostruct_spec.rb +15 -0
- data/spec/lib/parser_spec.rb +93 -0
- data/spec/lib/parsers/base_parser_spec.rb +128 -0
- data/spec/lib/parsers/coffeescript_parser_spec.rb +184 -0
- data/spec/lib/parsers/css_parser_spec.rb +136 -0
- data/spec/lib/parsers/javascript_parser_spec.rb +216 -0
- data/spec/lib/parsers/less_parser_spec.rb +111 -0
- data/spec/lib/parsers/sass_parser_spec.rb +233 -0
- data/spec/lib/parsers/stylus_parser_spec.rb +212 -0
- data/spec/lib/process_spec.rb +96 -0
- data/spec/lib/processors_spec.rb +555 -0
- data/spec/lib/renderers/base_renderer_spec.rb +122 -0
- data/spec/lib/renderers/common_features/helperable_spec.rb +30 -0
- data/spec/lib/renderers/erb_renderer_spec.rb +119 -0
- data/spec/lib/renderers/haml_renderer_spec.rb +103 -0
- data/spec/lib/renderers/slim_renderer_spec.rb +103 -0
- data/spec/lib/symbol_sources/jquery_symbol_source_spec.rb +25 -0
- data/spec/lib/symbol_sources/mdn_symbol_source_spec.rb +40 -0
- data/spec/lib/symbol_sources/sass_symbol_source_spec.rb +39 -0
- data/spec/lib/symbol_sources_spec.rb +19 -0
- data/spec/lib/tags/access_tag_spec.rb +32 -0
- data/spec/lib/tags/activate_with_tag_spec.rb +31 -0
- data/spec/lib/tags/active_tag_spec.rb +24 -0
- data/spec/lib/tags/alias_tag_spec.rb +31 -0
- data/spec/lib/tags/author_tag_spec.rb +172 -0
- data/spec/lib/tags/base_tag_spec.rb +21 -0
- data/spec/lib/tags/beta_tag_spec.rb +52 -0
- data/spec/lib/tags/class_tag_spec.rb +29 -0
- data/spec/lib/tags/compatibility_tag_spec.rb +159 -0
- data/spec/lib/tags/demo_type_tag_spec.rb +24 -0
- data/spec/lib/tags/deprecated_tag_spec.rb +50 -0
- data/spec/lib/tags/description_tag_spec.rb +242 -0
- data/spec/lib/tags/example_tag_spec.rb +37 -0
- data/spec/lib/tags/factory_tag_spec.rb +29 -0
- data/spec/lib/tags/for_tag_spec.rb +45 -0
- data/spec/lib/tags/group_tag_spec.rb +20 -0
- data/spec/lib/tags/helper_tag_spec.rb +22 -0
- data/spec/lib/tags/include_with_tag_spec.rb +74 -0
- data/spec/lib/tags/javascript_action_tag_spec.rb +20 -0
- data/spec/lib/tags/link_tag_spec.rb +49 -0
- data/spec/lib/tags/markup_tag_spec.rb +255 -0
- data/spec/lib/tags/member_tag_spec.rb +167 -0
- data/spec/lib/tags/method_tag_spec.rb +27 -0
- data/spec/lib/tags/name_tag_spec.rb +20 -0
- data/spec/lib/tags/object_tag_spec.rb +24 -0
- data/spec/lib/tags/param_tag_spec.rb +261 -0
- data/spec/lib/tags/pattern_tag_spec.rb +49 -0
- data/spec/lib/tags/preclude_tag_spec.rb +31 -0
- data/spec/lib/tags/private_tag_spec.rb +31 -0
- data/spec/lib/tags/property_tag_spec.rb +27 -0
- data/spec/lib/tags/public_tag_spec.rb +29 -0
- data/spec/lib/tags/require_tag_spec.rb +133 -0
- data/spec/lib/tags/returns_tag_spec.rb +85 -0
- data/spec/lib/tags/set_by_tag_spec.rb +92 -0
- data/spec/lib/tags/signature_tag_spec.rb +125 -0
- data/spec/lib/tags/since_tag_spec.rb +48 -0
- data/spec/lib/tags/state_tag_spec.rb +199 -0
- data/spec/lib/tags/static_tag_spec.rb +27 -0
- data/spec/lib/tags/subcomponent_tag_spec.rb +78 -0
- data/spec/lib/tags/subtitle_tag_spec.rb +13 -0
- data/spec/lib/tags/symbol_type_tag_spec.rb +20 -0
- data/spec/lib/tags/throws_tag_spec.rb +49 -0
- data/spec/lib/tags/title_tag_spec.rb +20 -0
- data/spec/lib/tags/type_tag_spec.rb +20 -0
- data/spec/lib/tags/value_tag_spec.rb +20 -0
- data/spec/lib/tags/variant_tag_spec.rb +13 -0
- data/spec/lib/tags/variation_tag_spec.rb +154 -0
- data/spec/lib/tags_spec.rb +264 -0
- data/spec/lib/templates_spec.rb +185 -0
- data/spec/lib/themes_spec.rb +32 -0
- data/spec/spec_helper.rb +34 -0
- data/tasks/rspec.rake +7 -0
- data/tasks/rubocop.rake +8 -0
- 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
|