with ARM_Output, ARM_Contents, Ada.Text_IO, Ada.Exceptions, Ada.Strings.Fixed; package body ARM_Text is -- -- Ada reference manual formatter (ARM_Form). -- -- This package defines the text output object. -- Output objects are responsible for implementing the details of -- a particular format. -- -- --------------------------------------- -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2011 -- AXE Consultants. All rights reserved. -- P.O. Box 1512, Madison WI 53701 -- E-Mail: randy@rrsoftware.com -- -- ARM_Form is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License version 3 -- as published by the Free Software Foundation. -- -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS" -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY, -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL. -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL, -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES, -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -- DAMAGES. -- -- A copy of the GNU General Public License is available in the file -- gpl-3-0.txt in the standard distribution of the ARM_Form tool. -- Otherwise, see . -- -- If the GPLv3 license is not satisfactory for your needs, a commercial -- use license is available for this tool. Contact Randy at AXE Consultants -- for more information. -- -- --------------------------------------- -- -- Edit History: -- -- 4/14/00 - RLB - Created base package. -- 4/18/00 - RLB - Added index and contents marker routines. -- - Improved formatting. -- 4/21/00 - RLB - Added line break and hard space routines. -- 4/24/00 - RLB - Added DR references and Insert/Delete text formats. -- 4/25/00 - RLB - Added size to format. -- 4/29/00 - RLB - Added more formats. -- 5/10/00 - RLB - Added even more formats. -- - RLB - Added End_Hang_Item. -- 5/12/00 - RLB - Added No_Prefix to Start_Paragraph. -- 5/13/00 - RLB - Added Special_Character. -- 5/17/00 - RLB - Added New_Page. -- 5/22/00 - RLB - Added Includes_Changes to Create. -- 5/23/00 - RLB - Added Set_Column and New_Column. -- - Added Tab_Info and Tab_Stops. -- 5/24/00 - RLB - Added Location to Text_Format. -- - RLB - Added No_Breaks and Keep_with_Next to Start_Paragraph. -- 5/25/00 - RLB - Added Big_Files to Create. Added Justification. -- - RLB - Added Separator_Lines and TOC routines. -- 5/26/00 - RLB - Added table operations. -- 6/ 2/00 - RLB - Added Soft_Line_Break. -- 8/ 2/00 - RLB - Added Soft_Hyphen_Break and left and right quote -- characters. -- - RLB - Added additional styles. -- 8/ 4/00 - RLB - Added additional styles. -- 8/ 7/00 - RLB - Added Leading flag to Start_Paragraph, removed "Leading" -- styles. -- 8/11/00 - RLB - Added Hanging_in_Bulleted styles. -- 8/16/00 - RLB - Added Code_Indented_Nested_Bulleted. -- 8/17/00 - RLB - Replaced "Leading" by "Space_After". -- - RLB - Added Nested_Enumerated. -- 8/22/00 - RLB - Added Revised_Clause_Header. -- 8/23/00 - RLB - Fixed a problem with long lines in examples. -- 9/26/00 - RLB - Added Syntax_Summary style. -- 7/18/02 - RLB - Removed Document parameter from Create, replaced by -- three strings and For_ISO boolean. -- - RLB - Added AI_Reference. -- - RLB - Added Change_Version_Type and uses. -- 9/10/04 - RLB - Added "Both" to possible changes to handle -- replacement of changed text. -- 9/14/04 - RLB - Moved Change_Version_Type to ARM_Contents. -- 11/03/04 - RLB - Added Nested_X2_Bulleted. -- 11/15/04 - RLB - Added Indented_Nested_Bulleted. -- 1/24/05 - RLB - Added Inner_Indented. -- 2/ 1/05 - RLB - Added Turkish chars to allow an AARM note. -- 5/27/05 - RLB - Added arbitrary Unicode characters. -- 1/11/06 - RLB - Eliminated dispatching Create in favor of tailored -- versions. -- 1/13/06 - RLB - Added new Link operations. -- 1/18/06 - RLB - Added additional styles. -- 2/ 8/06 - RLB - Added additional parameters to the table command. -- 2/10/06 - RLB - Added even more additional parameters to the -- table command. -- - RLB - Added picture command. -- 9/22/06 - RLB - Added Subsubclause. -- 9/25/06 - RLB - Handled optional renaming of TOC. -- - RLB - Added Last_Column_Width to Start_Table. -- 10/13/06 - RLB - Added Local_Link_Start and Local_Link_End to allow -- formatting in the linked text. -- 2/ 9/07 - RLB - Changed comments on AI_Reference. -- 2/13/07 - RLB - Revised to separate style and indent information -- for paragraphs. -- 12/18/07 - RLB - Added Plain_Annex. -- 12/19/07 - RLB - Added limited colors to Text_Format. -- 10/18/11 - RLB - Changed to GPLv3 license. LINE_LENGTH : constant := 78; -- Maximum intended line length. procedure Put_Line_Centered (File : in out Ada.Text_IO.File_Type; Text : in String) is -- Put a line of text centered. begin for I in 1 .. (LINE_LENGTH - Text'Length - 1) / 2 loop -- Center the heading. Ada.Text_IO.Put (File, ' '); end loop; Ada.Text_IO.Put_Line (File, Text); end Put_Line_Centered; procedure Create (Output_Object : in out Text_Output_Type; File_Prefix : in String; Title : in String := "") is -- Create an Output_Object for a document. -- The prefix of the output file names is File_Prefix - this -- should be no more then 4 characters allowed in file names. -- The title of the document is Title. begin if Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Already valid object"); end if; Output_Object.Is_Valid := True; Ada.Strings.Fixed.Move (Target => Output_Object.File_Prefix, Source => File_Prefix); -- We don't use the title. end Create; procedure Close (Output_Object : in out Text_Output_Type) is -- Close an Output_Object. No further output to the object is -- allowed after this call. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Ada.Text_IO.Is_Open (Output_Object.Output_File) then Ada.Text_IO.Close (Output_Object.Output_File); end if; Output_Object.Is_Valid := False; end Close; procedure Section (Output_Object : in out Text_Output_Type; Section_Title : in String; Section_Name : in String) is -- Start a new section. The title is Section_Title (this is -- intended for humans). The name is Section_Name (this is -- intended to be suitable to be a portion of a file name). begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Section in paragraph"); end if; if Ada.Text_IO.Is_Open (Output_Object.Output_File) then Ada.Text_IO.Close (Output_Object.Output_File); end if; -- Create a new file for this section: Ada.Text_IO.Create (Output_Object.Output_File, Ada.Text_IO.Out_File, ".\Output\" & Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, Ada.Strings.Right) & "-" & Section_Name & ".TXT"); Ada.Text_IO.New_Line (Output_Object.Output_File); end Section; procedure Set_Columns (Output_Object : in out Text_Output_Type; Number_of_Columns : in ARM_Output.Column_Count) is -- Set the number of columns. -- Raises Not_Valid_Error if in a paragraph. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "In paragraph"); end if; -- No columns in text format. end Set_Columns; procedure Make_Indent (Output_Object : in out Text_Output_Type) is -- Internal: -- Output the appropriate indent after a New_Line or Put_Line. begin --Ada.Text_IO.Put_Line("Make_Indent: Amount=" & Natural'Image(Output_Object.Indent_Amount)); for I in 1 .. Output_Object.Indent_Amount loop Ada.Text_IO.Put (Output_Object.Output_File, ' '); end loop; Output_Object.Char_Count := Output_Object.Indent_Amount; Output_Object.Out_Char_Count := Output_Object.Indent_Amount; Output_Object.Output_Buffer_Space_Before := False; end Make_Indent; procedure Spill (Output_Object : in out Text_Output_Type) is -- Internal: -- Empty the output buffer in preperation for a New_Line or Put_Line. begin if Output_Object.Output_Buffer_Space_Before then Ada.Text_IO.Put (Output_Object.Output_File, ' '); Output_Object.Char_Count := Output_Object.Char_Count + 1; -- Count the space. Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 1; -- Count the space. end if; if Output_Object.Output_Buffer_Len /= 0 then Ada.Text_IO.Put (Output_Object.Output_File, Output_Object.Output_Buffer (1 .. Output_Object.Output_Buffer_Len)); --Ada.Text_IO.Put_Line("Spill: Len=" & Natural'Image(Output_Object.Output_Buffer_Len) & -- " Space added=" & Boolean'Image(Output_Object.Output_Buffer_Space_Before) & " Text=" & -- Output_Object.Output_Buffer (1 .. Output_Object.Output_Buffer_Len)); Output_Object.Output_Buffer_Len := 0; Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + Output_Object.Output_Buffer_Len; end if; Output_Object.Output_Buffer_Space_Before := False; end Spill; procedure Buffer (Output_Object : in out Text_Output_Type; Char : in Character) is -- Internal: -- Add Char to the output buffer. Char will *not* be a word break -- character. begin if Output_Object.Output_Buffer_Len = Output_Object.Output_Buffer'Last then -- Oops, buffer is full. Spill it, and this character. --Ada.Text_IO.Put_Line("** Buffer overflow!!"); Spill (Output_Object); Ada.Text_IO.Put (Output_Object.Output_File, Char); Output_Object.Char_Count := Output_Object.Char_Count + 1; return; end if; Output_Object.Output_Buffer_Len := Output_Object.Output_Buffer_Len + 1; Output_Object.Output_Buffer(Output_Object.Output_Buffer_Len) := Char; Output_Object.Char_Count := Output_Object.Char_Count + 1; end Buffer; procedure Start_Paragraph (Output_Object : in out Text_Output_Type; Style : in ARM_Output.Paragraph_Style_Type; Indent : in ARM_Output.Paragraph_Indent_Type; Number : in String; No_Prefix : in Boolean := False; Tab_Stops : in ARM_Output.Tab_Info := ARM_Output.NO_TABS; No_Breaks : in Boolean := False; Keep_with_Next : in Boolean := False; Space_After : in ARM_Output.Space_After_Type := ARM_Output.Normal; Justification : in ARM_Output.Justification_Type := ARM_Output.Default) is -- Start a new paragraph. The style and indent of the paragraph is as -- specified. The (AA)RM paragraph number (which might include update -- and version numbers as well: [12.1/1]) is Number. If the format is -- a type with a prefix (bullets, hangining items), the prefix is -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for -- the paragraph. If No_Breaks is True, we will try to avoid page breaks -- in the paragraph. If Keep_with_Next is true, we will try to avoid -- separating this paragraph and the next one. (These may have no -- effect in formats that don't have page breaks). Space_After -- specifies the amount of space following the paragraph. Justification -- specifies the text justification for the paragraph. Not_Valid_Error -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format. Start_Indent : Natural; begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Already in paragraph"); end if; Output_Object.Is_In_Paragraph := True; Output_Object.Is_Hanging := False; Output_Object.Saw_Hang_End := False; Output_Object.Char_Count := 0; Output_Object.Out_Char_Count := 0; Output_Object.Output_Buffer_Space_Before := False; -- Nothing in it or on the line. Output_Object.Output_Buffer_Len := 0; if ARM_Output."/=" (Indent, 0) then Output_Object.Indent_Amount := Natural(Indent)*4 + 2; else Output_Object.Indent_Amount := 0; end if; Start_Indent := Output_Object.Indent_Amount; case Style is when ARM_Output.Normal => null; when ARM_Output.Wide_Above => null; when ARM_Output.Small => null; when ARM_Output.Small_Wide_Above => null; when ARM_Output.Header => null; when ARM_Output.Small_Header => null; when ARM_Output.Title => null; when ARM_Output.Index => null; when ARM_Output.Syntax_Summary => null; when ARM_Output.Examples => null; when ARM_Output.Small_Examples => null; when ARM_Output.Swiss_Examples => null; when ARM_Output.Small_Swiss_Examples => null; when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted | ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted => if No_Prefix then null; else -- Has prefix (added later) Start_Indent := Start_Indent - 4; end if; when ARM_Output.Wide_Hanging | ARM_Output.Small_Wide_Hanging => Output_Object.Is_Hanging := True; if No_Prefix then -- Three units for prefix. Output_Object.Saw_Hang_End := True; else -- Has prefix Output_Object.Saw_Hang_End := False; Start_Indent := Start_Indent - 12; -- Leave space for prefix. end if; when ARM_Output.Narrow_Hanging | ARM_Output.Small_Narrow_Hanging => null; Output_Object.Is_Hanging := True; if No_Prefix then -- One unit for prefix. Output_Object.Saw_Hang_End := True; else -- Has prefix. Output_Object.Saw_Hang_End := False; Start_Indent := Start_Indent - 4; -- Leave space for prefix. end if; when ARM_Output.Hanging_in_Bulleted | ARM_Output.Small_Hanging_in_Bulleted => Output_Object.Is_Hanging := True; if No_Prefix then -- Two units for prefix. Output_Object.Saw_Hang_End := True; else -- Has prefix. Output_Object.Saw_Hang_End := False; Start_Indent := Start_Indent - 8; -- Leave space for prefix. end if; when ARM_Output.Enumerated | ARM_Output.Small_Enumerated => Output_Object.Is_Hanging := True; if No_Prefix then -- One unit for prefix. Output_Object.Saw_Hang_End := True; else -- Has prefix. Output_Object.Saw_Hang_End := False; Start_Indent := Start_Indent - 4; -- Leave space for prefix. end if; end case; if Number /= "" then Ada.Text_IO.Put (Output_Object.Output_File, Number); Output_Object.Char_Count := Output_Object.Char_Count + Number'Length; for I in Integer'Min(Number'Length + 1, 6) .. 6 loop Ada.Text_IO.Put (Output_Object.Output_File, ' '); Output_Object.Char_Count := Output_Object.Char_Count + 1; end loop; if Start_Indent > 6 then -- Add any remaining indent. for I in 1 .. (Start_Indent-6)/4 loop Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := Output_Object.Char_Count + 4; end loop; end if; else -- No paragraph number: if Start_Indent /= 0 then Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := Output_Object.Char_Count + 2; for I in 1 .. (Start_Indent-2)/4 loop Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := Output_Object.Char_Count + 4; end loop; end if; end if; -- Add bullets if needed: case Style is when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted | ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted => if No_Prefix then null; else -- Has prefix (added later) Ada.Text_IO.Put (Output_Object.Output_File, " * "); Output_Object.Char_Count := Output_Object.Char_Count + 4; end if; when others => null; end case; case Style is when ARM_Output.Normal | ARM_Output.Wide_Above | ARM_Output.Small | ARM_Output.Small_Wide_Above | ARM_Output.Header | ARM_Output.Small_Header | ARM_Output.Index | ARM_Output.Syntax_Summary | ARM_Output.Title | ARM_Output.Examples | ARM_Output.Small_Examples | ARM_Output.Swiss_Examples | ARM_Output.Small_Swiss_Examples => Output_Object.Tab_Stops := Tab_Stops; -- We'll expand proportional stops here (text characters -- are larger than the variable ones these are set up for). for I in 1 .. Tab_Stops.Number loop if ARM_Output."=" (Tab_Stops.Stops(I).Kind, ARM_Output.Left_Proportional) then Output_Object.Tab_Stops.Stops(I).Stop := (Tab_Stops.Stops(I).Stop * 5 / 4) + Output_Object.Indent_Amount; else Output_Object.Tab_Stops.Stops(I).Stop := Tab_Stops.Stops(I).Stop + Output_Object.Indent_Amount; end if; end loop; when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted | ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted | ARM_Output.Wide_Hanging | ARM_Output.Narrow_Hanging | ARM_Output.Hanging_in_Bulleted | ARM_Output.Small_Wide_Hanging | ARM_Output.Small_Narrow_Hanging | ARM_Output.Small_Hanging_in_Bulleted | ARM_Output.Enumerated | ARM_Output.Small_Enumerated => if Tab_Stops.Number /= 0 then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Tabs in hanging/bulleted paragraph"); end if; end case; Output_Object.Out_Char_Count := Output_Object.Char_Count; -- Note: No_Breaks, Keep_with_Next, and Justification have no effect -- here. --Ada.Text_IO.Put_Line ("Start_Paragraph - Indent=" & Natural'Image(Output_Object.Indent_Amount) & " Cnt=" & -- Natural'Image(Output_Object.Char_Count)); end Start_Paragraph; procedure End_Paragraph (Output_Object : in out Text_Output_Type) is -- End a paragraph. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; if Output_Object.Output_Buffer_Len /= 0 then Spill (Output_Object); end if; Output_Object.Is_In_Paragraph := False; Ada.Text_IO.New_Line (Output_Object.Output_File, 2); -- Double space paragraphs. end End_Paragraph; procedure Category_Header (Output_Object : in out Text_Output_Type; Header_Text : String) is -- Output a Category header (that is, "Legality Rules", -- "Dynamic Semantics", etc.) -- (Note: We did not use a enumeration here to insure that these -- headers are spelled the same in all output versions). -- Raises Not_Valid_Error if in a paragraph. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Header in paragraph"); end if; Ada.Text_IO.New_Line (Output_Object.Output_File); Put_Line_Centered (Output_Object.Output_File, Header_Text); Ada.Text_IO.New_Line (Output_Object.Output_File); Output_Object.Char_Count := 0; Output_Object.Out_Char_Count := 0; end Category_Header; procedure Clause_Header (Output_Object : in out Text_Output_Type; Header_Text : in String; Level : in ARM_Contents.Level_Type; Clause_Number : in String; No_Page_Break : in Boolean := False) is -- Output a Clause header. The level of the header is specified -- in Level. The Clause Number is as specified. -- These should appear in the table of contents. -- For hyperlinked formats, this should generate a link target. -- If No_Page_Break is True, suppress any page breaks. -- Raises Not_Valid_Error if in a paragraph. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Header in paragraph"); end if; Ada.Text_IO.New_Line (Output_Object.Output_File); -- Special for table of contents: if Clause_Number = "" and then (Header_Text = "Table of Contents" or else -- Ada 95 format Header_Text = "Contents") then -- ISO 2004 format. Put_Line_Centered (Output_Object.Output_File, Header_Text); Ada.Text_IO.New_Line (Output_Object.Output_File, 2); Output_Object.Char_Count := 0; Output_Object.Out_Char_Count := 0; return; end if; case Level is when ARM_Contents.Plain_Annex => Put_Line_Centered (Output_Object.Output_File, Clause_Number); -- Note: Clause_Number includes "Annex" Put_Line_Centered (Output_Object.Output_File, Header_Text); when ARM_Contents.Normative_Annex => Put_Line_Centered (Output_Object.Output_File, Clause_Number); -- Note: Clause_Number includes "Annex" Put_Line_Centered (Output_Object.Output_File, "(normative)"); Ada.Text_IO.New_Line (Output_Object.Output_File); Put_Line_Centered (Output_Object.Output_File, Header_Text); when ARM_Contents.Informative_Annex => Put_Line_Centered (Output_Object.Output_File, Clause_Number); -- Note: Clause_Number includes "Annex" Put_Line_Centered (Output_Object.Output_File, "(informative)"); Ada.Text_IO.New_Line (Output_Object.Output_File); Put_Line_Centered (Output_Object.Output_File, Header_Text); when ARM_Contents.Section => Put_Line_Centered (Output_Object.Output_File, "Section " & Clause_Number & ": " & Header_Text); when ARM_Contents.Unnumbered_Section => if Header_Text /= "" then Put_Line_Centered (Output_Object.Output_File, Header_Text); end if; when ARM_Contents.Clause | ARM_Contents.Subclause | ARM_Contents.Subsubclause => Ada.Text_IO.Put_Line (Output_Object.Output_File, Clause_Number & ' ' & Header_Text); when ARM_Contents.Dead_Clause => raise Program_Error; -- No headers for dead clauses. end case; Ada.Text_IO.New_Line (Output_Object.Output_File, 2); Output_Object.Char_Count := 0; Output_Object.Out_Char_Count := 0; -- We don't have any page breaks here to suppress. end Clause_Header; procedure Revised_Clause_Header (Output_Object : in out Text_Output_Type; New_Header_Text : in String; Old_Header_Text : in String; Level : in ARM_Contents.Level_Type; Clause_Number : in String; Version : in ARM_Contents.Change_Version_Type; No_Page_Break : in Boolean := False) is -- Output a revised clause header. Both the original and new text will -- be output. The level of the header is specified in Level. The Clause -- Number is as specified. -- These should appear in the table of contents. -- For hyperlinked formats, this should generate a link target. -- If No_Page_Break is True, suppress any page breaks. -- Raises Not_Valid_Error if in a paragraph. function Header_Text return String is -- Note: Version is not used. begin return '{' & New_Header_Text & "} [" & Old_Header_Text & ']'; end Header_Text; begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Header in paragraph"); end if; Ada.Text_IO.New_Line (Output_Object.Output_File); -- Special for table of contents: if Clause_Number = "" and then (Header_Text = "Table of Contents" or else -- Ada 95 format Header_Text = "Contents") then -- ISO 2004 format. Put_Line_Centered (Output_Object.Output_File, Header_Text); Ada.Text_IO.New_Line (Output_Object.Output_File, 2); Output_Object.Char_Count := 0; Output_Object.Out_Char_Count := 0; return; end if; case Level is when ARM_Contents.Plain_Annex => Put_Line_Centered (Output_Object.Output_File, Clause_Number); -- Note: Clause_Number includes "Annex" Put_Line_Centered (Output_Object.Output_File, Header_Text); when ARM_Contents.Normative_Annex => Put_Line_Centered (Output_Object.Output_File, Clause_Number); -- Note: Clause_Number includes "Annex" Put_Line_Centered (Output_Object.Output_File, "(normative)"); Ada.Text_IO.New_Line (Output_Object.Output_File); Put_Line_Centered (Output_Object.Output_File, Header_Text); when ARM_Contents.Informative_Annex => Put_Line_Centered (Output_Object.Output_File, Clause_Number); -- Note: Clause_Number includes "Annex" Put_Line_Centered (Output_Object.Output_File, "(informative)"); Ada.Text_IO.New_Line (Output_Object.Output_File); Put_Line_Centered (Output_Object.Output_File, Header_Text); when ARM_Contents.Section => Put_Line_Centered (Output_Object.Output_File, "Section " & Clause_Number & ": " & Header_Text); when ARM_Contents.Unnumbered_Section => if Header_Text /= "" then Put_Line_Centered (Output_Object.Output_File, Header_Text); end if; when ARM_Contents.Clause | ARM_Contents.Subclause | ARM_Contents.Subsubclause => Ada.Text_IO.Put_Line (Output_Object.Output_File, Clause_Number & ' ' & Header_Text); when ARM_Contents.Dead_Clause => raise Program_Error; -- No headers for dead clauses. end case; Ada.Text_IO.New_Line (Output_Object.Output_File, 2); Output_Object.Char_Count := 0; Output_Object.Out_Char_Count := 0; -- We don't have any page breaks here to suppress. end Revised_Clause_Header; procedure TOC_Marker (Output_Object : in out Text_Output_Type; For_Start : in Boolean) is -- Mark the start (if For_Start is True) or end (if For_Start is -- False) of the table of contents data. Output objects that -- auto-generate the table of contents can use this to do needed -- actions. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; null; -- We don't care about this. end TOC_Marker; procedure New_Page (Output_Object : in out Text_Output_Type; Kind : ARM_Output.Page_Kind_Type := ARM_Output.Any_Page) is -- Output a page break. -- Note that this has no effect on non-printing formats. -- Any_Page breaks to the top of the next page (whatever it is); -- Odd_Page_Only breaks to the top of the odd-numbered page; -- Soft_Page allows a page break but does not force one (use in -- "No_Breaks" paragraphs.) -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or -- Odd_Page, and if not in a paragraph if Kind = Soft_Page. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; case Kind is when ARM_Output.Any_Page | ARM_Output.Odd_Page_Only => if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Page in paragraph"); end if; Ada.Text_IO.New_Line (Output_Object.Output_File, 2); when ARM_Output.Soft_Page => if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Soft page not in paragraph"); end if; null; -- No page breaks. Spill (Output_Object); end case; end New_Page; procedure New_Column (Output_Object : in out Text_Output_Type) is -- Output a column break. -- Raises Not_Valid_Error if in a paragraph, or if the number of -- columns is 1. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "New column in paragraph"); end if; -- No columns in text format. Ada.Text_IO.New_Line (Output_Object.Output_File); end New_Column; procedure Start_Table (Output_Object : in out Text_Output_Type; Columns : in ARM_Output.Column_Count; First_Column_Width : in ARM_Output.Column_Count; Last_Column_Width : in ARM_Output.Column_Count; Alignment : in ARM_Output.Column_Text_Alignment; No_Page_Break : in Boolean; Has_Border : in Boolean; Small_Text_Size : in Boolean; Header_Kind : in ARM_Output.Header_Kind_Type) is -- Starts a table. The number of columns is Columns; the first -- column has First_Column_Width times the normal column width, and -- the last column has Last_Column_Width times the normal column width. -- Alignment is the horizontal text alignment within the columns. -- No_Page_Break should be True to keep the table intact on a single -- page; False to allow it to be split across pages. -- Has_Border should be true if a border is desired, false otherwise. -- Small_Text_Size means that the contents will have the AARM size; -- otherwise it will have the normal size. -- Header_Kind determines whether the table has headers. -- This command starts a paragraph; the entire table is a single -- paragraph. Text will be considered part of the caption until the -- next table marker call. -- Raises Not_Valid_Error if in a paragraph. begin -- Alignment, No_Page_Break, Border, Small_Text_Size, and Header_Kind -- not used here. if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Table in paragraph"); end if; Output_Object.Tab_Stops.Number := Columns; declare Column_Units : constant ARM_Output.Column_Count := Columns+First_Column_Width+Last_Column_Width-2; Width : Natural := (72/(Column_Units)); begin if Column_Units <= 3 then -- Keep it from getting too wide. Width := 22; end if; for I in 1 .. Columns loop Output_Object.Tab_Stops.Stops(I) := (Kind => ARM_Output.Left_Fixed, Stop => Width*(I+First_Column_Width-1)+10); end loop; end; Output_Object.Indent_Amount := 10; Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := 10; Output_Object.Out_Char_Count := 10; Output_Object.Is_In_Paragraph := True; Output_Object.Is_In_Table := True; end Start_Table; procedure Table_Marker (Output_Object : in out Text_Output_Type; Marker : in ARM_Output.Table_Marker_Type) is -- Marks the end of an entity in a table. -- If Marker is End_Caption, the table caption ends and the -- future text is part of the table header. -- If Marker is End_Header, the table header ends and the -- future text is part of the table body. -- If Marker is End_Row, a row in the table is completed, and another -- row started. -- If Marker is End_Row_Next_Is_Last, a row in the table is completed, -- and another row started. That row is the last row in the table. -- If Marker is End_Item, an item in the table header or body is ended, -- and another started. -- If Marker is End_Table, the entire table is finished. -- Raises Not_Valid_Error if not in a table. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if (not Output_Object.Is_In_Paragraph) or (not Output_Object.Is_In_Table) then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Table marker not in table"); end if; case Marker is when ARM_Output.End_Item => -- Just tab over one row: Spill (Output_Object); Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := Output_Object.Char_Count + 1; Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 1; for I in 1 .. Output_Object.Tab_Stops.Number loop if Output_Object.Tab_Stops.Stops(I).Stop > Output_Object.Char_Count then for J in Output_Object.Char_Count+1 .. Output_Object.Tab_Stops.Stops(I).Stop-1 loop Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := Output_Object.Char_Count + 1; Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 1; end loop; end if; end loop; when ARM_Output.End_Caption => Spill (Output_Object); Ada.Text_IO.New_Line (Output_Object.Output_File, 2); Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := 10; Output_Object.Out_Char_Count := 10; when ARM_Output.End_Header => Spill (Output_Object); Ada.Text_IO.New_Line (Output_Object.Output_File, 2); Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := 10; Output_Object.Out_Char_Count := 10; when ARM_Output.End_Row | ARM_Output.End_Row_Next_Is_Last => Spill (Output_Object); Ada.Text_IO.New_Line (Output_Object.Output_File, 1); Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := 10; Output_Object.Out_Char_Count := 10; when ARM_Output.End_Table => Spill (Output_Object); Output_Object.Is_In_Paragraph := False; Output_Object.Is_In_Table := False; Ada.Text_IO.New_Line (Output_Object.Output_File); Output_Object.Tab_Stops := ARM_Output.NO_TABS; end case; end Table_Marker; procedure Separator_Line (Output_Object : in out Text_Output_Type; Is_Thin : Boolean := True) is -- Output a separator line. It is thin if "Is_Thin" is true. -- Raises Not_Valid_Error if in a paragraph. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Separator in paragraph"); end if; Ada.Text_IO.New_Line (Output_Object.Output_File); if Is_Thin then Ada.Text_IO.Put_Line (Output_Object.Output_File, "---------------------------------------------------------------------"); else Ada.Text_IO.Put_Line (Output_Object.Output_File, "====================================================================="); end if; Ada.Text_IO.New_Line (Output_Object.Output_File); end Separator_Line; -- Text output: These are only allowed after a Start_Paragraph and -- before any End_Paragraph. Raises Not_Valid_Error if not allowed. procedure Ordinary_Text (Output_Object : in out Text_Output_Type; Text : in String) is -- Output ordinary text. -- The text must end at a word break, never in the middle of a word. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; --Ada.Text_IO.Put_Line ("Ordinary_Text: Cnt=" & Natural'Image(Output_Object.Char_Count) & --" Buffer=" & Natural'Image(Output_Object.Output_Buffer_Len)); if Output_Object.Char_Count + Text'Length >= LINE_LENGTH - 2 and then Output_Object.Out_Char_Count > Output_Object.Indent_Amount then -- We want a line break here if the line is too long and something was output: Ada.Text_IO.New_Line (Output_Object.Output_File); Make_Indent (Output_Object); --Output_Object.Output_Buffer_Space_Before := False; -- Start of line, this is done by Make_Indent. Spill (Output_Object); else Spill (Output_Object); end if; Ada.Text_IO.Put (Output_Object.Output_File, Text); Output_Object.Char_Count := Output_Object.Char_Count + Text'Length; Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + Text'Length; Output_Object.Output_Buffer_Space_Before := False; -- No space between -- this and any following text. end Ordinary_Text; procedure Ordinary_Character (Output_Object : in out Text_Output_Type; Char : in Character) is -- Output an ordinary character. -- Spaces will be used to break lines as needed. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; if Output_Object.Char_Count >= LINE_LENGTH and then Output_Object.Out_Char_Count > Output_Object.Indent_Amount then -- Insert a break here if anything has been output (but don't -- Spill the buffer): --Ada.Text_IO.Put_Line ("Ordinary_Char [Break, no spill]: Cnt=" & Natural'Image(Output_Object.Char_Count)); Ada.Text_IO.New_Line (Output_Object.Output_File); Make_Indent (Output_Object); --Output_Object.Output_Buffer_Space_Before := False; -- Start of line, this is done by Make_Indent. -- Note that this may make the space disappear. -- Add the contents of the buffer to the character count for this line: Output_Object.Char_Count := Output_Object.Char_Count + Output_Object.Output_Buffer_Len; if Char /= ' ' then Buffer (Output_Object, Char); else -- Break character, spill on the new line: if Output_Object.Output_Buffer_Len /= 0 then Spill (Output_Object); -- Output the buffer up to the space. Output_Object.Output_Buffer_Space_Before := True; -- Mid-line now. -- else nothing in buffer, so nothing to output; just skip it. end if; end if; elsif Char = ' ' then -- Break character, and it fits on this line: if Output_Object.Output_Buffer_Len /= 0 then --Ada.Text_IO.Put_Line ("Ordinary_Char [Space spill]: Cnt=" & Natural'Image(Output_Object.Char_Count)); Spill (Output_Object); -- Output the buffer up to the space. Output_Object.Output_Buffer_Space_Before := True; -- Mid-line now. else -- nothing in buffer. -- nothing to output. But make sure we display a space before -- the next item. Output_Object.Output_Buffer_Space_Before := True; -- Mid-line now. end if; else Buffer (Output_Object, Char); end if; end Ordinary_Character; procedure Hard_Space (Output_Object : in out Text_Output_Type) is -- Output a hard space. No line break should happen at a hard space. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; Buffer (Output_Object, ' '); end Hard_Space; procedure Line_Break (Output_Object : in out Text_Output_Type) is -- Output a line break. This does not start a new paragraph. -- This corresponds to a "
" in HTML. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; --Ada.Text_Io.Put_Line ("Line_Break"); if Output_Object.Output_Buffer_Len /= 0 then Spill (Output_Object); end if; Ada.Text_IO.New_Line (Output_Object.Output_File); Make_Indent (Output_Object); end Line_Break; procedure Index_Line_Break (Output_Object : in out Text_Output_Type; Clear_Keep_with_Next : in Boolean) is -- Output a line break for the index. This does not start a new -- paragraph in terms of spacing. This corresponds to a "
" -- in HTML. If Clear_Keep_with_Next is true, insure that the next -- line does not require the following line to stay with it. -- Raises Not_Valid_Error if the paragraph is not in the index format. begin Line_Break (Output_Object); end Index_Line_Break; procedure Soft_Line_Break (Output_Object : in out Text_Output_Type) is -- Output a soft line break. This is a place (in the middle of a -- "word") that we allow a line break. It is usually used after -- underscores in long non-terminals. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; if Output_Object.Char_Count >= LINE_LENGTH - 10 then if Output_Object.Output_Buffer_Len /= 0 then Spill (Output_Object); end if; Ada.Text_IO.New_Line (Output_Object.Output_File); Make_Indent (Output_Object); -- else we don't need a line break. end if; end Soft_Line_Break; procedure Soft_Hyphen_Break (Output_Object : in out Text_Output_Type) is -- Output a soft line break, with a hyphen. This is a place (in the middle of -- a "word") that we allow a line break. If the line break is used, -- a hyphen will be added to the text. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; if Output_Object.Char_Count >= LINE_LENGTH - 8 then Spill (Output_Object); Ada.Text_IO.Put_Line (Output_Object.Output_File, "-"); -- Add the hyphen and break. Make_Indent (Output_Object); -- else we don't need a line break. end if; end Soft_Hyphen_Break; procedure Tab (Output_Object : in out Text_Output_Type) is -- Output a tab, inserting space up to the next tab stop. -- Raises Not_Valid_Error if the paragraph was created with -- Tab_Stops = ARM_Output.NO_TABS. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; if ARM_Output."="(Output_Object.Tab_Stops, ARM_Output.NO_TABS) then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Tab, but none set"); end if; -- We use the tab stops as characters here, and fixed and proportional -- stops are treated identically. -- Find the first stop greater than the current character count. (After -- writing a space). --Ada.Text_IO.Put_Line ("Tab"); Spill (Output_Object); Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := Output_Object.Char_Count + 1; Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 1; for I in 1 .. Output_Object.Tab_Stops.Number loop if Output_Object.Tab_Stops.Stops(I).Stop > Output_Object.Char_Count then for J in Output_Object.Char_Count+1 .. Output_Object.Tab_Stops.Stops(I).Stop-1 loop Ada.Text_IO.Put (Output_Object.Output_File, " "); Output_Object.Char_Count := Output_Object.Char_Count + 1; Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 1; --Ada.Text_IO.Put ("#"); end loop; exit; end if; end loop; -- If we drop out without finding a tab, we just use the single -- space already written. --Ada.Text_IO.New_Line; Output_Object.Output_Buffer_Space_Before := False; -- Spaces needed were output. end Tab; procedure Special_Character (Output_Object : in out Text_Output_Type; Char : in ARM_Output.Special_Character_Type) is -- Output an special character. begin case Char is when ARM_Output.EM_Dash => Ordinary_Character (Output_Object, '-'); -- Not available in plain text. when ARM_Output.EN_Dash => Ordinary_Character (Output_Object, '-'); -- Not available in plain text. when ARM_Output.GEQ => Ordinary_Text (Output_Object, ">="); -- Not available in plain text, use the Ada one. when ARM_Output.LEQ => Ordinary_Text (Output_Object, "<="); -- Not available in plain text, use the Ada one. when ARM_Output.NEQ => Ordinary_Text (Output_Object, "/="); -- Not available in plain text, use the Ada one. when ARM_Output.PI => Ordinary_Text (Output_Object, "PI"); -- Not available in plain text. when ARM_Output.Left_Ceiling => Ordinary_Text (Output_Object, "Ceiling("); -- Not available in plain text. when ARM_Output.Right_Ceiling => Ordinary_Text (Output_Object, ")"); -- Not available in plain text. when ARM_Output.Left_Floor => Ordinary_Text (Output_Object, "Floor("); -- Not available in plain text. when ARM_Output.Right_Floor => Ordinary_Text (Output_Object, ")"); -- Not available in plain text. when ARM_Output.Thin_Space => Ordinary_Text (Output_Object, " "); -- Not available in plain text. when ARM_Output.Left_Quote => Ordinary_Text (Output_Object, "`"); -- Not available in plain text, use back-quote. when ARM_Output.Right_Quote => Ordinary_Text (Output_Object, "'"); -- Not available in plain text, use quote. when ARM_Output.Left_Double_Quote => Ordinary_Text (Output_Object, """"); -- Not available in plain text, use double quote. when ARM_Output.Right_Double_Quote => Ordinary_Text (Output_Object, """"); -- Not available in plain text, use double quote. when ARM_Output.Small_Dotless_I => Ordinary_Text (Output_Object, "i"); -- Not available in plain text, use the nearest text. when ARM_Output.Capital_Dotted_I => Ordinary_Text (Output_Object, "I"); -- Not available in plain text, use the nearest text. end case; end Special_Character; procedure Unicode_Character (Output_Object : in out Text_Output_Type; Char : in ARM_Output.Unicode_Type) is -- Output a Unicode character, with code position Char. Char_Code : constant String := ARM_Output.Unicode_Type'Image(Char); begin -- We don't check, but we assume this is not a normal character. Ordinary_Text (Output_Object, ""); end Unicode_Character; procedure End_Hang_Item (Output_Object : in out Text_Output_Type) is -- Marks the end of a hanging item. Call only once per paragraph. -- Raises Not_Valid_Error if the paragraph style is not in -- Text_Prefixed_Style_Subtype, or if this has already been -- called for the current paragraph, or if the paragraph was started -- with No_Prefix = True. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; if not Output_Object.Is_Hanging then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not a hanging paragraph"); end if; if Output_Object.Saw_Hang_End then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Already saw the end of the hanging part"); end if; Output_Object.Saw_Hang_End := True; if Output_Object.Char_Count >= Output_Object.Indent_Amount then if Output_Object.Output_Buffer_Len /= 0 then Spill (Output_Object); end if; Ada.Text_IO.New_Line (Output_Object.Output_File); Make_Indent (Output_Object); else Spill (Output_Object); for I in Output_Object.Char_Count + 1 .. Output_Object.Indent_Amount loop Ada.Text_IO.Put (Output_Object.Output_File, ' '); end loop; Output_Object.Char_Count := Output_Object.Indent_Amount; Output_Object.Out_Char_Count := Output_Object.Indent_Amount; Output_Object.Output_Buffer_Space_Before := False; -- Spaces needed were output. end if; end End_Hang_Item; procedure Text_Format (Output_Object : in out Text_Output_Type; Format : in ARM_Output.Format_Type) is -- Change the text format so that all of the properties are as specified. -- Note: Changes to these properties ought be stack-like; that is, -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on, -- Bold off, Italic off should be avoided (as separate commands). use type ARM_Output.Change_Type; use type ARM_Output.Location_Type; begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; if Format.Location /= Output_Object.Location then if Output_Object.Location /= ARM_Output.Normal then Buffer(Output_Object, ')'); end if; end if; if Format.Change /= Output_Object.Change then if Format.Change = ARM_Output.Both then -- Open only the one(s) needed: case Output_Object.Change is -- Note: Version is not used. when ARM_Output.Insertion => -- Open the deletion: Buffer(Output_Object, '['); when ARM_Output.Deletion => -- Open the insertion: Buffer(Output_Object, '{'); when ARM_Output.None => Buffer(Output_Object, '{'); Buffer(Output_Object, '['); when ARM_Output.Both => null; end case; elsif Output_Object.Change = ARM_Output.Both then -- Close only the one(s) needed: case Format.Change is -- Note: Version is not used. when ARM_Output.Insertion => -- Close the deletion: Buffer(Output_Object, ']'); when ARM_Output.Deletion => -- Close the insertion: Buffer(Output_Object, '}'); when ARM_Output.None => Buffer(Output_Object, ']'); Buffer(Output_Object, '}'); when ARM_Output.Both => null; end case; else -- Both can't get here. case Output_Object.Change is when ARM_Output.Insertion => Buffer(Output_Object, '}'); when ARM_Output.Deletion => Buffer(Output_Object, ']'); when ARM_Output.None => null; when ARM_Output.Both => Buffer(Output_Object, ']'); Buffer(Output_Object, '}'); end case; case Format.Change is -- Note: Version is not used. when ARM_Output.Insertion => Buffer(Output_Object, '{'); when ARM_Output.Deletion => Buffer(Output_Object, '['); when ARM_Output.None => null; when ARM_Output.Both => Buffer(Output_Object, '{'); Buffer(Output_Object, '['); end case; end if; Output_Object.Change := Format.Change; end if; if Format.Location /= Output_Object.Location then if Format.Location /= ARM_Output.Normal then Buffer(Output_Object, '('); end if; Output_Object.Location := Format.Location; end if; null; -- Nothing else to do for plain text. end Text_Format; procedure Clause_Reference (Output_Object : in out Text_Output_Type; Text : in String; Clause_Number : in String) is -- Generate a reference to a clause in the standard. The text of -- the reference is "Text", and the number of the clause is -- Clause_Number. For hyperlinked formats, this should generate -- a link; for other formats, the text alone is generated. begin Ordinary_Text (Output_Object, Text); -- Nothing special in this format. end Clause_Reference; procedure Index_Target (Output_Object : in out Text_Output_Type; Index_Key : in Natural) is -- Generate a index target. This marks the location where an index -- reference occurs. Index_Key names the index item involved. -- For hyperlinked formats, this should generate a link target; -- for other formats, nothing is generated. begin if not Output_Object.Is_Valid then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not valid object"); end if; if not Output_Object.Is_In_Paragraph then Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity, "Not in paragraph"); end if; null; -- Nothing to do for plain text. end Index_Target; procedure Index_Reference (Output_Object : in out Text_Output_Type; Text : in String; Index_Key : in Natural; Clause_Number : in String) is -- Generate a reference to an index target in the standard. The text -- of the reference is "Text", and Index_Key and Clause_Number denotes -- the target. For hyperlinked formats, this should generate -- a link; for other formats, the text alone is generated. begin Ordinary_Text (Output_Object, Text); -- Nothing special in this format. end Index_Reference; procedure DR_Reference (Output_Object : in out Text_Output_Type; Text : in String; DR_Number : in String) is -- Generate a reference to an DR from the standard. The text -- of the reference is "Text", and DR_Number denotes -- the target. For hyperlinked formats, this should generate -- a link; for other formats, the text alone is generated. begin Ordinary_Text (Output_Object, Text); -- Nothing special in this format. end DR_Reference; procedure AI_Reference (Output_Object : in out Text_Output_Type; Text : in String; AI_Number : in String) is -- Generate a reference to an AI from the standard. The text -- of the reference is "Text", and AI_Number denotes -- the target (in unfolded format). For hyperlinked formats, this should -- generate a link; for other formats, the text alone is generated. begin Ordinary_Text (Output_Object, Text); -- Nothing special in this format. end AI_Reference; procedure Local_Target (Output_Object : in out Text_Output_Type; Text : in String; Target : in String) is -- Generate a local target. This marks the potential target of local -- links identified by "Target". Text is the text of the target. -- For hyperlinked formats, this should generate a link target; -- for other formats, only the text is generated. begin Ordinary_Text (Output_Object, Text); -- Nothing special in this format. end Local_Target; procedure Local_Link (Output_Object : in out Text_Output_Type; Text : in String; Target : in String; Clause_Number : in String) is -- Generate a local link to the target and clause given. -- Text is the text of the link. -- For hyperlinked formats, this should generate a link; -- for other formats, only the text is generated. begin Ordinary_Text (Output_Object, Text); -- Nothing special in this format. end Local_Link; procedure Local_Link_Start (Output_Object : in out Text_Output_Type; Target : in String; Clause_Number : in String) is -- Generate a local link to the target and clause given. -- The link will surround text until Local_Link_End is called. -- Local_Link_End must be called before this routine can be used again. -- For hyperlinked formats, this should generate a link; -- for other formats, only the text is generated. begin null; -- No link, nothing to do. end Local_Link_Start; procedure Local_Link_End (Output_Object : in out Text_Output_Type; Target : in String; Clause_Number : in String) is -- End a local link for the target and clause given. -- This must be in the same paragraph as the Local_Link_Start. -- For hyperlinked formats, this should generate a link; -- for other formats, only the text is generated. begin null; -- No link, nothing to do. end Local_Link_End; procedure URL_Link (Output_Object : in out Text_Output_Type; Text : in String; URL : in String) is -- Generate a link to the URL given. -- Text is the text of the link. -- For hyperlinked formats, this should generate a link; -- for other formats, only the text is generated. begin Ordinary_Text (Output_Object, Text); -- Nothing special in this format. end URL_Link; procedure Picture (Output_Object : in out Text_Output_Type; Name : in String; Descr : in String; Alignment : in ARM_Output.Picture_Alignment; Height, Width : in Natural; Border : in ARM_Output.Border_Kind) is -- Generate a picture. -- Name is the (simple) file name of the picture; Descr is a -- descriptive name for the picture (it will appear in some web -- browsers). -- We assume that it is a .GIF or .JPG and that it will be present -- in the same directory as the input files and the same directory as -- the .HTML output files. -- Alignment specifies the picture alignment. -- Height and Width specify the picture size in pixels. -- Border specifies the kind of border. begin case Alignment is when ARM_Output.Inline | ARM_Output.Float_Left | ARM_Output.Float_Right => -- Inside a paragraph: Ordinary_Text (Output_Object, "[Picture: " & Name & " - " & Descr & "]"); when ARM_Output.Alone_Left | ARM_Output.Alone_Right | ARM_Output.Alone_Center => -- Not in a paragraph: Ada.Text_IO.New_Line (Output_Object.Output_File); Ada.Text_IO.Put_Line (Output_Object.Output_File, "[Picture: " & Name & " - " & Descr & "]"); Ada.Text_IO.New_Line (Output_Object.Output_File); end case; end Picture; end ARM_Text;