Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow all 'couyards' pendants in Djot (passing attributes) #95

Merged
merged 1 commit into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions examples/sile-and-djot.dj
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,17 @@ The `.bigrule` pseudo-class produces a centered horizontal rule, taking 33% of t
{.bigrule}
***

The `.pendant` pseudo-class produces a nice curvy pendant.[^djot-couyards]
The `.pendant` pseudo-class produces a nice curvy pendant, provided the optional *couyards.sile* package module is installed.

{.pendant}
***

Valued attributes `type` (1 to 9, the default being 6), `width` and `height` are passed through to the underlying package, allowing to select another of its pendants, or to tune its size.
Here is type 2.

{.pendant type=2}
***

The `.none` pseudo-class produces nothing...

{.none}
Expand All @@ -327,10 +333,8 @@ solution, allowing you to both specify a divider style _and_ introduce a page br
cleaner, and Djot just shines here! Would you want only a page break, you now know the aim of the `.none`
pseudo-class.

[^djot-couyards]: As before, provided the optional *couyards.sile* package module is installed.
[^djot-hrules]: The order in which they are listed above corresponds to their priority.


#### Smarter typography

On inline content, the `.decimal` pseudo-class attribute instructs the converter to consider numbers
Expand Down Expand Up @@ -432,15 +436,16 @@ Other Djot converters will therefore likely skip the caption.
### Conditionals

While the interpretation of symbols presented above is not a standard, the Djot specification leaves it to the rendering engine.
What we proposed there is thus perfectly acceptable so far.
It is thus perfectly acceptable so far...

Since user-defined symbols and context metadata are now made available.
There's a trickier problem, however, if you want to only use a symbol if it is defined.
If you use a non-existent symbol, say `:non-existent:`, you just get :non-existent: in the output.
We cannot just ignore it, since something might have been expected there, but this is objectively not what you want.

This converter therefore introduces an extension to the Djot attributes syntax, allowing you to conditionally render content based on the existence of a symbol.
The content is always parsed (so it has to remain valid Djot), but is only rendered if the symbol is defined.
The content is always parsed (so it has to remain valid Djot), but is only rendered if the symbol is defined.[^djot-conds]

[^djot-conds]: In this implementation, it only affects the _rendering._ Another consequence is that footnotes (including the pseudo-footnotes used for variable substitution) are parsed, so this feature does _not_ allow to conditionally define symbols.

[This content has the `{?title}` condition, and since the `:title:` symbol is defined (_:title:_), it is rendered.]{?title}
Just below, however, a paragraph is annotated with the `{?non-existent}` condition, so you should not see it.
Expand All @@ -452,7 +457,7 @@ You should NOT see this paragraph in the output.
Now, this paragraph has the `{!non-existent}` condition, and since the `non-existent` symbol is NOT defined, it is rendered.

Conditions work on blocks and inline elements alike.
They only apply to user-defined symbols (defined as pseudo-footnotes) and metadata symbols (set by the calling context).
They only apply to user-defined symbols (defined as pseudo-footnotes) and contextual metadata symbols (set by the calling context).

We can't say if future versions of the Djot specification will make use of `?` and `!` in attributes or bracketed content.
Therefore, we recommend that you call template files containing conditional content with the `.djt` extension, as a way to remember.
Expand Down
27 changes: 22 additions & 5 deletions packages/markdown/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -229,21 +229,32 @@ function package:registerCommands ()

self:registerCommand("markdown:internal:thematicbreak", function (options, _)
if hasClass(options, "asterism") then
SILE.call("center", {}, { "⁂" }) -- Asterism
-- Asterism
SILE.call("center", {}, { "⁂" })
elseif hasClass(options, "dinkus") then
SILE.call("center", {}, { "* * *" }) -- Dinkus (with em-spaces)
-- Dinkus (with em-spaces)
SILE.call("center", {}, { "* * *" })
elseif hasClass(options, "bigrule") then
-- 33% line
SILE.call("center", {}, function ()
SILE.call("raise", { height = "0.5ex" }, function ()
SILE.call("hrule", { width = "33%lw", height = "0.4pt" })
end)
end)
elseif hasClass(options, "fullrule") and self:hasCouyards() then
-- Full line
SILE.call("fullrule", { thickness = "0.4pt" })
elseif hasClass(options, "pendant") and self:hasCouyards() then
-- Pendant, with more options available than in Markdown
local opts = {
type = SU.cast("integer", options.type or 6),
height = options.height,
width = not options.height and (options.width or "default")
}
SILE.call("smallskip")
SILE.call("couyard", { type = 6, width = "default" })
SILE.call("couyard", opts)
elseif not hasClass(options, "none") then
-- 20% line
SILE.call("center", {}, function ()
SILE.call("raise", { height = "0.5ex" }, function ()
SILE.call("hrule", { width = "20%lw", height = "0.4pt" })
Expand All @@ -258,27 +269,33 @@ function package:registerCommands ()

self:registerCommand("markdown:internal:hrule", function (options, _)
if options.separator == "***" then
SILE.call("center", {}, { "⁂" }) -- Asterism
-- Asterism
SILE.call("center", {}, { "⁂" })
elseif options.separator == "* * *" then
SILE.call("center", {}, { "* * *" }) -- Dinkus (with em-spaces)
-- Dinkus (with em-spaces)
SILE.call("center", {}, { "* * *" })
elseif options.separator == "---" then
-- 20% line
SILE.call("center", {}, function ()
SILE.call("raise", { height = "0.5ex" }, function ()
SILE.call("hrule", { width = "20%lw", height = "0.4pt" })
end)
end)
elseif options.separator == "----" then
-- 33% line
SILE.call("center", {}, function ()
SILE.call("raise", { height = "0.5ex" }, function ()
SILE.call("hrule", { width = "33%lw", height = "0.4pt" })
end)
end)
elseif options.separator == "- - - -" and self:hasCouyards() then
-- Pendant (fixed choice = the one I regularly use)
SILE.call("smallskip")
SILE.call("couyard", { type = 6, width = "default" })
elseif options.separator == "--------------" then -- Page break
SILE.call("eject")
else
-- Full line
SILE.call("fullrule", { thickness = "0.4pt" })
end
end, "Horizontal rule in Markdown (internal)")
Expand Down