From 06eb8c6edcb0df79717f9cf3afb4061b57157382 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Sat, 28 Nov 2020 15:32:25 +0100 Subject: issue #697: Test 32 reference to bell signal (XHTML, LaTeX) --- src/context.cpp | 14 +++++++++++++ src/docbookgen.cpp | 18 ++++++++++++++--- src/htmldocvisitor.cpp | 46 +++++++++++++++++++++++++++++++---------- src/htmlgen.cpp | 55 ++++++++++++++++++++++++++++++++++++-------------- src/util.cpp | 47 +++++++++++++++++++++++++++++++++--------- 5 files changed, 142 insertions(+), 38 deletions(-) diff --git a/src/context.cpp b/src/context.cpp index fc8833d..074e6ec 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -3802,6 +3802,7 @@ class TextGeneratorHtml : public TextGeneratorIntf : m_ts(ts), m_relPath(relPath) {} void writeString(const char *s,bool keepSpaces) const { + static const char *hex="0123456789ABCDEF"; if (s==0) return; if (keepSpaces) { @@ -3817,6 +3818,19 @@ class TextGeneratorHtml : public TextGeneratorIntf case '"': m_ts << """; break; case '&': m_ts << "&"; break; case ' ': m_ts << " "; break; + default: + { + uchar uc = static_cast(c); + if (uc<32 && !isspace(c)) // non-printable control characters + { + m_ts << "$" << hex[uc>>4] << hex[uc&0xF] << ";"; + } + else + { + m_ts << c; + } + } + break; } } } diff --git a/src/docbookgen.cpp b/src/docbookgen.cpp index db11c67..3615ad5 100644 --- a/src/docbookgen.cpp +++ b/src/docbookgen.cpp @@ -101,9 +101,21 @@ inline void writeDocbookCodeString(FTextStream &t,const char *s, int &col) case '&': t << "&"; col++; break; case '\'': t << "'"; col++; break; case '"': t << """; col++; break; - case '\007': t << "^G"; col++; break; // bell - case '\014': t << "^L"; col++; break; // form feed - default: t << c; col++; break; + default: + { + uchar uc = static_cast(c); + static const char *hex="0123456789ABCDEF"; + if (uc<32) + { + t << "$" << hex[uc>>4] << hex[uc&0xF] << ";"; + } + else + { + t << c; + } + col++; + } + break; } } } diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index a60a291..b93a2c4 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -62,10 +62,10 @@ static const char *contexts[10] = "interdd", // 8 "intertd" // 9 }; +static const char *hex="0123456789ABCDEF"; static QCString convertIndexWordToAnchor(const QCString &word) { - static char hex[] = "0123456789abcdef"; static int cnt = 0; QCString result="a"; QCString cntStr; @@ -2218,11 +2218,23 @@ void HtmlDocVisitor::filter(const char *str) case '>': m_t << ">"; break; case '&': m_t << "&"; break; case '\\': if ((*p == '(') || (*p == ')')) - m_t << "\\‍" << *p++; - else - m_t << c; - break; - default: m_t << c; + m_t << "\\‍" << *p++; + else + m_t << c; + break; + default: + { + uchar uc = static_cast(c); + if (uc<32 && !isspace(c)) // non-printable control characters + { + m_t << "$" << hex[uc>>4] << hex[uc&0xF] << ";"; + } + else + { + m_t << c; + } + } + break; } } } @@ -2244,11 +2256,23 @@ void HtmlDocVisitor::filterQuotedCdataAttr(const char* str) case '<': m_t << "<"; break; case '>': m_t << ">"; break; case '\\': if ((*p == '(') || (*p == ')')) - m_t << "\\‍" << *p++; - else - m_t << c; - break; - default: m_t << c; + m_t << "\\‍" << *p++; + else + m_t << c; + break; + default: + { + uchar uc = static_cast(c); + if (uc<32 && !isspace(c)) // non-printable control characters + { + m_t << "$" << hex[uc>>4] << hex[uc&0xF] << ";"; + } + else + { + m_t << c; + } + } + break; } } } diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 3a92020..58a0622 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -60,6 +60,7 @@ static QCString g_header; static QCString g_footer; static QCString g_mathjax_code; static QCString g_latex_macro; +static const char *hex="0123456789ABCDEF"; // note: this is only active if DISABLE_INDEX=YES, if DISABLE_INDEX is disabled, this // part will be rendered inside menu.js @@ -672,9 +673,21 @@ void HtmlCodeGenerator::codify(const char *str) m_t << "\\"; m_col++; break; - default: p=writeUtf8Char(m_t,p-1); - m_col++; - break; + default: + { + uchar uc = static_cast(c); + if (uc<32) + { + m_t << "$" << hex[uc>>4] << hex[uc&0xF] << ";"; + m_col++; + } + else + { + p=writeUtf8Char(m_t,p-1); + m_col++; + } + } + break; } } } @@ -698,18 +711,30 @@ void HtmlCodeGenerator::docify(const char *str) case '&': m_t << "&"; break; case '"': m_t << """; break; case '\\': - if (*p=='<') - { m_t << "<"; p++; } - else if (*p=='>') - { m_t << ">"; p++; } - else if (*p=='(') - { m_t << "\\‍("; p++; } - else if (*p==')') - { m_t << "\\‍)"; p++; } - else - m_t << "\\"; - break; - default: m_t << c; + if (*p=='<') + { m_t << "<"; p++; } + else if (*p=='>') + { m_t << ">"; p++; } + else if (*p=='(') + { m_t << "\\‍("; p++; } + else if (*p==')') + { m_t << "\\‍)"; p++; } + else + m_t << "\\"; + break; + default: + { + uchar uc = static_cast(c); + if (uc<32 && !isspace(c)) + { + m_t << "$" << hex[uc>>4] << hex[uc&0xF] << ";"; + } + else + { + m_t << c; + } + } + break; } } } diff --git a/src/util.cpp b/src/util.cpp index bc0abbd..0d94138 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -96,6 +96,8 @@ #define REL_PATH_TO_ROOT "../../" +static const char *hex = "0123456789ABCDEF"; + //------------------------------------------------------------------------ // TextGeneratorOLImpl implementation //------------------------------------------------------------------------ @@ -4087,7 +4089,6 @@ QCString stripScope(const char *name) /*! Converts a string to a HTML id string */ QCString convertToId(const char *s) { - static const char hex[] = "0123456789ABCDEF"; if (s==0) return ""; GrowBuf growBuf; const char *p=s; @@ -4222,13 +4223,18 @@ QCString convertToDocBook(const char *s) break; case '\'': growBuf.addStr("'"); break; case '"': growBuf.addStr("""); break; - case '\007': growBuf.addStr("␇"); break; - case 1: case 2: case 3: case 4: case 5: case 6: case 8: - case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: + case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: + case 11: case 12: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: - break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char) - default: growBuf.addChar(c); break; + growBuf.addStr("$"); + growBuf.addChar(hex[static_cast(c)>>4]); + growBuf.addChar(hex[static_cast(c)&0xF]); + growBuf.addChar(';'); + break; + default: + growBuf.addChar(c); + break; } } growBuf.addChar(0); @@ -4275,7 +4281,22 @@ QCString convertToHtml(const char *s,bool keepEntities) break; case '\'': growBuf.addStr("'"); break; case '"': growBuf.addStr("""); break; - default: growBuf.addChar(c); break; + default: + { + uchar uc = static_cast(c); + if (uc<32 && !isspace(c)) + { + growBuf.addStr("$"); + growBuf.addChar(hex[uc>>4]); + growBuf.addChar(hex[uc&0xF]); + growBuf.addChar(';'); + } + else + { + growBuf.addChar(c); + } + } + break; } } growBuf.addChar(0); @@ -5068,7 +5089,8 @@ void filterLatexString(FTextStream &t,const char *str, case ' ': if (keepSpaces) t << "~"; else t << ' '; break; default: - t << (char)c; + if (c<32) t << ' '; // non printable control character + else t << (char)c; break; } } @@ -5162,7 +5184,14 @@ void filterLatexString(FTextStream &t,const char *str, { t << "\\+"; } - t << (char)c; + if (c<32) + { + t << ' '; // non-printable control character + } + else + { + t << (char)c; + } } } pc = c; -- cgit v0.12