- using Ink.Parsed;
- using System.Text;
- using System.Collections.Generic;
- using System.Linq;
- namespace Ink
- {
- public partial class InkParser
- {
- void TrimEndWhitespace(List<Parsed.Object> mixedTextAndLogicResults, bool terminateWithSpace)
- {
-
- if (mixedTextAndLogicResults.Count > 0) {
- var lastObjIdx = mixedTextAndLogicResults.Count - 1;
- var lastObj = mixedTextAndLogicResults[lastObjIdx];
- if (lastObj is Text) {
- var text = (Text)lastObj;
- text.text = text.text.TrimEnd (' ', '\t');
- if (terminateWithSpace)
- text.text += " ";
-
- else if( text.text.Length == 0 ) {
- mixedTextAndLogicResults.RemoveAt(lastObjIdx);
-
- TrimEndWhitespace(mixedTextAndLogicResults, terminateWithSpace:false);
- }
- }
- }
- }
- protected List<Parsed.Object> LineOfMixedTextAndLogic()
- {
-
-
- Parse (Whitespace);
- var result = Parse(MixedTextAndLogic);
- if (result == null || result.Count == 0)
- return null;
-
- var firstText = result[0] as Text;
- if (firstText) {
- if (firstText.text.StartsWith ("return")) {
- Warning ("Do you need a '~' before 'return'? If not, perhaps use a glue: <> (since it's lowercase) or rewrite somehow?");
- }
- }
- if (result.Count == 0)
- return null;
- var lastObj = result [result.Count - 1];
- if (!(lastObj is Divert)) {
- TrimEndWhitespace (result, terminateWithSpace:false);
- }
- EndTagIfNecessary(result);
-
-
-
-
- bool lineIsPureTag = result.Count > 0 && result[0] is Parsed.Tag && ((Parsed.Tag)result[0]).isStart;
- if( !lineIsPureTag )
- result.Add (new Text ("\n"));
- Expect(EndOfLine, "end of line", recoveryRule: SkipToNextLine);
- return result;
- }
- protected List<Parsed.Object> MixedTextAndLogic()
- {
-
- var disallowedTilda = ParseObject(Spaced(String("~")));
- if (disallowedTilda != null)
- Error ("You shouldn't use a '~' here - tildas are for logic that's on its own line. To do inline logic, use { curly braces } instead");
-
- var results = Interleave<Parsed.Object>(Optional (ContentText), Optional (InlineLogicOrGlueOrStartTag));
-
-
-
- if (!_parsingChoice) {
- var diverts = Parse (MultiDivert);
- if (diverts != null) {
-
- if (results == null)
- results = new List<Parsed.Object> ();
-
- EndTagIfNecessary(results);
- TrimEndWhitespace (results, terminateWithSpace:true);
- results.AddRange (diverts);
- }
- }
-
- if (results == null)
- return null;
- return results;
- }
- protected Parsed.Text ContentText()
- {
- return ContentTextAllowingEcapeChar ();
- }
- protected Parsed.Text ContentTextAllowingEcapeChar()
- {
- StringBuilder sb = null;
- do {
- var str = Parse(ContentTextNoEscape);
- bool gotEscapeChar = ParseString(@"\") != null;
- if( gotEscapeChar || str != null ) {
- if( sb == null ) {
- sb = new StringBuilder();
- }
- if( str != null ) {
- sb.Append(str);
- }
- if( gotEscapeChar ) {
- char c = ParseSingleCharacter();
- sb.Append(c);
- }
- } else {
- break;
- }
- } while(true);
- if (sb != null ) {
- return new Parsed.Text (sb.ToString ());
- } else {
- return null;
- }
- }
-
-
-
- protected string ContentTextNoEscape()
- {
-
-
-
-
- if (_nonTextPauseCharacters == null) {
- _nonTextPauseCharacters = new CharacterSet ("-<");
- }
-
-
-
- if (_nonTextEndCharacters == null) {
- _nonTextEndCharacters = new CharacterSet ("{}|\n\r\\#");
- _notTextEndCharactersChoice = new CharacterSet (_nonTextEndCharacters);
- _notTextEndCharactersChoice.AddCharacters ("[]");
- _notTextEndCharactersString = new CharacterSet (_nonTextEndCharacters);
- _notTextEndCharactersString.AddCharacters ("\"");
- }
-
- ParseRule nonTextRule = () => OneOf (ParseDivertArrow, ParseThreadArrow, EndOfLine, Glue);
- CharacterSet endChars = null;
- if (parsingStringExpression) {
- endChars = _notTextEndCharactersString;
- }
- else if (_parsingChoice) {
- endChars = _notTextEndCharactersChoice;
- }
- else {
- endChars = _nonTextEndCharacters;
- }
- string pureTextContent = ParseUntil (nonTextRule, _nonTextPauseCharacters, endChars);
- if (pureTextContent != null ) {
- return pureTextContent;
- } else {
- return null;
- }
- }
- CharacterSet _nonTextPauseCharacters;
- CharacterSet _nonTextEndCharacters;
- CharacterSet _notTextEndCharactersChoice;
- CharacterSet _notTextEndCharactersString;
- }
- }