Closed nesquena closed 3 years ago
There's no straightforward way to do this using commonmarker itself; the recommendation is to do as GitHub do and use something like html-pipeline to post-process the generated HTML in stages to apply transforms as needed. This is a fair bit cleaner than trying to do everything in the Markdown→HTML step itself, and offers a lot of flexibility.
You'd need to define a filter that searches for ul li input[type=checkbox]
and mark the <ul>
s and <li>
s appropriately. An alternative would be to create your own tasklist transformer, which is how GitHub do it themselves — they don't actually use the tasklist extension provided in cmark-gfm (and thus commonmarker).
Oh, what am I saying — you can of course subclass Renderer
. See how the provided HtmlRenderer
renders tasklist items.
Thanks @kivikakk, good to know, I'll look at that and see if I can take the renderer subclass approach then. If I figure out the best way to modify, I am assuming I'd need to determine if a node is a tasklist and then use that to override list_item
https://github.com/gjtorikian/commonmarker/blob/b4335a63fe177160788d31b5325e1a0fc624a8c9/lib/commonmarker/renderer/html_renderer.rb#L57-L64 since tasklist
seems to only have control of the "input" not the li
or ul
. I'll respond back here if I figure things out. If anyone else has done this before in another project, would be interested to hear if this seems like the best path forward and if you have any prior work on this. Good to know about the html-pipeline option as a fallback.
Maybe something like:
def list_item(node)
block do
tasklist_data = tasklist(node)
container("<li#{" class='task-list-item'" if tasklist?(node)}#{sourcepos(node)}#{tasklist_data}>#{' ' if tasklist?(node)}", '</li>') do
out(:children)
end
end
end
I am happy for this to be closed for now, although I would wonder since 9/10 times you don't want to render tasklists with a bullet if it wouldn't be worth making this easier to achieve in the future. I understand that this may also be partly a responsibility of the underlying commonmark library though to expose that or simply out of scope.
Update, I ended up going the html-pipeline approach, here's what I did for anyone else that stumbles upon this later. Setup html-pipeline:
gem 'html-pipeline', '~> 2.14'
Created a custom filter to add the classes to the ul
and li
:
class MarkdownTaskListClassFilter < HTML::Pipeline::Filter
def call
doc.search("ul > li > input[type=checkbox]").each do |input|
input.parent['class'] = "task-list-item" # li
input.parent.parent['class'] = "contains-task-list" # ul
end
doc
end
end
Process the filter in my code here after rendering the markdown to HTML:
# Render the body to HTML to `html_body` using commonmark above...
pipeline = HTML::Pipeline.new [MarkdownTaskListClassFilter]
result = pipeline.call html_body
result[:output].to_s
I'm all set with that solution, thanks again.
Hi all! With
tasklist
extension enabled, this markdown:Generates the following HTML:
Is it possible to add classes (as GitHub does) to make these style-able?
GitHub renders as such:
Why is this feature necessary?
I want to add "list-style: none;" to the
<ul>
class, as it currently doesn't look good:and I'd want to see this rendered as:
Apologies if I've missed a way to do this, I've looked through the docs but couldn't see a way.