aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore0
-rw-r--r--README.md222
-rw-r--r--foo.1.adoc37
3 files changed, 259 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.gitignore
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0dc1b1e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,222 @@
+# Writing Man Pages with AsciiDoc
+
+A workflow for authoring Unix man pages in AsciiDoc and installing them into
+the local man database on Debian (and Debian-derived) systems.
+
+## Why AsciiDoc
+
+Native `roff` is terse and unforgiving. AsciiDoc is plain-text, version-control
+friendly, and `asciidoctor` ships a dedicated `manpage` backend that produces
+groff source indistinguishable from a hand-written page.
+
+## Prerequisites
+
+```sh
+sudo apt install asciidoctor
+```
+
+Confirm the manpage backend is available:
+
+```sh
+asciidoctor --backend=manpage --help >/dev/null && echo OK
+```
+
+## Source File Structure
+
+Name the source `<command>.<section>.adoc`, where the section is one of:
+
+| Section | Contents |
+|---------|--------------------------------|
+| 1 | User commands |
+| 5 | File formats and conventions |
+| 7 | Miscellaneous / overviews |
+| 8 | System administration commands |
+
+A minimal template (`foo.1.adoc`):
+
+```adoc
+= foo(1)
+Author Name <author@example.org>
+:doctype: manpage
+:manmanual: FOO Manual
+:mansource: FOO 1.0
+
+== NAME
+
+foo - one-line summary of what foo does
+
+== SYNOPSIS
+
+*foo* [_OPTIONS_] _ARGUMENT_
+
+== DESCRIPTION
+
+Longer prose description of the command.
+
+== OPTIONS
+
+*-h*, *--help*::
+ Print help and exit.
+
+*-v*, *--version*::
+ Print version and exit.
+
+*-f* _FILE_, *--file*=_FILE_::
+ Read input from _FILE_.
+
+== EXIT STATUS
+
+*0*::
+ Success.
+
+*1*::
+ General error.
+
+== EXAMPLES
+
+Run foo against a file:
+
+ foo -f /etc/hosts
+
+== ENVIRONMENT
+
+*FOO_CONFIG*::
+ Path to the configuration file.
+
+== FILES
+
+_~/.config/foo/config_::
+ User configuration.
+
+== SEE ALSO
+
+*bar*(1), *baz*(5)
+
+== AUTHORS
+
+Author Name <author@example.org>
+
+== BUGS
+
+Report bugs at https://example.org/foo/issues
+```
+
+### Mandatory elements
+
+- **Title line** `= name(section)` sets the page name and section number.
+- **`:doctype: manpage`** selects the manpage backend.
+- **`NAME`, `SYNOPSIS`, `DESCRIPTION`** headers (uppercase, `==`) are required.
+
+### Useful conventions
+
+- `*bold*` renders as bold (commands, flags).
+- `_italic_` renders as underline in terminals (variables, arguments, file
+ paths).
+- `*cmd*(N)` for cross-references to other man pages.
+- `::` after a term starts a definition list (options, environment vars).
+- Indented lines in `EXAMPLES` are preformatted blocks.
+
+## Building
+
+Convert AsciiDoc to groff man source:
+
+```sh
+asciidoctor -b manpage foo.1.adoc
+```
+
+Output: `foo.1` in the same directory.
+
+Preview without installing:
+
+```sh
+man -l ./foo.1
+```
+
+## Installing Locally
+
+Debian's `man-db` reads `~/.local/share/man` automatically (it is part of the
+default `MANPATH` derivation). No `manpath` edit required.
+
+```sh
+mkdir -p ~/.local/share/man/man1
+cp foo.1 ~/.local/share/man/man1/
+```
+
+After installation:
+
+```sh
+man foo # works immediately
+```
+
+For `apropos` and `whatis` to find the new page, rebuild the index:
+
+```sh
+mandb -u # incremental update of the user index
+```
+
+The user-level index lives in `~/.local/share/man/index.db`; no root needed.
+
+## System-Wide Installation (optional)
+
+For pages that should be visible to all users:
+
+```sh
+sudo cp foo.1 /usr/local/share/man/man1/
+sudo mandb
+```
+
+Use `/usr/local/share/man`, not `/usr/share/man` (the latter is reserved for
+distribution-packaged pages).
+
+## Verification
+
+```sh
+man -w foo # prints the path man would open
+man -k 'one-line summary' # apropos search; requires mandb update
+whatis foo
+```
+
+## Automating with Make
+
+A minimal `Makefile`:
+
+```makefile
+PREFIX ?= $(HOME)/.local
+MAN1DIR := $(PREFIX)/share/man/man1
+
+SOURCES := $(wildcard *.1.adoc)
+PAGES := $(SOURCES:.adoc=)
+
+all: $(PAGES)
+
+%.1: %.1.adoc
+ asciidoctor -b manpage $<
+
+install: all
+ install -d $(MAN1DIR)
+ install -m 644 $(PAGES) $(MAN1DIR)/
+ mandb -u
+
+clean:
+ rm -f $(PAGES)
+
+.PHONY: all install clean
+```
+
+Usage: `make`, `make install`, `make clean`.
+
+## Troubleshooting
+
+| Symptom | Cause / Fix |
+|-------------------------------------------|------------------------------------------------------------------|
+| `man foo` reports "No manual entry" | File not in MANPATH; check `manpath` and `man -w foo` |
+| `apropos foo` finds nothing | Run `mandb -u` |
+| Page renders but options look misaligned | Ensure `::` is on the same logical line as the term it defines |
+| Cross-references not linked in HTML build | Manpage backend renders them as `name(N)` text only; this is OK |
+| Asciidoctor warns about missing `NAME` | The required headers must be uppercase and start with `==` |
+
+## References
+
+- `asciidoctor(1)`, `man(1)`, `man-pages(7)`, `mandb(8)`
+- Asciidoctor manpage backend: <https://docs.asciidoctor.org/asciidoctor/latest/manpage-backend/>
+- File Hierarchy Standard, §4.11 (manual pages)
diff --git a/foo.1.adoc b/foo.1.adoc
new file mode 100644
index 0000000..8692d9e
--- /dev/null
+++ b/foo.1.adoc
@@ -0,0 +1,37 @@
+= foo(1)
+Łukasz Kasprzak
+:doctype: manpage
+:manmanual: FOO Manual
+:mansource: FOO 1.0
+
+== NAME
+
+foo - one-line description
+
+== SYNOPSIS
+
+*foo* [_OPTIONS_] _ARG_
+
+== DESCRIPTION
+
+Longer description.
+
+== OPTIONS
+
+*-h*, *--help*::
+ Show help.
+
+*-v*, *--version*::
+ Print version.
+
+== EXAMPLES
+
+ foo -v
+
+== SEE ALSO
+
+*bar*(1), *baz*(5)
+
+== AUTHOR
+
+Łukasz Kasprzak