dw_man.pp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818
  1. {$mode objfpc}
  2. {$H+}
  3. unit dw_man;
  4. {$WARN 5024 off : Parameter "$1" not used}
  5. interface
  6. uses
  7. Classes, SysUtils, DGlobals, dWriter, pastree, dom;
  8. Const
  9. DefaultManSection = 3;
  10. MaxListLevel = 4;
  11. // Suffixes for overview man pages.
  12. SManConsts = 'consts';
  13. SManVars = 'variables';
  14. SManTypes = 'types';
  15. SManResStr = 'resstr';
  16. // Standard man sections.
  17. SManDocName = 'NAME';
  18. SManDocSynopsis = 'SYNOPSIS';
  19. SManDocDescription = 'DESCRIPTION';
  20. SManDocErrors = 'ERRORS';
  21. SManDocSeeAlso = 'SEE ALSO';
  22. // FPDoc man sections.
  23. SManDocPackageUnits = 'PACKAGE UNITS';
  24. SManDocUsedUnits = 'USED UNITS';
  25. SManDocResourceStrings = 'RESOURCE STRINGS';
  26. SManDocVariables = 'VARIABLES';
  27. SManDocTypes = 'TYPES';
  28. SManDocConstants = 'CONSTANTS';
  29. SManDocFunctions = 'PROCEDURES AND FUNCTIONS';
  30. SManDocClasses = 'CLASSES';
  31. SManDocExamples = 'EXAMPLES';
  32. SManDocVisibility = 'VISIBILITY';
  33. SManDocArguments = 'ARGUMENTS';
  34. SManDocResult = 'RETURN VALUE';
  35. SManDocAccess = 'ACCESSIBILITY';
  36. SManDocMethods = 'METHODS';
  37. SManDocProperties = 'PROPERTIES';
  38. // Used to start listing
  39. SManDocListing = 'Listing:';
  40. Type
  41. { TManWriter }
  42. TManWriter = Class(TFPDocWriter)
  43. SkipUnitPrefix,
  44. FSkipTrim : Boolean;
  45. OutputDir,
  46. ModuleName,
  47. ManSection,
  48. PackageDescr,
  49. PackageName: String;
  50. FAtLineStart,
  51. FCheckEOL : Boolean;
  52. FStream : TStream;
  53. Module: TPasModule;
  54. FListLevel : Integer;
  55. FLists : Array [0..MaxListLevel] of integer;
  56. Protected
  57. // Writing support.
  58. procedure Write(const s: String);
  59. procedure WriteF(const s: String; const Args: array of const);
  60. procedure WriteLn(const s: String);
  61. procedure WriteLnF(const s: String; const Args: array of const);
  62. Procedure NewLine;
  63. Function PushWriteContext(S : TStream) : TStream;
  64. Procedure PopWriteContext(S : TSTream);
  65. Function EscapeText(const s : String) : String;
  66. // Formatting
  67. procedure WriteTP;
  68. procedure WriteB(Const Msg : String);
  69. procedure WriteBI(Const Msg : String);
  70. procedure NewListLevel(Initial : Integer);
  71. procedure DecListLevel;
  72. procedure StartListing(Frames: Boolean);
  73. // Sectioning routines
  74. Procedure StartManPage(AElement : TPasElement; ADocNode : TDocNode);
  75. Procedure StartManPage(FN : String);
  76. Procedure EndManPage;
  77. procedure StartSection(Const SectionName : String);
  78. procedure StartSubSection(Const SubSectionName : String);
  79. procedure PageTitle(Const ATitle,ASection,ASource,Amanual : String);
  80. // Referencing
  81. Function ElementToManPage(APasElement : TPasElement) : String;
  82. procedure WriteManRef(Const ManPage : String; Comma : Boolean);
  83. procedure WriteManRef(APasElement : TPasElement; Comma : Boolean);
  84. procedure WriteModuleSeealso(Comma : Boolean);
  85. procedure SortElementList(List : TFPList);
  86. Function GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
  87. function ConstValue(ConstDecl: TPasConst): String; virtual;
  88. procedure WriteCommentLine;
  89. procedure WriteComment(Comment : String);
  90. Procedure WriteExampleFile(FN : String); virtual;
  91. procedure WriteExample(ADocNode: TDocNode);
  92. procedure WriteSeeAlso(ADocNode: TDocNode; Comma : Boolean);
  93. // Here we write the documentation.
  94. procedure DoWriteDocumentation; override;
  95. Public
  96. Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
  97. // Documentation writing methods.
  98. // Package
  99. Procedure WritePackagePage;
  100. // Topics
  101. Procedure ProcessTopics(DocNode : TDocNode; Subs : Boolean);
  102. Procedure WriteTopicRefs(DocNode : TDocNode);
  103. Procedure WriteTopicPage(Parent,Node : TDocNode);
  104. // Module
  105. procedure ProcessModule(AModule: TPasModule);
  106. procedure WriteUnitPage(AModule: TPasModule);
  107. procedure WriteUnitUsesOverview(ASection: TPasSection);
  108. procedure WriteUnitFunctionsAndProceduresOverview(ASection: TPasSection);
  109. procedure WriteUnitClassesOverview(ASection: TPasSection);
  110. procedure WriteUnitResourceStrings(ASection: TPasSection);
  111. procedure WriteUnitConsts(ASection: TPasSection);
  112. procedure WriteUnitTypes(ASection: TPasSection);
  113. procedure WriteUnitVars(ASection: TPasSection);
  114. procedure WriteUnitClasses(ASection: TPasSection);
  115. procedure WriteUnitFunctionsAndProcedures(ASection: TPasSection);
  116. // Smaller elements
  117. procedure WriteEnumElements(TypeDecl : TPasEnumType);
  118. procedure WriteClassPage(ClassDecl: TPasClassType);
  119. procedure WriteClassMethodOverview(ClassDecl: TPasClassType);
  120. procedure WriteClassPropertyOverview(ClassDecl: TPasClassType);
  121. procedure WriteProcedurePage(ProcDecl: TPasProcedureBase);
  122. procedure AppendProcedureArgsSection(Element: TPasProcedureType);
  123. procedure AppendFunctionResultSection(Element: TPasFunctionType);
  124. procedure WritePropertyPage(PropDecl: TPasProperty);
  125. // Overriden from fpdocwriter;
  126. procedure DescrWriteText(const AText: DOMString); override;
  127. procedure DescrBeginBold; override;
  128. procedure DescrEndBold; override;
  129. procedure DescrBeginItalic; override;
  130. procedure DescrEndItalic; override;
  131. procedure DescrBeginEmph; override;
  132. procedure DescrEndEmph; override;
  133. procedure DescrBeginUnderline; override;
  134. procedure DescrEndUnderline; override;
  135. procedure DescrWriteFileEl(const AText: DOMString); override;
  136. procedure DescrWriteKeywordEl(const AText: DOMString); override;
  137. procedure DescrWriteVarEl(const AText: DOMString); override;
  138. procedure DescrBeginLink(const AId: DOMString); override;
  139. procedure DescrEndLink; override;
  140. procedure DescrWriteLinebreak; override;
  141. procedure DescrBeginParagraph; override;
  142. procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
  143. procedure DescrWriteCodeLine(const ALine: String); override;
  144. procedure DescrEndCode; override;
  145. procedure DescrEndParagraph; override;
  146. procedure DescrBeginOrderedList; override;
  147. procedure DescrEndOrderedList; override;
  148. procedure DescrBeginUnorderedList; override;
  149. procedure DescrEndUnorderedList; override;
  150. procedure DescrBeginDefinitionList; override;
  151. procedure DescrEndDefinitionList; override;
  152. procedure DescrBeginListItem; override;
  153. procedure DescrEndListItem; override;
  154. procedure DescrBeginDefinitionTerm; override;
  155. procedure DescrEndDefinitionTerm; override;
  156. procedure DescrBeginDefinitionEntry; override;
  157. procedure DescrEndDefinitionEntry; override;
  158. procedure DescrBeginSectionTitle; override;
  159. procedure DescrBeginSectionBody; override;
  160. procedure DescrEndSection; override;
  161. procedure DescrBeginRemark; override;
  162. procedure DescrEndRemark; override;
  163. procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); override;
  164. procedure DescrEndTable; override;
  165. procedure DescrBeginTableCaption; override;
  166. procedure DescrEndTableCaption; override;
  167. procedure DescrBeginTableHeadRow; override;
  168. procedure DescrEndTableHeadRow; override;
  169. procedure DescrBeginTableRow; override;
  170. procedure DescrEndTableRow; override;
  171. procedure DescrBeginTableCell; override;
  172. procedure DescrEndTableCell; override;
  173. Function InterPretOption(Const Cmd,Arg : String) : boolean; override;
  174. Class Function FileNameExtension : String; override;
  175. Class procedure Usage(List: TStrings); override;
  176. end;
  177. implementation
  178. uses fpdocstrs;
  179. { TManWriter }
  180. constructor TManWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
  181. procedure AddLabel(AElement: TPasElement);
  182. begin
  183. Engine.AddLink(AElement.PathName, ElementToManPage(AElement));
  184. end;
  185. procedure AddList(AElement: TPasElement; AList: TFPList);
  186. var
  187. i: Integer;
  188. begin
  189. for i := 0 to AList.Count - 1 do
  190. AddLabel(TPasElement(AList[i]));
  191. end;
  192. procedure AddTopicPages(AElement: TPasElement);
  193. var
  194. PreviousTopic,
  195. TopicElement : TTopicElement;
  196. DocNode,
  197. TopicNode : TDocNode;
  198. begin
  199. DocNode:=Engine.FindDocNode(AElement);
  200. If not Assigned(DocNode) then
  201. exit;
  202. TopicNode:=DocNode.FirstChild;
  203. PreviousTopic:=Nil;
  204. While Assigned(TopicNode) do
  205. begin
  206. If TopicNode.TopicNode then
  207. begin
  208. TopicElement:=TTopicElement.Create(TopicNode.Name,AElement);
  209. Topics.Add(TopicElement);
  210. TopicElement.TopicNode:=TopicNode;
  211. TopicElement.Previous:=PreviousTopic;
  212. If Assigned(PreviousTopic) then
  213. PreviousTopic.Next:=TopicElement;
  214. PreviousTopic:=TopicElement;
  215. if AElement is TTopicElement then
  216. TTopicElement(AElement).SubTopics.Add(TopicElement);
  217. Engine.AddLink(TopicElement.PathName, ElementToManPage(TopicElement));
  218. if AElement is TTopicElement then
  219. TTopicElement(AElement).SubTopics.Add(TopicElement)
  220. else // Only one level of recursion.
  221. AddTopicPages(TopicElement);
  222. end;
  223. TopicNode:=TopicNode.NextSibling;
  224. end;
  225. end;
  226. procedure ScanModule(AModule: TPasModule);
  227. var
  228. i, j, k: Integer;
  229. ClassEl: TPasClassType;
  230. FPEl, AncestorMemberEl: TPasElement;
  231. DocNode: TDocNode;
  232. DidAutolink: Boolean;
  233. begin
  234. AddLabel(AModule);
  235. AddTopicPages(AModule);
  236. with AModule do
  237. begin
  238. AddList(AModule, InterfaceSection.ResStrings);
  239. AddList(AModule, InterfaceSection.Consts);
  240. AddList(AModule, InterfaceSection.Types);
  241. if InterfaceSection.Classes.Count > 0 then
  242. begin
  243. for i := 0 to InterfaceSection.Classes.Count - 1 do
  244. begin
  245. ClassEl := TPasClassType(InterfaceSection.Classes[i]);
  246. AddLabel(ClassEl);
  247. for j := 0 to ClassEl.Members.Count - 1 do
  248. begin
  249. FPEl := TPasElement(ClassEl.Members[j]);
  250. if Not Engine.ShowElement(FPEl) then
  251. continue;
  252. DocNode := Engine.FindDocNode(FPEl);
  253. if not Assigned(DocNode) then
  254. begin
  255. DidAutolink := False;
  256. if Assigned(ClassEl.AncestorType) and
  257. (ClassEl.AncestorType.ClassType = TPasClassType) then
  258. begin
  259. for k := 0 to TPasClassType(ClassEl.AncestorType).Members.Count - 1 do
  260. begin
  261. AncestorMemberEl :=
  262. TPasElement(TPasClassType(ClassEl.AncestorType).Members[k]);
  263. if AncestorMemberEl.Name = FPEl.Name then
  264. begin
  265. DocNode := Engine.FindDocNode(AncestorMemberEl);
  266. if Assigned(DocNode) then
  267. begin
  268. DidAutolink := True;
  269. Engine.AddLink(FPEl.PathName,
  270. Engine.FindAbsoluteLink(AncestorMemberEl.PathName));
  271. break;
  272. end;
  273. end;
  274. end;
  275. end;
  276. if not DidAutolink then
  277. AddLabel(FPEl);
  278. end else
  279. AddLabel(FPEl);
  280. end;
  281. end;
  282. end;
  283. AddList(AModule, InterfaceSection.Functions);
  284. AddList(AModule, InterfaceSection.Variables);
  285. end;
  286. end;
  287. var
  288. i: Integer;
  289. begin
  290. inherited;
  291. if Length(Package.Name) > 1 then
  292. AddTopicPages(Package);
  293. for i := 0 to Package.Modules.Count - 1 do
  294. ScanModule(TPasModule(Package.Modules[i]));
  295. end;
  296. { ---------------------------------------------------------------------
  297. Writing support
  298. ---------------------------------------------------------------------}
  299. Function TManWriter.PushWriteContext(S : TStream) : TStream;
  300. begin
  301. Result:=FStream;
  302. FStream:=S;
  303. end;
  304. Procedure TManWriter.PopWriteContext(S : TSTream);
  305. begin
  306. FStream:=S;
  307. end;
  308. function TManWriter.EscapeText(const s: String): String;
  309. begin
  310. Result:=S;
  311. end;
  312. procedure TManWriter.Write(const s: String);
  313. Var
  314. W : String;
  315. L : Integer;
  316. begin
  317. W:=S;
  318. If FAtLineStart and not FSKipTrim then
  319. W:=TrimLeft(W);
  320. L:=Length(W);
  321. If (L>0) then
  322. FStream.Write(PChar(W)^,L);
  323. FAtLineStart:=false;
  324. If FCheckEOL then
  325. begin
  326. If (L>=LEOL) then
  327. FAtLineStart:=(Copy(W,L-LEOL+1,LEOL)=LineEnding);
  328. end;
  329. end;
  330. Procedure TManWriter.NewLine;
  331. begin
  332. if Not FAtLineStart then
  333. Writeln('');
  334. end;
  335. procedure TManWriter.WriteF(const s: String; const Args: array of const);
  336. begin
  337. Write(Format(S,Args));
  338. end;
  339. procedure TManWriter.WriteLn(const s: String);
  340. begin
  341. FCheckEOL:=False;
  342. Try
  343. Write(S);
  344. Write(LineEnding);
  345. FAtLineStart:=True;
  346. finally
  347. FCheckEOL:=True;
  348. end;
  349. end;
  350. procedure TManWriter.WriteLnF(const s: String; const Args: array of const);
  351. begin
  352. Write(Format(S,Args));
  353. Write(LineEnding);
  354. end;
  355. procedure TManWriter.DescrWriteText(const AText: DOMString);
  356. begin
  357. self.Write(EscapeText(Utf8Encode(AText)));
  358. end;
  359. procedure TManWriter.DescrBeginBold;
  360. begin
  361. NewLine;
  362. Write('.B ');
  363. end;
  364. procedure TManWriter.DescrEndBold;
  365. begin
  366. NewLine;
  367. end;
  368. procedure TManWriter.DescrBeginItalic;
  369. begin
  370. NewLine;
  371. Write('.I ');
  372. end;
  373. procedure TManWriter.DescrEndItalic;
  374. begin
  375. NewLine;
  376. end;
  377. procedure TManWriter.DescrBeginEmph;
  378. begin
  379. NewLine;
  380. Write('.I ');
  381. end;
  382. procedure TManWriter.DescrEndEmph;
  383. begin
  384. NewLine;
  385. end;
  386. procedure TManWriter.DescrBeginUnderline;
  387. begin
  388. NewLine;
  389. Write('.I '); //use ITALIC!
  390. end;
  391. procedure TManWriter.DescrEndUnderline;
  392. begin
  393. NewLine;
  394. end;
  395. procedure TManWriter.DescrWriteFileEl(const AText: DOMString);
  396. Var
  397. S : AnsiString;
  398. begin
  399. NewLine;
  400. S:=UTF8Encode(AText);
  401. Writeln('.I '+S);
  402. end;
  403. procedure TManWriter.DescrWriteKeywordEl(const AText: DOMString);
  404. Var
  405. S : AnsiString;
  406. begin
  407. NewLine;
  408. S:=Utf8Encode(AText);
  409. Writeln('.B '+S);
  410. end;
  411. procedure TManWriter.DescrWriteVarEl(const AText: DOMString);
  412. Var
  413. S : AnsiString;
  414. begin
  415. NewLine;
  416. S:=Utf8Encode(AText);
  417. Writeln('.B '+S);
  418. end;
  419. procedure TManWriter.DescrBeginLink(const AId: DOMString);
  420. begin
  421. // Do nothing
  422. end;
  423. procedure TManWriter.DescrEndLink;
  424. begin
  425. // Do nothing
  426. end;
  427. procedure TManWriter.DescrWriteLinebreak;
  428. begin
  429. NewLine;
  430. Writeln('.br');
  431. end;
  432. procedure TManWriter.DescrBeginParagraph;
  433. begin
  434. NewLine;
  435. Writeln('.PP');
  436. end;
  437. procedure TManWriter.DescrBeginCode(HasBorder: Boolean;
  438. const AHighlighterName: String);
  439. begin
  440. NewLine;
  441. Writeln('');
  442. end;
  443. procedure TManWriter.DescrWriteCodeLine(const ALine: String);
  444. begin
  445. FSkipTrim:=True;
  446. Try
  447. Writeln(ALine);
  448. Finally
  449. FSkipTrim:=False;
  450. end;
  451. DescrWriteLinebreak;
  452. end;
  453. procedure TManWriter.DescrEndCode;
  454. begin
  455. NewLine;
  456. Writeln('');
  457. end;
  458. procedure TManWriter.DescrEndParagraph;
  459. begin
  460. NewLine;
  461. Writeln('');
  462. end;
  463. procedure TManWriter.NewListLevel(Initial : Integer);
  464. begin
  465. Inc(FListLevel);
  466. If (FListLevel<MaxListLevel) then
  467. FLists[FListLevel]:=0;
  468. NewLine;
  469. Writeln('.RS');
  470. end;
  471. procedure TManWriter.DecListLevel;
  472. begin
  473. NewLine;
  474. Writeln('.RE');
  475. If (FListLevel>0) then
  476. Dec(FListLevel)
  477. end;
  478. procedure TManWriter.DescrBeginOrderedList;
  479. begin
  480. NewListLevel(0);
  481. end;
  482. procedure TManWriter.DescrEndOrderedList;
  483. begin
  484. DecListLevel;
  485. end;
  486. procedure TManWriter.DescrBeginUnorderedList;
  487. begin
  488. NewListLevel(-1);
  489. end;
  490. procedure TManWriter.DescrEndUnorderedList;
  491. begin
  492. DecListlevel;
  493. end;
  494. procedure TManWriter.DescrBeginDefinitionList;
  495. begin
  496. NewListLevel(-2);
  497. end;
  498. procedure TManWriter.DescrEndDefinitionList;
  499. begin
  500. DecListLevel
  501. end;
  502. procedure TManWriter.DescrBeginListItem;
  503. begin
  504. WriteTP
  505. end;
  506. procedure TManWriter.DescrEndListItem;
  507. begin
  508. NewLine;
  509. end;
  510. procedure TManWriter.DescrBeginDefinitionTerm;
  511. begin
  512. WriteTP;
  513. Write('.B ');
  514. end;
  515. procedure TManWriter.DescrEndDefinitionTerm;
  516. begin
  517. NewLine;
  518. end;
  519. procedure TManWriter.DescrBeginDefinitionEntry;
  520. begin
  521. NewLine;
  522. end;
  523. procedure TManWriter.DescrEndDefinitionEntry;
  524. begin
  525. NewLine;
  526. end;
  527. procedure TManWriter.DescrBeginSectionTitle;
  528. begin
  529. Write('.SH ');
  530. end;
  531. procedure TManWriter.DescrBeginSectionBody;
  532. begin
  533. NewLine;
  534. end;
  535. procedure TManWriter.DescrEndSection;
  536. begin
  537. NewLine;
  538. end;
  539. procedure TManWriter.DescrBeginRemark;
  540. begin
  541. WriteTP;
  542. WriteB(SDocRemark);
  543. end;
  544. procedure TManWriter.DescrEndRemark;
  545. begin
  546. NewLine;
  547. end;
  548. procedure TManWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
  549. begin
  550. NewLine;
  551. end;
  552. procedure TManWriter.DescrEndTable;
  553. begin
  554. NewLine;
  555. end;
  556. procedure TManWriter.DescrBeginTableCaption;
  557. begin
  558. NewLine;
  559. end;
  560. procedure TManWriter.DescrEndTableCaption;
  561. begin
  562. NewLine;
  563. end;
  564. procedure TManWriter.DescrBeginTableHeadRow;
  565. begin
  566. DescrBeginParagraph;
  567. end;
  568. procedure TManWriter.DescrEndTableHeadRow;
  569. begin
  570. DescrEndParagraph;
  571. end;
  572. procedure TManWriter.DescrBeginTableRow;
  573. begin
  574. DescrBeginParagraph;
  575. end;
  576. procedure TManWriter.DescrEndTableRow;
  577. begin
  578. DescrEndParagraph;
  579. end;
  580. procedure TManWriter.DescrBeginTableCell;
  581. begin
  582. // Do nothing
  583. end;
  584. procedure TManWriter.DescrEndTableCell;
  585. begin
  586. Writeln(#9);
  587. end;
  588. function TManWriter.InterPretOption(const Cmd, Arg: String): boolean;
  589. begin
  590. Result:=True;
  591. if (Cmd='--man-section') then
  592. ManSection:=Arg
  593. else if (Cmd='--man-description') then
  594. PackageDescr:=Arg
  595. else if (Cmd='--nounitprefix') then
  596. SkipUnitPrefix:=True
  597. else
  598. Result:=inherited InterPretOption(Cmd, Arg);
  599. end;
  600. Function TManWriter.GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
  601. Var
  602. S : TStringStream;
  603. F : TStream;
  604. begin
  605. Result:='';
  606. if Assigned(DescrNode) then
  607. begin
  608. S:=TStringStream.Create('');
  609. Try
  610. F:=PushWriteContext(S);
  611. Try
  612. ConvertDescr(AContext, DescrNode, False);
  613. Result:=S.DataString;
  614. FInally
  615. PopWriteContext(F);
  616. end;
  617. finally
  618. S.FRee;
  619. end;
  620. end;
  621. end;
  622. { ---------------------------------------------------------------------
  623. Formatting routines
  624. ---------------------------------------------------------------------}
  625. procedure TManWriter.WriteTP;
  626. begin
  627. NewLine;
  628. Writeln('.TP');
  629. end;
  630. procedure TManWriter.WriteB(Const Msg : String);
  631. begin
  632. NewLine;
  633. Writeln('.B '+MSG);
  634. end;
  635. procedure TManWriter.WriteBI(Const Msg : String);
  636. begin
  637. NewLine;
  638. Writeln('.BI '+MSG);
  639. end;
  640. { ---------------------------------------------------------------------
  641. Sectioning routines
  642. ---------------------------------------------------------------------}
  643. procedure TManWriter.StartListing(Frames: Boolean);
  644. begin
  645. Writeln('');
  646. WriteB(SManDocListing);
  647. end;
  648. procedure TManWriter.StartManPage(AElement: TPasElement; ADocNode: TDocNode);
  649. begin
  650. StartManPage(ElementToManPage(AElement))
  651. end;
  652. procedure TManWriter.StartManPage(FN: String);
  653. begin
  654. FN:=LowerCase(FN+'.'+mansection);
  655. FStream:=TFileStream.Create(OutputDir+FN,fmCreate);
  656. end;
  657. procedure TManWriter.EndManPage;
  658. begin
  659. FreeAndNil(FStream);
  660. end;
  661. procedure TManWriter.StartSection(Const SectionName: String);
  662. begin
  663. NewLine;
  664. Writeln('');
  665. Writeln('.SH '+SectionName);
  666. end;
  667. procedure TManWriter.StartSubSection(Const SubSectionName: String);
  668. begin
  669. NewLine;
  670. Writeln('.SS '+SubSectionName);
  671. end;
  672. procedure TManWriter.PageTitle(Const ATitle,ASection,ASource,Amanual : String);
  673. Var
  674. D : String;
  675. begin
  676. D:=FormatDateTime('mmmm yyyy',Date);
  677. WritelnF('.TH "%s" "%s" "%s" "%s" "%s"',[ATitle,ASection,D,ASource,AManual]);
  678. end;
  679. procedure TManWriter.WriteManRef(Const ManPage : String; Comma : Boolean);
  680. begin
  681. If Comma then
  682. Writeln(Lowercase(Format('%s (%s),',[ManPage,ManSection])))
  683. else
  684. Writeln(Lowercase(Format('%s (%s)',[ManPage,ManSection])));
  685. end;
  686. Function TManWriter.ElementToManPage(APasElement : TPasElement) : String;
  687. Var
  688. E : TPasElement;
  689. begin
  690. E:=APasElement; // Make code more readable
  691. If (E is TPasPackage) or (E is TPasModule) then
  692. begin
  693. Result:=APasElement.Name;
  694. If (Length(Result)>0) and (Result[1]='#') then
  695. Delete(Result,1,1);
  696. end
  697. else if E is TTopicElement then
  698. begin
  699. // Todo : Check for package
  700. Result:=ModuleName+E.name;
  701. end
  702. else
  703. begin
  704. If Not SkipUnitprefix then
  705. Result:=ModuleName+'.';
  706. If (E.Parent<>Nil) and (not (E.Parent is TPasSection)) then
  707. begin
  708. If (E.Parent.Name<>'') then
  709. Result:=Result+E.Parent.Name;
  710. If (E is TPasProperty) or (E is TPasProcedure) or (E is TPasClassType) then
  711. Result:=Result+E.Name;
  712. end
  713. else
  714. begin
  715. If (E is TPasConst) then
  716. Result:=Result+SManConsts
  717. else If E is TPasVariable then
  718. Result:=Result+SManVars
  719. else If E is TPasClassType then
  720. Result:=Result+E.Name
  721. else If E is TPasType then
  722. Result:=Result+SManTypes
  723. else If E is TPasResString then
  724. Result:=Result+SManResStr
  725. else
  726. Result:=Result+E.Name;
  727. end;
  728. end;
  729. Result:=LowerCase(Result);
  730. end;
  731. procedure TManWriter.WriteManRef(APasElement : TPasElement; Comma : Boolean);
  732. begin
  733. WriteManRef(ElementToManPage(APasElement),Comma);
  734. end;
  735. procedure TManWriter.WriteModuleSeealso(Comma : Boolean);
  736. Var
  737. HC,HT,HV,HR : Boolean;
  738. begin
  739. HC:=Module.InterfaceSection.Consts.Count>0;
  740. HR:=Module.InterfaceSection.ResStrings.Count>0;
  741. HV:=Module.InterfaceSection.Variables.Count>0;
  742. HT:=Module.InterfaceSection.Types.Count>0;
  743. WriteManRef(ModuleName,HC or HR or HV or HT or comma);
  744. if HC then
  745. WriteManRef(ModuleName+'.'+SManConsts,HR or HV or HT or comma);
  746. if HR then
  747. WriteManRef(ModuleName+'.'+SManResStr, HV or HT or comma);
  748. if HV then
  749. WriteManRef(ModuleName+'.'+SManVars, HT or comma);
  750. if HT then
  751. WriteManRef(ModuleName+'.'+SManTypes,comma);
  752. end;
  753. procedure TManWriter.WriteSeeAlso(ADocNode: TDocNode; Comma: Boolean);
  754. var
  755. Node: TDOMNode;
  756. s: String;
  757. begin
  758. if Not (Assigned(ADocNode) and Assigned(ADocNode.SeeAlso)) then
  759. Exit;
  760. Node := ADocNode.SeeAlso.FirstChild;
  761. while Assigned(Node) do
  762. begin
  763. if IsLinkNode(Node) then
  764. begin
  765. S:=UTF8Encode(TDomElement(Node)['id']);
  766. WriteManRef(S,(Node.NextSibling<>Nil) or Comma);
  767. end;
  768. Node:=Node.NextSibling;
  769. end;
  770. end;
  771. function TManWriter.ConstValue(ConstDecl: TPasConst): String;
  772. begin
  773. if Assigned(ConstDecl) then
  774. Result := ConstDecl.ClassName
  775. else
  776. Result := '<nil>';
  777. end;
  778. procedure TManWriter.WriteExample(ADocNode: TDocNode);
  779. var
  780. Example: TDOMElement;
  781. S : string;
  782. begin
  783. S:='';
  784. if Assigned(ADocNode) then
  785. begin
  786. Example := ADocNode.FirstExample;
  787. If Assigned(Example) then
  788. begin
  789. StartSection(SManDocExamples);
  790. while Assigned(Example) do
  791. begin
  792. s:=Engine.GetExampleFileName(Example);
  793. if (s<>'') then
  794. WriteExampleFile(S);
  795. DescrEndParaGraph;
  796. Repeat
  797. Example := TDomElement(Example.NextSibling);
  798. until (Example=Nil) or ((Example.NodeType=ELEMENT_NODE) and (Example.NodeName='example'));
  799. end;
  800. end;
  801. end;
  802. end;
  803. procedure TManWriter.WriteExampleFile(FN : String);
  804. Var
  805. L : TStringList;
  806. I : Integer;
  807. begin
  808. WriteBI(SDocExample+' \- '+ExtractFileName(FN));
  809. Writeln('');
  810. DescrWriteLineBreak;
  811. If (FN<>'') and FileExists(FN) then
  812. begin
  813. L:=TStringList.Create;
  814. Try
  815. L.LoadFromFile(FN);
  816. For I:=0 to L.Count-1 do
  817. DescrWriteCodeLine(L[i]);
  818. finally
  819. L.Free;
  820. end;
  821. end;
  822. end;
  823. { ---------------------------------------------------------------------
  824. Actual man page writing
  825. ---------------------------------------------------------------------}
  826. procedure TManWriter.DoWriteDocumentation;
  827. var
  828. i : Integer;
  829. L : TstringList;
  830. begin
  831. PackageName := LowerCase(Copy(Package.Name, 2, 255));
  832. If (Engine.Output<>'') then
  833. OutputDir:=Engine.Output
  834. else
  835. OutputDir:=PackageName+'.man';
  836. If not ForceDirectories(OutputDir) then
  837. FPDocError(SErrCouldNotCreateOutputDir,[OutputDir]);
  838. OutputDir:=IncludeTrailingPathDelimiter(OutputDir);
  839. If (ManSection='') then
  840. ManSection:=IntToStr(DefaultManSection);
  841. WritePackagePage;
  842. L:=TStringList.Create;
  843. Try
  844. // Sort modules.
  845. For I:=0 to Package.Modules.Count-1 do
  846. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  847. L.Sorted:=True;
  848. for i:=0 to L.Count - 1 do
  849. ProcessModule(TPasModule(L.Objects[i]));
  850. Finally
  851. L.Free;
  852. end;
  853. end;
  854. { ---------------------------------------------------------------------
  855. Package man page
  856. ---------------------------------------------------------------------}
  857. Procedure TManWriter.WritePackagePage;
  858. var
  859. D,DocNode: TDocNode;
  860. M : TPasModule;
  861. I : Integer;
  862. L : TStringList;
  863. begin
  864. DocNode:=Engine.FindDocNode(Package);
  865. If (PackageDescr='') and assigned(DocNode) then
  866. PackageDescr:=GetDescrString(Package,DocNode.ShortDescr);
  867. StartManPage(Package,DocNode);
  868. Try
  869. PageTitle(PackageName,ManSection,PackageName,PackageDescr);
  870. StartSection(SManDocName);
  871. Writeln(PackageName+' \- '+PackageDescr);
  872. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  873. begin
  874. StartSection(SDocDescription);
  875. WriteDescr(Package, DocNode.Descr);
  876. end;
  877. StartSection(SManDocPackageUnits);
  878. L:=TStringList.Create;
  879. Try
  880. For I:=0 to Package.Modules.Count-1 do
  881. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  882. L.Sorted:=True;
  883. for i:=0 to L.Count - 1 do
  884. begin
  885. WriteTP;
  886. WriteB(L[i]);
  887. M:=TPasModule(L.Objects[i]);
  888. D:=Engine.FindDocNode(M);
  889. if Assigned(D) then
  890. WriteLn(GetDescrString(M,D.ShortDescr))
  891. else
  892. WriteLn(GetDescrString(M,Nil))
  893. end;
  894. StartSection(SDocSeeAlso);
  895. WriteSeeAlso(DocNode,True);
  896. WriteTopicRefs(DocNode);
  897. for i:=0 to L.Count - 1 do
  898. WriteManRef(TPasModule(L.Objects[i]),I<L.Count-1);
  899. Finally
  900. L.Free;
  901. end;
  902. Finally
  903. EndManPage;
  904. end;
  905. ProcessTopics(DocNode,True);
  906. end;
  907. { ---------------------------------------------------------------------
  908. Topic support
  909. ---------------------------------------------------------------------}
  910. Procedure TManWriter.WriteTopicRefs(DocNode : TDocNode);
  911. Var
  912. Node : TDocNode;
  913. begin
  914. If Not Assigned(DocNode) then
  915. Exit;
  916. Node:=DocNode.FirstChild;
  917. While Assigned(Node) do
  918. begin
  919. If Node.TopicNode then
  920. WriteManRef(DocNode.Name,Node.NextSibling<>Nil);
  921. Node:=Node.NextSibling;
  922. end;
  923. end;
  924. Procedure TManWriter.ProcessTopics(DocNode : TDocNode; Subs : Boolean);
  925. Var
  926. Node,SubNode : TDocNode;
  927. begin
  928. If Not Assigned(DocNode) then
  929. Exit;
  930. Node:=DocNode.FirstChild;
  931. While Assigned(Node) do
  932. begin
  933. If Node.TopicNode then
  934. begin
  935. WriteTopicPage(DocNode,Node);
  936. If Subs then
  937. begin
  938. SubNode:=DocNode.FirstChild;
  939. While Assigned(SubNode) do
  940. If SubNode.TopicNode then
  941. WriteTopicPage(Node,SubNode);
  942. end;
  943. end;
  944. Node:=Node.NextSibling;
  945. end;
  946. end;
  947. Procedure TManWriter.WriteTopicPage(Parent,Node : TDocNode);
  948. Var
  949. Element : TTopicElement;
  950. begin
  951. Element:=FindTopicElement(Node);
  952. If Not Assigned(Element) then
  953. Exit;
  954. StartManPage(Element,Node) ;
  955. Try
  956. PageTitle(Node.Name,ManSection,PackageName,PackageDescr);
  957. StartSection(SManDocName);
  958. Writeln(Node.Name+' \- '+GetDescrString(Element,Node.ShortDescr));
  959. StartSection(SManDocDescription);
  960. If Assigned(Node.Descr) then
  961. WriteDescr(Element,Node.Descr);
  962. StartSection(SManDocSeeAlso);
  963. WriteSeeAlso(Node,True);
  964. WriteTopicRefs(Parent);
  965. WriteTopicRefs(Node);
  966. Finally
  967. EndManPage;
  968. end;
  969. end;
  970. { ---------------------------------------------------------------------
  971. Module man pages
  972. ---------------------------------------------------------------------}
  973. procedure TManWriter.ProcessModule(AModule : TPasModule);
  974. begin
  975. With AModule do
  976. begin
  977. Module:=AModule;
  978. ModuleName:=Name;
  979. With InterfaceSection do
  980. begin
  981. SortElementList(Declarations);
  982. SortElementList(Types);
  983. SortElementList(Consts);
  984. SortElementList(Classes);
  985. SortElementList(Functions);
  986. SortElementList(Variables);
  987. SortElementList(ResStrings);
  988. end;
  989. WriteUnitPage(AModule);
  990. WriteUnitResourceStrings(InterfaceSection);
  991. WriteUnitConsts(InterfaceSection);
  992. WriteUnitTypes(InterfaceSection);
  993. WriteUnitVars(InterfaceSection);
  994. WriteUnitClasses(InterfaceSection);
  995. WriteUnitFunctionsAndProcedures(InterfaceSection);
  996. end;
  997. end;
  998. procedure TManWriter.WriteUnitPage(AModule : TPasModule);
  999. Var
  1000. DocNode : TDocNode;
  1001. S : String;
  1002. begin
  1003. DocNode:=Engine.FindDocNode(AModule);
  1004. StartManPage(AModule,DocNode);
  1005. Try
  1006. PageTitle(AModule.Name,ManSection,PackageName,PackageDescr);
  1007. StartSection(SManDocName);
  1008. if Assigned(DocNode) then
  1009. S:=GetDescrString(AModule,DocNode.ShortDescr);
  1010. Writeln(AModule.Name+' \- '+S);
  1011. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  1012. begin
  1013. StartSection(SManDocDescription);
  1014. WriteDescr(AModule.Parent, DocNode.Descr);
  1015. end;
  1016. WriteUnitUsesOverview(AModule.InterfaceSection);
  1017. WriteUnitClassesOverView(AModule.InterfaceSection);
  1018. WriteUnitFunctionsAndProceduresOverView(AModule.InterfaceSection);
  1019. StartSection(SManDocSeealso);
  1020. WriteModuleSeeAlso(False);
  1021. finally
  1022. EndManPage;
  1023. end;
  1024. end;
  1025. procedure TManWriter.WriteUnitUsesOverview(ASection: TPasSection);
  1026. var
  1027. i: Integer;
  1028. UnitRef: TPasType;
  1029. DocNode: TDocNode;
  1030. begin
  1031. if ASection.UsesList.Count > 0 then
  1032. begin
  1033. StartSection(SManDocUsedUnits);
  1034. for i := 0 to ASection.UsesList.Count - 1 do
  1035. begin
  1036. UnitRef := TPasType(ASection.UsesList[i]);
  1037. WriteTP;
  1038. WriteB(UnitRef.Name);
  1039. DocNode := Engine.FindDocNode(UnitRef);
  1040. If Assigned(DocNode) then
  1041. WriteDescr(UnitRef,DocNode.ShortDescr)
  1042. end;
  1043. end;
  1044. end;
  1045. { ---------------------------------------------------------------------
  1046. Classes man pages
  1047. ---------------------------------------------------------------------}
  1048. procedure TManWriter.WriteUnitClassesOverview(ASection: TPasSection);
  1049. var
  1050. i : Integer;
  1051. DocNode : TDocNode;
  1052. ClassDecl : TPasClassType;
  1053. begin
  1054. // Overview page
  1055. if ASection.Classes.Count > 0 then
  1056. begin
  1057. StartSection(SManDocClasses);
  1058. for i := 0 to ASection.Classes.Count - 1 do
  1059. begin
  1060. ClassDecl:=TPasClassType(ASection.Classes[i]);
  1061. WriteTP;
  1062. WriteB(ClassDecl.Name);
  1063. DocNode:=Engine.FindDocNode(ClassDecl);
  1064. If Assigned(DocNode) then
  1065. WriteDescr(ClassDecl,DocNode.ShortDescr);
  1066. end;
  1067. end;
  1068. end;
  1069. procedure TManWriter.WriteUnitClasses(ASection: TPasSection);
  1070. var
  1071. i: Integer;
  1072. begin
  1073. if (ASection.Classes.Count > 0) then
  1074. begin
  1075. for i := 0 to ASection.Classes.Count - 1 do
  1076. WriteClassPage(TPasClassType(ASection.Classes[i]));
  1077. end;
  1078. end;
  1079. procedure TManWriter.WriteClassPage(ClassDecl: TPasClassType);
  1080. var
  1081. DocNode: TDocNode;
  1082. begin
  1083. DocNode:=Engine.FindDocNode(ClassDecl);
  1084. StartManPage(ClassDecl,DocNode);
  1085. Try
  1086. PageTitle(ClassDecl.Name,ManSection,PackageName,PackageDescr);
  1087. StartSection(SManDocName);
  1088. Write(ClassDecl.Name);
  1089. DocNode := Engine.FindDocNode(ClassDecl);
  1090. If Assigned(DocNode) then
  1091. begin
  1092. if not IsDescrNodeEmpty(DocNode.ShortDescr) then
  1093. begin
  1094. write(' \- ');
  1095. WriteDescr(ClassDecl,DocNode.ShortDescr);
  1096. end;
  1097. if Not (IsDescrNodeEmpty(DocNode.Descr)
  1098. and IsDescrNodeEmpty(DocNode.ShortDescr)) then
  1099. begin
  1100. StartSection(SDocDescription);
  1101. WriteDescr(ClassDecl);
  1102. end;
  1103. end;
  1104. // Write method overview
  1105. WriteClassMethodOverView(ClassDecl);
  1106. // Write Property Overview;
  1107. WriteClassPropertyOverView(ClassDecl);
  1108. Finally
  1109. EndManPage;
  1110. end
  1111. end;
  1112. procedure TManWriter.WriteClassPropertyOverview(ClassDecl : TPasClassType);
  1113. var
  1114. Member: TPasElement;
  1115. i: Integer;
  1116. A: String;
  1117. DocNode: TDocNode;
  1118. List : TStringList;
  1119. begin
  1120. // Write property overview
  1121. List:=TStringList.Create;
  1122. Try
  1123. for i := 0 to ClassDecl.Members.Count - 1 do
  1124. begin
  1125. Member := TPasElement(ClassDecl.Members[i]);
  1126. With Member do
  1127. if InheritsFrom(TPasProperty) and SHowMember(Member) then
  1128. List.AddObject(Member.Name,Member)
  1129. end;
  1130. List.Sorted:=True;
  1131. If (List.Count>0) then
  1132. begin
  1133. StartSection(SDocPropertyOverview);
  1134. For I:=0 to List.Count-1 do
  1135. begin
  1136. Member:=TPasElement(List.objects[i]);
  1137. WriteTP;
  1138. A:='';
  1139. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  1140. a := a + 'r';
  1141. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  1142. a := a + 'w';
  1143. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  1144. a := a + 's';
  1145. WriteBI(Member.Name+' '+A);
  1146. DocNode := Engine.FindDocNode(Member);
  1147. If Assigned(DocNode) then
  1148. WriteDescr(Member, DocNode.ShortDescr)
  1149. end;
  1150. end;
  1151. Finally
  1152. List.Free;
  1153. end;
  1154. end;
  1155. { ---------------------------------------------------------------------
  1156. Resource strings man page
  1157. ---------------------------------------------------------------------}
  1158. procedure TManWriter.WriteUnitResourceStrings(ASection: TPasSection);
  1159. var
  1160. ResStrDecl: TPasResString;
  1161. i: Integer;
  1162. begin
  1163. if ASection.ResStrings.Count > 0 then
  1164. begin
  1165. StartManpage(ModuleName+'.'+SManResStr);
  1166. Try
  1167. PageTitle(Modulename,ManSection,PackageName,PackageDescr);
  1168. StartSection(SManDocName);
  1169. Writeln(ModuleName+' \- '+SDocResStrings);
  1170. StartSection(SManDocResourceStrings);
  1171. Writeln('');
  1172. for i := 0 to ASection.ResStrings.Count - 1 do
  1173. begin
  1174. ResStrDecl := TPasResString(ASection.ResStrings[i]);
  1175. StartSubSection(ResStrDecl.Name);
  1176. DescrWriteCodeLine(EscapeText(ResStrDecl.GetDeclaration(False)));
  1177. end;
  1178. StartSection(SDocSeeAlso);
  1179. WriteModuleSeealso(False);
  1180. Finally
  1181. EndManPage;
  1182. end;
  1183. end;
  1184. end;
  1185. { ---------------------------------------------------------------------
  1186. Constants man page
  1187. ---------------------------------------------------------------------}
  1188. procedure TManWriter.WriteUnitConsts(ASection: TPasSection);
  1189. var
  1190. i: Integer;
  1191. ConstDecl: TPasConst;
  1192. DocNode: TDocNode;
  1193. begin
  1194. if ASection.Consts.Count > 0 then
  1195. begin
  1196. StartManpage(ModuleName+'.'+SManConsts);
  1197. Try
  1198. PageTitle(Modulename,ManSection,PackageName,PackageDescr);
  1199. StartSection(SManDocName);
  1200. Writeln(ModuleName+' \- '+SDocConstants);
  1201. StartSection(SManDocConstants);
  1202. for i := 0 to ASection.Consts.Count - 1 do
  1203. begin
  1204. ConstDecl := TPasConst(ASection.Consts[i]);
  1205. StartSubSection(ConstDecl.Name);
  1206. DescrWriteCodeLine(EscapeText(ConstDecl.GetDeclaration(True)));
  1207. DocNode:=Engine.FindDocNode(ConstDecl);
  1208. WriteDescr(ConstDecl,DocNode);
  1209. end;
  1210. StartSection(SDocSeeAlso);
  1211. WriteModuleSeealso(False);
  1212. Finally
  1213. EndManPage;
  1214. end;
  1215. end;
  1216. end;
  1217. { ---------------------------------------------------------------------
  1218. Types man page
  1219. ---------------------------------------------------------------------}
  1220. procedure TManWriter.WriteUnitTypes(ASection: TPasSection);
  1221. var
  1222. i: Integer;
  1223. TypeDecl: TPasType;
  1224. DocNode : TDocNode;
  1225. begin
  1226. if ASection.Types.Count > 0 then
  1227. begin
  1228. StartManpage(ModuleName+'.'+SManTypes);
  1229. Try
  1230. PageTitle(Modulename,ManSection,PackageName,PackageDescr);
  1231. StartSection(SManDocName);
  1232. Writeln(ModuleName+' \- '+SDocTypes);
  1233. StartSection(SManDocTypes);
  1234. for i := 0 to ASection.Types.Count - 1 do
  1235. begin
  1236. TypeDecl := TPasType(ASection.Types[i]);
  1237. StartSubsection(TypeDecl.Name);
  1238. DescrWriteCodeLine(EscapeText(TypeDecl.GetDeclaration(True)));
  1239. DocNode:=Engine.FindDocNode(TypeDecl);
  1240. If TypeDecl is TPasEnumType then
  1241. WriteEnumElements(TypeDecl as TPasEnumType);
  1242. WriteDescr(TypeDecl,DocNode);
  1243. end;
  1244. StartSection(SDocSeeAlso);
  1245. WriteModuleSeeAlso(False);
  1246. Finally
  1247. EndManPage;
  1248. end;
  1249. end;
  1250. end;
  1251. procedure TManWriter.WriteEnumElements(TypeDecl : TPasEnumType);
  1252. Var
  1253. EV : TPasEnumValue;
  1254. I : Integer;
  1255. DocNode : TDocNode;
  1256. begin
  1257. With TypeDecl do
  1258. begin
  1259. SortElementList(Values);
  1260. Writeln(EscapeText(Format(SDocValuesForEnum,[TypeDecl.Name])));
  1261. Try
  1262. For I:=0 to Values.Count-1 do
  1263. begin
  1264. EV:=TPasEnumValue(Values[i]);
  1265. WriteTP;
  1266. WriteB(EscapeText(EV.Name));
  1267. DocNode := Engine.FindDocNode(EV);
  1268. if Assigned(DocNode) and (not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  1269. WriteDescr(EV,DocNode.ShortDescr);
  1270. end;
  1271. Finally
  1272. NewLine;
  1273. end;
  1274. end;
  1275. end;
  1276. { ---------------------------------------------------------------------
  1277. Variables man page
  1278. ---------------------------------------------------------------------}
  1279. procedure TManWriter.WriteUnitVars(ASection: TPasSection);
  1280. var
  1281. VarDecl: TPasVariable;
  1282. i: Integer;
  1283. DocNode : TDocNode;
  1284. begin
  1285. if ASection.Variables.Count > 0 then
  1286. begin
  1287. StartManpage(ModuleName+'.'+SManVars);
  1288. Try
  1289. PageTitle(Modulename,ManSection,PackageName,PackageDescr);
  1290. StartSection(SManDocName);
  1291. Writeln(ModuleName+' \- '+SDocVariables);
  1292. StartSection(SManDocVariables);
  1293. for i := 0 to ASection.Variables.Count - 1 do
  1294. begin
  1295. VarDecl := TPasVariable(ASection.Variables[i]);
  1296. StartSubSection(VarDecl.Name);
  1297. DescrWriteCodeLine(EscapeText(VarDecl.GetDeclaration(True)));
  1298. DocNode:=Engine.FindDocNode(VarDecl);
  1299. WriteDescr(VarDecl,DocNode);
  1300. end;
  1301. StartSection(SDocSeeAlso);
  1302. WriteModuleSeeAlso(False);
  1303. Finally
  1304. EndManPage;
  1305. end;
  1306. end;
  1307. end;
  1308. { ---------------------------------------------------------------------
  1309. Procedure/Function/Method man page
  1310. ---------------------------------------------------------------------}
  1311. procedure TManWriter.WriteUnitFunctionsAndProceduresOverview(ASection: TPasSection);
  1312. var
  1313. i : Integer;
  1314. DocNode : TDocNode;
  1315. PDecl : TPasProcedureBase;
  1316. begin
  1317. // Overview page
  1318. if ASection.Functions.Count > 0 then
  1319. begin
  1320. StartSection(SManDocFunctions);
  1321. for i := 0 to ASection.Functions.Count - 1 do
  1322. begin
  1323. PDecl:=TPasProcedureBase(ASection.Functions[i]);
  1324. WriteTP;
  1325. WriteB(PDecl.Name);
  1326. DocNode:=Engine.FindDocNode(PDecl);
  1327. If Assigned(DocNode) then
  1328. WriteDescr(PDecl,DocNode.ShortDescr);
  1329. end;
  1330. end;
  1331. end;
  1332. procedure TManWriter.WriteUnitFunctionsAndProcedures(ASection: TPasSection);
  1333. var
  1334. i : Integer;
  1335. begin
  1336. // Pages for all identifiers.
  1337. for i := 0 to ASection.Functions.Count - 1 do
  1338. WriteProcedurePage(TPasProcedure(ASection.Functions[i]));
  1339. end;
  1340. procedure TManWriter.WriteProcedurePage(ProcDecl : TPasProcedureBase);
  1341. var
  1342. DocNode: TDocNode;
  1343. OP : TPasOverloadedProc;
  1344. i : integer;
  1345. D,N : String;
  1346. begin
  1347. N:=ProcDecl.name;
  1348. D:='';
  1349. DocNode := Engine.FindDocNode(ProcDecl);
  1350. StartManpage(ProcDecl,DocNode);
  1351. Try
  1352. PageTitle(ProcDecl.name,ManSection,PackageName,PackageDescr);
  1353. if Assigned(DocNode) then
  1354. D:=GetDescrString(ProcDecl,DocNode.ShortDescr);
  1355. // Name
  1356. StartSection(SManDocName);
  1357. Writeln(N+' \- '+D);
  1358. // Declaration
  1359. StartSection(SManDocSynopsis);
  1360. if ProcDecl is TPasOverloadedProc then
  1361. begin
  1362. OP:=TPasOverloadedProc(ProcDecl);
  1363. for i := 0 to OP.Overloads.Count - 1 do
  1364. begin
  1365. DescrWriteCodeLine(TPasProcedure(OP.Overloads[i]).GetDeclaration(True));
  1366. end;
  1367. end
  1368. else
  1369. DescrWriteCodeLine(ProcDecl.GetDeclaration(True));
  1370. // Visibility
  1371. If Assigned(ProcDecl.Parent) then
  1372. begin
  1373. StartSection(SManDocVisibility);
  1374. Writeln(VisibilityNames[ProcDecl.Visibility])
  1375. end;
  1376. // Arguments, if present.
  1377. If ProcDecl is TPasProcedure then
  1378. AppendProcedureArgsSection(TPasProcedure(ProcDecl).ProcType);
  1379. // Description
  1380. if Assigned(DocNode) then
  1381. begin
  1382. if Assigned(DocNode.Descr) then
  1383. begin
  1384. StartSection(SManDocDescription);
  1385. WriteDescr(ProcDecl,DocNode.Descr);
  1386. end;
  1387. // Errors
  1388. if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
  1389. begin
  1390. StartSection(SManDocErrors);
  1391. WriteDescr(ProcDecl, DocNode.ErrorsDoc);
  1392. end;
  1393. end;
  1394. // Arguments, if present.
  1395. If ProcDecl is TPasFunction then
  1396. AppendProcedureArgsSection(TPasFunction(ProcDecl).ProcType);
  1397. WriteExample(DocNode);
  1398. StartSection(SManDocSeeAlso);
  1399. WriteModuleSeeAlso(True);
  1400. WriteSeeAlso(DocNode,False);
  1401. Finally
  1402. EndManPage;
  1403. end;
  1404. end;
  1405. procedure TManWriter.AppendProcedureArgsSection(Element: TPasProcedureType);
  1406. var
  1407. IsFirst: Boolean;
  1408. DocNode: TDocNode;
  1409. i: Integer;
  1410. Arg: TPasArgument;
  1411. begin
  1412. If Not Assigned(Element) then
  1413. exit;
  1414. IsFirst := True;
  1415. for i := 0 to Element.Args.Count - 1 do
  1416. begin
  1417. Arg := TPasArgument(Element.Args[i]);
  1418. DocNode:=Engine.FindDocNode(Arg);
  1419. if Assigned(DocNode) and (Not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  1420. begin
  1421. if IsFirst then
  1422. begin
  1423. IsFirst:=False;
  1424. StartSection(SManDocArguments);
  1425. end;
  1426. WriteTP;
  1427. WriteB(Arg.Name);
  1428. WriteDescr(Arg,DocNode.ShortDescr);
  1429. end;
  1430. end;
  1431. end;
  1432. procedure TManWriter.AppendFunctionResultSection(Element: TPasFunctionType);
  1433. Var
  1434. ResultEl: TPasResultElement;
  1435. DocNode: TDocNode;
  1436. begin
  1437. If Not Assigned(Element) then
  1438. exit;
  1439. ResultEl := TPasFunctionType(Element).ResultEl;
  1440. DocNode := Engine.FindDocNode(ResultEl);
  1441. If Assigned(DocNode) then
  1442. begin
  1443. if IsDescrNodeEmpty(DocNode.Descr) or not IsDescrNodeEmpty(DocNode.ShortDescr) then
  1444. begin
  1445. StartSection(SManDocResult);
  1446. WriteDescr(ResultEl,DocNode);
  1447. end;
  1448. end;
  1449. end;
  1450. { ---------------------------------------------------------------------
  1451. Property man page
  1452. ---------------------------------------------------------------------}
  1453. procedure TManWriter.WritePropertyPage(PropDecl : TPasProperty);
  1454. var
  1455. DocNode: TDocNode;
  1456. N,D: String;
  1457. begin
  1458. DocNode := Engine.FindDocNode(PropDecl);
  1459. StartManpage(PropDecl,DocNode);
  1460. Try
  1461. N:= PropDecl.Name;
  1462. PageTitle(PropDecl.Name,ManSection,PackageName,PackageDescr);
  1463. if Assigned(DocNode) then
  1464. D:=GetDescrString(PropDecl,DocNode.ShortDescr);
  1465. // Name
  1466. StartSection(SManDocName);
  1467. Writeln(N+' \- '+D);
  1468. // Declaration
  1469. StartSection(SManDocSynopsis);
  1470. WriteLn(PropDecl.GetDeclaration(True));
  1471. // Visibility
  1472. If Assigned(PropDecl.Parent) then
  1473. begin
  1474. StartSection(SManDocVisibility);
  1475. Writeln(VisibilityNames[PropDecl.Visibility])
  1476. end;
  1477. StartSection(SManDocAccess);
  1478. D:='';
  1479. If Length(PropDecl.ReadAccessorName) > 0 then
  1480. D:='Read';
  1481. if Length(PropDecl.WriteAccessorName) > 0 then
  1482. begin
  1483. If D<>'' then
  1484. D:=D+',';
  1485. D:=D+'Write';
  1486. end;
  1487. Writeln(D);
  1488. if Assigned(DocNode) then
  1489. begin
  1490. // Description
  1491. if Assigned(DocNode.Descr) then
  1492. begin
  1493. StartSection(SManDocDescription);
  1494. WriteDescr(PropDecl,DocNode.Descr);
  1495. end;
  1496. // Errors
  1497. if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
  1498. begin
  1499. StartSection(SManDocErrors);
  1500. WriteDescr(PropDecl, DocNode.ErrorsDoc);
  1501. end;
  1502. WriteExample(DocNode);
  1503. WriteSeeAlso(DocNode,False);
  1504. end;
  1505. Finally
  1506. EndManPage;
  1507. end;
  1508. end;
  1509. Function CompareElements(P1,P2 : Pointer) : Integer;
  1510. begin
  1511. Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
  1512. end;
  1513. procedure TManWriter.SortElementList(List : TFPList);
  1514. begin
  1515. List.Sort(@CompareElements);
  1516. end;
  1517. procedure TManWriter.WriteCommentLine;
  1518. begin
  1519. WriteComment('-------------------------------------------------------');
  1520. end;
  1521. procedure TManWriter.WriteComment(Comment : String);
  1522. begin
  1523. Writeln('." '+Comment);
  1524. end;
  1525. class function TManWriter.FileNameExtension: String;
  1526. begin
  1527. Result:=IntToStr(DefaultManSection);
  1528. end;
  1529. procedure TManWriter.WriteClassMethodOverview(ClassDecl: TPasClassType);
  1530. var
  1531. Member : TPasElement;
  1532. i : Integer;
  1533. DocNode : TDocNode;
  1534. List : TStringList;
  1535. begin
  1536. List:=TStringList.Create;
  1537. Try
  1538. GetMethodList(ClassDecl,List);
  1539. If List.Count>0 then
  1540. begin
  1541. StartSection(SManDocMethods);
  1542. For I:=0 to List.Count-1 do
  1543. begin
  1544. Member:=TPasElement(List.Objects[i]);
  1545. WriteTP;
  1546. WriteB(EscapeText(Member.Name));
  1547. DocNode := Engine.FindDocNode(Member);
  1548. If Assigned(DocNode) then
  1549. WriteDescr(Member, DocNode.ShortDescr)
  1550. end;
  1551. end;
  1552. Finally
  1553. List.Free;
  1554. end;
  1555. end;
  1556. Class procedure TManWriter.Usage(List: TStrings);
  1557. begin
  1558. List.add('--nounitprefix');
  1559. List.Add(SManUsageNoUnitPrefix);
  1560. List.add('--man-section=ASection');
  1561. List.Add(SManUsageManSection);
  1562. List.Add('--man-description=descr');
  1563. List.Add(SManUsagePackageDescription);
  1564. end;
  1565. initialization
  1566. // Do not localize.
  1567. RegisterWriter(TMANWriter,'man',SManUsageWriterDescr);
  1568. finalization
  1569. UnRegisterWriter('man');
  1570. end.