3
FPDoc - Free Pascal Documentation Tool
4
Copyright (C) 2000 - 2003 by
5
Areca Systems GmbH / Sebastian Guenther, sg@freepascal.org
7
* Output string definitions
8
* Basic writer (output generator) class
10
See the file COPYING, included in this distribution,
11
for details about the copyright.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26
uses Classes, DOM, dGlobals, PasTree, SysUtils;
29
SErrFileWriting = 'An error occured during writing of file "%s": %s';
31
SErrInvalidShortDescr = 'Invalid short description';
32
SErrInvalidDescr = 'Invalid description (illegal XML element: "%s")';
33
SErrInvalidParaContent = 'Invalid paragraph content';
34
SErrInvalidElementInList = 'Invalid element in list - only "li" allowed';
35
SErrInvalidListContent = 'Invalid list content';
36
SErrInvalidRemarkContent = 'Invalid <remark> content (illegal XML element: "%s")';
37
SErrListIsEmpty = 'List is empty - need at least one "li" element';
38
SErrInvalidDefinitionTermContent = 'Invalid content in definition term';
39
SErrDefinitionEntryMissing = 'Definition entry after definition term is missing';
40
SErrInvalidBorderValue = 'Invalid "border" value for %s';
41
SErrInvalidTableContent = 'Invalid table content';
42
SErrTableRowEmpty = 'Table row is empty (no "td" elements found)';
43
SErrInvalidContentBeforeSectionTitle = 'Invalid content before section title';
44
SErrSectionTitleExpected = 'Section title ("title" element) expected';
46
SErrDescrTagUnknown = 'Warning: Unknown tag "%s" in description';
47
SErrUnknownEntityReference = 'Warning: Unknown entity reference "&%s;" found';
48
SErrUnknownLinkID = 'Warning: Target ID of <link> is unknown: "%s"';
49
SErrUnknownPrintShortID = 'Warning: Target ID of <printshort> is unknown: "%s"';
50
SErrUnknownLink = 'Could not resolve link to "%s"';
51
SErralreadyRegistered = 'Class for output format "%s" already registered';
52
SErrUnknownWriterClass = 'Unknown output format "%s"';
55
// Phony element for pas pages.
57
TTopicElement = Class(TPaselement)
58
Constructor Create(const AName: String; AParent: TPasElement); override;
59
Destructor Destroy; override;
70
FEngine : TFPDocEngine;
71
FPackage : TPasPackage;
76
procedure Warning(AContext: TPasElement; const AMsg: String);
77
procedure Warning(AContext: TPasElement; const AMsg: String;
78
const Args: array of const);
80
// function FindShortDescr(const Name: String): TDOMElement;
82
// Description conversion
83
function IsDescrNodeEmpty(Node: TDOMNode): Boolean;
84
function IsExtShort(Node: TDOMNode): Boolean;
85
function ConvertShort(AContext: TPasElement; El: TDOMElement): Boolean;
86
function ConvertBaseShort(AContext: TPasElement; Node: TDOMNode): Boolean;
87
procedure ConvertBaseShortList(AContext: TPasElement; Node: TDOMNode;
89
procedure ConvertLink(AContext: TPasElement; El: TDOMElement);
90
function ConvertExtShort(AContext: TPasElement; Node: TDOMNode): Boolean;
91
procedure ConvertDescr(AContext: TPasElement; El: TDOMElement;
92
AutoInsertBlock: Boolean);
93
function ConvertNonSectionBlock(AContext: TPasElement;
94
Node: TDOMNode): Boolean;
95
procedure ConvertExtShortOrNonSectionBlocks(AContext: TPasElement;
97
function ConvertSimpleBlock(AContext: TPasElement; Node: TDOMNode): Boolean;
98
Function FindTopicElement(Node : TDocNode): TTopicElement;
100
procedure DescrWriteText(const AText: DOMString); virtual; abstract;
101
procedure DescrBeginBold; virtual; abstract;
102
procedure DescrEndBold; virtual; abstract;
103
procedure DescrBeginItalic; virtual; abstract;
104
procedure DescrEndItalic; virtual; abstract;
105
procedure DescrBeginEmph; virtual; abstract;
106
procedure DescrEndEmph; virtual; abstract;
107
procedure DescrWriteFileEl(const AText: DOMString); virtual; abstract;
108
procedure DescrWriteKeywordEl(const AText: DOMString); virtual; abstract;
109
procedure DescrWriteVarEl(const AText: DOMString); virtual; abstract;
110
procedure DescrBeginLink(const AId: DOMString); virtual; abstract;
111
procedure DescrEndLink; virtual; abstract;
112
procedure DescrWriteLinebreak; virtual; abstract;
113
procedure DescrBeginParagraph; virtual; abstract;
114
procedure DescrEndParagraph; virtual; abstract;
115
procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); virtual; abstract;
116
procedure DescrWriteCodeLine(const ALine: String); virtual; abstract;
117
procedure DescrEndCode; virtual; abstract;
118
procedure DescrBeginOrderedList; virtual; abstract;
119
procedure DescrEndOrderedList; virtual; abstract;
120
procedure DescrBeginUnorderedList; virtual; abstract;
121
procedure DescrEndUnorderedList; virtual; abstract;
122
procedure DescrBeginDefinitionList; virtual; abstract;
123
procedure DescrEndDefinitionList; virtual; abstract;
124
procedure DescrBeginListItem; virtual; abstract;
125
procedure DescrEndListItem; virtual; abstract;
126
procedure DescrBeginDefinitionTerm; virtual; abstract;
127
procedure DescrEndDefinitionTerm; virtual; abstract;
128
procedure DescrBeginDefinitionEntry; virtual; abstract;
129
procedure DescrEndDefinitionEntry; virtual; abstract;
130
procedure DescrBeginSectionTitle; virtual; abstract;
131
procedure DescrBeginSectionBody; virtual; abstract;
132
procedure DescrEndSection; virtual; abstract;
133
procedure DescrBeginRemark; virtual; abstract;
134
procedure DescrEndRemark; virtual; abstract;
135
procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); virtual; abstract;
136
procedure DescrEndTable; virtual; abstract;
137
procedure DescrBeginTableCaption; virtual; abstract;
138
procedure DescrEndTableCaption; virtual; abstract;
139
procedure DescrBeginTableHeadRow; virtual; abstract;
140
procedure DescrEndTableHeadRow; virtual; abstract;
141
procedure DescrBeginTableRow; virtual; abstract;
142
procedure DescrEndTableRow; virtual; abstract;
143
procedure DescrBeginTableCell; virtual; abstract;
144
procedure DescrEndTableCell; virtual; abstract;
146
Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); virtual;
147
destructor Destroy; override;
148
property Engine : TFPDocEngine read FEngine;
149
Property Package : TPasPackage read FPackage;
150
Property Topics : TList Read FTopics;
151
// Should return True if option was succesfully interpreted.
152
Function InterpretOption(Const Cmd,Arg : String) : Boolean; Virtual;
153
Class Procedure Usage(List : TStrings); virtual;
154
procedure WriteDoc; virtual; Abstract;
155
procedure WriteDescr(Element: TPasElement);
156
procedure WriteDescr(Element: TPasElement; DocNode: TDocNode);
157
procedure WriteDescr(AContext: TPasElement; DescrNode: TDOMElement); virtual;
158
Procedure FPDocError(Msg : String);
159
Procedure FPDocError(Fmt : String; Args : Array of Const);
160
Function ShowMember(M : TPasElement) : boolean;
161
Procedure GetMethodList(ClassDecl: TPasClassType; List : TStringList);
164
TFPDocWriterClass = Class of TFPDocWriter;
165
EFPDocWriterError = Class(Exception);
168
Procedure RegisterWriter(AClass : TFPDocWriterClass; Const AName,ADescr : String);
169
// UnRegister backend
170
Procedure UnRegisterWriter(Const AName : String);
171
// Return back end class. Exception if not found.
172
Function GetWriterClass(AName : String) : TFPDocWriterClass;
173
// Return index of back end class.
174
Function FindWriterClass(AName : String) : Integer;
175
// List of backend in name=descr form.
176
Procedure EnumWriters(List : TStrings);
181
{ ---------------------------------------------------------------------
183
---------------------------------------------------------------------}
189
TWriterRecord = Class(TObject)
191
FClass : TFPDocWriterClass;
193
FDescription : String;
195
Constructor Create (AClass : TFPDocWriterClass; Const AName,ADescr : String);
200
constructor TWriterRecord.Create(AClass: TFPDocWriterClass; const AName,
205
FDescription:=ADescr;
209
Writers : TStringList;
211
Procedure InitWriterList;
214
Writers:=TStringList.Create;
215
Writers.Sorted:=True;
218
Procedure DoneWriterList;
224
For I:=Writers.Count-1 downto 0 do
225
Writers.Objects[i].Free;
229
procedure RegisterWriter(AClass : TFPDocWriterClass; Const AName, ADescr : String);
231
If Writers.IndexOf(AName)<>-1 then
232
Raise EFPDocWriterError.CreateFmt(SErralreadyRegistered,[ANAme]);
233
Writers.AddObject(AName,TWriterRecord.Create(AClass,AName,ADescr));
236
function FindWriterClass(AName : String) : Integer;
239
Result:=Writers.IndexOf(AName);
242
function GetWriterClass(AName : String) : TFPDocWriterClass;
248
Index:=FindWriterClass(AName);
250
Raise EFPDocWriterError.CreateFmt(SErrUnknownWriterClass,[ANAme]);
251
Result:=(Writers.Objects[Index] as TWriterRecord).FClass;
254
// UnRegister backend
256
Procedure UnRegisterWriter(Const AName : String);
261
Index:=Writers.IndexOf(AName);
263
Raise EFPDocWriterError.CreateFmt(SErrUnknownWriterClass,[ANAme]);
264
Writers.Objects[Index].Free;
265
Writers.Delete(Index);
269
Procedure EnumWriters(List : TStrings);
276
For I:=0 to Writers.Count-1 do
277
With (Writers.Objects[I] as TWriterRecord) do
278
List.Add(FName+'='+FDescription);
281
function IsWhitespaceNode(Node: TDOMText): Boolean;
293
While Result and (I<L) do
295
Result:=P^ in [#32,#10,#9,#13];
302
{ ---------------------------------------------------------------------
304
---------------------------------------------------------------------}
308
if Length(Engine.Output) = 0 then
309
WriteLn(SCmdLineOutputOptionMissing)
311
CreateIPFDocForPackage(Engine.Package, Engine);
316
Constructor TFPDocWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
321
FPackage := APackage;
322
FTopics:=Tlist.Create;
325
destructor TFPDocWriter.Destroy;
331
For I:=0 to FTopics.Count-1 do
332
TTopicElement(FTopics[i]).Free;
337
function TFPDocWriter.InterpretOption(Const Cmd,Arg : String): Boolean;
342
Class procedure TFPDocWriter.Usage(List: TStrings);
347
Function TFPDocWriter.FindTopicElement(Node : TDocNode): TTopicElement;
355
While (I>=0) and (Result=Nil) do
357
If (TTopicElement(FTopics[i]).TopicNode=Node) Then
358
Result:=TTopicElement(FTopics[i]);
363
{ ---------------------------------------------------------------------
364
Generic documentation node conversion
365
---------------------------------------------------------------------}
367
function IsContentNodeType(Node: TDOMNode): Boolean;
369
Result := (Node.NodeType = ELEMENT_NODE) or
370
((Node.NodeType = TEXT_NODE) and not IsWhitespaceNode(TDOMText(Node))) or
371
(Node.NodeType = ENTITY_REFERENCE_NODE);
375
procedure TFPDocWriter.Warning(AContext: TPasElement; const AMsg: String);
377
if (AContext<>nil) then
378
WriteLn('[', AContext.PathName, '] ', AMsg)
380
WriteLn('[<no context>] ', AMsg);
383
procedure TFPDocWriter.Warning(AContext: TPasElement; const AMsg: String;
384
const Args: array of const);
386
Warning(AContext, Format(AMsg, Args));
389
function TFPDocWriter.IsDescrNodeEmpty(Node: TDOMNode): Boolean;
393
if (not Assigned(Node)) or (not Assigned(Node.FirstChild)) then
397
Child := Node.FirstChild;
398
while Assigned(Child) do
400
if (Child.NodeType = ELEMENT_NODE) or (Child.NodeType = TEXT_NODE) or
401
(Child.NodeType = ENTITY_REFERENCE_NODE) then
406
Child := Child.NextSibling;
412
{ Check wether the nodes starting with the node given as argument make up an
413
'extshort' production. }
414
function TFPDocWriter.IsExtShort(Node: TDOMNode): Boolean;
416
while Assigned(Node) do
418
if Node.NodeType = ELEMENT_NODE then
419
if (Node.NodeName <> 'br') and
420
(Node.NodeName <> 'link') and
421
(Node.NodeName <> 'b') and
422
(Node.NodeName <> 'file') and
423
(Node.NodeName <> 'i') and
424
(Node.NodeName <> 'kw') and
425
(Node.NodeName <> 'printshort') and
426
(Node.NodeName <> 'var') then
431
Node := Node.NextSibling;
436
function TFPDocWriter.ConvertShort(AContext: TPasElement;
437
El: TDOMElement): Boolean;
442
if not Assigned(El) then
445
Node := El.FirstChild;
446
while Assigned(Node) do
448
if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'link') then
449
ConvertLink(AContext, TDOMElement(Node))
451
if not ConvertBaseShort(AContext, Node) then
453
Node := Node.NextSibling;
458
function TFPDocWriter.ConvertBaseShort(AContext: TPasElement;
459
Node: TDOMNode): Boolean;
461
function ConvertText: DOMString;
466
if Node.NodeType = TEXT_NODE then
470
SetLength(Result, 0);
471
while i <= Length(s) do
474
Result := Result + ' ';
478
end else if s[i] = #10 then
480
Result := Result + ' ';
484
Result := Result + s[i];
487
end else if Node.NodeType = ENTITY_REFERENCE_NODE then
488
if Node.NodeName = 'fpc' then
489
Result := 'Free Pascal'
490
else if Node.NodeName = 'delphi' then
494
Warning(AContext, Format(SErrUnknownEntityReference, [Node.NodeName]));
495
Result := Node.NodeName;
497
else if Node.NodeType = ELEMENT_NODE then
498
SetLength(Result, 0);
501
function ConvertTextContent: DOMString;
503
SetLength(Result, 0);
504
Node := Node.FirstChild;
505
while Assigned(Node) do
507
Result := Result + ConvertText;
508
Node := Node.NextSibling;
513
El, DescrEl: TDOMElement;
517
if Node.NodeType = ELEMENT_NODE then
518
if Node.NodeName = 'b' then
521
ConvertBaseShortList(AContext, Node, False);
524
if Node.NodeName = 'i' then
527
ConvertBaseShortList(AContext, Node, False);
530
if Node.NodeName = 'em' then
533
ConvertBaseShortList(AContext, Node, False);
536
if Node.NodeName = 'file' then
537
DescrWriteFileEl(ConvertTextContent)
538
else if Node.NodeName = 'kw' then
539
DescrWriteKeywordEl(ConvertTextContent)
540
else if Node.NodeName = 'printshort' then
542
El := TDOMElement(Node);
543
DescrEl := Engine.FindShortDescr(AContext.GetModule, El['id']);
544
if Assigned(DescrEl) then
545
ConvertShort(AContext, DescrEl)
548
Warning(AContext, Format(SErrUnknownPrintShortID, [El['id']]));
550
DescrWriteText('#ShortDescr:' + El['id']);
553
end else if Node.NodeName = 'var' then
554
DescrWriteVarEl(ConvertTextContent)
558
DescrWriteText(ConvertText);
561
procedure TFPDocWriter.ConvertBaseShortList(AContext: TPasElement;
562
Node: TDOMNode; MayBeEmpty: Boolean);
566
Child := Node.FirstChild;
567
while Assigned(Child) do
569
if not ConvertBaseShort(AContext, Child) then
570
Warning(AContext, SErrInvalidShortDescr)
573
Child := Child.NextSibling;
575
if not MayBeEmpty then
576
Warning(AContext, SErrInvalidShortDescr)
579
procedure TFPDocWriter.ConvertLink(AContext: TPasElement; El: TDOMElement);
581
DescrBeginLink(El['id']);
582
if not IsDescrNodeEmpty(El) then
583
ConvertBaseShortList(AContext, El, True)
585
DescrWriteText(El['id']);
589
function TFPDocWriter.ConvertExtShort(AContext: TPasElement;
590
Node: TDOMNode): Boolean;
594
while Assigned(Node) do
596
if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'link') then
597
ConvertLink(AContext, TDOMElement(Node))
598
else if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'br') then
601
if not ConvertBaseShort(AContext, Node) then
603
Node := Node.NextSibling;
608
procedure TFPDocWriter.ConvertDescr(AContext: TPasElement; El: TDOMElement;
609
AutoInsertBlock: Boolean);
611
Node, Child: TDOMNode;
612
ParaCreated: Boolean;
614
if AutoInsertBlock then
615
if IsExtShort(El.FirstChild) then
618
AutoInsertBlock := False;
620
Node := El.FirstChild;
621
if not ConvertExtShort(AContext, Node) then
623
while Assigned(Node) do
625
if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'section') then
627
DescrBeginSectionTitle;
628
Child := Node.FirstChild;
629
while Assigned(Child) and (Child.NodeType <> ELEMENT_NODE) do
631
if not IsDescrNodeEmpty(Child) then
632
Warning(AContext, SErrInvalidContentBeforeSectionTitle);
633
Child := Child.NextSibling;
635
if not Assigned(Child) or (Child.NodeName <> 'title') then
636
Warning(AContext, SErrSectionTitleExpected)
638
ConvertShort(AContext, TDOMElement(Child));
640
DescrBeginSectionBody;
642
if IsExtShort(Child) then
647
ParaCreated := False;
649
ConvertExtShortOrNonSectionBlocks(AContext, Child.NextSibling);
654
end else if not ConvertNonSectionBlock(AContext, Node) then
655
Warning(AContext, SErrInvalidDescr, [Node.NodeName]);
656
Node := Node.NextSibling;
659
if AutoInsertBlock then
663
procedure TFPDocWriter.ConvertExtShortOrNonSectionBlocks(AContext: TPasElement;
666
if not ConvertExtShort(AContext, Node) then
667
while Assigned(Node) do
669
if not ConvertNonSectionBlock(AContext, Node) then
670
Warning(AContext, SErrInvalidDescr, [Node.NodeName]);
671
Node := Node.NextSibling;
675
function TFPDocWriter.ConvertNonSectionBlock(AContext: TPasElement;
676
Node: TDOMNode): Boolean;
678
procedure ConvertCells(Node: TDOMNode);
683
Node := Node.FirstChild;
685
while Assigned(Node) do
687
if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'td') then
690
Child := Node.FirstChild;
691
if not ConvertExtShort(AContext, Child) then
692
while Assigned(Child) do
694
if not ConvertSimpleBlock(AContext, Child) then
695
Warning(AContext, SErrInvalidTableContent);
696
Child := Child.NextSibling;
701
if IsContentNodeType(Node) then
702
Warning(AContext, SErrInvalidTableContent);
703
Node := Node.NextSibling;
706
Warning(AContext, SErrTableRowEmpty);
709
procedure ConvertTable;
711
function GetColCount(Node: TDOMNode): Integer;
714
Node := Node.FirstChild;
715
while Assigned(Node) do
717
if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'td') then
719
Node := Node.NextSibling;
725
HasBorder, CaptionPossible, HeadRowPossible: Boolean;
726
ColCount, ThisRowColCount: Integer;
729
s := TDOMElement(Node)['border'];
735
if (Length(s) <> 0) and (s <> '0') then
736
Warning(AContext, SErrInvalidBorderValue, ['<table>']);
739
// Determine the number of columns
741
Subnode := Node.FirstChild;
742
while Assigned(Subnode) do
744
if Subnode.NodeType = ELEMENT_NODE then
745
if (Subnode.NodeName = 'caption') or (Subnode.NodeName = 'th') or
746
(Subnode.NodeName = 'tr') then
748
ThisRowColCount := GetColCount(Subnode);
749
if ThisRowColCount > ColCount then
750
ColCount := ThisRowColCount;
752
Subnode := Subnode.NextSibling;
755
DescrBeginTable(ColCount, HasBorder);
757
Node := Node.FirstChild;
758
CaptionPossible := True;
759
HeadRowPossible := True;
760
while Assigned(Node) do
762
if Node.NodeType = ELEMENT_NODE then
763
if CaptionPossible and (Node.NodeName = 'caption') then
765
DescrBeginTableCaption;
766
if not ConvertExtShort(AContext, Node.FirstChild) then
767
Warning(AContext, SErrInvalidTableContent);
768
DescrEndTableCaption;
769
CaptionPossible := False;
770
end else if HeadRowPossible and (Node.NodeName = 'th') then
772
DescrBeginTableHeadRow;
774
DescrEndTableHeadRow;
775
CaptionPossible := False;
776
HeadRowPossible := False;
777
end else if Node.NodeName = 'tr' then
783
Warning(AContext, SErrInvalidTableContent)
784
else if IsContentNodeType(Node) then
785
Warning(AContext, SErrInvalidTableContent);
786
Node := Node.NextSibling;
792
if Node.NodeType <> ELEMENT_NODE then
794
if Node.NodeType = TEXT_NODE then
795
Result := IsWhitespaceNode(TDOMText(Node))
797
Result := Node.NodeType = COMMENT_NODE;
800
if Node.NodeName = 'remark' then
803
Node := Node.FirstChild;
804
if not ConvertExtShort(AContext, Node) then
805
while Assigned(Node) do
807
if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'table') then
810
if not ConvertSimpleBlock(AContext, Node) then
811
Warning(AContext, SErrInvalidRemarkContent, [Node.NodeName]);
812
Node := Node.NextSibling;
816
end else if Node.NodeName = 'table' then
821
Result := ConvertSimpleBlock(AContext, Node);
824
function TFPDocWriter.ConvertSimpleBlock(AContext: TPasElement;
825
Node: TDOMNode): Boolean;
827
procedure ConvertListItems;
831
Node := Node.FirstChild;
833
while Assigned(Node) do
835
if ((Node.NodeType = TEXT_NODE) and not IsWhitespaceNode(TDOMText(Node))) or (Node.NodeType = ENTITY_REFERENCE_NODE)
837
Warning(AContext, SErrInvalidListContent)
838
else if Node.NodeType = ELEMENT_NODE then
839
if Node.NodeName = 'li' then
842
ConvertExtShortOrNonSectionBlocks(AContext, Node.FirstChild);
846
Warning(AContext, SErrInvalidElementInList);
847
Node := Node.NextSibling;
850
Warning(AContext, SErrListIsEmpty);
853
procedure ConvertDefinitionList;
855
Empty, ExpectDTNext: Boolean;
857
Node := Node.FirstChild;
859
ExpectDTNext := True;
860
while Assigned(Node) do
862
if ((Node.NodeType = TEXT_NODE) and not IsWhitespaceNode(TDOMText(Node))) or (Node.NodeType = ENTITY_REFERENCE_NODE)
864
Warning(AContext, SErrInvalidListContent)
865
else if Node.NodeType = ELEMENT_NODE then
866
if ExpectDTNext and (Node.NodeName = 'dt') then
868
DescrBeginDefinitionTerm;
869
if not ConvertShort(AContext, TDOMElement(Node)) then
870
Warning(AContext, SErrInvalidDefinitionTermContent);
871
DescrEndDefinitionTerm;
873
ExpectDTNext := False;
874
end else if not ExpectDTNext and (Node.NodeName = 'dd') then
876
DescrBeginDefinitionEntry;
877
ConvertExtShortOrNonSectionBlocks(AContext, Node.FirstChild);
878
DescrEndDefinitionEntry;
879
ExpectDTNext := True;
881
Warning(AContext, SErrInvalidElementInList);
882
Node := Node.NextSibling;
885
Warning(AContext, SErrListIsEmpty)
886
else if not ExpectDTNext then
887
Warning(AContext, SErrDefinitionEntryMissing);
890
procedure ProcessCodeBody(Node: TDOMNode);
895
Node := Node.FirstChild;
897
while Assigned(Node) do
899
if Node.NodeType = TEXT_NODE then
901
s := s + Node.NodeValue;
903
for i := 1 to Length(s) do
904
// In XML, linefeeds are normalized to #10 by the parser!
907
DescrWriteCodeLine(Copy(s, j, i - j));
911
s := Copy(s, j, Length(s));
913
Node := Node.NextSibling;
915
if Length(s) > 0 then
916
DescrWriteCodeLine(s);
923
if Node.NodeType <> ELEMENT_NODE then
925
Result := (Node.NodeType = TEXT_NODE) and IsWhitespaceNode(TDOMText(Node));
928
if Node.NodeName = 'p' then
931
if not ConvertExtShort(AContext, Node.FirstChild) then
932
Warning(AContext, SErrInvalidParaContent);
935
end else if Node.NodeName = 'code' then
937
s := TDOMElement(Node)['border'];
942
if (Length(s) > 0) and (s <> '0') then
943
Warning(AContext, SErrInvalidBorderValue, ['<code>']);
946
DescrBeginCode(HasBorder, TDOMElement(Node)['highlighter']);
947
ProcessCodeBody(Node);
950
end else if Node.NodeName = 'pre' then
952
DescrBeginCode(False, 'none');
953
ProcessCodeBody(Node);
956
end else if Node.NodeName = 'ul' then
958
DescrBeginUnorderedList;
960
DescrEndUnorderedList;
962
end else if Node.NodeName = 'ol' then
964
DescrBeginOrderedList;
968
end else if Node.NodeName = 'dl' then
970
DescrBeginDefinitionList;
971
ConvertDefinitionList;
972
DescrEndDefinitionList;
978
Constructor TTopicElement.Create(const AName: String; AParent: TPasElement);
981
Inherited Create(AName,AParent);
982
SubTopics:=TList.Create;
985
Destructor TTopicElement.Destroy;
988
// Actual subtopics are freed by TFPDocWriter Topics list.
993
procedure TFPDocWriter.WriteDescr(Element: TPasElement);
996
WriteDescr(ELement,Engine.FindDocNode(Element));
999
procedure TFPDocWriter.WriteDescr(Element: TPasElement; DocNode: TDocNode);
1002
if Assigned(DocNode) then
1004
if not IsDescrNodeEmpty(DocNode.Descr) then
1005
WriteDescr(Element, DocNode.Descr)
1006
else if not IsDescrNodeEmpty(DocNode.ShortDescr) then
1007
WriteDescr(Element, DocNode.ShortDescr);
1011
procedure TFPDocWriter.WriteDescr(AContext: TPasElement; DescrNode: TDOMElement);
1013
if Assigned(DescrNode) then
1014
ConvertDescr(AContext, DescrNode, False);
1017
procedure TFPDocWriter.FPDocError(Msg: String);
1019
Raise EFPDocWriterError.Create(Msg);
1022
procedure TFPDocWriter.FPDocError(Fmt: String; Args: array of const);
1024
FPDocError(Format(Fmt,Args));
1027
function TFPDocWriter.ShowMember(M: TPasElement): boolean;
1029
Result:=not ((M.Visibility=visPrivate) and Engine.HidePrivate);
1031
Result:=Not ((M.Visibility=visProtected) and Engine.HideProtected)
1034
Procedure TFPDocWriter.GetMethodList(ClassDecl: TPasClassType; List : TStringList);
1043
for i := 0 to ClassDecl.Members.Count - 1 do
1045
M:=TPasElement(ClassDecl.Members[i]);
1046
if M.InheritsFrom(TPasProcedureBase) and ShowMember(M) then
1047
List.AddObject(M.Name,M);