zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

earmark.ex (2658B)


      1 defmodule ExDoc.Markdown.Earmark do
      2   @moduledoc """
      3   ExDoc extension for the EarmarkParser Markdown parser.
      4   """
      5 
      6   @behaviour ExDoc.Markdown
      7 
      8   @impl true
      9   def available? do
     10     match?({:ok, _}, Application.ensure_all_started(:earmark_parser)) and
     11       Code.ensure_loaded?(EarmarkParser)
     12   end
     13 
     14   @doc """
     15   Generate HTML AST.
     16 
     17   ## Options
     18 
     19     * `:gfm` - (boolean) turns on Github Flavored Markdown extensions. Defaults to `true`.
     20 
     21     * `:breaks` - (boolean) only applicable if `gfm` is enabled. Makes all line
     22       breaks significant (so every line in the input is a new line in the output).
     23 
     24   """
     25   @impl true
     26   def to_ast(text, opts) do
     27     options = [
     28       gfm: true,
     29       line: 1,
     30       file: "nofile",
     31       breaks: false,
     32       pure_links: true
     33     ]
     34 
     35     options = Keyword.merge(options, opts)
     36 
     37     case EarmarkParser.as_ast(text, options) do
     38       {:ok, ast, messages} ->
     39         print_messages(messages, options)
     40         fixup(ast)
     41 
     42       {:error, ast, messages} ->
     43         print_messages(messages, options)
     44         fixup(ast)
     45     end
     46   end
     47 
     48   defp print_messages(messages, options) do
     49     for {severity, line, message} <- messages do
     50       file = options[:file]
     51       IO.warn("#{inspect(__MODULE__)} (#{severity}) #{file}:#{line} #{message}", [])
     52     end
     53   end
     54 
     55   defp fixup(list) when is_list(list) do
     56     fixup_list(list, [])
     57   end
     58 
     59   defp fixup(binary) when is_binary(binary) do
     60     binary
     61   end
     62 
     63   defp fixup({tag, attrs, ast}) do
     64     fixup({tag, attrs, ast, %{}})
     65   end
     66 
     67   defp fixup({tag, attrs, ast, meta}) when is_binary(tag) and is_list(attrs) and is_map(meta) do
     68     {fixup_tag(tag), Enum.map(attrs, &fixup_attr/1), fixup(ast), meta}
     69   end
     70 
     71   defp fixup({:comment, _, _, _}) do
     72     []
     73   end
     74 
     75   # We are matching on Livebook outputs here, because we prune comments at this point
     76   defp fixup_list(
     77          [
     78            {:comment, _, [~s/ livebook:{"output":true} /], %{comment: true}},
     79            {"pre", pre_attrs, [{"code", code_attrs, [source], code_meta}], pre_meta}
     80            | ast
     81          ],
     82          acc
     83        ) do
     84     code_attrs = Enum.reject(code_attrs, &match?({"class", _}, &1))
     85     new_code = {"code", [{"class", "output"} | code_attrs], [source], code_meta}
     86     fixup_list([{"pre", pre_attrs, [new_code], pre_meta} | ast], acc)
     87   end
     88 
     89   defp fixup_list([head | tail], acc) do
     90     fixed = fixup(head)
     91 
     92     if fixed == [] do
     93       fixup_list(tail, acc)
     94     else
     95       fixup_list(tail, [fixed | acc])
     96     end
     97   end
     98 
     99   defp fixup_list([], acc) do
    100     Enum.reverse(acc)
    101   end
    102 
    103   defp fixup_tag(tag) do
    104     String.to_atom(tag)
    105   end
    106 
    107   defp fixup_attr({name, value}) do
    108     {String.to_atom(name), value}
    109   end
    110 end