Skip to content

Commit 499f056

Browse files
authored
Merge pull request #9573 from sylvestre/ptx
ptx: implement GNU mode with dumb terminal format
2 parents a0c14aa + 15b2df9 commit 499f056

File tree

2 files changed

+78
-8
lines changed

2 files changed

+78
-8
lines changed

src/uu/ptx/src/ptx.rs

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,6 @@ struct WordRef {
197197

198198
#[derive(Debug, Error)]
199199
enum PtxError {
200-
#[error("{}", translate!("ptx-error-dumb-format"))]
201-
DumbFormat,
202-
203200
#[error("{}", translate!("ptx-error-not-implemented", "feature" => (*.0)))]
204201
NotImplemented(&'static str),
205202

@@ -216,8 +213,6 @@ fn get_config(matches: &clap::ArgMatches) -> UResult<Config> {
216213
config.gnu_ext = false;
217214
config.format = OutFormat::Roff;
218215
"[^ \t\n]+".clone_into(&mut config.context_regex);
219-
} else {
220-
return Err(PtxError::NotImplemented("GNU extensions").into());
221216
}
222217
if matches.contains_id(options::SENTENCE_REGEXP) {
223218
return Err(PtxError::NotImplemented("-S").into());
@@ -589,6 +584,69 @@ fn format_tex_line(
589584
output
590585
}
591586

587+
fn format_dumb_line(
588+
config: &Config,
589+
word_ref: &WordRef,
590+
line: &str,
591+
chars_line: &[char],
592+
reference: &str,
593+
) -> String {
594+
let (tail, before, keyword, after, head) =
595+
prepare_line_chunks(config, word_ref, line, chars_line, reference);
596+
597+
// Calculate the position for the left part
598+
// The left part consists of tail (if present) + space + before
599+
let left_part = if tail.is_empty() {
600+
before
601+
} else if before.is_empty() {
602+
tail
603+
} else {
604+
format!("{tail} {before}")
605+
};
606+
607+
// Calculate the position for the right part
608+
let right_part = if head.is_empty() {
609+
after
610+
} else if after.is_empty() {
611+
head
612+
} else {
613+
format!("{after} {head}")
614+
};
615+
616+
// Calculate the width for the left half (before the keyword)
617+
let half_width = config.line_width / 2;
618+
619+
// Right-justify the left part within the left half
620+
let padding = if left_part.len() < half_width {
621+
half_width - left_part.len()
622+
} else {
623+
0
624+
};
625+
626+
// Build the output line with padding, left part, gap, keyword, and right part
627+
let mut output = String::new();
628+
output.push_str(&" ".repeat(padding));
629+
output.push_str(&left_part);
630+
631+
// Add gap before keyword
632+
output.push_str(&" ".repeat(config.gap_size));
633+
634+
output.push_str(&keyword);
635+
output.push_str(&right_part);
636+
637+
// Add reference if needed
638+
if config.auto_ref || config.input_ref {
639+
if config.right_ref {
640+
output.push(' ');
641+
output.push_str(reference);
642+
} else {
643+
output = format!("{reference} {output}");
644+
}
645+
}
646+
647+
output
648+
}
649+
592650
fn format_roff_field(s: &str) -> String {
593651
s.replace('\"', "\"\"")
594652
}
@@ -716,9 +774,13 @@ fn write_traditional_output(
716774
&chars_lines[word_ref.local_line_nr],
717775
&reference,
718776
),
719-
OutFormat::Dumb => {
720-
return Err(PtxError::DumbFormat.into());
721-
}
777+
OutFormat::Dumb => format_dumb_line(
778+
config,
779+
word_ref,
780+
&lines[word_ref.local_line_nr],
781+
&chars_lines[word_ref.local_line_nr],
782+
&reference,
783+
),
722784
};
723785
writeln!(writer, "{output_line}")
724786
.map_err_context(|| translate!("ptx-error-write-failed"))?;

tests/by-util/test_ptx.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,11 @@ fn test_utf8() {
256256
.succeeds()
257257
.stdout_only("\\xx {}{it’s}{disabled}{}{}\n\\xx {}{}{it’s}{ disabled}{}\n");
258258
}
259+
260+
#[test]
261+
fn test_gnu_mode_dumb_format() {
262+
// Test GNU mode (dumb format) - the default mode without -G flag
263+
new_ucmd!().pipe_in("a b").succeeds().stdout_only(
264+
" a b\n a b\n",
265+
);
266+
}

0 commit comments

Comments
 (0)