mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 12:08:00 +01:00
Merge branch 'markdown'
This commit is contained in:
commit
625c0e4556
59 changed files with 2277 additions and 169 deletions
9
.github/workflows/elixir.yml
vendored
9
.github/workflows/elixir.yml
vendored
|
@ -16,9 +16,7 @@ jobs:
|
|||
key: ${{ runner.os }}-build-deps-${{ hashFiles('mix.lock') }}
|
||||
|
||||
- run: docker-compose pull
|
||||
|
||||
- uses: satackey/action-docker-layer-caching@v0.0.8
|
||||
continue-on-error: true
|
||||
- run: docker-compose build
|
||||
|
||||
- name: Build and test
|
||||
run: docker-compose run app run-test
|
||||
|
@ -27,8 +25,3 @@ jobs:
|
|||
run: |
|
||||
docker-compose run app mix sobelow --config
|
||||
docker-compose run app mix deps.audit
|
||||
|
||||
- name: Fix permissions
|
||||
run: |
|
||||
sudo chown -R $(whoami):$(id -ng) deps
|
||||
sudo chown -R $(whoami):$(id -ng) _build
|
||||
|
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -47,3 +47,9 @@ npm-debug.log
|
|||
|
||||
# Sobelow
|
||||
.sobelow
|
||||
|
||||
# Unportable compiled binaries
|
||||
/priv/native/
|
||||
|
||||
# Rust binaries
|
||||
/native/**/target
|
||||
|
|
|
@ -210,6 +210,20 @@ blockquote {
|
|||
background-color: inherit;
|
||||
}
|
||||
|
||||
// Prevent blockquote from gaining far too much indentation and breaking.
|
||||
blockquote blockquote blockquote blockquote blockquote blockquote {
|
||||
margin: 1em 0;
|
||||
padding: 1em 2px;
|
||||
}
|
||||
|
||||
// Horizontal space is at a high premium on mobile.
|
||||
@media (max-width: $min_px_width_for_desktop_layout) {
|
||||
blockquote {
|
||||
margin: 1em 4px;
|
||||
padding: 1em 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.spoiler {
|
||||
background-color: $admin_links_hover_color;
|
||||
color: $admin_links_hover_color;
|
||||
|
@ -267,6 +281,26 @@ blockquote {
|
|||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
img[alt=tiny] {
|
||||
max-height: $image_tiny_size;
|
||||
max-width: $image_tiny_size;
|
||||
}
|
||||
|
||||
img[alt=small] {
|
||||
max-height: $image_small_size;
|
||||
max-width: $image_small_size;
|
||||
}
|
||||
|
||||
img[alt=medium] {
|
||||
max-height: $image_medium_size;
|
||||
max-width: $image_medium_size;
|
||||
}
|
||||
|
||||
img[alt=large] {
|
||||
max-height: $image_large_size;
|
||||
max-width: $image_large_size;
|
||||
}
|
||||
|
||||
//donations
|
||||
.donate-button {
|
||||
background: 0;
|
||||
|
|
|
@ -16,6 +16,11 @@ $medium_layout_width: 1330px;
|
|||
$centered_layout_side_margin: 24px;
|
||||
$layout_side_margin: 12px;
|
||||
|
||||
$image_tiny_size: 64px;
|
||||
$image_small_size: 128px;
|
||||
$image_medium_size: 256px;
|
||||
$image_large_size: 512px;
|
||||
|
||||
$header_height: 36px;
|
||||
$header_field_height: 28px;
|
||||
$header_sub_height: 32px;
|
||||
|
|
|
@ -36,6 +36,11 @@ config :philomena, PhilomenaWeb.Endpoint,
|
|||
render_errors: [view: PhilomenaWeb.ErrorView, accepts: ~w(html json)],
|
||||
pubsub_server: Philomena.PubSub
|
||||
|
||||
# Markdown
|
||||
config :philomena, Philomena.Native,
|
||||
crate: "philomena",
|
||||
mode: :release
|
||||
|
||||
config :phoenix, :template_engines,
|
||||
slim: PhoenixSlime.Engine,
|
||||
slime: PhoenixSlime.Engine,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
FROM elixir:1.12.0-alpine
|
||||
|
||||
RUN apk update \
|
||||
&& apk add inotify-tools build-base git ffmpeg ffmpeg-dev npm nodejs file-dev libpng-dev gifsicle optipng libjpeg-turbo-utils librsvg imagemagick postgresql-client wget \
|
||||
&& apk add inotify-tools build-base git ffmpeg ffmpeg-dev npm nodejs file-dev libpng-dev gifsicle optipng libjpeg-turbo-utils librsvg imagemagick postgresql-client wget rust cargo \
|
||||
&& mix local.hex --force \
|
||||
&& mix local.rebar --force
|
||||
|
||||
|
@ -19,4 +19,5 @@ COPY docker/app/run-development /usr/local/bin/run-development
|
|||
COPY docker/app/run-test /usr/local/bin/run-test
|
||||
COPY docker/app/safe-rsvg-convert /usr/local/bin/safe-rsvg-convert
|
||||
COPY docker/app/purge-cache /usr/local/bin/purge-cache
|
||||
ENV PATH=$PATH:/root/.cargo/bin
|
||||
CMD run-development
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# For compatibility with musl libc
|
||||
export CARGO_FEATURE_DISABLE_INITIAL_EXEC_TLS=1
|
||||
|
||||
background() {
|
||||
while :; do
|
||||
mix run -e 'Philomena.Release.update_channels()'
|
||||
|
|
|
@ -1,39 +1,3 @@
|
|||
defmodule Camo.Image do
|
||||
def image_url(input) do
|
||||
uri = URI.parse(input)
|
||||
|
||||
cond do
|
||||
is_nil(uri.host) ->
|
||||
""
|
||||
|
||||
is_nil(camo_key()) ->
|
||||
input
|
||||
|
||||
uri.host in [cdn_host(), camo_host()] ->
|
||||
URI.to_string(%{uri | scheme: "https", port: 443})
|
||||
|
||||
true ->
|
||||
camo_digest = :crypto.mac(:hmac, :sha, camo_key(), input) |> Base.url_encode64(padding: false)
|
||||
|
||||
camo_uri = %URI{
|
||||
host: camo_host(),
|
||||
path: "/" <> camo_digest <> "/" <> Base.url_encode64(input, padding: false),
|
||||
scheme: "https"
|
||||
}
|
||||
|
||||
URI.to_string(camo_uri)
|
||||
end
|
||||
end
|
||||
|
||||
defp cdn_host do
|
||||
Application.get_env(:philomena, :cdn_host)
|
||||
end
|
||||
|
||||
defp camo_key do
|
||||
Application.get_env(:philomena, :camo_key)
|
||||
end
|
||||
|
||||
defp camo_host do
|
||||
Application.get_env(:philomena, :camo_host)
|
||||
end
|
||||
def image_url(input), do: Philomena.Native.camo_image_url(input)
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ defmodule Philomena.Badges.Badge do
|
|||
schema "badges" do
|
||||
field :title, :string
|
||||
field :description, :string, default: ""
|
||||
field :description_md, :string, default: ""
|
||||
field :image, :string
|
||||
field :disable_award, :boolean, default: false
|
||||
field :priority, :boolean, default: false
|
||||
|
|
|
@ -14,6 +14,7 @@ defmodule Philomena.Channels.Channel do
|
|||
field :short_name, :string
|
||||
field :title, :string, default: ""
|
||||
field :description, :string
|
||||
field :description_md, :string
|
||||
field :tags, :string
|
||||
field :viewers, :integer, default: 0
|
||||
field :nsfw, :boolean, default: false
|
||||
|
|
|
@ -11,6 +11,7 @@ defmodule Philomena.Comments.Comment do
|
|||
belongs_to :deleted_by, User
|
||||
|
||||
field :body, :string
|
||||
field :body_md, :string
|
||||
field :ip, EctoNetwork.INET
|
||||
field :fingerprint, :string
|
||||
field :user_agent, :string, default: ""
|
||||
|
|
|
@ -17,6 +17,10 @@ defmodule Philomena.Commissions.Commission do
|
|||
field :contact, :string
|
||||
field :will_create, :string
|
||||
field :will_not_create, :string
|
||||
field :information_md, :string
|
||||
field :contact_md, :string
|
||||
field :will_create_md, :string
|
||||
field :will_not_create_md, :string
|
||||
field :commission_items_count, :integer, default: 0
|
||||
|
||||
timestamps(inserted_at: :created_at, type: :utc_datetime)
|
||||
|
|
|
@ -11,8 +11,10 @@ defmodule Philomena.Commissions.Item do
|
|||
|
||||
field :item_type, :string
|
||||
field :description, :string
|
||||
field :description_md, :string
|
||||
field :base_price, :decimal
|
||||
field :add_ons, :string
|
||||
field :add_ons_md, :string
|
||||
|
||||
timestamps(inserted_at: :created_at, type: :utc_datetime)
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@ defmodule Philomena.Conversations.Message do
|
|||
belongs_to :from, User
|
||||
|
||||
field :body, :string
|
||||
field :body_md, :string
|
||||
|
||||
timestamps(inserted_at: :created_at, type: :utc_datetime)
|
||||
end
|
||||
|
|
|
@ -17,6 +17,9 @@ defmodule Philomena.DnpEntries.DnpEntry do
|
|||
field :hide_reason, :boolean, default: false
|
||||
field :instructions, :string, default: ""
|
||||
field :feedback, :string, default: ""
|
||||
field :conditions_md, :string, default: ""
|
||||
field :reason_md, :string, default: ""
|
||||
field :instructions_md, :string, default: ""
|
||||
|
||||
timestamps(inserted_at: :created_at, type: :utc_datetime)
|
||||
end
|
||||
|
|
|
@ -12,6 +12,7 @@ defmodule Philomena.Filters.Filter do
|
|||
|
||||
field :name, :string
|
||||
field :description, :string, default: ""
|
||||
field :description_md, :string, default: ""
|
||||
field :system, :boolean
|
||||
field :public, :boolean
|
||||
field :hidden_complex_str, :string
|
||||
|
|
|
@ -17,6 +17,7 @@ defmodule Philomena.Galleries.Gallery do
|
|||
field :title, :string
|
||||
field :spoiler_warning, :string, default: ""
|
||||
field :description, :string, default: ""
|
||||
field :description_md, :string, default: ""
|
||||
field :image_count, :integer
|
||||
field :order_position_asc, :boolean
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ defmodule Philomena.Images.Image do
|
|||
field :votes_count, :integer, default: 0
|
||||
field :source_url, :string
|
||||
field :description, :string, default: ""
|
||||
field :description_md, :string, default: ""
|
||||
field :image_sha512_hash, :string
|
||||
field :image_orig_sha512_hash, :string
|
||||
field :deletion_reason, :string
|
||||
|
@ -80,6 +81,7 @@ defmodule Philomena.Images.Image do
|
|||
field :destroyed_content, :boolean
|
||||
field :hidden_image_key, :string
|
||||
field :scratchpad, :string
|
||||
field :scratchpad_md, :string
|
||||
field :hides_count, :integer, default: 0
|
||||
|
||||
# todo: can probably remove these now
|
||||
|
|
16
lib/philomena/markdown.ex
Normal file
16
lib/philomena/markdown.ex
Normal file
|
@ -0,0 +1,16 @@
|
|||
defmodule Philomena.Markdown do
|
||||
@markdown_chars ~r/[\*_\[\]\(\)\^`\%\\~<>#\|]/
|
||||
|
||||
# When your NIF is loaded, it will override this function.
|
||||
def to_html(text, replacements), do: Philomena.Native.markdown_to_html(text, replacements)
|
||||
|
||||
def to_html_unsafe(text, replacements),
|
||||
do: Philomena.Native.markdown_to_html_unsafe(text, replacements)
|
||||
|
||||
def escape_markdown(text) do
|
||||
@markdown_chars
|
||||
|> Regex.replace(text, fn m ->
|
||||
"\\#{m}"
|
||||
end)
|
||||
end
|
||||
end
|
|
@ -12,6 +12,7 @@ defmodule Philomena.ModNotes.ModNote do
|
|||
field :notable_type, :string
|
||||
|
||||
field :body, :string
|
||||
field :body_md, :string
|
||||
|
||||
field :notable, :any, virtual: true
|
||||
|
||||
|
|
10
lib/philomena/native.ex
Normal file
10
lib/philomena/native.ex
Normal file
|
@ -0,0 +1,10 @@
|
|||
defmodule Philomena.Native do
|
||||
use Rustler, otp_app: :philomena
|
||||
|
||||
# Markdown
|
||||
def markdown_to_html(_text, _replacements), do: :erlang.nif_error(:nif_not_loaded)
|
||||
def markdown_to_html_unsafe(_text, _replacements), do: :erlang.nif_error(:nif_not_loaded)
|
||||
|
||||
# Camo
|
||||
def camo_image_url(_uri), do: :erlang.nif_error(:nif_not_loaded)
|
||||
end
|
|
@ -11,6 +11,7 @@ defmodule Philomena.Posts.Post do
|
|||
belongs_to :deleted_by, User
|
||||
|
||||
field :body, :string
|
||||
field :body_md, :string
|
||||
field :edit_reason, :string
|
||||
field :ip, EctoNetwork.INET
|
||||
field :fingerprint, :string
|
||||
|
|
|
@ -13,6 +13,7 @@ defmodule Philomena.Reports.Report do
|
|||
field :user_agent, :string, default: ""
|
||||
field :referrer, :string, default: ""
|
||||
field :reason, :string
|
||||
field :reason_md, :string
|
||||
field :state, :string, default: "open"
|
||||
field :open, :boolean, default: true
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ defmodule Philomena.Tags.Tag do
|
|||
field :category, :string
|
||||
field :images_count, :integer, default: 0
|
||||
field :description, :string
|
||||
field :description_md, :string
|
||||
field :short_description, :string
|
||||
field :namespace, :string
|
||||
field :name_in_namespace, :string
|
||||
|
|
|
@ -2,9 +2,9 @@ defmodule Philomena.Textile.Lexer do
|
|||
import NimbleParsec
|
||||
|
||||
token_list =
|
||||
Enum.to_list(0x01..0x29)
|
||||
++ Enum.to_list(0x2b..0x2f)
|
||||
++ ':;<=>?[]\\^`~|'
|
||||
Enum.to_list(0x01..0x29) ++
|
||||
Enum.to_list(0x2B..0x2F) ++
|
||||
':;<=>?[]\\^`~|'
|
||||
|
||||
space_list = '\f \r\t\u00a0\u1680\u180e\u202f\u205f\u3000' ++ Enum.to_list(0x2000..0x200A)
|
||||
space = utf8_char(space_list)
|
||||
|
|
601
lib/philomena/textile/parser_markdown.ex
Normal file
601
lib/philomena/textile/parser_markdown.ex
Normal file
|
@ -0,0 +1,601 @@
|
|||
# LUNA PRESENTS THEE
|
||||
#
|
||||
# DA ULTIMATE, BESTEST, MOST SECURE AND DEFINITELY NOT BUGGY
|
||||
# TEXTILE TO MARKDOWN CONVERTER PARSER LIBRARY THING!!!!!
|
||||
#
|
||||
# IT'S SO AWESOME I HAVE TO DESCRIBE IT IN ALL CAPS
|
||||
#
|
||||
# BY LOOKING AT THIS SOURCE CODE YOU AGREE THAT I MAY NOT BE HELD
|
||||
# RESPONSIBLE FOR YOU DEVELOPING EYE CANCER
|
||||
#
|
||||
# YOU'VE BEEN WARNED
|
||||
#
|
||||
# COPYRIGHT (C) (R) (TM) LUNA (C) (R) (TM) 2021-206969696969
|
||||
defmodule Philomena.Textile.ParserMarkdown do
|
||||
alias Philomena.Textile.Lexer
|
||||
alias Philomena.Markdown
|
||||
alias Phoenix.HTML
|
||||
|
||||
defp markdown_quote(text) do
|
||||
result = Regexp.replace(~r/\n/, text, "\\0> ")
|
||||
"> #{result}"
|
||||
end
|
||||
|
||||
def parse(parser, input) do
|
||||
parser = Map.put(parser, :state, %{})
|
||||
|
||||
with {:ok, tokens, _1, _2, _3, _4} <- Lexer.lex(String.trim(input || "")),
|
||||
{:ok, tree, []} <- repeat(&textile/3, parser, tokens, false, 0) do
|
||||
partial_flatten(tree)
|
||||
else
|
||||
_ ->
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
# Helper to turn a parse tree into a string
|
||||
def flatten(tree) do
|
||||
tree
|
||||
|> List.flatten()
|
||||
|> Enum.map_join("", fn {_k, v} -> v end)
|
||||
end
|
||||
|
||||
def flatten_unquote(tree) do
|
||||
tree
|
||||
|> List.flatten()
|
||||
|> Enum.map_join("", fn {_k, v} ->
|
||||
Regex.replace(~r/\n(> )/, v, "\n")
|
||||
end)
|
||||
end
|
||||
|
||||
# Helper to turn a parse tree into a list
|
||||
def partial_flatten(tree) do
|
||||
tree
|
||||
|> List.flatten()
|
||||
|> Enum.chunk_by(fn {k, _v} -> k end)
|
||||
|> Enum.map(fn list ->
|
||||
[{type, _v} | _rest] = list
|
||||
|
||||
value = Enum.map_join(list, "", fn {_k, v} -> v end)
|
||||
|
||||
{type, value}
|
||||
end)
|
||||
end
|
||||
|
||||
defp put_state(parser, new_state) do
|
||||
state = Map.put(parser.state, new_state, true)
|
||||
Map.put(parser, :state, state)
|
||||
end
|
||||
|
||||
# Helper corresponding to Kleene star (*) operator
|
||||
# Match a specificed rule zero or more times
|
||||
defp repeat(rule, parser, tokens, bq, level) when bq == true do
|
||||
case rule.(parser, tokens, true, level) do
|
||||
{:ok, tree, r_tokens} ->
|
||||
{:ok, tree2, r2_tokens, level} = repeat(rule, parser, r_tokens, true, level)
|
||||
{:ok, [tree, tree2], r2_tokens, level}
|
||||
|
||||
_ ->
|
||||
{:ok, [], tokens, level}
|
||||
end
|
||||
end
|
||||
|
||||
defp repeat(rule, parser, tokens, bq, level) do
|
||||
case rule.(parser, tokens, level) do
|
||||
{:ok, tree, r_tokens} ->
|
||||
{:ok, tree2, r2_tokens} = repeat(rule, parser, r_tokens, false, level)
|
||||
{:ok, [tree, tree2], r2_tokens}
|
||||
|
||||
_ ->
|
||||
{:ok, [], tokens}
|
||||
end
|
||||
end
|
||||
|
||||
# Helper to match a simple recursive grammar rule of the following form:
|
||||
#
|
||||
# open_token callback* close_token
|
||||
#
|
||||
defp simple_recursive(
|
||||
:bq_open,
|
||||
:bq_close,
|
||||
open_tag,
|
||||
close_tag,
|
||||
callback,
|
||||
parser,
|
||||
[
|
||||
{:bq_open, open} | r_tokens
|
||||
],
|
||||
level
|
||||
) do
|
||||
case repeat(callback, parser, r_tokens, true, level) do
|
||||
{:ok, tree, [{:bq_close, _} | r2_tokens], level} ->
|
||||
{:ok,
|
||||
[
|
||||
{:markup, "\n" <> String.duplicate(open_tag, level)},
|
||||
tree,
|
||||
{:markup, "\n" <> String.duplicate(close_tag, level - 1)}
|
||||
], r2_tokens}
|
||||
|
||||
{:ok, tree, r2_tokens, level} ->
|
||||
{:ok, [{:text, open}, tree], r2_tokens}
|
||||
end
|
||||
end
|
||||
|
||||
defp simple_recursive(
|
||||
open_token,
|
||||
close_token,
|
||||
open_tag,
|
||||
close_tag,
|
||||
callback,
|
||||
parser,
|
||||
[
|
||||
{open_token, open} | r_tokens
|
||||
],
|
||||
level
|
||||
) do
|
||||
case repeat(callback, parser, r_tokens, false, level) do
|
||||
{:ok, tree, [{^close_token, _} | r2_tokens]} ->
|
||||
{:ok, [{:markup, open_tag}, tree, {:markup, close_tag}], r2_tokens}
|
||||
|
||||
{:ok, tree, r2_tokens} ->
|
||||
{:ok, [{:text, open}, tree], r2_tokens}
|
||||
end
|
||||
end
|
||||
|
||||
defp simple_recursive(
|
||||
_open_token,
|
||||
_close_token,
|
||||
_open_tag,
|
||||
_close_tag,
|
||||
_callback,
|
||||
_parser,
|
||||
_tokens,
|
||||
_level
|
||||
) do
|
||||
{:error, "Expected a simple recursive rule"}
|
||||
end
|
||||
|
||||
# Helper to match a simple recursive grammar rule with negative lookahead:
|
||||
#
|
||||
# open_token callback* close_token (?!lookahead_not)
|
||||
#
|
||||
defp simple_lookahead_not(
|
||||
open_token,
|
||||
close_token,
|
||||
open_tag,
|
||||
close_tag,
|
||||
lookahead_not,
|
||||
callback,
|
||||
state,
|
||||
parser,
|
||||
[{open_token, open} | r_tokens],
|
||||
level
|
||||
) do
|
||||
case parser.state do
|
||||
%{^state => _} ->
|
||||
{:error, "End of rule"}
|
||||
|
||||
_ ->
|
||||
case r_tokens do
|
||||
[{forbidden_lookahead, _la} | _] when forbidden_lookahead in [:space, :newline] ->
|
||||
{:ok, [{:text, open}], r_tokens}
|
||||
|
||||
_ ->
|
||||
case repeat(callback, put_state(parser, state), r_tokens, false, level) do
|
||||
{:ok, tree, [{^close_token, close}, {^lookahead_not, ln} | r2_tokens]} ->
|
||||
{:ok, [{:text, open}, tree, {:text, close}], [{lookahead_not, ln} | r2_tokens]}
|
||||
|
||||
{:ok, tree, [{^close_token, _} | r2_tokens]} ->
|
||||
{:ok, [{:markup, open_tag}, tree, {:markup, close_tag}], r2_tokens}
|
||||
|
||||
{:ok, tree, r2_tokens} ->
|
||||
{:ok, [{:text, open}, tree], r2_tokens}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp simple_lookahead_not(
|
||||
_open_token,
|
||||
_close_token,
|
||||
_open_tag,
|
||||
_close_tag,
|
||||
_lookahead_not,
|
||||
_callback,
|
||||
_state,
|
||||
_parser,
|
||||
_tokens,
|
||||
_level
|
||||
) do
|
||||
{:error, "Expected a simple lookahead not rule"}
|
||||
end
|
||||
|
||||
# Helper to efficiently assemble a UTF-8 binary from tokens of the
|
||||
# given type
|
||||
defp assemble_binary(token_type, accumulator, [{token_type, t} | stream]) do
|
||||
assemble_binary(token_type, accumulator <> <<t::utf8>>, stream)
|
||||
end
|
||||
|
||||
defp assemble_binary(_token_type, accumulator, tokens), do: {accumulator, tokens}
|
||||
|
||||
#
|
||||
# inline_textile_element =
|
||||
# opening_markup inline_textile_element* closing_markup (?!quicktxt) |
|
||||
# closing_markup (?=quicktxt) |
|
||||
# link_delim block_textile_element* link_url |
|
||||
# image url? |
|
||||
# code_delim inline_textile_element* code_delim |
|
||||
# inline_textile_element_not_opening_markup;
|
||||
#
|
||||
|
||||
defp inline_textile_element(parser, tokens, level) do
|
||||
[
|
||||
{:b_delim, :b, "**", "**"},
|
||||
{:i_delim, :i, "_", "_"},
|
||||
{:strong_delim, :strong, "**", "**"},
|
||||
{:em_delim, :em, "*", "*"},
|
||||
{:ins_delim, :ins, "__", "__"},
|
||||
{:sup_delim, :sup, "^", "^"},
|
||||
{:del_delim, :del, "~~", "~~"},
|
||||
{:sub_delim, :sub, "%", "%"}
|
||||
]
|
||||
|> Enum.find_value(fn {delim_token, state, open_tag, close_tag} ->
|
||||
simple_lookahead_not(
|
||||
delim_token,
|
||||
delim_token,
|
||||
open_tag,
|
||||
close_tag,
|
||||
:quicktxt,
|
||||
&inline_textile_element/3,
|
||||
state,
|
||||
parser,
|
||||
tokens,
|
||||
level
|
||||
)
|
||||
|> case do
|
||||
{:ok, tree, r_tokens} ->
|
||||
{:ok, tree, r_tokens}
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end)
|
||||
|> case do
|
||||
nil -> inner_inline_textile_element(parser, tokens, level)
|
||||
value -> value
|
||||
end
|
||||
end
|
||||
|
||||
defp inner_inline_textile_element(parser, [{token, t}, {:quicktxt, q} | r_tokens], level)
|
||||
when token in [
|
||||
:b_delim,
|
||||
:i_delim,
|
||||
:strong_delim,
|
||||
:em_delim,
|
||||
:ins_delim,
|
||||
:sup_delim,
|
||||
:del_delim,
|
||||
:sub_delim
|
||||
] do
|
||||
case inline_textile_element(parser, [{:quicktxt, q} | r_tokens], level) do
|
||||
{:ok, tree, r2_tokens} ->
|
||||
{:ok, [{:text, t}, tree], r2_tokens}
|
||||
|
||||
_ ->
|
||||
{:ok, [{:text, t}], [{:quicktxt, q} | r_tokens]}
|
||||
end
|
||||
end
|
||||
|
||||
defp inner_inline_textile_element(parser, [{:link_delim, open} | r_tokens], level) do
|
||||
case repeat(&block_textile_element/3, parser, r_tokens, false, level) do
|
||||
{:ok, tree, [{:unbracketed_link_url, <<"\":", url::binary>>} | r2_tokens]} ->
|
||||
href = url
|
||||
|
||||
{:ok, [{:markup, "["}, tree, {:markup, "]("}, {:markup, href}, {:markup, ")"}], r2_tokens}
|
||||
|
||||
{:ok, tree, r2_tokens} ->
|
||||
{:ok, [{:text, open}, tree], r2_tokens}
|
||||
end
|
||||
end
|
||||
|
||||
defp inner_inline_textile_element(parser, [{:bracketed_link_open, open} | r_tokens], level) do
|
||||
case repeat(&inline_textile_element/3, parser, r_tokens, false, level) do
|
||||
{:ok, tree, [{:bracketed_link_url, <<"\":", url::binary>>} | r2_tokens]} ->
|
||||
href = url
|
||||
|
||||
{:ok, [{:markup, "["}, tree, {:markup, "]("}, {:markup, href}, {:markup, ")"}], r2_tokens}
|
||||
|
||||
{:ok, tree, r2_tokens} ->
|
||||
{:ok, [{:text, open}, tree], r2_tokens}
|
||||
end
|
||||
end
|
||||
|
||||
defp inner_inline_textile_element(
|
||||
parser,
|
||||
[
|
||||
{token, img},
|
||||
{:unbracketed_image_url, <<":", url::binary>>} | r_tokens
|
||||
],
|
||||
level
|
||||
)
|
||||
when token in [:unbracketed_image, :bracketed_image] do
|
||||
img = parser.image_transform.(img)
|
||||
|
||||
{:ok,
|
||||
[
|
||||
{:markup, "[![full]("},
|
||||
{:markup, img},
|
||||
{:markup, ")]("},
|
||||
{:markup, url},
|
||||
{:markup, ")"}
|
||||
], r_tokens}
|
||||
end
|
||||
|
||||
defp inner_inline_textile_element(parser, [{token, img} | r_tokens], level)
|
||||
when token in [:unbracketed_image, :bracketed_image] do
|
||||
img = parser.image_transform.(img)
|
||||
|
||||
{:ok,
|
||||
[
|
||||
{:markup, "![full]("},
|
||||
{:markup, img},
|
||||
{:markup, ")"}
|
||||
], r_tokens}
|
||||
end
|
||||
|
||||
defp inner_inline_textile_element(parser, [{:code_delim, open} | r_tokens], level) do
|
||||
case parser.state do
|
||||
%{code: _} ->
|
||||
{:error, "End of rule"}
|
||||
|
||||
_ ->
|
||||
case repeat(&inline_textile_element/3, put_state(parser, :code), r_tokens, false, level) do
|
||||
{:ok, tree, [{:code_delim, _} | r2_tokens]} ->
|
||||
{:ok, [{:markup, "`"}, tree, {:markup, "`"}], r2_tokens}
|
||||
|
||||
{:ok, tree, r2_tokens} ->
|
||||
{:ok, [{:text, open}, tree], r2_tokens}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp inner_inline_textile_element(parser, tokens, level \\ 0) do
|
||||
inline_textile_element_not_opening_markup(parser, tokens, level)
|
||||
end
|
||||
|
||||
#
|
||||
# bq_cite_text = (?!bq_cite_open);
|
||||
#
|
||||
|
||||
# Note that text is not escaped here because it will be escaped
|
||||
# when the tree is flattened
|
||||
defp bq_cite_text(_parser, [{:bq_cite_open, _open} | _rest], level) do
|
||||
{:error, "Expected cite tokens"}
|
||||
end
|
||||
|
||||
defp bq_cite_text(_parser, [{:char, lit} | r_tokens], level) do
|
||||
{:ok, [{:text, <<lit::utf8>>}], r_tokens}
|
||||
end
|
||||
|
||||
defp bq_cite_text(_parser, [{:quicktxt, lit} | r_tokens], level) do
|
||||
{:ok, [{:text, <<lit::utf8>>}], r_tokens}
|
||||
end
|
||||
|
||||
defp bq_cite_text(_parser, [{:space, _} | r_tokens], level) do
|
||||
{:ok, [{:text, " "}], r_tokens}
|
||||
end
|
||||
|
||||
defp bq_cite_text(_parser, [{_token, t} | r_tokens], level) do
|
||||
{:ok, [{:text, t}], r_tokens}
|
||||
end
|
||||
|
||||
defp bq_cite_text(_parser, _tokens, _level) do
|
||||
{:error, "Expected cite tokens"}
|
||||
end
|
||||
|
||||
#
|
||||
# inline_textile_element_not_opening_markup =
|
||||
# literal | space | char |
|
||||
# quicktxt opening_markup quicktxt |
|
||||
# quicktxt |
|
||||
# opening_block_tag block_textile_element* closing_block_tag;
|
||||
#
|
||||
|
||||
defp inline_textile_element_not_opening_markup(_parser, [{:literal, lit} | r_tokens], level) do
|
||||
{:ok, [{:markup, Markdown.escape_markdown(lit)}], r_tokens}
|
||||
end
|
||||
|
||||
defp inline_textile_element_not_opening_markup(_parser, [{:space, _} | r_tokens], level) do
|
||||
{:ok, [{:text, " "}], r_tokens}
|
||||
end
|
||||
|
||||
defp inline_textile_element_not_opening_markup(_parser, [{:char, lit} | r_tokens], level) do
|
||||
{binary, r2_tokens} = assemble_binary(:char, <<lit::utf8>>, r_tokens)
|
||||
{:ok, [{:text, binary}], r2_tokens}
|
||||
end
|
||||
|
||||
defp inline_textile_element_not_opening_markup(
|
||||
_parser,
|
||||
[
|
||||
{:quicktxt, q1},
|
||||
{token, t},
|
||||
{:quicktxt, q2} | r_tokens
|
||||
],
|
||||
level
|
||||
)
|
||||
when token in [
|
||||
:b_delim,
|
||||
:i_delim,
|
||||
:strong_delim,
|
||||
:em_delim,
|
||||
:ins_delim,
|
||||
:sup_delim,
|
||||
:del_delim,
|
||||
:sub_delim
|
||||
] do
|
||||
{:ok, [{:text, <<q1::utf8>>}, {:text, t}, {:text, <<q2::utf8>>}], r_tokens}
|
||||
end
|
||||
|
||||
defp inline_textile_element_not_opening_markup(_parser, [{:quicktxt, lit} | r_tokens], level) do
|
||||
{:ok, [{:text, <<lit::utf8>>}], r_tokens}
|
||||
end
|
||||
|
||||
defp inline_textile_element_not_opening_markup(
|
||||
parser,
|
||||
[{:bq_cite_start, start} | r_tokens],
|
||||
level
|
||||
) do
|
||||
case repeat(&bq_cite_text/3, parser, r_tokens, false, level) do
|
||||
{:ok, tree, [{:bq_cite_open, open} | r2_tokens]} ->
|
||||
case repeat(&block_textile_element/4, parser, r2_tokens, true, level + 1) do
|
||||
{:ok, tree2, [{:bq_close, _} | r3_tokens], level} ->
|
||||
cite = flatten(tree)
|
||||
|
||||
{:ok,
|
||||
[
|
||||
{:markup, "\n" <> String.duplicate("> ", level)},
|
||||
tree2,
|
||||
{:markup, "\n" <> String.duplicate("> ", level - 1)}
|
||||
], r3_tokens}
|
||||
|
||||
{:ok, tree2, r3_tokens, level} ->
|
||||
{:ok,
|
||||
[
|
||||
{:text, start},
|
||||
{:text, flatten(tree)},
|
||||
{:text, open},
|
||||
tree2
|
||||
], r3_tokens}
|
||||
end
|
||||
|
||||
_ ->
|
||||
{:ok, [{:text, start}], r_tokens}
|
||||
end
|
||||
end
|
||||
|
||||
defp inline_textile_element_not_opening_markup(
|
||||
_parser,
|
||||
[{:bq_cite_open, tok} | r_tokens],
|
||||
level
|
||||
) do
|
||||
{:ok, [{:text, tok}], r_tokens}
|
||||
end
|
||||
|
||||
defp inline_textile_element_not_opening_markup(
|
||||
parser,
|
||||
[{:bq_open, start} | r_tokens],
|
||||
level
|
||||
) do
|
||||
case repeat(&block_textile_element/4, parser, r_tokens, true, level + 1) do
|
||||
{:ok, tree, [{:bq_close, _} | r2_tokens], level} ->
|
||||
{:ok,
|
||||
[
|
||||
{:markup, "\n" <> String.duplicate("> ", level)},
|
||||
tree,
|
||||
{:markup, "\n" <> String.duplicate("> ", level - 1)}
|
||||
], r2_tokens}
|
||||
|
||||
{:ok, tree, r2_tokens, level} ->
|
||||
{:ok,
|
||||
[
|
||||
{:text, start},
|
||||
{:text, flatten_unquote(tree)}
|
||||
], r2_tokens}
|
||||
end
|
||||
end
|
||||
|
||||
defp inline_textile_element_not_opening_markup(
|
||||
_parser,
|
||||
[{:bq_open, tok} | r_tokens],
|
||||
level
|
||||
) do
|
||||
{:ok, [{:text, tok}], r_tokens}
|
||||
end
|
||||
|
||||
defp inline_textile_element_not_opening_markup(parser, tokens, level) do
|
||||
[
|
||||
{:spoiler_open, :spoiler_close, "||", "||"},
|
||||
{:bracketed_b_open, :bracketed_b_close, "**", "**"},
|
||||
{:bracketed_i_open, :bracketed_i_close, "_", "_"},
|
||||
{:bracketed_strong_open, :bracketed_strong_close, "**", "**"},
|
||||
{:bracketed_em_open, :bracketed_em_close, "*", "*"},
|
||||
{:bracketed_code_open, :bracketed_code_close, "```", "```"},
|
||||
{:bracketed_ins_open, :bracketed_ins_close, "__", "__"},
|
||||
{:bracketed_sup_open, :bracketed_sup_close, "^", "^"},
|
||||
{:bracketed_del_open, :bracketed_del_close, "~~", "~~"},
|
||||
{:bracketed_sub_open, :bracketed_sub_close, "%", "%"}
|
||||
]
|
||||
|> Enum.find_value(fn {open_token, close_token, open_tag, close_tag} ->
|
||||
simple_recursive(
|
||||
open_token,
|
||||
close_token,
|
||||
open_tag,
|
||||
close_tag,
|
||||
&block_textile_element/3,
|
||||
parser,
|
||||
tokens,
|
||||
level
|
||||
)
|
||||
|> case do
|
||||
{:ok, tree, r_tokens} ->
|
||||
{:ok, tree, r_tokens}
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end)
|
||||
|> Kernel.||({:error, "Expected block markup"})
|
||||
end
|
||||
|
||||
#
|
||||
# block_textile_element =
|
||||
# double_newline | newline | inline_textile_element;
|
||||
#
|
||||
|
||||
defp block_textile_element(_parser, [{:double_newline, _} | r_tokens], bq, level)
|
||||
when bq == true do
|
||||
one = "\n" <> String.duplicate("> ", level)
|
||||
{:ok, [{:markup, String.duplicate(one, 2)}], r_tokens}
|
||||
end
|
||||
|
||||
defp block_textile_element(_parser, [{:newline, _} | r_tokens], bq, level) when bq == true do
|
||||
{:ok, [{:markup, "\n" <> String.duplicate("> ", level)}], r_tokens}
|
||||
end
|
||||
|
||||
defp block_textile_element(parser, tokens, _bq, level) do
|
||||
inline_textile_element(parser, tokens, level)
|
||||
end
|
||||
|
||||
defp block_textile_element(_parser, [{:double_newline, _} | r_tokens]) do
|
||||
{:ok, [{:markup, "\n\n"}], r_tokens}
|
||||
end
|
||||
|
||||
defp block_textile_element(_parser, [{:newline, _} | r_tokens]) do
|
||||
{:ok, [{:markup, "\n"}], r_tokens}
|
||||
end
|
||||
|
||||
defp block_textile_element(parser, tokens, level) do
|
||||
inline_textile_element(parser, tokens, level)
|
||||
end
|
||||
|
||||
#
|
||||
# textile =
|
||||
# (block_textile_element | TOKEN)* eos;
|
||||
#
|
||||
|
||||
defp textile(parser, tokens, level) do
|
||||
case block_textile_element(parser, tokens, level) do
|
||||
{:ok, tree, r_tokens} ->
|
||||
{:ok, tree, r_tokens}
|
||||
|
||||
_ ->
|
||||
case tokens do
|
||||
[{_, string} | r_tokens] ->
|
||||
{:ok, [{:text, string}], r_tokens}
|
||||
|
||||
_ ->
|
||||
{:error, "Expected textile"}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -65,6 +65,7 @@ defmodule Philomena.Users.User do
|
|||
field :slug, :string
|
||||
field :role, :string, default: "user"
|
||||
field :description, :string
|
||||
field :description_md, :string
|
||||
field :avatar, :string
|
||||
|
||||
# Settings
|
||||
|
@ -115,6 +116,7 @@ defmodule Philomena.Users.User do
|
|||
field :last_renamed_at, :utc_datetime
|
||||
field :deleted_at, :utc_datetime
|
||||
field :scratchpad, :string
|
||||
field :scratchpad_md, :string
|
||||
field :secondary_role, :string
|
||||
field :hide_default_role, :boolean, default: false
|
||||
field :senior_staff, :boolean, default: false
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule PhilomenaWeb.Admin.DnpEntryController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.DnpEntries.DnpEntry
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
@ -44,8 +44,8 @@ defmodule PhilomenaWeb.Admin.DnpEntryController do
|
|||
|
||||
bodies =
|
||||
dnp_entries
|
||||
|> Enum.map(&%{body: &1.conditions})
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> Enum.map(&%{body: &1.conditions, body_md: &1.conditions_md})
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|
||||
dnp_entries = %{dnp_entries | entries: Enum.zip(bodies, dnp_entries.entries)}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule PhilomenaWeb.Admin.ModNoteController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.ModNotes.ModNote
|
||||
alias Philomena.Polymorphic
|
||||
alias Philomena.ModNotes
|
||||
|
@ -29,7 +29,7 @@ defmodule PhilomenaWeb.Admin.ModNoteController do
|
|||
|> order_by(desc: :id)
|
||||
|> Repo.paginate(conn.assigns.scrivener)
|
||||
|
||||
bodies = TextileRenderer.render_collection(mod_notes, conn)
|
||||
bodies = TextRenderer.render_collection(mod_notes, conn)
|
||||
preloaded = Polymorphic.load_polymorphic(mod_notes, notable: [notable_id: :notable_type])
|
||||
mod_notes = %{mod_notes | entries: Enum.zip(bodies, preloaded)}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule PhilomenaWeb.Admin.ReportController do
|
|||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.Elasticsearch
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Reports.Report
|
||||
alias Philomena.Reports.Query
|
||||
alias Philomena.Polymorphic
|
||||
|
@ -73,7 +73,7 @@ defmodule PhilomenaWeb.Admin.ReportController do
|
|||
reportable: [reportable_id: :reportable_type]
|
||||
)
|
||||
|
||||
body = TextileRenderer.render_one(%{body: report.reason}, conn)
|
||||
body = TextRenderer.render_one(%{body: report.reason, body_md: report.reason_md}, conn)
|
||||
|
||||
render(conn, "show.html", title: "Showing Report", report: report, body: body)
|
||||
end
|
||||
|
@ -125,7 +125,7 @@ defmodule PhilomenaWeb.Admin.ReportController do
|
|||
|
||||
mod_notes =
|
||||
mod_notes
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|> Enum.zip(mod_notes)
|
||||
|
||||
assign(conn, :mod_notes, mod_notes)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule PhilomenaWeb.CommentController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Elasticsearch
|
||||
alias Philomena.{Comments.Query, Comments.Comment}
|
||||
import Ecto.Query
|
||||
|
@ -39,7 +39,7 @@ defmodule PhilomenaWeb.CommentController do
|
|||
preload(Comment, [:deleted_by, image: [tags: :aliases], user: [awards: :badge]])
|
||||
)
|
||||
|
||||
rendered = TextileRenderer.render_collection(comments.entries, conn)
|
||||
rendered = TextRenderer.render_collection(comments.entries, conn)
|
||||
|
||||
comments = %{comments | entries: Enum.zip(rendered, comments.entries)}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule PhilomenaWeb.ConversationController do
|
|||
|
||||
alias PhilomenaWeb.NotificationCountPlug
|
||||
alias Philomena.{Conversations, Conversations.Conversation, Conversations.Message}
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
|
@ -72,7 +72,7 @@ defmodule PhilomenaWeb.ConversationController do
|
|||
|
||||
rendered =
|
||||
messages.entries
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|
||||
messages = %{messages | entries: Enum.zip(messages.entries, rendered)}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule PhilomenaWeb.DnpEntryController do
|
|||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.DnpEntries.DnpEntry
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.DnpEntries
|
||||
alias Philomena.Tags.Tag
|
||||
alias Philomena.ModNotes.ModNote
|
||||
|
@ -43,8 +43,8 @@ defmodule PhilomenaWeb.DnpEntryController do
|
|||
|
||||
bodies =
|
||||
dnp_entries
|
||||
|> Enum.map(&%{body: &1.conditions || "-"})
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> Enum.map(&%{body_md: &1.conditions_md, body: &1.conditions || "-"})
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|
||||
dnp_entries = %{dnp_entries | entries: Enum.zip(bodies, dnp_entries.entries)}
|
||||
|
||||
|
@ -61,11 +61,11 @@ defmodule PhilomenaWeb.DnpEntryController do
|
|||
dnp_entry = conn.assigns.dnp_entry
|
||||
|
||||
[conditions, reason, instructions] =
|
||||
TextileRenderer.render_collection(
|
||||
TextRenderer.render_collection(
|
||||
[
|
||||
%{body: dnp_entry.conditions || "-"},
|
||||
%{body: dnp_entry.reason || "-"},
|
||||
%{body: dnp_entry.instructions || "-"}
|
||||
%{body_md: dnp_entry.conditions_md, body: dnp_entry.conditions || "-"},
|
||||
%{body_md: dnp_entry.reason_md, body: dnp_entry.reason || "-"},
|
||||
%{body_md: dnp_entry.instructions_md, body: dnp_entry.instructions || "-"}
|
||||
],
|
||||
conn
|
||||
)
|
||||
|
@ -164,7 +164,7 @@ defmodule PhilomenaWeb.DnpEntryController do
|
|||
|
||||
mod_notes =
|
||||
mod_notes
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|> Enum.zip(mod_notes)
|
||||
|
||||
assign(conn, :mod_notes, mod_notes)
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule PhilomenaWeb.Image.CommentController do
|
|||
use PhilomenaWeb, :controller
|
||||
|
||||
alias PhilomenaWeb.CommentLoader
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.{Images.Image, Comments.Comment}
|
||||
alias Philomena.UserStatistics
|
||||
alias Philomena.Comments
|
||||
|
@ -48,7 +48,7 @@ defmodule PhilomenaWeb.Image.CommentController do
|
|||
def index(conn, _params) do
|
||||
comments = CommentLoader.load_comments(conn, conn.assigns.image)
|
||||
|
||||
rendered = TextileRenderer.render_collection(comments.entries, conn)
|
||||
rendered = TextRenderer.render_collection(comments.entries, conn)
|
||||
|
||||
comments = %{comments | entries: Enum.zip(comments.entries, rendered)}
|
||||
|
||||
|
@ -56,7 +56,7 @@ defmodule PhilomenaWeb.Image.CommentController do
|
|||
end
|
||||
|
||||
def show(conn, _params) do
|
||||
rendered = TextileRenderer.render_one(conn.assigns.comment, conn)
|
||||
rendered = TextRenderer.render_one(conn.assigns.comment, conn)
|
||||
|
||||
render(conn, "show.html",
|
||||
layout: false,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule PhilomenaWeb.Image.DescriptionController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.Images
|
||||
|
||||
|
@ -34,7 +34,8 @@ defmodule PhilomenaWeb.Image.DescriptionController do
|
|||
|
||||
Images.reindex_image(image)
|
||||
|
||||
body = TextileRenderer.render_one(%{body: image.description}, conn)
|
||||
body =
|
||||
TextRenderer.render_one(%{body: image.description, body_md: image.description_md}, conn)
|
||||
|
||||
conn
|
||||
|> put_view(PhilomenaWeb.ImageView)
|
||||
|
|
|
@ -4,7 +4,7 @@ defmodule PhilomenaWeb.ImageController do
|
|||
alias PhilomenaWeb.ImageLoader
|
||||
alias PhilomenaWeb.CommentLoader
|
||||
alias PhilomenaWeb.NotificationCountPlug
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
|
||||
alias Philomena.{
|
||||
Images,
|
||||
|
@ -63,13 +63,13 @@ defmodule PhilomenaWeb.ImageController do
|
|||
|
||||
comments = CommentLoader.load_comments(conn, image)
|
||||
|
||||
rendered = TextileRenderer.render_collection(comments.entries, conn)
|
||||
rendered = TextRenderer.render_collection(comments.entries, conn)
|
||||
|
||||
comments = %{comments | entries: Enum.zip(comments.entries, rendered)}
|
||||
|
||||
description =
|
||||
%{body: image.description}
|
||||
|> TextileRenderer.render_one(conn)
|
||||
%{body: image.description, body_md: image.description_md}
|
||||
|> TextRenderer.render_one(conn)
|
||||
|
||||
interactions = Interactions.user_interactions([image], conn.assigns.current_user)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule PhilomenaWeb.Post.PreviewController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Posts.Post
|
||||
alias Philomena.Repo
|
||||
|
||||
|
@ -11,7 +11,7 @@ defmodule PhilomenaWeb.Post.PreviewController do
|
|||
anonymous = params["anonymous"] == true
|
||||
|
||||
post = %Post{user: user, body: body, anonymous: anonymous}
|
||||
rendered = TextileRenderer.render_one(post, conn)
|
||||
rendered = TextRenderer.render_one(post, conn)
|
||||
|
||||
render(conn, "create.html", layout: false, post: post, body: rendered)
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule PhilomenaWeb.PostController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Elasticsearch
|
||||
alias Philomena.{Posts.Query, Posts.Post}
|
||||
import Ecto.Query
|
||||
|
@ -36,7 +36,7 @@ defmodule PhilomenaWeb.PostController do
|
|||
preload(Post, [:deleted_by, topic: :forum, user: [awards: :badge]])
|
||||
)
|
||||
|
||||
rendered = TextileRenderer.render_collection(posts.entries, conn)
|
||||
rendered = TextRenderer.render_collection(posts.entries, conn)
|
||||
|
||||
posts = %{posts | entries: Enum.zip(rendered, posts.entries)}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule PhilomenaWeb.Profile.CommissionController do
|
|||
|
||||
alias Philomena.Commissions.Commission
|
||||
alias Philomena.Commissions
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Users.User
|
||||
|
||||
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create, :edit, :update, :delete]
|
||||
|
@ -36,21 +36,21 @@ defmodule PhilomenaWeb.Profile.CommissionController do
|
|||
|
||||
item_descriptions =
|
||||
items
|
||||
|> Enum.map(&%{body: &1.description})
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> Enum.map(&%{body: &1.description, body_md: &1.description_md})
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|
||||
item_add_ons =
|
||||
items
|
||||
|> Enum.map(&%{body: &1.add_ons})
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> Enum.map(&%{body: &1.add_ons, body_md: &1.add_ons_md})
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|
||||
[information, contact, will_create, will_not_create] =
|
||||
TextileRenderer.render_collection(
|
||||
TextRenderer.render_collection(
|
||||
[
|
||||
%{body: commission.information || ""},
|
||||
%{body: commission.contact || ""},
|
||||
%{body: commission.will_create || ""},
|
||||
%{body: commission.will_not_create || ""}
|
||||
%{body_md: commission.information_md, body: commission.information || ""},
|
||||
%{body_md: commission.contact_md, body: commission.contact || ""},
|
||||
%{body_md: commission.will_create_md, body: commission.will_create || ""},
|
||||
%{body_md: commission.will_not_create_md, body: commission.will_not_create || ""}
|
||||
],
|
||||
conn
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule PhilomenaWeb.Profile.DetailController do
|
|||
|
||||
alias Philomena.UserNameChanges.UserNameChange
|
||||
alias Philomena.ModNotes.ModNote
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Polymorphic
|
||||
alias Philomena.Users.User
|
||||
alias Philomena.Repo
|
||||
|
@ -30,7 +30,7 @@ defmodule PhilomenaWeb.Profile.DetailController do
|
|||
|
||||
mod_notes =
|
||||
mod_notes
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|> Enum.zip(mod_notes)
|
||||
|
||||
name_changes =
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
|
||||
alias PhilomenaWeb.ImageLoader
|
||||
alias Philomena.Elasticsearch
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.UserStatistics.UserStatistic
|
||||
alias Philomena.Users.User
|
||||
alias Philomena.Bans
|
||||
|
@ -131,12 +131,14 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
recent_comments =
|
||||
recent_comments
|
||||
|> Enum.filter(&Canada.Can.can?(current_user, :show, &1.image))
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|> Enum.zip(recent_comments)
|
||||
|
||||
about_me = TextileRenderer.render_one(%{body: user.description || ""}, conn)
|
||||
about_me =
|
||||
TextRenderer.render_one(%{body_md: user.description_md, body: user.description || ""}, conn)
|
||||
|
||||
scratchpad = TextileRenderer.render_one(%{body: user.scratchpad || ""}, conn)
|
||||
scratchpad =
|
||||
TextRenderer.render_one(%{body_md: user.scratchpad_md, body: user.scratchpad || ""}, conn)
|
||||
|
||||
commission_information = commission_info(user.commission, conn)
|
||||
|
||||
|
@ -214,8 +216,9 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
defp map_fetch(nil, _field_name), do: nil
|
||||
defp map_fetch(map, field_name), do: Map.get(map, field_name)
|
||||
|
||||
defp commission_info(%{information: info}, conn) when info not in [nil, ""],
|
||||
do: TextileRenderer.render_one(%{body: info}, conn)
|
||||
defp commission_info(%{information: info, information_md: info_md}, conn)
|
||||
when info not in [nil, ""],
|
||||
do: TextRenderer.render_one(%{body: info, body_md: info_md}, conn)
|
||||
|
||||
defp commission_info(_commission, _conn), do: ""
|
||||
|
||||
|
@ -282,7 +285,7 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
|
||||
mod_notes =
|
||||
mod_notes
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> TextRenderer.render_collection(conn)
|
||||
|> Enum.zip(mod_notes)
|
||||
|
||||
assign(conn, :mod_notes, mod_notes)
|
||||
|
|
|
@ -5,7 +5,7 @@ defmodule PhilomenaWeb.TagController do
|
|||
alias Philomena.Elasticsearch
|
||||
alias Philomena.{Tags, Tags.Tag}
|
||||
alias Philomena.{Images, Images.Image}
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Interactions
|
||||
import Ecto.Query
|
||||
|
||||
|
@ -61,11 +61,12 @@ defmodule PhilomenaWeb.TagController do
|
|||
|
||||
interactions = Interactions.user_interactions(images, user)
|
||||
|
||||
body = TextileRenderer.render_one(%{body: tag.description || ""}, conn)
|
||||
body =
|
||||
TextRenderer.render_one(%{body_md: tag.description_md, body: tag.description || ""}, conn)
|
||||
|
||||
dnp_bodies =
|
||||
TextileRenderer.render_collection(
|
||||
Enum.map(tag.dnp_entries, &%{body: &1.conditions || ""}),
|
||||
TextRenderer.render_collection(
|
||||
Enum.map(tag.dnp_entries, &%{body_md: &1.conditions_md, body: &1.conditions || ""}),
|
||||
conn
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ defmodule PhilomenaWeb.TopicController do
|
|||
alias Philomena.{Forums.Forum, Topics.Topic, Posts.Post, Polls.Poll, PollOptions.PollOption}
|
||||
alias Philomena.{Forums, Topics, Polls, Posts}
|
||||
alias Philomena.PollVotes
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
|
@ -60,7 +60,7 @@ defmodule PhilomenaWeb.TopicController do
|
|||
|> preload([:deleted_by, :topic, topic: :forum, user: [awards: :badge]])
|
||||
|> Repo.all()
|
||||
|
||||
rendered = TextileRenderer.render_collection(posts, conn)
|
||||
rendered = TextRenderer.render_collection(posts, conn)
|
||||
|
||||
posts = Enum.zip(posts, rendered)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule PhilomenaWeb.ImageLoader do
|
|||
alias PhilomenaWeb.ImageSorter
|
||||
alias Philomena.Elasticsearch
|
||||
alias Philomena.Images.{Image, Query}
|
||||
alias PhilomenaWeb.TextileRenderer
|
||||
alias PhilomenaWeb.TextRenderer
|
||||
alias Philomena.Tags.Tag
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
@ -132,14 +132,15 @@ defmodule PhilomenaWeb.ImageLoader do
|
|||
|
||||
defp render_bodies([tag], conn) do
|
||||
dnp_bodies =
|
||||
TextileRenderer.render_collection(
|
||||
Enum.map(tag.dnp_entries, &%{body: &1.conditions || ""}),
|
||||
TextRenderer.render_collection(
|
||||
Enum.map(tag.dnp_entries, &%{body_md: &1.conditions_md, body: &1.conditions || ""}),
|
||||
conn
|
||||
)
|
||||
|
||||
dnp_entries = Enum.zip(dnp_bodies, tag.dnp_entries)
|
||||
|
||||
description = TextileRenderer.render_one(%{body: tag.description || ""}, conn)
|
||||
description =
|
||||
TextRenderer.render_one(%{body_md: tag.description_md, body: tag.description || ""}, conn)
|
||||
|
||||
[{tag, description, dnp_entries}]
|
||||
end
|
||||
|
|
106
lib/philomena_web/markdown_renderer.ex
Normal file
106
lib/philomena_web/markdown_renderer.ex
Normal file
|
@ -0,0 +1,106 @@
|
|||
defmodule PhilomenaWeb.MarkdownRenderer do
|
||||
alias Philomena.Markdown
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.Repo
|
||||
import Phoenix.HTML
|
||||
import Phoenix.HTML.Link
|
||||
import Ecto.Query
|
||||
|
||||
@image_view Module.concat(["PhilomenaWeb.ImageView"])
|
||||
|
||||
def render(text, conn) do
|
||||
images = find_images(text)
|
||||
representations = render_representations(images, conn)
|
||||
|
||||
Markdown.to_html(text, representations)
|
||||
end
|
||||
|
||||
defp find_images(text) do
|
||||
Regex.scan(~r/>>(\d+)([tsp])?/, text, capture: :all_but_first)
|
||||
|> Enum.map(fn matches ->
|
||||
[Enum.at(matches, 0) |> String.to_integer(), Enum.at(matches, 1) || ""]
|
||||
end)
|
||||
|> Enum.filter(fn m -> Enum.at(m, 0) < 2_147_483_647 end)
|
||||
end
|
||||
|
||||
defp load_images(images) do
|
||||
ids = Enum.map(images, fn m -> Enum.at(m, 0) end)
|
||||
|
||||
Image
|
||||
|> where([i], i.id in ^ids)
|
||||
|> preload(tags: :aliases)
|
||||
|> Repo.all()
|
||||
|> Map.new(&{&1.id, &1})
|
||||
end
|
||||
|
||||
defp link_suffix(image) do
|
||||
cond do
|
||||
not is_nil(image.duplicate_id) ->
|
||||
" (merged)"
|
||||
|
||||
image.hidden_from_users ->
|
||||
" (deleted)"
|
||||
|
||||
true ->
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
defp render_representations(images, conn) do
|
||||
loaded_images = load_images(images)
|
||||
|
||||
images
|
||||
|> Enum.map(fn group ->
|
||||
img = loaded_images[Enum.at(group, 0)]
|
||||
text = "#{Enum.at(group, 0)}#{Enum.at(group, 1)}"
|
||||
|
||||
rendered =
|
||||
cond do
|
||||
img != nil ->
|
||||
case group do
|
||||
[_id, "p"] when not img.hidden_from_users ->
|
||||
Phoenix.View.render(@image_view, "_image_target.html",
|
||||
image: img,
|
||||
size: :medium,
|
||||
conn: conn
|
||||
)
|
||||
|> safe_to_string()
|
||||
|
||||
[_id, "t"] when not img.hidden_from_users ->
|
||||
Phoenix.View.render(@image_view, "_image_target.html",
|
||||
image: img,
|
||||
size: :small,
|
||||
conn: conn
|
||||
)
|
||||
|> safe_to_string()
|
||||
|
||||
[_id, "s"] when not img.hidden_from_users ->
|
||||
Phoenix.View.render(@image_view, "_image_target.html",
|
||||
image: img,
|
||||
size: :thumb_small,
|
||||
conn: conn
|
||||
)
|
||||
|> safe_to_string()
|
||||
|
||||
[_id, ""] ->
|
||||
link(">>#{img.id}#{link_suffix(img)}", to: "/images/#{img.id}")
|
||||
|> safe_to_string()
|
||||
|
||||
[_id, suffix] when suffix in ["t", "s", "p"] ->
|
||||
link(">>#{img.id}#{suffix}#{link_suffix(img)}", to: "/images/#{img.id}")
|
||||
|> safe_to_string()
|
||||
|
||||
# This condition should never trigger, but let's leave it here just in case.
|
||||
[id, suffix] ->
|
||||
">>#{id}#{suffix}"
|
||||
end
|
||||
|
||||
true ->
|
||||
">>#{text}"
|
||||
end
|
||||
|
||||
[text, rendered]
|
||||
end)
|
||||
|> Map.new(fn [id, html] -> {id, html} end)
|
||||
end
|
||||
end
|
19
lib/philomena_web/text_renderer.ex
Normal file
19
lib/philomena_web/text_renderer.ex
Normal file
|
@ -0,0 +1,19 @@
|
|||
defmodule PhilomenaWeb.TextRenderer do
|
||||
alias PhilomenaWeb.MarkdownRenderer
|
||||
alias PhilomenaWeb.TextileMarkdownRenderer
|
||||
|
||||
def render_one(item, conn) do
|
||||
hd(render_collection([item], conn))
|
||||
end
|
||||
|
||||
def render_collection(items, conn) do
|
||||
Enum.map(items, fn item ->
|
||||
if Map.has_key?(item, :body_md) && item.body_md != nil && item.body_md != "" do
|
||||
MarkdownRenderer.render(item.body_md, conn)
|
||||
else
|
||||
markdown = TextileMarkdownRenderer.render_one(item)
|
||||
MarkdownRenderer.render(markdown, conn)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
22
lib/philomena_web/textile_markdown_renderer.ex
Normal file
22
lib/philomena_web/textile_markdown_renderer.ex
Normal file
|
@ -0,0 +1,22 @@
|
|||
defmodule PhilomenaWeb.TextileMarkdownRenderer do
|
||||
alias Philomena.Textile.ParserMarkdown
|
||||
|
||||
def render_one(post) do
|
||||
hd(render_collection([post]))
|
||||
end
|
||||
|
||||
def render_collection(posts) do
|
||||
opts = %{image_transform: &Camo.Image.image_url/1}
|
||||
parsed = Enum.map(posts, &ParserMarkdown.parse(opts, &1.body))
|
||||
|
||||
parsed
|
||||
|> Enum.map(fn tree ->
|
||||
tree
|
||||
|> Enum.map(fn
|
||||
{_k, text} ->
|
||||
text
|
||||
end)
|
||||
|> Enum.join()
|
||||
end)
|
||||
end
|
||||
end
|
|
@ -9,42 +9,32 @@ defmodule PhilomenaWeb.TextileRenderer do
|
|||
# Kill bogus compile time dependency on ImageView
|
||||
@image_view Module.concat(["PhilomenaWeb.ImageView"])
|
||||
|
||||
def render_one(post, conn) do
|
||||
hd(render_collection([post], conn))
|
||||
end
|
||||
|
||||
def render_collection(posts, conn) do
|
||||
def render(text, conn) do
|
||||
opts = %{image_transform: &Camo.Image.image_url/1}
|
||||
parsed = Enum.map(posts, &Parser.parse(opts, &1.body))
|
||||
parsed = Parser.parse(opts, text)
|
||||
|
||||
images =
|
||||
parsed
|
||||
|> Enum.flat_map(fn tree ->
|
||||
tree
|
||||
|> Enum.flat_map(fn
|
||||
{:text, text} ->
|
||||
[text]
|
||||
|> Enum.flat_map(fn
|
||||
{:text, text} ->
|
||||
[text]
|
||||
|
||||
_ ->
|
||||
[]
|
||||
end)
|
||||
_ ->
|
||||
[]
|
||||
end)
|
||||
|> find_images
|
||||
|
||||
parsed
|
||||
|> Enum.map(fn tree ->
|
||||
tree
|
||||
|> Enum.map(fn
|
||||
{:text, text} ->
|
||||
text
|
||||
|> replacement_entities()
|
||||
|> replacement_images(conn, images)
|
||||
|> Enum.map(fn
|
||||
{:text, text} ->
|
||||
text
|
||||
|> replacement_entities()
|
||||
|> replacement_images(conn, images)
|
||||
|
||||
{_k, markup} ->
|
||||
markup
|
||||
end)
|
||||
|> Enum.join()
|
||||
{_k, markup} ->
|
||||
markup
|
||||
end)
|
||||
|> Enum.join()
|
||||
end
|
||||
|
||||
defp replacement_entities(t) do
|
||||
|
@ -99,11 +89,11 @@ defmodule PhilomenaWeb.TextileRenderer do
|
|||
|> safe_to_string()
|
||||
|
||||
[image, suffix] when suffix in ["p", "t", "s"] ->
|
||||
link(">>#{image.id}#{suffix}#{link_postfix(image)}", to: "/#{image.id}")
|
||||
link(">>#{image.id}#{suffix}#{link_postfix(image)}", to: "/images/#{image.id}")
|
||||
|> safe_to_string()
|
||||
|
||||
[image] ->
|
||||
link(">>#{image.id}#{link_postfix(image)}", to: "/#{image.id}")
|
||||
link(">>#{image.id}#{link_postfix(image)}", to: "/images/#{image.id}")
|
||||
|> safe_to_string()
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
defmodule PhilomenaWeb.ErrorView do
|
||||
use PhilomenaWeb, :view
|
||||
|
||||
import PhilomenaWeb.LayoutView, only: [
|
||||
stylesheet_path: 2,
|
||||
dark_stylesheet_path: 1,
|
||||
viewport_meta_tag: 1
|
||||
]
|
||||
import PhilomenaWeb.LayoutView,
|
||||
only: [
|
||||
stylesheet_path: 2,
|
||||
dark_stylesheet_path: 1,
|
||||
viewport_meta_tag: 1
|
||||
]
|
||||
|
||||
@codes %{
|
||||
400 => {"Bad Request", "Couldn't process your request!"},
|
||||
403 => {"Forbidden", "Not allowed to access this page (are your cookies enabled?)"},
|
||||
404 => {"Not Found", "Couldn't find what you were looking for!"},
|
||||
500 => {"Internal Error", "Couldn't process your request!"},
|
||||
500 => {"Internal Error", "Couldn't process your request!"}
|
||||
}
|
||||
|
||||
# By default, Phoenix returns the status message from
|
||||
|
|
6
mix.exs
6
mix.exs
|
@ -11,7 +11,8 @@ defmodule Philomena.MixProject do
|
|||
start_permanent: Mix.env() == :prod,
|
||||
aliases: aliases(),
|
||||
deps: deps(),
|
||||
dialyzer: [plt_add_apps: [:mix]]
|
||||
dialyzer: [plt_add_apps: [:mix]],
|
||||
rustler_crates: [philomena_markdown: []]
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -69,6 +70,9 @@ defmodule Philomena.MixProject do
|
|||
{:mint, "~> 1.2"},
|
||||
{:exq, "~> 0.14"},
|
||||
|
||||
# Markdown
|
||||
{:rustler, "~> 0.22"},
|
||||
|
||||
# Linting
|
||||
{:credo, "~> 1.5", only: [:dev, :test], override: true},
|
||||
{:credo_envvar, "~> 0.1", only: [:dev, :test], runtime: false},
|
||||
|
|
21
mix.lock
21
mix.lock
|
@ -12,6 +12,7 @@
|
|||
"comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"},
|
||||
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
|
||||
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
|
||||
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"},
|
||||
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
|
||||
"credo": {:hex, :credo, "1.5.6", "e04cc0fdc236fefbb578e0c04bd01a471081616e741d386909e527ac146016c6", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "4b52a3e558bd64e30de62a648518a5ea2b6e3e5d2b164ef5296244753fc7eb17"},
|
||||
"credo_envvar": {:hex, :credo_envvar, "0.1.4", "40817c10334e400f031012c0510bfa0d8725c19d867e4ae39cf14f2cbebc3b20", [:mix], [{:credo, "~> 1.0", [hex: :credo, repo: "hexpm", optional: false]}], "hexpm", "5055cdb4bcbaf7d423bc2bb3ac62b4e2d825e2b1e816884c468dee59d0363009"},
|
||||
|
@ -19,9 +20,9 @@
|
|||
"db_connection": {:hex, :db_connection, "2.4.0", "d04b1b73795dae60cead94189f1b8a51cc9e1f911c234cc23074017c43c031e5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad416c21ad9f61b3103d254a71b63696ecadb6a917b36f563921e0de00d7d7c8"},
|
||||
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
|
||||
"dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"},
|
||||
"ecto": {:hex, :ecto, "3.7.1", "a20598862351b29f80f285b21ec5297da1181c0442687f9b8329f0445d228892", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d36e5b39fc479e654cffd4dbe1865d9716e4a9b6311faff799b6f90ab81b8638"},
|
||||
"ecto": {:hex, :ecto, "3.5.8", "8ebf12be6016cb99313348ba7bb4612f4114b9a506d6da79a2adc7ef449340bc", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ea0be182ea8922eb7742e3ae8e71b67ee00ae177de1bf76210299a5f16ba4c77"},
|
||||
"ecto_network": {:hex, :ecto_network, "1.3.0", "1e77fa37c20e0f6a426d3862732f3317b0fa4c18f123d325f81752a491d7304e", [:mix], [{:ecto_sql, ">= 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:phoenix_html, ">= 0.0.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.14.0", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm", "053a5e46ef2837e8ea5ea97c82fa0f5494699209eddd764e663c85f11b2865bd"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.7.0", "2fcaad4ab0c8d76a5afbef078162806adbe709c04160aca58400d5cbbe8eeac6", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a26135dfa1d99bf87a928c464cfa25bba6535a4fe761eefa56077a4febc60f70"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.5.0", "760aa2935cc80b72da83fbd8cc97923623a2401915c308afea2cf2b0aabf4b2e", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.5.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0 or ~> 0.4.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.0", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3bab456e3ebb5680b327313f57ebb5356882a59fe04964a03232a83dc4c44aa2"},
|
||||
"elastix": {:hex, :elastix, "0.10.0", "7567da885677ba9deffc20063db5f3ca8cd10f23cff1ab3ed9c52b7063b7e340", [:mix], [{:httpoison, "~> 1.4", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0", [hex: :poison, repo: "hexpm", optional: true]}, {:retry, "~> 0.8", [hex: :retry, repo: "hexpm", optional: false]}], "hexpm", "5fb342ce068b20f7845f5dd198c2dc80d967deafaa940a6e51b846db82696d1d"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"},
|
||||
"elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"},
|
||||
|
@ -39,13 +40,13 @@
|
|||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
|
||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
|
||||
"mint": {:hex, :mint, "1.3.0", "396b3301102f7b775e103da5a20494b25753aed818d6d6f0ad222a3a018c3600", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "a9aac960562e43ca69a77e5176576abfa78b8398cec5543dd4fb4ab0131d5c1e"},
|
||||
"mint": {:hex, :mint, "1.4.0", "cd7d2451b201fc8e4a8fd86257fb3878d9e3752899eb67b0c5b25b180bde1212", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "10a99e144b815cbf8522dccbc8199d15802440fc7a64d67b6853adb6fa170217"},
|
||||
"mix_audit": {:hex, :mix_audit, "0.1.4", "35c424173a574436a80ad7f63cf014a7d9ce727de8cd4e7b4138d90b11aec043", [:make, :mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.4.0", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "7a43fee661bcadbad31aa04a86d33a890421c174723814b8a3a7f0e7076936a1"},
|
||||
"neotoma": {:hex, :neotoma, "1.7.3", "d8bd5404b73273989946e4f4f6d529e5c2088f5fa1ca790b4dbe81f4be408e61", [:rebar], [], "hexpm", "2da322b9b1567ffa0706a7f30f6bbbde70835ae44a1050615f4b4a3d436e0f28"},
|
||||
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
|
||||
"pbkdf2": {:git, "https://github.com/code-time/erlang-pbkdf2.git", "f8f0012a97f58ade9c70ac93260e4259e4ca4b8d", [ref: "f8f0012a97f58ade9c70ac93260e4259e4ca4b8d"]},
|
||||
"phoenix": {:hex, :phoenix, "1.5.12", "75fddb14c720388eea93d33886166a690416a7ff8633fbd93f364355b6fe1166", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8f0ae6734fcc18bbaa646c161e2febc46fb899eae43f82679b92530983324113"},
|
||||
"phoenix": {:hex, :phoenix, "1.5.0", "59cf8c734a0e305736654961691aeaa11d80b96a0cc4aeb68d8610af42af1aef", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c695e372ea39914bb97d62ef632550bc3bb38a4bb78fa520f5d5d4be3630399e"},
|
||||
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"},
|
||||
"phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
|
||||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"},
|
||||
|
@ -53,25 +54,27 @@
|
|||
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
|
||||
"phoenix_pubsub_redis": {:hex, :phoenix_pubsub_redis, "3.0.1", "d4d856b1e57a21358e448543e1d091e07e83403dde4383b8be04ed9d2c201cbc", [:mix], [{:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5.1 or ~> 1.6", [hex: :poolboy, repo: "hexpm", optional: false]}, {:redix, "~> 0.10.0 or ~> 1.0", [hex: :redix, repo: "hexpm", optional: false]}], "hexpm", "0b36a17ff6e9a56159f8df8933d62b5c1f0695eae995a02e0c86c035ace6a309"},
|
||||
"phoenix_slime": {:hex, :phoenix_slime, "0.13.1", "a5d4d8febb87a618b02d690519f7106832c8bd0b4d1937fbba73d6e8666f2891", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:slime, "~> 1.0", [hex: :slime, repo: "hexpm", optional: false]}], "hexpm", "ff818744be2c903fb0174ba22b230c1c335238578fccf274b1d95d08f4844377"},
|
||||
"plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"},
|
||||
"plug_cowboy": {:hex, :plug_cowboy, "2.3.0", "149a50e05cb73c12aad6506a371cd75750c0b19a32f81866e1a323dda9e0e99d", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bc595a1870cef13f9c1e03df56d96804db7f702175e4ccacdb8fc75c02a7b97e"},
|
||||
"plug": {:hex, :plug, "1.10.0", "6508295cbeb4c654860845fb95260737e4a8838d34d115ad76cd487584e2fc4d", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "422a9727e667be1bf5ab1de03be6fa0ad67b775b2d84ed908f3264415ef29d4a"},
|
||||
"plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
|
||||
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
|
||||
"postgrex": {:hex, :postgrex, "0.15.10", "2809dee1b1d76f7cbabe570b2a9285c2e7b41be60cf792f5f2804a54b838a067", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "1560ca427542f6b213f8e281633ae1a3b31cdbcd84ebd7f50628765b8f6132be"},
|
||||
"pot": {:hex, :pot, "1.0.2", "13abb849139fdc04ab8154986abbcb63bdee5de6ed2ba7e1713527e33df923dd", [:rebar3], [], "hexpm", "78fe127f5a4f5f919d6ea5a2a671827bd53eb9d37e5b4128c0ad3df99856c2e0"},
|
||||
"qrcode": {:hex, :qrcode, "0.1.5", "551271830515c150f34568345b060c625deb0e6691db2a01b0a6de3aafc93886", [:mix], [], "hexpm", "a266b7fb7be0d3b713912055dde3575927eca920e5d604ded45cd534f6b7a447"},
|
||||
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
|
||||
"redix": {:hex, :redix, "0.10.7", "758916c71fc09e223e18d6715344581d7768c430983dabf77e792ba2087729e6", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "73fdf73c0472278dc040dcd1a5da91d4febe218201ae8ac0454b37e136886c34"},
|
||||
"redix": {:hex, :redix, "0.10.0", "886cfbb14f9b78b82f38963695be2c6ed54b4f5cf911acbf70278ba09144f55d", [:mix], [{:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d8266f5a13291f1d8d7003ad48820e80d34c48348dd762e6564a806cb4b5bc0f"},
|
||||
"remote_ip": {:hex, :remote_ip, "0.2.1", "cd27cd8ea54ecaaf3532776ff4c5e353b3804e710302e88c01eadeaaf42e7e24", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:inet_cidr, "~> 1.0", [hex: :inet_cidr, repo: "hexpm", optional: false]}, {:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2e7ab1a461cc3cd5719f37e116a08f45c8b8493923063631b164315d6b7ee8e0"},
|
||||
"retry": {:hex, :retry, "0.14.1", "722d1b0cf87096b71213f5801d99fface7ca76adc83fc9dbf3e1daee952aef10", [:mix], [], "hexpm", "b3a609f286f6fe4f6b2c15f32cd4a8a60427d78d05d7b68c2dd9110981111ae0"},
|
||||
"rustler": {:hex, :rustler, "0.22.0", "e2930f9d6933e910f87526bb0a7f904e32b62a7e838a3ca4a884ee7fdfb957ed", [:mix], [{:toml, "~> 0.5.2", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "01f5989dd511ebec09be481e07d3c59773d5373c5061e09d3ebc3ef61811b49d"},
|
||||
"scrivener": {:hex, :scrivener, "2.7.2", "1d913c965ec352650a7f864ad7fd8d80462f76a32f33d57d1e48bc5e9d40aba2", [:mix], [], "hexpm", "7866a0ec4d40274efbee1db8bead13a995ea4926ecd8203345af8f90d2b620d9"},
|
||||
"scrivener_ecto": {:hex, :scrivener_ecto, "2.7.0", "cf64b8cb8a96cd131cdbcecf64e7fd395e21aaa1cb0236c42a7c2e34b0dca580", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:scrivener, "~> 2.4", [hex: :scrivener, repo: "hexpm", optional: false]}], "hexpm", "e809f171687806b0031129034352f5ae44849720c48dd839200adeaf0ac3e260"},
|
||||
"secure_compare": {:hex, :secure_compare, "0.1.0", "01b3c93c8edb696e8a5b38397ed48e10958c8a5ec740606656445bcbec0aadb8", [:mix], [], "hexpm", "6391a49eb4a6182f0d7425842fc774bbed715e78b2bfb0c83b99c94e02c78b5c"},
|
||||
"slime": {:hex, :slime, "1.2.1", "71e036056051f0a6fae136af34eaa1322e8e11cdd2da3a56196fd31bca34dd49", [:mix], [{:neotoma, "~> 1.7", [hex: :neotoma, repo: "hexpm", optional: false]}], "hexpm", "298568e64291fed4eb690be094f6c46400daa03b594bab34fcaa0167e139c263"},
|
||||
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
||||
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
|
||||
"tesla": {:hex, :tesla, "1.4.3", "f5a494e08fb1abe4fd9c28abb17f3d9b62b8f6fc492860baa91efb1aab61c8a0", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "e0755bb664bf4d664af72931f320c97adbf89da4586670f4864bf259b5750386"},
|
||||
"telemetry": {:hex, :telemetry, "0.4.0", "8339bee3fa8b91cb84d14c2935f8ecf399ccd87301ad6da6b71c09553834b2ab", [:rebar3], [], "hexpm", "e9e3cacfd37c1531c0ca70ca7c0c30ce2dbb02998a4f7719de180fe63f8d41e4"},
|
||||
"tesla": {:hex, :tesla, "1.4.0", "1081bef0124b8bdec1c3d330bbe91956648fb008cf0d3950a369cda466a31a87", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "bf1374a5569f5fca8e641363b63f7347d680d91388880979a33bc12a6eb3e0aa"},
|
||||
"toml": {:hex, :toml, "0.5.2", "e471388a8726d1ce51a6b32f864b8228a1eb8edc907a0edf2bb50eab9321b526", [:mix], [], "hexpm", "f1e3dabef71fb510d015fad18c0e05e7c57281001141504c6b69d94e99750a07"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
"yamerl": {:hex, :yamerl, "0.8.1", "07da13ffa1d8e13948943789665c62ccd679dfa7b324a4a2ed3149df17f453a4", [:rebar3], [], "hexpm", "96cb30f9d64344fed0ef8a92e9f16f207de6c04dfff4f366752ca79f5bceb23f"},
|
||||
"yaml_elixir": {:hex, :yaml_elixir, "2.4.0", "2f444abc3c994c902851fde56b6a9cb82895c291c05a0490a289035c2e62ae71", [:mix], [{:yamerl, "~> 0.7", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "4e25a6d5c873e393689c6f1062c5ec90f6cd1be2527b073178ae37eae4c78bee"},
|
||||
|
|
959
native/philomena/Cargo.lock
generated
Normal file
959
native/philomena/Cargo.lock
generated
Normal file
|
@ -0,0 +1,959 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "comrak"
|
||||
version = "0.12.1"
|
||||
source = "git+https://github.com/philomena-dev/comrak?branch=main#3e2120b6b5d5d995b787dad27699f5bda4bc6112"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"entities",
|
||||
"lazy_static",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"regex",
|
||||
"shell-words",
|
||||
"syntect",
|
||||
"twoway",
|
||||
"typed-arena",
|
||||
"unicode_categories",
|
||||
"xdg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "entities"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca"
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "jemalloc-sys"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"fs_extra",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jemallocator"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43ae63fcfc45e99ab3d1b29a46782ad679e98436c3169d15a167a1108a724b69"
|
||||
dependencies = [
|
||||
"jemalloc-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103"
|
||||
|
||||
[[package]]
|
||||
name = "line-wrap"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9"
|
||||
dependencies = [
|
||||
"safemem",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||
|
||||
[[package]]
|
||||
name = "onig"
|
||||
version = "6.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16fd3c0e73b516af509c13c4ba76ec0c987ce20d78b38cff356b8d01fc6a6c0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"onig_sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "onig_sys"
|
||||
version = "69.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fd9442a09e4fbd08d196ddf419b2c79a43c3a46c800320cc841d45c2449a240"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
|
||||
dependencies = [
|
||||
"maplit",
|
||||
"pest",
|
||||
"sha-1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "philomena"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"comrak",
|
||||
"jemallocator",
|
||||
"ring",
|
||||
"rustler",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
|
||||
|
||||
[[package]]
|
||||
name = "plist"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a38d026d73eeaf2ade76309d0c65db5a35ecf649e3cec428db316243ea9d6711"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"chrono",
|
||||
"indexmap",
|
||||
"line-wrap",
|
||||
"serde",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustler"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b787d3b2a80007f41cd4c0c310cdeb3936192768159585f65ecc7e96faf97fc3"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"rustler_codegen",
|
||||
"rustler_sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustler_codegen"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a1f867002b6f0130f47abf215cac4405646db6f5d7b009b21c890980490aa4"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustler_sys"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cb382fde4f421c51555919e9920b058c0286f6bf59e53d02eb4d281eae6758b"
|
||||
dependencies = [
|
||||
"unreachable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.130"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.130"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shell-words"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6fa3938c99da4914afedd13bf3d79bcb6c277d1b2c398d23257a304d9e1b074"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syntect"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b20815bbe80ee0be06e6957450a841185fcf690fe0178f14d77a05ce2caa031"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitflags",
|
||||
"flate2",
|
||||
"fnv",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"onig",
|
||||
"plist",
|
||||
"regex-syntax",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5241dd6f21443a3606b432718b166d3cedc962fd4b8bea54a8bc7f514ebda986"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "twoway"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"unchecked-index",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "unchecked-index"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_categories"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||
|
||||
[[package]]
|
||||
name = "unreachable"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
dependencies = [
|
||||
"void",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "xdg"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
22
native/philomena/Cargo.toml
Normal file
22
native/philomena/Cargo.toml
Normal file
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
name = "philomena"
|
||||
version = "0.3.0"
|
||||
authors = ["Xe <https://github.com/Xe>", "Luna <https://github.com/Meow>", "Liam White <https://github.com/liamwhite>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "philomena"
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
comrak = { git = "https://github.com/philomena-dev/comrak", branch = "main" }
|
||||
rustler = "0.22"
|
||||
jemallocator = "0.3.2"
|
||||
ring = "0.16"
|
||||
base64 = "0.13"
|
||||
url = "2.2"
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
lto = true
|
22
native/philomena/README.md
Normal file
22
native/philomena/README.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# NIF for Elixir.Philomena.Markdown
|
||||
|
||||
## To build the NIF module:
|
||||
|
||||
- Make sure your projects `mix.exs` has the `:rustler` compiler listed in the `project` function: `compilers: [:rustler] ++ Mix.compilers()` If there already is a `:compilers` list, you should append `:rustler` to it.
|
||||
- Add your crate to the `rustler_crates` attribute in the `project function. [See here](https://hexdocs.pm/rustler/basics.html#crate-configuration).
|
||||
- Your NIF will now build along with your project.
|
||||
|
||||
## To load the NIF:
|
||||
|
||||
```elixir
|
||||
defmodule Philomena.Markdown do
|
||||
use Rustler, otp_app: <otp-app>, crate: "philomena_markdown"
|
||||
|
||||
# When your NIF is loaded, it will override this function.
|
||||
def add(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
|
||||
end
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
[This](https://github.com/hansihe/NifIo) is a complete example of a NIF written in Rust.
|
44
native/philomena/src/camo.rs
Normal file
44
native/philomena/src/camo.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
use ring::hmac;
|
||||
use std::env;
|
||||
use url::Url;
|
||||
|
||||
fn trusted_host(mut url: Url) -> Option<String> {
|
||||
url.set_port(Some(443)).ok()?;
|
||||
url.set_scheme("https").ok()?;
|
||||
|
||||
Some(url.to_string())
|
||||
}
|
||||
|
||||
fn untrusted_host(url: Url, camo_host: String, camo_key: String) -> Option<String> {
|
||||
let camo_url = format!("https://{}", camo_host);
|
||||
let key = hmac::Key::new(hmac::HMAC_SHA1_FOR_LEGACY_USE_ONLY, camo_key.as_ref());
|
||||
let tag = hmac::sign(&key, url.to_string().as_bytes());
|
||||
let encoded = base64::encode_config(tag.as_ref(), base64::URL_SAFE_NO_PAD);
|
||||
let encoded_url = base64::encode_config(url.as_ref(), base64::URL_SAFE_NO_PAD);
|
||||
let path = format!("{}/{}", encoded, encoded_url);
|
||||
|
||||
let mut camo_uri = Url::parse(&camo_url).ok()?;
|
||||
camo_uri.set_path(&path);
|
||||
camo_uri.set_port(Some(443)).ok()?;
|
||||
camo_uri.set_scheme("https").ok()?;
|
||||
|
||||
Some(camo_uri.to_string())
|
||||
}
|
||||
|
||||
pub fn image_url(uri: String) -> Option<String> {
|
||||
let cdn_host = env::var("CDN_HOST").ok()?;
|
||||
let camo_host = env::var("CAMO_HOST").ok()?;
|
||||
let camo_key = env::var("CAMO_KEY").ok()?;
|
||||
|
||||
if camo_key.is_empty() {
|
||||
return Some(uri);
|
||||
}
|
||||
|
||||
let url = Url::parse(&uri).ok()?;
|
||||
|
||||
match url.host_str() {
|
||||
Some(hostname) if hostname == cdn_host || hostname == camo_host => trusted_host(url),
|
||||
Some(_) => untrusted_host(url, camo_host, camo_key),
|
||||
None => Some(String::from("")),
|
||||
}
|
||||
}
|
32
native/philomena/src/lib.rs
Normal file
32
native/philomena/src/lib.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
use jemallocator::Jemalloc;
|
||||
use rustler::Term;
|
||||
|
||||
mod camo;
|
||||
mod markdown;
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL: Jemalloc = Jemalloc;
|
||||
|
||||
rustler::init! {
|
||||
"Elixir.Philomena.Native",
|
||||
[markdown_to_html, markdown_to_html_unsafe, camo_image_url]
|
||||
}
|
||||
|
||||
// Markdown NIF wrappers.
|
||||
|
||||
#[rustler::nif(schedule = "DirtyCpu")]
|
||||
fn markdown_to_html<'a>(input: String, reps: Term<'a>) -> String {
|
||||
markdown::to_html(input, reps)
|
||||
}
|
||||
|
||||
#[rustler::nif(schedule = "DirtyCpu")]
|
||||
fn markdown_to_html_unsafe<'a>(input: String, reps: Term<'a>) -> String {
|
||||
markdown::to_html_unsafe(input, reps)
|
||||
}
|
||||
|
||||
// Camo NIF wrappers.
|
||||
|
||||
#[rustler::nif]
|
||||
fn camo_image_url(input: String) -> String {
|
||||
camo::image_url(input).unwrap_or_else(|| String::from(""))
|
||||
}
|
48
native/philomena/src/markdown.rs
Normal file
48
native/philomena/src/markdown.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use comrak::ComrakOptions;
|
||||
use crate::camo;
|
||||
use rustler::{MapIterator, Term};
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn common_options() -> ComrakOptions {
|
||||
let mut options = ComrakOptions::default();
|
||||
options.extension.autolink = true;
|
||||
options.extension.table = true;
|
||||
options.extension.description_lists = true;
|
||||
options.extension.superscript = true;
|
||||
options.extension.strikethrough = true;
|
||||
options.extension.philomena = true;
|
||||
options.parse.smart = true;
|
||||
options.render.hardbreaks = true;
|
||||
options.render.github_pre_lang = true;
|
||||
|
||||
options.extension.camoifier = Some(|s| camo::image_url(s).unwrap_or_else(|| String::from("")));
|
||||
|
||||
options
|
||||
}
|
||||
|
||||
fn map_to_hashmap<'a>(map: Term<'a>) -> Option<HashMap<String, String>> {
|
||||
Some(MapIterator::new(map)?.map(|(key, value)| {
|
||||
let key: String = key.decode().unwrap_or_else(|_| String::from(""));
|
||||
let value: String = value.decode().unwrap_or_else(|_| String::from(""));
|
||||
|
||||
(key, value)
|
||||
}).collect())
|
||||
}
|
||||
|
||||
pub fn to_html<'a>(input: String, reps: Term<'a>) -> String {
|
||||
let mut options = common_options();
|
||||
options.render.escape = true;
|
||||
|
||||
options.extension.philomena_replacements = map_to_hashmap(reps);
|
||||
|
||||
comrak::markdown_to_html(&input, &options)
|
||||
}
|
||||
|
||||
pub fn to_html_unsafe<'a>(input: String, reps: Term<'a>) -> String {
|
||||
let mut options = common_options();
|
||||
options.render.unsafe_ = true;
|
||||
|
||||
options.extension.philomena_replacements = map_to_hashmap(reps);
|
||||
|
||||
comrak::markdown_to_html(&input, &options)
|
||||
}
|
145
priv/repo/migrations/20210912171343_add_markdown_columns.exs
Normal file
145
priv/repo/migrations/20210912171343_add_markdown_columns.exs
Normal file
|
@ -0,0 +1,145 @@
|
|||
defmodule Philomena.Repo.Migrations.AddMarkdownColumns do
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
alter table("comments") do
|
||||
add :body_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("messages") do
|
||||
add :body_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("mod_notes") do
|
||||
add :body_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("posts") do
|
||||
add :body_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("badges") do
|
||||
add :description_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("channels") do
|
||||
add :description_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("commission_items") do
|
||||
add :description_md, :varchar, default: nil
|
||||
add :add_ons_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("filters") do
|
||||
add :description_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("galleries") do
|
||||
add :description_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("images") do
|
||||
add :description_md, :varchar, default: nil
|
||||
add :scratchpad_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("tags") do
|
||||
add :description_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("users") do
|
||||
add :description_md, :varchar, default: nil
|
||||
add :scratchpad_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("dnp_entries") do
|
||||
add :conditions_md, :varchar, default: nil
|
||||
add :reason_md, :varchar, default: nil
|
||||
add :instructions_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("commissions") do
|
||||
add :information_md, :varchar, default: nil
|
||||
add :contact_md, :varchar, default: nil
|
||||
add :will_create_md, :varchar, default: nil
|
||||
add :will_not_create_md, :varchar, default: nil
|
||||
end
|
||||
|
||||
alter table("reports") do
|
||||
add :reason_md, :varchar, default: nil
|
||||
end
|
||||
end
|
||||
|
||||
def down do
|
||||
alter table("comments") do
|
||||
remove :body_md
|
||||
end
|
||||
|
||||
alter table("messages") do
|
||||
remove :body_md
|
||||
end
|
||||
|
||||
alter table("mod_notes") do
|
||||
remove :body_md
|
||||
end
|
||||
|
||||
alter table("posts") do
|
||||
remove :body_md
|
||||
end
|
||||
|
||||
alter table("badges") do
|
||||
remove :description_md
|
||||
end
|
||||
|
||||
alter table("channels") do
|
||||
remove :description_md
|
||||
end
|
||||
|
||||
alter table("commission_items") do
|
||||
remove :description_md
|
||||
remove :add_ons_md
|
||||
end
|
||||
|
||||
alter table("filters") do
|
||||
remove :description_md
|
||||
end
|
||||
|
||||
alter table("galleries") do
|
||||
remove :description_md
|
||||
end
|
||||
|
||||
alter table("images") do
|
||||
remove :description_md
|
||||
remove :scratchpad_md
|
||||
end
|
||||
|
||||
alter table("tags") do
|
||||
remove :description_md
|
||||
remove :short_description_md
|
||||
remove :mod_notes_md
|
||||
end
|
||||
|
||||
alter table("users") do
|
||||
remove :description_md
|
||||
remove :scratchpad_md
|
||||
end
|
||||
|
||||
alter table("dnp_entries") do
|
||||
remove :conditions_md
|
||||
remove :reason_md
|
||||
remove :instructions_md
|
||||
end
|
||||
|
||||
alter table("commissions") do
|
||||
remove :information_md
|
||||
remove :contact_md
|
||||
remove :will_create_md
|
||||
remove :will_not_create_md
|
||||
end
|
||||
|
||||
alter table("reports") do
|
||||
remove :reason_md
|
||||
end
|
||||
end
|
||||
end
|
|
@ -165,7 +165,8 @@ CREATE TABLE public.badges (
|
|||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
disable_award boolean DEFAULT false NOT NULL,
|
||||
priority boolean DEFAULT false
|
||||
priority boolean DEFAULT false,
|
||||
description_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -227,7 +228,8 @@ CREATE TABLE public.channels (
|
|||
total_viewer_minutes integer DEFAULT 0 NOT NULL,
|
||||
banner_image character varying,
|
||||
remote_stream_id integer,
|
||||
thumbnail_url character varying DEFAULT ''::character varying
|
||||
thumbnail_url character varying DEFAULT ''::character varying,
|
||||
description_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -272,7 +274,8 @@ CREATE TABLE public.comments (
|
|||
edited_at timestamp without time zone,
|
||||
deletion_reason character varying DEFAULT ''::character varying NOT NULL,
|
||||
destroyed_content boolean DEFAULT false,
|
||||
name_at_post_time character varying
|
||||
name_at_post_time character varying,
|
||||
body_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -308,7 +311,9 @@ CREATE TABLE public.commission_items (
|
|||
add_ons character varying,
|
||||
example_image_id integer,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
description_md character varying,
|
||||
add_ons_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -347,7 +352,11 @@ CREATE TABLE public.commissions (
|
|||
will_not_create character varying,
|
||||
commission_items_count integer DEFAULT 0 NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
information_md character varying,
|
||||
contact_md character varying,
|
||||
will_create_md character varying,
|
||||
will_not_create_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -426,7 +435,10 @@ CREATE TABLE public.dnp_entries (
|
|||
instructions character varying NOT NULL,
|
||||
feedback character varying NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
conditions_md character varying,
|
||||
reason_md character varying,
|
||||
instructions_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -539,7 +551,8 @@ CREATE TABLE public.filters (
|
|||
user_count integer DEFAULT 0 NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
user_id integer
|
||||
user_id integer,
|
||||
description_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -666,7 +679,8 @@ CREATE TABLE public.galleries (
|
|||
watcher_ids integer[] DEFAULT '{}'::integer[] NOT NULL,
|
||||
watcher_count integer DEFAULT 0 NOT NULL,
|
||||
image_count integer DEFAULT 0 NOT NULL,
|
||||
order_position_asc boolean DEFAULT false NOT NULL
|
||||
order_position_asc boolean DEFAULT false NOT NULL,
|
||||
description_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -950,7 +964,9 @@ CREATE TABLE public.images (
|
|||
hidden_image_key character varying,
|
||||
scratchpad character varying,
|
||||
hides_count integer DEFAULT 0 NOT NULL,
|
||||
image_duration double precision
|
||||
image_duration double precision,
|
||||
description_md character varying,
|
||||
scratchpad_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -983,7 +999,8 @@ CREATE TABLE public.messages (
|
|||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
from_id integer NOT NULL,
|
||||
conversation_id integer NOT NULL
|
||||
conversation_id integer NOT NULL,
|
||||
body_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -1018,7 +1035,8 @@ CREATE TABLE public.mod_notes (
|
|||
body text NOT NULL,
|
||||
deleted boolean DEFAULT false NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
body_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -1201,7 +1219,8 @@ CREATE TABLE public.posts (
|
|||
edited_at timestamp without time zone,
|
||||
deletion_reason character varying DEFAULT ''::character varying NOT NULL,
|
||||
destroyed_content boolean DEFAULT false NOT NULL,
|
||||
name_at_post_time character varying
|
||||
name_at_post_time character varying,
|
||||
body_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -1242,7 +1261,8 @@ CREATE TABLE public.reports (
|
|||
user_id integer,
|
||||
admin_id integer,
|
||||
reportable_id integer NOT NULL,
|
||||
reportable_type character varying NOT NULL
|
||||
reportable_type character varying NOT NULL,
|
||||
reason_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -1549,7 +1569,8 @@ CREATE TABLE public.tags (
|
|||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
category character varying,
|
||||
mod_notes character varying
|
||||
mod_notes character varying,
|
||||
description_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -1989,7 +2010,9 @@ CREATE TABLE public.users (
|
|||
forced_filter_id bigint,
|
||||
confirmed_at timestamp(0) without time zone,
|
||||
senior_staff boolean DEFAULT false,
|
||||
bypass_rate_limits boolean DEFAULT false
|
||||
bypass_rate_limits boolean DEFAULT false,
|
||||
description_md character varying,
|
||||
scratchpad_md character varying
|
||||
);
|
||||
|
||||
|
||||
|
@ -4845,4 +4868,5 @@ INSERT INTO public."schema_migrations" (version) VALUES (20201124224116);
|
|||
INSERT INTO public."schema_migrations" (version) VALUES (20210121200815);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20210301012137);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20210427022351);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20210912171343);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20210917190346);
|
||||
|
|
Loading…
Reference in a new issue