screenshot




───────────────── #Sed-based MarkDown viewer and linter ────────────────── This document is meant to be rendered using smd. If not, some renderings won't work as intended. You can see the document as intended by copy-pasting the following in a terminal: ┌── shell ─── url='https://codeberg.org/johann1764/smd/raw/branch/main/smd' smd="$(mktemp -d --tmpdir)" wget -P "$smd" "$url.sh" "$url.md" chmod +x "$smd/smd.sh" "$smd/smd.sh" -d or by visiting the HTML-ified term outputs: dark theme light theme
#Overview ▀────────── smd is a tool for viewing markdown files in a terminal that is feature-rich yet easy to use: ┌── shell ─── smd Readme.md will generate a view of Readme.md and output the result to less, allowing the user to navigate it. The set of markdown extensions vary from one implementation to another. smd offers the ability to process md files in order to make them understandable by most implementations, and to look good even when read as a pure text. ┌── shell ─── smd -i Readme.md will process Readme.md. Several options are available. As an example smd -r -f -i smd.md was used to process this file, and therefore this will have no effect if applied once more. This tool only requires bash and GNU sed, which are included with any GNU/Linux distribution. If you want to benefit from syntax highlighting, you also need bat. No build step is required: it works as is. smd is focused on: 1. providing a beautiful and readable view of md files; and 2. providing a lint process that helps to produce a md file that is both portable and is easy to read as text-only. Providing a pager or other terminal interactive utilities is out of scope of smd. smd mostly follows and extends commonmark specification, with a few exceptions: smd refuses to embed section titles into lists. smd makes a difference between thematic breaks declared with dashes and thematic breaks declared with stars. smd makes a difference between blocks that are separated with a blank line and blocks which are not: a fenced code block may either interrupt an existing paragraph or start a new one.
#1 ─#Install and a Note on Performance ▀─────────────────────────────────────── From a repository clone, installation is fairly trivial: ┌── shell ─── sudo cp smd.sh smd.md /usr/share && sudo ln -s /usr/share/smd.sh /bin/smd Updating with a new version is done with the first line, and uninstalling is obvious: ┌── shell ─── sudo rm -fv /usr/share/smd.sh /usr/share/smd.md /bin/smd You can also install/update smd from scratch by copy-pasting the following in a terminal emulator: ┌── shell ─── url='https://codeberg.org/johann1764/smd/raw/branch/main/smd' sudo wget -N -P /usr/share/ "$url.sh" "$url.md" && sudo chmod +x /usr/share/smd.sh && sudo ln -s /usr/share/smd.sh /bin/smd and then running: ┌── shell ─── smd -d will get you back to that documentation. You can try with an additional -2 to display it with two columns. See screenshots with two columns (light theme) and section Command Line Usage. If need be, you can activate --redraw-on-quit in less to keep the last output page of smd on the terminal. On performance: • on a Raspberry pi 4, smd has a small latency at startup. It will be mitigated, as there is room for speed improvement. smd streams its output: as a consequence, opening a 1000-pages document will take exactly as much time as opening a 2-pages document. However, pressing END will force the processing of the whole file, which might take some time when reading a huge document on a slow machine. This processing occurs even if you don't scroll, so it will usually long be over by the time you finish reading the first page.
#2 ─#Features ▀────────────── Not all features will be detailed here, only the ones that: • need documentation, such as syntax highlighting. • make this program unique, most noticeably: text justification, vertical space management, OSC8 links, and overall attention to details. (Also, there is a two columns mode, see Command Line Usage.) In the rest of this document, unique features are marked with a star *.
#2.1 ─#Text Justification* and Paragraph Breaks smd justifies its paragraph in view mode, just like man does for the man pages. For portability reasons, in linter mode, it just breaks lines without space-padding them. This feature looks obvious, but surprisingly enough, no markdown reader I know of does that. The line length is fixed to slightly more than the optimal readability length. When the output is a terminal, the line length is decreased if needed to fit the terminal width. The default maximum screen width can be modified with the environment variable SMD_W. Par breaks allows to break line inside a paragraph. This can be done with two trailing spaces, a <br/>, //, or \. All these sequences except the backslash \ may be followed by spaces. For example: ┌── md ─── This is a line that needs a break at some point because it is a bit long. This is a line that does not need it. This is the first line\ This is the second one<br/> This is the third one with 2 trailing blanks██ and just adding a newline is not enough. This is a line with a `<br/>` <br/> in the middle. results in: This is a line that needs a break at some point because it is a bit long. This is a line that does not need it. This is the first line This is the second one This is the third one with 2 trailing blanks and just adding a newline is not enough. This is a line with a <br/> in the middle. I follow commonmark suggestions on this topic, therefore linter mode expresses all par breaks using <br/>: ┌── md ─── This is a line that needs a break at some point because it is a bit long. This is a line that does not need it. This is the first line<br/> This is the second one<br/> This is the third one with 2 trailing blanks<br/> and just adding a newline is not enough. This is a line with a `<br/>`<br/> in the middle. Note: when no space is available for cutting the line the line is just not cut. This allow to detect problems more easily (like too long in-text quotes), and also preserves the links destination in lint mode, therefore keeping them clickable on your terminal emulator.
#2.2 ─#Sections
#2.1 ─#Sections and Vertical Space* (Sub)sections are surrounded by vertical space, whose amount depends on their hierarchical level, just like in LaΤeχ. They consume any additional blank line. When two (sub)sections follow each other, the space in between depends on the second one, therefore the first one after space is ignored in this case. In the case the first one is a subsection and the second is a subsubsection, the contrary happens. Why? Because it looks better this way. OK, but why? Visually, the dash-underlining of the subsection name works as a blank line, so it has to be compensated for. That is why. Besides this, the blank lines may or may not occur anywhere. However, multiple blank lines have the same effect as a single one. If the file begins (resp. ends) with blank lines, one of them is kept. (Sub)sections preceded by the beginning of the file have no preceding space.
#2.2 ─#Section Layout (with italics) smd provides different spacing and rendering for all five hierarchical levels. I recommend reserving level 1 for titles, or parts in a document that require a deep structure. As a rule of thumb, here are the levels of hierarchy you want to use in priority: 3, 2 and/or 4, 1, 5. If you have a document with low-level sections and want to improve the layout without changing their level, the -s option allows to have the layout and spacing of section n+1 at level n. Section titles may contain bold and italics. If this is redundant with the section layout, the meaning of these are reversed*: if a section is naturally bold, its bold content will be the only content that won't be bold in the output, and similarly for italics. In a faint context, faint characters will stay as is. For the sake of the demonstration, this document uses an exaggerated sectioning depth, and the level 5 is shown below, which allows to see how it looks. In a general setting, it is advisable to use less than that (2 or 3 in most cases).