public DynamicLayoutingData(UString title, IEnumerable<Printing.IPrintableLine> lineEnum, float leading, int numberOfLines) { _title = title; _lineEnum = lineEnum; _leading = leading; _numberOfLines = numberOfLines; }
public void BeginParagraph(ILatinWordMetric latinMetric, ParagraphStyle style) { _builder = new Formatting.ParagraphBuilder(latinMetric, style); _builder.BeginParagraph(); _inRuby = false; _rubyBaseText = new UStringBuilder(16); _rubyText = null; }
public static UString Parse(UString annotationText) { var match = _heading.Match(annotationText.String); if (match.Success) return new UString(match.Groups[1].Value); else return null; }
/// <summary>Gets the index of a substring in a StringBuilder</summary> /// <returns>Index of the first instance of the specified substring in the StringBuilder, or -1 if not found</returns> public static int IndexOf(this StringBuilder sb, UString searchStr, int startIndex = 0, bool ignoreCase = false) { var stopAt = sb.Length - searchStr.Length; for (int i = startIndex; i <= stopAt; i++) if (SubstringEqualHelper(sb, i, searchStr, ignoreCase)) return i; return -1; }
public void Ruby(int start, int end, UString rubyText) { if (start >= end) { Console.WriteLine("WARNING: ルビの親文字が空です({0}文字目/{1})", start + 1, _textBuffer.ToString()); return; } Upsert(start, MetaInfo.RUBY_START, rubyText); Upsert(end, MetaInfo.RUBY_END); }
public IExchangableText Convert(UString line) { var buffer = new FormattedTextBuffer(); var visitor = CreateTokenVisitor(buffer); foreach (var token in RubyParser.Parse(line)) { token.Accept(visitor); } return buffer; }
public void TextWithGroupRuby(UString baseText, UString rubyText) { var baseBuffer = new TextBuffer(_zwSize, _wordWrap, _advancing, _latinMetric, 64); var rubyBuffer = new TextBuffer(_rubyZwSize, _wordWrap, _advancing, _latinMetric, 128); _buffer.MoveLastLetterStateTo(baseBuffer); baseBuffer.Append(baseText); rubyBuffer.Append(rubyText); _buffer.AppendObject(new GroupRuby(baseBuffer.ToArray(), rubyBuffer.ToArray())); baseBuffer.MoveLastLetterStateTo(_buffer); baseBuffer.Clear(); rubyBuffer.Clear(); }
/// <summary>A simple method to parse a sequence of hex digits, without /// overflow checks or other features supported by methods like /// <see cref="TryParseInt(string, ref int, out int, int, bool)"/>.</summary> /// <returns>The number of digits parsed</returns> public static int TryParseHex(ref UString s, out int value) { value = 0; int len = 0; for(;; len++, s = s.Slice(1)) { int digit = HexDigitValue(s[0, '\0']); if (digit == -1) return len; else value = (value << 4) + digit; } }
/// <summary>Escapes characters in a string using C style.</summary> /// <param name="flags">Specifies which characters should be escaped.</param> /// <param name="quoteType">Specifies a character that should always be /// escaped (typically one of <c>' " `</c>)</param> public static string EscapeCStyle(UString s, EscapeC flags, char quoteType) { StringBuilder s2 = new StringBuilder(s.Length+1); bool usedEscapes = false, fail; for (;;) { int c = s.PopFirst(out fail); if (fail) break; usedEscapes |= EscapeCStyle(c, s2, flags, quoteType); } if (!usedEscapes && s.InternalString.Length == s.Length) return s.InternalString; return s2.ToString(); }
public static UString Parse(UString annotationText) { var match = _heading.Match(annotationText.String); if (match.Success) { var text = match.Groups[1].Value; var scale = ParseScale(match.Groups[1].Value[0]); return new UString(text); } else { return null; } }
/// <summary>Unescapes a string that uses C-style escape sequences, e.g. /// "\\\n\\\r" becomes "\n\r".</summary> /// <param name="encountered">Returns information about whether escape /// sequences were encountered, and which categories.</param> /// <param name="removeUnnecessaryBackslashes">Causes the backslash before /// an unrecognized escape sequence to be removed, e.g. "\z" => "z".</param> /// <remarks>See <see cref="UnescapeChar(ref UString, ref EscapeC)"/> for details.</remarks> public static StringBuilder UnescapeCStyle(UString s, out EscapeC encountered, bool removeUnnecessaryBackslashes = false) { encountered = 0; StringBuilder @out = new StringBuilder(s.Length); while (s.Length > 0) { EscapeC encounteredHere = 0; int c = UnescapeChar(ref s, ref encounteredHere); encountered |= encounteredHere; if (removeUnnecessaryBackslashes && (encounteredHere & EscapeC.Unrecognized) != 0) { Debug.Assert(c == '\\'); continue; } @out.AppendCodePoint(c); } return @out; }
private void Upsert(int index, uint flag, UString rubyText = null) { MetaInfo existing; if (!_metaInfos.TryGetValue(index, out existing)) { existing = new MetaInfo(); _metaInfos.Add(index, existing); } existing.Flags |= flag; if (flag == MetaInfo.RUBY_START) { if (rubyText == null) { throw new ArgumentNullException("rubyText"); } existing.RubyText = rubyText; } }
/// <inheritdoc cref="ParseSingle(IParsingService, UString, IMessageSink, IParsingOptions)"/> public static LNode ParseSingle(this IParsingService parser, UString expr, IMessageSink msgs = null, ParsingMode inputType = null, bool preserveComments = true) { return(ParseSingle(parser, expr, msgs, QuickOptions(inputType, preserveComments))); }
public OutlineNode FirstChild(UString title) { if (_firstChild != null) throw new InvalidOperationException(); return _firstChild = new OutlineNode(this, 1, title); }
public void PrintLatinText(UString text, float length) { //UNDONE: latin 単語中のサイズ変更は未対応 var cb = _writer.DirectContent; _emdashRenderer.Close(cb, _fontSize, _xtlm, MyYTLM); cb.SetFontAndSize(_latinFont, _fontSize); cb.SetTextMatrix(0, -1, 1, 0, _xtlm - _fontSize * 0.5F + _fontSize * _latinBaselineOffsetRatio, MyYTLM); cb.ShowText(text.String); //フォントを復帰。場合によっては後に重ねて設定されるが構わない cb.SetFontAndSize(_font, _fontSize); _deltaY += length; }
/// <summary>Parses a string and expects exactly one output.</summary> /// <exception cref="InvalidOperationException">The output list was empty or contained multiple nodes.</exception> public static LNode ParseSingle(this IParsingService parser, UString expr, IMessageSink msgs, IParsingOptions options) { var e = Parse(parser, expr, msgs, options); return(Single(e)); }
public OutlineNode(int initialValue, UString title) : this(null, initialValue, title) { }
static UString StripInitialNewline(UString input) { if (input.StartsWith("\r")) input = input.Slice(1); if (input.StartsWith("\n")) input = input.Slice(1); return input; }
public static bool UnescapeString(ref UString sourceText, char quoteType, bool isTripleQuoted, Action <int, string> onError, StringBuilder sb, UString indentation = default(UString), bool les3TQIndents = false) => Les3Lexer.UnescapeString(ref sourceText, quoteType, isTripleQuoted, onError, sb, indentation, les3TQIndents);
protected Symbol ParseBQStringValue() { UString s = ParseStringCore(false); return(IdToSymbol(s)); }
/// <summary>Parses a normal or triple-quoted string that still includes /// the quotes. Supports quote types '\'', '"' and '`'.</summary> /// <param name="sourceText">input text</param> /// <param name="onError">Called in case of parsing error (unknown escape sequence or missing end quotes)</param> /// <param name="indentation">Inside a triple-quoted string, any text /// following a newline is ignored as long as it matches this string. /// For example, if the text following a newline is "\t\t Foo" and this /// string is "\t\t\t", the tabs are ignored and " Foo" is kept.</param> /// <param name="les3TQIndents">Enable EC# triple-quoted string indent /// rules, which allow an additional one tab or three spaces of indent. /// (I'm leaning toward also supporting this in LES; switched on in v3)</param> /// <returns>The decoded string</returns> /// <remarks>This method recognizes LES and EC#-style string syntax. /// Firstly, it recognizes triple-quoted strings (''' """ ```). These /// strings enjoy special newline handling: the newline is always /// interpreted as \n regardless of the actual kind of newline (\r and /// \r\n newlines come out as \n), and indentation following the newline /// can be stripped out. Triple-quoted strings can have escape sequences /// that use both kinds of slash, like so: <c>\n/ \r/ \'/ \"/ \0/</c>. /// However, there are no unicode escapes (\u1234/ is NOT supported). /// <para/> /// Secondly, it recognizes normal strings (' " `). These strings stop /// parsing (with an error) at a newline, and can contain C-style escape /// sequences: <c>\n \r \' \" \0</c> etc. C#-style verbatim strings are /// NOT supported. /// </remarks> public static string UnescapeQuotedString(ref UString sourceText, Action <int, string> onError, UString indentation = default(UString), bool les3TQIndents = false) { var sb = new StringBuilder(); UnescapeQuotedString(ref sourceText, onError, sb, indentation, les3TQIndents); return(sb.ToString()); }
/// <summary>Parses a normal or triple-quoted string whose starting quotes /// have been stripped out. If triple-quote parsing was requested, stops /// parsing at three quote marks; otherwise, stops parsing at a single /// end-quote or newline.</summary> /// <returns>true if parsing stopped at one or three quote marks, or false /// if parsing stopped at the end of the input string or at a newline (in /// a string that is not triple-quoted).</returns> /// <remarks>This method recognizes LES and EC#-style string syntax.</remarks> public static bool UnescapeString(ref UString sourceText, char quoteType, bool isTripleQuoted, Action <int, string> onError, StringBuilder sb, UString indentation = default(UString)) { Debug.Assert(quoteType == '"' || quoteType == '\'' || quoteType == '`'); bool fail; for (;;) { if (sourceText.IsEmpty) { return(false); } int i0 = sourceText.InternalStart; if (!isTripleQuoted) { char c = G.UnescapeChar(ref sourceText); if ((c == quoteType || c == '\n') && sourceText.InternalStart == i0 + 1) { return(c == quoteType); // end of string } if (c == '\\' && sourceText.InternalStart == i0 + 1) { // This backslash was ignored by UnescapeChar onError(i0, Localize.From(@"Unrecognized escape sequence '\{0}' in string", G.EscapeCStyle(sourceText[0, ' '].ToString(), EscapeC.Control))); } sb.Append(c); } else { // Inside triple-quoted string int c; if (sourceText[2, '\0'] == '/') { // Detect escape sequence c = G.UnescapeChar(ref sourceText); if (sourceText.InternalStart > i0 + 1) { G.Verify(sourceText.PopFront(out fail) == '/'); } } else { c = sourceText.PopFront(out fail); if (fail) { return(false); } if (c == quoteType) { if (sourceText[0, '\0'] == quoteType && sourceText[1, '\0'] == quoteType) { sourceText = sourceText.Substring(2); // end of string return(true); } } if (c == '\r' || c == '\n') { // To ensure platform independency of source code, CR and // CR-LF become LF. if (c == '\r') { c = '\n'; var copy = sourceText.Clone(); if (sourceText.PopFront(out fail) != '\n') { sourceText = copy; } } // Inside a triple-quoted string, the indentation following a newline // is ignored, as long as it matches the indentation of the first line. UString src = sourceText.Clone(), ind = indentation; while (src.PopFront(out fail) == ind.PopFront(out fail) && !fail) { sourceText = src; } } } sb.Append((char)c); } } }
static object ParseIntegerValue(UString source, bool isNegative, int numberBase, Symbol suffix, ref string error) { if (source.IsEmpty) { error = Localize.From("Syntax error in integer literal"); return(CG.Cache(0)); } // Parse the integer ulong unsigned; bool overflow = !G.TryParseUInt(ref source, out unsigned, numberBase, G.ParseFlag.SkipUnderscores); if (!source.IsEmpty) { // I'm not sure if this can ever happen error = Localize.From("Syntax error in integer literal"); } // If no suffix, automatically choose int, uint, long or ulong if (suffix == null) { if (unsigned > long.MaxValue) { suffix = _UL; } else if (unsigned > uint.MaxValue) { suffix = _L; } else if (unsigned > int.MaxValue) { suffix = isNegative ? _L : _U; } } if (isNegative && (suffix == _U || suffix == _UL)) { // Oops, an unsigned number can't be negative, so treat // '-' as a separate token and let the number be reparsed. return(CodeSymbols.Sub); } // Create boxed integer of the appropriate type object value; if (suffix == _UL) { value = unsigned; } else if (suffix == _U) { overflow = overflow || (uint)unsigned != unsigned; value = (uint)unsigned; } else if (suffix == _L) { if (isNegative) { overflow = overflow || -(long)unsigned > 0; value = -(long)unsigned; } else { overflow = overflow || (long)unsigned < 0; value = (long)unsigned; } } else { value = isNegative ? -(int)unsigned : (int)unsigned; } if (overflow) { error = Localize.From("Overflow in integer literal (the number is 0x{0:X} after binary truncation).", value); } return(value); }
public static IListSource <LNode> Parse(this IParsingService parser, UString input, IMessageSink msgs = null, Symbol inputType = null) { return(parser.Parse(input, "", msgs ?? MessageSink.Current, inputType)); }
public static Page Get(String url) { try { if (url == null || url.Length > 100 || url.Length < 8) { return(null); } Page page = new Page(); page.url = url; CQ doc = CQ.CreateFromUrl(url); //Console.WriteLine(doc.Html()); doc ["script"].Remove(); doc ["style"].Remove(); doc ["Script"].Remove(); doc ["Style"].Remove(); page.title = doc ["title"].Text(); if (page.title == null) { page.title = doc ["Title"].Text(); } if (page.title == null) { page.title = url; } page.title = page.title.Trim(); if (page.title.Length < 2) { page.title = url; } if (page.title.Length > 80) { page.title = page.title.Substring(0, 80); } page.title = page.title.Replace("<", " ") .Replace(">", " ").Replace("$", " "); page.description = doc ["meta[name='description']"].Attr("content"); if (page.description == null) { page.description = doc ["meta[name='Description']"].Attr("content"); } if (page.description == null) { page.description = ""; } if (page.description.Length > 200) { page.description = page.description.Substring(0, 200); } page.description = page.description.Replace("<", " ") .Replace(">", " ").Replace("$", " "); doc = CQ.Create(doc.Text().Replace("<", "<") .Replace(">", ">")); doc ["script"].Remove(); doc ["style"].Remove(); doc ["Script"].Remove(); doc ["Style"].Remove(); String content = doc.Text().Trim(); content = content.Replace("\r", " ") .Replace("\n", " ") .Replace(" ", " ") .Replace(" ", " ") .Replace(" ", " ") .Replace(" ", " ") .Replace(" ", " ").Trim(); if (content.Length < 50) { return(null); } if (content.Length > 5000) { content = content.Substring(0, 5000); } page.content = ((content + " " + page.url + " " + page.description) .Replace("<", " ") .Replace(">", " ").Replace("$", " ") .Replace(" ", " ")); return(page); } catch (Exception ex) { Console.WriteLine(ex.ToString()); return(null); } }
public static LNode ParseSingle(this IParsingService parser, UString expr, IMessageSink msgs = null, Symbol inputType = null) { var e = parser.Parse(expr, msgs, inputType); return(Single(e)); }
public static ILexer<Token> Tokenize(this IParsingService parser, UString input, IMessageSink msgs = null) { return parser.Tokenize(input, "", msgs ?? MessageSink.Current); }
/// <summary>Parses a normal or triple-quoted string that still includes /// the quotes (see documentation of the first overload) into a /// StringBuilder.</summary> public static void UnescapeQuotedString(ref UString sourceText, Action <int, string> onError, StringBuilder sb, UString indentation = default(UString), bool les3TQIndents = false) { bool isTripleQuoted = false, fail; char quoteType = (char)sourceText.PopFirst(out fail); if (sourceText[0, '\0'] == quoteType && sourceText[1, '\0'] == quoteType) { sourceText = sourceText.Substring(2); isTripleQuoted = true; } if (!UnescapeString(ref sourceText, quoteType, isTripleQuoted, onError, sb, indentation, les3TQIndents)) { onError(sourceText.InternalStart, Localize.Localized("String literal did not end properly")); } }
public static LNode ParseSingle(this IParsingService parser, UString expr, IMessageSink msgs = null, Symbol inputType = null) { var e = parser.Parse(expr, msgs, inputType); return Single(e); }
public Les2Lexer(UString text, IMessageSink errorSink) : this(text, "", errorSink) { }
/// <summary>Finds out whether the StringBuilder starts with the specified substring.</summary> public static bool StartsWith(this StringBuilder sb, UString what, bool ignoreCase = false) { if (what.Length > sb.Length) return false; return SubstringEqualHelper(sb, 0, what, ignoreCase); }
/// <summary>Parses a normal or triple-quoted string whose starting quotes /// have been stripped out. If triple-quote parsing was requested, stops /// parsing at three quote marks; otherwise, stops parsing at a single /// end-quote or newline.</summary> /// <returns>true if parsing stopped at one or three quote marks, or false /// if parsing stopped at the end of the input string or at a newline (in /// a string that is not triple-quoted).</returns> /// <remarks>This method recognizes LES and EC#-style string syntax.</remarks> public static bool UnescapeString(ref UString sourceText, char quoteType, bool isTripleQuoted, Action <int, string> onError, StringBuilder sb, UString indentation = default(UString), bool les3TQIndents = false) { Debug.Assert(quoteType == '"' || quoteType == '\'' || quoteType == '`'); bool fail; for (;;) { if (sourceText.IsEmpty) { return(false); } int i0 = sourceText.InternalStart; if (!isTripleQuoted) { EscapeC category = 0; int c = ParseHelpers.UnescapeChar(ref sourceText, ref category); if ((c == quoteType || c == '\n') && sourceText.InternalStart == i0 + 1) { return(c == quoteType); // end of string } if ((category & EscapeC.Unrecognized) != 0) { // This backslash was ignored by UnescapeChar onError(i0, @"Unrecognized escape sequence '\{0}' in string".Localized(PrintHelpers.EscapeCStyle(sourceText[0, ' '].ToString(), EscapeC.Control))); } else if ((category & EscapeC.HasInvalid6DigitEscape) != 0) { onError(i0, @"Invalid 6-digit \u code treated as 5 digits".Localized()); } sb.AppendCodePoint(c); if ((category & EscapeC.BackslashX) != 0 && c >= 0x80) { DetectUtf8(sb); } else if (c.IsInRange(0xDC00, 0xDFFF)) { RecodeSurrogate(sb); } } else { // Inside triple-quoted string int c; if (sourceText[2, '\0'] == '/') { // Detect escape sequence c = ParseHelpers.UnescapeChar(ref sourceText); if (sourceText.InternalStart > i0 + 1) { G.Verify(sourceText.PopFirst(out fail) == '/'); } } else { c = sourceText.PopFirst(out fail); if (fail) { return(false); } if (c == quoteType) { if (sourceText[0, '\0'] == quoteType && sourceText[1, '\0'] == quoteType) { sourceText = sourceText.Substring(2); // end of string return(true); } } if (c == '\r' || c == '\n') { // To ensure platform independency of source code, CR and // CR-LF become LF. if (c == '\r') { c = '\n'; var copy = sourceText.Clone(); if (sourceText.PopFirst(out fail) != '\n') { sourceText = copy; } } // Inside a triple-quoted string, the indentation following a newline // is ignored, as long as it matches the indentation of the first line. UString src = sourceText, ind = indentation; int sp; while ((sp = src.PopFirst(out fail)) == ind.PopFirst(out fail) && !fail) { sourceText = src; } if (les3TQIndents && fail) { // Allow an additional one tab or three spaces when initial indent matches if (sp == '\t') { sourceText = src; } else if (sp == ' ') { sourceText = src; if (src.PopFirst(out fail) == ' ') { sourceText = src; } if (src.PopFirst(out fail) == ' ') { sourceText = src; } } } } } sb.AppendCodePoint(c); } } }
public static bool TryParseHex(UString s, out int value) { int count = TryParseHex(ref s, out value); return(count > 0 && s.IsEmpty); }
static object ParseIntegerValue(UString source, bool isNegative, int numberBase, Symbol typeSuffix, ref string error) { if (source.IsEmpty) { error = Localize.Localized("Syntax error in integer literal"); return(CG.Cache(0)); } bool overflow; if (typeSuffix == _Z) { // Fast path for BigInteger values. return(ParseBigIntegerValue(source, isNegative, numberBase, ref error)); } // Create a copy of the input, in case we need to re-parse it as // a BigInteger. var srcCopy = source; // Parse the integer ulong unsigned; overflow = !ParseHelpers.TryParseUInt(ref source, out unsigned, numberBase, ParseNumberFlag.SkipUnderscores); if (!source.IsEmpty) { // I'm not sure if this can ever happen error = Localize.Localized("Syntax error in integer literal"); } // If no suffix, automatically choose int, uint, long, ulong or BigInteger. if (typeSuffix == null) { if (overflow) { // If we tried to parse a plain integer literal (no suffix) // as a ulong, but failed due to overflow, then we'll parse // it as a BigInteger instead. return(ParseBigIntegerValue(srcCopy, isNegative, numberBase, ref error)); } else if (isNegative && -(long)unsigned > 0) { // We parsed a literal whose absolute value fits in a ulong, // but which cannot be represented as a long. Return a // BigInteger literal instead. return(-new BigInteger(unsigned)); } else if (unsigned > long.MaxValue) { typeSuffix = _UL; } else if (unsigned > uint.MaxValue) { typeSuffix = _L; } else if (unsigned > int.MaxValue) { typeSuffix = isNegative ? _L : _U; } } if (isNegative && (typeSuffix == _U || typeSuffix == _UL)) { // Oops, an unsigned number can't be negative, so treat // '-' as a separate token and let the number be reparsed. return(CodeSymbols.Sub); } // Create boxed integer of the appropriate type object value; if (typeSuffix == _UL) { value = unsigned; typeSuffix = null; } else if (typeSuffix == _U) { overflow = overflow || (uint)unsigned != unsigned; value = (uint)unsigned; typeSuffix = null; } else if (typeSuffix == _L) { if (isNegative) { overflow = overflow || -(long)unsigned > 0; value = -(long)unsigned; } else { overflow = overflow || (long)unsigned < 0; value = (long)unsigned; } typeSuffix = null; } else { value = isNegative ? -(int)unsigned : (int)unsigned; } if (overflow) { error = Localize.Localized("Overflow in integer literal (the number is 0x{0:X} after binary truncation).", value); } if (typeSuffix == null) { return(value); } else { return(new CustomLiteral(value, typeSuffix)); } }
public OutlineNode(UString title) : this(1, title) { }
public static ILexer <Token> Tokenize(this IParsingService parser, UString input, IMessageSink msgs = null) { return(parser.Tokenize(input, "", msgs ?? MessageSink.Current)); }
private OutlineNode(OutlineNode parent, int initialValue, UString title) { _parent = parent; _value = initialValue; _title = title; }
static bool SubstringEqualHelper(StringBuilder sb, int start, UString what, bool ignoreCase = false) { if (ignoreCase) for (int i = 0; i < what.Length; i++) { if (char.ToUpperInvariant(sb[start + i]) != char.ToUpperInvariant(what[i])) return false; } else for (int i = 0; i < what.Length; i++) { if (sb[start + i] != what[i]) return false; } return true; }
public LatinWord(UString letters, float length) { Letters = letters; Length = length; }
void IExchangableTextVisitor.Heading(int level, UString title) { //TODO: }
public void SetOutlineHere(int level, UString title) { _outlineBuilder.AppendOutline(level, title, _writer.DirectContent); }
/// <summary>Parses a string by invoking <see cref="IParsingService.Parse(ICharSource, string, IMessageSink, IParsingOptions)"/> using an empty string as the file name.</summary> public static IListSource <LNode> Parse(this IParsingService parser, UString input, IMessageSink msgs = null, ParsingMode inputType = null, bool preserveComments = true) { return(parser.Parse(input, "", msgs ?? MessageSink.Default, QuickOptions(inputType, preserveComments))); }
internal InlineWordPartLatin(float length, float offset, UString text) { _length = length; _offset = offset; _text = text; }
int MeasureIndent(UString indent) { return(MeasureIndent(indent, SpacesPerTab)); }
public static IListSource<LNode> Parse(this IParsingService parser, UString input, IMessageSink msgs = null, Symbol inputType = null) { return parser.Parse(input, "", msgs ?? MessageSink.Current, inputType); }
public static string EscapeCStyle(UString s, EscapeC flags = EscapeC.Default) { return(EscapeCStyle(s, flags, '\0')); }
/// <summary>Parses a string by invoking <see cref="IParsingService.Parse(ICharSource, string, IMessageSink, IParsingOptions)"/> using an empty string as the file name.</summary> public static IListSource <LNode> Parse(this IParsingService parser, UString input, IMessageSink msgs, IParsingOptions options) { return(parser.Parse(input, "", msgs ?? MessageSink.Default, options ?? _fileWithComments)); }
/// <summary>Low-level method that identifies the parts of a float literal /// of arbitrary base (typically base 2, 10, or 16) with no prefix or /// suffix, such as <c>2.Cp0</c> (which means 2.75 in base 16).</summary> /// <param name="radix">Base of the number to parse; must be between 2 /// and 36.</param> /// <param name="mantissa">Integer magnitude of the number.</param> /// <param name="exponentBase2">Base-2 exponent to apply, as specified by /// the 'p' suffix, or 0 if there is no 'p' suffix..</param> /// <param name="exponentBase10">Base-10 exponent to apply, as specified by /// the 'e' suffix, or 0 if there is no 'e' suffix..</param> /// <param name="exponentBaseR">Base-radix exponent to apply. This number /// is based on the front part of the number only (not including the 'p' or /// 'e' suffix). Negative values represent digits after the decimal point, /// while positive numbers represent 64-bit overflow. For example, if the /// input is <c>12.3456</c> with <c>radix=10</c>, the output will be /// <c>mantissa=123456</c> and <c>exponentBaseR=-4</c>. If the input is /// <c>0123_4567_89AB_CDEF_1234.5678</c> with <c>radix=16</c>, the mantissa /// overflows, and the result is <c>mantissa = 0x1234_5678_9ABC_DEF1</c> /// with <c>exponentBaseR=3</c>.</param> /// <param name="numDigits">Set to the number of digits in the number, not /// including the exponent part.</param> /// <param name="flags">Alters parsing behavior, see <see cref="ParseFlags"/>.</param> /// <remarks> /// The syntax required is /// <code> /// ( '+'|'-' )? /// ( Digits ('.' Digits?)? | '.' Digits ) /// ( ('p'|'P') ('-'|'+')? DecimalDigits+ )? /// ( ('e'|'E') ('-'|'+')? DecimalDigits+ )? /// </code> /// where Digits refers to one digits in the requested base, possibly /// including underscores or spaces if the flags allow it; similarly, /// DecimalDigits refers to base-10 digits and is also affected by the /// flags. /// <para/> /// Returns false if there was an error interpreting the input. /// <para/> /// To keep the parser relatively simple, it does not roll back in case of /// error the way the int parser does. For example, given the input "23p", /// the 'p' is consumed and causes the method to return false, even though /// the parse could have been successful if it had ignored the 'p'. /// </remarks> public static bool TryParseFloatParts(ref UString source, int radix, out bool negative, out ulong mantissa, out int exponentBaseR, out int exponentBase2, out int exponentBase10, out int numDigits, ParseNumberFlag flags = 0) { flags |= ParseNumberFlag.StopBeforeOverflow; if ((flags & ParseNumberFlag.SkipSpacesInFront) != 0) { source = SkipSpaces(source); } negative = false; char c = source[0, '\0']; if (c == '-' || c == '+') { negative = c == '-'; source = source.Slice(1); } int numDigits2 = 0; mantissa = 0; exponentBase2 = 0; exponentBase10 = 0; exponentBaseR = 0; bool success = TryParseUInt(ref source, ref mantissa, radix, flags, out numDigits); if (!success) // possible overflow, extra digits remain if so { numDigits += (exponentBaseR = SkipExtraDigits(ref source, radix, flags)); } c = source[0, '\0']; if (c == '.' || (c == ',' && (flags & ParseNumberFlag.AllowCommaDecimalPoint) != 0)) { source = source.Slice(1); if (exponentBaseR == 0) { success = TryParseUInt(ref source, ref mantissa, radix, flags, out numDigits2); if ((numDigits += numDigits2) == 0) { return(false); } exponentBaseR = -numDigits2; } else { Debug.Assert(!success); } if (!success) // possible overflow, extra digits remain if so { numDigits += SkipExtraDigits(ref source, radix, flags); } c = source[0, '\0']; } if (numDigits == 0) { return(false); } success = true; if (c == 'p' || c == 'P') { source = source.Slice(1); success = TryParseInt(ref source, out exponentBase2, 10, flags) && success; c = source[0, '\0']; } if (c == 'e' || c == 'E') { source = source.Slice(1); success = TryParseInt(ref source, out exponentBase10, 10, flags) && success; } return(success); }
/// <summary>Gets the index of a substring in a StringBuilder</summary> /// <returns>Index of the last instance of the specified substring in the StringBuilder, or -1 if not found</returns> public static int LastIndexOf(this StringBuilder sb, UString searchStr, int startIndex = int.MaxValue, bool ignoreCase = false) { if (startIndex > sb.Length - searchStr.Length) startIndex = sb.Length - searchStr.Length; for (int i = startIndex; i >= 0; i--) if (SubstringEqualHelper(sb, i, searchStr, ignoreCase)) return i; return -1; }
/// <summary>Unescapes a string that uses C-style escape sequences, e.g. "\n\r" becomes @"\n\r".</summary> public static string UnescapeCStyle(UString s, bool removeUnnecessaryBackslashes = false) { EscapeC _; return(UnescapeCStyle(s.InternalString, s.InternalStart, s.Length, out _, removeUnnecessaryBackslashes)); }
/// <summary>Checks if the sequences of characters <c>what</c> is equal to /// <c>sb.Substring(start, what.Length)</c>, without actually creating a /// substring object.</summary> public static bool SubstringEquals(StringBuilder sb, int start, UString what, bool ignoreCase = false) { CheckParam.IsNotNegative("start", start); if (start > sb.Length - what.Length) return false; return SubstringEqualHelper(sb, start, what, ignoreCase); }
public static void UnescapeQuotedString(ref UString sourceText, Action <int, string> onError, StringBuilder sb, UString indentation = default(UString), bool les3TQIndents = false) => Les3Lexer.UnescapeQuotedString(ref sourceText, onError, sb, indentation, les3TQIndents);
private void Init() { _descText.text = UString.RemoveLastPart(Key); _priceText.text = ""; }
static string UnescapeQuotedString(ref UString source, bool isVerbatim, Action <int, string> onError, UString indentation) { Debug.Assert(source.Length >= 1); if (isVerbatim) { bool fail; char stringType = (char)source.PopFront(out fail); StringBuilder sb = new StringBuilder(); int c; for (;;) { c = source.PopFront(out fail); if (fail) { break; } if (c == stringType) { if ((c = source.PopFront(out fail)) != stringType) { break; } } sb.Append((char)c); } return(sb.ToString()); } else { // triple-quoted or normal string: let LES lexer handle it return(LesLexer.UnescapeQuotedString(ref source, onError, indentation, true)); } }
void IExchangableTextVisitor.RubyStart(UString rubyText) { _buffer.AppendFormat("<RBY CHAR=\"{0}\" POS=J>", rubyText); }
/// <summary>Parses a string by invoking <see cref="IParsingService.Tokenize(ICharSource, string, IMessageSink, IParsingOptions)"/> using an empty string as the file name.</summary> public static ILexer <Token> Tokenize(this IParsingService parser, UString input, IMessageSink msgs = null) { return(parser.Tokenize(input, "", msgs ?? MessageSink.Default, _fileWithComments)); }