Merge pull request #1442 from matthiasbeyer/imag-view/markdown-compile

imag-view: markdown compile
This commit is contained in:
Matthias Beyer 2018-04-24 19:48:38 +02:00 committed by GitHub
commit 16747aa257
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 154 additions and 42 deletions

View file

@ -31,9 +31,12 @@ tempfile = "2.1"
libimagstore = { version = "0.8.0", path = "../../../lib/core/libimagstore" } libimagstore = { version = "0.8.0", path = "../../../lib/core/libimagstore" }
libimagrt = { version = "0.8.0", path = "../../../lib/core/libimagrt" } libimagrt = { version = "0.8.0", path = "../../../lib/core/libimagrt" }
libimagerror = { version = "0.8.0", path = "../../../lib/core/libimagerror" } libimagerror = { version = "0.8.0", path = "../../../lib/core/libimagerror" }
libimagentryview = { version = "0.8.0", path = "../../../lib/entry/libimagentryview" }
libimagutil = { version = "0.8.0", path = "../../../lib/etc/libimagutil" } libimagutil = { version = "0.8.0", path = "../../../lib/etc/libimagutil" }
[dependencies.libimagentryview]
version = "0.8.0"
path = "../../../lib/entry/libimagentryview"
[dependencies.clap] [dependencies.clap]
version = "^2.29" version = "^2.29"
default-features = false default-features = false

View file

@ -62,6 +62,7 @@ use libimagerror::str::ErrFromStr;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator; use libimagerror::iter::TraceIterator;
use libimagentryview::builtin::stdout::StdoutViewer; use libimagentryview::builtin::stdout::StdoutViewer;
use libimagentryview::builtin::md::MarkdownViewer;
use libimagentryview::viewer::Viewer; use libimagentryview::viewer::Viewer;
use libimagentryview::error::ViewError as VE; use libimagentryview::error::ViewError as VE;
use libimagstore::storeid::IntoStoreId; use libimagstore::storeid::IntoStoreId;
@ -171,24 +172,7 @@ fn main() {
drop(files); drop(files);
} else { } else {
let mut viewer = StdoutViewer::new(view_header, !hide_content); let iter = entry_ids
if rt.cli().occurrences_of("autowrap") != 0 {
let width = rt.cli().value_of("autowrap").unwrap(); // ensured by clap
let width = usize::from_str(width).unwrap_or_else(|e| {
error!("Failed to parse argument to number: autowrap = {:?}",
rt.cli().value_of("autowrap").map(String::from));
error!("-> {:?}", e);
::std::process::exit(1)
});
viewer.wrap_at(width);
}
let output = rt.stdout();
let mut lockout = output.lock();
entry_ids
.into_iter() .into_iter()
.into_get_iter(rt.store()) .into_get_iter(rt.store())
.map(|e| { .map(|e| {
@ -196,10 +180,35 @@ fn main() {
.ok_or_else(|| String::from("Entry not found")) .ok_or_else(|| String::from("Entry not found"))
.map_err(StoreError::from) .map_err(StoreError::from)
.map_err_trace_exit_unwrap(1) .map_err_trace_exit_unwrap(1)
})
.for_each(|e| {
viewer.view_entry(&e, &mut lockout).map_err_trace_exit_unwrap(1);
}); });
let out = rt.stdout();
let mut outlock = out.lock();
if rt.cli().is_present("compile-md") {
let viewer = MarkdownViewer::new(&rt);
for entry in iter {
viewer.view_entry(&entry, &mut outlock).map_err_trace_exit_unwrap(1);
}
} else {
let mut viewer = StdoutViewer::new(view_header, !hide_content);
if rt.cli().occurrences_of("autowrap") != 0 {
let width = rt.cli().value_of("autowrap").unwrap(); // ensured by clap
let width = usize::from_str(width).unwrap_or_else(|e| {
error!("Failed to parse argument to number: autowrap = {:?}",
rt.cli().value_of("autowrap").map(String::from));
error!("-> {:?}", e);
::std::process::exit(1)
});
viewer.wrap_at(width);
}
for entry in iter {
viewer.view_entry(&entry, &mut outlock).map_err_trace_exit_unwrap(1);
}
}
} }
} }

View file

@ -17,7 +17,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// //
use clap::{Arg, ArgGroup, App, SubCommand}; use clap::{Arg, ArgGroup, App};
pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
app app
@ -64,6 +64,15 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
.required(false) .required(false)
.help("Do not view content")) .help("Do not view content"))
.arg(Arg::with_name("compile-md")
.long("compile")
.short("c")
.takes_value(false)
.required(false)
.help("Do compile markdown to be nice")
.conflicts_with("not-view-content")
.conflicts_with("autowrap")) // markdown viewer does not support wrapping
.arg(Arg::with_name("in") .arg(Arg::with_name("in")
.long("in") .long("in")
.takes_value(true) .takes_value(true)
@ -71,23 +80,4 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
.multiple(false) .multiple(false)
.help("View content. If no value is given, this fails. Possible viewers are configured via the config file.")) .help("View content. If no value is given, this fails. Possible viewers are configured via the config file."))
.subcommand(SubCommand::with_name("compile")
.about("Compile content to other format for viewing, implies that the entry gets copied to /tmp")
.version("0.1")
.arg(Arg::with_name("from")
.long("from")
.short("f")
.takes_value(true) // "markdown" or "textile" or "restructuredtex"
.required(true)
.help("Compile from")
.value_name("FORMAT"))
.arg(Arg::with_name("to")
.long("to")
.short("t")
.takes_value(true) // "html" or "HTML" or ... json maybe?
.required(true)
.help("Compile to")
.value_name("FORMAT"))
)
} }

View file

@ -29,3 +29,23 @@ libimagrt = { version = "0.8.0", path = "../../../lib/core/libimagrt" }
libimagstore = { version = "0.8.0", path = "../../../lib/core/libimagstore" } libimagstore = { version = "0.8.0", path = "../../../lib/core/libimagstore" }
libimagerror = { version = "0.8.0", path = "../../../lib/core/libimagerror" } libimagerror = { version = "0.8.0", path = "../../../lib/core/libimagerror" }
libimagentryedit = { version = "0.8.0", path = "../../../lib/entry/libimagentryedit" } libimagentryedit = { version = "0.8.0", path = "../../../lib/entry/libimagentryedit" }
mdcat = { version = "0.8", optional = true }
failure = { version = "0.1", optional = true }
[dependencies.pulldown-cmark]
version = "^0.1"
optional = true
default-features = false
features = []
[dependencies.syntect]
version = "^2"
optional = true
default-features = false
features = ["parsing", "assets", "dump-load"]
[features]
default = [ "markdownviewer" ]
markdownviewer = ["mdcat", "failure", "pulldown-cmark", "syntect"]

View file

@ -0,0 +1,73 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2018 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
use std::io::Write;
use libimagstore::store::Entry;
use libimagrt::runtime::Runtime;
use mdcat::{ResourceAccess, Terminal, TerminalSize};
use pulldown_cmark::Parser;
use syntect::parsing::SyntaxSet;
use mdcat;
use viewer::Viewer;
use error::Result;
pub struct MarkdownViewer<'a> {
rt: &'a Runtime<'a>,
resource_access: ResourceAccess,
terminal: Terminal,
termsize: TerminalSize,
}
impl<'a> MarkdownViewer<'a> {
pub fn new(rt: &'a Runtime) -> Self {
MarkdownViewer {
rt,
resource_access: ResourceAccess::LocalOnly,
terminal: Terminal::detect(),
termsize: TerminalSize::detect().unwrap_or(TerminalSize {
width: 80,
height: 20,
}),
}
}
}
impl<'a> Viewer for MarkdownViewer<'a> {
fn view_entry<W>(&self, e: &Entry, sink: &mut W) -> Result<()>
where W: Write
{
let parser = Parser::new(e.get_content());
let base_dir = self.rt.rtp();
let syntax_set = SyntaxSet::load_defaults_newlines();
mdcat::push_tty(sink,
self.terminal.clone(),
self.termsize.clone(),
parser,
base_dir,
self.resource_access.clone(),
syntax_set)
.map_err(|e| e.compat())
.map_err(::error::ViewError::from)
}
}

View file

@ -20,3 +20,7 @@
pub mod editor; pub mod editor;
pub mod plain; pub mod plain;
pub mod stdout; pub mod stdout;
#[cfg(feature = "markdownviewer")]
pub mod md;

View file

@ -23,6 +23,7 @@ error_chain! {
} }
foreign_links { foreign_links {
Failure(::failure::Compat<::failure::Error>) #[cfg(feature = "markdownviewer")];
IO(::std::io::Error); IO(::std::io::Error);
} }

View file

@ -39,6 +39,18 @@ extern crate toml;
#[macro_use] extern crate error_chain; #[macro_use] extern crate error_chain;
extern crate textwrap; extern crate textwrap;
#[cfg(feature = "markdownviewer")]
extern crate mdcat;
#[cfg(feature = "markdownviewer")]
extern crate failure;
#[cfg(feature = "markdownviewer")]
extern crate pulldown_cmark;
#[cfg(feature = "markdownviewer")]
extern crate syntect;
extern crate libimagstore; extern crate libimagstore;
extern crate libimagrt; extern crate libimagrt;
extern crate libimagerror; extern crate libimagerror;