Comments (13)
Hi!
I think it is not possible to do it at the moment.
At the moment it is possible to change current cell where content will be inserted. In current implementation after that new content will overwrite existing one.
As far as I understand you want to get another behavior - new inserted content should be in a brand new row and the old rows should just go below.
Am I correct that you want to do something like that:
// in c++ api
std::string some_function()
{
fort::char_table tbl;
// populate tbl with data
// add header if some data were really added
if (!tbl.is_empty()) {
tbl.set_cur_cell(0, 0);
tbl << fort::header << "hdr1" << "hdr2" << "hdr3";
}
return tbl.to_string();
}
So as a generalization: you want somehow change (or be able to change) current strategy "overwrite old content with the new one" with the new strategy "insert new content, old content should be preserved and should be below" for content adding functions. Do I understand your problem correctly?
from libfort.
yes the snippet you posted is what I want to do.. For me as an user, the header line should always be the at the top of the table; irrespective of the time when it is added/coded.
int main()
{
fort::char_table table;
table << fort::header << "N"
<< "Driver"
<< "Time"
<< "Avg Speed" << fort::endr;
table << "1"
<< "Ricciardo"
<< "1:25.945"
<< "47.362" << fort::endr;
table << "2"
<< "Hamilton"
<< "1:26.373"
<< "35.02" << fort::endr;
std::cout << table.to_string() << std::endl;
}
please note that to add the header we need to do insert a special attribute to the able i.e. table << fort::header
So the table knows which is the header row. So why must we add the header the very beginning? Why can we just add it whenever we want to?
from libfort.
In my view all these code samples should produce the same output, but they don't:
int main()
{
fort::char_table table;
table << fort::header << "N"
<< "Driver"
<< "Time"
<< "Avg Speed" << fort::endr;
table << "1"
<< "Ricciardo"
<< "1:25.945"
<< "47.362" << fort::endr;
table << "2"
<< "Hamilton"
<< "1:26.373"
<< "35.02" << fort::endr;
std::cout << table.to_string() << std::endl;
}
int main()
{
fort::char_table table;
table << "1"
<< "Ricciardo"
<< "1:25.945"
<< "47.362" << fort::endr;
table << "2"
<< "Hamilton"
<< "1:26.373"
<< "35.02" << fort::endr;
table << fort::header << "N"
<< "Driver"
<< "Time"
<< "Avg Speed" << fort::endr;
std::cout << table.to_string() << std::endl;
}
int main()
{
fort::char_table table;
table << "1"
<< "Ricciardo"
<< "1:25.945"
<< "47.362" << fort::endr;
table << fort::header << "N"
<< "Driver"
<< "Time"
<< "Avg Speed" << fort::endr;
table << "2"
<< "Hamilton"
<< "1:26.373"
<< "35.02" << fort::endr;
std::cout << table.to_string() << std::endl;
}
from libfort.
btw what does << fort::header
do? Apparently its just equivalent to << fort::endr << fort::separator
from libfort.
I got your idea.
It doesn't work the way you think because in libfort there is no a distinct entity such as header. All rows (ordinary rows and headers) are pretty much the same. In libfort header is just a property of the row. Rows that have this property just have another border and that's all.
Approach when we treat headers as some kind of special entity is simply not flexible (e.g. you can't have headers at the bottom, headers in the middle of the table, multiple headers etc.).
fort::header
just sets property for the row (it equivalent to ft_set_cell_prop(table_, FT_CUR_ROW, FT_ANY_ROW, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
in C API)
from libfort.
well, spreadsheet applications for example treat headers as special entities, and allow to customize the header in many ways, for example put it in every page in a printout. :)
from libfort.
Yes, I understand what you mean but as I said this approach with treating headers and ordinary rows differently is more complicated and also I believe current approach is more flexible (e.g. you can have several headers in one table easily:
int main()
{
fort::char_table table;
table << fort::header
<< "N" << "Driver" << "Time" << "Avg Speed" << fort::endr
<< "1" << "Ricciardo" << "1:25.945" << "47.362" << fort::endr
<< "2" << "Hamilton" << "1:26.373" << "35.02" << fort::endr
<< "3" << "Verstappen" << "1:26.469" << "29.78" << fort::endr;
table << fort::header
<< "Some field" << "" << "" << "Avg Speed" << fort::endr
<< "fld1" << "" << "" << "47.362" << fort::endr
<< "fld2" << "" << "" << "29.78" << fort::endr;
table.cell(4, 0).set_cell_span(3);
table.cell(5, 0).set_cell_span(3);
table.cell(6, 0).set_cell_span(3);
std::cout << table.to_string() << std::endl;
}
output:
+---+------------+----------+-----------+
| N | Driver | Time | Avg Speed |
+---+------------+----------+-----------+
| 1 | Ricciardo | 1:25.945 | 47.362 |
| 2 | Hamilton | 1:26.373 | 35.02 |
| 3 | Verstappen | 1:26.469 | 29.78 |
+---+------------+----------+-----------+
| Some field | Avg Speed |
+---------------------------+-----------+
| fld1 | 47.362 |
| fld2 | 29.78 |
+---------------------------+-----------+
All that logic with some special behavior can be added externally in some kind of a wrapper(maybe I am wrong) or user functions. So I prefer to keep things simple and implement the most basic functionality.
Returning to you initial question. I can suggest adding new property to the tables (lets call it CONTENT_ADDING_STRATEGY (with 2 possible values REPLACE(default one) and INSERT). I think this approach is rather flexible. Also it will fit well for some other scenarios.
In this case your code will look like this.
// in c++ api
std::string some_function()
{
fort::char_table tbl;
// populate tbl with data
...
// add header at the top if some data were really added
if (!tbl.is_empty()) {
// you explicitly add header in place of the 0th row,
// all other rows will be shifted
tbl.set_adding_strategy(fort::strategy::INSERT);
tbl.set_cur_cell(0, 0);
tbl << fort::header << "hdr1" << "hdr2" << "hdr3";
}
return tbl.to_string();
}
In case you don't like to set this property (tbl.set_adding_strategy(fort::strategy::INSERT);
)for each table it will be possible set it one time during some initialization procedure:
fort::default_props().set_adding_strategy(fort::strategy::INSERT);
Does it suit you? Or maybe you don't like it?
from libfort.
Hi. I implemented adding_strategies
and merged branch to develop
.
Now it is possible to add rows (and headers) at any time to any place in the table.
Here is a simple example:
int main()
{
fort::char_table table;
table.set_adding_strategy(fort::add_strategy::insert);
// Fill table with data
table << "1" << "2" << fort::endr;
table << "3" << "4" << fort::endr;
// explicitly add header as the top row
table.set_cur_cell(0, 0);
table << fort::header
<< "hdr1" << "hdr2" << fort::endr;
std::cout << table.to_string() << std::endl;
}
Output:
+------+------+
| hdr1 | hdr2 |
+------+------+
| 1 | 2 |
| 3 | 4 |
+------+------+
The syntax is rather verbose but it is simple and straightforward. You have to explicitly specify adding_strategy
as replace
. After that when you want to insert some data inside the table you explicitly set current cell with set_cur_cell
and then use ordinary functions to fill the cells.
If this solution doesn't solve your problems fill free to write here your suggestions or problems that you encounter.
from libfort.
thanks, so now we can code the header either at the start or at the very end. I tried the following
int main()
{
fort::char_table table;
table.set_adding_strategy(fort::add_strategy::insert);
// Fill table with data
table << "1"
<< "2" << fort::endr;
// explicitly add header as the top row
table.set_cur_cell(0, 0);
table << fort::header << "hdr1"
<< "hdr2" << fort::endr;
table << "3"
<< "4" << fort::endr;
std::cout << table.to_string() << std::endl;
}
and this was the output
+------+------+
| hdr1 | hdr2 |
+------+------+
| 3 | 4 |
| 1 | 2 |
+------+------+
adding more data after adding the header gives counter-intuitive results.
from libfort.
Pressed the wrong button and the issue got closed...
from libfort.
That's expected behavior.
As I already said above there is nothing special with headers. They are ordinary rows. That's library design principle.
Functions set_adding_strategy
and set_cur_cell
also ordinary functions. They don't do any specific for headers. They designed in a general way so that they affect all inserted cells(either in headers or in ordinary rows). There is no reason to limit the functionality of adding cells to random place only for headers. Therefore when you specify that you will insert data to the beginning of the table library will add there all rows (headers and ordinary rows). It's a library user responsibility to specify where to place data. So in your last example if you want to add 3
and 4
to the end you have to explicitly specify it with table.set_curl_cell(2, 0);
before pushing these data. By the way it is a good use case to add a function to get the number of the rows from the issue #26 ( so that when you add something in the middle and then decide to continue pushing to the end you can do table.set_cur_cell(table.row_count(), 0);
).
However, maybe what you want can be implemented with a little bit different API. Something like that:
int main()
{
fort::char_table table;
table.set_adding_strategy(fort::add_strategy::insert);
// Fill table with data
table << "1" << "2" << fort::endr;
// Note that I explicitly specify 0th row (table[0]) where I will insert the header
table[0] << fort::header << "hdr1" << "hdr2" << fort::endr;
table << "3" << "4" << fort::endr;
std::cout << table.to_string() << std::endl;
}
So the idea of this API is that we can apply modifiing operations not on the table but on a particular row and that in this case this operations won't affect position of the current cell. I need to think about this possibility thoroughly and also how it will look with current modifying operation on distinct cells (like tbl[2][3] = "some_data";
) which affect position of the current cell. So I am not sure if it will be ok to implement it. Need to think about it anyway.
from libfort.
Wouldn't a header at the end typically be called a footer? :)
Since it is just decorative, perhaps renaming it as a cell/row border bolding or callout property? Something like: tables[123] << fort::emphasize << "Total:" << "123" << fort::endr;
from libfort.
appending the table at the end will be a footer, but pre-pending the table at the end will still be a header! :)
from libfort.
Related Issues (20)
- Support exported targets HOT 4
- Feature request: reduce RAM consumption HOT 1
- No CMake option to disable unit test HOT 2
- Undefined reference while building shared library that uses libfort HOT 3
- Is there an API to clear/erase a table, to make it empty? HOT 1
- Not more than 15 columns supported HOT 1
- It's not possible to build (or rather use) libfort as .dll on windows
- How to set decimal precision in a column? HOT 3
- Feature request: raw CSV output HOT 3
- Is it possible to update an existing column in the table without redrawing the whole table HOT 2
- Any plans on supporting sorting on one of the columns? :) HOT 2
- segfault in ft_to_string() HOT 3
- Remove trailing whitespace for FT_PLAIN_STYLE (& other similar styles) HOT 3
- Built-in style for RST (reStructuredText Markup) table HOT 4
- Are unicode characters supported? HOT 3
- Automatic serial numbers for rows
- ft_color skips one number, produces an assert if bg white HOT 1
- 2 tests fail on FreeBSD HOT 7
- CMake build does not generate .lib HOT 1
- Escape sequences break the formatting of tables
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from libfort.