Files
quickbook/block_list.cpp
Daniel James a8dfaf1852 Separate actions and state.
[SVN r59563]
2010-02-07 09:12:02 +00:00

92 lines
3.0 KiB
C++

/*=============================================================================
Copyright (c) 2002 2004 2006 Joel de Guzman
Copyright (c) 2004 Eric Niebler
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <stack>
#include <boost/assert.hpp>
#include "actions.hpp"
#include "state.hpp"
#include "gen_types.hpp"
#include "utils.hpp"
namespace quickbook
{
namespace {
int indent_length(std::string const& indent)
{
int length = 0;
for(std::string::const_iterator
first = indent.begin(), end = indent.end(); first != end; ++first)
{
switch(*first) {
case ' ': ++length; break;
// hardcoded tab to 4 for now
case '\t': length = ((length + 4) / 4) * 4; break;
default: BOOST_ASSERT(false);
}
}
return length;
}
}
struct stack_entry
{
explicit stack_entry(list2& list, int indent) : list(list), indent(indent) {}
list2& list;
int indent;
};
list2 process(quickbook::actions& actions, quickbook::list const& list)
{
list::const_iterator it = list.begin(), end = list.end();
BOOST_ASSERT(it != end);
list2 r;
r.mark = list.begin()->mark;
std::stack<stack_entry> stack;
stack.push(stack_entry(r, 0));
for(list::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
{
int new_indent = indent_length(it->indent);
BOOST_ASSERT(it->mark == '#' || it->mark == '*');
if (new_indent > stack.top().indent)
{
stack.push(stack_entry(stack.top().list.items.back().sublist, new_indent));
stack.top().list.mark = it->mark;
}
else if (new_indent < stack.top().indent)
{
// TODO: This assumes that new_indent is equal to one of the
// existing indents.
while (!stack.empty() && (new_indent < stack.top().indent))
stack.pop();
BOOST_ASSERT(!stack.empty());
}
list_item2 item;
item.content = it->content;
stack.top().list.items.push_back(item);
if (it->mark != stack.top().list.mark)
{
file_position const pos = it->position;
detail::outerr(pos.file,pos.line)
<< "Illegal change of list style near column " << pos.column << ".\n";
detail::outwarn(pos.file,pos.line)
<< "Ignoring change of list style" << std::endl;
++actions.state_.error_count;
}
}
return r;
}
}