texstream: implement way to terminate a command depending on the context

i.e.,
* space if non terminating char follows
* {} if space follows
* nothing if \, { or } follow
This commit is contained in:
Juergen Spitzmueller 2016-12-12 15:55:28 +01:00
parent e8b1ec66fc
commit 66f7c2930a
2 changed files with 68 additions and 4 deletions

View File

@ -59,11 +59,23 @@ void otexrowstream::put(char_type const & c)
void otexstream::put(char_type const & c)
{
bool isprotected = false;
if (protectspace_) {
if (!canbreakline_ && c == ' ')
if (!canbreakline_ && c == ' ') {
os() << "{}";
isprotected = true;
}
protectspace_ = false;
}
if (terminate_command_) {
if ((c == ' ' || c == '\0') && !isprotected)
// A space follows. Terminate with brackets.
os() << "{}";
else if (c != '\\' && c != '{' && c != '}')
// Non-terminating character follows. Terminate with space.
os() << " ";
terminate_command_ = false;
}
otexrowstream::put(c);
lastChar(c);
}
@ -89,6 +101,7 @@ TexString otexstringstream::release()
BreakLine breakln;
SafeBreakLine safebreakln;
TerminateCommand termcmd;
otexstream & operator<<(otexstream & ots, BreakLine)
@ -98,6 +111,7 @@ otexstream & operator<<(otexstream & ots, BreakLine)
ots.lastChar('\n');
}
ots.protectSpace(false);
ots.terminateCommand(false);
return ots;
}
@ -110,6 +124,14 @@ otexstream & operator<<(otexstream & ots, SafeBreakLine)
ots.lastChar('\n');
}
ots.protectSpace(false);
ots.terminateCommand(false);
return ots;
}
otexstream & operator<<(otexstream & ots, TerminateCommand)
{
ots.terminateCommand(true);
return ots;
}
@ -152,11 +174,24 @@ otexstream & operator<<(otexstream & ots, TexString ts)
return ots;
otexrowstream & otrs = ots;
bool isprotected = false;
char const c = ts.str[0];
if (ots.protectSpace()) {
if (!ots.canBreakLine() && ts.str[0] == ' ')
if (!ots.canBreakLine() && c == ' ') {
otrs << "{}";
isprotected = true;
}
ots.protectSpace(false);
}
if (ots.terminateCommand()) {
if ((c == ' ' || c == '\0') && !isprotected)
// A space follows. Terminate with brackets.
otrs << "{}";
else if (c != '\\' && c != '{' && c != '}')
// Non-terminating character follows. Terminate with space.
otrs << " ";
ots.terminateCommand(false);
}
if (len > 1)
ots.canBreakLine(ts.str[len - 2] != '\n');
@ -183,11 +218,24 @@ otexstream & operator<<(otexstream & ots, docstring const & s)
if (len == 0)
return ots;
otexrowstream & otrs = ots;
bool isprotected = false;
char const c = s[0];
if (ots.protectSpace()) {
if (!ots.canBreakLine() && s[0] == ' ')
if (!ots.canBreakLine() && c == ' ') {
otrs << "{}";
isprotected = true;
}
ots.protectSpace(false);
}
if (ots.terminateCommand()) {
if ((c == ' ' || c == '\0') && !isprotected)
// A space follows. Terminate with brackets.
otrs << "{}";
else if (c != '\\' && c != '{' && c != '}')
// Non-terminating character follows. Terminate with space.
otrs << " ";
ots.terminateCommand(false);
}
if (contains(s, 0xF0000)) {
// Some encoding changes for the underlying stream are embedded
@ -290,6 +338,7 @@ otexstream & operator<<(otexstream & ots, Type value)
ots.os() << value;
ots.lastChar(0);
ots.protectSpace(false);
ots.terminateCommand(false);
return ots;
}

View File

@ -81,7 +81,8 @@ public:
///
explicit otexstream(odocstream & os)
: otexrowstream(os), canbreakline_(false),
protectspace_(false), parbreak_(true), lastchar_(0) {}
protectspace_(false), terminate_command_(false),
parbreak_(true), lastchar_(0) {}
///
void put(char_type const & c);
///
@ -95,6 +96,10 @@ public:
///
bool protectSpace() const { return protectspace_; }
///
void terminateCommand(bool terminate) { terminate_command_ = terminate; }
///
bool terminateCommand() const { return terminate_command_; }
///
void lastChar(char_type const & c)
{
parbreak_ = (!canbreakline_ && c == '\n');
@ -111,6 +116,8 @@ private:
///
bool protectspace_;
///
bool terminate_command_;
///
bool parbreak_;
///
char_type lastchar_;
@ -144,14 +151,22 @@ struct SafeBreakLine {
char n;
};
/// Helper structs for terminating a command
struct TerminateCommand {
char n;
};
extern BreakLine breakln;
extern SafeBreakLine safebreakln;
extern TerminateCommand termcmd;
///
otexstream & operator<<(otexstream &, BreakLine);
///
otexstream & operator<<(otexstream &, SafeBreakLine);
///
otexstream & operator<<(otexstream &, TerminateCommand);
///
otexstream & operator<<(otexstream &, odocstream_manip);
///
otexstream & operator<<(otexstream &, TexString);