Code Monkey home page Code Monkey logo

Comments (13)

seleznevae avatar seleznevae commented on August 17, 2024

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.

pkbehera avatar pkbehera commented on August 17, 2024

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.

pkbehera avatar pkbehera commented on August 17, 2024

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.

pkbehera avatar pkbehera commented on August 17, 2024

btw what does << fort::header do? Apparently its just equivalent to << fort::endr << fort::separator

from libfort.

seleznevae avatar seleznevae commented on August 17, 2024

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.

pkbehera avatar pkbehera commented on August 17, 2024

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.

seleznevae avatar seleznevae commented on August 17, 2024

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.

seleznevae avatar seleznevae commented on August 17, 2024

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.

pkbehera avatar pkbehera commented on August 17, 2024

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.

pkbehera avatar pkbehera commented on August 17, 2024

Pressed the wrong button and the issue got closed...

from libfort.

seleznevae avatar seleznevae commented on August 17, 2024

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.

brlcad avatar brlcad commented on August 17, 2024

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.

pkbehera avatar pkbehera commented on August 17, 2024

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)

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.