mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
fix spoilers
This commit is contained in:
parent
235dd81469
commit
708852f3b5
4 changed files with 59 additions and 67 deletions
|
@ -63,13 +63,17 @@ h6 {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
.paragraph {
|
||||||
hyphens: none;
|
hyphens: none;
|
||||||
margin-bottom: 0.75rem;
|
margin-bottom: var(--padding-small);
|
||||||
margin-top: 0.25rem;
|
margin-top: var(--padding-small);
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
@extend .paragraph;
|
||||||
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background-color: $meta_color;
|
background-color: $meta_color;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
|
@ -32,3 +32,7 @@ $block_header_height: 32px;
|
||||||
$block_header_sub_height: 26px;
|
$block_header_sub_height: 26px;
|
||||||
$block_spacing: 6px;
|
$block_spacing: 6px;
|
||||||
$media_box_header_height: 22px;
|
$media_box_header_height: 22px;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--padding-small: 0.5em;
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
parser = Map.put(parser, :state, %{})
|
parser = Map.put(parser, :state, %{})
|
||||||
|
|
||||||
with {:ok, tokens, _1, _2, _3, _4} <- Lexer.lex(String.trim(input || "")),
|
with {:ok, tokens, _1, _2, _3, _4} <- Lexer.lex(String.trim(input || "")),
|
||||||
{:ok, tree, []} <- repeat(&textile/3, parser, tokens, false, 0) do
|
{:ok, tree, [], _level} <- repeat(&textile/3, parser, tokens, 0) do
|
||||||
partial_flatten(tree)
|
partial_flatten(tree)
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
|
@ -63,10 +63,10 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
|
|
||||||
# Helper corresponding to Kleene star (*) operator
|
# Helper corresponding to Kleene star (*) operator
|
||||||
# Match a specificed rule zero or more times
|
# Match a specificed rule zero or more times
|
||||||
defp repeat(rule, parser, tokens, bq, level) when bq == true do
|
defp repeat(rule, parser, tokens, level) do
|
||||||
case rule.(parser, tokens, true, level) do
|
case rule.(parser, tokens, level) do
|
||||||
{:ok, tree, r_tokens} ->
|
{:ok, tree, r_tokens} ->
|
||||||
{:ok, tree2, r2_tokens, level} = repeat(rule, parser, r_tokens, true, level)
|
{:ok, tree2, r2_tokens, level} = repeat(rule, parser, r_tokens, level)
|
||||||
{:ok, [tree, tree2], r2_tokens, level}
|
{:ok, [tree, tree2], r2_tokens, level}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
|
@ -74,17 +74,6 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
end
|
end
|
||||||
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:
|
# Helper to match a simple recursive grammar rule of the following form:
|
||||||
#
|
#
|
||||||
# open_token callback* close_token
|
# open_token callback* close_token
|
||||||
|
@ -101,8 +90,8 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
],
|
],
|
||||||
level
|
level
|
||||||
) do
|
) do
|
||||||
case repeat(callback, parser, r_tokens, false, level) do
|
case repeat(callback, parser, r_tokens, level) do
|
||||||
{:ok, tree, [{^close_token, _} | r2_tokens]} ->
|
{:ok, tree, [{^close_token, _} | r2_tokens], _level} ->
|
||||||
{:ok, [{:markup, open_tag}, tree, {:markup, close_tag}], r2_tokens}
|
{:ok, [{:markup, open_tag}, tree, {:markup, close_tag}], r2_tokens}
|
||||||
|
|
||||||
{:ok, tree, r2_tokens} ->
|
{:ok, tree, r2_tokens} ->
|
||||||
|
@ -149,14 +138,14 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
{:ok, [{:text, open}], r_tokens}
|
{:ok, [{:text, open}], r_tokens}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
case repeat(callback, put_state(parser, state), r_tokens, false, level) do
|
case repeat(callback, put_state(parser, state), r_tokens, level) do
|
||||||
{:ok, tree, [{^close_token, close}, {^lookahead_not, ln} | r2_tokens]} ->
|
{:ok, tree, [{^close_token, close}, {^lookahead_not, ln} | r2_tokens], _level} ->
|
||||||
{:ok, [{:text, open}, tree, {:text, close}], [{lookahead_not, ln} | r2_tokens]}
|
{:ok, [{:text, open}, tree, {:text, close}], [{lookahead_not, ln} | r2_tokens]}
|
||||||
|
|
||||||
{:ok, tree, [{^close_token, _} | r2_tokens]} ->
|
{:ok, tree, [{^close_token, _} | r2_tokens], _level} ->
|
||||||
{:ok, [{:markup, open_tag}, tree, {:markup, close_tag}], r2_tokens}
|
{:ok, [{:markup, open_tag}, tree, {:markup, close_tag}], r2_tokens}
|
||||||
|
|
||||||
{:ok, tree, r2_tokens} ->
|
{:ok, tree, r2_tokens, _level} ->
|
||||||
{:ok, [{:text, open}, tree], r2_tokens}
|
{:ok, [{:text, open}, tree], r2_tokens}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -255,25 +244,25 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp inner_inline_textile_element(parser, [{:link_delim, open} | r_tokens], level) do
|
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
|
case repeat(&block_textile_element/3, parser, r_tokens, level) do
|
||||||
{:ok, tree, [{:unbracketed_link_url, <<"\":", url::binary>>} | r2_tokens]} ->
|
{:ok, tree, [{:unbracketed_link_url, <<"\":", url::binary>>} | r2_tokens], _level} ->
|
||||||
href = url
|
href = url
|
||||||
|
|
||||||
{:ok, [{:markup, "["}, tree, {:markup, "]("}, {:markup, href}, {:markup, ")"}], r2_tokens}
|
{:ok, [{:markup, "["}, tree, {:markup, "]("}, {:markup, href}, {:markup, ")"}], r2_tokens}
|
||||||
|
|
||||||
{:ok, tree, r2_tokens} ->
|
{:ok, tree, r2_tokens, _level} ->
|
||||||
{:ok, [{:text, open}, tree], r2_tokens}
|
{:ok, [{:text, open}, tree], r2_tokens}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp inner_inline_textile_element(parser, [{:bracketed_link_open, open} | r_tokens], level) do
|
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
|
case repeat(&inline_textile_element/3, parser, r_tokens, level) do
|
||||||
{:ok, tree, [{:bracketed_link_url, <<"\":", url::binary>>} | r2_tokens]} ->
|
{:ok, tree, [{:bracketed_link_url, <<"\":", url::binary>>} | r2_tokens], _level} ->
|
||||||
href = url
|
href = url
|
||||||
|
|
||||||
{:ok, [{:markup, "["}, tree, {:markup, "]("}, {:markup, href}, {:markup, ")"}], r2_tokens}
|
{:ok, [{:markup, "["}, tree, {:markup, "]("}, {:markup, href}, {:markup, ")"}], r2_tokens}
|
||||||
|
|
||||||
{:ok, tree, r2_tokens} ->
|
{:ok, tree, r2_tokens, _level} ->
|
||||||
{:ok, [{:text, open}, tree], r2_tokens}
|
{:ok, [{:text, open}, tree], r2_tokens}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -284,7 +273,7 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
{token, img},
|
{token, img},
|
||||||
{:unbracketed_image_url, <<":", url::binary>>} | r_tokens
|
{:unbracketed_image_url, <<":", url::binary>>} | r_tokens
|
||||||
],
|
],
|
||||||
level
|
_level
|
||||||
)
|
)
|
||||||
when token in [:unbracketed_image, :bracketed_image] do
|
when token in [:unbracketed_image, :bracketed_image] do
|
||||||
img = parser.image_transform.(img)
|
img = parser.image_transform.(img)
|
||||||
|
@ -299,7 +288,7 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
], r_tokens}
|
], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp inner_inline_textile_element(parser, [{token, img} | r_tokens], level)
|
defp inner_inline_textile_element(parser, [{token, img} | r_tokens], _level)
|
||||||
when token in [:unbracketed_image, :bracketed_image] do
|
when token in [:unbracketed_image, :bracketed_image] do
|
||||||
img = parser.image_transform.(img)
|
img = parser.image_transform.(img)
|
||||||
|
|
||||||
|
@ -317,17 +306,17 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
{:error, "End of rule"}
|
{:error, "End of rule"}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
case repeat(&inline_textile_element/3, put_state(parser, :code), r_tokens, false, level) do
|
case repeat(&inline_textile_element/3, put_state(parser, :code), r_tokens, level) do
|
||||||
{:ok, tree, [{:code_delim, _} | r2_tokens]} ->
|
{:ok, tree, [{:code_delim, _} | r2_tokens], _level} ->
|
||||||
{:ok, [{:markup, "`"}, tree, {:markup, "`"}], r2_tokens}
|
{:ok, [{:markup, "`"}, tree, {:markup, "`"}], r2_tokens}
|
||||||
|
|
||||||
{:ok, tree, r2_tokens} ->
|
{:ok, tree, r2_tokens, _level} ->
|
||||||
{:ok, [{:text, open}, tree], r2_tokens}
|
{:ok, [{:text, open}, tree], r2_tokens}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp inner_inline_textile_element(parser, tokens, level \\ 0) do
|
defp inner_inline_textile_element(parser, tokens, level) do
|
||||||
inline_textile_element_not_opening_markup(parser, tokens, level)
|
inline_textile_element_not_opening_markup(parser, tokens, level)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -337,23 +326,23 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
|
|
||||||
# Note that text is not escaped here because it will be escaped
|
# Note that text is not escaped here because it will be escaped
|
||||||
# when the tree is flattened
|
# when the tree is flattened
|
||||||
defp bq_cite_text(_parser, [{:bq_cite_open, _open} | _rest], level) do
|
defp bq_cite_text(_parser, [{:bq_cite_open, _open} | _rest], _level) do
|
||||||
{:error, "Expected cite tokens"}
|
{:error, "Expected cite tokens"}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp bq_cite_text(_parser, [{:char, lit} | r_tokens], level) do
|
defp bq_cite_text(_parser, [{:char, lit} | r_tokens], _level) do
|
||||||
{:ok, [{:text, <<lit::utf8>>}], r_tokens}
|
{:ok, [{:text, <<lit::utf8>>}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp bq_cite_text(_parser, [{:quicktxt, lit} | r_tokens], level) do
|
defp bq_cite_text(_parser, [{:quicktxt, lit} | r_tokens], _level) do
|
||||||
{:ok, [{:text, <<lit::utf8>>}], r_tokens}
|
{:ok, [{:text, <<lit::utf8>>}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp bq_cite_text(_parser, [{:space, _} | r_tokens], level) do
|
defp bq_cite_text(_parser, [{:space, _} | r_tokens], _level) do
|
||||||
{:ok, [{:text, " "}], r_tokens}
|
{:ok, [{:text, " "}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp bq_cite_text(_parser, [{_token, t} | r_tokens], level) do
|
defp bq_cite_text(_parser, [{_token, t} | r_tokens], _level) do
|
||||||
{:ok, [{:text, t}], r_tokens}
|
{:ok, [{:text, t}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -369,15 +358,15 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
# opening_block_tag block_textile_element* closing_block_tag;
|
# opening_block_tag block_textile_element* closing_block_tag;
|
||||||
#
|
#
|
||||||
|
|
||||||
defp inline_textile_element_not_opening_markup(_parser, [{:literal, lit} | r_tokens], level) do
|
defp inline_textile_element_not_opening_markup(_parser, [{:literal, lit} | r_tokens], _level) do
|
||||||
{:ok, [{:markup, Markdown.escape_markdown(lit)}], r_tokens}
|
{:ok, [{:markup, Markdown.escape_markdown(lit)}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp inline_textile_element_not_opening_markup(_parser, [{:space, _} | r_tokens], level) do
|
defp inline_textile_element_not_opening_markup(_parser, [{:space, _} | r_tokens], _level) do
|
||||||
{:ok, [{:text, " "}], r_tokens}
|
{:ok, [{:text, " "}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp inline_textile_element_not_opening_markup(_parser, [{:char, lit} | r_tokens], level) do
|
defp inline_textile_element_not_opening_markup(_parser, [{:char, lit} | r_tokens], _level) do
|
||||||
{binary, r2_tokens} = assemble_binary(:char, <<lit::utf8>>, r_tokens)
|
{binary, r2_tokens} = assemble_binary(:char, <<lit::utf8>>, r_tokens)
|
||||||
{:ok, [{:text, binary}], r2_tokens}
|
{:ok, [{:text, binary}], r2_tokens}
|
||||||
end
|
end
|
||||||
|
@ -389,7 +378,7 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
{token, t},
|
{token, t},
|
||||||
{:quicktxt, q2} | r_tokens
|
{:quicktxt, q2} | r_tokens
|
||||||
],
|
],
|
||||||
level
|
_level
|
||||||
)
|
)
|
||||||
when token in [
|
when token in [
|
||||||
:b_delim,
|
:b_delim,
|
||||||
|
@ -404,7 +393,7 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
{:ok, [{:text, <<q1::utf8>>}, {:text, t}, {:text, <<q2::utf8>>}], r_tokens}
|
{:ok, [{:text, <<q1::utf8>>}, {:text, t}, {:text, <<q2::utf8>>}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp inline_textile_element_not_opening_markup(_parser, [{:quicktxt, lit} | r_tokens], level) do
|
defp inline_textile_element_not_opening_markup(_parser, [{:quicktxt, lit} | r_tokens], _level) do
|
||||||
{:ok, [{:text, <<lit::utf8>>}], r_tokens}
|
{:ok, [{:text, <<lit::utf8>>}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -413,12 +402,10 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
[{:bq_cite_start, start} | r_tokens],
|
[{:bq_cite_start, start} | r_tokens],
|
||||||
level
|
level
|
||||||
) do
|
) do
|
||||||
case repeat(&bq_cite_text/3, parser, r_tokens, false, level) do
|
case repeat(&bq_cite_text/3, parser, r_tokens, level) do
|
||||||
{:ok, tree, [{:bq_cite_open, open} | r2_tokens]} ->
|
{:ok, tree, [{:bq_cite_open, open} | r2_tokens], _level} ->
|
||||||
case repeat(&block_textile_element/4, parser, r2_tokens, true, level + 1) do
|
case repeat(&block_textile_element/3, parser, r2_tokens, level + 1) do
|
||||||
{:ok, tree2, [{:bq_close, _} | r3_tokens], level} ->
|
{:ok, tree2, [{:bq_close, _} | r3_tokens], level} ->
|
||||||
cite = flatten(tree)
|
|
||||||
|
|
||||||
{:ok,
|
{:ok,
|
||||||
[
|
[
|
||||||
{:markup, "\n" <> String.duplicate("> ", level)},
|
{:markup, "\n" <> String.duplicate("> ", level)},
|
||||||
|
@ -426,7 +413,7 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
{:markup, "\n" <> String.duplicate("> ", level - 1)}
|
{:markup, "\n" <> String.duplicate("> ", level - 1)}
|
||||||
], r3_tokens}
|
], r3_tokens}
|
||||||
|
|
||||||
{:ok, tree2, r3_tokens, level} ->
|
{:ok, tree2, r3_tokens, _level} ->
|
||||||
{:ok,
|
{:ok,
|
||||||
[
|
[
|
||||||
{:text, start},
|
{:text, start},
|
||||||
|
@ -444,7 +431,7 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
defp inline_textile_element_not_opening_markup(
|
defp inline_textile_element_not_opening_markup(
|
||||||
_parser,
|
_parser,
|
||||||
[{:bq_cite_open, tok} | r_tokens],
|
[{:bq_cite_open, tok} | r_tokens],
|
||||||
level
|
_level
|
||||||
) do
|
) do
|
||||||
{:ok, [{:text, tok}], r_tokens}
|
{:ok, [{:text, tok}], r_tokens}
|
||||||
end
|
end
|
||||||
|
@ -454,7 +441,7 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
[{:bq_open, start} | r_tokens],
|
[{:bq_open, start} | r_tokens],
|
||||||
level
|
level
|
||||||
) do
|
) do
|
||||||
case repeat(&block_textile_element/4, parser, r_tokens, true, level + 1) do
|
case repeat(&block_textile_element/3, parser, r_tokens, level + 1) do
|
||||||
{:ok, tree, [{:bq_close, _} | r2_tokens], level} ->
|
{:ok, tree, [{:bq_close, _} | r2_tokens], level} ->
|
||||||
{:ok,
|
{:ok,
|
||||||
[
|
[
|
||||||
|
@ -463,7 +450,7 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
{:markup, "\n" <> String.duplicate("> ", level - 1)}
|
{:markup, "\n" <> String.duplicate("> ", level - 1)}
|
||||||
], r2_tokens}
|
], r2_tokens}
|
||||||
|
|
||||||
{:ok, tree, r2_tokens, level} ->
|
{:ok, tree, r2_tokens, _level} ->
|
||||||
{:ok,
|
{:ok,
|
||||||
[
|
[
|
||||||
{:text, start},
|
{:text, start},
|
||||||
|
@ -512,26 +499,23 @@ defmodule Philomena.Textile.ParserMarkdown do
|
||||||
# double_newline | newline | inline_textile_element;
|
# double_newline | newline | inline_textile_element;
|
||||||
#
|
#
|
||||||
|
|
||||||
defp block_textile_element(_parser, [{:double_newline, _} | r_tokens], bq, level)
|
defp block_textile_element(_parser, [{:double_newline, _} | r_tokens], level)
|
||||||
when bq == true do
|
when level > 0 do
|
||||||
one = "\n" <> String.duplicate("> ", level)
|
one = "\n" <> String.duplicate("> ", level)
|
||||||
{:ok, [{:markup, String.duplicate(one, 2)}], r_tokens}
|
{:ok, [{:markup, String.duplicate(one, 2)}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp block_textile_element(_parser, [{:newline, _} | r_tokens], bq, level) when bq == true do
|
defp block_textile_element(_parser, [{:newline, _} | r_tokens], level) when level > 0 do
|
||||||
{:ok, [{:markup, "\n" <> String.duplicate("> ", level)}], r_tokens}
|
{:ok, [{:markup, "\n" <> String.duplicate("> ", level)}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp block_textile_element(parser, tokens, _bq, level) do
|
defp block_textile_element(_parser, [{:double_newline, _} | r_tokens], level)
|
||||||
inline_textile_element(parser, tokens, level)
|
when level == 0 do
|
||||||
|
{:ok, [{:markup, "\n\\\n"}], r_tokens}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp block_textile_element(_parser, [{:double_newline, _} | r_tokens], _level) do
|
defp block_textile_element(_parser, [{:newline, _} | r_tokens], level) when level == 0 do
|
||||||
{:ok, [{:markup, "\n\n"}], r_tokens}
|
{:ok, [{:markup, "\\\n"}], r_tokens}
|
||||||
end
|
|
||||||
|
|
||||||
defp block_textile_element(_parser, [{:newline, _} | r_tokens], _level) do
|
|
||||||
{:ok, [{:markup, "\n"}], r_tokens}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp block_textile_element(parser, tokens, level) do
|
defp block_textile_element(parser, tokens, level) do
|
||||||
|
|
2
native/philomena/Cargo.lock
generated
2
native/philomena/Cargo.lock
generated
|
@ -143,7 +143,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "comrak"
|
name = "comrak"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
source = "git+https://github.com/philomena-dev/comrak?branch=main#3e2120b6b5d5d995b787dad27699f5bda4bc6112"
|
source = "git+https://github.com/philomena-dev/comrak?branch=main#b9bd7fb744d5cade8355280f4b3b3a8303410595"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"entities",
|
"entities",
|
||||||
|
|
Loading…
Reference in a new issue