It can handle two different sets of doc per single file – one for ordinary users and another for developers
DocStrip uses its own macro language to format docs.
DocStrip is written in Tensile and is part of its distribution (see sl(1)) 
 
Essentially, a DocStrip block is a sequence of text characters and macros introduced with a backslash. Macros may have arguments which are enclosed into brackets. A macro name is either a single character or a sequence of alphanumeric characters and underscores starting with a letter. If a backslashed character has no macro definition, it is treated as an ordinary After alphanumeric macro names spaces are swallowed. Whether they are kept after arguments is macro-dependant. 
 
If a first line of a block doesn't start with a macro, it is treated as a subsection header. 
 
Empty lines separate paragraphs. 
 
There is a set of DocStrip primitives. Other common macros are defined in a format file. Some primitives expand their arguments using a limited subset of primitives. User-defined macros are expanded with arguments textually substituted, and the result of expansion is then re-examined. 
 
If a primitive itself is expanded in arguments, it is indicated with a plus after an argument list. If a primitive swallows spaces even after arguments, it is indicated with a 
@. 
SYNOPSIS
docstrip -mode=[user|dev[eloper]] -type=[man|plain|html] -options=global-opts -verbose 
-quiet -format=fmt-file-name -docpath=add-doc-path -docfmt=self-doc-file -define=macro-name[=value] 
-dir[ectory]=cur-dir -outdir=output-dir debug [infilename [outfilename]] 
If no input filename is given, stdin is assumed; if no output filename is given, stdout is assumed 
GENERAL STRUCTURE
DocStrip input is embedded into a source file inside comments. It support both C and C++ style comments as well as traditional shell hash comments. DocStrip block starts with 
///, /*** or ###. The block ends at the first non-comment line or at enclosing */. Comment-introducing characters, asterisks and spaces at line beginnings are swallowed. Non-empty lines are joined together. Line continuations (aka 
\) are recognized. 
SPECIAL CHARACTERS
Some characters and character sequences are treated specially by DocStrip backends They include: 
PRIMITIVES
Macro arguments are given in the line below its name. Each argument name is enclosed in brackets. Arguments which should not be empty are marked with an exclamation mark. Expandable arguments are marked with an asterisk. If a missing/empty argument is considered to have some default value, it is given after 
 sign. 
| NOTE: | DocStrip have some other primitives besides those listed below, but they are intended only for format-file developers and thence are undocumented here | 
Emits a hyper-reference whose user-visible part is description and which points to location. If a location is empty, it is guessed from the description. In particular, man page references in the form id(section) are recognized. A location may be either an URL or a anchor reference starting with #. In the former case, if a description is empty, it is considered equal to location. Otherwise, the result is backend-dependant. 
 
Sets an anchor to be refenced by href at the current point. If name is empty, a unique name is generated. 
 
Expands to the most recently defined anchor name (useful with generated names) 
 
Expands to a unique name suitable e. g. for anchor names 
 
This primitive takes the next input character as a delimiter and then treats all the following characters up to the next delimiter as ordinary. Special characters are not recognized within 
verbatim 
 
Sets a mark at the current point (not an anchor!) 
 
Defines a macro name with body. The macro will accept at most argcnt arguments. A body may contain argument references which are given as #number or #(number). Literal hash should be doubled. 
 
A name should not be defined. 
 
If doc-string is not empty and a self-documentation file is defined, doc-string is written to that file prepended by a macro name as a subsection. 
 
Redefines an alredy-defined macro to be body. Argument count remains the same. 
 
Undefines a macro name. If there is no such macro, does nothing. 
 
Like redefine, but expands body 
 
Expands to the body of a macro name or to an empty string if it is not defined No argument substitutions occur. 
 
Expands to body repeat count times. 
 
Starts a new paragraph 
 
Starts an indent block of text marked with label (if not empty). Sequential calls of indent are not cumulative 
 
Cancels indenting caused by indent 
 
Starts a list 
 
Starts a new list item (and a new list if there isn't one) possibly marking it with 
label. If there is no label, the marker is backend-specific, but usually a bullet will be used. 
 
Ends a list. A list is also ended by the end of the block. Some backends may end a list accepting 
indent or sectionig commands. 
 
Ends all the active lists. 
 
Sends opts to the current backend. Options are a set of semicolon-separated pairs keyword=value 
 
Starts a diversion, so that all the following output is kept at a special location. 
cmds are to be executed after the diversion end. Diversions cannot nest. 
 
Arranges cmds to be executed at the next flush (see flush) 
 
Arranges cmds to be executed after the end of each paragraph 
 
Ends the current diversion if their is one, and executes onflushed commands 
anchor
[name*] 
lastanchor
+ 
gensym 
+ 
verbatim
begin
+ 
define
[name!][body][argcnt][doc-string] @ 
redefine
[name][body] @ 
undefine
[name] 
let
[name][body*] @ 
bodyof
[name] + 
repeat
[count*][body] + 
par
indent
[label*] @ 
noindent
list
item
[label*] 
endlist
endlists
options
[opts] @ 
divert
[cmds!] @ 
onflush
[cmds] 
onpar
[cmds] 
flush
| NOTE: | An implicit flush occurs at the end of a block | 
Issues the content of a previously defined diversion 
 
Skips all the input until a matching else or endif if val1 != val2 
 
Same as if, but arguments are expanded 
 
Performs a numerical comparison on expanded strings num1 and num2. op may be ,  or . 
 
True if there was a text after the last begin or the start of the argument 
 
True if a macro name is defined 
 
True if there is a stored item in a table kind. 
 
True if the current output type is type 
 
True if in user doc mode 
 
True if in developer doc mode 
 
See if 
 
See if 
 
Includes a file name which is searched in the document path if doesn't start with `/', `./' or `../' 
 
Uses a file name as a new output file of the type, sending it options. The current output file is remembered unless the first char of name is `=' 
 
If type is empty, the current type is assumed. If name is empty, the output is switched to the previous output file; if there is no such file, nothing happens. If options start with `;', options passed on command line are prepended 
 
Issues a msg to stderr if not in quite mode 
 
Issues a msg to stderr if in verbose mode 
 
Extracts a C-like declaration from source following the end of the block and outputs it 
 
Like the previous, but operates on C statements 
 
Expands to the identifier caught by the last cdecl 
 
Expands to the name of the current input file 
 
Extracts up to cnt lines of source following the end of the block and outputs them. A line containing 
\end terminates extraction. If cnt is empty, an infinite maximal number is assumed. 
if
[val1][val2] @+ 
ifx 
[val1*][val2*] @+ 
ifnum
[op][num1][num2] @+ 
iftext
+ 
ifdef
[name] @+ 
ifkept
[kind][item*] @+ 
ifout
[type] @+ 
ifuser
+ 
ifdev
+ 
else
+ 
endif
+ 
include
[name] @ 
output
[type][name*][oprions*] 
echo
[msg] @ 
trace
[msg*] @ 
cdecl
cstmt
cdeclid
+ 
thisfile
+ 
source
[cnt] @ 
| NOTE: | The standard format file redefines this primitive so that it enforces developer mode | 
The source code that follows the block is treated as an array of string literals. Those are extracted and stored in a table kind
| BUG: | No escape sequences in literals are recognized | 
Stores a key associated with a property in a table. If a key has been already stored, the property is overwritten. 
 
Like the previous, but expands its second argument 
 
Expands to all the records from a table whose keys start with a prefix. cmds are executed for each such record, substituting a given key for  
Expands to a property associated with a key in a table; or to an empty string if no such key is stored. 
 
Clears a table. If table is empty, clears all tables 
 
Expands to the sum of val1 and val2 
 
Expands to the integral quotient of val1 and val2 
 
Expands to the length of expanded val 
 
Expands to numth Latin lower-case letter 
 
Expands to numth Latin upper-case letter 
 
Expands to an opaque number representation suitable for correct sorting 
 
Converts that opaque representation back to arabic digits 
 
Issues the current date 
 
Issues a character with ASCII code sym 
 
a null primitive used to eat unnecessary spaces 
 
Executes cmd as a primitive even if it is shadowed by a macro 
 
Prevents its argument from expansion 
 
Marks the following doc as user's 
 
Marks the following doc as developer's 
 
Marks the following doc as ambivalent 
 
Restores the user/developer mode before the last user, dev or any 
 
Writes self-doc into a self-documentation file if it is defined; otherwise does nothing 
 
Starts a new section 
 
Starts a new subsection 
 
Starts a new paragraph 
 
All the three commands puts a number before header if a corresponding level \numbering[1-3] is defined. \section and \subsection headers are always put into the table of contents, but 
\paragraph – only if \toc3 is defined 
 
Makes an index entry 
 
Makes a cross-reference for an index entry 
 
Issues an index contents without section references 
 
Issues an index contents with section references 
 
Emphasizes its argument 
 
Strongly hilites its argument 
 
Marks its argument as a sample 
 
Marks its argument as a variable name 
 
Marks its argument as a piece of code 
 
Renders its argument invisible 
 
Defines a copyright notice 
 
Defines the author's name. This command should go before any output-generating commands 
set
[table][key*][property*] 
insertall
[table][cmds][sep-cmds][prefix*] @+ 
%key; and its property for %prop;. Literal % should be typed twice inside cmds. sep-cmds are inserted between records (there is no substitutions here) 
insert
[table][key*] + 
zap
[table] @ 
add
[val1*][val2*] + 
divide
[val1*][val2*] + 
length
[val*] + 
alpha
[num*] + 
Alpha
[num*] + 
number
[val*] + 
unnumber
[num*] + 
date
symbol
[sym] + 
eat
builtin
[cmd] 
protect
[arg] + 
user
dev
any
restore
fmtdoc
[self-doc] @ 
STANDARD FORMAT MACROS
There are some shorthands for primitives defined: 
Internal-use macros are not documented here, as well as some DocStrip 1 compatibility macros. 
comment
Skips its argument. May be written as \% too 
space
Issues a space if there was a text after the last mark 
incr
Increments a macro body by 1 
section
[header] 
subsection
[header] 
paragraph
[header] 
*
[index][entry] 
see
[index][entry]
plainindexof
[index] 
indexof
[index] 
em
[arg] 
strong
[arg] 
sample
[arg] 
var
[arg] 
code
[arg] 
type
[arg] Marks its argument as a type name 
watermark
[arg] 
copyright
[notice] 
author
[name] 
bug
With no arguments, just marks the following text as a bug. If given two arguments, in addition, stores a bug record ##1 with a short description ##2 
note
Marks the following text as a note 
tip
Marks the following text as a tip 
error
Marks its argument as an error message 
todo
Stores its argument as a TODO-item. An optional second argument denotes priority (5 by default) 
readme
Stores a README file chunk 
returns
Mark the following text as a return value description 
ref
Like href, but in addition stores its argument in the see-also list. 
| NOTE: | It takes the only argument | 
| BUG: | Macro descriptions are too short |