Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73407 - in trunk/tools/quickbook: src test
From: dnljms_at_[hidden]
Date: 2011-07-27 19:50:42


Author: danieljames
Date: 2011-07-27 19:50:41 EDT (Wed, 27 Jul 2011)
New Revision: 73407
URL: http://svn.boost.org/trac/boost/changeset/73407

Log:
Quickbook: Clean id placeholder replacement.

And fix some bugs.
Text files modified:
   trunk/tools/quickbook/src/id_generator.cpp | 123 +++++++++++++++++++++------------------
   trunk/tools/quickbook/test/escape.gold | 9 ++
   trunk/tools/quickbook/test/escape.quickbook | 13 ++++
   3 files changed, 88 insertions(+), 57 deletions(-)

Modified: trunk/tools/quickbook/src/id_generator.cpp
==============================================================================
--- trunk/tools/quickbook/src/id_generator.cpp (original)
+++ trunk/tools/quickbook/src/id_generator.cpp 2011-07-27 19:50:41 EDT (Wed, 27 Jul 2011)
@@ -180,8 +180,10 @@
         std::string escape_postfix;
         std::string processing_instruction_postfix;
         std::string comment_postfix;
+ std::string whitespace;
         std::string tag_end;
         std::string name_end;
+ std::string attribute_assign;
         std::vector<std::string> id_attributes;
         
         std::string replace(std::string const&, id_generator&);
@@ -205,12 +207,14 @@
     }
 
     xml_processor::xml_processor()
- : escape_prefix("!--quickbook-escape-prefix-->")
- , escape_postfix("!--quickbook-escape-postfix-->")
+ : escape_prefix("<!--quickbook-escape-prefix-->")
+ , escape_postfix("<!--quickbook-escape-postfix-->")
         , processing_instruction_postfix("?>")
         , comment_postfix("-->")
+ , whitespace(" \t\n\r")
         , tag_end(" \t\n\r>")
         , name_end("= \t\n\r>")
+ , attribute_assign("= \t\n\r")
     {
         static int const n_id_attributes = sizeof(id_attributes_)/sizeof(char const*);
         for (int i = 0; i != n_id_attributes; ++i)
@@ -226,110 +230,115 @@
         std::string result;
 
         typedef std::string::const_iterator iterator;
- iterator pos = source.begin(), end = source.end();
- iterator next = pos;
 
- while (true) {
- next = std::find(next, end, '<');
- if (next == end) break;
+ // copied is the point up to which the source has been copied, or
+ // replaced, to result.
+ iterator copied = source.begin();
 
- if (end - pos > escape_prefix.size() && std::equal(
- escape_prefix.begin(), escape_prefix.end(), pos))
+ iterator end = source.end();
+
+ for(iterator it = copied; it != end; it = std::find(it, end, '<'))
+ {
+ assert(copied <= it && it <= end);
+
+ if (static_cast<std::size_t>(end - it) > escape_prefix.size() &&
+ std::equal(escape_prefix.begin(), escape_prefix.end(), it))
             {
- next = std::search(next + escape_prefix.size(), end,
+ it = std::search(it + escape_prefix.size(), end,
                     escape_postfix.begin(), escape_postfix.end());
 
- if (next == end) break;
+ if (it == end) break;
 
- next += escape_postfix.size();
+ it += escape_postfix.size();
                 continue;
             }
 
- ++next;
- if (next == end) break;
+ ++it;
+ if (it == end) break;
 
- switch(*next)
+ switch(*it)
             {
             case '?':
- next = std::search(next, end,
+ it = std::search(it, end,
                     processing_instruction_postfix.begin(),
                     processing_instruction_postfix.end());
-
- if (next != end) next += processing_instruction_postfix.size();
                 break;
+
             case '!':
- if (end - next > 3 && next[1] == '-' && next[2] == '-')
+ if (end - it > 3 && it[1] == '-' && it[2] == '-')
                 {
- next = std::search(next + 3, end,
- comment_postfix.begin(), comment_postfix.end());
-
- if (next != end) next += comment_postfix.size();
+ it = std::search(it + 3, end,
+ comment_postfix. begin(), comment_postfix.end());
+ if (it != end) it += comment_postfix.size();
                 }
                 else
                 {
- next = std::find(next + 1, end, '>');
- if (next != end) ++next;
+ it = std::find(it, end, '>');
                 }
                 break;
+
             default:
- if (*next >= 'a' || *next <= 'z' ||
- *next >= 'A' || *next <= 'Z' ||
- *next == '_' || *next == ':')
+ if ((*it >= 'a' && *it <= 'z') ||
+ (*it >= 'A' && *it <= 'Z') ||
+ *it == '_' || *it == ':')
                 {
- next = std::find_first_of(
- next + 1, end, tag_end.begin(), tag_end.end());
+ it = std::find_first_of(
+ it + 1, end, tag_end.begin(), tag_end.end());
 
                     while (true) {
- while(next != end && (*next == ' ' || *next == '\t'))
- ++next;
+ while(it != end &&
+ std::find(whitespace.begin(),
+ whitespace.end(), *it)
+ != whitespace.end())
+ ++it;
                             
- iterator name_start = next;
+ iterator name_start = it;
 
- next = std::find_first_of(
- next, end, name_end.begin(), name_end.end());
+ it = std::find_first_of(
+ it, end, name_end.begin(), name_end.end());
                         
- if (next == end || *next == '>') break;
+ if (it == end || *it == '>') break;
 
- string_ref name(name_start, next);
- ++next;
+ string_ref name(name_start, it);
+ ++it;
 
- while (next != end &&
- std::find(name_end.begin(), name_end.end(), *next)
- != name_end.end())
- ++next;
+ while (it != end &&
+ std::find(attribute_assign.begin(),
+ attribute_assign.end(), *it)
+ != attribute_assign.end())
+ ++it;
 
- if (next == end || (*next != '"' && *next != '\'')) break;
+ if (it == end || (*it != '"' && *it != '\'')) break;
 
- char delim = *next;
- ++next;
+ char delim = *it;
+ ++it;
 
- iterator value_start = next;
+ iterator value_start = it;
 
- next = std::find(next, end, delim);
- string_ref value(value_start, next);
- if (next == end) break;
- ++next;
+ it = std::find(it, end, delim);
+ string_ref value(value_start, it);
+ if (it == end) break;
+ ++it;
 
- if (std::find(id_attributes.begin(),
- id_attributes.end(), name)
+ if (std::find(id_attributes.begin(), id_attributes.end(),
+ name)
                                 != id_attributes.end())
                         {
- result.append(pos, value.begin());
+ result.append(copied, value.begin());
                             string_ref x = ids.get(value);
                             result.append(x.begin(), x.end());
- pos = value.end();
+ copied = value.end();
                         }
                     }
                 }
                 else
                 {
- next = std::find(next + 1, end, '>');
- if (next != end) ++next;
+ it = std::find(it, end, '>');
                 }
             }
         }
         
- result.append(pos, source.end());
+ result.append(copied, source.end());
         return result;
     }
 }

Modified: trunk/tools/quickbook/test/escape.gold
==============================================================================
--- trunk/tools/quickbook/test/escape.gold (original)
+++ trunk/tools/quickbook/test/escape.gold 2011-07-27 19:50:41 EDT (Wed, 27 Jul 2011)
@@ -13,5 +13,14 @@
     <para>
       These should be properly encoded: &gt; &lt; &quot;
     </para>
+ <para>
+ This <link linkend="$0">link</link> shouldn't be changed.
+ </para>
+ <para>
+ Some other problematic links:
+<link linkend="$157">one</link>,
+<link linkend="$-256">two</link>,
+<link linkend="$text">three</link>.
+ </para>
   </section>
 </article>

Modified: trunk/tools/quickbook/test/escape.quickbook
==============================================================================
--- trunk/tools/quickbook/test/escape.quickbook (original)
+++ trunk/tools/quickbook/test/escape.quickbook 2011-07-27 19:50:41 EDT (Wed, 27 Jul 2011)
@@ -11,5 +11,18 @@
 
 These should be properly encoded: \> \< \"
 
+[/ The following tests are based on internal knowledge of
+ how quickbook's id generator works. They make sure it
+ doesn't mess up escaped docbook. ]
+
+'''This <link linkend="$0">link</link> shouldn't be changed.'''
+
+'''
+Some other problematic links:
+<link linkend="$157">one</link>,
+<link linkend="$-256">two</link>,
+<link linkend="$text">three</link>.
+'''
+
 [endsect]
 


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