mirror of https://github.com/djcb/mu.git
mu-view: add --format=html
Support showing the HTML body (if any) instead of the default plain-text body. Update manpage.
This commit is contained in:
parent
72f43f11df
commit
3337c9babb
4
NEWS.org
4
NEWS.org
|
@ -19,6 +19,10 @@
|
|||
- what used to be the ~mu fields~ command has been merged into ~mu info~; i.e.,
|
||||
~mu fields~ is now ~mu info fields~.
|
||||
|
||||
- ~mu view~ gained ~--format=html~ for it to output the HTML body of the message
|
||||
rather than the (default) plain-text body. See its updated manpage for
|
||||
details.
|
||||
|
||||
- experimental: if you build ~mu~ with [[https://github.com/CLD2Owners/cld2][CLD2]] support (available in many Linux
|
||||
distros), ~mu~ will try to detect the language of the body of e-mail
|
||||
messages; you can then search by their ISO-639-1 code, e.g. ~mu find
|
||||
|
|
|
@ -15,13 +15,21 @@ mu [common options] view [options] [<file> ...]
|
|||
message files and does =not= require the message to be indexed in the database.
|
||||
|
||||
The command shows some common headers (From:, To:, Cc:, Bcc:, Subject: and
|
||||
Date:), the list of attachments and the plain-text body of the message (if any).
|
||||
Date:), the list of attachments and either the plain-text or html body of the
|
||||
message (if any), or its s-expression representation.
|
||||
|
||||
If no message file is provided, the command expects the message on
|
||||
If no message file is provided, the command reads the message from
|
||||
standard-input.
|
||||
|
||||
* VIEW OPTIONS
|
||||
|
||||
** --format,-o = <format>
|
||||
use the given output format, one of:
|
||||
|
||||
- ~plain~ - use the plain-text body; this is the default
|
||||
- ~html~ - use the HTML body
|
||||
- ~sexp~ - show the S-expression representation of the message
|
||||
|
||||
** --summary-len=<number>
|
||||
instead of displaying the full message, output a summary based upon the first
|
||||
=<number>= lines of the message.
|
||||
|
|
|
@ -85,29 +85,42 @@ print_field(const std::string& field, const std::string& val, bool color)
|
|||
static void
|
||||
body_or_summary(const Message& message, const Options& opts)
|
||||
{
|
||||
gboolean color;
|
||||
const auto color{!opts.nocolor};
|
||||
using Format = Options::View::Format;
|
||||
|
||||
color = !opts.nocolor;
|
||||
std::string body, btype;
|
||||
switch (opts.view.format) {
|
||||
case Format::Plain:
|
||||
btype = "plain text";
|
||||
body = message.body_text().value_or("");
|
||||
break;
|
||||
case Format::Html:
|
||||
btype = "html";
|
||||
body = message.body_html().value_or("");
|
||||
break;
|
||||
default:
|
||||
throw std::range_error("unsupported format"); // bug
|
||||
}
|
||||
|
||||
const auto body{message.body_text()};
|
||||
if (!body || body->empty()) {
|
||||
if (body.empty()) {
|
||||
if (any_of(message.flags() & Flags::Encrypted)) {
|
||||
color_maybe(MU_COLOR_CYAN);
|
||||
mu_println("[No text body found; message has encrypted parts]");
|
||||
mu_println("[No {} body found; message does have encrypted parts]",
|
||||
btype);
|
||||
} else {
|
||||
color_maybe(MU_COLOR_MAGENTA);
|
||||
mu_println("[No text body found]");
|
||||
mu_println("[No {} body found]", btype);
|
||||
}
|
||||
color_maybe(MU_COLOR_DEFAULT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (opts.view.summary_len) {
|
||||
const auto summ{summarize(body->c_str(), *opts.view.summary_len)};
|
||||
const auto summ{summarize(body, *opts.view.summary_len)};
|
||||
print_field("Summary", summ, color);
|
||||
} else {
|
||||
mu_print_encoded("{}", *body);
|
||||
if (!g_str_has_suffix(body->c_str(), "\n"))
|
||||
mu_print_encoded("{}", body);
|
||||
if (!g_str_has_suffix(body.c_str(), "\n"))
|
||||
mu_println("");
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +144,8 @@ view_msg_plain(const Message& message, const Options& opts)
|
|||
print_field("Tags", join(message.tags(), ", "), color);
|
||||
|
||||
print_field("Attachments",get_attach_str(message, opts), color);
|
||||
|
||||
mu_println("");
|
||||
body_or_summary(message, opts);
|
||||
|
||||
return Ok();
|
||||
|
@ -143,7 +158,9 @@ handle_msg(const Message& message, const Options& opts)
|
|||
|
||||
switch (opts.view.format) {
|
||||
case Format::Plain:
|
||||
case Format::Html:
|
||||
return view_msg_plain(message, opts);
|
||||
|
||||
case Format::Sexp:
|
||||
return view_msg_sexp(message, opts);
|
||||
default:
|
||||
|
@ -173,7 +190,8 @@ Mu::mu_cmd_view(const Options& opts)
|
|||
const auto msgtxt = read_from_stdin();
|
||||
if (!msgtxt)
|
||||
return Err(msgtxt.error());
|
||||
auto message = Message::make_from_text(*msgtxt,{}, message_options(opts.view));
|
||||
auto message = Message::make_from_text(*msgtxt,{},
|
||||
message_options(opts.view));
|
||||
if (!message)
|
||||
return Err(message.error());
|
||||
else
|
||||
|
|
|
@ -497,10 +497,13 @@ static void
|
|||
sub_view(CLI::App& sub, Options& opts)
|
||||
{
|
||||
using Format = Options::View::Format;
|
||||
static constexpr InfoEnum<Format, 2> FormatInfos = {{
|
||||
static constexpr InfoEnum<Format, 3> FormatInfos = {{
|
||||
{ Format::Plain,
|
||||
{"plain", "Plain output"}
|
||||
},
|
||||
{ Format::Html,
|
||||
{"html", "Plain output with HTML body"}
|
||||
},
|
||||
{ Format::Sexp,
|
||||
{"sexp", "S-expressions"}
|
||||
},
|
||||
|
|
|
@ -237,7 +237,7 @@ struct Options {
|
|||
bool terminate; /**< add \f between msgs in view */
|
||||
OptSize summary_len; /**< max # of lines for summary */
|
||||
|
||||
enum struct Format { Plain, Sexp };
|
||||
enum struct Format { Plain, Sexp, Html };
|
||||
Format format; /**< output format*/
|
||||
|
||||
StringVec files; /**< Message file(s) */
|
||||
|
|
Loading…
Reference in New Issue