Giter Club home page Giter Club logo

rust-term-grid's Introduction

rust-term-grid term-grid on crates.io Minimum Rust Version 1.31.0 Build status

This library arranges textual data in a grid format suitable for fixed-width fonts, using an algorithm to minimise the amount of space needed.

Installation

This crate works with Cargo. Add the following to your Cargo.toml dependencies section:

[dependencies]
term_grid = "0.2"

The earliest version of Rust that this crate is tested against is Rust v1.31.0.

Usage

This library arranges textual data in a grid format suitable for fixed-width fonts, using an algorithm to minimise the amount of space needed. For example:

use term_grid::{Grid, GridOptions, Direction, Filling, Cell};

let mut grid = Grid::new(GridOptions {
    filling:     Filling::Spaces(1),
    direction:   Direction::LeftToRight,
});

for s in &["one", "two", "three", "four", "five", "six", "seven",
           "eight", "nine", "ten", "eleven", "twelve"]
{
    grid.add(Cell::from(*s));
}

println!("{}", grid.fit_into_width(24).unwrap());

Produces the following tabular result:

one  two three  four
five six seven  eight
nine ten eleven twelve

Creating a grid

To add data to a grid, first create a new Grid value, and then add cells to them with the add method.

There are two options that must be specified in the GridOptions value that dictate how the grid is formatted:

  • filling: what to put in between two columns - either a number of spaces, or a text string;
  • direction, which specifies whether the cells should go along rows, or columns:
    • Direction::LeftToRight starts them in the top left and moves rightwards, going to the start of a new row after reaching the final column;
    • Direction::TopToBottom starts them in the top left and moves downwards, going to the top of a new column after reaching the final row.

Displaying a grid

When display a grid, you can either specify the number of columns in advance, or try to find the maximum number of columns that can fit in an area of a given width.

Splitting a series of cells into columns - or, in other words, starting a new row every n cells - is achieved with the fit_into_columns method on a Grid value. It takes as its argument the number of columns.

Trying to fit as much data onto one screen as possible is the main use case for specifying a maximum width instead. This is achieved with the fit_into_width method. It takes the maximum allowed width, including separators, as its argument. However, it returns an optional Display value, depending on whether any of the cells actually had a width greater than the maximum width! If this is the case, your best bet is to just output the cells with one per line.

Cells and data

Grids do not take Strings or &strs - they take Cells.

A Cell is a struct containing an individual cell’s contents, as a string, and its pre-computed length, which gets used when calculating a grid’s final dimensions. Usually, you want the Unicode width of the string to be used for this, so you can turn a String into a Cell with the .into() method.

However, you may also want to supply your own width: when you already know the width in advance, or when you want to change the measurement, such as skipping over terminal control characters. For cases like these, the fields on the Cell values are public, meaning you can construct your own instances as necessary.

rust-term-grid's People

Contributors

arnidagur avatar behnam avatar ignatenkobrain avatar ogham 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

rust-term-grid's Issues

Include license file in crate publication?

Hi! I'm reviewing this crate for inclusion in Fuchsia, and our dependency tooling works best when there's a LICENSE file in the root of the crate upload, see regex for an example.

The currently published version of this crate seems to exclude the license from the tarball: https://docs.rs/crate/term_grid/latest/source/Cargo.toml.orig, but I'm not seeing the equivalent on HEAD: https://github.com/ogham/rust-term-grid/blob/master/Cargo.toml#L7.

Would it be possible to publish an updated version of the crate based on the current tip-of-tree? Thanks!

it's not support emjio char

example:

grid.add(Cell::from(format!("πŸ“‚ {}", item)));
grid.add(Cell::from(format!("πŸ“„ {}", item.get_path())));

the return is none

Potential ways to optimize width_dimensions() algorithm

See the following commit in my (rather poor) Python implementation of this algorithm: ArniDagur/guide-key.nvim@fbd9b5e

As you can see, I tried both binary search and looping downwards from the theoretical maximum number of lines, to 1. Both seemed to improve performance, but there are almost certainly better ways to go about it.

I thought about basing binary search hi/lows off of the theoretical maximum number of lines, but the problem there is that I'm not sure how to efficiently calculate the theoretical minimum. This occurs when the items are sorted from highest to lowest (or the other way around).

@ogham I would love to hear your ideas and thoughts.

Performance issue with the redundancy operations

widths[index] = max(widths[index], cell.width);

For this line of code, it will always update the value of widths[index], even if the value of it does not change. This introduces some redundant operations.

If we change the code to this, we can eliminate these redundant operations.

if widths[index] < cell.width{
     widths[index] = cell.width;
}

According to my tests, the average execution time decreased from 6.5s to 4.8s, which is a 1.37x speedup.

Hope this information helps!

Color codes ruin width calculation.

uutils's ls --color re-calculates widths, passing them explicitly to cells, because terminal colors ruin the width calculation of term-grid.

Ideally, term-grid should recognize color escape sequences and treat them as zero-width, or at least have a grid option which makes that possible, to allow out-of-the-box color handling.

Bug in smallest_diminesions_yet calculation?

I believe this for loop code

for num_lines in (1 .. theoretical_max_num_lines).rev() {

should be inclusive

for num_lines in (1..=theoretical_max_num_lines).rev() {

I ran into this problem where the output should've been 2 rows but it would never output 2 rows. It would always fail and return the initialized value of None for smallest_dimensions_yet.

Please confirm.

Thanks!

Grid with 1 item fails to render

If you only add one string to the grid, it will fail and return None.
Here is the example code:

extern crate term_grid;
use term_grid::{Grid, GridOptions, Direction, Filling};

fn main() {
    let mut grid = Grid::new(GridOptions {
        direction:  Direction::TopToBottom,
        filling:    Filling::Spaces(2),
    });

    for i in 0..1 {
        grid.add(format!("{}", 2_isize.pow(i)).into())
    }

    if let Some(grid_display) = grid.fit_into_width(40) {
        println!("{}", grid_display);
    }
    else {
        println!("Couldn't fit grid into 40 columns!");
    }
}

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.