markdown-rails 2.0.2 → 2.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b38453e5c369cffc57667a7b5fa7ae44f5ff1b3627f85c5968348f1f7b86604
4
- data.tar.gz: 8f890184a209ed11e929f0f65cdef966f3c7fcbabec8924ff06d195a567b6c3c
3
+ metadata.gz: 2cce6aedcf3e854a5907729d8ef780db22f9c69a20e92dd34603a4dcbfb6e699
4
+ data.tar.gz: 13374d49447c0d025e5d17a84f927c9027b7031c8a0c938ba3e64a44e179c66d
5
5
  SHA512:
6
- metadata.gz: e84a055e1b3ff490bbbb701983e664e0ff2496e8039e531020cee7290b1447665b9476a0eea510538dd71a5a13fd06a61f0e2dc3a3c312bdccd6e53aaa5a9c26
7
- data.tar.gz: 82f67fb1eed9c4358e7ad507b15fa2881daf0571e49615bb08d37c205e6be704a67751c0b28abb9c4151842751d16f3843317eb59c67c00828fa74173e49f530
6
+ metadata.gz: eaf381f89c5d0105ef005a3008e71fac4ae726c5bc137f02c8a4e6b291ca95f491a018ee008248ada11af0842f2ae0efefa3b561ed061c1ab2450dfc5b4b1cea
7
+ data.tar.gz: 7d2e28141e71907f81a0fed9efca8b673708c9031adfdd19b94ed59823f51cd350687018ed74091085ebb949a736fa40fc8e3edc9c9103461ac434653d712f82
data/README.md CHANGED
@@ -68,12 +68,10 @@ end
68
68
 
69
69
  Only enable Erb in Markdown if you trust the source of the file. Do not enable it for markdown provided by users or they will be able to execute arbitrary Ruby code.
70
70
 
71
- To enable Erb, you can tell Rails to render all view files ending with `.markerb` using the `MarkdownRails::Handler::Erb` handler.
72
-
73
71
  ```ruby
74
72
  # ./config/initializers/markdown.rb
75
- MarkdownRails.handle :markerb, with: MarkdownRails::Handler::Erb do
76
- ApplicationMarkdown.new
73
+ MarkdownRails.handle :markerb do
74
+ ErbMarkdown.new
77
75
  end
78
76
  ```
79
77
 
@@ -88,11 +86,13 @@ MarkdownRails.handle :md do
88
86
  ApplicationMarkdown.new
89
87
  end
90
88
 
91
- MarkdownRails.handle :markerb, with: MarkdownRails::Handler::Erb do
92
- ApplicationMarkdown.new
89
+ MarkdownRails.handle :markerb do
90
+ ErbMarkdown.new
93
91
  end
94
92
  ```
95
93
 
94
+ The same technique can be used for preprocessing Markdown with other handlers, like liquid.
95
+
96
96
  ## Customizing renderer
97
97
 
98
98
  You might want to customize your Markdown handler to do things like syntax code highlighting, etc.
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
1
  require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
2
4
 
3
- load "rails/tasks/statistics.rake"
5
+ RSpec::Core::RakeTask.new(:spec)
4
6
 
5
- require "bundler/gem_tasks"
7
+ task default: :spec
@@ -6,20 +6,21 @@ class ApplicationMarkdown < MarkdownRails::Renderer::Rails
6
6
  # and feel smarter. Read the docs at https://github.com/vmg/redcarpet#also-now-our-pants-are-much-smarter
7
7
  include Redcarpet::Render::SmartyPants
8
8
 
9
- # Uncomment and run `bundle add rouge` for syntax highlighting
9
+ # Run `bundle add rouge` and uncomment the include below for syntax highlighting
10
10
  # include MarkdownRails::Helper::Rouge
11
11
 
12
- # If you need access to ActionController::Base.helpers, you can delegate by uncommenting
13
- # and adding to the list below. Several are already included for you in the `MarkdownRails::Renderer::Rails`,
14
- # but you can add more here.
12
+ # The renderer has access to the view_context, which provides access to:
13
+ # - View helpers (image_tag, link_to, content_tag, etc.)
14
+ # - Asset helpers (image_path, image_url, asset_path, etc.)
15
+ # - URL helpers (root_path, user_path, etc.)
15
16
  #
16
- # To see a list of methods available run `bin/rails runner "puts ActionController::Base.helpers.public_methods.sort"`
17
+ # Many common helpers are already delegated. You can add more by uncommenting
18
+ # and extending the delegate list in your subclass:
17
19
  #
18
20
  # delegate \
19
- # :request,
20
- # :cache,
21
- # :turbo_frame_tag,
22
- # to: :helpers
21
+ # :current_user,
22
+ # :some_custom_helper,
23
+ # to: :view_context
23
24
 
24
25
  # These flags control features in the Redcarpet renderer, which you can read
25
26
  # about at https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
@@ -28,16 +29,6 @@ class ApplicationMarkdown < MarkdownRails::Renderer::Rails
28
29
  [:fenced_code_blocks]
29
30
  end
30
31
 
31
- # These methods are called as the Markdown document is parsed. Block-level calls are
32
- # documented at https://github.com/vmg/redcarpet#block-level-calls and span level calls
33
- # are documented at https://github.com/vmg/redcarpet#block-level-calls so feel free to
34
- # add more as you see fit.
35
- def block_code(code, language)
36
- content_tag :pre, class: language do
37
- code # You could implement syntax highlighting here with Rouge.
38
- end
39
- end
40
-
41
32
  # Example of how you might override the images to show embeds, like a YouTube video.
42
33
  def image(link, title, alt)
43
34
  url = URI(link)
@@ -0,0 +1,11 @@
1
+ # DANGER! This parses Erb, which means arbitrary Ruby can be run. Make sure
2
+ # you trust the source of your markdown and that its not user input.
3
+
4
+ class ErbMarkdown < ApplicationMarkdown
5
+ # Enables Erb to render for the entire doc before the markdown is rendered.
6
+ # This works great, except when you have an `erb` code fence.
7
+ def preprocess(html)
8
+ # Read more about this render call at https://guides.rubyonrails.org/layouts_and_rendering.html
9
+ render inline: html, handler: :erb
10
+ end
11
+ end
@@ -8,6 +8,6 @@ end
8
8
  # Don't use Erb for untrusted markdown content created by users; otherwise they
9
9
  # can execute arbitrary code on your server. This should only be used for input you
10
10
  # trust, like content files from your code repo.
11
- MarkdownRails.handle :markerb, with: MarkdownRails::Handler::Erb do
12
- ApplicationMarkdown.new
13
- end
11
+ MarkdownRails.handle :markerb do
12
+ ErbMarkdown.new
13
+ end
@@ -4,7 +4,7 @@ module MarkdownRails
4
4
  # config/initializer files are processed. This makes the `:md`
5
5
  # extension work if the user forgot to install the initializers.
6
6
  config.before_initialize do
7
- MarkdownRails::Handler::Markdown.register_default_handler
7
+ MarkdownRails::Handler.register_default
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,47 @@
1
+ module MarkdownRails
2
+ # We cannot use MarkdownRails because it conflicts with RDiscount's Markdown class
3
+ class Handler
4
+ DEFAULT_EXTENSION = :md
5
+ @@handlers = {}
6
+
7
+ def initialize(extension, &block)
8
+ @extension = extension
9
+ @markdown = block
10
+ @@handlers[@extension] = self
11
+ end
12
+
13
+ def call(template, source = template.source)
14
+ # Generate code that fetches the handler and calls the block at render time
15
+ extension = @extension
16
+ <<~RUBY
17
+ begin
18
+ handler = MarkdownRails::Handler.handler_for(#{extension.inspect})
19
+ renderer = handler.create_renderer
20
+ renderer.view_context = self
21
+ renderer.renderer.render(#{source.inspect}).html_safe
22
+ end
23
+ RUBY
24
+ end
25
+
26
+ def create_renderer
27
+ @markdown.call
28
+ end
29
+
30
+ def self.handler_for(extension)
31
+ @@handlers[extension]
32
+ end
33
+
34
+ def self.handle(*extensions, &block)
35
+ Array(extensions).each do |extension|
36
+ handler = new(extension, &block)
37
+ ActionView::Template.register_template_handler extension, handler
38
+ end
39
+ end
40
+
41
+ # Registers a default `.md` handler for Rails templates. This might be
42
+ # replaced by a handler in the `config/initializers/markdown.rb` file.
43
+ def self.register_default
44
+ handle(DEFAULT_EXTENSION) { MarkdownRails::Renderer::Rails.new }
45
+ end
46
+ end
47
+ end
@@ -16,7 +16,9 @@ module MarkdownRails
16
16
  end
17
17
 
18
18
  def renderer
19
- ::Redcarpet::Markdown.new(self.class, **features)
19
+ # I can get away passing fatures into this class because they don't
20
+ # overlap and RedCarpet is happy accepting both.
21
+ ::Redcarpet::Markdown.new(self.class.new(**features), **features)
20
22
  end
21
23
 
22
24
  private
@@ -3,15 +3,31 @@ module MarkdownRails
3
3
  class Rails < Base
4
4
  include ::Rails.application.routes.url_helpers
5
5
 
6
- # Rendering from Markdown is actually outside of the view
7
- # context, so we need to delegate render to the ApplicationController
8
- # render method that can render outside of the view context.
9
- delegate \
10
- :helpers,
11
- :render,
12
- to: :base_controller
6
+ attr_accessor :view_context
7
+
8
+ def initialize(**options)
9
+ super(**options)
10
+ end
11
+
12
+ def image(link, title, alt)
13
+ image_tag link, title: title, alt: alt
14
+ end
13
15
 
16
+ def view_context
17
+ @view_context ||= self.class.default_view_context
18
+ end
19
+
20
+ # Delegate view helpers to view_context since they need view state.
21
+ # The view_context has all helpers properly configured with @output_buffer, etc.
22
+ # For custom helpers, access them via view_context:
23
+ # view_context.my_custom_helper
24
+ # Or delegate them explicitly in your subclass:
25
+ # delegate :my_custom_helper, to: :view_context
14
26
  delegate \
27
+ :render,
28
+ :link_to,
29
+ :button_to,
30
+ :mail_to,
15
31
  :asset_digest_path,
16
32
  :asset_path,
17
33
  :asset_url,
@@ -26,21 +42,32 @@ module MarkdownRails
26
42
  :video_path,
27
43
  :video_tag,
28
44
  :video_url,
45
+ :javascript_include_tag,
46
+ :stylesheet_link_tag,
29
47
  :tag,
30
48
  :content_tag,
31
49
  :request,
32
50
  :turbo_frame_tag,
33
51
  :controller,
34
52
  :raw,
35
- to: :helpers
53
+ :safe_join,
54
+ :capture,
55
+ to: :view_context
36
56
 
37
- def image(link, title, alt)
38
- image_tag link, title: title, alt: alt
57
+ def renderer
58
+ # Override Base#renderer to pass view_context to the new instance
59
+ new_instance = self.class.new(**features)
60
+ new_instance.view_context = view_context
61
+ ::Redcarpet::Markdown.new(new_instance, **features)
62
+ end
63
+
64
+ def self.default_view_context
65
+ ::ApplicationController.new.view_context
39
66
  end
40
67
 
41
- protected
42
- def base_controller
43
- ::ApplicationController
68
+ private
69
+ def features
70
+ Hash[Array(enable).map{ |feature| [ feature, true ] }]
44
71
  end
45
72
  end
46
73
  end
@@ -1,3 +1,3 @@
1
1
  module MarkdownRails
2
- VERSION = "2.0.2"
2
+ VERSION = "2.2.0"
3
3
  end
@@ -2,14 +2,11 @@ require "markdown-rails/version"
2
2
  require "markdown-rails/engine"
3
3
 
4
4
  module MarkdownRails
5
- def self.handle(*extensions, with: Handler::Markdown, &block)
6
- with.handle *extensions, &block
5
+ def self.handle(*extensions, &block)
6
+ Handler.handle(*extensions, &block)
7
7
  end
8
8
 
9
- module Handler
10
- autoload :Markdown, "markdown-rails/handler/markdown"
11
- autoload :Erb, "markdown-rails/handler/erb"
12
- end
9
+ autoload :Handler, "markdown-rails/handler"
13
10
 
14
11
  module Renderer
15
12
  autoload :Base, "markdown-rails/renderer/base"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Gessler
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-10-12 00:00:00.000000000 Z
10
+ date: 2025-11-04 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: railties
@@ -66,6 +65,20 @@ dependencies:
66
65
  - - ">="
67
66
  - !ruby/object:Gem::Version
68
67
  version: 3.0.0
68
+ - !ruby/object:Gem::Dependency
69
+ name: rspec-rails
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '6.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '6.0'
69
82
  description: Markdown Rails is a comprehensive stack for rendering Markdown templates
70
83
  and partials in Rails.
71
84
  email:
@@ -81,11 +94,11 @@ files:
81
94
  - lib/generators/markdown_rails/install/USAGE
82
95
  - lib/generators/markdown_rails/install/install_generator.rb
83
96
  - lib/generators/markdown_rails/install/templates/app/markdown/application_markdown.rb
97
+ - lib/generators/markdown_rails/install/templates/app/markdown/erb_markdown.rb
84
98
  - lib/generators/markdown_rails/install/templates/config/initializers/markdown.rb
85
99
  - lib/markdown-rails.rb
86
100
  - lib/markdown-rails/engine.rb
87
- - lib/markdown-rails/handler/erb.rb
88
- - lib/markdown-rails/handler/markdown.rb
101
+ - lib/markdown-rails/handler.rb
89
102
  - lib/markdown-rails/helper/rouge.rb
90
103
  - lib/markdown-rails/railtie.rb
91
104
  - lib/markdown-rails/renderer/base.rb
@@ -100,7 +113,6 @@ metadata:
100
113
  homepage_uri: https://github.com/sitepress/markdown-rails
101
114
  source_code_uri: https://github.com/sitepress/markdown-rails
102
115
  changelog_uri: https://github.com/sitepress/markdown-rails
103
- post_install_message:
104
116
  rdoc_options: []
105
117
  require_paths:
106
118
  - lib
@@ -115,8 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
127
  - !ruby/object:Gem::Version
116
128
  version: '0'
117
129
  requirements: []
118
- rubygems_version: 3.4.6
119
- signing_key:
130
+ rubygems_version: 3.6.2
120
131
  specification_version: 4
121
132
  summary: Markdown templates and partials in Rails.
122
133
  test_files: []
@@ -1,22 +0,0 @@
1
- module MarkdownRails
2
- module Handler
3
- class Erb < Markdown
4
- def call(template, source = template.source)
5
- compiled_source = compile_erb template, source
6
- # TODO: This won't properly handle initializer blocks. Somehow
7
- # I need to pass a reference to the block that's passed in.
8
- "#{markdown.class.name}.new.renderer.render(begin;#{compiled_source};end).html_safe"
9
- end
10
-
11
- private
12
-
13
- def compile_erb(template, source)
14
- erb.call(template, source)
15
- end
16
-
17
- def erb
18
- ActionView::Template.registered_template_handler(:erb)
19
- end
20
- end
21
- end
22
- end
@@ -1,45 +0,0 @@
1
- module MarkdownRails
2
- module Handler
3
- # We cannot use MarkdownRails because it conflicts with RDiscount's Markdown class
4
- class Markdown
5
- DEFAULT_EXTENSION = :md
6
-
7
- def initialize(&block)
8
- @markdown = block
9
- end
10
-
11
- def call(template, source = template.source)
12
- renderer.render(source).inspect + '.html_safe'
13
- end
14
-
15
- def self.handle(*extensions, &block)
16
- Array(extensions).each do |extension|
17
- handler = new &block
18
- ActionView::Template.register_template_handler extension, handler
19
- end
20
- end
21
-
22
- # Registers a default `.md` handler for Rails templates. This might be
23
- # replaced by a handler in the `config/initializers/markdown.rb` file.
24
- def self.register_default_handler
25
- handle(DEFAULT_EXTENSION) { MarkdownRails::Renderer::Rails.new }
26
- end
27
-
28
- private
29
-
30
- def markdown
31
- @cache = nil unless cache_enabled?
32
- @cache ||= @markdown.call
33
- end
34
-
35
- def renderer
36
- @renderer = nil unless cache_enabled?
37
- @renderer ||= markdown.renderer
38
- end
39
-
40
- def cache_enabled?
41
- ::Rails.configuration.cache_classes
42
- end
43
- end
44
- end
45
- end