Стартовый пул
This commit is contained in:
52
bgrabitmap/dev/assistant/builddata.py
Normal file
52
bgrabitmap/dev/assistant/builddata.py
Normal file
@@ -0,0 +1,52 @@
|
||||
# BGRABitmap Assistant: https://chat.openai.com/g/g-FO7aiutRx-bgrabitmap-assistant
|
||||
# This program extracts method signatures in BGRABitmap to help provide accurate examples
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
def gather_method_signatures(source_dir):
|
||||
print("Source directory:", source_dir)
|
||||
regexMethod = r"(?P<proc_or_fun>procedure|function)\s+(?P<class>\w+)\.(?P<method>\w+)(\((?P<parameters>[^)]*)\))?(:(?P<return_type>[^;]+))?;"
|
||||
patternMethod = re.compile(regexMethod)
|
||||
signatures = []
|
||||
classes = set()
|
||||
|
||||
for root, dirs, files in os.walk(source_dir):
|
||||
for file in files:
|
||||
if file.endswith('.pas') or file.endswith('.inc'):
|
||||
print("Source file:", file)
|
||||
with open(os.path.join(root, file), 'r') as source_file:
|
||||
content = source_file.read()
|
||||
matches = patternMethod.finditer(content)
|
||||
|
||||
for match in matches:
|
||||
proc_or_fun = match.group('proc_or_fun')
|
||||
class_name = match.group('class')
|
||||
method_name = match.group('method')
|
||||
parameters = match.group('parameters')
|
||||
if parameters is None:
|
||||
parameters = ""
|
||||
else:
|
||||
parameters = re.sub(r'\s', '', parameters).replace(':', ': ').replace(';', '; ')
|
||||
return_type = match.group('return_type')
|
||||
if return_type is None:
|
||||
return_type = ""
|
||||
else:
|
||||
return_type = return_type.strip()
|
||||
method_signature = f'{proc_or_fun} {class_name}.{method_name}({parameters})'
|
||||
if proc_or_fun == "function":
|
||||
method_signature += f': {return_type}'
|
||||
signatures.append(f"{method_signature}; {{in {file}}}")
|
||||
classes.add(class_name)
|
||||
return signatures, classes
|
||||
|
||||
app_directory = os.path.dirname(__file__)
|
||||
source_directory = os.path.join(app_directory, '../../bgrabitmap')
|
||||
signatures, classes = gather_method_signatures(source_directory)
|
||||
target_file = os.path.join(app_directory, 'all.pas')
|
||||
with open(target_file, "w") as file:
|
||||
for line in signatures:
|
||||
file.write(line + "\n")
|
||||
target_file = os.path.join(app_directory, 'all_classes.txt')
|
||||
with open(target_file, "w") as file:
|
||||
file.write(", ".join(classes))
|
67
bgrabitmap/dev/colorspace/generatecolorspaces.lpi
Normal file
67
bgrabitmap/dev/colorspace/generatecolorspaces.lpi
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="11"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<MainUnit Value="0"/>
|
||||
<Title Value="generatecolorspaces"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<BuildModes Count="1">
|
||||
<Item1 Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
<Modes Count="1">
|
||||
<Mode0 Name="default"/>
|
||||
</Modes>
|
||||
</RunParams>
|
||||
<Units Count="2">
|
||||
<Unit0>
|
||||
<Filename Value="generatecolorspaces.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="unitmakerunit.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="UnitMakerUnit"/>
|
||||
</Unit1>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target>
|
||||
<Filename Value="generatecolorspaces"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Other>
|
||||
<CustomOptions Value="-dColorHelpersMaker"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="3">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
8
bgrabitmap/dev/colorspace/generatecolorspaces.lpr
Normal file
8
bgrabitmap/dev/colorspace/generatecolorspaces.lpr
Normal file
@@ -0,0 +1,8 @@
|
||||
program generatecolorspaces;
|
||||
|
||||
uses UnitMakerUnit;
|
||||
|
||||
begin
|
||||
GenerateCode;
|
||||
end.
|
||||
|
1334
bgrabitmap/dev/colorspace/unitmakerunit.pas
Normal file
1334
bgrabitmap/dev/colorspace/unitmakerunit.pas
Normal file
File diff suppressed because it is too large
Load Diff
BIN
bgrabitmap/dev/makedoc/pmakedoc.ico
Normal file
BIN
bgrabitmap/dev/makedoc/pmakedoc.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
90
bgrabitmap/dev/makedoc/pmakedoc.lpi
Normal file
90
bgrabitmap/dev/makedoc/pmakedoc.lpi
Normal file
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<CompatibilityMode Value="True"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="pmakedoc"/>
|
||||
<ResourceType Value="res"/>
|
||||
<UseXPManifest Value="True"/>
|
||||
<Icon Value="0"/>
|
||||
</General>
|
||||
<i18n>
|
||||
<EnableI18N LFM="False"/>
|
||||
</i18n>
|
||||
<BuildModes Count="1">
|
||||
<Item1 Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
<Modes Count="1">
|
||||
<Mode0 Name="default"/>
|
||||
</Modes>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="1">
|
||||
<Item1>
|
||||
<PackageName Value="LCL"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="2">
|
||||
<Unit0>
|
||||
<Filename Value="pmakedoc.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="unit1.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="Form1"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="Unit1"/>
|
||||
</Unit1>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="pmakedoc"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf3"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
<Other>
|
||||
<ConfigFile>
|
||||
<WriteConfigFilePath Value="$(ProjOutDir)\fpclaz.cfg"/>
|
||||
</ConfigFile>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="3">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
21
bgrabitmap/dev/makedoc/pmakedoc.lpr
Normal file
21
bgrabitmap/dev/makedoc/pmakedoc.lpr
Normal file
@@ -0,0 +1,21 @@
|
||||
program pmakedoc;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||
cthreads,
|
||||
{$ENDIF}{$ENDIF}
|
||||
Interfaces, // this includes the LCL widgetset
|
||||
Forms, Unit1
|
||||
{ you can add units after this };
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
RequireDerivedFormResource := True;
|
||||
Application.Initialize;
|
||||
Application.CreateForm(TForm1, Form1);
|
||||
Application.Run;
|
||||
end.
|
||||
|
14
bgrabitmap/dev/makedoc/readme.txt
Normal file
14
bgrabitmap/dev/makedoc/readme.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Some pages on the wiki are generated by this program:
|
||||
http://wiki.freepascal.org/BGRABitmap#BGRABitmapTypes_unit_reference
|
||||
|
||||
The idea is to add comments with a specific format:
|
||||
- on the line preceding a declaration
|
||||
- using { } brackets
|
||||
- starting with * for a main entry. Example:
|
||||
{* Specifies the shape of a predefined blur }
|
||||
|
||||
- starting with ** for a sub-entry. Example, one enumeration:
|
||||
{** Gaussian-like, pixel importance decreases progressively }
|
||||
|
||||
The sections titles are prefixed and suffixed by ===. Example:
|
||||
{=== Miscellaneous types ===}
|
59
bgrabitmap/dev/makedoc/unit1.lfm
Normal file
59
bgrabitmap/dev/makedoc/unit1.lfm
Normal file
@@ -0,0 +1,59 @@
|
||||
object Form1: TForm1
|
||||
Left = 379
|
||||
Height = 331
|
||||
Top = 219
|
||||
Width = 536
|
||||
Caption = 'Form1'
|
||||
ClientHeight = 331
|
||||
ClientWidth = 536
|
||||
LCLVersion = '3.99.0.0'
|
||||
OnCreate = FormCreate
|
||||
object EPath: TEdit
|
||||
Left = 8
|
||||
Height = 22
|
||||
Top = 30
|
||||
Width = 520
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
TabOrder = 0
|
||||
Text = '../../bgrabitmap'
|
||||
end
|
||||
object Label1: TLabel
|
||||
Left = 9
|
||||
Height = 16
|
||||
Top = 9
|
||||
Width = 89
|
||||
Caption = 'Path of library:'
|
||||
ParentColor = False
|
||||
end
|
||||
object Memo1: TMemo
|
||||
Left = 8
|
||||
Height = 235
|
||||
Top = 88
|
||||
Width = 518
|
||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||
ScrollBars = ssBoth
|
||||
TabOrder = 1
|
||||
end
|
||||
object Button1: TButton
|
||||
Left = 8
|
||||
Height = 25
|
||||
Top = 56
|
||||
Width = 96
|
||||
Caption = 'Browse...'
|
||||
TabOrder = 2
|
||||
OnClick = Button1Click
|
||||
end
|
||||
object Button2: TButton
|
||||
Left = 112
|
||||
Height = 25
|
||||
Top = 56
|
||||
Width = 96
|
||||
Caption = 'Make doc'
|
||||
TabOrder = 3
|
||||
OnClick = Button2Click
|
||||
end
|
||||
object SelectDirectoryDialog1: TSelectDirectoryDialog
|
||||
Left = 300
|
||||
Top = 9
|
||||
end
|
||||
end
|
408
bgrabitmap/dev/makedoc/unit1.pas
Normal file
408
bgrabitmap/dev/makedoc/unit1.pas
Normal file
@@ -0,0 +1,408 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit Unit1;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
||||
fgl;
|
||||
|
||||
type
|
||||
|
||||
{ TForm1 }
|
||||
|
||||
TForm1 = class(TForm)
|
||||
Button1: TButton;
|
||||
Button2: TButton;
|
||||
EPath: TEdit;
|
||||
Label1: TLabel;
|
||||
Memo1: TMemo;
|
||||
SelectDirectoryDialog1: TSelectDirectoryDialog;
|
||||
procedure Button1Click(Sender: TObject);
|
||||
procedure Button2Click(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
private
|
||||
{ private declarations }
|
||||
public
|
||||
{ public declarations }
|
||||
end;
|
||||
|
||||
var
|
||||
Form1: TForm1;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
uses LazUTF8, FileUtil, LazFileUtils, RegExpr, StrUtils;
|
||||
|
||||
const
|
||||
BoldKeywords : array[1..58] of string = ('var','procedure','function','and',
|
||||
'or','xor','not','if','then','case','begin','end','of',
|
||||
'exit','new','class','is','const','div','do','downto','to','else','for',
|
||||
'in','mod','nil','object','record','repeat','self','shl','shr','string',
|
||||
'unit','until','uses','while','array','interface', 'out', 'constructor',
|
||||
'property','read','write','default', 'packed', 'operator', 'inline',
|
||||
'overload', 'virtual', 'abstract', 'helper', 'ifdef', 'endif', 'set',
|
||||
'specialize', 'generic');
|
||||
|
||||
type
|
||||
TDocumentationPages = specialize TFPGMap<string, string>;
|
||||
|
||||
{ TForm1 }
|
||||
|
||||
procedure TForm1.Button1Click(Sender: TObject);
|
||||
begin
|
||||
if SelectDirectoryDialog1.Execute then
|
||||
EPath.Text := SelectDirectoryDialog1.FileName;
|
||||
end;
|
||||
|
||||
procedure HighlightKeywords(var s: string);
|
||||
const keywordChars = ['a'..'z','A'..'Z'];
|
||||
moreKeywordChars = ['a'..'z','A'..'Z','0'..'9','_'];
|
||||
var
|
||||
i,start: Integer;
|
||||
w,wlower: string;
|
||||
j: Integer;
|
||||
found, first: boolean;
|
||||
begin
|
||||
i := 1;
|
||||
s := StringReplace(s, '''', ''', [rfReplaceAll]);
|
||||
s := StringReplace(s, '{%H-}', '', [rfReplaceAll]);
|
||||
first := true;
|
||||
while i <= length(s) do
|
||||
begin
|
||||
if s[i] in keywordChars then
|
||||
begin
|
||||
start := i;
|
||||
inc(i);
|
||||
while i <= length(s) do
|
||||
begin
|
||||
if not (s[i] in moreKeywordChars) then break;
|
||||
inc(i);
|
||||
end;
|
||||
w := copy(s,start,i-start);
|
||||
wlower := lowercase(w);
|
||||
found := false;
|
||||
for j := low(BoldKeywords) to high(BoldKeywords) do
|
||||
if BoldKeywords[j] = wlower then
|
||||
begin
|
||||
delete(s, start, length(w));
|
||||
dec(i, length(w));
|
||||
w := ''''''''+wlower+'''''''';
|
||||
insert(w, s, start);
|
||||
inc(i, length(w));
|
||||
found := true;
|
||||
break;
|
||||
end;
|
||||
if not found and first then
|
||||
begin
|
||||
delete(s, start, length(w));
|
||||
dec(i, length(w));
|
||||
first := copy(s, start, 1) = ',';
|
||||
w := ''''''+w+'''''';
|
||||
insert(w, s, start);
|
||||
inc(i, length(w));
|
||||
continue;
|
||||
end;
|
||||
first := false;
|
||||
end else
|
||||
inc(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure AdaptMarkdown(var s: string);
|
||||
var r: TRegExpr;
|
||||
begin
|
||||
r := TRegExpr.Create('([^A-Z0-9]|^)_([A-Z0-9]+([_.][A-Z0-9]+)*)_([^A-Z0-9]|$)'); r.ModifierI:= true;
|
||||
s := r.Replace(s, '$1''''$2''''$4', true);
|
||||
r.Free;
|
||||
|
||||
r := TRegExpr.Create('\*\*([A-Z0-9]+([_.][A-Z0-9]+)*)\*\*'); r.ModifierI:= true;
|
||||
s := r.Replace(s, '''''''$1''''''', true);
|
||||
r.Free;
|
||||
|
||||
r := TRegExpr.Create('([^\\]|^)\[([^\]]+)\]\(https://wiki.freepascal.org/(\w+)\)'); r.ModifierI:= true;
|
||||
s := r.Replace(s, '$1[[$3|$2]]', true);
|
||||
r.Free;
|
||||
|
||||
r := TRegExpr.Create('([^\\]|^)\[([^\]]+)\]\(([-\w:/.]+)\)'); r.ModifierI:= true;
|
||||
s := r.Replace(s, '$1[$3 $2]', true);
|
||||
r.Free;
|
||||
|
||||
r := TRegExpr.Create('```pascal([^`]+)```');
|
||||
s := r.Replace(s, '<syntaxhighlight>$1</syntaxhighlight>', true);
|
||||
r.Free;
|
||||
|
||||
r := TRegExpr.Create('\^([0-9]+)');
|
||||
s := r.Replace(s, '<sup>$1</sup>', true);
|
||||
r.Free;
|
||||
|
||||
s := StringReplace(s, '\[', '[', [rfReplaceAll]);
|
||||
s := StringReplace(s, ' --> ', ' → ', [rfReplaceAll]);
|
||||
s := StringReplace(s, ' <-- ', ' ← ', [rfReplaceAll]);
|
||||
end;
|
||||
|
||||
procedure MakeDocFor(AFilename: string; APages: TDocumentationPages);
|
||||
var
|
||||
t: textfile;
|
||||
fileoutput,s,bgcolor: String;
|
||||
description, element: String;
|
||||
comStart,comEnd, idxColor: integer;
|
||||
oddRow,indented : boolean;
|
||||
docName, colorStr: string;
|
||||
tableOpened, inCode, bulletPoint, prevBulletPoint: boolean;
|
||||
|
||||
procedure openTable;
|
||||
begin
|
||||
if not tableOpened then
|
||||
begin
|
||||
fileoutput += '<table style="border-collapse: collapse;">'+lineending;
|
||||
oddRow := true;
|
||||
tableOpened:= true;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure closeTable;
|
||||
begin
|
||||
if tableOpened then
|
||||
begin
|
||||
fileoutput += '</table>'+LineEnding;
|
||||
tableOpened:= false;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure flushOutput;
|
||||
var
|
||||
docIndex: Integer;
|
||||
begin
|
||||
if fileoutput <> '' then
|
||||
begin
|
||||
closeTable;
|
||||
if not APages.Find(docName, docIndex) then
|
||||
begin
|
||||
docIndex := APages.Add(docName, '=== ' + docName + ' ===' + LineEnding);
|
||||
end;
|
||||
APages.Data[docIndex] := APages.Data[docIndex] + fileoutput;
|
||||
fileoutput:= '';
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
docName := ExtractFileName(AFilename);
|
||||
fileoutput := '';
|
||||
tableOpened:= false;
|
||||
assignfile(t, UTF8ToSys(AFilename));
|
||||
reset(t);
|
||||
while not eof(t) do
|
||||
begin
|
||||
readln(t,s);
|
||||
|
||||
comStart:= pos('{====',s);
|
||||
if comStart <> 0 then
|
||||
begin
|
||||
comEnd:= pos('====}',s);
|
||||
if comEnd <> 0 then
|
||||
begin
|
||||
closeTable;
|
||||
fileOutput += trim(copy(s,comStart+1,comEnd+3 -(comStart+1)+1)) + LineEnding;
|
||||
continue;
|
||||
end;
|
||||
end;
|
||||
|
||||
comStart:= pos('{===',s);
|
||||
if comStart <> 0 then
|
||||
begin
|
||||
comEnd:= pos('===}',s);
|
||||
if comEnd <> 0 then
|
||||
begin
|
||||
flushOutput;
|
||||
docName:= trim(copy(s,comStart+4,comEnd-1 -(comStart+4)+1));
|
||||
continue;
|
||||
end;
|
||||
end;
|
||||
|
||||
comStart:= pos('{* ',s+' ');
|
||||
indented:= false;
|
||||
inCode := false;
|
||||
if comStart <> 0 then
|
||||
comStart += 2
|
||||
else
|
||||
begin
|
||||
comStart := pos('{** ',s+' ');
|
||||
if comStart <> 0 then
|
||||
comStart += 3;
|
||||
indented := true;
|
||||
end;
|
||||
if comStart<>0 then
|
||||
begin
|
||||
delete(s,1,comStart-1);
|
||||
comStart := 1;
|
||||
description := '';
|
||||
comEnd := pos('}',s);
|
||||
if comEnd = 0 then
|
||||
begin
|
||||
prevBulletPoint := false;
|
||||
description += trim(copy(s,comStart,length(s)-comStart+1));
|
||||
while not eof(t) do
|
||||
begin
|
||||
readln(t,s);
|
||||
bulletPoint := false;
|
||||
s := trim(s);
|
||||
if s.StartsWith('```') then inCode := not inCode;
|
||||
if not inCode then
|
||||
begin
|
||||
s := StringReplace(s, '<=', '≤', [rfReplaceAll]);
|
||||
s := StringReplace(s, '>=', '≥', [rfReplaceAll]);
|
||||
end;
|
||||
if s = '' then description += '<p>'
|
||||
else
|
||||
begin
|
||||
comEnd := pos('}',s);
|
||||
if comEnd > 0 then s := trim(copy(s,1,comEnd-1));
|
||||
if not inCode then
|
||||
begin
|
||||
if s.StartsWith('- ') then
|
||||
begin
|
||||
description += IfThen(prevBulletPoint,'',LineEnding)+'* '+s.Substring(2)+LineEnding;
|
||||
bulletPoint := true;
|
||||
end
|
||||
else
|
||||
description += ' '+s;
|
||||
end;
|
||||
if comEnd > 0 then break
|
||||
else if inCode then description += LineEnding;
|
||||
end;
|
||||
prevBulletPoint:= bulletPoint;
|
||||
end;
|
||||
end
|
||||
else
|
||||
description += trim(copy(s,comStart,comEnd-comStart));
|
||||
|
||||
AdaptMarkdown(description);
|
||||
|
||||
while pos('[#',description) <> 0 do
|
||||
begin
|
||||
idxColor := pos('[#',description);
|
||||
colorStr := copy(description, idxColor, 9);
|
||||
if (length(colorStr) = 9) and colorStr.EndsWith(']') then
|
||||
begin
|
||||
delete(description, idxColor, length(colorStr));
|
||||
insert('<span style="width:8px; height: 8px; display: inline-block; border: 1px solid black; background: '+copy(colorStr,2,length(colorStr)-2)+';"></span>', description, idxColor);
|
||||
end;
|
||||
end;
|
||||
|
||||
if not eof(t) then
|
||||
readln(t,element) else element := '?';
|
||||
|
||||
HighlightKeywords(element);
|
||||
element := trim(element);
|
||||
|
||||
openTable;
|
||||
if oddRow then bgcolor := 'white' else bgcolor := '#f0f0ff';
|
||||
|
||||
if indented then
|
||||
begin
|
||||
fileoutput += '<tr><td width="10%"></td><td colspan="2" style="background: '+bgcolor+';">'+element+'</td></tr>'+LineEnding;
|
||||
fileoutput += '<tr><td width="10%"></td><td width="10%" style="background: '+bgcolor+';"></td>'+
|
||||
'<td style="border: 1px solid #e0e0a0; background: #ffffe4;">'+description+'</td></tr>'+LineEnding;
|
||||
end else
|
||||
begin
|
||||
fileoutput += '<tr style="background: '+bgcolor+';"><td colspan="3">'+element+'</td></tr>'+LineEnding;
|
||||
fileoutput += '<tr style="background: '+bgcolor+';"><td width="10%"></td>'+
|
||||
'<td style="border: 1px solid #e0e0a0; background: #ffffe4;" colspan="2">'+description+'</td></tr>'+LineEnding;
|
||||
end;
|
||||
|
||||
fileoutput += '<tr style="height: 8px;"><td colspan="3"></td></tr>'+LineEnding;
|
||||
oddRow := not oddRow;
|
||||
end;
|
||||
end;
|
||||
closefile(t);
|
||||
flushOutput;
|
||||
end;
|
||||
|
||||
function ExportPages(APages: TDocumentationPages; APath: string): string;
|
||||
var
|
||||
i: Integer;
|
||||
u: textfile;
|
||||
outname, fullname, currentContent, fileoutput: String;
|
||||
begin
|
||||
result := '';
|
||||
if APages.Count = 0 then exit;
|
||||
CreateDirUTF8(APath+DirectorySeparator+'doc');
|
||||
for i := 0 to APages.Count-1 do
|
||||
begin
|
||||
outname := 'doc'+DirectorySeparator+APages.Keys[i]+'.txt';
|
||||
fullname := APath+outname;
|
||||
fileoutput := APages.Data[i];
|
||||
if FileExistsUTF8(fullname) then
|
||||
begin
|
||||
currentContent := ReadFileToString(fullname);
|
||||
if currentContent <> fileoutput then
|
||||
begin
|
||||
assignfile(u, UTF8ToSys(fullname));
|
||||
rewrite(u);
|
||||
write(u, fileoutput);
|
||||
closefile(u);
|
||||
result += outname + ' (updated)' + LineEnding;
|
||||
end else
|
||||
begin
|
||||
result += outname + ' (unchanged)' + LineEnding;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
result += outname + ' (created)' + LineEnding;
|
||||
assignfile(u, UTF8ToSys(fullname));
|
||||
rewrite(u);
|
||||
write(u, fileoutput);
|
||||
closefile(u);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button2Click(Sender: TObject);
|
||||
var sr: TSearchRec;
|
||||
output,ext: string;
|
||||
basePath,path: string;
|
||||
pages: TDocumentationPages;
|
||||
begin
|
||||
memo1.Text := 'Analyzing...';
|
||||
memo1.Update;
|
||||
basePath := ExtractFilePath(ParamStr(0));
|
||||
{$IFDEF DARWIN}
|
||||
if basePath.EndsWith('/MacOS/') then
|
||||
basePath := ExpandFileNameUTF8(basePath+'../../../');
|
||||
{$ENDIF}
|
||||
path := ExpandFileNameUTF8(AppendPathDelim(EPath.Text), basePath);
|
||||
if FindFirstUTF8(path+'*.*', faAnyFile, sr) = 0 then
|
||||
begin
|
||||
pages := TDocumentationPages.Create;
|
||||
pages.Sorted:= true;
|
||||
repeat
|
||||
if sr.Attr and (faDirectory or faVolumeId or faSymLink) <> 0 then continue;
|
||||
ext := AnsiLowerCase(ExtractFileExt(sr.Name));
|
||||
if (ext = '.pas') or (ext = '.inc') then
|
||||
MakeDocFor(path+sr.Name, pages);
|
||||
until FindNextUTF8(sr) <> 0;
|
||||
FindCloseUTF8(sr);
|
||||
|
||||
output := ExportPages(pages, path);
|
||||
if output = '' then
|
||||
Memo1.Text := 'No output'
|
||||
else
|
||||
Memo1.text := output;
|
||||
pages.Free;
|
||||
end
|
||||
else
|
||||
Memo1.Text := 'Nothing to do';
|
||||
end;
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
begin
|
||||
EPath.Text := StringReplace(EPath.Text, '/', PathDelim, [rfReplaceAll]);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
933
bgrabitmap/dev/parseunicode/ArabicShaping.txt
Normal file
933
bgrabitmap/dev/parseunicode/ArabicShaping.txt
Normal file
@@ -0,0 +1,933 @@
|
||||
# ArabicShaping-13.0.0.txt
|
||||
# Date: 2020-01-31, 23:55:00 GMT [KW, RP]
|
||||
# © 2020 Unicode®, Inc.
|
||||
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
|
||||
# For terms of use, see http://www.unicode.org/terms_of_use.html
|
||||
#
|
||||
# This file is a normative contributory data file in the
|
||||
# Unicode Character Database.
|
||||
#
|
||||
# This file defines the Joining_Type and Joining_Group property
|
||||
# values for Arabic, Syriac, N'Ko, Mandaic, and Manichaean positional
|
||||
# shaping, repeating in machine readable form the information
|
||||
# exemplified in Tables 9-3, 9-8, 9-9, 9-10, 9-14, 9-15, 9-16, 9-19,
|
||||
# 9-20, 10-4, 10-5, 10-6, 10-7, and 19-5 of The Unicode Standard core
|
||||
# specification. This file also defines Joining_Type values for
|
||||
# Mongolian, Phags-pa, Psalter Pahlavi, Sogdian, Chorasmian, and Adlam positional shaping,
|
||||
# and Joining_Type and Joining_Group values for Hanifi Rohingya positional shaping,
|
||||
# which are not listed in tables in the standard.
|
||||
#
|
||||
# See Sections 9.2, 9.3, 9.5, 10.5, 10.6, 13.4, 14.3, 14.10, 16.14, 19.4, and 19.9
|
||||
# of The Unicode Standard core specification for more information.
|
||||
#
|
||||
# Each line contains four fields, separated by a semicolon.
|
||||
#
|
||||
# Field 0: the code point, in 4-digit hexadecimal
|
||||
# form, of a character.
|
||||
#
|
||||
# Field 1: gives a short schematic name for that character.
|
||||
# The schematic name is descriptive of the shape, based as
|
||||
# consistently as possible on a name for the skeleton and
|
||||
# then the diacritic marks applied to the skeleton, if any.
|
||||
# Note that this schematic name is considered a comment,
|
||||
# and does not constitute a formal property value.
|
||||
#
|
||||
# Field 2: defines the joining type (property name: Joining_Type)
|
||||
# R Right_Joining
|
||||
# L Left_Joining
|
||||
# D Dual_Joining
|
||||
# C Join_Causing
|
||||
# U Non_Joining
|
||||
# T Transparent
|
||||
#
|
||||
# See Section 9.2, Arabic for more information on these joining types.
|
||||
# Note that for cursive joining scripts which are typically rendered
|
||||
# top-to-bottom, rather than right-to-left, Joining_Type=L conventionally
|
||||
# refers to bottom joining, and Joining_Type=R conventionally refers
|
||||
# to top joining. See Section 14.3, Phags-pa for more information on the
|
||||
# interpretation of joining types in vertical layout.
|
||||
#
|
||||
# Field 3: defines the joining group (property name: Joining_Group)
|
||||
#
|
||||
# The values of the joining group are based schematically on character
|
||||
# names. Where a schematic character name consists of two or more parts
|
||||
# separated by spaces, the formal Joining_Group property value, as specified in
|
||||
# PropertyValueAliases.txt, consists of the same name parts joined by
|
||||
# underscores. Hence, the entry:
|
||||
#
|
||||
# 0629; TEH MARBUTA; R; TEH MARBUTA
|
||||
#
|
||||
# corresponds to [Joining_Group = Teh_Marbuta].
|
||||
#
|
||||
# Note: The property value now designated [Joining_Group = Teh_Marbuta_Goal]
|
||||
# used to apply to both of the following characters
|
||||
# in earlier versions of the standard:
|
||||
#
|
||||
# U+06C2 ARABIC LETTER HEH GOAL WITH HAMZA ABOVE
|
||||
# U+06C3 ARABIC LETTER TEH MARBUTA GOAL
|
||||
#
|
||||
# However, it currently applies only to U+06C3, and *not* to U+06C2.
|
||||
# To avoid destabilizing existing Joining_Group property aliases, the
|
||||
# prior Joining_Group value for U+06C3 (Hamza_On_Heh_Goal) has been
|
||||
# retained as a property value alias, despite the fact that it
|
||||
# no longer applies to its namesake character, U+06C2.
|
||||
# See PropertyValueAliases.txt.
|
||||
#
|
||||
# When other cursive scripts are added to the Unicode Standard in the
|
||||
# future, the joining group value of all its letters will default to
|
||||
# jg=No_Joining_Group in this data file. Other, more specific
|
||||
# joining group values will be defined only if an explicit proposal
|
||||
# to define those values exactly has been approved by the UTC. This
|
||||
# is the convention exemplified by the N'Ko, Mandaic, Mongolian,
|
||||
# Phags-pa, Psalter Pahlavi, Sogdian, Chorasmian, and Adlam scripts.
|
||||
# Only the Arabic, Manichaean, and Syriac scripts currently have
|
||||
# explicit joining group values defined for all characters, including
|
||||
# those which have only a single character in a particular Joining_Group
|
||||
# class. Hanifi Rohingya has explicit Joining_Group values assigned only for
|
||||
# the few characters which share a particular Joining_Group class, but
|
||||
# assigns jg=No_Joining_Group to all the singletons.
|
||||
#
|
||||
# Note: Code points that are not explicitly listed in this file are
|
||||
# either of joining type T or U:
|
||||
#
|
||||
# - Those that are not explicitly listed and that are of General Category Mn, Me, or Cf
|
||||
# have joining type T.
|
||||
# - All others not explicitly listed have joining type U.
|
||||
#
|
||||
# For an explicit listing of all characters of joining type T, see
|
||||
# the derived property file DerivedJoiningType.txt.
|
||||
#
|
||||
# #############################################################
|
||||
|
||||
# Unicode; Schematic Name; Joining Type; Joining Group
|
||||
|
||||
# Arabic Characters
|
||||
|
||||
0600; ARABIC NUMBER SIGN; U; No_Joining_Group
|
||||
0601; ARABIC SIGN SANAH; U; No_Joining_Group
|
||||
0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group
|
||||
0603; ARABIC SIGN SAFHA; U; No_Joining_Group
|
||||
0604; ARABIC SIGN SAMVAT; U; No_Joining_Group
|
||||
0605; ARABIC NUMBER MARK ABOVE; U; No_Joining_Group
|
||||
0608; ARABIC RAY; U; No_Joining_Group
|
||||
060B; AFGHANI SIGN; U; No_Joining_Group
|
||||
0620; DOTLESS YEH WITH SEPARATE RING BELOW; D; YEH
|
||||
0621; HAMZA; U; No_Joining_Group
|
||||
0622; ALEF WITH MADDA ABOVE; R; ALEF
|
||||
0623; ALEF WITH HAMZA ABOVE; R; ALEF
|
||||
0624; WAW WITH HAMZA ABOVE; R; WAW
|
||||
0625; ALEF WITH HAMZA BELOW; R; ALEF
|
||||
0626; DOTLESS YEH WITH HAMZA ABOVE; D; YEH
|
||||
0627; ALEF; R; ALEF
|
||||
0628; BEH; D; BEH
|
||||
0629; TEH MARBUTA; R; TEH MARBUTA
|
||||
062A; DOTLESS BEH WITH 2 DOTS ABOVE; D; BEH
|
||||
062B; DOTLESS BEH WITH 3 DOTS ABOVE; D; BEH
|
||||
062C; HAH WITH DOT BELOW; D; HAH
|
||||
062D; HAH; D; HAH
|
||||
062E; HAH WITH DOT ABOVE; D; HAH
|
||||
062F; DAL; R; DAL
|
||||
0630; DAL WITH DOT ABOVE; R; DAL
|
||||
0631; REH; R; REH
|
||||
0632; REH WITH DOT ABOVE; R; REH
|
||||
0633; SEEN; D; SEEN
|
||||
0634; SEEN WITH 3 DOTS ABOVE; D; SEEN
|
||||
0635; SAD; D; SAD
|
||||
0636; SAD WITH DOT ABOVE; D; SAD
|
||||
0637; TAH; D; TAH
|
||||
0638; TAH WITH DOT ABOVE; D; TAH
|
||||
0639; AIN; D; AIN
|
||||
063A; AIN WITH DOT ABOVE; D; AIN
|
||||
063B; KEHEH WITH 2 DOTS ABOVE; D; GAF
|
||||
063C; KEHEH WITH 3 DOTS BELOW; D; GAF
|
||||
063D; FARSI YEH WITH INVERTED V ABOVE; D; FARSI YEH
|
||||
063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH
|
||||
063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH
|
||||
0640; TATWEEL; C; No_Joining_Group
|
||||
0641; FEH; D; FEH
|
||||
0642; QAF; D; QAF
|
||||
0643; KAF; D; KAF
|
||||
0644; LAM; D; LAM
|
||||
0645; MEEM; D; MEEM
|
||||
0646; NOON; D; NOON
|
||||
0647; HEH; D; HEH
|
||||
0648; WAW; R; WAW
|
||||
0649; DOTLESS YEH; D; YEH
|
||||
064A; YEH; D; YEH
|
||||
066E; DOTLESS BEH; D; BEH
|
||||
066F; DOTLESS QAF; D; QAF
|
||||
0671; ALEF WITH WASLA ABOVE; R; ALEF
|
||||
0672; ALEF WITH WAVY HAMZA ABOVE; R; ALEF
|
||||
0673; ALEF WITH WAVY HAMZA BELOW; R; ALEF
|
||||
0674; HIGH HAMZA; U; No_Joining_Group
|
||||
0675; HIGH HAMZA ALEF; R; ALEF
|
||||
0676; HIGH HAMZA WAW; R; WAW
|
||||
0677; HIGH HAMZA WAW WITH DAMMA ABOVE; R; WAW
|
||||
0678; HIGH HAMZA DOTLESS YEH; D; YEH
|
||||
0679; DOTLESS BEH WITH TAH ABOVE; D; BEH
|
||||
067A; DOTLESS BEH WITH VERTICAL 2 DOTS ABOVE; D; BEH
|
||||
067B; DOTLESS BEH WITH VERTICAL 2 DOTS BELOW; D; BEH
|
||||
067C; DOTLESS BEH WITH ATTACHED RING BELOW AND 2 DOTS ABOVE; D; BEH
|
||||
067D; DOTLESS BEH WITH INVERTED 3 DOTS ABOVE; D; BEH
|
||||
067E; DOTLESS BEH WITH 3 DOTS BELOW; D; BEH
|
||||
067F; DOTLESS BEH WITH 4 DOTS ABOVE; D; BEH
|
||||
0680; DOTLESS BEH WITH 4 DOTS BELOW; D; BEH
|
||||
0681; HAH WITH HAMZA ABOVE; D; HAH
|
||||
0682; HAH WITH VERTICAL 2 DOTS ABOVE; D; HAH
|
||||
0683; HAH WITH 2 DOTS BELOW; D; HAH
|
||||
0684; HAH WITH VERTICAL 2 DOTS BELOW; D; HAH
|
||||
0685; HAH WITH 3 DOTS ABOVE; D; HAH
|
||||
0686; HAH WITH 3 DOTS BELOW; D; HAH
|
||||
0687; HAH WITH 4 DOTS BELOW; D; HAH
|
||||
0688; DAL WITH TAH ABOVE; R; DAL
|
||||
0689; DAL WITH ATTACHED RING BELOW; R; DAL
|
||||
068A; DAL WITH DOT BELOW; R; DAL
|
||||
068B; DAL WITH DOT BELOW AND TAH ABOVE; R; DAL
|
||||
068C; DAL WITH 2 DOTS ABOVE; R; DAL
|
||||
068D; DAL WITH 2 DOTS BELOW; R; DAL
|
||||
068E; DAL WITH 3 DOTS ABOVE; R; DAL
|
||||
068F; DAL WITH INVERTED 3 DOTS ABOVE; R; DAL
|
||||
0690; DAL WITH 4 DOTS ABOVE; R; DAL
|
||||
0691; REH WITH TAH ABOVE; R; REH
|
||||
0692; REH WITH V ABOVE; R; REH
|
||||
0693; REH WITH ATTACHED RING BELOW; R; REH
|
||||
0694; REH WITH DOT BELOW; R; REH
|
||||
0695; REH WITH V BELOW; R; REH
|
||||
0696; REH WITH DOT BELOW AND DOT WITHIN; R; REH
|
||||
0697; REH WITH 2 DOTS ABOVE; R; REH
|
||||
0698; REH WITH 3 DOTS ABOVE; R; REH
|
||||
0699; REH WITH 4 DOTS ABOVE; R; REH
|
||||
069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN
|
||||
069B; SEEN WITH 3 DOTS BELOW; D; SEEN
|
||||
069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN
|
||||
069D; SAD WITH 2 DOTS BELOW; D; SAD
|
||||
069E; SAD WITH 3 DOTS ABOVE; D; SAD
|
||||
069F; TAH WITH 3 DOTS ABOVE; D; TAH
|
||||
06A0; AIN WITH 3 DOTS ABOVE; D; AIN
|
||||
06A1; DOTLESS FEH; D; FEH
|
||||
06A2; DOTLESS FEH WITH DOT BELOW; D; FEH
|
||||
06A3; FEH WITH DOT BELOW; D; FEH
|
||||
06A4; DOTLESS FEH WITH 3 DOTS ABOVE; D; FEH
|
||||
06A5; DOTLESS FEH WITH 3 DOTS BELOW; D; FEH
|
||||
06A6; DOTLESS FEH WITH 4 DOTS ABOVE; D; FEH
|
||||
06A7; DOTLESS QAF WITH DOT ABOVE; D; QAF
|
||||
06A8; DOTLESS QAF WITH 3 DOTS ABOVE; D; QAF
|
||||
06A9; KEHEH; D; GAF
|
||||
06AA; SWASH KAF; D; SWASH KAF
|
||||
06AB; KEHEH WITH ATTACHED RING BELOW; D; GAF
|
||||
06AC; KAF WITH DOT ABOVE; D; KAF
|
||||
06AD; KAF WITH 3 DOTS ABOVE; D; KAF
|
||||
06AE; KAF WITH 3 DOTS BELOW; D; KAF
|
||||
06AF; GAF; D; GAF
|
||||
06B0; GAF WITH ATTACHED RING BELOW; D; GAF
|
||||
06B1; GAF WITH 2 DOTS ABOVE; D; GAF
|
||||
06B2; GAF WITH 2 DOTS BELOW; D; GAF
|
||||
06B3; GAF WITH VERTICAL 2 DOTS BELOW; D; GAF
|
||||
06B4; GAF WITH 3 DOTS ABOVE; D; GAF
|
||||
06B5; LAM WITH V ABOVE; D; LAM
|
||||
06B6; LAM WITH DOT ABOVE; D; LAM
|
||||
06B7; LAM WITH 3 DOTS ABOVE; D; LAM
|
||||
06B8; LAM WITH 3 DOTS BELOW; D; LAM
|
||||
06B9; NOON WITH DOT BELOW; D; NOON
|
||||
06BA; DOTLESS NOON; D; NOON
|
||||
06BB; DOTLESS NOON WITH TAH ABOVE; D; NOON
|
||||
06BC; NOON WITH ATTACHED RING BELOW; D; NOON
|
||||
06BD; NYA; D; NYA
|
||||
06BE; KNOTTED HEH; D; KNOTTED HEH
|
||||
06BF; HAH WITH 3 DOTS BELOW AND DOT ABOVE; D; HAH
|
||||
06C0; DOTLESS TEH MARBUTA WITH HAMZA ABOVE; R; TEH MARBUTA
|
||||
06C1; HEH GOAL; D; HEH GOAL
|
||||
06C2; HEH GOAL WITH HAMZA ABOVE; D; HEH GOAL
|
||||
06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL
|
||||
06C4; WAW WITH ATTACHED RING WITHIN; R; WAW
|
||||
06C5; WAW WITH BAR; R; WAW
|
||||
06C6; WAW WITH V ABOVE; R; WAW
|
||||
06C7; WAW WITH DAMMA ABOVE; R; WAW
|
||||
06C8; WAW WITH ALEF ABOVE; R; WAW
|
||||
06C9; WAW WITH INVERTED V ABOVE; R; WAW
|
||||
06CA; WAW WITH 2 DOTS ABOVE; R; WAW
|
||||
06CB; WAW WITH 3 DOTS ABOVE; R; WAW
|
||||
06CC; FARSI YEH; D; FARSI YEH
|
||||
06CD; YEH WITH TAIL; R; YEH WITH TAIL
|
||||
06CE; FARSI YEH WITH V ABOVE; D; FARSI YEH
|
||||
06CF; WAW WITH DOT ABOVE; R; WAW
|
||||
06D0; DOTLESS YEH WITH VERTICAL 2 DOTS BELOW; D; YEH
|
||||
06D1; DOTLESS YEH WITH 3 DOTS BELOW; D; YEH
|
||||
06D2; YEH BARREE; R; YEH BARREE
|
||||
06D3; YEH BARREE WITH HAMZA ABOVE; R; YEH BARREE
|
||||
06D5; DOTLESS TEH MARBUTA; R; TEH MARBUTA
|
||||
06DD; ARABIC END OF AYAH; U; No_Joining_Group
|
||||
06EE; DAL WITH INVERTED V ABOVE; R; DAL
|
||||
06EF; REH WITH INVERTED V ABOVE; R; REH
|
||||
06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN
|
||||
06FB; SAD WITH DOT BELOW AND DOT ABOVE; D; SAD
|
||||
06FC; AIN WITH DOT BELOW AND DOT ABOVE; D; AIN
|
||||
06FF; KNOTTED HEH WITH INVERTED V ABOVE; D; KNOTTED HEH
|
||||
|
||||
# Syriac Characters
|
||||
|
||||
070F; SYRIAC ABBREVIATION MARK; T; No_Joining_Group
|
||||
0710; ALAPH; R; ALAPH
|
||||
0712; BETH; D; BETH
|
||||
0713; GAMAL; D; GAMAL
|
||||
0714; GAMAL GARSHUNI; D; GAMAL
|
||||
0715; DALATH; R; DALATH RISH
|
||||
0716; DOTLESS DALATH RISH; R; DALATH RISH
|
||||
0717; HE; R; HE
|
||||
0718; WAW; R; SYRIAC WAW
|
||||
0719; ZAIN; R; ZAIN
|
||||
071A; HETH; D; HETH
|
||||
071B; TETH; D; TETH
|
||||
071C; TETH GARSHUNI; D; TETH
|
||||
071D; YUDH; D; YUDH
|
||||
071E; YUDH HE; R; YUDH HE
|
||||
071F; KAPH; D; KAPH
|
||||
0720; LAMADH; D; LAMADH
|
||||
0721; MIM; D; MIM
|
||||
0722; NUN; D; NUN
|
||||
0723; SEMKATH; D; SEMKATH
|
||||
0724; FINAL SEMKATH; D; FINAL SEMKATH
|
||||
0725; E; D; E
|
||||
0726; PE; D; PE
|
||||
0727; REVERSED PE; D; REVERSED PE
|
||||
0728; SADHE; R; SADHE
|
||||
0729; QAPH; D; QAPH
|
||||
072A; RISH; R; DALATH RISH
|
||||
072B; SHIN; D; SHIN
|
||||
072C; TAW; R; TAW
|
||||
072D; PERSIAN BHETH; D; BETH
|
||||
072E; PERSIAN GHAMAL; D; GAMAL
|
||||
072F; PERSIAN DHALATH; R; DALATH RISH
|
||||
074D; SOGDIAN ZHAIN; R; ZHAIN
|
||||
074E; SOGDIAN KHAPH; D; KHAPH
|
||||
074F; SOGDIAN FE; D; FE
|
||||
|
||||
# Arabic Supplement Characters
|
||||
|
||||
0750; DOTLESS BEH WITH HORIZONTAL 3 DOTS BELOW; D; BEH
|
||||
0751; BEH WITH 3 DOTS ABOVE; D; BEH
|
||||
0752; DOTLESS BEH WITH INVERTED 3 DOTS BELOW; D; BEH
|
||||
0753; DOTLESS BEH WITH INVERTED 3 DOTS BELOW AND 2 DOTS ABOVE; D; BEH
|
||||
0754; DOTLESS BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH
|
||||
0755; DOTLESS BEH WITH INVERTED V BELOW; D; BEH
|
||||
0756; DOTLESS BEH WITH V ABOVE; D; BEH
|
||||
0757; HAH WITH 2 DOTS ABOVE; D; HAH
|
||||
0758; HAH WITH INVERTED 3 DOTS BELOW; D; HAH
|
||||
0759; DAL WITH VERTICAL 2 DOTS BELOW AND TAH ABOVE; R; DAL
|
||||
075A; DAL WITH INVERTED V BELOW; R; DAL
|
||||
075B; REH WITH BAR; R; REH
|
||||
075C; SEEN WITH 4 DOTS ABOVE; D; SEEN
|
||||
075D; AIN WITH 2 DOTS ABOVE; D; AIN
|
||||
075E; AIN WITH INVERTED 3 DOTS ABOVE; D; AIN
|
||||
075F; AIN WITH VERTICAL 2 DOTS ABOVE; D; AIN
|
||||
0760; DOTLESS FEH WITH 2 DOTS BELOW; D; FEH
|
||||
0761; DOTLESS FEH WITH INVERTED 3 DOTS BELOW; D; FEH
|
||||
0762; KEHEH WITH DOT ABOVE; D; GAF
|
||||
0763; KEHEH WITH 3 DOTS ABOVE; D; GAF
|
||||
0764; KEHEH WITH INVERTED 3 DOTS BELOW; D; GAF
|
||||
0765; MEEM WITH DOT ABOVE; D; MEEM
|
||||
0766; MEEM WITH DOT BELOW; D; MEEM
|
||||
0767; NOON WITH 2 DOTS BELOW; D; NOON
|
||||
0768; NOON WITH TAH ABOVE; D; NOON
|
||||
0769; NOON WITH V ABOVE; D; NOON
|
||||
076A; LAM WITH BAR; D; LAM
|
||||
076B; REH WITH VERTICAL 2 DOTS ABOVE; R; REH
|
||||
076C; REH WITH HAMZA ABOVE; R; REH
|
||||
076D; SEEN WITH VERTICAL 2 DOTS ABOVE; D; SEEN
|
||||
076E; HAH WITH TAH BELOW; D; HAH
|
||||
076F; HAH WITH TAH AND 2 DOTS BELOW; D; HAH
|
||||
0770; SEEN WITH 2 DOTS AND TAH ABOVE; D; SEEN
|
||||
0771; REH WITH 2 DOTS AND TAH ABOVE; R; REH
|
||||
0772; HAH WITH TAH ABOVE; D; HAH
|
||||
0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF
|
||||
0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF
|
||||
0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH
|
||||
0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH
|
||||
0777; DOTLESS YEH WITH DIGIT FOUR BELOW; D; YEH
|
||||
0778; WAW WITH DIGIT TWO ABOVE; R; WAW
|
||||
0779; WAW WITH DIGIT THREE ABOVE; R; WAW
|
||||
077A; BURUSHASKI YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE
|
||||
077B; BURUSHASKI YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE
|
||||
077C; HAH WITH DIGIT FOUR BELOW; D; HAH
|
||||
077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN
|
||||
077E; SEEN WITH INVERTED V ABOVE; D; SEEN
|
||||
077F; KAF WITH 2 DOTS ABOVE; D; KAF
|
||||
|
||||
# N'Ko Characters
|
||||
|
||||
07CA; NKO A; D; No_Joining_Group
|
||||
07CB; NKO EE; D; No_Joining_Group
|
||||
07CC; NKO I; D; No_Joining_Group
|
||||
07CD; NKO E; D; No_Joining_Group
|
||||
07CE; NKO U; D; No_Joining_Group
|
||||
07CF; NKO OO; D; No_Joining_Group
|
||||
07D0; NKO O; D; No_Joining_Group
|
||||
07D1; NKO DAGBASINNA; D; No_Joining_Group
|
||||
07D2; NKO N; D; No_Joining_Group
|
||||
07D3; NKO BA; D; No_Joining_Group
|
||||
07D4; NKO PA; D; No_Joining_Group
|
||||
07D5; NKO TA; D; No_Joining_Group
|
||||
07D6; NKO JA; D; No_Joining_Group
|
||||
07D7; NKO CHA; D; No_Joining_Group
|
||||
07D8; NKO DA; D; No_Joining_Group
|
||||
07D9; NKO RA; D; No_Joining_Group
|
||||
07DA; NKO RRA; D; No_Joining_Group
|
||||
07DB; NKO SA; D; No_Joining_Group
|
||||
07DC; NKO GBA; D; No_Joining_Group
|
||||
07DD; NKO FA; D; No_Joining_Group
|
||||
07DE; NKO KA; D; No_Joining_Group
|
||||
07DF; NKO LA; D; No_Joining_Group
|
||||
07E0; NKO NA WOLOSO; D; No_Joining_Group
|
||||
07E1; NKO MA; D; No_Joining_Group
|
||||
07E2; NKO NYA; D; No_Joining_Group
|
||||
07E3; NKO NA; D; No_Joining_Group
|
||||
07E4; NKO HA; D; No_Joining_Group
|
||||
07E5; NKO WA; D; No_Joining_Group
|
||||
07E6; NKO YA; D; No_Joining_Group
|
||||
07E7; NKO NYA WOLOSO; D; No_Joining_Group
|
||||
07E8; NKO JONA JA; D; No_Joining_Group
|
||||
07E9; NKO JONA CHA; D; No_Joining_Group
|
||||
07EA; NKO JONA RA; D; No_Joining_Group
|
||||
07FA; NKO LAJANYALAN; C; No_Joining_Group
|
||||
|
||||
# Mandaic Characters
|
||||
|
||||
0840; MANDAIC HALQA; R; No_Joining_Group
|
||||
0841; MANDAIC AB; D; No_Joining_Group
|
||||
0842; MANDAIC AG; D; No_Joining_Group
|
||||
0843; MANDAIC AD; D; No_Joining_Group
|
||||
0844; MANDAIC AH; D; No_Joining_Group
|
||||
0845; MANDAIC USHENNA; D; No_Joining_Group
|
||||
0846; MANDAIC AZ; R; No_Joining_Group
|
||||
0847; MANDAIC IT; R; No_Joining_Group
|
||||
0848; MANDAIC ATT; D; No_Joining_Group
|
||||
0849; MANDAIC AKSA; R; No_Joining_Group
|
||||
084A; MANDAIC AK; D; No_Joining_Group
|
||||
084B; MANDAIC AL; D; No_Joining_Group
|
||||
084C; MANDAIC AM; D; No_Joining_Group
|
||||
084D; MANDAIC AN; D; No_Joining_Group
|
||||
084E; MANDAIC AS; D; No_Joining_Group
|
||||
084F; MANDAIC IN; D; No_Joining_Group
|
||||
0850; MANDAIC AP; D; No_Joining_Group
|
||||
0851; MANDAIC ASZ; D; No_Joining_Group
|
||||
0852; MANDAIC AQ; D; No_Joining_Group
|
||||
0853; MANDAIC AR; D; No_Joining_Group
|
||||
0854; MANDAIC ASH; R; No_Joining_Group
|
||||
0855; MANDAIC AT; D; No_Joining_Group
|
||||
0856; MANDAIC DUSHENNA; R; No_Joining_Group
|
||||
0857; MANDAIC KAD; R; No_Joining_Group
|
||||
0858; MANDAIC AIN; R; No_Joining_Group
|
||||
|
||||
# Syriac Supplement Characters
|
||||
|
||||
0860; MALAYALAM NGA; D; MALAYALAM NGA
|
||||
0861; MALAYALAM JA; U; MALAYALAM JA
|
||||
0862; MALAYALAM NYA; D; MALAYALAM NYA
|
||||
0863; MALAYALAM TTA; D; MALAYALAM TTA
|
||||
0864; MALAYALAM NNA; D; MALAYALAM NNA
|
||||
0865; MALAYALAM NNNA; D; MALAYALAM NNNA
|
||||
0866; MALAYALAM BHA; U; MALAYALAM BHA
|
||||
0867; MALAYALAM RA; R; MALAYALAM RA
|
||||
0868; MALAYALAM LLA; D; MALAYALAM LLA
|
||||
0869; MALAYALAM LLLA; R; MALAYALAM LLLA
|
||||
086A; MALAYALAM SSA; R; MALAYALAM SSA
|
||||
|
||||
# Arabic Extended-A Characters
|
||||
|
||||
08A0; DOTLESS BEH WITH V BELOW; D; BEH
|
||||
08A1; BEH WITH HAMZA ABOVE; D; BEH
|
||||
08A2; HAH WITH DOT BELOW AND 2 DOTS ABOVE; D; HAH
|
||||
08A3; TAH WITH 2 DOTS ABOVE; D; TAH
|
||||
08A4; DOTLESS FEH WITH DOT BELOW AND 3 DOTS ABOVE; D; FEH
|
||||
08A5; QAF WITH DOT BELOW; D; QAF
|
||||
08A6; LAM WITH DOUBLE BAR; D; LAM
|
||||
08A7; MEEM WITH 3 DOTS ABOVE; D; MEEM
|
||||
08A8; YEH WITH HAMZA ABOVE; D; YEH
|
||||
08A9; YEH WITH DOT ABOVE; D; YEH
|
||||
08AA; REH WITH LOOP; R; REH
|
||||
08AB; WAW WITH DOT WITHIN; R; WAW
|
||||
08AC; ROHINGYA YEH; R; ROHINGYA YEH
|
||||
08AD; LOW ALEF; U; No_Joining_Group
|
||||
08AE; DAL WITH 3 DOTS BELOW; R; DAL
|
||||
08AF; SAD WITH 3 DOTS BELOW; D; SAD
|
||||
08B0; KEHEH WITH STROKE BELOW; D; GAF
|
||||
08B1; STRAIGHT WAW; R; STRAIGHT WAW
|
||||
08B2; REH WITH DOT AND INVERTED V ABOVE; R; REH
|
||||
08B3; AIN WITH 3 DOTS BELOW; D; AIN
|
||||
08B4; KAF WITH DOT BELOW; D; KAF
|
||||
08B6; BEH WITH MEEM ABOVE; D; BEH
|
||||
08B7; DOTLESS BEH WITH 3 DOTS BELOW AND MEEM ABOVE; D; BEH
|
||||
08B8; DOTLESS BEH WITH TEH ABOVE; D; BEH
|
||||
08B9; REH WITH NOON ABOVE; R; REH
|
||||
08BA; YEH WITH NOON ABOVE; D; YEH
|
||||
08BB; AFRICAN FEH; D; AFRICAN FEH
|
||||
08BC; AFRICAN QAF; D; AFRICAN QAF
|
||||
08BD; AFRICAN NOON; D; AFRICAN NOON
|
||||
08BE; DOTLESS BEH WITH 3 DOTS BELOW AND V ABOVE; D; BEH
|
||||
08BF; DOTLESS BEH WITH 2 DOTS AND V ABOVE; D; BEH
|
||||
08C0; DOTLESS BEH WITH TAH AND V ABOVE; D; BEH
|
||||
08C1; HAH WITH 3 DOTS BELOW AND V ABOVE; D; HAH
|
||||
08C2; KEHEH WITH V ABOVE; D; GAF
|
||||
08C3; AIN WITH DIAMOND 4 DOTS ABOVE; D; AIN
|
||||
08C4; AFRICAN QAF WITH 3 DOTS ABOVE; D; AFRICAN QAF
|
||||
08C5; HAH WITH DOT BELOW AND 3 DOTS ABOVE; D; HAH
|
||||
08C6; HAH WITH DIAMOND 4 DOTS BELOW; D; HAH
|
||||
08C7; LAM WITH TAH ABOVE; D; LAM
|
||||
08E2; ARABIC DISPUTED END OF AYAH; U; No_Joining_Group
|
||||
|
||||
# Mongolian Characters
|
||||
|
||||
1806; MONGOLIAN TODO SOFT HYPHEN; U; No_Joining_Group
|
||||
1807; MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER; D; No_Joining_Group
|
||||
180A; MONGOLIAN NIRUGU; C; No_Joining_Group
|
||||
180E; MONGOLIAN VOWEL SEPARATOR; U; No_Joining_Group
|
||||
1820; MONGOLIAN A; D; No_Joining_Group
|
||||
1821; MONGOLIAN E; D; No_Joining_Group
|
||||
1822; MONGOLIAN I; D; No_Joining_Group
|
||||
1823; MONGOLIAN O; D; No_Joining_Group
|
||||
1824; MONGOLIAN U; D; No_Joining_Group
|
||||
1825; MONGOLIAN OE; D; No_Joining_Group
|
||||
1826; MONGOLIAN UE; D; No_Joining_Group
|
||||
1827; MONGOLIAN EE; D; No_Joining_Group
|
||||
1828; MONGOLIAN NA; D; No_Joining_Group
|
||||
1829; MONGOLIAN ANG; D; No_Joining_Group
|
||||
182A; MONGOLIAN BA; D; No_Joining_Group
|
||||
182B; MONGOLIAN PA; D; No_Joining_Group
|
||||
182C; MONGOLIAN QA; D; No_Joining_Group
|
||||
182D; MONGOLIAN GA; D; No_Joining_Group
|
||||
182E; MONGOLIAN MA; D; No_Joining_Group
|
||||
182F; MONGOLIAN LA; D; No_Joining_Group
|
||||
1830; MONGOLIAN SA; D; No_Joining_Group
|
||||
1831; MONGOLIAN SHA; D; No_Joining_Group
|
||||
1832; MONGOLIAN TA; D; No_Joining_Group
|
||||
1833; MONGOLIAN DA; D; No_Joining_Group
|
||||
1834; MONGOLIAN CHA; D; No_Joining_Group
|
||||
1835; MONGOLIAN JA; D; No_Joining_Group
|
||||
1836; MONGOLIAN YA; D; No_Joining_Group
|
||||
1837; MONGOLIAN RA; D; No_Joining_Group
|
||||
1838; MONGOLIAN WA; D; No_Joining_Group
|
||||
1839; MONGOLIAN FA; D; No_Joining_Group
|
||||
183A; MONGOLIAN KA; D; No_Joining_Group
|
||||
183B; MONGOLIAN KHA; D; No_Joining_Group
|
||||
183C; MONGOLIAN TSA; D; No_Joining_Group
|
||||
183D; MONGOLIAN ZA; D; No_Joining_Group
|
||||
183E; MONGOLIAN HAA; D; No_Joining_Group
|
||||
183F; MONGOLIAN ZRA; D; No_Joining_Group
|
||||
1840; MONGOLIAN LHA; D; No_Joining_Group
|
||||
1841; MONGOLIAN ZHI; D; No_Joining_Group
|
||||
1842; MONGOLIAN CHI; D; No_Joining_Group
|
||||
1843; MONGOLIAN TODO LONG VOWEL SIGN; D; No_Joining_Group
|
||||
1844; MONGOLIAN TODO E; D; No_Joining_Group
|
||||
1845; MONGOLIAN TODO I; D; No_Joining_Group
|
||||
1846; MONGOLIAN TODO O; D; No_Joining_Group
|
||||
1847; MONGOLIAN TODO U; D; No_Joining_Group
|
||||
1848; MONGOLIAN TODO OE; D; No_Joining_Group
|
||||
1849; MONGOLIAN TODO UE; D; No_Joining_Group
|
||||
184A; MONGOLIAN TODO ANG; D; No_Joining_Group
|
||||
184B; MONGOLIAN TODO BA; D; No_Joining_Group
|
||||
184C; MONGOLIAN TODO PA; D; No_Joining_Group
|
||||
184D; MONGOLIAN TODO QA; D; No_Joining_Group
|
||||
184E; MONGOLIAN TODO GA; D; No_Joining_Group
|
||||
184F; MONGOLIAN TODO MA; D; No_Joining_Group
|
||||
1850; MONGOLIAN TODO TA; D; No_Joining_Group
|
||||
1851; MONGOLIAN TODO DA; D; No_Joining_Group
|
||||
1852; MONGOLIAN TODO CHA; D; No_Joining_Group
|
||||
1853; MONGOLIAN TODO JA; D; No_Joining_Group
|
||||
1854; MONGOLIAN TODO TSA; D; No_Joining_Group
|
||||
1855; MONGOLIAN TODO YA; D; No_Joining_Group
|
||||
1856; MONGOLIAN TODO WA; D; No_Joining_Group
|
||||
1857; MONGOLIAN TODO KA; D; No_Joining_Group
|
||||
1858; MONGOLIAN TODO GAA; D; No_Joining_Group
|
||||
1859; MONGOLIAN TODO HAA; D; No_Joining_Group
|
||||
185A; MONGOLIAN TODO JIA; D; No_Joining_Group
|
||||
185B; MONGOLIAN TODO NIA; D; No_Joining_Group
|
||||
185C; MONGOLIAN TODO DZA; D; No_Joining_Group
|
||||
185D; MONGOLIAN SIBE E; D; No_Joining_Group
|
||||
185E; MONGOLIAN SIBE I; D; No_Joining_Group
|
||||
185F; MONGOLIAN SIBE IY; D; No_Joining_Group
|
||||
1860; MONGOLIAN SIBE UE; D; No_Joining_Group
|
||||
1861; MONGOLIAN SIBE U; D; No_Joining_Group
|
||||
1862; MONGOLIAN SIBE ANG; D; No_Joining_Group
|
||||
1863; MONGOLIAN SIBE KA; D; No_Joining_Group
|
||||
1864; MONGOLIAN SIBE GA; D; No_Joining_Group
|
||||
1865; MONGOLIAN SIBE HA; D; No_Joining_Group
|
||||
1866; MONGOLIAN SIBE PA; D; No_Joining_Group
|
||||
1867; MONGOLIAN SIBE SHA; D; No_Joining_Group
|
||||
1868; MONGOLIAN SIBE TA; D; No_Joining_Group
|
||||
1869; MONGOLIAN SIBE DA; D; No_Joining_Group
|
||||
186A; MONGOLIAN SIBE JA; D; No_Joining_Group
|
||||
186B; MONGOLIAN SIBE FA; D; No_Joining_Group
|
||||
186C; MONGOLIAN SIBE GAA; D; No_Joining_Group
|
||||
186D; MONGOLIAN SIBE HAA; D; No_Joining_Group
|
||||
186E; MONGOLIAN SIBE TSA; D; No_Joining_Group
|
||||
186F; MONGOLIAN SIBE ZA; D; No_Joining_Group
|
||||
1870; MONGOLIAN SIBE RAA; D; No_Joining_Group
|
||||
1871; MONGOLIAN SIBE CHA; D; No_Joining_Group
|
||||
1872; MONGOLIAN SIBE ZHA; D; No_Joining_Group
|
||||
1873; MONGOLIAN MANCHU I; D; No_Joining_Group
|
||||
1874; MONGOLIAN MANCHU KA; D; No_Joining_Group
|
||||
1875; MONGOLIAN MANCHU RA; D; No_Joining_Group
|
||||
1876; MONGOLIAN MANCHU FA; D; No_Joining_Group
|
||||
1877; MONGOLIAN MANCHU ZHA; D; No_Joining_Group
|
||||
1878; MONGOLIAN MANCHU CHA WITH 2 DOTS; D; No_Joining_Group
|
||||
1880; MONGOLIAN ALI GALI ANUSVARA ONE; U; No_Joining_Group
|
||||
1881; MONGOLIAN ALI GALI VISARGA ONE; U; No_Joining_Group
|
||||
1882; MONGOLIAN ALI GALI DAMARU; U; No_Joining_Group
|
||||
1883; MONGOLIAN ALI GALI UBADAMA; U; No_Joining_Group
|
||||
1884; MONGOLIAN ALI GALI INVERTED UBADAMA; U; No_Joining_Group
|
||||
1885; MONGOLIAN ALI GALI BALUDA; T; No_Joining_Group
|
||||
1886; MONGOLIAN ALI GALI THREE BALUDA; T; No_Joining_Group
|
||||
1887; MONGOLIAN ALI GALI A; D; No_Joining_Group
|
||||
1888; MONGOLIAN ALI GALI I; D; No_Joining_Group
|
||||
1889; MONGOLIAN ALI GALI KA; D; No_Joining_Group
|
||||
188A; MONGOLIAN ALI GALI NGA; D; No_Joining_Group
|
||||
188B; MONGOLIAN ALI GALI CA; D; No_Joining_Group
|
||||
188C; MONGOLIAN ALI GALI TTA; D; No_Joining_Group
|
||||
188D; MONGOLIAN ALI GALI TTHA; D; No_Joining_Group
|
||||
188E; MONGOLIAN ALI GALI DDA; D; No_Joining_Group
|
||||
188F; MONGOLIAN ALI GALI NNA; D; No_Joining_Group
|
||||
1890; MONGOLIAN ALI GALI TA; D; No_Joining_Group
|
||||
1891; MONGOLIAN ALI GALI DA; D; No_Joining_Group
|
||||
1892; MONGOLIAN ALI GALI PA; D; No_Joining_Group
|
||||
1893; MONGOLIAN ALI GALI PHA; D; No_Joining_Group
|
||||
1894; MONGOLIAN ALI GALI SSA; D; No_Joining_Group
|
||||
1895; MONGOLIAN ALI GALI ZHA; D; No_Joining_Group
|
||||
1896; MONGOLIAN ALI GALI ZA; D; No_Joining_Group
|
||||
1897; MONGOLIAN ALI GALI AH; D; No_Joining_Group
|
||||
1898; MONGOLIAN TODO ALI GALI TA; D; No_Joining_Group
|
||||
1899; MONGOLIAN TODO ALI GALI ZHA; D; No_Joining_Group
|
||||
189A; MONGOLIAN MANCHU ALI GALI GHA; D; No_Joining_Group
|
||||
189B; MONGOLIAN MANCHU ALI GALI NGA; D; No_Joining_Group
|
||||
189C; MONGOLIAN MANCHU ALI GALI CA; D; No_Joining_Group
|
||||
189D; MONGOLIAN MANCHU ALI GALI JHA; D; No_Joining_Group
|
||||
189E; MONGOLIAN MANCHU ALI GALI TTA; D; No_Joining_Group
|
||||
189F; MONGOLIAN MANCHU ALI GALI DDHA; D; No_Joining_Group
|
||||
18A0; MONGOLIAN MANCHU ALI GALI TA; D; No_Joining_Group
|
||||
18A1; MONGOLIAN MANCHU ALI GALI DHA; D; No_Joining_Group
|
||||
18A2; MONGOLIAN MANCHU ALI GALI SSA; D; No_Joining_Group
|
||||
18A3; MONGOLIAN MANCHU ALI GALI CYA; D; No_Joining_Group
|
||||
18A4; MONGOLIAN MANCHU ALI GALI ZHA; D; No_Joining_Group
|
||||
18A5; MONGOLIAN MANCHU ALI GALI ZA; D; No_Joining_Group
|
||||
18A6; MONGOLIAN ALI GALI HALF U; D; No_Joining_Group
|
||||
18A7; MONGOLIAN ALI GALI HALF YA; D; No_Joining_Group
|
||||
18A8; MONGOLIAN MANCHU ALI GALI BHA; D; No_Joining_Group
|
||||
18AA; MONGOLIAN MANCHU ALI GALI LHA; D; No_Joining_Group
|
||||
|
||||
# Other
|
||||
|
||||
200C; ZERO WIDTH NON-JOINER; U; No_Joining_Group
|
||||
200D; ZERO WIDTH JOINER; C; No_Joining_Group
|
||||
202F; NARROW NO-BREAK SPACE; U; No_Joining_Group
|
||||
2066; LEFT-TO-RIGHT ISOLATE; U; No_Joining_Group
|
||||
2067; RIGHT-TO-LEFT ISOLATE; U; No_Joining_Group
|
||||
2068; FIRST STRONG ISOLATE; U; No_Joining_Group
|
||||
2069; POP DIRECTIONAL ISOLATE; U; No_Joining_Group
|
||||
|
||||
# Phags-Pa Characters
|
||||
|
||||
A840; PHAGS-PA KA; D; No_Joining_Group
|
||||
A841; PHAGS-PA KHA; D; No_Joining_Group
|
||||
A842; PHAGS-PA GA; D; No_Joining_Group
|
||||
A843; PHAGS-PA NGA; D; No_Joining_Group
|
||||
A844; PHAGS-PA CA; D; No_Joining_Group
|
||||
A845; PHAGS-PA CHA; D; No_Joining_Group
|
||||
A846; PHAGS-PA JA; D; No_Joining_Group
|
||||
A847; PHAGS-PA NYA; D; No_Joining_Group
|
||||
A848; PHAGS-PA TA; D; No_Joining_Group
|
||||
A849; PHAGS-PA THA; D; No_Joining_Group
|
||||
A84A; PHAGS-PA DA; D; No_Joining_Group
|
||||
A84B; PHAGS-PA NA; D; No_Joining_Group
|
||||
A84C; PHAGS-PA PA; D; No_Joining_Group
|
||||
A84D; PHAGS-PA PHA; D; No_Joining_Group
|
||||
A84E; PHAGS-PA BA; D; No_Joining_Group
|
||||
A84F; PHAGS-PA MA; D; No_Joining_Group
|
||||
A850; PHAGS-PA TSA; D; No_Joining_Group
|
||||
A851; PHAGS-PA TSHA; D; No_Joining_Group
|
||||
A852; PHAGS-PA DZA; D; No_Joining_Group
|
||||
A853; PHAGS-PA WA; D; No_Joining_Group
|
||||
A854; PHAGS-PA ZHA; D; No_Joining_Group
|
||||
A855; PHAGS-PA ZA; D; No_Joining_Group
|
||||
A856; PHAGS-PA SMALL A; D; No_Joining_Group
|
||||
A857; PHAGS-PA YA; D; No_Joining_Group
|
||||
A858; PHAGS-PA RA; D; No_Joining_Group
|
||||
A859; PHAGS-PA LA; D; No_Joining_Group
|
||||
A85A; PHAGS-PA SHA; D; No_Joining_Group
|
||||
A85B; PHAGS-PA SA; D; No_Joining_Group
|
||||
A85C; PHAGS-PA HA; D; No_Joining_Group
|
||||
A85D; PHAGS-PA A; D; No_Joining_Group
|
||||
A85E; PHAGS-PA I; D; No_Joining_Group
|
||||
A85F; PHAGS-PA U; D; No_Joining_Group
|
||||
A860; PHAGS-PA E; D; No_Joining_Group
|
||||
A861; PHAGS-PA O; D; No_Joining_Group
|
||||
A862; PHAGS-PA QA; D; No_Joining_Group
|
||||
A863; PHAGS-PA XA; D; No_Joining_Group
|
||||
A864; PHAGS-PA FA; D; No_Joining_Group
|
||||
A865; PHAGS-PA GGA; D; No_Joining_Group
|
||||
A866; PHAGS-PA EE; D; No_Joining_Group
|
||||
A867; PHAGS-PA SUBJOINED WA; D; No_Joining_Group
|
||||
A868; PHAGS-PA SUBJOINED YA; D; No_Joining_Group
|
||||
A869; PHAGS-PA TTA; D; No_Joining_Group
|
||||
A86A; PHAGS-PA TTHA; D; No_Joining_Group
|
||||
A86B; PHAGS-PA DDA; D; No_Joining_Group
|
||||
A86C; PHAGS-PA NNA; D; No_Joining_Group
|
||||
A86D; PHAGS-PA ALTERNATE YA; D; No_Joining_Group
|
||||
A86E; PHAGS-PA VOICELESS SHA; D; No_Joining_Group
|
||||
A86F; PHAGS-PA VOICED HA; D; No_Joining_Group
|
||||
A870; PHAGS-PA ASPIRATED FA; D; No_Joining_Group
|
||||
A871; PHAGS-PA SUBJOINED RA; D; No_Joining_Group
|
||||
A872; PHAGS-PA SUPERFIXED RA; L; No_Joining_Group
|
||||
A873; PHAGS-PA CANDRABINDU; U; No_Joining_Group
|
||||
|
||||
# Manichaean Characters
|
||||
|
||||
10AC0; MANICHAEAN ALEPH; D; MANICHAEAN ALEPH
|
||||
10AC1; MANICHAEAN BETH; D; MANICHAEAN BETH
|
||||
10AC2; MANICHAEAN BETH WITH 2 DOTS ABOVE; D; MANICHAEAN BETH
|
||||
10AC3; MANICHAEAN GIMEL; D; MANICHAEAN GIMEL
|
||||
10AC4; MANICHAEAN GIMEL WITH ATTACHED RING BELOW; D; MANICHAEAN GIMEL
|
||||
10AC5; MANICHAEAN DALETH; R; MANICHAEAN DALETH
|
||||
10AC6; MANICHAEAN HE; U; No_Joining_Group
|
||||
10AC7; MANICHAEAN WAW; R; MANICHAEAN WAW
|
||||
10AC8; MANICHAEAN UD; U; No_Joining_Group
|
||||
10AC9; MANICHAEAN ZAYIN; R; MANICHAEAN ZAYIN
|
||||
10ACA; MANICHAEAN ZAYIN WITH 2 DOTS ABOVE; R; MANICHAEAN ZAYIN
|
||||
10ACB; MANICHAEAN JAYIN; U; No_Joining_Group
|
||||
10ACC; MANICHAEAN JAYIN WITH 2 DOTS ABOVE; U; No_Joining_Group
|
||||
10ACD; MANICHAEAN HETH; L; MANICHAEAN HETH
|
||||
10ACE; MANICHAEAN TETH; R; MANICHAEAN TETH
|
||||
10ACF; MANICHAEAN YODH; R; MANICHAEAN YODH
|
||||
10AD0; MANICHAEAN KAPH; R; MANICHAEAN KAPH
|
||||
10AD1; MANICHAEAN KAPH WITH DOT ABOVE; R; MANICHAEAN KAPH
|
||||
10AD2; MANICHAEAN KAPH WITH 2 DOTS ABOVE; R; MANICHAEAN KAPH
|
||||
10AD3; MANICHAEAN LAMEDH; D; MANICHAEAN LAMEDH
|
||||
10AD4; MANICHAEAN DHAMEDH; D; MANICHAEAN DHAMEDH
|
||||
10AD5; MANICHAEAN THAMEDH; D; MANICHAEAN THAMEDH
|
||||
10AD6; MANICHAEAN MEM; D; MANICHAEAN MEM
|
||||
10AD7; MANICHAEAN NUN; L; MANICHAEAN NUN
|
||||
10AD8; MANICHAEAN SAMEKH; D; MANICHAEAN SAMEKH
|
||||
10AD9; MANICHAEAN AYIN; D; MANICHAEAN AYIN
|
||||
10ADA; MANICHAEAN AYIN WITH 2 DOTS ABOVE; D; MANICHAEAN AYIN
|
||||
10ADB; MANICHAEAN PE; D; MANICHAEAN PE
|
||||
10ADC; MANICHAEAN PE WITH DOT ABOVE; D; MANICHAEAN PE
|
||||
10ADD; MANICHAEAN SADHE; R; MANICHAEAN SADHE
|
||||
10ADE; MANICHAEAN QOPH; D; MANICHAEAN QOPH
|
||||
10ADF; MANICHAEAN QOPH WITH DOT ABOVE; D; MANICHAEAN QOPH
|
||||
10AE0; MANICHAEAN QOPH WITH 2 DOTS ABOVE; D; MANICHAEAN QOPH
|
||||
10AE1; MANICHAEAN RESH; R; MANICHAEAN RESH
|
||||
10AE2; MANICHAEAN SHIN; U; No_Joining_Group
|
||||
10AE3; MANICHAEAN SHIN WITH 2 DOTS ABOVE; U; No_Joining_Group
|
||||
10AE4; MANICHAEAN TAW; R; MANICHAEAN TAW
|
||||
10AEB; MANICHAEAN ONE; D; MANICHAEAN ONE
|
||||
10AEC; MANICHAEAN FIVE; D; MANICHAEAN FIVE
|
||||
10AED; MANICHAEAN TEN; D; MANICHAEAN TEN
|
||||
10AEE; MANICHAEAN TWENTY; D; MANICHAEAN TWENTY
|
||||
10AEF; MANICHAEAN HUNDRED; R; MANICHAEAN HUNDRED
|
||||
|
||||
# Psalter Pahlavi Characters
|
||||
|
||||
10B80; PSALTER PAHLAVI ALEPH; D; No_Joining_Group
|
||||
10B81; PSALTER PAHLAVI BETH; R; No_Joining_Group
|
||||
10B82; PSALTER PAHLAVI GIMEL; D; No_Joining_Group
|
||||
10B83; PSALTER PAHLAVI DALETH; R; No_Joining_Group
|
||||
10B84; PSALTER PAHLAVI HE; R; No_Joining_Group
|
||||
10B85; PSALTER PAHLAVI WAW-AYIN-RESH; R; No_Joining_Group
|
||||
10B86; PSALTER PAHLAVI ZAYIN; D; No_Joining_Group
|
||||
10B87; PSALTER PAHLAVI HETH; D; No_Joining_Group
|
||||
10B88; PSALTER PAHLAVI YODH; D; No_Joining_Group
|
||||
10B89; PSALTER PAHLAVI KAPH; R; No_Joining_Group
|
||||
10B8A; PSALTER PAHLAVI LAMEDH; D; No_Joining_Group
|
||||
10B8B; PSALTER PAHLAVI MEM-QOPH; D; No_Joining_Group
|
||||
10B8C; PSALTER PAHLAVI NUN; R; No_Joining_Group
|
||||
10B8D; PSALTER PAHLAVI SAMEKH; D; No_Joining_Group
|
||||
10B8E; PSALTER PAHLAVI PE; R; No_Joining_Group
|
||||
10B8F; PSALTER PAHLAVI SADHE; R; No_Joining_Group
|
||||
10B90; PSALTER PAHLAVI SHIN; D; No_Joining_Group
|
||||
10B91; PSALTER PAHLAVI TAW; R; No_Joining_Group
|
||||
10BA9; PSALTER PAHLAVI ONE; R; No_Joining_Group
|
||||
10BAA; PSALTER PAHLAVI TWO; R; No_Joining_Group
|
||||
10BAB; PSALTER PAHLAVI THREE; R; No_Joining_Group
|
||||
10BAC; PSALTER PAHLAVI FOUR; R; No_Joining_Group
|
||||
10BAD; PSALTER PAHLAVI TEN; D; No_Joining_Group
|
||||
10BAE; PSALTER PAHLAVI TWENTY; D; No_Joining_Group
|
||||
10BAF; PSALTER PAHLAVI HUNDRED; U; No_Joining_Group
|
||||
|
||||
# Hanifi Rohingya Characters
|
||||
|
||||
10D00; HANIFI ROHINGYA A; L; No_Joining_Group
|
||||
10D01; HANIFI ROHINGYA BA; D; No_Joining_Group
|
||||
10D02; HANIFI ROHINGYA PA; D; HANIFI ROHINGYA PA
|
||||
10D03; HANIFI ROHINGYA TA; D; No_Joining_Group
|
||||
10D04; HANIFI ROHINGYA TTA; D; No_Joining_Group
|
||||
10D05; HANIFI ROHINGYA JA; D; No_Joining_Group
|
||||
10D06; HANIFI ROHINGYA CA; D; No_Joining_Group
|
||||
10D07; HANIFI ROHINGYA HA; D; No_Joining_Group
|
||||
10D08; HANIFI ROHINGYA KHA; D; No_Joining_Group
|
||||
10D09; HANIFI ROHINGYA PA WITH DOT ABOVE; D; HANIFI ROHINGYA PA
|
||||
10D0A; HANIFI ROHINGYA DA; D; No_Joining_Group
|
||||
10D0B; HANIFI ROHINGYA DDA; D; No_Joining_Group
|
||||
10D0C; HANIFI ROHINGYA RA; D; No_Joining_Group
|
||||
10D0D; HANIFI ROHINGYA RRA; D; No_Joining_Group
|
||||
10D0E; HANIFI ROHINGYA ZA; D; No_Joining_Group
|
||||
10D0F; HANIFI ROHINGYA SA; D; No_Joining_Group
|
||||
10D10; HANIFI ROHINGYA SHA; D; No_Joining_Group
|
||||
10D11; HANIFI ROHINGYA KA; D; No_Joining_Group
|
||||
10D12; HANIFI ROHINGYA GA; D; No_Joining_Group
|
||||
10D13; HANIFI ROHINGYA LA; D; No_Joining_Group
|
||||
10D14; HANIFI ROHINGYA MA; D; No_Joining_Group
|
||||
10D15; HANIFI ROHINGYA NA; D; No_Joining_Group
|
||||
10D16; HANIFI ROHINGYA WA; D; No_Joining_Group
|
||||
10D17; HANIFI ROHINGYA KINNA WA; D; No_Joining_Group
|
||||
10D18; HANIFI ROHINGYA YA; D; No_Joining_Group
|
||||
10D19; HANIFI ROHINGYA KINNA YA; D; HANIFI ROHINGYA KINNA YA
|
||||
10D1A; HANIFI ROHINGYA NGA; D; No_Joining_Group
|
||||
10D1B; HANIFI ROHINGYA NYA; D; No_Joining_Group
|
||||
10D1C; HANIFI ROHINGYA PA WITH 3 DOTS ABOVE; D; HANIFI ROHINGYA PA
|
||||
10D1D; HANIFI ROHINGYA VOWEL A; D; No_Joining_Group
|
||||
10D1E; HANIFI ROHINGYA DOTLESS KINNA YA WITH LEFT-FACING HOOK BELOW; D; HANIFI ROHINGYA KINNA YA
|
||||
10D1F; HANIFI ROHINGYA VOWEL U; D; No_Joining_Group
|
||||
10D20; HANIFI ROHINGYA DOTLESS KINNA YA WITH RIGHT-FACING HOOK BELOW; D; HANIFI ROHINGYA KINNA YA
|
||||
10D21; HANIFI ROHINGYA VOWEL O; D; No_Joining_Group
|
||||
10D22; HANIFI ROHINGYA SAKIN; R; No_Joining_Group
|
||||
10D23; HANIFI ROHINGYA DOTLESS KINNA YA WITH DOT ABOVE; D; HANIFI ROHINGYA KINNA YA
|
||||
|
||||
# Sogdian Characters
|
||||
|
||||
10F30; SOGDIAN ALEPH; D; No_Joining_Group
|
||||
10F31; SOGDIAN BETH; D; No_Joining_Group
|
||||
10F32; SOGDIAN GIMEL; D; No_Joining_Group
|
||||
10F33; SOGDIAN HE; R; No_Joining_Group
|
||||
10F34; SOGDIAN WAW; D; No_Joining_Group
|
||||
10F35; SOGDIAN ZAYIN; D; No_Joining_Group
|
||||
10F36; SOGDIAN HETH; D; No_Joining_Group
|
||||
10F37; SOGDIAN YODH; D; No_Joining_Group
|
||||
10F38; SOGDIAN KAPH; D; No_Joining_Group
|
||||
10F39; SOGDIAN LAMEDH; D; No_Joining_Group
|
||||
10F3A; SOGDIAN MEM; D; No_Joining_Group
|
||||
10F3B; SOGDIAN NUN; D; No_Joining_Group
|
||||
10F3C; SOGDIAN SAMEKH; D; No_Joining_Group
|
||||
10F3D; SOGDIAN AYIN; D; No_Joining_Group
|
||||
10F3E; SOGDIAN PE; D; No_Joining_Group
|
||||
10F3F; SOGDIAN SADHE; D; No_Joining_Group
|
||||
10F40; SOGDIAN RESH-AYIN; D; No_Joining_Group
|
||||
10F41; SOGDIAN SHIN; D; No_Joining_Group
|
||||
10F42; SOGDIAN TAW; D; No_Joining_Group
|
||||
10F43; SOGDIAN FETH; D; No_Joining_Group
|
||||
10F44; SOGDIAN LESH; D; No_Joining_Group
|
||||
10F45; SOGDIAN INDEPENDENT SHIN; U; No_Joining_Group
|
||||
10F51; SOGDIAN ONE; D; No_Joining_Group
|
||||
10F52; SOGDIAN TEN; D; No_Joining_Group
|
||||
10F53; SOGDIAN TWENTY; D; No_Joining_Group
|
||||
10F54; SOGDIAN ONE HUNDRED; R; No_Joining_Group
|
||||
|
||||
# Chorasmian Characters
|
||||
|
||||
10FB0; CHORASMIAN ALEPH; D; No_Joining_Group
|
||||
10FB1; CHORASMIAN SMALL ALEPH; U; No_Joining_Group
|
||||
10FB2; CHORASMIAN BETH; D; No_Joining_Group
|
||||
10FB3; CHORASMIAN GIMEL; D; No_Joining_Group
|
||||
10FB4; CHORASMIAN DALETH; R; No_Joining_Group
|
||||
10FB5; CHORASMIAN HE; R; No_Joining_Group
|
||||
10FB6; CHORASMIAN WAW; R; No_Joining_Group
|
||||
10FB7; CHORASMIAN CURLED WAW; U; No_Joining_Group
|
||||
10FB8; CHORASMIAN ZAYIN; D; No_Joining_Group
|
||||
10FB9; CHORASMIAN HETH; R; No_Joining_Group
|
||||
10FBA; CHORASMIAN YODH; R; No_Joining_Group
|
||||
10FBB; CHORASMIAN KAPH; D; No_Joining_Group
|
||||
10FBC; CHORASMIAN LAMEDH; D; No_Joining_Group
|
||||
10FBD; CHORASMIAN MEM; R; No_Joining_Group
|
||||
10FBE; CHORASMIAN NUN; D; No_Joining_Group
|
||||
10FBF; CHORASMIAN SAMEKH; D; No_Joining_Group
|
||||
10FC0; CHORASMIAN AYIN; U; No_Joining_Group
|
||||
10FC1; CHORASMIAN PE; D; No_Joining_Group
|
||||
10FC2; CHORASMIAN RESH; R; No_Joining_Group
|
||||
10FC3; CHORASMIAN SHIN; R; No_Joining_Group
|
||||
10FC4; CHORASMIAN TAW; D; No_Joining_Group
|
||||
10FC5; CHORASMIAN ONE; U; No_Joining_Group
|
||||
10FC6; CHORASMIAN TWO; U; No_Joining_Group
|
||||
10FC7; CHORASMIAN THREE; U; No_Joining_Group
|
||||
10FC8; CHORASMIAN FOUR; U; No_Joining_Group
|
||||
10FC9; CHORASMIAN TEN; R; No_Joining_Group
|
||||
10FCA; CHORASMIAN TWENTY; D; No_Joining_Group
|
||||
10FCB; CHORASMIAN ONE HUNDRED; L; No_Joining_Group
|
||||
|
||||
# Kaithi Number Signs
|
||||
# These are prepended concatenation marks, comparable
|
||||
# to the number signs in the Arabic script.
|
||||
# Listed here for consistency in property values.
|
||||
|
||||
110BD; KAITHI NUMBER SIGN; U; No_Joining_Group
|
||||
110CD; KAITHI NUMBER SIGN ABOVE; U; No_Joining_Group
|
||||
|
||||
# Adlam Characters
|
||||
|
||||
1E900;ADLAM CAPITAL ALIF; D; No_Joining_Group
|
||||
1E901;ADLAM CAPITAL DAALI; D; No_Joining_Group
|
||||
1E902;ADLAM CAPITAL LAAM; D; No_Joining_Group
|
||||
1E903;ADLAM CAPITAL MIIM; D; No_Joining_Group
|
||||
1E904;ADLAM CAPITAL BA; D; No_Joining_Group
|
||||
1E905;ADLAM CAPITAL SINNYIIYHE; D; No_Joining_Group
|
||||
1E906;ADLAM CAPITAL PE; D; No_Joining_Group
|
||||
1E907;ADLAM CAPITAL BHE; D; No_Joining_Group
|
||||
1E908;ADLAM CAPITAL RA; D; No_Joining_Group
|
||||
1E909;ADLAM CAPITAL E; D; No_Joining_Group
|
||||
1E90A;ADLAM CAPITAL FA; D; No_Joining_Group
|
||||
1E90B;ADLAM CAPITAL I; D; No_Joining_Group
|
||||
1E90C;ADLAM CAPITAL O; D; No_Joining_Group
|
||||
1E90D;ADLAM CAPITAL DHA; D; No_Joining_Group
|
||||
1E90E;ADLAM CAPITAL YHE; D; No_Joining_Group
|
||||
1E90F;ADLAM CAPITAL WAW; D; No_Joining_Group
|
||||
1E910;ADLAM CAPITAL NUN; D; No_Joining_Group
|
||||
1E911;ADLAM CAPITAL KAF; D; No_Joining_Group
|
||||
1E912;ADLAM CAPITAL YA; D; No_Joining_Group
|
||||
1E913;ADLAM CAPITAL U; D; No_Joining_Group
|
||||
1E914;ADLAM CAPITAL JIIM; D; No_Joining_Group
|
||||
1E915;ADLAM CAPITAL CHI; D; No_Joining_Group
|
||||
1E916;ADLAM CAPITAL HA; D; No_Joining_Group
|
||||
1E917;ADLAM CAPITAL QAAF; D; No_Joining_Group
|
||||
1E918;ADLAM CAPITAL GA; D; No_Joining_Group
|
||||
1E919;ADLAM CAPITAL NYA; D; No_Joining_Group
|
||||
1E91A;ADLAM CAPITAL TU; D; No_Joining_Group
|
||||
1E91B;ADLAM CAPITAL NHA; D; No_Joining_Group
|
||||
1E91C;ADLAM CAPITAL VA; D; No_Joining_Group
|
||||
1E91D;ADLAM CAPITAL KHA; D; No_Joining_Group
|
||||
1E91E;ADLAM CAPITAL GBE; D; No_Joining_Group
|
||||
1E91F;ADLAM CAPITAL ZAL; D; No_Joining_Group
|
||||
1E920;ADLAM CAPITAL KPO; D; No_Joining_Group
|
||||
1E921;ADLAM CAPITAL SHA; D; No_Joining_Group
|
||||
1E922;ADLAM SMALL ALIF; D; No_Joining_Group
|
||||
1E923;ADLAM SMALL DAALI; D; No_Joining_Group
|
||||
1E924;ADLAM SMALL LAAM; D; No_Joining_Group
|
||||
1E925;ADLAM SMALL MIIM; D; No_Joining_Group
|
||||
1E926;ADLAM SMALL BA; D; No_Joining_Group
|
||||
1E927;ADLAM SMALL SINNYIIYHE; D; No_Joining_Group
|
||||
1E928;ADLAM SMALL PE; D; No_Joining_Group
|
||||
1E929;ADLAM SMALL BHE; D; No_Joining_Group
|
||||
1E92A;ADLAM SMALL RA; D; No_Joining_Group
|
||||
1E92B;ADLAM SMALL E; D; No_Joining_Group
|
||||
1E92C;ADLAM SMALL FA; D; No_Joining_Group
|
||||
1E92D;ADLAM SMALL I; D; No_Joining_Group
|
||||
1E92E;ADLAM SMALL O; D; No_Joining_Group
|
||||
1E92F;ADLAM SMALL DHA; D; No_Joining_Group
|
||||
1E930;ADLAM SMALL YHE; D; No_Joining_Group
|
||||
1E931;ADLAM SMALL WAW; D; No_Joining_Group
|
||||
1E932;ADLAM SMALL NUN; D; No_Joining_Group
|
||||
1E933;ADLAM SMALL KAF; D; No_Joining_Group
|
||||
1E934;ADLAM SMALL YA; D; No_Joining_Group
|
||||
1E935;ADLAM SMALL U; D; No_Joining_Group
|
||||
1E936;ADLAM SMALL JIIM; D; No_Joining_Group
|
||||
1E937;ADLAM SMALL CHI; D; No_Joining_Group
|
||||
1E938;ADLAM SMALL HA; D; No_Joining_Group
|
||||
1E939;ADLAM SMALL QAAF; D; No_Joining_Group
|
||||
1E93A;ADLAM SMALL GA; D; No_Joining_Group
|
||||
1E93B;ADLAM SMALL NYA; D; No_Joining_Group
|
||||
1E93C;ADLAM SMALL TU; D; No_Joining_Group
|
||||
1E93D;ADLAM SMALL NHA; D; No_Joining_Group
|
||||
1E93E;ADLAM SMALL VA; D; No_Joining_Group
|
||||
1E93F;ADLAM SMALL KHA; D; No_Joining_Group
|
||||
1E940;ADLAM SMALL GBE; D; No_Joining_Group
|
||||
1E941;ADLAM SMALL ZAL; D; No_Joining_Group
|
||||
1E942;ADLAM SMALL KPO; D; No_Joining_Group
|
||||
1E943;ADLAM SMALL SHA; D; No_Joining_Group
|
||||
1E94B;ADLAM NASALIZATION MARK; T; No_Joining_Group
|
||||
|
||||
# EOF
|
185
bgrabitmap/dev/parseunicode/BidiBrackets.txt
Normal file
185
bgrabitmap/dev/parseunicode/BidiBrackets.txt
Normal file
@@ -0,0 +1,185 @@
|
||||
# BidiBrackets-13.0.0.txt
|
||||
# Date: 2019-09-09, 19:31:00 GMT [AG, LI, KW]
|
||||
# © 2019 Unicode®, Inc.
|
||||
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
|
||||
# For terms of use, see http://www.unicode.org/terms_of_use.html
|
||||
#
|
||||
# Unicode Character Database
|
||||
# For documentation, see http://www.unicode.org/reports/tr44/
|
||||
#
|
||||
# Bidi_Paired_Bracket and Bidi_Paired_Bracket_Type Properties
|
||||
#
|
||||
# This file is a normative contributory data file in the Unicode
|
||||
# Character Database.
|
||||
#
|
||||
# Bidi_Paired_Bracket is a normative property of type Miscellaneous,
|
||||
# which establishes a mapping between characters that are treated as
|
||||
# bracket pairs by the Unicode Bidirectional Algorithm.
|
||||
#
|
||||
# Bidi_Paired_Bracket_Type is a normative property of type Enumeration,
|
||||
# which classifies characters into opening and closing paired brackets
|
||||
# for the purposes of the Unicode Bidirectional Algorithm.
|
||||
#
|
||||
# This file lists the set of code points with Bidi_Paired_Bracket_Type
|
||||
# property values Open and Close. The set is derived from the character
|
||||
# properties General_Category (gc), Bidi_Class (bc), Bidi_Mirrored (Bidi_M),
|
||||
# and Bidi_Mirroring_Glyph (bmg), as follows: two characters, A and B,
|
||||
# form a bracket pair if A has gc=Ps and B has gc=Pe, both have bc=ON and
|
||||
# Bidi_M=Y, and bmg of A is B. Bidi_Paired_Bracket (bpb) maps A to B and
|
||||
# vice versa, and their Bidi_Paired_Bracket_Type (bpt) property values are
|
||||
# Open (o) and Close (c), respectively.
|
||||
#
|
||||
# The brackets with ticks U+298D LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
|
||||
# through U+2990 RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER are paired the
|
||||
# same way their glyphs form mirror pairs, according to their bmg property
|
||||
# values. They are not paired on the basis of a diagonal or antidiagonal
|
||||
# matching of the corner ticks inferred from code point order.
|
||||
#
|
||||
# For legacy reasons, the characters U+FD3E ORNATE LEFT PARENTHESIS and
|
||||
# U+FD3F ORNATE RIGHT PARENTHESIS do not mirror in bidirectional display
|
||||
# and therefore do not form a bracket pair.
|
||||
#
|
||||
# The Unicode property value stability policy guarantees that characters
|
||||
# which have bpt=o or bpt=c also have bc=ON and Bidi_M=Y. As a result, an
|
||||
# implementation can optimize the lookup of the Bidi_Paired_Bracket_Type
|
||||
# property values Open and Close by restricting the processing to characters
|
||||
# with bc=ON.
|
||||
#
|
||||
# The format of the file is three fields separated by a semicolon.
|
||||
# Field 0: Unicode code point value, represented as a hexadecimal value
|
||||
# Field 1: Bidi_Paired_Bracket property value, a code point value or <none>
|
||||
# Field 2: Bidi_Paired_Bracket_Type property value, one of the following:
|
||||
# o Open
|
||||
# c Close
|
||||
# n None
|
||||
# The names of the characters in field 0 are given in comments at the end
|
||||
# of each line.
|
||||
#
|
||||
# For information on bidirectional paired brackets, see UAX #9: Unicode
|
||||
# Bidirectional Algorithm, at http://www.unicode.org/unicode/reports/tr9/
|
||||
#
|
||||
# This file was originally created by Andrew Glass and Laurentiu Iancu
|
||||
# for Unicode 6.3.
|
||||
|
||||
0028; 0029; o # LEFT PARENTHESIS
|
||||
0029; 0028; c # RIGHT PARENTHESIS
|
||||
005B; 005D; o # LEFT SQUARE BRACKET
|
||||
005D; 005B; c # RIGHT SQUARE BRACKET
|
||||
007B; 007D; o # LEFT CURLY BRACKET
|
||||
007D; 007B; c # RIGHT CURLY BRACKET
|
||||
0F3A; 0F3B; o # TIBETAN MARK GUG RTAGS GYON
|
||||
0F3B; 0F3A; c # TIBETAN MARK GUG RTAGS GYAS
|
||||
0F3C; 0F3D; o # TIBETAN MARK ANG KHANG GYON
|
||||
0F3D; 0F3C; c # TIBETAN MARK ANG KHANG GYAS
|
||||
169B; 169C; o # OGHAM FEATHER MARK
|
||||
169C; 169B; c # OGHAM REVERSED FEATHER MARK
|
||||
2045; 2046; o # LEFT SQUARE BRACKET WITH QUILL
|
||||
2046; 2045; c # RIGHT SQUARE BRACKET WITH QUILL
|
||||
207D; 207E; o # SUPERSCRIPT LEFT PARENTHESIS
|
||||
207E; 207D; c # SUPERSCRIPT RIGHT PARENTHESIS
|
||||
208D; 208E; o # SUBSCRIPT LEFT PARENTHESIS
|
||||
208E; 208D; c # SUBSCRIPT RIGHT PARENTHESIS
|
||||
2308; 2309; o # LEFT CEILING
|
||||
2309; 2308; c # RIGHT CEILING
|
||||
230A; 230B; o # LEFT FLOOR
|
||||
230B; 230A; c # RIGHT FLOOR
|
||||
2329; 232A; o # LEFT-POINTING ANGLE BRACKET
|
||||
232A; 2329; c # RIGHT-POINTING ANGLE BRACKET
|
||||
2768; 2769; o # MEDIUM LEFT PARENTHESIS ORNAMENT
|
||||
2769; 2768; c # MEDIUM RIGHT PARENTHESIS ORNAMENT
|
||||
276A; 276B; o # MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
|
||||
276B; 276A; c # MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
|
||||
276C; 276D; o # MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
|
||||
276D; 276C; c # MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
|
||||
276E; 276F; o # HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
|
||||
276F; 276E; c # HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
|
||||
2770; 2771; o # HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
|
||||
2771; 2770; c # HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
|
||||
2772; 2773; o # LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
|
||||
2773; 2772; c # LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
|
||||
2774; 2775; o # MEDIUM LEFT CURLY BRACKET ORNAMENT
|
||||
2775; 2774; c # MEDIUM RIGHT CURLY BRACKET ORNAMENT
|
||||
27C5; 27C6; o # LEFT S-SHAPED BAG DELIMITER
|
||||
27C6; 27C5; c # RIGHT S-SHAPED BAG DELIMITER
|
||||
27E6; 27E7; o # MATHEMATICAL LEFT WHITE SQUARE BRACKET
|
||||
27E7; 27E6; c # MATHEMATICAL RIGHT WHITE SQUARE BRACKET
|
||||
27E8; 27E9; o # MATHEMATICAL LEFT ANGLE BRACKET
|
||||
27E9; 27E8; c # MATHEMATICAL RIGHT ANGLE BRACKET
|
||||
27EA; 27EB; o # MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
|
||||
27EB; 27EA; c # MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
|
||||
27EC; 27ED; o # MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
|
||||
27ED; 27EC; c # MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
|
||||
27EE; 27EF; o # MATHEMATICAL LEFT FLATTENED PARENTHESIS
|
||||
27EF; 27EE; c # MATHEMATICAL RIGHT FLATTENED PARENTHESIS
|
||||
2983; 2984; o # LEFT WHITE CURLY BRACKET
|
||||
2984; 2983; c # RIGHT WHITE CURLY BRACKET
|
||||
2985; 2986; o # LEFT WHITE PARENTHESIS
|
||||
2986; 2985; c # RIGHT WHITE PARENTHESIS
|
||||
2987; 2988; o # Z NOTATION LEFT IMAGE BRACKET
|
||||
2988; 2987; c # Z NOTATION RIGHT IMAGE BRACKET
|
||||
2989; 298A; o # Z NOTATION LEFT BINDING BRACKET
|
||||
298A; 2989; c # Z NOTATION RIGHT BINDING BRACKET
|
||||
298B; 298C; o # LEFT SQUARE BRACKET WITH UNDERBAR
|
||||
298C; 298B; c # RIGHT SQUARE BRACKET WITH UNDERBAR
|
||||
298D; 2990; o # LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
|
||||
298E; 298F; c # RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
|
||||
298F; 298E; o # LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
|
||||
2990; 298D; c # RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
|
||||
2991; 2992; o # LEFT ANGLE BRACKET WITH DOT
|
||||
2992; 2991; c # RIGHT ANGLE BRACKET WITH DOT
|
||||
2993; 2994; o # LEFT ARC LESS-THAN BRACKET
|
||||
2994; 2993; c # RIGHT ARC GREATER-THAN BRACKET
|
||||
2995; 2996; o # DOUBLE LEFT ARC GREATER-THAN BRACKET
|
||||
2996; 2995; c # DOUBLE RIGHT ARC LESS-THAN BRACKET
|
||||
2997; 2998; o # LEFT BLACK TORTOISE SHELL BRACKET
|
||||
2998; 2997; c # RIGHT BLACK TORTOISE SHELL BRACKET
|
||||
29D8; 29D9; o # LEFT WIGGLY FENCE
|
||||
29D9; 29D8; c # RIGHT WIGGLY FENCE
|
||||
29DA; 29DB; o # LEFT DOUBLE WIGGLY FENCE
|
||||
29DB; 29DA; c # RIGHT DOUBLE WIGGLY FENCE
|
||||
29FC; 29FD; o # LEFT-POINTING CURVED ANGLE BRACKET
|
||||
29FD; 29FC; c # RIGHT-POINTING CURVED ANGLE BRACKET
|
||||
2E22; 2E23; o # TOP LEFT HALF BRACKET
|
||||
2E23; 2E22; c # TOP RIGHT HALF BRACKET
|
||||
2E24; 2E25; o # BOTTOM LEFT HALF BRACKET
|
||||
2E25; 2E24; c # BOTTOM RIGHT HALF BRACKET
|
||||
2E26; 2E27; o # LEFT SIDEWAYS U BRACKET
|
||||
2E27; 2E26; c # RIGHT SIDEWAYS U BRACKET
|
||||
2E28; 2E29; o # LEFT DOUBLE PARENTHESIS
|
||||
2E29; 2E28; c # RIGHT DOUBLE PARENTHESIS
|
||||
3008; 3009; o # LEFT ANGLE BRACKET
|
||||
3009; 3008; c # RIGHT ANGLE BRACKET
|
||||
300A; 300B; o # LEFT DOUBLE ANGLE BRACKET
|
||||
300B; 300A; c # RIGHT DOUBLE ANGLE BRACKET
|
||||
300C; 300D; o # LEFT CORNER BRACKET
|
||||
300D; 300C; c # RIGHT CORNER BRACKET
|
||||
300E; 300F; o # LEFT WHITE CORNER BRACKET
|
||||
300F; 300E; c # RIGHT WHITE CORNER BRACKET
|
||||
3010; 3011; o # LEFT BLACK LENTICULAR BRACKET
|
||||
3011; 3010; c # RIGHT BLACK LENTICULAR BRACKET
|
||||
3014; 3015; o # LEFT TORTOISE SHELL BRACKET
|
||||
3015; 3014; c # RIGHT TORTOISE SHELL BRACKET
|
||||
3016; 3017; o # LEFT WHITE LENTICULAR BRACKET
|
||||
3017; 3016; c # RIGHT WHITE LENTICULAR BRACKET
|
||||
3018; 3019; o # LEFT WHITE TORTOISE SHELL BRACKET
|
||||
3019; 3018; c # RIGHT WHITE TORTOISE SHELL BRACKET
|
||||
301A; 301B; o # LEFT WHITE SQUARE BRACKET
|
||||
301B; 301A; c # RIGHT WHITE SQUARE BRACKET
|
||||
FE59; FE5A; o # SMALL LEFT PARENTHESIS
|
||||
FE5A; FE59; c # SMALL RIGHT PARENTHESIS
|
||||
FE5B; FE5C; o # SMALL LEFT CURLY BRACKET
|
||||
FE5C; FE5B; c # SMALL RIGHT CURLY BRACKET
|
||||
FE5D; FE5E; o # SMALL LEFT TORTOISE SHELL BRACKET
|
||||
FE5E; FE5D; c # SMALL RIGHT TORTOISE SHELL BRACKET
|
||||
FF08; FF09; o # FULLWIDTH LEFT PARENTHESIS
|
||||
FF09; FF08; c # FULLWIDTH RIGHT PARENTHESIS
|
||||
FF3B; FF3D; o # FULLWIDTH LEFT SQUARE BRACKET
|
||||
FF3D; FF3B; c # FULLWIDTH RIGHT SQUARE BRACKET
|
||||
FF5B; FF5D; o # FULLWIDTH LEFT CURLY BRACKET
|
||||
FF5D; FF5B; c # FULLWIDTH RIGHT CURLY BRACKET
|
||||
FF5F; FF60; o # FULLWIDTH LEFT WHITE PARENTHESIS
|
||||
FF60; FF5F; c # FULLWIDTH RIGHT WHITE PARENTHESIS
|
||||
FF62; FF63; o # HALFWIDTH LEFT CORNER BRACKET
|
||||
FF63; FF62; c # HALFWIDTH RIGHT CORNER BRACKET
|
||||
|
||||
# EOF
|
2
bgrabitmap/dev/parseunicode/BidiCharacterTest.result
Normal file
2
bgrabitmap/dev/parseunicode/BidiCharacterTest.result
Normal file
@@ -0,0 +1,2 @@
|
||||
0 fail
|
||||
91699 success
|
96437
bgrabitmap/dev/parseunicode/BidiCharacterTest.txt
Normal file
96437
bgrabitmap/dev/parseunicode/BidiCharacterTest.txt
Normal file
File diff suppressed because it is too large
Load Diff
625
bgrabitmap/dev/parseunicode/BidiMirroring.txt
Normal file
625
bgrabitmap/dev/parseunicode/BidiMirroring.txt
Normal file
@@ -0,0 +1,625 @@
|
||||
# BidiMirroring-13.0.0.txt
|
||||
# Date: 2019-09-09, 19:34:00 GMT [KW, LI, RP]
|
||||
# © 2019 Unicode®, Inc.
|
||||
# For terms of use, see http://www.unicode.org/terms_of_use.html
|
||||
#
|
||||
# Unicode Character Database
|
||||
# For documentation, see http://www.unicode.org/reports/tr44/
|
||||
#
|
||||
# Bidi_Mirroring_Glyph Property
|
||||
#
|
||||
# This file is an informative contributory data file in the
|
||||
# Unicode Character Database.
|
||||
#
|
||||
# This data file lists characters that have the Bidi_Mirrored=Yes property
|
||||
# value, for which there is another Unicode character that typically has a glyph
|
||||
# that is the mirror image of the original character's glyph.
|
||||
#
|
||||
# The repertoire covered by the file is Unicode 13.0.0.
|
||||
#
|
||||
# The file contains a list of lines with mappings from one code point
|
||||
# to another one for character-based mirroring.
|
||||
# Note that for "real" mirroring, a rendering engine needs to select
|
||||
# appropriate alternative glyphs, and that many Unicode characters do not
|
||||
# have a mirror-image Unicode character.
|
||||
#
|
||||
# Each mapping line contains two fields, separated by a semicolon (';').
|
||||
# Each of the two fields contains a code point represented as a
|
||||
# variable-length hexadecimal value with 4 to 6 digits.
|
||||
# A comment indicates where the characters are "BEST FIT" mirroring.
|
||||
#
|
||||
# Code points for which Bidi_Mirrored=Yes, but for which no appropriate
|
||||
# characters exist with mirrored glyphs, are
|
||||
# listed as comments at the end of the file.
|
||||
#
|
||||
# Formally, the default value of the Bidi_Mirroring_Glyph property
|
||||
# for each code point is <none>, unless a mapping to
|
||||
# some other character is specified in this data file. When a code
|
||||
# point has the default value for the Bidi_Mirroring_Glyph property,
|
||||
# that means that no other character exists whose glyph is suitable
|
||||
# for character-based mirroring.
|
||||
#
|
||||
# For information on bidi mirroring, see UAX #9: Unicode Bidirectional Algorithm,
|
||||
# at http://www.unicode.org/unicode/reports/tr9/
|
||||
#
|
||||
# This file was originally created by Markus Scherer.
|
||||
# Extended for Unicode 3.2, 4.0, 4.1, 5.0, 5.1, 5.2, and 6.0 by Ken Whistler,
|
||||
# and for subsequent versions by Ken Whistler, Laurentiu Iancu, and Roozbeh Pournader.
|
||||
#
|
||||
# Historical and Compatibility Information:
|
||||
#
|
||||
# The OpenType Mirroring Pairs List (OMPL) is frozen to match the
|
||||
# Unicode 5.1 version of the Bidi_Mirroring_Glyph property (2008).
|
||||
# See https://www.microsoft.com/typography/otspec/ompl.txt
|
||||
#
|
||||
# The Unicode 6.1 version of the Bidi_Mirroring_Glyph property (2011)
|
||||
# added one mirroring pair: 27CB <--> 27CD.
|
||||
#
|
||||
# The Unicode 11.0 version of the Bidi_Mirroring_Glyph property (2018)
|
||||
# underwent a substantial revision, to formally recognize all of the
|
||||
# exact mirroring pairs and "BEST FIT" mirroring pairs that had been
|
||||
# added after the freezing of the OMPL list. As a result, starting
|
||||
# with Unicode 11.0, the bmg mapping values more accurately reflect
|
||||
# the current status of glyphs for Bidi_Mirrored characters in
|
||||
# the Unicode Standard, but this listing now extends significantly
|
||||
# beyond the frozen OMPL list. Implementers should be aware of this
|
||||
# intentional distinction.
|
||||
#
|
||||
# ############################################################
|
||||
#
|
||||
# Property: Bidi_Mirroring_Glyph
|
||||
#
|
||||
# @missing: 0000..10FFFF; <none>
|
||||
|
||||
0028; 0029 # LEFT PARENTHESIS
|
||||
0029; 0028 # RIGHT PARENTHESIS
|
||||
003C; 003E # LESS-THAN SIGN
|
||||
003E; 003C # GREATER-THAN SIGN
|
||||
005B; 005D # LEFT SQUARE BRACKET
|
||||
005D; 005B # RIGHT SQUARE BRACKET
|
||||
007B; 007D # LEFT CURLY BRACKET
|
||||
007D; 007B # RIGHT CURLY BRACKET
|
||||
00AB; 00BB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
00BB; 00AB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
0F3A; 0F3B # TIBETAN MARK GUG RTAGS GYON
|
||||
0F3B; 0F3A # TIBETAN MARK GUG RTAGS GYAS
|
||||
0F3C; 0F3D # TIBETAN MARK ANG KHANG GYON
|
||||
0F3D; 0F3C # TIBETAN MARK ANG KHANG GYAS
|
||||
169B; 169C # OGHAM FEATHER MARK
|
||||
169C; 169B # OGHAM REVERSED FEATHER MARK
|
||||
2039; 203A # SINGLE LEFT-POINTING ANGLE QUOTATION MARK
|
||||
203A; 2039 # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
|
||||
2045; 2046 # LEFT SQUARE BRACKET WITH QUILL
|
||||
2046; 2045 # RIGHT SQUARE BRACKET WITH QUILL
|
||||
207D; 207E # SUPERSCRIPT LEFT PARENTHESIS
|
||||
207E; 207D # SUPERSCRIPT RIGHT PARENTHESIS
|
||||
208D; 208E # SUBSCRIPT LEFT PARENTHESIS
|
||||
208E; 208D # SUBSCRIPT RIGHT PARENTHESIS
|
||||
2208; 220B # ELEMENT OF
|
||||
2209; 220C # NOT AN ELEMENT OF
|
||||
220A; 220D # SMALL ELEMENT OF
|
||||
220B; 2208 # CONTAINS AS MEMBER
|
||||
220C; 2209 # DOES NOT CONTAIN AS MEMBER
|
||||
220D; 220A # SMALL CONTAINS AS MEMBER
|
||||
2215; 29F5 # DIVISION SLASH
|
||||
221F; 2BFE # RIGHT ANGLE
|
||||
2220; 29A3 # ANGLE
|
||||
2221; 299B # MEASURED ANGLE
|
||||
2222; 29A0 # SPHERICAL ANGLE
|
||||
2224; 2AEE # DOES NOT DIVIDE
|
||||
223C; 223D # TILDE OPERATOR
|
||||
223D; 223C # REVERSED TILDE
|
||||
2243; 22CD # ASYMPTOTICALLY EQUAL TO
|
||||
2245; 224C # APPROXIMATELY EQUAL TO
|
||||
224C; 2245 # ALL EQUAL TO
|
||||
2252; 2253 # APPROXIMATELY EQUAL TO OR THE IMAGE OF
|
||||
2253; 2252 # IMAGE OF OR APPROXIMATELY EQUAL TO
|
||||
2254; 2255 # COLON EQUALS
|
||||
2255; 2254 # EQUALS COLON
|
||||
2264; 2265 # LESS-THAN OR EQUAL TO
|
||||
2265; 2264 # GREATER-THAN OR EQUAL TO
|
||||
2266; 2267 # LESS-THAN OVER EQUAL TO
|
||||
2267; 2266 # GREATER-THAN OVER EQUAL TO
|
||||
2268; 2269 # [BEST FIT] LESS-THAN BUT NOT EQUAL TO
|
||||
2269; 2268 # [BEST FIT] GREATER-THAN BUT NOT EQUAL TO
|
||||
226A; 226B # MUCH LESS-THAN
|
||||
226B; 226A # MUCH GREATER-THAN
|
||||
226E; 226F # [BEST FIT] NOT LESS-THAN
|
||||
226F; 226E # [BEST FIT] NOT GREATER-THAN
|
||||
2270; 2271 # [BEST FIT] NEITHER LESS-THAN NOR EQUAL TO
|
||||
2271; 2270 # [BEST FIT] NEITHER GREATER-THAN NOR EQUAL TO
|
||||
2272; 2273 # [BEST FIT] LESS-THAN OR EQUIVALENT TO
|
||||
2273; 2272 # [BEST FIT] GREATER-THAN OR EQUIVALENT TO
|
||||
2274; 2275 # [BEST FIT] NEITHER LESS-THAN NOR EQUIVALENT TO
|
||||
2275; 2274 # [BEST FIT] NEITHER GREATER-THAN NOR EQUIVALENT TO
|
||||
2276; 2277 # LESS-THAN OR GREATER-THAN
|
||||
2277; 2276 # GREATER-THAN OR LESS-THAN
|
||||
2278; 2279 # [BEST FIT] NEITHER LESS-THAN NOR GREATER-THAN
|
||||
2279; 2278 # [BEST FIT] NEITHER GREATER-THAN NOR LESS-THAN
|
||||
227A; 227B # PRECEDES
|
||||
227B; 227A # SUCCEEDS
|
||||
227C; 227D # PRECEDES OR EQUAL TO
|
||||
227D; 227C # SUCCEEDS OR EQUAL TO
|
||||
227E; 227F # [BEST FIT] PRECEDES OR EQUIVALENT TO
|
||||
227F; 227E # [BEST FIT] SUCCEEDS OR EQUIVALENT TO
|
||||
2280; 2281 # [BEST FIT] DOES NOT PRECEDE
|
||||
2281; 2280 # [BEST FIT] DOES NOT SUCCEED
|
||||
2282; 2283 # SUBSET OF
|
||||
2283; 2282 # SUPERSET OF
|
||||
2284; 2285 # [BEST FIT] NOT A SUBSET OF
|
||||
2285; 2284 # [BEST FIT] NOT A SUPERSET OF
|
||||
2286; 2287 # SUBSET OF OR EQUAL TO
|
||||
2287; 2286 # SUPERSET OF OR EQUAL TO
|
||||
2288; 2289 # [BEST FIT] NEITHER A SUBSET OF NOR EQUAL TO
|
||||
2289; 2288 # [BEST FIT] NEITHER A SUPERSET OF NOR EQUAL TO
|
||||
228A; 228B # [BEST FIT] SUBSET OF WITH NOT EQUAL TO
|
||||
228B; 228A # [BEST FIT] SUPERSET OF WITH NOT EQUAL TO
|
||||
228F; 2290 # SQUARE IMAGE OF
|
||||
2290; 228F # SQUARE ORIGINAL OF
|
||||
2291; 2292 # SQUARE IMAGE OF OR EQUAL TO
|
||||
2292; 2291 # SQUARE ORIGINAL OF OR EQUAL TO
|
||||
2298; 29B8 # CIRCLED DIVISION SLASH
|
||||
22A2; 22A3 # RIGHT TACK
|
||||
22A3; 22A2 # LEFT TACK
|
||||
22A6; 2ADE # ASSERTION
|
||||
22A8; 2AE4 # TRUE
|
||||
22A9; 2AE3 # FORCES
|
||||
22AB; 2AE5 # DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
|
||||
22B0; 22B1 # PRECEDES UNDER RELATION
|
||||
22B1; 22B0 # SUCCEEDS UNDER RELATION
|
||||
22B2; 22B3 # NORMAL SUBGROUP OF
|
||||
22B3; 22B2 # CONTAINS AS NORMAL SUBGROUP
|
||||
22B4; 22B5 # NORMAL SUBGROUP OF OR EQUAL TO
|
||||
22B5; 22B4 # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO
|
||||
22B6; 22B7 # ORIGINAL OF
|
||||
22B7; 22B6 # IMAGE OF
|
||||
22B8; 27DC # MULTIMAP
|
||||
22C9; 22CA # LEFT NORMAL FACTOR SEMIDIRECT PRODUCT
|
||||
22CA; 22C9 # RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT
|
||||
22CB; 22CC # LEFT SEMIDIRECT PRODUCT
|
||||
22CC; 22CB # RIGHT SEMIDIRECT PRODUCT
|
||||
22CD; 2243 # REVERSED TILDE EQUALS
|
||||
22D0; 22D1 # DOUBLE SUBSET
|
||||
22D1; 22D0 # DOUBLE SUPERSET
|
||||
22D6; 22D7 # LESS-THAN WITH DOT
|
||||
22D7; 22D6 # GREATER-THAN WITH DOT
|
||||
22D8; 22D9 # VERY MUCH LESS-THAN
|
||||
22D9; 22D8 # VERY MUCH GREATER-THAN
|
||||
22DA; 22DB # LESS-THAN EQUAL TO OR GREATER-THAN
|
||||
22DB; 22DA # GREATER-THAN EQUAL TO OR LESS-THAN
|
||||
22DC; 22DD # EQUAL TO OR LESS-THAN
|
||||
22DD; 22DC # EQUAL TO OR GREATER-THAN
|
||||
22DE; 22DF # EQUAL TO OR PRECEDES
|
||||
22DF; 22DE # EQUAL TO OR SUCCEEDS
|
||||
22E0; 22E1 # [BEST FIT] DOES NOT PRECEDE OR EQUAL
|
||||
22E1; 22E0 # [BEST FIT] DOES NOT SUCCEED OR EQUAL
|
||||
22E2; 22E3 # [BEST FIT] NOT SQUARE IMAGE OF OR EQUAL TO
|
||||
22E3; 22E2 # [BEST FIT] NOT SQUARE ORIGINAL OF OR EQUAL TO
|
||||
22E4; 22E5 # [BEST FIT] SQUARE IMAGE OF OR NOT EQUAL TO
|
||||
22E5; 22E4 # [BEST FIT] SQUARE ORIGINAL OF OR NOT EQUAL TO
|
||||
22E6; 22E7 # [BEST FIT] LESS-THAN BUT NOT EQUIVALENT TO
|
||||
22E7; 22E6 # [BEST FIT] GREATER-THAN BUT NOT EQUIVALENT TO
|
||||
22E8; 22E9 # [BEST FIT] PRECEDES BUT NOT EQUIVALENT TO
|
||||
22E9; 22E8 # [BEST FIT] SUCCEEDS BUT NOT EQUIVALENT TO
|
||||
22EA; 22EB # [BEST FIT] NOT NORMAL SUBGROUP OF
|
||||
22EB; 22EA # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP
|
||||
22EC; 22ED # [BEST FIT] NOT NORMAL SUBGROUP OF OR EQUAL TO
|
||||
22ED; 22EC # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL
|
||||
22F0; 22F1 # UP RIGHT DIAGONAL ELLIPSIS
|
||||
22F1; 22F0 # DOWN RIGHT DIAGONAL ELLIPSIS
|
||||
22F2; 22FA # ELEMENT OF WITH LONG HORIZONTAL STROKE
|
||||
22F3; 22FB # ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
|
||||
22F4; 22FC # SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
|
||||
22F6; 22FD # ELEMENT OF WITH OVERBAR
|
||||
22F7; 22FE # SMALL ELEMENT OF WITH OVERBAR
|
||||
22FA; 22F2 # CONTAINS WITH LONG HORIZONTAL STROKE
|
||||
22FB; 22F3 # CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
|
||||
22FC; 22F4 # SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
|
||||
22FD; 22F6 # CONTAINS WITH OVERBAR
|
||||
22FE; 22F7 # SMALL CONTAINS WITH OVERBAR
|
||||
2308; 2309 # LEFT CEILING
|
||||
2309; 2308 # RIGHT CEILING
|
||||
230A; 230B # LEFT FLOOR
|
||||
230B; 230A # RIGHT FLOOR
|
||||
2329; 232A # LEFT-POINTING ANGLE BRACKET
|
||||
232A; 2329 # RIGHT-POINTING ANGLE BRACKET
|
||||
2768; 2769 # MEDIUM LEFT PARENTHESIS ORNAMENT
|
||||
2769; 2768 # MEDIUM RIGHT PARENTHESIS ORNAMENT
|
||||
276A; 276B # MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
|
||||
276B; 276A # MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
|
||||
276C; 276D # MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
|
||||
276D; 276C # MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
|
||||
276E; 276F # HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
|
||||
276F; 276E # HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
|
||||
2770; 2771 # HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
|
||||
2771; 2770 # HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
|
||||
2772; 2773 # LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
|
||||
2773; 2772 # LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
|
||||
2774; 2775 # MEDIUM LEFT CURLY BRACKET ORNAMENT
|
||||
2775; 2774 # MEDIUM RIGHT CURLY BRACKET ORNAMENT
|
||||
27C3; 27C4 # OPEN SUBSET
|
||||
27C4; 27C3 # OPEN SUPERSET
|
||||
27C5; 27C6 # LEFT S-SHAPED BAG DELIMITER
|
||||
27C6; 27C5 # RIGHT S-SHAPED BAG DELIMITER
|
||||
27C8; 27C9 # REVERSE SOLIDUS PRECEDING SUBSET
|
||||
27C9; 27C8 # SUPERSET PRECEDING SOLIDUS
|
||||
27CB; 27CD # MATHEMATICAL RISING DIAGONAL
|
||||
27CD; 27CB # MATHEMATICAL FALLING DIAGONAL
|
||||
27D5; 27D6 # LEFT OUTER JOIN
|
||||
27D6; 27D5 # RIGHT OUTER JOIN
|
||||
27DC; 22B8 # LEFT MULTIMAP
|
||||
27DD; 27DE # LONG RIGHT TACK
|
||||
27DE; 27DD # LONG LEFT TACK
|
||||
27E2; 27E3 # WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK
|
||||
27E3; 27E2 # WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK
|
||||
27E4; 27E5 # WHITE SQUARE WITH LEFTWARDS TICK
|
||||
27E5; 27E4 # WHITE SQUARE WITH RIGHTWARDS TICK
|
||||
27E6; 27E7 # MATHEMATICAL LEFT WHITE SQUARE BRACKET
|
||||
27E7; 27E6 # MATHEMATICAL RIGHT WHITE SQUARE BRACKET
|
||||
27E8; 27E9 # MATHEMATICAL LEFT ANGLE BRACKET
|
||||
27E9; 27E8 # MATHEMATICAL RIGHT ANGLE BRACKET
|
||||
27EA; 27EB # MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
|
||||
27EB; 27EA # MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
|
||||
27EC; 27ED # MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
|
||||
27ED; 27EC # MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
|
||||
27EE; 27EF # MATHEMATICAL LEFT FLATTENED PARENTHESIS
|
||||
27EF; 27EE # MATHEMATICAL RIGHT FLATTENED PARENTHESIS
|
||||
2983; 2984 # LEFT WHITE CURLY BRACKET
|
||||
2984; 2983 # RIGHT WHITE CURLY BRACKET
|
||||
2985; 2986 # LEFT WHITE PARENTHESIS
|
||||
2986; 2985 # RIGHT WHITE PARENTHESIS
|
||||
2987; 2988 # Z NOTATION LEFT IMAGE BRACKET
|
||||
2988; 2987 # Z NOTATION RIGHT IMAGE BRACKET
|
||||
2989; 298A # Z NOTATION LEFT BINDING BRACKET
|
||||
298A; 2989 # Z NOTATION RIGHT BINDING BRACKET
|
||||
298B; 298C # LEFT SQUARE BRACKET WITH UNDERBAR
|
||||
298C; 298B # RIGHT SQUARE BRACKET WITH UNDERBAR
|
||||
298D; 2990 # LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
|
||||
298E; 298F # RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
|
||||
298F; 298E # LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
|
||||
2990; 298D # RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
|
||||
2991; 2992 # LEFT ANGLE BRACKET WITH DOT
|
||||
2992; 2991 # RIGHT ANGLE BRACKET WITH DOT
|
||||
2993; 2994 # LEFT ARC LESS-THAN BRACKET
|
||||
2994; 2993 # RIGHT ARC GREATER-THAN BRACKET
|
||||
2995; 2996 # DOUBLE LEFT ARC GREATER-THAN BRACKET
|
||||
2996; 2995 # DOUBLE RIGHT ARC LESS-THAN BRACKET
|
||||
2997; 2998 # LEFT BLACK TORTOISE SHELL BRACKET
|
||||
2998; 2997 # RIGHT BLACK TORTOISE SHELL BRACKET
|
||||
299B; 2221 # MEASURED ANGLE OPENING LEFT
|
||||
29A0; 2222 # SPHERICAL ANGLE OPENING LEFT
|
||||
29A3; 2220 # REVERSED ANGLE
|
||||
29A4; 29A5 # ANGLE WITH UNDERBAR
|
||||
29A5; 29A4 # REVERSED ANGLE WITH UNDERBAR
|
||||
29A8; 29A9 # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT
|
||||
29A9; 29A8 # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT
|
||||
29AA; 29AB # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT
|
||||
29AB; 29AA # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT
|
||||
29AC; 29AD # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP
|
||||
29AD; 29AC # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP
|
||||
29AE; 29AF # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN
|
||||
29AF; 29AE # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN
|
||||
29B8; 2298 # CIRCLED REVERSE SOLIDUS
|
||||
29C0; 29C1 # CIRCLED LESS-THAN
|
||||
29C1; 29C0 # CIRCLED GREATER-THAN
|
||||
29C4; 29C5 # SQUARED RISING DIAGONAL SLASH
|
||||
29C5; 29C4 # SQUARED FALLING DIAGONAL SLASH
|
||||
29CF; 29D0 # LEFT TRIANGLE BESIDE VERTICAL BAR
|
||||
29D0; 29CF # VERTICAL BAR BESIDE RIGHT TRIANGLE
|
||||
29D1; 29D2 # BOWTIE WITH LEFT HALF BLACK
|
||||
29D2; 29D1 # BOWTIE WITH RIGHT HALF BLACK
|
||||
29D4; 29D5 # TIMES WITH LEFT HALF BLACK
|
||||
29D5; 29D4 # TIMES WITH RIGHT HALF BLACK
|
||||
29D8; 29D9 # LEFT WIGGLY FENCE
|
||||
29D9; 29D8 # RIGHT WIGGLY FENCE
|
||||
29DA; 29DB # LEFT DOUBLE WIGGLY FENCE
|
||||
29DB; 29DA # RIGHT DOUBLE WIGGLY FENCE
|
||||
29E8; 29E9 # DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK
|
||||
29E9; 29E8 # DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK
|
||||
29F5; 2215 # REVERSE SOLIDUS OPERATOR
|
||||
29F8; 29F9 # BIG SOLIDUS
|
||||
29F9; 29F8 # BIG REVERSE SOLIDUS
|
||||
29FC; 29FD # LEFT-POINTING CURVED ANGLE BRACKET
|
||||
29FD; 29FC # RIGHT-POINTING CURVED ANGLE BRACKET
|
||||
2A2B; 2A2C # MINUS SIGN WITH FALLING DOTS
|
||||
2A2C; 2A2B # MINUS SIGN WITH RISING DOTS
|
||||
2A2D; 2A2E # PLUS SIGN IN LEFT HALF CIRCLE
|
||||
2A2E; 2A2D # PLUS SIGN IN RIGHT HALF CIRCLE
|
||||
2A34; 2A35 # MULTIPLICATION SIGN IN LEFT HALF CIRCLE
|
||||
2A35; 2A34 # MULTIPLICATION SIGN IN RIGHT HALF CIRCLE
|
||||
2A3C; 2A3D # INTERIOR PRODUCT
|
||||
2A3D; 2A3C # RIGHTHAND INTERIOR PRODUCT
|
||||
2A64; 2A65 # Z NOTATION DOMAIN ANTIRESTRICTION
|
||||
2A65; 2A64 # Z NOTATION RANGE ANTIRESTRICTION
|
||||
2A79; 2A7A # LESS-THAN WITH CIRCLE INSIDE
|
||||
2A7A; 2A79 # GREATER-THAN WITH CIRCLE INSIDE
|
||||
2A7B; 2A7C # [BEST FIT] LESS-THAN WITH QUESTION MARK ABOVE
|
||||
2A7C; 2A7B # [BEST FIT] GREATER-THAN WITH QUESTION MARK ABOVE
|
||||
2A7D; 2A7E # LESS-THAN OR SLANTED EQUAL TO
|
||||
2A7E; 2A7D # GREATER-THAN OR SLANTED EQUAL TO
|
||||
2A7F; 2A80 # LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
|
||||
2A80; 2A7F # GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
|
||||
2A81; 2A82 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
|
||||
2A82; 2A81 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
|
||||
2A83; 2A84 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT
|
||||
2A84; 2A83 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT
|
||||
2A85; 2A86 # [BEST FIT] LESS-THAN OR APPROXIMATE
|
||||
2A86; 2A85 # [BEST FIT] GREATER-THAN OR APPROXIMATE
|
||||
2A87; 2A88 # [BEST FIT] LESS-THAN AND SINGLE-LINE NOT EQUAL TO
|
||||
2A88; 2A87 # [BEST FIT] GREATER-THAN AND SINGLE-LINE NOT EQUAL TO
|
||||
2A89; 2A8A # [BEST FIT] LESS-THAN AND NOT APPROXIMATE
|
||||
2A8A; 2A89 # [BEST FIT] GREATER-THAN AND NOT APPROXIMATE
|
||||
2A8B; 2A8C # LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN
|
||||
2A8C; 2A8B # GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN
|
||||
2A8D; 2A8E # [BEST FIT] LESS-THAN ABOVE SIMILAR OR EQUAL
|
||||
2A8E; 2A8D # [BEST FIT] GREATER-THAN ABOVE SIMILAR OR EQUAL
|
||||
2A8F; 2A90 # [BEST FIT] LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN
|
||||
2A90; 2A8F # [BEST FIT] GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN
|
||||
2A91; 2A92 # LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL
|
||||
2A92; 2A91 # GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL
|
||||
2A93; 2A94 # LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL
|
||||
2A94; 2A93 # GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL
|
||||
2A95; 2A96 # SLANTED EQUAL TO OR LESS-THAN
|
||||
2A96; 2A95 # SLANTED EQUAL TO OR GREATER-THAN
|
||||
2A97; 2A98 # SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE
|
||||
2A98; 2A97 # SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE
|
||||
2A99; 2A9A # DOUBLE-LINE EQUAL TO OR LESS-THAN
|
||||
2A9A; 2A99 # DOUBLE-LINE EQUAL TO OR GREATER-THAN
|
||||
2A9B; 2A9C # DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN
|
||||
2A9C; 2A9B # DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN
|
||||
2A9D; 2A9E # [BEST FIT] SIMILAR OR LESS-THAN
|
||||
2A9E; 2A9D # [BEST FIT] SIMILAR OR GREATER-THAN
|
||||
2A9F; 2AA0 # [BEST FIT] SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN
|
||||
2AA0; 2A9F # [BEST FIT] SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN
|
||||
2AA1; 2AA2 # DOUBLE NESTED LESS-THAN
|
||||
2AA2; 2AA1 # DOUBLE NESTED GREATER-THAN
|
||||
2AA6; 2AA7 # LESS-THAN CLOSED BY CURVE
|
||||
2AA7; 2AA6 # GREATER-THAN CLOSED BY CURVE
|
||||
2AA8; 2AA9 # LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
|
||||
2AA9; 2AA8 # GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
|
||||
2AAA; 2AAB # SMALLER THAN
|
||||
2AAB; 2AAA # LARGER THAN
|
||||
2AAC; 2AAD # SMALLER THAN OR EQUAL TO
|
||||
2AAD; 2AAC # LARGER THAN OR EQUAL TO
|
||||
2AAF; 2AB0 # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN
|
||||
2AB0; 2AAF # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN
|
||||
2AB1; 2AB2 # [BEST FIT] PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO
|
||||
2AB2; 2AB1 # [BEST FIT] SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO
|
||||
2AB3; 2AB4 # PRECEDES ABOVE EQUALS SIGN
|
||||
2AB4; 2AB3 # SUCCEEDS ABOVE EQUALS SIGN
|
||||
2AB5; 2AB6 # [BEST FIT] PRECEDES ABOVE NOT EQUAL TO
|
||||
2AB6; 2AB5 # [BEST FIT] SUCCEEDS ABOVE NOT EQUAL TO
|
||||
2AB7; 2AB8 # [BEST FIT] PRECEDES ABOVE ALMOST EQUAL TO
|
||||
2AB8; 2AB7 # [BEST FIT] SUCCEEDS ABOVE ALMOST EQUAL TO
|
||||
2AB9; 2ABA # [BEST FIT] PRECEDES ABOVE NOT ALMOST EQUAL TO
|
||||
2ABA; 2AB9 # [BEST FIT] SUCCEEDS ABOVE NOT ALMOST EQUAL TO
|
||||
2ABB; 2ABC # DOUBLE PRECEDES
|
||||
2ABC; 2ABB # DOUBLE SUCCEEDS
|
||||
2ABD; 2ABE # SUBSET WITH DOT
|
||||
2ABE; 2ABD # SUPERSET WITH DOT
|
||||
2ABF; 2AC0 # SUBSET WITH PLUS SIGN BELOW
|
||||
2AC0; 2ABF # SUPERSET WITH PLUS SIGN BELOW
|
||||
2AC1; 2AC2 # SUBSET WITH MULTIPLICATION SIGN BELOW
|
||||
2AC2; 2AC1 # SUPERSET WITH MULTIPLICATION SIGN BELOW
|
||||
2AC3; 2AC4 # SUBSET OF OR EQUAL TO WITH DOT ABOVE
|
||||
2AC4; 2AC3 # SUPERSET OF OR EQUAL TO WITH DOT ABOVE
|
||||
2AC5; 2AC6 # SUBSET OF ABOVE EQUALS SIGN
|
||||
2AC6; 2AC5 # SUPERSET OF ABOVE EQUALS SIGN
|
||||
2AC7; 2AC8 # [BEST FIT] SUBSET OF ABOVE TILDE OPERATOR
|
||||
2AC8; 2AC7 # [BEST FIT] SUPERSET OF ABOVE TILDE OPERATOR
|
||||
2AC9; 2ACA # [BEST FIT] SUBSET OF ABOVE ALMOST EQUAL TO
|
||||
2ACA; 2AC9 # [BEST FIT] SUPERSET OF ABOVE ALMOST EQUAL TO
|
||||
2ACB; 2ACC # [BEST FIT] SUBSET OF ABOVE NOT EQUAL TO
|
||||
2ACC; 2ACB # [BEST FIT] SUPERSET OF ABOVE NOT EQUAL TO
|
||||
2ACD; 2ACE # SQUARE LEFT OPEN BOX OPERATOR
|
||||
2ACE; 2ACD # SQUARE RIGHT OPEN BOX OPERATOR
|
||||
2ACF; 2AD0 # CLOSED SUBSET
|
||||
2AD0; 2ACF # CLOSED SUPERSET
|
||||
2AD1; 2AD2 # CLOSED SUBSET OR EQUAL TO
|
||||
2AD2; 2AD1 # CLOSED SUPERSET OR EQUAL TO
|
||||
2AD3; 2AD4 # SUBSET ABOVE SUPERSET
|
||||
2AD4; 2AD3 # SUPERSET ABOVE SUBSET
|
||||
2AD5; 2AD6 # SUBSET ABOVE SUBSET
|
||||
2AD6; 2AD5 # SUPERSET ABOVE SUPERSET
|
||||
2ADE; 22A6 # SHORT LEFT TACK
|
||||
2AE3; 22A9 # DOUBLE VERTICAL BAR LEFT TURNSTILE
|
||||
2AE4; 22A8 # VERTICAL BAR DOUBLE LEFT TURNSTILE
|
||||
2AE5; 22AB # DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE
|
||||
2AEC; 2AED # DOUBLE STROKE NOT SIGN
|
||||
2AED; 2AEC # REVERSED DOUBLE STROKE NOT SIGN
|
||||
2AEE; 2224 # DOES NOT DIVIDE WITH REVERSED NEGATION SLASH
|
||||
2AF7; 2AF8 # TRIPLE NESTED LESS-THAN
|
||||
2AF8; 2AF7 # TRIPLE NESTED GREATER-THAN
|
||||
2AF9; 2AFA # DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO
|
||||
2AFA; 2AF9 # DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO
|
||||
2BFE; 221F # REVERSED RIGHT ANGLE
|
||||
2E02; 2E03 # LEFT SUBSTITUTION BRACKET
|
||||
2E03; 2E02 # RIGHT SUBSTITUTION BRACKET
|
||||
2E04; 2E05 # LEFT DOTTED SUBSTITUTION BRACKET
|
||||
2E05; 2E04 # RIGHT DOTTED SUBSTITUTION BRACKET
|
||||
2E09; 2E0A # LEFT TRANSPOSITION BRACKET
|
||||
2E0A; 2E09 # RIGHT TRANSPOSITION BRACKET
|
||||
2E0C; 2E0D # LEFT RAISED OMISSION BRACKET
|
||||
2E0D; 2E0C # RIGHT RAISED OMISSION BRACKET
|
||||
2E1C; 2E1D # LEFT LOW PARAPHRASE BRACKET
|
||||
2E1D; 2E1C # RIGHT LOW PARAPHRASE BRACKET
|
||||
2E20; 2E21 # LEFT VERTICAL BAR WITH QUILL
|
||||
2E21; 2E20 # RIGHT VERTICAL BAR WITH QUILL
|
||||
2E22; 2E23 # TOP LEFT HALF BRACKET
|
||||
2E23; 2E22 # TOP RIGHT HALF BRACKET
|
||||
2E24; 2E25 # BOTTOM LEFT HALF BRACKET
|
||||
2E25; 2E24 # BOTTOM RIGHT HALF BRACKET
|
||||
2E26; 2E27 # LEFT SIDEWAYS U BRACKET
|
||||
2E27; 2E26 # RIGHT SIDEWAYS U BRACKET
|
||||
2E28; 2E29 # LEFT DOUBLE PARENTHESIS
|
||||
2E29; 2E28 # RIGHT DOUBLE PARENTHESIS
|
||||
3008; 3009 # LEFT ANGLE BRACKET
|
||||
3009; 3008 # RIGHT ANGLE BRACKET
|
||||
300A; 300B # LEFT DOUBLE ANGLE BRACKET
|
||||
300B; 300A # RIGHT DOUBLE ANGLE BRACKET
|
||||
300C; 300D # [BEST FIT] LEFT CORNER BRACKET
|
||||
300D; 300C # [BEST FIT] RIGHT CORNER BRACKET
|
||||
300E; 300F # [BEST FIT] LEFT WHITE CORNER BRACKET
|
||||
300F; 300E # [BEST FIT] RIGHT WHITE CORNER BRACKET
|
||||
3010; 3011 # LEFT BLACK LENTICULAR BRACKET
|
||||
3011; 3010 # RIGHT BLACK LENTICULAR BRACKET
|
||||
3014; 3015 # LEFT TORTOISE SHELL BRACKET
|
||||
3015; 3014 # RIGHT TORTOISE SHELL BRACKET
|
||||
3016; 3017 # LEFT WHITE LENTICULAR BRACKET
|
||||
3017; 3016 # RIGHT WHITE LENTICULAR BRACKET
|
||||
3018; 3019 # LEFT WHITE TORTOISE SHELL BRACKET
|
||||
3019; 3018 # RIGHT WHITE TORTOISE SHELL BRACKET
|
||||
301A; 301B # LEFT WHITE SQUARE BRACKET
|
||||
301B; 301A # RIGHT WHITE SQUARE BRACKET
|
||||
FE59; FE5A # SMALL LEFT PARENTHESIS
|
||||
FE5A; FE59 # SMALL RIGHT PARENTHESIS
|
||||
FE5B; FE5C # SMALL LEFT CURLY BRACKET
|
||||
FE5C; FE5B # SMALL RIGHT CURLY BRACKET
|
||||
FE5D; FE5E # SMALL LEFT TORTOISE SHELL BRACKET
|
||||
FE5E; FE5D # SMALL RIGHT TORTOISE SHELL BRACKET
|
||||
FE64; FE65 # SMALL LESS-THAN SIGN
|
||||
FE65; FE64 # SMALL GREATER-THAN SIGN
|
||||
FF08; FF09 # FULLWIDTH LEFT PARENTHESIS
|
||||
FF09; FF08 # FULLWIDTH RIGHT PARENTHESIS
|
||||
FF1C; FF1E # FULLWIDTH LESS-THAN SIGN
|
||||
FF1E; FF1C # FULLWIDTH GREATER-THAN SIGN
|
||||
FF3B; FF3D # FULLWIDTH LEFT SQUARE BRACKET
|
||||
FF3D; FF3B # FULLWIDTH RIGHT SQUARE BRACKET
|
||||
FF5B; FF5D # FULLWIDTH LEFT CURLY BRACKET
|
||||
FF5D; FF5B # FULLWIDTH RIGHT CURLY BRACKET
|
||||
FF5F; FF60 # FULLWIDTH LEFT WHITE PARENTHESIS
|
||||
FF60; FF5F # FULLWIDTH RIGHT WHITE PARENTHESIS
|
||||
FF62; FF63 # [BEST FIT] HALFWIDTH LEFT CORNER BRACKET
|
||||
FF63; FF62 # [BEST FIT] HALFWIDTH RIGHT CORNER BRACKET
|
||||
|
||||
# The following characters have no appropriate mirroring character.
|
||||
# For these characters it is up to the rendering system
|
||||
# to provide mirrored glyphs.
|
||||
|
||||
# 2140; DOUBLE-STRUCK N-ARY SUMMATION
|
||||
# 2201; COMPLEMENT
|
||||
# 2202; PARTIAL DIFFERENTIAL
|
||||
# 2203; THERE EXISTS
|
||||
# 2204; THERE DOES NOT EXIST
|
||||
# 2211; N-ARY SUMMATION
|
||||
# 2216; SET MINUS
|
||||
# 221A; SQUARE ROOT
|
||||
# 221B; CUBE ROOT
|
||||
# 221C; FOURTH ROOT
|
||||
# 221D; PROPORTIONAL TO
|
||||
# 2226; NOT PARALLEL TO
|
||||
# 222B; INTEGRAL
|
||||
# 222C; DOUBLE INTEGRAL
|
||||
# 222D; TRIPLE INTEGRAL
|
||||
# 222E; CONTOUR INTEGRAL
|
||||
# 222F; SURFACE INTEGRAL
|
||||
# 2230; VOLUME INTEGRAL
|
||||
# 2231; CLOCKWISE INTEGRAL
|
||||
# 2232; CLOCKWISE CONTOUR INTEGRAL
|
||||
# 2233; ANTICLOCKWISE CONTOUR INTEGRAL
|
||||
# 2239; EXCESS
|
||||
# 223B; HOMOTHETIC
|
||||
# 223E; INVERTED LAZY S
|
||||
# 223F; SINE WAVE
|
||||
# 2240; WREATH PRODUCT
|
||||
# 2241; NOT TILDE
|
||||
# 2242; MINUS TILDE
|
||||
# 2244; NOT ASYMPTOTICALLY EQUAL TO
|
||||
# 2246; APPROXIMATELY BUT NOT ACTUALLY EQUAL TO
|
||||
# 2247; NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
|
||||
# 2248; ALMOST EQUAL TO
|
||||
# 2249; NOT ALMOST EQUAL TO
|
||||
# 224A; ALMOST EQUAL OR EQUAL TO
|
||||
# 224B; TRIPLE TILDE
|
||||
# 225F; QUESTIONED EQUAL TO
|
||||
# 2260; NOT EQUAL TO
|
||||
# 2262; NOT IDENTICAL TO
|
||||
# 228C; MULTISET
|
||||
# 22A7; MODELS
|
||||
# 22AA; TRIPLE VERTICAL BAR RIGHT TURNSTILE
|
||||
# 22AC; DOES NOT PROVE
|
||||
# 22AD; NOT TRUE
|
||||
# 22AE; DOES NOT FORCE
|
||||
# 22AF; NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
|
||||
# 22BE; RIGHT ANGLE WITH ARC
|
||||
# 22BF; RIGHT TRIANGLE
|
||||
# 22F5; ELEMENT OF WITH DOT ABOVE
|
||||
# 22F8; ELEMENT OF WITH UNDERBAR
|
||||
# 22F9; ELEMENT OF WITH TWO HORIZONTAL STROKES
|
||||
# 22FF; Z NOTATION BAG MEMBERSHIP
|
||||
# 2320; TOP HALF INTEGRAL
|
||||
# 2321; BOTTOM HALF INTEGRAL
|
||||
# 27C0; THREE DIMENSIONAL ANGLE
|
||||
# 27CC; LONG DIVISION
|
||||
# 27D3; LOWER RIGHT CORNER WITH DOT
|
||||
# 27D4; UPPER LEFT CORNER WITH DOT
|
||||
# 299C; RIGHT ANGLE VARIANT WITH SQUARE
|
||||
# 299D; MEASURED RIGHT ANGLE WITH DOT
|
||||
# 299E; ANGLE WITH S INSIDE
|
||||
# 299F; ACUTE ANGLE
|
||||
# 29A2; TURNED ANGLE
|
||||
# 29A6; OBLIQUE ANGLE OPENING UP
|
||||
# 29A7; OBLIQUE ANGLE OPENING DOWN
|
||||
# 29C2; CIRCLE WITH SMALL CIRCLE TO THE RIGHT
|
||||
# 29C3; CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT
|
||||
# 29C9; TWO JOINED SQUARES
|
||||
# 29CE; RIGHT TRIANGLE ABOVE LEFT TRIANGLE
|
||||
# 29DC; INCOMPLETE INFINITY
|
||||
# 29E1; INCREASES AS
|
||||
# 29E3; EQUALS SIGN AND SLANTED PARALLEL
|
||||
# 29E4; EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE
|
||||
# 29E5; IDENTICAL TO AND SLANTED PARALLEL
|
||||
# 29F4; RULE-DELAYED
|
||||
# 29F6; SOLIDUS WITH OVERBAR
|
||||
# 29F7; REVERSE SOLIDUS WITH HORIZONTAL STROKE
|
||||
# 2A0A; MODULO TWO SUM
|
||||
# 2A0B; SUMMATION WITH INTEGRAL
|
||||
# 2A0C; QUADRUPLE INTEGRAL OPERATOR
|
||||
# 2A0D; FINITE PART INTEGRAL
|
||||
# 2A0E; INTEGRAL WITH DOUBLE STROKE
|
||||
# 2A0F; INTEGRAL AVERAGE WITH SLASH
|
||||
# 2A10; CIRCULATION FUNCTION
|
||||
# 2A11; ANTICLOCKWISE INTEGRATION
|
||||
# 2A12; LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE
|
||||
# 2A13; LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE
|
||||
# 2A14; LINE INTEGRATION NOT INCLUDING THE POLE
|
||||
# 2A15; INTEGRAL AROUND A POINT OPERATOR
|
||||
# 2A16; QUATERNION INTEGRAL OPERATOR
|
||||
# 2A17; INTEGRAL WITH LEFTWARDS ARROW WITH HOOK
|
||||
# 2A18; INTEGRAL WITH TIMES SIGN
|
||||
# 2A19; INTEGRAL WITH INTERSECTION
|
||||
# 2A1A; INTEGRAL WITH UNION
|
||||
# 2A1B; INTEGRAL WITH OVERBAR
|
||||
# 2A1C; INTEGRAL WITH UNDERBAR
|
||||
# 2A1E; LARGE LEFT TRIANGLE OPERATOR
|
||||
# 2A1F; Z NOTATION SCHEMA COMPOSITION
|
||||
# 2A20; Z NOTATION SCHEMA PIPING
|
||||
# 2A21; Z NOTATION SCHEMA PROJECTION
|
||||
# 2A24; PLUS SIGN WITH TILDE ABOVE
|
||||
# 2A26; PLUS SIGN WITH TILDE BELOW
|
||||
# 2A29; MINUS SIGN WITH COMMA ABOVE
|
||||
# 2A3E; Z NOTATION RELATIONAL COMPOSITION
|
||||
# 2A57; SLOPING LARGE OR
|
||||
# 2A58; SLOPING LARGE AND
|
||||
# 2A6A; TILDE OPERATOR WITH DOT ABOVE
|
||||
# 2A6B; TILDE OPERATOR WITH RISING DOTS
|
||||
# 2A6C; SIMILAR MINUS SIMILAR
|
||||
# 2A6D; CONGRUENT WITH DOT ABOVE
|
||||
# 2A6F; ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT
|
||||
# 2A70; APPROXIMATELY EQUAL OR EQUAL TO
|
||||
# 2A73; EQUALS SIGN ABOVE TILDE OPERATOR
|
||||
# 2A74; DOUBLE COLON EQUAL
|
||||
# 2AA3; DOUBLE NESTED LESS-THAN WITH UNDERBAR
|
||||
# 2ADC; FORKING
|
||||
# 2AE2; VERTICAL BAR TRIPLE RIGHT TURNSTILE
|
||||
# 2AE6; LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL
|
||||
# 2AF3; PARALLEL WITH TILDE OPERATOR
|
||||
# 2AFB; TRIPLE SOLIDUS BINARY RELATION
|
||||
# 2AFD; DOUBLE SOLIDUS OPERATOR
|
||||
# 1D6DB; MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
|
||||
# 1D715; MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
|
||||
# 1D74F; MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
|
||||
# 1D789; MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
|
||||
# 1D7C3; MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
|
||||
|
||||
# EOF
|
33797
bgrabitmap/dev/parseunicode/UnicodeData.txt
Normal file
33797
bgrabitmap/dev/parseunicode/UnicodeData.txt
Normal file
File diff suppressed because it is too large
Load Diff
69
bgrabitmap/dev/parseunicode/parseunicodeclasses.lpi
Normal file
69
bgrabitmap/dev/parseunicode/parseunicodeclasses.lpi
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="11"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<MainUnit Value="0"/>
|
||||
<Title Value="parseunicodeclasses"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<BuildModes Count="1">
|
||||
<Item1 Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
<Modes Count="1">
|
||||
<Mode0 Name="default"/>
|
||||
</Modes>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="1">
|
||||
<Item1>
|
||||
<PackageName Value="LazUtils"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="1">
|
||||
<Unit0>
|
||||
<Filename Value="parseunicodeclasses.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit0>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target>
|
||||
<Filename Value="parseunicodeclasses"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="0"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="3">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
771
bgrabitmap/dev/parseunicode/parseunicodeclasses.lpr
Normal file
771
bgrabitmap/dev/parseunicode/parseunicodeclasses.lpr
Normal file
@@ -0,0 +1,771 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-only (modified to allow linking)
|
||||
program parseunicodeclasses;
|
||||
|
||||
uses Classes, sysutils, fgl, LazUTF8;
|
||||
|
||||
type
|
||||
TIntegerList = specialize TFPGList<Integer>;
|
||||
|
||||
var
|
||||
UnicodeData: array of record
|
||||
Code: LongInt;
|
||||
Name, Category: string;
|
||||
CombiningClass: byte;
|
||||
BidiClass, Decomposition: string;
|
||||
Mirrored: boolean;
|
||||
OldName: string;
|
||||
end;
|
||||
UnicodeCount: integer;
|
||||
|
||||
procedure LoadUnicodeData;
|
||||
var
|
||||
lines, cells: TStringList;
|
||||
i: Integer;
|
||||
begin
|
||||
lines := TStringList.Create;
|
||||
lines.LoadFromFile('UnicodeData.txt');
|
||||
setlength(UnicodeData, lines.Count);
|
||||
UnicodeCount := 0;
|
||||
cells := TStringList.Create;
|
||||
cells.Delimiter := ';';
|
||||
cells.QuoteChar := '"';
|
||||
cells.StrictDelimiter := true;
|
||||
for i := 0 to lines.Count-1 do
|
||||
begin
|
||||
cells.DelimitedText := lines[i];
|
||||
if cells.Count >= 11 then
|
||||
with UnicodeData[UnicodeCount] do
|
||||
begin
|
||||
Code := StrToInt('$'+cells[0]);
|
||||
Name := cells[1];
|
||||
Category := cells[2];
|
||||
CombiningClass:= StrToInt(cells[3]);
|
||||
BidiClass := cells[4];
|
||||
Decomposition:= cells[5];
|
||||
Mirrored := (cells[9] = 'Y');
|
||||
OldName := cells[10];
|
||||
inc(UnicodeCount);
|
||||
end;
|
||||
end;
|
||||
SetLength(UnicodeData, unicodeCount);
|
||||
lines.Free;
|
||||
end;
|
||||
|
||||
function IndexOfUnicode(u: LongInt): integer;
|
||||
var
|
||||
low, high, mid: Integer;
|
||||
begin
|
||||
low := 0;
|
||||
high := UnicodeCount-1;
|
||||
while low < high do
|
||||
begin
|
||||
mid := (low+high) div 2;
|
||||
if u > UnicodeData[mid].Code then
|
||||
low := mid+1
|
||||
else
|
||||
high := mid;
|
||||
end;
|
||||
if UnicodeData[low].Code = u then
|
||||
result := low
|
||||
else
|
||||
result := -1;
|
||||
end;
|
||||
|
||||
function GetUnicodeBidiClass(u: LongInt): string;
|
||||
var
|
||||
idx: Integer;
|
||||
begin
|
||||
idx := IndexOfUnicode(u);
|
||||
if idx = -1 then
|
||||
result := ''
|
||||
else result := UnicodeData[idx].BidiClass;
|
||||
end;
|
||||
|
||||
function GetUnicodeCombiningClass(u: LongInt): byte;
|
||||
var
|
||||
idx: Integer;
|
||||
begin
|
||||
idx := IndexOfUnicode(u);
|
||||
if idx = -1 then
|
||||
result := 0
|
||||
else result := UnicodeData[idx].CombiningClass;
|
||||
end;
|
||||
|
||||
function UnicodeCharToUTF8(u: LongInt): string;
|
||||
begin
|
||||
if u >= 0 then
|
||||
result := UnicodeToUTF8(cardinal(u))
|
||||
else
|
||||
result := '';
|
||||
end;
|
||||
|
||||
function ArrayOfCodeToCase(ACodes: array of integer; AIndent: string): string;
|
||||
var
|
||||
codeCount, i: Integer;
|
||||
bufLines: TStringList;
|
||||
buf: String;
|
||||
begin
|
||||
codeCount := length(ACodes);
|
||||
if codeCount = 0 then exit('');
|
||||
|
||||
bufLines := TStringList.Create;
|
||||
i := 0;
|
||||
buf := AIndent+' ';
|
||||
while i < codeCount do
|
||||
begin
|
||||
if i > 0 then buf += ', ';
|
||||
|
||||
if length(buf) > 95 then
|
||||
begin
|
||||
bufLines.Add(buf);
|
||||
buf := AIndent+' ';
|
||||
end;
|
||||
|
||||
if (i+2 < codeCount) and (ACodes[i]+1 = ACodes[i+1]) and (ACodes[i+1]+1 = ACodes[i+2]) then
|
||||
begin
|
||||
buf += '$'+IntToHex(ACodes[i],2) + '..';
|
||||
while (i+1 < codeCount) and (ACodes[i]+1 = ACodes[i+1]) do inc(i);
|
||||
buf += '$'+IntToHex(ACodes[i],2);
|
||||
end else
|
||||
buf += '$'+IntToHex(ACodes[i],2);
|
||||
|
||||
inc(i);
|
||||
end;
|
||||
|
||||
if trim(buf) <> '' then bufLines.Add(buf);
|
||||
|
||||
result := '';
|
||||
for i := 0 to bufLines.Count-1 do
|
||||
begin
|
||||
if i > 0 then result += LineEnding;
|
||||
result += bufLines[i];
|
||||
end;
|
||||
|
||||
bufLines.Free;
|
||||
result += ': ';
|
||||
end;
|
||||
|
||||
function ArrayOfCodeToCase(ACodes: TIntegerList; AIndent: string): string;
|
||||
var a: array of integer;
|
||||
i: Integer;
|
||||
begin
|
||||
setlengtH(a, ACodes.Count);
|
||||
for i := 0 to high(a) do
|
||||
a[i] := ACodes[i];
|
||||
result := ArrayOfCodeToCase(a, AIndent);
|
||||
end;
|
||||
|
||||
procedure GenerateUnicodeFunctions;
|
||||
const Indent = ' ';
|
||||
var
|
||||
tIn, tOut: TextFile;
|
||||
|
||||
procedure ParseBidiClasses;
|
||||
type
|
||||
TUnicodeBidiClass = (ubcBoundaryNeutral, ubcSegmentSeparator, ubcParagraphSeparator, ubcWhiteSpace, ubcOtherNeutrals,
|
||||
ubcCommonSeparator, ubcNonSpacingMark,
|
||||
ubcLeftToRight, ubcEuropeanNumber, ubcEuropeanNumberSeparator, ubcEuropeanNumberTerminator,
|
||||
ubcRightToLeft, ubcArabicLetter, ubcArabicNumber,
|
||||
ubcUnknown,
|
||||
ubcCombiningLeftToRight, //ubcLeftToRight in Mc category
|
||||
ubcMirroredNeutral); //ubcOtherNeutrals with Mirrored property
|
||||
|
||||
procedure IncludeClasses(AClasses: TStrings; AMinCode, AMaxCode: integer);
|
||||
const
|
||||
MaxGapsPerClass = 20;
|
||||
var
|
||||
codes: array[TUnicodeBidiClass] of TIntegerList;
|
||||
gaps: array[TUnicodeBidiClass] of integer;
|
||||
|
||||
procedure FlushCase(curBidi: TUnicodeBidiClass);
|
||||
var
|
||||
caseStr: string;
|
||||
begin
|
||||
if codes[curBidi].Count = 0 then exit;
|
||||
caseStr := ArrayOfCodeToCase(codes[curBidi], Indent);
|
||||
|
||||
case curBidi of
|
||||
ubcCommonSeparator: WriteLn(tOut,caseStr+'result := ubcCommonSeparator;');
|
||||
ubcLeftToRight: WriteLn(tOut,caseStr+'result := ubcLeftToRight;');
|
||||
ubcCombiningLeftToRight: WriteLn(tOut,caseStr+'result := ubcCombiningLeftToRight;');
|
||||
ubcEuropeanNumber: WriteLn(tOut,caseStr+'result := ubcEuropeanNumber;');
|
||||
ubcEuropeanNumberSeparator: WriteLn(tOut,caseStr+'result := ubcEuropeanNumberSeparator;');
|
||||
ubcEuropeanNumberTerminator: WriteLn(tOut,caseStr+'result := ubcEuropeanNumberTerminator;');
|
||||
ubcRightToLeft: WriteLn(tOut,caseStr+'result := ubcRightToLeft;');
|
||||
ubcArabicLetter: WriteLn(tOut,caseStr+'result := ubcArabicLetter;');
|
||||
ubcArabicNumber: WriteLn(tOut,caseStr+'result := ubcArabicNumber;');
|
||||
ubcNonSpacingMark: WriteLn(tOut,caseStr+'result := ubcNonSpacingMark;');
|
||||
ubcBoundaryNeutral: WriteLn(tOut,caseStr+'result := ubcBoundaryNeutral;');
|
||||
ubcParagraphSeparator: WriteLn(tOut,caseStr+'result := ubcParagraphSeparator;');
|
||||
ubcSegmentSeparator: WriteLn(tOut,caseStr+'result := ubcSegmentSeparator;');
|
||||
ubcWhiteSpace: WriteLn(tOut,caseStr+'result := ubcWhiteSpace;');
|
||||
ubcMirroredNeutral: WriteLn(tOut,caseStr+'result := ubcMirroredNeutral;');
|
||||
ubcOtherNeutrals: WriteLn(tOut,caseStr+'result := ubcOtherNeutrals;');
|
||||
else raise exception.Create('Unknown bidi class');
|
||||
end;
|
||||
codes[curBidi].Clear;
|
||||
gaps[curBidi] := 0;
|
||||
end;
|
||||
|
||||
var
|
||||
newBidi: TUnicodeBidiClass;
|
||||
curCode: LongInt;
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
write(' ', AClasses.DelimitedText);
|
||||
for newBidi := low(TUnicodeBidiClass) to high(TUnicodeBidiClass) do
|
||||
begin
|
||||
codes[newBidi] := TIntegerList.Create;
|
||||
gaps[newBidi] := 0;
|
||||
end;
|
||||
for i := 0 to UnicodeCount-1 do
|
||||
begin
|
||||
case UnicodeData[i].BidiClass of
|
||||
'CS': newBidi := ubcCommonSeparator;
|
||||
'L': newBidi := ubcLeftToRight;
|
||||
'EN': newBidi := ubcEuropeanNumber;
|
||||
'ES': newBidi := ubcEuropeanNumberSeparator;
|
||||
'ET': newBidi := ubcEuropeanNumberTerminator;
|
||||
'R': newBidi := ubcRightToLeft;
|
||||
'AL': newBidi := ubcArabicLetter;
|
||||
'AN': newBidi := ubcArabicNumber;
|
||||
'NSM': newBidi := ubcNonSpacingMark;
|
||||
'BN': newBidi := ubcBoundaryNeutral;
|
||||
'B': newBidi := ubcParagraphSeparator;
|
||||
'S': newBidi := ubcSegmentSeparator;
|
||||
'WS': newBidi := ubcWhiteSpace;
|
||||
'ON': newBidi := ubcOtherNeutrals;
|
||||
else continue;
|
||||
end;
|
||||
if (newBidi = ubcLeftToRight) and (UnicodeData[i].Category = 'Mc') then newBidi := ubcCombiningLeftToRight
|
||||
else if (newBidi = ubcOtherNeutrals) and UnicodeData[i].Mirrored then newBidi := ubcMirroredNeutral;
|
||||
if AClasses.IndexOf(UnicodeData[i].BidiClass)<>-1 then
|
||||
begin
|
||||
curCode := UnicodeData[i].Code;
|
||||
if (curCode >= AMinCode) and (curCode <= AMaxCode) then
|
||||
begin
|
||||
if (codes[newBidi].Count > 0) and (codes[newBidi].Last+1 <> curCode) then
|
||||
inc(gaps[newBidi]);
|
||||
codes[newBidi].Add(curCode);
|
||||
if gaps[newBidi] > MaxGapsPerClass then
|
||||
FlushCase(newBidi);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
for newBidi := low(TUnicodeBidiClass) to high(TUnicodeBidiClass) do
|
||||
begin
|
||||
FlushCase(newBidi);
|
||||
codes[newBidi].Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
var c: TStringList;
|
||||
|
||||
procedure Include(AMinCode,AMaxCode: integer);
|
||||
begin
|
||||
write('Classes from ',IntToHex(AMinCode,2),' to ',IntToHex(AMaxCode,2),':');
|
||||
Writeln(tOut,Indent+'case u of');
|
||||
c.CommaText := 'BN';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'S';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'B';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'WS';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'L,CL,R,AL';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'EN';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'ES';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'ET';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'AN';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'CS,NSM';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
c.CommaText := 'ON,MN';
|
||||
IncludeClasses(c, AMinCode,AMaxCode);
|
||||
writeln(tout,Indent+'else result := ubcUnknown;');
|
||||
writeln(tout,Indent+'end;');
|
||||
writeln;
|
||||
end;
|
||||
|
||||
begin
|
||||
Writeln(tOut,'function GetUnicodeBidiClassEx(u: LongWord): TUnicodeBidiClass;');
|
||||
Writeln(tOut,'begin');
|
||||
c := TStringList.Create;
|
||||
writeln(tOut,' case u of');
|
||||
writeln(tOut,' $00000..$07FFF:');
|
||||
writeln(tOut,' case u of');
|
||||
writeln(tOut,' $00000..$003FF:');
|
||||
Include($00000, $003FF);
|
||||
writeln(tOut,' $00400..$007FF:');
|
||||
Include($00400, $007FF);
|
||||
writeln(tOut,' $00800..$00BFF:');
|
||||
Include($00800, $00BFF);
|
||||
writeln(tOut,' $00C00..$00FFF:');
|
||||
Include($00C00, $00FFF);
|
||||
writeln(tOut,' $01000..$017FF:');
|
||||
Include($01000, $017FF);
|
||||
writeln(tOut,' $01800..$01FFF:');
|
||||
Include($01800, $01FFF);
|
||||
writeln(tOut,' $02000..$02FFF:');
|
||||
Include($02000, $02FFF);
|
||||
writeln(tOut,' else');
|
||||
Include($03000, $07FFF);
|
||||
writeln(tOut,' end;');
|
||||
writeln(tOut,' $08000..$0BFFF:');
|
||||
Include($08000, $0BFFF);
|
||||
writeln(tOut,' $0C000..$0FFFF:');
|
||||
Include($0C000, $0FFFF);
|
||||
writeln(tOut,' else');
|
||||
writeln(tOut,' case u of');
|
||||
writeln(tOut,' $10000..$107FF:');
|
||||
Include($10000, $107FF);
|
||||
writeln(tOut,' $10800..$10FFF:');
|
||||
Include($10800, $10FFF);
|
||||
writeln(tOut,' $11000..$117FF:');
|
||||
Include($11000, $117FF);
|
||||
writeln(tOut,' $11800..$17FFF:');
|
||||
Include($11800, $17FFF);
|
||||
writeln(tOut,' $18000..$1DFFF:');
|
||||
Include($18000, $1DFFF);
|
||||
writeln(tOut,' $1E000..$FFFFF:');
|
||||
Include($1E000, $FFFFF);
|
||||
writeln(tOut,' else result := ubcUnknown;');
|
||||
writeln(tOut,' end');
|
||||
writeln(tOut,' end');
|
||||
c.Free;
|
||||
|
||||
writeln(tout,'end;');
|
||||
writeln(tout);
|
||||
end;
|
||||
|
||||
procedure ParseBidiBrackets;
|
||||
var elem: TStringList;
|
||||
line: string;
|
||||
tIn: TextFile;
|
||||
begin
|
||||
Writeln(tOut,'function GetUnicodeBracketInfo(u: LongWord): TUnicodeBracketInfo;');
|
||||
Writeln(tOut,' procedure Bracket(AOpening,AClosing: LongWord);');
|
||||
Writeln(tOut,' begin');
|
||||
Writeln(tOut,' result.IsBracket := true;');
|
||||
Writeln(tOut,' result.OpeningBracket := AOpening;');
|
||||
Writeln(tOut,' result.ClosingBracket := AClosing;');
|
||||
Writeln(tOut,' end;');
|
||||
Writeln(tOut,'begin');
|
||||
Writeln(tOut,' case u of');
|
||||
|
||||
writeln('Parsing bracket data...');
|
||||
assignfile(tIn, 'BidiBrackets.txt');
|
||||
reset(tin);
|
||||
elem := TStringList.Create;
|
||||
elem.Delimiter := ';';
|
||||
elem.StrictDelimiter:= true;
|
||||
while not eof(tin) do
|
||||
begin
|
||||
readln(tin, line);
|
||||
elem.DelimitedText:= line;
|
||||
if elem.Count >= 3 then
|
||||
begin
|
||||
if copy(trim(elem[2]),1,1) = 'o' then
|
||||
writeln(tOut,' $'+trim(elem[0])+', $'+trim(elem[1])+': Bracket($'+trim(elem[0])+', $'+trim(elem[1])+');');
|
||||
end;
|
||||
end;
|
||||
elem.Free;
|
||||
closefile(tin);
|
||||
|
||||
writeln(tout,' else');
|
||||
writeln(tout,' begin');
|
||||
writeln(tout,' result.IsBracket := false;');
|
||||
writeln(tout,' result.OpeningBracket := 0;');
|
||||
writeln(tout,' result.ClosingBracket := 0;');
|
||||
writeln(tout,' end;');
|
||||
Writeln(tOut,' end;');
|
||||
Writeln(tOut,'end;');
|
||||
Writeln(tOut);
|
||||
end;
|
||||
|
||||
procedure ParseArabicLigature;
|
||||
var
|
||||
line: string;
|
||||
cells: TStringList;
|
||||
chars: TStringList;
|
||||
u: LongInt;
|
||||
j: Integer;
|
||||
|
||||
procedure AddJoiningType(joinType: string; joinTypeEnum: string; AIndent: string; AMinIndex,AMaxIndex: integer);
|
||||
var
|
||||
i,nb: Integer;
|
||||
charsList: array of integer;
|
||||
begin
|
||||
nb := 0;
|
||||
for i := AMinIndex to AMaxIndex do
|
||||
if chars.ValueFromIndex[i]=joinType then inc(nb);
|
||||
if nb = 0 then exit;
|
||||
setlength(charsList, nb);
|
||||
nb := 0;
|
||||
for i := AMinIndex to AMaxIndex do
|
||||
if chars.ValueFromIndex[i]=joinType then
|
||||
begin
|
||||
charsList[nb] := StrToInt('$'+chars.Names[i]);
|
||||
inc(nb);
|
||||
end;
|
||||
writeln(tOut,ArrayOfCodeToCase(charsList, AIndent)+'result := '+joinTypeEnum+';');
|
||||
end;
|
||||
|
||||
procedure AddJoiningTypeRange(AMinIndex,AMaxIndex: integer; AIndent: string; AForceCase: boolean = false);
|
||||
const MaxGaps = 45;
|
||||
var
|
||||
mid, i, gaps, halfGaps: Integer;
|
||||
begin
|
||||
gaps := 0;
|
||||
for i := AMinIndex+1 to AMaxIndex do
|
||||
if (StrToInt('$'+chars.Names[i])-StrToInt('$'+chars.Names[i-1]) > 1) or
|
||||
(chars.ValueFromIndex[i] <> chars.ValueFromIndex[i-1]) then inc(gaps);
|
||||
if (gaps > MaxGaps) and not AForceCase then
|
||||
begin
|
||||
halfGaps := 0;
|
||||
mid := (AMinIndex+AMaxIndex) div 2;
|
||||
for i := AMinIndex+1 to AMaxIndex do
|
||||
if (StrToInt('$'+chars.Names[i])-StrToInt('$'+chars.Names[i-1]) > 1) or
|
||||
(chars.ValueFromIndex[i] <> chars.ValueFromIndex[i-1]) then
|
||||
begin
|
||||
inc(halfGaps);
|
||||
if halfGaps >= gaps shr 1 then
|
||||
begin
|
||||
mid := i;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
if gaps <= MaxGaps*2.5 then
|
||||
begin
|
||||
writeln(tOut,AIndent, 'if u <= $', chars.Names[mid],' then');
|
||||
AddJoiningTypeRange(AMinIndex, mid, AIndent+' ', true);
|
||||
writeln(tOut,AIndent, 'else');
|
||||
AddJoiningTypeRange(mid+1, AMaxIndex, AIndent+' ', true);
|
||||
end else
|
||||
begin
|
||||
writeln(tOut,AIndent, 'if u <= $', chars.Names[mid],' then begin');
|
||||
AddJoiningTypeRange(AMinIndex, mid, AIndent+' ');
|
||||
writeln(tOut,AIndent, 'end else begin');
|
||||
AddJoiningTypeRange(mid+1, AMaxIndex, AIndent+' ');
|
||||
writeln(tOut,AIndent, 'end');
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
writeln(tOut,AIndent, 'case u of');
|
||||
AddJoiningType('T', 'ujtTransparent', AIndent, AMinIndex, AMaxIndex);
|
||||
AddJoiningType('R', 'ujtRightJoining', AIndent, AMinIndex, AMaxIndex);
|
||||
AddJoiningType('L', 'ujtLeftJoining', AIndent, AMinIndex, AMaxIndex);
|
||||
AddJoiningType('D', 'ujtDualJoining', AIndent, AMinIndex, AMaxIndex);
|
||||
AddJoiningType('C', 'ujtJoinCausing', AIndent, AMinIndex, AMaxIndex);
|
||||
writeln(tOut,AIndent, 'end');
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
writeln('Parsing arabic ligature data...');
|
||||
chars := TStringList.Create;
|
||||
for j := 0 to UnicodeCount-1 do
|
||||
begin
|
||||
if (UnicodeData[j].Category = 'Mn') or (UnicodeData[j].Category = 'Me')
|
||||
or (UnicodeData[j].Category = 'Cf') then
|
||||
chars.Values[IntToHex(UnicodeData[j].Code,6)] := 'T';
|
||||
end;
|
||||
assignfile(tIn, 'ArabicShaping.txt');
|
||||
reset(tIn);
|
||||
cells := TStringList.Create;
|
||||
cells.Delimiter := ';';
|
||||
cells.QuoteChar := '"';
|
||||
cells.StrictDelimiter := true;
|
||||
while not eof(tIn) do
|
||||
begin
|
||||
readln(tIn, line);
|
||||
if (line = '') or (line[1]='#') then continue;
|
||||
cells.DelimitedText:= line;
|
||||
if cells.Count >= 4 then
|
||||
begin
|
||||
u := StrToInt('$'+cells[0]);
|
||||
if trim(cells[2]) = 'U' then
|
||||
begin
|
||||
j := chars.IndexOfName(IntToHex(u,6));
|
||||
if j <> -1 then
|
||||
chars.Delete(j);
|
||||
end
|
||||
else
|
||||
chars.Values[IntToHex(u,6)] := trim(cells[2]);
|
||||
end;
|
||||
end;
|
||||
closefile(tIn);
|
||||
cells.Free;
|
||||
chars.Sort;
|
||||
Writeln(tOut,'function GetUnicodeJoiningType(u: LongWord): TUnicodeJoiningType;');
|
||||
Writeln(tOut,'begin');
|
||||
writeln(tOut,' result := ujtNonJoining;');
|
||||
AddJoiningTypeRange(0, chars.Count-1, ' ');
|
||||
chars.Free;
|
||||
Writeln(tOut,'end;');
|
||||
Writeln(tOut);
|
||||
end;
|
||||
|
||||
procedure ParseCombiningClasses;
|
||||
const
|
||||
CombineLeftOnly = '093F,094E,' + {DEVANAGARI}
|
||||
'09BF,09C7,09C8,' + {BENGALI}
|
||||
'0A3F,' + {GURMUKHI}
|
||||
'0ABF,' + {GUJARATI}
|
||||
'0B47,0B48,0B4B,0B4C,' + {ORIYA}
|
||||
'0BC6,0BC7,0BC8,' + {TAMIL}
|
||||
'0D46,0D47,0D48,' + {MALAYALAM}
|
||||
'0DD9,0DDA,0DDB,0DDC,0DDD,0DDE,' + {SINHALA}
|
||||
'1031,103C,1084,' + {MYANMAR}
|
||||
'17BE,17C1,17C2,17C3,' + {KHMER}
|
||||
'1A19,' + {BUGINESE}
|
||||
'1B3E,1B3F,' + {BALINESE}
|
||||
'302E,302F,' + {HANGUL}
|
||||
'A9BA,A9BB,A9BF,' + {JAVANESE}
|
||||
'AA2F,AA30,AA34,'; {CHAM}
|
||||
CombineLeftAndRight = '09CB,09CC,' + {BENGALI}
|
||||
'0BCA,0BCB,0BCC,' + {TAMIL}
|
||||
'0D4A,0D4B,0D4C,' + {MALAYALAM}
|
||||
'17BF,17C0,17C4,17C5,' + {KHMER}
|
||||
'1B3D,1B40,1B41,'; {BALINESE}
|
||||
|
||||
var
|
||||
i: Integer;
|
||||
infos: TStringList;
|
||||
u: LongInt;
|
||||
c: byte;
|
||||
s: String;
|
||||
|
||||
procedure FlushLine;
|
||||
begin
|
||||
writeln(tOut, s);
|
||||
s := ' ';
|
||||
end;
|
||||
|
||||
begin
|
||||
infos := TStringList.Create;
|
||||
for i := 0 to UnicodeCount-1 do
|
||||
begin
|
||||
u := UnicodeData[i].Code;
|
||||
if (UnicodeData[i].BidiClass = 'NSM') or
|
||||
(UnicodeData[i].Category = 'Mc') then
|
||||
begin
|
||||
c := UnicodeData[i].CombiningClass;
|
||||
if (c = 0) and (UnicodeData[i].Category = 'Mc') then
|
||||
begin
|
||||
if pos(IntToHex(u,4)+',', CombineLeftOnly) <> 0 then c := 208
|
||||
else if pos(IntToHex(u,4)+',', CombineLeftAndRight) <> 0 then c := 0
|
||||
else c := 210;
|
||||
end;
|
||||
infos.Add('(u:$'+IntToHex(u,2)+'; c:'+IntToStr(c)+')');
|
||||
end;
|
||||
end;
|
||||
writeln(tOut,'type');
|
||||
writeln(tOut,' TUnicodeCombiningInfo = record');
|
||||
writeln(tOut,' u: LongWord;');
|
||||
writeln(tOut,' c: Byte;');
|
||||
writeln(tOut,' end;');
|
||||
writeln(tOut,'const');
|
||||
writeln(tOut,' UnicodeCombiningInfos: array[0..',infos.count-1,'] of TUnicodeCombiningInfo =');
|
||||
s := ' (';
|
||||
for i := 0 to infos.Count-1 do
|
||||
begin
|
||||
if length(s) + length(infos[i]) + 2 > 80 then FlushLine;
|
||||
AppendStr(s, ' ' + infos[i]);
|
||||
if i < infos.Count-1 then AppendStr(s, ',');
|
||||
end;
|
||||
if s <> ' ' then FlushLine;
|
||||
writeln(tOut,' );');
|
||||
writeln(tOut);
|
||||
infos.Free;
|
||||
end;
|
||||
|
||||
begin
|
||||
AssignFile(tOut, 'generatedunicode.inc');
|
||||
Rewrite(tOut);
|
||||
writeln(tOut,'{ This file is generated by dev/parseunicode/parseunicodeclasses program }');
|
||||
Writeln(tOut);
|
||||
ParseBidiClasses;
|
||||
ParseBidiBrackets;
|
||||
ParseArabicLigature;
|
||||
ParseCombiningClasses;
|
||||
CloseFile(tOut);
|
||||
end;
|
||||
|
||||
function ListCompareBinary(List: TStringList; Index1, Index2: Integer): Integer;
|
||||
begin
|
||||
result := CompareStr(List[Index1], List[Index2]);
|
||||
end;
|
||||
|
||||
procedure ParseUTF8Decomposition;
|
||||
type TDecompositionKind = string;
|
||||
const dMultichar = 'arNone';
|
||||
dInitial = 'arInitial';
|
||||
dMedial = 'arMedial';
|
||||
dFinal = 'arFinal';
|
||||
dIsolated = 'arIsolated';
|
||||
const UTF8_ARABIC_ALEPH = 'ا';
|
||||
UTF8_ARABIC_ALEPH_HAMZA_BELOW = 'إ';
|
||||
UTF8_ARABIC_ALEPH_HAMZA_ABOVE = 'أ';
|
||||
UTF8_ARABIC_ALEPH_MADDA_ABOVE = 'آ';
|
||||
UTF8_ARABIC_LAM = 'ل';
|
||||
var tOut: TextFile;
|
||||
decomposed, kind, decomposedUTF8, s: string;
|
||||
decomposedFirstChar: LongInt;
|
||||
mergedU,nextU, fallbackU: LongInt;
|
||||
posClose, posSpace: SizeInt;
|
||||
hasNSM, isLa: Boolean;
|
||||
correspList: TStringList;
|
||||
kerningFallback: TStringList;
|
||||
i, decomposedLen, j: Integer;
|
||||
typedKind: TDecompositionKind;
|
||||
hasMarkLeft, hasMarkRight: boolean;
|
||||
|
||||
function RemoveUptoTab(AText: string): string;
|
||||
var
|
||||
idxTab: SizeInt;
|
||||
begin
|
||||
idxTab := pos(#9, AText);
|
||||
result := copy(AText, idxTab+1, length(AText)-idxTab);
|
||||
end;
|
||||
|
||||
begin
|
||||
writeln('Parsing decomposition data...');
|
||||
correspList := TStringList.Create;
|
||||
kerningFallback := TStringList.Create;
|
||||
for j := 0 to UnicodeCount-1 do
|
||||
begin
|
||||
mergedU := UnicodeData[j].Code;
|
||||
if UnicodeData[j].BidiClass = 'NSM' then continue;
|
||||
decomposed := UnicodeData[j].Decomposition;
|
||||
if decomposed = '' then continue;
|
||||
typedKind := dMultichar;
|
||||
if decomposed[1] = '<' then
|
||||
begin
|
||||
posClose := pos('>', decomposed);
|
||||
if posClose = 0 then continue;
|
||||
kind := copy(decomposed,1,posClose);
|
||||
delete(decomposed, 1, posClose);
|
||||
if kind = '<initial>' then typedKind := dInitial else
|
||||
if kind = '<medial>' then typedKind := dMedial else
|
||||
if kind = '<final>' then typedKind := dFinal else
|
||||
if kind = '<isolated>' then typedKind := dIsolated else
|
||||
if (kind = '<compat>') and (mergedU >= $FB00) and (mergedU <= $FB04) then
|
||||
typedKind := dMultichar
|
||||
else
|
||||
continue;
|
||||
decomposed := trim(decomposed);
|
||||
end;
|
||||
decomposedUTF8 := '';
|
||||
decomposedLen := 0;
|
||||
decomposedFirstChar:= 0;
|
||||
hasMarkLeft := false;
|
||||
hasMarkRight := false;
|
||||
hasNSM := false;
|
||||
while decomposed <> '' do
|
||||
begin
|
||||
posSpace := pos(' ',decomposed);
|
||||
if posSpace = 0 then posSpace := length(decomposed)+1;
|
||||
nextU := strToInt('$'+copy(decomposed,1,posSpace-1));
|
||||
if GetUnicodeBidiClass(nextU) = 'NSM' then hasNSM := true;
|
||||
case GetUnicodeCombiningClass(nextU) of
|
||||
200,208,212,218,224,228: hasMarkLeft := true;
|
||||
204,210,216,222,226,232: hasMarkRight := true;
|
||||
end;
|
||||
if decomposedLen = 0 then decomposedFirstChar:= nextU;
|
||||
AppendStr(decomposedUTF8, UnicodeCharToUTF8(nextU));
|
||||
delete(decomposed, 1, posSpace);
|
||||
inc(decomposedLen);
|
||||
end;
|
||||
isLa := (decomposedUTF8 = UTF8_ARABIC_LAM+UTF8_ARABIC_ALEPH) or
|
||||
(decomposedUTF8 = UTF8_ARABIC_LAM+UTF8_ARABIC_ALEPH_HAMZA_BELOW) or
|
||||
(decomposedUTF8 = UTF8_ARABIC_LAM+UTF8_ARABIC_ALEPH_HAMZA_ABOVE) or
|
||||
(decomposedUTF8 = UTF8_ARABIC_LAM+UTF8_ARABIC_ALEPH_MADDA_ABOVE);
|
||||
if ((typedKind = dMultichar) and (decomposedLen > 1)
|
||||
and (hasNSM or (copy(decomposedUTF8,1,1) = 'f'))) or
|
||||
((typedKind <> dMultichar) and ((decomposedLen = 1) or isLa)) then
|
||||
correspList.Add(decomposedUTF8+#9+'('+
|
||||
'de:''' + decomposedUTF8 + '''; ' +
|
||||
're:''' + UnicodeCharToUTF8(mergedU) + '''; ' +
|
||||
'join:' + typedKind +
|
||||
')');
|
||||
if (typedKind = dMultichar) and (decomposedUTF8 <> '') and not hasMarkLeft and not hasMarkRight and
|
||||
((decomposedUTF8[1] in ['A'..'Z']) or (copy(decomposedUTF8,1,length('Æ')) = 'Æ') or
|
||||
(copy(decomposedUTF8,1,length('Ç')) = 'Ç') or
|
||||
(copy(decomposedUTF8,1,length('Г')) = 'Г') or
|
||||
(copy(decomposedUTF8,1,length('Ѵ')) = 'Ѵ') or
|
||||
(copy(decomposedUTF8,1,length('Ω')) = 'Ω') or
|
||||
(copy(decomposedUTF8,1,length('Ө')) = 'Ө')) then
|
||||
begin
|
||||
fallbackU := decomposedFirstChar;
|
||||
if fallbackU <> 32 then
|
||||
kerningFallback.Add('(u:$' + inttohex(mergedU,2)+'; fb:$'+ inttohex(fallbackU,2)+')');
|
||||
end;
|
||||
end;
|
||||
|
||||
AssignFile(tOut, 'generatedutf8.inc');
|
||||
Rewrite(tOut);
|
||||
writeln(tOut,'{ This file is generated by dev/parseunicode/parseunicodeclasses program }');
|
||||
writeln(tOut, 'type');
|
||||
writeln(tOut, ' TArabicJoin = (arNone, arInitial, arMedial, arFinal, arIsolated);');
|
||||
writeln(tOut, ' TUTF8Decomposition = record');
|
||||
writeln(tOut, ' de, re: string; //decomposed, recomposed UTF8');
|
||||
writeln(tOut, ' join: TArabicJoin;');
|
||||
writeln(tOut, ' end;');
|
||||
writeln(tOut, 'const');
|
||||
writeln(tOut, ' UTF8Decomposition : array[0..', correspList.Count-1, '] of TUTF8Decomposition = (');
|
||||
correspList.CustomSort(@ListCompareBinary);
|
||||
for i := 0 to correspList.Count-1 do
|
||||
if i <> correspList.Count-1 then
|
||||
writeln(tOut, ' ', RemoveUptoTab(correspList[i]), ',')
|
||||
else
|
||||
writeln(tOut, ' ', RemoveUptoTab(correspList[i]));
|
||||
correspList.Free;
|
||||
writeln(tOut, ' );');
|
||||
writeln(tout);
|
||||
CloseFile(tOut);
|
||||
|
||||
AssignFile(tOut, 'generatedkerningfallback.inc');
|
||||
Rewrite(tOut);
|
||||
writeln(tOut,'{ This file is generated by dev/parseunicode/parseunicodeclasses program }');
|
||||
writeln(tOut, 'type');
|
||||
writeln(tOut, ' TKerningFallbackInfo = record');
|
||||
writeln(tOut, ' u: integer; //composed charcode');
|
||||
writeln(tOut, ' fb: integer; //fallback code');
|
||||
writeln(tOut, ' end;');
|
||||
writeln(tOut, 'const');
|
||||
writeln(tOut, ' KerningFallbackInfo : array[0..', kerningFallback.Count-1, '] of TKerningFallbackInfo = (');
|
||||
s := '';
|
||||
for i := 0 to kerningFallback.Count-1 do
|
||||
begin
|
||||
if i <> kerningFallback.Count-1 then
|
||||
AppendStr(s, kerningFallback[i] + ', ')
|
||||
else
|
||||
AppendStr(s, kerningFallback[i]);
|
||||
if length(s) > 70 then
|
||||
begin
|
||||
writeln(tOut, ' ', s);
|
||||
s := '';
|
||||
end;
|
||||
end;
|
||||
if s <> '' then
|
||||
writeln(tOut, ' ', s);
|
||||
writeln(tOut, ' );');
|
||||
writeln(tout);
|
||||
kerningFallback.Free;
|
||||
CloseFile(tOut);
|
||||
end;
|
||||
|
||||
begin
|
||||
LoadUnicodeData;
|
||||
GenerateUnicodeFunctions;
|
||||
ParseUTF8Decomposition;
|
||||
writeln('Done.');
|
||||
end.
|
||||
|
68
bgrabitmap/dev/parseunicode/testunicodealgo.lpi
Normal file
68
bgrabitmap/dev/parseunicode/testunicodealgo.lpi
Normal file
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="10"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<MainUnit Value="0"/>
|
||||
<Title Value="testunicodealgo"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<BuildModes Count="1">
|
||||
<Item1 Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<local>
|
||||
<FormatVersion Value="1"/>
|
||||
</local>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="1">
|
||||
<Item1>
|
||||
<PackageName Value="BGRABitmapPack4NoGUI"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="1">
|
||||
<Unit0>
|
||||
<Filename Value="testunicodealgo.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit0>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target>
|
||||
<Filename Value="testunicodealgo"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="0"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="3">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
85
bgrabitmap/dev/parseunicode/testunicodealgo.lpr
Normal file
85
bgrabitmap/dev/parseunicode/testunicodealgo.lpr
Normal file
@@ -0,0 +1,85 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-only (modified to allow linking)
|
||||
program testunicodealgo;
|
||||
|
||||
uses BGRAUTF8, Classes, sysUtils;
|
||||
|
||||
var
|
||||
tIn,tOut: TextFile;
|
||||
testDef: string;
|
||||
testElem, unicodeChars: TStringList;
|
||||
testText: string;
|
||||
posHash, i: integer;
|
||||
a: TBidiUTF8Array;
|
||||
levelStr, orderStr: string;
|
||||
failCount, successCount: integer;
|
||||
o: TUnicodeDisplayOrder;
|
||||
|
||||
begin
|
||||
assignfile(tIn, 'BidiCharacterTest.txt');
|
||||
reset(tIn);
|
||||
|
||||
assignfile(tOut, 'BidiCharacterTest.result');
|
||||
rewrite(tOut);
|
||||
testElem := TStringList.Create;
|
||||
testElem.Delimiter := ';';
|
||||
testElem.StrictDelimiter:= true;
|
||||
unicodeChars := TStringList.Create;
|
||||
unicodeChars.Delimiter := ' ';
|
||||
unicodeChars.StrictDelimiter := true;
|
||||
while not eof(tIn) do
|
||||
begin
|
||||
readln(tIn, testDef);
|
||||
posHash := pos('#',testDef);
|
||||
if posHash <> 0 then testDef := copy(testDef,1,posHash-1);
|
||||
testElem.DelimitedText := testDef;
|
||||
if testElem.Count = 5 then
|
||||
begin
|
||||
unicodeChars.DelimitedText := testElem[0];
|
||||
testText := '';
|
||||
for i := 0 to unicodeChars.Count-1 do
|
||||
testText += UnicodeCharToUTF8(StrToInt('$'+unicodeChars[i]));
|
||||
|
||||
if testText = '' then continue;
|
||||
|
||||
//writeln(testDef);
|
||||
case testElem[1] of
|
||||
'0': a := AnalyzeBidiUTF8(testText,false);
|
||||
'1': a := AnalyzeBidiUTF8(testText,true);
|
||||
'2': a := AnalyzeBidiUTF8(testText);
|
||||
end;
|
||||
levelStr := '';
|
||||
for i := 0 to high(a) do
|
||||
begin
|
||||
if i > 0 then levelStr += ' ';
|
||||
if a[i].BidiInfo.IsRemoved then
|
||||
levelStr += 'x'
|
||||
else
|
||||
levelStr += inttostr(a[i].BidiInfo.BidiLevel);
|
||||
end;
|
||||
|
||||
o := GetUTF8DisplayOrder(a);
|
||||
orderStr := '';
|
||||
for i := 0 to high(o) do
|
||||
begin
|
||||
if i > 0 then orderStr += ' ';
|
||||
orderStr += inttostr(o[i]);
|
||||
end;
|
||||
|
||||
if (levelStr <> testElem[3]) or (orderStr <> testElem[4]) then
|
||||
begin
|
||||
if levelStr = testElem[3] then
|
||||
write(tOut,'Success;') else write(tOut,'Fail;');
|
||||
|
||||
writeln(tOut, testDef, ';', levelStr, ';', orderStr+';', testText);
|
||||
inc(failCount);
|
||||
end else
|
||||
inc(successCount);
|
||||
end;
|
||||
end;
|
||||
writeln(tOut, failCount, ' fail');
|
||||
writeln(tOut, successCount, ' success');
|
||||
closefile(tOut);
|
||||
|
||||
closefile(tIn);
|
||||
end.
|
||||
|
6
bgrabitmap/dev/readme.txt
Normal file
6
bgrabitmap/dev/readme.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
List of directories:
|
||||
- assistant: script to generate instructions for GPT
|
||||
- makedoc: contains a program to make documentation from source code
|
||||
- colorspace: contains a program to generate code for colorspaces
|
||||
- parseunicode: parse the data provided by unicode and test unicode algorithm
|
||||
- releaser: program to update BGRABitmap version for release
|
59
bgrabitmap/dev/releaser/archiveurl.pas
Normal file
59
bgrabitmap/dev/releaser/archiveurl.pas
Normal file
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit ArchiveUrl;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ReleaserTypes;
|
||||
|
||||
type
|
||||
|
||||
{ TArchiveUrl }
|
||||
|
||||
TArchiveUrl = class(TReleaserObject)
|
||||
private
|
||||
FUrl: string;
|
||||
public
|
||||
constructor Create(AParameters: TStringList; ALogicDir: string); override;
|
||||
class function IsUnique: boolean; override;
|
||||
function GetUrlForVersion(AVersion: TVersion): string;
|
||||
property Url: string read FUrl;
|
||||
procedure GetVersions({%H-}AVersionList: TStringList); override;
|
||||
procedure Save; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TArchiveUrl }
|
||||
|
||||
constructor TArchiveUrl.Create(AParameters: TStringList; ALogicDir: string);
|
||||
begin
|
||||
inherited Create(AParameters, ALogicDir);
|
||||
ExpectParamCount(1);
|
||||
FUrl := Param[0];
|
||||
end;
|
||||
|
||||
class function TArchiveUrl.IsUnique: boolean;
|
||||
begin
|
||||
Result:= true;
|
||||
end;
|
||||
|
||||
function TArchiveUrl.GetUrlForVersion(AVersion: TVersion): string;
|
||||
begin
|
||||
result := ReplaceVariables(FUrl, AVersion);
|
||||
end;
|
||||
|
||||
procedure TArchiveUrl.GetVersions(AVersionList: TStringList);
|
||||
begin
|
||||
//nothing
|
||||
end;
|
||||
|
||||
procedure TArchiveUrl.Save;
|
||||
begin
|
||||
//nothing
|
||||
end;
|
||||
|
||||
end.
|
||||
|
10
bgrabitmap/dev/releaser/bgrabitmap.logic
Normal file
10
bgrabitmap/dev/releaser/bgrabitmap.logic
Normal file
@@ -0,0 +1,10 @@
|
||||
cd ..\..
|
||||
manager update_BGRABitmap.json
|
||||
archive https://github.com/bgrabitmap/bgrabitmap/archive/v$(Version).zip
|
||||
cd bgrabitmap
|
||||
package bgrabitmappack.lpk
|
||||
package bgrabitmappack4fpgui.lpk
|
||||
package bgrabitmappack4nogui.lpk
|
||||
package bgrabitmappack4android.lpk
|
||||
const bgrabitmaptypes.pas BGRABitmapVersion
|
||||
|
174
bgrabitmap/dev/releaser/constfile.pas
Normal file
174
bgrabitmap/dev/releaser/constfile.pas
Normal file
@@ -0,0 +1,174 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit ConstFile;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ReleaserTypes;
|
||||
|
||||
type
|
||||
|
||||
{ TConstFile }
|
||||
|
||||
TConstFile = class(TReleaserObject)
|
||||
private
|
||||
FFilename, FConstname: String;
|
||||
FSourceCode: string;
|
||||
FChanged: boolean;
|
||||
procedure AnalyzeVersionLine(ALine: string; out AValueStart,
|
||||
AValueLength: integer);
|
||||
public
|
||||
constructor Create(AParameters: TStringList; ALogicDir: string); override;
|
||||
destructor Destroy; override;
|
||||
procedure Save; override;
|
||||
function TryVersion(out AValue: TVersion): boolean;
|
||||
procedure GetVersions(AVersionList: TStringList); override;
|
||||
procedure UpdateVersion(AVersion: TVersion); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TConstFile }
|
||||
|
||||
procedure TConstFile.AnalyzeVersionLine(ALine: string; out AValueStart, AValueLength: integer);
|
||||
var
|
||||
s: String;
|
||||
p: integer;
|
||||
begin
|
||||
AValueStart := 0;
|
||||
AValueLength:= 0;
|
||||
|
||||
s := ALine;
|
||||
p := pos(FConstname+' ',s);
|
||||
if (p<> 0) and ((p=1) or (s[p-1] in[#0..#32])) then
|
||||
begin
|
||||
inc(p, length(FConstName));
|
||||
while (p <= length(s)) and (s[p] in[#0..#32]) do inc(p);
|
||||
if (p <= length(s)) and (s[p] = '=') then
|
||||
begin
|
||||
inc(p);
|
||||
while (p <= length(s)) and (s[p] in[#0..#32]) do inc(p);
|
||||
AValueStart := p;
|
||||
while (p <= length(s)) and (s[p] in['0'..'9']) do inc(p);
|
||||
AValueLength:= p-AValueStart;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TConstFile.Create(AParameters: TStringList; ALogicDir: string);
|
||||
var
|
||||
ver: TVersion;
|
||||
str: TStringStream;
|
||||
stream: TFileStream;
|
||||
begin
|
||||
inherited Create(AParameters, ALogicDir);
|
||||
ExpectParamCount(2);
|
||||
FFilename := ExpandFileName(ReplaceVariables(Param[0]));
|
||||
FConstname := Param[1];
|
||||
stream := nil;
|
||||
str := nil;
|
||||
try
|
||||
stream := TFileStream.Create(FFilename, fmOpenRead);
|
||||
str := TStringStream.Create('');
|
||||
if str.CopyFrom(stream, stream.Size)<>stream.Size then
|
||||
raise exception.Create('Unable to read file');
|
||||
FSourceCode := str.DataString;
|
||||
finally
|
||||
str.Free;
|
||||
stream.Free;
|
||||
end;
|
||||
if TryVersion(ver) then
|
||||
writeln('Code file "',ExtractFileName(FFilename),'" version ',VersionToStr(ver))
|
||||
else
|
||||
writeln('Code file "',ExtractFileName(FFilename),'" undefined version');
|
||||
end;
|
||||
|
||||
destructor TConstFile.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TConstFile.Save;
|
||||
var
|
||||
stream: TFileStream;
|
||||
begin
|
||||
if FChanged then
|
||||
begin
|
||||
writeln('Updating code file "',ExtractFileName(FFilename),'"');
|
||||
stream := TFileStream.Create(FFilename, fmCreate);
|
||||
try
|
||||
if FSourceCode <> '' then
|
||||
stream.WriteBuffer(FSourceCode[1], length(FSourceCode));
|
||||
finally
|
||||
stream.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TConstFile.TryVersion(out AValue: TVersion): boolean;
|
||||
var
|
||||
valueStart,valueLen,errPos: integer;
|
||||
verValue: LongWord;
|
||||
begin
|
||||
AValue.Major:= 0;
|
||||
AValue.Minor:= 0;
|
||||
AValue.Release:= 0;
|
||||
AValue.Build:= 0;
|
||||
AnalyzeVersionLine(FSourceCode, valueStart, valueLen);
|
||||
if valueStart > 0 then
|
||||
begin
|
||||
val(copy(FSourceCode, valueStart, valueLen), verValue, errPos);
|
||||
if errPos = 0 then
|
||||
begin
|
||||
AValue.Major:= verValue div 1000000;
|
||||
AValue.Minor := (verValue div 10000) mod 100;
|
||||
AValue.Release := (verValue div 100) mod 100;
|
||||
AValue.Build := verValue mod 100;
|
||||
exit(true);
|
||||
end;
|
||||
end;
|
||||
result := false;
|
||||
end;
|
||||
|
||||
procedure TConstFile.GetVersions(AVersionList: TStringList);
|
||||
var
|
||||
ver: TVersion;
|
||||
verStr: String;
|
||||
begin
|
||||
if TryVersion(ver) then
|
||||
begin
|
||||
verStr := VersionToStr(ver);
|
||||
if AVersionList.IndexOf(verStr)=-1 then AVersionList.Add(verStr);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TConstFile.UpdateVersion(AVersion: TVersion);
|
||||
var
|
||||
ver: TVersion;
|
||||
newValue, valueStart, valueLength: Integer;
|
||||
s: String;
|
||||
begin
|
||||
newValue := AVersion.Major*1000000 + AVersion.Minor*10000 + AVersion.Release*100 + AVersion.Build;
|
||||
if TryVersion(ver) then
|
||||
begin
|
||||
if AVersion<>ver then
|
||||
begin
|
||||
AnalyzeVersionLine(FSourceCode, valueStart,valueLength);
|
||||
if valueStart <> 0 then
|
||||
begin
|
||||
s := FSourceCode;
|
||||
delete(s, valueStart,valueLength);
|
||||
insert(IntToStr(newValue), s,valueStart);
|
||||
FSourceCode := s;
|
||||
FChanged:= true;
|
||||
end;
|
||||
end;
|
||||
end else
|
||||
writeln('Please add manually a constant ',FConstname,' = ',newValue,' in "',ExtractFileName(FFilename),'"');
|
||||
end;
|
||||
|
||||
end.
|
||||
|
83
bgrabitmap/dev/releaser/copyfile.pas
Normal file
83
bgrabitmap/dev/releaser/copyfile.pas
Normal file
@@ -0,0 +1,83 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit CopyFile;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ReleaserTypes;
|
||||
|
||||
type
|
||||
|
||||
{ TCopyFile }
|
||||
|
||||
TCopyFile = class(TReleaserObject)
|
||||
private
|
||||
FSourceFilename, FDestFilename: String;
|
||||
FVersion: TVersion;
|
||||
FVersionDefined: boolean;
|
||||
public
|
||||
constructor Create(AParameters: TStringList; ALogicDir: string); override;
|
||||
procedure Save; override;
|
||||
procedure GetVersions({%H-}AVersionList: TStringList); override;
|
||||
procedure UpdateVersion(AVersion: TVersion); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TCopyFile }
|
||||
|
||||
constructor TCopyFile.Create(AParameters: TStringList; ALogicDir: string);
|
||||
begin
|
||||
inherited Create(AParameters, ALogicDir);
|
||||
ExpectParamCount(2);
|
||||
FSourceFilename := ExpandFileName(Param[0]);
|
||||
FDestFilename := ExpandFileName(Param[1]);
|
||||
end;
|
||||
|
||||
procedure TCopyFile.Save;
|
||||
var
|
||||
dest: String;
|
||||
streamIn,streamOut: TStream;
|
||||
buf: array of byte;
|
||||
bufCount: LongInt;
|
||||
begin
|
||||
if not FVersionDefined then exit;
|
||||
streamIn := TFileStream.Create(ReplaceVariables(FSourceFilename), fmOpenRead);
|
||||
streamOut := nil;
|
||||
buf := nil;
|
||||
try
|
||||
dest := ReplaceVariables(FDestFilename);
|
||||
if FileExists(dest) then
|
||||
writeln('Replacing file "',ExtractFilename(dest),'"');
|
||||
streamOut := TFileStream.Create(dest, fmCreate);
|
||||
setlength(buf, 4096);
|
||||
repeat
|
||||
bufCount:= streamIn.Read(buf[0], length(buf));
|
||||
streamOut.WriteBuffer(buf[0], bufCount);
|
||||
until bufCount = 0;
|
||||
finally
|
||||
buf := nil;
|
||||
streamOut.Free;
|
||||
streamIn.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCopyFile.GetVersions(AVersionList: TStringList);
|
||||
begin
|
||||
//nothing
|
||||
end;
|
||||
|
||||
procedure TCopyFile.UpdateVersion(AVersion: TVersion);
|
||||
begin
|
||||
if not FileExists(ReplaceVariables(FSourceFilename)) then
|
||||
raise exception.Create('Source file not found: '+FSourceFilename);
|
||||
if not DirectoryExists(ExtractFilePath(ReplaceVariables(FDestFilename))) then
|
||||
raise exception.Create('Target directory not found: '+ExtractFilePath(ReplaceVariables(FDestFilename)));
|
||||
FVersion := AVersion;
|
||||
FVersionDefined := true;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
208
bgrabitmap/dev/releaser/macbundle.pas
Normal file
208
bgrabitmap/dev/releaser/macbundle.pas
Normal file
@@ -0,0 +1,208 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit MacBundle;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ReleaserTypes, laz2_XMLRead, laz2_XMLWrite, Laz2_DOM;
|
||||
|
||||
type
|
||||
|
||||
{ TMacBundle }
|
||||
|
||||
TMacBundle = class(TReleaserObject)
|
||||
private
|
||||
FBundlepath: string;
|
||||
FFilename: string;
|
||||
FXml: TXmlDocument;
|
||||
FDict: TStringList;
|
||||
FChanged: boolean;
|
||||
function GetName: string;
|
||||
function GetPListFilename: string;
|
||||
function ReadDict(ARoot: TDOMNode): TStringList;
|
||||
procedure UpdateDict(ARoot: TDOMNode; ADict: TStringList);
|
||||
function GetPList: TDOMNode;
|
||||
public
|
||||
constructor Create(AParameters: TStringList; ALogicDir: string); override;
|
||||
destructor Destroy; override;
|
||||
property Filename: string read FFilename;
|
||||
function GetVersion: TVersion;
|
||||
procedure GetVersions(AVersionList: TStringList); override;
|
||||
procedure CheckVersion(AVersion: TVersion); override;
|
||||
property Name: string read GetName;
|
||||
procedure Save; override;
|
||||
procedure UpdateVersion(AVersion: TVersion); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TMacBundle }
|
||||
|
||||
function TMacBundle.GetName: string;
|
||||
begin
|
||||
result := '';
|
||||
if Assigned(FDict) then
|
||||
result := FDict.Values['CFBundleName'];
|
||||
if result = '' then
|
||||
result := ChangeFileExt(ExtractFileName(FBundlepath),'');
|
||||
end;
|
||||
|
||||
function TMacBundle.GetPListFilename: string;
|
||||
begin
|
||||
result := FBundlepath+PathDelim+'Contents'+PathDelim+'Info.plist';
|
||||
end;
|
||||
|
||||
function TMacBundle.ReadDict(ARoot: TDOMNode): TStringList;
|
||||
var
|
||||
dict, entry: TDOMNode;
|
||||
key: string;
|
||||
begin
|
||||
result := TStringList.Create;
|
||||
if Assigned(ARoot) then
|
||||
begin
|
||||
dict := ARoot.FindNode('dict');
|
||||
if Assigned(dict) then
|
||||
begin
|
||||
entry := dict.FirstChild;
|
||||
while entry <> nil do
|
||||
begin
|
||||
if entry.NodeName = 'key' then
|
||||
begin
|
||||
key := entry.TextContent;
|
||||
entry := entry.NextSibling;
|
||||
if (entry <> nil) and (entry.NodeName = 'string') then
|
||||
begin
|
||||
result.Values[key] := entry.TextContent;
|
||||
entry := entry.NextSibling;
|
||||
end
|
||||
else if (entry <> nil) and (entry.NodeName <> 'key') then
|
||||
entry := entry.NextSibling;
|
||||
end else
|
||||
entry := entry.NextSibling;
|
||||
end;
|
||||
end else
|
||||
raise exception.Create('"dict" node not found');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMacBundle.UpdateDict(ARoot: TDOMNode; ADict: TStringList);
|
||||
var
|
||||
dict, entry: TDOMNode;
|
||||
key: string;
|
||||
begin
|
||||
if Assigned(ARoot) then
|
||||
begin
|
||||
dict := ARoot.FindNode('dict');
|
||||
if Assigned(dict) then
|
||||
begin
|
||||
entry := dict.FirstChild;
|
||||
while entry <> nil do
|
||||
begin
|
||||
if entry.NodeName = 'key' then
|
||||
begin
|
||||
key := entry.TextContent;
|
||||
entry := entry.NextSibling;
|
||||
if (entry <> nil) and (entry.NodeName = 'string') then
|
||||
begin
|
||||
entry.TextContent := ADict.Values[key];
|
||||
entry := entry.NextSibling;
|
||||
end
|
||||
else if (entry <> nil) and (entry.NodeName <> 'key') then
|
||||
entry := entry.NextSibling;
|
||||
end else
|
||||
entry := entry.NextSibling;
|
||||
end;
|
||||
end else
|
||||
raise exception.Create('"dict" node not found');
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMacBundle.GetPList: TDOMNode;
|
||||
begin
|
||||
result := FXml.FirstChild;
|
||||
while (result <> nil) and not (result is TDOMElement) do result := result.NextSibling;
|
||||
if (result = nil) or (result.NodeName <> 'plist') then raise exception.Create('"plist" node not found');
|
||||
end;
|
||||
|
||||
constructor TMacBundle.Create(AParameters: TStringList; ALogicDir: string);
|
||||
var
|
||||
stream: TFileStream;
|
||||
begin
|
||||
inherited Create(AParameters, ALogicDir);
|
||||
ExpectParamCount(1);
|
||||
FBundlepath:= ExpandFileName(ReplaceVariables(Param[0]));
|
||||
stream := TFileStream.Create(GetPListFilename, fmOpenRead);
|
||||
try
|
||||
ReadXMLFile(FXml,stream);
|
||||
finally
|
||||
stream.Free;
|
||||
end;
|
||||
FDict := ReadDict(GetPList);
|
||||
writeln('Bundle ',Name,' version ',VersionToStr(GetVersion));
|
||||
end;
|
||||
|
||||
destructor TMacBundle.Destroy;
|
||||
begin
|
||||
FXml.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TMacBundle.GetVersion: TVersion;
|
||||
begin
|
||||
if Assigned(FDict) then
|
||||
result := StrToVersion(FDict.Values['CFBundleVersion'])
|
||||
else raise exception.Create('Version node not found');
|
||||
end;
|
||||
|
||||
procedure TMacBundle.GetVersions(AVersionList: TStringList);
|
||||
var
|
||||
ver: TVersion;
|
||||
verStr: String;
|
||||
begin
|
||||
ver := GetVersion;
|
||||
verStr := VersionToStr(ver);
|
||||
if AVersionList.IndexOf(verStr)=-1 then
|
||||
AVersionList.Add(verStr);
|
||||
end;
|
||||
|
||||
procedure TMacBundle.CheckVersion(AVersion: TVersion);
|
||||
begin
|
||||
inherited CheckVersion(AVersion);
|
||||
if AVersion<>GetVersion then raise exception.Create('Inconsistent version of bundle '+Name);
|
||||
end;
|
||||
|
||||
procedure TMacBundle.Save;
|
||||
begin
|
||||
if FChanged then
|
||||
begin
|
||||
writeln('Updating bundle ', Name,'...');
|
||||
WriteXMLFile(FXml, GetPListFilename);
|
||||
end else
|
||||
writeln('Bundle unchanged');
|
||||
end;
|
||||
|
||||
procedure TMacBundle.UpdateVersion(AVersion: TVersion);
|
||||
var
|
||||
versionStr: String;
|
||||
begin
|
||||
if Assigned(FDict) then
|
||||
begin
|
||||
versionStr := VersionToStr(AVersion);
|
||||
if FDict.Values['CFBundleVersion'] <> versionStr then
|
||||
begin
|
||||
FDict.Values['CFBundleVersion'] := versionStr;
|
||||
FChanged := true;
|
||||
end;
|
||||
if FDict.Values['CFBundleShortVersionString'] <> versionStr then
|
||||
begin
|
||||
FDict.Values['CFBundleShortVersionString'] := versionStr;
|
||||
FChanged := true;
|
||||
end;
|
||||
UpdateDict(GetPList, FDict);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
260
bgrabitmap/dev/releaser/managerfile.pas
Normal file
260
bgrabitmap/dev/releaser/managerfile.pas
Normal file
@@ -0,0 +1,260 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit ManagerFile;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ReleaserTypes,
|
||||
fpjson, jsonparser, ArchiveUrl, PackageFile;
|
||||
|
||||
type
|
||||
|
||||
{ TManagerFile }
|
||||
|
||||
TManagerFile = class(TReleaserObject)
|
||||
private
|
||||
FArchive: TArchiveUrl;
|
||||
FFilename: string;
|
||||
FPackages: TPackageFileList;
|
||||
FRoot: TJSONObject;
|
||||
FNew, FChanged: boolean;
|
||||
FLineEnding: string;
|
||||
procedure SetArchive(AValue: TArchiveUrl);
|
||||
function GetPackageUpdateList: TJSONArray;
|
||||
function GetDataNode: TJSONObject;
|
||||
function GetDownloadUrl: string;
|
||||
public
|
||||
constructor Create(AParameters: TStringList; ALogicDir: string); override;
|
||||
destructor Destroy; override;
|
||||
class function IsUnique: boolean; override;
|
||||
procedure LinkWith(AOtherObject: TReleaserObject); override;
|
||||
property Archive: TArchiveUrl read FArchive write SetArchive;
|
||||
procedure GetVersions({%H-}AVersionList: TStringList); override;
|
||||
procedure CheckVersion(AVersion: TVersion); override;
|
||||
procedure UpdateVersion(AVersion: TVersion); override;
|
||||
procedure Save; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TManagerFile }
|
||||
|
||||
procedure TManagerFile.SetArchive(AValue: TArchiveUrl);
|
||||
begin
|
||||
if FArchive=AValue then Exit;
|
||||
FArchive:=AValue;
|
||||
end;
|
||||
|
||||
function TManagerFile.GetPackageUpdateList: TJSONArray;
|
||||
const packagePath1 = 'UpdateLazPackages';
|
||||
packagePath2 = 'UpdatePackageFiles';
|
||||
var
|
||||
node: TJSONData;
|
||||
begin
|
||||
node := FRoot.FindPath(packagePath1);
|
||||
if node = nil then node := FRoot.FindPath(packagePath2);
|
||||
if node <> nil then result := node as TJSONArray
|
||||
else
|
||||
begin
|
||||
result := TJSONArray.Create;
|
||||
FRoot.Add(packagePath1, result);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TManagerFile.GetDataNode: TJSONObject;
|
||||
const dataPath = 'UpdatePackageData';
|
||||
var
|
||||
node: TJSONData;
|
||||
begin
|
||||
node := FRoot.FindPath(dataPath);
|
||||
if node <> nil then result := node as TJSONObject
|
||||
else
|
||||
begin
|
||||
result := TJSONObject.Create;
|
||||
FRoot.Add(dataPath, result);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TManagerFile.GetDownloadUrl: string;
|
||||
var
|
||||
url: string;
|
||||
data: TJSONObject;
|
||||
begin
|
||||
if Archive <> nil then
|
||||
begin
|
||||
data := GetDataNode;
|
||||
url := '';
|
||||
url := data.Get('DownloadZipURL', url);
|
||||
result := url;
|
||||
end
|
||||
else result := '';
|
||||
end;
|
||||
|
||||
constructor TManagerFile.Create(AParameters: TStringList; ALogicDir: string);
|
||||
var
|
||||
stream: TFileStream;
|
||||
begin
|
||||
inherited Create(AParameters, ALogicDir);
|
||||
ExpectParamCount(1);
|
||||
FFilename:= ExpandFileName(ReplaceVariables(Param[0]));
|
||||
if FileExists(FFilename) then
|
||||
begin
|
||||
FLineEnding:= DetectLineEnding(FFilename);
|
||||
FNew := false;
|
||||
stream := TFileStream.Create(FFilename, fmOpenRead);
|
||||
try
|
||||
FRoot := GetJSON(stream) as TJSONObject;
|
||||
finally
|
||||
stream.Free;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
FNew := true;
|
||||
FRoot := TJSONObject.Create;
|
||||
end;
|
||||
FPackages := TPackageFileList.Create;
|
||||
end;
|
||||
|
||||
destructor TManagerFile.Destroy;
|
||||
begin
|
||||
FPackages.Free;
|
||||
FRoot.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
class function TManagerFile.IsUnique: boolean;
|
||||
begin
|
||||
Result:= true;
|
||||
end;
|
||||
|
||||
procedure TManagerFile.LinkWith(AOtherObject: TReleaserObject);
|
||||
var
|
||||
updateList: TJSONArray;
|
||||
packageEntry: TJSONObject;
|
||||
name: String;
|
||||
i: Integer;
|
||||
updateName: string;
|
||||
package: TPackageFile;
|
||||
updateVer: TVersion;
|
||||
begin
|
||||
inherited LinkWith(AOtherObject);
|
||||
if AOtherObject is TArchiveUrl then
|
||||
Archive := TArchiveUrl(AOtherObject)
|
||||
else if AOtherObject is TPackageFile then
|
||||
begin
|
||||
package := TPackageFile(AOtherObject);
|
||||
name := ExtractFileName(package.Filename);
|
||||
updateList := GetPackageUpdateList;
|
||||
if FNew then
|
||||
begin
|
||||
packageEntry := TJSONObject.Create;
|
||||
packageEntry.Booleans['ForceNotify'] := false;
|
||||
packageEntry.Integers['InternalVersion'] := 1;
|
||||
packageEntry.Strings['Name'] := name;
|
||||
packageEntry.Strings['Version'] := VersionToStr(package.GetVersion, true);
|
||||
updateList.Add(packageEntry);
|
||||
FPackages.Add(package);
|
||||
end else
|
||||
for i := 0 to updateList.Count-1 do
|
||||
begin
|
||||
packageEntry := updateList.Items[i] as TJSONObject;
|
||||
updateName := packageEntry.Strings['Name'];
|
||||
updateVer := StrToVersion(packageEntry.Strings['Version']);
|
||||
if updateName = name then
|
||||
begin
|
||||
FPackages.Add(package);
|
||||
writeln('Package ', package.name,' is used in manager');
|
||||
if updateVer <> package.GetVersion then
|
||||
raise exception.Create('Package version specified in manager is inconsistent');
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TManagerFile.GetVersions(AVersionList: TStringList);
|
||||
begin
|
||||
//version will be provided by packages
|
||||
end;
|
||||
|
||||
procedure TManagerFile.CheckVersion(AVersion: TVersion);
|
||||
var
|
||||
url: string;
|
||||
begin
|
||||
inherited CheckVersion(AVersion);
|
||||
if Archive <> nil then
|
||||
begin
|
||||
url := GetDownloadUrl;
|
||||
if (url <> '') and (url <> Archive.GetUrlForVersion(AVersion)) then
|
||||
raise exception.Create('Archive version is not consistent (DownloadZipURL field of JSON)');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TManagerFile.UpdateVersion(AVersion: TVersion);
|
||||
var
|
||||
name, updateName, url: String;
|
||||
i, j: Integer;
|
||||
updateList: TJSONArray;
|
||||
packageEntry, data: TJSONObject;
|
||||
begin
|
||||
for i := 0 to FPackages.Count-1 do
|
||||
begin
|
||||
name := ExtractFileName(FPackages[i].Filename);
|
||||
updateList := GetPackageUpdateList;
|
||||
for j := 0 to updateList.Count-1 do
|
||||
begin
|
||||
packageEntry := updateList.Items[j] as TJSONObject;
|
||||
updateName := packageEntry.Strings['Name'];
|
||||
if updateName = name then
|
||||
begin
|
||||
packageEntry.Strings['Version'] := VersionToStr(AVersion, true);
|
||||
FChanged := true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
data := GetDataNode;
|
||||
url := Archive.GetUrlForVersion(AVersion);
|
||||
data.Strings['DownloadZipURL'] := url;
|
||||
end;
|
||||
|
||||
procedure TManagerFile.Save;
|
||||
var t: textfile;
|
||||
data: TJSONObject;
|
||||
url: String;
|
||||
begin
|
||||
if (FPackages.Count = 0) then raise exception.Create('Manager does not have an associated package');
|
||||
|
||||
data := GetDataNode;
|
||||
if FNew then
|
||||
begin
|
||||
data.Booleans['DisableInOPM'] := false;
|
||||
data.Strings['Name'] := FPackages[0].Name;
|
||||
end;
|
||||
if Assigned(Archive) then
|
||||
begin
|
||||
if GetDownloadUrl = '' then
|
||||
begin
|
||||
url := Archive.GetUrlForVersion(FPackages[0].GetVersion);
|
||||
data.Strings['DownloadZipURL'] := url;
|
||||
FChanged := true;
|
||||
end;
|
||||
end;
|
||||
|
||||
if FNew or FChanged then
|
||||
begin
|
||||
if FNew then
|
||||
writeln('Creating manager file...')
|
||||
else
|
||||
writeln('Updating manager file...');
|
||||
assignfile(t, FFilename);
|
||||
rewrite(t);
|
||||
write(t, StringReplace(FRoot.FormatJSON, LineEnding, FLineEnding, [rfReplaceAll]));
|
||||
closefile(t);
|
||||
end else
|
||||
writeln('Manager file unchanged');
|
||||
end;
|
||||
|
||||
end.
|
||||
|
177
bgrabitmap/dev/releaser/packagefile.pas
Normal file
177
bgrabitmap/dev/releaser/packagefile.pas
Normal file
@@ -0,0 +1,177 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit PackageFile;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ReleaserTypes, fgl, laz2_XMLRead, laz2_XMLWrite, Laz2_DOM;
|
||||
|
||||
type
|
||||
|
||||
{ TPackageFile }
|
||||
|
||||
TPackageFile = class(TReleaserObject)
|
||||
private
|
||||
FFilename: string;
|
||||
FLineEnding: string;
|
||||
FXml: TXmlDocument;
|
||||
FChanged: boolean;
|
||||
function GetName: string;
|
||||
public
|
||||
constructor Create(AParameters: TStringList; ALogicDir: string); override;
|
||||
destructor Destroy; override;
|
||||
property Filename: string read FFilename;
|
||||
function GetVersion: TVersion;
|
||||
procedure GetVersions(AVersionList: TStringList); override;
|
||||
procedure CheckVersion(AVersion: TVersion); override;
|
||||
property Name: string read GetName;
|
||||
procedure Save; override;
|
||||
procedure UpdateVersion(AVersion: TVersion); override;
|
||||
end;
|
||||
|
||||
TPackageFileList = specialize TFPGList<TPackageFile>;
|
||||
|
||||
implementation
|
||||
|
||||
{ TPackageFile }
|
||||
|
||||
function TPackageFile.GetName: string;
|
||||
var
|
||||
config, packageNode, nameNode: TDOMNode;
|
||||
begin
|
||||
config := FXml.FindNode('CONFIG');
|
||||
if Assigned(config) then
|
||||
begin
|
||||
packageNode := config.FindNode('Package');
|
||||
if Assigned(packageNode) then
|
||||
begin
|
||||
nameNode := packageNode.FindNode('Name');
|
||||
if Assigned(nameNode) then
|
||||
begin
|
||||
with (nameNode as TDOMElement) do
|
||||
begin
|
||||
result := GetAttribute('Value');
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
result := ChangeFileExt(ExtractFileName(FFilename),'');
|
||||
end;
|
||||
|
||||
constructor TPackageFile.Create(AParameters: TStringList; ALogicDir: string);
|
||||
var
|
||||
stream: TFileStream;
|
||||
begin
|
||||
inherited Create(AParameters, ALogicDir);
|
||||
ExpectParamCount(1);
|
||||
FFilename:= ExpandFileName(ReplaceVariables(Param[0]));
|
||||
FLineEnding:= DetectLineEnding(FFilename);
|
||||
stream := TFileStream.Create(FFilename, fmOpenRead);
|
||||
try
|
||||
ReadXMLFile(FXml,stream);
|
||||
finally
|
||||
stream.Free;
|
||||
end;
|
||||
writeln('Package ',Name,' version ',VersionToStr(GetVersion));
|
||||
end;
|
||||
|
||||
destructor TPackageFile.Destroy;
|
||||
begin
|
||||
FXml.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TPackageFile.GetVersion: TVersion;
|
||||
var
|
||||
config, packageNode, versionNode: TDOMNode;
|
||||
begin
|
||||
config := FXml.FindNode('CONFIG');
|
||||
if Assigned(config) then
|
||||
begin
|
||||
packageNode := config.FindNode('Package');
|
||||
if Assigned(packageNode) then
|
||||
begin
|
||||
versionNode := packageNode.FindNode('Version');
|
||||
if Assigned(versionNode) then
|
||||
begin
|
||||
with (versionNode as TDOMElement) do
|
||||
begin
|
||||
result.Major:= StrToIntDef(GetAttribute('Major'),0);
|
||||
result.Minor:= StrToIntDef(GetAttribute('Minor'),0);
|
||||
result.Release:= StrToIntDef(GetAttribute('Release'),0);
|
||||
result.Build:= StrToIntDef(GetAttribute('Build'),0);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
raise exception.Create('Version node not found');
|
||||
end;
|
||||
|
||||
procedure TPackageFile.GetVersions(AVersionList: TStringList);
|
||||
var
|
||||
ver: TVersion;
|
||||
verStr: String;
|
||||
begin
|
||||
ver := GetVersion;
|
||||
verStr := VersionToStr(ver);
|
||||
if AVersionList.IndexOf(verStr)=-1 then
|
||||
AVersionList.Add(verStr);
|
||||
end;
|
||||
|
||||
procedure TPackageFile.CheckVersion(AVersion: TVersion);
|
||||
begin
|
||||
inherited CheckVersion(AVersion);
|
||||
if AVersion<>GetVersion then raise exception.Create('Inconsistent version of package '+Name);
|
||||
end;
|
||||
|
||||
procedure TPackageFile.Save;
|
||||
var textStream: TStringStream;
|
||||
t: TextFile;
|
||||
begin
|
||||
if FChanged then
|
||||
begin
|
||||
writeln('Updating package ', Name,'...');
|
||||
textStream := TStringStream.Create;
|
||||
WriteXMLFile(FXml, textStream);
|
||||
AssignFile(t, FFilename);
|
||||
Rewrite(t);
|
||||
Write(t, StringReplace(textStream.DataString, LineEnding, FLineEnding, [rfReplaceAll]));
|
||||
CloseFile(t);
|
||||
textStream.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPackageFile.UpdateVersion(AVersion: TVersion);
|
||||
var
|
||||
config, packageNode, versionNode: TDOMNode;
|
||||
begin
|
||||
config := FXml.FindNode('CONFIG');
|
||||
if Assigned(config) then
|
||||
begin
|
||||
packageNode := config.FindNode('Package');
|
||||
if Assigned(packageNode) then
|
||||
begin
|
||||
versionNode := packageNode.FindNode('Version');
|
||||
if Assigned(versionNode) then
|
||||
begin
|
||||
with (versionNode as TDOMElement) do
|
||||
begin
|
||||
FChanged := true;
|
||||
SetAttribute('Major', inttostr(AVersion.Major));
|
||||
if AVersion.Minor <> 0 then SetAttribute('Minor', inttostr(AVersion.Minor)) else RemoveAttribute('Minor');
|
||||
if AVersion.Release <> 0 then SetAttribute('Release', inttostr(AVersion.Release)) else RemoveAttribute('Release');
|
||||
if AVersion.Build <> 0 then SetAttribute('Build', inttostr(AVersion.Build)) else RemoveAttribute('Build');
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
raise exception.Create('Version node not found');
|
||||
end;
|
||||
|
||||
end.
|
||||
|
200
bgrabitmap/dev/releaser/projectfile.pas
Normal file
200
bgrabitmap/dev/releaser/projectfile.pas
Normal file
@@ -0,0 +1,200 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit ProjectFile;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ReleaserTypes, laz2_XMLRead, laz2_XMLWrite, Laz2_DOM;
|
||||
|
||||
type
|
||||
|
||||
{ TProjectFile }
|
||||
|
||||
TProjectFile = class(TReleaserObject)
|
||||
private
|
||||
FFilename: string;
|
||||
FXml: TXmlDocument;
|
||||
FChanged: boolean;
|
||||
function GetName: string;
|
||||
public
|
||||
constructor Create(AParameters: TStringList; ALogicDir: string); override;
|
||||
destructor Destroy; override;
|
||||
property Filename: string read FFilename;
|
||||
function GetVersion: TVersion;
|
||||
procedure GetVersions(AVersionList: TStringList); override;
|
||||
procedure CheckVersion(AVersion: TVersion); override;
|
||||
property Name: string read GetName;
|
||||
procedure Save; override;
|
||||
procedure UpdateVersion(AVersion: TVersion); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TProjectFile }
|
||||
|
||||
function TProjectFile.GetName: string;
|
||||
var
|
||||
config, projectNode, titleNode, generalNode: TDOMNode;
|
||||
begin
|
||||
config := FXml.FindNode('CONFIG');
|
||||
if Assigned(config) then
|
||||
begin
|
||||
projectNode := config.FindNode('ProjectOptions');
|
||||
if Assigned(projectNode) then
|
||||
begin
|
||||
generalNode := projectNode.FindNode('General');
|
||||
if Assigned(generalNode) then
|
||||
begin
|
||||
titleNode := generalNode.FindNode('Title');
|
||||
if Assigned(titleNode) then
|
||||
begin
|
||||
with (titleNode as TDOMElement) do
|
||||
begin
|
||||
result := GetAttribute('Value');
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
result := ChangeFileExt(ExtractFileName(FFilename),'');
|
||||
end;
|
||||
|
||||
constructor TProjectFile.Create(AParameters: TStringList; ALogicDir: string);
|
||||
var
|
||||
stream: TFileStream;
|
||||
begin
|
||||
inherited Create(AParameters, ALogicDir);
|
||||
ExpectParamCount(1);
|
||||
FFilename:= ExpandFileName(ReplaceVariables(Param[0]));
|
||||
stream := TFileStream.Create(FFilename, fmOpenRead);
|
||||
try
|
||||
ReadXMLFile(FXml,stream);
|
||||
finally
|
||||
stream.Free;
|
||||
end;
|
||||
writeln('Project ',Name,' version ',VersionToStr(GetVersion));
|
||||
end;
|
||||
|
||||
destructor TProjectFile.Destroy;
|
||||
begin
|
||||
FXml.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TProjectFile.GetVersion: TVersion;
|
||||
var
|
||||
config, projectNode, versionNode: TDOMNode;
|
||||
|
||||
function GetSubNode(ATag: string): integer;
|
||||
var
|
||||
subNode: TDOMNode;
|
||||
begin
|
||||
subNode := versionNode.FindNode(ATag);
|
||||
if Assigned(subNode) then with (subNode as TDOMElement) do
|
||||
result:= StrToIntDef(GetAttribute('Value'),0)
|
||||
else
|
||||
result:= 0;
|
||||
end;
|
||||
|
||||
begin
|
||||
config := FXml.FindNode('CONFIG');
|
||||
if Assigned(config) then
|
||||
begin
|
||||
projectNode := config.FindNode('ProjectOptions');
|
||||
if Assigned(projectNode) then
|
||||
begin
|
||||
versionNode := projectNode.FindNode('VersionInfo');
|
||||
if Assigned(versionNode) then
|
||||
begin
|
||||
result.Major:= GetSubNode('MajorVersionNr');
|
||||
result.Minor:= GetSubNode('MinorVersionNr');
|
||||
result.Release:= GetSubNode('RevisionNr');
|
||||
result.Build:= GetSubNode('BuildNr');
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
raise exception.Create('Version node not found');
|
||||
end;
|
||||
|
||||
procedure TProjectFile.GetVersions(AVersionList: TStringList);
|
||||
var
|
||||
ver: TVersion;
|
||||
verStr: String;
|
||||
begin
|
||||
ver := GetVersion;
|
||||
verStr := VersionToStr(ver);
|
||||
if AVersionList.IndexOf(verStr)=-1 then
|
||||
AVersionList.Add(verStr);
|
||||
end;
|
||||
|
||||
procedure TProjectFile.CheckVersion(AVersion: TVersion);
|
||||
begin
|
||||
inherited CheckVersion(AVersion);
|
||||
if AVersion<>GetVersion then raise exception.Create('Inconsistent version of project '+Name);
|
||||
end;
|
||||
|
||||
procedure TProjectFile.Save;
|
||||
begin
|
||||
if FChanged then
|
||||
begin
|
||||
writeln('Updating project ', Name,'...');
|
||||
WriteXMLFile(FXml, FFilename);
|
||||
end else
|
||||
writeln('Project file unchanged');
|
||||
end;
|
||||
|
||||
procedure TProjectFile.UpdateVersion(AVersion: TVersion);
|
||||
var
|
||||
config, projectNode, versionNode: TDOMNode;
|
||||
|
||||
procedure UpdateSubNode(ATag: string; AValue: integer);
|
||||
var
|
||||
subNode: TDOMElement;
|
||||
begin
|
||||
subNode := versionNode.FindNode(ATag) as TDOMElement;
|
||||
if AValue<>0 then
|
||||
begin
|
||||
if subNode=nil then
|
||||
begin
|
||||
subNode := FXml.CreateElement(ATag);
|
||||
versionNode.AppendChild(subNode);
|
||||
end;
|
||||
subNode.SetAttribute('Value', inttostr(AValue));
|
||||
end else
|
||||
begin
|
||||
if Assigned(subNode) then
|
||||
begin
|
||||
versionNode.RemoveChild(subNode);
|
||||
subNode.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
config := FXml.FindNode('CONFIG');
|
||||
if Assigned(config) then
|
||||
begin
|
||||
projectNode := config.FindNode('ProjectOptions');
|
||||
if Assigned(projectNode) then
|
||||
begin
|
||||
versionNode := projectNode.FindNode('VersionInfo');
|
||||
if Assigned(versionNode) then
|
||||
begin
|
||||
FChanged := true;
|
||||
UpdateSubNode('MajorVersionNr', AVersion.Major);
|
||||
UpdateSubNode('MinorVersionNr', AVersion.Minor);
|
||||
UpdateSubNode('RevisionNr', AVersion.Release);
|
||||
UpdateSubNode('BuildNr', AVersion.Build);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
raise exception.Create('Version node not found');
|
||||
end;
|
||||
|
||||
end.
|
||||
|
116
bgrabitmap/dev/releaser/releaser.lpi
Normal file
116
bgrabitmap/dev/releaser/releaser.lpi
Normal file
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
<CompatibilityMode Value="True"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="Releaser"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<BuildModes Count="1">
|
||||
<Item1 Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<UseFileFilters Value="True"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="1">
|
||||
<Item1>
|
||||
<PackageName Value="LazUtils"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="11">
|
||||
<Unit0>
|
||||
<Filename Value="releaser.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="Releaser"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="bgrabitmap.logic"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="releasertypes.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ReleaserTypes"/>
|
||||
</Unit2>
|
||||
<Unit3>
|
||||
<Filename Value="managerfile.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ManagerFile"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="archiveurl.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ArchiveUrl"/>
|
||||
</Unit4>
|
||||
<Unit5>
|
||||
<Filename Value="packagefile.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="PackageFile"/>
|
||||
</Unit5>
|
||||
<Unit6>
|
||||
<Filename Value="constfile.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ConstFile"/>
|
||||
</Unit6>
|
||||
<Unit7>
|
||||
<Filename Value="projectfile.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ProjectFile"/>
|
||||
</Unit7>
|
||||
<Unit8>
|
||||
<Filename Value="textline.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="TextLine"/>
|
||||
</Unit8>
|
||||
<Unit9>
|
||||
<Filename Value="copyfile.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="CopyFile"/>
|
||||
</Unit9>
|
||||
<Unit10>
|
||||
<Filename Value="macbundle.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="MacBundle"/>
|
||||
</Unit10>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target>
|
||||
<Filename Value="releaser"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf2Set"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="3">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
325
bgrabitmap/dev/releaser/releaser.lpr
Normal file
325
bgrabitmap/dev/releaser/releaser.lpr
Normal file
@@ -0,0 +1,325 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-only (modified to allow linking)
|
||||
program Releaser;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||
cthreads,
|
||||
{$ENDIF}{$ENDIF}
|
||||
Classes, SysUtils, CustApp, ReleaserTypes, ManagerFile, ArchiveUrl,
|
||||
PackageFile, ProjectFile, ConstFile, TextLine, CopyFile, MacBundle
|
||||
{ you can add units after this };
|
||||
|
||||
type
|
||||
|
||||
{ TReleaserApp }
|
||||
|
||||
TReleaserApp = class(TCustomApplication)
|
||||
protected
|
||||
procedure DoRun; override;
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
procedure ProcessFile(AFilename: string; AOptions: TStringList);
|
||||
destructor Destroy; override;
|
||||
procedure WriteHelp; virtual;
|
||||
end;
|
||||
|
||||
TIfState = (isNone, isSkipTrue, isDoTrue, isSkipFalse, isDoFalse);
|
||||
|
||||
{ TReleaserApp }
|
||||
|
||||
procedure TReleaserApp.DoRun;
|
||||
var
|
||||
ErrorMsg, dir: String;
|
||||
opts, logicFiles: TStringList;
|
||||
i: Integer;
|
||||
findRec: TRawByteSearchRec;
|
||||
begin
|
||||
// quick check parameters
|
||||
opts := TStringList.Create;
|
||||
logicFiles := TStringList.Create;
|
||||
ErrorMsg:=CheckOptions('hv', ['help','version:'], opts, logicFiles);
|
||||
if ErrorMsg<>'' then begin
|
||||
writeln(ErrorMsg);
|
||||
Terminate;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
// parse parameters
|
||||
if HasOption('h', 'help') then begin
|
||||
WriteHelp;
|
||||
Terminate;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if logicFiles.Count = 0 then
|
||||
begin
|
||||
if FindFirst('*.logic', faAnyFile, findRec)=0 then
|
||||
repeat
|
||||
if (findRec.Attr and faDirectory)=0 then logicFiles.Add(ExpandFileName(findRec.Name));
|
||||
until FindNext(findRec)<>0;
|
||||
FindClose(findRec);
|
||||
end;
|
||||
|
||||
dir := GetCurrentDir;
|
||||
for i := 0 to logicFiles.Count-1 do
|
||||
begin
|
||||
SetCurrentDir(dir);
|
||||
ProcessFile(logicFiles[i], opts);
|
||||
end;
|
||||
|
||||
opts.Free;
|
||||
logicFiles.Free;
|
||||
|
||||
// stop program loop
|
||||
Terminate;
|
||||
end;
|
||||
|
||||
constructor TReleaserApp.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
StopOnException:=True;
|
||||
end;
|
||||
|
||||
procedure TReleaserApp.ProcessFile(AFilename: string;
|
||||
AOptions: TStringList);
|
||||
var
|
||||
objs: TReleaserObjectList;
|
||||
|
||||
function GetVersion: TVersion;
|
||||
var versions: TStringList;
|
||||
i: integer;
|
||||
begin
|
||||
versions := TStringList.Create;
|
||||
try
|
||||
for i := 0 to objs.Count-1 do
|
||||
objs[i].GetVersions(versions);
|
||||
if versions.Count = 0 then raise exception.Create('Version not found')
|
||||
else if versions.Count > 1 then writeln('Multiple versions found!');
|
||||
result := StrToVersion(versions[0]);
|
||||
finally
|
||||
versions.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
t: textfile;
|
||||
s, cmd: string;
|
||||
ver, newVer: TVersion;
|
||||
line: TStringList;
|
||||
factory: TReleaserObjectFactory;
|
||||
i, lineNumber, j: Integer;
|
||||
newVerStr, logicDir, newDir: string;
|
||||
ifStack: array of TIfState;
|
||||
skipCommand: boolean;
|
||||
|
||||
function PeekIfStack: TIfState;
|
||||
begin
|
||||
if ifStack = nil then
|
||||
result := isNone
|
||||
else result := ifStack[high(ifStack)];
|
||||
end;
|
||||
|
||||
procedure PokeIfStack(AValue: TIfState);
|
||||
begin
|
||||
if ifStack <> nil then
|
||||
ifStack[high(ifStack)] := AValue;
|
||||
end;
|
||||
|
||||
procedure PopIfStack;
|
||||
begin
|
||||
if ifStack <> nil then
|
||||
setlength(ifStack, length(ifStack)-1);
|
||||
end;
|
||||
|
||||
procedure PushIfStack(AValue: TIfState);
|
||||
begin
|
||||
setlength(ifStack, length(ifStack)+1);
|
||||
ifStack[high(ifStack)] := AValue;
|
||||
end;
|
||||
|
||||
begin
|
||||
AFilename := ExpandFileName(AFilename);
|
||||
writeln('Logic file "', AFilename,'"');
|
||||
assignfile(t, AFilename);
|
||||
reset(t);
|
||||
line := TStringList.Create;
|
||||
objs := TReleaserObjectList.Create;
|
||||
lineNumber := 0;
|
||||
ifStack := nil;
|
||||
try
|
||||
while not eof(t) do
|
||||
begin
|
||||
inc(lineNumber);
|
||||
readln(t, s);
|
||||
line.CommaText:= trim(s);
|
||||
if line.Count > 0 then
|
||||
begin
|
||||
cmd := line[0];
|
||||
line.Delete(0);
|
||||
|
||||
skipCommand := false;
|
||||
if (cmd = 'end') and (PeekIfStack <> isNone) then
|
||||
begin
|
||||
PopIfStack;
|
||||
skipCommand:= true;
|
||||
end;
|
||||
if (cmd = 'else') and (PeekIfStack in[isDoTrue,isSkipTrue]) then
|
||||
begin
|
||||
if PeekIfStack = isDoTrue then
|
||||
PokeIfStack(isSkipFalse)
|
||||
else PokeIfStack(isDoFalse);
|
||||
skipCommand:= true;
|
||||
end;
|
||||
|
||||
if not skipCommand and (PeekIfStack in[isSkipTrue,isSkipFalse]) then
|
||||
skipCommand:= true;
|
||||
factory := nil;
|
||||
if not skipCommand then
|
||||
case LowerCase(cmd) of
|
||||
'cd': begin
|
||||
if line.Count <> 1 then raise exception.Create('Expecting directory');
|
||||
logicDir := ExtractFilePath(AFilename);
|
||||
delete(logicDir, length(logicDir), 1);
|
||||
newDir := StringReplace(AdaptPathDelim(line[0]),'($LogicDir)',logicDir,[rfReplaceAll]);
|
||||
SetCurrentDir(newDir);
|
||||
end;
|
||||
'manager': factory := TManagerFile;
|
||||
'archive': factory := TArchiveUrl;
|
||||
'package': factory := TPackageFile;
|
||||
'project': factory := TProjectFile;
|
||||
'bundle': factory := TMacBundle;
|
||||
'const': factory := TConstFile;
|
||||
'echo': for i := 0 to line.Count-1 do writeln(line[i]);
|
||||
'text': factory := TTextLine;
|
||||
'copy': factory := TCopyFile;
|
||||
'if': begin
|
||||
if line.Count = 0 then
|
||||
raise exception.Create('Expecting condition');
|
||||
if line[0] = 'exists' then
|
||||
begin
|
||||
if line.Count <> 2 then
|
||||
raise exception.Create('Expecting 1 parameter');
|
||||
if FileExists(line[1]) or DirectoryExists(line[1]) then
|
||||
PushIfStack(isDoTrue)
|
||||
else PushIfStack(isSkipTrue);
|
||||
end else
|
||||
raise exception.Create('Unknown condition "'+line[0]);
|
||||
|
||||
end;
|
||||
'else', 'end': raise exception.Create('Unexpected branching "'+cmd+'"');
|
||||
else
|
||||
raise exception.Create('Unknown command "'+cmd+'"');
|
||||
end;
|
||||
if Assigned(factory) then
|
||||
begin
|
||||
if factory.IsUnique then
|
||||
begin
|
||||
for i := 0 to objs.Count-1 do
|
||||
if objs[i] is factory then
|
||||
raise exception.Create('Unicity constraint not satisfied for '+factory.ClassName);
|
||||
end;
|
||||
objs.Add(factory.Create(line, logicDir));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
lineNumber := 0;
|
||||
for i := 0 to objs.Count-1 do
|
||||
for j := 0 to objs.Count-1 do
|
||||
objs[i].LinkWith(objs[j]);
|
||||
|
||||
ver := GetVersion;
|
||||
for i := 0 to objs.Count-1 do
|
||||
objs[i].CheckVersion(ver);
|
||||
|
||||
writeln('Current version: ',VersionToStr(ver));
|
||||
newVerStr := '';
|
||||
for i := 0 to AOptions.Count-1 do
|
||||
if AOptions[i].StartsWith('version=') then
|
||||
begin
|
||||
newVerStr := copy(AOptions[i], length('version=')+1, length(AOptions[i])-length('version='));
|
||||
break;
|
||||
end;
|
||||
if newVerStr = '' then
|
||||
begin
|
||||
write('New version (press Enter to keep the same): ');
|
||||
readln(newVerStr);
|
||||
end else
|
||||
writeln('New version: ', newVerStr);
|
||||
|
||||
if Trim(newVerStr)='' then newVer := ver
|
||||
else newVer := StrToVersion(newVerStr);
|
||||
|
||||
if newVer <> ver then
|
||||
begin
|
||||
for i := 0 to objs.Count-1 do
|
||||
objs[i].UpdateVersion(newVer);
|
||||
end else
|
||||
begin
|
||||
for i := 0 to objs.Count-1 do
|
||||
if (objs[i] is TConstFile) or (objs[i] is TCopyFile) then //constants and copied files are loosely checked
|
||||
objs[i].UpdateVersion(newVer);
|
||||
end;
|
||||
|
||||
for i := 0 to objs.Count-1 do
|
||||
objs[i].Save;
|
||||
writeln('Done.');
|
||||
except
|
||||
on ex:exception do
|
||||
begin
|
||||
write('Error');
|
||||
if lineNumber <> 0 then write(' on line ',lineNumber);
|
||||
writeln(': ', ex.Message);
|
||||
end;
|
||||
end;
|
||||
objs.Free;
|
||||
line.Free;
|
||||
closefile(t);
|
||||
end;
|
||||
|
||||
destructor TReleaserApp.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TReleaserApp.WriteHelp;
|
||||
begin
|
||||
{ add your help code here }
|
||||
writeln('Update version number and check its consistence.');
|
||||
writeln;
|
||||
writeln('Usage: ', ExeName, ' [logicfile1 logicfile2...] [--version=versionNb] [--help]');
|
||||
writeln;
|
||||
writeln(' Parameter Description');
|
||||
writeln(' --------- ----------------------------------------------------------------');
|
||||
writeln(' versionNb New version number to assign to manager and packages');
|
||||
writeln;
|
||||
writeln(' logicfile File containing the location of the version number. If it is not');
|
||||
writeln(' specified, all logic files in current directory are processed.');
|
||||
writeln;
|
||||
writeln(' Sample file: mylib.logic');
|
||||
writeln(' ----------------------------------------------------------------');
|
||||
writeln(' cd /mylib');
|
||||
writeln(' manager update_mylib.json');
|
||||
writeln(' archive https://github.com/mylib/mylib/archive/v$(Version).zip');
|
||||
writeln(' package mylib/mylibpack1.lpk');
|
||||
writeln(' package mylib/mylibpack2.lpk');
|
||||
writeln(' const mylib/mylibtypes.pas MyLibVersion');
|
||||
writeln;
|
||||
writeln(' Sample file: myprog.logic');
|
||||
writeln(' ----------------------------------------------------------------');
|
||||
writeln(' cd ($LogicDir)');
|
||||
writeln(' project myproject.lpi');
|
||||
writeln(' const myconsts.pas MyProjectVersion');
|
||||
writeln;
|
||||
end;
|
||||
|
||||
var
|
||||
Application: TReleaserApp;
|
||||
begin
|
||||
Application:=TReleaserApp.Create(nil);
|
||||
Application.Title:='Releaser';
|
||||
Application.Run;
|
||||
Application.Free;
|
||||
end.
|
||||
|
199
bgrabitmap/dev/releaser/releasertypes.pas
Normal file
199
bgrabitmap/dev/releaser/releasertypes.pas
Normal file
@@ -0,0 +1,199 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit ReleaserTypes;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, fgl;
|
||||
|
||||
type
|
||||
TVersion = record
|
||||
case boolean of
|
||||
false: (Value: array[1..4] of integer);
|
||||
true: (Major, Minor, Release, Build: integer);
|
||||
end;
|
||||
|
||||
operator =(AVersion1,AVersion2: TVersion): boolean;
|
||||
function VersionToStr(AVersion: TVersion; AAlwaysIncludeZero: boolean = false): string;
|
||||
function StrToVersion(AStr: string): TVersion;
|
||||
|
||||
type
|
||||
{ TReleaserObject }
|
||||
|
||||
TReleaserObject = class
|
||||
private
|
||||
function GetParam(AIndex: integer): string;
|
||||
function GetParamCount: integer;
|
||||
protected
|
||||
FLogicDir: string;
|
||||
function ReplaceVariables(AText: string; AVersion: TVersion): string; overload;
|
||||
function ReplaceVariables(AText: string): string; overload;
|
||||
public
|
||||
FParameters: TStringList;
|
||||
constructor Create(AParameters: TStringList; ALogicDir: string); virtual;
|
||||
procedure ExpectParamCount(ACount: integer);
|
||||
destructor Destroy; override;
|
||||
property ParamCount: integer read GetParamCount;
|
||||
property Param[AIndex: integer]: string read GetParam;
|
||||
class function IsUnique: boolean; virtual;
|
||||
procedure LinkWith({%H-}AOtherObject: TReleaserObject); virtual;
|
||||
procedure GetVersions(AVersionList: TStringList); virtual; abstract;
|
||||
procedure CheckVersion({%H-}AVersion: TVersion); virtual;
|
||||
procedure UpdateVersion({%H-}AVersion: TVersion); virtual;
|
||||
procedure Save; virtual; abstract;
|
||||
end;
|
||||
|
||||
TReleaserObjectFactory = class of TReleaserObject;
|
||||
|
||||
TReleaserObjectList = specialize TFPGObjectList<TReleaserObject>;
|
||||
|
||||
function AdaptPathDelim(APath: string): string;
|
||||
function DetectLineEnding(AFilename: string): string;
|
||||
|
||||
implementation
|
||||
|
||||
operator=(AVersion1, AVersion2: TVersion): boolean;
|
||||
begin
|
||||
result := (AVersion1.Major = AVersion2.Major) and
|
||||
(AVersion1.Minor = AVersion2.Minor) and
|
||||
(AVersion1.Release = AVersion2.Release) and
|
||||
(AVersion1.Build = AVersion2.Build);
|
||||
end;
|
||||
|
||||
function VersionToStr(AVersion: TVersion; AAlwaysIncludeZero: boolean): string;
|
||||
begin
|
||||
result := IntToStr(AVersion.Major);
|
||||
if AAlwaysIncludeZero or (AVersion.Minor<>0) or (AVersion.Release<>0) or (AVersion.Build<>0) then
|
||||
begin
|
||||
result += '.' + IntToStr(AVersion.Minor);
|
||||
if AAlwaysIncludeZero or (AVersion.Release<>0) or (AVersion.Build<>0) then
|
||||
begin
|
||||
result += '.' + IntToStr(AVersion.Release);
|
||||
if AAlwaysIncludeZero or (AVersion.Build<>0) then
|
||||
begin
|
||||
result += '.' + IntToStr(AVersion.Build);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function StrToVersion(AStr: string): TVersion;
|
||||
var
|
||||
lst: TStringList;
|
||||
i: Integer;
|
||||
begin
|
||||
lst := TStringList.Create;
|
||||
lst.Delimiter:= '.';
|
||||
lst.DelimitedText := AStr;
|
||||
if lst.Count > 4 then
|
||||
begin
|
||||
lst.Free;
|
||||
raise exception.Create('Invalid version string');
|
||||
end;
|
||||
for i := 1 to 4 do result.Value[i] := 0;
|
||||
for i := 1 to lst.Count do
|
||||
result.Value[i] := StrToInt(lst[i-1]);
|
||||
lst.Free;
|
||||
end;
|
||||
|
||||
function AdaptPathDelim(APath: string): string;
|
||||
begin
|
||||
if PathDelim <> '\' then
|
||||
result := StringReplace(APath, '\', PathDelim, [rfReplaceAll]);
|
||||
if PathDelim <> '/' then
|
||||
result := StringReplace(APath, '/', PathDelim, [rfReplaceAll]);
|
||||
end;
|
||||
|
||||
function DetectLineEnding(AFilename: string): string;
|
||||
var t: TextFile;
|
||||
c, c2: char;
|
||||
begin
|
||||
result := LineEnding;
|
||||
AssignFile(t, AFilename);
|
||||
Reset(t);
|
||||
repeat
|
||||
read(t, c);
|
||||
if c in[#13,#10] then
|
||||
begin
|
||||
result := c;
|
||||
if not eof(t) then
|
||||
begin
|
||||
read(t, c2);
|
||||
if (c2 in [#13,#10]) and (c2 <> c) then
|
||||
result += c2;
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
until eof(t);
|
||||
CloseFile(t);
|
||||
end;
|
||||
|
||||
{ TReleaserObject }
|
||||
|
||||
function TReleaserObject.GetParam(AIndex: integer): string;
|
||||
begin
|
||||
result := FParameters[AIndex];
|
||||
end;
|
||||
|
||||
function TReleaserObject.GetParamCount: integer;
|
||||
begin
|
||||
result := FParameters.Count;
|
||||
end;
|
||||
|
||||
function TReleaserObject.ReplaceVariables(AText: string; AVersion: TVersion): string;
|
||||
begin
|
||||
result := AText;
|
||||
result := StringReplace(result, '$(Version)', VersionToStr(AVersion), [rfIgnoreCase,rfReplaceAll]);
|
||||
result := StringReplace(result, '$(LogicDir)', FLogicDir, [rfIgnoreCase,rfReplaceAll]);
|
||||
end;
|
||||
|
||||
function TReleaserObject.ReplaceVariables(AText: string): string;
|
||||
begin
|
||||
result := AText;
|
||||
result := StringReplace(result, '$(Version)', '?', [rfIgnoreCase,rfReplaceAll]);
|
||||
result := StringReplace(result, '$(LogicDir)', FLogicDir, [rfIgnoreCase,rfReplaceAll]);
|
||||
end;
|
||||
|
||||
constructor TReleaserObject.Create(AParameters: TStringList; ALogicDir: string);
|
||||
begin
|
||||
FParameters := TStringList.Create;
|
||||
FParameters.AddStrings(AParameters);
|
||||
FLogicDir := ALogicDir;
|
||||
end;
|
||||
|
||||
procedure TReleaserObject.ExpectParamCount(ACount: integer);
|
||||
begin
|
||||
if ACount <> ParamCount then
|
||||
raise exception.Create('Invalid number of parameters. Found '+inttostr(ParamCount)+' but expected '+inttostr(ACount));
|
||||
end;
|
||||
|
||||
destructor TReleaserObject.Destroy;
|
||||
begin
|
||||
FParameters.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
class function TReleaserObject.IsUnique: boolean;
|
||||
begin
|
||||
result := false;
|
||||
end;
|
||||
|
||||
procedure TReleaserObject.LinkWith(AOtherObject: TReleaserObject);
|
||||
begin
|
||||
//nothing
|
||||
end;
|
||||
|
||||
procedure TReleaserObject.CheckVersion(AVersion: TVersion);
|
||||
begin
|
||||
//nothing
|
||||
end;
|
||||
|
||||
procedure TReleaserObject.UpdateVersion(AVersion: TVersion);
|
||||
begin
|
||||
//nothing
|
||||
end;
|
||||
|
||||
end.
|
||||
|
150
bgrabitmap/dev/releaser/textline.pas
Normal file
150
bgrabitmap/dev/releaser/textline.pas
Normal file
@@ -0,0 +1,150 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
||||
unit TextLine;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ReleaserTypes;
|
||||
|
||||
type
|
||||
|
||||
{ TTextLine }
|
||||
|
||||
TTextLine = class(TReleaserObject)
|
||||
private
|
||||
FFilename, FTextLine: String;
|
||||
FTextLineStart, FTextLineEnd: integer;
|
||||
FVersion: TVersion;
|
||||
FText: string;
|
||||
FChanged: boolean;
|
||||
public
|
||||
constructor Create(AParameters: TStringList; ALogicDir: string); override;
|
||||
destructor Destroy; override;
|
||||
procedure Save; override;
|
||||
function GetLineForVersion(AVersion: TVersion): string;
|
||||
procedure GetVersions({%H-}AVersionList: TStringList); override;
|
||||
procedure CheckVersion(AVersion: TVersion); override;
|
||||
procedure UpdateVersion(AVersion: TVersion); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TTextLine }
|
||||
|
||||
constructor TTextLine.Create(AParameters: TStringList; ALogicDir: string);
|
||||
var
|
||||
str: TStringStream;
|
||||
stream: TFileStream;
|
||||
begin
|
||||
inherited Create(AParameters, ALogicDir);
|
||||
ExpectParamCount(2);
|
||||
FFilename := ExpandFileName(ReplaceVariables(Param[0]));
|
||||
FTextLine := Param[1];
|
||||
FTextLineStart:= 0;
|
||||
FTextLineEnd:= 0;
|
||||
stream := nil;
|
||||
str := nil;
|
||||
try
|
||||
stream := TFileStream.Create(FFilename, fmOpenRead);
|
||||
str := TStringStream.Create('');
|
||||
if str.CopyFrom(stream, stream.Size)<>stream.Size then
|
||||
raise exception.Create('Unable to read file');
|
||||
FText := str.DataString;
|
||||
finally
|
||||
str.Free;
|
||||
stream.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TTextLine.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TTextLine.Save;
|
||||
var
|
||||
stream: TFileStream;
|
||||
begin
|
||||
if FChanged then
|
||||
begin
|
||||
writeln('Updating text file "',ExtractFileName(FFilename),'"');
|
||||
stream := TFileStream.Create(FFilename, fmCreate);
|
||||
try
|
||||
if FText <> '' then
|
||||
stream.WriteBuffer(FText[1], length(FText));
|
||||
finally
|
||||
stream.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TTextLine.GetLineForVersion(AVersion: TVersion): string;
|
||||
begin
|
||||
result := ReplaceVariables(FTextLine, AVersion);
|
||||
end;
|
||||
|
||||
procedure TTextLine.GetVersions(AVersionList: TStringList);
|
||||
begin
|
||||
//nothing
|
||||
end;
|
||||
|
||||
procedure TTextLine.CheckVersion(AVersion: TVersion);
|
||||
var
|
||||
i, start: Integer;
|
||||
expectLine: string;
|
||||
|
||||
procedure TryLine(AEnd: integer);
|
||||
var
|
||||
curLine: String;
|
||||
begin
|
||||
if AEnd > start then
|
||||
begin
|
||||
curLine := copy(FText, start, AEnd-start);
|
||||
if curLine = expectLine then
|
||||
begin
|
||||
FTextLineStart:= start;
|
||||
FTextLineEnd:= AEnd;
|
||||
FVersion := AVersion;
|
||||
end;
|
||||
end;
|
||||
start := AEnd+1;
|
||||
end;
|
||||
|
||||
begin
|
||||
inherited CheckVersion(AVersion);
|
||||
if FTextLineEnd > FTextLineStart then exit;
|
||||
expectLine := GetLineForVersion(AVersion);
|
||||
i := 1;
|
||||
start := 1;
|
||||
while (i < length(FText)) and (FTextLineEnd <= FTextLineStart) do
|
||||
begin
|
||||
if FText[i] in[#13,#10] then TryLine(i);
|
||||
inc(i);
|
||||
end;
|
||||
if (FTextLineEnd <= FTextLineStart) then TryLine(i);
|
||||
if FTextLineEnd > FTextLineStart then
|
||||
writeln('Text file "',ExtractFileName(FFilename),'" line found')
|
||||
else
|
||||
writeln('Text file "',ExtractFileName(FFilename),'" line not found');
|
||||
end;
|
||||
|
||||
procedure TTextLine.UpdateVersion(AVersion: TVersion);
|
||||
var
|
||||
newLine: String;
|
||||
begin
|
||||
if AVersion = FVersion then exit;
|
||||
newLine := GetLineForVersion(AVersion);
|
||||
if FTextLineEnd > FTextLineStart then
|
||||
begin
|
||||
delete(FText, FTextLineStart, FTextLineEnd-FTextLineStart);
|
||||
insert(newLine, FText, FTextLineStart);
|
||||
FTextLineEnd:= FTextLineStart+length(newLine);
|
||||
FChanged:= true;
|
||||
end else
|
||||
writeln('Please add manually a line "',newLine,'" in "',ExtractFileName(FFilename),'"');
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Reference in New Issue
Block a user