Verbatim-safe typography, ^-punctuation quoting, full-range ^UUUU^, polyglot html
Typographic transforms (---, quote pairs, ~) no longer touch verbatim text: @c/@code/@source_listing content and ^'...'^ spans show exactly the characters written. "^" before any punctuation character quotes it in every target (the apostrophe excepted: ^' opens a literal span), with the new :resolve option on @@@target declaring per-target renderings. The ^UUUU^ code-point form accepts 4-6 hex digits, the full Unicode range. The html output and transform spellings are polyglot (XML-valid), in preparation for an EPUB target. New suites: transform_test, character_test (engine), typography_test (SKS). (from dev 07ce5ea86a0a)
This commit is contained in:
@@ -36,6 +36,9 @@ std::string utf8char(int cp)
|
||||
c[1] = ((cp>>12)&63)+128;
|
||||
c[2] = ((cp>>6)&63)+128;
|
||||
c[3]=(cp&63)+128;
|
||||
} else {
|
||||
// Reachable since ^UUUU^ accepts 6 hex digits: FFFFFF > 10FFFF.
|
||||
return "Invalid Unicode: " + std::to_string(cp);
|
||||
}
|
||||
return std::string(c);
|
||||
}
|
||||
@@ -65,7 +68,13 @@ std::string unicode_hex_to_char(std::string s, int width=4) //, std::string mark
|
||||
std::string process_diacritics(std::string s)
|
||||
{
|
||||
(void)K::log(4);
|
||||
std::regex diacritic_re("\\^([^\\s`'~@|^:*#])([" + diacritic_symbols + "])");
|
||||
// The base may not be whitespace, a digit, or ASCII punctuation (the
|
||||
// four ranges !-/ :-@ [-` {-~): a diacritic sits on a letter. Without
|
||||
// the exclusion, ^ before a quoted punctuation character followed by a
|
||||
// mark character composed nonsense -- ^-- became a hyphen with a macron
|
||||
// instead of a literal hyphen before a hyphen. A multi-byte (non-ASCII)
|
||||
// base is unaffected: its bytes are outside every excluded range.
|
||||
std::regex diacritic_re("\\^([^\\s0-9!-/:-@\\[-`{-~])([" + diacritic_symbols + "])");
|
||||
|
||||
std::string result {s};
|
||||
std::sregex_iterator end {};
|
||||
@@ -126,9 +135,14 @@ std::string process_unicode_codepoint(std::string s)
|
||||
//return std::regex_replace(s, unicode_re, hidehat + "$1" + hidehat);
|
||||
std::string result {s};
|
||||
std::sregex_iterator end {};
|
||||
for (std::sregex_iterator p { s.begin(), s.end(), unicode_re }; p!= end; ++p) {
|
||||
for (std::sregex_iterator p { s.begin(), s.end(), unicode_re }; p!= end; ++p) {
|
||||
std::regex hit_re { regex_escape((*p)[0].str()) };
|
||||
result = std::regex_replace(result, hit_re, unicode_hex_to_char((*p)[1].str()));
|
||||
// Convert the captured hex DIRECTLY: unicode_hex_to_char() re-scans
|
||||
// its argument at a fixed width, and its 4-digit default truncated a
|
||||
// 5-digit code point to its first four digits (^13000^ rendered as
|
||||
// U+1300 followed by a literal "0").
|
||||
result = std::regex_replace(result, hit_re,
|
||||
utf8char(std::stoi((*p)[1].str(), nullptr, 16)));
|
||||
}
|
||||
return result;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user