Commits

Thomas Aglassinger  committed 17ed4e2

#1: Add lexer for FOCUS master and access files.

  • Participants
  • Parent commits 3a6587a

Comments (0)

Files changed (4)

File pygments/lexers/_mapping.py

     'FancyLexer': ('pygments.lexers.agile', 'Fancy', ('fancy', 'fy'), ('*.fy', '*.fancypack'), ('text/x-fancysrc',)),
     'FantomLexer': ('pygments.lexers.compiled', 'Fantom', ('fan',), ('*.fan',), ('application/x-fantom',)),
     'FelixLexer': ('pygments.lexers.compiled', 'Felix', ('felix', 'flx'), ('*.flx', '*.flxh'), ('text/x-felix',)),
+    'FocusAccessLexer': ('pygments.lexers.other', 'FOCUS access', (), ('*.acx',), ('text/x-focus-access',)),
+    'FocusMasterLexer': ('pygments.lexers.other', 'FOCUS master', ('master',), ('*.mas',), ('text/x-focus-master',)),
     'FortranLexer': ('pygments.lexers.compiled', 'Fortran', ('fortran',), ('*.f', '*.f90', '*.F', '*.F90'), ('text/x-fortran',)),
     'FoxProLexer': ('pygments.lexers.foxpro', 'FoxPro', ('Clipper', 'XBase'), ('*.PRG', '*.prg'), ()),
     'GLShaderLexer': ('pygments.lexers.compiled', 'GLSL', ('glsl',), ('*.vert', '*.frag', '*.geo'), ('text/x-glslsrc',)),

File pygments/lexers/other.py

            'MscgenLexer', 'KconfigLexer', 'VGLLexer', 'SourcePawnLexer',
            'RobotFrameworkLexer', 'PuppetLexer', 'NSISLexer', 'RPMSpecLexer',
            'CbmBasicV2Lexer', 'AutoItLexer', 'EasytrieveLexer', 'JclLexer',
-           'RexxLexer', 'WebFocusLexer']
+           'RexxLexer', 'WebFocusLexer', 'FocusAccessLexer',
+           'FocusMasterLexer']
 
 
 class ECLLexer(RegexLexer):
         return result
 
 
+class FocusMasterLexer(RegexLexer):
+    """
+    FOCUS master files describes files and tables to be queried by FOCUS
+    programs. The are somewhat comparable to SQL ``create table`` statements.
+
+    *New in Pygments 1.x.*
+    """
+    name = 'FOCUS master'
+    aliases = ['master']
+    filenames = ['*.mas']
+    mimetypes = ['text/x-focus-master']
+    flags = re.IGNORECASE
+
+    tokens = {
+        'root': [
+            (r'\$.*\n', Comment.Single),
+            (r'\s+', Whitespace),
+            (r'[a-z_][a-z0-9_]*', Name),
+            (r'=', Punctuation, 'value'),
+            (r'\.', Punctuation),
+         ],
+        'value': [
+            (r'\$.*\n', Comment.Single, 'root'),
+            (r'\n', Text),
+            (r',', Punctuation, 'root'),
+            (r'\.!', Punctuation),
+            (r'["]', String, 'string_double'),
+            (r'\'', String, 'string_single'),
+            (r'[a-z_][a-z0-9_]*', Text),
+            (r'[0-9]+(\.[0-9]+)?', Number),
+            (r'.', Text),
+        ],
+        'string_double': [
+            (r'\'["]["]', String),
+            (r'["]', String, 'value'),
+            (r'[^"]', String),
+        ],
+        'string_single': [
+            (r'\'\'', String),
+            (r'\'', String, 'value'),
+            (r'[^\']', String),
+        ],
+    }
+
+    _HEADER_PATTERN = re.compile(
+        r'^((\s*\$.*)\n)*file(name)?\s*=\s*[a-z_][a-z0-9_]+\s*,(\s*(\$.*)\n)*\s*suffix\s*=\s*.+',
+        re.IGNORECASE
+    )
+
+    def analyse_text(text):
+        """
+        Check for ``FILE=..., SUFFIX=...`` while ignoring comments starting with ``$``.
+        """
+        result = 0.0
+
+        if FocusMasterLexer._HEADER_PATTERN.match(text):
+            result = 0.8
+        
+        assert 0.0 <= result <= 1.0
+        return result
+
+
+class FocusAccessLexer(FocusMasterLexer):
+    """
+    FOCUS access files associate segments in FOCUS master files with actual
+    tables containing data.
+
+    *New in Pygments 1.x.*
+    """
+    name = 'FOCUS access'
+    aliases = []
+    filenames = ['*.acx']
+    mimetypes = ['text/x-focus-access']
+
+    _HEADER_PATTERN = re.compile(
+        r'^((\s*\$.*)\n)*segment\s*=\s*[a-z_][a-z0-9_]+\s*,(\s*(\$.*)\n)*\s*tablename\s*=\s*.+',
+        re.IGNORECASE
+    )
+
+    def analyse_text(text):
+        """
+        Check for ``SEGMENT=..., TABLENAME=...`` while ignoring comments starting with ``$``.
+        """
+        result = 0.0
+
+        if FocusAccessLexer._HEADER_PATTERN.match(text):
+            result = 0.8
+        
+        assert 0.0 <= result <= 1.0
+        return result
+
+
 class RexxLexer(RegexLexer):
     """
     `Rexx <http://www.rexxinfo.org/>`_ is a scripting language available for

File tests/examplefiles/example.acx

+$ Example FOCUS access file.
+SEGNAME=CUSTOMERS, TABLENAME = "SOME"."CUSTOMERS", KEYS =1,
+ WRITE= NO,   DBSPACE = SOME.WHERE0,$

File tests/examplefiles/example.mas

+$ Example FOCUS master file.
+FILE=CENTGL, SUFFIX=FOC
+SEGNAME=ACCOUNTS,SEGTYPE = S01
+FIELDNAME=GL_ACCOUNT,           ALIAS=GLACCT,  FORMAT=A7,
+          TITLE='Ledger,Account', FIELDTYPE=I, $
+FIELDNAME=GL_ACCOUNT_PARENT,    ALIAS=GLPAR,   FORMAT=A7,
+          TITLE=Parent,
+          PROPERTY=PARENT_OF, REFERENCE=GL_ACCOUNT, $
+FIELDNAME=GL_ACCOUNT_TYPE,      ALIAS=GLTYPE,  FORMAT=A1,
+          TITLE=Type,$
+
+FIELDNAME=GL_ROLLUP_OP,         ALIAS=GLROLL,  FORMAT=A1,
+          TITLE=Op, $ Some comment.
+FIELDNAME=GL_ACCOUNT_LEVEL,     ALIAS=GLLEVEL, FORMAT=I3,
+          TITLE=Lev, $
+    $ Another comment.
+FIELDNAME=GL_ACCOUNT_CAPTION,   ALIAS=GLCAP,   FORMAT=A30,
+          TITLE=Caption,
+          PROPERTY=CAPTION,   REFERENCE=GL_ACCOUNT, $
+FIELDNAME=SYS_ACCOUNT,          ALIAS=ALINE,   FORMAT=A6,
+          TITLE='System,Account,Line', MISSING=ON, $