1use std::{convert::Infallible, str::FromStr};
40
41use crate::{control_sequences::*, modes::Mode, ControlFunction, ControlFunctionType};
42
43macro_rules! param {
44 ($self:ident, $index:literal, $default:literal) => {
45 get_param(&$self.parameters, $index, $default)
46 };
47 ($self:ident, ordinal $index:literal, $default:literal) => {
48 ordinal_indicator(get_param(&$self.parameters, $index, $default))
49 };
50}
51
52macro_rules! explain_selection {
53 ($selection:ident, $self:ident, $index:literal) => {
54 $selection::from_str(
55 $self
56 .parameters
57 .get($index)
58 .map(&String::as_ref)
59 .unwrap_or(""),
60 )
61 .expect("Reached infallible code.")
62 .explain()
63 };
64}
65
66#[derive(Debug)]
67enum Function {
68 ACK,
70 BEL,
71 BS,
72 CAN,
73 CR,
74 DC1,
75 DC2,
76 DC3,
77 DC4,
78 DLE,
79 EM,
80 ENQ,
81 EOT,
82 ESC,
83 ETB,
84 ETX,
85 FF,
86 HT,
87 IS1,
88 IS2,
89 IS3,
90 IS4,
91 LF,
92 LS0,
93 LS1,
94 NAK,
95 NUL,
96 SOH,
97 STX,
98 SUB,
99 SYN,
100 VT,
101 APC,
103 BPH,
104 CCH,
105 CSI,
106 DCS,
107 EPA,
108 ESA,
109 HTJ,
110 HTS,
111 MW,
112 NBH,
113 NEL,
114 OSC,
115 PLD,
116 PLU,
117 PM,
118 PU1,
119 PU2,
120 RI,
121 SCI,
122 SOS,
123 SPA,
124 SSA,
125 SS2,
126 SS3,
127 ST,
128 STS,
129 VTS,
130 CMD,
132 DMI,
133 EMI,
134 INT,
135 LS1R,
136 LS2,
137 LS2R,
138 LS3,
139 LS3R,
140 RIS,
141 CBT,
143 CHA,
144 CHT,
145 CNL,
146 CPL,
147 CPR,
148 CTC,
149 CUB,
150 CUD,
151 CUF,
152 CUP,
153 CUU,
154 CVT,
155 DA,
156 DAQ,
157 DCH,
158 DL,
159 DSR,
160 DTA,
161 EA,
162 ECH,
163 ED,
164 EF,
165 EL,
166 FNK,
167 FNT,
168 GCC,
169 GSM,
170 GSS,
171 HPA,
172 HPB,
173 HPR,
174 HVP,
175 ICH,
176 IDCS,
177 IGS,
178 IL,
179 JFY,
180 MC,
181 NP,
182 PEC,
183 PFS,
184 PP,
185 PPA,
186 PPB,
187 PPR,
188 PTX,
189 QUAD,
190 REP,
191 RM,
192 SACS,
193 SAPV,
194 SCO,
195 SCP,
196 SCS,
197 SD,
198 SDS,
199 SEE,
200 SEF,
201 SGR,
202 SHS,
203 SIMD,
204 SL,
205 SLH,
206 SLL,
207 SLS,
208 SM,
209 SPD,
210 SPH,
211 SPI,
212 SPL,
213 SPQR,
214 SR,
215 SRCS,
216 SRS,
217 SSU,
218 SSW,
219 STAB,
220 SU,
221 SVS,
222 TAC,
223 TALE,
224 TATE,
225 TBC,
226 TCC,
227 TSR,
228 TSS,
229 VPA,
230 VPB,
231 VPR,
232 PRIVATE,
233}
234
235fn function(control_function: &ControlFunction<'_>) -> Function {
236 match control_function.function_type {
237 ControlFunctionType::C0 => {
238 let byte = control_function.value.as_bytes()[0];
240
241 match byte {
242 0 => Function::NUL,
243 1 => Function::SOH,
244 2 => Function::STX,
245 3 => Function::ETX,
246 4 => Function::EOT,
247 5 => Function::ENQ,
248 6 => Function::ACK,
249 7 => Function::BEL,
250 8 => Function::BS,
251 9 => Function::HT,
252 10 => Function::LF,
253 11 => Function::VT,
254 12 => Function::FF,
255 13 => Function::CR,
256 14 => Function::LS1,
257 15 => Function::LS0,
258 16 => Function::DLE,
259 17 => Function::DC1,
260 18 => Function::DC2,
261 19 => Function::DC3,
262 20 => Function::DC4,
263 21 => Function::NAK,
264 22 => Function::SYN,
265 23 => Function::ETB,
266 24 => Function::CAN,
267 25 => Function::EM,
268 26 => Function::SUB,
269 27 => Function::ESC,
270 28 => Function::IS4,
271 29 => Function::IS3,
272 30 => Function::IS2,
273 31 => Function::IS1,
274 _ => {
275 unreachable!("No C0 control function exists outside of above range")
276 }
277 }
278 }
279 ControlFunctionType::C1 => {
280 let byte = control_function.value.as_bytes()[0];
282
283 match byte {
284 66 => Function::BPH,
285 67 => Function::NBH,
286 69 => Function::NEL,
287 70 => Function::SSA,
288 71 => Function::ESA,
289 72 => Function::HTS,
290 73 => Function::HTJ,
291 74 => Function::VTS,
292 75 => Function::PLD,
293 76 => Function::PLU,
294 77 => Function::RI,
295 78 => Function::SS2,
296 79 => Function::SS3,
297 80 => Function::DCS,
298 81 => Function::PU1,
299 82 => Function::PU2,
300 83 => Function::STS,
301 84 => Function::CCH,
302 85 => Function::MW,
303 86 => Function::SPA,
304 87 => Function::EPA,
305 88 => Function::SOS,
306 90 => Function::SCI,
307 91 => Function::CSI,
308 92 => Function::ST,
309 93 => Function::OSC,
310 94 => Function::PM,
311 95 => Function::APC,
312 _ => {
313 unreachable!("No C1 control function exists outside of above range")
314 }
315 }
316 }
317 ControlFunctionType::IndependentControlFunction => {
318 let byte = control_function.value.as_bytes()[0];
320
321 match byte {
322 96 => Function::DMI,
323 97 => Function::INT,
324 98 => Function::EMI,
325 99 => Function::RIS,
326 100 => Function::CMD,
327 110 => Function::LS2,
328 111 => Function::LS3,
329 124 => Function::LS3R,
330 125 => Function::LS2R,
331 126 => Function::LS1R,
332 _ => {
333 unreachable!("No independent control function exists outside of above range")
334 }
335 }
336 }
337 ControlFunctionType::ControlSequence => {
338 let bytes = control_function.value.as_bytes();
339 if bytes.len() == 1 {
340 let byte = bytes[0];
342 return match byte {
343 64 => Function::ICH,
344 65 => Function::CUU,
345 66 => Function::CUD,
346 67 => Function::CUF,
347 68 => Function::CUB,
348 69 => Function::CNL,
349 70 => Function::CPL,
350 71 => Function::CHA,
351 72 => Function::CUP,
352 73 => Function::CHT,
353 74 => Function::ED,
354 75 => Function::EL,
355 76 => Function::IL,
356 77 => Function::DL,
357 78 => Function::EF,
358 79 => Function::EA,
359 80 => Function::DCH,
360 81 => Function::SEE,
361 82 => Function::CPR,
362 83 => Function::SU,
363 84 => Function::SD,
364 85 => Function::NP,
365 86 => Function::PP,
366 87 => Function::CTC,
367 88 => Function::ECH,
368 89 => Function::CVT,
369 90 => Function::CBT,
370 91 => Function::SRS,
371 92 => Function::PTX,
372 93 => Function::SDS,
373 94 => Function::SIMD,
374 96 => Function::HPA,
375 97 => Function::HPR,
376 98 => Function::REP,
377 99 => Function::DA,
378 100 => Function::VPA,
379 101 => Function::VPR,
380 102 => Function::HVP,
381 103 => Function::TBC,
382 104 => Function::SM,
383 105 => Function::MC,
384 106 => Function::HPB,
385 107 => Function::VPB,
386 108 => Function::RM,
387 109 => Function::SGR,
388 110 => Function::DSR,
389 111 => Function::DAQ,
390 112..=127 => Function::PRIVATE,
391 _ => {
392 unreachable!("No valid control sequence exist outside of above range")
393 }
394 };
395 }
396 if bytes.len() == 2 {
397 let byte = bytes[1];
399 return match byte {
400 64 => Function::SL,
401 65 => Function::SR,
402 66 => Function::GSM,
403 67 => Function::GSS,
404 68 => Function::FNT,
405 69 => Function::TSS,
406 70 => Function::JFY,
407 71 => Function::SPI,
408 72 => Function::QUAD,
409 73 => Function::SSU,
410 74 => Function::PFS,
411 75 => Function::SHS,
412 76 => Function::SVS,
413 77 => Function::IGS,
414 79 => Function::IDCS,
415 80 => Function::PPA,
416 81 => Function::PPR,
417 82 => Function::PPB,
418 83 => Function::SPD,
419 84 => Function::DTA,
420 85 => Function::SLH,
421 86 => Function::SLL,
422 87 => Function::FNK,
423 88 => Function::SPQR,
424 89 => Function::SEF,
425 90 => Function::PEC,
426 91 => Function::SSW,
427 92 => Function::SACS,
428 93 => Function::SAPV,
429 94 => Function::STAB,
430 95 => Function::GCC,
431 96 => Function::TATE,
432 97 => Function::TALE,
433 98 => Function::TAC,
434 99 => Function::TCC,
435 100 => Function::TSR,
436 101 => Function::SCO,
437 102 => Function::SRCS,
438 103 => Function::SCS,
439 104 => Function::SLS,
440 105 => Function::SPH,
441 106 => Function::SPL,
442 107 => Function::SCP,
443 112..=127 => Function::PRIVATE,
444 _ => {
445 unreachable!("No valid control sequence exist outside of above range")
446 }
447 };
448 }
449 unreachable!("No valid control sequence exist outside of above range")
450 }
451 }
452}
453
454fn ordinal_indicator(numeric_value: String) -> String {
455 numeric_value
456 .parse::<u64>()
457 .map(|value| match value % 10 {
458 0 | 4..=9 => numeric_value.clone(),
459 1 => format!("{}st", value),
460 2 => format!("{}nd", value),
461 3 => format!("{}rd", value),
462 _ => {
463 unreachable!("This is not reachable, all possible values of modulo 10 are covered.")
464 }
465 })
466 .unwrap_or_else(|_| numeric_value)
467}
468
469fn get_param(parameters: &Vec<String>, index: usize, default_value: u64) -> String {
470 parameters
471 .get(index)
472 .map(|value| value.to_owned())
473 .unwrap_or_else(|| format!("{default_value}"))
474}
475
476trait ExplainSelection {
477 fn explain(&self) -> String;
478}
479
480trait ExplainMode {
481 fn name(&self) -> String;
482 fn explain_reset(&self) -> String;
483 fn explain_set(&self) -> String;
484}
485
486pub trait Explain {
488 fn short_name(&self) -> Option<&'static str>;
492
493 fn long_name(&self) -> &'static str;
495
496 fn short_description(&self) -> String;
498
499 fn long_description(&self) -> String;
504}
505
506impl Explain for ControlFunction<'_> {
507 fn short_name(&self) -> Option<&'static str> {
508 match function(&self) {
509 Function::ACK => Some("ACK"),
510 Function::BEL => Some("BEL"),
511 Function::BS => Some("BS"),
512 Function::CAN => Some("CAN"),
513 Function::CR => Some("CR"),
514 Function::DC1 => Some("DC1"),
515 Function::DC2 => Some("DC2"),
516 Function::DC3 => Some("DC3"),
517 Function::DC4 => Some("DC4"),
518 Function::DLE => Some("DLE"),
519 Function::EM => Some("EM"),
520 Function::ENQ => Some("ENQ"),
521 Function::EOT => Some("EOT"),
522 Function::ESC => Some("ESC"),
523 Function::ETB => Some("ETB"),
524 Function::ETX => Some("ETX"),
525 Function::FF => Some("FF"),
526 Function::HT => Some("HT"),
527 Function::IS1 => Some("IS1"),
528 Function::IS2 => Some("IS2"),
529 Function::IS3 => Some("IS3"),
530 Function::IS4 => Some("IS4"),
531 Function::LF => Some("LF"),
532 Function::LS0 => Some("LS0"),
533 Function::LS1 => Some("LS1"),
534 Function::NAK => Some("NAK"),
535 Function::NUL => Some("NUL"),
536 Function::SOH => Some("SOH"),
537 Function::STX => Some("STX"),
538 Function::SUB => Some("SUB"),
539 Function::SYN => Some("SYN"),
540 Function::VT => Some("VT"),
541 Function::APC => Some("APC"),
542 Function::BPH => Some("BPH"),
543 Function::CCH => Some("CCH"),
544 Function::CSI => Some("CSI"),
545 Function::DCS => Some("DCS"),
546 Function::EPA => Some("EPA"),
547 Function::ESA => Some("ESA"),
548 Function::HTJ => Some("HTJ"),
549 Function::HTS => Some("HTS"),
550 Function::MW => Some("MW"),
551 Function::NBH => Some("NBH"),
552 Function::NEL => Some("NEL"),
553 Function::OSC => Some("OSC"),
554 Function::PLD => Some("PLD"),
555 Function::PLU => Some("PLU"),
556 Function::PM => Some("PM"),
557 Function::PU1 => Some("PU1"),
558 Function::PU2 => Some("PU2"),
559 Function::RI => Some("RI"),
560 Function::SCI => Some("SCI"),
561 Function::SOS => Some("SOS"),
562 Function::SPA => Some("SPA"),
563 Function::SSA => Some("SSA"),
564 Function::SS2 => Some("SS2"),
565 Function::SS3 => Some("SS3"),
566 Function::ST => Some("ST"),
567 Function::STS => Some("STS"),
568 Function::VTS => Some("VTS"),
569 Function::CMD => Some("CMD"),
570 Function::DMI => Some("DMI"),
571 Function::EMI => Some("EMI"),
572 Function::INT => Some("INT"),
573 Function::LS1R => Some("LS1R"),
574 Function::LS2 => Some("LS2"),
575 Function::LS2R => Some("LS2R"),
576 Function::LS3 => Some("LS3"),
577 Function::LS3R => Some("LS3R"),
578 Function::RIS => Some("RIS"),
579 Function::CBT => Some("CBT"),
580 Function::CHA => Some("CHA"),
581 Function::CHT => Some("CHT"),
582 Function::CNL => Some("CNL"),
583 Function::CPL => Some("CPL"),
584 Function::CPR => Some("CPR"),
585 Function::CTC => Some("CTC"),
586 Function::CUB => Some("CUB"),
587 Function::CUD => Some("CUD"),
588 Function::CUF => Some("CUF"),
589 Function::CUP => Some("CUP"),
590 Function::CUU => Some("CUU"),
591 Function::CVT => Some("CVT"),
592 Function::DA => Some("DA"),
593 Function::DAQ => Some("DAQ"),
594 Function::DCH => Some("DCH"),
595 Function::DL => Some("DL"),
596 Function::DSR => Some("DSR"),
597 Function::DTA => Some("DTA"),
598 Function::EA => Some("EA"),
599 Function::ECH => Some("ECH"),
600 Function::ED => Some("ED"),
601 Function::EF => Some("EF"),
602 Function::EL => Some("EL"),
603 Function::FNK => Some("FNK"),
604 Function::FNT => Some("FNT"),
605 Function::GCC => Some("GCC"),
606 Function::GSM => Some("GSM"),
607 Function::GSS => Some("GSS"),
608 Function::HPA => Some("HPA"),
609 Function::HPB => Some("HPB"),
610 Function::HPR => Some("HPR"),
611 Function::HVP => Some("HVP"),
612 Function::ICH => Some("ICH"),
613 Function::IDCS => Some("IDCS"),
614 Function::IGS => Some("IGS"),
615 Function::IL => Some("IL"),
616 Function::JFY => Some("JFY"),
617 Function::MC => Some("MC"),
618 Function::NP => Some("NP"),
619 Function::PEC => Some("PEC"),
620 Function::PFS => Some("PFS"),
621 Function::PP => Some("PP"),
622 Function::PPA => Some("PPA"),
623 Function::PPB => Some("PPB"),
624 Function::PPR => Some("PPR"),
625 Function::PTX => Some("PTX"),
626 Function::QUAD => Some("QUAD"),
627 Function::REP => Some("REP"),
628 Function::RM => Some("RM"),
629 Function::SACS => Some("SACS"),
630 Function::SAPV => Some("SAPV"),
631 Function::SCO => Some("SCO"),
632 Function::SCP => Some("SCP"),
633 Function::SCS => Some("SCS"),
634 Function::SD => Some("SD"),
635 Function::SDS => Some("SDS"),
636 Function::SEE => Some("SEE"),
637 Function::SEF => Some("SEF"),
638 Function::SGR => Some("SGR"),
639 Function::SHS => Some("SHS"),
640 Function::SIMD => Some("SIMD"),
641 Function::SL => Some("SL"),
642 Function::SLH => Some("SLH"),
643 Function::SLL => Some("SLL"),
644 Function::SLS => Some("SLS"),
645 Function::SM => Some("SM"),
646 Function::SPD => Some("SPD"),
647 Function::SPI => Some("SPI"),
648 Function::SPL => Some("SPL"),
649 Function::SPH => Some("SPH"),
650 Function::SPQR => Some("SPQR"),
651 Function::SR => Some("SR"),
652 Function::SRCS => Some("SRCS"),
653 Function::SRS => Some("SRS"),
654 Function::SSU => Some("SSU"),
655 Function::SSW => Some("SSW"),
656 Function::STAB => Some("STAB"),
657 Function::SU => Some("SU"),
658 Function::SVS => Some("SVS"),
659 Function::TAC => Some("TAC"),
660 Function::TALE => Some("TALE"),
661 Function::TATE => Some("TATE"),
662 Function::TBC => Some("TBC"),
663 Function::TCC => Some("TCC"),
664 Function::TSR => Some("TSR"),
665 Function::TSS => Some("TSS"),
666 Function::VPA => Some("VPA"),
667 Function::VPB => Some("VPB"),
668 Function::VPR => Some("VPR"),
669 Function::PRIVATE => None,
670 }
671 }
672
673 fn long_name(&self) -> &'static str {
674 match function(&self) {
675 Function::ACK => "Acknowledge",
676 Function::BEL => "Bell",
677 Function::BS => "Backspace",
678 Function::CAN => "Cancel",
679 Function::CR => "Carriage Return",
680 Function::DC1 => "Device Control One",
681 Function::DC2 => "Device Control Two",
682 Function::DC3 => "Device Control Three",
683 Function::DC4 => "Device Control Four",
684 Function::DLE => "Data Link Escape",
685 Function::EM => "End of Medium",
686 Function::ENQ => "Enquiry",
687 Function::EOT => "End of Transmission",
688 Function::ESC => "Escape",
689 Function::ETB => "End of Transmission Block",
690 Function::ETX => "End of Text",
691 Function::FF => "Form Feed",
692 Function::HT => "Character Tabulation",
693 Function::IS1 => "Information Separator One (US - Unit Separator)",
694 Function::IS2 => "Information Separator Two (RS - Record Separator)",
695 Function::IS3 => "Information Separator Three (GS - Group Separator)",
696 Function::IS4 => "Information Separator Four (FS - File Separator)",
697 Function::LF => "Line Feed",
698 Function::LS0 => "Locking-Shift Zero (Shift-In)",
699 Function::LS1 => "Locking-Shift One (Shift-Out)",
700 Function::NAK => "Negative Acknowledge",
701 Function::NUL => "Null",
702 Function::SOH => "Start of Heading",
703 Function::STX => "Start of Text",
704 Function::SUB => "Substitute",
705 Function::SYN => "Synchronous Idle",
706 Function::VT => "Line Tabulation",
707 Function::APC => "Application Program Command",
708 Function::BPH => "Break Permitted Here",
709 Function::CCH => "Cancel Character",
710 Function::CSI => "Control Sequence Introducer",
711 Function::DCS => "Device Control String",
712 Function::EPA => "End of Guarded Area",
713 Function::ESA => "End of Selected Area",
714 Function::HTJ => "Character Tabulation With Justification",
715 Function::HTS => "Character Tabulation Set",
716 Function::MW => "Message Waiting",
717 Function::NBH => "No Break Here",
718 Function::NEL => "Next Line",
719 Function::OSC => "Operating System Command",
720 Function::PLD => "Partial Line Forward",
721 Function::PLU => "Partial Line Backwards",
722 Function::PM => "Privacy Message",
723 Function::PU1 => "Private Use One",
724 Function::PU2 => "Private Use Two",
725 Function::RI => "Reverse Line Feed",
726 Function::SCI => "Single Character Introducer",
727 Function::SOS => "Start of String",
728 Function::SPA => "Start of Guarded Area",
729 Function::SSA => "Start of Selected Area",
730 Function::SS2 => "Single-Shift Two",
731 Function::SS3 => "Single-Shift Three",
732 Function::ST => "String Terminator",
733 Function::STS => "Set Transmit State",
734 Function::VTS => "Line Tabulation Set",
735 Function::CMD => "Coding Method Delimiter",
736 Function::DMI => "Disable Manual Input",
737 Function::EMI => "Enable Manual Input",
738 Function::INT => "Interrupt",
739 Function::LS1R => "Locking-Shift One Right",
740 Function::LS2 => "Locking-Shift Two",
741 Function::LS2R => "Locking-Shift Two Right",
742 Function::LS3 => "Locking-Shift Three",
743 Function::LS3R => "Locking-Shift Three Right",
744 Function::RIS => "Reset to Initial State",
745 Function::CBT => "Cursor Backwards Tabulation",
746 Function::CHA => "Cursor Character Absolute",
747 Function::CHT => "Cursor Forward Tabulation",
748 Function::CNL => "Cursors Next Line",
749 Function::CPL => "Cursor Preceding Line",
750 Function::CPR => "Active Position Report",
751 Function::CTC => "Cursor Tabulation Control",
752 Function::CUB => "Cursor Left",
753 Function::CUD => "Cursor Down",
754 Function::CUF => "Cursor Right",
755 Function::CUP => "Cursor Position",
756 Function::CUU => "Cursor Up",
757 Function::CVT => "Cursor Line Tabulation",
758 Function::DA => "Device Attributes",
759 Function::DAQ => "Define Area Qualification",
760 Function::DCH => "Delete Character",
761 Function::DL => "Delete Line",
762 Function::DSR => "Device Status Report",
763 Function::DTA => "Dimension Text Area",
764 Function::EA => "Erase Area",
765 Function::ECH => "Erase Character",
766 Function::ED => "Erase in Page",
767 Function::EF => "Erase in Field",
768 Function::EL => "Erase in Line",
769 Function::FNK => "Function Key",
770 Function::FNT => "Font Selection",
771 Function::GCC => "Graphic Character Combination",
772 Function::GSM => "Graphic Size Modification",
773 Function::GSS => "Graphic Size Selection",
774 Function::HPA => "Character Position Absolute",
775 Function::HPB => "Character Position Backwards",
776 Function::HPR => "Character Position Forward",
777 Function::HVP => "Character and Line Position",
778 Function::ICH => "Insert Character",
779 Function::IDCS => "Identify Device Control String",
780 Function::IGS => "Identify Graphic Subrepertoire",
781 Function::IL => "Insert Line",
782 Function::JFY => "Justify",
783 Function::MC => "Media Copy",
784 Function::NP => "Next Page",
785 Function::PEC => "Presentation Expand or Contract",
786 Function::PFS => "Page Format Selection",
787 Function::PP => "Preceding Page",
788 Function::PPA => "Page Position Absolute",
789 Function::PPB => "Page Position Backwards",
790 Function::PPR => "Page Position Forward",
791 Function::PTX => "Parallel Texts",
792 Function::QUAD => "Quad",
793 Function::REP => "Repeat",
794 Function::RM => "Reset Mode",
795 Function::SACS => "Set Additional Character Representation",
796 Function::SAPV => "Select Alternative Presentation Variants",
797 Function::SCO => "Select Character Orientation",
798 Function::SCP => "Select Character Path",
799 Function::SCS => "Set Character Spacing",
800 Function::SD => "Scroll Down",
801 Function::SDS => "Start Directed String",
802 Function::SEE => "Select Editing Extent",
803 Function::SEF => "Sheet Eject and Feed",
804 Function::SGR => "Select Graphic Rendition",
805 Function::SHS => "Select Character Spacing",
806 Function::SIMD => "Select Implicit Movement Direction",
807 Function::SL => "Scroll Left",
808 Function::SLH => "Set Line Home",
809 Function::SLL => "Set Line Limit",
810 Function::SLS => "Set Line Spacing",
811 Function::SM => "Set Mode",
812 Function::SPD => "Select Presentation Direction",
813 Function::SPH => "Set Page Home",
814 Function::SPI => "Spacing Increment",
815 Function::SPL => "Set Page Limit",
816 Function::SPQR => "Select Page Quality and Rapidity",
817 Function::SR => "Scroll Right",
818 Function::SRCS => "Set Reduced Character Separation",
819 Function::SRS => "Start Reversed String",
820 Function::SSU => "Select Size Unit",
821 Function::SSW => "Set Space Width",
822 Function::STAB => "Selective Tabulation",
823 Function::SU => "Scroll Up",
824 Function::SVS => "Select Line Spacing",
825 Function::TAC => "Tabulation Aligned Centred",
826 Function::TALE => "Tabulation Aligned Leading Edge",
827 Function::TATE => "Tabulation Aligned Trailing Edge",
828 Function::TBC => "Tabulation Clear",
829 Function::TCC => "Tabulation Centred on Character",
830 Function::TSR => "Tabulation Stop Remove",
831 Function::TSS => "Thin Space Specification",
832 Function::VPA => "Line Position Absolute",
833 Function::VPB => "Line Position Backwards",
834 Function::VPR => "Line Position Forward",
835 Function::PRIVATE => "Private Use / Experimental Use",
836 }
837 }
838
839 fn short_description(&self) -> String {
840 match function(&self) {
841 Function::ACK => {
842 String::from("Transmitted by a receiver as an affirmative response to the sender.")
843 }
844 Function::BEL => String::from("Calls for attention."),
845 Function::BS => {
846 String::from("Causes the active data position to be moved one character backwards.")
847 }
848 Function::CAN => String::from("Indicate that the preceding data is in error."),
849 Function::CR => String::from("Move to the beginning of the line."),
850 Function::DC1 => {
851 String::from("Primarily intended for turning on or starting an ancillary device.")
852 }
853 Function::DC2 => {
854 String::from("Primarily intended for turning on or starting an ancillary device.")
855 }
856 Function::DC3 => {
857 String::from("Primarily intended for turning off or stopping an ancillary device.")
858 }
859 Function::DC4 => String::from(
860 "Primarily intended for turning off, stopping, or interrupting an ancillary device."
861 ),
862 Function::DLE => String::from("Used exclusively to provide supplementary transmission control functions."),
863 Function::EM => String::from("Identifies the physical end of a medium."),
864 Function::ENQ => String::from("Transmitted by a sender as a request for a response from a receiver."),
865 Function::EOT => String::from("Indicates the conclusion of the transmission of one or more texts."),
866 Function::ESC => String::from("Used for code extension purposes."),
867 Function::ETB => String::from(
868 concat!(
869 "Indicates the end of a block of data, where the data are divided into such blocks for ",
870 "transmission purposes."
871 )
872 ),
873 Function::ETX => String::from("Indicates the end of a text."),
874 Function::FF => String::from(
875 "Causes the active presentation position to be moved to the line home position of the next line."
876 ),
877 Function::HT => String::from(
878 concat!(
879 "Causes the active presentation position to be moved to the following character tabulation stop ",
880 "in the presentation component."
881 )
882 ),
883 Function::IS1 => String::from("Separates and qualifies data logically."),
884 Function::IS2 => String::from("Separates and qualifies data logically."),
885 Function::IS3 => String::from("Separates and qualifies data logically."),
886 Function::IS4 => String::from("Separates and qualifies data logically."),
887 Function::LF => String::from("Move to following line."),
888 Function::LS0 => String::from("Used for code extension purposes."),
889 Function::LS1 => String::from("Used for code extension purposes."),
890 Function::NAK => String::from("Transmitted by a receiver as a negative response to the sender."),
891 Function::NUL => String::from("Used for media-fill or time-fill."),
892 Function::SOH => String::from("Indicates the beginning of a heading."),
893 Function::STX => String::from("Indicates the beginning of a text and the end of a heading."),
894 Function::SUB => String::from(
895 "Used in the place of a character that has been found to be invalid or in error"
896 ),
897 Function::SYN => String::from(
898 "Used by a synchronous transmission system in the absence of any other character."
899 ),
900 Function::VT => String::from("Move to the next line that has a line tabulation stop."),
901 Function::APC => String::from("Opening delimiter of a control string for application program use."),
902 Function::BPH => String::from("A break may occur here when text is formatted."),
903 Function::CCH => String::from(
904 concat!(
905 "Indicates that both the preceding graphic character in the data stream, and this character ",
906 "should be ignored."
907 )
908 ),
909 Function::CSI => String::from("Used as the first character of a longer control sequence."),
910 Function::DCS => String::from("Opening delimiter of a control string for device control use."),
911 Function::EPA => String::from("End of an area that protects its content against unwanted alteration."),
912 Function::ESA => String::from(
913 "End of an area selected for transferring or transmitting to an ancillary input/output device."
914 ),
915 Function::HTJ => String::from(
916 concat!(
917 "Shift the contents of the active field forward, so that it ends in before of the next character ",
918 "tabulation stop."
919 )
920 ),
921 Function::HTS => String::from("Set a character tabulation stop at the current position."),
922 Function::MW => String::from("Sets a message waiting indicator in the receiving device."),
923 Function::NBH => String::from("A line break shall not occur here when the text is formatted."),
924 Function::NEL => String::from("Move to the next line."),
925 Function::OSC => String::from("Opening delimiter of a control string for operating system use."),
926 Function::PLD => String::from(
927 "Move to an imaginary line with a partial offset downwards of the current line."
928 ),
929 Function::PLU => String::from(
930 "Move to an imaginary line with a partial offset upwards of the current line."
931 ),
932 Function::PM => String::from("Opening delimiter of a control string for privacy message use."),
933 Function::PU1 => String::from(
934 "Reserved for function without standardized meaning, for private use as required."
935 ),
936 Function::PU2 => String::from(
937 "Reserved for function without standardized meaning, for private use as required."
938 ),
939 Function::RI => String::from("Move to the preceding line."),
940 Function::SCI => String::from(
941 "This character and the following one represent a control function or a graphic character."
942 ),
943 Function::SOS => String::from("Opening delimiter of a control String."),
944 Function::SPA => String::from("
945 First position of a string that is guarded against manual alteration, transmission, transferor deletion."
946 ),
947 Function::SSA => String::from(
948 concat!(
949 "First position of a string that is eligible to be transmitted or transferred to an ancillary ",
950 "input/output device."
951 )
952 ),
953 Function::SS2 => String::from(
954 concat!(
955 "Used for code extension purposes. Changes the meaning of the bit combinations following it in ",
956 "the data stream."
957 )
958 ),
959 Function::SS3 => String::from(
960 concat!(
961 "Used for code extension purposes. Changes the meaning of the bit combinations following it in ",
962 "the data stream."
963 )
964 ),
965 Function::ST => String::from("Closing delimiter of a control string opened by APC, DCS, OSC, PM or SOS."),
966 Function::STS => String::from(
967 concat!(
968 "Establish the transmit state in the receiving device. In this state the transmission of data ",
969 "from the device is possible."
970 )
971 ),
972 Function::VTS => String::from("Set a line tabulation stop at the active line."),
973 Function::CMD => String::from("Delimits a string of data coded according to standard ECMA-35."),
974 Function::DMI => String::from("Causes the manual input facilities of a device to be disabled."),
975 Function::EMI => String::from("Causes the manual input facilities of a device to be enabled."),
976 Function::INT => String::from(
977 concat!(
978 "Indicate to the receiving device that the current process is to be interrupted and an agreed ",
979 "procedure is to be initiated."
980 )
981 ),
982 Function::LS1R => String::from(
983 "Used for code extension purposes. Changes the meaning of the following characters in the data stream."
984 ),
985 Function::LS2 => String::from(
986 "Used for code extension purposes. Changes the meaning of the following characters in the data stream."
987 ),
988 Function::LS2R => String::from(
989 "Used for code extension purposes. Changes the meaning of the following characters in the data stream."
990 ),
991 Function::LS3 => String::from(
992 "Used for code extension purposes. Changes the meaning of the following characters in the data stream."
993 ),
994 Function::LS3R => String::from(
995 "Used for code extension purposes. Changes the meaning of the following characters in the data stream."
996 ),
997 Function::RIS => String::from("Causes a device to be reset to its initial state."),
998 Function::CBT => format!(
999 "Causes the active position to be moved backwards by {} tabulation stops.",
1000 param!(self, 0, 1)
1001 ),
1002 Function::CHA => format!(
1003 "Causes the active position to be set to character position {} in the active line",
1004 param!(self, 0, 1)
1005 ),
1006 Function::CHT => format!(
1007 "Causes the active position to be moved forward by {} tabulation stops.",
1008 param!(self, 0, 1)
1009 ),
1010 Function::CNL => format!(
1011 "Causes the active position to be moved to the first character of the {} following line.",
1012 param!(self, ordinal 0, 1)
1013 ),
1014 Function::CPL => format!(
1015 concat!(
1016 "Causes the active position to be moved to the first character of the {} preceding line."
1017 ),
1018 param!(self, ordinal 0, 1)
1019 ),
1020 Function::CPR => format!(
1021 concat!(
1022 "The active position is reported to be in line {} at character position {}."
1023 ),
1024 param!(self, 0, 1), param!(self, 1, 1)
1025 ),
1026 Function::CTC => explain_selection!(TabulationControl, self, 0),
1027 Function::CUB => format!(
1028 "Move the active position {} characters to the left.",
1029 param!(self, 0, 1)
1030 ),
1031 Function::CUD => format!(
1032 "Move the active position {} lines downwards.",
1033 param!(self, 0, 1)
1034 ),
1035 Function::CUF => format!(
1036 "Move the active position {} characters to the right.",
1037 param!(self, 0, 1)
1038 ),
1039 Function::CUP => format!(
1040 "Move the active position to line {} and character {}.",
1041 param!(self, 0, 1),
1042 param!(self, 1, 1),
1043 ),
1044 Function::CUU => format!(
1045 "Move the active position {} lines upwards.",
1046 param!(self, 0, 1)
1047 ),
1048 Function::CVT => format!(
1049 "Causes the active position to the {} following line tabulation stop.",
1050 param!(self, ordinal 0, 1)
1051 ),
1052 Function::DA => explain_selection!(DeviceAttributes, self, 0),
1053 Function::DAQ => format!(
1054 "The active position is the first position of a qualified area. This area {}.",
1055 explain_selection!(AreaQualification, self, 0),
1056 ),
1057 Function::DCH => format!(
1058 "Delete {} characters, starting from the active position to the left.",
1059 param!(self, 0, 1)
1060 ),
1061 Function::DL => format!(
1062 "Delete {} lines",
1063 param!(self, 0, 1)
1064 ),
1065 Function::DSR => explain_selection!(DeviceStatusReport, self, 0),
1066 Function::DTA => format!(
1067 concat!(
1068 "Establishes the dimension of the text area for subsequent pages. Dimension perpendicular to the ",
1069 "line orientation: {}. Dimension parallel to the line orientation: {}."
1070 ),
1071 param!(self, 0, 0),
1072 param!(self, 1, 0)
1073 ),
1074 Function::EA => format!("This {}.", explain_selection!(EraseArea, self, 0)),
1075 Function::ECH => format!(
1076 concat!(
1077 "Erase {} characters from the active position to the right."
1078 ),
1079 param!(self, 0, 1)
1080 ),
1081 Function::ED => format!("This {}.", explain_selection!(ErasePage, self, 0)),
1082 Function::EF => format!("This {}.", explain_selection!(EraseField, self, 0)),
1083 Function::EL => format!("This {}.", explain_selection!(EraseLine, self, 0)),
1084 Function::FNK => format!("Function Key number {} has been pressed.",
1085 param!(self, 0, 1)
1086 ),
1087 Function::FNT => format!(
1088 concat!(
1089 "Indicates that the {} should be set to font {} and be accessible as {} from here on."
1090 ),
1091 explain_selection!(Font, self, 0),
1092 param!(self, 1, 0),
1093 explain_selection!(Font, self, 0)
1094 ),
1095 Function::GCC => explain_selection!(GraphicCharacterCombination, self, 0),
1096 Function::GSM => format!(
1097 "Modify the text height and / or width of all fonts to {}% height and {}% width.",
1098 param!(self, 0, 100),
1099 param!(self, 1, 100)
1100 ),
1101 Function::GSS => format!(
1102 "Modify the text height of all fonts to {}. The width is implicitly defined by the height.",
1103 param!(self, 0, 0)
1104 ),
1105 Function::HPA => format!(
1106 "Move the active data position to character position {} in the active line.",
1107 param!(self, 0, 1)
1108 ),
1109 Function::HPB => format!(
1110 "Move the active data position backwards by {} characters.",
1111 param!(self, 0, 1)
1112 ),
1113 Function::HPR => format!(
1114 "Move the active data position forward by {} characters.",
1115 param!(self, 0, 1)
1116 ),
1117 Function::HVP => format!(
1118 "Move the active data position to the {} line and {} character.",
1119 param!(self, ordinal 0, 1),
1120 param!(self, ordinal 1, 1)
1121 ),
1122 Function::ICH => format!(
1123 "Prepare the insertion of {} characters.",
1124 param!(self, 0, 1)
1125 ),
1126 Function::IDCS => explain_selection!(IdentifyDeviceControlString, self, 0),
1127 Function::IGS => format!(
1128 "The graphic subrepertoire {} is used in the subsequent text.",
1129 param!(self, 0, 0)
1130 ),
1131 Function::IL => format!(
1132 "Prepare the insertion of {} liens.",
1133 param!(self, 0, 1)
1134 ),
1135 Function::JFY => explain_selection!(Justification, self, 0),
1136 Function::MC => explain_selection!(MediaCopy, self, 0),
1137 Function::NP => format!(
1138 "Display the {} following page in the presentation component.",
1139 param!(self, ordinal 0, 1)
1140 ),
1141 Function::PEC => format!(
1142 concat!(
1143 "Display the following graphic characters with spacing and extent in {}."
1144 ),
1145 explain_selection!(PresentationExpandContract, self, 0)
1146 ),
1147 Function::PFS => explain_selection!(PageFormat, self, 0),
1148 Function::PP => format!(
1149 "Display the {} preceding page in the presentation component.",
1150 param!(self, ordinal 0, 1)
1151 ),
1152 Function::PPA => format!(
1153 "Causes the active data position to be moved to the corresponding character position on page {}.",
1154 param!(self, 0, 1)
1155 ),
1156 Function::PPB => format!(
1157 concat!(
1158 "Causes the active data position to be moved to the corresponding character position on the {} ",
1159 "previous pages."
1160 ),
1161 param!(self, ordinal 0, 1)
1162 ),
1163 Function::PPR => format!(
1164 concat!(
1165 "Causes the active data position to be moved to the corresponding character position on the {} ",
1166 "following pages."
1167 ),
1168 param!(self, ordinal 0, 1)
1169 ),
1170 Function::PTX => explain_selection!(ParallelText, self, 0),
1171 Function::QUAD => format!(
1172 "Indicates the end of a string of graphic characters that are to be positioned on a single line {}.",
1173 explain_selection!(Alignment, self, 0)
1174 ),
1175 Function::REP => format!(
1176 "Repeat the previous graphic character {} times.",
1177 param!(self, 0, 1)
1178 ),
1179 Function::RM => format!(
1180 "Reset the following Modes: {}",
1181 self.parameters.iter().map(|value| {
1182 value.parse::<Mode>().expect("Expect only valid Modes").name()
1183 }).fold(String::new(), |mut modes, mode| {
1184 modes.push_str(", ");
1185 modes.push_str(&mode);
1186 modes
1187 })
1188 ),
1189 Function::SACS => format!(
1190 "Enlarge inter-character escapement by {} units.",
1191 param!(self, 0, 0)
1192 ),
1193 Function::SAPV => format!(
1194 "Select an alternative presentation variant for the subsequent text. {}",
1195 explain_selection!(PresentationVariant, self, 0)
1196 ),
1197 Function::SCO => format!(
1198 "Establishes the amount of rotation of graphic characters following. {}",
1199 explain_selection!(CharacterOrientation, self, 0)
1200 ),
1201 Function::SCP => format!(
1202 "Change the character path. {} {}",
1203 explain_selection!(CharacterPath, self, 0),
1204 explain_selection!(CharacterPathScope, self, 1)
1205 ),
1206 Function::SCS => format!(
1207 "Character are spaced by {} units",
1208 param!(self, 0, 0)
1209 ),
1210 Function::SD => format!(
1211 concat!(
1212 "Scroll down by {} lines."
1213 ),
1214 param!(self, 0, 1)
1215 ),
1216 Function::SDS => explain_selection!(StringDirection, self, 0),
1217 Function::SEE => format!(
1218 "When character or line insertions or deletions require content to be shifted, {}.",
1219 explain_selection!(EditingExtend, self, 0)
1220 ),
1221 Function::SEF => format!(
1222 "{} {}",
1223 explain_selection!(Load, self, 0),
1224 explain_selection!(Stack, self, 1)
1225 ),
1226 Function::SGR => format!(
1227 "Change the representation of following text. {}.",
1228 self.parameters.iter().map(|value| {
1229 value.parse::<GraphicRendition>().expect("Expect only valid Graphic Renditions").explain()
1230 }).fold(String::new(), |mut renditions, rendition| {
1231 renditions.push_str(", ");
1232 renditions.push_str(&rendition);
1233 renditions
1234 })
1235 ),
1236 Function::SHS => explain_selection!(CharacterSpacing, self, 0),
1237 Function::SIMD => explain_selection!(MovementDirection, self, 0),
1238 Function::SL => format!(
1239 "Scroll left by {} characters",
1240 param!(self, 0, 1)
1241 ),
1242 Function::SLH => format!(
1243 "Set the line home position to line {} for the active and following lines.",
1244 param!(self, 0, 0)
1245 ),
1246 Function::SLL => format!(
1247 "Set the line limit position to character position {} for the active and following lines.",
1248 param!(self, 0, 0)
1249 ),
1250 Function::SLS => format!(
1251 "Set the line spacing to {}, expressed in the unit established by 'Select Size Unit' (SSU).",
1252 param!(self, 0, 0)
1253 ),
1254 Function::SM => format!(
1255 "Set the following Modes: {}",
1256 self.parameters.iter().map(|value| {
1257 value.parse::<Mode>().expect("Expect only valid Modes").name()
1258 }).fold(String::new(), |mut modes, mode| {
1259 modes.push_str(", ");
1260 modes.push_str(&mode);
1261 modes
1262 })
1263 ),
1264 Function::SPD => format!(
1265 "In {}, set the presentation direction to {}.",
1266 explain_selection!(PresentationDirectionScope, self, 1),
1267 explain_selection!(PresentationDirection, self, 0)
1268 ),
1269 Function::SPH => format!(
1270 "Set the page home position to line position {}.",
1271 param!(self, 0, 0)
1272 ),
1273 Function::SPI => format!(
1274 concat!(
1275 "Establish the spacing increment to {} line spacing and {} character spacing, expressed in the ",
1276 "unit established by 'Select Size Unit' (SSU)."
1277 ),
1278 param!(self, 0, 0),
1279 param!(self, 1, 0)
1280 ),
1281 Function::SPL => format!(
1282 "Set the page limit position to line {} for the active and following lines.",
1283 param!(self, 0, 0)
1284 ),
1285 Function::SPQR => explain_selection!(PrintQuality, self, 0),
1286 Function::SR => format!(
1287 "Scroll right by {} characters.",
1288 param!(self, 0, 1)
1289 ),
1290 Function::SRCS => format!(
1291 "Establish reduced inter-character escapement by {} units for subsequent text.",
1292 param!(self, 0, 0)
1293 ),
1294 Function::SRS => explain_selection!(ReversedString, self, 0),
1295 Function::SSU => format!(
1296 "The size unit for operation is expressed as {}",
1297 explain_selection!(SizeUnit, self, 0)
1298 ),
1299 Function::SSW => format!(
1300 "Set the escapement of space to {} units.",
1301 param!(self, 0, 0)
1302 ),
1303 Function::STAB => format!(
1304 concat!(
1305 "Causes subsequent text in the presentation component to be aligned according to the position and ",
1306 "properties of a tabulation stop which is selected from a list according to the value of the ",
1307 "parameter: {}."
1308 ),
1309 param!(self, 0, 0)
1310 ),
1311 Function::SU => format!(
1312 "Scroll up by {} lines.",
1313 param!(self, 0, 1)
1314 ),
1315 Function::SVS => explain_selection!(LineSpacing, self, 0),
1316 Function::TAC => format!(
1317 concat!(
1318 "Causes a character tabulation stop calling for centring to be set at character position {} in ",
1319 "the active line."
1320 ),
1321 param!(self, 0, 0)
1322 ),
1323 Function::TALE => format!(
1324 concat!(
1325 "Causes a character tabulation stop calling for leading edge alignment to be set at character ",
1326 "position {} in the active line."
1327 ),
1328 param!(self, 0, 0)
1329 ),
1330 Function::TATE => format!(
1331 concat!(
1332 "Causes a character tabulation stop calling for trailing edge alignment to be set at character ",
1333 "position {} in the active line."
1334 ),
1335 param!(self, 0, 0)
1336 ),
1337 Function::TBC => explain_selection!(ClearTabulation, self, 0),
1338 Function::TCC => format!(
1339 concat!(
1340 "Causes a character tabulation stop calling for alignment of a target graphic character {} to be ",
1341 "set at character position {} in the active line."
1342 ),
1343 param!(self, 1, 32),
1344 param!(self, 0, 0)
1345 ),
1346 Function::TSR => format!(
1347 concat!(
1348 "Causes any character tabulation stop at character position {} in the active line and subsequent ",
1349 "lines to be cleared."
1350 ),
1351 param!(self, 0, 0)
1352 ),
1353 Function::TSS => format!(
1354 "Establish the width of a thin space for subsequent text to be {} units.",
1355 param!(self, 0, 0)
1356 ),
1357 Function::VPA => format!(
1358 concat!(
1359 "Causes the active data position to be moved to line position {} in the data component in a ",
1360 "direction parallel to the line progression."
1361 ),
1362 param!(self, 0, 1)
1363 ),
1364 Function::VPB => format!(
1365 concat!(
1366 "Causes the active data position to be moved by {} line positions in the data component in a ",
1367 "direction opposite of that of the line progression."
1368 ),
1369 param!(self, 0, 1)
1370 ),
1371 Function::VPR => format!(
1372 concat!(
1373 "Causes the active data position to be moved {} line positions in the data component in a ",
1374 "direction parallel of the line progression."
1375 ),
1376 param!(self, 0, 1)
1377 ),
1378 Function::PRIVATE => String::from("Reserved for private use / not standardized."),
1379 }
1380 }
1381
1382 fn long_description(&self) -> String {
1383 match function(&self) {
1384 Function::BEL => String::from(
1385 "Calls for the attention of the user by controlling an alarm or attention device.",
1386 ),
1387 Function::BS => String::from(
1388 concat!(
1389 "Causes the active data position to be moved one character position in the direction opposite to ",
1390 "that of the implicit character movement. The direction of the implicit movement depends on the ",
1391 "parameter value of 'Select Implicit Movement Direction' (SIMD)."
1392 )
1393 ),
1394 Function::CAN => String::from(
1395 concat!(
1396 "Indicates that the data preceding it is in error. As a result, this data shall be ignored. ",
1397 "The specific meaning of this control function shall be defined for each application and/or ",
1398 "between sender and recipient."
1399 )
1400 ),
1401 Function::CR => String::from(
1402 concat!(
1403 "Move the cursor to the beginning of the line. The exact meaning depends on the setting of ",
1404 "'Device Component Select Mode' (DCSM) and on the parameter value of 'Select Implicit Movement ",
1405 "Direction' (SIMD).",
1406 "\n",
1407 "\n",
1408 "If the DCSM is set to 'Presentation' and SIMD is set to 'Normal', it ",
1409 "causes the active presentation position to be moved to the line home position of the same line ",
1410 "in the presentation component. The line home position is established by the parameter value of ",
1411 "'Set Line Home' SLH.",
1412 "\n",
1413 "With SIMD set to 'Opposite', it causes the active presentation position ",
1414 "to be moved to the line limit position of the same line in the presentation component. ",
1415 "The line limit position is established by the parameter value of 'Set Line Limit' (SLL).",
1416 "\n",
1417 "\n",
1418 "If the DCSM is set to 'Data' and SIMD is set to 'Normal', it causes the active data position to ",
1419 "be moved to the line home position of the same line in the data component. The line home ",
1420 "position is established by the parameter value of 'Set Line Home' (SLH)",
1421 "\n",
1422 "With SIMD set to 'Opposite', it causes the active data position to be moved to the line limit ",
1423 "position of the same line in the data component. The line limit position position is established ",
1424 "by the parameter value of 'Set Line Limit' (SLL)."
1425 )
1426 ),
1427 Function::DC1 => String::from(
1428 concat!(
1429 "Primarily intended for turning on or starting an ancillary device. If it is not required for ",
1430 "this purpose, it may be used to restore a device to the basic mode of operation. When used for ",
1431 "data flow control, it is also sometimes called X-ON."
1432 )
1433 ),
1434 Function::DC2 => String::from(
1435 concat!(
1436 "Primarily intended for turning on or starting an ancillary device. If it is not required for ",
1437 "this purpose, it may be used to set a device to a special mode of operation (in which case DC1 ",
1438 "is used to restore the mode of operation to the normal mode), or for any other device control ",
1439 "function not provided by other DCs."
1440 )
1441 ),
1442 Function::DC3 => String::from(
1443 concat!(
1444 "Primarily intended for turning off or stopping an ancillary device. This function may be a ",
1445 "secondary level stop, for example wait, pause, stand-by, or halt (in which case DC1 is used to ",
1446 "restore normal operation). If it is not required for this purpose, it may be used for any other ",
1447 "device control function not provided by other DCs."
1448 )
1449 ),
1450 Function::DC4 => String::from(
1451 concat!(
1452 "Primarily intended for turning off, stopping, or interrupting an ancillary device. If it is not ",
1453 "required for this purpose, it may be used for any other device control function not provided by ",
1454 "other DCs."
1455 )
1456 ),
1457 Function::EM => String::from(
1458 concat!(
1459 "Identifies the physical end of a medium, or the end of the used portion of a medium, or the end ",
1460 "of the wanted portion of data recorded on a medium."
1461 )
1462 ),
1463 Function::ESC => String::from(
1464 concat!(
1465 "Used for code extension purposes. It causes the meanings of a limited number of bit combinations ",
1466 "following it in the data stream to be changed."
1467 )
1468 ),
1469 Function::FF => String::from(
1470 concat!(
1471 "Causes the active presentation position to be moved to the corresponding character position of ",
1472 "the line at the page home position of the next form or page in the presentation component. The ",
1473 "page home position is established by the parameter value of 'Set Page Home' (SPH)."
1474 )
1475 ),
1476 Function::HT => String::from(
1477 concat!(
1478 "Causes the active presentation position to be moved to the following character tabulation stop ",
1479 "in the presentation component. In addition, if that following character tabulation stop has been ",
1480 "set by 'Tabulation Align Center' (TAC), 'Tabulation Align Leading Edge' (TALE), or 'Tabulation ",
1481 "Centred On Character' (TACE), it causes the beginning of a string of text which is to be ",
1482 "positioned within a line according to the properties of that tabulation stop. The end of the ",
1483 "string is indicated by the next occurrence of HT, CR, or NEL in the data stream."
1484 )
1485 ),
1486 Function::IS1 => String::from(
1487 concat!(
1488 "Separates and qualifies data logically, its specific meaning has to be defined for each ",
1489 "application. If this control function is used in hierarchical order, it may delimit a data item ",
1490 "called a unit."
1491 )
1492 ),
1493 Function::IS2 => String::from(
1494 concat!(
1495 "Separates and qualifies data logically, its specific meaning has to be defined for each ",
1496 "application. If this control function is used in hierarchical order, it may delimit a data item ",
1497 "called a record."
1498 )
1499 ),
1500 Function::IS3 => String::from(
1501 concat!(
1502 "Separates and qualifies data logically, its specific meaning has to be defined for each ",
1503 "application. If this control function is used in hierarchical order, it may delimit a data item ",
1504 "called a group."
1505 )
1506 ),
1507 Function::IS4 => String::from(
1508 concat!(
1509 "Separates and qualifies data logically, its specific meaning has to be defined for each ",
1510 "application. If this control function is used in hierarchical order, it may delimit a data item ",
1511 "called a file."
1512 )
1513 ),
1514 Function::LF => String::from(
1515 concat!(
1516 "If the 'Device Component Select Mode' is set to 'Presentation', it causes the active ",
1517 "presentation position to be moved to the corresponding character position of the following line ",
1518 "in the presentation component.",
1519 "\n",
1520 "\n",
1521 "If the 'Device Component Select Mode' is set to 'Data', it causes the active data position to be ",
1522 "moved to the corresponding character position of the following line in the data component."
1523 )
1524 ),
1525 Function::LS0 => String::from(
1526 concat!(
1527 "Used for code extension purposes. It causes the meanings of the bit combinations following it in ",
1528 "the data stream to be changed."
1529 )
1530 ),
1531 Function::LS1 => String::from(
1532 concat!(
1533 "Used for code extension purposes. It causes the meanings of the bit combinations following it in ",
1534 "the data stream to be changed."
1535 )
1536 ),
1537 Function::NUL => String::from(
1538 concat!(
1539 "Used for media-fill or time-fill. NUL characters may be inserted into, or removed from, a data ",
1540 "stream without affecting information content of that stream, but such action may affect the ",
1541 "information layout and/or the control of equipment."
1542 )
1543 ),
1544 Function::SYN => String::from(
1545 concat!(
1546 "Used by a synchronous transmission system in the absence of any other character (idle condition) ",
1547 "to provide a signal from which synchronism may be achieved or retained between data terminal ",
1548 "equipment."
1549 )
1550 ),
1551 Function::VT => String::from(
1552 concat!(
1553 "Causes the active presentation position to be moved in the presentation component to the ",
1554 "corresponding character position on th e line at which the following line tabulation stop is ",
1555 "set."
1556 )
1557 ),
1558 Function::APC => String::from(
1559 concat!(
1560 "Used as the opening delimiter of a control string for application program use. The command ",
1561 "string following may consist of bit combinations in the range 00/08 to 00/13 and 02/00 to 07/14. ",
1562 "The control string is closed by the terminating delimiter 'String Terminator' (ST). The ",
1563 "interpretation of the command string depends on the relevant application program."
1564 )
1565 ),
1566 Function::CCH => String::from(
1567 concat!(
1568 "Indicates that both the preceding graphic character in the data stream (represented by one or ",
1569 "more bit combinations), including 'Space', and the control function itself are to be ignored ",
1570 "for further interpretation in the data stream.",
1571 "\n",
1572 "\n",
1573 "If the character preceding CCH in the data stream is a control function (represented by one or ",
1574 "more bit combinations), the effect of CCH is not defined."
1575 )
1576 ),
1577 Function::DCS => String::from(
1578 concat!(
1579 "Used as the opening delimiter of a control string for device control use. The command string ",
1580 "following may consist of bit combinations in the range 00/08 to 00/13 and 02/00 to 07/14. The ",
1581 "control string is closed by the terminating delimiter 'String Terminator' (ST)."
1582 )
1583 ),
1584 Function::EPA => String::from(
1585 concat!(
1586 "Indicates that the active presentation position is the last of a string of character positions ",
1587 "in the presentation component, the contents of which are protected against manual alteration, ",
1588 "are guarded against transmission or transfer, depending on the settings of 'Guarded Area ",
1589 "Transfer Mode' (GATM), and may be protected against erasure, depending on the setting of ",
1590 "'Erasure Mode' (ERM). The beginning of this string is indicated by 'Start of Guarded Area' (SPA)."
1591 )
1592 ),
1593 Function::ESA => String::from(
1594 concat!(
1595 "Indicates that the active presentation position is the last of a string of character positions ",
1596 "in the presentation component, the contents of which are eligible to be transmitted in the form ",
1597 "of a data stream or transferred to an auxiliary input/output device. The beginning of the string ",
1598 "is indicated by 'Start of Selected Area' (SSA)"
1599 )
1600 ),
1601 Function::HTJ => String::from(
1602 concat!(
1603 "Causes the contents of the active field (the field in the presentation component that contains ",
1604 "active presentation position) to be shifted forwarded, so that it ends at the character position ",
1605 "preceding the following character tabulation stop. The active presentation position is moved to ",
1606 "that following character tabulation stop. The character position which precede the beginning of ",
1607 "the shifted string are put into the erased state."
1608 )
1609 ),
1610 Function::HTS => String::from(
1611 concat!(
1612 "Causes a character tabulation stop to be set at the active presentation position in the ",
1613 "presentation component. The number of lines affected depends on the setting of the ",
1614 "'Tabulation Stop Mode' (TSM)."
1615 )
1616 ),
1617 Function::MW => String::from(
1618 concat!(
1619 "Sets a message waiting indicated in the receiving device. An appropriate acknowledgement to the ",
1620 "receipt of MW may be given by using 'Device Status Report' (DSR)."
1621 )
1622 ),
1623 Function::NBH => String::from(
1624 concat!(
1625 "Indicates a point where a line break shall not occur when text is formatted. This may occur ",
1626 "between two graphic characters, either or both which may be 'Space'."
1627 )
1628 ),
1629 Function::NEL => String::from(
1630 concat!(
1631 "The effect of NEL depends on the setting of the 'Device Component Select Mode' (DCSM) and the ",
1632 "parameter value of 'Select Implicit Movement Direction' (SIMD).",
1633 "\n",
1634 "\n",
1635 "If DCSM is set to 'Presentation' and SIMD equal to 'Normal', it causes the active presentation ",
1636 "position to be moved to the line home position of the following line in the presentation ",
1637 "component. The line home position may be established by the parameter of 'Set Line Home' (SLH). ",
1638 "\n",
1639 "With SIMD equal to 'Opposite', it causes the active presentation position to be moved to the ",
1640 "line limit position of the following line in the presentation component. The line limit position ",
1641 "may be established by the parameter of 'Set Line Limit' (SLL).",
1642 "\n",
1643 "\n",
1644 "If DCSM is set to 'Data' and SIMD equal to 'Normal', it causes the active data ",
1645 "position to be moved to the line home position of the following line in the data ",
1646 "component. The line home position may be established by the parameter of 'Set Line Home' (SLH). ",
1647 "\n",
1648 "With SIMD equal to 'Opposite', it causes the active data position to be moved to the ",
1649 "line limit position of the following line in the data component. The line limit position ",
1650 "may be established by the parameter of 'Set Line Limit' (SLL)."
1651 )
1652 ),
1653 Function::OSC => String::from(
1654 concat!(
1655 "Opening delimiter of a control string for operating system use. The command string following may ",
1656 "consist of a sequence of bit combinations in the range 00/08 to 00/13 and 02/00 to 07/14. The ",
1657 "control string is closed by the terminating delimiter 'String Terminator' (ST). The ",
1658 "interpretation of the command string depends on the relevant operating system."
1659 )
1660 ),
1661 Function::PLD => String::from(
1662 concat!(
1663 "Move the active presentation position in the presentation component to the corresponding ",
1664 "position of an imaginary line with a partial offset in the direction of line progression. This ",
1665 "offset should be sufficient either to image following characters as subscripts until the first ",
1666 "following occurrence of 'Partial Line Backwards' (PLU) in the data stream, or, if preceding ",
1667 "characters were imaged as superscripts, to restore imaging of following characters to the active ",
1668 "line."
1669 )
1670 ),
1671 Function::PLU => String::from(
1672 concat!(
1673 "Move the active presentation position in the presentation component to the corresponding ",
1674 "position of an imaginary line with a partial offset in the direction opposite of line ",
1675 "progression. This offset should be sufficient either to image following characters as ",
1676 "superscripts until the first following occurrence of 'Partial Line Forward' (PLD) in the data ",
1677 "stream, or, if preceding characters were imaged as subscripts, to restore imaging of following ",
1678 "characters to the active line."
1679 )
1680 ),
1681 Function::PM => String::from(
1682 concat!(
1683 "Indicates the beginning of a control string privacy message use. The command string following ",
1684 "may consist of bit combination sin the range 00/08 to 00/13 and 02/00 to 07/14. The control ",
1685 "string is closed by the terminating delimiter 'String Terminator' (ST). The interpretation",
1686 "of the command string depends on the relevant privacy discipline."
1687 )
1688 ),
1689 Function::RI => String::from(
1690 concat!(
1691 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', it causes the active ",
1692 "presentation position to be moved in the presentation component to the corresponding character ",
1693 "position of the preceding line.",
1694 "\n",
1695 "\n",
1696 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', it causes the active ",
1697 "data position to be moved in the data component to the corresponding character ",
1698 "position of the preceding line."
1699 )
1700 ),
1701 Function::SCI => String::from(
1702 concat!(
1703 "This and the bit combination following it are used to represent a control function or a graphic ",
1704 "character. The bit combination following SCI must be from 00/08 to 00/13 or 02/00 to 07/14. The ",
1705 "use of SCI is reserved for future standardization."
1706 )
1707 ),
1708 Function::SOS => String::from(
1709 concat!(
1710 "Used as the opening delimiter of a control string. The character string following may consist of ",
1711 "any bit combinations, except those representing SOS or 'String Terminator' (ST). The control ",
1712 "string is closed by the terminating delimiter 'String Terminator' (ST). The interpretation of the ",
1713 "character string depends on the application."
1714 )
1715 ),
1716 Function::SPA => String::from(
1717 concat!(
1718 "Used to indicate that the active presentation position is the first of a string of character ",
1719 "positions in the presentation component, the contents of which are protected against manual ",
1720 "alteration, are guarded against transmission or transfer, depending on the setting of 'Guarded ",
1721 "Area Transfer Mode' (GATM), and may be protected against erasure, depending on the setting of ",
1722 "the 'Erasure Mode' (ERM). The end of this string is indicated by 'End of Guarded Area' (EPA)."
1723 )
1724 ),
1725 Function::SSA => String::from(
1726 concat!(
1727 "Indicates that the active presentation position is the first of a string of character positions ",
1728 "in the presentation component, the contents of which are eligible to be transmitted in the form ",
1729 "of a data stream or transferred to an ancillary input/output device. The end of this string is ",
1730 "indicated by 'End of Selected Area' (ESA). ",
1731 "\n",
1732 "\n",
1733 "The string of character actually transmitted or transferred depends on the setting of 'Guarded ",
1734 "Area Transfer mode' (GATM) and on any guarded areas established by 'Define Area Qualification' ",
1735 "(DAQ), or by 'Start of Guarded Area' (SPA) and 'End of Guarded Area' (EPA)."
1736 )
1737 ),
1738 Function::STS => String::from(
1739 concat!(
1740 "Used to establish the transmit state in the receiving device. In this state the transmission of ",
1741 "data from the device is possible. The actual initiation of transmission of data is performed by ",
1742 "a data communication or input/output interface control procedure, which is outside of the scope ",
1743 "of this Standard.",
1744 "\n",
1745 "\n",
1746 "The transmit state is established either by this appearing in the received data stream, or by ",
1747 "the operation of an appropriate key on a keyboard."
1748 )
1749 ),
1750 Function::CMD => String::from(
1751 concat!(
1752 "Delimits a string of data coded according to standard ECMA-35, and to switch to a general level ",
1753 "of control. The use of this is not mandatory if the higher level protocol defines means of ",
1754 "delimiting the string, for instance by specifying the length of the string."
1755 )
1756 ),
1757 Function::RIS => String::from(
1758 concat!(
1759 "Reset the receiving device to its initial state, i.e. the state it has after it is made ",
1760 "operational. This may imply, if applicable: clear tabulation stops, remove qualified areas, ",
1761 "reset graphic rendition, put all character positions into the erased state, move the active ",
1762 "presentation position to the first position of the first line in the presentation component, ",
1763 "move the active data position to the first character position in the first line in the data ",
1764 "component, set the modes into the reset state, etc.."
1765 )
1766 ),
1767 Function::CBT => format!(
1768 concat!(
1769 "Causes the active presentation position to be moved to the character position corresponding ",
1770 "to the {} preceding character tabulation stop in the presentation component, according to ",
1771 "the character path.",
1772
1773 ),
1774 param!(self, ordinal 0, 1)
1775 ),
1776 Function::CHA => format!(
1777 concat!(
1778 "Causes the active presentation position to be moved to character position {} in the active line ",
1779 "in the presentation component"
1780 ),
1781 param!(self, 0, 1)
1782 ),
1783 Function::CHT => format!(
1784 concat!(
1785 "Causes the active presentation position to be moved to the character position corresponding to ",
1786 "the {} following character tabulation stop in the presentation component, according to the ",
1787 "character path."
1788 ),
1789 param!(self, ordinal 0, 1)
1790 ),
1791 Function::CNL => format!(
1792 concat!(
1793 "Causes the active presentation position to be moved to the first character position of the {} ",
1794 "following line in the presentation component."
1795 ),
1796 param!(self, ordinal 0, 1)
1797 ),
1798 Function::CPL => format!(
1799 concat!(
1800 "Causes the active presentation position to be moved to the first character position of the {} ",
1801 "preceding line in the presentation component."
1802 ),
1803 param!(self, ordinal 0, 1)
1804 ),
1805 Function::CPR => format!(
1806 concat!(
1807 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', reports the active ",
1808 "presentation position of the sending device as residing in the presentation component at the {} ",
1809 "line position according to the line progress and at the {} character position according to the ",
1810 "character path.",
1811 "\n\n",
1812 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', reports the active data position ",
1813 "of the sending device as residing in the data component at the {} line position according to the ",
1814 "line progression and at the {} character position according to the character progression.",
1815 "\n\n",
1816 "CPR may be solicited by a 'Device Status Report' (DSR) or be sent unsolicited."
1817 ),
1818 param!(self, ordinal 0, 1),
1819 param!(self, ordinal 1, 1),
1820 param!(self, ordinal 0, 1),
1821 param!(self, ordinal 1, 1),
1822 ),
1823 Function::CUB => format!(
1824 concat!(
1825 "Causes the active presentation position to be moved leftwards in the presentation component by ",
1826 "{} character positions, if the character path is horizontal, or by {} line positions, if the ",
1827 "character path is vertical."
1828 ),
1829 param!(self, 0, 1),
1830 param!(self, 0, 1)
1831 ),
1832 Function::CUD => format!(
1833 concat!(
1834 "Causes the active presentation position to be moved downwards in the presentation component by ",
1835 "{} line positions, if the character path is horizontal, or by {} character positions, if the ",
1836 "character path is vertical."
1837 ),
1838 param!(self, 0, 1),
1839 param!(self, 0, 1)
1840 ),
1841 Function::CUF => format!(
1842 concat!(
1843 "Causes the active presentation position to be moved rightwards in the presentation component by ",
1844 "{} character positions, if the character path is horizontal, or by {} line positions, if the ",
1845 "character path is vertical."
1846 ),
1847 param!(self, 0, 1),
1848 param!(self, 0, 1)
1849 ),
1850 Function::CUP => format!(
1851 concat!(
1852 "Causes the active presentation position to be moved in the presentation component to the {} line ",
1853 "position according to the line progression, and to the {} character position according to the ",
1854 "character path.",
1855 ),
1856 param!(self, ordinal 0, 1),
1857 param!(self, ordinal 1, 1)
1858 ),
1859 Function::CUU => format!(
1860 concat!(
1861 "Causes the active presentation position to be moved upwards in the presentation component by {} ",
1862 "line positions, if the character path is horizontal, or by {} character positions, if the ",
1863 "character path is vertical."
1864 ),
1865 param!(self, 0, 1),
1866 param!(self, 0, 1)
1867 ),
1868 Function::CVT => format!(
1869 concat!(
1870 "Causes the active presentation position to be moved to the character position of the line ",
1871 "corresponding to the {} following line tabulation stop in the presentation component."
1872 ),
1873 param!(self, ordinal 0, 1)
1874 ),
1875 Function::DAQ => format!(
1876 concat!(
1877 "This is used to indicate that the active presentation position in the presentation component is ",
1878 "the first character position of a qualified area. The last character position of the qualified ",
1879 "area is the character position in the presentation component immediately preceding the first ",
1880 "character position of the following qualified area. This area {}."
1881 ),
1882 explain_selection!(AreaQualification, self, 0)
1883 ),
1884 Function::DCH => format!(
1885 concat!(
1886 "If the 'Device Component Select Mode' (DSCM) is set to 'Presentation', it causes the contents ",
1887 "of the active presentation position and, depending on the setting of 'Character Editing Mode' ",
1888 "(HEM), the contents of the preceding or following character positions to be removed from the ",
1889 "presentation component. The resulting gap of {} characters is closed by shifting the contents of ",
1890 "the adjacent character positions towards the active presentation position. At the other end of ",
1891 "the shifter part {} character positions are put into the erased state.",
1892 "\n\n",
1893 "The extend of the shifted part is established by 'Select Editing Extend' (SEE).",
1894 "\n\n",
1895 "The effect of this on the start or end of a selected area, the start or end of a qualified area, ",
1896 "or a tabulation stop in the shifted part is undefined.",
1897 "\n\n",
1898 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', it causes the contents of the ",
1899 "active data position and, depending on the setting of 'Character Editing Mode' (HEM), the ",
1900 "contents of the preceding or following character positions to be removed from the data ",
1901 "component. The resulting gap of {} characters is closed by shifting the contents of the adjacent ",
1902 "character positions towards the active data position. At the other end of the shifted part, {} ",
1903 "character positions are put into the erased state."
1904 ),
1905 param!(self, 0, 1),
1906 param!(self, 0, 1),
1907 param!(self, 0, 1),
1908 param!(self, 0, 1)
1909 ),
1910 Function::DL => format!(
1911 concat!(
1912 "If the 'Device Component Select Mode' (DSCM) is set to 'Presentation', it causes the contents of ",
1913 "the active line (the line that contains the active presentation position) and, depending on the ",
1914 "setting of the 'Line Editing Mode' (VEM), the contents of the preceding or following lines to be ",
1915 "removed from the presentation component. The resulting gap of {} lines is closed by shifting the ",
1916 "contents of a number of adjacent lines towards the active line. At the end of the shifted part, ",
1917 "{} lines are put into the erased state. The active presentation position is moved to the line ",
1918 "home position in the active line. The line home position is established by the parameter value ",
1919 "of 'Set Line Home' (SLH). If the 'Tabulation Stop Mode' (TSM) is set to 'Single', character ",
1920 "tabulation stops are cleared in the lines that are put into the erased state.",
1921 "\n\n",
1922 "The extend of the shifted part is established by 'Select Editing Extend' (SEE).",
1923 "\n\n",
1924 "Any occurrences of the start or end of a selected area, the start or end of a qualified area, or ",
1925 "a tabulation stop in the shifted part, are also shifted.",
1926 "\n\n",
1927 "If the 'Device Component Select Mode (DCSM) is set to 'Data', it causes the contents of the ",
1928 "active line (the line that contains the active data position) and, depending on the settings of ",
1929 "the 'Line Editing Mode' (VEM), the contents of the preceding or following lines to be removed ",
1930 "from the data component. The resulting gap of {} lines is closed by shifting the contents of a ",
1931 "number of adjacent lines towards the active line. At the other end of the shifted part, {} lines ",
1932 "are put into the erased state. The active data position is moved to the line home position in ",
1933 "the active line. The line home position is established by the parameter value of 'Set Line Home' ",
1934 "(SLH)."
1935 ),
1936 param!(self, 0, 1),
1937 param!(self, 0, 1),
1938 param!(self, 0, 1),
1939 param!(self, 0, 1)
1940 ),
1941 Function::DTA => format!(
1942 concat!(
1943 "Establishes the dimension of the text area for subsequent pages. The established dimensions ",
1944 "remain in effect until the next occurrence of DTA in the data stream. The new dimension is ",
1945 "specified to be {} in the direction perpendicular to the line orientation and {} parallel to the ",
1946 "line orientation. The unit in which the value is expressed is that established by the parameter ",
1947 "value of 'Select Size Unit' (SSU)."
1948 ),
1949 param!(self, 0, 0),
1950 param!(self, 1, 0)
1951 ),
1952 Function::EA => format!(
1953 concat!(
1954 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', {} in the presentation ",
1955 "component. The contents of the removed area are put into the erased state.",
1956 "\n\n",
1957 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', {} in the data component. The ",
1958 "contents of the removed area are put into the erased state.",
1959 "\n\n",
1960 "Whether the character positions of protected areas are put into the erased state, or the ",
1961 "character positions of unprotected areas only, depends on the settings of 'Erasure Mode' (ERM)."
1962 ),
1963 explain_selection!(EraseArea, self, 0),
1964 explain_selection!(EraseArea, self, 0)
1965 ),
1966 Function::ECH => format!(
1967 concat!(
1968 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', it causes the active ",
1969 "presentation position and the following character positions in the presentation component to be ",
1970 "put into the erased state. {} characters will be erased.",
1971 "\n\n",
1972 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', it causes the active data position ",
1973 "and the following character positions in the data component to be put into the erased state. {} ",
1974 "characters will be erased.",
1975 "\n\n",
1976 "Whether the character positions of protected areas are put into the erased state, or the ",
1977 "character positions of unprotected areas only, depends on the settings of 'Erasure Mode' (ERM)."
1978 ),
1979 param!(self, 0, 1),
1980 param!(self, 0, 1)
1981 ),
1982 Function::ED => format!(
1983 concat!(
1984 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', {} in the presentation ",
1985 "component. The contents of the removed page are put into the erased state.",
1986 "\n\n",
1987 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', {} in the data component. The ",
1988 "contents of the removed page are put into the erased state.",
1989 "\n\n",
1990 "Whether the character positions of protected areas are put into the erased state, or the ",
1991 "character positions of unprotected areas only, depends on the settings of 'Erasure Mode' (ERM)."
1992 ),
1993 explain_selection!(EraseArea, self, 0),
1994 explain_selection!(EraseArea, self, 0)
1995 ),
1996 Function::EF => format!(
1997 concat!(
1998 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', {} in the presentation ",
1999 "component. The contents of the removed field are put into the erased state.",
2000 "\n\n",
2001 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', {} in the data component. The ",
2002 "contents of the removed field are put into the erased state.",
2003 "\n\n",
2004 "Whether the character positions of protected areas are put into the erased state, or the ",
2005 "character positions of unprotected areas only, depends on the settings of 'Erasure Mode' (ERM)."
2006 ),
2007 explain_selection!(EraseArea, self, 0),
2008 explain_selection!(EraseArea, self, 0)
2009 ),
2010 Function::EL => format!(
2011 concat!(
2012 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', {} in the presentation ",
2013 "component. The contents of the removed line are put into the erased state.",
2014 "\n\n",
2015 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', {} in the data component. The ",
2016 "contents of the removed line are put into the erased state.",
2017 "\n\n",
2018 "Whether the character positions of protected areas are put into the erased state, or the ",
2019 "character positions of unprotected areas only, depends on the settings of 'Erasure Mode' (ERM)."
2020 ),
2021 explain_selection!(EraseArea, self, 0),
2022 explain_selection!(EraseArea, self, 0)
2023 ),
2024 Function::FNT => format!(
2025 concat!(
2026 "{}\n\n",
2027 "The active Font might be switched in the following data stream by 'Select Graphic Rendition (SGR)."
2028 ),
2029 self.short_description()
2030 ),
2031 Function::GSM => format!(
2032 concat!(
2033 "Used to modify the text height and / or width of the subsequent text for all primary and ",
2034 "alternatives fonts and established 'Graphic Size Select' (GSS). The established values remain in ",
2035 "effect until the next occurrence of GSM or GSS in the data stream. The new size is set to to {}% ",
2036 "height and {}% width."
2037 ),
2038 param!(self, 0, 100),
2039 param!(self, 1, 100)
2040 ),
2041 Function::GSS => format!(
2042 concat!(
2043 "Used to establish the height for the subsequent text for all primary and alternative fonts. The ",
2044 "established value remains in effect until the next occurrence of GSS in the data stream. The new ",
2045 "height is set to {} with a unit established by 'Select Size Unit' (SSU)."
2046 ),
2047 param!(self, 0, 0)
2048 ),
2049 Function::HPA => format!(
2050 concat!(
2051 "Causes the active data position to be moved to the character position {} in the active line (the ",
2052 "line in the data component that contains the active data position)"
2053 ),
2054 param!(self, 0, 1)
2055 ),
2056 Function::HPB => format!(
2057 concat!(
2058 "Causes the active data position to be moved by {} character positions in the data component in ",
2059 "the direction opposite to that of the character progression."
2060 ),
2061 param!(self, 0, 1)
2062 ),
2063 Function::HPR => format!(
2064 concat!(
2065 "Causes the active data position to be moved by {} character positions in the data component in ",
2066 "the direction of character progression."
2067 ),
2068 param!(self, 0, 1)
2069 ),
2070 Function::HVP => format!(
2071 concat!(
2072 "Causes the active data position to be moved in the data component to the {} line position ",
2073 "according to the line progression and to the {} character position according to the character ",
2074 "position."
2075 ),
2076 param!(self, ordinal 0, 1),
2077 param!(self, ordinal 1, 1)
2078 ),
2079 Function::ICH => format!(
2080 concat!(
2081 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', this is used to prepare ",
2082 "the insertion of {} characters, by putting into the erased state the active presentation ",
2083 "position and, depending on the setting of the Character Editing Mode (HEM), the preceding or ",
2084 "following character positions in the presentation component. The previous contents of the active ",
2085 "presentation position and an adjacent string of character positions are shifted away from the ",
2086 "active presentation position. The contents of {} character positions at the other end of the ",
2087 "shifted part are removed. The active presentation position is moved to the line home position in ",
2088 "the active line. The line home position is established by the parameter value of 'Set Line Home' ",
2089 "(SLH).",
2090 "\n\n",
2091 "The extent of the shifted part is established by Select Editing Extend (SEE).",
2092 "\n\n",
2093 "The effect of this on the start or end of a selected area, the start or end of a qualified area, ",
2094 "or a tabulation stop in the shifted part is undefined.",
2095 "\n\n",
2096 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', this is used to prepare the ",
2097 "insertion of {} characters, by putting into the erased state the active data position and, ",
2098 "depending on the setting of the Character Editing Mode (HEM), the preceding or following ",
2099 "character positions in the data component. The previous contents of the active data position and ",
2100 "and adjacent string of character positions are shifted away from the active data position. ",
2101 "The contents of {} character positions at the other end of the shifted part are removed. The ",
2102 "active data position is moved to the line home position in the active line. The line ",
2103 "home position is established by the parameter value of Set Line Home (SLH)."
2104 ),
2105 param!(self, ordinal 0, 1),
2106 param!(self, ordinal 0, 1),
2107 param!(self, ordinal 0, 1),
2108 param!(self, ordinal 0, 1)
2109 ),
2110 Function::IGS => format!(
2111 concat!(
2112 "Indicates that the graphic subrepertoire {} is used in the subsequent text according to the ",
2113 "graphic characters of ISO/IEC 10367. The graphic subrepertoire {} is registered in accordance ",
2114 "with ISO/IEC 7350"
2115 ),
2116 param!(self, 0, 0),
2117 param!(self, 0, 0)
2118 ),
2119 Function::IL => format!(
2120 concat!(
2121 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', this is used to prepare ",
2122 "the insertion of {} lines, by putting into the erased state in the presentation component the ",
2123 "active line (the line that contains the active presentation position) and, depending on the ",
2124 "setting of the 'Line Editing Mode' (VEM), the preceding or following lines. The previous contents ",
2125 "of the active line and of adjacent lines are shifted away from the active line. The contents of ",
2126 "{} lines at the other end of the shifted part are removed. The active presentation position is ",
2127 "moved to the line home position in the active line. The line home position is established by the ",
2128 "parameter value of 'Set Line Home' (SLH).",
2129 "\n\n",
2130 "The extent of the shifted part is established by 'Select Editing Extent' (SEE).",
2131 "\n\n",
2132 "Any occurrence of the start or end of a selected area, the start or end of a qualified area, or ",
2133 "a tabulation stop in the shifted part, are also shifted.",
2134 "\n\n",
2135 "If the 'Tabulation Stop Mode' (TSM) is set to 'Single', character tabulation stops are cleared ",
2136 "in the lines that are put into the erased state.",
2137 "\n\n",
2138 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', this is used to prepare the ",
2139 "insertion of {} lines, by putting into the erased state in the data component the active line ",
2140 "(the line that contains the active data position) and, depending on the setting of the 'Line ",
2141 "Editing Mode' (VEM), the preceding or following lines. The previous contents of the active line ",
2142 "and of adjacent lines are shifted away from the active line. The contents of {} lines at the ",
2143 "other end of the shifted part are removed. The active data position is moved to the line home ",
2144 "position in the active line. The line home position is established by the parameter value of ",
2145 "'Set Line Home' (SLH)."
2146 ),
2147 param!(self, 0, 1),
2148 param!(self, 0, 1),
2149 param!(self, 0, 1),
2150 param!(self, 0, 1)
2151 ),
2152 Function::JFY => format!(
2153 concat!(
2154 "Indicates the beginning of a string of graphic characters in the presentation component that are ",
2155 "to be justified according to the layout specified: {}"
2156 ),
2157 self.short_description()
2158 ),
2159 Function::PEC => format!(
2160 concat!(
2161 "Establish the spacing and the extent of graphic characters for subsequent text. {}",
2162 "\n\n",
2163 "The spacing is specified in the line as multiples of the spacing established by the most recent ",
2164 "occurrence of 'Set Character Spacing' (SCS), of 'Select Character Spacing' (SHS), or of 'Spacing ",
2165 "Increment' (SPI) in the data stream. The extent of characters is implicitly established by these ",
2166 "control functions. The established spacing and extent remain in effect until the next occurrence ",
2167 "of PEC. "
2168 ),
2169 self.short_description()
2170 ),
2171 Function::PFS => format!(
2172 concat!(
2173 "Establish the available area for the imaging of pages of text based on paper size. {}",
2174 "\n\n",
2175 "The pages are introduced by the subsequent occurrences of 'Form Feed' (FF) in the data stream. ",
2176 "The established area stays into effect until the next occurrence.",
2177 "\n\n",
2178 "The page home position is established by 'Set Page Home' (SPH), the page limit position is ",
2179 "established by 'Set Page Limit' (SPL)."
2180 ),
2181 self.short_description()
2182 ),
2183 Function::PTX => format!(
2184 concat!(
2185 "Used to delimit strings of graphic characters that are communicated one after another in the ",
2186 "data stream, but that are intended to be presented in parallel with another one, usually in ",
2187 "adjacent lines.",
2188 "\n\n",
2189 "{}"
2190 ),
2191 self.short_description()
2192 ),
2193 Function::QUAD => format!(
2194 concat!(
2195 "Indicates the end of a string of graphic characters that are to be positioned on a single line ",
2196 "{}.\n\n",
2197 "The beginning of the string to be positioned is indicated by the preceding occurrence in the data ",
2198 "stream of either another QUAD, or one of the following formator functions: FF, LF, NEL, RI, VT, ",
2199 "HVP, HPA, PPB, PPR, VPA, VPB.",
2200 "\n\n",
2201 "The line home position is established by the parameter value of 'Set Line Home' (SLH). The line ",
2202 "limit position is established by the parameter value of 'Set Line Home' (SLH)."
2203 ),
2204 self.short_description()
2205 ),
2206 Function::REP => format!(
2207 concat!(
2208 "Used to indicate that the preceding character in the data stream, if it is a graphic character, ",
2209 "including 'Space', is to be repeated {} times. If the preceding character is a control function ",
2210 "or part of a control function, the effect is undefined."
2211 ),
2212 param!(self, 0, 1)
2213 ),
2214 Function::RM =>
2215 self.parameters.iter().map(|value| {
2216 value.parse::<Mode>().expect("Expect only valid Modes").explain_reset()
2217 }).fold(String::new(), |mut modes, mode| {
2218 modes.push_str(", ");
2219 modes.push_str(&mode);
2220 modes
2221 }
2222 ),
2223 Function::SACS => format!(
2224 concat!(
2225 "Used to establish extra inter-character escapement for subsequent text. The established extra ",
2226 "escapement remains in effect until the next occurrence of SACS or of 'Set Reduced Character ",
2227 "Separation' (SRCS) in the data stream or until it is reset to the default value by a subsequent ",
2228 "occurrence of 'Carriage Return Line Feed' (CR LF) or of 'Next Line' (NEL) in the data stream.",
2229 "\n\n",
2230 "The inter-character escapement is enlarged by {} units",
2231 "\n\n",
2232 "the unit in which the parameter value is expressed is that established by the parameter value of ",
2233 "'Select Size Unit' (SSU)."
2234 ),
2235 param!(self, 0, 0)
2236 ),
2237 Function::SCS => format!(
2238 concat!(
2239 "Establishes the character spacing for subsequent text. The established spacing remains in effect ",
2240 "until the next occurrence, or of 'Select Character Spacing' (SHS) or of 'Spacing Increment' ",
2241 "(SPI) in the data stream.\n\nCharacters are spaced by {} units.",
2242 "\n\n",
2243 "The units in which the value is expressed is that established by the parameter value of 'Select ",
2244 "Size Unit' (SSU)."
2245 ),
2246 param!(self, 0, 0)
2247 ),
2248 Function::SD => format!(
2249 concat!(
2250 "Causes the data in the presentation component to be moved by {} line positions if the line ",
2251 "orientation is horizontal, or by {} character positions if the line orientation is vertical, ",
2252 "such that the data appear to move down.",
2253 "\n\n",
2254 "The active presentation position is not affected by this function."
2255 ),
2256 param!(self, 0, 1),
2257 param!(self, 0, 1)
2258 ),
2259 Function::SDS => format!(
2260 concat!(
2261 "Establishes in the data component the beginning and end of a string of characters, as well as ",
2262 "the direction of the string. This direction may be different from that currently established. ",
2263 "The indicated string follows the preceding text. The established character progression is not ",
2264 "affected. {}"
2265 ),
2266 self.short_description()
2267 ),
2268 Function::SEE => format!(
2269 concat!(
2270 "Used to establish the editing extend for subsequent character or line insertion or deletion. The ",
2271 "established context remains in effect until the next occurrence of SEE in the data stream. {}"
2272 ),
2273 self.short_description()
2274 ),
2275 Function::SEF => format!(
2276 concat!(
2277 "Causes a sheet of paper to be ejected from a printing device into a specified output stacker an ",
2278 "another sheet to be loaded into the printing device from a specified paper bin. {} {}"
2279 ),
2280 explain_selection!(Load, self, 0),
2281 explain_selection!(Stack, self, 1)
2282 ),
2283 Function::SGR => format!(
2284 concat!(
2285 "Establishes one or more graphic rendition aspects for subsequent text. The established aspects ",
2286 "remain in effect until the next occurrence, depending on the setting of the 'Graphic Rendition ",
2287 "Combination Mode' (GRCM).\n\n{}"
2288 ),
2289 self.parameters.iter().map(|value| {
2290 value.parse::<GraphicRendition>().expect("Expect only valid Graphic Renditions").explain()
2291 }).fold(String::new(), |mut renditions, rendition| {
2292 renditions.push_str(", ");
2293 renditions.push_str(&rendition);
2294 renditions
2295 })
2296 ),
2297 Function::SHS => format!(
2298 concat!(
2299 "Used to establish the character spacing for subsequent text. {} The established spacing remains ",
2300 "in effect until the next occurrence of SHS or of 'Set Character Spacing' (SHS) or of 'Spacing ",
2301 "Increment' (SPI)."
2302 ),
2303 self.short_description()
2304 ),
2305 Function::SIMD => format!(
2306 concat!(
2307 "Used to select the direction of implicit movement of the data position relative to the character ",
2308 "position. Remains in effect until the next occurrence of SIMD. {}"
2309 ),
2310 self.short_description()
2311 ),
2312 Function::SL => format!(
2313 concat!(
2314 "Causes the data in the presentation component to be moved by {} character positions if the line ",
2315 "orientation is horizontal, or by {} line positions if the line orientation is vertical, such ",
2316 "that the data appear to move to the left. The active presentation position is not affected by ",
2317 "this control function."
2318 ),
2319 param!(self, 0, 1),
2320 param!(self, 0, 1)
2321 ),
2322 Function::SLH => format!(
2323 concat!(
2324 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', this is used to establish ",
2325 "at character position {} in the active line (the line that contains the active presentation ",
2326 "position) and lines of subsequent text in the presentation component, the position to which the ",
2327 "active presentation position will be moved by subsequent occurrences of 'Carriage Return' (CR), ",
2328 "'Delete Line' (DL), 'Insert Line' (IL) or 'Next Line' (NEL) in the data stream. In the case of a ",
2329 "device without a data component, it is also the position ahead of which no implicit movement of ",
2330 "the active presentation position shall occur.",
2331 "\n\n",
2332 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', this is used to establish at ",
2333 "character position {} in the active line (the line that contains the active data position) and ",
2334 "lines of subsequent text in the data component, the position to which the active data position ",
2335 "will be moved by subsequent occurrences of 'Carriage Return' (CR), 'Delete Line' (DL), 'Insert ",
2336 "Line' (IL), or 'Next Line' (NEL) in the data stream. It is also the position ahead of which no ",
2337 "implicit movement of the active data position shall occur.",
2338 "\n\n",
2339 "The established position is called the line home position and remains in effect until the next ",
2340 "occurrence of SLH in the data stream."
2341 ),
2342 param!(self, 0, 0),
2343 param!(self, 0, 0)
2344 ),
2345 Function::SLL => format!(
2346 concat!(
2347 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', this is used to establish ",
2348 "at character position {} in the active line (the line that contains the active presentation ",
2349 "position) and lines of subsequent text in the presentation component, the position to which the ",
2350 "active presentation position will be moved by subsequent occurrences of 'Carriage Return' (CR) ",
2351 "or 'Next Line' (NEL) in the data stream, if the parameter value of 'Select Implicit Movement ",
2352 "Direction' (SIMD) is equal to 'Opposite'. In the case of a device without data component, it is ",
2353 "also the position beyond which no implicit movement of the active presentation position shall ",
2354 "occur.",
2355 "\n\n",
2356 "If the 'Device Component Select Mode' (DSCM) is set to 'Data', this is used to establish at ",
2357 "character position {} in the active line (the line that contains the active data position) and ",
2358 "lines of subsequent text in the data component, the position beyond which no implicit movement ",
2359 "of the active data position shall occur. It is also the position in the data component to which ",
2360 "the active data position will be moved by subsequent occurrences of 'Carriage Return' (CR) or ",
2361 "'Next Line' (NEL) in the data stream, if the parameter value of 'Select Implicit Movement ",
2362 "Direction' (SIMD) is equal to 'Opposite'.",
2363 "\n\n",
2364 "The established position is called the line limit position and remains in effect until the next ",
2365 "occurrence of SLL in the data stream."
2366 ),
2367 param!(self, 0, 0),
2368 param!(self, 0, 0)
2369 ),
2370 Function::SLS => format!(
2371 concat!(
2372 "Establishes the line spacing for subsequent text. The established spacing remains in effect ",
2373 "until the next occurrence of SLS or of 'Select Line Spacing' (SVS) in the data stream. {}"
2374 ),
2375 self.short_description()
2376 ),
2377 Function::SM =>
2378 self.parameters.iter().map(|value| {
2379 value.parse::<Mode>().expect("Expect only valid Modes").explain_set()
2380 }).fold(String::new(), |mut modes, mode| {
2381 modes.push_str(", ");
2382 modes.push_str(&mode);
2383 modes
2384 }
2385 ),
2386 Function::SPH => format!(
2387 concat!(
2388 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', this is used to establish ",
2389 "at line position {} in the active page (the page that contains the active presentation position) ",
2390 "and subsequent pages in the presentation component, the position to which the active ",
2391 "presentation position will be moved by subsequent occurrences of 'Form Feed' (FF) in the data ",
2392 "stream. In the case of a device without data component, it is also the position ahead of which ",
2393 "no implicit movement of the active presentation position shall occur.",
2394 "\n\n",
2395 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', this is used to establish at line ",
2396 "position {} in the active page (the page that contains the active data position) and subsequent ",
2397 "pages in the data component, the position to which the active data position will be moved by ",
2398 "subsequent occurrences of 'Form Feed' (FF) in the data stream. It is also the position ahead of ",
2399 "which no implicit movement of the active presentation position shall occur.",
2400 "\n\n",
2401 "The established position is called the page home position and remains in effect until the next ",
2402 "occurrence of SPH in the data stream."
2403 ),
2404 param!(self, 0, 0),
2405 param!(self, 0, 0)
2406 ),
2407 Function::SPI => format!(
2408 concat!(
2409 "Used to establish the line spacing and the character spacing for subsequent text. The ",
2410 "established line spacing remains in effect until the next occurrence of SPI or 'Set Line ",
2411 "Spacing' (SLS) or of 'Select Line Spacing' (SVS) in the data stream. The established character ",
2412 "spacing remains in effect until the next occurrence of 'Set Character Spacing' (SCS) or of ",
2413 "'Select Character Spacing' (SHS) in the data stream.",
2414 "\n\n",
2415 "Line spacing is set to {}, character spacing is set to {}, expressed in the unit that is ",
2416 "established by 'Select Size Unit' (SSU)."
2417
2418 ),
2419 param!(self, 0, 0),
2420 param!(self, 1, 0)
2421 ),
2422 Function::SPL => format!(
2423 concat!(
2424 "If the 'Device Component Select Mode' (DCSM) is set to 'Presentation', this is used to establish ",
2425 "at line position {} in the active page (the page that contains the active presentation position) ",
2426 "and pages of subsequent text in the presentation component, the position beyond which the active ",
2427 "presentation position can normally not be moved. In the case of a device without data component, ",
2428 "it is also the position beyond which no implicit movement of the active presentation position ",
2429 "shall occur.",
2430 "\n\n",
2431 "If the 'Device Component Select Mode' (DCSM) is set to 'Data', this is used to establish at line ",
2432 "position {} in the active page (the page that contains the active data position) and pages of ",
2433 "subsequent text in the data component, the position beyond which no implicit movement of the ",
2434 "active data position shall occur.",
2435 "\n\n",
2436 "The established position is called the page limit position and remains in effect until the next ",
2437 "occurrence of SPL in the data stream."
2438 ),
2439 param!(self, 0, 0),
2440 param!(self, 0, 0)
2441 ),
2442 Function::SPQR => format!(
2443 concat!(
2444 "Select the relative print quality and print speed for devices where the output quality and ",
2445 "speed are inversely related. The selected value will remain in effect until the next ",
2446 "occurrence of SPQR. {}"
2447 ),
2448 self.short_description()
2449 ),
2450 Function::SR => format!(
2451 concat!(
2452 "Causes the data in the presentation component to be moved by {} character positions if the ",
2453 "line orientation is horizontal, or by {} line positions if the line orientation is ",
2454 "vertical, such that the data appear to be moved to the right.",
2455 "\n\n",
2456 "The active presentation position is not affected by this control function."
2457 ),
2458 param!(self, 0, 1),
2459 param!(self, 0, 1)
2460 ),
2461 Function::SRCS => format!(
2462 concat!(
2463 "Used to establish reduced inter-character escapement by {} units. The established reduced ",
2464 "escapement remains in effect until the next occurrence of SRCS or of 'Set Additional ",
2465 "Character Separation' (SACS) in the data stream or until it is reset to the default value ",
2466 "by a subsequent occurrence of 'Carriage Return/Line Feed' (CRLF) or of 'Next Line' (NEL) in ",
2467 "the data stream.",
2468 "\n\n",
2469 "The unit in which the escapement is reduced is that established by 'Select Size Unit' (SSU)."
2470 ),
2471 param!(self, 0, 0)
2472 ),
2473 Function::SRS => format!(
2474 concat!(
2475 "Used to establish in the data component the beginning and the end of a string of ",
2476 "characters as well as the direction of this string. This direction is opposite to that ",
2477 "currently established. The indicated string follows the preceding text. The established ",
2478 "character progression is not affected. {}"
2479 ),
2480 self.short_description()
2481 ),
2482 Function::SSU => format!(
2483 concat!(
2484 "Used to establish the unit in which the numeric parameters of certain control functions ",
2485 "are expressed. The establish unit remains in effect until the next occurrence of SSU in ",
2486 "the data stream. {}"
2487 ),
2488 self.short_description()
2489 ),
2490 Function::SSW => format!(
2491 concat!(
2492 "Used to establish for subsequent text the character escapement associated with the ",
2493 "character 'SPACE'. The established escapement remains in effect until the next occurrence ",
2494 "of SSW in the data stream or until it is reset to the default value by a subsequent ",
2495 "occurrence of 'Carriage Return/Line Feed' (CRLF), 'Carriage Return/Form Feed' (CRFF), or ",
2496 "'Next Line' (NEL) in the data stream.",
2497 "\n\n",
2498 "{}",
2499 "\n\n",
2500 "The unit in which the value is expressed is defined by 'Select Size Unit' (SSU).",
2501 "\n\n",
2502 "The default character escapement of 'SPACE' is specified by the most recent occurrence of ",
2503 "'Set Character Spacing' (SCS) or of 'Select Character Spacing' (SHS) or of 'Select Spacing ",
2504 "Increment' (SPI) in the data stream if the current font has constant spacing, or is ",
2505 "specified by the normal width of the character 'SPACE' in the current font if that font ",
2506 "has proportional spacing."
2507 ),
2508 self.short_description()
2509 ),
2510 Function::STAB => format!(
2511 concat!(
2512 "{} The use of this control function and means of specifying a list of tabulation stop to ",
2513 "be referenced by the control function are specified in other standards, for example ISO ",
2514 "8613-6."
2515 ),
2516 self.short_description()
2517 ),
2518 Function::SU => format!(
2519 concat!(
2520 "Causes the data in the presentation component to be moved by {} line positions, if the line ",
2521 "operation is horizontal, or by {} character positions, if the line orientation is vertical, ",
2522 "such that the data appear to move up. The active presentation position is not affected by ",
2523 "this control function."
2524 ),
2525 param!(self, 0, 1),
2526 param!(self, 0, 1)
2527 ),
2528 Function::SVS => format!(
2529 concat!(
2530 "Used to establish the line spacing for subsequent text. {} The established spacing remains ",
2531 "in effect until the next occurrence of SVS or of 'Set Line Spacing' (SLS) or of 'Spacing ",
2532 "Increment' (SPI) in the data stream."
2533 ),
2534 explain_selection!(LineSpacing, self, 0)
2535 ),
2536 Function::TAC => format!(
2537 concat!(
2538 "Causes a character tabulation stop calling for centring to be set at character position {} ",
2539 "in the active line (the line that contains the active presentation position) and lines of ",
2540 "subsequent text in the presentation component. TAC causes the replacement of any ",
2541 "tabulation stop previously set at that character position, but does not affect other ",
2542 "tabulation stops.",
2543 "\n\n",
2544 "A text string centred upon a tabulation stop set by TAC will be positioned so that the ",
2545 "(trailing edge of the) first graphic character and the (leading edge of the) last graphic ",
2546 "character are at approximately equal distances from the tabulation stop."
2547 ),
2548 param!(self, 0, 0)
2549 ),
2550 Function::TALE => format!(
2551 concat!(
2552 "Causes a character tabulation stop calling for leading edge alignment to be set at ",
2553 "character position {} in the active line (the line that contains the active presentation ",
2554 "position) and lines of subsequent text in the presentation component. TALE causes the ",
2555 "replacement of any tabulation stop previously set at that character position, but does not ",
2556 "affect other tabulation stops.",
2557 "\n\n",
2558 "A text string aligned with a tabulation stop set by TALE will be positioned so that the ",
2559 "(leading edge of the) last graphic character of the string is placed at the tabulation stop."
2560 ),
2561 param!(self, 0, 0)
2562 ),
2563 Function::TATE => format!(
2564 concat!(
2565 "Causes a character tabulation stop calling for trailing edge alignment to be set at ",
2566 "character position {} in the active line (the line that contains the active presentation ",
2567 "position) and lines of subsequent text in the presentation component. TATE causes the ",
2568 "replacement of any tabulation stop previously set at the character position, but does not ",
2569 "affect other tabulation stops.",
2570 "\n\n",
2571 "A text string aligned with a tabulation stop set by TATE will be positioned so that the ",
2572 "(trailing edge of the) first graphic character of the string is placed at the tabulation ",
2573 "stop."
2574 ),
2575 param!(self, 0, 0)
2576 ),
2577 Function::TCC => format!(
2578 concat!(
2579 "Causes a character tabulation stop calling for alignment of a target graphic character {} ",
2580 "to be set at character position {} in the active line (the line that contains the active ",
2581 "presentation position) and lines of subsequent text in the presentation component. TCC ",
2582 "causes the replacement of any tabulation stop previously set at that character position, ",
2583 "but does not affect other tabulation stops.",
2584 "\n\n",
2585 "The positioning of a text string aligned with a tabulation stop set by TCC will be ",
2586 "determined by the first occurrence in the string of the target graphic character; that ",
2587 "character will be centred upon the tabulation stop. If the target character does not occur ",
2588 "within the string, then the trailing edge of the first character of the string will be ",
2589 "positioned at the tabulation stop.",
2590 "\n\n",
2591 "The value of {} indicates the code table position (binary value) of the target character ",
2592 "in the currently invoked code. For a 7-bit code, the permissible range of values is 32 ",
2593 "to 127; for an 8-bit code, the permissible range of values is 32 to 127 and 160 to 255."
2594 ),
2595 param!(self, 1, 32),
2596 param!(self, 0, 0),
2597 param!(self, 1, 32)
2598 ),
2599 Function::TSS => format!(
2600 concat!(
2601 "Used to establish the width of a thin space for subsequent text to be {} units. The ",
2602 "established width remains in effect until the next occurrence of TSS in the data stream.",
2603 "\n\n",
2604 "The unit in which the parameter is expressed is that established by the value of 'Select ",
2605 "Size Unit' (SSU)."
2606 ),
2607 param!(self, 0, 0)
2608 ),
2609 _ => self.short_description(),
2610 }
2611 }
2612}
2613
2614impl FromStr for TabulationControl {
2615 type Err = Infallible;
2616
2617 fn from_str(s: &str) -> Result<Self, Self::Err> {
2618 Ok(match s {
2619 "1" => Self::SetLineTabulationStop,
2620 "2" => Self::ClearCharacterTabulationStop,
2621 "3" => Self::ClearLineTabulationStop,
2622 "4" => Self::ClearCharacterTabulationStopsInLine,
2623 "5" => Self::ClearAllCharacterTabulationStops,
2624 "6" => Self::ClearLineTabulationStop,
2625 _ => Self::SetCharacterTabulationStop,
2626 })
2627 }
2628}
2629
2630impl ExplainSelection for TabulationControl {
2631 fn explain(&self) -> String {
2632 match self {
2633 Self::SetCharacterTabulationStop => {
2634 String::from("Set a character tabulation at the active position.")
2635 }
2636 Self::SetLineTabulationStop => {
2637 String::from("Set a line tabulation stop at the active line.")
2638 }
2639 Self::ClearCharacterTabulationStop => {
2640 String::from("Clear the character tabulation stop at the active position.")
2641 }
2642 Self::ClearLineTabulationStop => {
2643 String::from("Clear the line tabulation stop at the active line.")
2644 }
2645 Self::ClearCharacterTabulationStopsInLine => {
2646 String::from("Clear all character tabulation stops in the active line.")
2647 }
2648 Self::ClearAllCharacterTabulationStops => {
2649 String::from("Clear all character tabulation stops.")
2650 }
2651 Self::ClearAllLineTabulationStops => String::from("Clear all line tabulation stops."),
2652 }
2653 }
2654}
2655
2656impl FromStr for DeviceAttributes {
2657 type Err = Infallible;
2658
2659 fn from_str(s: &str) -> Result<Self, Self::Err> {
2660 Ok(match s {
2661 "0" => Self::Request,
2662 value @ _ => Self::Identify(
2663 value
2664 .parse::<u32>()
2665 .expect("Expected valid Device Attributes."),
2666 ),
2667 })
2668 }
2669}
2670
2671impl ExplainSelection for DeviceAttributes {
2672 fn explain(&self) -> String {
2673 match self {
2674 Self::Request => {
2675 String::from("Request Device Attribute identification from the receiving device.")
2676 }
2677 Self::Identify(v) => {
2678 format!(
2679 "The device sending this identifies as device with code {}.",
2680 v
2681 )
2682 }
2683 }
2684 }
2685}
2686
2687impl FromStr for AreaQualification {
2688 type Err = Infallible;
2689
2690 fn from_str(s: &str) -> Result<Self, Self::Err> {
2691 Ok(match s {
2692 "1" => Self::ProtectedGuarded,
2693 "2" => Self::GraphicCharacterInput,
2694 "3" => Self::NumericInput,
2695 "4" => Self::AlphabeticInput,
2696 "5" => Self::InputAlignedRight,
2697 "6" => Self::FillZeros,
2698 "7" => Self::SetCharacterTabulationStop,
2699 "8" => Self::ProtectedUnguarded,
2700 "9" => Self::FillSpaces,
2701 "10" => Self::InputAlignedLeft,
2702 "11" => Self::Reversed,
2703 _ => Self::UnprotectedUnguarded,
2704 })
2705 }
2706}
2707
2708impl ExplainSelection for AreaQualification {
2709 fn explain(&self) -> String {
2710 match self {
2711 Self::UnprotectedUnguarded => String::from("is unprotected an unguarded"),
2712 Self::ProtectedGuarded => String::from("is protected and guarded"),
2713 Self::GraphicCharacterInput => String::from("is a graphic input area"),
2714 Self::NumericInput => String::from("is a numeric input area"),
2715 Self::AlphabeticInput => String::from("is an alphabetic input area"),
2716 Self::InputAlignedRight => {
2717 String::from("has input aligned to the last position of this area")
2718 }
2719 Self::FillZeros => String::from("will be filled with ZEROs"),
2720 Self::SetCharacterTabulationStop => String::from("indicates a beginning of a field"),
2721 Self::ProtectedUnguarded => String::from("is protected and unguarded"),
2722 Self::FillSpaces => String::from("will be filled with SPACEs"),
2723 Self::InputAlignedLeft => {
2724 String::from("has input aligned to the first position of the area")
2725 }
2726 Self::Reversed => {
2727 String::from("has the order of character positions in the input field reversed.")
2728 }
2729 }
2730 }
2731}
2732
2733impl FromStr for DeviceStatusReport {
2734 type Err = Infallible;
2735
2736 fn from_str(s: &str) -> Result<Self, Self::Err> {
2737 Ok(match s {
2738 "1" => Self::BusyRepeat,
2739 "2" => Self::BusyLater,
2740 "3" => Self::MalfunctionRepeat,
2741 "4" => Self::MalfunctionLater,
2742 "5" => Self::RequestDeviceStatusReport,
2743 "6" => Self::RequestActivePositionReport,
2744 _ => Self::Ready,
2745 })
2746 }
2747}
2748
2749impl ExplainSelection for DeviceStatusReport {
2750 fn explain(&self) -> String {
2751 match self {
2752 Self::Ready => String::from(
2753 "The sending device reports to be read and no malfunctions have been detected."
2754 ),
2755 Self::BusyRepeat => String::from(
2756 "The sending device is busy. Another Device Status Report must be requested later."
2757 ),
2758 Self::BusyLater => String::from(
2759 "The sending device is busy. Another Device Status Report will be sent later."
2760 ),
2761 Self::MalfunctionRepeat => String::from(
2762 concat!(
2763 "Some malfunction has been detected by the sending device. Another Device Status Report must be ",
2764 "requested later."
2765 )
2766 ),
2767 Self::MalfunctionLater => String::from(
2768 concat!(
2769 "Some malfunction has been detected by the sending device. Another Device Status Report will ",
2770 "be sent later."
2771 )
2772 ),
2773 Self::RequestDeviceStatusReport => String::from(
2774 "A device status report is requested."
2775 ),
2776 Self::RequestActivePositionReport => String::from(
2777 concat!(
2778 "A report of the active presentation position or of the active data position in form of 'Active ",
2779 "Position Report' (CPR) is requested from the receiving device."
2780 )
2781 )
2782 }
2783 }
2784}
2785
2786impl FromStr for EraseArea {
2787 type Err = Infallible;
2788
2789 fn from_str(s: &str) -> Result<Self, Self::Err> {
2790 Ok(match s {
2791 "1" => Self::BeginToActivePosition,
2792 "2" => Self::BeginToEnd,
2793 _ => Self::ActivePositionToEnd,
2794 })
2795 }
2796}
2797
2798impl ExplainSelection for EraseArea {
2799 fn explain(&self) -> String {
2800 match self {
2801 Self::ActivePositionToEnd => String::from(
2802 "erases the contents of the currently active qualified area from the current position to the end"
2803 ),
2804 Self::BeginToActivePosition => String::from(
2805 concat!(
2806 "erases the contents of the currently active qualified area from the beginning of format area to ",
2807 "the current position"
2808 )
2809 ),
2810 Self::BeginToEnd => String::from(
2811 "erases all contents of the currently active qualified area"
2812 ),
2813 }
2814 }
2815}
2816
2817impl FromStr for ErasePage {
2818 type Err = Infallible;
2819
2820 fn from_str(s: &str) -> Result<Self, Self::Err> {
2821 Ok(match s {
2822 "1" => Self::BeginToActivePosition,
2823 "2" => Self::BeginToEnd,
2824 _ => Self::ActivePositionToEnd,
2825 })
2826 }
2827}
2828
2829impl ExplainSelection for ErasePage {
2830 fn explain(&self) -> String {
2831 match self {
2832 Self::ActivePositionToEnd => String::from(
2833 "erases the contents of the currently active page from the current position to the end"
2834 ),
2835 Self::BeginToActivePosition => String::from(
2836 concat!(
2837 "erases the contents of the currently active page from the beginning of format area to ",
2838 "the current position"
2839 )
2840 ),
2841 Self::BeginToEnd => String::from(
2842 "erases all contents of the currently active page"
2843 ),
2844 }
2845 }
2846}
2847
2848impl FromStr for EraseField {
2849 type Err = Infallible;
2850
2851 fn from_str(s: &str) -> Result<Self, Self::Err> {
2852 Ok(match s {
2853 "1" => Self::BeginToActivePosition,
2854 "2" => Self::BeginToEnd,
2855 _ => Self::ActivePositionToEnd,
2856 })
2857 }
2858}
2859
2860impl ExplainSelection for EraseField {
2861 fn explain(&self) -> String {
2862 match self {
2863 Self::ActivePositionToEnd => String::from(
2864 "erases the contents of the currently active field from the current position to the end"
2865 ),
2866 Self::BeginToActivePosition => String::from(
2867 concat!(
2868 "erases the contents of the currently active field from the beginning of format area to ",
2869 "the current position"
2870 )
2871 ),
2872 Self::BeginToEnd => String::from(
2873 "erases all contents of the currently active field"
2874 ),
2875 }
2876 }
2877}
2878
2879impl FromStr for EraseLine {
2880 type Err = Infallible;
2881
2882 fn from_str(s: &str) -> Result<Self, Self::Err> {
2883 Ok(match s {
2884 "1" => Self::BeginToActivePosition,
2885 "2" => Self::BeginToEnd,
2886 _ => Self::ActivePositionToEnd,
2887 })
2888 }
2889}
2890
2891impl ExplainSelection for EraseLine {
2892 fn explain(&self) -> String {
2893 match self {
2894 Self::ActivePositionToEnd => String::from(
2895 "erases the contents of the currently active line from the current position to the end"
2896 ),
2897 Self::BeginToActivePosition => String::from(
2898 concat!(
2899 "erases the contents of the currently active line from the beginning of format area to ",
2900 "the current position"
2901 )
2902 ),
2903 Self::BeginToEnd => String::from(
2904 "erases all contents of the currently active line"
2905 ),
2906 }
2907 }
2908}
2909
2910impl FromStr for Font {
2911 type Err = Infallible;
2912
2913 fn from_str(s: &str) -> Result<Self, Self::Err> {
2914 Ok(match s {
2915 "1" => Self::Alternative1,
2916 "2" => Self::Alternative2,
2917 "3" => Self::Alternative3,
2918 "4" => Self::Alternative4,
2919 "5" => Self::Alternative5,
2920 "6" => Self::Alternative6,
2921 "7" => Self::Alternative7,
2922 "8" => Self::Alternative8,
2923 "9" => Self::Alternative9,
2924 _ => Self::Primary,
2925 })
2926 }
2927}
2928
2929impl ExplainSelection for Font {
2930 fn explain(&self) -> String {
2931 match self {
2932 Self::Primary => String::from("primary font"),
2933 Self::Alternative1 => String::from("alternative font 1"),
2934 Self::Alternative2 => String::from("alternative font 2"),
2935 Self::Alternative3 => String::from("alternative font 3"),
2936 Self::Alternative4 => String::from("alternative font 4"),
2937 Self::Alternative5 => String::from("alternative font 5"),
2938 Self::Alternative6 => String::from("alternative font 6"),
2939 Self::Alternative7 => String::from("alternative font 7"),
2940 Self::Alternative8 => String::from("alternative font 8"),
2941 Self::Alternative9 => String::from("alternative font 9"),
2942 }
2943 }
2944}
2945
2946impl FromStr for GraphicCharacterCombination {
2947 type Err = Infallible;
2948
2949 fn from_str(s: &str) -> Result<Self, Self::Err> {
2950 Ok(match s {
2951 "1" => Self::StartOfCombination,
2952 "2" => Self::EndOfCombination,
2953 _ => Self::CombineTwo,
2954 })
2955 }
2956}
2957
2958impl ExplainSelection for GraphicCharacterCombination {
2959 fn explain(&self) -> String {
2960 match self {
2961 Self::CombineTwo => String::from(
2962 "Combine the following two graphic characters into a single symbol."
2963 ),
2964 Self::StartOfCombination => String::from(
2965 concat!(
2966 "Combine all following graphic characters into a single symbol, until the end of combination of ",
2967 "characters is indicated."
2968 )
2969 ),
2970 Self::EndOfCombination => String::from(
2971 "Indicates the end of combining all previous graphic characters into a single symbol."
2972 ),
2973 }
2974 }
2975}
2976
2977impl FromStr for IdentifyDeviceControlString {
2978 type Err = Infallible;
2979
2980 fn from_str(s: &str) -> Result<Self, Self::Err> {
2981 Ok(match s {
2982 "0" => Self::Diagnostic,
2983 "1" => Self::DynamicallyRedefinableCharacterSet,
2984 value @ _ => Self::Private(
2985 value
2986 .parse::<u32>()
2987 .expect("Expected valid Identify Device Control String."),
2988 ),
2989 })
2990 }
2991}
2992
2993impl ExplainSelection for IdentifyDeviceControlString {
2994 fn explain(&self) -> String {
2995 match self {
2996 Self::Diagnostic => String::from(
2997 concat!(
2998 "Subsequent 'Device Control Strings' (DCS) are intended for the diagnostic state of the ",
2999 "'Status Report Transfer Mode'"
3000 )
3001 ),
3002 Self::DynamicallyRedefinableCharacterSet => String::from(
3003 concat!(
3004 "Subsequent 'Device Control Strings' (DCS) are reserved for dynamically refinable character sets ",
3005 "according to Standard ECMA-35."
3006 )
3007 ),
3008 Self::Private(_) => String::from(
3009 "Subsequent 'Device Control Strings' (DCS) are for private use."
3010 ),
3011 }
3012 }
3013}
3014
3015impl FromStr for Justification {
3016 type Err = Infallible;
3017
3018 fn from_str(s: &str) -> Result<Self, Self::Err> {
3019 Ok(match s {
3020 "1" => Self::WordFill,
3021 "2" => Self::WordSpace,
3022 "3" => Self::LetterSpace,
3023 "4" => Self::Hyphenation,
3024 "5" => Self::Left,
3025 "6" => Self::Centre,
3026 "7" => Self::Right,
3027 "8" => Self::ItalianHyphenation,
3028 _ => Self::None,
3029 })
3030 }
3031}
3032
3033impl ExplainSelection for Justification {
3034 fn explain(&self) -> String {
3035 match self {
3036 Self::None => {
3037 String::from("The following text is not formatted to a special justification.")
3038 }
3039 Self::WordFill => String::from("The following text uses word-fill justification."),
3040 Self::WordSpace => String::from("The following text uses word-space justification."),
3041 Self::LetterSpace => {
3042 String::from("The following text uses letter-space justification.")
3043 }
3044 Self::Hyphenation => String::from("The following text uses hyphenation justification."),
3045 Self::Left => String::from("The following text is left aligned."),
3046 Self::Centre => String::from("The following text is centred."),
3047 Self::Right => String::from("The following text is right aligned."),
3048 Self::ItalianHyphenation => {
3049 String::from("The following text uses italian hyphenation justification.")
3050 }
3051 }
3052 }
3053}
3054
3055impl FromStr for MediaCopy {
3056 type Err = Infallible;
3057
3058 fn from_str(s: &str) -> Result<Self, Self::Err> {
3059 Ok(match s {
3060 "1" => Self::BeginTransferFromPrimary,
3061 "2" => Self::BeginTransferToSecondary,
3062 "3" => Self::BeginTransferFromSecondary,
3063 "4" => Self::StopRelayPrimary,
3064 "5" => Self::StartRelayPrimary,
3065 "6" => Self::StopRelaySecondary,
3066 "7" => Self::StartRelaySecondary,
3067 _ => Self::BeginTransferToPrimary,
3068 })
3069 }
3070}
3071
3072impl ExplainSelection for MediaCopy {
3073 fn explain(&self) -> String {
3074 match self {
3075 Self::BeginTransferToPrimary => {
3076 String::from("Initiate transfer to a primary auxiliary device.")
3077 }
3078 Self::BeginTransferFromPrimary => {
3079 String::from("Initiate transfer from a primary auxiliary device.")
3080 }
3081 Self::BeginTransferToSecondary => {
3082 String::from("Initiate transfer to a secondary auxiliary device.")
3083 }
3084 Self::BeginTransferFromSecondary => {
3085 String::from("Initiate transfer from a secondary auxiliary device.")
3086 }
3087 Self::StopRelayPrimary => String::from("Stop relay to a primary auxiliary device."),
3088 Self::StartRelayPrimary => String::from("Start relay to a primary auxiliary device."),
3089 Self::StopRelaySecondary => String::from("Stop relay to a secondary auxiliary device."),
3090 Self::StartRelaySecondary => {
3091 String::from("Start relay to a secondary auxiliary device.")
3092 }
3093 }
3094 }
3095}
3096
3097impl FromStr for PresentationExpandContract {
3098 type Err = Infallible;
3099
3100 fn from_str(s: &str) -> Result<Self, Self::Err> {
3101 Ok(match s {
3102 "1" => Self::Expanded,
3103 "2" => Self::Condensed,
3104 _ => Self::Normal,
3105 })
3106 }
3107}
3108
3109impl ExplainSelection for PresentationExpandContract {
3110 fn explain(&self) -> String {
3111 match self {
3112 Self::Normal => String::from("normal mode, as specified by SCS, SHS or SPI"),
3113 Self::Expanded => {
3114 String::from("extended mode, multiplied by a factor not greater than 2")
3115 }
3116 Self::Condensed => {
3117 String::from("condensed mode, multiplied by a factor not less than 0.5")
3118 }
3119 }
3120 }
3121}
3122
3123impl FromStr for PageFormat {
3124 type Err = Infallible;
3125
3126 fn from_str(s: &str) -> Result<Self, Self::Err> {
3127 Ok(match s {
3128 "1" => Self::WideBasicText,
3129 "2" => Self::TallBasicA4,
3130 "3" => Self::WideBasicA4,
3131 "4" => Self::TallLetter,
3132 "5" => Self::WideLetter,
3133 "6" => Self::TallExtendedA4,
3134 "7" => Self::WideExtendedA4,
3135 "8" => Self::TallLegal,
3136 "9" => Self::WideLegal,
3137 "10" => Self::A4ShortLines,
3138 "11" => Self::A4LongLines,
3139 "12" => Self::B5ShortLines,
3140 "13" => Self::B5LongLines,
3141 "14" => Self::B4ShortLines,
3142 "15" => Self::B4LongLines,
3143 _ => Self::TallBasicText,
3144 })
3145 }
3146}
3147
3148impl ExplainSelection for PageFormat {
3149 fn explain(&self) -> String {
3150 match self {
3151 Self::TallBasicText => String::from("Set the page to tall basic communication format."),
3152 Self::WideBasicText => String::from("Set the page to wide basic communication format."),
3153 Self::TallBasicA4 => String::from("Set the page to tall basic A4 format."),
3154 Self::WideBasicA4 => String::from("Set the page to wide basic A4 format."),
3155 Self::TallLetter => String::from("Set the page to north american tall letter format."),
3156 Self::WideLetter => String::from("Set the page to north american wide letter format."),
3157 Self::TallExtendedA4 => String::from("Set the page to tall extended A4 format."),
3158 Self::WideExtendedA4 => String::from("Set the page to wide extended A4 format."),
3159 Self::TallLegal => String::from("Set the page to north american tall legal format."),
3160 Self::WideLegal => String::from("Set the page to north american wide legal format."),
3161 Self::A4ShortLines => String::from("Set the page to A4 short lines format."),
3162 Self::A4LongLines => String::from("Set the page to A4 long lines format."),
3163 Self::B5ShortLines => String::from("Set the page to B5 short lines format."),
3164 Self::B5LongLines => String::from("Set the page to B5 long lines format."),
3165 Self::B4ShortLines => String::from("Set the page to B4 short lines format."),
3166 Self::B4LongLines => String::from("Set the page to B4 long lines format."),
3167 }
3168 }
3169}
3170
3171impl FromStr for ParallelText {
3172 type Err = Infallible;
3173
3174 fn from_str(s: &str) -> Result<Self, Self::Err> {
3175 Ok(match s {
3176 "1" => Self::BeginPrincipal,
3177 "2" => Self::BeginSupplementary,
3178 "3" => Self::BeginJapanesePhonetic,
3179 "4" => Self::BeginChinesePhonetic,
3180 "5" => Self::EndPhonetic,
3181 _ => Self::End,
3182 })
3183 }
3184}
3185
3186impl ExplainSelection for ParallelText {
3187 fn explain(&self) -> String {
3188 match self {
3189 Self::End => String::from(
3190 "End of parallel texts."
3191 ),
3192 Self::BeginPrincipal => String::from(
3193 concat!(
3194 "Beginning of principal text that should be displayed in parallel with one or more strings of ",
3195 "supplementary text."
3196 )
3197 ),
3198 Self::BeginSupplementary => String::from(
3199 "Beginning of supplementary text that should be displayed in parallel to the principal text."
3200 ),
3201 Self::BeginJapanesePhonetic => String::from(
3202 concat!(
3203 "Beginning of supplementary japanese phonetic annotation that should be displayed in parallel to ",
3204 "the principal text."
3205 )
3206 ),
3207 Self::BeginChinesePhonetic => String::from(
3208 concat!(
3209 "Beginning of supplementary chinese phonetic annotation that should be displayed in parallel to ",
3210 "the principal text."
3211 )
3212 ),
3213 Self::EndPhonetic => String::from(
3214 "End of a string of supplementary phonetic annotations."
3215 ),
3216 }
3217 }
3218}
3219
3220impl FromStr for Alignment {
3221 type Err = Infallible;
3222
3223 fn from_str(s: &str) -> Result<Self, Self::Err> {
3224 Ok(match s {
3225 "1" => Self::LineHomeLeader,
3226 "2" => Self::Centre,
3227 "3" => Self::CentreLeader,
3228 "4" => Self::LineLimit,
3229 "5" => Self::LineLimitLeader,
3230 "6" => Self::Justify,
3231 _ => Self::LineHome,
3232 })
3233 }
3234}
3235
3236impl ExplainSelection for Alignment {
3237 fn explain(&self) -> String {
3238 match self {
3239 Self::LineHome => String::from(
3240 "flush to the line home position"
3241 ),
3242 Self::LineHomeLeader => String::from(
3243 "flush to the line home position, margin and fill with leader"
3244 ),
3245 Self::Centre => String::from(
3246 "centred between line home position and line limit position margins"
3247 ),
3248 Self::CentreLeader => String::from(
3249 "centred between line home position and line limit position margins and fill with leader"
3250 ),
3251 Self::LineLimit => String::from(
3252 "flush to the line limit position margin"
3253 ),
3254 Self::LineLimitLeader => String::from(
3255 "flush to the line limit position margin and fill with leader"
3256 ),
3257 Self::Justify => String::from(
3258 "flush to both margins"
3259 ),
3260 }
3261 }
3262}
3263
3264impl FromStr for Mode {
3265 type Err = Infallible;
3266
3267 fn from_str(s: &str) -> Result<Self, Self::Err> {
3268 Ok(match s {
3269 "2" => Self::KeyboardActionMode,
3270 "3" => Self::ControlPresentationMode,
3271 "4" => Self::InsertionReplacementMode,
3272 "5" => Self::StatusReportTransferMode,
3273 "6" => Self::ErasureMode,
3274 "7" => Self::LineEditingMode,
3275 "8" => Self::BiDirectionalSupportMode,
3276 "9" => Self::DeviceComponentSelectMode,
3277 "10" => Self::CharacterEditingMode,
3278 "11" => Self::PositioningUnitMode,
3279 "12" => Self::SendReceiveMode,
3280 "13" => Self::FormatEffectorActionMode,
3281 "14" => Self::FormatEffectorTransferMode,
3282 "15" => Self::MultipleAreaTransferMode,
3283 "16" => Self::TransferTerminationMode,
3284 "17" => Self::StatusReportTransferMode,
3285 "18" => Self::TabulationStopMode,
3286 "21" => Self::GraphicRenditionCombinationMode,
3287 "22" => Self::ZeroDefaultMode,
3288 _ => Self::GuardedAreaTransferMode,
3289 })
3290 }
3291}
3292
3293impl ExplainMode for Mode {
3294 fn name(&self) -> String {
3295 match self {
3296 Self::GuardedAreaTransferMode => String::from("Guarded Area Transfer Mode"),
3297 Self::KeyboardActionMode => String::from("Keyboard Action Mode"),
3298 Self::ControlPresentationMode => String::from("Control Presentation Mode"),
3299 Self::InsertionReplacementMode => String::from("Insertion Replacement Mode"),
3300 Self::StatusReportTransferMode => String::from("Status Report Transfer Mode"),
3301 Self::ErasureMode => String::from("Erasure Mode"),
3302 Self::LineEditingMode => String::from("Line Editing Mode"),
3303 Self::BiDirectionalSupportMode => String::from("Bi-Directional Support Mode"),
3304 Self::DeviceComponentSelectMode => String::from("Device Component Select Mode"),
3305 Self::CharacterEditingMode => String::from("Character Editing Mode"),
3306 Self::PositioningUnitMode => String::from("Positioning Unit Mode"),
3307 Self::SendReceiveMode => String::from("Send Receive Mode"),
3308 Self::FormatEffectorActionMode => String::from("Format Effector Action Mode"),
3309 Self::FormatEffectorTransferMode => String::from("Format Effector Transfer Mode"),
3310 Self::MultipleAreaTransferMode => String::from("Multiple Area Transfer mode"),
3311 Self::TransferTerminationMode => String::from("Transfer Termination Mode"),
3312 Self::SelectedAreaTransferMode => String::from("Selected Area Transfer Mode"),
3313 Self::TabulationStopMode => String::from("Tabulation Stop Mode"),
3314 Self::GraphicRenditionCombinationMode => {
3315 String::from("Graphic Rendition Combination Mode")
3316 }
3317 Self::ZeroDefaultMode => String::from("Zero Default Mode"),
3318 }
3319 }
3320
3321 fn explain_reset(&self) -> String {
3322 match self {
3323 Self::GuardedAreaTransferMode => String::from(
3324 "Only the contents of unguarded areas in an eligible area are transmitted or transferred."
3325 ),
3326 Self::KeyboardActionMode => String::from(
3327 "All or part of the manual input facilities are enabled to be used."
3328 ),
3329 Self::ControlPresentationMode => String::from(
3330 "All control functions are performed as defined."
3331 ),
3332 Self::InsertionReplacementMode => String::from(
3333 concat!(
3334 "The graphic symbol of a graphic character or a control function, for which a graphical ",
3335 "representation is required, replaces (or, depending on the implementation, is combined with) the ",
3336 "graphic symbol imaged at the active presentation position"
3337 )
3338 ),
3339 Self::StatusReportTransferMode => String::from(
3340 "Status reports in the form of 'Device Control String' (DCS) are not generated automatically."
3341 ),
3342 Self::ErasureMode => String::from(
3343 "Only the contents of unprotected areas are affected by an erasure control function."
3344 ),
3345 Self::LineEditingMode => String::from(
3346 concat!(
3347 "The insertion of a line causes the contents of the active line and the following lines to be ",
3348 "shifted in the direction of line progression. A line deletion causes the contents of the ",
3349 "following lines to shifted in the opposite direction of line progression."
3350 )
3351 ),
3352 Self::BiDirectionalSupportMode => String::from(
3353 "Control functions are performed in the data component or the presentation component."
3354 ),
3355 Self::DeviceComponentSelectMode => String::from(
3356 "Certain control functions are performed in the presentation component at the current position."
3357 ),
3358 Self::CharacterEditingMode => String::from(
3359 concat!(
3360 "The insertion of a character causes the following contents to be shifted in the direction of ",
3361 "character progression. A character deletion causes the following contents to be shifted in the ",
3362 "direction opposite of character progression."
3363 )
3364 ),
3365 Self::PositioningUnitMode => String::from(
3366 "The unit for numeric parameters of the position format effectors is one character position."
3367 ),
3368 Self::SendReceiveMode => String::from(
3369 "Data which are locally entered are immediately imaged."
3370 ),
3371 Self::FormatEffectorActionMode => String::from(
3372 "Formator functions are performed immediately and may be stored in addition to being performed."
3373 ),
3374 Self::FormatEffectorTransferMode => String::from(
3375 concat!(
3376 "Formator functions may be inserted in a data stream to be transmitted or in data to be ",
3377 "transferred to an auxiliary input/output device."
3378 )
3379 ),
3380 Self::MultipleAreaTransferMode => String::from(
3381 concat!(
3382 "Only the contents of the selected area which contains the active presentation position are ",
3383 "eligible to be transmitted or transferred."
3384 )
3385 ),
3386 Self::TransferTerminationMode => String::from(
3387 concat!(
3388 "Only the contents of the character positions preceding the active presentation position in the ",
3389 "presentation component are eligible to be transmitted or transferred."
3390 )
3391 ),
3392 Self::SelectedAreaTransferMode => String::from(
3393 "Only the contents of selected areas are eligible to be transmitted or transferred."
3394 ),
3395 Self::TabulationStopMode => String::from(
3396 concat!(
3397 "Character tabulation stops in the presentation component are set or cleared in the active line ",
3398 "and in the corresponding character positions of the preceding lines and the following lines."
3399 )
3400 ),
3401 Self::GraphicRenditionCombinationMode => String::from(
3402 concat!(
3403 "Each occurrence of the control function 'Select Graphic Rendition' (SGR) cancels the effect of ",
3404 "any preceding occurrence."
3405 )
3406 ),
3407 Self::ZeroDefaultMode => String::from(
3408 "A parameter value of 0 of a control functions means the number 0."
3409 ),
3410 }
3411 }
3412
3413 fn explain_set(&self) -> String {
3414 match self {
3415 Self::GuardedAreaTransferMode => String::from(
3416 concat!(
3417 "The contents of guarded as well as of unguarded areas in an eligible area are transmitted or ",
3418 "transferred."
3419 )
3420 ),
3421 Self::KeyboardActionMode => String::from(
3422 "All or part of the manual input facilities are disabled."
3423 ),
3424 Self::ControlPresentationMode => String::from(
3425 "All control functions, except 'Reset Mode' are treated as graphic characters."
3426 ),
3427 Self::InsertionReplacementMode => String::from(
3428 concat!(
3429 "The graphic symbol of a graphic character or a control function, for which a graphical ",
3430 "representation is required,is inserted at the active presentation position."
3431 )
3432 ),
3433 Self::StatusReportTransferMode => String::from(
3434 concat!(
3435 "Status reports in the form of 'Device Control String' (DCS) are included in every data stream ",
3436 "transmitted or transferred."
3437 )
3438 ),
3439 Self::ErasureMode => String::from(
3440 "Only the contents of protected as well as protected areas are affected by an erasure control function."
3441 ),
3442 Self::LineEditingMode => String::from(
3443 concat!(
3444 "The insertion of a line causes the contents of the active line and the following lines to be ",
3445 "shifted in the direction of line progression. A line deletion causes the contents of the ",
3446 "following lines to shifted in the opposite direction of line progression."
3447 )
3448 ),
3449 Self::BiDirectionalSupportMode => String::from(
3450 concat!(
3451 "Control functions are performed in the data component. All bi-directional aspects of data are ",
3452 "handled by the device itself."
3453 )
3454 ),
3455 Self::DeviceComponentSelectMode => String::from(
3456 "Certain control functions are performed in the data component at the current position."
3457 ),
3458 Self::CharacterEditingMode => String::from(
3459 concat!(
3460 "The insertion of a character causes the following contents to be shifted in the direction ",
3461 "opposite of character progression. A character deletion causes the following contents to be ",
3462 "shifted in the direction of character progression."
3463 )
3464 ),
3465 Self::PositioningUnitMode => String::from(
3466 concat!(
3467 "The unit for numeric parameters of the position format effectors is that established by 'Select ",
3468 "Size Unit' (SSU)."
3469 )
3470 ),
3471 Self::SendReceiveMode => String::from(
3472 "Local input facilities are logically disconnected from the output mechanism."
3473 ),
3474 Self::FormatEffectorActionMode => String::from(
3475 "Formator functions are stored but not performed."
3476 ),
3477 Self::FormatEffectorTransferMode => String::from(
3478 concat!(
3479 "No formator functions other than those received while the 'Format Effector Action Mode' (FEAM) ",
3480 "is set to 'Store' are included in a transmitted data stream."
3481 )
3482 ),
3483 Self::MultipleAreaTransferMode => String::from(
3484 "The contents of all selected areas are eligible to be transmitted or transferred."
3485 ),
3486 Self::TransferTerminationMode => String::from(
3487 concat!(
3488 "The contents of character positions preceding, following, and at the active position are ",
3489 "eligible to be transmitted or transferred."
3490 )
3491 ),
3492 Self::SelectedAreaTransferMode => String::from(
3493 concat!(
3494 "The contents of all character positions, irrespective of any explicitly defined selected areas, ",
3495 "are eligible to be transmitted or transferred."
3496 )
3497 ),
3498 Self::TabulationStopMode => String::from(
3499 "Character tabulation stops in the presentation component are set or cleared in the active line only."
3500 ),
3501 Self::GraphicRenditionCombinationMode => String::from(
3502 concat!(
3503 "Each occurrence of the control function 'Select Graphic Rendition' (SGR) cancels only those ",
3504 "graphic rendition aspects to be changed that are specified by that SGR. All other graphic ",
3505 "rendition aspects remain unchanged."
3506 )
3507 ),
3508 Self::ZeroDefaultMode => String::from(
3509 "A parameter value of 0 of a control functions means a default value that might be different from 0."
3510 ),
3511 }
3512 }
3513}
3514
3515impl FromStr for PresentationVariant {
3516 type Err = Infallible;
3517
3518 fn from_str(s: &str) -> Result<Self, Self::Err> {
3519 Ok(match s {
3520 "1" => Self::LatinDecimals,
3521 "2" => Self::ArabicDecimals,
3522 "3" => Self::MirrorPairs,
3523 "4" => Self::MirrorFormulae,
3524 "5" => Self::Isolated,
3525 "6" => Self::Initial,
3526 "7" => Self::Medial,
3527 "8" => Self::Final,
3528 "9" => Self::DecimalFullStop,
3529 "10" => Self::DecimalComma,
3530 "11" => Self::VowelAboveOrBelow,
3531 "12" => Self::VowelAfterPreceding,
3532 "13" => Self::ContextualShapeArabicScriptWithLamAleph,
3533 "14" => Self::ContextualShapeArabicScript,
3534 "15" => Self::NoMirroring,
3535 "16" => Self::NoVowels,
3536 "17" => Self::SlantFollowsStringDirection,
3537 "18" => Self::NoContextualShapeArabicScript,
3538 "19" => Self::NoContextualShapeArabicScriptExceptDigits,
3539 "20" => Self::DeviceDependentDecimalDigits,
3540 "21" => Self::PersistCharacterForm,
3541 "22" => Self::DesistCharacterForm,
3542 _ => Self::Default,
3543 })
3544 }
3545}
3546
3547impl ExplainSelection for PresentationVariant {
3548 fn explain(&self) -> String {
3549 match self {
3550 Self::Default => String::from(
3551 "Default presentation. Cancels the effect of any other preceding SAPV."
3552 ),
3553 Self::LatinDecimals => String::from(
3554 "The decimal digits are presented by means of the graphic symbols used in the Latin script."
3555 ),
3556 Self::ArabicDecimals => String::from(
3557 concat!(
3558 "The decimal digits are presented by means of the graphic symbols used in the Arabic script, i.e. ",
3559 "the Hindi symbols."
3560 )
3561 ),
3562 Self::MirrorPairs => String::from(
3563 concat!(
3564 "When the direction of the character path is right-to-left, each of the graphic characters in the ",
3565 "character set(s) in use which is one of a left/right handed pair (parenthesis, square brackets, ",
3566 "curly brackets, greater-than/less-than signs, etc.) is presented as mirrored"
3567 )
3568 ),
3569 Self::MirrorFormulae => String::from(
3570 concat!(
3571 "When the direction of the character path is right-to-left, all graphic characters which ",
3572 "represent operators and delimiters in mathematical formulae and which are not symmetrical about ",
3573 "a vertical axis are presented as mirrored about that vertical axis."
3574 )
3575 ),
3576 Self::Isolated => String::from(
3577 "The following graphic character is presented in its isolated form."
3578 ),
3579 Self::Initial => String::from(
3580 "The following graphic character is presented in its initial form."
3581 ),
3582 Self::Medial => String::from(
3583 "The following graphic character is presented in its medial form."
3584 ),
3585 Self::Final => String::from(
3586 "The following graphic character is presented in its final form."
3587 ),
3588 Self::DecimalFullStop => String::from(
3589 concat!(
3590 "Where the bit combination 02/14 (FULL STOP) is intended to represent a decimal mark in a decimal ",
3591 "number it shall be represented by means of the graphic symbol FULL STOP."
3592 )
3593 ),
3594 Self::DecimalComma => String::from(
3595 concat!(
3596 "Where the bit combination 02/14 (FULL STOP) is intended to represent a decimal mark in a decimal ",
3597 "number it shall be presented by means of the graphic symbol COMMA."
3598 )
3599 ),
3600 Self::VowelAboveOrBelow => String::from(
3601 "Vowels are presented above or below the preceding character."
3602 ),
3603 Self::VowelAfterPreceding => String::from(
3604 "Vowels are presented after the preceding character."
3605 ),
3606 Self::ContextualShapeArabicScriptWithLamAleph => String::from(
3607 concat!(
3608 "Contextual shap determination of Arabic scripts, including the LAM-ALEPH ligature but excluding ",
3609 "all other Arabic ligatures."
3610 )
3611 ),
3612 Self::ContextualShapeArabicScript => String::from(
3613 "Contextual shape determination of Arabic scripts, excluding all Arabic ligatures."
3614 ),
3615 Self::NoMirroring => String::from(
3616 "Cancels the effect of mirroring settings."
3617 ),
3618 Self::NoVowels => String::from(
3619 "Vowels are not presented."
3620 ),
3621 Self::SlantFollowsStringDirection => String::from(
3622 concat!(
3623 "When the string direction is right-to-left, the italicized characters are slanted to the left, ",
3624 "when the string direction is left-to-right, the italicized characters are slanted to the left."
3625 )
3626 ),
3627 Self::NoContextualShapeArabicScript => String::from(
3628 concat!(
3629 "Contextual shape determination of Arabic scripts is not used, the graphic characters - including ",
3630 "the digits - are presented in the form they are stored (pass-through)."
3631 )
3632 ),
3633 Self::NoContextualShapeArabicScriptExceptDigits => String::from(
3634 concat!(
3635 "Contextual shape determination of Arabic scripts is not used, the graphic characters - excluding ",
3636 "the digits - are presented in the form they are stored (pass-through)."
3637 )
3638 ),
3639 Self::DeviceDependentDecimalDigits => String::from(
3640 "The graphic symbols used to present the decimal digits are device dependent."
3641 ),
3642 Self::PersistCharacterForm => String::from(
3643 concat!(
3644 "Establishes the effect of parameter values 'Isolated', 'Initial, 'Medial', and 'Final' for the ",
3645 "following graphic characters until cancelled."
3646 )
3647 ),
3648 Self::DesistCharacterForm => String::from(
3649 concat!(
3650 "Establishes the effect of parameter values 'Isolated', 'Initial', 'Medial', and 'Final' for the ",
3651 "next single graphic character only."
3652 )
3653 ),
3654 }
3655 }
3656}
3657
3658impl FromStr for CharacterOrientation {
3659 type Err = Infallible;
3660
3661 fn from_str(s: &str) -> Result<Self, Self::Err> {
3662 Ok(match s {
3663 "1" => Self::Rotate45,
3664 "2" => Self::Rotate90,
3665 "3" => Self::Rotate135,
3666 "4" => Self::Rotate180,
3667 "5" => Self::Rotate225,
3668 "6" => Self::Rotate270,
3669 "7" => Self::Rotate315,
3670 _ => Self::Normal,
3671 })
3672 }
3673}
3674
3675impl ExplainSelection for CharacterOrientation {
3676 fn explain(&self) -> String {
3677 match self {
3678 Self::Normal => String::from("Rotate by 0°."),
3679 Self::Rotate45 => String::from("Rotate by 45°."),
3680 Self::Rotate90 => String::from("Rotate by 90°."),
3681 Self::Rotate135 => String::from("Rotate by 135°."),
3682 Self::Rotate180 => String::from("Rotate by 180°."),
3683 Self::Rotate225 => String::from("Rotate by 225°."),
3684 Self::Rotate270 => String::from("Rotate by 270°."),
3685 Self::Rotate315 => String::from("Rotate by 315°."),
3686 }
3687 }
3688}
3689
3690impl FromStr for CharacterPath {
3691 type Err = Infallible;
3692
3693 fn from_str(s: &str) -> Result<Self, Self::Err> {
3694 Ok(match s {
3695 "2" => Self::RightToLeft,
3696 _ => Self::LefToRight,
3697 })
3698 }
3699}
3700
3701impl ExplainSelection for CharacterPath {
3702 fn explain(&self) -> String {
3703 match self {
3704 Self::LefToRight => String::from("Left-to-right, or top-to-bottom."),
3705 Self::RightToLeft => String::from("Right-to-left, or bottom-to-top."),
3706 }
3707 }
3708}
3709
3710impl FromStr for CharacterPathScope {
3711 type Err = Infallible;
3712
3713 fn from_str(s: &str) -> Result<Self, Self::Err> {
3714 Ok(match s {
3715 "1" => Self::InPresentationComponent,
3716 "2" => Self::InDataComponent,
3717 _ => Self::Undefined,
3718 })
3719 }
3720}
3721
3722impl ExplainSelection for CharacterPathScope {
3723 fn explain(&self) -> String {
3724 match self {
3725 CharacterPathScope::Undefined => String::from(
3726 "The scope of the new character path is undefined."
3727 ),
3728 CharacterPathScope::InPresentationComponent => String::from(
3729 concat!(
3730 "The content of the active line in the presentation component is updated to correspond to the ",
3731 "content of the active line in the data component according to the newly established character ",
3732 "path characteristics in the presentation component."
3733 )
3734 ),
3735 CharacterPathScope::InDataComponent => String::from(
3736 concat!(
3737 "The content of the active line in the data component is updated to correspond to the content of ",
3738 "the active line in the presentation component according to the newly established character path ",
3739 "characteristics in the presentation component."
3740 )
3741 ),
3742 }
3743 }
3744}
3745
3746impl FromStr for StringDirection {
3747 type Err = Infallible;
3748
3749 fn from_str(s: &str) -> Result<Self, Self::Err> {
3750 Ok(match s {
3751 "1" => Self::StartLeftToRight,
3752 "2" => Self::StartRightToLeft,
3753 _ => Self::End,
3754 })
3755 }
3756}
3757
3758impl ExplainSelection for StringDirection {
3759 fn explain(&self) -> String {
3760 match self {
3761 Self::End => {
3762 String::from("End of a directed string - re-establish the previous direction.")
3763 }
3764 Self::StartLeftToRight => {
3765 String::from("Start of a directed string, establish the direction left-to-right.")
3766 }
3767 Self::StartRightToLeft => {
3768 String::from("Start of a directed string, establish the direction right-to-left.")
3769 }
3770 }
3771 }
3772}
3773
3774impl FromStr for EditingExtend {
3775 type Err = Infallible;
3776
3777 fn from_str(s: &str) -> Result<Self, Self::Err> {
3778 Ok(match s {
3779 "1" => Self::ActiveLine,
3780 "2" => Self::ActiveField,
3781 "3" => Self::QualifiedArea,
3782 "4" => Self::All,
3783 _ => Self::ActivePage,
3784 })
3785 }
3786}
3787
3788impl ExplainSelection for EditingExtend {
3789 fn explain(&self) -> String {
3790 match self {
3791 Self::ActivePage => String::from("the shifted part is limited to the active page"),
3792 Self::ActiveLine => String::from("the shifted part is limited to the active line"),
3793 Self::ActiveField => String::from("the shifted part is limited to the active field"),
3794 Self::QualifiedArea => {
3795 String::from("the shifted part is limited to the active qualified area")
3796 }
3797 Self::All => String::from("the shifted part is not limited"),
3798 }
3799 }
3800}
3801
3802impl FromStr for Load {
3803 type Err = Infallible;
3804
3805 fn from_str(s: &str) -> Result<Self, Self::Err> {
3806 Ok(match s {
3807 "0" => Self::None,
3808 value @ _ => Self::Bin(
3809 value
3810 .parse::<u32>()
3811 .expect("Expected valid value for Load directive"),
3812 ),
3813 })
3814 }
3815}
3816
3817impl ExplainSelection for Load {
3818 fn explain(&self) -> String {
3819 match self {
3820 Self::None => String::from("Eject sheet, no new sheet loaded."),
3821 Self::Bin(bin) => format!("Eject sheet, load a new sheet from bin {}.", bin),
3822 }
3823 }
3824}
3825
3826impl FromStr for Stack {
3827 type Err = Infallible;
3828
3829 fn from_str(s: &str) -> Result<Self, Self::Err> {
3830 Ok(match s {
3831 "0" => Self::None,
3832 value @ _ => Self::Stacker(
3833 value
3834 .parse::<u32>()
3835 .expect("Expected valid value for Load directive"),
3836 ),
3837 })
3838 }
3839}
3840
3841impl ExplainSelection for Stack {
3842 fn explain(&self) -> String {
3843 match self {
3844 Self::None => String::from("Eject sheet, no stacker specified."),
3845 Self::Stacker(stacker) => format!("Eject sheet into the stacker {}.", stacker),
3846 }
3847 }
3848}
3849
3850impl FromStr for GraphicRendition {
3851 type Err = Infallible;
3852
3853 fn from_str(s: &str) -> Result<Self, Self::Err> {
3854 Ok(match s {
3855 "1" => Self::HighIntensity,
3856 "2" => Self::LowIntensity,
3857 "3" => Self::Italicized,
3858 "4" => Self::Underlined,
3859 "5" => Self::SlowlyBlinking,
3860 "6" => Self::RapidlyBlinking,
3861 "7" => Self::Negative,
3862 "8" => Self::Concealed,
3863 "9" => Self::CrossedOut,
3864 "10" => Self::PrimaryFont,
3865 "11" => Self::FirstAlternativeFont,
3866 "12" => Self::SecondAlternativeFont,
3867 "13" => Self::ThirdAlternativeFont,
3868 "14" => Self::ForthAlternativeFont,
3869 "15" => Self::FifthAlternativeFont,
3870 "16" => Self::SixthAlternativeFont,
3871 "17" => Self::SeventhAlternativeFont,
3872 "18" => Self::EighthAlternativeFont,
3873 "19" => Self::NinthAlternativeFont,
3874 "20" => Self::Fraktur,
3875 "21" => Self::DoublyUnderlined,
3876 "22" => Self::NormalIntensity,
3877 "23" => Self::NormalStyle,
3878 "24" => Self::NotUnderlined,
3879 "25" => Self::NotBlinking,
3880 "27" => Self::Positive,
3881 "28" => Self::Revealed,
3882 "29" => Self::NotCrossedOut,
3883 "30" => Self::BlackForeground,
3884 "31" => Self::RedForeground,
3885 "32" => Self::GreenForeground,
3886 "33" => Self::YellowForeground,
3887 "34" => Self::BlueForeground,
3888 "35" => Self::MagentaForeground,
3889 "36" => Self::CyanForeground,
3890 "37" => Self::WhiteForeground,
3891 "39" => Self::DefaultForeground,
3892 "40" => Self::BlackBackground,
3893 "41" => Self::RedBackground,
3894 "42" => Self::GreenBackground,
3895 "43" => Self::YellowBackground,
3896 "44" => Self::BlueBackground,
3897 "45" => Self::MagentaBackground,
3898 "46" => Self::CyanBackground,
3899 "47" => Self::WhiteBackground,
3900 "49" => Self::DefaultBackground,
3901 "51" => Self::Framed,
3902 "52" => Self::Encircled,
3903 "53" => Self::Overlined,
3904 "54" => Self::NotFramed,
3905 "55" => Self::NotOverlined,
3906 "60" => Self::IdeogramUnderline,
3907 "61" => Self::IdeogramUnderline,
3908 "62" => Self::IdeogramStressMarking,
3909 "63" => Self::CancelIdeogramRendition,
3910 _ => Self::Default,
3911 })
3912 }
3913}
3914
3915impl ExplainSelection for GraphicRendition {
3916 fn explain(&self) -> String {
3917 match self {
3918 Self::Default => String::from("Default rendition, cancel all effects."),
3919 Self::HighIntensity => String::from("Bold or increased intensity."),
3920 Self::LowIntensity => String::from("Faint, decreased intensity or second color."),
3921 Self::Italicized => String::from("Italicized."),
3922 Self::Underlined => String::from("Singly underlined."),
3923 Self::SlowlyBlinking => String::from("Slowly blinking (less than 150 per minute)."),
3924 Self::RapidlyBlinking => String::from("Rapidly blinking (more than 150 per minute)."),
3925 Self::Negative => String::from("Negative image."),
3926 Self::Concealed => String::from("Concealed characters."),
3927 Self::CrossedOut => {
3928 String::from("Crossed-out (characters still legible but marked as to be deleted).")
3929 }
3930 Self::PrimaryFont => String::from("Primary (default) font."),
3931 Self::FirstAlternativeFont => String::from("First alternative font."),
3932 Self::SecondAlternativeFont => String::from("Second alternative font."),
3933 Self::ThirdAlternativeFont => String::from("Third alternative font."),
3934 Self::ForthAlternativeFont => String::from("Forth alternative font."),
3935 Self::FifthAlternativeFont => String::from("Fifth alternative font."),
3936 Self::SixthAlternativeFont => String::from("Sixth alternative font."),
3937 Self::SeventhAlternativeFont => String::from("Seventh alternative font."),
3938 Self::EighthAlternativeFont => String::from("Eighth alternative font."),
3939 Self::NinthAlternativeFont => String::from("Ninth alternative font."),
3940 Self::Fraktur => String::from("Fraktur (Gothic)."),
3941 Self::DoublyUnderlined => String::from("Doubly underlined."),
3942 Self::NormalIntensity => String::from("Normal intensity or normal color."),
3943 Self::NormalStyle => String::from("Normal style, not italicized, not fraktur."),
3944 Self::NotUnderlined => String::from("Not underlined."),
3945 Self::NotBlinking => String::from("Not blinking."),
3946 Self::Positive => String::from("Positive image."),
3947 Self::Revealed => String::from("Revealed characters."),
3948 Self::NotCrossedOut => String::from("Not crossed out."),
3949 Self::BlackForeground => String::from("Black foreground color."),
3950 Self::RedForeground => String::from("Red foreground color."),
3951 Self::GreenForeground => String::from("Green foreground color."),
3952 Self::YellowForeground => String::from("Yellow foreground color."),
3953 Self::BlueForeground => String::from("Blue foreground color."),
3954 Self::MagentaForeground => String::from("Magenta foreground color."),
3955 Self::CyanForeground => String::from("Cyan foreground color."),
3956 Self::WhiteForeground => String::from("White foreground color."),
3957 Self::DefaultForeground => String::from("Default foreground color."),
3958 Self::BlackBackground => String::from("Black background color."),
3959 Self::RedBackground => String::from("Red background color."),
3960 Self::GreenBackground => String::from("Green background color."),
3961 Self::YellowBackground => String::from("Yellow background color."),
3962 Self::BlueBackground => String::from("Blue background color."),
3963 Self::MagentaBackground => String::from("Magenta background color."),
3964 Self::CyanBackground => String::from("Cyan background color."),
3965 Self::WhiteBackground => String::from("White background color."),
3966 Self::DefaultBackground => String::from("Default background color."),
3967 Self::Framed => String::from("Framed."),
3968 Self::Encircled => String::from("Encircled."),
3969 Self::Overlined => String::from("Overlined."),
3970 Self::NotFramed => String::from("Not Framed."),
3971 Self::NotOverlined => String::from("Not Overlined."),
3972 Self::IdeogramUnderline => String::from("Ideogram underline or right side line."),
3973 Self::IdeogramDoubleUnderline => {
3974 String::from("Ideogram double underline or double line on the right side.")
3975 }
3976 Self::IdeogramStressMarking => String::from("Ideogram stress marking."),
3977 Self::CancelIdeogramRendition => String::from("Cancel Ideogram rendition settings."),
3978 }
3979 }
3980}
3981
3982impl FromStr for CharacterSpacing {
3983 type Err = Infallible;
3984
3985 fn from_str(s: &str) -> Result<Self, Self::Err> {
3986 Ok(match s {
3987 "1" => Self::TwelveCharacters,
3988 "2" => Self::FifteenCharacters,
3989 "3" => Self::SixCharacters,
3990 "4" => Self::ThreeCharacters,
3991 "5" => Self::NineCharacters,
3992 "6" => Self::FourCharacters,
3993 _ => Self::TenCharacters,
3994 })
3995 }
3996}
3997
3998impl ExplainSelection for CharacterSpacing {
3999 fn explain(&self) -> String {
4000 match self {
4001 Self::TenCharacters => {
4002 String::from("Set character spacing to 10 characters per 25.4mm.")
4003 }
4004 Self::TwelveCharacters => {
4005 String::from("Set character spacing to 12 characters per 25.4mm.")
4006 }
4007 Self::FifteenCharacters => {
4008 String::from("Set character spacing to 15 characters per 25.4mm.")
4009 }
4010 Self::SixCharacters => {
4011 String::from("Set character spacing to 6 characters per 25.4mm.")
4012 }
4013 Self::ThreeCharacters => {
4014 String::from("Set character spacing to 3 characters per 25.4mm.")
4015 }
4016 Self::NineCharacters => {
4017 String::from("Set character spacing to 9 characters per 25.4mm.")
4018 }
4019 Self::FourCharacters => {
4020 String::from("Set character spacing to 4 characters per 25.4mm.")
4021 }
4022 }
4023 }
4024}
4025
4026impl FromStr for MovementDirection {
4027 type Err = Infallible;
4028
4029 fn from_str(s: &str) -> Result<Self, Self::Err> {
4030 Ok(match s {
4031 "1" => Self::Opposite,
4032 _ => Self::Normal,
4033 })
4034 }
4035}
4036
4037impl ExplainSelection for MovementDirection {
4038 fn explain(&self) -> String {
4039 match self {
4040 Self::Normal => String::from(
4041 "Implicit movement is in the same direction as that of character progression.",
4042 ),
4043 Self::Opposite => String::from(
4044 "Implicit movement is in the opposite direction as that of character progression.",
4045 ),
4046 }
4047 }
4048}
4049
4050impl FromStr for PresentationDirection {
4051 type Err = Infallible;
4052
4053 fn from_str(s: &str) -> Result<Self, Self::Err> {
4054 Ok(match s {
4055 "1" => Self::VerticalLinesRightToLeftTopToBottom,
4056 "2" => Self::VerticalLinesLeftToRightTopToBottom,
4057 "3" => Self::HorizontalLinesTopToBottomRightToLeft,
4058 "4" => Self::VerticalLinesLeftToRightBottomToTop,
4059 "5" => Self::HorizontalLinesBottomToTopRightToLeft,
4060 "6" => Self::HorizontalLinesBottomToTopLefToRight,
4061 "7" => Self::VerticalLinesRightToLeftBottomToTop,
4062 _ => Self::HorizontalLinesTopToBottomLeftToRight,
4063 })
4064 }
4065}
4066
4067impl ExplainSelection for PresentationDirection {
4068 fn explain(&self) -> String {
4069 match self {
4070 Self::HorizontalLinesTopToBottomLeftToRight => String::from(
4071 "horizontal line orientation, top-to-bottom line progression, left-to-right character path"
4072 ),
4073 Self::VerticalLinesRightToLeftTopToBottom => String::from(
4074 "vertical line orientation, right-to-left line progression, top-to-bottom character path"
4075 ),
4076 Self::VerticalLinesLeftToRightTopToBottom => String::from(
4077 "vertical line orientation, left-to-right line progression, top-to-bottom character path"
4078 ),
4079 Self::HorizontalLinesTopToBottomRightToLeft => String::from(
4080 "horizontal line orientation, top-to-bottom line progression, right-to-left character path"
4081 ),
4082 Self::VerticalLinesLeftToRightBottomToTop => String::from(
4083 "vertical line orientation, left-to-right line progression, bottom-to-top character path"
4084 ),
4085 Self::HorizontalLinesBottomToTopRightToLeft => String::from(
4086 "horizontal line orientation, bottom-to-top line progression, right-to-left character path"
4087 ),
4088 Self::HorizontalLinesBottomToTopLefToRight => String::from(
4089 "horizontal line orientation, bottom-to-top line progression, left-to-right character path"
4090 ),
4091 Self::VerticalLinesRightToLeftBottomToTop => String::from(
4092 "vertical line orientation, right to left line progression, bottom-to-top character path"
4093 ),
4094 }
4095 }
4096}
4097
4098impl FromStr for PresentationDirectionScope {
4099 type Err = Infallible;
4100
4101 fn from_str(s: &str) -> Result<Self, Self::Err> {
4102 Ok(match s {
4103 "1" => Self::InPresentationComponent,
4104 "2" => Self::InDataComponent,
4105 _ => Self::Undefined,
4106 })
4107 }
4108}
4109
4110impl ExplainSelection for PresentationDirectionScope {
4111 fn explain(&self) -> String {
4112 match self {
4113 Self::Undefined => String::from("an undefined scope"),
4114 Self::InPresentationComponent => String::from("the presentation component"),
4115 Self::InDataComponent => String::from("the data component"),
4116 }
4117 }
4118}
4119
4120impl FromStr for PrintQuality {
4121 type Err = Infallible;
4122
4123 fn from_str(s: &str) -> Result<Self, Self::Err> {
4124 Ok(match s {
4125 "1" => Self::MediumQualityMediumSpeed,
4126 "2" => Self::LowQualityHighSpeed,
4127 _ => Self::HighQualityLowSpeed,
4128 })
4129 }
4130}
4131
4132impl ExplainSelection for PrintQuality {
4133 fn explain(&self) -> String {
4134 match self {
4135 Self::HighQualityLowSpeed => String::from("Print in high quality with low speed."),
4136 Self::MediumQualityMediumSpeed => {
4137 String::from("Print in medium quality with medium speed.")
4138 }
4139 Self::LowQualityHighSpeed => String::from("Print in low quality with high speed."),
4140 }
4141 }
4142}
4143
4144impl FromStr for ReversedString {
4145 type Err = Infallible;
4146
4147 fn from_str(s: &str) -> Result<Self, Self::Err> {
4148 Ok(match s {
4149 "1" => Self::Start,
4150 _ => Self::End,
4151 })
4152 }
4153}
4154
4155impl ExplainSelection for ReversedString {
4156 fn explain(&self) -> String {
4157 match self {
4158 Self::End => {
4159 String::from("End of a reversed string; re-establish the previous direction.")
4160 }
4161 Self::Start => String::from("Beginning of a reversed string; reverse the direction."),
4162 }
4163 }
4164}
4165
4166impl FromStr for SizeUnit {
4167 type Err = Infallible;
4168
4169 fn from_str(s: &str) -> Result<Self, Self::Err> {
4170 Ok(match s {
4171 "1" => Self::Millimetre,
4172 "2" => Self::ComputerDecipoint,
4173 "3" => Self::Decidot,
4174 "4" => Self::Mil,
4175 "5" => Self::BasicMeasuringUnit,
4176 "6" => Self::Micrometer,
4177 "7" => Self::Pixel,
4178 "8" => Self::Decipoint,
4179 _ => Self::Character,
4180 })
4181 }
4182}
4183
4184impl ExplainSelection for SizeUnit {
4185 fn explain(&self) -> String {
4186 match self {
4187 Self::Character => {
4188 String::from("Character. The dimension of this unit is device-dependent.")
4189 }
4190 Self::Millimetre => String::from("Millimetre."),
4191 Self::ComputerDecipoint => {
4192 String::from("Computer decipoint (0.03528 mm - 1/720 of 25.4 mm).")
4193 }
4194 Self::Decidot => String::from("Decidot (0.03759 mm - 10/266 mm)."),
4195 Self::Mil => String::from("Mil (0.0254 mm - 1/1000 of 25.4 mm)."),
4196 Self::BasicMeasuringUnit => {
4197 String::from("Basic Measuring Unit (BMU) (0.02117 mm - 1/1200 of 25.4 mm).")
4198 }
4199 Self::Micrometer => String::from("Micrometer (0.001 mm)"),
4200 Self::Pixel => {
4201 String::from("Pixel, the smallest increment that can be specified in the device.")
4202 }
4203 Self::Decipoint => String::from("Decipoint (0.03514mm - 35/996 mm)."),
4204 }
4205 }
4206}
4207
4208impl FromStr for LineSpacing {
4209 type Err = Infallible;
4210
4211 fn from_str(s: &str) -> Result<Self, Self::Err> {
4212 Ok(match s {
4213 "1" => Self::FourLinesPer25,
4214 "2" => Self::ThreeLinesPer25,
4215 "3" => Self::TwelveLinesPer25,
4216 "4" => Self::EightLinesPer25,
4217 "5" => Self::SixLinesPer30,
4218 "6" => Self::FourLinesPer30,
4219 "7" => Self::ThreeLinesPer30,
4220 "8" => Self::TwelveLinesPer30,
4221 "9" => Self::TwoLinesPer25,
4222 _ => Self::SixLinesPer25,
4223 })
4224 }
4225}
4226
4227impl ExplainSelection for LineSpacing {
4228 fn explain(&self) -> String {
4229 match self {
4230 Self::SixLinesPer25 => String::from("Set line spacing to 6 lines per 25 mm."),
4231 Self::FourLinesPer25 => String::from("Set line spacing to 4 lines per 25 mm."),
4232 Self::ThreeLinesPer25 => String::from("Set line spacing to 3 lines per 25 mm."),
4233 Self::TwelveLinesPer25 => String::from("Set line spacing to 12 lines per 25 mm."),
4234 Self::EightLinesPer25 => String::from("Set line spacing to 8 lines per 25 mm."),
4235 Self::SixLinesPer30 => String::from("Set line spacing to 6 lines per 30 mm."),
4236 Self::FourLinesPer30 => String::from("Set line spacing to 4 lines per 30 mm."),
4237 Self::ThreeLinesPer30 => String::from("Set line spacing to 3 lines per 30 mm."),
4238 Self::TwelveLinesPer30 => String::from("Set line spacing to 12 lines per 30 mm."),
4239 Self::TwoLinesPer25 => String::from("Set line spacing to 2 lines per 25 mm."),
4240 }
4241 }
4242}
4243
4244impl FromStr for ClearTabulation {
4245 type Err = Infallible;
4246
4247 fn from_str(s: &str) -> Result<Self, Self::Err> {
4248 Ok(match s {
4249 "1" => Self::LineTabulationStopActiveLine,
4250 "2" => Self::AllCharacterTabulationStopsActiveLine,
4251 "3" => Self::AllCharacterTabulationStops,
4252 "4" => Self::AllTabulationStops,
4253 "5" => Self::AllTabulationStops,
4254 _ => Self::CharacterTabulationStopActivePosition,
4255 })
4256 }
4257}
4258
4259impl ExplainSelection for ClearTabulation {
4260 fn explain(&self) -> String {
4261 match self {
4262 Self::CharacterTabulationStopActivePosition => String::from(
4263 "Clear the character tabulation stop at the active presentation position.",
4264 ),
4265 Self::LineTabulationStopActiveLine => {
4266 String::from("Clear the line tabulation stop at the active line.")
4267 }
4268 Self::AllCharacterTabulationStopsActiveLine => {
4269 String::from("Clear all character tabulation stops at the active line.")
4270 }
4271 Self::AllCharacterTabulationStops => {
4272 String::from("Clear all character tabulation stops.")
4273 }
4274 Self::AllLineTabulationStops => String::from("Clear all line tabulation stops."),
4275 Self::AllTabulationStops => String::from("Clear all tabulation stops."),
4276 }
4277 }
4278}
4279
4280#[cfg(test)]
4281mod tests {
4282 use crate::{c0::CR, explain::Explain};
4283
4284 #[test]
4286 fn get_short_name() {
4287 assert_eq!(CR.short_name(), Some("CR"))
4288 }
4289
4290 #[test]
4292 fn get_long_name() {
4293 assert_eq!(CR.long_name(), "Carriage Return")
4294 }
4295
4296 #[test]
4298 fn get_short_description() {
4299 assert_eq!(CR.short_description(), "Move to the beginning of the line.")
4300 }
4301
4302 #[test]
4304 fn get_long_description() {
4305 assert_eq!(CR.long_description(),
4306 concat!(
4307 "Move the cursor to the beginning of the line. The exact meaning depends on the setting of 'Device ",
4308 "Component Select Mode' (DCSM) and on the parameter value of 'Select Implicit Movement Direction' (SIMD).",
4309 "\n\nIf the DCSM is set to 'Presentation' and SIMD is set to 'Normal', it causes the active presentation ",
4310 "position to be moved to the line home position of the same line in the presentation component. The line ",
4311 "home position is established by the parameter value of 'Set Line Home' SLH.\nWith SIMD set to ",
4312 "'Opposite', it causes the active presentation position to be moved to the line limit position of the ",
4313 "same line in the presentation component. The line limit position is established by the parameter value ",
4314 "of 'Set Line Limit' (SLL).\n\nIf the DCSM is set to 'Data' and SIMD is set to 'Normal', it causes the ",
4315 "active data position to be moved to the line home position of the same line in the data component. The ",
4316 "line home position is established by the parameter value of 'Set Line Home' (SLH)\nWith SIMD set to ",
4317 "'Opposite', it causes the active data position to be moved to the line limit position of the same line ",
4318 "in the data component. The line limit position position is established by the parameter value of ",
4319 "'Set Line Limit' (SLL)."
4320 )
4321 )
4322 }
4323}