Skip to content

Commit

Permalink
[#141943791] Markdown support
Browse files Browse the repository at this point in the history
  • Loading branch information
ferigis committed Mar 31, 2017
1 parent 5851873 commit 60ec73c
Show file tree
Hide file tree
Showing 14 changed files with 438 additions and 95 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ log/
*_plt
.DS_Store
doc/
_elixir_build/
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ This is the format (see [sheldon_config.erl](https://github.com/inaka/sheldon/bl
#{ ignore_words => [string()]
, ignore_patterns => [regex()]
, ignore_blocks => [ignore_block()]
, adapters => [adapter()]
}.
```
Then, if we call the previous `sheldon:check/1` but with configuration we can skip the error
Expand All @@ -60,6 +61,29 @@ Then, if we call the previous `sheldon:check/1` but with configuration we can sk
ok
```

## Adapters

Sometimes we have to check the spelling of formatted text but `sheldon` handles it as a plain text so we will face problems with that.
One example is `markdown` files, if we try to check them `sheldon` will complain about things like '##' or '\*something\*'.
For these cases `sheldon` provides `adapters`. An adapter is an Erlang module with an `adapt/1` function which will receive a line in `binary()` format and returns that line transformed.
For example, `sheldon` provides [markdown_adapter](https://github.com/inaka/sheldon/blob/master/src/adapter/markdown_adapter.erl) which converts from `markdown` to plain text.

In order to use them we only have to declare them in the config file:

```erlang
#{adapters => [markdown_adapter]}.
```

You can create your own adapter which fits your requirements, you only need to respect the `adapt/1` function signature.

```erlang
-spec adapt(binary()) -> iodata().
adapt(Line) ->
...
```

You can add all the adapters you want and they will be executed in order.

## Examples
Check [this](examples/README.md) out.

Expand All @@ -76,3 +100,4 @@ Check [this](examples/README.md) out.

- Erlang/OTP 19+ in order to use it.
- Erlang/OTP 19.0.2+ in order to test it.
- Elixir "~> 1.4"
3 changes: 2 additions & 1 deletion elvis.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
{config,
[#{dirs => ["src", "test"],
filter => "*.erl",
ruleset => erl_files
ruleset => erl_files,
rules => [{elvis_style, line_length, #{limit => 100}}]
},
#{dirs => ["."],
filter => "Makefile",
Expand Down
17 changes: 17 additions & 0 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
%% == Dependencies ==

{deps, [
{earmark, {elixir, "earmark" ,"1.2.0"}}
]}.

%% == Profiles ==
Expand Down Expand Up @@ -85,3 +86,19 @@
{base_plt_location, "."},
{base_plt_prefix, "sheldon"}
]}.

%% == Plugins ==
{plugins, [
{ rebar3_elixir_compile, ".*", {git, "https://github.com/barrel-db/rebar3_elixir_compile.git", {ref, "1c6c516"}}}
]}.

{provider_hooks, [
{pre, [{compile, {ex, compile}}]},
{pre, [{release, {ex, compile}}]}
]}.

{elixir_opts,
[
{env, dev}
]
}.
5 changes: 4 additions & 1 deletion rebar.lock
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
[].
[{<<"bunt">>,{elixir,"bunt","0.2.0"},2},
{<<"credo">>,{elixir,"credo","0.7.2"},1},
{<<"dialyxir">>,{elixir,"dialyxir","0.5.0"},1},
{<<"earmark">>,{elixir,"earmark","1.2.0"},0}].
73 changes: 73 additions & 0 deletions src/adapter/html_adapter.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
%%% @doc HTML Adapter. *Note* This is not the final version of html_adapter, currently it only
%%% escapes tags and replace some special html characters.
%%%
%%% Copyright 2017 Inaka &lt;[email protected]&gt;
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
%%%
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% Unless required by applicable law or agreed to in writing, software
%%% distributed under the License is distributed on an "AS IS" BASIS,
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
%%% @end
%%% @copyright Inaka <[email protected]>
%%%
-module(html_adapter).
-author("Felipe Ripoll <[email protected]>").

%% API
-export([adapt/1]).

%%%===================================================================
%%% API
%%%===================================================================

-spec adapt(binary()) -> iodata().
adapt(Line) ->
Line1 = escape_tags(Line),
replace_chars(Line1).

%%%===================================================================
%%% Internal Functions
%%%===================================================================

-spec replace_chars(binary()) -> iodata().
replace_chars(Line) ->
Chars = chars_to_replace(),
replace_chars(Line, Chars).

-spec replace_chars(iodata(), [{string(), string()}]) -> iodata().
replace_chars(Line, []) ->
Line;
replace_chars(Line, [{Pattern, ReplaceBy} | Rest]) ->
Result = re:replace(Line, Pattern, ReplaceBy),
Result2 = replace(Result, Line, {Pattern, ReplaceBy}),
replace_chars(Result2, Rest).

-spec escape_tags(iodata()) -> iodata().
escape_tags(Line) ->
Pattern = "<[^>]*>",
ReplaceBy = "",
Result = re:replace(Line, Pattern, ReplaceBy),
replace(Result, Line, {Pattern, ReplaceBy}).

-spec replace(iodata(), iodata(), {string(), string()}) -> iodata().
replace(Line, Line, _) ->
Line;
replace([Line, []], _, _) ->
Line;
replace(Line, _PreviousLine, {Pattern, ReplaceBy}) ->
Result = re:replace(Line, Pattern, ReplaceBy),
replace(Result, Line, {Pattern, ReplaceBy}).

-spec chars_to_replace() -> [{string(), string()}].
chars_to_replace() ->
[ {"&quot;", "\""}
, {"&amp;", "&"}
, {"&lt;", "<"}
].
36 changes: 36 additions & 0 deletions src/adapter/markdown_adapter.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
%%% @doc Markdown Adapter.
%%%
%%% Copyright 2017 Inaka &lt;[email protected]&gt;
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
%%%
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% Unless required by applicable law or agreed to in writing, software
%%% distributed under the License is distributed on an "AS IS" BASIS,
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
%%% @end
%%% @copyright Inaka <[email protected]>
%%%
-module(markdown_adapter).
-author("Felipe Ripoll <[email protected]>").

%% API
-export([adapt/1]).

%%%===================================================================
%%% API
%%%===================================================================

-spec adapt(binary()) -> iodata().
adapt(Line) ->
{ok, Line1, _} = 'Elixir.Earmark':as_html(Line),
% Earmark replace ' by ’ and ‘ which causes a bitstring, so we replace it by ' again
Line2 = binary:replace(Line1, [<<226, 128, 152>>, <<226, 128, 153>>], <<39>>, [global]),
% replace “ and ” by "
Line3 = binary:replace(Line2, [<<226, 128, 156>>, <<226, 128, 157>>], <<34>>, [global]),
html_adapter:adapt(Line3).
4 changes: 3 additions & 1 deletion src/sheldon.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
{registered, []},
{applications, [
kernel,
stdlib
stdlib,
elixir,
earmark
]},
{modules, []},
{mod, {sheldon_app, []}},
Expand Down
Loading

0 comments on commit 60ec73c

Please sign in to comment.