Semi-automatic indentation in streams possible?

Discussion in 'C++' started by Klaus Nowikow, Feb 12, 2004.

  1. I would like to be able to do the following:

    std::cout // Or any other ostream
    << "Line 1\n"
    << push_tab
    << "Line 2\n"
    << "Line 3\n"
    << push_tab
    << "Line 4\n"
    << pop_tab
    << "Line 5"
    << std::endl;

    producing the following output:
    Line 1
    Line 2
    Line 3
    Line 4
    Line 5

    That is, a '\n' character should automatically be replaced by '\n' plus
    (4*indentation) spaces (later I want to add a tabsize() modifier).

    I came up with the following "semi-solution" (sorry for the long post):

    // my_ios.h ***************
    #include <iostream>

    struct index
    {
    static int indent();
    };

    template <class charT, class traits>
    std::basic_ostream<charT, traits>& indent(
    std::basic_ostream<charT, traits>& strm
    )
    {
    const long& in = strm.iword(index::indent());
    for(long i = 0; i < in; ++i)
    strm << " ";
    return strm;
    }

    template <class charT, class traits>
    std::basic_ostream<charT, traits>& push_indent(
    std::basic_ostream<charT, traits>& strm
    )
    {
    strm.iword(index::indent())++;
    return strm;
    }

    template <class charT, class traits>
    std::basic_ostream<charT, traits>& pop_indent(
    std::basic_ostream<charT, traits>& strm
    )
    {
    long in = strm.iword(index::indent());
    if(in > 0)
    strm.iword(index::indent()) = in - 1;
    return strm;
    }
    // eof ----------------------------

    // my_ios.cpp *************************
    #include "my_ios.h"
    /*static*/ int index::indent()
    {
    static const int idx = std::ios_base::xalloc();
    return idx;
    }

    // eof ------------------------------------

    Now i can do the following:
    #include "my_ios.h"
    #include <iostream>

    int main(int argc, char* argv[])
    {
    std::cout
    << indent << "Line 1\n"
    << push_indent
    << indent << "Line 2\n"
    << indent << "Line 3\n"
    << push_indent
    << indent << "Line 4\n"
    << pop_indent
    << indent << "Line 5\n"
    ;
    return 0;
    }

    i.e., I have to put
    << indent
    to the beginning of each output line. Things like
    cout << push_indent << "Line 1\nLine 2";
    producing the desired result are not possible.

    Do you know of any way to do this?

    Best regards,
    Klaus
     
    Klaus Nowikow, Feb 12, 2004
    #1
    1. Advertising

  2. "Klaus Nowikow" <> wrote...
    > I would like to be able to do the following:
    >
    > std::cout // Or any other ostream
    > << "Line 1\n"
    > << push_tab
    > << "Line 2\n"
    > << "Line 3\n"
    > << push_tab
    > << "Line 4\n"
    > << pop_tab
    > << "Line 5"
    > << std::endl;
    >
    > producing the following output:
    > Line 1
    > Line 2
    > Line 3
    > Line 4
    > Line 5
    >
    > That is, a '\n' character should automatically be replaced by '\n' plus
    > (4*indentation) spaces (later I want to add a tabsize() modifier).
    >
    > [...]
    > Do you know of any way to do this?


    I'd look into two possible ways: (a) modification of the streambuf which
    when \n is output automatically appends the necessary amount of whitespace
    and (b) creating your own 'endl' for the same purpose instead of using
    '\n'.

    Victor
     
    Victor Bazarov, Feb 12, 2004
    #2
    1. Advertising

  3. Klaus Nowikow <> wrote in message news:<newscache$4kuysh$0u41$>...
    > I would like to be able to do the following:
    >
    > std::cout // Or any other ostream
    > << "Line 1\n"
    > << push_tab
    > << "Line 2\n"
    > << "Line 3\n"
    > << push_tab
    > << "Line 4\n"
    > << pop_tab
    > << "Line 5"
    > << std::endl;


    You are heading in the right direction with the use of ios::iword() etc,
    but to do it how you want, you really need to implement a streambuf
    which intercepts the character stream looking for the start of each
    new line and which interjects the appropriate spacing.

    Rather than post a lot of code here, go grab a copy of OSE from:

    http://ose.sourceforge.net

    and look at how its OTC_TraceStream and OTC_TraceBuf classes work.
    These classes implement an indenting scheme in the style that you are
    looking for.
     
    Graham Dumpleton, Feb 13, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Francesc
    Replies:
    3
    Views:
    567
  2. Peter Flynn
    Replies:
    3
    Views:
    486
  3. James Stroud

    py2app semi-standalone semi-works

    James Stroud, Oct 4, 2006, in forum: Python
    Replies:
    2
    Views:
    740
    James Stroud
    Oct 4, 2006
  4. Keith Thompson

    groups.google.com indentation bugs [semi-OT]

    Keith Thompson, Jan 9, 2005, in forum: C Programming
    Replies:
    10
    Views:
    576
    Flash Gordon
    Feb 1, 2005
  5. Jesse B.
    Replies:
    2
    Views:
    219
    Josh Cheek
    Mar 27, 2010
Loading...

Share This Page