Elastic tabstops for Rust.

Overview

tabwriter is a crate that implements elastic tabstops. It provides both a library for wrapping Rust Writers and a small program that exposes the same functionality at the command line.

Build status

Dual-licensed under MIT or the UNLICENSE.

Simple example of library

use std::io::Write;

use tabwriter::TabWriter;

let mut tw = TabWriter::new(vec![]);
tw.write_all(b"
Bruce Springsteen\tBorn to Run
Bob Seger\tNight Moves
Metallica\tBlack
The Boss\tDarkness on the Edge of Town
").unwrap();
tw.flush().unwrap();

let written = String::from_utf8(tw.into_inner().unwrap()).unwrap();

assert_eq!(&written, "
Bruce Springsteen  Born to Run
Bob Seger          Night Moves
Metallica          Black
The Boss           Darkness on the Edge of Town
");

You can see an example of real use in my CSV toolkit.

Simple example of command line utility

[andrew@Liger tabwriter] cat sample | sed 's/   /\\t/g'
a\tb\tc
abc\tmnopqrstuv\txyz
abcmnoxyz\tmore text

a\tb\tc
[andrew@Liger tabwriter] ./target/tabwriter < sample
a          b           c
abc        mnopqrstuv  xyz
abcmnoxyz  more text

a   b   c

Notice that once a column block is broken, alignment starts over again.

Documentation

The API is fully documented with some examples: http://burntsushi.net/rustdoc/tabwriter/.

Installation

This crate works with Cargo. Assuming you have Rust and Cargo installed, simply check out the source and run tests:

git clone git://github.com/BurntSushi/tabwriter
cd tabwriter
cargo test

You can also add tabwriter as a dependency to your project's Cargo.toml:

[dependencies]
tabwriter = "1"

Dealing with ANSI escape codes

If you want tabwriter to be aware of ANSI escape codes, then compile it with the ansi_formatting feature enabled.

Minimum Rust version policy

This crate's minimum supported rustc version is 1.34.0.

The current policy is that the minimum Rust version required to use this crate can be increased in minor version updates. For example, if crate 1.0 requires Rust 1.20.0, then crate 1.0.z for all values of z will also require Rust 1.20.0 or newer. However, crate 1.y for y > 0 may require a newer minimum version of Rust.

In general, this crate will be conservative with respect to the minimum supported version of Rust.

Comments
  • Formatting broken when using ansi colours

    Formatting broken when using ansi colours

    I am trying to combine tabwriter and ansi_term crate to format some text output but tabwriter doesn't seem to handle the ANSI escape code and the formatting fails. I have no idea how this works in detail so I cannot probably provide a fix.

    The code:

    extern crate tabwriter;
    extern crate ansi_term;
    use ansi_term::Colour::Red;
    use tabwriter::TabWriter;
    use std::io::Write;
    
    fn tabify(mut tw: TabWriter<Vec<u8>>, s: &str) -> String {
        write!(&mut tw, "{}", s).unwrap();
        tw.flush().unwrap();
        String::from_utf8(tw.unwrap()).unwrap()
    }
    
    fn main() {
        let output = format!("Title1\tTitle2\tTitle3\n{}\t{}\t{}",
                                   Red.paint("value1"), Red.paint("value2"), Red.paint("value3"));
    
        let tw = TabWriter::new(Vec::<u8>::new());
        println!("{}", tabify(tw, &output[..]));
    }
    

    The output when running the code above:

    Title1         Title2         Title3
    value1  value2  value3
    
    opened by mhristache 8
  • Add optional support for ANSI formatting

    Add optional support for ANSI formatting

    I have enhanced my old PR to use an optional feature to enable ANSI formatting support.During implementation, I noticed tabwriter.rs is no longer needed so I removed it.

    opened by mhristache 6
  • move binary to src

    move binary to src

    I don't know what the motivation for having the binary in its own directory with its own Cargo.toml is, but I think it makes more sense to just move main.rs to src and delete the other files.

    opened by vks 6
  • Allow Center and Right Alignment of Texts

    Allow Center and Right Alignment of Texts

    This would be really useful for Headers and Numbers. Looks like it's unstable at the moment however: https://doc.rust-lang.org/std/fmt/struct.Formatter.html#method.align

    enhancement 
    opened by CryZe 4
  • Possible to disable alignment for certain lines?

    Possible to disable alignment for certain lines?

    Hi,

    I have a usecase that I want to add a line in between of some other lines, and I don't want the length of this line to be considered during alignment. Is it possible?

    Thanks!

    question 
    opened by sefeng211 3
  • padding(0) gives one space of padding

    padding(0) gives one space of padding

    It looks like the minimum padding is one space, with padding(n) giving n+1 spaces of padding? The documentation says otherwise, so I'm a little confused.

    use std::io::{Write, stdout};
    
    use tabwriter::TabWriter;
    
    fn main() {
        let mut tw = TabWriter::new(stdout()).padding(0);
        writeln!(tw, "{}\t{}", 1, 2).unwrap();
        tw.flush().unwrap();
    }
    

    Outputs "1 2"

    opened by BartMassey 2
  • MemWriter has been deprecated

    MemWriter has been deprecated

    error[E0433]: failed to resolve. Could not find `MemWriter` in `io`                                      
       --> src/cmds.rs:111:25                           
        |                     
    111 |     let mw = ::std::io::MemWriter::new();     
        |                         ^^^^^^^^^ Could not find `MemWriter` in `io` 
    
    opened by vitiral 2
  • Example in README doesn't work

    Example in README doesn't work

    Attempting to compile the "Simple example" section of the README gives the following errors:

    error[E0599]: no method named `write_str` found for type `tabwriter::TabWriter<std::vec::Vec<u8>>` in the current scope
      --> src/main.rs:10:4
       |
    10 | tw.write_str("
       |    ^^^^^^^^^
    
    error[E0599]: no method named `as_slice` found for type `std::string::String` in the current scope
      --> src/main.rs:20:20
       |
    20 | assert_eq!(written.as_slice(), "
       |                    ^^^^^^^^
    
    opened by royaldark 1
  • Broken link to CSV toolkit example in README.md

    Broken link to CSV toolkit example in README.md

    The link to the CSV toolkit example in README.md points to https://github.com/BurntSushi/xcsv/blob/master/src/table.rs#L37-L40, but that page does not exist. The file appears to have moved to https://github.com/BurntSushi/xsv/blob/master/src/cmd/table.rs, but I'm not sure what lines should be referenced.

    opened by kraai 0
  • Relicense under dual MIT/Apache-2.0

    Relicense under dual MIT/Apache-2.0

    Why?

    The MIT license requires reproducing countless copies of the same copyright header with different names in the copyright field, for every MIT library in use. The Apache license does not have this drawback, and has protections from patent trolls and an explicit contribution licensing clause. However, the Apache license is incompatible with GPLv2. This is why Rust is dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for GPLv2 compat), and doing so would be wise for this project. This also makes this crate suitable for inclusion in the Rust standard distribution and other project using dual MIT/Apache.

    How?

    To do this, get explicit approval from each contributor of copyrightable work (as not all contributions qualify for copyright) and then add the following to your README:

    ## License
    
    Licensed under either of
     * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
     * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
    at your option.
    
    ### Contribution
    
    Unless you explicitly state otherwise, any contribution intentionally submitted
    for inclusion in the work by you shall be dual licensed as above, without any
    additional terms or conditions.
    

    and in your license headers, use the following boilerplate (based on that used in Rust):

    // Copyright (c) 2015 t developers
    // Licensed under the Apache License, Version 2.0
    // <LICENSE-APACHE or
    // http://www.apache.org/licenses/LICENSE-2.0> or the MIT
    // license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
    // at your option. All files in the project carrying such
    // notice may not be copied, modified, or distributed except
    // according to those terms.
    

    And don't forget to update the license metadata in your Cargo.toml!

    Contributor checkoff

    • [ ] @BurntSushi
    opened by emberian 0
  • Trailing cells in right and center alignment mode

    Trailing cells in right and center alignment mode

    Previously, a cell was a block of text to the left of some tab.

    This meant that a table like this:

    aa\tbb
    a\tb
    

    would be formatted as

    aa bb
     a b
    

    in right-alignment mode because the b's were not actually in a cell, and thus didn't get aligned.

    This commit modifies the notion of a "cell" in right- and center-alignment mode to also include text to the right of the last tab on the line.

    This text is now considered part of a cell and aligned accordingly.

    Implemented as describe above, this change would cause many trailing spaces to be printed in right- and center-alignment modes, including on empty lines.

    To alleviate this, trailing spaces in the final cell of a line are not printed.

    fixes #29

    opened by alex-ozdemir 0
  • Right alignment of last column

    Right alignment of last column

    Right alignment of the last column only works when there is a trailing tab on the line. Otherwise the last column is left-aligned which looks strange. If this is a known restriction and not a bug it could possibly be documented.

    bug help wanted 
    opened by mj-64 8
  • Awkwardness with std::fmt::Display?

    Awkwardness with std::fmt::Display?

    I'm trying to use tabwriter inside an impl of std::fmt::Display, and it seems really complex and inefficient. I'm currently doing it like this. Any suggestions on how to clean things up? Ideally I'd like to just write the table directly to the Formatter.

    opened by BartMassey 2
Owner
Andrew Gallant
I love to code.
Andrew Gallant
Fast suffix arrays for Rust (with Unicode support).

suffix Fast linear time & space suffix arrays for Rust. Supports Unicode! Dual-licensed under MIT or the UNLICENSE. Documentation https://docs.rs/suff

Andrew Gallant 207 Dec 26, 2022
An efficient and powerful Rust library for word wrapping text.

Textwrap Textwrap is a library for wrapping and indenting text. It is most often used by command-line programs to format dynamic output nicely so it l

Martin Geisler 322 Dec 26, 2022
⏮ ⏯ ⏭ A Rust library to easily read forwards, backwards or randomly through the lines of huge files.

EasyReader The main goal of this library is to allow long navigations through the lines of large files, freely moving forwards and backwards or gettin

Michele Federici 81 Dec 6, 2022
An implementation of regular expressions for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs.

regex A Rust library for parsing, compiling, and executing regular expressions. Its syntax is similar to Perl-style regular expressions, but lacks a f

The Rust Programming Language 2.6k Jan 8, 2023
Natural language detection library for Rust. Try demo online: https://www.greyblake.com/whatlang/

Whatlang Natural language detection for Rust with focus on simplicity and performance. Content Features Get started Documentation Supported languages

Sergey Potapov 805 Dec 28, 2022
Multilingual implementation of RAKE algorithm for Rust

RAKE.rs The library provides a multilingual implementation of Rapid Automatic Keyword Extraction (RAKE) algorithm for Rust. How to Use Append rake to

Navid 26 Dec 16, 2022
A Rust library for generically joining iterables with a separator

joinery A Rust library for generically joining iterables with a separator. Provides the tragically missing string join functionality to rust. extern c

Nathan West 72 Dec 16, 2022
Rust edit distance routines accelerated using SIMD. Supports fast Hamming, Levenshtein, restricted Damerau-Levenshtein, etc. distance calculations and string search.

triple_accel Rust edit distance routines accelerated using SIMD. Supports fast Hamming, Levenshtein, restricted Damerau-Levenshtein, etc. distance cal

Daniel Liu 75 Jan 8, 2023
Rust native ready-to-use NLP pipelines and transformer-based models (BERT, DistilBERT, GPT2,...)

rust-bert Rust native Transformer-based models implementation. Port of Hugging Face's Transformers library, using the tch-rs crate and pre-processing

null 1.3k Jan 8, 2023
👄 The most accurate natural language detection library in the Rust ecosystem, suitable for long and short text alike

Table of Contents What does this library do? Why does this library exist? Which languages are supported? How good is it? Why is it better than other l

Peter M. Stahl 569 Jan 3, 2023
Snips NLU rust implementation

Snips NLU Rust Installation Add it to your Cargo.toml: [dependencies] snips-nlu-lib = { git = "https://github.com/snipsco/snips-nlu-rs", branch = "mas

Snips 327 Dec 26, 2022
A fast, low-resource Natural Language Processing and Text Correction library written in Rust.

nlprule A fast, low-resource Natural Language Processing and Error Correction library written in Rust. nlprule implements a rule- and lookup-based app

Benjamin Minixhofer 496 Jan 8, 2023
A fast implementation of Aho-Corasick in Rust.

aho-corasick A library for finding occurrences of many patterns at once with SIMD acceleration in some cases. This library provides multiple pattern s

Andrew Gallant 662 Dec 31, 2022
Natural Language Processing for Rust

rs-natural Natural language processing library written in Rust. Still very much a work in progress. Basically an experiment, but hey maybe something c

Chris Tramel 211 Dec 28, 2022
finalfusion embeddings in Rust

Introduction finalfusion is a crate for reading, writing, and using embeddings in Rust. finalfusion primarily works with its own format which supports

finalfusion 55 Jan 2, 2023
Rust-tokenizer offers high-performance tokenizers for modern language models, including WordPiece, Byte-Pair Encoding (BPE) and Unigram (SentencePiece) models

rust-tokenizers Rust-tokenizer offers high-performance tokenizers for modern language models, including WordPiece, Byte-Pair Encoding (BPE) and Unigra

null 165 Jan 1, 2023
Context-sensitive word embeddings with subwords. In Rust.

finalfrontier Introduction finalfrontier is a Rust program for training word embeddings. finalfrontier currently has the following features: Models: s

finalfusion 74 Dec 29, 2022
Simple NLP in Rust with Python bindings

vtext NLP in Rust with Python bindings This package aims to provide a high performance toolkit for ingesting textual data for machine learning applica

Roman Yurchak 133 Jan 3, 2023
Neural network transition-based dependency parser (in Rust)

dpar Introduction dpar is a neural network transition-based dependency parser. The original Go version can be found in the oldgo branch. Dependencies

Daniël de Kok 41 Jan 25, 2022