Code Monkey home page Code Monkey logo

tabulate's Introduction

ci status standard license version

Source for the above image can be found here

Table of Contents

Quick Start

tabulate is a header-only library. Just add include/ to your include_directories and you should be good to go. A single header file version is also available in single_include/.

NOTE Tabulate supports >=C++11. The rest of this README, however, assumes C++17 support.

Create a Table object and call Table.add_rows to add rows to your table.

#include <tabulate/table.hpp>
using namespace tabulate;

int main() {

  Table universal_constants;

  universal_constants.add_row({"Quantity", "Value"});
  universal_constants.add_row({"Characteristic impedance of vacuum", "376.730 313 461... Ω"});
  universal_constants.add_row({"Electric constant (permittivity of free space)", "8.854 187 817... × 10⁻¹²F·m⁻¹"});
  universal_constants.add_row({"Magnetic constant (permeability of free space)", "4π × 10⁻⁷ N·A⁻² = 1.2566 370 614... × 10⁻⁶ N·A⁻²"});
  universal_constants.add_row({"Gravitational constant (Newtonian constant of gravitation)", "6.6742(10) × 10⁻¹¹m³·kg⁻¹·s⁻²"});
  universal_constants.add_row({"Planck's constant", "6.626 0693(11) × 10⁻³⁴ J·s"});
  universal_constants.add_row({"Dirac's constant", "1.054 571 68(18) × 10⁻³⁴ J·s"});
  universal_constants.add_row({"Speed of light in vacuum", "299 792 458 m·s⁻¹"});

Use RowStream to format table data with stream insertion.

  employees.add_row({"Emp. ID", "First Name", "Last Name", "Department / Business Unit", "Pay Rate"});
  employees.add_row(RowStream{} << 101 << "Donald" << "Patrick" << "Finance" << 59.6154);
  employees.add_row(RowStream{} << 102 << "Rachel" << "Williams" << "Marketing and Operational\nLogistics Planning" << 34.9707);
  employees.add_row(RowStream{} << 103 << "Ian" << "Jacob" << department << 57.0048);

You can format this table using Table.format() which returns a Format object. Using a fluent interface, format properties of the table, e.g., borders, font styles, colors etc.

  universal_constants.format()
    .font_style({FontStyle::bold})
    .border_top(" ")
    .border_bottom(" ")
    .border_left(" ")
    .border_right(" ")
    .corner(" ");

You can access rows in the table using Table[row_index]. This will return a Row object on which you can similarly call Row.format() to format properties of all the cells in that row.

Now, let's format the header of the table. The following code changes the font background of the header row to red, aligns the cell contents to center and applies a padding to the top and bottom of the row.

  universal_constants[0].format()
    .padding_top(1)
    .padding_bottom(1)
    .font_align(FontAlign::center)
    .font_style({FontStyle::underline})
    .font_background_color(Color::red);

Calling Table.column(index) will return a Column object. Similar to rows, you can use Column.format() to format all the cells in that column.

Now, let's change the font color of the second column to yellow:

  universal_constants.column(1).format()
    .font_color(Color::yellow);

You can access cells by indexing twice from a table: From a row using Table[row_index][col_index] or from a column using Table.column(col_index)[cell_index]. Just like rows, columns, and tables, you can use Cell.format() to format individual cells

  universal_constants[0][1].format()
    .font_background_color(Color::blue)
    .font_color(Color::white);
}

Print the table using the stream operator<< like so:

  std::cout << universal_constants << std::endl;

You could also use Table.print(stream) to print the table, e.g., universal_constants.print(std::cout).

Formatting Options

Style Inheritance Model

Formatting in tabulate follows a simple style-inheritance model. When rendering each cell:

  1. Apply cell formatting if specified
  2. If no cell formatting is specified, apply its parent row formatting
  3. If no row formatting is specified, apply its parent table formatting
  4. If no table formatting is specified, apply the default table formatting

This enables overriding the formatting for a particular cell even though row or table formatting is specified, e.g., when an entire row is colored yellow but you want a specific cell to be colored red.

Word Wrapping

tabulate supports automatic word-wrapping when printing cells.

Although word-wrapping is automatic, there is a simple override. Automatic word-wrapping is used only if the cell contents do not have any embedded newline \n characters. So, you can embed newline characters in the cell contents and enforce the word-wrapping manually.

#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table table;

  table.add_row({"This paragraph contains a veryveryveryveryveryverylong word. The long word will "
                 "break and word wrap to the next line.",
                 "This paragraph \nhas embedded '\\n' \ncharacters and\n will break\n exactly "
                 "where\n you want it\n to\n break."});

  table[0][0].format().width(20);
  table[0][1].format().width(50);

  std::cout << table << std::endl;
}
  • The above table has 1 row and 2 columns.
  • The first cell has automatic word-wrapping.
  • The second cell uses the embedded newline characters in the cell contents - even though the second column has plenty of space (50 characters width), it uses user-provided newline characters to break into new lines and enforce the cell style.
  • NOTE: Whether word-wrapping is automatic or not, tabulate performs a trim operation on each line of each cell to remove whitespace characters from either side of line.

NOTE: Both columns in the above table are left-aligned by default. This, however, can be easily changed.

Font Alignment

tabulate supports three font alignment settings: left, center, and right. By default, all table content is left-aligned. To align cells, use .format().font_align(alignment).

#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table movies;
  movies.add_row({"S/N", "Movie Name", "Director", "Estimated Budget", "Release Date"});
  movies.add_row({"tt1979376", "Toy Story 4", "Josh Cooley", "$200,000,000", "21 June 2019"});
  movies.add_row({"tt3263904", "Sully", "Clint Eastwood", "$60,000,000", "9 September 2016"});
  movies.add_row({"tt1535109", "Captain Phillips", "Paul Greengrass", "$55,000,000", " 11 October 2013"});

  // center align 'Director' column
  movies.column(2).format()
    .font_align(FontAlign::center);

  // right align 'Estimated Budget' column
  movies.column(3).format()
    .font_align(FontAlign::right);

  // right align 'Release Date' column
  movies.column(4).format()
    .font_align(FontAlign::right);

  // center-align and color header cells
  for (size_t i = 0; i < 5; ++i) {
    movies[0][i].format()
      .font_color(Color::yellow)
      .font_align(FontAlign::center)
      .font_style({FontStyle::bold});
  }

  std::cout << movies << std::endl;
}

Font Styles

tabulate supports 8 font styles: bold, dark, italic, underline, blink, reverse, concealed, crossed. Depending on the terminal (or terminal settings), some of these might not work.

To apply a font style, simply call .format().font_style({...}). The font_style method takes a vector of font styles. This allows to apply multiple font styles to a cell, e.g., bold and italic.

#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table styled_table;
  styled_table.add_row({"Bold", "Italic", "Bold & Italic", "Blinking"});
  styled_table.add_row({"Underline", "Crossed", "Dark", "Bold, Italic & Underlined"});

  styled_table[0][0].format()
    .font_style({FontStyle::bold});

  styled_table[0][1].format()
    .font_style({FontStyle::italic});

  styled_table[0][2].format()
    .font_style({FontStyle::bold, FontStyle::italic});

  styled_table[0][3].format()
    .font_style({FontStyle::blink});

  styled_table[1][0].format()
    .font_style({FontStyle::underline});

  styled_table[1][1].format()
    .font_style({FontStyle::crossed});

  styled_table[1][2].format()
    .font_style({FontStyle::dark});


  styled_table[1][3].format()
    .font_style({FontStyle::bold, FontStyle::italic, FontStyle::underline});

  std::cout << styled_table << std::endl;

}

NOTE: Font styles are applied to the entire cell. Unlike HTML, you cannot currently apply styles to specific words in a cell.

Cell Colors

There are a number of methods in the Format object to color cells - foreground and background - for font, borders, corners, and column separators. Thanks to termcolor, tabulate supports 8 colors: grey, red, green, yellow, blue, magenta, cyan, and white. The look of these colors vary depending on your terminal.

For font, border, and corners, you can call .format().<element>_color(value) to set the foreground color and .format().<element>_background_color(value) to set the background color. Here's an example:

#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table colors;

  colors.add_row({"Font Color is Red", "Font Color is Blue", "Font Color is Green"});
  colors.add_row({"Everything is Red", "Everything is Blue", "Everything is Green"});
  colors.add_row({"Font Background is Red", "Font Background is Blue", "Font Background is Green"});

  colors[0][0].format()
    .font_color(Color::red)
    .font_style({FontStyle::bold});
  colors[0][1].format()
    .font_color(Color::blue)
    .font_style({FontStyle::bold});
  colors[0][2].format()
    .font_color(Color::green)
    .font_style({FontStyle::bold});

  colors[1][0].format()
    .border_left_color(Color::red)
    .border_left_background_color(Color::red)
    .font_background_color(Color::red)
    .font_color(Color::red);

  colors[1][1].format()
    .border_left_color(Color::blue)
    .border_left_background_color(Color::blue)
    .font_background_color(Color::blue)
    .font_color(Color::blue);

  colors[1][2].format()
    .border_left_color(Color::green)
    .border_left_background_color(Color::green)
    .font_background_color(Color::green)
    .font_color(Color::green)
    .border_right_color(Color::green)
    .border_right_background_color(Color::green);

  colors[2][0].format()
    .font_background_color(Color::red)
    .font_style({FontStyle::bold});
  colors[2][1].format()
    .font_background_color(Color::blue)
    .font_style({FontStyle::bold});
  colors[2][2].format()
    .font_background_color(Color::green)
    .font_style({FontStyle::bold});

  std::cout << colors << std::endl;
}

Borders and Corners

tabulate allows for fine control over borders and corners. For each border and corner, you can set the text, color, and background color.

NOTE: You can use .corner(..), .corner_color(..), and .corner_background_color(..) to set a common style for all corners. Similarly, you can use .border(..), .border_color(..) and .border_background_color(..) to set a common style for all borders.

NOTE: Note the use of .format().multi_byte_characters(true). Use this when you know your table has multi-byte characters. This is an opt-in because the calculation of column width when dealing with multi-byte characters is more involved and you don't want to pay the performance penalty unless you need it. Just like any other format setting, you can set this at the table-level, row-level, or on a per-cell basis.

Here's an example where each border and corner is individually styled:

#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table table;

  table.add_row({"ᛏᚺᛁᛊ ᛁᛊ ᚨ ᛊᛏᛟᚱy ᛟᚠᚨ ᛒᛖᚨᚱ ᚨᚾᛞ\n"
                 "ᚨ ᚹᛟᛚᚠ, ᚹᚺᛟ ᚹᚨᚾᛞᛖᚱᛖᛞ ᛏᚺᛖ\n"
                 "ᚱᛖᚨᛚᛗᛊ ᚾᛁᚾᛖ ᛏᛟ ᚠᚢᛚᚠᛁᛚᛚ ᚨ ᛈᚱᛟᛗᛁᛊᛖ\n"
                 "ᛏᛟ ᛟᚾᛖ ᛒᛖᚠᛟᚱᛖ; ᛏᚺᛖy ᚹᚨᛚᚲ ᛏᚺᛖ\n"
                 "ᛏᚹᛁᛚᛁᚷᚺᛏ ᛈᚨᛏᚺ, ᛞᛖᛊᛏᛁᚾᛖᛞ ᛏᛟ\n"
                 "ᛞᛁᛊcᛟᚹᛖᚱ ᛏᚺᛖ ᛏᚱᚢᛏᚺ\nᛏᚺᚨᛏ ᛁᛊ ᛏᛟ cᛟᛗᛖ."});

  table.format()
      .multi_byte_characters(true)
      // Font styling
      .font_style({FontStyle::bold, FontStyle::dark})
      .font_align(FontAlign::center)
      .font_color(Color::red)
      .font_background_color(Color::yellow)
      // Corners
      .corner_top_left("")
      .corner_top_right("")
      .corner_bottom_left("")
      .corner_bottom_right("")
      .corner_top_left_color(Color::cyan)
      .corner_top_right_color(Color::yellow)
      .corner_bottom_left_color(Color::green)
      .corner_bottom_right_color(Color::red)
      // Borders
      .border_top("")
      .border_bottom("")
      .border_left("")
      .border_right("")
      .border_left_color(Color::yellow)
      .border_right_color(Color::green)
      .border_top_color(Color::cyan)
      .border_bottom_color(Color::red);

  std::cout << table << std::endl;
}

Range-based Iteration

Hand-picking and formatting cells using operator[] gets tedious very quickly. To ease this, tabulate supports range-based iteration on tables, rows, and columns. Quickly iterate over rows and columns to format cells.

#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table table;

  table.add_row({"Company", "Contact", "Country"});
  table.add_row({"Alfreds Futterkiste", "Maria Anders", "Germany"});
  table.add_row({"Centro comercial Moctezuma", "Francisco Chang", "Mexico"});
  table.add_row({"Ernst Handel", "Roland Mendel", "Austria"});
  table.add_row({"Island Trading", "Helen Bennett", "UK"});
  table.add_row({"Laughing Bacchus Winecellars", "Yoshi Tannamuri", "Canada"});
  table.add_row({"Magazzini Alimentari Riuniti", "Giovanni Rovelli", "Italy"});

  // Set width of cells in each column
  table.column(0).format().width(40);
  table.column(1).format().width(30);
  table.column(2).format().width(30);

  // Iterate over cells in the first row
  for (auto& cell : table[0]) {
    cell.format()
      .font_style({FontStyle::underline})
      .font_align(FontAlign::center);
  }

  // Iterator over cells in the first column
  for (auto& cell : table.column(0)) {
    if (cell.get_text() != "Company") {
      cell.format()
        .font_align(FontAlign::right);
    }
  }

  // Iterate over rows in the table
  size_t index = 0;
  for (auto& row : table) {
    row.format()
      .font_style({FontStyle::bold});

    // Set blue background color for alternate rows
    if (index > 0 && index % 2 == 0) {
      for (auto& cell : row) {
        cell.format()
          .font_background_color(Color::blue);
      }      
    }
    index += 1;
  }

  std::cout << table << std::endl;
}

Nested Tables

Table.add_row(...) takes either a std::string or a tabulate::Table. This can be used to nest tables within tables. Here's an example program that prints a UML class diagram using tabulate. Note the use of font alignment, style, and width settings to generate a diagram that looks centered and great.

#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table class_diagram;

  // Global styling
  class_diagram.format().font_style({FontStyle::bold}).font_align(FontAlign::center).width(60);

  // Animal class
  Table animal;
  animal.add_row({"Animal"});
  animal[0].format().font_align(FontAlign::center);

  // Animal properties nested table
  Table animal_properties;
  animal_properties.format().width(20);
  animal_properties.add_row({"+age: Int"});
  animal_properties.add_row({"+gender: String"});
  animal_properties[1].format().hide_border_top();

  // Animal methods nested table
  Table animal_methods;
  animal_methods.format().width(20);
  animal_methods.add_row({"+isMammal()"});
  animal_methods.add_row({"+mate()"});
  animal_methods[1].format().hide_border_top();

  animal.add_row({animal_properties});
  animal.add_row({animal_methods});
  animal[2].format().hide_border_top();

  class_diagram.add_row({animal});

  // Add rows in the class diagram for the up-facing arrow
  // THanks to center alignment, these will align just fine
  class_diagram.add_row({""});
  class_diagram[1][0].format().hide_border_top().multi_byte_characters(true); // ▲ is multi-byte
  
  class_diagram.add_row({"|"});
  class_diagram[2].format().hide_border_top();
  class_diagram.add_row({"|"});
  class_diagram[3].format().hide_border_top();

  // Duck class
  Table duck;
  duck.add_row({"Duck"});
  duck[0].format().font_align(FontAlign::center);

  // Duck proeperties nested table
  Table duck_properties;
  duck_properties.format().width(40);
  duck_properties.add_row({"+beakColor: String = \"yellow\""});

  // Duck methods nested table
  Table duck_methods;
  duck_methods.format().width(40);
  duck_methods.add_row({"+swim()"});
  duck_methods.add_row({"+quack()"});
  duck_methods[1].format().hide_border_top();

  duck.add_row({duck_properties});
  duck.add_row({duck_methods});
  duck[2].format().hide_border_top();

  class_diagram.add_row({duck});
  class_diagram[4].format().hide_border_top();

  std::cout << class_diagram << std::endl;
}

UTF-8 Support

In *nix, wcswidth is used to compute the display width of multi-byte characters. Column alignment works well when your system supports the necessary locale, e.g., I've noticed on MacOS 10 there is no Arabic locale (searched with locale -a) and this ends up causing alignment issues when using Arabic text, e.g., "ٲنَا بحِبَّك (Ana bahebak)" in tables.

The following table prints the phrase I love you in different languages. Note the use of .format().multi_byte_characters(true) for the second column. Remember to do this when dealing with multi-byte characters.

#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table table;

  table.format().corner("")
    .font_style({FontStyle::bold})
    .corner_color(Color::magenta)
    .border_color(Color::magenta);

  table.add_row({"English", "I love you"});
  table.add_row({"French", "Je t’aime"});
  table.add_row({"Spanish", "Te amo"});
  table.add_row({"German", "Ich liebe Dich"});
  table.add_row({"Mandarin Chinese", "我爱你"});
  table.add_row({"Japanese", "愛してる"});
  table.add_row({"Korean", "사랑해 (Saranghae)"});
  table.add_row({"Greek", "Σ΄αγαπώ (Se agapo)"});
  table.add_row({"Italian", "Ti amo"});
  table.add_row({"Russian", "Я тебя люблю (Ya tebya liubliu)"});
  table.add_row({"Hebrew", "אני אוהב אותך (Ani ohev otakh)"});

  // Column 1 is using mult-byte characters
  table.column(1).format()
    .multi_byte_characters(true);

  std::cout << table << std::endl;
}

You can explicitly set the locale for a cell using .format().locale(value). Note that the locale string is system-specific. So, the following code might throw std::runtime_error locale::facet::_S_create_c_locale name not valid on your system.

  // Set English-US locale for first column
  table.column(0).format().locale("en_US.UTF-8");
  table[0][1].format().locale("en_US.UTF-8");

  // Set locale for individual cells
  table[1][1].format().locale("fr_FR.UTF-8");  // French
  table[2][1].format().locale("es_ES.UTF-8");  // Spanish
  table[3][1].format().locale("de_DE.UTF-8");  // German
  table[4][1].format().locale("zh_CN.UTF-8");  // Chinese
  table[5][1].format().locale("ja_JP.UTF-8");  // Japanese
  table[6][1].format().locale("ko_KR.UTF-8");  // Korean
  table[7][1].format().locale("el_GR.UTF-8");  // Greek
  table[8][1].format().locale("it_IT.UTF-8");  // Italian
  table[9][1].format().locale("ru_RU.UTF-8");  // Russian
  table[10][1].format().locale("he_IL.UTF-8"); // Hebrew

Exporters

Markdown

Tables can be exported to GitHub-flavored markdown using a MarkdownExporter. Simply create an exporter object and call exporter.dump(table) to generate a Markdown-formatted std::string.

#include <tabulate/markdown_exporter.hpp>
using namespace tabulate;

int main() {
  Table movies;
  movies.add_row({"S/N", "Movie Name", "Director", "Estimated Budget", "Release Date"});  
  movies.add_row({"tt1979376", "Toy Story 4", "Josh Cooley", "$200,000,000", "21 June 2019"});
  movies.add_row({"tt3263904", "Sully", "Clint Eastwood", "$60,000,000", "9 September 2016"});
  movies.add_row(
      {"tt1535109", "Captain Phillips", "Paul Greengrass", "$55,000,000", " 11 October 2013"});

  // center align 'Director' column
  movies.column(2).format().font_align(FontAlign::center);

  // right align 'Estimated Budget' column
  movies.column(3).format().font_align(FontAlign::right);

  // right align 'Release Date' column
  movies.column(4).format().font_align(FontAlign::right);

  // Color header cells
  for (size_t i = 0; i < 5; ++i) {
    movies[0][i].format().font_color(Color::yellow).font_style({FontStyle::bold});
  }

  // Export to Markdown
  MarkdownExporter exporter;
  auto markdown = exporter.dump(movies);

  // tabulate::table
  std::cout << movies << "\n\n";

  // Exported Markdown
  std::cout << markdown << std::endl;
}

The above table renders in Markdown like below.

NOTE: Unlike tabulate, you cannot align individual cells in Markdown. Alignment is on a per-column basis. Markdown allows a second header row where such column-wise alignment can be specified. The MarkdownExporter uses the formatting of the header cells in the original tabulate::Table to decide how to align each column. As per the Markdown spec, columns are left-aligned by default.

S/N Movie Name Director Estimated Budget Release Date
tt1979376 Toy Story 4 Josh Cooley $200,000,000 21 June 2019
tt3263904 Sully Clint Eastwood $60,000,000 9 September 2016
tt1535109 Captain Phillips Paul Greengrass $55,000,000 11 October 2013

AsciiDoc

Tabulate can export tables as AsciiDoc using an AsciiDocExporter.

#include <tabulate/asciidoc_exporter.hpp>
using namespace tabulate;

int main() {
  Table movies;
  movies.add_row({"S/N", "Movie Name", "Director", "Estimated Budget", "Release Date"});
  movies.add_row({"tt1979376", "Toy Story 4", "Josh Cooley", "$200,000,000", "21 June 2019"});
  movies.add_row({"tt3263904", "Sully", "Clint Eastwood", "$60,000,000", "9 September 2016"});
  movies.add_row(
      {"tt1535109", "Captain Phillips", "Paul Greengrass", "$55,000,000", " 11 October 2013"});

  // center align 'Director' column
  movies.column(2).format().font_align(FontAlign::center);

  // right align 'Estimated Budget' column
  movies.column(3).format().font_align(FontAlign::right);

  // right align 'Release Date' column
  movies.column(4).format().font_align(FontAlign::right);

  movies[1][2].format().font_style({FontStyle::bold, FontStyle::italic});
  movies[2][1].format().font_style({FontStyle::italic});

  // Color header cells
  for (size_t i = 0; i < 5; ++i) {
    movies[0][i]
        .format()
        .font_color(Color::white)
        .font_style({FontStyle::bold})
        .background_color(Color::blue);
  }

  AsciiDocExporter exporter;
  auto asciidoc = exporter.dump(movies);

  // tabulate::table
  std::cout << movies << "\n\n";

  // Exported AsciiDoc
  std::cout << asciidoc << std::endl;
}

Below is the export of the example above:

[cols="<,<,^,>,>"]
|===
|*S/N*|*Movie Name*|*Director*|*Estimated Budget*|*Release Date*

|tt1979376|Toy Story 4|*_Josh Cooley_*|$200,000,000|21 June 2019
|tt3263904|_Sully_|Clint Eastwood|$60,000,000|9 September 2016
|tt1535109|Captain Phillips|Paul Greengrass|$55,000,000| 11 October 2013
|===

The rendered output you can see here: http://tpcg.io/pbbfU3ks

NOTE Alignment is only supported per column. The font styles FontStyle::bold and FontStyle::italic can be used for each cell, also in combination.

Building Samples

There are a number of samples in the samples/ directory, e.g., Mario. You can build these samples by running the following commands.

mkdir build
cd build
cmake -DSAMPLES=ON -DUSE_CPP17=ON ..
make
./samples/mario

Note the USE_CPP17 variable. Tabulate uses std::variant and std::optional. If you do not have C++17 compiler support for these data structures, build without this flag. Tabulate will then use variant-lite and optional-lite.

Generating Single Header

python3 utils/amalgamate/amalgamate.py -c single_include.json -s .

Contributing

Contributions are welcome, have a look at the CONTRIBUTING.md document for more information.

License

The project is available under the MIT license.

tabulate's People

Contributors

ahfriedman avatar edisonhello avatar holasoyender avatar huytuan123 avatar marimeireles avatar mohsenomidi avatar p-ranav avatar rlalik avatar silverqx avatar stehfyn 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  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

tabulate's Issues

[cosmetic] tabulate generates warning with -Wall

Hi,

First, wonderful library !
Found out that tabulate code generates some warning when compield with -Wall.

tabulate-src/include/tabulate/table_internal.hpp: In static member function ‘static void tabulate::Printer::print_table(std::ostream&, tabulate::TableInternal&)’:
tabulate-src/include/tabulate/table_internal.hpp:218:14: warning: unused variable ‘column_width’ [-Wunused-variable]
  218 |         auto column_width = column_widths[j];
      |              ^~~~~~~~~~~~
tabulate-src/include/tabulate/table_internal.hpp: In static member function ‘static void tabulate::Printer::print_row_in_cell(std::ostream&, tabulate::TableInternal&, const std::pair<long unsigned int, long unsigned int>&, const std::pair<long unsigned int, long unsigned int>&, size_t, size_t)’:
tabulate-src/include/tabulate/table_internal.hpp:244:8: warning: unused variable ‘row_height’ [-Wunused-variable]
  244 |   auto row_height = dimension.first;
      |        ^~~~~~~~~~
tabulate-src/include/tabulate/table_internal.hpp:256:8: warning: unused variable ‘padding_bottom’ [-Wunused-variable]
  256 |   auto padding_bottom = format.padding_bottom_.value();
      |        ^~~~~~~~~~~~~~

Nothing very drastic but it could be cool if the library could compile warning free with -Wall.

Best regards

Improve multi-byte character support in Windows

Description

  • In *nix, tabulate uses wcswidth to compute the display width for multi-byte characters
  • In Windows, tabulate computes the number of multi-byte characters correctly but this is not the same as the "display width", i.e., number of columns to be occupied by the cell contents.

References

Visual Studio 2017 fails to compile

I'm using the latest C++ language and tried many different linker configurations to get rid of the errors below. I can't seem to get the example program to build:

c:\users\bountyhunter\code\open_netbattle_api\client\extern\tabulate\include\tabulate\format.hpp(715): error C2672: 'std::isspace': no matching overloaded function found
c:\users\bountyhunter\code\open_netbattle_api\client\extern\tabulate\include\tabulate\format.hpp(715): error C2780: 'bool std::isspace(_Elem,const std::locale &)': expects 2 arguments - 1 provided
c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\locale(253): note: see declaration of 'std::isspace'
c:\users\bountyhunter\code\open_netbattle_api\client\extern\tabulate\include\tabulate\format.hpp(723): error C2672: 'std::isspace': no matching overloaded function found
c:\users\bountyhunter\code\open_netbattle_api\client\extern\tabulate\include\tabulate\format.hpp(723): error C2780: 'bool std::isspace(_Elem,const std::locale &)': expects 2 arguments - 1 provided
c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\locale(253): note: see declaration of 'std::isspace'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(103): warning C4005: 'AF_IPX': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(457): note: see previous definition of 'AF_IPX'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(147): warning C4005: 'AF_MAX': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(476): note: see previous definition of 'AF_MAX'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(185): warning C4005: 'SO_DONTLINGER': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(399): note: see previous definition of 'SO_DONTLINGER'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(235): error C2011: 'sockaddr': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(1007): note: see declaration of 'sockaddr'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(437): error C2059: syntax error: 'constant'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(437): error C3805: 'constant': unexpected token, expected either '}' or a ','
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(572): warning C4005: 'IN_CLASSA': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(284): note: see previous definition of 'IN_CLASSA'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(578): warning C4005: 'IN_CLASSB': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(290): note: see previous definition of 'IN_CLASSB'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(584): warning C4005: 'IN_CLASSC': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(296): note: see previous definition of 'IN_CLASSC'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(595): warning C4005: 'INADDR_ANY': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(301): note: see previous definition of 'INADDR_ANY'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(597): warning C4005: 'INADDR_BROADCAST': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(303): note: see previous definition of 'INADDR_BROADCAST'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2def.h(633): error C2011: 'sockaddr_in': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(1011): note: see declaration of 'sockaddr_in'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(136): error C2011: 'fd_set': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(1019): note: see declaration of 'fd_set'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(156): warning C4005: 'FD_CLR': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(94): note: see previous definition of 'FD_CLR'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(171): warning C4005: 'FD_SET': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(99): note: see previous definition of 'FD_SET'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(180): error C2011: 'timeval': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(1035): note: see declaration of 'timeval'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(236): error C2011: 'hostent': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(1023): note: see declaration of 'hostent'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(249): error C2011: 'netent': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(177): note: see declaration of 'netent'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(256): error C2011: 'servent': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(1027): note: see declaration of 'servent'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(268): error C2011: 'protoent': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(1031): note: see declaration of 'protoent'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(364): error C2011: 'WSAData': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(319): note: see declaration of 'WSAData'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(462): error C2011: 'sockproto': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(491): note: see declaration of 'sockproto'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(504): error C2011: 'linger': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(1015): note: see declaration of 'linger'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(517): warning C4005: 'SOMAXCONN': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(541): note: see previous definition of 'SOMAXCONN'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(552): warning C4005: 'FD_READ': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(559): note: see previous definition of 'FD_READ'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(555): warning C4005: 'FD_WRITE': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(560): note: see previous definition of 'FD_WRITE'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(558): warning C4005: 'FD_OOB': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(561): note: see previous definition of 'FD_OOB'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(561): warning C4005: 'FD_ACCEPT': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(562): note: see previous definition of 'FD_ACCEPT'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(564): warning C4005: 'FD_CONNECT': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(563): note: see previous definition of 'FD_CONNECT'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(567): warning C4005: 'FD_CLOSE': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(564): note: see previous definition of 'FD_CLOSE'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1625): error C2375: 'accept': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(739): note: see declaration of 'accept'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1647): error C2375: 'bind': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(744): note: see declaration of 'bind'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1668): error C2375: 'closesocket': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(749): note: see declaration of 'closesocket'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1685): error C2375: 'connect': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(751): note: see declaration of 'connect'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1706): error C2375: 'ioctlsocket': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(756): note: see declaration of 'ioctlsocket'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1729): error C2375: 'getpeername': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(761): note: see declaration of 'getpeername'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1750): error C2375: 'getsockname': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(766): note: see declaration of 'getsockname'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1771): error C2375: 'getsockopt': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(771): note: see declaration of 'getsockopt'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1796): error C2375: 'htonl': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(778): note: see declaration of 'htonl'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1813): error C2375: 'htons': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(780): note: see declaration of 'htons'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1831): error C2375: 'inet_addr': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(782): note: see declaration of 'inet_addr'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1849): error C2375: 'inet_ntoa': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(784): note: see declaration of 'inet_ntoa'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1949): error C2375: 'listen': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(786): note: see declaration of 'listen'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1968): error C2375: 'ntohl': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(790): note: see declaration of 'ntohl'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(1985): error C2375: 'ntohs': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(792): note: see declaration of 'ntohs'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2002): error C2375: 'recv': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(794): note: see declaration of 'recv'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2025): error C2375: 'recvfrom': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(800): note: see declaration of 'recvfrom'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2052): error C2375: 'select': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(808): note: see declaration of 'select'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2077): error C2375: 'send': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(815): note: see declaration of 'send'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2100): error C2375: 'sendto': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(821): note: see declaration of 'sendto'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2127): error C2375: 'setsockopt': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(829): note: see declaration of 'setsockopt'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2152): error C2375: 'shutdown': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(836): note: see declaration of 'shutdown'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2172): error C2375: 'socket': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(840): note: see declaration of 'socket'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2197): error C2375: 'gethostbyaddr': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(847): note: see declaration of 'gethostbyaddr'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2219): error C2375: 'gethostbyname': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(852): note: see declaration of 'gethostbyname'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2236): error C2375: 'gethostname': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(854): note: see declaration of 'gethostname'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2276): error C2375: 'getservbyport': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(858): note: see declaration of 'getservbyport'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2295): error C2375: 'getservbyname': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(862): note: see declaration of 'getservbyname'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2314): error C2375: 'getprotobynumber': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(866): note: see declaration of 'getprotobynumber'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2331): error C2375: 'getprotobyname': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(868): note: see declaration of 'getprotobyname'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2351): error C2375: 'WSAStartup': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(872): note: see declaration of 'WSAStartup'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2371): error C2375: 'WSACleanup': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(876): note: see declaration of 'WSACleanup'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2388): error C2375: 'WSASetLastError': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(878): note: see declaration of 'WSASetLastError'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2405): error C2375: 'WSAGetLastError': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(880): note: see declaration of 'WSAGetLastError'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2426): error C2375: 'WSAIsBlocking': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(882): note: see declaration of 'WSAIsBlocking'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2444): error C2375: 'WSAUnhookBlockingHook': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(884): note: see declaration of 'WSAUnhookBlockingHook'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2462): error C2375: 'WSASetBlockingHook': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(886): note: see declaration of 'WSASetBlockingHook'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2480): error C2375: 'WSACancelBlockingCall': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(888): note: see declaration of 'WSACancelBlockingCall'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2498): error C2375: 'WSAAsyncGetServByName': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(890): note: see declaration of 'WSAAsyncGetServByName'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2526): error C2375: 'WSAAsyncGetServByPort': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(898): note: see declaration of 'WSAAsyncGetServByPort'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2554): error C2375: 'WSAAsyncGetProtoByName': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(906): note: see declaration of 'WSAAsyncGetProtoByName'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2580): error C2375: 'WSAAsyncGetProtoByNumber': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(913): note: see declaration of 'WSAAsyncGetProtoByNumber'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2606): error C2375: 'WSAAsyncGetHostByName': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(920): note: see declaration of 'WSAAsyncGetHostByName'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2632): error C2375: 'WSAAsyncGetHostByAddr': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(927): note: see declaration of 'WSAAsyncGetHostByAddr'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2662): error C2375: 'WSACancelAsyncRequest': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(936): note: see declaration of 'WSACancelAsyncRequest'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock2.h(2680): error C2375: 'WSAAsyncSelect': redefinition; different linkage
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(938): note: see declaration of 'WSAAsyncSelect'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(80): error C2079: 'sockaddr_gen::Address' uses undefined struct 'sockaddr'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(81): error C2079: 'sockaddr_gen::AddressIn' uses undefined struct 'sockaddr_in'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(135): warning C4005: 'IP_TOS': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(349): note: see previous definition of 'IP_TOS'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(136): warning C4005: 'IP_TTL': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(348): note: see previous definition of 'IP_TTL'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(137): warning C4005: 'IP_MULTICAST_IF': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(343): note: see previous definition of 'IP_MULTICAST_IF'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(138): warning C4005: 'IP_MULTICAST_TTL': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(344): note: see previous definition of 'IP_MULTICAST_TTL'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(139): warning C4005: 'IP_MULTICAST_LOOP': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(345): note: see previous definition of 'IP_MULTICAST_LOOP'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(140): warning C4005: 'IP_ADD_MEMBERSHIP': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(346): note: see previous definition of 'IP_ADD_MEMBERSHIP'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(141): warning C4005: 'IP_DROP_MEMBERSHIP': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(347): note: see previous definition of 'IP_DROP_MEMBERSHIP'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(142): warning C4005: 'IP_DONTFRAGMENT': macro redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(350): note: see previous definition of 'IP_DONTFRAGMENT'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(222): error C2079: '_SOCKADDR_INET::Ipv4' uses undefined struct 'sockaddr_in'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\ws2ipdef.h(738): error C2011: 'ip_mreq': 'struct' type redefinition
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\winsock.h(360): note: see declaration of 'ip_mreq'
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\ws2tcpip.h(744): error C2065: 'WSASetLastError': undeclared identifier
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\ws2tcpip.h(751): error C2065: 'WSASetLastError': undeclared identifier
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\ws2tcpip.h(790): error C2065: 'WSASetLastError': undeclared identifier
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\ws2tcpip.h(797): error C2065: 'WSASetLastError': undeclared identifier
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\ws2tcpip.h(841): error C2065: 'WSASetLastError': undeclared identifier
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\ws2tcpip.h(848): error C2065: 'WSASetLastError': undeclared identifier
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\ws2tcpip.h(889): error C2065: 'WSASetLastError': undeclared identifier
c:\program files (x86)\windows kits\10\include\10.0.17763.0\um\ws2tcpip.h(896): error C2065: 'WSASetLastError': undeclared identifier

Account for padding when calculating width and height

+---------+------------+-----------+-------------+
|         |            |           |             |
| Emp. ID | First Name | Last Name | Department  |
|         |            |           |             |
+-------+----------+---------+-----------+
|101    |Donald    |Patrick  |Finance    |
+-------+----------+---------+-----------+
|102    |Donald    |Patrick  |Marketing  |
+-------+----------+---------+-----------+
|103    |Ian       |Jacob    |Engineering|
+-------+----------+---------+-----------+

New release?

Hey @p-ranav, I'd like to use the shape tuple that's implemented in the master branch.

I'm one of the maintainers of the conda package and ideally it depends on your git releases to have a conda package release.

Do you have any plans for making a new release?

Thanks a lot =)

.clear() method

Hi,
it would be idiomatic to add clear() method.
Implementation would be trivial, unless std::shared_ptr<TableInternal> table_; field is kept somewhere else (it is?).

Is it possible to print table rows sequentially?

Is there a possibility to update the table via adding new rows and flushing them to the standard output during runtime?

The idea is:

  1. Firstly, i added the header row and printed it.
  2. Then made some computations, added a row to the table, then printed that row.
  3. And so on...

I checked the issue #53, but it's not actually what i am looking for.

Adding version file

It may be useful to add a basic cmake version file with e.g. write_basic_package_version_file, so that we can do e.g.

find_package(tabulate 1.3 REQUIRED)

in downstream projects.

New tagged version on github?

Hey @p-ranav, would be nice to have a new version of tabulate on conda :)

I can of course create the new version on conda, but for that I need a new tagged version on github.

Lemme know if you want any help to get this going.

Thanks!

Question - Dynamically Change the tables Content

Dear Contributors,

Thanks for your useful library, I am trying to use this table objects in real-time terminal application and show the columns contents dynamically, when they changed, for example during the execution the contents of tables needs to change (like top command it refreshed the generated output), is it possible to do it ?

Thanks :)

New version?

Hey @p-ranav I know I just asked for a new release, but it was before I realized I had to make those changes for tabulate to work in OSX.
Is it possible to make a new release for now for conda forge grab it automatically?
Thanks a lot!

omit inner borders

Is there a way to suppress inner row and/or column borders in a table?

+--+--+
| A | B |
+--+--+
| 1 | 2 |
| 3 | 4 |
+--+--+

format border commands have no effect

I'm trying to print tables without any border characters. When I use the .format().border_top(" ") etc type of commands, it has no effect and always prints the default +----+ type borders. Similarly using output_table.format().hide_border(); also has no effect, and still prints with the default borders. Am I using this wrong or is it a bug?

Put "requires C++17" with variant and optional utilities support

Modern C++ is C++17 however on the internet "modern" is synonymous with C++11 at minimum. I didn't see any notes anywhere trying to compile but #include <variant> and #include <optional> gave it away...

On that same note, my mingw tools for gcc on windows have the std::optional utility under experimental/*.

I don't think there's a substitute for variant under experimental but a way to be able to swap it out (and optional too) for a custom structures could be achieved for those < C++17. Variants and optional are very simple structures. They're not fundamentally difficult to write and would open the lib up to C++14 at least.

Is it possible to show a table title in the border?

When showing multiple tables it would be nice to see a table name at the top of the table, e.g. in the upper border. At the moment I embed the table in an outer table and put a string as first row as the title. But then you handle with 2 tables.

Color is not working in nested tables

When I try to put a Table with a colored cell into another Table the color is not working anymore.

Here is an example:

#include "tabulate/tabulate.hpp"
#include <iostream>

int main()
{
    using namespace tabulate;

    Table inner;
    inner.add_row({"A"});
    inner[0][0].format().font_color(Color::green);
    std::cout << "Here 'A' is green:\n" << inner << std::endl;

    Table outer;
    outer.add_row({inner});
    std::cout << "Here 'A' is not green:\n" << outer << std::endl;
    return 0;
}

which gives the following output on Ubuntu:

Here 'A' is green:
+---+
| A |
+---+
Here 'A' is not green:
+-------+
| +---+ |
| | A | |
| +---+ |
+-------+

element count and error checking

So I've just recently tried out this library today. Pretty good overall =)

Fairly surprised that there was no way to query the number of rows/columns/cells in a table.
Formatting the last row of a table, I tried a size() or a end()-1 function, like you would see in a standard container.
Frustrating to have to treat a class like a C array, with external variables to keep track of.
Would be good to have a shape() function for the row/column count.

Second, I didn't realise that a variable cell count for each row doesn't work. Something like:
table.add_row("Title").add_row("Key", "Value")
There was no indication that something was wrong until a very generic 'vector subscript out of range' assert triggered.
An assert (for example) within add_row(...) would help prevent a waste of time in the future..

Summay Sample Crashes on Windows

Description

When running the summary.exe sample on Windows 10 in Debug, an assertion is triggered due to a string subscript being out of range. It happens on line 165 of row.hpp:

  if (word_wrapped_text[word_wrapped_text.size() - 1] != '\n')
      estimated_row_height += 1;

There is no check for word_wrapped_text.empty(). If the size of the string is 0, then the program crashes.

Platform

OS: Windows 10
IDE: Visual Studio Code
Compiler: VS 2019 x64, Debug build

Issues I'm facing

Hello, what am I doing wrong? The special characters, emoji and table graph are incorrect
picture:
https://i.imgur.com/f0Fj1Fe.png

the github link isn't underlined or in italic either.
Usual visual studio 16.0.29709

ps. is there a single header available?

Bad output with multilines table when we hide left border

I have some troubles when we hide the left border with a table composed of several lines. With this code :

  Table table;                                                                                                                                                                                                                                                                        
  table.add_row({"key","value1\nvalue2"});                                                                                                                                                                                                                                            
  table[0][0].format().hide_border_left();                                                                                                                                                                                                                                            
  Table table2;                                                                                                                                                                                                                                                                       
  table2.add_row({table});                                                                                                                                                                                                                                                            
  std::cout << "first table :\n" << table << std::endl;                                                                                                                                                                                                                               
  std::cout << "second table :\n" << table2 << std::endl;

My result is :

first table :
+-----+--------+
 key | value1 |
     | value2 |
+-----+--------+
second table :
+------------------+
| +-----+--------+ |
| key | value1 |   |
| | value2 |       |
| +-----+--------+ |
+------------------+

any hints or it’s an issue?

Create ColumnView class for column formatting

Example usage:

table.column(0).format()
    .font_color_predicate([](std::string_view cell) { 
        if (cell == "WARNING") return Color::yellow;
        else if (cell == "ERROR") return Color::red;
        else return Color::white; 
   });

applies font color using a predicate function applied on the cell contents for each cell in that column.

Interactive drawing feature

Hi guys, thanks for sharing this project. I'm now practicing c++ with new features, and it seems that I can learn much from this project. However, as a tabulation tool, it would be great if it can support interactive drawing, like CLING. If it is possible to add this feature in future? #

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.