zf

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

context.ex (3991B)


      1 defmodule EarmarkParser.Context do
      2   @moduledoc false
      3   alias EarmarkParser.Options
      4 
      5   @type t :: %__MODULE__{
      6           options: EarmarkParser.Options.t(),
      7           links: map(),
      8           footnotes: map(),
      9           referenced_footnote_ids: MapSet.t(String.t()),
     10           value: String.t() | [String.t()]
     11         }
     12 
     13   defstruct options: %EarmarkParser.Options{},
     14             links: Map.new(),
     15             rules: nil,
     16             footnotes: Map.new(),
     17             referenced_footnote_ids: MapSet.new([]),
     18             value: []
     19 
     20   ##############################################################################
     21   # Handle adding option specific rules and processors                         #
     22   ##############################################################################
     23 
     24   @doc false
     25   def modify_value(%__MODULE__{value: value} = context, fun) do
     26     nv = fun.(value)
     27     %{context | value: nv}
     28   end
     29 
     30   @doc false
     31   def prepend(context1, ast_or_context, context2_or_nil \\ nil)
     32 
     33   def prepend(%__MODULE__{} = context1, %__MODULE__{} = context2, nil) do
     34     context1
     35     |> _merge_contexts(context2)
     36     |> _prepend(context2.value)
     37   end
     38 
     39   def prepend(%__MODULE__{} = context1, ast, nil) do
     40     context1
     41     |> _prepend(ast)
     42   end
     43 
     44   def prepend(%__MODULE__{} = context1, ast, %__MODULE__{} = context2) do
     45     context1
     46     |> _merge_contexts(context2)
     47     |> _prepend(ast)
     48   end
     49 
     50   defp _merge_contexts(
     51          %__MODULE__{referenced_footnote_ids: orig} = context1,
     52          %__MODULE__{referenced_footnote_ids: new} = context2
     53        ) do
     54     context_ = _merge_messages(context1, context2)
     55     %{context_| referenced_footnote_ids: MapSet.union(orig, new)}
     56   end
     57 
     58   defp _merge_messages(context, context_or_messages)
     59   defp _merge_messages(context, %__MODULE__{options: %Options{messages: messages}}) do
     60     _merge_messages(context, messages)
     61   end
     62   defp _merge_messages(context, messages) do
     63     %{context | options: %{context.options|messages: MapSet.union(context.options.messages, messages)}}
     64   end
     65 
     66 
     67   defp _prepend(ctxt, []), do: ctxt
     68 
     69   defp _prepend(%{value: value} = ctxt, {:comment, _, _, _} = ct),
     70     do: %{ctxt | value: [ct | value]}
     71 
     72   defp _prepend(%{value: value} = ctxt, tuple) when is_tuple(tuple) do
     73     %{ctxt | value: [tuple | value] |> List.flatten()}
     74   end
     75 
     76   defp _prepend(%{value: value} = ctxt, list) when is_list(list),
     77     do: %{ctxt | value: List.flatten(list ++ value)}
     78 
     79   @doc """
     80   Convenience method to prepend to the value list
     81   """
     82   def set_value(%__MODULE__{} = ctx, value) do
     83     %{ctx | value: value}
     84   end
     85 
     86   def clear_value(%__MODULE__{} = ctx), do: %{ctx | value: []}
     87 
     88   # this is called by the command line processor to update
     89   # the inline-specific rules in light of any options
     90   def update_context(context = %EarmarkParser.Context{options: options}) do
     91     %{context | rules: rules_for(options)}
     92   end
     93 
     94   #                 ( "[" .*? "]"n or anything w/o {"[", "]"}* or "]" ) *
     95   @link_text ~S{(?:\[[^]]*\]|[^][]|\])*}
     96   # "
     97   # @href ~S{\s*<?(.*?)>?(?:\s+['"](.*?)['"])?\s*}
     98 
     99   defp basic_rules do
    100     [
    101       br: ~r<^ {2,}\n(?!\s*$)>,
    102       text: ~r<^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)>
    103     ]
    104   end
    105 
    106   defp rules_for(options) do
    107     subsup =
    108       if options.sub_sup do
    109         "~^"
    110       else
    111         ""
    112       end
    113     rule_updates =
    114       if options.gfm do
    115         rules = [
    116           text: ~r{^[\s\S]+?(?=~~|[\\<!\[_*`#{subsup}]|https?://| \{2,\}\n|$)}
    117         ]
    118 
    119         if options.breaks do
    120           break_updates = [
    121             br: ~r{^ *\n(?!\s*$)},
    122             text: ~r{^[\s\S]+?(?=[\\<!\[_*`#{subsup}]|https?://| *\n|$)}
    123           ]
    124 
    125           Keyword.merge(rules, break_updates)
    126         else
    127           rules
    128         end
    129       else
    130         []
    131       end
    132 
    133     footnote = if options.footnotes, do: ~r{^\[\^(#{@link_text})\]}, else: ~r{\z\A}
    134     rule_updates = Keyword.merge(rule_updates, footnote: footnote)
    135 
    136     Keyword.merge(basic_rules(), rule_updates)
    137     |> Enum.into(%{})
    138   end
    139 end
    140 
    141 # SPDX-License-Identifier: Apache-2.0