/// <summary> /// Construct a <see cref="PropertyToken"/>. /// </summary> /// <param name="propertyName">The name of the property.</param> /// <param name="rawText">The token as it appears in the message template.</param> /// <param name="format">The format applied to the property, if any.</param> /// <param name="alignment">The alignment applied to the property, if any.</param> /// <param name="destructuring">The destructuring strategy applied to the property, if any.</param> /// <param name="startIndex">The token's start index in the template.</param> /// <exception cref="ArgumentNullException"></exception> public PropertyToken(string propertyName, string rawText, string format = null, Alignment? alignment = null, Destructuring destructuring = Destructuring.Default, int startIndex = -1) : base(startIndex) { if (propertyName == null) throw new ArgumentNullException("propertyName"); if (rawText == null) throw new ArgumentNullException("rawText"); _propertyName = propertyName; _format = format; _destructuring = destructuring; _rawText = rawText; _alignment = alignment; int position; if (int.TryParse(_propertyName, NumberStyles.None, CultureInfo.InvariantCulture, out position) && position >= 0) { _position = position; } }
static MessageTemplateToken ParsePropertyToken(int startAt, string messageTemplate, out int next) { var first = startAt; startAt++; while (startAt < messageTemplate.Length && IsValidInPropertyTag(messageTemplate[startAt])) startAt++; if (startAt == messageTemplate.Length || messageTemplate[startAt] != '}') { next = startAt; return new TextToken(messageTemplate.Substring(first, next - first), first); } next = startAt + 1; var rawText = messageTemplate.Substring(first, next - first); var tagContent = messageTemplate.Substring(first + 1, next - (first + 2)); if (tagContent.Length == 0 || !IsValidInPropertyTag(tagContent[0])) return new TextToken(rawText, first); string propertyNameAndDestructuring, format, alignment; if (!TrySplitTagContent(tagContent, out propertyNameAndDestructuring, out format, out alignment)) return new TextToken(rawText, first); var propertyName = propertyNameAndDestructuring; Destructuring destructuring; if (TryGetDestructuringHint(propertyName[0], out destructuring)) propertyName = propertyName.Substring(1); if (propertyName == "" || !IsValidInPropertyName(propertyName[0])) return new TextToken(rawText, first); for (var i = 0; i < propertyName.Length; ++i) { var c = propertyName[i]; if (!IsValidInPropertyName(c)) return new TextToken(rawText, first); } if (format != null) { for (var i = 0; i < format.Length; ++i) { var c = format[i]; if (!IsValidInFormat(c)) return new TextToken(rawText, first); } } Alignment? alignmentValue = null; if (alignment != null) { for (var i = 0; i < alignment.Length; ++i) { var c = alignment[i]; if (!IsValidInAlignment(c)) return new TextToken(rawText, first); } var lastDash = alignment.LastIndexOf('-'); if (lastDash > 0) return new TextToken(rawText, first); var width = lastDash == -1 ? int.Parse(alignment) : int.Parse(alignment.Substring(1)); if (width == 0) return new TextToken(rawText, first); var direction = lastDash == -1 ? AlignmentDirection.Right : AlignmentDirection.Left; alignmentValue = new Alignment(direction, width); } return new PropertyToken( propertyName, rawText, format, alignmentValue, destructuring, first); }