Giter Site home page Giter Site logo

canop / termimad Goto Github PK

View Code? Open in Web Editor NEW
843.0 10.0 31.0 1.23 MB

A library to display rich (Markdown) snippets and texts in a rust terminal application

License: MIT License

Rust 99.94% Shell 0.06%
markdown rust parser renderer terminal hacktoberfest

termimad's Introduction

MIT Latest Version docs Chat on Miaou

A CLI utilities library leveraging Markdown to format terminal rendering, allowing separation of structure, data and skin.

Based on crossterm so works on most terminals (even on windows).

text

The goal isn't to display any markdown text with its various extensions (a terminal isn't really fit for that). The goal is rather to improve the display of texts in a terminal application when we want both the text and the skin to be easily configured.

Termimad also includes a few utilities helping efficient managing of events and user input in a multithread application.

Wrapping, table balancing, and scrolling are essential features of Termimad.

A text or a table can be displayed in an a priori unknown part of the screen, scrollable if desired, with a dynamically discovered width.

For example this markdown:

|:-:|:-:|-
|**feature**|**supported**|**details**|
|-:|:-:|-
| tables | yes | pipe based, with or without alignments
| italic, bold | yes | star based |
| inline code | yes | `with backquotes` (it works in tables too)
| code bloc | yes |with tabs or code fences
| syntax coloring | no |
| crossed text |  ~~not yet~~ | wait... now it works `~~like this~~`
| horizontal rule | yes | Use 3 or more dashes (`---`)
| lists | yes|* unordered lists supported
|  | |* ordered lists *not* supported
| quotes |  yes |> What a wonderful time to be alive!
| links | no | (but your terminal already handles raw URLs)
|-

will give different results depending on the width:

table

table

table

Usage

[dependencies]
termimad = "0.20"

With the default skin:

termimad::print_inline("**some** *nested **style*** and `some(code)`");

or

print!("{}", termimad::inline("**some** *nested **style*** and `some(code)`"));

Result:

simple example

Inline snippets with a custom skin:

Inline snippets are one line or less.

let mut skin = MadSkin::default();
skin.bold.set_fg(Yellow);
skin.print_inline("*Hey* **World!** Here's `some(code)`");
skin.paragraph.set_fgbg(Magenta, rgb(30, 30, 40));
skin.italic.add_attr(Underlined);
println!("\nand now {}\n", skin.inline("a little *too much* **style!** (and `some(code)` too)"));

Result:

too much style

Texts

Texts can be several lines. Tables and code blocks are automatically aligned, justified and consistently wrapped.

skin.print_text("# title\n* a list item\n* another item");

Scrollable TextView in a raw terminal:

scrollable

The code for this example is in examples/scrollable. To read the whole text just do

cargo run --example scrollable

Templates

In order to separate the rendering format from the content, you may want to have some constant markdown and fill some placeholders with dynamic items.

The format! macro is not always a good solution for that because you may not be sure the content is free of characters which may mess the markdown.

A solution is to use one of the templating functions or macros.

A template is to markdown what a prepared statement is to SQL: interpreted once and preventing the content to be interpreted as parts of the structure.

Inline Templates

Example:

mad_print_inline!(
    &skin,
    "**$0 formula:** *$1*", // the markdown template, interpreted once
    "Disk",  // fills $0
    "2*π*r", // fills $1. Note that the stars don't mess the markdown
);

mad_print_inline

Main difference with using skin.print_inline(format!( ... )) to build some markdown and parse it:

  • the markdown parsing and template building are done only once (using once_cell internally)
  • the given values aren't interpreted as markdown fragments and don't impact the style
  • arguments can be omited, repeated, given in any order
  • no support for fmt parameters or arguments other than &str (in the current version)

Inline templates are especially convenient combined with automated expansion or ellipsis, for filling a field in a terminal application.

You'll find more examples and advice in the inline-template example.

Text Template

When you want to fill a multi-line area, for example the help page of your terminal application, you may use a text template.

A template defines placeholders as ${name} which you may fill when using it.

For example

let text_template = TextTemplate::from(r#"
    # ${app-name} v${app-version}
    It is *very* ${adj}.
    "#);
let mut expander = text_template.expander();
expander
    .set("app-name", "MyApp")
    .set("adj", "pretty")
    .set("app-version", "42.5.3");
skin.print_expander(expander);

This would render like this:

text_template_01

The values you set with set aren't parsed as markdown, so they may freely contain stars or backquotes.

A template is reusable and can be defined from a text content or any string.

By using sub-templates, you may handle repetitions. They're handy for lists or tables.

For example

let text_template = TextTemplate::from(r#"
    |:-:|:-:|:-:|
    |**name**|**path**|**description**|
    |-:|:-:|:-|
    ${module-rows
    |**${module-name}**|`${app-version}/${module-key}`|${module-description}|
    }
    |-|-|-|
    "#);
let mut expander = text_template.expander();
expander
    .set("app-version", "2");
expander.sub("module-rows")
    .set("module-name", "lazy-regex")
    .set("module-key", "lrex")
    .set("module-description", "eases regexes");
expander.sub("module-rows")
    .set("module-name", "termimad")
    .set("module-key", "tmd")
    .set_md("module-description", "do things on *terminal*");
skin.print_expander(expander);

to get

text_template_02

On this example, you can note that

  • sub("module-rows") gets an expander for the sub template called module-rows
  • set_md can be used when you want to insert not just a raw uninterpreted string but some inline markdown.
  • you don't need to fill global placeholders again (here ${app-version}).

If you want to insert a block of code, you may use set_lines which applies the line style to all passed lines.

For example

let text_template = TextTemplate::from(r#"
    ## Example of a code block
        ${some-function}
    "#);
let mut expander = text_template.expander();
expander.set_lines("some-function", r#"
    fun test(a rational) {
    irate(a)
    }
    "#);
skin.print_expander(expander);

to get

text_template_03

You'll find more text template functions in the documentation and in the example (run cargo run --example text-template).

You may also be interested in OwningTemplateExpander: an alternative expander owning the values which may be handy when you build them while iterating in sub templates.

Asking questions

A frequent need in CLI apps is to ask the user to select an answer. The Question API and the ask! macros cover most basic needs.

Here's an example of asking with a default choice (that you get by hitting enter) and a returned value:

let choice = ask!(skin, "Do you want to drink something ?", ('n') {
    ('w', "I'd like some **w**ater, please.") => {
        mad_print_inline!(skin, "*Wait a minute, please, I'll fetch some.*\n");
        Some("water")
    }
    ('b', "Could I get a **b**eer glass ?") => {
        mad_print_inline!(skin, "We have no glass, so here's a *bottle*.\n");
        Some("beer")
    }
    ('n', "*No*, thank you.") => {
        None
    }
});
dbg!(choice);

ask example

Skin Files

A MadSkin can be deserialized using serde.

For example, such a skin in Hjson could be

bold: "#fb0 bold"
italic: dim italic
strikeout: crossedout red
bullet: ○ yellow bold
paragraph: gray(20)
code_block: gray(2) gray(15) center
headers: [
    yellow bold center
    yellow underlined
    yellow
]
quote: > red
horizontal-rule: "~ #00cafe"
table: "#540 center"
scrollbar: "#fb0 gray(11) |"

Execute cargo run --example skin-file for an example and explanations.

Advices to get started

  • Start by reading the examples (in /examples): they cover almost the whole API, including templates, how to use an alternate screen or scroll the page, etc. Many examples print a bunch of relevant documentation.
  • The render-input-markdown example lets you type some markdown in a text area and see it rendered below
  • Be careful that some colors aren't displayable on all terminals. The default color set of your application should not include arbitrary RGB colors.
  • The event / event-source part of Termimad is currently tailored for a short number of applications. If you use it or want to use it, please come and tell me so that your needs are taken into account!
  • If your goal is to format some CLI application output, for example a few tables, have a look at dysk which is one of the simplest possible uses
  • If a feature is missing, or you don't know how to use some part, come and ping me on my chat during West European hours.

Open-source applications using termimad

  • broot is a file manager and uses termimad for its help screen, status information and event management

  • lfs is a linux utility displaying file systems. Termimad templates are used to show the data in tables

  • SafeCloset is a secret safe. Its TUI uses Termimad a lot, especially inputs

  • Rhit is a nginx log analyzer. Termimad templates are used to show the data in tables

  • bacon is a background Rust compiler. It uses Termimad for display and event management

  • lapin is a terminal game. It uses Termimad for display and event management

  • backdown is a file deduplicator. It uses Termimad to print on screen and ask questions

  • Humility is a debugger for embedded systems. It uses Termimad to print Markdown documentation with the humility doc subcommand

If you're the author of another application using Termimad, please tell me.

Crossterm compatibility

Crossterm is a 0.x library which means its API isn't frozen. And it does change sometimes so libraries based on Crossterm can't always use its last version.

Crossterm 0.27.x is reexported by Termimad so you don't have to declare the import yourself. You may use crossterm as termimad::crossterm.

termimad's People

Contributors

canop avatar lerina avatar major avatar matthiasbeyer avatar mkeeter avatar stargateur avatar tathanhdinh avatar theidexisted avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

termimad's Issues

How to render a code block that has new lines in it in one block.

When I try to render a piece of code that contains a new line in it, I get the new line without any background highlight.

for instance,

use termimad;

fn main() {
    let code = r#"
        let x =0;

        println!("{}", x);

    "#;

    println!("{}", termimad::MadSkin::default_dark().term_text(code));
}

this will produce this rendering
screenshot-1691873778

as you can see it does not render it in one block.

wrapping bulleted text -- bug?

Hi,

I have this when I wrap bulleted text:

- [x] gfsdsdfsdfsdfsdf sdf sd fsd fsdf 
sdfsdf

Can the 2nd+ lines also be made to be as indented as the first, like so:

- [x] gfsdsdfsdfsdfsdf sdf sd fsd fsdf 
      sdfsdf

thanks!

Question: Indented output to terminal?

Hi,

Is there a way to print rendered markdown to the terminal with everything indented, say a few spaces? I don't want to use an alternate screen, or scrollable frame, just the text printed directly to the terminal.

This is what I have so far:

let desc_text =  i.description.unwrap();
    let mut area = Area::full_screen();
    area.pad(6,0);
    let md = skin.area_text(desc_text.as_str(), &area);
    print!("{}", &md);

This renders the text 6 characters narrower than the terminal width, now all I need to do is figure out how to indent this by 3 characters..

Any help is much appreciated. Thanks.

Code blocks are 100 columns even if `Some(< 100)` is passed to `text`

termimad is a great help to me, so thanks for building it!

I am doing this:

fn text_width() -> usize {
    let (terminal_width, _) = terminal_size();
    let terminal_width = terminal_width as usize;
    match env::var("MANWIDTH") {
        Ok(man_width) => match man_width.parse::<usize>() {
            Ok(w) => min(terminal_width, w),
            Err(_) => min(terminal_width, 80_usize),
        },
        Err(_) => min(terminal_width, 80_usize),
    }
}

fn terminal_text<'a>(s: &'a str, stream: Stream, skin: &'a MadSkin) -> TerminalText<'a> {
    if atty::is(stream) {
        TerminalText::Formatted(skin.text(s, Some(text_width())))
    } else {
        TerminalText::String(s)
    }
}

I find that even when the requested or real width is < 100, the inverted style for code blocks is 100 columns wide. The code in the block still wraps at the requested width. But it ends up noodling up the formatting when the terminal is < 100 wide.

Thanks!

Panic from `print_text`

I've discovered a different panic from print_text, this one originating from splitting within a unicode char, i.e. not at a char boundary.

This is a reproducible example

use std::io::Write;
use termimad::*;

static MD: &str = "ZA\u{360}\u{321}\u{34a}\u{35d}LGΌ IS\u{36e}\u{302}\u{489}\u{32f}\u{348}\u{355}\u{339}\u{318}\u{331} T</b>O\u{345}\u{347}\u{339}\u{33a}Ɲ\u{334}ȳ\u{333} TH\u{318}<b>E\u{344}\u{309}\u{356} \u{360}P\u{32f}\u{34d}\u{32d}O\u{31a}\u{200b}N\u{310}Y\u{321} H\u{368}\u{34a}\u{33d}\u{305}\u{33e}\u{30e}\u{321}\u{338}\u{32a}\u{32f}E\u{33e}\u{35b}\u{36a}\u{344}\u{300}\u{301}\u{327}\u{358}\u{32c}\u{329} \u{367}\u{33e}\u{36c}\u{327}\u{336}\u{328}\u{331}\u{339}\u{32d}\u{32f}C\u{36d}\u{30f}\u{365}\u{36e}\u{35f}\u{337}\u{319}\u{332}\u{31d}\u{356}O\u{36e}\u{34f}\u{32e}\u{32a}\u{31d}\u{34d}";

fn main() {
    let skin = MadSkin::default();
    skin.print_text(MD);
}

resulting in the error

thread 'main' panicked at 'byte index 137 is not a char boundary; it is inside '\u{329}' (bytes 136..138) of `ZA͠͝LGΌ IS̱ͮ T</b>O̺ͅƝ̴ȳ̳ TH̘<b>Ë͖́ ͠P̯̭O̚N̐Y̡ H̯ͨE̩̾ ̯ͧC͖ͭO̪ͮ`', /Users/sam/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcore/str/mod.rs:2052:47
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1069
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1504
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:218
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:511
  11: rust_begin_unwind
             at src/libstd/panicking.rs:419
  12: core::panicking::panic_fmt
             at src/libcore/panicking.rs:111
  13: core::str::slice_error_fail
             at src/libcore/str/mod.rs:0
  14: core::str::traits::<impl core::slice::SliceIndex<str> for core::ops::range::RangeFrom<usize>>::index::{{closure}}
             at /Users/sam/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcore/str/mod.rs:2052
  15: core::option::Option<T>::unwrap_or_else
             at /Users/sam/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcore/option.rs:428
  16: core::str::traits::<impl core::slice::SliceIndex<str> for core::ops::range::RangeFrom<usize>>::index
             at /Users/sam/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcore/str/mod.rs:2052
  17: core::str::traits::<impl core::ops::index::Index<I> for str>::index
             at /Users/sam/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcore/str/mod.rs:1780
  18: minimad::compound::Compound::cut_tail
             at /Users/sam/.cargo/registry/src/github.com-1ecc6299db9ec823/minimad-0.6.5/src/compound.rs:119
  19: termimad::wrap::hard_wrap_composite
             at src/wrap.rs:144
  20: termimad::wrap::hard_wrap_lines
             at src/wrap.rs:173
  21: termimad::text::FmtText::from_text
             at src/text.rs:44
  22: termimad::text::FmtText::from
             at src/text.rs:32
  23: termimad::skin::MadSkin::term_text
             at src/skin.rs:208
  24: termimad::skin::MadSkin::print_text
             at src/skin.rs:243
  25: text::main
             at examples/text/main.rs:8
  26: std::rt::lang_start::{{closure}}
             at /Users/sam/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src/libstd/rt.rs:67
  27: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:52
  28: std::panicking::try::do_call
             at src/libstd/panicking.rs:331
  29: std::panicking::try
             at src/libstd/panicking.rs:274
  30: std::panic::catch_unwind
             at src/libstd/panic.rs:394
  31: std::rt::lang_start_internal
             at src/libstd/rt.rs:51
  32: std::rt::lang_start
             at /Users/sam/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src/libstd/rt.rs:67
  33: main

however you need to make sure your terminal width isn't too narrow / too wide. If you can't reproduce let me know and I will figure out the specific width necessary to repro.

Termimad Parses some random text when used with TUI

I am trying to parse markdown input with termimad in a tui widget but i get an output like this [48;5;235m[38;5;249mhi[49m[39m when i type a string hi with two single quote (``) around it.

To reproduce

    let input = Paragraph::new(termimad::MadSkin::default().term_text(app.input.as_ref()).to_string())
       .style(match app.input_mode {
            InputMode::Normal => Style::default(),
            InputMode::Editing => Style::default().fg(Color::Yellow),
        })
        .block(Block::default().borders(Borders::ALL).title("Input"));
    f.render_widget(input, chunks[2]);

Please this is my first time working with rust would there be any way to work this ?

Display fenced code block issue

Hi! When I try to test printing code blocks, I found that the printing has a small issue.

My code is

image

Then I got this

image

You see python is printed out. I see #1 is not implemented so syntax highlighting is not working, but I think as least termimad should omit the language name.

Pass InputField into a MadSkin

GIven an input field

 Input: InputField::default(),

How do i get the input rendered as MD with a skin like so ?

skin.write_in_area_on(w, Input, &self.area);

I am just trying to render MD directly from the input

Make it possible to Indent Code Blocks

Is there a way to indent code blocks? I see that you can set the alignment to left, center, or right, but can I add four spaces indent to a left-aligned code block?

Indented list rendering

i'm seeing some surprising rendering for indented lists, given this input

fn main() {
    let doc = r#"
list one:

- a
    - b
        - c
            - d

list two:

- a
  - b
    - c
      - d
"#;
    termimad::print_text(doc);
}

i see a dark background and the list indentation doesn't seem quite right:

image

i'd expect output more like glow's:

image

wanted to confirm this is a bug before trying to take a stab at a PR. i'm a rust noob so not confident i'd be able to fix it, but maybe 🤞🏻 .

[Feature] Code Fences

Would it be possible to support code fences? The README says that they are not supported and I was not sure if that was a intentional design decision.

The purpose for supporting code fences, in my case, is that I am taking the same markdown that I am using for Termimad and using it to power my online documentation with mdbook. mdbook supports syntax highlighting when using code fences, so if Termimad allowed them, even without syntax highlighting, it will allow me to use syntax highlighting in mdbook.


On a side note, only because of Termimad am I able to use the same documentation for the CLI and the web documentation and it is awesome. Thanks a lot for helping enable this for my project:

image

"coloor" dependency introduces LGPL-3.0

First of all: I am not a lawyer.

With that out of the way: The coloor dependency depends (since its 0.6.0 release) on a crate that is LGPL-3.0.

To my understanding, that means that the coloor crate is LGPL-3.0 itself, because of static linking and LGPL is only "lesser" for non-static linking, is it not? That would mean that termimad is LGPL-3.0 since the introduction of the coloor dependency as well.

I found that because CI broke here: TheNeikos/type_description#265 (job).

Code Fences With Language Specified

Code fences currently don't render if you specify a language:

```bash
# comment
$ echo "hi"
```

I know that Termimad itself doesn't support code highlighting, but I'm using the same markdown docs for my web docs as my terminal docs so the web docs will pick up the syntax highlighting.

@Canop Thanks for all your help. 🙂

Cannot compile inputs or render-input-markdown examples

Description

Received a linker error when attempting to compile inputs and render-input-markdown examples

Steps to reproduce

  • Clone v0.20.6 (current main)
  • Run cargo run --example inputs

System Info

OS: macOS Monteray v12.3
Chipset: Apple Silicon (M1 Pro)
rustc: 1.65.0 (897e37553 2022-11-02)

Expected Result

Should build and run inputs example

Actual Result

**Linker Error: **

cargo run --example inputs -v
       Fresh autocfg v1.1.0
       Fresh cfg-if v1.0.0
       Fresh unicode-ident v1.0.6
       Fresh scopeguard v1.1.0
       Fresh libc v0.2.138
       Fresh proc-macro2 v1.0.49
       Fresh log v0.4.17
       Fresh quote v1.0.23
       Fresh signal-hook-registry v1.4.0
       Fresh crossbeam-utils v0.8.14
       Fresh memchr v2.5.0
       Fresh smallvec v1.10.0
       Fresh lock_api v0.4.9
       Fresh mio v0.8.5
       Fresh syn v1.0.107
       Fresh parking_lot_core v0.9.5
       Fresh quick-xml v0.22.0
       Fresh signal-hook v0.3.14
       Fresh memoffset v0.7.1
       Fresh signal-hook-mio v0.2.3
       Fresh thiserror-impl v1.0.38
       Fresh parking_lot v0.12.1
       Fresh bitflags v1.3.2
       Fresh once_cell v1.16.0
       Fresh thiserror v1.0.38
       Fresh crossterm v0.23.2
       Fresh num-traits v0.2.15
       Fresh core-foundation-sys v0.8.3
       Fresh crossbeam-epoch v0.9.13
       Fresh iana-time-zone v0.1.53
       Fresh serde_derive v1.0.151
       Fresh crossbeam-deque v0.8.2
       Fresh crossbeam-queue v0.3.8
       Fresh xcb v0.10.1
       Fresh num-integer v0.1.45
       Fresh crossbeam-channel v0.5.6
       Fresh time v0.1.45
       Fresh chrono v0.4.23
       Fresh crossbeam v0.8.2
       Fresh x11-clipboard v0.5.3
       Fresh coolor v0.5.0
       Fresh minimad v0.9.1
       Fresh proc-status v0.1.1
       Fresh crokey-proc_macros v0.4.0
       Fresh file-size v1.0.3
       Fresh serde v1.0.151
       Fresh unicode-width v0.1.10
       Fresh anyhow v1.0.68
       Fresh cli-log v2.0.0
       Fresh terminal-clipboard v0.3.1
       Fresh crokey v0.4.3
   Compiling termimad v0.20.6 (/Users/cardamom/src/personal/termimad)
     Running `rustc --crate-name inputs --edition=2021 examples/inputs/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C split-debuginfo=unpacked -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="special-renders"' -C metadata=c5e207a04cd84114 -C extra-filename=-c5e207a04cd84114 --out-dir /Users/cardamom/src/personal/termimad/target/debug/examples -C incremental=/Users/cardamom/src/personal/termimad/target/debug/incremental -L dependency=/Users/cardamom/src/personal/termimad/target/debug/deps --extern anyhow=/Users/cardamom/src/personal/termimad/target/debug/deps/libanyhow-21978be410a2fbf0.rlib --extern cli_log=/Users/cardamom/src/personal/termimad/target/debug/deps/libcli_log-7017e0c0864902d9.rlib --extern coolor=/Users/cardamom/src/personal/termimad/target/debug/deps/libcoolor-d1f48a62f08063b6.rlib --extern crokey=/Users/cardamom/src/personal/termimad/target/debug/deps/libcrokey-743332353c50acdb.rlib --extern crossbeam=/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossbeam-b70ab4c4cabb1784.rlib --extern crossterm=/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossterm-b8ddcaf17b7be669.rlib --extern minimad=/Users/cardamom/src/personal/termimad/target/debug/deps/libminimad-fa7d8038005ee9e5.rlib --extern termimad=/Users/cardamom/src/personal/termimad/target/debug/deps/libtermimad-a46e755f18bc2231.rlib --extern terminal_clipboard=/Users/cardamom/src/personal/termimad/target/debug/deps/libterminal_clipboard-e8f3d74634f60fc9.rlib --extern thiserror=/Users/cardamom/src/personal/termimad/target/debug/deps/libthiserror-72a4dbe2d40f3703.rlib --extern unicode_width=/Users/cardamom/src/personal/termimad/target/debug/deps/libunicode_width-3d01bf217eabcebb.rlib`
error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-arch" "arm64" "/var/folders/46/xxvfd9m166x8j9kstkxbm9xr0000gn/T/rustc2acZID/symbols.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.100wk0928zbr9qp9.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.11526cri3pxdtmeo.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.12orupzludbpt9wn.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.18qlhyaoio8i4m93.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.19qwxxfphj4e77zo.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1c6trk4b8bjb3r1l.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1fp5ttonuy94d12y.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1ifpok2va4vvm0ov.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1ivj76btxn1j7owi.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1j1g5veabfupbnwr.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1je6wkxg2kzp6z52.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1ou6z336jyly3afw.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1rrjefc6j9lv8vh3.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1uy8pfz5e8y9v1v4.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1y0l4yorw63i14hz.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1ya9bqkat78p259o.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.1zpnz0kkyjb2y22o.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.227jlkz2ltqqjtvl.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.26fuu88e0a70c5l2.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2cdc4xi8vfw05kvz.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2cnlabugax8a4pud.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2fsg0h8uk1xjtn2h.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2kn4c9bg4s2m196h.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2mmkbu4vxxx5jrci.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2oig49tqjbi5y09d.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2oq4x2pyj6q6b7z0.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2pvv2peukt8l4gxw.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2qklzvyzufzb11m5.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2s536ollch7lpoms.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2tvnhlasozl6kl61.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.2w73qydkh0giseyk.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.30duuwp7z5bhcm87.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.31xoaatzybi8fnsx.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.32v0nfftmyt2lpkd.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.34dxpv5srvcsfsjd.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.365d2gb4cr0vgsff.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.3cta7nbz79y70oly.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.3irv965p0z9alueo.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.3ivaggie58janes9.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.3ixzfxno095jmky5.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.3mlugzpnvr12r5cj.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.3nsqare3wlhc3h3x.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.3o2802ch35cjvbrn.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.3tze6ih00xtsaw88.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4099g8n0t565b5n7.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.422uvxxf8dovk4ad.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.436i0k88vyd25phc.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.445xs51hz2zsiy1w.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4gmg8zrhddp49x4g.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4kdmd42qe5os18fk.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4kjlzmf7zigrortb.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4lrwndb2ra1rnjfs.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4neqg4typ4p8uw5r.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4pkb1x383bg53073.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4qgidpo754isg24x.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4t5o1clzs00v1ged.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4vma69d2w4pl26a9.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4wf7o2c5stv2ygmj.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.4z8bpwnaeokvowo0.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.51jdvnn7gk2fhodq.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.5a14ut7wk28l66jn.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.5an62l8jowkyjfj9.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.5cot473u3o4ycelk.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.5e9nb2l15qussca.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.5eklxdwm17c643gp.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.5fuzt20ag5k3y2eo.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.8es9qp1gacwurye.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.9qxkrvpl6iztj0d.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.ab4y3d7fa4810j0.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.ck53ctc4sc65zx3.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.dzrjr2tfrqidp60.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.fwzdy8x7t08w0i4.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.iscvfgm3wf00je0.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.mc8swht2vmk55t1.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.na7we0syhuidue.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.osrl2zo7p8syqkq.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.r8v3a7d9og36c0l.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.tgyndqtjqh3vcxx.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.uumo0a7navb1jaf.rcgu.o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114.xamaif9grz4ptws.rcgu.o" "-L" "/Users/cardamom/src/personal/termimad/target/debug/deps" "-L" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libterminal_clipboard-e8f3d74634f60fc9.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libx11_clipboard-1d914fc39d270104.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libxcb-6b560f2e462d6589.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcrokey-743332353c50acdb.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libserde-ddd2a52f4cd7c7c2.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libanyhow-21978be410a2fbf0.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libtermimad-a46e755f18bc2231.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcoolor-d1f48a62f08063b6.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossbeam-b70ab4c4cabb1784.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossbeam_channel-59f4eaf1aaa6da17.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossbeam_deque-b3ebade16322fe17.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossbeam_queue-f4b4a720b50e6c01.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossbeam_epoch-0390e0098c63e91a.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libmemoffset-8cedb80e7952119f.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossbeam_utils-8dcf4d53da288f8f.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libunicode_width-3d01bf217eabcebb.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libminimad-fa7d8038005ee9e5.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libonce_cell-a50890e42af3f299.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossterm-b8ddcaf17b7be669.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libsignal_hook_mio-289c35cbba69b450.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libsignal_hook-6e86e8460ac1361e.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libsignal_hook_registry-ffbfb85aa8a13b5c.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libmio-5700baba73e9ba09.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libparking_lot-7ba3afe11365a716.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libparking_lot_core-710141fb9189b898.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libsmallvec-2f02ddcbd54d9ddc.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/liblock_api-aefd6ed82f4ed634.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libscopeguard-eb1e61010332a1cf.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libbitflags-295066ef4f1a08fb.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcli_log-7017e0c0864902d9.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libfile_size-b432198dda13496c.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libproc_status-42aa69f5653e62b0.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libthiserror-72a4dbe2d40f3703.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libchrono-3f7e9f14b1d42cc2.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libiana_time_zone-c194462dbf7ec684.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcore_foundation_sys-a98884409e1a2efe.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libnum_integer-bc6e2a572eaceb6a.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libnum_traits-699c286c440bab1f.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libtime-b59c77b9afbdf5ba.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/liblibc-1296c5a414011619.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/liblog-8aaf2fada90fd261.rlib" "/Users/cardamom/src/personal/termimad/target/debug/deps/libcfg_if-e6509c5f025d8702.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libstd-0ea869fe6cd419aa.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libpanic_unwind-cec68d6b04523a7c.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libobject-63f595d80ff58213.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libmemchr-8763a2dbee186cdb.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libaddr2line-5c062bda19d9d8ff.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libgimli-f661f75085be205d.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/librustc_demangle-778598e0d10758f6.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libstd_detect-aa27b90bf7fd1432.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libhashbrown-3e59a62b515378ce.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libminiz_oxide-2d9579d5c16d038c.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libadler-68620bbed0e743bb.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/librustc_std_workspace_alloc-af17eba547e34f93.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libunwind-7309143273eafd44.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libcfg_if-d1a0ff487d6d4d55.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/liblibc-1432fbf85665684e.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/liballoc-e26d2fb48c01825f.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/librustc_std_workspace_core-a8a859a864856684.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libcore-908209eee60fb642.rlib" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libcompiler_builtins-d567ed3625eefebc.rlib" "-lxcb" "-lxcb-render" "-lxcb-shape" "-lxcb-xfixes" "-framework" "CoreFoundation" "-liconv" "-lSystem" "-lc" "-lm" "-L" "/Users/cardamom/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib" "-o" "/Users/cardamom/src/personal/termimad/target/debug/examples/inputs-c5e207a04cd84114" "-Wl,-dead_strip" "-nodefaultlibs"
  = note: ld: library not found for -lxcb
          clang: error: linker command failed with exit code 1 (use -v to see invocation)


error: could not compile `termimad` due to previous error

Caused by:
  process didn't exit successfully: `rustc --crate-name inputs --edition=2021 examples/inputs/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C split-debuginfo=unpacked -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="special-renders"' -C metadata=c5e207a04cd84114 -C extra-filename=-c5e207a04cd84114 --out-dir /Users/cardamom/src/personal/termimad/target/debug/examples -C incremental=/Users/cardamom/src/personal/termimad/target/debug/incremental -L dependency=/Users/cardamom/src/personal/termimad/target/debug/deps --extern anyhow=/Users/cardamom/src/personal/termimad/target/debug/deps/libanyhow-21978be410a2fbf0.rlib --extern cli_log=/Users/cardamom/src/personal/termimad/target/debug/deps/libcli_log-7017e0c0864902d9.rlib --extern coolor=/Users/cardamom/src/personal/termimad/target/debug/deps/libcoolor-d1f48a62f08063b6.rlib --extern crokey=/Users/cardamom/src/personal/termimad/target/debug/deps/libcrokey-743332353c50acdb.rlib --extern crossbeam=/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossbeam-b70ab4c4cabb1784.rlib --extern crossterm=/Users/cardamom/src/personal/termimad/target/debug/deps/libcrossterm-b8ddcaf17b7be669.rlib --extern minimad=/Users/cardamom/src/personal/termimad/target/debug/deps/libminimad-fa7d8038005ee9e5.rlib --extern termimad=/Users/cardamom/src/personal/termimad/target/debug/deps/libtermimad-a46e755f18bc2231.rlib --extern terminal_clipboard=/Users/cardamom/src/personal/termimad/target/debug/deps/libterminal_clipboard-e8f3d74634f60fc9.rlib --extern thiserror=/Users/cardamom/src/personal/termimad/target/debug/deps/libthiserror-72a4dbe2d40f3703.rlib --extern unicode_width=/Users/cardamom/src/personal/termimad/target/debug/deps/libunicode_width-3d01bf217eabcebb.rlib` (exit status: 1)

Attempted Resolutions

  • Installed libxcb
  • Installed x11
  • Tried both stable & nightly
  • Tried updating rust (1.66)

Upgrade to Crossterm 0.14

Crossterm 0.14 was just released and it has a new event system along with support for resize events. These are features I'd like to use in my project, but Termimad would need to update to 0.14 first.

Would it help if I were to submit a PR for this? I haven't yet looked into how hard that might be, but I'm thinking it would be simple.

Trait implementations for serialization

I'd like to have my MadSkin come from a user-supplied theme, like colors.yml. I don't mind just making a newtype around MadSkin to do so, but I noticed the code in broot that handles parsing some user-friendlier keywords, etc., and just wanted to check if you plan on moving that back out to minimad or termimad.

I also thought, to minimize effort, perhaps you'd be interested in just adding a package flag serialization which if set, would add serde dependency and provide serialize/deserialize traits. (To avoid users having to deal with orphan problems when they want to have theme configuration.)

Just opening this issue for your awareness; if you don't feel that serialization should be a part of the library, feel free to close it! Thanks.

MadSkin.print_text() Can Panic on Broken Pipe!

Hey there, thanks for this awesome library. I'm using it for my organization's new Lucky project.

Would it be possible to have a version of MadSkin.print_text that returns a result instead of panicking? I would much prefer to print a proper error message than to panic.

Rendering inline code with newlines

We've been using termimad to print documentation in the Humility debugger, and it's been great so far (feel free to add it to the list of projects, or I can open a PR to do so).

I noticed that if inline code spans multiple input lines, the highlighting is not maintained.

For example,

When listening, it is mandatory to specify the interface (e.g. `humility rpc
--listen -i en0` on MacOS).

is printed like this:

image

It looks like the code highlighting terminates at the end of the line, instead of continuing to the backtick on the next line.

This is unfortunate, because our docs are written as docstrings, i.e. with hard-wrapping (here).

Any ideas on how to fix or work around this issue?

Thanks!

Panic from `print_text`

Someone has observed thread 'main' panicked at 'attempt to subtract with overflow' coming from a skin.print_text call (ref samtay/so#8), and also found that such panic goes away when using skin.print_inline. Unfortunately I couldn't repo this myself, but the relevant details from that issue are:

  • OS: Ubuntu 18.04
  • Terminal: gnome-terminal
  • Terminal size when rendering: (190, 51)
  • Relevant part of the stack trace:
      13:     0x55f43543f6ed - core::panicking::panic::h68e56c2eeba99c8c
                                 at src/libcore/panicking.rs:50
    14:     0x55f434c96c0d - minimad::compound::Compound::cut_tail::h65a621fcce14ec17
                                 at /home/e/.cargo/registry/src/github.com-1ecc6299db9ec823/minimad-0.6.4/src/compound.rs:117
    15:     0x55f434c7062c - termimad::wrap::hard_wrap_composite::ha144c51dfb0493a2
                                 at /home/eyehuda/.cargo/registry/src/github.com-1ecc6299db9ec823/termimad-0.8.24/src/wrap.rs:137
    16:     0x55f434c71116 - termimad::wrap::hard_wrap_lines::hcc2fff69ff958a06
                                 at /home/eyehuda/.cargo/registry/src/github.com-1ecc6299db9ec823/termimad-0.8.24/src/wrap.rs:172
    17:     0x55f434c72f2e - termimad::text::FmtText::from_text::hdd93418c5a6ceb6b
                                 at /home/eyehuda/.cargo/registry/src/github.com-1ecc6299db9ec823/termimad-0.8.24/src/text.rs:44
    18:     0x55f434c72de0 - termimad::text::FmtText::from::h5006d4ececb9711c
                                 at /home/eyehuda/.cargo/registry/src/github.com-1ecc6299db9ec823/termimad-0.8.24/src/text.rs:32
    19:     0x55f434c7f0eb - termimad::skin::MadSkin::term_text::hd65d68486384d1a9
                                 at /home/eyehuda/.cargo/registry/src/github.com-1ecc6299db9ec823/termimad-0.8.24/src/skin.rs:208
    20:     0x55f434c7f160 - termimad::skin::MadSkin::print_text::h1276bb441ef97417
                                 at /home/eyehuda/.cargo/registry/src/github.com-1ecc6299db9ec823/termimad-0.8.24/src/skin.rs:243
    
  • Input causing panic: gist link

Note the markdown input is quite large, so I put it in a gist. I also embedded it within the ./examples/text/main.rs file so that it would be easier to run.

EDIT: I was able to repro this. At terminal width 112 there is no panic. If the terminal width is greater than or equal to 117, you can observe this panic.

I think if you make sure your terminal width is that wide (e.g. go full screen), and run this:

cd /path/to/termimad
curl -o "examples/text/main.rs" "https://gist.githubusercontent.com/samtay/cf9d1b8c0c7935baf6f6971101bd567e/raw/dff5e762f9a56f76aa64e9c61b57311c42c7a0f0/example-panic.rs"
RUST_BACKTRACE=1 cargo run --example text

you should be able to observe it.

No bug in `crossterm`?

I was chasing a bug in cargo crev verify -1 - the display would be blinking / wrong. Eventually I've found:

/// Return a (width, height) with the dimensions of the available
/// terminal in characters.
pub fn terminal_size() -> (u16, u16) {
    let (w, h) = Terminal::new().terminal_size();
    // there's a bug in crossterm 0.9.6. It reports a size smaller by
    //  one in both directions
    (w + 1, h + 1)
}

I don't think that's the case, at least on my system (Linux). After I got rid of this additional +1s the problem is gone.

Cannot escape markdown characters

I'm using this crate in my compiler to automatically generate documentation, and I've run into an issue where I cannot escape (use as regular characters) * characters, or other characters such as `. We've tried \*, \\*, and \\\*, and nothing works. Is there a way to display asterisks and other markdown command characters?

Incorrect handling of list entry text

To add multiple lines of text to a list entry one should indent the text below the entry to signify that it belongs to it. This sign isn't currently looked for by termimad, so the text of a sub-list entry is highlighted as a codeblock (since it is indented 4 spaces).

Adding some statefulness to the printing, to track if printing indented lines after a list entry of which depth, would be a nice improvement.

Missing characters from text when wrapped in a MadView

I ran the scrollable example from termimad 0.8.17 and noticed there are a few characters missing (see screenshot). For instance, the w from wrapping on line 7 and the b from but parsing is cheap on line 32.

It seems like it happens when the beginning of a bold or italic section gets wrapped to the beginning of the line maybe?

2020-04-10-180358_2657x2752_scrot

Update to crossterm 0.20.0

When using crossterm 0.20.0 with termimad 0.11.1, I get the following error:

error[E0308]: mismatched types
   --> src/command/output.rs:125:36
    |
125 |                 skin.bold.add_attr(Underlined);
    |                                    ^^^^^^^^^^ expected enum `crossterm::style::types::attribute::Attribute`, found enum `crossterm::style::Attribute`
    |
    = note: perhaps two different versions of crate `crossterm` are being used?

error[E0308]: mismatched types
   --> src/command/output.rs:125:36
    |
125 |                 skin.bold.add_attr(Underlined);
    |                                    ^^^^^^^^^^ expected enum `crossterm::style::types::attribute::Attribute`, found enum `crossterm::style::Attribute`
    |
    = note: perhaps two different versions of crate `crossterm` are being used?

It looks to me as if there were some breaking changes in the crossterm crate that just moved where the types live. termimad should update their API to accept this new type, and possibly consider re-exporting the types that are expected to be used within the skin builder API so consumer crates don't have to worry about matching dependency versions.

Executable

Is there a simple way to use this as an executable?

One workflow I'd like to have is the following:

Having open a text editor to edit markdown
and termimad in another window, outputting the formatted markdown and watching for file changes (in order to update the markdown, whenever I hit safe

example compile error on M1 mac

reproduce

git clone .
cargo run --example render-input-markdown

error msg

Compiling termimad v0.20.2 (/Users/andyjado/Projects/termimad)
error: linking with cc failed: exit status: 1
|
= note: "cc" "-arch" "arm64" "/

Lone newlines not interpreted as space

Commonly in markdown a single newline is interpreted as space (and often indentation on the next line ignored). This is to allow keeping one's markdown source limited to 80 columns without limiting the width it can be printed as. Instead two consecutive newlines are treated as a new paragraph.

As I have 80 column markdown source and would like to be able to print it wider than that I quite miss this feature.

From a quick look at your codebase it is either that a user will need to modify their input markdown before giving it into either of MadView or TextView (the workaround I'll be using for now) or the library can handle it when splitting the markdown string into lines. I'll see if I can throw together a suggestion for how to do this.

Crossterm 0.25.0 breaking changes

When using crossterm 0.25.0 with termimad 0.20.3, I get the following error when I followed the code example in the docs:

error[E0308]: mismatched types
 --> src/theme.rs:9:46
  |
9 |     skin.strikeout = CompoundStyle::new(Some(Red), None, Bold.into());
  |                                              ^^^ expected enum `crossterm::style::types::color::Color`, found enum `Color`
  |
  = note: perhaps two different versions of crate `crossterm` are being used?

error[E0277]: the trait bound `crossterm::style::attributes::Attributes: From<Attribute>` is not satisfied
 --> src/theme.rs:9:63
  |
9 |     skin.strikeout = CompoundStyle::new(Some(Red), None, Bold.into());
  |                                                               ^^^^ the trait `From<Attribute>` is not implemented for `crossterm::style::attributes::Attributes`
  |
  = help: the following implementations were found:
            <crossterm::style::attributes::Attributes as From<&[crossterm::style::types::attribute::Attribute]>>
            <crossterm::style::attributes::Attributes as From<crossterm::style::types::attribute::Attribute>>
  = note: required because of the requirements on the impl of `Into<crossterm::style::attributes::Attributes>` for `Attribute`

From this answer, it seems there there is a breaking change between crossterm 0.23 and crossterm 0.25.
https://stackoverflow.com/questions/74141606/cannot-compile-rust-program-due-to-e0308-error/74144038#74144038

Is it possible to state what version of crossterm supported by termimad or update the library to accept the newest version of crossterm?

Scroll To End of a TextView/MadView

Is there a way to scroll to the end of a TextView/MadView? Currently I'm just running view.try_scroll_pages(90000); which works completely fine, but I feel like there should be a better way to do that.

Feature request: please add custom style syntax

First of all thank you for this great crate! I am using termimad to implement a CLI tool which should output text in different colors, not related to bold, italic, code, or strikeout styles. In other words, once I have personalized my bold / italic / code / strikeout styles, then I also need to apply different colors to both stylized and normal text.
It would be great to add the possibility to define new custom syntax. For instance, with reference to the following example:

skin.strikeout = CompoundStyle::new(Some(Red), None, Bold.into());

since I need to keep the strikeout style for some text, and also apply red bold style to some other text, it would be great to be able to write something like:

skin.custom_style("rb") = CompoundStyle::new(Some(Red), None, Bold.into());

and then apply it for instance as:

termimad::print_inline("#rb#red bold text!#rb#");

[Feature] Provide a Way to Escape Blocks of Content

I am trying to create manpage-like help pages using Termimad and I want to be able to inline the Clap commandline argument help into the document, but the styling for the help message gets a little confused because Termimad is interpreting the indentation in the help message as code blocks.

Could there be a way to make a whole block of the document so that it is taken literally instead of interpreted as Markdown syntax?

Maybe something like this:

\\\
Literal block here.

    This won't be interpreted as a codeblock because it is in the literal block section
\\\

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.