diff --git a/NEWS.org b/NEWS.org index c8af9b24..2a29aa2c 100644 --- a/NEWS.org +++ b/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 diff --git a/man/mu-view.1.org b/man/mu-view.1.org index db066465..aabfa661 100644 --- a/man/mu-view.1.org +++ b/man/mu-view.1.org @@ -15,13 +15,21 @@ mu [common options] view [options] [ ...] 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 = +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= instead of displaying the full message, output a summary based upon the first == lines of the message. diff --git a/mu/mu-cmd-view.cc b/mu/mu-cmd-view.cc index e2a2d704..8d646dfb 100644 --- a/mu/mu-cmd-view.cc +++ b/mu/mu-cmd-view.cc @@ -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 diff --git a/mu/mu-options.cc b/mu/mu-options.cc index 0f79b096..ada68ada 100644 --- a/mu/mu-options.cc +++ b/mu/mu-options.cc @@ -497,10 +497,13 @@ static void sub_view(CLI::App& sub, Options& opts) { using Format = Options::View::Format; - static constexpr InfoEnum FormatInfos = {{ + static constexpr InfoEnum FormatInfos = {{ { Format::Plain, {"plain", "Plain output"} }, + { Format::Html, + {"html", "Plain output with HTML body"} + }, { Format::Sexp, {"sexp", "S-expressions"} }, diff --git a/mu/mu-options.hh b/mu/mu-options.hh index 73868722..ca540994 100644 --- a/mu/mu-options.hh +++ b/mu/mu-options.hh @@ -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) */