diff --git a/.formatter.exs b/.formatter.exs
index 17fe611..e69200f 100644
--- a/.formatter.exs
+++ b/.formatter.exs
@@ -6,6 +6,7 @@ locals_without_parens = [
[
locals_without_parens: locals_without_parens,
import_deps: [],
+ line_length: 120,
plugins: [Styler],
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
export: [locals_without_parens: locals_without_parens]
diff --git a/README.md b/README.md
index 05a7190..5e754db 100644
--- a/README.md
+++ b/README.md
@@ -132,7 +132,7 @@ defmodule MySite.RootLayout do
end
if Mix.env() == :dev do
- c &Tableau.live_reload/1
+ c &TableauDevServer.live_reload/1
end
end
end
@@ -187,7 +187,7 @@ config :tableau, :reloader,
]
```
-All you need to do is render the `Tableau.live_reload/1` component right after your `body` tag.
+All you need to do is render the `TableauDevServer.live_reload/1` component right after your `body` tag.
```elixir
# lib/layouts/app.ex
diff --git a/lib/tableau.ex b/lib/tableau.ex
index a3b0619..5772fab 100644
--- a/lib/tableau.ex
+++ b/lib/tableau.ex
@@ -7,11 +7,11 @@ defmodule Tableau do
* `:timezone` - string - Timezone to use when parsing date times. Defaults to `Etc/UTC`.
* `:base_path` - string - Development server root. Defaults to '/'.
* `:url` - string (required) - The URL of your website.
- * `:converters` - mapping of file extensions to converter module. Defaults to `[md: Tableau.MDExConverter]`
- * `:markdown` - keyword
- * `:mdex` - keyword - Options to pass to `MDEx.to_html/2`
+ * `:converters` - mapping of file extensions to converter module. Defaults to `[md: Tableau.MDExExtension]`
* `:slug` - keyword - Options to pass to `Slug.slugify/2`
+ You'll want to check out each extension's documentation to see configuration options.
+
### Example
```elixir
@@ -23,39 +23,12 @@ defmodule Tableau do
url: "http://localhost:8080",
timezone: "America/Indiana/Indianapolis",
converters: [
- md: Tableau.MDExConverter,
+ md: Tableau.MDExExtension,
dj: MySite.DjotConverter
],
slug: [
lowercase: false
- ],
- markdown: [
- mdex: [
- extension: [
- table: true,
- header_ids: "",
- tasklist: true,
- strikethrough: true,
- autolink: true,
- alerts: true,
- footnotes: true
- ],
- render: [unsafe: true],
- syntax_highlight: [formatter: {:html_inline, theme: "neovim_dark"}],
- plugins: [MDExGFM]
- ]
]
```
"""
-
- @doc """
- Convert markdown content to HTML using `MDEx.to_html!/2`.
-
- Will use the globally configured options, but you can also pass it overrides.
- """
- def markdown(content, overrides \\ []) do
- {:ok, config} = Tableau.Config.get()
-
- MDEx.to_html!(content, Keyword.merge(config.markdown[:mdex], overrides))
- end
end
diff --git a/lib/tableau/config.ex b/lib/tableau/config.ex
index 59beaad..82291ac 100644
--- a/lib/tableau/config.ex
+++ b/lib/tableau/config.ex
@@ -11,8 +11,7 @@ defmodule Tableau.Config do
timezone: "Etc/UTC",
reload_log: false,
slug: [],
- converters: [md: Tableau.MDExConverter],
- markdown: [mdex: []]
+ converters: []
]
def new(config) do
diff --git a/lib/tableau/converter.ex b/lib/tableau/converter.ex
index c0626b3..7e73164 100644
--- a/lib/tableau/converter.ex
+++ b/lib/tableau/converter.ex
@@ -1,13 +1,52 @@
defmodule Tableau.Converter do
@moduledoc """
- Defines the interface for the converter module used by extensions to parse markup files.
- """
+ Convenience module for converting content into HTML. Useful for extension authors to convert content consistently with other
+ extensions without making beskope code.
+
+ By default, will convert markdown content into HTML using `Tableau.MDExExtension`.
+
+ You can configure other converters (an extension that implements the convert callback) with:
+
+ ```elixir
+ config :tableau, :config,
+ converters: [
+ ext: ConverterModule
+ ]
+ ```
+
+ This will be merged in with the default of `[md: Tableau.MDExExtension]`.
- @doc """
- Converts content into HTML.
+ This can be called via an explicit converter or with an extension that will be looked up via the configuration.
- Is given the file path, the frontmatter, the content of the files (sans front matter), and a list of options.
+ ```elixir
+ Tableau.Converter.convert(content, converter: MyConverter)
+
+ Tableau.Converter.convert(content, ext: :md)
+ ```
+
+ This makes it somewhat easier to swap out your converter without needing to make big application changes, but you can still
+ call a converter explicitly in your layout/page code. Doing so will allow you to pass configuration options to the
+ converter itself (assuming the implementation allows that).
+
+ ```elixir
+ Tableau.MDExExtension.convert(content, extension: [autolink: false])
+ ```
"""
- @callback convert(filepath :: String.t(), front_matter :: map(), content :: String.t(), opts :: Keyword.t()) ::
- String.t()
+ @default_converters [
+ md: Tableau.MDExExtension
+ ]
+ def convert(content, opts \\ []) do
+ converters =
+ Keyword.merge(
+ @default_converters,
+ Application.get_env(:tableau, :config, [])[:converters] || []
+ )
+
+ with nil <- opts[:converter],
+ nil <- converters[opts[:ext]] do
+ content
+ else
+ converter -> converter.convert(content)
+ end
+ end
end
diff --git a/lib/tableau/converters/mdex_converter.ex b/lib/tableau/converters/mdex_converter.ex
deleted file mode 100644
index 597e773..00000000
--- a/lib/tableau/converters/mdex_converter.ex
+++ /dev/null
@@ -1,8 +0,0 @@
-defmodule Tableau.MDExConverter do
- @moduledoc """
- Converter to parse markdown content with `MDEx`
- """
- def convert(_filepath, _front_matter, body, %{site: %{config: config}}) do
- MDEx.to_html!(body, config.markdown[:mdex])
- end
-end
diff --git a/lib/tableau/extension.ex b/lib/tableau/extension.ex
index e8df2a9..a725fec 100644
--- a/lib/tableau/extension.ex
+++ b/lib/tableau/extension.ex
@@ -93,12 +93,20 @@ defmodule Tableau.Extension do
"""
@callback config(Keyword.t() | map()) :: {:ok, map()} | {:error, any()}
+ @doc """
+ Called by content generators to convert content for a specific content type.
+ """
+ @callback convert(String.t(), any()) :: String.t()
+ @callback convert(String.t()) :: String.t()
+
@optional_callbacks [
config: 1,
pre_build: 1,
pre_render: 1,
pre_write: 1,
- post_write: 1
+ post_write: 1,
+ convert: 1,
+ convert: 2
]
defmacro __using__(opts) do
diff --git a/lib/tableau/extensions/common.ex b/lib/tableau/extensions/common.ex
index 9eb9937..e593526 100644
--- a/lib/tableau/extensions/common.ex
+++ b/lib/tableau/extensions/common.ex
@@ -36,9 +36,22 @@ defmodule Tableau.Extension.Common do
"""
def entries(paths, callback) do
for path <- paths do
- {front_matter, body} = Tableau.YamlFrontMatter.parse!(File.read!(path), atoms: true)
+ content = File.read!(path)
+
+ {front_matter, body} =
+ case Tableau.YamlFrontMatter.parse(content) do
+ {:ok, fm, body} -> {fm, body}
+ {:error, _} -> {%{}, content}
+ end
+
"." <> ext = Path.extname(path)
- callback.(%{path: path, ext: String.to_atom(ext), front_matter: front_matter, pre_convert_body: body})
+
+ callback.(%{
+ path: path,
+ ext: String.to_atom(ext),
+ front_matter: front_matter,
+ pre_convert_body: body
+ })
end
end
diff --git a/lib/tableau/extensions/mdex_extension.ex b/lib/tableau/extensions/mdex_extension.ex
new file mode 100644
index 00000000..19acd8e
--- /dev/null
+++ b/lib/tableau/extensions/mdex_extension.ex
@@ -0,0 +1,115 @@
+defmodule Tableau.MDExExtension do
+ @moduledoc """
+ Converter to parse markdown content with `MDEx`.
+
+ > #### Warning {: .warning}
+ > [MDEx](https://github.com/leandrocp/mdex), [mdex_native](https://github.com/leandrocp/mdex_native), and [Lumis](https://github.com/leandrocp/lumis) are constantly evolving projects that change quickly. This module only relies on the `MDEx.to_html/2` function, so breaking changes are unlikely from a Tableau perspective, but if you update any of these libraries, you must check for breaking configuration changes and update your site accordingly.
+
+ Configure `MDEx` options (these are passed directly to `MDEx.to_html/2`) with:
+
+ ```elixir
+ config :mdex_native, :syntax_highlighter, :lumis
+
+ config :tableau, Tableau.MDExExtension,
+ extension: [
+ table: true,
+ header_id_prefix: "",
+ tasklist: true,
+ strikethrough: true,
+ autolink: true,
+ alerts: true,
+ footnotes: true
+ ],
+ render: [unsafe: true],
+ syntax_highlight: [
+ engine: :lumis,
+ opts: [
+ formatter: {:html_inline, theme: "neovim_dark"}
+ ]
+ ]
+ ```
+
+ ### Syntax Highlighting
+
+ > #### mdex_native {: .tip}
+ > MDEx allows you to highlight your code with [Lumis](https://github.com/leandrocp/lumis/) or [Syntect](https://docs.rs/syntect/latest/syntect/). Lumis requires you to add `:lumis` to your dependencies (Syntect does not require this).
+ >
+ > You need to configure `:mdex_native` which syntax highlighter to use.
+ > ```elixir
+ > # config/config.exs
+ >
+ > config :mdex_native, :syntax_highlighter, :lumis
+ > # or
+ > config :mdex_native, :syntax_highlighter, :syntect
+ > ```
+
+ #### Lumis
+
+ Lumis requires you to install the `:lumis` dependency as well as the parsers as dependencies as well. You can see the documentation for this [here](https://docs.lumis.sh/).
+
+ In addition to setting the `:mdex_native` configuration, you must also configure the `:engine` option for `:mdex`
+
+ You can find full configuration optiosn in the MDEx documentation.
+
+ ```elixir
+ # mix.exs
+ defp deps() do
+ [
+ {:lumis, "~> 0.10"},
+ ]
+ end
+
+ # config/config.exs
+ config :mdex_native, :syntax_highlighter, :lumis
+
+ config :tableau, Tableau.MDExExtension,
+ syntax_highlight: [
+ engine: :lumis,
+ opts: [
+ formatter: {:html_inline, theme: "neovim_dark"}
+ ]
+ ]
+ ```
+
+ #### Syntect
+
+ In addition to setting the `:mdex_native` configuration, you must also configure the `:engine` option for `:mdex`
+
+ You can find full configuration optiosn in the MDEx documentation.
+
+ ```elixir
+ # config/config.exs
+ config :mdex_native, :syntax_highlighter, :syntect
+
+ config :tableau, Tableau.MDExExtension,
+ syntax_highlight: [
+ engine: :syntect,
+ opts: [
+ theme: "Catppuccin Macchiato"
+ ]
+ ]
+ ```
+ """
+
+ use Tableau.Extension, key: :mdex
+
+ @impl true
+ def convert(body, config_overrides \\ []) do
+ if Code.ensure_loaded?(MDEx) do
+ config =
+ :tableau
+ |> Application.get_env(__MODULE__, [])
+ |> Keyword.merge(config_overrides)
+
+ MDEx.to_html!(body, config)
+ else
+ raise """
+ MDEx is not installed!
+
+ You'll need to add `:mdex` as a dependency in mix.exs.
+
+ `{:mdex, "~> 0.14"}`
+ """
+ end
+ end
+end
diff --git a/lib/tableau/extensions/page_extension.ex b/lib/tableau/extensions/page_extension.ex
index 98bf67b..3e5598e 100644
--- a/lib/tableau/extensions/page_extension.ex
+++ b/lib/tableau/extensions/page_extension.ex
@@ -2,6 +2,8 @@ defmodule Tableau.PageExtension do
@moduledoc """
Content files (with YAML frontmatter) in the configured pages directory will be automatically compiled into Tableau pages.
+ All files in the directory are copied to the output directory, and if their filetype has a matching converter, they are converted.
+
Certain frontmatter keys are required and all keys are passed as options to the `Tableau.Page`.
## Options
@@ -89,16 +91,14 @@ defmodule Tableau.PageExtension do
@impl Tableau.Extension
def pre_build(token) do
- %{site: %{config: %{converters: converters}}, extensions: %{pages: %{config: config}}} = token
-
- exts = Enum.map_join(converters, ",", fn {ext, _} -> to_string(ext) end)
+ %{extensions: %{pages: %{config: config}}} = token
pages =
config.dir
|> List.wrap()
|> Enum.flat_map(fn path ->
path
- |> Path.join("**/*.{#{exts}}")
+ |> Path.join("**/*.*")
|> Common.paths()
end)
|> Common.entries(fn entry ->
@@ -110,13 +110,7 @@ defmodule Tableau.PageExtension do
} = entry
build(path, front_matter, body, config, fn assigns ->
- converter =
- case front_matter[:converter] do
- nil -> converters[ext]
- converter -> Module.concat([converter])
- end
-
- converter.convert(path, front_matter, body, assigns)
+ Tableau.Converter.convert(body, converter: assigns.page[:converter], ext: ext)
end)
end)
@@ -129,7 +123,12 @@ defmodule Tableau.PageExtension do
Tableau.Graph.insert(
token.graph,
Enum.map(token.pages, fn page ->
- %Tableau.Page{parent: page.layout, permalink: page.permalink, template: page.renderer, opts: page}
+ %Tableau.Page{
+ parent: page.layout,
+ permalink: page.permalink,
+ template: page.renderer,
+ opts: page
+ }
end)
)
@@ -137,12 +136,20 @@ defmodule Tableau.PageExtension do
end
defp build(filename, front_matter, body, pages_config, renderer) do
+ converter =
+ case front_matter[:converter] do
+ nil -> nil
+ converter -> Module.concat([converter])
+ end
+
front_matter
|> Map.put(:__tableau_page_extension__, true)
|> Map.put(:body, body)
+ |> Map.put(:title, front_matter[:title] || filename |> Path.basename() |> Path.rootname())
|> Map.put(:file, filename)
|> Map.put(:renderer, renderer)
|> Map.put(:layout, Module.concat([front_matter[:layout] || pages_config.layout]))
+ |> Map.put(:converter, converter)
|> Common.build_permalink(pages_config)
end
end
diff --git a/lib/tableau/extensions/post_extension.ex b/lib/tableau/extensions/post_extension.ex
index b21234f..621d7be 100644
--- a/lib/tableau/extensions/post_extension.ex
+++ b/lib/tableau/extensions/post_extension.ex
@@ -2,6 +2,8 @@ defmodule Tableau.PostExtension do
@moduledoc """
Content files (with YAML frontmatter) in the configured posts directory will be automatically compiled into Tableau pages.
+ All files in the directory are copied to the output directory, and if their filetype has a matching converter, they are converted.
+
Certain frontmatter keys are required and all keys are passed as options to the `Tableau.Page`.
## Options
@@ -10,7 +12,7 @@ defmodule Tableau.PostExtension do
* `:title` - The title of the post.
* `:permalink` - The permalink of the post. `:title` will be replaced with the posts title and non alphanumeric characters removed. Optional.
- * `:date` - A string representation of an Elixir `NaiveDateTime`, often presented as a `sigil_N`. This will be converted to your configured timezone.
+ * `:date` - A string representation of a date time, parsed by `DateTimeParser`. Supports timezones.
* `:layout` - A string representation of a Tableau layout module.
* `:converter` - A string representation of a converter module. (optional)
@@ -104,26 +106,26 @@ defmodule Tableau.PostExtension do
@impl Tableau.Extension
def pre_build(token) do
- %{site: %{config: %{converters: converters}}, extensions: %{posts: %{config: config}}} = token
- exts = Enum.map_join(converters, ",", fn {ext, _} -> to_string(ext) end)
+ %{extensions: %{posts: %{config: config}}} = token
posts =
config.dir
|> List.wrap()
|> Enum.flat_map(fn path ->
path
- |> Path.join("**/*.{#{exts}}")
+ |> Path.join("**/*.*")
|> Common.paths()
end)
- |> Common.entries(fn %{path: path, front_matter: front_matter, pre_convert_body: body, ext: ext} ->
- build(path, front_matter, body, config, fn assigns ->
- converter =
- case front_matter[:converter] do
- nil -> converters[ext]
- converter -> Module.concat([converter])
- end
+ |> Common.entries(fn entry ->
+ %{
+ path: path,
+ front_matter: front_matter,
+ pre_convert_body: body,
+ ext: ext
+ } = entry
- converter.convert(path, front_matter, body, assigns)
+ build(path, front_matter, body, config, fn assigns ->
+ Tableau.Converter.convert(body, converter: assigns.page[:converter], ext: ext)
end)
end)
|> Enum.sort_by(fn post -> post.date end, {:desc, DateTime})
@@ -144,23 +146,50 @@ defmodule Tableau.PostExtension do
Tableau.Graph.insert(
token.graph,
Enum.map(token.posts, fn post ->
- %Tableau.Page{parent: post.layout, permalink: post.permalink, template: post.renderer, opts: post}
+ %Tableau.Page{
+ parent: post.layout,
+ permalink: post.permalink,
+ template: post.renderer,
+ opts: post
+ }
end)
)
{:ok, Map.put(token, :graph, graph)}
end
- defp build(filename, attrs, body, posts_config, renderer) do
+ defp build(filename, front_matter, body, posts_config, renderer) do
Application.put_env(:date_time_parser, :include_zones_from, ~N[2010-01-01T00:00:00])
- attrs
+ converter =
+ case front_matter[:converter] do
+ nil -> nil
+ converter -> Module.concat([converter])
+ end
+
+ front_matter
|> Map.put(:__tableau_post_extension__, true)
|> Map.put(:body, body)
+ |> Map.put(:title, front_matter[:title] || filename |> Path.basename() |> Path.rootname())
|> Map.put(:file, filename)
|> Map.put(:renderer, renderer)
- |> Map.put(:layout, Module.concat([attrs[:layout] || posts_config.layout]))
- |> Map.put(:date, DateTimeParser.parse_datetime!(attrs.date, assume_time: true, assume_utc: true))
+ |> Map.put(:layout, Module.concat([front_matter[:layout] || posts_config.layout]))
+ |> Map.put(:converter, converter)
+ |> Map.put(
+ :date,
+ parse_datetime!(front_matter[:date], filename)
+ )
|> Common.build_permalink(posts_config)
end
+
+ defp parse_datetime!(nil, filename) do
+ raise "Missing required front matter missing from post #{filename}: date"
+ end
+
+ defp parse_datetime!(datetime, _filename) do
+ DateTimeParser.parse_datetime!(datetime,
+ assume_time: true,
+ assume_utc: true
+ )
+ end
end
diff --git a/lib/tableau/extensions/rss_extension.ex b/lib/tableau/extensions/rss_extension.ex
index 1ca9bf9..79e0777 100644
--- a/lib/tableau/extensions/rss_extension.ex
+++ b/lib/tableau/extensions/rss_extension.ex
@@ -113,7 +113,7 @@ defmodule Tableau.RSSExtension do
#{URI.merge(url, post.permalink)}
#{Calendar.strftime(post.date, "%a, %d %b %Y %X %Z")}
#{URI.merge(url, post.permalink)}
-
+
"""
end
diff --git a/lib/tableau/yaml_front_matter.ex b/lib/tableau/yaml_front_matter.ex
index 0d25ef8..fbba57d 100644
--- a/lib/tableau/yaml_front_matter.ex
+++ b/lib/tableau/yaml_front_matter.ex
@@ -5,8 +5,6 @@ defmodule Tableau.YamlFrontMatter.Error do
@moduledoc false
defexception [:message]
- # message: "Error parsing yaml front matter"
-
@impl true
def exception(value) do
%__MODULE__{message: "Error parsing yaml front matter: #{inspect(value)}"}
@@ -15,15 +13,15 @@ end
defmodule Tableau.YamlFrontMatter do
@moduledoc false
- def parse(string, opts \\ []) do
+ def parse(string) do
string
|> split_string()
- |> process_parts(opts)
+ |> process_parts()
end
- def parse!(string, opts \\ []) do
- case parse(string, opts) do
- {:ok, matter, body} -> {atomicize(matter), body}
+ def parse!(string) do
+ case parse(string) do
+ {:ok, matter, body} -> {matter, body}
{:error, error} -> raise Tableau.YamlFrontMatter.Error, error
end
end
@@ -37,32 +35,32 @@ defmodule Tableau.YamlFrontMatter do
|> then(&Regex.split(split_pattern, &1, parts: 3))
end
- defp process_parts([_, yaml | rest], opts) do
- case parse_yaml(yaml, opts) do
- {:ok, yaml} -> {:ok, yaml, List.first(rest, "")}
+ defp process_parts([_, yaml | rest]) do
+ case parse_yaml(yaml) do
+ {:ok, yaml} -> {:ok, atomize(yaml), List.first(rest, "")}
{:error, error} -> {:error, error}
end
end
- defp process_parts(_, _), do: {:error, :invalid_front_matter}
+ defp process_parts(_), do: {:error, :invalid_front_matter}
- defp parse_yaml(yaml, opts) do
- case YamlElixir.read_from_string(yaml, opts) do
+ defp parse_yaml(yaml) do
+ case YamlElixir.read_from_string(yaml) do
{:ok, parsed} -> {:ok, parsed}
error -> error
end
end
- defp atomicize(map) when is_map(map) do
+ defp atomize(map) when is_map(map) do
Map.new(map, fn
- {k, v} when is_binary(k) -> {String.to_atom(k), atomicize(v)}
+ {k, v} when is_binary(k) -> {String.to_atom(k), atomize(v)}
other -> other
end)
end
- defp atomicize(list) when is_list(list) do
- Enum.map(list, &atomicize/1)
+ defp atomize(list) when is_list(list) do
+ Enum.map(list, &atomize/1)
end
- defp atomicize(other), do: other
+ defp atomize(other), do: other
end
diff --git a/mix.exs b/mix.exs
index a14124c..9889a9d 100644
--- a/mix.exs
+++ b/mix.exs
@@ -35,12 +35,14 @@ defmodule Tableau.MixProject do
{:date_time_parser, "~> 1.2"},
{:html_entities, "~> 0.5.2"},
{:libgraph, "~> 0.16.0"},
- {:mdex, "~> 0.11.1"},
{:schematic, "~> 0.5.1"},
{:slugify, "~> 1.3"},
{:tz, "~> 0.28.1"},
{:yaml_elixir, "~> 2.9"},
+ # optional
+ {:mdex, "~> 0.14", optional: true},
+
# dev
{:floki, "~> 0.34", only: :test},
{:ex_doc, ">= 0.0.0", only: :dev},
@@ -76,18 +78,16 @@ defmodule Tableau.MixProject do
Tableau.Layout,
Tableau.Page,
Tableau.Document.Helper,
- Tableau.Extension
- ],
- Converters: [
- Tableau.Converter,
- Tableau.MDExConverter
+ Tableau.Extension,
+ Tableau.Converter
],
Extensions: [
- Tableau.PostExtension,
+ Tableau.DataExtension,
+ Tableau.MDExExtension,
Tableau.PageExtension,
- Tableau.SitemapExtension,
+ Tableau.PostExtension,
Tableau.RSSExtension,
- Tableau.DataExtension,
+ Tableau.SitemapExtension,
Tableau.TagExtension
]
]
diff --git a/mix.lock b/mix.lock
index 38c835c..e25a453 100644
--- a/mix.lock
+++ b/mix.lock
@@ -7,11 +7,11 @@
"jason": {:hex, :jason, "1.4.5", "2e3a008590b0b8d7388c20293e9dcc9cf3e5d642fd2a114e4cbbb52e595d940a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b0c823996102bcd0239b3c2444eb00409b72f6a140c1950bc8b457d836b30684"},
"kday": {:hex, :kday, "1.1.0", "64efac85279a12283eaaf3ad6f13001ca2dff943eda8c53288179775a8c057a0", [:mix], [{:ex_doc, "~> 0.21", [hex: :ex_doc, repo: "hexpm", optional: true]}], "hexpm", "69703055d63b8d5b260479266c78b0b3e66f7aecdd2022906cd9bf09892a266d"},
"libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"},
- "lumis": {:hex, :lumis, "0.6.3", "a14ea311298e45f31f3dff17d3b41b9717c0757ce1aa5275e190e46aa95ea04d", [:mix], [{:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:rustler, "~> 0.29", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.6", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "c0b3dd853f5d44a604202a732fe8c4d0575c4cca263d4e2b4a6f7794d00fab6e"},
"makeup": {:hex, :makeup, "1.2.2", "882d46dc0905e9ff7abf2aab61a7e6b3dcc555533977d8a23b06019e6c89ac94", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "9a1a24e5b343b8ae16abea0822c10a6f75da27af7fa802ada5251f7579bfccfa"},
"makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"},
"makeup_erlang": {:hex, :makeup_erlang, "1.1.0", "835f7e60792e08824cda445639555d7bf1bbbddb1b60b306e33cb6f6db24dc74", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "1cd6780fb1dd1a03979abaed0fe82712b0625118fd5257d3ebbf73f960c73c3c"},
- "mdex": {:hex, :mdex, "0.11.7", "583b35c7160c4e26deab6233f967669d51de6f8b5f7b605adc55037abf7a20d2", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:lumis, "~> 0.1", [hex: :lumis, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:rustler, "~> 0.32", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.7", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "6dac3deb3ecb1a0a5ac9f383c9c57e46510b0a519e6fb21883d9ead34d0e4ffd"},
+ "mdex": {:hex, :mdex, "0.14.0", "6bb28b49682465f802e9a129db4319e48a34edf9626e8186c1d5ea29de3f2a81", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:lumis, "~> 0.9", [hex: :lumis, repo: "hexpm", optional: true]}, {:mdex_native, ">= 0.2.9", [hex: :mdex_native, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.20.0 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}], "hexpm", "60e591041b7f5811004cc275e8d3ae1dffb6958159812402427264b444de5080"},
+ "mdex_native": {:hex, :mdex_native, "0.2.9", "898cc5514d556c4d46fa43035d6fc925116413bb3821c5a71d4bd42f87a90b85", [:mix], [{:rustler, "~> 0.32", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.8", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "7470e6051b6193c620be02acbc12f1acd758250a60c13695ed36ebda512267ac"},
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"},
"rustler_precompiled": {:hex, :rustler_precompiled, "0.9.0", "3a052eda09f3d2436364645cc1f13279cf95db310eb0c17b0d8f25484b233aa0", [:mix], [{:rustler, "~> 0.23", [hex: :rustler, repo: "hexpm", optional: true]}], "hexpm", "471d97315bd3bf7b64623418b3693eedd8e47de3d1cb79a0ac8f9da7d770d94c"},
diff --git a/test/tableau/extensions/page_extension_test.exs b/test/tableau/extensions/page_extension_test.exs
index b6e8838..ba29393 100644
--- a/test/tableau/extensions/page_extension_test.exs
+++ b/test/tableau/extensions/page_extension_test.exs
@@ -31,7 +31,8 @@ defmodule Tableau.PageExtensionTest do
describe "run" do
setup %{tmp_dir: dir} do
- assert {:ok, config} = PageExtension.config(%{dir: dir, enabled: true, layout: Blog.DefaultPageLayout})
+ assert {:ok, config} =
+ PageExtension.config(%{dir: dir, enabled: true, layout: Blog.DefaultPageLayout})
token = %{
site: %{config: %{converters: [md: Tableau.MDExConverter]}},
@@ -165,8 +166,13 @@ defmodule Tableau.PageExtensionTest do
vertices = Graph.vertices(graph)
- assert Enum.any?(vertices, fn v -> is_struct(v, Tableau.Page) and v.permalink == page_1.permalink end)
- assert Enum.any?(vertices, fn v -> is_struct(v, Tableau.Page) and v.permalink == page_2.permalink end)
+ assert Enum.any?(vertices, fn v ->
+ is_struct(v, Tableau.Page) and v.permalink == page_1.permalink
+ end)
+
+ assert Enum.any?(vertices, fn v ->
+ is_struct(v, Tableau.Page) and v.permalink == page_2.permalink
+ end)
end
test "configured permalink works when you dont specify one", %{tmp_dir: dir, token: token} do
@@ -180,7 +186,8 @@ defmodule Tableau.PageExtensionTest do
A great page
""")
- assert {:ok, config} = PageExtension.config(%{dir: dir, enabled: true, permalink: "/page/:title"})
+ assert {:ok, config} =
+ PageExtension.config(%{dir: dir, enabled: true, permalink: "/page/:title"})
token = put_in(token.extensions.pages.config, config)
@@ -202,7 +209,10 @@ defmodule Tableau.PageExtensionTest do
} = token
end
- test "generates permalink from file path if not configured or in front matter", %{tmp_dir: dir, token: token} do
+ test "generates permalink from file path if not configured or in front matter", %{
+ tmp_dir: dir,
+ token: token
+ } do
assert {:ok, config} = PageExtension.config(%{dir: [dir], enabled: true})
token = put_in(token.extensions.pages.config, config)
@@ -339,7 +349,7 @@ defmodule Tableau.PageExtensionTest do
assert {:ok, token} = PageExtension.pre_render(token)
assert %{
- pages: [%{body: "\nA great page\n", converter: "Tableau.PageExtensionTest"}],
+ pages: [%{body: "\nA great page\n", converter: Tableau.PageExtensionTest}],
graph: graph
} = token
@@ -361,5 +371,5 @@ defmodule Tableau.PageExtensionTest do
end
end
- def convert(_, _, body, _), do: String.upcase(body)
+ def convert(body), do: String.upcase(body)
end
diff --git a/test/tableau/extensions/post_extension_test.exs b/test/tableau/extensions/post_extension_test.exs
index 167f7a1..afd2966 100644
--- a/test/tableau/extensions/post_extension_test.exs
+++ b/test/tableau/extensions/post_extension_test.exs
@@ -33,7 +33,8 @@ defmodule Tableau.PostExtensionTest do
describe "run" do
setup %{tmp_dir: dir} do
- assert {:ok, config} = PostExtension.config(%{dir: dir, enabled: true, layout: Blog.DefaultPostLayout})
+ assert {:ok, config} =
+ PostExtension.config(%{dir: dir, enabled: true, layout: Blog.DefaultPostLayout})
token = %{
site: %{config: %{converters: [md: Tableau.MDExConverter]}},
@@ -247,7 +248,8 @@ defmodule Tableau.PostExtensionTest do
A great post
""")
- assert {:ok, config} = PostExtension.config(%{dir: dir, enabled: true, permalink: "/post/:title"})
+ assert {:ok, config} =
+ PostExtension.config(%{dir: dir, enabled: true, permalink: "/post/:title"})
token = put_in(token.extensions.posts.config, config)
@@ -269,7 +271,10 @@ defmodule Tableau.PostExtensionTest do
} = token
end
- test "generates permalink from file path if not configured or in front matter", %{tmp_dir: dir, token: token} do
+ test "generates permalink from file path if not configured or in front matter", %{
+ tmp_dir: dir,
+ token: token
+ } do
assert {:ok, config} = PostExtension.config(%{dir: [dir], enabled: true})
token = put_in(token.extensions.posts.config, config)
@@ -412,7 +417,7 @@ defmodule Tableau.PostExtensionTest do
assert {:ok, token} = PostExtension.pre_build(token)
assert {:ok, token} = PostExtension.pre_render(token)
- assert %{posts: [%{converter: "Tableau.PostExtensionTest"}], graph: graph} = token
+ assert %{posts: [%{converter: Tableau.PostExtensionTest}], graph: graph} = token
page =
graph
@@ -432,5 +437,5 @@ defmodule Tableau.PostExtensionTest do
end
end
- def convert(_, _, body, _), do: String.upcase(body)
+ def convert(body), do: String.upcase(body)
end
diff --git a/test/tableau/extensions/tag_extension_test.exs b/test/tableau/extensions/tag_extension_test.exs
index 0da2ccb..1221983 100644
--- a/test/tableau/extensions/tag_extension_test.exs
+++ b/test/tableau/extensions/tag_extension_test.exs
@@ -56,7 +56,9 @@ defmodule Tableau.TagExtensionTest do
} => [
%{title: "Post 2"}
],
- %{tag: "C++", title: "C++", permalink: "/tags/c-plus-plus", slug: "c-plus-plus"} => [%{title: "Post 2"}]
+ %{tag: "C++", title: "C++", permalink: "/tags/c-plus-plus", slug: "c-plus-plus"} => [
+ %{title: "Post 2"}
+ ]
},
graph: graph
} = token