\chyph

\hsize=11cm \vsize=16cm
\parindent=1.5em

\emergencystretch=2em

\widowpenalty=10000
\clubpenalty=10000

\raggedbottom

\font\bbf=csbx12
\font\smalltt=cstt8
\font\smallrm=csr8

\hyphenation{docby}

\newcount\secnum

\def\sec #1\par {\removelastskip\bigskip
\advance\secnum by1\noindent\hbox to\parindent{\bbf\hss\the\secnum.\hss}%
   {\bbf #1}\par\nobreak\medskip}

\def\title #1\par {\centerline{\bbf #1}\medskip}
\def\author #1\par {\centerline{\it #1}\medskip}

\def\abstract #1\par{\bgroup \smallrm \baselineskip=10pt 
   \leftskip=\parindent \rightskip=\parindent
   \noindent #1\par \egroup}

\def\url#1{{\tt#1}}

%% \begtt, \endtt

\def\begtt{\medskip\bgroup
   \nobreak\setverb \parskip=0pt %\parindent=0pt
   \def\par{\endgraf\penalty200\leavevmode}
   \baselineskip=10pt
   \obeylines \obeyspaces
   \startverb}
{\catcode`\|=0 \catcode`\\=12
  |gdef|startverb#1\endtt{%
        |smalltt#1|nobreak|egroup|penalty0|vskip-3pt|relax|scannexttoken}}
\long\def\scannexttoken#1{\ifx#1\par\else\noindent#1\fi}
\def\setverb{\def\do##1{\catcode`##1=12}\dospecials}

\def\begitems{\medskip}
\def\enditems{\par\medskip}
\def\item{\par\noindent\hbox to\parindent{\hss$\bullet$\hss}%
  \hangindent=\parindent \hangafter=1\relax}

\let\cmd=\uv

\title DocBy.\TeX{} -- dokumentování zdrojových textů \TeX{}em

\author Petr Olšák

\abstract 
DocBy.\TeX{} je makro \TeX{}u, které umožní jednoduše
dokumentovat zdrojové texty v programovacích jazycích, například v
jazyku~C. Obsahuje možnost vkládání vymezených úseků zdrojových textů
a díky enc\TeX{}u umí automaticky zvýraznit dokumentovaná slova 
v~těchto textech a udělat z nich aktivní odkazy. Automaticky vytváří
obsah a rejstřík. K vytvoření cílové dokumentace v PDF formátu je
potřeba pouze pdf\TeX{} doplněný enc\TeX{}em. Není nutné použít žádné
preprocesory.

\sec Úvod, motivace, zadání

Můj syn Mirek píše ročníkovou práci z programování a je zřejmé, že
pokud to bude chtít odevzdat, měl by své zdrojové kódy nějak
dokumentovat. Nabídl jsem se mu, že mu pro tyto účely napíšu \TeX{}ové
udělátko. Snažil jsem se splnit následující cíle

\begitems
\item Formát dokumentace je klikací PDF. Dokumentaci ve formátu html
  negenerujeme. 
\item Věc by měla být co nejjednodušší, tj. pokud možno jen
  použití \TeX{}u. Případné preprocesory by práci zbytečně
  komplikovaly.
\item K napsanému zdrojovému kódu se může psát dokumentace zvlášť
  do \uv{vedlejšího} \TeX{}ového souboru, v němž budou příkazy na
  vkládání vymezených úseků zdrojového kódu podle potřeby. Kód bude
  tedy vložen v době zpracování dokumentace \TeX{}em aktuální. 
  Tj. přesně ten, který načítá kompilátor při překladu programu.
\item Zdrojový kód je členěn do modulů. Kompilátor je překládá do objektů
  {\tt *.o} a ty pak sestavuje do výsledného programu. Jeden modul z
  pohledu programátora řeší jeden ucelený problém a stojí za to jej
  dokumentovat jako \uv{samostatnou jednotku}. \TeX{}ové soubory 
  s dokumentací tedy respektují strukturu členění na moduly.
\item Pomocí enc\TeX{}u je možné zařídit, že libovolný výskyt
  dokumentovaného slova v začleněném zdrojovém kódu se stane
  automaticky aktivním odkazem na místo, kde je slovo
  dokumentováno. Dokumentovaným slovem může být funkce, struktura,
  proměnná nebo cokoli jiného.
\item DocBy.\TeX{} sám vytvoří pod čarou na stránce, kde je slovo
  dokumentováno, seznam všech stránek, kde se slovo vyskytuje napříč
  celou dokumentací. Podobné seznamy stránek vznikají v rejstříku.
\item Rejstřík vzniká ze všech dokumentovaných slov zcela automaticky
  uvnitř \TeX{}u. Tj. bylo potřeba implementovat makrojazykem \TeX{}u
  abecední třídění.
\item Členění na sekce a podsekce a automatické vytvoření obsahu,
  který je klikací, je samozřejmostí.
\item Věc funguje v csplainu, protože já i syn používáme tento formát.
\enditems

Přiznám se bez mučení, že možnosti současných nástrojů na
dokumentování zdrojových kódů jsem moc nestudoval. Je tedy možné, že 
v~některých aspektech znovu vynalézám kolo a že některé vlastnosti,
které se běžně při dokumentování používají, chybí. Je to
taková \uv{rodinná} zakázka na míru programu, který syn odevzdává jako
ročníkovou práci. Nicméně jsem se snažil nástroj udělat aspoň trochu
obecně použitelný a dovolím si jej na konferenci \TeX{}perience 2008
předvést. Posluchači sami posoudí, zda jim to může být k něčemu
dobré. Obecnou použitelnost deklaruji například tím, že dokumentaci k
DocBy.\TeX{}u (včetně technické dokumentace s~rozborem všech maker)
píšu v DocBy.\TeX{}u.

Zvažoval jsem aspoň na vteřinu doporučit synovi literární
programování, jak jej vytvořil Donald Knuth (tzv. WEB). Ovšem, velmi rychle
jsem od toho upustil. Domnívám se, že doba, kdy Knuth vytvářel své
dílo, byla poznamenána poněkud jinými počítači, než jaké máme před
sebou dnes. Dnes je běžné grafické rozhraní, ve kterém je možné
současně otevřít více editorů vedle sebe v různých oknech s různými
texty.  V jednom třeba může být text určený pro počítač a v druhém
text, který je určen pro člověka. Vše je vidět naráz, jak může vidět i
čtenář tohoto článku na obrázku~1. Není tedy nutné tyto informace
slučovat do jediného souboru, aby byly blízko sebe, a poté je
preprocesory (tangle, weave) zase oddělovat. Dnešní programátoři také
obvykle přemýšlejí v~intencích, jak kód zpracovává kompilátor. Trhání
tohoto kódu na úseky (jako v Knuthově WEBu) asi moc nemilují.

Poznamenávám ještě, že jsem Knuthův WEB nezavrhl z neznalosti. Sám jej
velmi dobře znám. Vrtal jsem se poměrně do hloubky ve zdrojových
kódech \TeX{}u a také jsem napsal jednoduchoučký program vlna v CWEBu.
Synův program je ovšem asi stokrát složitější než program vlna,
takže rozhodování o CWEBu ani moc dlouho netrvalo. CWEB jsme nepoužili.

Protože syn bude odevzdávat svou ročníkovou práci až v lednu roku
2009, nečekejte nyní hotové dílo. Jeho program je ve stádiu zrodu a
DocBy.\TeX{} se také zatím vyvíjí podle požadavků programátora. 
V~době, kdy se snažím aspoň částečně dodržet termín odevzdání tohoto
příspěvku (srpen 2008) tedy není DocBy.\TeX{} ve stádiu, kdy bych jej
mohl zveřejnit na internetu. Ani ukázek zatím moc není. Syn má
naprogramováno v tuto chvíli asi 20 modulů svého programu a bude
přidávat ještě mnoho dalších. Dokumentovány DocBy.\TeX{}em má moduly
dva. Na obrázcích 2, 3 můžete posoudit, jak vypadá současná verze
dokumentace jeho programu. Na obrázku 4 pak vidíte stránku z dokumentace
samotného DocBy.\TeX{}u.

Až DocBy\TeX{} dospěje do nějaké rozumně stabilní verze, najdete jej
na internetu na \url{http://www.olsak.net/docbytex.html}.

\sec Příklad použití DocBy.\TeX{}u

Předpokládá se, že program je členěn na moduly. Každý modul obsahuje
skupinu funkcí, která řeší jeden ucelený problém. Předpokládejme
teoretický program {\tt lup}, který má tři moduly: main v souboru 
{\tt main.c}, win v souborech {\tt win.c} a {\tt win.h} a konečně
modul base v souborech {\tt base.h} a {\tt base c}. Dokumentace k
takovému programu vznikne tak, že autor napíše hlavní \TeX{}ový soubor
(například {\tt lup.tex}) a z něj bude číst další \TeX{}ové soubory,
které obsahují dokumentaci k jednotlivým modulům: {\tt main.d},
{\tt win.d} a {\tt base.d}. V {\tt lup.tex} může být nějaký rozverný
úvod a dále příkazem \cmd{\tt\char`\\module} jsou načítány jednotlivé
dokumentační soubory k modulům. V těchto souborech se autor dokumentace
soustředí na problém řešený v daném modulu (něco jako sekce v Knuthově
WEBu) a postupně vkládá do dokumentace vymezené úseky kódu ze souborů
{\tt *.c} a {\tt *.h} pomocí příkazu \cmd{\tt\char`\\ins}. Dokumentovaná
slova vymezuje příkazem \cmd{\tt\char`\\dg} (dokumentace globálního slova). 
Vztah mezi jednotlivými soubory při načítání kompilátorem a při
načítání \TeX{}em je naznačen na obrázku~5.

Obsah souboru {\tt lup.tex} může vypadat třeba takto:

\begtt
\input docby.tex

\title   Program lup -- dokumentace ke zdrojovým textům

\author  Progr a Mátor

\dotoc  % tady bude obsah

\sec Členění zdrojových textů

Zdrojové texty programu "lup" jsou rozděleny do tří modulů. 
V "base.c" jsou definovány pomocné funkce a v "base.h" jsou 
jejich prototypy. Podobně ve "win.c" jsou funkce pro okenní 
záležitosti a "win.h" obsahuje jejich prototypy. Konečně 
"main.c" obsahuje hlavní funkci programu.

\module base
\module win
\module main
\doindex  % v tomto místě bude sestaven rejstřík
\end
\endtt

V tomto příkladě jsme se rozhodli čtenáře dokumentace seznamovat s
programem \uv{zdola nahoru}, tedy od elementárních funkcí až k hotovému
programu. Někdo možná preferuje cestu \uv{shora dolů} a může mít v
dokumentaci na konci souboru {\tt lup.tex} třeba napsáno:

\begtt
\module main
\module win
\module base
\doindex
\end
\endtt

Oba přístupy jsou možné, protože dokumentace je automaticky provázána
hyperlinky. Čtenář se kdykoli může podívat na dokumentaci té funkce,
jejíž použití zrovna čte, a obráceně může projít výskyty veškerého
použití funkce, když čte její dokumentaci.

Podívejme se nyní podrobněji například do souboru {\tt base.d}, kde je
soustředěna dokumentace modulu base. Část tohoto souboru může vypadat
třeba takto:

\begtt
Struktura \dg dvojice se používá jako návratová hodnota funkce
"uzasna_funkce" a sdružuje dvě hodnoty typu "float".
\ins c dvojice

Funkce \dg [struct dvojice]uzasna_funkce() si vezme jeden parametr 
"p" a vrátí ve struktuře "dvojice" dvojnásobek a trojnásobek 
tohoto parametru. 
\ins c uzasna_funkce
\endtt

Příkazem \cmd{\tt\char`\\ins c dvojice} jsme dali najevo, že potřebujeme
ze souboru se stejným jménem jako je aktuální název modulu (tj. base)
a s~příponou {\tt.c} přečíst část kódu, který obsahuje deklaraci zmíněné
struktury. Pro vymezení částí z načítaného souboru je potřeba do
zdrojového kódu vložit vymezující poznámky tvaru
{\tt//:~slovo}. Příklad části kódu ze souboru {\tt base.c} vše
osvětlí:

\begtt
#include <stdio.h>

//: dvojice

struct dvojice {
  float x, y;
};

//: uzasna_funkce

struct dvojice uzasna_funkce (float p)
{
  struct dvojice navrat;
  navrat.x = 2*p; // tady nasobim p dvema
  navrat.y = 3*p; // tady nasobim p tremi
  return navrat;
} 
\endtt

Příkaz \cmd{\tt\char`\\ins c slovo} tedy načte část kódu od vymezující
poznámky tvaru {\tt//:~slovo} po výskyt poznámky tvaru {\tt//:} nebo až
po konec souboru. Do zdrojového kódu je tedy potřeba vložit vymezující
poznámky. 

Na pořadí úseků, které zahrnujeme ze zdrojového textu do dokumentace,
nezáleží. Klidně jsme mohli dokumentaci začít od povídání o~úžasné
funkci (včetně vložení jejího kódu) a potom ještě dopsat, co to je ta 
struktura {\tt dvojice} a následně vložit deklaraci této struktury.

Na obrázku~6 je vidět zhruba výsledek zpracování našeho příkladu
DocBy.\TeX{}em (první stránka). Níže sice píšu \uv{všimněte
si}, \uv{za povšimnutí stojí} atd., ovšem je to potřeba brát s rezervou. Je
možné, že tisk obrázku~6 bude jen černobílý a pravděpodobně dost
zmenšený. Omlouvám se tedy preventivně čtenáři, pokud ho nutím, aby si
všiml, že něco zmodralo nebo zezelenalo, když asi obrázek~6 mu tuto
informaci jednoznačně neposkytne.

Všimněme si, že \TeX{} zapsal čísla řádků přesně podle toho, jak jsou
ve zdrojovém kódu. Tj. počítal i přeskakovaný řádek
{\tt\#include~<stdio.h>} i přeskakované prázdné a vymezující řádky.
Komentářový řádek s~vymezením {\tt//:~slovo} není do dokumentace zahrnut a pokud
následuje za řádkem s~vymezením prázdný řádek, ani ten není do
dokumentace zahrnut. 

Za povšimnutí stojí použití příkazu \cmd{\tt\char`\\dg}. Za
ním následuje slovo (separované mezerou), které dokumentujeme. Toto
slovo se v dokumentaci výrazně označí (v PDF verzi červenou barvou
navíc v barevném rámečku) a jakýkoli jiný výskyt takového slova ve
zdrojovém textu nebo mezi uvozovkami {\tt\char`\"...\char`\"} bude
automaticky označen modrou barvou a bude klikací. Kliknutí na modrý
výskyt slova kdekoli v dokumentaci vrátí čtenáře na červený výskyt,
kde je slovo dokumentováno.

Všechny Céčkové komentáře ve vloženém zdrojovém kódu automaticky zezelenaly.

Palcové uvozovky {\tt\char`\"...\char`\"} vymezují kusy kódu
uvnitř odstavce. Text takto uvozený je psán strojopisem a pokud se 
v něm vyskytují dokumentovaná slova, tato slova automaticky modrají.
Text mezi těmito uvozovkami je navíc přepisován ve \uv{verbatim}
módu \TeX{}u, tj. žádné znaky nemají speciální vlastnosti (s výjimkou
koncové palcové uvozovky).

Na stránce, kde je slovo dokumentováno (pomocí \cmd{\tt\char`\\dg}), je
v poznámkách pod čarou slovo znovu zmíněno a vedle této zmínky je
seznam všech stránek, na kterých se kdekoli v textu vyskytuje použití
tohoto slova.  Dále jsou všechna dokumentovaná slova zahrnuta do
závěrečného abecedního rejstříku, který odkazuje jednak na stránku,
kde je slovo dokumentováno, i na stránky se všemi výskyty slova.

Pozorný čtenář si jistě všiml, že v poznámce pod čarou a v rejstříku
je {\tt uzasna\_funkce} zmíněna včetně jejího návratového typu a navíc je
slovo ukončeno dvojicí závorek {\tt()} a tím je naznačeno, že se jedná
o~funkci. Je to díky zápisu
\cmd{\tt\char`\\dg~[struct~dvojice]uzasna\_funkce()} v~místě dokumentace
funkce. Nepovinný parametr s návratovou hodnotou funkce se přepíše
před jméno funkce pod čáru i do rejstříku, ale rejstřík při abecedním
řazení tento parametr ignoruje.

\sec Další možnosti

DocBy.\TeX{} umožňuje vyznačit vkládané úseky kódu dalšími způsoby: je
možné kontrolovat, zda se vloží nebo nevloží vymezující řádky, nebo
jen vymezující řádek na jedné straně, je možné navazovat vkládáním od
místa, kde vkládání naposledy skončilo, je možné vložit prototyp
funkce, je možné vkládat od libovolně vymezeného místa ve zdrojovém
kódu do dalšího vymezeného místa (není tedy nutné vymezovat text jen
výše uvedenými poznámkami), je možné vložit jediný řádek s prvním
výskytem slova nebo s dalším výskytem slova od místa posledního
vložení.

Je možné nastavit jiné vzory, podle kterých zelenají ve vložených
souborech komentáře. Implicitně DocBy.\TeX{} považuje za komentář úsek
od {\tt//} do konce řádku a úsek mezi {\tt/*...*/}.

V DocBy.\TeX{}u může autor dokumentace založit sekce a subsekce,
přitom implicitně příkaz \cmd{\tt\char`\\module} založí novou sekci.
Je možné odkazovat pomocí lejblíků na sekce, subsekce.
Je možné vkládat obrázky a odkazovat na ně. 

DocBy\TeX{} implementuje jmenné prostory, takže je možné dokumentovat
slovo lokálně v rámci úseku dokumentace, která vymezuje určitý jmenný
prostor. Nastavení jmenných prostorů je poměrně flexibilní a umožňuje
na lokálně dokumentované slovo odkazovat globálně při dlouhém výpisu
slova včetně specifikace jmenného prostoru.

DocBy.\TeX{} rozlišuje mezi PDF a DVI módem, dále mezi enc a non-enc
módem a konečně mezi csplain a plain módem.

Pro zpracování dokumentace je ideální použít pdf\TeX{} s aktivovaným
výstupem do PDF (tj. PDF mód) a s enc\TeX{}em (tj. enc mód)  
a s formátem csplain nebo plain (tj. csplain nebo plain mód).
V~takovém případě fungují barvy, odkazy i automatické tvoření
aktivních odkazů ve vkládaném zdrojovém textu.

Není-li aktivován PDF výstup, DocBy.\TeX{} o tom napíše varování na
terminál a přejde do DVI módu. V tomto módu nefungují barvy a odkazy
nejsou klikací.

Není-li aktivován enc\TeX{}, DocBy.\TeX{} přejde do non-enc módu a
napíše o tom varování na terminál. V takovém případě dokumentovaná
slova ve vkládaném zdrojovém textu automaticky nemodrají a nestávají
se klikatelnými odkazy. Ani se jejich výskyty neuvádějí na správných
stránkách v rejstříku a v poznámkách pod čarou. Taktéž komentáře
automaticky nezelenají.

Při csplain módu generuje DocBy.\TeX{} některé názvy česky. Jedná se
o název kapitoly s obsahem, rejstříkem a modulem. V plain módu jsou
tyto názvy anglicky. Pracujete-li s jiným jazykem, můžete předefinovat
odpovídající makra.

Generování rejstříku i obsahu probíhá v DocBy.\TeX{}u zcela
automaticky. Pro vytvoření rejstříku není nutné používat externí
program (DocBy.\TeX{} si slova abecedně zatřídí sám).  Stačí tedy
vložit na požadovaná místa příkazy \cmd{\tt\char`\\dotoc} a
\cmd{\tt\char`\\doindex}. Rejstřík ani obsah nejsou správně vygenerovány po
prvním průchodu \TeX{}u. Je potřeba \TeX{}ovat dvakrát nebo třikrát.
Pro generování obsahu i rejstříku si DocBy.\TeX{}
zakládá pomocný soubor s příponou {\tt.ref}, v našem příkladě tedy
{\tt lup.ref}.

\bigskip

\abstract
DocBy.\TeX{} is a \TeX{} macro which gives you possibility to
simply document your source codes written in various programming
languages, for instance written in C. You can include parts of your
source code into your documentation. All occurrences of documented
words in your included source code are automatically made as active
links if enc\TeX{} and pdf\TeX{} is in progress. To make PDF output,
you needn't no more than pdf\TeX{} with enc\TeX.  The table of
contents and the index are created automatically too.  The sorting of
words in the index is implemented at \TeX{} macro level.

\end

\pic [plocha] {Obrázek 1. Pracovní plocha s více editory}

\pic [mireka] {Obrázek 2. Ukázka z Mirkovy dokumentace, modul hash}

\pic [mirekb] {Obrázek 3. Ukázka z Mirkovy dokumentace, rejstřík}

\pic [docdoc] {Obrázek 4. Úvodní strana dokumentace k DocBy.\TeX{}u}

\pic [vztahy] {Obrázek 5. Vztahy mezi zdrojovými soubory}

\pic [lupkuk] {Obrázek 6. Ukázka ukázkového výstupu}

