showPositionButton: Buttons.Button ← Buttons.Create[info: [name: "CapsArrows"], proc: Button, documentation: "Under test"];
Button: Buttons.ButtonProc = {
rope: Rope.ROPE ← ViewerTools.GetSelectionContents[];
viewer: ViewerClasses.Viewer;
start, end: TiogaOps.Location;
level: TiogaOps.SelectionGrain;
[viewer:viewer, start:start, end:end, level:level] ← TiogaOps.GetSelection[];
IF mouseButton=red
THEN {
rope←MesaToPascal[rope];
}
ELSE IF mouseButton=blue
THEN {
rope←PascalToMesa[rope];
}
ELSE MessageWindow.Append["Left: Mesa ids to Pascal ids; Right: vice versa", TRUE];
viewer.class.notify[viewer, LIST[$Delete, rope]];
[end:end] ← TiogaOps.GetSelection[];
end.where ← end.where - 1; -- God only knows why this is necessary
TiogaOps.SetSelection[viewer:viewer, start:start, end:end, level:level, caretBefore: FALSE];
};
MesaToPascal:
PROCEDURE [rope: Rope.
ROPE]
RETURNS [new: Rope.
ROPE] = {
firstInToken: BOOLEAN ← TRUE;
startPos: INT ← 0; -- used to avoid Rope.Cats of single chars.
new ← "";
FOR i:
INT
IN [0..rope.Length[])
DO
char: CHAR ← rope.Fetch[i];
SELECT
TRUE
FROM
char
IN ['A..'Z]
AND firstInToken => {
new ← Rope.Cat[new, rope.Substr[start~startPos, len~i-startPos], Rope.FromChar[Ascii.Lower[char]]];
firstInToken ← FALSE;
startPos ← i+1;
};
char
IN ['A..'Z]
AND
NOT firstInToken => {
new ← Rope.Cat[new, rope.Substr[start~startPos, len~i-startPos], "←", Rope.FromChar[Ascii.Lower[char]]];
startPos ← i+1;
};
Ascii.Letter[char], Ascii.Digit[char], char = '$ => {
firstInToken ← FALSE;
};
ENDCASE => {
firstInToken ← TRUE;
};
ENDLOOP;
IF startPos < rope.Length[]
THEN
new ← Rope.Cat[new, rope.Substr[start~startPos, len~rope.Length[]-startPos]];
};