From 2791de95c98a33f5d21372ad0db72a06ae5f6291 Mon Sep 17 00:00:00 2001 From: Frank Zechert Date: Fri, 31 Mar 2023 22:57:18 +0200 Subject: [PATCH] implements all control functions of ECMA-48 --- .gitignore | 2 + Cargo.toml | 16 + LICENSE.txt | 21 + src/c0.rs | 330 ++++ src/c1.rs | 319 ++++ src/control_sequences.rs | 2446 ++++++++++++++++++++++++++ src/control_strings.rs | 10 + src/independent_control_functions.rs | 113 ++ src/lib.rs | 166 ++ src/modes.rs | 123 ++ 10 files changed, 3546 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 LICENSE.txt create mode 100644 src/c0.rs create mode 100644 src/c1.rs create mode 100644 src/control_sequences.rs create mode 100644 src/control_strings.rs create mode 100644 src/independent_control_functions.rs create mode 100644 src/lib.rs create mode 100644 src/modes.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..be7f8ed --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "ansi" +description = "This library contains all ANSI Escape Codes that are defined in the ISO 6429 Standard" +version = "0.1.0" +edition = "2021" + +authors = ["Frank Zechert "] +repository = "" +license = "MIT" + +# crates.io +publish = false +keywords = ["ansi", "escape codes", "ISO 6429", "ECMA 48", "ANSI X3.64"] +categories = ["command-line-interface"] + +[dependencies] diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..5db5c6d --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Frank Zechert + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/c0.rs b/src/c0.rs new file mode 100644 index 0000000..8a4b682 --- /dev/null +++ b/src/c0.rs @@ -0,0 +1,330 @@ +//! Elements of the C0 set. +//! +//! These control functions are represented in 7-bit codes by bit combinations from `00/00` to `01/15`. +//! +//! The 3-character escape sequence designating and invoking this C0 set is `ESC 02/01 04/00`, +//! see [`ANNOUNCER_SEQUENCE`]. +//! +//! It is assumed that even with no invoked C0 set, the control character `ESCAPE` (`ESC`) is always available, and is +//! represented by bit combination `01/00`. +//! +//! ## Overview of the C0 Set +//! +//! | Row Number | Column `00` | Column `01` | +//! | ---------: | :---------: | :---------: | +//! | `00` | [`NUL`] | [`DLE`] | +//! | `01` | [`SOH`] | [`DC1`] | +//! | `02` | [`STX`] | [`DC2`] | +//! | `03` | [`ETX`] | [`DC3`] | +//! | `04` | [`EOT`] | [`DC4`] | +//! | `05` | [`ENQ`] | [`NAK`] | +//! | `06` | [`ACK`] | [`SYN`] | +//! | `07` | [`BEL`] | [`ETB`] | +//! | `08` | [`BS`] | [`CAN`] | +//! | `09` | [`HT`] | [`EM`] | +//! | `10` | [`LF`] | [`SUB`] | +//! | `11` | [`VT`] | [`ESC`] | +//! | `12` | [`FF`] | [`IS4`] | +//! | `13` | [`CR`] | [`IS3`] | +//! | `14` | [`SO`] | [`IS2`] | +//! | `15` | [`SI`] | [`IS1`] | +use crate::ControlFunction; + +macro_rules! c0 { + ($xx:literal/$yy:literal) => { + ControlFunction::new_c0(ascii!($xx / $yy)) + }; +} + +/// Announcer Sequence for C0. +/// +/// Designate the C0 set of control functions as the active set of control functions. +/// +/// ## Note 1 +/// +/// The use of this escape sequence implies that all control function of this C0 set must be implemented. +/// +/// ## Note 2 +/// +/// It is assumed that even with no invoked C0 set, the control character `ESCAPE` (`ESC`) is available, and is +/// represented by the bit combination `01/11`. +pub const ANNOUNCER_SEQUENCE: &'static str = ascii!(01 / 11, 02 / 01, 04 / 00); + +/// Acknowledge. +/// +/// `ACK` is transmitted by a receiver as an affirmative response to the sender. +/// +/// The use of `ACK` is defined in ISO 1745. +pub const ACK: ControlFunction = c0!(00 / 06); + +/// Bell. +/// +/// `BEL` is used when there is a need to call for attention; it may control alarm or attention devices. +pub const BEL: ControlFunction = c0!(00 / 07); + +/// Backspace. +/// +/// `BS` causes the active data position to be moved one character position in the data component in the direction +/// opposite to that of the implicit movement. +/// +/// The direction of the implicit movement depends on the parameter value of Select Implicit Movement Direction +/// (`SIMD`). +pub const BS: ControlFunction = c0!(00 / 08); + +/// Cancel. +/// +/// `CAN` is used to indicate that the data preceding it in the data stream is in error. As a result, this data shall be +/// ignored. The specific meaning of this control function shall be defined for each application and/or between sender +/// and recipient. +pub const CAN: ControlFunction = c0!(01 / 08); + +/// Carriage Return. +/// +/// The effect of `CR` depends on the setting of the DEVICE COMPONENT SELECT MODE (`DCSM`) and on the parameter value of +/// SELECT IMPLICIT MOVEMENT DIRECTION (`SIMD`). +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION and with the parameter value of `SIMD` equal to +/// `0`, `CR` causes the active presentation position to be moved to the line home position of the same line in the +/// presentation component. The line home position is established by the parameter value of SET LINE HOME (`SLH`). +/// +/// With a parameter value of `SIMD` equal to `1`, `CR` causes the active presentation position to be moved to the line +/// limit position of the same line in the presentation component. The line limit position is established by the +/// parameter value of SET LINE LIMIT (`SSL`). +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA and with a parameter of `SIMD` equal to `0`, `CR` causes +/// the active data position to be moved to the line home position of the same line in the data component. The line home +/// position is established by the parameter value of SET LINE HOME (`SLH`). +/// +/// With a parameter value of `SIMD` equal to `1`, `CR` causes the active data position to be moved to the line limit +/// position of the same line in the data component. The line limit position is established by the parameter value of +/// SET LINE LIMIT (`SSL`). +pub const CR: ControlFunction = c0!(00 / 13); + +/// Device Control One. +/// +/// `DC1` is primarily intended for tuning on or starting an ancillary device. If it is not required for this purpose, +/// it may be used to restore a device to the basic mode of operation (see also [`DC2`] and [`DC3`]), or any other +/// device control function not provided by other DCs. +/// +/// ## Note +/// +/// When used for data flow control, `DC1` is sometimes called `X-ON`. +pub const DC1: ControlFunction = c0!(01 / 01); + +/// Device Control Two. +/// +/// `DC2` is primarily intended for tuning on or starting an ancillary device. If it is not required for this purpose, +/// it may be used to set a device to a special mode of operation (in which case [`DC1`] is used to restore the device +/// to the basic mode), or for any other device control function not provided by other DCs. +pub const DC2: ControlFunction = c0!(01 / 02); + +/// Device Control Three. +/// +/// `DC3` is primarily intended for turning off or stopping an ancillary device. This function may be a secondary level +/// stop, for example wait, pause, stand-by or halt (in which case [`DC1`] is used to restore normal operation). If it +/// is not required for this purpose, it may be used for any other device control function not provided by other DCs. +pub const DC3: ControlFunction = c0!(01 / 03); + +/// Device Control Four. +/// +/// `DC4` is primarily intended for turning off, stopping or interrupting an ancillary device. If it is not required for +/// this purpose, it may be used for any other device control function not provided by other DCs. +pub const DC4: ControlFunction = c0!(01 / 04); + +/// Data Link Escape. +/// +/// `DLE` is used exclusively to provide supplementary transmission control functions. +/// +/// The use of `DLE` is defined in ISO 1745. +pub const DLE: ControlFunction = c0!(01 / 00); + +/// End Of Medium. +/// +/// `EM` is used to identify the physical end of a medium, or the end of the used portion of a medium, or the end of the +/// wanted portion of data recorded on a medium. +pub const EM: ControlFunction = c0!(01 / 09); + +/// Enquiry. +/// +/// `ENQ` is transmitted by a sender as a request for a response from a receiver. +/// +/// The use of `EOT` is defined in ISO 1745. +pub const ENQ: ControlFunction = c0!(00 / 05); + +/// End Of Transmission. +/// +/// `EOT` is used to indicate the conclusion of the transmission of one or more texts. +/// +/// The use of `EOT` is defined in ISO 1745. +pub const EOT: ControlFunction = c0!(00 / 04); + +/// Escape. +/// +/// `ESC` is used for code extension purposes. It causes the meanings of a limited number of bit combinations following +/// it in the data stream to be changed. +/// +/// The use of `ESC` is defined in Standard ECMA-35. +pub const ESC: ControlFunction = c0!(01 / 11); + +/// End Of Transmission Block. +/// +/// `ETB` is used to indicate the end of a block of data where the data are divided into such blocks for transmission +/// purposes. +/// +/// The use of `ETB` is defined in ISO 1745. +pub const ETB: ControlFunction = c0!(01 / 07); + +/// End Of Text. +/// +/// `ETX` is used to indicate the end of a text. +/// +/// The use of `ETX` is defined in ISO 1745. +pub const ETX: ControlFunction = c0!(00 / 03); + +/// Form Feed. +/// +/// `FF` causes the active presentation position to be moved to the corresponding character position of the line at the +/// page home position of the next form or page in the presentation component. The page home position is established by +/// the parameter value of SET PAGE HOME (`SPH`). +pub const FF: ControlFunction = c0!(00 / 12); + +/// Character Tabulation. +/// +/// `HT` causes the active presentation position to be moved to the following character tabulation stop in the +/// presentation component. +/// +/// In addition, if that following character tabulation stop has been set by TABULATION ALIGN CENTRE (`TAC`), TABULATION +/// ALIGN LEADING EDGE (`TALE`), TABULATION ALIGN TRAILING EDGE (`TATE`) or TABULATION CENTERED ON CHARACTER (`TCC`), +/// `HT` indicates the beginning of a string of text which is to be positioned within a line according to the properties +/// of that tabulation stop. The end of the string is indicated by the next occurrence of `HT` or CARRIAGE RETURN +/// ([`CR`]) or NEXT LINE ([`NEL`][crate::c1::NEL]) in the data stream. +pub const HT: ControlFunction = c0!(00 / 09); + +/// Information Separator One (US - Unit Separator). +/// +/// `IS1` is used to separate and qualify data logically; its specific meaning has to be defined for each application. +/// If this control function is used in hierarchical order, it may delimit a data item called a unit. +pub const IS1: ControlFunction = c0!(01 / 15); + +/// Information Separator Two (RS - Record Separator). +/// +/// `IS2` is used to separate and qualify data logically; its specific meaning has to be defined for each application. +/// If this control function is used in hierarchical order, it may delimit a data item called a record. +pub const IS2: ControlFunction = c0!(01 / 14); + +/// Information Separator Three (GS - Group Separator). +/// +/// `IS3` is used to separate and qualify data logically; its specific meaning has to be defined for each application. +/// If this control function is used in hierarchical order, it may delimit a data item called a group. +pub const IS3: ControlFunction = c0!(01 / 13); + +/// Information Separator Four (FS - File Separator). +/// +/// `IS4` is used to separate and qualify data logically; its specific meaning has to be defined for each application. +/// If this control function is used in hierarchical order, it may delimit a data item called a file. +pub const IS4: ControlFunction = c0!(01 / 12); + +/// Line Feed. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `LF` causes the active presentation position +/// to be moved to the corresponding character position of the following line in the presentation component. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `LF` causes the active data position to be moved to the +/// corresponding character position of the following line in the data component. +pub const LF: ControlFunction = c0!(00 / 10); + +/// Locking-Shift Zero. +/// +/// `LS0` is used for code extension purposes. It causes the meanings of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `LS0` is defined in Standard ECMA-35. +/// +/// ## Note +/// +/// `LS0` is used in 8-bit environments only; in 7-bit environments SHIFT-IN ([`SI`]) is used instead. +pub const LS0: ControlFunction = c0!(00 / 15); + +/// Locking-Shift One. +/// +/// `LS1` is used for code extension purposes. It causes the meanings of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `LS1` is defined in Standard ECMA-35. +/// +/// ## Note +/// +/// `LS1` is used in 8-bit environments only; in 7-bit environments SHIFT-OUT ([`SO`]) is used instead. +pub const LS1: ControlFunction = c0!(00 / 14); + +/// Negative Acknowledge. +/// +/// `NAK` is transmitted by a receiver as a negative response to the sender. +/// +/// The use of `NAK` is defined in ISO 1745. +pub const NAK: ControlFunction = c0!(01 / 05); + +/// Null. +/// +/// `NUL` is used for media-fill or time-fill. `NUL` characters may be inserted into, or removed from, a data stream +/// without affecting information content of that stream, but such action may affect the information layout and/or the +/// control of equipment. +pub const NUL: ControlFunction = c0!(00 / 00); + +/// Shift-In. +/// +/// `SI` is used for code extension purposes. It causes the meanings of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `SI` is defined in Standard ECMA-35. +/// +/// ## Note +/// +/// `SI` is used in 7-bit environments only; in 8-bit environments LOCKING-SHIFT ZERO (`LS0`) is used instead. +pub const SI: ControlFunction = c0!(00 / 15); + +/// Shift-Out. +/// +/// `SO` is used for code extension purposes. It causes the meanings of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `SI` is defined in Standard ECMA-35. +/// +/// ## Note +/// +/// `SO` is used in 7-bit environments only; in 8-bit environments LOCKING-SHIFT ONE (`LS1`) is used instead. +pub const SO: ControlFunction = c0!(00 / 14); + +/// Start of Heading. +/// +/// `SOH` is used to indicate the beginning of a heading. +/// +/// The use of `SOH` is defined in ISO 1745. +pub const SOH: ControlFunction = c0!(00 / 01); + +/// Start of Text. +/// +/// `STX` is used to indicate the beginning of a text and the ned of a heading. +/// +/// The use of `STX` is defined in ISO 1745. +pub const STX: ControlFunction = c0!(00 / 02); + +/// Substitute. +/// +/// `SUB` is used in the place of a character that has been found to be invalid or in error. `SUB` is intended to be +/// introduced by automatic means. +pub const SUB: ControlFunction = c0!(01 / 10); + +/// Synchronous Idle. +/// +/// `SYN` is used by a synchronous transmission system in the absence of any other character (idle condition) to provide +/// a signal from which synchronism may be achieved or retained between data terminal equipment. +/// +/// The use of `SYN` is defined in ISO 1745. +pub const SYN: ControlFunction = c0!(01 / 06); + +/// Line Tabulation. +/// +/// `VT` causes the active presentation position to be moved in the presentation component to the corresponding +/// character position on the line at which the following line tabulation stop is set. +pub const VT: ControlFunction = c0!(00 / 11); diff --git a/src/c1.rs b/src/c1.rs new file mode 100644 index 0000000..b0f38c9 --- /dev/null +++ b/src/c1.rs @@ -0,0 +1,319 @@ +//! Elements of the C1 set. +//! +//! These control functions are represented in 7-bit codes by escape sequences of the form `ESC Fe`, where `ESC` is +//! represented by bit combination `01/11` and `Fe` is represented by a bit combination from `04/00` to `05/15`. +//! +//! The unallocated bit combinations are reserved for future standardization and shall not be used. +//! +//! The 3-character escape sequence designating and invoking this c1 set is `ESC 02/06 04/00` and `ESC 02/02 F`. +//! see [`ANNOUNCER_SEQUENCE`], and [`ALTERNATIVE_ANNOUNCER_SEQUENCE`]. +//! +//! ## Overview of the C1 Set +//! +//! | Row Number | Column `04` | Column `05` | +//! | ---------: | :---------: | :---------: | +//! | `00` | -- | [`DCS`] | +//! | `01` | -- | [`PU1`] | +//! | `02` | [`BPH`] | [`PU2`] | +//! | `03` | [`NBH`] | [`STS`] | +//! | `04` | -- | [`CCH`] | +//! | `05` | [`NEL`] | [`MW`] | +//! | `06` | [`SSA`] | [`SPA`] | +//! | `07` | [`ESA`] | [`EPA`] | +//! | `08` | [`HTS`] | [`SOS`] | +//! | `09` | [`HTJ`] | -- | +//! | `10` | [`VTS`] | [`SCI`] | +//! | `11` | [`PLD`] | [`CSI`] | +//! | `12` | [`PLU`] | [`ST`] | +//! | `13` | [`RI`] | [`OSC`] | +//! | `14` | [`SS2`] | [`PM`] | +//! | `15` | [`SS3`] | [`APC`] | + +use crate::ControlFunction; + +macro_rules! c1 { + ($xx:literal/$yy:literal) => { + ControlFunction::new_c1(ascii!($xx / $yy)) + }; +} + +/// Announcer Sequence for C1. +/// +/// Designate the C1 set of control functions as the active set of control functions. +/// +/// ## Note +/// +/// The use of this escape sequence implies that all control function of this c1 set must be implemented. +pub const ANNOUNCER_SEQUENCE: &'static str = ascii!(01 / 11, 02 / 06, 04 / 00); + +/// Alternative Announcer Sequence for C1. +/// +/// Designate the C1 set of control functions as the active set of control functions. +/// +/// ## Note +/// +/// The use of this escape sequence implies that all control function of this c1 set must be implemented. +pub const ALTERNATIVE_ANNOUNCER_SEQUENCE: &'static str = ascii!(01 / 11, 02 / 02, 04 / 06); + +/// Application Program Command. +/// +/// `APC` is used as the opening delimiter of a control string for application program use. The command string following +/// may consist of bit combinations in the range `00/08` to `00/13` and `02/00` to `07/14`. The control string is closed +/// by the terminating delimiter String Terminator (`ST`). The interpretation of the command string depends on the +/// relevant application program. +pub const APC: ControlFunction = c1!(05 / 15); + +/// Break Permitted Here. +/// +/// `BPH` is used to indicate a point where a line break may occur when text is formatted. `BPH` may occur between two +/// graphic characters, either or both of which may be `SPACE`. +pub const BPH: ControlFunction = c1!(04 / 02); + +/// Cancel Character. +/// +/// `CCH` is used to indicate that both the preceding graphic character in the data stream (represented by one or more +/// bit combinations), including `SPACE`, and the control function `CCH` itself are to be ignored for further +/// interpretation of the data stream. +/// +/// If the character preceding `CCH` in the data stream is a control function (represented by one or more bit +/// combinations), the effect of `CCH` is not defined. +pub const CCH: ControlFunction = c1!(05 / 04); + +/// Control Sequence Introducer. +/// +/// `CSI` is used as the first character of a control sequence. See [control_sequences][crate::control_sequences]. +pub const CSI: ControlFunction = c1!(05 / 11); + +/// Device Control String. +/// +/// `DCS` is used as the opening delimiter of a control string for device control use. The command string following may +/// consist of bit combinations in the range `00/08` to `00/13` and `02/00` to `07/14`. The control string is closed by +/// the terminating delimiter STRING TERMINATOR (`ST`). +/// +/// The command string represents either one or more commands for the receiving device, or one or more status reports +/// from the sending device. The purpose and the format of the command string are specified by the most recent +/// occurrence of IDENTIFY DEVICE CONTROL STRING (`IDCS`), if any, or depend on the sending and/or the receiving device. +pub const DCS: ControlFunction = c1!(05 / 00); + +/// End Of Guarded Area. +/// +/// `EPA` is used to indicate that the active presentation position is the last of a string of character positions in +/// the presentation component, the contents of which are protected against manual alteration, are guarded against +/// transmission or transfer, depending on the setting of GUARDED AREA TRANSFER MODE (`GATM`), and may be protected +/// against erasure, depending on the setting of the ERASURE MODE (`ERM`). The beginning of this string is indicated +/// by START OF GUARDED AREA ([`SPA`]). +/// +/// ## Note +/// +/// The control functions for area definition ([`DAQ`][crate::control_sequences::DAQ], [`EPA`], [`ESA`], [`SPA`], +/// [`SSA`]) should not be used within an `SRS` string or an `SDS` string. +pub const EPA: ControlFunction = c1!(05 / 07); + +/// End Of Selected Area. +/// +/// `ESA` is used to indicate that the active presentation position is the last of a string of character positions in +/// the presentation component, the contents of which are eligible to be transmitted in the form of a data stream or +/// transferred to an auxiliary input/output device. The beginning of the string is indicated by START OF SELECTED +/// AREA ([`SSA`]) +/// +/// ## Note +/// +/// The control functions for area definition ([`DAQ`][crate::control_sequences::DAQ], [`EPA`], [`ESA`], [`SPA`], +/// [`SSA`]) should not be used within an `SRS` string or an `SDS` string. +pub const ESA: ControlFunction = c1!(04 / 07); + +/// Character Tabulation With Justification. +/// +/// `HTJ` causes the contents of the active field (the field in the presentation component that contains the active +/// presentation position) to be shifted forward so that it ends at the character position preceding the following +/// character tabulation stop. The active presentation position is moved to that following character tabulation stop. +/// The character positions which precede the beginning of the shifted string are put into the erased state. +pub const HTJ: ControlFunction = c1!(04 / 09); + +/// Character Tabulation Set. +/// +/// `HTS` causes a character tabulation stop to be set at the active presentation position in the presentation +/// component. +/// +/// The number of liens affected depends on the setting of the TABULATION STOP MODE (`TSM`). +pub const HTS: ControlFunction = c1!(04 / 08); + +/// Message Waiting. +/// +/// `MW` is used to set a message waiting indicator in the receiving device. An appropriate acknowledgement to the +/// receipt of `MW` may be given by using DEVICE STATUS REPORT (`DSR`). +pub const MW: ControlFunction = c1!(05 / 05); + +/// No Break Here. +/// +/// `NBH` is used to indicate a point where a line break shall not occur when text is formatted. `NBH` may occur between +/// two graphic characters either or both of which may be SPACE. +pub const NBH: ControlFunction = c1!(04 / 03); + +/// Next Line. +/// +/// The effect of `NEL` depends on the setting of the DEVICE COMPONENT SELECT MODE (`DCSM`) and on the parameter value +/// of SELECT IMPLICIT MOVEMENT DIRECTION (`SIMD`). +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION and with a parameter value of `SIMD` equal to +/// `0`, `NEL` causes the active presentation position to be moved to the line home position of the following line in +/// the presentation component. The line home position is established by the parameter value of SET LINE HOME (`SLH`). +/// +/// With a parameter value of `SIMD` equal to `1`, `NEL` causes the active presentation position to be moved to the line +/// limit position of the following line in the presentation component. The line limit position is established by the +/// parameter value of SET LINE LIMIT (`SLL`). +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA and with a parameter value of `SIMD` equal to `0`, `NEL` +/// causes the active data position to be moved to the line home position of the following line in the data component. +/// The line home position is established by the parameter value of SET LINE HOME (`SLH`). +/// +/// With a parameter value of `SIMD` equal to `1`, `NEL` causes the active data position to be moved to the line limit +/// position of the following line in the data component. The line limit position is established by the parameter value +/// of SET LINE LIMIT (`SLL`). +pub const NEL: ControlFunction = c1!(04 / 05); + +/// Operating System Command +/// +/// `OSC` is used as the opening delimiter of a control string for operating system use. The command string following +/// may consist of a sequence of bit combinations in the range `00/08` to `00/13` and `02/00` to `07/14`. The control +/// string is closed by the terminating delimiter STRING TERMINATOR (`ST`). The interpretation of the command string +/// depends on the relevant operating system. +pub const OSC: ControlFunction = c1!(05 / 13); + +/// Partial Line Forward. +/// +/// `PLD` causes the active presentation position to be moved in the presentation component to the corresponding +/// position of an imaginary line with a partial offset in the direction of the line progression. This offset should be +/// sufficient either to image following characters as subscripts until the first following occurrence of PARTIAL LINE +/// BACKWARD (`PLU`) in the data stream, or, if preceding characters were imaged as superscripts, to restore imaging +/// of following characters to the active line (the line that contains the active presentation position). +/// +/// Any interactions between `PLD` and format effectors other than `PLU` are not defined. +pub const PLD: ControlFunction = c1!(04 / 11); + +/// Partial Line Backwards. +/// +/// `PLU` causes the active presentation position to be moved in the presentation component to the corresponding +/// position of an imaginary line with a partial offset in the direction opposite to that of the line progression. This +/// offset should be sufficient either to image following characters as superscripts until the first following +/// occurrence of PARTIAL LINE FORWARD (`PLD`) in the data stream, or, if preceding characters were imaged as +/// subscripts, to restore imaging of following characters to the active line (the line that contains the active +/// presentation position). +/// +/// Any interactions between `PLU` and format effectors other than `PLD` are not defined. +pub const PLU: ControlFunction = c1!(04 / 12); + +/// Privacy Message. +/// +/// `PM` is used as the opening delimiter of a control string for privacy message use. The command string following may +/// consist of a sequence of bit combinations in the range `00/08` to `00/13` and `02/00` to `07/14`. The control string +/// is closed by the terminating delimiter STRING TERMINATOR (`ST`). The interpretation of the command string depends +/// on the relevant privacy discipline. +pub const PM: ControlFunction = c1!(05 / 14); + +/// Private Use One. +/// +/// `PU1` is reserved for a function without standardized meaning for private use as required, subject to the prior +/// agreement between the sender and the recipient of the data. +pub const PU1: ControlFunction = c1!(05 / 01); + +/// Private Use Two. +/// +/// `PU2` is reserved for a function without standardized meaning for private use as required, subject to the prior +/// agreement between the sender and the recipient of the data. +pub const PU2: ControlFunction = c1!(05 / 02); + +/// Reverse Line Feed. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `RI` causes the active presentation position to +/// be moved in the presentation component to the corresponding character position of the preceding line feed. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `RI` causes the active data position to be moved in the +/// data component to the corresponding character position of the preceding line. +pub const RI: ControlFunction = c1!(04 / 13); + +/// Single Character Introducer. +/// +/// `SCI` and the bit combination following it are used to represent a control function or a graphic character. The bit +/// combination following `SCI` must be from `00/08` to `00/13` or `02/00` to `07/14`. The use of `SCI` is reserved +/// for future standardization. +pub const SCI: ControlFunction = c1!(05 / 10); + +/// Start of String. +/// +/// `SOS` is used as the opening delimiter of a control string. The character string following may consist of any bit +/// combination, except those representing `SOS` or STRING TERMINATOR (`ST`). The control string is closed by the +/// terminating delimiter STRING TERMINATOR (`ST`). The interpretation of the character string depends on the +/// application. +pub const SOS: ControlFunction = c1!(05 / 08); + +/// Start of Guarded Area. +/// +/// `SPA` is used to indicate that the active presentation position is the first of a string of character positions in +/// the presentation component, the contents of which are protected against manual alteration, are guarded against +/// transmission or transfer, depending on the setting of the GUARDED AREA TRANSFER MODE (`GATM`) and may be protected +/// against erasure, depending on the setting of the ERASURE MODE (`ERM`). The end of this string is indicated by +/// END OF GUARDED AREA (`EPA`). +/// +/// ## Note +/// +/// The control functions for area definition (`DAQ`, `EPA`, `ESA`, `SPA`, `SSA`) should not be used within an `SRS` +/// string or an `SDS` string. +pub const SPA: ControlFunction = c1!(05 / 06); + +/// Start of Selected Area. +/// +/// `SSA` is used to indicate that the active presentation position is the first of a string of character positions in +/// the presentation component, the contents of which are eligible to be transmitted in the form of a data stream or +/// transferred to an auxilliary input/output device. +/// +/// The end of this string is indicated by END OF SELECTED AREA ([`ESA`]). The string of characters actually transmitted +/// or transferred depends on the setting of the GUARDED AREA TRANSFER MODE ([`GATM`][crate::modes::GATM]) and on any +/// guarded areas established by DEFINE AREA QUALIFICATION ([`DAQ`][crate::control_sequences::DAQ]), or by START OF +/// GUARDED AREA ([`SPA`]) and END OF GUARDED AREA ([`EPA`]). +/// +/// ## Note +/// +/// The control functions for area definition (`DAQ`, `EPA`, `ESA`, `SPA`, `SSA`) should not be used within an `SRS` +/// string or an `SDS` string. +pub const SSA: ControlFunction = c1!(04 / 06); + +/// Single-Shift Two. +/// +/// `SS2` is used for code extension purposes. It causes the meanings of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `SS2` is defined in Standard ECMA-35. +pub const SS2: ControlFunction = c1!(04 / 14); + +/// Single-Shift Three. +/// +/// `SS3` is used for code extension purposes. It causes the meanings of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `SS3` is defined in Standard ECMA-35. +pub const SS3: ControlFunction = c1!(04 / 15); + +/// String Terminator. +/// +/// `ST` is used as the closing delimiter of a control string opened by APPLICATION PROGRAM COMMAND (`APC`), DEVICE +/// CONTROL STRING (`DCS`), OPERATING SYSTEM COMMAND (`OSC`), PRIVACY MESSAGE (`PM`), or START OF STRING (`SOS`). +pub const ST: ControlFunction = c1!(05 / 12); + +/// Set Transmit State. +/// +/// `STS` is used to establish the transmit state in the receiving device. In this state the transmission of data from +/// the device is possible. +/// +/// The actual initiation of transmission of data is performed by a data communication or input/output interface control +/// procedure which is outside the scope of this Standard. +/// +/// The transmit state is established either by `STS` appearing in the received data stream or by the operation of an +/// appropriate key on a keyboard. +pub const STS: ControlFunction = c1!(05 / 03); + +/// Line Tabulation Set. +/// +/// `VTS` causes a line tabulation stop to be set at the active line (the line that contains the active presentation +/// position). +pub const VTS: ControlFunction = c1!(04 / 10); diff --git a/src/control_sequences.rs b/src/control_sequences.rs new file mode 100644 index 0000000..7ba6597 --- /dev/null +++ b/src/control_sequences.rs @@ -0,0 +1,2446 @@ +//! Control Sequences. +//! +//! A control sequence is a string of bit combinations starting with the control function Control Sequence Introducer +//! (`CSI`), followed by one or more bit combinations representing parameters, if any, and by one or more bit +//! combinations identifying the control function. The control function `CSI` itself is an element of the +//! [C1][crate::c1] set. +//! +//! ## Overview of the Control Sequences +//! +//! ### Without Intermediate Bytes +//! +//! | Row Number | Column `04` | Column `05` | Column `06` | +//! | ---------: | :---------: | :---------: | :---------: | +//! | `00` | [`ICH`] | [`DCH`] | [`HPA`] | +//! | `01` | [`CUU`] | [`SSE`] | [`HPR`] | +//! | `02` | [`CUD`] | [`CPR`] | [`REP`] | +//! | `03` | [`CUF`] | [`SU`] | [`DA`] | +//! | `04` | [`CUB`] | [`SD`] | [`VPA`] | +//! | `05` | [`CNL`] | [`NP`] | [`VPR`] | +//! | `06` | [`CPL`] | [`PP`] | [`HVP`] | +//! | `07` | [`CHA`] | [`CTC`] | [`TBC`] | +//! | `08` | [`CUP`] | [`ECH`] | [`SM`] | +//! | `09` | [`CHT`] | [`CVT`] | [`MC`] | +//! | `10` | [`ED`] | [`CBT`] | [`HPB`] | +//! | `11` | [`EL`] | [`SRS`] | [`VPB`] | +//! | `12` | [`IL`] | [`PTX`] | [`RM`] | +//! | `13` | [`DL`] | [`SDS`] | [`SGR`] | +//! | `14` | [`EF`] | [`SIMD`] | [`DSR`] | +//! | `15` | [`EA`] | -- | [`DAQ`] | +//! +//! ### With Intermediate Bytes `02/00` +//! +//! | Row Number | Column `04` | Column `05` | Column `06` | +//! | ---------: | :---------: | :---------: | :---------: | +//! | `00` | [`SL`] | [`PPA`] | [`TATE`] | +//! | `01` | [`SR`] | [`PPR`] | [`TALE`] | +//! | `02` | [`GSM`] | [`PPB`] | [`TAC`] | +//! | `03` | [`GSS`] | [`SPD`] | [`TCC`] | +//! | `04` | [`FNT`] | [`DTA`] | [`TSR`] | +//! | `05` | [`TSS`] | [`SLH`] | [`SCO`] | +//! | `06` | [`JFY`] | [`SLL`] | [`SRCS`] | +//! | `07` | [`SPI`] | [`FNK`] | [`SCS`] | +//! | `08` | [`QUAD`] | [`SPQR`] | [`SLS`] | +//! | `09` | [`SSU`] | [`SEF`] | -- | +//! | `10` | [`PFS`] | [`PEC`] | -- | +//! | `11` | [`SHS`] | [`SSW`] | [`SCP`] | +//! | `12` | [`SVS`] | [`SACS`] | -- | +//! | `13` | [`IGS`] | [`SAPV`] | -- | +//! | `14` | -- | [`STAB`] | -- | +//! | `15` | [`IDCS`] | [`GCC`] | -- | +//! +//! ## Note +//! +//! As intended by the standard, notation of control functions is kept identical to the definitions in the standard. +//! This means that functions in this rust module will not follow the standard snake_case rust naming convention, but +//! instead follow the ECMA standard. This is intended. +#![allow(non_snake_case)] + +use crate::{modes::Mode, ControlFunction}; + +macro_rules! sequence { + // numeric control sequence with no intermediate byte and no default value + ($xx:literal / $yy:literal, numeric $param:ident) => { + ControlFunction::new_sequence(ascii!($xx / $yy), vec![$param.to_string()]) + }; + // numeric control sequence with no intermediate byte and default value + ($xx:literal / $yy:literal, numeric $param:ident, default $default:literal) => { + ControlFunction::new_sequence( + ascii!($xx / $yy), + vec![$param.unwrap_or($default).to_string()], + ) + }; + // numeric control sequence with no intermediate byte, two parameters and default values + ($xx:literal / $yy:literal, numeric $param1:ident, default $default1:literal, numeric $param2:ident, default $default2:literal) => { + ControlFunction::new_sequence( + ascii!($xx / $yy), + vec![ + $param1.unwrap_or($default1).to_string(), + $param2.unwrap_or($default2).to_string(), + ], + ) + }; + // selective control sequence with no intermediate byte and default value + ($xx:literal / $yy:literal, selective default $param:ident) => { + ControlFunction::new_sequence( + ascii!($xx / $yy), + vec![($param.unwrap_or(Default::default()) as u32).to_string()], + ) + }; + // selective control sequence with intermediate byte and default value + ($xx1:literal / $yy1:literal, $xx2:literal / $yy2:literal, selective default $param:ident) => { + ControlFunction::new_sequence( + ascii!($xx1 / $yy1, $xx2 / $yy2), + vec![($param.unwrap_or(Default::default()) as u32).to_string()], + ) + }; + // selective control sequence with intermediate byte and two default value + ($xx1:literal / $yy1:literal, $xx2:literal / $yy2:literal, selective default $param1:ident, selective default $param2:ident) => { + ControlFunction::new_sequence( + ascii!($xx1 / $yy1, $xx2 / $yy2), + vec![ + ($param1.unwrap_or(Default::default()) as u32).to_string(), + ($param2.unwrap_or(Default::default()) as u32).to_string(), + ], + ) + }; + // numeric control sequence with intermediate byte, one parameters, and no default value + ($xx1:literal / $yy1:literal, $xx2:literal / $yy2:literal, numeric $param:ident) => { + ControlFunction::new_sequence(ascii!($xx1 / $yy1, $xx2 / $yy2), vec![$param.to_string()]) + }; + // numeric control sequence with intermediate byte, one parameters, and default value + ($xx1:literal / $yy1:literal, $xx2:literal / $yy2:literal, numeric $param:ident, default $default:literal) => { + ControlFunction::new_sequence( + ascii!($xx1 / $yy1, $xx2 / $yy2), + vec![$param.unwrap_or($default).to_string()], + ) + }; + // numeric control sequence with intermediate byte, two parameters, and no default value + ($xx1:literal / $yy1:literal, $xx2:literal / $yy2:literal, numeric $param1:ident, numeric $param2:ident) => { + ControlFunction::new_sequence( + ascii!($xx1 / $yy1, $xx2 / $yy2), + vec![$param1.to_string(), $param2.to_string()], + ) + }; + // numeric control sequence with intermediate byte, two parameters, and default values + ($xx1:literal / $yy1:literal, $xx2:literal / $yy2:literal, numeric $param1:ident, default $default1:literal, numeric $param2:ident, default $default2:literal) => { + ControlFunction::new_sequence( + ascii!($xx1 / $yy1, $xx2 / $yy2), + vec![ + $param1.unwrap_or($default1).to_string(), + $param2.unwrap_or($default2).to_string(), + ], + ) + }; + // control sequence with variadic number of selective arguments + ($xx:literal / $yy: literal, variadic selective $vector:expr) => { + ControlFunction::new_sequence( + ascii!($xx / $yy), + $vector.iter().map(|e| (*e as u32).to_string()).collect(), + ) + }; +} + +/// Cursor Backward Tabulation. +/// +/// `CBT` causes the active presentation position to be moved to the character position corresponding to the `n`-th +/// preceding character tabulation stop in the presentation component, according to the character path. +/// +/// Default value for `n` is `1`. +pub fn CBT(n: Option) -> ControlFunction { + sequence!(05 / 10, numeric n, default 1) +} + +/// Cursor Character Absolute. +/// +/// `CHA` causes the active presentation position to be moved to character position `n` in the active line in the +/// presentation component. +/// +/// Default value for `n` is `1`. +pub fn CHA(n: Option) -> ControlFunction { + sequence!(04 / 07, numeric n, default 1) +} + +/// Cursor Forward Tabulation. +/// +/// `CHT` causes the active presentation position to be moved to the character position corresponding to the `n`-th +/// following character tabulation stop in the presentation component, according to the character path. +/// +/// Default value for `n` is `1`. +pub fn CHT(n: Option) -> ControlFunction { + sequence!(04 / 09, numeric n, default 1) +} + +/// Cursor Next Line. +/// +/// `CNL` causes the active presentation position to be moved to the first character position of the `n`-th following +/// line in the presentation component. +/// +/// Default value for `n` is `1`. +pub fn CNL(n: Option) -> ControlFunction { + sequence!(04 / 05, numeric n, default 1) +} + +/// Cursor Preceding Line. +/// +/// `CPL` causes the active presentation position to be moved to the first character position of the `n`-th preceding +/// line in the presentation component. +/// +/// Default value for `n` is `1`. +pub fn CPL(n: Option) -> ControlFunction { + sequence!(04 / 06, numeric n, default 1) +} + +/// Active Position Report. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `CPR` is used to report the active presentation +/// position of the sending device as residing in the presentation component at the `n`-th line position according to +/// the line progression and at the `m`-th character position according to the character path. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `CPR` is used to report the active data position of the +/// sending device as residing in the data component at the `n`-th line position according to the line progression and +/// at the `m`-th character position according to the character progression. +/// +/// `CPR` may be solicited by a DEVICE STATUS REPORT (`DSR`) or be sent unsolicited. +/// +/// Default value for `n` and `m` is `1`. +pub fn CPR(n: Option, m: Option) -> ControlFunction { + sequence!(05 / 02, numeric n, default 1, numeric m, default 1) +} + +/// Valid parameter values to the function [`CTC`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum TabulationControl { + /// A character tabulation stop is set at the active presentation position. + #[default] + SetCharacterTabulationStop = 0, + + /// A line tabulation stop is set at the active line (the line that contains the active presentation position). + SetLineTabulationStop, + + /// The character tabulation stop at the active presentation position is cleared. + ClearCharacterTabulationStop, + + /// The line tabulation stop at the active line is cleared. + ClearLineTabulationStop, + + /// All character tabulation stops in the active line are cleared. + ClearCharacterTabulationStopsInLine, + + /// All character tabulation stops are cleared. + ClearAllCharacterTabulationStops, + + /// All line tabulation stops are cleared. + ClearAllLineTabulationStops, +} + +/// Cursor Tabulation Control. +/// +/// `CTC` causes one or more tabulation stops to be set or cleared in the presentation component, depending on the +/// parameter value. +/// +/// Default value for `s` is [`TabulationControl::SetCharacterTabulationStop`]. +pub fn CTC(s: Option) -> ControlFunction { + sequence!(05 / 07, selective default s) +} + +/// Cursor Left. +/// +/// `CUB` causes the active presentation position to be moved leftwards in the presentation component by `n` character +/// positions, if the character path is horizontal, or by `n` line positions if the character path is vertical. +/// +/// Default value for `n` is `1`. +pub fn CUB(n: Option) -> ControlFunction { + sequence!(04 / 04, numeric n, default 1) +} + +/// Cursor Down. +/// +/// `CUD` causes the active presentation position to be moved downwards in the presentation component by `n` line +/// positions, if the character path is horizontal, or by `n` character positions if the character path is vertical. +/// +/// Default value for `n` is `1`. +pub fn CUD(n: Option) -> ControlFunction { + sequence!(04 / 02, numeric n, default 1) +} + +/// Cursor Right. +/// +/// `CUF` causes the active presentation position to be moved rightwards in the presentation component by `n` character +/// positions, if the character path is horizontal, or by `n` line positions if the character path is vertical. +/// +/// Default value for `n` is `1`. +pub fn CUF(n: Option) -> ControlFunction { + sequence!(04 / 03, numeric n, default 1) +} + +/// Cursor Position. +/// +/// `CUP` causes the active presentation position to be moved in the presentation component ot the `n`-th line position +/// according to the line progression, and to the `m`-th character position according to the character path. +/// +/// Default value for `n` and `m` is `1`. +pub fn CUP(n: Option, m: Option) -> ControlFunction { + sequence!(04 / 08, numeric n, default 1, numeric m, default 1) +} + +/// Cursor Up. +/// +/// `CUU` causes the active presentation position to be moved upwards in the presentation component by `n` line +/// positions, if the character path is horizontal, or by `n` character positions if the character path is vertical. +/// +/// Default value for `n` is `1`. +pub fn CUU(n: Option) -> ControlFunction { + sequence!(04 / 01, numeric n, default 1) +} + +/// Cursor Line Tabulation. +/// +/// `CVT` causes the active presentation position to be moved to the character position of the line corresponding to +/// the `n`-th following line tabulation stop in the presentation component. +/// +/// Default value for `n` is `1`. +pub fn CVT(n: Option) -> ControlFunction { + sequence!(05 / 09, numeric n, default 1) +} + +/// Valid parameter values to the function [`DA`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum DeviceAttributes { + /// Request identifying device attributes from a device. + #[default] + Request, + + /// Device attributes identification code. + Identify(u32), +} + +/// Device Attributes. +/// +/// With a parameter [`DeviceAttributes::Identify`] (not equal to 0), `DA` is used to identify the device which sends +/// the `DA`. The parameter value is a device type identification code according to a register which is to be +/// established. +/// +/// If the parameter value is [`DeviceAttributes::Request`], `DA` is used to request an identifying `DA` from a device. +/// +/// Default value for `s` is [`DeviceAttributes::Request`]. +pub fn DA(s: Option) -> ControlFunction { + let v = match s { + Some(DeviceAttributes::Request) => 0, + Some(DeviceAttributes::Identify(x)) => x, + None => 0, + }; + sequence!(06 / 03, numeric v) +} + +/// Valid parameter values to the function [`DAQ`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum AreaQualification { + /// Unprotected and unguarded. + #[default] + UnprotectedUnguarded = 0, + + /// Protected and guarded. + ProtectedGuarded, + + /// Graphic character input. + GraphicCharacterInput, + + /// Numeric input. + NumericInput, + + /// Alphabetic input. + AlphabeticInput, + + /// Input aligned on the last character position of the qualified area. + InputAlignedRight, + + /// Fill with ZEROs. + FillZeros, + + /// Set a character tabulation stop at the active presentation position (the first character position of the + /// qualified area) to indicate the beginning of a field. + SetCharacterTabulationStop, + + /// Protected and unguarded + ProtectedUnguarded, + + /// Fill with SPACEs + FillSpaces, + + /// Input aligned on the first character position of the qualified area. + InputAlignedLeft, + + /// The order of the character positions in the input field is reserved, i.e. the last position in each line becomes + /// the first and vice versa; input begins at the new first position. + Reversed, +} + +/// Define Area Qualification. +/// +/// `DAQ` is used to indicate that the active presentation position in the presentation component is the first character +/// position of a qualified area. The last character position of the qualified area is the character position in the +/// presentation component immediately preceding the first character position of the following qualified area. +/// +/// The control function operates independently of the setting of the TABULATION STOP MODE (`TSM`). The character +/// tabulation stop set by parameter value [`AreaQualification::SetCharacterTabulationStop`] applies to the active line +/// only. +/// +/// The default value for `s` is [`AreaQualification::UnprotectedUnguarded]. +/// +/// ## Note +/// +/// The control functions for area definitions ([`DAQ`], [`EPA`][crate::c1::EPA], [`ESA`][crate::c1::ESA], +/// [`SPA`][crate::c1::SPA], [`SSA`][crate::c1::SSA]) should not be used within an [`SRS`] string or an [`SDS`] string. +pub fn DAQ(s: Option) -> ControlFunction { + sequence!(06 / 15, selective default s) +} + +/// Delete Character. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DSCM`) is set to PRESENTATION, `DCH` causes the contents of the active +/// presentation position and, depending on the setting of the CHARACTER EDITING MODE (`HEM`), the contents of the `n-1` +/// preceding or following character positions to be removed from the presentation component. The resulting gap is +/// closed by shifting the contents of the adjacent character positions towards the active presentation position. At the +/// other end of the shifted part, `n` character positions are put into the erased state. +/// +/// The extent of the shifted part is established by SELECT EDITING EXTEND (`SEE`). +/// +/// The effect of `CDH` on the start or end of a selected area, the start or end of a qualified area, or a tabulation +/// stop in the shifted part is undefined. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `DCH` causes the contents of the active data position +/// and, depending on the setting of the CHARACTER EDITING MODE (`HEM`), the contents of the `n-1` preceding or +/// following character positions to be removed from the data component. The resulting gap is closed by shifting the +/// contents of the adjacent character positions towards the active data position. At the other end of the shifted part, +/// `n` character positions are put into the erased state. +/// +/// Default value for `n` is `1`. +pub fn DCH(n: Option) -> ControlFunction { + sequence!(05 / 00, numeric n, default 1) +} + +/// Delete Line. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `DL` causes the contents of the active line +/// (the line that contains the active presentation position) and, depending on the setting of the LINE EDITING MODE +/// (`VEM`), the contents of the `n-1` preceding or following lines to be removed from the presentation component. The +/// resulting gap is closed by shifting the contents of a number of adjacent lines towards the active line. At the other +/// end of the shifted part, `n` lines are put into the erased state. +/// +/// The active presentation position is moved to the line home position in the active line. The line home position is +/// established by the parameter value of SET LINE HOME (`SLH`). If the TABULATION STOP MODE (`TSM`) is set to SINGLE, +/// character tabulation stops are cleared in the lines that are put into the erased state. +/// +/// The extent of the shifted part is established by SELECT EDITING EXTEND (`SEE`). +/// +/// Any occurrences of the start or end of a selected area, the start or end of a qualified area, or a tabulation stop +/// in the shifted part, are also shifted. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `DL` causes the contents of the active line (the line +/// that contains the active data position) and, depending on the setting of the LINE EDITING MODE (`VEM`), the contents +/// of the `n-1` preceding or following lines to be removed from the data component. The resulting gap is closed by +/// shifting the contents of a number of adjacent lines towards the active line. At the other end of the shifted part, +/// `n` lines are put into the erased state. The active data position is moved to the lines home position in the active +/// line. The line home position is established by the parameter value of SET LINE HOME (`SLH`). +/// +/// The default value for `n` is `1`. +pub fn DL(n: Option) -> ControlFunction { + sequence!(04 / 13, numeric n, default 1) +} + +/// Valid parameter values to the function [`DSR`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum DeviceStatusReport { + /// The device is ready, no malfunction detected + #[default] + Ready = 0, + + /// The device is busy, another `DSR` must be requested later. + BusyRepeat, + + /// The device is busy, another `DSR` will be sent later. + BusyLater, + + /// Some malfunction detected, another `DSR` must be requested later. + MalfunctionRepeat, + + /// Some malfunction detected, another `DSR` will be sent later. + MalfunctionLater, + + /// A device status report is requested. + RequestDeviceStatusReport, + + /// A report of the active presentation position or of the active data position in the form of ACTIVE POSITION + /// REPORT (`CPR`) is requested. + RequestActivePositionReport, +} + +/// Device Status Report. +/// +/// `DSR` is used either to report the status of the sending device or to request a status report from the receiving +/// device, depending on the parameter value. +/// +/// `DSR` with parameter value [`DeviceStatusReport::Ready`], [`DeviceStatusReport::BusyRepeat`], +/// [`DeviceStatusReport::BusyLater`], [`DeviceStatusReport::MalfunctionRepeat`], or +/// [`DeviceStatusReport::MalfunctionLater`] may be sent either unsolicited or as a response to a request such as a +/// `DSR` with a parameter value [`DeviceStatusReport::RequestDeviceStatusReport`] or MESSAGE WAITING +/// ([`MW`][crate::c1::MW]). +/// +/// The default value for `s` is [`DeviceStatusReport::Ready`]. +pub fn DSR(s: Option) -> ControlFunction { + sequence!(06 / 14, selective default s) +} + +/// Dimension Text Area. +/// +/// `DTA` is used to establish the dimensions of the text area for subsequent pages. +/// +/// The established dimensions remain in effect until the next occurrence of `DTA` in the data stream. +/// +/// - `n` specifies the dimension in the direction perpendicular to the line orientation. +/// - `m` specifies the dimension in the direction parallel to the line orientation. +/// +/// The unit in which the parameter value is expressed is that established by the parameter value of SELECT SIZE UNIT +/// (`SSU`). +pub fn DTA(n: u32, m: u32) -> ControlFunction { + sequence!(02 / 00, 05 / 04, numeric n, numeric m) +} + +/// Valid parameter values to the function [`EA`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum EraseArea { + /// Erase from the active position until the end of the qualified area. + #[default] + ActivePositionToEnd = 0, + + /// Erase from the beginning of the qualified area until (including) the active position. + BeginToActivePosition, + + /// Erase all contents from the beginning of the qualified area until the end of the qualified area. + BeginToEnd, +} + +/// Erase in Area. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `EA` causes some or all character positions in +/// the active qualified area (the qualified area in the presentation component which contains the active presentation +/// position) to be put into the erased state, depending on the parameter value. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `EA` causes some or all character positions in the +/// active qualified area (the qualified area in the data component which contains the active data position) to be put +/// into the erased state, depending ont he parameter value. +/// +/// Whether the character positions of protected areas are put into the erased state, or the character positions of +/// unprotected areas only, depends on the setting of ERASURE MODE (`ERM`). +/// +/// The default value of `s` is [`EraseArea::ActivePositionToEnd`]. +pub fn EA(s: Option) -> ControlFunction { + sequence!(04 / 15, selective default s) +} + +/// Erase Character. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `ECH` causes the active presentation position +/// and the `n-1` following character positions in the presentation component to be put into the erased state. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `ECH` causes the active data position and the `n-1` +/// following character positions in the data component to be put into the erased state. +/// +/// Whether the character positions of protected areas are putinto the erased state, or the character positions of +/// unprotected areas only, depends on the setting of the ERASURE MODE (`ERM`). +/// +/// The default value for `n` is `1´. +pub fn ECH(n: Option) -> ControlFunction { + sequence!(05 / 08, numeric n, default 1) +} + +/// Valid parameter values to the function [`ED`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum ErasePage { + /// Erase from the active position until the end of the page. + #[default] + ActivePositionToEnd = 0, + + /// Erase from the beginning of the page until (including) the active position. + BeginToActivePosition, + + /// Erase all contents from the beginning of the page until the end of the page. + BeginToEnd, +} + +/// Erase In Page. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `ED` causes some or all character positions +/// of the active page (the page which contains the active presentation position in the presentation component) to be +/// put into the erased state, depending on the parameter value. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `ED` causes some or all character positions of the +/// active page (the page which contains the active data position in the data component) to be put into the erased +/// state, depending on the parameter value. +/// +/// Whether the character positions of protected areas are put into the erased state, or the character positions of +/// unprotected areas only, depends on the setting of the ERASURE MODE (`ERM`). +/// +/// The default value of `s` is [`ErasePage::ActivePositionToEnd`]. +pub fn ED(s: Option) -> ControlFunction { + sequence!(04 / 10, selective default s) +} + +/// Valid parameter values to the function [`EF`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum EraseField { + /// Erase from the active position until the end of the field. + #[default] + ActivePositionToEnd = 0, + + /// Erase from the beginning of the field until (including) the active position. + BeginToActivePosition, + + /// Erase all contents from the beginning of the field until the end of the field. + BeginToEnd, +} + +/// Erase In Field. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `EF` causes some or all character positions of +/// the active field (the field which contains the active presentation position in the presentatio component) to be put +/// into the erased state, depending on the parameter value. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `EF` causes some or all character positions of the +/// active field (the field which contains the active data position in the data component) to be put into the erased +/// state, depending on the parameter value. +/// +/// Whether the character positions of protected areas are put into the erased state, or the character positions of +/// unprotected areas only, depends on the setting of the ERASURE MODE (`ERM`). +/// +/// The default value for `s` is [`EraseField::ActivePositionToEnd`]. +pub fn EF(s: Option) -> ControlFunction { + sequence!(04 / 14, selective default s) +} + +/// Valid parameter values to the function [`EL`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum EraseLine { + /// Erase from the active position until the end of the line. + #[default] + ActivePositionToEnd = 0, + + /// Erase from the beginning of the line until (including) the active position. + BeginToActivePosition, + + /// Erase all contents from the beginning of the line until the end of the line. + BeginToEnd, +} + +/// Erase In Line. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `EL` causes some or all character positions of +/// the active line (the line which contains the active presentation position in the presentation component) to be put +/// into the erased state, depending on the parameter value. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `EL` causes some or all character positions of the +/// active line (the line which contains the active data position in the data component) to be put into the erased +/// state, depending on the parameter value. +/// +/// Whether the character positions of protected areas are put into the erased state, or the character positions of +/// unprotected areas only, depends on the setting of the ERASURE MODE (`ERM`). +/// +/// The default value for `s` is [`EraseLine::ActivePositionToEnd`]. +pub fn EL(s: Option) -> ControlFunction { + sequence!(04 / 11, selective default s) +} + +/// Function Key. +/// +/// `FNK` is a control function in which the parameter value identifies the function key which has been operated. +pub fn FNK(n: u32) -> ControlFunction { + sequence!(02 / 00, 05 / 07, numeric n) +} + +/// Valid parameter values to the function [`FNT`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum Font { + /// Primary font. + #[default] + Primary = 0, + + /// First alternative font. + Alternative1, + + /// Second alternative font. + Alternative2, + + /// Third alternative font. + Alternative3, + + /// Forth alternative font. + Alternative4, + + /// Fifth alternative font. + Alternative5, + + /// Sixth alternative font. + Alternative6, + + /// Seventh alternative font. + Alternative7, + + /// Eighth alternative font. + Alternative8, + + /// Ninth alternative font. + Alternative9, +} + +/// Font Selection. +/// +/// `FNT` is used to identify the character font to be selected as primary or alternative font by subsequent occurrences +/// of SELECT GRAPHIC RENDITION (`SGR`) in the data stream. +/// +/// - `s` specifies the primary or alternative font concerned. +/// - `t` identifies the character font according to a register which is to be established. +/// +/// The default value for `s` is [`Font::Primary`], and for `t` is `0`. +pub fn FNT(s: Option, t: Option) -> ControlFunction { + let a = match s { + Some(font) => font as u32, + None => (Font::default()) as u32, + }; + let b = t.unwrap_or(0); + sequence!(02 / 00, 04 / 04, numeric a, numeric b) +} + +/// Valid parameter values to the function [`GCC`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum GraphicCharacterCombination { + /// Combine the following two graphic characters into a single graphic symbol. + #[default] + CombineTwo = 0, + + /// Combine all following graphic characters, until the occurrence of + /// [`GraphicCharacterCombination::EndOfCombination`] into a single graphic symbol. + StartOfCombination, + + /// Combine all preceding graphic characters, starting from [`GraphicCharacterCombination::StartOfCombination`], + /// into a single graphic symbol. + EndOfCombination, +} + +/// Graphic Character Combination +/// +/// `GCC` is used to indicate that two or more graphic characters are to be imaged as one single graphic symbol. +/// +/// The default value of `s` is [`GraphicCharacterCombination::CombineTwo`]. +/// +/// ## Note +/// +/// `GCC` does not explicitly specify the relative sizes or placements of the component parts of a composite graphic +/// symbol. In the simplest case, two components may be "half-width" and side-by-side. For example in Japanese text a +/// pair of characters may be presented side-by-side, and occupy the space of a normal-size Kanji character. +pub fn GCC(s: Option) -> ControlFunction { + sequence!(02 / 00, 05 / 15, selective default s) +} + +/// Graphic Size Modification. +/// +/// `GSM` is used to modify for subsequent text the height and / or the width of all primary and alternative fonts +/// identified by FONT SELECT ([`FNT`]) and established by GRAPHIC SIZE SELECTION (`GSS`). The established values +/// remain in effect until the next occurrence of `GSM` or [`GSS`] in the data stream. +/// +/// - `h` specifies the height as a percentage of the height established by [`GSS`]. +/// - `w` specifies the width as a percentage of the width established by [`GSS`]. +/// +/// The default value for `h`, and `w` is `100`. +pub fn GSM(h: Option, w: Option) -> ControlFunction { + sequence!(02 / 00, 04 / 02, numeric h, default 100, numeric w, default 100) +} + +/// Graphic Size Selection. +/// +/// `GSS` is used to establish for subsequent texts the height and the width of all primary and alternative fonts +/// identified by FONT SELECT (`FNT`). The established values remain in effect until the next occurrence of `GSS` in the +/// data stream. +/// +/// - `n` specifies the height, the width is implicitly defined by the height. +/// +/// The unit in which the parameter value is expressed is that established by the parameter value of SELECT SIZE UNIT +/// (`SSU`). +pub fn GSS(n: u32) -> ControlFunction { + sequence!(02 / 00, 04/03, numeric n) +} + +/// Character Position Absolute. +/// +/// `HPA` causes the active data position to be moved to character position `n` in the active line (the line in the data +/// component that contains the active data position). +/// +/// The default value for `n` is `1`. +pub fn HPA(n: Option) -> ControlFunction { + sequence!(06 / 00, numeric n, default 1) +} + +/// Character Position Backward. +/// +/// `HPB` causes the active data position to be moved by `n` character positions in the data component in the direction +/// opposite to that of the character progression. +/// +/// The default value for `n` is `1`. +pub fn HPB(n: Option) -> ControlFunction { + sequence!(06 / 10, numeric n, default 1) +} + +/// Character Position Forward. +/// +/// `HPR` causes the active data position to be moved by `n` character positions in the data component in the direction +/// of the character progression. +/// +/// The default value for `n` is `1`. +pub fn HPR(n: Option) -> ControlFunction { + sequence!(06 / 01, numeric n, default 1) +} + +/// Character And Line Position. +/// +/// `HVP` causes the active data position to be moved in the data component to the `n`-th line position according to the +/// line progression and to the `m`-th character position according to the character progression. +/// +/// The default value for `n` and `m` is `1`. +pub fn HVP(n: Option, m: Option) -> ControlFunction { + sequence!(06 / 06, numeric n, default 1, numeric m, default 1) +} + +/// Insert Character. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `ICH` is used to prepare the insertion of `n` +/// characters, by putting into the erased state the active presentation position and, depending on the setting of the +/// CHARACTER EDITING MODE (`HEM`), the `n-1` preceding or following character positions in the presentation component. +/// The previous contents of the active presentation position and an adjacent string of character positions are shifted +/// away from the active presentation position. The contents of `n` character positions at the other end of the shifted +/// part are removed. The active presentation position is moved to the line home position in the active line. The line +/// home position is established by the parameter value of SET LINE HOME (`SLH`). +/// +/// The extent of the shifted part is established by SELECT EDITING EXTENT (`SEE`). +/// +/// The effect of `ICH` on the start or end of a selected area, the start or end of a qualified area, or a tabulation +/// stop in the shifted part is undefined. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `ICH` is used to prepare the insertion of `n` +/// characters, by putting into the erased state the active data position and, depending on the setting of the +/// CHARACTER EDITING MODE (`HEM`), the `n-1` preceding or following character positions in the data component. The +/// previous contents of the active data position and and adjacent string of character positions are shifted away from +/// the active data position. The contents of `n` character positions at the other end of the shifted part are removed. +/// The active data position is moved to the line home position in the active line. The line home position is +/// established by the parameter value of SET LINE HOME (`SLH`). +/// +/// The default value for `n` is `1`. +pub fn ICH(n: Option) -> ControlFunction { + sequence!(04 / 00, numeric n, default 1) +} + +/// Valid parameter values to the function [`IDCS`]. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum IdentifyDeviceControlString { + /// Reserved for use with the DIAGNOSTIC state of the STATUS REPORT TRANSFER MODE. + Diagnostic, + + /// Reserved for Dynamically Redefinable Character Sets (`DRCS`) according to Standard ECMA-35. + DynamicallyRedefinableCharacterSet, + + /// Private command string. + Private(u32), +} + +/// Identify Device Control String. +/// +/// `IDCS` is used to specify the purpose and format of the command string of subsequent DEVICE CONTROL STRINGS (`DCS`). +/// The specified purpose and format remain in effect until the next occurrence of `IDCS` in the data stream. +/// +/// The format and interpretation of the command string corresponding to the parameter `s` are to be defined in +/// appropriate standards. If this control function is used to identify a private command string, a private parameter +/// value shall be used [`IdentifyDeviceControlString::Private`]. +pub fn IDCS(s: IdentifyDeviceControlString) -> ControlFunction { + let v = match s { + IdentifyDeviceControlString::Private(i) => i, + IdentifyDeviceControlString::Diagnostic => 1, + IdentifyDeviceControlString::DynamicallyRedefinableCharacterSet => 2, + }; + + sequence!(02 / 00, 04 / 15, numeric v) +} + +/// Identify Graphic Subrepertoire. +/// +/// `IGS` is used to indicate that a repertoire of the graphic characters of ISO/IEC 10367 is used in the subsequent +/// text. +/// +/// The parameter value of `IGS` identifies a graphic character repertoire registered in accordance with ISO/IEC 7350. +pub fn IGS(n: u32) -> ControlFunction { + sequence!(02 / 00, 04 / 13, numeric n) +} + +/// Insert Line. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to PRESENTATION, `IL` is used to prepare the insertion of `n` +/// lines, by putting into the erased state in the presentation component the active line (the line that contains the +/// active presentation position) and, depending on the setting of the LINE EDITING MODE (`VEM`), the `n-1` preceding +/// or following lines. The previous contents of the active line and of adjacent lines are shifted away from the active +/// line. The contents of `n` lines at the other end of the shifted part are removed. The active presentation position +/// is moved to the line home position in the active line. The line home position is established by the parameter value +/// of SET LINE HOME (`SLH`). +/// +/// The extent of the shifted part is established by SELECT EDITING EXTENT (`SEE`). +/// +/// Any occurrence of the start or end of a selected area, the start or end of a qualified area, or a tabulation stop in +/// the shifted part, are also shifted. +/// +/// If the TABULATION STOP MODE (`TSM`) is set to SINGLE, character tabulation stops are cleared in the lines that are +/// put into the erased state. +/// +/// If the DEVICE COMPONENT SELECT MODE (`DCSM`) is set to DATA, `IL` is used to prepare the insertion of `n` lines, by +/// putting into the erased state in the data component the active line (the line that contains the active data +/// position) and, depending on the setting of the LINE EDITING MODE (`VEM`), the `n-1` preceding or following lines. +/// The previous contents of the active line and of adjacent lines are shifted away from the active line. The contents +/// of `n` lines at the other end of the shifted part are removed. The active data position is moved to the line home +/// position in the active line. The line home position is established by the parameter value of SET LINE HOME (`SLH`). +/// +/// The default value for `n` is `1`. +pub fn IL(n: Option) -> ControlFunction { + sequence!(04 / 12, numeric n, default 1) +} + +/// Valid parameter values to the function [`JFY`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum Justification { + /// No justification, end of justification of preceding text. + #[default] + None = 0, + + /// Word fill. + WordFill, + + /// Word space. + WordSpace, + + /// Letter space. + LetterSpace, + + /// Hyphenation. + Hyphenation, + + /// Flush to line home position margin. + Left, + + /// Centre between line home position and line limit position margins. + Centre, + + /// Flush to line limit position margin. + Right, + + /// Italian hyphenation. + ItalianHyphenation, +} + +/// Justify. +/// +/// `JFY` is used to indicate the beginning of a string of graphic characters in the presentation component that are to +/// be justified according to the layout specified by the parameter value. +/// +/// The end of the string to be justified is indicated by the next occurrence of `JFY` in the data stream. +/// +/// The line home position is established by the parameter value of SET LINE HOME (`SLH`). The line limit position is +/// established by the parameter value of SET LINE LIMIT (`SLL`). +/// +/// The default value of `s` is [`Justification::None`]. +pub fn JFY(s: Option) -> ControlFunction { + sequence!(02 / 00, 04 / 06, selective default s) +} + +/// Valid parameter values to the function [`MC`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum MediaCopy { + /// Initiate transfer to a primary auxiliary device. + #[default] + BeginTransferToPrimary = 0, + + /// Initiate transfer from a primary auxiliary device. + BeginTransferFromPrimary, + + /// Initiate transfer to a secondary auxiliary device. + BeginTransferToSecondary, + + /// Initiate transfer from a secondary auxiliary device. + BeginTransferFromSecondary, + + /// Stop relay to a primary auxiliary device. + StopRelayPrimary, + + /// Start relay to a primary auxiliary device. + StartRelayPrimary, + + /// Stop relay to a secondary auxiliary device. + StopRelaySecondary, + + /// Start relay to a secondary auxiliary device. + StartRelaySecondary, +} + +/// Media Copy. +/// +/// `MC` is used either to initiate a transfer of data from or to an auxiliary input/output device or to enable or +/// disable the relay of the received data stream to an auxiliary input/output device, depending on the parameter value. +/// +/// The default value for `s` is [`MediaCopy::BeginTransferToPrimary`]. +pub fn MC(s: Option) -> ControlFunction { + sequence!(06 / 09, selective default s) +} + +/// Next Page. +/// +/// `NP` causes the `n`-th following page in the presentation component to be displayed. +/// +/// The effect of this control function on the active presentation position is not defined. +/// +/// The default value for `n` is `1`. +pub fn NP(n: Option) -> ControlFunction { + sequence!(05 / 05, numeric n, default 1) +} + +/// Valid parameter values to the function [`PEC`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum PresentationExpandContract { + /// Normal, as specified by `SCS`, `SHS` or `SPI`. + #[default] + Normal = 0, + + /// Expanded, multiplied by a factor not greater than `2`. + Expanded, + + /// Condensed, multiplied by a factor not less than `0.5`. + Condensed, +} + +/// Presentation Expand or Contract. +/// +/// `PEC` is used to establish the spacing and the extent of the graphic characters for subsequent text. The spacing is +/// specified in the line as multiples of the spacing established by the most recent occurrence of SET CHARACTER SPACING +/// (`SCS`) or of SELECT CHARACTER SPACING (`SHS`) or of SPACING INCREMENT (`SPI`) in the data stream. The extent of the +/// characters is implicitly established by these control functions. The established spacing and the extent remain in +/// effect until the next occurrence of `PEC`, of `SCS`, of `SHS` or of `SPI` in the data stream. +/// +/// The default value for `s` is [`PresentationExpandContract::Normal`]. +pub fn PEC(s: Option) -> ControlFunction { + sequence!(02/00, 05/10, selective default s) +} + +/// Valid parameter values to the function [`PFS`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum PageFormat { + /// Tall basic text communication format. + #[default] + TallBasicText = 0, + + /// Wide basic text communication format. + WideBasicText, + + ///Tall basic A4 format. + TallBasicA4, + + /// Wide basic A4 format. + WideBasicA4, + + /// Tall North American letter format. + TallLetter, + + /// Wide North American letter format. + WideLetter, + + /// Tall extended A4 format. + TallExtendedA4, + + /// Wide extended A4 format. + WideExtendedA4, + + /// Tall North American legal format. + TallLegal, + + /// Wide North American legal format. + WideLegal, + + /// A4 short lines format. + A4ShortLines, + + /// A4 long lines format. + A4LongLines, + + /// B5 short lines format. + B5ShortLines, + + /// B5 long lines format + B5LongLines, + + /// B4 short lines format. + B4ShortLines, + + /// B4 long lines format + B4LongLines, +} + +/// Page Format Selection +/// +/// `PFS` is used to establish the available area for the imaging of pages of text based on paper size. The pages are +/// introduced by the subsequent occurrence of FORM FEED (`FF`) in the data stream. +/// +/// The established image area remains in effect until the next occurrence of `PFS` in the data stream. +/// +/// The page home position is established by the parameter value of SET PAGE HOME (`SPH`), the page limit position is +/// established by the parameter value of SET PAGE LIMIT (`SPL`). +/// +/// The default value for `s` is [`PageFormat::TallBasicText`]. +pub fn PFS(s: Option) -> ControlFunction { + sequence!(02/00, 04/10, selective default s) +} + +/// Preceding Page. +/// +/// `PP` causes the `n`-th preceding page in the presentation component to be displayed. The effect of this control +/// function on the active presentation position is not defined. +/// +/// The default for `n` is `1`. +pub fn PP(n: Option) -> ControlFunction { + sequence!(05 / 06, numeric n, default 1) +} + +/// Page Position Absolute. +/// +/// `PPA` causes the active data position to be moved in the data component to the corresponding character position on +/// the `n-th` page. +/// +/// The default for `n` is `1`. +pub fn PPA(n: Option) -> ControlFunction { + sequence!(02 / 00, 05 / 00, numeric n, default 1) +} + +/// Page Position Backward. +/// +/// `PPB` causes the active data position to be moved in the data component to the corresponding character position on +/// the `n-th` page. +/// +/// The default value for `n` is `1`. +pub fn PPB(n: Option) -> ControlFunction { + sequence!(02 / 00, 05 / 02, numeric n, default 1) +} + +/// Page Position Forward. +/// +/// `PPR` causes the active data position to be moved in the data component to the corresponding character position on +/// the `n`-th following page. +/// +/// The default value for `n` is `1`. +pub fn PPR(n: Option) -> ControlFunction { + sequence!(02 / 00, 05 / 01, numeric n, default 1) +} + +/// Valid parameter values to the function [`PTX`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum ParallelText { + /// End of parallel texts. + #[default] + End = 0, + + /// Beginning of a string of principal parallel text. + BeginPrincipal, + + /// Beginning of a string of supplementary parallel text. + BeginSupplementary, + + /// Beginning of a string of supplementary Japanese phonetic annotation + BeginJapanesePhonetic, + + /// Beginning of a string of supplementary Chinese phonetic annotation + BeginChinesePhonetic, + + /// End of a string of supplementary phonetic annotations + EndPhonetic, +} + +/// Parallel Texts. +/// +/// `PTX` is used to delimit strings of graphic characters that are communicated one after another in the data stream, +/// but that are intended to be presented in parallel with one another, usually in adjacent lines. +/// +/// `PTX` with a parameter value of [`ParallelText::BeginPrincipal`] indicates the beginning of the string of principal +/// text intended to be presented in parallel with one or more strings of supplementary text. +/// +/// `PTX` with a parameter value of [`ParallelText::BeginSupplementary`], [`ParallelText::BeginJapanesePhonetic`], or +/// [`ParallelText::BeginChinesePhonetic`] indicates the beginning of a string of supplementary text that is intended to +/// be presented in parallel with either a string of principal text or the immediately preceding string of supplementary +/// text, if any; at the same time it indicates the end of the preceding string of principal text or of the immediately +/// preceding string of supplementary text, if any. The end of a string of supplementary text is indicated by a +/// subsequent occurrence of `PTX` with a parameter other than [`ParallelText::BeginPrincipal`]. +/// +/// `PTX` with a parameter value of [`ParallelText::End`] indicates the end of the strings of text intended to be +/// presented in parallel with one another. +/// +/// The default value for `s` is [`ParallelText::End]`. +/// +/// ## Note +/// +/// `PTX` does not explicitly specify the relative placement of the strings of principal and supplementary parallel +/// texts, or the relative sizes of graphic characters in the strings of parallel text. A string of supplementary text +/// is normally presented in a line adjacent to the line containing the string of principal text, or adjacent to the +/// line containing the immediately preceding string of supplementary text, if any. The first graphic character of the +/// string of principal text and the first graphic character of a string of supplementary text are normally presented +/// in the same position of their respective lines. However, a string of supplementary text longer (when presented) +/// than the associated string of principal text may be centred on that string. In the case of long strings of text, +/// such as paragraphs in different languages, the strings may be presented in successive lines in parallel columns, +/// with their beginnings aligned with one another and the shorter of the paragraphs followed by an appropriate amount +/// of "white space". +/// +/// Japanese phonetic annotation typically consists of a few half-size or smaller Kana characters which indicate the +/// pronunciation or interpretation of one ore more Kanji characters and are presented above those Kanji characters if +/// the character path is horizontal, or to the right of them if the character path is vertical. +/// +/// Chines phonetic annotation typically consists of a few Pinyin characters which indicate the pronunciation of one +/// or more Hanzi characters and are presented above those Hanzi characters. Alternatively, the Pinyin characters may +/// be presented in the same line as the Hanzi characters and following the respective Hanzi characters. The Pinyin +/// characters will then be presented within enclosing paris of parentheses. +pub fn PTX(s: Option) -> ControlFunction { + sequence!(05 / 12, selective default s) +} + +/// Valid parameter values to the function [`QUAD`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum Alignment { + /// Flush to line home position margin. + #[default] + LineHome = 0, + + /// Flush to line home position margin and fill with leader. + LineHomeLeader, + + /// Centre between line home position and line limit position margins. + Centre, + + /// Center between line home position and line limit position margins and fill with leader. + CentreLeader, + + /// Flush to line limit position margin. + LineLimit, + + /// Flush to line limit position margin and fill with leader. + LineLimitLeader, + + /// Flush to both margins + Justify, +} + +/// Quad. +/// +/// `QUAD` is used to indicate the end of a string of graphic characters that are to be positioned on a single line +/// according to the layout specified by the parameter value, see [`Alignment`]. +/// +/// The beginning of the string to be positioned is indicated by the preceding occurrence in the data stream of either +/// `QUAD` or one of the following formator functions: FORM FEED (`FF`), CHARACTER AND LINE POSITION (`HVP`), LINE FEED +/// (`LF`), NEXT LINE (`NEL`), PAGE POSITION ABSOLUTE (`PPA`), PAGE POSITION BACKWARD (`PPB`), PAGE POSITION FORWARD +/// (`PPR`), REVERSE LINE FEED (`RI`), LINE POSITION ABSOLUTE (`VPA`), LINE POSITION BACKWARD (`VPB`), LINE POSITION +/// FORWARD (`VPR`), or LINE TABULATION (`VT`). +/// +/// The line home position is established by the parameter value of SET LINE HOME (`SLH`). The line limit position is +/// established by the parameter value of SET LINE LIMIT (`SLL`). +/// +/// The default value for `s` is [`Alignment::LineHome`]. +pub fn QUAD(s: Option) -> ControlFunction { + sequence!(02 / 00, 04 / 08, selective default s) +} + +/// Repeat. +/// +/// `REP` is used to indicate that the preceding character in the data stream, if it is a graphic character (presented +/// by one or more bit combinations) including SPACE, is to be repeated `n` times. If the character preceding `REP` is +/// a control function or part of a control function, the effect of `REP` is not defined. +/// +/// The default value for `n` is `1`. +pub fn REP(n: Option) -> ControlFunction { + sequence!(06 / 02, numeric n, default 1) +} + +/// Reset Mode. +/// +/// `RM` causes the modes of the receiving device to be reset as specified by the parameter values. +pub fn RM(v: Vec) -> ControlFunction { + sequence!(06 / 12, variadic selective v) +} + +/// Set Additional Character Representation. +/// +/// `SACS` is used to establish extra inter-character escapement for subsequent text. The established extra escapement +/// remains in effect until the next occurrence of `SACS` or of SET REDUCED CHARACTER SEPARATION (`SRCS`) in the data +/// stream or until it is reset to the default value by a subsequent occurrence of CARRIAGE RETURN LINE FEED (`CR LF`) +/// or of NEXT LINE (`NEL`) in the data stream. +/// +/// `n` specifies the number of units by which the inter-character escapement is enlarged. +/// +/// The unit in which the parameter value is expressed is that established by the parameter value of SELECT SIZE UNIT +/// (`SSU`). +/// +/// The default value for `n` is 0. +pub fn SACS(n: Option) -> ControlFunction { + sequence!(02 / 00, 05 / 12, numeric n, default 0) +} + +/// Valid parameter values to the function [`SAPV`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum PresentationVariant { + /// Default presentation (implementation-defined); cancels the effect of any preceding occurrence of `SAPV` in the + /// data stream. + #[default] + Default = 0, + + /// The decimal digits are presented by means of the graphic symbols used in the Latin script. + LatinDecimals, + + /// The decimal digits are presented by means of the graphic symbols used in the Arabic script, i.e. the Hindi + /// symbols. + ArabicDecimals, + + /// When the direction of the character path is right-to-left, each of the graphic characters in the graphic + /// character set(s) in use which is one of a left/right handed pair (parentheses, square brackets, curly brackets, + /// greater-than/less-than signs, etc.) is presented as "mirrored", i.e. as the other member of the pair. For + /// example, the coded graphic character given the name LEFT PARENTHESIS is presented as RIGHT PARENTHESIS, and + /// vice versa. + MirrorPairs, + + /// When the direction of the character path is right-to-left, all graphic characters which represent operators and + /// delimiters in mathematical formulae and which are not symmetrical about a vertical axis are presented as + /// mirrored about that vertical axis. + MirrorFormulae, + + /// The following graphic character is presented in its isolated form. + Isolated, + + /// The following graphic character is presented in its initial form. + Initial, + + /// The following graphic character is presented in its medial form. + Medial, + + /// The following graphic character is presented in its final form. + Final, + + /// Where the bit combination `02/14` is intended to represent a decimal mark in a decimal number it shall be + /// represented by means of the graphic symbol FULL STOP. + DecimalFullStop, + + /// Where the bit combination `02/14` is intended to represent a decimal mark in a decimal number it shall be + /// represented by means of the graphic symbol COMMA. + DecimalComma, + + /// Vowels are presented above or below the preceding character. + VowelAboveOrBelow, + + /// Vowels are presented after the preceding character. + VowelAfterPreceding, + + /// Contextual shape determination of Arabic scripts, including the LAM-ALEPH ligature but excluding all other + /// Arabic ligatures. + ContextualShapeArabicScriptWithLamAleph, + + /// Contextual shape determination of Arabic scripts, excluding all Arabic ligatures. + ContextualShapeArabicScript, + + /// Cancels the effect of [`PresentationVariant::MirrorPairs`] and [`PresentationVariant::MirrorFormulae`]. + NoMirroring, + + /// Vowels are not presented. + NoVowels, + + /// When the string direction is right-to-left, the italicized characters are slanted to the left, when the string + /// direction is left-to-right, the italicized characters are slanted to the right. + SlantFollowsStringDirection, + + /// Contextual shape determination of Arabic scripts is not used, the graphic characters - including the digits - + /// are presented in the form they are stored (pass-through). + NoContextualShapeArabicScript, + + /// Contextual shape determination of Arabic scripts i not used, the graphic characters - excluding the digits - + /// are presented in the form thye are stored (pass-through). + NoContextualShapeArabicScriptExceptDigits, + + /// The graphic symbols used to present the decimal digits are device dependent. + DeviceDependentDecimalDigits, + + /// Establishes the effect of parameter values [`PresentationVariant::Isolated`], [`PresentationVariant::Initial`], + /// [`PresentationVariant::Medial`], and [`PresentationVariant::Final`] for the following graphic characters until + /// cancelled. + PersistCharacterForm, + + /// Cancels the effect of parameter value [`PresentationVariant::PersistCharacterForm`], i.e. re-establishes the + /// effect of parameter values [`PresentationVariant::Isolated`], [`PresentationVariant::Initial`], + /// [`PresentationVariant::Medial`], and [`PresentationVariant::Final`] for the next single graphic character only. + DesistCharacterForm, +} + +/// Select Alternative Presentation Variants. +/// +/// `SAPV` is used to specify one or more variants for the presentation of subsequent text. +/// +/// The default value for `s` is [`PresentationVariant::Default`]. +pub fn SAPV(s: Option) -> ControlFunction { + sequence!(02 / 00, 05 / 13, selective default s) +} + +/// Valid parameter values to the function [`SCO`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum CharacterOrientation { + /// Rotate by 0°, normal orientation. + #[default] + Normal = 0, + + /// Rotate by 45°. + Rotate45, + + /// Rotate by 90°. + Rotate90, + + /// Rotate by 135°. + Rotate135, + + /// Rotate by 180°. + Rotate180, + + /// Rotate by 225°. + Rotate225, + + /// Rotate by 270°. + Rotate270, + + /// Rotate by 315°. + Rotate315, +} + +/// Select Character Orientation. +/// +/// `SCO` is used to establish the amount of rotation of the graphic characters following in the data stream. The +/// established value remains in effect until the next occurrence of `SCO` in the data stream. +/// +/// Rotation is positive, i.e. counter-clockwise and applies to the normal presentation of the graphic characters along +/// the character path. The centre of rotation of the affected graphic characters is not default. +/// +/// The default value for `s` is [`CharacterOrientation::Normal`]. +pub fn SCO(s: Option) -> ControlFunction { + sequence!(02 / 00, 06 / 05, selective default s) +} + +/// Valid parameter values to the function [`SCP`]. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum CharacterPath { + /// Left-to-right (in the case of horizontal line orientation), or top-to-bottom (in the case of vertical line + /// orientation). + LefToRight = 1, + + /// Right-to-left (in the case of horizontal line orientation), or bottom-to-top (in the case of vertical line + /// orientation). + RightToLeft, +} + +/// Valid parameter values to the function [`SCP`]. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum CharacterPathScope { + /// Undefined, implementation specific. + /// + /// ## Note + /// + /// This may also permit the effect to take place after the next occurrence of `CR`, `NEL` or any control function + /// which initiates an absolute movement of the active presentation position or the active data position. + Undefined = 0, + + /// The content of the active line in the presentation component (the line that contains the active presentation + /// position) is updated to correspond to the content of the active line in the data component (the line that + /// contains the active data position) according to the newly established character path characteristics in the + /// presentation component; the active data position is moved to the first character position in the active line + /// in the data component, the active presentation position in the presentation component is updated accordingly. + InPresentationComponent, + + /// The content of the active line in the data component (the line that contains the active data position) is + /// updated to correspond to the content of the active line in the presentation component (the line that contains + /// the active presentation position) according to the newly established character path characteristics of the + /// presentation component; the active presentation position is moved to the first character position in the active + /// line in the presentation component, the active data position in the data component is updated accordingly. + InDataComponent, +} + +/// Select Character Path. +/// +/// `SCP` is used to select the character paht, relative to the line orientation, for the active line (the line that +/// contains the active presentation position) and subsequent lines in the presentation component. It is also used to +/// update the content of the active line in the presentation component and the content of the active line (the line +/// that contains the active data position) in the data component. This takes effect immediately. +pub fn SCP(s: CharacterPath, t: CharacterPathScope) -> ControlFunction { + let (n, m) = ((s as u32), (t as u32)); + sequence!(02 / 00, 06 / 11, numeric n, numeric m) +} + +/// Set Character Spacing. +/// +/// `SCS` is used to establish the character spacing for subsequent text. The established spacing remains in effect +/// until the next occurrence of `SCS`, or of SELECT CHARACTER SPACING (`SHS`) or of SPACING INCREMENT (`SPI`) in the +/// data stream. +/// +/// `n` specifies the character spacing. +/// +/// The unit in which the parameter value is expressed is that established by the parameter value of SELECT SIZE UNIT +/// (`SSU`). +pub fn SCS(n: u32) -> ControlFunction { + sequence!(02 / 00, 06 / 07, numeric n) +} + +/// Scroll Down. +/// +/// `SD` causes the data in the presentation component to be moved by `n` line positions if the line orientation is +/// horizontal, or by `n` character positions if the line orientation is vertical, such that the data appear to +/// move down. +/// +/// The active presentation position is not affected by this control function. +/// +/// The default value for `n` is `1´. +pub fn SD(n: Option) -> ControlFunction { + sequence!(05 / 04, numeric n, default 1) +} + +/// Valid parameter values to the function [`SDS`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum StringDirection { + /// End of a directed string; re-establish the previous direction. + #[default] + End = 0, + + /// Start of a directed string, establish the direction left-to-right. + StartLeftToRight, + + /// Start of a directed string, establish the direction right-to-left. + StartRightToLeft, +} + +/// Start Directed String. +/// +/// `SDS` is used to establish in the data component the beginning and end of a string of characters as well as the +/// direction of the string. This direction may be different from that currently established. The indicated string +/// follows the preceding text. The established character progression is not affected. +/// +/// The beginning of a directed string is indicated by `SDS` with a parameter value not equal to +/// [`StringDirection::End`]. A directed string may contain one or more nested strings. These nested strings may be +/// directed strings the beginning of which are indicated by `SDS` with a parameter value not equal to +/// [`StringDirection::End`], or reversed stings the beginning of which are indicated by START REVERSED STRING (`SRS`) +/// with a parameter value of [`ReversedString::Start`]. Every beginning of such a string invokes the next deeper level +/// of nesting. +/// +/// The standard does not define the location of the active data position within any such nested string. +/// +/// The end of a directed string is indicated by `SDS` with a parameter value of [`StringDirection::End`]. Every such +/// end of such a string re-establishes the next higher level of nesting (the one in effect prior to the string just +/// ended). The direction is re-established to that in effect prior to the string just ended. The active data position +/// is moved to the character position following the characters of the string just ended. +/// +/// The default value of `s` is [`StringDirection::End`]. +/// +/// ## Note 1 +/// +/// The effect of receiving a `CVT`, `HT`, `SCP`, `SPD`, or `VT` control function within an `SDS` string is not defined. +/// +/// ## Note 2 +/// +/// The control functions for area definitions (`DAQ, `EPA`, `SPA`, `SSA`) should not be used within an `SDS` string. +pub fn SDS(s: Option) -> ControlFunction { + sequence!(05 / 13, selective default s) +} + +/// Valid parameter values to the function [`SSE`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum EditingExtend { + /// The shifted part is limitied to the active page in the presentation component. + #[default] + ActivePage = 0, + + /// The shifted part is limited to the active line in the presentation component. + ActiveLine, + + /// The shifted part is limited to the active field in the presentation component. + ActiveField, + + /// The shifted part is limited to the active qualified area. + QualifiedArea, + + /// The shifted part consists of the relevant part of the entire presentation component. + All, +} + +/// Select Editing Extent. +/// +/// `SEE` is used to establish the editing extent for subsequent character or line line insertion or deletion. The +/// established extent remains in effect until the next occurrence of `SEE` in the data stream. The editing extend +/// depends on the parameter value. +/// +/// The default value for `s` is [`EditingExtend::ActivePage`]. +pub fn SSE(s: Option) -> ControlFunction { + sequence!(05 / 01, selective default s) +} + +/// Valid parameter values to the function [`SEF`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum Load { + /// Eject sheet, no new sheet loaded + #[default] + None, + + /// Eject sheet and load another from the given bin. + Bin(u32), +} + +/// Valid parameter values to the function [`SEF`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum Stack { + /// Eject sheet, no stacker specified. + #[default] + None, + + /// Eject sheet into the specified stacker. + Stacker(u32), +} + +/// Sheet Eject And Feed. +/// +/// `SEF` causes a sheet of paper to be ejected from a printing device into a specified output stacker and another +/// sheet to be loaded into the printing device from a specified paper bin. +/// +/// The default value for `l` is [`Load::None`]. +/// The default value for `s` is [`Stack::None`]. +pub fn SEF(l: Option, s: Option) -> ControlFunction { + let n = match l.unwrap_or(Load::default()) { + Load::None => 0, + Load::Bin(bin) => bin, + }; + let m = match s.unwrap_or(Stack::default()) { + Stack::None => 0, + Stack::Stacker(stacker) => stacker, + }; + sequence!(02 / 00, 05 / 09, numeric n, numeric m) +} + +/// Valid parameter values to the function [`SGR`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum GraphicRendition { + /// Default rendition (implementation-defined), cancels the effect of any preceding occurrence of `SGR` in the data + /// stream regardless of the setting of the GRAPHIC RENDITION COMBINATION MODE (`GRCM`). + #[default] + Default = 0, + + /// Bold or increased intensity. + HighIntensity, + + /// Faint, decreased intensity or second color. + LowIntensity, + + /// Italicized. + Italicized, + + /// Singly underlined. + Underlined, + + /// Slowly blinking (less than 150 per minute). + SlowlyBlinking, + + /// Rapidly blinking (more than 150 per minute). + RapidlyBlinking, + + /// Negative image. + Negative, + + /// Concealed characters. + Concealed, + + /// Crossed-out (characters still legible but marked as to be deleted). + CrossedOut, + + /// Primary (default) font. + PrimaryFont, + + /// First alternative font. + FirstAlternativeFont, + + /// Second alternative font. + SecondAlternativeFont, + + /// Third alternative font. + ThirdAlternativeFont, + + /// Forth alternative font. + ForthAlternativeFont, + + /// Fifth alternative font. + FifthAlternativeFont, + + /// Sixth alternative font. + SixthAlternativeFont, + + /// Seventh alternative font. + SeventhAlternativeFont, + + /// Eighth alternative font. + EighthAlternativeFont, + + /// Ninth alternative font. + NinthAlternativeFont, + + /// Fraktur (Gothic). + Fraktur, + + /// Doubly underlined. + DoublyUnderlined, + + /// Normal colour or normal intensity (neither bold nor faint). + NormalIntensity, + + /// Not italicized, not fraktur + NormalStyle, + + /// Not underlined (neither singly nor doubly). + NotUnderlined, + + /// Steady (not blinking). + NotBlinking, + + /// Positive Image. + Positive = 27, + + /// Revealed characters. + Revealed, + + /// Not crossed out. + NotCrossedOut, + + /// Black display. + BlackForeground, + + /// Red display. + RedForeground, + + /// Green display. + GreenForeground, + + /// Yellow display. + YellowForeground, + + /// Blue display. + BlueForeground, + + /// Magenta display. + MagentaForeground, + + /// Cyan display. + CyanForeground, + + /// White display. + WhiteForeground, + + /// Default display color (implementation specific). + DefaultForeground = 39, + + /// Black background. + BlackBackground, + + /// Red background. + RedBackground, + + /// Green Background. + GreenBackground, + + /// Yellow background. + YellowBackground, + + /// Blue background. + BlueBackground, + + /// Magenta background. + MagentaBackground, + + /// Cyan background. + CyanBackground, + + /// White background. + WhiteBackground, + + /// Default background color (implementation specific). + DefaultBackground = 49, + + /// Framed. + Framed = 51, + + /// Encircled. + Encircled, + + /// Overlined. + Overlined, + + /// Not framed, not encircled. + NotFramed, + + /// Not overlined, + NotOverlined, + + /// Ideogram underline or right side line. + IdeogramUnderline = 60, + + /// Ideogram double underline or double line on the right side. + IdeogramDoubleUnderline, + + /// Ideogram stress marking. + IdeogramStressMarking, + + /// Cancel Ideogram rendition settings. + CancelIdeogramRendition, +} + +/// Select Graphic Rendition. +/// +/// `SGR` is used to establish one or more graphic rendition aspects for subsequent text. The established aspects remain +/// in effect until the next occurrence of `SGR` in the data stream, depending on the setting of the GRAPHIC RENDITION +/// COMBINATION MODE (`GRCM`). Each graphic rendition aspect is specified by a parameter value of [`GraphicRendition`]. +/// +/// The default value for `s` is [`GraphicRendition::Default`]. +/// +/// ## Note +/// +/// The usable combinations of parameter values are determined by the implementation. +pub fn SGR(s: Option>) -> ControlFunction { + let g = s.unwrap_or(vec![Default::default()]); + sequence!(06 / 13, variadic selective g) +} + +/// Valid parameter values to the function [`SHS`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum CharacterSpacing { + /// 10 characters per 25.4 mm. + #[default] + TenCharacters = 0, + + /// 12 characters per 25.4 mm. + TwelveCharacters, + + /// 15 characters per 25.4 mm. + FifteenCharacters, + + /// 6 characters per 25.4 mm. + SixCharacters, + + /// 3 characters per 25.4 mm. + ThreeCharacters, + + /// 9 characters per 25.4 mm. + NineCharacters, + + /// 4 characters per 25.4 mm. + FourCharacters, +} + +/// Select Character Spacing. +/// +/// `SHS` is used to establish the character spacing for subsequent text. The established spacing remains in effect +/// until the next occurrence of `SHS` or of SET CHARACTER SPACING (`SPS`) or of SPACING INCREMENT (`SPI`) in the data +/// stream. +/// +/// The default value for `s` is [`CharacterSpacing::TenCharacters`]. +pub fn SHS(s: Option) -> ControlFunction { + sequence!(02 / 00, 04 / 11, selective default s) +} + +/// Valid parameter values to the function [`SIMD`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum MovementDirection { + /// The direction of implicit movement is the same as that of the character progression. + #[default] + Normal = 0, + + /// The direction of implicit movement is opposite to that of the character progression. + Opposite, +} + +/// Select Implicit Movement Direction. +/// +/// `SIMD` is used to select the direction of implicit movement of the data position relative to the character +/// progression. The direction selected remains in effect until the next occurrence of `SIMD`. +/// +/// The default value of `s` is [`MovementDirection::Normal`]. +pub fn SIMD(s: Option) -> ControlFunction { + sequence!(05 / 14, selective default s) +} + +/// Scroll Left. +/// +/// `SL` causes the data in the presentation component to be moved by `n` character positions if the line orientation +/// is horizontal, or by `n` line positions if the line orientation is vertical, such that the data appear to move +/// to the left. +/// +/// The active presentation position is not affected by this control function. +/// +/// The default value for `n` is `1`. +pub fn SL(n: Option) -> ControlFunction { + sequence!(02 / 00, 04 / 00, numeric n, default 1) +} + +/// Set Line Home. +/// +/// If the DEVICE COMPONENT SELECT MODE is set to PRESENTATION, `SLH` is used to establish at character position `n` in +/// the active line (the line that contains the active presentation position) and lines of subsequent text in the +/// presentation component the position to which the active presentation position will be moved by subsequent +/// occurrences of CARRIAGE RETURN (`CR`), DELETE LINE (`DL`), INSERT LINE (`IL`) or NEXT LINE (`NEL`) in the data +/// stream. In the case of a device without data component, it is also the position ahead of which no implicit movement +/// of the active presentation position shall occur. +/// +/// If the DEVICE COMPONENT SELECT MODE is set to DATA, `SLH` is used to establish at character position `n` in the +/// active line (the line that contains the active data position) and lines of subsequent text in the data component +/// the position to which the active data position will be moved by subsequent occurrences of CARRIAGE RETURN (`CR`), +/// DELETE LINE (`DL`), INSERT LINE (`IL`) or NEXT LINE (`NEL`) in the data stream. It is also the position ahead of +/// which no implicit movement of the active data position shall occur. +/// +/// The established position is called the line home position and remains in effect until the next occurrence of `SLH` +/// in the data stream. +pub fn SLH(n: u32) -> ControlFunction { + sequence!(02 / 00, 05 / 05, numeric n) +} + +/// Set Line Limit. +/// +/// If the DEVICE COMPONENT SELECT MODE is set to PRESENTATION, `SLL` is used to establish at character position `n` in +/// the active line (the line that contains the active presentation position) and lines of subsequent text in the +/// presentation component the position to which the active presentation position will be moved by subsequent +/// occurrences of CARRIAGE RETURN (`CR`), or NEXT LINE (`NEL`) in the data stream if the parameter value of SELECT +/// IMPLICIT MOVEMENT DIRECTION (`SIMD`) is equal to [`MovementDirection::Opposite`]. In the case of a device without +/// data component, it is also the position beyond which no implicit movement of the active presentation position shall +/// occur. +/// +/// If the DEVICE COMPONENT SELECT MODE is set to DATA, `SLL` is used to establish at character position `n` in the +/// active line (the line that contains the active data position) and lines of subsequent text in the data component the +/// position beyond which no implicit movement of the active data position shall occur. It is also the position in the +/// data component to which the active data position will be moved by subsequent occurrences of `CR` or `NEL` in the +/// data stream, if the parameter value of SELECT IMPLICIT MOVEMENT DIRECTION (SIMD) is equal to +/// [`MovementDirection::Opposite`]. +/// +/// The established position is called the line limit position and remains in effect until the next occurrence of `SLL` +/// in the data stream. +pub fn SLL(n: u32) -> ControlFunction { + sequence!(02 / 00, 05 / 06, numeric n) +} + +/// Set Line Spacing. +/// +/// `SLS` is used to establish the line spacing for subsequent text. The established spacing remains in effect until the +/// next occurrence of `SLS` or of SELECT LINE SPACING (`SVS`) or of SPACING INCREMENT (`SPI`) in the data stream. +/// +/// `n` specifies the line spacing. +/// +/// The unit in which the parameter value is epxressed is that established by the paramaeter value of SELECT SIZE UNIT +/// (`SSU`). +pub fn SLS(n: u32) -> ControlFunction { + sequence!(02 / 00, 06 / 08, numeric n) +} + +/// Set Mode. +/// +/// `SM` causes the modes of the receiving device to be set as specified by the parameter values. +pub fn SM(s: Vec) -> ControlFunction { + sequence!(06 / 08, variadic selective s) +} + +/// Valid parameter values to the function [`SPD`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum PresentationDirection { + /// Horizontal line orientation, top-to-bottom line progression, left-to-right character path. + #[default] + HorizontalLinesTopToBottomLeftToRight = 0, + + /// Vertical line orientation, right-to-left line progression, top-to-bottom character path. + VerticalLinesRightToLeftTopToBottom, + + /// Vertical line orientation, left-to-right line progression, top-to-bottom character path. + VerticalLinesLeftToRightTopToBottom, + + /// Horizontal line orientation, top-to-bottom line progression, right-to-left character path. + HorizontalLinesTopToBottomRightToLeft, + + /// Vertical line orientation, left-to-right line progression, bottom-to-top character path. + VerticalLinesLeftToRightBottomToTop, + + /// Horizontal line orientation, bottom-to-top line progression, right-to-left character path. + HorizontalLinesBottomToTopRightToLeft, + + /// Horizontal line orientation, bottom-to-top line progression, left-to-right character path. + HorizontalLinesBottomToTopLefToRight, + + /// Vertical line orientation, right to left line progression, bottom-to-top character path. + VerticalLinesRightToLeftBottomToTop, +} + +/// Valid parameter values to the function [`SPD`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum PresentationDirectionScope { + /// Undefined, implementation specific. + /// + /// ## Note + /// + /// This may also permit the effect to take place after the next occurrence of `CR`, `NEL` or any control function + /// which initiates an absolute movement of the active presentation position or the active data position. + #[default] + Undefined = 0, + + /// The content of the presentation component is updated to correspond to the content of the data component + /// according to the newly established characteristics of the presentation component; the active data position is + /// moved to the first character position in the first line in the data component, the active presentation position + /// in the presentation component is updated accordingly. + InPresentationComponent, + + /// The content of the data component is updated to correspond to the content of the presentation component + /// according to the newly established characteristics of the presentation component; the active presentation + /// position is moved to the first character position in the first line in the presentation component, the active + /// data position in the data component is updated accordingly. + InDataComponent, +} + +/// Select Presentation Directions. +/// +/// `SPD` is used to select the line orientation, the line progression, and the character path in the presentation +/// component. It is also used to update the content of the presentation component and the content of the data +/// component. This takes effect immediately. +/// +/// `s` specifies the line orientation, the line progression and the character path. +/// `t` specifies the effect on the content of the presentation component and the content of the data component. +/// +/// The default value for `s` is [`PresentationDirection::HorizontalLinesTopToBottomLeftToRight`]. +/// The default value for `t` is [`PresentationDirectionScope::Undefined`]. +pub fn SPD( + s: Option, + t: Option, +) -> ControlFunction { + sequence!(02 / 00, 05 / 03, selective default s, selective default t) +} + +/// Set Page Home. +/// +/// If the DEVICE COMPONENT SELECT MODE is set to PRESENTATION, `SPH` is used to establish at line position `n` in the +/// active page (the page that contains the active presentation position) and subsequent pages in the presentation +/// component the position to which the active presentation position will be moved by subsequent occurrences of FORM +/// FEED (`FF`) in the data stream. In the case of a device without data component, it is also the position ahead of +/// which no implicit movement of the active presentation position shall occur. +/// +/// If the DEVICE COMPONENT SELECT MODE is set to DATA, `SPH` is used to establish at line position `n´ in the active page +/// (the page that contains the active data position) and subsequent pages in the data component the position to which +/// the active data position will be moved by subsequent occurrences of FORM FEED (`FF`) in the data stream. It is also +/// the position ahead of which no implicit movement of the active presentation position shall occur. +/// +/// The established position is called the page home position and remains in effect until the next occurrence of ´SPH` +/// in the data stream. +pub fn SPH(n: u32) -> ControlFunction { + sequence!(02 / 00, 06 / 09, numeric n) +} + +/// Spacing Increment. +/// +/// `SPI` is used to establish the line spacing and the character spacing for subsequent text. The established line +/// spacing remains in effect until the next occurrence of `SPI` or of SET LINE SPACING (`SLS`) or of SELECT LINE +/// SPACING (`SVS`) in the data stream. The established character spacing remains in effect until the next occurrence +/// of SET CHARACTER SPACING (`SCS`) or of SELECT CHARACTER SPACING (`SHS`) in the data stream. +/// +/// `l` specifies the line spacing. +/// `c` specifies the character spacing. +/// +/// The unit in which the parameter values are expressed is that established by the parameter value of SELECT SIZE UNIT +/// (`SSU`). +pub fn SPI(l: u32, c: u32) -> ControlFunction { + sequence!(02 / 00, 04 / 07, numeric l, numeric c) +} + +/// Set Page Limit. +/// +/// If the DEVICE COMPONENT SELECT MODE is set to PRESENTATION, `SPL` is used to establish at line position `n` in the +/// active page (the page that contains the active presentation position) and pages of subsequent text in the +/// presentation component the position beyond which the active presentation position can normally not be moved. In the +/// case of a device without data component, it is also the position beyond which no implicit movement of the active +/// presentation position shall occur. +/// +/// If the DEVICE COMPONENT SELECT MODE is set to DATA, `SPL` is used to establish at line position `n` in the active +/// page (the page that contains the active data position) and pages of subsequent text in the data component the +/// position beyond which no implicit movement of the active data position shall occur. +/// +/// The established position is called the page limit position and remains in effect until the next occurrence of `SPL` +/// in the data stream. +pub fn SPL(n: u32) -> ControlFunction { + sequence!(02 / 00, 06 / 10, numeric n) +} + +/// Valid parameter values to the function [`SPQR`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum PrintQuality { + /// Highest available print quality, low print speed + #[default] + HighQualityLowSpeed = 0, + + /// Medium print quality, medium print speed. + MediumQualityMediumSpeed, + + /// Draft print quality, highest available print speed + LowQualityHighSpeed, +} + +/// Select Print Quality and Rapidity. +/// +/// `SPQR` is used to select the relative print quality and the print speed for devices where the output quality and +/// speed of are inversely related. The selected values remain in effect until the next occurrence of `SPQR` in the +/// data stream. +/// +/// The default value of `s` is [`PrintQuality::HighQualityLowSpeed`]. +pub fn SPQR(s: Option) -> ControlFunction { + sequence!(02 / 00, 05 / 08, selective default s) +} + +/// Scroll Right. +/// +/// `SR` causes the data in the presentation component to be moved by `n` character positions if the line orientation is +/// horizontal, or by `n` line positions if the line orientation is vertical, such that the data appear to move to the +/// right. +/// +/// The active presentation position is not affected by this control function. +/// +/// The default value for `n` is `1`. +pub fn SR(n: Option) -> ControlFunction { + sequence!(02 / 00, 05 / 08, numeric n, default 1) +} + +/// Set Reduced Character Separation. +/// +/// `SRCS` is used to establish reduced inter-character escapement for subsequent text. The established reduced +/// escapement remains in effect until the next occurrence of `SRCS` or of SET ADDITIONAL CHARACTER SEPARATION (`SACS`) +/// in the data stream or until it is reset to the default value by a subsequent occurrence of CARRIAGE RETURN/LINE FEED +/// (`CR/LF`) or of NEXT LINE (`NEL`) in the data stream. +/// +/// `n` specifies the number of units by which the inter-character escapement is reduced. +/// +/// The unit in which the parameter values are expressed is that established by the parameter value of SELECT SIZE UNIT +/// (`SSU`). +/// +/// The default value of `n` is `0`. +pub fn SRCS(n: Option) -> ControlFunction { + sequence!(02 / 00, 06 / 06, numeric n, default 0) +} + +/// Valid parameter values to the function [`SRS`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum ReversedString { + /// End of a reversed string; re-establish the previous direction. + #[default] + End = 0, + + /// Beginning of a reversed string; reverse the direction + Start, +} + +/// Start Reversed String. +/// +/// `SRS` is used to establish in the data component the beginning and the end of a string of characters as well as +/// the direction of the string. This direction is opposite to that currently established. The indicated string follows +/// the preceding text. The established character progression is not affected. +/// +/// The beginning of a reversed string is indicated by `SRS` with a parameter value of [`ReversedString::Start`]. +/// A reversed string may contain one or more nested strings. These nested strings may be reversed strings the +/// beginnings of which are indicated by `SRS` with a parameter value of [`ReversedString::Start`], or directed strings +/// the beginnings of which are indicated by START DIRECTED STRING (`SDS`) with a parameter value not equal to +/// [`StringDirection::End`]. Every beginning of such a string invokes the next deeper level of nesting. +/// +/// This Standard does not define the location of the active data position within any such nested string. +/// +/// The end of a reversed string is indicated by `SRS` with a parameter value of [`ReversedString::End`]. Every end of +/// such a string re-establishes the next higher level of nesting (the one in effect prior to the string just ended). +/// The direction is re-established to that in effect prior to the string just ended. The active data position is moved +/// to the character position following the characters of the string just ended. +/// +/// Default value of `s` is [`ReversedString::End`]. +/// +/// ## Note 1 +/// +/// The effect of receiving a `CVT`, `HT`, `SCP`, `SPD`, or `VT` control function within an `SRS` string is not defined. +/// +/// ## Note 2 +/// +/// The control functions for area definition (`DAQ`, `EPA`, `ESA`, `SPA`, `SSA`) should not be used within an `SRS` +/// string. +pub fn SRS(s: Option) -> ControlFunction { + sequence!(05 / 11, selective default s) +} + +/// Valid parameter values to the function [`SSU`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum SizeUnit { + /// The dimension of this unit are device-dependent. + #[default] + Character = 0, + + /// Millimetre. + Millimetre, + + /// Computer Decipoint (0.03528 mm - 1/720 of 25.4 mm). + ComputerDecipoint, + + /// Decidot (0.03759 mm - 10/266 mm). + Decidot, + + /// Mil (0.0254 mm - 1/1000 of 25.4 mm). + Mil, + + /// Basic Measuring Unit (BMU) (0.02117 mm - 1/1200 of 25.4 mm). + BasicMeasuringUnit, + + /// Micrometer (0.001 mm). + Micrometer, + + /// Pixel. The smallest increment that can be specified in a device. + Pixel, + + /// Decipoint (0.03514mm - 35/996 mm). + Decipoint, +} + +/// Select Size Unit. +/// +/// `SSU` is used to establish the unit in which the numeric parameters of certain control functions are expressed. The +/// established unit remains in effect until the next occurrence of `SSU` in the data stream. +/// +/// Default value of `s` is [`SizeUnit::Character`]. +pub fn SSU(s: Option) -> ControlFunction { + sequence!(02 / 00, 04 / 09, selective default s) +} + +/// Set Space Width. +/// +/// `SSW` is used to establish for subsequent text the character escapement associated with the character SPACE. The +/// established escapement remains in effect until the next occurrence of `SSW` in the data stream or until it is reset +/// to the default value by a subsequent occurrence of CARRIAGE RETURN/LINE FEED (`CR/LF`), CARRIAGE RETURN/FORM FEED +/// (`CR/FF`), or of NEXT LINE (`NEL`) in the data stream. +/// +/// `n` specifies the escapement. +/// +/// The unit in which the parameter value is expressed is that established by the parameter value of SELECT SIZE UNIT +/// (`SSU`). +/// +/// The default character escapement of SPACE is specified by the most recent occurrence of SET CHARACTER SPACING +/// (`SCS`) or of SELECT CHARACTER SPACING (`SHS`) or of SELECT SPACING INCREMENT (`SPI`) in the data stream if the +/// current font has constant spacing, or is specified by the nominal width of the character SPACE in the current font +/// if that font has proportional spacing. +pub fn SSW(n: u32) -> ControlFunction { + sequence!(02 / 00, 05 / 11, numeric n) +} + +/// Selective Tabulation. +/// +/// `STAB` causes subsequent text in the presentation component to be aligned according to the position and the +/// properties of a tabulation stop which is selected from a list according to the value of the parameter `s`. +/// +/// The use of this control function and means of specifying a list of tabulation stop to be referenced by the control +/// function are specified in other standards, for example ISO 8613-6. +pub fn STAB(s: u32) -> ControlFunction { + sequence!(02 / 00, 05 / 14, numeric s) +} + +/// Scroll Up. +/// +/// `SU` causes the data in the presentation component to be moved by `n` line positions if the line operation is +/// horizontal, or by `n` character positions if the line orientation is vertical, such that the dat data appear to move +/// up. +/// +/// The active presentation position is not affected by this control function. +/// +/// The default value for `n` is `1`. +pub fn SU(n: Option) -> ControlFunction { + sequence!(05 / 03, numeric n, default 1) +} + +/// Valid parameter values to the function [`SLS`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum LineSpacing { + /// Six lines per 25.4 mm. + #[default] + SixLinesPer25 = 0, + + /// Four lines per 25.4 mm. + FourLinesPer25, + + /// Three lines per 25.4 mm. + ThreeLinesPer25, + + /// Twelve lines per 25.4 mm. + TwelveLinesPer25, + + /// Eight lines per 25.4 mm. + EightLinesPer25, + + /// Six lines per 30 mm. + SixLinesPer30, + + /// Four lines per 30 mm. + FourLinesPer30, + + /// Three lines per 30 mm. + ThreeLinesPer30, + + /// Twelve lines per 30 mm. + TwelveLinesPer30, + + /// Two lines per 25.4 mm. + TwoLinesPer25, +} + +/// Select Line Spacing. +/// +/// `SVS` is used to establish the line spacing for subsequent text. The established spacing remains in effect until the +/// next occurrence of `SVS` or of SET LINE SPACING (`SLS`) or of SPACING INCREMENT (`SPI`) in the data stream. +/// +/// The default value for `s` is [`LineSpacing::SixLinesPer25`]. +pub fn SVS(s: Option) -> ControlFunction { + sequence!(02 / 00, 04 / 12, selective default s) +} + +/// Tabulation Aligned Centred. +/// +/// `TAC` causes a character tabulation stop calling for centring to be set at character position `n` in the active +/// line (the line that contains the active presentation position) and lines of subsequent text in the presentation +/// component. `TAC` causes the replacement of any tabulation stop previously set at that character position, but does +/// not affect other tabulation stops. +/// +/// A text string centred upon a tabulation stop set by `TAC` will be positioned so that the (trailing edge of the) +/// first graphic character and the (leading edge of the) last graphic character are at approximately equal distances +/// from the tabulation stop. +pub fn TAC(n: u32) -> ControlFunction { + sequence!(02 / 00, 06 / 02, numeric n) +} + +/// Tabulation Aligned Leading Edge. +/// +/// `TALE` causes a character tabulation stop calling for leading edge alignment to be set at character position `n` in +/// the active line (the line that contains the active presentation position) and lines of subsequent text in the +/// presentation component. `TALE` causes the replacement of any tabulation stop previously set at that character +/// position, but does not affect other tabulation stops. +/// +/// A text string aligned with a tabulation stop set by `TALE` will be positioned so that the (leading edge of the) last +/// graphic character of the string is placed at the tabulation stop. +pub fn TALE(n: u32) -> ControlFunction { + sequence!(02 / 00, 06 / 01, numeric n) +} + +/// Tabulation Aligned Trailing Edge. +/// +/// `TATE` causes a character tabulation stop calling for trailing edge alignment to be set at character position `n` +/// in the active line (the line that contains the active presentation position) and lines of subsequent text in the +/// presentation component. `TATE` causes the replacement of any tabulation stop previously set at the character +/// position, but does not affect other tabulation stops. +/// +/// A text string aligned with a tabulation stop set by `TATE` will be positioned so that the (trailing edge of the) +/// first graphic character of the string is placed at the tabulation stop. +pub fn TATE(n: u32) -> ControlFunction { + sequence!(02 / 00, 06 / 00, numeric n) +} + +/// Valid parameter values to the function [`TBC`]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum ClearTabulation { + #[default] + CharacterTabulationStopActivePosition = 0, + LineTabulationStopActiveLine, + AllCharacterTabulationStopsActiveLine, + AllCharacterTabulationStops, + AllLineTabulationStops, + AllTabulationStops, +} + +/// Tabulation Clear. +/// +/// `TBC` causes one or more tabulation stops in the presentation component to be cleared, depending on the parameter +/// value `s`. +/// +/// The default value for `s` is [`ClearTabulation::CharacterTabulationStopActivePosition`]. +pub fn TBC(s: Option) -> ControlFunction { + sequence!(06 / 07, selective default s) +} + +/// Tabulation Centred on Character. +/// +/// `TCC` causes a character tabulation stop calling for alignment of a target graphic character to be set at character +/// position `n` in the active line (the line that contains the active presentation position) and lines of subsequent +/// text in the presentation component, and the target character about which centring is to be performed is specified +/// by parameter `m`. `TCC` causes the replacement of any tabulation stop previously set at that character position, but +/// does not affect other tabulation stops. +/// +/// The positioning of a text string aligned with a tabulation stop set by `TCC` will be determined by the first +/// occurrence in the string of the target graphic character; that character will be centred upon the tabulation stop. +/// If the target character does not occur within the string, then the trailing edge of the first character of the +/// string will be positioned at the tabulation stop. +/// +/// The value of `m` indicates the code table position (binary value) of the target character in the currently invoked +/// code. For a 7-bit code, the permissible range of values is `32` to `127`; for an 8-bit code, the permissible range +/// of values is `32` to `127` and `160` to `255`. +/// +/// The default value ofr `m` is `32`. +pub fn TCC(n: u32, m: Option) -> ControlFunction { + let k = m.unwrap_or(32); + sequence!(02 / 00, 06 / 03, numeric n, numeric k) +} + +/// Tabulation Stop Remove. +/// +/// `TSR` causes any character tabulation stop at character position `n` in the active line (the line that contains the +/// active presentation position) and lines of subsequent text in the presentation component to be cleared, but does +/// not affect other tabulation stops. +/// +pub fn TSR(n: u32) -> ControlFunction { + sequence!(02 / 00, 06 /04, numeric n) +} + +/// Thin Space Specification. +/// +/// `TSS` is used to establish the width of a thin space for subsequent text. The established width remains in effect +/// until the next occurrence of `TSS` in the data stream. +/// +/// `n` specifies the width of the thin space. +/// +/// The unit in which the parameter value is expressed is that established by the parameter value of SELECT SIZE UNIT +/// ([`SSU`]). +pub fn TSS(n: u32) -> ControlFunction { + sequence!(02 / 00, 04 / 05, numeric n) +} + +/// Line Position Absolute. +/// +/// `VPA` causes the active data position to be moved to line position `n` in the data component in a direction +/// parallel to the line progression. +/// +/// The default value for `n` is `1`. +pub fn VPA(n: Option) -> ControlFunction { + sequence!(06 / 04, numeric n, default 1) +} + +/// Line Position Backward. +/// +/// `VPB` causes the active data position to be moved by `n` line positions in the data component in a direction +/// opposite to that of the line progression. +/// +/// The default value for `n` is `1`. +pub fn VPB(n: Option) -> ControlFunction { + sequence!(06 / 11, numeric n, default 1) +} + +/// Line Position Forward. +/// +/// `VPR` causes the active data position to be moved `n` line positions in the data component in a direction parallel +/// to the line progression. +/// +/// The default value for `n` is `1`. +pub fn VPR(n: Option) -> ControlFunction { + sequence!(06 / 05, numeric n, default 1) +} diff --git a/src/control_strings.rs b/src/control_strings.rs new file mode 100644 index 0000000..43ac0a2 --- /dev/null +++ b/src/control_strings.rs @@ -0,0 +1,10 @@ +//! Control Strings. +//! +//! A control string is a string of bit combinations which may occur in the data stream as a logical entity for +//! control purposes. A control string consists of an opening delimiter, a command string or a character string, +//! and a terminating delimiter, the String Terminator (`ST`). +//! +//! A command string is a sequence of bit combinations in the range `00/08` to `00/13` and `02/00` to `07/14`. +//! +//! A character string is a sequence of any bit combination, except those representing Start Of String (`SOS`) or String +//! Terminator (`ST`). diff --git a/src/independent_control_functions.rs b/src/independent_control_functions.rs new file mode 100644 index 0000000..15e5471 --- /dev/null +++ b/src/independent_control_functions.rs @@ -0,0 +1,113 @@ +//! Independent Control Functions. +//! +//! These control functions are represented in 7-bit codes by 2-character escape sequences of the form `ESC Fs`, where +//! `ESC` is represented by bit combination `01/11` and `Fs` is represented by a bit combination from `06/00` to +//! `07/14`. +//! +//! ## Overview of the Independent Control Functions +//! +//! | Row Number | Column `06` | Column `07` | +//! | ---------: | :---------: | :---------: | +//! | `00` | [`DMI`] | -- | +//! | `01` | [`INT`] | -- | +//! | `02` | [`EMI`] | -- | +//! | `03` | [`RIS`] | -- | +//! | `04` | [`CMD`] | -- | +//! | `05` | -- | -- | +//! | `06` | -- | -- | +//! | `07` | -- | -- | +//! | `08` | -- | -- | +//! | `09` | -- | -- | +//! | `10` | -- | -- | +//! | `11` | -- | -- | +//! | `12` | -- | [`LS3R`] | +//! | `13` | -- | [`LS2R`] | +//! | `14` | [`LS2`] | [`LS1R`] | +//! | `15` | [`LS3`] | -- | +//! +//! ## Note +//! +//! `ESC Fs` sequences are registered in the ISO International Register of Coded Character Sets to be Used with Escape +//! Sequences, which is maintained by the Registration Authority for ISO 2375. + +use crate::ControlFunction; + +macro_rules! independent { + ($xx:literal/$yy:literal) => { + ControlFunction::new_independent_control_function(ascii!($xx / $yy)) + }; +} + +/// Coding Method Delimiter. +/// +/// `CMD` is used as the delimiter of a string of data coded according to Standard ECMA-35, and to switch to a general +/// level of control. +/// +/// The use of `CMD` is not mandatory if the higher level protocol defines means of delimiting the string, for instance, +/// by specifying the length of the string. +pub const CMD: ControlFunction = independent!(06 / 04); + +/// Disable Manual Input +/// +/// `DMI` causes the manual input facilities of a device to be disabled. +pub const DMI: ControlFunction = independent!(06 / 00); + +/// Enable Manual Input. +/// +/// `EMI` is used to enable the manual input facilities of a device. +pub const EMI: ControlFunction = independent!(06 / 02); + +/// Interrupt. +/// +/// `INT` is used to indicate to the receiving device that the current process is to be interrupted and an agreed +/// procedure is to be initiated. This control function is applicable to either direction of transmission. +pub const INT: ControlFunction = independent!(06 / 01); + +/// Locking-Shift One Right. +/// +/// `LS1R` is used for code extension purposes. It causes the meaning of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `LS1R` is defined in Standard ECMA-35. +pub const LS1R: ControlFunction = independent!(07 / 14); + +/// Locking-Shift Two. +/// +/// `LS2` is used for code extension purposes. It causes the meaning of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `LS2` is defined in Standard ECMA-35. +pub const LS2: ControlFunction = independent!(06 / 14); + +/// Locking-Shift Two Right. +/// +/// `LS2R` is used for code extension purposes. It causes the meaning of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `LS2R` is defined in Standard ECMA-35. +pub const LS2R: ControlFunction = independent!(07 / 13); + +/// Locking-Shift Three. +/// +/// `LS3` is used for code extension purposes. It causes the meaning of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `LS3` is defined in Standard ECMA-35. +pub const LS3: ControlFunction = independent!(06 / 15); + +/// Locking-Shift Three Right. +/// +/// `LS3R` is used for code extension purposes. It causes the meaning of the bit combinations following it in the data +/// stream to be changed. +/// +/// The use of `LS3R` is defined in Standard ECMA-35. +pub const LS3R: ControlFunction = independent!(07 / 12); + +/// Reset to Initial State. +/// +/// `RIS` causes a device to be reset to its initial state, i.e. the state it has after it is made operational. This +/// may imply, if applicable: clear tabulation stops, remove qualified areas, reset graphic rendition, put all character +/// positions into the erased state, move the active presentation position to the first position of the first line in +/// the presentation component, move the active data position to the first character position of the first line in the +/// data component, set the modes into the reset state, etc.. +pub const RIS: ControlFunction = independent!(06 / 03); diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..5afeccd --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,166 @@ +//! # ANSI Escape Code Library +//! +//! ANSI escape sequences are a standard for in-band signalling to control cursor location, color, font styling, and +//! other options on video text terminals and terminal emulators. +//! +//! This library contains all ANSI Escape Codes that are defined in the [ISO 6429 Standard][iso-6429]. ISO 6429 is +//! the international standard that followed from the efforts of aligning the european [ECMA-48 Standard][ecma-48] and +//! the american [ANSI X3.64 Standard][ansi-x364]. +//! +//! ## Notation +//! +//! In the [ECMA-48 Standard][ecma-48] a convention has been adopted to assist the reader of the Standard. +//! +//! Capital letters are used to refer to a specific control function, mode, mode setting, or graphic character in order +//! to avoid confusion, for example, between the concept `space`, and the character `SPACE`. +//! +//! As is intended by the [ECMA-48 Standard][ecma-48], this convention and all acronyms of modes, and control functions +//! are retained in this library, where rust permits. +//! +//! A character from the [ASCII table][ascii-table] is represented in the form `xx/yy`, where `xx` represents the column +//! number `00` to `07` in a 7-bit code table, and `yy` represents the row number `00` to `15`. +//! +//! ## Source Material +//! +//! The second, and newer, editions of the [ECMA-48 Standard][ecma-48] are based on the text of the +//! [ISO 6429 Standard][iso-6429] and are technically identical with it. Since the [ISO 6429 Standard][iso-6429] is not +//! freely available on the internet, this implementation is based on the publicly available documents of the +//! [ECMA-48 Standard][ecma-48]. In particular on edition 5 of the [ECMA-48 Standard][ecma-48], which is identical to +//! the third edition of [ISO-6429][iso-6429]. +//! +//! The [ANSI X3.64 Standard][ansi-x364] has been withdrawn by ANSI in 1994 in favour of the international standard. +//! +//! You can read more about the history of the standards on [Wikipedia: ANSI escape code][wikipedia-ansi]. +//! +//! [ansi-x364]: https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub86.pdf +//! [ascii-table]: https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png +//! [ecma-48]: https://www.ecma-international.org/publications-and-standards/standards/ecma-48/ +//! [iso-6429]: https://www.iso.org/standard/12782.html +//! [wikipedia-ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code +#![allow(dead_code)] + +use std::str; + +/// Convert the ascii table notation `xx/yy` into a rust string. +/// +/// A character from the [ASCII table][ascii-table] is represented in the form `xx/yy`, where `xx` represents the column +/// number `00` to `07` in a 7-bit code table, and `yy` represents the row number `00` to `15`. +/// +/// The macro can be used to convert a single code point into a str, or to convert a sequence of them. +/// +/// ``` +/// let a: &'static str = ascii!(06 / 01); +/// let abc: &'static str = ascii!(06 / 01, 06 / 02, 06 / 03); +/// ``` +/// +/// ## Safeness +/// +/// This macro converts the given `xx/yy` combination into a ascii code by the formula `(xx << 4) + yy`. +/// The result is passed to the unsafe function std::str::from_utf8_unchecked. +/// +/// This will result in an unsafe calculation, if the values for xx and yy are out of range. Valid ranges are: +/// +/// - `xx: [0,7]` +/// - `yy: [0,15]` +/// +/// Since this macro is not public and only used by the library itself, it is assumed to be used only within safe +/// bounds. +/// +/// [ascii-table]: https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png +macro_rules! ascii { + ($($xx:literal/$yy:literal), *) => { + unsafe { std::str::from_utf8_unchecked(&[$(($xx << 4) + $yy),*]) } + }; +} + +/// The different types of control functions. +enum ControlFunctionType { + /// Elements of the C0 set. + /// + /// C0 control functions are represented in 7-bit codes by bit combinations from 00/00 to 01/15. + C0, + + /// Elements of the C1 set. + /// + /// C1 control functions are represented in 7-bit codes by 2-character escape sequences of the form `ESC Fe`, + /// where `ESC` is represented by bit combination `01/11`, and `Fe` is represented by a bit combination from + /// `04/00` to `05/15`. + C1, + + /// Control Sequences. + /// + /// Control sequences are strings of bit combinations starting with the control function Control Function Introducer + /// (`CSI`), followed by one or more bit combinations representing parameters, if any, and by one ore more bit + /// combinations identifying the control function. The control function `CSI` itself is an element of the independent_control_function set. + ControlSequence, + + /// Independent Control Functions. + /// + /// Independent control functions are represented in 7-bit codes by 2-character escape sequences of the form + /// `ESC Fs`, where `ESC` is represented by bit combination `01/11`, and `Fs` is represented by a bit combination + /// from `06/00` to `07/14` + IndependentControlFunction, + + /// Control Strings. + /// + /// A control string is a string of bit combinations which may occur in the data stream as a logical entity for + /// control purposes. A control string consists of an opening delimiter, a command string or character string, and + /// a terminating delimiter, the String Terminator (`ST`). + ControlString, +} + +/// A control function. +pub struct ControlFunction { + function_type: ControlFunctionType, + value: &'static str, + parameters: Vec, +} + +impl ControlFunction { + /// Creates a new control function of type [C0][ControlFunctionType::C0]. + /// + /// C0 control functions do not accept any parameters. + const fn new_c0(value: &'static str) -> Self { + ControlFunction { + function_type: ControlFunctionType::C0, + value, + parameters: vec![], + } + } + + /// Creates a new control function of type [C1][ControlFunctionType::C1]. + /// + /// independent_control_function control functions do not accept any parameters. + const fn new_c1(value: &'static str) -> Self { + ControlFunction { + function_type: ControlFunctionType::C1, + value, + parameters: vec![], + } + } + + /// Creates a new control function of type [ControlSequence][ControlFunctionType::ControlSequence]. + const fn new_sequence(value: &'static str, parameters: Vec) -> Self { + ControlFunction { + function_type: ControlFunctionType::ControlSequence, + value, + parameters, + } + } + + /// Creates a new control function of type [IndependentControlFunction][ControlFunctionType::IndependentControlFunction]. + const fn new_independent_control_function(value: &'static str) -> Self { + ControlFunction { + function_type: ControlFunctionType::IndependentControlFunction, + value, + parameters: vec![], + } + } +} + +pub mod c0; +pub mod c1; +pub mod control_sequences; +pub mod control_strings; +pub mod independent_control_functions; +pub mod modes; diff --git a/src/modes.rs b/src/modes.rs new file mode 100644 index 0000000..dc240a8 --- /dev/null +++ b/src/modes.rs @@ -0,0 +1,123 @@ +/// Device Modes. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum Mode { + /// Guarded Area Transfer Mode `GATM`. + GuardedAreaTransferMode = 1, + + /// Keyboard Action Mode `KAM`. + KeyboardActionMode, + + /// Control Presentation Mode `CRM`. + ControlPresentationMode, + + /// Insertion Replacement Mode `IRM`. + InsertionReplacementMode, + + /// Status Report Transfer Mode `SRTM`. + StatusReportTransferMode, + + /// Erasure Mode `ERM`. + ErasureMode, + + /// Line Editing Mode `VEM`. + LineEditingMode, + + /// Bi-directional support mode `BDSM`. + BiDirectionalSupportMode, + + /// Device Component Select Mode `DCSM`. + DeviceComponentSelectMode, + + /// Character Editing Mode `HEM`. + CharacterEditingMode, + + /// Positioning Unit Mode `PUM`. + PositioningUnitMode, + + /// Send/Receive Mode `SRM`. + SendReceiveMode, + + /// Format Effector Action Mode `FEAM`. + FormatEffectorActionMode, + + /// Format Effector Transfer Mode `FETM`. + FormatEffectorTransferMode, + + /// Multiple Area Transfer Mode `MATM`. + MultipleAreaTransferMode, + + /// Transfer Termination Mode `TTM`. + TransferTerminationMode, + + /// Selected Area Transfer Mode `SATM`. + SelectedAreaTransferMode, + + /// Tabulation Stop Mode `TSM`. + TabulationStopMode, + + /// Graphic Rendition Combination Mode `GRCM`. + GraphicRenditionCombinationMode = 21, + + /// Zero Default Mode `ZDM`. + ZeroDefaultMode, +} + +/// Guarded Area Transfer Mode `GATM`. +pub const GATM: Mode = Mode::GuardedAreaTransferMode; + +/// Keyboard Action Mode `KAM`. +pub const KAM: Mode = Mode::KeyboardActionMode; + +/// Control Presentation Mode `CRM`. +pub const CRM: Mode = Mode::ControlPresentationMode; + +/// Insertion Replacement Mode `IRM`. +pub const IRM: Mode = Mode::InsertionReplacementMode; + +/// Status Report Transfer Mode `SRTM`. +pub const SRTM: Mode = Mode::StatusReportTransferMode; + +/// Erasure Mode `ERM`. +pub const ERM: Mode = Mode::ErasureMode; + +/// Line Editing Mode `VEM`. +pub const VEM: Mode = Mode::LineEditingMode; + +/// Bi-directional support mode `BDSM`. +pub const BDSM: Mode = Mode::BiDirectionalSupportMode; + +/// Device Component Select Mode `DCSM`. +pub const DCSM: Mode = Mode::DeviceComponentSelectMode; + +/// Character Editing Mode `HEM`. +pub const HEM: Mode = Mode::CharacterEditingMode; + +/// Positioning Unit Mode `PUM`. +pub const PUM: Mode = Mode::PositioningUnitMode; + +/// Send/Receive Mode `SRM`. +pub const SRM: Mode = Mode::SendReceiveMode; + +/// Format Effector Action Mode `FEAM`. +pub const FEAM: Mode = Mode::FormatEffectorActionMode; + +/// Format Effector Transfer Mode `FETM`. +pub const FETM: Mode = Mode::FormatEffectorTransferMode; + +/// Multiple Area Transfer Mode `MATM`. +pub const MATM: Mode = Mode::MultipleAreaTransferMode; + +/// Transfer Termination Mode `TTM`. +pub const TTM: Mode = Mode::TransferTerminationMode; + +/// Selected Area Transfer Mode `SATM`. +pub const SATM: Mode = Mode::SelectedAreaTransferMode; + +/// Tabulation Stop Mode `TSM`. +pub const TSM: Mode = Mode::TabulationStopMode; + +/// Graphic Rendition Combination Mode `GRCM`. +pub const GRCM: Mode = Mode::GraphicRenditionCombinationMode; + +/// Zero Default Mode `ZDM`. +pub const ZDM: Mode = Mode::ZeroDefaultMode;