592 lines
21 KiB
Markdown
592 lines
21 KiB
Markdown
---
|
|
title: >-
|
|
Writing and Editing Documentation
|
|
# katex
|
|
---
|
|
# Pandoc Markdown
|
|
|
|
Much documentation is in Pandoc markdown, because easier to write. But html
|
|
is easier to read, and allows superior control of appearance
|
|
|
|
To convert Pandoc markdown to its final html form, invoke `Pandoc` by the bash
|
|
shell file `./mkdoc.sh`, which generates html.
|
|
|
|
In the windows 10 environment, shell scripts used in this project need to be
|
|
associated with [Git Bash](libraries/git_bash_undocumented.html) or run from within Git Bash.
|
|
|
|
If the title in the markdown file is followed by `# katex`, as in
|
|
the markdown form of this file, the shell script will tell Pandoc to display
|
|
any formulae using katex in the html file.
|
|
|
|
More precisely, if any of the first three lines in the yaml header specifying
|
|
the title at the start of the markdown file are `# katex`, the `./mkdoc.sh`
|
|
will tell Pandoc to use katex to display maths formula.
|
|
|
|
This vast pile of notes is out of control, and writing code and maths in
|
|
html leads to intolerable overheads.
|
|
|
|
Hence markdown, the popular markdown conversion program
|
|
being the open source Pandoc.
|
|
|
|
Markdown converters are apt to throw a flood of incomprehensible html code
|
|
into your final document, taking low level html control away from the writer.
|
|
|
|
Pandoc, however, will allow you to take control. To integrate html and css
|
|
with markdown using Pandoc is a bit like rolling marbles with your
|
|
elbows through a cage. One has to work through and around the entry
|
|
points that Pandoc gives you, while if you were writing in html you could
|
|
just write what you damn well wanted directly, but having done the work,
|
|
Pandoc can then ensure it is done for every document in the same style in
|
|
the same way, and you can change the final form of every document in the
|
|
same way all at once.
|
|
|
|
Sphinx is very popular and widely used, and written in the far more
|
|
accessible language python, but to access the power of html, css, and
|
|
JavaScript one must write a Sphinx theme, and the creation of a Sphinx theme
|
|
is less than well documented and appears to be subject to change.
|
|
|
|
Visual Studio Code theoretically does automatic generation of the html
|
|
equivalents of markdown files, but I never was able to get it working
|
|
satisfactorily.
|
|
|
|
Pandoc has a number of powerful extensions that allow integration of html and
|
|
markdown, among them markdown native mode divs `:::`
|
|
|
|
```markdown
|
|
::: {style="…"}
|
|
…
|
|
:::
|
|
```
|
|
|
|
And native mode spans `[…]{style="…"}`
|
|
|
|
Which extensions do not work correctly in Visual Studio Code.
|
|
|
|
These can be used to put an anchor in text, but the easiest and most
|
|
intelligible way to insert an anchor is as a header.
|
|
|
|
Pandoc can do a good job of rendering math markdown without invoking
|
|
katex, and in such cases, one should generate the html
|
|
|
|
```bash
|
|
fn=filename
|
|
pandoc --toc --eol=lf --wrap=preserve --from markdown+ascii_identifiers --to html --metadata=lang:en --verbose --include-in-header=./pandoc_templates/header.pandoc --include-before-body=./pandoc_templates/before.pandoc --include-after-body=./pandoc_templates/after.Pandoc -o $fn.html $fn.md
|
|
```
|
|
|
|
Since markdown has no concept of a title, Pandoc expects to find the
|
|
title in a yaml inline, which is most conveniently put at the top, which
|
|
renders it somewhat legible as a title.
|
|
|
|
Thus the markdown version of this document starts with:
|
|
|
|
```markdown
|
|
---
|
|
title: >-
|
|
Writing and Editing Documentation
|
|
# katex
|
|
---
|
|
```
|
|
|
|
# Converting html source to markdown source
|
|
|
|
In bash
|
|
|
|
```bash
|
|
fn=foobar
|
|
git mv $fn.html $fn.md && cp $fn.md $fn.html && pandoc -s --to markdown-smart --eol=lf --wrap=preserve --verbose -o $fn.md $fn.html
|
|
```
|
|
|
|
# Math expressions and katex
|
|
|
|
Pandoc can render most maths markdown without needing katex, for example:
|
|
$${e}^{i\pi}+1=0$$
|
|
$$a=b+c$$
|
|
$$f(x) = x^2$$
|
|
$$\sin(\pi/6) = 0.5$$
|
|
$$\int_a^b f(x) dx$$
|
|
$$\int_a^b \tan(x) dx$$
|
|
$$\int \sin(x) dx = \cos(x)$$
|
|
$$\sum a_i$$
|
|
$$\lfloor{(x+5)÷6}\rfloor = \lceil{(x÷6}\rceil$$
|
|
$$\lfloor{(x+5)/6}\rfloor = \lceil{(x/6}\rceil$$
|
|
Using Omicron, \bigcirc, not capital O for big \bigcirc. `\Omicron` will not always
|
|
compile correctly, but `\ln` and `\log` is more likely to compile correctly than
|
|
`ln` and `log`, which it tends to render as symbols multiplied, rather than one
|
|
symbol.
|
|
$$\ln(1+x)=x-\bigcirc(x^2)$$
|
|
$$H(a|b|v)$$
|
|
|
|
though it is subtly prettier with katex, and some maths expressions will
|
|
break Pandoc unless one tells it to use katex.
|
|
|
|
Some maths, Pandoc needs katex:
|
|
|
|
$$\sin(\frac{\pi}{6}) = \frac12$$
|
|
$$\displaystyle\frac{u(x)}{v(x)}$$
|
|
Inline equation $\displaystyle\sum\limits_{i=1}^n i^2 = \frac{n(n+1)(2n+1)}{6}$ text after inline equation
|
|
|
|
$$\displaystyle\sum\limits_{i} i^2 = \frac{i(i+1)(2i+1)}6$$
|
|
The square root of 100 is $\sqrt{100}=10$.\
|
|
The cubic root of 64 is $\sqrt[3]{64}=4$
|
|
$$\bigg\lfloor\frac{x+5)}{6}\bigg\rfloor = \bigg\lceil{\frac{x}{6}}\bigg\rceil$$
|
|
|
|
So for documents requiring some heavy maths display, we convert from markdown
|
|
to html with, in the bash script `./mkdoc.sh`:
|
|
|
|
```bash
|
|
fn=filename
|
|
pandoc --katex=./ --toc --eol=lf --wrap=preserve --from markdown --to html --metadata=lang:en --verbose --include-in-header=./pandoc_templates/header.pandoc --include-before-body=./pandoc_templates/before.pandoc --include-after-body=./pandoc_templates/after.pandoc -o $fn.html $fn.md
|
|
```
|
|
|
|
The `./` tells `pandoc` to expect to find the files
|
|
|
|
```bash
|
|
./katex.min.css
|
|
./katex.min.js
|
|
```
|
|
|
|
That a file needs katex is flagged for `./mkdoc.sh` in the yaml header.
|
|
|
|
A file that does not need katex has the header:
|
|
|
|
```markdown
|
|
---
|
|
title: >-
|
|
Document title
|
|
---
|
|
```
|
|
|
|
But if it does need katex, it has the header
|
|
|
|
```markdown
|
|
---
|
|
title: >-
|
|
Document title
|
|
# katex
|
|
---
|
|
```
|
|
|
|
So that the bash script file `./mkdoc.sh` will tell `Pandoc` to find the katex scripts.
|
|
|
|
For it offends me to put unnecessary fat in html files.
|
|
|
|
## overly clever katex tricks
|
|
|
|
$$k \approx \frac{m\,l\!n(2)}{n}%uses\, to increase spacing, uses \! to merge letters, uses % for comments $$
|
|
|
|
$$k \approx\frac{m\>\ln(2)}{n}%uses\> for a marginally larger increase in spacing and uses \ln, the escape for the well known function ln $$
|
|
|
|
$$ \exp\bigg(\frac{a+bt}{x}\bigg)=\huge e^{\bigg(\frac{a+bt}{x}\bigg)}%use the escape for well known functions, use text size sets$$
|
|
|
|
$$k\text{, the number of hashes} \approx \frac{m\ln(2)}{n}% \text{} for render as text$$
|
|
|
|
$$\def\mydef#1{\frac{#1}{1+#1}} \mydef{\mydef{\mydef{\mydef{y}}}}%katex macro $$
|
|
|
|
# diagrams
|
|
|
|
The best way to do diagrams is Inkscape and the Visual Studio Code
|
|
scalable vector graphics extensions.
|
|
|
|
I decided to place the data directly inline in markdown because interfacing
|
|
scalable vector graphics files (`svg` files) to html can get complicated, and
|
|
interfacing the resulting complicated html to markdown can get more
|
|
complicated.
|
|
|
|
Inkscape files are unreadable, and once they are cleaned up, Inkscape
|
|
cannot read them. To (irreversibly) clean up an Inkscape file, minify it in
|
|
Visual Studio Code to get rid of all confusing mystery cruft inserted by
|
|
Inkscape, edit it back into markdown compatible form, and reinsert it in
|
|
the markdown file.
|
|
|
|
A sequence of straight lines is M point, L point, L point.
|
|
|
|
Z and z draw a straight line back to the beginning, use in conjunction with
|
|
`fill="#red"` , for example `fill="#FF0000"`. If the line is open, `fill="none"`
|
|
|
|
Drawing smooth curves by typing in text is painful and slow, but so is
|
|
drawing them in Inkscape. Inkscape is apt to do a series of C beziers with
|
|
sharp corners between them, and when I try to fix the sharp corners, the
|
|
bezier goes weird.
|
|
|
|
What Inkscape should do is let you manipulate a sequence of control
|
|
points, and draw an M C S S ..S bezier to the point halfway between the
|
|
final even numbered control point and the preceding control point,
|
|
creating an additional control point by mirroring if the user only provides
|
|
an odd number of control points.
|
|
|
|
What it does instead is complicated and mysterious.
|
|
|
|
To convert a sequence of straight lines into a smooth curve, you encounter
|
|
much grief matching the end of one bezier to the start of the next.\
|
|
And if you do not match them, you get corners between beziers.
|
|
|
|
* find the midpoint of each edge, or the midpoint of every second edge\
|
|
When I say midpoint, somewhere along the line, close to where
|
|
you want the turn to sharp, and far from where you want the turn to be gentle.
|
|
|
|
* A smooth curve starts a midpoint of first edge then:\
|
|
C first vertex, second vertex, next midpoint S second next vertex
|
|
next midpoint S second next vertex, next midpoint ... S second next
|
|
vertex next midpoint ...\
|
|
When I say second next vertex, I mean you skip a vertex, and thus
|
|
do not have to find the preceding midpoint. But the implied vertex
|
|
is the mirror of the preceding vertex, which if your midpoint is off,
|
|
is not where you expect it to be.\
|
|
If it fails to go through the midpoint parallel to what you think the
|
|
endpoints are, you need to tinker the control point to reduce the
|
|
discrepancy, or else it is apt to be off at subsequent midpoints.
|
|
|
|
* Or starts at midpoint of first edge then:\
|
|
Q vertex midpoint T midpoint T midpoint ....\
|
|
But the Q T T T chain is apt to act weird unless your midpoints are
|
|
near the middle, because the implied vertex is the mirror of the
|
|
preceding vertex, which may not be the vertex that you intended if
|
|
your midpoint is not near the centre of the line segment to that vertex.
|
|
|
|
Using S and T has the enormous advantage that if your midpoint is a bit
|
|
off to one side of the line segment or the other, you still get a smooth
|
|
curve, no kinks between beziers But if it is too far off from the centre,
|
|
your curve will be off from the line segments, often in weird, surprising,
|
|
and complicated ways.
|
|
|
|
On the other hand, if you have a C or a Q bezier following a previous C
|
|
or Q bezier, getting the join smooth is a bitch.
|
|
|
|
To find the midpoint of a line segment, I use `M` approximate midpoint
|
|
`v6 v-12 v6 h6 h-12 h6` to mark the location with a cross.
|
|
|
|
To draw a long twisty curve, mark your intended path with a sequence of
|
|
line segments, with your final line segment passing through your
|
|
destination, because destination will be the midpoint of that line segment.
|
|
Then do a M first point, C second point, third point, midpoint, then S
|
|
even numbered vertex, midpoint following the even numbered vertex, starting
|
|
with the fourth vertex and the midpoint to the fifth vertex. The midpoint of
|
|
the final vertex will be your destination.
|
|
|
|
Scalable vector graphics are dimensionless, and the `<svg>` tag's height,
|
|
width, and ViewBox properties translate the dimensionless quantities into
|
|
pixels. The graphics default to fixed aspect ratio, and anything outside
|
|
the viewbox is not drawn. To adjust your image's position within the
|
|
viewbox, you put everything into a single big group, and apply a translate
|
|
to that group.
|
|
|
|
You need to set an Inkscape tools properties from an existing element that
|
|
you have manually edited as text, as a great deal of functionality is only
|
|
available by editing vector graphics as text, and attempting to manipulate
|
|
that functionality from Inkscape, though in theory possible, just creates
|
|
an uncontrollable mess.
|
|
|
|
Every so often, a tool's properties get set to something stupid for some
|
|
stupid reason, and there is no fix available in the Inkscape UI, other than
|
|
selecting a graphic element, double clicking on the tool, and telling it to
|
|
take its defaults from the element selected. (which can be an entire group,
|
|
or the entire high top level group, in which case it will pick up sane and
|
|
appropriate properties from the first relevant item in the group.)
|
|
|
|
The enormous advantage of scalable vector graphics is that it handles
|
|
repetitious items in diagrams beautifully, because you can define an item
|
|
by reference to another item, thus very large hierarchical structure can be
|
|
defined by very small source code.
|
|
|
|
You might decide to keep it around as soup, in an `svg` file that only
|
|
Inkscape ever tries to read, but then you are going to have to edit it as text
|
|
again. And I wound up embedding my vector graphics files in markdown
|
|
rather than invoking them as separate graphics files because my last step
|
|
was apt to be editing them as text. Which irreversibly made them
|
|
uneditable by Inkscape
|
|
|
|
It is convenient to construct and position all the graphical elements in
|
|
Inkscape, then edit the resulting `svg` file in Visual Studio Code with the
|
|
`svg` extension, watching the resulting graphic in the `svg` editor's preview
|
|
pane, then use the `svg` extension's minify command to get rid of all the
|
|
excess stuff generated by Inkscape, then edit the `svg` file to be compatible
|
|
with Markdown, then edit it into the markdown file, then edit the
|
|
markdown file in the Visual Studio Code markdown editor, watching the
|
|
graphic in the markdown preview pane.
|
|
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="29em" height="12em"
|
|
viewBox="40 60 60 50"
|
|
style="background-color:ivory">
|
|
<g id="startblocks"
|
|
font-family="'Times New Roman'" font-size="5"
|
|
font-weight="400"
|
|
stroke-width="2"
|
|
style="text-decoration:underline; cursor:pointer;" >
|
|
<line x1="22" y1="70" x2="28" y2="100" stroke="lightgrey"/>
|
|
<rect style="fill:#FFFF00;"
|
|
x="12" y="64" width="36" height="20">
|
|
<animate attributeType="XML" attributeName="y"
|
|
from="64" to="110"
|
|
dur="5s" repeatCount="2" restart="always" />
|
|
</rect>
|
|
<text style="fill:blue;" x="14" y="74">
|
|
<animate attributeType="XML" attributeName="y"
|
|
from="74" to="120"
|
|
dur="5s" repeatCount="2" restart="always" />
|
|
start animation
|
|
</text>
|
|
</g>
|
|
<rect x="60" y="64" width="20" height="20">
|
|
<animate attributeType="XML" attributeName="y"
|
|
from="64" to="120"
|
|
dur="3s" repeatCount="5" restart="whenNotActive"/>
|
|
<animate attributeType="XML" attributeName="x"
|
|
from="60" to="0"
|
|
dur="3s" repeatCount="5" restart="whenNotActive"/></rect>
|
|
<g
|
|
font-family="'Times New Roman'" font-size="5"
|
|
font-weight="400"
|
|
stroke-width="2">
|
|
<path fill="none" stroke="#00f000"
|
|
d="M14 101, c40 -20, 30 -56,
|
|
54 -18, s60 15, 40 15"/>
|
|
<ellipse cx="60" cy="85" rx="12" ry="5" style="fill:red" />
|
|
<text x="60" y="82" text-anchor="middle" style="fill:#A050C0;" >
|
|
A simple scalable vector graphic
|
|
<tspan x="60" dy="8">
|
|
directly embedded in markdown.
|
|
</tspan>
|
|
</text>
|
|
</g>
|
|
</svg>
|
|
|
|
<script>
|
|
document.getElementById("startblocks").addEventListener
|
|
(
|
|
"click", evt =>
|
|
{
|
|
document.querySelectorAll("animate").forEach
|
|
(
|
|
element =>
|
|
{
|
|
element.beginElement();
|
|
}
|
|
);
|
|
}
|
|
);
|
|
</script>
|
|
|
|
```svg
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="29em" height="12em"
|
|
viewBox="40 60 60 50"
|
|
style="background-color:ivory">
|
|
<g id="startblocks"
|
|
font-family="'Times New Roman'" font-size="5"
|
|
font-weight="400"
|
|
stroke-width="2"
|
|
style="text-decoration:underline; cursor:pointer;" >
|
|
<line x1="22" y1="70" x2="28" y2="100" stroke="lightgrey"/>
|
|
<rect style="fill:#FFFF00;"
|
|
x="12" y="64" width="36" height="20">
|
|
<animate attributeType="XML" attributeName="y"
|
|
from="64" to="120"
|
|
dur="5s" repeatCount="2" restart="always" />
|
|
</rect>
|
|
<text style="fill:blue;" x="14" y="74">
|
|
<animate attributeType="XML" attributeName="y"
|
|
from="74" to="130"
|
|
dur="5s" repeatCount="2" restart="always" />
|
|
start animation
|
|
</text>
|
|
</g>
|
|
<rect x="60" y="64" width="20" height="20">
|
|
<animate attributeType="XML" attributeName="y"
|
|
from="64" to="120"
|
|
dur="5s" repeatCount="3" restart="whenNotActive"/>
|
|
</rect>
|
|
<g
|
|
font-family="'Times New Roman'" font-size="5"
|
|
font-weight="400"
|
|
stroke-width="2">
|
|
<path fill="none" stroke="#00f000"
|
|
d="M14.629 101.381c25.856-20.072 50.69-56.814
|
|
54.433-18.37 3.742 38.443 40.484 15.309 40.484 15.309"/>
|
|
<ellipse cx="60" cy="85" rx="12" ry="5" style="fill:red" />
|
|
<text x="60" y="82" text-anchor="middle" style="fill:#A050C0;" >
|
|
A simple scalable vector graphic
|
|
<tspan x="60" dy="8">
|
|
directly embedded in markdown.
|
|
</tspan>
|
|
</text>
|
|
</g>
|
|
</svg>
|
|
```
|
|
|
|
```script
|
|
<script>
|
|
document.getElementById("startblocks").addEventListener
|
|
(
|
|
"click", evt =>
|
|
{
|
|
document.querySelectorAll("animate").forEach
|
|
(
|
|
element =>
|
|
{
|
|
element.beginElement();
|
|
}
|
|
);
|
|
}
|
|
);
|
|
</script>
|
|
|
|
# tables
|
|
|
|
<table border="1" cellpadding="6" cellspacing="0" width="95%">
|
|
<tbody>
|
|
<tr>
|
|
<td colspan="2" style="background-color: #99CC66;
|
|
text-align:center;">May Scale of monetary hardness </td>
|
|
</tr>
|
|
<tr>
|
|
<td style="text-align:center;"><b> Hardness</b> </td>
|
|
<td> <br/>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2" style=" text-align:center;">Hard</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>1</b></td>
|
|
<td>Street cash, US dollars</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>2</b></td>
|
|
<td>Street cash, euro currencies, japan</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>3</b></td>
|
|
<td>Major crypto currencies, such as Bitcoin and Monaro</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>4</b></td>
|
|
<td>Street cash, other regions</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>5</b></td>
|
|
<td>Interbank transfers of various sorts (wires etc),
|
|
bank checks</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>6</b></td>
|
|
<td>personal checks</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>7</b>
|
|
</td>
|
|
<td>Consumer-level electronic account transfers (eg
|
|
bPay)</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>8</b></td>
|
|
<td>Business-account-level retail transfer systems</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2" style=" text-align:center;">Soft</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>9</b></td>
|
|
<td>Paypal and similar 'new money' entities, beenz</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="center"><b>10</b></td>
|
|
<td>Credit cards</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
```
|
|
|
|
# Tables
|
|
|
|
## Pipe table with header and alignment control
|
|
|
|
Without counting spaces, but without multiline
|
|
|
|
Pipe table:
|
|
|
|
| Right | Left | Default | Center |
|
|
|------:|:-----|---------|:----------------------:|
|
|
| 12 | 12 | 12 | 12 |
|
|
| 123 | 123 | 123 | the quick brown fox jumped over the lazy dog |
|
|
| 1 | 1 | Carrian Corporation | 1 |
|
|
|
|
## And, with less mucking about, alignments
|
|
|
|
with alignment, without counting spaces, but without multiline
|
|
|
|
fruit| price
|
|
:-----|-----:
|
|
apple|2.05
|
|
pear|1.37
|
|
orange|3.09
|
|
|
|
## multiline without bothering with pipes
|
|
|
|
Counting spaces to align. Only editable in fixed font
|
|
|
|
This allows multiline, but visual studio code does not like it. Visual Studio Code only supports tables that can be intelligibly laid out in visual studio code.
|
|
|
|
-------------------------------------------------------------
|
|
Centered Default Right Left
|
|
Header Aligned Aligned Aligned
|
|
----------- ------- --------------- -------------------------
|
|
First row 12.0 Example of a row that
|
|
spans multiple lines.
|
|
|
|
Second row 5.0 Here's another one. Note
|
|
the blank line between
|
|
rows.
|
|
-------------------------------------------------------------
|
|
|
|
## The header may be omitted in multiline tables as well as simple tables
|
|
|
|
Notice the alignment is controlled by the first item in a column
|
|
|
|
In this table, edited in a fixed font, you are using whitespace and blank lines to lay out the table. It is unintellible in a variable width font.
|
|
|
|
----------- ------- --------------- -------------------------
|
|
First row 12.0 Example of a row that
|
|
spans multiple lines.
|
|
|
|
Second row 5.0 Here's another one. Note
|
|
the blank line between
|
|
rows.
|
|
----------- ------- --------------- -------------------------
|
|
|
|
## Grid tables
|
|
|
|
Allows multiline, and alignment, but visual studio does not like it, and you still have to count those spacees
|
|
|
|
+---------------+---------------+--------------------+
|
|
| Fruit | Price | Advantages |
|
|
+===============+==============:+====================+
|
|
| Bananas | $1.34 | - built-in wrapper |
|
|
| | | - bright color |
|
|
+---------------+---------------+--------------------+
|
|
| Oranges | $2.10 | - cures scurvy |
|
|
| | | - tasty |
|
|
+---------------+---------------+--------------------+
|
|
| Durian | $22.10 | - king of fruits |
|
|
+---------------+---------------+--------------------+
|
|
|
|
Alignments can be specified as with pipe tables, by putting colons at the boundaries of the separator line after the header.
|
|
|
|
+------------+---------+---------------------+
|
|
| Left | Right | Centered |
|
|
+:===========+========:+:===================:+
|
|
| Bananas | $1.34 | - built-in wrapper |
|
|
| | | - bright color |
|
|
+------------+---------+---------------------+
|
|
| Durian | $22.10 | - king of fruits |
|
|
+------------+---------+---------------------+
|
|
|
|
## For headerless tables, the colons go on the top line instead:
|
|
|
|
+--------------:+:--------------+:------------------:+
|
|
| Right | Left | Centered |
|
|
+---------------+---------------+--------------------+
|