Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't enable kitty/iterm in export mode #101

Merged
merged 2 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions scripts/test-pdf-generation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@ trap 'rm -rf "${env_dir}"' EXIT
python -mvenv "${env_dir}/pyenv"
source "${env_dir}/pyenv/bin/activate"

echo "Installing presenterm-export==0.2.0"
echo "Installing presenterm-export==0.1.2"
pip install presenterm-export

echo "Running presenterm..."
rm -f "${root_dir}/examples/demo.pdf"
cargo run -q -- --export-pdf "${root_dir}/examples/demo.md"

if test -f "${root_dir}/examples/demo.pdf"; then
echo "PDF file has been created"
rm -f "${root_dir}/examples/demo.pdf"
if test -f "${root_dir}/examples/demo.pdf"
then
echo "PDF file has been created"
rm -f "${root_dir}/examples/demo.pdf"
else
echo "PDF file does not exist"
exit 1
echo "PDF file does not exist"
exit 1
fi

4 changes: 0 additions & 4 deletions src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,6 @@ impl<'a> Exporter<'a> {
let presenterm_path = presenterm_path.display().to_string();
let presentation_path = metadata.presentation_path.display().to_string();
let metadata = serde_json::to_vec(&metadata).expect("serialization failed");
// Remove the LC_TERMINAL environment variable as otherwise viuer will try to talk in
// iterm2 protocol to tmux and that breaks.
env::remove_var("LC_TERMINAL");

ThirdPartyTools::presenterm_export(&[&presenterm_path, "--export", &presentation_path])
.stdin(metadata)
.run()?;
Expand Down
7 changes: 6 additions & 1 deletion src/presenter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
render::{
draw::{RenderError, RenderResult, TerminalDrawer},
highlighting::CodeHighlighter,
media::GraphicsMode,
},
resource::Resources,
theme::PresentationTheme,
Expand Down Expand Up @@ -68,7 +69,11 @@ impl<'a> Presenter<'a> {
pub fn present(mut self, path: &Path) -> Result<(), PresentationError> {
self.state = PresenterState::Presenting(self.load_presentation(path)?);

let mut drawer = TerminalDrawer::new(io::stdout())?;
let graphics_mode = match self.mode {
PresentMode::Export => GraphicsMode::AsciiBlocks,
_ => GraphicsMode::default(),
};
let mut drawer = TerminalDrawer::new(io::stdout(), graphics_mode)?;
loop {
self.render(&mut drawer)?;
self.update_widgets(&mut drawer)?;
Expand Down
11 changes: 6 additions & 5 deletions src/render/draw.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{engine::RenderEngine, terminal::Terminal};
use super::{engine::RenderEngine, media::GraphicsMode, terminal::Terminal};
use crate::{
markdown::{
elements::StyledText,
Expand All @@ -17,23 +17,24 @@ pub(crate) type RenderResult = Result<(), RenderError>;
/// Allows drawing elements in the terminal.
pub(crate) struct TerminalDrawer<W: io::Write> {
terminal: Terminal<W>,
graphics_mode: GraphicsMode,
}

impl<W> TerminalDrawer<W>
where
W: io::Write,
{
/// Construct a drawer over a [std::io::Write].
pub(crate) fn new(handle: W) -> io::Result<Self> {
pub(crate) fn new(handle: W, graphics_mode: GraphicsMode) -> io::Result<Self> {
let terminal = Terminal::new(handle)?;
Ok(Self { terminal })
Ok(Self { terminal, graphics_mode })
}

/// Render a slide.
pub(crate) fn render_slide(&mut self, presentation: &Presentation) -> RenderResult {
let window_dimensions = WindowSize::current()?;
let slide = presentation.current_slide();
let engine = RenderEngine::new(&mut self.terminal, window_dimensions);
let engine = RenderEngine::new(&mut self.terminal, window_dimensions, self.graphics_mode.clone());
engine.render(slide.iter_operations())?;
self.terminal.flush()?;
Ok(())
Expand Down Expand Up @@ -64,7 +65,7 @@ where
let op = RenderOperation::RenderText { line: WeightedLine::from(error), alignment: alignment.clone() };
operations.extend([op, RenderOperation::RenderLineBreak]);
}
let engine = RenderEngine::new(&mut self.terminal, dimensions);
let engine = RenderEngine::new(&mut self.terminal, dimensions, self.graphics_mode.clone());
engine.render(operations.iter())?;
self.terminal.flush()?;
Ok(())
Expand Down
20 changes: 16 additions & 4 deletions src/render/engine.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{
draw::{RenderError, RenderResult},
layout::Layout,
media::{Image, MediaRender},
media::{GraphicsMode, Image, MediaRender},
properties::CursorPosition,
terminal::Terminal,
text::TextDrawer,
Expand All @@ -24,17 +24,29 @@ where
colors: Colors,
max_modified_row: u16,
layout: LayoutState,
graphics_mode: GraphicsMode,
}

impl<'a, W> RenderEngine<'a, W>
where
W: io::Write,
{
pub(crate) fn new(terminal: &'a mut Terminal<W>, window_dimensions: WindowSize) -> Self {
pub(crate) fn new(
terminal: &'a mut Terminal<W>,
window_dimensions: WindowSize,
graphics_mode: GraphicsMode,
) -> Self {
let max_modified_row = terminal.cursor_row;
let current_rect = WindowRect { dimensions: window_dimensions, start_column: 0 };
let window_rects = vec![current_rect.clone()];
Self { terminal, window_rects, colors: Default::default(), max_modified_row, layout: Default::default() }
Self {
terminal,
window_rects,
colors: Default::default(),
max_modified_row,
layout: Default::default(),
graphics_mode,
}
}

pub(crate) fn render<'b>(mut self, operations: impl Iterator<Item = &'b RenderOperation>) -> RenderResult {
Expand Down Expand Up @@ -134,7 +146,7 @@ where

fn render_image(&mut self, image: &Image) -> RenderResult {
let position = CursorPosition { row: self.terminal.cursor_row, column: self.current_rect().start_column };
let (_, height) = MediaRender::default()
let (_, height) = MediaRender::new(self.graphics_mode.clone())
.draw_image(image, position, self.current_dimensions())
.map_err(|e| RenderError::Other(Box::new(e)))?;
let row = self.terminal.cursor_row + height as u16;
Expand Down
49 changes: 36 additions & 13 deletions src/render/media.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::render::properties::WindowSize;
use image::{DynamicImage, ImageError};
use std::{fmt::Debug, io, ops::Deref, path::PathBuf, rc::Rc};
use viuer::{is_iterm_supported, ViuError};
use viuer::{get_kitty_support, is_iterm_supported, KittySupport, ViuError};

use super::properties::CursorPosition;

Expand Down Expand Up @@ -50,10 +50,15 @@ pub(crate) enum ImageSource {

/// A media render.
pub struct MediaRender {
mode: TerminalMode,
mode: GraphicsMode,
}

impl MediaRender {
/// Construct a new media render.
pub fn new(mode: GraphicsMode) -> Self {
Self { mode }
}

/// Draw an image.
///
/// This will use the current terminal size and try to render the image where the cursor is
Expand Down Expand Up @@ -101,16 +106,19 @@ impl MediaRender {
width: Some(width_in_columns),
x: start_column,
y: position.row as i16,
use_iterm: false,
use_kitty: false,
..Default::default()
};
let config = self.mode.apply(config);
// If we're using the iterm2 protocol, print this from the file as that makes images print
// faster _and_ it causes gifs to be animated.
//
// This switch is because otherwise `viuer::print_from_file` for kitty/ascii blocks will
// re-read the image every time.
let dimensions = match (&self.mode, source) {
(TerminalMode::Iterm2, ImageSource::Filesystem(image_path)) => viuer::print_from_file(image_path, &config)?,
(TerminalMode::Other, _) | (_, ImageSource::Generated) => viuer::print(image, &config)?,
(GraphicsMode::Iterm2, ImageSource::Filesystem(image_path)) => viuer::print_from_file(image_path, &config)?,
_ => viuer::print(image, &config)?,
};
Ok(dimensions)
}
Expand All @@ -124,19 +132,34 @@ impl MediaRender {
}
}

impl Default for MediaRender {
#[derive(Clone, Debug)]
pub enum GraphicsMode {
Iterm2,
Kitty,
AsciiBlocks,
}

impl Default for GraphicsMode {
fn default() -> Self {
let mode = match is_iterm_supported() {
true => TerminalMode::Iterm2,
false => TerminalMode::Other,
};
Self { mode }
if is_iterm_supported() {
Self::Iterm2
} else if get_kitty_support() != KittySupport::None {
Self::Kitty
} else {
Self::Iterm2
}
}
}

enum TerminalMode {
Iterm2,
Other,
impl GraphicsMode {
fn apply(&self, mut config: viuer::Config) -> viuer::Config {
match self {
Self::Iterm2 => config.use_iterm = true,
Self::Kitty => config.use_kitty = true,
Self::AsciiBlocks => (),
};
config
}
}

/// An invalid image.
Expand Down
Loading