zf

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

html_formatter.ex (3512B)


      1 defmodule Makeup.Formatters.HTML.HTMLFormatter do
      2   @moduledoc """
      3   Turns a list of tokens into HTML fragments.
      4   """
      5 
      6   @group_highlight_js "lib/makeup/formatters/html/scripts/group_highlighter_javascript.js" |> File.read!
      7 
      8   defp render_token(escaped_value, css_class, meta, highlight_tag) do
      9     group_id = meta[:group_id]
     10     selectable = Map.get(meta, :selectable, [])
     11 
     12     classes = [
     13       css_class || [],
     14       if selectable == false do " unselectable" else [] end
     15     ]
     16 
     17     [
     18       "<",
     19       highlight_tag,
     20       ~S( class="),
     21       classes,
     22       ~S("),
     23       if group_id do [~S( data-group-id="), group_id, ~S(")] else [] end,
     24       ">",
     25       escaped_value,
     26       "</",
     27       highlight_tag,
     28       ">",
     29     ]
     30   end
     31 
     32   @doc """
     33   Format a single token into an iolist.
     34   """
     35   def format_token({tag, meta, value}, highlight_tag) do
     36     escaped_value = escape(value)
     37     css_class = Makeup.Token.Utils.css_class_for_token_type(tag)
     38     render_token(escaped_value, css_class, meta, highlight_tag)
     39   end
     40 
     41   defp escape_for(?&), do: "&amp;"
     42 
     43   defp escape_for(?<), do: "&lt;"
     44 
     45   defp escape_for(?>), do: "&gt;"
     46 
     47   defp escape_for(?"), do: "&quot;"
     48 
     49   defp escape_for(?'), do: "&#39;"
     50 
     51   defp escape_for(c) when is_integer(c) and c <= 127, do: c
     52 
     53   defp escape_for(c) when is_integer(c) and c >= 128, do: << c :: utf8 >>
     54 
     55   defp escape_for(string) when is_binary(string) do
     56     string
     57     |> to_charlist()
     58     |> Enum.map(&escape_for/1)
     59   end
     60 
     61   defp escape(iodata) when is_list(iodata) do
     62     iodata
     63     |> :lists.flatten()
     64     |> Enum.map(&escape_for/1)
     65   end
     66 
     67   defp escape(other) when is_binary(other) do
     68     escape_for(other)
     69   end
     70 
     71   defp escape(c) when is_integer(c) do
     72     [escape_for(c)]
     73   end
     74 
     75   defp escape(other) do
     76     raise "Found `#{inspect(other)}` inside what should be an iolist"
     77   end
     78 
     79   @doc """
     80   Turns a list of tokens into an iolist which represents an HTML fragment.
     81   This fragment can be embedded directly into an HTML document.
     82   """
     83   def format_inner_as_iolist(tokens, opts) do
     84     highlight_tag = Keyword.get(opts, :highlight_tag, "span")
     85     Enum.map(tokens, &format_token(&1, highlight_tag))
     86   end
     87 
     88   @doc """
     89   Turns a list of tokens into an HTML fragment.
     90   This fragment can be embedded directly into an HTML document.
     91   """
     92   def format_inner_as_binary(tokens, opts) do
     93     tokens
     94     |> format_inner_as_iolist(opts)
     95     |> IO.iodata_to_binary
     96   end
     97 
     98   @doc """
     99   Turns a list of tokens into an iolist which represents an HTML fragment.
    100   This fragment can be embedded directly into an HTML document.
    101   """
    102   def format_as_iolist(tokens, opts \\ []) do
    103     css_class = Keyword.get(opts, :css_class, "highlight")
    104     inner = format_inner_as_iolist(tokens, opts)
    105 
    106     [
    107       ~S(<pre class="),
    108       css_class,
    109       ~S("><code>),
    110       inner,
    111       ~S(</code></pre>)
    112     ]
    113   end
    114 
    115   @doc """
    116   Turns a list of tokens into an HTML fragment.
    117   This fragment can be embedded directly into an HTML document.
    118   """
    119   def format_as_binary(tokens, opts \\ []) do
    120     tokens
    121     |> format_as_iolist(opts)
    122     |> IO.iodata_to_binary
    123   end
    124 
    125   @doc """
    126   Return the CSS stylesheet for a given style.
    127   """
    128   def stylesheet(style, css_class \\ "highlight") do
    129     Makeup.Styles.HTML.Style.stylesheet(style, css_class)
    130   end
    131 
    132   @doc """
    133   Return a JavaScript snippet to highlight code on mouseover.
    134   This is "raw" javascript, and for inclusion in an HTML file
    135   it must be wrapped in a `<script>` tag.
    136   """
    137   def group_highlighter_javascript() do
    138     @group_highlight_js
    139   end
    140 end