Skip to content

Commit

Permalink
callouts -> admonitions
Browse files Browse the repository at this point in the history
  • Loading branch information
nessan committed Aug 25, 2024
1 parent ac4d2f0 commit 6241c83
Show file tree
Hide file tree
Showing 70 changed files with 267 additions and 341 deletions.
7 changes: 7 additions & 0 deletions docs/_extensions/nessan/admonitions/_extension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
title: admonitions
author: nessan
version: 1.0.0
quarto-required: ">=1.5.0"
contributes:
filters:
- admonitions.lua
89 changes: 89 additions & 0 deletions docs/_extensions/nessan/admonitions/admonitions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
--[[
Quarto extension to process AsciiDoc style 'admonitions'
See: https://docs.asciidoctor.org/asciidoc/latest/blocks/admonitions/
For now we only support paragraph syntax for admonitions and only have HTML output.
SPDX-FileCopyrightText: 2024 Nessan Fitzmaurice <[email protected]>
SPDX-License-Identifier: MIT
--]]

-- Here are the admonition styles we recognize.
-- For example, a paragraph starting with 'NOTE: ' will trigger a NOTE style admonition.
local admonitions = {
NOTE = { name = "note", title = "Note"},
TIP = { name = "tip", title = "Tip" },
WARNING = { name = "warning", title = "Warning" },
CAUTION = { name = "caution", title = "Caution" },
IMPORTANT = { name = "important", title = "Important" }
}

-- We process each admonition into an one row, two cell HTML table decorated with CSS classes etc.
-- Need to inject the the appropriate links and CSS for those to get those tables rendered correctly.
local need_html_dependencies = true
local function process_admonition_dependencies()
if need_html_dependencies then
-- Inject a link to the fontawesome stylesheet (we use some of their icons to mark the admonition)
local fontawesome_link = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>'
quarto.doc.include_text('in-header', fontawesome_link)

-- Inject our own CSS for styling admonition content and icons -- we have those CSS rules in a local stylesheet.
quarto.doc.add_html_dependency({
name = 'admonitions',
version = '1.0.0',
stylesheets = {'assets/admonitions.css'}
})

-- Don't need to call this again
need_html_dependencies = false
end
end

-- Given an admonition style and its content we create an apporiate HTML table to insert in its place.
local function process_admonition(admonition, content)

-- Add the HTML dependencies if we need to.
if need_html_dependencies then process_admonition_dependencies() end

-- Create an HTML div containing a table with one row and two cells [icon, content].
-- The div & table cells are decorated with classes that depend on the particular admonition style.
-- The HTML for that looks like the following where we use placeholders for the class names etc.
local pre_template = [[<div class="admonition {{<name>}}">
<table><tr>
<td class="icon"> <i class="fa icon-{{<name>}}" title="{{<Title>}}"></i></td>
<td class="content">
]]

-- Turn the template into the specific HTML for this admonition style.
local pre_html = pre_template:gsub('{{<name>}}', admonition.name):gsub('{{<Title>}}', admonition.title)

-- The cell/row/table/div block needs to get closed out with a bunch of closure tags.
local post_html = "</td></tr></table></div>"

-- The admonition will be the the pre & post HTML with the admonition content in between.
return {pandoc.RawBlock('html', pre_html), content, pandoc.RawBlock('html', post_html)}

end

-- Check the passed paragraph to see if we are dealing with an admonition.
local function process_para(el)
-- Grab the first word from the paragraph.
local content = el.content
local first = content[1].text
if first then
-- If that first word is all upper-case and followed by a colon we *may* have an admonition
local possible_admonition = first:match("^(%u*):")
if possible_admonition then
-- Key has the correct form but do we recognize it?
local admonition = admonitions[possible_admonition]
-- Yes it is an admonition
if admonition then
-- Remove the key and a likely space character thereafter to get the admonition content
local start = 2
if #content > 1 and content[2].t == 'Space' then start = 3 end
local admonition_content = { table.unpack(content, start) }
return process_admonition(admonition, admonition_content)
end
end
end
end

return { Para = process_para }
78 changes: 78 additions & 0 deletions docs/_extensions/nessan/admonitions/assets/admonitions.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* More or less the same as AsciiDoc admonitions */

.admonition > table {
width: 100%;
margin-bottom: 1.25em;
word-wrap: normal;
border-collapse: separate;
border: 0;
background: none;
}

.admonition > table tr th,
.admonition > table tr td {
padding: 0.5625em 0.625em;
font-size: inherit;
color: rgba(0, 0, 0, 0.8);
}

.admonition > table tr td {
line-height: 1.6;
}

.admonition > table td.icon {
text-align: center;
width: 80px;
}
.admonition > table td.icon img {
max-width: none;
}
.admonition > table td.icon .title {
font-weight: bold;
font-family: "Open Sans", "DejaVu Sans", sans-serif;
text-transform: uppercase;
}

.admonition > table td.content {
padding-left: 1.125em;
padding-right: 1.25em;
border-left: 1px solid #dddddf;
color: rgba(0, 0, 0, 0.6);
word-wrap: anywhere;
}

.admonition > table td.content > :last-child > :last-child {
margin-bottom: 0;
}

.admonition td.icon [class^="fa icon-"] {
font-size: 2.5em;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
cursor: default;
}

.admonition td.icon .icon-note::before {
content: "\f05a";
color: #19407c;
}

.admonition td.icon .icon-tip::before {
content: "\f0eb";
text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8);
color: #111;
}

.admonition td.icon .icon-warning::before {
content: "\f071";
color: #bf6900;
}

.admonition td.icon .icon-caution::before {
content: "\f06d";
color: #bf3400;
}

.admonition td.icon .icon-important::before {
content: "\f06a";
color: #bf0000;
}
2 changes: 2 additions & 0 deletions docs/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ project:

# Extensions:
# simple-vars: Lets us reference variables as `{name}` instead of the wordier `{{< var name >}}`
# admonitions: A simpler alternative to Quarto callout blocks.
filters:
- simple-vars
- admonitions

format:
html:
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/gauss/constructors.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@ On construction, a `gauss` computes the {reduced-row-echelon-form} of $A$ by us
It performs the same operations to a copy of the input bit-vector $b$.
Once done, it can readily compute the rank of $A$, check the system for consistency, calculate the number of free variables, etc.
::: {.callout-note}
# Efficiency
If $A$ is $n \times n$, then construction is an $\mathcal{O}(n^3)$ operation (though due to the nature of {f2}, things are done in blocks at a time).
NOTE: If $A$ is $n \times n$, then construction is an $\mathcal{O}(n^3)$ operation (though due to the nature of {f2}, things are done in blocks at a time).
There are potentially sub-cubic ways of doing this work using various block-iterative methods that have not yet been implemented.
:::
[Example]{.bt}
```cpp
Expand Down
10 changes: 2 additions & 8 deletions docs/pages/gauss/functor.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@ bit::vector operator()(std::size_t i) const; // <2>
1. Return a random solution amongst all the possible solutions for the system $A \cdot x = b$.
2. Return a specific solution (solution number `i` if you like) for the system $A \cdot x = b$.
::: {.callout-warning}
# Beware of systems with no solutions
Both these methods throw an exception if the system has no solutions.
WARNING: Both these methods throw an exception if the system has no solutions.
You can avoid that by first calling the {gauss.solution_count}method.
:::
If the system is consistent (so at least one solution) with $m$ independent equations for $n$ unknowns and $n > m$, then it has $f = n-m$ free variables.
Expand All @@ -35,10 +32,7 @@ It will return 0 for an inconsistent system, 1 for a full-rank system, and $\min
If the solver is our Gauss object, then the call solver(n) will return the solution "number" n, where `n` is one of those addressable solutions.
::: {.callout-warning}
# Range checking
The `n` must be less than {gauss.solution_count}, or an exception is thrown.
:::
WARNING: The `n` must be less than {gauss.solution_count}, or an exception is thrown.
[Example]{.bt}
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/gauss/solve.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,11 @@ If there is a problem, the return value will be a {std.nullopt}.
This happens if the system of equations has no solution.
It will also be the case if `A` is not square or if the size of `b` is not the same as the number of rows in `A`.
::: {.callout-note}
# The concept
The idea is to get _one_ solution for a system of equations with the least possible fuss. +
NOTE: The idea is to get _one_ solution for a system of equations with the least possible fuss. +
Over {f2}, any free variable can take on one of the values 0 and 1.
Hence, if the system is consistent and has $f$ free variables, it will have $2^f$ possible solutions.
So, a consistent system will have a unique solution only if $A$ has full-rank.
The {gauss.operator(i)} method iterates through potentially non-unique solutions if that is required.
:::
[Example]{.bt}
```cpp
Expand Down
12 changes: 4 additions & 8 deletions docs/pages/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,8 @@ c(M) yields:
│0 0 0 0 0 0│
│0 0 0 0 0 0│
```
::: {.callout-note}
# The special nature of {f2}
`bit` makes it possible to quickly extract the characteristic polynomial for a bit-matrix with millions of elements---​a problem that chokes a naive implementation that does not consider the special nature of arithmetic in {f2}.
:::

NOTE: `bit` makes it possible to quickly extract the characteristic polynomial for a bit-matrix with millions of elements --- ​a problem that chokes a naive implementation that does not consider the special nature of arithmetic in {f2}.

## Installation

Expand All @@ -77,11 +75,9 @@ This command downloads and unpacks an archive of the current version of `bit` to

Used like this, `FetchContent` will only download a minimal library version without any redundant test code, sample programs, documentation files, etc.

::: {.callout-note}
# Library versions
The shown `URL` gets the `current` version of the library---whatever is in the main branch.
NOTE: The shown `URL` gets the `current` version of the library---whatever is in the main branch.
For a fixed, stable library version (say release `2.0.0`), use a `URL` parameter like `https://github.com/nessan/bit/releases/download/2.0.0/bit.zip`.
:::


## Why Use `bit`?

Expand Down
10 changes: 2 additions & 8 deletions docs/pages/lu/constructors.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,10 @@ The permutation matrix $P$ is also stored compactly --- see {lu.permute}.
The decomposition always works even if $A$ is singular, but other `lu` methods will not.
::: {.callout-note}
# Generalizations
There are generalizations of the {LU-decomposition} that handle rectangular matrices, but we have not implemented those yet.
:::
NOTE: There are generalizations of the {LU-decomposition} that handle rectangular matrices, but we have not implemented those yet.
::: {.callout-note}
# Efficiency
If $A$ is $n \times n$, then construction is an $\mathcal{O}(n^3)$ operation (though due to the nature of {f2}, things are done in blocks at a time).
NOTE: If $A$ is $n \times n$, then construction is an $\mathcal{O}(n^3)$ operation (though due to the nature of {f2}, things are done in blocks at a time).
There are sub-cubic ways of doing this work using various block-iterative methods, but those methods have not been implemented here yet.
:::
[Example]{.bt}
```cpp
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/lu/functor.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ If $A$ is $n \times n$ each system solution takes just $\mathcal{O}(n^2)$ operat
These methods return {std.nullopt} if the underlying bit-matrix $A$ is singular.
You can avoid that by first calling the {lu.singular} method.
::: {.callout-warning}
# Size checking
Both methods throw an exception if the number of elements in $b$ or rows in $B$ does not match the number of rows in $A$.
WARNING: Both methods throw an exception if the number of elements in $b$ or rows in $B$ does not match the number of rows in $A$.
They could instead return a {std.nullopt}, but a dimension mismatch is likely an indication of a coding error somewhere.
:::
[Example]{.bt}
```cpp
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/lu/permute.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,8 @@ This _row-swaps_ scheme gives swapping instructions to be applied one after the
Our example in this format becomes $[0, 2, 2, 4, 4]$.
This vector can be interpreted as no swap on row 0, followed by a swap of rows 1 and 2, then no further swap on row 2, followed by a swap of rows 3 and 4, and finally, no further swap on row 4.
::: {.callout-note}
# This is for information only
Internally, we store and use $P$ in the row-swaps instruction form.
NOTE: Internally, we store and use $P$ in the row-swaps instruction form.
The index permutation form is provided only for informational purposes.
:::
### See Also
{lu.operator()}
5 changes: 1 addition & 4 deletions docs/pages/matrix/access.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,8 @@ col(std::size_t j) const; // <6>
5. Synonyms for the `row(i)` methods to allow for alternate `C` style indexing a la `matrix[i][j]`.
6. Read-only access to the elements in column `i` of a bit-matrix.
::: {.callout-warning}
# Range checks
In general, these methods do *not* check whether an index is in bounds, and if it isn't, the behaviour is undefined (but bound to be wrong!)
WARNING: In general, these methods do *not* check whether an index is in bounds, and if it isn't, the behaviour is undefined (but bound to be wrong!)
Set the `BIT_VERIFY` flag at compile time to check this condition --- any violation will cause the program to abort with a helpful message.
:::
[Example]{.bt}
```cpp
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/matrix/all.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@ constexpr bool none() const; // <3>
2. Return `true` if any elements in the bit-matrix are 1; otherwise, `false`.
3. Return `true` if none of the elements in the bit-matrix are 1; otherwise, `false`.

::: {.callout-caution}
# Empty bit-matrices
Calling these methods for an empty bit-matrix is likely an error --- if you set the `BIT_VERIFY` flag at compile time, we throw an exception with a helpful message.
CAUTION: Calling these methods for an empty bit-matrix is likely an error --- if you set the `BIT_VERIFY` flag at compile time, we throw an exception with a helpful message.
If the `BIT_VERIFY` flag is not set, `all()` and `none()` _both_ return `true` while `any()` will return `false`.
:::

[Example]{.bt}
```cpp
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/matrix/append.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ bit::matrix join(const bit::matrix& M, const bit::vector& V); // <4>
3. Returns a new matrix, the augmented $M|v$.
4. Returns a new matrix, the augmented $M|V$.
::: {.callout-warning}
# Consistency
The number of rows in `v` and `V` must match the number in `M`.
:::
WARNING: The number of rows in `v` and `V` must match the number in `M`.
[Example]{.bt}
```cpp
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/matrix/capacity.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ constexpr std::size_t col_capacity() const; // <2>
1. How many rows can be added without a memory allocation?
2. How many columns can be added without a memory allocation?

::: {.callout-warning}
# Each row is not checked.
The rows may not all have the same capacity --- the `col_capacity()` method reports the capacity of the _first_ row.
:::
WARNING: The rows may not all have the same capacity --- the `col_capacity()` method reports the capacity of the _first_ row.

[Example]{.bt}
```cpp
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/matrix/constructors.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ bit::matrix(std::string &src, bool bit_order = false); // <7>
Newlines, white spaces, commas, or semi-colons must separate the rows.
Each row should be encoded in a string as documented in the {vec.constructors} page.
::: {.callout-note}
# Exceptions
If parse errors exist, these methods throw a `std::invalid_argument` exception.
:::
NOTE: If parse errors exist, these methods throw a `std::invalid_argument` exception.
### Method Arguments
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/matrix/description.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ constexpr void description(const std::string &head = "", +
You can send along some arbitrary text that gets prepended or appended to the description of the bit-matrix.
See the example below.
::: {.callout-caution}
# The output format may change
The primary use for these methods is debugging. \
CAUTION: The primary use for these methods is debugging. \
The format of the descriptive data may change from time to time.
:::
[Example]{.bt}
```cpp
Expand Down
Loading

0 comments on commit 6241c83

Please sign in to comment.