markdown_record 0.1.3

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 (84) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +225 -0
  4. data/Rakefile +9 -0
  5. data/app/assets/config/markdown_cms_manifest.js +1 -0
  6. data/app/assets/stylesheets/markdown_cms/application.css +15 -0
  7. data/app/controllers/markdown_record/application_controller.rb +11 -0
  8. data/app/controllers/markdown_record/content_controller.rb +19 -0
  9. data/app/controllers/markdown_record/html_controller.rb +11 -0
  10. data/app/controllers/markdown_record/json_controller.rb +11 -0
  11. data/app/helpers/markdown_record/application_helper.rb +4 -0
  12. data/app/helpers/markdown_record/controller_helpers.rb +39 -0
  13. data/app/helpers/markdown_record/view_helpers.rb +84 -0
  14. data/app/models/markdown_record/demo/dsl_command.rb +10 -0
  15. data/app/models/markdown_record/demo/section.rb +9 -0
  16. data/app/models/markdown_record/tests/child_model.rb +15 -0
  17. data/app/models/markdown_record/tests/fake_active_record_model.rb +13 -0
  18. data/app/models/markdown_record/tests/model.rb +15 -0
  19. data/app/models/markdown_record/tests/other_child_model.rb +15 -0
  20. data/config/routes.rb +13 -0
  21. data/lib/generators/markdown_record_generator.rb +44 -0
  22. data/lib/markdown_record/association.rb +131 -0
  23. data/lib/markdown_record/associations.rb +106 -0
  24. data/lib/markdown_record/base.rb +25 -0
  25. data/lib/markdown_record/cli.rb +54 -0
  26. data/lib/markdown_record/configuration.rb +66 -0
  27. data/lib/markdown_record/content_associations.rb +46 -0
  28. data/lib/markdown_record/content_dsl/attribute.rb +22 -0
  29. data/lib/markdown_record/content_dsl/directory_fragment.rb +22 -0
  30. data/lib/markdown_record/content_dsl/disable.rb +22 -0
  31. data/lib/markdown_record/content_dsl/enable.rb +22 -0
  32. data/lib/markdown_record/content_dsl/end_attribute.rb +22 -0
  33. data/lib/markdown_record/content_dsl/end_model.rb +22 -0
  34. data/lib/markdown_record/content_dsl/fragment.rb +22 -0
  35. data/lib/markdown_record/content_dsl/model.rb +23 -0
  36. data/lib/markdown_record/content_dsl/render_format.rb +22 -0
  37. data/lib/markdown_record/content_dsl/render_strategy.rb +22 -0
  38. data/lib/markdown_record/content_dsl/use_layout.rb +22 -0
  39. data/lib/markdown_record/content_dsl.rb +37 -0
  40. data/lib/markdown_record/content_fragment.rb +123 -0
  41. data/lib/markdown_record/engine.rb +13 -0
  42. data/lib/markdown_record/errors/base.rb +6 -0
  43. data/lib/markdown_record/errors/duplicate_filename_error.rb +21 -0
  44. data/lib/markdown_record/errors/duplicate_id_error.rb +11 -0
  45. data/lib/markdown_record/errors/missing_parent_error.rb +11 -0
  46. data/lib/markdown_record/file_saver.rb +39 -0
  47. data/lib/markdown_record/html_renderer.rb +194 -0
  48. data/lib/markdown_record/indexer.rb +34 -0
  49. data/lib/markdown_record/json_renderer.rb +270 -0
  50. data/lib/markdown_record/model_inflator.rb +107 -0
  51. data/lib/markdown_record/path_utilities.rb +86 -0
  52. data/lib/markdown_record/rendering.rb +57 -0
  53. data/lib/markdown_record/routes_renderer.rb +0 -0
  54. data/lib/markdown_record/validator.rb +59 -0
  55. data/lib/markdown_record/version.rb +3 -0
  56. data/lib/markdown_record.rb +28 -0
  57. data/templates/Thorfile +3 -0
  58. data/templates/base/content/example_content.md +3 -0
  59. data/templates/base/layouts/_concatenated_layout.html.erb +8 -0
  60. data/templates/base/layouts/_custom_layout.html.erb +7 -0
  61. data/templates/base/layouts/_file_layout.html.erb +8 -0
  62. data/templates/base/layouts/_global_layout.html.erb +8 -0
  63. data/templates/demo/assets/images/ruby-logo.png +0 -0
  64. data/templates/demo/content/10_custom_models_and_associations.md.erb +78 -0
  65. data/templates/demo/content/11_controller_helpers.md.erb +20 -0
  66. data/templates/demo/content/12_configuration.md.erb +26 -0
  67. data/templates/demo/content/13_sandbox/1_foo.md +12 -0
  68. data/templates/demo/content/13_sandbox/2_sandbox_nested/1_bar.md +18 -0
  69. data/templates/demo/content/1_home.md.erb +40 -0
  70. data/templates/demo/content/2_installation.md.erb +129 -0
  71. data/templates/demo/content/3_rendering_basics.md.erb +71 -0
  72. data/templates/demo/content/4_content_dsl.md.erb +104 -0
  73. data/templates/demo/content/5_routes.md.erb +43 -0
  74. data/templates/demo/content/6_model_basics.md.erb +105 -0
  75. data/templates/demo/content/7_content_frags.md.erb +78 -0
  76. data/templates/demo/content/8_erb_syntax_and_view_helpers.md.erb +88 -0
  77. data/templates/demo/content/9_layouts.md.erb +15 -0
  78. data/templates/demo/layouts/_concatenated_layout.html.erb +12 -0
  79. data/templates/demo/layouts/_custom_layout.html.erb +14 -0
  80. data/templates/demo/layouts/_file_layout.html.erb +15 -0
  81. data/templates/demo/layouts/_global_layout.html.erb +108 -0
  82. data/templates/markdown_record_initializer.rb +3 -0
  83. data/templates/render_content.thor +57 -0
  84. metadata +270 -0
@@ -0,0 +1,131 @@
1
+ require "markdown_record/errors/duplicate_id_error"
2
+
3
+ module MarkdownRecord
4
+ class Association
5
+ attr_accessor :base_filters
6
+ attr_accessor :search_filters
7
+ attr_reader :fulfilled
8
+
9
+ def initialize(base_filters, search_filters = {})
10
+ @base_filters = base_filters
11
+ @include_fragments = false
12
+ @search_filters = search_filters
13
+ @data = []
14
+ @fulfilled = false
15
+ end
16
+
17
+ def execute
18
+ reset
19
+ final_filters = self.search_filters.merge(self.base_filters)
20
+ if @include_fragments
21
+ final_filters.merge!(:klass => ::MarkdownRecord::ContentFragment)
22
+ else
23
+ final_filters.merge!(:exclude_fragments => true)
24
+ end
25
+ results = MarkdownRecord::ModelInflator.new.where(final_filters)
26
+ @data.push(*results)
27
+ @fulfilled = true
28
+ end
29
+
30
+ def fragmentize
31
+ reset
32
+ @include_fragments = true
33
+ self
34
+ end
35
+
36
+ def to_fragments
37
+ execute unless fulfilled
38
+ return @data if @include_fragments
39
+
40
+ @data.map { |m| m.fragment }
41
+ end
42
+
43
+ def reset
44
+ @data = []
45
+ @fulfilled = false
46
+ end
47
+
48
+ def all
49
+ execute unless fulfilled
50
+ @data
51
+ end
52
+
53
+ def to_a
54
+ execute unless fulfilled
55
+ @data
56
+ end
57
+
58
+ def not(filters = {})
59
+ search_filters[:__not__] ||= {}
60
+ search_filters[:__not__].merge!(filters)
61
+ execute
62
+ self
63
+ end
64
+
65
+ def where(filters = {})
66
+ search_filters.merge!(filters)
67
+ execute
68
+ self
69
+ end
70
+
71
+ def each(...)
72
+ execute unless fulfilled
73
+ all unless fulfilled
74
+ @data.each(...)
75
+ end
76
+
77
+ def map(...)
78
+ execute unless fulfilled
79
+ execute
80
+ @data.map(...)
81
+ end
82
+
83
+ def count(...)
84
+ execute unless fulfilled
85
+ @data.count(...)
86
+ end
87
+
88
+ def any?(...)
89
+ execute unless fulfilled
90
+ @data.any?(...)
91
+ end
92
+
93
+ def empty?(...)
94
+ execute unless fulfilled
95
+ @data.empty?(...)
96
+ end
97
+
98
+ def first(...)
99
+ execute unless fulfilled
100
+ @data.first(...)
101
+ end
102
+
103
+ def last(...)
104
+ execute unless fulfilled
105
+ @data.first(...)
106
+ end
107
+
108
+ def second(...)
109
+ execute unless fulfilled
110
+ @data.second(...)
111
+ end
112
+
113
+ def third(...)
114
+ execute unless fulfilled
115
+ @data.third(...)
116
+ end
117
+
118
+ def fourth(...)
119
+ execute unless fulfilled
120
+ @data.fourth(...)
121
+ end
122
+
123
+ def __find__(id)
124
+ reset
125
+ search_filters.merge!({:id => id})
126
+ execute
127
+ raise ::MarkdownRecord::Errors::DuplicateIdError.new(@base_filters[:klass].name, id) if @data.count > 1
128
+ @data.first
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,106 @@
1
+ module MarkdownRecord
2
+ module Associations
3
+ extend ActiveSupport::Concern
4
+ include ::MarkdownRecord::PathUtilities
5
+
6
+ class_methods do
7
+ def has_many_content(association, **options)
8
+ klass = infer_klass(association, options)
9
+ raise ArgumentError.new("The association class name could not be inferred, and was not provided") if klass.nil?
10
+
11
+ foreign_key = "#{self.name.demodulize.underscore}_id".to_sym
12
+
13
+ define_method(association) do
14
+ klass.new_association({:klass => klass, foreign_key => self.id})
15
+ end
16
+ end
17
+
18
+ def has_one_content(association, **options)
19
+ klass = infer_klass(association, options)
20
+ raise ArgumentError.new("The association class name could not be inferred, and was not provided") if klass.nil?
21
+
22
+ foreign_key = "#{self.name.demodulize.underscore}_id".to_sym
23
+
24
+ define_method(association) do
25
+ results = klass.new_association({:klass => klass, foreign_key => self.id}).all
26
+ if results.count > 1
27
+ raise ArgumentError.new("Multiple MarkdownRecords belong to the same record in a has_one_content assocition: #{self.class.name} has a has_one_content #{association} and the following records ids were found #{ results.map(&:id) } ")
28
+ end
29
+
30
+ results.first
31
+ end
32
+ end
33
+
34
+ def belongs_to_content(association, **options)
35
+ klass = infer_klass(association, options)
36
+
37
+ raise ArgumentError.new("The association class name could not be inferred, and was not provided") if klass.nil?
38
+
39
+ foreign_key = "#{association}_id".to_sym
40
+ self.attribute foreign_key unless self.attributes[foreign_key].present?
41
+
42
+ define_method(association) do
43
+ klass.find(self[foreign_key])
44
+ end
45
+ end
46
+
47
+ def all
48
+ new_association({ :klass => self }).all
49
+ end
50
+
51
+ def where(filters = {})
52
+ new_association({ :klass => self }, filters)
53
+ end
54
+
55
+ def find(id)
56
+ new_association({ :klass => self }).__find__(id)
57
+ end
58
+
59
+ def infer_klass(association, options)
60
+ class_name = options[:class_name]
61
+ class_name ||= association.to_s.singularize.camelize
62
+
63
+ if self.name.include?("::") && !class_name.include?("::")
64
+ klass = "#{self.name.split('::')[0...-1].join("::")}::#{class_name}".safe_constantize
65
+ end
66
+
67
+ klass ||= class_name.camelize.safe_constantize
68
+ end
69
+ end
70
+
71
+ def siblings(filters = {})
72
+ self.class.new_association(filters.merge({:subdirectory => subdirectory}).merge!(not_self))
73
+ end
74
+
75
+ def class_siblings(filters = {})
76
+ self.class.new_association(filters.merge({:klass => self.class, :subdirectory => subdirectory, :__not__ => { :id => self.id }}))
77
+ end
78
+
79
+ def children(filters = {})
80
+ sub_start = "#{subdirectory}/".delete_prefix("/")
81
+ self.class.new_association(filters.merge({:subdirectory => Regexp.new("#{sub_start}[\\S|\\w]+")}).merge!(not_self))
82
+ end
83
+
84
+ def fragment
85
+ self.class.new_association.fragmentize.__find__(fragment_id)
86
+ end
87
+
88
+ private
89
+
90
+ def not_self
91
+ {
92
+ :__or__ => [
93
+ { :__not__ => {
94
+ :id => self.id
95
+ }
96
+ },
97
+ {
98
+ :__not__ => {
99
+ :type => self.type
100
+ }
101
+ }
102
+ ]
103
+ }
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,25 @@
1
+ require "active_attr"
2
+
3
+ module MarkdownRecord
4
+ class Base
5
+ include ::ActiveAttr::Model
6
+ include ::MarkdownRecord::Associations
7
+
8
+ attribute :id
9
+ attribute :type, :type => String
10
+ attribute :subdirectory, :type => String
11
+ attribute :filename, :type => String
12
+
13
+ def self.new_association(base_filters = {}, search_filters = {})
14
+ MarkdownRecord::Association.new(base_filters, search_filters)
15
+ end
16
+
17
+ def fragment_id
18
+ Pathname.new(subdirectory).join(filename).to_s
19
+ end
20
+
21
+ def self.json_klass
22
+ name.underscore
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,54 @@
1
+ require 'thor'
2
+
3
+ module MarkdownRecord
4
+
5
+ class Cli < Thor
6
+ include ::Thor::Actions
7
+
8
+ source_root File.expand_path("../../spec/dummy", __dir__)
9
+
10
+ desc "install", "installs rendered comparison files for specs"
11
+ def install
12
+ # Install the gem in the dummy app
13
+ system "cd spec/dummy && rails g markdown_record"
14
+
15
+ # Run render_content thor task to generate content and save it
16
+ system "cd spec/dummy && thor render_content:all -s"
17
+
18
+ # Copy the generated content to the spec folder for the specs to use
19
+ copy_file "markdown_record/rendered/content/part_1/chapter_1/content.html", "spec/rendered/chapter_1/content.html"
20
+ copy_file "markdown_record/rendered/content/part_1/chapter_1/content.json", "spec/rendered/chapter_1/content.json"
21
+ copy_file "markdown_record/rendered/content/part_1/chapter_1/content_fragments.json", "spec/rendered/chapter_1/content_fragments.json"
22
+
23
+ copy_file "markdown_record/rendered/content/part_1/chapter_2/content.html", "spec/rendered/chapter_2/content.html"
24
+ copy_file "markdown_record/rendered/content/part_1/chapter_2/content.json", "spec/rendered/chapter_2/content.json"
25
+ copy_file "markdown_record/rendered/content/part_1/chapter_2/content_fragments.json", "spec/rendered/chapter_2/content_fragments.json"
26
+
27
+ copy_file "markdown_record/rendered/content.html", "spec/rendered/concatenated/content.html"
28
+ copy_file "markdown_record/rendered/content.json", "spec/rendered/concatenated/content.json"
29
+ copy_file "markdown_record/rendered/content_fragments.json", "spec/rendered/concatenated/content_fragments.json"
30
+
31
+ # Run render content again with a custom layout
32
+ system "cd spec/dummy && thor render_content:all -s -l \"_custom_layout.html.erb\" -r full"
33
+
34
+ # Copy the new files to the spec directory
35
+ copy_file "markdown_record/rendered/content.html", "spec/rendered/custom_layout/content.html"
36
+ copy_file "markdown_record/rendered/content/part_1/chapter_1/content.html", "spec/rendered/custom_layout/chapter_1/content.html"
37
+
38
+ # Run render content again with a custom layout
39
+ system "cd spec/dummy && thor render_file:json -s -f part_1/chapter_1/content.md"
40
+ copy_file "markdown_record/rendered/content/part_1/chapter_1/content.json", "spec/rendered/chapter_1/no_frag_content.json"
41
+
42
+ # Remove generated content and installed files
43
+ FileUtils.remove_dir("spec/dummy/markdown_record/rendered", true)
44
+ FileUtils.remove_dir("spec/dummy/markdown_record/content", true)
45
+ FileUtils.remove_entry("spec/dummy/markdown_record/layouts/_concatenated_layout.html.erb", true)
46
+ FileUtils.remove_entry("spec/dummy/markdown_record/layouts/_file_layout.html.erb", true)
47
+ FileUtils.remove_entry("spec/dummy/lib/tasks/render_content.thor", true)
48
+ FileUtils.remove_entry("spec/dummy/lib/tasks/render_file.thor", true)
49
+ FileUtils.remove_entry("spec/dummy/config/initializers/markdown_record.rb", true)
50
+ FileUtils.remove_entry("spec/dummy/Thorfile", true)
51
+ gsub_file "spec/dummy/config/routes.rb", "\n mount MarkdownRecord::Engine, at: MarkdownRecord.config.mount_path, as: \"markdown_record\"", ""
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,66 @@
1
+ module MarkdownRecord
2
+ class Configuration
3
+ include Singleton
4
+
5
+ attr_accessor :content_root
6
+ attr_accessor :rendered_content_root
7
+ attr_accessor :layout_directory
8
+ attr_accessor :concatenated_layout_path
9
+ attr_accessor :file_layout_path
10
+ attr_accessor :global_layout_path
11
+ attr_accessor :markdown_extensions
12
+ attr_accessor :html_render_options
13
+ attr_accessor :public_layout
14
+ attr_accessor :render_strategy
15
+ attr_accessor :html_routes
16
+ attr_accessor :json_routes
17
+ attr_accessor :content_routes
18
+ attr_accessor :mount_path
19
+ attr_accessor :render_content_fragment_json
20
+ attr_accessor :render_controller
21
+ attr_accessor :ignore_numeric_prefix
22
+
23
+ RENDER_STRATEGIES = [:full, :directory, :file]
24
+
25
+ def initialize
26
+ @content_root = Rails.root.join("markdown_record","content")
27
+ @rendered_content_root = Rails.root.join("markdown_record","rendered")
28
+ @layout_directory = Rails.root.join("markdown_record","layouts")
29
+ @html_render_options = {}
30
+ @markdown_extensions = { :fenced_code_blocks => true, :disable_indented_code_blocks => true, :no_intra_emphasis => true}
31
+ @concatenated_layout_path = "_concatenated_layout.html.erb"
32
+ @file_layout_path = "_file_layout.html.erb"
33
+ @global_layout_path = "_global_layout.html.erb"
34
+ @public_layout = "layouts/application"
35
+ @render_strategy = :full
36
+ @html_routes = [:show]
37
+ @json_routes = [:show]
38
+ @content_routes = [:show]
39
+ @mount_path = "mdr"
40
+ @render_content_fragment_json = true
41
+ @render_controller = nil
42
+ @ignore_numeric_prefix = true
43
+ end
44
+
45
+ def render_strategy_options(strategy = nil)
46
+ strat = strategy || @render_strategy
47
+
48
+ unless RENDER_STRATEGIES.include?(strat)
49
+ raise ::ArgumentError.new("Invalide render strategy.")
50
+ end
51
+
52
+ case strategy || @render_strategy
53
+ when :full
54
+ {:concat => true, :deep => true}
55
+ when :directory
56
+ {:concat => true, :deep => false}
57
+ when :file
58
+ {:concat => false, :deep => true}
59
+ end
60
+ end
61
+
62
+ def routing
63
+ { :html => html_routes, :json => json_routes, :content => content_routes}
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,46 @@
1
+ module MarkdownRecord
2
+ module ContentAssociations
3
+ extend ActiveSupport::Concern
4
+
5
+ class_methods do
6
+ def has_many_content(association, **options)
7
+ klass = infer_klass(association, options)
8
+ raise ArgumentError.new("The association class name could not be inferred, and was not provided") if klass.nil?
9
+
10
+ foreign_key = "#{association.to_s.singularize}_ids"
11
+ raise ArgumentError.new("#{self} does not have the #{foreign_key} attribute required for this association.") unless self.attribute_names.include?(foreign_key)
12
+
13
+ define_method(association) do
14
+ klass.new_association({:klass => klass, :id => self[foreign_key.to_sym]})
15
+ end
16
+ end
17
+
18
+ def has_one_content(association, **options)
19
+ belongs_to_content(association, **options)
20
+ end
21
+
22
+ def belongs_to_content(association, **options)
23
+ klass = infer_klass(association, options)
24
+ raise ArgumentError.new("The association class name could not be inferred, and was not provided") if klass.nil?
25
+
26
+ foreign_key = "#{association.to_s.singularize}_id"
27
+ raise ArgumentError.new("#{self} does not have the #{foreign_key} attribute required for this association.") unless self.attribute_names.include?(foreign_key)
28
+
29
+ define_method(association) do
30
+ klass.find(self[foreign_key])
31
+ end
32
+ end
33
+
34
+ def infer_klass(association, options)
35
+ class_name = options[:class_name]
36
+ class_name ||= association.to_s.singularize.camelize
37
+
38
+ if self.name.include?("::") && !class_name.include?("::")
39
+ klass = "#{self.name.split('::')[0...-1].join("::")}::#{class_name}".safe_constantize
40
+ end
41
+
42
+ klass ||= class_name.camelize.safe_constantize
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module Attribute
4
+ REGEX = /(?<!`|`\\n|`html\\n)<!--\s*attribute\s*:\s*(\w+)\s*(?::((?:html|md|int|float|string)?))?-->(?!`|\\n`)/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*attribute\s*:\s*(\w+)\s*(?::((?:html|md|int|float|string)?))?--&gt;(?!<\/code>)/
6
+
7
+ def attribute_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ [match[1].strip, match[2]&.strip]
12
+ else
13
+ nil
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module DirectoryFragment
4
+ REGEX = /(?<!`|`\\n|`html\\n)<!--\s*directory_fragment\s*({[\s"'\\\w:,.\[\]\{\}_\/]*})\s*-->(?!`|\\n`)/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*directory_fragment\s*({[\s"'\\\w:,.\[\]\{\}_\/]*})\s*--&gt;(?!<\/code>)/
6
+
7
+ def directory_fragment_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ JSON.parse(match[1])
12
+ else
13
+ nil
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module Disable
4
+ REGEX = /<!--\s*disable\s*-->/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*disable\s*--&gt;(?!<\/code>)/
6
+
7
+ def disable_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ true
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module Enable
4
+ REGEX = /<!--\s*enable\s*-->/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*enable\s*--&gt;(?!<\/code>)/
6
+
7
+ def enable_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ true
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module EndAttribute
4
+ REGEX = /(?<!`|`\\n|`html\\n)<!--\s*end_attribute\s*-->(?!`|\\n`)/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*end_attribute\s*--&gt;(?!<\/code>)/
6
+
7
+ def end_attribute_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ true
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module EndModel
4
+ REGEX = /(?<!`|`\\n|`html\\n)<!--\s*end_model\s*-->(?!`|\\n`)/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*end_model\s*--&gt;(?!<\/code>)/
6
+
7
+ def end_model_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ true
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module Fragment
4
+ REGEX = /(?<!`|`\\n|`html\\n)<!--\s*fragment\s*({[\s"'\\\w:,.\[\]\{\}_\/]*})\s*-->(?!`|\\n`)/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*fragment\s+({[\s"'\\\w:,.\[\]\{\}_\/]*})\s*--&gt;(?!<\/code>)/
6
+
7
+ def fragment_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ JSON.parse(match[1])
12
+ else
13
+ nil
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module Model
4
+ TEMP = /<!--\s*model\s*({[\s"'\\\w:,.\[\]\{\}_\/]*})\s*-->/
5
+ REGEX = /(?<!`|`\\n|`html\\n)<!--\s*model\s*({[\s"'\\\w:,.\[\]\{\}_\/]*})\s*-->(?!`|\\n`)/
6
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*model\s*({[\s"'\\\w:,.\[\]\{\}_\/]*})\s*--&gt;(?!<\/code>)/
7
+
8
+ def model_dsl(text)
9
+ match = text.match(REGEX)
10
+
11
+ if match
12
+ JSON.parse(match[1])
13
+ else
14
+ nil
15
+ end
16
+ end
17
+
18
+ def self.remove_dsl(text)
19
+ text.gsub(ENCODED_REGEX, "")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module RenderFormat
4
+ REGEX = /(?<!`|`\\n|`html\\n)<!--\s*render_format\s*:\s*(.*)\s*-->(?!`|\\n`)/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*render_format\s*:\s*(.*)\s*--&gt;(?!<\/code>)/
6
+
7
+ def render_format_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ match[1].strip
12
+ else
13
+ nil
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module RenderStrategy
4
+ REGEX = /(?<!`|`\\n|`html\\n)<!--\s*render_strategy\s*:\s*(.*)\s*-->(?!`|\\n`)/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*render_strategy\s*:\s*(.*)\s*--&gt;(?!<\/code>)/
6
+
7
+ def render_strategy_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ match[1].strip
12
+ else
13
+ nil
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module MarkdownRecord
2
+ module ContentDsl
3
+ module UseLayout
4
+ REGEX = /(?<!`|`\\n|`html\\n)<!--\s*use_layout\s*:\s*(.*)\s*-->(?!`|\\n`)/
5
+ ENCODED_REGEX = /(?<!<code>|<code class="html">)&lt;!--\s*use_layout\s*:\s*(.*)\s*--&gt;(?!<\/code>)/
6
+
7
+ def use_layout_dsl(text)
8
+ match = text.match(REGEX)
9
+
10
+ if match
11
+ match[1].strip
12
+ else
13
+ nil
14
+ end
15
+ end
16
+
17
+ def self.remove_dsl(text)
18
+ text.gsub(ENCODED_REGEX, "")
19
+ end
20
+ end
21
+ end
22
+ end