API REFERENCE
=============
Complete public API for Lingenic-Text, organized by module.
All types and subprograms are listed with their contracts.
================================================================================
LINGENIC_TEXT (Root Package)
================================================================================
Types:
subtype Codepoint is Natural range 0 .. 16#10_FFFF#;
Full Unicode codespace (0 to 1,114,111).
subtype Byte is Natural range 0 .. 255;
Single byte value.
type Byte_Array is array (Positive range <>) of Byte;
Contiguous byte sequence. Used for all UTF-8 data, buffers,
and UCD file contents.
Constants:
Max_Codepoint : constant := 16#10_FFFF#;
Codepoint_Count : constant := 1_114_112;
Surrogate_First : constant := 16#D800#;
Surrogate_Last : constant := 16#DFFF#;
LF, CR, Space, Tab, Hash, Dot, Semicolon : constant Byte;
Zero, Nine, Upper_A, Upper_F : constant Byte;
Functions:
Is_Scalar_Value(CP) -> Boolean
True if CP is not in the surrogate range (D800..DFFF).
Is_Noncharacter(CP) -> Boolean
True if CP is a Unicode noncharacter (FDD0..FDEF, xFFFE, xFFFF).
Is_Hex_Digit(B) -> Boolean
Hex_Value(B) -> Natural
Is_Line_End(B) -> Boolean
Is_Field_Space(B) -> Boolean
Byte classification for UCD file parsing.
================================================================================
LINGENIC_TEXT.UTF8
================================================================================
procedure Decode
(Source : Byte_Array;
Pos : Positive;
CP : out Codepoint;
Length : out Positive;
Valid : out Boolean);
Pre: Pos in Source'Range
Source'Last < Positive'Last
Post: Length in 1..4
Valid = UTF8_Spec.Well_Formed_At(Source, Pos)
if Valid: CP = Decoded_At, Is_Scalar_Value(CP),
Encoded_At(Source, Pos, CP), Length = Lead_Length
if not Valid: CP = 0, Length = 1
procedure Encode
(CP : Codepoint;
Target : in out Byte_Array;
Pos : Positive;
Length : out Positive);
Pre: Is_Scalar_Value(CP)
Pos in Target'Range
Target'Last < Positive'Last
Target'Last - Pos >= Encoded_Length(CP) - 1
Post: Length = Encoded_Length(CP)
Encoded_At(Target, Pos, CP)
Well_Formed_At(Target, Pos)
Decoded_At(Target, Pos) = CP
Frame: bytes outside [Pos..Pos+Length-1] unchanged
================================================================================
LINGENIC_TEXT.UCD_PARSER
================================================================================
Types:
subtype Property_Index is Natural range 0 .. 255;
type Property_Table is array (Codepoint) of Property_Index;
type Value_Name is record First : Positive; Last : Natural; end record;
type Value_Name_Array is array (1 .. 255) of Value_Name;
procedure Parse_Property_File
(Source : Byte_Array;
Names : Value_Name_Array;
Num_Values : Property_Index;
Table : out Property_Table;
Success : out Boolean);
Post: for all CP => Table(CP) in 0..Num_Values
for all CP => Table(CP) = Expected_Value(Source, 1, CP, ...)
procedure Extract_Value_Names
(Source : Byte_Array;
Names : out Value_Name_Array;
Num_Values : out Property_Index;
Success : out Boolean);
================================================================================
LINGENIC_TEXT.FILE_IO
================================================================================
procedure Read_File
(Name : String;
Buffer : out Byte_Array;
Length : out Natural;
Success : out Boolean);
Maximum file size: 4 MB. SPARK_Mode(Off).
================================================================================
LINGENIC_TEXT.PROPERTIES
================================================================================
procedure Initialize(UCD_Dir : String; Success : out Boolean);
Post: if Success then Initialized
function Initialized return Boolean;
-- Script (UAX #24)
function Get_Script(CP) -> Property_Index;
function Script_Name_Count -> Property_Index;
function Script_Name(Idx) -> String;
-- Script_Extensions (UAX #24)
function Is_In_Script_Extensions(CP, Script_Idx) -> Boolean;
function Get_Script_Extension_Count(CP) -> Scx_Member_Count;
function Get_Script_Extension(CP, K) -> Property_Index;
-- Grapheme_Cluster_Break (UAX #29)
function Get_GBP(CP) -> Property_Index;
function GBP_Name_Count -> Property_Index;
function GBP_Name(Idx) -> String;
function GBP_To_Abstract(Idx) -> GBP_Value;
-- Extended_Pictographic (UTS #51)
function Get_ExtPict(CP) -> Boolean;
-- Indic_Conjunct_Break (UAX #44)
function Get_InCB(CP) -> Property_Index;
function InCB_Name_Count -> Property_Index;
function InCB_To_Abstract(Idx) -> InCB_Value;
-- Word_Break (UAX #29)
function Get_WBP(CP) -> Property_Index;
function WBP_Name_Count -> Property_Index;
function WBP_Name(Idx) -> String;
function WBP_To_Abstract(Idx) -> WBP_Value;
-- Sentence_Break (UAX #29)
function Get_SBP(CP) -> Property_Index;
function SBP_Name_Count -> Property_Index;
function SBP_Name(Idx) -> String;
function SBP_To_Abstract(Idx) -> SBP_Value;
-- East_Asian_Width (UAX #11)
function Get_EAW(CP) -> Property_Index;
function EAW_Name_Count -> Property_Index;
function EAW_Name(Idx) -> String;
function EAW_To_Abstract(Idx) -> EAW_Value;
-- Line_Break (UAX #14)
function Get_LBP(CP) -> LBP_Value;
Returns resolved class (after LB1, QU/OP/CP splits).
-- General_Category (UAX #44)
function Get_GC(CP) -> Property_Index;
function GC_Name_Count -> Property_Index;
function GC_Name(Idx) -> String;
-- Bidi_Class (UAX #9)
function Get_BC(CP) -> BC_Value;
Returns resolved class.
-- Joining_Type (UAX #44)
function Get_JT(CP) -> JT_Value;
-- Bidi_Mirrored (UAX #9)
function Get_Bidi_Mirrored(CP) -> Boolean;
-- XID_Start / XID_Continue (UAX #31)
function Get_XID_Start(CP) -> Boolean;
function Get_XID_Continue(CP) -> Boolean;
All accessors: Pre => Initialized.
================================================================================
LINGENIC_TEXT.GRAPHEMES
================================================================================
procedure Next_Grapheme_Cluster_Break
(Text : Byte_Array;
Pos : Positive;
Next_Pos : out Positive);
Pre: Text'First = 1, Text'Last >= 1, Text'Last < Positive'Last
Pos in Text'Range, Properties.Initialized
Post: Next_Pos = Next_GCB_From(Text, Pos)
Next_Pos > Pos
Next_Pos <= Text'Last + 1
================================================================================
LINGENIC_TEXT.WORDS
================================================================================
procedure Next_Word_Break
(Text : Byte_Array;
Pos : Positive;
Next_Pos : out Positive);
Pre: Text'First = 1, Text'Last >= 1, Text'Last < Positive'Last
Pos in Text'Range, Properties.Initialized
Post: Next_Pos = Next_WB_From(Text, Pos)
Next_Pos > Pos
Next_Pos <= Text'Last + 1
================================================================================
LINGENIC_TEXT.SENTENCES
================================================================================
procedure Next_Sentence_Break
(Text : Byte_Array;
Pos : Positive;
Next_Pos : out Positive);
Pre: Text'First = 1, Text'Last >= 1, Text'Last < Positive'Last
Pos in Text'Range, Properties.Initialized
Post: Next_Pos = Next_SB_From(Text, Pos)
Next_Pos > Pos
Next_Pos <= Text'Last + 1
================================================================================
LINGENIC_TEXT.LINE_BREAK
================================================================================
procedure Next_Line_Break
(Text : Byte_Array;
Pos : Positive;
Next_Pos : out Positive);
Pre: Text'First = 1, Text'Last >= 1, Text'Last < Positive'Last
Pos in Text'Range, Properties.Initialized
Post: Next_Pos = Next_LB_From(Text, Pos)
Next_Pos > Pos
Next_Pos <= Text'Last + 1
================================================================================
LINGENIC_TEXT.NORMALIZATION
================================================================================
Types:
type Norm_Status is (Success, Buffer_Overflow, Invalid_Input);
type Normalization_Form is (NFD, NFC, NFKD, NFKC);
type QC_Value is (QC_Yes, QC_No, QC_Maybe);
procedure Initialize(UCD_Dir : String; Success : out Boolean);
Post: if Success then Initialized and Data_All_Terminal
function Initialized return Boolean;
function Data_All_Terminal return Boolean; -- Ghost
procedure Normalize
(Input : Byte_Array;
Form : Normalization_Form;
Output : in out Byte_Array;
Last : out Natural;
Status : out Norm_Status);
Pre: Initialized, Data_All_Terminal
Input'Length >= 1, Output'Length >= 1
Output'Length <= Max_Norm_Acc
Post: if Success then
Last in Output'First..Output'Last
NFD/NFKD: Ghost_Is_NFD(Output, Output'First, Last)
NFC/NFKC: Ghost_Is_NFC(Output, Output'First, Last, ...)
else Last = Output'First - 1
function Quick_Check(Input, Form) -> QC_Value;
Pre: Initialized, Input'Length >= 1
function Is_Normalized(Input, Form) -> Boolean;
Pre: Initialized, Input'Length >= 1
function Get_CCC(CP) -> CCC_Value;
function Get_NFC_QC(CP) -> QC_Value;
function Get_NFKC_QC(CP) -> QC_Value;
Pre: Initialized
================================================================================
LINGENIC_TEXT.CASE_MAPPING
================================================================================
Types:
type Case_Status is (Success, Buffer_Overflow, Invalid_Input);
procedure Initialize(UCD_Dir : String; Success : out Boolean);
Pre: Properties.Initialized
Post: if Success then Initialized
function Initialized return Boolean;
procedure Uppercase(Input, Output, Last, Status);
Pre: Initialized, Input/Output valid
Post: if Success then Last - Output'First + 1 = Ghost_Upper_Total(Input)
procedure Lowercase(Input, Output, Last, Status);
Post: if Success then Last - Output'First + 1 = Ghost_Lower_Total(Input)
procedure Titlecase(Input, Output, Last, Status);
Pre: additionally Input'First = 1, Properties.Initialized
Post: if Success then Last - Output'First + 1 = Ghost_Title_Total(Input)
procedure Casefold(Input, Output, Last, Status);
Post: if Success then Last - Output'First + 1 = Ghost_Fold_Total(Input)
function Is_Cased(CP) -> Boolean;
function Is_Case_Ignorable(CP) -> Boolean;
function Get_Upper_Map_Len(CP) -> Natural;
function Get_Upper_Map_CP(CP, Idx) -> Codepoint;
function Get_Lower_Map_Len(CP) -> Natural;
function Get_Lower_Map_CP(CP, Idx) -> Codepoint;
function Get_Title_Map_Len(CP) -> Natural;
function Get_Title_Map_CP(CP, Idx) -> Codepoint;
function Get_Fold_Map_Len(CP) -> Natural;
function Get_Fold_Map_CP(CP, Idx) -> Codepoint;
Pre: Initialized (+ Idx bounds for *_Map_CP)
================================================================================
LINGENIC_TEXT.COLLATION
================================================================================
Types:
type Variable_Weight_Option is (Non_Ignorable, Shifted);
type Comparison_Result is (Less, Equal, Greater);
procedure Initialize(UCD_Dir : String; Success : out Boolean);
Pre: Normalization.Initialized
Post: if Success then Initialized
function Initialized return Boolean;
procedure Compare
(Left, Right : Byte_Array;
Option : Variable_Weight_Option;
Result : out Comparison_Result;
Success : out Boolean);
Pre: Initialized, Normalization.Initialized,
Normalization.Data_All_Terminal
procedure Sort_Key
(Input : Byte_Array;
Option : Variable_Weight_Option;
Key : in out Byte_Array;
Last : out Natural;
Success : out Boolean);
Post: if Success then Last in Key'First..Key'Last
else Last = Key'First - 1
================================================================================
LINGENIC_TEXT.BIDI
================================================================================
Types:
subtype Embedding_Level is Natural range 0 .. 126;
subtype Paragraph_Length is Natural range 0 .. Max_Paragraph_CPs;
type Level_Array is array (1 .. Max_Paragraph_CPs) of Embedding_Level;
type Index_Array is array (1 .. Max_Paragraph_CPs) of Natural;
type Paragraph_Direction is (Dir_Auto, Dir_LTR, Dir_RTL);
Constants:
Max_Depth = 125
Max_Paragraph_CPs = 4096
procedure Initialize(UCD_Dir : String; Success : out Boolean);
Pre: Properties.Initialized
Post: if Success then Initialized
function Initialized return Boolean;
procedure Resolve_Levels
(Text : Byte_Array;
Dir : Paragraph_Direction;
Levels : out Level_Array;
Num_CPs : out Paragraph_Length;
Para_Level : out Embedding_Level;
Success : out Boolean);
Post: if Success then
Num_CPs >= 1, Para_Level <= 1
for all I in 1..Num_CPs => Levels(I) <= Max_Depth + 1
else Num_CPs = 0
procedure Reorder
(Levels : Level_Array;
Num_CPs : Paragraph_Length;
Para_Level : Embedding_Level;
Order : out Index_Array;
Success : out Boolean);
Post: if Success then
for all I => Order(I) in 1..Num_CPs (range)
for all V => (for some I => Order(I) = V) (surjection)
function Needs_Mirror(CP, Level) -> Boolean;
Post: Result = (Level mod 2 = 1) and then Get_Bidi_Mirrored(CP)
================================================================================
LINGENIC_TEXT.EMOJI
================================================================================
Types:
type Emoji_Sequence_Type is
(Not_Emoji, Emoji_Character, Emoji_Presentation_Seq,
Emoji_Keycap_Seq, Emoji_Modifier_Seq, Emoji_Flag_Seq,
Emoji_Tag_Seq, Emoji_ZWJ_Seq);
procedure Initialize(UCD_Dir : String; Success : out Boolean);
Post: if Success then Initialized
function Initialized return Boolean;
function Is_Emoji(CP) -> Boolean;
function Is_Emoji_Presentation(CP) -> Boolean;
function Is_Emoji_Modifier(CP) -> Boolean;
function Is_Emoji_Modifier_Base(CP) -> Boolean;
function Is_Emoji_Component(CP) -> Boolean;
Pre: Initialized
function Classify_Sequence(Input : Byte_Array) -> Emoji_Sequence_Type;
Pre: Initialized, Input'Length in 1..Max_Sequence_Bytes
Post: Result = Ghost_Classify_All(Input)
================================================================================
LINGENIC_TEXT.EAW
================================================================================
function Display_Width(CP : Codepoint) return Natural;
Pre: Properties.Initialized
Post: Result = Cell_Width(EAW_To_Abstract(Get_EAW(CP)))
Wide/Fullwidth -> 2, others -> 1
================================================================================
LINGENIC_TEXT.IDENTIFIERS
================================================================================
function Is_Identifier_Start(CP : Codepoint) return Boolean;
Pre: Properties.Initialized
Post: Result = Properties.Get_XID_Start(CP)
function Is_Identifier_Part(CP : Codepoint) return Boolean;
Pre: Properties.Initialized
Post: Result = Properties.Get_XID_Continue(CP)
================================================================================
LINGENIC_TEXT.IDNA
================================================================================
Types:
type IDNA_Result is
(Success, Invalid_Input, Disallowed_Codepoint, Label_Too_Long,
Domain_Too_Long, Invalid_Hyphen, Leading_Combining_Mark,
NFC_Failure, Bidi_Failure, ContextJ_Failure, Punycode_Failure,
Buffer_Overflow, STD3_Failure, Too_Many_Labels, Empty_Label);
type IDNA_Options is record
Check_Hyphens : Boolean;
Check_Bidi : Boolean;
Check_Joiners : Boolean;
Use_STD3_Rules : Boolean;
Verify_DNS_Length : Boolean;
end record;
procedure Initialize(UCD_Dir : String; Success : out Boolean);
Post: if Success then Initialized
function Initialized return Boolean;
procedure To_ASCII
(Input : Byte_Array; Options : IDNA_Options;
Output : in out Byte_Array; Last : out Natural;
Status : out IDNA_Result);
Pre: Initialized, Properties.Initialized,
Normalization.Initialized, Normalization.Data_All_Terminal
Post: if Success then
Last in Output'First..Output'Last
for all I in Output'First..Last => Output(I) < 128
if Verify_DNS_Length then length in 1..253
else Last = Output'First - 1
procedure To_Unicode
(Input : Byte_Array; Options : IDNA_Options;
Output : in out Byte_Array; Last : out Natural;
Status : out IDNA_Result);
Post: if Success then Last in Output'First..Output'Last
else Last = Output'First - 1
================================================================================
LINGENIC_TEXT.TEXT_TRANSFORM (Generic)
================================================================================
generic
type State_Type is private;
with function Output_Valid(S, Output, Last) -> Boolean;
with function Partial_Valid(S, Output, Pos) -> Boolean;
with procedure On_Codepoint(State, CP, Output, Pos, OK)
Pre: Partial_Valid(State, Output, Pos) and OK
Post: Pos >= Pos'Old, Pos <= Output'Last + 1,
if OK then Partial_Valid(State, Output, Pos);
with procedure On_Finish(State, Output, Pos, OK)
Pre: Partial_Valid(State, Output, Pos) and OK
Post: Pos >= Pos'Old, Pos <= Output'Last + 1,
if OK and Pos > Output'First then
Output_Valid(State, Output, Pos - 1);
procedure Lingenic_Text.Text_Transform
(Input : Byte_Array;
State : in out State_Type;
Output : in out Byte_Array;
Last : out Natural;
OK : out Boolean);
Pre: Input'Length >= 1, Output'Length >= 1
Partial_Valid(State, Output, Output'First)
Post: if OK then
Last in Output'First..Output'Last
Output_Valid(State, Output, Last)
else Last = Output'First - 1
================================================================================
INITIALIZATION ORDER SUMMARY
================================================================================
Required initialization order:
1. Properties.Initialize(UCD_Dir, ...)
2. Emoji.Initialize(UCD_Dir, ...) -- independent of Properties
3. Normalization.Initialize(UCD_Dir, ...) -- no dependencies
4. Case_Mapping.Initialize(UCD_Dir, ...) -- requires Properties
5. Collation.Initialize(UCD_Dir, ...) -- requires Normalization
6. Bidi.Initialize(UCD_Dir, ...) -- requires Properties
7. IDNA.Initialize(UCD_Dir, ...) -- requires Properties + Normalization
Modules without Initialize:
Graphemes, Words, Sentences, Line_Break -- require Properties.Initialized
EAW, Identifiers -- require Properties.Initialized