mirror of
https://github.com/tealdeer-rs/tealdeer.git
synced 2026-08-09 09:49:10 +02:00
97 lines
2.8 KiB
Rust
97 lines
2.8 KiB
Rust
//! Functions for printing pages to the terminal
|
|
|
|
use std::io::{self, BufRead, BufReader, Read, Write};
|
|
|
|
use anyhow::{Context, Result};
|
|
use yansi::Paint;
|
|
|
|
use crate::{
|
|
config::{Config, StyleConfig},
|
|
formatter::{highlight_lines, PageSnippet},
|
|
line_iterator::LineIterator,
|
|
};
|
|
|
|
/// Set up display pager
|
|
///
|
|
/// SAFETY: this function may be called multiple times
|
|
#[cfg(not(target_os = "windows"))]
|
|
fn configure_pager(_: bool) {
|
|
use std::sync::Once;
|
|
static INIT: Once = Once::new();
|
|
INIT.call_once(|| pager::Pager::with_default_pager("less -R").setup());
|
|
}
|
|
|
|
#[cfg(target_os = "windows")]
|
|
fn configure_pager(enable_styles: bool) {
|
|
use crate::utils::print_warning;
|
|
print_warning(enable_styles, "--pager flag not available on Windows!");
|
|
}
|
|
|
|
/// Print page by path
|
|
pub fn print_page(
|
|
reader: impl Read,
|
|
enable_markdown: bool,
|
|
enable_styles: bool,
|
|
use_pager: bool,
|
|
config: &Config,
|
|
) -> Result<()> {
|
|
let reader = BufReader::new(reader);
|
|
|
|
// Configure pager if applicable
|
|
if use_pager || config.display.use_pager {
|
|
configure_pager(enable_styles);
|
|
}
|
|
|
|
// Lock stdout only once, this improves performance considerably
|
|
let stdout = io::stdout();
|
|
let mut handle = stdout.lock();
|
|
|
|
if enable_markdown {
|
|
// Print the raw markdown of the file.
|
|
for line in reader.lines() {
|
|
let line = line.context("Error while reading from a page")?;
|
|
writeln!(handle, "{line}").context("Could not write to stdout")?;
|
|
}
|
|
} else {
|
|
// Closure that processes a page snippet and writes it to stdout
|
|
let mut process_snippet = |snip: PageSnippet<&str>| {
|
|
if snip.is_empty() {
|
|
Ok(())
|
|
} else {
|
|
print_snippet(&mut handle, snip, &config.style).context("Failed to print snippet")
|
|
}
|
|
};
|
|
|
|
// Print highlighted lines
|
|
highlight_lines(
|
|
LineIterator::new(reader),
|
|
&mut process_snippet,
|
|
!config.display.compact,
|
|
config.display.show_title,
|
|
config.display.indent,
|
|
)
|
|
.context("Could not write to stdout")?;
|
|
}
|
|
|
|
// We're done outputting data, flush stdout now!
|
|
handle.flush().context("Could not flush stdout")?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn print_snippet(
|
|
writer: &mut impl Write,
|
|
snip: PageSnippet<&str>,
|
|
style: &StyleConfig,
|
|
) -> io::Result<()> {
|
|
use PageSnippet::*;
|
|
|
|
match snip {
|
|
CommandName(s) | Title(s) => write!(writer, "{}", s.paint(style.command_name)),
|
|
Variable(s) => write!(writer, "{}", s.paint(style.example_variable)),
|
|
NormalCode(s) => write!(writer, "{}", s.paint(style.example_code)),
|
|
Description(s) => write!(writer, "{}", s.paint(style.description)),
|
|
Text(s) => write!(writer, "{}", s.paint(style.example_text)),
|
|
Linebreak => writeln!(writer),
|
|
}
|
|
}
|