slim-template/slim

variable markdown filter at compilation time

noraj opened this issue · 1 comments

noraj commented

There are various ways to include markdown

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.

noraj commented

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.