public bool TrySetAutoRotateOptions(XElement element, IAutoRotateRoot ancestor, IAutoRotateRoot target) { if (ancestor != null) { target.AutoRotate = ancestor.AutoRotate; target.AutoRotateFlip = ancestor.AutoRotateFlip; } var autorotate = element.Attribute("autorotate"); if (autorotate == null) { return(true); } var options = autorotate.Value.Split(','); if (options.Length == 0) { logger.LogError(autorotate, "Autorotate options cannot be empty"); return(false); } if (!Enum.TryParse <AutoRotateType>(options[0], true, out var autoRotateType)) { logger.LogError(autorotate, $"Unknown autorotation type '{options[0]}'"); return(false); } var flipState = FlipState.None; foreach (var option in options.Skip(1)) { if (string.Equals(option, "FlipPrimary", StringComparison.OrdinalIgnoreCase)) { flipState |= FlipState.Primary; } else if (string.Equals(option, "FlipSecondary", StringComparison.OrdinalIgnoreCase)) { flipState |= FlipState.Secondary; } else { logger.LogError(autorotate, $"Unknown option '{option}'"); return(false); } } target.AutoRotate = autoRotateType; target.AutoRotateFlip = flipState; return(true); }
public static bool GetAttribute(this XElement element, string name, IXmlLoadLogger logger, out XAttribute attr) { attr = element.Attribute(name); if (attr == null) { logger.LogError(element, $"Missing attribute '{name}' for <{element.Name.LocalName}> tag"); return(false); } return(true); }
private bool TryReadDouble(XAttribute attr, out ConditionalCollection <double> result) { if (!attr.Value.StartsWith("$")) { if (double.TryParse(attr.Value, out var plainValue)) { result = new ConditionalCollection <double> { new Conditional <double>(plainValue, ConditionTree.Empty) }; return(true); } result = null; return(false); } // Check variable exists var variableName = attr.Value.Substring(1); if (!definitionsSection.Definitions.TryGetValue(variableName, out var variableValues)) { logger.LogError(attr, $"Variable '{attr.Value}' does not exist"); result = null; return(false); } // Check all possible values are valid result = new ConditionalCollection <double>(); foreach (var variableValue in variableValues) { if (!double.TryParse(variableValue.Value, out var parsedValue)) { logger.LogError(attr, $"Value '{attr.Value}' for ${variableName} is not a valid number"); return(false); } result.Add(new Conditional <double>(parsedValue, variableValue.Conditions)); } return(true); }
public bool ReadRenderCommand(XElement element, ComponentDescription description, out IXmlRenderCommand command) { var textCommand = new XmlRenderTextWithDefinitions(); command = textCommand; if (!ReadTextLocation(element, textCommand)) { return(false); } if (!TryParseTextAlignment(element.Attribute("align"), out ConditionalCollection <TextAlignment> alignment)) { return(false); } textCommand.Alignment = alignment; var tRotation = "0"; if (description.Metadata.FormatVersion >= TextRotationMinFormatVersion && element.Attribute("rotate") != null) { tRotation = element.Attribute("rotate").Value; } var rotation = TextRotation.None; switch (tRotation) { case "0": rotation = TextRotation.None; break; case "90": rotation = TextRotation.Rotate90; break; case "180": rotation = TextRotation.Rotate180; break; case "270": rotation = TextRotation.Rotate270; break; default: logger.LogError(element.Attribute("rotate"), $"Invalid value for text rotation: '{tRotation}'"); break; } textCommand.Rotation = new ConditionalCollection <TextRotation> { new Conditional <TextRotation>(rotation, ConditionTree.Empty), }; double size = 11d; if (element.Attribute("size") != null) { if (element.Attribute("size").Value.ToLowerInvariant() == "large") { size = 12d; } } var textValueNode = element.Element(XmlLoader.ComponentNamespace + "value"); if (textValueNode != null) { foreach (var spanNode in textValueNode.Elements()) { string nodeValue = spanNode.Value; var formatting = TextRunFormatting.Normal; if (spanNode.Name.LocalName == "sub") { formatting = TextRunFormatting.Subscript; } else if (spanNode.Name.LocalName == "sup") { formatting = TextRunFormatting.Superscript; } else if (spanNode.Name.LocalName != "span") { logger.LogWarning(spanNode, $"Unknown node '{spanNode.Name}' will be treated as <span>"); } var textRun = new TextRun(nodeValue, formatting); if (!ValidateText(element, description, textRun.Text)) { return(false); } textCommand.TextRuns.Add(textRun); } } else if (element.GetAttribute("value", logger, out var value)) { var textRun = new TextRun(value.Value, new TextRunFormatting(TextRunFormattingType.Normal, size)); if (!ValidateText(value, description, textRun.Text)) { return(false); } textCommand.TextRuns.Add(textRun); } else { return(false); } return(true); }
protected IEnumerable <RenderDescription> ReadRenderDescriptions(ComponentDescription description, XElement renderNode) { IConditionTreeItem conditionCollection = ConditionTree.Empty; var conditionsAttribute = renderNode.Attribute("conditions"); if (conditionsAttribute != null) { if (!conditionParser.Parse(conditionsAttribute, description, logger, out conditionCollection)) { yield break; } } var declaredDefinitions = new List <string>(); var whenDefinedAttribute = renderNode.Attribute("whenDefined"); if (whenDefinedAttribute != null) { var usedVariables = whenDefinedAttribute.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); declaredDefinitions.AddRange(usedVariables.Select(x => x.Substring(1))); } var allUndefined = declaredDefinitions.Except(availableDefinitions).ToHashSet(); if (allUndefined.Any()) { foreach (var undefined in allUndefined) { logger.LogError(whenDefinedAttribute, $"Usage of undefined variable: ${undefined}"); } yield break; } var commands = new List <IRenderCommand>(); foreach (var renderCommandNode in renderNode.Descendants()) { string commandType = renderCommandNode.Name.LocalName; if (commandType == "line") { foreach (var renderLineDescription in ReadLineCommand(renderCommandNode, conditionCollection, declaredDefinitions)) { yield return(renderLineDescription); } } else if (commandType == "rect") { foreach (var renderRectDescription in ReadRectCommand(renderCommandNode, conditionCollection, declaredDefinitions)) { yield return(renderRectDescription); } } else if (commandType == "ellipse") { if (ReadEllipseCommand(description.Metadata.Version, renderCommandNode, out var command)) { commands.Add(command); } } else if (commandType == "text") { foreach (var renderTextDescription in ReadTextCommand(renderCommandNode, description, conditionCollection, declaredDefinitions)) { yield return(renderTextDescription); } } else if (commandType == "path") { if (ReadPathCommand(renderCommandNode, out var command)) { commands.Add(command); } } } yield return(new RenderDescription(conditionCollection, commands.ToArray())); }
public void ReadSection(XElement declarationElement, ComponentDescription description) { // Read meta nodes foreach (var metaElement in declarationElement.Elements(XmlLoader.ComponentNamespace + "meta")) { ReadMetaNode(metaElement, description); } // Check all required metadata was set if (string.IsNullOrEmpty(description.ComponentName)) { logger.LogError(declarationElement, "Component name is required."); } // Read properties List <ComponentProperty> properties = new List <ComponentProperty>(); foreach (var propertyElement in declarationElement.Elements(XmlLoader.ComponentNamespace + "property")) { ComponentProperty property = ScanPropertyNode(description, propertyElement); properties.Add(property); } description.Properties = properties.ToArray(); properties.Clear(); foreach (var propertyElement in declarationElement.Elements(XmlLoader.ComponentNamespace + "property")) { ComponentProperty property = ReadPropertyNode(description, propertyElement); properties.Add(property); } description.Properties = properties.ToArray(); // Read flags List <Conditional <FlagOptions> > flagOptions = new List <Conditional <FlagOptions> >(); foreach (var flagGroup in declarationElement.Elements(XmlLoader.ComponentNamespace + "flags")) { var flags = ReadFlagOptionNode(description, flagGroup); if (flags != null) { flagOptions.Add(flags); } } description.Flags = flagOptions.ToArray(); // Read configurations var componentConfigurations = new List <ComponentConfiguration>(); var configurations = declarationElement.Element(XmlLoader.ComponentNamespace + "configurations"); if (configurations != null) { foreach (var node in configurations.Elements(XmlLoader.ComponentNamespace + "configuration")) { ComponentConfiguration newConfiguration = ReadConfigurationNode(node, description); componentConfigurations.Add(newConfiguration); } } description.Metadata.Configurations.AddRange(componentConfigurations); }
public bool Load(Stream stream, IXmlLoadLogger logger, out ComponentDescription description) { description = new ComponentDescription(); if (stream is FileStream fs) { description.Source = new ComponentDescriptionSource(fs.Name); } var errorCheckingLogger = new ErrorCheckingLogger(logger); var sectionRegistry = new SectionRegistry(); try { var root = XElement.Load(stream, LoadOptions.SetLineInfo); ReadHeader(root, description); var featureSwitcher = new FeatureSwitcher(); // Read declaration var declaration = root.Element(ComponentNamespace + "declaration"); if (declaration == null) { logger.LogError(root, "Missing required element: 'declaration'"); return(false); } var declarationReader = container.Value.ResolveNamed <IXmlSectionReader>(declaration.Name.NamespaceName + ":" + declaration.Name.LocalName, new TypedParameter(typeof(IXmlLoadLogger), errorCheckingLogger), new TypedParameter(typeof(FeatureSwitcher), featureSwitcher)); declarationReader.ReadSection(declaration, description); var descriptionInstance = description; var scope = container.Value.BeginLifetimeScope(configure => { configure.RegisterInstance(errorCheckingLogger).As <IXmlLoadLogger>(); configure.RegisterInstance(sectionRegistry).As <ISectionRegistry>(); configure.RegisterInstance(descriptionInstance); configure.RegisterInstance(featureSwitcher).As <IFeatureSwitcher>(); foreach (var feature in features) { if (featureSwitcher.IsFeatureEnabled(feature.Key, out var featureSourceElement)) { logger.Log(LogLevel.Information, featureSourceElement, $"Feature enabled: {feature.Key}"); feature.Value(configure); } } }); try { // Read remaining elements foreach (var element in root.Elements().Except(new[] { declaration })) { var sectionReader = scope.ResolveOptionalNamed <IXmlSectionReader>(element.Name.NamespaceName + ":" + element.Name.LocalName); sectionReader?.ReadSection(element, description); } return(!errorCheckingLogger.HasErrors); } finally { scope.Dispose(); } } catch (Exception ex) { logger.Log(LogLevel.Error, new FileRange(1, 1, 1, 2), ex.Message, ex); return(false); } }
protected virtual bool ReadTextCommand(XElement element, ComponentDescription description, out RenderText command) { command = new RenderText(); ReadTextLocation(element, command); string tAlignment = "TopLeft"; if (element.Attribute("align") != null) { tAlignment = element.Attribute("align").Value; } if (!Enum.TryParse(tAlignment, out TextAlignment alignment)) { logger.LogError(element.Attribute("align"), $"Invalid value for text alignment: '{tAlignment}'"); } command.Alignment = alignment; double size = 11d; if (element.Attribute("size") != null) { if (element.Attribute("size").Value.ToLowerInvariant() == "large") { size = 12d; } } var textValueNode = element.Element(XmlLoader.ComponentNamespace + "value"); if (textValueNode != null) { foreach (var spanNode in textValueNode.Elements()) { string nodeValue = spanNode.Value; var formatting = TextRunFormatting.Normal; if (spanNode.Name.LocalName == "sub") { formatting = TextRunFormatting.Subscript; } else if (spanNode.Name.LocalName == "sup") { formatting = TextRunFormatting.Superscript; } else if (spanNode.Name.LocalName != "span") { logger.LogWarning(spanNode, $"Unknown node '{spanNode.Name}' will be treated as <span>"); } var textRun = new TextRun(nodeValue, formatting); if (!ValidateText(element, description, textRun.Text)) { return(false); } command.TextRuns.Add(textRun); } } else if (element.GetAttribute("value", logger, out var value)) { var textRun = new TextRun(value.Value, new TextRunFormatting(TextRunFormattingType.Normal, size)); if (!ValidateText(value, description, textRun.Text)) { return(false); } command.TextRuns.Add(textRun); } else { return(false); } return(true); }
public bool ReadRenderCommand(XElement element, ComponentDescription description, out IXmlRenderCommand command) { var textCommand = new XmlRenderText(); command = textCommand; if (!ReadTextLocation(element, textCommand)) { return(false); } string tAlignment = "TopLeft"; if (element.Attribute("align") != null) { tAlignment = element.Attribute("align").Value; } if (!Enum.TryParse(tAlignment, out TextAlignment alignment)) { logger.LogError(element.Attribute("align"), $"Invalid value for text alignment: '{tAlignment}'"); return(false); } textCommand.Alignment = alignment; var tRotation = "0"; if (description.Metadata.FormatVersion >= TextRotationMinFormatVersion && element.Attribute("rotate") != null) { tRotation = element.Attribute("rotate").Value; } var rotation = TextRotation.None; switch (tRotation) { case "0": rotation = TextRotation.None; break; case "90": rotation = TextRotation.Rotate90; break; case "180": rotation = TextRotation.Rotate180; break; case "270": rotation = TextRotation.Rotate270; break; default: logger.LogError(element.Attribute("rotate"), $"Invalid value for text rotation: '{tRotation}'"); break; } textCommand.Rotation = rotation; double size = 11d; if (element.Attribute("size") != null) { switch (element.Attribute("size").Value.ToLowerInvariant()) { case "large": size = 12.0; break; case "sm": case "small": size = 10.0; break; case "xs": size = 9.0; break; case "xxs": size = 8.0; break; default: logger.LogWarning(element.Attribute("size"), $"Invalid value for size attribute: '{element.Attribute("size").Value}'"); break; } } var textValueNode = element.Element(XmlLoader.ComponentNamespace + "value"); if (textValueNode != null) { foreach (var spanNode in textValueNode.Elements()) { string nodeValue = spanNode.Value; var formatting = new TextRunFormatting(TextRunFormattingType.Normal, size); if (spanNode.Name.LocalName == "sub") { formatting.FormattingType = TextRunFormattingType.Subscript; } else if (spanNode.Name.LocalName == "sup") { formatting.FormattingType = TextRunFormattingType.Superscript; } else if (spanNode.Name.LocalName != "span") { logger.LogWarning(spanNode, $"Unknown node '{spanNode.Name}' will be treated as <span>"); } var textRun = new TextRun(nodeValue, formatting); if (!ValidateText(element, description, textRun.Text)) { return(false); } textCommand.TextRuns.Add(textRun); } } else if (element.GetAttribute("value", logger, out var value)) { var textRun = new TextRun(value.Value, new TextRunFormatting(TextRunFormattingType.Normal, size)); if (!ValidateText(value, description, textRun.Text)) { return(false); } textCommand.TextRuns.Add(textRun); } else { return(false); } return(true); }