Code/Dependencies/DotNetGraph/Core/DotIdentifier.cs
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Nodebox.Dependencies.DotNetGraph.Compilation;
using Nodebox.Dependencies.DotNetGraph.Extensions;
namespace Nodebox.Dependencies.DotNetGraph.Core {
public class DotIdentifier : IDotElement, IEquatable<DotIdentifier> {
private readonly bool _quoteReservedWords;
private static readonly Regex NoQuotesRequiredRegex
= new Regex("^([a-zA-Z\\200-\\377_][a-zA-Z\\200-\\3770-9_]*|[-]?(.[0-9]+|[0-9]+(.[0-9]+)?))$");
private static readonly string[] ReservedWords =
{
"graph",
"digraph",
"subgraph",
"strict",
"node",
"edge"
};
public string Value { get; set; }
public bool IsHtml { get; set; } = false;
public DotIdentifier(string value, bool isHtml = false, bool quoteReservedWords = true) {
_quoteReservedWords = quoteReservedWords;
Value = value;
IsHtml = isHtml;
}
public async Task CompileAsync(CompilationContext context) {
if (IsHtml) {
await context.TextWriter.WriteAsync($"<{Value}>");
return;
}
var value = context.Options.AutomaticEscapedCharactersFormat ? Value.FormatGraphvizEscapedCharacters() : Value;
if (RequiresDoubleQuotes(value) && _quoteReservedWords)
await context.TextWriter.WriteAsync($"\"{value}\"");
else
await context.TextWriter.WriteAsync($"{value}");
}
private static bool RequiresDoubleQuotes(string value) {
return ReservedWords.Contains(value) || !NoQuotesRequiredRegex.IsMatch(value);
}
public bool Equals(DotIdentifier other) {
if (ReferenceEquals(null, other))
return false;
if (ReferenceEquals(this, other))
return true;
return Value == other.Value && IsHtml == other.IsHtml;
}
public override bool Equals(object obj) {
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
if (obj.GetType() != GetType())
return false;
return Equals((DotIdentifier)obj);
}
public override int GetHashCode() {
unchecked {
return ((Value != null ? Value.GetHashCode() : 0) * 397) ^ IsHtml.GetHashCode();
}
}
public static bool operator ==(DotIdentifier identifier1, DotIdentifier identifier2) {
if (identifier1 is null)
return identifier2 is null;
return identifier1.Equals(identifier2);
}
public static bool operator !=(DotIdentifier identifier1, DotIdentifier identifier2) => !(identifier1 == identifier2);
}
}