variable markdown filter at compilation time
noraj opened this issue · 1 comments
There are various ways to include markdown
- Embedded engines (aka filters) to write markdown directly
- via includes [1] [2] to include a whole markdown file
- via interpolation inside a markdown filter as discussed below, not working because the interpolation is done first at runtime and the markdown rendering is done after at compilation time
- Rendering interpolated values as Markdown #538
- Slim doesn't render markdown stored in a variable #614
- Slim template doesn't render markdown stored in a variable
- Rendering markdown with Slim/Rails from an instance var
- variable filter at compilation time (Will be discussed in this post)
Having an embedded engine aka filter for markdown is nice, but it actually only allow to write markdown directly without a way to import any content from an external source that is not a file.
The issue is if you have markdown stored in a variable or from data (ex: JSON) you can't get it rendered in any way.
Examples:
From a variable (where pull_markdown_content is a function that will return markdown content, and so myvar
will contain markdown):
- myvar = pull_markdown_content(x, y, z)
markdown:myvar
From data:
markdown:data.jsonfile.node.subnode.markdown_description
jsonfile.json
{
"node": {
"toto": "tata",
"subnode": {
"title": "test",
"markdown_description": "**Markdown** is _huge_"
}
}
}
As the references linked above are showing a lot of people have tried to interpolation in a filter instead eg. something like that:
- myvar = pull_markdown_content(x, y, z)
markdown:
#{myvar}
#{data.jsonfile.node.subnode.markdown_description}
which can't work for the reasons we have seen above.
For static website generator there all is compiled there is no "runtime" as you compile static files and are not running a dynamic backend.
So instead if there were a way to enhance filters so they can accept an object to render too this would solve the problem.
Examples:
Current behavior (filter with markdown content block)
markdown:
**Markdown** is _huge_
New additional behavior (filter with inline object)
markdown:data.source.node
markdown:variable
I understand the interpolation inside a filter is a no go, but at least if there was a render some markdown content that come from a data file or a variable it would solve many headaches.
If my explanation is not clear feel free to ask questions.
workaround for slim usage in middleman
Add redcarpet (markdown renderer) in the Gemfile:
gem 'tilt', '>= 2.0.9', '< 3.0.0'
gem 'redcarpet', '~> 3.5', '>= 3.5.1'
In middleman config (config.rb) add:
set :markdown_engine, :redcarpet
In the slim template:
- markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :no_intra_emphasis => true, :tables => true, :fenced_code_blocks => true, :filter_html => false, :with_toc_data => true)
p = markdown.render(data.jsonfile.node.subnode.markdown_description)
It works but it is super heavy and unhandy.
Pug filters warning about interpolation in filters
Warning
Filters are rendered at compile time. This makes them fast, but it > also means that they cannot support dynamic content or options.
By default, compilation in the browser does not have access to > JSTransformer-based filters, unless the JSTransformer modules are > explicitly packed and made available through a CommonJS platform > (such as Browserify or Webpack). In fact, the page you are reading > right now uses Browserify to make the filters available in the > browser.
Templates pre-compiled on the server do not have this limitation.
But it seems in Pug, custom filters may enable to process a variable or even create a function that will modify the processed content.