markdown_record 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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,105 @@
1
+ <!--fragment { "author": "Bryant Morrill", "parent_id": "content/home", "name": "Model Basics" } -->
2
+ <!--model { "type": "markdown_record/demo/section", "id": 5, "name": "Model Basics" } -->
3
+
4
+ # MarkdownRecord Models
5
+
6
+ The `::MarkdownRecord::Base` model is the base class for all models used for interacting with the JSON content that is rendered by MarkdownRecord. It has the following attributes:
7
+
8
+ - `id`
9
+ - `type<String>`
10
+ - `subdirectory<String>`
11
+ - `filename<String>`
12
+
13
+ The `id` attribute doesn't have a type, but for `::MarkdownRecord::ContentFragment` models it will always be a string value equal to the relative path of the file the model represents. You can set it to any value for the models you define, but each model should have an id that is unique among models of the same type.
14
+
15
+ The `type` attribute is the fully qualified class name of the model in underscore form (i.e. `::MarkdownRecord::ContentFragment` would be `markdown_record/content_fragment`).
16
+
17
+ `subdirectory` and `filename` always match the relative path of the file the model was defined in, or in the case of content fragments, the file the model represents. These attributes are auto-populated during the rendering process.
18
+
19
+ ## Query Methods
20
+
21
+ `::MarkdownRecord::Base` provides several query methods to it's child classes. They are:
22
+
23
+ - `find`
24
+ - `all`
25
+ - `where`
26
+
27
+ These methods all work similarly to ActiveRecord by design. For example, if we use the models defined in the previously in this guide, then we could do this:
28
+
29
+ ```ruby
30
+ ::MarkdownRecord::Demo::DslCommand.find(4)
31
+ => #<MarkdownRecord::Demo::DslCommand description: "end_model tells MarkdownRecord to pop the top model of the stack. This command isn't necessary unless you are defining models in a way that requires you to assign attributes to a model that is no longer the top model on the stack.", filename: "content_dsl", id: 4, name: "end_model", subdirectory: "content/api_docs", type: "markdown_record/demo/dsl_command">
32
+
33
+ ```
34
+
35
+ *or*
36
+
37
+ ```ruby
38
+ ::MarkdownRecord::Demo::DslCommand.all
39
+ =>
40
+ [#<MarkdownRecord::Demo::DslCommand description: "...", name: "model", ...>,
41
+ #<MarkdownRecord::Demo::DslCommand description: "...", name: "attribute", ...>
42
+ ...
43
+ ]
44
+ ```
45
+
46
+ The `where` query method takes an optional hash of filters and returns a `MarkdownRecord::Association` object, which you can chain additional methods onto. The methods you can chain onto this object are:
47
+
48
+ - `where`: subsequent calls to this query method will merge the passed filters into the previously provided filter hash.
49
+ - `not`: this method takes a hash of filters that is negated, so it will only return models that don't pass filters.
50
+ - `fragmentize`: this method turns the association into a fragment association, meaning it will filter and return `MarkdownRecord::ContentFragment` models only.
51
+ - `to_fragments`: this method queries for MarkdownRecord models but returns their corresponding content fragments instead. This will often result in duplicates due to models being defined in the same file.
52
+ - `all`: this method simply returns an Array of models, filtered according to whatever filters have been provided to the association object.
53
+
54
+ `MarkdownRecord::Association` also supports the `to_a`, `each`, `map`, `count`, `any?`, `empty?`, `first`, `last`, `second`, `third` and `fourth` methods which get executed on the backing Array after loading the data with the most recent filters. For additional functionality, you may call `all` or `to_a` to work with the backing Array directly.
55
+
56
+ ## Filters
57
+
58
+ MarkdownRecord supports various types of filter values. Those types and what they mean are as follows:
59
+
60
+ - `Array`: the attribute value must be included in the array.
61
+ - `Hash`: the attribute value must be a Hash which the filter value (a Hash of nested filters) will be applied against.
62
+ - `nil`: the attribute value must be nil/null.
63
+ - `Regexp`: the attribute value must match the Regex expression.
64
+ - `:not_null`: the attribute value must not be nil/null.
65
+ - `:null`: the attribute value must be nil/null.
66
+ - Any other valid JSON type, in which case the attribute value must equal the filter value.
67
+
68
+ In addition, you can pass `:__and__` or `:__or__` as filter keys that point to arrays of filter hashes. In the former case, all filter hashes must pass, and in the later case, only one of the filter hashes must pass.
69
+
70
+ Finally, you can pass `:__not__` as a filter key as well, which should point to a filter hash where all the filters must not pass.
71
+
72
+ Examples:
73
+
74
+ ```ruby
75
+ # querying with a string value
76
+ MarkdownRecord::Demo::DslCommand.where(:name => "model").all
77
+ => [#<MarkdownRecord::Demo::DslCommand ...>]
78
+ ```
79
+
80
+ ```ruby
81
+ # querying for models that don't have "fragment" in the name.
82
+ MarkdownRecord::Demo::DslCommand.where(__not__: { :name => /fragment/}).map(&:name)
83
+ => ["model", "attribute", "end_attribute", "end_model", "use_layout"]
84
+ ```
85
+
86
+ ```ruby
87
+ MarkdownRecord::Demo::DslCommand.where(__or__: [{ :name => /fragment/}, {:name => :null}]).map(&:name)
88
+ => ["model", "fragment", "directory_fragment"]
89
+ ```
90
+
91
+ ```ruby
92
+ MarkdownRecord::ContentFragment.where(:meta => {:author => "Bryant Morrill"}).first
93
+ => #<MarkdownRecord::ContentFragment ...>
94
+ ```
95
+
96
+ ## Automatic Associations
97
+
98
+ `::MarkdownRecord::Base` provides several associations automatically to its child classes, which are all based on their relative relative location to each other. These associations are:
99
+
100
+ - `siblings`: all models generated from files in the same directory and at the same level as the current model.
101
+ - `class_siblings`: same as `siblings` but only models of the same type.
102
+ - `children`: all models generated from files in nested directories within the directory the current model is defined in.
103
+ - `fragment`: the `MarkdownRecord::ContentFragment` instance representing the file where the model was defined.
104
+
105
+ `siblings`, `class_siblings` and `children` are all methods that return a `MarkdownRecord::Association` object. The `fragment` method returns a `MarkdownRecord::ContentFragment` instance.
@@ -0,0 +1,78 @@
1
+ <!--fragment { "author": "Bryant Morrill", "parent_id": "content/home", "name": "Content Fragments" } -->
2
+ <!---model { "type": "markdown_record/demo/section", "id": 6, "name": "Content Fragments" } -->
3
+
4
+ # Content Fragments
5
+
6
+ This section describes how to use the `::MarkdownRecord::ContentFragment` model to easily interact with your written markdown content from your application code.
7
+
8
+ Each file and directory in the `content` directory that gets rendered as either HTML or JSON will have a content fragment JSON object created for it that represents that source file. These JSON objects get stored in the corresponding file with a `_fragments` suffix.
9
+
10
+ In your application code, you can interact with content fragment JSON objects via the `::MarkdownRecord::ContentFragment` model. This model is a child class of `::MarkdownRecord::Base` and adds the following attributes:
11
+
12
+ - `meta<Hash>`
13
+ - `concatenated<Boolean>`
14
+
15
+ The `meta` attribute contains a `Hash` populated with any data you that you defined using the `fragment` or `directory_fragment` content DSL methods.
16
+
17
+ `concatentated` will be auto-populated during rendering and will be true for fragments representing a directory, and false for those representing files.
18
+
19
+ ### Querying Content Fragments
20
+
21
+ You can query content fragments just like you query other MarkdownRecord models, but these queries will only return content fragments. Using filter values that are Hashes, however, will allow you to query and filter content fragments based on their `meta` attributes.
22
+
23
+ ## Associations
24
+
25
+ Content fragments also have a few extra associations, which are:
26
+
27
+ - `ancestors`: the content fragments above the current fragment in the content structure.
28
+ - `ancestors_from`: the content fragments above the current fragment in the content structure, starting with a content fragment or content fragment id that is passed in.
29
+ - `parent`: the content fragment directly above the current fragment in the content structure.
30
+
31
+ Each of the above associations use the file tree structure, meaning that they will only return content fragments representing directories.
32
+
33
+ The `parent` method, however, can have its behavior overridden by setting a `parent_id` field in the `meta` hash of the content fragment to the id of another content fragment using the Content DSL.
34
+
35
+ For example, the file that this text is written in is at `content/blog/content_frags.md`, meaning that the parent of the directory level content fragment with `id = "content/blog"` would normally be the directory level content fragment with `id = "content"`.
36
+
37
+ In code, this would look like:
38
+
39
+ ```ruby
40
+ MarkdownRecord::ContentFragment.find("content/content_frags").parent
41
+ => #<MarkdownRecord::ContentFragment concatenated: true, filename: "content", id: "content", meta: {"name"=>"Demo", ...}, subdirectory: "", type: "markdown_record/content_fragment">
42
+ ```
43
+
44
+ But one of the files in in `content/blog` uses the Content DSL to define meta data for the directory content fragment, like so:
45
+
46
+ ```html
47
+ <!---directory_fragment { "name": "Example: Blog", "parent_id": "content/home" } -->
48
+ ```
49
+
50
+ The `parent_id` in the `meta` hash overrides the default behavior, which changes what fragment is returned from `parent`:
51
+
52
+ ```ruby
53
+ MarkdownRecord::ContentFragment.find("content/content_frags").parent
54
+ => #<MarkdownRecord::ContentFragment concatenated: false, filename: "home", id: "content/home", meta: {"name"=>"Home", ...}, subdirectory: "content", type: "markdown_record/content_fragment">
55
+ ```
56
+
57
+ The ability to override the natural `parent` of a content fragment is useful for constructing a list or hierarchy of content that is not strictly based on file structure. The `parents_from` method is useful in doing this, as it builds a hierarchy but respect any `parent_id` of the content fragments it comes across instead of assuming the containing directory is the parent. This is useful for constructing breadcrumbs and navigation in your views.
58
+
59
+ Exampe:
60
+
61
+ ```ruby
62
+ MarkdownRecord::ContentFragment.find("content/sandbox/foo")
63
+ .parents_from("content/home")
64
+ .map(&:id)
65
+ => ["content/home", "content/sandbox"]
66
+ ```
67
+
68
+ ## Instance Methods
69
+
70
+ `MarkdownRecord::ContentFragment` has the following instance methods:
71
+
72
+ - `exists?`: returns `true`` or `false`` depending on whether a JSON or HTML file corresponding to the content fragment can be found. This should always return `true` unless something has gone wrong with the rendering process.
73
+ - `json_exists?`: returns `true` if a corresponding JSON files can be found.
74
+ - `html_exists?`: returns `true` if a corresponding HTML files can be found.
75
+ - `read_json`: reads the corresponding JSON file.
76
+ - `read_html`: reads the corresponding HTML file.
77
+ - `json_path`: returns the path to the corresponding JSON file.
78
+ - `html_path`: returns the path to the corresponding HTML file.
@@ -0,0 +1,88 @@
1
+ <!--fragment { "author": "Bryant Morrill", "parent_id": "content/home", "name": "ERB Syntax and View Helpers" } -->
2
+ <!---model { "type": "markdown_record/demo/section", "id": 7, "name": "ERB Syntax and View Helpers" } -->
3
+
4
+ # ERB Syntax and View Helpers
5
+
6
+ This section describes how to use ERB syntax and view helpers in your markdown files and ERB views in conjunction with MarkdownRecord models to make navigating across all your rendered content easy.
7
+
8
+ ## ERB Syntax
9
+
10
+ MarkdownRecord supports the use of ERB syntax in your markdown source files. It also provides the following local variables for use in your ERB code:
11
+
12
+ - `filename`: the name of the file being rendered.
13
+ - `subdirectory`: the subdirectory of the file being rendered.
14
+ - `frag_id`: the id of the fragment corresponding to the file being rendered.
15
+ - `fragment`: the content fragment model instance corresponding to the file being rendered.
16
+
17
+ ## Rails View Helpers
18
+
19
+ All the standard view helpers that come with Rails should be accessible within your markdown source files when rendered as ERB files, such as tag helpers and path helpers.
20
+
21
+ For example, the image below is rendered using the `image_tag` tag helper:
22
+
23
+ <%= image_tag("ruby-logo") %>
24
+
25
+ ## View Helpers
26
+
27
+ MarkdownRecord provides the following view helpers to use in your ERB views as well as in your markdown content source files:
28
+
29
+ - `link_to_markdown_record`: generates a link to the content fragment you pass in, or else the content fragment corresponding to the MarkdownRecord model you pass in.
30
+
31
+ For example, for a content fragment such as:
32
+
33
+ ```ruby
34
+ fragment
35
+ => #<MarkdownRecord::ContentFragment filename: "content", id: "content/erb_syntax_and_view_helpers", meta: {"name"=>"ERB Syntax and View Helpers", ...}, ...>
36
+ ```
37
+
38
+ When you pass it into the view helper like so:
39
+
40
+ ```html
41
+ <%%%= link_to_markdown_record(fragment)%>
42
+ ```
43
+
44
+ The result would be the following markup:
45
+
46
+ ```html
47
+ <a href="/mdr/content/erb_syntax_and_view_helpers">ERB Syntax and View Helpers</a>
48
+ ```
49
+
50
+ Notice how the text in the link is the name value found in the content fragment meta attribute. This is because MarkdownRecord checks to see if the model passed in responds to `name`, and `MarkdownRecord::ContentFragment` has a `name` method that returns the `name` field, if present, from its meta hash.
51
+
52
+ A fragment without a name will be rendered like this:
53
+
54
+ ```html
55
+ <a href="/mdr/content/erb_syntax_and_view_helpers">/mdr/content/blog/view_helpers</a>
56
+ ```
57
+
58
+ Unless you pass in a name explicitly:
59
+
60
+ ```html
61
+ <%%%= link_to_markdown_record(fragment, "Click Here!") %>
62
+ ```
63
+
64
+ Which will produce:
65
+
66
+ ```html
67
+ <a href="/mdr/content/erb_syntax_and_view_helpers">Click Here!</a>
68
+ ```
69
+
70
+ You may have noticed that this view helper works almost identically to the standard Rails `link_to` method, and in fact this helper simply wraps `link_to`. As such, it has the same API that accepts `html_options` and a `block` as well. The only difference is that you have to pass in a `MarkdownRecord` model as the first parameter.
71
+
72
+ - `link_to_markdown_record_html`: this view helper works identically to `link_to_markdown_record`, but adds the `html` prefix to the route so that it can only return HTML.
73
+ - `link_to_download_markdown_record_html`: same as `link_to_markdown_record_html` but downloads a file instead.
74
+ - `link_to_markdown_record_json`: this view helper works identically to `link_to_markdown_record`, but adds the `json` prefix to the route so that it can only return HTML.
75
+ - `link_to_download_markdown_record_html`: same as `link_to_markdown_record_json` but downloads a file instead.
76
+
77
+ ### Breadcrumbs
78
+
79
+ Using the view helpers in conjunction with content fragments, you can easily build navigation that automatically updates when you rerender your content. This guide uses this technique and you can find the following code in the `_global_layout.html.erb` layout:
80
+
81
+ ```html
82
+ <%%% fragment.parents_from("content/home").each_with_index do |frag, index| %>
83
+ <%%% unless index == 0%>
84
+ <span class="breadcrumb_divider">/</span>
85
+ <%%% end %>
86
+ <li><%%%= link_to_markdown_record(frag)%>
87
+ <%%% end %>
88
+ ```
@@ -0,0 +1,15 @@
1
+ <!--fragment { "author": "Bryant Morrill", "parent_id": "content/home", "name": "Layouts" } -->
2
+ <!---model { "type": "markdown_record/demo/section", "id": 8, "name": "Layouts" } -->
3
+
4
+ # Layouts
5
+
6
+ When MarkdownRecord renders markdown source files, it looks for three different ERB layouts that it can use as templates. These layouts are each passed the same local variables as a markdown file when rendered as ERB (as discussed in the previous section), as well as an `html` variable that is the rendered html produced from the markdown content.
7
+
8
+ The layouts that MarkdownRecord uses by default are added to your application at the time of install in the `markdown_record/layouts` directory. They are:
9
+
10
+ - `_file_layout.html.erb`: this is the layout used for individual files. Concatenated files will show this layout multiple times, each with a different file rendered in it. The red border of this guide is part of this layout.
11
+ - `_concatenated_layout.html.erb`: this is the layout used only for concatenated files. It will only be rendered once per file, but not for files that don't contain the concatenated contents of a directory. Some of the pages of this guide have a blue border, which is a style defined only in this layout.
12
+ - `_global_layout.html.erb`: this is the layout that is used for every rendered file, regardless of whether it is a concatenated file or not. This is the recommended layout to use for global styles, etc.
13
+
14
+ In addition to the above, there is also a `_custom_layout.html.erb` which is used for the contents of the <%= link_to_markdown_record(::MarkdownRecord::ContentFragment.find("content/sandbox"), "sandbox") %> part of this guide. This demonstrates how you can override the layout used for a specific file using the `user_layout` Content DSL command.
15
+
@@ -0,0 +1,12 @@
1
+ <style>
2
+ .concatenated{
3
+ border: 1px solid #a5d6ff;
4
+ padding: 10px;
5
+ }
6
+ </style>
7
+
8
+ <div class="concatenated">
9
+ <%= raw(html) %>
10
+ <%= raw("<!--#{subdirectory}/#{filename}-->") %>
11
+ <p class="rendered_at"><em>The above content was rendered from source files at: <%= link_to_markdown_record(fragment, fragment.id) %></em></p>
12
+ </div>
@@ -0,0 +1,14 @@
1
+ <style>
2
+ .custom_layout_file {
3
+ padding: 10px;
4
+ border: 1px solid pink;
5
+ margin-bottom: 10px;
6
+ }
7
+ </style>
8
+
9
+ <div class="custom_layout_file">
10
+ <h3>Rendered Using a Custom Layout</h3>
11
+ <%= raw(html) %>
12
+ <%= raw("<!--#{subdirectory}/#{filename}-->") %>
13
+ <p class="rendered_at"><em>The above content was rendered from source files at: <%= link_to_markdown_record(fragment, fragment.id) %></em></p>
14
+ </div>
@@ -0,0 +1,15 @@
1
+ <style>
2
+
3
+ .file {
4
+ padding: 10px;
5
+ border: 1px solid #cc4400;
6
+ margin-bottom: 10px;
7
+ }
8
+
9
+ </style>
10
+
11
+ <div class="file">
12
+ <%= raw(html) %>
13
+ <%= raw("<!--#{subdirectory}/#{filename}-->") %>
14
+ <p class="rendered_at"><em>The above content was rendered from source files at: <%= link_to_markdown_record(fragment, fragment.id) %></em></p>
15
+ </div>
@@ -0,0 +1,108 @@
1
+ <style>
2
+ body{
3
+ background-color: black;
4
+ padding: 10px;
5
+ }
6
+
7
+ code{
8
+ padding: 0.2em 0.4em;
9
+ margin: 0;
10
+ font-size: 85%;
11
+ white-space: break-spaces;
12
+ background-color: rgb(110 118 129 / 40%);
13
+ border-radius: 6px;
14
+ }
15
+
16
+ pre{
17
+ padding: 16px;
18
+ overflow: auto;
19
+ font-size: 85%;
20
+ line-height: 1.45;
21
+ color: #f2f2f2;
22
+ background-color: #161b22;
23
+ border-radius: 6px;
24
+ font-family: andale mono, monaco, monospace;
25
+ word-wrap: normal;
26
+ }
27
+
28
+ pre code{
29
+ color: inherit;
30
+ background-color: inherit;
31
+ font-family: inherit;
32
+ padding: 0px;
33
+ margin: 0;
34
+ font-size: inherit;
35
+ white-space: inherit;
36
+ background-color: inherit;
37
+ border-radius: 0px;
38
+ }
39
+
40
+ h1{
41
+ color: #6699ff;
42
+ }
43
+
44
+ h2{
45
+ color: #b3ccff;
46
+ }
47
+
48
+ h3{
49
+ color: #b3ccff;
50
+ }
51
+
52
+ h4{
53
+ color: #b3ccff;
54
+ }
55
+
56
+ a{
57
+ color: #33ffcc;
58
+ }
59
+
60
+ .container {
61
+ margin-bottom: 10px;
62
+ padding: 10px;
63
+ color: #f2f2f2;
64
+ background-color: #0d1117;
65
+ font-family: trebuchet ms;
66
+ font-size: 16px;
67
+ line-height: 1.5;
68
+ }
69
+
70
+ .rendered_at{
71
+ font-size: 12px;
72
+ }
73
+
74
+ .navigation ul{
75
+ padding: 0px;
76
+ }
77
+
78
+ .navigation li{
79
+ display: inline;
80
+ }
81
+ </style>
82
+
83
+ <div class="container">
84
+ <div class="navigation">
85
+ <ul>
86
+ <li>Breadcrumbs: </li>
87
+ <% fragment.parents_from("content/home").each_with_index do |frag, index| %>
88
+ <% unless index == 0%>
89
+ <span class="breadcrumb_divider">/</span>
90
+ <% end %>
91
+ <li><%= link_to_markdown_record(frag)%></li>
92
+ <% end %>
93
+ </ul>
94
+ </div>
95
+ <%= raw(html) %>
96
+ <%= raw("<!--#{subdirectory}/#{filename}-->") %>
97
+ <div class="navigation">
98
+ <ul>
99
+ <li>Breadcrumbs: </li>
100
+ <% fragment.parents_from("content/home").each_with_index do |frag, index| %>
101
+ <% unless index == 0%>
102
+ <span class="breadcrumb_divider">/</span>
103
+ <% end %>
104
+ <li><%= link_to_markdown_record(frag)%></li>
105
+ <% end %>
106
+ </ul>
107
+ </div>
108
+ </div>
@@ -0,0 +1,3 @@
1
+ ::MarkdownRecord.configure do |config|
2
+ # configure MarkdownRecord here
3
+ end
@@ -0,0 +1,57 @@
1
+ require "thor"
2
+
3
+ class RenderContent < Thor
4
+ include MarkdownRecord::Rendering
5
+
6
+ class_option :subdirectory, required: false, type: :string, aliases: :d, default: ""
7
+ class_option :save, type: :boolean, aliases: :s, default: false
8
+ class_option :strat, type: :string, aliases: :r
9
+ class_option :frag, type: :boolean, aliases: :f
10
+
11
+ desc "html", "renders html content"
12
+ def html
13
+ return unless validate
14
+ lines = []
15
+ strategy_options = generate_render_strategy_options(options)
16
+ report_start(lines, strategy_options, "html")
17
+
18
+ file_saver = ::MarkdownRecord::FileSaver.new
19
+ ::MarkdownRecord::HtmlRenderer.new(file_saver: file_saver)
20
+ .render_html_for_subdirectory(subdirectory: options[:subdirectory], **strategy_options)
21
+
22
+ report_rendered_files(lines, file_saver)
23
+ end
24
+
25
+ desc "json", "renders json content"
26
+ def json
27
+ return unless validate
28
+ lines = []
29
+ strategy_options = generate_render_strategy_options(options)
30
+ report_start(lines, strategy_options, "json")
31
+
32
+ file_saver = ::MarkdownRecord::FileSaver.new
33
+ ::MarkdownRecord::JsonRenderer.new(file_saver: file_saver)
34
+ .render_models_for_subdirectory(subdirectory: options[:subdirectory], **strategy_options)
35
+
36
+ report_rendered_files(lines, file_saver)
37
+ end
38
+
39
+ desc "all", "renders html and json content"
40
+ def all
41
+ return unless validate
42
+ lines = []
43
+ strategy_options = generate_render_strategy_options(options)
44
+ report_start(lines, strategy_options, "html and json")
45
+
46
+
47
+ file_saver = ::MarkdownRecord::FileSaver.new
48
+ ::MarkdownRecord::JsonRenderer.new(file_saver: file_saver)
49
+ .render_models_for_subdirectory(subdirectory: options[:subdirectory], **strategy_options)
50
+
51
+ ::MarkdownRecord::HtmlRenderer.new(file_saver: file_saver)
52
+ .render_html_for_subdirectory(subdirectory: options[:subdirectory], **strategy_options)
53
+
54
+
55
+ report_rendered_files(lines, file_saver)
56
+ end
57
+ end