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