convert thesaurus and spellchecker to docstring

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16229 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2006-12-10 11:52:46 +00:00
parent 6836e00c07
commit 55f575c4dd
16 changed files with 102 additions and 92 deletions

View File

@ -12,17 +12,17 @@
#include "Thesaurus.h" #include "Thesaurus.h"
#include "support/lstrings.h"
#include <algorithm> #include <algorithm>
#include <string>
namespace lyx { namespace lyx {
using std::string;
#ifdef HAVE_LIBAIKSAURUS #ifdef HAVE_LIBAIKSAURUS
using std::sort; using std::sort;
using std::string;
Thesaurus::Thesaurus() Thesaurus::Thesaurus()
@ -36,10 +36,19 @@ Thesaurus::~Thesaurus()
} }
Thesaurus::Meanings Thesaurus::lookup(string const & text) Thesaurus::Meanings Thesaurus::lookup(docstring const & t)
{ {
Meanings meanings; Meanings meanings;
// aiksaurus is for english text only, therefore it does not work
// with non-ascii strings.
// The interface of the Thesaurus class uses docstring because a
// non-english thesaurus is possible in theory.
if (!support::isAscii(t))
// to_ascii() would assert
return meanings;
string const text = to_ascii(t);
if (!aik_->find(text.c_str())) if (!aik_->find(text.c_str()))
return meanings; return meanings;
@ -47,29 +56,27 @@ Thesaurus::Meanings Thesaurus::lookup(string const & text)
int prev_meaning = -1; int prev_meaning = -1;
int cur_meaning; int cur_meaning;
string meaning; docstring meaning;
// correct, returns "" at the end // correct, returns "" at the end
string ret = aik_->next(cur_meaning); string ret = aik_->next(cur_meaning);
while (!ret.empty()) { while (!ret.empty()) {
if (cur_meaning != prev_meaning) { if (cur_meaning != prev_meaning) {
meaning = ret; meaning = from_ascii(ret);
ret = aik_->next(cur_meaning); ret = aik_->next(cur_meaning);
prev_meaning = cur_meaning; prev_meaning = cur_meaning;
} else { } else {
if (ret != text) { if (ret != text)
meanings[meaning].push_back(ret); meanings[meaning].push_back(from_ascii(ret));
}
} }
ret = aik_->next(cur_meaning); ret = aik_->next(cur_meaning);
} }
for (Meanings::iterator it = meanings.begin(); for (Meanings::iterator it = meanings.begin();
it != meanings.end(); ++it) { it != meanings.end(); ++it)
sort(it->second.begin(), it->second.end()); sort(it->second.begin(), it->second.end());
}
return meanings; return meanings;
} }
@ -86,7 +93,7 @@ Thesaurus::~Thesaurus()
} }
Thesaurus::Meanings Thesaurus::lookup(string const &) Thesaurus::Meanings Thesaurus::lookup(docstring const &)
{ {
return Meanings(); return Meanings();
} }

View File

@ -12,9 +12,10 @@
#ifndef THESAURUS_H #ifndef THESAURUS_H
#define THESAURUS_H #define THESAURUS_H
#include "support/docstring.h"
#include <vector> #include <vector>
#include <map> #include <map>
#include <string>
#ifdef HAVE_LIBAIKSAURUS #ifdef HAVE_LIBAIKSAURUS
#include AIKSAURUS_H_LOCATION #include AIKSAURUS_H_LOCATION
@ -33,12 +34,12 @@ public:
/// ///
~Thesaurus(); ~Thesaurus();
typedef std::map<std::string, std::vector<std::string> > Meanings; typedef std::map<docstring, std::vector<docstring> > Meanings;
/** /**
* look up some text in the thesaurus * look up some text in the thesaurus
*/ */
Meanings lookup(std::string const & text); Meanings lookup(docstring const & text);
private: private:
#ifdef HAVE_LIBAIKSAURUS #ifdef HAVE_LIBAIKSAURUS

View File

@ -15,8 +15,6 @@
#include "funcrequest.h" #include "funcrequest.h"
#include "lyxfind.h" #include "lyxfind.h"
using std::string;
namespace lyx { namespace lyx {
namespace frontend { namespace frontend {
@ -25,20 +23,20 @@ ControlSearch::ControlSearch(Dialog & parent)
{} {}
void ControlSearch::find(string const & search, bool casesensitive, void ControlSearch::find(docstring const & search, bool casesensitive,
bool matchword, bool forward) bool matchword, bool forward)
{ {
string const data = find2string(search, casesensitive, docstring const data = find2string(search, casesensitive,
matchword, forward); matchword, forward);
kernel().dispatch(FuncRequest(LFUN_WORD_FIND, data)); kernel().dispatch(FuncRequest(LFUN_WORD_FIND, data));
} }
void ControlSearch::replace(string const & search, string const & replace, void ControlSearch::replace(docstring const & search, docstring const & replace,
bool casesensitive, bool matchword, bool casesensitive, bool matchword,
bool forward, bool all) bool forward, bool all)
{ {
string const data = docstring const data =
replace2string(search, replace, casesensitive, replace2string(search, replace, casesensitive,
matchword, all, forward); matchword, all, forward);
kernel().dispatch(FuncRequest(LFUN_WORD_REPLACE, data)); kernel().dispatch(FuncRequest(LFUN_WORD_REPLACE, data));

View File

@ -29,11 +29,11 @@ public:
virtual bool isBufferDependent() const { return true; } virtual bool isBufferDependent() const { return true; }
/// Searches occurence of string /// Searches occurence of string
void find(std::string const & search, void find(docstring const & search,
bool casesensitive, bool matchword, bool forward); bool casesensitive, bool matchword, bool forward);
/// Replaces occurence of string /// Replaces occurence of string
void replace(std::string const & search, std::string const & replace, void replace(docstring const & search, docstring const & replace,
bool casesensitive, bool matchword, bool casesensitive, bool matchword,
bool forward, bool all); bool forward, bool all);
}; };

View File

@ -27,7 +27,7 @@ ControlThesaurus::ControlThesaurus(Dialog & parent)
bool ControlThesaurus::initialiseParams(string const & data) bool ControlThesaurus::initialiseParams(string const & data)
{ {
oldstr_ = data; oldstr_ = from_utf8(data);
return true; return true;
} }
@ -38,13 +38,13 @@ void ControlThesaurus::clearParams()
} }
void ControlThesaurus::replace(string const & newstr) void ControlThesaurus::replace(docstring const & newstr)
{ {
/* FIXME: this is not suitable ! We need to have a "lock" /* FIXME: this is not suitable ! We need to have a "lock"
* on a particular charpos in a paragraph that is broken on * on a particular charpos in a paragraph that is broken on
* deletion/change ! * deletion/change !
*/ */
string const data = docstring const data =
replace2string(oldstr_, newstr, replace2string(oldstr_, newstr,
true, // case sensitive true, // case sensitive
true, // match word true, // match word
@ -54,7 +54,7 @@ void ControlThesaurus::replace(string const & newstr)
} }
Thesaurus::Meanings const & ControlThesaurus::getMeanings(string const & str) Thesaurus::Meanings const & ControlThesaurus::getMeanings(docstring const & str)
{ {
if (str != laststr_) if (str != laststr_)
meanings_ = thesaurus.lookup(str); meanings_ = thesaurus.lookup(str);

View File

@ -35,23 +35,23 @@ public:
virtual bool isBufferDependent() const { return true; } virtual bool isBufferDependent() const { return true; }
/// replace the particular string /// replace the particular string
void replace(std::string const & newstr); void replace(docstring const & newstr);
/// get meanings /// get meanings
Thesaurus::Meanings const & getMeanings(std::string const & str); Thesaurus::Meanings const & getMeanings(docstring const & str);
/// the text /// the text
std::string const & text() const { return oldstr_; } docstring const & text() const { return oldstr_; }
private: private:
/// last string looked up /// last string looked up
std::string laststr_; docstring laststr_;
/// entries for last string /// entries for last string
Thesaurus::Meanings meanings_; Thesaurus::Meanings meanings_;
/// original string /// original string
std::string oldstr_; docstring oldstr_;
/// not needed. /// not needed.
virtual void apply() {} virtual void apply() {}

View File

@ -46,14 +46,14 @@ void QSearch::build_dialog()
} }
void QSearch::find(string const & str, bool casesens, void QSearch::find(docstring const & str, bool casesens,
bool words, bool backwards) bool words, bool backwards)
{ {
controller().find(str, casesens, words, !backwards); controller().find(str, casesens, words, !backwards);
} }
void QSearch::replace(string const & findstr, string const & replacestr, void QSearch::replace(docstring const & findstr, docstring const & replacestr,
bool casesens, bool words, bool backwards, bool all) bool casesens, bool words, bool backwards, bool all)
{ {
controller().replace(findstr, replacestr, casesens, words, controller().replace(findstr, replacestr, casesens, words,

View File

@ -37,11 +37,11 @@ private:
/// build the dialog /// build the dialog
virtual void build_dialog(); virtual void build_dialog();
void find(std::string const & str, bool casesens, void find(docstring const & str, bool casesens,
bool words, bool backwards); bool words, bool backwards);
void replace(std::string const & findstr, void replace(docstring const & findstr,
std::string const & replacestr, docstring const & replacestr,
bool casesens, bool words, bool backwards, bool all); bool casesens, bool words, bool backwards, bool all);
}; };

View File

@ -22,7 +22,6 @@
#include <qlineedit.h> #include <qlineedit.h>
#include <qpushbutton.h> #include <qpushbutton.h>
using std::string;
namespace lyx { namespace lyx {
namespace frontend { namespace frontend {
@ -88,7 +87,7 @@ void QSearchDialog::findChanged()
void QSearchDialog::findClicked() void QSearchDialog::findClicked()
{ {
string const find(fromqstr(findCO->currentText())); docstring const find(qstring_to_ucs4(findCO->currentText()));
form_->find(find, form_->find(find,
caseCB->isChecked(), caseCB->isChecked(),
wordsCB->isChecked(), wordsCB->isChecked(),
@ -99,8 +98,8 @@ void QSearchDialog::findClicked()
void QSearchDialog::replaceClicked() void QSearchDialog::replaceClicked()
{ {
string const find(fromqstr(findCO->currentText())); docstring const find(qstring_to_ucs4(findCO->currentText()));
string const replace(fromqstr(replaceCO->currentText())); docstring const replace(qstring_to_ucs4(replaceCO->currentText()));
form_->replace(find, replace, form_->replace(find, replace,
caseCB->isChecked(), caseCB->isChecked(),
wordsCB->isChecked(), wordsCB->isChecked(),
@ -112,8 +111,8 @@ void QSearchDialog::replaceClicked()
void QSearchDialog::replaceallClicked() void QSearchDialog::replaceallClicked()
{ {
form_->replace(fromqstr(findCO->currentText()), form_->replace(qstring_to_ucs4(findCO->currentText()),
fromqstr(replaceCO->currentText()), qstring_to_ucs4(replaceCO->currentText()),
caseCB->isChecked(), caseCB->isChecked(),
wordsCB->isChecked(), wordsCB->isChecked(),
false, true); false, true);

View File

@ -52,7 +52,7 @@ void QThesaurus::update_contents()
void QThesaurus::replace() void QThesaurus::replace()
{ {
controller().replace(fromqstr(dialog_->replaceED->text())); controller().replace(qstring_to_ucs4(dialog_->replaceED->text()));
} }
} // namespace frontend } // namespace frontend

View File

@ -113,14 +113,14 @@ void QThesaurusDialog::updateLists()
meaningsTV->clear(); meaningsTV->clear();
meaningsTV->setUpdatesEnabled(false); meaningsTV->setUpdatesEnabled(false);
Thesaurus::Meanings meanings = form_->controller().getMeanings(fromqstr(entryED->text())); Thesaurus::Meanings meanings = form_->controller().getMeanings(qstring_to_ucs4(entryED->text()));
for (Thesaurus::Meanings::const_iterator cit = meanings.begin(); for (Thesaurus::Meanings::const_iterator cit = meanings.begin();
cit != meanings.end(); ++cit) { cit != meanings.end(); ++cit) {
QTreeWidgetItem * i = new QTreeWidgetItem(meaningsTV); QTreeWidgetItem * i = new QTreeWidgetItem(meaningsTV);
i->setText(0, toqstr(cit->first)); i->setText(0, toqstr(cit->first));
meaningsTV->expandItem(i); meaningsTV->expandItem(i);
for (std::vector<string>::const_iterator cit2 = cit->second.begin(); for (std::vector<docstring>::const_iterator cit2 = cit->second.begin();
cit2 != cit->second.end(); ++cit2) { cit2 != cit->second.end(); ++cit2) {
QTreeWidgetItem * i2 = new QTreeWidgetItem(i); QTreeWidgetItem * i2 = new QTreeWidgetItem(i);
i2->setText(0, toqstr(*cit2)); i2->setText(0, toqstr(*cit2));

View File

@ -30,8 +30,7 @@
#include "frontends/Alert.h" #include "frontends/Alert.h"
#include "support/convert.h" #include "support/convert.h"
#include "support/docstream.h"
#include <sstream>
namespace lyx { namespace lyx {
@ -40,17 +39,15 @@ using support::uppercase;
using support::split; using support::split;
using std::advance; using std::advance;
using std::ostringstream;
using std::string;
namespace { namespace {
bool parse_bool(string & howto) bool parse_bool(docstring & howto)
{ {
if (howto.empty()) if (howto.empty())
return false; return false;
string var; docstring var;
howto = split(howto, var, ' '); howto = split(howto, var, ' ');
return (var == "1"); return (var == "1");
} }
@ -59,18 +56,18 @@ bool parse_bool(string & howto)
class MatchString : public std::binary_function<Paragraph, pos_type, bool> class MatchString : public std::binary_function<Paragraph, pos_type, bool>
{ {
public: public:
MatchString(string const & str, bool cs, bool mw) MatchString(docstring const & str, bool cs, bool mw)
: str(str), cs(cs), mw(mw) : str(str), cs(cs), mw(mw)
{} {}
// returns true if the specified string is at the specified position // returns true if the specified string is at the specified position
bool operator()(Paragraph const & par, pos_type pos) const bool operator()(Paragraph const & par, pos_type pos) const
{ {
string::size_type const size = str.length(); docstring::size_type const size = str.length();
pos_type i = 0; pos_type i = 0;
pos_type const parsize = par.size(); pos_type const parsize = par.size();
for (i = 0; pos + i < parsize; ++i) { for (i = 0; pos + i < parsize; ++i) {
if (string::size_type(i) >= size) if (docstring::size_type(i) >= size)
break; break;
if (cs && str[i] != par.getChar(pos + i)) if (cs && str[i] != par.getChar(pos + i))
break; break;
@ -78,7 +75,7 @@ public:
break; break;
} }
if (size != string::size_type(i)) if (size != docstring::size_type(i))
return false; return false;
// if necessary, check whether string matches word // if necessary, check whether string matches word
@ -95,7 +92,7 @@ public:
private: private:
// search string // search string
string str; docstring str;
// case sensitive // case sensitive
bool cs; bool cs;
// match whole words only // match whole words only
@ -132,7 +129,7 @@ bool findChange(DocIterator & cur)
} }
bool searchAllowed(BufferView * bv, string const & str) bool searchAllowed(BufferView * bv, docstring const & str)
{ {
if (str.empty()) { if (str.empty()) {
frontend::Alert::error(_("Search error"), frontend::Alert::error(_("Search error"),
@ -143,7 +140,7 @@ bool searchAllowed(BufferView * bv, string const & str)
} }
bool find(BufferView * bv, string const & searchstr, bool cs, bool mw, bool fw) bool find(BufferView * bv, docstring const & searchstr, bool cs, bool mw, bool fw)
{ {
if (!searchAllowed(bv, searchstr)) if (!searchAllowed(bv, searchstr))
return false; return false;
@ -162,7 +159,7 @@ bool find(BufferView * bv, string const & searchstr, bool cs, bool mw, bool fw)
int replaceAll(BufferView * bv, int replaceAll(BufferView * bv,
string const & searchstr, string const & replacestr, docstring const & searchstr, docstring const & replacestr,
bool cs, bool mw) bool cs, bool mw)
{ {
Buffer & buf = *bv->buffer(); Buffer & buf = *bv->buffer();
@ -185,7 +182,7 @@ int replaceAll(BufferView * bv,
= cur.paragraph().getFontSettings(buf.params(), pos); = cur.paragraph().getFontSettings(buf.params(), pos);
int striked = ssize - cur.paragraph().eraseChars(pos, pos + ssize, int striked = ssize - cur.paragraph().eraseChars(pos, pos + ssize,
buf.params().trackChanges); buf.params().trackChanges);
cur.paragraph().insert(pos, from_utf8(replacestr), font, cur.paragraph().insert(pos, replacestr, font,
Change(buf.params().trackChanges ? Change(buf.params().trackChanges ?
Change::INSERTED : Change::UNCHANGED)); Change::INSERTED : Change::UNCHANGED));
for (int i = 0; i < rsize + striked; ++i) for (int i = 0; i < rsize + striked; ++i)
@ -201,13 +198,13 @@ int replaceAll(BufferView * bv,
} }
bool stringSelected(BufferView * bv, string const & searchstr, bool stringSelected(BufferView * bv, docstring const & searchstr,
bool cs, bool mw, bool fw) bool cs, bool mw, bool fw)
{ {
// if nothing selected or selection does not equal search // if nothing selected or selection does not equal search
// string search and select next occurance and return // string search and select next occurance and return
string const & str1 = searchstr; docstring const & str1 = searchstr;
string const str2 = to_utf8(bv->cursor().selectionAsString(false)); docstring const str2 = bv->cursor().selectionAsString(false);
if ((cs && str1 != str2) || lowercase(str1) != lowercase(str2)) { if ((cs && str1 != str2) || lowercase(str1) != lowercase(str2)) {
find(bv, searchstr, cs, mw, fw); find(bv, searchstr, cs, mw, fw);
return false; return false;
@ -217,8 +214,8 @@ bool stringSelected(BufferView * bv, string const & searchstr,
} }
int replace(BufferView * bv, string const & searchstr, int replace(BufferView * bv, docstring const & searchstr,
string const & replacestr, bool cs, bool mw, bool fw) docstring const & replacestr, bool cs, bool mw, bool fw)
{ {
if (!searchAllowed(bv, searchstr) || bv->buffer()->isReadonly()) if (!searchAllowed(bv, searchstr) || bv->buffer()->isReadonly())
return 0; return 0;
@ -227,7 +224,7 @@ int replace(BufferView * bv, string const & searchstr,
return 0; return 0;
LCursor & cur = bv->cursor(); LCursor & cur = bv->cursor();
cap::replaceSelectionWithString(cur, from_utf8(replacestr), fw); cap::replaceSelectionWithString(cur, replacestr, fw);
bv->buffer()->markDirty(); bv->buffer()->markDirty();
find(bv, searchstr, cs, mw, fw); find(bv, searchstr, cs, mw, fw);
bv->update(); bv->update();
@ -238,10 +235,10 @@ int replace(BufferView * bv, string const & searchstr,
} // namespace anon } // namespace anon
string const find2string(string const & search, docstring const find2string(docstring const & search,
bool casesensitive, bool matchword, bool forward) bool casesensitive, bool matchword, bool forward)
{ {
ostringstream ss; odocstringstream ss;
ss << search << '\n' ss << search << '\n'
<< int(casesensitive) << ' ' << int(casesensitive) << ' '
<< int(matchword) << ' ' << int(matchword) << ' '
@ -250,11 +247,11 @@ string const find2string(string const & search,
} }
string const replace2string(string const & search, string const & replace, docstring const replace2string(docstring const & search, docstring const & replace,
bool casesensitive, bool matchword, bool casesensitive, bool matchword,
bool all, bool forward) bool all, bool forward)
{ {
ostringstream ss; odocstringstream ss;
ss << search << '\n' ss << search << '\n'
<< replace << '\n' << replace << '\n'
<< int(casesensitive) << ' ' << int(casesensitive) << ' '
@ -275,8 +272,8 @@ void find(BufferView * bv, FuncRequest const & ev)
// data is of the form // data is of the form
// "<search> // "<search>
// <casesensitive> <matchword> <forward>" // <casesensitive> <matchword> <forward>"
string search; docstring search;
string howto = split(to_utf8(ev.argument()), search, '\n'); docstring howto = split(ev.argument(), search, '\n');
bool casesensitive = parse_bool(howto); bool casesensitive = parse_bool(howto);
bool matchword = parse_bool(howto); bool matchword = parse_bool(howto);
@ -300,9 +297,9 @@ void replace(BufferView * bv, FuncRequest const & ev)
// "<search> // "<search>
// <replace> // <replace>
// <casesensitive> <matchword> <all> <forward>" // <casesensitive> <matchword> <all> <forward>"
string search; docstring search;
string rplc; docstring rplc;
string howto = split(to_utf8(ev.argument()), search, '\n'); docstring howto = split(ev.argument(), search, '\n');
howto = split(howto, rplc, '\n'); howto = split(howto, rplc, '\n');
bool casesensitive = parse_bool(howto); bool casesensitive = parse_bool(howto);

View File

@ -15,9 +15,7 @@
#ifndef LYXFIND_H #ifndef LYXFIND_H
#define LYXFIND_H #define LYXFIND_H
#include "support/types.h" #include "support/docstring.h"
#include <string>
namespace lyx { namespace lyx {
@ -28,7 +26,7 @@ class LyXText;
/** Encode the parameters needed to find \c search as a string /** Encode the parameters needed to find \c search as a string
* that can be dispatched to the LyX core in a FuncRequest wrapper. * that can be dispatched to the LyX core in a FuncRequest wrapper.
*/ */
std::string const find2string(std::string const & search, docstring const find2string(docstring const & search,
bool casesensitive, bool casesensitive,
bool matchword, bool matchword,
bool forward); bool forward);
@ -37,8 +35,8 @@ std::string const find2string(std::string const & search,
* as a string that can be dispatched to the LyX core in a FuncRequest * as a string that can be dispatched to the LyX core in a FuncRequest
* wrapper. * wrapper.
*/ */
std::string const replace2string(std::string const & search, docstring const replace2string(docstring const & search,
std::string const & replace, docstring const & replace,
bool casesensitive, bool casesensitive,
bool matchword, bool matchword,
bool all, bool all,

View File

@ -764,12 +764,12 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
case LFUN_WORD_FIND_FORWARD: case LFUN_WORD_FIND_FORWARD:
case LFUN_WORD_FIND_BACKWARD: { case LFUN_WORD_FIND_BACKWARD: {
BOOST_ASSERT(lyx_view_ && lyx_view_->view()); BOOST_ASSERT(lyx_view_ && lyx_view_->view());
static string last_search; static docstring last_search;
string searched_string; docstring searched_string;
if (!argument.empty()) { if (!cmd.argument().empty()) {
last_search = argument; last_search = cmd.argument();
searched_string = argument; searched_string = cmd.argument();
} else { } else {
searched_string = last_search; searched_string = last_search;
} }
@ -778,7 +778,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
break; break;
bool const fw = action == LFUN_WORD_FIND_FORWARD; bool const fw = action == LFUN_WORD_FIND_FORWARD;
string const data = docstring const data =
find2string(searched_string, true, false, fw); find2string(searched_string, true, false, fw);
find(view(), FuncRequest(LFUN_WORD_FIND, data)); find(view(), FuncRequest(LFUN_WORD_FIND, data));
break; break;

View File

@ -361,8 +361,8 @@ namespace {
// since we cannot use std::tolower and std::toupper directly in the // since we cannot use std::tolower and std::toupper directly in the
// calls to std::transform yet, we use these helper clases. (Lgb) // calls to std::transform yet, we use these helper clases. (Lgb)
struct local_lowercase { template<typename Char> struct local_lowercase {
char operator()(char c) const { Char operator()(Char c) const {
return tolower(c); return tolower(c);
} }
}; };
@ -384,10 +384,19 @@ struct local_ascii_lowercase {
string const lowercase(string const & a) string const lowercase(string const & a)
{ {
string tmp(a); string tmp(a);
transform(tmp.begin(), tmp.end(), tmp.begin(), local_lowercase()); transform(tmp.begin(), tmp.end(), tmp.begin(), local_lowercase<char>());
return tmp; return tmp;
} }
docstring const lowercase(docstring const & a)
{
docstring tmp(a);
transform(tmp.begin(), tmp.end(), tmp.begin(), local_lowercase<char_type>());
return tmp;
}
string const uppercase(string const & a) string const uppercase(string const & a)
{ {
string tmp(a); string tmp(a);

View File

@ -92,6 +92,7 @@ std::string const ascii_lowercase(std::string const &);
/// ///
std::string const lowercase(std::string const &); std::string const lowercase(std::string const &);
docstring const lowercase(docstring const &);
/// ///
std::string const uppercase(std::string const &); std::string const uppercase(std::string const &);