Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
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
6 changes: 6 additions & 0 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
pull_request:
push:
branches:
- i164-use-formatter
- master

jobs:
Expand Down Expand Up @@ -83,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
Expand Down
Empty file added 2
Empty file.
7 changes: 7 additions & 0 deletions README.md.eex
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@

Pull Requests are happily accepted.

### mix format

Now we have decided to enforce formatting, when providing PRs please be sure that that `mix format --check-formatted` passes
because it will be tested in the GHA workflow

### Editing README

Please be aware of one _caveat_ when correcting/improving `README.md`.

The `README.md` is generated by the coammand mix task `xtra` from `README.md.eex` and
Expand Down
9 changes: 5 additions & 4 deletions lib/earmark_parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down
21 changes: 17 additions & 4 deletions lib/earmark_parser/ast/emitter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
51 changes: 39 additions & 12 deletions lib/earmark_parser/ast/inline.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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?)
Expand Down Expand Up @@ -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)\^}
Expand All @@ -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\\])\$}
Expand All @@ -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]+?)\$\$}
Expand All @@ -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{^
Expand Down Expand Up @@ -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
Expand All @@ -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}
Expand All @@ -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
Expand Down Expand Up @@ -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
72 changes: 46 additions & 26 deletions lib/earmark_parser/ast/renderer/ast_walker.ex
Original file line number Diff line number Diff line change
@@ -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
13 changes: 7 additions & 6 deletions lib/earmark_parser/ast/renderer/footnote_renderer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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", ["&#x21A9;"], a_attrs, %{verbatim: true}) | context1.value],
id: "fn:#{id}")
{[footnote_li_ast|ast], MapSet.union(errors, context1.options.messages), context}
emit("li", [emit("a", ["&#x21A9;"], 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
Loading
Loading