1 /*=============================================================================
2 Copyright (c) 2002 2004 2006 Joel de Guzman
3 Copyright (c) 2004 Eric Niebler
4 http://spirit.sourceforge.net/
6 Use, modification and distribution is subject to the Boost Software
7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
12 #include <boost/foreach.hpp>
13 #include <boost/spirit/include/classic_core.hpp>
14 #include <boost/spirit/include/classic_loops.hpp>
15 #include <boost/spirit/include/classic_symbols.hpp>
16 #include <boost/spirit/include/classic_chset.hpp>
17 #include <boost/spirit/include/classic_numerics.hpp>
18 #include <boost/spirit/include/phoenix1_primitives.hpp>
19 #include <boost/spirit/include/phoenix1_operators.hpp>
20 #include "grammar_impl.hpp"
22 #include "actions.hpp"
23 #include "doc_info_tags.hpp"
24 #include "phrase_tags.hpp"
28 namespace cl
= boost::spirit::classic
;
32 attribute_info(value::tag_type t
, cl::rule
<scanner
>* r
)
37 cl::rule
<scanner
>* rule
;
40 struct doc_info_grammar_local
42 struct assign_attribute_type
44 assign_attribute_type(doc_info_grammar_local
& l
)
48 void operator()(value::tag_type
& t
) const {
49 l
.attribute_rule
= *l
.attribute_rules
[t
];
53 doc_info_grammar_local
& l
;
56 struct fallback_attribute_type
58 fallback_attribute_type(doc_info_grammar_local
& l
)
62 void operator()(parse_iterator
, parse_iterator
) const {
63 l
.attribute_rule
= l
.doc_fallback
;
64 l
.attribute_tag
= value::default_tag
;
67 doc_info_grammar_local
& l
;
71 doc_info_block
, doc_attribute
, doc_info_attribute
,
72 doc_info_escaped_attributes
,
73 doc_title
, doc_simple
, doc_phrase
, doc_fallback
,
74 doc_authors
, doc_author
,
75 doc_copyright
, doc_copyright_holder
,
76 doc_source_mode
, doc_biblioid
, doc_compatibility_mode
,
77 quickbook_version
, macro
, char_
;
78 cl::uint_parser
<int, 10, 4, 4> doc_copyright_year
;
79 cl::symbols
<> doc_types
;
80 cl::symbols
<value::tag_type
> doc_info_attributes
;
81 cl::symbols
<value::tag_type
> doc_attributes
;
82 std::map
<value::tag_type
, cl::rule
<scanner
>* > attribute_rules
;
83 value::tag_type attribute_tag
;
84 cl::rule
<scanner
> attribute_rule
;
85 assign_attribute_type assign_attribute
;
86 fallback_attribute_type fallback_attribute
;
88 doc_info_grammar_local()
89 : assign_attribute(*this)
90 , fallback_attribute(*this)
93 bool source_mode_unset
;
96 void quickbook_grammar::impl::init_doc_info()
98 doc_info_grammar_local
& local
= cleanup_
.add(
99 new doc_info_grammar_local
);
101 typedef cl::uint_parser
<int, 10, 1, 2> uint2_t
;
104 "book", "article", "library", "chapter", "part"
105 , "appendix", "preface", "qandadiv", "qandaset"
109 BOOST_FOREACH(value::tag_type t
, doc_attributes::tags()) {
110 local
.doc_attributes
.add(doc_attributes::name(t
), t
);
111 local
.doc_info_attributes
.add(doc_attributes::name(t
), t
);
114 BOOST_FOREACH(value::tag_type t
, doc_info_attributes::tags()) {
115 local
.doc_info_attributes
.add(doc_info_attributes::name(t
), t
);
119 error_action
error(state
);
120 plain_char_action
plain_char(state
);
121 do_macro_action
do_macro(state
);
122 scoped_parser
<to_value_scoped_action
> to_value(state
);
123 member_action_value
<quickbook::state
, source_mode_type
> change_source_mode(
124 state
, &state::change_source_mode
);
125 member_action_fixed_value
<quickbook::state
, source_mode_type
> default_source_mode(
126 state
, &state::change_source_mode
, source_mode_tags::cpp
);
129 cl::eps_p
[ph::var(local
.source_mode_unset
) = true]
131 >> local
.doc_attribute
134 >> local
.doc_info_block
139 local
.doc_info_block
=
142 >> (local
.doc_types
>> cl::eps_p
)
143 [state
.values
.entry(ph::arg1
, ph::arg2
, doc_info_tags::type
)]
145 >> to_value(doc_info_tags::title
)
146 [ *( ~cl::eps_p(blank
>> (cl::ch_p('[') | ']' | cl::eol_p
))
149 // Include 'blank' here so that it will be included in
154 >> !(qbk_ver(106u) >> cl::eps_p(ph::var(local
.source_mode_unset
))
155 [default_source_mode
]
157 >> ( *( ( local
.doc_info_attribute
158 | local
.doc_info_escaped_attributes
162 ) [state
.values
.sort()]
169 local
.doc_attribute
=
172 >> local
.doc_attributes
[local
.assign_attribute
]
174 >> state
.values
.list(ph::var(local
.attribute_tag
))
175 [ cl::eps_p
[state
.values
.entry(ph::arg1
, ph::arg2
, doc_info_tags::before_docinfo
)]
176 >> local
.attribute_rule
182 local
.doc_info_attribute
=
185 >> ( local
.doc_info_attributes
186 [local
.assign_attribute
]
187 | (+(cl::alnum_p
| '_' | '-'))
188 [local
.fallback_attribute
]
189 [error("Unrecognized document attribute: '%s'.")]
192 >> state
.values
.list(ph::var(local
.attribute_tag
))
193 [local
.attribute_rule
]
198 local
.doc_fallback
= to_value() [
199 *(~cl::eps_p(']') >> local
.char_
)
202 local
.doc_info_escaped_attributes
=
204 >> (*(cl::anychar_p
- "'''")) [state
.values
.entry(ph::arg1
, ph::arg2
, doc_info_tags::escaped_attribute
)]
205 >> ( cl::str_p("'''")
206 | cl::eps_p
[error("Unclosed boostbook escape.")]
210 // Document Attributes
212 local
.quickbook_version
=
213 cl::uint_p
[state
.values
.entry(ph::arg1
)]
215 >> uint2_t() [state
.values
.entry(ph::arg1
)]
218 local
.attribute_rules
[doc_attributes::qbk_version
] = &local
.quickbook_version
;
220 local
.doc_compatibility_mode
=
221 cl::uint_p
[state
.values
.entry(ph::arg1
)]
223 >> uint2_t() [state
.values
.entry(ph::arg1
)]
226 local
.attribute_rules
[doc_attributes::compatibility_mode
] = &local
.doc_compatibility_mode
;
228 local
.doc_source_mode
= source_modes
230 [ph::var(local
.source_mode_unset
) = false]
233 local
.attribute_rules
[doc_attributes::source_mode
] = &local
.doc_source_mode
;
235 // Document Info Attributes
237 local
.doc_simple
= to_value() [*(~cl::eps_p(']') >> local
.char_
)];
238 local
.attribute_rules
[doc_info_attributes::version
] = &local
.doc_simple
;
239 local
.attribute_rules
[doc_info_attributes::id
] = &local
.doc_simple
;
240 local
.attribute_rules
[doc_info_attributes::dirname
] = &local
.doc_simple
;
241 local
.attribute_rules
[doc_info_attributes::category
] = &local
.doc_simple
;
242 local
.attribute_rules
[doc_info_attributes::last_revision
] = &local
.doc_simple
;
243 local
.attribute_rules
[doc_info_attributes::lang
] = &local
.doc_simple
;
244 local
.attribute_rules
[doc_info_attributes::xmlbase
] = &local
.doc_simple
;
246 local
.doc_copyright_holder
249 | ',' >> space
>> local
.doc_copyright_year
254 local
.doc_copyright
=
255 *( +( local
.doc_copyright_year
256 [state
.values
.entry(ph::arg1
, doc_info_tags::copyright_year
)]
260 >> local
.doc_copyright_year
261 [state
.values
.entry(ph::arg1
, doc_info_tags::copyright_year_end
)]
267 >> to_value(doc_info_tags::copyright_name
) [ local
.doc_copyright_holder
]
273 local
.attribute_rules
[doc_info_attributes::copyright
] = &local
.doc_copyright
;
275 local
.doc_phrase
= to_value() [ nested_phrase
];
276 local
.attribute_rules
[doc_info_attributes::purpose
] = &local
.doc_phrase
;
277 local
.attribute_rules
[doc_info_attributes::license
] = &local
.doc_phrase
;
282 >> to_value(doc_info_tags::author_surname
)
283 [*(~cl::eps_p(',') >> local
.char_
)]
285 >> to_value(doc_info_tags::author_first
)
286 [*(~cl::eps_p(']') >> local
.char_
)]
293 >> !(cl::ch_p(',') >> space
)
297 local
.attribute_rules
[doc_info_attributes::authors
] = &local
.doc_authors
;
300 (+cl::alnum_p
) [state
.values
.entry(ph::arg1
, ph::arg2
, doc_info_tags::biblioid_class
)]
302 >> to_value(doc_info_tags::biblioid_value
)
303 [+(~cl::eps_p(']') >> local
.char_
)]
306 local
.attribute_rules
[doc_info_attributes::biblioid
] = &local
.doc_biblioid
;
311 | cl::anychar_p
[plain_char
];
317 >> ~cl::eps_p(cl::alpha_p
| '_')
318 // must not be followed by alpha or underscore
320 & macro_identifier
// must be a valid macro for the current version
322 >> state
.macro
[do_macro
]