<?xml version="1.0" encoding="UTF-8"?>
<language id="blueprint" name="Blueprint" version="2.0" _section="Other">
  <metadata>
    <property name="globs">*.blp</property>
    <property name="block-comment-start">/*</property>
    <property name="block-comment-end">*/</property>
    <property name="line-comment-start">//</property>
  </metadata>

  <styles>

    <!-- global -->
    <style id="comment"                     name="Comment"                     map-to="def:comment"/>
    <style id="translator"                  name="Translator Comment"          map-to="def:emphasis"/>
    <style id="keyword"                     name="Keyword"                     map-to="def:keyword"/>
    <style id="external"                    name="External"                    map-to="def:inline-code"/>
    <style id="object_id"                   name="Object ID"                   map-to="def:inline-code"/>
    <style id="namespace"                   name="Namespace"                   map-to="def:type"/>
    <style id="class"                       name="Class"                       map-to="def:type"/>
    <style id="property"                    name="Property"                    map-to="def:identifier"/>
    <style id="signal"                      name="Signal"                      map-to="def:identifier"/>
    <style id="identifier"                  name="Identifier"                  map-to="def:identifier"/>
    <style id="child_type"                  name="Child Type"                  map-to="def:identifier"/>

    <!-- data types -->
    <style id="escape"                      name="Escape Sequence"             map-to="def:special-char"/>
    <style id="string"                      name="String"                      map-to="def:string"/>
    <style id="boolean"                     name="Boolean"                     map-to="def:boolean"/>
    <style id="number"                      name="Number"                      map-to="def:number"/>
    <style id="integer"                     name="Integer"                     map-to="def:decimal"/>
  </styles>

  <definitions>
    <define-regex id="ident">[A-Za-z_][\d\w\-_]*</define-regex>
    <define-regex id="quoted">("(\\"|[^"\n])+"|'(\\'|[^'\n])+')</define-regex>
    <define-regex id="number">([-+]?\d[\d_]*(\.\d[\d_]*)?|0x[A-Fa-f0-9]+)</define-regex>
    <define-regex id="comment">(/\*[\s\S]*\*/|\/\/[^\n]*)</define-regex>
    <define-regex id="op">[:=\.=\|&lt;&gt;\+\-/\*]+</define-regex>
    <define-regex id="escape">\\n|\\"|\\'</define-regex>
    <define-regex id="block_keyword">accessibility|layout|attributes|menu|submenu|item|section</define-regex>

    <context id="using">
      <match extended="true">
        (using)
        \s+
        (\%{ident})
        \s+
        (\%{number})
      </match>
      <include>
        <context sub-pattern="1" style-ref="keyword"/>
        <context sub-pattern="2" style-ref="namespace"/>
        <context sub-pattern="3" style-ref="namespace"/>
      </include>
    </context>

    <context id="value">
      <include>
        <context ref="child"/>
        <context id="bool" style-ref="boolean">
          <match>true|false</match>
        </context>
        <context id="number" style-ref="number">
          <match>\%{number}</match>
        </context>
        <context id="quoted" style-ref="string">
          <start>"</start>
          <end>"</end>
          <include>
            <context id="escape" style-ref="escape">
              <match>\%{escape}</match>
            </context>
          </include>
        </context>
        <context id="quoted2" style-ref="string">
          <start>'</start>
          <end>'</end>
          <include>
            <context id="escape2" style-ref="escape">
              <match>\%{escape}</match>
            </context>
          </include>
        </context>
        <context id="ident" style-ref="identifier">
          <match>\%{ident}</match>
        </context>
      </include>
    </context>

    <context id="comment">
      <include>
        <context id="line-comment" style-ref="comment" end-at-line-end="true" class="comment" class-disabled="no-spell-check">
          <start>//</start>
          <include>
            <context ref="def:in-line-comment"/>
          </include>
        </context>

        <context id="multiline-comment" style-ref="comment" class="comment" class-disabled="no-spell-check">
          <start>/\*</start>
          <end>\*/</end>
          <include>
            <context ref="def:in-comment"/>
            <context id="translator-comment" style-ref="translator">
              <match case-sensitive="false">translators:</match>
            </context>
          </include>
        </context>
      </include>
    </context>

    <context id="attribute">
      <start extended="true">
        (\%{ident})
        \s*
        :
      </start>
      <end>;</end>
      <include>
        <context where="start" sub-pattern="1" style-ref="property"/>
        <context ref="keywords"/>
        <context ref="value"/>
      </include>
    </context>

    <context id="signal">
      <start extended="true">
        (\%{ident})
        \s*
        =>
      </start>
      <end>;</end>
      <include>
        <context where="start" sub-pattern="1" style-ref="property"/>
        <context ref="value"/>
        <context ref="keywords"/>
      </include>
    </context>

    <context id="child-type" style-ref="child_type">
      <match>\[\%{ident}\]</match>
    </context>

    <context id="template">
      <start extended="true">
        (template)\s*
        (?&lt;template_id&gt;\%{ident})\s*
        :\s*
        ((?&lt;template_ns&gt;\%{ident})?\s*\.)?\s*
        (?&lt;template_class&gt;\%{ident})\s*
        {
      </start>
      <end>}</end>
      <include>
        <context where="start" sub-pattern="1" style-ref="keyword"/>
        <context where="start" sub-pattern="template_id" style-ref="object_id"/>
        <context where="start" sub-pattern="template_ns" style-ref="namespace"/>
        <context where="start" sub-pattern="template_class" style-ref="class"/>
        <context ref="block-content"/>
      </include>
    </context>

    <context id="child">
      <start extended="true">
        (
          ((?&lt;child_ns&gt;\%{ident})?\s*\.)?\s*
          (?(?=(?&lt;child_kw&gt;\%{block_keyword}))(\%{block_keyword})|(?&lt;child_class&gt;\%{ident}))\s*
          (?&lt;child_id&gt;\%{ident})?
        )\s*
        {
      </start>
      <end>}</end>
      <include>
        <context where="start" sub-pattern="child_kw" style-ref="keyword"/>
        <context where="start" sub-pattern="child_ns" style-ref="namespace"/>
        <context where="start" sub-pattern="child_class" style-ref="class"/>
        <context where="start" sub-pattern="child_id" style-ref="object_id"/>
        <context ref="block-content"/>
      </include>
    </context>

    <context id="block-content">
      <include>
        <context ref="comment"/>
        <context ref="attribute"/>
        <context ref="signal"/>
        <context ref="keywords"/>
        <context ref="block"/>
        <context ref="child-type"/>
        <context ref="list"/>
        <context ref="args"/>
        <context ref="child"/>
      </include>
    </context>

    <context id="block">
      <start>{</start>
      <end>}</end>
      <include>
        <context ref="block-content"/>
      </include>
    </context>

    <context id="list">
      <start>\[</start>
      <end>\]</end>
      <include>
        <context ref="comment"/>
        <context ref="value"/>
        <context ref="keywords"/>
      </include>
    </context>

    <context id="args">
      <start>\(</start>
      <end>\)</end>
      <include>
        <context ref="comment"/>
        <context ref="value"/>
        <context ref="keywords"/>
      </include>
    </context>

    <context id="keywords" style-ref="keyword">
      <keyword>accessibility</keyword>
      <keyword>bidirectional</keyword>
      <keyword>bind</keyword>
      <keyword>item</keyword>
      <keyword>items</keyword>
      <keyword>layout</keyword>
      <keyword>menu</keyword>
      <keyword>patterns</keyword>
      <keyword>section</keyword>
      <keyword>strings</keyword>
      <keyword>styles</keyword>
      <keyword>submenu</keyword>
      <keyword>suffixes</keyword>
      <keyword>swapped</keyword>
      <keyword>sync-create</keyword>
      <keyword>template</keyword>
      <keyword>mime-types</keyword>
      <keyword>widgets</keyword>
    </context>

    <context id="blueprint" class="no-spell-check">
      <include>
        <context ref="comment"/>
        <context ref="using"/>
        <context ref="template"/>
        <context ref="keywords"/>
        <context ref="block"/>
        <context ref="child"/>
      </include>
    </context>
  </definitions>
</language>

