void PushToOutputStreamIndividual(Runtime.Object obj) { var glue = obj as Runtime.Glue; var text = obj as Runtime.StringValue; bool includeInOutput = true; if (glue) { // Found matching left-glue for right-glue? Close it. Glue matchingRightGlue = null; if (glue.isLeft) { matchingRightGlue = MatchRightGlueForLeftGlue(glue); } // Left/Right glue is auto-generated for inline expressions // where we want to absorb newlines but only in a certain direction. // "Bi" glue is written by the user in their ink with <> if (glue.isLeft || glue.isBi) { TrimNewlinesFromOutputStream(matchingRightGlue); } includeInOutput = glue.isBi || glue.isRight; } else if (text) { if (currentGlueIndex != -1) { // Absorb any new newlines if there's existing glue // in the output stream. // Also trim any extra whitespace (spaces/tabs) if so. if (text.isNewline) { TrimFromExistingGlue(); includeInOutput = false; } // Able to completely reset when else if (text.isNonWhitespace) { RemoveExistingGlue(); } } else if (text.isNewline) { if (outputStreamEndsInNewline || !outputStreamContainsContent) { includeInOutput = false; } } } if (includeInOutput) { _outputStream.Add(obj); } }
protected Parsed.Wrap<Runtime.Glue> Glue() { // Don't want to parse whitespace, since it might be important // surrounding the glue. var glueStr = ParseString("<>"); if (glueStr != null) { var glue = new Runtime.Glue (Runtime.GlueType.Bidirectional); return new Parsed.Wrap<Runtime.Glue> (glue); } else { return null; } }
protected Parsed.Glue Glue() { // Don't want to parse whitespace, since it might be important // surrounding the glue. var glueStr = ParseString("<>"); if (glueStr != null) { var glue = new Runtime.Glue(Runtime.GlueType.Bidirectional); return(new Parsed.Glue(glue)); } else { return(null); } }
Runtime.Glue MatchRightGlueForLeftGlue(Glue leftGlue) { if (!leftGlue.isLeft) { return(null); } for (int i = _outputStream.Count - 1; i >= 0; i--) { var c = _outputStream [i]; var g = c as Glue; if (g && g.isRight && g.parent == leftGlue.parent) { return(g); } else if (c is ControlCommand) // e.g. BeginString { break; } } return(null); }
void TrimNewlinesFromOutputStream(Glue rightGlueToStopAt) { int removeWhitespaceFrom = -1; int rightGluePos = -1; bool foundNonWhitespace = false; // Work back from the end, and try to find the point where // we need to start removing content. There are two ways: // - Start from the matching right-glue (because we just saw a left-glue) // - Simply work backwards to find the first newline in a string of whitespace int i = _outputStream.Count - 1; while (i >= 0) { var obj = _outputStream [i]; var cmd = obj as ControlCommand; var txt = obj as StringValue; var glue = obj as Glue; if (cmd || (txt && txt.isNonWhitespace)) { foundNonWhitespace = true; if (rightGlueToStopAt == null) { break; } } else if (rightGlueToStopAt && glue == rightGlueToStopAt) { rightGluePos = i; break; } else if (txt && txt.isNewline && !foundNonWhitespace) { removeWhitespaceFrom = i; } i--; } // Remove the whitespace if (removeWhitespaceFrom >= 0) { i = removeWhitespaceFrom; while (i < _outputStream.Count) { var text = _outputStream [i] as StringValue; if (text) { _outputStream.RemoveAt(i); } else { i++; } } } // Remove the glue (it will come before the whitespace, // so index is still valid) // Also remove any other non-matching right glues that come after, // since they'll have lost their matching glues already if (rightGlueToStopAt && rightGluePos > -1) { i = rightGluePos; while (i < _outputStream.Count) { if (_outputStream [i] is Glue && ((Glue)_outputStream [i]).isRight) { _outputStream.RemoveAt(i); } else { i++; } } } OutputStreamDirty(); }
Runtime.Glue MatchRightGlueForLeftGlue (Glue leftGlue) { if (!leftGlue.isLeft) return null; for (int i = _outputStream.Count - 1; i >= 0; i--) { var c = _outputStream [i]; var g = c as Glue; if (g && g.isRight && g.parent == leftGlue.parent) { return g; } else if (c is ControlCommand) // e.g. BeginString break; } return null; }
void TrimNewlinesFromOutputStream(Glue rightGlueToStopAt) { int removeWhitespaceFrom = -1; int rightGluePos = -1; bool foundNonWhitespace = false; // Work back from the end, and try to find the point where // we need to start removing content. There are two ways: // - Start from the matching right-glue (because we just saw a left-glue) // - Simply work backwards to find the first newline in a string of whitespace int i = _outputStream.Count-1; while (i >= 0) { var obj = _outputStream [i]; var cmd = obj as ControlCommand; var txt = obj as StringValue; var glue = obj as Glue; if (cmd || (txt && txt.isNonWhitespace)) { foundNonWhitespace = true; if( rightGlueToStopAt == null ) break; } else if (rightGlueToStopAt && glue == rightGlueToStopAt) { rightGluePos = i; break; } else if (txt && txt.isNewline && !foundNonWhitespace) { removeWhitespaceFrom = i; } i--; } // Remove the whitespace if (removeWhitespaceFrom >= 0) { i=removeWhitespaceFrom; while(i < _outputStream.Count) { var text = _outputStream [i] as StringValue; if (text) { _outputStream.RemoveAt (i); } else { i++; } } } // Remove the glue (it will come before the whitespace, // so index is still valid) // Also remove any other non-matching right glues that come after, // since they'll have lost their matching glues already if (rightGlueToStopAt && rightGluePos > -1) { i = rightGluePos; while(i < _outputStream.Count) { if (_outputStream [i] is Glue && ((Glue)_outputStream [i]).isRight) { _outputStream.RemoveAt (i); } else { i++; } } } }