From 58bb9c4de170558e4bae9086e34e386dd1156593 Mon Sep 17 00:00:00 2001 From: RobertDober Date: Sun, 21 Feb 2021 19:02:19 +0100 Subject: [PATCH] Fixes: #403; --- RELEASE.md | 14 ++++---- lib/earmark.ex | 12 +++---- lib/earmark/message.ex | 4 +++ lib/earmark/options.ex | 33 +++++++++++++++++++ test/acceptance/html/illegal_options_test.exs | 30 +++++++++++++++++ 5 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 test/acceptance/html/illegal_options_test.exs diff --git a/RELEASE.md b/RELEASE.md index 9acaea1a..61e3b348 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -8,16 +8,18 @@ - fixing picture links in README.eex +- [403-warn-if-illegal-keyword-options-are-provided](https://github.com/robertdober/earmark_parser/issues/403) + - [401-option-to-disable-html-escapes](https://github.com/robertdober/earmark_parser/pull/401-to-disable-html-escapes) Kudos to [paradox460](https://github.com/paradox460) -- [397-typo fix](https://github.com/robertdober/earmark_parser/pull/397) - Kudos to [rubysolo](https://github.com/rubysolo) - +- [398-walk-ast-helper-and-ast-postprocessing-option](https://github.com/robertdober/earmark_parser/issues/398) +- [397-typo fix](https://github.com/robertdober/earmark_parser/pull/397) + Kudos to [rubysolo](https://github.com/rubysolo) # 1.4.13 2020-12-03 - + - A minor fix for the compact output option , Noo Issue, OMG ;) # 1.4.12 2020-11-27 @@ -27,10 +29,10 @@ Adapted the CLI to accept the wikilinks switch for `EarmarkParser` # 1.4.11 2020-11-26 - [394-compact-html-output](https://github.com/robertdober/earmark_parser/pull/394) - Kudos and Спасибо to [rinpatch](https://github.com/rinpatch) + Kudos and Спасибо to [rinpatch](https://github.com/rinpatch) - [387-treat-del-tag-as-compact-tag](https://github.com/pragdave/earmark/pull/387) - Kudos to [Médi-Rémi Hashim](https://github.com/mediremi) + Kudos to [Médi-Rémi Hashim](https://github.com/mediremi) - [383-smartyants-inside-code-blocks](https://github.com/robertdober/earmark_parser/issues/-) Kudos to [David Bernheisel](https://github.com/dbernheisel) diff --git a/lib/earmark.ex b/lib/earmark.ex index 1ee7f6ee..8703714d 100644 --- a/lib/earmark.ex +++ b/lib/earmark.ex @@ -186,7 +186,10 @@ defmodule Earmark do def as_html(lines, options \\ %Options{}) def as_html(lines, options) when is_list(options) do - as_html(lines, struct(Options, options)) + case Options.make_options(options) do + {:ok, options1} -> as_html(lines, options1) + {:error, messages} -> {:error, "", messages} + end end def as_html(lines, options) do @@ -225,12 +228,7 @@ defmodule Earmark do Otherwise it behaves exactly as `as_html`. """ def as_html!(lines, options \\ %Options{}) - - def as_html!(lines, options) when is_list(options) do - as_html!(lines, struct(Options, options)) - end - - def as_html!(lines, options = %Options{}) do + def as_html!(lines, options) do {_status, html, messages} = as_html(lines, options) emit_messages(messages, options) html diff --git a/lib/earmark/message.ex b/lib/earmark/message.ex index 4dabbd2f..3ac98c25 100644 --- a/lib/earmark/message.ex +++ b/lib/earmark/message.ex @@ -37,6 +37,10 @@ defmodule Earmark.Message do messages |> Enum.each(&emit_message(file, &1)) end + def emit_messages(messages, _) do + messages + |> Enum.each(&emit_message("", &1)) + end @doc """ For final output diff --git a/lib/earmark/options.ex b/lib/earmark/options.ex index 5b1e6871..d646aab6 100644 --- a/lib/earmark/options.ex +++ b/lib/earmark/options.ex @@ -65,10 +65,43 @@ defmodule Earmark.Options do end end + @doc false + def make_options(options) do + legal_keys = + __MODULE__ + |> struct() + |> Map.keys + |> MapSet.new + + given_keys = + options + |> Keyword.keys + |> MapSet.new + + violators = + MapSet.difference(given_keys, legal_keys) + + if MapSet.size(violators) == 0 do + {:ok, struct(__MODULE__, options)} + else + {:error, _format_errors(violators, options)} + end + end + @doc false def plugin_for_prefix(options, plugin_name) do Map.get(options.plugins, plugin_name, false) end + + defp _format_error(violator, options) do + {:warning, 0, "Unrecognized option #{violator}: #{Keyword.get(options, violator) |> inspect()} ignored"} + end + + defp _format_errors(violators, options) do + violators + |> Enum.map(&_format_error(&1, options)) + end + end # SPDX-License-Identifier: Apache-2.0 diff --git a/test/acceptance/html/illegal_options_test.exs b/test/acceptance/html/illegal_options_test.exs new file mode 100644 index 00000000..8295359d --- /dev/null +++ b/test/acceptance/html/illegal_options_test.exs @@ -0,0 +1,30 @@ +defmodule Test.Acceptance.Html.IllegalOptionsTest do + use ExUnit.Case + + import ExUnit.CaptureIO + import Earmark, only: [as_html: 2, as_html!: 2] + + describe "unrecognized options" do + test "with empty" do + messages = [ + {:warning, 0, "Unrecognized option no_such_option: true ignored"} + ] + assert as_html("", no_such_option: true) == {:error, "", messages} + end + test "with non empty" do + messages = [ + {:warning, 0, "Unrecognized option hello: 42 ignored"}, + {:warning, 0, "Unrecognized option no_such_option: true ignored"}, + ] + assert as_html("hello", no_such_option: true, hello: 42) == {:error, "", messages} + end + end + + test "with as_html!" do + error_messages = + capture_io(:stderr, fn -> + as_html!("hello", oops: Earmark) + end) + assert error_messages == ":0: warning: Unrecognized option oops: Earmark ignored\n" + end +end