|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r75446 - in branches/quickbook-dev/tools/quickbook: doc src test
From: dnljms_at_[hidden]
Date: 2011-11-10 13:17:05
Author: danieljames
Date: 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
New Revision: 75446
URL: http://svn.boost.org/trac/boost/changeset/75446
Log:
Quickbook: Parse lists with paragraphs.
Quite a big change. I moved the list logic into the grammar so that it's
easier to tell how to parse different blocks. Also reworked some of the
block vs. phrase stuff - it's a lot cleaner now which helped implement
this. It generates terrible markup at the moment, but at least the
parser is in place.
Added:
branches/quickbook-dev/tools/quickbook/test/list_test-1_6.gold
- copied, changed from r75445, /branches/quickbook-dev/tools/quickbook/test/list_test-1_5.gold
branches/quickbook-dev/tools/quickbook/test/list_test-1_6.quickbook
- copied, changed from r75445, /branches/quickbook-dev/tools/quickbook/test/list_test-1_5.quickbook
Text files modified:
branches/quickbook-dev/tools/quickbook/doc/1_6.qbk | 33 +++
branches/quickbook-dev/tools/quickbook/src/actions.cpp | 97 ++-------
branches/quickbook-dev/tools/quickbook/src/actions.hpp | 15 +
branches/quickbook-dev/tools/quickbook/src/actions_class.cpp | 1
branches/quickbook-dev/tools/quickbook/src/actions_class.hpp | 6
branches/quickbook-dev/tools/quickbook/src/block_tags.hpp | 2
branches/quickbook-dev/tools/quickbook/src/grammar_impl.hpp | 31 +-
branches/quickbook-dev/tools/quickbook/src/main_grammar.cpp | 390 +++++++++++++++++++++++++++++++--------
branches/quickbook-dev/tools/quickbook/src/quickbook.cpp | 10
branches/quickbook-dev/tools/quickbook/test/Jamfile.v2 | 1
branches/quickbook-dev/tools/quickbook/test/list_test-1_5.gold | 123 ++++++++++++
branches/quickbook-dev/tools/quickbook/test/list_test-1_5.quickbook | 33 +++
branches/quickbook-dev/tools/quickbook/test/list_test-1_6.gold | 161 ++++++++++++++++
branches/quickbook-dev/tools/quickbook/test/list_test-1_6.quickbook | 49 ++++
14 files changed, 772 insertions(+), 180 deletions(-)
Modified: branches/quickbook-dev/tools/quickbook/doc/1_6.qbk
==============================================================================
--- branches/quickbook-dev/tools/quickbook/doc/1_6.qbk (original)
+++ branches/quickbook-dev/tools/quickbook/doc/1_6.qbk 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -200,4 +200,37 @@
[endsect]
+[section:listparagraphs Pargraphs in lists]
+
+I'm still refining this, but paragraphs can now be used in lists:
+
+[pre
+* Para 1
+
+ Para 2
+ * Nested Para 1
+
+ Nested Para 2
+
+ Code block
+ Para 3
+]
+
+generates:
+
+* Para 1
+
+ Para 2
+ * Nested Para 1
+
+ Nested Para 2
+
+ Code block
+ Para 3
+
+/TODO/: Improve code generation.
+/TODO/: Allow block elements in list items.
+
+[endsect]
+
[endsect] [/1_6]
\ No newline at end of file
Modified: branches/quickbook-dev/tools/quickbook/src/actions.cpp
==============================================================================
--- branches/quickbook-dev/tools/quickbook/src/actions.cpp (original)
+++ branches/quickbook-dev/tools/quickbook/src/actions.cpp 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -67,7 +67,6 @@
}
}
- void list_action(quickbook::actions&, value);
void explicit_list_action(quickbook::actions&, value);
void header_action(quickbook::actions&, value);
void begin_section_action(quickbook::actions&, value);
@@ -99,8 +98,6 @@
switch(v.get_tag())
{
- case block_tags::list:
- return list_action(actions, v);
case block_tags::ordered_list:
case block_tags::itemized_list:
return explicit_list_action(actions, v);
@@ -314,6 +311,14 @@
}
}
+ void list_item_action::operator()() const
+ {
+ std::string str;
+ actions.phrase.swap(str);
+ actions.out << str;
+ write_anchors(actions, actions.out);
+ }
+
void phrase_end_action::operator()() const
{
write_anchors(actions, actions.phrase);
@@ -486,76 +491,30 @@
}
}
- void list_action(quickbook::actions& actions, value list)
+ void actions::start_list(char mark)
{
- write_anchors(actions, actions.out);
-
- typedef std::pair<char, int> mark_type;
- std::stack<mark_type> list_marks;
- int list_indent = -1;
-
- BOOST_FOREACH(value_consumer values, list)
- {
- int new_indent = indent_length(
- values.consume(general_tags::list_indent).get_quickbook());
- value mark_value = values.consume(general_tags::list_mark);
- std::string content = values.consume().get_boostbook();
- values.finish();
-
- char mark = *mark_value.get_quickbook().begin();
- assert(mark == '*' || mark == '#');
-
- if(list_indent == -1) {
- assert(new_indent == 0);
- }
-
- if(new_indent > list_indent)
- {
- list_indent = new_indent;
- list_marks.push(mark_type(mark, list_indent));
-
- actions.out << ((mark == '#') ? "<orderedlist>\n" : "<itemizedlist>\n");
- }
- else if (new_indent < list_indent)
- {
- BOOST_ASSERT(!list_marks.empty());
- list_indent = new_indent;
+ write_anchors(*this, out);
+ assert(mark == '*' || mark == '#');
+ out << ((mark == '#') ? "<orderedlist>\n" : "<itemizedlist>\n");
+ }
- while (!list_marks.empty() && (list_indent < list_marks.top().second))
- {
- char mark = list_marks.top().first;
- list_marks.pop();
- actions.out << "</simpara></listitem>";
- actions.out << ((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");
- }
- actions.out << "</simpara></listitem>";
- }
- else
- {
- actions.out << "</simpara></listitem>";
- }
+ void actions::end_list(char mark)
+ {
+ write_anchors(*this, out);
+ assert(mark == '*' || mark == '#');
+ out << ((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");
+ }
- if (mark != list_marks.top().first) // new_indent == list_indent
- {
- detail::outerr(mark_value.get_file(), mark_value.get_position())
- << "Illegal change of list style.\n";
- detail::outwarn(mark_value.get_file(), mark_value.get_position())
- << "Ignoring change of list style" << std::endl;
- ++actions.error_count;
- }
-
- actions.out << "<listitem><simpara>";
- actions.out << content;
- }
+ void actions::start_list_item()
+ {
+ out << "<listitem><simpara>";
+ write_anchors(*this, out);
+ }
- assert(!list_marks.empty());
- while (!list_marks.empty())
- {
- char mark = list_marks.top().first;
- list_marks.pop();
- actions.out << "</simpara></listitem>";
- actions.out << ((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");
- }
+ void actions::end_list_item()
+ {
+ write_anchors(*this, out);
+ out << "</simpara></listitem>";
}
void explicit_list_action(quickbook::actions& actions, value list)
Modified: branches/quickbook-dev/tools/quickbook/src/actions.hpp
==============================================================================
--- branches/quickbook-dev/tools/quickbook/src/actions.hpp (original)
+++ branches/quickbook-dev/tools/quickbook/src/actions.hpp 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -131,6 +131,21 @@
quickbook::actions& actions;
};
+ struct list_item_action
+ {
+ // implicit paragraphs
+ // doesn't output the paragraph if it's only whitespace.
+
+ list_item_action(
+ quickbook::actions& actions)
+ : actions(actions) {}
+
+ void operator()() const;
+ void operator()(parse_iterator, parse_iterator) const { (*this)(); }
+
+ quickbook::actions& actions;
+ };
+
struct phrase_end_action
{
phrase_end_action(quickbook::actions& actions) :
Modified: branches/quickbook-dev/tools/quickbook/src/actions_class.cpp
==============================================================================
--- branches/quickbook-dev/tools/quickbook/src/actions_class.cpp (original)
+++ branches/quickbook-dev/tools/quickbook/src/actions_class.cpp 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -59,6 +59,7 @@
, code_block(phrase, phrase, *this)
, inline_code(phrase, *this)
, paragraph(*this)
+ , list_item(*this)
, phrase_end(*this)
, raw_char(phrase)
, plain_char(phrase, *this)
Modified: branches/quickbook-dev/tools/quickbook/src/actions_class.hpp
==============================================================================
--- branches/quickbook-dev/tools/quickbook/src/actions_class.hpp (original)
+++ branches/quickbook-dev/tools/quickbook/src/actions_class.hpp 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -77,6 +77,11 @@
// actions
///////////////////////////////////////////////////////////////////////////
+ void start_list(char mark);
+ void end_list(char mark);
+ void start_list_item();
+ void end_list_item();
+
scoped_parser<to_value_scoped_action>
to_value;
scoped_parser<cond_phrase_push>
@@ -91,6 +96,7 @@
code_action code_block;
inline_code_action inline_code;
paragraph_action paragraph;
+ list_item_action list_item;
phrase_end_action phrase_end;
raw_char_action raw_char;
plain_char_action plain_char;
Modified: branches/quickbook-dev/tools/quickbook/src/block_tags.hpp
==============================================================================
--- branches/quickbook-dev/tools/quickbook/src/block_tags.hpp (original)
+++ branches/quickbook-dev/tools/quickbook/src/block_tags.hpp 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -23,7 +23,7 @@
(variable_list)(table)
(xinclude)(import)(include)
(paragraph)
- (list)(ordered_list)(itemized_list)
+ (ordered_list)(itemized_list)
(hr)
)
Modified: branches/quickbook-dev/tools/quickbook/src/grammar_impl.hpp
==============================================================================
--- branches/quickbook-dev/tools/quickbook/src/grammar_impl.hpp (original)
+++ branches/quickbook-dev/tools/quickbook/src/grammar_impl.hpp 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -22,26 +22,21 @@
struct element_info
{
- enum context {
- in_block = 1,
- in_phrase = 2,
- in_conditional = 4,
- in_nested_block = 8,
- // This is a magic value to indicate an element that
- // might be a block or might be a phrase. It isn't
- // perfect, if a contextual_block appears at the
- // beginning of a paragraph it might interpreted as
- // a block when is should be a phrase.
- contextual_block = 16
- };
-
enum type_enum {
nothing = 0,
- block = in_block,
- conditional_or_block = block | in_conditional,
- nested_block = conditional_or_block | in_nested_block,
- phrase = nested_block | in_phrase,
- maybe_block = phrase | contextual_block
+ block = 1,
+ conditional_or_block = 2,
+ nested_block = 4,
+ phrase = 8,
+ maybe_block = 16
+ };
+
+ enum context {
+ in_phrase = phrase | maybe_block,
+ in_conditional = in_phrase | conditional_or_block,
+ in_nested_block = in_conditional | nested_block,
+ only_block = block | conditional_or_block | nested_block,
+ only_contextual_block = block | conditional_or_block | nested_block | maybe_block
};
element_info()
Modified: branches/quickbook-dev/tools/quickbook/src/main_grammar.cpp
==============================================================================
--- branches/quickbook-dev/tools/quickbook/src/main_grammar.cpp (original)
+++ branches/quickbook-dev/tools/quickbook/src/main_grammar.cpp 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -16,6 +16,7 @@
#include "phrase_tags.hpp"
#include "parsers.hpp"
#include "scoped.hpp"
+#include "input_path.hpp"
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_chset.hpp>
#include <boost/spirit/include/classic_if.hpp>
@@ -23,16 +24,65 @@
#include <boost/spirit/include/classic_attribute.hpp>
#include <boost/spirit/include/classic_lazy.hpp>
#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/range/algorithm/find_first_of.hpp>
+#include <boost/range/as_literal.hpp>
+
+#include <iostream>
namespace quickbook
{
namespace cl = boost::spirit::classic;
+ struct list_stack_item {
+ bool root;
+ unsigned int indent;
+ unsigned int indent2;
+ char mark;
+
+ list_stack_item() :
+ root(true), indent(0), indent2(0), mark('\0') {}
+
+ list_stack_item(char mark, unsigned int indent, unsigned int indent2) :
+ root(false), indent(indent), indent2(indent2), mark(mark)
+ {}
+
+ };
+
+ struct block_types {
+ enum values {
+ none, code, list, paragraph
+ };
+ };
+
+ template <typename T>
+ struct member_action
+ {
+ typedef void(T::*member_function)(parse_iterator, parse_iterator);
+
+ T& l;
+ member_function mf;
+
+ member_action(T& l, member_function mf) : l(l), mf(mf) {}
+
+ void operator()(parse_iterator first, parse_iterator last) const {
+ (l.*mf)(first, last);
+ }
+ };
+
struct main_grammar_local
{
////////////////////////////////////////////////////////////////////////
// Local actions
+ void start_blocks_impl(parse_iterator first, parse_iterator last);
+ void end_blocks_impl(parse_iterator first, parse_iterator last);
+ void check_indentation_impl(parse_iterator first, parse_iterator last);
+ void check_code_block_impl(parse_iterator first, parse_iterator last);
+ void plain_block(string_iterator first, string_iterator last);
+ void list_block(string_iterator first, string_iterator mark_pos,
+ string_iterator last);
+ void clear_stack();
+
struct process_element_impl : scoped_action_base {
process_element_impl(main_grammar_local& l)
: l(l) {}
@@ -45,16 +95,10 @@
info_ = l.info;
- if (!(info_.type & element_info::in_phrase))
+ if (info_.type != element_info::phrase &&
+ info_.type != element_info::maybe_block)
l.actions_.paragraph();
- if ((info_.type & element_info::contextual_block) &&
- l.top_level.parse_blocks())
- {
- info_.type = element_info::type_enum(
- info_.type & ~element_info::in_phrase);
- }
-
l.actions_.values.builder.reset();
return true;
@@ -76,32 +120,25 @@
main_grammar_local& l;
element_info info_;
};
-
- struct is_block_type
- {
- typedef bool result_type;
- template <typename Arg1 = void>
- struct result { typedef bool type; };
-
- is_block_type(main_grammar_local& l)
- : l_(l)
- {}
- bool operator()() const
- {
- return l_.element_type && !(l_.element_type & element_info::in_phrase);
+ struct in_list_impl {
+ main_grammar_local& l;
+
+ in_list_impl(main_grammar_local& l) :
+ l(l) {}
+
+ bool operator()() const {
+ return !l.list_stack.top().root;
}
-
- main_grammar_local& l_;
};
////////////////////////////////////////////////////////////////////////
// Local members
cl::rule<scanner>
- blocks, paragraph_separator,
+ top_level, indent_check,
+ paragraph_separator,
code, code_line, blank_line, hr,
- list, list_item,
inline_code,
template_,
code_block, macro,
@@ -121,10 +158,9 @@
member1 mark;
};
- struct block_parse_closure
- : cl::closure<block_parse_closure, bool>
+ struct block_item_closure : cl::closure<block_item_closure, bool>
{
- member1 parse_blocks;
+ member1 still_in_block;
};
struct context_closure : cl::closure<context_closure, element_info::context>
@@ -135,24 +171,39 @@
cl::rule<scanner, simple_markup_closure::context_t> simple_markup;
cl::rule<scanner> simple_markup_end;
- cl::rule<scanner, block_parse_closure::context_t> top_level;
+ cl::rule<scanner, block_item_closure::context_t> paragraph;
+ cl::rule<scanner, context_closure::context_t> paragraph_item;
+ cl::rule<scanner, block_item_closure::context_t> list;
+ cl::rule<scanner, context_closure::context_t> list_item;
cl::rule<scanner, context_closure::context_t> common;
cl::rule<scanner, context_closure::context_t> element;
+ std::stack<list_stack_item> list_stack;
+ unsigned int list_indent;
+ block_types::values block_type;
+
element_info info;
element_info::type_enum element_type;
quickbook::actions& actions_;
+ member_action<main_grammar_local> check_indentation;
+ member_action<main_grammar_local> check_code_block;
+ member_action<main_grammar_local> start_blocks;
+ member_action<main_grammar_local> end_blocks;
+ in_list_impl in_list;
scoped_parser<process_element_impl> process_element;
- is_block_type is_block;
////////////////////////////////////////////////////////////////////////
// Local constructor
main_grammar_local(quickbook::actions& actions)
: actions_(actions)
+ , check_indentation(*this, &main_grammar_local::check_indentation_impl)
+ , check_code_block(*this, &main_grammar_local::check_indentation_impl)
+ , start_blocks(*this, &main_grammar_local::start_blocks_impl)
+ , end_blocks(*this, &main_grammar_local::end_blocks_impl)
+ , in_list(*this)
, process_element(*this)
- , is_block(*this)
{}
};
@@ -219,47 +270,85 @@
]
;
// Top level blocks
- block_start = local.top_level;
+ block_start =
+ (*eol) [local.start_blocks]
+ >> (*local.top_level) [local.end_blocks]
+ ;
local.top_level =
- cl::eps_p [local.top_level.parse_blocks = true]
- >> *( cl::eps_p(local.top_level.parse_blocks)
- >> local.blocks
- | local.element(element_info::in_block)
- [local.top_level.parse_blocks = false]
- >> !(cl::eps_p(local.is_block) >> +eol)
- [local.top_level.parse_blocks = true]
- | local.paragraph_separator [local.top_level.parse_blocks = true]
- | local.common(element_info::in_phrase)
- [local.top_level.parse_blocks = false]
+ cl::eps_p(local.indent_check)
+ >> ( cl::eps_p(ph::var(local.block_type) == block_types::code)
+ >> local.code
+ | cl::eps_p(ph::var(local.block_type) == block_types::list)
+ >> local.list
+ | cl::eps_p(ph::var(local.block_type) == block_types::paragraph)
+ >> ( local.hr
+ | local.paragraph
+ )
+ )
+ >> *eol
+ ;
+
+ local.indent_check =
+ ( *cl::blank_p
+ >> !( (cl::ch_p('*') | '#')
+ >> *cl::blank_p)
+ ) [local.check_indentation]
+ ;
+
+ local.paragraph =
+ cl::eps_p [local.paragraph.still_in_block = true]
+ >> local.paragraph_item(element_info::only_contextual_block)
+ >> *( cl::eps_p(local.paragraph.still_in_block)
+ >> local.paragraph_item(element_info::only_block)
)
>> cl::eps_p [actions.paragraph]
;
+ local.paragraph_item =
+ local.element(local.paragraph_item.context)
+ >> !eol [local.paragraph.still_in_block = false]
+ | local.paragraph_separator [local.paragraph.still_in_block = false]
+ | local.common(element_info::in_phrase)
+ ;
+
+ local.list =
+ *cl::blank_p
+ >> (cl::ch_p('*') | '#')
+ >> *cl::blank_p [local.list.still_in_block = true]
+ >> *( cl::eps_p(local.list.still_in_block)
+ >> local.list_item
+ )
+ >> cl::eps_p [actions.list_item]
+ ;
+
+ local.list_item =
+ cl::eps_p(local.paragraph_separator) [local.list.still_in_block = false]
+ | local.common(element_info::in_phrase)
+ ;
+
+ local.paragraph_separator =
+ cl::eol_p
+ >> cl::eps_p
+ ( *cl::blank_p
+ >> ( cl::eol_p
+ | cl::eps_p(local.in_list) >> (cl::ch_p('*') | '#')
+ )
+ )
+ >> *eol
+ ;
+
// Blocks contains within an element, e.g. a table cell or a footnote.
inside_paragraph =
actions.values.save()
[ *( local.paragraph_separator [actions.paragraph]
+ >> *eol
| ~cl::eps_p(']')
>> local.common(element_info::in_nested_block)
)
] [actions.paragraph]
;
- local.blocks =
- +( local.code
- | local.list
- | local.hr
- | +eol
- )
- ;
-
- local.paragraph_separator
- = cl::eol_p
- >> *cl::blank_p
- >> cl::eol_p [actions.paragraph]
- ;
-
local.hr =
cl::str_p("----")
>> actions.values.list(block_tags::hr)
@@ -297,39 +386,18 @@
;
local.code_line =
- cl::blank_p >> *(cl::anychar_p - cl::eol_p) >> (cl::eol_p | cl::end_p)
+ ( *cl::blank_p
+ >> ~cl::eps_p(cl::eol_p)
+ ) [local.check_code_block]
+ >> cl::eps_p(ph::var(local.block_type) == block_types::code)
+ >> *(cl::anychar_p - cl::eol_p)
+ >> (cl::eol_p | cl::end_p)
;
local.blank_line =
*cl::blank_p >> cl::eol_p
;
- local.list =
- cl::eps_p(cl::ch_p('*') | '#')
- >> actions.values.list(block_tags::list)
- [ +actions.values.list()
- [ (*cl::blank_p) [actions.values.entry(ph::arg1, ph::arg2, general_tags::list_indent)]
- >> (cl::ch_p('*') | '#')
- [actions.values.entry(ph::arg1, ph::arg2, general_tags::list_mark)]
- >> *cl::blank_p
- >> actions.to_value() [ local.list_item ]
- ]
- ] [actions.element]
- ;
-
- local.list_item =
- actions.values.save()
- [
- *( ~cl::eps_p
- ( cl::eol_p >> *cl::blank_p
- >> (cl::ch_p('*') | '#' | cl::eol_p)
- )
- >> local.common(element_info::in_phrase)
- )
- ]
- >> (+eol | cl::end_p)
- ;
-
local.common =
local.macro
| local.element(local.common.context)
@@ -621,4 +689,160 @@
>> +(cl::anychar_p - (cl::space_p | ']'))
;
}
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Indentation Handling
+
+ template <typename Iterator>
+ int indent_length(Iterator first, Iterator end)
+ {
+ int length = 0;
+ for(; first != end; ++first)
+ {
+ if (*first == '\t') {
+ // hardcoded tab to 4 for now
+ length = length + 4 - (length % 4);
+ }
+ else {
+ ++length;
+ }
+ }
+
+ return length;
+ }
+
+ void main_grammar_local::start_blocks_impl(parse_iterator, parse_iterator)
+ {
+ list_stack.push(list_stack_item());
+ }
+
+ void main_grammar_local::end_blocks_impl(parse_iterator, parse_iterator)
+ {
+ clear_stack();
+ list_stack.pop();
+ }
+
+ void main_grammar_local::check_indentation_impl(parse_iterator first_, parse_iterator last_)
+ {
+ string_iterator first = first_.base();
+ string_iterator last = last_.base();
+ string_iterator mark_pos = boost::find_first_of(
+ boost::make_iterator_range(first, last),
+ boost::as_literal("#*"));
+
+ if (mark_pos == last) {
+ plain_block(first, last);
+ }
+ else {
+ list_block(first, mark_pos, last);
+ }
+ }
+
+ void main_grammar_local::check_code_block_impl(parse_iterator first, parse_iterator last)
+ {
+ unsigned int new_indent = indent_length(first.base(), last.base());
+
+ block_type = (new_indent > list_stack.top().indent2) ?
+ block_types::code : block_types::none;
+ }
+
+ void main_grammar_local::plain_block(string_iterator first, string_iterator last)
+ {
+ if (qbk_version_n >= 106u) {
+ unsigned int new_indent = indent_length(first, last);
+
+ if (new_indent > list_stack.top().indent2) {
+ block_type = block_types::code;
+ }
+ else {
+ while (!list_stack.top().root && new_indent < list_stack.top().indent)
+ {
+ actions_.end_list_item();
+ actions_.end_list(list_stack.top().mark);
+ list_stack.pop();
+ list_indent = list_stack.top().indent;
+ }
+
+ if (!list_stack.top().root && new_indent == list_stack.top().indent)
+ {
+ list_stack_item save = list_stack.top();
+ list_stack.pop();
+ if (new_indent == list_stack.top().indent) {
+ actions_.end_list_item();
+ actions_.end_list(save.mark);
+ list_indent = list_stack.top().indent;
+ }
+ else {
+ list_stack.push(save);
+ }
+ }
+
+ block_type = block_types::paragraph;
+ }
+ }
+ else {
+ clear_stack();
+
+ if (last == first)
+ block_type = block_types::paragraph;
+ else
+ block_type = block_types::code;
+ }
+ }
+
+ void main_grammar_local::list_block(string_iterator first, string_iterator mark_pos,
+ string_iterator last)
+ {
+ unsigned int new_indent = indent_length(first, mark_pos);
+ unsigned int new_indent2 = indent_length(first, last);
+ char mark = *mark_pos;
+
+ if (list_stack.top().root && new_indent > 0) {
+ block_type = block_types::code;
+ return;
+ }
+
+ if (list_stack.top().root || new_indent > list_indent) {
+ list_stack.push(list_stack_item(mark, new_indent, new_indent2));
+ actions_.start_list(mark);
+ }
+ else if (new_indent == list_indent) {
+ actions_.end_list_item();
+ }
+ else {
+ // This should never reach root, since the first list
+ // has indentation 0.
+ while(!list_stack.top().root && new_indent < list_stack.top().indent)
+ {
+ actions_.end_list_item();
+ actions_.end_list(list_stack.top().mark);
+ list_stack.pop();
+ }
+
+ actions_.end_list_item();
+ }
+
+ list_indent = new_indent;
+
+ if (mark != list_stack.top().mark)
+ {
+ detail::outerr(actions_.current_file, first)
+ << "Illegal change of list style.\n";
+ detail::outwarn(actions_.current_file, first)
+ << "Ignoring change of list style." << std::endl;
+ ++actions_.error_count;
+ }
+
+ actions_.start_list_item();
+ block_type = block_types::list;
+ }
+
+ void main_grammar_local::clear_stack()
+ {
+ while (!list_stack.top().root) {
+ actions_.end_list_item();
+ actions_.end_list(list_stack.top().mark);
+ list_stack.pop();
+ }
+ }
}
Modified: branches/quickbook-dev/tools/quickbook/src/quickbook.cpp
==============================================================================
--- branches/quickbook-dev/tools/quickbook/src/quickbook.cpp (original)
+++ branches/quickbook-dev/tools/quickbook/src/quickbook.cpp 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -98,10 +98,8 @@
pre(actor.out, actor, include_doc_id, docinfo_type);
info = cl::parse(info.hit ? info.stop : first, last, actor.grammar().block);
- if (info.full)
- {
- post(actor.out, actor, docinfo_type);
- }
+
+ post(actor.out, actor, docinfo_type);
}
if (!info.full)
@@ -148,10 +146,10 @@
result = 1;
}
- std::string stage2 = ids.replace_placeholders(buffer.str());
-
if (result == 0)
{
+ std::string stage2 = ids.replace_placeholders(buffer.str());
+
fs::ofstream fileout(fileout_);
if (pretty_print)
Modified: branches/quickbook-dev/tools/quickbook/test/Jamfile.v2
==============================================================================
--- branches/quickbook-dev/tools/quickbook/test/Jamfile.v2 (original)
+++ branches/quickbook-dev/tools/quickbook/test/Jamfile.v2 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -60,6 +60,7 @@
[ quickbook-test link-1_1 ]
[ quickbook-test link-1_6 ]
[ quickbook-test list_test-1_5 ]
+ [ quickbook-test list_test-1_6 ]
[ quickbook-test macro-1_5 ]
[ quickbook-test macro-1_6 ]
[ quickbook-error-test mismatched_brackets-1_1-fail ]
Modified: branches/quickbook-dev/tools/quickbook/test/list_test-1_5.gold
==============================================================================
--- branches/quickbook-dev/tools/quickbook/test/list_test-1_5.gold (original)
+++ branches/quickbook-dev/tools/quickbook/test/list_test-1_5.gold 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -211,6 +211,77 @@
</listitem>
</orderedlist>
<para>
+ Inconsistent Indentation:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A1
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ B1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B2
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ C1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ C2
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B3
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B4
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B5
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ C3
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B6
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A2
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A3
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ <para>
Markup in list:
</para>
<itemizedlist>
@@ -239,6 +310,58 @@
</simpara>
</listitem>
</itemizedlist>
+ <para>
+ Don't end list with comment 1:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A2
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A3
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A4
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Don't end list with comment 2:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A1
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ B1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B2
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B3
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ </itemizedlist>
<section id="list_test.list_immediately_following_markup">
<title><link linkend="list_test.list_immediately_following_markup">List immediately
following markup</link></title>
Modified: branches/quickbook-dev/tools/quickbook/test/list_test-1_5.quickbook
==============================================================================
--- branches/quickbook-dev/tools/quickbook/test/list_test-1_5.quickbook (original)
+++ branches/quickbook-dev/tools/quickbook/test/list_test-1_5.quickbook 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -52,6 +52,21 @@
# G
# H
+Inconsistent Indentation:
+
+* A1
+ * B1
+ * B2
+ * C1
+ * C2
+ * B3
+ * B4
+ * B5
+ * C3
+ * B6
+ * A2
+* A3
+
Markup in list:
* *Bold*
@@ -59,6 +74,24 @@
* ["Quoted]
* [footnote Footnote]
+Don't end list with comment 1:
+
+* A1
+* A2
+
+[/ End list?]
+* A3
+* A4
+
+Don't end list with comment 2:
+
+* A1
+ * B1
+
+[/ End list?]
+ * B2
+ * B3
+
[section List immediately following markup]
* One
* Two
Copied: branches/quickbook-dev/tools/quickbook/test/list_test-1_6.gold (from r75445, /branches/quickbook-dev/tools/quickbook/test/list_test-1_5.gold)
==============================================================================
--- /branches/quickbook-dev/tools/quickbook/test/list_test-1_5.gold (original)
+++ branches/quickbook-dev/tools/quickbook/test/list_test-1_6.gold 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -211,6 +211,77 @@
</listitem>
</orderedlist>
<para>
+ Inconsistent Indentation:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A1
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ B1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B2
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ C1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ C2
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B3
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B4
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B5
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ C3
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B6
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A2
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A3
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ <para>
Markup in list:
</para>
<itemizedlist>
@@ -239,8 +310,60 @@
</simpara>
</listitem>
</itemizedlist>
- <section id="list_test.list_immediately_following_markup">
- <title><link linkend="list_test.list_immediately_following_markup">List immediately
+ <para>
+ Don't end list with comment 1:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A2
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A3
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ A4
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Don't end list with comment 2:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A1
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ B1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B2
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B3
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ <section id="list_test.list_immediately_following_marku">
+ <title><link linkend="list_test.list_immediately_following_marku">List immediately
following markup</link></title>
<itemizedlist>
<listitem>
@@ -260,4 +383,38 @@
</listitem>
</itemizedlist>
</section>
+ <section id="list_test.paragraphs_in_list_items">
+ <title><link linkend="list_test.paragraphs_in_list_items">Paragraphs in list
+ items</link></title>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ One
+ <para>
+ Two
+ </para>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Three
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ Four
+ <para>
+ Five
+ </para>
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Six
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </section>
</article>
Copied: branches/quickbook-dev/tools/quickbook/test/list_test-1_6.quickbook (from r75445, /branches/quickbook-dev/tools/quickbook/test/list_test-1_5.quickbook)
==============================================================================
--- /branches/quickbook-dev/tools/quickbook/test/list_test-1_5.quickbook (original)
+++ branches/quickbook-dev/tools/quickbook/test/list_test-1_6.quickbook 2011-11-10 13:17:00 EST (Thu, 10 Nov 2011)
@@ -1,5 +1,5 @@
[article List Test
-[quickbook 1.5]
+[quickbook 1.6]
]
Simple list:
@@ -52,6 +52,21 @@
# G
# H
+Inconsistent Indentation:
+
+* A1
+ * B1
+ * B2
+ * C1
+ * C2
+ * B3
+ * B4
+ * B5
+ * C3
+ * B6
+ * A2
+* A3
+
Markup in list:
* *Bold*
@@ -59,9 +74,41 @@
* ["Quoted]
* [footnote Footnote]
+Don't end list with comment 1:
+
+* A1
+* A2
+
+[/ End list?]
+* A3
+* A4
+
+Don't end list with comment 2:
+
+* A1
+ * B1
+
+[/ End list?]
+ * B2
+ * B3
+
[section List immediately following markup]
* One
* Two
* Three
[endsect]
+
+[section Paragraphs in list items]
+
+* One
+
+ Two
+
+* Three
+ * Four
+
+ Five
+* Six
+
+[endsect]
\ No newline at end of file
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk