diff --git a/CHANGELOG.md b/CHANGELOG.md index f70f05b..c340c77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog -## v3.0.4 +## unreleased + +- Add `before_markdown_render` and `after_markdown_render` hooks, allowing + content manipulation. + +## v3.1.0 - Add support for [Github's alert syntax](https://github.com/orgs/community/discussions/16925). diff --git a/README.md b/README.md index ee727bf..ed46f51 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ To highlight code, use fenced code blocks. You can even provide options: - ```php?start_inline=1&line_numbers=1 + ```php?start_line=1&line_numbers=1 echo "Hello World"; ``` @@ -206,6 +206,24 @@ The following Redcarpet options are enabled: - `superscript` - `tables` +### Hooks + +There are a few hooks that allows manipulating the content. You can use +`before_markdown_render` and `after_markdown_render`. You can add such hooks to +your `config/helpers.rb` file. + +```ruby +Kitabu.add_hook(:before_markdown_render) do |markdown| + # manipulate content and return it. + markdown +end + +Kitabu.add_hook(:after_markdown_render) do |html| + # manipulate content and return it. + html +end +``` + ### Using custom fonts You can use custom fonts for your PDF. Just add them to the `fonts` directory diff --git a/lib/kitabu.rb b/lib/kitabu.rb index 94f4bf6..72b591f 100644 --- a/lib/kitabu.rb +++ b/lib/kitabu.rb @@ -46,6 +46,7 @@ module Kitabu require "kitabu/footnotes/base" require "kitabu/footnotes/html" require "kitabu/footnotes/pdf" + require "kitabu/hook" require "kitabu/toc/html" require "kitabu/toc/html/stream" require "kitabu/toc/epub" @@ -53,6 +54,29 @@ module Kitabu require "kitabu/stats" require "kitabu/helpers" + # Hook up and run custom code before certain actions. Existing hooks: + # + # * before_markdown_render + # * after_markdown_render + # + # To add a new hook: + # + # Kitabu.add_hook(:before_markdown_render) do |content| + # content + # end + # + def self.hooks + @hooks ||= Hash.new {|h, k| h[k] = [] } + end + + def self.add_hook(name, &block) + hooks[name.to_sym] << block + end + + def self.run_hooks(name, arg) + hooks[name.to_sym].reduce(arg) {|buffer, hook| hook.call(buffer) } + end + def self.config(root_dir = nil) root_dir ||= Pathname.new(Dir.pwd) path = root_dir.join("config/kitabu.yml") diff --git a/lib/kitabu/exporter/html.rb b/lib/kitabu/exporter/html.rb index db06ec1..b1f75f2 100644 --- a/lib/kitabu/exporter/html.rb +++ b/lib/kitabu/exporter/html.rb @@ -54,7 +54,9 @@ def content File.read(file_path) end - Kitabu::Markdown.render(content) + content = Kitabu.run_hooks(:before_markdown_render, content) + content = Kitabu::Markdown.render(content) + Kitabu.run_hooks(:after_markdown_render, content) end private def file_format(file_path) diff --git a/lib/kitabu/hook.rb b/lib/kitabu/hook.rb new file mode 100644 index 0000000..dfbb253 --- /dev/null +++ b/lib/kitabu/hook.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Kitabu + class Hook + # The hook name. + attr_reader :name + + # The block that will be called with the data for that hook. + attr_reader :callback + + def initialize(hook, &block) + @hook = hook + @callback = block + end + end +end diff --git a/spec/kitabu/exporter/html_spec.rb b/spec/kitabu/exporter/html_spec.rb index 590bd31..1f11089 100644 --- a/spec/kitabu/exporter/html_spec.rb +++ b/spec/kitabu/exporter/html_spec.rb @@ -6,6 +6,27 @@ let(:root) { SPECDIR.join("support/mybook") } let(:format) { described_class.new(root) } + context "hooks" do + let(:file) { SPECDIR.join("support/mybook/output/mybook.html") } + let(:html) { File.read(file) } + + it "calls before markdown render hook" do + index = 0 + + Kitabu.add_hook(:after_markdown_render) do |_content| + index += 1 + "
after #{index}
" + end + + format.export + + expect(html).to have_tag("p", "after 1") + expect(html).to have_tag("p", "after 2") + expect(html).to have_tag("p", "after 3") + expect(html).to have_tag("p", "after 4") + end + end + context "when generating HTML" do let(:file) { SPECDIR.join("support/mybook/output/mybook.html") } let(:html) { File.read(file) } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5d97466..86741a7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -56,4 +56,5 @@ def bundle_install config.before(&cleaner) config.after(&cleaner) config.before { FileUtils.mkdir_p(TMPDIR) } + config.before { Kitabu.hooks.clear } end