The help of sda chapter --help
states:
COMMAND CHAPTER
chapter [SUB-COMMAND] [COMMON-OPTIONS] [ARGS]
COMMON-OPTIONS
| option | args | description |
| -p, --preserve-case | | do not lowercase title for filename suffix |
| -h, --help | | show help |
chapter new CHAPTER-FILENAME-OR-TOPIC
* Convert CHAPTER-TOPIC to a canonical name CANONICAL-CHAPTER-TOPIC
which is suitable as filename README-CANONICAL-CHAPTER-TOPIC.txt
* Generate README-CANONICAL-CHAPTER-TOPIC.txt, if it does not exist.
However, this is not how the command actually works.
With an existing file README-Check-Chapter-New.txt
, the command
sda chapter new README-Check-Chapter-New.txt
takes no action. No canonicalization whatsoever is performed.
It is obvious, that the phrasing of the help text is less than clear and should be more precise to produce a meaningful command description.
It always helps to construct a BNF syntax declaration or at least have it in mind to clearly identify the parts of a syntactic entity.
A BNF syntax is constructed top-down. It starts with top-level syntax elements, which are then further defined until only terminal definitions or transformations are used.
The production of a BNF syntax is extremely simple:
Starting with the input CHAPTER-FILENAME-or-TOPIC, the BNF syntax is as follows.
// input
CHAPTER-FILENAME-or-TOPIC:
CHAPTER-FILENAME | TOPIC
CHAPTER-FILENAME:
PREFIX TOPIC-SUFFIX EXTENSION
TOPIC:
"Mixed Case Topic with Spaces"
PREFIX:
"README"
TOPIC-SUFFIX:
"-" FN-TOPIC | /* empty */
EXTENSION:
".txt"
FN-TOPIC:
subst("[^-0-9A-Za-z], "-", TOPIC)
The output of the operation requires a CANONICAL-CHAPTER-FILENAME, which is constructed from some fixed string elements and a transformed canonical-topic derived from a TOPIC which is one possible input. The other possible input is a CHAPTER-FILENAME, which contains a TOPIC and must therefore be deconstructed.
// output
CANONICAL-CHAPTER-FILENAME:
PREFIX CANONICAL-TOPIC-SUFFIX EXTENSION
CANONICAL-TOPIC-SUFFIX:
"-" FN-CANONICAL-TOPIC | /* empty */
FN-CANONICAL-TOPIC:
subst("[^-0-9A-Za-z], "-", canonical-topic)
canonical-topic:
lowercase(TOPIC)
It is more appropiate to describe the simpler transformation of a generic TOPIC into a canonical-topic and a CANONICAL-TOPIC-SUFFIX before describing the deconstruction of a CHAPTER-FILENAME and then again describing the transformation of the generic TOPIC into a CANONICAL-TOPIC-SUFFIX.
The requirement of a CHAPTER-FILENAME as input is too strict, it is better to accept the name of any existing file, construct a proper chapter filename and rename the input file (FILE-NAME).
With option –preserve-case the chapter filename output is not canonical.
All of this should be reflected in the underlying BNF syntax tree:
// input
TOPIC-or-FILENAME:
TOPIC | FILENAME
TOPIC:
"Mixed Case Topic with Spaces"
FILENAME:
FILEBASE EXTENSION | FILEBASE
FILEBASE:
PREFIX TOPIC-SUFFIX | TOPIC
EXTENSION:
".txt"
PREFIX:
"README"
TOPIC-SUFFIX:
"-" TOPIC | /* empty */
// output
CHAPTER-FILENAME:
PREFIX TOPIC-SUFFIX EXTENSION
TOPIC-SUFFIX:
"-" FN-TOPIC | /* empty */
FN-TOPIC:
subst([^-0-9A-Za-z], "-", CHAPTER-TOPIC)
CHAPTER-TOPIC:
ifelse(--preserve-case, TOPIC, canonical-topic)
canonical-topic:
lowercase(TOPIC)
The description should then speak of
chapter new TOPIC-or-FILENAME
1. If TOPIC-or-FILENAME is the name of an existing file
- extract TOPIC from FILENAME
2. If --preserve-case is given,
- use TOPIC as CHAPTER-TOPIC, otherwise
- use TOPIC converted to lowercase as CHAPTER-TOPIC.
3. Construct FN-TOPIC by replacing all non-alpha characters
in CHAPTER-TOPIC with dashes "-" and squeezing multiple
dashes into a single dash.
4. Construct CHAPTER-FILENAME from FN-TOPIC as:
"README" "-" FN-TOPIC ".txt"
5. If CHAPTER-FILENAME exists
- if FILENAME exists
- if FILENAME is different from CHAPTER-FILENAME
- warn about existing CHAPTER-FILENAME for FILENAME
- warn about existing CHAPTER-FILENAME for TOPIC
- if FILENAME exists
- if FILENAME is different from CHAPTER-FILENAME
- rename FILENAME as CHAPTER-FILENAME
- Create new CHAPTER-FILENAME with title TOPIC.
"README-" canonical-chapter-topic ".txt"