examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

elastic-tabstops.cpp (1631B)


      1 #include <iostream>
      2 #include <vector>
      3 #include <cassert>
      4 #include <sstream>
      5 #include <memory>
      6 
      7 #if 1
      8 #define DIM	"\e[2m"
      9 #define RESET	"\e[m"
     10 #define INDENT	DIM "   >>   " RESET
     11 #define PADDING	DIM " ยป" RESET
     12 #else
     13 #define INDENT	"      "
     14 #define PADDING	"  "
     15 #endif
     16 
     17 using namespace std;
     18 
     19 struct column
     20 {
     21 	size_t width;
     22 	bool is_indent;
     23 };
     24 
     25 struct cell
     26 {
     27 	string str;
     28 	shared_ptr<column> column_ref;
     29 };
     30 
     31 struct line
     32 {
     33 	vector<cell> cells;
     34 	string tail;
     35 };
     36 
     37 vector<line> backlog;
     38 
     39 void flush_backlog()
     40 {
     41 	for (auto& line : backlog)
     42 	{
     43 		for (auto& c : line.cells)
     44 		{
     45 			if (c.column_ref->is_indent)
     46 				cout << INDENT;
     47 			else
     48 			{
     49 				c.str.resize(c.column_ref->width, ' ');
     50 				cout << c.str << PADDING;
     51 			}
     52 		}
     53 		cout << line.tail << endl;
     54 	}
     55 	backlog.clear();
     56 }
     57 
     58 int main()
     59 {
     60 	string buf;
     61 	vector<size_t> chunk_stack;
     62 	vector<shared_ptr<column>> columns;
     63 
     64 	while (getline(cin, buf))
     65 	{
     66 		struct line l;
     67 		istringstream in2(move(buf));
     68 
     69 		while (getline(in2, buf, '\t'))
     70 			l.cells.push_back({move(buf), {}});
     71 
     72 		if (l.cells.size())
     73 		{
     74 			l.tail = move(l.cells.back().str);
     75 			l.cells.pop_back();
     76 		}
     77 
     78 		columns.resize(l.cells.size());
     79 
     80 		bool indenting = true;
     81 		for (size_t i = 0; i < columns.size(); ++i)
     82 		{
     83 			auto& p = columns[i];
     84 			auto width = l.cells[i].str.size();
     85 
     86 			if (width)
     87 				indenting = false;
     88 
     89 			if (p)
     90 			{
     91 				p->width = max(p->width, width);
     92 				p->is_indent &= indenting;
     93 			} else
     94 				p = make_shared<column>(column{width, indenting});
     95 
     96 			l.cells[i].column_ref = p;
     97 		}
     98 
     99 		backlog.push_back(move(l));
    100 		auto& C = backlog.back().cells;
    101 
    102 		if (C.empty())
    103 			flush_backlog();
    104 	}
    105 	flush_backlog();
    106 }