📄 ujaddnodes.pas
字号:
begin
OptionValue := '';
Result := False;
end;
{Returns the absolute path, if a relative path is specified it is interpreted
relative to the current path.
~param FileName the name (and path) which should be interpreted relative to the
current path, unless it is an absolute path
~result the absolute path of the file }
function TJaddNodeOwner.GetFullPath(const FileName: String): String;
begin
//by default relative to current working directory
Result := GetAbsolutePathCurrent(FileName);
end;
{Adds a message to the generator.
~param Msg the kind of the message to add
~param Text the text of the message }
procedure TJaddNodeOwner.AddMessage(Msg: TJaddNodeMessages;
const Text: String);
begin
//by default ignore messages
end;
{Adds a formatted message to the generator.
~param Msg the kind of the message to add
~param Fmt the format of the message
~param Args the values to be included in the message as specified by the
format }
procedure TJaddNodeOwner.AddMessageFmt(Msg: TJaddNodeMessages;
const Fmt: String;
const Args: array of const);
begin
AddMessage(Msg, Format(Fmt, Args)); //just format and add the message text
end;
{ * * * *** * * * *** TJaddNode *** * * * *** * * * }
{Creates the object and registers itself to its owner.
~param Owner the owner of the node, responsible for freeing it }
constructor TJaddNode.Create(Owner: TJaddNodeOwner);
begin
inherited Create; //create the object
assert(assigned(Owner));
if assigned(Owner) then
begin
Owner.AddNode(Self); //register itself to the owner
FOwner := Owner; //save the owner
end;
end;
{Uniques all whitespaces to a single space ' ' while adding the text to the
node, i.e. no (white) spaces will be adjacent in the added text. A whitespace
is any character < ' '. An empty line is converted to a paragraph break, for
this test the character #10 is treated as a line break.
~param Text the text to add with only single white spaces
~param ToNode the node to which the text should be added
~param IgnoreWhiteSpace whether leading white spaces should be ignored }
procedure TJaddNode.ParagraphizeText(Text: String; ToNode: TICNCompound;
IgnoreWhiteSpace: Boolean);
const LineBreakChar = #10; //the character breaking a line
var len :Integer; //numer of characters to scan
Read :PChar; //to read each character
Write :PChar; //position to write character
ParagraphStart :PChar; //start of the optimized paragraph
InSpace :Boolean; //white space already written?
LineCounter :Integer; //number of empty lines
begin
len := Length(Text); //get number of characters
if len > 0 then //text not empty?
begin
//the string is compressed/optimized "in-place"
UniqueString(Text); //so we can change the string low-level
Read := @Text[1]; //initialize read and write position
Write := Read;
ParagraphStart := Write;
InSpace := False; //no space written so far
LineCounter := 0; //just for the compiler warning
while len > 0 do //for each character
begin
if Read^ <= ' ' then //read a white space?
begin
if not InSpace then //space not already written?
begin
InSpace := True; //space will be written now
LineCounter := Ord(Read^ = LineBreakChar);
Write^ := ' '; //write the space
inc(Write); //move write pointer
end
else
if Read^ = LineBreakChar then //new line starts?
Inc(LineCounter); //add another line
end //if Read^ <= ' '
else
begin
if InSpace then //was after white spaces
begin
InSpace := False; //no space written
if LineCounter >= 2 then //after at least one empty line?
begin
//texts starts with a white space (or empty line)?
if (ParagraphStart = @Text[1]) and (ParagraphStart^ = ' ') and
//don't add a space before paragraph break
((Write = @Text[2]) or
IgnoreWhiteSpace) then //leading white spaces ignored?
inc(ParagraphStart); //so remove it
if ParagraphStart <> Write then //some text in the paragraph?
begin
//add the text
ToNode.AppendNode(TICNText.CreateText(ToNode.Owner,
Copy(Text, ParagraphStart - @Text[1] + 1,
Write - ParagraphStart)));
ParagraphStart := Write; //set start of new paragraph
end;
//add the paragraph break
ToNode.AppendNode(TICNBreak.CreateBreak(ToNode.Owner,
icbsParagraphBreak));
end; //if LineCounter >= 2
end; //if InSpace
Write^ := Read^; //copy non-white space
inc(Write); //move write pointer
end; //else Read^ <= ' '
inc(Read); //move read pointer
dec(len); //one less to read
end; //while len > 0
if ParagraphStart <> Write then //some text in the last paragraph?
begin
//texts starts with a white space (or empty line)?
if (ParagraphStart = @Text[1]) and (ParagraphStart^ = ' ') and
IgnoreWhiteSpace then //and leading white spaces should be ignored?
inc(ParagraphStart); //so remove it
if ParagraphStart <> Write then //some text in the last paragraph?
//add the text
ToNode.AppendNode(TICNText.CreateText(ToNode.Owner,
Copy(Text, ParagraphStart - @Text[1] + 1,
Write - ParagraphStart)));
if InSpace and (LineCounter >= 2) then //after at least one empty line?
//add the paragraph break
ToNode.AppendNode(TICNBreak.CreateBreak(ToNode.Owner,
icbsParagraphBreak));
end; //if ParagraphStart <> Write
end; //if len > 0
end;
{Optimizes text by compressing white spaces to a single space ' '.
~param Text the text to unique all white spaces in
~param ToNode the node to add the optimized text to
~param IgnoreWhiteSpace whether leading white spaces should be ignored }
procedure TJaddNode.OptimizeText(Text: String; ToNode: TICNCompound;
IgnoreWhiteSpace: Boolean = False);
var Pref :Boolean; //whether the format of the text should be kept
begin
Pref := Owner.GetPreformattedState; //format should be kept?
//format shouldn't be kept and empty lines are paragraph breaks?
if not Pref and Owner.EmptyCommentLinesBreakParagraphs then
//add the text with paragraphs breaks at empty lines
ParagraphizeText(Text, ToNode, IgnoreWhiteSpace)
else
begin
if not Pref then //format should not be kept?
begin
Text := UniqueWhiteSpacesToSpace(Text); //unique white spaces
//leading white space should be ignored and starts with white space(s)?
if IgnoreWhiteSpace and (Text <> '') and (Text[1] = ' ') then
Delete(Text, 1, 1); //remove the white space
end;
if Text <> '' then //some text is left?
ToNode.AppendNode(TICNText.CreateText(ToNode.Owner, Text)); //add it
end;
end;
{Checks whether this node is inside a link.
~result whether this node is inside a link node }
function TJaddNode.InALink: Boolean;
var Parent :TJaddNodeCompound; //all nodes above this one
begin
Result := False; //no link found so far
Parent := FParent; //get the parent node
while not Result and assigned(Parent) do //while no link found and not root
begin
Result := (Parent is TJaddNodeInlineCommand) and //is a link?
(TJaddNodeInlineCommand(Parent).InlineCommand in
JaddInlineCommandLinks);
Parent := Parent.Parent; //get the parent node
end;
end;
{ * * * *** * * * *** TJaddNodeText *** * * * *** * * * }
{Creates an object representing the text.
~param Owner the owner of the node, responsible for freeing it
~param Text the represented text }
constructor TJaddNodeText.CreateText(Owner: TJaddNodeOwner;
const Text: String);
begin
assert(Text <> '');
inherited Create(Owner); //create the object
FText := Text; //save the represented text
end;
{Transforms the node to the more general ~[linkUnit UICNodes COM].
~param ToNode the node to which the transformed node should be added
~param DestComment the comment the tranformed node will be part of }
procedure TJaddNodeText.TransformToIC(ToNode: TICNCompound;
DestComment: TICDocComment);
begin
OptimizeText(FText, ToNode); //add the text optimized to the COM
end;
{Copies the node to the specified node.
~param Compound the node to which a copy of this node should be added }
procedure TJaddNodeText.CopyTo(Compound: TJaddNodeCompound);
begin //create a copy and add it to the node
Compound.AppendNode(TJaddNodeText.CreateText(Compound.Owner, FText));
end;
{ * * * *** * * * *** TJaddNodeCompound *** * * * *** * * * }
{Creates the object and registers itself to its owner.
~param Owner the owner of the node, responsible for freeing it }
constructor TJaddNodeCompound.Create(Owner: TJaddNodeOwner);
begin
inherited Create(Owner); //create the object
FChildren := TList.Create; //create list for the child nodes
end;
{Frees the list of child nodes and the node itself. }
destructor TJaddNodeCompound.Destroy;
begin
FChildren.Free; //free list for child nodes
inherited Destroy; //free the object
end;
{Returns the specified child node.
~param Index the index of the child node, between 0 and ~[link ChildCount] - 1
~result the specified child node }
function TJaddNodeCompound.GetChild(Index: Integer): TJaddNode;
begin
Result := FChildren[Index]; //return the specified child node
end;
{Returns the remnant of the content of the node as a parameter (ignores
formattings etc.).
~param StartText
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -