Can I use JavascriptLanguage (which is included in Web add-on) with custom DynamicLexicalPattern?

SyntaxEditor Web Languages Add-on for WPF Forum

Posted 6 years ago by Hyundong Hwang
Version: 13.2.0591
Avatar

Hi I was developing some Javascript code editor with Actipro Web add-on.

And I needed to add some keyword ( my custom class name ) like TAccout, TGraph into pure Javascript language.

So I used JavaScriptSyntaxLanguage at First, and then I registered additional DynamicLexer.

I expected that keyword from pure javacsript and my language will be highlighted together, but only javascript keyword were worked.

I don't know how to fix my code.

My codes follows

public class TradeJsLexer : DynamicLexer
{
	public TradeJsLexer()
	{
		//I know that this is the wrong way to register color to this ClassificationType
		//But I don't know how to match some color to ClassificationType.
		//I want to make this TAccount TGraph keywords highlighted. :(
		var cf = new ClassificationType("TradeJsClassType", "#FF2B91AF");
		var lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "TradeJsClassType", ClassificationTypes.Keyword);
		lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("TAccount"));
		lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("TGraph"));
		this.DefaultLexicalState.LexicalPatternGroups.Add(lexicalPatternGroup);
	}
}



this.SyntaxEditorObj = new SyntaxEditor();
this.SyntaxEditorObj.Document.Language = new JavaScriptSyntaxLanguage();
this.SyntaxEditorObj.Document.Language.RegisterService(new TradeJsLexer());

Comments (2)

Answer - Posted 6 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello, the advanced JavaScript language in the Web Languages Add-on uses a programmatic lexer.  That means it is hand written in code and isn't a dynamic lexer.  Also you can't register more than one lexer on a language.

While you could purchase the Blueprint source code for the add-on and then clone/update the lexer we wrote to meet your needs, the problem then is that the parser grammar would likely start to add warnings when your new keywords were used, since the parser wouldn't be expecting those.  You would need to upgrade the grammar as well.

Alternatively you could do something like use a classification tagger (see our documentation and samples like the adornments ones), which would allow you to assign a classification type over desired ranges and if a style is associated with that classification type, you could alter the range's foreground.  Then you aren't modifying the core lexer at all.  That might be the best way for you to go.


Actipro Software Support

Posted 6 years ago by Hyundong Hwang
Avatar

I fix that you mentioned then works greatly, thank you :)

I append my fixed codes on this thread to help others who has similar problem.

The fixed codes follows

public class VictoriaClassificationTagger : TaggerBase<IClassificationTag>
{
	ITagAggregator<ITokenTag> _tokenTagAggregator;
	IClassificationType _wordHighlightClassificationType = new ClassificationType("TradeJsApiClass", "TradeJsApiClass");

	public VictoriaClassificationTagger(ICodeDocument document)
		: base("VictoriaClassificationTagger", new[] { new Ordering(TaggerKeys.Token, OrderPlacement.Before) }, document)
	{
		// Get a token tag aggregator
		_tokenTagAggregator = document.CreateTagAggregator<ITokenTag>();

		IHighlightingStyle style = new HighlightingStyle(new SolidColorBrush(Color.FromArgb(0xff, 0x2b, 0x91, 0xaf)));
		AmbientHighlightingStyleRegistry.Instance.Register(_wordHighlightClassificationType, style);
	}

	public override IEnumerable<TagSnapshotRange<IClassificationTag>> GetTags(NormalizedTextSnapshotRangeCollection snapshotRanges, object parameter)
	{
		// Loop through the requested snapshot ranges...
		foreach (var snapshotRange in snapshotRanges)
		{
			// If the snapshot range is not zero-length...
			if (!snapshotRange.IsZeroLength)
			{
				var tokenTagRanges = _tokenTagAggregator.GetTags(snapshotRange);
				if (tokenTagRanges != null)
				{
					foreach (var tokenTagRange in tokenTagRanges)
					{
						var tokenText = tokenTagRange.SnapshotRange.Text;
						var isFound = TradeJsApiDocModel.Current.ApiInfoDic.Any(kv => tokenText.EndsWith(kv.Value.Class) == true);

						if (isFound == true)
						{
							yield return new TagSnapshotRange<IClassificationTag>(
								new TextSnapshotRange(snapshotRange.Snapshot, tokenTagRange.SnapshotRange),
								new ClassificationTag(_wordHighlightClassificationType)
								);
						}
					}
				}
			}
		}
	}
}



this.SyntaxEditorObj.Document.Language = new JavaScriptSyntaxLanguage();
this.SyntaxEditorObj.Document.Language.RegisterService(new CodeDocumentTaggerProvider<VictoriaClassificationTagger>(typeof(VictoriaClassificationTagger)));

 

 

the blue color token is javascript origin keyword and the emerald one is my custom defiend keyword.

http://sdrv.ms/1dInjnd

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.