Skip to content

Instantly share code, notes, and snippets.

@shyouhei
Created February 20, 2017 03:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shyouhei/e396ceb0cb8b55ae4a5a1f1057e9c370 to your computer and use it in GitHub Desktop.
Save shyouhei/e396ceb0cb8b55ae4a5a1f1057e9c370 to your computer and use it in GitHub Desktop.
DOM of a Markdown document. Because Redcarpet is strongly HTML-centric we cannot pass non-String return values around. We instead have to retain all generated s-expressions and left markers of them in the return value. The DOM is constructed back from that info after we finished rendering.
#! /your/favourite/path/to/ruby
# -*- coding: utf-8 -*-
# -*- frozen_string_literal: true -*-
# -*- warn_indent: true -*-
require 'redcarpet'
class MD2DOM < Redcarpet::Render::Base
def preprocess str
@sexp = []
return str
end
def convert *a
ret = [__callee__, *a]
@sexp << ret
return sprintf("%d\n", @sexp.size - 1)
end
def postprocess str
return str.each_line.map do |l|
n = Integer(l) rescue nil
next l unless n
m = @sexp[n]
next l unless m
type, *a = *m
b = a.map do |i|
case i when String then
postprocess i
else
i
end
end
next [type, *b]
end
end
%i[
block_code block_quote block_html footnotes footnote_def header
hrule list list_item paragraph table table_row table_cell autolink
codespan double_emphasis emphasis image linebreak link raw_html
triple_emphasis strikethrough superscript underline highlight
quote footnote_ref entity normal_text doc_header doc_footer
].each do |m|
alias_method m, :convert
end
end
#! /your/favourite/path/to/ruby
# -*- coding: utf-8 -*-
# -*- frozen_string_literal: true -*-
# -*- warn_indent: true -*-
require 'json'
md = Redcarpet::Markdown.new MD2DOM
dom = md.render ARGF.read
json = JSON.pretty_generate dom
puts json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment