outputformatters - using just one decorator string

Hi Reece, This just popped into my head. A lot of confusion seems to come from how you pass decorators. What I'm trying to say is that it can be very difficult to get the decorator strings right (especially for more complex things like XML) from the first time. I would suggest every formatter takes only one string which parses and finds all decorators itself. Each formatter will have one or more escape sequences which it uses to find the decorators. Something like: // in this case, '%' is used for identifying an element // '*' is to mean "leave default" (don't change) std::vector<int> v; // equivalent to your "[ ", ", ", " ]" std::cout << formatob(v, "[ %, % ]"); // eq. to "<< ", " | ", " >>" std::cout << formatob(v, "<< % | % >>"); // set only open/close decorators std::cout << formatob(v, "<< %*% >>"); // sets only the separator std::cout << formatob(v, "*% | %*"); // for pair - you have "%1" and "%2" std::vector< std::pair<int,long> > vp; // write XML std::cout << formatob(vp, containerfmt("<elem> % </elem><elem> % </elem>", pairfrt("<int>%1</int><long>%2</long>"))); How's that? Best, John -- John Torjo -- john@torjo.com Contributing editor, C/C++ Users Journal -- "Win32 GUI Generics" -- generics & GUI do mix, after all -- http://www.torjo.com/win32gui/ -- v1.4 - save_dlg - true binding of your data to UI controls! + easily add validation rules (win32gui/examples/smart_dlg)

Vladimir Prus wrote:
Basically this is just a simper interface for the user. The decorator will parse the string, which in the above case means: - open: "<elem> " - seq : " </elem><elem> " - close: " </elem>" But to the human eye, it's much easier to understand: "<elem> % </elem><elem> % </elem>" than "<elem> "," </elem><elem> "," </elem>" At least, IMO. Best, John -- John Torjo -- john@torjo.com Contributing editor, C/C++ Users Journal -- "Win32 GUI Generics" -- generics & GUI do mix, after all -- http://www.torjo.com/win32gui/ -- v1.4 - save_dlg - true binding of your data to UI controls! + easily add validation rules (win32gui/examples/smart_dlg)

From: John Torjo <john.lists@torjo.com>
BTW, that parsing can be to simply replace "%" with \0 and tracking the pointers to the start of each piece. Thus, no copying is needed.
Agreed, but pipes ("|") are easier to grok: "<elem> | </elem><elem> | </elem>" -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart wrote:
of course, I just showed it as an example. There are many ways to implement it ;)
That's fine too. Best, John -- John Torjo -- john@torjo.com Contributing editor, C/C++ Users Journal -- "Win32 GUI Generics" -- generics & GUI do mix, after all -- http://www.torjo.com/win32gui/ -- v1.4 - save_dlg - true binding of your data to UI controls! + easily add validation rules (win32gui/examples/smart_dlg)

John Torjo wrote:
This again runs into the problem of what if you want '|' in your format string? One possibility is to use non-printable characters, e.g. \xFF, but I don't think this would have widespread support. Implementing escaping for the above will complicate the evaluation of the format string as you cannot use str.find( "|" ). One possibility is to check if '\' exists before '|' after a find; if yes, repeat. Thus '\' becomes context-sensitive. This approach leads to "< |\\| >" for "< a\\b\\c >" formatting being ill-defined. Regards, Reece

Reece Dunn wrote:
I am optimistic and know you'll find a solution. The same goes for when you use any string in C++ code. If you want '"' character, you escape it. So, just make it easy to escape a few chars ;) Best, John -- John Torjo -- john@torjo.com Contributing editor, C/C++ Users Journal -- "Win32 GUI Generics" -- generics & GUI do mix, after all -- http://www.torjo.com/win32gui/ -- v1.4 - save_dlg - true binding of your data to UI controls! + easily add validation rules (win32gui/examples/smart_dlg)

From: Reece Dunn <msclrhd@hotmail.com>
The point is that this notation is far simpler to understand than what you currently offer in your library, so it seems like a good idea. If you accept that point, then you must choose a delimiter. Your choice of delimiter should be based upon readability and frequency of use elsewhere in the format string. Nevertheless, whichever delimiter you choose, you must allow it to be escaped because someone, somewhere, sometime will want the delimiter to be part of the text used to format the data. Pipes shine in the readability category, but are probably somewhat likely to appear in output -- for the same reason they are readable in the format string. Some other good choices are "#", "@", "!", "^", and "_". Have a look at the previous example (I've removed the spaces so the delimiters are set apart with spaces so we can see how good they really are): "<elem>|</elem><elem>|</elem>" "<elem>#</elem><elem>#</elem>" "<elem>@</elem><elem>@</elem>" "<elem>!</elem><elem>!</elem>" "<elem>^</elem><elem>^</elem>" "<elem>_</elem><elem>_</elem>" -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

On Thu, Sep 23, 2004 at 09:46:44AM -0400, Rob Stewart <stewart@sig.com> wrote:
You could also make the divider a user defined value of the formater object and maybe pick '%' as a default value: std::cout << formatob(v, "[ %, % ]"); std::cout << formatob(v, "[ |, | ]", '|' ); Thus you could ignore the escape-problem completely. Andreas Pokorny

On Sep 21, 2004, at 6:26 PM, John Torjo wrote:
I like this as well. But it brings to the fore something I've been wondering about the overall coherence of boost, (I haven't spoken up as I'm relatively new to the list). What the discussion has evolved to, above, looks a *lot* like what is in boost.format, and it would seem to me that boost.format would be an appropriate place for it (both specifically, as above, and theoretically as well). The docs mention that the serialization part of outputformatters is better left to the serialization library itself, so that's not an issue... offhand I just don't see why this functionality should be separate. I apologize if this has been discussed. I just got back from vacation and the boost folder has 700 unread messages in it. :/ -t

troy d. straszheim wrote:
boost::format takes care of formatting of "single" values. You can do printf-like formatting with boost::format. Output Formatters addresses a different issue - that is : formatting of collections/containers. Best, John -- John Torjo -- john@torjo.com Contributing editor, C/C++ Users Journal -- "Win32 GUI Generics" -- generics & GUI do mix, after all -- http://www.torjo.com/win32gui/ -- v1.4 - save_dlg - true binding of your data to UI controls! + easily add validation rules (win32gui/examples/smart_dlg)
participants (6)
-
Andreas Pokorny
-
John Torjo
-
Reece Dunn
-
Rob Stewart
-
troy d. straszheim
-
Vladimir Prus