From 7f1ab5767311d651c20482b3d2dba25c6b1e58bf Mon Sep 17 00:00:00 2001 From: RobertDober Date: Wed, 12 Mar 2025 08:18:34 +0100 Subject: [PATCH 1/7] Road to #164 - added .formatter.exs - modified CI to check for formatted, WIP --- .formatter.exs | 10 ++++++++++ .github/workflows/elixir.yml | 5 +++++ 2 files changed, 15 insertions(+) create mode 100644 .formatter.exs diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..119aa3d --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,10 @@ +[ + force_do_end_blocks: true, + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"], + line_length: 120, + migrate: true, + migrate_bitstring_modifiers: true, + migrate_charlists_as_sigils: true, + migrate_unless: false, +] +# SPDX-License-Identifier: Apache-2.0 diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 87fe759..6214b73 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -68,6 +68,11 @@ jobs: env: CC: gcc-10 CXX: g++-10 + - run: mix format --check-formatted + if: matrix.warnings_as_errors + env: + CC: gcc-10 + CXX: g++-10 - run: mix compile if: ${{! matrix.warnings_as_errors}} env: From faae95251e6ca2e73704ceae342c5c0510be4ff5 Mon Sep 17 00:00:00 2001 From: RobertDober Date: Wed, 12 Mar 2025 11:19:29 +0100 Subject: [PATCH 2/7] Road to #164 - added .formatter.exs - modified CI to check for formatted, WIP - modified CI to run on this branch --- .github/workflows/elixir.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 6214b73..e094096 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -4,6 +4,7 @@ on: pull_request: push: branches: + - i164-use-formatter - master jobs: From 7aa41276e381f20ff4bc681335fd81d68bdf94ea Mon Sep 17 00:00:00 2001 From: RobertDober Date: Wed, 12 Mar 2025 11:24:32 +0100 Subject: [PATCH 3/7] Road to #164 - Commented all but one matrix entry as we will use lots of workers here - Put formatting action at the end to check all other actions for each pushed commit --- .github/workflows/elixir.yml | 56 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index e094096..a6086c4 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -15,29 +15,29 @@ jobs: fail-fast: false matrix: include: - - elixir: 1.14.x - otp: 25 - os: ubuntu-latest - - elixir: 1.15.x - otp: 25 - os: ubuntu-latest - warnings_as_errors: true - - elixir: 1.16.x - otp: 26 - os: ubuntu-latest - warnings_as_errors: true - - elixir: 1.17.x - otp: 27 - os: ubuntu-latest - warnings_as_errors: true - - elixir: 1.18.0-otp-25 - otp: 25 - os: ubuntu-latest - warnings_as_errors: true - - elixir: 1.18.0-otp-27 - otp: 27 - os: ubuntu-latest - warnings_as_errors: true + # - elixir: 1.14.x + # otp: 25 + # os: ubuntu-latest + # - elixir: 1.15.x + # otp: 25 + # os: ubuntu-latest + # warnings_as_errors: true + # - elixir: 1.16.x + # otp: 26 + # os: ubuntu-latest + # warnings_as_errors: true + # - elixir: 1.17.x + # otp: 27 + # os: ubuntu-latest + # warnings_as_errors: true + # - elixir: 1.18.0-otp-25 + # otp: 25 + # os: ubuntu-latest + # warnings_as_errors: true + # - elixir: 1.18.0-otp-27 + # otp: 27 + # os: ubuntu-latest + # warnings_as_errors: true - elixir: 1.18.3-otp-27 otp: 27 os: ubuntu-latest @@ -69,11 +69,6 @@ jobs: env: CC: gcc-10 CXX: g++-10 - - run: mix format --check-formatted - if: matrix.warnings_as_errors - env: - CC: gcc-10 - CXX: g++-10 - run: mix compile if: ${{! matrix.warnings_as_errors}} env: @@ -89,6 +84,11 @@ jobs: env: CC: gcc-10 CXX: g++-10 + - run: mix format --check-formatted + if: matrix.warnings_as_errors + env: + CC: gcc-10 + CXX: g++-10 # This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by From dcaa98373da2e713d74ff33bdec3b5acf83c3b6c Mon Sep 17 00:00:00 2001 From: RobertDober Date: Wed, 12 Mar 2025 13:05:36 +0100 Subject: [PATCH 4/7] Road to #164 - formatted files: - mix.exs - lib/earmark_parser.ex - lib/earmark_parser/ast/**/*.ex --- lib/earmark_parser.ex | 9 +-- lib/earmark_parser/ast/emitter.ex | 21 ++++-- lib/earmark_parser/ast/inline.ex | 51 +++++++++---- lib/earmark_parser/ast/renderer/ast_walker.ex | 72 ++++++++++++------- .../ast/renderer/footnote_renderer.ex | 13 ++-- .../ast/renderer/html_renderer.ex | 18 ++++- .../ast/renderer/table_renderer.ex | 25 +++++-- mix.exs | 14 +++- 8 files changed, 159 insertions(+), 64 deletions(-) diff --git a/lib/earmark_parser.ex b/lib/earmark_parser.ex index d6cfaa8..49ef870 100644 --- a/lib/earmark_parser.ex +++ b/lib/earmark_parser.ex @@ -615,7 +615,7 @@ defmodule EarmarkParser do The AST is exposed in the spirit of [Floki's](https://hex.pm/packages/floki). """ - @spec as_ast(binary()|list(binary()), any()) :: t() + @spec as_ast(binary() | list(binary()), any()) :: t() def as_ast(lines, options \\ %Options{}) def as_ast(lines, %Options{} = options) do @@ -644,7 +644,7 @@ defmodule EarmarkParser do end def as_ast(_, options) do - raise ArgumentError, "#{inspect options} not a legal options map or keyword list" + raise ArgumentError, "#{inspect(options)} not a legal options map or keyword list" end defp _as_ast(lines, options) do @@ -657,8 +657,9 @@ defmodule EarmarkParser do `iex` usage. """ def version() do - with {:ok, version} <- :application.get_key(:earmark_parser, :vsn), - do: to_string(version) + with {:ok, version} <- :application.get_key(:earmark_parser, :vsn) do + to_string(version) + end end end diff --git a/lib/earmark_parser/ast/emitter.ex b/lib/earmark_parser/ast/emitter.ex index f71b710..7e0e3b2 100644 --- a/lib/earmark_parser/ast/emitter.ex +++ b/lib/earmark_parser/ast/emitter.ex @@ -2,28 +2,41 @@ defmodule EarmarkParser.Ast.Emitter do @moduledoc false def emit(tag, content \\ [], atts \\ [], meta \\ %{}) + def emit(tag, content, atts, meta) when is_binary(content) or is_tuple(content) do {tag, _to_atts(atts), [content], meta} end + def emit(tag, content, atts, meta) do {tag, _to_atts(atts), content, meta} end - defp _to_atts(atts) - defp _to_atts(nil), do: [] + + defp _to_atts(nil) do + [] + end + defp _to_atts(atts) when is_map(atts) do atts |> Enum.into([]) |> Enum.map(fn {name, value} -> {to_string(name), _to_string(value)} end) end + defp _to_atts(atts) do atts |> Enum.map(fn {name, value} -> {to_string(name), _to_string(value)} end) end defp _to_string(value) - defp _to_string(value) when is_list(value), do: Enum.join(value, " ") - defp _to_string(value), do: to_string(value) + + defp _to_string(value) when is_list(value) do + Enum.join(value, " ") + end + + defp _to_string(value) do + to_string(value) + end end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/ast/inline.ex b/lib/earmark_parser/ast/inline.ex index f785132..da4c6e1 100644 --- a/lib/earmark_parser/ast/inline.ex +++ b/lib/earmark_parser/ast/inline.ex @@ -32,7 +32,9 @@ defmodule EarmarkParser.Ast.Inline do prepend(context, src) end - defp _convert("", _, context, _), do: context + defp _convert("", _, context, _) do + context + end defp _convert(src, current_lnb, context, use_linky?) do {src1, lnb1, context1, use_linky1?} = _convert_next(src, current_lnb, context, use_linky?) @@ -218,7 +220,9 @@ defmodule EarmarkParser.Ast.Inline do end end - def converter_for_sub(_), do: nil + def converter_for_sub(_) do + nil + end def converter_for_sup({src, _, %{options: %{sub_sup: true}}, _} = conv_tuple) do sup_rgx = ~r{\A\^(?=\S)(.*?\S)\^} @@ -228,7 +232,9 @@ defmodule EarmarkParser.Ast.Inline do end end - def converter_for_sup(_), do: nil + def converter_for_sup(_) do + nil + end def converter_for_math_inline({src, lnb, %{options: %{math: true}} = context, use_linky?}) do math_inline_rgx = ~r{\A\$(?=[^\s$])([\s\S]*?[^\s\\])\$} @@ -241,7 +247,9 @@ defmodule EarmarkParser.Ast.Inline do end end - def converter_for_math_inline(_), do: nil + def converter_for_math_inline(_) do + nil + end def converter_for_math_display({src, lnb, %{options: %{math: true}} = context, use_linky?}) do math_display_rgx = ~r{\A\$\$([\s\S]+?)\$\$} @@ -254,7 +262,9 @@ defmodule EarmarkParser.Ast.Inline do end end - def converter_for_math_display(_), do: nil + def converter_for_math_display(_) do + nil + end def converter_for_code({src, lnb, context, use_linky?}) do code = ~r{^ @@ -326,8 +336,7 @@ defmodule EarmarkParser.Ast.Inline do context1 = _convert(content, lnb, set_value(context, []), use_linky?) - {behead(src, match1), lnb, prepend(context, emit(for_tag, context1.value |> Enum.reverse())), - use_linky?} + {behead(src, match1), lnb, prepend(context, emit(for_tag, context1.value |> Enum.reverse())), use_linky?} end defp _prepend_footnote(context, out, id) do @@ -339,7 +348,13 @@ defmodule EarmarkParser.Ast.Inline do defp convert_autolink(link, separator) defp convert_autolink(link, _separator = "@") do - link = if String.at(link, 6) == ":", do: behead(link, 7), else: link + link = + if String.at(link, 6) == ":" do + behead(link, 7) + else + link + end + text = link href = "mailto:" <> text {href, text} @@ -359,8 +374,14 @@ defmodule EarmarkParser.Ast.Inline do end defp hard_line_breaks(text, gfm) - defp hard_line_breaks(text, false), do: text - defp hard_line_breaks(text, nil), do: text + + defp hard_line_breaks(text, false) do + text + end + + defp hard_line_breaks(text, nil) do + text + end defp hard_line_breaks(text, _) do text @@ -460,8 +481,14 @@ defmodule EarmarkParser.Ast.Inline do end defp _remove_leading_empty(list) - defp _remove_leading_empty(["" | rest]), do: rest - defp _remove_leading_empty(list), do: list + + defp _remove_leading_empty(["" | rest]) do + rest + end + + defp _remove_leading_empty(list) do + list + end end # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/ast/renderer/ast_walker.ex b/lib/earmark_parser/ast/renderer/ast_walker.ex index 3a60b0b..7fce56f 100644 --- a/lib/earmark_parser/ast/renderer/ast_walker.ex +++ b/lib/earmark_parser/ast/renderer/ast_walker.ex @@ -1,54 +1,74 @@ defmodule EarmarkParser.Ast.Renderer.AstWalker do - @moduledoc false - def walk(anything, fun, ignore_map_keys \\ false), do: _walk(anything, fun, ignore_map_keys, false) - - def walk_ast(ast, fun), do: _walk_ast(ast, fun, []) + def walk(anything, fun, ignore_map_keys \\ false) do + _walk(anything, fun, ignore_map_keys, false) + end + def walk_ast(ast, fun) do + _walk_ast(ast, fun, []) + end defp _walk(ast, fun, ignore_map_keys, child_of_map) - defp _walk([], _fun, _ignore_map_keys, _child_of_map), do: [] + + defp _walk([], _fun, _ignore_map_keys, _child_of_map) do + [] + end + defp _walk(list, fun, ignore_map_keys, _child_of_map) when is_list(list) do - Enum.map(list, &(_walk(&1, fun, ignore_map_keys, false))) + Enum.map(list, &_walk(&1, fun, ignore_map_keys, false)) end + defp _walk(map, fun, ignore_map_keys, _child_of_map) when is_map(map) do map - |> Enum.into(%{}, &(_walk(&1, fun, ignore_map_keys, true))) + |> Enum.into(%{}, &_walk(&1, fun, ignore_map_keys, true)) end + defp _walk(tuple, fun, ignore_map_keys, child_of_map) when is_tuple(tuple) do if child_of_map && ignore_map_keys do _walk_map_element(tuple, fun, ignore_map_keys) else tuple - |> Tuple.to_list - |> Enum.map(&(_walk(&1, fun, ignore_map_keys, false))) - |> List.to_tuple + |> Tuple.to_list() + |> Enum.map(&_walk(&1, fun, ignore_map_keys, false)) + |> List.to_tuple() end end - defp _walk(ele, fun, _ignore_map_keys, _child_of_map), do: fun.(ele) - defp _walk_map_element({key, value}, fun, ignore_map_keys) do - {key, _walk(value, fun, ignore_map_keys, false)} + defp _walk(ele, fun, _ignore_map_keys, _child_of_map) do + fun.(ele) end + defp _walk_map_element({key, value}, fun, ignore_map_keys) do + {key, _walk(value, fun, ignore_map_keys, false)} + end defp _walk_ast(ast, fun, res) - defp _walk_ast([], _fun, res), do: Enum.reverse(res) - defp _walk_ast(stringy, fun, res) when is_binary(stringy), do: _walk_ast([stringy], fun, res) - defp _walk_ast([stringy|rest], fun, res) when is_binary(stringy) do - res1 = - case fun.(stringy) do - [] -> res - [_|_]=trans -> List.flatten([Enum.reverse(trans)|res]) - stringy1 -> [stringy1|res] - end + + defp _walk_ast([], _fun, res) do + Enum.reverse(res) + end + + defp _walk_ast(stringy, fun, res) when is_binary(stringy) do + _walk_ast([stringy], fun, res) + end + + defp _walk_ast([stringy | rest], fun, res) when is_binary(stringy) do + res1 = + case fun.(stringy) do + [] -> res + [_ | _] = trans -> List.flatten([Enum.reverse(trans) | res]) + stringy1 -> [stringy1 | res] + end + _walk_ast(rest, fun, res1) end - defp _walk_ast([{tag, atts, content, meta}|rest], fun, res) do - _walk_ast(rest, fun, [{tag, atts, _walk_ast(content, fun, []), meta}|res]) + + defp _walk_ast([{tag, atts, content, meta} | rest], fun, res) do + _walk_ast(rest, fun, [{tag, atts, _walk_ast(content, fun, []), meta} | res]) end - defp _walk_ast([list|rest], fun, res) when is_list(list) do - _walk_ast(rest, fun, [_walk_ast(list, fun, [])|res]) + + defp _walk_ast([list | rest], fun, res) when is_list(list) do + _walk_ast(rest, fun, [_walk_ast(list, fun, []) | res]) end end diff --git a/lib/earmark_parser/ast/renderer/footnote_renderer.ex b/lib/earmark_parser/ast/renderer/footnote_renderer.ex index 3010387..d284154 100644 --- a/lib/earmark_parser/ast/renderer/footnote_renderer.ex +++ b/lib/earmark_parser/ast/renderer/footnote_renderer.ex @@ -23,26 +23,27 @@ defmodule EarmarkParser.Ast.Renderer.FootnoteRenderer do prepend(context, ast) |> Message.add_messages(errors) end - defp _render_footnote_def(%Block.FnDef{blocks: blocks, id: id}, {ast, errors, context}=acc) do + defp _render_footnote_def(%Block.FnDef{blocks: blocks, id: id}, {ast, errors, context} = acc) do if MapSet.member?(context.referenced_footnote_ids, id) do context1 = AstRenderer.render(blocks, clear_value(context)) a_attrs = %{title: "return to article", class: "reversefootnote", href: "#fnref:#{id}"} + footnote_li_ast = - emit("li", [emit("a", ["↩"], a_attrs, %{verbatim: true}) | context1.value], - id: "fn:#{id}") - {[footnote_li_ast|ast], MapSet.union(errors, context1.options.messages), context} + emit("li", [emit("a", ["↩"], a_attrs, %{verbatim: true}) | context1.value], id: "fn:#{id}") + + {[footnote_li_ast | ast], MapSet.union(errors, context1.options.messages), context} else acc end end - defp render_footnote_blocks(footnotes, context) do {elements, errors, _} = footnotes |> Enum.reduce({[], @empty_set, context}, &_render_footnote_def/2) - {elements|>Enum.reverse, errors} + {elements |> Enum.reverse(), errors} end end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/ast/renderer/html_renderer.ex b/lib/earmark_parser/ast/renderer/html_renderer.ex index 0e61afd..e58cd05 100644 --- a/lib/earmark_parser/ast/renderer/html_renderer.ex +++ b/lib/earmark_parser/ast/renderer/html_renderer.ex @@ -10,13 +10,27 @@ defmodule EarmarkParser.Ast.Renderer.HtmlRenderer do def render_html_block(lines, context, annotation) do [tag] = parse_html(lines) - tag_ = if annotation, do: annotate(tag, annotation), else: tag + + tag_ = + if annotation do + annotate(tag, annotation) + else + tag + end + prepend(context, tag_) end def render_html_oneline([line | _], context, annotation \\ []) do [tag | rest] = parse_html([line]) - tag_ = if annotation, do: annotate(tag, annotation), else: tag + + tag_ = + if annotation do + annotate(tag, annotation) + else + tag + end + prepend(context, [tag_ | rest]) end diff --git a/lib/earmark_parser/ast/renderer/table_renderer.ex b/lib/earmark_parser/ast/renderer/table_renderer.ex index 1411ef4..dfa6ee7 100644 --- a/lib/earmark_parser/ast/renderer/table_renderer.ex +++ b/lib/earmark_parser/ast/renderer/table_renderer.ex @@ -11,18 +11,19 @@ defmodule EarmarkParser.Ast.Renderer.TableRenderer do header |> Enum.zip(aligns) |> Enum.map_reduce(context, &_render_col(&1, &2, lnb, "th")) + {emit("thead", emit("tr", th_ast)), context1} end def render_rows(rows, lnb, aligns, context) do {rows1, context1} = rows - |> Enum.zip(Stream.iterate(lnb, &(&1 + 1))) - |> Enum.map_reduce(context, &_render_row(&1, &2, aligns)) + |> Enum.zip(Stream.iterate(lnb, &(&1 + 1))) + |> Enum.map_reduce(context, &_render_row(&1, &2, aligns)) + {[emit("tbody", rows1)], context1} end - defp _render_cols(row, lnb, aligns, context, coltype \\ "td") do row |> Enum.zip(aligns) @@ -31,7 +32,7 @@ defmodule EarmarkParser.Ast.Renderer.TableRenderer do defp _render_col({col, align}, context, lnb, coltype) do context1 = Inline.convert(col, lnb, Context.clear_value(context)) - {emit(coltype, context1.value |> Enum.reverse, _align_to_style(align)), context1} + {emit(coltype, context1.value |> Enum.reverse(), _align_to_style(align)), context1} end defp _render_row({row, lnb}, context, aligns) do @@ -40,8 +41,18 @@ defmodule EarmarkParser.Ast.Renderer.TableRenderer do end defp _align_to_style(align) - defp _align_to_style(:left), do: [{"style", "text-align: left;"}] - defp _align_to_style(:right), do: [{"style", "text-align: right;"}] - defp _align_to_style(:center), do: [{"style", "text-align: center;"}] + + defp _align_to_style(:left) do + [{"style", "text-align: left;"}] + end + + defp _align_to_style(:right) do + [{"style", "text-align: right;"}] + end + + defp _align_to_style(:center) do + [{"style", "text-align: center;"}] + end end + # SPDX-License-Identifier: Apache-2.0 diff --git a/mix.exs b/mix.exs index 2501baf..1c43e8f 100644 --- a/mix.exs +++ b/mix.exs @@ -59,9 +59,17 @@ defmodule EarmarkParser.MixProject do ] end - defp elixirc_paths(:test), do: ["lib", "test/support", "dev"] - defp elixirc_paths(:dev), do: ["lib", "bench", "dev"] - defp elixirc_paths(_), do: ["lib"] + defp elixirc_paths(:test) do + ["lib", "test/support", "dev"] + end + + defp elixirc_paths(:dev) do + ["lib", "bench", "dev"] + end + + defp elixirc_paths(_) do + ["lib"] + end @module "EarmarkParser" defp build_docs(_) do From 2513e71503914b23b1055e552d28eb1d8d3ece22 Mon Sep 17 00:00:00 2001 From: RobertDober Date: Wed, 12 Mar 2025 13:08:50 +0100 Subject: [PATCH 5/7] Road to #164 This commit completes reformatting of all application files NEXT: test/ - formatted files: - lib/earmark_parser/*.ex (main modules) - lib/earmark_parser/line_scanner/ - lib/earmark_parser/parser/ anterior commits: - lib/earmark_parser/block/ - lib/earmark_parser/enum/ - lib/earmark_parser/helpers/ - mix.exs - lib/earmark_parser.ex - lib/earmark_parser/ast/**/*.ex --- 2 | 0 lib/earmark_parser/ast_renderer.ex | 17 +- lib/earmark_parser/block/block_quote.ex | 1 + lib/earmark_parser/block/code.ex | 1 + lib/earmark_parser/block/fn_def.ex | 1 + lib/earmark_parser/block/fn_list.ex | 1 + lib/earmark_parser/block/heading.ex | 1 + lib/earmark_parser/block/html.ex | 1 + lib/earmark_parser/block/html_comment.ex | 1 + lib/earmark_parser/block/html_oneline.ex | 1 + lib/earmark_parser/block/ial.ex | 1 + lib/earmark_parser/block/id_def.ex | 1 + lib/earmark_parser/block/list.ex | 1 + lib/earmark_parser/block/list_item.ex | 1 + lib/earmark_parser/block/para.ex | 1 + lib/earmark_parser/block/ruler.ex | 1 + lib/earmark_parser/block/table.ex | 1 + lib/earmark_parser/block/text.ex | 1 + lib/earmark_parser/context.ex | 27 ++- lib/earmark_parser/enum/ext.ex | 16 +- lib/earmark_parser/helpers.ex | 28 ++- lib/earmark_parser/helpers/ast_helpers.ex | 55 ++++-- lib/earmark_parser/helpers/attr_parser.ex | 64 ++++--- lib/earmark_parser/helpers/html_parser.ex | 46 ++--- lib/earmark_parser/helpers/leex_helpers.ex | 31 ++-- lib/earmark_parser/helpers/line_helpers.ex | 44 +++-- .../helpers/lookahead_helpers.ex | 35 ++-- .../helpers/pure_link_helpers.ex | 10 +- lib/earmark_parser/helpers/reparse_helpers.ex | 9 +- lib/earmark_parser/helpers/string_helpers.ex | 3 +- lib/earmark_parser/helpers/yecc_helpers.ex | 9 +- lib/earmark_parser/line.ex | 50 ++++-- lib/earmark_parser/line_scanner.ex | 76 +++++--- lib/earmark_parser/line_scanner/rgx.ex | 93 +++++++--- lib/earmark_parser/message.ex | 11 +- lib/earmark_parser/options.ex | 86 ++++----- lib/earmark_parser/parser.ex | 109 +++++++++--- lib/earmark_parser/parser/footnote_parser.ex | 4 +- lib/earmark_parser/parser/link_parser.ex | 80 ++++++--- lib/earmark_parser/parser/list_info.ex | 14 +- lib/earmark_parser/parser/list_parser.ex | 165 +++++++++++------- 41 files changed, 719 insertions(+), 379 deletions(-) create mode 100644 2 diff --git a/2 b/2 new file mode 100644 index 0000000..e69de29 diff --git a/lib/earmark_parser/ast_renderer.ex b/lib/earmark_parser/ast_renderer.ex index 6a51ade..d339ba2 100644 --- a/lib/earmark_parser/ast_renderer.ex +++ b/lib/earmark_parser/ast_renderer.ex @@ -17,7 +17,10 @@ defmodule EarmarkParser.AstRenderer do end defp _render(blocks, context, loose?) - defp _render([], context, _loose?), do: context + + defp _render([], context, _loose?) do + context + end defp _render([block | blocks], context, loose?) do context1 = render_block(block, clear_value(context), loose?) @@ -139,9 +142,11 @@ defmodule EarmarkParser.AstRenderer do _loose? ) do classes = - if language && language != "", - do: [code_classes(language, options.code_class_prefix)], - else: [] + if language && language != "" do + [code_classes(language, options.code_class_prefix)] + else + [] + end lines = render_code(block) @@ -232,7 +237,9 @@ defmodule EarmarkParser.AstRenderer do # IDDef is ignored # #################### - defp render_block(%Block.IdDef{}, context, _loose?), do: context + defp render_block(%Block.IdDef{}, context, _loose?) do + context + end # Helpers # ------- diff --git a/lib/earmark_parser/block/block_quote.ex b/lib/earmark_parser/block/block_quote.ex index e457e03..6cb001e 100644 --- a/lib/earmark_parser/block/block_quote.ex +++ b/lib/earmark_parser/block/block_quote.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.BlockQuote do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, blocks: [] end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/code.ex b/lib/earmark_parser/block/code.ex index 495ed72..820dc36 100644 --- a/lib/earmark_parser/block/code.ex +++ b/lib/earmark_parser/block/code.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.Code do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, lines: [], language: nil end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/fn_def.ex b/lib/earmark_parser/block/fn_def.ex index 8819b47..5d26767 100644 --- a/lib/earmark_parser/block/fn_def.ex +++ b/lib/earmark_parser/block/fn_def.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.FnDef do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, id: nil, number: nil, blocks: [] end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/fn_list.ex b/lib/earmark_parser/block/fn_list.ex index 2b21881..173a0d2 100644 --- a/lib/earmark_parser/block/fn_list.ex +++ b/lib/earmark_parser/block/fn_list.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.FnList do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: ".footnotes", blocks: [] end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/heading.ex b/lib/earmark_parser/block/heading.ex index 5a95464..2ef0405 100644 --- a/lib/earmark_parser/block/heading.ex +++ b/lib/earmark_parser/block/heading.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.Heading do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, content: nil, level: nil end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/html.ex b/lib/earmark_parser/block/html.ex index d147b2b..ba01b0d 100644 --- a/lib/earmark_parser/block/html.ex +++ b/lib/earmark_parser/block/html.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.Html do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, html: [], tag: nil end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/html_comment.ex b/lib/earmark_parser/block/html_comment.ex index bbc4c85..63dfd90 100644 --- a/lib/earmark_parser/block/html_comment.ex +++ b/lib/earmark_parser/block/html_comment.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.HtmlComment do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, lines: [] end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/html_oneline.ex b/lib/earmark_parser/block/html_oneline.ex index d910d40..ef6a429 100644 --- a/lib/earmark_parser/block/html_oneline.ex +++ b/lib/earmark_parser/block/html_oneline.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.HtmlOneline do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, html: "" end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/ial.ex b/lib/earmark_parser/block/ial.ex index 42e4aba..5a397b0 100644 --- a/lib/earmark_parser/block/ial.ex +++ b/lib/earmark_parser/block/ial.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.Ial do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, content: nil, verbatim: "" end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/id_def.ex b/lib/earmark_parser/block/id_def.ex index 51fc1e1..9e860cb 100644 --- a/lib/earmark_parser/block/id_def.ex +++ b/lib/earmark_parser/block/id_def.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.IdDef do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, id: nil, url: nil, title: nil end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/list.ex b/lib/earmark_parser/block/list.ex index 9b09930..e7e4f9a 100644 --- a/lib/earmark_parser/block/list.ex +++ b/lib/earmark_parser/block/list.ex @@ -14,4 +14,5 @@ defmodule EarmarkParser.Block.List do start: "", type: :ul end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/list_item.ex b/lib/earmark_parser/block/list_item.ex index e575c75..de9d682 100644 --- a/lib/earmark_parser/block/list_item.ex +++ b/lib/earmark_parser/block/list_item.ex @@ -9,4 +9,5 @@ defmodule EarmarkParser.Block.ListItem do spaced?: true, type: :ul end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/para.ex b/lib/earmark_parser/block/para.ex index ef015cb..4e35d7d 100644 --- a/lib/earmark_parser/block/para.ex +++ b/lib/earmark_parser/block/para.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.Para do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, lines: [] end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/ruler.ex b/lib/earmark_parser/block/ruler.ex index 75a4aa6..17c8a30 100644 --- a/lib/earmark_parser/block/ruler.ex +++ b/lib/earmark_parser/block/ruler.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.Ruler do @moduledoc false defstruct lnb: 0, annotation: nil, attrs: nil, type: nil end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/table.ex b/lib/earmark_parser/block/table.ex index 33a4988..fb9b90b 100644 --- a/lib/earmark_parser/block/table.ex +++ b/lib/earmark_parser/block/table.ex @@ -6,4 +6,5 @@ defmodule EarmarkParser.Block.Table do %__MODULE__{alignments: Elixir.List.duplicate(:left, n)} end end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/block/text.ex b/lib/earmark_parser/block/text.ex index ac96550..a0a2d8d 100644 --- a/lib/earmark_parser/block/text.ex +++ b/lib/earmark_parser/block/text.ex @@ -2,4 +2,5 @@ defmodule EarmarkParser.Block.Text do @moduledoc false defstruct attrs: nil, lnb: 0, annotation: nil, line: "" end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/context.ex b/lib/earmark_parser/context.ex index d57f865..ec139ac 100644 --- a/lib/earmark_parser/context.ex +++ b/lib/earmark_parser/context.ex @@ -52,29 +52,34 @@ defmodule EarmarkParser.Context do %__MODULE__{referenced_footnote_ids: new} = context2 ) do context_ = _merge_messages(context1, context2) - %{context_| referenced_footnote_ids: MapSet.union(orig, new)} + %{context_ | referenced_footnote_ids: MapSet.union(orig, new)} end defp _merge_messages(context, context_or_messages) + defp _merge_messages(context, %__MODULE__{options: %Options{messages: messages}}) do _merge_messages(context, messages) end + defp _merge_messages(context, messages) do - %{context | options: %{context.options|messages: MapSet.union(context.options.messages, messages)}} + %{context | options: %{context.options | messages: MapSet.union(context.options.messages, messages)}} end + defp _prepend(ctxt, []) do + ctxt + end - defp _prepend(ctxt, []), do: ctxt - - defp _prepend(%{value: value} = ctxt, {:comment, _, _, _} = ct), - do: %{ctxt | value: [ct | value]} + defp _prepend(%{value: value} = ctxt, {:comment, _, _, _} = ct) do + %{ctxt | value: [ct | value]} + end defp _prepend(%{value: value} = ctxt, tuple) when is_tuple(tuple) do %{ctxt | value: [tuple | value] |> List.flatten()} end - defp _prepend(%{value: value} = ctxt, list) when is_list(list), - do: %{ctxt | value: List.flatten(list ++ value)} + defp _prepend(%{value: value} = ctxt, list) when is_list(list) do + %{ctxt | value: List.flatten(list ++ value)} + end @doc """ Convenience method to prepend to the value list @@ -83,7 +88,9 @@ defmodule EarmarkParser.Context do %{ctx | value: value} end - def clear_value(%__MODULE__{} = ctx), do: %{ctx | value: []} + def clear_value(%__MODULE__{} = ctx) do + %{ctx | value: []} + end # this is called by the command line processor to update # the inline-specific rules in light of any options @@ -109,12 +116,14 @@ defmodule EarmarkParser.Context do else "" end + math = if options.math do "$" else "" end + rule_updates = if options.gfm do rules = [ diff --git a/lib/earmark_parser/enum/ext.ex b/lib/earmark_parser/enum/ext.ex index b23ffc1..9a2c405 100644 --- a/lib/earmark_parser/enum/ext.ex +++ b/lib/earmark_parser/enum/ext.ex @@ -21,10 +21,12 @@ defmodule EarmarkParser.Enum.Ext do penalty concerning the complexity of the reducer function """ def reduce_with_end(collection, initial_acc, reducer_fn) + def reduce_with_end([], acc, reducer_fn) do reducer_fn.(:end, acc) end - def reduce_with_end([ele|rest], acc, reducer_fn) do + + def reduce_with_end([ele | rest], acc, reducer_fn) do reduce_with_end(rest, reducer_fn.({:element, ele}, acc), reducer_fn) end @@ -45,11 +47,17 @@ defmodule EarmarkParser.Enum.Ext do # Helpers {{{ defp _reverse_map_reduce(list, acc, result, fun) - defp _reverse_map_reduce([], acc, result, _fun), do: {result, acc} - defp _reverse_map_reduce([fst|rst], acc, result, fun) do + + defp _reverse_map_reduce([], acc, result, _fun) do + {result, acc} + end + + defp _reverse_map_reduce([fst | rst], acc, result, fun) do {new_ele, new_acc} = fun.(fst, acc) - _reverse_map_reduce(rst, new_acc, [new_ele|result], fun) + _reverse_map_reduce(rst, new_acc, [new_ele | result], fun) end + # }}} end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/helpers.ex b/lib/earmark_parser/helpers.ex index 8ecdb33..a075102 100644 --- a/lib/earmark_parser/helpers.ex +++ b/lib/earmark_parser/helpers.ex @@ -58,13 +58,25 @@ defmodule EarmarkParser.Helpers do end end - defp _trim_line({line, annot}), - do: {line |> String.trim_trailing("\n") |> String.trim_trailing("\r"), annot} + defp _trim_line({line, annot}) do + {line |> String.trim_trailing("\n") |> String.trim_trailing("\r"), annot} + end - defp pad(1), do: " " - defp pad(2), do: " " - defp pad(3), do: " " - defp pad(4), do: " " + defp pad(1) do + " " + end + + defp pad(2) do + " " + end + + defp pad(3) do + " " + end + + defp pad(4) do + " " + end @doc """ `Regex.replace` with the arguments in the correct order @@ -80,7 +92,9 @@ defmodule EarmarkParser.Helpers do convert non-entity ampersands. """ - def escape(html), do: _escape(Regex.replace(~r{&(?!#?\w+;)}, html, "&")) + def escape(html) do + _escape(Regex.replace(~r{&(?!#?\w+;)}, html, "&")) + end defp _escape(html) do html diff --git a/lib/earmark_parser/helpers/ast_helpers.ex b/lib/earmark_parser/helpers/ast_helpers.ex index c9cf30d..0686279 100644 --- a/lib/earmark_parser/helpers/ast_helpers.ex +++ b/lib/earmark_parser/helpers/ast_helpers.ex @@ -1,5 +1,4 @@ defmodule EarmarkParser.Helpers.AstHelpers do - @moduledoc false import EarmarkParser.Ast.Emitter @@ -9,29 +8,41 @@ defmodule EarmarkParser.Helpers.AstHelpers do @doc false def annotate(node, from_block) - def annotate(node, %{annotation: nil}), do: node - def annotate({tag, atts, children, meta}, %{annotation: annotation}), - do: {tag, atts, children, Map.put(meta, :annotation, annotation)} - def annotate({tag, atts, children, meta}, annotation), - do: {tag, atts, children, Map.put(meta, :annotation, annotation)} + + def annotate(node, %{annotation: nil}) do + node + end + + def annotate({tag, atts, children, meta}, %{annotation: annotation}) do + {tag, atts, children, Map.put(meta, :annotation, annotation)} + end + + def annotate({tag, atts, children, meta}, annotation) do + {tag, atts, children, Map.put(meta, :annotation, annotation)} + end @doc false def attrs_to_string_keys(key_value_pair) + def attrs_to_string_keys({k, vs}) when is_list(vs) do {to_string(k), Enum.join(vs, " ")} end + def attrs_to_string_keys({k, vs}) do - {to_string(k),to_string(vs)} + {to_string(k), to_string(vs)} end @doc false def augment_tag_with_ial(tags, ial, src) - def augment_tag_with_ial([{t, a, c, m}|tags], atts, _src) do - [{t, merge_attrs(a, atts), c, m}|tags] + + def augment_tag_with_ial([{t, a, c, m} | tags], atts, _src) do + [{t, merge_attrs(a, atts), c, m} | tags] end + def augment_tag_with_ial([], _atts, _src) do [] end + def augment_tag_with_ial([any], _atts, src) do [any <> src] end @@ -41,7 +52,8 @@ defmodule EarmarkParser.Helpers.AstHelpers do classes = ["" | String.split(prefix || "")] |> Enum.map(fn pfx -> "#{pfx}#{language}" end) - {"class", classes |> Enum.join(" ")} + + {"class", classes |> Enum.join(" ")} end @doc false @@ -84,7 +96,6 @@ defmodule EarmarkParser.Helpers.AstHelpers do emit("a", text, href: _encode(url)) end - ############################################## # add attributes to the outer tag in a block # ############################################## @@ -94,15 +105,24 @@ defmodule EarmarkParser.Helpers.AstHelpers do |> String.split(~r<%[\da-f]{2}>i, include_captures: true) |> Enum.chunk_every(2) |> Enum.map(&_encode_chunk/1) - |> IO.chardata_to_string + |> IO.chardata_to_string() + end + + defp _encode_chunk([encodable, verbatim]) do + [URI.encode(encodable), verbatim] end - defp _encode_chunk([encodable, verbatim]), do: [URI.encode(encodable), verbatim] - defp _encode_chunk([encodable]), do: URI.encode(encodable) + defp _encode_chunk([encodable]) do + URI.encode(encodable) + end @doc false def merge_attrs(maybe_atts, new_atts) - def merge_attrs(nil, new_atts), do: new_atts + + def merge_attrs(nil, new_atts) do + new_atts + end + def merge_attrs(atts, new) when is_list(atts) do atts |> Enum.into(%{}) @@ -117,13 +137,14 @@ defmodule EarmarkParser.Helpers.AstHelpers do end defp _value_merger(key, val1, val2) + defp _value_merger(_, val1, val2) when is_list(val1) do val1 ++ [val2] end + defp _value_merger(_, val1, val2) do [val1, val2] end - - end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/helpers/attr_parser.ex b/lib/earmark_parser/helpers/attr_parser.ex index 398833f..64fd722 100644 --- a/lib/earmark_parser/helpers/attr_parser.ex +++ b/lib/earmark_parser/helpers/attr_parser.ex @@ -1,61 +1,71 @@ defmodule EarmarkParser.Helpers.AttrParser do - @moduledoc false - import EarmarkParser.Helpers.StringHelpers, only: [ behead: 2 ] + import EarmarkParser.Helpers.StringHelpers, only: [behead: 2] import EarmarkParser.Message, only: [add_message: 2] - - @type errorlist :: list(String.t) + @type errorlist :: list(String.t()) def parse_attrs(context, attrs, lnb) do - { attrs, errors } = _parse_attrs(%{}, attrs, [], lnb) - { add_errors(context, errors, lnb), attrs } + {attrs, errors} = _parse_attrs(%{}, attrs, [], lnb) + {add_errors(context, errors, lnb), attrs} end defp _parse_attrs(dict, attrs, errors, lnb) do cond do - Regex.match?(~r{^\s*$}, attrs) -> {dict, errors} + Regex.match?(~r{^\s*$}, attrs) -> + {dict, errors} match = Regex.run(~r{^\.(\S+)\s*}, attrs) -> - [ leader, class ] = match - Map.update(dict, "class", [ class ], &[ class | &1]) - |> _parse_attrs(behead(attrs, leader), errors, lnb) + [leader, class] = match + + Map.update(dict, "class", [class], &[class | &1]) + |> _parse_attrs(behead(attrs, leader), errors, lnb) match = Regex.run(~r{^\#(\S+)\s*}, attrs) -> - [ leader, id ] = match - Map.update(dict, "id", [ id ], &[ id | &1]) - |> _parse_attrs(behead(attrs, leader), errors, lnb) + [leader, id] = match + + Map.update(dict, "id", [id], &[id | &1]) + |> _parse_attrs(behead(attrs, leader), errors, lnb) # Might we being running into escape issues here too? - match = Regex.run(~r{^(\S+)=\'([^\']*)'\s*}, attrs) -> #' - [ leader, name, value ] = match - Map.update(dict, name, [ value ], &[ value | &1]) + # ' + match = Regex.run(~r{^(\S+)=\'([^\']*)'\s*}, attrs) -> + [leader, name, value] = match + + Map.update(dict, name, [value], &[value | &1]) |> _parse_attrs(behead(attrs, leader), errors, lnb) # Might we being running into escape issues here too? - match = Regex.run(~r{^(\S+)=\"([^\"]*)"\s*}, attrs) -> #" - [ leader, name, value ] = match - Map.update(dict, name, [ value ], &[ value | &1]) + # " + match = Regex.run(~r{^(\S+)=\"([^\"]*)"\s*}, attrs) -> + [leader, name, value] = match + + Map.update(dict, name, [value], &[value | &1]) |> _parse_attrs(behead(attrs, leader), errors, lnb) match = Regex.run(~r{^(\S+)=(\S+)\s*}, attrs) -> - [ leader, name, value ] = match - Map.update(dict, name, [ value ], &[ value | &1]) - |> _parse_attrs(behead(attrs, leader), errors, lnb) + [leader, name, value] = match + + Map.update(dict, name, [value], &[value | &1]) + |> _parse_attrs(behead(attrs, leader), errors, lnb) match = Regex.run(~r{^(\S+)\s*(.*)}, attrs) -> - [ _, incorrect, rest ] = match - _parse_attrs(dict, rest, [ incorrect | errors ], lnb) + [_, incorrect, rest] = match + _parse_attrs(dict, rest, [incorrect | errors], lnb) :otherwise -> - {dict, [attrs | errors ]} + {dict, [attrs | errors]} end end - defp add_errors(context, [], _lnb), do: context - defp add_errors(context, errors, lnb), do: add_message(context, {:warning, lnb, "Illegal attributes #{inspect errors} ignored in IAL"}) + defp add_errors(context, [], _lnb) do + context + end + defp add_errors(context, errors, lnb) do + add_message(context, {:warning, lnb, "Illegal attributes #{inspect(errors)} ignored in IAL"}) + end end # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/helpers/html_parser.ex b/lib/earmark_parser/helpers/html_parser.ex index 23a05fc..d210ca3 100644 --- a/lib/earmark_parser/helpers/html_parser.ex +++ b/lib/earmark_parser/helpers/html_parser.ex @@ -1,17 +1,17 @@ defmodule EarmarkParser.Helpers.HtmlParser do - @moduledoc false import EarmarkParser.Helpers.StringHelpers, only: [behead: 2] import EarmarkParser.LineScanner, only: [void_tag?: 1] def parse_html(lines) - def parse_html([tag_line|rest]) do + + def parse_html([tag_line | rest]) do case _parse_tag(tag_line) do - { :ok, tag, "" } -> [_parse_rest(rest, tag, [])] - { :ok, tag, suffix } -> [_parse_rest(rest, tag, [suffix])] - { :ext, tag, "" } -> [_parse_rest(rest, tag, [])] - { :ext, tag, suffix } -> [_parse_rest(rest, tag, []), [suffix]] + {:ok, tag, ""} -> [_parse_rest(rest, tag, [])] + {:ok, tag, suffix} -> [_parse_rest(rest, tag, [suffix])] + {:ext, tag, ""} -> [_parse_rest(rest, tag, [])] + {:ext, tag, suffix} -> [_parse_rest(rest, tag, []), [suffix]] end end @@ -22,14 +22,16 @@ defmodule EarmarkParser.Helpers.HtmlParser do quoted_attr = ~r{\A ([-\w]+) \s* = \s* (["']) (.*?) \2 \s*}x case Regex.run(quoted_attr, string) do - [all, name, _delim, value] -> _parse_atts(behead(string, all), tag, [{name, value}|atts]) + [all, name, _delim, value] -> + _parse_atts(behead(string, all), tag, [{name, value} | atts]) + _ -> unquoted_attr = ~r{\A ([-\w]+) (?: \s* = \s* ([^&\s>]*))? \s*}x case Regex.run(unquoted_attr, string) do - [all, name, value] -> _parse_atts(behead(string, all), tag, [{name, value}|atts]) - [all, name] -> _parse_atts(behead(string, all), tag, [{name, name}|atts]) - _ -> _parse_tag_tail(string, tag, atts) + [all, name, value] -> _parse_atts(behead(string, all), tag, [{name, value} | atts]) + [all, name] -> _parse_atts(behead(string, all), tag, [{name, name} | atts]) + _ -> _parse_tag_tail(string, tag, atts) end end end @@ -37,6 +39,7 @@ defmodule EarmarkParser.Helpers.HtmlParser do # Are leading and trailing "-"s ok? defp _parse_tag(string) do tag_head = ~r{\A \s* <([-\w]+) \s*}x + case Regex.run(tag_head, string) do [all, tag] -> _parse_atts(behead(string, all), tag, []) end @@ -44,8 +47,9 @@ defmodule EarmarkParser.Helpers.HtmlParser do defp _parse_tag_tail(string, tag, atts) do tag_tail = ~r{\A .*? (/?)> \s* (.*) \z}x + case Regex.run(tag_tail, string) do - [_, closing, suffix] -> + [_, closing, suffix] -> suffix1 = String.replace(suffix, ~r{\s*.*}, "") _close_tag_tail(tag, atts, closing != "", suffix1) end @@ -53,9 +57,9 @@ defmodule EarmarkParser.Helpers.HtmlParser do defp _close_tag_tail(tag, atts, closing?, suffix) do if closing? || void_tag?(tag) do - {:ext, {tag, Enum.reverse(atts)}, suffix } + {:ext, {tag, Enum.reverse(atts)}, suffix} else - {:ok, {tag, Enum.reverse(atts)}, suffix } + {:ok, {tag, Enum.reverse(atts)}, suffix} end end @@ -64,26 +68,28 @@ defmodule EarmarkParser.Helpers.HtmlParser do @verbatim %{verbatim: true} defp _parse_rest(rest, tag_tpl, lines) + defp _parse_rest([], tag_tpl, lines) do _tag_append(tag_tpl, lines) end - defp _parse_rest([last_line], {tag, _}=tag_tpl, lines) do + + defp _parse_rest([last_line], {tag, _} = tag_tpl, lines) do case Regex.run(~r{\A\s*\s*(.*)}, last_line) do - nil -> _tag_append(tag_tpl, [last_line|lines]) - [_, ""] -> _tag_append(tag_tpl, lines) + nil -> _tag_append(tag_tpl, [last_line | lines]) + [_, ""] -> _tag_append(tag_tpl, lines) [_, suffix] -> [_tag_append(tag_tpl, lines), suffix] end end - defp _parse_rest([inner_line|rest], tag_tpl, lines) do - _parse_rest(rest, tag_tpl, [inner_line|lines]) - end + defp _parse_rest([inner_line | rest], tag_tpl, lines) do + _parse_rest(rest, tag_tpl, [inner_line | lines]) + end defp _tag_append(tag_tpl, lines) do tag_tpl |> Tuple.insert_at(2, Enum.reverse(lines)) |> Tuple.insert_at(3, @verbatim) end - end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/helpers/leex_helpers.ex b/lib/earmark_parser/helpers/leex_helpers.ex index 12c06f2..7043f6f 100644 --- a/lib/earmark_parser/helpers/leex_helpers.ex +++ b/lib/earmark_parser/helpers/leex_helpers.ex @@ -1,31 +1,36 @@ defmodule EarmarkParser.Helpers.LeexHelpers do - @moduledoc false @doc """ Allows to lex an Elixir string with a leex lexer and returns the tokens as needed for a yecc parser. """ - def lex text, with: lexer do + def lex(text, with: lexer) do case text - |> String.to_charlist() - |> lexer.string() do - {:ok, tokens, _} -> tokens - end + |> String.to_charlist() + |> lexer.string() do + {:ok, tokens, _} -> tokens + end end - def tokenize line, with: lexer do + def tokenize(line, with: lexer) do {:ok, tokens, _} = - line - |> to_charlist() - |> lexer.string() - elixirize_tokens(tokens,[]) + line + |> to_charlist() + |> lexer.string() + + elixirize_tokens(tokens, []) |> Enum.reverse() end defp elixirize_tokens(tokens, rest) - defp elixirize_tokens([], result), do: result - defp elixirize_tokens([{token, _, text}|rest], result), do: elixirize_tokens(rest, [{token,to_string(text)}|result]) + defp elixirize_tokens([], result) do + result + end + + defp elixirize_tokens([{token, _, text} | rest], result) do + elixirize_tokens(rest, [{token, to_string(text)} | result]) + end end # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/helpers/line_helpers.ex b/lib/earmark_parser/helpers/line_helpers.ex index 0f5398f..7fa8d88 100644 --- a/lib/earmark_parser/helpers/line_helpers.ex +++ b/lib/earmark_parser/helpers/line_helpers.ex @@ -1,17 +1,31 @@ defmodule EarmarkParser.Helpers.LineHelpers do - @moduledoc false alias EarmarkParser.Line - def blank?(%Line.Blank{}), do: true - def blank?(_), do: false + def blank?(%Line.Blank{}) do + true + end + + def blank?(_) do + false + end + + def blockquote_or_text?(%Line.BlockQuote{}) do + true + end - def blockquote_or_text?(%Line.BlockQuote{}), do: true - def blockquote_or_text?(struct), do: text?(struct) + def blockquote_or_text?(struct) do + text?(struct) + end - def indent_or_blank?(%Line.Indent{}), do: true - def indent_or_blank?(line), do: blank?(line) + def indent_or_blank?(%Line.Indent{}) do + true + end + + def indent_or_blank?(line) do + blank?(line) + end # Gruber's tests have # @@ -27,10 +41,18 @@ defmodule EarmarkParser.Helpers.LineHelpers do # # I think the second is a better interpretation, so I commented # out the 2nd match below. - def text?(%Line.Text{}), do: true - def text?(%Line.TableLine{}), do: true -# def text?(%Line.ListItem{}), do: true - def text?(_), do: false + def text?(%Line.Text{}) do + true + end + + def text?(%Line.TableLine{}) do + true + end + # def text?(%Line.ListItem{}), do: true + def text?(_) do + false + end end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/helpers/lookahead_helpers.ex b/lib/earmark_parser/helpers/lookahead_helpers.ex index 86243d3..7b66c0c 100644 --- a/lib/earmark_parser/helpers/lookahead_helpers.ex +++ b/lib/earmark_parser/helpers/lookahead_helpers.ex @@ -1,5 +1,4 @@ defmodule EarmarkParser.Helpers.LookaheadHelpers do - @moduledoc false import EarmarkParser.Helpers.LeexHelpers @@ -41,22 +40,31 @@ defmodule EarmarkParser.Helpers.LookaheadHelpers do defp has_still_opening_backtix(tokens, opened_so_far) # Empty, done, but take care of tangeling escape (\) - defp has_still_opening_backtix([], :force_outside), do: nil - defp has_still_opening_backtix([], open), do: open + defp has_still_opening_backtix([], :force_outside) do + nil + end + + defp has_still_opening_backtix([], open) do + open + end # Outside state, represented by nil - defp has_still_opening_backtix([{:other, _} | rest], nil), - do: has_still_opening_backtix(rest, nil) + defp has_still_opening_backtix([{:other, _} | rest], nil) do + has_still_opening_backtix(rest, nil) + end - defp has_still_opening_backtix([{:backtix, btx} | rest], nil), - do: has_still_opening_backtix(rest, {:new, btx}) + defp has_still_opening_backtix([{:backtix, btx} | rest], nil) do + has_still_opening_backtix(rest, {:new, btx}) + end - defp has_still_opening_backtix([{:escape, _} | rest], nil), - do: has_still_opening_backtix(rest, :force_outside) + defp has_still_opening_backtix([{:escape, _} | rest], nil) do + has_still_opening_backtix(rest, :force_outside) + end # Next state forced outside, represented by :force_outside - defp has_still_opening_backtix([_ | rest], :force_outside), - do: has_still_opening_backtix(rest, nil) + defp has_still_opening_backtix([_ | rest], :force_outside) do + has_still_opening_backtix(rest, nil) + end # Inside state, represented by { :old | :new, btx } defp has_still_opening_backtix([{:backtix, btx} | rest], open = {_, openedbtx}) do @@ -67,8 +75,9 @@ defmodule EarmarkParser.Helpers.LookaheadHelpers do end end - defp has_still_opening_backtix([_ | rest], open = {_, _}), - do: has_still_opening_backtix(rest, open) + defp has_still_opening_backtix([_ | rest], open = {_, _}) do + has_still_opening_backtix(rest, open) + end end # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/helpers/pure_link_helpers.ex b/lib/earmark_parser/helpers/pure_link_helpers.ex index e30332f..8064b86 100644 --- a/lib/earmark_parser/helpers/pure_link_helpers.ex +++ b/lib/earmark_parser/helpers/pure_link_helpers.ex @@ -56,9 +56,13 @@ defmodule EarmarkParser.Helpers.PureLinkHelpers do # balance parens and return unbalanced *trailing* paren count defp balance_parens(reverse_text, trailing_count, non_trailing_count \\ 0) - defp balance_parens(<<>>, trailing_paren_count, _non_trailing_count), do: trailing_paren_count + defp balance_parens(<<>>, trailing_paren_count, _non_trailing_count) do + trailing_paren_count + end - defp balance_parens(_reverse_text, 0, _non_trailing_count), do: 0 + defp balance_parens(_reverse_text, 0, _non_trailing_count) do + 0 + end defp balance_parens(")" <> rest, trailing_paren_count, non_trailing_count) do balance_parens(rest, trailing_paren_count, non_trailing_count + 1) @@ -73,7 +77,7 @@ defmodule EarmarkParser.Helpers.PureLinkHelpers do end end - defp balance_parens(<<_::utf8,rest::binary>>, trailing_paren_count, non_trailing_count) do + defp balance_parens(<<_::utf8, rest::binary>>, trailing_paren_count, non_trailing_count) do balance_parens(rest, trailing_paren_count, non_trailing_count) end end diff --git a/lib/earmark_parser/helpers/reparse_helpers.ex b/lib/earmark_parser/helpers/reparse_helpers.ex index d91f0e4..2cd7fca 100644 --- a/lib/earmark_parser/helpers/reparse_helpers.ex +++ b/lib/earmark_parser/helpers/reparse_helpers.ex @@ -1,5 +1,4 @@ defmodule EarmarkParser.Helpers.ReparseHelpers do - @moduledoc false alias EarmarkParser.Line @@ -10,13 +9,15 @@ defmodule EarmarkParser.Helpers.ReparseHelpers do """ # Add additional spaces for any indentation past level 1 def properly_indent(%Line.Indent{level: level, content: content}, target_level) - when level == target_level do + when level == target_level do content end + def properly_indent(%Line.Indent{level: level, content: content}, target_level) - when level > target_level do - String.duplicate(" ", level-target_level) <> content + when level > target_level do + String.duplicate(" ", level - target_level) <> content end + def properly_indent(line, _) do line.content end diff --git a/lib/earmark_parser/helpers/string_helpers.ex b/lib/earmark_parser/helpers/string_helpers.ex index 4b3b5a8..6795e24 100644 --- a/lib/earmark_parser/helpers/string_helpers.ex +++ b/lib/earmark_parser/helpers/string_helpers.ex @@ -1,5 +1,4 @@ defmodule EarmarkParser.Helpers.StringHelpers do - @moduledoc false @doc """ @@ -13,6 +12,6 @@ defmodule EarmarkParser.Helpers.StringHelpers do def behead(str, leading_string) do behead(str, String.length(leading_string)) end - end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/helpers/yecc_helpers.ex b/lib/earmark_parser/helpers/yecc_helpers.ex index 1d232dd..baa103d 100644 --- a/lib/earmark_parser/helpers/yecc_helpers.ex +++ b/lib/earmark_parser/helpers/yecc_helpers.ex @@ -1,16 +1,15 @@ defmodule EarmarkParser.Helpers.YeccHelpers do - @moduledoc false import EarmarkParser.Helpers.LeexHelpers, only: [lex: 2] - def parse!( text, lexer: lexer, parser: parser ) do + def parse!(text, lexer: lexer, parser: parser) do case parse(text, lexer: lexer, parser: parser) do - {:ok, ast} -> ast - {:error, _} -> nil + {:ok, ast} -> ast + {:error, _} -> nil end end - def parse( text, lexer: lexer, parser: parser ) do + def parse(text, lexer: lexer, parser: parser) do with tokens <- lex(text, with: lexer) do parser.parse(tokens) end diff --git a/lib/earmark_parser/line.ex b/lib/earmark_parser/line.ex index 54ce40b..df4d142 100644 --- a/lib/earmark_parser/line.ex +++ b/lib/earmark_parser/line.ex @@ -1,66 +1,67 @@ defmodule EarmarkParser.Line do - @moduledoc false -defmodule Blank do + defmodule Blank do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, content: "") end -defmodule Ruler do + + defmodule Ruler do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, type: "- or * or _") end -defmodule Heading do + defmodule Heading do @moduledoc false defstruct(annotation: nil, ial: nil, lnb: 0, line: "", indent: -1, level: 1, content: "inline text") end -defmodule BlockQuote do + defmodule BlockQuote do @moduledoc false defstruct(annotation: nil, ial: nil, lnb: 0, line: "", indent: -1, content: "text") end -defmodule Indent do + defmodule Indent do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, level: 0, content: "text") end -defmodule Fence do + defmodule Fence do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, delimiter: "~ or `", language: nil) end -defmodule HtmlOpenTag do + defmodule HtmlOpenTag do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, tag: "", content: "") end -defmodule HtmlCloseTag do + defmodule HtmlCloseTag do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, tag: "<... to eol") end -defmodule HtmlComment do + + defmodule HtmlComment do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, complete: true) end -defmodule HtmlOneLine do + defmodule HtmlOneLine do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, tag: "", content: "") end -defmodule IdDef do + defmodule IdDef do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, id: nil, url: nil, title: nil) end -defmodule FnDef do + defmodule FnDef do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, id: nil, content: "text") end -defmodule ListItem do + defmodule ListItem do @moduledoc false defstruct( annotation: nil, @@ -76,23 +77,34 @@ defmodule ListItem do ) end -defmodule SetextUnderlineHeading do + defmodule SetextUnderlineHeading do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, level: 1) end -defmodule TableLine do + defmodule TableLine do @moduledoc false - defstruct(annotation: nil, lnb: 0, line: "", indent: -1, content: "", columns: 0, is_header: false, needs_header: false) + defstruct( + annotation: nil, + lnb: 0, + line: "", + indent: -1, + content: "", + columns: 0, + is_header: false, + needs_header: false + ) end -defmodule Ial do + defmodule Ial do @moduledoc false defstruct(annotation: nil, ial: nil, lnb: 0, line: "", indent: -1, attrs: "", verbatim: "") end -defmodule Text do + + defmodule Text do @moduledoc false defstruct(annotation: nil, lnb: 0, line: "", indent: -1, content: "") end end + # SPDX-License-Identifier: Apache-2.0 diff --git a/lib/earmark_parser/line_scanner.ex b/lib/earmark_parser/line_scanner.ex index c5a56a9..0ac8760 100644 --- a/lib/earmark_parser/line_scanner.ex +++ b/lib/earmark_parser/line_scanner.ex @@ -7,7 +7,9 @@ defmodule EarmarkParser.LineScanner do # This is the re that matches the ridiculous "[id]: url title" syntax @doc false - def void_tag?(tag), do: Regex.match?(void_tag_rgx(), "<#{tag}>") + def void_tag?(tag) do + Regex.match?(void_tag_rgx(), "<#{tag}>") + end def scan_lines(lines, options, recursive) do _lines_with_count(lines, options.line - 1) @@ -15,8 +17,9 @@ defmodule EarmarkParser.LineScanner do end def type_of(line, recursive) - when is_boolean(recursive), - do: type_of(line, %Options{}, recursive) + when is_boolean(recursive) do + type_of(line, %Options{}, recursive) + end def type_of({line, lnb}, options = %Options{annotations: annotations}, recursive) when is_binary(line) do @@ -112,7 +115,14 @@ defmodule EarmarkParser.LineScanner do match = lt_four? && id_def_matches(content) -> [_, id, url | title] = match - title = if(Enum.empty?(title), do: "", else: hd(title)) + + title = + if(Enum.empty?(title)) do + "" + else + hd(title) + end + %Line.IdDef{id: id, url: url, title: title, indent: indent, line: line} match = options.footnotes && footnote_def_matches(line) -> @@ -153,7 +163,7 @@ defmodule EarmarkParser.LineScanner do } line - |> String.replace(table_header_rgx(), "") + |> String.replace(table_header_rgx(), "") |> String.match?(table_first_column_rgx()) -> columns = _split_table_columns(line) @@ -180,7 +190,14 @@ defmodule EarmarkParser.LineScanner do match = set_ext_underline_matches(line) -> [_, type] = match - level = if(String.starts_with?(type, "="), do: 1, else: 2) + + level = + if(String.starts_with?(type, "=")) do + 1 + else + 2 + end + %Line.SetextUnderlineHeading{level: level, indent: 0, line: line} match = lt_four? && ial_matches(content) -> @@ -192,17 +209,24 @@ defmodule EarmarkParser.LineScanner do end end - defp _attribute_escape(string), - do: - string - |> String.replace("&", "&") - |> String.replace("<", "<") + defp _attribute_escape(string) do + string + |> String.replace("&", "&") + |> String.replace("<", "<") + end defp _create_list_item(match, indent, line) defp _create_list_item([_, bullet, spaces, text], indent, line) do sl = byte_size(spaces) - sl1 = if sl > 3, do: 1, else: sl + 1 + + sl1 = + if sl > 3 do + 1 + else + sl + 1 + end + sl2 = sl1 + byte_size(bullet) %Line.ListItem{ @@ -220,17 +244,21 @@ defmodule EarmarkParser.LineScanner do _create_text(line, content, indent) end - defp _create_text(line, "", indent), - do: %Line.Blank{indent: indent, line: line} + defp _create_text(line, "", indent) do + %Line.Blank{indent: indent, line: line} + end - defp _create_text(line, content, indent), - do: %Line.Text{content: content, indent: indent, line: line} + defp _create_text(line, content, indent) do + %Line.Text{content: content, indent: indent, line: line} + end - defp _count_indent(<>, indent) when space in [?\s, ?\t], - do: _count_indent(rest, indent + 1) + defp _count_indent(<>, indent) when space in [?\s, ?\t] do + _count_indent(rest, indent + 1) + end - defp _count_indent(rest, indent), - do: {rest, indent} + defp _count_indent(rest, indent) do + {rest, indent} + end defp _lines_with_count(lines, offset) do Enum.zip(lines, offset..(offset + Enum.count(lines))) @@ -250,9 +278,13 @@ defmodule EarmarkParser.LineScanner do end end - defp _with_lookahead([], _options, _recursive), do: [] + defp _with_lookahead([], _options, _recursive) do + [] + end - defp _lookahead_until_match([], _, _, _), do: [] + defp _lookahead_until_match([], _, _, _) do + [] + end defp _lookahead_until_match([{line, lnb} | lines], regex, options, recursive) do if line =~ regex do diff --git a/lib/earmark_parser/line_scanner/rgx.ex b/lib/earmark_parser/line_scanner/rgx.ex index 168ca6d..dfc8185 100644 --- a/lib/earmark_parser/line_scanner/rgx.ex +++ b/lib/earmark_parser/line_scanner/rgx.ex @@ -32,42 +32,66 @@ defmodule EarmarkParser.LineScanner.Rgx do void_tag_matches: 1, void_tag_rgx: 0} - def block_quote_matches(content), do: Regex.run(~r/\A > \s? (.*)/x, content) + def block_quote_matches(content) do + Regex.run(~r/\A > \s? (.*)/x, content) + end - def bullet_list_item_matches(content), do: Regex.run(~r/\A ([-*+]) \s (\s*) (.*)/x, content) + def bullet_list_item_matches(content) do + Regex.run(~r/\A ([-*+]) \s (\s*) (.*)/x, content) + end - def dash_ruler_matches(content), do: Regex.run(~r/\A (?:-\s?){3,} \z/x, content) + def dash_ruler_matches(content) do + Regex.run(~r/\A (?:-\s?){3,} \z/x, content) + end - def fence_matches(content), - do: Regex.run(~r/\A (\s*) (`{3,} | ~{3,}) \s* ([^`\s]*) \s* \z/ux, content) + def fence_matches(content) do + Regex.run(~r/\A (\s*) (`{3,} | ~{3,}) \s* ([^`\s]*) \s* \z/ux, content) + end - def footnote_def_matches(content), do: Regex.run(~r/\A \[\^([^\s\]]+)\] : \s+ (.*)/x, content) + def footnote_def_matches(content) do + Regex.run(~r/\A \[\^([^\s\]]+)\] : \s+ (.*)/x, content) + end # @heading ~r/\A # (\#{1,6}) \s+ # (?|(.*?) \s* #* \s* \z # | # (.*))/ux - def heading_matches(content), - do: Regex.run(~r/\A(\#{1,6})\s+(?|(.*?)\s*#*\s*\z|(.*))/u, content) + def heading_matches(content) do + Regex.run(~r/\A(\#{1,6})\s+(?|(.*?)\s*#*\s*\z|(.*))/u, content) + end - def html_close_tag_matches(content), do: Regex.run(~r/\A < \/ ([-\w]+?) >/x, content) + def html_close_tag_matches(content) do + Regex.run(~r/\A < \/ ([-\w]+?) >/x, content) + end - def html_comment_start_matches(content), do: Regex.run(~r/\A " - ast = {:comment, [], [" Hello "], %{comment: true}} + ast = {:comment, [], [" Hello "], %{comment: true}} messages = [] assert as_ast(markdown) == {:ok, [ast], messages} @@ -14,7 +14,7 @@ defmodule Acceptance.Ast.CommentTest do test "more lines" do markdown = "" - ast = {:comment, [], [" Hello", " World"], %{comment: true}} + ast = {:comment, [], [" Hello", " World"], %{comment: true}} messages = [] assert as_ast(markdown) == {:ok, [ast], messages} @@ -22,7 +22,7 @@ defmodule Acceptance.Ast.CommentTest do test "what about the closing" do markdown = "garbish" - ast = {:comment, [], [" Hello", " World "], %{comment: true}} + ast = {:comment, [], [" Hello", " World "], %{comment: true}} messages = [] assert as_ast(markdown) == {:ok, [ast], messages} @@ -34,7 +34,8 @@ defmodule Acceptance.Ast.CommentTest do ```elixir World --> garbish """ - ast = {:comment, [], [" Hello", "```elixir", " World "], %{comment: true}} + + ast = {:comment, [], [" Hello", "```elixir", " World "], %{comment: true}} messages = [] assert as_ast(markdown) == {:ok, [ast], messages} @@ -45,12 +46,13 @@ defmodule Acceptance.Ast.CommentTest do