diff --git a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTBrowserConstants.xml b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTBrowserConstants.xml index edd5dc1..28c05ef 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTBrowserConstants.xml +++ b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTBrowserConstants.xml @@ -65,6 +65,9 @@ public class ARBAOTBrowserConstants public static const str DisplayStr = 'Display'; public static const str Action = 'Action'; public static const str Output = 'Output'; + public static const str Source = 'Source'; + public static const str ClassDeclaration = 'ClassDeclaration'; + public static const str Declaration = 'Declaration'; } ]]> diff --git a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTree.xml b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTree.xml index 4e2bc5a..6065512 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTree.xml +++ b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTree.xml @@ -16,6 +16,7 @@ using System.Linq.Enumerable; public class ARBAOTObjectTree { public static Microsoft.Dynamics.AX.Metadata.Providers.IMetadataProvider MetadataProvider; + public static Microsoft.Dynamics.AX.Metadata.Providers.IMetadataProvider BackupMetadataProvider; protected FormTreeControl treeControl; protected ARBAOTObjectType aotObjectType; protected boolean extensionsInline; @@ -29,10 +30,28 @@ public class ARBAOTObjectTree typenew + + + updateProvider + @@ -109,121 +128,127 @@ public class ARBAOTObjectTree /// /// The name of the AOT Object /// The AOT Object - public anytype getAOTObject(TreeNodeName _aotNodeName) + public anytype getAOTObject(TreeNodeName _aotNodeName, Microsoft.Dynamics.AX.Metadata.Providers.IMetadataProvider _metadataProvider = MetadataProvider) { anytype aotObject; switch (aotObjectType) { case ARBAOTObjectType::Table: - aotObject = MetadataProvider.Tables.Read(_aotNodeName); + aotObject = _metadataProvider.Tables.Read(_aotNodeName); break; case ARBAOTObjectType::View: - aotObject = MetadataProvider.Views.Read(_aotNodeName); + aotObject = _metadataProvider.Views.Read(_aotNodeName); break; case ARBAOTObjectType::DataEntity: - aotObject = MetadataProvider.DataEntityViews.Read(_aotNodeName); + aotObject = _metadataProvider.DataEntityViews.Read(_aotNodeName); break; case ARBAOTObjectType::BaseEnum: - aotObject = MetadataProvider.Enums.Read(_aotNodeName); + aotObject = _metadataProvider.Enums.Read(_aotNodeName); break; case ARBAOTObjectType::ExtendedDataType: - aotObject = MetadataProvider.Edts.Read(_aotNodeName); + aotObject = _metadataProvider.Edts.Read(_aotNodeName); break; case ARBAOTObjectType::Class: - aotObject = MetadataProvider.Classes.Read(_aotNodeName); + aotObject = _metadataProvider.Classes.Read(_aotNodeName); break; case ARBAOTObjectType::Form: - aotObject = MetadataProvider.Forms.Read(_aotNodeName); + aotObject = _metadataProvider.Forms.Read(_aotNodeName); break; case ARBAOTObjectType::Query: - aotObject = MetadataProvider.Queries.Read(_aotNodeName); + aotObject = _metadataProvider.Queries.Read(_aotNodeName); break; case ARBAOTObjectType::Map: - aotObject = MetadataProvider.Maps.Read(_aotNodeName); + aotObject = _metadataProvider.Maps.Read(_aotNodeName); break; case ARBAOTObjectType::Tile: - aotObject = MetadataProvider.Tiles.Read(_aotNodeName); + aotObject = _metadataProvider.Tiles.Read(_aotNodeName); break; case ARBAOTObjectType::Menu: - aotObject = MetadataProvider.Menus.Read(_aotNodeName); + aotObject = _metadataProvider.Menus.Read(_aotNodeName); break; case ARBAOTObjectType::TableCollection: - aotObject = MetadataProvider.TableCollections.Read(_aotNodeName); + aotObject = _metadataProvider.TableCollections.Read(_aotNodeName); break; case ARBAOTObjectType::CompositeDataEntity: - aotObject = MetadataProvider.CompositeDataEntityViews.Read(_aotNodeName); + aotObject = _metadataProvider.CompositeDataEntityViews.Read(_aotNodeName); break; case ARBAOTObjectType::MenuItemDisplay: - aotObject = MetadataProvider.MenuItemDisplays.Read(_aotNodeName); + aotObject = _metadataProvider.MenuItemDisplays.Read(_aotNodeName); break; case ARBAOTObjectType::MenuItemAction: - aotObject = MetadataProvider.MenuItemActions.Read(_aotNodeName); + aotObject = _metadataProvider.MenuItemActions.Read(_aotNodeName); break; case ARBAOTObjectType::MenuItemOutput: - aotObject = MetadataProvider.MenuItemOutputs.Read(_aotNodeName); + aotObject = _metadataProvider.MenuItemOutputs.Read(_aotNodeName); break; case ARBAOTObjectType::SecurityRole: - aotObject = MetadataProvider.SecurityRoles.Read(_aotNodeName); + aotObject = _metadataProvider.SecurityRoles.Read(_aotNodeName); break; case ARBAOTObjectType::SecurityDuty: - aotObject = MetadataProvider.SecurityDuties.Read(_aotNodeName); + aotObject = _metadataProvider.SecurityDuties.Read(_aotNodeName); break; case ARBAOTObjectType::SecurityPrivilege: - aotObject = MetadataProvider.SecurityPrivileges.Read(_aotNodeName); + aotObject = _metadataProvider.SecurityPrivileges.Read(_aotNodeName); break; case ARBAOTObjectType::AggregateDataEntity: - aotObject = MetadataProvider.AggregateDataEntities.Read(_aotNodeName); + aotObject = _metadataProvider.AggregateDataEntities.Read(_aotNodeName); break; case ARBAOTObjectType::WorkflowCategory: - aotObject = MetadataProvider.WorkflowCategories.Read(_aotNodeName); + aotObject = _metadataProvider.WorkflowCategories.Read(_aotNodeName); break; case ARBAOTObjectType::WorkflowApproval: - aotObject = MetadataProvider.WorkflowApprovals.Read(_aotNodeName); + aotObject = _metadataProvider.WorkflowApprovals.Read(_aotNodeName); break; case ARBAOTObjectType::WorkflowTask: - aotObject = MetadataProvider.WorkflowTasks.Read(_aotNodeName); + aotObject = _metadataProvider.WorkflowTasks.Read(_aotNodeName); break; case ARBAOTObjectType::WorkflowAutomatedTask: - aotObject = MetadataProvider.WorkflowAutomatedTasks.Read(_aotNodeName); + aotObject = _metadataProvider.WorkflowAutomatedTasks.Read(_aotNodeName); break; case ARBAOTObjectType::WorkflowType: - aotObject = MetadataProvider.WorkflowTemplates.Read(_aotNodeName); + aotObject = _metadataProvider.WorkflowTemplates.Read(_aotNodeName); break; case ARBAOTObjectType::WorkflowHierarchyAssignmentProvider: - aotObject = MetadataProvider.WorkflowHierarchyAssignmentProviders.Read(_aotNodeName); + aotObject = _metadataProvider.WorkflowHierarchyAssignmentProviders.Read(_aotNodeName); break; case ARBAOTObjectType::WorkflowParticipantAssignmentProvider: - aotObject = MetadataProvider.WorkflowParticipantAssignmentProviders.Read(_aotNodeName); + aotObject = _metadataProvider.WorkflowParticipantAssignmentProviders.Read(_aotNodeName); break; case ARBAOTObjectType::WorkflowQueueAssignmentProvider: - aotObject = MetadataProvider.WorkflowQueueAssignmentProviders.Read(_aotNodeName); + aotObject = _metadataProvider.WorkflowQueueAssignmentProviders.Read(_aotNodeName); break; case ARBAOTObjectType::WorkflowDueDateCalculationProvider: - aotObject = MetadataProvider.WorkflowDueDateCalculationProviders.Read(_aotNodeName); + aotObject = _metadataProvider.WorkflowDueDateCalculationProviders.Read(_aotNodeName); break; case ARBAOTObjectType::Resource: - aotObject = MetadataProvider.Resources.Read(_aotNodeName); + aotObject = _metadataProvider.Resources.Read(_aotNodeName); break; case ARBAOTObjectType::LicenseCode: - aotObject = MetadataProvider.LicenseCodes.Read(_aotNodeName); + aotObject = _metadataProvider.LicenseCodes.Read(_aotNodeName); break; case ARBAOTObjectType::ConfigKey: - aotObject = MetadataProvider.ConfigurationKeys.Read(_aotNodeName); + aotObject = _metadataProvider.ConfigurationKeys.Read(_aotNodeName); break; case ARBAOTObjectType::ConfigKeyGroup: - aotObject = MetadataProvider.ConfigurationKeyGroups.Read(_aotNodeName); + aotObject = _metadataProvider.ConfigurationKeyGroups.Read(_aotNodeName); break; case ARBAOTObjectType::Service: - aotObject = MetadataProvider.Services.Read(_aotNodeName); + aotObject = _metadataProvider.Services.Read(_aotNodeName); break; case ARBAOTObjectType::ServiceGroup: - aotObject = MetadataProvider.ServiceGroups.Read(_aotNodeName); + aotObject = _metadataProvider.ServiceGroups.Read(_aotNodeName); break; case ARBAOTObjectType::Report: - aotObject = MetadataProvider.Reports.Read(_aotNodeName); + aotObject = _metadataProvider.Reports.Read(_aotNodeName); break; } + if (aotObject == null + && _metadataProvider != BackupMetadataProvider) + { + aotObject = this.getAOTObject(_aotNodeName, BackupMetadataProvider); + } + return aotObject; } @@ -442,6 +467,11 @@ public class ARBAOTObjectTree /// The tree index of the new node public TreeItemIdx addTreeNode(anytype _object, TreeItemIdx _idx, int _formTreeAdd = FormTreeAdd::Sort, boolean _skipAddHeader = false, str _extensionName = '') { + if (_object == null) + { + return 0; + } + System.Type t = _object.GetType(); var props = t.GetProperties(); diff --git a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeDataEntity.xml b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeDataEntity.xml index 3831bce..46b23c5 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeDataEntity.xml +++ b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeDataEntity.xml @@ -80,6 +80,11 @@ class ARBAOTObjectTreeDataEntity extends ARBAOTObjectTree /// The tree index of the new node public TreeItemIdx addTreeNode(anytype _object, TreeItemIdx _idx, int _formTreeAdd = FormTreeAdd::Sort, boolean _skipAddHeader = false, str _extensionName = '') { + if (_object == null) + { + return 0; + } + str objectName = this.getObjectName(_object); boolean insertIntoMap = false; if (_object is AxQuerySimpleRootDataSource) diff --git a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeForm.xml b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeForm.xml index d412e04..918abf8 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeForm.xml +++ b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeForm.xml @@ -15,10 +15,42 @@ using CoreMetaModel = Microsoft.Dynamics.AX.Metadata.Core.MetaModel; class ARBAOTObjectTreeForm extends ARBAOTObjectTree { Map controlMap = new Map(Types::String, Types::Integer); + str selectedControlName; } ]]> + + parmSelectedControl + + + + update + + /// Update the object tree + /// + /// The name of the AOT object + public void update(TreeNodeName _aotNodeName) + { + super(_aotNodeName); + + if (selectedControlName && controlMap.exists(selectedControlName)) + { + treeControl.select(controlMap.lookup(selectedControlName)); + } + } + +]]> + addExtensionCollection The tree index of the new node public TreeItemIdx addTreeNode(anytype _object, TreeItemIdx _idx, int _formTreeAdd = FormTreeAdd::Sort, boolean _skipAddHeader = false, str _extensionName = '') { + if (_object == null) + { + return 0; + } + str objectName = this.getObjectName(_object); boolean insertIntoMap = false; if (_object is AxFormDesign) diff --git a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeMenu.xml b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeMenu.xml index 17a547c..d958422 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeMenu.xml +++ b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeMenu.xml @@ -77,6 +77,11 @@ class ARBAOTObjectTreeMenu extends ARBAOTObjectTree /// The tree index of the new node public TreeItemIdx addTreeNode(anytype _object, TreeItemIdx _idx, int _formTreeAdd = FormTreeAdd::Sort, boolean _skipAddHeader = false, str _extensionName = '') { + if (_object == null) + { + return 0; + } + str objectName = this.getObjectName(_object); boolean insertIntoMap = false; if (_object is AxMenu) diff --git a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeQuery.xml b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeQuery.xml index cc9d5a8..ccbecad 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeQuery.xml +++ b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeQuery.xml @@ -107,6 +107,11 @@ class ARBAOTObjectTreeQuery extends ARBAOTObjectTree /// The tree index of the new node public TreeItemIdx addTreeNode(anytype _object, TreeItemIdx _idx, int _formTreeAdd = FormTreeAdd::Sort, boolean _skipAddHeader = false, str _extensionName = '') { + if (_object == null) + { + return 0; + } + str objectName = this.getObjectName(_object); boolean insertIntoMap = false; if (_object is AxQuerySimpleRootDataSource) diff --git a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeView.xml b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeView.xml index d31bc61..ca0ef84 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeView.xml +++ b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBAOTObjectTreeView.xml @@ -113,6 +113,11 @@ class ARBAOTObjectTreeView extends ARBAOTObjectTree /// The tree index of the new node public TreeItemIdx addTreeNode(anytype _object, TreeItemIdx _idx, int _formTreeAdd = FormTreeAdd::Sort, boolean _skipAddHeader = false, str _extensionName = '') { + if (_object == null) + { + return 0; + } + str objectName = this.getObjectName(_object); boolean insertIntoMap = false; if (_object is AxQuerySimpleRootDataSource) diff --git a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBFormControlPersonalization_EventHandler.xml b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBFormControlPersonalization_EventHandler.xml index f633799..ce08f1f 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBFormControlPersonalization_EventHandler.xml +++ b/Metadata/AOTBrowser/AOTBrowser/AxClass/ARBFormControlPersonalization_EventHandler.xml @@ -29,6 +29,7 @@ class ARBFormControlPersonalization_EventHandler args.parmEnumType(enumNum(ARBAOTObjectType)); args.parmEnum(ARBAOTObjectType::Form); args.parm(sender.formRun().args().caller().name()); + args.parmObject(sender.formRun().args().parmObject()); args.caller(sender.formRun()); new MenuFunction(menuItemDisplayStr(ARBAOTBrowser), MenuItemType::Display).run(args); diff --git a/Metadata/AOTBrowser/AOTBrowser/AxForm/ARBAOTBrowser.xml b/Metadata/AOTBrowser/AOTBrowser/AxForm/ARBAOTBrowser.xml index b25372b..cae3c03 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxForm/ARBAOTBrowser.xml +++ b/Metadata/AOTBrowser/AOTBrowser/AxForm/ARBAOTBrowser.xml @@ -22,10 +22,12 @@ public class ARBAOTBrowser extends FormRun FormGridControl propertiesMatrixGrid; boolean extensionsInline; Map matrixControlMap; + boolean showCode; - #define.CurrentVersion(1) + #define.CurrentVersion(2) #localmacro.CurrentList - extensionsInline + extensionsInline, + showCode #endmacro } @@ -140,6 +142,7 @@ public class ARBAOTBrowser extends FormRun void getControlValuesForSysLastValues() { extensionsInline = ExtensionViewToggle.toggleValue(); + showCode = ViewCodeToggle.toggleValue(); } ]]> @@ -150,6 +153,7 @@ public class ARBAOTBrowser extends FormRun void setControlValuesFromSysLastValues() { ExtensionViewToggle.toggleValue(extensionsInline); + ViewCodeToggle.toggleValue(showCode); } ]]> @@ -183,7 +187,15 @@ public class ARBAOTBrowser extends FormRun tableBrowserEnabled = true; } - ARBAOTObjectTree::newFromAOTObject(ObjectTree, _objectType, ExtensionViewToggle.toggleValue()).update(_aotNodeName); + ARBAOTObjectTree aotObjectTree = ARBAOTObjectTree::newFromAOTObject(ObjectTree, _objectType, ExtensionViewToggle.toggleValue()); + if (element.args().parmObject() != null + && aotObjectTree is ARBAOTObjectTreeForm) + { + ARBAOTObjectTreeForm objectTreeForm = aotObjectTree as ARBAOTObjectTreeForm; + FormControl selectedControl = element.args().parmObject() as FormControl; + objectTreeForm.parmSelectedControl(selectedControl.name()); + } + aotObjectTree.update(_aotNodeName); DetailsTab.caption(_aotNodeName + ' - ' + enum2Str(_objectType)); ARBOpenTableBrowser.enabled(tableBrowserEnabled); } @@ -290,6 +302,8 @@ public class ARBAOTBrowser extends FormRun ARBAOTObjectPropertiesMatrix.insert(); } + CodeViewerGroup.visible(false); + CodeViewer.parmHtml(''); delete_from ARBAOTObjectProperties; delete_from ARBAOTObjectPropertiesMatrix; @@ -383,10 +397,18 @@ public class ARBAOTBrowser extends FormRun && prop.Name != ARBAOTBrowserConstants::Design && prop.Name != ARBAOTBrowserConstants::FormControl) { - ARBAOTObjectProperties.clear(); - ARBAOTObjectProperties.Name = prop.Name; - ARBAOTObjectProperties.Value = this.getPropertyValue(prop, object); - ARBAOTObjectProperties.insert(); + if (showCode && (prop.Name == ARBAOTBrowserConstants::Source || prop.Name == ARBAOTBrowserConstants::ClassDeclaration || prop.Name == ARBAOTBrowserConstants::Declaration)) + { + CodeViewer.parmHtml(Arbela.Dynamics.AX.Xpp.Support.HtmlFormatHelper::Format(this.getPropertyValue(prop, object))); + CodeViewerGroup.visible(true); + } + else + { + ARBAOTObjectProperties.clear(); + ARBAOTObjectProperties.Name = prop.Name; + ARBAOTObjectProperties.Value = this.getPropertyValue(prop, object); + ARBAOTObjectProperties.insert(); + } } } @@ -473,6 +495,16 @@ public class ARBAOTBrowser extends FormRun xSysLastValue::getLast(this); this.setControlValuesFromSysLastValues(); + Microsoft.Dynamics.ApplicationPlatform.Environment.IApplicationEnvironment applicationEnvironment = Microsoft.Dynamics.ApplicationPlatform.Environment.EnvironmentFactory::GetApplicationEnvironment(); + if (!applicationEnvironment.Common.IsOneboxEnvironment) + { + showCode = false; + ViewCodeToggle.toggleValue(showCode); + ViewCodeToggle.visible(false); + } + + ARBAOTObjectTree::updateProvider(showCode); + ResourceImage.imageLocation(SysImageLocation::AOTResource); ResourceImageGroup.colorScheme(FormColorScheme::RGB); ResourceImageGroup.backgroundColor(WinAPI::RGB2int(220,220,220)); @@ -640,6 +672,38 @@ public class ARBAOTBrowser extends FormRun } } +]]> + + + + + ViewCodeToggle + Button + + + clicked + + /// + /// + public void clicked() + { + super(); + + showCode = this.toggleValue(); + ARBAOTObjectTree::updateProvider(showCode); + + Args args = element.args(); + if (args.parmEnumType() == enumNum(ARBAOTObjectType) && args.parm() != null) + { + element.updateControls(args.parmEnum(), args.parm()); + } + else + { + element.updateControlsFromTable(); + } + } + ]]> @@ -1151,6 +1215,7 @@ public class ARBAOTBrowser extends FormRun No No + View @@ -1194,6 +1259,17 @@ public class ARBAOTBrowser extends FormRun @AOTBrowser:ViewExtensionsInline Check + + ViewCodeToggle + Yes + @AOTBrowser:ViewCodeHelp + Button + + @AOTBrowser:ViewCode + Check + General @@ -1394,35 +1470,47 @@ public class ARBAOTBrowser extends FormRun i:nil="true" /> - PropertiesGrid - Yes - SizeToContent - Grid - SizeToContent + i:type="AxFormGroupControl"> + PropertiesGridGroup + SizeToAvailable + Group + 500 - ACMAOTObjectProperties_Name - String - - Name - ARBAOTObjectProperties - - - ACMAOTObjectProperties_Value - String + i:type="AxFormGridControl"> + PropertiesGrid + Yes + Grid + 225 - Value + + + ACMAOTObjectProperties_Name + String + + Name + ARBAOTObjectProperties + + + ACMAOTObjectProperties_Value + String + + Value + ARBAOTObjectProperties + + ARBAOTObjectProperties + No + - ARBAOTObjectProperties @@ -1448,8 +1536,39 @@ public class ARBAOTBrowser extends FormRun @SYS58650 + + CodeViewerGroup + Yes + SizeToAvailable + Group + SizeToAvailable + + + + CodeViewer + Yes + SizeToAvailable + SizeToAvailable + + HtmlViewerControl + + + + htmlField + String + + + + + + Fill + No + - Fill + Auto + 2 None diff --git a/Metadata/AOTBrowser/AOTBrowser/AxLabelFile/LabelResources/en-US/AOTBrowser.en-US.label.txt b/Metadata/AOTBrowser/AOTBrowser/AxLabelFile/LabelResources/en-US/AOTBrowser.en-US.label.txt index 0a2dee7..fbbd785 100644 --- a/Metadata/AOTBrowser/AOTBrowser/AxLabelFile/LabelResources/en-US/AOTBrowser.en-US.label.txt +++ b/Metadata/AOTBrowser/AOTBrowser/AxLabelFile/LabelResources/en-US/AOTBrowser.en-US.label.txt @@ -92,3 +92,6 @@ AOTBrowserUser=AOT browser user ;ARB_AOTBrowser ViewExtensionsInline=Show extensions inline ;ARB_AOTBrowser +ViewCode=View source code + ;ARB_AOTBrowser +ViewCodeHelp=Toggles the ability to view the source code. (NOTE: Viewing metadata from 3rd parties provided by deployable package is not supported with this turned on) diff --git a/Metadata/AOTBrowser/AOTBrowser/AxReference/PygmentSharp.Core.xml b/Metadata/AOTBrowser/AOTBrowser/AxReference/PygmentSharp.Core.xml new file mode 100644 index 0000000..cc98bef --- /dev/null +++ b/Metadata/AOTBrowser/AOTBrowser/AxReference/PygmentSharp.Core.xml @@ -0,0 +1,7 @@ + + + PygmentSharp.Core + PygmentSharp.Core + PygmentSharp.Core, Version=0.2.0.0, Culture=neutral, PublicKeyToken=null + 0.2.0.0 + \ No newline at end of file diff --git a/Projects/AOTBrowser/AOTBrowser.sln b/Projects/AOTBrowser/AOTBrowser.sln index 1ce2d9a..e536187 100644 --- a/Projects/AOTBrowser/AOTBrowser.sln +++ b/Projects/AOTBrowser/AOTBrowser.sln @@ -7,6 +7,8 @@ Project("{FC65038C-1B2F-41E1-A629-BED71D161FFF}") = "AOTBrowser (ISV) [AOTBrowse EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Arbela.Dynamics.AX.Xpp.Support", "Arbela.Dynamics.AX.Xpp.Support\Arbela.Dynamics.AX.Xpp.Support.csproj", "{2F618DA7-59BC-4ABE-8F24-72D2D59F9AD4}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PygmentSharp.Core", "PygmentSharp.Core\PygmentSharp.Core.csproj", "{9EB63A83-0F9D-4C49-BC2A-95E37EB1CB15}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {2F618DA7-59BC-4ABE-8F24-72D2D59F9AD4}.Debug|Any CPU.Build.0 = Debug|Any CPU {2F618DA7-59BC-4ABE-8F24-72D2D59F9AD4}.Release|Any CPU.ActiveCfg = Release|Any CPU {2F618DA7-59BC-4ABE-8F24-72D2D59F9AD4}.Release|Any CPU.Build.0 = Release|Any CPU + {9EB63A83-0F9D-4C49-BC2A-95E37EB1CB15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9EB63A83-0F9D-4C49-BC2A-95E37EB1CB15}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9EB63A83-0F9D-4C49-BC2A-95E37EB1CB15}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9EB63A83-0F9D-4C49-BC2A-95E37EB1CB15}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Projects/AOTBrowser/AOTBrowser/AOTBrowser.rnrproj b/Projects/AOTBrowser/AOTBrowser/AOTBrowser.rnrproj index c1fec45..612cec6 100644 --- a/Projects/AOTBrowser/AOTBrowser/AOTBrowser.rnrproj +++ b/Projects/AOTBrowser/AOTBrowser/AOTBrowser.rnrproj @@ -222,6 +222,11 @@ {2f618da7-59bc-4abe-8f24-72d2d59f9ad4} True + + PygmentSharp.Core + {9eb63a83-0f9d-4c49-bc2a-95e37eb1cb15} + True + diff --git a/Projects/AOTBrowser/Arbela.Dynamics.AX.Xpp.Support/Arbela.Dynamics.AX.Xpp.Support.csproj b/Projects/AOTBrowser/Arbela.Dynamics.AX.Xpp.Support/Arbela.Dynamics.AX.Xpp.Support.csproj index 5151ebf..cdc1630 100644 --- a/Projects/AOTBrowser/Arbela.Dynamics.AX.Xpp.Support/Arbela.Dynamics.AX.Xpp.Support.csproj +++ b/Projects/AOTBrowser/Arbela.Dynamics.AX.Xpp.Support/Arbela.Dynamics.AX.Xpp.Support.csproj @@ -54,6 +54,7 @@ + @@ -62,9 +63,16 @@ + + + + {9eb63a83-0f9d-4c49-bc2a-95e37eb1cb15} + PygmentSharp.Core + + ", TokenTypes.Comment) + .Add(@"-", TokenTypes.Comment) + .Build(); + + rules["tag"] = builder.NewRuleSet() + .Add(@"\s+", TokenTypes.Text) + .ByGroups(@"([\w:-]+\s*)(=)(\s*)", "attr", + new TokenGroupProcessor(TokenTypes.Name.Attribute), + new TokenGroupProcessor(TokenTypes.Operator), + new TokenGroupProcessor(TokenTypes.Text)) + .Add(@"[\w:-]+", TokenTypes.Name.Attribute) + .ByGroups(@"(/?)(\s*)(>)", "#pop", + new TokenGroupProcessor(TokenTypes.Punctuation), + new TokenGroupProcessor(TokenTypes.Text), + new TokenGroupProcessor(TokenTypes.Punctuation)) + .Build(); + + rules["script-content"] = builder.NewRuleSet() + .ByGroups(@"(<)(\s*)(/)(\s*)(script)(\s*)(>)", "#pop", + new TokenGroupProcessor(TokenTypes.Punctuation), + new TokenGroupProcessor(TokenTypes.Text), + new TokenGroupProcessor(TokenTypes.Punctuation), + new TokenGroupProcessor(TokenTypes.Text), + new TokenGroupProcessor(TokenTypes.Name.Tag), + new TokenGroupProcessor(TokenTypes.Text), + new TokenGroupProcessor(TokenTypes.Punctuation)) + .Using(@".+?(?=<\s*/\s*script\s*>)") + .Build(); + + + rules["style-content"] = builder.NewRuleSet() + .ByGroups(@"(<)(\s*)(/)(\s*)(style)(\s*)(>)", "#pop", + new TokenGroupProcessor(TokenTypes.Punctuation), + new TokenGroupProcessor(TokenTypes.Text), + new TokenGroupProcessor(TokenTypes.Punctuation), + new TokenGroupProcessor(TokenTypes.Text), + new TokenGroupProcessor(TokenTypes.Name.Tag), + new TokenGroupProcessor(TokenTypes.Text), + new TokenGroupProcessor(TokenTypes.Punctuation)) + .Using(@".+?(?=<\s*/\s*style\s*>)") + .Build(); + + rules["attr"] = builder.NewRuleSet() + .Add(@""".*?""", TokenTypes.String, "#pop") + .Add(@"'.*?'", TokenTypes.String, "#pop") + .Add(@"[^\s>]+", TokenTypes.String, "#pop") + .Build(); + + return rules; + } + } +} diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Lexing/JavascriptLexer.cs b/Projects/AOTBrowser/PygmentSharp.Core/Lexing/JavascriptLexer.cs new file mode 100644 index 0000000..524b756 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Lexing/JavascriptLexer.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +using PygmentSharp.Core.Tokens; + +namespace PygmentSharp.Core.Lexing +{ + /// + /// A lexer for javascript + /// + [Lexer("Javascript", AlternateNames = "javascript,ecmascript,js,json")] + [LexerFileExtension("*.js")] + [LexerFileExtension("*.json")] + public class JavascriptLexer : RegexLexer + { + /// + /// Gets the state transition rules for the lexer. Each time a regex is matched, + /// the internal state machine can be bumped to a new state which determines what + /// regexes become valid again + /// + /// + protected override IDictionary GetStateRules() + { + var rules = new Dictionary(); + + string JS_IDENT_START = "(?:[$_" + RegexUtil.Combine("Lu", "Ll", "Lt", "Lm", "Lo", "Nl") + "]|\\\\u[a-fA-F0-9]{4})"; + string JS_IDENT_PART = "(?:[$" + RegexUtil.Combine("Lu", "Ll", "Lt", "Lm", "Lo", "Nl", "Mn", "Mc", "Nd", "Pc") + "\u200c\u200d]|\\\\u[a-fA-F0-9]{4})"; + string JS_IDENT = JS_IDENT_START + "(?:" + JS_IDENT_PART + ")*"; + + var builder = new StateRuleBuilder(); + builder.DefaultRegexOptions = RegexOptions.Multiline; + + rules["commentsandwhitespace"] = builder.NewRuleSet() + .Add(@"\s+", TokenTypes.Text) + .Add(@"", TokenTypes.Comment, "#pop") + .Add(@"-", TokenTypes.Comment) + .Build(); + + rules["tag"] = builder.NewRuleSet() + .Add(@"\s+", TokenTypes.Text) + .Add(@"[\w.:-]+\s*=", TokenTypes.Name.Attribute, "attr") + .Add(@"/?\s*>", TokenTypes.Name.Tag, "#pop") + .Build(); + + rules["attr"] = builder.NewRuleSet() + .Add(@"\s+", TokenTypes.Text) + .Add(@""".*?""", TokenTypes.String, "#pop") + .Add(@".*?'", TokenTypes.String, "#pop") + .Add(@"[^\s>]+", TokenTypes.String, "#pop") + .Build(); + + return rules; + } + } +} diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Properties/AssemblyInfo.cs b/Projects/AOTBrowser/PygmentSharp.Core/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a9a02d7 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PygmentSharp.Core")] +[assembly: AssemblyDescription("Port of Python's Pygments syntax highlighter")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PygmentSharp.Core")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9eb63a83-0f9d-4c49-bc2a-95e37eb1cb15")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.2.0")] +[assembly: AssemblyFileVersion("0.2.0")] +[assembly: InternalsVisibleTo("PygmentSharp.UnitTests")] diff --git a/Projects/AOTBrowser/PygmentSharp.Core/PygmentSharp.Core.csproj b/Projects/AOTBrowser/PygmentSharp.Core/PygmentSharp.Core.csproj new file mode 100644 index 0000000..ee40a8a --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/PygmentSharp.Core.csproj @@ -0,0 +1,154 @@ + + + + + Debug + AnyCPU + {9EB63A83-0F9D-4C49-BC2A-95E37EB1CB15} + Library + Properties + PygmentSharp.Core + PygmentSharp.Core + v4.5.2 + 512 + 0 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + False + False + True + False + False + False + True + True + True + True + True + True + True + True + False + True + False + True + False + False + False + False + True + False + True + True + True + False + False + + + + + + + + True + False + False + True + Full + %28none%29 + 0 + true + false + bin\Debug\PygmentSharp.Core.XML + + + 1591 + Rules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\PygmentSharp.Core.XML + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/PygmentSharp.Core.nuspec b/Projects/AOTBrowser/PygmentSharp.Core/PygmentSharp.Core.nuspec new file mode 100644 index 0000000..d49485c --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/PygmentSharp.Core.nuspec @@ -0,0 +1,22 @@ + + + + $id$ + $version$ + $title$ + Matt Burke + Matt Burke + https://raw.githubusercontent.com/akatakritos/PygmentSharp/master/LICENSE + https://github.com/akatakritos/PygmentSharp + false + $description$ + + - Fix exception parsing C# files + - Search for lexers case insensitively + - Removed dependency on Jetbrains.Annotations + - BREAKING CHANGE: Lexer locator API is now static method + + Copyright 2016 + + + \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Pygmentize.cs b/Projects/AOTBrowser/PygmentSharp.Core/Pygmentize.cs new file mode 100644 index 0000000..8651cfa --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Pygmentize.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +using PygmentSharp.Core.Formatting; +using PygmentSharp.Core.Lexing; + +namespace PygmentSharp.Core +{ + /// + /// Represents the result of a highlighting operation + /// + public class HighlightingResult + { + /// + /// Gets the output stream + /// + public Stream OutputStream { get; } + + /// + /// Gets the input text + /// + public string Input { get; } + + /// + /// Initializes a new instance of the class + /// + /// The input text + /// output stream + public HighlightingResult(string input, Stream output) + { + Input = input; + OutputStream = output; + } + + /// + /// Outputs the stream in an optional encoding. Default is UTF8 + /// + /// optional encoding. default is utf-8 + /// the formatted text + public string OutputAsString(Encoding encoding = null) + { + var outputEncoding = encoding ?? Encoding.UTF8; + var reader = new StreamReader(OutputStream, outputEncoding); + return reader.ReadToEnd(); + } + } + + /// + /// Fluen interface extension methods + /// + public static class FluentExtensions + { + //public static IPygmentizeBuilder WithLexerFor(this IPygmentizeBuilder builder, string name) + //{ + // throw new NotImplementedException(); + //} + + //public static IPygmentizeBuilder WithLexerForFile(this IPygmentizeBuilder builder, string filename) + //{ + // throw new NotImplementedException(); + //} + + /// + /// Defines the process to output to html with the default HTML options + /// + /// the builder + /// + public static IPygmentizeBuilder ToHtml(this IPygmentizeBuilder builder) + { + return builder.WithFormatter(new HtmlFormatter()); + } + } + + + /// + /// Defines an interface for building a highlighting operation + /// + public interface IPygmentizeBuilder + { + /// + /// Specifies the input encoding + /// + /// The encoding + /// + IPygmentizeBuilder WithInputEncoding(Encoding encoding); + + /// + /// Specifies the output encoding + /// + /// The encoding + /// + IPygmentizeBuilder WithOutputEncoding(Encoding encoding); + + /// + /// Specifies which lexer to use + /// + /// The lexer + /// + IPygmentizeBuilder WithLexer(Lexer lexer); + + /// + /// Specifies which formatter to use + /// + /// The lexer + /// + IPygmentizeBuilder WithFormatter(Formatter formatter); + + /// + /// Executes the highlighting process and returns a string + /// + /// + string AsString(); + + /// + /// Executes the process and writes to a file + /// + /// The filename to write + void ToFile(string filename); + } + + internal class PygmentizeContentBuilder : IPygmentizeBuilder + { + private readonly string _input; + public PygmentizeContentBuilder(string content) + { + _input = content; + } + + private Lexer _lexer = new PlainLexer(); + private Formatter _formatter = new NullFormatter(); + + public IPygmentizeBuilder WithInputEncoding(Encoding encoding) + { + throw new NotImplementedException(); + } + + public IPygmentizeBuilder WithOutputEncoding(Encoding encoding) + { + throw new NotImplementedException(); + } + + public IPygmentizeBuilder WithLexer(Lexer lexer) + { + _lexer = lexer; + return this; + } + + public IPygmentizeBuilder WithFormatter(Formatter formatter) + { + _formatter = formatter; + return this; + } + + public string AsString() + { + var tokens = _lexer.GetTokens(_input); + var memoryStream = new StringWriter(); + _formatter.Format(tokens, memoryStream); + + return memoryStream.ToString(); + } + + public void ToFile(string filename) + { + var formatter = FormatterLocator.FindByFilename(filename); + var tokens = _lexer.GetTokens(_input); + using (var output = new StreamWriter(File.OpenWrite(filename), Encoding.UTF8)) + { + formatter.Format(tokens, output); + } + } + } + + + /// + /// Main fluent interface starter for highlighting + /// + public static class Pygmentize + { + /// + /// Starts building a highlighting operation against string content + /// + /// The text to highlight + /// + public static IPygmentizeBuilder Content(string content) + { + return new PygmentizeContentBuilder(content); + } + + + /// + /// Starts building a highlighting operation against a file + /// + /// The file to hightlight + /// + public static IPygmentizeBuilder File(string filename) + { + var lexer = LexerLocator.FindByFilename(filename); + return new PygmentizeContentBuilder(System.IO.File.ReadAllText(filename)) + .WithLexer(lexer); + } + + } +} diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Rules.ruleset b/Projects/AOTBrowser/PygmentSharp.Core/Rules.ruleset new file mode 100644 index 0000000..a7cc69c --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Rules.ruleset @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Styles/DefaultStyle.cs b/Projects/AOTBrowser/PygmentSharp.Core/Styles/DefaultStyle.cs new file mode 100644 index 0000000..4230073 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Styles/DefaultStyle.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using PygmentSharp.Core.Tokens; + +namespace PygmentSharp.Core.Styles +{ + /// + /// The default style configuration + /// + public class DefaultStyle : Style + { + /// + /// Initializes a new instance of the class + /// + public DefaultStyle() : base(StyleMap) + { + BackgroundColor = "#f8f8f8"; + } + + private static IDictionary StyleMap => new Dictionary() + { + {TokenTypes.Whitespace, "#bbbbbb"}, + {TokenTypes.Comment, "italic #408080"}, + {TokenTypes.Comment.Preproc, "noitalic #BC7A00"}, + + //{ TokenTypes.Keyword, "bold #AA22FF" }, + {TokenTypes.Keyword, "bold #008000"}, + {TokenTypes.Keyword.Pseudo, "nobold"}, + {TokenTypes.Keyword.Type, "nobold #B00040"}, + {TokenTypes.Operator, "#666666"}, + {TokenTypes.Operator.Word, "bold #AA22FF"}, + {TokenTypes.Name.Builtin, "#008000"}, + {TokenTypes.Name.Function, "#0000FF"}, + {TokenTypes.Name.Class, "bold #0000FF"}, + {TokenTypes.Name.Namespace, "bold #0000FF"}, + {TokenTypes.Name.Exception, "bold #D2413A"}, + {TokenTypes.Name.Variable, "#19177C"}, + {TokenTypes.Name.Constant, "#880000"}, + {TokenTypes.Name.Label, "#A0A000"}, + {TokenTypes.Name.Entity, "bold #999999"}, + {TokenTypes.Name.Attribute, "#7D9029"}, + {TokenTypes.Name.Tag, "bold #008000"}, + {TokenTypes.Name.Decorator, "#AA22FF"}, + + {TokenTypes.String, "#BA2121"}, + {TokenTypes.String.Doc, "italic"}, + {TokenTypes.String.Interpol, "bold #BB6688"}, + {TokenTypes.String.Escape, "bold #BB6622"}, + {TokenTypes.String.Regex, "#BB6688"}, + //{ TokenTypes.String.Symbol, "#B8860B" }, + {TokenTypes.String.Symbol, "#19177C"}, + {TokenTypes.String.Other, "#008000"}, + {TokenTypes.Number, "#666666"}, + + {TokenTypes.Generic.Heading, "bold #000080"}, + {TokenTypes.Generic.Subheading, "bold #800080"}, + {TokenTypes.Generic.Deleted, "#A00000"}, + {TokenTypes.Generic.Inserted, "#00A000"}, + {TokenTypes.Generic.Error, "#FF0000"}, + {TokenTypes.Generic.Emph, "italic"}, + {TokenTypes.Generic.Strong, "bold"}, + {TokenTypes.Generic.Prompt, "bold #000080"}, + {TokenTypes.Generic.Output, "#888"}, + {TokenTypes.Generic.Traceback, "#04D"}, + + {TokenTypes.Error, "border:#FF0000"} + }; + } +} diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Styles/Style.cs b/Projects/AOTBrowser/PygmentSharp.Core/Styles/Style.cs new file mode 100644 index 0000000..e5b821b --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Styles/Style.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +using PygmentSharp.Core.Tokens; + +namespace PygmentSharp.Core.Styles +{ + /// + /// Represents a mapping of token types to text formatting + /// + public class Style : IEnumerable> + { + private readonly Dictionary _styles; + + /// + /// Initializes a new instance of the class + /// + public Style() + { + _styles = new Dictionary(); + } + + /// + /// Initializes a new instance of the class + /// + /// A mapping of token types to parseable styledata specifiers + public Style(IDictionary styles) + { + _styles = ParseStyles(styles); + } + + private static Dictionary ParseStyles(IDictionary styles) + { + foreach (var ttype in TokenTypeMap.Instance.Keys) + { + if (!styles.ContainsKey(ttype)) + styles[ttype] = ""; + } + + var output = new Dictionary(); + foreach (var style in styles) + { + foreach (var ttype in style.Key.Split()) + { + if (output.ContainsKey(ttype)) + continue; + + var styledefs = styles[ttype] ?? ""; + + var parentStyle = ttype.Parent == null ? null : output[ttype.Parent]; + + if (parentStyle == null) + parentStyle = new StyleData(); + else if (style.Value.Contains("noinherit") && ttype != TokenTypes.Token) + parentStyle = output[TokenTypes.Token]; //inherit from Token + + output[ttype] = StyleData.Parse(styledefs, parentStyle); + } + } + + return output; + } + + /// + /// Gets or sets the background color + /// + public string BackgroundColor { get; set; } = "#ffffff"; + + /// + /// Gets or sets the highlight color + /// + public string HighlightColor { get; set; } = "#ffffcc"; + + /// + /// Gets the style for a provided TokenType + /// + /// The type of token + /// + public StyleData StyleForToken(TokenType ttype) + { + return this[ttype]; + } + + /// + /// Gets the style for a token type + /// + /// The type of token + public StyleData this[TokenType ttype] => _styles.ContainsKey(ttype) ? _styles[ttype] : null; + + /// Returns an enumerator that iterates through the collection. + /// A that can be used to iterate through the collection. + /// 1 + public IEnumerator> GetEnumerator() + { + return _styles.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable) _styles).GetEnumerator(); + } + } +} diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Styles/StyleData.cs b/Projects/AOTBrowser/PygmentSharp.Core/Styles/StyleData.cs new file mode 100644 index 0000000..6058ee5 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Styles/StyleData.cs @@ -0,0 +1,257 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace PygmentSharp.Core.Styles +{ + /// + /// Represents formatting and color style + /// + public sealed class StyleData : IEquatable + { + /// + /// Gets the text color + /// + public string Color { get; } + + /// + /// Gets a value indicating if the text is bold + /// + public bool Bold { get; } + + /// + /// Gets a value indicating if the text is italic + /// + public bool Italic { get; } + + /// + /// Gets a value indicating if the text is underliend + /// + public bool Underline { get; } + + /// + /// gets the background color + /// + public string BackgroundColor { get; } + + /// + /// gets the border color + /// + public string BorderColor { get; } + + /// + /// gets a value indicating if the font should come from the Roman family + /// + public bool Roman { get; } + + /// + /// gets a value indicating if the font should be sans-serif + /// + public bool Sans { get; } + + /// + /// gets a value indicating if the font should be monospaced + /// + public bool Mono { get; } + + /// + /// Initializea a new instance of the class + /// + /// text color + /// text bolded? + /// text italics? + /// text udnerliend? + /// background color + /// border color + /// font roman? + /// font sans-serif? + /// font monospaced? + public StyleData(string color = null, + bool bold = false, + bool italic = false, + bool underline = false, + string bgColor = null, + string borderColor = null, + bool roman = false, + bool sans = false, + bool mono = false) + { + Color = color; + Bold = bold; + Italic = italic; + Underline = underline; + BackgroundColor = bgColor; + BorderColor = borderColor; + Roman = roman; + Sans = sans; + Mono = mono; + } + + /// + /// Parses a instance from a string + /// + /// the string to parse + /// + public static StyleData Parse(string text) => Parse(text, new StyleData()); + + /// + /// Parses a instance from a string, merging with a default. Unset properties in the parse string will + /// be copied from the base style + /// + /// The string to parse + /// The base style to merge with + /// + public static StyleData Parse(string text, StyleData merged) + { + string color = merged.Color, bgColor = merged.BackgroundColor, borderColor = merged.BorderColor; + bool bold = merged.Bold, italic = merged.Italic, underline = merged.Underline, roman = merged.Roman, sans = merged.Sans, mono = merged.Mono; + + foreach (var styledef in text.Split(new [] {' '}, StringSplitOptions.RemoveEmptyEntries)) + { + if (styledef == "noinherit") + { + // noop + } + else if (styledef == "bold") + bold = true; + else if (styledef == "nobold") + bold = false; + else if (styledef == "italic") + italic = true; + else if (styledef == "noitalic") + italic = false; + else if (styledef == "underline") + underline = true; + else if (styledef.StartsWith("bg:", StringComparison.Ordinal)) + bgColor = ColorFormat(styledef.Substring(3)); + else if (styledef.StartsWith("border:", StringComparison.Ordinal)) + borderColor = ColorFormat(styledef.Substring(7)); + else if (styledef == "roman") + roman = true; + else if (styledef == "sans") + sans = true; + else if (styledef == "mono") + mono = true; + else + color = ColorFormat(styledef); + } + + return new StyleData(color, bold, italic, underline, bgColor, borderColor, roman, sans, mono); + } + + /// Returns a string that represents the current object. Basically CSS style + /// A string that represents the current object. + /// 2 + public override string ToString() + { + var color = string.IsNullOrEmpty(Color) ? null : $"color:#{Color};"; + var fontWeight = Bold ? "font-weight:bold;" : null; + var fontStyle = Italic ? "font-style:italic;" : null; + var textDecoration = Underline ? "text-decoration:underline;" : null; + var borderColor = string.IsNullOrEmpty(BorderColor) ? null : $"border-color:#{BorderColor};"; + var backgroundColor = string.IsNullOrEmpty(BackgroundColor) ? null : $"background-color:#{BackgroundColor};"; + var fontFamily = new StringBuilder(); + if (Roman || Sans || Mono) + { + fontFamily.Append("font-family:"); + if (Roman) fontFamily.Append(" roman"); + if (Sans) fontFamily.Append(" sans"); + if (Mono) fontFamily.Append(" mono"); + fontFamily.Append(";"); + } + + return string.Concat(color, backgroundColor, borderColor, fontFamily, fontWeight, fontStyle, textDecoration); + } + + private static string ColorFormat(string color) + { + if (color.StartsWith("#", StringComparison.InvariantCulture)) + { + var colorPart = color.Substring(1); + if (colorPart.Length == 6) + return colorPart; + + if (colorPart.Length == 3) + { + var r = colorPart[0]; + var g = colorPart[1]; + var b = colorPart[2]; + return string.Concat(r, r, g, g, b, b); + } + } + else if (color == "") + return ""; + + throw new FormatException($"Could not understand color '{color}'."); + } + + #region R# Equality + + /// Indicates whether the current object is equal to another object of the same type. + /// true if the current object is equal to the parameter; otherwise, false. + /// An object to compare with this object. + public bool Equals(StyleData other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return string.Equals(Color, other.Color) && Bold == other.Bold && Italic == other.Italic && Underline == other.Underline && string.Equals(BackgroundColor, other.BackgroundColor) && string.Equals(BorderColor, other.BorderColor) && Roman == other.Roman && Sans == other.Sans && Mono == other.Mono; + } + + /// Determines whether the specified object is equal to the current object. + /// true if the specified object is equal to the current object; otherwise, false. + /// The object to compare with the current object. + /// 2 + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((StyleData) obj); + } + + /// Serves as the default hash function. + /// A hash code for the current object. + /// 2 + public override int GetHashCode() + { + unchecked + { + var hashCode = (Color != null ? Color.GetHashCode() : 0); + hashCode = (hashCode*397) ^ Bold.GetHashCode(); + hashCode = (hashCode*397) ^ Italic.GetHashCode(); + hashCode = (hashCode*397) ^ Underline.GetHashCode(); + hashCode = (hashCode*397) ^ (BackgroundColor != null ? BackgroundColor.GetHashCode() : 0); + hashCode = (hashCode*397) ^ (BorderColor != null ? BorderColor.GetHashCode() : 0); + hashCode = (hashCode*397) ^ Roman.GetHashCode(); + hashCode = (hashCode*397) ^ Sans.GetHashCode(); + hashCode = (hashCode*397) ^ Mono.GetHashCode(); + return hashCode; + } + } + + /// + /// Compares two StyleDatas for equality + /// + /// The LHS styledata + /// The RHS styledata + /// + public static bool operator ==(StyleData left, StyleData right) + { + return Equals(left, right); + } + + /// + /// Compares two StyleDatas for inequality + /// + /// The LHS styledata + /// The RHS styledata + /// + public static bool operator !=(StyleData left, StyleData right) + { + return !Equals(left, right); + } + + #endregion + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Styles/TokenTypeMap.cs b/Projects/AOTBrowser/PygmentSharp.Core/Styles/TokenTypeMap.cs new file mode 100644 index 0000000..7723f20 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Styles/TokenTypeMap.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using PygmentSharp.Core.Tokens; + +namespace PygmentSharp.Core.Styles +{ + internal class TokenTypeMap + { + private readonly IDictionary _map; + + public TokenTypeMap() : this(new Dictionary()) + { + } + + public TokenTypeMap(IDictionary map) + { + _map = map; + } + + public string this[TokenType type] => _map.ContainsKey(type) ? _map[type] : null; + + public bool Contains(TokenType type) => _map.ContainsKey(type); + + static TokenTypeMap() + { + Instance = new TokenTypeMap(); + Instance._map[TokenTypes.Token] = ""; + Instance._map[TokenTypes.Text] = ""; + Instance._map[TokenTypes.Whitespace] = "w"; + Instance._map[TokenTypes.Escape] = "esc"; + Instance._map[TokenTypes.Error] = "err"; + Instance._map[TokenTypes.Other] = "x"; + Instance._map[TokenTypes.Keyword] = "k"; + Instance._map[TokenTypes.Keyword.Constant] = "kc"; + Instance._map[TokenTypes.Keyword.Declaration] = "kd"; + Instance._map[TokenTypes.Keyword.Namespace] = "kn"; + Instance._map[TokenTypes.Keyword.Pseudo] = "kp"; + Instance._map[TokenTypes.Keyword.Reserved] = "kr"; + Instance._map[TokenTypes.Keyword.Type] = "kt"; + Instance._map[TokenTypes.Name] = "n"; + Instance._map[TokenTypes.Name.Attribute] = "na"; + Instance._map[TokenTypes.Name.Builtin] = "nb"; + Instance._map[TokenTypes.Name.Builtin.Pseudo] = "bp"; + Instance._map[TokenTypes.Name.Class] = "nc"; + Instance._map[TokenTypes.Name.Constant] = "no"; + Instance._map[TokenTypes.Name.Decorator] = "nd"; + Instance._map[TokenTypes.Name.Entity] = "ni"; + Instance._map[TokenTypes.Name.Exception] = "ne"; + Instance._map[TokenTypes.Name.Function] = "nf"; + Instance._map[TokenTypes.Name.Property] = "py"; + Instance._map[TokenTypes.Name.Label] = "nl"; + Instance._map[TokenTypes.Name.Namespace] = "nn"; + Instance._map[TokenTypes.Name.Other] = "nx"; + Instance._map[TokenTypes.Name.Tag] = "nt"; + Instance._map[TokenTypes.Name.Variable] = "nv"; + Instance._map[TokenTypes.Name.Variable.Class] = "vc"; + Instance._map[TokenTypes.Name.Variable.Global] = "vg"; + Instance._map[TokenTypes.Name.Variable.Instance] = "vi"; + Instance._map[TokenTypes.Literal] = "l"; + Instance._map[TokenTypes.Literal.Date] = "ld"; + Instance._map[TokenTypes.String] = "s"; + Instance._map[TokenTypes.String.Backtick] = "sb"; + Instance._map[TokenTypes.String.Char] = "sc"; + Instance._map[TokenTypes.String.Doc] = "sd"; + Instance._map[TokenTypes.String.Double] = "s2"; + Instance._map[TokenTypes.String.Escape] = "se"; + Instance._map[TokenTypes.String.Heredoc] = "sh"; + Instance._map[TokenTypes.String.Interpol] = "si"; + Instance._map[TokenTypes.String.Other] = "sx"; + Instance._map[TokenTypes.String.Regex] = "sr"; + Instance._map[TokenTypes.String.Single] = "s1"; + Instance._map[TokenTypes.String.Symbol] = "ss"; + Instance._map[TokenTypes.Number] = "m"; + Instance._map[TokenTypes.Number.Bin] = "mb"; + Instance._map[TokenTypes.Number.Float] = "mf"; + Instance._map[TokenTypes.Number.Hex] = "mh"; + Instance._map[TokenTypes.Number.Integer] = "mi"; + Instance._map[TokenTypes.Number.Integer.Long] = "il"; + Instance._map[TokenTypes.Number.Oct] = "mo"; + Instance._map[TokenTypes.Operator] = "o"; + Instance._map[TokenTypes.Operator.Word] = "ow"; + Instance._map[TokenTypes.Punctuation] = "p"; + Instance._map[TokenTypes.Comment] = "c"; + Instance._map[TokenTypes.Comment.Hashbang] = "ch"; + Instance._map[TokenTypes.Comment.Multiline] = "cm"; + Instance._map[TokenTypes.Comment.Preproc] = "cp"; + Instance._map[TokenTypes.Comment.PreprocFile] = "cpf"; + Instance._map[TokenTypes.Comment.Single] = "c1"; + Instance._map[TokenTypes.Comment.Special] = "cs"; + Instance._map[TokenTypes.Generic] = "g"; + Instance._map[TokenTypes.Generic.Deleted] = "gd"; + Instance._map[TokenTypes.Generic.Emph] = "ge"; + Instance._map[TokenTypes.Generic.Error] = "gr"; + Instance._map[TokenTypes.Generic.Heading] = "gh"; + Instance._map[TokenTypes.Generic.Inserted] = "gi"; + Instance._map[TokenTypes.Generic.Output] = "go"; + Instance._map[TokenTypes.Generic.Prompt] = "gp"; + Instance._map[TokenTypes.Generic.Strong] = "gs"; + Instance._map[TokenTypes.Generic.Subheading] = "gu"; + Instance._map[TokenTypes.Generic.Traceback] = "gt"; + + } + + public static TokenTypeMap Instance { get; } + public IEnumerable Keys => _map.Keys; + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/CommentTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/CommentTokenType.cs new file mode 100644 index 0000000..68835c8 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/CommentTokenType.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of comment tokesn + /// + public class CommentTokenType : TokenType + { + internal CommentTokenType(TokenType parent) : base(parent, "Comment") + { + Hashbang = CreateChild("Hashbang"); + Multiline = CreateChild("Multiline"); + Preproc = CreateChild("Preproc"); + PreprocFile = CreateChild("PreprocFile"); + Single = CreateChild("Single"); + Special = CreateChild("Special"); + } + + /// + /// Gets a token for representing a hashbang line + /// + public TokenType Hashbang { get; } + + /// + /// Gets a token for representing a multiline comment + /// + public TokenType Multiline { get; } + + /// + /// Gets a token for representing a preprocessor commenet + /// + public TokenType Preproc { get; } + + /// + /// Gets a token for representing a prepreocessor file + /// + public TokenType PreprocFile { get; } + + /// + /// Gets a token for representing a single line comment + /// + public TokenType Single { get; } + + /// + /// Gets a token for representing a special comment + /// + public TokenType Special { get; } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/GenericTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/GenericTokenType.cs new file mode 100644 index 0000000..ae20b34 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/GenericTokenType.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of generic tokens + /// + public class GenericTokenType : TokenType + { + internal GenericTokenType(TokenType parent) : base(parent, "Generic") + { + Deleted = CreateChild("Deleted"); + Emph = CreateChild("Emph"); + Error = CreateChild("Error"); + Heading = CreateChild("Heading"); + Inserted = CreateChild("Inserted"); + Output = CreateChild("Output"); + Prompt = CreateChild(nameof(Prompt)); + Strong = CreateChild(nameof(Strong)); + Subheading = CreateChild(nameof(Subheading)); + Traceback = CreateChild(nameof(Traceback)); + + } + + + /// + /// Gets a token for representing deleted text + /// + public TokenType Deleted { get; } + + /// + /// Gets a token for representing emphasized text + /// + public TokenType Emph { get; } + + /// + /// Gets a token for representing error text + /// + public TokenType Error { get; } + + /// + /// Gets a token for representing heading text + /// + public TokenType Heading { get; } + + /// + /// Gets a token for representing inserted text + /// + public TokenType Inserted { get; } + + /// + /// Gets a token for representing output text + /// + public TokenType Output { get; } + + /// + /// Gets a token for representing prompt text + /// + public TokenType Prompt { get; } + + /// + /// Gets a token for representing strong text + /// + public TokenType Strong { get; } + + /// + /// Gets a token for representing subheading text + /// + public TokenType Subheading { get; } + + /// + /// Gets a token for representing traceback text + /// + public TokenType Traceback { get; } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/IntegerTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/IntegerTokenType.cs new file mode 100644 index 0000000..5f2129f --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/IntegerTokenType.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of integer tokens + /// + public class IntegerTokenType : TokenType + { + internal IntegerTokenType(TokenType parent) : base(parent, "Integer") + { + Long = CreateChild("Long"); + } + + /// + /// Gets a token for representing a long integer + /// + public TokenType Long { get; } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/KeywordTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/KeywordTokenType.cs new file mode 100644 index 0000000..94940ff --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/KeywordTokenType.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of keyword tokens + /// + public class KeywordTokenType : TokenType + { + internal KeywordTokenType(TokenType parent) : base(parent, "Keyword") + { + Constant = CreateChild("Constant"); + Declaration = CreateChild("Declaration"); + Namespace = CreateChild("Namespace"); + Pseudo = CreateChild("Pseudo"); + Reserved = CreateChild("Reserved"); + Type = CreateChild("Type"); + } + + /// + /// Gets a token for representing a constant keyword + /// + public TokenType Constant { get; } + + /// + /// Gets a token for representing a declaration keyword + /// + public TokenType Declaration { get; } + + /// + /// Gets a token for representing a namespace keyword + /// + public TokenType Namespace { get; } + + /// + /// Gets a token for representing a pseudo keyword + /// + public TokenType Pseudo { get; } + + /// + /// Gets a token for representing a reserved word + /// + public TokenType Reserved { get; } + + /// + /// Gets a token for representing a type keyword + /// + public TokenType Type { get; } + + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/LiteralTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/LiteralTokenType.cs new file mode 100644 index 0000000..6017ae3 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/LiteralTokenType.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of literal tokens + /// + public class LiteralTokenType : TokenType + { + internal LiteralTokenType(TokenType parent) : base(parent, "Literal") + { + Date = CreateChild("Date"); + String = AddChild(new StringTokenType(this)); + Number = AddChild(new NumberTokenType(this)); + } + + /// + /// Gets a token for representing a date literal + /// + public TokenType Date { get; } + + /// + /// Gets a token for representing a string literal + /// + public StringTokenType String { get; } + + /// + /// Gets a token for representing a number literal + /// + public NumberTokenType Number { get; } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NameBuiltinTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NameBuiltinTokenType.cs new file mode 100644 index 0000000..920f456 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NameBuiltinTokenType.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of builtin name tokens + /// + public class NameBuiltinTokenType : TokenType + { + internal NameBuiltinTokenType(TokenType parent) : base(parent, "Builtin") + { + Pseudo = CreateChild("Pseudo"); + } + + + /// + /// Gets a token for representing a pseudo name token + /// + public TokenType Pseudo { get; } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NameTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NameTokenType.cs new file mode 100644 index 0000000..3593e08 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NameTokenType.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of name tokens + /// + public class NameTokenType : TokenType + { + internal NameTokenType(TokenType parent) : base(parent, "Name") + { + Attribute = CreateChild("Attribute"); + Builtin = AddChild(new NameBuiltinTokenType(this)); + Class = CreateChild("Class"); + Constant = CreateChild("Constant"); + Decorator = CreateChild("Decorator"); + Entity = CreateChild("Entity"); + Exception = CreateChild("Exception"); + Function = CreateChild("Function"); + Property = CreateChild("Property"); + Label = CreateChild("Label"); + Namespace = CreateChild("Namespace"); + Other = CreateChild("Other"); + Tag = CreateChild("Tag"); + Variable = new NameVariableTokenType(this); + } + + + /// + /// Gets a token for representing the name of an attribute + /// + public TokenType Attribute { get; } + + /// + /// Gets a token for representing the name of a builtin name + /// + public NameBuiltinTokenType Builtin { get; } + + /// + /// Gets a token for representing the name of a class + /// + public TokenType Class { get; } + + /// + /// Gets a token for representing the name of a constant + /// + public TokenType Constant { get; } + + /// + /// Gets a token for representing the name of a decorator + /// + public TokenType Decorator { get; } + + /// + /// Gets a token for representing the name of an entity + /// + public TokenType Entity { get; } + + /// + /// Gets a token for representing the name of an exception + /// + public TokenType Exception { get; } + + /// + /// Gets a token for representing the name of a function + /// + public TokenType Function { get; } + + /// + /// Gets a token for representing the name of a property + /// + public TokenType Property { get; } + + /// + /// Gets a token for representing the name of a label + /// + public TokenType Label { get; } + + /// + /// Gets a token for representing the name of a namespace + /// + public TokenType Namespace { get; } + + /// + /// Gets a token for representing an unknown type of name + /// + public TokenType Other { get; } + + /// + /// Gets a token for representing the name of a tag + /// + public TokenType Tag { get; } + + /// + /// Gets a token for representing the name of a variable + /// + public NameVariableTokenType Variable { get; } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NameVariableTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NameVariableTokenType.cs new file mode 100644 index 0000000..5a213ac --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NameVariableTokenType.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds diffenent types of variable scopes + /// + public class NameVariableTokenType : TokenType + { + internal NameVariableTokenType(TokenType parent) : base(parent, "Variable") + { + Class = CreateChild("Class"); + Global = CreateChild("Global"); + Instance = CreateChild("Instance"); + } + + /// + /// Gets a token for representing the name of a class variable + /// + public TokenType Class { get; } + + /// + /// Gets a token for representing the name of a global variable + /// + public TokenType Global { get; } + + /// + /// Gets a token for representing the name of an instance variable + /// + public TokenType Instance { get; } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NumberTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NumberTokenType.cs new file mode 100644 index 0000000..3477ac5 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/NumberTokenType.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of number tokens + /// + public class NumberTokenType : TokenType + { + internal NumberTokenType(TokenType parent) : base(parent, "Number") + { + + Bin = CreateChild("Bin"); + Float = CreateChild("Float"); + Hex = CreateChild("Hex"); + Integer = AddChild(new IntegerTokenType(this)); + Oct = CreateChild("Oct"); + } + + + /// + /// Gets a token for representing a binary number + /// + public TokenType Bin { get; } + + /// + /// Gets a token for representing a floating point number + /// + public TokenType Float { get; } + + /// + /// Gets a token for representing a hexadecimal number + /// + public TokenType Hex { get; } + + /// + /// Gets a token for representing an integer number + /// + public IntegerTokenType Integer { get; } + + /// + /// Gets a token for representing an octal number + /// + public TokenType Oct { get; } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/OperatorTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/OperatorTokenType.cs new file mode 100644 index 0000000..45e6ffe --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/OperatorTokenType.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of operator tokens + /// + public class OperatorTokenType : TokenType + { + internal OperatorTokenType(TokenType parent) : base(parent, "Operator") + { + Word = CreateChild("Word"); + } + + /// + /// Gets a token for representing word operator + /// + public TokenType Word { get; } + + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/StringTokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/StringTokenType.cs new file mode 100644 index 0000000..a95625d --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/StringTokenType.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Holds different types of string tokens + /// + public class StringTokenType : TokenType + { + internal StringTokenType(TokenType parent) : base(parent, "String") + { + Backtick = CreateChild("Backtick"); + Char = CreateChild("Char"); + Doc = CreateChild("Doc"); + Double = CreateChild("Double"); + Escape = CreateChild("Escape"); + Heredoc = CreateChild("Heredoc"); + Interpol = CreateChild("Interpol"); + Other = CreateChild("Other"); + Regex = CreateChild("Regex"); + Single = CreateChild("Single"); + Symbol = CreateChild("Symbol"); + + } + + + /// + /// Gets a token for representing a backtick string + /// + public TokenType Backtick { get; } + + /// + /// Gets a token for representing a character + /// + public TokenType Char { get; } + + /// + /// Gets a token for representing a documentation string + /// + public TokenType Doc { get; } + + /// + /// Gets a token for representing a double quoted string + /// + public TokenType Double { get; } + + /// + /// Gets a token for representing a single quoted string + /// + public TokenType Escape { get; } + + /// + /// Gets a token for representing a heredoc string + /// + public TokenType Heredoc { get; } + + /// + /// Gets a token for representing an interpolated string + /// + public TokenType Interpol { get; } + + /// + /// Gets a token for representing some other string + /// + public TokenType Other { get; } + + /// + /// Gets a token for representing a regular expression string + /// + public TokenType Regex { get; } + + /// + /// Gets a token for representing a single quote string + /// + public TokenType Single { get; } + + /// + /// Gets a token for representing a symbol + /// + public TokenType Symbol { get; } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/Token.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/Token.cs new file mode 100644 index 0000000..f323956 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/Token.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Represents a token from the lexing file. A Token is a type, value, and position + /// + /// + /// Lexers will emit a sequence of Tokens, each with a given type. Formatters will consume + /// Tokens and turn them into highlighted text in whatever format they support + /// + public struct Token : IEquatable + { + /// + /// The 0 based index into the string being lexed + /// + public int Index { get; } + + /// + /// The type of this token (Comment, Text, Keyword, etc) + /// + public TokenType Type { get; } + + /// + /// The string value of the token + /// + public string Value { get; } + + /// + /// Initializes a new Token at index 0 + /// + /// The type of the Token + /// The value of the Token + public Token(TokenType type, string value) : this(0, type, value) + { + } + + /// + /// Initializes a new Token at a provided index + /// + /// The index into the string being lexer + /// The type of the Token + /// The value of the Token + public Token(int index, TokenType type, string value) + { + Index = index; + Value = value; + Type = type; + } + + /// + /// Creates a new token with an index adjusted by + /// + /// This is useful for nested lexers that pass the inner lexer a substring of the full file, and nead to adjust the posititions accordingly + /// The number of characters to offset + /// A new token offset by the specified number of characters + public Token Offset(int indexOffset) + { + return new Token(Index + indexOffset, Type, Value); + } + + /// + /// Gets a string representation of the Token + /// + /// + public override string ToString() => $"{Index}: \"{Value}\" ({Type})"; + + #region R# Equality Members + + /// Indicates whether the current object is equal to another object of the same type. + /// true if the current object is equal to the parameter; otherwise, false. + /// An object to compare with this object. + public bool Equals(Token other) + { + return Index == other.Index && Type.Equals(other.Type) && string.Equals(Value, other.Value); + } + + /// Indicates whether this instance and a specified object are equal. + /// true if and this instance are the same type and represent the same value; otherwise, false. + /// The object to compare with the current instance. + /// 2 + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is Token && Equals((Token) obj); + } + + /// Returns the hash code for this instance. + /// A 32-bit signed integer that is the hash code for this instance. + /// 2 + public override int GetHashCode() + { + unchecked + { + var hashCode = Index; + hashCode = (hashCode*397) ^ Type.GetHashCode(); + hashCode = (hashCode*397) ^ Value.GetHashCode(); + return hashCode; + } + } + + /// + /// compares two tokens for equality + /// + /// The LHS token + /// The RHS token + /// + public static bool operator ==(Token left, Token right) + { + return left.Equals(right); + } + + /// + /// Compares two tokens for inequality + /// + /// The LHS token + /// The RHS token + /// + public static bool operator !=(Token left, Token right) + { + return !left.Equals(right); + } + + #endregion + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/TokenType.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/TokenType.cs new file mode 100644 index 0000000..933b4a2 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/TokenType.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// Represents a nested type for a + /// + /// + /// Token Types are nested. For example, a Comment will have nested types Comment.Multiline, + /// Comment.Single, or Comment.Preproc. Lexers and formatters have a choice on how + /// specific they want to get. If a formatter doesn't want to support different styles for each of + /// those comment types, it can just implement highlighting for Comment and all the child types will + /// fall in line. + /// + public class TokenType + { + /// + /// Gets the parent type + /// + public TokenType Parent { get; } + + /// + /// Gets the name of this type + /// + public string Name { get; set; } + + private readonly List _subtypes; + /// + /// Gets the depth of this Token Type + /// + /// + /// For example, Root.Comment.Preproc has a depth of 3 + /// + public int Depth { get; } + + /// + /// Gets the list of subtypes for this token type + /// + public IReadOnlyCollection Subtypes => _subtypes; + + /// + /// Initializes a new instance of the class + /// + /// The parent token type + /// The name of this token type + public TokenType(TokenType parent, string name) + { + Parent = parent; + Name = name; + + _subtypes = new List(); + Depth = CalculateDepth(); + } + + /// + /// Creates a child token type + /// + /// The name of the child token type + /// + public TokenType CreateChild(string name) + { + var newTokenType = new TokenType(this, name); + _subtypes.Add(newTokenType); + return newTokenType; + } + + /// + /// Adds a child to this Token + /// + /// The type of child being added + /// The child to add + /// + public TChild AddChild(TChild child) where TChild : TokenType + { + _subtypes.Add(child); + return child; + } + + /// + /// Gets a list of types for this token, starting with itself and ending at its highest level parent + /// + /// + public IEnumerable Split() + { + return YieldAncestors().Reverse(); + } + + private int CalculateDepth() + { + return YieldAncestors().Count(); + } + + private IEnumerable YieldAncestors() + { + var current = this; + + do + { + yield return current; + current = current.Parent; + + } while (current != null); + } + + /// Returns a string that represents the current object. + /// A string that represents the current object. + /// 2 + public override string ToString() + { + return string.Join(".", Split().Select(t => t.Name)); + } + + } +} diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Tokens/TokenTypes.cs b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/TokenTypes.cs new file mode 100644 index 0000000..cd45411 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Tokens/TokenTypes.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Tokens +{ + /// + /// The set of known s + /// + public static class TokenTypes + { + /// + /// Gets the default (root) Token + /// + public static readonly TokenType Token = new TokenType(null, "Token"); + + /// + /// Gets a token for representing basic text + /// + public static readonly TokenType Text = Token.CreateChild("Text"); + + /// + /// Gets a token for representing whitespace + /// + public static readonly TokenType Whitespace = Text.CreateChild("Whitespace"); + + /// + /// Gets a token for representing an escape character + /// + public static readonly TokenType Escape = Token.CreateChild("Escape"); + + /// + /// Gets a token for representing an error in tokenizing + /// + public static readonly TokenType Error = Token.CreateChild("Error"); + + /// + /// Gets a token for representing an unknwon type of token + /// + public static readonly TokenType Other = Token.CreateChild("Other"); + + /// + /// Gets a token for representing a language keyword + /// + public static readonly KeywordTokenType Keyword = Token.AddChild(new KeywordTokenType(Token)); + + /// + /// Gets a token for representing a name + /// + public static readonly NameTokenType Name = Token.AddChild(new NameTokenType(Token)); + + /// + /// Gets a token for representing a literal value + /// + public static readonly LiteralTokenType Literal = Token.AddChild(new LiteralTokenType(Token)); + + + /// + /// Gets a token for representing string literal. Alias for Literal.String + /// + public static readonly StringTokenType String = Literal.String; + + /// + /// Gets a token for representing a number literal. Alias for Literal.Number + /// + public static readonly NumberTokenType Number = Literal.Number; + + /// + /// Gets a token for representing generic punctuation + /// + public static readonly TokenType Punctuation = Token.CreateChild("Punctuation"); + + /// + /// Gets a token for representing an arithmetic operator + /// + public static readonly OperatorTokenType Operator = Token.AddChild(new OperatorTokenType(Token)); + + /// + /// Gets a token for representing a comment + /// + public static readonly CommentTokenType Comment = Token.AddChild(new CommentTokenType(Token)); + + /// + /// Gets a token for representing a generic token + /// + public static readonly GenericTokenType Generic = Token.AddChild(new GenericTokenType(Token)); + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Utils/Argument.cs b/Projects/AOTBrowser/PygmentSharp.Core/Utils/Argument.cs new file mode 100644 index 0000000..4b31f91 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Utils/Argument.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Utils +{ + internal static class Argument + { + /// + /// Validates a value is not null + /// + /// Thrown if is null + /// The argument to validate + /// The name of the argument + // ReSharper disable once UnusedParameter.Global + public static void EnsureNotNull(object arg, string argName) + { + if (arg == null) + throw new ArgumentNullException(argName); + } + } +} diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Utils/CommonPrefix.cs b/Projects/AOTBrowser/PygmentSharp.Core/Utils/CommonPrefix.cs new file mode 100644 index 0000000..b2c747b --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Utils/CommonPrefix.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Utils +{ + /// + /// Calculations for the longest common prefix of a list of strings + /// + /// https://docs.python.org/2/library/os.path.html + /// + /// + internal static class CommonPrefix + { + /// + /// Computes the longest common prefix of a list of . + /// The shortest common prefix is empty string + /// + /// The list of strings to check + /// The common prefix + public static string Of(params string[] strings) + { + return Of((IReadOnlyList)strings); + } + + public static string Of(IReadOnlyList strings) + { + var sorted = strings.OrderBy(s => s.Length).ToArray(); + var check = sorted.First(); + + while (check.Length > 0) + { + if (sorted.All(s => s.StartsWith(check, StringComparison.InvariantCulture))) + { + return check; + } + + check = check.Substring(0, check.Length - 1); + } + + return check; + } + } +} \ No newline at end of file diff --git a/Projects/AOTBrowser/PygmentSharp.Core/Utils/Slice.cs b/Projects/AOTBrowser/PygmentSharp.Core/Utils/Slice.cs new file mode 100644 index 0000000..d96d325 --- /dev/null +++ b/Projects/AOTBrowser/PygmentSharp.Core/Utils/Slice.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace PygmentSharp.Core.Utils +{ + /// + /// Represents a slice of an array. A slice is a readonly view of an underlying + /// array that can be treated like an independent collection: but it doesn't involve + /// copy array parts all around. + /// + /// + internal struct Slice : IReadOnlyList + { + /// + /// Gets the start index into the underlying array + /// + public int Start { get; } + + /// + /// Gets the length of the slice + /// + public int Length { get; } + + private readonly T[] _inner; + + /// + /// Constructs a new slice of an array + /// + /// the underlying array + /// The starting index at which this slice will begin + /// The length of the slice + public Slice(T[] inner, int start, int length) + { + _inner = inner; + Start = start; + + if (length < 0) + Length = 0; + else + Length = Math.Min(length, (_inner.Length - start)); + } + + /// + /// Constructs a new slice of an array, from a index to the end + /// + /// The underlying array + /// The starting index of the slice + public Slice(T[] inner, int start) + { + _inner = inner; + Start = start; + Length = _inner.Length - start; + } + + /// + /// Constructs a slice over an entire array + /// + /// The underlying array + public Slice(T[] inner) + { + _inner = inner; + Start = 0; + Length = inner.Length; + } + + public IEnumerator GetEnumerator() + { + for (int i = 0; i < Length; i++) + { + yield return _inner[Start + i]; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// Gets a value at the specified of the slice + /// + /// The index to read + /// The value from the underlying array + public T this[int index] + { + get + { + if (index < 0) + throw new IndexOutOfRangeException(); + if (index >= Length) + throw new IndexOutOfRangeException(); + + return _inner[Start + index]; + } + } + + public static implicit operator Slice(T[] inner) + { + return new Slice(inner); + } + + public Slice SubSlice(int start) + { + int length = (Length - start); + return new Slice(_inner, Start + start, length); + } + + public int Count => Length; + + } + + internal static class ArrayExtensions + { + /// + /// Slices an array + /// + /// + /// The underlying array + /// The index in which to start the slice + /// The length of the slice + /// + public static Slice Slice(this T[] inner, int start, int length) + { + return new Slice(inner, start, length); + } + + /// + /// Slices an array starting at a given index. If is negative, + /// the slicing starts from that many items from the end of the array + /// + /// + /// + /// + /// + public static Slice Slice(this T[] inner, int start) + { + var startIndex = start < 0 ? inner.Length + start : start; + return new Slice(inner, startIndex); + } + + } +} diff --git a/Projects/Dependency.xml b/Projects/Dependency.xml index 003060c..2dfefc8 100644 --- a/Projects/Dependency.xml +++ b/Projects/Dependency.xml @@ -1,5 +1,12 @@ + + Project + AOTBrowser/PygmentSharp.Core/PygmentSharp.Core.csproj + + AOTBrowser + + Project AOTBrowser/Arbela.Dynamics.AX.Xpp.Support/Arbela.Dynamics.AX.Xpp.Support.csproj