mirror of
https://github.com/tstack/lnav.git
synced 2024-09-11 13:05:51 +03:00
[markdown] add border-left/border-right support
This commit is contained in:
parent
4b9f81a65a
commit
80bf31b338
9
NEWS.md
9
NEWS.md
@ -46,9 +46,12 @@ Features:
|
||||
the directory where cached data is stored, respectively.
|
||||
* The `<pre>` tag is now recognized in Markdown files.
|
||||
* The `style` attribute in `<span>` tags is now supported.
|
||||
Basic properties like `color`, `background-color`,
|
||||
`font-weight`, and `text-decoration` can be used. CSS
|
||||
color names should work as well.
|
||||
The following CSS properties and values are supported:
|
||||
* `color` and `background-color` with CSS color names
|
||||
* `font-weight` with a value of `bold` or `bolder`
|
||||
* `text-decoration` with `underline`
|
||||
* `border-left` and `border-right` with the `solid`,
|
||||
`dashed` and `dotted` line styles and colors.
|
||||
|
||||
Bug Fixes:
|
||||
* Binary data piped into stdin should now be treated the same
|
||||
|
@ -368,7 +368,7 @@ private:
|
||||
|
||||
nonstd::optional<auto_fd> lb_cached_fd;
|
||||
|
||||
file_header_t lb_header;
|
||||
file_header_t lb_header{mapbox::util::no_init{}};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -134,25 +134,27 @@ logfile::open(std::string filename, const logfile_open_options& loo, auto_fd fd)
|
||||
lf->lf_indexing = lf->lf_options.loo_is_visible;
|
||||
|
||||
const auto& hdr = lf->lf_line_buffer.get_header_data();
|
||||
log_info("%s: has header %d", lf->lf_filename.c_str(), hdr.valid());
|
||||
hdr.match(
|
||||
[&lf](const lnav::gzip::header& gzhdr) {
|
||||
if (!gzhdr.empty()) {
|
||||
lf->lf_embedded_metadata["net.zlib.gzip.header"] = {
|
||||
if (hdr.valid()) {
|
||||
log_info("%s: has header %d", lf->lf_filename.c_str(), hdr.valid());
|
||||
hdr.match(
|
||||
[&lf](const lnav::gzip::header& gzhdr) {
|
||||
if (!gzhdr.empty()) {
|
||||
lf->lf_embedded_metadata["net.zlib.gzip.header"] = {
|
||||
text_format_t::TF_JSON,
|
||||
file_header_handlers.to_string(gzhdr),
|
||||
};
|
||||
}
|
||||
},
|
||||
[&lf](const lnav::piper::header& phdr) {
|
||||
lf->lf_embedded_metadata["org.lnav.piper.header"] = {
|
||||
text_format_t::TF_JSON,
|
||||
file_header_handlers.to_string(gzhdr),
|
||||
lnav::piper::header_handlers.to_string(phdr),
|
||||
};
|
||||
}
|
||||
},
|
||||
[&lf](const lnav::piper::header& phdr) {
|
||||
lf->lf_embedded_metadata["org.lnav.piper.header"] = {
|
||||
text_format_t::TF_JSON,
|
||||
lnav::piper::header_handlers.to_string(phdr),
|
||||
};
|
||||
log_debug("setting file name: %s", phdr.h_name.c_str());
|
||||
lf->set_filename(phdr.h_name);
|
||||
lf->lf_valid_filename = false;
|
||||
});
|
||||
log_debug("setting file name: %s", phdr.h_name.c_str());
|
||||
lf->set_filename(phdr.h_name);
|
||||
lf->lf_valid_filename = false;
|
||||
});
|
||||
}
|
||||
|
||||
ensure(lf->invariant());
|
||||
|
||||
|
@ -488,6 +488,94 @@ md2attr_line::leave_span(const md4cpp::event_handler::span& sp)
|
||||
return Ok();
|
||||
}
|
||||
|
||||
enum class border_side {
|
||||
left,
|
||||
right,
|
||||
};
|
||||
|
||||
enum class border_line_width {
|
||||
thin,
|
||||
medium,
|
||||
thick,
|
||||
};
|
||||
|
||||
static const char*
|
||||
left_border_string(border_line_width width)
|
||||
{
|
||||
switch (width) {
|
||||
case border_line_width::thin:
|
||||
return "\u258F";
|
||||
case border_line_width::medium:
|
||||
return "\u258E";
|
||||
case border_line_width::thick:
|
||||
return "\u258C";
|
||||
}
|
||||
}
|
||||
|
||||
static const char*
|
||||
right_border_string(border_line_width width)
|
||||
{
|
||||
switch (width) {
|
||||
case border_line_width::thin:
|
||||
return "\u2595";
|
||||
case border_line_width::medium:
|
||||
return "\u2595";
|
||||
case border_line_width::thick:
|
||||
return "\u2590";
|
||||
}
|
||||
}
|
||||
|
||||
static attr_line_t
|
||||
span_style_border(border_side side, const string_fragment& value)
|
||||
{
|
||||
static const auto NAME_THIN = string_fragment::from_const("thin");
|
||||
static const auto NAME_MEDIUM = string_fragment::from_const("medium");
|
||||
static const auto NAME_THICK = string_fragment::from_const("thick");
|
||||
static const auto NAME_SOLID = string_fragment::from_const("solid");
|
||||
static const auto NAME_DASHED = string_fragment::from_const("dashed");
|
||||
static const auto NAME_DOTTED = string_fragment::from_const("dotted");
|
||||
static const auto& vc = view_colors::singleton();
|
||||
|
||||
text_attrs border_attrs;
|
||||
auto border_sf = value;
|
||||
auto width = border_line_width::thick;
|
||||
auto ch = side == border_side::left ? left_border_string(width)
|
||||
: right_border_string(width);
|
||||
|
||||
while (!border_sf.empty()) {
|
||||
auto border_split_res
|
||||
= border_sf.split_when(string_fragment::tag1{' '});
|
||||
auto bval = border_split_res.first;
|
||||
|
||||
if (bval == NAME_THIN) {
|
||||
width = border_line_width::thin;
|
||||
} else if (bval == NAME_MEDIUM) {
|
||||
width = border_line_width::medium;
|
||||
} else if (bval == NAME_THICK) {
|
||||
width = border_line_width::thick;
|
||||
} else if (bval == NAME_DOTTED) {
|
||||
ch = "\u250A";
|
||||
} else if (bval == NAME_DASHED) {
|
||||
ch = "\u254F";
|
||||
} else if (bval == NAME_SOLID) {
|
||||
ch = side == border_side::left ? left_border_string(width)
|
||||
: right_border_string(width);
|
||||
} else {
|
||||
auto color_res = styling::color_unit::from_str(bval);
|
||||
if (color_res.isErr()) {
|
||||
log_error("invalid border color: %.*s -- %s",
|
||||
bval.length(),
|
||||
bval.data(),
|
||||
color_res.unwrapErr().c_str());
|
||||
} else {
|
||||
border_attrs.ta_fg_color = vc.match_color(color_res.unwrap());
|
||||
}
|
||||
}
|
||||
border_sf = border_split_res.second;
|
||||
}
|
||||
return attr_line_t(ch).with_attr_for_all(VC_STYLE.value(border_attrs));
|
||||
}
|
||||
|
||||
static attr_line_t
|
||||
to_attr_line(const pugi::xml_node& doc)
|
||||
{
|
||||
@ -499,6 +587,10 @@ to_attr_line(const pugi::xml_node& doc)
|
||||
= string_fragment::from_const("font-weight");
|
||||
static const auto NAME_TEXT_DECO
|
||||
= string_fragment::from_const("text-decoration");
|
||||
static const auto NAME_BORDER_LEFT
|
||||
= string_fragment::from_const("border-left");
|
||||
static const auto NAME_BORDER_RIGHT
|
||||
= string_fragment::from_const("border-right");
|
||||
static const auto& vc = view_colors::singleton();
|
||||
|
||||
attr_line_t retval;
|
||||
@ -507,6 +599,8 @@ to_attr_line(const pugi::xml_node& doc)
|
||||
}
|
||||
for (const auto& child : doc.children()) {
|
||||
if (child.name() == NAME_SPAN) {
|
||||
nonstd::optional<attr_line_t> left_border;
|
||||
nonstd::optional<attr_line_t> right_border;
|
||||
auto styled_span = attr_line_t(child.text().get());
|
||||
|
||||
auto span_class = child.attribute("class");
|
||||
@ -578,6 +672,12 @@ to_attr_line(const pugi::xml_node& doc)
|
||||
|
||||
deco_sf = deco_split_res.second;
|
||||
}
|
||||
} else if (key == NAME_BORDER_LEFT) {
|
||||
left_border
|
||||
= span_style_border(border_side::left, value);
|
||||
} else if (key == NAME_BORDER_RIGHT) {
|
||||
right_border
|
||||
= span_style_border(border_side::right, value);
|
||||
}
|
||||
}
|
||||
style_sf = split_res.second;
|
||||
@ -586,7 +686,13 @@ to_attr_line(const pugi::xml_node& doc)
|
||||
styled_span.with_attr_for_all(VC_STYLE.value(ta));
|
||||
}
|
||||
}
|
||||
if (left_border) {
|
||||
retval.append(left_border.value());
|
||||
}
|
||||
retval.append(styled_span);
|
||||
if (right_border) {
|
||||
retval.append(right_border.value());
|
||||
}
|
||||
} else if (child.name() == NAME_PRE) {
|
||||
auto pre_al = attr_line_t();
|
||||
|
||||
@ -643,7 +749,8 @@ md2attr_line::text(MD_TEXTTYPE tt, const string_fragment& sf)
|
||||
std::string ct_name;
|
||||
};
|
||||
|
||||
mapbox::util::variant<open_tag, close_tag> tag;
|
||||
mapbox::util::variant<open_tag, close_tag> tag{
|
||||
mapbox::util::no_init{}};
|
||||
|
||||
if (sf.startswith("</")) {
|
||||
tag = close_tag{
|
||||
|
@ -11,3 +11,6 @@
|
||||
|
||||
Hello,
|
||||
World!
|
||||
|
||||
|
||||
Goodbye, [36m▌[0mWorld[32m╏[0m!
|
||||
|
@ -16,3 +16,5 @@
|
||||
Hello,
|
||||
<span class="name">World</span>!
|
||||
</pre>
|
||||
|
||||
Goodbye, <span style="border-left: solid cyan; border-right: dashed green">World</span>!
|
||||
|
Loading…
Reference in New Issue
Block a user