📄 ucommentextraction.pas
字号:
{ JADD - Just Another DelphiDoc: Documentation from Delphi Source Code
Copyright (C) 2003-2008 Gerold Veith
This file is part of JADD - Just Another DelphiDoc.
DelphiDoc is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.
DelphiDoc is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
}
unit UCommentExtraction;
{Contains another abstract class to extract comments for the generators of
documentation. ~[link TSectionExtractor] implements the sectionizing of one
big text, like a comment in source code, into sections by a special character
followed by the name of the section. The ~[link ExtractorClasses list of all
extractors] is also administrated here.
}
interface
uses Classes, IniFiles,
UOptions,
UComments, UMakeDoc;
//the default special character starting/separating sections
const DefaultSectionSeparatorChar = '~';
//the valid characters for names of sections
SectionNameChars = ['A'..'Z', 'a'..'z', '0'..'9', #128..#255];
//the valid characters to start names of sections with
SectionNameStartChars = SectionNameChars - ['0'..'9'];
//the names of the options to set the names of the sections in the
//comments;
//please mind, that the first value "param" is used for the help text in
//options.html, so if you change it (or the order) change it there, too
CommentSectionOptionNames: array[csFirstNonDefaultComment..
High(TCommentSection)] of String =
('param', 'result',
'exception',
'see', 'seeText',
'deprecated', 'todo', 'feature',
'example',
'author', 'version',
'AdditionalAttribute1',
'AdditionalAttribute2',
'AdditionalAttribute3',
'page',
'guiinclude', 'guialias', 'guimanual',
'gui');
//the default names of the sections in the comments
DefaultCommentSectionNames: array[csFirstNonDefaultComment..
High(TCommentSection)] of String =
('param', 'result,return,returns',
'exception,throws,raises',
'see', 'seeText',
'deprecated', 'todo', 'feature',
'example',
'author', 'version',
'Additional Attribute 1',
'Additional Attribute 2',
'Additional Attribute 3',
'page',
'guiinclude', 'guialias', 'guimanual',
'gui');
type
{ * * * *** * * * *** TSectionExtractor *** * * * *** * * * }
{Still as an abstract class it implements the functionality to sectionize one
big text, like found as a comment in the source code, into several sections.
These are recognized by a special character followed by the name of the
section. }
TSectionExtractor = class(TCommentExtractor)
private
//the character starting sections in comments
FSectionSeparatorChar: Char;
//whether the text should never be sectioned
//(except when parameter Force of method ~[link Sectionize] is used)
FDoNotSectionize: Boolean;
//the list of names of all sections, the number is encoded in the Objects
FSectionNames: TStringList;
//a list of ignored section names
FIgnoredSectionNames: TStringList;
protected
//Returns the text up to the beginning of the next section and removes it
//from the text.
function GetCommentTillNextSection(var Comment: String): String;
property SectionNames: TStringList read FSectionNames;
public
//Creates the object and initializes the names of the sections.
constructor Create(Generator: TMakeDoc); override;
//Frees the object and the names of the sections.
destructor Destroy; override;
//Returns the number of available options in extractors of this class.
class function GetOptionCount: Cardinal; override;
//Gets a description of an option.
class procedure GetOptionDescription(Index: Cardinal;
var Desc: TOptionDescription);
override;
//Gets the value of an option.
function GetOption(Index: Cardinal): TOptionValue; override;
//Sets the value of an option.
procedure SetOption(Index: Cardinal; const Value: TOptionValue); override;
//Sets the names of sections not to be recognized as sections on its own.
function SetIgnoredSectionNames(IgnoredNames: TStrings): Boolean; override;
//Returns the text as comments.
function Sectionize(Text: String; Force: Boolean): TComment; override;
property SectionSeparatorChar: Char read FSectionSeparatorChar;
property DoNotSectionize: Boolean read FDoNotSectionize;
property IgnoredSectionNames: TStringList read FIgnoredSectionNames;
end;
//The list of extractors of comments.
//Contains the names of the classes of the extractors and references to the
//classed themselves in the corresponding objects.
var ExtractorClasses: TStringList = nil;
//Adds a class of extractors of comments to the list of extractors.
procedure AddCommentExtractorClass(ExtractorClass: TCommentExtractorClass);
//Removes the first line from Text and returns it.
function GetLine(var Text: String): String;
//Removes the left indentation of the text.
function TrimLeftMargin(Text: String): String;
//Transforms tabulator characters to spaces.
function TransformTabulators(Text: String; TabWidth: Integer): String;
//Strips trailing whitespaces from the lines.
function StripTrailingWhiteSpaces(Text: String): String;
implementation
uses SysUtils,
General;
{Removes the first line from Text and returns it.
~param Text the text to get and remove the first line from
~result the first line of the text }
function GetLine(var Text: String): String;
var cr, lf :Integer; //first positions of #13 and #10 in Text
begin
cr := Pos(#13, Text); //get first positions of #13 and #10
lf := Pos(#10, Text);
if cr = 0 then //if no #13 found use #10
cr := lf;
if cr = 0 then //no end-of-line (EOL) character found?
begin
Result := Text; //use whole text as line
Text := ''; //all text used, remnant is empty
end
else
begin
if lf < cr then //correct values for #13#10
if lf = cr - 1 then
begin
Dec(cr);
Inc(lf);
end
else
cr := lf;
Result := Copy(Text, 1, cr - 1); //get first line
Delete(Text, 1, cr + Ord(lf = cr + 1)); //delete it with EOL marker
end;
end;
{Removes the left indentation of the text. This is tried to perform somehow
intelligently in order to not delete wanted indentation for instance in code
snippets. The indentation of the first line is ignored and not removed, but
simply TrimLeft can be used for that.
~param Text the text to remove the indentation from
~result the text without an indentation }
function TrimLeftMargin(Text: String): String;
var Margin :Integer; //the margin of the text
TextCopy :String; //copy to extract the text line by line
Line :String; //each line of the text
LineTextLength :Integer; //length of the line without margin
LineMargin :Integer; //margin of the line
begin
if Text <> '' then //something to remove indentation from?
begin
Margin := High(Margin); //assume maximum indentation so far
TextCopy := Text; //copy text to get it line by line
GetLine(TextCopy); //skip first line
while (Margin <> 0) and (TextCopy <> '') do //while margin & text available
begin
Line := GetLine(TextCopy); //get next line
if Line <> '' then //line is not empty?
begin
LineTextLength := Length(TrimLeft(Line)); //length without indentation
if LineTextLength <> 0 then //line not empty?
begin
LineMargin := Length(Line) - LineTextLength; //get indentation
if LineMargin < Margin then //new minimum margin?
Margin := LineMargin; //save new minimum
end;
end;
end;
//a margin to remove and lines to remove it from?
if (Margin <> 0) and (Margin <> High(Margin)) then
begin
Inc(Margin); //increment to first valid character
Result := GetLine(Text); //get first line
while Text <> '' do //for each line, add it without margin
Result := Result + #13#10 +
Copy(GetLine(Text), Margin, High(Length(Text)));
end
else
Result := Text; //just remove the text
Result := TrimRight(Result); //remove following whitespaces
end
else
Result := ''; //just return the empty text
end;
{Transforms tabulator characters to spaces.
~param Text the text to transform the tabulator characters in
~param TabWidth the distance at which the tab-stops are set (the maxmimum width
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -