The Manpage mini-HOWTO <author>Jens Schweikhardt, <htmlurl url="mailto:schweikh@noc.dfn.de" name="schweikh@noc.dfn.de"><newline> <date>v2.3, kwiecień 1996 <bf>Wersja polska: Gwidon S. Naskrent <htmlurl url="mailto:naskrent@hoth.amu.edu.pl" name="naskrent@hoth.amu.edu.pl"><newline> </bf> v1.0, wrzesień 1997 <abstract>To HOWTO objaśnia to o czym powinieneś pamiętać zabierając się do pisania dokumentacji w postaci elektronicznej - tak zwanej manpage [manual page, tj. strona podręcznika] - którą chcesz udostępnić poprzez komendę man(1). Dokument ten został napisany w standardzie ISO-8859-2. Oryginał tego dokumentu znajduje się pod adresem <htmlurl url="ftp.icm.edu.pl/pub/Linux/sunsite/docs/HOWTO/"> </abstract> Copyright 1995,96 Jens Schweikhardt <schweikh@noc.dfn.de> Dalsze informacje o warunkach kopiowania - patrz niżej Uprasza się o poprawki i sugestie! W tym HOWTO, o "kartce" podręcznika mówi się po prostu manpage, niezależnie od faktycznej długości. [Od tłumacza: użyłem nietłumaczonego terminu "manpage" aby nie plątać się w skomplikowane eufemizmy typu "strona podręcznika man", co nie jest ani wygodne, ani nie służy stylowi. W niektórych jednak miejscach mówię o niej, za autorem, po prostu "strona"] <toc> <sect>0) Kilka uwag o dokumentacji<p> Po co pisze się dokumentację? Głupie pytanie? Ponieważ chcemy aby inni mogli używać naszego programu, funkcji bibliotecznej czy czegokolwiek cośmy napisali i udostępnili. Ale napisanie dokumentacji to nie wszystko: <itemize> <item>dokumentacja musi być dostępna. Jeśli schowano ją w jakimś niestandardowym miejscu gdzie nie znajdą jej odpowiednie narzędzia - jak może służyć swoim celom? <item>dokumentacja musi być godna zaufania i dokładna. Nie ma nic bardziej denerwującego niż niezgoda zachowania się programu i dokumentacji. Użytkownicy będą cię przeklinać, posyłać ci hate-maile i wrzucą twoje dzieło do kosza na bity, z mocnym postanowieniem nieinstalowania więcej czegokolwiek napisanego przez tego kretyna. </itemize> Historycznym i dobrze znanym sposobem dokumentację na UNIXie uzyskuje się komendą man(1). To HOWTO opisuje co musisz zrobić aby napisać manpage którą prawidłowo przetworzą narzędzia zajmujące się dokumentacją. Najważniejszymi z tych narzędzi są man(1), xman(1x), apropos(1), makewhatis(8) oraz catman(8). Niezawodność i dokładność informacji zależą, oczywiście, od ciebie. Ale nawet w tym względzie znajdziesz poniżej pomysły które pomogą ci uniknąć pewnych częstych potknięć. <sect>1) Jak udostępniane są manpages?<p> Musisz znać dokładny mechanizm udostępniania manpages aby nadać swojej manpage właściwą nazwę i zainstalować ją we właściwym miejscu. Każda manpage należy do konkretnej sekcji, którą oznaczona jest pojedynczym znakiem. Najbardziej popularne sekcje w Linuxie i ich tłumaczone na ludzki nazwy to: <verb> Sekcja Tłumaczenie na ludzki 1 Komendy użytkownika, uruchamialne przez wszystkich 2 Wywołania systemowe, to jest, funkcje udostępniane przez jądro 3 Podprogramy, to jest, funkcje biblioteczne 4 Urządzenia, to jest, specjalne pliki w katalogu /dev 5 Opisy formatów plików, np. /etc/passwd 6 Gry, mówi samo za siebie 7 Różne, np. pakiety makr, konwencje [np. iso-8859-1, Unicode - dop. tłum.] 8 Narzędzia do zarządzania systemem, których używać może tylko administrator 9 Jeszcze jedno miejsce na dokumentację procedur jądra (specyficzne dla Linuxa) n Nowa dokumentacja którą przenieść można do odpowiedniejszej sekcji o Stara dokumetacja, utrzymywana przez okres próbny l Dokumentacja lokalna, odnosząca się do tego szczególnego systemu </verb> Nazwą pliku źródłowego dla manpage (daną wejściową systemu formatującego) jest nazwa komendy, funkcji lub pliku, plus kropka, plus numer sekcji. Jeśli piszesz dokumentację na temat formatu pliku "passwd", musisz nazwać plik źródłowy "passwd.5". Mamy tu też przykład nazwy pliku takiej samej jak nazwa komendy. Może też istnieć podprogram biblioteczny zwany passwd. Podział na sekcje jest zwyczajowym sposobem rozwiązania tych niejasności; opis komendy znajduje się w pliku "passwd.1" a hipotetycznego podprogramu bibliotecznego w "passwd.3" Czasami do nazwy dołączone są dodatkowe znaki, wygląda więc ona np. jak "xterm.1x" lub "wish.1tk". Zamiarem jest zaznaczenie że jest to dokumentacja dla programu Xowego lub aplikacji Tk, odpowiednio. Niektóre przeglądarki manpages potrafią wykorzystać tą dodatkową informację. Na przykład xman użyje "xterm(x)" i "wish(tk)" w liście dostępnej dokumentacji. Proszę nie używać sekcji n, o oraz l; zgodnie z File System Standard (FSS) sekcje te straciły wartość. Trzymaj się sekcji oznaczonych numerami. Uważaj na kolizje nazw z istniejącymi programami, funkcjami i nazwami plików. Na pewno złym pomysłem jest napisanie jeszcze jednego edytora i nazwanie go <tt/ed/, <tt/sed/ (smart ed) czy <tt/red/ (Rocky's ed). Upewniwszy się że nazwa twojego programu jest jedyna w swoim rodzaju unikasz sytuacji w której ktoś wykona twój program i przeczyta czyjąś inną manpage, lub odwrotnie. Zacząć można od sprawdzenia bazy danych lsm z nazwą programu. Teraz znamy już nazwę którą nadamy naszemu plikowi. Następna decyzja to to w jakim katalogu zostanie on w końcu zainstalowany (powiedzmy gdy użytkownik wykona "<tt/make install/" dla twojego pakietu). W Linuxie wszystkie manpages znajdują się poniżej katalogów wymienionych w zmiennej środowiskowej <tt/MANPATH/. Narzędzia dokumentacyjne używają jej w całkiem podobny sposób jak powłoka używa <tt/PATH/ do znalezienia programów wykonywalnych. W rzeczy samej, <tt/MANPATH/ ma ten sam format co <tt/PATH/. Obie zawierają rozdzieloną dwukropkami listę katalogów (z tym wyjątkiem że <tt/MANPATH/ nie pozwala na puste pola i ścieżki względne, ale tylko nazwy absolutne). Jeśli <tt/MANPATH/ nie została ustawiona lub wyeksportowana, użyta zostanie wartość domyślna, która zawiera co najmniej katalog <tt>/usr/man</tt>. By przyspieszyć szukanie i ograniczyć rozmiar katalogów katalogi wyspecyfikowane przez <tt/MANPATH/ zawierają szereg podkatalogów o nazwach "<tt/man(s)/" gdzie <tt/(s)/ oznacza jeden znak sekcji, jak w tabeli powyżej. Nie wszystkie sekcje muszą być reprezentowane przez podkatalog, ponieważ po prostu nie ma powodu utrzymywania pustego podkatalogu <tt>../mano</tt>. Mogą jednak istnieć podkatalogi zwane "cat(s)", "dvi(s)" i "ps(s)" [(s) i tutaj oznacza znak sekcji], które zawierają dokumentację gotową do obejrzenia/wydrukowania. Jedynym innym plikiem w katalogu bazowym powinien być plik o nazwie whatis. (jego cel i metoda tworzenia zostanie opisana również w par. 11). Najbezpieczniejszą metodą zainstalowania manpage z sekcji (s) we właściwym miejscu jest wsadzenie jej do katalogu <tt>/usr/man/man(s)</tt>. Dobry <tt/Makefile/ jednak pozwoli wybrać użytkownikowi katalog bazowy za pomocą zmiennej w <tt/make/, powiedzmy <tt/MANDIR/. Większość pakietów GNU skonfigurować można opcją <tt>--prefix=/cos/tam</tt>. Strony podręcznika zostaną wtedy zainstalowane pod katalogiem bazowym <tt>/cos/tam/man</tt>. Sugeruję żebyś również stworzył jakiś sposób na zrobienie czegoś podobnego. Z nadejściem linuxowego File System Standard (FSS) sprawy nieco się skomplikowały. FSS 1.2 zaznacza że "należy przygotować strukturę <tt>/usr/man</tt> do obsługi stron podręcznika które napisane są w innym (lub różnych) językach". Osiąga się to wprowadzając jeszcze jeden poziom katalogów, który rozróżnia między rozmaitymi językami. Ponownie cytując FSS 1.2: "To nazywanie podkatalogów językowych <tt>/usr/man</tt> opiera się na Dodatku E standardu POSIX 1003.1, który opisuje ciąg znaków identyfikujący locale - najbardziej akceptowaną metodę opisywania środowiska kulturowego. Ciąg <locale> to: <verb><język>[_<terytorium>][.<zestaw_znaków>][,<wersja>]"</verb> (Patrz FSS co do kilku popularnych ciągów <locale>). Zgodnie z tymi wytycznymi mamy nasze manpages w <tt>/usr/man/<locale>/man[1-9lno]</tt>. Sformatowane wersje powinny więc oczywiście znajdować się w <tt>/usr/man/<locale>/cat[1-9lno]</tt>, w przeciwnym razie dostawalibyśmy je tylko dla jednego locale. JEDNAKŻE nie mogę polecić przestawienia się na tą strukturę w obecnym czasie. FSS 1.2 zezwala również na to aby "systemy które używają jednego języka i zestawu znaków dla wszystkich manpages mogą pominąć podciąg <locale> i trzymać wszystkie manpages w <mandir>. Na przykład systemy które używają tylko angielskich manpages kodowanych w ASCII mogą trzymać je (katalogi <tt/man[1-9lno]/) bezpośrednio w <tt>/usr/man</tt> (taki jest w rzeczy samej tradycyjny układ)". Nie przestawiłbym się dopóki wszystkie narzędzia (jak <tt/xman/, <tt/tkman/, <tt/info/ i wiele innych które odczytują manpages) nie będą potrafiły sobie radzić z nową strukturą. <sect>2) Jak powinna wyglądać sformatowana manpage?<p> Pozwól mi zaprezentować przykład. Poniżej objaśnię go szczegółówo. Ze względu na naturę tego dokumentu, nie mogę pokazać różnych krojów czcionki (pogrubionego i kursywy). Zobacz paragraf "Jakie są konwencje dotyczące czcionek?" co do dalszych wyjaśnień. Oto manpage dla (hipotetycznego) programu <tt/foo/ <verb> FOO(1) User Manuals FOO(1) NAME foo - frobnikuje bibliotekę bar SYNOPSIS <bf>foo [-bar] [-c</bf> <it>plik-konfiguracji</it> <bf/]/ <it/plik .../ DESCRIPTION <bf>foo</bf> frobnikuje bibliotekę bar poprzez upychanie wewnętrznych tablicy symboli. Domyślnie przetwarza to wszystkie segmenty baz i porządkuje je w odwrotnej kolejności według czasu po to aby mógł je odnaleźć linker xyzzy(1). Symdef jest następnie kompresowany z użyciem algorytmu WBG (Whiz-Bang- Gizmo). Wszystkie pliki przetwarzane są w podanej kolejności. OPTIONS <it>-b</it> Nie wypisuj sygnału zajętości na stdout podczas przetwarzania <it>-c plik-konfiguracyjny</it> Użyj alternatywnego całosystemowego pliku konfigura- cji, zamiast <tt>/etc/foo.conf</tt>. Unieważnia to jakąkolwiek zmienną środowiskową <tt/FOOCONF/. <it>-a</it> Oprócz segmentów baz, przetwórz również nagłówki blurfl. <it>-r</it> Tryb rekursywny. Pracuje z szybkością błyskawicy kosztem megabajta pamięci wirtualnej. FILES <it>/etc/foo.conf</it> Całosystemowy plik konfiguracyjny. Po szczegóły, patrz foo(5). <it>~/.foorc</it> Plik konfiguracji dla użytkownika. Po szczegóły, patrz foo(5). ENVIRONMENT <tt/FOOCONF/ Jeśli niepusta, pełna ścieżka alternatywnego całosys- temowego <tt/foo.conf/. Unieważniana opcją <it/-c/. DIAGNOSTICS Na stderr mogą zostać wysłane następujące komunikaty: <bf>Bad magic number</bf>. Plik wejściowy nie wygląda jak plik archiwum. <bf>Old style baz segments</bf>. foo może operować tylko na segmentach baz nowego stylu. Biblioteki obiektowe COBOLA nie są obsługiwane w tej wersji. BUGS Nazwa komendy powinna zostać wybrana bardziej dokładnie, tak aby odpowiadała jej przeznaczeniu. AUTHOR Jens Schweikhardt <jens@kssun3.rus.uni-stuttgart.de> SEE ALSO bar(1), foo(5), xyzzy(1) Linux Marzec 1995 1 </verb> Oto objaśnienie które obiecywałem: <bf> Sekcja NAME</bf> ...to jedyna wymagana sekcja. Manpages bez sekcji nazwowej są tak użyteczne jak lodówki na biegunie północnym. Sekcja ta ma także ustandardyzowany format, składający się z oddzielonej przecinkami listy programów lub nazw funkcji, plus myślnik, plus krótki (zwykle jednolinijkowy) opis jaki pożytek ten program (funkcja, plik) ma przynosić. Używając makewhatis(8) sekcje nazwowe złożyć można w plik bazy whatis. Makewhatis to powód dla którego sekcja nazwowa musi istnieć i stosować się do formatu który opisałem. W źródle <tt/groffa/ musi ona wyglądać tak: <verb> .SH NAME foo \- frobnikuje bibliotekę baz </verb> "\-" ma tu znaczenie. Ukośnik w prawo potrzebny jest do odrożnienia myślnika od myślnika interpunkcyjnego, który może się pojawić w nazwie komendy lub w jednolinijkowym opisie. <bf> Sekcja SYNOPSIS</bf> ...ma w zamiarze podać krótkie omówienie dostępnych opcji programu. Dla funkcji sekcja ta wylicza odpowiadające pliki włączeniowe i prototypy, tak aby programista znał typ i liczbę argumentów, jak również typ rezultatu. <bf> Sekcja DESCRIPTION</bf> ...podaje elokwentne wyjaśnienie dlaczego twoja sekwencja zer i jedynek jest w ogóle czegoś warta. Tutaj właśnie wypisujesz całą swoją wiedzę. Zdobądź podziw innych programistów i użytkowników czyniąc tą sekcję źródłem godnej zaufania i szczegółówej informacji. Wytłumacz do czego służą argumenty, format plików, jakie algorytmy wykonują całą brudną robotę. <bf> Sekcja OPTIONS</bf> ...podaje opis każdej opcji, i to jak wpływa ona na zachowanie się programu. Wiedziałeś o tym, prawda? <bf> Sekcja FILES</bf> ...wylicza pliki których używa program lub funkcja. Na przykład: pliki konfiguracyjne, startowe, pliki na których program operuje bezpośrednio. Dobrym pomysłem jest podanie pełnej ścieżki tych plików i zmuszenie procesu instalacji do zmodyfikowania części katalogowej ścieżki dostosowywując ją do preferencji użytkownika; podręczniki tworzone <tt/groff/ mają domyślny przedrostek <tt>/usr/local</tt>, tak więc odnoszą się domyślnie do <tt>/usr/local/lib/groff/*</tt>. Niemniej jeśli instalujesz program używając <tt>"make prefix=/opt/gnu"</tt> odniesienia na manpages zmienią się na <tt>/opt/gnu/lib/groff/*</tt> <bf> Sekcja ENVIRONMENT</bf> ...wylicza wszystkie zmienne środowiskowe które wpływają na twój program lub funkcję i mówi oczywiście w jaki sposób. Zmienne najczęściej zawierają ścieżki, nazwy plików lub domyślne opcje. <bf> Sekcja DIAGNOSTICS</bf> ...powinna podawać omówienie najczęstszych komunikatów o błędach twojego programu i tego jak sobie z nimi poradzić. Nie ma potrzeby tłumaczyć komunikatów o błędach systemowych (z perror(3)) czy sygnałów fatalnych (z psignal(3)), ponieważ mogą się one pojawić podczas wykonywania każdego programu. <bf> Sekcja BUGS</bf> ...idealnie powinna nie istnieć. Jeśli jesteś odważny, możesz tu opisać ograniczenia, znane niedogodności, funkcje programu które inni mogą uznać za nieudane. Jeśli nie jesteś tak odważny, przemianuj tą sekcję na TO DO :-) <bf> Sekcja AUTHOR</bf> ...miło ją mieć w razie gdy w dokumentacji lub zachowaniu się programu znajdują się poważne błędy, i chcesz wysłać raport o pluskwach. <bf> Sekcja SEE ALSO</bf> ...jest listą manpages odnoszących się do tego samego zagadnienia, w porządku alfabetycznym. Konwencjonalnie jest to sekcja ostatnia. Masz wolną rękę w wymyślaniu innych sekcji, jeśli rzeczywiście nie pasują one do jednej z dotychczas opisanych. [wszystkie powyższe sekcje z wyjątkiem NAME można przetłumaczyć na język polski; do zmiany NAME potrzebny byłby przerobiony <tt/makewhatis/ - przyp. tłum.] Jakże więc dokładnie stworzyłeś tą manpage? Spodziewałem się tego pytania, oto źródło: <verb> .\" Przetwórz ten plik używając .\" groff -man -Tascii foo.1 .\" .TH FOO 1 "MARCH 1995" Linux "User Manuals" .SH NAME foo \- frobnikuje bibliotekę bar .SH SYNOPSIS .B foo [-bar] [-c .I plik-konfiguracji .B ] .I plik .B ... .SH DESCRIPTION .B foo frobnikuje bibliotekę bar poprzez upychanie wewnętrznych tablic symboli. Domyślnie przetwarza to wszystkie segmenty baz i porządkuje je w odwrotnej kolejności według czasu po to aby mógł JE odnaleźć linker .BR xyzzy (1) Symdef jest następnie kompresowany z użyciem algorytmu WBG (Whiz-Bang-Gizmo). Wszystkie pliki przetwarzane są w podanej kolejności. .SH OPTIONS .IP -b Nie wypisuj sygnału zajętości na stdout podczas przetwarzania .IP "-c config-file" Użyj alternatywnego całosystemowego pliku konfiguracji zamiast .IR /etc/foo.conf . Unieważnia to jakąkolwiek zmienną środowiskową .B FOOCONF .IP -a Oprócz segmentów baz, przetwórz również nagłówki blurfl. .IP -r Tryb rekursywny. Pracuje z szybkością błyskawicy kosztem megabajta pamięci wirtualnej. .SH FILES .I /etc/foo.conf .RS Całosystemowy plik konfiguracyjny. Po szczegóły, patrz .BR foo (5) .RE .I ~/.foorc .RS Plik konfiguracji dla użytkownika. Po szczegóły, patrz .BR foo (5) for further details. .SH ENVIRONMENT .IP FOOCONF Jeśli niepusta, pełna ścieżka alternatywnego całosystemowego .IR foo.conf . Unieważniana opcją .B -c . .SH DIAGNOSTICS Na stderr mogą zostać wysłane następujące komunikaty: Bad magic number. .RS Plik wejściowy nie wygląda jak plik archiwum. .RE Old style baz segments. .RS .B foo może operować tylko na segmentach baz nowego stylu. Biblioteki obiektowe COBOLA nie są obsługiwane w tej wersji. .SH BUGS Nazwa komendy powinna zostać wybrana bardziej dokładnie, tak aby odpowiadała jej przeznaczeniu. .SH AUTHOR Jens Schweikhardt <jens@kssun3.rus.uni-stuttgart.de> .SH "SEE ALSO" .BR bar (1), .BR foo (5), .BR xyzzy (1) </verb> <sect>3) Jak udokumentować kilka programów/funkcji w pojedynczej manpage?<p> Wiele programów (<tt/grep/, <tt/egrep/) oraz funkcji (<tt/printf/, <tt/fprintf/) udokumentowane są w pojedynczej manpage. Manpages te byłyby jednak zupełnie bezużyteczne jeśli byłyby dostępne tylko pod jedną nazwą. Nie możemy oczekiwać od użytkownika pamiętania że manpage <tt/egrep/ to w rzeczywistości manpage <tt/grep/. Koniecznym jest więc uczynienie manpage dostępnej pod różnymi nazwami. Masz kilka możliwości aby to osiągnąć: <enum> <item> zrobić identyczne kopie dla każdej nazwy, <item> połączyć wszystkie manpages za pomocą twardych odnośników, <item> odnośniki symboliczne wskazujące na właściwą manpage, <item> użyć mechanizmu "źródła" <tt/groff/, który daje makro <tt>".so"</tt> </enum> Pierwsza metoda to oczywiście marnotrawstwo miejsca na dysku. Drugiej nie poleca się, bowiem inteligetne wersje programu catman mogą oszczędzić wiele pracy poprzez spojrzenie na typ lub zawartość pliku. Twarde odnośniki nie pozwolą programowi catman wykazać się sprytem (celem catman jest formatowanie wszystkich manpages dla szybszego wyświetlania). Trzecia alternatywa ma niewielką niedogodność: jeśli chodzi o elastyczność, musisz być świadom że są systemy które nie obsługują odnośników symbolicznych. Wynika z tego to że Najlepszą Metodą (tm) jest użycie mechanizmu źródła <tt/groff/. Oto jak to uczynić: Jeśli chcesz mieć swoją manpage dostępną pod dwiema nazwami: <tt/"foo"/ i <tt/"bar"/ w sekcji 1, wstaw manpage do <tt/foo.1/ i stwórz <tt/bar.1/ z zawartością jak niżej: <verb>.so man1/foo.1</verb> Ważne jest podanie katalogu <tt>man1/</tt>, tak samo jak nazwy pliku <tt>"foo.1"</tt>, ponieważ podczas wywołania <tt/groff/ przez przeglądarkę będzie miał on [<tt/groff/] bazowy katalog programu <tt/man/ jako swój katalog bieżący (CWD), a <tt/groff/ interpretuje argumenty .so relatywnie względem CWD. <sect>4) Jakich pakietów makr powinienem używać?<p> Istnieje pewna liczba pakietów makr zaprojektowanych specjalnie do użytku przy pisaniu manpages. Zwykle znajdują się on w katalogu makr groff (<tt>/usr/lib/groff/tmac</tt>). Nazwy plików to <tt>tmac.<coś></tt>, gdzie <tt><coś></tt> jest argumentem z opcji <tt>-m groff</tt>. <tt/Groff/ użyje <tt>tmac.<coś></tt> przy podaniu mu opcji <tt>"-m <coś>"</tt>. Często opuszcza się spację między <tt>"-m"</tt> i <tt>"<coś>"</tt>, tak więc możemy napisać <tt>"groff -man"</tt> przy formatowaniu manpages z użyciem pakietu makr <tt/tmac.an/ (to jest właśnie powód dziwnej nazwy <tt/tmac.an/). Oprócz tmac.an istnieje jeszcze inny popularny pakiet makr, <tt/tmac.doc/, biorący początek z University of California w Berkeley. Używa go wiele manpages z BSD, i zdaje się że UCB uczynił go swoim standardem w dokumentacji. Makra <tt/tmac.doc/ są o wiele bardziej elastyczne, ale niestety istnieją przeglądarki które nie będą ich używać, lecz zawsze wywołają <tt/groff -man/. Dla przykładu, wszystkie programy <tt/xman/ które widziałem psuły manpages wymagające <tt/tmac.doc/. Zrób więc sobie przysługę: używaj <tt/tmac.an/ - używanie każdego innego pakietu makr uważane jest za szkodliwe. <tt/Tmac.andoc/ jest to pseudopakiet który spogląda na źródło i ładuje <tt/tmac.an/ lub <tt/tmac.doc/. Praktycznie każda przeglądarka manpages powinna go używać, ale jak dotąd nie wszystkie to robią, najlepiej jest więc trzymać się starego dobrego <tt/tmac.an/. Wszystko co piszę od tej pory i co się tyczy makr jest prawdziwe tylko dla <tt/tmac.an/. Jeśli chcesz używać mimo wszystko makr tmac.doc, oto odnośnik do szczegółowych informacji na temat ich używania (<tt><url url="http://www.bsdi.com/bsdi-man"></tt>) Na owej stronie znajduje się szukalny index. Wpisz mdoc, a odnajdzie ci on mdoc(7) i mdoc.samples(7), samouczkowe wprowadzenie do pisania manpages pod BSD. <sect>5) Jakich preprocesorów mogę używać?<p> <tt/Groff/ zawiera w sobie przynajmniej trzy preprocesory: <tt/tbl/, <tt/eqn/ oraz <tt/pic/ (na niektórych systemach nazywają się one <tt/gbtl/, <tt/geqn/ i <tt/gpic/). Ich celem jest przetłumaczenie makr preprocesorowych i ich danych na zwykłe dane wejściowe <tt/troff/. <tt/Tbl/ to preprocesor tabel, <tt/eqn/ - równań i wyraźeń matematycznych, a <tt/pic/ - obrazów. Zajrzyj do ich manpages po więcej informacji na temat funkcjonalności którą oferują. Ujmując to krótko: nie pisz manpages które by wymagały jakiegoś preprocesora. <tt/Eqn/ zwykle da fatalne rezultaty na urządzeniach "maszynopisaniowych", a niestety jest to ten typ urządzenia na którym ogląda się 99% manpages. Na przykład <tt/XAllocColor.3x/ używa kilku wyrażeń z wykładnikami. Ze względu na naturę urządzenia "maszynopisaniowego" wykładnik znajdował się będzie w tej samej linii co podstawa. N do potęgi drugiej wygląda jak "N2". <tt/Tbl/ powinno się unikać, ponieważ wszystkie programy <tt/xman/ które widziałem mają z nimi problemy. <tt/Xman 3.1.6/ używa do formatowania manpages następującej komendy, np. dla signal(7): <verb> gtbl /usr/man/man7/signal.7 | geqn | gtbl | groff -Tascii -man \ > /tmp/xmana01760 2> /dev/null </verb> co psuje się w źródłach uźywających <tt/gtbl/, ponieważ dane wyjściowe <tt/gtbl/ znowu posyłane są do <tt/gbtl/. W efekcie w manpage brakuje tabeli. Nie wiem czy to "pluskwa", czy jedna z opcji iż <tt/groff/ krztusi się swoim własnym rezultatem, ani czy <tt/xman/ nie mógłby być nieco sprytniejszy i nie używać <tt/gtbl/ dwa razy... Jeśli jednak chcesz mieć tabelę, sformatuj ją sam i wstaw ją między dwie linie .nf i .fi, tak żeby pozostała niesformatowana. Nie uzyskasz w ten sposób pogrubienia i kursywy, ale lepsze to niż niespodziewane połknięcie tabeli. Nie widziałem jeszcze manpage wymagającej przedprzetworzenia <tt/pic/, ale nie podobałaby mi się. Jak widać wyżej, xman nie będzie go [<tt/pic/] używał, a <tt/groff/ z pewnością powyczynia różne pokręcone rzeczy z danymi. <sect 6) Czy powinienem rozpowszechniać źródło i/lub już sformatowaną dokumentację?<p> Pozwól mi przytoczyć plusy (+) i minusy (-) kilku wybranych możliwości: 1) Tylko źródło: + mniejszy pakiet dystrybucyjny - niedostępne na systemach bez <tt/groff/ 2) Tylko nieskompresowane sformatowanie: + dostępne nawet na systemach bez <tt/groff/ - użytkownik nie może stworzyć pliku .dvi lub postscriptowego - marnotrawstwo przestrzeni dyskowej na systemach które obsługują także strony skompresowane 3) Tylko skompresowane formatowanie: + dostępne nawet na systemach bez <tt/groff/ - użytkownik nie może stworzyć pliku .dvi lub postscriptowego - którego formatu kompresji użyjesz? .Z? .z? .gz? Wszystkich? 4) Źródło i nieskompresowane sformatowanie: + dostępne nawet na systemach bez <tt/groff/ - większy pakiet dystrybucyjny - niektóre systemy mogą oczekiwać manpages skompresowanych i sformatowanych - zbyteczne informacje na systemach wyposażonych w <tt/groff/ IMHO najlepiej jest rozpowszechniać tylko źródło. Argument że nie jest ono dostępne na systemach bez groff nie liczy się. Ponad 500 manpages Linux Documentation Project istnieje tylko w źródle. Manpages XFree86 również, tak samo te z FSF. W rzeczy samej rzadko widywałem oprogramowanie rozpowszechniane ze sformatowanymi manpages. Jeśli jakiś administrator rzeczywiście dba o dostępność manpages, ma też zainstalowany <tt/groff/. <sect>7) Jakie są konwencje dotyczące czcionek?<p> Przede wszystkim: nie używaj bezpośrednich operatorów czcionek takich jak \fB \fP itd. Tą drogą unikniesz częstego potknięcia: zapomnienia zmiany czcionki na końcu słowa i sprawienia że pogrubienie czy kursywa rozciąga się aż do następnej zmiany czcionki. Uwierz mi, zdarza się to częściej niż myślisz. Makra <tt/tmac.an/ dają następujące kroje czcionek: <verb> .B pogrubiony .BI pogrubiony na przemian z kursywą .BR pogrubiony n/p z normalnym [roman] .I kursywa .IB kursywa n/p z pogrubionym .IR kursywa n/p z normalnym .RB normalny n/p z pogrubionym .RI normalny n/p z kursywą .SM mały (skalowany 90% normalnego rozmiaru) .SB mały pogrubiony (NIE mały n/p z pogrubionym) </verb> X na przemian z Y znaczy że argumenty parzyste są składane w X, natomiast nieparzyste w Y. Na przykład: .BI "Arg 1 jest pogrubiony", "Arg 2 jest kursywą", "pogrubiony", "kursywa". Cudzysłowy są konieczne aby w argumencie zawrzeć spacje. To tyle na temat tego co jest dostępne. Oto jak powienieneś wykorzystywać różne kroje czcionki (części bezwstydnie podkradzione z man(7)): Chociaż w świecie UNIXa istnieje wiele samowolnych kowencji dla manpages, istnienie kilkuset manpages specyficznych dla Linuxa definiuje nasze standardy: Dla funkcji, argumenty są zawsze podawane kursywą, nawet w sekcji SYNOPSIS, gdzie reszta funkcji podana jest jako pogrubiona: <verb> .BI "mojafunkcja(int " argc ", char **" argv );</verb> Nazwy plików zawsze podawane są kursywą, z wyjątkiem sekcji SYNOPSIS, gdzie pliki włączeniowe są pogrubione. Powienieś więc używać <verb> .I /usr/include/stdio.h oraz .B #include <stdio.h> </verb> Makra specjalne, zwykle dużymi literami, są pogrubione: <verb> .B MAXINT</verb> Przy wyliczaniu listy kodów błędów, kody są pogrubione. Lista ta używa zwykle makra .TP (paragraf z wystającym znacznikiem), jak poniżej: </verb> .TP .B EBADF .I fd nie jest ważnym deskryptorem pliku. .TP .B EINVAL .I fd nie nadaje się do czytania. </verb> Każdy odnośnik do innej manpage (albo do tematu bieżącej manpage) jest pogrubiony. Jeśli podany jest numer sekcji man, pisze się go krojem normalnym bez żadnych spacji: <verb> .BR man (7)</verb> Akronimy wyglądają najlepiej składane małym krojem. Polecam więc: <verb> .SM UNIX .SM ASCII .SM TAB .SM NFS .SM LALR(1)</verb> <sect>8) Upiększanie swojej manpage<p> Poniżej kilka wskazówek których zastosowanie zwiększy wiarygodność, czytelność i formatowalność twojej dokumentacji. <itemize> <item>Sprawdzaj czy działają przykłady (używaj wycinania i wklejania by podać powłoce dokładne sformułowanie z manpage), czytaj wynik twojej komendy do swojej manpage, nie pisz tego co ty MYŚLISZ że twój program wypisze. <item>Zrób korektę, zapuść <tt/ispell/, daj komuś innemu do przeczytania, zwłaszcza jeśli angielski nie jest twoim językiem ojczystym. <item>Przetestuj swoją manpage: czy <tt/groff/ narzeka przy formatowaniu? Miło jest umieścić parametry <tt/groff/ z linii komend w komentarzu. Czy komenda man(1) skarży się przy wywoływaniu "man twójprogram"? Czy sposób w jaki man(1) używa systemu formatującego daje spodziewane rezultaty? Czy xman(1x) i tkman(1tk) radzą sobie z twoją stroną? XFree86 3.1 ma xman 3.1.6 - X11R6, będzie próbować odkompresować używając </itemize> <verb><tscreen> gzip -c -d < %s > %s zcat < %s > %s </tscreen></verb> <itemize> <item>Czy makewhatis(8) zdolny jest wydobyć jednoliniowy opis z sekcji NAME? </itemize> <sect>9) Jak uzyskać czystą manpagę bez tych wszystkich _^H?<p> Rzuć okiem na col(1). <tt/col/ potrafi wyfiltrowywać sekwencje z wsteczną spacją. Na wszelki wypadek, gdybyś nie mógł czekać tak długo: <verb> groff -t -e -mandoc -Tascii manpage.1 | col -bx > manpage.txt</verb> Przełączniki -t i -e mówią <tt/groff/ aby przedprzetworzył używając <tt/tbl/ i <tt/eqn/. To przesada dla manpages które nie wymagają przedprzetworzenia, ale nie zaszkodzi, oprócz zmarnowania kilku cykli procesora. Z drugiej strony, nieużycie -t gdy faktycznie go potrzeba naprawdę szkodzi: tabela jest sformatowana strasznie. Możesz nawet wykryć (no, "zgadnąć" to lepsze słowo) jakiej komendy potrzeba do sformatowania jakiegoś dokumentu groff (nie tylko manpages) pisząc <verb> grog /usr/man/man7/signal.7 groff -t -man /usr/man/man7/signal.7 </verb> "grog" oznacza "GROff Guess" i robi to co wskazuje nazwa - zgaduje. Jeśliby był doskonały, nie potrzebowalibyśmy już więcej opcji. Widziałem że źle zgadywał pakiety makr, ale nigdy nie preprocesory. Oto mały skrypt w perlu który napisałem, i który potrafi usunąć nagłówki i stopki stron, oszczedzając ci przez to kilku stron przy wydruku długich i skomplikowanych manpages. Zachowaj go w pliku o nazwie strip-header i wykonaj <tt/chmod 755/. <verb><tscreen> #!/usr/bin/perl -n # każ mu łyknąć cały plik naraz: undef $/; # usuń znaki końca strony: s/\n{4}\S.{50,}\n{6}\S.{50,}\n{3}/\n/g; # usuń pierwszy nagłówek i ostatnią stopkę: s/\n\S.{50,}\n//g; # zwiń dwie lub więcej pustych linii w jedną: s/\n{3,}/\n\n/g; # pokaż co zostało... print; </tscreen></verb> Musisz go użyć jako pierwszy filtr po komendzie "man", ponieważ polega na liczbie znaków nowej linii wysłanych przez groff. Na przykład: <verb> man bash | strip-headers | col -bx > bash.txt</verb> <sect>10)Jak otrzymać wysokiej jakości manpage w postscripcie?<p> <verb> groff -t -e -mandoc -Tps manpage.1 > manpage.ps</verb> Wydrukuj to przy użyciu swojego ulubionego interpretera postscriptu. Zajrzyj do 9) po wyjaśnienie opcji. <sect>11)Jak zmusić do działania <tt/apropos/ i <tt/whatis/?<p> Załóżmy że ciekaw jesteś jakie są na twoim systemie zainstalowane kompilatory i jak można je wywołać. By odpowiedzieć na to (często zadawane) pytanie piszesz: <verb><tscreen> % apropos compiler f77 (1) - Fortran 77 compiler gcc (1) - GNU C and C++ compiler pc (1) - Pascal compiler </tscreen></verb> <tt/apropos/ oraz <tt/whatis/ używa się by uzyskać szybką odpowiedź która manpage posiada informacje na określony temat. Oba programy przeszukują pewną liczbę plików zwanych <tt/whatis/, które znaleźć można w każdym z bazowych katalogów manpages. Tak jak powiedziałem wcześniej, pliki bazowe danych <tt/whatis/ zawierają jednolinijkowy opis każdej manpage w odpowiednim drzewie katalogów. W rzeczy samej, każda linia to dokładnie sekcja NAME (ściśle mówiąc: połączona w jedną linię, z usuniętym dzieleniem wyrazów, zauważ też że sekcja znajduje się wewnątrz nawiasów). Pliki bazowe danych <tt/whatis/ tworzy się programem makewhatis(8). Istnieje ich kilka wersji, zajrzyj więc do manpage co do dostępnych opcji. Aby <tt/makewhatis/ zdolny był prawidłowo wydobyć sekcje NAME ważne jest abyś ty, piszący manpage, trzymał się formatu sekcji NAME opisanego w paragrafie 2. Różnica między apropos i whtais polega na tym gdzie i czego szukają w linii. Apropos (równoważne <tt/man -k/) szuka podanego jako argument łańcucha w całej linii, podczas gdy <tt/whatis/ (równoważne <tt/man -f/) próbuje znaleźć kompletną nazwę komendy tylko w części przed myślnikiem. W konsekwencji <tt/whatis cc/ da znać jeśli istnieje manpage dla <tt/cc/, ale przemilczy tą dla <tt/gcc/. Uprasza się o poprawki i sugestie! Copyright 1995,96 Jens Schweikhardt <tt>schweikh@noc.dfn.de</tt> tel. ++49 7151 909516 [standardowa copyright license] </article>