case '\t':
case ' ': parser.push(TToken(TToken::SPACE, ch)); break;
case '~': parser.push(TToken(TToken::ACTIVE, ch)); break;
- case '%': parser.push(TToken(TToken::COMMENT)); break;
+ case '%': parser.push(TToken(TToken::COMMENT)); break;
default:
if (isalpha(ch)) parser.push(TToken(TToken::LETTER, ch));
else if (isdigit(ch)) parser.push(TToken(TToken::DIGIT, ch));
case ACCEPT:
if (ch == '\\') state = ESCAPE;
else if (ch == '#') state = PARAMETER;
+ else if (ch == '\b') parser.push(TToken(TToken::GDELETE));
else transaction(ch, ACCEPT);
break;
case ESCAPE:
buffer.push_back(ch);
state = MACRO;
}
+ else if (ch == '\b')
+ {
+ state = ACCEPT;
+ }
else
{
parser.push(TToken(TToken::CONTROL, ch));
buffer.erase();
state = PARAMETER;
}
+ else if (ch == '\b')
+ {
+ buffer.erase(buffer.length() - 1, 1);
+ if (buffer.length() == 0) state = ESCAPE;
+ }
else if (isalpha(ch))
buffer.push_back(ch);
else
if (ch == '\\') state = ESCAPE;
else if (ch == '#') state = PARAMETER;
else if (isspace(ch)) ;
+ else if (ch == '\b') parser.push(TToken(TToken::GDELETE));
else transaction(ch, ACCEPT);
break;
case PARAMETER:
}
}
+void
+TPushParser::gdelete_prev()
+{
+ // if in this function, the prev of cursor does exist, also the parent and we want a graphical deleting
+ TNode prev = cursor.prev();
+ if (prev.is("i") || prev.is("o") || prev.is("n"))
+ {
+ // the control below is designed to handle the case in which val have more than one unicode character
+ DOM::UCS4String ucs4val(prev.element().getAttribute("val"));
+ if (ucs4val.length() <= 1)
+ {
+ cursor.remove();
+ prev.replace(cursor);
+ }
+ else
+ {
+ ucs4val.erase(ucs4val.length() - 1, 1);
+ prev.element().setAttribute(DOM::GdomeString("val"), DOM::GdomeString(ucs4val));
+ }
+ } // end of if (prev.is("i") || ...)
+ else if (prev.is("sp") || prev.is("sb"))
+ {
+ cursor.remove();
+ prev.append(cursor);
+ do_gdelete();
+ } // end of if (prev.is("sp") || prev.is("sb"))
+ else if (prev.isG())
+ {
+ cursor.remove();
+ prev.append(cursor);
+ do_gdelete();
+ }
+ else if (prev.isC())
+ {
+// cursor.remove();
+// prev.append(cursor);
+// do_gdelete();
+ }
+ else
+ {
+ // not handled
+ }
+
+} // end of method
+
+void
+TPushParser::do_gdelete()
+{
+ // this function operates a graphical deleting
+
+ TNode parent = cursor.parent();
+
+ // if no parent, do nothing
+ if (parent)
+ {
+ assert(parent);
+ if (parent.isG())
+ {
+ TNode prev = cursor.prev();
+ if (prev)
+ {
+ // i try to delete the preceding element
+ gdelete_prev();
+
+ // if gdelete_prev has removed all parent's child, and the group has Id, it should be removed.
+ // this control should be re-done on the new parent and so on.
+ while ((parent.first() == cursor) && parent.isG() && parent.hasId())
+ {
+ cursor.remove();
+ parent.replace(cursor);
+ parent = cursor.parent();
+ }
+ }
+ else // no previous node is present
+ {
+ if (!parent.parent().is("math"))
+ {
+ cursor.remove();
+ parent.replace(cursor);
+
+ // if the new parent is a group with Id, it should be removed
+ if (cursor.parent().isG() && cursor.parent().hasId()) do_gdelete();
+ }
+ else
+ {
+ // nothing to do...i think
+ }
+ }
+ }
+ else if (parent.isC())
+ {
+ // i think i have to implement different behaviors based on the attribute name and/or left-open
+ }
+ else if (parent.is("sp") || parent.is("sb"))
+ {
+ // being here means that a prev MUST exist
+
+ TNode prev = cursor.prev();
+
+ if (!prev) cout << "qualcosa non va" << endl;
+ else
+ {
+ if (parent.first().next() == cursor) // there's only an element preceding the cursor
+ {
+ cursor.remove();
+ parent.replace(prev);
+ prev.parent().append(cursor);
+ }
+ else // there are two elements preceding the cursor
+ {
+ gdelete_prev();
+ }
+ }
+ }
+ else
+ {
+ // not handled: no control for tables, ...
+ }
+ }
+ else
+ {
+ // do nothing ??
+ }
+
+} // end of method
+
void
TPushParser::process(const TToken& token)
{
case TToken::ACTIVE: do_active(token.value); break;
case TToken::COMMENT: do_comment(); break;
case TToken::CONTROL: do_control(token.value); break;
+ case TToken::GDELETE: do_gdelete(); break;
}
}