StyleToolToJaMImpl.mesa
Written by Linda Gass on August 9, 1982 1:22 pm
Last Edit by Linda Gass on November 4, 1982 2:29 pm
Last Edited by: Plass, March 28, 1983 3:04 pm
DIRECTORY
ChoiceButtons USING [EnumTypeRef, GetSelectedButton],
IO USING [EndOfStream, GetToken, CreateInputStreamFromRope, PutFToRope, real],
MessageWindow USING [Append, Blink],
NodeStyle USING [FontFace, GetBindingMargin, GetBottomIndent, GetBottomLeading,
GetBottomLeadingShrink, GetBottomLeadingStretch, GetBottomMargin, GetFirstIndent, GetFontSize, GetLeading, GetLeadingStretch, GetLeadingShrink, GetLeftIndent, GetLeftMargin, GetMinLineGap, GetPageBreakPenalty, GetPageBreakAfterFirstLinePenalty, GetPageBreakBeforeLastLinePenalty, GetPageBreakBeforeFirstLinePenalty, GetPageBreakAfterLastLinePenalty, GetPageLength, GetPageWidth, GetRestIndent, GetRightIndent, GetRightMargin, GetTabStops, GetTopIndent, GetTopLeading, GetTopLeadingStretch, GetTopLeadingShrink, GetTopMargin, GetVShift, Ref],
Real USING [FixC],
Rope USING [ROPE, Cat, Equal, Size],
StyleToolDefs,
StyleToolConvert USING [BadNumber, ConvertUnits, FontAlphChoiceToJaM, GetFontFamily,
GetFontFaceJaM, GetFontAlphabetsChoice, GetFontUnderliningChoice, FontUndChoiceToJaM,
GetLineFormattingChoice, LineChoiceToJaM, GetRealFromViewer],
StyleToolToJaM,
VFonts USING [Error, EstablishFont],
ViewerClasses USING [Viewer],
ViewerTools USING [GetContents, SetContents, SetSelection];
StyleToolToJaMImpl: CEDAR PROGRAM
IMPORTS ChoiceButtons, IO, MessageWindow, NodeStyle, Real, Rope, StyleToolConvert, StyleToolDefs, VFonts, ViewerTools
EXPORTS StyleToolToJaM =
BEGIN OPEN StyleToolDefs, StyleToolToJaM;
NoName: SIGNAL = CODE;
GetNameFromViewer: PRIVATE PROCEDURE [viewer: ViewerClasses.Viewer] RETURNS [nameRope: Rope.ROPE] = {
nameRope ← ViewerTools.GetContents[viewer];
IF Rope.Size[nameRope] = 0 THEN SIGNAL NoName
ELSE {
 nameRope ← GetEssentialsOfName[nameRope];
IF Rope.Size[nameRope] = 0 THEN SIGNAL NoName;
 };
};
GetEssentialsOfName: PRIVATE PROC [name: Rope.ROPE] RETURNS [realName: Rope.ROPE] = {
strips off leading SP, CR, ESC, LF, TAB, COMMA, SEMICOLON if they exist and returns the alpha-numeric name.
realName ← IO.GetToken[IO.CreateInputStreamFromRope[name] ! IO.EndOfStream => CONTINUE];
the name might not have any trailing SP, CR, ESC, LF, TAB, COMMA, SEMICOLON causing an EndOfStream error to be raised. We can safely igonore this.
};
WriteDisplayInfo: PUBLIC PROCEDURE [handle: StyleToolHandle, info: NodeStyle.Ref, format: BOOLEAN] = BEGIN
write out everything that doesn't correspond to the default
displayRope: Rope.ROPE ← "";
nameRope: Rope.ROPE ← GetNameFromViewer[handle.styleNameData.textViewer ! NoName =>
GOTO CouldntWriteStyleName];
formatNameRope, looksRope, ruleRope: Rope.ROPE;
found: BOOLEAN;
first clear out the WriteOutViewer, in case it contains any information (we don't want the user to get confused; any old information should be discarded.
ViewerTools.SetContents[handle.swap.jamCodeInfo.text, NIL];

ruleRope ← ChoiceButtons.GetSelectedButton[handle.ruleType];
IF ~ handle.changesMode THEN {
-- dont bother writing out this information if the user is just interested in changes
IF format THEN {
  formatNameRope ← GetNameFromViewer[handle.formatNameData.textViewer ! NoName =>
   GOTO CouldntWriteFormat];
  displayRope ← Rope.Cat[displayRope, "(", formatNameRope, ") {\n"];
  }
ELSE {
  looksRope ← GetNameFromViewer[handle.looksData.textViewer ! NoName =>
   GOTO CouldntWriteLook];
  displayRope ← Rope.Cat[displayRope, "(look.", looksRope, ") {\n"];
  };
 };
[displayRope, found] ← AppendFontInfoRope[handle, info, displayRope];
IF found THEN {
displayRope ← AppendIndentInfoRope[handle, info, displayRope];
displayRope ← AppendLeadingInfoRope[handle, info, displayRope];
displayRope ← AppendMiscInfoRope[handle, info, displayRope];
IF ~Rope.Equal[ruleRope, "ScreenRule", FALSE] THEN {
 displayRope ← AppendPenaltyInfoRope[handle, info, displayRope];
 displayRope ← AppendPageInfoRope[handle, info, displayRope];
 };
displayRope ← AppendArtworkInfoRope[handle, info, displayRope];
IF ~ handle.changesMode THEN displayRope ← Rope.Cat[displayRope, "} ", ruleRope, "\n"];
ViewerTools.SetContents[handle.swap.jamCodeInfo.text, displayRope];
};
EXITS CouldntWriteStyleName => {OPEN MessageWindow;
   Append["Couldn't write style. No valid style name given.", TRUE];
   Blink[];
   -- force selection into Style Name viewer
   ViewerTools.SetSelection[handle.styleNameData.textViewer];
   };
  CouldntWriteFormat => {OPEN MessageWindow;
   Append["Couldn't write style. No valid Format name given.", TRUE];
   Blink[];
   ViewerTools.SetSelection[handle.formatNameData.textViewer];
   };
  CouldntWriteLook => {OPEN MessageWindow;
   Append["Couldn't write style. No valid Look name given.", TRUE];
   Blink[];
   ViewerTools.SetSelection[handle.looksData.textViewer];
   };
END;
RopeDifferences: PRIVATE PROC[handle: StyleToolHandle, selection, default, nodeInfo: Rope.ROPE] RETURNS [BOOLEAN] = {
IF handle.changesMode THEN {
IF ~Rope.Equal[selection, default, FALSE] AND ~Rope.Equal[selection, nodeInfo, FALSE] THEN
  RETURN [TRUE]
ELSE RETURN [FALSE];
 }
ELSE {
IF ~Rope.Equal[selection, default, FALSE] THEN RETURN [TRUE]
ELSE RETURN [FALSE];
 };
};
RealDifferences: PRIVATE PROC[handle: StyleToolHandle, selection, default, nodeInfo: REAL] RETURNS [BOOLEAN] = {
IF handle.changesMode THEN {
IF (selection # default) AND (selection # nodeInfo) THEN RETURN [TRUE]
ELSE RETURN [FALSE];
 }
ELSE {
IF (selection # default) THEN RETURN [TRUE]
ELSE RETURN [FALSE];
 };
};
IntDifferences: PRIVATE PROC[handle: StyleToolHandle, selection, default, nodeInfo: INTEGER] RETURNS [BOOLEAN] = {
IF handle.changesMode THEN {
IF (selection # default) AND (selection # nodeInfo) THEN RETURN [TRUE]
ELSE RETURN [FALSE];
 }
ELSE {
IF (selection # default) THEN RETURN [TRUE]
ELSE RETURN [FALSE];
 };
};
AppendUnits: PRIVATE PROCEDURE [displayRope, units: Rope.ROPE] RETURNS [Rope.ROPE] = {
NOTE: the ropes in the left column "points", "picas", etc correspond to the ropes in the UnitsList in StyleToolBuilers.
SELECT TRUE FROM
Rope.Equal[units, "points", FALSE]  => displayRope ← Rope.Cat[displayRope, " pt"];
Rope.Equal[units, "picas", FALSE]   => displayRope ← Rope.Cat[displayRope, " pc"];
Rope.Equal[units, "inches", FALSE]  => displayRope ← Rope.Cat[displayRope, " in"];
Rope.Equal[units, "centimeters", FALSE] => displayRope ← Rope.Cat[displayRope, " cm"];
Rope.Equal[units, "millimeters", FALSE] => displayRope ← Rope.Cat[displayRope, " mm"];
Rope.Equal[units, "didot points", FALSE] => displayRope ← Rope.Cat[displayRope, " dd"];
Rope.Equal[units, "ems", FALSE]   => displayRope ← Rope.Cat[displayRope, " em"];
Rope.Equal[units, "ens", FALSE]   => displayRope ← Rope.Cat[displayRope, " en"];
Rope.Equal[units, "spaces", FALSE]  => displayRope ← Rope.Cat[displayRope, " sp"];
ENDCASE;
RETURN[displayRope];
};
AppendValueAndUnits: PRIVATE PROCEDURE [handle: StyleToolHandle, displayRope: Rope.ROPE, selection, default, nodeInfo: REAL, addOn: Rope.ROPE, units: ChoiceButtons.EnumTypeRef] RETURNS [Rope.ROPE] = {
IF RealDifferences[handle, selection, default, nodeInfo] THEN {
 displayRope ← Rope.Cat[displayRope, IO.PutFToRope[realNumberFormat, IO.real[selection]]];
 displayRope ← AppendUnits[displayRope, units.flipLabel.name];
 displayRope ← Rope.Cat[displayRope, " ", addOn, "\n"];
 }
ELSE {
 selectionOnRope: Rope.ROPE ← ChoiceButtons.GetSelectedButton[units];
IF ~Rope.Equal[selectionOnRope, "points", FALSE] THEN {
  displayRope ← Rope.Cat[displayRope," ", IO.PutFToRope[realNumberFormat,
   IO.real[selection]]];
  displayRope ← AppendUnits[displayRope,units.flipLabel.name];
  displayRope ← Rope.Cat[displayRope, " ", addOn, "\n"];
  };
 };
RETURN [displayRope];
};
GetReal: PRIVATE PROCEDURE [valueAndUnits: ValueAndUnitsRef] RETURNS [num: REAL] = BEGIN
num ← 0; -- default to zero in case there's a bad number in the viewer. We want to return
   -- something reasonable rather than giving an error.
IF valueAndUnits.valueData.textViewer.newVersion THEN
 num ← StyleToolConvert.GetRealFromViewer[valueAndUnits.valueData.textViewer
  ! StyleToolConvert.BadNumber => CONTINUE]
ELSE {
 num ← valueAndUnits.originalValue;
 num ← StyleToolConvert.ConvertUnits[num, valueAndUnits.originalUnits,
  valueAndUnits.units.flipLabel.name];
-- make sure we return the number converted to the current units
 };
END;
AppendFontInfoRope: PUBLIC PROCEDURE [handle: StyleToolHandle, default: NodeStyle.Ref, displayRope: Rope.ROPE] RETURNS [returnRope: Rope.ROPE, found: BOOLEAN] = BEGIN
selectionOnRope, nodeInfoRope, defaultRope: Rope.ROPE;
selectionReal, nodeInfoReal, defaultReal: REAL;
bold, italic: BOOLEAN;
fontFamily: Rope.ROPENIL;
fontSize: CARDINAL;
found ← TRUE;

selectionOnRope ← ChoiceButtons.GetSelectedButton[handle.display.fontFamilyChoice];
IF ~Rope.Equal[selectionOnRope, "none", FALSE] THEN {
-- if no font family was selected then dont bother to append anything
IF Rope.Equal[selectionOnRope, "other", FALSE] THEN {
  selectionOnRope ← GetNameFromViewer[handle.display.fontFamilyOtherViewer];
  defaultRope ← StyleToolConvert.GetFontFamily[default.name[fontFamily]].text;
  nodeInfoRope ← StyleToolConvert.GetFontFamily[handle.nodeInfo.name[fontFamily]].text;
  }
ELSE {
  defaultRope ← StyleToolConvert.GetFontFamily[default.name[fontFamily]].name;
  nodeInfoRope ← StyleToolConvert.GetFontFamily[handle.nodeInfo.name[fontFamily]].name;
  };
 fontFamily ← selectionOnRope;
IF RopeDifferences[handle, selectionOnRope, defaultRope, nodeInfoRope] THEN
  displayRope ← Rope.Cat[displayRope, """", selectionOnRope, """", " family\n"];
 };
selectionOnRope ← ChoiceButtons.GetSelectedButton[handle.display.fontFaceChoice];
defaultRope ← StyleToolConvert.GetFontFace[default.fontFace];
nodeInfoRope ← StyleToolConvert.GetFontFace[handle.nodeInfo.fontFace];
IF RopeDifferences[handle, selectionOnRope, defaultRope, nodeInfoRope] THEN
displayRope ← Rope.Cat[displayRope, selectionOnRope, " face\n"];
[displayRope, bold, italic] ← AppendFontFace[handle, default, displayRope];

selectionReal← GetReal[handle.display.fontSizeInfo];
defaultReal ← NodeStyle.GetFontSize[default];
nodeInfoReal ← NodeStyle.GetFontSize[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "size", handle.display.fontSizeInfo.units];
fontSize ← Real.FixC[selectionReal];

Check that the font given exists and put a message up if it doesn't
IF fontFamily # NIL THEN {
 [] ← VFonts.EstablishFont[fontFamily, fontSize, bold, italic, FALSE ! VFonts.Error =>
  SELECT code FROM
   illegalFormat => CONTINUE;
   fontNotFound => { -- Try again with bold and italic turned off because those will
         -- be synthesized
         [] ← VFonts.EstablishFont[fontFamily, fontSize, FALSE, FALSE,
          FALSE ! VFonts.Error => { OPEN MessageWindow;
          Append["Font specified cannot be found", TRUE];
          Blink[];
          found ← FALSE;
          CONTINUE;
          }];
         CONTINUE;
         };
   ENDCASE => ERROR;]
 };

selectionOnRope ← ChoiceButtons.GetSelectedButton[handle.display.fontAlphabetsChoice];
defaultRope ← StyleToolConvert.GetFontAlphabetsChoice[default.fontAlphabets];
nodeInfoRope ← StyleToolConvert.GetFontAlphabetsChoice[handle.nodeInfo.fontAlphabets];
IF RopeDifferences[handle, selectionOnRope, defaultRope, nodeInfoRope] THEN
 displayRope ← Rope.Cat[displayRope,
  StyleToolConvert.FontAlphChoiceToJaM[selectionOnRope], " alphabets\n"];

selectionOnRope ← ChoiceButtons.GetSelectedButton[handle.display.fontUnderliningChoice];
defaultRope ← StyleToolConvert.GetFontUnderliningChoice[default.underlining];
nodeInfoRope ← StyleToolConvert.GetFontUnderliningChoice[handle.nodeInfo.underlining];
IF RopeDifferences[handle, selectionOnRope, defaultRope, nodeInfoRope] THEN
 displayRope ← Rope.Cat[displayRope,StyleToolConvert.FontUndChoiceToJaM[selectionOnRope],
  " underlining\n"];
  
returnRope ← displayRope;
END;
AppendFontFace: PROCEDURE [handle: StyleToolHandle, default: NodeStyle.Ref,
 displayRope: Rope.ROPE] RETURNS [returnRope: Rope.ROPE, bold, italic: BOOLEAN] = BEGIN
face: NodeStyle.FontFace;
bold ← italic ← FALSE;
IF (handle.display.boldFontFace.state=default AND handle.display.italicFontFace.state=default)
OR (handle.display.boldFontFace.state=default AND handle.display.italicFontFace.state=off)
OR (handle.display.boldFontFace.state=off AND handle.display.italicFontFace.state=default)
THEN RETURN[displayRope, bold, italic] -- dont do anything if default and off
ELSE IF handle.display.boldFontFace.state = off AND handle.display.italicFontFace.state = off
THEN face ← Regular
ELSE IF handle.display.boldFontFace.state = on AND handle.display.italicFontFace.state # on
THEN {face ← Bold; bold ← TRUE}
ELSE IF handle.display.boldFontFace.state # on AND handle.display.italicFontFace.state = on
THEN {face ← Italic; italic ← TRUE}
ELSE IF handle.display.boldFontFace.state = on AND handle.display.italicFontFace.state = on
THEN {face ← BoldItalic; bold ← TRUE; italic ← TRUE};
IF default.fontFace # face AND handle.nodeInfo.fontFace # face THEN
 displayRope ← Rope.Cat[displayRope, StyleToolConvert.GetFontFaceJaM[face], " face\n"];
returnRope ← displayRope;
END;
AppendIndentInfoRope: PUBLIC PROCEDURE [handle: StyleToolHandle, default: NodeStyle.Ref, displayRope: Rope.ROPE] RETURNS [Rope.ROPE] = BEGIN
selectionReal, nodeInfoReal, defaultReal: REAL;

selectionReal ← GetReal[handle.display.leftIndentInfo];
defaultReal ← NodeStyle.GetLeftIndent[default];
nodeInfoReal ← NodeStyle.GetLeftIndent[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "leftIndent", handle.display.leftIndentInfo.units];

selectionReal ← GetReal[handle.display.rightIndentInfo];
defaultReal ← NodeStyle.GetRightIndent[default];
nodeInfoReal ← NodeStyle.GetRightIndent[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "rightIndent", handle.display.rightIndentInfo.units];   

selectionReal ← GetReal[handle.display.firstIndentInfo];
defaultReal ← NodeStyle.GetFirstIndent[default];
nodeInfoReal ← NodeStyle.GetFirstIndent[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "firstIndent", handle.display.firstIndentInfo.units];   

selectionReal ← GetReal[handle.display.restIndentInfo];
defaultReal ← NodeStyle.GetRestIndent[default];
nodeInfoReal ← NodeStyle.GetRestIndent[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "restIndent", handle.display.restIndentInfo.units];   

selectionReal ← GetReal[handle.display.topIndentInfo];
defaultReal ← NodeStyle.GetTopIndent[default];
nodeInfoReal ← NodeStyle.GetTopIndent[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "topIndent", handle.display.topIndentInfo.units]; 

selectionReal ← GetReal[handle.display.bottomIndentInfo];
defaultReal ← NodeStyle.GetBottomIndent[default];
nodeInfoReal ← NodeStyle.GetBottomIndent[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "bottomIndent", handle.display.bottomIndentInfo.units];   
  
RETURN[displayRope];
END;
AppendLeadingInfoRope: PUBLIC PROCEDURE [handle: StyleToolHandle, default: NodeStyle.Ref, displayRope: Rope.ROPE] RETURNS [Rope.ROPE] = BEGIN
leadingReal, stretchReal, shrinkReal, nodeInfoReal, defaultReal: REAL;
AppendGlue: PROCEDURE [displayRope: Rope.ROPE, units: ChoiceButtons.EnumTypeRef, addOn: Rope.ROPE] RETURNS [Rope.ROPE] = {
measure: Rope.ROPE ← ChoiceButtons.GetSelectedButton[units];
leadingReal ← StyleToolConvert.ConvertUnits[leadingReal, measure, "points"];
stretchReal ← StyleToolConvert.ConvertUnits[stretchReal, measure, "points"];
shrinkReal ← StyleToolConvert.ConvertUnits[shrinkReal, measure, "points"];
displayRope ← Rope.Cat[displayRope, IO.PutFToRope[realNumberFormat, IO.real[leadingReal]],
 " ", IO.PutFToRope[realNumberFormat, IO.real[stretchReal]], " ",
IO.PutFToRope[realNumberFormat, IO.real[shrinkReal]]];
displayRope ← Rope.Cat[displayRope, " ", addOn, "\n"];
RETURN[displayRope];
};
GetStretchShrink: PROC [leadingInfo: LeadingRef] RETURNS [stretch, shrink: REAL] = {
stretch ← shrink ← 0;
IF leadingInfo.stretch.textViewer.newVersion THEN
 stretch ← StyleToolConvert.GetRealFromViewer[leadingInfo.stretch.textViewer
  ! StyleToolConvert.BadNumber => CONTINUE]
ELSE stretch ← leadingInfo.originalStretch;
IF leadingInfo.shrink.textViewer.newVersion THEN
 shrink ← StyleToolConvert.GetRealFromViewer[leadingInfo.shrink.textViewer
  ! StyleToolConvert.BadNumber => CONTINUE]
ELSE shrink ← leadingInfo.originalShrink;
};
leadingReal ← GetReal[handle.display.leadingInfo.leading];
[stretchReal, shrinkReal] ← GetStretchShrink[handle.display.leadingInfo];
defaultReal ← NodeStyle.GetLeadingStretch[default];
nodeInfoReal ← NodeStyle.GetLeadingStretch[handle.nodeInfo];
IF RealDifferences[handle, stretchReal, defaultReal, nodeInfoReal] THEN
 displayRope ← AppendGlue[displayRope, handle.display.leadingInfo.leading.units,
  "leadingGlue"]
ELSE {
 defaultReal ← NodeStyle.GetLeadingShrink[default];
 nodeInfoReal ← NodeStyle.GetLeadingShrink[handle.nodeInfo];
IF RealDifferences[handle, shrinkReal, defaultReal, nodeInfoReal] THEN
  displayRope ← AppendGlue[displayRope, handle.display.leadingInfo.leading.units,
   "leadingGlue"]
ELSE {
  defaultReal ← NodeStyle.GetLeading[default];
  nodeInfoReal ← NodeStyle.GetLeading[handle.nodeInfo];
  displayRope ← AppendValueAndUnits[handle, displayRope, leadingReal, defaultReal,
   nodeInfoReal, "leading", handle.display.leadingInfo.leading.units];
  };
 };

leadingReal ← GetReal[handle.display.topLeadingInfo.leading];
[stretchReal, shrinkReal] ← GetStretchShrink[handle.display.topLeadingInfo];
defaultReal ← NodeStyle.GetTopLeadingStretch[default];
nodeInfoReal ← NodeStyle.GetTopLeadingStretch[handle.nodeInfo];
IF RealDifferences[handle, stretchReal, defaultReal, nodeInfoReal] THEN
 displayRope ← AppendGlue[displayRope, handle.display.topLeadingInfo.leading.units,
  "topLeadingGlue"]
ELSE {
 defaultReal ← NodeStyle.GetTopLeadingShrink[default];
 nodeInfoReal ← NodeStyle.GetTopLeadingShrink[handle.nodeInfo];
IF RealDifferences[handle, shrinkReal, defaultReal, nodeInfoReal] THEN
  displayRope ← AppendGlue[displayRope, handle.display.topLeadingInfo.leading.units,
   "topLeadingGlue"]
ELSE {
  defaultReal ← NodeStyle.GetTopLeading[default];
  nodeInfoReal ← NodeStyle.GetTopLeading[handle.nodeInfo];
  displayRope ← AppendValueAndUnits[handle, displayRope, leadingReal, defaultReal,
   nodeInfoReal, "topLeading", handle.display.topLeadingInfo.leading.units];
  };
 };

leadingReal ← GetReal[handle.display.bottomLeadingInfo.leading];
[stretchReal, shrinkReal] ← GetStretchShrink[handle.display.bottomLeadingInfo];
defaultReal ← NodeStyle.GetBottomLeadingStretch[default];
nodeInfoReal ← NodeStyle.GetBottomLeadingStretch[handle.nodeInfo];
IF RealDifferences[handle, stretchReal, defaultReal, nodeInfoReal] THEN
 displayRope ← AppendGlue[displayRope, handle.display.bottomLeadingInfo.leading.units,
  "bottomLeadingGlue"]
ELSE {
 defaultReal ← NodeStyle.GetBottomLeadingShrink[default];
 nodeInfoReal ← NodeStyle.GetBottomLeadingShrink[handle.nodeInfo];
IF RealDifferences[handle, shrinkReal, defaultReal, nodeInfoReal] THEN
  displayRope ← AppendGlue[displayRope, handle.display.bottomLeadingInfo.leading.units,
   "bottomLeadingGlue"]
ELSE {
  defaultReal ← NodeStyle.GetBottomLeading[default];
  nodeInfoReal ← NodeStyle.GetBottomLeading[handle.nodeInfo];
  displayRope ← AppendValueAndUnits[handle, displayRope, leadingReal, defaultReal,
   nodeInfoReal, "bottomLeading", handle.display.bottomLeadingInfo.leading.units];
  };
 };  
  
RETURN[displayRope];
END;
AppendMiscInfoRope: PUBLIC PROCEDURE [handle: StyleToolHandle, default: NodeStyle.Ref, displayRope: Rope.ROPE] RETURNS [Rope.ROPE] = BEGIN
selectionOnRope, nodeInfoRope, defaultRope: Rope.ROPE;
selectionReal, defaultReal, nodeInfoReal: REAL;

selectionReal ← GetReal[handle.display.vshiftInfo];
defaultReal ← NodeStyle.GetVShift[default];
nodeInfoReal ← NodeStyle.GetVShift[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "vShift", handle.display.vshiftInfo.units];

selectionReal ← GetReal[handle.display.minLineGapInfo];
defaultReal ← NodeStyle.GetMinLineGap[default];
nodeInfoReal ← NodeStyle.GetMinLineGap[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "minLineGap", handle.display.minLineGapInfo.units];   

selectionReal ← StyleToolConvert.GetRealFromViewer[
 handle.display.tabStopsViewer ! StyleToolConvert.BadNumber => CONTINUE];
defaultReal ← NodeStyle.GetTabStops[default];
nodeInfoReal ← NodeStyle.GetTabStops[handle.nodeInfo];
IF RealDifferences[handle, selectionReal, defaultReal, nodeInfoReal] THEN
 displayRope ← Rope.Cat[displayRope,ViewerTools.GetContents[handle.display.tabStopsViewer],
  " sp tabStops\n"];
  
selectionOnRope ← ChoiceButtons.GetSelectedButton[handle.display.lineFormattingChoice];
defaultRope ← StyleToolConvert.GetLineFormattingChoice[default.lineFormatting];
nodeInfoRope ← StyleToolConvert.GetLineFormattingChoice[handle.nodeInfo.lineFormatting];
IF RopeDifferences[handle, selectionOnRope, defaultRope, nodeInfoRope] THEN
 displayRope ← Rope.Cat[displayRope, StyleToolConvert.LineChoiceToJaM[selectionOnRope],
  " lineFormatting\n"];
  
RETURN[displayRope];
END;
AppendPenaltyInfoRope: PUBLIC PROCEDURE [handle: StyleToolHandle, default: NodeStyle.Ref, displayRope: Rope.ROPE] RETURNS [Rope.ROPE] = BEGIN
selectionReal, defaultReal, nodeInfoReal: REAL;

selectionReal ← StyleToolConvert.GetRealFromViewer[
 handle.swap.penalty.pageBreakPenalty ! StyleToolConvert.BadNumber => CONTINUE];
defaultReal ← NodeStyle.GetPageBreakPenalty[default];
nodeInfoReal ← NodeStyle.GetPageBreakPenalty[handle.nodeInfo];
IF RealDifferences[handle, selectionReal, defaultReal, nodeInfoReal] THEN
 displayRope ← Rope.Cat[displayRope,
  ViewerTools.GetContents[handle.swap.penalty.pageBreakPenalty]," pageBreakPenalty\n"];

selectionReal ← StyleToolConvert.GetRealFromViewer[
 handle.swap.penalty.afterFirstLinePenalty ! StyleToolConvert.BadNumber => CONTINUE];
defaultReal ← NodeStyle.GetPageBreakAfterFirstLinePenalty[default];
nodeInfoReal ← NodeStyle.GetPageBreakAfterFirstLinePenalty[handle.nodeInfo];
IF RealDifferences[handle, selectionReal, defaultReal, nodeInfoReal] THEN
 displayRope ← Rope.Cat[displayRope,
  ViewerTools.GetContents[handle.swap.penalty.afterFirstLinePenalty],
  " pageBreakAfterFirstLinePenalty\n"];

selectionReal ← StyleToolConvert.GetRealFromViewer[
 handle.swap.penalty.beforeLastLinePenalty ! StyleToolConvert.BadNumber => CONTINUE];
defaultReal ← NodeStyle.GetPageBreakBeforeLastLinePenalty[default];
nodeInfoReal ← NodeStyle.GetPageBreakBeforeLastLinePenalty[handle.nodeInfo];
IF RealDifferences[handle, selectionReal, defaultReal, nodeInfoReal] THEN
 displayRope ← Rope.Cat[displayRope,
  ViewerTools.GetContents[handle.swap.penalty.beforeLastLinePenalty],
  " pageBreakBeforeLastLinePenalty\n"];

selectionReal ← StyleToolConvert.GetRealFromViewer[
 handle.swap.penalty.beforeFirstLinePenalty ! StyleToolConvert.BadNumber => CONTINUE];
defaultReal ← NodeStyle.GetPageBreakBeforeFirstLinePenalty[default];
nodeInfoReal ← NodeStyle.GetPageBreakBeforeFirstLinePenalty[handle.nodeInfo];
IF RealDifferences[handle, selectionReal, defaultReal, nodeInfoReal] THEN
 displayRope ← Rope.Cat[displayRope,
  ViewerTools.GetContents[handle.swap.penalty.beforeFirstLinePenalty],
  " pageBreakBeforeFirstLinePenalty\n"];

selectionReal ← StyleToolConvert.GetRealFromViewer[
 handle.swap.penalty.afterLastLinePenalty ! StyleToolConvert.BadNumber => CONTINUE];
defaultReal ← NodeStyle.GetPageBreakAfterLastLinePenalty[default];
nodeInfoReal ← NodeStyle.GetPageBreakAfterLastLinePenalty[handle.nodeInfo];
IF RealDifferences[handle, selectionReal, defaultReal, nodeInfoReal] THEN
 displayRope ← Rope.Cat[displayRope,
  ViewerTools.GetContents[handle.swap.penalty.afterLastLinePenalty],
  " pageBreakAfterLastLinePenalty\n"];
    
RETURN[displayRope];
END;
AppendPageInfoRope: PUBLIC PROCEDURE [handle: StyleToolHandle, default: NodeStyle.Ref, displayRope: Rope.ROPE] RETURNS [Rope.ROPE] = BEGIN
selectionReal, defaultReal, nodeInfoReal: REAL;
-- selectionInt: INTEGER;

selectionReal ← GetReal[handle.swap.layout.pageWidth];
defaultReal ← NodeStyle.GetPageWidth[default];
nodeInfoReal ← NodeStyle.GetPageWidth[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "pageWidth", handle.swap.layout.pageWidth.units];

selectionReal ← GetReal[handle.swap.layout.pageLength];
defaultReal ← NodeStyle.GetPageLength[default];
nodeInfoReal ← NodeStyle.GetPageLength[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "pageLength", handle.swap.layout.pageLength.units];

selectionReal ← GetReal[handle.swap.layout.leftMargin];
defaultReal ← NodeStyle.GetLeftMargin[default];
nodeInfoReal ← NodeStyle.GetLeftMargin[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "leftMargin", handle.swap.layout.leftMargin.units];

selectionReal ← GetReal[handle.swap.layout.rightMargin];
defaultReal ← NodeStyle.GetRightMargin[default];
nodeInfoReal ← NodeStyle.GetRightMargin[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "rightMargin", handle.swap.layout.rightMargin.units];

selectionReal ← GetReal[handle.swap.layout.topMargin];
defaultReal ← NodeStyle.GetTopMargin[default];
nodeInfoReal ← NodeStyle.GetTopMargin[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "topMargin", handle.swap.layout.topMargin.units];

selectionReal ← GetReal[handle.swap.layout.bottomMargin];
defaultReal ← NodeStyle.GetBottomMargin[default];
nodeInfoReal ← NodeStyle.GetBottomMargin[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "bottomMargin", handle.swap.layout.bottomMargin.units];
selectionReal ← GetReal[handle.swap.layout.headerMargin];
defaultReal ← NodeStyle.GetHeaderMargin[default];
nodeInfoReal ← NodeStyle.GetHeaderMargin[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "headerMargin", handle.swap.layout.headerMargin.units];

selectionReal ← GetReal[handle.swap.layout.footerMargin];
defaultReal ← NodeStyle.GetFooterMargin[default];
nodeInfoReal ← NodeStyle.GetFooterMargin[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "footerMargin", handle.swap.layout.footerMargin.units];
selectionReal ← GetReal[handle.swap.layout.bindingMargin];
defaultReal ← NodeStyle.GetBindingMargin[default];
nodeInfoReal ← NodeStyle.GetBindingMargin[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "bindingMargin", handle.swap.layout.bindingMargin.units];
selectionReal ← GetReal[handle.swap.layout.lineLength];
defaultReal ← NodeStyle.GetLineLength[default];
nodeInfoReal ← NodeStyle.GetLineLength[handle.nodeInfo];
displayRope ← AppendValueAndUnits[handle, displayRope, selectionReal, defaultReal,
 nodeInfoReal, "lineLength", handle.swap.layout.lineLength.units];

selectionInt ← StyleToolConvert.GetIntegerFromViewer[handle.swap.layout.column
 ! StyleToolConvert.BadNumber => CONTINUE];
IF IntDifferences[handle, selectionInt, NodeStyle.GetColumns[default],
             NodeStyle.GetColumns[handle.nodeInfo]] THEN
 displayRope ← Rope.Cat[displayRope, IO.PutFToRope[integerFormat, IO.int[selectionInt]],
  " column\n"];
RETURN[displayRope];
END;
END.