Batch Syntax Highlighting in the DigitalRune Text Editor Control

In a previous article I described how to create a CSS syntax highlighting definition file for use with the open source DigitalRune Text Editor Control.

Today I was testing events in one of our myriad of prototypes, which triggered an sample TextEditorControl to apply the BAT syntax definition found in BAT-Mode.xshd.

While it validated the particular piece of code I was working on rather nicely, I was less then enamoured with the highlighting. The image below shows an example of this.

Pretty ugly isn't it? However, I was actually doing a vaguely real-world test as I did want to see some simple batch file syntax highlighting. Perfect timing for a distraction to go look at another problem.

The following screenshot shows my new and improved syntax highlighting file, based on my experiences creating the CSS version. I couldn't do everything I tried/wanted, and I suspect this will be limitations of the TextEditorControl, but fixing that is "rainy day" stuff. Otherwise, simple as this was, it was a nice distraction with immediate benefits!

The XML Definition

The definition is very straightforward, as it's basically just keyword tokens and a single highlighting span for environment variables.

I was trying for something similar to how Notepad++ highlights batch files, in which if the first "word" on a line isn't a command, it's assumed to be a program and highlighted accordingly, but I couldn't get that working correctly so it's commented out in the definition - if you know of a trick or code patch to make it work, please let me know!

<?xml version="1.0" encoding="utf-8"?>

<!-- Batch File syntax highlighting for DigitalRune TextEditor. Created by Cyotek (http://cyotek.com/) -->

<SyntaxDefinition name="Batch" extensions="*.bat;*.cmd">

  <Environment>
    <Default color="#000000" bgcolor="#ffffff" />
  </Environment>

  <RuleSets>

    <RuleSet ignorecase="true">

      <!-- Adding @ as a delimiter means the "ECHO" in "@ECHO OFF" will be highlighted. -->
      <Delimiters>@:</Delimiters> 

      <!-- REM comment -->
      <Span name="LineComment" bold="false" italic="false" color="#008000" stopateol="true">
        <Begin>REM</Begin>
      </Span>
      
      <!-- :: style comment -->
      <Span name="LineComment2" bold="false" italic="false" color="#008000" stopateol="true">
        <Begin>::</Begin>
      </Span>

      <!-- label -->
      <Span name="Label" bold="false" italic="false" color="#FF0000" bgcolor="#FFFF80" stopateol="true">
        <Begin startofline="true">:</Begin>
      </Span>
      
      <!-- Environment Variable -->
      <Span name="Variable" bold="false" italic="false" color="#FF8000" bgcolor="#FCFFF0" stopateol="true">
        <Begin>%</Begin>
        <End>%</End>
      </Span>

      <!-- Programs -->
      <!-- The idea here is the first word on a line that isn't a keyword is a program. 
           Doesn't work with the default TextEditorControl though. -->
      <!--<Span name="Program" bold="false" italic="true" color="Red" bgcolor="#FCFFF0" stopateol="true">
        <Begin startofline="true" singleword="true"></Begin>
        <End> </End>
      </Span>-->

      <!-- Operators -->
      <KeyWords name="Punctuation" bold="false" italic="false" color="#FF0000">
        <Key word="+" />
        <Key word="-" />
        <Key word="*" />
        <Key word="&amp;lt;" />
        <Key word="&amp;gt;" />
        <Key word="=" />
        <Key word="@" />
      </KeyWords>
      
      <!-- Standard command.com keywords -->
      <!-- http://en.wikipedia.org/wiki/COMMAND.COM -->
     
      <KeyWords name="command.com-internalcommands" bold="true" italic="false" color="#0000FF">
        <Key word="break" />
        <Key word="chcp" />
        <Key word="chdir" />
        <Key word="cd" />
        <Key word="cls" />
        <Key word="copy" />
        <Key word="ctty" />
        <Key word="date" />
        <Key word="del" />
        <Key word="erase" />
        <Key word="dir" />
        <Key word="echo" />
        <Key word="exit" />
        <Key word="lfnfor" />
        <Key word="loadhigh" />
        <Key word="lh" />
        <Key word="lock" />
        <Key word="move" />
        <Key word="mkdir" />
        <Key word="md" />
        <Key word="path" />
        <Key word="prompt" />
        <Key word="ren" />
        <Key word="rename" />
        <Key word="rmdir" />
        <Key word="rd" />
        <Key word="set" />
        <Key word="time" />
        <Key word="truename" />
        <Key word="type" />
        <Key word="unlock" />
        <Key word="ver" />
        <Key word="verify" />
        <Key word="vol" />
        <!-- http://ss64.com/nt/ -->
        <Key word="color" />
        <Key word="endlocal" />
        <Key word="ftype" />
        <Key word="mklink" />
        <Key word="popd" />
        <Key word="pushd" />
        <Key word="setlocal" />
        <Key word="start" />
        <Key word="title" />
      </KeyWords>

      <KeyWords name="command.com-commands" bold="true" italic="false" color="#0000FF">
        <Key word="call" />
        <Key word="for" />
        <Key word="goto" />
        <Key word="if" />
        <Key word="in" />
        <Key word="do" />
        <Key word="pause" />
        <Key word="rem" />
        <Key word="shift" />
      </KeyWords>
      
      <!-- Redirects -->
      <KeyWords name="command.com-redirects" bold="true" italic="false" color="#0000FF">
        <Key word="nul" />
        <Key word="con" />
        <Key word="prn" />
        <Key word="aux" />
        <Key word="clock$" />
        <Key word="com0" />
        <Key word="com1" />
        <Key word="com2" />
        <Key word="com3" />
        <Key word="com4" />
        <Key word="com5" />
        <Key word="com6" />
        <Key word="com7" />
        <Key word="com8" />
        <Key word="com9" />
        <Key word="lpt0" />
        <Key word="lpt1" />
        <Key word="lpt2" />
        <Key word="lpt3" />
        <Key word="lpt4" />
        <Key word="lpt5" />
        <Key word="lpt6" />
        <Key word="lpt7" />
        <Key word="lpt8" />
        <Key word="lpt9" />
      </KeyWords>

    </RuleSet>

  </RuleSets>
</SyntaxDefinition>

A sample project

I've attached a basic sample project, which shows how to dynamic load in the definition file. And yes, that is a (stripped down) version of one of the build scripts used by Spriter. I'm still an old school guy at heart, and so I use msbuild to compile a solution, but for anything else I still tend to turn to batch scripts and custom console apps first rather than MSBuild tasks or PowerShell cmdlets.

Although the example project loads in the definition from an external file, I would recommend that you build it into the TextEditorControl assembly itself to make deployment easier. I covered this in the Compiling the definition into the assembly section of the previous article so I won't replicate that here.

Downloads

Filename Description Version Release Date
DigitalRuneTextEditorBatHighlighting.zip
  • md5: c961d4fb5ee06a22c58bc600232d9949

Sample project for the Batch Syntax Highlighting in the DigitalRune Text Editor Control blog post.

23/06/2014 Download

About The Author

Gravatar

The founder of Cyotek, Richard enjoys creating new blog content for the site. Much more though, he likes to develop programs, and can often found writing reams of code. A long term gamer, he has aspirations in one day creating an epic video game. Until that time, he is mostly content with adding new bugs to WebCopy and the other Cyotek products.

Leave a Comment

While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?