--[[****************************************************************************
*                                                                              *
*           Highlight Language Definition "Clean Slate" Boilerplate            *
*                                                                              *
*                v1.1.0 (2019/03/02) | Highlight v3.49 | Lua 5.3               *
*                                                                              *
*                              by Tristano Ajmone                              *
*                                                                              *
********************************************************************************
This is a langDef boilerplate intended as a starting point to build your own
custom language definition on top of it. This boilerplate is based on a "clean
slate" approach: all possible syntax elements definition are present, but they
are set to a never matching regular expression:

    [=[ \A(?!x)x ]=]

This boilerplate will never match anything; even Highlight's built-in defaults
are overridden (ie: those elements which, if undefined, would take fallback
default values). The idea is that of starting with a "clean slate" language
definition, where nothing is matched at all; and then start to build the lang
def one element definition after the other, without the potential interference
of any default definitions. This is a "distraction free" approach, which allows
to focus on single syntax elements in a "vacuum" environment, particularly
useful when dealing with syntax definitions where conflicts between various
elements arise. Once you've succeeded in defining a given syntax element, you
can comment it out and replace it with the original never matching RegEx, and
start working on the next element. Working on a single element at the time
prevents cross-elements interferences creeping in; and switching between an
element's real definition and it's never matching RegEx is a practical way to
isolate which element is interfering with others in the final context.

Just copy this boilerplate, rename it, and edit it as required. The language
definition template "template.lang" can be referenced for guidelines and useful
presets while working on your custom language -- the template contains useful
comments and preset examples on the various syntax elements. The comments in
this boilerplate have been kept down to the essential references for this
context; for more details refer to "template.lang" comments and the official
documentation.
--------------------------------------------------------------------------------
Written by Tristano Ajmone:
    <tajmone@gmail.com>
    https://github.com/tajmone
    https://gitlab.com/tajmone
Released into the public domain according to the Unlicense terms:
    http://unlicense.org/
------------------------------------------------------------------------------]]

Description = "Clean Slate" -- Syntax description

--[[============================================================================
                                  CATEGORIES
================================================================================
Categories:        Table, List of categories (config, source, script, etc)
------------------------------------------------------------------------------]]
Categories = {"source", "script"}

-- The (optional) 'Categories' element is used to filter languages by categories
-- when querying Highlight for the list of available syntaxes, e.g.:

--     highlight --list-scripts=langs --list-cat=markup

-- ... will list all the available syntax definitions for markup languages.

-- You should provide as many categories as required for you own syntax.Common
-- categories are: "config", "markup", "script" and "source". For a full list
-- of categories in use by the syntaxes that ship with Highlight, see the Wiki:

--     https://gitlab.com/saalen/highlight/wikis/LangDefs-Elements#categories

--------------------------------------------------------------------------------

IgnoreCase = false -- Are keywords case-sensitive? (true/false)

EnableIndentation = false -- Syntax may be reformatted and indented? (true/false)

--[[============================================================================
                                  IDENTIFIERS
================================================================================
String, Regular expression which defines identifiers (optional).

Highlight's default Identifiers definition:

  Identifiers=[=[ [a-zA-Z_]\w* ]=]

------------------------------------------------------------------------------]]
-- UNCOMMENT THE FOLLOWING TO USE NEVER-MATCHING REGEX:

-- Identifiers = [=[ \A(?!x)x ]=] -- Never-Matching RegEx!

-- ** WARNING ** By setting Identifiers to a never-matching RegEx, Keywords lists
--               won't be reckognized anymore by the parser! This can be a useful
--               trick/hack needed in some syntax which rely only on RegEx-defined
--               Keywords, and to avoid conflicts with other elements in some
--               edge-cases. Try it only to check if the current (or default)
--               Identifiers definition might be interfering in the parsing of
--               other elements.

--[[============================================================================
                                    COMMENTS
================================================================================
Comments = { {Block, Nested?, Delimiter=} }

  Block:     Boolean, true if comment is a block comment
  Nested:    Boolean, true if block comments can be nested (optional)
  Delimiter: List, contains open delimiter regex (line comment) or open and
              close delimiter regexes (block comment)
------------------------------------------------------------------------------]]
Comments = {
  -- Define BLOCK-COMMENTS delimiters
  { Block  = true,
    Nested = false, -- Can block comments be nested? (optional)
    Delimiter = {
      [=[ \A(?!x)x ]=], -- Never-Matching RegEx!
      [=[ \A(?!x)x ]=]  -- Never-Matching RegEx!
    }
  },
  -- Define SINGLE-LINE-COMMENTS delimiter
  { Block = false,
    Delimiter = { [=[ \A(?!x)x ]=] } -- Never-Matching RegEx!
  }
}
--[[============================================================================
                                    STRINGS
================================================================================
Strings = { Delimiter|DelimiterPairs={Open, Close, Raw?}, Escape?, Interpolation?,
            RawPrefix?, AssertEqualLength? }

  Delimiter:         String, regular expression which describes string delimiters
  DelimiterPairs:    List, includes open and close delimiter expressions if not
                      equal, includes optional Raw flag as boolean which marks
                      delimiter pair to contain a raw string
  Escape:            String, regex of escape sequences (optional)
  Interpolation:     String, regex of interpolation sequences (optional)
  RawPrefix:         String, defines raw string indicator (optional)
  AssertEqualLength: Boolean, set true if delimiters must have the same length
------------------------------------------------------------------------------]]
Strings = {

--------------------------------------------------------------------------------
--                              STRING DELIMITERS
--------------------------------------------------------------------------------

  -- SYMMETRICAL STRINGS DELIMITERS
  Delimiter = [=[ \A(?!x)x ]=], -- Never-Matching RegEx!

  -- ASYMMETRICAL STRINGS DELIMITERS
  DelimiterPairs= {
    { Open  = [=[ \A(?!x)x ]=], -- Never-Matching RegEx!
      Close = [=[ \A(?!x)x ]=], -- Never-Matching RegEx!
      Raw = true, -- Are these raw string delimiters? (true/false)
    }
  },
  AssertEqualLength = true, -- Delimiters must have the same length?

  -- RAW-STRING PREFIX (if language supports it)
  RawPrefix = [=[ \A(?!x)x ]=], -- Never-Matching RegEx!
--[==[--------------------------------------------------------------------------
                                ESCAPE SEQUENCES
--------------------------------------------------------------------------------
If the language at hand supports escape sequences, define a RegEx pattern to
capture them.

Highlight's default built-in Escape definition:

  Escape=[=[ \\u[[:xdigit:]]{4}|\\\d{3}|\\x[[:xdigit:]]{2}|\\[ntvbrfa\\\?'"] ]=]

NOTE: Escape sequences will be matched anywhere, not just inside strings. If you
      need to restrict them to strings only, you'll need to write a custom hook
      function (for an example, see the "template.lang" file).              ]==]

  Escape = [=[ \A(?!x)x ]=], -- Never-Matching RegEx!
--[[----------------------------------------------------------------------------
                                INTERPOLATION
--------------------------------------------------------------------------------
String, regex of interpolation sequences (optional)                         --]]

  Interpolation = [=[ \A(?!x)x ]=], -- Never-Matching RegEx!
}

--[[============================================================================
                                  PREPROCESSOR
================================================================================
PreProcessor = { Prefix, Continuation? }

  Prefix:        String, regular expression which describes open delimiter
  Continuation:  String, contains line continuation character (optional).   --]]

PreProcessor = {
  Prefix = [=[ \A(?!x)x ]=], -- Never-Matching RegEx!

-- UNCOMMENT IF YOU NEED CONTINUATION CHARACTER:
  -- Continuation = "", -- A character, not a RegEx! (escaping rules apply)
}
--[[============================================================================
                                  OPERATORS
============================================================================--]]
Operators = [=[ \A(?!x)x ]=] -- Never-Matching RegEx!

--[[============================================================================
                                        DIGITS
================================================================================
String, Regular expression which defines digits (optional).

Highlight's default built-in Digits definition:

  Digits=[=[ (?:0x|0X)[0-9a-fA-F]+|\d*[\.]?\d+(?:[eE][\-\+]\d+)?[lLuU]* ]=]
--]]
Digits = [=[ \A(?!x)x ]=] -- Never-Matching RegEx!

--[[============================================================================
                                      KEYWORDS
================================================================================
Keywords = { Id, List|Regex, Group? }

  Id:    Integer, keyword group id (values 1-4, can be reused for several keyword
          groups)
  List:  List, list of keywords
  Regex: String, regular expression
  Group: Integer, capturing group id of regular expression, defines part of regex
          which should be returned as keyword (optional; if not set, the match
          with the highest group number is returned (counts from left to right))

NOTE: Keyword group Ids are not limited to 4, you can create as many as you
      need; but bare in mind that most themes that ship with Highlight usually
      provide definitions only for Ids 1-4, so in order to syntax-color Keyword
      groups with Ids greater than 4 you'll need to define a theme that covers
      their definitions.                                                    --]]

Keywords = {
--------------------------------------------------------------------------------
--                               Keywords by List
--------------------------------------------------------------------------------
-- NOTE: If you've set `IgnoreCase = false` then all keywords in the list must
--       be in lowercase otherwise they'll never match! With case-insensitive
--       languages, Highlight converts to lowercase the token before comparing
--       it to the entries of the Keywords list, but the list entries are not
--       manipulated before comparison.
  { Id = 1,
    List = {
      -- Keywords list
      "XYZ", "ZYX" -- Dummy Sample Values
    }
  },
--------------------------------------------------------------------------------
--                              Keywords by RegEx
--------------------------------------------------------------------------------
  { Id = 2,
    Regex = [=[ \A(?!x)x ]=], -- Never-Matching RegEx!
    Group = 1
  }
}

--[[****************************************************************************
*                                                                              *
*                            CUSTOM HOOK-FUNCTIONS                             *
*                                                                              *
********************************************************************************
In some cases you might need to gain finer control over Highlight parser; you
can do so by defining some custom hooks via the OnStateChange() function.

For more info, see:
    https://github.com/andre-simon/highlight/blob/master/README#L596
    https://github.com/andre-simon/highlight/blob/master/README_PLUGINS#L170
------------------------------------------------------------------------------]]

--[[============================================================================
                                  CHANGELOG
================================================================================
v1.1.0 (2019/03/02) | Highlight v3.49
  - Added new 'Categories' element.

v1.0.2 (2018/07/02) | Highlight v3.43
  - Cleaned up code and comments.
  - Some notes added.

v1.0.1 (2018/01/04) | Highlight v3.41
  - First release.                                                          --]]
