mirror of
https://github.com/boostorg/quickbook.git
synced 2026-02-01 08:42:16 +00:00
111 lines
3.4 KiB
C++
111 lines
3.4 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 "utils.hpp"
|
|
|
|
#include <cctype>
|
|
#include <cstring>
|
|
#include <map>
|
|
|
|
namespace quickbook { namespace detail
|
|
{
|
|
std::string encode_string(boost::string_ref str)
|
|
{
|
|
std::string result;
|
|
result.reserve(str.size());
|
|
|
|
for (boost::string_ref::const_iterator it = str.begin();
|
|
it != str.end(); ++it)
|
|
{
|
|
switch (*it)
|
|
{
|
|
case '<': result += "<"; break;
|
|
case '>': result += ">"; break;
|
|
case '&': result += "&"; break;
|
|
case '"': result += """; break;
|
|
default: result += *it; break;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void print_char(char ch, std::ostream& out)
|
|
{
|
|
switch (ch)
|
|
{
|
|
case '<': out << "<"; break;
|
|
case '>': out << ">"; break;
|
|
case '&': out << "&"; break;
|
|
case '"': out << """; break;
|
|
default: out << ch; break;
|
|
// note ' is not included. see the curse of apos:
|
|
// http://fishbowl.pastiche.org/2003/07/01/the_curse_of_apos
|
|
}
|
|
}
|
|
|
|
void print_string(boost::string_ref str, std::ostream& out)
|
|
{
|
|
for (boost::string_ref::const_iterator cur = str.begin();
|
|
cur != str.end(); ++cur)
|
|
{
|
|
print_char(*cur, out);
|
|
}
|
|
}
|
|
|
|
char filter_identifier_char(char ch)
|
|
{
|
|
if (!std::isalnum(static_cast<unsigned char>(ch)))
|
|
ch = '_';
|
|
return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
|
|
}
|
|
|
|
static std::string escape_uri_impl(std::string& uri_param, char const* mark)
|
|
{
|
|
// Extra capital characters for validating percent escapes.
|
|
static char const hex[] = "0123456789abcdefABCDEF";
|
|
|
|
std::string uri;
|
|
uri.swap(uri_param);
|
|
|
|
for (std::string::size_type n = 0; n < uri.size(); ++n)
|
|
{
|
|
if (static_cast<unsigned char>(uri[n]) > 127 ||
|
|
(!std::isalnum(static_cast<unsigned char>(uri[n])) &&
|
|
!std::strchr(mark, uri[n])) ||
|
|
(uri[n] == '%' && !(n + 2 < uri.size() &&
|
|
std::strchr(hex, uri[n+1]) &&
|
|
std::strchr(hex, uri[n+2]))))
|
|
{
|
|
char escape[] = { hex[uri[n] / 16], hex[uri[n] % 16] };
|
|
uri.insert(n + 1, escape, 2);
|
|
uri[n] = '%';
|
|
n += 2;
|
|
}
|
|
else if (uri[n] == '%')
|
|
{
|
|
n += 2;
|
|
}
|
|
}
|
|
|
|
return uri;
|
|
}
|
|
|
|
std::string escape_uri(std::string uri_param)
|
|
{
|
|
// TODO: I don't understand this choice of characters.....
|
|
return escape_uri_impl(uri_param, "-_.!~*'()?\\/");
|
|
}
|
|
|
|
std::string partially_escape_uri(std::string uri_param)
|
|
{
|
|
return escape_uri_impl(uri_param, "-_.!~*'()?\\/:&=#%");
|
|
}
|
|
}}
|