Skip to content

Commit bbaca9d

Browse files
committed
Fix bugs in rendering of source code comments
Revised TActiveTextTextRenderer and made more customisable. Heavily revised code used in TSourceComments to generate source code comments from snippet description active text. Also increased indent size. Update UTextSnippetDoc re change in TActiveTextTextRenderer & increased indent size.
1 parent 9b947ed commit bbaca9d

File tree

3 files changed

+75
-69
lines changed

3 files changed

+75
-69
lines changed

Src/ActiveText.UTextRenderer.pas

Lines changed: 38 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,21 @@ interface
2121

2222
type
2323
TActiveTextTextRenderer = class(TObject)
24-
public
24+
strict private
2525
const
2626
/// <summary>Special space character used to indicate the start of a list
2727
/// item.</summary>
2828
/// <remarks>This special character is a necessary kludge because some
29-
/// c odethat renders active text as formatted plain text strips away
29+
/// code that renders active text as formatted plain text strips away
3030
/// leading #32 characters as part of the formatting process. Therefore
3131
/// indentation in list items is lost if #32 characters are used for it.
32-
/// NBSP was chosen since it should render the same as a space if calling
33-
/// code doesn't convert it.</remarks>
32+
/// NBSP was chosen since it should render the same as a space if not
33+
/// removed.</remarks>
3434
LISpacer = NBSP; // Do not localise. Must be <> #32
3535
/// <summary>Bullet character used when rendering unordered list items.
3636
/// </summary>
3737
Bullet = '*'; // Do not localise. Must be <> #32 and <> LISpacer
38-
strict private
39-
const
40-
IndentDelta = 2;
38+
DefaultIndentDelta = 2;
4139
type
4240
TListKind = (lkNumber, lkBullet);
4341
TListState = record
@@ -60,6 +58,7 @@ TLIState = record
6058
fIndent: UInt16;
6159
fInPara: Boolean;
6260
fInListItem: Boolean;
61+
fIndentDelta: UInt8;
6362
function CanEmitInline: Boolean;
6463
procedure AppendToPara(const AText: string);
6564
procedure InitialiseRender;
@@ -75,9 +74,10 @@ TLIState = record
7574
destructor Destroy; override;
7675
property DisplayURLs: Boolean read fDisplayURLs write fDisplayURLs
7776
default False;
78-
function RenderWrapped(ActiveText: IActiveText; const PageWidth, LMargin,
79-
ParaOffset: Cardinal; const Prefix: string = '';
80-
const Suffix: string = ''): string;
77+
property IndentDelta: UInt8 read fIndentDelta write fIndentDelta
78+
default DefaultIndentDelta;
79+
function RenderWrapped(ActiveText: IActiveText; const PageWidth,
80+
LMargin: Cardinal): string;
8181
end;
8282

8383

@@ -122,6 +122,7 @@ constructor TActiveTextTextRenderer.Create;
122122
fIndent := 0;
123123
fInPara := False;
124124
fInListItem := False;
125+
fIndentDelta := DefaultIndentDelta;
125126
end;
126127

127128
destructor TActiveTextTextRenderer.Destroy;
@@ -200,6 +201,21 @@ function TActiveTextTextRenderer.Render(ActiveText: IActiveText): string;
200201

201202
procedure TActiveTextTextRenderer.RenderBlockActionElem(
202203
Elem: IActiveTextActionElem);
204+
205+
procedure OpenListContainer(const ListKind: TListKind);
206+
begin
207+
if (fListStack.Count > 0) and (fInPara) then
208+
OutputParagraph;
209+
fListStack.Push(TListState.Create(ListKind));
210+
Inc(fIndent, IndentDelta);
211+
end;
212+
213+
procedure AddListMarker(const Marker: string);
214+
begin
215+
fParaBuilder.Append(Marker);
216+
fParaBuilder.Append(StringOfChar(NBSP, IndentDelta - Length(Marker)));
217+
end;
218+
203219
var
204220
ListState: TListState;
205221
begin
@@ -208,22 +224,12 @@ procedure TActiveTextTextRenderer.RenderBlockActionElem(
208224
begin
209225
fBlocksStack.Push(Elem.Kind);
210226
case Elem.Kind of
211-
ekPara: {Do nothing} ;
212-
ekHeading: {Do nothing} ;
227+
ekPara, ekHeading, ekBlock:
228+
{Do nothing} ;
213229
ekUnorderedList:
214-
begin
215-
if (fListStack.Count > 0) and (fInPara) then
216-
OutputParagraph;
217-
fListStack.Push(TListState.Create(lkBullet));
218-
Inc(fIndent, IndentDelta);
219-
end;
230+
OpenListContainer(lkBullet);
220231
ekOrderedList:
221-
begin
222-
if (fListStack.Count > 0) and (fInPara) then
223-
OutputParagraph;
224-
fListStack.Push(TListState.Create(lkNumber));
225-
Inc(fIndent, IndentDelta);
226-
end;
232+
OpenListContainer(lkNumber);
227233
ekListItem:
228234
begin
229235
// Update list number of current list
@@ -235,34 +241,19 @@ procedure TActiveTextTextRenderer.RenderBlockActionElem(
235241
// Act depending on current list kind
236242
case fListStack.Peek.ListKind of
237243
lkNumber:
238-
begin
239-
// Number list: start a new numbered item, with current number
240-
fParaBuilder.Append(IntToStr(fListStack.Peek.ListNumber));
241-
fParaBuilder.Append(NBSP);
242-
end;
244+
AddListMarker(IntToStr(fListStack.Peek.ListNumber));
243245
lkBullet:
244-
begin
245-
// Bullet list: start a new bullet point
246-
fParaBuilder.Append(Bullet + NBSP);
247-
end;
246+
AddListMarker(Bullet);
248247
end;
249248
end;
250249
end;
251250
end;
252251
fsClose:
253252
begin
254253
case Elem.Kind of
255-
ekPara:
254+
ekPara, ekHeading, ekBlock:
256255
OutputParagraph;
257-
ekHeading:
258-
OutputParagraph;
259-
ekUnorderedList:
260-
begin
261-
OutputParagraph;
262-
fListStack.Pop;
263-
Dec(fIndent, IndentDelta);
264-
end;
265-
ekOrderedList:
256+
ekUnorderedList, ekOrderedList:
266257
begin
267258
OutputParagraph;
268259
fListStack.Pop;
@@ -315,7 +306,7 @@ procedure TActiveTextTextRenderer.RenderURL(Elem: IActiveTextActionElem);
315306
end;
316307

317308
function TActiveTextTextRenderer.RenderWrapped(ActiveText: IActiveText;
318-
const PageWidth, LMargin, ParaOffset: Cardinal; const Prefix, Suffix: string):
309+
const PageWidth, LMargin: Cardinal):
319310
string;
320311
var
321312
Paras: IStringList;
@@ -367,13 +358,13 @@ function TActiveTextTextRenderer.RenderWrapped(ActiveText: IActiveText;
367358

368359
begin
369360
Result := '';
370-
Paras := TIStringList.Create(Prefix + Render(ActiveText) + Suffix, EOL, True);
361+
Paras := TIStringList.Create(Render(ActiveText), EOL, True);
371362
for Para in Paras do
372363
begin
373364
if IsListItem then
374365
begin
375-
Offset := -ParaOffset;
376-
ParaIndent := CalcParaIndent + LMargin + ParaOffset;
366+
Offset := -IndentDelta;
367+
ParaIndent := CalcParaIndent + LMargin + IndentDelta;
377368
end
378369
else
379370
begin

Src/USourceGen.pas

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ TSourceComments = class(TNoConstructObject)
4141
/// maximum width indented by the given number of spaces on the left,
4242
/// optionally truncated to the first paragraph.</summary>
4343
class function FormatActiveTextCommentInner(ActiveText: IActiveText;
44-
const Indent: Cardinal; const Truncate: Boolean): string;
44+
const LineWidth: Cardinal; const Truncate: Boolean): string;
4545
public
4646

4747
/// <summary>Returns a description of the given comment style.</summary>
@@ -60,7 +60,7 @@ TSourceComments = class(TNoConstructObject)
6060
/// <returns>string.Formatted comment or empty string if Style = csNone.
6161
/// </returns>
6262
class function FormatSnippetComment(const Style: TCommentStyle;
63-
const TruncateComments: Boolean; const Text: IActiveText): string;
63+
const TruncateComments: Boolean; Text: IActiveText): string;
6464

6565
/// <summary>Formats document's header text as a Pascal comment.</summary>
6666
/// <param name="Comments">IStringList [in] List of paragraphs of header
@@ -259,9 +259,11 @@ implementation
259259
const
260260
/// <summary>Maximum number of characters on a source code line.</summary>
261261
cLineWidth = 80;
262-
const
263262
/// <summary>Size of indenting used for source code, in characters.</summary>
264263
cIndent = 2;
264+
/// <summary>Size of indenting used for rendering comments from active text.
265+
/// </summary>
266+
cCommentIndent = 4;
265267

266268

267269
type
@@ -1137,11 +1139,13 @@ class function TSourceComments.CommentStyleDesc(
11371139
end;
11381140

11391141
class function TSourceComments.FormatActiveTextCommentInner(
1140-
ActiveText: IActiveText; const Indent: Cardinal; const Truncate: Boolean):
1141-
string;
1142+
ActiveText: IActiveText; const LineWidth: Cardinal;
1143+
const Truncate: Boolean): string;
11421144
var
11431145
Renderer: TActiveTextTextRenderer;
11441146
ProcessedActiveText: IActiveText;
1147+
Lines: IStringList;
1148+
Line: string;
11451149
begin
11461150
if Truncate then
11471151
ProcessedActiveText := ActiveText.FirstBlock
@@ -1150,9 +1154,17 @@ class function TSourceComments.FormatActiveTextCommentInner(
11501154
Renderer := TActiveTextTextRenderer.Create;
11511155
try
11521156
Renderer.DisplayURLs := False;
1153-
Result := Renderer.RenderWrapped(
1154-
ProcessedActiveText, cLineWidth, Indent, Indent
1157+
Renderer.IndentDelta := cCommentIndent;
1158+
Result := '';
1159+
Lines := TIStringList.Create(
1160+
Renderer.RenderWrapped(ProcessedActiveText, LineWidth, 0),
1161+
EOL,
1162+
True,
1163+
False
11551164
);
1165+
for Line in Lines do
1166+
Result := Result + StringOfChar(' ', cLineWidth - LineWidth) + Line + EOL;
1167+
Result := StrTrimRight(Result);
11561168
finally
11571169
Renderer.Free;
11581170
end;
@@ -1189,25 +1201,27 @@ class function TSourceComments.FormatHeaderComments(
11891201
end;
11901202

11911203
class function TSourceComments.FormatSnippetComment(const Style: TCommentStyle;
1192-
const TruncateComments: Boolean; const Text: IActiveText): string;
1204+
const TruncateComments: Boolean; Text: IActiveText): string;
11931205
begin
11941206
case Style of
11951207
csNone:
11961208
Result := '';
11971209
csBefore:
1198-
Result := '{'
1199-
+ EOL
1200-
+ FormatActiveTextCommentInner(Text, cIndent, TruncateComments)
1201-
+ EOL
1202-
+ '}';
1210+
begin
1211+
Result := '{' + EOL
1212+
+ FormatActiveTextCommentInner(
1213+
Text, cLineWidth - cIndent, TruncateComments
1214+
)
1215+
+ EOL + '}';
1216+
end;
12031217
csAfter:
1204-
Result := StrOfChar(TActiveTextTextRenderer.LISpacer, cIndent)
1205-
+ '{'
1206-
+ EOL
1207-
+ FormatActiveTextCommentInner(Text, 2 * cIndent, TruncateComments)
1208-
+ EOL
1209-
+ StrOfChar(TActiveTextTextRenderer.LISpacer, cIndent)
1210-
+ '}';
1218+
begin
1219+
Result := StrOfChar(' ', cIndent) + '{' + EOL
1220+
+ FormatActiveTextCommentInner(
1221+
Text, cLineWidth - 2 * cIndent, TruncateComments
1222+
)
1223+
+ EOL + StringOfChar(' ', cIndent) + '}';
1224+
end;
12111225
end;
12121226
end;
12131227

Src/UTextSnippetDoc.pas

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ TTextSnippetDoc = class(TSnippetDoc)
3636
cPageWidth = 80;
3737
/// <summary>Size of a single level of indentation in characters.
3838
/// </summary>
39-
cIndent = 2;
39+
cIndent = 4;
4040
strict private
4141
/// <summary>Renders given active text as word-wrapped paragraphs of width
4242
/// cPageWidth.</summary>
@@ -111,8 +111,9 @@ procedure TTextSnippetDoc.RenderActiveText(ActiveText: IActiveText);
111111
Renderer := TActiveTextTextRenderer.Create;
112112
try
113113
Renderer.DisplayURLs := True;
114+
Renderer.IndentDelta := cIndent;
114115
fWriter.WriteLine(
115-
Renderer.RenderWrapped(ActiveText, cPageWidth, 0, cIndent)
116+
Renderer.RenderWrapped(ActiveText, cPageWidth, 0)
116117
);
117118
finally
118119
Renderer.Free;

0 commit comments

Comments
 (0)