[
  {
    "path": ".gitattributes",
    "content": "* -text\r\n**.cxx text\r\n**.cpp text\r\n**.c text\r\n**.h text\r\n**.hpp text\r\n**.m text\r\n**.mm text\r\n**.iface text\r\n**.template text\r\n**.mk text\r\n**.mk text\r\n**.py text\r\n**.rc text\r\n**.css text\r\n**.html text\r\n**.bat text\r\n**.bsh text\r\n**.zsh text\r\n**.mak text\r\n**.def text\r\n**.manifest text\r\n**.properties text\r\n**.props text\r\n**.session text\r\n**.styled text\r\n**.folded text\r\n**.adoc text\r\n**.asp text\r\n**.aspx text\r\n**.php text\r\n**.vb text\r\n**.vbs text\r\n**.ans text\r\n**.asm text\r\n**.cob text\r\n**.cmake text\r\n**.d text\r\n**.dart text\r\n**.diff text\r\n**.erl text\r\n**.f text\r\n**.forth text\r\n**.gd text\r\n**.gui text\r\n**.iss text\r\n**.jl text\r\n**.json text\r\n**.lua text\r\n**.m3 text\r\n**.matlab text\r\n**.ml text\r\n**.nim text\r\n**.nix text\r\n**.octave text\r\n**.p text\r\n**.pas text\r\n**.pl text\r\n**.p6 text\r\n**.ps1 text\r\n**.r text\r\n**.rb text\r\n**.roff text\r\n**.rs text\r\n**.snx text\r\n**.sql text\r\n**.st text\r\n**.tcl text\r\n**.toml text\r\n**.tsql text\r\n**.err text\r\n**.mms text\r\n**.tex text\r\n**.fs text\r\n**.vh text\r\n**.vhd text\r\n**.x12 text\r\n**.xml text\r\n**.yaml text\r\n**.zig text\r\n**.md text\r\n**.txt text\r\n**.pch text\r\n**.hg* text\r\n**.dsp text\r\n**.pbxproj text\r\n**.plist text\r\n**.xcworkspacedata text\r\n**.pro text\r\n**.gen text\r\n**makefile text\r\n**.bmp binary\r\n**.cur binary\r\n**.ico binary\r\n**.jpg binary\r\n**.png binary\r\n**.sh text eol=lf\r\ntgzsrc text eol=lf\r\n"
  },
  {
    "path": ".github/workflows/build-check-macos.yml",
    "content": "name: \"Build and check Lexilla on macOS\"\n\non: [push]\n\njobs:\n    build:\n\n        runs-on: macos-latest\n\n        strategy:\n            matrix:\n                cpp_compiler: [clang++]\n\n        steps:\n        - uses: actions/checkout@v6\n        - name: Cache Scintilla\n          id: cache-scintilla\n          uses: actions/cache@v5\n          with:\n            path: scintilla\n            key: ${{ runner.os }}-scintilla\n        - name: Install Scintilla source\n          if: steps.cache-scintilla.outputs.cache-hit != 'true'\n          run: |\n              (mkdir scintilla)\n              (cd .. && wget --no-verbose https://www.scintilla.org/scintilla500.zip)\n              (unzip ../scintilla500.zip -d scintilla)\n        - name: Copy Scintilla\n          run: |\n              (cp -r scintilla/scintilla/ ../scintilla)\n        - name: Unit Test\n          run: (cd test/unit && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) test)\n        - name: Build Lexilla\n          run: (cd src && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN))\n        - uses: actions/upload-artifact@v6\n          with:\n              name: liblexilla.dylib\n              path: bin/liblexilla.dylib\n        - name: Test lexing and folding\n          run: (cd test && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) test)\n        - name: Check metadata\n          run: |\n              (cd test/Metadata && make CXX=${{matrix.cpp_compiler}})\n              (cd test/Metadata && ./Metadata -check)\n        - name: CheckLexilla C Example\n          run: (cd examples/CheckLexilla && make DEBUG=1 --jobs=$(getconf _NPROCESSORS_ONLN) check)\n        - name: SimpleLexer Example\n          run: (cd examples/SimpleLexer && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) check)\n"
  },
  {
    "path": ".github/workflows/build-check-win32.yml",
    "content": "name: \"Build and check Lexilla on Win32 with Visual C++\"\n\non: [push]\n\njobs:\n    # Compile for amd64 and cross-compile for arm64. Tests run only for amd64.\n    build:\n\n        runs-on: windows-latest\n\n        strategy:\n          matrix:\n            arch:\n              - amd64\n              - amd64_arm64\n        env:\n          TEST: ${{ matrix.arch == 'amd64' && 'test' || '' }}\n        steps:\n        - uses: actions/checkout@v6\n        - name: Preparing nmake\n          uses: ilammy/msvc-dev-cmd@v1\n          with:\n            arch: ${{ matrix.arch }}\n        - name: Cache Scintilla\n          id: cache-scintilla\n          uses: actions/cache@v5\n          with:\n            path: scintilla\n            key: ${{ runner.os }}-scintilla\n        - name: Install Scintilla source\n          if: steps.cache-scintilla.outputs.cache-hit != 'true'\n          run: |\n              pwd\n              New-Item -Name \"scintilla\" -Type Directory -Force\n              cd scintilla\n              curl --fail --location --show-error --retry 3 -O https://www.scintilla.org/scintilla500.zip\n              ls\n              7z x scintilla500.zip\n              cd ..\n        - name: Copy Scintilla\n          run: |\n              xcopy /s scintilla\\scintilla\\ ..\\scintilla\\\n        - name: Unit Test\n          run: |\n              cd test/unit\n              nmake -f test.mak DEBUG=1 $env:TEST\n              cd ../..\n        - name: Build Lexilla\n          run: |\n              cd src\n              nmake -f lexilla.mak DEBUG=1\n              cd ..\n        - uses: actions/upload-artifact@v6\n          with:\n              name: lexilla${{ matrix.arch == 'amd64_arm64' && '-arm64' || '' }}.dll\n              path: bin/lexilla.dll\n        - name: Test lexing and folding\n          run: |\n              cd test\n              nmake -f testlexers.mak DEBUG=1 $env:TEST\n              cd ..\n        - name: Check metadata\n          if: matrix.arch == 'amd64'\n          run: |\n              cd test/Metadata\n              cl Metadata.cxx ../../access/LexillaAccess.cxx -EHsc -std:c++17 -I ../../include -I ../../access -I ../../../scintilla/include -Fe: Metadata\n              ./Metadata -check\n              cd ../..\n        - name: CheckLexilla C Example\n          if: matrix.arch == 'amd64'\n          run: |\n              cd examples/CheckLexilla\n              cl -MP CheckLexilla.c -I ../../include -Fe: CheckLexilla\n              .\\CheckLexilla.exe\n              cd ../..\n        - name: SimpleLexer Example\n          run: |\n              cd examples/SimpleLexer\n              cl -MP -std:c++17 -EHsc -LD -I ../../../scintilla/include -I ../../include -I ../../lexlib SimpleLexer.cxx ../../lexlib/*.cxx\n              cd ../..\n"
  },
  {
    "path": ".github/workflows/build-check.yml",
    "content": "name: \"Build and check Lexilla on Linux\"\n\non: [push]\n\njobs:\n    build:\n\n        runs-on: ubuntu-latest\n\n        strategy:\n            matrix:\n                cpp_compiler: [g++, clang++]\n\n        steps:\n        - uses: actions/checkout@v6\n        - name: Cache Scintilla\n          id: cache-scintilla\n          uses: actions/cache@v5\n          with:\n            path: scintilla\n            key: ${{ runner.os }}-scintilla\n        - name: Install Scintilla source\n          if: steps.cache-scintilla.outputs.cache-hit != 'true'\n          run: |\n              (mkdir scintilla)\n              (cd .. && wget --no-verbose https://www.scintilla.org/scintilla500.zip)\n              (unzip ../scintilla500.zip -d scintilla)\n        - name: Copy Scintilla\n          run: |\n              (cp -r scintilla/scintilla/ ../scintilla)\n        - name: Unit Test\n          run: (cd test/unit && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) test)\n        - name: Build Lexilla\n          run: (cd src && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN))\n        - uses: actions/upload-artifact@v6\n          with:\n              name: liblexilla-${{matrix.cpp_compiler}}.so\n              path: bin/liblexilla.so\n              overwrite: true\n        - name: Test lexing and folding\n          run: (cd test && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) test)\n        - name: Check metadata\n          run: |\n              (cd test/Metadata && make CXX=${{matrix.cpp_compiler}})\n              (cd test/Metadata && ./Metadata -check)\n        - name: CheckLexilla C Example\n          run: (cd examples/CheckLexilla && make DEBUG=1 --jobs=$(getconf _NPROCESSORS_ONLN) check)\n        - name: SimpleLexer Example\n          run: (cd examples/SimpleLexer && make DEBUG=1 CXX=${{matrix.cpp_compiler}} --jobs=$(getconf _NPROCESSORS_ONLN) check)\n"
  },
  {
    "path": ".gitignore",
    "content": "*.o\n*.a\n*.lib\n*.obj\n*.iobj\n__pycache__\n*.pyc\n*.dll\n*.so\n*.dylib\n*.framework\n*.pyd\n*.exe\n*.exp\n*.lib\n*.pdb\n*.ipdb\n*.res\n*.bak\n*.sbr\n*.suo\n*.aps\n*.sln\n*.vcxproj.*\n*.idb\n*.bsc\n*.intermediate.manifest\n*.lastbuildstate\n*.nativecodeanalysis.xml\n*.cache\n*.ilk\n*.ncb\n*.tlog\n*.sdf\ngtk/*.plist\nwin32/*.plist\n*.opt\n*.plg\n*.pbxbtree\n*.mode1v3\n*.pbxuser\n*.pbproj\n*.tgz\n*.log\n*.xcbkptlist\n*.xcuserstate\nxcuserdata/\n*.xcsettings\nxcschememanagement.plist\n.DS_Store\ntest/TestLexers\nRelease\nDebug\nx64\nARM64\ncocoa/build\ncocoa/ScintillaFramework/build\ncocoa/ScintillaTest/build\nmacosx/SciTest/build\n*.cppcheck\n*.pro.user\n.qmake.stash\ncov-int\n.vs\nmeson-private\nmeson-logs\nbuild.ninja\n.ninja*\ncompile_commands.json\n.vscode/\nVTune Profiler Results/\n"
  },
  {
    "path": ".travis.yml",
    "content": "# Build Lexilla with gcc and clang on Linux, macOS, and Windows\r\n# Test Lexilla with gcc and clang on Linux and macOS \r\n# Windows has older versions of libraries so can't compile std::filesystem\r\n# with gcc or std::string::starts_with with clang.\r\n# On macOS, gcc is a synonym for clang so exclude gcc.\r\nos:\r\n - linux\r\n - osx\r\n - windows\r\n\r\ndist: focal\r\n\r\nosx_image: xcode12.3\r\n\r\nlanguage: cpp\r\n\r\njobs:\r\n  exclude:\r\n  - os: osx\r\n    compiler: gcc\r\n\r\ninstall:\r\n - cd ..\r\n - wget --no-verbose https://www.scintilla.org/scintilla500.zip\r\n - if [ \"$TRAVIS_OS_NAME\" = \"windows\" ]; then 7z x scintilla500.zip ; else unzip scintilla500.zip ; fi\r\n - cd lexilla\r\n\r\ncompiler:\r\n - gcc\r\n - clang\r\n\r\nscript:\r\n - if [ \"$TRAVIS_OS_NAME\" = \"windows\" ]; then MAKER=\"mingw32-make windir=1\" ; else MAKER=\"make\" ; fi\r\n - (cd src && $MAKER DEBUG=1)\r\n - cd test\r\n - if [ \"$TRAVIS_OS_NAME\" != \"windows\" ]; then make DEBUG=1 test ; fi\r\n - (cd unit && $MAKER DEBUG=1 test)\r\n - cd ..\r\n - cd examples\r\n - (cd CheckLexilla && $MAKER DEBUG=1 check)\r\n - (cd SimpleLexer && $MAKER DEBUG=1 check)\r\n - cd ..\r\n"
  },
  {
    "path": "CONTRIBUTING",
    "content": "Lexilla is on GitHub at https://github.com/ScintillaOrg/lexilla\r\n\r\nBugs, fixes and features should be posted to the Issue Tracker\r\nhttps://github.com/ScintillaOrg/lexilla/issues\r\n\r\nAI-generated code and issues are often low quality and difficult to understand\r\nso should not be posted.\r\n\r\nPatches should include test cases. Add a test case file in \r\nlexilla/test/examples/<language> and run the test program in \r\nlexilla/test.\r\nThe result will be new files with \".styled.new\" and \".folded.new\"\r\nappended containing lexing or folding results.\r\nFor lexing, there are brace surrounded style numbers for each style\r\nstart as markup:\r\n{5}import{0} {11}contextlib{0}\r\n\r\nFor folding, there are 4 columns of folding results preceding the example text:\r\n 2 400   0 + --[[ coding:UTF-8\r\n 0 402   0 | comment ]]\r\nSee the test/README file for more explanation of the folding results.\r\n\r\nTo build lexilla and the tests with gcc there are Windows batch\r\nand Unix shell files scripts/RunTest.bat scripts/RunTest.sh.\r\nCheck the result of the .new files and, if correct, rename replacing\r\n\".styled.new\" with \".styled\" and \".folded.new\" with \".folded\".\r\nRun the tests again and success should be reported.\r\nInclude the .styled and .folded files in the patch.\r\nIncluding test cases ensures that the change won't be undone by\r\nother changes in the future and clarifies the intentions of the author.\r\n\r\nEither send unified diffs (or patch files) or zip archives with whole files.\r\nMercurial/Git patch files are best as they include author information and commit\r\nmessages.\r\n\r\nQuestions should go to the scintilla-interest mailing list\r\nhttps://groups.google.com/forum/#!forum/scintilla-interest\r\n\r\nCode should follow the guidelines at\r\nhttps://www.scintilla.org/SciCoding.html\r\n\r\nLexilla is on GitHub so use its facilities rather than SourceForge which is\r\nthe home of Scintilla.\r\nThe neilh @ scintilla.org account receives much spam and is only checked\r\noccasionally. Almost all Scintilla mail should go to the mailing list.\r\n"
  },
  {
    "path": "License.txt",
    "content": "License for Lexilla, Scintilla, and SciTE\n\nCopyright 1998-2021 by Neil Hodgson <neilh@scintilla.org>\n\nAll Rights Reserved\n\nPermission to use, copy, modify, and distribute this software and its\ndocumentation for any purpose and without fee is hereby granted,\nprovided that the above copyright notice appear in all copies and that\nboth that copyright notice and this permission notice appear in\nsupporting documentation.\n\nNEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS\nSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY\nSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\nWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\nTORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE\nOR PERFORMANCE OF THIS SOFTWARE."
  },
  {
    "path": "README",
    "content": "README for Lexilla library.\r\n\r\nThe Lexilla library contains a set of lexers and folders that provides support for\r\nprogramming, mark-up, and data languages for the Scintilla source code editing\r\ncomponent.\r\n\r\nLexilla is made available as both a shared library and static library.\r\nThe shared library is called liblexilla.so / liblexilla.dylib / lexilla.dll on Linux / macOS /\r\nWindows.\r\nThe static library is called liblexilla.a when built with GCC or Clang and liblexilla.lib\r\nwhen built with MSVC.\r\n\r\nLexilla is developed on Windows, Linux, and macOS and requires a C++17 compiler.\r\nIt may work on other Unix platforms like BSD but that is not a development focus.\r\nMSVC 2019.4, GCC 9.0, Clang 9.0, and Apple Clang 11.0 are known to work.\r\n\r\nMSVC is only available on Windows.\r\n\r\nGCC and Clang work on Windows and Linux.\r\n\r\nOn macOS, only Apple Clang is available.\r\n\r\nLexilla requires some headers from Scintilla to build and expects a directory named\r\n\"scintilla\" containing a copy of Scintilla 5+ to be a peer of the Lexilla top level\r\ndirectory conventionally called \"lexilla\".\r\n\r\nTo use GCC, run lexilla/src/makefile:\r\n\tmake\r\n\r\nTo use Clang, run lexilla/src/makefile:\r\n\tmake CLANG=1\r\nOn macOS, CLANG is set automatically so this can just be\r\n\tmake\r\n\r\nTo use MSVC, run lexilla/src/lexilla.mak:\r\n\tnmake -f lexilla.mak\r\n\r\nTo build a debugging version of the library, add DEBUG=1 to the command:\r\n\tmake DEBUG=1\r\n\t\r\nThe built libraries are copied into lexilla/bin.\r\n\r\nLexilla relies on a list of lexers from the lexilla/lexers directory. If any changes are\r\nmade to the set of lexers then source and build files can be regenerated with the\r\nlexilla/scripts/LexillaGen.py script which requires Python 3 and is tested with 3.7+.\r\nUnix:\r\n\tpython3 LexillaGen.py\r\nWindows:\r\n\tpyw LexillaGen.py\r\n"
  },
  {
    "path": "access/LexillaAccess.cxx",
    "content": "// SciTE - Scintilla based Text Editor\n/** @file LexillaAccess.cxx\n ** Interface to loadable lexers.\n ** Maintains a list of lexer library paths and CreateLexer functions.\n ** If list changes then load all the lexer libraries and find the functions.\n ** When asked to create a lexer, call each function until one succeeds.\n **/\n// Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <set>\n\n#if !defined(_WIN32)\n#include <dlfcn.h>\n#else\n#include <windows.h>\n#endif\n\n#include \"ILexer.h\"\n\n#include \"Lexilla.h\"\n\n#include \"LexillaAccess.h\"\n\nnamespace {\n\n#if defined(_WIN32)\nusing Function = FARPROC;\nusing Module = HMODULE;\nconstexpr const char *pathSeparator = \"\\\\\";\n#else\nusing Function = void *;\nusing Module = void *;\nconstexpr const char *pathSeparator = \"/\";\n#endif\n\n/// Generic function to convert from a Function(void* or FARPROC) to a function pointer.\n/// This avoids undefined and conditionally defined behaviour.\ntemplate<typename T>\nT FunctionPointer(Function function) noexcept {\n\tstatic_assert(sizeof(T) == sizeof(function));\n\tT fp {};\n\tmemcpy(&fp, &function, sizeof(T));\n\treturn fp;\n}\n\n#if defined(_WIN32)\n\nstd::wstring WideStringFromUTF8(std::string_view sv) {\n\tconst int sLength = static_cast<int>(sv.length());\n\tconst int cchWide = ::MultiByteToWideChar(CP_UTF8, 0, sv.data(), sLength, nullptr, 0);\n\tstd::wstring sWide(cchWide, 0);\n\t::MultiByteToWideChar(CP_UTF8, 0, sv.data(), sLength, sWide.data(), cchWide);\n\treturn sWide;\n}\n\n#endif\n\n// Turn off deprecation checks as LexillaAccess deprecates its wrapper over\n// the deprecated LexerNameFromID. Thus use within LexillaAccess is intentional.\n#if defined(__GNUC__) || defined(__clang__)\n#pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#else\n#pragma warning(disable: 4996)\n#endif\n\nstd::string directoryLoadDefault;\nstd::string lastLoaded;\n\nstruct LexLibrary {\n\tLexilla::CreateLexerFn fnCL;\n\tLexilla::LexerNameFromIDFn fnLNFI;\n\tLexilla::GetLibraryPropertyNamesFn fnGLPN;\n\tLexilla::SetLibraryPropertyFn fnSLP;\n\tstd::string nameSpace;\n};\nstd::vector<LexLibrary> libraries;\n\nstd::vector<std::string> lexers;\nstd::vector<std::string> libraryProperties;\n\nFunction FindSymbol(Module m, const char *symbol) noexcept {\n#if defined(_WIN32)\n\treturn ::GetProcAddress(m, symbol);\n#else\n\treturn dlsym(m, symbol);\n#endif\n}\n\nLexilla::CreateLexerFn pCreateLexerDefault = nullptr;\n\nbool NameContainsDot(std::string_view path) noexcept {\n\tfor (std::string_view::const_reverse_iterator it = path.crbegin();\n\t     it != path.crend(); ++it) {\n\t\tif (*it == '.')\n\t\t\treturn true;\n\t\tif (*it == '/' || *it == '\\\\')\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nconstexpr bool HasPrefix(std::string_view s, std::string_view prefix) noexcept {\n\treturn (s.size() >= prefix.size()) && (prefix == s.substr(0, prefix.size()));\n}\n\n}\n\nvoid Lexilla::SetDefault(CreateLexerFn pCreate) noexcept {\n\tpCreateLexerDefault = pCreate;\n}\n\nvoid Lexilla::SetDefaultDirectory(std::string_view directory) {\n\tdirectoryLoadDefault = directory;\n}\n\nbool Lexilla::Load(std::string_view sharedLibraryPaths) {\n\tif (sharedLibraryPaths == lastLoaded) {\n\t\treturn !libraries.empty();\n\t}\n\n\tstd::string_view paths = sharedLibraryPaths;\n\tlexers.clear();\n\n\tlibraries.clear();\n\twhile (!paths.empty()) {\n\t\tconst size_t separator = paths.find_first_of(';');\n\t\tstd::string path(paths.substr(0, separator));\n\t\tif (separator == std::string::npos) {\n\t\t\tpaths.remove_prefix(paths.size());\n\t\t} else {\n\t\t\tpaths.remove_prefix(separator + 1);\n\t\t}\n\t\tif (path == \".\") {\n\t\t\tif (directoryLoadDefault.empty()) {\n\t\t\t\tpath = \"\";\n\t\t\t} else {\n\t\t\t\tpath = directoryLoadDefault;\n\t\t\t\tpath += pathSeparator;\n\t\t\t}\n\t\t\tpath += LEXILLA_LIB;\n\t\t}\n\t\tif (!NameContainsDot(path)) {\n\t\t\t// No '.' in name so add extension\n\t\t\tpath.append(LEXILLA_EXTENSION);\n\t\t}\n#if defined(_WIN32)\n\t\t// Convert from UTF-8 to wide characters\n\t\tstd::wstring wsPath = WideStringFromUTF8(path);\n\t\tModule lexillaDL = ::LoadLibraryW(wsPath.c_str());\n#else\n\t\tModule lexillaDL = dlopen(path.c_str(), RTLD_LAZY);\n#endif\n\t\tif (lexillaDL) {\n\t\t\tGetLexerCountFn fnLexerCount = FunctionPointer<GetLexerCountFn>(\n\t\t\t\tFindSymbol(lexillaDL, LEXILLA_GETLEXERCOUNT));\n\t\t\tGetLexerNameFn fnLexerName = FunctionPointer<GetLexerNameFn>(\n\t\t\t\tFindSymbol(lexillaDL, LEXILLA_GETLEXERNAME));\n\t\t\tif (fnLexerCount && fnLexerName) {\n\t\t\t\tconst int nLexers = fnLexerCount();\n\t\t\t\tfor (int i = 0; i < nLexers; i++) {\n\t\t\t\t\tconstexpr size_t lengthName = 200;\n\t\t\t\t\tchar name[lengthName]{};\n\t\t\t\t\tfnLexerName(i, name, sizeof(name));\n\t\t\t\t\tlexers.emplace_back(name);\n\t\t\t\t}\n\t\t\t}\n\t\t\tCreateLexerFn fnCL = FunctionPointer<CreateLexerFn>(\n\t\t\t\tFindSymbol(lexillaDL, LEXILLA_CREATELEXER));\n\t\t\tLexerNameFromIDFn fnLNFI = FunctionPointer<LexerNameFromIDFn>(\n\t\t\t\tFindSymbol(lexillaDL, LEXILLA_LEXERNAMEFROMID));\n\t\t\tGetLibraryPropertyNamesFn fnGLPN = FunctionPointer<GetLibraryPropertyNamesFn>(\n\t\t\t\tFindSymbol(lexillaDL, LEXILLA_GETLIBRARYPROPERTYNAMES));\n\t\t\tSetLibraryPropertyFn fnSLP = FunctionPointer<SetLibraryPropertyFn>(\n\t\t\t\tFindSymbol(lexillaDL, LEXILLA_SETLIBRARYPROPERTY));\n\t\t\tGetNameSpaceFn fnGNS = FunctionPointer<GetNameSpaceFn>(\n\t\t\t\tFindSymbol(lexillaDL, LEXILLA_GETNAMESPACE));\n\t\t\tstd::string nameSpace;\n\t\t\tif (fnGNS) {\n\t\t\t\tnameSpace = fnGNS();\n\t\t\t\tnameSpace += LEXILLA_NAMESPACE_SEPARATOR;\n\t\t\t}\n\t\t\tLexLibrary lexLib {\n\t\t\t\tfnCL,\n\t\t\t\tfnLNFI,\n\t\t\t\tfnGLPN,\n\t\t\t\tfnSLP,\n\t\t\t\tnameSpace\n\t\t\t};\n\t\t\tlibraries.push_back(lexLib);\n\t\t}\n\t}\n\tlastLoaded = sharedLibraryPaths;\n\n\tstd::set<std::string> nameSet;\n\tfor (const LexLibrary &lexLib : libraries) {\n\t\tif (lexLib.fnGLPN) {\n\t\t\tconst char *cpNames = lexLib.fnGLPN();\n\t\t\tif (cpNames) {\n\t\t\t\tstd::string_view names = cpNames;\n\t\t\t\twhile (!names.empty()) {\n\t\t\t\t\tconst size_t separator = names.find_first_of('\\n');\n\t\t\t\t\tstd::string name(names.substr(0, separator));\n\t\t\t\t\tnameSet.insert(name);\n\t\t\t\t\tif (separator == std::string::npos) {\n\t\t\t\t\t\tnames.remove_prefix(names.size());\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnames.remove_prefix(separator + 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Standard Lexilla does not have any properties so can't be added to set.\n\tlibraryProperties = std::vector<std::string>(nameSet.begin(), nameSet.end());\n\n\treturn !libraries.empty();\n}\n\nScintilla::ILexer5 *Lexilla::MakeLexer(std::string_view languageName) {\n\tstd::string sLanguageName(languageName);\t// Ensure NUL-termination\n\t// First, try to match namespace then name suffix\n\tfor (const LexLibrary &lexLib : libraries) {\n\t\tif (lexLib.fnCL && !lexLib.nameSpace.empty()) {\n\t\t\tif (HasPrefix(languageName, lexLib.nameSpace)) {\n\t\t\t\tScintilla::ILexer5 *pLexer = lexLib.fnCL(sLanguageName.substr(lexLib.nameSpace.size()).c_str());\n\t\t\t\tif (pLexer) {\n\t\t\t\t\treturn pLexer;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// If no match with namespace, try to just match name\n\tfor (const LexLibrary &lexLib : libraries) {\n\t\tif (lexLib.fnCL) {\n\t\t\tScintilla::ILexer5 *pLexer = lexLib.fnCL(sLanguageName.c_str());\n\t\t\tif (pLexer) {\n\t\t\t\treturn pLexer;\n\t\t\t}\n\t\t}\n\t}\n\tif (pCreateLexerDefault) {\n\t\treturn pCreateLexerDefault(sLanguageName.c_str());\n\t}\n#if defined(LEXILLA_STATIC)\n\tScintilla::ILexer5 *pLexer = CreateLexer(sLanguageName.c_str());\n\tif (pLexer) {\n\t\treturn pLexer;\n\t}\n#endif\n\treturn nullptr;\n}\n\nstd::vector<std::string> Lexilla::Lexers() {\n\treturn lexers;\n}\n\nstd::string Lexilla::NameFromID(int identifier) {\n\tfor (const LexLibrary &lexLib : libraries) {\n\t\tif (lexLib.fnLNFI) {\n\t\t\tconst char *name = lexLib.fnLNFI(identifier);\n\t\t\tif (name) {\n\t\t\t\treturn name;\n\t\t\t}\n\t\t}\n\t}\n\treturn {};\n}\n\nstd::vector<std::string> Lexilla::LibraryProperties() {\n\treturn libraryProperties;\n}\n\nvoid Lexilla::SetProperty(const char *key, const char *value) {\n\tfor (const LexLibrary &lexLib : libraries) {\n\t\tif (lexLib.fnSLP) {\n\t\t\tlexLib.fnSLP(key, value);\n\t\t}\n\t}\n\t// Standard Lexilla does not have any properties so don't set.\n}\n"
  },
  {
    "path": "access/LexillaAccess.h",
    "content": "// SciTE - Scintilla based Text Editor\n/** @file LexillaAccess.h\n ** Interface to loadable lexers.\n ** This does not depend on SciTE code so can be copied out into other projects.\n **/\n// Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef LEXILLAACCESS_H\n#define LEXILLAACCESS_H\n\nnamespace Lexilla {\n\n// Directory to load default Lexilla from, commonly the directory of the application.\nvoid SetDefaultDirectory(std::string_view directory);\n\n// Specify CreateLexer when statically linked so no hard dependency in LexillaAccess\n// so it doesn't have to be built in two forms - static and dynamic.\nvoid SetDefault(CreateLexerFn pCreate) noexcept;\n\n// sharedLibraryPaths is a ';' separated list of shared libraries to load.\n// On Win32 it is treated as UTF-8 and on Unix it is passed to dlopen directly.\n// Return true if any shared libraries are loaded.\nbool Load(std::string_view sharedLibraryPaths);\n\nScintilla::ILexer5 *MakeLexer(std::string_view languageName);\n\nstd::vector<std::string> Lexers();\n[[deprecated]] std::string NameFromID(int identifier);\nstd::vector<std::string> LibraryProperties();\nvoid SetProperty(const char *key, const char *value);\n\n}\n\n#endif\n"
  },
  {
    "path": "access/README",
    "content": "README for access directory.\r\n\r\nLexillaAccess is a module that simplifies using multiple libraries that follow the Lexilla protocol.\r\n\r\nIt can be compiled into a Lexilla client application.\r\n\r\nApplications with complex needs can copy the code and customise it to meet their requirements.\r\n\r\nThis module is not meant to be compiled into Lexilla.\r\n"
  },
  {
    "path": "bin/empty.txt",
    "content": "This empty files ensures that the directory is created."
  },
  {
    "path": "cppcheck.suppress",
    "content": "// File to suppress cppcheck warnings for files that will not be fixed.\r\n// Does not suppress warnings where an additional occurrence of the warning may be of interest.\r\n// Configured for cppcheck 2.20\r\n\r\n// Just a report of how many checkers are run\r\ncheckersReport\r\n\r\n// This just warns that cppcheck isn't exhaustive and it still appears in exhaustive mode\r\nnormalCheckLevelMaxBranches\r\n\r\n// Coding style is to use assignments in constructor when there are many\r\n// members to initialize or the initialization is complex or has comments.\r\nuseInitializationList\r\n\r\n// These may be interesting but its not clear without examining each instance closely\r\n// Would have to ensure that any_of/all_of has same early/late exits as current code and\r\n// produces same result on empty collections\r\nuseStlAlgorithm\r\n\r\n// Common for lexer object destructors\r\nmissingOverride\r\n\r\n// Some non-explicit constructors are used for conversions or are private to lexers\r\nnoExplicitConstructor\r\n\r\n// The performance cost of by-value passing is often small and using a reference decreases\r\n// code legibility.\r\npassedByValue\r\n\r\n// cppcheck 2.11 can't find system headers on Win32.\r\nmissingIncludeSystem\r\n\r\n// Passing temporary string into hidden object creator functions: they do not hold the argument\r\nreturnDanglingLifetime:lexilla/access/LexillaAccess.cxx\r\n\r\n// Used from other projects\r\nunusedFunction:lexilla/access/LexillaAccess.cxx\r\nunusedFunction:lexilla/src/Lexilla.cxx\r\n\r\n// cppcheck 2.11 limits checking of complex functions unless --check-level=exhaustive but that\r\n// only finds one false issue in LexRuby\r\ncheckLevelNormal:lexilla/lexers/LexBash.cxx\r\ncheckLevelNormal:lexilla/lexers/LexCPP.cxx\r\ncheckLevelNormal:lexilla/lexers/LexHTML.cxx\r\ncheckLevelNormal:lexilla/lexers/LexPerl.cxx\r\ncheckLevelNormal:lexilla/lexers/LexRuby.cxx\r\n\r\n// Physically but not logically const.\r\nconstVariablePointer:lexilla/examples/CheckLexilla/CheckLexilla.c\r\n\r\n// cppcheck appears to be incorrectly determining control flow: target_end is used after write\r\nunreadVariable:lexilla/lexers/LexRuby.cxx\r\n\r\n// Suppress most lexer warnings since the lexers are maintained by others\r\nredundantCondition:lexilla/lexers/LexA68k.cxx\r\nconstParameterReference:lexilla/lexers/LexAbaqus.cxx\r\nconstParameterReference:lexilla/lexers/LexAda.cxx\r\nconstParameterReference:lexilla/lexers/LexAsciidoc.cxx\r\nconstParameterCallback:lexilla/lexers/LexAsn1.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexAU3.cxx\r\nshadowVariable:lexilla/lexers/LexAU3.cxx\r\nconstParameterReference:lexilla/lexers/LexBaan.cxx\r\nunreadVariable:lexilla/lexers/LexBaan.cxx\r\nvariableScope:lexilla/lexers/LexBaan.cxx\r\nconstParameterPointer:lexilla/lexers/LexBaan.cxx\r\nconstParameterReference:lexilla/lexers/LexBash.cxx\r\nvariableScope:lexilla/lexers/LexBash.cxx\r\nconstVariable:lexilla/lexers/LexBasic.cxx\r\nconstParameterReference:lexilla/lexers/LexBullant.cxx\r\nconstParameterReference:lexilla/lexers/LexCLW.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexCLW.cxx\r\nvariableScope:lexilla/lexers/LexCmake.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexCmake.cxx\r\nconstParameterReference:lexilla/lexers/LexCmake.cxx\r\nconstParameterReference:lexilla/lexers/LexCOBOL.cxx\r\nconstVariablePointer:lexilla/lexers/LexCOBOL.cxx\r\nconstParameterReference:lexilla/lexers/LexCoffeeScript.cxx\r\nconstParameterPointer:lexilla/lexers/LexCoffeeScript.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexCoffeeScript.cxx\r\nconstVariableReference:lexilla/lexers/LexConf.cxx\r\nconstParameterReference:lexilla/lexers/LexCPP.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexCPP.cxx\r\nvariableScope:lexilla/lexers/LexCSS.cxx\r\nconstVariablePointer:lexilla/lexers/LexCSS.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexDataflex.cxx\r\nconstParameterReference:lexilla/lexers/LexDataflex.cxx\r\nvariableScope:lexilla/lexers/LexDataflex.cxx\r\nconstParameterReference:lexilla/lexers/LexDart.cxx\r\nfunctionStatic:lexilla/lexers/LexDart.cxx\r\nfunctionStatic:lexilla/lexers/LexDMIS.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexECL.cxx\r\nvariableScope:lexilla/lexers/LexECL.cxx\r\nconstParameter:lexilla/lexers/LexEDIFACT.cxx\r\nconstParameterPointer:lexilla/lexers/LexEDIFACT.cxx\r\nfunctionStatic:lexilla/lexers/LexEDIFACT.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexEiffel.cxx\r\nvariableScope:lexilla/lexers/LexErlang.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexErlang.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexEScript.cxx\r\nconstParameter:lexilla/lexers/LexFortran.cxx\r\nconstParameterReference:lexilla/lexers/LexFortran.cxx\r\nredundantContinue:lexilla/lexers/LexFortran.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexFSharp.cxx\r\nvariableScope:lexilla/lexers/LexFSharp.cxx\r\nconstParameterReference:lexilla/lexers/LexGAP.cxx\r\nconstParameterReference:lexilla/lexers/LexGDScript.cxx\r\nvariableScope:lexilla/lexers/LexGui4Cli.cxx\r\nconstParameterReference:lexilla/lexers/LexHaskell.cxx\r\nconstParameterReference:lexilla/lexers/LexHex.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexHex.cxx\r\nconstVariable:lexilla/lexers/LexHollywood.cxx\r\nvariableScope:lexilla/lexers/LexInno.cxx\r\nconstVariableReference:lexilla/lexers/LexInno.cxx\r\nconstParameterPointer:lexilla/lexers/LexJulia.cxx\r\nconstParameterReference:lexilla/lexers/LexJulia.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexJulia.cxx\r\nunreadVariable:lexilla/lexers/LexJulia.cxx\r\nvariableScope:lexilla/lexers/LexJulia.cxx\r\nvariableScope:lexilla/lexers/LexLaTeX.cxx\r\nconstParameterReference:lexilla/lexers/LexLaTeX.cxx\r\nconstParameterReference:lexilla/lexers/LexLisp.cxx\r\nconstParameterPointer:lexilla/lexers/LexMagik.cxx\r\nconstParameterReference:lexilla/lexers/LexMagik.cxx\r\nconstParameterPointer:lexilla/lexers/LexMatlab.cxx\r\nconstParameterReference:lexilla/lexers/LexMatlab.cxx\r\nunreadVariable:lexilla/lexers/LexMatlab.cxx\r\nvariableScope:lexilla/lexers/LexMatlab.cxx\r\nvariableScope:lexilla/lexers/LexMetapost.cxx\r\nconstParameterReference:lexilla/lexers/LexModula.cxx\r\nduplicateBreak:lexilla/lexers/LexModula.cxx\r\nvariableScope:lexilla/lexers/LexModula.cxx\r\nconstParameterReference:lexilla/lexers/LexMPT.cxx\r\nvariableScope:lexilla/lexers/LexMSSQL.cxx\r\nshadowArgument:lexilla/lexers/LexMySQL.cxx\r\nconstParameterReference:lexilla/lexers/LexNim.cxx\r\nconstParameterReference:lexilla/lexers/LexNimrod.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexNimrod.cxx\r\nvariableScope:lexilla/lexers/LexNimrod.cxx\r\nfunctionStatic:lexilla/lexers/LexNix.cxx\r\nvariableScope:lexilla/lexers/LexNsis.cxx\r\nconstParameterReference:lexilla/lexers/LexNsis.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexNsis.cxx\r\nvariableScope:lexilla/lexers/LexOpal.cxx\r\nconstParameterReference:lexilla/lexers/LexOpal.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexOpal.cxx\r\nconstParameterReference:lexilla/lexers/LexOScript.cxx\r\nconstParameterReference:lexilla/lexers/LexPascal.cxx\r\nvariableScope:lexilla/lexers/LexPB.cxx\r\nconstParameterReference:lexilla/lexers/LexPerl.cxx\r\nconstVariableReference:lexilla/lexers/LexPerl.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexPerl.cxx\r\nfunctionStatic:lexilla/lexers/LexPerl.cxx\r\nconstParameterReference:lexilla/lexers/LexPLM.cxx\r\nconstParameterReference:lexilla/lexers/LexPO.cxx\r\nvariableScope:lexilla/lexers/LexPO.cxx\r\nconstVariablePointer:lexilla/lexers/LexPOV.cxx\r\nconstParameterReference:lexilla/lexers/LexPython.cxx\r\nshadowVariable:lexilla/lexers/LexPowerPro.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexPowerPro.cxx\r\nvariableScope:lexilla/lexers/LexProgress.cxx\r\nconstParameterReference:lexilla/lexers/LexProgress.cxx\r\nconstParameterReference:lexilla/lexers/LexRaku.cxx\r\nvariableScope:lexilla/lexers/LexRaku.cxx\r\nfunctionStatic:lexilla/lexers/LexRaku.cxx\r\nredundantInitialization:lexilla/lexers/LexRegistry.cxx\r\nconstParameterReference:lexilla/lexers/LexRuby.cxx\r\nconstParameterReference:lexilla/lexers/LexRust.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexScriptol.cxx\r\nconstParameterReference:lexilla/lexers/LexScriptol.cxx\r\nconstParameterReference:lexilla/lexers/LexSINEX.cxx\r\nvariableScope:lexilla/lexers/LexSINEX.cxx\r\nconstParameterPointer:lexilla/lexers/LexSmalltalk.cxx\r\nvariableScope:lexilla/lexers/LexSpecman.cxx\r\nunreadVariable:lexilla/lexers/LexSpice.cxx\r\nconstParameterReference:lexilla/lexers/LexSpice.cxx\r\nfunctionStatic:lexilla/lexers/LexSQL.cxx\r\nconstParameterReference:lexilla/lexers/LexSTTXT.cxx\r\nconstParameterReference:lexilla/lexers/LexTACL.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexTACL.cxx\r\nvariableScope:lexilla/lexers/LexTACL.cxx\r\nclarifyCalculation:lexilla/lexers/LexTADS3.cxx\r\nconstParameterReference:lexilla/lexers/LexTADS3.cxx\r\nconstParameterReference:lexilla/lexers/LexTAL.cxx\r\nvariableScope:lexilla/lexers/LexTAL.cxx\r\nconstVariableReference:lexilla/lexers/LexTCL.cxx\r\nconstParameterPointer:lexilla/lexers/LexTCMD.cxx\r\ninvalidscanf:lexilla/lexers/LexTCMD.cxx\r\nconstParameterReference:lexilla/lexers/LexTeX.cxx\r\nvariableScope:lexilla/lexers/LexTeX.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexVB.cxx\r\nconstParameterReference:lexilla/lexers/LexVerilog.cxx\r\nvariableScope:lexilla/lexers/LexVerilog.cxx\r\nbadBitmaskCheck:lexilla/lexers/LexVerilog.cxx\r\nuselessCallsSubstr:lexilla/lexers/LexVerilog.cxx\r\nduplicateCondition:lexilla/lexers/LexVerilog.cxx\r\nconstParameterReference:lexilla/lexers/LexVHDL.cxx\r\nconstVariable:lexilla/lexers/LexVHDL.cxx\r\nshadowVariable:lexilla/lexers/LexVHDL.cxx\r\nunreadVariable:lexilla/lexers/LexVHDL.cxx\r\nvariableScope:lexilla/lexers/LexVHDL.cxx\r\nunreadVariable:lexilla/lexers/LexVisualProlog.cxx\r\nvariableScope:lexilla/lexers/LexVisualProlog.cxx\r\nshiftTooManyBitsSigned:lexilla/lexers/LexVisualProlog.cxx\r\nbitwiseOnBoolean:lexilla/lexers/LexVisualProlog.cxx\r\niterateByValue:lexilla/lexers/LexVisualProlog.cxx\r\nfunctionStatic:lexilla/lexers/LexVisualProlog.cxx\r\nunreadVariable:lexilla/lexers/LexX12.cxx\r\nconstVariableReference:lexilla/lexers/LexX12.cxx\r\nconstParameterPointer:lexilla/lexers/LexX12.cxx\r\nuselessCallsSubstr:lexilla/lexers/LexX12.cxx\r\nconstParameterReference:lexilla/lexers/LexYAML.cxx\r\nknownConditionTrueFalse:lexilla/lexers/LexYAML.cxx\r\n\r\n// These are due to Accessor::IndentAmount not declaring the callback as taking a const.\r\n// Changing this could cause problems for downstream projects.\r\nconstParameterCallback:lexilla/lexers/LexEiffel.cxx\r\nconstParameterCallback:lexilla/lexers/LexGDScript.cxx\r\nconstParameterCallback:lexilla/lexers/LexPython.cxx\r\nconstParameterCallback:lexilla/lexers/LexScriptol.cxx\r\nconstParameterCallback:lexilla/lexers/LexVB.cxx\r\n\r\nconstVariableReference:lexilla/lexers/LexA68k.cxx\r\nconstVariableReference:lexilla/lexers/LexAPDL.cxx\r\nconstVariableReference:lexilla/lexers/LexASY.cxx\r\nconstVariableReference:lexilla/lexers/LexAVE.cxx\r\nconstVariableReference:lexilla/lexers/LexAVS.cxx\r\nconstVariableReference:lexilla/lexers/LexAU3.cxx\r\nconstVariableReference:lexilla/lexers/LexAsn1.cxx\r\nconstVariableReference:lexilla/lexers/LexBibTeX.cxx\r\nconstVariableReference:lexilla/lexers/LexCaml.cxx\r\nconstVariableReference:lexilla/lexers/LexCLW.cxx\r\nconstVariableReference:lexilla/lexers/LexCmake.cxx\r\nconstVariableReference:lexilla/lexers/LexCOBOL.cxx\r\nconstVariableReference:lexilla/lexers/LexCoffeeScript.cxx\r\nconstVariableReference:lexilla/lexers/LexCsound.cxx\r\nconstVariableReference:lexilla/lexers/LexCSS.cxx\r\nconstVariableReference:lexilla/lexers/LexCrontab.cxx\r\nconstVariableReference:lexilla/lexers/LexDataflex.cxx\r\nconstVariableReference:lexilla/lexers/LexDMAP.cxx\r\nconstVariableReference:lexilla/lexers/LexECL.cxx\r\nconstVariableReference:lexilla/lexers/LexEiffel.cxx\r\nconstVariableReference:lexilla/lexers/LexEScript.cxx\r\nconstVariableReference:lexilla/lexers/LexErlang.cxx\r\nconstVariableReference:lexilla/lexers/LexFlagship.cxx\r\nconstVariableReference:lexilla/lexers/LexForth.cxx\r\nconstVariableReference:lexilla/lexers/LexFortran.cxx\r\nconstVariableReference:lexilla/lexers/LexGAP.cxx\r\nconstVariableReference:lexilla/lexers/LexGui4Cli.cxx\r\nconstVariableReference:lexilla/lexers/LexKix.cxx\r\nconstVariableReference:lexilla/lexers/LexKVIrc.cxx\r\nconstVariableReference:lexilla/lexers/LexLout.cxx\r\nconstVariableReference:lexilla/lexers/LexMagik.cxx\r\nconstVariableReference:lexilla/lexers/LexMatlab.cxx\r\nconstVariableReference:lexilla/lexers/LexMetapost.cxx\r\nconstVariableReference:lexilla/lexers/LexMMIXAL.cxx\r\nconstVariableReference:lexilla/lexers/LexMSSQL.cxx\r\nconstVariableReference:lexilla/lexers/LexNsis.cxx\r\nconstVariableReference:lexilla/lexers/LexOpal.cxx\r\nconstVariableReference:lexilla/lexers/LexPOV.cxx\r\nconstVariableReference:lexilla/lexers/LexPB.cxx\r\nconstVariableReference:lexilla/lexers/LexPowerPro.cxx\r\nconstVariableReference:lexilla/lexers/LexPS.cxx\r\nconstVariableReference:lexilla/lexers/LexRebol.cxx\r\nconstVariableReference:lexilla/lexers/LexSAS.cxx\r\nconstVariableReference:lexilla/lexers/LexSML.cxx\r\nconstVariableReference:lexilla/lexers/LexSorcus.cxx\r\nconstVariableReference:lexilla/lexers/LexSpecman.cxx\r\nconstVariableReference:lexilla/lexers/LexStata.cxx\r\nconstVariableReference:lexilla/lexers/LexTACL.cxx\r\nconstVariableReference:lexilla/lexers/LexTADS3.cxx\r\nconstVariableReference:lexilla/lexers/LexTAL.cxx\r\nconstVariableReference:lexilla/lexers/LexTCMD.cxx\r\nconstVariableReference:lexilla/lexers/LexTeX.cxx\r\nconstVariableReference:lexilla/lexers/LexVHDL.cxx\r\n\r\n// Suppress everything in test example files\r\n*:lexilla/test/examples/*\r\n\r\n// Suppress everything in catch.hpp as won't be changing\r\n*:lexilla/test/unit/catch.hpp\r\n// cppcheck gives up inside catch.hpp\r\n*:lexilla/test/unit/UnitTester.cxx\r\n*:lexilla/test/unit/unitTest.cxx\r\n\r\n// cppcheck fails REQUIRE from Catch\r\ncomparisonOfFuncReturningBoolError:lexilla/test/unit/*.cxx\r\n\r\n// cppcheck fails SECTION from Catch\r\nsyntaxError:lexilla/test/unit/*.cxx\r\n\r\n// Tests often test things that are always true\r\nknownConditionTrueFalse:lexilla/test/unit/testCharacterSet.cxx\r\n\r\n// unread/unused variables and overwritten without read in tests\r\nunreadVariable:lexilla/test/unit/*.cxx\r\nunusedVariable:lexilla/test/unit/*.cxx\r\nredundantInitialization:lexilla/test/unit/*.cxx\r\n\r\n// doesn't understand cppcheck generated functions\r\nunusedFunction:lexilla/test/unit/*.cxx\r\n\r\n// argv has a standardised type\r\nconstParameter:lexilla/examples/CheckLexilla/CheckLexilla.c\r\n"
  },
  {
    "path": "delbin.bat",
    "content": "@del /S /Q *.a *.aps *.bsc *.dll *.dsw *.exe *.idb *.ilc *.ild *.ilf *.ilk *.ils *.lib *.map *.ncb *.obj *.o *.opt *.ipdb *.pdb *.plg *.res *.sbr *.tds *.exp *.tlog *.lastbuildstate >NUL:\n"
  },
  {
    "path": "doc/Lexilla.html",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta name=\"generator\" content=\"HTML Tidy, see www.w3.org\" />\n    <meta name=\"generator\" content=\"SciTE\" />\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />\n    <meta name=\"keywords\" content=\"Scintilla, SciTE, Editing Component, Text Editor\" />\n    <meta name=\"Description\"\n    content=\"www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application.\" />\n    <meta name=\"Date.Modified\" content=\"20260429\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n        .logo {\n            background: url(https://www.scintilla.org/LexillaLogo.png) no-repeat;\n            background-image: image-set(\n                        url(https://www.scintilla.org/LexillaLogo.png) 1x,\n                        url(https://www.scintilla.org/LexillaLogo2x.png) 2x  );\n            height:150px;\n        }\n        #versionlist {\n            margin: 0;\n            padding: .5em;\n            list-style-type: none;\n            color: #FFCC99;\n            background: #000000;\n        }\n        #versionlist li {\n            margin-bottom: .5em;\n        }\n        #menu {\n            margin: 0;\n            padding: .5em 0;\n            list-style-type: none;\n            font-size: larger;\n            background: #CCCCCC;\n        }\n        #menu li {\n            margin: 0;\n            padding: 0 .5em;\n            display: inline;\n        }\n    </style>\n    <script type=\"text/javascript\">\n   \tfunction IsRemote() {\n\t\tvar loc = '' + window.location;\n\t\treturn (loc.indexOf('http:')) != -1 || (loc.indexOf('https:') != -1);\n   \t}\n    </script>\n     <title>\n       Lexilla\n     </title>\n    <link rel=\"canonical\" href=\"https://scintilla.org/Lexilla.html\" />\n  </head>\n  <body bgcolor=\"#FFFFFF\" text=\"#000000\">\n    <table bgcolor=\"#000000\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n      <tr>\n        <td width=\"256\">\n        </td>\n        <td width=\"40%\" align=\"left\">\n          <font color=\"#FFCC99\" size=\"4\"> A library of language lexers for use with Scintilla</font>\n        </td>\n        <td width=\"40%\" align=\"right\">\n          <font color=\"#FFCC99\" size=\"3\">Release version 5.4.9<br />\n           Site last modified April 29 2026</font>\n        </td>\n        <td width=\"20%\">\n          &nbsp;\n        </td>\n      </tr>\n    </table>\n    <table bgcolor=\"#000000\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n      <tr>\n        <td width=\"100%\" class=\"logo\">\n          &nbsp;\n        </td>\n      </tr>\n    </table>\n    <ul id=\"versionlist\">\n      <li>Version 5.4.9 improves Assembler, C++, F#, LaTeX, Pascal, and Ruby.</li>\n      <li>Version 5.4.8 improves Batch, Forth, JavaScript, and JSON.</li>\n      <li>Version 5.4.7 adds EscapeSequence lexer escseq. Improves Errorlist, Makefile, Perl, and Progress.</li>\n      <li>Version 5.4.6 adds SINEX lexer. Improves Errorlist, Progress, and Python.</li>\n      <li>Version 5.4.5 improves Dart, Makefile, Nix, TOML, and Zig.</li>\n    </ul>\n    <ul id=\"menu\">\n      <li id=\"remote1\"><a href=\"https://www.scintilla.org/SciTEImage.html\">Screenshot</a></li>\n      <li id=\"remote2\"><a href=\"https://www.scintilla.org/LexillaDownload.html\">Download</a></li>\n      <li><a href=\"https://www.scintilla.org/LexillaDoc.html\">Documentation</a></li>\n      <li><a href=\"https://github.com/ScintillaOrg/lexilla/issues\">Bugs</a></li>\n      <li id=\"remote3\"><a href=\"https://www.scintilla.org/SciTE.html\">SciTE</a></li>\n      <li><a href=\"https://www.scintilla.org/LexillaHistory.html\">History</a></li>\n      <li><a href=\"https://www.scintilla.org/ScintillaRelated.html\">Related</a></li>\n      <li id=\"remote4\"><a href=\"https://www.scintilla.org/Privacy.html\">Privacy</a></li>\n    </ul>\n<script type=\"text/javascript\" language=\"JavaScript\"><!--\nif (!IsRemote()) { //if NOT remote...\n    document.getElementById('remote1').style.display='none';\n    document.getElementById('remote2').style.display='none';\n    document.getElementById('remote3').style.display='none';\n    document.getElementById('remote4').style.display='none';\n}\n//--></script>\n    <p>\n       <a href=\"https://www.scintilla.org/LexillaDoc.html\">Lexilla</a> is a free library of language\n       lexers that can be used with the <a href=\"https://www.scintilla.org/index.html\">Scintilla</a>\n       editing component.\n       It comes with complete source code and a <a href=\"https://www.scintilla.org/License.txt\">license</a> that\n       permits use in any free project or commercial product.\n    </p>\n    <p>\n       Originally, this functionality was incorporated inside Scintilla.\n       It has been extracted as a separate project to make it easier for contributors to work on\n       support for new languages and to fix bugs in existing lexers.\n       It also defines a protocol where projects can implement their own lexers and distribute\n       them as they wish.\n    </p>\n    <p>\n       Current development requires a recent C++ compiler that supports C++17.\n       The testing framework uses some C++20 features but the basic library only uses C++17.\n    </p>\n    <p>\n       Lexilla is currently available for Intel Win32, macOS, and Linux compatible operating\n      systems. It has been run on Windows 10, macOS 10.13+, and on Ubuntu 20.04 but is likely\n      to run on earlier systems as it has no GUI functionality.\n    </p>\n    <p>\n       You can <a href=\"https://www.scintilla.org/LexillaDownload.html\">download Lexilla.</a>\n    </p>\n    <p>\n       The source code can be downloaded via Git at GitHub\n\t<a href=\"https://github.com/ScintillaOrg/lexilla\">Lexilla project page</a>.<br />\n        <code>git clone https://github.com/ScintillaOrg/lexilla</code>\n    </p>\n    <p>Current repository status:<br />\n    <a href=\"https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml\"><img src=\"https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml/badge.svg\" /></a><br />\n    <a href=\"https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check-win32.yml\"><img src=\"https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check-win32.yml/badge.svg\" /></a><br />\n    <a href=\"https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check-macos.yml\"><img src=\"https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check-macos.yml/badge.svg\" /></a>\n    </p>\n    <p>\n       <a href=\"https://www.scintilla.org/ScintillaRelated.html\">Related sites.</a>\n    </p>\n    <p>\n       <a href=\"https://github.com/ScintillaOrg/lexilla/issues\">Bugs and other issues.</a>\n    </p>\n    <p>\n       <a href=\"https://www.scintilla.org/LexillaHistory.html\">History and contribution credits.</a>\n    </p>\n    <p>\n      Questions and comments about Lexilla should be directed to the\n      <a href=\"https://groups.google.com/forum/#!forum/scintilla-interest\">scintilla-interest</a>\n      mailing list,\n      which is for discussion of Scintilla and related projects, their bugs and future features.\n      This is a low traffic list, averaging less than 20 messages per week.\n      To avoid spam, only list members can write to the list.\n      New versions of Lexilla are announced on scintilla-interest.\n      <br />\n    </p>\n  </body>\n</html>\n\n"
  },
  {
    "path": "doc/LexillaDoc.html",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta name=\"generator\"\n    content=\"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org\" />\n    <meta name=\"generator\" content=\"SciTE\" />\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />\n\n    <title>Lexilla Documentation</title>\n    <link rel=\"canonical\" href=\"https://scintilla.org/LexillaDoc.html\" />\n\n    <style type=\"text/css\">\n<!--\n/*<![CDATA[*/\n\tCODE { font-weight: bold; font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace; }\n\tA:visited { color: blue; }\n\tA:hover { text-decoration: underline ! important; }\n\tA.message { text-decoration: none; font-weight: bold; font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace; }\n\tA.seealso { text-decoration: none; font-weight: bold; font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace; }\n\tA.toc { text-decoration: none; }\n\tA.jump { text-decoration: none; }\n\tLI.message { text-decoration: none; font-weight: bold; font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace; }\n\tH2 { background: #E0EAFF; }\n\n\ttable {\n\t\tborder: 0px;\n\t\tborder-collapse: collapse;\n\t}\n\n        div.console {\n            font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;\n            color: #008000;\n            font-weight: bold;\n            background: #F7FCF7;\n            border: 1px solid #C0D7C0;\n            margin: 0.3em 3em;\n            padding: 0.3em 0.6em;\n        }\n        span.console {\n            font-family: Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;\n            color: #008000;\n            font-weight: bold;\n            background: #F7FCF7;\n            border: 1px solid #C0D7C0;\n            margin: 0.1em 0em;\n            padding: 0.1em 0.3em;\n        }\n\n        .name {\n\t\tcolor: #B08000;\n        }\n/*]]>*/\n-->\n    </style>\n  </head>\n\n  <body bgcolor=\"#FFFFFF\" text=\"#000000\">\n    <table bgcolor=\"#000000\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"\n    summary=\"Banner\">\n      <tr>\n        <td><img src=\"SciTEIco.png\" border=\"3\" height=\"64\" width=\"64\" alt=\"Lexilla icon\" /></td>\n\n        <td><a href=\"index.html\"\n        style=\"color:white;text-decoration:none;font-size:200%\">Lexilla</a></td>\n      </tr>\n    </table>\n\n    <h1>Lexilla Documentation</h1>\n\n    <p>Last edited 21 April 2021 NH</p>\n\n    <h2>Introduction</h2>\n\n    <p>Lexilla is a library containing lexers for use with Scintilla. It can be either a static library\n    that is linked into an application or a shared library that is loaded at runtime.</p>\n\n    <p>Lexilla does not interact with the display so there is no need to compile it for a\n    particular GUI toolkit. Therefore there can be a common library shared by applications using\n    different GUI toolkits. In some circumstances there may need to be both 32-bit and 64-bit versions\n    on one system to match different applications.</p>\n\n    <p>Different extensions are commonly used for shared libraries: .so on Linux, .dylib on macOS, and .DLL on Windows.\n     </p>\n\n    <h2>The Lexilla protocol</h2>\n\n    <p>A set of functions is defined by Lexilla for use by applications. Libraries that provide these functions\n    can be used as a replacement for Lexilla or to add new lexers beyond those provided by Lexilla.</p>\n\n    <p>The Lexilla protocol is a superset of the external lexer protocol and defines these functions that may be exported from a shared library:<br />\n    <code>int <span class=\"name\">GetLexerCount</span>()</code><br />\n    <code>void <span class=\"name\">GetLexerName</span>(unsigned int index, char *name, int buflength)</code><br />\n    <code>LexerFactoryFunction <span class=\"name\">GetLexerFactory</span>(unsigned int index)</code><br />\n    <code>ILexer5 *<span class=\"name\">CreateLexer</span>(const char *name)</code><br />\n    <code>const char *<span class=\"name\">LexerNameFromID</span>(int identifier)</code><br />\n    <code>const char *<span class=\"name\">GetLibraryPropertyNames</span>()</code><br />\n    <code>void <span class=\"name\">SetLibraryProperty</span>(const char *key, const char *value)</code><br />\n    <code>const char *<span class=\"name\">GetNameSpace</span>()</code>\n    </p>\n\n    <p><span class=\"name\">ILexer5</span> is defined by Scintilla in include/ILexer.h as the interface provided by lexers which is called by Scintilla.\n    Many clients do not actually need to call methods on <span class=\"name\">ILexer5</span> - they just take the return from CreateLexer and plug it\n    straight into Scintilla so it can be treated as a machine pointer (void *).\n    </p>\n\n    <p><span class=\"name\">LexerFactoryFunction</span> is defined as a function that takes no arguments and returns an <span class=\"name\">ILexer5</span> *:\n    <code>ILexer5 *(*LexerFactoryFunction)()</code> but this can be ignored by most client code.\n    </p>\n\n    <p>The Lexilla protocol is a superset of the earlier external lexer protocol that defined the first 3 functions\n    (<span class=\"name\">GetLexerCount</span>, <span class=\"name\">GetLexerName</span>, <span class=\"name\">GetLexerFactory</span>)\n    so Lexilla can be loaded by applications that support that protocol.\n    <span class=\"name\">GetLexerFactory</span> will rarely be used now as it is easier to call <span class=\"name\">CreateLexer</span>.\n    </p>\n\n    <p><span class=\"name\">CreateLexer</span> is the main call that will create a lexer for a particular language. The returned lexer can then be\n    set as the current lexer in Scintilla by calling\n    <a class=\"seealso\" href=\"ScintillaDoc.html#SCI_SETILEXER\">SCI_SETILEXER</a>.</p>\n\n    <p><span class=\"name\">LexerNameFromID</span> is an optional function that returns the name for a lexer identifier.\n    <code>LexerNameFromID(SCLEX_CPP) &rarr; \"cpp\"</code>.\n    This is a temporary affordance to make it easier to convert applications to using Lexilla.\n    Applications should move to using lexer names instead of IDs.\n    This function is deprecated, showing warnings with some compilers, and will be removed in a future version of Lexilla.</p>\n\n    <p><span class=\"name\">SetLibraryProperty</span> and <span class=\"name\">GetLibraryPropertyNames</span>\n    are optional functions that can be\n    defined if a library requires initialisation before calling other methods.\n    For example, a lexer library that reads language definitions from XML files may require that the\n    directory containing these files be set before a call to CreateLexer.\n    <code>SetLibraryProperty(\"definitions.directory\", \"/usr/share/xeditor/language-definitions\")</code>\n    If a library implements SetLibraryProperty then it may also provide a set of valid property names with\n    GetLibraryPropertyNames that can then be used by the application to define configuration file property\n    names or user interface elements for options dialogs.</p>\n\n    <p><span class=\"name\">GetNameSpace</span> is an optional function that returns a namespace string\n    that can be used to disambiguate lexers with the same name from different providers.\n    If Lexilla and XMLLexers both provide a \"cpp\" lexer than a request for \"cpp\" may be satisfied by either but \"xmllexers.cpp\"\n    unambiguously refers to the \"cpp\" lexer from XMLLexers.</p>\n\n    <h2>Building Lexilla</h2>\n\n    <p>Before using Lexilla it must be built or downloaded.</p>\n    <p>Lexilla requires some headers from Scintilla to build and expects a directory named\n    \"scintilla\" containing a copy of Scintilla 5+ to be a peer of the Lexilla top level\n    directory conventionally called \"lexilla\".</p>\n\n    <div>To build Lexilla, in the lexilla/src directory, run make (for gcc or clang)</div>\n    <div class=\"console\">make</div>\n    <div>or nmake for MSVC</div>\n    <div class=\"console\">nmake -f lexilla.mak</div>\n    <br />\n\n    <div>After building Lexilla, its test suite can be run with make/nmake in the lexilla/test directory. For gcc or clang</div>\n    <div class=\"console\">make test</div>\n    or for MSVC<br />\n    <div class=\"console\">nmake -f testlexers.mak test</div>\n    <div>Each test case should show \"<code>Lexing ...</code>\" and errors will display a diagnostic, commonly showing\n    a difference between the actual and expected result:<br>\n    <code>C:\\u\\hg\\lexilla\\test\\examples\\python\\x.py:1: is different</code>\n    </div>\n\n    <p>There are also RunTest.sh / RunTest.bat scripts in the scripts directory to build Lexilla and then build and run the tests.\n    These both use gcc/clang, not MSVC.</p>\n\n    <p>There are Microsoft Visual C++ and Xcode projects that can be used to build Lexilla.\n    For Visual C++: src/Lexilla.vcxproj. For Xcode: src/Lexilla/Lexilla.xcodeproj.\n    There is also test/TestLexers.vcxproj to build the tests with Visual C++.</p>\n\n    <h2>Using Lexilla</h2>\n\n    <p>Definitions for using Lexilla from C and C++ are included in lexilla/include/Lexilla.h.\n    For C++, scintilla/include/ILexer.h should be included before Lexilla.h as the\n    <code>ILexer5</code> type is used.\n    For C, ILexer.h should not be included as C does not understand it and from C,\n    <code>void*</code> is used instead of <code>ILexer5*</code>.\n    </p>\n\n    <p>For many applications the main Lexilla operations are loading the Lexilla library, creating a\n    lexer and using that lexer in Scintilla.\n    Applications need to define the location (or locations) they expect\n    to find Lexilla or libraries that support the Lexilla protocol.\n    They also need to define how they request particular lexers, perhaps with a mapping from\n    file extensions to lexer names.</p>\n\n    <h3 id=\"CheckLexilla\">From C - CheckLexilla</h3>\n\n    <p>An example C program for accessing Lexilla is provided in lexilla/examples/CheckLexilla.\n    Build with <span class=\"console\">make</span> and run with <span class=\"console\">make check</span>.\n    </p>\n\n    <h3>From C++ - LexillaAccess</h3>\n\n    <p>A C++ module, LexillaAccess.cxx / LexillaAccess.h is provided in lexilla/access.\n    This can either be compiled into the application when it is sufficient\n    or the source code can be copied into the application and customized when the application has additional requirements\n    (such as checking code signatures).\n    SciTE uses LexillaAccess.</p>\n\n    <p>LexillaAccess supports loading multiple shared libraries implementing the Lexilla protocol at one time.</p>\n\n    <h3>From Qt</h3>\n\n    <p>For Qt, use either LexillaAccess from above or Qt's QLibrary class. With 'Call' defined to call Scintilla APIs.<br />\n    <code>\n#if _WIN32<br />\n&nbsp;&nbsp;&nbsp;&nbsp;typedef void *(__stdcall *CreateLexerFn)(const char *name);<br />\n#else<br />\n&nbsp;&nbsp;&nbsp;&nbsp;typedef void *(*CreateLexerFn)(const char *name);<br />\n#endif<br />\n&nbsp;&nbsp;&nbsp;&nbsp;QFunctionPointer fn = QLibrary::resolve(\"lexilla\", \"CreateLexer\");<br />\n&nbsp;&nbsp;&nbsp;&nbsp;void *lexCpp = ((CreateLexerFn)fn)(\"cpp\");<br />\n&nbsp;&nbsp;&nbsp;&nbsp;Call(SCI_SETILEXER, 0, (sptr_t)(void *)lexCpp);<br />\n    </code></p>\n\n    <p>Applications may discover the set of lexers provided by a library by first calling\n    <span class=\"name\">GetLexerCount</span> to find the number of lexers implemented in the library then looping over calling\n    <span class=\"name\">GetLexerName</span> with integers 0 to <code>GetLexerCount()-1</code>.</p>\n\n    <p>Applications may set properties on a library by calling <span class=\"name\">SetLibraryProperty</span> if provided.\n    This may be needed for initialisation so should before calling <span class=\"name\">GetLexerCount</span> or <span class=\"name\">CreateLexer</span>.\n    A set of property names may be available from <span class=\"name\">GetLibraryPropertyNames</span> if provided.\n    It returns a string pointer where the string contains a list of property names separated by '\\n'.\n    It is up to applications to define how properties are defined and persisted in its user interface\n    and configuration files.</p>\n\n    <h2>Modifying or adding lexers</h2>\n\n    <p>Lexilla can be modified or a new library created that can be used to replace or augment Lexilla.</p>\n\n    <p>Lexer libraries that provide the same functions as Lexilla may provide lexers for use by Scintilla,\n    augmenting or replacing those provided by Lexilla.\n    To allow initialisation of lexer libraries, a <code>SetLibraryProperty(const char *key, const char *value)</code>\n    may optionally be implemented. For example, a lexer library that uses XML based lexer definitions may\n    be provided with a directory to search for such definitions.\n    Lexer libraries should ignore any properties that they do not understand.\n    The set of properties supported by a lexer library is specified as a '\\n' separated list of property names by\n    an optional <code>const char *GetLibraryPropertyNames()</code> function.\n    </p>\n\n    <p>Lexilla and its contained lexers can be tested with the TestLexers program in lexilla/test.\n    Read lexilla/test/README for information on building and using TestLexers.</p>\n\n    <p>An example of a simple lexer housed in a shared library that is compatible with the\n    Lexilla protocol can be found in lexilla/examples/SimpleLexer. It is implemented in C++.\n    Build with <span class=\"console\">make</span> and check by running <a href=\"#CheckLexilla\">CheckLexilla</a> against it with\n    <span class=\"console\">make check</span>.\n    </p>\n\n  </body>\n</html>\n\n"
  },
  {
    "path": "doc/LexillaDownload.html",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta name=\"generator\" content=\"HTML Tidy, see www.w3.org\" />\n    <meta name=\"generator\" content=\"SciTE\" />\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <title>\n      Download Lexilla\n    </title>\n  </head>\n  <body bgcolor=\"#FFFFFF\" text=\"#000000\">\n    <table bgcolor=\"#000000\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n      <tr>\n        <td>\n          <img src=\"SciTEIco.png\" border=\"3\" height=\"64\" width=\"64\" alt=\"Scintilla icon\" />\n        </td>\n        <td>\n          <a href=\"index.html\" style=\"color:white;text-decoration:none\"><font size=\"5\">Download\n          Lexilla</font></a>\n        </td>\n      </tr>\n    </table>\n    <table bgcolor=\"#CCCCCC\" width=\"100%\" cellspacing=\"0\" cellpadding=\"8\" border=\"0\">\n      <tr>\n        <td>\n          <font size=\"4\"> <a href=\"https://www.scintilla.org/lexilla549.zip\">\n\tWindows</a>&nbsp;&nbsp;\n\t<a href=\"https://www.scintilla.org/lexilla549.tgz\">\n          GTK/Linux</a>&nbsp;&nbsp;\n\t</font>\n        </td>\n      </tr>\n    </table>\n    <h2>\n       Download.\n    </h2>\n    <p>\n       The <a href=\"License.txt\">license</a> for using Lexilla is similar to that of Python\n      containing very few restrictions.\n    </p>\n    <h3>\n       Release 5.4.9\n    </h3>\n    <h4>\n       Source Code\n    </h4>\n       The source code package contains all of the source code for Lexilla but no binary\n\texecutable code and is available in\n       <ul>\n       <li><a href=\"https://www.scintilla.org/lexilla549.zip\">zip format</a> (1.5M) commonly used on Windows</li>\n       <li><a href=\"https://www.scintilla.org/lexilla549.tgz\">tgz format</a> (1.1M) commonly used on Linux and compatible operating systems</li>\n       </ul>\n       Instructions for building on both Windows and Linux are included in the readme file.\n    <h4>\n       Windows Executable Code\n    </h4>\n       There is no download available containing only the Lexilla DLL.\n       However, it is included in the <a href=\"SciTEDownload.html\">SciTE\n       executable full download</a> as Lexilla.DLL.\n    <p>\n       <a href=\"SciTEDownload.html\">SciTE</a> is a good demonstration of Lexilla.\n    </p>\n    <p>\n       Previous versions can be downloaded from the <a href=\"LexillaHistory.html\">history\n      page</a>.\n    </p>\n  </body>\n</html>\n"
  },
  {
    "path": "doc/LexillaHistory.html",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta name=\"generator\" content=\"HTML Tidy, see www.w3.org\" />\n    <meta name=\"generator\" content=\"SciTE\" />\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <title>\n      Lexilla\n    </title>\n    <style type=\"text/css\">\n        table {\n            border-collapse: collapse;\n            font-size: 80%;\n        }\n        td {\n            xborder: 1px solid #1F1F1F;\n            padding: 0px 4px;\n        }\n    </style>\n  </head>\n  <body bgcolor=\"#FFFFFF\" text=\"#000000\">\n    <table bgcolor=\"#000000\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n      <tr>\n        <td>\n          <img src=\"SciTEIco.png\" border=\"3\" height=\"64\" width=\"64\" alt=\"Scintilla icon\" />\n        </td>\n        <td>\n          <a href=\"index.html\" style=\"color:white;text-decoration:none\"><font size=\"5\">Lexilla</font></a>\n        </td>\n      </tr>\n    </table>\n    <h1>History of Lexilla</h1>\n    <p>\n       Lexilla was originally code that was part of the Scintilla project.\n       Thus it shares much of the history and contributors of Scintilla before it was extracted as its own project.\n    </p>\n    <a href=\"#Releases\">Releases</a>\n    <h2>Contributors</h2>\n    <p>\n       Thanks to all the people that have contributed patches, bug reports and suggestions.\n    </p>\n    <p>\n       Source code and documentation have been contributed by\n    </p>\n    <table>\n      <tr>\n\t<td>Atsuo Ishimoto</td>\n\t<td>Mark Hammond</td>\n\t<td>Francois Le Coguiec</td>\n\t<td>Dale Nagata</td>\n      </tr><tr>\n\t<td>Ralf Reinhardt</td>\n\t<td>Philippe Lhoste</td>\n\t<td>Andrew McKinlay</td>\n\t<td>Stephan R. A. Deibel</td>\n      </tr><tr>\n\t<td>Hans Eckardt</td>\n\t<td>Vassili Bourdo</td>\n\t<td>Maksim Lin</td>\n\t<td>Robin Dunn</td>\n      </tr><tr>\n\t<td>John Ehresman</td>\n\t<td>Steffen Goeldner</td>\n\t<td>Deepak S.</td>\n\t<td><a href=\"http://www.develop.com\">DevelopMentor</a></td>\n      </tr><tr>\n\t<td>Yann Gaillard</td>\n\t<td>Aubin Paul</td>\n\t<td>Jason Diamond</td>\n\t<td>Ahmad Baitalmal</td>\n      </tr><tr>\n\t<td>Paul Winwood</td>\n\t<td>Maxim Baranov</td>\n\t<td>Ragnar Højland</td>\n\t<td>Christian Obrecht</td>\n      </tr><tr>\n\t<td>Andreas Neukoetter</td>\n\t<td>Adam Gates</td>\n\t<td>Steve Lhomme</td>\n\t<td>Ferdinand Prantl</td>\n      </tr><tr>\n\t<td>Jan Dries</td>\n\t<td>Markus Gritsch</td>\n\t<td>Tahir Karaca</td>\n\t<td>Ahmad Zawawi</td>\n      </tr><tr>\n\t<td>Laurent le Tynevez</td>\n\t<td>Walter Braeu</td>\n\t<td>Ashley Cambrell</td>\n\t<td>Garrett Serack</td>\n      </tr><tr>\n\t<td>Holger Schmidt</td>\n\t<td><a href=\"http://www.activestate.com\">ActiveState</a></td>\n\t<td>James Larcombe</td>\n\t<td>Alexey Yutkin</td>\n      </tr><tr>\n\t<td>Jan Hercek</td>\n\t<td>Richard Pecl</td>\n\t<td>Edward K. Ream</td>\n\t<td>Valery Kondakoff</td>\n      </tr><tr>\n\t<td>Smári McCarthy</td>\n\t<td>Clemens Wyss</td>\n\t<td>Simon Steele</td>\n\t<td>Serge A. Baranov</td>\n      </tr><tr>\n\t<td>Xavier Nodet</td>\n\t<td>Willy Devaux</td>\n\t<td>David Clain</td>\n\t<td>Brendon Yenson</td>\n      </tr><tr>\n\t<td><a href=\"http://www.baanboard.com\">Vamsi Potluru</a></td>\n\t<td>Praveen Ambekar</td>\n\t<td>Alan Knowles</td>\n\t<td>Kengo Jinno</td>\n      </tr><tr>\n\t<td>Valentin Valchev</td>\n\t<td>Marcos E. Wurzius</td>\n\t<td>Martin Alderson</td>\n\t<td>Robert Gustavsson</td>\n      </tr><tr>\n\t<td>José Fonseca</td>\n\t<td>Holger Kiemes</td>\n\t<td>Francis Irving</td>\n\t<td>Scott Kirkwood</td>\n      </tr><tr>\n\t<td>Brian Quinlan</td>\n\t<td>Ubi</td>\n\t<td>Michael R. Duerig</td>\n\t<td>Deepak T</td>\n      </tr><tr>\n\t<td>Don Paul Beletsky</td>\n\t<td>Gerhard Kalab</td>\n\t<td>Olivier Dagenais</td>\n\t<td>Josh Wingstrom</td>\n      </tr><tr>\n\t<td>Bruce Dodson</td>\n\t<td>Sergey Koshcheyev</td>\n\t<td>Chuan-jian Shen</td>\n\t<td>Shane Caraveo</td>\n      </tr><tr>\n\t<td>Alexander Scripnik</td>\n\t<td>Ryan Christianson</td>\n\t<td>Martin Steffensen</td>\n\t<td>Jakub Vrána</td>\n      </tr><tr>\n\t<td>The Black Horus</td>\n\t<td>Bernd Kreuss</td>\n\t<td>Thomas Lauer</td>\n\t<td>Mike Lansdaal</td>\n      </tr><tr>\n\t<td>Yukihiro Nakai</td>\n\t<td>Jochen Tucht</td>\n\t<td>Greg Smith</td>\n\t<td>Steve Schoettler</td>\n      </tr><tr>\n\t<td>Mauritius Thinnes</td>\n\t<td>Darren Schroeder</td>\n\t<td>Pedro Guerreiro</td>\n\t<td>Steven te Brinke</td>\n      </tr><tr>\n\t<td>Dan Petitt</td>\n\t<td>Biswapesh Chattopadhyay</td>\n\t<td>Kein-Hong Man</td>\n\t<td>Patrizio Bekerle</td>\n      </tr><tr>\n\t<td>Nigel Hathaway</td>\n\t<td>Hrishikesh Desai</td>\n\t<td>Sergey Puljajev</td>\n\t<td>Mathias Rauen</td>\n      </tr><tr>\n\t<td><a href=\"http://www.spaceblue.com\">Angelo Mandato</a></td>\n\t<td>Denis Sureau</td>\n\t<td>Kaspar Schiess</td>\n\t<td>Christoph Hösler</td>\n      </tr><tr>\n\t<td>João Paulo F Farias</td>\n\t<td>Ron Schofield</td>\n\t<td>Stefan Wosnik</td>\n\t<td>Marius Gheorghe</td>\n      </tr><tr>\n\t<td>Naba Kumar</td>\n\t<td>Sean O'Dell</td>\n\t<td>Stefanos Togoulidis</td>\n\t<td>Hans Hagen</td>\n      </tr><tr>\n\t<td>Jim Cape</td>\n\t<td>Roland Walter</td>\n\t<td>Brian Mosher</td>\n\t<td>Nicholas Nemtsev</td>\n      </tr><tr>\n\t<td>Roy Wood</td>\n\t<td>Peter-Henry Mander</td>\n\t<td>Robert Boucher</td>\n\t<td>Christoph Dalitz</td>\n      </tr><tr>\n\t<td>April White</td>\n\t<td>S. Umar</td>\n\t<td>Trent Mick</td>\n\t<td>Filip Yaghob</td>\n      </tr><tr>\n\t<td>Avi Yegudin</td>\n\t<td>Vivi Orunitia</td>\n\t<td>Manfred Becker</td>\n\t<td>Dimitris Keletsekis</td>\n      </tr><tr>\n\t<td>Yuiga</td>\n\t<td>Davide Scola</td>\n\t<td>Jason Boggs</td>\n\t<td>Reinhold Niesner</td>\n      </tr><tr>\n\t<td>Jos van der Zande</td>\n\t<td>Pescuma</td>\n\t<td>Pavol Bosik</td>\n\t<td>Johannes Schmid</td>\n      </tr><tr>\n\t<td>Blair McGlashan</td>\n\t<td>Mikael Hultgren</td>\n\t<td>Florian Balmer</td>\n\t<td>Hadar Raz</td>\n      </tr><tr>\n\t<td>Herr Pfarrer</td>\n\t<td>Ben Key</td>\n\t<td>Gene Barry</td>\n\t<td>Niki Spahiev</td>\n      </tr><tr>\n\t<td>Carsten Sperber</td>\n\t<td>Phil Reid</td>\n\t<td>Iago Rubio</td>\n\t<td>Régis Vaquette</td>\n      </tr><tr>\n\t<td>Massimo Corà</td>\n\t<td>Elias Pschernig</td>\n\t<td>Chris Jones</td>\n\t<td>Josiah Reynolds</td>\n      </tr><tr>\n\t<td>Robert Roessler <a href=\"http://www.rftp.com\">rftp.com</a></td>\n\t<td>Steve Donovan</td>\n\t<td>Jan Martin Pettersen</td>\n\t<td>Sergey Philippov</td>\n      </tr><tr>\n\t<td>Borujoa</td>\n\t<td>Michael Owens</td>\n\t<td>Franck Marcia</td>\n\t<td>Massimo Maria Ghisalberti</td>\n      </tr><tr>\n\t<td>Frank Wunderlich</td>\n\t<td>Josepmaria Roca</td>\n\t<td>Tobias Engvall</td>\n\t<td>Suzumizaki Kimitaka</td>\n      </tr><tr>\n\t<td>Michael Cartmell</td>\n\t<td>Pascal Hurni</td>\n\t<td>Andre</td>\n\t<td>Randy Butler</td>\n      </tr><tr>\n\t<td>Georg Ritter</td>\n\t<td>Michael Goffioul</td>\n\t<td>Ben Harper</td>\n\t<td>Adam Strzelecki</td>\n      </tr><tr>\n\t<td>Kamen Stanev</td>\n\t<td>Steve Menard</td>\n\t<td>Oliver Yeoh</td>\n\t<td>Eric Promislow</td>\n      </tr><tr>\n\t<td>Joseph Galbraith</td>\n\t<td>Jeffrey Ren</td>\n\t<td>Armel Asselin</td>\n\t<td>Jim Pattee</td>\n      </tr><tr>\n\t<td>Friedrich Vedder</td>\n\t<td>Sebastian Pipping</td>\n\t<td>Andre Arpin</td>\n\t<td>Stanislav Maslovski</td>\n      </tr><tr>\n\t<td>Martin Stone</td>\n\t<td>Fabien Proriol</td>\n\t<td>mimir</td>\n\t<td>Nicola Civran</td>\n      </tr><tr>\n\t<td>Snow</td>\n\t<td>Mitchell Foral</td>\n\t<td>Pieter Holtzhausen</td>\n\t<td>Waldemar Augustyn</td>\n      </tr><tr>\n\t<td>Jason Haslam</td>\n\t<td>Sebastian Steinlechner</td>\n\t<td>Chris Rickard</td>\n\t<td>Rob McMullen</td>\n      </tr><tr>\n\t<td>Stefan Schwendeler</td>\n\t<td>Cristian Adam</td>\n\t<td>Nicolas Chachereau</td>\n\t<td>Istvan Szollosi</td>\n      </tr><tr>\n\t<td>Xie Renhui</td>\n\t<td>Enrico Tröger</td>\n\t<td>Todd Whiteman</td>\n\t<td>Yuval Papish</td>\n      </tr><tr>\n\t<td>instanton</td>\n\t<td>Sergio Lucato</td>\n\t<td>VladVRO</td>\n\t<td>Dmitry Maslov</td>\n      </tr><tr>\n\t<td>chupakabra</td>\n\t<td>Juan Carlos Arevalo Baeza</td>\n\t<td>Nick Treleaven</td>\n\t<td>Stephen Stagg</td>\n      </tr><tr>\n\t<td>Jean-Paul Iribarren</td>\n\t<td>Tim Gerundt</td>\n\t<td>Sam Harwell</td>\n\t<td>Boris</td>\n      </tr><tr>\n\t<td>Jason Oster</td>\n\t<td>Gertjan Kloosterman</td>\n\t<td>alexbodn</td>\n\t<td>Sergiu Dotenco</td>\n      </tr><tr>\n\t<td>Anders Karlsson</td>\n\t<td>ozlooper</td>\n\t<td>Marko Njezic</td>\n\t<td>Eugen Bitter</td>\n      </tr><tr>\n\t<td>Christoph Baumann</td>\n\t<td>Christopher Bean</td>\n\t<td>Sergey Kishchenko</td>\n\t<td>Kai Liu</td>\n      </tr><tr>\n\t<td>Andreas Rumpf</td>\n\t<td>James Moffatt</td>\n\t<td>Yuzhou Xin</td>\n\t<td>Nic Jansma</td>\n      </tr><tr>\n\t<td>Evan Jones</td>\n\t<td>Mike Lischke</td>\n\t<td>Eric Kidd</td>\n\t<td>maXmo</td>\n      </tr><tr>\n\t<td>David Severwright</td>\n\t<td>Jon Strait</td>\n\t<td>Oliver Kiddle</td>\n\t<td>Etienne Girondel</td>\n      </tr><tr>\n\t<td>Haimag Ren</td>\n\t<td>Andrey Moskalyov</td>\n\t<td>Xavi</td>\n\t<td>Toby Inkster</td>\n      </tr><tr>\n\t<td>Eric Forgeot</td>\n\t<td>Colomban Wendling</td>\n\t<td>Neo</td>\n\t<td>Jordan Russell</td>\n      </tr><tr>\n\t<td>Farshid Lashkari</td>\n\t<td>Sam Rawlins</td>\n\t<td>Michael Mullin</td>\n\t<td>Carlos SS</td>\n      </tr><tr>\n\t<td>vim</td>\n\t<td>Martial Demolins</td>\n\t<td>Tino Weinkauf</td>\n\t<td>Jérôme Laforge</td>\n      </tr><tr>\n\t<td>Udo Lechner</td>\n\t<td>Marco Falda</td>\n\t<td>Dariusz Knociński</td>\n\t<td>Ben Fisher</td>\n      </tr><tr>\n\t<td>Don Gobin</td>\n\t<td>John Yeung</td>\n\t<td>Adobe</td>\n\t<td>Elizabeth A. Irizarry</td>\n      </tr><tr>\n\t<td>Mike Schroeder</td>\n\t<td>Morten MacFly</td>\n\t<td>Jaime Gimeno</td>\n\t<td>Thomas Linder Puls</td>\n      </tr><tr>\n\t<td>Artyom Zuikov</td>\n\t<td>Gerrit</td>\n\t<td>Occam's Razor</td>\n\t<td>Ben Bluemel</td>\n      </tr><tr>\n\t<td>David Wolfendale</td>\n\t<td>Chris Angelico</td>\n\t<td>Marat Dukhan</td>\n\t<td>Stefan Weil</td>\n      </tr><tr>\n\t<td>Rex Conn</td>\n\t<td>Ross McKay</td>\n\t<td>Bruno Barbieri</td>\n\t<td>Gordon Smith</td>\n      </tr><tr>\n\t<td>dimitar</td>\n\t<td>Sébastien Granjoux</td>\n\t<td>zeniko</td>\n\t<td>James Ribe</td>\n      </tr><tr>\n\t<td>Markus Nißl</td>\n\t<td>Martin Panter</td>\n\t<td>Mark Yen</td>\n\t<td>Philippe Elsass</td>\n      </tr><tr>\n\t<td>Dimitar Zhekov</td>\n\t<td>Fan Yang</td>\n\t<td>Denis Shelomovskij</td>\n\t<td>darmar</td>\n      </tr><tr>\n\t<td>John Vella</td>\n\t<td>Chinh Nguyen</td>\n\t<td>Sakshi Verma</td>\n\t<td>Joel B. Mohler</td>\n      </tr><tr>\n\t<td>Isiledhel</td>\n\t<td>Vidya Wasi</td>\n\t<td>G. Hu</td>\n\t<td>Byron Hawkins</td>\n      </tr><tr>\n\t<td>Alpha</td>\n\t<td>John Donoghue</td>\n\t<td>kudah</td>\n\t<td>Igor Shaula</td>\n      </tr><tr>\n\t<td>Pavel Bulochkin</td>\n\t<td>Yosef Or Boczko</td>\n\t<td>Brian Griffin</td>\n\t<td>Özgür Emir</td>\n      </tr><tr>\n\t<td>Neomi</td>\n\t<td>OmegaPhil</td>\n\t<td>SiegeLord</td>\n\t<td>Erik</td>\n      </tr><tr>\n\t<td>TJF</td>\n\t<td>Mark Robinson</td>\n\t<td>Thomas Martitz</td>\n\t<td>felix</td>\n      </tr><tr>\n\t<td>Christian Walther</td>\n\t<td>Ebben</td>\n\t<td>Robert Gieseke</td>\n\t<td>Mike M</td>\n      </tr><tr>\n\t<td>nkmathew</td>\n\t<td>Andreas Tscharner</td>\n\t<td>Lee Wilmott</td>\n\t<td>johnsonj</td>\n      </tr><tr>\n\t<td>Vicente</td>\n\t<td>Nick Gravgaard</td>\n\t<td>Ian Goldby</td>\n\t<td>Holger Stenger</td>\n      </tr><tr>\n\t<td>danselmi</td>\n\t<td>Mat Berchtold</td>\n\t<td>Michael Staszewski</td>\n\t<td>Baurzhan Muftakhidinov</td>\n      </tr><tr>\n\t<td>Erik Angelin</td>\n\t<td>Yusuf Ramazan Karagöz</td>\n\t<td>Markus Heidelberg</td>\n\t<td>Joe Mueller</td>\n      </tr><tr>\n\t<td>Mika Attila</td>\n\t<td>JoMazM</td>\n\t<td>Markus Moser</td>\n\t<td>Stefan Küng</td>\n      </tr><tr>\n\t<td>Jiří Techet</td>\n\t<td>Jonathan Hunt</td>\n\t<td>Serg Stetsuk</td>\n\t<td>Jordan Jueckstock</td>\n      </tr><tr>\n\t<td>Yury Dubinsky</td>\n\t<td>Sam Hocevar</td>\n\t<td>Luyomi</td>\n\t<td>Matt Gilarde</td>\n      </tr><tr>\n\t<td>Mark C</td>\n\t<td>Johannes Sasongko</td>\n\t<td>fstirlitz</td>\n\t<td>Robin Haberkorn</td>\n      </tr><tr>\n\t<td>Pavel Sountsov</td>\n\t<td>Dirk Lorenzen</td>\n\t<td>Kasper B. Graversen</td>\n\t<td>Chris Mayo</td>\n      </tr><tr>\n\t<td>Van de Bugger</td>\n\t<td>Tse Kit Yam</td>\n\t<td><a href=\"https://www.smartsharesystems.com/\">SmartShare Systems</a></td>\n\t<td>Morten Brørup</td>\n      </tr><tr>\n\t<td>Alexey Denisov</td>\n\t<td>Justin Dailey</td>\n\t<td>oirfeodent</td>\n\t<td>A-R-C-A</td>\n      </tr><tr>\n\t<td>Roberto Rossi</td>\n\t<td>Kenny Liu</td>\n\t<td>Iain Clarke</td>\n\t<td>desto</td>\n      </tr><tr>\n\t<td>John Flatness</td>\n\t<td>Thorsten Kani</td>\n\t<td>Bernhard M. Wiedemann</td>\n\t<td>Baldur Karlsson</td>\n      </tr><tr>\n\t<td>Martin Kleusberg</td>\n\t<td>Jannick</td>\n\t<td>Zufu Liu</td>\n\t<td>Simon Sobisch</td>\n      </tr><tr>\n\t<td>Georger Araújo</td>\n\t<td>Tobias Kühne</td>\n\t<td>Dimitar Radev</td>\n\t<td>Liang Bai</td>\n      </tr><tr>\n\t<td>Gunter Königsmann</td>\n\t<td>Nicholai Benalal</td>\n\t<td>Uniface</td>\n\t<td>Raghda Morsy</td>\n      </tr><tr>\n\t<td>Giuseppe Corbelli</td>\n\t<td>Andreas Rönnquist</td>\n\t<td>Henrik Hank</td>\n\t<td>Luke Rasmussen</td>\n      </tr><tr>\n\t<td>Philipp</td>\n\t<td>maboroshin</td>\n\t<td>Gokul Krishnan</td>\n\t<td>John Horigan</td>\n      </tr><tr>\n\t<td>jj5</td>\n\t<td>Jad Altahan</td>\n\t<td>Andrea Ricchi</td>\n\t<td>Juarez Rudsatz</td>\n      </tr><tr>\n\t<td>Wil van Antwerpen</td>\n\t<td>Hodong Kim</td>\n\t<td>Michael Conrad</td>\n\t<td>Dejan Budimir</td>\n      </tr><tr>\n\t<td>Andreas Falkenhahn</td>\n\t<td>Mark Reay</td>\n\t<td>David Shuman</td>\n\t<td>McLoo</td>\n      </tr><tr>\n\t<td>Shmuel Zeigerman</td>\n\t<td>Chris Graham</td>\n\t<td>Hugues Larrive</td>\n\t<td>Prakash Sahni</td>\n      </tr><tr>\n\t<td>Michel Sauvard</td>\n\t<td>uhf7</td>\n\t<td>gnombat</td>\n\t<td>Derek Brown</td>\n      </tr><tr>\n\t<td>Robert Di Pardo</td>\n\t<td>riQQ</td>\n\t<td>YX Hao</td>\n\t<td>Bertrand Lacoste</td>\n      </tr><tr>\n\t<td>Ivan Ustûžanin</td>\n\t<td>Rainer Kottenhoff</td>\n\t<td>feitoi</td>\n\t<td>vsl7</td>\n      </tr><tr>\n\t<td>Michael Heath</td>\n\t<td>Antonio Cebrián</td>\n\t<td>David Yu Yang</td>\n\t<td>Arkadiusz Michalski</td>\n      </tr><tr>\n\t<td>Red_M</td>\n\t<td>cdbdev</td>\n\t<td>Andrey Smolyakov</td>\n\t<td>Knut Leimbert</td>\n      </tr><tr>\n\t<td>German Aizek</td>\n\t<td>Tsuyoshi Miyake</td>\n\t<td>Martin Schäfer</td>\n\t<td>RainRat</td>\n      </tr><tr>\n\t<td>Henrik S. Johansen</td>\n\t<td>Ekopalypse</td>\n\t<td>HoTschir</td>\n\t<td>Ahmet Sait</td>\n      </tr><tr>\n\t<td>Franck Reinquin</td>\n\t<td>Peter C. Jones</td>\n\t<td>Stefan Löffler</td>\n    </tr>\n    </table>\n    <h2 id=\"Releases\">Releases</h2>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla550.zip\">Release 5.5.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 29 April 2026.\n\t</li>\n\t<li>\n\tLaTeX: Fix issues at end of file.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/355\">Issue #355</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/358\">Pull request #358</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla549.zip\">Release 5.4.9</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 29 April 2026.\n\t</li>\n\t<li>\n\tAssembler: Add SCE_ASM_STRINGBACKQUOTE for NASM `back-quoted strings`.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/220\">Issue #220</a>.\n\t</li>\n\t<li>\n\tC++: Fold for '#pragma region' and '#pragma endregion'.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/324\">Issue #324</a>.\n\t</li>\n\t<li>\n\tF#: Allow '!' for async keywords.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/352\">Issue #352</a>.\n\t</li>\n\t<li>\n\tF#: Stabilize styling of long strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/353\">Issue #353</a>.\n\t</li>\n\t<li>\n\tF#: Fold long strings with fold.fsharp.quotes.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/354\">Issue #354</a>.\n\t</li>\n\t<li>\n\tLaTeX: Fix bug when \"\\\" at end of file.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/355\">Issue #355</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/356\">Pull request #356</a>.\n\t</li>\n\t<li>\n\tPascal: New SCE_PAS_MULTILINESTRING for multi-line triple-quoted strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/321\">Issue #321</a>.\n\t</li>\n\t<li>\n\tRuby: Fix bug when \"?\\\" at end of file.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/355\">Issue #355</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/357\">Pull request #357</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla548.zip\">Release 5.4.8</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 26 March 2026.\n\t</li>\n\t<li>\n\tBatch: Remove line length limitation and change to an object lexer.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/228\">Issue #228</a>.\n\t</li>\n\t<li>\n\tForth: Treat \\r\\n line ends the same as \\n. This makes testing easier.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/349\">Issue #349</a>.\n\t</li>\n\t<li>\n\tForth: Allow more Forth words to be symbols or begin with a symbol.\n\tRequire whitespace around line comment tokens,\n\tsimilar to the left-hand parenthesis of stream comments.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/351\">Issue #351</a>.\n\t</li>\n\t<li>\n\tJavaScript: in cpp lexer, add lexer.cpp.enable.preprocessor and lexer.cpp.allow.hashes properties.\n\tThis allows disabling preprocessor recognition (as JavaScript doesn't have a preprocessor) and\n\trecognizing private elements that start with a #.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/48\">Issue #48</a>.\n\t</li>\n\t<li>\n\tJSON: Fix escaped quote in SCE_JSON_URI.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/72\">Issue #72</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla547.zip\">Release 5.4.7</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 25 February 2026.\n\t</li>\n\t<li>\n\tTest a single lexer or multiple directories by specifying as command line arguments to TestLexers.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/344\">Pull request #344</a>.\n\t</li>\n\t<li>\n\tLexer added for escape sequences \"escseq\".\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/336\">Pull request #336</a>.\n\t</li>\n\t<li>\n\tErrorlist: Fix reset escape sequence to set style SCE_ERR_DEFAULT (0) instead of SCE_ERR_ES_BLACK.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/333\">Issue #333</a>.\n\t</li>\n\t<li>\n\tMakefile: Recognize comments in more situations.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/40\">Issue #40</a>.\n\t</li>\n\t<li>\n\tPerl: Handle 'method' the same as 'sub' for special cases.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/342\">Issue #342</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/343\">Pull request #343</a>.\n\t</li>\n\t<li>\n\tProgress: Add SCE_ABL_ANNOTATION and SCE_ABL_TYPEDANNOTATION styles.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/346\">Pull request #346</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla546.zip\">Release 5.4.6</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 10 November 2025.\n\t</li>\n\t<li>\n\tLexer added for SINEX \"sinex\".\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/329\">Pull request #329</a>.\n\t</li>\n\t<li>\n\tUpdate character categories to Unicode 16.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1569/\">Feature #1569</a>.\n\t</li>\n\t<li>\n\tErrorlist: Allow \"bright\" ANSI sequences (ESC[90m - ESC[97m).\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/332\">Pull request #332</a>.\n\t</li>\n\t<li>\n\tProgress: Treat '.' as part of compound identifiers instead of as an operator between identifiers.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/316\">Pull request #316</a>.\n\t</li>\n\t<li>\n\tPython: Support t-strings t\\\"var={var}\\\" added by Python 3.14.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/328\">Pull request #328</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla545.zip\">Release 5.4.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 8 June 2025.\n\t</li>\n\t<li>\n\tDart: Add error state SCE_DART_STRINGEOL for unterminated string.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/315\">Pull request #315</a>.\n\t</li>\n\t<li>\n\tMakefile: Add a keyword list to makefile lexer to highlight GNU Make directives like 'ifdef' and 'vpath' as\n\tSCE_MAKE_PREPROCESSOR since these are similar to NMAKE directives like '!IFDEF'.\n\t</li>\n\t<li>\n\tNix: Add error state SCE_NIX_STRINGEOL for unterminated string.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/315\">Pull request #315</a>.\n\t</li>\n\t<li>\n\tTOML: Add error state SCE_TOML_STRINGEOL for unterminated string.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/315\">Pull request #315</a>.\n\t</li>\n\t<li>\n\tZig: Add error state SCE_ZIG_STRINGEOL for unterminated string.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/315\">Pull request #315</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla544.zip\">Release 5.4.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 2 April 2025.\n\t</li>\n\t<li>\n\tFix building for ARM64.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/308\">Pull request #308</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla543.zip\">Release 5.4.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 25 February 2025.\n\t</li>\n\t<li>\n\tC++: Fix evaluation of != in preprocessor condition.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/299\">Issue #299</a>.\n\t</li>\n\t<li>\n\tModula-3: Allow digits in uppercase identifiers.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/297\">Issue #297</a>.\n\t</li>\n\t<li>\n\tPascal: Fix asm style extending past end.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/295\">Issue #295</a>.\n\t</li>\n\t<li>\n\tPython: Fix detection of attributes and decorators.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/294\">Issue #294</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/302\">Pull request #302</a>.\n\t</li>\n\t<li>\n\tRuby: Implement substyles for identifiers SCE_RB_IDENTIFIER.\n\t</li>\n\t<li>\n\tRuby: Recognize name as SCE_RB_DEFNAME in def when `::` used as well as `.`.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/300\">Issue #300</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla542.zip\">Release 5.4.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 18 December 2024.\n\t</li>\n\t<li>\n\tUpdate to Unicode 15.1.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/285\">Issue #285</a>.\n\t</li>\n\t<li>\n\tLexer added for Nix \"nix\".\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/282\">Pull request #282</a>.\n\t</li>\n\t<li>\n\tJavaScript: Use correct SCE_HJA_TEMPLATELITERAL style for server-side template literals in\n\tHTML instead of client-side style.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/286\">Issue #286</a>.\n\t</li>\n\t<li>\n\tJavaScript: Use correct SCE_HJ_SYMBOLS style for '.' after regex instead of SCE_HJ_WORD.\n\tPrevent empty word assertion when non-word character after regex flag.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/289\">Issue #289</a>.\n\t</li>\n\t<li>\n\tPHP: Fix unstable lexing with substyled keyword and unterminated string.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/288\">Issue #288</a>.\n\t</li>\n\t<li>\n\tRust: Add C string and raw C string literal styles SCE_RUST_CSTRING and SCE_RUST_CSTRINGR.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/292\">Pull request #292</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/268\">Issue #268</a>.\n\t</li>\n\t<li>\n\tTOML: Don't treat keys without values as errors.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/283\">Pull request #283</a>.\n\t</li>\n\t<li>\n\tZig: Add SCE_ZIG_IDENTIFIER_STRING for identifiers expressed as strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/287\">Pull request #287</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla541.zip\">Release 5.4.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 19 October 2024.\n\t</li>\n\t<li>\n\tLexer added for Dart \"dart\".\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/265\">Pull request #265</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/275\">Pull request #275</a>.\n\t</li>\n\t<li>\n\tLexer added for troff / nroff \"troff\".\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/264\">Pull request #264</a>.\n\t</li>\n\t<li>\n\tLexer added for Zig \"zig\".\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/267\">Pull request #267</a>.\n\t</li>\n\t<li>\n\tC++: Fix crash for empty documentation comment keyword where '&lt;' occurs at line end.\n\t</li>\n\t<li>\n\tF#: Include EOLs in the style range of SCE_FSHARP_COMMENTLINE.\n\tStabilizes EOL detection when folding line comment groups.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/276\">Issue #276</a>.\n\t</li>\n\t<li>\n\tF#: Fix per-line folding in F# documents.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/277\">Issue #277</a>.\n\t</li>\n\t<li>\n\tHTML: Improve SGML/DTD lexing.\n\tDon't terminate SGML when &gt; inside quoted string.\n\tLex both [ and ] as SCE_H_SGML_DEFAULT.\n\tNested sections handled instead of switching to SCE_H_SGML_ERROR.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/272\">Issue #272</a>.\n\t</li>\n\t<li>\n\tJavaScript: New SCE_HJ_TEMPLATELITERAL and SCE_HJA_TEMPLATELITERAL\n\tstyles for template literals when lexer is hypertext, or xml.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/280\">Issue #280</a>.\n\t</li>\n\t<li>\n\tPHP: Fix failure to recognize PHP start \"&lt;?php' at end of document.\n\tCaused by not capping retrieval range at document end causing no text to be retrieved.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/269\">Issue #269</a>.\n\t</li>\n\t<li>\n\tSmalltalk: Fix scaled decimal numbers without decimal separator.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/274\">Pull request #274</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla540.zip\">Release 5.4.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 21 August 2024.\n\t</li>\n\t<li>\n\tInside Lexilla, LexerModule instances are now const.\n\tThis will require changes to applications that modify Lexilla.cxx, which\n\tmay be done to add custom lexers.\n\t</li>\n\t<li>\n\tLexer added for TOML \"toml\".\n\t</li>\n\t<li>\n\tBash: Handle backslash in heredoc delimiter.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/257\">Issue #257</a>.\n\t</li>\n\t<li>\n\tProgress: Fix lexing of nested comments.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/258\">Pull request #258</a>.\n\t</li>\n\t<li>\n\tForce lower-casing of case-insensitive keyword lists so keywords match in some lexers.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/259\">Issue #259</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla533.zip\">Release 5.3.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 22 July 2024.\n\t</li>\n\t<li>\n\tASP: Control whether ASP is enabled for XML and HTML with\n\tlexer.xml.allow.asp and lexer.html.allow.asp.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/252\">Issue #252</a>.\n\t</li>\n\t<li>\n\tJavaScript: Recognize regular expressions at start or after '&gt;' in JavaScript when lexer is cpp,\n\thypertext, or xml.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/250\">Issue #250</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/918/\">Bug #918</a>.\n\t</li>\n\t<li>\n\tJavaScript: Recognize initial #! 'shebang' line as a comment in standalone files.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/253\">Issue #253</a>.\n\t</li>\n\t<li>\n\tLua: Fix non-ASCII identifiers joined with '.' or ':'.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/242\">Issue #242</a>.\n\t</li>\n\t<li>\n\tLua: Fix folding for multi-line SCE_LUA_LITERALSTRING and SCE_LUA_COMMENT\n\twhen performed incrementally.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/247\">Issue #247</a>.\n\t</li>\n\t<li>\n\tPHP: Control whether PHP is enabled for XML and HTML with\n\tlexer.xml.allow.php and lexer.html.allow.php.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/252\">Issue #252</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla532.zip\">Release 5.3.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 23 April 2024.\n\t</li>\n\t<li>\n\tCOBOL: Stop string literal continuing over line end.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/229\">Issue #229</a>.\n\t</li>\n\t<li>\n\tCOBOL: Stop doc comment assigning different styles to \\r and \\n at line end.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/229\">Issue #229</a>.\n\t</li>\n\t<li>\n\tCOBOL: Recognize keywords that start with 'V'.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/230\">Issue #230</a>.\n\t</li>\n\t<li>\n\tCOBOL: Recognize comments after tag or that start with '/'.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/231\">Issue #231</a>.\n\t</li>\n\t<li>\n\tHTML: Implement substyles for tags, attributes, and identifiers\n\tSCE_H_TAG, SCE_H_ATTRIBUTE, SCE_HJ_WORD, SCE_HJA_WORD, SCE_HB_WORD, SCE_HP_WORD, SCE_HPHP_WORD.\n\t</li>\n\t<li>\n\tHTML: Implement context-sensitive attributes. \"tag.attribute\" matches \"attribute\" only inside \"tag\".\n\t</li>\n\t<li>\n\tHTML: Match standard handling of comments.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/232\">Issue #232</a>.\n\t</li>\n\t<li>\n\tLua: Implement substyles for identifiers SCE_LUA_IDENTIFIER.\n\t</li>\n\t<li>\n\tRuby: Allow non-ASCII here-doc delimiters.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/234\">Issue #234</a>.\n\t</li>\n\t<li>\n\tRuby: Allow modifier if, unless, while and until after heredoc delimiter.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/236\">Issue #236</a>.\n\t</li>\n\t<li>\n\tRust: Recognize raw identifiers.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/239\">Issue #239</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/240\">Pull request #240</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla531.zip\">Release 5.3.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 5 March 2024.\n\t</li>\n\t<li>\n\tAssembler: After comments, treat \\r\\n line ends the same as \\n. This makes testing easier.\n\t</li>\n\t<li>\n\tBash: Fix folding when line changed to/from comment and previous line is comment.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/224\">Issue #224</a>.\n\t</li>\n\t<li>\n\tBatch: Fix handling ':' next to keywords.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/222\">Issue #222</a>.\n\t</li>\n\t<li>\n\tJavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted\n\tstrings as template literals which allow embedded ${expressions}.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/94\">Issue #94</a>.\n\t</li>\n\t<li>\n\tPython: fix lexing of rb'' and rf'' strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/223\">Issue #223</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/227\">Pull request #227</a>.\n\t</li>\n\t<li>\n\tRuby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/225\">Issue #225</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla530.zip\">Release 5.3.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 27 December 2023.\n\t</li>\n\t<li>\n\tFix calling AddStaticLexerModule by defining as C++ instead of C which matches header.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2421/\">Bug #2421</a>.\n\t</li>\n\t<li>\n\tBash: Fix shift operator &lt;&lt; incorrectly recognized as here-doc.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/215\">Issue #215</a>.\n\t</li>\n\t<li>\n\tBash: Fix termination of '${' with first unquoted '}' instead of nesting.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/216\">Issue #216</a>.\n\t</li>\n\t<li>\n\tHTML: JavaScript double-quoted strings may escape line end with '\\'.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/214\">Issue #214</a>.\n\t</li>\n\t<li>\n\tLua: recognize --- doc comments.\n\tDefined by <a href=\"https://github.com/lunarmodules/ldoc\">LDoc</a>.\n\tDoes not recognize --[[-- doc comments which seem less common.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla529.zip\">Release 5.2.9</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 18 November 2023.\n\t</li>\n\t<li>\n\tXcode build settings changed to avoid problems with Xcode 15.0.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla528.zip\">Release 5.2.8</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 5 November 2023.\n\t</li>\n\t<li>\n\tPython: Update f-string handling to match PEP 701 and Python 3.12.\n\tControlled with property lexer.python.strings.f.pep.701.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/150\">Issue #150</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/209\">Pull request #209</a>.\n\t</li>\n\t<li>\n\tR: Fix escape sequence highlighting with change of for loop to while loop.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/206\">Issue #206</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/207\">Pull request #207</a>.\n\t</li>\n\t<li>\n\tMinimum supported macOS release increased to 10.13.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla527.zip\">Release 5.2.7</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 22 September 2023.\n\t</li>\n\t<li>\n\tFix building on Windows with non-English environment.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/200\">Pull request #200</a>.\n\t</li>\n\t<li>\n\tBash: fix line continuation for comments and when multiple backslashes at line end.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/195\">Issue #195</a>.\n\t</li>\n\t<li>\n\tBash: treat  += as operator and, inside arithmetic expressions, treat ++ and -- as operators.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/197\">Issue #197</a>.\n\t</li>\n\t<li>\n\tBash: improve backslash handling inside backquoted command substitution and fix $ at end of backtick expression.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/194\">Issue #194</a>.\n\t</li>\n\t<li>\n\tBash: treat words that are similar to numbers but invalid wholly as identifiers.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/199\">Issue #199</a>.\n\t</li>\n\t<li>\n\tBash: consistently handle '-' options at line start and after '|' as identifiers.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/202\">Issue #202</a>.\n\t</li>\n\t<li>\n\tBash: handle '-' options differently in [ single ] and [[ double ]] bracket constructs.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/203\">Issue #203</a>.\n\t</li>\n\t<li>\n\tF#: improve speed of folding long lines.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/198\">Issue #198</a>.\n\t</li>\n\t<li>\n\tHTML: fix invalid entity at line end and terminate invalid entity before invalid character.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/192\">Issue #192</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla526.zip\">Release 5.2.6</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 26 July 2023.\n\t</li>\n\t<li>\n\tInclude empty word list names in value returned by DescribeWordListSets and SCI_DESCRIBEKEYWORDSETS.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/175\">Issue #175</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/176\">Pull request #176</a>.\n\t</li>\n\t<li>\n\tBash: style here-doc end delimiters as SCE_SH_HERE_DELIM instead of SCE_SH_HERE_Q.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/177\">Issue #177</a>.\n\t</li>\n\t<li>\n\tBash: allow '$' as last character in string.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/180\">Issue #180</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/181\">Pull request #181</a>.\n\t</li>\n\t<li>\n\tBash: fix state after expansion. Highlight all numeric and file test operators.\n\tDon't highlight dash in long option as operator.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/182\">Issue #182</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/183\">Pull request #183</a>.\n\t</li>\n\t<li>\n\tBash: strict checking of special parameters ($*, $@, $$, ...) with property lexer.bash.special.parameter to specify\n\tvalid parameters.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/184\">Issue #184</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/186\">Pull request #186</a>.\n\t</li>\n\t<li>\n\tBash: recognize keyword before redirection operators (&lt; and &gt;).\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/188\">Issue #188</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/189\">Pull request #189</a>.\n\t</li>\n\t<li>\n\tErrorlist: recognize Bash diagnostic messages.\n\t</li>\n\t<li>\n\tHTML: allow ASP block to terminate inside line comment.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/185\">Issue #185</a>.\n\t</li>\n\t<li>\n\tHTML: fix folding with JSP/ASP.NET &lt;%-- comment.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/191\">Issue #191</a>.\n\t</li>\n\t<li>\n\tHTML: fix incremental styling of multi-line ASP.NET directive.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/191\">Issue #191</a>.\n\t</li>\n\t<li>\n\tMatlab: improve arguments blocks.\n\tAdd support for multiple arguments blocks.\n\tPrevent \"arguments\" from being keyword in function declaration line.\n\tFix semicolon handling.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/179\">Pull request #179</a>.\n\t</li>\n\t<li>\n\tVisual Prolog: add support for embedded syntax with SCE_VISUALPROLOG_EMBEDDED\n\tand SCE_VISUALPROLOG_PLACEHOLDER.<br />\n\tStyling of string literals changed with no differentiation between literals with quotes and those\n\tthat are prefixed with \"@\".\n\tQuote characters are in a separate style (SCE_VISUALPROLOG_STRING_QUOTE)\n\tto contents (SCE_VISUALPROLOG_STRING).<br />\n\tSCE_VISUALPROLOG_CHARACTER, SCE_VISUALPROLOG_CHARACTER_TOO_MANY,\n\tSCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR, SCE_VISUALPROLOG_STRING_EOL_OPEN,\n\tand SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL were removed (replaced with\n\tSCE_VISUALPROLOG_UNUSED[1-5]).\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/178\">Pull request #178</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla525.zip\">Release 5.2.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 31 May 2023.\n\t</li>\n\t<li>\n\tAdd CharacterSetArray constructor without setBase initial argument for common case\n\twhere this is setNone and the initialSet argument completely defines the characters.\n\tThis shortens and clarifies use of CharacterSetArray.\n\t</li>\n\t<li>\n\tBash: implement highlighting inside quoted elements and here-docs.\n\tControlled with properties lexer.bash.styling.inside.string, lexer.bash.styling.inside.backticks,\n\tlexer.bash.styling.inside.parameter, and lexer.bash.styling.inside.heredoc.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/154\">Issue #154</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/153\">Issue #153</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1033/\">Feature #1033</a>.\n\t</li>\n\t<li>\n\tBash: add property lexer.bash.command.substitution to choose how to style command substitutions.\n\t0 &rarr; SCE_SH_BACKTICKS;\n\t1 &rarr; surrounding \"$(\" and \")\" as operators and contents styled as bash code;\n\t2 &rarr; use distinct styles (base style + 64) for contents.\n\tChoice (2) is a provisional feature and details may change before it is finalized.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/153\">Issue #153</a>.\n\t</li>\n\t<li>\n\tBash: fix nesting of parameters (SCE_SH_PARAM) like ${var/$sub/\"${rep}}\"}.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/154\">Issue #154</a>.\n\t</li>\n\t<li>\n\tBash: fix single character special parameters like $? by limiting style.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/154\">Issue #154</a>.\n\t</li>\n\t<li>\n\tBash: treat \"$$\" as special parameter and end scalars before \"$\".\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/154\">Issue #154</a>.\n\t</li>\n\t<li>\n\tBash: treat \"&lt;&lt;\" in arithmetic contexts as left bitwise shift operator instead of here-doc.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/137\">Issue #137</a>.\n\t</li>\n\t<li>\n\tBatch: style SCE_BAT_AFTER_LABEL used for rest of line after label which is not executed.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/148\">Issue #148</a>.\n\t</li>\n\t<li>\n\tF#: Lex interpolated verbatim strings as verbatim.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/156\">Issue #156</a>.\n\t</li>\n\t<li>\n\tVB: allow multiline strings when lexer.vb.strings.multiline set.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/151\">Issue #151</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla524.zip\">Release 5.2.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 13 March 2023.\n\t</li>\n\t<li>\n\tC++: Fix failure to recognize keywords containing upper case.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/149\">Issue #149</a>.\n\t</li>\n\t<li>\n\tGDScript: Support % and $ node paths.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/145\">Issue #145</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/146\">Pull request #146</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla523.zip\">Release 5.2.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 8 March 2023.\n\t</li>\n\t<li>\n\tAdd scripts/PromoteNew.bat script to promote .new files after checking.\n\t</li>\n\t<li>\n\tMakefile: Remove 1024-byte line length limit..\n\t</li>\n\t<li>\n\tRuby: Add new lexical classes for % literals SCE_RB_STRING_W (%w non-interpolable string array),\n\tSCE_RB_STRING_I (%i non-interpolable symbol array),\n\tSCE_RB_STRING_QI (%I interpolable symbol array),\n\tand SCE_RB_STRING_QS (%s symbol).\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/124\">Issue #124</a>.\n\t</li>\n\t<li>\n\tRuby: Disambiguate %= which may be a quote or modulo assignment.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/124\">Issue #124</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1255/\">Bug #1255</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2182/\">Bug #2182</a>.\n\t</li>\n\t<li>\n\tRuby: Fix additional fold level for single character in SCE_RB_STRING_QW.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/132\">Issue #132</a>.\n\t</li>\n\t<li>\n\tRuby: Set SCE_RB_HERE_QQ for unquoted and double-quoted heredocs and\n\tSCE_RB_HERE_QX for backticks-quoted heredocs.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/134\">Issue #134</a>.\n\t</li>\n\t<li>\n\tRuby: Recognise #{} inside SCE_RB_HERE_QQ and SCE_RB_HERE_QX.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/134\">Issue #134</a>.\n\t</li>\n\t<li>\n\tRuby: Improve regex and heredoc recognition.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/136\">Issue #136</a>.\n\t</li>\n\t<li>\n\tRuby: Highlight #@, #@@ and #$ style interpolation.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/140\">Issue #140</a>.\n\t</li>\n\t<li>\n\tRuby: Fix folding for multiple heredocs started on one line.\n\tFix folding when there is a space after heredoc opening delimiter.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/135\">Issue #135</a>.\n\t</li>\n\t<li>\n\tYAML: Remove 1024-byte line length limit.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla522.zip\">Release 5.2.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 8 February 2023.\n\t</li>\n\t<li>\n\tC++: Fix keywords that start with non-ASCII. Also affects other lexers.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/130\">Issue #130</a>.\n\t</li>\n\t<li>\n\tMatlab: Include more prefix and suffix characters in numeric literals.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/120\">Issue #120</a>.\n\t</li>\n\t<li>\n\tMatlab: More accurate treatment of line ends inside strings. Matlab and Octave are different here.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/18\">Issue #18</a>.\n\t</li>\n\t<li>\n\tModula-3: Don't treat identifier suffix that matches keyword as keyword.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/129\">Issue #129</a>.\n\t</li>\n\t<li>\n\tModula-3: Fix endless loop in folder.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/128\">Issue #128</a>.\n\t</li>\n\t<li>\n\tModula-3: Fix access to lines beyond document end in folder.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/131\">Issue #131</a>.\n\t</li>\n\t<li>\n\tPython: Don't highlight match and case as keywords in contexts where they probably aren't used as keywords.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/122\">Pull request #122</a>.\n\t</li>\n\t<li>\n\tX12: Support empty envelopes.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2369/\">Bug #2369</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla521.zip\">Release 5.2.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 6 December 2022.\n\t</li>\n\t<li>\n\tUpdate to Unicode 14.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1461/\">Feature #1461</a>.\n\t</li>\n\t<li>\n\tChange default compilation optimization option to favour speed over space.\n\t-O2 for MSVC and -O3 for gcc and clang.\n\t</li>\n\t<li>\n\tBatch: Fix comments starting inside strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/115\">Issue #115</a>.\n\t</li>\n\t<li>\n\tF#: Lex signed numeric literals more accurately.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/110\">Issue #110</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/111\">Issue #111</a>.\n\t</li>\n\t<li>\n\tF#: Add specifiers for 64-bit integer and floating point literals.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/112\">Issue #112</a>.\n\t</li>\n\t<li>\n\tMarkdown: Stop styling numbers at line start in PRECHAR style.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/117\">Issue #117</a>.\n\t</li>\n\t<li>\n\tPowerShell: Recognise numeric literals more accurately.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/118\">Issue #118</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla520.zip\">Release 5.2.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 12 October 2022.\n\t</li>\n\t<li>\n\tPowerShell: End comment before \\r carriage return so \\r and \\n in same\n\tSCE_POWERSHELL_DEFAULT style.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/99\">Pull request #99</a>.\n\t</li>\n\t<li>\n\tPowerShell: Fix character truncation bug that lead to 'ġ' styled as an operator since its low 8 bits\n\tare equal to '!'.\n\t</li>\n\t<li>\n\tR: Support hexadecimal, float exponent and number suffix.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/101\">Issue #101</a>.\n\t</li>\n\t<li>\n\tR: Highlight backticks.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/102\">Pull request #102</a>.\n\t</li>\n\t<li>\n\tR: Highlight raw strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/100\">Issue #100</a>.\n\t</li>\n\t<li>\n\tR: Optionally highlight escape sequences in strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/100\">Issue #100</a>.\n\t</li>\n\t<li>\n\tFix early truncation from LexAccessor::GetRange and LexAccessor::GetRangeLowered.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/17\">Issue #17</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla519.zip\">Release 5.1.9</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 27 August 2022.\n\t</li>\n\t<li>\n\tJulia: Parse unicode forall and exists as identifiers #42314.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/98\">Pull request #98</a>.\n\t</li>\n\t<li>\n\tJulia: Parse apostrophe as char and not adjoint after exclamation.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/97\">Issue #97</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/98\">Pull request #98</a>.\n\t</li>\n\t<li>\n\tProperties: Don't set header flag for empty section.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/96\">Issue #96</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla518.zip\">Release 5.1.8</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 10 July 2022.\n\t</li>\n\t<li>\n\tF#: Recognize nested comments in F#.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/93\">Issue #93</a>.\n\t</li>\n\t<li>\n\tMS SQL: Recognize nested comments in Transact-SQL.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/87\">Issue #87</a>.\n\t</li>\n\t<li>\n\tMS SQL: Preference data types more consistently to not depend on how lexing is broken\n\tup into segments. This is needed because there are keywords that are both data type\n\tnames and function names such as 'CHAR'.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/90\">Issue #90</a>.\n\t</li>\n\t<li>\n\tPowerShell: Fix single quoted strings to not treat backtick as escape.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/92\">Pull request #92</a>.\n\t</li>\n\t<li>\n\tVisual Prolog: Treat \\r\\n line ends the same as \\n. This makes testing easier.\n\tAdd test case.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/83\">Issue #83</a>.\n\t</li>\n\t<li>\n\tVisual Prolog: Allow disabling verbatim strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/89\">Pull request #89</a>.\n\t</li>\n\t<li>\n\tVisual Prolog: Support backquoted strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/89\">Pull request #89</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla517.zip\">Release 5.1.7</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 22 May 2022.\n\t</li>\n\t<li>\n\tAdd LexAccessor::StyleIndexAt to retrieve style values as unsigned to handle styles > 127 better.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/61\">Issue #61</a>.\n\t</li>\n\t<li>\n\tAssociate more than one file extension with a setting for testing.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/81\">Issue #81</a>.\n\t</li>\n\t<li>\n\tCMake: Fix folding of \"ElseIf\".\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/77\">Issue #77</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/78\">Pull request #78</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2213/\">Bug #2213</a>.\n\t</li>\n\t<li>\n\tHTML: Fix folding of JavaScript doc comments.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2219/\">Bug #2219</a>.\n\t</li>\n\t<li>\n\tMatlab: add \"classdef\" and \"spmd\" to folding keywords.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/70\">Pull request #70</a>.\n\t</li>\n\t<li>\n\tMatlab: handle \"arguments\" contextual keyword.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/70\">Pull request #70</a>.\n\t</li>\n\t<li>\n\tMatlab: improve support of class definition syntax.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/75\">Pull request #75</a>.\n\t</li>\n\t<li>\n\tRaku: fix escape detection.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/76\">Pull request #76</a>.\n\t</li>\n\t<li>\n\tRuby: fix character sequence \"?\\\\#\" to not include '#' in SCE_RB_NUMBER as only second '\\' is quoted.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/69\">Issue #69</a>.\n\t</li>\n\t<li>\n\tRuby: improve styling of ternary expressions as commonly used.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/69\">Issue #69</a>.\n\t</li>\n\t<li>\n\tVHDL: support folding for VHDL 08 else-generate and case-generate.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/80\">Pull request #80</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla516.zip\">Release 5.1.6</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 31 March 2022.\n\t</li>\n\t<li>\n\tImplement conditional statements \"if\" and \"match\", comparison function \"$(=\", and \"FileNameExt\"\n\tproperty in TestLexers to allow varying lexer properties over different files.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/62\">Issue #62</a>.\n\t</li>\n\t<li>\n\tAdd LexAccessor::BufferStyleAt to retrieve style values to simplify logic and\n\timprove performance.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/54\">Issue #54</a>.\n\t</li>\n\t<li>\n\tMarkdown: Optionally style all of Markdown header lines.\n\tEnabled with lexer.markdown.header.eolfill=1.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/60\">Issue #60</a>.\n\t</li>\n\t<li>\n\tRuby: Fix operator method styling so next word not treated as method name.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/65\">Issue #65</a>.\n\t</li>\n\t<li>\n\tRuby: Fix folding for Ruby 3 endless method definition.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/65\">Issue #65</a>.\n\t</li>\n\t<li>\n\tRuby: Fold string array SCE_RB_STRING_QW.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/65\">Issue #65</a>.\n\t</li>\n\t<li>\n\tRuby: Fix final \\n in indented heredoc to be SCE_RB_HERE_Q.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/66\">Issue #66</a>.\n\t</li>\n\t<li>\n\tRuby: Fix heredoc recognition when '.' and ',' used in method calls and after SCE_RB_GLOBAL.\n\tClassify word after heredoc delimiter instead of styling as keyword.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/67\">Issue #67</a>.\n\t</li>\n\t<li>\n\tRuby: Improve method highlighting so method name is styled as SCE_RB_DEFNAME and class/object\n\tis styled appropriately.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/68\">Issue #68</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla515.zip\">Release 5.1.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 9 February 2022.\n\t</li>\n\t<li>\n\tBash: Treat \\r\\n line ends the same as \\n. This makes testing easier.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/57\">Issue #57</a>.\n\t</li>\n\t<li>\n\tBatch: Recognise \"::\" comments when second command on line.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2304/\">Bug #2304</a>.\n\t</li>\n\t<li>\n\tF#: Recognise format specifiers in interpolated strings and %B for binary.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/46\">Issue #46</a>.\n\t</li>\n\t<li>\n\tF#: More accurate line-based folding.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/56\">Issue #56</a>.\n\t</li>\n\t<li>\n\tHTML: Fix folding inside script blocks.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/47\">Issue #47</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/53\">Issue #53</a>.\n\t</li>\n\t<li>\n\tInno Setup: Fix multiline comments in code.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/44\">Issue #44</a>.\n\t</li>\n\t<li>\n\tPython: Add attribute style with properties lexer.python.identifier.attributes and\n\tlexer.python.decorator.attributes.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/49\">Pull request #49</a>.\n\t</li>\n\t<li>\n\tAllow choice of object file directory with makefile by setting DIR_O.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/50\">Issue #50</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla514.zip\">Release 5.1.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 7 December 2021.\n\t</li>\n\t<li>\n\tAdd AsciiDoc lexer.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/39\">Pull request #39</a>.\n\t</li>\n\t<li>\n\tAdd GDScript lexer.\n\tSome behaviour and lexical states may change before this lexer is stable.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/41\">Pull request #41</a>.\n\t</li>\n\t<li>\n\tFix strings ending in escaped '\\' in F#.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/38\">Issue #38</a>.\n\t</li>\n\t<li>\n\tBetter handling of bad terminators and folding for X12.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1420/\">Feature #1420</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla513.zip\">Release 5.1.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 8 November 2021.\n\t</li>\n\t<li>\n\tFix parsing of 128-bit integer literals in Rust.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/33\">Issue #33</a>.\n\t</li>\n\t<li>\n\tFix different styles between \\r and \\n at end of line comments for Rust.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/34\">Issue #34</a>.\n\t</li>\n\t<li>\n\tFor Rust, don't go past end when file ends with unterminated block comment.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/35\">Issue #35</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla512.zip\">Release 5.1.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 23 September 2021.\n\t</li>\n\t<li>\n\tImplement conditional group rules in CSS.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/25\">Issue #25</a>,\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/28\">Pull request #28</a>.\n\t</li>\n\t<li>\n\tAllow F# triple-quoted strings to interpolate string literals.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/21\">Issue #21</a>.\n\t</li>\n\t<li>\n\tHighlight F# printf specifiers in type-checked interpolated strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/24\">Issue #24</a>.\n\t</li>\n\t<li>\n\tFix styling for Inno Setup scripts handling unterminated strings,\n\tmessage sections, and avoid terminating comments between CR and LF.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/29\">Pull request #29</a>.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1415/\">Feature #1415</a>.\n\t</li>\n\t<li>\n\tFix Markdown hang when document ends with \"`\", \"*\", \"_\",  or similar.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/23\">Issue #23</a>.\n\t</li>\n\t<li>\n\tTreat '.' as an operator instead of part of a word for PHP.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/22\">Issue #22</a>.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2225/\">Bug #2225</a>.\n\t</li>\n\t<li>\n\tCheck PHP numeric literals, showing invalid values with default style instead of numeric.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/20\">Issue #20</a>.\n\t</li>\n\t<li>\n\tFor PHP, recognize start of comment after numeric literal.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/20\">Issue #20</a>.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2143/\">Bug #2143</a>.\n\t</li>\n\t<li>\n\tFor PHP, recognize PHP code within JavaScript strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/27\">Pull request #27</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla511.zip\">Release 5.1.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 26 July 2021.\n\t</li>\n\t<li>\n\tOn 32-bit Win32 using Visual C++ projects, stop exported functions ending with @n causing failures with GetProcAddress.\n\t</li>\n\t<li>\n\tFixed crash when calling TagsOfStyle on C++ lexer after allocating substyles.\n\t</li>\n\t<li>\n\tFixed folding for Julia which could be inconsistent depending on range folded.\n\tAdded SCE_JULIA_KEYWORD4 and SCE_JULIA_TYPEOPERATOR lexical styles and\n\tchanged keyword set 4 from \"Raw string literals\" to \"Built in functions\".\n\tProperty lexer.julia.string.interpolation removed.\n\tUpdated set of characters for identifiers.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/13\">Pull request #13</a>.\n\t</li>\n\t<li>\n\tFixed Markdown emphasis spans to only be recognized when closed in same paragraph.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1216/\">Bug #1216</a>.\n\t</li>\n\t<li>\n\tFixed Markdown code block to terminate when end marker is indented.\n\tDisplay all of end marker in code block style.\n\tOnly recognize inline code when closed in same paragraph.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2247/\">Bug #2247</a>.\n\t</li>\n\t<li>\n\tFixed Matlab to not allow escape sequences in double-quoted strings.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/18\">Issue #18</a>.\n\t</li>\n\t<li>\n\tSupport flexible heredoc and nowdoc syntax for PHP.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/19\">Issue #19</a>.\n\t</li>\n\t<li>\n\tEnabled '_' digit separator in numbers for PHP.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/19\">Issue #19</a>.\n\t</li>\n\t<li>\n\tStop styling attributes as comments for PHP.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/19\">Issue #19</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla510.zip\">Release 5.1.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 23 June 2021.\n\t</li>\n\t<li>\n\tThis is a stable release. The Lexilla protocol should remain compatible through 5.x releases.\n\t</li>\n\t<li>\n\tFixed bugs with styling Erlang by handling \\n and \\r\\n line endings consistently.\n\t</li>\n\t<li>\n\tFixed folding for F# open statements and for strings that contain comment prefixes.\n\t</li>\n\t<li>\n\tFormat specifiers lexed in F# strings.\n\t</li>\n\t<li>\n\tFixed folding for ASP files where scripts were treated inconsistently when '&lt;%' was included\n\tor not included in range examined.\n\t</li>\n\t<li>\n\tFixed folding of Raku heredocs that start with \"q:to\" or \"qq:to\".\n\t</li>\n\t<li>\n\tFixed folding at end of Ruby files where these is no final new line.\n\t</li>\n\t<li>\n\tMade folding of Tcl files more consistent by always treating completely empty lines as whitespace.\n\t</li>\n\t<li>\n\tFixed styling of \"a:b\" with no spaces in YAML as a single piece of text instead of a key-value pair.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/15\">Pull request #15</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla503.zip\">Release 5.0.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 2 June 2021.\n\t</li>\n\t<li>\n\tAdd namespace feature with GetNameSpace function.\n\t</li>\n\t<li>\n\tAdd Julia lexer.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1380/\">Feature #1380</a>.\n\t</li>\n\t<li>\n\tFix transition to comment for --> inside JavaScript string.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2207/\">Bug #2207</a>.\n\t</li>\n\t<li>\n\tFix variable expansion in Batch.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/4\">Issue #4</a>.\n\t</li>\n\t<li>\n\tFix empty link titles in Markdown.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2235/\">Bug #2235</a>.\n\tAlso fix detection of whether the previous line had content which treated '\\n' and '\\r\\n' line endings differently.\n\t</li>\n\t<li>\n\tRemove nested comment and long string support as these were removed from Lua.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2205/\">Bug #2205</a>.\n\t</li>\n\t<li>\n\tUpdate to Unicode 13.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1379/\">Feature #1379</a>.\n\t</li>\n\t<li>\n\tAddStaticLexerModule function adds a static lexer to Lexilla's list.\n\t</li>\n\t<li>\n\tOn Win32 enable hardware-enforced stack protection.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1405/\">Feature #1405</a>.\n\t</li>\n\t<li>\n\tOn 32-bit Win32 using g++, stop exported functions ending with @n causing failures with GetProcAddress.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/issues/10\">Issue #10</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla502.zip\">Release 5.0.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 23 April 2021.\n\t</li>\n\t<li>\n\tFix assertion in cpp lexer handling of preprocessor.\n\tEmpty preprocessor statement '#' caused preprocessor history to be stored on incorrect line number.\n\tDangling #else or #elif without corresponding #if led to inconsistent state.\n\tChange treatment of empty preprocessor statement to set subsequent line end characters in\n\tpreprocessor style as this is more consistent with other preprocessor directives and avoids\n\tdifferences between \\n and \\r\\n line ends.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2245/\">Bug #2245</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla501.zip\">Release 5.0.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 9 April 2021.\n\t</li>\n\t<li>\n\tAdd LexerNameFromID function to Lexilla protocol as optional and temporary to\n\thelp applications migrate to Lexilla.\n\tIt is marked deprecated and will be removed in a future release.\n\t</li>\n\t<li>\n\tThe cpp lexer supports XML styled comment doc keywords.\n\t<a href=\"https://github.com/ScintillaOrg/lexilla/pull/2\">Pull request #2</a>.\n\t</li>\n\t<li>\n\tThe errorlist lexer detects NMAKE fatal errors and Microsoft linker errors as SCE_ERR_MS.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/lexilla500.zip\">Release 5.0.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 5 March 2021.\n\t</li>\n\t<li>\n\tFirst version that separates Lexilla from Scintilla.\n\tEach of the 3 projects now has a separate history page but history before 5.0.0 remains combined.\n\t</li>\n\t<li>\n\tLexer added for F#.\n\t</li>\n    </ul>\n    <h3>\n       Lexilla became a separate project at this point.\n    </h3>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite446.zip\">Release 4.4.6</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 1 December 2020.\n\t</li>\n\t<li>\n\tFix building with Xcode 12.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2187/\">Bug #2187</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite445.zip\">Release 4.4.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 11 September 2020.\n\t</li>\n\t<li>\n\tLexilla interface supports setting initialisation properties on lexer libraries with\n\tSetLibraryProperty and GetLibraryPropertyNames functions.\n\tThese are called by SciTE which will forward properties to lexer libraries that are prefixed with\n\t\"lexilla.context.\".\n\t</li>\n\t<li>\n\tAllow cross-building for GTK by choosing pkg-config.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2189/\">Bug #2189</a>.\n\t</li>\n\t<li>\n\tOn GTK, allow setting CPPFLAGS (and LDFLAGS for SciTE) to support hardening.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2191/\">Bug #2191</a>.\n\t</li>\n\t<li>\n\tChanged SciTE's indent.auto mode to set tab size to indent size when file uses tabs for indentation.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2198/\">Bug #2198</a>.\n\t</li>\n\t<li>\n\tFix position of marker symbols for SC_MARGIN_RTEXT which were being moved based on\n\twidth of text.\n\t</li>\n\t<li>\n\tFixed bug on Win32 where cursor was flickering between hand and text over an\n\tindicator with hover style.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2170/\">Bug #2170</a>.\n\t</li>\n\t<li>\n\tFixed bug where hovered indicator was not returning to non-hover\n\tappearance when mouse moved out of window or into margin.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2193/\">Bug #2193</a>.\n\t</li>\n\t<li>\n\tFixed bug where a hovered INDIC_TEXTFORE indicator was not applying the hover\n\tcolour to the whole range.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2199/\">Bug #2199</a>.\n\t</li>\n\t<li>\n\tFixed bug where gradient indicators were not showing hovered appearance.\n\t</li>\n\t<li>\n\tFixed bug where layout caching was ineffective.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2197/\">Bug #2197</a>.\n\t</li>\n\t<li>\n\tFor SciTE, don't show the output pane for quiet jobs.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1365/\">Feature #1365</a>.\n\t</li>\n\t<li>\n\tSupport command.quiet for SciTE on GTK.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1365/\">Feature #1365</a>.\n\t</li>\n\t<li>\n\tFixed a bug in SciTE with stack balance when a syntax error in the Lua startup script\n\tcaused continuing failures to find functions after the syntax error was corrected.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2176/\">Bug #2176</a>.\n\t</li>\n\t<li>\n\tAdded method for iterating through multiple vertical edges: SCI_GETMULTIEDGECOLUMN.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1350/\">Feature #1350</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite444.zip\">Release 4.4.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 21 July 2020.\n\t</li>\n\t<li>\n\tEnd of line annotations implemented.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2141/\">Bug #2141</a>.\n\t</li>\n\t<li>\n\tAdd SCI_BRACEMATCHNEXT API.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1368/\">Feature #1368</a>.\n\t</li>\n\t<li>\n\tThe latex lexer supports lstlisting environment that is similar to verbatim.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1358/\">Feature #1358</a>.\n\t</li>\n\t<li>\n\tFor SciTE on Linux, place liblexilla.so and libscintilla.so in /usr/lib/scite.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2184/\">Bug #2184</a>.\n\t</li>\n\t<li>\n\tRound SCI_TEXTWIDTH instead of truncating as this may be more accurate when sizing application\n\telements to match text.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1355/\">Feature #1355</a>.\n\t</li>\n\t<li>\n\tDisplay DEL control character as visible \"DEL\" block like other control characters.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1369/\">Feature #1369</a>.\n\t</li>\n\t<li>\n\tAllow caret width to be up to 20 pixels.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1361/\">Feature #1361</a>.\n\t</li>\n\t<li>\n\tSciTE on Windows adds create.hidden.console option to stop console window flashing\n\twhen Lua script calls os.execute or io.popen.\n\t</li>\n\t<li>\n\tFix translucent rectangle drawing on Qt. When drawing a translucent selection, there were edge\n\tartifacts as the calls used were drawing outlines over fill areas. Make bottom and right borders on\n\tINDIC_ROUNDBOX be same intensity as top and left.\n\tReplaced some deprecated Qt calls with currently supported calls.\n\t</li>\n\t<li>\n\tFix printing on Windows to use correct text size.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2185/\">Bug #2185</a>.\n\t</li>\n\t<li>\n\tFix bug on Win32 where calling WM_GETTEXT for more text than in document could return\n\tless text than in document.\n\t</li>\n\t<li>\n\tFixed a bug in SciTE with Lua stack balance causing failure to find\n\tfunctions after reloading script.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2176/\">Bug #2176</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite443.zip\">Release 4.4.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 3 June 2020.\n\t</li>\n\t<li>\n\tFix syntax highlighting for SciTE on Windows by setting executable directory for loading Lexilla.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2181/\">Bug #2181</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite442.zip\">Release 4.4.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 2 June 2020.\n\t</li>\n\t<li>\n\tOn Cocoa using Xcode changed Lexilla.dylib install path to @rpath as would otherwise try /usr/lib which\n\twon't work for sandboxed applications.\n\t</li>\n\t<li>\n\tOn Cocoa using Xcode made work on old versions of macOS by specifying deployment target as 10.8\n\tinstead of 10.15.\n\t</li>\n\t<li>\n\tOn Win32 fix static linking of Lexilla by specifying calling convention in Lexilla.h.\n\t</li>\n\t<li>\n\tSciTE now uses default shared library extension even when directory contains '.'.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite440.zip\">Release 4.4.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 1 June 2020.\n\t</li>\n\t<li>\n\tAdded Xcode project files for Lexilla and Scintilla with no lexers (cocoa/Scintilla).\n\t</li>\n\t<li>\n\tFor GTK, build a shared library with no lexers libscintilla.so or libscintilla.dll.\n\t</li>\n\t<li>\n\tLexilla used as a shared library for most builds of SciTE except for the single file executable on Win32.\n\tOn GTK, Scintilla shared library used.\n\tLexillaLibrary code can be copied out of SciTE for other applications that want to interface to Lexilla.\n\t</li>\n\t<li>\n\tConstants in Scintilla.h can be disabled with SCI_DISABLE_AUTOGENERATED.\n\t</li>\n\t<li>\n\tImplement per-monitor DPI Awareness on Win32 so both Scintilla and SciTE\n\twill adapt to the display scale when moved between monitors.\n\tApplications should forward WM_DPICHANGED to Scintilla.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2171/\">Bug #2171</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2063/\">Bug #2063</a>.\n\t</li>\n\t<li>\n\tOptimized performance when opening huge files.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1347/\">Feature #1347</a>.\n\t</li>\n\t<li>\n\tAdd Appearance and Contrast properties to SciTE that allow customising visuals for dark mode and\n\thigh contrast modes.\n\t</li>\n\t<li>\n\tFixed bug in Batch lexer where a single character line with a single character line end continued\n\tstate onto the next line.\n\t</li>\n\t<li>\n\tAdded SCE_ERR_GCC_EXCERPT style for GCC 9 diagnostics in errorlist lexer.\n\t</li>\n\t<li>\n\tFixed buffer over-read bug with absolute references in MMIXAL lexer.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2019/\">Bug #2019</a>.\n\t</li>\n\t<li>\n\tFixed bug with GTK on recent Linux distributions where underscores were invisible.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2173/\">Bug #2173</a>.\n\t</li>\n\t<li>\n\tFixed GTK on Linux bug when pasting from closed application.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2175/\">Bug #2175</a>.\n\t</li>\n\t<li>\n\tFixed bug in SciTE with Lua stack balance.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2176/\">Bug #2176</a>.\n\t</li>\n\t<li>\n\tFor macOS, SciTE reverts to running python (2) due to python3 not being available in the sandbox.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite433.zip\">Release 4.3.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 27 April 2020.\n\t</li>\n\t<li>\n\tAdded Visual Studio project files for Lexilla and Scintilla with no lexers.\n\t</li>\n\t<li>\n\tAdd methods for iterating through the marker handles and marker numbers on a line:\n\tSCI_MARKERHANDLEFROMLINE and SCI_MARKERNUMBERFROMLINE.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1344/\">Feature #1344</a>.\n\t</li>\n\t<li>\n\tAssembler lexers asm and as can change comment character with lexer.as.comment.character property.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1314/\">Feature #1314</a>.\n\t</li>\n\t<li>\n\tFix brace styling in Batch lexer so that brace matching works.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1624/\">Bug #1624</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1906/\">Bug #1906</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1997/\">Bug #1997</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2065/\">Bug #2065</a>.\n\t</li>\n\t<li>\n\tChange Perl lexer to style all line ends of comment lines in comment line style.\n\tPreviously, the last character was in default style which made the characters in\n\t\\r\\n line ends have mismatching styles.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2164/\">Bug #2164</a>.\n\t</li>\n\t<li>\n\tWhen a lexer has been set with SCI_SETILEXER, fix SCI_GETLEXER and avoid\n\tsending SCN_STYLENEEDED notifications.\n\t</li>\n\t<li>\n\tOn Win32 fix handling Japanese IME input when both GCS_COMPSTR and\n\tGCS_RESULTSTR set.\n\t</li>\n\t<li>\n\tWith Qt on Win32 add support for line copy format on clipboard, compatible with Visual Studio.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2167/\">Bug #2167</a>.\n\t</li>\n\t<li>\n\tOn Qt with default encoding (ISO 8859-1) fix bug where 'µ' (Micro Sign) case-insensitively matches '?'\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2168/\">Bug #2168</a>.\n\t</li>\n\t<li>\n\tOn GTK with Wayland fix display of windowed IME.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2149/\">Bug #2149</a>.\n\t</li>\n\t<li>\n\tFor Python programs, SciTE defaults to running python3 on Unix and pyw on Windows which will run\n\tthe most recently installed Python in many cases.\n\tSet the \"python.command\" property to override this.\n\tScripts distributed with Scintilla and SciTE are checked with Python 3 and may not work with Python 2.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite432.zip\">Release 4.3.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 6 March 2020.\n\t</li>\n\t<li>\n\tOn Win32 fix new bug that treated all dropped text as rectangular.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite431.zip\">Release 4.3.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 4 March 2020.\n\t</li>\n\t<li>\n\tAdd default argument for StyleContext::GetRelative.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1336/\">Feature #1336</a>.\n\t</li>\n\t<li>\n\tFix drag and drop between different encodings on Win32 by always providing CF_UNICODETEXT only.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2151/\">Bug #2151</a>.\n\t</li>\n\t<li>\n\tAutomatically scroll while dragging text.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/497/\">Feature #497</a>.\n\t</li>\n\t<li>\n\tOn Win32, the numeric keypad with Alt pressed can be used to enter characters by number.\n\tThis can produce unexpected results in non-numlock mode when function keys are assigned.\n\tPotentially problematic keys like Alt+KeypadUp are now ignored.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2152/\">Bug #2152</a>.\n\t</li>\n\t<li>\n\tCrash fixed with Direct2D on Win32 when updating driver.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2138/\">Bug #2138</a>.\n\t</li>\n\t<li>\n\tFor SciTE on Win32, fix crashes when Lua script closes application.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2155/\">Bug #2155</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite430.zip\">Release 4.3.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 16 January 2020.\n\t</li>\n\t<li>\n\tLexers made available as Lexilla library.\n\tTestLexers program with tests for Lexilla and lexers added in lexilla/test.\n\t</li>\n\t<li>\n\tSCI_SETILEXER implemented to use lexers from Lexilla or other sources.\n\t</li>\n\t<li>\n\tILexer5 interface defined provisionally to support use of Lexilla.\n\tThe details of this interface may change before being stabilised in Scintilla 5.0.\n\t</li>\n\t<li>\n\tSCI_LOADLEXERLIBRARY implemented on Cocoa.\n\t</li>\n\t<li>\n\tBuild Scintilla with SCI_EMPTYCATALOGUE to avoid making lexers available.\n\t</li>\n\t<li>\n\tLexer and folder added for Raku language.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1328/\">Feature #1328</a>.\n\t</li>\n\t<li>\n\tDon't clear clipboard before copying text with Qt.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2147/\">Bug #2147</a>.\n\t</li>\n\t<li>\n\tOn Win32, remove support for CF_TEXT clipboard format as Windows will convert to\n\tCF_UNICODETEXT.\n\t</li>\n\t<li>\n\tImprove IME behaviour on GTK.\n\tSet candidate position for windowed IME.\n\tImprove location of candidate window.\n\tPrevent movement of candidate window while typing.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2135/\">Bug #2135</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite423.zip\">Release 4.2.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 11 December 2019.\n\t</li>\n\t<li>\n\tFix failure in SciTE's Complete Symbol command.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite422.zip\">Release 4.2.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 7 December 2019.\n\t</li>\n\t<li>\n\tMove rather than grow selection when insertion at start.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2140/\">Bug #2140</a>.\n\t</li>\n\t<li>\n\tAllow target to have virtual space.\n\tAdd methods for finding the virtual space at start and end of multiple selections.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1316/\">Feature #1316</a>.\n\t</li>\n\t<li>\n\tSciTE on Win32 adds mouse button \"Forward\" and \"Backward\" key definitions for use in\n\tproperties like user.shortcuts.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1317/\">Feature #1317</a>.\n\t</li>\n\t<li>\n\tLexer and folder added for Hollywood language.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1324/\">Feature #1324</a>.\n\t</li>\n\t<li>\n\tHTML lexer treats custom tags from HTML5 as known tags. These contain \"-\" like \"custom-tag\".\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1299/\">Feature #1299</a>.\n\t</li>\n\t<li>\n\tHTML lexer fixes bug with some non-alphabetic characters in unknown tags.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1320/\">Feature #1320</a>.\n\t</li>\n\t<li>\n\tFix bug in properties file lexer where long lines were only styled for the first 1024 characters.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1933/\">Bug #1933</a>.\n\t</li>\n\t<li>\n\tRuby lexer recognizes squiggly heredocs.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1326/\">Feature #1326</a>.\n\t</li>\n\t<li>\n\tAvoid unnecessary IME caret movement on Win32.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1304/\">Feature #1304</a>.\n\t</li>\n\t<li>\n\tClear IME state when switching language on Win32.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2137/\">Bug #2137</a>.\n\t</li>\n\t<li>\n\tFixed drawing of translucent rounded rectangles on Win32 with Direct2D.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2144/\">Bug #2144</a>.\n\t</li>\n\t<li>\n\tSetting rectangular selection made faster.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2130/\">Bug #2130</a>.\n\t</li>\n\t<li>\n\tSciTE reassigns *.s extension to the GNU Assembler language from the S+ statistical language.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite421.zip\">Release 4.2.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 24 October 2019.\n\t</li>\n\t<li>\n\tAdd SCI_SETTABMINIMUMWIDTH to set the minimum width of tabs.\n\tThis allows minimaps or overviews to be laid out to match the full size editing view.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2118/\">Bug #2118</a>.\n\t</li>\n\t<li>\n\tSciTE enables use of SCI_ commands in user.context.menu.\n\t</li>\n \t<li>\n\tXML folder adds fold.xml.at.tag.open option to fold tags at the start of the tag \"&lt;\" instead of the end \"&gt;\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2128/\">Bug #2128</a>.\n\t</li>\n \t<li>\n\tMetapost lexer fixes crash with 'interface=none' comment.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2129/\">Bug #2129</a>.\n\t</li>\n \t<li>\n\tPerl lexer supports indented here-docs.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2121/\">Bug #2121</a>.\n\t</li>\n \t<li>\n\tPerl folder folds qw arrays.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1306/\">Feature #1306</a>.\n\t</li>\n \t<li>\n\tTCL folder can turn off whitespace flag by setting fold.compact property to 0.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2131/\">Bug #2131</a>.\n\t</li>\n \t<li>\n\tOptimize setting up keyword lists in lexers.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1305/\">Feature #1305</a>.\n\t</li>\n\t<li>\n\tUpdated case conversion and character categories to Unicode 12.1.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1315/\">Feature #1315</a>.\n\t</li>\n \t<li>\n\tOn Win32, stop the IME candidate window moving unnecessarily and position it better.<br />\n\tStop candidate window overlapping composition text and taskbar.<br />\n\tPosition candidate window closer to composition text.<br />\n\tStop candidate window moving while typing.<br />\n\tAlign candidate window to target part of composition text.<br />\n\tStop Google IME on Windows 7 moving while typing.<br />\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2120/\">Bug #2120</a>.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1300/\">Feature #1300</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite420.zip\">Release 4.2.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 5 July 2019.\n\t</li>\n \t<li>\n\tScintilla.iface adds line and pointer types, increases use of the position type, uses enumeration\n\ttypes in methods and properties, and adds enumeration aliases to produce better CamelCase\n\tidentifiers.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1297/\">Feature #1297</a>.\n\t</li>\n \t<li>\n\tSource of input (direct / IME composition / IME result) reported in SCN_CHARADDED so applications\n\tcan treat temporary IME composition input differently.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2038/\">Bug #2038</a>.\n\t</li>\n \t<li>\n\tLexer added for DataFlex.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1295/\">Feature #1295</a>.\n\t</li>\n \t<li>\n\tMatlab lexer now treats keywords as case-sensitive.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2112/\">Bug #2112</a>.\n\t</li>\n \t<li>\n\tSQL lexer fixes single quoted strings where '\" (quote, double quote) was seen as continuing the string.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2098/\">Bug #2098</a>.\n\t</li>\n \t<li>\n\tPlatform layers should use InsertCharacter method to perform keyboard and IME input, replacing\n\tAddCharUTF method.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1293/\">Feature #1293</a>.\n\t</li>\n \t<li>\n\tAdd CARETSTYLE_BLOCK_AFTER option to always display block caret after selection.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1924/\">Bug #1924</a>.\n\t</li>\n \t<li>\n\tOn Win32, limit text returned from WM_GETTEXT to the length specified in wParam.\n\tThis could cause failures when using assistive technologies like NVDA.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2110/\">Bug #2110</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2114/\">Bug #2114</a>.\n\t</li>\n \t<li>\n\tFix deletion of isolated invalid bytes.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2116/\">Bug #2116</a>.\n\t</li>\n \t<li>\n\tFix position of line caret when overstrike caret set to block.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2106/\">Bug #2106</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite417.zip\">Release 4.1.7</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 13 June 2019.\n\t</li>\n\t<li>\n\tFixes an incorrect default setting in SciTE which caused multiple visual features to fail to display.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite416.zip\">Release 4.1.6</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 10 June 2019.\n\t</li>\n\t<li>\n\tFor Visual C++ 2019, /std:c++latest now includes some C++20 features so switch to /std:c++17.\n\t</li>\n\t<li>\n\tSciTE supports editing files larger than 2 gigabytes when built as a 64-bit application.\n\t</li>\n \t<li>\n\tLexer added for X12.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1280/\">Feature #1280</a>.\n\t</li>\n \t<li>\n\tCMake folder folds function - endfunction.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1289/\">Feature #1289</a>.\n\t</li>\n \t<li>\n\tVB lexer adds support for VB2017 binary literal &amp;B and digit separators 123_456.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1288/\">Feature #1288</a>.\n\t</li>\n\t<li>\n\tImproved performance of line folding code on large files when no folds are contracted.\n\tThis improves the time taken to open or close large files.\n\t</li>\n\t<li>\n\tFix bug where changing identifier sets in lexers preserved previous identifiers.\n\t</li>\n\t<li>\n\tFixed bug where changing to Unicode would rediscover line end positions even if still\n\tsticking to ASCII (not Unicode NEL, LS, PS) line ends.\n\tOnly noticeable on huge files with over 100,000 lines.\n\t</li>\n \t<li>\n\tChanged behaviour of SCI_STYLESETCASE(*,SC_CASE_CAMEL) so that it only treats 'a-zA-Z'\n\tas word characters because this covers the feature's intended use (viewing case-insensitive ASCII-only\n\tkeywords in a specified casing style) and simplifies the behaviour and code.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1238/\">Feature #1238</a>.\n\t</li>\n \t<li>\n\tIn SciTE added Camel case option \"case:c\" for styles to show keywords with initial capital.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite415.zip\">Release 4.1.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 17 April 2019.\n\t</li>\n \t<li>\n\tOn Win32, removed special handling of non-0 wParam to WM_PAINT.\n\t</li>\n \t<li>\n\tImplement high-priority idle on Win32 to make redraw smoother and more efficient.\n\t</li>\n\t<li>\n\tAdd vertical bookmark symbol SC_MARK_VERTICALBOOKMARK.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1276/\">Feature #1276</a>.\n\t</li>\n \t<li>\n\tSet default fold display text SCI_SETDEFAULTFOLDDISPLAYTEXT(text).\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1272/\">Feature #1272</a>.\n\t</li>\n \t<li>\n\tAdd SCI_SETCHARACTERCATEGORYOPTIMIZATION API to optimize speed\n\tof character category features like determining whether a character is a space or number\n\tat the expense of memory.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1259/\">Feature #1259</a>.\n\t</li>\n \t<li>\n\tImprove the styling of numbers in Nim.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1268/\">Feature #1268</a>.\n\t</li>\n \t<li>\n\tFix exception when inserting DBCS text.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2093/\">Bug #2093</a>.\n\t</li>\n\t<li>\n\tImprove performance of accessibility on GTK.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2094/\">Bug #2094</a>.\n\t</li>\n \t<li>\n\tFix text reported for deletion with accessibility on GTK.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2095/\">Bug #2095</a>.\n\t</li>\n \t<li>\n\tFix flicker when inserting primary selection on GTK.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2087/\">Bug #2087</a>.\n\t</li>\n \t<li>\n\tSupport coloured text in Windows 8.1+.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1277/\">Feature #1277</a>.\n\t</li>\n \t<li>\n\tAvoid potential long hangs with idle styling for huge documents on Cocoa and GTK.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite414.zip\">Release 4.1.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 7 March 2019.\n\t</li>\n\t<li>\n\tCalltips implemented on Qt.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1548/\">Bug #1548</a>.\n\t</li>\n \t<li>\n\tBlock caret in overtype mode SCI_SETCARETSTYLE(caretStyle | CARETSTYLE_OVERSTRIKE_BLOCK).\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1217/\">Feature #1217</a>.\n\t</li>\n \t<li>\n\tSciTE supports changing caret style via caret.style property.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1264/\">Feature #1264</a>.\n\t</li>\n \t<li>\n\tLexer added for .NET's Common Intermediate Language CIL.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1265/\">Feature #1265</a>.\n\t</li>\n \t<li>\n\tThe C++ lexer, with styling.within.preprocessor on, now interprets \"(\" in preprocessor \"#if(\"\n\tas an operator instead of part of the directive. This improves folding as well which could become\n\tunbalanced.\n\t</li>\n \t<li>\n\tFix raw strings in Nim.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1253/\">Feature #1253</a>.\n\t</li>\n \t<li>\n\tFix inconsistency with dot styling in Nim.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1260/\">Feature #1260</a>.\n\t</li>\n \t<li>\n\tEnhance the styling of backticks in Nim.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1261/\">Feature #1261</a>.\n\t</li>\n \t<li>\n\tEnhance raw string identifier styling in Nim.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1262/\">Feature #1262</a>.\n\t</li>\n \t<li>\n\tFix fold behaviour with comments in Nim.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1254/\">Feature #1254</a>.\n\t</li>\n \t<li>\n\tFix TCL lexer recognizing '\"' after \",\" inside a bracketed substitution.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1947/\">Bug #1947</a>.\n\t</li>\n \t<li>\n\tFix garbage text from SCI_MOVESELECTEDLINESUP and SCI_MOVESELECTEDLINESDOWN\n\tfor rectangular or thin selection by performing no action.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2078/\">Bug #2078</a>.\n\t</li>\n \t<li>\n\tEnsure container notified if Insert pressed when caret off-screen.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2083/\">Bug #2083</a>.\n\t</li>\n \t<li>\n\tFix memory leak when checking running instance on GTK.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1267/\">Feature #1267</a>.\n\t</li>\n\t<li>\n\tPlatform layer font cache removed on Win32 as there is a platform-independent cache.\n\t</li>\n\t<li>\n\tSciTE for GTK easier to build on macOS.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2084/\">Bug #2084</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite413.zip\">Release 4.1.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 10 January 2019.\n\t</li>\n\t<li>\n\tAdd SCI_SETCOMMANDEVENTS API to allow turning off command events as they\n\tcan be a significant performance cost.\n\t</li>\n\t<li>\n\tImprove efficiency of idle wrapping by wrapping in blocks as large as possible while\n\tstill remaining responsive.\n\t</li>\n\t<li>\n\tUpdated case conversion and character categories to Unicode 11.\n\t</li>\n\t<li>\n\tErrorlist lexer recognizes negative line numbers as some programs show whole-file\n\terrors occurring on line -1.\n\tSciTE's parsing of diagnostics also updated to handle this case.\n\t</li>\n \t<li>\n\tAdded \"nim\" lexer (SCLEX_NIM) for the Nim language which was previously called Nimrod.\n\tFor compatibility, the old \"nimrod\" lexer is still present but is deprecated and will be removed at the\n\tnext major version.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1242/\">Feature #1242</a>.\n\t</li>\n \t<li>\n\tThe Bash lexer implements substyles for multiple sets of keywords and supports SCI_PROPERTYNAMES.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2054/\">Bug #2054</a>.\n\t</li>\n \t<li>\n\tThe C++ lexer interprets continued preprocessor lines correctly by reading all of\n\tthe logical line.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2062/\">Bug #2062</a>.\n\t</li>\n \t<li>\n\tThe C++ lexer interprets preprocessor arithmetic expressions containing multiplicative and additive\n\toperators correctly by following operator precedence rules.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2069/\">Bug #2069</a>.\n\t</li>\n \t<li>\n\tThe EDIFACT lexer handles message groups as well as messages.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1247/\">Feature #1247</a>.\n\t</li>\n \t<li>\n\tFor SciTE's Find in Files, allow case-sensitivity and whole-word options when running\n\ta user defined command.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2053/\">Bug #2053</a>.\n\t</li>\n\t<li>\n\tNotify with SC_UPDATE_SELECTION when user performs a multiple selection add.\n\t</li>\n\t<li>\n\tOn macOS 10.14 Cocoa, fix incorrect horizontal offset.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2022/\">Bug #2022</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, fix a crash that occurred when entering a dead key diacritic then a character\n\tthat can not take that diacritic, such as option+e (acute accent) followed by g.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2061/\">Bug #2061</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, use dark info bar background when system is set to Dark Appearance.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2055/\">Bug #2055</a>.\n\t</li>\n\t<li>\n\tFixed a crash on Cocoa in bidirectional mode where some patterns of invalid UTF-8\n\tcaused failures to create Unicode strings.\n\t</li>\n\t<li>\n\tSCI_MARKERADD returns -1 for invalid lines as documented instead of 0.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2051/\">Bug #2051</a>.\n\t</li>\n\t<li>\n\tImprove performance of text insertion when Unicode line indexing off.\n\t</li>\n\t<li>\n\tFor Qt on Windows, stop specifying -std:c++latest as that is no longer needed\n\tto enable C++17 with MSVC 2017 and Qt 5.12 and it caused duplicate flag warnings.\n\t</li>\n\t<li>\n\tOn Linux, enable Lua to access dynamic libraries.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2058/\">Bug #2058</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite412.zip\">Release 4.1.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 2 October 2018.\n\t</li>\n\t<li>\n\tC++ lexer fixes evaluation of \"#elif\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2045/\">Bug #2045</a>.\n\t</li>\n\t<li>\n\tMarkdown lexer fixes highlighting of non-ASCII characters in links.\n\t</li>\n\t<li>\n\tSciTE on Win32 drops menukey feature, makes Del key work again in find and replace strips\n\tand disables F5 while command running.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/2044/\">Bug #2044</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite411.zip\">Release 4.1.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 9 September 2018.\n\t</li>\n\t<li>\n\tOptional indexing of line starts in UTF-8 documents by UTF-32 code points and UTF-16 code units added.\n\tThis can improve performance for clients that provide UTF-32 or UTF-16 interfaces or that need to interoperate\n\twith UTF-32 or UTF-16 components.\n\t</li>\n\t<li>\n\tLexers added for SAS and Stata.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1185/\">Feature #1185.</a>\n\t</li>\n\t<li>\n\tShell folder folds \"if\", \"do\", and \"case\".\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1144/\">Feature #1144.</a>\n\t</li>\n\t<li>\n\tSciTE's menukey feature implemented on Windows.\n\t</li>\n\t<li>\n\tFor SciTE on Windows, user defined strip lists are now scrollable.\n\tCursor no longer flickers in edit and combo boxes.\n\tFocus in and out events occur for combo boxes.\n\t</li>\n\t<li>\n\tFix a leak in the bidirectional code on Win32.\n\t</li>\n\t<li>\n\tFix crash on Win32 when switching technology to default after setting bidirectional mode.\n\t</li>\n\t<li>\n\tFix margin cursor on Cocoa to point more accurately.\n\t</li>\n\t<li>\n\tFix SciTE crash on GTK+ when using director interface.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite410.zip\">Release 4.1.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 19 June 2018.\n\t</li>\n\t<li>\n\tExperimental and incomplete support added for bidirectional text on Windows using DirectWrite and Cocoa for\n\tUTF-8 documents by calling SCI_SETBIDIRECTIONAL(SC_BIDIRECTIONAL_L2R).\n\tThis allows documents that contain Arabic or Hebrew to be edited more easily in a way that is similar\n\tto other editors.\n\t</li>\n\t<li>\n\tINDIC_GRADIENT and INDIC_GRADIENTCENTRE indicator types added.\n\tINDIC_GRADIENT starts with a specified colour and alpha at top of line and fades\n\tto fully transparent at bottom.\n\tINDIC_GRADIENTCENTRE starts with a specified colour and alpha at centre of line and fades\n\tto fully transparent at top and bottom.\n\t</li>\n\t<li>\n\tWrap indent mode SC_WRAPINDENT_DEEPINDENT added which indents two tabs from previous line.\n\t</li>\n\t<li>\n\tIndicators are drawn for line end characters when displayed.\n\t</li>\n\t<li>\n\tMost invalid bytes in DBCS encodings are displayed as blobs to make problems clear\n\tand ensure something is shown.\n\t</li>\n\t<li>\n\tOn Cocoa, invalid text in DBCS encodings will be interpreted through the\n\tsingle-byte MacRoman encoding as that will accept any byte.\n\t</li>\n\t<li>\n\tDiff lexer adds styles for diffs containing patches.\n\t</li>\n\t<li>\n\tCrashes fixed on macOS for invalid DBCS characters when dragging text,\n\tchanging case of text, case-insensitive searching, and retrieving text as UTF-8.\n\t</li>\n\t<li>\n\tRegular expression crash fixed on macOS when linking to libstdc++.\n\t</li>\n\t<li>\n\tSciTE on GTK+, when running in single-instance mode, now forwards all command line arguments\n\tto the already running instance.\n\tThis allows \"SciTE filename -goto:line\" to work.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite405.zip\">Release 4.0.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 10 May 2018.\n\t</li>\n\t<li>\n\tAdd experimental SC_DOCUMENTOPTION_TEXT_LARGE option to accommodate documents larger than\n\t2 GigaBytes.\n\t</li>\n\t<li>\n\tAdditional print option SC_PRINT_SCREENCOLOURS prints with the same colours used on screen\n\tincluding line numbers.\n\t</li>\n\t<li>\n\tSciTE can read settings in EditorConfig format when enabled with editor.config.enable property.\n\t</li>\n\t<li>\n\tEDIFACT lexer adds property lexer.edifact.highlight.un.all to highlight all UN* segments.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1166/\">Feature #1166.</a>\n\t</li>\n\t<li>\n\tFortran folder understands \"change team\" and \"endteam\".\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1216/\">Feature #1216.</a>\n\t</li>\n\t<li>\n\tSet the last X chosen when SCI_REPLACESEL called to ensure macros work\n\twhen text insertion followed by caret up or down.\n\t</li>\n\t<li>\n\tBugs fixed in regular expression searches in Scintilla where some matches did not occur in an\n\teffort to avoid infinite loops when replacing on empty matches like \"^\" and \"$\".\n\tApplications should always handle empty matches in a way that avoids infinite loops, commonly\n\tby incrementing the search position after replacing an empty match.\n\tSciTE fixes a bug where replacing \"^\" always matched on the first line even when it was an\n\t\"in selection\" replace and the selection started after the line start.\n\t</li>\n\t<li>\n\tBug fixed in SciTE where invalid numeric properties could crash.\n\t</li>\n\t<li>\n\tRuntime warnings fixed with SciTE on GTK after using Find in Files.\n\t</li>\n\t<li>\n\tSciTE on Windows find and replace strips place caret at end of text after search.\n\t</li>\n\t<li>\n\tBug fixed with SciTE on macOS where corner debris appeared in the margin when scrolling.\n\tFixed by not completely hiding the status bar so the curved corner is no longer part of the\n\tscrolling region.\n\tBy default, 4 pixels of the status bar remain visible and this can be changed with\n\tthe statusbar.minimum.height property or turned off if the debris are not a problem by\n\tsetting the property to 0.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite404.zip\">Release 4.0.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 10 April 2018.\n\t</li>\n\t<li>\n\tOn Win32, the standard makefiles build a libscintilla static library as well as the existing dynamic libraries.\n\tThe statically linked version of SciTE, Sc1, links to this static library. A new file, ScintillaDLL.cxx, provides\n\tthe DllMain function required for a stand-alone Scintilla DLL. Build and project files should include this\n\tfile when producing a DLL and omit it when producing a static library or linking Scintilla statically.\n\tThe STATIC_BUILD preprocessor symbol is no longer used.\n\t</li>\n\t<li>\n\tOn Win32, Direct2D support is no longer automatically detected during build.\n\tDISABLE_D2D may still be defined to remove Direct2D features.\n\t</li>\n\t<li>\n\tIn some cases, invalid UTF-8 is handled in a way that is a little friendlier.\n\tFor example, when copying to the clipboard on Windows, an invalid lead byte will be copied as the\n\tequivalent ISO 8859-1 character and will not hide the following byte.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1211/\">Feature #1211.</a>\n\t</li>\n\t<li>\n\tLexer added for the Maxima computer algebra language.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1210/\">Feature #1210.</a>\n\t</li>\n\t<li>\n\tFix hang in Lua lexer when lexing a label up to the terminating \"::\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1999/\">Bug #1999</a>.\n\t</li>\n\t<li>\n\tLua lexer matches identifier chains with dots and colons.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1952/\">Bug #1952</a>.\n\t</li>\n\t<li>\n\tFor rectangular selections, pressing Home or End now moves the caret to the Home or End\n\tposition instead of the limit of the rectangular selection.\n\t</li>\n\t<li>\n\tFix move-extends-selection mode for rectangular and line selections.\n\t</li>\n\t<li>\n\tOn GTK+, change lifetime of selection widget to avoid runtime warnings.\n\t</li>\n\t<li>\n\tFix building on Mingw/MSYS to perform file copies and deletions.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1993/\">Bug #1993</a>.\n\t</li>\n\t<li>\n\tSciTE can match a wider variety of file patterns where '*' is in the middle of\n\tthe pattern and where there are multiple '*'.\n\tA '?' matches any single character.\n\t</li>\n\t<li>\n\tSciTE on Windows can execute Python scripts directly by name when on path.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1209/\">Feature #1209.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows Find in Files checks for cancel after every 10,000 lines read so\n\tcan be stopped on huge files.\n\t</li>\n\t<li>\n\tSciTE remembers entered values in lists in more cases for find, replace and find in files.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1715/\">Bug #1715</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite403.zip\">Release 4.0.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 12 February 2018.\n\t</li>\n\t<li>\n\tFeatures from C++14 and C++17 are used more often, with build files now specifying\n\tc++17, gnu++17, c++1z, or std:c++latest (MSVC).\n\tRequires Microsoft Visual C++ 2017.5, GCC 7, Xcode 9.2 or Clang 4.0 or newer.\n\t</li>\n\t<li>\n\tSCI_CREATEDOCUMENT adds a bytes argument to allocate memory for an initial size.\n\tSCI_CREATELOADER and SCI_CREATEDOCUMENT add a documentOption argument to\n\tallow choosing different document capabilities.\n\t</li>\n\t<li>\n\tAdd SC_DOCUMENTOPTION_STYLES_NONE option to stop allocating memory for styles.\n\t</li>\n\t<li>\n\tAdd SCI_GETMOVEEXTENDSSELECTION to allow applications to add more\n\tcomplex selection commands.\n\t</li>\n\t<li>\n\tSciTE property bookmark.symbol allows choosing symbol used for bookmarks.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1208/\">Feature #1208.</a>\n\t</li>\n\t<li>\n\tImprove VHDL lexer's handling of character literals and escape characters in strings.\n\t</li>\n\t<li>\n\tFix double tap word selection on Windows 10 1709 Fall Creators Update.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1983/\">Bug #1983</a>.\n\t</li>\n\t<li>\n\tFix closing autocompletion lists on Cocoa for macOS 10.13 where the window\n\twas emptying but staying visible.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1981/\">Bug #1981</a>.\n\t</li>\n\t<li>\n\tFix drawing failure on Cocoa with animated find indicator in large files with macOS 10.12\n\tby disabling animation.\n\t</li>\n\t<li>\n\tSciTE on GTK+ installs its desktop file as non-executable and supports the common\n\tLDLIBS make variable.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1989/\">Bug #1989</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1990/\">Bug #1990</a>.\n\t</li>\n\t<li>\n\tSciTE shows correct column number when caret in virtual space.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1991/\">Bug #1991</a>.\n\t</li>\n\t<li>\n\tSciTE preserves selection positions when saving with strip.trailing.spaces\n\tand virtual space turned on.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1992/\">Bug #1992</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite402.zip\">Release 4.0.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 26 October 2017.\n\t</li>\n\t<li>\n\tFix HTML lexer handling of Django so that nesting a  &#123;&#123; &#125;&#125; or &#123;% %&#125;\n\tDjango tag inside of a &#123;# #&#125; Django comment does not break highlighting of rest of file\n\t</li>\n\t<li>\n\tThe Matlab folder now treats \"while\" as a fold start.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1985/\">Bug #1985</a>.\n\t</li>\n\t<li>\n\tFix failure on Cocoa with animated find indicator in large files with macOS 10.13\n\tby disabling animation on 10.13.\n\t</li>\n\t<li>\n\tFix Cocoa hang when Scintilla loaded from SMB share on macOS 10.13.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1979/\">Bug #1979</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite401.zip\">Release 4.0.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 23 October 2017.\n\t</li>\n\t<li>\n\tThe ILoader interface is defined in its own header ILoader.h as it is not\n\trelated to lexing so doesn't belong in ILexer.h.\n\t</li>\n\t<li>\n\tThe Scintilla namespace is always active for internal symbols and for the lexer interfaces\n\tILexer4 and IDocument.\n\t</li>\n\t<li>\n\tThe Baan lexer checks that matches to 3rd set of keywords are function calls and leaves as identifiers if not.\n\tBaan lexer and folder support #context_on / #context_off preprocessor feature.\n\t</li>\n\t<li>\n\tThe C++ lexer improved preprocessor conformance.<br />\n\tDefault value of 0 for undefined preprocessor symbols.<br />\n\t#define A is treated as #define A 1.<br />\n\t\"defined A\" removes \"A\" before replacing \"defined\" with value.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1966/\">Bug #1966</a>.\n\t</li>\n\t<li>\n\tThe Python folder treats triple-quoted f-strings like triple-quoted strings.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1977/\">Bug #1977</a>.\n\t</li>\n\t<li>\n\tThe SQL lexer uses sql.backslash.escapes for double quoted strings.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1968/\">Bug #1968</a>.\n\t</li>\n\t<li>\n\tMinor undefined behaviour fixed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1978/\">Bug #1978</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, improve scrolling on macOS 10.12.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1885/\">Bug #1885</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, fix line selection by clicking in the margin when scrolled.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1971/\">Bug #1971</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite400.zip\">Release 4.0.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 16 August 2017.\n\t</li>\n\t<li>\n\tThis is an unstable release with changes to interfaces used for lexers and platform access.\n\tSome more changes may occur to internal and external interfaces before stability is regained with 4.1.0.\n\t</li>\n\t<li>\n\tUses C++14 features. Requires Microsoft Visual C++ 2017, GCC 7, and Clang 4.0 or newer.\n\t</li>\n\t<li>\n\tSupport dropped for GTK+ versions before 2.24.\n\t</li>\n\t<li>\n\tThe lexer interfaces ILexer and ILexerWithSubStyles, along with additional style metadata methods, were merged into ILexer4.\n\tMost lexers will need to be updated to match the new interfaces.\n\t</li>\n\t<li>\n\tThe IDocumentWithLineEnd interface was merged into IDocument.\n\t</li>\n\t<li>\n\tThe platform layer interface has changed with unused methods removed, a new mechanism for\n\treporting events, removal of methods that take individual keyboard modifiers, and removal of old timer methods.\n\t</li>\n\t<li>\n\t<a href=\"StyleMetadata.html\">Style metadata</a> may be retrieved from lexers that support this through the SCI_GETNAMEDSTYLES, SCI_NAMEOFSTYLE,\n\tSCI_TAGSOFSTYLE, and SCI_DESCRIPTIONOFSTYLE APIs.\n\t</li>\n\t<li>\n\tThe Cocoa platform layer uses Automatic Reference Counting (ARC).\n\t</li>\n\t<li>\n\tThe default encoding in Scintilla is UTF-8.\n\t</li>\n\t<li>\n\tAn SCN_AUTOCSELECTIONCHANGE notification is sent when items are highlighted in an autocompletion or user list.\n\t</li>\n\t<li>\n\tThe data parameter to ILoader::AddData made const.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1955/\">Bug #1955</a>.\n\t</li>\n\t<li>\n\tSciTE's embedded Lua interpreter updated to Lua 5.3.\n\t</li>\n\t<li>\n\tSciTE allows event handlers to be arbitrary callables, not just functions.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1190/\">Feature #1190.</a>\n\t</li>\n\t<li>\n\tSciTE allows user.shortcuts to be defined with symbolic Scintilla messages like\n\t'Ctrl+L|SCI_LINEDELETE|'.\n\t</li>\n\t<li>\n\tThe Matlab lexer treats 'end' as a number rather than a keyword when used as an index.\n\tThis also stops incorrect folding.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1951/\">Bug #1951</a>.\n\t</li>\n\t<li>\n\tThe Matlab folder implements \"fold\", \"fold.comment\", and \"fold.compact\" properties.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1965/\">Bug #1965</a>.\n\t</li>\n\t<li>\n\tThe Rust lexer recognizes 'usize' numeric literal suffixes.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1919/\">Bug #1919</a>.\n\t</li>\n\t<li>\n\tEnsure redraw when application changes overtype mode so caret change visible even when not blinking.\n\tNotify application with SC_UPDATE_SELECTION when overtype changed - previously\n\tsent SC_UPDATE_CONTENT.\n\t</li>\n\t<li>\n\tFix drawing failure when in wrap mode for delete to start/end of line which\n\taffects later lines but did not redraw them.\n\tAlso fixed drawing for wrap mode on GTK+ 2.x.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1949/\">Bug #1949</a>.\n\t</li>\n\t<li>\n\tOn GTK+ fix drawing problems including incorrect scrollbar redrawing and flickering of text.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1876/\">Bug #1876</a>.\n\t</li>\n\t<li>\n\tOn Linux, both for GTK+ and Qt, the default modifier key for rectangular selection is now Alt.\n\tThis is the same as Windows and macOS.\n\tThis was changed from Ctrl as window managers are less likely to intercept Alt+Drag for\n\tmoving windows than in the past.\n\t</li>\n\t<li>\n\tOn Cocoa, fix doCommandBySelector but avoid double effect of 'delete'\n\tkey.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1958/\">Bug #1958</a>.\n\t</li>\n\t<li>\n\tOn Qt, the updateUi signal includes the 'updated' flags.\n\tNo updateUi signal is sent for focus in events.\n\tThese changes make Qt behave more like the other platforms.\n\t</li>\n\t<li>\n\tOn Qt, dropping files on Scintilla now fires the SCN_URIDROPPED notification\n\tinstead of inserting text.\n\t</li>\n\t<li>\n\tOn Qt, focus changes send the focusChanged signal.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1957/\">Bug #1957</a>.\n\t</li>\n\t<li>\n\tOn Qt, mouse tracking is reenabled when the window is reshown.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1948/\">Bug #1948</a>.\n\t</li>\n\t<li>\n\tOn Windows, the DirectWrite modes SC_TECHNOLOGY_DIRECTWRITEDC and\n\tSC_TECHNOLOGY_DIRECTWRITERETAIN are no longer provisional.\n\t</li>\n\t<li>\n\tSciTE on macOS fixes a crash when platform-specific and platform-independent\n\tsession restoration clashed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1960/\">Bug #1960</a>.\n\t</li>\n\t<li>\n\tSciTE on GTK+ implements find.close.on.find.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1152/\">Bug #1152</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1254/\">Bug #1254</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1762/\">Bug #1762</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/849/\">Feature #849</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scintilla376.zip\">Release 3.7.6</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 8 August 2017.\n\t</li>\n\t<li>\n\tThis is the first release of the\n\t<a href=\"https://scintilla.sourceforge.io/LongTermDownload.html\">long term branch</a>\n\twhich avoids using features from C++14 or later in order to support older systems.\n\t</li>\n\t<li>\n\tThe Baan lexer correctly highlights numbers when followed by an operator.\n\t</li>\n\t<li>\n\tOn Cocoa, fix a bug with retrieving encoded bytes.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite375.zip\">Release 3.7.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 26 May 2017.\n\t</li>\n\t<li>\n\tThis is the final release of SciTE 3.x.\n\t</li>\n\t<li>\n\tSupport dropped for Microsoft Visual C++ 2013 due to increased use of C++11 features.\n\t</li>\n\t<li>\n\tAdded a caret line frame as an alternative visual for highlighting the caret line.\n\t</li>\n\t<li>\n\tAdded \"Reverse Selected Lines\" feature.\n\t</li>\n\t<li>\n\tSciTE adds \"Select All Bookmarks\" command.\n\t</li>\n\t<li>\n\tSciTE adds a save.path.suggestion setting to suggest a file name when saving an\n\tunnamed buffer.\n\t</li>\n\t<li>\n\tUpdated case conversion and character categories to Unicode 9.\n\t</li>\n\t<li>\n\tThe Baan lexer recognizes numeric literals in a more compliant manner including\n\thexadecimal numbers and exponentials.\n\t</li>\n\t<li>\n\tThe Bash lexer recognizes strings in lists in more cases.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1944/\">Bug #1944</a>.\n\t</li>\n\t<li>\n\tThe Fortran lexer recognizes a preprocessor line after a line continuation &amp;.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1935/\">Bug #1935</a>.\n\t</li>\n\t<li>\n\tThe Fortran folder can fold comments.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1936/\">Bug #1936</a>.\n\t</li>\n\t<li>\n\tThe PowerShell lexer recognizes escaped quotes in strings.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1929/\">Bug #1929</a>.\n\t</li>\n\t<li>\n\tThe Python lexer recognizes identifiers more accurately when they include non-ASCII characters.\n\t</li>\n\t<li>\n\tThe Python folder treats comments at the end of the file as separate from the preceding structure.\n\t</li>\n\t<li>\n\tThe YAML lexer recognizes comments in more situations and styles a\n\t\"...\" line like a \"---\" line.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1931/\">Bug #1931</a>.\n\t</li>\n\t<li>\n\tUpdate scroll bar when annotations added, removed, or visibility changed.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1187/\">Feature #1187.</a>\n\t</li>\n\t<li>\n\tCanceling modes with the Esc key preserves a rectangular selection.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1940/\">Bug #1940</a>.\n\t</li>\n\t<li>\n\tBuilds are made with a sorted list of lexers to be more reproducible.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1946/\">Bug #1946</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, a leak of mouse tracking areas was fixed.\n\t</li>\n\t<li>\n\tOn Cocoa, the autocompletion is 4 pixels wider to avoid text truncation.\n\t</li>\n\t<li>\n\tOn Windows, stop drawing a focus rectangle on the autocompletion list and\n\traise the default list length to 9 items.\n\t</li>\n\t<li>\n\tSciTE examines at most 1 MB of a file to automatically determine indentation\n\tfor indent.auto to avoid a lengthy pause when loading very large files.\n\t</li>\n\t<li>\n\tSciTE user interface uses lighter colours and fewer 3D elements to match current desktop environments.\n\t</li>\n\t<li>\n\tSciTE sets buffer dirty and shows message when file deleted if load.on.activate on.\n\t</li>\n\t<li>\n\tSciTE on Windows Find strip Find button works in incremental no-close mode.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1926/\">Bug #1926</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite374.zip\">Release 3.7.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 21 March 2017.\n\t</li>\n\t<li>\n\tRequires a C++11 compiler. GCC 4.8 and MSVC 2015 are supported.\n\t</li>\n\t<li>\n\tSupport dropped for Windows NT 4.\n\t</li>\n\t<li>\n\tAccessibility support may be queried with SCI_GETACCESSIBILITY.\n\tOn GTK+, accessibility may be disabled by calling SCI_SETACCESSIBILITY.\n\t</li>\n\t<li>\n\tLexer added for \"indent\" language which is styled as plain text but folded by indentation level.\n\t</li>\n\t<li>\n\tThe Progress ABL lexer handles nested comments where comment starts or ends\n\tare adjacent like \"/*/*\" or \"*/*/\".\n\t</li>\n\t<li>\n\tIn the Python lexer, improve f-string support.\n\tAdd support for multiline expressions in triple quoted f-strings.\n\tHandle nested \"()\", \"[]\", and \"{}\" in f-string expressions and terminate expression colouring at \":\" or \"!\".\n\tEnd f-string if ending quote is seen in a \"{}\" expression.\n\tFix terminating single quoted f-string at EOL.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1918/\">Bug #1918</a>.\n\t</li>\n\t<li>\n\tThe VHDL folder folds an \"entity\" on the first line of the file.\n\t</li>\n\t<li>\n\tFor IMEs, do not clear selected text when there is no composition text to show.\n\t</li>\n\t<li>\n\tFix to crash with fold tags where line inserted at start.\n\t</li>\n\t<li>\n\tFix to stream selection mode when moving caret up or down.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1905/\">Bug #1905</a>.\n\t</li>\n\t<li>\n\tDrawing fixes for fold tags include fully drawing lines and not overlapping some\n\tdrawing and ensuring edges and mark underlines are visible.\n\t</li>\n\t<li>\n\tFix Cocoa failure to display accented character chooser for European\n\tlanguages by partially reverting a change made to prevent a crash with\n\tChinese input by special-casing the Cangjie input source.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1881/\">Bug #1881</a>.\n\t</li>\n\t<li>\n\tFix potential problems with IME on Cocoa when document contains invalid\n\tUTF-8.\n\t</li>\n\t<li>\n\tFix crash on Cocoa with OS X 10.9 due to accessibility API not available.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1915/\">Bug #1915</a>.\n\t</li>\n\t<li>\n\tImproved speed of accessibility code on GTK+ by using additional memory\n\tas a cache.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1910/\">Bug #1910</a>.\n\t</li>\n\t<li>\n\tFix crash in accessibility code on GTK+ &lt; 3.3.6 caused by previous bug fix.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1907/\">Bug #1907</a>.\n\t</li>\n\t<li>\n\tFix to prevent double scrolling on GTK+ with X11.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1901/\">Bug #1901</a>.\n\t</li>\n\t<li>\n\tSciTE on GTK+ adds an \"accessibility\" property to allow disabling accessibility\n\ton GTK+ as an optimization.\n\t</li>\n\t<li>\n\tSciTE on GTK+ has changed file chooser behaviour for some actions:\n\toverwriting an existing file shows a warning;\n\tthe default session file name \"SciTE.session\" is shown and a \"*.session\" filter is applied;\n\tappropriate filters are applied when exporting;\n\tthe current file name is displayed in \"Save As\" even when that file no longer exists.\n\t</li>\n\t<li>\n\tSciTE fixed a bug where, on GTK+, when the output pane had focus, menu commands\n\tperformed by mouse were sent instead to the edit pane.\n\t</li>\n\t<li>\n\tSciTE on Windows 8+ further restricts the paths searched for DLLs to the application\n\tand system directories which may prevent some binary planting attacks.\n\t</li>\n\t<li>\n\tFix failure to load Direct2D on Windows when used on old versions of Windows.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1653/\">Bug #1653</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite373.zip\">Release 3.7.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 19 February 2017.\n\t</li>\n\t<li>\n\tDisplay block caret over the character at the end of a selection to be similar\n\tto other editors.\n\t</li>\n\t<li>\n\tIn SciTE can choose colours for fold markers.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1172/\">Feature #1172.</a>\n\t</li>\n\t<li>\n\tIn SciTE can hide buffer numbers in tabs.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1173/\">Feature #1173.</a>\n\t</li>\n\t<li>\n\tThe Diff lexer recognizes deleted lines that start with \"--- \".\n\t</li>\n\t<li>\n\tThe Lua lexer requires the first line to start with \"#!\" to be treated as a shebang comment,\n\tnot just \"#\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1900/\">Bug #1900</a>.\n\t</li>\n\t<li>\n\tThe Matlab lexer requires block comment start and end to be alone on a line.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1902/\">Bug #1902</a>.\n\t</li>\n\t<li>\n\tThe Python lexer supports f-strings with new styles, allows Unicode identifiers,\n\tand no longer allows @1 to be a decorator.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1848/\">Bug #1848</a>.\n\t</li>\n\t<li>\n\tFix folding inconsistency when fold header added above a folded part.\n\tAvoid unnecessary unfolding when a deletion does not include a line end.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1896/\">Bug #1896</a>.\n\t</li>\n\t<li>\n\tFix finalization crash on Cocoa.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1909/\">Bug #1909</a>.\n\t</li>\n\t<li>\n\tSciTE on GTK+ can have a wide divider between the panes with the\n\tsplit.wide property.\n\t</li>\n\t<li>\n\tFix display of autocompletion lists and calltips on GTK+ 3.22 on Wayland.\n\tNewer APIs used on GTK+ 3.22 as older APIs were deprecated.\n\t</li>\n\t<li>\n\tFix crash in accessibility code on GTK+ due to signal receipt after destruction.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1907/\">Bug #1907</a>.\n\t</li>\n\t<li>\n\tMake trackpad scrolling work on Wayland.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1901/\">Bug #1901</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite372.zip\">Release 3.7.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 30 December 2016.\n\t</li>\n\t<li>\n\tMinimize redrawing for SCI_SETSELECTIONN* APIs.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1888/\">Bug #1888</a>.\n\t</li>\n\t<li>\n\tUse more precision to allow selecting individual lines in files with\n\tmore than 16.7 million lines.\n\t</li>\n\t<li>\n\tFor Qt 5, define QT_WS_MAC or QT_WS_X11 on those platforms.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1887/\">Bug #1887</a>.\n\t</li>\n\t<li>\n\tFor Cocoa, fix crash on view destruction with macOS 10.12.2.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1891/\">Bug #1891</a>.\n\t</li>\n\t<li>\n\tFix crash on GTK+ &lt;3.8 due to incorrect lifetime of accessibility object.\n\tMore accurate reporting of attribute ranges and deletion lengths for accessibility.\n\t</li>\n\t<li>\n\tIn SciTE, if a Lua script causes a Scintilla failure exception, display error\n\tmessage in output pane instead of exiting.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1773/\">Bug #1773</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite371.zip\">Release 3.7.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 4 December 2016.\n\t</li>\n\t<li>\n\tThe Scintilla namespace is no longer applied to struct definitions in Scintilla.h even\n\twhen SCI_NAMESPACE defined.\n\tClient code should not define SCI_NAMESPACE.\n\t</li>\n\t<li>\n\tStructure names in Scintilla.h without prefixes are deprecated and will now only\n\tbe usable with INCLUDE_DEPRECATED_FEATURES defined.<br />\n\tUse the newer names with the \"Sci_\" prefix:<br />\n\tCharacterRange &rarr; Sci_CharacterRange<br />\n\tTextRange &rarr; Sci_TextRange<br />\n\tTextToFind &rarr; Sci_TextToFind<br />\n\tRangeToFormat &rarr; Sci_RangeToFormat<br />\n\tNotifyHeader &rarr; Sci_NotifyHeader\n\t</li>\n\t<li>\n\tPreviously deprecated features SC_CP_DBCS, SCI_SETUSEPALETTE. and SCI_GETUSEPALETTE\n\thave been removed and can no longer be used in client code.\n\t</li>\n\t<li>\n\tSingle phase drawing SC_PHASES_ONE is deprecated along with the\n\tSCI_SETTWOPHASEDRAW and SCI_GETTWOPHASEDRAW messages.\n\t</li>\n\t<li>\n\tAccessibility support allowing screen readers to work added on GTK+ and Cocoa.\n\t</li>\n\t<li>\n\tTextual tags may be displayed to the right on folded lines with SCI_TOGGLEFOLDSHOWTEXT.\n\tThis is commonly something like \"{ ... }\" or \"&lt;tr&gt;...&lt;/tr&gt;\".\n\tIt is displayed with the STYLE_FOLDDISPLAYTEXT style and may have a box drawn around it\n\twith SCI_FOLDDISPLAYTEXTSETSTYLE.\n\t</li>\n\t<li>\n\tA mouse right-click over the margin may send an SCN_MARGINRIGHTCLICK event.\n\tThis only occurs when popup menus are turned off.\n\tSCI_USEPOPUP now has three states: SC_POPUP_NEVER, SC_POPUP_ALL, or SC_POPUP_TEXT.\n\t</li>\n\t<li>\n\tINDIC_POINT and INDIC_POINTCHARACTER indicators added to display small arrows\n\tunderneath positions or characters.\n\t</li>\n\t<li>\n\tAdded alternate appearance for visible tabs which looks like a horizontal line.\n\tControlled with SCI_SETTABDRAWMODE.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1165/\">Feature #1165.</a>\n\t</li>\n\t<li>\n\tOn Cocoa, a modulemap file is included to allow Scintilla to be treated as a module.\n\tThis makes it easier to use Scintilla from the Swift language.\n\t</li>\n\t<li>\n\tBaan folder accommodates sections and lexer fixes definition of SCE_BAAN_FUNCDEF.\n\t</li>\n\t<li>\n\tEDIFACT lexer and folder added.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1166/\">Feature #1166.</a>\n\t</li>\n\t<li>\n\tJSON folder fixed where it didn't resume folding with the correct fold level.\n\t</li>\n\t<li>\n\tMatlab folder based on syntax instead of indentation so more accurate.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1692/\">Bug #1692</a>.\n\t</li>\n\t<li>\n\tYAML lexer fixed style of references and keywords when followed by a comment.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1872/\">Bug #1872</a>.\n\t</li>\n\t<li>\n\tMargin click to select line now clears rectangular and additional selections.\n\t</li>\n\t<li>\n\tFixed a NULL access bug on GTK+ where the scrollbars could be used during destruction.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1873/\">Bug #1873</a>.\n\t</li>\n\t<li>\n\tA potential bug on GTK+ fixed where asynchronous clipboard could be delivered after its\n\ttarget Scintilla instance was destroyed.\n\t</li>\n\t<li>\n\tCocoa IME made more compliant with documented behaviour to avoid bugs that caused\n\thuge allocations.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1881/\">Bug #1881</a>.\n\t</li>\n\t<li>\n\tOn Win32 fix EM_SETSEL to match Microsoft documentation..\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1886/\">Bug #1886</a>.\n\t</li>\n\t<li>\n\tSciTE on GTK+ allows localizing tool bar tool tips.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1167/\">Feature #1167.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows restores focus to edit pane after closing user strip.\n\t</li>\n\t<li>\n\tSciTE measures files larger that 2 GB which allows it to refuse to open huge files more consistently\n\tand to show better warning messages.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite370.zip\">Release 3.7.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 16 October 2016.\n\t</li>\n\t<li>\n\tWord selection, navigation, and manipulation is now performed on characters instead of bytes\n\tleading to more natural behaviour for multi-byte encodings like UTF-8.\n\tFor UTF-8 characters 0x80 and above, classification into word; punctuation; space; or line-end\n\tis based on the Unicode general category of the character and is not customizable.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1832/\">Bug #1832</a>.\n\t</li>\n\t<li>\n\tTwo enums changed in Scintilla.iface which may lead to changed bindings.\n\tThere were 2 FontQuality enums and the first is now PhasesDraw.\n\tThe prefix for FoldAction was SC_FOLDACTION and is now SC_FOLDACTION_\n\twhich is similar to other enums.\n\tThese changes do not affect the standard C/C++ binding.\n\t</li>\n\t<li>\n\tEDGE_MULTILINE and SCI_MULTIEDGEADDLINE added to allow displaying multiple\n\tvertical edges simultaneously.\n\t</li>\n\t<li>\n\tThe number of margins can be changed with SCI_SETMARGINS.\n\t</li>\n\t<li>\n\tMargin type SC_MARGIN_COLOUR added so that the application may\n\tchoose any colour for a margin with SCI_SETMARGINBACKN.\n\t</li>\n\t<li>\n\tOn Win32, mouse wheel scrolling can be restricted to only occur when the mouse is\n\twithin the window.\n\t</li>\n\t<li>\n\tThe WordList class in lexlib used by lexers adds an InListAbridged method for\n\tmatching keywords that have particular prefixes and/or suffixes.\n\t</li>\n\t<li>\n\tThe Baan lexer was changed significantly with more lexical states, keyword sets,\n\tand support for abridged keywords.\n\t</li>\n\t<li>\n\tThe CoffeeScript lexer styles interpolated code in strings.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1865/\">Bug #1865</a>.\n\t</li>\n\t<li>\n\tThe Progress lexer \"progress\" has been replaced with a new lexer \"abl\"\n\t(Advanced Business Language)\n\twith a different set of lexical states and more functionality.\n\tThe lexical state prefix has changed from SCE_4GL_ to SCE_ABL_.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1143/\">Feature #1143.</a>\n\t</li>\n\t<li>\n\tThe PowerShell lexer understands the grave accent escape character.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1868/\">Bug #1868</a>.\n\t</li>\n\t<li>\n\tThe YAML lexer recognizes inline comments.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1660/\">Bug #1660</a>.\n\t</li>\n\t<li>\n\tSciTE on Windows can retain coloured selection when inactive with\n\tselection.always.visible property.\n\t</li>\n\t<li>\n\tSciTE on Windows adds a state to close.on.find to close the find strip when\n\ta match is found.\n\t</li>\n\t<li>\n\tFix caret position after left or right movement with rectangular selection.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1861/\">Bug #1861</a>.\n\t</li>\n\t<li>\n\tIn SciTE, optional prefix argument added to scite.ConstantName method.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1860/\">Bug #1860</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, include ILexer.h in the public headers of the framework.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1855/\">Bug #1855</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, allow subclass of SCIContentView to set cursor.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1863/\">Bug #1863</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, recognize the numeric keypad '+', '-', and '/' keys as\n\tSCK_ADD, SCK_SUBTRACT, and SCK_DIVIDE.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1867/\">Bug #1867</a>.\n\t</li>\n\t<li>\n\tOn GTK+ 3.21+ fix incorrect font size in auto-completion list.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1859/\">Bug #1859</a>.\n\t</li>\n\t<li>\n\tFix SciTE crash when command.mode ends with comma.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1857/\">Bug #1857</a>.\n\t</li>\n\t<li>\n\tSciTE on Windows has a full size toolbar icon for \"Close\".\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite367.zip\">Release 3.6.7</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 4 September 2016.\n\t</li>\n\t<li>\n\tC++11 range-based for loops used in SciTE so GCC 4.6 is now the minimum supported version.\n\t</li>\n\t<li>\n\tSC_CHARSET_DEFAULT now means code page 1252 on Windows unless a code page is set.\n\tThis prevents unexpected behaviour and crashes on East Asian systems where default locales are commonly DBCS.\n\tProjects which want to default to DBCS code pages in East Asian locales should set the code page and\n\tcharacter set explicitly.\n\t</li>\n\t<li>\n\tSCVS_NOWRAPLINESTART option stops left arrow from wrapping to the previous line.\n\tMost commonly wanted when virtual space is used.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1648/\">Bug #1648</a>.\n\t</li>\n\t<li>\n\tThe C++ lexer can fold on #else and #elif with the fold.cpp.preprocessor.at.else property.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/210/\">Bug #210</a>.\n\t</li>\n\t<li>\n\tThe errorlist lexer detects warnings from Visual C++ which do not contain line numbers.\n\t</li>\n\t<li>\n\tThe HTML lexer no longer treats \"&lt;?\" inside a string in a script as potentially starting an XML document.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/767/\">Bug #767</a>.\n\t</li>\n\t<li>\n\tThe HTML lexer fixes a problem resuming at a script start where the starting state continued\n\tpast where it should.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1849/\">Bug #1849</a>.\n\t</li>\n\t<li>\n\tWhen inserting spaces for virtual space and the position is in indentation and tabs are enabled\n\tfor indentation then use tabs.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1850/\">Bug #1850</a>.\n\t</li>\n\t<li>\n\tFix fold expand when some child text not styled.\n\tCaused by fixes for Bug #1799.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1842/\">Bug #1842</a>.\n\t</li>\n\t<li>\n\tFix key binding bug on Cocoa for control+.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1854/\">Bug #1854</a>.\n\t</li>\n\t<li>\n\tFix scroll bar size warnings on GTK+ caused by #1831.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1851/\">Bug #1851</a>.\n\t</li>\n\t<li>\n\tSmall fixes for GTK+ makefile.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1844/\">Bug #1844</a>.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1845/\">Bug #1845</a>.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1846/\">Bug #1846</a>.\n\t</li>\n\t<li>\n\tFix SciTE indentation after code like \"void function () {}\".\n\t</li>\n\t<li>\n\tFix SciTE global regex replace of \"^\" with something which missed the line after empty\n\tlines with LF line ends.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1839/\">Bug #1839</a>.\n\t</li>\n\t<li>\n\tFix SciTE on GTK+ 3.20 bug where toggle buttons on find and replace strips\n\tdid not show active state.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1853/\">Bug #1853</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite366.zip\">Release 3.6.6</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 24 May 2016.\n\t</li>\n\t<li>\n\tC++ 11 &lt;regex&gt; support built by default. Can be disabled by defining NO_CXX11_REGEX.\n\t</li>\n\t<li>\n\tSciTE_USERHOME environment variable allows separate location for writeable properties files.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/965/\">Feature #965.</a>\n\t</li>\n\t<li>\n\tGObject introspection supports notify and command events.\n\t</li>\n\t<li>\n\tThe Progress lexer now allows comments preceded by a tab.\n\t</li>\n\t<li>\n\tScripts reading Scintilla.iface file include comments for enu and lex definitions.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1829/\">Bug #1829</a>.\n\t</li>\n\t<li>\n\tFix crashes on GTK+ if idle work active when destroyed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1827/\">Bug #1827</a>.\n\t</li>\n\t<li>\n\tFixed bugs when used on GTK+ 3.20.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1825/\">Bug #1825</a>.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1831/\">Bug #1831</a>.\n\t</li>\n\t<li>\n\tFix SciTE search field background with dark theme on GTK+ 2.x.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1826/\">Bug #1826</a>.\n\t</li>\n\t<li>\n\tFixed bug on Win32 that allowed resizing autocompletion from bottom when it was\n\tlocated above the caret.\n\t</li>\n\t<li>\n\tOn Win32, when using a screen reader and selecting text using Shift+Arrow,\n\tfix bug when scrolling made the caret stay at the same screen location\n\tso the screen reader did not speak the added or removed selection.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite365.zip\">Release 3.6.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 26 April 2016.\n\t</li>\n\t<li>\n\tJSON lexer added.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1140/\">Feature #1140.</a>\n\t</li>\n\t<li>\n\tThe C++ lexer fixes a bug with multi-line strings with line continuation where the string style\n\toverflowed after an edit.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1824/\">Bug #1824</a>.\n\t</li>\n\t<li>\n\tThe Python lexer treats '@' as an operator except when it is the first visible character on a line.\n\tThis is for Python 3.5.\n\t</li>\n\t<li>\n\tThe Rust lexer allows '?' as an operator.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1146/\">Feature #1146.</a>\n\t</li>\n\t<li>\n\tDoubled size of compiled regex buffer.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1822/\">Bug #1822</a>.\n\t</li>\n\t<li>\n\tFor GTK+, the Super modifier key can be used in key bindings.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1142/\">Feature #1142.</a>\n\t</li>\n\t<li>\n\tFor GTK+, fix some crashes when using multiple threads.\n\t</li>\n\t<li>\n\tPlatform layer font cache removed on GTK+ as platform-independent caches are used.\n\tThis avoids the use of thread locking and initialization of threads so any GTK+\n\tapplications that rely on Scintilla initializing threads will have to do that themselves.\n\t</li>\n\t<li>\n\tSciTE bug fixed with exported HTML where extra line shown.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1816/\">Bug #1816</a>.\n\t</li>\n\t<li>\n\tSciTE on Windows fixes bugs with pop-up menus in the find and replace strips.\n\tFor the replace strip, menu choices change the state.\n\tFor the find strip, menu choices are reflected in the appearance of their corresponding buttons.\n\t</li>\n\t<li>\n\tSciTE on Windows on high DPI displays fixes the height of edit boxes in user strips.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite364.zip\">Release 3.6.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 13 March 2016.\n\t</li>\n\t<li>\n\tSciTE allows setting the autocompletion type separator character.\n\t</li>\n\t<li>\n\tThe C++ folder folds code on '(' and ')' to allow multi-line calls to be folded.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1138/\">Feature #1138.</a>\n\t</li>\n\t<li>\n\tFor the HTML lexer, limit the extent of Mako line comments to finish before\n\tthe line end characters.\n\t</li>\n\t<li>\n\tFolds unfolded when two fold regions are merged by either deleting an intervening line\n\tor changing its fold level by adding characters.\n\tThis was fixed both in Scintilla and in SciTE's equivalent code.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1799/\">Bug #1799</a>.<br />\n\t</li>\n\t<li>\n\tThe Progress lexer supports hexadecimal numeric literals,\n\tsingle-line comments, abbreviated keywords and\n\textends nested comments to unlimited levels.\n\t</li>\n\t<li>\n\tRuby lexer treats alternate hash key syntax \"key:\" as a symbol.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1810/\">Bug #1810</a>.\n\t</li>\n\t<li>\n\tRust lexer handles bracketed Unicode string escapes like \"\\u{123abc}\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1809/\">Bug #1809</a>.\n\t</li>\n\t<li>\n\tFor GTK+ on Windows fix 64-bit build which was broken in 3.6.3.\n\t</li>\n\t<li>\n\tFor Qt, release builds have assertions turned off.\n\t</li>\n\t<li>\n\tFor Qt on Windows, fix compilation failure for Qt 4.x.\n\t</li>\n\t<li>\n\tIME target range displayed on Qt for OS X.\n\t</li>\n\t<li>\n\tOn Windows, make clipboard operations more robust by retrying OpenClipboard if it fails\n\tas this may occur when another application has opened the clipboard.\n\t</li>\n\t<li>\n\tOn Windows back out change that removed use of def file to ensure\n\tScintilla_DirectFunction exported without name mangling.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1813/\">Bug #1813</a>.\n\t</li>\n\t<li>\n\tOn GTK+ and Qt over Win32 in Korean fix bug caused by last release's word input change.\n\t</li>\n\t<li>\n\tFor SciTE, more descriptive error messages are displayed when there are problems loading the\n\tLua startup script.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1139/\">Feature #1139.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite363.zip\">Release 3.6.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 18 January 2016.\n\t</li>\n\t<li>\n\tAllow painting without first styling all visible text then styling in the background\n\tusing idle-time. This helps performance when scrolling down in very large documents.\n\tCan also incrementally style after the visible area to the end of the document so that\n\tthe document is already styled when the user scrolls to it.\n\t</li>\n\t<li>\n\tSupport GObject introspection on GTK+.\n\t</li>\n\t<li>\n\tSciTE supports pasting to each selection with the selection.multipaste setting.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1123/\">Feature #1123.</a>\n\t</li>\n\t<li>\n\tSciTE can optionally display a read-only indicator on tabs and in the Buffers menu.\n\t</li>\n\t<li>\n\tBash lexer flags incomplete here doc delimiters as syntax errors.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1789/\">Bug #1789</a>.<br />\n\tSupport added for using '#' in non-comment ways as is possible with zsh.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1794/\">Bug #1794</a>.<br />\n\tRecognize more characters as here-doc delimiters.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1778/\">Bug #1778</a>.\n\t</li>\n\t<li>\n\tErrorlist lexer highlights warning messages from the Microsoft linker.\n\t</li>\n\t<li>\n\tErrorlist lexer fixes bug with final line in escape sequence recognition mode.\n\t</li>\n\t<li>\n\tLua lexer includes '&amp;' and '|' bitwise operators for Lua 5.3.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1790/\">Bug #1790</a>.\n\t</li>\n\t<li>\n\tPerl lexer updated for Perl 5.20 and 5.22.<br />\n\tAllow '_' for subroutine prototypes.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1791/\">Bug #1791</a>.<br />\n\tDouble-diamond operator &lt;&lt;&gt;&gt;.<br />\n\tHexadecimal floating point literals.<br />\n\tRepetition in list assignment.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1793/\">Bug #1793</a>.<br />\n\tHighlight changed subroutine prototype syntax for Perl 5.20.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1797/\">Bug #1797</a>.<br />\n\tFix module ::-syntax when special characters such as 'x' are used.<br />\n\tAdded ' and \" detection as prefix chars for x repetition operator.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1800/\">Bug #1800</a>.\n\t</li>\n\t<li>\n\tVisual Prolog lexer recognizes numbers more accurately and allows non-ASCII verbatim\n\tquoting characters.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1130/\">Feature #1130.</a>\n\t</li>\n\t<li>\n\tSend SCN_UPDATEUI with SC_UPDATE_SELECTION when the application changes multiple\n\tselection.\n\t</li>\n\t<li>\n\tExpand folded areas before deleting fold header line.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1796/\">Bug #1796</a>.\n\t</li>\n\t<li>\n\tTreat Unicode line ends like common line ends when maintaining fold state.\n\t</li>\n\t<li>\n\tHighlight whole run for hover indicator when wrapped.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1784/\">Bug #1784</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, fix crash when autocompletion list closed during scroll bounce-back.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1788/\">Bug #1788</a>.\n\t</li>\n\t<li>\n\tOn Windows, fix non-BMP input through WM_CHAR and allow WM_UNICHAR to work\n\twith non-BMP characters and on non-Unicode documents.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1779/\">Bug #1779</a>.\n\t</li>\n\t<li>\n\tOn Windows using DirectWrite, for ligatures and other character clusters,\n\tdisplay caret and selections part-way through clusters so that the caret doesn't stick\n\tto the end of the cluster making it easier to understand editing actions.\n\t</li>\n\t<li>\n\tOn Windows, Scintilla no longer uses a .DEF file during linking as it duplicates\n\tsource code directives.\n\t</li>\n\t<li>\n\tOn GTK+ and Qt, Korean input by word fixed.\n\t</li>\n\t<li>\n\tOn GTK+, Qt, and Win32 block IME input when document is read-only or any selected text\n\tis protected.\n\t</li>\n\t<li>\n\tOn GTK+ on OS X, fix warning during destruction.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1777/\">Bug #1777</a>.\n\t</li>\n\t<li>\n\tFix SciTE crashes when using LPEG lexers.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite362.zip\">Release 3.6.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 6 November 2015.\n\t</li>\n\t<li>\n\tWhitespace may be made visible just in indentation.\n\t</li>\n\t<li>\n\tWhitespace dots are centred when larger than 1 pixel.\n\t</li>\n\t<li>\n\tThe Scintilla framework on Cocoa now contains version numbers.\n\t</li>\n\t<li>\n\tSciTE's standard properties collect values from all active .properties file to produce the Language menu\n\tand the file types pull-down in the File open dialog.\n\t</li>\n\t<li>\n\tThe single executable version of SciTE, Sc1, uses 'module' statements within its embedded\n\tproperties. This makes it act more like the full distribution allowing languages to be turned on\n\tand off by setting imports.include and imports.exclude.\n\tThe default imports.exclude property adds eiffel, erlang, ps, and pov so these languages are\n\tturned off by default.\n\t</li>\n\t<li>\n\tSciTE adds an output.blank.margin.left property to allow setting the output pane\n\tmargin to a different width than the edit pane.\n\t</li>\n\t<li>\n\tCoffeeScript lexer highlights ranges correctly.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1765/\">Bug #1765</a>.\n\t</li>\n\t<li>\n\tMarkdown lexer treats line starts consistently to always highlight *foo* or similar at line start.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1766/\">Bug #1766</a>.\n\t</li>\n\t<li>\n\tOptimize marker redrawing by only drawing affected lines when markers shown in the text.\n\t</li>\n\t<li>\n\tOn Cocoa, timers and idling now work in modal dialogs. This also stops some crashes.\n\t</li>\n\t<li>\n\tOn Cocoa, fix crashes when deleting a ScintillaView. These crashes could occur when scrolling\n\tat the time the ScintillaView was deleted although there may have been other cases.\n\t</li>\n\t<li>\n\tOn GTK+ 2.x, fix height of lines in autocompletion lists.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1774/\">Bug #1774</a>.\n\t</li>\n\t<li>\n\tFix bug with SCI_LINEENDDISPLAY where the caret moved to the next document line instead of the\n\tend of the display line.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1772/\">Bug #1772</a>.\n\t</li>\n\t<li>\n\tReport error (SC_STATUS_FAILURE) when negative length passed to SCI_SETSTYLING.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1768/\">Bug #1768</a>.\n\t</li>\n\t<li>\n\tWhen SC_MARK_UNDERLINE is not assigned to a margin, stop drawing the whole line.\n\t</li>\n\t<li>\n\tWhen reverting an untitled document in SciTE, just clear it with no message about a file.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1764/\">Bug #1764</a>.\n\t</li>\n\t<li>\n\tSciTE on GTK+ allows use of Ctrl+A (Select All) inside find and replace strips.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1769/\">Bug #1769</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite361.zip\">Release 3.6.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 15 September 2015.\n\t</li>\n\t<li>\n\tThe oldest version of GTK+ supported now is 2.18 and for glib it is 2.22.\n\t</li>\n\t<li>\n\tOn GTK+, SC_CHARSET_OEM866 added to allow editing Russian files encoded in code page 866.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1019/\">Feature #1019.</a>\n\t</li>\n\t<li>\n\tOn Windows, reconversion is performed when requested by the IME.\n\t</li>\n\t<li>\n\tCoffeeScript lexer adds lexical class for instance properties and fixes some cases of regex highlighting.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1749/\">Bug #1749</a>.\n\t</li>\n\t<li>\n\tThe errorlist lexer understands some ANSI escape sequences to change foreground colour and intensity.\n\tThis is sufficient to colour diagnostic output from gcc and clang when -fdiagnostics-color set.\n\t</li>\n\t<li>\n\tThe errorlist lexer allows the line number to be 0 in GCC errors as some tools report whole file\n\terrors as line 0.\n\t</li>\n\t<li>\n\tMySql lexer fixes empty comments /**/ so the comment state does not continue.\n\t</li>\n\t<li>\n\tVHDL folder supports \"protected\" keyword.\n\t</li>\n\t<li>\n\tTreat CRLF line end as two characters in SCI_COUNTCHARACTERS.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1757/\">Bug #1757</a>.\n\t</li>\n\t<li>\n\tOn GTK+ 3.x, fix height of lines in autocompletion lists to match the font.\n\tSwitch from deprecated style calls to CSS styling.\n\tRemoved setting list colours on GTK+ 3.16+ as no longer appears needed.\n\t</li>\n\t<li>\n\tOn GTK+, avoid \"Invalid rectangle passed\" warning messages by never reporting the client\n\trectangle with a negative width or height.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1743/\">Bug #1743</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, copy Sci_Position.h into the framework so clients can build.\n\t</li>\n\t<li>\n\tOn Cocoa fix bug with drag and drop that could lead to crashes.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1751/\">Bug #1751</a>.\n\t</li>\n\t<li>\n\tFix SciTE disk exhaustion bug by reporting failures when writing files.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1760/\">Bug #1760</a>.\n\t</li>\n\t<li>\n\tFix find strip in SciTE on Windows XP to be visible.\n\t</li>\n\t<li>\n\tSciTE on Windows changes the way it detects that a tool has finished executing to ensure all output data\n\tfrom the process is read.\n\t</li>\n\t<li>\n\tSciTE on Windows improves the time taken to read output from tools that produce a large amount\n\tof output by a factor of around 10.\n\t</li>\n\t<li>\n\tOn GTK+ the keyboard command for View | End of Line was changed to Ctrl+Shift+N\n\tto avoid clash with Search | Selection Add Next.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1750/\">Bug #1750</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite360.zip?download\">Release 3.6.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 3 August 2015.\n\t</li>\n\t<li>\n\tExternal interfaces use the Sci_Position and Sci_PositionU typedefs instead of int and unsigned int\n\tto allow for changes to a 64-bit interface on 64-bit platforms in the future.\n\tApplications and external lexers should start using the new type names so that\n\tthey will be compatible when the 64-bit change occurs.\n\tThere is also Sci_PositionCR (long) for use in the Sci_CharacterRange struct which will\n\talso eventually become 64-bit.\n\t</li>\n\t<li>\n\tMultiple selection now works over more key commands.\n\tThe new multiple-selection handling commands include horizontal movement and selection commands,\n\tline up and down movement and selection commands, word and line deletion commands, and\n\tline end insertion.\n\tThis change in behaviours is conditional on setting the SCI_SETADDITIONALSELECTIONTYPING property.\n\t</li>\n\t<li>\n\tAutocompletion lists send an SCN_AUTOCCOMPLETED notification after the text has been inserted.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1109/\">Feature #1109.</a>\n\t</li>\n\t<li>\n\tThe case mode style attribute can now be SC_CASE_CAMEL.\n\t</li>\n\t<li>\n\tThe Python lexer supports substyles for identifiers.\n\t</li>\n\t<li>\n\tSciTE adds support for substyles.\n\t</li>\n\t<li>\n\tSciTE's Export as RTF and Copy as RTF commands support UTF-8.\n\t</li>\n\t<li>\n\tSciTE can display autocompletion on all IME input with ime.autocomplete property.\n\t</li>\n\t<li>\n\tSciTE properties files now discard trailing white space on variable names.\n\t</li>\n\t<li>\n\tCalling SCI_SETIDENTIFIERS resets styling to ensure any added identifier are highlighted.\n\t</li>\n\t<li>\n\tAvoid candidate box randomly popping up away from edit pane with (especially\n\tJapanese) IME input.\n\t</li>\n\t<li>\n\tOn Cocoa fix problems with positioning of autocompletion lists near screen edge\n\tor under dock. Cancel autocompletion when window moved.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1740/\">Bug #1740</a>.\n\t</li>\n\t<li>\n\tFix drawing problem when control characters are in a hidden style as they then\n\thave a zero width rectangle to draw but modify that rectangle in a way that\n\tclears some pixels.\n\t</li>\n\t<li>\n\tReport error when attempt to resize buffer to more than 2GB with SC_STATUS_FAILURE.\n\t</li>\n\t<li>\n\tFix bug on GTK+ with scroll bars leaking.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1742/\">Bug #1742</a>.\n\t</li>\n\t<li>\n\tLexOthers.cxx file split into one file per lexer: LexBatch, LexDiff,\n\tLexErrorList, LexMake, LexNull, and LexProps.\n\t</li>\n\t<li>\n\tSciTE exporters handle styles &gt; 127 correctly now.\n\t</li>\n\t<li>\n\tSciTE on Windows can scale window element sizes based on the system DPI setting.\n\t</li>\n\t<li>\n\tSciTE implements find.in.files.close.on.find on all platforms, not just Windows.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite357.zip?download\">Release 3.5.7</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 20 June 2015.\n\t</li>\n\t<li>\n\tAdded SCI_MULTIPLESELECTADDNEXT to add the next occurrence of the main selection within the\n\ttarget to the set of selections as main. If the current selection is empty then select word around caret.\n\tSCI_MULTIPLESELECTADDEACH adds each occurrence of the main selection within the\n\ttarget to the set of selections.\n\t</li>\n\t<li>\n\tSciTE adds \"Selection Add Next\" and \"Selection Add Each\" commands to the Search menu.\n\t</li>\n\t<li>\n\tAdded SCI_ISRANGEWORD to determine if the parameters are at the start and end of a word.\n\t</li>\n\t<li>\n\tAdded SCI_TARGETWHOLEDOCUMENT to set the target to the whole document.\n\t</li>\n\t<li>\n\tVerilog lexer recognizes protected regions and the folder folds protected regions.\n\t</li>\n\t<li>\n\tA performance problem with markers when deleting many lines was fixed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1733/\">Bug #1733</a>.\n\t</li>\n\t<li>\n\tOn Cocoa fix crash when ScintillaView destroyed if no autocompletion ever displayed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1728/\">Bug #1728</a>.\n\t</li>\n\t<li>\n\tOn Cocoa fix crash in drag and drop.\n\t</li>\n\t<li>\n\tOn GTK+ 3.4+, when there are both horizontal and vertical scrollbars, draw the lower-right corner\n\tso that it does not appear black when text selected.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1611/\">Bug #1611</a>.\n\t</li>\n\t<li>\n\tFixed most calls deprecated in GTK+ 3.16. Does not fix style override calls\n\tas they are more complex.\n\t</li>\n\t<li>\n\tSciTE on GTK+ 3.x uses a different technique for highlighting the search strip when there is\n\tno match which is more compatible with future and past versions and different themes.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite356.zip?download\">Release 3.5.6</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 26 May 2015.\n\t</li>\n\t<li>\n\tOn Qt, use fractional positioning calls and avoid rounding to ensure consistency.\n\t</li>\n\t<li>\n\tSCI_TARGETASUTF8 and SCI_ENCODEDFROMUTF8 implemented on\n\tWin32 as well as GTK+ and Cocoa.\n\t</li>\n\t<li>\n\tC++ lexer fixes empty backquoted string.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1711/\">Bug #1711</a>.\n\t</li>\n\t<li>\n\tC++ lexer fixes #undef directive.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1719/\">Bug #1719</a>.\n\t</li>\n\t<li>\n\tFortran folder fixes handling of \"selecttype\" and \"selectcase\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1724/\">Bug #1724</a>.\n\t</li>\n\t<li>\n\tVerilog folder folds interface definitions.\n\t</li>\n\t<li>\n\tVHDL folder folds units declarations and fixes a case insensitivity bug with not treating \"IS\" the same as \"is\".\n\t</li>\n\t<li>\n\tFix bug when drawing text margins in buffered mode which would use default\n\tencoding instead of chosen encoding.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1703/\">Bug #1703</a>.\n\t</li>\n\t<li>\n\tFix bug with Korean Hanja conversions in DBCS encoding on Windows.\n\t</li>\n\t<li>\n\tFix for reading a UTF-16 file in SciTE where a non-BMP character is split over a read buffer boundary.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1710/\">Bug #1710</a>.\n\t</li>\n\t<li>\n\tFix bug on GTK+ 2.x for Windows where there was an ABI difference between\n\tcompiler version.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1726/\">Bug #1726</a>.\n\t</li>\n\t<li>\n\tFix undo bug on Cocoa that could lose data..\n\t</li>\n\t<li>\n\tFix link error on Windows when SCI_NAMESPACE used.\n\t</li>\n\t<li>\n\tFix exporting from SciTE when using Scintillua for lexing.\n\t</li>\n\t<li>\n\tSciTE does not report twice that a search string can not be found when \"Replace\" pressed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1716/\">Bug #1716</a>.\n\t</li>\n\t<li>\n\tSciTE on GTK+ 3.x disables arrow in search combo when no entries.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1717/\">Bug #1717</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite355.zip?download\">Release 3.5.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 17 April 2015.\n\t</li>\n\t<li>\n\tScintilla on Windows is now always a wide character window so SCI_SETKEYSUNICODE has no effect\n\tand SCI_GETKEYSUNICODE always returns true. These APIs are deprecated and should not be called.\n\t</li>\n\t<li>\n\tThe wxWidgets-specific ascent member of Font has been removed which breaks\n\tcompatibility with current wxStyledTextCtrl.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1682/\">Bug #1682</a>.\n\t</li>\n\t<li>\n\tIME on Qt supports multiple carets and behaves more like other platforms.\n\t</li>\n\t<li>\n\tAlways use inline IME on GTK+ for Korean.\n\t</li>\n\t<li>\n\tSQL lexer fixes handling of '+' and '-' in numbers so the '-' in '1-1' is seen as an operator and for\n\t'1--comment' the comment is recognized.\n\t</li>\n\t<li>\n\tTCL lexer reverts change to string handling.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1642/\">Bug #1642</a>.\n\t</li>\n\t<li>\n\tVerilog lexer fixes bugs with macro styling.\n\tVerilog folder fixes bugs with `end completing an `if* instead of `endif and fold.at.else, and implements\n\tfolding at preprocessor `else.\n\t</li>\n\t<li>\n\tVHDL lexer supports extended identifiers.\n\t</li>\n\t<li>\n\tFix bug on Cocoa where the calltip would display incorrectly when\n\tswitching calltips and the new calltip required a taller window.\n\t</li>\n\t<li>\n\tFix leak on Cocoa with autocompletion lists.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1706/\">Bug #1706</a>.\n\t</li>\n\t<li>\n\tFix potential crash on Cocoa with drag and drop.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1709/\">Bug #1709</a>.\n\t</li>\n\t<li>\n\tFix bug on Windows when compiling with MinGW-w64 which caused text to not be drawn\n\twhen in wrap mode.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1705/\">Bug #1705</a>.\n\t</li>\n\t<li>\n\tFix SciTE bug with missing file open filters and add hex to excluded set of properties files so that its\n\tsettings don't appear.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1707/\">Bug #1707</a>.\n\t</li>\n\t<li>\n\tFix SciTE bug where files without extensions like \"makefile\" were not highlighted correctly.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite354.zip?download\">Release 3.5.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 8 March 2015.\n\t</li>\n\t<li>\n\tIndicators may have a different colour and style when the mouse is over them or the caret is moved into them.\n\t</li>\n\t<li>\n\tAn indicator may display in a large variety of colours with the SC_INDICFLAG_VALUEFORE\n\tflag taking the colour from the indicator's value, which may differ for every character, instead of its\n\tforeground colour attribute.\n\t</li>\n\t<li>\n\tOn Cocoa, additional IME methods implemented so that more commands are enabled.\n\tFor Japanese: Reverse Conversion, Convert to Related Character, and Search Similar Kanji\n\tcan now be performed.\n\tThe global definition hotkey Command+Control+D and the equivalent three finger tap gesture\n\tcan be used.\n\t</li>\n\t<li>\n\tMinimum version of Qt supported is now 4.8 due to the use of QElapsedTimer::nsecsElapsed.\n\t</li>\n\t<li>\n\tOn Windows, for Korean, the VK_HANJA key is implemented to choose Hanja for Hangul and\n\tto convert from Hanja to Hangul.\n\t</li>\n\t<li>\n\tC++ lexer adds lexer.cpp.verbatim.strings.allow.escapes option that allows verbatim (@\") strings\n\tto contain escape sequences. This should remain off (0) for C# and be turned on (1) for Objective C.\n\t</li>\n\t<li>\n\tRust lexer accepts new 'is'/'us' integer suffixes instead of 'i'/'u'.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1098/\">Bug #1098</a>.\n\t</li>\n\t<li>\n\tRuby folder can fold multiline comments.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1697/\">Bug #1697</a>.\n\t</li>\n\t<li>\n\tSQL lexer fixes a bug with the q-quote operator.\n\t</li>\n\t<li>\n\tTCL lexer fixes a bug with some strings.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1642/\">Bug #1642</a>.\n\t</li>\n\t<li>\n\tVerilog lexer handles escaped identifiers that begin with \\ and end with space like \\reset* .\n\tVerilog folder fixes one bug with inconsistent folding when fold.comment is on and another\n\twith typedef class statements creating a fold point, expecting an endclass statement.\n\t</li>\n\t<li>\n\tVHDL folder fixes hang in folding when document starts with \"entity\".\n\t</li>\n\t<li>\n\tAdd new indicators INDIC_COMPOSITIONTHIN, INDIC_FULLBOX, and INDIC_TEXTFORE.\n\tINDIC_COMPOSITIONTHIN is a thin underline that mimics the appearance of non-target segments in OS X IME.\n\tINDIC_FULLBOX is similar to INDIC_STRAIGHTBOX but covers the entire character area which means that\n\tindicators with this style on contiguous lines may touch. INDIC_TEXTFORE changes the text foreground colour.\n\t</li>\n\t<li>\n\tFix adaptive scrolling speed for GTK+ on OS X with GTK Quartz backend (as opposed to X11 backend).\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1696/\">Bug #1696</a>.\n\t</li>\n\t<li>\n\tFix position of autocompletion and calltips on Cocoa when there were two screens stacked vertically.\n\t</li>\n\t<li>\n\tFix crash in SciTE when saving large files in background when closing application.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1691/\">Bug #1691</a>.\n\t</li>\n\t<li>\n\tFix decoding of MSVC warnings in SciTE so that files in the C:\\Program Files (x86)\\ directory can be opened.\n\tThis is a common location of system include files.\n\t</li>\n\t<li>\n\tFix compilation failure of C++11 &lt;regex&gt; on Windows using gcc.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite353.zip?download\">Release 3.5.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 20 January 2015.\n\t</li>\n\t<li>\n\tSupport removed for Windows 95, 98, and ME.\n\t</li>\n\t<li>\n\tLexers added for Motorola S-Record files, Intel hex files, and Tektronix extended hex files with folding for Intel hex files.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1091/\">Feature #1091.</a>\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1093/\">Feature #1093.</a>\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1095/\">Feature #1095.</a>\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1096/\">Feature #1096.</a>\n\t</li>\n\t<li>\n\tC++ folder allows folding on square brackets '['.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1087/\">Feature #1087.</a>\n\t</li>\n\t<li>\n\tShell lexer fixes three issues with here-documents.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1672/\">Bug #1672</a>.\n\t</li>\n\t<li>\n\tVerilog lexer highlights doc comment keywords; has separate styles for input, output, and inout ports\n\t(lexer.verilog.portstyling); fixes a bug in highlighting numbers; can treat upper-case identifiers as\n\tkeywords (lexer.verilog.allupperkeywords); and can use different styles for code that is inactive due\n\tto preprocessor commands (lexer.verilog.track.preprocessor, lexer.verilog.update.preprocessor).\n\t</li>\n\t<li>\n\tWhen the calltip window is taller than the Scintilla window, leave it in a\n\tposition that avoids overlapping the Scintilla text.\n\t</li>\n\t<li>\n\tWhen a text margin is displayed, for annotation lines, use the background colour of the base line.\n\t</li>\n\t<li>\n\tOn Windows GDI, assume font names are encoded in UTF-8. This matches the Direct2D code path.\n\t</li>\n\t<li>\n\tFix paste for GTK+ on OS X.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1677/\">Bug #1677</a>.\n\t</li>\n\t<li>\n\tReverted a fix on Qt where Qt 5.3 has returned to the behaviour of 4.x.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1575/\">Bug #1575</a>.\n\t</li>\n\t<li>\n\tWhen the mouse is on the line between margin and text changed to treat as within text.\n\tThis makes the PLAT_CURSES character cell platform work better.\n\t</li>\n\t<li>\n\tFix a crash in SciTE when the command line is just \"-close:\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1675/\">Bug #1675</a>.\n\t</li>\n\t<li>\n\tFix unexpected dialog in SciTE on Windows when the command line has a quoted filename then ends with a space.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1673/\">Bug #1673</a>.\n\t</li>\n\t<li>\n\tOn Windows and GTK+, use indicators for inline IME.\n\t</li>\n\t<li>\n\tSciTE shuts down quicker when there is no user-written OnClose function and no directors are attached.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite352.zip?download\">Release 3.5.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 2 December 2014.\n\t</li>\n\t<li>\n\tFor OS X Cocoa switch C++ runtime to libc++ to enable use of features that will never\n\tbe added to libstdc++ including those part of C++11.\n\tScintilla will now run only on OS X 10.7 or later and only in 64-bit mode.\n\t</li>\n\t<li>\n\tInclude support for using C++11 &lt;regex&gt; for regular expression searches.\n\tEnabling this requires rebuilding Scintilla with a non-default option.\n\tThis is a provisional feature and may change API before being made permanent.\n\t</li>\n\t<li>\n\tAllocate indicators used for Input Method Editors after 31 which was the previous limit of indicators to\n\tensure no clash between the use of indicators for IME and for the application.\n\t</li>\n\t<li>\n\tANNOTATION_INDENTED added which is similar to ANNOTATION_BOXED in terms of positioning\n\tbut does not show a border.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1086/\">Feature #1086.</a>\n\t</li>\n\t<li>\n\tAllow platform overrides for drawing tab arrows, wrap markers, and line markers.\n\tSize of double click detection area is a variable.\n\tThese enable better visuals and behaviour for PLAT_CURSES as it is character cell based.\n\t</li>\n\t<li>\n\tCoffeeScript lexer fixes \"/*\" to not be a comment.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1420/\">Bug #1420</a>.\n\t</li>\n\t<li>\n\tVHDL folder fixes \"block\" keyword.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1664/\">Bug #1664</a>.\n\t</li>\n\t<li>\n\tPrevent caret blinking when holding down Delete key.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1657/\">Bug #1657</a>.\n\t</li>\n\t<li>\n\tOn Windows, allow right click selection in popup menu.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1080/\">Feature #1080.</a>\n\t</li>\n\t<li>\n\tOn Windows, only call ShowCaret in GDI mode as it interferes with caret drawing when using Direct2D.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1643/\">Bug #1643</a>.\n\t</li>\n\t<li>\n\tOn Windows, another DirectWrite mode SC_TECHNOLOGY_DIRECTWRITEDC added\n\twhich may avoid drawing failures in some circumstances by drawing into a GDI DC.\n\tThis feature is provisional and may be changed or removed if a better solution is found.\n\t</li>\n\t<li>\n\tOn Windows, avoid processing mouse move events where the mouse has not moved as these can\n\tcause unexpected dwell start notifications.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1670/\">Bug #1670</a>.\n\t</li>\n\t<li>\n\tFor GTK+ on Windows, avoid extra space when pasting from external application.\n\t</li>\n\t<li>\n\tOn GTK+ 2.x allow Scintilla to be used inside tool tips by changing when preedit window created.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1662/\">Bug #1662</a>.\n\t</li>\n\t<li>\n\tSupport MinGW compilation under Linux.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1077/\">Feature #1077.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite351.zip?download\">Release 3.5.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 30 September 2014.\n\t</li>\n\t<li>\n\tBibTeX lexer added.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1071/\">Feature #1071.</a>\n\t</li>\n\t<li>\n\tSQL lexer supports the q-quote operator as SCE_SQL_QOPERATOR(24).\n\t</li>\n\t<li>\n\tVHDL lexer supports block comments.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1527/\">Bug #1527</a>.\n\t</li>\n\t<li>\n\tVHDL folder fixes case where \"component\" used before name.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/613/\">Bug #613</a>.\n\t</li>\n\t<li>\n\tRestore fractional pixel tab positioning which was truncated to whole pixels in 3.5.0.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1652/\">Bug #1652</a>.\n\t</li>\n\t<li>\n\tAllow choice between windowed and inline IME on some platforms.\n\t</li>\n\t<li>\n\tOn GTK+ cache autocomplete window to avoid platform bug where windows\n\twere sometimes lost.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1649/\">Bug #1649</a>.\n\t</li>\n\t<li>\n\tOn GTK+ size autocomplete window more accurately.\n\t</li>\n\t<li>\n\tOn Windows only unregister windows classes registered.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1639/\">Bug #1639</a>.\n\t</li>\n\t<li>\n\tOn Windows another DirectWrite mode SC_TECHNOLOGY_DIRECTWRITERETAIN added\n\twhich may avoid drawing failures on some cards and drivers.\n\tThis feature is provisional and may be changed or removed if a better solution is found.\n\t</li>\n\t<li>\n\tOn Windows support the Visual Studio 2010+ clipboard format that indicates a line copy.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1636/\">Bug #1636</a>.\n\t</li>\n\t<li>\n\tSciTE session files remember the scroll position.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite350.zip?download\">Release 3.5.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 13 August 2014.\n\t</li>\n\t<li>\n\tText may share space vertically so that extreme ascenders and descenders are\n\tnot cut off by calling SCI_SETPHASESDRAW(SC_PHASES_MULTIPLE).\n\t</li>\n\t<li>\n\tSeparate timers are used for each type of periodic activity and they are turned on and off\n\tas required. This saves power as there are fewer wake ups.\n\tOn recent releases of OS X Cocoa and Windows, coalescing timers are used to further\n\tsave power.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1086/\">Bug #1086</a>.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1532/\">Bug #1532</a>.\n\t</li>\n\t<li>\n\tExplicit tab stops may be set for each line.\n\t</li>\n\t<li>\n\tOn Windows and GTK+, when using Korean input methods, IME composition is moved from a\n\tseparate window into the Scintilla window.\n\t</li>\n\t<li>\n\tSciTE adds a \"Clean\" command to the \"Tools\" menu which is meant to be bound to a command like\n\t\"make clean\".\n\t</li>\n\t<li>\n\tLexer added for Windows registry files.\n\t</li>\n\t<li>\n\tHTML lexer fixes a crash with SGML after a Mako comment.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1622/\">Bug #1622</a>.\n\t</li>\n\t<li>\n\tKiXtart lexer adds a block comment state.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1053/\">Feature #1053.</a>\n\t</li>\n\t<li>\n\tMatlab lexer fixes transpose operations like \"X{1}'\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1629/\">Bug #1629</a>.\n\t</li>\n\t<li>\n\tRuby lexer fixes bugs with the syntax of symbols including allowing a symbol to end with '?'.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1627/\">Bug #1627</a>.\n\t</li>\n\t<li>\n\tRust lexer supports byte string literals, naked CR can be escaped in strings, and files starting with\n\t\"#![\" are not treated as starting with a hashbang comment.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1063/\">Feature #1063.</a>\n\t</li>\n\t<li>\n\tBug fixed where style data was stale when deleting a rectangular selection.\n\t</li>\n\t<li>\n\tBug fixed where annotations disappeared when SCI_CLEARDOCUMENTSTYLE called.\n\t</li>\n\t<li>\n\tBug fixed where selection not redrawn after SCI_DELWORDRIGHT.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1633/\">Bug #1633</a>.\n\t</li>\n\t<li>\n\tChange the function prototypes to be complete for functions exported as \"C\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1618/\">Bug #1618</a>.\n\t</li>\n\t<li>\n\tFix a memory leak on GTK+ with autocompletion lists.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1638/\">Bug #1638</a>.\n\t</li>\n\t<li>\n\tOn GTK+, use the full character width for the overstrike caret for multibyte characters.\n\t</li>\n\t<li>\n\tOn Qt, set list icon size to largest icon. Add padding on OS X.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1634/\">Bug #1634</a>.\n\t</li>\n\t<li>\n\tOn Qt, fix building on FreeBSD 9.2.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1635/\">Bug #1635</a>.\n\t</li>\n\t<li>\n\tOn Qt, add a get_character method on the document.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1064/\">Feature #1064.</a>\n\t</li>\n\t<li>\n\tOn Qt, add SCI_* for methods to ScintillaConstants.py.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1065/\">Feature #1065.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ crash fixed with Insert Abbreviation command.\n\t</li>\n\t<li>\n\tFor SciTE with read-only files and are.you.sure=0 reenable choice to save to another\n\tlocation when using Save or Close commands.\n\t</li>\n\t<li>\n\tFix SciTE bug where toggle bookmark did not work after multiple lines with bookmarks merged.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1617/\">Bug #1617</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite344.zip?download\">Release 3.4.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 3 July 2014.\n\t</li>\n\t<li>\n\tStyle byte indicators removed. They were deprecated in 2007. Standard indicators should be used instead.\n\tSome elements used by lexers no longer take number of bits or mask arguments so lexers may need to be\n\tupdated for LexAccessor::StartAt,  LexAccessor::SetFlags (removed),  LexerModule::LexerModule.\n\t</li>\n\t<li>\n\tWhen multiple selections are active, autocompletion text may be inserted at each selection with new\n\tSCI_AUTOCSETMULTI method.\n\t</li>\n\t<li>\n\tC++ lexer fixes crash for \"#define x(\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1614/\">Bug #1614</a>.\n\t</li>\n\t<li>\n\tC++ lexer fixes raw string recognition so that R\"xxx(blah)xxx\" is styled as SCE_C_STRINGRAW.\n\t</li>\n\t<li>\n\tThe Postscript lexer no longer marks token edges with indicators as this used style byte indicators.\n\t</li>\n\t<li>\n\tThe Scriptol lexer no longer displays indicators for poor indentation as this used style byte indicators.\n\t</li>\n\t<li>\n\tTCL lexer fixes names of keyword sets.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1615/\">Bug #1615</a>.\n\t</li>\n\t<li>\n\tShell lexer fixes fold matching problem caused by \"&lt;&lt;&lt;\".\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1605/\">Bug #1605</a>.\n\t</li>\n\t<li>\n\tFix bug where indicators were not removed when fold highlighting on.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1604/\">Bug #1604</a>.\n\t</li>\n\t<li>\n\tFix bug on Cocoa where emoji were treated as being zero width.\n\t</li>\n\t<li>\n\tFix crash on GTK+ with Ubuntu 12.04 and overlay scroll bars.\n\t</li>\n\t<li>\n\tAvoid creating a Cairo context when measuring text on GTK+ as future versions of GTK+\n\tmay prohibit calling gdk_cairo_create except inside drawing handlers. This prohibition may\n\tbe required on Wayland.\n\t</li>\n\t<li>\n\tOn Cocoa, the registerNotifyCallback method is now marked as deprecated so client code that\n\tuses it will display an error message.\n\tClient code should use the delegate mechanism or subclassing instead.\n\tThe method will be removed in the next version.\n\t</li>\n\t<li>\n\tOn Cocoa, package Scintilla more in compliance with platform conventions.\n\tOnly publish public headers in the framework headers directory.\n\tOnly define the Scintilla namespace in Scintilla.h when compiling as C++.\n\tUse the Cocoa NS_ENUM and NS_OPTIONS macros for exposed enumerations.\n\tHide internal methods from public headers.\n\tThese changes are aimed towards publishing Scintilla as a module which will allow it to\n\tbe used from the Swift programming language, although more changes will be needed here.\n\t</li>\n\t<li>\n\tFix crash in SciTE when stream comment performed at line end.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1610/\">Bug #1610</a>.\n\t</li>\n\t<li>\n\tFor SciTE on Windows, display error message when common dialogs fail.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/156/\">Bug #156</a>.\n\t</li>\n\t<li>\n\tFor SciTE on GTK+ fix bug with initialization of toggle buttons in find and replace strips.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1612/\">Bug #1612</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite343.zip?download\">Release 3.4.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 27 May 2014.\n\t</li>\n\t<li>\n\tFix hangs and crashes in DLL at shutdown on Windows when using Direct2D.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite342.zip?download\">Release 3.4.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 22 May 2014.\n\t</li>\n\t<li>\n\tInsertions can be filtered or modified by calling SCI_CHANGEINSERTION inside a handler for\n\tSC_MOD_INSERTCHECK.\n\t</li>\n\t<li>\n\tDMIS lexer added. DMIS is a language for coordinate measuring machines.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1049/\">Feature #1049.</a>\n\t</li>\n\t<li>\n\tLine state may be displayed in the line number margin to aid in debugging lexing and folding with\n\tSC_FOLDFLAG_LINESTATE (128).\n\t</li>\n\t<li>\n\tC++ lexer understands more preprocessor statements. #if defined SYMBOL is understood.\n\tSome macros with arguments can be understood and these may be predefined in keyword set 4\n\t(keywords5 for SciTE)\n\twith syntax similar to CHECKVERSION(x)=(x&lt;3).\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1051/\">Feature #1051.</a>\n\t</li>\n\t<li>\n\tC++ lexer can highlight task marker keywords in comments as SCE_C_TASKMARKER.\n\t</li>\n\t<li>\n\tC++ lexer can optionally highlight escape sequences in strings as SCE_C_ESCAPESEQUENCE.\n\t</li>\n\t<li>\n\tC++ lexer supports Go back quoted raw string literals with lexer.cpp.backquoted.strings option.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1047/\">Feature #1047.</a>\n\t</li>\n\t<li>\n\tSciTE performs word and search match highlighting as an idle task to improve interactivity\n\tand allow use of these features on large files.\n\t</li>\n\t<li>\n\tBug fixed on Cocoa where previous caret lines were visible.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1593/\">Bug #1593</a>.\n\t</li>\n\t<li>\n\tBug fixed where caret remained invisible when period set to 0.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1592/\">Bug #1592</a>.\n\t</li>\n\t<li>\n\tFixed display flashing when scrolling with GTK+ 3.10.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1567/\">Bug #1567</a>.\n\t</li>\n\t<li>\n\tFixed calls and constants deprecated in GTK+ 3.10.\n\t</li>\n\t<li>\n\tFixed bug on Windows where WM_GETTEXT did not provide data in UTF-16 for Unicode window.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/685/\">Bug #685</a>.\n\t</li>\n\t<li>\n\tFor SciTE, protect access to variables used by threads with a mutex to prevent data races.\n\t</li>\n\t<li>\n\tFor SciTE on GTK+ fix thread object leaks.\n\tDisplay the version of GTK+ compiled against in the about box.\n\t</li>\n\t<li>\n\tFor SciTE on GTK+ 3.10, fix the size of the tab bar's content and use\n\tfreedesktop.org standard icon names where possible.\n\t</li>\n\t<li>\n\tFor SciTE on Windows, fix bug where invoking help resubmitted the\n\trunning program.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/272/\">Bug #272</a>.\n\t</li>\n\t<li>\n\tSciTE's highlight current word feature no longer matches the selection when it contains space.\n\t</li>\n\t<li>\n\tFor building SciTE in Visual C++, the win\\SciTE.vcxproj project file should be used.\n\tThe boundscheck directory and its project and solution files have been removed.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite341.zip?download\">Release 3.4.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 1 April 2014.\n\t</li>\n\t<li>\n\tDisplay Unicode line ends as [LS], [PS], and [NEL] blobs.\n\t</li>\n\t<li>\n\tBug fixed where cursor down failed on wrapped lines.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1585/\">Bug #1585</a>.\n\t</li>\n\t<li>\n\tCaret positioning changed a little to appear inside characters less often by\n\trounding the caret position to the pixel grid instead of truncating.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1588/\">Bug #1588</a>.\n\t</li>\n\t<li>\n\tBug fixed where automatic indentation wrong when caret in virtual space.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1586/\">Bug #1586</a>.\n\t</li>\n\t<li>\n\tBug fixed on Windows where WM_LBUTTONDBLCLK was no longer sent to window.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1587/\">Bug #1587</a>.\n\t</li>\n\t<li>\n\tBug fixed with SciTE on Windows XP where black stripes appeared inside the find and\n\treplace strips.\n\t</li>\n\t<li>\n\tCrash fixed in SciTE with recursive properties files.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1507/\">Bug #1507</a>.\n\t</li>\n\t<li>\n\tBug fixed with SciTE where Ctrl+E before an unmatched end brace jumps to file start.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/315/\">Bug #315</a>.\n\t</li>\n\t<li>\n\tFixed scrolling on Cocoa to avoid display glitches and be smoother.\n\t</li>\n\t<li>\n\tFixed crash on Cocoa when character composition used when autocompletion list active.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite340.zip?download\">Release 3.4.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 22 March 2014.\n\t</li>\n\t<li>\n\tThe Unicode line ends and substyles features added as provisional in 3.2.5 are now finalized.\n\tThere are now no provisional features.\n\t</li>\n\t<li>\n\tAdded wrap mode SC_WRAP_WHITESPACE which only wraps on whitespace, not on style changes.\n\t</li>\n\t<li>\n\tSciTE find and replace strips can perform incremental searching and temporary highlighting of all\n\tmatches with the find.strip.incremental, replace.strip.incremental, and find.indicator.incremental settings.\n\t</li>\n\t<li>\n\tSciTE default settings changed to use strips for find and replace and to draw with Direct2D and\n\tDirectWrite on Windows.\n\t</li>\n\t<li>\n\tSciTE on Windows scales image buttons on the find and replace strips to match the current system scale factor.\n\t</li>\n\t<li>\n\tAdditional assembler lexer variant As(SCLEX_AS) for Unix assembly code which uses '#' for comments and\n\t';' to separate statements.\n\t</li>\n\t<li>\n\tFix Coffeescript lexer for keyword style extending past end of word.\n\tAlso fixes styling 0...myArray.length all as a number.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1583/\">Bug #1583</a>.\n\t</li>\n\t<li>\n\tFix crashes and other bugs in Fortran folder by removing folding of do-label constructs.\n\t</li>\n\t<li>\n\tDeleting a whole line deletes the annotations on that line instead of the annotations on the next line.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1577/\">Bug #1577</a>.\n\t</li>\n\t<li>\n\tChanged position of tall calltips to prefer lower half of screen to cut off end instead of start.\n\t</li>\n\t<li>\n\tFix Qt bug where double click treated as triple click.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1575/\">Bug #1575</a>.\n\t</li>\n\t<li>\n\tOn Qt, selecting an item in an autocompletion list that is not currently visible positions it at the top.\n\t</li>\n\t<li>\n\tFix bug on Windows when resizing autocompletion list with only short strings caused the list to move.\n\t</li>\n\t<li>\n\tOn Cocoa reduce scrollable height by one line to fix bugs with moving caret\n\tup or down.\n\t</li>\n\t<li>\n\tOn Cocoa fix calltips which did not appear when they were created in an off-screen position.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite339.zip?download\">Release 3.3.9</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 31 January 2014.\n\t</li>\n\t<li>\n\tFix 3.3.8 bug where external lexers became inaccessible.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1574/\">Bug #1574</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite338.zip?download\">Release 3.3.8</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 28 January 2014.\n\t</li>\n\t<li>\n\tDropSelectionN API added to drop a selection from a multiple selection.\n\t</li>\n\t<li>\n\tCallTipSetPosStart API added to change the position at which backspacing removes the calltip.\n\t</li>\n\t<li>\n\tSC_MARK_BOOKMARK marker symbol added which looks like bookmark ribbons used in\n\tbook reading applications.\n\t</li>\n\t<li>\n\tBasic lexer highlights hex, octal, and binary numbers in FreeBASIC which use the prefixes\n\t&amp;h, &amp;o and &amp;b respectively.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1041/\">Feature #1041.</a>\n\t</li>\n\t<li>\n\tC++ lexer fixes bug where keyword followed immediately by quoted string continued\n\tkeyword style.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1564/\">Bug #1564</a>.\n\t</li>\n\t<li>\n\tMatlab lexer treats '!' differently for Matlab and Octave languages.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1571/\">Bug #1571</a>.\n\t</li>\n\t<li>\n\tRust lexer improved with nested comments, more compliant doc-comment detection,\n\toctal literals, NUL characters treated as valid, and highlighting of raw string literals and float literals fixed.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1038/\">Feature #1038.</a>\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1570/\">Bug #1570</a>.\n\t</li>\n\t<li>\n\tOn Qt expose the EOLMode on the document object.\n\t</li>\n\t<li>\n\tFix hotspot clicking where area was off by half a character width.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1562/\">Bug #1562</a>.\n\t</li>\n\t<li>\n\tTweaked scroll positioning by either 2 pixels or 1 pixel when caret is at left or right of view\n\tto ensure caret is inside visible area.\n\t</li>\n\t<li>\n\tSend SCN_UPDATEUI with SC_UPDATE_SELECTION for Shift+Tab inside text.\n\t</li>\n\t<li>\n\tOn Windows update the system caret position when scrolling to help screen readers\n\tsee the scroll quickly.\n\t</li>\n\t<li>\n\tOn Cocoa, GTK+, and Windows/Direct2D draw circles more accurately so that\n\tcircular folding margin markers appear circular, of consistent size, and centred.\n\tMake SC_MARK_ARROWS drawing more even.\n\tFix corners of SC_MARK_ROUNDRECT with Direct2D to be similar to other platforms.\n\t</li>\n\t<li>\n\tSciTE uses a bookmark ribbon symbol for bookmarks as it scales better to higher resolutions\n\tthan the previous blue gem bitmap.\n\t</li>\n\t<li>\n\tSciTE will change the width of margins while running when the margin.width and fold.margin.width\n\tproperties are changed.\n\t</li>\n\t<li>\n\tSciTE on Windows can display a larger tool bar with the toolbar.large property.\n\t</li>\n\t<li>\n\tSciTE displays a warning message when asked to open a directory.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1568/\">Bug #1568</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite337.zip?download\">Release 3.3.7</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 12 December 2013.\n\t</li>\n\t<li>\n\tLexer added for DMAP language.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1026/\">Feature #1026.</a>\n\t</li>\n\t<li>\n\tBasic lexer supports multiline comments in FreeBASIC.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1023/\">Feature #1023.</a>\n\t</li>\n\t<li>\n\tBash lexer allows '#' inside words..\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1553/\">Bug #1553</a>.\n\t</li>\n\t<li>\n\tC++ lexer recognizes C++11 user-defined literals and applies lexical class SCE_C_USERLITERAL.\n\t</li>\n\t<li>\n\tC++ lexer allows single quote characters as digit separators in numeric literals like 123'456 as this is\n\tincluded in C++14.\n\t</li>\n\t<li>\n\tC++ lexer fixes bug with #include statements without \" or &gt; terminating filename.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1538/\">Bug #1538</a>.\n\t</li>\n\t<li>\n\tC++ lexer fixes split of Doxygen keywords @code{.fileExtension} and @param[in,out].\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1551/\">Bug #1551</a>.\n\t</li>\n\t<li>\n\tC++ lexer styles Doxygen keywords at end of document.\n\t</li>\n\t<li>\n\tCmake lexer fixes bug with empty comments.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1550/\">Bug #1550</a>.\n\t</li>\n\t<li>\n\tFortran folder improved. Treats \"else\" as fold header.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/962/\">Feature #962.</a>\n\t</li>\n\t<li>\n\tFix bug with adjacent instances of the same indicator with different values where only the first was drawn.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1560/\">Bug #1560</a>.\n\t</li>\n\t<li>\n\tFor DirectWrite, use the GDI ClearType gamma value for SC_EFF_QUALITY_LCD_OPTIMIZED as\n\tthis results in text that is similar in colour intensity to GDI.\n\tFor the duller default DirectWrite ClearType text appearance, use SC_EFF_QUALITY_DEFAULT.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/887/\">Feature #887.</a>\n\t</li>\n\t<li>\n\tFix another problem with drawing on Windows with Direct2D when returning from lock screen.\n\tThe whole window is redrawn as just redrawing the initially required area left other areas black.\n\t</li>\n\t<li>\n\tWhen scroll width is tracked, take width of annotation lines into account.\n\t</li>\n\t<li>\n\tFor Cocoa on OS X 10.9, responsive scrolling is supported.\n\t</li>\n\t<li>\n\tOn Cocoa, apply font quality setting to line numbers.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1544/\">Bug #1544</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, clicking in margin now sets focus.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1542/\">Bug #1542</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, correct cursor displayed in margin after showing dialog.\n\t</li>\n\t<li>\n\tOn Cocoa, multipaste mode now works.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1541/\">Bug #1541</a>.\n\t</li>\n\t<li>\n\tOn GTK+, chain up to superclass finalize so that all finalization is performed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1549/\">Bug #1549</a>.\n\t</li>\n\t<li>\n\tOn GTK+, fix horizontal scroll bar range to not be double the needed width.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1546/\">Bug #1546</a>.\n\t</li>\n\t<li>\n\tOn OS X GTK+, report control key as SCI_META for mouse down events.\n\t</li>\n\t<li>\n\tOn Qt, bug fixed with drawing of scrollbars, where previous contents were not drawn over with some\n\tthemes.\n\t</li>\n\t<li>\n\tOn Qt, bug fixed with finding monitor rectangle which could lead to autocomplete showing at wrong location.\n\t</li>\n\t<li>\n\tSciTE fix for multiple message boxes when failing to save a file with save.on.deactivate.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1540/\">Bug #1540</a>.\n\t</li>\n\t<li>\n\tSciTE on GTK+ fixes SIGCHLD handling so that Lua scripts can determine the exit status of processes\n\tthey start.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1557/\">Bug #1557</a>.\n\t</li>\n\t<li>\n\tSciTE on Windows XP fixes bad display of find and replace values when using strips.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite336.zip?download\">Release 3.3.6</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 15 October 2013.\n\t</li>\n\t<li>\n\tAdded functions to help convert between substyles and base styles and between secondary and primary styles.\n\tSCI_GETSTYLEFROMSUBSTYLE finds the base style of substyles.\n\tCan be used to treat all substyles of a style equivalent to that style.\n\tSCI_GETPRIMARYSTYLEFROMSTYLE finds the primary style of secondary styles.\n\tStyleFromSubStyle and PrimaryStyleFromStyle methods were added to ILexerWithSubStyles so each lexer can implement these.\n\t</li>\n\t<li>\n\tLexer added for Rust language.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1024/\">Feature #1024.</a>\n\t</li>\n\t<li>\n\tAvoid false matches in errorlist lexer which is used for the SciTE output pane\n\tby stricter checking of ctags lines.\n\t</li>\n\t<li>\n\tPerl lexer fixes bugs with multi-byte characters, including in HEREDOCs and PODs.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1528/\">Bug #1528</a>.\n\t</li>\n\t<li>\n\tSQL folder folds 'create view' statements.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1020/\">Feature #1020.</a>\n\t</li>\n\t<li>\n\tVisual Prolog lexer updated with better support for string literals and Unicode.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1025/\">Feature #1025.</a>\n\t</li>\n\t<li>\n\tFor SCI_SETIDENTIFIERS, \\t, \\r, and \\n are allowed as well as space between identifiers.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1521/\">Bug #1521</a>.\n\t</li>\n\t<li>\n\tGaining and losing focus is now reported as a notification with the code set to SCN_FOCUSIN\n\tor SCN_FOCUSOUT.\n\tThis allows clients to uniformly use notifications instead of commands.\n\tSince there is no longer a need for commands they will be deprecated in a future version.\n\tClients should switch any code that currently uses SCEN_SETFOCUS or SCEN_KILLFOCUS.\n\t</li>\n\t<li>\n\tOn Cocoa, clients should use the delegate mechanism or subclass ScintillaView in preference\n\tto registerNotifyCallback: which will be deprecated in the future.\n\t</li>\n\t<li>\n\tOn Cocoa, the ScintillaView.h header hides internal implementation details from Platform.h and ScintillaCocoa.h.\n\tInnerView was renamed to SCIContentView and MarginView was renamed to SCIMarginView.\n\tdealloc removed from @interface.\n\t</li>\n\t<li>\n\tOn Cocoa, clients may customize SCIContentView by subclassing both SCIContentView and ScintillaView\n\tand implementing the contentViewClass class method on the ScintillaView subclass to return the class of\n\tthe SCIContentView subclass.\n\t</li>\n\t<li>\n\tOn Cocoa, fixed appearance of alpha rectangles to use specified alpha and colour for outline as well as corner size.\n\tThis makes INDIC_STRAIGHTBOX and INDIC_ROUNDBOX look correct.\n\t</li>\n\t<li>\n\tOn Cocoa, memory leak fixed for MarginView.\n\t</li>\n\t<li>\n\tOn Cocoa, make drag and drop work when destination view is empty.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1534/\">Bug #1534</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, drag image fixed when view scrolled.\n\t</li>\n\t<li>\n\tOn Cocoa, SCI_POSITIONFROMPOINTCLOSE fixed when view scrolled.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1021/\">Feature #1021.</a>\n\t</li>\n\t<li>\n\tOn Cocoa, don't send selection change notification when scrolling.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1522/\">Bug #1522</a>.\n\t</li>\n\t<li>\n\tOn Qt, turn off idle events on destruction to prevent repeatedly calling idle.\n\t</li>\n\t<li>\n\tQt bindings in ScintillaEdit changed to use signed first parameter.\n\t</li>\n\t<li>\n\tCompilation errors fixed on Windows and GTK+ with SCI_NAMESPACE.\n\t</li>\n\t<li>\n\tOn Windows, building with gcc will check if Direct2D headers are available and enable Direct2D if they are.\n\t</li>\n\t<li>\n\tAvoid attempts to redraw empty areas when lexing beyond the currently visible lines.\n\t</li>\n\t<li>\n\tControl more attributes of indicators in SciTE with find.mark.indicator and highlight.current.word.indicator\n\tproperties.\n\t</li>\n\t<li>\n\tFix SciTE bug with buffers becoming read-only.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1525/\">Bug #1525</a>.\n\t</li>\n\t<li>\n\tFix linking SciTE on non-Linux Unix systems with GNU toolchain by linking to libdl.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1523/\">Bug #1523</a>.\n\t</li>\n\t<li>\n\tOn Windows, SciTE's Incremental Search displays match failures by changing the background colour\n\tinstead of not adding the character that caused failure.\n\t</li>\n\t<li>\n\tFix SciTE on GTK+ 3.x incremental search to change foreground colour when no match as\n\tchanging background colour is difficult.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite335.zip?download\">Release 3.3.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 31 August 2013.\n\t</li>\n\t<li>\n\tCharacters may be represented by strings.\n\tIn Unicode mode C1 control characters are represented by their mnemonics.\n\t</li>\n\t<li>\n\tAdded SCI_POSITIONRELATIVE to optimize navigation by character.\n\t</li>\n\t<li>\n\tOption to allow mouse selection to switch to rectangular by pressing Alt after start of gesture.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1007/\">Feature #1007.</a>\n\t</li>\n\t<li>\n\tLexer added for KVIrc script.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1008/\">Feature #1008.</a>\n\t</li>\n\t<li>\n\tBash lexer fixed quoted HereDoc delimiters.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1500/\">Bug #1500</a>.\n\t</li>\n\t<li>\n\tMS SQL lexer fixed ';' to appear as an operator.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1509/\">Bug #1509</a>.\n\t</li>\n\t<li>\n\tStructured Text lexer fixed styling of enumeration members.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1508/\">Bug #1508</a>.\n\t</li>\n\t<li>\n\tFixed bug with horizontal caret position when margin changed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1512/\">Bug #1512</a>.\n\t</li>\n\t<li>\n\tFixed bug on Cocoa where coordinates were relative to text subview instead of whole view.\n\t</li>\n\t<li>\n\tEnsure selection redrawn correctly in two cases.\n\tWhen switching from stream to rectangular selection with Alt+Shift+Up.\n\tWhen reducing the range of an additional selection by moving mouse up.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1007/\">Feature #1007.</a>\n\t</li>\n\t<li>\n\tCopy and paste of rectangular selections compatible with Borland Delphi IDE on Windows.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/1002/\">Feature #1002.</a>\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1513/\">Bug #1513</a>.\n\t</li>\n\t<li>\n\tInitialize extended styles to the default style.\n\t</li>\n\t<li>\n\tOn Windows, fix painting on an explicit HDC when first paint attempt abandoned.\n\t</li>\n\t<li>\n\tQt bindings in ScintillaEdit made to work on 64-bit Unix systems.\n\t</li>\n\t<li>\n\tEasier access to printing on Qt with formatRange method.\n\t</li>\n\t<li>\n\tFixed SciTE failure to save initial buffer in single buffer mode.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1339/\">Bug #1339</a>.\n\t</li>\n\t<li>\n\tFixed compilation problem with Visual C++ in non-English locales.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1506/\">Bug #1506</a>.\n\t</li>\n\t<li>\n\tDisable Direct2D when compiling with MinGW gcc on Windows because of changes in the recent MinGW release.\n\t</li>\n\t<li>\n\tSciTE crash fixed for negative line.margin.width.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1504/\">Bug #1504</a>.\n\t</li>\n\t<li>\n\tSciTE fix for infinite dialog boxes when failing to automatically save a file.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1503/\">Bug #1503</a>.\n\t</li>\n\t<li>\n\tSciTE settings buffered.draw, two.phase.draw, and technology are applied to the\n\toutput pane as well as the edit pane.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite334.zip?download\">Release 3.3.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 19 July 2013.\n\t</li>\n\t<li>\n\tHandling of UTF-8 and DBCS text in lexers improved with methods ForwardBytes and\n\tGetRelativeCharacter added to StyleContext.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1483/\">Bug #1483</a>.\n\t</li>\n\t<li>\n\tFor Unicode text, case-insensitive searching and making text upper or lower case is now\n\tcompliant with Unicode standards on all platforms and is much faster for non-ASCII characters.\n\t</li>\n\t<li>\n\tA CategoriseCharacter function was added to return the Unicode general category of a character\n\twhich can be useful in lexers.\n\t</li>\n\t<li>\n\tOn Cocoa, the LCD Optimized font quality level turns font smoothing on.\n\t</li>\n\t<li>\n\tSciTE 'immediate' subsystem added to allow scripts that work while tools are executed.\n\t</li>\n\t<li>\n\tFont quality exposed in SciTE as font.quality setting.\n\t</li>\n\t<li>\n\tOn Cocoa, message:... methods simplify direct access to Scintilla and avoid call layers..\n\t</li>\n\t<li>\n\tA68K lexer updated.\n\t</li>\n\t<li>\n\tCoffeeScript lexer fixes a bug with comment blocks.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1495/\">Bug #1495</a>\n\t</li>\n\t<li>\n\tECL lexer regular expression code fixed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1491/\">Bug #1491</a>.\n\t</li>\n\t<li>\n\terrorlist lexer only recognizes Perl diagnostics when there is a filename between\n\t\"at\" and \"line\". Had been triggering for MSVC errors containing \"at line\".\n\t</li>\n\t<li>\n\tHaskell lexer fixed to avoid unnecessary full redraws.\n\tDon't highlight CPP inside comments when styling.within.preprocessor is on.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1459/\">Bug #1459</a>.\n\t</li>\n\t<li>\n\tLua lexer fixes bug in labels with UTF-8 text.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1483/\">Bug #1483</a>.\n\t</li>\n\t<li>\n\tPerl lexer fixes bug in string interpolation with UTF-8 text.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1483/\">Bug #1483</a>.\n\t</li>\n\t<li>\n\tFixed bugs with case conversion when the result was longer or shorter than the original text.\n\tCould access past end of string potentially crashing.\n\tSelection now updated to result length.\n\t</li>\n\t<li>\n\tFixed bug where data being inserted and removed was not being reported in\n\tnotification messages. Bug was introduced in 3.3.2.\n\t</li>\n\t<li>\n\tWord wrap bug fixed where the last line could be shown twice.\n\t</li>\n\t<li>\n\tWord wrap bug fixed for lines wrapping too short on Windows and GTK+.\n\t</li>\n\t<li>\n\tWord wrap performance improved.\n\t</li>\n\t<li>\n\tMinor memory leak fixed.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1487/\">Bug #1487</a>.\n\t</li>\n\t<li>\n\tOn Cocoa, fixed insertText: method which was broken when implementing a newer protocol.\n\t</li>\n\t<li>\n\tOn Cocoa, fixed a crash when performing string folding for bytes that do not represent a character\n\tin the current encoding.\n\t</li>\n\t<li>\n\tOn Qt, fixed layout problem when QApplication construction delayed.\n\t</li>\n\t<li>\n\tOn Qt, find_text reports failure with -1 as first element of return value.\n\t</li>\n\t<li>\n\tFixed SciTE on GTK+ bug where a tool command could be performed using the keyboard while one was\n\talready running leading to confusion and crashes.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1486/\">Bug #1486</a>.\n\t</li>\n\t<li>\n\tFixed SciTE bug in Copy as RTF which was limited to first 32 styles.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1011/\">Bug #1011</a>.\n\t</li>\n\t<li>\n\tFixed SciTE on Windows user strip height when the system text scaling factor is 125% or 150%.\n\t</li>\n\t<li>\n\tCompile time checks for Digital Mars C++ removed.\n\t</li>\n\t<li>\n\tVisual C++ 2013 supported.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1492/\">Bug #1492</a>.\n\t</li>\n\t<li>\n\tPython scripts used for building and maintenance improved and moved into scripts directory.\n\t</li>\n\t<li>\n\tTesting scripts now work on Linux using Qt and PySide.\n\t</li>\n\t<li>\n\tTk platform defined.\n\tImplementation for Tk will be available separately from main Scintilla distribution.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite333.zip?download\">Release 3.3.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 2 June 2013.\n\t</li>\n\t<li>\n\tLexer and folder added for Structured Text language.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/959/\">Feature #959.</a>\n\t</li>\n\t<li>\n\tOut of bounds access fixed for GTK+.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1480/\">Bug #1480</a>.\n\t</li>\n\t<li>\n\tCrash fixed for GTK+ on Windows paste.\n\t</li>\n\t<li>\n\tBug fixed with incorrect event copying on GTK+ 3.x.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1481/\">Bug #1481</a>.\n\t</li>\n\t<li>\n\tBug fixed with right to left locales, like Hebrew, on GTK+.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1477/\">Bug #1477</a>.\n\t</li>\n\t<li>\n\tBug fixed with undo grouping of tab and backtab commands.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1478/\">Bug #1478</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite332.zip?download\">Release 3.3.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 22 May 2013.\n\t</li>\n\t<li>\n\tBasic implementations of common folding methods added to Scintilla to make it\n\teasier for containers to implement folding.\n\t</li>\n\t<li>\n\tAdd indicator INDIC_COMPOSITIONTHICK, a thick low underline, to mimic an\n\tappearance used for Asian language input composition.\n\t</li>\n\t<li>\n\tOn Cocoa, implement font quality setting.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/988/\">Feature #988.</a>\n\t</li>\n\t<li>\n\tOn Cocoa, implement automatic enabling of commands and added clear command.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/987/\">Feature #987.</a>\n\t</li>\n\t<li>\n\tC++ lexer adds style for preprocessor doc comment.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/990/\">Feature #990.</a>\n\t</li>\n\t<li>\n\tHaskell lexer and folder improved. Separate mode for literate Haskell \"literatehaskell\" SCLEX_LITERATEHASKELL.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1459/\">Bug #1459 </a>.\n\t</li>\n\t<li>\n\tLaTeX lexer bug fixed for Unicode character following '\\'.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1468/\">Bug #1468 </a>.\n\t</li>\n\t<li>\n\tPowerShell lexer recognizes here strings and doccomment keywords.\n\t#region folding added.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/985/\">Feature #985.</a>\n\t</li>\n\t<li>\n\tFix multi-typing when two carets are located in virtual space on one line so that spaces\n\tare preserved.\n\t</li>\n\t<li>\n\tFixes to input composition on Cocoa and implementation of accented character input through\n\tpress and hold. Set selection correctly so that changes to pieces of composition text are easier to perform.\n\tRestore undo collection after a sequence of composition actions.\n\tComposition popups appear near input.\n\t</li>\n\t<li>\n\tFix lexer problem where no line end was seen at end of document.\n\t</li>\n\t<li>\n\tFix crash on Cocoa when view deallocated.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1466/\">Bug #1466</a>.\n\t</li>\n\t<li>\n\tFix Qt window positioning to not assume the top right of a monitor is at 0, 0.\n\t</li>\n\t<li>\n\tFix Qt to not track mouse when widget is hidden.\n\t</li>\n\t<li>\n\tQt now supports Qt 5.0.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1448/\">Bug #1448</a>.\n\t</li>\n\t<li>\n\tFix drawing on Windows with Direct2D when returning from lock screen.\n\tThe render target had to be recreated and an area would be black since the drawing was not retried.\n\t</li>\n\t<li>\n\tFix display of DBCS documents on Windows Direct2D/DirectWrite with default character set.\n\t</li>\n\t<li>\n\tFor SciTE on Windows, fixed most-recently-used menu when files opened through check.if.already.opened.\n\t</li>\n\t<li>\n\tIn SciTE, do not call OnSave twice when files saved asynchronously.\n\t</li>\n\t<li>\n\tScintilla no longer builds with Visual C++ 6.0.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite331.zip?download\">Release 3.3.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 11 April 2013.\n\t</li>\n\t<li>\n\tAutocompletion lists can now appear in priority order or be sorted by Scintilla.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/981/\">Feature #981.</a>\n\t</li>\n\t<li>\n\tMost lexers now lex an extra NUL byte at the end of the\n\tdocument which makes it more likely they will classify keywords at document end correctly.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/574/\">Bug #574</a>,\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/588/\">Bug #588.</a>\n\t</li>\n\t<li>\n\tHaskell lexer improved in several ways.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1459/\">Bug #1459.</a>\n\t</li>\n\t<li>\n\tMatlab/Octave lexer recognizes block comments and ... comments.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1414/\">Bug #1414.</a>\n\t</li>\n\t<li>\n\tRuby lexer crash fixed with keyword at start of document.\n\t</li>\n\t<li>\n\tThe PLAT_NCURSES platform now called PLAT_CURSES as may work on other implementations.\n\t</li>\n\t<li>\n\tBug on Cocoa fixed where input composition with multiple selection or virtual space selection\n\tcould make undo stop working.\n\t</li>\n\t<li>\n\tDirect2D/DirectWrite mode on Windows now displays documents in non-Latin1 8-bit encodings correctly.\n\t</li>\n\t<li>\n\tCharacter positioning corrected in Direct2D/DirectWrite mode on Windows to avoid text moving and cutting off\n\tlower parts of characters.\n\t</li>\n\t<li>\n\tPosition of calltip and autocompletion lists fixed on Cocoa.\n\t</li>\n\t<li>\n\tWhile regular expression search in DBCS text is still not working, matching partial characters is now avoided\n\tby moving end of match to end of character.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite330.zip?download\">Release 3.3.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 30 March 2013.\n\t</li>\n\t<li>\n\tOverlay scrollers and kinetic scrolling implemented on Cocoa.\n\t</li>\n\t<li>\n\tTo improve display smoothness, styling and UI Update notifications will, when possible, be performed in\n\ta high-priority idle task on Cocoa instead of during painting.\n\tPerforming these jobs inside painting can cause paints to be abandoned and a new paint scheduled.\n\tOn GTK+, the high-priority idle task is used in more cases.\n\t</li>\n\t<li>\n\tSCI_SCROLLRANGE added to scroll the view to display a range of text.\n\tIf the whole range can not be displayed, priority is given to one end.\n\t</li>\n\t<li>\n\tC++ lexer no longer recognizes raw (R\"\") strings when the first character after \"\n\tis invalid.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1454/\">Bug #1454.</a>\n\t</li>\n\t<li>\n\tHTML lexer recognizes JavaScript RegEx literals in more contexts.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1412/\">Bug #1412.</a>\n\t</li>\n\t<li>\n\tFixed automatic display of folded text when return pressed at end of fold header and\n\tfirst folded line was blank.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1455/\">Bug #1455.</a>\n\t</li>\n\t<li>\n\tSCI_VISIBLEFROMDOCLINE fixed to never return a line beyond the document end.\n\t</li>\n\t<li>\n\tSCI_LINESCROLL fixed for a negative column offset.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1450/\">Bug #1450.</a>\n\t</li>\n\t<li>\n\tOn GTK+, fix tab markers so visible if indent markers are visible.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1453/\">Bug #1453.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite325.zip?download\">Release 3.2.5</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 26 February 2013.\n\t</li>\n\t<li>\n\tTo allow cooperation between different uses of extended (beyond 255) styles they should be allocated\n\tusing SCI_ALLOCATEEXTENDEDSTYLES.\n\t</li>\n\t<li>\n\tFor Unicode documents, lexers that use StyleContext will retrieve whole characters\n\tinstead of bytes.\n\tLexAccessor provides a LineEnd method which can be a more efficient way to\n\thandle line ends and can enable Unicode line ends.\n\t</li>\n\t<li>\n\tThe C++ lexer understands the #undef directive when determining preprocessor definitions.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/978/\">Feature #978.</a>\n\t</li>\n\t<li>\n\tThe errorlist lexer recognizes gcc include path diagnostics that appear before an error.\n\t</li>\n\t<li>\n\tFolding implemented for GetText (PO)  translation language.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1437/\">Bug #1437.</a>\n\t</li>\n\t<li>\n\tHTML lexer does not interrupt comment style for processing instructions.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1447/\">Bug #1447.</a>\n\t</li>\n\t<li>\n\tFix SciTE forgetting caret x-position when switching documents.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1442/\">Bug #1442.</a>\n\t</li>\n\t<li>\n\tFixed bug where vertical scrollbar thumb appeared at beginning of document when\n\tscrollbar shown.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1446/\">Bug #1446.</a>\n\t</li>\n\t<li>\n\tFixed brace-highlighting bug on OS X 10.8 where matching brace is on a different line.\n\t</li>\n\t<li>\n\t<a href=\"ScintillaDoc.html#ProvisionalMessages\">Provisional features</a>\n\tare new features that may change or be removed if they cause problems but should become\n\tpermanent if they work well.\n\tFor this release <a href=\"ScintillaDoc.html#SCI_GETLINEENDTYPESSUPPORTED\">Unicode line ends</a> and\n\t<a href=\"ScintillaDoc.html#Substyles\">substyles</a>\n\tare provisional features.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite324.zip?download\">Release 3.2.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 17 January 2013.\n\t</li>\n\t<li>\n\tCaret line highlight can optionally remain visible when window does not have focus.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/964/\">Feature #964.</a>\n\t</li>\n\t<li>\n\tDelegate mechanism for notifications added on Cocoa.\n\t</li>\n\t<li>\n\tNUL characters in selection are copied to clipboard as spaces to avoid truncating\n\tat the NUL.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1289/\">Bug #1289.</a>\n\t</li>\n\t<li>\n\tC++ lexer fixes problem with showing inactive sections when preprocessor lines contain trailing comment.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1413/\">Bug #1413.</a>\n\t</li>\n\t<li>\n\tC++ lexer fixes problem with JavaScript regular expressions with '/' in character ranges.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1415/\">Bug #1415.</a>\n\t</li>\n\t<li>\n\tLaTeX folder added.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/970/\">Feature #970.</a>\n\t</li>\n\t<li>\n\tLaTeX lexer improves styling of math environments.\n\t<a href=\"https://sourceforge.net/p/scintilla/feature-requests/970/\">Feature #970.</a>\n\t</li>\n\t<li>\n\tMySQL lexer implements hidden commands.\n\t</li>\n\t<li>\n\tOnly produce a single undo step when autocompleting a single word.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1421/\">Bug #1421.</a>\n\t</li>\n\t<li>\n\tFixed crash when printing lines longer than 8000 characters.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1430/\">Bug #1430.</a>\n\t</li>\n\t<li>\n\tFixed problem in character movement extends selection mode where reversing\n\tdirection collapsed the selection.\n\t</li>\n\t<li>\n\tMemory issues fixed on Cocoa, involving object ownership,\n\tlifetime of timers, and images held by the info bar.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1436/\">Bug #1436.</a>\n\t</li>\n\t<li>\n\tCocoa key binding for Alt+Delete changed to delete previous word to be more compatible with\n\tplatform standards.\n\t</li>\n\t<li>\n\tFixed crash on Cocoa with scrollbar when there is no scrolling possible.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1416/\">Bug #1416.</a>\n\t</li>\n\t<li>\n\tOn Cocoa with retina display fixed positioning of autocompletion lists.\n\t</li>\n\t<li>\n\tFixed SciTE on Windows failure to run a batch file with a name containing a space by\n\tquoting the path in the properties file.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1423/\">Bug #1423.</a>\n\t</li>\n\t<li>\n\tFixed scaling bug when printing on GTK+.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1427/\">Bug #1427.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK toolbar.detachable feature removed.\n\t</li>\n\t<li>\n\tFixed some background saving bugs in SciTE.\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1366/\">Bug #1366.</a>\n\t<a href=\"https://sourceforge.net/p/scintilla/bugs/1339/\">Bug #1339.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite323.zip?download\">Release 3.2.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 21 October 2012.\n\t</li>\n\t<li>\n\tImprove speed when performing multiple searches.\n\t</li>\n\t<li>\n\tSciTE adds definition of PLAT_UNIX for both PLAT_GTK and PLAT_MAC to allow consolidation of\n\tsettings valid on all Unix variants.\n\t</li>\n\t<li>\n\tSignal autoCompleteCancelled added on Qt.\n\t</li>\n\t<li>\n\tBash lexer supports nested delimiter pairs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3569352&group_id=2439\">Feature #3569352.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1515556&group_id=2439\">Bug #1515556.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3008483&group_id=2439\">Bug #3008483.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3512208&group_id=2439\">Bug #3512208.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3515392&group_id=2439\">Bug #3515392.</a>\n\t</li>\n\t<li>\n\tFor C/C++, recognize exponent in floating point hexadecimal literals.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3576454&group_id=2439\">Bug #3576454.</a>\n\t</li>\n\t<li>\n\tFor C #include statements, do not treat // in the path as a comment.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3519260&group_id=2439\">Bug #3519260.</a>\n\t</li>\n\t<li>\n\tLexer for GetText translations (PO) improved with additional styles and single instance limitation fixed.\n\t</li>\n\t<li>\n\tRuby for loop folding fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3240902&group_id=2439\">Bug #3240902.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3567391&group_id=2439\">Bug #3567391.</a>\n\t</li>\n\t<li>\n\tRuby recognition of here-doc after class or instance variable fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3567809&group_id=2439\">Bug #3567809.</a>\n\t</li>\n\t<li>\n\tSQL folding of loop and case fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3567905&group_id=2439\">Bug #3567905.</a>\n\t</li>\n\t<li>\n\tSQL folding of case with assignment fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3571820&group_id=2439\">Bug #3571820.</a>\n\t</li>\n\t<li>\n\tFix hang when removing all characters from indicator at end of document.\n\t</li>\n\t<li>\n\tFix failure of \\xhh in regular expression search for values greater than 0x79.\n\t</li>\n\t<li>\n\tOn Cocoa on OS X 10.8, fix inverted drawing of find indicator.\n\t</li>\n\t<li>\n\tOn Cocoa, fix double drawing when horizontal scroll range small and user swipes horizontally.\n\t</li>\n\t<li>\n\tOn Cocoa, remove incorrect setting of save point when reading information through 'string' and 'selectedString'.\n\t</li>\n\t<li>\n\tOn Cocoa, fix incorrect memory management of infoBar.\n\t</li>\n\t<li>\n\tOn GTK+ 3 Ubuntu, fix crash when drawing margin.\n\t</li>\n\t<li>\n\tOn ncurses, fix excessive spacing with italics line end.\n\t</li>\n\t<li>\n\tOn Windows, search for D2D1.DLL and DWRITE.DLL in system directory to avoid loading from earlier\n\tin path where could be planted by malware.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite322.zip?download\">Release 3.2.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 31 August 2012.\n\t</li>\n\t<li>\n\tRetina display support for Cocoa. Text size fixed.\n\tScale factor for images implemented so they can be displayed in high definition.\n\t</li>\n\t<li>\n\tImplement INDIC_SQUIGGLEPIXMAP as a faster version of INDIC_SQUIGGLE.\n\tAvoid poor drawing at right of INDIC_SQUIGGLE.\n\tAlign INDIC_DOTBOX to pixel grid for full intensity.\n\t</li>\n\t<li>\n\tImplement SCI_GETSELECTIONEMPTY API.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3543121&group_id=2439\">Bug #3543121.</a>\n\t</li>\n\t<li>\n\tAdded SCI_VCHOMEDISPLAY and SCI_VCHOMEDISPLAYEXTEND key commands.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3561433&group_id=2439\">Feature #3561433.</a>\n\t</li>\n\t<li>\n\tAllow specifying SciTE Find in Files directory with find.in.directory property.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3558594&group_id=2439\">Feature #3558594.</a>\n\t</li>\n\t<li>\n\tOverride SciTE global strip.trailing.spaces with strip.trailing.spaces by pattern files.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3556320&group_id=2439\">Feature #3556320.</a>\n\t</li>\n\t<li>\n\tFix long XML script tag handling in XML lexer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3534190&group_id=2439\">Bug #3534190.</a>\n\t</li>\n\t<li>\n\tFix rectangular selection range after backspace.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3543097&group_id=2439\">Bug #3543097.</a>\n\t</li>\n\t<li>\n\tSend SCN_UPDATEUI with SC_UPDATE_SELECTION for backspace in virtual space.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3543121&group_id=2439\">Bug #3543121.</a>\n\t</li>\n\t<li>\n\tAvoid problems when calltip highlight range is negative.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3545938&group_id=2439\">Bug #3545938.</a>\n\t</li>\n\t<li>\n\tOn Cocoa, fix image drawing code so that image is not accessed after being freed\n\tand is drawn in the correct location.\n\t</li>\n\t<li>\n\tOn Cocoa, limit horizontal touch scrolling to existing established width.\n\t</li>\n\t<li>\n\tOn Cocoa, decrease sensitivity of pinch-zoom.\n\t</li>\n\t<li>\n\tFix Cocoa drawing where style changes were not immediately visible.\n\t</li>\n\t<li>\n\tFix Cocoa memory leak due to reference cycle.\n\t</li>\n\t<li>\n\tFix Cocoa bug where notifications were sent after Scintilla was freed.\n\t</li>\n\t<li>\n\tSciTE on OS X user shortcuts treats \"Ctrl+D\" as equivalent to \"Ctrl+d\".\n\t</li>\n\t<li>\n\tOn Windows, saving SciTE's Lua startup script causes it to run.\n\t</li>\n\t<li>\n\tLimit time allowed to highlight current word in SciTE to 0.25 seconds to remain responsive.\n\t</li>\n\t<li>\n\tFixed SciTE read-only mode to stick with buffer.\n\t</li>\n\t<li>\n\tFor SciTE on Windows, enable Ctrl+Z, Ctrl+X, and Ctrl+C (Undo, Cut, and Copy) in the\n\teditable fields of find and replace strips\n\t</li>\n\t<li>\n\tRemove limit on logical line length in SciTE .properties files.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3544312&group_id=2439\">Bug #3544312.</a>\n\t</li>\n\t<li>\n\tImprove performance of SciTE Save As command.\n\t</li>\n\t<li>\n\tFix SciTE crash with empty .properties files. Bug #3545938.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3555308&group_id=2439\">Bug #3555308.</a>\n\t</li>\n\t<li>\n\tFix repeated letter in SciTE calltips.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3545938&group_id=2439\">Bug #3545938.</a>\n\t</li>\n\t<li>\n\tRefine build time checking for Direct2D and DirectWrite.\n\t</li>\n\t<li>\n\tAvoid potential build problems on Windows with MultiMon.h by explicitly checking for multi-monitor APIs.\n\t</li>\n\t<li>\n\tAutomatically disable themed drawing in SciTE when building on Windows 2000.\n\tReenable building for Windows NT 4 on NT 4 .\n\t</li>\n\t<li>\n\tAdded ncurses platform definitions. Implementation is maintained separately as\n\t<a href=\"https://orbitalquark.github.io/scinterm\">Scinterm</a>.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite321.zip?download\">Release 3.2.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 14 July 2012.\n\t</li>\n\t<li>\n\tIn Scintilla.iface, specify features as properties instead of functions where possible and fix some enumerations.\n\t</li>\n\t<li>\n\tIn SciTE Lua scripts, string properties in Scintilla API can be retrieved as well as set using property notation.\n\t</li>\n\t<li>\n\tAdded character class APIs: SCI_SETPUNCTUATIONCHARS, SCI_GETWORDCHARS, SCI_GETWHITESPACECHARS,\n\tand SCI_GETPUNCTUATIONCHARS.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3529805&group_id=2439\">Feature #3529805.</a>\n\t</li>\n\t<li>\n\tLess/Hss support added to CSS lexer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3532413&group_id=2439\">Feature #3532413.</a>\n\t</li>\n\t<li>\n\tC++ lexer style SCE_C_PREPROCESSORCOMMENT added for stream comments in preprocessor.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3487406&group_id=2439\">Bug #3487406.</a>\n\t</li>\n\t<li>\n\tFix incorrect styling of inactive code in C++ lexer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3533036&group_id=2439\">Bug #3533036.</a>\n\t</li>\n\t<li>\n\tFix incorrect styling by C++ lexer after empty lines in preprocessor style.\n\t</li>\n\t<li>\n\tC++ lexer option \"lexer.cpp.allow.dollars\" fixed so can be turned off after being on.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3541461&group_id=2439\">Bug #3541461.</a>\n\t</li>\n\t<li>\n\tFortran fixed format lexer fixed to style comments from column 73.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3540486&group_id=2439\">Bug #3540486.</a>\n\t</li>\n\t<li>\n\tFortran folder folds CRITICAL .. END CRITICAL.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3540486&group_id=2439\">Bug #3540486.</a>\n\t</li>\n\t<li>\n\tFortran lexer fixes styling after comment line ending with '&amp;'.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3087226&group_id=2439\">Bug #3087226.</a>\n\t</li>\n\t<li>\n\tFortran lexer styles preprocessor lines so they do not trigger incorrect folding.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2906275&group_id=2439\">Bug #2906275.</a>\n\t</li>\n\t<li>\n\tFortran folder fixes folding of nested ifs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2809176&group_id=2439\">Bug #2809176.</a>\n\t</li>\n\t<li>\n\tHTML folder fixes folding of CDATA when fold.html.preprocessor=0.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3540491&group_id=2439\">Bug #3540491.</a>\n\t</li>\n\t<li>\n\tOn Cocoa, fix autocompletion font lifetime issue and row height computation.\n\t</li>\n\t<li>\n\tIn 'choose single' mode, autocompletion will close an existing list if asked to display a single entry list.\n\t</li>\n\t<li>\n\tFixed SCI_MARKERDELETE to only delete one marker per call.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3535806&group_id=2439\">Bug #3535806.</a>\n\t</li>\n\t<li>\n\tProperly position caret after undoing coalesced delete operations.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3523326&group_id=2439\">Bug #3523326.</a>\n\t</li>\n\t<li>\n\tEnsure margin is redrawn when SCI_MARGINSETSTYLE called.\n\t</li>\n\t<li>\n\tFix clicks in first pixel of margins to send SCN_MARGINCLICK.\n\t</li>\n\t<li>\n\tFix infinite loop when drawing block caret for a zero width space character at document start.\n\t</li>\n\t<li>\n\tCrash fixed for deleting negative range.\n\t</li>\n\t<li>\n\tFor characters that overlap the beginning of their space such as italics descenders and bold serifs, allow start\n\tof text to draw 1 pixel into margin.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=699587&group_id=2439\">Bug #699587.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3537799&group_id=2439\">Bug #3537799.</a>\n\t</li>\n\t<li>\n\tFixed problems compiling Scintilla for Qt with GCC 4.7.1 x64.\n\t</li>\n\t<li>\n\tFixed problem with determining GTK+ sub-platform caused when adding Qt support in 3.2.0.\n\t</li>\n\t<li>\n\tFix incorrect measurement of untitled file in SciTE on Linux leading to message \"File ...' is 2147483647 bytes long\".\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3537764&group_id=2439\">Bug #3537764.</a>\n\t</li>\n\t<li>\n\tIn SciTE, fix open of selected filename with line number to go to that line.\n\t</li>\n\t<li>\n\tFix problem with last visible buffer closing in SciTE causing invisible buffers to be active.\n\t</li>\n\t<li>\n\tAvoid blinking of SciTE's current word highlight when output pane changes.\n\t</li>\n\t<li>\n\tSciTE properties files can be longer than 60K.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite320.zip?download\">Release 3.2.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 1 June 2012.\n\t</li>\n\t<li>\n\tPlatform layer added for the Qt open-source cross-platform application and user interface framework\n\tfor development in C++ or in Python with the PySide bindings for Qt.\n\t</li>\n\t<li>\n\tDirect access provided to the document bytes for ranges within Scintilla.\n\tThis is similar to the existing SCI_GETCHARACTERPOINTER API but allows for better performance.\n\t</li>\n\t<li>\n\tCtrl+Double Click and Ctrl+Triple Click add the word or line to the set of selections.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3520037&group_id=2439\">Feature #3520037.</a>\n\t</li>\n\t<li>\n\tA SCI_DELETERANGE API was added for deleting a range of text.\n\t</li>\n\t<li>\n\tLine wrap markers may now be drawn in the line number margin.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3518198&group_id=2439\">Feature #3518198.</a>\n\t</li>\n\t<li>\n\tSciTE on OS X adds option to hide hidden files in the open dialog box.\n\t</li>\n\t<li>\n\tLexer added for OScript language.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3523197&group_id=2439\">Feature #3523197.</a>\n\t</li>\n\t<li>\n\tLexer added for Visual Prolog language.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3523018&group_id=2439\">Feature #3523018.</a>\n\t</li>\n\t<li>\n\tUTF-8 validity is checked more stringently and consistently. All 66 non-characters are now treated as invalid.\n\t</li>\n\t<li>\n\tHTML lexer bug fixed with inconsistent highlighting for PHP when attribute on separate line from tag.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3520027&group_id=2439\">Bug #3520027.</a>\n\t</li>\n\t<li>\n\tHTML lexer bug fixed for JavaScript block comments.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3520032&group_id=2439\">Bug #3520032.</a>\n\t</li>\n\t<li>\n\tAnnotation drawing bug fixed when box displayed with different colours on different lines.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3519872&group_id=2439\">Bug #3519872.</a>\n\t</li>\n\t<li>\n\tOn Windows with Direct2D, fix drawing with 125% and 150% DPI system settings.\n\t</li>\n\t<li>\n\tVirtual space selection bug fixed for rectangular selections.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3519246&group_id=2439\">Bug #3519246.</a>\n\t</li>\n\t<li>\n\tReplacing multiple selection with newline changed to only affect main selection.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3522251&group_id=2439\">Bug #3522251.</a>\n\t</li>\n\t<li>\n\tReplacing selection with newline changed to group deletion and insertion as a single undo action.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3522250&group_id=2439\">Bug #3522250.</a>\n\t</li>\n\t<li>\n\tAuto-completion lists on GTK+ 3 set height correctly instead of showing too few lines.\n\t</li>\n\t<li>\n\tMouse wheel scrolling changed to avoid GTK+ bug in recent distributions.\n\t</li>\n\t<li>\n\tIME bug on Windows fixed for horizontal jump.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3529728&group_id=2439\">Bug #3529728.</a>\n\t</li>\n\t<li>\n\tSciTE case-insensitive autocompletion filters equal identifiers better.\n\tCalltip arrows work with bare word identifiers.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3517810&group_id=2439\">Bug #3517810.</a>\n\t</li>\n\t<li>\n\tSciTE bug fixed where shbang lines not setting file type when switching\n\tto file loaded in background.\n\t</li>\n\t<li>\n\tSciTE on GTK+ shows open and save dialogs with the directory of the current file displayed.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite310.zip?download\">Release 3.1.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 20 April 2012.\n\t</li>\n\t<li>\n\tAnimated find indicator added on Cocoa.\n\t</li>\n\t<li>\n\tButtons can be made default in SciTE user strips.\n\t</li>\n\t<li>\n\tSciTE allows find and replace histories to be saved in session.\n\t</li>\n\t<li>\n\tOption added to allow case-insensitive selection in auto-completion lists.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3516538&group_id=2439\">Bug #3516538.</a>\n\t</li>\n\t<li>\n\tReplace \\0 by complete found text in regular expressions.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3510979&group_id=2439\">Feature #3510979.</a>\n\t</li>\n\t<li>\n\tFixed single quoted strings in bash lexer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3512208&group_id=2439\">Bug #3512208.</a>\n\t</li>\n\t<li>\n\tIncorrect highlighting fixed in C++ lexer for continued lines.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3509317&group_id=2439\">Bug #3509317.</a>\n\t</li>\n\t<li>\n\tHang fixed in diff lexer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3508602&group_id=2439\">Bug #3508602.</a>\n\t</li>\n\t<li>\n\tFolding improved for SQL CASE/MERGE statement.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3503277&group_id=2439\">Bug #3503277.</a>\n\t</li>\n\t<li>\n\tFix extra drawing of selection inside word wrap indentation.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3515555&group_id=2439\">Bug #3515555.</a>\n\t</li>\n\t<li>\n\tFix problem with determining the last line that needs styling when drawing.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3514882&group_id=2439\">Bug #3514882.</a>\n\t</li>\n\t<li>\n\tFix problems with drawing in margins.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3514882&group_id=2439\">Bug #3514882.</a>\n\t</li>\n\t<li>\n\tFix printing crash when using Direct2D to display on-screen.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3513946&group_id=2439\">Bug #3513946.</a>\n\t</li>\n\t<li>\n\tFix SciTE bug where background.*.size disabled restoration of bookmarks and positions from session.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3514885&group_id=2439\">Bug #3514885.</a>\n\t</li>\n\t<li>\n\tFixed the Move Selected Lines command when last line does not end with a line end character.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3511023&group_id=2439\">Bug #3511023.</a>\n\t</li>\n\t<li>\n\tFix word wrap indentation printing to use printer settings instead of screen settings.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3512961&group_id=2439\">Bug #3512961.</a>\n\t</li>\n\t<li>\n\tFix SciTE bug where executing an empty command prevented executing further commands\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3512976&group_id=2439\">Bug #3512976.</a>\n\t</li>\n\t<li>\n\tFix SciTE bugs with focus in user strips and made strips more robust with invalid definitions.\n\t</li>\n\t<li>\n\tSuppress SciTE regular expression option when searching with find next selection.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3510985&group_id=2439\">Bug #3510985.</a>\n\t</li>\n\t<li>\n\tSciTE Find in Files command matches empty pattern to all files.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3495918&group_id=2439\">Feature #3495918.</a>\n\t</li>\n\t<li>\n\tFix scroll with mouse wheel on GTK+.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3501321&group_id=2439\">Bug #3501321.</a>\n\t</li>\n\t<li>\n\tFix column finding method so that tab is counted correctly.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3483713&group_id=2439\">Bug #3483713.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite304.zip?download\">Release 3.0.4</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 8 March 2012.\n\t</li>\n\t<li>\n\tSciTE scripts can create user interfaces as strips.\n\t</li>\n\t<li>\n\tSciTE can save files automatically in the background.\n\t</li>\n\t<li>\n\tPinch zoom implemented on Cocoa.\n\t</li>\n\t<li>\n\tECL lexer added.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3488209&group_id=2439\">Feature #3488209.</a>\n\t</li>\n\t<li>\n\tCPP lexer fixes styling after document comment keywords.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3495445&group_id=2439\">Bug #3495445.</a>\n\t</li>\n\t<li>\n\tPascal folder improves handling of some constructs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3486385&group_id=2439\">Feature #3486385.</a>\n\t</li>\n\t<li>\n\tXML lexer avoids entering a bad mode due to complex preprocessor instructions.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3488060&group_id=2439\">Bug #3488060.</a>\n\t</li>\n\t<li>\n\tDuplicate command is always remembered as a distinct command for undo.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3495836&group_id=2439\">Bug #3495836.</a>\n\t</li>\n\t<li>\n\tSciTE xml.auto.close.tags no longer closes with PHP code similar to &lt;a $this-&gt;\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3488067&group_id=2439\">Bug #3488067.</a>\n\t</li>\n\t<li>\n\tFix bug where setting an indicator for the whole document would fail.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3487440&group_id=2439\">Bug #3487440.</a>\n\t</li>\n\t<li>\n\tCrash fixed for SCI_MOVESELECTEDLINESDOWN with empty vertical selection.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3496403&group_id=2439\">Bug #3496403.</a>\n\t</li>\n\t<li>\n\tDifferences between buffered and unbuffered mode on Direct2D eliminated.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3495791&group_id=2439\">Bug #3495791.</a>\n\t</li>\n\t<li>\n\tFont leading implemented for Direct2D to improve display of character blobs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494744&group_id=2439\">Bug #3494744.</a>\n\t</li>\n\t<li>\n\tFractional widths used for line numbers, character markers and other situations.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494492&group_id=2439\">Bug #3494492.</a>\n\t</li>\n\t<li>\n\tTranslucent rectangles drawn using Direct2D with sharper corners.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494492&group_id=2439\">Bug #3494492.</a>\n\t</li>\n\t<li>\n\tRGBA markers drawn sharper when centred using Direct2D.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494202&group_id=2439\">Bug #3494202.</a>\n\t</li>\n\t<li>\n\tRGBA markers are drawn centred when taller than line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494184&group_id=2439\">Bug #3494184.</a>\n\t</li>\n\t<li>\n\tImage marker drawing problem fixed for markers taller than line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3493503&group_id=2439\">Bug #3493503.</a>\n\t</li>\n\t<li>\n\tMarkers are drawn horizontally off-centre based on margin type instead of dimensions.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3488696&group_id=2439\">Bug #3488696.</a>\n\t</li>\n\t<li>\n\tFold tail markers drawn vertically centred.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3488289&group_id=2439\">Feature #3488289.</a>\n\t</li>\n\t<li>\n\tOn Windows, Scintilla is more responsive in wrap mode.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3487397&group_id=2439\">Bug #3487397.</a>\n\t</li>\n\t<li>\n\tUnimportant \"Gdk-CRITICAL\" messages are no longer displayed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3488481&group_id=2439\">Bug #3488481.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows Find in Files sets focus to dialog when already created; allows opening dialog when a job is running.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3480635&group_id=2439\">Bug #3480635.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3486657&group_id=2439\">Bug #3486657.</a>\n\t</li>\n\t<li>\n\tFixed problems with multiple clicks in margin and with mouse actions combined with virtual space.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3484370&group_id=2439\">Bug #3484370.</a>\n\t</li>\n\t<li>\n\tFixed bug with using page up and down and not returning to original line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3485669&group_id=2439\">Bug #3485669.</a>\n\t</li>\n\t<li>\n\tDown arrow with wrapped text no longer skips lines.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1776560&group_id=2439\">Bug #1776560.</a>\n\t</li>\n\t<li>\n\tFix problem with dwell ending immediately due to word wrap.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3484416&group_id=2439\">Bug #3484416.</a>\n\t</li>\n\t<li>\n\tWrapped lines are rewrapped more consistently while resizing window.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3484179&group_id=2439\">Bug #3484179.</a>\n\t</li>\n\t<li>\n\tSelected line ends are highlighted more consistently.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3484330&group_id=2439\">Bug #3484330.</a>\n\t</li>\n\t<li>\n\tFix grey background on files that use shbang to choose language.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3482777&group_id=2439\">Bug #3482777.</a>\n\t</li>\n\t<li>\n\tFix failure messages from empty commands in SciTE.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3480645&group_id=2439\">Bug #3480645.</a>\n\t</li>\n\t<li>\n\tRedrawing reduced for some marker calls.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3493530&group_id=2439\">Feature #3493530.</a>\n\t</li>\n\t<li>\n\tMatch brace and select brace commands work in SciTE output pane.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3486598&group_id=2439\">Feature #3486598.</a>\n\t</li>\n\t<li>\n\tPerforming SciTE \"Show Calltip\" command when a calltip is already visible shows the next calltip.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3487017&group_id=2439\">Feature #3487017.</a>\n\t</li>\n\t<li>\n\tSciTE allows saving file even when file unchanged.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3486654&group_id=2439\">Feature #3486654.</a>\n\t</li>\n\t<li>\n\tSciTE allows optional use of character escapes in calltips.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3495239&group_id=2439\">Feature #3495239.</a>\n\t</li>\n\t<li>\n\tSciTE can open file:// URLs with Ctrl+Shift+O.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3495389&group_id=2439\">Feature #3495389.</a>\n\t</li>\n\t<li>\n\tKey modifiers updated for GTK+ on OS X to match upstream changes.\n\t</li>\n\t<li>\n\tSciTE hang when marking all occurrences of regular expressions fixed.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite303.zip?download\">Release 3.0.3</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 28 January 2012.\n\t</li>\n\t<li>\n\tPrinting works on GTK+ version 2.x as well as 3.x.\n\t</li>\n\t<li>\n\tLexer added for the AviSynth language.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3475611&group_id=2439\">Feature #3475611.</a>\n\t</li>\n\t<li>\n\tLexer added for the Take Command / TCC scripting language.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3462462&group_id=2439\">Feature #3462462.</a>\n\t</li>\n\t<li>\n\tCSS lexer gains support for SCSS.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3268017&group_id=2439\">Feature #3268017.</a>\n\t</li>\n\t<li>\n\tCPP lexer fixes problems in the preprocessor structure caused by continuation lines.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3458508&group_id=2439\">Bug #3458508.</a>\n\t</li>\n\t<li>\n\tErrorlist lexer handles column numbers for GCC format diagnostics.\n\tIn SciTE, Next Message goes to column where this can be decoded from GCC format diagnostics.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3453075&group_id=2439\">Feature #3453075.</a>\n\t</li>\n\t<li>\n\tHTML folder fixes spurious folds on some tags.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3459262&group_id=2439\">Bug #3459262.</a>\n\t</li>\n\t<li>\n\tRuby lexer fixes bug where '=' at start of file caused whole file to appear as a comment.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3452488&group_id=2439\">Bug #3452488.</a>\n\t</li>\n\t<li>\n\tSQL folder folds blocks of single line comments.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3467425&group_id=2439\">Feature #3467425.</a>\n\t</li>\n\t<li>\n\tOn Windows using Direct2D, defer invalidation of render target until completion of painting to avoid failures.\n\t</li>\n\t<li>\n\tFurther support of fractional positioning. Spaces, tabs, and single character tokens can take fractional space\n\tand wrapped lines are positioned taking fractional positions into account.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3471998&group_id=2439\">Bug #3471998.</a>\n\t</li>\n\t<li>\n\tOn Windows using Direct2D, fix extra carets appearing.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3471998&group_id=2439\">Bug #3471998.</a>\n\t</li>\n\t<li>\n\tFor autocompletion lists Page Up and Down move by the list height instead of by 5 lines.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3455493&group_id=2439\">Bug #3455493.</a>\n\t</li>\n\t<li>\n\tFor SCI_LINESCROLLDOWN/UP don't select into virtual space.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3451681&group_id=2439\">Bug #3451681.</a>\n\t</li>\n\t<li>\n\tFix fold highlight not being fully drawn.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3469936&group_id=2439\">Bug #3469936.</a>\n\t</li>\n\t<li>\n\tFix selection margin appearing black when starting in wrap mode.\n\t</li>\n\t<li>\n\tFix crash when changing end of document after adding an annotation.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3476637&group_id=2439\">Bug #3476637.</a>\n\t</li>\n\t<li>\n\tFix problems with building to make RPMs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3476149&group_id=2439\">Bug #3476149.</a>\n\t</li>\n\t<li>\n\tFix problem with building on GTK+ where recent distributions could not find gmodule.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3469056&group_id=2439\">Bug #3469056.</a>\n\t</li>\n\t<li>\n\tFix problem with installing SciTE on GTK+ due to icon definition in .desktop file including an extension.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3476117&group_id=2439\">Bug #3476117.</a>\n\t</li>\n\t<li>\n\tFix SciTE bug where new buffers inherited some properties from previously opened file.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3457060&group_id=2439\">Bug #3457060.</a>\n\t</li>\n\t<li>\n\tFix focus when closing tab in SciTE with middle click. Focus moves to edit pane instead of staying on tab bar.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3440142&group_id=2439\">Bug #3440142.</a>\n\t</li>\n\t<li>\n\tFor SciTE on Windows fix bug where Open Selected Filename for URL would append a file extension.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3459185&group_id=2439\">Feature #3459185.</a>\n\t</li>\n\t<li>\n\tFor SciTE on Windows fix key handling of control characters in Parameters dialog so normal editing (Ctrl+C, ...) works.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3459345&group_id=2439\">Bug #3459345.</a>\n\t</li>\n\t<li>\n\tFix SciTE bug where files became read-only after saving. Drop the \"*\" dirty marker after save completes.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3467432&group_id=2439\">Bug #3467432.</a>\n\t</li>\n\t<li>\n\tFor SciTE handling of diffs with \"+++\" and \"---\" lines, also handle case where not followed by tab.\n\tGo to correct line for diff \"+++\" message.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3467143&group_id=2439\">Bug #3467143.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3467178&group_id=2439\">Bug #3467178.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ now performs threaded actions even on GTK+ versions before 2.12.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite302.zip?download\">Release 3.0.2</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 9 December 2011.\n\t</li>\n\t<li>\n\tSciTE saves files in the background without blocking the user interface.\n\t</li>\n\t<li>\n\tPrinting implemented in SciTE on GTK+ 3.x.\n\t</li>\n\t<li>\n\tILoader interface for background loading finalized and documented.\n\t</li>\n\t<li>\n\tCoffeeScript lexer added.\n\t</li>\n\t<li>\n\tC++ lexer fixes crash with \"#if defined( XXX 1\".\n\t</li>\n\t<li>\n\tCrash with Direct2D on Windows fixed.\n\t</li>\n\t<li>\n\tBackspace removing protected range fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3445911&group_id=2439\">Bug #3445911.</a>\n\t</li>\n\t<li>\n\tCursor setting failure on Windows when screen saver on fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3438780&group_id=2439\">Bug #3438780.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ hang fixed with -open:file option.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3441980&group_id=2439\">Bug #3441980.</a>\n\t</li>\n\t<li>\n\tFailure to evaluate shbang fixed in SciTE.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3441801&group_id=2439\">Bug #3441801.</a>\n\t</li>\n\t<li>\n\tSciTE failure to treat files starting with \"&lt;?xml\" as XML fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3440718&group_id=2439\">Bug #3440718.</a>\n\t</li>\n\t<li>\n\tMade untitled tab saveable when created by closing all files.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3440244&group_id=2439\">Bug #3440244.</a>\n\t</li>\n\t<li>\n\tSciTE crash fixed when using Scintillua.\n\t</li>\n\t<li>\n\tSciTE revert command fixed so that undo works on individual actions instead of undoing to revert point.\n\t</li>\n\t<li>\n\tFocus loss in SciTE when opening a recent file fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3440142&group_id=2439\">Bug #3440142.</a>\n\t</li>\n\t<li>\n\tFixed SciTE SelLength property to measure characters instead of bytes.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3283519&group_id=2439\">Bug #3283519.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite301.zip?download\">Release 3.0.1</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 15 November 2011.\n\t</li>\n\t<li>\n\tSciTE on Windows now runs Lua scripts directly on the main thread instead of starting them on a\n\tsecondary thread and then moving back to the main thread.\n\t</li>\n\t<li>\n\tHighlight \"else\" as a keyword for TCL in the same way as other languages.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1836954&group_id=2439\">Bug #1836954.</a>\n\t</li>\n\t<li>\n\tFix problems with setting fonts for autocompletion lists on Windows where\n\tfont handles were copied and later deleted causing a system default font to be used.\n\t</li>\n\t<li>\n\tFix font size used on Windows for Asian language input methods which sometimes led to IME not being visible.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3436753&group_id=2439\">Bug #3436753.</a>\n\t</li>\n\t<li>\n\tFixed polygon drawing on Windows so fold symbols are visible again.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3433558&group_id=2439\">Bug #3433558.</a>\n\t</li>\n\t<li>\n\tChanged background drawing on GTK+ to allow for fractional character positioning as occurs on OS X\n\tas this avoids faint lines at lexeme boundaries.\n\t</li>\n\t<li>\n\tEnsure pixmaps allocated before painting as there was a crash when Scintilla drew without common initialization calls.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3432354&group_id=2439\">Bug #3432354.</a>\n\t</li>\n\t<li>\n\tFixed SciTE on Windows bug causing wrong caret position after indenting a selection.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3433433&group_id=2439\">Bug #3433433.</a>\n\t</li>\n\t<li>\n\tFixed SciTE session saving to store buffer position matching buffer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3434372&group_id=2439\">Bug #3434372.</a>\n\t</li>\n\t<li>\n\tFixed leak of document objects in SciTE.\n\t</li>\n\t<li>\n\tRecognize URL characters '?' and '%' for Open Selected command in SciTE.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3429409&group_id=2439\">Bug #3429409.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite300.zip?download\">Release 3.0.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 1 November 2011.\n\t</li>\n\t<li>\n\tCarbon platform support removed. OS X applications should switch to Cocoa.\n\t</li>\n\t<li>\n\tOn Windows Vista or newer, drawing may be performed with Direct2D and DirectWrite instead of GDI.\n\t</li>\n\t<li>\n\tCairo is now used for all drawing on GTK+. GDK drawing was removed.\n\t</li>\n\t<li>\n\tPaletted display support removed.\n\t</li>\n\t<li>\n\tFractional font sizes can be specified.\n\t</li>\n\t<li>\n\tDifferent weights of text supported on some platforms instead of just normal and bold.\n\t</li>\n\t<li>\n\tSub-pixel character positioning supported.\n\t</li>\n\t<li>\n\tSciTE loads files in the background without blocking the user interface.\n\t</li>\n\t<li>\n\tSciTE can display diagnostic messages interleaved with the text of files immediately after the\n\tline referred to by the diagnostic.\n\t</li>\n\t<li>\n\tNew API to see if all lines are visible which can be used to optimize processing fold structure notifications.\n\t</li>\n\t<li>\n\tScrolling optimized by avoiding invalidation of fold margin when redrawing whole window.\n\t</li>\n\t<li>\n\tOptimized SCI_MARKERNEXT.\n\t</li>\n\t<li>\n\tC++ lexer supports Pike hash quoted strings when turned on with lexer.cpp.hashquoted.strings.\n\t</li>\n\t<li>\n\tFixed incorrect line height with annotations in wrapped mode when there are multiple views.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3388159&group_id=2439\">Bug #3388159.</a>\n\t</li>\n\t<li>\n\tCalltips may be displayed above the text as well as below.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3410830&group_id=2439\">Bug #3410830.</a>\n\t</li>\n\t<li>\n\tFor huge files SciTE only examines the first megabyte for newline discovery.\n\t</li>\n\t<li>\n\tSciTE on GTK+ removes the fileselector.show.hidden property and check box as this was buggy and GTK+ now\n\tsupports an equivalent feature.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3413630&group_id=2439\">Bug #3413630.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ supports mnemonics in dynamic menus.\n\t</li>\n\t<li>\n\tSciTE on GTK+ displays the user's home directory as '~' in menus to make them shorter.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite229.zip?download\">Release 2.29</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 16 September 2011.\n\t</li>\n\t<li>\n\tTo automatically discover the encoding of a file when opening it, SciTE can run a program set with command.discover.properties.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3324341&group_id=2439\">Feature #3324341.</a>\n\t</li>\n\t<li>\n\tCairo always used for drawing on GTK+.\n\t</li>\n\t<li>\n\tThe set of properties files imported by SciTE can be controlled with the properties imports.include and imports.exclude.\n\tThe import statement has been extended to allow \"import *\".\n\tThe properties files for some languages are no longer automatically loaded by default. The properties files affected are\n\tavenue, baan, escript, lot, metapost, and mmixal.\n\t</li>\n\t<li>\n\tC++ lexer fixed a bug with raw strings being recognized too easily.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3388122&group_id=2439\">Bug #3388122.</a>\n\t</li>\n\t<li>\n\tLaTeX lexer improved with more states and fixes to most outstanding bugs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1493111&group_id=2439\">Bug #1493111.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1856356&group_id=2439\">Bug #1856356.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3081692&group_id=2439\">Bug #3081692.</a>\n\t</li>\n\t<li>\n\tLua lexer updates for Lua 5.2 beta with goto labels and \"\\z\" string escape.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3386330&group_id=2439\">Feature #3386330.</a>\n\t</li>\n\t<li>\n\tPerl string styling highlights interpolated variables.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3394258&group_id=2439\">Feature #3394258.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3076629&group_id=2439\">Bug #3076629.</a>\n\t</li>\n\t<li>\n\tPerl lexer updated for Perl 5.14.0 with 0X and 0B numeric literal prefixes, break keyword and \"+\" supported in subroutine prototypes.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3388802&group_id=2439\">Feature #3388802.</a>\n\t</li>\n\t<li>\n\tPerl bug fixed with CRLF line endings.\n\t</li>\n\t<li>\n\tMarkdown lexer fixed to not change state with \"_\" in middle of word.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3398184&group_id=2439\">Bug #3398184.</a>\n\t</li>\n\t<li>\n\tCocoa restores compatibility with OS X 10.5.\n\t</li>\n\t<li>\n\tMouse pointer changes over selection to an arrow near start when scrolled horizontally.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3389055&group_id=2439\">Bug #3389055.</a>\n\t</li>\n\t<li>\n\tIndicators that finish at the end of the document no longer expand when text is appended.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3378718&group_id=2439\">Bug #3378718.</a>\n\t</li>\n\t<li>\n\tSparseState merge fixed to check if other range is empty.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3387053&group_id=2439\">Bug #3387053.</a>\n\t</li>\n\t<li>\n\tOn Windows, autocompletion lists will scroll instead of document when mouse wheel spun.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3403600&group_id=2439\">Feature #3403600.</a>\n\t</li>\n\t<li>\n\tSciTE performs more rapid polling for command completion so will return faster and report more accurate times.\n\t</li>\n\t<li>\n\tSciTE resizes panes proportionally when switched between horizontal and vertical layout.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3376784&group_id=2439\">Feature #3376784.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ opens multiple files into a single instance more reliably.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3363754&group_id=2439\">Bug #3363754.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite228.zip?download\">Release 2.28</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 1 August 2011.\n\t</li>\n\t<li>\n\tGTK+ Cairo support works back to GTK+ version 2.8. Requires changing Scintilla source code to enable before GTK+ 2.22.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3322351&group_id=2439\">Bug #3322351.</a>\n\t</li>\n\t<li>\n\tTranslucent images in RGBA format can be used for margin markers and in autocompletion lists.\n\t</li>\n\t<li>\n\tINDIC_DOTBOX added as a translucent dotted rectangular indicator.\n\t</li>\n\t<li>\n\tAsian text input using IME works for GTK+ 3.x and GTK+ 2.x with Cairo.\n\t</li>\n\t<li>\n\tOn GTK+, IME works for Ctrl+Shift+U Unicode input in Scintilla. For SciTE, Ctrl+Shift+U is still Make Selection Uppercase.\n\t</li>\n\t<li>\n\tKey bindings for GTK+ on OS X made compatible with Cocoa port and platform conventions.\n\t</li>\n\t<li>\n\tCocoa port supports different character encodings, improves scrolling performance and drag image appearance.\n\tThe control ID is included in WM_COMMAND notifications. Text may be deleted by dragging to the trash.\n\tScrollToStart and ScrollToEnd key commands added to simplify implementation of standard OS X Home and End\n\tbehaviour.\n\t</li>\n\t<li>\n\tSciTE on GTK+ uses a paned widget to contain the edit and output panes instead of custom code.\n\tThis allows the divider to be moved easily on GTK+ 3 and its appearance follows GTK+ conventions more closely.\n\t</li>\n\t<li>\n\tSciTE builds and installs on BSD.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3324644&group_id=2439\">Bug #3324644.</a>\n\t</li>\n\t<li>\n\tCobol supports fixed format comments.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3014850&group_id=2439\">Bug #3014850.</a>\n\t</li>\n\t<li>\n\tMako template language block syntax extended and ## comments recognized.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3325178&group_id=2439\">Feature #3325178.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3318818&group_id=2439\">Bug #3318818.</a>\n\t</li>\n\t<li>\n\tFolding of Mako template language within HTML fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3324563&group_id=2439\">Bug #3324563.</a>\n\t</li>\n\t<li>\n\tPython lexer has lexer.python.keywords2.no.sub.identifiers option to avoid highlighting second set of\n\tkeywords following '.'.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3325333&group_id=2439\">Bug #3325333.</a>\n\t</li>\n\t<li>\n\tPython folder fixes bug where fold would not extend to final line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3349157&group_id=2439\">Bug #3349157.</a>\n\t</li>\n\t<li>\n\tSciTE treats LPEG lexers the same as script lexers by setting all 8 style bits.\n\t</li>\n\t<li>\n\tFor Cocoa, crashes with unsupported font variants and memory leaks for colour objects fixed.\n\t</li>\n\t<li>\n\tShift-JIS lead byte ranges modified to match Windows.\n\t</li>\n\t<li>\n\tMouse pointer changes over selection to an arrow more consistently.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3315756&group_id=2439\">Bug #3315756.</a>\n\t</li>\n\t<li>\n\tBug fixed with annotations beyond end of document.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3347268&group_id=2439\">Bug #3347268.</a>\n\t</li>\n\t<li>\n\tIncorrect drawing fixed for combination of background colour change and translucent selection.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3377116&group_id=2439\">Bug #3377116.</a>\n\t</li>\n\t<li>\n\tLexers initialized correctly when started at position other than start of line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3377148&group_id=2439\">Bug #3377148.</a>\n\t</li>\n\t<li>\n\tFold highlight drawing fixed for some situations.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3323015&group_id=2439\">Bug #3323015.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3323805&group_id=2439\">Bug #3323805.</a>\n\t</li>\n\t<li>\n\tCase insensitive search fixed for cases where folded character uses fewer bytes than base character.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3362038&group_id=2439\">Bug #3362038.</a>\n\t</li>\n\t<li>\n\tSciTE bookmark.alpha setting fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3373907&group_id=2439\">Bug #3373907.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite227.zip?download\">Release 2.27</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 20 June 2011.\n\t</li>\n\t<li>\n\tOn recent GTK+ 2.x versions when using Cairo, bug fixed where wrong colours were drawn.\n\t</li>\n\t<li>\n\tSciTE on GTK+ slow performance in menu maintenance fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3315233&group_id=2439\">Bug #3315233.</a>\n\t</li>\n\t<li>\n\tCocoa platform supports 64-bit builds and uses only non-deprecated APIs.\n\tAsian Input Method Editors are supported.\n\tAutocompletion lists and calltips implemented.\n\tControl identifier used in notifications.\n\t</li>\n\t<li>\n\tOn Cocoa, rectangular selection now uses Option/Alt key to be compatible with Apple Human\n\tInterface Guidelines and other applications.\n\tThe Control key is reported with an SCMOD_META modifier bit.\n\t</li>\n\t<li>\n\tAPI added for setting and retrieving the identifier number used in notifications.\n\t</li>\n\t<li>\n\tSCI_SETEMPTYSELECTION added to set selection without scrolling or redrawing more than needed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3314877&group_id=2439\">Feature #3314877.</a>\n\t</li>\n\t<li>\n\tAdded new indicators. INDIC_DASH and INDIC_DOTS are variants of underlines.\n\tINDIC_SQUIGGLELOW indicator added as shorter alternative to INDIC_SQUIGGLE for small fonts.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3314591&group_id=2439\">Bug #3314591</a>\n\t</li>\n\t<li>\n\tMargin line selection can be changed to select display lines instead of document lines.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3312763&group_id=2439\">Bug #3312763.</a>\n\t</li>\n\t<li>\n\tOn Windows, SciTE can perform reverse searches by pressing Shift+Enter\n\tin the Find or Replace strips or dialogs.\n\t</li>\n\t<li>\n\tMatlab lexer does not special case '\\' in single quoted strings.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=948757&group_id=2439\">Bug #948757</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1755950&group_id=2439\">Bug #1755950</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1888738&group_id=2439\">Bug #1888738</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3316852&group_id=2439\">Bug #3316852.</a>\n\t</li>\n\t<li>\n\tVerilog lexer supports SystemVerilog folding and keywords.\n\t</li>\n\t<li>\n\tFont leak fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3306156&group_id=2439\">Bug #3306156.</a>\n\t</li>\n\t<li>\n\tAutomatic scrolling works for long wrapped lines.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3312763&group_id=2439\">Bug #3312763.</a>\n\t</li>\n\t<li>\n\tMultiple typing works for cases where selections collapse together.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3309906&group_id=2439\">Bug #3309906.</a>\n\t</li>\n\t<li>\n\tFold expanded when needed in word wrap mode.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3291579&group_id=2439\">Bug #3291579.</a>\n\t</li>\n\t<li>\n\tBug fixed with edge drawn in wrong place on wrapped lines.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3314807&group_id=2439\">Bug #3314807.</a>\n\t</li>\n\t<li>\n\tBug fixed with unnecessary scrolling for SCI_GOTOLINE.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3303406&group_id=2439\">Bug #3303406.</a>\n\t</li>\n\t<li>\n\tBug fixed where extra step needed to undo SCI_CLEAR in virtual space.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3159691&group_id=2439\">Bug #3159691.</a>\n\t</li>\n\t<li>\n\tRegular expression search fixed for \\$ on last line of search range.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3313746&group_id=2439\">Bug #3313746.</a>\n\t</li>\n\t<li>\n\tSciTE performance improved when switching to a tab with a very large file.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3311421&group_id=2439\">Bug #3311421.</a>\n\t</li>\n\t<li>\n\tOn Windows, SciTE advanced search remembers the \"Search only in this style\" setting.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3313344&group_id=2439\">Bug #3313344.</a>\n\t</li>\n\t<li>\n\tOn GTK+, SciTE opens help using \"xdg-open\" instead of \"netscape\" as \"netscape\" no longer commonly installed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3314377&group_id=2439\">Bug #3314377.</a>\n\t</li>\n\t<li>\n\tSciTE script lexers can use 256 styles.\n\t</li>\n\t<li>\n\tSciTE word highlight works for words containing DBCS characters.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3315173&group_id=2439\">Bug #3315173.</a>\n\t</li>\n\t<li>\n\tCompilation fixed for wxWidgets.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3306156&group_id=2439\">Bug #3306156.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite226.zip?download\">Release 2.26</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 25 May 2011.\n\t</li>\n\t<li>\n\tFolding margin symbols can be highlighted for the current folding block.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3147069&group_id=2439\">Feature #3147069.</a>\n\t</li>\n\t<li>\n\tSelected lines can be moved up or down together.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3304850&group_id=2439\">Feature #3304850.</a>\n\t</li>\n\t<li>\n\tSciTE can highlight all occurrences of the current word or selected text.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3291636&group_id=2439\">Feature #3291636.</a>\n\t</li>\n\t<li>\n\tExperimental GTK+ 3.0 support: build with \"make GTK3=1\".\n\t</li>\n\t<li>\n\tINDIC_STRAIGHTBOX added. Is similar to INDIC_ROUNDBOX but without rounded corners.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3290435&group_id=2439\">Bug #3290435.</a>\n\t</li>\n\t<li>\n\tCan show brace matching and mismatching with indicators instead of text style.\n\tTranslucency of outline can be altered for INDIC_ROUNDBOX and INDIC_STRAIGHTBOX.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3290434&group_id=2439\">Feature #3290434.</a>\n\t</li>\n\t<li>\n\tSciTE can automatically indent python by examining previous line for scope-starting ':' with indent.python.colon.\n\t</li>\n\t<li>\n\tBatch file lexer allows braces '(' or ')' inside variable names.\n\t</li>\n\t<li>\n\tThe cpp lexer only recognizes Vala triple quoted strings when lexer.cpp.triplequoted.strings property is set.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3239234&group_id=2439\">Bug #3239234.</a>\n\t</li>\n\t<li>\n\tMake file lexer treats a variable with a nested variable like $(f$(qx)b) as one variable.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3298223&group_id=2439\">Bug #3298223.</a>\n\t</li>\n\t<li>\n\tFolding bug fixed for JavaScript with nested PHP.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3193530&group_id=2439\">Bug #3193530.</a>\n\t</li>\n\t<li>\n\tHTML lexer styles Django's {# #} comments.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3013798&group_id=2439\">Bug #3013798.</a>\n\t</li>\n\t<li>\n\tHTML lexer styles JavaScript regular expression correctly for /abc/i.test('abc');.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3209108&group_id=2439\">Bug #3209108.</a>\n\t</li>\n\t<li>\n\tInno Setup Script lexer now works properly when it restarts from middle of [CODE] section.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3283880&group_id=2439\">Bug #3283880.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3129044&group_id=2439\">Bug #3129044.</a>\n\t</li>\n\t<li>\n\tLua lexer updated for Lua 5.2 with hexadecimal floating-point numbers and '\\*' whitespace escaping in strings.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3243811&group_id=2439\">Feature #3243811.</a>\n\t</li>\n\t<li>\n\tPerl folding folds \"here doc\"s and adds options fold.perl.at.else and fold.perl.comment.explicit. Fold structure for Perl fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3112671&group_id=2439\">Feature #3112671.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3265401&group_id=2439\">Bug #3265401.</a>\n\t</li>\n\t<li>\n\tPython lexer supports cpdef keyword for Cython.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3279728&group_id=2439\">Bug #3279728.</a>\n\t</li>\n\t<li>\n\tSQL folding option lexer.sql.fold.at.else renamed to fold.sql.at.else.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3271474&group_id=2439\">Bug #3271474.</a>\n\t</li>\n\t<li>\n\tSQL lexer no longer treats ';' as terminating a comment.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3196071&group_id=2439\">Bug #3196071.</a>\n\t</li>\n\t<li>\n\tText drawing and measurement segmented into smaller runs to avoid platform bugs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3277449&group_id=2439\">Bug #3277449.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3165743&group_id=2439\">Bug #3165743.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows adds temp.files.sync.load property to open dropped temporary files synchronously as they may\n\tbe removed before they can be opened asynchronously.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3072009&group_id=2439\">Bug #3072009.</a>\n\t</li>\n\t<li>\n\tBug fixed with indentation guides ignoring first line in SC_IV_LOOKBOTH mode.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3291317&group_id=2439\">Bug #3291317.</a>\n\t</li>\n\t<li>\n\tBugs fixed in backward regex search.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3292659&group_id=2439\">Bug #3292659.</a>\n\t</li>\n\t<li>\n\tBugs with display of folding structure fixed for wrapped lines and where there is a fold header but no body.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3291579&group_id=2439\">Bug #3291579.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3265401&group_id=2439\">Bug #3265401.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows cursor changes to an arrow now when over horizontal splitter near top of window.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3286620&group_id=2439\">Bug #3286620.</a>\n\t</li>\n\t<li>\n\tFixed default widget size problem on GTK+.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3267892&group_id=2439\">Bug #3267892.</a>\n\t</li>\n\t<li>\n\tFixed font size when using Cairo on GTK+.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3272662&group_id=2439\">Bug #3272662.</a>\n\t</li>\n\t<li>\n\tFixed primary selection and cursor issues on GTK+ when unrealized then realized.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3256153&group_id=2439\">Bug #3256153.</a>\n\t</li>\n\t<li>\n\tRight click now cancels selection on GTK+ like on Windows.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3235190&group_id=2439\">Bug #3235190.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ implements z-order buffer switching like on Windows.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3228384&group_id=2439\">Bug #3228384.</a>\n\t</li>\n\t<li>\n\tImprove selection position after SciTE Insert Abbreviation command when abbreviation expansion includes '|'.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite225.zip?download\">Release 2.25</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 21 March 2011.\n\t</li>\n\t<li>\n\tSparseState class makes it easier to write lexers which have to remember complex state between lines.\n\t</li>\n\t<li>\n\tVisual Studio project (.dsp) files removed. The make files should be used instead as described in the README.\n\t</li>\n\t<li>\n\tModula 3 lexer added along with SciTE support.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3173374&group_id=2439\">Feature #3173374.</a>\n\t</li>\n\t<li>\n\tAsm, Basic, and D lexers add extra folding properties.\n\t</li>\n\t<li>\n\tRaw string literals for C++0x supported in C++ lexer.\n\t</li>\n\t<li>\n\tTriple-quoted strings used in Vala language supported in C++ lexer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3177601&group_id=2439\">Feature #3177601.</a>\n\t</li>\n\t<li>\n \tThe errorlist lexer used in SciTE's output pane colours lines that start with '&lt;' as diff deletions.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3172878&group_id=2439\">Feature #3172878.</a>\n\t</li>\n\t<li>\n \tThe Fortran lexer correctly folds type-bound procedures from Fortran 2003.\n\t</li>\n\t<li>\n\tLPeg lexer support‎ improved in SciTE.\n\t</li>\n\t<li>\n\tSciTE on Windows-64 fixes for menu localization and Lua scripts.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3204502&group_id=2439\">Bug #3204502.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows avoids locking folders when using the open or save dialogs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1795484&group_id=2439\">Bug #1795484.</a>\n\t</li>\n\t<li>\n\tDiff lexer fixes problem where diffs of diffs producing lines that start with \"----\".\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3197952&group_id=2439\">Bug #3197952.</a>\n\t</li>\n\t<li>\n\tBug fixed when searching upwards in Chinese code page 936.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3176271&group_id=2439\">Bug #3176271.</a>\n\t</li>\n\t<li>\n\tOn Cocoa, translucent drawing performed as on other platforms instead of 2.5 times less translucent.\n\t</li>\n\t<li>\n\tPerformance issue and potential bug fixed on GTK+ with caret line for long lines.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite224.zip?download\">Release 2.24</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 3 February 2011.\n\t</li>\n\t<li>\n\tFixed memory leak in GTK+ Cairo code.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3157655&group_id=2439\">Feature #3157655.</a>\n\t</li>\n\t<li>\n\tInsert Abbreviation dialog added to SciTE on GTK+.\n\t</li>\n\t<li>\n\tSCN_UPDATEUI notifications received when window scrolled. An 'updated' bit mask indicates which\n\ttypes of update have occurred from SC_UPDATE_SELECTION, SC_UPDATE_CONTENT, SC_UPDATE_H_SCROLL\n\tor SC_UPDATE_V_SCROLL.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3125977&group_id=2439\">Feature #3125977.</a>\n\t</li>\n\t<li>\n\tOn Windows, to ensure reverse arrow cursor matches platform default, it is now generated by\n\treflecting the platform arrow cursor.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3143968&group_id=2439\">Feature #3143968.</a>\n\t</li>\n\t<li>\n\tCan choose mouse cursor used in margins.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3161326&group_id=2439\">Feature #3161326.</a>\n\t</li>\n\t<li>\n\tOn GTK+, SciTE sets a mime type of text/plain in its .desktop file so that it will appear in the shell context menu.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3137126&group_id=2439\">Feature #3137126.</a>\n\t</li>\n\t<li>\n\tBash folder handles here docs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3118223&group_id=2439\">Feature #3118223.</a>\n\t</li>\n\t<li>\n\tC++ folder adds fold.cpp.syntax.based, fold.cpp.comment.multiline, fold.cpp.explicit.start, fold.cpp.explicit.end,\n\tand fold.cpp.explicit.anywhere properties to allow more control over folding and choice of explicit fold markers.\n\t</li>\n\t<li>\n\tC++ lexer fixed to always handle single quote strings continued past a line end.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3150522&group_id=2439\">Bug #3150522.</a>\n\t</li>\n\t<li>\n\tRuby folder handles here docs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3118224&group_id=2439\">Feature #3118224.</a>\n\t</li>\n\t<li>\n\tSQL lexer allows '.' to be part of words.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3103129&group_id=2439\">Feature #3103129.</a>\n\t</li>\n\t<li>\n\tSQL folder handles case statements in more situations.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3135027&group_id=2439\">Feature #3135027.</a>\n\t</li>\n\t<li>\n\tSQL folder adds fold points inside expressions based on bracket structure.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3165488&group_id=2439\">Feature #3165488.</a>\n\t</li>\n\t<li>\n\tSQL folder drops fold.sql.exists property as 'exists' is handled automatically.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3164194&group_id=2439\">Bug #3164194.</a>\n\t</li>\n\t<li>\n\tSciTE only forwards properties to lexers when they have been explicitly set so the defaults set by lexers are used\n\trather than 0.\n\t</li>\n\t<li>\n\tMouse double click word selection chooses the word around the character under the mouse rather than\n\tthe inter-character position under the mouse. This makes double clicking select what the user is pointing\n\tat and avoids selecting adjacent non-word characters.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3111174&group_id=2439\">Bug #3111174.</a>\n\t</li>\n\t<li>\n\tFixed mouse double click to always perform word select, not line select.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3143635&group_id=2439\">Bug #3143635.</a>\n\t</li>\n\t<li>\n\tRight click cancels autocompletion.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3144531&group_id=2439\">Bug #3144531.</a>\n\t</li>\n\t<li>\n\tFixed multiPaste to work when additionalSelectionTyping off.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3126221&group_id=2439\">Bug #3126221.</a>\n\t</li>\n\t<li>\n\tFixed virtual space problems when text modified at caret.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3154986&group_id=2439\">Bug #3154986.</a>\n\t</li>\n\t<li>\n\tFixed memory leak in lexer object code.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3133672&group_id=2439\">Bug #3133672.</a>\n\t</li>\n\t<li>\n\tFixed SciTE on GTK+ search failure when using regular expression.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3156217&group_id=2439\">Bug #3156217.</a>\n\t</li>\n\t<li>\n\tAvoid unnecessary full window redraw for SCI_GOTOPOS.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3146650&group_id=2439\">Feature #3146650.</a>\n\t</li>\n\t<li>\n\tAvoid unnecessary redraw when indicator fill range makes no real change.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite223.zip?download\">Release 2.23</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 7 December 2010.\n\t</li>\n\t<li>\n\tOn GTK+ version 2.22 and later, drawing is performed with Cairo rather than GDK.\n\tThis is in preparation for GTK+ 3.0 which will no longer support GDK drawing.\n\tThe appearance of some elements will be different with Cairo as it is anti-aliased and uses sub-pixel positioning.\n\tCairo may be turned on for GTK+ versions before 2.22 by defining USE_CAIRO although this has not\n\tbeen extensively tested.\n\t</li>\n\t<li>\n\tNew lexer a68k for Motorola 68000 assembler.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3101598&group_id=2439\">Feature #3101598.</a>\n\t</li>\n\t<li>\n\tBorland C++ is no longer supported for building Scintilla or SciTE on Windows.\n\t</li>\n\t<li>\n\tPerformance improved when creating large rectangular selections.\n\t</li>\n\t<li>\n\tPHP folder recognizes #region and #endregion comments.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3101624&group_id=2439\">Feature #3101624.</a>\n\t</li>\n\t<li>\n\tSQL lexer has a lexer.sql.numbersign.comment option to turn off use of '#' comments\n\tas these are a non-standard feature only available in some implementations.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3098071&group_id=2439\">Feature #3098071.</a>\n\t</li>\n\t<li>\n\tSQL folder recognizes case statements and understands the fold.at.else property.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3104091&group_id=2439\">Bug #3104091.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3107362&group_id=2439\">Bug #3107362.</a>\n\t</li>\n\t<li>\n\tSQL folder fixes bugs with end statements when fold.sql.only.begin=1.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3104091&group_id=2439\">Bug #3104091.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows bug fixed with multi-line tab bar not adjusting correctly when maximizing and demaximizing.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3097517&group_id=2439\">Bug #3097517.</a>\n\t</li>\n\t<li>\n\tCrash fixed on GTK+ when Scintilla widget destroyed while it still has an outstanding style idle pending.\n\t</li>\n\t<li>\n\tBug fixed where searching backwards in DBCS text (code page 936 or similar) failed to find occurrences at the start of the line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3103936&group_id=2439\">Bug #3103936.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows supports Unicode file names when executing help applications with winhelp and htmlhelp subsystems.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite222.zip?download\">Release 2.22</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 27 October 2010.\n\t</li>\n\t<li>\n\tSciTE includes support for integrating with Scintillua which allows lexers to be implemented in Lua as a\n\tParsing Expression Grammar (PEG).\n\t</li>\n\t<li>\n\tRegular expressions allow use of '?' for non-greedy matches or to match 0 or 1 instances of an item.\n\t</li>\n\t<li>\n\tSCI_CONTRACTEDFOLDNEXT added to allow rapid retrieval of folding state.\n\t</li>\n\t<li>\n\tSCN_HOTSPOTRELEASECLICK notification added which is similar to SCN_HOTSPOTCLICK but occurs\n\twhen the mouse is released.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3082409&group_id=2439\">Feature #3082409.</a>\n\t</li>\n\t<li>\n\tCommand added for centring current line in window.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3064696&group_id=2439\">Feature #3064696.</a>\n\t</li>\n\t<li>\n\tSciTE performance improved by not examining document for line ends when switching buffers and not\n\tstoring folds when folding turned off.\n\t</li>\n\t<li>\n\tBug fixed where scrolling to ensure the caret is visible did not take into account all pixels of the line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3081721&group_id=2439\">Bug #3081721.</a>\n\t</li>\n\t<li>\n\tBug fixed for autocompletion list overlapping text when WS_EX_CLIENTEDGE used.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3079778&group_id=2439\">Bug #3079778.</a>\n\t</li>\n\t<li>\n\tAfter autocompletion, the caret's X is updated.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3079114&group_id=2439\">Bug #3079114.</a>\n\t</li>\n\t<li>\n\tOn Windows, default to the system caret blink time.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3079784&group_id=2439\">Feature #3079784.</a>\n\t</li>\n\t<li>\n\tPgUp/PgDn fixed to allow virtual space.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3077452&group_id=2439\">Bug #3077452.</a>\n\t</li>\n\t<li>\n\tCrash fixed when AddMark and AddMarkSet called with negative argument.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3075074&group_id=2439\">Bug #3075074.</a>\n\t</li>\n\t<li>\n\tDwell notifications fixed so that they do not occur when the mouse is outside Scintilla.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3073481&group_id=2439\">Bug #3073481.</a>\n\t</li>\n\t<li>\n\tBash lexer bug fixed for here docs starting with &lt;&lt;-.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3063822&group_id=2439\">Bug #3063822.</a>\n\t</li>\n\t<li>\n\tC++ lexer bug fixed for // comments that are continued onto a second line by a \\.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3066031&group_id=2439\">Bug #3066031.</a>\n\t</li>\n\t<li>\n\tC++ lexer fixes wrong highlighting for float literals containing +/-.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3058924&group_id=2439\">Bug #3058924.</a>\n\t</li>\n\t<li>\n\tJavaScript lexer recognize regexes following return keyword.‎\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3062287&group_id=2439\">Bug #3062287.</a>\n\t</li>\n\t<li>\n\tRuby lexer handles % quoting better and treats range dots as operators in 1..2 and 1...2.\n\tRuby folder handles \"if\" keyword used as a modifier even when it is separated from the modified statement by an escaped new line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2093767&group_id=2439\">Bug #2093767.</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3058496&group_id=2439\">Bug #3058496.</a>\n\t</li>\n\t<li>\n\tBug fixed where upwards search failed with DBCS code pages.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3065912&group_id=2439\">Bug #3065912.</a>\n\t</li>\n\t<li>\n\tSciTE has a default Lua startup script name distributed in SciTEGlobal.properties.\n\tNo error message is displayed if this file does not exist.\n\t</li>\n\t<li>\n\tSciTE on Windows tab control height is calculated better.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2635702&group_id=2439\">Bug #2635702.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows uses better themed check buttons in find and replace strips.\n\t</li>\n\t<li>\n\tSciTE on Windows fixes bug with Find strip appearing along with Incremental Find strip.\n\t</li>\n\t<li>\n\tSciTE setting find.close.on.find added to allow preventing the Find dialog from closing.\n\t</li>\n\t<li>\n\tSciTE on Windows attempts to rerun commands that fail by prepending them with \"cmd.exe /c\".\n\tThis allows commands built in to the command processor like \"dir\" to run.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite221.zip?download\">Release 2.21</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 1 September 2010.\n\t</li>\n\t<li>\n\tAsian Double Byte Character Set (DBCS) support improved.\n\tCase insensitive search works and other operations are much faster.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2999125&group_id=2439\">Bug #2999125,</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2774616&group_id=2439\">Bug #2774616,</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2991942&group_id=2439\">Bug #2991942,</a>\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3005688&group_id=2439\">Bug #3005688.</a>\n\t</li>\n\t<li>\n\tScintilla on GTK+ uses only non-deprecated APIs (for GTK+ 2.20) except for GdkFont and GdkFont use can be disabled\n\twith the preprocessor symbol DISABLE_GDK_FONT.\n\t</li>\n\t<li>\n\tIDocument interface used by lexers adds BufferPointer and GetLineIndentation methods.\n\t</li>\n\t<li>\n\tOn Windows, clicking sets focus before processing the click or sending notifications.\n\t</li>\n\t<li>\n\tBug on OS X (macosx platform) fixed where drag/drop overwrote clipboard.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3039732&group_id=2439\">Bug #3039732.</a>\n\t</li>\n\t<li>\n\tGTK+ drawing bug when the view was horizontally scrolled more than 32000 pixels fixed.\n\t</li>\n\t<li>\n\tSciTE bug fixed with invoking Complete Symbol from output pane.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3050957&group_id=2439\">Bug #3050957.</a>\n\t</li>\n\t<li>\n\tBug fixed where it was not possible to disable folding.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3040649&group_id=2439\">Bug #3040649.</a>\n\t</li>\n\t<li>\n\tBug fixed with pressing Enter on a folded fold header line not opening the fold.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3043419&group_id=2439\">Bug #3043419.</a>\n\t</li>\n\t<li>\n\tSciTE 'Match case' option in find and replace user interfaces changed to 'Case sensitive' to allow use of 'v'\n\trather than 'c' as the mnemonic.\n\t</li>\n\t<li>\n\tSciTE displays stack trace for Lua when error occurs..\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3051397&group_id=2439\">Bug #3051397.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows fixes bug where double clicking on error message left focus in output pane.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1264835&group_id=2439\">Bug #1264835.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows uses SetDllDirectory to avoid a security problem.\n\t</li>\n\t<li>\n\tC++ lexer crash fixed with preprocessor expression that looked like division by 0.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3056825&group_id=2439\">Bug #3056825.</a>\n\t</li>\n\t<li>\n\tHaskell lexer improved.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3039490&group_id=2439\">Feature #3039490.</a>\n\t</li>\n\t<li>\n\tHTML lexing fixed around Django {% %} tags.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3034853&group_id=2439\">Bug #3034853.</a>\n\t</li>\n\t<li>\n\tHTML JavaScript lexing fixed when line end escaped.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3038381&group_id=2439\">Bug #3038381.</a>\n\t</li>\n\t<li>\n\tHTML lexer stores line state produced by a line on that line rather than on the next line.\n\t</li>\n\t<li>\n\tMarkdown lexer fixes infinite loop.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3045386&group_id=2439\">Bug #3045386.</a>\n\t</li>\n\t<li>\n\tMySQL folding bugs with END statements fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3031742&group_id=2439\">Bug #3031742.</a>\n\t</li>\n\t<li>\n\tPowerShell lexer allows '_' as a word character.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3042228&group_id=2439\">Feature #3042228.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ abandons processing of subsequent commands if a command.go.needs command fails.\n\t</li>\n\t<li>\n\tWhen SciTE is closed, all buffers now receive an OnClose call.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3033857&group_id=2439\">Bug #3033857.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite220.zip?download\">Release 2.20</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 30 July 2010.\n\t</li>\n\t<li>\n\tLexers are implemented as objects so that they may retain extra state.\n\tThe interfaces defined for this are tentative and may change before the next release.\n\tCompatibility classes allow current lexers compiled into Scintilla to run with few changes.\n\tThe interface to external lexers has changed and existing external lexers will need to have changes\n\tmade and be recompiled.\n\tA single lexer object is attached to a document whereas previously lexers were attached to views\n\twhich could lead to different lexers being used for split views with confusing results.\n\t</li>\n\t<li>\n\tC++ lexer understands the preprocessor enough to grey-out inactive code due to conditional compilation.\n\t</li>\n\t<li>\n\tSciTE can use strips within the main window for find and replace rather than dialogs.\n\tOn Windows SciTE always uses a strip for incremental search.\n\t</li>\n\t<li>\n\tLexer added for Txt2Tags language.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3018736&group_id=2439\">Feature #3018736.</a>\n\t</li>\n\t<li>\n\tSticky caret feature enhanced with additional SC_CARETSTICKY_WHITESPACE mode .\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3027559&group_id=2439\">Feature #3027559.</a>\n\t</li>\n\t<li>\n\tBash lexer implements basic parsing of compound commands and constructs.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3033135&group_id=2439\">Feature #3033135.</a>\n\t</li>\n\t<li>\n\tC++ folder allows disabling explicit fold comments.\n\t</li>\n\t<li>\n\tPerl folder works for array blocks, adjacent package statements, nested PODs, and terminates package folding at __DATA__, ^D and ^Z.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3030887&group_id=2439\">Feature #3030887.</a>\n\t</li>\n\t<li>\n\tPowerShell lexer supports multiline &lt;# .. #&gt; comments and adds 2 keyword classes.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3015176&group_id=2439\">Feature #3015176.</a>\n\t</li>\n\t<li>\n\tLexing performed incrementally when needed by wrapping to make user interface more responsive.\n\t</li>\n\t<li>\n\tSciTE setting replaceselection:yes works on GTK+.\n\t</li>\n\t<li>\n\tSciTE Lua scripts calling io.open or io.popen on Windows have arguments treated as UTF-8 and converted to Unicode\n\tso that non-ASCII file paths will work. Lua files with non-ASCII paths run.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3016951&group_id=2439\">Bug #3016951.</a>\n\t</li>\n\t<li>\n\tCrash fixed when searching for empty string.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3017572&group_id=2439\">Bug #3017572.</a>\n\t</li>\n\t<li>\n\tBugs fixed with folding and lexing when Enter pressed at start of line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3032652&group_id=2439\">Bug #3032652.</a>\n\t</li>\n\t<li>\n\tBug fixed with line selection mode not affecting selection range.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3021480&group_id=2439\">Bug #3021480.</a>\n\t</li>\n\t<li>\n\tBug fixed where indicator alpha was limited to 100 rather than 255.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3021473&group_id=2439\">Bug #3021473.</a>\n\t</li>\n\t<li>\n\tBug fixed where changing annotation did not cause automatic redraw.\n\t</li>\n\t<li>\n\tRegular expression bug fixed when a character range included non-ASCII characters.\n\t</li>\n\t<li>\n\tCompilation failure with recent compilers fixed on GTK+.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3022027&group_id=2439\">Bug #3022027.</a>\n\t</li>\n\t<li>\n\tBug fixed on Windows with multiple monitors where autocomplete pop up would appear off-screen\n\tor straddling monitors.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3017512&group_id=2439\">Bug #3017512.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows bug fixed where changing directory to a Unicode path failed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3011987&group_id=2439\">Bug #3011987.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows bug fixed where combo boxes were not allowing Unicode characters.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3012986&group_id=2439\">Bug #3012986.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ bug fixed when dragging files into SciTE on KDE.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3026555&group_id=2439\">Bug #3026555.</a>\n\t</li>\n\t<li>\n\tSciTE bug fixed where closing untitled file could lose data if attempt to name file same as another buffer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3011680&group_id=2439\">Bug #3011680.</a>\n\t</li>\n\t<li>\n\tCOBOL number masks now correctly highlighted.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3012164&group_id=2439\">Bug #3012164.</a>\n\t</li>\n\t<li>\n\tPHP comments can include &lt;?PHP without triggering state change.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2854183&group_id=2439\">Bug #2854183.</a>\n\t</li>\n\t<li>\n\tVHDL lexer styles unclosed string correctly.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3029627&group_id=2439\">Bug #3029627.</a>\n\t</li>\n\t<li>\n\tMemory leak fixed in list boxes on GTK+.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3007669&group_id=2439\">Bug #3007669.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite212.zip?download\">Release 2.12</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 1 June 2010.\n\t</li>\n\t<li>\n\tDrawing optimizations improve speed and fix some visible flashing when scrolling.\n\t</li>\n\t<li>\n\tCopy Path command added to File menu in SciTE.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2986745&group_id=2439\">Feature #2986745.</a>\n\t</li>\n\t<li>\n\tOptional warning displayed by SciTE when saving a file which has been modified by another process.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2975041&group_id=2439\">Feature #2975041.</a>\n\t</li>\n\t<li>\n\tFlagship lexer for xBase languages updated to follow the language much more closely.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2992689&group_id=2439\">Feature #2992689.</a>\n\t</li>\n\t<li>\n\tHTML lexer highlights Django templates in more regions.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3002874&group_id=2439\">Feature #3002874.</a>\n\t</li>\n\t<li>\n\tDropping files on SciTE on Windows, releases the drag object earlier and opens the files asynchronously,\n\tleading to smoother user experience.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2986724&group_id=2439\">Feature #2986724.</a>\n\t</li>\n\t<li>\n\tSciTE HTML exports take the Use Monospaced Font setting into account.\n\t</li>\n\t<li>\n\tSciTE window title \"[n of m]\" localized.\n\t</li>\n\t<li>\n\tWhen new line inserted at start of line, markers are moved down.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2986727&group_id=2439\">Bug #2986727.</a>\n\t</li>\n\t<li>\n\tOn Windows, dropped text has its line ends converted, similar to pasting.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3005328&group_id=2439\">Bug #3005328.</a>\n\t</li>\n\t<li>\n\tFixed bug with middle-click paste in block select mode where text was pasted next to selection rather than at cursor.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2984460&group_id=2439\">Bug #2984460.</a>\n\t</li>\n\t<li>\n\tFixed SciTE crash where a style had a size parameter without a value.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3003834&group_id=2439\">Bug #3003834.</a>\n\t</li>\n\t<li>\n\tDebug assertions in multiple lexers fixed.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3000566&group_id=2439\">Bug #3000566.</a>\n\t</li>\n\t<li>\n\tCSS lexer fixed bug where @font-face displayed incorrectly\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2994224&group_id=2439\">Bug #2994224.</a>\n\t</li>\n\t<li>\n\tCSS lexer fixed bug where open comment caused highlighting error.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1683672&group_id=2439\">Bug #1683672.</a>\n\t</li>\n\t<li>\n\tShell file lexer fixed highlight glitch with here docs where the first line is a comment.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2830239&group_id=2439\">Bug #2830239.</a>\n\t</li>\n\t<li>\n\tBug fixed in SciTE openpath property that caused Open Selected File to fail to open the selected file.\n\t</li>\n\t<li>\n\tBug fixed in SciTE FileExt property when file name with no extension evaluated to whole path.\n\t</li>\n\t<li>\n\tFixed SciTE on Windows printing bug where the $(CurrentTime), $(CurrentPage) variables were not expanded.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2994612&group_id=2439\">Bug #2994612.</a>\n\t</li>\n\t<li>\n\tSciTE compiles for 64-bit Windows and runs without crashing.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2986312&group_id=2439\">Bug #2986312.</a>\n\t</li>\n\t<li>\n\tFull Screen mode in Windows Vista/7 improved to hide Start button and size borders a little better.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3002813&group_id=2439\">Bug #3002813.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite211.zip?download\">Release 2.11</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 9 April 2010.\n\t</li>\n\t<li>\n\tFixes compatibility of Scintilla.h with the C language.\n\t</li>\n\t<li>\n\tWith a rectangular selection SCI_GETSELECTIONSTART and SCI_GETSELECTIONEND return limits of the\n\trectangular selection rather than the limits of the main selection.\n\t</li>\n\t<li>\n\tWhen SciTE on Windows is minimized to tray, only takes a single click to restore rather than a double click.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=981917&group_id=2439\">Feature #981917.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite210.zip?download\">Release 2.10</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 4 April 2010.\n\t</li>\n\t<li>\n\tVersion 1.x of GTK+ is no longer supported.\n\t</li>\n\t<li>\n\tSciTE is no longer supported on Windows 95, 98 or ME.\n\t</li>\n\t<li>\n\tCase-insensitive search works for non-ASCII characters in UTF-8 and 8-bit encodings.\n\tNon-regex search in DBCS encodings is always case-sensitive.\n\t</li>\n\t<li>\n\tNon-ASCII characters may be changed to upper and lower case.\n\t</li>\n\t<li>\n\tSciTE on Windows can access all files including those with names outside the user's preferred character encoding.\n\t</li>\n\t<li>\n\tSciTE may be extended with lexers written in Lua.\n\t</li>\n\t<li>\n\tWhen there are multiple selections, the paste command can go either to the main selection or to each\n\tselection. This is controlled with SCI_SETMULTIPASTE.\n\t</li>\n\t<li>\n\tMore forms of bad UTF-8 are detected including overlong sequences, surrogates, and characters outside\n\tthe valid range. Bad UTF-8 bytes are now displayed as 2 hex digits preceded by 'x'.\n\t</li>\n\t<li>\n\tSCI_GETTAG retrieves the value of captured expressions within regular expression searches.\n\t</li>\n\t<li>\n\tDjango template highlighting added to the HTML lexer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2974889&group_id=2439\">Feature #2974889.</a>\n\t</li>\n\t<li>\n\tVerilog line comments can be folded.\n\t</li>\n\t<li>\n\tSciTE on Windows allows specifying a filter for the Save As dialog.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2943445&group_id=2439\">Feature #2943445.</a>\n\t</li>\n\t<li>\n\tBug fixed when multiple selection disabled where rectangular selections could be expanded into multiple selections.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2948260&group_id=2439\">Bug #2948260.</a>\n\t</li>\n\t<li>\n\tBug fixed when document horizontally scrolled and up/down-arrow did not return to the same\n\tcolumn after horizontal scroll occurred.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2950799&group_id=2439\">Bug #2950799.</a>\n\t</li>\n\t<li>\n\tBug fixed to remove hotspot highlight when mouse is moved out of the document. Windows only fix.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&aid=2951353&group_id=2439&atid=102439\">Bug #2951353.</a>\n\t</li>\n\t<li>\n\tR lexer now performs case-sensitive check for keywords.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2956543&group_id=2439\">Bug #2956543.</a>\n\t</li>\n\t<li>\n\tBug fixed on GTK+ where text disappeared when a wrap occurred.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2958043&group_id=2439\">Bug #2958043.</a>\n\t</li>\n\t<li>\n\tBug fixed where regular expression replace cannot escape the '\\' character by using '\\\\'.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2959876&group_id=2439\">Bug #2959876.</a>\n\t</li>\n\t<li>\n\tBug fixed on GTK+ when virtual space disabled, middle-click could still paste text beyond end of line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2971618&group_id=2439\">Bug #2971618.</a>\n\t</li>\n\t<li>\n\tSciTE crash fixed when double clicking on a malformed error message in the output pane.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2976551&group_id=2439\">Bug #2976551.</a>\n\t</li>\n\t<li>\n\tImproved performance on GTK+ when changing parameters associated with scroll bars to the same value.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2964357&group_id=2439\">Bug #2964357.</a>\n\t</li>\n\t<li>\n\tFixed bug with pressing Shift+Tab with a rectangular selection so that it performs an un-indent\n\tsimilar to how Tab performs an indent.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite203.zip?download\">Release 2.03</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased 14 February 2010.\n\t</li>\n\t<li>\n\tAdded SCI_SETFIRSTVISIBLELINE to match SCI_GETFIRSTVISIBLELINE.\n\t</li>\n\t<li>\n\tErlang lexer extended set of numeric bases recognized; separate style for module:function_name; detects\n\tbuilt-in functions, known module attributes, and known preprocessor instructions; recognizes EDoc and EDoc macros;\n\tseparates types of comments.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2942448&group_id=2439\">Bug #2942448.</a>\n\t</li>\n\t<li>\n\tPython lexer extended with lexer.python.strings.over.newline option that allows non-triple-quoted strings to extend\n\tpast line ends. This allows use of the Ren'Py language.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2945550&group_id=2439\">Feature #2945550.</a>\n\t</li>\n\t<li>\n\tFixed bugs with cursor movement after deleting a rectangular selection.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2942131&group_id=2439\">Bug #2942131.</a>\n\t</li>\n\t<li>\n\tFixed bug where calling SCI_SETSEL when there is a rectangular selection left\n\tthe additional selections selected.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2947064&group_id=2439\">Bug #2947064.</a>\n\t</li>\n\t<li>\n\tFixed macro recording bug where not all bytes in multi-byte character insertions were reported through\n\tSCI_REPLACESEL.\n\t</li>\n\t<li>\n\tFixed SciTE bug where using Ctrl+Enter followed by Ctrl+Space produced an autocompletion list\n\twith only a single line containing all the identifiers.\n\t</li>\n\t<li>\n\tFixed SciTE on GTK+ bug where running a tool made the user interface completely unresponsive.\n\t</li>\n\t<li>\n\tFixed SciTE on Windows Copy to RTF bug.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2108574&group_id=2439\">Bug #2108574.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite202.zip?download\">Release 2.02</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 25 January 2010.\n\t</li>\n\t<li>\n\tMarkdown lexer added.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2844081&group_id=2439\">Feature #2844081.</a>\n\t</li>\n\t<li>\n\tOn GTK+, include code that understands the ranges of lead bytes for code pages 932, 936, and 950\n\tso that most Chinese and Japanese text can be used on systems that are not set to the corresponding locale.\n\t</li>\n\t<li>\n\tAllow changing the size of dots in visible whitespace using SCI_SETWHITESPACESIZE.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2839427&group_id=2439\">Feature #2839427.</a>\n\t</li>\n\t<li>\n\tAdditional carets can be hidden with SCI_SETADDITIONALCARETSVISIBLE.\n\t</li>\n\t<li>\n\tCan choose anti-aliased, non-anti-aliased or lcd-optimized text using SCI_SETFONTQUALITY.\n\t</li>\n\t<li>\n\tRetrieve the current selected text in the autocompletion list with SCI_AUTOCGETCURRENTTEXT.\n\t</li>\n\t<li>\n\tRetrieve the name of the current lexer with SCI_GETLEXERLANGUAGE.\n\t</li>\n\t<li>\n\tProgress 4GL lexer improves handling of comments in preprocessor declaration.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2902206&group_id=2439\">Feature #2902206.</a>\n\t</li>\n\t<li>\n\tHTML lexer extended to handle Mako template language.\n\t</li>\n\t<li>\n\tSQL folder extended for SQL Anywhere \"EXISTS\" and \"ENDIF\" keywords.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2887524&group_id=2439\">Feature #2887524.</a>\n\t</li>\n\t<li>\n\tSciTE adds APIPath and AbbrevPath variables.\n\t</li>\n\t<li>\n\tSciTE on GTK+ uses pipes instead of temporary files for running tools. This should be more secure.\n\t</li>\n\t<li>\n\tFixed crash when calling SCI_STYLEGETFONT for a style which does not have a font set.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2857425&group_id=2439\">Bug #2857425.</a>\n\t</li>\n\t<li>\n\tFixed crash caused by not having sufficient styles allocated after choosing a lexer.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2881279&group_id=2439\">Bug #2881279.</a>\n\t</li>\n\t<li>\n\tFixed crash in SciTE using autocomplete word when word characters includes space.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2840141&group_id=2439\">Bug #2840141.</a>\n\t</li>\n\t<li>\n\tFixed bug with handling upper-case file extensions SciTE on GTK+.\n\t</li>\n\t<li>\n\tFixed SciTE loading files from sessions with folded folds where it would not\n\tbe scrolled to the correct location.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2882775&group_id=2439\">Bug #2882775.</a>\n\t</li>\n\t<li>\n\tFixed SciTE loading files from sessions when file no longer exists.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2883437&group_id=2439\">Bug #2883437.</a>\n\t</li>\n\t<li>\n\tFixed SciTE export to HTML using the wrong background colour.\n\t</li>\n\t<li>\n\tFixed crash when adding an annotation and then adding a new line after the annotation.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2929708&group_id=2439\">Bug #2929708.</a>\n\t</li>\n\t<li>\n\tFixed crash in SciTE setting a property to nil from Lua.\n\t</li>\n\t<li>\n\tSCI_GETSELTEXT fixed to return correct length.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2929441&group_id=2439\">Bug #2929441.</a>\n\t</li>\n\t<li>\n\tFixed text positioning problems with selection in some circumstances.\n\t</li>\n\t<li>\n\tFixed text positioning problems with ligatures on GTK+.\n\t</li>\n\t<li>\n\tFixed problem pasting into rectangular selection with caret at bottom caused text to go from the caret down\n\trather than replacing the selection.\n\t</li>\n\t<li>\n\tFixed problem replacing in a rectangular selection where only the final line was changed.\n\t</li>\n\t<li>\n\tFixed inability to select a rectangular area using Alt+Shift+Click at both corners.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2899746&group_id=2439\">Bug #2899746.</a>\n\t</li>\n\t<li>\n\tFixed problem moving to start/end of a rectangular selection with left/right key.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2871358&group_id=2439\">Bug #2871358.</a>\n\t</li>\n\t<li>\n\tFixed problem with Select All when there's a rectangular selection.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2930488&group_id=2439\">Bug #2930488.</a>\n\t</li>\n\t<li>\n\tFixed SCI_LINEDUPLICATE on a rectangular selection to not produce multiple discontinuous selections.\n\t</li>\n\t<li>\n\tVirtual space removed when performing delete word left or delete line left.\n\tVirtual space converted to real space for delete word right.\n\tPreserve virtual space when pressing Delete key.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2882566&group_id=2439\">Bug #2882566.</a>\n\t</li>\n\t<li>\n\tFixed problem where Shift+Alt+Down did not move through wrapped lines.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2871749&group_id=2439\">Bug #2871749.</a>\n\t</li>\n\t<li>\n\tFixed incorrect background colour when using coloured lines with virtual space.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2914691&group_id=2439\">Bug #2914691.</a>\n\t</li>\n\t<li>\n\tFixed failure to display wrap symbol for SC_WRAPVISUALFLAGLOC_END_BY_TEXT.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2936108&group_id=2439\">Bug #2936108.</a>\n\t</li>\n\t<li>\n\tFixed blank background colour with EOLFilled style on last line.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2890105&group_id=2439\">Bug #2890105.</a>\n\t</li>\n\t<li>\n\tFixed problem in VB lexer with keyword at end of file.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2901239&group_id=2439\">Bug #2901239.</a>\n\t</li>\n\t<li>\n\tFixed SciTE bug where double clicking on a tab closed the file.\n\t</li>\n\t<li>\n\tFixed SciTE brace matching commands to only work when the caret is next to the brace, not when\n\tit is in virtual space.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2885560&group_id=2439\">Bug #2885560.</a>\n\t</li>\n\t<li>\n\tFixed SciTE on Windows Vista to access files in the Program Files directory rather than allow Windows\n\tto virtualize access.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2916685&group_id=2439\">Bug #2916685.</a>\n\t</li>\n\t<li>\n\tFixed NSIS folder to handle keywords that start with '!'.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2872157&group_id=2439\">Bug #2872157.</a>\n\t</li>\n\t<li>\n\tChanged linkage of Scintilla_LinkLexers to \"C\" so that it can be used by clients written in C.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2844718&group_id=2439\">Bug #2844718.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite201.zip?download\">Release 2.01</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 19 August 2009.\n\t</li>\n\t<li>\n\tFix to positioning rectangular paste when viewing line ends.\n\t</li>\n\t<li>\n\tDon't insert new lines and indentation for line ends at end of rectangular paste.\n\t</li>\n\t<li>\n\tWhen not in additional selection typing mode, cutting a rectangular selection removes all of the selected text.\n\t</li>\n\t<li>\n\tRectangular selections are copied to the clipboard in document order, not in the order of selection.\n\t</li>\n\t<li>\n\tSCI_SETCURRENTPOS and SCI_SETANCHOR work in rectangular mode.\n\t</li>\n\t<li>\n\tOn GTK+, drag and drop to a later position in the document now drops at the position.\n\t</li>\n\t<li>\n\tFix bug where missing property did not use default value.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite200.zip?download\">Release 2.0</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 11 August 2009.\n\t</li>\n\t<li>\n\tMultiple pieces of text can be selected simultaneously by holding control while dragging the mouse.\n\tTyping, backspace and delete may affect all selections together.\n\t</li>\n\t<li>\n\tVirtual space allows selecting beyond the last character on a line.\n\t</li>\n\t<li>\n\tSciTE on GTK+ path bar is now optional and defaults to off.\n\t</li>\n\t<li>\n\tMagikSF lexer recognizes numbers correctly.\n\t</li>\n\t<li>\n\tFolding of Python comments and blank lines improved. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=210240&group_id=2439\">Bug #210240.</a>\n\t</li>\n\t<li>\n\tBug fixed where background colour of last character in document leaked past that character.\n\t</li>\n\t<li>\n\tCrash fixed when adding marker beyond last line in document. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2830307&group_id=2439\">Bug #2830307.</a>\n\t</li>\n\t<li>\n\tResource leak fixed in SciTE for Windows when printing fails. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2816524&group_id=2439\">Bug #2816524.</a>\n\t</li>\n\t<li>\n\tBug fixed on Windows where the system caret was destroyed during destruction when another window\n\twas using the system caret. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2830223&group_id=2439\">Bug #2830223.</a>\n\t</li>\n\t<li>\n\tBug fixed where indentation guides were drawn over text when the indentation used a style with a different\n\tspace width to the default style.\n\t</li>\n\t<li>\n\tSciTE bug fixed where box comment added a bare line feed rather than the chosen line end. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2818104&group_id=2439\">Bug #2818104.</a>\n\t</li>\n\t<li>\n\tReverted fix that led to wrapping whole document when displaying the first line of the document.\n\t</li>\n\t<li>\n\tExport to LaTeX in SciTE fixed to work in more cases and not use as much space. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1286548&group_id=2439\">Bug #1286548.</a>\n\t</li>\n\t<li>\n\tBug fixed where EN_CHANGE notification was sent when performing a paste operation in a\n\tread-only document. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2825485&group_id=2439\">Bug #2825485.</a>\n\t</li>\n\t<li>\n\tRefactored code so that Scintilla exposes less of its internal implementation and uses the C++ standard\n\tlibrary for some basic collections. Projects that linked to Scintilla's SString or PropSet classes\n\tshould copy this code from a previous version of Scintilla or from SciTE.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite179.zip?download\">Release 1.79</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 1 July 2009.\n\t</li>\n\t<li>\n\tMemory exhaustion and other exceptions handled by placing an error value into the\n\tstatus property rather than crashing.\n\tScintilla now builds with exception handling enabled and requires exception handling to be enabled. <br />\n\tThis is a major change and application developers should consider how they will deal with Scintilla exhausting\n\tmemory since Scintilla may not be in a stable state.\n\t</li>\n\t<li>\n\tDeprecated APIs removed. The symbols removed are:\n\t<ul>\n <li>SCI_SETCARETPOLICY</li>\n<li> CARET_CENTER</li>\n<li> CARET_XEVEN</li>\n<li> CARET_XJUMPS</li>\n<li> SC_FOLDFLAG_BOX</li>\n<li> SC_FOLDLEVELBOXHEADERFLAG</li>\n<li> SC_FOLDLEVELBOXFOOTERFLAG</li>\n<li> SC_FOLDLEVELCONTRACTED</li>\n<li> SC_FOLDLEVELUNINDENT</li>\n<li> SCN_POSCHANGED</li>\n<li> SCN_CHECKBRACE</li>\n<li> SCLEX_ASP</li>\n<li> SCLEX_PHP</li>\n</ul>\n\t</li>\n\t<li>\n\tCocoa platform added.\n\t</li>\n\t<li>\n\tNames of struct types in Scintilla.h now start with \"Sci_\" to avoid possible clashes with platform\n\tdefinitions. Currently, the old names still work but these will be phased out.\n\t</li>\n\t<li>\n\tWhen lines are wrapped, subsequent lines may be indented to match the indent of the initial line,\n\tor one more indentation level. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2796119&group_id=2439\">Feature #2796119.</a>\n\t</li>\n\t<li>\n\tAPIs added for finding the character at a point rather than an inter-character position. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2646738&group_id=2439\">Feature #2646738.</a>\n\t</li>\n\t<li>\n\tA new marker SC_MARK_BACKGROUND_UNDERLINE is drawn in the text area as an underline\n\tthe full width of the window.\n\t</li>\n\t<li>\n\tBatch file lexer understands variables surrounded by '!'.\n\t</li>\n\t<li>\n\tCAML lexer also supports SML.\n\t</li>\n\t<li>\n\tD lexer handles string and numeric literals more accurately. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2793782&group_id=2439\">Feature #2793782.</a>\n\t</li>\n\t<li>\n\tForth lexer is now case-insensitive and better supports numbers like $hex and %binary. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2804894&group_id=2439\">Feature #2804894.</a>\n\t</li>\n\t<li>\n\tLisp lexer treats '[', ']', '{', and '}' as balanced delimiters which is common usage. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2794989&group_id=2439\">Feature #2794989.</a>\n\t<br />\n\tIt treats keyword argument names as being equivalent to symbols. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2794901&group_id=2439\">Feature #2794901.</a>\n\t</li>\n\t<li>\n\tPascal lexer bug fixed to prevent hang when 'interface' near beginning of file. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2802863&group_id=2439\">Bug #2802863.</a>\n\t</li>\n\t<li>\n\tPerl lexer bug fixed where previous lexical states persisted causing \"/\" special case styling and\n\tsubroutine prototype styling to not be correct. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2809168&group_id=2439\">Bug #2809168.</a>\n\t</li>\n\t<li>\n\tXML lexer fixes bug where Unicode entities like '&amp;—' were broken into fragments. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2804760&group_id=2439\">Bug #2804760.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ enables scrolling the tab bar on recent versions of GTK+. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2061821&group_id=2439\">Feature #2061821.</a>\n\t</li>\n\t<li>\n\tSciTE on Windows allows tab bar tabs to be reordered by drag and drop.\n\t</li>\n\t<li>\n\tUnit test script for Scintilla on Windows included with source code.\n\t</li>\n\t<li>\n\tUser defined menu items are now localized when there is a matching translation.\n\t</li>\n\t<li>\n\tWidth of icon column of autocompletion lists on GTK+ made more consistent.\n\t</li>\n\t<li>\n\tBug with slicing UTF-8 text into character fragments when there is a sequence of 100 or more 3 byte characters. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2780566&group_id=2439\">Bug #2780566.</a>\n\t</li>\n\t<li>\n\tFolding bugs introduced in 1.78 fixed. Some of the fix was generic and there was also a specific fix for C++.\n\t</li>\n\t<li>\n\tBug fixed where a rectangular paste was not padding the line with sufficient spaces to align the pasted text.\n\t</li>\n\t<li>\n\tBug fixed with showing all text on each line of multi-line annotations when styling the whole annotation using SCI_ANNOTATIONSETSTYLE. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2789430&group_id=2439\">Bug #2789430.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite178.zip?download\">Release 1.78</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 28 April 2009.\n\t</li>\n\t<li>\n\tAnnotation lines may be added to each line.\n\t</li>\n\t<li>\n\tA text margin may be defined with different text on each line.\n\t</li>\n\t<li>\n\tApplication actions may be added to the undo history.\n\t</li>\n\t<li>\n\tCan query the symbol defined for a marker.\n\tAn available symbol added for applications to indicate that plugins may allocate a marker.\n\t</li>\n\t<li>\n\tCan increase the amount of font ascent and descent.\n\t</li>\n\t<li>\n\tCOBOL lexer added. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2127406&group_id=2439\">Feature #2127406.</a>\n\t</li>\n\t<li>\n\tNimrod lexer added. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2642620&group_id=2439\">Feature #2642620.</a>\n\t</li>\n\t<li>\n\tPowerPro lexer added. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2195308&group_id=2439\">Feature #2195308.</a>\n\t</li>\n\t<li>\n\tSML lexer added. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2710950&group_id=2439\">Feature #2710950.</a>\n\t</li>\n\t<li>\n\tSORCUS Installation file lexer added. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2343375&group_id=2439\">Feature #2343375.</a>\n\t</li>\n\t<li>\n\tTACL lexer added. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2127406&group_id=2439\">Feature #2127406.</a>\n\t</li>\n\t<li>\n\tTAL lexer added. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2127406&group_id=2439\">Feature #2127406.</a>\n\t</li>\n\t<li>\n\tRewritten Pascal lexer with improved folding and other fixes. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2190650&group_id=2439\">Feature #2190650.</a>\n\t</li>\n\t<li>\n\tINDIC_ROUNDBOX translucency level can be modified. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2586290&group_id=2439\">Feature #2586290.</a>\n\t</li>\n\t<li>\n\tC++ lexer treats angle brackets in #include directives as quotes when styling.within.preprocessor. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2551033&group_id=2439\">Bug #2551033.</a>\n\t</li>\n\t<li>\n\tInno Setup lexer is sensitive to whether within the [Code] section and handles comments better. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2552973&group_id=2439\">Bug #2552973.</a>\n\t</li>\n\t<li>\n\tHTML lexer does not go into script mode when script tag is self-closing.\n\t</li>\n\t<li>\n\tHTML folder fixed where confused by comments when fold.html.preprocessor off. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2532774&group_id=2439\">Bug #2532774.</a>\n\t</li>\n\t<li>\n\tPerl lexer fixes problem with string matching caused by line endings. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2648342&group_id=2439\">Bug #2648342.</a>\n\t</li>\n\t<li>\n\tProgress lexer fixes problem with \"last-event:function\" phrase. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2483619&group_id=2439\">Bug #2483619.</a>\n\t</li>\n\t<li>\n\tProperties file lexer extended to handle RFC2822 text when lexer.props.allow.initial.spaces on.\n\t</li>\n\t<li>\n\tPython lexer adds options for Python 3 and Cython.\n\t</li>\n\t<li>\n\tShell lexer fixes heredoc problem caused by line endings. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2635257&group_id=2439\">Bug #2635257.</a>\n\t</li>\n\t<li>\n\tTeX lexer handles comment at end of line correctly. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2698766&group_id=2439\">Bug #2698766.</a>\n\t</li>\n\t<li>\n\tSciTE retains selection range when performing a replace selection command. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2339160&group_id=2439\">Feature #2339160.</a>\n\t</li>\n\t<li>\n\tSciTE definition of word characters fixed to match documentation. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2464531&group_id=2439\">Bug #2464531.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ performing Search or Replace when dialog already shown now brings dialog to foreground.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2634224&group_id=2439\">Bug #2634224.</a>\n\t</li>\n\t<li>\n\tFixed encoding bug with calltips on GTK+.\n\t</li>\n\t<li>\n\tBlock caret drawn in correct place on wrapped lines. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2126144&group_id=2439\">Bug #2126144.</a>\n\t</li>\n\t<li>\n\tCompilation for 64 bit Windows works using MinGW. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2515578&group_id=2439\">Bug #2515578.</a>\n\t</li>\n\t<li>\n\tIncorrect memory freeing fixed on OS X.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2354098&group_id=2439\">Bug #2354098</a>,\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2671749&group_id=2439\">Bug #2671749.</a>\n\t</li>\n\t<li>\n\tSciTE on GTK+ crash fixed on startup when child process exits before initialization complete.\n\t<a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2716987&group_id=2439\">Bug #2716987.</a>\n\t</li>\n\t<li>\n\tCrash fixed when AutoCompleteGetCurrent called with no active autocompletion.\n\t</li>\n\t<li>\n\tFlickering diminished when pressing Tab. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2723006&group_id=2439\">Bug #2723006.</a>\n\t</li>\n\t<li>\n\tNamespace compilation issues with GTK+ on OS X fixed.\n\t</li>\n\t<li>\n\tIncreased maximum length of SciTE's Language menu on GTK+ to 100 items. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2528241&group_id=2439\">Bug #2528241.</a>\n\t</li>\n\t<li>\n\tFixed incorrect Python lexing for multi-line continued strings. <a href=\"https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2450963&group_id=2439\">Bug #2450963.</a>\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite177.zip?download\">Release 1.77</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 18 October 2008.\n\t</li>\n\t<li>\n\tDirect temporary access to Scintilla's text buffer to allow simple efficient interfacing\n\tto libraries like regular expression libraries.\n\t</li>\n\t<li>\n\tScintilla on Windows can interpret keys as Unicode even when a narrow character\n\twindow with SCI_SETKEYSUNICODE.\n\t</li>\n\t<li>\n\tNotification sent when autocompletion cancelled.\n\t</li>\n\t<li>\n\tMySQL lexer added.\n\t</li>\n\t<li>\n\tLexer for gettext .po files added.\n\t</li>\n\t<li>\n\tAbaqus lexer handles program structure more correctly.\n\t</li>\n\t<li>\n\tAssembler lexer works with non-ASCII text.\n\t</li>\n\t<li>\n\tC++ lexer allows mixed case doc comment tags.\n\t</li>\n\t<li>\n\tCSS lexer updated and works with non-ASCII.\n\t</li>\n\t<li>\n\tDiff lexer adds style for changed lines, handles subversion diffs better and\n\tfixes styling and folding for lines containing chunk dividers (\"---\").\n\t</li>\n\t<li>\n\tFORTRAN lexer accepts more styles of compiler directive.\n\t</li>\n\t<li>\n\tHaskell lexer allows hexadecimal literals.\n\t</li>\n\t<li>\n\tHTML lexer improves PHP and JavaScript folding.\n\tPHP heredocs, nowdocs, strings and comments processed more accurately.\n\tInternet Explorer's non-standard &gt;comment&lt; tag supported.\n\tScript recognition in XML can be controlled with lexer.xml.allow.scripts property.\n\t</li>\n\t<li>\n\tLua lexer styles last character correctly.\n\t</li>\n\t<li>\n\tPerl lexer update.\n\t</li>\n\t<li>\n\tComment folding implemented for Ruby.\n\t</li>\n\t<li>\n\tBetter TeX folding.\n\t</li>\n\t<li>\n\tVerilog lexer updated.\n\t</li>\n\t<li>\n\tWindows Batch file lexer handles %~ and %*.\n\t</li>\n\t<li>\n\tYAML lexer allows non-ASCII text.\n\t</li>\n\t<li>\n\tSciTE on GTK+ implements \"Replace in Buffers\" in advanced mode.\n\t</li>\n\t<li>\n\tThe extender OnBeforeSave method can override the default file saving behaviour by retuning true.\n\t</li>\n\t<li>\n\tWindow position and recent files list may be saved into the session file.\n\t</li>\n\t<li>\n\tRight button press outside the selection moves the caret.\n\t</li>\n\t<li>\n\tSciTE load.on.activate works when closing a document reveals a changed document.\n\t</li>\n\t<li>\n\tSciTE bug fixed where eol.mode not used for initial buffer.\n\t</li>\n\t<li>\n\tSciTE bug fixed where a file could be saved as the same name as another\n\tbuffer leading to confusing behaviour.\n\t</li>\n\t<li>\n\tFixed display bug for long lines in same style on Windows.\n\t</li>\n\t<li>\n\tFixed SciTE crash when finding matching preprocessor command used on some files.\n\t</li>\n\t<li>\n\tDrawing performance improved for files with many blank lines.\n\t</li>\n\t<li>\n\tFolding bugs fixed where changing program text produced a decrease in fold level on a fold header line.\n\t</li>\n\t<li>\n\tClearing document style now clears all indicators.\n\t</li>\n\t<li>\n\tSciTE's embedded Lua updated to 5.1.4.\n\t</li>\n\t<li>\n\tSciTE will compile with versions of GTK+ before 2.8 again.\n\t</li>\n\t<li>\n\tSciTE on GTK+ bug fixed where multiple files not opened.\n\t</li>\n\t<li>\n\tBug fixed with SCI_VCHOMEWRAP and SCI_VCHOMEWRAPEXTEND on white last line.\n\t</li>\n\t<li>\n\tRegular expression bug fixed where \"^[^(]+$\" matched empty lines.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite176.zip?download\">Release 1.76</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 16 March 2008.\n\t</li>\n\t<li>\n\tSupport for PowerShell.\n\t</li>\n\t<li>\n\tLexer added for Magik.\n\t</li>\n\t<li>\n\tDirector extension working on GTK+.\n\t</li>\n\t<li>\n\tDirector extension may set focus to SciTE through \"focus:\" message on GTK+.\n\t</li>\n\t<li>\n\tC++ folder handles final line better in some cases.\n\t</li>\n\t<li>\n\tSCI_COPYALLOWLINE added which is similar to SCI_COPY except that if the selection is empty then\n\tthe line holding the caret is copied. On Windows an extra clipboard format allows pasting this as a whole\n\tline before the current selection. This behaviour is compatible with Visual Studio.\n\t</li>\n\t<li>\n\tOn Windows, the horizontal scroll bar can handle wider files.\n\t</li>\n\t<li>\n\tOn Windows, a system palette leak was fixed. Should not affect many as palette mode is rarely used.\n\t</li>\n\t<li>\n\tInstall command on GTK+ no longer tries to set explicit owner.\n\t</li>\n\t<li>\n\tPerl lexer handles defined-or operator \"//\".\n\t</li>\n\t<li>\n\tOctave lexer fixes \"!=\" operator.\n\t</li>\n\t<li>\n\tOptimized selection change drawing to not redraw as much when not needed.\n\t</li>\n\t<li>\n\tSciTE on GTK+ no longer echoes Lua commands so is same as on Windows.\n\t</li>\n\t<li>\n\tAutomatic vertical scrolling limited to one line at a time so is not too fast.\n\t</li>\n\t<li>\n\tCrash fixed when line states set beyond end of line states. This occurred when lexers did not\n\tset a line state for each line.\n\t</li>\n\t<li>\n\tCrash in SciTE on Windows fixed when search for 513 character string fails.\n\t</li>\n\t<li>\n\tSciTE disables translucent features on Windows 9x due to crashes reported when using translucency.\n\t</li>\n\t<li>\n\tBug fixed where whitespace background was not seen on wrapped lines.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite175.zip?download\">Release 1.75</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 22 November 2007.\n\t</li>\n\t<li>\n\tSome WordList and PropSet functionality moved from Scintilla to SciTE.\n\tProjects that link to Scintilla's code for these classes may need to copy\n\tcode from SciTE.\n\t</li>\n\t<li>\n\tBorland C++ can no longer build Scintilla.\n\t</li>\n\t<li>\n\tInvalid bytes in UTF-8 mode are displayed as hex blobs. This also prevents crashes due to\n\tpassing invalid UTF-8 to platform calls.\n\t</li>\n\t<li>\n\tIndentation guides enhanced to be visible on completely empty lines when possible.\n\t</li>\n\t<li>\n\tThe horizontal scroll bar may grow to match the widest line displayed.\n\t</li>\n\t<li>\n\tAllow autocomplete pop ups to appear outside client rectangle in some cases.\n\t</li>\n\t<li>\n\tWhen line state changed, SC_MOD_CHANGELINESTATE modification notification sent and\n\tmargin redrawn.\n\t</li>\n\t<li>\n\tSciTE scripts can access the menu command values IDM_*.\n\t</li>\n\t<li>\n\tSciTE's statement.end property has been implemented again.\n\t</li>\n\t<li>\n\tSciTE shows paths and matches in different styles for Find In Files.\n\t</li>\n\t<li>\n\tIncremental search in SciTE for Windows is modeless to make it easier to exit.\n\t</li>\n\t<li>\n\tFolding performance improved.\n\t</li>\n\t<li>\n\tSciTE for GTK+ now includes a Browse button in the Find In Files dialog.\n\t</li>\n\t<li>\n\tOn Windows versions that support Unicode well, Scintilla is a wide character window\n\twhich allows input for some less common languages like Armenian, Devanagari,\n\tTamil, and Georgian. To fully benefit, applications should use wide character calls.\n\t</li>\n\t<li>\n\tLua function names are exported from SciTE to allow some extension libraries to work.\n\t</li>\n\t<li>\n\tLexers added for Abaqus, Ansys APDL, Asymptote, and R.\n\t</li>\n\t<li>\n\tSCI_DELWORDRIGHTEND added for closer compatibility with GTK+ entry widget.\n\t</li>\n\t<li>\n\tThe styling buffer may now use all 8 bits in each byte for lexical states with 0 bits for indicators.\n\t</li>\n\t<li>\n\tMultiple characters may be set for SciTE's calltip.&lt;lexer&gt;.parameters.start property.\n\t</li>\n\t<li>\n\tBash lexer handles octal literals.\n\t</li>\n\t<li>\n\tC++/JavaScript lexer recognizes regex literals in more situations.\n\t</li>\n\t<li>\n\tHaskell lexer fixed for quoted strings.\n\t</li>\n\t<li>\n\tHTML/XML lexer does not notice XML indicator if there is\n\tnon-whitespace between the \"&lt;?\" and \"XML\".\n\tASP problem fixed where &lt;/ is used inside a comment.\n\t</li>\n\t<li>\n\tError messages from Lua 5.1 are recognized.\n\t</li>\n\t<li>\n\tFolding implemented for Metapost.\n\t</li>\n\t<li>\n\tPerl lexer enhanced for handling minus-prefixed barewords,\n\tunderscores in numeric literals and vector/version strings,\n\t^D and ^Z similar to __END__,\n\tsubroutine prototypes as a new lexical class,\n\tformats and format blocks as new lexical classes, and\n\t'/' suffixed keywords and barewords.\n\t</li>\n\t<li>\n\tPython lexer styles all of a decorator in the decorator style rather than just the name.\n\t</li>\n\t<li>\n\tYAML lexer styles colons as operators.\n\t</li>\n\t<li>\n\tFixed SciTE bug where undo would group together multiple separate modifications.\n\t</li>\n\t<li>\n\tBug fixed where setting background colour of calltip failed.\n\t</li>\n\t<li>\n\tSciTE allows wildcard suffixes for file pattern based properties.\n\t</li>\n\t<li>\n\tSciTE on GTK+ bug fixed where user not prompted to save untitled buffer.\n\t</li>\n\t<li>\n\tSciTE bug fixed where property values from one file were not seen by lower priority files.\n\t</li>\n\t<li>\n\tBug fixed when showing selection with a foreground colour change which highlighted\n\tan incorrect range in some positions.\n\t</li>\n\t<li>\n\tCut now invokes SCN_MODIFYATTEMPTRO notification.\n\t</li>\n\t<li>\n\tBug fixed where caret not shown at beginning of wrapped lines.\n\tCaret made visible in some cases after wrapping and scroll bar updated after wrapping.\n\t</li>\n\t<li>\n\tModern indicators now work on wrapped lines.\n\t</li>\n\t<li>\n\tSome crashes fixed for 64-bit GTK+.\n\t</li>\n\t<li>\n\tOn GTK+ clipboard features improved for VMWare tools copy and paste.\n\tSciTE exports the clipboard more consistently on shut down.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite174.zip?download\">Release 1.74</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 18 June 2007.\n\t</li>\n\t<li>\n\tOS X support.\n\t</li>\n\t<li>\n\tIndicators changed to be a separate data structure allowing more indicators. Storing indicators in high bits\n\tof styling bytes is deprecated and will be removed in the next version.\n\t</li>\n\t<li>\n\tUnicode support extended to all Unicode characters not just the Basic Multilingual Plane.\n\t</li>\n\t<li>\n\tPerformance improved on wide lines by breaking long runs in a single style into shorter segments.\n\t</li>\n\t<li>\n\tPerformance improved by caching layout of short text segments.\n\t</li>\n\t<li>\n\tSciTE includes Lua 5.1.\n\t</li>\n\t<li>\n\tCaret may be displayed as a block.\n\t</li>\n\t<li>\n\tLexer added for GAP.\n\t</li>\n\t<li>\n\tLexer added for PL/M.\n\t</li>\n\t<li>\n\tLexer added for Progress.\n\t</li>\n\t<li>\n\tSciTE session files have changed format to be like other SciTE .properties files\n\tand now use the extension .session.\n\tBookmarks and folds may optionally be saved in session files.\n\tSession files created with previous versions of SciTE will not load into this version.\n\t</li>\n\t<li>\n\tSciTE's extension and scripting interfaces add OnKey, OnDwellStart, and OnClose methods.\n\t</li>\n\t<li>\n\tOn GTK+, copying to the clipboard does not include the text/urilist type since this caused problems when\n\tpasting into Open Office.\n\t</li>\n\t<li>\n\tOn GTK+, Scintilla defaults caret blink rate to platform preference.\n\t</li>\n\t<li>\n\tDragging does not start until the mouse has been dragged a certain amount.\n\tThis stops spurious drags when just clicking inside the selection.\n\t</li>\n\t<li>\n\tBug fixed where brace highlight not shown when caret line background set.\n\t</li>\n\t<li>\n\tBug fixed in Ruby lexer where out of bounds access could occur.\n\t</li>\n\t<li>\n\tBug fixed in XML folding where tags were not being folded because they are singletons in HTML.\n\t</li>\n\t<li>\n\tBug fixed when many font names used.\n\t</li>\n\t<li>\n\tLayout bug fixed on GTK+ where fonts have ligatures available.\n\t</li>\n\t<li>\n\tBug fixed with SCI_LINETRANSPOSE on a blank line.\n\t</li>\n\t<li>\n\tSciTE hang fixed when using UNC path with directory properties feature.\n\t</li>\n\t<li>\n\tBug on Windows fixed by examining dropped text for Unicode even in non-Unicode mode so it\n\tcan work when source only provides Unicode or when using an encoding different from the\n\tsystem default.\n\t</li>\n\t<li>\n\tSciTE bug on GTK+ fixed where Stop Executing did not work when more than a single process started.\n\t</li>\n\t<li>\n\tSciTE bug on GTK+ fixed where mouse wheel was not switching between buffers.\n\t</li>\n\t<li>\n\tMinor line end fix to PostScript lexer.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite173.zip?download\">Release 1.73</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 31 March 2007.\n\t</li>\n\t<li>\n\tSciTE adds a Directory properties file to configure behaviour for files in a directory and its subdirectories.\n\t</li>\n\t<li>\n\tStyle changes may be made during text modification events.\n\t</li>\n\t<li>\n\tRegular expressions recognize \\d, \\D, \\s, \\S, \\w, \\W, and \\xHH.\n\t</li>\n\t<li>\n\tSupport for cmake language added.\n\t</li>\n\t<li>\n\tMore Scintilla properties can be queried.\n\t</li>\n\t<li>\n\tEdge line drawn under text.\n\t</li>\n\t<li>\n\tA savesession command added to SciTE director interface.\n\t</li>\n\t<li>\n\tSciTE File | Encoding menu item names changed to be less confusing.\n\t</li>\n\t<li>\n\tSciTE on GTK+ dialog buttons reordered to follow guidelines.\n\t</li>\n\t<li>\n\tSciTE on GTK+ removed GTK+ 1.x compatible file dialog code.\n\t</li>\n\t<li>\n\tSciTE on GTK+ recognizes key names KeypadMultiply and KeypadDivide.\n\t</li>\n\t<li>\n\tBackground colour of line wrapping visual flag changed to STYLE_DEFAULT.\n\t</li>\n\t<li>\n\tMakefile lexing enhanced for ':=' operator and when lines start with tab.\n\t</li>\n\t<li>\n\tTADS3 lexer and folder improved.\n\t</li>\n\t<li>\n\tSCN_DOUBLECLICK notification may set SCI_SHIFT, SCI_CTRL, and SCI_ALT flags on modifiers field.\n\t</li>\n\t<li>\n\tSlow folding of large constructs in Python fixed.\n\t</li>\n\t<li>\n\tMSSQL folding fixed to be case-insensitive and fold at more keywords.\n\t</li>\n\t<li>\n\tSciTE's brace matching works better for HTML.\n\t</li>\n\t<li>\n\tDetermining API list items checks for specified parameters start character before default '('.\n\t</li>\n\t<li>\n\tHang fixed in HTML lexer.\n\t</li>\n\t<li>\n\tBug fixed in with LineTranspose command where markers could move to different line.\n\t</li>\n\t<li>\n\tMemory released when buffer completely emptied.\n\t</li>\n\t<li>\n\tIf translucency not available on Windows, draw rectangular outline instead.\n\t</li>\n\t<li>\n\tBash lexer handles \"-x\" in \"--x-includes...\" better.\n\t</li>\n\t<li>\n\tAutoIt3 lexer fixes string followed by '+'.\n\t</li>\n\t<li>\n\tLinesJoin fixed where it stopped early due to not adjusting for inserted spaces..\n\t</li>\n\t<li>\n\tStutteredPageDown fixed when lines wrapped.\n\t</li>\n\t<li>\n\tFormatRange fixed to not double count line number width which could lead to a large space.\n\t</li>\n\t<li>\n\tSciTE Export As PDF and Latex commands fixed to format floating point numbers with '.' even in locales\n\tthat use ','.\n\t</li>\n\t<li>\n\tSciTE bug fixed where File | New could produce buffer with contents of previous file when using read-only mode.\n\t</li>\n\t<li>\n\tSciTE retains current scroll position when switching buffers and fold.on.open set.\n\t</li>\n\t<li>\n\tSciTE crash fixed where '*' used to invoke parameters dialog.\n\t</li>\n\t<li>\n\tSciTE bugs when writing large UCS-2 files fixed.\n\t</li>\n\t<li>\n\tBug fixed when scrolling inside a SCN_PAINTED event by invalidating window\n\trather than trying to perform synchronous painting.\n\t</li>\n\t<li>\n\tSciTE for GTK+ View | Full Screen works on recent versions of GTK+.\n\t</li>\n\t<li>\n\tSciTE for Windows enables and disables toolbar commands correctly.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite172.zip?download\">Release 1.72</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 15 January 2007.\n\t</li>\n\t<li>\n\tPerformance of per-line data improved.\n\t</li>\n\t<li>\n\tSC_STARTACTION flag set on the first modification notification in an undo\n\ttransaction to help synchronize the container's undo stack with Scintilla's.\n\t</li>\n\t<li>\n\tOn GTK+ drag and drop defaults to move rather than copy.\n\t</li>\n\t<li>\n\tScintilla supports extending appearance of selection to right hand margin.\n\t</li>\n\t<li>\n\tIncremental search available on GTK+.\n\t</li>\n\t<li>\n\tSciTE Indentation Settings dialog available on GTK+ and adds a \"Convert\" button.\n\t</li>\n\t<li>\n\tFind in Files can optionally ignore binary files or directories that start with \".\".\n\t</li>\n\t<li>\n\tLexer added for \"D\" language.\n\t</li>\n\t<li>\n\tExport as HTML shows folding with underline lines and +/- symbols.\n\t</li>\n\t<li>\n\tRuby lexer interprets interpolated strings as expressions.\n\t</li>\n\t<li>\n\tLua lexer fixes some cases of numeric literals.\n\t</li>\n\t<li>\n\tC++ folder fixes bug with \"@\" in doc comments.\n\t</li>\n\t<li>\n\tNSIS folder handles !if and related commands.\n\t</li>\n\t<li>\n\tInno setup lexer adds styling for single and double quoted strings.\n\t</li>\n\t<li>\n\tMatlab lexer handles backslashes in string literals correctly.\n\t</li>\n\t<li>\n\tHTML lexer fixed to allow \"?&gt;\" in comments in Basic script.\n\t</li>\n\t<li>\n\tAdded key codes for Windows key and Menu key.\n\t</li>\n\t<li>\n\tLua script method scite.MenuCommand(x) performs a menu command.\n\t</li>\n\t<li>\n\tSciTE bug fixed with box comment command near start of file setting selection to end of file.\n\t</li>\n\t<li>\n\tSciTE on GTK+, fixed loop that occurred with automatic loading for an unreadable file.\n\t</li>\n\t<li>\n\tSciTE asks whether to save files when Windows shuts down.\n\t</li>\n\t<li>\n\tSave Session on Windows now defaults the extension to \"ses\".\n\t</li>\n\t<li>\n\tBug fixed with single character keywords.\n\t</li>\n\t<li>\n\tFixed infinite loop for SCI_GETCOLUMN for position beyond end of document.\n\t</li>\n\t<li>\n\tFixed failure to accept typing on Solaris/GTK+ when using default ISO-8859-1 encoding.\n\t</li>\n\t<li>\n\tFixed warning from Lua in SciTE when creating a new buffer when already have\n\tmaximum number of buffers open.\n\t</li>\n\t<li>\n\tCrash fixed with \"%%\" at end of batch file.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite171.zip?download\">Release 1.71</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 21 August 2006.\n\t</li>\n\t<!--li>\n\tOn GTK+ drag and drop defaults to move rather than copy.\n\t</li-->\n\t<li>\n\tDouble click notification includes line and position.\n\t</li>\n\t<li>\n\tVB lexer bugs fixed for preprocessor directive below a comment or some other states and\n\tto use string not closed style back to the starting quote when there are internal doubled quotes.\n\t</li>\n\t<li>\n\tC++ lexer allows identifiers to contain '$' and non-ASCII characters such as UTF-8.\n\tThe '$' character can be disallowed with lexer.cpp.allow.dollars=0.\n\t</li>\n\t<li>\n\tPerl lexer allows UTF-8 identifiers and has some other small improvements.\n\t</li>\n\t<li>\n\tSciTE's $(CurrentWord) uses word.characters.&lt;filepattern&gt; to define the word\n\trather than a hardcoded list of word characters.\n\t</li>\n\t<li>\n\tSciTE Export as HTML adds encoding information for UTF-8 file and fixes DOCTYPE.\n\t</li>\n\t<li>\n\tSciTE session and .recent files default to the user properties directory rather than global\n\tproperties directory.\n\t</li>\n\t<li>\n\tLeft and right scroll events handled correctly on GTK+ and horizontal scroll bar has more sensible\n\tdistances for page and arrow clicks.\n\t</li>\n\t<li>\n\tSciTE on GTK+ tab bar fixed to work on recent versions of GTK+.\n\t</li>\n\t<li>\n\tOn GTK+, if the approximate character set conversion is unavailable, a second attempt is made\n\twithout approximations. This may allow keyboard input and paste to work on older systems.\n\t</li>\n\t<li>\n\tSciTE on GTK+ can redefine the Insert key.\n\t</li>\n\t<li>\n\tSciTE scripting interface bug fixed where some string properties could not be changed.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite170.zip?download\">Release 1.70</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 20 June 2006.\n\t</li>\n\t<li>\n\tOn GTK+, character set conversion is performed using an option that allows approximate conversions rather\n\tthan failures when a character can not be converted. This may lead to similar characters being inserted or\n\twhen no similar character is available a '?' may be inserted.\n\t</li>\n\t<li>\n\tOn GTK+, the internationalized IM (Input Method) feature is used for all typed input for all character sets.\n\t</li>\n\t<li>\n\tScintilla has new margin types SC_MARGIN_BACK and SC_MARGIN_FORE that use the default\n\tstyle's background and foreground colours (normally white and black) as the background to the margin.\n\t</li>\n\t<li>\n\tScintilla/GTK+ allows file drops on Windows when drop is of type DROPFILES_DND\n\tas well as text/uri-list.\n\t</li>\n\t<li>\n\tCode page can only be set to one of the listed valid values.\n\t</li>\n\t<li>\n\tText wrapping fixed for cases where insertion was not wide enough to trigger\n\twrapping before being styled but was after styling.\n\t</li>\n\t<li>\n\tSciTE find marks are removed before printing or exporting to avoid producing incorrect styles.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite169.zip?download\">Release 1.69</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 29 May 2006.\n\t</li>\n\t<li>\n\tSciTE supports z-order based buffer switching on Ctrl+Tab.\n\t</li>\n\t<li>\n\tTranslucent support for selection and whole line markers.\n\t</li>\n\t<li>\n\tSciTE may have per-language abbreviations files.\n\t</li>\n\t<li>\n\tSupport for Spice language.\n\t</li>\n\t<li>\n\tOn GTK+ autocompletion lists are optimized and use correct selection colours.\n\t</li>\n\t<li>\n\tOn GTK+ the URI data type is preferred in drag and drop so that applications\n\twill see files dragged from the shell rather than dragging the text of the file name\n\tinto the document.\n\t</li>\n\t<li>\n\tIncreased number of margins to 5.\n\t</li>\n\t<li>\n\tBasic lexer allows include directive $include: \"file name\".\n\t</li>\n\t<li>\n\tSQL lexer no longer bases folding on indentation.\n\t</li>\n\t<li>\n\tLine ends are transformed when copied to clipboard on\n\tWindows/GTK+2 as well as Windows/GTK+ 1.\n\t</li>\n\t<li>\n\tLexing code masks off the indicator bits on the start style before calling the lexer\n\tto avoid confusing the lexer when an application has used an indicator.\n\t</li>\n\t<li>\n\tSciTE savebefore:yes only saves the file when it has been changed.\n\t</li>\n\t<li>\n\tSciTE adds output.initial.hide setting to allow setting the size of the output pane\n\twithout it showing initially.\n\t</li>\n\t<li>\n\tSciTE on Windows Go To dialog allows line number with more digits.\n\t</li>\n\t<li>\n\tBug in HTML lexer fixed where a segment of PHP could switch scripting language\n\tbased on earlier text on that line.\n\t</li>\n\t<li>\n\tMemory bug fixed when freeing regions on GTK+.\n\tOther minor bugs fixed on GTK+.\n\t</li>\n\t<li>\n\tDeprecated GTK+ calls in Scintilla replaced with current calls.\n\t</li>\n\t<li>\n\tFixed a SciTE bug where closing the final buffer, if read-only, left the text present in an\n\tuntitled buffer.\n\t</li>\n\t<li>\n\tBug fixed in bash lexer that prevented folding.\n\t</li>\n\t<li>\n\tCrash fixed in bash lexer when backslash at end of file.\n\t</li>\n\t<li>\n\tCrash on recent releases of GTK+ 2.x avoided by changing default font from X\n\tcore font to Pango font \"!Sans\".\n\t</li>\n\t<li>\n\tFix for SciTE properties files where multiline properties continued over completely blank lines.\n\t</li>\n\t<li>\n\tBug fixed in SciTE/GTK+ director interface where more data available than\n\tbuffer size.\n\t</li>\n\t<li>\n\tMinor visual fixes to SciTE splitter on GTK+.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite168.zip?download\">Release 1.68</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 9 March 2006.\n\t</li>\n\t<li>\n\tTranslucent drawing implemented for caret line and box indicators.\n\t</li>\n\t<li>\n\tLexer specifically for TCL is much more accurate than reusing C++ lexer.\n\t</li>\n\t<li>\n\tSupport for Inno Setup scripts.\n\t</li>\n\t<li>\n\tSupport for Opal language.\n\t</li>\n\t<li>\n\tCalltips may use a new style, STYLE_CALLTIP which allows choosing a\n\tdifferent font for calltips.\n\t</li>\n\t<li>\n\tPython lexer styles comments on decorators.\n\t</li>\n\t<li>\n\tHTML lexer refined handling of \"?>\" and \"%>\" within server\n\tside scripts.\n\t</li>\n\t<li>\n\tBatch file lexer improved.\n\t</li>\n\t<li>\n\tEiffel lexer doesn't treat '.' as a name character.\n\t</li>\n\t<li>\n\tLua lexer handles length operator, #, and hex literals.\n\t</li>\n\t<li>\n\tProperties file lexer has separate style for keys.\n\t</li>\n\t<li>\n\tPL/SQL folding improved.\n\t</li>\n\t<li>\n\tSciTE Replace dialog always searches in forwards direction.\n\t</li>\n\t<li>\n\tSciTE can detect language of file from initial #! line.\n\t</li>\n\t<li>\n\tSciTE on GTK+ supports output.scroll=2 setting.\n\t</li>\n\t<li>\n\tSciTE can perform an import a properties file from the command line.\n\t</li>\n\t<li>\n\tSet of word characters used for regular expression \\&lt; and \\&gt;.\n\t</li>\n\t<li>\n\tBug fixed with SCI_COPYTEXT stopping too early.\n\t</li>\n\t<li>\n\tBug fixed with splitting lines so that all lines are split.\n\t</li>\n\t<li>\n\tSciTE calls OnSwitchFile when closing one buffer causes a switch to another.\n\t</li>\n\t<li>\n\tSciTE bug fixed where properties were being reevaluated without good reason\n\tafter running a macro.\n\t</li>\n\t<li>\n\tCrash fixed when clearing document with some lines contracted in word wrap mode.\n\t</li>\n\t<li>\n\tPalette expands as more entries are needed.\n\t</li>\n\t<li>\n\tSCI_POSITIONFROMPOINT returns more reasonable value when close to\n\tlast text on a line.\n\t</li>\n\t<li>\n\tOn Windows, long pieces of text may be drawn in segments if they fail to draw\n\tas a whole.\n\t</li>\n\t<li>\n\tBug fixed with bad drawing when some visual changes made inside SCN_UPDATEUI\n\tnotification.\n\t</li>\n\t<li>\n\tSciTE bug fixed with groupundo setting.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite167.zip?download\">Release 1.67</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 17 December 2005.\n\t</li>\n\t<li>\n\tScintilla checks the paint region more accurately when seeing if an area is being\n\trepainted. Platform layer implementations may need to change for this to take\n\teffect. This fixes some drawing and styling bugs. Also optimized some parts of\n\tmarker code to only redraw the line of the marker rather than whole of the margin.\n\t</li>\n\t<li>\n\tQuoted identifier style for SQL. SQL folding performed more simply.\n\t</li>\n\t<li>\n\tRuby lexer improved to better handle here documents and non-ASCII\n\tcharacters.\n\t</li>\n\t<li>\n\tLua lexer supports long string and block comment syntax from Lua 5.1.\n\t</li>\n\t<li>\n\tBash lexer handles here documents better.\n\t</li>\n\t<li>\n\tJavaScript lexing recognizes regular expressions more accurately and includes flag\n\tcharacters in the regular expression style. This is both in JavaScript files and when\n\tJavaScript is embedded in HTML.\n\t</li>\n\t<li>\n\tScintilla API provided to reveal how many style bits are needed for the\n\tcurrent lexer.\n\t</li>\n\t<li>\n\tSelection duplicate added.\n\t</li>\n\t<li>\n\tScintilla API for adding a set of markers to a line.\n\t</li>\n\t<li>\n\tDBCS encodings work on Windows 9x.\n\t</li>\n\t<li>\n\tConvention defined for property names to be used by lexers and folders\n\tso they can be automatically discovered and forwarded from containers.\n\t</li>\n\t<li>\n\tDefault bookmark in SciTE changed to a blue sphere image.\n\t</li>\n\t<li>\n\tSciTE stores the time of last asking for a save separately for each buffer\n\twhich fixes bugs with automatic reloading.\n\t</li>\n\t<li>\n\tOn Windows, pasted text has line ends converted to current preference.\n\tGTK+ already did this.\n\t</li>\n\t<li>\n\tKid template language better handled by HTML lexer by finishing ASP Python\n\tmode when a ?> is found.\n\t</li>\n\t<li>\n\tSciTE counts number of characters in a rectangular selection correctly.\n\t</li>\n\t<li>\n\t64-bit compatibility improved. One change that may affect user code is that\n\tthe notification message header changed to include a pointer-sized id field\n\tto match the current Windows definition.\n\t</li>\n\t<li>\n\tEmpty ranges can no longer be dragged.\n\t</li>\n\t<li>\n\tCrash fixed when calls made that use layout inside the painted notification.\n\t</li>\n\t<li>\n\tBug fixed where Scintilla created pixmap buffers that were too large leading\n\tto failures when many instances used.\n\t</li>\n\t<li>\n\tSciTE sets the directory of a new file to the directory of the currently\n\tactive file.\n\t</li>\n\t<li>\n\tSciTE allows choosing a code page for the output pane.\n\t</li>\n\t<li>\n\tSciTE HTML exporter no longer honours monospaced font setting.\n\t</li>\n\t<li>\n\tLine layout cache in page mode caches the line of the caret. An assertion is\n\tnow used to ensure that the layout reentrancy problem that caused this\n\tis easier to find.\n\t</li>\n\t<li>\n\tSpeed optimized for long lines and lines containing many control characters.\n\t</li>\n\t<li>\n\tBug fixed in brace matching in DBCS files where byte inside character\n\tis same as brace.\n\t</li>\n\t<li>\n\tIndent command does not indent empty lines.\n\t</li>\n\t<li>\n\tSciTE bug fixed for commands that operate on files with empty extensions.\n\t</li>\n\t<li>\n\tSciTE bug fixed where monospaced option was copied for subsequently opened files.\n\t</li>\n\t<li>\n\tSciTE on Windows bug fixed in the display of a non-ASCII search string\n\twhich can not be found.\n\t</li>\n\t<li>\n\tBugs fixed with nested calls displaying a new calltip while one is already\n\tdisplayed.\n\t</li>\n\t<li>\n\tBug fixed when styling PHP strings.\n\t</li>\n\t<li>\n\tBug fixed when styling C++ continued preprocessor lines.\n\t</li>\n\t<li>\n\tSciTE bug fixed where opening file from recently used list reset choice of\n\tlanguage.\n\t</li>\n\t<li>\n\tSciTE bug fixed when compiled with NO_EXTENSIONS and\n\tclosing one file closes the application.\n\t</li>\n\t<li>\n\tSciTE crash fixed for error messages that look like Lua messages but aren't\n\tin the same order.\n\t</li>\n\t<li>\n\tRemaining fold box support deprecated. The symbols SC_FOLDLEVELBOXHEADERFLAG,\n   SC_FOLDLEVELBOXFOOTERFLAG, SC_FOLDLEVELCONTRACTED,\n   SC_FOLDLEVELUNINDENT, and SC_FOLDFLAG_BOX are deprecated.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite166.zip?download\">Release 1.66</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 26 August 2005.\n\t</li>\n\t<li>\n\tNew, more ambitious Ruby lexer.\n\t</li>\n\t<li>\n\tSciTE Find in Files dialog has options for matching case and whole words which are\n\tenabled when the internal find command is used.\n\t</li>\n\t<li>\n\tSciTE output pane can display automatic completion after \"$(\" typed.\n\tAn initial \">\" on a line is ignored when Enter pressed.\n\t</li>\n\t<li>\n\tC++ lexer recognizes keywords within line doc comments. It continues styles over line\n\tend characters more consistently so that eolfilled style can be used for preprocessor lines\n\tand line comments.\n\t</li>\n\t<li>\n\tVB lexer improves handling of file numbers and date literals.\n\t</li>\n\t<li>\n\tLua folder handles repeat until, nested comments and nested strings.\n\t</li>\n\t<li>\n\tPOV lexer improves handling of comment lines.\n\t</li>\n\t<li>\n\tAU3 lexer and folder updated. COMOBJ style added.\n\t</li>\n\t<li>\n\tBug fixed with text display on GTK+ with Pango 1.8.\n\t</li>\n\t<li>\n\tCaret painting avoided when not focused.\n\t</li>\n\t<li>\n\tSciTE on GTK+ handles file names used to reference properties as case-sensitive.\n\t</li>\n\t<li>\n\tSciTE on GTK+ Save As and Export commands set the file name field.\n\tOn GTK+ the Export commands modify the file name in the same way as on Windows.\n\t</li>\n\t<li>\n\tFixed SciTE problem where confirmation was not displaying when closing a file where all\n\tcontents had been deleted.\n\t</li>\n\t<li>\n\tMiddle click on SciTE tab now closes correct buffer on Windows when tool bar is visible.\n\t</li>\n\t<li>\n\tSciTE bugs fixed where files contained in directory that includes '.' character.\n\t</li>\n\t<li>\n\tSciTE bug fixed where import in user options was reading file from directory of\n\tglobal options.\n\t</li>\n\t<li>\n\tSciTE calltip bug fixed where single line calltips had arrow displayed incorrectly.\n\t</li>\n\t<li>\n\tSciTE folding bug fixed where empty lines were shown for no reason.\n\t</li>\n\t<li>\n\tBug fixed where 2 byte per pixel XPM images caused crash although they are still not\n\tdisplayed.\n\t</li>\n\t<li>\n\tAutocompletion list size tweaked.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite165.zip?download\">Release 1.65</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 1 August 2005.\n\t</li>\n\t<li>\n\tFreeBasic support.\n\t</li>\n\t<li>\n\tSciTE on Windows handles command line arguments\n\t\"-\" (read standard input into buffer),\n\t\"--\" (read standard input into output pane) and\n\t\"-@\" (read file names from standard input and open each).\n\t</li>\n\t<li>\n\tSciTE includes a simple implementation of Find in Files which is used if no find.command is set.\n\t</li>\n\t<li>\n\tSciTE can close tabs with a mouse middle click.\n\t</li>\n\t<li>\n\tSciTE includes a save.all.for.build setting.\n\t</li>\n\t<li>\n\tFolder for MSSQL.\n\t</li>\n\t<li>\n\tBatch file lexer understands more of the syntax and the behaviour of built in commands.\n\t</li>\n\t<li>\n\tPerl lexer handles here docs better; disambiguates barewords, quote-like delimiters, and repetition operators;\n\thandles Pods after __END__; recognizes numbers better; and handles some typeglob special variables.\n\t</li>\n\t<li>\n\tLisp adds more lexical states.\n\t</li>\n\t<li>\n\tPHP allows spaces after &lt;&lt;&lt;.\n\t</li>\n\t<li>\n\tTADS3 has a simpler set of states and recognizes identifiers.\n\t</li>\n\t<li>\n\tAvenue elseif folds better.\n\t</li>\n\t<li>\n\tErrorlist lexer treats lines starting with '+++' and '---' as separate\n\tstyles from '+' and '-' as they indicate file names in diffs.\n\t</li>\n\t<li>\n\tSciTE error recognizer handles file paths in extra explanatory lines from MSVC\n\tand in '+++' and '---' lines from diff.\n\t</li>\n\t<li>\n\tBugs fixed in SciTE and Scintilla folding behaviour when text pasted before\n\tfolded text caused unnecessary\n\tunfolding and cutting text could lead to text being irretrievably hidden.\n\t</li>\n\t<li>\n\tSciTE on Windows uses correct font for dialogs and better font for tab bar\n\tallowing better localization\n\t</li>\n\t<li>\n\tWhen Windows is used with a secondary monitor before the primary\n\tmonitor, autocompletion lists are not forced onto the primary monitor.\n\t</li>\n\t<li>\n\tScintilla calltip bug fixed where down arrow setting wrong value in notification\n\tif not in first line. SciTE bug fixed where second arrow only shown on multiple line\n\tcalltip and was therefore misinterpreting the notification value.\n\t</li>\n\t<li>\n\tLexers will no longer be re-entered recursively during, for example, fold level setting.\n\t</li>\n\t<li>\n\tUndo of typing in overwrite mode undoes one character at a time rather than requiring a removal\n\tand addition step for each character.\n\t</li>\n\t<li>\n\tEM_EXSETSEL(0,-1) fixed.\n\t</li>\n\t<li>\n\tBug fixed where part of a rectangular selection was not shown as selected.\n\t</li>\n\t<li>\n\tAutocomplete window size fixed.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite164.zip?download\">Release 1.64</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 6 June 2005.\n\t</li>\n\t<li>\n\tTADS3 support\n\t</li>\n\t<li>\n\tSmalltalk support.\n\t</li>\n\t<li>\n\tRebol support.\n\t</li>\n\t<li>\n\tFlagship (Clipper / XBase) support.\n\t</li>\n\t<li>\n\tCSound support.\n\t</li>\n\t<li>\n\tSQL enhanced to support SQL*Plus.\n\t</li>\n\t<li>\n\tSC_MARK_FULLRECT margin marker fills the whole marker margin for marked\n\tlines with a colour.\n\t</li>\n\t<li>\n\tPerformance improved for some large undo and redo operations and modification flags\n\tadded in notifications.\n\t</li>\n\t<li>\n\tSciTE adds command equivalents for fold margin mouse actions.\n\t</li>\n\t<li>\n\tSciTE adds OnUpdateUI to set of events that can be handled by a Lua script.\n\t</li>\n\t<li>\n\tProperties set in Scintilla can be read.\n\t</li>\n\t<li>\n\tGTK+ SciTE exit confirmation adds Cancel button.\n\t</li>\n\t<li>\n\tMore accurate lexing of numbers in PHP and Caml.\n\t</li>\n\t<li>\n\tPerl can fold POD and package sections. POD verbatim section style.\n\tGlobbing syntax recognized better.\n\t</li>\n\t<li>\n\tContext menu moved slightly on GTK+ so that it will be under the mouse and will\n\tstay open if just clicked rather than held.\n\t</li>\n\t<li>\n\tRectangular selection paste works the same whichever direction the selection was dragged in.\n\t</li>\n\t<li>\n\tEncodedFromUTF8 handles -1 length argument as documented.\n\t</li>\n\t<li>\n\tUndo and redo can cause SCN_MODIFYATTEMPTRO notifications.\n\t</li>\n\t<li>\n\tIndicators display correctly when they start at the second character on a line.\n\t</li>\n\t<li>\n\tSciTE Export As HTML uses standards compliant CSS.\n\t</li>\n\t<li>\n\tSciTE automatic indentation handles keywords for indentation better.\n\t</li>\n\t<li>\n\tSciTE fold.comment.python property removed as does not work.\n\t</li>\n\t<li>\n\tFixed problem with character set conversion when pasting on GTK+.\n\t</li>\n\t<li>\n\tSciTE default character set changed from ANSI_CHARSET to DEFAULT_CHARSET.\n\t</li>\n\t<li>\n\tFixed crash when creating empty autocompletion list.\n\t</li>\n\t<li>\n\tAutocomplete window size made larger under some conditions to make truncation less common.\n\t</li>\n\t<li>\n\tBug fixed where changing case of a selection did not affect initial character of lines\n\tin multi-byte encodings.\n\t</li>\n\t<li>\n\tBug fixed where rectangular selection not displayed after Alt+Shift+Click.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite163.zip?download\">Release 1.63</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 4 April 2005.\n\t</li>\n\t<li>\n\tAutocompletion on Windows changed to use pop up window, be faster,\n\tallow choice of maximum width and height, and to highlight only the text of the\n\tselected item rather than both the text and icon if any.\n\t</li>\n\t<li>\n\tExtra items can be added to the context menu in SciTE.\n\t</li>\n\t<li>\n\tCharacter wrap mode in Scintilla helps East Asian languages.\n\t</li>\n\t<li>\n\tLexer added for Haskell.\n\t</li>\n\t<li>\n\tObjective Caml support.\n\t</li>\n\t<li>\n\tBlitzBasic and PureBasic support.\n\t</li>\n\t<li>\n\tCSS support updated to handle CSS2.\n\t</li>\n\t<li>\n\tC++ lexer is more selective about document comment keywords.\n\t</li>\n\t<li>\n\tAutoIt 3 lexer improved.\n\t</li>\n\t<li>\n\tLua lexer styles end of line characters on comment and preprocessor\n\tlines so that the eolfilled style can be applied to them.\n\t</li>\n\t<li>\n\tNSIS support updated for line continuations, box comments, SectionGroup and\n\tPageEx, and with more up-to-date properties.\n\t</li>\n\t<li>\n\tClarion lexer updated to perform folding and have more styles.\n\t</li>\n\t<li>\n\tSQL lexer gains second set of keywords.\n\t</li>\n\t<li>\n\tErrorlist lexer recognizes Borland Delphi error messages.\n\t</li>\n\t<li>\n\tMethod added for determining number of visual lines occupied by a document\n\tline due to wrapping.\n\t</li>\n\t<li>\n\tSticky caret mode does not modify the preferred caret x position when typing\n\tand may be useful for typing columns of text.\n\t</li>\n\t<li>\n\tDwell end notification sent when scroll occurs.\n\t</li>\n\t<li>\n\tOn GTK+, Scintilla requisition height is screen height rather than large fixed value.\n\t</li>\n\t<li>\n\tCase insensitive autocompletion prefers exact case match.\n\t</li>\n\t<li>\n\tSCI_PARADOWN and SCI_PARAUP treat lines containing only white\n\tspace as empty and handle text hidden by folding.\n\t</li>\n\t<li>\n\tScintilla on Windows supports WM_PRINTCLIENT although there are some\n\tlimitations.\n\t</li>\n\t<li>\n\tSCN_AUTOCSELECTION notification sent when user selects from autoselection list.\n\t</li>\n\t<li>\n\tSciTE's standard properties file sets buffers to 10, uses Pango fonts on GTK+ and\n\thas dropped several languages to make the menu fit on screen.\n\t</li>\n\t<li>\n\tSciTE's encoding cookie detection loosened so that common XML files will load\n\tin UTF-8 if that is their declared encoding.\n\t</li>\n\t<li>\n\tSciTE on GTK+ changes menus and toolbars to not be detachable unless turned\n\ton with a property. Menus no longer tear off. The toolbar may be set to use the\n\tdefault theme icons rather than SciTE's set. Changed key for View | End of Line\n\tbecause of a conflict. Language menu can contain more items.\n\t</li>\n\t<li>\n\tSciTE on GTK+ 2.x allows the height and width of the file open file chooser to\n\tbe set, for the show hidden files check box to be set from an option and for it\n\tto be opened in the directory of the current file explicitly. Enter key works in\n\tsave chooser.\n\t</li>\n\t<li>\n\tScintilla lexers should no longer see bits in style bytes that are outside the set\n\tthey modify so should be able to correctly lex documents where the container\n\thas used indicators.\n\t</li>\n\t<li>\n\tSciTE no longer asks to save before performing a revert.\n\t</li>\n\t<li>\n\tSciTE director interface adds a reloadproperties command to reload properties\n\tfrom files.\n\t</li>\n\t<li>\n\tAllow build on CYGWIN platform.\n\t</li>\n\t<li>\n\tAllow use from LccWin compiler.\n\t</li>\n\t<li>\n\tSCI_COLOURISE for SCLEX_CONTAINER causes a\n\tSCN_STYLENEEDED notification.\n\t</li>\n\t<li>\n\tBugs fixed in lexing of HTML/ASP/JScript.\n\t</li>\n\t<li>\n\tFix for folding becoming confused.\n\t</li>\n\t<li>\n\tOn Windows, fixes for Japanese Input Method Editor and for 8 bit Katakana\n\tcharacters.\n\t</li>\n\t<li>\n\tFixed buffer size bug avoided when typing long words by making buffer bigger.\n\t</li>\n\t<li>\n\tUndo after automatic indentation more sensible.\n\t</li>\n\t<li>\n\tSciTE menus on GTK+ uses Shift and Ctrl rather than old style abbreviations.\n\t</li>\n\t<li>\n\tSciTE full screen mode on Windows calculates size more correctly.\n\t</li>\n\t<li>\n\tSciTE on Windows menus work better with skinning applications.\n\t</li>\n\t<li>\n\tSearching bugs fixed.\n\t</li>\n\t<li>\n\tColours reallocated when changing image using SCI_REGISTERIMAGE.\n\t</li>\n\t<li>\n\tCaret stays visible when Enter held down.\n\t</li>\n\t<li>\n\tUndo of automatic indentation more reasonable.\n\t</li>\n\t<li>\n\tHigh processor usage fixed in background wrapping under some\n\tcircumstances.\n\t</li>\n\t<li>\n\tCrashing bug fixed on AMD64.\n\t</li>\n\t<li>\n\tSciTE crashing bug fixed when position.height or position.width not set.\n\t</li>\n\t<li>\n\tCrashing bug on GTK+ fixed when setting cursor and window is NULL.\n\t</li>\n\t<li>\n\tCrashing bug on GTK+ preedit window fixed.\n\t</li>\n\t<li>\n\tSciTE crashing bug fixed in incremental search on Windows ME.\n\t</li>\n\t<li>\n\tSciTE on Windows has an optional find and replace dialogs that can search through\n\tall buffers and search within a particular style number.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite162.zip?download\">Release 1.62</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 31 October 2004.\n\t</li>\n\t<li>\n\tLexer added for ASN.1.\n\t</li>\n\t<li>\n\tLexer added for VHDL.\n\t</li>\n\t<li>\n\tOn Windows, an invisible system caret is used to allow screen readers to determine\n\twhere the caret is. The visible caret is still drawn by the painting code.\n\t</li>\n\t<li>\n\tOn GTK+, Scintilla has methods to read the target as UTF-8 and to convert\n\ta string from UTF-8 to the document encoding. This eases integration with\n\tcontainers that use the UTF-8 encoding which is the API encoding for GTK+ 2.\n\t</li>\n\t<li>\n\tSciTE on GTK+2 and Windows NT/2000/XP allows search and replace of Unicode text.\n\t</li>\n\t<li>\n\tSciTE calltips allow setting the characters used to start and end parameter lists and\n\tto separate parameters.\n\t</li>\n\t<li>\n\tFindColumn method converts a line and column into a position, taking into account\n\ttabs and multi-byte characters.\n\t</li>\n\t<li>\n\tOn Windows, when Scintilla copies text to the clipboard as Unicode, it avoids\n\tadding an ANSI copy as the system will automatically convert as required in\n\ta context-sensitive manner.\n\t</li>\n\t<li>\n\tSciTE indent.auto setting automatically determines indent.size and use.tabs from\n\tdocument contents.\n\t</li>\n\t<li>\n\tSciTE defines a CurrentMessage property that holds the most recently selected\n\toutput pane message.\n\t</li>\n\t<li>\n\tSciTE Lua scripting enhanced with\n\t<ul>\n\t<li>A Lua table called 'buffer' is associated with each buffer and can be used to\n\tmaintain buffer-specific state.</li>\n\t<li>A 'scite' object allows interaction with the application such as opening\n\tfiles from script.</li>\n\t<li>Dynamic properties can be reset by assigning nil to a given key in\n\tthe props table.</li>\n\t<li>An 'OnClear' event fires whenever properties and extension scripts are\n\tabout to be reloaded.</li>\n\t<li>On Windows, loadlib is enabled and can be used to access Lua\n\tbinary modules / DLLs.</li></ul>\n\t</li>\n\t<li>\n\tSciTE Find in Files on Windows can be used in a modeless way and gains a '..'\n\tbutton to move up to the parent directory. It is also wider so that longer paths\n\tcan be seen.\n\t</li>\n\t<li>\n\tClose buttons added to dialogs in SciTE on Windows.\n\t</li>\n\t<li>\n\tSciTE on GTK+ 2 has a \"hidden files\" check box in file open dialog.\n\t</li>\n\t<li>\n\tSciTE use.monospaced setting removed. More information in the\n\t<a href=\"SciTEFAQ.html\">FAQ</a>.\n\t</li>\n\t<li>\n\tAPDL lexer updated with more lexical classes\n\t</li>\n\t<li>\n\tAutoIt3 lexer updated.\n\t</li>\n\t<li>\n\tAda lexer fixed to support non-ASCII text.\n\t</li>\n\t<li>\n\tCpp lexer now only matches exactly three slashes as starting a doc-comment so that\n\tlines of slashes are seen as a normal comment.\n\tLine ending characters are appear in default style on preprocessor and single line\n\tcomment lines.\n\t</li>\n\t<li>\n\tCSS lexer updated to support CSS2 including second set of keywords.\n\t</li>\n\t<li>\n\tErrorlist lexer now understands Java stack trace lines.\n\t</li>\n\t<li>\n\tSciTE's handling of HTML Tidy messages jumps to column as well as line indicated.\n\t</li>\n\t<li>\n\tLisp lexer allows multiline strings.\n\t</li>\n\t<li>\n\tLua lexer treats .. as an operator when between identifiers.\n\t</li>\n\t<li>\n\tPHP lexer handles 'e' in numerical literals.\n\t</li>\n\t<li>\n\tPowerBasic lexer updated for macros and optimized.\n\t</li>\n\t<li>\n\tProperties file folder changed to leave lines before a header at the base level\n\tand thus avoid a vertical line when using connected folding symbols.\n\t</li>\n\t<li>\n\tGTK+ on Windows version uses Alt for rectangular selection to be compatible with\n\tplatform convention.\n\t</li>\n\t<li>\n\tSciTE abbreviations file moved from system directory to user directory\n\tso each user can have separate abbreviations.\n\t</li>\n\t<li>\n\tSciTE on GTK+ has improved .desktop file and make install support that may\n\tlead to better integration with system shell.\n\t</li>\n\t<li>\n\tDisabling of themed background drawing on GTK+ extended to all cases.\n\t</li>\n\t<li>\n\tSciTE date formatting on Windows performed with the user setting rather than the\n\tsystem setting.\n\t</li>\n\t<li>\n\tGTK+ 2 redraw while scrolling fixed.\n\t</li>\n\t<li>\n\tRecursive property definitions are safer, avoiding expansion when detected.\n\t</li>\n\t<li>\n\tSciTE thread synchronization for scripts no longer uses HWND_MESSAGE\n\tso is compatible with older versions of Windows.\n\tOther Lua scripting bugs fixed.\n\t</li>\n\t<li>\n\tSciTE on Windows localization of menu accelerators changed to be compatible\n\twith alternative UI themes.\n\t</li>\n\t<li>\n\tSciTE on Windows full screen mode now fits better when menu different height\n\tto title bar height.\n\t</li>\n\t<li>\n\tSC_MARK_EMPTY marker is now invisible and does not change the background\n\tcolour.\n\t</li>\n\t<li>\n\tBug fixed in HTML lexer to allow use of &lt;?xml in strings in scripts without\n\ttriggering xml mode.\n\t</li>\n\t<li>\n\tBug fixed in SciTE abbreviation expansion that could break indentation or crash.\n\t</li>\n\t<li>\n\tBug fixed when searching for a whole word string that ends one character before\n\tend of document.\n\t</li>\n\t<li>\n\tDrawing bug fixed when indicators drawn on wrapped lines.\n\t</li>\n\t<li>\n\tBug fixed when double clicking a hotspot.\n\t</li>\n\t<li>\n\tBug fixed where autocompletion would remove typed text if no match found.\n\t</li>\n\t<li>\n\tBug fixed where display does not scroll when inserting in long wrapped line.\n\t</li>\n\t<li>\n\tBug fixed where SCI_MARKERDELETEALL would only remove one of the markers\n\ton a line that contained multiple markers with the same number.\n\t</li>\n\t<li>\n\tBug fixed where markers would move when converting line endings.\n\t</li>\n\t<li>\n\tBug fixed where SCI_LINEENDWRAP would move too far when line ends are visible.\n\t</li>\n\t<li>\n\tBugs fixed where calltips with unicode or other non-ASCII text would display\n\tincorrectly.\n\t</li>\n\t<li>\n\tBug fixed in determining if at save point after undoing from save point and then\n\tperforming changes.\n\t</li>\n\t<li>\n\tBug fixed on GTK+ using unsupported code pages where extraneous text could\n\tbe drawn.\n\t</li>\n\t<li>\n\tBug fixed in drag and drop code on Windows where dragging from SciTE to\n\tFirefox could hang both applications.\n\t</li>\n\t<li>\n\tCrashing bug fixed on GTK+ when no font allocation succeeds.\n\t</li>\n\t<li>\n\tCrashing bug fixed when autocompleting word longer than 1000 characters.\n\t</li>\n\t<li>\n\tSciTE crashing bug fixed when both Find and Replace dialogs shown by disallowing\n\tthis situation.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite161.zip?download\">Release 1.61</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 29 May 2004.\n\t</li>\n\t<li>\n\tImprovements to selection handling on GTK+.\n\t</li>\n\t<li>\n\tSciTE on GTK+ 2.4 uses the improved file chooser which allows\n\tfile extension filters, multiple selection, and remembers favourite\n\tdirectories.\n\t</li>\n\t<li>\n\tSciTE Load Session and Save Session commands available on GTK+.\n\t</li>\n\t<li>\n\tSciTE lists Lua Startup Script in Options menu when loaded.\n\t</li>\n\t<li>\n\tIn SciTE, OnUserListSelection can be implemented in Lua.\n\t</li>\n\t<li>\n\tSciTE on Windows has a context menu on the file tabs.\n\t</li>\n\t<li>\n\tSQL lexer allows '#' comments and optionally '\\' quoting inside strings.\n\t</li>\n\t<li>\n\tMssql lexer improved.\n\t</li>\n\t<li>\n\tAutoIt3 lexer updated.\n\t</li>\n\t<li>\n\tPerl lexer recognizes regular expression use better.\n\t</li>\n\t<li>\n\tErrorlist lexer understands Lua tracebacks and copes with findstr\n\toutput for file names that end with digits.\n\t</li>\n\t<li>\n\tDrawing of lines on GTK+ improved and made more like Windows\n\twithout final point.\n\t</li>\n\t<li>\n\tSciTE on GTK+ uses a high resolution window icon.\n\t</li>\n\t<li>\n\tSciTE can be set to warn before loading files larger than a particular size.\n\t</li>\n\t<li>\n\tSciTE Lua scripting bugs fixed included a crashing bug when using\n\tan undefined function name that would go before first actual name.\n\t</li>\n\t<li>\n\tSciTE bug fixed where a modified buffer was not saved if it was\n\tthe last buffer and was not current when the New command used.\n\t</li>\n\t<li>\n\tSciTE monofont mode no longer affects line numbers.\n\t</li>\n\t<li>\n\tCrashing bug in SciTE avoided by not allowing both the Find and Replace\n\tdialogs to be visible at one time.\n\t</li>\n\t<li>\n\tCrashing bug in SciTE fixed when Lua scripts were being run\n\tconcurrently.\n\t</li>\n\t<li>\n\tBug fixed that caused incorrect line number width in SciTE.\n\t</li>\n\t<li>\n\tPHP folding bug fixed.\n\t</li>\n\t<li>\n\tRegression fixed when setting word characters to not include\n\tsome of the standard word characters.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite160.zip?download\">Release 1.60</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 1 May 2004.\n\t</li>\n\t<li>\n\tSciTE can be scripted using the Lua programming language.\n\t</li>\n\t<li>\n\tcommand.mode is a better way to specify tool command options in SciTE.\n\t</li>\n\t<li>\n\tContinuation markers can be displayed so that you can see which lines are wrapped.\n\t</li>\n\t<li>\n\tLexer for Gui4Cli language.\n\t</li>\n\t<li>\n\tLexer for Kix language.\n\t</li>\n\t<li>\n\tLexer for Specman E language.\n\t</li>\n\t<li>\n\tLexer for AutoIt3 language.\n\t</li>\n\t<li>\n\tLexer for APDL language.\n\t</li>\n\t<li>\n\tLexer for Bash language. Also reasonable for other Unix shells.\n\t</li>\n\t<li>\n\tSciTE can load lexers implemented in external shared libraries.\n\t</li>\n\t<li>\n\tPerl treats \".\" not as part of an identifier and interprets '/' and '->'\n\tcorrectly in more circumstances.\n\t</li>\n\t<li>\n\tPHP recognizes variables within strings.\n\t</li>\n\t<li>\n\tNSIS has properties \"nsis.uservars\" and \"nsis.ignorecase\".\n\t</li>\n\t<li>\n\tMSSQL lexer adds keyword list for operators and stored procedures,\n\tdefines '(', ')', and ',' as operators and changes some other details.\n\t</li>\n\t<li>\n\tInput method preedit window on GTK+ 2 may support some Asian languages.\n\t</li>\n\t<li>\n\tPlatform interface adds an extra platform-specific flag to Font::Create.\n\tUsed on wxWidgets to choose antialiased text display but may be used for\n\tany task that a platform needs.\n\t</li>\n\t<li>\n\tOnBeforeSave method added to Extension interface.\n\t</li>\n\t<li>\n\tScintilla methods that return strings can be called with a NULL pointer\n\tto find out how long the string should be.\n\t</li>\n\t<li>\n\tVisual Studio .NET project file now in VS .NET 2003 format so can not be used\n\tdirectly in VS .NET 2002.\n\t</li>\n\t<li>\n\tScintilla can be built with GTK+ 2 on Windows.\n\t</li>\n\t<li>\n\tUpdated RPM spec for SciTE on GTK+.\n\t</li>\n\t<li>\n\tGTK+ makefile for SciTE allows selection of destination directory, creates destination\n\tdirectories and sets file modes and owners better.\n\t</li>\n\t<li>\n\tTab indents now go to next tab multiple rather than add tab size.\n\t</li>\n\t<li>\n\tSciTE abbreviations now use the longest possible match rather than the shortest.\n\t</li>\n\t<li>\n\tAutocompletion does not remove prefix when actioned with no choice selected.\n\t</li>\n\t<li>\n\tAutocompletion cancels when moving beyond the start position, not at the start position.\n\t</li>\n\t<li>\n\tSciTE now shows only calltips for functions that match exactly, not\n\tthose that match as a prefix.\n\t</li>\n\t<li>\n\tSciTE can repair box comment sections where some lines were added without\n\tthe box comment middle line prefix.\n\t</li>\n\t<li>\n\tAlt+ works in user.shortcuts on Windows.\n\t</li>\n\t<li>\n\tSciTE on GTK+ enables replace in selection for rectangular selections.\n\t</li>\n\t<li>\n\tKey bindings for command.shortcut implemented in a way that doesn't break\n\twhen the menus are localized.\n\t</li>\n\t<li>\n\tDrawing of background on GTK+ faster as theme drawing disabled.\n\t</li>\n\t<li>\n\tOn GTK+, calltips are moved back onto the screen if they extend beyond the screen bounds.\n\t</li>\n\t<li>\n\tOn Windows, the Scintilla object is destroyed on WM_NCDESTROY rather than\n\tWM_DESTROY which arrives earlier. This fixes some problems when Scintilla was subclassed.\n\t</li>\n\t<li>\n\tThe zorder switching feature removed due to number of crashing bugs.\n\t</li>\n\t<li>\n\tCode for XPM images made more robust.\n\t</li>\n\t<li>\n\tBug fixed with primary selection on GTK+.\n\t</li>\n\t<li>\n\tOn GTK+ 2, copied or cut text can still be pasted after the Scintilla widget is destroyed.\n\t</li>\n\t<li>\n\tStyling change not visible problem fixed when line was cached.\n\t</li>\n\t<li>\n\tBug in SciTE on Windows fixed where clipboard commands stopped working.\n\t</li>\n\t<li>\n\tCrashing bugs in display fixed in line layout cache.\n\t</li>\n\t<li>\n\tCrashing bug may be fixed on AMD64 processor on GTK+.\n\t</li>\n\t<li>\n\tRare hanging crash fixed in Python lexer.\n\t</li>\n\t<li>\n\tDisplay bugs fixed with DBCS characters on GTK+.\n\t</li>\n\t<li>\n\tAutocompletion lists on GTK+ 2 are not sorted by the ListModel as the\n\tcontents are sorted correctly by Scintilla.\n\t</li>\n\t<li>\n\tSciTE fixed to not open extra untitled buffers with check.if.already.open.\n\t</li>\n\t<li>\n\tSizing bug fixed on GTK+ when window resized while unmapped.\n\t</li>\n\t<li>\n\tText drawing crashing bug fixed on GTK+ with non-Pango fonts and long strings.\n\t</li>\n\t<li>\n\tFixed some issues if characters are unsigned.\n\t</li>\n\t<li>\n\tFixes in NSIS support.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite159.zip?download\">Release 1.59</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 19 February 2004.\n\t</li>\n\t<li>\n\tSciTE Options and Language menus reduced in length by commenting\n\tout some languages. Languages can be enabled by editing the global\n\tproperties file.\n\t</li>\n\t<li>\n\tVerilog language supported.\n\t</li>\n\t<li>\n\tLexer for Microsoft dialect of SQL. SciTE properties file available from extras page.\n\t</li>\n\t<li>\n\tPerl lexer disambiguates '/' better.\n\t</li>\n\t<li>\n\tNSIS lexer improved with a lexical class for numbers, option for ignoring case\n\tof keywords, and folds only occurring when folding keyword first on line.\n\t</li>\n\t<li>\n\tPowerBasic lexer improved with styles for constants and assembler and\n\tfolding improvements.\n\t</li>\n\t<li>\n\tOn GTK+, input method support only invoked for Asian languages and not\n\tEuropean languages as the old European keyboard code works better.\n\t</li>\n\t<li>\n\tScintilla can be requested to allocate a certain amount and so avoid repeated\n\treallocations and memory inefficiencies. SciTE uses this and so should require\n\tless memory.\n\t</li>\n\t<li>\n\tSciTE's \"toggle current fold\" works when invoked on child line as well as\n\tfold header.\n\t</li>\n\t<li>\n\tSciTE output pane scrolling can be set to not scroll back to start after\n\tcompletion of command.\n\t</li>\n\t<li>\n\tSciTE has a $(SessionPath) property.\n\t</li>\n\t<li>\n\tSciTE on Windows can use VK_* codes for keys in user.shortcuts.\n\t</li>\n\t<li>\n\tStack overwrite bug fixed in SciTE's command to move to the end of a\n\tpreprocessor conditional.\n\t</li>\n\t<li>\n\tBug fixed where vertical selection appeared to select a different set of characters\n\tthen would be used by, for example, a copy.\n\t</li>\n\t<li>\n\tSciTE memory leak fixed in fold state remembering.\n\t</li>\n\t<li>\n\tBug fixed where changing the style of some text outside the\n\tstandard StyleNeeded notification would not be visible.\n\t</li>\n\t<li>\n\tOn GTK+ 2 g_iconv is used in preference to iconv, as it is provided by GTK+\n\tso should avoid problems finding the iconv library.\n\t</li>\n\t<li>\n\tOn GTK+ fixed a style reference count bug.\n\t</li>\n\t<li>\n\tMemory corruption bug fixed with GetSelText.\n\t</li>\n\t<li>\n\tOn Windows Scintilla deletes memory on WM_NCDESTROY rather than\n\tthe earlier WM_DESTROY to avoid problems when the window is subclassed.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite158.zip?download\">Release 1.58</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 11 January 2004.\n\t</li>\n\t<li>\n\tMethod to discover the currently highlighted element in an autocompletion list.\n\t</li>\n\t<li>\n\tOn GTK+, the lexers are now included in the scintilla.a library file. This\n\twill require changes to the make files of dependent projects.\n\t</li>\n\t<li>\n\tOctave support added alongside related Matlab language and Matlab support improved.\n\t</li>\n\t<li>\n\tVB lexer gains an unterminated string state and 4 sets of keywords.\n\t</li>\n\t<li>\n\tRuby lexer handles $' correctly.\n\t</li>\n\t<li>\n\tError line handling improved for FORTRAN compilers from Absoft and Intel.\n\t</li>\n\t<li>\n\tInternational input enabled on GTK+ 2 although there is no way to choose an\n\tinput method.\n\t</li>\n\t<li>\n\tMultiplexExtension in SciTE allows multiple extensions to be used at once.\n\t</li>\n\t<li>\n\tRegular expression replace interprets backslash expressions \\a, \\b, \\f, \\n, \\r, \\t,\n\tand \\v in the replacement value.\n\t</li>\n\t<li>\n\tSciTE Replace dialog displays number of replacements made when Replace All or\n\tReplace in Selection performed.\n\t</li>\n\t<li>\n\tLocalization files may contain a translation.encoding setting which is used\n\ton GTK+ 2 to automatically reencode the translation to UTF-8 so it will be\n\tthe localized text will be displayed correctly.\n\t</li>\n\t<li>\n\tSciTE on GTK+ implements check.if.already.open.\n\t</li>\n\t<li>\n\tMake files for Mac OS X made more robust.\n\t</li>\n\t<li>\n\tPerformance improved in SciTE when switching buffers when there\n\tis a rectangular selection.\n\t</li>\n\t<li>\n\tFixed failure to display some text when wrapped.\n\t</li>\n\t<li>\n\tSciTE crashes from Ctrl+Tab buffer cycling fixed.\n\tMay still be some rare bugs here.\n\t</li>\n\t<li>\n\tCrash fixed when decoding an error message that appears similar to a\n\tBorland error message.\n\t</li>\n\t<li>\n\tFix to auto-scrolling allows containers to implement enhanced double click selection.\n\t</li>\n\t<li>\n\tHang fixed in idle word wrap.\n\t</li>\n\t<li>\n\tCrash fixed in hotspot display code..\n\t</li>\n\t<li>\n\tSciTE on Windows Incremental Search no longer moves caret back.\n\t</li>\n\t<li>\n\tSciTE hang fixed when performing a replace with a find string that\n\tmatched zero length strings such as \".*\".\n\t</li>\n\t<li>\n\tSciTE no longer styles the whole file when saving buffer fold state\n\tas that was slow.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite157.zip?download\">Release 1.57</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 27 November 2003.\n\t</li>\n\t<li>\n\tSciTE remembers folding of each buffer.\n\t</li>\n\t<li>\n\tLexer for Erlang language.\n\t</li>\n\t<li>\n\tScintilla allows setting the set of white space characters.\n\t</li>\n\t<li>\n\tScintilla has 'stuttered' page movement commands to first move\n\tto top or bottom within current visible lines before scrolling.\n\t</li>\n\t<li>\n\tScintilla commands for moving to end of words.\n\t</li>\n\t<li>\n\tIncremental line wrap enabled on Windows.\n\t</li>\n\t<li>\n\tSciTE PDF exporter produces output that is more compliant with reader\n\tapplications, is smaller and allows more configuration.\n\tHTML exporter optimizes size of output files.\n\t</li>\n\t<li>\n\tSciTE defines properties PLAT_WINNT and PLAT_WIN95 on the\n\tcorresponding platforms.\n\t</li>\n\t<li>\n\tSciTE can adjust the line margin width to fit the largest line number.\n\tThe line.numbers property is split between line.margin.visible and\n\tline.margin.width.\n\t</li>\n\t<li>\n\tSciTE on GTK+ allows user defined menu accelerators.\n\tAlt can be included in user.shortcuts.\n\t</li>\n\t<li>\n\tSciTE Language menu can have items commented out.\n\t</li>\n\t<li>\n\tSciTE on Windows Go to dialog allows choosing a column number as\n\twell as a line number.\n\t</li>\n\t<li>\n\tSciTE on GTK+ make file uses prefix setting more consistently.\n\t</li>\n\t<li>\n\tBug fixed that caused word wrapping to fail to display all text.\n\t</li>\n\t<li>\n\tCrashing bug fixed in GTK+ version of Scintilla when using GDK fonts\n\tand opening autocompletion.\n\t</li>\n\t<li>\n\tBug fixed in Scintilla SCI_GETSELTEXT where an extra NUL\n\twas included at end of returned string\n\t</li>\n\t<li>\n\tCrashing bug fixed in SciTE z-order switching implementation.\n\t</li>\n\t<li>\n\tHanging bug fixed in Perl lexer.\n\t</li>\n\t<li>\n\tSciTE crashing bug fixed for using 'case' without argument in style definition.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite156.zip?download\">Release 1.56</a>\n    </h3>\n    <ul>\n\t<li>\n\tReleased on 25 October 2003.\n\t</li>\n\t<li>\n\tRectangular selection can be performed using the keyboard.\n\tGreater programmatic control over rectangular selection.\n\tThis has caused several changes to key bindings.\n\t</li>\n\t<li>\n\tSciTE Replace In Selection works on rectangular selections.\n\t</li>\n\t<li>\n\tImproved lexer for TeX, new lexer for Metapost and other support for these\n\tlanguages.\n\t</li>\n\t<li>\n\tLexer for PowerBasic.\n\t</li>\n\t<li>\n\tLexer for Forth.\n\t</li>\n\t<li>\n\tYAML lexer improved to include error styling.\n\t</li>\n\t<li>\n\tPerl lexer improved to correctly handle more cases.\n\t</li>\n\t<li>\n\tAssembler lexer updated to support single-quote strings and fix some\n\tproblems.\n\t</li>\n\t<li>\n\tSciTE on Windows can switch between buffers in order of use (z-order) rather\n\tthan static order.\n\t</li>\n\t<li>\n\tSciTE supports adding an extension for \"Open Selected Filename\".\n\tThe openpath setting works on GTK+.\n\t</li>\n\t<li>\n\tSciTE can Export as XML.\n\t</li>\n\t<li>\n\tSciTE $(SelHeight) variable gives a more natural result for empty and whole line\n\tselections.\n\t</li>\n\t<li>\n\tFixes to wrapping problems, such as only first display line being visible in some\n\tcases.\n\t</li>\n\t<li>\n\tFixes to hotspot to only highlight when over the hotspot, only use background\n\tcolour when set and option to limit hotspots to a single line.\n\t</li>\n\t<li>\n\tSmall fixes to FORTRAN lexing and folding.\n\t</li>\n\t<li>\n\tSQL lexer treats single quote strings as a separate class to double quote strings..\n\t</li>\n\t<li>\n\tScintilla made compatible with expectations of container widget in GTK+ 2.3.\n\t</li>\n\t<li>\n\tFix to strip out pixmap ID when automatically choosing from an autocompletion\n\tlist with only one element.\n\t</li>\n\t<li>\n\tSciTE bug fixed where UTF-8 files longer than 128K were gaining more than one\n\tBOM.\n\t</li>\n\t<li>\n\tCrashing bug fixed in SciTE on GTK+ where using \"Stop Executing\" twice leads\n\tto all applications exiting.\n\t</li>\n\t<li>\n\tBug fixed in autocompletion scrolling on GTK+ 2 with a case sensitive list.\n\tThe ListBox::Sort method is no longer needed or available so platform\n\tmaintainers should remove it.\n\t</li>\n\t<li>\n\tSciTE check.if.already.open setting removed from GTK+ version as unmaintained.\n\t</li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite155.zip?download\">Release 1.55</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 25 September 2003.\n      </li>\n      <li>\n\tFix a crashing bug in indicator display in Scintilla.\n      </li>\n      <li>\n\tGTK+ version now defaults to building for GTK+ 2 rather than 1.\n      </li>\n      <li>\n\tMingw make file detects compiler version and avoids options\n\tthat are cause problems for some versions.\n      </li>\n      <li>\n\tLarge performance improvement on GTK+ 2 for long lines.\n      </li>\n      <li>\n\tIncremental line wrap on GTK+.\n      </li>\n      <li>\n\tInternational text entry works much better on GTK+ with particular\n\timprovements for Baltic languages and languages that use 'dead' accents.\n\tNUL key events such as those generated by some function keys, ignored.\n      </li>\n      <li>\n\tUnicode clipboard support on GTK+.\n      </li>\n      <li>\n\tIndicator type INDIC_BOX draws a rectangle around the text.\n      </li>\n      <li>\n\tClarion language support.\n      </li>\n      <li>\n\tYAML language support.\n      </li>\n      <li>\n\tMPT LOG language support.\n      </li>\n      <li>\n\tOn Windows, SciTE can switch buffers based on activation order rather\n\tthan buffer number.\n      </li>\n      <li>\n\tSciTE save.on.deactivate saves all buffers rather than just the current buffer.\n      </li>\n      <li>\n\tLua lexer handles non-ASCII characters correctly.\n      </li>\n      <li>\n\tError lexer understands Borland errors with pathnames that contain space.\n      </li>\n      <li>\n\tOn GTK+ 2, autocompletion uses TreeView rather than deprecated CList.\n      </li>\n      <li>\n\tSciTE autocompletion removed when expand abbreviation command used.\n      </li>\n      <li>\n\tSciTE calltips support overloaded functions.\n      </li>\n      <li>\n\tWhen Save fails in SciTE, choice offered to Save As.\n      </li>\n      <li>\n\tSciTE message boxes on Windows may be moved to front when needed.\n      </li>\n      <li>\n\tIndicators drawn correctly on wrapped lines.\n      </li>\n      <li>\n\tRegular expression search no longer matches characters with high bit\n\tset to characters without high bit set.\n      </li>\n      <li>\n\tHang fixed in backwards search in multi byte character documents.\n      </li>\n      <li>\n\tHang fixed in SciTE Mark All command when wrap around turned off.\n      </li>\n      <li>\n\tSciTE Incremental Search no longer uses hot keys on Windows.\n      </li>\n      <li>\n\tCalltips draw non-ASCII characters correctly rather than as arrows.\n      </li>\n      <li>\n\tSciTE crash fixed when going to an error message with empty file name.\n      </li>\n      <li>\n\tBugs fixed in XPM image handling code.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite154.zip?download\">Release 1.54</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 12 August 2003.\n      </li>\n      <li>\n\tSciTE on GTK+ 2.x can display a tab bar.\n      </li>\n      <li>\n\tSciTE on Windows provides incremental search.\n      </li>\n      <li>\n\tLexer for PostScript.\n      </li>\n      <li>\n\tLexer for the NSIS scripting language.\n      </li>\n      <li>\n\tNew lexer for POV-Ray Scene Description Language\n\treplaces previous implementation.\n      </li>\n      <li>\n\tLexer for the MMIX Assembler language.\n      </li>\n      <li>\n\tLexer for the Scriptol language.\n      </li>\n      <li>\n\tIncompatibility: SQL keywords are specified in lower case rather than upper case.\n\tSQL lexer allows double quoted strings.\n      </li>\n      <li>\n\tPascal lexer: character constants that start with '#' understood,\n\t'@' only allowed within assembler blocks,\n\t'$' can be the start of a number,\n\tinitial '.' in 0..constant not treated as part of a number,\n\tand assembler blocks made more distinctive.\n      </li>\n      <li>\n\tLua lexer allows '.' in keywords.\n\tMulti-line strings and comments can be folded.\n      </li>\n      <li>\n\tCSS lexer handles multiple psuedoclasses.\n      </li>\n      <li>\n\tProperties file folder works for INI file format.\n      </li>\n      <li>\n\tHidden indicator style allows the container to mark text within Scintilla\n\twithout there being any visual effect.\n      </li>\n      <li>\n\tSciTE does not prompt to save changes when the buffer is empty and untitled.\n      </li>\n      <li>\n\tModification notifications caused by SCI_INSERTSTYLEDSTRING\n\tnow include the contents of the insertion.\n      </li>\n      <li>\n\tSCI_MARKERDELETEALL deletes all the markers on a line\n\trather than just the first match.\n      </li>\n      <li>\n\tBetter handling of 'dead' accents on GTK+ 2 for languages\n\tthat use accented characters.\n      </li>\n      <li>\n\tSciTE now uses value of output.vertical.size property.\n      </li>\n      <li>\n\tCrash fixed in SciTE autocompletion on long lines.\n      </li>\n      <li>\n\tCrash fixed in SciTE comment command on long lines.\n      </li>\n      <li>\n\tBug fixed with backwards regular expression search skipping\n\tevery second match.\n      </li>\n      <li>\n\tHang fixed with regular expression replace where both target and replacement were empty.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite153.zip?download\">Release 1.53</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 16 May 2003.\n      </li>\n      <li>\n\tOn GTK+ 2, encodings other than ASCII, Latin1, and Unicode are\n\tsupported for both display and input using iconv.\n      </li>\n      <li>\n\tExternal lexers supported on GTK+/Linux.\n\tExternal lexers must now be explicitly loaded with SCI_LOADLEXERLIBRARY\n\trather than relying upon a naming convention and automatic loading.\n      </li>\n      <li>\n\tSupport of Lout typesetting language.\n      </li>\n      <li>\n\tSupport of E-Scripts language used in the POL Ultima Online Emulator.\n      </li>\n      <li>\n\tScrolling and drawing performance on GTK+ enhanced, particularly for GTK+ 2.x\n\twith an extra window for the text area avoiding conflicts with the scroll bars.\n      </li>\n      <li>\n\tCopyText and CopyRange methods in Scintilla allow container to\n\teasily copy to the system clipboard.\n      </li>\n      <li>\n\tLine Copy command implemented and bound to Ctrl+Shift+T.\n      </li>\n      <li>\n\tScintilla APIs PositionBefore and PositionAfter can be used to iterate through\n\ta document taking into account the encoding and multi-byte characters.\n      </li>\n      <li>\n\tC++ folder can fold on the \"} else {\" line of an if statement by setting\n\tfold.at.else property to 1.\n      </li>\n      <li>\n\tC++ lexer allows an extra set of keywords.\n      </li>\n      <li>\n\tProperty names and thus abbreviations may be non-ASCII.\n      </li>\n      <li>\n\tRemoved attempt to load a file when setting properties that was\n\tpart of an old scripting experiment.\n      </li>\n      <li>\n\tSciTE no longer warns about a file not existing when opening\n\tproperties files from the Options menu as there is a good chance\n\tthe user wants to create one.\n      </li>\n      <li>\n\tBug fixed with brace recognition in multi-byte encoded files where a partial\n\tcharacter matched a brace byte.\n      </li>\n      <li>\n\tMore protection against infinite loops or recursion with recursive property definitions.\n      </li>\n      <li>\n\tOn Windows, cursor will no longer disappear over margins in custom builds when\n\tcursor resource not present. The Windows default cursor is displayed instead.\n      </li>\n      <li>\n\tload.on.activate fixed in SciTE as was broken in 1.52.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite152.zip?download\">Release 1.52</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 17 April 2003.\n      </li>\n      <li>\n\tPango font support on GTK+ 2.\n\tUnicode input improved on GTK+ 2.\n      </li>\n      <li>\n\tHotspot style implemented in Scintilla.\n      </li>\n      <li>\n\tSmall up and down arrows can be displayed in calltips and the container\n\tis notified when the mouse is clicked on a calltip.\n\tNormal and selected calltip text colours can be set.\n      </li>\n      <li>\n\tPOSIX compatibility flag in Scintilla regular expression search\n\tinterprets bare ( and ) as tagged sections.\n      </li>\n      <li>\n\tError message lexer tightened to yield fewer false matches.\n\tRecognition of Lahey and Intel FORTRAN error formats.\n      </li>\n      <li>\n\tScintilla keyboard commands for moving to start and end of\n\tscreen lines rather than document lines, unless already there\n\twhere these keys move to the start or end of the document line.\n      </li>\n      <li>\n\tLine joining command.\n      </li>\n      <li>\n\tLexer for POV-Ray.\n      </li>\n      <li>\n\tCalltips on Windows are no longer clipped by the parent window.\n      </li>\n      <li>\n\tAutocompletion lists are cancelled when focus leaves their parent window.\n      </li>\n      <li>\n\tMove to next/previous empty line delimited paragraph key commands.\n      </li>\n      <li>\n\tSciTE hang fixed with recursive property definitions by placing limit\n\ton number of substitutions performed.\n      </li>\n      <li>\n\tSciTE Export as PDF reenabled and works.\n      </li>\n      <li>\n\tAdded loadsession: command line command to SciTE.\n      </li>\n      <li>\n\tSciTE option to quit application when last document closed.\n      </li>\n      <li>\n\tSciTE option to ask user if it is OK to reload a file that has been\n\tmodified outside SciTE.\n      </li>\n      <li>\n\tSciTE option to automatically save before running particular command tools\n\tor to ask user or to not save.\n      </li>\n      <li>\n\tSciTE on Windows 9x will write a Ctrl+Z to the process input pipe before\n\tclosing the pipe when running tool commands that take input.\n      </li>\n      <li>\n\tAdded a manifest resource to SciTE on Windows to enable Windows XP\n\tthemed UI.\n      </li>\n      <li>\n\tSciTE calltips handle nested calls and other situations better.\n      </li>\n      <li>\n\tCSS lexer improved.\n      </li>\n      <li>\n\tInterface to platform layer changed - Surface initialization now requires\n\ta WindowID parameter.\n      </li>\n      <li>\n\tBug fixed with drawing or measuring long pieces of text on Windows 9x\n\tby truncating the pieces.\n      </li>\n      <li>\n\tBug fixed with SciTE on GTK+ where a user shortcut for a visible character\n\tinserted the character as well as executing the command.\n      </li>\n      <li>\n\tBug fixed where primary selection on GTK+ was reset by\n\tScintilla during creation.\n      </li>\n      <li>\n\tBug fixed where SciTE would close immediately on startup\n\twhen using save.session.\n      </li>\n      <li>\n\tCrash fixed when entering '\\' in LaTeX file.\n      </li>\n      <li>\n\tHang fixed when '#' last character in VB file.\n      </li>\n      <li>\n\tCrash fixed in error message lexer.\n      </li>\n      <li>\n\tCrash fixed when searching for long regular expressions.\n      </li>\n      <li>\n\tPressing return when nothing selected in user list sends notification with\n\tempty text rather than random text.\n      </li>\n      <li>\n\tMouse debouncing disabled on Windows as it interfered with some\n\tmouse utilities.\n      </li>\n      <li>\n\tBug fixed where overstrike mode inserted before rather than replaced last\n\tcharacter in document.\n      </li>\n      <li>\n\tBug fixed with syntax highlighting of Japanese text.\n      </li>\n      <li>\n\tBug fixed in split lines function.\n      </li>\n      <li>\n\tCosmetic fix to SciTE tab bar on Windows when window resized.\n\tFocus sticks to either pane more consistently.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite151.zip?download\">Release 1.51</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 16 February 2003.\n      </li>\n      <li>\n\tTwo phase drawing avoids cutting off text that overlaps runs by drawing\n\tall the backgrounds of a line then drawing all the text transparently.\n\tSingle phase drawing is an option.\n      </li>\n      <li>\n\tScintilla method to split lines at a particular width by adding new line\n\tcharacters.\n      </li>\n      <li>\n\tThe character used in autocompletion lists to separate the text from the image\n\tnumber can be changed.\n      </li>\n      <li>\n\tThe scrollbar range will automatically expand when the caret is moved\n\tbeyond the current range.\n\tThe scroll bar is updated when SCI_SETXOFFSET is called.\n      </li>\n      <li>\n\tMouse cursors on GTK+ improved to be consistent with other applications\n\tand the Windows version.\n      </li>\n      <li>\n\tHorizontal scrollbar on GTK+ now disappears in wrapped mode.\n      </li>\n      <li>\n\tScintilla on GTK+ 2: mouse wheel scrolling, cursor over scrollbars, focus,\n\tand syntax highlighting now work.\n\tgtk_selection_notify avoided for compatibility with GTK+ 2.2.\n      </li>\n      <li>\n\tFold margin colours can now be set.\n      </li>\n      <li>\n\tSciTE can be built for GTK+ 2.\n      </li>\n      <li>\n\tSciTE can optionally preserve the undo history over an automatic file reload.\n      </li>\n      <li>\n\tTags can optionally be case insensitive in XML and HTML.\n      </li>\n      <li>\n\tSciTE on Windows handles input to tool commands in a way that should avoid\n\tdeadlock. Output from tools can be used to replace the selection.\n      </li>\n      <li>\n\tSciTE on GTK+ automatically substitutes '|' for '/' in menu items as '/'\n\tis used to define the menu hierarchy.\n      </li>\n      <li>\n\tOptional buffer number in SciTE title bar.\n      </li>\n      <li>\n\tCrash fixed in SciTE brace matching.\n      </li>\n      <li>\n\tBug fixed where automatic scrolling past end of document\n\tflipped back to the beginning.\n      </li>\n      <li>\n\tBug fixed where wrapping caused text to disappear.\n      </li>\n      <li>\n\tBug fixed on Windows where images in autocompletion lists were\n\tshown on the wrong item.\n      </li>\n      <li>\n\tCrash fixed due to memory bug in autocompletion lists on Windows.\n      </li>\n      <li>\n\tCrash fixed when double clicking some error messages.\n      </li>\n      <li>\n\tBug fixed in word part movement where sometimes no movement would occur.\n      </li>\n      <li>\n\tBug fixed on Windows NT where long text runs were truncated by\n\ttreating NT differently to 9x where there is a limitation.\n      </li>\n      <li>\n\tText in not-changeable style works better but there remain some cases where\n\tit is still possible to delete text protected this way.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite150.zip?download\">Release 1.50</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 24 January 2003.\n      </li>\n      <li>\n\tAutocompletion lists may have a per-item pixmap.\n      </li>\n      <li>\n\tAutocompletion lists allow Unicode text on Windows.\n      </li>\n      <li>\n\tScintilla documentation rewritten.\n      </li>\n      <li>\n\tAdditional DBCS encoding support in Scintilla on GTK+ primarily aimed at\n\tJapanese EUC encoding.\n      </li>\n      <li>\n\tCSS (Cascading Style Sheets) lexer added.\n      </li>\n      <li>\n\tdiff lexer understands some more formats.\n      </li>\n      <li>\n\tFold box feature is an alternative way to show the structure of code.\n      </li>\n      <li>\n\tAvenue lexer supports multiple keyword lists.\n      </li>\n      <li>\n\tThe caret may now be made invisible by setting the caret width to 0.\n      </li>\n      <li>\n\tPython folder attaches comments before blocks to the next block rather\n\tthan the previous block.\n      </li>\n      <li>\n\tSciTE openpath property on Windows searches a path for files that are\n\tthe subject of the Open Selected Filename command.\n      </li>\n      <li>\n        The localization file name can be changed with the locale.properties property.\n      </li>\n      <li>\n\tOn Windows, SciTE can pipe the result of a string expression into a command line tool.\n      </li>\n      <li>\n\tOn Windows, SciTE's Find dialog has a Mark All button.\n      </li>\n      <li>\n\tOn Windows, there is an Insert Abbreviation command that allows a choice from\n\tthe defined abbreviations and inserts the selection into the abbreviation at the\n\tposition of a '|'.\n      </li>\n      <li>\n\tMinor fixes to Fortran lexer.\n      </li>\n      <li>\n\tfold.html.preprocessor decides whether to fold &lt;? and ?&gt;.\n\tMinor improvements to PHP folding.\n      </li>\n      <li>\n\tMaximum number of keyword lists allowed increased from 6 to 9.\n      </li>\n      <li>\n\tDuplicate line command added with default assignment to Ctrl+D.\n      </li>\n      <li>\n\tSciTE sets $(Replacements) to the number of replacements made by the\n\tReplace All command. $(CurrentWord) is set to the word before the caret if the caret\n\tis at the end of a word.\n      </li>\n      <li>\n\tOpening a SciTE session now loads files in remembered order, sets the current file\n\tas remembered, and moves the caret to the remembered line.\n      </li>\n      <li>\n\tBugs fixed with printing on Windows where line wrapping was causing some text\n\tto not print.\n      </li>\n      <li>\n\tBug fixed with Korean Input Method Editor on Windows.\n      </li>\n      <li>\n\tBugs fixed with line wrap which would sometimes choose different break positions\n\tafter switching focus away and back.\n      </li>\n      <li>\n\tBug fixed where wheel scrolling had no effect on GTK+ after opening a fold.\n      </li>\n      <li>\n\tBug fixed with file paths containing non-ASCII characters on Windows.\n      </li>\n      <li>\n\tCrash fixed with printing on Windows after defining pixmap marker.\n      </li>\n      <li>\n\tCrash fixed in makefile lexer when first character on line was '='.\n      </li>\n      <li>\n\tBug fixed where local properties were not always being applied.\n      </li>\n      <li>\n\tCtrl+Keypad* fold command works on GTK+.\n      </li>\n      <li>\n\tHangs fixed in SciTE's Replace All command when replacing regular expressions '^'\n\tor '$'.\n      </li>\n      <li>\n\tSciTE monospace setting behaves more sensibly.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite149.zip?download\">Release 1.49</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 1 November 2002.\n      </li>\n      <li>\n\tUnicode supported on GTK+. To perform well, this added a font cache to GTK+\n\tand to make that safe, a mutex is used. The mutex requires the application to link in\n\tthe threading library by evaluating `glib-config --libs gthread`. A Unicode locale\n\tshould also be set up by a call like setlocale(LC_CTYPE, \"en_US.UTF-8\").\n\tscintilla_release_resources function added to release mutex.\n      </li>\n      <li>\n\tFORTRAN and assembler lexers added along with other support for these\n\tlanguages in SciTE.\n      </li>\n      <li>\n\tAda lexer improved handling of based numbers, identifier validity and attributes\n\tdistinguished from character literals.\n      </li>\n      <li>\n\tLua lexer handles block comments and a deep level of nesting for literal strings\n\tand block comments.\n      </li>\n      <li>\n\tErrorlist lexer recognizes PHP error messages.\n      </li>\n      <li>\n\tVariant of the C++ lexer with case insensitive keywords\n\tcalled cppnocase. Whitespace in preprocessor text handled more correctly.\n      </li>\n      <li>\n\tFolder added for Perl.\n      </li>\n      <li>\n\tCompilation with GCC 3.2 supported.\n      </li>\n      <li>\n\tMarkers can be pixmaps.\n      </li>\n      <li>\n\tLines are wrapped when printing.\n\tBug fixed which printed line numbers in different styles.\n      </li>\n      <li>\n\tText can be appended to end with AppendText method.\n      </li>\n      <li>\n\tChooseCaretX method added.\n      </li>\n      <li>\n\tVertical scroll bar can be turned off with SetVScrollBar method.\n      </li>\n      <li>\n\tSciTE Save All command saves all buffers.\n      </li>\n      <li>\n\tSciTE localization compares keys case insensitively to make translations more flexible.\n      </li>\n      <li>\n\tSciTE detects a utf-8 coding cookie \"coding: utf-8\" in first two\n\tlines and goes into Unicode mode.\n      </li>\n      <li>\n\tSciTE key bindings are definable.\n      </li>\n      <li>\n\tSciTE Find in Files dialog can display directory browser to\n\tchoose directory to search.\n      </li>\n      <li>\n\tSciTE enabling of undo and redo toolbar buttons improved.\n      </li>\n      <li>\n\tSciTE on Windows file type filters in open dialog sorted.\n      </li>\n      <li>\n\tFixed crashing bug when using automatic tag closing in XML or HTML.\n      </li>\n      <li>\n\tFixed bug on Windows causing very long (&gt;64K) lines to not display.\n      </li>\n      <li>\n\tFixed bug in backwards regular expression searching.\n      </li>\n      <li>\n\tFixed bug in calltips where wrong argument was highlighted.\n      </li>\n      <li>\n\tFixed bug in tab timmy feature when file has line feed line endings.\n      </li>\n      <li>\n\tFixed bug in compiling without INCLUDE_DEPRECATED_FEATURES\n\tdefined.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite148.zip?download\">Release 1.48</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 9 September 2002.\n      </li>\n      <li>\n\tImproved Pascal lexer with context sensitive keywords\n\tand separate folder which handles  //{ and //} folding comments and\n\t{$region} and {$end} folding directives.\n\tThe \"case\" statement now folds correctly.\n      </li>\n      <li>\n\tC++ lexer correctly handles comments on preprocessor lines.\n      </li>\n      <li>\n\tNew commands for moving to beginning and end of display lines when in line\n\twrap mode. Key bindings added for these commands.\n      </li>\n      <li>\n\tNew marker symbols that look like \">>>\" and \"...\" which can be used for\n\tinteractive shell prompts for Python.\n      </li>\n      <li>\n\tThe foreground and background colours of visible whitespace can be chosen\n\tindependent of the colours chosen for the lexical class of that whitespace.\n      </li>\n      <li>\n\tPer line data optimized by using an exponential allocation scheme.\n      </li>\n      <li>\n\tSciTE API file loading optimized.\n      </li>\n      <li>\n\tSciTE for GTK+ subsystem 2 documented. The exit status of commands\n\tis decoded into more understandable fields.\n      </li>\n      <li>\n\tSciTE find dialog remembers previous find string when there is no selection.\n\tFind in Selection button disabled when selection is rectangular as command\n\tdid not work.\n      </li>\n      <li>\n\tShift+Enter made equivalent to Enter to avoid users having to let go of\n\tthe shift key when typing. Avoids the possibility of entering single carriage\n\treturns in a file that contains CR+LF line ends.\n      </li>\n      <li>\n\tAutocompletion does not immediately disappear when the length parameter\n\tto SCI_AUTOCSHOW is 0.\n      </li>\n      <li>\n\tSciTE focuses on the editor pane when File | New executed and when the\n\toutput pane is closed with F8. Double clicking on a non-highlighted output\n\tpane line selects the word under the cursor rather than seeking the next\n\thighlighted line.\n      </li>\n      <li>\n\tSciTE director interface implements an \"askproperty\" command.\n      </li>\n      <li>\n\tSciTE's Export as LaTeX output improved.\n      </li>\n      <li>\n\tBetter choice of autocompletion displaying above the caret rather than\n\tbelow when that is more sensible.\n      </li>\n      <li>\n\tBug fixed where context menu would not be completely visible if invoked\n\twhen cursor near bottom or left of screen.\n      </li>\n      <li>\n\tCrashing bug fixed when displaying long strings on GTK+ caused failure of X server\n\tby displaying long text in segments.\n      </li>\n      <li>\n\tCrashing bug fixed on GTK+ when a Scintilla window was removed from its parent\n\tbut was still the selection owner.\n      </li>\n      <li>\n\tBug fixed on Windows in Unicode mode where not all characters on a line\n\twere displayed when that line contained some characters not in ASCII.\n      </li>\n      <li>\n\tCrashing bug fixed in SciTE on Windows with clearing output while running command.\n      </li>\n      <li>\n\tBug fixed in SciTE for GTK+ with command completion not detected when\n\tno output was produced by the command.\n      </li>\n      <li>\n\tBug fixed in SciTE for Windows where menus were not shown translated.\n      </li>\n      <li>\n\tBug fixed where words failed to display in line wrapping mode with visible\n\tline ends.\n      </li>\n      <li>\n\tBug fixed in SciTE where files opened from a session file were not closed.\n      </li>\n      <li>\n\tCosmetic flicker fixed when using Ctrl+Up and Ctrl+Down with some caret policies.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite147.zip?download\">Release 1.47</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 1 August 2002.\n      </li>\n      <li>\n\tSupport for GTK+ 2 in Scintilla. International input methods not supported\n\ton GTK+2.\n      </li>\n      <li>\n\tLine wrapping performance improved greatly.\n      </li>\n      <li>\n\tNew caret policy implementation that treats horizontal and vertical\n\tpositioning equivalently and independently. Old caret policy methods\n\tdeprecated and not all options work correctly with old methods.\n      </li>\n      <li>\n\tExtra fold points for C, C++, Java, ... for fold comments //{ .. //} and\n\t#if / #ifdef .. #endif and the #region .. #endregion feature of C#.\n      </li>\n      <li>\n\tScintilla method to find the height in pixels of a line. Currently returns the\n\tsame result for every line as all lines are same height.\n      </li>\n      <li>\n\tSeparate make file, scintilla_vc6.mak, for Scintilla to use Visual C++\n\tversion 6 since main makefile now assumes VS .NET.\n\tVS .NET project files available for combined Scintilla and\n\tSciTE in scite/boundscheck.\n      </li>\n      <li>\n\tSciTE automatically recognizes Unicode files based\n\ton their Byte Order Marks and switches to Unicode mode.\n\tOn Windows, where SciTE supports Unicode display, this\n\tallows display of non European characters.\n\tThe file is saved back into the same character encoding unless\n\tthe user decides to switch using the File | Encoding menu.\n      </li>\n      <li>\n\tHandling of character input changed so that a fillup character, typically '('\n\tdisplays a calltip when an autocompletion list was being displayed.\n      </li>\n      <li>\n\tMultiline strings lexed better for C++ and Lua.\n      </li>\n      <li>\n\tRegular expressions in JavaScript within hypertext files are lexed better.\n      </li>\n      <li>\n\tOn Windows, Scintilla exports a function called Scintilla_DirectFunction\n\tthat can be used the same as the function returned by GetDirectFunction.\n      </li>\n      <li>\n\tScintilla converts line endings of text obtained from the clipboard to\n\tthe current default line endings.\n      </li>\n      <li>\n\tNew SciTE property ensure.final.line.end can ensure that saved files\n\talways end with a new line as this is required by some tools.\n\tThe ensure.consistent.line.ends property ensures all line ends are the\n\tcurrent default when saving files.\n\tThe strip.trailing.spaces property now works on the buffer so the\n\tbuffer in memory and the file on disk are the same after a save is performed.\n      </li>\n      <li>\n\tThe SciTE expand abbreviation command again allows '|' characters\n\tin expansions to be quoted by using '||'.\n      </li>\n      <li>\n\tSciTE on Windows can send data to the find tool through standard\n\tinput rather than using a command line argument to avoid problems\n\twith quoting command line arguments.\n      </li>\n      <li>\n\tThe Stop Executing command in SciTE on Windows improved to send\n\ta Ctrl+Z character to the tool. Better messages when stopping a tool.\n      </li>\n      <li>\n\tAutocompletion can automatically \"fill up\" when one of a set of characters is\n\ttype with the autocomplete.&lt;lexer&gt;.fillups property.\n      </li>\n      <li>\n\tNew predefined properties in SciTE, SelectionStartColumn, SelectionStartLine,\n\tSelectionEndColumn, SelectionEndLine can be used to integrate with other\n\tapplications.\n      </li>\n      <li>\n\tEnvironment variables are available as properties in SciTE.\n      </li>\n      <li>\n\tSciTE on Windows keeps status line more current.\n      </li>\n      <li>\n\tAbbreviations work in SciTE on Linux when first opened.\n      </li>\n      <li>\n\tFile saving fixed in SciTE to ensure files are not closed when they can not be\n\tsaved because of file permissions. Also fixed a problem with buffers that\n\tcaused files to not be saved.\n      </li>\n      <li>\n\tSciTE bug fixed where monospace mode not remembered when saving files.\n\tSome searching options now remembered when switching files.\n      </li>\n      <li>\n\tSciTE on Linux now waits on child termination when it shuts a child down\n\tto avoid zombies.\n      </li>\n      <li>\n\tSciTE on Linux has a Print menu command that defaults to invoking a2ps.\n      </li>\n      <li>\n\tFixed incorrect highlighting of indentation guides in SciTE for Python.\n      </li>\n      <li>\n\tCrash fixed in Scintilla when calling GetText for 0 characters.\n      </li>\n      <li>\n\tExporting as LaTeX improved when processing backslashes and tabs\n\tand setting up font.\n      </li>\n      <li>\n\tCrash fixed in SciTE when exporting or copying as RTF.\n      </li>\n      <li>\n\tSciTE session loading fixed to handle more than 10 files in session.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite146.zip?download\">Release 1.46</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 10 May 2002.\n      </li>\n      <li>\n\tSet of lexers compiled into Scintilla can now be changed by adding and\n\tremoving lexer source files from scintilla/src and running LexGen.py.\n      </li>\n      <li>\n\tSCN_ZOOM notification provided by Scintilla when user changes zoom level.\n\tMethod to determine width of strings in pixels so that elements can be sized\n\trelative to text size.\n\tSciTE changed to keep line number column displaying a given\n\tnumber of characters.\n      </li>\n      <li>\n\tThe logical width of the document used to determine scroll bar range can be set.\n      </li>\n      <li>\n\tSetting to allow vertical scrolling to display last line at top rather than\n\tbottom of window.\n      </li>\n      <li>\n\tRead-only mode improved to avoid changing the selection in most cases\n\twhen a modification is attempted. Drag and drop cursors display correctly\n\tfor read-only in some cases.\n      </li>\n      <li>\n\tVisual C++ options in make files changed to suit Visual Studio .NET.\n      </li>\n      <li>\n\tScintilla.iface includes feature types for enumerations and lexers.\n      </li>\n      <li>\n\tLua lexer improves handling of literal strings and copes with nested literal strings.\n      </li>\n      <li>\n\tDiff lexer changed to treat lines starting with \"***\" similarly to \"---\".\n\tSymbolic names defined for lexical classes.\n      </li>\n      <li>\n\tnncrontab lexer improved.\n      </li>\n      <li>\n\tTurkish fonts (iso8859-9) supported on GTK+.\n      </li>\n      <li>\n\tAutomatic close tag feature for XML and HTML in SciTE.\n      </li>\n      <li>\n\tAutomatic indentation in SciTE improved.\n      </li>\n      <li>\n\tMaximum number of buffers available in SciTE increased. May be up to 100\n\talthough other restrictions on menu length limit the real maximum.\n      </li>\n      <li>\n\tSave a Copy command added to SciTE.\n      </li>\n      <li>\n\tExport as TeX command added to SciTE.\n      </li>\n      <li>\n\tExport as HTML command in SciTE respects Use Monospaced Font and\n\tbackground colour settings.\n      </li>\n      <li>\n\tCompilation problem on Solaris fixed.\n      </li>\n      <li>\n\tOrder of files displayed for SciTE's previous and next menu and key commands\n\tare now consistent.\n      </li>\n      <li>\n\tSaving of MRU in recent file changed so files open when SciTE quit\n\tare remembered.\n      </li>\n      <li>\n\tMore variants of ctags tags handled by Open Selected Filename in SciTE.\n      </li>\n      <li>\n\tJavaScript embedded in XML highlighted again.\n      </li>\n      <li>\n\tSciTE status bar updated after changing parameters in case they are being\n\tdisplayed in status bar.\n      </li>\n      <li>\n\tCrash fixed when handling some multi-byte languages.\n      </li>\n      <li>\n\tCrash fixed when replacing end of line characters.\n      </li>\n      <li>\n\tBug in SciTE fixed in multiple buffer mode where automatic loading\n\tturned on could lead to losing file contents.\n      </li>\n      <li>\n\tBug in SciTE on GTK+ fixed where dismissing dialogs with close box led to\n\tthose dialogs never being shown again.\n      </li>\n      <li>\n\tBug in SciTE on Windows fixed where position.tile with default positions\n\tled to SciTE being positioned off-screen.\n      </li>\n      <li>\n\tBug fixed in read-only mode, clearing all deletes contraction state data\n\tleading to it not being synchronized with text.\n      </li>\n      <li>\n\tCrash fixed in SciTE on Windows when tab bar displayed.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite145.zip?download\">Release 1.45</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 15 March 2002.\n      </li>\n      <li>\n\tLine layout cache implemented to improve performance by maintaining\n\tthe positioning of characters on lines. Can be set to cache nothing,\n\tthe line with the caret, the visible page or the whole document.\n      </li>\n      <li>\n\tSupport, including a new lexer, added for Matlab programs.\n      </li>\n      <li>\n\tLua folder supports folding {} ranges and compact mode.\n\tLua lexer styles floating point numbers in number style instead of\n\tsetting the '.' in operator style.\n\tUp to 6 sets of keywords.\n\tBetter support for [[ although only works well\n\twhen all on one line.\n      </li>\n      <li>\n\tPython lexer improved to handle floating point numbers that contain negative\n\texponents and that start with '.'.\n      </li>\n      <li>\n\tWhen performing a rectangular paste, the caret now remains at the\n\tinsertion point.\n      </li>\n      <li>\n\tOn Windows with a wheel mouse, page-at-a-time mode is recognized.\n      </li>\n      <li>\n\tRead-only mode added to SciTE with a property to initialize it and another property,\n\t$(ReadOnly) available to show this mode in the status bar.\n      </li>\n      <li>\n\tSciTE status bar can show the number of lines in the selection\n\twith the $(SelHeight) property.\n      </li>\n      <li>\n\tSciTE's \"Export as HTML\" command uses the current character set to produce\n\tcorrect output for non-Western-European character sets, such as Russian.\n      </li>\n      <li>\n\tSciTE's \"Export as RTF\" fixed to produce correct output when file contains '\\'.\n      </li>\n      <li>\n\tSciTE goto command accepts a column as well as a line.\n\tIf given a column, it selects the word at that column.\n      </li>\n      <li>\n\tSciTE's Build, Compile and Go commands are now disabled if no\n\taction has been assigned to them.\n      </li>\n      <li>\n\tThe Refresh button in the status bar has been removed from SciTE on Windows.\n      </li>\n      <li>\n\tBug fixed in line wrap mode where cursor up or down command did not work.\n      </li>\n      <li>\n\tSome styling bugs fixed that were due to a compilation problem with\n\tgcc and inline functions with same name but different code.\n      </li>\n      <li>\n\tThe way that lexers loop over text was changed to avoid accessing beyond the\n\tend or setting beyond the end. May fix some bugs and make the code safer but\n\tmay also cause new bugs.\n      </li>\n      <li>\n\tBug fixed in HTML lexer's handling of SGML.\n      </li>\n      <li>\n\tBug fixed on GTK+/X where lines wider than 32767 pixels did not display.\n      </li>\n      <li>\n\tSciTE bug fixed with file name generation for standard property files.\n      </li>\n      <li>\n\tSciTE bug fixed with Open Selected Filename command when used with\n\tfile name and line number combination.\n      </li>\n      <li>\n\tIn SciTE, indentation and tab settings stored with buffers so maintained correctly\n\tas buffers selected.\n\tThe properties used to initialize these settings can now be set separately for different\n\tfile patterns.\n      </li>\n      <li>\n\tThread safety improved on Windows with a critical section protecting the font\n\tcache and initialization of globals performed within Scintilla_RegisterClasses.\n\tNew Scintilla_ReleaseResources call provided to allow explicit freeing of resources\n\twhen statically bound into another application. Resources automatically freed\n\tin DLL version. The window classes are now unregistered as part of resource\n\tfreeing which fixes bugs that occurred in some containers such as Internet Explorer.\n      </li>\n      <li>\n\t'make install' fixed on Solaris.\n      </li>\n      <li>\n\tBug fixed that could lead to a file being opened twice in SciTE.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite144.zip?download\">Release 1.44</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 4 February 2002.\n      </li>\n      <li>\n\tCrashing bug fixed in Editor::Paint.\n      </li>\n      <li>\n\tLua lexer no longer treats '.' as a word character and\n\thandles 6 keyword sets.\n      </li>\n      <li>\n\tWordStartPosition and WordEndPosition take an onlyWordCharacters\n\targument.\n      </li>\n      <li>\n\tSciTE option for simplified automatic indentation which repeats\n\tthe indentation of the previous line.\n      </li>\n      <li>\n\tCompilation fix on Alpha because of 64 bit.\n      </li>\n      <li>\n\tCompilation fix for static linking.\n      </li>\n      <li>\n\tLimited maximum line length handled to 8000 characters as previous\n\tvalue of 16000 was causing stack exhaustion crashes for some.\n      </li>\n      <li>\n\tWhen whole document line selected, only the last display line gets\n\tthe extra selected rectangle at the right hand side rather than\n\tevery display line.\n      </li>\n      <li>\n\tCaret disappearing bug fixed for the case that the caret was not on the\n\tfirst display line of a document line.\n      </li>\n      <li>\n\tSciTE bug fixed where untitled buffer containing text was sometimes\n\tdeleted without chance to save.\n      </li>\n      <li>\n\tSciTE bug fixed where use.monospaced not working with\n\tmultiple buffers.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite143.zip?download\">Release 1.43</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 19 January 2002.\n      </li>\n      <li>\n\tLine wrapping robustness and performance improved in Scintilla.\n      </li>\n      <li>\n\tLine wrapping option added to SciTE for both edit and output panes.\n      </li>\n      <li>\n\tStatic linking on Windows handles cursor resource better.\n\tDocumentation of static linking improved.\n      </li>\n      <li>\n\tAutocompletion has an option to delete any word characters after the caret\n\tupon selecting an item.\n      </li>\n      <li>\n\tFOX version identified by PLAT_FOX in Platform.h.\n      </li>\n      <li>\n\tCalltips in SciTE use the calltip.&lt;lexer&gt;.word.characters setting to\n\tcorrectly find calltips for functions that include characters like '$' which\n\tis not normally considered a word character.\n      </li>\n      <li>\n\tSciTE has a command to show help on itself which gets hooked up to displaying\n\tSciTEDoc.html.\n      </li>\n      <li>\n\tSciTE option calltip.&lt;lexer&gt;.end.definition to display help text on a\n\tsecond line of calltip.\n      </li>\n      <li>\n\tFixed the handling of the Buffers menu on GTK+ to ensure current buffer\n\tindicated and no warnings occur.\n\tChanged some menu items on GTK+ version to be same as Windows version.\n      </li>\n      <li>\n\tuse.monospaced property for SciTE determines initial state of Use Monospaced Font\n\tsetting.\n      </li>\n      <li>\n\tThe SciTE Complete Symbol command now works when there are no word\n\tcharacters before the caret, even though it is slow to display the whole set of\n\tsymbols.\n      </li>\n      <li>\n\tFunction names removed from SciTE's list of PHP keywords. The full list of\n\tpredefined functions is available from another web site mentioned on the\n\tExtras page.\n      </li>\n      <li>\n\tCrashing bug at startup on GTK+ for some configurations fixed.\n      </li>\n      <li>\n\tCrashing bug on GTK+ on 64 bit platforms fixed.\n      </li>\n      <li>\n\tCompilation problem with some compilers fixed in GTK+.\n      </li>\n      <li>\n\tJapanese text entry improved on Windows 9x.\n      </li>\n      <li>\n        SciTE recent files directory problem on Windows when HOME and SciTE_HOME\n\tenvironment variables not set is now the directory of the executable.\n      </li>\n      <li>\n\tSession files no longer include untitled buffers.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite142.zip?download\">Release 1.42</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 24 December 2001.\n      </li>\n      <li>\n\tBetter localization support including context menus and most messages.\n\tTranslations of the SciTE user interface available for Bulgarian,\n\tFrench, German, Italian, Russian, and Turkish.\n      </li>\n      <li>\n\tCan specify a character to use to indicate control characters\n\trather than having them displayed as mnemonics.\n      </li>\n      <li>\n\tScintilla key command for backspace that will not delete line\n\tend characters.\n      </li>\n      <li>\n\tScintilla method to find start and end of words.\n      </li>\n      <li>\n\tSciTE on GTK+ now supports the load.on.activate and save.on.deactivate\n\tproperties in an equivalent way to the Windows version.\n      </li>\n      <li>\n\tThe output pane of SciTE on Windows is now interactive so command line\n\tutilities that prompt for input or confirmation can be used.\n      </li>\n      <li>\n\tSciTE on Windows can choose directory for a \"Find in Files\"\n\tcommand like the GTK+ version could.\n      </li>\n      <li>\n\tSciTE can now load a set of API files rather than just one file.\n      </li>\n      <li>\n\tElapsedTime class added to Platform for accurate measurement of durations.\n\tUsed for debugging and for showing the user how long commands take in SciTE.\n      </li>\n      <li>\n\tBaan lexer added.\n      </li>\n      <li>\n\tIn C++ lexer, document comment keywords no longer have to be at the start\n\tof the line.\n      </li>\n      <li>\n\tPHP lexer changed to match keywords case insensitively.\n      </li>\n      <li>\n\tMore shell keywords added.\n      </li>\n      <li>\n\tSciTE support for VoiceXML added to xml.properties.\n      </li>\n       <li>\n\tIn SciTE the selection is not copied to the find field of the Search and Replace\n\tdialogs if it contains end of line characters.\n      </li>\n      <li>\n\tSciTE on Windows has a menu item to decide whether to respond to other\n\tinstances which are performing their check.if.already.open check.\n      </li>\n      <li>\n\tSciTE accelerator key for Box Comment command changed to avoid problems\n\tin non-English locales.\n      </li>\n      <li>\n\tSciTE context menu includes Close command for the editor pane and\n\tHide command for the output pane.\n      </li>\n      <li>\n\toutput: command added to SciTE director interface to add text to the\n\toutput pane. The director interface can execute commands (such as tool\n\tcommands with subsystem set to 3) by sending a macro:run message.\n      </li>\n      <li>\n\tSciTE on GTK+ will defer to the Window Manager for position if position.left or\n\tposition.top not set and for size if position.width or position.height not set.\n      </li>\n      <li>\n\tSciTE on Windows has a position.tile property to place a second instance\n\tto the right of the first.\n      </li>\n      <li>\n\t Scintilla on Windows again supports EM_GETSEL and EM_SETSEL.\n      </li>\n      <li>\n\tProblem fixed in Scintilla on Windows where control ID is no longer cached\n\tas it could be changed by external code.\n      </li>\n      <li>\n\tProblems fixed in SciTE on Windows when finding any other open instances at\n\tstart up when check.if.already.open is true.\n      </li>\n      <li>\n\tBugs fixed in SciTE where command strings were not always having\n\tvariables evaluated.\n      </li>\n      <li>\n\tBugs fixed with displaying partial double-byte and Unicode characters\n\tin rectangular selections and at the edge when edge mode is EDGE_BACKGROUND.\n\tColumn numbers reported by GetColumn treat multiple byte characters as one column\n\trather than counting bytes.\n      </li>\n      <li>\n\tBug fixed with caret movement over folded lines.\n      </li>\n      <li>\n        Another bug fixed with tracking selection in secondary views when performing\n\tmodifications.\n      </li>\n      <li>\n\tHorizontal scrolling and display of long lines optimized.\n      </li>\n      <li>\n\tCursor setting in Scintilla on GTK+ optimized.\n      </li>\n      <li>\n\tExperimental changeable style attribute.\n\tSet to false to make text read-only.\n\tCurrently only stops caret from being within not-changeable\n\ttext and does not yet stop deleting a range that contains\n\tnot-changeable text.\n\tCan be used from SciTE by adding notchangeable to style entries.\n      </li>\n      <li>\n\tExperimental line wrapping.\n\tCurrently has performance and appearance problems.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite141.zip?download\">Release 1.41</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 6 November 2001.\n      </li>\n      <li>\n        Changed Platform.h to not include platform\theaders. This lessens likelihood and impact of\n\tname clashes from system headers and also speeds up compilation.\n\tRenamed DrawText to DrawTextNoClip to avoid name clash.\n      </li>\n      <li>\n        Changed way word functions work to treat a sequence of punctuation as\n\ta word. This is more sensible and also more compatible with other editors.\n      </li>\n      <li>\n        Cursor changes over the margins and selection on GTK+ platform.\n      </li>\n      <li>\n        SC_MARK_BACKGROUND is a marker that only changes the line's background colour.\n      </li>\n      <li>\n\tEnhanced Visual Basic lexer handles character date and octal literals,\n\tand bracketed keywords for VB.NET. There are two VB lexers, vb and vbscript\n\twith type indication characters like ! and $ allowed at the end of identifiers\n\tin vb but not vbscript. Lexer states now separate from those used for C++ and\n\tnames start with SCE_B.\n      </li>\n      <li>\n         Lexer added for Bullant language.\n      </li>\n      <li>\n         The horizontal scroll position, xOffset, is now exposed through the API.\n      </li>\n      <li>\n         The SCN_POSCHANGED notification is deprecated as it was causing confusion.\n\t Use SCN_UPDATEUI  instead.\n      </li>\n      <li>\n         Compilation problems fixed for some versions of gcc.\n      </li>\n      <li>\n        Support for WM_GETTEXT restored on Windows.\n      </li>\n      <li>\n        Double clicking on an autocompletion list entry works on GTK+.\n      </li>\n      <li>\n        Bug fixed with case insensitive sorts for autocompletion lists.\n      </li>\n      <li>\n        Bug fixed with tracking selection in secondary views when performing modifications.\n      </li>\n      <li>\n        SciTE's abbreviation expansion feature will now indent expansions to the current\n\tindentation level if indent.automatic is on.\n      </li>\n      <li>\n        SciTE allows setting up of parameters to commands from a dialog and can also\n       show this dialog automatically to prompt for arguments when running a command.\n      </li>\n      <li>\n        SciTE's Language menu (formerly Options | Use Lexer) is now defined by the\n\tmenu.language property rather than being hardcoded.\n      </li>\n      <li>\n        The user interface of SciTE can be localized to a particular language by editing\n\ta locale.properties file.\n      </li>\n      <li>\n        On Windows, SciTE will try to move to the front when opening a new file from\n\tthe shell and using check.if.already.open.\n      </li>\n      <li>\n        SciTE can display the file name and directory in the title bar in the form\n\t\"file @ directory\" when title.full.path=2.\n      </li>\n      <li>\n        The SciTE time.commands property reports the time taken by a command as well\n\tas its status when completed.\n      </li>\n      <li>\n        The SciTE find.files property is now a list separated by '|' characters and this list is\n\tadded into the Files pull down of the Find in Files dialog.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite140.zip?download\">Release 1.40</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 23 September 2001.\n      </li>\n      <li>\n\tRemoval of emulation of Win32 RichEdit control in core of Scintilla.\n\t<em>This change may be incompatible with existing client code.</em>\n\tSome emulation still done in Windows platform layer.\n      </li>\n      <li>\n\tSGML support in the HTML/XML lexer.\n      </li>\n      <li>\n\tSciTE's \"Stop Executing\" command will terminate GUI programs on\n\tWindows NT and Windows 2000.\n      </li>\n      <li>\n\tStyleContext class helps construct lexers that are simple and accurate.\n\tUsed in the C++, Eiffel, and Python lexers.\n      </li>\n      <li>\n\tClipboard operations in GTK+ version convert between platform '\\n' line endings and\n\tcurrently chosen line endings.\n      </li>\n      <li>\n\tAny character in range 0..255 can be used as a marker.\n\tThis can be used to support numbered bookmarks, for example.\n      </li>\n      <li>\n\tThe default scripting language for ASP can be set.\n      </li>\n      <li>\n\tNew lexer and other support for crontab files used with the nncron scheduler.\n      </li>\n      <li>\n\tFolding of Python improved.\n      </li>\n      <li>\n\tThe ` character is treated as a Python operator.\n      </li>\n      <li>\n\tLine continuations (\"\\\" at end of line) handled inside Python strings.\n      </li>\n      <li>\n\tMore consistent handling of line continuation ('\\' at end of line) in\n\tC++ lexer.\n\tThis fixes macro definitions that span more than one line.\n      </li>\n      <li>\n\tC++ lexer can understand Doxygen keywords in doc comments.\n      </li>\n      <li>\n\tSciTE on Windows allows choosing to open the \"open\" dialog on the directory\n\tof the current file rather than in the default directory.\n      </li>\n      <li>\n\tSciTE on Windows handles command line arguments in \"check.if.already.open\"\n\tcorrectly when the current directory of the new instance is different to the\n\talready open instance of SciTE.\n      </li>\n      <li>\n\t\"cwd\" command (change working directory) defined for SciTE director interface.\n      </li>\n      <li>\n\tSciTE \"Export As HTML\" produces better, more compliant, and shorter files.\n      </li>\n      <li>\n\tSciTE on Windows allows several options for determining default file name\n\tfor exported files.\n      </li>\n      <li>\n\tAutomatic indentation of Python in SciTE fixed.\n      </li>\n      <li>\n\tExported HTML can support folding.\n      </li>\n      <li>\n\tBug fixed in SCI_GETTEXT macro command of director interface.\n      </li>\n      <li>\n\tCursor leak fixed on GTK+.\n      </li>\n      <li>\n\tDuring SciTE shutdown, \"identity\" messages are no longer sent over the director interface.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite139.zip?download\">Release 1.39</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 22 August 2001.\n      </li>\n      <li>\n\tWindows version requires msvcrt.dll to be available so will not work\n\ton original Windows 95 version 1. The msvcrt.dll file is installed\n\tby almost everything including Internet Explorer so should be available.\n      </li>\n      <li>\n\tFlattened tree control style folding margin. The SciTE fold.plus option is\n\tnow fold.symbols and has more values for the new styles.\n      </li>\n      <li>\n\tMouse dwell events are generated when the user holds the mouse steady\n\tover Scintilla.\n      </li>\n      <li>\n      PositionFromPointClose is like PositionFromPoint but returns\n      INVALID_POSITION when point outside window or after end of line.\n      </li>\n      <li>\n      Input of Hungarian and Russian characters in GTK+ version works by\n      truncating input to 8 bits if in the range of normal characters.\n      </li>\n      <li>\n      Better choices for font descriptors on GTK+ for most character sets.\n      </li>\n      <li>\n      GTK+ Scintilla is destroyed upon receiving destroy signal rather than\n      destroy_event signal.\n      </li>\n      <li>\n      Style setting that force upper or lower case text.\n      </li>\n      <li>\n      Case-insensitive autocompletion lists work correctly.\n      </li>\n      <li>\n      Keywords can be prefix based so ^GTK_ will treat all words that start\n      with GTK_ as keywords.\n      </li>\n      <li>\n      Horizontal scrolling can be jumpy rather than gradual.\n      </li>\n      <li>\n      GetSelText places a '\\0' in the buffer if the selection is empty..\n      </li>\n      <li>\n      EnsureVisible split into two methods EnsureVisible which will not scroll to show\n      the line and EnsureVisibleEnforcePolicy which may scroll.\n      </li>\n      <li>\n      Python folder has options to fold multi-line comments and triple quoted strings.\n      </li>\n      <li>\n      C++ lexer handles keywords before '.' like \"this.x\" in Java as keywords.\n      Compact folding mode option chooses whether blank lines after a structure are\n      folded with that structure. Second set of keywords with separate style supported.\n      </li>\n      <li>\n      Ruby lexer handles multi-line comments.\n      </li>\n      <li>\n      VB has folder.\n      </li>\n      <li>\n      PHP lexer has an operator style, handles \"&lt;?\" and \"?&gt;\" inside strings\n      and some comments.\n      </li>\n      <li>\n      TCL lexer which is just an alias for the C++ lexer so does not really\n      understand TCL syntax.\n      </li>\n      <li>\n      Error lines lexer has styles for Lua error messages and .NET stack traces.\n      </li>\n      <li>\n      Makefile lexer has a target style.\n      </li>\n      <li>\n      Lua lexer handles some [[]] string literals.\n      </li>\n      <li>\n      HTML and XML lexer have a SCE_H_SGML state for tags that\n      start with \"&lt;!\".\n      </li>\n      <li>\n      Fixed Scintilla bugs with folding. When modifications were performed near\n      folded regions sometimes no unfolding occurred when it should have. Deleting a\n      fold causing character sometimes failed to update fold information correctly.\n      </li>\n      <li>\n      Better support for Scintilla on GTK+ for Win32 including separate\n      PLAT_GTK_WIN32 definition and correct handling of rectangular selection\n      with clipboard operations.\n      </li>\n      <li>\n      SciTE has a Tools | Switch Pane (Ctrl+F6) command to switch focus between\n      edit and output panes.\n      </li>\n      <li>\n      SciTE option output.scroll allows automatic scrolling of output pane to\n      be turned off.\n      </li>\n      <li>\n      Commands can be typed into the SciTE output pane similar to a shell window.\n      </li>\n      <li>\n      SciTE properties magnification and output magnification set initial zoom levels.\n      </li>\n      <li>\n      Option for SciTE comment block command to place comments at start of line.\n      </li>\n      <li>\n       SciTE for Win32 has an option to minimize to the tray rather than the task bar.\n      </li>\n      <li>\n      Close button on SciTE tool bar for Win32.\n      </li>\n      <li>\n      SciTE compiles with GCC 3.0.\n      </li>\n      <li>\n      SciTE's automatic indentation of C++ handles braces without preceding keyword\n      correctly.\n      </li>\n      <li>\n      Bug fixed with GetLine method writing past the end of where it should.\n      </li>\n      <li>\n      Bug fixed with mouse drag automatic scrolling when some lines were folded.\n      </li>\n      <li>\n      Bug fixed because caret XEven setting was inverted.\n      </li>\n      <li>\n      Bug fixed where caret was initially visible even though window was not focussed.\n      </li>\n      <li>\n      Bug fixed where some file names could end with \"\\\\\" which caused slow\n      downs on Windows 9x.\n      </li>\n      <li>\n      On Win32, SciTE Replace dialog starts with focus on replacement text.\n      </li>\n      <li>\n      SciTE Go to dialog displays correct current line.\n      </li>\n      <li>\n      Fixed bug with SciTE opening multiple files at once.\n      </li>\n      <li>\n      Fixed bug with Unicode key values reported to container truncated.\n      </li>\n      <li>\n      Fixed bug with unnecessary save point notifications.\n      </li>\n      <li>\n      Fixed bugs with indenting and unindenting at start of line.\n      </li>\n      <li>\n      Monospace Font setting behaves more consistently.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite138.zip?download\">Release 1.38</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 23 May 2001.\n      </li>\n      <li>\n\tLoadable lexer plugins on Windows.\n      </li>\n      <li>\n\tRuby lexer and support.\n      </li>\n      <li>\n\tLisp lexer and support.\n      </li>\n      <li>\n\tEiffel lexer and support.\n      </li>\n      <li>\n\tModes for better handling of Tab and BackSpace keys within\n\tindentation. Mode to avoid autocompletion list cancelling when\n\tthere are no viable matches.\n      </li>\n      <li>\n\tReplaceTarget replaced with two calls ReplaceTarget\n\t(which is incompatible with previous ReplaceTarget) and\n\tReplaceTargetRE. Both of these calls have a count first\n\tparameter which allows using strings containing nulls.\n\tSearchInTarget and SetSearchFlags functions allow\n\tspecifying a search in several simple steps which helps\n\tsome clients which can not create structs or pointers easily.\n      </li>\n      <li>\n\tAsian language input through an Input Method Editor works\n\ton Windows 2000.\n      </li>\n      <li>\n\tOn Windows, control characters can be entered through use of\n\tthe numeric keypad in conjunction with the Alt key.\n      </li>\n      <li>\n\tDocument memory allocation changed to grow exponentially\n\twhich reduced time to load a 30 Megabyte file from\n\t1000 seconds to 25. Change means more memory may be used.\n      </li>\n      <li>\n\tWord part movement keys now handled in Scintilla rather than\n\tSciTE.\n      </li>\n      <li>\n\tRegular expression '^' and '$' work more often allowing insertion\n\tof text at start or end of line with a replace command.\n\tBackslash quoted control characters \\a, \\b, \\f, \\t, and \\v\n\trecognized within sets.\n      </li>\n      <li>\n\tSession files for SciTE.\n      </li>\n      <li>\n\tExport as PDF command hidden in SciTE as it often failed.\n\tCode still present so can be turned on by those willing to cope.\n      </li>\n      <li>\n\tBug fixed in HTML lexer handling % before &gt; as end ASP\n\teven when no start ASP encountered.\n        Bug fixed when scripts ended with a quoted string and\n        end tag was not seen.\n      </li>\n      <li>\n\tBug fixed on Windows where context menu key caused menu to\n\tappear in corner of screen rather than within window.\n      </li>\n      <li>\n\tBug fixed in SciTE's Replace All command not processing\n\twhole file when replace string longer than search string.\n      </li>\n      <li>\n\tBug fixed in SciTE's MRU list repeating entries if Ctrl+Tab\n\tused when all entries filled.\n      </li>\n      <li>\n\tConvertEOLs call documentation fixed.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite137.zip?download\">Release 1.37</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 17 April 2001.\n      </li>\n      <li>\n\tBug fixed with scroll bars being invisible on GTK+ 1.2.9.\n      </li>\n      <li>\n\tScintilla and SciTE support find and replace using simple regular\n\texpressions with tagged expressions. SciTE supports C '\\' escapes\n\tin the Find and Replace dialogs.\n\tReplace in Selection available in SciTE.\n      </li>\n      <li>\n\tScintilla has a 'target' feature for replacing code rapidly without\n\tcausing display updates.\n      </li>\n      <li>\n\tScintilla and SciTE on GTK+ support file dropping from file managers\n\tsuch as Nautilus and gmc. Files or other URIs dropped on Scintilla\n\tresult in a URIDropped notification.\n      </li>\n      <li>\n\tLexers may have separate Lex and Fold functions.\n      </li>\n      <li>\n\tLexer infrastructure improved to allow for plug in lexers and for referring\n\tto lexers by name rather than by ID.\n      </li>\n      <li>\n\tAda lexer and support added.\n      </li>\n      <li>\n\tOption in both Scintilla and SciTE to treat both left and right margin\n\tas equally important when repositioning visible area in response to\n\tcaret movement. Default is to prefer visible area positioning which\n\tminimizes the horizontal scroll position thus favouring the left margin.\n      </li>\n      <li>\n\tCaret line highlighting.\n      </li>\n      <li>\n\tCommands to delete from the caret to the end of line and\n\tfrom the caret to the beginning of line.\n      </li>\n      <li>\n\tSciTE has commands for inserting and removing block comments and\n\tfor inserting stream comments.\n      </li>\n      <li>\n\tSciTE Director interface uses C++ '\\' escapes to send control characters.\n      </li>\n      <li>\n\tSciTE Director interface adds more commands including support for macros.\n      </li>\n      <li>\n\tSciTE has menu options for recording and playing macros which are visible\n\twhen used with a companion program that supports these features.\n      </li>\n      <li>\n\tSciTE has an Expand Abbreviation command.\n\tAbbreviations are stored in a global abbrev.properties file.\n      </li>\n      <li>\n\tSciTE has a Full Screen command to switch between a normal window\n\tsize and using the full screen. On Windows, the menu bar can be turned\n\toff when in full screen mode.\n      </li>\n      <li>\n\tSciTE has a Use monospaced font command to switch between the normal\n\tset of fonts and one size of a particular fixed width font.\n      </li>\n      <li>\n\tSciTE's use of tabs can be controlled for particular file names\n\tas well as globally.\n      </li>\n      <li>\n\tThe contents of SciTE's status bar can be defined by a property and\n\tinclude variables. On Windows, several status bar definitions can be active\n\twith a click on the status bar cycling through them.\n      </li>\n      <li>\n\tCopy as RTF command in SciTE on Windows to allow pasting\n\tstyled text into word processors.\n      </li>\n      <li>\n\tSciTE can allow the use of non-alphabetic characters in\n\tComplete Symbol lists and can automatically display this autocompletion\n\tlist when a trigger character such as '.' is typed.\n\tComplete word can be set to pop up when the user is typing a word and\n\tthere is only one matching word in the document.\n      </li>\n      <li>\n\tSciTE lists the imported properties files on a menu to allow rapid\n\taccess to them.\n      </li>\n      <li>\n\tSciTE on GTK+ improvements to handling accelerator keys and focus\n\tin dialogs. Message boxes respond to key presses without the Alt key as\n\tthey have no text entries to accept normal keystrokes.\n      </li>\n      <li>\n\tSciTE on GTK+ sets the application icon.\n      </li>\n      <li>\n\tSciTE allows setting the colours used to indicate the current\n\terror line.\n      </li>\n      <li>\n\tVariables within PHP strings have own style. Keyword list updated.\n      </li>\n      <li>\n\tKeyword list for Lua updated for Lua 4.0.\n      </li>\n      <li>\n\tBug fixed in rectangular selection where rectangle still appeared\n\tselected after using cursor keys to move caret.\n      </li>\n      <li>\n\tBug fixed in C++ lexer when deleting a '{' controlling a folded range\n\tled to that range becoming permanently invisible.\n      </li>\n      <li>\n\tBug fixed in Batch lexer where comments were not recognized.\n      </li>\n      <li>\n\tBug fixed with undo actions coalescing into steps incorrectly.\n      </li>\n      <li>\n\tBug fixed with Scintilla on GTK+ positioning scroll bars 1 pixel\n\tover the Scintilla window leading to their sides being chopped off.\n      </li>\n      <li>\n\tBugs fixed in SciTE when doing some actions led to the start\n\tor end of the file being displayed rather than the current location.\n      </li>\n      <li>\n\tAppearance of calltips fixed to look like document text including\n\tany zoom factor. Positioned to be outside current line even when\n\tmultiple fonts and sizes used.\n      </li>\n      <li>\n\tBug fixed in Scintilla macro support where typing Enter caused both a newline\n\tcommand and newline character insertion to be recorded.\n      </li>\n      <li>\n\tBug fixed in SciTE on GTK+ where focus was moving\n\tbetween widgets incorrectly.\n      </li>\n      <li>\n\tBug fixed with fold symbols sometimes not updating when\n\tthe text changed.\n      </li>\n      <li>\n\tBugs fixed in SciTE's handling of folding commands.\n      </li>\n      <li>\n\tDeprecated undo collection enumeration removed from API.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite136.zip?download\">Release 1.36</a>\n    </h3>\n    <ul>\n      <li>\n\tReleased on 1 March 2001.\n      </li>\n      <li>\n\tScintilla supports GTK+ on Win32.\n      </li>\n      <li>\n\tSome untested work on making Scintilla and SciTE 64 bit compatible.\n\tFor users on GTK+ this requires including Scintilla.h before\n\tScintillaWidget.h.\n      </li>\n      <li>\n\tHTML lexer allows folding HTML.\n      </li>\n      <li>\n\tNew lexer for Avenue files which are used in the ESRI ArcView GIS.\n      </li>\n      <li>\n\tDOS Batch file lexer has states for '@', external commands, variables and\n\toperators.\n      </li>\n      <li>\n\tC++ lexer can fold comments of /* .. */ form.\n      </li>\n      <li>\n\tBetter disabling of pop up menu items in Scintilla when in read-only mode.\n      </li>\n      <li>\n\tStarting to move to Doxygen compatible commenting.\n      </li>\n      <li>\n\tDirector interface on Windows enables another application to control SciTE.\n      </li>\n      <li>\n\tOpening SciTE on Windows 9x sped up greatly for some cases.\n      </li>\n      <li>\n\tThe command.build.directory property allows SciTE to run the build\n\tcommand in a different directory to the source files.\n      </li>\n      <li>\n\tSciTE on Windows allows setting foreground and background colours\n\tfor printed headers and footers.\n      </li>\n      <li>\n\tBug fixed in finding calltips in SciTE which led to no calltips for some identifiers.\n      </li>\n      <li>\n\tDocumentation added for lexers and for the extension and director interfaces.\n      </li>\n      <li>\n\tSciTE menus rearranged with new View menu taking over some of the items that\n\twere under the Options menu. Clear All Bookmarks command added.\n      </li>\n      <li>\n\tClear Output command in SciTE.\n      </li>\n      <li>\n\tSciTE on Windows gains an Always On Top command.\n      </li>\n      <li>\n\tBug fixed in SciTE with attempts to define properties recursively.\n      </li>\n      <li>\n\tBug fixed in SciTE properties where only one level of substitution was done.\n      </li>\n      <li>\n\tBug fixed in SciTE properties where extensions were not being\n\tmatched in a case insensitive manner.\n      </li>\n      <li>\n\tBug fixed in SciTE on Windows where the Go to dialog displays the correct\n\tline number.\n      </li>\n      <li>\n\tIn SciTE, if fold.on.open set then switching buffers also performs fold.\n      </li>\n      <li>\n\tBug fixed in Scintilla where ensuring a line was visible in the presence of folding\n\toperated on the document line instead of the visible line.\n      </li>\n      <li>\n\tSciTE command line processing modified to operate on arguments in order and in\n\ttwo phases. First any arguments before the first file name are processed, then the\n\tUI is opened, then the remaining arguments are processed. Actions defined for the\n\tDirector interface (currently only \"open\") may also be used on the command line.\n\tFor example, \"SciTE -open:x.txt\" will start SciTE and open x.txt.\n      </li>\n      <li>\n\tNumbered menu items SciTE's Buffers menu and the Most Recently Used portion\n\tof the File menu go from 1..0 rather than 0..9.\n      </li>\n      <li>\n\tThe tab bar in SciTE for Windows has numbers.\n\tThe tab.hide.one option hides the tab bar until there is more than one buffer open.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite135.zip?download\">Release 1.35</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 29 January 2001.\n      </li>\n      <li>\n        Rewritten and simplified widget code for the GTK+ version to enhance\n        solidity and make more fully compliant with platform norms. This includes more\n        normal handling of keystrokes so they are forwarded to containers correctly.\n      </li>\n      <li>\n        User defined lists can be shown.\n      </li>\n      <li>\n        Many fixes to the Perl lexer.\n      </li>\n      <li>\n        Pascal lexer handles comments more correctly.\n      </li>\n      <li>\n        C/C++/Java/JavaScript lexer has a state for line doc comments.\n      </li>\n      <li>\n        Error output lexer understands Sun CC messages.\n      </li>\n      <li>\n        Make file lexer has variable, preprocessor, and operator states.\n      </li>\n      <li>\n        Wider area given to an italics character that is at the end of a line to prevent it\n\tbeing cut off.\n      </li>\n      <li>\n        Call to move the caret inside the currently visible area.\n      </li>\n      <li>\n        Paste Rectangular will space fill on the left hand side of the pasted text as\n\tneeded to ensure it is kept rectangular.\n      </li>\n      <li>\n        Cut and Paste Rectangular does nothing in read-only mode.\n      </li>\n      <li>\n        Undo batching changed so that a paste followed by typing creates two undo actions..\n      </li>\n      <li>\n        A \"visibility policy\" setting for Scintilla determines which range of lines are displayed\n\twhen a particular line is moved to. Also exposed as a property in SciTE.\n      </li>\n      <li>\n        SciTE command line allows property settings.\n      </li>\n      <li>\n        SciTE has a View Output command to hide or show the output pane.\n      </li>\n      <li>\n        SciTE's Edit menu has been split in two with searching commands moved to a\n\tnew Search menu. Find Previous and Previous Bookmark are in the Search menu.\n      </li>\n      <li>\n        SciTE on Windows has options for setting print margins, headers and footers.\n      </li>\n      <li>\n        SciTE on Windows has tooltips for toolbar.\n      </li>\n      <li>\n        SciTE on GTK+ has properties for setting size of file selector.\n      </li>\n      <li>\n        Visual and audio cues in SciTE on Windows enhanced.\n      </li>\n      <li>\n        Fixed performance problem in SciTE for GTK+ by dropping the extra 3D\n        effect on the content windows.\n      </li>\n      <li>\n        Fixed problem in SciTE where choosing a specific lexer then meant\n        that no lexer was chosen when files opened.\n      </li>\n      <li>\n        Default selection colour changed to be visible on low colour displays.\n      </li>\n      <li>\n        Fixed problems with automatically reloading changed documents in SciTE on\n        Windows.\n      </li>\n      <li>\n        Fixed problem with uppercase file extensions in SciTE.\n      </li>\n      <li>\n        Fixed some problems when using characters >= 128, some of which were being\n        incorrectly treated as spaces.\n      </li>\n      <li>\n        Fixed handling multiple line tags, non-inline scripts, and XML end tags /&gt; in HTML/XML lexer.\n      </li>\n      <li>\n        Bookmarks in SciTE no longer disappear when switching between buffers.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite134.zip?download\">Release 1.34</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 28 November 2000.\n      </li>\n      <li>\n        Pascal lexer.\n      </li>\n      <li>\n        Export as PDF in SciTE.\n      </li>\n      <li>\n        Support for the OpenVMS operating system in SciTE.\n      </li>\n      <li>\n        SciTE for GTK+ can check for another instance of SciTE\n\tediting a file and switch to it rather than open a second instance\n\ton one file.\n      </li>\n      <li>\n        Fixes to quoting and here documents in the Perl lexer.\n      </li>\n      <li>\n        SciTE on Windows can give extra visual and audio cues when a\n\twarning is shown or find restarts from beginning of file.\n      </li>\n      <li>\n        Open Selected Filename command in SciTE. Also understands some\n\twarning message formats.\n      </li>\n      <li>\n        Wider area for line numbers when printing.\n      </li>\n      <li>\n        Better scrolling performance on GTK+.\n      </li>\n      <li>\n        Fixed problem where rectangles with negative coordinates were\n\tinvalidated leading to trouble with platforms that use\n\tunsigned coordinates.\n      </li>\n      <li>\n        GTK+ Scintilla uses more compliant signalling code so that keyboard\n\tevents should propagate to containers.\n      </li>\n      <li>\n        Bug fixed with opening full or partial paths.\n      </li>\n      <li>\n        Improved handling of paths in error messages in SciTE.\n      </li>\n      <li>\n        Better handling of F6 in SciTE.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite133.zip?download\">Release 1.33</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 6 November 2000.\n      </li>\n      <li>\n        XIM support for the GTK+ version of Scintilla ensures that more non-English\n        characters can be typed.\n      </li>\n      <li>\n        Caret may be 1, 2, or 3 pixels wide.\n      </li>\n      <li>\n        Cursor may be switched to wait image during lengthy processing.\n      </li>\n      <li>\n        Scintilla's internal focus flag is exposed for clients where focus is handled in\n        complex ways.\n      </li>\n      <li>\n        Error status defined for Scintilla to hold indication that an operation failed and the reason\n        for that failure. No detection yet implemented but clients may start using the interface\n        so as to be ready for when it does.\n      </li>\n      <li>\n        Context sensitive help in SciTE.\n      </li>\n      <li>\n        CurrentWord property available in SciTE holding the value of the word the\n        caret is within or near.\n      </li>\n      <li>\n        Apache CONF file lexer.\n      </li>\n      <li>\n        Changes to Python lexer to allow 'as' as a context sensitive keyword and the\n        string forms starting with u, r, and ur to be recognized.\n      </li>\n      <li>\n        SCN_POSCHANGED notification now working and SCN_PAINTED notification added.\n      </li>\n      <li>\n        Word part movement commands for cursoring between the parts of reallyLongCamelIdentifiers and\n        other_ways_of_making_words.\n      </li>\n      <li>\n        When text on only one line is selected, Shift+Tab moves to the previous tab stop.\n      </li>\n      <li>\n        Tab control available for Windows version of SciTE listing all the buffers\n        and making it easy to switch between them.\n      </li>\n      <li>\n        SciTE can be set to automatically determine the line ending type from the contents of a\n        file when it is opened.\n      </li>\n      <li>\n        Dialogs in GTK+ version of SciTE made more modal and have accelerator keys.\n      </li>\n      <li>\n        Find in Files command in GTK+ version of SciTE allows choice of directory.\n      </li>\n      <li>\n        On Windows, multiple files can be opened at once.\n      </li>\n      <li>\n        SciTE source broken up into more files.\n      </li>\n      <li>\n        Scintilla headers made safe for C language, not just C++.\n      </li>\n      <li>\n        New printing modes - force background to white and force default background to white.\n      </li>\n      <li>\n        Automatic unfolding not occurring when Enter pressed at end of line bug fixed.\n      </li>\n      <li>\n        Bugs fixed in line selection.\n      </li>\n      <li>\n        Bug fixed with escapes in PHP strings in the HTML lexer.\n      </li>\n      <li>\n        Bug fixed in SciTE for GTK+ opening files when given full paths.\n      </li>\n      <li>\n        Bug fixed in autocompletion where user backspaces into existing text.\n      </li>\n      <li>\n        Bugs fixed in opening files and ensuring they are saved before running.\n        A case bug also fixed here.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite132.zip?download\">Release 1.32</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 8 September 2000.\n      </li>\n      <li>\n        Fixes bugs in complete word and related code. Protection against a bug when\n\treceiving a bad argument.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite131.zip?download\">Release 1.31</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 6 September 2000.\n      </li>\n      <li>\n        Scintilla is available as a COM control from the scintillactrl module in CVS.\n      </li>\n      <li>\n        Style setting to underline text. Exposed in SciTE as \"underlined\".\n      </li>\n      <li>\n        Style setting to make text invisible.\n      </li>\n      <li>\n        SciTE has an extensibility interface that can be used to implement features such as\n        a scripting language or remote control. An example use of this is the extlua module\n        available from CVS which allows SciTE to be scripted in Lua.\n      </li>\n      <li>\n        Many minor fixes to all of the lexers.\n      </li>\n      <li>\n        New lexer for diff and patch files.\n      </li>\n      <li>\n        Error message lexer understands Perl error messages.\n      </li>\n      <li>\n        C/C++/Java lexer now supports C#, specifically verbatim strings and\n\t@ quoting of identifiers that are the same as keywords. SciTE has\n\ta set of keywords for C# and a build command set up for C#.\n      </li>\n      <li>\n        Scintilla property to see whether in overtype or insert state.\n      </li>\n      <li>\n         PosChanged notification fired when caret moved.\n      </li>\n      <li>\n        Comboboxes in dialogs in SciTE on Windows can be horizontally scrolled.\n      </li>\n      <li>\n        Autocompletion and calltips can treat the document as case sensitive or\n        case insensitive.\n      </li>\n      <li>\n        Autocompletion can be set to automatically choose the only\n\telement in a single element list.\n      </li>\n      <li>\n        Set of characters that automatically complete an autocompletion list\n\tcan be set.\n      </li>\n      <li>\n        SciTE command to display calltip - useful when dropped because of\n\tediting.\n      </li>\n      <li>\n        SciTE has a Revert command to go back to the last saved version.\n      </li>\n      <li>\n        SciTE has an Export as RTF command. Save as HTML is renamed\n\tto Export as HTML and is located on the Export sub menu.\n      </li>\n      <li>\n        SciTE command \"Complete Word\" searches document for any\n\twords starting with characters before caret.\n      </li>\n      <li>\n        SciTE options for changing aspects of the formatting of files exported\n\tas HTML or RTF.\n      </li>\n      <li>\n        SciTE \"character.set\" option for choosing the character\n\tset for all fonts.\n      </li>\n      <li>\n        SciTE has a \"Toggle all folds\" command.\n      </li>\n      <li>\n        The makefiles have changed. The makefile_vc and\n\tmakefile_bor files in scintilla/win32 and scite/win32 have been\n\tmerged into scintilla/win32/scintilla.mak and scite/win32/scite.mak.\n\tDEBUG may be defined for all make files and this will turn on\n\tassertions and for some make files will choose other debugging\n\toptions.\n      </li>\n      <li>\n         To make debugging easier and allow good use of BoundsChecker\n\t there is a Visual C++ project file in scite/boundscheck that builds\n\t all of Scintilla and SciTE into one executable.\n      </li>\n      <li>\n         The size of the SciTE output window can be set with the\n\t output.horizontal.size and output.vertical.size settings.\n      </li>\n      <li>\n         SciTE status bar indicator for insert or overwrite mode.\n      </li>\n      <li>\n        Performance improvements to autocompletion and calltips.\n      </li>\n      <li>\n        A caret redraw problem when undoing is fixed.\n      </li>\n      <li>\n        Crash with long lines fixed.\n      </li>\n      <li>\n        Bug fixed with merging markers when lines merged.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite130.zip?download\">Release 1.30</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 26 July 2000.\n      </li>\n      <li>\n        Much better support for PHP which is now an integral part of the HTML support.\n      </li>\n      <li>\n        Start replacement of Windows-specific APIs with cross platform APIs.\n        In 1.30, the new APIs are introduced but the old APIs are still available.\n        For the GTK+ version, may have to include \"WinDefs.h\" explicitly to\n        use the old APIs.\n      </li>\n      <li>\n        \"if\" and \"import\" statements in SciTE properties files allows modularization into\n        language-specific properties files and choices based upon platform.\n        This means that SciTE is delivered with 9 language-specific properties files\n        as well as the standard SciTEGlobal.properties file.\n      </li>\n      <li>\n        Much lower resource usage on Windows 9x.\n      </li>\n      <li>\n        \"/p\" option in SciTE on Windows for printing a file and then exiting.\n      </li>\n      <li>\n        Options for printing with inverted brightness (when the screen is set to use\n        a dark background) and to force black on white printing.\n      </li>\n      <li>\n        Option for printing magnified or miniaturized from screen settings.\n      </li>\n      <li>\n        In SciTE, Ctrl+F3 and Ctrl+Shift+F3 find the selection in the forwards and backwards\n        directions respectively.\n      </li>\n      <li>\n        Auto-completion lists may be set to cancel when the cursor goes before\n        its start position or before the start of string being completed.\n      </li>\n      <li>\n        Auto-completion lists automatically size more sensibly.\n      </li>\n      <li>\n        SCI_CLEARDOCUMENTSTYLE zeroes all style bytes, ensures all\n        lines are shown and deletes all folding information.\n      </li>\n      <li>\n        On Windows, auto-completion lists are visually outdented rather than indented.\n      </li>\n      <li>\n        Close all command in SciTE.\n      </li>\n      <li>\n        On Windows multiple files can be dragged into SciTE.\n      </li>\n      <li>\n        When saving a file, the SciTE option save.deletes.first deletes it before doing the save.\n        This allows saving with a different capitalization on Windows.\n      </li>\n      <li>\n        When use tabs option is off pressing the tab key inserts spaces.\n      </li>\n      <li>\n        Bug in indicators leading to extra line drawn fixed.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite128.zip?download\">Release 1.28</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 27 June 2000.\n      </li>\n      <li>\n         Fixes crash in indentation guides when indent size set to 0.\n      </li>\n      <li>\n         Fixes to installation on GTK+/Linux. User properties file on GTK+ has a dot at front of name:\n         .SciTEUser.properties. Global properties file location configurable at compile time\n         defaulting to $prefix/share/scite. $prefix determined from Gnome if present else its\n         /usr/local and can be overridden by installer. Gnome menu integration performed in\n         make install if Gnome present.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite127.zip?download\">Release 1.27</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 23 June 2000.\n      </li>\n      <li>\n         Indentation guides. View whitespace mode may be set to not display whitespace\n\t in indentation.\n      </li>\n      <li>\n        Set methods have corresponding gets for UndoCollection, BufferedDraw,\n\tCodePage, UsePalette, ReadOnly, CaretFore, and ModEventMask.\n      </li>\n      <li>\n        Caret is continuously on rather than blinking while typing or holding down\n\tdelete or backspace. And is now always shown if non blinking when focused on GTK+.\n      </li>\n      <li>\n        Bug fixed in SciTE with file extension comparison now done in case insensitive way.\n      </li>\n      <li>\n        Bugs fixed in SciTE's file path handling on Windows.\n      </li>\n      <li>\n        Bug fixed with preprocessor '#' last visible character causing hang.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite126.zip?download\">Release 1.26</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 13 June 2000.\n      </li>\n      <li>\n         Support for the Lua language in both Scintilla and SciTE.\n      </li>\n      <li>\n        Multiple buffers may be open in SciTE.\n      </li>\n      <li>\n        Each style may have a character set configured. This may determine\n\tthe characters that are displayed by the style.\n      </li>\n      <li>\n         In the C++ lexer, lexing of preprocessor source may either treat it all as being in\n\t the preprocessor class or only the initial # and preprocessor command word as\n\t being in the preprocessor class.\n      </li>\n      <li>\n        Scintilla provides SCI_CREATEDOCUMENT, SCI_ADDREFDOCUMENT, and\n\tSCI_RELEASEDOCUMENT to make it easier for a container to deal with multiple\n\tdocuments.\n      </li>\n      <li>\n        GTK+ specific definitions in Scintilla.h were removed to ScintillaWidget.h. All GTK+ clients will need to\n\t#include \"ScintillaWidget.h\".\n      </li>\n      <li>\n        For GTK+, tools can be executed in the background by setting subsystem to 2.\n      </li>\n      <li>\n        Keys in the properties files are now case sensitive. This leads to a performance increase.\n      </li>\n      <li>\n        Menu to choose which lexer to use on a file.\n      </li>\n      <li>\n        Tab size dialog on Windows.\n      </li>\n      <li>\n        File dialogs enlarged on GTK+.\n      </li>\n      <li>\n         Match Brace command bound to Ctrl+E on both platforms with Ctrl+] a synonym on Windows.\n         Ctrl+Shift+E is select to matching brace. Brace matching tries to match to either the inside or the\n         outside, depending on whether the cursor is inside or outside the braces initially.\n\tView End of Line bound to Ctrl+Shift+O.\n      </li>\n      <li>\n        The Home key may be bound to move the caret to either the start of the line or the start of the\n        text on the line.\n      </li>\n      <li>\n        Visual C++ project file for SciTE.\n      </li>\n      <li>\n        Bug fixed with current x location after Tab key.\n      </li>\n      <li>\n        Bug fixed with hiding fold margin by setting fold.margin.width to 0.\n      </li>\n      <li>\n        Bugs fixed with file name confusion on Windows when long and short names used, or different capitalizations,\n\tor relative paths.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite125.zip?download\">Release 1.25</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 9 May 2000.\n      </li>\n      <li>\n        Some Unicode support on Windows. Treats buffer and API as UTF-8 and displays\n\tthrough UCS-2 of Windows.\n      </li>\n      <li>\n        Automatic indentation. Indentation size can be different to tab size.\n      </li>\n      <li>\n        Tool bar.\n      </li>\n      <li>\n        Status bar now on Windows as well as GTK+.\n      </li>\n      <li>\n        Input fields in Find and Replace dialogs now have history on both Windows and\n\tGTK+.\n      </li>\n      <li>\n        Auto completion list items may be separated by a chosen character to allow spaces\n\tin items. The selected item may be changed through the API.\n      </li>\n      <li>\n        Horizontal scrollbar can be turned off.\n      </li>\n      <li>\n        Property to remove trailing spaces when saving file.\n      </li>\n      <li>\n        On Windows, changed font size calculation to be more compatible with\n\tother applications.\n      </li>\n      <li>\n        On GTK+, SciTE's global properties files are looked for in the directory specified in the\n\tSCITE_HOME environment variable if it is set. This allows hiding in a dot directory.\n      </li>\n      <li>\n        Keyword lists in SciTE updated for JavaScript to include those destined to be used in\n\tthe future. IDL includes XPIDL keywords as well as MSIDL keywords.\n      </li>\n      <li>\n        Zoom level can be set and queried through API.\n      </li>\n      <li>\n        New notification sent before insertions and deletions.\n      </li>\n      <li>\n        LaTeX lexer.\n      </li>\n      <li>\n        Fixes to folding including when deletions and additions are performed.\n      </li>\n      <li>\n        Fix for crash with very long lines.\n      </li>\n      <li>\n        Fix to affect all of rectangular selections with deletion and case changing.\n      </li>\n      <li>\n        Removed non-working messages that had been included only for Richedit compatibility.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/scite124.zip\">Release 1.24</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 29 March 2000.\n      </li>\n      <li>\n        Added lexing of IDL based on C++ lexer with extra UUID lexical class.\n      </li>\n      <li>\n        Functions and associated keys for Line Delete, Line Cut, Line Transpose,\n\tSelection Lower Case and Selection Upper Case.\n      </li>\n      <li>\n        Property setting for SciTE, eol.mode, chooses initial state of line end characters.\n      </li>\n      <li>\n        Fixed bugs in undo history with small almost-contiguous changes being incorrectly coalesced.\n      </li>\n      <li>\n        Fixed bugs with incorrect expansion of ContractionState data structures causing crash.\n      </li>\n      <li>\n        Fixed bugs relating to null fonts.\n      </li>\n      <li>\n        Fixed bugs where recolourization was not done sometimes when required.\n      </li>\n      <li>\n        Fixed compilation problems with SVector.h.\n      </li>\n      <li>\n        Fixed bad setting of fold points in Python.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/scite123.zip?download\">Release 1.23</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 21 March 2000.\n      </li>\n      <li>\n        Directory structure to separate on basis of product (Scintilla, SciTE, DMApp)\n\tand environment (Cross-platform, Win32, GTK+).\n      </li>\n      <li>\n        Download packaging to allow download of the source or platform dependent executables.\n      </li>\n      <li>\n        Source code now available from CVS at SourceForge.\n      </li>\n      <li>\n        Very simple Windows-only demonstration application DMApp is available from cvs as dmapp.\n      </li>\n      <li>\n        Lexing functionality may optionally be included in Scintilla rather than be provided by\n        the container.\n      </li>\n      <li>\n        Set of lexers included is determined at link time by defining which of the Lex* object files\n\tare linked in.\n      </li>\n      <li>\n        On Windows, the SciLexer.DLL extends Scintilla.DLL with the standard lexers.\n      </li>\n      <li>\n        Enhanced HTML lexer styles embedded VBScript and Python.\n\tASP segments are styled and ASP scripts in JavaScript, VBScript and Python are styled.\n      </li>\n      <li>\n        PLSQL and PHP supported.\n      </li>\n      <li>\n        Maximum number of lexical states extended to 128.\n      </li>\n      <li>\n        Lexers may store per line parse state for multiple line features such as ASP script language choice.\n      </li>\n      <li>\n        Lexing API simplified.\n      </li>\n      <li>\n        Project file for Visual C++.\n      </li>\n      <li>\n        Can now cycle through all recent files with Ctrl+Tab in SciTE.\n      </li>\n      <li>\n        Bookmarks in SciTE.\n      </li>\n      <li>\n        Drag and drop copy works when dragging to the edge of the selection.\n      </li>\n      <li>\n        Fixed bug with value sizes in properties file.\n      </li>\n      <li>\n        Fixed bug with last line in properties file not being used.\n      </li>\n      <li>\n        Bug with multiple views of one document fixed.\n      </li>\n      <li>\n        Keypad now works on GTK+.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/SciTE122.zip?download\">Release 1.22</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 27 February 2000.\n      </li>\n      <li>\n        wxWindows platform defined.\n\tImplementation for wxWindows will be available separately\n\tfrom main Scintilla distribution.\n      </li>\n      <li>\n        Line folding in Scintilla.\n      </li>\n      <li>\n        SciTE performs syntax directed folding for C/C++/Java/JavaScript and for Python.\n      </li>\n      <li>\n        Optional macro recording support.\n      </li>\n      <li>\n        User properties file (SciTEUser.properties) allows for customization by the user\n\tthat is not overwritten with each installation of SciTE.\n      </li>\n      <li>\n        Python lexer detects and highlights inconsistent indentation.\n      </li>\n      <li>\n        Margin API made more orthogonal. SCI_SETMARGINWIDTH and SCI_SETLINENUMBERWIDTH\n        are deprecated in favour of this new API.\n      </li>\n      <li>\n        Margins may be made sensitive to forward mouse click events to container.\n      </li>\n      <li>\n        SQL lexer and styles included.\n      </li>\n      <li>\n        Perl lexer handles regular expressions better.\n      </li>\n      <li>\n        Caret policy determines how closely caret is tracked by visible area.\n      </li>\n      <li>\n        New marker shapes: arrow pointing down, plus and minus.\n      </li>\n      <li>\n        Optionally display full path in title rather than just file name.\n      </li>\n      <li>\n        Container is notified when Scintilla gains or loses focus.\n      </li>\n      <li>\n        SciTE handles focus in a more standard way and applies the main\n\tedit commands to the focused pane.\n      </li>\n      <li>\n        Container is notified when Scintilla determines that a line needs to be made visible.\n      </li>\n      <li>\n        Document watchers receive notification when document about to be deleted.\n      </li>\n      <li>\n        Document interface allows access to list of watchers.\n      </li>\n      <li>\n        Line end determined correctly for lines ending with only a '\\n'.\n      </li>\n      <li>\n        Search variant that searches form current selection and sets selection.\n      </li>\n      <li>\n        SciTE understands format of diagnostic messages from WScript.\n      </li>\n      <li>\n        SciTE remembers top line of window for each file in MRU list so switching to a recent file\n\tis more likely to show the same text as when the file was previously visible.\n      </li>\n      <li>\n        Document reference count now initialized correctly.\n      </li>\n      <li>\n        Setting a null document pointer creates an empty document.\n      </li>\n      <li>\n        WM_GETTEXT can no longer overrun buffer.\n      </li>\n      <li>\n        Polygon drawing bug fixed on GTK+.\n      </li>\n      <li>\n        Java and JavaScript lexers merged into C++ lexer.\n      </li>\n      <li>\n        C++ lexer indicates unterminated strings by colouring the end of the line\n\trather than changing the rest of the file to string style. This is less\n\tobtrusive and helps the folding.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://prdownloads.sourceforge.net/scintilla/SciTE121.zip?download\">Release 1.21</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 2 February 2000.\n      </li>\n      <li>\n        Blank margins on left and right side of text.\n      </li>\n      <li>\n        SCN_CHECKBRACE renamed SCN_UPDATEUI and made more efficient.\n      </li>\n      <li>\n        SciTE source code refactored into platform independent and platform specific classes.\n      </li>\n      <li>\n        XML and Perl subset lexers in SciTE.\n      </li>\n      <li>\n        Large improvement to lexing speed.\n      </li>\n      <li>\n        A new subsystem, 2, allows use of ShellExec on Windows.\n      </li>\n      <li>\n        Borland compatible makefile.\n      </li>\n      <li>\n        Status bar showing caret position in GTK+ version of SciTE.\n      </li>\n      <li>\n        Bug fixes to selection drawing when part of selection outside window, mouse release over\n        scroll bars, and scroll positioning after deletion.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE120.zip\">Release 1.2</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 21 January 2000.\n      </li>\n      <li>\n        Multiple views of one document.\n      </li>\n      <li>\n        Rectangular selection, cut, copy, paste, drag and drop.\n      </li>\n      <li>\n        Long line indication.\n      </li>\n      <li>\n        Reverse searching\n      </li>\n      <li>\n        Line end conversion.\n      </li>\n      <li>\n        Generic autocompletion and calltips in SciTE.\n      </li>\n      <li>\n        Call tip background colour can be set.\n      </li>\n      <li>\n        SCI_MARKERPREV for moving to a previous marker.\n      </li>\n      <li>\n        Caret kept more within window where possible.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE115.zip\">Release 1.15</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 15 December 1999.\n      </li>\n      <li>\n        Brace highlighting and badlighting (for mismatched braces).\n      </li>\n      <li>\n        Visible line ends.\n      </li>\n      <li>\n        Multiple line call tips.\n      </li>\n      <li>\n        Printing now works from SciTE on Windows.\n      </li>\n      <li>\n        SciTE has a global \"*\" lexer style that is used as the basis for all the lexers' styles.\n      </li>\n      <li>\n        Fixes some warnings on GTK+ 1.2.6.\n      </li>\n      <li>\n        Better handling of modal dialogs on GTK+.\n      </li>\n      <li>\n        Resize handle drawn on pane splitter in SciTE on GTK+ so it looks more like a regular GTK+\n        *paned widget.\n      </li>\n      <li>\n        SciTE does not place window origin offscreen if no properties file found on GTK+.\n      </li>\n      <li>\n        File open filter remembered in SciTE on Windows.\n      </li>\n      <li>\n        New mechanism using style numbers 32 to 36 standardizes the setting of styles for brace\n        highlighting, brace badlighting, line numbers, control characters and the default style.\n      </li>\n      <li>\n        Old messages SCI_SETFORE .. SCI_SETFONT have been replaced by the default style 32. The old\n        messages are deprecated and will disappear in a future version.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE114.zip\">Release 1.14</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 20 November 1999.\n      </li>\n      <li>\n        Fixes a scrolling bug reported on GTK+.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE113.zip\">Release 1.13</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 18 November 1999.\n      </li>\n      <li>\n        Fixes compilation problems with the mingw32 GCC 2.95.2 on Windows.\n      </li>\n      <li>\n        Control characters are now visible.\n      </li>\n      <li>\n        Performance has improved, particularly for scrolling.\n      </li>\n      <li>\n        Windows RichEdit emulation is more accurate. This may break client code that uses these\n        messages: EM_GETLINE, EM_GETLINECOUNT, EM_EXGETSEL, EM_EXSETSEL, EM_EXLINEFROMCHAR,\n        EM_LINELENGTH, EM_LINEINDEX, EM_CHARFROMPOS, EM_POSFROMCHAR, and EM_GETTEXTRANGE.\n      </li>\n      <li>\n        Menus rearranged and accelerator keys set for all static items.\n      </li>\n      <li>\n        Placement of space indicators in view whitespace mode is more accurate with some fonts.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE112.zip\">Release 1.12</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 9 November 1999.\n      </li>\n      <li>\n        Packaging error in 1.11 meant that the compilation error was not fixed in that release.\n        Linux/GTK+ should compile with GCC 2.95 this time.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE111.zip\">Release 1.11</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 7 November 1999.\n      </li>\n      <li>\n        Fixed a compilation bug in ScintillaGTK.cxx.\n      </li>\n      <li>\n        Added a README file to explain how to build.\n      </li>\n      <li>\n        GTK+/Linux downloads now include documentation.\n      </li>\n      <li>\n        Binary only Sc1.EXE one file download for Windows.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE110.zip\">Release 1.1</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 6 November 1999.\n      </li>\n      <li>\n        Major restructuring for better modularity and platform independence.\n      </li>\n      <li>\n        Inter-application drag and drop.\n      </li>\n      <li>\n        Printing support in Scintilla on Windows.\n      </li>\n      <li>\n        Styles can select colouring to end of line. This can be used when a file contains more than\n        one language to differentiate between the areas in each language. An example is the HTML +\n        JavaScript styling in SciTE.\n      </li>\n      <li>\n        Actions can be grouped in the undo stack, so they will be undone together. This grouping is\n        hierarchical so higher level actions such as replace all can be undone in one go. Call to\n        discover whether there are any actions to redo.\n      </li>\n      <li>\n        The set of characters that define words can be changed.\n      </li>\n      <li>\n        Markers now have identifiers and can be found and deleted by their identifier. The empty\n        marker type can be used to make a marker that is invisible and which is only used to trace\n        where a particular line moves to.\n      </li>\n      <li>\n        Double click notification.\n      </li>\n      <li>\n        HTML styling in SciTE also styles embedded JavaScript.\n      </li>\n      <li>\n        Additional tool commands can be added to SciTE.\n      </li>\n      <li>\n        SciTE option to allow reloading if changed upon application activation and saving on\n        application deactivation. Not yet working on GTK+ version.\n      </li>\n      <li>\n        Entry fields in search dialogs remember last 10 user entries. Not working in all cases in\n        Windows version.\n      </li>\n      <li>\n        SciTE can save a styled copy of the current file in HTML format. As SciTE does not yet\n        support printing, this can be used to print a file by then using a browser to print the\n        HTML file.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE102.zip\">Release 1.02</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 1 October 1999.\n      </li>\n      <li>\n        GTK+ version compiles with GCC 2.95.\n      </li>\n      <li>\n        Properly deleting objects when window destroyed under GTK+.\n      </li>\n      <li>\n        If the selection is not empty backspace deletes the selection.\n      </li>\n      <li>\n        Some X style middle mouse button handling for copying the primary selection to and from\n        Scintilla. Does not work in all cases.\n      </li>\n      <li>\n        HTML styling in SciTE.\n      </li>\n      <li>\n        Stopped dirty flag being set in SciTE when results pane modified.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE101.zip\">Release 1.01</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 28 September 1999.\n      </li>\n      <li>\n        Better DBCS support on Windows including IME.\n      </li>\n      <li>\n        Wheel mouse support for scrolling and zooming on Windows. Zooming with Ctrl+KeypadPlus and\n        Ctrl+KeypadMinus.\n      </li>\n      <li>\n        Performance improvements especially on GTK+.\n      </li>\n      <li>\n        Caret blinking and settable colour on both GTK+ and Windows.\n      </li>\n      <li>\n        Drag and drop within a Scintilla window. On Windows, files can be dragged into SciTE.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/SciTE100.zip\">Release 1.0</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 17 May 1999.\n      </li>\n      <li>\n        Changed name of \"Tide\" to \"SciTE\" to avoid clash with a TCL based IDE. \"SciTE\" is a\n        SCIntilla based Text Editor and is Latin meaning something like \"understanding in a neat\n        way\" and is also an Old English version of the word \"shit\".\n      </li>\n      <li>\n        There is a SCI_AUTOCSTOPS message for defining a string of characters that will stop\n        autocompletion mode. Autocompletion mode is cancelled when any cursor movement occurs apart\n        from backspace.\n      </li>\n      <li>\n        GTK+ version now splits horizontally as well as vertically and all dialogs cancel when the\n        escape key is pressed.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/Tide92.zip\">Beta release 0.93</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 12 May 1999.\n      </li>\n      <li>\n        A bit more robust than 0.92 and supports SCI_MARKERNEXT message.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/Tide92.zip\">Beta release 0.92</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 11 May 1999.\n      </li>\n      <li>\n        GTK+ version now contains all features of Windows version with some very small differences.\n        Executing programs works much better now.\n      </li>\n      <li>\n        New palette code to allow more colours to be displayed in 256 colour screen modes. A line\n        number column can be displayed to the left of the selection margin.\n      </li>\n      <li>\n        The code that maps from line numbers to text positions and back has been completely\n        rewritten to be faster, and to allow markers to move with the text.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/Tide91.zip\">Beta release 0.91</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 30 April 1999, containing fixes to text measuring to make Scintilla work better\n        with bitmap fonts. Also some small fixes to make compiling work with Visual C++.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/Tide90.zip\">Beta release 0.90</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 29 April 1999, containing working GTK+/Linux version.\n      </li>\n      <li>\n        The Java, C++ and Python lexers recognize operators as distinct from default allowing them\n        to be highlighted.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/Tide82.zip\">Beta release 0.82</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 1 April 1999, to fix a problem with handling the Enter key in PythonWin. Also\n        fixes some problems with cmd key mapping.\n      </li>\n    </ul>\n    <h3>\n       <a href=\"https://www.scintilla.org/Tide81.zip\">Beta release 0.81</a>\n    </h3>\n    <ul>\n      <li>\n        Released on 30th March 1999, containing bug fixes and a few more features.\n      </li>\n      <li>\n        Static linking supported and Tidy.EXE, a statically linked version of Tide.EXE. Changes to\n        compiler flags in the makefiles to optimize for size.\n      </li>\n      <li>\n        Scintilla supports a 'savepoint' in the undo stack which can be set by the container when\n        the document is saved. Notifications are sent to the container when the savepoint is\n        entered or left, allowing the container to display a dirty indicator and change its\n        menus.\n      </li>\n      <li>\n        When Scintilla is set to read-only mode, a notification is sent to the container should the\n        user try to edit the document. This can be used to check the document out of a version\n        control system.\n      </li>\n      <li>\n        There is an API for setting the appearance of indicators.\n      </li>\n      <li>\n        The keyboard mapping can be redefined or removed so it can be implemented completely by the\n        container. All of the keyboard commands are now commands which can be sent by the\n        container.\n      </li>\n      <li>\n        A home command like Visual C++ with one hit going to the start of the text on the line and\n        the next going to the left margin is available. I do not personally like this but my\n        fingers have become trained to it by much repetition.\n      </li>\n      <li>\n        SCI_MARKERDELETEALL has an argument in wParam which is the number of the type marker to\n        delete with -1 performing the old action of removing all marker types.\n      </li>\n      <li>\n        Tide now understands both the file name and line numbers in error messages in most cases.\n      </li>\n      <li>\n        Tide remembers the current lines of files in the recently used list.\n      </li>\n      <li>\n        Tide has a Find in Files command.\n      </li>\n    </ul>\n    <h3>\n       Beta release 0.80\n    </h3>\n    <ul>\n      <li>\n        This was the first public release on 14th March 1999, containing a mostly working Win32\n        Scintilla DLL and Tide EXE.\n      </li>\n    </ul>\n    <h3>\n       Beta releases of SciTE were called Tide\n    </h3>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/CheckLexilla/CheckLexilla.c",
    "content": "// Lexilla lexer library use example\n/** @file CheckLexilla.c\n ** Check that Lexilla.h works.\n **/\n// Copyright 2021 by Neil Hodgson <neilh@scintilla.org>\n// This file is in the public domain.\n// If the public domain is not possible in your location then it can also be used under the same\n// license as Scintilla. https://www.scintilla.org/License.txt\n\n/* Build and run\n\n    Win32\ngcc CheckLexilla.c -I ../../include -o CheckLexilla\nCheckLexilla\nCheckLexilla ../SimpleLexer/SimpleLexer.dll\n\n   Win32 Visual C++\ncl CheckLexilla.c -I ../../include -Fe: CheckLexilla\nCheckLexilla\nCheckLexilla ../SimpleLexer/SimpleLexer.dll\n\n    macOS\nclang CheckLexilla.c -I ../../include -o CheckLexilla\n./CheckLexilla\n./CheckLexilla ../SimpleLexer/SimpleLexer.dylib\n\n    Linux\ngcc CheckLexilla.c -I ../../include -ldl -o CheckLexilla\n./CheckLexilla\n./CheckLexilla ../SimpleLexer/SimpleLexer.so\n\nWhile principally meant for compilation as C to act as an example of using Lexilla\nfrom C it can also be built as C++.\n\nWarnings are intentionally shown for the deprecated typedef LexerNameFromIDFn when compiled with\nGCC or Clang or as C++.\n\n*/\n\n#include <stdio.h>\n\n#if defined(_WIN32)\n#include <windows.h>\n#else\n#include <dlfcn.h>\n#endif\n\n#if defined(__cplusplus)\n#include \"ILexer.h\"\n#endif\n\n#include \"Lexilla.h\"\n\n#if defined(__cplusplus)\nusing namespace Lexilla;\n#endif\n\n#if defined(_WIN32)\ntypedef FARPROC Function;\ntypedef HMODULE Module;\n#else\ntypedef void *Function;\ntypedef void *Module;\n#endif\n\nstatic Function FindSymbol(Module m, const char *symbol) {\n#if defined(_WIN32)\n\treturn GetProcAddress(m, symbol);\n#else\n\treturn dlsym(m, symbol);\n#endif\n}\n\nint main(int argc, char *argv[]) {\n\tconst char szLexillaPath[] = \"../../bin/\" LEXILLA_LIB LEXILLA_EXTENSION;\n\tconst char *libPath = szLexillaPath;\n\tif (argc > 1) {\n\t\tlibPath = argv[1];\n\t}\n#if defined(_WIN32)\n\tModule lexillaLibrary = LoadLibraryA(libPath);\n#else\n\tModule lexillaLibrary = dlopen(libPath, RTLD_LAZY);\n#endif\n\n\tprintf(\"Opened %s -> %p.\\n\", libPath, lexillaLibrary);\n\tif (lexillaLibrary) {\n\t\tGetLexerCountFn lexerCount = (GetLexerCountFn)FindSymbol(lexillaLibrary, LEXILLA_GETLEXERCOUNT);\n\t\tif (lexerCount) {\n\t\t\tint nLexers = lexerCount();\n\t\t\tprintf(\"There are %d lexers.\\n\", nLexers);\n\t\t\tGetLexerNameFn lexerName = (GetLexerNameFn)FindSymbol(lexillaLibrary, LEXILLA_GETLEXERNAME);\n\t\t\tfor (int i = 0; i < nLexers; i++) {\n\t\t\t\tchar name[100] = \"\";\n\t\t\t\tlexerName(i, name, sizeof(name));\n\t\t\t\tprintf(\"%s \", name);\n\t\t\t}\n\t\t\tprintf(\"\\n\");\n\n\t\t\tGetLexerFactoryFn lexerFactory = (GetLexerFactoryFn)FindSymbol(lexillaLibrary, LEXILLA_GETLEXERFACTORY);\n\t\t\tLexerFactoryFunction lexerFactory4 = lexerFactory(4);\t// 4th entry is \"as\" which is an object lexer so works\n\t\t\tprintf(\"Lexer factory 4 -> %p.\\n\", lexerFactory4);\n\n\t\t\tCreateLexerFn lexerCreate = (CreateLexerFn)FindSymbol(lexillaLibrary, LEXILLA_CREATELEXER);\n\t\t\tILexer5 *lexerCpp = lexerCreate(\"cpp\");\n\t\t\tprintf(\"Created cpp lexer -> %p.\\n\", lexerCpp);\n\n\t\t\tLexerNameFromIDFn lexerNameFromID = (LexerNameFromIDFn)FindSymbol(lexillaLibrary, LEXILLA_LEXERNAMEFROMID);\n\t\t\tif (lexerNameFromID) {\n\t\t\t\tconst char *lexerNameCpp = lexerNameFromID(3);\t// SCLEX_CPP=3\n\t\t\t\tif (lexerNameCpp) {\n\t\t\t\t\tprintf(\"Lexer name 3 -> %s.\\n\", lexerNameCpp);\n\t\t\t\t} else {\n\t\t\t\t\tprintf(\"Lexer name 3 not available.\\n\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tprintf(\"Lexer name from ID not supported.\\n\");\n\t\t\t}\n\n\t\t\tGetLibraryPropertyNamesFn libraryProperties = (GetLibraryPropertyNamesFn)FindSymbol(lexillaLibrary, LEXILLA_GETLIBRARYPROPERTYNAMES);\n\t\t\tif (libraryProperties) {\n\t\t\t\tconst char *names = libraryProperties();\n\t\t\t\tprintf(\"Property names '%s'.\\n\", names);\n\t\t\t} else {\n\t\t\t\tprintf(\"Property names not supported.\\n\");\n\t\t\t}\n\n\t\t\tSetLibraryPropertyFn librarySetProperty = (SetLibraryPropertyFn)FindSymbol(lexillaLibrary, LEXILLA_SETLIBRARYPROPERTY);\n\t\t\tif (librarySetProperty) {\n\t\t\t\tlibrarySetProperty(\"key\", \"value\");\n\t\t\t} else {\n\t\t\t\tprintf(\"Set property not supported.\\n\");\n\t\t\t}\n\n\t\t\tGetNameSpaceFn libraryNameSpace = (GetLibraryPropertyNamesFn)FindSymbol(lexillaLibrary, LEXILLA_GETNAMESPACE);\n\t\t\tif (libraryNameSpace) {\n\t\t\t\tconst char *nameSpace = libraryNameSpace();\n\t\t\t\tprintf(\"Name space '%s'.\\n\", nameSpace);\n\t\t\t} else {\n\t\t\t\tprintf(\"Name space not supported.\\n\");\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "examples/CheckLexilla/makefile",
    "content": ".PHONY: all check clean\n\nINCLUDES = -I ../../include\nEXE = $(if $(windir),CheckLexilla.exe,CheckLexilla)\n\nifdef windir\n\tRM = $(if $(wildcard $(dir $(SHELL))rm.exe), $(dir $(SHELL))rm.exe -f, del /q)\n\tCC = gcc\nelse\n\tLIBS += -ldl\nendif\n\nall: $(EXE)\n\ncheck: $(EXE)\n\t./$(EXE)\n\nclean:\n\t$(RM) $(EXE)\n\n$(EXE): *.c\n\t$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $^ $(LIBS) $(LDLIBS) -o $@\n"
  },
  {
    "path": "examples/SimpleLexer/SimpleLexer.cxx",
    "content": "//  A simple lexer\n/** @file SimpleLexer.cxx\n ** A lexer that follows the Lexilla protocol to allow it to be used from Lexilla clients like SciTE.\n ** The lexer applies alternating styles (0,1) to bytes of the text.\n **/\n// Copyright 2021 by Neil Hodgson <neilh@scintilla.org>\n// This file is in the public domain.\n// If the public domain is not possible in your location then it can also be used under the same\n// license as Scintilla. https://www.scintilla.org/License.txt\n\n// Windows/MSVC\n// cl -std:c++17 -EHsc -LD -I ../../../scintilla/include -I ../../include -I ../../lexlib SimpleLexer.cxx ../../lexlib/*.cxx\n\n// macOS/clang\n// clang++ -dynamiclib --std=c++17 -I ../../../scintilla/include -I ../../include -I ../../lexlib SimpleLexer.cxx ../../lexlib/*.cxx -o SimpleLexer.dylib\n\n// Linux/g++\n// g++ -fPIC -shared --std=c++17 -I ../../../scintilla/include -I ../../include -I ../../lexlib SimpleLexer.cxx ../../lexlib/*.cxx -o SimpleLexer.so\n\n/* It can be demonstrated in SciTE like this, substituting the actual shared library location as lexilla.path:\nlexilla.path=.;C:\\u\\hg\\lexilla\\examples\\SimpleLexer\\SimpleLexer.dll\nlexer.*.xx=simple\nstyle.simple.1=fore:#FF0000\n*/\n\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n// Lexilla.h should not be included here as it declares statically linked functions without the __declspec( dllexport )\n\n#include \"WordList.h\"\n#include \"PropSetSimple.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"LexerBase.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nclass LexerSimple : public LexerBase {\npublic:\n        LexerSimple() {\n        }\n        void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override {\n                try {\n\t\t\tAccessor astyler(pAccess, &props);\n\t\t\tif (length > 0) {\n\t\t\t\tastyler.StartAt(startPos);\n\t\t\t\tastyler.StartSegment(startPos);\n\t\t\t\tfor (unsigned int k=0; k<length; k++) {\n\t\t\t\t\tastyler.ColourTo(startPos+k, (startPos+k)%2);\n\t\t\t\t}\n\t\t\t}\n                        astyler.Flush();\n                } catch (...) {\n                        // Should not throw into caller as may be compiled with different compiler or options\n                        pAccess->SetErrorStatus(SC_STATUS_FAILURE);\n                }\n        }\n        void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override {\n        }\n\n        static ILexer5 *LexerFactorySimple() {\n                try {\n                        return new LexerSimple();\n                } catch (...) {\n                        // Should not throw into caller as may be compiled with different compiler or options\n                        return nullptr;\n                }\n        }\n};\n\n#if defined(_WIN32)\n#define EXPORT_FUNCTION __declspec(dllexport)\n#define CALLING_CONVENTION __stdcall\n#else\n#define EXPORT_FUNCTION __attribute__((visibility(\"default\")))\n#define CALLING_CONVENTION\n#endif\n\nstatic const char *lexerName = \"simple\";\n\nextern \"C\" {\n\nEXPORT_FUNCTION int CALLING_CONVENTION GetLexerCount() {\n        return 1;\n}\n\nEXPORT_FUNCTION void CALLING_CONVENTION GetLexerName(unsigned int index, char *name, int buflength) {\n        *name = 0;\n        if ((index == 0) && (buflength > static_cast<int>(strlen(lexerName)))) {\n                strcpy(name, lexerName);\n        }\n}\n\nEXPORT_FUNCTION LexerFactoryFunction CALLING_CONVENTION GetLexerFactory(unsigned int index) {\n        if (index == 0)\n                return LexerSimple::LexerFactorySimple;\n        else\n                return 0;\n}\n\nEXPORT_FUNCTION Scintilla::ILexer5* CALLING_CONVENTION CreateLexer(const char *name) {\n\tif (0 == strcmp(name, lexerName)) {\n\t\treturn LexerSimple::LexerFactorySimple();\n\t}\n\treturn nullptr;\n}\n\nEXPORT_FUNCTION const char * CALLING_CONVENTION GetNameSpace() {\n\treturn \"example\";\n}\n\n}\n"
  },
  {
    "path": "examples/SimpleLexer/makefile",
    "content": ".PHONY: all check clean\n\nINCLUDES = -I ../../../scintilla/include -I ../../include -I ../../lexlib\n\nBASE_FLAGS += --std=c++17\n\nifdef windir\n    SHAREDEXTENSION = dll\nelse\n    ifeq ($(shell uname),Darwin)\n        SHAREDEXTENSION = dylib\n        BASE_FLAGS += -arch arm64 -arch x86_64\n        LINK_FLAGS += -dynamiclib\n    else\n        BASE_FLAGS += -fPIC\n        SHAREDEXTENSION = so\n    endif\n    BASE_FLAGS += -fvisibility=hidden\nendif\n\nifdef windir\n\tRM = $(if $(wildcard $(dir $(SHELL))rm.exe), $(dir $(SHELL))rm.exe -f, del /q)\n\tCXX = g++\nendif\n\nLIBRARY = SimpleLexer.$(SHAREDEXTENSION)\n\nvpath %.cxx ../../lexlib\n \nLEXLIB_SOURCES := $(sort $(notdir $(wildcard ../../lexlib/*.cxx)))\nLEXLIB = $(LEXLIB_SOURCES:.cxx=.o)\n\n%.o: %.cxx\n\t$(CXX) $(INCLUDES) $(BASE_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@\n\nall: $(LIBRARY)\n\n# make check requires CheckLexilla to have already been built\ncheck: $(LIBRARY)\n\t../CheckLexilla/CheckLexilla ./$(LIBRARY)\n\nclean:\n\t$(RM) *.o *obj *.lib *.exp $(LIBRARY)\n\n$(LIBRARY): $(LEXLIB) *.cxx\n\t$(CXX) $(INCLUDES) $(LINK_FLAGS) $(BASE_FLAGS) -shared $(CPPFLAGS) $(CXXFLAGS) $^ $(LIBS) $(LDLIBS) -o $@\n"
  },
  {
    "path": "include/LexicalStyles.iface",
    "content": "## This file defines the interface to Lexilla\n\n## Copyright 2000-2020 by Neil Hodgson <neilh@scintilla.org>\n## The License.txt file describes the conditions under which this software may be distributed.\n\n## Similar file structure as Scintilla.iface but only contains constants.\n\ncat Default\n\n################################################\n# For SciLexer.h\nenu Lexer=SCLEX_\nval SCLEX_CONTAINER=0\nval SCLEX_NULL=1\nval SCLEX_PYTHON=2\nval SCLEX_CPP=3\nval SCLEX_HTML=4\nval SCLEX_XML=5\nval SCLEX_PERL=6\nval SCLEX_SQL=7\nval SCLEX_VB=8\nval SCLEX_PROPERTIES=9\nval SCLEX_ERRORLIST=10\nval SCLEX_MAKEFILE=11\nval SCLEX_BATCH=12\nval SCLEX_XCODE=13\nval SCLEX_LATEX=14\nval SCLEX_LUA=15\nval SCLEX_DIFF=16\nval SCLEX_CONF=17\nval SCLEX_PASCAL=18\nval SCLEX_AVE=19\nval SCLEX_ADA=20\nval SCLEX_LISP=21\nval SCLEX_RUBY=22\nval SCLEX_EIFFEL=23\nval SCLEX_EIFFELKW=24\nval SCLEX_TCL=25\nval SCLEX_NNCRONTAB=26\nval SCLEX_BULLANT=27\nval SCLEX_VBSCRIPT=28\nval SCLEX_BAAN=31\nval SCLEX_MATLAB=32\nval SCLEX_SCRIPTOL=33\nval SCLEX_ASM=34\nval SCLEX_CPPNOCASE=35\nval SCLEX_FORTRAN=36\nval SCLEX_F77=37\nval SCLEX_CSS=38\nval SCLEX_POV=39\nval SCLEX_LOUT=40\nval SCLEX_ESCRIPT=41\nval SCLEX_PS=42\nval SCLEX_NSIS=43\nval SCLEX_MMIXAL=44\nval SCLEX_CLW=45\nval SCLEX_CLWNOCASE=46\nval SCLEX_LOT=47\nval SCLEX_YAML=48\nval SCLEX_TEX=49\nval SCLEX_METAPOST=50\nval SCLEX_POWERBASIC=51\nval SCLEX_FORTH=52\nval SCLEX_ERLANG=53\nval SCLEX_OCTAVE=54\nval SCLEX_MSSQL=55\nval SCLEX_VERILOG=56\nval SCLEX_KIX=57\nval SCLEX_GUI4CLI=58\nval SCLEX_SPECMAN=59\nval SCLEX_AU3=60\nval SCLEX_APDL=61\nval SCLEX_BASH=62\nval SCLEX_ASN1=63\nval SCLEX_VHDL=64\nval SCLEX_CAML=65\nval SCLEX_BLITZBASIC=66\nval SCLEX_PUREBASIC=67\nval SCLEX_HASKELL=68\nval SCLEX_PHPSCRIPT=69\nval SCLEX_TADS3=70\nval SCLEX_REBOL=71\nval SCLEX_SMALLTALK=72\nval SCLEX_FLAGSHIP=73\nval SCLEX_CSOUND=74\nval SCLEX_FREEBASIC=75\nval SCLEX_INNOSETUP=76\nval SCLEX_OPAL=77\nval SCLEX_SPICE=78\nval SCLEX_D=79\nval SCLEX_CMAKE=80\nval SCLEX_GAP=81\nval SCLEX_PLM=82\nval SCLEX_PROGRESS=83\nval SCLEX_ABAQUS=84\nval SCLEX_ASYMPTOTE=85\nval SCLEX_R=86\nval SCLEX_MAGIK=87\nval SCLEX_POWERSHELL=88\nval SCLEX_MYSQL=89\nval SCLEX_PO=90\nval SCLEX_TAL=91\nval SCLEX_COBOL=92\nval SCLEX_TACL=93\nval SCLEX_SORCUS=94\nval SCLEX_POWERPRO=95\nval SCLEX_NIMROD=96\nval SCLEX_SML=97\nval SCLEX_MARKDOWN=98\nval SCLEX_TXT2TAGS=99\nval SCLEX_A68K=100\nval SCLEX_MODULA=101\nval SCLEX_COFFEESCRIPT=102\nval SCLEX_TCMD=103\nval SCLEX_AVS=104\nval SCLEX_ECL=105\nval SCLEX_OSCRIPT=106\nval SCLEX_VISUALPROLOG=107\nval SCLEX_LITERATEHASKELL=108\nval SCLEX_STTXT=109\nval SCLEX_KVIRC=110\nval SCLEX_RUST=111\nval SCLEX_DMAP=112\nval SCLEX_AS=113\nval SCLEX_DMIS=114\nval SCLEX_REGISTRY=115\nval SCLEX_BIBTEX=116\nval SCLEX_SREC=117\nval SCLEX_IHEX=118\nval SCLEX_TEHEX=119\nval SCLEX_JSON=120\nval SCLEX_EDIFACT=121\nval SCLEX_INDENT=122\nval SCLEX_MAXIMA=123\nval SCLEX_STATA=124\nval SCLEX_SAS=125\nval SCLEX_NIM=126\nval SCLEX_CIL=127\nval SCLEX_X12=128\nval SCLEX_DATAFLEX=129\nval SCLEX_HOLLYWOOD=130\nval SCLEX_RAKU=131\nval SCLEX_FSHARP=132\nval SCLEX_JULIA=133\nval SCLEX_ASCIIDOC=134\nval SCLEX_GDSCRIPT=135\nval SCLEX_TOML=136\nval SCLEX_TROFF=137\nval SCLEX_DART=138\nval SCLEX_ZIG=139\nval SCLEX_NIX=140\nval SCLEX_SINEX=141\nval SCLEX_ESCSEQ=142\n\n# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a\n# value assigned in sequence from SCLEX_AUTOMATIC+1.\nval SCLEX_AUTOMATIC=1000\n# Lexical states for SCLEX_PYTHON\nlex Python=SCLEX_PYTHON SCE_P_\nlex Nimrod=SCLEX_NIMROD SCE_P_\nval SCE_P_DEFAULT=0\nval SCE_P_COMMENTLINE=1\nval SCE_P_NUMBER=2\nval SCE_P_STRING=3\nval SCE_P_CHARACTER=4\nval SCE_P_WORD=5\nval SCE_P_TRIPLE=6\nval SCE_P_TRIPLEDOUBLE=7\nval SCE_P_CLASSNAME=8\nval SCE_P_DEFNAME=9\nval SCE_P_OPERATOR=10\nval SCE_P_IDENTIFIER=11\nval SCE_P_COMMENTBLOCK=12\nval SCE_P_STRINGEOL=13\nval SCE_P_WORD2=14\nval SCE_P_DECORATOR=15\nval SCE_P_FSTRING=16\nval SCE_P_FCHARACTER=17\nval SCE_P_FTRIPLE=18\nval SCE_P_FTRIPLEDOUBLE=19\nval SCE_P_ATTRIBUTE=20\n# Lexical states for SCLEX_CPP\n# Lexical states for SCLEX_BULLANT\n# Lexical states for SCLEX_TACL\n# Lexical states for SCLEX_TAL\nlex Cpp=SCLEX_CPP SCE_C_\nlex BullAnt=SCLEX_BULLANT SCE_C_\nlex TACL=SCLEX_TACL SCE_C_\nlex TAL=SCLEX_TAL SCE_C_\nval SCE_C_DEFAULT=0\nval SCE_C_COMMENT=1\nval SCE_C_COMMENTLINE=2\nval SCE_C_COMMENTDOC=3\nval SCE_C_NUMBER=4\nval SCE_C_WORD=5\nval SCE_C_STRING=6\nval SCE_C_CHARACTER=7\nval SCE_C_UUID=8\nval SCE_C_PREPROCESSOR=9\nval SCE_C_OPERATOR=10\nval SCE_C_IDENTIFIER=11\nval SCE_C_STRINGEOL=12\nval SCE_C_VERBATIM=13\nval SCE_C_REGEX=14\nval SCE_C_COMMENTLINEDOC=15\nval SCE_C_WORD2=16\nval SCE_C_COMMENTDOCKEYWORD=17\nval SCE_C_COMMENTDOCKEYWORDERROR=18\nval SCE_C_GLOBALCLASS=19\nval SCE_C_STRINGRAW=20\nval SCE_C_TRIPLEVERBATIM=21\nval SCE_C_HASHQUOTEDSTRING=22\nval SCE_C_PREPROCESSORCOMMENT=23\nval SCE_C_PREPROCESSORCOMMENTDOC=24\nval SCE_C_USERLITERAL=25\nval SCE_C_TASKMARKER=26\nval SCE_C_ESCAPESEQUENCE=27\n# Lexical states for SCLEX_COBOL\nlex COBOL=SCLEX_COBOL SCE_COBOL_\nval SCE_COBOL_DEFAULT=0\nval SCE_COBOL_COMMENT=1\nval SCE_COBOL_COMMENTLINE=2\nval SCE_COBOL_COMMENTDOC=3\nval SCE_COBOL_NUMBER=4\nval SCE_COBOL_WORD=5\nval SCE_COBOL_STRING=6\nval SCE_COBOL_CHARACTER=7\nval SCE_COBOL_WORD3=8\nval SCE_COBOL_PREPROCESSOR=9\nval SCE_COBOL_OPERATOR=10\nval SCE_COBOL_IDENTIFIER=11\nval SCE_COBOL_WORD2=16\n# Lexical states for SCLEX_D\nlex D=SCLEX_D SCE_D_\nval SCE_D_DEFAULT=0\nval SCE_D_COMMENT=1\nval SCE_D_COMMENTLINE=2\nval SCE_D_COMMENTDOC=3\nval SCE_D_COMMENTNESTED=4\nval SCE_D_NUMBER=5\nval SCE_D_WORD=6\nval SCE_D_WORD2=7\nval SCE_D_WORD3=8\nval SCE_D_TYPEDEF=9\nval SCE_D_STRING=10\nval SCE_D_STRINGEOL=11\nval SCE_D_CHARACTER=12\nval SCE_D_OPERATOR=13\nval SCE_D_IDENTIFIER=14\nval SCE_D_COMMENTLINEDOC=15\nval SCE_D_COMMENTDOCKEYWORD=16\nval SCE_D_COMMENTDOCKEYWORDERROR=17\nval SCE_D_STRINGB=18\nval SCE_D_STRINGR=19\nval SCE_D_WORD5=20\nval SCE_D_WORD6=21\nval SCE_D_WORD7=22\n# Lexical states for SCLEX_TCL\nlex TCL=SCLEX_TCL SCE_TCL_\nval SCE_TCL_DEFAULT=0\nval SCE_TCL_COMMENT=1\nval SCE_TCL_COMMENTLINE=2\nval SCE_TCL_NUMBER=3\nval SCE_TCL_WORD_IN_QUOTE=4\nval SCE_TCL_IN_QUOTE=5\nval SCE_TCL_OPERATOR=6\nval SCE_TCL_IDENTIFIER=7\nval SCE_TCL_SUBSTITUTION=8\nval SCE_TCL_SUB_BRACE=9\nval SCE_TCL_MODIFIER=10\nval SCE_TCL_EXPAND=11\nval SCE_TCL_WORD=12\nval SCE_TCL_WORD2=13\nval SCE_TCL_WORD3=14\nval SCE_TCL_WORD4=15\nval SCE_TCL_WORD5=16\nval SCE_TCL_WORD6=17\nval SCE_TCL_WORD7=18\nval SCE_TCL_WORD8=19\nval SCE_TCL_COMMENT_BOX=20\nval SCE_TCL_BLOCK_COMMENT=21\n# Lexical states for SCLEX_HTML, SCLEX_XML\nlex HTML=SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_\nlex XML=SCLEX_XML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_\nval SCE_H_DEFAULT=0\nval SCE_H_TAG=1\nval SCE_H_TAGUNKNOWN=2\nval SCE_H_ATTRIBUTE=3\nval SCE_H_ATTRIBUTEUNKNOWN=4\nval SCE_H_NUMBER=5\nval SCE_H_DOUBLESTRING=6\nval SCE_H_SINGLESTRING=7\nval SCE_H_OTHER=8\nval SCE_H_COMMENT=9\nval SCE_H_ENTITY=10\n# XML and ASP\nval SCE_H_TAGEND=11\nval SCE_H_XMLSTART=12\nval SCE_H_XMLEND=13\nval SCE_H_SCRIPT=14\nval SCE_H_ASP=15\nval SCE_H_ASPAT=16\nval SCE_H_CDATA=17\nval SCE_H_QUESTION=18\n# More HTML\nval SCE_H_VALUE=19\n# X-Code, ASP.NET, JSP\nval SCE_H_XCCOMMENT=20\n# SGML\nval SCE_H_SGML_DEFAULT=21\nval SCE_H_SGML_COMMAND=22\nval SCE_H_SGML_1ST_PARAM=23\nval SCE_H_SGML_DOUBLESTRING=24\nval SCE_H_SGML_SIMPLESTRING=25\nval SCE_H_SGML_ERROR=26\nval SCE_H_SGML_SPECIAL=27\nval SCE_H_SGML_ENTITY=28\nval SCE_H_SGML_COMMENT=29\nval SCE_H_SGML_1ST_PARAM_COMMENT=30\nval SCE_H_SGML_BLOCK_DEFAULT=31\n# Embedded Javascript\nval SCE_HJ_START=40\nval SCE_HJ_DEFAULT=41\nval SCE_HJ_COMMENT=42\nval SCE_HJ_COMMENTLINE=43\nval SCE_HJ_COMMENTDOC=44\nval SCE_HJ_NUMBER=45\nval SCE_HJ_WORD=46\nval SCE_HJ_KEYWORD=47\nval SCE_HJ_DOUBLESTRING=48\nval SCE_HJ_SINGLESTRING=49\nval SCE_HJ_SYMBOLS=50\nval SCE_HJ_STRINGEOL=51\nval SCE_HJ_REGEX=52\nval SCE_HJ_TEMPLATELITERAL=53\n# ASP Javascript\nval SCE_HJA_START=55\nval SCE_HJA_DEFAULT=56\nval SCE_HJA_COMMENT=57\nval SCE_HJA_COMMENTLINE=58\nval SCE_HJA_COMMENTDOC=59\nval SCE_HJA_NUMBER=60\nval SCE_HJA_WORD=61\nval SCE_HJA_KEYWORD=62\nval SCE_HJA_DOUBLESTRING=63\nval SCE_HJA_SINGLESTRING=64\nval SCE_HJA_SYMBOLS=65\nval SCE_HJA_STRINGEOL=66\nval SCE_HJA_REGEX=67\nval SCE_HJA_TEMPLATELITERAL=68\n# Embedded VBScript\nval SCE_HB_START=70\nval SCE_HB_DEFAULT=71\nval SCE_HB_COMMENTLINE=72\nval SCE_HB_NUMBER=73\nval SCE_HB_WORD=74\nval SCE_HB_STRING=75\nval SCE_HB_IDENTIFIER=76\nval SCE_HB_STRINGEOL=77\n# ASP VBScript\nval SCE_HBA_START=80\nval SCE_HBA_DEFAULT=81\nval SCE_HBA_COMMENTLINE=82\nval SCE_HBA_NUMBER=83\nval SCE_HBA_WORD=84\nval SCE_HBA_STRING=85\nval SCE_HBA_IDENTIFIER=86\nval SCE_HBA_STRINGEOL=87\n# Embedded Python\nval SCE_HP_START=90\nval SCE_HP_DEFAULT=91\nval SCE_HP_COMMENTLINE=92\nval SCE_HP_NUMBER=93\nval SCE_HP_STRING=94\nval SCE_HP_CHARACTER=95\nval SCE_HP_WORD=96\nval SCE_HP_TRIPLE=97\nval SCE_HP_TRIPLEDOUBLE=98\nval SCE_HP_CLASSNAME=99\nval SCE_HP_DEFNAME=100\nval SCE_HP_OPERATOR=101\nval SCE_HP_IDENTIFIER=102\n# PHP\nval SCE_HPHP_COMPLEX_VARIABLE=104\n# ASP Python\nval SCE_HPA_START=105\nval SCE_HPA_DEFAULT=106\nval SCE_HPA_COMMENTLINE=107\nval SCE_HPA_NUMBER=108\nval SCE_HPA_STRING=109\nval SCE_HPA_CHARACTER=110\nval SCE_HPA_WORD=111\nval SCE_HPA_TRIPLE=112\nval SCE_HPA_TRIPLEDOUBLE=113\nval SCE_HPA_CLASSNAME=114\nval SCE_HPA_DEFNAME=115\nval SCE_HPA_OPERATOR=116\nval SCE_HPA_IDENTIFIER=117\n# PHP\nval SCE_HPHP_DEFAULT=118\nval SCE_HPHP_HSTRING=119\nval SCE_HPHP_SIMPLESTRING=120\nval SCE_HPHP_WORD=121\nval SCE_HPHP_NUMBER=122\nval SCE_HPHP_VARIABLE=123\nval SCE_HPHP_COMMENT=124\nval SCE_HPHP_COMMENTLINE=125\nval SCE_HPHP_HSTRING_VARIABLE=126\nval SCE_HPHP_OPERATOR=127\n# Lexical states for SCLEX_PERL\nlex Perl=SCLEX_PERL SCE_PL_\nval SCE_PL_DEFAULT=0\nval SCE_PL_ERROR=1\nval SCE_PL_COMMENTLINE=2\nval SCE_PL_POD=3\nval SCE_PL_NUMBER=4\nval SCE_PL_WORD=5\nval SCE_PL_STRING=6\nval SCE_PL_CHARACTER=7\nval SCE_PL_PUNCTUATION=8\nval SCE_PL_PREPROCESSOR=9\nval SCE_PL_OPERATOR=10\nval SCE_PL_IDENTIFIER=11\nval SCE_PL_SCALAR=12\nval SCE_PL_ARRAY=13\nval SCE_PL_HASH=14\nval SCE_PL_SYMBOLTABLE=15\nval SCE_PL_VARIABLE_INDEXER=16\nval SCE_PL_REGEX=17\nval SCE_PL_REGSUBST=18\nval SCE_PL_LONGQUOTE=19\nval SCE_PL_BACKTICKS=20\nval SCE_PL_DATASECTION=21\nval SCE_PL_HERE_DELIM=22\nval SCE_PL_HERE_Q=23\nval SCE_PL_HERE_QQ=24\nval SCE_PL_HERE_QX=25\nval SCE_PL_STRING_Q=26\nval SCE_PL_STRING_QQ=27\nval SCE_PL_STRING_QX=28\nval SCE_PL_STRING_QR=29\nval SCE_PL_STRING_QW=30\nval SCE_PL_POD_VERB=31\nval SCE_PL_SUB_PROTOTYPE=40\nval SCE_PL_FORMAT_IDENT=41\nval SCE_PL_FORMAT=42\nval SCE_PL_STRING_VAR=43\nval SCE_PL_XLAT=44\nval SCE_PL_REGEX_VAR=54\nval SCE_PL_REGSUBST_VAR=55\nval SCE_PL_BACKTICKS_VAR=57\nval SCE_PL_HERE_QQ_VAR=61\nval SCE_PL_HERE_QX_VAR=62\nval SCE_PL_STRING_QQ_VAR=64\nval SCE_PL_STRING_QX_VAR=65\nval SCE_PL_STRING_QR_VAR=66\n# Lexical states for SCLEX_RUBY\nlex Ruby=SCLEX_RUBY SCE_RB_\nval SCE_RB_DEFAULT=0\nval SCE_RB_ERROR=1\nval SCE_RB_COMMENTLINE=2\nval SCE_RB_POD=3\nval SCE_RB_NUMBER=4\nval SCE_RB_WORD=5\nval SCE_RB_STRING=6\nval SCE_RB_CHARACTER=7\nval SCE_RB_CLASSNAME=8\nval SCE_RB_DEFNAME=9\nval SCE_RB_OPERATOR=10\nval SCE_RB_IDENTIFIER=11\nval SCE_RB_REGEX=12\nval SCE_RB_GLOBAL=13\nval SCE_RB_SYMBOL=14\nval SCE_RB_MODULE_NAME=15\nval SCE_RB_INSTANCE_VAR=16\nval SCE_RB_CLASS_VAR=17\nval SCE_RB_BACKTICKS=18\nval SCE_RB_DATASECTION=19\nval SCE_RB_HERE_DELIM=20\nval SCE_RB_HERE_Q=21\nval SCE_RB_HERE_QQ=22\nval SCE_RB_HERE_QX=23\nval SCE_RB_STRING_Q=24\nval SCE_RB_STRING_QQ=25\nval SCE_RB_STRING_QX=26\nval SCE_RB_STRING_QR=27\nval SCE_RB_STRING_QW=28\nval SCE_RB_WORD_DEMOTED=29\nval SCE_RB_STDIN=30\nval SCE_RB_STDOUT=31\nval SCE_RB_STDERR=40\nval SCE_RB_STRING_W=41\nval SCE_RB_STRING_I=42\nval SCE_RB_STRING_QI=43\nval SCE_RB_STRING_QS=44\nval SCE_RB_UPPER_BOUND=45\n# Lexical states for SCLEX_VB, SCLEX_VBSCRIPT, SCLEX_POWERBASIC, SCLEX_BLITZBASIC, SCLEX_PUREBASIC, SCLEX_FREEBASIC\nlex VB=SCLEX_VB SCE_B_\nlex VBScript=SCLEX_VBSCRIPT SCE_B_\nlex PowerBasic=SCLEX_POWERBASIC SCE_B_\nlex BlitzBasic=SCLEX_BLITZBASIC SCE_B_\nlex PureBasic=SCLEX_PUREBASIC SCE_B_\nlex FreeBasic=SCLEX_FREEBASIC SCE_B_\nval SCE_B_DEFAULT=0\nval SCE_B_COMMENT=1\nval SCE_B_NUMBER=2\nval SCE_B_KEYWORD=3\nval SCE_B_STRING=4\nval SCE_B_PREPROCESSOR=5\nval SCE_B_OPERATOR=6\nval SCE_B_IDENTIFIER=7\nval SCE_B_DATE=8\nval SCE_B_STRINGEOL=9\nval SCE_B_KEYWORD2=10\nval SCE_B_KEYWORD3=11\nval SCE_B_KEYWORD4=12\nval SCE_B_CONSTANT=13\nval SCE_B_ASM=14\nval SCE_B_LABEL=15\nval SCE_B_ERROR=16\nval SCE_B_HEXNUMBER=17\nval SCE_B_BINNUMBER=18\nval SCE_B_COMMENTBLOCK=19\nval SCE_B_DOCLINE=20\nval SCE_B_DOCBLOCK=21\nval SCE_B_DOCKEYWORD=22\n# Lexical states for SCLEX_PROPERTIES\nlex Properties=SCLEX_PROPERTIES SCE_PROPS_\nval SCE_PROPS_DEFAULT=0\nval SCE_PROPS_COMMENT=1\nval SCE_PROPS_SECTION=2\nval SCE_PROPS_ASSIGNMENT=3\nval SCE_PROPS_DEFVAL=4\nval SCE_PROPS_KEY=5\n# Lexical states for SCLEX_LATEX\nlex LaTeX=SCLEX_LATEX SCE_L_\nval SCE_L_DEFAULT=0\nval SCE_L_COMMAND=1\nval SCE_L_TAG=2\nval SCE_L_MATH=3\nval SCE_L_COMMENT=4\nval SCE_L_TAG2=5\nval SCE_L_MATH2=6\nval SCE_L_COMMENT2=7\nval SCE_L_VERBATIM=8\nval SCE_L_SHORTCMD=9\nval SCE_L_SPECIAL=10\nval SCE_L_CMDOPT=11\nval SCE_L_ERROR=12\n# Lexical states for SCLEX_LUA\nlex Lua=SCLEX_LUA SCE_LUA_\nval SCE_LUA_DEFAULT=0\nval SCE_LUA_COMMENT=1\nval SCE_LUA_COMMENTLINE=2\nval SCE_LUA_COMMENTDOC=3\nval SCE_LUA_NUMBER=4\nval SCE_LUA_WORD=5\nval SCE_LUA_STRING=6\nval SCE_LUA_CHARACTER=7\nval SCE_LUA_LITERALSTRING=8\nval SCE_LUA_PREPROCESSOR=9\nval SCE_LUA_OPERATOR=10\nval SCE_LUA_IDENTIFIER=11\nval SCE_LUA_STRINGEOL=12\nval SCE_LUA_WORD2=13\nval SCE_LUA_WORD3=14\nval SCE_LUA_WORD4=15\nval SCE_LUA_WORD5=16\nval SCE_LUA_WORD6=17\nval SCE_LUA_WORD7=18\nval SCE_LUA_WORD8=19\nval SCE_LUA_LABEL=20\n# Lexical states for SCLEX_ERRORLIST\nlex ErrorList=SCLEX_ERRORLIST SCE_ERR_\nval SCE_ERR_DEFAULT=0\nval SCE_ERR_PYTHON=1\nval SCE_ERR_GCC=2\nval SCE_ERR_MS=3\nval SCE_ERR_CMD=4\nval SCE_ERR_BORLAND=5\nval SCE_ERR_PERL=6\nval SCE_ERR_NET=7\nval SCE_ERR_LUA=8\nval SCE_ERR_CTAG=9\nval SCE_ERR_DIFF_CHANGED=10\nval SCE_ERR_DIFF_ADDITION=11\nval SCE_ERR_DIFF_DELETION=12\nval SCE_ERR_DIFF_MESSAGE=13\nval SCE_ERR_PHP=14\nval SCE_ERR_ELF=15\nval SCE_ERR_IFC=16\nval SCE_ERR_IFORT=17\nval SCE_ERR_ABSF=18\nval SCE_ERR_TIDY=19\nval SCE_ERR_JAVA_STACK=20\nval SCE_ERR_VALUE=21\nval SCE_ERR_GCC_INCLUDED_FROM=22\nval SCE_ERR_ESCSEQ=23\nval SCE_ERR_ESCSEQ_UNKNOWN=24\nval SCE_ERR_GCC_EXCERPT=25\nval SCE_ERR_BASH=26\nval SCE_ERR_ES_BLACK=40\nval SCE_ERR_ES_RED=41\nval SCE_ERR_ES_GREEN=42\nval SCE_ERR_ES_BROWN=43\nval SCE_ERR_ES_BLUE=44\nval SCE_ERR_ES_MAGENTA=45\nval SCE_ERR_ES_CYAN=46\nval SCE_ERR_ES_GRAY=47\nval SCE_ERR_ES_DARK_GRAY=48\nval SCE_ERR_ES_BRIGHT_RED=49\nval SCE_ERR_ES_BRIGHT_GREEN=50\nval SCE_ERR_ES_YELLOW=51\nval SCE_ERR_ES_BRIGHT_BLUE=52\nval SCE_ERR_ES_BRIGHT_MAGENTA=53\nval SCE_ERR_ES_BRIGHT_CYAN=54\nval SCE_ERR_ES_WHITE=55\n# Lexical states for SCLEX_BATCH\nlex Batch=SCLEX_BATCH SCE_BAT_\nval SCE_BAT_DEFAULT=0\nval SCE_BAT_COMMENT=1\nval SCE_BAT_WORD=2\nval SCE_BAT_LABEL=3\nval SCE_BAT_HIDE=4\nval SCE_BAT_COMMAND=5\nval SCE_BAT_IDENTIFIER=6\nval SCE_BAT_OPERATOR=7\nval SCE_BAT_AFTER_LABEL=8\n# Lexical states for SCLEX_TCMD\nlex TCMD=SCLEX_TCMD SCE_TCMD_\nval SCE_TCMD_DEFAULT=0\nval SCE_TCMD_COMMENT=1\nval SCE_TCMD_WORD=2\nval SCE_TCMD_LABEL=3\nval SCE_TCMD_HIDE=4\nval SCE_TCMD_COMMAND=5\nval SCE_TCMD_IDENTIFIER=6\nval SCE_TCMD_OPERATOR=7\nval SCE_TCMD_ENVIRONMENT=8\nval SCE_TCMD_EXPANSION=9\nval SCE_TCMD_CLABEL=10\n# Lexical states for SCLEX_MAKEFILE\nlex MakeFile=SCLEX_MAKEFILE SCE_MAKE_\nval SCE_MAKE_DEFAULT=0\nval SCE_MAKE_COMMENT=1\nval SCE_MAKE_PREPROCESSOR=2\nval SCE_MAKE_IDENTIFIER=3\nval SCE_MAKE_OPERATOR=4\nval SCE_MAKE_TARGET=5\nval SCE_MAKE_IDEOL=9\n# Lexical states for SCLEX_DIFF\nlex Diff=SCLEX_DIFF SCE_DIFF_\nval SCE_DIFF_DEFAULT=0\nval SCE_DIFF_COMMENT=1\nval SCE_DIFF_COMMAND=2\nval SCE_DIFF_HEADER=3\nval SCE_DIFF_POSITION=4\nval SCE_DIFF_DELETED=5\nval SCE_DIFF_ADDED=6\nval SCE_DIFF_CHANGED=7\nval SCE_DIFF_PATCH_ADD=8\nval SCE_DIFF_PATCH_DELETE=9\nval SCE_DIFF_REMOVED_PATCH_ADD=10\nval SCE_DIFF_REMOVED_PATCH_DELETE=11\n# Lexical states for SCLEX_CONF (Apache Configuration Files Lexer)\nlex Conf=SCLEX_CONF SCE_CONF_\nval SCE_CONF_DEFAULT=0\nval SCE_CONF_COMMENT=1\nval SCE_CONF_NUMBER=2\nval SCE_CONF_IDENTIFIER=3\nval SCE_CONF_EXTENSION=4\nval SCE_CONF_PARAMETER=5\nval SCE_CONF_STRING=6\nval SCE_CONF_OPERATOR=7\nval SCE_CONF_IP=8\nval SCE_CONF_DIRECTIVE=9\n# Lexical states for SCLEX_AVE, Avenue\nlex Avenue=SCLEX_AVE SCE_AVE_\nval SCE_AVE_DEFAULT=0\nval SCE_AVE_COMMENT=1\nval SCE_AVE_NUMBER=2\nval SCE_AVE_WORD=3\nval SCE_AVE_STRING=6\nval SCE_AVE_ENUM=7\nval SCE_AVE_STRINGEOL=8\nval SCE_AVE_IDENTIFIER=9\nval SCE_AVE_OPERATOR=10\nval SCE_AVE_WORD1=11\nval SCE_AVE_WORD2=12\nval SCE_AVE_WORD3=13\nval SCE_AVE_WORD4=14\nval SCE_AVE_WORD5=15\nval SCE_AVE_WORD6=16\n# Lexical states for SCLEX_ADA\nlex Ada=SCLEX_ADA SCE_ADA_\nval SCE_ADA_DEFAULT=0\nval SCE_ADA_WORD=1\nval SCE_ADA_IDENTIFIER=2\nval SCE_ADA_NUMBER=3\nval SCE_ADA_DELIMITER=4\nval SCE_ADA_CHARACTER=5\nval SCE_ADA_CHARACTEREOL=6\nval SCE_ADA_STRING=7\nval SCE_ADA_STRINGEOL=8\nval SCE_ADA_LABEL=9\nval SCE_ADA_COMMENTLINE=10\nval SCE_ADA_ILLEGAL=11\n# Lexical states for SCLEX_BAAN\nlex Baan=SCLEX_BAAN SCE_BAAN_\nval SCE_BAAN_DEFAULT=0\nval SCE_BAAN_COMMENT=1\nval SCE_BAAN_COMMENTDOC=2\nval SCE_BAAN_NUMBER=3\nval SCE_BAAN_WORD=4\nval SCE_BAAN_STRING=5\nval SCE_BAAN_PREPROCESSOR=6\nval SCE_BAAN_OPERATOR=7\nval SCE_BAAN_IDENTIFIER=8\nval SCE_BAAN_STRINGEOL=9\nval SCE_BAAN_WORD2=10\nval SCE_BAAN_WORD3=11\nval SCE_BAAN_WORD4=12\nval SCE_BAAN_WORD5=13\nval SCE_BAAN_WORD6=14\nval SCE_BAAN_WORD7=15\nval SCE_BAAN_WORD8=16\nval SCE_BAAN_WORD9=17\nval SCE_BAAN_TABLEDEF=18\nval SCE_BAAN_TABLESQL=19\nval SCE_BAAN_FUNCTION=20\nval SCE_BAAN_DOMDEF=21\nval SCE_BAAN_FUNCDEF=22\nval SCE_BAAN_OBJECTDEF=23\nval SCE_BAAN_DEFINEDEF=24\n# Lexical states for SCLEX_LISP\nlex Lisp=SCLEX_LISP SCE_LISP_\nval SCE_LISP_DEFAULT=0\nval SCE_LISP_COMMENT=1\nval SCE_LISP_NUMBER=2\nval SCE_LISP_KEYWORD=3\nval SCE_LISP_KEYWORD_KW=4\nval SCE_LISP_SYMBOL=5\nval SCE_LISP_STRING=6\nval SCE_LISP_STRINGEOL=8\nval SCE_LISP_IDENTIFIER=9\nval SCE_LISP_OPERATOR=10\nval SCE_LISP_SPECIAL=11\nval SCE_LISP_MULTI_COMMENT=12\n# Lexical states for SCLEX_EIFFEL and SCLEX_EIFFELKW\nlex Eiffel=SCLEX_EIFFEL SCE_EIFFEL_\nlex EiffelKW=SCLEX_EIFFELKW SCE_EIFFEL_\nval SCE_EIFFEL_DEFAULT=0\nval SCE_EIFFEL_COMMENTLINE=1\nval SCE_EIFFEL_NUMBER=2\nval SCE_EIFFEL_WORD=3\nval SCE_EIFFEL_STRING=4\nval SCE_EIFFEL_CHARACTER=5\nval SCE_EIFFEL_OPERATOR=6\nval SCE_EIFFEL_IDENTIFIER=7\nval SCE_EIFFEL_STRINGEOL=8\n# Lexical states for SCLEX_NNCRONTAB (nnCron crontab Lexer)\nlex NNCronTab=SCLEX_NNCRONTAB SCE_NNCRONTAB_\nval SCE_NNCRONTAB_DEFAULT=0\nval SCE_NNCRONTAB_COMMENT=1\nval SCE_NNCRONTAB_TASK=2\nval SCE_NNCRONTAB_SECTION=3\nval SCE_NNCRONTAB_KEYWORD=4\nval SCE_NNCRONTAB_MODIFIER=5\nval SCE_NNCRONTAB_ASTERISK=6\nval SCE_NNCRONTAB_NUMBER=7\nval SCE_NNCRONTAB_STRING=8\nval SCE_NNCRONTAB_ENVIRONMENT=9\nval SCE_NNCRONTAB_IDENTIFIER=10\n# Lexical states for SCLEX_FORTH (Forth Lexer)\nlex Forth=SCLEX_FORTH SCE_FORTH_\nval SCE_FORTH_DEFAULT=0\nval SCE_FORTH_COMMENT=1\nval SCE_FORTH_COMMENT_ML=2\nval SCE_FORTH_IDENTIFIER=3\nval SCE_FORTH_CONTROL=4\nval SCE_FORTH_KEYWORD=5\nval SCE_FORTH_DEFWORD=6\nval SCE_FORTH_PREWORD1=7\nval SCE_FORTH_PREWORD2=8\nval SCE_FORTH_NUMBER=9\nval SCE_FORTH_STRING=10\nval SCE_FORTH_LOCALE=11\n# Lexical states for SCLEX_MATLAB\nlex MatLab=SCLEX_MATLAB SCE_MATLAB_\nval SCE_MATLAB_DEFAULT=0\nval SCE_MATLAB_COMMENT=1\nval SCE_MATLAB_COMMAND=2\nval SCE_MATLAB_NUMBER=3\nval SCE_MATLAB_KEYWORD=4\n# single quoted string\nval SCE_MATLAB_STRING=5\nval SCE_MATLAB_OPERATOR=6\nval SCE_MATLAB_IDENTIFIER=7\nval SCE_MATLAB_DOUBLEQUOTESTRING=8\n# Lexical states for SCLEX_MAXIMA\nlex Maxima=SCLEX_MAXIMA SCE_MAXIMA_\nval SCE_MAXIMA_OPERATOR=0\nval SCE_MAXIMA_COMMANDENDING=1\nval SCE_MAXIMA_COMMENT=2\nval SCE_MAXIMA_NUMBER=3\nval SCE_MAXIMA_STRING=4\nval SCE_MAXIMA_COMMAND=5\nval SCE_MAXIMA_VARIABLE=6\nval SCE_MAXIMA_UNKNOWN=7\n# Lexical states for SCLEX_SCRIPTOL\nlex Sol=SCLEX_SCRIPTOL SCE_SCRIPTOL_\nval SCE_SCRIPTOL_DEFAULT=0\nval SCE_SCRIPTOL_WHITE=1\nval SCE_SCRIPTOL_COMMENTLINE=2\nval SCE_SCRIPTOL_PERSISTENT=3\nval SCE_SCRIPTOL_CSTYLE=4\nval SCE_SCRIPTOL_COMMENTBLOCK=5\nval SCE_SCRIPTOL_NUMBER=6\nval SCE_SCRIPTOL_STRING=7\nval SCE_SCRIPTOL_CHARACTER=8\nval SCE_SCRIPTOL_STRINGEOL=9\nval SCE_SCRIPTOL_KEYWORD=10\nval SCE_SCRIPTOL_OPERATOR=11\nval SCE_SCRIPTOL_IDENTIFIER=12\nval SCE_SCRIPTOL_TRIPLE=13\nval SCE_SCRIPTOL_CLASSNAME=14\nval SCE_SCRIPTOL_PREPROCESSOR=15\n# Lexical states for SCLEX_ASM, SCLEX_AS\nlex Asm=SCLEX_ASM SCE_ASM_\nlex As=SCLEX_AS SCE_ASM_\nval SCE_ASM_DEFAULT=0\nval SCE_ASM_COMMENT=1\nval SCE_ASM_NUMBER=2\nval SCE_ASM_STRING=3\nval SCE_ASM_OPERATOR=4\nval SCE_ASM_IDENTIFIER=5\nval SCE_ASM_CPUINSTRUCTION=6\nval SCE_ASM_MATHINSTRUCTION=7\nval SCE_ASM_REGISTER=8\nval SCE_ASM_DIRECTIVE=9\nval SCE_ASM_DIRECTIVEOPERAND=10\nval SCE_ASM_COMMENTBLOCK=11\nval SCE_ASM_CHARACTER=12\nval SCE_ASM_STRINGEOL=13\nval SCE_ASM_EXTINSTRUCTION=14\nval SCE_ASM_COMMENTDIRECTIVE=15\nval SCE_ASM_STRINGBACKQUOTE=16\n# Lexical states for SCLEX_FORTRAN\nlex Fortran=SCLEX_FORTRAN SCE_F_\nlex F77=SCLEX_F77 SCE_F_\nval SCE_F_DEFAULT=0\nval SCE_F_COMMENT=1\nval SCE_F_NUMBER=2\nval SCE_F_STRING1=3\nval SCE_F_STRING2=4\nval SCE_F_STRINGEOL=5\nval SCE_F_OPERATOR=6\nval SCE_F_IDENTIFIER=7\nval SCE_F_WORD=8\nval SCE_F_WORD2=9\nval SCE_F_WORD3=10\nval SCE_F_PREPROCESSOR=11\nval SCE_F_OPERATOR2=12\nval SCE_F_LABEL=13\nval SCE_F_CONTINUATION=14\n# Lexical states for SCLEX_CSS\nlex CSS=SCLEX_CSS SCE_CSS_\nval SCE_CSS_DEFAULT=0\nval SCE_CSS_TAG=1\nval SCE_CSS_CLASS=2\nval SCE_CSS_PSEUDOCLASS=3\nval SCE_CSS_UNKNOWN_PSEUDOCLASS=4\nval SCE_CSS_OPERATOR=5\nval SCE_CSS_IDENTIFIER=6\nval SCE_CSS_UNKNOWN_IDENTIFIER=7\nval SCE_CSS_VALUE=8\nval SCE_CSS_COMMENT=9\nval SCE_CSS_ID=10\nval SCE_CSS_IMPORTANT=11\nval SCE_CSS_DIRECTIVE=12\nval SCE_CSS_DOUBLESTRING=13\nval SCE_CSS_SINGLESTRING=14\nval SCE_CSS_IDENTIFIER2=15\nval SCE_CSS_ATTRIBUTE=16\nval SCE_CSS_IDENTIFIER3=17\nval SCE_CSS_PSEUDOELEMENT=18\nval SCE_CSS_EXTENDED_IDENTIFIER=19\nval SCE_CSS_EXTENDED_PSEUDOCLASS=20\nval SCE_CSS_EXTENDED_PSEUDOELEMENT=21\nval SCE_CSS_GROUP_RULE=22\nval SCE_CSS_VARIABLE=23\n# Lexical states for SCLEX_POV\nlex POV=SCLEX_POV SCE_POV_\nval SCE_POV_DEFAULT=0\nval SCE_POV_COMMENT=1\nval SCE_POV_COMMENTLINE=2\nval SCE_POV_NUMBER=3\nval SCE_POV_OPERATOR=4\nval SCE_POV_IDENTIFIER=5\nval SCE_POV_STRING=6\nval SCE_POV_STRINGEOL=7\nval SCE_POV_DIRECTIVE=8\nval SCE_POV_BADDIRECTIVE=9\nval SCE_POV_WORD2=10\nval SCE_POV_WORD3=11\nval SCE_POV_WORD4=12\nval SCE_POV_WORD5=13\nval SCE_POV_WORD6=14\nval SCE_POV_WORD7=15\nval SCE_POV_WORD8=16\n# Lexical states for SCLEX_LOUT\nlex LOUT=SCLEX_LOUT SCE_LOUT_\nval SCE_LOUT_DEFAULT=0\nval SCE_LOUT_COMMENT=1\nval SCE_LOUT_NUMBER=2\nval SCE_LOUT_WORD=3\nval SCE_LOUT_WORD2=4\nval SCE_LOUT_WORD3=5\nval SCE_LOUT_WORD4=6\nval SCE_LOUT_STRING=7\nval SCE_LOUT_OPERATOR=8\nval SCE_LOUT_IDENTIFIER=9\nval SCE_LOUT_STRINGEOL=10\n# Lexical states for SCLEX_ESCRIPT\nlex ESCRIPT=SCLEX_ESCRIPT SCE_ESCRIPT_\nval SCE_ESCRIPT_DEFAULT=0\nval SCE_ESCRIPT_COMMENT=1\nval SCE_ESCRIPT_COMMENTLINE=2\nval SCE_ESCRIPT_COMMENTDOC=3\nval SCE_ESCRIPT_NUMBER=4\nval SCE_ESCRIPT_WORD=5\nval SCE_ESCRIPT_STRING=6\nval SCE_ESCRIPT_OPERATOR=7\nval SCE_ESCRIPT_IDENTIFIER=8\nval SCE_ESCRIPT_BRACE=9\nval SCE_ESCRIPT_WORD2=10\nval SCE_ESCRIPT_WORD3=11\n# Lexical states for SCLEX_PS\nlex PS=SCLEX_PS SCE_PS_\nval SCE_PS_DEFAULT=0\nval SCE_PS_COMMENT=1\nval SCE_PS_DSC_COMMENT=2\nval SCE_PS_DSC_VALUE=3\nval SCE_PS_NUMBER=4\nval SCE_PS_NAME=5\nval SCE_PS_KEYWORD=6\nval SCE_PS_LITERAL=7\nval SCE_PS_IMMEVAL=8\nval SCE_PS_PAREN_ARRAY=9\nval SCE_PS_PAREN_DICT=10\nval SCE_PS_PAREN_PROC=11\nval SCE_PS_TEXT=12\nval SCE_PS_HEXSTRING=13\nval SCE_PS_BASE85STRING=14\nval SCE_PS_BADSTRINGCHAR=15\n# Lexical states for SCLEX_NSIS\nlex NSIS=SCLEX_NSIS SCE_NSIS_\nval SCE_NSIS_DEFAULT=0\nval SCE_NSIS_COMMENT=1\nval SCE_NSIS_STRINGDQ=2\nval SCE_NSIS_STRINGLQ=3\nval SCE_NSIS_STRINGRQ=4\nval SCE_NSIS_FUNCTION=5\nval SCE_NSIS_VARIABLE=6\nval SCE_NSIS_LABEL=7\nval SCE_NSIS_USERDEFINED=8\nval SCE_NSIS_SECTIONDEF=9\nval SCE_NSIS_SUBSECTIONDEF=10\nval SCE_NSIS_IFDEFINEDEF=11\nval SCE_NSIS_MACRODEF=12\nval SCE_NSIS_STRINGVAR=13\nval SCE_NSIS_NUMBER=14\nval SCE_NSIS_SECTIONGROUP=15\nval SCE_NSIS_PAGEEX=16\nval SCE_NSIS_FUNCTIONDEF=17\nval SCE_NSIS_COMMENTBOX=18\n# Lexical states for SCLEX_MMIXAL\nlex MMIXAL=SCLEX_MMIXAL SCE_MMIXAL_\nval SCE_MMIXAL_LEADWS=0\nval SCE_MMIXAL_COMMENT=1\nval SCE_MMIXAL_LABEL=2\nval SCE_MMIXAL_OPCODE=3\nval SCE_MMIXAL_OPCODE_PRE=4\nval SCE_MMIXAL_OPCODE_VALID=5\nval SCE_MMIXAL_OPCODE_UNKNOWN=6\nval SCE_MMIXAL_OPCODE_POST=7\nval SCE_MMIXAL_OPERANDS=8\nval SCE_MMIXAL_NUMBER=9\nval SCE_MMIXAL_REF=10\nval SCE_MMIXAL_CHAR=11\nval SCE_MMIXAL_STRING=12\nval SCE_MMIXAL_REGISTER=13\nval SCE_MMIXAL_HEX=14\nval SCE_MMIXAL_OPERATOR=15\nval SCE_MMIXAL_SYMBOL=16\nval SCE_MMIXAL_INCLUDE=17\n# Lexical states for SCLEX_CLW\nlex Clarion=SCLEX_CLW SCE_CLW_\nval SCE_CLW_DEFAULT=0\nval SCE_CLW_LABEL=1\nval SCE_CLW_COMMENT=2\nval SCE_CLW_STRING=3\nval SCE_CLW_USER_IDENTIFIER=4\nval SCE_CLW_INTEGER_CONSTANT=5\nval SCE_CLW_REAL_CONSTANT=6\nval SCE_CLW_PICTURE_STRING=7\nval SCE_CLW_KEYWORD=8\nval SCE_CLW_COMPILER_DIRECTIVE=9\nval SCE_CLW_RUNTIME_EXPRESSIONS=10\nval SCE_CLW_BUILTIN_PROCEDURES_FUNCTION=11\nval SCE_CLW_STRUCTURE_DATA_TYPE=12\nval SCE_CLW_ATTRIBUTE=13\nval SCE_CLW_STANDARD_EQUATE=14\nval SCE_CLW_ERROR=15\nval SCE_CLW_DEPRECATED=16\n# Lexical states for SCLEX_LOT\nlex LOT=SCLEX_LOT SCE_LOT_\nval SCE_LOT_DEFAULT=0\nval SCE_LOT_HEADER=1\nval SCE_LOT_BREAK=2\nval SCE_LOT_SET=3\nval SCE_LOT_PASS=4\nval SCE_LOT_FAIL=5\nval SCE_LOT_ABORT=6\n# Lexical states for SCLEX_YAML\nlex YAML=SCLEX_YAML SCE_YAML_\nval SCE_YAML_DEFAULT=0\nval SCE_YAML_COMMENT=1\nval SCE_YAML_IDENTIFIER=2\nval SCE_YAML_KEYWORD=3\nval SCE_YAML_NUMBER=4\nval SCE_YAML_REFERENCE=5\nval SCE_YAML_DOCUMENT=6\nval SCE_YAML_TEXT=7\nval SCE_YAML_ERROR=8\nval SCE_YAML_OPERATOR=9\n# Lexical states for SCLEX_TEX\nlex TeX=SCLEX_TEX SCE_TEX_\nval SCE_TEX_DEFAULT=0\nval SCE_TEX_SPECIAL=1\nval SCE_TEX_GROUP=2\nval SCE_TEX_SYMBOL=3\nval SCE_TEX_COMMAND=4\nval SCE_TEX_TEXT=5\nlex Metapost=SCLEX_METAPOST SCE_METAPOST_\nval SCE_METAPOST_DEFAULT=0\nval SCE_METAPOST_SPECIAL=1\nval SCE_METAPOST_GROUP=2\nval SCE_METAPOST_SYMBOL=3\nval SCE_METAPOST_COMMAND=4\nval SCE_METAPOST_TEXT=5\nval SCE_METAPOST_EXTRA=6\n# Lexical states for SCLEX_ERLANG\nlex Erlang=SCLEX_ERLANG SCE_ERLANG_\nval SCE_ERLANG_DEFAULT=0\nval SCE_ERLANG_COMMENT=1\nval SCE_ERLANG_VARIABLE=2\nval SCE_ERLANG_NUMBER=3\nval SCE_ERLANG_KEYWORD=4\nval SCE_ERLANG_STRING=5\nval SCE_ERLANG_OPERATOR=6\nval SCE_ERLANG_ATOM=7\nval SCE_ERLANG_FUNCTION_NAME=8\nval SCE_ERLANG_CHARACTER=9\nval SCE_ERLANG_MACRO=10\nval SCE_ERLANG_RECORD=11\nval SCE_ERLANG_PREPROC=12\nval SCE_ERLANG_NODE_NAME=13\nval SCE_ERLANG_COMMENT_FUNCTION=14\nval SCE_ERLANG_COMMENT_MODULE=15\nval SCE_ERLANG_COMMENT_DOC=16\nval SCE_ERLANG_COMMENT_DOC_MACRO=17\nval SCE_ERLANG_ATOM_QUOTED=18\nval SCE_ERLANG_MACRO_QUOTED=19\nval SCE_ERLANG_RECORD_QUOTED=20\nval SCE_ERLANG_NODE_NAME_QUOTED=21\nval SCE_ERLANG_BIFS=22\nval SCE_ERLANG_MODULES=23\nval SCE_ERLANG_MODULES_ATT=24\nval SCE_ERLANG_UNKNOWN=31\n# Lexical states for SCLEX_OCTAVE are identical to MatLab\nlex Octave=SCLEX_OCTAVE SCE_MATLAB_\n# Lexical states for SCLEX_JULIA\nlex Julia=SCLEX_JULIA SCE_JULIA_\nval SCE_JULIA_DEFAULT=0\nval SCE_JULIA_COMMENT=1\nval SCE_JULIA_NUMBER=2\nval SCE_JULIA_KEYWORD1=3\nval SCE_JULIA_KEYWORD2=4\nval SCE_JULIA_KEYWORD3=5\nval SCE_JULIA_CHAR=6\nval SCE_JULIA_OPERATOR=7\nval SCE_JULIA_BRACKET=8\nval SCE_JULIA_IDENTIFIER=9\nval SCE_JULIA_STRING=10\nval SCE_JULIA_SYMBOL=11\nval SCE_JULIA_MACRO=12\nval SCE_JULIA_STRINGINTERP=13\nval SCE_JULIA_DOCSTRING=14\nval SCE_JULIA_STRINGLITERAL=15\nval SCE_JULIA_COMMAND=16\nval SCE_JULIA_COMMANDLITERAL=17\nval SCE_JULIA_TYPEANNOT=18\nval SCE_JULIA_LEXERROR=19\nval SCE_JULIA_KEYWORD4=20\nval SCE_JULIA_TYPEOPERATOR=21\n# Lexical states for SCLEX_MSSQL\nlex MSSQL=SCLEX_MSSQL SCE_MSSQL_\nval SCE_MSSQL_DEFAULT=0\nval SCE_MSSQL_COMMENT=1\nval SCE_MSSQL_LINE_COMMENT=2\nval SCE_MSSQL_NUMBER=3\nval SCE_MSSQL_STRING=4\nval SCE_MSSQL_OPERATOR=5\nval SCE_MSSQL_IDENTIFIER=6\nval SCE_MSSQL_VARIABLE=7\nval SCE_MSSQL_COLUMN_NAME=8\nval SCE_MSSQL_STATEMENT=9\nval SCE_MSSQL_DATATYPE=10\nval SCE_MSSQL_SYSTABLE=11\nval SCE_MSSQL_GLOBAL_VARIABLE=12\nval SCE_MSSQL_FUNCTION=13\nval SCE_MSSQL_STORED_PROCEDURE=14\nval SCE_MSSQL_DEFAULT_PREF_DATATYPE=15\nval SCE_MSSQL_COLUMN_NAME_2=16\n# Lexical states for SCLEX_VERILOG\nlex Verilog=SCLEX_VERILOG SCE_V_\nval SCE_V_DEFAULT=0\nval SCE_V_COMMENT=1\nval SCE_V_COMMENTLINE=2\nval SCE_V_COMMENTLINEBANG=3\nval SCE_V_NUMBER=4\nval SCE_V_WORD=5\nval SCE_V_STRING=6\nval SCE_V_WORD2=7\nval SCE_V_WORD3=8\nval SCE_V_PREPROCESSOR=9\nval SCE_V_OPERATOR=10\nval SCE_V_IDENTIFIER=11\nval SCE_V_STRINGEOL=12\nval SCE_V_USER=19\nval SCE_V_COMMENT_WORD=20\nval SCE_V_INPUT=21\nval SCE_V_OUTPUT=22\nval SCE_V_INOUT=23\nval SCE_V_PORT_CONNECT=24\n# Lexical states for SCLEX_KIX\nlex Kix=SCLEX_KIX SCE_KIX_\nval SCE_KIX_DEFAULT=0\nval SCE_KIX_COMMENT=1\nval SCE_KIX_STRING1=2\nval SCE_KIX_STRING2=3\nval SCE_KIX_NUMBER=4\nval SCE_KIX_VAR=5\nval SCE_KIX_MACRO=6\nval SCE_KIX_KEYWORD=7\nval SCE_KIX_FUNCTIONS=8\nval SCE_KIX_OPERATOR=9\nval SCE_KIX_COMMENTSTREAM=10\nval SCE_KIX_IDENTIFIER=31\n# Lexical states for SCLEX_GUI4CLI\nlex Gui4Cli=SCLEX_GUI4CLI SCE_GC_\nval SCE_GC_DEFAULT=0\nval SCE_GC_COMMENTLINE=1\nval SCE_GC_COMMENTBLOCK=2\nval SCE_GC_GLOBAL=3\nval SCE_GC_EVENT=4\nval SCE_GC_ATTRIBUTE=5\nval SCE_GC_CONTROL=6\nval SCE_GC_COMMAND=7\nval SCE_GC_STRING=8\nval SCE_GC_OPERATOR=9\n# Lexical states for SCLEX_SPECMAN\nlex Specman=SCLEX_SPECMAN SCE_SN_\nval SCE_SN_DEFAULT=0\nval SCE_SN_CODE=1\nval SCE_SN_COMMENTLINE=2\nval SCE_SN_COMMENTLINEBANG=3\nval SCE_SN_NUMBER=4\nval SCE_SN_WORD=5\nval SCE_SN_STRING=6\nval SCE_SN_WORD2=7\nval SCE_SN_WORD3=8\nval SCE_SN_PREPROCESSOR=9\nval SCE_SN_OPERATOR=10\nval SCE_SN_IDENTIFIER=11\nval SCE_SN_STRINGEOL=12\nval SCE_SN_REGEXTAG=13\nval SCE_SN_SIGNAL=14\nval SCE_SN_USER=19\n# Lexical states for SCLEX_AU3\nlex Au3=SCLEX_AU3 SCE_AU3_\nval SCE_AU3_DEFAULT=0\nval SCE_AU3_COMMENT=1\nval SCE_AU3_COMMENTBLOCK=2\nval SCE_AU3_NUMBER=3\nval SCE_AU3_FUNCTION=4\nval SCE_AU3_KEYWORD=5\nval SCE_AU3_MACRO=6\nval SCE_AU3_STRING=7\nval SCE_AU3_OPERATOR=8\nval SCE_AU3_VARIABLE=9\nval SCE_AU3_SENT=10\nval SCE_AU3_PREPROCESSOR=11\nval SCE_AU3_SPECIAL=12\nval SCE_AU3_EXPAND=13\nval SCE_AU3_COMOBJ=14\nval SCE_AU3_UDF=15\n# Lexical states for SCLEX_APDL\nlex APDL=SCLEX_APDL SCE_APDL_\nval SCE_APDL_DEFAULT=0\nval SCE_APDL_COMMENT=1\nval SCE_APDL_COMMENTBLOCK=2\nval SCE_APDL_NUMBER=3\nval SCE_APDL_STRING=4\nval SCE_APDL_OPERATOR=5\nval SCE_APDL_WORD=6\nval SCE_APDL_PROCESSOR=7\nval SCE_APDL_COMMAND=8\nval SCE_APDL_SLASHCOMMAND=9\nval SCE_APDL_STARCOMMAND=10\nval SCE_APDL_ARGUMENT=11\nval SCE_APDL_FUNCTION=12\n# Lexical states for SCLEX_BASH\nlex Bash=SCLEX_BASH SCE_SH_\nval SCE_SH_DEFAULT=0\nval SCE_SH_ERROR=1\nval SCE_SH_COMMENTLINE=2\nval SCE_SH_NUMBER=3\nval SCE_SH_WORD=4\nval SCE_SH_STRING=5\nval SCE_SH_CHARACTER=6\nval SCE_SH_OPERATOR=7\nval SCE_SH_IDENTIFIER=8\nval SCE_SH_SCALAR=9\nval SCE_SH_PARAM=10\nval SCE_SH_BACKTICKS=11\nval SCE_SH_HERE_DELIM=12\nval SCE_SH_HERE_Q=13\n# Lexical states for SCLEX_ASN1\nlex Asn1=SCLEX_ASN1 SCE_ASN1_\nval SCE_ASN1_DEFAULT=0\nval SCE_ASN1_COMMENT=1\nval SCE_ASN1_IDENTIFIER=2\nval SCE_ASN1_STRING=3\nval SCE_ASN1_OID=4\nval SCE_ASN1_SCALAR=5\nval SCE_ASN1_KEYWORD=6\nval SCE_ASN1_ATTRIBUTE=7\nval SCE_ASN1_DESCRIPTOR=8\nval SCE_ASN1_TYPE=9\nval SCE_ASN1_OPERATOR=10\n# Lexical states for SCLEX_VHDL\nlex VHDL=SCLEX_VHDL SCE_VHDL_\nval SCE_VHDL_DEFAULT=0\nval SCE_VHDL_COMMENT=1\nval SCE_VHDL_COMMENTLINEBANG=2\nval SCE_VHDL_NUMBER=3\nval SCE_VHDL_STRING=4\nval SCE_VHDL_OPERATOR=5\nval SCE_VHDL_IDENTIFIER=6\nval SCE_VHDL_STRINGEOL=7\nval SCE_VHDL_KEYWORD=8\nval SCE_VHDL_STDOPERATOR=9\nval SCE_VHDL_ATTRIBUTE=10\nval SCE_VHDL_STDFUNCTION=11\nval SCE_VHDL_STDPACKAGE=12\nval SCE_VHDL_STDTYPE=13\nval SCE_VHDL_USERWORD=14\nval SCE_VHDL_BLOCK_COMMENT=15\n# Lexical states for SCLEX_CAML\nlex Caml=SCLEX_CAML SCE_CAML_\nval SCE_CAML_DEFAULT=0\nval SCE_CAML_IDENTIFIER=1\nval SCE_CAML_TAGNAME=2\nval SCE_CAML_KEYWORD=3\nval SCE_CAML_KEYWORD2=4\nval SCE_CAML_KEYWORD3=5\nval SCE_CAML_LINENUM=6\nval SCE_CAML_OPERATOR=7\nval SCE_CAML_NUMBER=8\nval SCE_CAML_CHAR=9\nval SCE_CAML_WHITE=10\nval SCE_CAML_STRING=11\nval SCE_CAML_COMMENT=12\nval SCE_CAML_COMMENT1=13\nval SCE_CAML_COMMENT2=14\nval SCE_CAML_COMMENT3=15\n# Lexical states for SCLEX_HASKELL\nlex Haskell=SCLEX_HASKELL SCE_HA_\nval SCE_HA_DEFAULT=0\nval SCE_HA_IDENTIFIER=1\nval SCE_HA_KEYWORD=2\nval SCE_HA_NUMBER=3\nval SCE_HA_STRING=4\nval SCE_HA_CHARACTER=5\nval SCE_HA_CLASS=6\nval SCE_HA_MODULE=7\nval SCE_HA_CAPITAL=8\nval SCE_HA_DATA=9\nval SCE_HA_IMPORT=10\nval SCE_HA_OPERATOR=11\nval SCE_HA_INSTANCE=12\nval SCE_HA_COMMENTLINE=13\nval SCE_HA_COMMENTBLOCK=14\nval SCE_HA_COMMENTBLOCK2=15\nval SCE_HA_COMMENTBLOCK3=16\nval SCE_HA_PRAGMA=17\nval SCE_HA_PREPROCESSOR=18\nval SCE_HA_STRINGEOL=19\nval SCE_HA_RESERVED_OPERATOR=20\nval SCE_HA_LITERATE_COMMENT=21\nval SCE_HA_LITERATE_CODEDELIM=22\n# Lexical states of SCLEX_TADS3\nlex TADS3=SCLEX_TADS3 SCE_T3_\nval SCE_T3_DEFAULT=0\nval SCE_T3_X_DEFAULT=1\nval SCE_T3_PREPROCESSOR=2\nval SCE_T3_BLOCK_COMMENT=3\nval SCE_T3_LINE_COMMENT=4\nval SCE_T3_OPERATOR=5\nval SCE_T3_KEYWORD=6\nval SCE_T3_NUMBER=7\nval SCE_T3_IDENTIFIER=8\nval SCE_T3_S_STRING=9\nval SCE_T3_D_STRING=10\nval SCE_T3_X_STRING=11\nval SCE_T3_LIB_DIRECTIVE=12\nval SCE_T3_MSG_PARAM=13\nval SCE_T3_HTML_TAG=14\nval SCE_T3_HTML_DEFAULT=15\nval SCE_T3_HTML_STRING=16\nval SCE_T3_USER1=17\nval SCE_T3_USER2=18\nval SCE_T3_USER3=19\nval SCE_T3_BRACE=20\n# Lexical states for SCLEX_REBOL\nlex Rebol=SCLEX_REBOL SCE_REBOL_\nval SCE_REBOL_DEFAULT=0\nval SCE_REBOL_COMMENTLINE=1\nval SCE_REBOL_COMMENTBLOCK=2\nval SCE_REBOL_PREFACE=3\nval SCE_REBOL_OPERATOR=4\nval SCE_REBOL_CHARACTER=5\nval SCE_REBOL_QUOTEDSTRING=6\nval SCE_REBOL_BRACEDSTRING=7\nval SCE_REBOL_NUMBER=8\nval SCE_REBOL_PAIR=9\nval SCE_REBOL_TUPLE=10\nval SCE_REBOL_BINARY=11\nval SCE_REBOL_MONEY=12\nval SCE_REBOL_ISSUE=13\nval SCE_REBOL_TAG=14\nval SCE_REBOL_FILE=15\nval SCE_REBOL_EMAIL=16\nval SCE_REBOL_URL=17\nval SCE_REBOL_DATE=18\nval SCE_REBOL_TIME=19\nval SCE_REBOL_IDENTIFIER=20\nval SCE_REBOL_WORD=21\nval SCE_REBOL_WORD2=22\nval SCE_REBOL_WORD3=23\nval SCE_REBOL_WORD4=24\nval SCE_REBOL_WORD5=25\nval SCE_REBOL_WORD6=26\nval SCE_REBOL_WORD7=27\nval SCE_REBOL_WORD8=28\n# Lexical states for SCLEX_SQL\nlex SQL=SCLEX_SQL SCE_SQL_\nval SCE_SQL_DEFAULT=0\nval SCE_SQL_COMMENT=1\nval SCE_SQL_COMMENTLINE=2\nval SCE_SQL_COMMENTDOC=3\nval SCE_SQL_NUMBER=4\nval SCE_SQL_WORD=5\nval SCE_SQL_STRING=6\nval SCE_SQL_CHARACTER=7\nval SCE_SQL_SQLPLUS=8\nval SCE_SQL_SQLPLUS_PROMPT=9\nval SCE_SQL_OPERATOR=10\nval SCE_SQL_IDENTIFIER=11\nval SCE_SQL_SQLPLUS_COMMENT=13\nval SCE_SQL_COMMENTLINEDOC=15\nval SCE_SQL_WORD2=16\nval SCE_SQL_COMMENTDOCKEYWORD=17\nval SCE_SQL_COMMENTDOCKEYWORDERROR=18\nval SCE_SQL_USER1=19\nval SCE_SQL_USER2=20\nval SCE_SQL_USER3=21\nval SCE_SQL_USER4=22\nval SCE_SQL_QUOTEDIDENTIFIER=23\nval SCE_SQL_QOPERATOR=24\n# Lexical states for SCLEX_SMALLTALK\nlex Smalltalk=SCLEX_SMALLTALK SCE_ST_\nval SCE_ST_DEFAULT=0\nval SCE_ST_STRING=1\nval SCE_ST_NUMBER=2\nval SCE_ST_COMMENT=3\nval SCE_ST_SYMBOL=4\nval SCE_ST_BINARY=5\nval SCE_ST_BOOL=6\nval SCE_ST_SELF=7\nval SCE_ST_SUPER=8\nval SCE_ST_NIL=9\nval SCE_ST_GLOBAL=10\nval SCE_ST_RETURN=11\nval SCE_ST_SPECIAL=12\nval SCE_ST_KWSEND=13\nval SCE_ST_ASSIGN=14\nval SCE_ST_CHARACTER=15\nval SCE_ST_SPEC_SEL=16\n# Lexical states for SCLEX_FLAGSHIP (clipper)\nlex FlagShip=SCLEX_FLAGSHIP SCE_FS_\nval SCE_FS_DEFAULT=0\nval SCE_FS_COMMENT=1\nval SCE_FS_COMMENTLINE=2\nval SCE_FS_COMMENTDOC=3\nval SCE_FS_COMMENTLINEDOC=4\nval SCE_FS_COMMENTDOCKEYWORD=5\nval SCE_FS_COMMENTDOCKEYWORDERROR=6\nval SCE_FS_KEYWORD=7\nval SCE_FS_KEYWORD2=8\nval SCE_FS_KEYWORD3=9\nval SCE_FS_KEYWORD4=10\nval SCE_FS_NUMBER=11\nval SCE_FS_STRING=12\nval SCE_FS_PREPROCESSOR=13\nval SCE_FS_OPERATOR=14\nval SCE_FS_IDENTIFIER=15\nval SCE_FS_DATE=16\nval SCE_FS_STRINGEOL=17\nval SCE_FS_CONSTANT=18\nval SCE_FS_WORDOPERATOR=19\nval SCE_FS_DISABLEDCODE=20\nval SCE_FS_DEFAULT_C=21\nval SCE_FS_COMMENTDOC_C=22\nval SCE_FS_COMMENTLINEDOC_C=23\nval SCE_FS_KEYWORD_C=24\nval SCE_FS_KEYWORD2_C=25\nval SCE_FS_NUMBER_C=26\nval SCE_FS_STRING_C=27\nval SCE_FS_PREPROCESSOR_C=28\nval SCE_FS_OPERATOR_C=29\nval SCE_FS_IDENTIFIER_C=30\nval SCE_FS_STRINGEOL_C=31\n# Lexical states for SCLEX_CSOUND\nlex Csound=SCLEX_CSOUND SCE_CSOUND_\nval SCE_CSOUND_DEFAULT=0\nval SCE_CSOUND_COMMENT=1\nval SCE_CSOUND_NUMBER=2\nval SCE_CSOUND_OPERATOR=3\nval SCE_CSOUND_INSTR=4\nval SCE_CSOUND_IDENTIFIER=5\nval SCE_CSOUND_OPCODE=6\nval SCE_CSOUND_HEADERSTMT=7\nval SCE_CSOUND_USERKEYWORD=8\nval SCE_CSOUND_COMMENTBLOCK=9\nval SCE_CSOUND_PARAM=10\nval SCE_CSOUND_ARATE_VAR=11\nval SCE_CSOUND_KRATE_VAR=12\nval SCE_CSOUND_IRATE_VAR=13\nval SCE_CSOUND_GLOBAL_VAR=14\nval SCE_CSOUND_STRINGEOL=15\n# Lexical states for SCLEX_INNOSETUP\nlex Inno=SCLEX_INNOSETUP SCE_INNO_\nval SCE_INNO_DEFAULT=0\nval SCE_INNO_COMMENT=1\nval SCE_INNO_KEYWORD=2\nval SCE_INNO_PARAMETER=3\nval SCE_INNO_SECTION=4\nval SCE_INNO_PREPROC=5\nval SCE_INNO_INLINE_EXPANSION=6\nval SCE_INNO_COMMENT_PASCAL=7\nval SCE_INNO_KEYWORD_PASCAL=8\nval SCE_INNO_KEYWORD_USER=9\nval SCE_INNO_STRING_DOUBLE=10\nval SCE_INNO_STRING_SINGLE=11\nval SCE_INNO_IDENTIFIER=12\n# Lexical states for SCLEX_OPAL\nlex Opal=SCLEX_OPAL SCE_OPAL_\nval SCE_OPAL_SPACE=0\nval SCE_OPAL_COMMENT_BLOCK=1\nval SCE_OPAL_COMMENT_LINE=2\nval SCE_OPAL_INTEGER=3\nval SCE_OPAL_KEYWORD=4\nval SCE_OPAL_SORT=5\nval SCE_OPAL_STRING=6\nval SCE_OPAL_PAR=7\nval SCE_OPAL_BOOL_CONST=8\nval SCE_OPAL_DEFAULT=32\n# Lexical states for SCLEX_SPICE\nlex Spice=SCLEX_SPICE SCE_SPICE_\nval SCE_SPICE_DEFAULT=0\nval SCE_SPICE_IDENTIFIER=1\nval SCE_SPICE_KEYWORD=2\nval SCE_SPICE_KEYWORD2=3\nval SCE_SPICE_KEYWORD3=4\nval SCE_SPICE_NUMBER=5\nval SCE_SPICE_DELIMITER=6\nval SCE_SPICE_VALUE=7\nval SCE_SPICE_COMMENTLINE=8\n# Lexical states for SCLEX_CMAKE\nlex CMAKE=SCLEX_CMAKE SCE_CMAKE_\nval SCE_CMAKE_DEFAULT=0\nval SCE_CMAKE_COMMENT=1\nval SCE_CMAKE_STRINGDQ=2\nval SCE_CMAKE_STRINGLQ=3\nval SCE_CMAKE_STRINGRQ=4\nval SCE_CMAKE_COMMANDS=5\nval SCE_CMAKE_PARAMETERS=6\nval SCE_CMAKE_VARIABLE=7\nval SCE_CMAKE_USERDEFINED=8\nval SCE_CMAKE_WHILEDEF=9\nval SCE_CMAKE_FOREACHDEF=10\nval SCE_CMAKE_IFDEFINEDEF=11\nval SCE_CMAKE_MACRODEF=12\nval SCE_CMAKE_STRINGVAR=13\nval SCE_CMAKE_NUMBER=14\n# Lexical states for SCLEX_GAP\nlex Gap=SCLEX_GAP SCE_GAP_\nval SCE_GAP_DEFAULT=0\nval SCE_GAP_IDENTIFIER=1\nval SCE_GAP_KEYWORD=2\nval SCE_GAP_KEYWORD2=3\nval SCE_GAP_KEYWORD3=4\nval SCE_GAP_KEYWORD4=5\nval SCE_GAP_STRING=6\nval SCE_GAP_CHAR=7\nval SCE_GAP_OPERATOR=8\nval SCE_GAP_COMMENT=9\nval SCE_GAP_NUMBER=10\nval SCE_GAP_STRINGEOL=11\n# Lexical state for SCLEX_PLM\nlex PLM=SCLEX_PLM SCE_PLM_\nval SCE_PLM_DEFAULT=0\nval SCE_PLM_COMMENT=1\nval SCE_PLM_STRING=2\nval SCE_PLM_NUMBER=3\nval SCE_PLM_IDENTIFIER=4\nval SCE_PLM_OPERATOR=5\nval SCE_PLM_CONTROL=6\nval SCE_PLM_KEYWORD=7\n# Lexical state for SCLEX_PROGRESS\nlex Progress=SCLEX_PROGRESS SCE_ABL_\nval SCE_ABL_DEFAULT=0\nval SCE_ABL_NUMBER=1\nval SCE_ABL_WORD=2\nval SCE_ABL_STRING=3\nval SCE_ABL_CHARACTER=4\nval SCE_ABL_PREPROCESSOR=5\nval SCE_ABL_OPERATOR=6\nval SCE_ABL_IDENTIFIER=7\nval SCE_ABL_BLOCK=8\nval SCE_ABL_END=9\nval SCE_ABL_COMMENT=10\nval SCE_ABL_TASKMARKER=11\nval SCE_ABL_LINECOMMENT=12\nval SCE_ABL_ANNOTATION=13\nval SCE_ABL_TYPEDANNOTATION=14\n# Lexical states for SCLEX_ABAQUS\nlex ABAQUS=SCLEX_ABAQUS SCE_ABAQUS_\nval SCE_ABAQUS_DEFAULT=0\nval SCE_ABAQUS_COMMENT=1\nval SCE_ABAQUS_COMMENTBLOCK=2\nval SCE_ABAQUS_NUMBER=3\nval SCE_ABAQUS_STRING=4\nval SCE_ABAQUS_OPERATOR=5\nval SCE_ABAQUS_WORD=6\nval SCE_ABAQUS_PROCESSOR=7\nval SCE_ABAQUS_COMMAND=8\nval SCE_ABAQUS_SLASHCOMMAND=9\nval SCE_ABAQUS_STARCOMMAND=10\nval SCE_ABAQUS_ARGUMENT=11\nval SCE_ABAQUS_FUNCTION=12\n# Lexical states for SCLEX_ASYMPTOTE\nlex Asymptote=SCLEX_ASYMPTOTE SCE_ASY_\nval SCE_ASY_DEFAULT=0\nval SCE_ASY_COMMENT=1\nval SCE_ASY_COMMENTLINE=2\nval SCE_ASY_NUMBER=3\nval SCE_ASY_WORD=4\nval SCE_ASY_STRING=5\nval SCE_ASY_CHARACTER=6\nval SCE_ASY_OPERATOR=7\nval SCE_ASY_IDENTIFIER=8\nval SCE_ASY_STRINGEOL=9\nval SCE_ASY_COMMENTLINEDOC=10\nval SCE_ASY_WORD2=11\n# Lexical states for SCLEX_R\nlex R=SCLEX_R SCE_R_\nval SCE_R_DEFAULT=0\nval SCE_R_COMMENT=1\nval SCE_R_KWORD=2\nval SCE_R_BASEKWORD=3\nval SCE_R_OTHERKWORD=4\nval SCE_R_NUMBER=5\nval SCE_R_STRING=6\nval SCE_R_STRING2=7\nval SCE_R_OPERATOR=8\nval SCE_R_IDENTIFIER=9\nval SCE_R_INFIX=10\nval SCE_R_INFIXEOL=11\nval SCE_R_BACKTICKS=12\nval SCE_R_RAWSTRING=13\nval SCE_R_RAWSTRING2=14\nval SCE_R_ESCAPESEQUENCE=15\n# Lexical state for SCLEX_MAGIK\nlex MagikSF=SCLEX_MAGIK SCE_MAGIK_\nval SCE_MAGIK_DEFAULT=0\nval SCE_MAGIK_COMMENT=1\nval SCE_MAGIK_HYPER_COMMENT=16\nval SCE_MAGIK_STRING=2\nval SCE_MAGIK_CHARACTER=3\nval SCE_MAGIK_NUMBER=4\nval SCE_MAGIK_IDENTIFIER=5\nval SCE_MAGIK_OPERATOR=6\nval SCE_MAGIK_FLOW=7\nval SCE_MAGIK_CONTAINER=8\nval SCE_MAGIK_BRACKET_BLOCK=9\nval SCE_MAGIK_BRACE_BLOCK=10\nval SCE_MAGIK_SQBRACKET_BLOCK=11\nval SCE_MAGIK_UNKNOWN_KEYWORD=12\nval SCE_MAGIK_KEYWORD=13\nval SCE_MAGIK_PRAGMA=14\nval SCE_MAGIK_SYMBOL=15\n# Lexical state for SCLEX_POWERSHELL\nlex PowerShell=SCLEX_POWERSHELL SCE_POWERSHELL_\nval SCE_POWERSHELL_DEFAULT=0\nval SCE_POWERSHELL_COMMENT=1\nval SCE_POWERSHELL_STRING=2\nval SCE_POWERSHELL_CHARACTER=3\nval SCE_POWERSHELL_NUMBER=4\nval SCE_POWERSHELL_VARIABLE=5\nval SCE_POWERSHELL_OPERATOR=6\nval SCE_POWERSHELL_IDENTIFIER=7\nval SCE_POWERSHELL_KEYWORD=8\nval SCE_POWERSHELL_CMDLET=9\nval SCE_POWERSHELL_ALIAS=10\nval SCE_POWERSHELL_FUNCTION=11\nval SCE_POWERSHELL_USER1=12\nval SCE_POWERSHELL_COMMENTSTREAM=13\nval SCE_POWERSHELL_HERE_STRING=14\nval SCE_POWERSHELL_HERE_CHARACTER=15\nval SCE_POWERSHELL_COMMENTDOCKEYWORD=16\n# Lexical state for SCLEX_MYSQL\nlex MySQL=SCLEX_MYSQL SCE_MYSQL_\nval SCE_MYSQL_DEFAULT=0\nval SCE_MYSQL_COMMENT=1\nval SCE_MYSQL_COMMENTLINE=2\nval SCE_MYSQL_VARIABLE=3\nval SCE_MYSQL_SYSTEMVARIABLE=4\nval SCE_MYSQL_KNOWNSYSTEMVARIABLE=5\nval SCE_MYSQL_NUMBER=6\nval SCE_MYSQL_MAJORKEYWORD=7\nval SCE_MYSQL_KEYWORD=8\nval SCE_MYSQL_DATABASEOBJECT=9\nval SCE_MYSQL_PROCEDUREKEYWORD=10\nval SCE_MYSQL_STRING=11\nval SCE_MYSQL_SQSTRING=12\nval SCE_MYSQL_DQSTRING=13\nval SCE_MYSQL_OPERATOR=14\nval SCE_MYSQL_FUNCTION=15\nval SCE_MYSQL_IDENTIFIER=16\nval SCE_MYSQL_QUOTEDIDENTIFIER=17\nval SCE_MYSQL_USER1=18\nval SCE_MYSQL_USER2=19\nval SCE_MYSQL_USER3=20\nval SCE_MYSQL_HIDDENCOMMAND=21\nval SCE_MYSQL_PLACEHOLDER=22\n# Lexical state for SCLEX_PO\nlex Po=SCLEX_PO SCE_PO_\nval SCE_PO_DEFAULT=0\nval SCE_PO_COMMENT=1\nval SCE_PO_MSGID=2\nval SCE_PO_MSGID_TEXT=3\nval SCE_PO_MSGSTR=4\nval SCE_PO_MSGSTR_TEXT=5\nval SCE_PO_MSGCTXT=6\nval SCE_PO_MSGCTXT_TEXT=7\nval SCE_PO_FUZZY=8\nval SCE_PO_PROGRAMMER_COMMENT=9\nval SCE_PO_REFERENCE=10\nval SCE_PO_FLAGS=11\nval SCE_PO_MSGID_TEXT_EOL=12\nval SCE_PO_MSGSTR_TEXT_EOL=13\nval SCE_PO_MSGCTXT_TEXT_EOL=14\nval SCE_PO_ERROR=15\n# Lexical states for SCLEX_PASCAL\nlex Pascal=SCLEX_PASCAL SCE_PAS_\nval SCE_PAS_DEFAULT=0\nval SCE_PAS_IDENTIFIER=1\nval SCE_PAS_COMMENT=2\nval SCE_PAS_COMMENT2=3\nval SCE_PAS_COMMENTLINE=4\nval SCE_PAS_PREPROCESSOR=5\nval SCE_PAS_PREPROCESSOR2=6\nval SCE_PAS_NUMBER=7\nval SCE_PAS_HEXNUMBER=8\nval SCE_PAS_WORD=9\nval SCE_PAS_STRING=10\nval SCE_PAS_STRINGEOL=11\nval SCE_PAS_CHARACTER=12\nval SCE_PAS_OPERATOR=13\nval SCE_PAS_ASM=14\nval SCE_PAS_MULTILINESTRING=15\n# Lexical state for SCLEX_SORCUS\nlex SORCUS=SCLEX_SORCUS SCE_SORCUS_\nval SCE_SORCUS_DEFAULT=0\nval SCE_SORCUS_COMMAND=1\nval SCE_SORCUS_PARAMETER=2\nval SCE_SORCUS_COMMENTLINE=3\nval SCE_SORCUS_STRING=4\nval SCE_SORCUS_STRINGEOL=5\nval SCE_SORCUS_IDENTIFIER=6\nval SCE_SORCUS_OPERATOR=7\nval SCE_SORCUS_NUMBER=8\nval SCE_SORCUS_CONSTANT=9\n# Lexical state for SCLEX_POWERPRO\nlex PowerPro=SCLEX_POWERPRO SCE_POWERPRO_\nval SCE_POWERPRO_DEFAULT=0\nval SCE_POWERPRO_COMMENTBLOCK=1\nval SCE_POWERPRO_COMMENTLINE=2\nval SCE_POWERPRO_NUMBER=3\nval SCE_POWERPRO_WORD=4\nval SCE_POWERPRO_WORD2=5\nval SCE_POWERPRO_WORD3=6\nval SCE_POWERPRO_WORD4=7\nval SCE_POWERPRO_DOUBLEQUOTEDSTRING=8\nval SCE_POWERPRO_SINGLEQUOTEDSTRING=9\nval SCE_POWERPRO_LINECONTINUE=10\nval SCE_POWERPRO_OPERATOR=11\nval SCE_POWERPRO_IDENTIFIER=12\nval SCE_POWERPRO_STRINGEOL=13\nval SCE_POWERPRO_VERBATIM=14\nval SCE_POWERPRO_ALTQUOTE=15\nval SCE_POWERPRO_FUNCTION=16\n# Lexical states for SCLEX_SML\nlex SML=SCLEX_SML SCE_SML_\nval SCE_SML_DEFAULT=0\nval SCE_SML_IDENTIFIER=1\nval SCE_SML_TAGNAME=2\nval SCE_SML_KEYWORD=3\nval SCE_SML_KEYWORD2=4\nval SCE_SML_KEYWORD3=5\nval SCE_SML_LINENUM=6\nval SCE_SML_OPERATOR=7\nval SCE_SML_NUMBER=8\nval SCE_SML_CHAR=9\nval SCE_SML_STRING=11\nval SCE_SML_COMMENT=12\nval SCE_SML_COMMENT1=13\nval SCE_SML_COMMENT2=14\nval SCE_SML_COMMENT3=15\n# Lexical state for SCLEX_MARKDOWN\nlex Markdown=SCLEX_MARKDOWN SCE_MARKDOWN_\nval SCE_MARKDOWN_DEFAULT=0\nval SCE_MARKDOWN_LINE_BEGIN=1\nval SCE_MARKDOWN_STRONG1=2\nval SCE_MARKDOWN_STRONG2=3\nval SCE_MARKDOWN_EM1=4\nval SCE_MARKDOWN_EM2=5\nval SCE_MARKDOWN_HEADER1=6\nval SCE_MARKDOWN_HEADER2=7\nval SCE_MARKDOWN_HEADER3=8\nval SCE_MARKDOWN_HEADER4=9\nval SCE_MARKDOWN_HEADER5=10\nval SCE_MARKDOWN_HEADER6=11\nval SCE_MARKDOWN_PRECHAR=12\nval SCE_MARKDOWN_ULIST_ITEM=13\nval SCE_MARKDOWN_OLIST_ITEM=14\nval SCE_MARKDOWN_BLOCKQUOTE=15\nval SCE_MARKDOWN_STRIKEOUT=16\nval SCE_MARKDOWN_HRULE=17\nval SCE_MARKDOWN_LINK=18\nval SCE_MARKDOWN_CODE=19\nval SCE_MARKDOWN_CODE2=20\nval SCE_MARKDOWN_CODEBK=21\n# Lexical state for SCLEX_TXT2TAGS\nlex Txt2tags=SCLEX_TXT2TAGS SCE_TXT2TAGS_\nval SCE_TXT2TAGS_DEFAULT=0\nval SCE_TXT2TAGS_LINE_BEGIN=1\nval SCE_TXT2TAGS_STRONG1=2\nval SCE_TXT2TAGS_STRONG2=3\nval SCE_TXT2TAGS_EM1=4\nval SCE_TXT2TAGS_EM2=5\nval SCE_TXT2TAGS_HEADER1=6\nval SCE_TXT2TAGS_HEADER2=7\nval SCE_TXT2TAGS_HEADER3=8\nval SCE_TXT2TAGS_HEADER4=9\nval SCE_TXT2TAGS_HEADER5=10\nval SCE_TXT2TAGS_HEADER6=11\nval SCE_TXT2TAGS_PRECHAR=12\nval SCE_TXT2TAGS_ULIST_ITEM=13\nval SCE_TXT2TAGS_OLIST_ITEM=14\nval SCE_TXT2TAGS_BLOCKQUOTE=15\nval SCE_TXT2TAGS_STRIKEOUT=16\nval SCE_TXT2TAGS_HRULE=17\nval SCE_TXT2TAGS_LINK=18\nval SCE_TXT2TAGS_CODE=19\nval SCE_TXT2TAGS_CODE2=20\nval SCE_TXT2TAGS_CODEBK=21\nval SCE_TXT2TAGS_COMMENT=22\nval SCE_TXT2TAGS_OPTION=23\nval SCE_TXT2TAGS_PREPROC=24\nval SCE_TXT2TAGS_POSTPROC=25\n# Lexical states for SCLEX_A68K\nlex A68k=SCLEX_A68K SCE_A68K_\nval SCE_A68K_DEFAULT=0\nval SCE_A68K_COMMENT=1\nval SCE_A68K_NUMBER_DEC=2\nval SCE_A68K_NUMBER_BIN=3\nval SCE_A68K_NUMBER_HEX=4\nval SCE_A68K_STRING1=5\nval SCE_A68K_OPERATOR=6\nval SCE_A68K_CPUINSTRUCTION=7\nval SCE_A68K_EXTINSTRUCTION=8\nval SCE_A68K_REGISTER=9\nval SCE_A68K_DIRECTIVE=10\nval SCE_A68K_MACRO_ARG=11\nval SCE_A68K_LABEL=12\nval SCE_A68K_STRING2=13\nval SCE_A68K_IDENTIFIER=14\nval SCE_A68K_MACRO_DECLARATION=15\nval SCE_A68K_COMMENT_WORD=16\nval SCE_A68K_COMMENT_SPECIAL=17\nval SCE_A68K_COMMENT_DOXYGEN=18\n# Lexical states for SCLEX_MODULA\nlex Modula=SCLEX_MODULA SCE_MODULA_\nval SCE_MODULA_DEFAULT=0\nval SCE_MODULA_COMMENT=1\nval SCE_MODULA_DOXYCOMM=2\nval SCE_MODULA_DOXYKEY=3\nval SCE_MODULA_KEYWORD=4\nval SCE_MODULA_RESERVED=5\nval SCE_MODULA_NUMBER=6\nval SCE_MODULA_BASENUM=7\nval SCE_MODULA_FLOAT=8\nval SCE_MODULA_STRING=9\nval SCE_MODULA_STRSPEC=10\nval SCE_MODULA_CHAR=11\nval SCE_MODULA_CHARSPEC=12\nval SCE_MODULA_PROC=13\nval SCE_MODULA_PRAGMA=14\nval SCE_MODULA_PRGKEY=15\nval SCE_MODULA_OPERATOR=16\nval SCE_MODULA_BADSTR=17\n# Lexical states for SCLEX_COFFEESCRIPT\nlex CoffeeScript=SCLEX_COFFEESCRIPT SCE_COFFEESCRIPT_\nval SCE_COFFEESCRIPT_DEFAULT=0\nval SCE_COFFEESCRIPT_COMMENT=1\nval SCE_COFFEESCRIPT_COMMENTLINE=2\nval SCE_COFFEESCRIPT_COMMENTDOC=3\nval SCE_COFFEESCRIPT_NUMBER=4\nval SCE_COFFEESCRIPT_WORD=5\nval SCE_COFFEESCRIPT_STRING=6\nval SCE_COFFEESCRIPT_CHARACTER=7\nval SCE_COFFEESCRIPT_UUID=8\nval SCE_COFFEESCRIPT_PREPROCESSOR=9\nval SCE_COFFEESCRIPT_OPERATOR=10\nval SCE_COFFEESCRIPT_IDENTIFIER=11\nval SCE_COFFEESCRIPT_STRINGEOL=12\nval SCE_COFFEESCRIPT_VERBATIM=13\nval SCE_COFFEESCRIPT_REGEX=14\nval SCE_COFFEESCRIPT_COMMENTLINEDOC=15\nval SCE_COFFEESCRIPT_WORD2=16\nval SCE_COFFEESCRIPT_COMMENTDOCKEYWORD=17\nval SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR=18\nval SCE_COFFEESCRIPT_GLOBALCLASS=19\nval SCE_COFFEESCRIPT_STRINGRAW=20\nval SCE_COFFEESCRIPT_TRIPLEVERBATIM=21\nval SCE_COFFEESCRIPT_COMMENTBLOCK=22\nval SCE_COFFEESCRIPT_VERBOSE_REGEX=23\nval SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT=24\nval SCE_COFFEESCRIPT_INSTANCEPROPERTY=25\n# Lexical states for SCLEX_AVS\nlex AVS=SCLEX_AVS SCE_AVS_\nval SCE_AVS_DEFAULT=0\nval SCE_AVS_COMMENTBLOCK=1\nval SCE_AVS_COMMENTBLOCKN=2\nval SCE_AVS_COMMENTLINE=3\nval SCE_AVS_NUMBER=4\nval SCE_AVS_OPERATOR=5\nval SCE_AVS_IDENTIFIER=6\nval SCE_AVS_STRING=7\nval SCE_AVS_TRIPLESTRING=8\nval SCE_AVS_KEYWORD=9\nval SCE_AVS_FILTER=10\nval SCE_AVS_PLUGIN=11\nval SCE_AVS_FUNCTION=12\nval SCE_AVS_CLIPPROP=13\nval SCE_AVS_USERDFN=14\n# Lexical states for SCLEX_ECL\nlex ECL=SCLEX_ECL SCE_ECL_\nval SCE_ECL_DEFAULT=0\nval SCE_ECL_COMMENT=1\nval SCE_ECL_COMMENTLINE=2\nval SCE_ECL_NUMBER=3\nval SCE_ECL_STRING=4\nval SCE_ECL_WORD0=5\nval SCE_ECL_OPERATOR=6\nval SCE_ECL_CHARACTER=7\nval SCE_ECL_UUID=8\nval SCE_ECL_PREPROCESSOR=9\nval SCE_ECL_UNKNOWN=10\nval SCE_ECL_IDENTIFIER=11\nval SCE_ECL_STRINGEOL=12\nval SCE_ECL_VERBATIM=13\nval SCE_ECL_REGEX=14\nval SCE_ECL_COMMENTLINEDOC=15\nval SCE_ECL_WORD1=16\nval SCE_ECL_COMMENTDOCKEYWORD=17\nval SCE_ECL_COMMENTDOCKEYWORDERROR=18\nval SCE_ECL_WORD2=19\nval SCE_ECL_WORD3=20\nval SCE_ECL_WORD4=21\nval SCE_ECL_WORD5=22\nval SCE_ECL_COMMENTDOC=23\nval SCE_ECL_ADDED=24\nval SCE_ECL_DELETED=25\nval SCE_ECL_CHANGED=26\nval SCE_ECL_MOVED=27\n# Lexical states for SCLEX_OSCRIPT\nlex OScript=SCLEX_OSCRIPT SCE_OSCRIPT_\nval SCE_OSCRIPT_DEFAULT=0\nval SCE_OSCRIPT_LINE_COMMENT=1\nval SCE_OSCRIPT_BLOCK_COMMENT=2\nval SCE_OSCRIPT_DOC_COMMENT=3\nval SCE_OSCRIPT_PREPROCESSOR=4\nval SCE_OSCRIPT_NUMBER=5\nval SCE_OSCRIPT_SINGLEQUOTE_STRING=6\nval SCE_OSCRIPT_DOUBLEQUOTE_STRING=7\nval SCE_OSCRIPT_CONSTANT=8\nval SCE_OSCRIPT_IDENTIFIER=9\nval SCE_OSCRIPT_GLOBAL=10\nval SCE_OSCRIPT_KEYWORD=11\nval SCE_OSCRIPT_OPERATOR=12\nval SCE_OSCRIPT_LABEL=13\nval SCE_OSCRIPT_TYPE=14\nval SCE_OSCRIPT_FUNCTION=15\nval SCE_OSCRIPT_OBJECT=16\nval SCE_OSCRIPT_PROPERTY=17\nval SCE_OSCRIPT_METHOD=18\n# Lexical states for SCLEX_VISUALPROLOG\nlex VisualProlog=SCLEX_VISUALPROLOG SCE_VISUALPROLOG_\nval SCE_VISUALPROLOG_DEFAULT=0\nval SCE_VISUALPROLOG_KEY_MAJOR=1\nval SCE_VISUALPROLOG_KEY_MINOR=2\nval SCE_VISUALPROLOG_KEY_DIRECTIVE=3\nval SCE_VISUALPROLOG_COMMENT_BLOCK=4\nval SCE_VISUALPROLOG_COMMENT_LINE=5\nval SCE_VISUALPROLOG_COMMENT_KEY=6\nval SCE_VISUALPROLOG_COMMENT_KEY_ERROR=7\nval SCE_VISUALPROLOG_IDENTIFIER=8\nval SCE_VISUALPROLOG_VARIABLE=9\nval SCE_VISUALPROLOG_ANONYMOUS=10\nval SCE_VISUALPROLOG_NUMBER=11\nval SCE_VISUALPROLOG_OPERATOR=12\nval SCE_VISUALPROLOG_UNUSED1=13\nval SCE_VISUALPROLOG_UNUSED2=14\nval SCE_VISUALPROLOG_UNUSED3=15\nval SCE_VISUALPROLOG_STRING_QUOTE=16\nval SCE_VISUALPROLOG_STRING_ESCAPE=17\nval SCE_VISUALPROLOG_STRING_ESCAPE_ERROR=18\nval SCE_VISUALPROLOG_UNUSED4=19\nval SCE_VISUALPROLOG_STRING=20\nval SCE_VISUALPROLOG_UNUSED5=21\nval SCE_VISUALPROLOG_STRING_EOL=22\nval SCE_VISUALPROLOG_EMBEDDED=23\nval SCE_VISUALPROLOG_PLACEHOLDER=24\n# Lexical states for SCLEX_STTXT\nlex StructuredText=SCLEX_STTXT SCE_STTXT_\nval SCE_STTXT_DEFAULT=0\nval SCE_STTXT_COMMENT=1\nval SCE_STTXT_COMMENTLINE=2\nval SCE_STTXT_KEYWORD=3\nval SCE_STTXT_TYPE=4\nval SCE_STTXT_FUNCTION=5\nval SCE_STTXT_FB=6\nval SCE_STTXT_NUMBER=7\nval SCE_STTXT_HEXNUMBER=8\nval SCE_STTXT_PRAGMA=9\nval SCE_STTXT_OPERATOR=10\nval SCE_STTXT_CHARACTER=11\nval SCE_STTXT_STRING1=12\nval SCE_STTXT_STRING2=13\nval SCE_STTXT_STRINGEOL=14\nval SCE_STTXT_IDENTIFIER=15\nval SCE_STTXT_DATETIME=16\nval SCE_STTXT_VARS=17\nval SCE_STTXT_PRAGMAS=18\n# Lexical states for SCLEX_KVIRC\nlex KVIrc=SCLEX_KVIRC SCE_KVIRC_\nval SCE_KVIRC_DEFAULT=0\nval SCE_KVIRC_COMMENT=1\nval SCE_KVIRC_COMMENTBLOCK=2\nval SCE_KVIRC_STRING=3\nval SCE_KVIRC_WORD=4\nval SCE_KVIRC_KEYWORD=5\nval SCE_KVIRC_FUNCTION_KEYWORD=6\nval SCE_KVIRC_FUNCTION=7\nval SCE_KVIRC_VARIABLE=8\nval SCE_KVIRC_NUMBER=9\nval SCE_KVIRC_OPERATOR=10\nval SCE_KVIRC_STRING_FUNCTION=11\nval SCE_KVIRC_STRING_VARIABLE=12\n# Lexical states for SCLEX_RUST\nlex Rust=SCLEX_RUST SCE_RUST_\nval SCE_RUST_DEFAULT=0\nval SCE_RUST_COMMENTBLOCK=1\nval SCE_RUST_COMMENTLINE=2\nval SCE_RUST_COMMENTBLOCKDOC=3\nval SCE_RUST_COMMENTLINEDOC=4\nval SCE_RUST_NUMBER=5\nval SCE_RUST_WORD=6\nval SCE_RUST_WORD2=7\nval SCE_RUST_WORD3=8\nval SCE_RUST_WORD4=9\nval SCE_RUST_WORD5=10\nval SCE_RUST_WORD6=11\nval SCE_RUST_WORD7=12\nval SCE_RUST_STRING=13\nval SCE_RUST_STRINGR=14\nval SCE_RUST_CHARACTER=15\nval SCE_RUST_OPERATOR=16\nval SCE_RUST_IDENTIFIER=17\nval SCE_RUST_LIFETIME=18\nval SCE_RUST_MACRO=19\nval SCE_RUST_LEXERROR=20\nval SCE_RUST_BYTESTRING=21\nval SCE_RUST_BYTESTRINGR=22\nval SCE_RUST_BYTECHARACTER=23\nval SCE_RUST_CSTRING=24\nval SCE_RUST_CSTRINGR=25\n# Lexical states for SCLEX_DMAP\nlex DMAP=SCLEX_DMAP SCE_DMAP_\nval SCE_DMAP_DEFAULT=0\nval SCE_DMAP_COMMENT=1\nval SCE_DMAP_NUMBER=2\nval SCE_DMAP_STRING1=3\nval SCE_DMAP_STRING2=4\nval SCE_DMAP_STRINGEOL=5\nval SCE_DMAP_OPERATOR=6\nval SCE_DMAP_IDENTIFIER=7\nval SCE_DMAP_WORD=8\nval SCE_DMAP_WORD2=9\nval SCE_DMAP_WORD3=10\n# Lexical states for SCLEX_DMIS\nlex DMIS=SCLEX_DMIS SCE_DMIS_\nval SCE_DMIS_DEFAULT=0\nval SCE_DMIS_COMMENT=1\nval SCE_DMIS_STRING=2\nval SCE_DMIS_NUMBER=3\nval SCE_DMIS_KEYWORD=4\nval SCE_DMIS_MAJORWORD=5\nval SCE_DMIS_MINORWORD=6\nval SCE_DMIS_UNSUPPORTED_MAJOR=7\nval SCE_DMIS_UNSUPPORTED_MINOR=8\nval SCE_DMIS_LABEL=9\n# Lexical states for SCLEX_REGISTRY\nlex REG=SCLEX_REGISTRY SCE_REG_\nval SCE_REG_DEFAULT=0\nval SCE_REG_COMMENT=1\nval SCE_REG_VALUENAME=2\nval SCE_REG_STRING=3\nval SCE_REG_HEXDIGIT=4\nval SCE_REG_VALUETYPE=5\nval SCE_REG_ADDEDKEY=6\nval SCE_REG_DELETEDKEY=7\nval SCE_REG_ESCAPED=8\nval SCE_REG_KEYPATH_GUID=9\nval SCE_REG_STRING_GUID=10\nval SCE_REG_PARAMETER=11\nval SCE_REG_OPERATOR=12\n# Lexical state for SCLEX_BIBTEX\nlex BibTeX=SCLEX_BIBTEX SCE_BIBTEX_\nval SCE_BIBTEX_DEFAULT=0\nval SCE_BIBTEX_ENTRY=1\nval SCE_BIBTEX_UNKNOWN_ENTRY=2\nval SCE_BIBTEX_KEY=3\nval SCE_BIBTEX_PARAMETER=4\nval SCE_BIBTEX_VALUE=5\nval SCE_BIBTEX_COMMENT=6\n# Lexical state for SCLEX_SREC\nlex Srec=SCLEX_SREC SCE_HEX_\nval SCE_HEX_DEFAULT=0\nval SCE_HEX_RECSTART=1\nval SCE_HEX_RECTYPE=2\nval SCE_HEX_RECTYPE_UNKNOWN=3\nval SCE_HEX_BYTECOUNT=4\nval SCE_HEX_BYTECOUNT_WRONG=5\nval SCE_HEX_NOADDRESS=6\nval SCE_HEX_DATAADDRESS=7\nval SCE_HEX_RECCOUNT=8\nval SCE_HEX_STARTADDRESS=9\nval SCE_HEX_ADDRESSFIELD_UNKNOWN=10\nval SCE_HEX_EXTENDEDADDRESS=11\nval SCE_HEX_DATA_ODD=12\nval SCE_HEX_DATA_EVEN=13\nval SCE_HEX_DATA_UNKNOWN=14\nval SCE_HEX_DATA_EMPTY=15\nval SCE_HEX_CHECKSUM=16\nval SCE_HEX_CHECKSUM_WRONG=17\nval SCE_HEX_GARBAGE=18\n# Lexical state for SCLEX_IHEX (shared with Srec)\nlex IHex=SCLEX_IHEX SCE_HEX_\n# Lexical state for SCLEX_TEHEX (shared with Srec)\nlex TEHex=SCLEX_TEHEX SCE_HEX_\n# Lexical states for SCLEX_JSON\nlex JSON=SCLEX_JSON SCE_JSON_\nval SCE_JSON_DEFAULT=0\nval SCE_JSON_NUMBER=1\nval SCE_JSON_STRING=2\nval SCE_JSON_STRINGEOL=3\nval SCE_JSON_PROPERTYNAME=4\nval SCE_JSON_ESCAPESEQUENCE=5\nval SCE_JSON_LINECOMMENT=6\nval SCE_JSON_BLOCKCOMMENT=7\nval SCE_JSON_OPERATOR=8\nval SCE_JSON_URI=9\nval SCE_JSON_COMPACTIRI=10\nval SCE_JSON_KEYWORD=11\nval SCE_JSON_LDKEYWORD=12\nval SCE_JSON_ERROR=13\nlex EDIFACT=SCLEX_EDIFACT SCE_EDI_\nval SCE_EDI_DEFAULT=0\nval SCE_EDI_SEGMENTSTART=1\nval SCE_EDI_SEGMENTEND=2\nval SCE_EDI_SEP_ELEMENT=3\nval SCE_EDI_SEP_COMPOSITE=4\nval SCE_EDI_SEP_RELEASE=5\nval SCE_EDI_UNA=6\nval SCE_EDI_UNH=7\nval SCE_EDI_BADSEGMENT=8\n# Lexical states for SCLEX_STATA\nlex STATA=SCLEX_STATA SCE_STATA_\nval SCE_STATA_DEFAULT=0\nval SCE_STATA_COMMENT=1\nval SCE_STATA_COMMENTLINE=2\nval SCE_STATA_COMMENTBLOCK=3\nval SCE_STATA_NUMBER=4\nval SCE_STATA_OPERATOR=5\nval SCE_STATA_IDENTIFIER=6\nval SCE_STATA_STRING=7\nval SCE_STATA_TYPE=8\nval SCE_STATA_WORD=9\nval SCE_STATA_GLOBAL_MACRO=10\nval SCE_STATA_MACRO=11\n# Lexical states for SCLEX_SAS\nlex SAS=SCLEX_SAS SCE_SAS_\nval SCE_SAS_DEFAULT=0\nval SCE_SAS_COMMENT=1\nval SCE_SAS_COMMENTLINE=2\nval SCE_SAS_COMMENTBLOCK=3\nval SCE_SAS_NUMBER=4\nval SCE_SAS_OPERATOR=5\nval SCE_SAS_IDENTIFIER=6\nval SCE_SAS_STRING=7\nval SCE_SAS_TYPE=8\nval SCE_SAS_WORD=9\nval SCE_SAS_GLOBAL_MACRO=10\nval SCE_SAS_MACRO=11\nval SCE_SAS_MACRO_KEYWORD=12\nval SCE_SAS_BLOCK_KEYWORD=13\nval SCE_SAS_MACRO_FUNCTION=14\nval SCE_SAS_STATEMENT=15\n# Lexical states for SCLEX_NIM\nlex Nim=SCLEX_NIM SCE_NIM_\nval SCE_NIM_DEFAULT=0\nval SCE_NIM_COMMENT=1\nval SCE_NIM_COMMENTDOC=2\nval SCE_NIM_COMMENTLINE=3\nval SCE_NIM_COMMENTLINEDOC=4\nval SCE_NIM_NUMBER=5\nval SCE_NIM_STRING=6\nval SCE_NIM_CHARACTER=7\nval SCE_NIM_WORD=8\nval SCE_NIM_TRIPLE=9\nval SCE_NIM_TRIPLEDOUBLE=10\nval SCE_NIM_BACKTICKS=11\nval SCE_NIM_FUNCNAME=12\nval SCE_NIM_STRINGEOL=13\nval SCE_NIM_NUMERROR=14\nval SCE_NIM_OPERATOR=15\nval SCE_NIM_IDENTIFIER=16\n# Lexical states for SCLEX_CIL\nlex CIL=SCLEX_CIL SCE_CIL_\nval SCE_CIL_DEFAULT=0\nval SCE_CIL_COMMENT=1\nval SCE_CIL_COMMENTLINE=2\nval SCE_CIL_WORD=3\nval SCE_CIL_WORD2=4\nval SCE_CIL_WORD3=5\nval SCE_CIL_STRING=6\nval SCE_CIL_LABEL=7\nval SCE_CIL_OPERATOR=8\nval SCE_CIL_IDENTIFIER=9\nval SCE_CIL_STRINGEOL=10\n# Lexical states for SCLEX_X12\nlex X12=SCLEX_X12 SCE_X12_\nval SCE_X12_DEFAULT=0\nval SCE_X12_BAD=1\nval SCE_X12_ENVELOPE=2\nval SCE_X12_FUNCTIONGROUP=3\nval SCE_X12_TRANSACTIONSET=4\nval SCE_X12_SEGMENTHEADER=5\nval SCE_X12_SEGMENTEND=6\nval SCE_X12_SEP_ELEMENT=7\nval SCE_X12_SEP_SUBELEMENT=8\n# Lexical states for SCLEX_DATAFLEX\nlex Dataflex=SCLEX_DATAFLEX SCE_DF_\nval SCE_DF_DEFAULT=0\nval SCE_DF_IDENTIFIER=1\nval SCE_DF_METATAG=2\nval SCE_DF_IMAGE=3\nval SCE_DF_COMMENTLINE=4\nval SCE_DF_PREPROCESSOR=5\nval SCE_DF_PREPROCESSOR2=6\nval SCE_DF_NUMBER=7\nval SCE_DF_HEXNUMBER=8\nval SCE_DF_WORD=9\nval SCE_DF_STRING=10\nval SCE_DF_STRINGEOL=11\nval SCE_DF_SCOPEWORD=12\nval SCE_DF_OPERATOR=13\nval SCE_DF_ICODE=14\n# Lexical states for SCLEX_HOLLYWOOD\nlex Hollywood=SCLEX_HOLLYWOOD SCE_HOLLYWOOD_\nval SCE_HOLLYWOOD_DEFAULT=0\nval SCE_HOLLYWOOD_COMMENT=1\nval SCE_HOLLYWOOD_COMMENTBLOCK=2\nval SCE_HOLLYWOOD_NUMBER=3\nval SCE_HOLLYWOOD_KEYWORD=4\nval SCE_HOLLYWOOD_STDAPI=5\nval SCE_HOLLYWOOD_PLUGINAPI=6\nval SCE_HOLLYWOOD_PLUGINMETHOD=7\nval SCE_HOLLYWOOD_STRING=8\nval SCE_HOLLYWOOD_STRINGBLOCK=9\nval SCE_HOLLYWOOD_PREPROCESSOR=10\nval SCE_HOLLYWOOD_OPERATOR=11\nval SCE_HOLLYWOOD_IDENTIFIER=12\nval SCE_HOLLYWOOD_CONSTANT=13\nval SCE_HOLLYWOOD_HEXNUMBER=14\n# Lexical states for SCLEX_RAKU\nlex Raku=SCLEX_RAKU SCE_RAKU_\nval SCE_RAKU_DEFAULT=0\nval SCE_RAKU_ERROR=1\nval SCE_RAKU_COMMENTLINE=2\nval SCE_RAKU_COMMENTEMBED=3\nval SCE_RAKU_POD=4\nval SCE_RAKU_CHARACTER=5\nval SCE_RAKU_HEREDOC_Q=6\nval SCE_RAKU_HEREDOC_QQ=7\nval SCE_RAKU_STRING=8\nval SCE_RAKU_STRING_Q=9\nval SCE_RAKU_STRING_QQ=10\nval SCE_RAKU_STRING_Q_LANG=11\nval SCE_RAKU_STRING_VAR=12\nval SCE_RAKU_REGEX=13\nval SCE_RAKU_REGEX_VAR=14\nval SCE_RAKU_ADVERB=15\nval SCE_RAKU_NUMBER=16\nval SCE_RAKU_PREPROCESSOR=17\nval SCE_RAKU_OPERATOR=18\nval SCE_RAKU_WORD=19\nval SCE_RAKU_FUNCTION=20\nval SCE_RAKU_IDENTIFIER=21\nval SCE_RAKU_TYPEDEF=22\nval SCE_RAKU_MU=23\nval SCE_RAKU_POSITIONAL=24\nval SCE_RAKU_ASSOCIATIVE=25\nval SCE_RAKU_CALLABLE=26\nval SCE_RAKU_GRAMMAR=27\nval SCE_RAKU_CLASS=28\n# Lexical states for SCLEX_FSHARP\nlex FSharp=SCLEX_FSHARP SCE_FSHARP_\nval SCE_FSHARP_DEFAULT=0\nval SCE_FSHARP_KEYWORD=1\nval SCE_FSHARP_KEYWORD2=2\nval SCE_FSHARP_KEYWORD3=3\nval SCE_FSHARP_KEYWORD4=4\nval SCE_FSHARP_KEYWORD5=5\nval SCE_FSHARP_IDENTIFIER=6\nval SCE_FSHARP_QUOT_IDENTIFIER=7\nval SCE_FSHARP_COMMENT=8\nval SCE_FSHARP_COMMENTLINE=9\nval SCE_FSHARP_PREPROCESSOR=10\nval SCE_FSHARP_LINENUM=11\nval SCE_FSHARP_OPERATOR=12\nval SCE_FSHARP_NUMBER=13\nval SCE_FSHARP_CHARACTER=14\nval SCE_FSHARP_STRING=15\nval SCE_FSHARP_VERBATIM=16\nval SCE_FSHARP_QUOTATION=17\nval SCE_FSHARP_ATTRIBUTE=18\nval SCE_FSHARP_FORMAT_SPEC=19\n# Lexical states for SCLEX_ASCIIDOC\nlex Asciidoc=SCLEX_ASCIIDOC SCE_ASCIIDOC_\nval SCE_ASCIIDOC_DEFAULT=0\nval SCE_ASCIIDOC_STRONG1=1\nval SCE_ASCIIDOC_STRONG2=2\nval SCE_ASCIIDOC_EM1=3\nval SCE_ASCIIDOC_EM2=4\nval SCE_ASCIIDOC_HEADER1=5\nval SCE_ASCIIDOC_HEADER2=6\nval SCE_ASCIIDOC_HEADER3=7\nval SCE_ASCIIDOC_HEADER4=8\nval SCE_ASCIIDOC_HEADER5=9\nval SCE_ASCIIDOC_HEADER6=10\nval SCE_ASCIIDOC_ULIST_ITEM=11\nval SCE_ASCIIDOC_OLIST_ITEM=12\nval SCE_ASCIIDOC_BLOCKQUOTE=13\nval SCE_ASCIIDOC_LINK=14\nval SCE_ASCIIDOC_CODEBK=15\nval SCE_ASCIIDOC_PASSBK=16\nval SCE_ASCIIDOC_COMMENT=17\nval SCE_ASCIIDOC_COMMENTBK=18\nval SCE_ASCIIDOC_LITERAL=19\nval SCE_ASCIIDOC_LITERALBK=20\nval SCE_ASCIIDOC_ATTRIB=21\nval SCE_ASCIIDOC_ATTRIBVAL=22\nval SCE_ASCIIDOC_MACRO=23\n# Lexical states for SCLEX_GDSCRIPT\nlex GDScript=SCLEX_GDSCRIPT SCE_GD_\nval SCE_GD_DEFAULT=0\nval SCE_GD_COMMENTLINE=1\nval SCE_GD_NUMBER=2\nval SCE_GD_STRING=3\nval SCE_GD_CHARACTER=4\nval SCE_GD_WORD=5\nval SCE_GD_TRIPLE=6\nval SCE_GD_TRIPLEDOUBLE=7\nval SCE_GD_CLASSNAME=8\nval SCE_GD_FUNCNAME=9\nval SCE_GD_OPERATOR=10\nval SCE_GD_IDENTIFIER=11\nval SCE_GD_COMMENTBLOCK=12\nval SCE_GD_STRINGEOL=13\nval SCE_GD_WORD2=14\nval SCE_GD_ANNOTATION=15\nval SCE_GD_NODEPATH=16\n# Lexical states for SCLEX_TOML\nlex TOML=SCLEX_TOML SCE_TOML_\nval SCE_TOML_DEFAULT=0\nval SCE_TOML_COMMENT=1\nval SCE_TOML_IDENTIFIER=2\nval SCE_TOML_KEYWORD=3\nval SCE_TOML_NUMBER=4\nval SCE_TOML_TABLE=5\nval SCE_TOML_KEY=6\nval SCE_TOML_ERROR=7\nval SCE_TOML_OPERATOR=8\nval SCE_TOML_STRING_SQ=9\nval SCE_TOML_STRING_DQ=10\nval SCE_TOML_TRIPLE_STRING_SQ=11\nval SCE_TOML_TRIPLE_STRING_DQ=12\nval SCE_TOML_ESCAPECHAR=13\nval SCE_TOML_DATETIME=14\nval SCE_TOML_STRINGEOL=15\n# Lexical states for SCLEX_TROFF\nlex troff=SCLEX_TROFF SCE_TROFF_\nval SCE_TROFF_DEFAULT=0\nval SCE_TROFF_REQUEST=1\nval SCE_TROFF_COMMAND=2\nval SCE_TROFF_NUMBER=3\nval SCE_TROFF_OPERATOR=4\nval SCE_TROFF_STRING=5\nval SCE_TROFF_COMMENT=6\nval SCE_TROFF_IGNORE=7\nval SCE_TROFF_ESCAPE_STRING=8\nval SCE_TROFF_ESCAPE_MACRO=9\nval SCE_TROFF_ESCAPE_FONT=10\nval SCE_TROFF_ESCAPE_NUMBER=11\nval SCE_TROFF_ESCAPE_COLOUR=12\nval SCE_TROFF_ESCAPE_GLYPH=13\nval SCE_TROFF_ESCAPE_ENV=14\nval SCE_TROFF_ESCAPE_SUPPRESSION=15\nval SCE_TROFF_ESCAPE_SIZE=16\nval SCE_TROFF_ESCAPE_TRANSPARENT=17\nval SCE_TROFF_ESCAPE_ISVALID=18\nval SCE_TROFF_ESCAPE_DRAW=19\nval SCE_TROFF_ESCAPE_MOVE=20\nval SCE_TROFF_ESCAPE_HEIGHT=21\nval SCE_TROFF_ESCAPE_OVERSTRIKE=22\nval SCE_TROFF_ESCAPE_SLANT=23\nval SCE_TROFF_ESCAPE_WIDTH=24\nval SCE_TROFF_ESCAPE_VSPACING=25\nval SCE_TROFF_ESCAPE_DEVICE=26\nval SCE_TROFF_ESCAPE_NOMOVE=27\n# Lexical states for SCLEX_DART\nlex Dart=SCLEX_DART SCE_DART_\nval SCE_DART_DEFAULT=0\nval SCE_DART_COMMENTLINE=1\nval SCE_DART_COMMENTLINEDOC=2\nval SCE_DART_COMMENTBLOCK=3\nval SCE_DART_COMMENTBLOCKDOC=4\nval SCE_DART_STRING_SQ=5\nval SCE_DART_STRING_DQ=6\nval SCE_DART_TRIPLE_STRING_SQ=7\nval SCE_DART_TRIPLE_STRING_DQ=8\nval SCE_DART_RAWSTRING_SQ=9\nval SCE_DART_RAWSTRING_DQ=10\nval SCE_DART_TRIPLE_RAWSTRING_SQ=11\nval SCE_DART_TRIPLE_RAWSTRING_DQ=12\nval SCE_DART_ESCAPECHAR=13\nval SCE_DART_IDENTIFIER=14\nval SCE_DART_IDENTIFIER_STRING=15\nval SCE_DART_OPERATOR=16\nval SCE_DART_OPERATOR_STRING=17\nval SCE_DART_SYMBOL_IDENTIFIER=18\nval SCE_DART_SYMBOL_OPERATOR=19\nval SCE_DART_NUMBER=20\nval SCE_DART_KEY=21\nval SCE_DART_METADATA=22\nval SCE_DART_KW_PRIMARY=23\nval SCE_DART_KW_SECONDARY=24\nval SCE_DART_KW_TERTIARY=25\nval SCE_DART_KW_TYPE=26\nval SCE_DART_STRINGEOL=27\n# Lexical states for SCLEX_ZIG\nlex Zig=SCLEX_ZIG SCE_ZIG_\nval SCE_ZIG_DEFAULT=0\nval SCE_ZIG_COMMENTLINE=1\nval SCE_ZIG_COMMENTLINEDOC=2\nval SCE_ZIG_COMMENTLINETOP=3\nval SCE_ZIG_NUMBER=4\nval SCE_ZIG_OPERATOR=5\nval SCE_ZIG_CHARACTER=6\nval SCE_ZIG_STRING=7\nval SCE_ZIG_MULTISTRING=8\nval SCE_ZIG_ESCAPECHAR=9\nval SCE_ZIG_IDENTIFIER=10\nval SCE_ZIG_FUNCTION=11\nval SCE_ZIG_BUILTIN_FUNCTION=12\nval SCE_ZIG_KW_PRIMARY=13\nval SCE_ZIG_KW_SECONDARY=14\nval SCE_ZIG_KW_TERTIARY=15\nval SCE_ZIG_KW_TYPE=16\nval SCE_ZIG_IDENTIFIER_STRING=17\nval SCE_ZIG_STRINGEOL=18\n# Lexical states for SCLEX_NIX\nlex Nix=SCLEX_NIX SCE_NIX_\nval SCE_NIX_DEFAULT=0\nval SCE_NIX_COMMENTLINE=1\nval SCE_NIX_COMMENTBLOCK=2\nval SCE_NIX_STRING=3\nval SCE_NIX_STRING_MULTILINE=4\nval SCE_NIX_ESCAPECHAR=5\nval SCE_NIX_IDENTIFIER=6\nval SCE_NIX_OPERATOR=7\nval SCE_NIX_OPERATOR_STRING=8\nval SCE_NIX_NUMBER=9\nval SCE_NIX_KEY=10\nval SCE_NIX_PATH=11\nval SCE_NIX_KEYWORD1=12\nval SCE_NIX_KEYWORD2=13\nval SCE_NIX_KEYWORD3=14\nval SCE_NIX_KEYWORD4=15\nval SCE_NIX_STRINGEOL=16\n# Lexical states for SCLEX_SINEX\nlex Sinex=SCLEX_SINEX SCE_SINEX_\nval SCE_SINEX_DEFAULT=0\nval SCE_SINEX_COMMENTLINE=1\nval SCE_SINEX_BLOCK_START=2\nval SCE_SINEX_BLOCK_END=3\nval SCE_SINEX_DATE=4\nval SCE_SINEX_NUMBER=5\n# Lexical states for SCLEX_ESCSEQ\nlex ESCSEQ=SCLEX_ESCSEQ SCE_ESCSEQ_\nval SCE_ESCSEQ_DEFAULT=0\nval SCE_ESCSEQ_BLACK_DEFAULT=1\nval SCE_ESCSEQ_RED_DEFAULT=2\nval SCE_ESCSEQ_GREEN_DEFAULT=3\nval SCE_ESCSEQ_YELLOW_DEFAULT=4\nval SCE_ESCSEQ_BLUE_DEFAULT=5\nval SCE_ESCSEQ_MAGENTA_DEFAULT=6\nval SCE_ESCSEQ_CYAN_DEFAULT=7\nval SCE_ESCSEQ_WHITE_DEFAULT=8\nval SCE_ESCSEQ_DEFAULT_BLACK=9\nval SCE_ESCSEQ_BLACK_BLACK=10\nval SCE_ESCSEQ_RED_BLACK=11\nval SCE_ESCSEQ_GREEN_BLACK=12\nval SCE_ESCSEQ_YELLOW_BLACK=13\nval SCE_ESCSEQ_BLUE_BLACK=14\nval SCE_ESCSEQ_MAGENTA_BLACK=15\nval SCE_ESCSEQ_CYAN_BLACK=16\nval SCE_ESCSEQ_WHITE_BLACK=17\nval SCE_ESCSEQ_DEFAULT_RED=18\nval SCE_ESCSEQ_BLACK_RED=19\nval SCE_ESCSEQ_RED_RED=20\nval SCE_ESCSEQ_GREEN_RED=21\nval SCE_ESCSEQ_YELLOW_RED=22\nval SCE_ESCSEQ_BLUE_RED=23\nval SCE_ESCSEQ_MAGENTA_RED=24\nval SCE_ESCSEQ_CYAN_RED=25\nval SCE_ESCSEQ_WHITE_RED=26\nval SCE_ESCSEQ_DEFAULT_GREEN=27\nval SCE_ESCSEQ_BLACK_GREEN=28\nval SCE_ESCSEQ_RED_GREEN=29\nval SCE_ESCSEQ_GREEN_GREEN=30\nval SCE_ESCSEQ_YELLOW_GREEN=40\nval SCE_ESCSEQ_BLUE_GREEN=41\nval SCE_ESCSEQ_MAGENTA_GREEN=42\nval SCE_ESCSEQ_CYAN_GREEN=43\nval SCE_ESCSEQ_WHITE_GREEN=44\nval SCE_ESCSEQ_DEFAULT_YELLOW=45\nval SCE_ESCSEQ_BLACK_YELLOW=46\nval SCE_ESCSEQ_RED_YELLOW=47\nval SCE_ESCSEQ_GREEN_YELLOW=48\nval SCE_ESCSEQ_YELLOW_YELLOW=49\nval SCE_ESCSEQ_BLUE_YELLOW=50\nval SCE_ESCSEQ_MAGENTA_YELLOW=51\nval SCE_ESCSEQ_CYAN_YELLOW=52\nval SCE_ESCSEQ_WHITE_YELLOW=53\nval SCE_ESCSEQ_DEFAULT_BLUE=54\nval SCE_ESCSEQ_BLACK_BLUE=55\nval SCE_ESCSEQ_RED_BLUE=56\nval SCE_ESCSEQ_GREEN_BLUE=57\nval SCE_ESCSEQ_YELLOW_BLUE=58\nval SCE_ESCSEQ_BLUE_BLUE=59\nval SCE_ESCSEQ_MAGENTA_BLUE=60\nval SCE_ESCSEQ_CYAN_BLUE=61\nval SCE_ESCSEQ_WHITE_BLUE=62\nval SCE_ESCSEQ_DEFAULT_MAGENTA=63\nval SCE_ESCSEQ_BLACK_MAGENTA=64\nval SCE_ESCSEQ_RED_MAGENTA=65\nval SCE_ESCSEQ_GREEN_MAGENTA=66\nval SCE_ESCSEQ_YELLOW_MAGENTA=67\nval SCE_ESCSEQ_BLUE_MAGENTA=68\nval SCE_ESCSEQ_MAGENTA_MAGENTA=69\nval SCE_ESCSEQ_CYAN_MAGENTA=70\nval SCE_ESCSEQ_WHITE_MAGENTA=71\nval SCE_ESCSEQ_DEFAULT_CYAN=72\nval SCE_ESCSEQ_BLACK_CYAN=73\nval SCE_ESCSEQ_RED_CYAN=74\nval SCE_ESCSEQ_GREEN_CYAN=75\nval SCE_ESCSEQ_YELLOW_CYAN=76\nval SCE_ESCSEQ_BLUE_CYAN=77\nval SCE_ESCSEQ_MAGENTA_CYAN=78\nval SCE_ESCSEQ_CYAN_CYAN=79\nval SCE_ESCSEQ_WHITE_CYAN=80\nval SCE_ESCSEQ_DEFAULT_WHITE=81\nval SCE_ESCSEQ_BLACK_WHITE=82\nval SCE_ESCSEQ_RED_WHITE=83\nval SCE_ESCSEQ_GREEN_WHITE=84\nval SCE_ESCSEQ_YELLOW_WHITE=85\nval SCE_ESCSEQ_BLUE_WHITE=86\nval SCE_ESCSEQ_MAGENTA_WHITE=87\nval SCE_ESCSEQ_CYAN_WHITE=88\nval SCE_ESCSEQ_WHITE_WHITE=89\nval SCE_ESCSEQ_BOLD_DEFAULT=90\nval SCE_ESCSEQ_BOLD_BLACK_DEFAULT=91\nval SCE_ESCSEQ_BOLD_RED_DEFAULT=92\nval SCE_ESCSEQ_BOLD_GREEN_DEFAULT=93\nval SCE_ESCSEQ_BOLD_YELLOW_DEFAULT=94\nval SCE_ESCSEQ_BOLD_BLUE_DEFAULT=95\nval SCE_ESCSEQ_BOLD_MAGENTA_DEFAULT=96\nval SCE_ESCSEQ_BOLD_CYAN_DEFAULT=97\nval SCE_ESCSEQ_BOLD_WHITE_DEFAULT=98\nval SCE_ESCSEQ_BOLD_DEFAULT_BLACK=99\nval SCE_ESCSEQ_BOLD_BLACK_BLACK=100\nval SCE_ESCSEQ_BOLD_RED_BLACK=101\nval SCE_ESCSEQ_BOLD_GREEN_BLACK=102\nval SCE_ESCSEQ_BOLD_YELLOW_BLACK=103\nval SCE_ESCSEQ_BOLD_BLUE_BLACK=104\nval SCE_ESCSEQ_BOLD_MAGENTA_BLACK=105\nval SCE_ESCSEQ_BOLD_CYAN_BLACK=106\nval SCE_ESCSEQ_BOLD_WHITE_BLACK=107\nval SCE_ESCSEQ_BOLD_DEFAULT_RED=108\nval SCE_ESCSEQ_BOLD_BLACK_RED=109\nval SCE_ESCSEQ_BOLD_RED_RED=110\nval SCE_ESCSEQ_BOLD_GREEN_RED=111\nval SCE_ESCSEQ_BOLD_YELLOW_RED=112\nval SCE_ESCSEQ_BOLD_BLUE_RED=113\nval SCE_ESCSEQ_BOLD_MAGENTA_RED=114\nval SCE_ESCSEQ_BOLD_CYAN_RED=115\nval SCE_ESCSEQ_BOLD_WHITE_RED=116\nval SCE_ESCSEQ_BOLD_DEFAULT_GREEN=117\nval SCE_ESCSEQ_BOLD_BLACK_GREEN=118\nval SCE_ESCSEQ_BOLD_RED_GREEN=119\nval SCE_ESCSEQ_BOLD_GREEN_GREEN=120\nval SCE_ESCSEQ_BOLD_YELLOW_GREEN=121\nval SCE_ESCSEQ_BOLD_BLUE_GREEN=122\nval SCE_ESCSEQ_BOLD_MAGENTA_GREEN=123\nval SCE_ESCSEQ_BOLD_CYAN_GREEN=124\nval SCE_ESCSEQ_BOLD_WHITE_GREEN=125\nval SCE_ESCSEQ_BOLD_DEFAULT_YELLOW=126\nval SCE_ESCSEQ_BOLD_BLACK_YELLOW=127\nval SCE_ESCSEQ_BOLD_RED_YELLOW=128\nval SCE_ESCSEQ_BOLD_GREEN_YELLOW=129\nval SCE_ESCSEQ_BOLD_YELLOW_YELLOW=130\nval SCE_ESCSEQ_BOLD_BLUE_YELLOW=131\nval SCE_ESCSEQ_BOLD_MAGENTA_YELLOW=132\nval SCE_ESCSEQ_BOLD_CYAN_YELLOW=133\nval SCE_ESCSEQ_BOLD_WHITE_YELLOW=134\nval SCE_ESCSEQ_BOLD_DEFAULT_BLUE=135\nval SCE_ESCSEQ_BOLD_BLACK_BLUE=136\nval SCE_ESCSEQ_BOLD_RED_BLUE=137\nval SCE_ESCSEQ_BOLD_GREEN_BLUE=138\nval SCE_ESCSEQ_BOLD_YELLOW_BLUE=139\nval SCE_ESCSEQ_BOLD_BLUE_BLUE=140\nval SCE_ESCSEQ_BOLD_MAGENTA_BLUE=141\nval SCE_ESCSEQ_BOLD_CYAN_BLUE=142\nval SCE_ESCSEQ_BOLD_WHITE_BLUE=143\nval SCE_ESCSEQ_BOLD_DEFAULT_MAGENTA=144\nval SCE_ESCSEQ_BOLD_BLACK_MAGENTA=145\nval SCE_ESCSEQ_BOLD_RED_MAGENTA=146\nval SCE_ESCSEQ_BOLD_GREEN_MAGENTA=147\nval SCE_ESCSEQ_BOLD_YELLOW_MAGENTA=148\nval SCE_ESCSEQ_BOLD_BLUE_MAGENTA=149\nval SCE_ESCSEQ_BOLD_MAGENTA_MAGENTA=150\nval SCE_ESCSEQ_BOLD_CYAN_MAGENTA=151\nval SCE_ESCSEQ_BOLD_WHITE_MAGENTA=152\nval SCE_ESCSEQ_BOLD_DEFAULT_CYAN=153\nval SCE_ESCSEQ_BOLD_BLACK_CYAN=154\nval SCE_ESCSEQ_BOLD_RED_CYAN=155\nval SCE_ESCSEQ_BOLD_GREEN_CYAN=156\nval SCE_ESCSEQ_BOLD_YELLOW_CYAN=157\nval SCE_ESCSEQ_BOLD_BLUE_CYAN=158\nval SCE_ESCSEQ_BOLD_MAGENTA_CYAN=159\nval SCE_ESCSEQ_BOLD_CYAN_CYAN=160\nval SCE_ESCSEQ_BOLD_WHITE_CYAN=161\nval SCE_ESCSEQ_BOLD_DEFAULT_WHITE=162\nval SCE_ESCSEQ_BOLD_BLACK_WHITE=163\nval SCE_ESCSEQ_BOLD_RED_WHITE=164\nval SCE_ESCSEQ_BOLD_GREEN_WHITE=165\nval SCE_ESCSEQ_BOLD_YELLOW_WHITE=166\nval SCE_ESCSEQ_BOLD_BLUE_WHITE=167\nval SCE_ESCSEQ_BOLD_MAGENTA_WHITE=168\nval SCE_ESCSEQ_BOLD_CYAN_WHITE=169\nval SCE_ESCSEQ_BOLD_WHITE_WHITE=170\nval SCE_ESCSEQ_IDENTIFIER=171\nval SCE_ESCSEQ_UNKNOWN=172\n"
  },
  {
    "path": "include/Lexilla.h",
    "content": "// Lexilla lexer library\n/** @file Lexilla.h\n ** Lexilla definitions for dynamic and static linking.\n ** For C++, more features and type safety are available with the LexillaAccess module.\n **/\n// Copyright 2020 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef LEXILLA_H\n#define LEXILLA_H\n\n// Define the default Lexilla shared library name for each platform\n#if defined(_WIN32)\n#define LEXILLA_LIB \"lexilla\"\n#define LEXILLA_EXTENSION \".dll\"\n#else\n#define LEXILLA_LIB \"liblexilla\"\n#if defined(__APPLE__)\n#define LEXILLA_EXTENSION \".dylib\"\n#else\n#define LEXILLA_EXTENSION \".so\"\n#endif\n#endif\n\n// On Win32 use the stdcall calling convention otherwise use the standard calling convention\n#if defined(_WIN32)\n#define LEXILLA_CALL __stdcall\n#else\n#define LEXILLA_CALL\n#endif\n\n#if defined(__OBJC2__)\n// Objective C(++) treats '[' as a message expression.\n#define DEPRECATE_DEFINITION\n#elif defined(__cplusplus)\n#define DEPRECATE_DEFINITION [[deprecated]]\n#elif defined(__GNUC__) || defined(__clang__)\n#define DEPRECATE_DEFINITION __attribute__((deprecated))\n#else\n// MSVC __declspec(deprecated) has different positioning rules to GCC so define to nothing\n#define DEPRECATE_DEFINITION\n#endif\n\n#if defined(__cplusplus)\n// Must have already included ILexer.h to have Scintilla::ILexer5 defined.\nusing Scintilla::ILexer5;\n#else\ntypedef void ILexer5;\n#endif\n\ntypedef ILexer5 *(*LexerFactoryFunction)(void);\n\n#if defined(__cplusplus)\nnamespace Lexilla {\n#endif\n\ntypedef int (LEXILLA_CALL *GetLexerCountFn)(void);\ntypedef void (LEXILLA_CALL *GetLexerNameFn)(unsigned int Index, char *name, int buflength);\ntypedef LexerFactoryFunction(LEXILLA_CALL *GetLexerFactoryFn)(unsigned int Index);\ntypedef ILexer5*(LEXILLA_CALL *CreateLexerFn)(const char *name);\nDEPRECATE_DEFINITION typedef const char *(LEXILLA_CALL *LexerNameFromIDFn)(int identifier);\ntypedef const char *(LEXILLA_CALL *GetLibraryPropertyNamesFn)(void);\ntypedef void(LEXILLA_CALL *SetLibraryPropertyFn)(const char *key, const char *value);\ntypedef const char *(LEXILLA_CALL *GetNameSpaceFn)(void);\n\n#if defined(__cplusplus)\n}\n#endif\n\n#define LEXILLA_NAMESPACE_SEPARATOR '.'\n\n#define LEXILLA_GETLEXERCOUNT \"GetLexerCount\"\n#define LEXILLA_GETLEXERNAME \"GetLexerName\"\n#define LEXILLA_GETLEXERFACTORY \"GetLexerFactory\"\n#define LEXILLA_CREATELEXER \"CreateLexer\"\n#define LEXILLA_LEXERNAMEFROMID \"LexerNameFromID\"\n#define LEXILLA_GETLIBRARYPROPERTYNAMES \"GetLibraryPropertyNames\"\n#define LEXILLA_SETLIBRARYPROPERTY \"SetLibraryProperty\"\n#define LEXILLA_GETNAMESPACE \"GetNameSpace\"\n\n// Static linking prototypes\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\nILexer5 * LEXILLA_CALL CreateLexer(const char *name);\nint LEXILLA_CALL GetLexerCount(void);\nvoid LEXILLA_CALL GetLexerName(unsigned int index, char *name, int buflength);\nLexerFactoryFunction LEXILLA_CALL GetLexerFactory(unsigned int index);\nDEPRECATE_DEFINITION const char *LEXILLA_CALL LexerNameFromID(int identifier);\nconst char * LEXILLA_CALL GetLibraryPropertyNames(void);\nvoid LEXILLA_CALL SetLibraryProperty(const char *key, const char *value);\nconst char *LEXILLA_CALL GetNameSpace(void);\n\n#if defined(__cplusplus)\n}\n#endif\n\n#if defined(__cplusplus)\nnamespace Lexilla {\n\tclass LexerModule;\n}\n// Add a static lexer (in the same binary) to Lexilla's list\nvoid AddStaticLexerModule(const Lexilla::LexerModule *plm);\n#endif\n\n#endif\n"
  },
  {
    "path": "include/SciLexer.h",
    "content": "/* Scintilla source code edit control */\n/** @file SciLexer.h\n ** Interface to the lexer functions in Lexilla.\n ** File called SciLexer.h ro retain compatibility with client code.\n **/\n/* Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n * The License.txt file describes the conditions under which this software may be distributed. */\n\n/* Most of this file is automatically generated from the LexicalStyles.iface interface definition\n * file. LexFacer.py does the generation. */\n\n#ifndef SCILEXER_H\n#define SCILEXER_H\n\n/* Lexilla features */\n\n/* ++Autogenerated -- start of section automatically generated from LexicalStyles.iface */\n#define SCLEX_CONTAINER 0\n#define SCLEX_NULL 1\n#define SCLEX_PYTHON 2\n#define SCLEX_CPP 3\n#define SCLEX_HTML 4\n#define SCLEX_XML 5\n#define SCLEX_PERL 6\n#define SCLEX_SQL 7\n#define SCLEX_VB 8\n#define SCLEX_PROPERTIES 9\n#define SCLEX_ERRORLIST 10\n#define SCLEX_MAKEFILE 11\n#define SCLEX_BATCH 12\n#define SCLEX_XCODE 13\n#define SCLEX_LATEX 14\n#define SCLEX_LUA 15\n#define SCLEX_DIFF 16\n#define SCLEX_CONF 17\n#define SCLEX_PASCAL 18\n#define SCLEX_AVE 19\n#define SCLEX_ADA 20\n#define SCLEX_LISP 21\n#define SCLEX_RUBY 22\n#define SCLEX_EIFFEL 23\n#define SCLEX_EIFFELKW 24\n#define SCLEX_TCL 25\n#define SCLEX_NNCRONTAB 26\n#define SCLEX_BULLANT 27\n#define SCLEX_VBSCRIPT 28\n#define SCLEX_BAAN 31\n#define SCLEX_MATLAB 32\n#define SCLEX_SCRIPTOL 33\n#define SCLEX_ASM 34\n#define SCLEX_CPPNOCASE 35\n#define SCLEX_FORTRAN 36\n#define SCLEX_F77 37\n#define SCLEX_CSS 38\n#define SCLEX_POV 39\n#define SCLEX_LOUT 40\n#define SCLEX_ESCRIPT 41\n#define SCLEX_PS 42\n#define SCLEX_NSIS 43\n#define SCLEX_MMIXAL 44\n#define SCLEX_CLW 45\n#define SCLEX_CLWNOCASE 46\n#define SCLEX_LOT 47\n#define SCLEX_YAML 48\n#define SCLEX_TEX 49\n#define SCLEX_METAPOST 50\n#define SCLEX_POWERBASIC 51\n#define SCLEX_FORTH 52\n#define SCLEX_ERLANG 53\n#define SCLEX_OCTAVE 54\n#define SCLEX_MSSQL 55\n#define SCLEX_VERILOG 56\n#define SCLEX_KIX 57\n#define SCLEX_GUI4CLI 58\n#define SCLEX_SPECMAN 59\n#define SCLEX_AU3 60\n#define SCLEX_APDL 61\n#define SCLEX_BASH 62\n#define SCLEX_ASN1 63\n#define SCLEX_VHDL 64\n#define SCLEX_CAML 65\n#define SCLEX_BLITZBASIC 66\n#define SCLEX_PUREBASIC 67\n#define SCLEX_HASKELL 68\n#define SCLEX_PHPSCRIPT 69\n#define SCLEX_TADS3 70\n#define SCLEX_REBOL 71\n#define SCLEX_SMALLTALK 72\n#define SCLEX_FLAGSHIP 73\n#define SCLEX_CSOUND 74\n#define SCLEX_FREEBASIC 75\n#define SCLEX_INNOSETUP 76\n#define SCLEX_OPAL 77\n#define SCLEX_SPICE 78\n#define SCLEX_D 79\n#define SCLEX_CMAKE 80\n#define SCLEX_GAP 81\n#define SCLEX_PLM 82\n#define SCLEX_PROGRESS 83\n#define SCLEX_ABAQUS 84\n#define SCLEX_ASYMPTOTE 85\n#define SCLEX_R 86\n#define SCLEX_MAGIK 87\n#define SCLEX_POWERSHELL 88\n#define SCLEX_MYSQL 89\n#define SCLEX_PO 90\n#define SCLEX_TAL 91\n#define SCLEX_COBOL 92\n#define SCLEX_TACL 93\n#define SCLEX_SORCUS 94\n#define SCLEX_POWERPRO 95\n#define SCLEX_NIMROD 96\n#define SCLEX_SML 97\n#define SCLEX_MARKDOWN 98\n#define SCLEX_TXT2TAGS 99\n#define SCLEX_A68K 100\n#define SCLEX_MODULA 101\n#define SCLEX_COFFEESCRIPT 102\n#define SCLEX_TCMD 103\n#define SCLEX_AVS 104\n#define SCLEX_ECL 105\n#define SCLEX_OSCRIPT 106\n#define SCLEX_VISUALPROLOG 107\n#define SCLEX_LITERATEHASKELL 108\n#define SCLEX_STTXT 109\n#define SCLEX_KVIRC 110\n#define SCLEX_RUST 111\n#define SCLEX_DMAP 112\n#define SCLEX_AS 113\n#define SCLEX_DMIS 114\n#define SCLEX_REGISTRY 115\n#define SCLEX_BIBTEX 116\n#define SCLEX_SREC 117\n#define SCLEX_IHEX 118\n#define SCLEX_TEHEX 119\n#define SCLEX_JSON 120\n#define SCLEX_EDIFACT 121\n#define SCLEX_INDENT 122\n#define SCLEX_MAXIMA 123\n#define SCLEX_STATA 124\n#define SCLEX_SAS 125\n#define SCLEX_NIM 126\n#define SCLEX_CIL 127\n#define SCLEX_X12 128\n#define SCLEX_DATAFLEX 129\n#define SCLEX_HOLLYWOOD 130\n#define SCLEX_RAKU 131\n#define SCLEX_FSHARP 132\n#define SCLEX_JULIA 133\n#define SCLEX_ASCIIDOC 134\n#define SCLEX_GDSCRIPT 135\n#define SCLEX_TOML 136\n#define SCLEX_TROFF 137\n#define SCLEX_DART 138\n#define SCLEX_ZIG 139\n#define SCLEX_NIX 140\n#define SCLEX_SINEX 141\n#define SCLEX_ESCSEQ 142\n#define SCLEX_AUTOMATIC 1000\n#define SCE_P_DEFAULT 0\n#define SCE_P_COMMENTLINE 1\n#define SCE_P_NUMBER 2\n#define SCE_P_STRING 3\n#define SCE_P_CHARACTER 4\n#define SCE_P_WORD 5\n#define SCE_P_TRIPLE 6\n#define SCE_P_TRIPLEDOUBLE 7\n#define SCE_P_CLASSNAME 8\n#define SCE_P_DEFNAME 9\n#define SCE_P_OPERATOR 10\n#define SCE_P_IDENTIFIER 11\n#define SCE_P_COMMENTBLOCK 12\n#define SCE_P_STRINGEOL 13\n#define SCE_P_WORD2 14\n#define SCE_P_DECORATOR 15\n#define SCE_P_FSTRING 16\n#define SCE_P_FCHARACTER 17\n#define SCE_P_FTRIPLE 18\n#define SCE_P_FTRIPLEDOUBLE 19\n#define SCE_P_ATTRIBUTE 20\n#define SCE_C_DEFAULT 0\n#define SCE_C_COMMENT 1\n#define SCE_C_COMMENTLINE 2\n#define SCE_C_COMMENTDOC 3\n#define SCE_C_NUMBER 4\n#define SCE_C_WORD 5\n#define SCE_C_STRING 6\n#define SCE_C_CHARACTER 7\n#define SCE_C_UUID 8\n#define SCE_C_PREPROCESSOR 9\n#define SCE_C_OPERATOR 10\n#define SCE_C_IDENTIFIER 11\n#define SCE_C_STRINGEOL 12\n#define SCE_C_VERBATIM 13\n#define SCE_C_REGEX 14\n#define SCE_C_COMMENTLINEDOC 15\n#define SCE_C_WORD2 16\n#define SCE_C_COMMENTDOCKEYWORD 17\n#define SCE_C_COMMENTDOCKEYWORDERROR 18\n#define SCE_C_GLOBALCLASS 19\n#define SCE_C_STRINGRAW 20\n#define SCE_C_TRIPLEVERBATIM 21\n#define SCE_C_HASHQUOTEDSTRING 22\n#define SCE_C_PREPROCESSORCOMMENT 23\n#define SCE_C_PREPROCESSORCOMMENTDOC 24\n#define SCE_C_USERLITERAL 25\n#define SCE_C_TASKMARKER 26\n#define SCE_C_ESCAPESEQUENCE 27\n#define SCE_COBOL_DEFAULT 0\n#define SCE_COBOL_COMMENT 1\n#define SCE_COBOL_COMMENTLINE 2\n#define SCE_COBOL_COMMENTDOC 3\n#define SCE_COBOL_NUMBER 4\n#define SCE_COBOL_WORD 5\n#define SCE_COBOL_STRING 6\n#define SCE_COBOL_CHARACTER 7\n#define SCE_COBOL_WORD3 8\n#define SCE_COBOL_PREPROCESSOR 9\n#define SCE_COBOL_OPERATOR 10\n#define SCE_COBOL_IDENTIFIER 11\n#define SCE_COBOL_WORD2 16\n#define SCE_D_DEFAULT 0\n#define SCE_D_COMMENT 1\n#define SCE_D_COMMENTLINE 2\n#define SCE_D_COMMENTDOC 3\n#define SCE_D_COMMENTNESTED 4\n#define SCE_D_NUMBER 5\n#define SCE_D_WORD 6\n#define SCE_D_WORD2 7\n#define SCE_D_WORD3 8\n#define SCE_D_TYPEDEF 9\n#define SCE_D_STRING 10\n#define SCE_D_STRINGEOL 11\n#define SCE_D_CHARACTER 12\n#define SCE_D_OPERATOR 13\n#define SCE_D_IDENTIFIER 14\n#define SCE_D_COMMENTLINEDOC 15\n#define SCE_D_COMMENTDOCKEYWORD 16\n#define SCE_D_COMMENTDOCKEYWORDERROR 17\n#define SCE_D_STRINGB 18\n#define SCE_D_STRINGR 19\n#define SCE_D_WORD5 20\n#define SCE_D_WORD6 21\n#define SCE_D_WORD7 22\n#define SCE_TCL_DEFAULT 0\n#define SCE_TCL_COMMENT 1\n#define SCE_TCL_COMMENTLINE 2\n#define SCE_TCL_NUMBER 3\n#define SCE_TCL_WORD_IN_QUOTE 4\n#define SCE_TCL_IN_QUOTE 5\n#define SCE_TCL_OPERATOR 6\n#define SCE_TCL_IDENTIFIER 7\n#define SCE_TCL_SUBSTITUTION 8\n#define SCE_TCL_SUB_BRACE 9\n#define SCE_TCL_MODIFIER 10\n#define SCE_TCL_EXPAND 11\n#define SCE_TCL_WORD 12\n#define SCE_TCL_WORD2 13\n#define SCE_TCL_WORD3 14\n#define SCE_TCL_WORD4 15\n#define SCE_TCL_WORD5 16\n#define SCE_TCL_WORD6 17\n#define SCE_TCL_WORD7 18\n#define SCE_TCL_WORD8 19\n#define SCE_TCL_COMMENT_BOX 20\n#define SCE_TCL_BLOCK_COMMENT 21\n#define SCE_H_DEFAULT 0\n#define SCE_H_TAG 1\n#define SCE_H_TAGUNKNOWN 2\n#define SCE_H_ATTRIBUTE 3\n#define SCE_H_ATTRIBUTEUNKNOWN 4\n#define SCE_H_NUMBER 5\n#define SCE_H_DOUBLESTRING 6\n#define SCE_H_SINGLESTRING 7\n#define SCE_H_OTHER 8\n#define SCE_H_COMMENT 9\n#define SCE_H_ENTITY 10\n#define SCE_H_TAGEND 11\n#define SCE_H_XMLSTART 12\n#define SCE_H_XMLEND 13\n#define SCE_H_SCRIPT 14\n#define SCE_H_ASP 15\n#define SCE_H_ASPAT 16\n#define SCE_H_CDATA 17\n#define SCE_H_QUESTION 18\n#define SCE_H_VALUE 19\n#define SCE_H_XCCOMMENT 20\n#define SCE_H_SGML_DEFAULT 21\n#define SCE_H_SGML_COMMAND 22\n#define SCE_H_SGML_1ST_PARAM 23\n#define SCE_H_SGML_DOUBLESTRING 24\n#define SCE_H_SGML_SIMPLESTRING 25\n#define SCE_H_SGML_ERROR 26\n#define SCE_H_SGML_SPECIAL 27\n#define SCE_H_SGML_ENTITY 28\n#define SCE_H_SGML_COMMENT 29\n#define SCE_H_SGML_1ST_PARAM_COMMENT 30\n#define SCE_H_SGML_BLOCK_DEFAULT 31\n#define SCE_HJ_START 40\n#define SCE_HJ_DEFAULT 41\n#define SCE_HJ_COMMENT 42\n#define SCE_HJ_COMMENTLINE 43\n#define SCE_HJ_COMMENTDOC 44\n#define SCE_HJ_NUMBER 45\n#define SCE_HJ_WORD 46\n#define SCE_HJ_KEYWORD 47\n#define SCE_HJ_DOUBLESTRING 48\n#define SCE_HJ_SINGLESTRING 49\n#define SCE_HJ_SYMBOLS 50\n#define SCE_HJ_STRINGEOL 51\n#define SCE_HJ_REGEX 52\n#define SCE_HJ_TEMPLATELITERAL 53\n#define SCE_HJA_START 55\n#define SCE_HJA_DEFAULT 56\n#define SCE_HJA_COMMENT 57\n#define SCE_HJA_COMMENTLINE 58\n#define SCE_HJA_COMMENTDOC 59\n#define SCE_HJA_NUMBER 60\n#define SCE_HJA_WORD 61\n#define SCE_HJA_KEYWORD 62\n#define SCE_HJA_DOUBLESTRING 63\n#define SCE_HJA_SINGLESTRING 64\n#define SCE_HJA_SYMBOLS 65\n#define SCE_HJA_STRINGEOL 66\n#define SCE_HJA_REGEX 67\n#define SCE_HJA_TEMPLATELITERAL 68\n#define SCE_HB_START 70\n#define SCE_HB_DEFAULT 71\n#define SCE_HB_COMMENTLINE 72\n#define SCE_HB_NUMBER 73\n#define SCE_HB_WORD 74\n#define SCE_HB_STRING 75\n#define SCE_HB_IDENTIFIER 76\n#define SCE_HB_STRINGEOL 77\n#define SCE_HBA_START 80\n#define SCE_HBA_DEFAULT 81\n#define SCE_HBA_COMMENTLINE 82\n#define SCE_HBA_NUMBER 83\n#define SCE_HBA_WORD 84\n#define SCE_HBA_STRING 85\n#define SCE_HBA_IDENTIFIER 86\n#define SCE_HBA_STRINGEOL 87\n#define SCE_HP_START 90\n#define SCE_HP_DEFAULT 91\n#define SCE_HP_COMMENTLINE 92\n#define SCE_HP_NUMBER 93\n#define SCE_HP_STRING 94\n#define SCE_HP_CHARACTER 95\n#define SCE_HP_WORD 96\n#define SCE_HP_TRIPLE 97\n#define SCE_HP_TRIPLEDOUBLE 98\n#define SCE_HP_CLASSNAME 99\n#define SCE_HP_DEFNAME 100\n#define SCE_HP_OPERATOR 101\n#define SCE_HP_IDENTIFIER 102\n#define SCE_HPHP_COMPLEX_VARIABLE 104\n#define SCE_HPA_START 105\n#define SCE_HPA_DEFAULT 106\n#define SCE_HPA_COMMENTLINE 107\n#define SCE_HPA_NUMBER 108\n#define SCE_HPA_STRING 109\n#define SCE_HPA_CHARACTER 110\n#define SCE_HPA_WORD 111\n#define SCE_HPA_TRIPLE 112\n#define SCE_HPA_TRIPLEDOUBLE 113\n#define SCE_HPA_CLASSNAME 114\n#define SCE_HPA_DEFNAME 115\n#define SCE_HPA_OPERATOR 116\n#define SCE_HPA_IDENTIFIER 117\n#define SCE_HPHP_DEFAULT 118\n#define SCE_HPHP_HSTRING 119\n#define SCE_HPHP_SIMPLESTRING 120\n#define SCE_HPHP_WORD 121\n#define SCE_HPHP_NUMBER 122\n#define SCE_HPHP_VARIABLE 123\n#define SCE_HPHP_COMMENT 124\n#define SCE_HPHP_COMMENTLINE 125\n#define SCE_HPHP_HSTRING_VARIABLE 126\n#define SCE_HPHP_OPERATOR 127\n#define SCE_PL_DEFAULT 0\n#define SCE_PL_ERROR 1\n#define SCE_PL_COMMENTLINE 2\n#define SCE_PL_POD 3\n#define SCE_PL_NUMBER 4\n#define SCE_PL_WORD 5\n#define SCE_PL_STRING 6\n#define SCE_PL_CHARACTER 7\n#define SCE_PL_PUNCTUATION 8\n#define SCE_PL_PREPROCESSOR 9\n#define SCE_PL_OPERATOR 10\n#define SCE_PL_IDENTIFIER 11\n#define SCE_PL_SCALAR 12\n#define SCE_PL_ARRAY 13\n#define SCE_PL_HASH 14\n#define SCE_PL_SYMBOLTABLE 15\n#define SCE_PL_VARIABLE_INDEXER 16\n#define SCE_PL_REGEX 17\n#define SCE_PL_REGSUBST 18\n#define SCE_PL_LONGQUOTE 19\n#define SCE_PL_BACKTICKS 20\n#define SCE_PL_DATASECTION 21\n#define SCE_PL_HERE_DELIM 22\n#define SCE_PL_HERE_Q 23\n#define SCE_PL_HERE_QQ 24\n#define SCE_PL_HERE_QX 25\n#define SCE_PL_STRING_Q 26\n#define SCE_PL_STRING_QQ 27\n#define SCE_PL_STRING_QX 28\n#define SCE_PL_STRING_QR 29\n#define SCE_PL_STRING_QW 30\n#define SCE_PL_POD_VERB 31\n#define SCE_PL_SUB_PROTOTYPE 40\n#define SCE_PL_FORMAT_IDENT 41\n#define SCE_PL_FORMAT 42\n#define SCE_PL_STRING_VAR 43\n#define SCE_PL_XLAT 44\n#define SCE_PL_REGEX_VAR 54\n#define SCE_PL_REGSUBST_VAR 55\n#define SCE_PL_BACKTICKS_VAR 57\n#define SCE_PL_HERE_QQ_VAR 61\n#define SCE_PL_HERE_QX_VAR 62\n#define SCE_PL_STRING_QQ_VAR 64\n#define SCE_PL_STRING_QX_VAR 65\n#define SCE_PL_STRING_QR_VAR 66\n#define SCE_RB_DEFAULT 0\n#define SCE_RB_ERROR 1\n#define SCE_RB_COMMENTLINE 2\n#define SCE_RB_POD 3\n#define SCE_RB_NUMBER 4\n#define SCE_RB_WORD 5\n#define SCE_RB_STRING 6\n#define SCE_RB_CHARACTER 7\n#define SCE_RB_CLASSNAME 8\n#define SCE_RB_DEFNAME 9\n#define SCE_RB_OPERATOR 10\n#define SCE_RB_IDENTIFIER 11\n#define SCE_RB_REGEX 12\n#define SCE_RB_GLOBAL 13\n#define SCE_RB_SYMBOL 14\n#define SCE_RB_MODULE_NAME 15\n#define SCE_RB_INSTANCE_VAR 16\n#define SCE_RB_CLASS_VAR 17\n#define SCE_RB_BACKTICKS 18\n#define SCE_RB_DATASECTION 19\n#define SCE_RB_HERE_DELIM 20\n#define SCE_RB_HERE_Q 21\n#define SCE_RB_HERE_QQ 22\n#define SCE_RB_HERE_QX 23\n#define SCE_RB_STRING_Q 24\n#define SCE_RB_STRING_QQ 25\n#define SCE_RB_STRING_QX 26\n#define SCE_RB_STRING_QR 27\n#define SCE_RB_STRING_QW 28\n#define SCE_RB_WORD_DEMOTED 29\n#define SCE_RB_STDIN 30\n#define SCE_RB_STDOUT 31\n#define SCE_RB_STDERR 40\n#define SCE_RB_STRING_W 41\n#define SCE_RB_STRING_I 42\n#define SCE_RB_STRING_QI 43\n#define SCE_RB_STRING_QS 44\n#define SCE_RB_UPPER_BOUND 45\n#define SCE_B_DEFAULT 0\n#define SCE_B_COMMENT 1\n#define SCE_B_NUMBER 2\n#define SCE_B_KEYWORD 3\n#define SCE_B_STRING 4\n#define SCE_B_PREPROCESSOR 5\n#define SCE_B_OPERATOR 6\n#define SCE_B_IDENTIFIER 7\n#define SCE_B_DATE 8\n#define SCE_B_STRINGEOL 9\n#define SCE_B_KEYWORD2 10\n#define SCE_B_KEYWORD3 11\n#define SCE_B_KEYWORD4 12\n#define SCE_B_CONSTANT 13\n#define SCE_B_ASM 14\n#define SCE_B_LABEL 15\n#define SCE_B_ERROR 16\n#define SCE_B_HEXNUMBER 17\n#define SCE_B_BINNUMBER 18\n#define SCE_B_COMMENTBLOCK 19\n#define SCE_B_DOCLINE 20\n#define SCE_B_DOCBLOCK 21\n#define SCE_B_DOCKEYWORD 22\n#define SCE_PROPS_DEFAULT 0\n#define SCE_PROPS_COMMENT 1\n#define SCE_PROPS_SECTION 2\n#define SCE_PROPS_ASSIGNMENT 3\n#define SCE_PROPS_DEFVAL 4\n#define SCE_PROPS_KEY 5\n#define SCE_L_DEFAULT 0\n#define SCE_L_COMMAND 1\n#define SCE_L_TAG 2\n#define SCE_L_MATH 3\n#define SCE_L_COMMENT 4\n#define SCE_L_TAG2 5\n#define SCE_L_MATH2 6\n#define SCE_L_COMMENT2 7\n#define SCE_L_VERBATIM 8\n#define SCE_L_SHORTCMD 9\n#define SCE_L_SPECIAL 10\n#define SCE_L_CMDOPT 11\n#define SCE_L_ERROR 12\n#define SCE_LUA_DEFAULT 0\n#define SCE_LUA_COMMENT 1\n#define SCE_LUA_COMMENTLINE 2\n#define SCE_LUA_COMMENTDOC 3\n#define SCE_LUA_NUMBER 4\n#define SCE_LUA_WORD 5\n#define SCE_LUA_STRING 6\n#define SCE_LUA_CHARACTER 7\n#define SCE_LUA_LITERALSTRING 8\n#define SCE_LUA_PREPROCESSOR 9\n#define SCE_LUA_OPERATOR 10\n#define SCE_LUA_IDENTIFIER 11\n#define SCE_LUA_STRINGEOL 12\n#define SCE_LUA_WORD2 13\n#define SCE_LUA_WORD3 14\n#define SCE_LUA_WORD4 15\n#define SCE_LUA_WORD5 16\n#define SCE_LUA_WORD6 17\n#define SCE_LUA_WORD7 18\n#define SCE_LUA_WORD8 19\n#define SCE_LUA_LABEL 20\n#define SCE_ERR_DEFAULT 0\n#define SCE_ERR_PYTHON 1\n#define SCE_ERR_GCC 2\n#define SCE_ERR_MS 3\n#define SCE_ERR_CMD 4\n#define SCE_ERR_BORLAND 5\n#define SCE_ERR_PERL 6\n#define SCE_ERR_NET 7\n#define SCE_ERR_LUA 8\n#define SCE_ERR_CTAG 9\n#define SCE_ERR_DIFF_CHANGED 10\n#define SCE_ERR_DIFF_ADDITION 11\n#define SCE_ERR_DIFF_DELETION 12\n#define SCE_ERR_DIFF_MESSAGE 13\n#define SCE_ERR_PHP 14\n#define SCE_ERR_ELF 15\n#define SCE_ERR_IFC 16\n#define SCE_ERR_IFORT 17\n#define SCE_ERR_ABSF 18\n#define SCE_ERR_TIDY 19\n#define SCE_ERR_JAVA_STACK 20\n#define SCE_ERR_VALUE 21\n#define SCE_ERR_GCC_INCLUDED_FROM 22\n#define SCE_ERR_ESCSEQ 23\n#define SCE_ERR_ESCSEQ_UNKNOWN 24\n#define SCE_ERR_GCC_EXCERPT 25\n#define SCE_ERR_BASH 26\n#define SCE_ERR_ES_BLACK 40\n#define SCE_ERR_ES_RED 41\n#define SCE_ERR_ES_GREEN 42\n#define SCE_ERR_ES_BROWN 43\n#define SCE_ERR_ES_BLUE 44\n#define SCE_ERR_ES_MAGENTA 45\n#define SCE_ERR_ES_CYAN 46\n#define SCE_ERR_ES_GRAY 47\n#define SCE_ERR_ES_DARK_GRAY 48\n#define SCE_ERR_ES_BRIGHT_RED 49\n#define SCE_ERR_ES_BRIGHT_GREEN 50\n#define SCE_ERR_ES_YELLOW 51\n#define SCE_ERR_ES_BRIGHT_BLUE 52\n#define SCE_ERR_ES_BRIGHT_MAGENTA 53\n#define SCE_ERR_ES_BRIGHT_CYAN 54\n#define SCE_ERR_ES_WHITE 55\n#define SCE_BAT_DEFAULT 0\n#define SCE_BAT_COMMENT 1\n#define SCE_BAT_WORD 2\n#define SCE_BAT_LABEL 3\n#define SCE_BAT_HIDE 4\n#define SCE_BAT_COMMAND 5\n#define SCE_BAT_IDENTIFIER 6\n#define SCE_BAT_OPERATOR 7\n#define SCE_BAT_AFTER_LABEL 8\n#define SCE_TCMD_DEFAULT 0\n#define SCE_TCMD_COMMENT 1\n#define SCE_TCMD_WORD 2\n#define SCE_TCMD_LABEL 3\n#define SCE_TCMD_HIDE 4\n#define SCE_TCMD_COMMAND 5\n#define SCE_TCMD_IDENTIFIER 6\n#define SCE_TCMD_OPERATOR 7\n#define SCE_TCMD_ENVIRONMENT 8\n#define SCE_TCMD_EXPANSION 9\n#define SCE_TCMD_CLABEL 10\n#define SCE_MAKE_DEFAULT 0\n#define SCE_MAKE_COMMENT 1\n#define SCE_MAKE_PREPROCESSOR 2\n#define SCE_MAKE_IDENTIFIER 3\n#define SCE_MAKE_OPERATOR 4\n#define SCE_MAKE_TARGET 5\n#define SCE_MAKE_IDEOL 9\n#define SCE_DIFF_DEFAULT 0\n#define SCE_DIFF_COMMENT 1\n#define SCE_DIFF_COMMAND 2\n#define SCE_DIFF_HEADER 3\n#define SCE_DIFF_POSITION 4\n#define SCE_DIFF_DELETED 5\n#define SCE_DIFF_ADDED 6\n#define SCE_DIFF_CHANGED 7\n#define SCE_DIFF_PATCH_ADD 8\n#define SCE_DIFF_PATCH_DELETE 9\n#define SCE_DIFF_REMOVED_PATCH_ADD 10\n#define SCE_DIFF_REMOVED_PATCH_DELETE 11\n#define SCE_CONF_DEFAULT 0\n#define SCE_CONF_COMMENT 1\n#define SCE_CONF_NUMBER 2\n#define SCE_CONF_IDENTIFIER 3\n#define SCE_CONF_EXTENSION 4\n#define SCE_CONF_PARAMETER 5\n#define SCE_CONF_STRING 6\n#define SCE_CONF_OPERATOR 7\n#define SCE_CONF_IP 8\n#define SCE_CONF_DIRECTIVE 9\n#define SCE_AVE_DEFAULT 0\n#define SCE_AVE_COMMENT 1\n#define SCE_AVE_NUMBER 2\n#define SCE_AVE_WORD 3\n#define SCE_AVE_STRING 6\n#define SCE_AVE_ENUM 7\n#define SCE_AVE_STRINGEOL 8\n#define SCE_AVE_IDENTIFIER 9\n#define SCE_AVE_OPERATOR 10\n#define SCE_AVE_WORD1 11\n#define SCE_AVE_WORD2 12\n#define SCE_AVE_WORD3 13\n#define SCE_AVE_WORD4 14\n#define SCE_AVE_WORD5 15\n#define SCE_AVE_WORD6 16\n#define SCE_ADA_DEFAULT 0\n#define SCE_ADA_WORD 1\n#define SCE_ADA_IDENTIFIER 2\n#define SCE_ADA_NUMBER 3\n#define SCE_ADA_DELIMITER 4\n#define SCE_ADA_CHARACTER 5\n#define SCE_ADA_CHARACTEREOL 6\n#define SCE_ADA_STRING 7\n#define SCE_ADA_STRINGEOL 8\n#define SCE_ADA_LABEL 9\n#define SCE_ADA_COMMENTLINE 10\n#define SCE_ADA_ILLEGAL 11\n#define SCE_BAAN_DEFAULT 0\n#define SCE_BAAN_COMMENT 1\n#define SCE_BAAN_COMMENTDOC 2\n#define SCE_BAAN_NUMBER 3\n#define SCE_BAAN_WORD 4\n#define SCE_BAAN_STRING 5\n#define SCE_BAAN_PREPROCESSOR 6\n#define SCE_BAAN_OPERATOR 7\n#define SCE_BAAN_IDENTIFIER 8\n#define SCE_BAAN_STRINGEOL 9\n#define SCE_BAAN_WORD2 10\n#define SCE_BAAN_WORD3 11\n#define SCE_BAAN_WORD4 12\n#define SCE_BAAN_WORD5 13\n#define SCE_BAAN_WORD6 14\n#define SCE_BAAN_WORD7 15\n#define SCE_BAAN_WORD8 16\n#define SCE_BAAN_WORD9 17\n#define SCE_BAAN_TABLEDEF 18\n#define SCE_BAAN_TABLESQL 19\n#define SCE_BAAN_FUNCTION 20\n#define SCE_BAAN_DOMDEF 21\n#define SCE_BAAN_FUNCDEF 22\n#define SCE_BAAN_OBJECTDEF 23\n#define SCE_BAAN_DEFINEDEF 24\n#define SCE_LISP_DEFAULT 0\n#define SCE_LISP_COMMENT 1\n#define SCE_LISP_NUMBER 2\n#define SCE_LISP_KEYWORD 3\n#define SCE_LISP_KEYWORD_KW 4\n#define SCE_LISP_SYMBOL 5\n#define SCE_LISP_STRING 6\n#define SCE_LISP_STRINGEOL 8\n#define SCE_LISP_IDENTIFIER 9\n#define SCE_LISP_OPERATOR 10\n#define SCE_LISP_SPECIAL 11\n#define SCE_LISP_MULTI_COMMENT 12\n#define SCE_EIFFEL_DEFAULT 0\n#define SCE_EIFFEL_COMMENTLINE 1\n#define SCE_EIFFEL_NUMBER 2\n#define SCE_EIFFEL_WORD 3\n#define SCE_EIFFEL_STRING 4\n#define SCE_EIFFEL_CHARACTER 5\n#define SCE_EIFFEL_OPERATOR 6\n#define SCE_EIFFEL_IDENTIFIER 7\n#define SCE_EIFFEL_STRINGEOL 8\n#define SCE_NNCRONTAB_DEFAULT 0\n#define SCE_NNCRONTAB_COMMENT 1\n#define SCE_NNCRONTAB_TASK 2\n#define SCE_NNCRONTAB_SECTION 3\n#define SCE_NNCRONTAB_KEYWORD 4\n#define SCE_NNCRONTAB_MODIFIER 5\n#define SCE_NNCRONTAB_ASTERISK 6\n#define SCE_NNCRONTAB_NUMBER 7\n#define SCE_NNCRONTAB_STRING 8\n#define SCE_NNCRONTAB_ENVIRONMENT 9\n#define SCE_NNCRONTAB_IDENTIFIER 10\n#define SCE_FORTH_DEFAULT 0\n#define SCE_FORTH_COMMENT 1\n#define SCE_FORTH_COMMENT_ML 2\n#define SCE_FORTH_IDENTIFIER 3\n#define SCE_FORTH_CONTROL 4\n#define SCE_FORTH_KEYWORD 5\n#define SCE_FORTH_DEFWORD 6\n#define SCE_FORTH_PREWORD1 7\n#define SCE_FORTH_PREWORD2 8\n#define SCE_FORTH_NUMBER 9\n#define SCE_FORTH_STRING 10\n#define SCE_FORTH_LOCALE 11\n#define SCE_MATLAB_DEFAULT 0\n#define SCE_MATLAB_COMMENT 1\n#define SCE_MATLAB_COMMAND 2\n#define SCE_MATLAB_NUMBER 3\n#define SCE_MATLAB_KEYWORD 4\n#define SCE_MATLAB_STRING 5\n#define SCE_MATLAB_OPERATOR 6\n#define SCE_MATLAB_IDENTIFIER 7\n#define SCE_MATLAB_DOUBLEQUOTESTRING 8\n#define SCE_MAXIMA_OPERATOR 0\n#define SCE_MAXIMA_COMMANDENDING 1\n#define SCE_MAXIMA_COMMENT 2\n#define SCE_MAXIMA_NUMBER 3\n#define SCE_MAXIMA_STRING 4\n#define SCE_MAXIMA_COMMAND 5\n#define SCE_MAXIMA_VARIABLE 6\n#define SCE_MAXIMA_UNKNOWN 7\n#define SCE_SCRIPTOL_DEFAULT 0\n#define SCE_SCRIPTOL_WHITE 1\n#define SCE_SCRIPTOL_COMMENTLINE 2\n#define SCE_SCRIPTOL_PERSISTENT 3\n#define SCE_SCRIPTOL_CSTYLE 4\n#define SCE_SCRIPTOL_COMMENTBLOCK 5\n#define SCE_SCRIPTOL_NUMBER 6\n#define SCE_SCRIPTOL_STRING 7\n#define SCE_SCRIPTOL_CHARACTER 8\n#define SCE_SCRIPTOL_STRINGEOL 9\n#define SCE_SCRIPTOL_KEYWORD 10\n#define SCE_SCRIPTOL_OPERATOR 11\n#define SCE_SCRIPTOL_IDENTIFIER 12\n#define SCE_SCRIPTOL_TRIPLE 13\n#define SCE_SCRIPTOL_CLASSNAME 14\n#define SCE_SCRIPTOL_PREPROCESSOR 15\n#define SCE_ASM_DEFAULT 0\n#define SCE_ASM_COMMENT 1\n#define SCE_ASM_NUMBER 2\n#define SCE_ASM_STRING 3\n#define SCE_ASM_OPERATOR 4\n#define SCE_ASM_IDENTIFIER 5\n#define SCE_ASM_CPUINSTRUCTION 6\n#define SCE_ASM_MATHINSTRUCTION 7\n#define SCE_ASM_REGISTER 8\n#define SCE_ASM_DIRECTIVE 9\n#define SCE_ASM_DIRECTIVEOPERAND 10\n#define SCE_ASM_COMMENTBLOCK 11\n#define SCE_ASM_CHARACTER 12\n#define SCE_ASM_STRINGEOL 13\n#define SCE_ASM_EXTINSTRUCTION 14\n#define SCE_ASM_COMMENTDIRECTIVE 15\n#define SCE_ASM_STRINGBACKQUOTE 16\n#define SCE_F_DEFAULT 0\n#define SCE_F_COMMENT 1\n#define SCE_F_NUMBER 2\n#define SCE_F_STRING1 3\n#define SCE_F_STRING2 4\n#define SCE_F_STRINGEOL 5\n#define SCE_F_OPERATOR 6\n#define SCE_F_IDENTIFIER 7\n#define SCE_F_WORD 8\n#define SCE_F_WORD2 9\n#define SCE_F_WORD3 10\n#define SCE_F_PREPROCESSOR 11\n#define SCE_F_OPERATOR2 12\n#define SCE_F_LABEL 13\n#define SCE_F_CONTINUATION 14\n#define SCE_CSS_DEFAULT 0\n#define SCE_CSS_TAG 1\n#define SCE_CSS_CLASS 2\n#define SCE_CSS_PSEUDOCLASS 3\n#define SCE_CSS_UNKNOWN_PSEUDOCLASS 4\n#define SCE_CSS_OPERATOR 5\n#define SCE_CSS_IDENTIFIER 6\n#define SCE_CSS_UNKNOWN_IDENTIFIER 7\n#define SCE_CSS_VALUE 8\n#define SCE_CSS_COMMENT 9\n#define SCE_CSS_ID 10\n#define SCE_CSS_IMPORTANT 11\n#define SCE_CSS_DIRECTIVE 12\n#define SCE_CSS_DOUBLESTRING 13\n#define SCE_CSS_SINGLESTRING 14\n#define SCE_CSS_IDENTIFIER2 15\n#define SCE_CSS_ATTRIBUTE 16\n#define SCE_CSS_IDENTIFIER3 17\n#define SCE_CSS_PSEUDOELEMENT 18\n#define SCE_CSS_EXTENDED_IDENTIFIER 19\n#define SCE_CSS_EXTENDED_PSEUDOCLASS 20\n#define SCE_CSS_EXTENDED_PSEUDOELEMENT 21\n#define SCE_CSS_GROUP_RULE 22\n#define SCE_CSS_VARIABLE 23\n#define SCE_POV_DEFAULT 0\n#define SCE_POV_COMMENT 1\n#define SCE_POV_COMMENTLINE 2\n#define SCE_POV_NUMBER 3\n#define SCE_POV_OPERATOR 4\n#define SCE_POV_IDENTIFIER 5\n#define SCE_POV_STRING 6\n#define SCE_POV_STRINGEOL 7\n#define SCE_POV_DIRECTIVE 8\n#define SCE_POV_BADDIRECTIVE 9\n#define SCE_POV_WORD2 10\n#define SCE_POV_WORD3 11\n#define SCE_POV_WORD4 12\n#define SCE_POV_WORD5 13\n#define SCE_POV_WORD6 14\n#define SCE_POV_WORD7 15\n#define SCE_POV_WORD8 16\n#define SCE_LOUT_DEFAULT 0\n#define SCE_LOUT_COMMENT 1\n#define SCE_LOUT_NUMBER 2\n#define SCE_LOUT_WORD 3\n#define SCE_LOUT_WORD2 4\n#define SCE_LOUT_WORD3 5\n#define SCE_LOUT_WORD4 6\n#define SCE_LOUT_STRING 7\n#define SCE_LOUT_OPERATOR 8\n#define SCE_LOUT_IDENTIFIER 9\n#define SCE_LOUT_STRINGEOL 10\n#define SCE_ESCRIPT_DEFAULT 0\n#define SCE_ESCRIPT_COMMENT 1\n#define SCE_ESCRIPT_COMMENTLINE 2\n#define SCE_ESCRIPT_COMMENTDOC 3\n#define SCE_ESCRIPT_NUMBER 4\n#define SCE_ESCRIPT_WORD 5\n#define SCE_ESCRIPT_STRING 6\n#define SCE_ESCRIPT_OPERATOR 7\n#define SCE_ESCRIPT_IDENTIFIER 8\n#define SCE_ESCRIPT_BRACE 9\n#define SCE_ESCRIPT_WORD2 10\n#define SCE_ESCRIPT_WORD3 11\n#define SCE_PS_DEFAULT 0\n#define SCE_PS_COMMENT 1\n#define SCE_PS_DSC_COMMENT 2\n#define SCE_PS_DSC_VALUE 3\n#define SCE_PS_NUMBER 4\n#define SCE_PS_NAME 5\n#define SCE_PS_KEYWORD 6\n#define SCE_PS_LITERAL 7\n#define SCE_PS_IMMEVAL 8\n#define SCE_PS_PAREN_ARRAY 9\n#define SCE_PS_PAREN_DICT 10\n#define SCE_PS_PAREN_PROC 11\n#define SCE_PS_TEXT 12\n#define SCE_PS_HEXSTRING 13\n#define SCE_PS_BASE85STRING 14\n#define SCE_PS_BADSTRINGCHAR 15\n#define SCE_NSIS_DEFAULT 0\n#define SCE_NSIS_COMMENT 1\n#define SCE_NSIS_STRINGDQ 2\n#define SCE_NSIS_STRINGLQ 3\n#define SCE_NSIS_STRINGRQ 4\n#define SCE_NSIS_FUNCTION 5\n#define SCE_NSIS_VARIABLE 6\n#define SCE_NSIS_LABEL 7\n#define SCE_NSIS_USERDEFINED 8\n#define SCE_NSIS_SECTIONDEF 9\n#define SCE_NSIS_SUBSECTIONDEF 10\n#define SCE_NSIS_IFDEFINEDEF 11\n#define SCE_NSIS_MACRODEF 12\n#define SCE_NSIS_STRINGVAR 13\n#define SCE_NSIS_NUMBER 14\n#define SCE_NSIS_SECTIONGROUP 15\n#define SCE_NSIS_PAGEEX 16\n#define SCE_NSIS_FUNCTIONDEF 17\n#define SCE_NSIS_COMMENTBOX 18\n#define SCE_MMIXAL_LEADWS 0\n#define SCE_MMIXAL_COMMENT 1\n#define SCE_MMIXAL_LABEL 2\n#define SCE_MMIXAL_OPCODE 3\n#define SCE_MMIXAL_OPCODE_PRE 4\n#define SCE_MMIXAL_OPCODE_VALID 5\n#define SCE_MMIXAL_OPCODE_UNKNOWN 6\n#define SCE_MMIXAL_OPCODE_POST 7\n#define SCE_MMIXAL_OPERANDS 8\n#define SCE_MMIXAL_NUMBER 9\n#define SCE_MMIXAL_REF 10\n#define SCE_MMIXAL_CHAR 11\n#define SCE_MMIXAL_STRING 12\n#define SCE_MMIXAL_REGISTER 13\n#define SCE_MMIXAL_HEX 14\n#define SCE_MMIXAL_OPERATOR 15\n#define SCE_MMIXAL_SYMBOL 16\n#define SCE_MMIXAL_INCLUDE 17\n#define SCE_CLW_DEFAULT 0\n#define SCE_CLW_LABEL 1\n#define SCE_CLW_COMMENT 2\n#define SCE_CLW_STRING 3\n#define SCE_CLW_USER_IDENTIFIER 4\n#define SCE_CLW_INTEGER_CONSTANT 5\n#define SCE_CLW_REAL_CONSTANT 6\n#define SCE_CLW_PICTURE_STRING 7\n#define SCE_CLW_KEYWORD 8\n#define SCE_CLW_COMPILER_DIRECTIVE 9\n#define SCE_CLW_RUNTIME_EXPRESSIONS 10\n#define SCE_CLW_BUILTIN_PROCEDURES_FUNCTION 11\n#define SCE_CLW_STRUCTURE_DATA_TYPE 12\n#define SCE_CLW_ATTRIBUTE 13\n#define SCE_CLW_STANDARD_EQUATE 14\n#define SCE_CLW_ERROR 15\n#define SCE_CLW_DEPRECATED 16\n#define SCE_LOT_DEFAULT 0\n#define SCE_LOT_HEADER 1\n#define SCE_LOT_BREAK 2\n#define SCE_LOT_SET 3\n#define SCE_LOT_PASS 4\n#define SCE_LOT_FAIL 5\n#define SCE_LOT_ABORT 6\n#define SCE_YAML_DEFAULT 0\n#define SCE_YAML_COMMENT 1\n#define SCE_YAML_IDENTIFIER 2\n#define SCE_YAML_KEYWORD 3\n#define SCE_YAML_NUMBER 4\n#define SCE_YAML_REFERENCE 5\n#define SCE_YAML_DOCUMENT 6\n#define SCE_YAML_TEXT 7\n#define SCE_YAML_ERROR 8\n#define SCE_YAML_OPERATOR 9\n#define SCE_TEX_DEFAULT 0\n#define SCE_TEX_SPECIAL 1\n#define SCE_TEX_GROUP 2\n#define SCE_TEX_SYMBOL 3\n#define SCE_TEX_COMMAND 4\n#define SCE_TEX_TEXT 5\n#define SCE_METAPOST_DEFAULT 0\n#define SCE_METAPOST_SPECIAL 1\n#define SCE_METAPOST_GROUP 2\n#define SCE_METAPOST_SYMBOL 3\n#define SCE_METAPOST_COMMAND 4\n#define SCE_METAPOST_TEXT 5\n#define SCE_METAPOST_EXTRA 6\n#define SCE_ERLANG_DEFAULT 0\n#define SCE_ERLANG_COMMENT 1\n#define SCE_ERLANG_VARIABLE 2\n#define SCE_ERLANG_NUMBER 3\n#define SCE_ERLANG_KEYWORD 4\n#define SCE_ERLANG_STRING 5\n#define SCE_ERLANG_OPERATOR 6\n#define SCE_ERLANG_ATOM 7\n#define SCE_ERLANG_FUNCTION_NAME 8\n#define SCE_ERLANG_CHARACTER 9\n#define SCE_ERLANG_MACRO 10\n#define SCE_ERLANG_RECORD 11\n#define SCE_ERLANG_PREPROC 12\n#define SCE_ERLANG_NODE_NAME 13\n#define SCE_ERLANG_COMMENT_FUNCTION 14\n#define SCE_ERLANG_COMMENT_MODULE 15\n#define SCE_ERLANG_COMMENT_DOC 16\n#define SCE_ERLANG_COMMENT_DOC_MACRO 17\n#define SCE_ERLANG_ATOM_QUOTED 18\n#define SCE_ERLANG_MACRO_QUOTED 19\n#define SCE_ERLANG_RECORD_QUOTED 20\n#define SCE_ERLANG_NODE_NAME_QUOTED 21\n#define SCE_ERLANG_BIFS 22\n#define SCE_ERLANG_MODULES 23\n#define SCE_ERLANG_MODULES_ATT 24\n#define SCE_ERLANG_UNKNOWN 31\n#define SCE_JULIA_DEFAULT 0\n#define SCE_JULIA_COMMENT 1\n#define SCE_JULIA_NUMBER 2\n#define SCE_JULIA_KEYWORD1 3\n#define SCE_JULIA_KEYWORD2 4\n#define SCE_JULIA_KEYWORD3 5\n#define SCE_JULIA_CHAR 6\n#define SCE_JULIA_OPERATOR 7\n#define SCE_JULIA_BRACKET 8\n#define SCE_JULIA_IDENTIFIER 9\n#define SCE_JULIA_STRING 10\n#define SCE_JULIA_SYMBOL 11\n#define SCE_JULIA_MACRO 12\n#define SCE_JULIA_STRINGINTERP 13\n#define SCE_JULIA_DOCSTRING 14\n#define SCE_JULIA_STRINGLITERAL 15\n#define SCE_JULIA_COMMAND 16\n#define SCE_JULIA_COMMANDLITERAL 17\n#define SCE_JULIA_TYPEANNOT 18\n#define SCE_JULIA_LEXERROR 19\n#define SCE_JULIA_KEYWORD4 20\n#define SCE_JULIA_TYPEOPERATOR 21\n#define SCE_MSSQL_DEFAULT 0\n#define SCE_MSSQL_COMMENT 1\n#define SCE_MSSQL_LINE_COMMENT 2\n#define SCE_MSSQL_NUMBER 3\n#define SCE_MSSQL_STRING 4\n#define SCE_MSSQL_OPERATOR 5\n#define SCE_MSSQL_IDENTIFIER 6\n#define SCE_MSSQL_VARIABLE 7\n#define SCE_MSSQL_COLUMN_NAME 8\n#define SCE_MSSQL_STATEMENT 9\n#define SCE_MSSQL_DATATYPE 10\n#define SCE_MSSQL_SYSTABLE 11\n#define SCE_MSSQL_GLOBAL_VARIABLE 12\n#define SCE_MSSQL_FUNCTION 13\n#define SCE_MSSQL_STORED_PROCEDURE 14\n#define SCE_MSSQL_DEFAULT_PREF_DATATYPE 15\n#define SCE_MSSQL_COLUMN_NAME_2 16\n#define SCE_V_DEFAULT 0\n#define SCE_V_COMMENT 1\n#define SCE_V_COMMENTLINE 2\n#define SCE_V_COMMENTLINEBANG 3\n#define SCE_V_NUMBER 4\n#define SCE_V_WORD 5\n#define SCE_V_STRING 6\n#define SCE_V_WORD2 7\n#define SCE_V_WORD3 8\n#define SCE_V_PREPROCESSOR 9\n#define SCE_V_OPERATOR 10\n#define SCE_V_IDENTIFIER 11\n#define SCE_V_STRINGEOL 12\n#define SCE_V_USER 19\n#define SCE_V_COMMENT_WORD 20\n#define SCE_V_INPUT 21\n#define SCE_V_OUTPUT 22\n#define SCE_V_INOUT 23\n#define SCE_V_PORT_CONNECT 24\n#define SCE_KIX_DEFAULT 0\n#define SCE_KIX_COMMENT 1\n#define SCE_KIX_STRING1 2\n#define SCE_KIX_STRING2 3\n#define SCE_KIX_NUMBER 4\n#define SCE_KIX_VAR 5\n#define SCE_KIX_MACRO 6\n#define SCE_KIX_KEYWORD 7\n#define SCE_KIX_FUNCTIONS 8\n#define SCE_KIX_OPERATOR 9\n#define SCE_KIX_COMMENTSTREAM 10\n#define SCE_KIX_IDENTIFIER 31\n#define SCE_GC_DEFAULT 0\n#define SCE_GC_COMMENTLINE 1\n#define SCE_GC_COMMENTBLOCK 2\n#define SCE_GC_GLOBAL 3\n#define SCE_GC_EVENT 4\n#define SCE_GC_ATTRIBUTE 5\n#define SCE_GC_CONTROL 6\n#define SCE_GC_COMMAND 7\n#define SCE_GC_STRING 8\n#define SCE_GC_OPERATOR 9\n#define SCE_SN_DEFAULT 0\n#define SCE_SN_CODE 1\n#define SCE_SN_COMMENTLINE 2\n#define SCE_SN_COMMENTLINEBANG 3\n#define SCE_SN_NUMBER 4\n#define SCE_SN_WORD 5\n#define SCE_SN_STRING 6\n#define SCE_SN_WORD2 7\n#define SCE_SN_WORD3 8\n#define SCE_SN_PREPROCESSOR 9\n#define SCE_SN_OPERATOR 10\n#define SCE_SN_IDENTIFIER 11\n#define SCE_SN_STRINGEOL 12\n#define SCE_SN_REGEXTAG 13\n#define SCE_SN_SIGNAL 14\n#define SCE_SN_USER 19\n#define SCE_AU3_DEFAULT 0\n#define SCE_AU3_COMMENT 1\n#define SCE_AU3_COMMENTBLOCK 2\n#define SCE_AU3_NUMBER 3\n#define SCE_AU3_FUNCTION 4\n#define SCE_AU3_KEYWORD 5\n#define SCE_AU3_MACRO 6\n#define SCE_AU3_STRING 7\n#define SCE_AU3_OPERATOR 8\n#define SCE_AU3_VARIABLE 9\n#define SCE_AU3_SENT 10\n#define SCE_AU3_PREPROCESSOR 11\n#define SCE_AU3_SPECIAL 12\n#define SCE_AU3_EXPAND 13\n#define SCE_AU3_COMOBJ 14\n#define SCE_AU3_UDF 15\n#define SCE_APDL_DEFAULT 0\n#define SCE_APDL_COMMENT 1\n#define SCE_APDL_COMMENTBLOCK 2\n#define SCE_APDL_NUMBER 3\n#define SCE_APDL_STRING 4\n#define SCE_APDL_OPERATOR 5\n#define SCE_APDL_WORD 6\n#define SCE_APDL_PROCESSOR 7\n#define SCE_APDL_COMMAND 8\n#define SCE_APDL_SLASHCOMMAND 9\n#define SCE_APDL_STARCOMMAND 10\n#define SCE_APDL_ARGUMENT 11\n#define SCE_APDL_FUNCTION 12\n#define SCE_SH_DEFAULT 0\n#define SCE_SH_ERROR 1\n#define SCE_SH_COMMENTLINE 2\n#define SCE_SH_NUMBER 3\n#define SCE_SH_WORD 4\n#define SCE_SH_STRING 5\n#define SCE_SH_CHARACTER 6\n#define SCE_SH_OPERATOR 7\n#define SCE_SH_IDENTIFIER 8\n#define SCE_SH_SCALAR 9\n#define SCE_SH_PARAM 10\n#define SCE_SH_BACKTICKS 11\n#define SCE_SH_HERE_DELIM 12\n#define SCE_SH_HERE_Q 13\n#define SCE_ASN1_DEFAULT 0\n#define SCE_ASN1_COMMENT 1\n#define SCE_ASN1_IDENTIFIER 2\n#define SCE_ASN1_STRING 3\n#define SCE_ASN1_OID 4\n#define SCE_ASN1_SCALAR 5\n#define SCE_ASN1_KEYWORD 6\n#define SCE_ASN1_ATTRIBUTE 7\n#define SCE_ASN1_DESCRIPTOR 8\n#define SCE_ASN1_TYPE 9\n#define SCE_ASN1_OPERATOR 10\n#define SCE_VHDL_DEFAULT 0\n#define SCE_VHDL_COMMENT 1\n#define SCE_VHDL_COMMENTLINEBANG 2\n#define SCE_VHDL_NUMBER 3\n#define SCE_VHDL_STRING 4\n#define SCE_VHDL_OPERATOR 5\n#define SCE_VHDL_IDENTIFIER 6\n#define SCE_VHDL_STRINGEOL 7\n#define SCE_VHDL_KEYWORD 8\n#define SCE_VHDL_STDOPERATOR 9\n#define SCE_VHDL_ATTRIBUTE 10\n#define SCE_VHDL_STDFUNCTION 11\n#define SCE_VHDL_STDPACKAGE 12\n#define SCE_VHDL_STDTYPE 13\n#define SCE_VHDL_USERWORD 14\n#define SCE_VHDL_BLOCK_COMMENT 15\n#define SCE_CAML_DEFAULT 0\n#define SCE_CAML_IDENTIFIER 1\n#define SCE_CAML_TAGNAME 2\n#define SCE_CAML_KEYWORD 3\n#define SCE_CAML_KEYWORD2 4\n#define SCE_CAML_KEYWORD3 5\n#define SCE_CAML_LINENUM 6\n#define SCE_CAML_OPERATOR 7\n#define SCE_CAML_NUMBER 8\n#define SCE_CAML_CHAR 9\n#define SCE_CAML_WHITE 10\n#define SCE_CAML_STRING 11\n#define SCE_CAML_COMMENT 12\n#define SCE_CAML_COMMENT1 13\n#define SCE_CAML_COMMENT2 14\n#define SCE_CAML_COMMENT3 15\n#define SCE_HA_DEFAULT 0\n#define SCE_HA_IDENTIFIER 1\n#define SCE_HA_KEYWORD 2\n#define SCE_HA_NUMBER 3\n#define SCE_HA_STRING 4\n#define SCE_HA_CHARACTER 5\n#define SCE_HA_CLASS 6\n#define SCE_HA_MODULE 7\n#define SCE_HA_CAPITAL 8\n#define SCE_HA_DATA 9\n#define SCE_HA_IMPORT 10\n#define SCE_HA_OPERATOR 11\n#define SCE_HA_INSTANCE 12\n#define SCE_HA_COMMENTLINE 13\n#define SCE_HA_COMMENTBLOCK 14\n#define SCE_HA_COMMENTBLOCK2 15\n#define SCE_HA_COMMENTBLOCK3 16\n#define SCE_HA_PRAGMA 17\n#define SCE_HA_PREPROCESSOR 18\n#define SCE_HA_STRINGEOL 19\n#define SCE_HA_RESERVED_OPERATOR 20\n#define SCE_HA_LITERATE_COMMENT 21\n#define SCE_HA_LITERATE_CODEDELIM 22\n#define SCE_T3_DEFAULT 0\n#define SCE_T3_X_DEFAULT 1\n#define SCE_T3_PREPROCESSOR 2\n#define SCE_T3_BLOCK_COMMENT 3\n#define SCE_T3_LINE_COMMENT 4\n#define SCE_T3_OPERATOR 5\n#define SCE_T3_KEYWORD 6\n#define SCE_T3_NUMBER 7\n#define SCE_T3_IDENTIFIER 8\n#define SCE_T3_S_STRING 9\n#define SCE_T3_D_STRING 10\n#define SCE_T3_X_STRING 11\n#define SCE_T3_LIB_DIRECTIVE 12\n#define SCE_T3_MSG_PARAM 13\n#define SCE_T3_HTML_TAG 14\n#define SCE_T3_HTML_DEFAULT 15\n#define SCE_T3_HTML_STRING 16\n#define SCE_T3_USER1 17\n#define SCE_T3_USER2 18\n#define SCE_T3_USER3 19\n#define SCE_T3_BRACE 20\n#define SCE_REBOL_DEFAULT 0\n#define SCE_REBOL_COMMENTLINE 1\n#define SCE_REBOL_COMMENTBLOCK 2\n#define SCE_REBOL_PREFACE 3\n#define SCE_REBOL_OPERATOR 4\n#define SCE_REBOL_CHARACTER 5\n#define SCE_REBOL_QUOTEDSTRING 6\n#define SCE_REBOL_BRACEDSTRING 7\n#define SCE_REBOL_NUMBER 8\n#define SCE_REBOL_PAIR 9\n#define SCE_REBOL_TUPLE 10\n#define SCE_REBOL_BINARY 11\n#define SCE_REBOL_MONEY 12\n#define SCE_REBOL_ISSUE 13\n#define SCE_REBOL_TAG 14\n#define SCE_REBOL_FILE 15\n#define SCE_REBOL_EMAIL 16\n#define SCE_REBOL_URL 17\n#define SCE_REBOL_DATE 18\n#define SCE_REBOL_TIME 19\n#define SCE_REBOL_IDENTIFIER 20\n#define SCE_REBOL_WORD 21\n#define SCE_REBOL_WORD2 22\n#define SCE_REBOL_WORD3 23\n#define SCE_REBOL_WORD4 24\n#define SCE_REBOL_WORD5 25\n#define SCE_REBOL_WORD6 26\n#define SCE_REBOL_WORD7 27\n#define SCE_REBOL_WORD8 28\n#define SCE_SQL_DEFAULT 0\n#define SCE_SQL_COMMENT 1\n#define SCE_SQL_COMMENTLINE 2\n#define SCE_SQL_COMMENTDOC 3\n#define SCE_SQL_NUMBER 4\n#define SCE_SQL_WORD 5\n#define SCE_SQL_STRING 6\n#define SCE_SQL_CHARACTER 7\n#define SCE_SQL_SQLPLUS 8\n#define SCE_SQL_SQLPLUS_PROMPT 9\n#define SCE_SQL_OPERATOR 10\n#define SCE_SQL_IDENTIFIER 11\n#define SCE_SQL_SQLPLUS_COMMENT 13\n#define SCE_SQL_COMMENTLINEDOC 15\n#define SCE_SQL_WORD2 16\n#define SCE_SQL_COMMENTDOCKEYWORD 17\n#define SCE_SQL_COMMENTDOCKEYWORDERROR 18\n#define SCE_SQL_USER1 19\n#define SCE_SQL_USER2 20\n#define SCE_SQL_USER3 21\n#define SCE_SQL_USER4 22\n#define SCE_SQL_QUOTEDIDENTIFIER 23\n#define SCE_SQL_QOPERATOR 24\n#define SCE_ST_DEFAULT 0\n#define SCE_ST_STRING 1\n#define SCE_ST_NUMBER 2\n#define SCE_ST_COMMENT 3\n#define SCE_ST_SYMBOL 4\n#define SCE_ST_BINARY 5\n#define SCE_ST_BOOL 6\n#define SCE_ST_SELF 7\n#define SCE_ST_SUPER 8\n#define SCE_ST_NIL 9\n#define SCE_ST_GLOBAL 10\n#define SCE_ST_RETURN 11\n#define SCE_ST_SPECIAL 12\n#define SCE_ST_KWSEND 13\n#define SCE_ST_ASSIGN 14\n#define SCE_ST_CHARACTER 15\n#define SCE_ST_SPEC_SEL 16\n#define SCE_FS_DEFAULT 0\n#define SCE_FS_COMMENT 1\n#define SCE_FS_COMMENTLINE 2\n#define SCE_FS_COMMENTDOC 3\n#define SCE_FS_COMMENTLINEDOC 4\n#define SCE_FS_COMMENTDOCKEYWORD 5\n#define SCE_FS_COMMENTDOCKEYWORDERROR 6\n#define SCE_FS_KEYWORD 7\n#define SCE_FS_KEYWORD2 8\n#define SCE_FS_KEYWORD3 9\n#define SCE_FS_KEYWORD4 10\n#define SCE_FS_NUMBER 11\n#define SCE_FS_STRING 12\n#define SCE_FS_PREPROCESSOR 13\n#define SCE_FS_OPERATOR 14\n#define SCE_FS_IDENTIFIER 15\n#define SCE_FS_DATE 16\n#define SCE_FS_STRINGEOL 17\n#define SCE_FS_CONSTANT 18\n#define SCE_FS_WORDOPERATOR 19\n#define SCE_FS_DISABLEDCODE 20\n#define SCE_FS_DEFAULT_C 21\n#define SCE_FS_COMMENTDOC_C 22\n#define SCE_FS_COMMENTLINEDOC_C 23\n#define SCE_FS_KEYWORD_C 24\n#define SCE_FS_KEYWORD2_C 25\n#define SCE_FS_NUMBER_C 26\n#define SCE_FS_STRING_C 27\n#define SCE_FS_PREPROCESSOR_C 28\n#define SCE_FS_OPERATOR_C 29\n#define SCE_FS_IDENTIFIER_C 30\n#define SCE_FS_STRINGEOL_C 31\n#define SCE_CSOUND_DEFAULT 0\n#define SCE_CSOUND_COMMENT 1\n#define SCE_CSOUND_NUMBER 2\n#define SCE_CSOUND_OPERATOR 3\n#define SCE_CSOUND_INSTR 4\n#define SCE_CSOUND_IDENTIFIER 5\n#define SCE_CSOUND_OPCODE 6\n#define SCE_CSOUND_HEADERSTMT 7\n#define SCE_CSOUND_USERKEYWORD 8\n#define SCE_CSOUND_COMMENTBLOCK 9\n#define SCE_CSOUND_PARAM 10\n#define SCE_CSOUND_ARATE_VAR 11\n#define SCE_CSOUND_KRATE_VAR 12\n#define SCE_CSOUND_IRATE_VAR 13\n#define SCE_CSOUND_GLOBAL_VAR 14\n#define SCE_CSOUND_STRINGEOL 15\n#define SCE_INNO_DEFAULT 0\n#define SCE_INNO_COMMENT 1\n#define SCE_INNO_KEYWORD 2\n#define SCE_INNO_PARAMETER 3\n#define SCE_INNO_SECTION 4\n#define SCE_INNO_PREPROC 5\n#define SCE_INNO_INLINE_EXPANSION 6\n#define SCE_INNO_COMMENT_PASCAL 7\n#define SCE_INNO_KEYWORD_PASCAL 8\n#define SCE_INNO_KEYWORD_USER 9\n#define SCE_INNO_STRING_DOUBLE 10\n#define SCE_INNO_STRING_SINGLE 11\n#define SCE_INNO_IDENTIFIER 12\n#define SCE_OPAL_SPACE 0\n#define SCE_OPAL_COMMENT_BLOCK 1\n#define SCE_OPAL_COMMENT_LINE 2\n#define SCE_OPAL_INTEGER 3\n#define SCE_OPAL_KEYWORD 4\n#define SCE_OPAL_SORT 5\n#define SCE_OPAL_STRING 6\n#define SCE_OPAL_PAR 7\n#define SCE_OPAL_BOOL_CONST 8\n#define SCE_OPAL_DEFAULT 32\n#define SCE_SPICE_DEFAULT 0\n#define SCE_SPICE_IDENTIFIER 1\n#define SCE_SPICE_KEYWORD 2\n#define SCE_SPICE_KEYWORD2 3\n#define SCE_SPICE_KEYWORD3 4\n#define SCE_SPICE_NUMBER 5\n#define SCE_SPICE_DELIMITER 6\n#define SCE_SPICE_VALUE 7\n#define SCE_SPICE_COMMENTLINE 8\n#define SCE_CMAKE_DEFAULT 0\n#define SCE_CMAKE_COMMENT 1\n#define SCE_CMAKE_STRINGDQ 2\n#define SCE_CMAKE_STRINGLQ 3\n#define SCE_CMAKE_STRINGRQ 4\n#define SCE_CMAKE_COMMANDS 5\n#define SCE_CMAKE_PARAMETERS 6\n#define SCE_CMAKE_VARIABLE 7\n#define SCE_CMAKE_USERDEFINED 8\n#define SCE_CMAKE_WHILEDEF 9\n#define SCE_CMAKE_FOREACHDEF 10\n#define SCE_CMAKE_IFDEFINEDEF 11\n#define SCE_CMAKE_MACRODEF 12\n#define SCE_CMAKE_STRINGVAR 13\n#define SCE_CMAKE_NUMBER 14\n#define SCE_GAP_DEFAULT 0\n#define SCE_GAP_IDENTIFIER 1\n#define SCE_GAP_KEYWORD 2\n#define SCE_GAP_KEYWORD2 3\n#define SCE_GAP_KEYWORD3 4\n#define SCE_GAP_KEYWORD4 5\n#define SCE_GAP_STRING 6\n#define SCE_GAP_CHAR 7\n#define SCE_GAP_OPERATOR 8\n#define SCE_GAP_COMMENT 9\n#define SCE_GAP_NUMBER 10\n#define SCE_GAP_STRINGEOL 11\n#define SCE_PLM_DEFAULT 0\n#define SCE_PLM_COMMENT 1\n#define SCE_PLM_STRING 2\n#define SCE_PLM_NUMBER 3\n#define SCE_PLM_IDENTIFIER 4\n#define SCE_PLM_OPERATOR 5\n#define SCE_PLM_CONTROL 6\n#define SCE_PLM_KEYWORD 7\n#define SCE_ABL_DEFAULT 0\n#define SCE_ABL_NUMBER 1\n#define SCE_ABL_WORD 2\n#define SCE_ABL_STRING 3\n#define SCE_ABL_CHARACTER 4\n#define SCE_ABL_PREPROCESSOR 5\n#define SCE_ABL_OPERATOR 6\n#define SCE_ABL_IDENTIFIER 7\n#define SCE_ABL_BLOCK 8\n#define SCE_ABL_END 9\n#define SCE_ABL_COMMENT 10\n#define SCE_ABL_TASKMARKER 11\n#define SCE_ABL_LINECOMMENT 12\n#define SCE_ABL_ANNOTATION 13\n#define SCE_ABL_TYPEDANNOTATION 14\n#define SCE_ABAQUS_DEFAULT 0\n#define SCE_ABAQUS_COMMENT 1\n#define SCE_ABAQUS_COMMENTBLOCK 2\n#define SCE_ABAQUS_NUMBER 3\n#define SCE_ABAQUS_STRING 4\n#define SCE_ABAQUS_OPERATOR 5\n#define SCE_ABAQUS_WORD 6\n#define SCE_ABAQUS_PROCESSOR 7\n#define SCE_ABAQUS_COMMAND 8\n#define SCE_ABAQUS_SLASHCOMMAND 9\n#define SCE_ABAQUS_STARCOMMAND 10\n#define SCE_ABAQUS_ARGUMENT 11\n#define SCE_ABAQUS_FUNCTION 12\n#define SCE_ASY_DEFAULT 0\n#define SCE_ASY_COMMENT 1\n#define SCE_ASY_COMMENTLINE 2\n#define SCE_ASY_NUMBER 3\n#define SCE_ASY_WORD 4\n#define SCE_ASY_STRING 5\n#define SCE_ASY_CHARACTER 6\n#define SCE_ASY_OPERATOR 7\n#define SCE_ASY_IDENTIFIER 8\n#define SCE_ASY_STRINGEOL 9\n#define SCE_ASY_COMMENTLINEDOC 10\n#define SCE_ASY_WORD2 11\n#define SCE_R_DEFAULT 0\n#define SCE_R_COMMENT 1\n#define SCE_R_KWORD 2\n#define SCE_R_BASEKWORD 3\n#define SCE_R_OTHERKWORD 4\n#define SCE_R_NUMBER 5\n#define SCE_R_STRING 6\n#define SCE_R_STRING2 7\n#define SCE_R_OPERATOR 8\n#define SCE_R_IDENTIFIER 9\n#define SCE_R_INFIX 10\n#define SCE_R_INFIXEOL 11\n#define SCE_R_BACKTICKS 12\n#define SCE_R_RAWSTRING 13\n#define SCE_R_RAWSTRING2 14\n#define SCE_R_ESCAPESEQUENCE 15\n#define SCE_MAGIK_DEFAULT 0\n#define SCE_MAGIK_COMMENT 1\n#define SCE_MAGIK_HYPER_COMMENT 16\n#define SCE_MAGIK_STRING 2\n#define SCE_MAGIK_CHARACTER 3\n#define SCE_MAGIK_NUMBER 4\n#define SCE_MAGIK_IDENTIFIER 5\n#define SCE_MAGIK_OPERATOR 6\n#define SCE_MAGIK_FLOW 7\n#define SCE_MAGIK_CONTAINER 8\n#define SCE_MAGIK_BRACKET_BLOCK 9\n#define SCE_MAGIK_BRACE_BLOCK 10\n#define SCE_MAGIK_SQBRACKET_BLOCK 11\n#define SCE_MAGIK_UNKNOWN_KEYWORD 12\n#define SCE_MAGIK_KEYWORD 13\n#define SCE_MAGIK_PRAGMA 14\n#define SCE_MAGIK_SYMBOL 15\n#define SCE_POWERSHELL_DEFAULT 0\n#define SCE_POWERSHELL_COMMENT 1\n#define SCE_POWERSHELL_STRING 2\n#define SCE_POWERSHELL_CHARACTER 3\n#define SCE_POWERSHELL_NUMBER 4\n#define SCE_POWERSHELL_VARIABLE 5\n#define SCE_POWERSHELL_OPERATOR 6\n#define SCE_POWERSHELL_IDENTIFIER 7\n#define SCE_POWERSHELL_KEYWORD 8\n#define SCE_POWERSHELL_CMDLET 9\n#define SCE_POWERSHELL_ALIAS 10\n#define SCE_POWERSHELL_FUNCTION 11\n#define SCE_POWERSHELL_USER1 12\n#define SCE_POWERSHELL_COMMENTSTREAM 13\n#define SCE_POWERSHELL_HERE_STRING 14\n#define SCE_POWERSHELL_HERE_CHARACTER 15\n#define SCE_POWERSHELL_COMMENTDOCKEYWORD 16\n#define SCE_MYSQL_DEFAULT 0\n#define SCE_MYSQL_COMMENT 1\n#define SCE_MYSQL_COMMENTLINE 2\n#define SCE_MYSQL_VARIABLE 3\n#define SCE_MYSQL_SYSTEMVARIABLE 4\n#define SCE_MYSQL_KNOWNSYSTEMVARIABLE 5\n#define SCE_MYSQL_NUMBER 6\n#define SCE_MYSQL_MAJORKEYWORD 7\n#define SCE_MYSQL_KEYWORD 8\n#define SCE_MYSQL_DATABASEOBJECT 9\n#define SCE_MYSQL_PROCEDUREKEYWORD 10\n#define SCE_MYSQL_STRING 11\n#define SCE_MYSQL_SQSTRING 12\n#define SCE_MYSQL_DQSTRING 13\n#define SCE_MYSQL_OPERATOR 14\n#define SCE_MYSQL_FUNCTION 15\n#define SCE_MYSQL_IDENTIFIER 16\n#define SCE_MYSQL_QUOTEDIDENTIFIER 17\n#define SCE_MYSQL_USER1 18\n#define SCE_MYSQL_USER2 19\n#define SCE_MYSQL_USER3 20\n#define SCE_MYSQL_HIDDENCOMMAND 21\n#define SCE_MYSQL_PLACEHOLDER 22\n#define SCE_PO_DEFAULT 0\n#define SCE_PO_COMMENT 1\n#define SCE_PO_MSGID 2\n#define SCE_PO_MSGID_TEXT 3\n#define SCE_PO_MSGSTR 4\n#define SCE_PO_MSGSTR_TEXT 5\n#define SCE_PO_MSGCTXT 6\n#define SCE_PO_MSGCTXT_TEXT 7\n#define SCE_PO_FUZZY 8\n#define SCE_PO_PROGRAMMER_COMMENT 9\n#define SCE_PO_REFERENCE 10\n#define SCE_PO_FLAGS 11\n#define SCE_PO_MSGID_TEXT_EOL 12\n#define SCE_PO_MSGSTR_TEXT_EOL 13\n#define SCE_PO_MSGCTXT_TEXT_EOL 14\n#define SCE_PO_ERROR 15\n#define SCE_PAS_DEFAULT 0\n#define SCE_PAS_IDENTIFIER 1\n#define SCE_PAS_COMMENT 2\n#define SCE_PAS_COMMENT2 3\n#define SCE_PAS_COMMENTLINE 4\n#define SCE_PAS_PREPROCESSOR 5\n#define SCE_PAS_PREPROCESSOR2 6\n#define SCE_PAS_NUMBER 7\n#define SCE_PAS_HEXNUMBER 8\n#define SCE_PAS_WORD 9\n#define SCE_PAS_STRING 10\n#define SCE_PAS_STRINGEOL 11\n#define SCE_PAS_CHARACTER 12\n#define SCE_PAS_OPERATOR 13\n#define SCE_PAS_ASM 14\n#define SCE_PAS_MULTILINESTRING 15\n#define SCE_SORCUS_DEFAULT 0\n#define SCE_SORCUS_COMMAND 1\n#define SCE_SORCUS_PARAMETER 2\n#define SCE_SORCUS_COMMENTLINE 3\n#define SCE_SORCUS_STRING 4\n#define SCE_SORCUS_STRINGEOL 5\n#define SCE_SORCUS_IDENTIFIER 6\n#define SCE_SORCUS_OPERATOR 7\n#define SCE_SORCUS_NUMBER 8\n#define SCE_SORCUS_CONSTANT 9\n#define SCE_POWERPRO_DEFAULT 0\n#define SCE_POWERPRO_COMMENTBLOCK 1\n#define SCE_POWERPRO_COMMENTLINE 2\n#define SCE_POWERPRO_NUMBER 3\n#define SCE_POWERPRO_WORD 4\n#define SCE_POWERPRO_WORD2 5\n#define SCE_POWERPRO_WORD3 6\n#define SCE_POWERPRO_WORD4 7\n#define SCE_POWERPRO_DOUBLEQUOTEDSTRING 8\n#define SCE_POWERPRO_SINGLEQUOTEDSTRING 9\n#define SCE_POWERPRO_LINECONTINUE 10\n#define SCE_POWERPRO_OPERATOR 11\n#define SCE_POWERPRO_IDENTIFIER 12\n#define SCE_POWERPRO_STRINGEOL 13\n#define SCE_POWERPRO_VERBATIM 14\n#define SCE_POWERPRO_ALTQUOTE 15\n#define SCE_POWERPRO_FUNCTION 16\n#define SCE_SML_DEFAULT 0\n#define SCE_SML_IDENTIFIER 1\n#define SCE_SML_TAGNAME 2\n#define SCE_SML_KEYWORD 3\n#define SCE_SML_KEYWORD2 4\n#define SCE_SML_KEYWORD3 5\n#define SCE_SML_LINENUM 6\n#define SCE_SML_OPERATOR 7\n#define SCE_SML_NUMBER 8\n#define SCE_SML_CHAR 9\n#define SCE_SML_STRING 11\n#define SCE_SML_COMMENT 12\n#define SCE_SML_COMMENT1 13\n#define SCE_SML_COMMENT2 14\n#define SCE_SML_COMMENT3 15\n#define SCE_MARKDOWN_DEFAULT 0\n#define SCE_MARKDOWN_LINE_BEGIN 1\n#define SCE_MARKDOWN_STRONG1 2\n#define SCE_MARKDOWN_STRONG2 3\n#define SCE_MARKDOWN_EM1 4\n#define SCE_MARKDOWN_EM2 5\n#define SCE_MARKDOWN_HEADER1 6\n#define SCE_MARKDOWN_HEADER2 7\n#define SCE_MARKDOWN_HEADER3 8\n#define SCE_MARKDOWN_HEADER4 9\n#define SCE_MARKDOWN_HEADER5 10\n#define SCE_MARKDOWN_HEADER6 11\n#define SCE_MARKDOWN_PRECHAR 12\n#define SCE_MARKDOWN_ULIST_ITEM 13\n#define SCE_MARKDOWN_OLIST_ITEM 14\n#define SCE_MARKDOWN_BLOCKQUOTE 15\n#define SCE_MARKDOWN_STRIKEOUT 16\n#define SCE_MARKDOWN_HRULE 17\n#define SCE_MARKDOWN_LINK 18\n#define SCE_MARKDOWN_CODE 19\n#define SCE_MARKDOWN_CODE2 20\n#define SCE_MARKDOWN_CODEBK 21\n#define SCE_TXT2TAGS_DEFAULT 0\n#define SCE_TXT2TAGS_LINE_BEGIN 1\n#define SCE_TXT2TAGS_STRONG1 2\n#define SCE_TXT2TAGS_STRONG2 3\n#define SCE_TXT2TAGS_EM1 4\n#define SCE_TXT2TAGS_EM2 5\n#define SCE_TXT2TAGS_HEADER1 6\n#define SCE_TXT2TAGS_HEADER2 7\n#define SCE_TXT2TAGS_HEADER3 8\n#define SCE_TXT2TAGS_HEADER4 9\n#define SCE_TXT2TAGS_HEADER5 10\n#define SCE_TXT2TAGS_HEADER6 11\n#define SCE_TXT2TAGS_PRECHAR 12\n#define SCE_TXT2TAGS_ULIST_ITEM 13\n#define SCE_TXT2TAGS_OLIST_ITEM 14\n#define SCE_TXT2TAGS_BLOCKQUOTE 15\n#define SCE_TXT2TAGS_STRIKEOUT 16\n#define SCE_TXT2TAGS_HRULE 17\n#define SCE_TXT2TAGS_LINK 18\n#define SCE_TXT2TAGS_CODE 19\n#define SCE_TXT2TAGS_CODE2 20\n#define SCE_TXT2TAGS_CODEBK 21\n#define SCE_TXT2TAGS_COMMENT 22\n#define SCE_TXT2TAGS_OPTION 23\n#define SCE_TXT2TAGS_PREPROC 24\n#define SCE_TXT2TAGS_POSTPROC 25\n#define SCE_A68K_DEFAULT 0\n#define SCE_A68K_COMMENT 1\n#define SCE_A68K_NUMBER_DEC 2\n#define SCE_A68K_NUMBER_BIN 3\n#define SCE_A68K_NUMBER_HEX 4\n#define SCE_A68K_STRING1 5\n#define SCE_A68K_OPERATOR 6\n#define SCE_A68K_CPUINSTRUCTION 7\n#define SCE_A68K_EXTINSTRUCTION 8\n#define SCE_A68K_REGISTER 9\n#define SCE_A68K_DIRECTIVE 10\n#define SCE_A68K_MACRO_ARG 11\n#define SCE_A68K_LABEL 12\n#define SCE_A68K_STRING2 13\n#define SCE_A68K_IDENTIFIER 14\n#define SCE_A68K_MACRO_DECLARATION 15\n#define SCE_A68K_COMMENT_WORD 16\n#define SCE_A68K_COMMENT_SPECIAL 17\n#define SCE_A68K_COMMENT_DOXYGEN 18\n#define SCE_MODULA_DEFAULT 0\n#define SCE_MODULA_COMMENT 1\n#define SCE_MODULA_DOXYCOMM 2\n#define SCE_MODULA_DOXYKEY 3\n#define SCE_MODULA_KEYWORD 4\n#define SCE_MODULA_RESERVED 5\n#define SCE_MODULA_NUMBER 6\n#define SCE_MODULA_BASENUM 7\n#define SCE_MODULA_FLOAT 8\n#define SCE_MODULA_STRING 9\n#define SCE_MODULA_STRSPEC 10\n#define SCE_MODULA_CHAR 11\n#define SCE_MODULA_CHARSPEC 12\n#define SCE_MODULA_PROC 13\n#define SCE_MODULA_PRAGMA 14\n#define SCE_MODULA_PRGKEY 15\n#define SCE_MODULA_OPERATOR 16\n#define SCE_MODULA_BADSTR 17\n#define SCE_COFFEESCRIPT_DEFAULT 0\n#define SCE_COFFEESCRIPT_COMMENT 1\n#define SCE_COFFEESCRIPT_COMMENTLINE 2\n#define SCE_COFFEESCRIPT_COMMENTDOC 3\n#define SCE_COFFEESCRIPT_NUMBER 4\n#define SCE_COFFEESCRIPT_WORD 5\n#define SCE_COFFEESCRIPT_STRING 6\n#define SCE_COFFEESCRIPT_CHARACTER 7\n#define SCE_COFFEESCRIPT_UUID 8\n#define SCE_COFFEESCRIPT_PREPROCESSOR 9\n#define SCE_COFFEESCRIPT_OPERATOR 10\n#define SCE_COFFEESCRIPT_IDENTIFIER 11\n#define SCE_COFFEESCRIPT_STRINGEOL 12\n#define SCE_COFFEESCRIPT_VERBATIM 13\n#define SCE_COFFEESCRIPT_REGEX 14\n#define SCE_COFFEESCRIPT_COMMENTLINEDOC 15\n#define SCE_COFFEESCRIPT_WORD2 16\n#define SCE_COFFEESCRIPT_COMMENTDOCKEYWORD 17\n#define SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR 18\n#define SCE_COFFEESCRIPT_GLOBALCLASS 19\n#define SCE_COFFEESCRIPT_STRINGRAW 20\n#define SCE_COFFEESCRIPT_TRIPLEVERBATIM 21\n#define SCE_COFFEESCRIPT_COMMENTBLOCK 22\n#define SCE_COFFEESCRIPT_VERBOSE_REGEX 23\n#define SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT 24\n#define SCE_COFFEESCRIPT_INSTANCEPROPERTY 25\n#define SCE_AVS_DEFAULT 0\n#define SCE_AVS_COMMENTBLOCK 1\n#define SCE_AVS_COMMENTBLOCKN 2\n#define SCE_AVS_COMMENTLINE 3\n#define SCE_AVS_NUMBER 4\n#define SCE_AVS_OPERATOR 5\n#define SCE_AVS_IDENTIFIER 6\n#define SCE_AVS_STRING 7\n#define SCE_AVS_TRIPLESTRING 8\n#define SCE_AVS_KEYWORD 9\n#define SCE_AVS_FILTER 10\n#define SCE_AVS_PLUGIN 11\n#define SCE_AVS_FUNCTION 12\n#define SCE_AVS_CLIPPROP 13\n#define SCE_AVS_USERDFN 14\n#define SCE_ECL_DEFAULT 0\n#define SCE_ECL_COMMENT 1\n#define SCE_ECL_COMMENTLINE 2\n#define SCE_ECL_NUMBER 3\n#define SCE_ECL_STRING 4\n#define SCE_ECL_WORD0 5\n#define SCE_ECL_OPERATOR 6\n#define SCE_ECL_CHARACTER 7\n#define SCE_ECL_UUID 8\n#define SCE_ECL_PREPROCESSOR 9\n#define SCE_ECL_UNKNOWN 10\n#define SCE_ECL_IDENTIFIER 11\n#define SCE_ECL_STRINGEOL 12\n#define SCE_ECL_VERBATIM 13\n#define SCE_ECL_REGEX 14\n#define SCE_ECL_COMMENTLINEDOC 15\n#define SCE_ECL_WORD1 16\n#define SCE_ECL_COMMENTDOCKEYWORD 17\n#define SCE_ECL_COMMENTDOCKEYWORDERROR 18\n#define SCE_ECL_WORD2 19\n#define SCE_ECL_WORD3 20\n#define SCE_ECL_WORD4 21\n#define SCE_ECL_WORD5 22\n#define SCE_ECL_COMMENTDOC 23\n#define SCE_ECL_ADDED 24\n#define SCE_ECL_DELETED 25\n#define SCE_ECL_CHANGED 26\n#define SCE_ECL_MOVED 27\n#define SCE_OSCRIPT_DEFAULT 0\n#define SCE_OSCRIPT_LINE_COMMENT 1\n#define SCE_OSCRIPT_BLOCK_COMMENT 2\n#define SCE_OSCRIPT_DOC_COMMENT 3\n#define SCE_OSCRIPT_PREPROCESSOR 4\n#define SCE_OSCRIPT_NUMBER 5\n#define SCE_OSCRIPT_SINGLEQUOTE_STRING 6\n#define SCE_OSCRIPT_DOUBLEQUOTE_STRING 7\n#define SCE_OSCRIPT_CONSTANT 8\n#define SCE_OSCRIPT_IDENTIFIER 9\n#define SCE_OSCRIPT_GLOBAL 10\n#define SCE_OSCRIPT_KEYWORD 11\n#define SCE_OSCRIPT_OPERATOR 12\n#define SCE_OSCRIPT_LABEL 13\n#define SCE_OSCRIPT_TYPE 14\n#define SCE_OSCRIPT_FUNCTION 15\n#define SCE_OSCRIPT_OBJECT 16\n#define SCE_OSCRIPT_PROPERTY 17\n#define SCE_OSCRIPT_METHOD 18\n#define SCE_VISUALPROLOG_DEFAULT 0\n#define SCE_VISUALPROLOG_KEY_MAJOR 1\n#define SCE_VISUALPROLOG_KEY_MINOR 2\n#define SCE_VISUALPROLOG_KEY_DIRECTIVE 3\n#define SCE_VISUALPROLOG_COMMENT_BLOCK 4\n#define SCE_VISUALPROLOG_COMMENT_LINE 5\n#define SCE_VISUALPROLOG_COMMENT_KEY 6\n#define SCE_VISUALPROLOG_COMMENT_KEY_ERROR 7\n#define SCE_VISUALPROLOG_IDENTIFIER 8\n#define SCE_VISUALPROLOG_VARIABLE 9\n#define SCE_VISUALPROLOG_ANONYMOUS 10\n#define SCE_VISUALPROLOG_NUMBER 11\n#define SCE_VISUALPROLOG_OPERATOR 12\n#define SCE_VISUALPROLOG_UNUSED1 13\n#define SCE_VISUALPROLOG_UNUSED2 14\n#define SCE_VISUALPROLOG_UNUSED3 15\n#define SCE_VISUALPROLOG_STRING_QUOTE 16\n#define SCE_VISUALPROLOG_STRING_ESCAPE 17\n#define SCE_VISUALPROLOG_STRING_ESCAPE_ERROR 18\n#define SCE_VISUALPROLOG_UNUSED4 19\n#define SCE_VISUALPROLOG_STRING 20\n#define SCE_VISUALPROLOG_UNUSED5 21\n#define SCE_VISUALPROLOG_STRING_EOL 22\n#define SCE_VISUALPROLOG_EMBEDDED 23\n#define SCE_VISUALPROLOG_PLACEHOLDER 24\n#define SCE_STTXT_DEFAULT 0\n#define SCE_STTXT_COMMENT 1\n#define SCE_STTXT_COMMENTLINE 2\n#define SCE_STTXT_KEYWORD 3\n#define SCE_STTXT_TYPE 4\n#define SCE_STTXT_FUNCTION 5\n#define SCE_STTXT_FB 6\n#define SCE_STTXT_NUMBER 7\n#define SCE_STTXT_HEXNUMBER 8\n#define SCE_STTXT_PRAGMA 9\n#define SCE_STTXT_OPERATOR 10\n#define SCE_STTXT_CHARACTER 11\n#define SCE_STTXT_STRING1 12\n#define SCE_STTXT_STRING2 13\n#define SCE_STTXT_STRINGEOL 14\n#define SCE_STTXT_IDENTIFIER 15\n#define SCE_STTXT_DATETIME 16\n#define SCE_STTXT_VARS 17\n#define SCE_STTXT_PRAGMAS 18\n#define SCE_KVIRC_DEFAULT 0\n#define SCE_KVIRC_COMMENT 1\n#define SCE_KVIRC_COMMENTBLOCK 2\n#define SCE_KVIRC_STRING 3\n#define SCE_KVIRC_WORD 4\n#define SCE_KVIRC_KEYWORD 5\n#define SCE_KVIRC_FUNCTION_KEYWORD 6\n#define SCE_KVIRC_FUNCTION 7\n#define SCE_KVIRC_VARIABLE 8\n#define SCE_KVIRC_NUMBER 9\n#define SCE_KVIRC_OPERATOR 10\n#define SCE_KVIRC_STRING_FUNCTION 11\n#define SCE_KVIRC_STRING_VARIABLE 12\n#define SCE_RUST_DEFAULT 0\n#define SCE_RUST_COMMENTBLOCK 1\n#define SCE_RUST_COMMENTLINE 2\n#define SCE_RUST_COMMENTBLOCKDOC 3\n#define SCE_RUST_COMMENTLINEDOC 4\n#define SCE_RUST_NUMBER 5\n#define SCE_RUST_WORD 6\n#define SCE_RUST_WORD2 7\n#define SCE_RUST_WORD3 8\n#define SCE_RUST_WORD4 9\n#define SCE_RUST_WORD5 10\n#define SCE_RUST_WORD6 11\n#define SCE_RUST_WORD7 12\n#define SCE_RUST_STRING 13\n#define SCE_RUST_STRINGR 14\n#define SCE_RUST_CHARACTER 15\n#define SCE_RUST_OPERATOR 16\n#define SCE_RUST_IDENTIFIER 17\n#define SCE_RUST_LIFETIME 18\n#define SCE_RUST_MACRO 19\n#define SCE_RUST_LEXERROR 20\n#define SCE_RUST_BYTESTRING 21\n#define SCE_RUST_BYTESTRINGR 22\n#define SCE_RUST_BYTECHARACTER 23\n#define SCE_RUST_CSTRING 24\n#define SCE_RUST_CSTRINGR 25\n#define SCE_DMAP_DEFAULT 0\n#define SCE_DMAP_COMMENT 1\n#define SCE_DMAP_NUMBER 2\n#define SCE_DMAP_STRING1 3\n#define SCE_DMAP_STRING2 4\n#define SCE_DMAP_STRINGEOL 5\n#define SCE_DMAP_OPERATOR 6\n#define SCE_DMAP_IDENTIFIER 7\n#define SCE_DMAP_WORD 8\n#define SCE_DMAP_WORD2 9\n#define SCE_DMAP_WORD3 10\n#define SCE_DMIS_DEFAULT 0\n#define SCE_DMIS_COMMENT 1\n#define SCE_DMIS_STRING 2\n#define SCE_DMIS_NUMBER 3\n#define SCE_DMIS_KEYWORD 4\n#define SCE_DMIS_MAJORWORD 5\n#define SCE_DMIS_MINORWORD 6\n#define SCE_DMIS_UNSUPPORTED_MAJOR 7\n#define SCE_DMIS_UNSUPPORTED_MINOR 8\n#define SCE_DMIS_LABEL 9\n#define SCE_REG_DEFAULT 0\n#define SCE_REG_COMMENT 1\n#define SCE_REG_VALUENAME 2\n#define SCE_REG_STRING 3\n#define SCE_REG_HEXDIGIT 4\n#define SCE_REG_VALUETYPE 5\n#define SCE_REG_ADDEDKEY 6\n#define SCE_REG_DELETEDKEY 7\n#define SCE_REG_ESCAPED 8\n#define SCE_REG_KEYPATH_GUID 9\n#define SCE_REG_STRING_GUID 10\n#define SCE_REG_PARAMETER 11\n#define SCE_REG_OPERATOR 12\n#define SCE_BIBTEX_DEFAULT 0\n#define SCE_BIBTEX_ENTRY 1\n#define SCE_BIBTEX_UNKNOWN_ENTRY 2\n#define SCE_BIBTEX_KEY 3\n#define SCE_BIBTEX_PARAMETER 4\n#define SCE_BIBTEX_VALUE 5\n#define SCE_BIBTEX_COMMENT 6\n#define SCE_HEX_DEFAULT 0\n#define SCE_HEX_RECSTART 1\n#define SCE_HEX_RECTYPE 2\n#define SCE_HEX_RECTYPE_UNKNOWN 3\n#define SCE_HEX_BYTECOUNT 4\n#define SCE_HEX_BYTECOUNT_WRONG 5\n#define SCE_HEX_NOADDRESS 6\n#define SCE_HEX_DATAADDRESS 7\n#define SCE_HEX_RECCOUNT 8\n#define SCE_HEX_STARTADDRESS 9\n#define SCE_HEX_ADDRESSFIELD_UNKNOWN 10\n#define SCE_HEX_EXTENDEDADDRESS 11\n#define SCE_HEX_DATA_ODD 12\n#define SCE_HEX_DATA_EVEN 13\n#define SCE_HEX_DATA_UNKNOWN 14\n#define SCE_HEX_DATA_EMPTY 15\n#define SCE_HEX_CHECKSUM 16\n#define SCE_HEX_CHECKSUM_WRONG 17\n#define SCE_HEX_GARBAGE 18\n#define SCE_JSON_DEFAULT 0\n#define SCE_JSON_NUMBER 1\n#define SCE_JSON_STRING 2\n#define SCE_JSON_STRINGEOL 3\n#define SCE_JSON_PROPERTYNAME 4\n#define SCE_JSON_ESCAPESEQUENCE 5\n#define SCE_JSON_LINECOMMENT 6\n#define SCE_JSON_BLOCKCOMMENT 7\n#define SCE_JSON_OPERATOR 8\n#define SCE_JSON_URI 9\n#define SCE_JSON_COMPACTIRI 10\n#define SCE_JSON_KEYWORD 11\n#define SCE_JSON_LDKEYWORD 12\n#define SCE_JSON_ERROR 13\n#define SCE_EDI_DEFAULT 0\n#define SCE_EDI_SEGMENTSTART 1\n#define SCE_EDI_SEGMENTEND 2\n#define SCE_EDI_SEP_ELEMENT 3\n#define SCE_EDI_SEP_COMPOSITE 4\n#define SCE_EDI_SEP_RELEASE 5\n#define SCE_EDI_UNA 6\n#define SCE_EDI_UNH 7\n#define SCE_EDI_BADSEGMENT 8\n#define SCE_STATA_DEFAULT 0\n#define SCE_STATA_COMMENT 1\n#define SCE_STATA_COMMENTLINE 2\n#define SCE_STATA_COMMENTBLOCK 3\n#define SCE_STATA_NUMBER 4\n#define SCE_STATA_OPERATOR 5\n#define SCE_STATA_IDENTIFIER 6\n#define SCE_STATA_STRING 7\n#define SCE_STATA_TYPE 8\n#define SCE_STATA_WORD 9\n#define SCE_STATA_GLOBAL_MACRO 10\n#define SCE_STATA_MACRO 11\n#define SCE_SAS_DEFAULT 0\n#define SCE_SAS_COMMENT 1\n#define SCE_SAS_COMMENTLINE 2\n#define SCE_SAS_COMMENTBLOCK 3\n#define SCE_SAS_NUMBER 4\n#define SCE_SAS_OPERATOR 5\n#define SCE_SAS_IDENTIFIER 6\n#define SCE_SAS_STRING 7\n#define SCE_SAS_TYPE 8\n#define SCE_SAS_WORD 9\n#define SCE_SAS_GLOBAL_MACRO 10\n#define SCE_SAS_MACRO 11\n#define SCE_SAS_MACRO_KEYWORD 12\n#define SCE_SAS_BLOCK_KEYWORD 13\n#define SCE_SAS_MACRO_FUNCTION 14\n#define SCE_SAS_STATEMENT 15\n#define SCE_NIM_DEFAULT 0\n#define SCE_NIM_COMMENT 1\n#define SCE_NIM_COMMENTDOC 2\n#define SCE_NIM_COMMENTLINE 3\n#define SCE_NIM_COMMENTLINEDOC 4\n#define SCE_NIM_NUMBER 5\n#define SCE_NIM_STRING 6\n#define SCE_NIM_CHARACTER 7\n#define SCE_NIM_WORD 8\n#define SCE_NIM_TRIPLE 9\n#define SCE_NIM_TRIPLEDOUBLE 10\n#define SCE_NIM_BACKTICKS 11\n#define SCE_NIM_FUNCNAME 12\n#define SCE_NIM_STRINGEOL 13\n#define SCE_NIM_NUMERROR 14\n#define SCE_NIM_OPERATOR 15\n#define SCE_NIM_IDENTIFIER 16\n#define SCE_CIL_DEFAULT 0\n#define SCE_CIL_COMMENT 1\n#define SCE_CIL_COMMENTLINE 2\n#define SCE_CIL_WORD 3\n#define SCE_CIL_WORD2 4\n#define SCE_CIL_WORD3 5\n#define SCE_CIL_STRING 6\n#define SCE_CIL_LABEL 7\n#define SCE_CIL_OPERATOR 8\n#define SCE_CIL_IDENTIFIER 9\n#define SCE_CIL_STRINGEOL 10\n#define SCE_X12_DEFAULT 0\n#define SCE_X12_BAD 1\n#define SCE_X12_ENVELOPE 2\n#define SCE_X12_FUNCTIONGROUP 3\n#define SCE_X12_TRANSACTIONSET 4\n#define SCE_X12_SEGMENTHEADER 5\n#define SCE_X12_SEGMENTEND 6\n#define SCE_X12_SEP_ELEMENT 7\n#define SCE_X12_SEP_SUBELEMENT 8\n#define SCE_DF_DEFAULT 0\n#define SCE_DF_IDENTIFIER 1\n#define SCE_DF_METATAG 2\n#define SCE_DF_IMAGE 3\n#define SCE_DF_COMMENTLINE 4\n#define SCE_DF_PREPROCESSOR 5\n#define SCE_DF_PREPROCESSOR2 6\n#define SCE_DF_NUMBER 7\n#define SCE_DF_HEXNUMBER 8\n#define SCE_DF_WORD 9\n#define SCE_DF_STRING 10\n#define SCE_DF_STRINGEOL 11\n#define SCE_DF_SCOPEWORD 12\n#define SCE_DF_OPERATOR 13\n#define SCE_DF_ICODE 14\n#define SCE_HOLLYWOOD_DEFAULT 0\n#define SCE_HOLLYWOOD_COMMENT 1\n#define SCE_HOLLYWOOD_COMMENTBLOCK 2\n#define SCE_HOLLYWOOD_NUMBER 3\n#define SCE_HOLLYWOOD_KEYWORD 4\n#define SCE_HOLLYWOOD_STDAPI 5\n#define SCE_HOLLYWOOD_PLUGINAPI 6\n#define SCE_HOLLYWOOD_PLUGINMETHOD 7\n#define SCE_HOLLYWOOD_STRING 8\n#define SCE_HOLLYWOOD_STRINGBLOCK 9\n#define SCE_HOLLYWOOD_PREPROCESSOR 10\n#define SCE_HOLLYWOOD_OPERATOR 11\n#define SCE_HOLLYWOOD_IDENTIFIER 12\n#define SCE_HOLLYWOOD_CONSTANT 13\n#define SCE_HOLLYWOOD_HEXNUMBER 14\n#define SCE_RAKU_DEFAULT 0\n#define SCE_RAKU_ERROR 1\n#define SCE_RAKU_COMMENTLINE 2\n#define SCE_RAKU_COMMENTEMBED 3\n#define SCE_RAKU_POD 4\n#define SCE_RAKU_CHARACTER 5\n#define SCE_RAKU_HEREDOC_Q 6\n#define SCE_RAKU_HEREDOC_QQ 7\n#define SCE_RAKU_STRING 8\n#define SCE_RAKU_STRING_Q 9\n#define SCE_RAKU_STRING_QQ 10\n#define SCE_RAKU_STRING_Q_LANG 11\n#define SCE_RAKU_STRING_VAR 12\n#define SCE_RAKU_REGEX 13\n#define SCE_RAKU_REGEX_VAR 14\n#define SCE_RAKU_ADVERB 15\n#define SCE_RAKU_NUMBER 16\n#define SCE_RAKU_PREPROCESSOR 17\n#define SCE_RAKU_OPERATOR 18\n#define SCE_RAKU_WORD 19\n#define SCE_RAKU_FUNCTION 20\n#define SCE_RAKU_IDENTIFIER 21\n#define SCE_RAKU_TYPEDEF 22\n#define SCE_RAKU_MU 23\n#define SCE_RAKU_POSITIONAL 24\n#define SCE_RAKU_ASSOCIATIVE 25\n#define SCE_RAKU_CALLABLE 26\n#define SCE_RAKU_GRAMMAR 27\n#define SCE_RAKU_CLASS 28\n#define SCE_FSHARP_DEFAULT 0\n#define SCE_FSHARP_KEYWORD 1\n#define SCE_FSHARP_KEYWORD2 2\n#define SCE_FSHARP_KEYWORD3 3\n#define SCE_FSHARP_KEYWORD4 4\n#define SCE_FSHARP_KEYWORD5 5\n#define SCE_FSHARP_IDENTIFIER 6\n#define SCE_FSHARP_QUOT_IDENTIFIER 7\n#define SCE_FSHARP_COMMENT 8\n#define SCE_FSHARP_COMMENTLINE 9\n#define SCE_FSHARP_PREPROCESSOR 10\n#define SCE_FSHARP_LINENUM 11\n#define SCE_FSHARP_OPERATOR 12\n#define SCE_FSHARP_NUMBER 13\n#define SCE_FSHARP_CHARACTER 14\n#define SCE_FSHARP_STRING 15\n#define SCE_FSHARP_VERBATIM 16\n#define SCE_FSHARP_QUOTATION 17\n#define SCE_FSHARP_ATTRIBUTE 18\n#define SCE_FSHARP_FORMAT_SPEC 19\n#define SCE_ASCIIDOC_DEFAULT 0\n#define SCE_ASCIIDOC_STRONG1 1\n#define SCE_ASCIIDOC_STRONG2 2\n#define SCE_ASCIIDOC_EM1 3\n#define SCE_ASCIIDOC_EM2 4\n#define SCE_ASCIIDOC_HEADER1 5\n#define SCE_ASCIIDOC_HEADER2 6\n#define SCE_ASCIIDOC_HEADER3 7\n#define SCE_ASCIIDOC_HEADER4 8\n#define SCE_ASCIIDOC_HEADER5 9\n#define SCE_ASCIIDOC_HEADER6 10\n#define SCE_ASCIIDOC_ULIST_ITEM 11\n#define SCE_ASCIIDOC_OLIST_ITEM 12\n#define SCE_ASCIIDOC_BLOCKQUOTE 13\n#define SCE_ASCIIDOC_LINK 14\n#define SCE_ASCIIDOC_CODEBK 15\n#define SCE_ASCIIDOC_PASSBK 16\n#define SCE_ASCIIDOC_COMMENT 17\n#define SCE_ASCIIDOC_COMMENTBK 18\n#define SCE_ASCIIDOC_LITERAL 19\n#define SCE_ASCIIDOC_LITERALBK 20\n#define SCE_ASCIIDOC_ATTRIB 21\n#define SCE_ASCIIDOC_ATTRIBVAL 22\n#define SCE_ASCIIDOC_MACRO 23\n#define SCE_GD_DEFAULT 0\n#define SCE_GD_COMMENTLINE 1\n#define SCE_GD_NUMBER 2\n#define SCE_GD_STRING 3\n#define SCE_GD_CHARACTER 4\n#define SCE_GD_WORD 5\n#define SCE_GD_TRIPLE 6\n#define SCE_GD_TRIPLEDOUBLE 7\n#define SCE_GD_CLASSNAME 8\n#define SCE_GD_FUNCNAME 9\n#define SCE_GD_OPERATOR 10\n#define SCE_GD_IDENTIFIER 11\n#define SCE_GD_COMMENTBLOCK 12\n#define SCE_GD_STRINGEOL 13\n#define SCE_GD_WORD2 14\n#define SCE_GD_ANNOTATION 15\n#define SCE_GD_NODEPATH 16\n#define SCE_TOML_DEFAULT 0\n#define SCE_TOML_COMMENT 1\n#define SCE_TOML_IDENTIFIER 2\n#define SCE_TOML_KEYWORD 3\n#define SCE_TOML_NUMBER 4\n#define SCE_TOML_TABLE 5\n#define SCE_TOML_KEY 6\n#define SCE_TOML_ERROR 7\n#define SCE_TOML_OPERATOR 8\n#define SCE_TOML_STRING_SQ 9\n#define SCE_TOML_STRING_DQ 10\n#define SCE_TOML_TRIPLE_STRING_SQ 11\n#define SCE_TOML_TRIPLE_STRING_DQ 12\n#define SCE_TOML_ESCAPECHAR 13\n#define SCE_TOML_DATETIME 14\n#define SCE_TOML_STRINGEOL 15\n#define SCE_TROFF_DEFAULT 0\n#define SCE_TROFF_REQUEST 1\n#define SCE_TROFF_COMMAND 2\n#define SCE_TROFF_NUMBER 3\n#define SCE_TROFF_OPERATOR 4\n#define SCE_TROFF_STRING 5\n#define SCE_TROFF_COMMENT 6\n#define SCE_TROFF_IGNORE 7\n#define SCE_TROFF_ESCAPE_STRING 8\n#define SCE_TROFF_ESCAPE_MACRO 9\n#define SCE_TROFF_ESCAPE_FONT 10\n#define SCE_TROFF_ESCAPE_NUMBER 11\n#define SCE_TROFF_ESCAPE_COLOUR 12\n#define SCE_TROFF_ESCAPE_GLYPH 13\n#define SCE_TROFF_ESCAPE_ENV 14\n#define SCE_TROFF_ESCAPE_SUPPRESSION 15\n#define SCE_TROFF_ESCAPE_SIZE 16\n#define SCE_TROFF_ESCAPE_TRANSPARENT 17\n#define SCE_TROFF_ESCAPE_ISVALID 18\n#define SCE_TROFF_ESCAPE_DRAW 19\n#define SCE_TROFF_ESCAPE_MOVE 20\n#define SCE_TROFF_ESCAPE_HEIGHT 21\n#define SCE_TROFF_ESCAPE_OVERSTRIKE 22\n#define SCE_TROFF_ESCAPE_SLANT 23\n#define SCE_TROFF_ESCAPE_WIDTH 24\n#define SCE_TROFF_ESCAPE_VSPACING 25\n#define SCE_TROFF_ESCAPE_DEVICE 26\n#define SCE_TROFF_ESCAPE_NOMOVE 27\n#define SCE_DART_DEFAULT 0\n#define SCE_DART_COMMENTLINE 1\n#define SCE_DART_COMMENTLINEDOC 2\n#define SCE_DART_COMMENTBLOCK 3\n#define SCE_DART_COMMENTBLOCKDOC 4\n#define SCE_DART_STRING_SQ 5\n#define SCE_DART_STRING_DQ 6\n#define SCE_DART_TRIPLE_STRING_SQ 7\n#define SCE_DART_TRIPLE_STRING_DQ 8\n#define SCE_DART_RAWSTRING_SQ 9\n#define SCE_DART_RAWSTRING_DQ 10\n#define SCE_DART_TRIPLE_RAWSTRING_SQ 11\n#define SCE_DART_TRIPLE_RAWSTRING_DQ 12\n#define SCE_DART_ESCAPECHAR 13\n#define SCE_DART_IDENTIFIER 14\n#define SCE_DART_IDENTIFIER_STRING 15\n#define SCE_DART_OPERATOR 16\n#define SCE_DART_OPERATOR_STRING 17\n#define SCE_DART_SYMBOL_IDENTIFIER 18\n#define SCE_DART_SYMBOL_OPERATOR 19\n#define SCE_DART_NUMBER 20\n#define SCE_DART_KEY 21\n#define SCE_DART_METADATA 22\n#define SCE_DART_KW_PRIMARY 23\n#define SCE_DART_KW_SECONDARY 24\n#define SCE_DART_KW_TERTIARY 25\n#define SCE_DART_KW_TYPE 26\n#define SCE_DART_STRINGEOL 27\n#define SCE_ZIG_DEFAULT 0\n#define SCE_ZIG_COMMENTLINE 1\n#define SCE_ZIG_COMMENTLINEDOC 2\n#define SCE_ZIG_COMMENTLINETOP 3\n#define SCE_ZIG_NUMBER 4\n#define SCE_ZIG_OPERATOR 5\n#define SCE_ZIG_CHARACTER 6\n#define SCE_ZIG_STRING 7\n#define SCE_ZIG_MULTISTRING 8\n#define SCE_ZIG_ESCAPECHAR 9\n#define SCE_ZIG_IDENTIFIER 10\n#define SCE_ZIG_FUNCTION 11\n#define SCE_ZIG_BUILTIN_FUNCTION 12\n#define SCE_ZIG_KW_PRIMARY 13\n#define SCE_ZIG_KW_SECONDARY 14\n#define SCE_ZIG_KW_TERTIARY 15\n#define SCE_ZIG_KW_TYPE 16\n#define SCE_ZIG_IDENTIFIER_STRING 17\n#define SCE_ZIG_STRINGEOL 18\n#define SCE_NIX_DEFAULT 0\n#define SCE_NIX_COMMENTLINE 1\n#define SCE_NIX_COMMENTBLOCK 2\n#define SCE_NIX_STRING 3\n#define SCE_NIX_STRING_MULTILINE 4\n#define SCE_NIX_ESCAPECHAR 5\n#define SCE_NIX_IDENTIFIER 6\n#define SCE_NIX_OPERATOR 7\n#define SCE_NIX_OPERATOR_STRING 8\n#define SCE_NIX_NUMBER 9\n#define SCE_NIX_KEY 10\n#define SCE_NIX_PATH 11\n#define SCE_NIX_KEYWORD1 12\n#define SCE_NIX_KEYWORD2 13\n#define SCE_NIX_KEYWORD3 14\n#define SCE_NIX_KEYWORD4 15\n#define SCE_NIX_STRINGEOL 16\n#define SCE_SINEX_DEFAULT 0\n#define SCE_SINEX_COMMENTLINE 1\n#define SCE_SINEX_BLOCK_START 2\n#define SCE_SINEX_BLOCK_END 3\n#define SCE_SINEX_DATE 4\n#define SCE_SINEX_NUMBER 5\n#define SCE_ESCSEQ_DEFAULT 0\n#define SCE_ESCSEQ_BLACK_DEFAULT 1\n#define SCE_ESCSEQ_RED_DEFAULT 2\n#define SCE_ESCSEQ_GREEN_DEFAULT 3\n#define SCE_ESCSEQ_YELLOW_DEFAULT 4\n#define SCE_ESCSEQ_BLUE_DEFAULT 5\n#define SCE_ESCSEQ_MAGENTA_DEFAULT 6\n#define SCE_ESCSEQ_CYAN_DEFAULT 7\n#define SCE_ESCSEQ_WHITE_DEFAULT 8\n#define SCE_ESCSEQ_DEFAULT_BLACK 9\n#define SCE_ESCSEQ_BLACK_BLACK 10\n#define SCE_ESCSEQ_RED_BLACK 11\n#define SCE_ESCSEQ_GREEN_BLACK 12\n#define SCE_ESCSEQ_YELLOW_BLACK 13\n#define SCE_ESCSEQ_BLUE_BLACK 14\n#define SCE_ESCSEQ_MAGENTA_BLACK 15\n#define SCE_ESCSEQ_CYAN_BLACK 16\n#define SCE_ESCSEQ_WHITE_BLACK 17\n#define SCE_ESCSEQ_DEFAULT_RED 18\n#define SCE_ESCSEQ_BLACK_RED 19\n#define SCE_ESCSEQ_RED_RED 20\n#define SCE_ESCSEQ_GREEN_RED 21\n#define SCE_ESCSEQ_YELLOW_RED 22\n#define SCE_ESCSEQ_BLUE_RED 23\n#define SCE_ESCSEQ_MAGENTA_RED 24\n#define SCE_ESCSEQ_CYAN_RED 25\n#define SCE_ESCSEQ_WHITE_RED 26\n#define SCE_ESCSEQ_DEFAULT_GREEN 27\n#define SCE_ESCSEQ_BLACK_GREEN 28\n#define SCE_ESCSEQ_RED_GREEN 29\n#define SCE_ESCSEQ_GREEN_GREEN 30\n#define SCE_ESCSEQ_YELLOW_GREEN 40\n#define SCE_ESCSEQ_BLUE_GREEN 41\n#define SCE_ESCSEQ_MAGENTA_GREEN 42\n#define SCE_ESCSEQ_CYAN_GREEN 43\n#define SCE_ESCSEQ_WHITE_GREEN 44\n#define SCE_ESCSEQ_DEFAULT_YELLOW 45\n#define SCE_ESCSEQ_BLACK_YELLOW 46\n#define SCE_ESCSEQ_RED_YELLOW 47\n#define SCE_ESCSEQ_GREEN_YELLOW 48\n#define SCE_ESCSEQ_YELLOW_YELLOW 49\n#define SCE_ESCSEQ_BLUE_YELLOW 50\n#define SCE_ESCSEQ_MAGENTA_YELLOW 51\n#define SCE_ESCSEQ_CYAN_YELLOW 52\n#define SCE_ESCSEQ_WHITE_YELLOW 53\n#define SCE_ESCSEQ_DEFAULT_BLUE 54\n#define SCE_ESCSEQ_BLACK_BLUE 55\n#define SCE_ESCSEQ_RED_BLUE 56\n#define SCE_ESCSEQ_GREEN_BLUE 57\n#define SCE_ESCSEQ_YELLOW_BLUE 58\n#define SCE_ESCSEQ_BLUE_BLUE 59\n#define SCE_ESCSEQ_MAGENTA_BLUE 60\n#define SCE_ESCSEQ_CYAN_BLUE 61\n#define SCE_ESCSEQ_WHITE_BLUE 62\n#define SCE_ESCSEQ_DEFAULT_MAGENTA 63\n#define SCE_ESCSEQ_BLACK_MAGENTA 64\n#define SCE_ESCSEQ_RED_MAGENTA 65\n#define SCE_ESCSEQ_GREEN_MAGENTA 66\n#define SCE_ESCSEQ_YELLOW_MAGENTA 67\n#define SCE_ESCSEQ_BLUE_MAGENTA 68\n#define SCE_ESCSEQ_MAGENTA_MAGENTA 69\n#define SCE_ESCSEQ_CYAN_MAGENTA 70\n#define SCE_ESCSEQ_WHITE_MAGENTA 71\n#define SCE_ESCSEQ_DEFAULT_CYAN 72\n#define SCE_ESCSEQ_BLACK_CYAN 73\n#define SCE_ESCSEQ_RED_CYAN 74\n#define SCE_ESCSEQ_GREEN_CYAN 75\n#define SCE_ESCSEQ_YELLOW_CYAN 76\n#define SCE_ESCSEQ_BLUE_CYAN 77\n#define SCE_ESCSEQ_MAGENTA_CYAN 78\n#define SCE_ESCSEQ_CYAN_CYAN 79\n#define SCE_ESCSEQ_WHITE_CYAN 80\n#define SCE_ESCSEQ_DEFAULT_WHITE 81\n#define SCE_ESCSEQ_BLACK_WHITE 82\n#define SCE_ESCSEQ_RED_WHITE 83\n#define SCE_ESCSEQ_GREEN_WHITE 84\n#define SCE_ESCSEQ_YELLOW_WHITE 85\n#define SCE_ESCSEQ_BLUE_WHITE 86\n#define SCE_ESCSEQ_MAGENTA_WHITE 87\n#define SCE_ESCSEQ_CYAN_WHITE 88\n#define SCE_ESCSEQ_WHITE_WHITE 89\n#define SCE_ESCSEQ_BOLD_DEFAULT 90\n#define SCE_ESCSEQ_BOLD_BLACK_DEFAULT 91\n#define SCE_ESCSEQ_BOLD_RED_DEFAULT 92\n#define SCE_ESCSEQ_BOLD_GREEN_DEFAULT 93\n#define SCE_ESCSEQ_BOLD_YELLOW_DEFAULT 94\n#define SCE_ESCSEQ_BOLD_BLUE_DEFAULT 95\n#define SCE_ESCSEQ_BOLD_MAGENTA_DEFAULT 96\n#define SCE_ESCSEQ_BOLD_CYAN_DEFAULT 97\n#define SCE_ESCSEQ_BOLD_WHITE_DEFAULT 98\n#define SCE_ESCSEQ_BOLD_DEFAULT_BLACK 99\n#define SCE_ESCSEQ_BOLD_BLACK_BLACK 100\n#define SCE_ESCSEQ_BOLD_RED_BLACK 101\n#define SCE_ESCSEQ_BOLD_GREEN_BLACK 102\n#define SCE_ESCSEQ_BOLD_YELLOW_BLACK 103\n#define SCE_ESCSEQ_BOLD_BLUE_BLACK 104\n#define SCE_ESCSEQ_BOLD_MAGENTA_BLACK 105\n#define SCE_ESCSEQ_BOLD_CYAN_BLACK 106\n#define SCE_ESCSEQ_BOLD_WHITE_BLACK 107\n#define SCE_ESCSEQ_BOLD_DEFAULT_RED 108\n#define SCE_ESCSEQ_BOLD_BLACK_RED 109\n#define SCE_ESCSEQ_BOLD_RED_RED 110\n#define SCE_ESCSEQ_BOLD_GREEN_RED 111\n#define SCE_ESCSEQ_BOLD_YELLOW_RED 112\n#define SCE_ESCSEQ_BOLD_BLUE_RED 113\n#define SCE_ESCSEQ_BOLD_MAGENTA_RED 114\n#define SCE_ESCSEQ_BOLD_CYAN_RED 115\n#define SCE_ESCSEQ_BOLD_WHITE_RED 116\n#define SCE_ESCSEQ_BOLD_DEFAULT_GREEN 117\n#define SCE_ESCSEQ_BOLD_BLACK_GREEN 118\n#define SCE_ESCSEQ_BOLD_RED_GREEN 119\n#define SCE_ESCSEQ_BOLD_GREEN_GREEN 120\n#define SCE_ESCSEQ_BOLD_YELLOW_GREEN 121\n#define SCE_ESCSEQ_BOLD_BLUE_GREEN 122\n#define SCE_ESCSEQ_BOLD_MAGENTA_GREEN 123\n#define SCE_ESCSEQ_BOLD_CYAN_GREEN 124\n#define SCE_ESCSEQ_BOLD_WHITE_GREEN 125\n#define SCE_ESCSEQ_BOLD_DEFAULT_YELLOW 126\n#define SCE_ESCSEQ_BOLD_BLACK_YELLOW 127\n#define SCE_ESCSEQ_BOLD_RED_YELLOW 128\n#define SCE_ESCSEQ_BOLD_GREEN_YELLOW 129\n#define SCE_ESCSEQ_BOLD_YELLOW_YELLOW 130\n#define SCE_ESCSEQ_BOLD_BLUE_YELLOW 131\n#define SCE_ESCSEQ_BOLD_MAGENTA_YELLOW 132\n#define SCE_ESCSEQ_BOLD_CYAN_YELLOW 133\n#define SCE_ESCSEQ_BOLD_WHITE_YELLOW 134\n#define SCE_ESCSEQ_BOLD_DEFAULT_BLUE 135\n#define SCE_ESCSEQ_BOLD_BLACK_BLUE 136\n#define SCE_ESCSEQ_BOLD_RED_BLUE 137\n#define SCE_ESCSEQ_BOLD_GREEN_BLUE 138\n#define SCE_ESCSEQ_BOLD_YELLOW_BLUE 139\n#define SCE_ESCSEQ_BOLD_BLUE_BLUE 140\n#define SCE_ESCSEQ_BOLD_MAGENTA_BLUE 141\n#define SCE_ESCSEQ_BOLD_CYAN_BLUE 142\n#define SCE_ESCSEQ_BOLD_WHITE_BLUE 143\n#define SCE_ESCSEQ_BOLD_DEFAULT_MAGENTA 144\n#define SCE_ESCSEQ_BOLD_BLACK_MAGENTA 145\n#define SCE_ESCSEQ_BOLD_RED_MAGENTA 146\n#define SCE_ESCSEQ_BOLD_GREEN_MAGENTA 147\n#define SCE_ESCSEQ_BOLD_YELLOW_MAGENTA 148\n#define SCE_ESCSEQ_BOLD_BLUE_MAGENTA 149\n#define SCE_ESCSEQ_BOLD_MAGENTA_MAGENTA 150\n#define SCE_ESCSEQ_BOLD_CYAN_MAGENTA 151\n#define SCE_ESCSEQ_BOLD_WHITE_MAGENTA 152\n#define SCE_ESCSEQ_BOLD_DEFAULT_CYAN 153\n#define SCE_ESCSEQ_BOLD_BLACK_CYAN 154\n#define SCE_ESCSEQ_BOLD_RED_CYAN 155\n#define SCE_ESCSEQ_BOLD_GREEN_CYAN 156\n#define SCE_ESCSEQ_BOLD_YELLOW_CYAN 157\n#define SCE_ESCSEQ_BOLD_BLUE_CYAN 158\n#define SCE_ESCSEQ_BOLD_MAGENTA_CYAN 159\n#define SCE_ESCSEQ_BOLD_CYAN_CYAN 160\n#define SCE_ESCSEQ_BOLD_WHITE_CYAN 161\n#define SCE_ESCSEQ_BOLD_DEFAULT_WHITE 162\n#define SCE_ESCSEQ_BOLD_BLACK_WHITE 163\n#define SCE_ESCSEQ_BOLD_RED_WHITE 164\n#define SCE_ESCSEQ_BOLD_GREEN_WHITE 165\n#define SCE_ESCSEQ_BOLD_YELLOW_WHITE 166\n#define SCE_ESCSEQ_BOLD_BLUE_WHITE 167\n#define SCE_ESCSEQ_BOLD_MAGENTA_WHITE 168\n#define SCE_ESCSEQ_BOLD_CYAN_WHITE 169\n#define SCE_ESCSEQ_BOLD_WHITE_WHITE 170\n#define SCE_ESCSEQ_IDENTIFIER 171\n#define SCE_ESCSEQ_UNKNOWN 172\n/* --Autogenerated -- end of section automatically generated from LexicalStyles.iface */\n\n#endif\n"
  },
  {
    "path": "lexers/LexA68k.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexA68k.cxx\n ** Lexer for Assembler, just for the MASM syntax\n ** Written by Martial Demolins AKA Folco\n **/\n// Copyright 2010 Martial Demolins <mdemolins(a)gmail.com>\n// The License.txt file describes the conditions under which this software\n// may be distributed.\n\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\n// Return values for GetOperatorType\n#define NO_OPERATOR     0\n#define OPERATOR_1CHAR  1\n#define OPERATOR_2CHAR  2\n\n\n/**\n *  IsIdentifierStart\n *\n *  Return true if the given char is a valid identifier first char\n */\n\nstatic inline bool IsIdentifierStart (const int ch)\n{\n    return (isalpha(ch) || (ch == '_') || (ch == '\\\\'));\n}\n\n\n/**\n *  IsIdentifierChar\n *\n *  Return true if the given char is a valid identifier char\n */\n\nstatic inline bool IsIdentifierChar (const int ch)\n{\n    return (isalnum(ch) || (ch == '_') || (ch == '@') || (ch == ':') || (ch == '.'));\n}\n\n\n/**\n *  GetOperatorType\n *\n *  Return:\n *  NO_OPERATOR     if char is not an operator\n *  OPERATOR_1CHAR  if the operator is one char long\n *  OPERATOR_2CHAR  if the operator is two chars long\n */\n\nstatic inline int GetOperatorType (const int ch1, const int ch2)\n{\n    int OpType = NO_OPERATOR;\n\n    if ((ch1 == '+') || (ch1 == '-') || (ch1 == '*') || (ch1 == '/') || (ch1 == '#') ||\n        (ch1 == '(') || (ch1 == ')') || (ch1 == '~') || (ch1 == '&') || (ch1 == '|') || (ch1 == ','))\n        OpType = OPERATOR_1CHAR;\n\n    else if ((ch1 == ch2) && (ch1 == '<' || ch1 == '>'))\n        OpType = OPERATOR_2CHAR;\n\n    return OpType;\n}\n\n\n/**\n *  IsBin\n *\n *  Return true if the given char is 0 or 1\n */\n\nstatic inline bool IsBin (const int ch)\n{\n    return (ch == '0') || (ch == '1');\n}\n\n\n/**\n *  IsDoxygenChar\n *\n *  Return true if the char may be part of a Doxygen keyword\n */\n\nstatic inline bool IsDoxygenChar (const int ch)\n{\n    return isalpha(ch) || (ch == '$') || (ch == '[') || (ch == ']') || (ch == '{') || (ch == '}');\n}\n\n\n/**\n *  ColouriseA68kDoc\n *\n *  Main function, which colourises a 68k source\n */\n\nstatic void ColouriseA68kDoc (Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler)\n{\n    // Used to buffer a string, to be able to compare it using built-in functions\n    char Buffer[100];\n\n\n    // Used to know the length of an operator\n    int OpType;\n\n\n    // Get references to keywords lists\n    WordList &cpuInstruction = *keywordlists[0];\n    WordList &registers = *keywordlists[1];\n    WordList &directive = *keywordlists[2];\n    WordList &extInstruction = *keywordlists[3];\n    WordList &alert          = *keywordlists[4];\n    WordList &doxygenKeyword = *keywordlists[5];\n\n\n    // Instanciate a context for our source\n    StyleContext sc(startPos, length, initStyle, styler);\n\n\n    /************************************************************\n    *\n    *   Parse the source\n    *\n    ************************************************************/\n\n    for ( ; sc.More(); sc.Forward())\n    {\n        /************************************************************\n        *\n        *   A style always terminates at the end of a line, even for\n        *   comments (no multi-lines comments)\n        *\n        ************************************************************/\n        if (sc.atLineStart) {\n            sc.SetState(SCE_A68K_DEFAULT);\n        }\n\n\n        /************************************************************\n        *\n        *   If we are not in \"default style\", check if the style continues\n        *   In this case, we just have to loop\n        *\n        ************************************************************/\n\n        if (sc.state != SCE_A68K_DEFAULT)\n        {\n            if (   ((sc.state == SCE_A68K_NUMBER_DEC)        && isdigit(sc.ch))                      // Decimal number\n                || ((sc.state == SCE_A68K_NUMBER_BIN) && IsBin(sc.ch))                                      // Binary number\n                || ((sc.state == SCE_A68K_NUMBER_HEX) && isxdigit(sc.ch))                                   // Hexa number\n                || ((sc.state == SCE_A68K_MACRO_ARG)         && isdigit(sc.ch))                      // Macro argument\n                || ((sc.state == SCE_A68K_STRING1)    && (sc.ch != '\\''))                                   // String single-quoted\n                || ((sc.state == SCE_A68K_STRING2)    && (sc.ch != '\\\"'))                                   // String double-quoted\n                || ((sc.state == SCE_A68K_MACRO_DECLARATION) && IsIdentifierChar(sc.ch))             // Macro declaration (or global label, we don't know at this point)\n                || ((sc.state == SCE_A68K_IDENTIFIER)        && IsIdentifierChar(sc.ch))             // Identifier\n                || ((sc.state == SCE_A68K_LABEL)             && IsIdentifierChar(sc.ch))             // Label (local)\n                || ((sc.state == SCE_A68K_COMMENT_DOXYGEN)   && IsDoxygenChar(sc.ch))                // Doxygen keyword\n                || ((sc.state == SCE_A68K_COMMENT_SPECIAL)   && isalpha(sc.ch))                      // Alert\n                || ((sc.state == SCE_A68K_COMMENT)           && !isalpha(sc.ch) && (sc.ch != '\\\\'))) // Normal comment\n            {\n                continue;\n            }\n\n        /************************************************************\n        *\n        *   Check if current state terminates\n        *\n        ************************************************************/\n\n            // Strings: include terminal ' or \" in the current string by skipping it\n            if ((sc.state == SCE_A68K_STRING1) || (sc.state == SCE_A68K_STRING2)) {\n                sc.Forward();\n                }\n\n\n            // If a macro declaration was terminated with ':', it was a label\n            else if ((sc.state == SCE_A68K_MACRO_DECLARATION) && (sc.chPrev == ':')) {\n                sc.ChangeState(SCE_A68K_LABEL);\n            }\n\n\n            // If it wasn't a Doxygen keyword, change it to normal comment\n            else if (sc.state == SCE_A68K_COMMENT_DOXYGEN) {\n                sc.GetCurrent(Buffer, sizeof(Buffer));\n                if (!doxygenKeyword.InList(Buffer)) {\n                    sc.ChangeState(SCE_A68K_COMMENT);\n                }\n                sc.SetState(SCE_A68K_COMMENT);\n                continue;\n            }\n\n\n            // If it wasn't an Alert, change it to normal comment\n            else if (sc.state == SCE_A68K_COMMENT_SPECIAL) {\n                sc.GetCurrent(Buffer, sizeof(Buffer));\n                if (!alert.InList(Buffer)) {\n                    sc.ChangeState(SCE_A68K_COMMENT);\n                }\n                // Reset style to normal comment, or to Doxygen keyword if it begins with '\\'\n                if (sc.ch == '\\\\') {\n                    sc.SetState(SCE_A68K_COMMENT_DOXYGEN);\n                }\n                else {\n                sc.SetState(SCE_A68K_COMMENT);\n                }\n                continue;\n            }\n\n\n            // If we are in a comment, it's a Doxygen keyword or an Alert\n            else if (sc.state == SCE_A68K_COMMENT) {\n                if (sc.ch == '\\\\') {\n                    sc.SetState(SCE_A68K_COMMENT_DOXYGEN);\n                }\n                else {\n                    sc.SetState(SCE_A68K_COMMENT_SPECIAL);\n                }\n                continue;\n            }\n\n\n            // Check if we are at the end of an identifier\n            // In this case, colourise it if was a keyword.\n            else if ((sc.state == SCE_A68K_IDENTIFIER) && !IsIdentifierChar(sc.ch)) {\n                sc.GetCurrentLowered(Buffer, sizeof(Buffer));                           // Buffer the string of the current context\n                if (cpuInstruction.InList(Buffer)) {                                    // And check if it belongs to a keyword list\n                    sc.ChangeState(SCE_A68K_CPUINSTRUCTION);\n                }\n                else if (extInstruction.InList(Buffer)) {\n                    sc.ChangeState(SCE_A68K_EXTINSTRUCTION);\n                }\n                else if (registers.InList(Buffer)) {\n                    sc.ChangeState(SCE_A68K_REGISTER);\n                }\n                else if (directive.InList(Buffer)) {\n                    sc.ChangeState(SCE_A68K_DIRECTIVE);\n                }\n            }\n\n            // All special contexts are now handled.Come back to default style\n            sc.SetState(SCE_A68K_DEFAULT);\n        }\n\n\n        /************************************************************\n        *\n        *   Check if we must enter a new state\n        *\n        ************************************************************/\n\n        // Something which begins at the beginning of a line, and with\n        // - '\\' + an identifier start char, or\n        // - '\\\\@' + an identifier start char\n        // is a local label (second case is used for macro local labels). We set it already as a label, it can't be a macro/equ declaration\n        if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.chNext) && (sc.ch == '\\\\')) {\n            sc.SetState(SCE_A68K_LABEL);\n        }\n\n        if (sc.atLineStart && (sc.ch < 0x80) && (sc.ch == '\\\\') && (sc.chNext == '\\\\')) {\n            sc.Forward(2);\n            if ((sc.ch == '@') && IsIdentifierStart(sc.chNext)) {\n                sc.ChangeState(SCE_A68K_LABEL);\n                sc.SetState(SCE_A68K_LABEL);\n            }\n        }\n\n        // Label and macro identifiers start at the beginning of a line\n        // We set both as a macro id, but if it wasn't one (':' at the end),\n        // it will be changed as a label.\n        if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {\n            sc.SetState(SCE_A68K_MACRO_DECLARATION);\n        }\n        else if ((sc.ch < 0x80) && (sc.ch == ';')) {                            // Default: alert in a comment. If it doesn't match\n            sc.SetState(SCE_A68K_COMMENT);                                      // with an alert, it will be toggle to a normal comment\n        }\n        else if ((sc.ch < 0x80) && isdigit(sc.ch)) {                            // Decimal numbers haven't prefix\n            sc.SetState(SCE_A68K_NUMBER_DEC);\n        }\n        else if ((sc.ch < 0x80) && (sc.ch == '%')) {                            // Binary numbers are prefixed with '%'\n            sc.SetState(SCE_A68K_NUMBER_BIN);\n        }\n        else if ((sc.ch < 0x80) && (sc.ch == '$')) {                            // Hexadecimal numbers are prefixed with '$'\n            sc.SetState(SCE_A68K_NUMBER_HEX);\n        }\n        else if ((sc.ch < 0x80) && (sc.ch == '\\'')) {                           // String (single-quoted)\n            sc.SetState(SCE_A68K_STRING1);\n        }\n        else if ((sc.ch < 0x80) && (sc.ch == '\\\"')) {                           // String (double-quoted)\n            sc.SetState(SCE_A68K_STRING2);\n        }\n        else if ((sc.ch < 0x80) && (sc.ch == '\\\\') && (isdigit(sc.chNext))) {   // Replacement symbols in macro are prefixed with '\\'\n            sc.SetState(SCE_A68K_MACRO_ARG);\n        }\n        else if ((sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {                  // An identifier: constant, label, etc...\n            sc.SetState(SCE_A68K_IDENTIFIER);\n        }\n        else {\n            if (sc.ch < 0x80) {\n                OpType = GetOperatorType(sc.ch, sc.chNext);                     // Check if current char is an operator\n                if (OpType != NO_OPERATOR) {\n                    sc.SetState(SCE_A68K_OPERATOR);\n                    if (OpType == OPERATOR_2CHAR) {                             // Check if the operator is 2 bytes long\n                        sc.ForwardSetState(SCE_A68K_OPERATOR);                  // (>> or <<)\n                    }\n                }\n            }\n        }\n    }                                                                           // End of for()\n    sc.Complete();\n}\n\n\n// Names of the keyword lists\n\nstatic const char * const a68kWordListDesc[] =\n{\n    \"CPU instructions\",\n    \"Registers\",\n    \"Directives\",\n    \"Extended instructions\",\n    \"Comment special words\",\n    \"Doxygen keywords\",\n    0\n};\n\nextern const LexerModule lmA68k(SCLEX_A68K, ColouriseA68kDoc, \"a68k\", 0, a68kWordListDesc);\n"
  },
  {
    "path": "lexers/LexAPDL.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexAPDL.cxx\n ** Lexer for APDL. Based on the lexer for Assembler by The Black Horus.\n ** By Hadar Raz.\n **/\n// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80 && (isalnum(ch) || ch == '_'));\n}\n\nstatic inline bool IsAnOperator(char ch) {\n\t// '.' left out as it is used to make up numbers\n\tif (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||\n\t\tch == '(' || ch == ')' || ch == '=' || ch == '^' ||\n\t\tch == '[' || ch == ']' || ch == '<' || ch == '&' ||\n\t\tch == '>' || ch == ',' || ch == '|' || ch == '~' ||\n\t\tch == '$' || ch == ':' || ch == '%')\n\t\treturn true;\n\treturn false;\n}\n\nstatic void ColouriseAPDLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler) {\n\n\tint stringStart = ' ';\n\n\tWordList &processors = *keywordlists[0];\n\tWordList &commands = *keywordlists[1];\n\tWordList &slashcommands = *keywordlists[2];\n\tWordList &starcommands = *keywordlists[3];\n\tWordList &arguments = *keywordlists[4];\n\tWordList &functions = *keywordlists[5];\n\n\t// Do not leak onto next line\n\tinitStyle = SCE_APDL_DEFAULT;\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_APDL_NUMBER) {\n\t\t\tif (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||\n\t\t\t\t((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {\n\t\t\t\tsc.SetState(SCE_APDL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_APDL_COMMENT) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_APDL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_APDL_COMMENTBLOCK) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tif (sc.ch == '\\r') {\n\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.ForwardSetState(SCE_APDL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_APDL_STRING) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_APDL_DEFAULT);\n\t\t\t} else if ((sc.ch == '\\'' && stringStart == '\\'') || (sc.ch == '\\\"' && stringStart == '\\\"')) {\n\t\t\t\tsc.ForwardSetState(SCE_APDL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_APDL_WORD) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tif (processors.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_APDL_PROCESSOR);\n\t\t\t\t} else if (slashcommands.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_APDL_SLASHCOMMAND);\n\t\t\t\t} else if (starcommands.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_APDL_STARCOMMAND);\n\t\t\t\t} else if (commands.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_APDL_COMMAND);\n\t\t\t\t} else if (arguments.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_APDL_ARGUMENT);\n\t\t\t\t} else if (functions.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_APDL_FUNCTION);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_APDL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_APDL_OPERATOR) {\n\t\t\tif (!IsAnOperator(static_cast<char>(sc.ch))) {\n\t\t\t    sc.SetState(SCE_APDL_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_APDL_DEFAULT) {\n\t\t\tif (sc.ch == '!' && sc.chNext == '!') {\n\t\t\t\tsc.SetState(SCE_APDL_COMMENTBLOCK);\n\t\t\t} else if (sc.ch == '!') {\n\t\t\t\tsc.SetState(SCE_APDL_COMMENT);\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_APDL_NUMBER);\n\t\t\t} else if (sc.ch == '\\'' || sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_APDL_STRING);\n\t\t\t\tstringStart = sc.ch;\n\t\t\t} else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {\n\t\t\t\tsc.SetState(SCE_APDL_WORD);\n\t\t\t} else if (IsAnOperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_APDL_OPERATOR);\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\n//------------------------------------------------------------------------------\n// 06-27-07 Sergio Lucato\n// - Included code folding for Ansys APDL lexer\n// - Copyied from LexBasic.cxx and modified for APDL\n//------------------------------------------------------------------------------\n\n/* Bits:\n * 1  - whitespace\n * 2  - operator\n * 4  - identifier\n * 8  - decimal digit\n * 16 - hex digit\n * 32 - bin digit\n */\nstatic int character_classification[128] =\n{\n    0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  1,  0,  0,\n    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n    1,  2,  0,  2,  2,  2,  2,  2,  2,  2,  6,  2,  2,  2,  10, 6,\n    60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2,  2,  2,  2,  2,  2,\n    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,\n    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  4,\n    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,\n    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  0\n};\n\nstatic bool IsSpace(int c) {\n\treturn c < 128 && (character_classification[c] & 1);\n}\n\nstatic bool IsIdentifier(int c) {\n\treturn c < 128 && (character_classification[c] & 4);\n}\n\nstatic int LowerCase(int c)\n{\n\tif (c >= 'A' && c <= 'Z')\n\t\treturn 'a' + c - 'A';\n\treturn c;\n}\n\nstatic int CheckAPDLFoldPoint(char const *token, int &level) {\n\tif (!strcmp(token, \"*if\") ||\n\t\t!strcmp(token, \"*do\") ||\n\t\t!strcmp(token, \"*dowhile\") ) {\n\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\treturn 1;\n\t}\n\tif (!strcmp(token, \"*endif\") ||\n\t\t!strcmp(token, \"*enddo\") ) {\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nstatic void FoldAPDLDoc(Sci_PositionU startPos, Sci_Position length, int,\n\tWordList *[], Accessor &styler) {\n\n\tSci_Position line = styler.GetLine(startPos);\n\tint level = styler.LevelAt(line);\n\tint go = 0, done = 0;\n\tSci_Position endPos = startPos + length;\n\tchar word[256];\n\tint wordlen = 0;\n\tSci_Position i;\n    bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\t// Scan for tokens at the start of the line (they may include\n\t// whitespace, for tokens like \"End Function\"\n\tfor (i = startPos; i < endPos; i++) {\n\t\tint c = styler.SafeGetCharAt(i);\n\t\tif (!done && !go) {\n\t\t\tif (wordlen) { // are we scanning a token already?\n\t\t\t\tword[wordlen] = static_cast<char>(LowerCase(c));\n\t\t\t\tif (!IsIdentifier(c)) { // done with token\n\t\t\t\t\tword[wordlen] = '\\0';\n\t\t\t\t\tgo = CheckAPDLFoldPoint(word, level);\n\t\t\t\t\tif (!go) {\n\t\t\t\t\t\t// Treat any whitespace as single blank, for\n\t\t\t\t\t\t// things like \"End   Function\".\n\t\t\t\t\t\tif (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {\n\t\t\t\t\t\t\tword[wordlen] = ' ';\n\t\t\t\t\t\t\tif (wordlen < 255)\n\t\t\t\t\t\t\t\twordlen++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse // done with this line\n\t\t\t\t\t\t\tdone = 1;\n\t\t\t\t\t}\n\t\t\t\t} else if (wordlen < 255) {\n\t\t\t\t\twordlen++;\n\t\t\t\t}\n\t\t\t} else { // start scanning at first non-whitespace character\n\t\t\t\tif (!IsSpace(c)) {\n\t\t\t\t\tif (IsIdentifier(c)) {\n\t\t\t\t\t\tword[0] = static_cast<char>(LowerCase(c));\n\t\t\t\t\t\twordlen = 1;\n\t\t\t\t\t} else // done with this line\n\t\t\t\t\t\tdone = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (c == '\\n') { // line end\n\t\t\tif (!done && wordlen == 0 && foldCompact) // line was only space\n\t\t\t\tlevel |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (level != styler.LevelAt(line))\n\t\t\t\tstyler.SetLevel(line, level);\n\t\t\tlevel += go;\n\t\t\tline++;\n\t\t\t// reset state\n\t\t\twordlen = 0;\n\t\t\tlevel &= ~SC_FOLDLEVELHEADERFLAG;\n\t\t\tlevel &= ~SC_FOLDLEVELWHITEFLAG;\n\t\t\tgo = 0;\n\t\t\tdone = 0;\n\t\t}\n\t}\n}\n\nstatic const char * const apdlWordListDesc[] = {\n    \"processors\",\n    \"commands\",\n    \"slashommands\",\n    \"starcommands\",\n    \"arguments\",\n    \"functions\",\n    0\n};\n\nextern const LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, \"apdl\", FoldAPDLDoc, apdlWordListDesc);\n"
  },
  {
    "path": "lexers/LexASY.cxx",
    "content": "// Scintilla source code edit control\n// @file LexASY.cxx\n//Author: instanton (email: soft_share<at>126<dot>com)\n// This lexer is for the Asymptote vector graphics language\n// https://en.wikipedia.org/wiki/Asymptote_(vector_graphics_language)\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ColouriseAsyDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\tWordList *keywordlists[], Accessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\n\tCharacterSet setWordStart(CharacterSet::setAlpha, \"_\", 0x80, true);\n\tCharacterSet setWord(CharacterSet::setAlphaNum, \"._\", 0x80, true);\n\n\tint visibleChars = 0;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.atLineStart) {\n\t\t\tif (sc.state == SCE_ASY_STRING) {\n\t\t\t\tsc.SetState(SCE_ASY_STRING);\n\t\t\t}\n\t\t\tvisibleChars = 0;\n\t\t}\n\n\t\tif (sc.ch == '\\\\') {\n\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n//\t\t\t\tcontinuationLine = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_ASY_OPERATOR:\n\t\t\t\tsc.SetState(SCE_ASY_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_ASY_NUMBER:\n\t\t\t\tif (!setWord.Contains(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_ASY_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ASY_IDENTIFIER:\n\t\t\t\tif (!setWord.Contains(sc.ch) || (sc.ch == '.')) {\n\t\t\t\t\tchar s[1000];\n\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ASY_WORD);\n\t\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ASY_WORD2);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_ASY_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ASY_COMMENT:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_ASY_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ASY_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_ASY_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ASY_STRING:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_ASY_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tsc.ForwardSetState(SCE_ASY_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ASY_CHARACTER:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_ASY_STRINGEOL);\n\t\t\t\t} else \tif (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\tsc.ForwardSetState(SCE_ASY_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_ASY_DEFAULT) {\n\t\t\tif (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {\n\t\t\t\tsc.SetState(SCE_ASY_IDENTIFIER);\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tsc.SetState(SCE_ASY_COMMENT);\n\t\t\t\tsc.Forward();\t//\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tsc.SetState(SCE_ASY_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_ASY_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_ASY_CHARACTER);\n\t\t\t} else if (sc.ch == '#' && visibleChars == 0) {\n\t\t\t\tdo {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} while ((sc.ch == ' ' || sc.ch == '\\t') && sc.More());\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.SetState(SCE_ASY_DEFAULT);\n\t\t\t\t}\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_ASY_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t}\n\tsc.Complete();\n}\n\nstatic bool IsAsyCommentStyle(int style) {\n\treturn style == SCE_ASY_COMMENT;\n}\n\n\nstatic inline bool isASYidentifier(int ch) {\n\treturn\n      ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ;\n}\n\nstatic int ParseASYWord(Sci_PositionU pos, Accessor &styler, char *word)\n{\n  int length=0;\n  char ch=styler.SafeGetCharAt(pos);\n  *word=0;\n\n  while(isASYidentifier(ch) && length<100){\n          word[length]=ch;\n          length++;\n          ch=styler.SafeGetCharAt(pos+length);\n  }\n  word[length]=0;\n  return length;\n}\n\nstatic bool IsASYDrawingLine(Sci_Position line, Accessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\n\tSci_Position startpos = pos;\n\tchar buffer[100]=\"\";\n\n\twhile (startpos<eol_pos){\n\t\tchar ch = styler[startpos];\n\t\tParseASYWord(startpos,styler,buffer);\n\t\tbool drawcommands = strncmp(buffer,\"draw\",4)==0||\n\t\t\tstrncmp(buffer,\"pair\",4)==0||strncmp(buffer,\"label\",5)==0;\n\t\tif (!drawcommands && ch!=' ') return false;\n\t\telse if (drawcommands) return true;\n\t\tstartpos++;\n\t}\n\treturn false;\n}\n\nstatic void FoldAsyDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\t\t\t\t   WordList *[], Accessor &styler) {\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tbool foldAtElse = styler.GetPropertyInt(\"fold.at.else\", 0) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelMinCurrent = levelCurrent;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (foldComment && IsAsyCommentStyle(style)) {\n\t\t\tif (!IsAsyCommentStyle(stylePrev) && (stylePrev != SCE_ASY_COMMENTLINEDOC)) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (!IsAsyCommentStyle(styleNext) && (styleNext != SCE_ASY_COMMENTLINEDOC) && !atEOL) {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (style == SCE_ASY_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t}\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\n\t\tif (atEOL && IsASYDrawingLine(lineCurrent, styler)){\n\t\t\tif (lineCurrent==0 && IsASYDrawingLine(lineCurrent + 1, styler))\n\t\t\t\tlevelNext++;\n\t\t\telse if (lineCurrent!=0 && !IsASYDrawingLine(lineCurrent - 1, styler)\n\t\t\t\t&& IsASYDrawingLine(lineCurrent + 1, styler)\n\t\t\t\t)\n\t\t\t\tlevelNext++;\n\t\t\telse if (lineCurrent!=0 && IsASYDrawingLine(lineCurrent - 1, styler) &&\n\t\t\t\t!IsASYDrawingLine(lineCurrent+1, styler))\n\t\t\t\tlevelNext--;\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tif (foldAtElse) {\n\t\t\t\tlevelUse = levelMinCurrent;\n\t\t\t}\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelMinCurrent = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\t}\n}\n\nstatic const char * const asyWordLists[] = {\n            \"Primary keywords and identifiers\",\n            \"Secondary keywords and identifiers\",\n            0,\n        };\n\nextern const LexerModule lmASY(SCLEX_ASYMPTOTE, ColouriseAsyDoc, \"asy\", FoldAsyDoc, asyWordLists);\n"
  },
  {
    "path": "lexers/LexAU3.cxx",
    "content": "// Scintilla source code edit control\n// @file LexAU3.cxx\n// Lexer for AutoIt3 https://www.autoitscript.com/site/\n// by Jos van der Zande, jvdzande@yahoo.com\n//\n// Changes:\n// March 28, 2004 - Added the standard Folding code\n// April 21, 2004 - Added Preprosessor Table + Syntax Highlighting\n//                  Fixed Number highlighting\n//                  Changed default isoperator to IsAOperator to have a better match to AutoIt3\n//                  Fixed \"#comments_start\" -> \"#comments-start\"\n//                  Fixed \"#comments_end\" -> \"#comments-end\"\n//                  Fixed Sendkeys in Strings when not terminated with }\n//                  Added support for Sendkey strings that have second parameter e.g. {UP 5} or {a down}\n// April 26, 2004 - Fixed # pre-processor statement inside of comment block would invalidly change the color.\n//                  Added logic for #include <xyz.au3> to treat the <> as string\n//                  Added underscore to IsAOperator.\n// May 17, 2004   - Changed the folding logic from indent to keyword folding.\n//                  Added Folding logic for blocks of single-commentlines or commentblock.\n//                        triggered by: fold.comment=1\n//                  Added Folding logic for preprocessor blocks triggered by fold.preprocessor=1\n//                  Added Special for #region - #endregion syntax highlight and folding.\n// May 30, 2004   - Fixed issue with continuation lines on If statements.\n// June 5, 2004   - Added comma to Operators for better readability.\n//                  Added fold.compact support set with fold.compact=1\n//                  Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1\n//                        it will now only happen when fold.comment=2.\n// Sep 5, 2004    - Added logic to handle colourizing words on the last line.\n//                        Typed Characters now show as \"default\" till they match any table.\n// Oct 10, 2004   - Added logic to show Comments in \"Special\" directives.\n// Nov  1, 2004   - Added better testing for Numbers supporting x and e notation.\n// Nov 28, 2004   - Added logic to handle continuation lines for syntax highlighting.\n// Jan 10, 2005   - Added Abbreviations Keyword used for expansion\n// Mar 24, 2005   - Updated Abbreviations Keywords to fix when followed by Operator.\n// Apr 18, 2005   - Updated #CE/#Comment-End logic to take a linecomment \";\" into account\n//                - Added folding support for With...EndWith\n//                - Added support for a DOT in variable names\n//                - Fixed Underscore in CommentBlock\n// May 23, 2005   - Fixed the SentKey lexing in case of a missing }\n// Aug 11, 2005   - Fixed possible bug with s_save length > 100.\n// Aug 23, 2005   - Added Switch/endswitch support to the folding logic.\n// Sep 27, 2005   - Fixed the SentKey lexing logic in case of multiple sentkeys.\n// Mar 12, 2006   - Fixed issue with <> coloring as String in stead of Operator in rare occasions.\n// Apr  8, 2006   - Added support for AutoIt3 Standard UDF library (SCE_AU3_UDF)\n// Mar  9, 2007   - Fixed bug with + following a String getting the wrong Color.\n// Jun 20, 2007   - Fixed Commentblock issue when LF's are used as EOL.\n// Jul 26, 2007   - Fixed #endregion undetected bug.\n//\n// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n// Scintilla source code edit control\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsTypeCharacter(const int ch)\n{\n    return ch == '$';\n}\nstatic inline bool IsAWordChar(const int ch)\n{\n    return (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\nstatic inline bool IsAWordStart(const int ch)\n{\n    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$' || ch == '.');\n}\n\nstatic inline bool IsAOperator(char ch) {\n\tif (IsASCII(ch) && isalnum(ch))\n\t\treturn false;\n\tif (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||\n\t    ch == '&' || ch == '^' || ch == '=' || ch == '<' || ch == '>' ||\n\t    ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == ',' )\n\t\treturn true;\n\treturn false;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// GetSendKey() filters the portion before and after a/multiple space(s)\n// and return the first portion to be looked-up in the table\n// also check if the second portion is valid... (up,down.on.off,toggle or a number)\n///////////////////////////////////////////////////////////////////////////////\n\nstatic int GetSendKey(const char *szLine, char *szKey)\n{\n\tint\t\tnFlag\t= 0;\n\tint\t\tnStartFound\t= 0;\n\tint\t\tnKeyPos\t= 0;\n\tint\t\tnSpecPos= 0;\n\tint\t\tnSpecNum= 1;\n\tint\t\tnPos\t= 0;\n\tchar\tcTemp;\n\tchar\tszSpecial[100];\n\n\t// split the portion of the sendkey in the part before and after the spaces\n\twhile ( ( (cTemp = szLine[nPos]) != '\\0'))\n\t{\n\t\t// skip leading Ctrl/Shift/Alt state\n\t\tif (cTemp == '{') {\n\t\t\tnStartFound = 1;\n\t\t}\n\t\t//\n\t\tif (nStartFound == 1) {\n\t\t\tif ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space\n\t\t\t{\n\t\t\t\tnFlag = 1;\n\t\t\t\t// Add } to the end of the first bit for table lookup later.\n\t\t\t\tszKey[nKeyPos++] = '}';\n\t\t\t}\n\t\t\telse if (cTemp == ' ')\n\t\t\t{\n\t\t\t\t// skip other spaces\n\t\t\t}\n\t\t\telse if (nFlag == 0)\n\t\t\t{\n\t\t\t\t// save first portion into var till space or } is hit\n\t\t\t\tszKey[nKeyPos++] = cTemp;\n\t\t\t}\n\t\t\telse if ((nFlag == 1) && (cTemp != '}'))\n\t\t\t{\n\t\t\t\t// Save second portion into var...\n\t\t\t\tszSpecial[nSpecPos++] = cTemp;\n\t\t\t\t// check if Second portion is all numbers for repeat fuction\n\t\t\t\tif (isdigit(cTemp) == false) {nSpecNum = 0;}\n\t\t\t}\n\t\t}\n\t\tnPos++;\t\t\t\t\t\t\t\t\t// skip to next char\n\n\t} // End While\n\n\n\t// Check if the second portion is either a number or one of these keywords\n\tszKey[nKeyPos] = '\\0';\n\tszSpecial[nSpecPos] = '\\0';\n\tif (strcmp(szSpecial,\"down\")== 0    || strcmp(szSpecial,\"up\")== 0  ||\n\t\tstrcmp(szSpecial,\"on\")== 0      || strcmp(szSpecial,\"off\")== 0 ||\n\t\tstrcmp(szSpecial,\"toggle\")== 0  || nSpecNum == 1 )\n\t{\n\t\tnFlag = 0;\n\t}\n\telse\n\t{\n\t\tnFlag = 1;\n\t}\n\treturn nFlag;  // 1 is bad, 0 is good\n\n} // GetSendKey()\n\n//\n// Routine to check the last \"none comment\" character on a line to see if its a continuation\n//\nstatic bool IsContinuationLine(Sci_PositionU szLine, Accessor &styler)\n{\n\tSci_Position nsPos = styler.LineStart(szLine);\n\tSci_Position nePos = styler.LineStart(szLine+1) - 2;\n\t//int stylech = styler.StyleAt(nsPos);\n\twhile (nsPos < nePos)\n\t{\n\t\t//stylech = styler.StyleAt(nePos);\n\t\tint stylech = styler.StyleAt(nsPos);\n\t\tif (!(stylech == SCE_AU3_COMMENT)) {\n\t\t\tchar ch = styler.SafeGetCharAt(nePos);\n\t\t\tif (!isspacechar(ch)) {\n\t\t\t\tif (ch == '_')\n\t\t\t\t\treturn true;\n\t\t\t\telse\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tnePos--; // skip to next char\n\t} // End While\n\treturn false;\n} // IsContinuationLine()\n\n//\n// syntax highlighting logic\nstatic void ColouriseAU3Doc(Sci_PositionU startPos,\n\t\t\t\t\t\t\tSci_Position length, int initStyle,\n\t\t\t\t\t\t\tWordList *keywordlists[],\n\t\t\t\t\t\t\tAccessor &styler) {\n\n    WordList &keywords = *keywordlists[0];\n    WordList &keywords2 = *keywordlists[1];\n    WordList &keywords3 = *keywordlists[2];\n    WordList &keywords4 = *keywordlists[3];\n    WordList &keywords5 = *keywordlists[4];\n    WordList &keywords6 = *keywordlists[5];\n    WordList &keywords7 = *keywordlists[6];\n    WordList &keywords8 = *keywordlists[7];\n\t// find the first previous line without continuation character at the end\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tSci_Position s_startPos = startPos;\n\t// When not inside a Block comment: find First line without _\n\tif (!(initStyle==SCE_AU3_COMMENTBLOCK)) {\n\t\twhile ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||\n\t\t\t   (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {\n\t\t\tlineCurrent--;\n\t\t\tstartPos = styler.LineStart(lineCurrent); // get start position\n\t\t\tinitStyle =  0;                           // reset the start style to 0\n\t\t}\n\t}\n\t// Set the new length to include it from the start and set the start position\n\tlength = length + s_startPos - startPos;      // correct the total length to process\n    styler.StartAt(startPos);\n\n    StyleContext sc(startPos, length, initStyle, styler);\n\tchar si;     // string indicator \"=1 '=2\n\tchar ni;     // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3\n\tchar ci;     // comment indicator 0=not linecomment(;)\n\tchar s_save[100] = \"\";\n\tsi=0;\n\tni=0;\n\tci=0;\n\t//$$$\n    for (; sc.More(); sc.Forward()) {\n\t\tchar s[100];\n\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t// **********************************************\n\t\t// save the total current word for eof processing\n\t\tif (IsAWordChar(sc.ch) || sc.ch == '}')\n\t\t{\n\t\t\tstrcpy(s_save,s);\n\t\t\tint tp = static_cast<int>(strlen(s_save));\n\t\t\tif (tp < 99) {\n\t\t\t\ts_save[tp] = static_cast<char>(tolower(sc.ch));\n\t\t\t\ts_save[tp+1] = '\\0';\n\t\t\t}\n\t\t}\n\t\t// **********************************************\n\t\t//\n\t\tswitch (sc.state)\n        {\n            case SCE_AU3_COMMENTBLOCK:\n            {\n\t\t\t\t//Reset at line end\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tci=0;\n\t\t\t\t\tif (strcmp(s, \"#ce\")== 0 || strcmp(s, \"#comments-end\")== 0) {\n\t\t\t\t\t\tif (sc.atLineEnd)\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_COMMENTBLOCK);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t//skip rest of line when a ; is encountered\n\t\t\t\tif (sc.chPrev == ';') {\n\t\t\t\t\tci=2;\n\t\t\t\t\tsc.SetState(SCE_AU3_COMMENTBLOCK);\n\t\t\t\t}\n\t\t\t\t// skip rest of the line\n\t\t\t\tif (ci==2)\n\t\t\t\t\tbreak;\n\t\t\t\t// check when first character is detected on the line\n\t\t\t\tif (ci==0) {\n\t\t\t\t\tif (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {\n\t\t\t\t\t\tci=1;\n\t\t\t\t\t\tsc.SetState(SCE_AU3_COMMENTBLOCK);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, \"#comments\") == 0))) {\n\t\t\t\t\tif ((strcmp(s, \"#ce\")== 0 || strcmp(s, \"#comments-end\")== 0))\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_COMMENT);  // set to comment line for the rest of the line\n\t\t\t\t\telse\n\t\t\t\t\t\tci=2;  // line doesn't begin with #CE so skip the rest of the line\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n            case SCE_AU3_COMMENT:\n            {\n                if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}\n                break;\n            }\n            case SCE_AU3_OPERATOR:\n            {\n                // check if its a COMobject\n\t\t\t\tif (sc.chPrev == '.' && IsAWordChar(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_AU3_COMOBJ);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t}\n                break;\n            }\n            case SCE_AU3_SPECIAL:\n            {\n                if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}\n\t\t\t\tif (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}\n                break;\n            }\n            case SCE_AU3_KEYWORD:\n            {\n                if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && (strcmp(s, \"#comments\") == 0 || strcmp(s, \"#include\") == 0))))\n                {\n                    if (!IsTypeCharacter(sc.ch))\n                    {\n\t\t\t\t\t\tif (strcmp(s, \"#cs\")== 0 || strcmp(s, \"#comments-start\")== 0 )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_COMMENTBLOCK);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_COMMENTBLOCK);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (keywords.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_KEYWORD);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (keywords2.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_FUNCTION);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (keywords3.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_MACRO);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (keywords5.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_PREPROCESSOR);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\t\tif (strcmp(s, \"#include\")== 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsi = 3;   // use to determine string start for #inlude <>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (keywords6.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_SPECIAL);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_SPECIAL);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_EXPAND);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (keywords8.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_UDF);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (strcmp(s, \"_\") == 0) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_OPERATOR);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (!IsAWordChar(sc.ch)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n                if (sc.atLineEnd) {\n\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);}\n                break;\n            }\n\t\t\tcase SCE_AU3_NUMBER:\n            {\n\t\t\t\t// Numeric indicator error=9 normal=0 normal+dec=1 hex=2 E-not=3\n\t\t\t\t//\n\t\t\t\t// test for Hex notation\n\t\t\t\tif (strcmp(s, \"0\") == 0 && (sc.ch == 'x' || sc.ch == 'X') && ni == 0)\n\t\t\t\t{\n\t\t\t\t\tni = 2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// test for E notation\n\t\t\t\tif (IsADigit(sc.chPrev) && (sc.ch == 'e' || sc.ch == 'E') && ni <= 1)\n\t\t\t\t{\n\t\t\t\t\tni = 3;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t//  Allow Hex characters inside hex numeric strings\n\t\t\t\tif ((ni == 2) &&\n\t\t\t\t\t(sc.ch == 'a' || sc.ch == 'b' || sc.ch == 'c' || sc.ch == 'd' || sc.ch == 'e' || sc.ch == 'f' ||\n\t\t\t\t\t sc.ch == 'A' || sc.ch == 'B' || sc.ch == 'C' || sc.ch == 'D' || sc.ch == 'E' || sc.ch == 'F' ))\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// test for 1 dec point only\n\t\t\t\tif (sc.ch == '.')\n\t\t\t\t{\n\t\t\t\t\tif (ni==0)\n\t\t\t\t\t{\n\t\t\t\t\t\tni=1;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tni=9;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// end of numeric string ?\n\t\t\t\tif (!(IsADigit(sc.ch)))\n\t\t\t\t{\n\t\t\t\t\tif (ni==9)\n\t\t\t\t\t{\n\t\t\t\t\t\tsc.ChangeState(SCE_AU3_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_AU3_VARIABLE:\n\t\t\t{\n\t\t\t\t// Check if its a COMObject\n\t\t\t\tif (sc.ch == '.' && !IsADigit(sc.chNext)) {\n\t\t\t\t\tsc.SetState(SCE_AU3_OPERATOR);\n\t\t\t\t}\n\t\t\t\telse if (!IsAWordChar(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n            }\n\t\t\tcase SCE_AU3_COMOBJ:\n\t\t\t{\n\t\t\t\tif (!(IsAWordChar(sc.ch))) {\n\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n            }\n            case SCE_AU3_STRING:\n            {\n\t\t\t\t// check for \" to end a double qouted string or\n\t\t\t\t// check for ' to end a single qouted string\n\t            if ((si == 1 && sc.ch == '\\\"') || (si == 2 && sc.ch == '\\'') || (si == 3 && sc.ch == '>'))\n\t\t\t\t{\n\t\t\t\t\tsc.ForwardSetState(SCE_AU3_DEFAULT);\n\t\t\t\t\tsi=0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n                if (sc.atLineEnd)\n\t\t\t\t{\n\t\t\t\t\tsi=0;\n\t\t\t\t\t// at line end and not found a continuation char then reset to default\n\t\t\t\t\tSci_Position lineCurrent = styler.GetLine(sc.currentPos);\n\t\t\t\t\tif (!IsContinuationLine(lineCurrent,styler))\n\t\t\t\t\t{\n\t\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// find Sendkeys in a STRING\n\t\t\t\tif (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ) {\n\t\t\t\t\tsc.SetState(SCE_AU3_SENT);}\n\t\t\t\tbreak;\n            }\n\n            case SCE_AU3_SENT:\n            {\n\t\t\t\t// Send key string ended\n\t\t\t\tif (sc.chPrev == '}' && sc.ch != '}')\n\t\t\t\t{\n\t\t\t\t\t// set color to SENDKEY when valid sendkey .. else set back to regular string\n\t\t\t\t\tchar sk[100];\n\t\t\t\t\t// split {111 222} and return {111} and check if 222 is valid.\n\t\t\t\t\t// if return code = 1 then invalid 222 so must be string\n\t\t\t\t\tif (GetSendKey(s,sk))\n\t\t\t\t\t{\n\t\t\t\t\t\tsc.ChangeState(SCE_AU3_STRING);\n\t\t\t\t\t}\n\t\t\t\t\t// if single char between {?} then its ok as sendkey for a single character\n\t\t\t\t\telse if (strlen(sk) == 3)\n\t\t\t\t\t{\n\t\t\t\t\t\tsc.ChangeState(SCE_AU3_SENT);\n\t\t\t\t\t}\n\t\t\t\t\t// if sendkey {111} is in table then ok as sendkey\n\t\t\t\t\telse if (keywords4.InList(sk))\n\t\t\t\t\t{\n\t\t\t\t\t\tsc.ChangeState(SCE_AU3_SENT);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsc.ChangeState(SCE_AU3_STRING);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_AU3_STRING);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// check if the start is a valid SendKey start\n\t\t\t\t\tSci_Position\t\tnPos\t= 0;\n\t\t\t\t\tint\t\tnState\t= 1;\n\t\t\t\t\tchar\tcTemp;\n\t\t\t\t\twhile (!(nState == 2) && ((cTemp = s[nPos]) != '\\0'))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (cTemp == '{' && nState == 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnState = 2;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (nState == 1 && !(cTemp == '+' || cTemp == '!' || cTemp == '^' || cTemp == '#' ))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnState = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnPos++;\n\t\t\t\t\t}\n\t\t\t\t\t//Verify characters infront of { ... if not assume  regular string\n\t\t\t\t\tif (nState == 1 && (!(sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ))) {\n\t\t\t\t\t\tsc.ChangeState(SCE_AU3_STRING);\n\t\t\t\t\t\tsc.SetState(SCE_AU3_STRING);\n\t\t\t\t\t}\n\t\t\t\t\t// If invalid character found then assume its a regular string\n\t\t\t\t\tif (nState == 0) {\n\t\t\t\t\t\tsc.ChangeState(SCE_AU3_STRING);\n\t\t\t\t\t\tsc.SetState(SCE_AU3_STRING);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// check if next portion is again a sendkey\n\t\t\t\tif (sc.atLineEnd)\n\t\t\t\t{\n\t\t\t\t\tsc.ChangeState(SCE_AU3_STRING);\n\t\t\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t\t\t\tsi = 0;  // reset string indicator\n\t\t\t\t}\n\t\t\t\t//* check in next characters following a sentkey are again a sent key\n\t\t\t\t// Need this test incase of 2 sentkeys like {F1}{ENTER} but not detect {{}\n\t\t\t\tif (sc.state == SCE_AU3_STRING && (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' )) {\n\t\t\t\t\tsc.SetState(SCE_AU3_SENT);}\n\t\t\t\t// check to see if the string ended...\n\t\t\t\t// Sendkey string isn't complete but the string ended....\n\t\t\t\tif ((si == 1 && sc.ch == '\\\"') || (si == 2 && sc.ch == '\\''))\n\t\t\t\t{\n\t\t\t\t\tsc.ChangeState(SCE_AU3_STRING);\n\t\t\t\t\tsc.ForwardSetState(SCE_AU3_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n            }\n        }  //switch (sc.state)\n\n        // Determine if a new state should be entered:\n\n\t\tif (sc.state == SCE_AU3_DEFAULT)\n        {\n            if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}\n            else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}\n            else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}\n            else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}\n            else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}\n            //else if (sc.ch == '_') {sc.SetState(SCE_AU3_KEYWORD);}\n            else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);}  // string after #include\n            else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_AU3_STRING);\n\t\t\t\tsi = 1;\t}\n            else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_AU3_STRING);\n\t\t\t\tsi = 2;\t}\n            else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))\n\t\t\t{\n\t\t\t\tsc.SetState(SCE_AU3_NUMBER);\n\t\t\t\tni = 0;\n\t\t\t}\n            else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}\n            else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}\n\t\t\telse if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}\n        }\n    }      //for (; sc.More(); sc.Forward())\n\n\t//*************************************\n\t// Colourize the last word correctly\n\t//*************************************\n\tif (sc.state == SCE_AU3_KEYWORD)\n\t\t{\n\t\tif (strcmp(s_save, \"#cs\")== 0 || strcmp(s_save, \"#comments-start\")== 0 )\n\t\t{\n\t\t\tsc.ChangeState(SCE_AU3_COMMENTBLOCK);\n\t\t\tsc.SetState(SCE_AU3_COMMENTBLOCK);\n\t\t}\n\t\telse if (keywords.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_AU3_KEYWORD);\n\t\t\tsc.SetState(SCE_AU3_KEYWORD);\n\t\t}\n\t\telse if (keywords2.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_AU3_FUNCTION);\n\t\t\tsc.SetState(SCE_AU3_FUNCTION);\n\t\t}\n\t\telse if (keywords3.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_AU3_MACRO);\n\t\t\tsc.SetState(SCE_AU3_MACRO);\n\t\t}\n\t\telse if (keywords5.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_AU3_PREPROCESSOR);\n\t\t\tsc.SetState(SCE_AU3_PREPROCESSOR);\n\t\t}\n\t\telse if (keywords6.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_AU3_SPECIAL);\n\t\t\tsc.SetState(SCE_AU3_SPECIAL);\n\t\t}\n\t\telse if (keywords7.InList(s_save) && sc.atLineEnd) {\n\t\t\tsc.ChangeState(SCE_AU3_EXPAND);\n\t\t\tsc.SetState(SCE_AU3_EXPAND);\n\t\t}\n\t\telse if (keywords8.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_AU3_UDF);\n\t\t\tsc.SetState(SCE_AU3_UDF);\n\t\t}\n\t\telse {\n\t\t\tsc.ChangeState(SCE_AU3_DEFAULT);\n\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t}\n\t}\n\tif (sc.state == SCE_AU3_SENT)\n    {\n\t\t// Send key string ended\n\t\tif (sc.chPrev == '}' && sc.ch != '}')\n\t\t{\n\t\t\t// set color to SENDKEY when valid sendkey .. else set back to regular string\n\t\t\tchar sk[100];\n\t\t\t// split {111 222} and return {111} and check if 222 is valid.\n\t\t\t// if return code = 1 then invalid 222 so must be string\n\t\t\tif (GetSendKey(s_save,sk))\n\t\t\t{\n\t\t\t\tsc.ChangeState(SCE_AU3_STRING);\n\t\t\t}\n\t\t\t// if single char between {?} then its ok as sendkey for a single character\n\t\t\telse if (strlen(sk) == 3)\n\t\t\t{\n\t\t\t\tsc.ChangeState(SCE_AU3_SENT);\n\t\t\t}\n\t\t\t// if sendkey {111} is in table then ok as sendkey\n\t\t\telse if (keywords4.InList(sk))\n\t\t\t{\n\t\t\t\tsc.ChangeState(SCE_AU3_SENT);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsc.ChangeState(SCE_AU3_STRING);\n\t\t\t}\n\t\t\tsc.SetState(SCE_AU3_STRING);\n\t\t}\n\t\t// check if next portion is again a sendkey\n\t\tif (sc.atLineEnd)\n\t\t{\n\t\t\tsc.ChangeState(SCE_AU3_STRING);\n\t\t\tsc.SetState(SCE_AU3_DEFAULT);\n\t\t}\n    }\n\t//*************************************\n\tsc.Complete();\n}\n\n//\nstatic bool IsStreamCommentStyle(int style) {\n\treturn style == SCE_AU3_COMMENT || style == SCE_AU3_COMMENTBLOCK;\n}\n\n//\n// Routine to find first none space on the current line and return its Style\n// needed for comment lines not starting on pos 1\nstatic int GetStyleFirstWord(Sci_PositionU szLine, Accessor &styler)\n{\n\tSci_Position nsPos = styler.LineStart(szLine);\n\tSci_Position nePos = styler.LineStart(szLine+1) - 1;\n\twhile (isspacechar(styler.SafeGetCharAt(nsPos)) && nsPos < nePos)\n\t{\n\t\tnsPos++; // skip to next char\n\n\t} // End While\n\treturn styler.StyleAt(nsPos);\n\n} // GetStyleFirstWord()\n\n\n//\nstatic void FoldAU3Doc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)\n{\n\tSci_Position endPos = startPos + length;\n\t// get settings from the config files for folding comments and preprocessor lines\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldInComment = styler.GetPropertyInt(\"fold.comment\") == 2;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tbool foldpreprocessor = styler.GetPropertyInt(\"fold.preprocessor\") != 0;\n\t// Backtrack to previous line in case need to fix its fold status\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (startPos > 0) {\n\t\tif (lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t\t}\n\t}\n\t// vars for style of previous/current/next lines\n\tint style = GetStyleFirstWord(lineCurrent,styler);\n\tint stylePrev = 0;\n\t// find the first previous line without continuation character at the end\n\twhile ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||\n\t       (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {\n\t\tlineCurrent--;\n\t\tstartPos = styler.LineStart(lineCurrent);\n\t}\n\tif (lineCurrent > 0) {\n\t\tstylePrev = GetStyleFirstWord(lineCurrent-1,styler);\n\t}\n\t// vars for getting first word to check for keywords\n\tbool FirstWordStart = false;\n\tbool FirstWordEnd = false;\n\tchar szKeyword[11]=\"\";\n\tint\t szKeywordlen = 0;\n\tchar szThen[5]=\"\";\n\tint\t szThenlen = 0;\n\tbool ThenFoundLast = false;\n\t// var for indentlevel\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelNext = levelCurrent;\n\t//\n\tint\tvisibleChars = 0;\n\tchar chNext = styler.SafeGetCharAt(startPos);\n\tchar chPrev = ' ';\n\t//\n\tfor (Sci_Position i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tif (IsAWordChar(ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t\t// get the syle for the current character neede to check in comment\n\t\tint stylech = styler.StyleAt(i);\n\t\t// get first word for the line for indent check max 9 characters\n\t\tif (FirstWordStart && (!(FirstWordEnd))) {\n\t\t\tif (!IsAWordChar(ch)) {\n\t\t\t\tFirstWordEnd = true;\n\t\t\t\tszKeyword[szKeywordlen] = '\\0';\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (szKeywordlen < 10) {\n\t\t\t\tszKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// start the capture of the first word\n\t\tif (!(FirstWordStart)) {\n\t\t\tif (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') {\n\t\t\t\tFirstWordStart = true;\n\t\t\t\tszKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));\n\t\t\t}\n\t\t}\n\t\t// only process this logic when not in comment section\n\t\tif (!(stylech == SCE_AU3_COMMENT)) {\n\t\t\tif (ThenFoundLast) {\n\t\t\t\tif (IsAWordChar(ch)) {\n\t\t\t\t\tThenFoundLast = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// find out if the word \"then\" is the last on a \"if\" line\n\t\t\tif (FirstWordEnd && strcmp(szKeyword,\"if\") == 0) {\n\t\t\t\tif (szThenlen == 4) {\n\t\t\t\t\tszThen[0] = szThen[1];\n\t\t\t\t\tszThen[1] = szThen[2];\n\t\t\t\t\tszThen[2] = szThen[3];\n\t\t\t\t\tszThen[3] = static_cast<char>(tolower(ch));\n\t\t\t\t\tif (strcmp(szThen,\"then\") == 0 ) {\n\t\t\t\t\t\tThenFoundLast = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tszThen[szThenlen++] = static_cast<char>(tolower(ch));\n\t\t\t\t\tif (szThenlen == 5) {\n\t\t\t\t\t\tszThen[4] = '\\0';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// End of Line found so process the information\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n') || (i == endPos)) {\n\t\t\t// **************************\n\t\t\t// Folding logic for Keywords\n\t\t\t// **************************\n\t\t\t// if a keyword is found on the current line and the line doesn't end with _ (continuation)\n\t\t\t//    and we are not inside a commentblock.\n\t\t\tif (szKeywordlen > 0 && (!(chPrev == '_')) &&\n\t\t\t\t((!(IsStreamCommentStyle(style)) || foldInComment)) ) {\n\t\t\t\tszKeyword[szKeywordlen] = '\\0';\n\t\t\t\t// only fold \"if\" last keyword is \"then\"  (else its a one line if)\n\t\t\t\tif (strcmp(szKeyword,\"if\") == 0  && ThenFoundLast) {\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t}\n\t\t\t\t// create new fold for these words\n\t\t\t\tif (strcmp(szKeyword,\"do\") == 0   || strcmp(szKeyword,\"for\") == 0 ||\n\t\t\t\t\tstrcmp(szKeyword,\"func\") == 0 || strcmp(szKeyword,\"while\") == 0||\n\t\t\t\t\tstrcmp(szKeyword,\"with\") == 0 || strcmp(szKeyword,\"#region\") == 0 ) {\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t}\n\t\t\t\t// create double Fold for select&switch because Case will subtract one of the current level\n\t\t\t\tif (strcmp(szKeyword,\"select\") == 0 || strcmp(szKeyword,\"switch\") == 0) {\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t}\n\t\t\t\t// end the fold for these words before the current line\n\t\t\t\tif (strcmp(szKeyword,\"endfunc\") == 0 || strcmp(szKeyword,\"endif\") == 0 ||\n\t\t\t\t\tstrcmp(szKeyword,\"next\") == 0    || strcmp(szKeyword,\"until\") == 0 ||\n\t\t\t\t\tstrcmp(szKeyword,\"endwith\") == 0 ||strcmp(szKeyword,\"wend\") == 0){\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t\t// end the fold for these words before the current line and Start new fold\n\t\t\t\tif (strcmp(szKeyword,\"case\") == 0      || strcmp(szKeyword,\"else\") == 0 ||\n\t\t\t\t\tstrcmp(szKeyword,\"elseif\") == 0 ) {\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t\t// end the double fold for this word before the current line\n\t\t\t\tif (strcmp(szKeyword,\"endselect\") == 0 || strcmp(szKeyword,\"endswitch\") == 0 ) {\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t\t// end the fold for these words on the current line\n\t\t\t\tif (strcmp(szKeyword,\"#endregion\") == 0 ) {\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Preprocessor and Comment folding\n\t\t\tint styleNext = GetStyleFirstWord(lineCurrent + 1,styler);\n\t\t\t// *************************************\n\t\t\t// Folding logic for preprocessor blocks\n\t\t\t// *************************************\n\t\t\t// process preprosessor line\n\t\t\tif (foldpreprocessor && style == SCE_AU3_PREPROCESSOR) {\n\t\t\t\tif (!(stylePrev == SCE_AU3_PREPROCESSOR) && (styleNext == SCE_AU3_PREPROCESSOR)) {\n\t\t\t\t    levelNext++;\n\t\t\t\t}\n\t\t\t\t// fold till the last line for normal comment lines\n\t\t\t\telse if (stylePrev == SCE_AU3_PREPROCESSOR && !(styleNext == SCE_AU3_PREPROCESSOR)) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// *********************************\n\t\t\t// Folding logic for Comment blocks\n\t\t\t// *********************************\n\t\t\tif (foldComment && IsStreamCommentStyle(style)) {\n\t\t\t\t// Start of a comment block\n\t\t\t\tif (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {\n\t\t\t\t    levelNext++;\n\t\t\t\t}\n\t\t\t\t// fold till the last line for normal comment lines\n\t\t\t\telse if (IsStreamCommentStyle(stylePrev)\n\t\t\t\t\t\t&& !(styleNext == SCE_AU3_COMMENT)\n\t\t\t\t\t\t&& stylePrev == SCE_AU3_COMMENT\n\t\t\t\t\t\t&& style == SCE_AU3_COMMENT) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t\t// fold till the one but last line for Blockcomment lines\n\t\t\t\telse if (IsStreamCommentStyle(stylePrev)\n\t\t\t\t\t\t&& !(styleNext == SCE_AU3_COMMENTBLOCK)\n\t\t\t\t\t\t&& style == SCE_AU3_COMMENTBLOCK) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t\tint levelUse = levelCurrent;\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext) {\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\t// reset values for the next line\n\t\t\tlineCurrent++;\n\t\t\tstylePrev = style;\n\t\t\tstyle = styleNext;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tvisibleChars = 0;\n\t\t\t// if the last character is an Underscore then don't reset since the line continues on the next line.\n\t\t\tif (!(chPrev == '_')) {\n\t\t\t\tszKeywordlen = 0;\n\t\t\t\tszThenlen = 0;\n\t\t\t\tFirstWordStart = false;\n\t\t\t\tFirstWordEnd = false;\n\t\t\t\tThenFoundLast = false;\n\t\t\t}\n\t\t}\n\t\t// save the last processed character\n\t\tif (!isspacechar(ch)) {\n\t\t\tchPrev = ch;\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n}\n\n\n//\n\nstatic const char * const AU3WordLists[] = {\n    \"#autoit keywords\",\n    \"#autoit functions\",\n    \"#autoit macros\",\n    \"#autoit Sent keys\",\n    \"#autoit Pre-processors\",\n    \"#autoit Special\",\n    \"#autoit Expand\",\n    \"#autoit UDF\",\n    0\n};\nextern const LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, \"au3\", FoldAU3Doc , AU3WordLists);\n"
  },
  {
    "path": "lexers/LexAVE.cxx",
    "content": "// SciTE - Scintilla based Text Editor\n/** @file LexAVE.cxx\n ** Lexer for Avenue.\n **\n  ** Written by Alexey Yutkin <yutkin@geol.msu.ru>.\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');\n}\nstatic inline bool IsEnumChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch)|| ch == '_');\n}\nstatic inline bool IsANumberChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '.' );\n}\n\ninline bool IsAWordStart(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\ninline bool isAveOperator(char ch) {\n\tif (IsASCII(ch) && isalnum(ch))\n\t\treturn false;\n\t// '.' left out as it is used to make up numbers\n\tif (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||\n\t\tch == '(' || ch == ')' || ch == '=' ||\n\t\tch == '{' || ch == '}' ||\n\t\tch == '[' || ch == ']' || ch == ';' ||\n\t\tch == '<' || ch == '>' || ch == ',' ||\n\t\tch == '.'  )\n\t\treturn true;\n\treturn false;\n}\n\nstatic void ColouriseAveDoc(\n\tSci_PositionU startPos,\n\tSci_Position length,\n\tint initStyle,\n\tWordList *keywordlists[],\n\tAccessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\tWordList &keywords4 = *keywordlists[3];\n\tWordList &keywords5 = *keywordlists[4];\n\tWordList &keywords6 = *keywordlists[5];\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_AVE_STRINGEOL) {\n\t\tinitStyle = SCE_AVE_DEFAULT;\n\t}\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\tif (sc.atLineEnd) {\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tSci_Position currentLine = styler.GetLine(sc.currentPos);\n\t\t\tstyler.SetLineState(currentLine, 0);\n\t\t}\n\t\tif (sc.atLineStart && (sc.state == SCE_AVE_STRING)) {\n\t\t\t// Prevent SCE_AVE_STRINGEOL from leaking back to previous line\n\t\t\tsc.SetState(SCE_AVE_STRING);\n\t\t}\n\n\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_AVE_OPERATOR) {\n\t\t\tsc.SetState(SCE_AVE_DEFAULT);\n\t\t} else if (sc.state == SCE_AVE_NUMBER) {\n\t\t\tif (!IsANumberChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_AVE_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVE_ENUM) {\n\t\t\tif (!IsEnumChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_AVE_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVE_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch) || (sc.ch == '.')) {\n\t\t\t\tchar s[100];\n\t\t\t\t//sc.GetCurrent(s, sizeof(s));\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVE_WORD);\n\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVE_WORD2);\n\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVE_WORD3);\n\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVE_WORD4);\n\t\t\t\t} else if (keywords5.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVE_WORD5);\n\t\t\t\t} else if (keywords6.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVE_WORD6);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_AVE_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVE_COMMENT) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_AVE_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVE_STRING) {\n\t\t\t if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_AVE_DEFAULT);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_AVE_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_AVE_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_AVE_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_AVE_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_AVE_IDENTIFIER);\n\t\t\t} else if (sc.Match('\\\"')) {\n\t\t\t\tsc.SetState(SCE_AVE_STRING);\n\t\t\t} else if (sc.Match('\\'')) {\n\t\t\t\tsc.SetState(SCE_AVE_COMMENT);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (isAveOperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_AVE_OPERATOR);\n\t\t\t} else if (sc.Match('#')) {\n\t\t\t\tsc.SetState(SCE_AVE_ENUM);\n\t\t\t\tsc.Forward();\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void FoldAveDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],\n                       Accessor &styler) {\n\tSci_PositionU lengthDoc = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = static_cast<char>(tolower(styler[startPos]));\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tint styleNext = styler.StyleAt(startPos);\n\tchar s[10] = \"\";\n\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = static_cast<char>(tolower(chNext));\n\t\tchNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (style == SCE_AVE_WORD) {\n\t\t\tif (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') {\n\t\t\t\tfor (unsigned int j = 0; j < 6; j++) {\n\t\t\t\t\tif (!iswordchar(styler[i + j])) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ts[j] = static_cast<char>(tolower(styler[i + j]));\n\t\t\t\t\ts[j + 1] = '\\0';\n\t\t\t\t}\n\n\t\t\t\tif ((strcmp(s, \"then\") == 0) || (strcmp(s, \"for\") == 0) || (strcmp(s, \"while\") == 0)) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t}\n\t\t\t\tif ((strcmp(s, \"end\") == 0) || (strcmp(s, \"elseif\") == 0)) {\n\t\t\t\t\t// Normally \"elseif\" and \"then\" will be on the same line and will cancel\n\t\t\t\t\t// each other out.  // As implemented, this does not support fold.at.else.\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (style == SCE_AVE_OPERATOR) {\n\t\t\tif (ch == '{' || ch == '(') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == '}' || ch == ')') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact) {\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\t}\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0)) {\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nextern const LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, \"ave\", FoldAveDoc);\n\n"
  },
  {
    "path": "lexers/LexAVS.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexAVS.cxx\n ** Lexer for AviSynth.\n **/\n// Copyright 2012 by Bruno Barbieri <brunorex@gmail.com>\n// Heavily based on LexPOV by Neil Hodgson\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\nstatic inline bool IsAWordStart(int ch) {\n\treturn isalpha(ch) || (ch != ' ' && ch != '\\n' && ch != '(' && ch != '.' && ch != ',');\n}\n\nstatic inline bool IsANumberChar(int ch) {\n\t// Not exactly following number definition (several dots are seen as OK, etc.)\n\t// but probably enough in most cases.\n\treturn (ch < 0x80) &&\n\t\t\t(isdigit(ch) || ch == '.' || ch == '-' || ch == '+');\n}\n\nstatic void ColouriseAvsDoc(\n\tSci_PositionU startPos,\n\tSci_Position length,\n\tint initStyle,\n\tWordList *keywordlists[],\n\tAccessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &filters = *keywordlists[1];\n\tWordList &plugins = *keywordlists[2];\n\tWordList &functions = *keywordlists[3];\n\tWordList &clipProperties = *keywordlists[4];\n\tWordList &userDefined = *keywordlists[5];\n\n\tSci_Position currentLine = styler.GetLine(startPos);\n\t// Initialize the block comment nesting level, if we are inside such a comment.\n\tint blockCommentLevel = 0;\n\tif (initStyle == SCE_AVS_COMMENTBLOCK || initStyle == SCE_AVS_COMMENTBLOCKN) {\n\t\tblockCommentLevel = styler.GetLineState(currentLine - 1);\n\t}\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_AVS_COMMENTLINE) {\n\t\tinitStyle = SCE_AVS_DEFAULT;\n\t}\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\tif (sc.atLineEnd) {\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tcurrentLine = styler.GetLine(sc.currentPos);\n\t\t\tif (sc.state == SCE_AVS_COMMENTBLOCK || sc.state == SCE_AVS_COMMENTBLOCKN) {\n\t\t\t\t// Inside a block comment, we set the line state\n\t\t\t\tstyler.SetLineState(currentLine, blockCommentLevel);\n\t\t\t} else {\n\t\t\t\t// Reset the line state\n\t\t\t\tstyler.SetLineState(currentLine, 0);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_AVS_OPERATOR) {\n\t\t\tsc.SetState(SCE_AVS_DEFAULT);\n\t\t} else if (sc.state == SCE_AVS_NUMBER) {\n\t\t\t// We stop the number definition on non-numerical non-dot non-sign char\n\t\t\tif (!IsANumberChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_AVS_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVS_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVS_KEYWORD);\n\t\t\t\t} else if (filters.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVS_FILTER);\n\t\t\t\t} else if (plugins.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVS_PLUGIN);\n\t\t\t\t} else if (functions.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVS_FUNCTION);\n\t\t\t\t} else if (clipProperties.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVS_CLIPPROP);\n\t\t\t\t} else if (userDefined.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_AVS_USERDFN);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_AVS_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVS_COMMENTBLOCK) {\n\t\t\tif (sc.Match('/', '*')) {\n\t\t\t\tblockCommentLevel++;\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match('*', '/') && blockCommentLevel > 0) {\n\t\t\t\tblockCommentLevel--;\n\t\t\t\tsc.Forward();\n\t\t\t\tif (blockCommentLevel == 0) {\n\t\t\t\t\tsc.ForwardSetState(SCE_AVS_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVS_COMMENTBLOCKN) {\n\t\t\tif (sc.Match('[', '*')) {\n\t\t\t\tblockCommentLevel++;\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match('*', ']') && blockCommentLevel > 0) {\n\t\t\t\tblockCommentLevel--;\n\t\t\t\tsc.Forward();\n\t\t\t\tif (blockCommentLevel == 0) {\n\t\t\t\t\tsc.ForwardSetState(SCE_AVS_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVS_COMMENTLINE) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_AVS_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVS_STRING) {\n\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_AVS_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_AVS_TRIPLESTRING) {\n\t\t\tif (sc.Match(\"\\\"\\\"\\\"\")) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_AVS_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_AVS_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_AVS_NUMBER);\n\t\t\t} else \tif (IsADigit(sc.ch) || (sc.ch == ',' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState(SCE_AVS_NUMBER);\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tblockCommentLevel = 1;\n\t\t\t\tsc.SetState(SCE_AVS_COMMENTBLOCK);\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('[', '*')) {\n\t\t\t\tblockCommentLevel = 1;\n\t\t\t\tsc.SetState(SCE_AVS_COMMENTBLOCKN);\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_AVS_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tif (sc.Match(\"\\\"\\\"\\\"\")) {\n\t\t\t\t\tsc.SetState(SCE_AVS_TRIPLESTRING);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_AVS_STRING);\n\t\t\t\t}\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_AVS_OPERATOR);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_AVS_IDENTIFIER);\n\t\t\t}\n\t\t}\n\t}\n\n\t// End of file: complete any pending changeState\n\tif (sc.state == SCE_AVS_IDENTIFIER) {\n\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\tchar s[100];\n\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\n\t\t\tif (keywords.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_AVS_KEYWORD);\n\t\t\t} else if (filters.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_AVS_FILTER);\n\t\t\t} else if (plugins.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_AVS_PLUGIN);\n\t\t\t} else if (functions.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_AVS_FUNCTION);\n\t\t\t} else if (clipProperties.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_AVS_CLIPPROP);\n\t\t\t} else if (userDefined.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_AVS_USERDFN);\n\t\t\t}\n\t\t\tsc.SetState(SCE_AVS_DEFAULT);\n\t\t}\n\t}\n\n\tsc.Complete();\n}\n\nstatic void FoldAvsDoc(\n\tSci_PositionU startPos,\n\tSci_Position length,\n\tint initStyle,\n\tWordList *[],\n\tAccessor &styler) {\n\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (foldComment && style == SCE_AVS_COMMENTBLOCK) {\n\t\t\tif (stylePrev != SCE_AVS_COMMENTBLOCK) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if ((styleNext != SCE_AVS_COMMENTBLOCK) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\tif (foldComment && style == SCE_AVS_COMMENTBLOCKN) {\n\t\t\tif (stylePrev != SCE_AVS_COMMENTBLOCKN) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if ((styleNext != SCE_AVS_COMMENTBLOCKN) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\tif (style == SCE_AVS_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const avsWordLists[] = {\n\t\"Keywords\",\n\t\"Filters\",\n\t\"Plugins\",\n\t\"Functions\",\n\t\"Clip properties\",\n\t\"User defined functions\",\n\t0,\n};\n\nextern const LexerModule lmAVS(SCLEX_AVS, ColouriseAvsDoc, \"avs\", FoldAvsDoc, avsWordLists);\n"
  },
  {
    "path": "lexers/LexAbaqus.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexAbaqus.cxx\n ** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.\n ** By Sergio Lucato.\n ** Sort of completely rewritten by Gertjan Kloosterman\n **/\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// Code folding copyied and modified from LexBasic.cxx\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAKeywordChar(const int ch) {\n\treturn (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));\n}\n\nstatic inline bool IsASetChar(const int ch) {\n\treturn (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-')));\n}\n\nstatic void ColouriseABAQUSDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList*[] /* *keywordlists[] */,\n                            Accessor &styler) {\n\tenum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \\\n\t\t\t\t\t  DAT_LINE_VAL, DAT_LINE_COMMA,\\\n\t\t\t\t\t  COMMENT_LINE,\\\n\t\t\t\t\t  ST_ERROR, LINE_END } state ;\n\n\t// Do not leak onto next line\n\tstate = LINE_END ;\n\tinitStyle = SCE_ABAQUS_DEFAULT;\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\t// Things are actually quite simple\n\t// we have commentlines\n\t// keywordlines and datalines\n\t// On a data line there will only be colouring of numbers\n\t// a keyword line is constructed as\n\t// *word,[ paramname[=paramvalue]]*\n\t// if the line ends with a , the keyword line continues onto the new line\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\tswitch ( state ) {\n        case KW_LINE_KW :\n            if ( sc.atLineEnd ) {\n                // finished the line in keyword state, switch to LINE_END\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = LINE_END ;\n            } else if ( IsAKeywordChar(sc.ch) ) {\n                // nothing changes\n                state = KW_LINE_KW ;\n            } else if ( sc.ch == ',' ) {\n                // Well well we say a comma, arguments *MUST* follow\n                sc.SetState(SCE_ABAQUS_OPERATOR) ;\n                state = KW_LINE_COMMA ;\n            } else {\n                // Flag an error\n                sc.SetState(SCE_ABAQUS_PROCESSOR) ;\n                state = ST_ERROR ;\n            }\n            // Done with processing\n            break ;\n        case KW_LINE_COMMA :\n            // acomma on a keywordline was seen\n            if ( IsAKeywordChar(sc.ch)) {\n                sc.SetState(SCE_ABAQUS_ARGUMENT) ;\n                state = KW_LINE_PAR ;\n            } else if ( sc.atLineEnd || (sc.ch == ',') ) {\n                // we remain in keyword mode\n                state = KW_LINE_COMMA ;\n            } else if ( sc.ch == ' ' ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = KW_LINE_COMMA ;\n            } else {\n                // Anything else constitutes an error\n                sc.SetState(SCE_ABAQUS_PROCESSOR) ;\n                state = ST_ERROR ;\n            }\n            break ;\n        case KW_LINE_PAR :\n            if ( sc.atLineEnd ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = LINE_END ;\n            } else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) {\n                // remain in this state\n                state = KW_LINE_PAR ;\n            } else if ( sc.ch == ',' ) {\n                sc.SetState(SCE_ABAQUS_OPERATOR) ;\n                state = KW_LINE_COMMA ;\n            } else if ( sc.ch == '=' ) {\n                sc.SetState(SCE_ABAQUS_OPERATOR) ;\n                state = KW_LINE_EQ ;\n            } else {\n                // Anything else constitutes an error\n                sc.SetState(SCE_ABAQUS_PROCESSOR) ;\n                state = ST_ERROR ;\n            }\n            break ;\n        case KW_LINE_EQ :\n            if ( sc.ch == ' ' ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                // remain in this state\n                state = KW_LINE_EQ ;\n            } else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) {\n                sc.SetState(SCE_ABAQUS_NUMBER) ;\n                state = KW_LINE_VAL ;\n            } else if ( IsAKeywordChar(sc.ch) ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = KW_LINE_VAL ;\n            } else if ( (sc.ch == '\\'') || (sc.ch == '\\\"') ) {\n                sc.SetState(SCE_ABAQUS_STRING) ;\n                state = KW_LINE_VAL ;\n            } else {\n                sc.SetState(SCE_ABAQUS_PROCESSOR) ;\n                state = ST_ERROR ;\n            }\n            break ;\n        case KW_LINE_VAL :\n            if ( sc.atLineEnd ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = LINE_END ;\n            } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {\n                // nothing changes\n                state = KW_LINE_VAL ;\n            } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||\n                    ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&\n                    (sc.state == SCE_ABAQUS_NUMBER)) {\n                // remain in number mode\n                state = KW_LINE_VAL ;\n            } else if (sc.state == SCE_ABAQUS_STRING) {\n                // accept everything until a closing quote\n                if ( sc.ch == '\\'' || sc.ch == '\\\"' ) {\n                    sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                    state = KW_LINE_VAL ;\n                }\n            } else if ( sc.ch == ',' ) {\n                sc.SetState(SCE_ABAQUS_OPERATOR) ;\n                state = KW_LINE_COMMA ;\n            } else {\n                // anything else is an error\n                sc.SetState(SCE_ABAQUS_PROCESSOR) ;\n                state = ST_ERROR ;\n            }\n            break ;\n        case DAT_LINE_VAL :\n            if ( sc.atLineEnd ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = LINE_END ;\n            } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {\n                // nothing changes\n                state = DAT_LINE_VAL ;\n            } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||\n                    ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&\n                    (sc.state == SCE_ABAQUS_NUMBER)) {\n                // remain in number mode\n                state = DAT_LINE_VAL ;\n            } else if (sc.state == SCE_ABAQUS_STRING) {\n                // accept everything until a closing quote\n                if ( sc.ch == '\\'' || sc.ch == '\\\"' ) {\n                    sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                    state = DAT_LINE_VAL ;\n                }\n            } else if ( sc.ch == ',' ) {\n                sc.SetState(SCE_ABAQUS_OPERATOR) ;\n                state = DAT_LINE_COMMA ;\n            } else {\n                // anything else is an error\n                sc.SetState(SCE_ABAQUS_PROCESSOR) ;\n                state = ST_ERROR ;\n            }\n            break ;\n        case DAT_LINE_COMMA :\n            // a comma on a data line was seen\n            if ( sc.atLineEnd ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = LINE_END ;\n            } else if ( sc.ch == ' ' ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = DAT_LINE_COMMA ;\n            } else if (sc.ch == ',')  {\n                sc.SetState(SCE_ABAQUS_OPERATOR) ;\n                state = DAT_LINE_COMMA ;\n            } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {\n                sc.SetState(SCE_ABAQUS_NUMBER) ;\n                state = DAT_LINE_VAL ;\n            } else if ( IsAKeywordChar(sc.ch) ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = DAT_LINE_VAL ;\n            } else if ( (sc.ch == '\\'') || (sc.ch == '\\\"') ) {\n                sc.SetState(SCE_ABAQUS_STRING) ;\n                state = DAT_LINE_VAL ;\n            } else {\n                sc.SetState(SCE_ABAQUS_PROCESSOR) ;\n                state = ST_ERROR ;\n            }\n            break ;\n        case COMMENT_LINE :\n            if ( sc.atLineEnd ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = LINE_END ;\n            }\n            break ;\n        case ST_ERROR :\n            if ( sc.atLineEnd ) {\n                sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                state = LINE_END ;\n            }\n            break ;\n        case LINE_END :\n            if ( sc.atLineEnd || sc.ch == ' ' ) {\n                // nothing changes\n                state = LINE_END ;\n            } else if ( sc.ch == '*' ) {\n                if ( sc.chNext == '*' ) {\n                    state = COMMENT_LINE ;\n                    sc.SetState(SCE_ABAQUS_COMMENT) ;\n                } else {\n                    state = KW_LINE_KW ;\n                    sc.SetState(SCE_ABAQUS_STARCOMMAND) ;\n                }\n            } else {\n                // it must be a data line, things are as if we are in DAT_LINE_COMMA\n                if ( sc.ch == ',' ) {\n                    sc.SetState(SCE_ABAQUS_OPERATOR) ;\n                    state = DAT_LINE_COMMA ;\n                } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {\n                    sc.SetState(SCE_ABAQUS_NUMBER) ;\n                    state = DAT_LINE_VAL ;\n                } else if ( IsAKeywordChar(sc.ch) ) {\n                    sc.SetState(SCE_ABAQUS_DEFAULT) ;\n                    state = DAT_LINE_VAL ;\n                } else if ( (sc.ch == '\\'') || (sc.ch == '\\\"') ) {\n                    sc.SetState(SCE_ABAQUS_STRING) ;\n                    state = DAT_LINE_VAL ;\n                } else {\n                    sc.SetState(SCE_ABAQUS_PROCESSOR) ;\n                    state = ST_ERROR ;\n                }\n            }\n            break ;\n\t\t  }\n   }\n   sc.Complete();\n}\n\n//------------------------------------------------------------------------------\n// This copyied and modified from LexBasic.cxx\n//------------------------------------------------------------------------------\n\n/* Bits:\n * 1  - whitespace\n * 2  - operator\n * 4  - identifier\n * 8  - decimal digit\n * 16 - hex digit\n * 32 - bin digit\n */\nstatic int character_classification[128] =\n{\n    0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  1,  0,  0,\n    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n    1,  2,  0,  2,  2,  2,  2,  2,  2,  2,  6,  2,  2,  2,  10, 6,\n    60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2,  2,  2,  2,  2,  2,\n    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,\n    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  4,\n    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,\n    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  0\n};\n\nstatic bool IsSpace(int c) {\n\treturn c < 128 && (character_classification[c] & 1);\n}\n\nstatic bool IsIdentifier(int c) {\n\treturn c < 128 && (character_classification[c] & 4);\n}\n\nstatic int LowerCase(int c)\n{\n\tif (c >= 'A' && c <= 'Z')\n\t\treturn 'a' + c - 'A';\n\treturn c;\n}\n\nstatic Sci_Position LineEnd(Sci_Position line, Accessor &styler)\n{\n    const Sci_Position docLines = styler.GetLine(styler.Length() - 1);  // Available last line\n    Sci_Position eol_pos ;\n    // if the line is the last line, the eol_pos is styler.Length()\n    // eol will contain a new line, or a virtual new line\n    if ( docLines == line )\n        eol_pos = styler.Length() ;\n    else\n        eol_pos = styler.LineStart(line + 1) - 1;\n    return eol_pos ;\n}\n\nstatic Sci_Position LineStart(Sci_Position line, Accessor &styler)\n{\n    return styler.LineStart(line) ;\n}\n\n// LineType\n//\n// bits determines the line type\n// 1  : data line\n// 2  : only whitespace\n// 3  : data line with only whitespace\n// 4  : keyword line\n// 5  : block open keyword line\n// 6  : block close keyword line\n// 7  : keyword line in error\n// 8  : comment line\nstatic int LineType(Sci_Position line, Accessor &styler) {\n    Sci_Position pos = LineStart(line, styler) ;\n    Sci_Position eol_pos = LineEnd(line, styler) ;\n\n    int c ;\n    char ch = ' ';\n\n    Sci_Position i = pos ;\n    while ( i < eol_pos ) {\n        c = styler.SafeGetCharAt(i);\n        ch = static_cast<char>(LowerCase(c));\n        // We can say something as soon as no whitespace\n        // was encountered\n        if ( !IsSpace(c) )\n            break ;\n        i++ ;\n    }\n\n    if ( i >= eol_pos ) {\n        // This is a whitespace line, currently\n        // classifies as data line\n        return 3 ;\n    }\n\n    if ( ch != '*' ) {\n        // This is a data line\n        return 1 ;\n    }\n\n    if ( i == eol_pos - 1 ) {\n        // Only a single *, error but make keyword line\n        return 4+3 ;\n    }\n\n    // This means we can have a second character\n    // if that is also a * this means a comment\n    // otherwise it is a keyword.\n    c = styler.SafeGetCharAt(i+1);\n    ch = static_cast<char>(LowerCase(c));\n    if ( ch == '*' ) {\n        return 8 ;\n    }\n\n    // At this point we know this is a keyword line\n    // the character at position i is a *\n    // it is not a comment line\n    char word[256] ;\n    int  wlen = 0;\n\n    word[wlen] = '*' ;\n\twlen++ ;\n\n    i++ ;\n    while ( (i < eol_pos) && (wlen < 255) ) {\n        c = styler.SafeGetCharAt(i);\n        ch = static_cast<char>(LowerCase(c));\n\n        if ( (!IsSpace(c)) && (!IsIdentifier(c)) )\n            break ;\n\n        if ( IsIdentifier(c) ) {\n            word[wlen] = ch ;\n\t\t\twlen++ ;\n\t\t}\n\n        i++ ;\n    }\n\n    word[wlen] = 0 ;\n\n    // Make a comparison\n\tif ( !strcmp(word, \"*step\") ||\n         !strcmp(word, \"*part\") ||\n         !strcmp(word, \"*instance\") ||\n         !strcmp(word, \"*assembly\")) {\n       return 4+1 ;\n    }\n\n\tif ( !strcmp(word, \"*endstep\") ||\n         !strcmp(word, \"*endpart\") ||\n         !strcmp(word, \"*endinstance\") ||\n         !strcmp(word, \"*endassembly\")) {\n       return 4+2 ;\n    }\n\n    return 4 ;\n}\n\nstatic void SafeSetLevel(Sci_Position line, int level, Accessor &styler)\n{\n    if ( line < 0 )\n        return ;\n\n    int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG));\n\n    if ( (level & mask) < 0 )\n        return ;\n\n    if ( styler.LevelAt(line) != level )\n        styler.SetLevel(line, level) ;\n}\n\nstatic void FoldABAQUSDoc(Sci_PositionU startPos, Sci_Position length, int,\nWordList *[], Accessor &styler) {\n    Sci_Position startLine = styler.GetLine(startPos) ;\n    Sci_Position endLine   = styler.GetLine(startPos+length-1) ;\n\n    // bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n    // We want to deal with all the cases\n    // To know the correct indentlevel, we need to look back to the\n    // previous command line indentation level\n\t// order of formatting keyline datalines commentlines\n    Sci_Position beginData    = -1 ;\n    Sci_Position beginComment = -1 ;\n    Sci_Position prvKeyLine   = startLine ;\n    Sci_Position prvKeyLineTp =  0 ;\n\n    // Scan until we find the previous keyword line\n    // this will give us the level reference that we need\n    while ( prvKeyLine > 0 ) {\n        prvKeyLine-- ;\n        prvKeyLineTp = LineType(prvKeyLine, styler) ;\n        if ( prvKeyLineTp & 4 )\n            break ;\n    }\n\n    // Determine the base line level of all lines following\n    // the previous keyword\n    // new keyword lines are placed on this level\n    //if ( prvKeyLineTp & 4 ) {\n    int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ;\n    //}\n\n    // uncomment line below if weird behaviour continues\n    prvKeyLine = -1 ;\n\n    // Now start scanning over the lines.\n    for ( Sci_Position line = startLine; line <= endLine; line++ ) {\n        int lineType = LineType(line, styler) ;\n\n        // Check for comment line\n        if ( lineType == 8 ) {\n            if ( beginComment < 0 ) {\n                beginComment = line ;\n\t\t\t}\n        }\n\n        // Check for data line\n        if ( (lineType == 1) || (lineType == 3) ) {\n            if ( beginData < 0 ) {\n                if ( beginComment >= 0 ) {\n                    beginData = beginComment ;\n                } else {\n                    beginData = line ;\n                }\n            }\n\t\t\tbeginComment = -1 ;\n\t\t}\n\n        // Check for keywordline.\n        // As soon as a keyword line is encountered, we can set the\n        // levels of everything from the previous keyword line to this one\n        if ( lineType & 4 ) {\n            // this is a keyword, we can now place the previous keyword\n            // all its data lines and the remainder\n\n            // Write comments and data line\n            if ( beginComment < 0 ) {\n                beginComment = line ;\n\t\t\t}\n\n            if ( beginData < 0 ) {\n                beginData = beginComment ;\n\t\t\t\tif ( prvKeyLineTp != 5 )\n\t\t\t\t\tSafeSetLevel(prvKeyLine, level, styler) ;\n\t\t\t\telse\n\t\t\t\t\tSafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;\n            } else {\n                SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;\n            }\n\n            int datLevel = level + 1 ;\n\t\t\tif ( !(prvKeyLineTp & 4) ) {\n\t\t\t\tdatLevel = level ;\n\t\t\t}\n\n            for ( Sci_Position ll = beginData; ll < beginComment; ll++ )\n                SafeSetLevel(ll, datLevel, styler) ;\n\n            // The keyword we just found is going to be written at another level\n            // if we have a type 5 and type 6\n            if ( prvKeyLineTp == 5 ) {\n                level += 1 ;\n\t\t\t}\n\n            if ( prvKeyLineTp == 6 ) {\n                level -= 1 ;\n\t\t\t\tif ( level < 0 ) {\n\t\t\t\t\tlevel = 0 ;\n\t\t\t\t}\n            }\n\n            for ( Sci_Position lll = beginComment; lll < line; lll++ )\n                SafeSetLevel(lll, level, styler) ;\n\n            // wrap and reset\n            beginComment = -1 ;\n            beginData    = -1 ;\n            prvKeyLine   = line ;\n            prvKeyLineTp = lineType ;\n        }\n\n    }\n\n    if ( beginComment < 0 ) {\n        beginComment = endLine + 1 ;\n    } else {\n        // We need to find out whether this comment block is followed by\n        // a data line or a keyword line\n        const Sci_Position docLines = styler.GetLine(styler.Length() - 1);\n\n        for ( Sci_Position line = endLine + 1; line <= docLines; line++ ) {\n            Sci_Position lineType = LineType(line, styler) ;\n\n            if ( lineType != 8 ) {\n\t\t\t\tif ( !(lineType & 4) )  {\n\t\t\t\t\tbeginComment = endLine + 1 ;\n\t\t\t\t}\n                break ;\n\t\t\t}\n        }\n    }\n\n    if ( beginData < 0 ) {\n        beginData = beginComment ;\n\t\tif ( prvKeyLineTp != 5 )\n\t\t\tSafeSetLevel(prvKeyLine, level, styler) ;\n\t\telse\n\t\t\tSafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;\n    } else {\n        SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;\n    }\n\n    int datLevel = level + 1 ;\n\tif ( !(prvKeyLineTp & 4) ) {\n\t\tdatLevel = level ;\n\t}\n\n    for ( Sci_Position ll = beginData; ll < beginComment; ll++ )\n        SafeSetLevel(ll, datLevel, styler) ;\n\n    if ( prvKeyLineTp == 5 ) {\n        level += 1 ;\n    }\n\n    if ( prvKeyLineTp == 6 ) {\n        level -= 1 ;\n    }\n    for ( Sci_Position m = beginComment; m <= endLine; m++ )\n        SafeSetLevel(m, level, styler) ;\n}\n\nstatic const char * const abaqusWordListDesc[] = {\n    \"processors\",\n    \"commands\",\n    \"slashommands\",\n    \"starcommands\",\n    \"arguments\",\n    \"functions\",\n    0\n};\n\nextern const LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, \"abaqus\", FoldABAQUSDoc, abaqusWordListDesc);\n"
  },
  {
    "path": "lexers/LexAda.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexAda.cxx\n ** Lexer for Ada 95\n **/\n// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n/*\n * Interface\n */\n\nstatic void ColouriseDocument(\n    Sci_PositionU startPos,\n    Sci_Position length,\n    int initStyle,\n    WordList *keywordlists[],\n    Accessor &styler);\n\nstatic const char * const adaWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmAda(SCLEX_ADA, ColouriseDocument, \"ada\", NULL, adaWordListDesc);\n\n/*\n * Implementation\n */\n\n// Functions that have apostropheStartsAttribute as a parameter set it according to whether\n// an apostrophe encountered after processing the current token will start an attribute or\n// a character literal.\nstatic void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL);\nstatic void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);\nstatic void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);\n\nstatic inline bool IsDelimiterCharacter(int ch);\nstatic inline bool IsSeparatorOrDelimiterCharacter(int ch);\nstatic bool IsValidIdentifier(const std::string& identifier);\nstatic bool IsValidNumber(const std::string& number);\nstatic inline bool IsWordStartCharacter(int ch);\nstatic inline bool IsWordCharacter(int ch);\n\nstatic void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) {\n\tapostropheStartsAttribute = true;\n\n\tsc.SetState(SCE_ADA_CHARACTER);\n\n\t// Skip the apostrophe and one more character (so that '' is shown as non-terminated and '''\n\t// is handled correctly)\n\tsc.Forward();\n\tsc.Forward();\n\n\tColouriseContext(sc, '\\'', SCE_ADA_CHARACTEREOL);\n}\n\nstatic void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) {\n\twhile (!sc.atLineEnd && !sc.Match(chEnd)) {\n\t\tsc.Forward();\n\t}\n\n\tif (!sc.atLineEnd) {\n\t\tsc.ForwardSetState(SCE_ADA_DEFAULT);\n\t} else {\n\t\tsc.ChangeState(stateEOL);\n\t}\n}\n\nstatic void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {\n\t// Apostrophe meaning is not changed, but the parameter is present for uniformity\n\n\tsc.SetState(SCE_ADA_COMMENTLINE);\n\n\twhile (!sc.atLineEnd) {\n\t\tsc.Forward();\n\t}\n}\n\nstatic void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {\n\tapostropheStartsAttribute = sc.Match (')');\n\tsc.SetState(SCE_ADA_DELIMITER);\n\tsc.ForwardSetState(SCE_ADA_DEFAULT);\n}\n\nstatic void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {\n\tapostropheStartsAttribute = false;\n\n\tsc.SetState(SCE_ADA_LABEL);\n\n\t// Skip \"<<\"\n\tsc.Forward();\n\tsc.Forward();\n\n\tstd::string identifier;\n\n\twhile (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {\n\t\tidentifier += static_cast<char>(tolower(sc.ch));\n\t\tsc.Forward();\n\t}\n\n\t// Skip \">>\"\n\tif (sc.Match('>', '>')) {\n\t\tsc.Forward();\n\t\tsc.Forward();\n\t} else {\n\t\tsc.ChangeState(SCE_ADA_ILLEGAL);\n\t}\n\n\t// If the name is an invalid identifier or a keyword, then make it invalid label\n\tif (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) {\n\t\tsc.ChangeState(SCE_ADA_ILLEGAL);\n\t}\n\n\tsc.SetState(SCE_ADA_DEFAULT);\n\n}\n\nstatic void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {\n\tapostropheStartsAttribute = true;\n\n\tstd::string number;\n\tsc.SetState(SCE_ADA_NUMBER);\n\n\t// Get all characters up to a delimiter or a separator, including points, but excluding\n\t// double points (ranges).\n\twhile (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {\n\t\tnumber += static_cast<char>(sc.ch);\n\t\tsc.Forward();\n\t}\n\n\t// Special case: exponent with sign\n\tif ((sc.chPrev == 'e' || sc.chPrev == 'E') &&\n\t        (sc.ch == '+' || sc.ch == '-')) {\n\t\tnumber += static_cast<char>(sc.ch);\n\t\tsc.Forward ();\n\n\t\twhile (!IsSeparatorOrDelimiterCharacter(sc.ch)) {\n\t\t\tnumber += static_cast<char>(sc.ch);\n\t\t\tsc.Forward();\n\t\t}\n\t}\n\n\tif (!IsValidNumber(number)) {\n\t\tsc.ChangeState(SCE_ADA_ILLEGAL);\n\t}\n\n\tsc.SetState(SCE_ADA_DEFAULT);\n}\n\nstatic void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) {\n\tapostropheStartsAttribute = true;\n\n\tsc.SetState(SCE_ADA_STRING);\n\tsc.Forward();\n\n\tColouriseContext(sc, '\"', SCE_ADA_STRINGEOL);\n}\n\nstatic void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {\n\t// Apostrophe meaning is not changed, but the parameter is present for uniformity\n\tsc.SetState(SCE_ADA_DEFAULT);\n\tsc.ForwardSetState(SCE_ADA_DEFAULT);\n}\n\nstatic void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {\n\tapostropheStartsAttribute = true;\n\tsc.SetState(SCE_ADA_IDENTIFIER);\n\n\tstd::string word;\n\n\twhile (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {\n\t\tword += static_cast<char>(tolower(sc.ch));\n\t\tsc.Forward();\n\t}\n\n\tif (!IsValidIdentifier(word)) {\n\t\tsc.ChangeState(SCE_ADA_ILLEGAL);\n\n\t} else if (keywords.InList(word.c_str())) {\n\t\tsc.ChangeState(SCE_ADA_WORD);\n\n\t\tif (word != \"all\") {\n\t\t\tapostropheStartsAttribute = false;\n\t\t}\n\t}\n\n\tsc.SetState(SCE_ADA_DEFAULT);\n}\n\n//\n// ColouriseDocument\n//\n\nstatic void ColouriseDocument(\n    Sci_PositionU startPos,\n    Sci_Position length,\n    int initStyle,\n    WordList *keywordlists[],\n    Accessor &styler) {\n\tWordList &keywords = *keywordlists[0];\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tbool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;\n\n\twhile (sc.More()) {\n\t\tif (sc.atLineEnd) {\n\t\t\t// Go to the next line\n\t\t\tsc.Forward();\n\t\t\tlineCurrent++;\n\n\t\t\t// Remember the line state for future incremental lexing\n\t\t\tstyler.SetLineState(lineCurrent, apostropheStartsAttribute);\n\n\t\t\t// Don't continue any styles on the next line\n\t\t\tsc.SetState(SCE_ADA_DEFAULT);\n\t\t}\n\n\t\t// Comments\n\t\tif (sc.Match('-', '-')) {\n\t\t\tColouriseComment(sc, apostropheStartsAttribute);\n\n\t\t// Strings\n\t\t} else if (sc.Match('\"')) {\n\t\t\tColouriseString(sc, apostropheStartsAttribute);\n\n\t\t// Characters\n\t\t} else if (sc.Match('\\'') && !apostropheStartsAttribute) {\n\t\t\tColouriseCharacter(sc, apostropheStartsAttribute);\n\n\t\t// Labels\n\t\t} else if (sc.Match('<', '<')) {\n\t\t\tColouriseLabel(sc, keywords, apostropheStartsAttribute);\n\n\t\t// Whitespace\n\t\t} else if (IsASpace(sc.ch)) {\n\t\t\tColouriseWhiteSpace(sc, apostropheStartsAttribute);\n\n\t\t// Delimiters\n\t\t} else if (IsDelimiterCharacter(sc.ch)) {\n\t\t\tColouriseDelimiter(sc, apostropheStartsAttribute);\n\n\t\t// Numbers\n\t\t} else if (IsADigit(sc.ch) || sc.ch == '#') {\n\t\t\tColouriseNumber(sc, apostropheStartsAttribute);\n\n\t\t// Keywords or identifiers\n\t\t} else {\n\t\t\tColouriseWord(sc, keywords, apostropheStartsAttribute);\n\t\t}\n\t}\n\n\tsc.Complete();\n}\n\nstatic inline bool IsDelimiterCharacter(int ch) {\n\tswitch (ch) {\n\tcase '&':\n\tcase '\\'':\n\tcase '(':\n\tcase ')':\n\tcase '*':\n\tcase '+':\n\tcase ',':\n\tcase '-':\n\tcase '.':\n\tcase '/':\n\tcase ':':\n\tcase ';':\n\tcase '<':\n\tcase '=':\n\tcase '>':\n\tcase '|':\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nstatic inline bool IsSeparatorOrDelimiterCharacter(int ch) {\n\treturn IsASpace(ch) || IsDelimiterCharacter(ch);\n}\n\nstatic bool IsValidIdentifier(const std::string& identifier) {\n\t// First character can't be '_', so initialize the flag to true\n\tbool lastWasUnderscore = true;\n\n\tsize_t length = identifier.length();\n\n\t// Zero-length identifiers are not valid (these can occur inside labels)\n\tif (length == 0) {\n\t\treturn false;\n\t}\n\n\t// Check for valid character at the start\n\tif (!IsWordStartCharacter(identifier[0])) {\n\t\treturn false;\n\t}\n\n\t// Check for only valid characters and no double underscores\n\tfor (size_t i = 0; i < length; i++) {\n\t\tif (!IsWordCharacter(identifier[i]) ||\n\t\t        (identifier[i] == '_' && lastWasUnderscore)) {\n\t\t\treturn false;\n\t\t}\n\t\tlastWasUnderscore = identifier[i] == '_';\n\t}\n\n\t// Check for underscore at the end\n\tif (lastWasUnderscore == true) {\n\t\treturn false;\n\t}\n\n\t// All checks passed\n\treturn true;\n}\n\nstatic bool IsValidNumber(const std::string& number) {\n\tsize_t hashPos = number.find(\"#\");\n\tbool seenDot = false;\n\n\tsize_t i = 0;\n\tsize_t length = number.length();\n\n\tif (length == 0)\n\t\treturn false; // Just in case\n\n\t// Decimal number\n\tif (hashPos == std::string::npos) {\n\t\tbool canBeSpecial = false;\n\n\t\tfor (; i < length; i++) {\n\t\t\tif (number[i] == '_') {\n\t\t\t\tif (!canBeSpecial) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcanBeSpecial = false;\n\t\t\t} else if (number[i] == '.') {\n\t\t\t\tif (!canBeSpecial || seenDot) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcanBeSpecial = false;\n\t\t\t\tseenDot = true;\n\t\t\t} else if (IsADigit(number[i])) {\n\t\t\t\tcanBeSpecial = true;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!canBeSpecial)\n\t\t\treturn false;\n\t} else {\n\t\t// Based number\n\t\tbool canBeSpecial = false;\n\t\tint base = 0;\n\n\t\t// Parse base\n\t\tfor (; i < length; i++) {\n\t\t\tint ch = number[i];\n\t\t\tif (ch == '_') {\n\t\t\t\tif (!canBeSpecial)\n\t\t\t\t\treturn false;\n\t\t\t\tcanBeSpecial = false;\n\t\t\t} else if (IsADigit(ch)) {\n\t\t\t\tbase = base * 10 + (ch - '0');\n\t\t\t\tif (base > 16)\n\t\t\t\t\treturn false;\n\t\t\t\tcanBeSpecial = true;\n\t\t\t} else if (ch == '#' && canBeSpecial) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif (base < 2)\n\t\t\treturn false;\n\t\tif (i == length)\n\t\t\treturn false;\n\n\t\ti++; // Skip over '#'\n\n\t\t// Parse number\n\t\tcanBeSpecial = false;\n\n\t\tfor (; i < length; i++) {\n\t\t\tint ch = tolower(number[i]);\n\n\t\t\tif (ch == '_') {\n\t\t\t\tif (!canBeSpecial) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcanBeSpecial = false;\n\n\t\t\t} else if (ch == '.') {\n\t\t\t\tif (!canBeSpecial || seenDot) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcanBeSpecial = false;\n\t\t\t\tseenDot = true;\n\n\t\t\t} else if (IsADigit(ch)) {\n\t\t\t\tif (ch - '0' >= base) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcanBeSpecial = true;\n\n\t\t\t} else if (ch >= 'a' && ch <= 'f') {\n\t\t\t\tif (ch - 'a' + 10 >= base) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcanBeSpecial = true;\n\n\t\t\t} else if (ch == '#' && canBeSpecial) {\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif (i == length) {\n\t\t\treturn false;\n\t\t}\n\n\t\ti++;\n\t}\n\n\t// Exponent (optional)\n\tif (i < length) {\n\t\tif (number[i] != 'e' && number[i] != 'E')\n\t\t\treturn false;\n\n\t\ti++; // Move past 'E'\n\n\t\tif (i == length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (number[i] == '+')\n\t\t\ti++;\n\t\telse if (number[i] == '-') {\n\t\t\tif (seenDot) {\n\t\t\t\ti++;\n\t\t\t} else {\n\t\t\t\treturn false; // Integer literals should not have negative exponents\n\t\t\t}\n\t\t}\n\n\t\tif (i == length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tbool canBeSpecial = false;\n\n\t\tfor (; i < length; i++) {\n\t\t\tif (number[i] == '_') {\n\t\t\t\tif (!canBeSpecial) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcanBeSpecial = false;\n\t\t\t} else if (IsADigit(number[i])) {\n\t\t\t\tcanBeSpecial = true;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif (!canBeSpecial)\n\t\t\treturn false;\n\t}\n\n\t// if i == length, number was parsed successfully.\n\treturn i == length;\n}\n\nstatic inline bool IsWordCharacter(int ch) {\n\treturn IsWordStartCharacter(ch) || IsADigit(ch);\n}\n\nstatic inline bool IsWordStartCharacter(int ch) {\n\treturn (IsASCII(ch) && isalpha(ch)) || ch == '_';\n}\n"
  },
  {
    "path": "lexers/LexAsciidoc.cxx",
    "content": "/******************************************************************\n *  LexAsciidoc.cxx\n *\n *  A simple Asciidoc lexer for scintilla.\n *\n *  Based on the LexMarkdown.cxx by Jon Strait - jstrait@moonloop.net\n *\n *  The License.txt file describes the conditions under which this\n *  software may be distributed.\n *\n *****************************************************************/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\ntypedef struct {\n    bool start;\n    int len1;\n    int len2;\n    const char *name;\n} MacroItem;\n\nstatic const MacroItem MacroList[] = {\n    // Directives\n    {true,  5, 2, \"ifdef::\"},\n    {true,  6, 2, \"ifeval::\"},\n    {true,  6, 2, \"ifndef::\"},\n    {true,  5, 2, \"endif::\"},\n    // Macros\n    {true,  5, 2, \"audio::\"},\n    {true,  7, 2, \"include::\"},\n    {true,  5, 2, \"image::\"},\n    {true,  5, 2, \"video::\"},\n    {false, 8, 1, \"asciimath:\"},\n    {false, 3, 1, \"btn:\"},\n    {false, 5, 1, \"image:\"},\n    {false, 3, 1, \"kbd:\"},\n    {false, 9, 1, \"latexmath:\"},\n    {false, 4, 1, \"link:\"},\n    {false, 6, 1, \"mailto:\"},\n    {false, 4, 1, \"menu:\"},\n    {false, 4, 1, \"pass:\"},\n    {false, 4, 1, \"stem:\"},\n    {false, 4, 1, \"xref:\"},\n    // Admonitions\n    {true,  7, 1, \"CAUTION:\"},\n    {true,  9, 1, \"IMPORTANT:\"},\n    {true,  4, 1, \"NOTE:\"},\n    {true,  3, 1, \"TIP:\"},\n    {true,  7, 1, \"WARNING:\"},\n    {false, 0, 0, NULL}\n};\n\nconstexpr bool IsNewline(const int ch) {\n    // sc.GetRelative(i) returns '\\0' if out of range\n    return (ch == '\\n' || ch == '\\r' || ch == '\\0');\n}\n\n}\n\nstatic bool AtTermStart(StyleContext &sc) {\n    return sc.currentPos == 0 || sc.chPrev == 0 || isspacechar(sc.chPrev);\n}\n\nstatic void ColorizeAsciidocDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                                WordList **, Accessor &styler) {\n    bool freezeCursor = false;\n\n    StyleContext sc(startPos, static_cast<Sci_PositionU>(length), initStyle, styler);\n\n    while (sc.More()) {\n        // Skip past escaped characters\n        if (sc.ch == '\\\\') {\n            sc.Forward();\n            continue;\n        }\n\n        // Skip newline.\n        if (IsNewline(sc.ch)) {\n            // Newline doesn't end blocks\n            if (sc.state != SCE_ASCIIDOC_CODEBK && \\\n                sc.state != SCE_ASCIIDOC_PASSBK && \\\n                sc.state != SCE_ASCIIDOC_COMMENTBK && \\\n                sc.state != SCE_ASCIIDOC_LITERALBK) {\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            sc.Forward();\n            continue;\n        }\n\n        // Conditional state-based actions\n        switch (sc.state) {\n\n        // Strong\n        case SCE_ASCIIDOC_STRONG1:\n            if (sc.ch == '*' && sc.chPrev != ' ') {\n                sc.Forward();\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n                freezeCursor = true;\n            }\n            break;\n        case SCE_ASCIIDOC_STRONG2:\n            if (sc.Match(\"**\") && sc.chPrev != ' ') {\n                sc.Forward(2);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n                freezeCursor = true;\n            }\n            break;\n\n        // Emphasis\n        case SCE_ASCIIDOC_EM1:\n            if (sc.ch == '_' && sc.chPrev != ' ') {\n                sc.Forward();\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n                freezeCursor = true;\n            }\n            break;\n        case SCE_ASCIIDOC_EM2:\n            if (sc.Match(\"__\") && sc.chPrev != ' ') {\n                sc.Forward(2);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n                freezeCursor = true;\n            }\n            break;\n\n        // Link\n        case SCE_ASCIIDOC_LINK:\n            if (sc.ch == ']' && sc.chPrev != '\\\\') {\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            break;\n\n        // Code block\n        case SCE_ASCIIDOC_CODEBK:\n            if (sc.atLineStart && sc.Match(\"----\") && IsNewline(sc.GetRelative(4))) {\n                sc.Forward(4);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            break;\n\n        // Passthrough block\n        case SCE_ASCIIDOC_PASSBK:\n            if (sc.atLineStart && sc.Match(\"++++\") && IsNewline(sc.GetRelative(4))) {\n                sc.Forward(4);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            break;\n\n        // Comment block\n        case SCE_ASCIIDOC_COMMENTBK:\n            if (sc.atLineStart && sc.Match(\"////\") && IsNewline(sc.GetRelative(4))) {\n                sc.Forward(4);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            break;\n\n        // Literal\n        case SCE_ASCIIDOC_LITERAL:\n            if (sc.ch == '+' && sc.chPrev != '\\\\') {\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            break;\n\n        // Literal block\n        case SCE_ASCIIDOC_LITERALBK:\n            if (sc.atLineStart && sc.Match(\"....\") && IsNewline(sc.GetRelative(4))) {\n                sc.Forward(4);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            break;\n\n        // Attribute\n        case SCE_ASCIIDOC_ATTRIB:\n            if (sc.ch == ':' && sc.chPrev != ' ' && sc.chNext == ' ') {\n                sc.Forward();\n                sc.SetState(SCE_ASCIIDOC_ATTRIBVAL);\n            }\n            break;\n\n        // Macro\n        case SCE_ASCIIDOC_MACRO:\n            if (sc.ch == ']' && sc.chPrev != '\\\\') {\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            break;\n\n        // Default\n        case SCE_ASCIIDOC_DEFAULT:\n            // Headers\n            if (sc.atLineStart && sc.Match(\"====== \")) {\n                sc.SetState(SCE_ASCIIDOC_HEADER6);\n                sc.Forward(6);\n            }\n            else if (sc.atLineStart && sc.Match(\"===== \")) {\n                sc.SetState(SCE_ASCIIDOC_HEADER5);\n                sc.Forward(5);\n            }\n            else if (sc.atLineStart && sc.Match(\"==== \")) {\n                sc.SetState(SCE_ASCIIDOC_HEADER4);\n                sc.Forward(4);\n            }\n            else if (sc.atLineStart && sc.Match(\"=== \")) {\n                sc.SetState(SCE_ASCIIDOC_HEADER3);\n                sc.Forward(3);\n            }\n            else if (sc.atLineStart && sc.Match(\"== \")) {\n                sc.SetState(SCE_ASCIIDOC_HEADER2);\n                sc.Forward(2);\n            }\n            else if (sc.atLineStart && sc.Match(\"= \")) {\n                sc.SetState(SCE_ASCIIDOC_HEADER1);\n                sc.Forward(1);\n            }\n            // Unordered list item\n            else if (sc.atLineStart && sc.Match(\"****** \")) {\n                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);\n                sc.Forward(6);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\"***** \")) {\n                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);\n                sc.Forward(5);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\"**** \")) {\n                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);\n                sc.Forward(4);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\"*** \")) {\n                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);\n                sc.Forward(3);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\"** \")) {\n                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);\n                sc.Forward(2);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\"* \")) {\n                sc.SetState(SCE_ASCIIDOC_ULIST_ITEM);\n                sc.Forward(1);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            // Ordered list item\n            else if (sc.atLineStart && sc.Match(\"...... \")) {\n                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);\n                sc.Forward(6);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\"..... \")) {\n                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);\n                sc.Forward(5);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\".... \")) {\n                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);\n                sc.Forward(4);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\"... \")) {\n                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);\n                sc.Forward(3);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\".. \")) {\n                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);\n                sc.Forward(2);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            else if (sc.atLineStart && sc.Match(\". \")) {\n                sc.SetState(SCE_ASCIIDOC_OLIST_ITEM);\n                sc.Forward(1);\n                sc.SetState(SCE_ASCIIDOC_DEFAULT);\n            }\n            // Blockquote\n            else if (sc.atLineStart && sc.Match(\"> \")) {\n                sc.SetState(SCE_ASCIIDOC_BLOCKQUOTE);\n                sc.Forward();\n            }\n            // Link\n            else if (!sc.atLineStart && sc.ch == '[' && sc.chPrev != '\\\\' && sc.chNext != ' ') {\n                sc.Forward();\n                sc.SetState(SCE_ASCIIDOC_LINK);\n                freezeCursor = true;\n            }\n            // Code block\n            else if (sc.atLineStart && sc.Match(\"----\") && IsNewline(sc.GetRelative(4))) {\n                sc.SetState(SCE_ASCIIDOC_CODEBK);\n                sc.Forward(4);\n            }\n            // Passthrough block\n            else if (sc.atLineStart && sc.Match(\"++++\") && IsNewline(sc.GetRelative(4))) {\n                sc.SetState(SCE_ASCIIDOC_PASSBK);\n                sc.Forward(4);\n            }\n            // Comment block\n            else if (sc.atLineStart && sc.Match(\"////\") && IsNewline(sc.GetRelative(4))) {\n                sc.SetState(SCE_ASCIIDOC_COMMENTBK);\n                sc.Forward(4);\n            }\n            // Comment\n            else if (sc.atLineStart && sc.Match(\"//\")) {\n                sc.SetState(SCE_ASCIIDOC_COMMENT);\n                sc.Forward();\n            }\n            // Literal\n            else if (sc.ch == '+' && sc.chPrev != '\\\\' && sc.chNext != ' ' && AtTermStart(sc)) {\n                sc.Forward();\n                sc.SetState(SCE_ASCIIDOC_LITERAL);\n                freezeCursor = true;\n            }\n            // Literal block\n            else if (sc.atLineStart && sc.Match(\"....\") && IsNewline(sc.GetRelative(4))) {\n                sc.SetState(SCE_ASCIIDOC_LITERALBK);\n                sc.Forward(4);\n            }\n            // Attribute\n            else if (sc.atLineStart && sc.ch == ':' && sc.chNext != ' ') {\n                sc.SetState(SCE_ASCIIDOC_ATTRIB);\n            }\n            // Strong\n            else if (sc.Match(\"**\") && sc.GetRelative(2) != ' ') {\n                sc.SetState(SCE_ASCIIDOC_STRONG2);\n                sc.Forward();\n            }\n            else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) {\n                sc.SetState(SCE_ASCIIDOC_STRONG1);\n            }\n            // Emphasis\n            else if (sc.Match(\"__\") && sc.GetRelative(2) != ' ') {\n                sc.SetState(SCE_ASCIIDOC_EM2);\n                sc.Forward();\n            }\n            else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) {\n                sc.SetState(SCE_ASCIIDOC_EM1);\n            }\n            // Macro\n            else if (sc.atLineStart && sc.ch == '[' && sc.chNext != ' ') {\n                sc.Forward();\n                sc.SetState(SCE_ASCIIDOC_MACRO);\n                freezeCursor = true;\n            }\n            else {\n                int i = 0;\n                bool found = false;\n                while (!found && MacroList[i].name != NULL) {\n                    if (MacroList[i].start)\n                        found = sc.atLineStart && sc.Match(MacroList[i].name);\n                    else\n                        found = sc.Match(MacroList[i].name);\n                    if (found) {\n                        sc.SetState(SCE_ASCIIDOC_MACRO);\n                        sc.Forward(MacroList[i].len1);\n                        sc.SetState(SCE_ASCIIDOC_DEFAULT);\n                        if (MacroList[i].len2 > 1)\n                            sc.Forward(MacroList[i].len2 - 1);\n                    }\n                    i++;\n                }\n            }\n            break;\n        }\n        // Advance if not holding back the cursor for this iteration.\n        if (!freezeCursor)\n            sc.Forward();\n        freezeCursor = false;\n    }\n    sc.Complete();\n}\n\nextern const LexerModule lmAsciidoc(SCLEX_ASCIIDOC, ColorizeAsciidocDoc, \"asciidoc\");\n"
  },
  {
    "path": "lexers/LexAsm.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexAsm.cxx\n ** Lexer for Assembler, just for the MASM syntax\n ** Written by The Black Horus\n ** Enhancements and NASM stuff by Kein-Hong Man, 2003-10\n ** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring\n ** Converted to lexer object and added further folding features/properties by \"Udo Lechner\" <dlchnr(at)gmx(dot)net>\n **/\n// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <set>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\nbool IsAWordChar(const int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == '?';\n}\n\nbool IsAWordStart(const int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '_' || ch == '.' ||\n\t\tch == '%' || ch == '@' || ch == '$' || ch == '?';\n}\n\nbool IsAsmOperator(const int ch) noexcept {\n\tif (IsAlphaNumeric(ch))\n\t\treturn false;\n\t// '.' left out as it is used to make up numbers\n\treturn AnyOf(ch, '*', '/', '-', '+', '(', ')', '=', '^', '[', ']', '<', '&', '>', ',', '|', '~', '%', ':');\n}\n\nconstexpr bool IsStreamCommentStyle(int style) noexcept {\n\treturn style == SCE_ASM_COMMENTDIRECTIVE || style == SCE_ASM_COMMENTBLOCK;\n}\n\n// An individual named option for use in an OptionSet\n\n// Options used for LexerAsm\nstruct OptionsAsm {\n\tstd::string delimiter;\n\tbool fold = false;\n\tbool foldSyntaxBased = true;\n\tbool foldCommentMultiline = false;\n\tbool foldCommentExplicit = false;\n\tstd::string foldExplicitStart;\n\tstd::string foldExplicitEnd;\n\tbool foldExplicitAnywhere = false;\n\tbool foldCompact = true;\n\tstd::string commentChar;\n\t[[nodiscard]] char Delimiter() const noexcept {\n\t\treturn delimiter.empty() ? '~' : delimiter[0];\n\t}\n};\n\nconst char *const asmWordListDesc[] = {\n\t\"CPU instructions\",\n\t\"FPU instructions\",\n\t\"Registers\",\n\t\"Directives\",\n\t\"Directive operands\",\n\t\"Extended instructions\",\n\t\"Directives4Foldstart\",\n\t\"Directives4Foldend\",\n\tnullptr\n};\n\nstruct OptionSetAsm : public OptionSet<OptionsAsm> {\n\tOptionSetAsm() {\n\t\tDefineProperty(\"lexer.asm.comment.delimiter\", &OptionsAsm::delimiter,\n\t\t\t\"Character used for COMMENT directive's delimiter, replacing the standard \\\"~\\\".\");\n\n\t\tDefineProperty(\"fold\", &OptionsAsm::fold);\n\n\t\tDefineProperty(\"fold.asm.syntax.based\", &OptionsAsm::foldSyntaxBased,\n\t\t\t\"Set this property to 0 to disable syntax based folding.\");\n\n\t\tDefineProperty(\"fold.asm.comment.multiline\", &OptionsAsm::foldCommentMultiline,\n\t\t\t\"Set this property to 1 to enable folding multi-line comments.\");\n\n\t\tDefineProperty(\"fold.asm.comment.explicit\", &OptionsAsm::foldCommentExplicit,\n\t\t\t\"This option enables folding explicit fold points when using the Asm lexer. \"\n\t\t\t\"Explicit fold points allows adding extra folding by placing a ;{ comment at the start and a ;} \"\n\t\t\t\"at the end of a section that should fold.\");\n\n\t\tDefineProperty(\"fold.asm.explicit.start\", &OptionsAsm::foldExplicitStart,\n\t\t\t\"The string to use for explicit fold start points, replacing the standard ;{.\");\n\n\t\tDefineProperty(\"fold.asm.explicit.end\", &OptionsAsm::foldExplicitEnd,\n\t\t\t\"The string to use for explicit fold end points, replacing the standard ;}.\");\n\n\t\tDefineProperty(\"fold.asm.explicit.anywhere\", &OptionsAsm::foldExplicitAnywhere,\n\t\t\t\"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\");\n\n\t\tDefineProperty(\"fold.compact\", &OptionsAsm::foldCompact);\n\n\t\tDefineProperty(\"lexer.as.comment.character\", &OptionsAsm::commentChar,\n\t\t\t\"Overrides the default comment character (which is ';' for asm and '#' for as).\");\n\n\t\tDefineWordListSets(asmWordListDesc);\n\t}\n};\n\nconst LexicalClass lexicalClassesAsm[] = {\n\t// Lexer Assembler SCLEX_ASM SCE_ASM_:\n\t0, \"SCE_ASM_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_ASM_COMMENT\", \"comment line\", \"Comment\",\n\t2, \"SCE_ASM_NUMBER\", \"literal numeric\", \"Number\",\n\t3, \"SCE_ASM_STRING\", \"literal string\", \"String\",\n\t4, \"SCE_ASM_OPERATOR\", \"operator\", \"Operator\",\n\t5, \"SCE_ASM_IDENTIFIER\", \"identifier\", \"Identifier\",\n\t6, \"SCE_ASM_CPUINSTRUCTION\", \"keyword\", \"CPU Instruction\",\n\t7, \"SCE_ASM_MATHINSTRUCTION\", \"keyword\", \"FPU Instruction\",\n\t8, \"SCE_ASM_REGISTER\", \"keyword identifier\", \"Register\",\n\t9, \"SCE_ASM_DIRECTIVE\", \"keyword\", \"Directive\",\n\t10, \"SCE_ASM_DIRECTIVEOPERAND\", \"keyword\", \"Directive Operand\",\n\t11, \"SCE_ASM_COMMENTBLOCK\", \"comment\", \"Comment block\",\n\t12, \"SCE_ASM_CHARACTER\", \"literal string\", \"Single quoted string\",\n\t13, \"SCE_ASM_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n\t14, \"SCE_ASM_EXTINSTRUCTION\", \"keyword\", \"Extended Instruction\",\n\t15, \"SCE_ASM_COMMENTDIRECTIVE\", \"comment\", \"Directive Comment\",\n\t16, \"SCE_ASM_STRINGBACKQUOTE\", \"literal string\", \"Back quoted string\",\n};\n\nconst LexicalClass lexicalClassesAs[] = {\n\t// Lexer.Secondary As SCLEX_AS SCE_ASM_:\n\t0, \"SCE_ASM_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_ASM_COMMENT\", \"comment line\", \"Comment\",\n\t2, \"SCE_ASM_NUMBER\", \"literal numeric\", \"Number\",\n\t3, \"SCE_ASM_STRING\", \"literal string\", \"String\",\n\t4, \"SCE_ASM_OPERATOR\", \"operator\", \"Operator\",\n\t5, \"SCE_ASM_IDENTIFIER\", \"identifier\", \"Identifier\",\n\t6, \"SCE_ASM_CPUINSTRUCTION\", \"keyword\", \"CPU Instruction\",\n\t7, \"SCE_ASM_MATHINSTRUCTION\", \"keyword\", \"FPU Instruction\",\n\t8, \"SCE_ASM_REGISTER\", \"keyword identifier\", \"Register\",\n\t9, \"SCE_ASM_DIRECTIVE\", \"keyword\", \"Directive\",\n\t10, \"SCE_ASM_DIRECTIVEOPERAND\", \"keyword\", \"Directive Operand\",\n\t11, \"SCE_ASM_COMMENTBLOCK\", \"comment\", \"Comment block\",\n\t12, \"SCE_ASM_CHARACTER\", \"literal string\", \"Single quoted string\",\n\t13, \"SCE_ASM_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n\t14, \"SCE_ASM_EXTINSTRUCTION\", \"keyword\", \"Extended Instruction\",\n\t15, \"SCE_ASM_COMMENTDIRECTIVE\", \"comment\", \"Directive Comment\",\n\t16, \"SCE_ASM_STRINGBACKQUOTE\", \"literal string\", \"Back quoted string\",\n};\n\nclass LexerAsm : public DefaultLexer {\n\tWordList cpuInstruction;\n\tWordList mathInstruction;\n\tWordList registers;\n\tWordList directive;\n\tWordList directiveOperand;\n\tWordList extInstruction;\n\tWordList directives4foldstart;\n\tWordList directives4foldend;\n\tOptionsAsm options;\n\tOptionSetAsm osAsm;\n\tchar commentChar;\npublic:\n\tLexerAsm(const char *languageName_, int language_, char commentChar_) :\n\t\tDefaultLexer(languageName_, language_,\n\t\t(language_ == SCLEX_ASM) ? lexicalClassesAsm : lexicalClassesAs,\n\t\t(language_ == SCLEX_ASM) ? std::size(lexicalClassesAsm) : std::size(lexicalClassesAs)),\n\t\tcommentChar(commentChar_) {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osAsm.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osAsm.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osAsm.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osAsm.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osAsm.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn nullptr;\n\t}\n\n\tstatic ILexer5 *LexerFactoryAsm() {\n\t\treturn new LexerAsm(\"asm\", SCLEX_ASM, ';');\n\t}\n\n\tstatic ILexer5 *LexerFactoryAs() {\n\t\treturn new LexerAsm(\"as\", SCLEX_AS, '#');\n\t}\n};\n\nSci_Position SCI_METHOD LexerAsm::PropertySet(const char *key, const char *val) {\n\tif (osAsm.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &cpuInstruction;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &mathInstruction;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &registers;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &directive;\n\t\tbreak;\n\tcase 4:\n\t\twordListN = &directiveOperand;\n\t\tbreak;\n\tcase 5:\n\t\twordListN = &extInstruction;\n\t\tbreak;\n\tcase 6:\n\t\twordListN = &directives4foldstart;\n\t\tbreak;\n\tcase 7:\n\t\twordListN = &directives4foldend;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl, true)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\n\tconst char commentCharacter = options.commentChar.empty() ?\n\t\tcommentChar : options.commentChar.front();\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_ASM_STRINGEOL)\n\t\tinitStyle = SCE_ASM_DEFAULT;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.atLineStart) {\n\t\t\tswitch (sc.state) {\n\t\t\tcase SCE_ASM_STRING:\n\t\t\tcase SCE_ASM_CHARACTER:\n\t\t\tcase SCE_ASM_STRINGBACKQUOTE:\n\t\t\t\t// Prevent SCE_ASM_STRINGEOL from leaking back to previous line\n\t\t\t\tsc.SetState(sc.state);\n\t\t\t\tbreak;\n\t\t\tcase SCE_ASM_COMMENT:\n\t\t\t\tsc.SetState(SCE_ASM_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Handle line continuation generically.\n\t\tif (sc.ch == '\\\\') {\n\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\tcase SCE_ASM_OPERATOR:\n\t\t\tif (!IsAsmOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_ASM_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ASM_NUMBER:\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_ASM_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ASM_IDENTIFIER:\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tbool IsDirective = false;\n\n\t\t\t\tif (cpuInstruction.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_ASM_CPUINSTRUCTION);\n\t\t\t\t} else if (mathInstruction.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_ASM_MATHINSTRUCTION);\n\t\t\t\t} else if (registers.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_ASM_REGISTER);\n\t\t\t\t}  else if (directive.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_ASM_DIRECTIVE);\n\t\t\t\t\tIsDirective = true;\n\t\t\t\t} else if (directiveOperand.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);\n\t\t\t\t} else if (extInstruction.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_ASM_EXTINSTRUCTION);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_ASM_DEFAULT);\n\t\t\t\tif (IsDirective && !strcmp(s, \"comment\")) {\n\t\t\t\t\twhile (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_ASM_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t\tif (sc.ch == options.Delimiter()) {\n\t\t\t\t\t\tsc.SetState(SCE_ASM_COMMENTDIRECTIVE);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ASM_COMMENTDIRECTIVE:\n\t\t\tif (sc.ch == options.Delimiter()) {\n\t\t\t\twhile (!sc.MatchLineEnd()) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_ASM_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ASM_STRING:\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_ASM_DEFAULT);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_ASM_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_ASM_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ASM_CHARACTER:\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.ForwardSetState(SCE_ASM_DEFAULT);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_ASM_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_ASM_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ASM_STRINGBACKQUOTE:\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\' || sc.chNext == '`') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '`') {\n\t\t\t\tsc.ForwardSetState(SCE_ASM_DEFAULT);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_ASM_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_ASM_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_ASM_DEFAULT) {\n\t\t\tif (sc.ch == commentCharacter) {\n\t\t\t\tsc.SetState(SCE_ASM_COMMENT);\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_ASM_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_ASM_IDENTIFIER);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_ASM_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_ASM_CHARACTER);\n\t\t\t} else if (sc.ch == '`') {\n\t\t\t\tsc.SetState(SCE_ASM_STRINGBACKQUOTE);\n\t\t\t} else if (IsAsmOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_ASM_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t}\n\tsc.Complete();\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"else\".\n\nvoid SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, IDocument *pAccess) {\n\n\tif (!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\n\tconst Sci_Position startPos = static_cast<Sci_Position>(startPos_);\n\tconst Sci_Position endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = FoldLevelStart(styler.LevelAt(lineCurrent-1));\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleIndexAt(startPos);\n\tint style = initStyle;\n\tstd::string word;\n\tconst bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();\n\tfor (Sci_Position i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleIndexAt(i + 1);\n\t\tconst bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (options.foldCommentMultiline && IsStreamCommentStyle(style)) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (options.foldCommentExplicit && ((style == SCE_ASM_COMMENT) || options.foldExplicitAnywhere)) {\n\t\t\tif (userDefinedFoldMarkers) {\n\t\t\t\tif (styler.Match(i, options.foldExplicitStart.c_str())) {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (ch == ';') {\n\t\t\t\t\tif (chNext == '{') {\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t} else if (chNext == '}') {\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) {\n\t\t\tword.push_back(MakeLowerCase(ch));\n\t\t\tif (styleNext != SCE_ASM_DIRECTIVE) {   // reading directive ready\n\t\t\t\tif (directives4foldstart.InList(word)) {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (directives4foldend.InList(word)) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t\tword.clear();\n\t\t\t}\n\t\t}\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\t\tif (atEOL || (i == endPos-1)) {\n\t\t\tconst int lev = FoldLevelForCurrentNext(levelCurrent, levelNext) |\n\t\t\t\tFoldLevelFlags(levelCurrent, levelNext, visibleChars == 0 && options.foldCompact);\n\t\t\tstyler.SetLevelIfDifferent(lineCurrent, lev);\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tif (atEOL && (i == (styler.Length() - 1))) {\n\t\t\t\t// There is an empty line at end of file so give it same level and empty\n\t\t\t\tstyler.SetLevel(lineCurrent, FoldLevelForCurrent(levelCurrent) | SC_FOLDLEVELWHITEFLAG);\n\t\t\t}\n\t\t\tvisibleChars = 0;\n\t\t}\n\t}\n}\n\n}\n\nextern const LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, \"asm\", asmWordListDesc);\nextern const LexerModule lmAs(SCLEX_AS, LexerAsm::LexerFactoryAs, \"as\", asmWordListDesc);\n\n"
  },
  {
    "path": "lexers/LexAsn1.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexAsn1.cxx\n ** Lexer for ASN.1\n **/\n// Copyright 2004 by Herr Pfarrer rpfarrer <at> yahoo <dot> de\n// Last Updated: 20/07/2004\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// Some char test functions\nstatic bool isAsn1Number(int ch)\n{\n\treturn (ch >= '0' && ch <= '9');\n}\n\nstatic bool isAsn1Letter(int ch)\n{\n\treturn (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');\n}\n\nstatic bool isAsn1Char(int ch)\n{\n\treturn (ch == '-' ) || isAsn1Number(ch) || isAsn1Letter (ch);\n}\n\n//\n//\tFunction determining the color of a given code portion\n//\tBased on a \"state\"\n//\nstatic void ColouriseAsn1Doc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordLists[], Accessor &styler)\n{\n\t// The keywords\n\tWordList &Keywords = *keywordLists[0];\n\tWordList &Attributes = *keywordLists[1];\n\tWordList &Descriptors = *keywordLists[2];\n\tWordList &Types = *keywordLists[3];\n\n\t// Parse the whole buffer character by character using StyleContext\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tfor (; sc.More(); sc.Forward())\n\t{\n\t\t// The state engine\n\t\tswitch (sc.state)\n\t\t{\n\t\tcase SCE_ASN1_DEFAULT:\t\t// Plain characters\nasn1_default:\n\t\t\tif (sc.ch == '-' && sc.chNext == '-')\n\t\t\t\t// A comment begins here\n\t\t\t\tsc.SetState(SCE_ASN1_COMMENT);\n\t\t\telse if (sc.ch == '\"')\n\t\t\t\t// A string begins here\n\t\t\t\tsc.SetState(SCE_ASN1_STRING);\n\t\t\telse if (isAsn1Number (sc.ch))\n\t\t\t\t// A number starts here (identifier should start with a letter in ASN.1)\n\t\t\t\tsc.SetState(SCE_ASN1_SCALAR);\n\t\t\telse if (isAsn1Char (sc.ch))\n\t\t\t\t// An identifier starts here (identifier always start with a letter)\n\t\t\t\tsc.SetState(SCE_ASN1_IDENTIFIER);\n\t\t\telse if (sc.ch == ':')\n\t\t\t\t// A ::= operator starts here\n\t\t\t\tsc.SetState(SCE_ASN1_OPERATOR);\n\t\t\tbreak;\n\t\tcase SCE_ASN1_COMMENT:\t\t// A comment\n\t\t\tif (sc.ch == '\\r' || sc.ch == '\\n')\n\t\t\t\t// A comment ends here\n\t\t\t\tsc.SetState(SCE_ASN1_DEFAULT);\n\t\t\tbreak;\n\t\tcase SCE_ASN1_IDENTIFIER:\t// An identifier (keyword, attribute, descriptor or type)\n\t\t\tif (!isAsn1Char (sc.ch))\n\t\t\t{\n\t\t\t\t// The end of identifier is here: we can look for it in lists by now and change its state\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\tif (Keywords.InList(s))\n\t\t\t\t\t// It's a keyword, change its state\n\t\t\t\t\tsc.ChangeState(SCE_ASN1_KEYWORD);\n\t\t\t\telse if (Attributes.InList(s))\n\t\t\t\t\t// It's an attribute, change its state\n\t\t\t\t\tsc.ChangeState(SCE_ASN1_ATTRIBUTE);\n\t\t\t\telse if (Descriptors.InList(s))\n\t\t\t\t\t// It's a descriptor, change its state\n\t\t\t\t\tsc.ChangeState(SCE_ASN1_DESCRIPTOR);\n\t\t\t\telse if (Types.InList(s))\n\t\t\t\t\t// It's a type, change its state\n\t\t\t\t\tsc.ChangeState(SCE_ASN1_TYPE);\n\n\t\t\t\t// Set to default now\n\t\t\t\tsc.SetState(SCE_ASN1_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_ASN1_STRING:\t\t// A string delimited by \"\"\n\t\t\tif (sc.ch == '\"')\n\t\t\t{\n\t\t\t\t// A string ends here\n\t\t\t\tsc.ForwardSetState(SCE_ASN1_DEFAULT);\n\n\t\t\t\t// To correctly manage a char sticking to the string quote\n\t\t\t\tgoto asn1_default;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_ASN1_SCALAR:\t\t// A plain number\n\t\t\tif (!isAsn1Number (sc.ch))\n\t\t\t\t// A number ends here\n\t\t\t\tsc.SetState(SCE_ASN1_DEFAULT);\n\t\t\tbreak;\n\t\tcase SCE_ASN1_OPERATOR:\t\t// The affectation operator ::= and wath follows (eg: ::= { org 6 } OID or ::= 12 trap)\n\t\t\tif (sc.ch == '{')\n\t\t\t{\n\t\t\t\t// An OID definition starts here: enter the sub loop\n\t\t\t\tfor (; sc.More(); sc.Forward())\n\t\t\t\t{\n\t\t\t\t\tif (isAsn1Number (sc.ch) && (!isAsn1Char (sc.chPrev) || isAsn1Number (sc.chPrev)))\n\t\t\t\t\t\t// The OID number is highlighted\n\t\t\t\t\t\tsc.SetState(SCE_ASN1_OID);\n\t\t\t\t\telse if (isAsn1Char (sc.ch))\n\t\t\t\t\t\t// The OID parent identifier is plain\n\t\t\t\t\t\tsc.SetState(SCE_ASN1_IDENTIFIER);\n\t\t\t\t\telse\n\t\t\t\t\t\tsc.SetState(SCE_ASN1_DEFAULT);\n\n\t\t\t\t\tif (sc.ch == '}')\n\t\t\t\t\t\t// Here ends the OID and the operator sub loop: go back to main loop\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isAsn1Number (sc.ch))\n\t\t\t{\n\t\t\t\t// A trap number definition starts here: enter the sub loop\n\t\t\t\tfor (; sc.More(); sc.Forward())\n\t\t\t\t{\n\t\t\t\t\tif (isAsn1Number (sc.ch))\n\t\t\t\t\t\t// The trap number is highlighted\n\t\t\t\t\t\tsc.SetState(SCE_ASN1_OID);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// The number ends here: go back to main loop\n\t\t\t\t\t\tsc.SetState(SCE_ASN1_DEFAULT);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (sc.ch != ':' && sc.ch != '=' && sc.ch != ' ')\n\t\t\t\t// The operator doesn't imply an OID definition nor a trap, back to main loop\n\t\t\t\tgoto asn1_default; // To be sure to handle actually the state change\n\t\t\tbreak;\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void FoldAsn1Doc(Sci_PositionU, Sci_Position, int, WordList *[], Accessor &styler)\n{\n\t// No folding enabled, no reason to continue...\n\tif( styler.GetPropertyInt(\"fold\") == 0 )\n\t\treturn;\n\n\t// No folding implemented: doesn't make sense for ASN.1\n}\n\nstatic const char * const asn1WordLists[] = {\n\t\"Keywords\",\n\t\"Attributes\",\n\t\"Descriptors\",\n\t\"Types\",\n\t0, };\n\n\nextern const LexerModule lmAsn1(SCLEX_ASN1, ColouriseAsn1Doc, \"asn1\", FoldAsn1Doc, asn1WordLists);\n"
  },
  {
    "path": "lexers/LexBaan.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexBaan.cxx\n** Lexer for Baan.\n** Based heavily on LexCPP.cxx\n**/\n// Copyright 2001- by Vamsi Potluru <vamsi@who.net> & Praveen Ambekar <ambekarpraveen@yahoo.com>\n// Maintainer Email: oirfeodent@yahoo.co.in\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// C standard library\n#include <stdlib.h>\n#include <string.h>\n\n// C++ wrappers of C standard library\n#include <cassert>\n\n// C++ standard library\n#include <string>\n#include <string_view>\n#include <map>\n#include <functional>\n\n// Scintilla headers\n\n// Non-platform-specific headers\n\n// include\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n// lexlib\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n// Use an unnamed namespace to protect the functions and classes from name conflicts\n\n// Options used for LexerBaan\nstruct OptionsBaan {\n\tbool fold;\n\tbool foldComment;\n\tbool foldPreprocessor;\n\tbool foldCompact;\n\tbool baanFoldSyntaxBased;\n\tbool baanFoldKeywordsBased;\n\tbool baanFoldSections;\n\tbool baanFoldInnerLevel;\n\tbool baanStylingWithinPreprocessor;\n\tOptionsBaan() {\n\t\tfold = false;\n\t\tfoldComment = false;\n\t\tfoldPreprocessor = false;\n\t\tfoldCompact = false;\n\t\tbaanFoldSyntaxBased = false;\n\t\tbaanFoldKeywordsBased = false;\n\t\tbaanFoldSections = false;\n\t\tbaanFoldInnerLevel = false;\n\t\tbaanStylingWithinPreprocessor = false;\n\t}\n};\n\nconst char *const baanWordLists[] = {\n\t\"Baan & BaanSQL Reserved Keywords \",\n\t\"Baan Standard functions\",\n\t\"Baan Functions Abridged\",\n\t\"Baan Main Sections \",\n\t\"Baan Sub Sections\",\n\t\"PreDefined Variables\",\n\t\"PreDefined Attributes\",\n\t\"Enumerates\",\n\t0,\n};\n\nstruct OptionSetBaan : public OptionSet<OptionsBaan> {\n\tOptionSetBaan() {\n\t\tDefineProperty(\"fold\", &OptionsBaan::fold);\n\n\t\tDefineProperty(\"fold.comment\", &OptionsBaan::foldComment);\n\n\t\tDefineProperty(\"fold.preprocessor\", &OptionsBaan::foldPreprocessor);\n\n\t\tDefineProperty(\"fold.compact\", &OptionsBaan::foldCompact);\n\n\t\tDefineProperty(\"fold.baan.syntax.based\", &OptionsBaan::baanFoldSyntaxBased,\n\t\t\t\"Set this property to 0 to disable syntax based folding, which is folding based on '{' & '('.\");\n\n\t\tDefineProperty(\"fold.baan.keywords.based\", &OptionsBaan::baanFoldKeywordsBased,\n\t\t\t\"Set this property to 0 to disable keywords based folding, which is folding based on \"\n\t\t\t\" for, if, on (case), repeat, select, while and fold ends based on endfor, endif, endcase, until, endselect, endwhile respectively.\"\n\t\t\t\"Also folds declarations which are grouped together.\");\n\n\t\tDefineProperty(\"fold.baan.sections\", &OptionsBaan::baanFoldSections,\n\t\t\t\"Set this property to 0 to disable folding of Main Sections as well as Sub Sections.\");\n\n\t\tDefineProperty(\"fold.baan.inner.level\", &OptionsBaan::baanFoldInnerLevel,\n\t\t\t\"Set this property to 1 to enable folding of inner levels of select statements.\"\n\t\t\t\"Disabled by default. case and if statements are also eligible\" );\n\n\t\tDefineProperty(\"lexer.baan.styling.within.preprocessor\", &OptionsBaan::baanStylingWithinPreprocessor,\n\t\t\t\"For Baan code, determines whether all preprocessor code is styled in the \"\n\t\t\t\"preprocessor style (0, the default) or only from the initial # to the end \"\n\t\t\t\"of the command word(1).\");\n\n\t\tDefineWordListSets(baanWordLists);\n\t}\n};\n\nstatic inline bool IsAWordChar(const int  ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$');\n}\n\nstatic inline bool IsAnOperator(int ch) {\n\tif (IsAlphaNumeric(ch))\n\t\treturn false;\n\tif (ch == '#' || ch == '^' || ch == '&' || ch == '*' ||\n\t\tch == '(' || ch == ')' || ch == '-' || ch == '+' ||\n\t\tch == '=' || ch == '|' || ch == '{' || ch == '}' ||\n\t\tch == '[' || ch == ']' || ch == ':' || ch == ';' ||\n\t\tch == '<' || ch == '>' || ch == ',' || ch == '/' ||\n\t\tch == '?' || ch == '!' || ch == '\"' || ch == '~' ||\n\t\tch == '\\\\')\n\t\treturn true;\n\treturn false;\n}\n\nstatic inline int IsAnyOtherIdentifier(char *s, Sci_Position sLength) {\n\n\t/*\tIsAnyOtherIdentifier uses standard templates used in baan.\n\tThe matching template is shown as comments just above the return condition.\n\t^ - refers to any character [a-z].\n\t# - refers to any number [0-9].\n\tOther characters shown are compared as is.\n\tTried implementing with Regex... it was too complicated for me.\n\tAny other implementation suggestion welcome.\n\t*/\n\tswitch (sLength) {\n\tcase 8:\n\t\tif (isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {\n\t\t\t//^^^^^###\n\t\t\treturn(SCE_BAAN_TABLEDEF);\n\t\t}\n\t\tbreak;\n\tcase 9:\n\t\tif (s[0] == 't' && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && isalpha(s[5]) && IsADigit(s[6]) && IsADigit(s[7]) && IsADigit(s[8])) {\n\t\t\t//t^^^^^###\n\t\t\treturn(SCE_BAAN_TABLEDEF);\n\t\t}\n\t\telse if (s[8] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {\n\t\t\t//^^^^^###.\n\t\t\treturn(SCE_BAAN_TABLESQL);\n\t\t}\n\t\tbreak;\n\tcase 13:\n\t\tif (s[8] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {\n\t\t\t//^^^^^###.****\n\t\t\treturn(SCE_BAAN_TABLESQL);\n\t\t}\n\t\telse if (s[0] == 'r' && s[1] == 'c' && s[2] == 'd' && s[3] == '.' && s[4] == 't' && isalpha(s[5]) && isalpha(s[6]) && isalpha(s[7]) && isalpha(s[8]) && isalpha(s[9]) && IsADigit(s[10]) && IsADigit(s[11]) && IsADigit(s[12])) {\n\t\t\t//rcd.t^^^^^###\n\t\t\treturn(SCE_BAAN_TABLEDEF);\n\t\t}\n\t\tbreak;\n\tcase 14:\n\tcase 15:\n\t\tif (s[8] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {\n\t\t\tif (s[13] != ':') {\n\t\t\t\t//^^^^^###.******\n\t\t\t\treturn(SCE_BAAN_TABLESQL);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase 16:\n\tcase 17:\n\t\tif (s[8] == '.' && s[9] == '_' && s[10] == 'i' && s[11] == 'n' && s[12] == 'd' && s[13] == 'e' && s[14] == 'x' && IsADigit(s[15]) && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {\n\t\t\t//^^^^^###._index##\n\t\t\treturn(SCE_BAAN_TABLEDEF);\n\t\t}\n\t\telse if (s[8] == '.' && s[9] == '_' && s[10] == 'c' && s[11] == 'o' && s[12] == 'm' && s[13] == 'p' && s[14] == 'n' && s[15] == 'r' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {\n\t\t\t//^^^^^###._compnr\n\t\t\treturn(SCE_BAAN_TABLEDEF);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tif (sLength > 14 && s[5] == '.' && s[6] == 'd' && s[7] == 'l' && s[8] == 'l' && s[13] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[9]) && IsADigit(s[10]) && IsADigit(s[11]) && IsADigit(s[12])) {\n\t\t//^^^^^.dll####.\n\t\treturn(SCE_BAAN_FUNCTION);\n\t}\n\telse if (sLength > 15 && s[2] == 'i' && s[3] == 'n' && s[4] == 't' && s[5] == '.' && s[6] == 'd' && s[7] == 'l' && s[8] == 'l' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[9]) && isalpha(s[10]) && isalpha(s[11]) && isalpha(s[12]) && isalpha(s[13])) {\n\t\t//^^int.dll^^^^^.\n\t\treturn(SCE_BAAN_FUNCTION);\n\t}\n\telse if (sLength > 11 && s[0] == 'i' && s[10] == '.' && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && isalpha(s[5]) && IsADigit(s[6]) && IsADigit(s[7]) && IsADigit(s[8]) && IsADigit(s[9])) {\n\t\t//i^^^^^####.\n\t\treturn(SCE_BAAN_FUNCTION);\n\t}\n\n\treturn(SCE_BAAN_DEFAULT);\n}\n\nstatic bool IsCommentLine(Sci_Position line, LexAccessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tint style = styler.StyleAt(i);\n\t\tif (ch == '|' && style == SCE_BAAN_COMMENT)\n\t\t\treturn true;\n\t\telse if (!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nstatic bool IsPreProcLine(Sci_Position line, LexAccessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tint style = styler.StyleAt(i);\n\t\tif (ch == '#' && style == SCE_BAAN_PREPROCESSOR) {\n\t\t\tif (styler.Match(i, \"#elif\") || styler.Match(i, \"#else\") || styler.Match(i, \"#endif\")\n\t\t\t\t|| styler.Match(i, \"#if\") || styler.Match(i, \"#ifdef\") || styler.Match(i, \"#ifndef\"))\n\t\t\t\t// Above PreProcessors has a seperate fold mechanism.\n\t\t\t\treturn false;\n\t\t\telse\n\t\t\t\treturn true;\n\t\t}\n\t\telse if (ch == '^')\n\t\t\treturn true;\n\t\telse if (!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nstatic int mainOrSubSectionLine(Sci_Position line, LexAccessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tint style = styler.StyleAt(i);\n\t\tif (style == SCE_BAAN_WORD5 || style == SCE_BAAN_WORD4)\n\t\t\treturn style;\n\t\telse if (IsASpaceOrTab(ch))\n\t\t\tcontinue;\n\t\telse\n\t\t\tbreak;\n\t}\n\treturn 0;\n}\n\nstatic bool priorSectionIsSubSection(Sci_Position line, LexAccessor &styler){\n\twhile (line > 0) {\n\t\tSci_Position pos = styler.LineStart(line);\n\t\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\t\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\t\tchar ch = styler[i];\n\t\t\tint style = styler.StyleAt(i);\n\t\t\tif (style == SCE_BAAN_WORD4)\n\t\t\t\treturn true;\n\t\t\telse if (style == SCE_BAAN_WORD5)\n\t\t\t\treturn false;\n\t\t\telse if (IsASpaceOrTab(ch))\n\t\t\t\tcontinue;\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\tline--;\n\t}\n\treturn false;\n}\n\nstatic bool nextSectionIsSubSection(Sci_Position line, LexAccessor &styler) {\n\twhile (line > 0) {\n\t\tSci_Position pos = styler.LineStart(line);\n\t\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\t\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\t\tchar ch = styler[i];\n\t\t\tint style = styler.StyleAt(i);\n\t\t\tif (style == SCE_BAAN_WORD4)\n\t\t\t\treturn true;\n\t\t\telse if (style == SCE_BAAN_WORD5)\n\t\t\t\treturn false;\n\t\t\telse if (IsASpaceOrTab(ch))\n\t\t\t\tcontinue;\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\tline++;\n\t}\n\treturn false;\n}\n\nstatic bool IsDeclarationLine(Sci_Position line, LexAccessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tint style = styler.StyleAt(i);\n\t\tif (style == SCE_BAAN_WORD) {\n\t\t\tif (styler.Match(i, \"table\") || styler.Match(i, \"extern\") || styler.Match(i, \"long\")\n\t\t\t\t|| styler.Match(i, \"double\") || styler.Match(i, \"boolean\") || styler.Match(i, \"string\")\n\t\t\t\t|| styler.Match(i, \"domain\")) {\n\t\t\t\tfor (Sci_Position j = eol_pos; j > pos; j--) {\n\t\t\t\t\tint styleFromEnd = styler.StyleAt(j);\n\t\t\t\t\tif (styleFromEnd == SCE_BAAN_COMMENT)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\telse if (IsASpace(styler[j]))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\telse if (styler[j] != ',')\n\t\t\t\t\t\t//Above conditions ensures, Declaration is not part of any function parameters.\n\t\t\t\t\t\treturn true;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nstatic bool IsInnerLevelFold(Sci_Position line, LexAccessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tint style = styler.StyleAt(i);\n\t\tif (style == SCE_BAAN_WORD && (styler.Match(i, \"else\" ) || styler.Match(i, \"case\")\n\t\t\t|| styler.Match(i, \"default\") || styler.Match(i, \"selectdo\") || styler.Match(i, \"selecteos\")\n\t\t\t|| styler.Match(i, \"selectempty\") || styler.Match(i, \"selecterror\")))\n\t\t\treturn true;\n\t\telse if (IsASpaceOrTab(ch))\n\t\t\tcontinue;\n\t\telse\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nstatic inline bool wordInArray(const std::string& value, std::string *array, int length)\n{\n\tfor (int i = 0; i < length; i++)\n\t{\n\t\tif (value == array[i])\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nclass WordListAbridged : public WordList {\npublic:\n\tWordListAbridged() {\n\t\tkwAbridged = false;\n\t\tkwHasSection = false;\n\t};\n\t~WordListAbridged() {\n\t\tClear();\n\t};\n\tbool kwAbridged;\n\tbool kwHasSection;\n\tbool Contains(const char *s) {\n\t\treturn kwAbridged ? InListAbridged(s, '~') : InList(s);\n\t};\n};\n\n}\n\nclass LexerBaan : public DefaultLexer {\n\tWordListAbridged keywords;\n\tWordListAbridged keywords2;\n\tWordListAbridged keywords3;\n\tWordListAbridged keywords4;\n\tWordListAbridged keywords5;\n\tWordListAbridged keywords6;\n\tWordListAbridged keywords7;\n\tWordListAbridged keywords8;\n\tWordListAbridged keywords9;\n\tOptionsBaan options;\n\tOptionSetBaan osBaan;\npublic:\n\tLexerBaan() : DefaultLexer(\"baan\", SCLEX_BAAN) {\n\t}\n\n\tvirtual ~LexerBaan() {\n\t}\n\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\n\tconst char * SCI_METHOD PropertyNames() override {\n\t\treturn osBaan.PropertyNames();\n\t}\n\n\tint SCI_METHOD PropertyType(const char * name) override {\n\t\treturn osBaan.PropertyType(name);\n\t}\n\n\tconst char * SCI_METHOD DescribeProperty(const char * name) override {\n\t\treturn osBaan.DescribeProperty(name);\n\t}\n\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osBaan.PropertyGet(key);\n\t}\n\n\tconst char * SCI_METHOD DescribeWordListSets() override {\n\t\treturn osBaan.DescribeWordListSets();\n\t}\n\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid * SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn NULL;\n\t}\n\n\tstatic ILexer5 * LexerFactoryBaan() {\n\t\treturn new LexerBaan();\n\t}\n};\n\nSci_Position SCI_METHOD LexerBaan::PropertySet(const char *key, const char *val) {\n\tif (osBaan.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerBaan::WordListSet(int n, const char *wl) {\n\tWordListAbridged *WordListAbridgedN = 0;\n\tswitch (n) {\n\tcase 0:\n\t\tWordListAbridgedN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\tWordListAbridgedN = &keywords2;\n\t\tbreak;\n\tcase 2:\n\t\tWordListAbridgedN = &keywords3;\n\t\tbreak;\n\tcase 3:\n\t\tWordListAbridgedN = &keywords4;\n\t\tbreak;\n\tcase 4:\n\t\tWordListAbridgedN = &keywords5;\n\t\tbreak;\n\tcase 5:\n\t\tWordListAbridgedN = &keywords6;\n\t\tbreak;\n\tcase 6:\n\t\tWordListAbridgedN = &keywords7;\n\t\tbreak;\n\tcase 7:\n\t\tWordListAbridgedN = &keywords8;\n\t\tbreak;\n\tcase 8:\n\t\tWordListAbridgedN = &keywords9;\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (WordListAbridgedN) {\n\t\tWordListAbridged wlNew;\n\t\twlNew.Set(wl);\n\t\tif (*WordListAbridgedN != wlNew) {\n\t\t\tWordListAbridgedN->Set(wl);\n\t\t\tWordListAbridgedN->kwAbridged = strchr(wl, '~') != NULL;\n\t\t\tWordListAbridgedN->kwHasSection = strchr(wl, ':') != NULL;\n\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\n\tif (initStyle == SCE_BAAN_STRINGEOL)\t// Does not leak onto next line\n\t\tinitStyle = SCE_BAAN_DEFAULT;\n\n\tint visibleChars = 0;\n\tbool lineHasDomain = false;\n\tbool lineHasFunction = false;\n\tbool lineHasPreProc = false;\n\tbool lineIgnoreString = false;\n\tbool lineHasDefines = false;\n\tbool numberIsHex = false;\n\tchar word[1000];\n\tint wordlen = 0;\n\n\tstd::string preProcessorTags[13] = { \"#context_off\", \"#context_on\",\n\t\t\"#define\", \"#elif\", \"#else\", \"#endif\",\n\t\t\"#ident\", \"#if\", \"#ifdef\", \"#ifndef\",\n\t\t\"#include\", \"#pragma\", \"#undef\" };\n\tLexAccessor styler(pAccess);\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\tcase SCE_BAAN_OPERATOR:\n\t\t\tsc.SetState(SCE_BAAN_DEFAULT);\n\t\t\tbreak;\n\t\tcase SCE_BAAN_NUMBER:\n\t\t\tif (IsASpaceOrTab(sc.ch) || sc.ch == '\\r' || sc.ch == '\\n' || IsAnOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_BAAN_DEFAULT);\n\t\t\t}\n\t\t\telse if ((numberIsHex && !(MakeLowerCase(sc.ch) == 'x' || MakeLowerCase(sc.ch) == 'e' ||\n\t\t\t\tIsADigit(sc.ch, 16) || sc.ch == '.' || sc.ch == '-' || sc.ch == '+')) ||\n\t\t\t\t(!numberIsHex && !(MakeLowerCase(sc.ch) == 'e' || IsADigit(sc.ch)\n\t\t\t\t|| sc.ch == '.' || sc.ch == '-' || sc.ch == '+'))) {\n\t\t\t\t\t// check '-' for possible -10e-5. Add '+' as well.\n\t\t\t\t\tnumberIsHex = false;\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_IDENTIFIER);\n\t\t\t\t\tsc.SetState(SCE_BAAN_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_BAAN_IDENTIFIER:\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[1000];\n\t\t\t\tchar s1[1000];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tif (sc.ch == ':') {\n\t\t\t\t\tmemcpy(s1, s, sizeof(s));\n\t\t\t\t\ts1[sc.LengthCurrent()] = sc.ch;\n\t\t\t\t\ts1[sc.LengthCurrent() + 1] = '\\0';\n\t\t\t\t}\n\t\t\t\tif ((keywords.kwHasSection && (sc.ch == ':')) ? keywords.Contains(s1) : keywords.Contains(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_WORD);\n\t\t\t\t\tif (0 == strcmp(s, \"domain\")) {\n\t\t\t\t\t\tlineHasDomain = true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (0 == strcmp(s, \"function\")) {\n\t\t\t\t\t\tlineHasFunction = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (lineHasDomain) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_DOMDEF);\n\t\t\t\t\tlineHasDomain = false;\n\t\t\t\t}\n\t\t\t\telse if (lineHasFunction) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_FUNCDEF);\n\t\t\t\t\tlineHasFunction = false;\n\t\t\t\t}\n\t\t\t\telse if ((keywords2.kwHasSection && (sc.ch == ':')) ? keywords2.Contains(s1) : keywords2.Contains(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_WORD2);\n\t\t\t\t}\n\t\t\t\telse if ((keywords3.kwHasSection && (sc.ch == ':')) ? keywords3.Contains(s1) : keywords3.Contains(s)) {\n\t\t\t\t\tif (sc.ch == '(')\n\t\t\t\t\t\tsc.ChangeState(SCE_BAAN_WORD3);\n\t\t\t\t\telse\n\t\t\t\t\t\tsc.ChangeState(SCE_BAAN_IDENTIFIER);\n\t\t\t\t}\n\t\t\t\telse if ((keywords4.kwHasSection && (sc.ch == ':')) ? keywords4.Contains(s1) : keywords4.Contains(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_WORD4);\n\t\t\t\t}\n\t\t\t\telse if ((keywords5.kwHasSection && (sc.ch == ':')) ? keywords5.Contains(s1) : keywords5.Contains(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_WORD5);\n\t\t\t\t}\n\t\t\t\telse if ((keywords6.kwHasSection && (sc.ch == ':')) ? keywords6.Contains(s1) : keywords6.Contains(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_WORD6);\n\t\t\t\t}\n\t\t\t\telse if ((keywords7.kwHasSection && (sc.ch == ':')) ? keywords7.Contains(s1) : keywords7.Contains(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_WORD7);\n\t\t\t\t}\n\t\t\t\telse if ((keywords8.kwHasSection && (sc.ch == ':')) ? keywords8.Contains(s1) : keywords8.Contains(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_WORD8);\n\t\t\t\t}\n\t\t\t\telse if ((keywords9.kwHasSection && (sc.ch == ':')) ? keywords9.Contains(s1) : keywords9.Contains(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_WORD9);\n\t\t\t\t}\n\t\t\t\telse if (lineHasPreProc) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_OBJECTDEF);\n\t\t\t\t\tlineHasPreProc = false;\n\t\t\t\t}\n\t\t\t\telse if (lineHasDefines) {\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_DEFINEDEF);\n\t\t\t\t\tlineHasDefines = false;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tint state = IsAnyOtherIdentifier(s, sc.LengthCurrent());\n\t\t\t\t\tif (state > 0) {\n\t\t\t\t\t\tsc.ChangeState(state);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_BAAN_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_BAAN_PREPROCESSOR:\n\t\t\tif (options.baanStylingWithinPreprocessor) {\n\t\t\t\tif (IsASpace(sc.ch) || IsAnOperator(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_BAAN_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (sc.atLineEnd && (sc.chNext != '^')) {\n\t\t\t\t\tsc.SetState(SCE_BAAN_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_BAAN_COMMENT:\n\t\t\tif (sc.ch == '\\r' || sc.ch == '\\n') {\n\t\t\t\tsc.SetState(SCE_BAAN_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_BAAN_COMMENTDOC:\n\t\t\tif (sc.MatchIgnoreCase(\"enddllusage\")) {\n\t\t\t\tfor (unsigned int i = 0; i < 10; i++) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.ForwardSetState(SCE_BAAN_DEFAULT);\n\t\t\t}\n\t\t\telse if (sc.MatchIgnoreCase(\"endfunctionusage\")) {\n\t\t\t\tfor (unsigned int i = 0; i < 15; i++) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.ForwardSetState(SCE_BAAN_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_BAAN_STRING:\n\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_BAAN_DEFAULT);\n\t\t\t}\n\t\t\telse if ((sc.atLineEnd) && (sc.chNext != '^')) {\n\t\t\t\tsc.ChangeState(SCE_BAAN_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_BAAN_DEFAULT);\n\t\t\t\tvisibleChars = 0;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_BAAN_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))\n\t\t\t\t|| ((sc.ch == '-' || sc.ch == '+') && (IsADigit(sc.chNext) || sc.chNext == '.'))\n\t\t\t\t|| (MakeLowerCase(sc.ch) == 'e' && (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-'))) {\n\t\t\t\tif ((sc.ch == '0' && MakeLowerCase(sc.chNext) == 'x') ||\n\t\t\t\t\t((sc.ch == '-' || sc.ch == '+') && sc.chNext == '0' && MakeLowerCase(sc.GetRelativeCharacter(2)) == 'x')){\n\t\t\t\t\tnumberIsHex = true;\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_BAAN_NUMBER);\n\t\t\t}\n\t\t\telse if (sc.MatchIgnoreCase(\"dllusage\") || sc.MatchIgnoreCase(\"functionusage\")) {\n\t\t\t\tsc.SetState(SCE_BAAN_COMMENTDOC);\n\t\t\t\tdo {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} while ((!sc.atLineEnd) && sc.More());\n\t\t\t}\n\t\t\telse if (iswordstart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_BAAN_IDENTIFIER);\n\t\t\t}\n\t\t\telse if (sc.Match('|')) {\n\t\t\t\tsc.SetState(SCE_BAAN_COMMENT);\n\t\t\t}\n\t\t\telse if (sc.ch == '\\\"' && !(lineIgnoreString)) {\n\t\t\t\tsc.SetState(SCE_BAAN_STRING);\n\t\t\t}\n\t\t\telse if (sc.ch == '#' && visibleChars == 0) {\n\t\t\t\t// Preprocessor commands are alone on their line\n\t\t\t\tsc.SetState(SCE_BAAN_PREPROCESSOR);\n\t\t\t\tword[0] = '\\0';\n\t\t\t\twordlen = 0;\n\t\t\t\twhile (sc.More() && !(IsASpace(sc.chNext) || IsAnOperator(sc.chNext))) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\twordlen++;\n\t\t\t\t}\n\t\t\t\tsc.GetCurrentLowered(word, sizeof(word));\n\t\t\t\tif (!sc.atLineEnd) {\n\t\t\t\t\tword[wordlen++] = sc.ch;\n\t\t\t\t\tword[wordlen++] = '\\0';\n\t\t\t\t}\n\t\t\t\tif (!wordInArray(word, preProcessorTags, 13))\n\t\t\t\t\t// Colorise only preprocessor built in Baan.\n\t\t\t\t\tsc.ChangeState(SCE_BAAN_IDENTIFIER);\n\t\t\t\tif (strcmp(word, \"#pragma\") == 0 || strcmp(word, \"#include\") == 0) {\n\t\t\t\t\tlineHasPreProc = true;\n\t\t\t\t\tlineIgnoreString = true;\n\t\t\t\t}\n\t\t\t\telse if (strcmp(word, \"#define\") == 0 || strcmp(word, \"#undef\") == 0 ||\n\t\t\t\t\tstrcmp(word, \"#ifdef\") == 0 || strcmp(word, \"#if\") == 0 || strcmp(word, \"#ifndef\") == 0) {\n\t\t\t\t\tlineHasDefines = true;\n\t\t\t\t\tlineIgnoreString = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (IsAnOperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_BAAN_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\t// Reset states to begining of colourise so no surprises\n\t\t\t// if different sets of lines lexed.\n\t\t\tvisibleChars = 0;\n\t\t\tlineHasDomain = false;\n\t\t\tlineHasFunction = false;\n\t\t\tlineHasPreProc = false;\n\t\t\tlineIgnoreString = false;\n\t\t\tlineHasDefines = false;\n\t\t\tnumberIsHex = false;\n\t\t}\n\t\tif (!IsASpace(sc.ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nvoid SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tif (!options.fold)\n\t\treturn;\n\n\tchar word[100];\n\tint wordlen = 0;\n\tbool foldStart = true;\n\tbool foldNextSelect = true;\n\tbool afterFunctionSection = false;\n\tbool beforeDeclarationSection = false;\n\tint currLineStyle = 0;\n\tint nextLineStyle = 0;\n\n\tstd::string startTags[6] = { \"for\", \"if\", \"on\", \"repeat\", \"select\", \"while\" };\n\tstd::string endTags[6] = { \"endcase\", \"endfor\", \"endif\", \"endselect\", \"endwhile\", \"until\" };\n\tstd::string selectCloseTags[5] = { \"selectdo\", \"selecteos\", \"selectempty\", \"selecterror\", \"endselect\" };\n\n\tLexAccessor styler(pAccess);\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\n\t// Backtrack to previous line in case need to fix its fold status\n\tif (startPos > 0) {\n\t\tif (lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t\t}\n\t}\n\n\tint levelPrev = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelPrev = styler.LevelAt(lineCurrent - 1) >> 16;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint style = initStyle;\n\tint styleNext = styler.StyleAt(startPos);\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tint stylePrev = (i) ? styler.StyleAt(i - 1) : SCE_BAAN_DEFAULT;\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\t// Comment folding\n\t\tif (options.foldComment && style == SCE_BAAN_COMMENTDOC) {\n\t\t\tif (style != stylePrev) {\n\t\t\t\tlevelCurrent++;\n\t\t\t}\n\t\t\telse if (style != styleNext) {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {\n\t\t\tif (!IsCommentLine(lineCurrent - 1, styler)\n\t\t\t\t&& IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (IsCommentLine(lineCurrent - 1, styler)\n\t\t\t\t&& !IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelCurrent--;\n\t\t}\n\t\t// PreProcessor Folding\n\t\tif (options.foldPreprocessor) {\n\t\t\tif (atEOL && IsPreProcLine(lineCurrent, styler)) {\n\t\t\t\tif (!IsPreProcLine(lineCurrent - 1, styler)\n\t\t\t\t\t&& IsPreProcLine(lineCurrent + 1, styler))\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\telse if (IsPreProcLine(lineCurrent - 1, styler)\n\t\t\t\t\t&& !IsPreProcLine(lineCurrent + 1, styler))\n\t\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t\telse if (style == SCE_BAAN_PREPROCESSOR) {\n\t\t\t\t// folds #ifdef/#if/#ifndef - they are not part of the IsPreProcLine folding.\n\t\t\t\tif (ch == '#') {\n\t\t\t\t\tif (styler.Match(i, \"#ifdef\") || styler.Match(i, \"#if\") || styler.Match(i, \"#ifndef\")\n\t\t\t\t\t\t|| styler.Match(i, \"#context_on\"))\n\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\telse if (styler.Match(i, \"#endif\") || styler.Match(i, \"#context_off\"))\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t//Syntax Folding\n\t\tif (options.baanFoldSyntaxBased && (style == SCE_BAAN_OPERATOR)) {\n\t\t\tif (ch == '{' || ch == '(') {\n\t\t\t\tlevelCurrent++;\n\t\t\t}\n\t\t\telse if (ch == '}' || ch == ')') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\t//Keywords Folding\n\t\tif (options.baanFoldKeywordsBased) {\n\t\t\tif (atEOL && IsDeclarationLine(lineCurrent, styler)) {\n\t\t\t\tif (!IsDeclarationLine(lineCurrent - 1, styler)\n\t\t\t\t\t&& IsDeclarationLine(lineCurrent + 1, styler))\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\telse if (IsDeclarationLine(lineCurrent - 1, styler)\n\t\t\t\t\t&& !IsDeclarationLine(lineCurrent + 1, styler))\n\t\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t\telse if (style == SCE_BAAN_WORD) {\n\t\t\t\tword[wordlen++] = static_cast<char>(MakeLowerCase(ch));\n\t\t\t\tif (wordlen == 100) {                   // prevent overflow\n\t\t\t\t\tword[0] = '\\0';\n\t\t\t\t\twordlen = 1;\n\t\t\t\t}\n\t\t\t\tif (styleNext != SCE_BAAN_WORD) {\n\t\t\t\t\tword[wordlen] = '\\0';\n\t\t\t\t\twordlen = 0;\n\t\t\t\t\tif (strcmp(word, \"for\") == 0) {\n\t\t\t\t\t\tSci_PositionU j = i + 1;\n\t\t\t\t\t\twhile ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (styler.Match(j, \"update\")) {\n\t\t\t\t\t\t\t// Means this is a \"for update\" used by Select which is already folded.\n\t\t\t\t\t\t\tfoldStart = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (strcmp(word, \"on\") == 0) {\n\t\t\t\t\t\tSci_PositionU j = i + 1;\n\t\t\t\t\t\twhile ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!styler.Match(j, \"case\")) {\n\t\t\t\t\t\t\t// Means this is not a \"on Case\" statement... could be \"on\" used by index.\n\t\t\t\t\t\t\tfoldStart = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (strcmp(word, \"select\") == 0) {\n\t\t\t\t\t\tif (foldNextSelect) {\n\t\t\t\t\t\t\t// Next Selects are sub-clause till reach of selectCloseTags[] array.\n\t\t\t\t\t\t\tfoldNextSelect = false;\n\t\t\t\t\t\t\tfoldStart = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tfoldNextSelect = false;\n\t\t\t\t\t\t\tfoldStart = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (wordInArray(word, selectCloseTags, 5)) {\n\t\t\t\t\t\t// select clause ends, next select clause can be folded.\n\t\t\t\t\t\tfoldNextSelect = true;\n\t\t\t\t\t\tfoldStart = true;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfoldStart = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (foldStart) {\n\t\t\t\t\t\tif (wordInArray(word, startTags, 6)) {\n\t\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (wordInArray(word, endTags, 6)) {\n\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Fold inner level of if/select/case statements\n\t\tif (options.baanFoldInnerLevel && atEOL) {\n\t\t\tbool currLineInnerLevel = IsInnerLevelFold(lineCurrent, styler);\n\t\t\tbool nextLineInnerLevel = IsInnerLevelFold(lineCurrent + 1, styler);\n\t\t\tif (currLineInnerLevel && currLineInnerLevel != nextLineInnerLevel) {\n\t\t\t\tlevelCurrent++;\n\t\t\t}\n\t\t\telse if (nextLineInnerLevel && nextLineInnerLevel != currLineInnerLevel) {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\t// Section Foldings.\n\t\t// One way of implementing Section Foldings, as there is no END markings of sections.\n\t\t// first section ends on the previous line of next section.\n\t\t// Re-written whole folding to accomodate this.\n\t\tif (options.baanFoldSections && atEOL) {\n\t\t\tcurrLineStyle = mainOrSubSectionLine(lineCurrent, styler);\n\t\t\tnextLineStyle = mainOrSubSectionLine(lineCurrent + 1, styler);\n\t\t\tif (currLineStyle != 0 && currLineStyle != nextLineStyle) {\n\t\t\t\tif (levelCurrent < levelPrev)\n\t\t\t\t\t--levelPrev;\n\t\t\t\tfor (Sci_Position j = styler.LineStart(lineCurrent); j < styler.LineStart(lineCurrent + 1) - 1; j++) {\n\t\t\t\t\tif (IsASpaceOrTab(styler[j]))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\telse if (styler.StyleAt(j) == SCE_BAAN_WORD5) {\n\t\t\t\t\t\tif (styler.Match(j, \"functions:\")) {\n\t\t\t\t\t\t\t// Means functions: is the end of MainSections.\n\t\t\t\t\t\t\t// Nothing to fold after this.\n\t\t\t\t\t\t\tafterFunctionSection = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tafterFunctionSection = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tafterFunctionSection = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!afterFunctionSection)\n\t\t\t\t\tlevelCurrent++;\n\t\t\t}\n\t\t\telse if (nextLineStyle != 0 && currLineStyle != nextLineStyle\n\t\t\t\t&& (priorSectionIsSubSection(lineCurrent -1 ,styler)\n\t\t\t\t\t|| !nextSectionIsSubSection(lineCurrent + 1, styler))) {\n\t\t\t\tfor (Sci_Position j = styler.LineStart(lineCurrent + 1); j < styler.LineStart(lineCurrent + 1 + 1) - 1; j++) {\n\t\t\t\t\tif (IsASpaceOrTab(styler[j]))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\telse if (styler.StyleAt(j) == SCE_BAAN_WORD5) {\n\t\t\t\t\t\tif (styler.Match(j, \"declaration:\")) {\n\t\t\t\t\t\t\t// Means declaration: is the start of MainSections.\n\t\t\t\t\t\t\t// Nothing to fold before this.\n\t\t\t\t\t\t\tbeforeDeclarationSection = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tbeforeDeclarationSection = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tbeforeDeclarationSection = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!beforeDeclarationSection) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\tif (nextLineStyle == SCE_BAAN_WORD5 && priorSectionIsSubSection(lineCurrent-1, styler))\n\t\t\t\t\t\t// next levelCurrent--; is to unfold previous subsection fold.\n\t\t\t\t\t\t// On reaching the next main section, the previous main as well sub section ends.\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tlev |= levelCurrent << 16;\n\t\t\tif (visibleChars == 0 && options.foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nextern const LexerModule lmBaan(SCLEX_BAAN, LexerBaan::LexerFactoryBaan, \"baan\", baanWordLists);\n"
  },
  {
    "path": "lexers/LexBash.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexBash.cxx\n ** Lexer for Bash.\n **/\n// Copyright 2004-2012 by Neil Hodgson <neilh@scintilla.org>\n// Adapted from LexPerl by Kein-Hong Man 2004\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <initializer_list>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"StringCopy.h\"\n#include \"InList.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"SubStyles.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\n#define HERE_DELIM_MAX\t\t\t256\n\n// define this if you want 'invalid octals' to be marked as errors\n// usually, this is not a good idea, permissive lexing is better\n#undef PEDANTIC_OCTAL\n\n#define BASH_BASE_ERROR\t\t\t65\n#define BASH_BASE_DECIMAL\t\t66\n#define BASH_BASE_HEX\t\t\t67\n#ifdef PEDANTIC_OCTAL\n#define BASH_BASE_OCTAL\t\t\t68\n#define\tBASH_BASE_OCTAL_ERROR\t69\n#endif\n\n// state constants for parts of a bash command segment\nenum class CmdState {\n\tBody,\n\tStart,\n\tWord,\n\tTest,\t\t\t// test\n\tSingleBracket,\t// []\n\tDoubleBracket,\t// [[]]\n\tArithmetic,\n\tDelimiter,\n};\n\nenum class CommandSubstitution : int {\n\tBacktick,\n\tInside,\n\tInsideTrack,\n};\n\n// state constants for nested delimiter pairs, used by\n// SCE_SH_STRING, SCE_SH_PARAM and SCE_SH_BACKTICKS processing\nenum class QuoteStyle {\n\tLiteral,\t\t// ''\n\tCString,\t\t// $''\n\tString,\t\t\t// \"\"\n\tLString,\t\t// $\"\"\n\tHereDoc,\t\t// here document\n\tBacktick,\t\t// ``\n\tParameter,\t\t// ${}\n\tCommand,\t\t// $()\n\tCommandInside,\t// $() with styling inside\n\tArithmetic,\t\t// $(()), $[]\n};\n\n#define BASH_QUOTE_STACK_MAX\t7\n#define BASH_SPECIAL_PARAMETER\t\"*@#?-$!\"\n\nconstexpr int commandSubstitutionFlag = 0x40;\nconstexpr int MaskCommand(int state) noexcept {\n\treturn state & ~commandSubstitutionFlag;\n}\n\nconstexpr int translateBashDigit(int ch) noexcept {\n\tif (ch >= '0' && ch <= '9') {\n\t\treturn ch - '0';\n\t} else if (ch >= 'a' && ch <= 'z') {\n\t\treturn ch - 'a' + 10;\n\t} else if (ch >= 'A' && ch <= 'Z') {\n\t\treturn ch - 'A' + 36;\n\t} else if (ch == '@') {\n\t\treturn 62;\n\t} else if (ch == '_') {\n\t\treturn 63;\n\t}\n\treturn BASH_BASE_ERROR;\n}\n\nint getBashNumberBase(const char *s) noexcept {\n\tint i = 0;\n\tint base = 0;\n\twhile (*s) {\n\t\tbase = base * 10 + (*s++ - '0');\n\t\ti++;\n\t}\n\tif (base > 64 || i > 2) {\n\t\treturn BASH_BASE_ERROR;\n\t}\n\treturn base;\n}\n\nconstexpr int opposite(int ch) noexcept {\n\tif (ch == '(') return ')';\n\tif (ch == '[') return ']';\n\tif (ch == '{') return '}';\n\tif (ch == '<') return '>';\n\treturn ch;\n}\n\nint GlobScan(StyleContext &sc) {\n\t// forward scan for zsh globs, disambiguate versus bash arrays\n\t// complex expressions may still fail, e.g. unbalanced () '' \"\" etc\n\tint c = 0;\n\tint sLen = 0;\n\tint pCount = 0;\n\tint hash = 0;\n\twhile ((c = sc.GetRelativeCharacter(++sLen)) != 0) {\n\t\tif (IsASpace(c)) {\n\t\t\treturn 0;\n\t\t} else if (c == '\\'' || c == '\\\"') {\n\t\t\tif (hash != 2) return 0;\n\t\t} else if (c == '#' && hash == 0) {\n\t\t\thash = (sLen == 1) ? 2:1;\n\t\t} else if (c == '(') {\n\t\t\tpCount++;\n\t\t} else if (c == ')') {\n\t\t\tif (pCount == 0) {\n\t\t\t\tif (hash) return sLen;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tpCount--;\n\t\t}\n\t}\n\treturn 0;\n}\n\nbool IsCommentLine(Sci_Position line, LexAccessor &styler) {\n\tconst Sci_Position pos = styler.LineStart(line);\n\tconst Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tconst char ch = styler[i];\n\t\tif (ch == '#')\n\t\t\treturn true;\n\t\tif (ch != ' ' && ch != '\\t')\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nconstexpr bool StyleForceBacktrack(int state) noexcept {\n\treturn AnyOf(state, SCE_SH_CHARACTER, SCE_SH_STRING, SCE_SH_BACKTICKS, SCE_SH_HERE_Q, SCE_SH_PARAM);\n}\n\nstruct OptionsBash {\n\tbool fold = false;\n\tbool foldComment = false;\n\tbool foldCompact = true;\n\tbool stylingInsideString = false;\n\tbool stylingInsideBackticks = false;\n\tbool stylingInsideParameter = false;\n\tbool stylingInsideHeredoc = false;\n\tbool nestedBackticks = true;\n\tCommandSubstitution commandSubstitution = CommandSubstitution::Backtick;\n\tstd::string specialParameter = BASH_SPECIAL_PARAMETER;\n\n\t[[nodiscard]] bool stylingInside(int state) const noexcept {\n\t\tswitch (state) {\n\t\tcase SCE_SH_STRING:\n\t\t\treturn stylingInsideString;\n\t\tcase SCE_SH_BACKTICKS:\n\t\t\treturn stylingInsideBackticks;\n\t\tcase SCE_SH_PARAM:\n\t\t\treturn stylingInsideParameter;\n\t\tcase SCE_SH_HERE_Q:\n\t\t\treturn stylingInsideHeredoc;\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\nconst char * const bashWordListDesc[] = {\n\t\"Keywords\",\n\tnullptr\n};\n\nstruct OptionSetBash : public OptionSet<OptionsBash> {\n\tOptionSetBash() {\n\t\tDefineProperty(\"fold\", &OptionsBash::fold);\n\n\t\tDefineProperty(\"fold.comment\", &OptionsBash::foldComment);\n\n\t\tDefineProperty(\"fold.compact\", &OptionsBash::foldCompact);\n\n\t\tDefineProperty(\"lexer.bash.styling.inside.string\", &OptionsBash::stylingInsideString,\n\t\t\t\"Set this property to 1 to highlight shell expansions inside string.\");\n\n\t\tDefineProperty(\"lexer.bash.styling.inside.backticks\", &OptionsBash::stylingInsideBackticks,\n\t\t\t\"Set this property to 1 to highlight shell expansions inside backticks.\");\n\n\t\tDefineProperty(\"lexer.bash.styling.inside.parameter\", &OptionsBash::stylingInsideParameter,\n\t\t\t\"Set this property to 1 to highlight shell expansions inside ${} parameter expansion.\");\n\n\t\tDefineProperty(\"lexer.bash.styling.inside.heredoc\", &OptionsBash::stylingInsideHeredoc,\n\t\t\t\"Set this property to 1 to highlight shell expansions inside here document.\");\n\n\t\tDefineProperty(\"lexer.bash.command.substitution\", &OptionsBash::commandSubstitution,\n\t\t\t\"Set how to highlight $() command substitution. \"\n\t\t\t\"0 (the default) highlighted as backticks. \"\n\t\t\t\"1 highlighted inside. \"\n\t\t\t\"2 highlighted inside with extra scope tracking.\");\n\n\t\tDefineProperty(\"lexer.bash.nested.backticks\", &OptionsBash::nestedBackticks,\n\t\t\t\"Set this property to 0 to disable nested backquoted command substitution.\");\n\n\t\tDefineProperty(\"lexer.bash.special.parameter\", &OptionsBash::specialParameter,\n\t\t\t\"Set shell (default is Bash) special parameters.\");\n\n\t\tDefineWordListSets(bashWordListDesc);\n\t}\n};\n\nclass QuoteCls {\t// Class to manage quote pairs (simplified vs LexPerl)\npublic:\n\tint Count = 0;\n\tint Up = '\\0';\n\tint Down = '\\0';\n\tQuoteStyle Style = QuoteStyle::Literal;\n\tint Outer = SCE_SH_DEFAULT;\n\tCmdState State = CmdState::Body;\n\tvoid Clear() noexcept {\n\t\tCount = 0;\n\t\tUp\t  = '\\0';\n\t\tDown  = '\\0';\n\t\tStyle = QuoteStyle::Literal;\n\t\tOuter = SCE_SH_DEFAULT;\n\t\tState = CmdState::Body;\n\t}\n\tvoid Start(int u, QuoteStyle s, int outer, CmdState state) noexcept {\n\t\tCount = 1;\n\t\tUp    = u;\n\t\tDown  = opposite(Up);\n\t\tStyle = s;\n\t\tOuter = outer;\n\t\tState = state;\n\t}\n};\n\nclass QuoteStackCls {\t// Class to manage quote pairs that nest\npublic:\n\tint Depth = 0;\n\tint State = SCE_SH_DEFAULT;\n\tbool lineContinuation = false;\n\tbool nestedBackticks = false;\n\tCommandSubstitution commandSubstitution = CommandSubstitution::Backtick;\n\tint insideCommand = 0;\n\tunsigned backtickLevel = 0;\n\tQuoteCls Current;\n\tQuoteCls Stack[BASH_QUOTE_STACK_MAX];\n\tconst CharacterSet &setParamStart;\n\tQuoteStackCls(const CharacterSet &setParamStart_) noexcept : setParamStart{setParamStart_} {}\n\t[[nodiscard]] bool Empty() const noexcept {\n\t\treturn Current.Up == '\\0';\n\t}\n\tvoid Start(int u, QuoteStyle s, int outer, CmdState state) noexcept {\n\t\tif (Empty()) {\n\t\t\tCurrent.Start(u, s, outer, state);\n\t\t\tif (s == QuoteStyle::Backtick) {\n\t\t\t\t++backtickLevel;\n\t\t\t}\n\t\t} else {\n\t\t\tPush(u, s, outer, state);\n\t\t}\n\t}\n\tvoid Push(int u, QuoteStyle s, int outer, CmdState state) noexcept {\n\t\tif (Depth >= BASH_QUOTE_STACK_MAX) {\n\t\t\treturn;\n\t\t}\n\t\tStack[Depth] = Current;\n\t\tDepth++;\n\t\tCurrent.Start(u, s, outer, state);\n\t\tif (s == QuoteStyle::Backtick) {\n\t\t\t++backtickLevel;\n\t\t}\n\t}\n\tvoid Pop() noexcept {\n\t\tif (Depth == 0) {\n\t\t\tClear();\n\t\t\treturn;\n\t\t}\n\t\tif (backtickLevel != 0 && Current.Style == QuoteStyle::Backtick) {\n\t\t\t--backtickLevel;\n\t\t}\n\t\tif (insideCommand != 0 && Current.Style == QuoteStyle::CommandInside) {\n\t\t\tinsideCommand = 0;\n\t\t\tfor (int i = 0; i < Depth; i++) {\n\t\t\t\tif (Stack[i].Style == QuoteStyle::CommandInside) {\n\t\t\t\t\tinsideCommand = commandSubstitutionFlag;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tDepth--;\n\t\tCurrent = Stack[Depth];\n\t}\n\tvoid Clear() noexcept {\n\t\tDepth = 0;\n\t\tState = SCE_SH_DEFAULT;\n\t\tinsideCommand = 0;\n\t\tbacktickLevel = 0;\n\t\tCurrent.Clear();\n\t}\n\tbool CountDown(StyleContext &sc, CmdState &cmdState) {\n\t\tCurrent.Count--;\n\t\twhile (Current.Count > 0 && sc.chNext == Current.Down) {\n\t\t\tCurrent.Count--;\n\t\t\tsc.Forward();\n\t\t}\n\t\tif (Current.Count == 0) {\n\t\t\tcmdState = Current.State;\n\t\t\tconst int outer = Current.Outer;\n\t\t\tPop();\n\t\t\tsc.ForwardSetState(outer | insideCommand);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\tvoid Expand(StyleContext &sc, CmdState &cmdState, bool stylingInside) {\n\t\tconst CmdState current = cmdState;\n\t\tconst int state = sc.state;\n\t\tQuoteStyle style = QuoteStyle::Literal;\n\t\tState = state;\n\t\tsc.SetState(SCE_SH_SCALAR);\n\t\tsc.Forward();\n\t\tif (sc.ch == '{') {\n\t\t\tstyle = QuoteStyle::Parameter;\n\t\t\tsc.ChangeState(SCE_SH_PARAM);\n\t\t} else if (sc.ch == '\\'') {\n\t\t\tstyle = QuoteStyle::CString;\n\t\t\tsc.ChangeState(SCE_SH_STRING);\n\t\t} else if (sc.ch == '\"') {\n\t\t\tstyle = QuoteStyle::LString;\n\t\t\tsc.ChangeState(SCE_SH_STRING);\n\t\t} else if (sc.ch == '(' || sc.ch == '[') {\n\t\t\tif (sc.ch == '[' || sc.chNext == '(') {\n\t\t\t\tstyle = QuoteStyle::Arithmetic;\n\t\t\t\tcmdState = CmdState::Arithmetic;\n\t\t\t\tsc.ChangeState(SCE_SH_OPERATOR);\n\t\t\t} else {\n\t\t\t\tif (stylingInside && commandSubstitution >= CommandSubstitution::Inside) {\n\t\t\t\t\tstyle = QuoteStyle::CommandInside;\n\t\t\t\t\tcmdState = CmdState::Delimiter;\n\t\t\t\t\tsc.ChangeState(SCE_SH_OPERATOR);\n\t\t\t\t\tif (commandSubstitution == CommandSubstitution::InsideTrack) {\n\t\t\t\t\t\tinsideCommand = commandSubstitutionFlag;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstyle = QuoteStyle::Command;\n\t\t\t\t\tsc.ChangeState(SCE_SH_BACKTICKS);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// scalar has no delimiter pair\n\t\t\tif (!setParamStart.Contains(sc.ch)) {\n\t\t\t\tstylingInside = false; // not scalar\n\t\t\t}\n\t\t}\n\t\tif (!stylingInside) {\n\t\t\tsc.ChangeState(state);\n\t\t} else {\n\t\t\tsc.ChangeState(sc.state | insideCommand);\n\t\t}\n\t\tif (style != QuoteStyle::Literal) {\n\t\t\tStart(sc.ch, style, state, current);\n\t\t\tsc.Forward();\n\t\t}\n\t}\n\tvoid Escape(StyleContext &sc) {\n\t\tunsigned count = 1;\n\t\twhile (sc.chNext == '\\\\') {\n\t\t\t++count;\n\t\t\tsc.Forward();\n\t\t}\n\t\tbool escaped = count & 1U; // odd backslash escape next character\n\t\tif (escaped && (sc.chNext == '\\r' || sc.chNext == '\\n')) {\n\t\t\tlineContinuation = true;\n\t\t\tif (sc.state == SCE_SH_IDENTIFIER) {\n\t\t\t\tsc.SetState(SCE_SH_OPERATOR | insideCommand);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (backtickLevel > 0 && nestedBackticks) {\n\t\t\t/*\n\t\t\tfor $k$ level substitution with $N$ backslashes:\n\t\t\t* when $N/2^k$ is odd, following dollar is escaped.\n\t\t\t* when $(N - 1)/2^k$ is even, following quote is escaped.\n\t\t\t* when $N = n\\times 2^{k + 1} - 1$, following backtick is escaped.\n\t\t\t* when $N = n\\times 2^{k + 1} + 2^k - 1$, following backtick starts inner substitution.\n\t\t\t* when $N = m\\times 2^k + 2^{k - 1} - 1$ and $k > 1$, following backtick ends current substitution.\n\t\t\t*/\n\t\t\tif (sc.chNext == '$') {\n\t\t\t\tescaped = (count >> backtickLevel) & 1U;\n\t\t\t} else if (sc.chNext == '\\\"' || sc.chNext == '\\'') {\n\t\t\t\tescaped = (((count - 1) >> backtickLevel) & 1U) == 0;\n\t\t\t} else if (sc.chNext == '`' && escaped) {\n\t\t\t\tunsigned mask = 1U << (backtickLevel + 1);\n\t\t\t\tcount += 1;\n\t\t\t\tescaped = (count & (mask - 1)) == 0;\n\t\t\t\tif (!escaped) {\n\t\t\t\t\tunsigned remain = count - (mask >> 1U);\n\t\t\t\t\tif (static_cast<int>(remain) >= 0 && (remain & (mask - 1)) == 0) {\n\t\t\t\t\t\tescaped = true;\n\t\t\t\t\t\t++backtickLevel;\n\t\t\t\t\t} else if (backtickLevel > 1) {\n\t\t\t\t\t\tmask >>= 1U;\n\t\t\t\t\t\tremain = count - (mask >> 1U);\n\t\t\t\t\t\tif (static_cast<int>(remain) >= 0 && (remain & (mask - 1)) == 0) {\n\t\t\t\t\t\t\tescaped = true;\n\t\t\t\t\t\t\t--backtickLevel;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (escaped) {\n\t\t\tsc.Forward();\n\t\t}\n\t}\n};\n\nconst char styleSubable[] = { SCE_SH_IDENTIFIER, SCE_SH_SCALAR, 0 };\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer Bash SCLEX_BASH SCE_SH_:\n\t0, \"SCE_SH_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_SH_ERROR\", \"error\", \"Error\",\n\t2, \"SCE_SH_COMMENTLINE\", \"comment line\", \"Line comment: #\",\n\t3, \"SCE_SH_NUMBER\", \"literal numeric\", \"Number\",\n\t4, \"SCE_SH_WORD\", \"keyword\", \"Keyword\",\n\t5, \"SCE_SH_STRING\", \"literal string\", \"String\",\n\t6, \"SCE_SH_CHARACTER\", \"literal string\", \"Single quoted string\",\n\t7, \"SCE_SH_OPERATOR\", \"operator\", \"Operators\",\n\t8, \"SCE_SH_IDENTIFIER\", \"identifier\", \"Identifiers\",\n\t9, \"SCE_SH_SCALAR\", \"identifier\", \"Scalar variable\",\n\t10, \"SCE_SH_PARAM\", \"identifier\", \"Parameter\",\n\t11, \"SCE_SH_BACKTICKS\", \"literal string\", \"Backtick quoted command\",\n\t12, \"SCE_SH_HERE_DELIM\", \"operator\", \"Heredoc delimiter\",\n\t13, \"SCE_SH_HERE_Q\", \"here-doc literal string\", \"Heredoc quoted string\",\n};\n\n}\n\nclass LexerBash final : public DefaultLexer {\n\tWordList keywords;\n\tWordList cmdDelimiter;\n\tWordList bashStruct;\n\tWordList bashStruct_in;\n\tWordList testOperator;\n\tOptionsBash options;\n\tOptionSetBash osBash;\n\tCharacterSet setParamStart;\n\tenum { ssIdentifier, ssScalar };\n\tSubStyles subStyles{styleSubable};\npublic:\n\tLexerBash() :\n\t\tDefaultLexer(\"bash\", SCLEX_BASH, lexicalClasses, std::size(lexicalClasses)),\n\t\tsetParamStart(CharacterSet::setAlphaNum, \"_\" BASH_SPECIAL_PARAMETER) {\n\t\tcmdDelimiter.Set(\"| || |& & && ; ;; ( ) { }\");\n\t\tbashStruct.Set(\"if elif fi while until else then do done esac eval\");\n\t\tbashStruct_in.Set(\"for case select\");\n\t\ttestOperator.Set(\"eq ge gt le lt ne ef nt ot\");\n\t\tSetOptionSet(&osBash);\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {\n\t\treturn subStyles.Allocate(styleBase, numberStyles);\n\t}\n\tint SCI_METHOD SubStylesStart(int styleBase) override {\n\t\treturn subStyles.Start(styleBase);\n\t}\n\tint SCI_METHOD SubStylesLength(int styleBase) override {\n\t\treturn subStyles.Length(styleBase);\n\t}\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override {\n\t\tconst int styleBase = subStyles.BaseStyle(subStyle);\n\t\treturn styleBase;\n\t}\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) override {\n\t\treturn style;\n\t}\n\tvoid SCI_METHOD FreeSubStyles() override {\n\t\tsubStyles.Free();\n\t}\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {\n\t\tsubStyles.SetIdentifiers(style, identifiers);\n\t}\n\tint SCI_METHOD DistanceToSecondaryStyles() override {\n\t\treturn 0;\n\t}\n\tconst char *SCI_METHOD GetSubStyleBases() override {\n\t\treturn styleSubable;\n\t}\n\n\tbool IsTestOperator(const char *s, const CharacterSet &setSingleCharOp) const noexcept {\n\t\treturn (s[2] == '\\0' && setSingleCharOp.Contains(s[1]))\n\t\t\t|| testOperator.InList(s + 1);\n\t}\n\n\tstatic ILexer5 *LexerFactoryBash() {\n\t\treturn new LexerBash();\n\t}\n};\n\nSci_Position SCI_METHOD LexerBash::PropertySet(const char *key, const char *val) {\n\tif (osBash.PropertySet(&options, key, val)) {\n\t\tif (strcmp(key, \"lexer.bash.special.parameter\") == 0) {\n\t\t\tsetParamStart = CharacterSet(CharacterSet::setAlphaNum, \"_\");\n\t\t\tsetParamStart.AddString(options.specialParameter.empty() ? BASH_SPECIAL_PARAMETER : options.specialParameter.c_str());\n\t\t}\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerBash::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tconst CharacterSet setWordStart(CharacterSet::setAlpha, \"_\");\n\t// note that [+-] are often parts of identifiers in shell scripts\n\tconst CharacterSet setWord(CharacterSet::setAlphaNum, \"._+-\");\n\tCharacterSet setMetaCharacter(CharacterSet::setNone, \"|&;()<> \\t\\r\\n\");\n\tsetMetaCharacter.Add(0);\n\tconst CharacterSet setBashOperator(CharacterSet::setNone, \"^&%()-+=|{}[]:;>,*/<?!.~@\");\n\tconst CharacterSet setSingleCharOp(CharacterSet::setNone, \"rwxoRWXOezsfdlpSbctugkTBMACahGLNn\");\n\tconst CharacterSet setParam(CharacterSet::setAlphaNum, \"_\");\n\tconst CharacterSet setHereDoc(CharacterSet::setAlpha, \"_\\\\-+!%*,./:?@[]^`{}~\");\n\tconst CharacterSet setHereDoc2(CharacterSet::setAlphaNum, \"_-+!%*,./:=?@[]^`{}~\");\n\tconst CharacterSet setLeftShift(CharacterSet::setDigits, \"$\");\n\n\tclass HereDocCls {\t// Class to manage HERE document elements\n\tpublic:\n\t\tint State = 0;\t\t\t// 0: '<<' encountered\n\t\t// 1: collect the delimiter\n\t\t// 2: here doc text (lines after the delimiter)\n\t\tint Quote = '\\0';\t\t// the char after '<<'\n\t\tbool Quoted = false;\t\t// true if Quote in ('\\'','\"','`')\n\t\tbool Escaped = false;\t\t// backslash in delimiter, common in configure script\n\t\tbool Indent = false;\t\t// indented delimiter (for <<-)\n\t\tint BackslashCount = 0;\n\t\tint DelimiterLength = 0;\t// strlen(Delimiter)\n\t\tchar Delimiter[HERE_DELIM_MAX]{};\t// the Delimiter\n\t\tHereDocCls() noexcept = default;\n\t\tvoid Append(int ch) {\n\t\t\tDelimiter[DelimiterLength++] = static_cast<char>(ch);\n\t\t\tDelimiter[DelimiterLength] = '\\0';\n\t\t}\n\t};\n\tHereDocCls HereDoc;\n\n\tQuoteStackCls QuoteStack(setParamStart);\n\tQuoteStack.nestedBackticks = options.nestedBackticks;\n\tQuoteStack.commandSubstitution = options.commandSubstitution;\n\n\tconst WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_SH_IDENTIFIER);\n\tconst WordClassifier &classifierScalars = subStyles.Classifier(SCE_SH_SCALAR);\n\n\tint numBase = 0;\n\tint digit = 0;\n\tconst Sci_PositionU endPos = startPos + length;\n\tCmdState cmdState = CmdState::Start;\n\tLexAccessor styler(pAccess);\n\n\t// Always backtracks to the start of a line that is not a continuation\n\t// of the previous line (i.e. start of a bash command segment)\n\tSci_Position ln = styler.GetLine(startPos);\n\tif (ln > 0 && startPos == static_cast<Sci_PositionU>(styler.LineStart(ln)))\n\t\tln--;\n\tfor (;;) {\n\t\tstartPos = styler.LineStart(ln);\n\t\tif (ln == 0 || styler.GetLineState(ln) == static_cast<int>(CmdState::Start))\n\t\t\tbreak;\n\t\tln--;\n\t}\n\tinitStyle = SCE_SH_DEFAULT;\n\n\tStyleContext sc(startPos, endPos - startPos, initStyle, styler);\n\n\twhile (sc.More()) {\n\n\t\t// handle line continuation, updates per-line stored state\n\t\tif (sc.atLineStart) {\n\t\t\tCmdState state = CmdState::Body;\t// force backtrack while retaining cmdState\n\t\t\tif (!StyleForceBacktrack(MaskCommand(sc.state))) {\n\t\t\t\t// retain last line's state\n\t\t\t\t// arithmetic expression and double bracket test can span multiline without line continuation\n\t\t\t\tif (!QuoteStack.lineContinuation && !AnyOf(cmdState, CmdState::DoubleBracket, CmdState::Arithmetic)) {\n\t\t\t\t\tcmdState = CmdState::Start;\n\t\t\t\t}\n\t\t\t\tif (QuoteStack.Empty()) {\t// force backtrack when nesting\n\t\t\t\t\tstate = cmdState;\n\t\t\t\t}\n\t\t\t}\n\t\t\tQuoteStack.lineContinuation = false;\n\t\t\tstyler.SetLineState(sc.currentLine, static_cast<int>(state));\n\t\t}\n\n\t\t// controls change of cmdState at the end of a non-whitespace element\n\t\t// states Body|Test|Arithmetic persist until the end of a command segment\n\t\t// state Word persist, but ends with 'in' or 'do' construct keywords\n\t\tCmdState cmdStateNew = CmdState::Body;\n\t\tif (cmdState >= CmdState::Word && cmdState <= CmdState::Arithmetic)\n\t\t\tcmdStateNew = cmdState;\n\t\tconst int stylePrev = MaskCommand(sc.state);\n\t\tconst int insideCommand = QuoteStack.insideCommand;\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (MaskCommand(sc.state)) {\n\t\t\tcase SCE_SH_OPERATOR:\n\t\t\t\tsc.SetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\tif (cmdState == CmdState::Delimiter)\t\t// if command delimiter, start new command\n\t\t\t\t\tcmdStateNew = CmdState::Start;\n\t\t\t\telse if (sc.chPrev == '\\\\')\t\t\t// propagate command state if line continued\n\t\t\t\t\tcmdStateNew = cmdState;\n\t\t\t\tbreak;\n\t\t\tcase SCE_SH_WORD:\n\t\t\t\t// \".\" never used in Bash variable names but used in file names\n\t\t\t\tif (!setWord.Contains(sc.ch) || sc.Match('+', '=') || sc.Match('.', '.')) {\n\t\t\t\t\tchar s[500];\n\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\tint identifierStyle = SCE_SH_IDENTIFIER | insideCommand;\n\t\t\t\t\tconst int subStyle = classifierIdentifiers.ValueFor(s);\n\t\t\t\t\tif (subStyle >= 0) {\n\t\t\t\t\t\tidentifierStyle = subStyle | insideCommand;\n\t\t\t\t\t}\n\t\t\t\t\t// allow keywords ending in a whitespace, meta character or command delimiter\n\t\t\t\t\tchar s2[10]{};\n\t\t\t\t\ts2[0] = static_cast<char>(sc.ch);\n\t\t\t\t\ts2[1] = '\\0';\n\t\t\t\t\tconst bool keywordEnds = IsASpace(sc.ch) || setMetaCharacter.Contains(sc.ch) || cmdDelimiter.InList(s2);\n\t\t\t\t\t// 'in' or 'do' may be construct keywords\n\t\t\t\t\tif (cmdState == CmdState::Word) {\n\t\t\t\t\t\tif (strcmp(s, \"in\") == 0 && keywordEnds)\n\t\t\t\t\t\t\tcmdStateNew = CmdState::Body;\n\t\t\t\t\t\telse if (strcmp(s, \"do\") == 0 && keywordEnds)\n\t\t\t\t\t\t\tcmdStateNew = CmdState::Start;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsc.ChangeState(identifierStyle);\n\t\t\t\t\t\tsc.SetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t// a 'test' keyword starts a test expression\n\t\t\t\t\tif (strcmp(s, \"test\") == 0) {\n\t\t\t\t\t\tif (cmdState == CmdState::Start && keywordEnds) {\n\t\t\t\t\t\t\tcmdStateNew = CmdState::Test;\n\t\t\t\t\t\t} else\n\t\t\t\t\t\t\tsc.ChangeState(identifierStyle);\n\t\t\t\t\t}\n\t\t\t\t\t// detect bash construct keywords\n\t\t\t\t\telse if (bashStruct.InList(s)) {\n\t\t\t\t\t\tif (cmdState == CmdState::Start && keywordEnds)\n\t\t\t\t\t\t\tcmdStateNew = CmdState::Start;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsc.ChangeState(identifierStyle);\n\t\t\t\t\t}\n\t\t\t\t\t// 'for'|'case'|'select' needs 'in'|'do' to be highlighted later\n\t\t\t\t\telse if (bashStruct_in.InList(s)) {\n\t\t\t\t\t\tif (cmdState == CmdState::Start && keywordEnds)\n\t\t\t\t\t\t\tcmdStateNew = CmdState::Word;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsc.ChangeState(identifierStyle);\n\t\t\t\t\t}\n\t\t\t\t\t// disambiguate option items and file test operators\n\t\t\t\t\telse if (s[0] == '-') {\n\t\t\t\t\t\tif (!AnyOf(cmdState, CmdState::Test, CmdState::SingleBracket, CmdState::DoubleBracket)\n\t\t\t\t\t\t\t  || !keywordEnds || !IsTestOperator(s, setSingleCharOp))\n\t\t\t\t\t\t\tsc.ChangeState(identifierStyle);\n\t\t\t\t\t}\n\t\t\t\t\t// disambiguate keywords and identifiers\n\t\t\t\t\telse if (cmdState != CmdState::Start\n\t\t\t\t\t\t  || !(keywords.InList(s) && keywordEnds)) {\n\t\t\t\t\t\tsc.ChangeState(identifierStyle);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_SH_IDENTIFIER:\n\t\t\t\tif (!setWord.Contains(sc.ch) ||\n\t\t\t\t\t  (cmdState == CmdState::Arithmetic && !setWordStart.Contains(sc.ch))) {\n\t\t\t\t\tchar s[500];\n\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\tconst int subStyle = classifierIdentifiers.ValueFor(s);\n\t\t\t\t\tif (subStyle >= 0) {\n\t\t\t\t\t\tsc.ChangeState(subStyle | insideCommand);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_SH_NUMBER:\n\t\t\t\tdigit = translateBashDigit(sc.ch);\n\t\t\t\tif (numBase == BASH_BASE_DECIMAL) {\n\t\t\t\t\tif (sc.ch == '#') {\n\t\t\t\t\t\tchar s[10];\n\t\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\t\tnumBase = getBashNumberBase(s);\n\t\t\t\t\t\tif (numBase != BASH_BASE_ERROR)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (IsADigit(sc.ch))\n\t\t\t\t\t\tbreak;\n\t\t\t\t} else if (numBase == BASH_BASE_HEX) {\n\t\t\t\t\tif (IsADigit(sc.ch, 16))\n\t\t\t\t\t\tbreak;\n#ifdef PEDANTIC_OCTAL\n\t\t\t\t} else if (numBase == BASH_BASE_OCTAL ||\n\t\t\t\t\t\t   numBase == BASH_BASE_OCTAL_ERROR) {\n\t\t\t\t\tif (digit <= 7)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (digit <= 9) {\n\t\t\t\t\t\tnumBase = BASH_BASE_OCTAL_ERROR;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n#endif\n\t\t\t\t} else if (numBase == BASH_BASE_ERROR) {\n\t\t\t\t\tif (digit <= 9)\n\t\t\t\t\t\tbreak;\n\t\t\t\t} else {\t// DD#DDDD number style handling\n\t\t\t\t\tif (digit != BASH_BASE_ERROR) {\n\t\t\t\t\t\tif (numBase <= 36) {\n\t\t\t\t\t\t\t// case-insensitive if base<=36\n\t\t\t\t\t\t\tif (digit >= 36) digit -= 26;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (digit < numBase)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tif (digit <= 9) {\n\t\t\t\t\t\t\tnumBase = BASH_BASE_ERROR;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// fallthrough when number is at an end or error\n\t\t\t\tif (numBase == BASH_BASE_ERROR\n#ifdef PEDANTIC_OCTAL\n\t\t\t\t\t|| numBase == BASH_BASE_OCTAL_ERROR\n#endif\n\t\t\t\t) {\n\t\t\t\t\tsc.ChangeState(SCE_SH_ERROR | insideCommand);\n\t\t\t\t} else if (digit < 62 || digit == 63 || (cmdState != CmdState::Arithmetic &&\n\t\t\t\t\t(sc.ch == '-' || (sc.ch == '.' && sc.chNext != '.')))) {\n\t\t\t\t\t// current character is alpha numeric, underscore, hyphen or dot\n\t\t\t\t\tsc.ChangeState(SCE_SH_IDENTIFIER | insideCommand);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\tbreak;\n\t\t\tcase SCE_SH_COMMENTLINE:\n\t\t\t\tif (sc.MatchLineEnd()) {\n\t\t\t\t\tsc.SetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_SH_HERE_DELIM:\n\t\t\t\t// From Bash info:\n\t\t\t\t// ---------------\n\t\t\t\t// Specifier format is: <<[-]WORD\n\t\t\t\t// Optional '-' is for removal of leading tabs from here-doc.\n\t\t\t\t// Whitespace acceptable after <<[-] operator\n\t\t\t\t//\n\t\t\t\tif (HereDoc.State == 0) { // '<<' encountered\n\t\t\t\t\tHereDoc.Quote = sc.chNext;\n\t\t\t\t\tHereDoc.Quoted = false;\n\t\t\t\t\tHereDoc.Escaped = false;\n\t\t\t\t\tHereDoc.BackslashCount = 0;\n\t\t\t\t\tHereDoc.DelimiterLength = 0;\n\t\t\t\t\tHereDoc.Delimiter[HereDoc.DelimiterLength] = '\\0';\n\t\t\t\t\tif (sc.chNext == '\\'' || sc.chNext == '\\\"') {\t// a quoted here-doc delimiter (' or \")\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\tHereDoc.Quoted = true;\n\t\t\t\t\t\tHereDoc.State = 1;\n\t\t\t\t\t} else if (setHereDoc.Contains(sc.chNext) ||\n\t\t\t\t\t           (sc.chNext == '=' && cmdState != CmdState::Arithmetic)) {\n\t\t\t\t\t\t// an unquoted here-doc delimiter, no special handling\n\t\t\t\t\t\tHereDoc.State = 1;\n\t\t\t\t\t} else if (sc.chNext == '<') {\t// HERE string <<<\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\tsc.ForwardSetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\t\t} else if (IsASpace(sc.chNext)) {\n\t\t\t\t\t\t// eat whitespace\n\t\t\t\t\t} else if (setLeftShift.Contains(sc.chNext) ||\n\t\t\t\t\t           (sc.chNext == '=' && cmdState == CmdState::Arithmetic)) {\n\t\t\t\t\t\t// left shift <<$var or <<= cases\n\t\t\t\t\t\tsc.ChangeState(SCE_SH_OPERATOR | insideCommand);\n\t\t\t\t\t\tsc.ForwardSetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// symbols terminates; deprecated zero-length delimiter\n\t\t\t\t\t\tHereDoc.State = 1;\n\t\t\t\t\t}\n\t\t\t\t} else if (HereDoc.State == 1) { // collect the delimiter\n\t\t\t\t\t// * if single quoted, there's no escape\n\t\t\t\t\t// * if double quoted, there are \\\\ and \\\" escapes\n\t\t\t\t\tif (HereDoc.Quoted && sc.ch == HereDoc.Quote && (HereDoc.BackslashCount & 1) == 0) { // closing quote => end of delimiter\n\t\t\t\t\t\tsc.ForwardSetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\t\t} else if (sc.ch == '\\\\' && HereDoc.Quote != '\\'') {\n\t\t\t\t\t\tHereDoc.Escaped = true;\n\t\t\t\t\t\tHereDoc.BackslashCount += 1;\n\t\t\t\t\t\tif ((HereDoc.BackslashCount & 1) == 0 || (HereDoc.Quoted && !AnyOf(sc.chNext, '\\\"', '\\\\'))) {\n\t\t\t\t\t\t\t// in quoted prefixes only \\ and the quote eat the escape\n\t\t\t\t\t\t\tHereDoc.Append(sc.ch);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// skip escape prefix\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (HereDoc.Quoted || setHereDoc2.Contains(sc.ch) || (sc.ch > 32 && sc.ch < 127 && (HereDoc.BackslashCount & 1) != 0)) {\n\t\t\t\t\t\tHereDoc.BackslashCount = 0;\n\t\t\t\t\t\tHereDoc.Append(sc.ch);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\t\t}\n\t\t\t\t\tif (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {\t// force blowup\n\t\t\t\t\t\tsc.SetState(SCE_SH_ERROR | insideCommand);\n\t\t\t\t\t\tHereDoc.State = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_SH_SCALAR:\t// variable names\n\t\t\t\tif (!setParam.Contains(sc.ch)) {\n\t\t\t\t\tchar s[500];\n\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\tconst int subStyle = classifierScalars.ValueFor(&s[1]); // skip the $\n\t\t\t\t\tif (subStyle >= 0) {\n\t\t\t\t\t\tsc.ChangeState(subStyle | insideCommand);\n\t\t\t\t\t}\n\t\t\t\t\tif (sc.LengthCurrent() == 1) {\n\t\t\t\t\t\t// Special variable\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(QuoteStack.State | insideCommand);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_SH_HERE_Q:\n\t\t\t\t// HereDoc.State == 2\n\t\t\t\tif (sc.atLineStart && QuoteStack.Current.Style == QuoteStyle::HereDoc) {\n\t\t\t\t\tsc.SetState(SCE_SH_HERE_Q | insideCommand);\n\t\t\t\t\tif (HereDoc.Indent) { // tabulation prefix\n\t\t\t\t\t\twhile (sc.ch == '\\t') {\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ((static_cast<Sci_Position>(sc.currentPos + HereDoc.DelimiterLength) == sc.lineEnd) &&\n\t\t\t\t\t\t(HereDoc.DelimiterLength == 0 || sc.Match(HereDoc.Delimiter))) {\n\t\t\t\t\t\tif (HereDoc.DelimiterLength != 0) {\n\t\t\t\t\t\t\tsc.SetState(SCE_SH_HERE_DELIM | insideCommand);\n\t\t\t\t\t\t\twhile (!sc.MatchLineEnd()) {\n\t\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tQuoteStack.Pop();\n\t\t\t\t\t\tsc.SetState(SCE_SH_DEFAULT | QuoteStack.insideCommand);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (HereDoc.Quoted || HereDoc.Escaped) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// fall through to handle nested shell expansions\n\t\t\t\t[[fallthrough]];\n\t\t\tcase SCE_SH_STRING:\t// delimited styles, can nest\n\t\t\tcase SCE_SH_PARAM: // ${parameter}\n\t\t\tcase SCE_SH_BACKTICKS:\n\t\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t\tif (QuoteStack.Current.Style != QuoteStyle::Literal)\n\t\t\t\t\t\tQuoteStack.Escape(sc);\n\t\t\t\t} else if (sc.ch == QuoteStack.Current.Down) {\n\t\t\t\t\tif (QuoteStack.CountDown(sc, cmdState)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == QuoteStack.Current.Up) {\n\t\t\t\t\tif (QuoteStack.Current.Style != QuoteStyle::Parameter) {\n\t\t\t\t\t\tQuoteStack.Current.Count++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (QuoteStack.Current.Style == QuoteStyle::String ||\n\t\t\t\t\t\tQuoteStack.Current.Style == QuoteStyle::HereDoc ||\n\t\t\t\t\t\tQuoteStack.Current.Style == QuoteStyle::LString\n\t\t\t\t\t) {\t// do nesting for \"string\", $\"locale-string\", heredoc\n\t\t\t\t\t\tconst bool stylingInside = options.stylingInside(MaskCommand(sc.state));\n\t\t\t\t\t\tif (sc.ch == '`') {\n\t\t\t\t\t\t\tQuoteStack.Push(sc.ch, QuoteStyle::Backtick, sc.state, cmdState);\n\t\t\t\t\t\t\tif (stylingInside) {\n\t\t\t\t\t\t\t\tsc.SetState(SCE_SH_BACKTICKS | insideCommand);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.ch == '$' && !AnyOf(sc.chNext, '\\\"', '\\'')) {\n\t\t\t\t\t\t\tQuoteStack.Expand(sc, cmdState, stylingInside);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (QuoteStack.Current.Style == QuoteStyle::Command ||\n\t\t\t\t\t\t\t   QuoteStack.Current.Style == QuoteStyle::Parameter ||\n\t\t\t\t\t\t\t   QuoteStack.Current.Style == QuoteStyle::Backtick\n\t\t\t\t\t) {\t// do nesting for $(command), `command`, ${parameter}\n\t\t\t\t\t\tconst bool stylingInside = options.stylingInside(MaskCommand(sc.state));\n\t\t\t\t\t\tif (sc.ch == '\\'') {\n\t\t\t\t\t\t\tif (stylingInside) {\n\t\t\t\t\t\t\t\tQuoteStack.State = sc.state;\n\t\t\t\t\t\t\t\tsc.SetState(SCE_SH_CHARACTER | insideCommand);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tQuoteStack.Push(sc.ch, QuoteStyle::Literal, sc.state, cmdState);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\t\t\tQuoteStack.Push(sc.ch, QuoteStyle::String, sc.state, cmdState);\n\t\t\t\t\t\t\tif (stylingInside) {\n\t\t\t\t\t\t\t\tsc.SetState(SCE_SH_STRING | insideCommand);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.ch == '`') {\n\t\t\t\t\t\t\tQuoteStack.Push(sc.ch, QuoteStyle::Backtick, sc.state, cmdState);\n\t\t\t\t\t\t\tif (stylingInside) {\n\t\t\t\t\t\t\t\tsc.SetState(SCE_SH_BACKTICKS | insideCommand);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.ch == '$') {\n\t\t\t\t\t\t\tQuoteStack.Expand(sc, cmdState, stylingInside);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_SH_CHARACTER: // singly-quoted strings\n\t\t\t\tif (sc.ch == '\\'') {\n\t\t\t\t\tsc.ForwardSetState(QuoteStack.State | insideCommand);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Must check end of HereDoc state 1 before default state is handled\n\t\tif (HereDoc.State == 1 && sc.MatchLineEnd()) {\n\t\t\t// Begin of here-doc (the line after the here-doc delimiter):\n\t\t\t// Lexically, the here-doc starts from the next line after the >>, but the\n\t\t\t// first line of here-doc seem to follow the style of the last EOL sequence\n\t\t\tHereDoc.State = 2;\n\t\t\tif (HereDoc.Quoted) {\n\t\t\t\tif (MaskCommand(sc.state) == SCE_SH_HERE_DELIM) {\n\t\t\t\t\t// Missing quote at end of string! Syntax error in bash 4.3\n\t\t\t\t\t// Mark this bit as an error, do not colour any here-doc\n\t\t\t\t\tsc.ChangeState(SCE_SH_ERROR | insideCommand);\n\t\t\t\t\tsc.SetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t\t} else {\n\t\t\t\t\t// HereDoc.Quote always == '\\''\n\t\t\t\t\tsc.SetState(SCE_SH_HERE_Q | insideCommand);\n\t\t\t\t\tQuoteStack.Start(-1, QuoteStyle::HereDoc, SCE_SH_DEFAULT, cmdState);\n\t\t\t\t}\n\t\t\t} else if (HereDoc.DelimiterLength == 0) {\n\t\t\t\t// no delimiter, illegal (but '' and \"\" are legal)\n\t\t\t\tsc.ChangeState(SCE_SH_ERROR | insideCommand);\n\t\t\t\tsc.SetState(SCE_SH_DEFAULT | insideCommand);\n\t\t\t} else {\n\t\t\t\tsc.SetState(SCE_SH_HERE_Q | insideCommand);\n\t\t\t\tQuoteStack.Start(-1, QuoteStyle::HereDoc, SCE_SH_DEFAULT, cmdState);\n\t\t\t}\n\t\t}\n\n\t\t// update cmdState about the current command segment\n\t\tif (stylePrev != SCE_SH_DEFAULT && MaskCommand(sc.state) == SCE_SH_DEFAULT) {\n\t\t\tcmdState = cmdStateNew;\n\t\t}\n\t\t// Determine if a new state should be entered.\n\t\tif (MaskCommand(sc.state) == SCE_SH_DEFAULT) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t// Bash can escape any non-newline as a literal\n\t\t\t\tsc.SetState(SCE_SH_IDENTIFIER | insideCommand);\n\t\t\t\tQuoteStack.Escape(sc);\n\t\t\t} else if (IsADigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_SH_NUMBER | insideCommand);\n\t\t\t\tnumBase = BASH_BASE_DECIMAL;\n\t\t\t\tif (sc.ch == '0') {\t// hex,octal\n\t\t\t\t\tif (sc.chNext == 'x' || sc.chNext == 'X') {\n\t\t\t\t\t\tnumBase = BASH_BASE_HEX;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else if (IsADigit(sc.chNext)) {\n#ifdef PEDANTIC_OCTAL\n\t\t\t\t\t\tnumBase = BASH_BASE_OCTAL;\n#endif\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (setWordStart.Contains(sc.ch)) {\n\t\t\t\tsc.SetState(((cmdState == CmdState::Arithmetic)? SCE_SH_IDENTIFIER : SCE_SH_WORD) | insideCommand);\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tif (stylePrev != SCE_SH_WORD && stylePrev != SCE_SH_IDENTIFIER &&\n\t\t\t\t\t(sc.currentPos == 0 || setMetaCharacter.Contains(sc.chPrev))) {\n\t\t\t\t\tsc.SetState(SCE_SH_COMMENTLINE | insideCommand);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_SH_WORD | insideCommand);\n\t\t\t\t}\n\t\t\t\t// handle some zsh features within arithmetic expressions only\n\t\t\t\tif (cmdState == CmdState::Arithmetic) {\n\t\t\t\t\tif (sc.chPrev == '[') {\t// [#8] [##8] output digit setting\n\t\t\t\t\t\tsc.SetState(SCE_SH_WORD | insideCommand);\n\t\t\t\t\t\tif (sc.chNext == '#') {\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (sc.Match(\"##^\") && IsUpperCase(sc.GetRelative(3))) {\t// ##^A\n\t\t\t\t\t\tsc.SetState(SCE_SH_IDENTIFIER | insideCommand);\n\t\t\t\t\t\tsc.Forward(3);\n\t\t\t\t\t} else if (sc.chNext == '#' && !IsASpace(sc.GetRelative(2))) {\t// ##a\n\t\t\t\t\t\tsc.SetState(SCE_SH_IDENTIFIER | insideCommand);\n\t\t\t\t\t\tsc.Forward(2);\n\t\t\t\t\t} else if (setWordStart.Contains(sc.chNext)) {\t// #name\n\t\t\t\t\t\tsc.SetState(SCE_SH_IDENTIFIER | insideCommand);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_SH_STRING | insideCommand);\n\t\t\t\tQuoteStack.Start(sc.ch, QuoteStyle::String, SCE_SH_DEFAULT, cmdState);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tQuoteStack.State = SCE_SH_DEFAULT;\n\t\t\t\tsc.SetState(SCE_SH_CHARACTER | insideCommand);\n\t\t\t} else if (sc.ch == '`') {\n\t\t\t\tsc.SetState(SCE_SH_BACKTICKS | insideCommand);\n\t\t\t\tQuoteStack.Start(sc.ch, QuoteStyle::Backtick, SCE_SH_DEFAULT, cmdState);\n\t\t\t} else if (sc.ch == '$') {\n\t\t\t\tQuoteStack.Expand(sc, cmdState, true);\n\t\t\t\tcontinue;\n\t\t\t} else if (cmdState != CmdState::Arithmetic && sc.Match('<', '<')) {\n\t\t\t\tsc.SetState(SCE_SH_HERE_DELIM | insideCommand);\n\t\t\t\tHereDoc.State = 0;\n\t\t\t\tif (sc.GetRelative(2) == '-') {\t// <<- indent case\n\t\t\t\t\tHereDoc.Indent = true;\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tHereDoc.Indent = false;\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '-' && // test operator or short and long option\n\t\t\t\t\t   cmdState != CmdState::Arithmetic &&\n\t\t\t\t\t   sc.chPrev != '~' && !IsADigit(sc.chNext)) {\n\t\t\t\tif (IsASpace(sc.chPrev) || setMetaCharacter.Contains(sc.chPrev)) {\n\t\t\t\t\tsc.SetState(SCE_SH_WORD | insideCommand);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_SH_IDENTIFIER | insideCommand);\n\t\t\t\t}\n\t\t\t} else if (setBashOperator.Contains(sc.ch)) {\n\t\t\t\tbool isCmdDelim = false;\n\t\t\t\tsc.SetState(SCE_SH_OPERATOR | insideCommand);\n\t\t\t\t// arithmetic expansion and command substitution\n\t\t\t\tif (QuoteStack.Current.Style == QuoteStyle::Arithmetic || QuoteStack.Current.Style == QuoteStyle::CommandInside) {\n\t\t\t\t\tif (sc.ch == QuoteStack.Current.Down) {\n\t\t\t\t\t\tif (QuoteStack.CountDown(sc, cmdState)) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (sc.ch == QuoteStack.Current.Up) {\n\t\t\t\t\t\tQuoteStack.Current.Count++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// globs have no whitespace, do not appear in arithmetic expressions\n\t\t\t\tif (cmdState != CmdState::Arithmetic && sc.ch == '(' && sc.chNext != '(') {\n\t\t\t\t\tconst int i = GlobScan(sc);\n\t\t\t\t\tif (i > 1) {\n\t\t\t\t\t\tsc.SetState(SCE_SH_IDENTIFIER | insideCommand);\n\t\t\t\t\t\tsc.Forward(i + 1);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// handle opening delimiters for test/arithmetic expressions - ((,[[,[\n\t\t\t\tif (cmdState == CmdState::Start\n\t\t\t\t || cmdState == CmdState::Body) {\n\t\t\t\t\tif (sc.Match('(', '(')) {\n\t\t\t\t\t\tcmdState = CmdState::Arithmetic;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else if (sc.Match('[', '[') && IsASpace(sc.GetRelative(2))) {\n\t\t\t\t\t\tcmdState = CmdState::DoubleBracket;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else if (sc.ch == '[' && IsASpace(sc.chNext)) {\n\t\t\t\t\t\tcmdState = CmdState::SingleBracket;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// special state -- for ((x;y;z)) in ... looping\n\t\t\t\tif (cmdState == CmdState::Word && sc.Match('(', '(')) {\n\t\t\t\t\tcmdState = CmdState::Arithmetic;\n\t\t\t\t\tsc.Forward(2);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// handle command delimiters in command Start|Body|Word state, also Test if 'test' or '[]'\n\t\t\t\tif (cmdState < CmdState::DoubleBracket) {\n\t\t\t\t\tchar s[10]{};\n\t\t\t\t\ts[0] = static_cast<char>(sc.ch);\n\t\t\t\t\tif (setBashOperator.Contains(sc.chNext)) {\n\t\t\t\t\t\ts[1] = static_cast<char>(sc.chNext);\n\t\t\t\t\t\ts[2] = '\\0';\n\t\t\t\t\t\tisCmdDelim = cmdDelimiter.InList(s);\n\t\t\t\t\t\tif (isCmdDelim)\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tif (!isCmdDelim) {\n\t\t\t\t\t\ts[1] = '\\0';\n\t\t\t\t\t\tisCmdDelim = cmdDelimiter.InList(s);\n\t\t\t\t\t}\n\t\t\t\t\tif (isCmdDelim) {\n\t\t\t\t\t\tcmdState = CmdState::Delimiter;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// handle closing delimiters for test/arithmetic expressions - )),]],]\n\t\t\t\tif (cmdState == CmdState::Arithmetic && sc.Match(')', ')')) {\n\t\t\t\t\tcmdState = CmdState::Body;\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (sc.ch == ']' && IsASpace(sc.chPrev)) {\n\t\t\t\t\tif (cmdState == CmdState::SingleBracket) {\n\t\t\t\t\t\tcmdState = CmdState::Body;\n\t\t\t\t\t} else if (cmdState == CmdState::DoubleBracket && sc.chNext == ']') {\n\t\t\t\t\t\tcmdState = CmdState::Body;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}// sc.state\n\n\t\tsc.Forward();\n\t}\n\tsc.Complete();\n\tif (MaskCommand(sc.state) == SCE_SH_HERE_Q) {\n\t\tstyler.ChangeLexerState(sc.currentPos, styler.Length());\n\t}\n\tsc.Complete();\n}\n\nvoid SCI_METHOD LexerBash::Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tif(!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\n\tSci_Position startPos = startPos_;\n\tconst Sci_Position endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\t// Backtrack to previous line in case need to fix its fold status\n\tif (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tstartPos = styler.LineStart(lineCurrent);\n\t\tinitStyle = (startPos > 0) ? styler.StyleIndexAt(startPos - 1) : 0;\n\t}\n\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = MaskCommand(styler.StyleIndexAt(startPos));\n\tint style = MaskCommand(initStyle);\n\tchar word[8] = { '\\0' }; // we're not interested in long words anyway\n\tsize_t wordlen = 0;\n\tfor (Sci_Position i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = MaskCommand(styler.StyleIndexAt(i + 1));\n\t\tconst bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\t// Comment folding\n\t\tif (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler))\n\t\t{\n\t\t\tif (!IsCommentLine(lineCurrent - 1, styler)\n\t\t\t\t&& IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (IsCommentLine(lineCurrent - 1, styler)\n\t\t\t\t\t && !IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelCurrent--;\n\t\t}\n\n\t\tswitch (style) {\n\t\tcase SCE_SH_WORD:\n\t\t\tif ((wordlen + 1) < sizeof(word))\n\t\t\t\tword[wordlen++] = ch;\n\t\t\tif (styleNext != style) {\n\t\t\t\tword[wordlen] = '\\0';\n\t\t\t\twordlen = 0;\n\t\t\t\tif (InList(word, {\"if\", \"case\", \"do\"})) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t} else if (InList(word, {\"fi\", \"esac\", \"done\"})) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_SH_OPERATOR:\n\t\t\tif (ch == '{') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t\tbreak;\n\n\t\t// Here Document folding\n\t\tcase SCE_SH_HERE_DELIM:\n\t\t\tif (stylePrev == SCE_SH_HERE_Q) {\n\t\t\t\tlevelCurrent--;\n\t\t\t} else if (stylePrev != SCE_SH_HERE_DELIM) {\n\t\t\t\tif (ch == '<' && chNext == '<') {\n\t\t\t\t\tif (styler.SafeGetCharAt(i + 2) != '<') {\n\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SH_HERE_Q:\n\t\t\tif (styleNext == SCE_SH_DEFAULT) {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tconst int lev = levelPrev |\n\t\t\t\tFoldLevelFlags(levelPrev, levelCurrent, visibleChars == 0 && options.foldCompact, visibleChars > 0);\n\t\t\tstyler.SetLevelIfDifferent(lineCurrent, lev);\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tconst int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nextern const LexerModule lmBash(SCLEX_BASH, LexerBash::LexerFactoryBash, \"bash\", bashWordListDesc);\n"
  },
  {
    "path": "lexers/LexBasic.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexBasic.cxx\n ** Lexer for BlitzBasic and PureBasic.\n ** Converted to lexer object and added further folding features/properties by \"Udo Lechner\" <dlchnr(at)gmx(dot)net>\n **/\n// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// This tries to be a unified Lexer/Folder for all the BlitzBasic/BlitzMax/PurBasic basics\n// and derivatives. Once they diverge enough, might want to split it into multiple\n// lexers for more code clearity.\n//\n// Mail me (elias <at> users <dot> sf <dot> net) for any bugs.\n\n// Folding only works for simple things like functions or types.\n\n// You may want to have a look at my ctags lexer as well, if you additionally to coloring\n// and folding need to extract things like label tags in your editor.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\n/* Bits:\n * 1  - whitespace\n * 2  - operator\n * 4  - identifier\n * 8  - decimal digit\n * 16 - hex digit\n * 32 - bin digit\n * 64 - letter\n */\nstatic int character_classification[128] =\n{\n\t\t0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  1,  0,  0,\n\t\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n\t\t1,  2,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  10, 2,\n\t 60, 60, 28, 28, 28, 28, 28, 28, 28, 28,  2,  2,  2,  2,  2,  2,\n\t\t2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68,\n\t 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,  2,  2,  2,  2, 68,\n\t\t2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68,\n\t 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,  2,  2,  2,  2,  0\n};\n\nstatic bool IsSpace(int c) {\n\treturn c < 128 && (character_classification[c] & 1);\n}\n\nstatic bool IsOperator(int c) {\n\treturn c < 128 && (character_classification[c] & 2);\n}\n\nstatic bool IsIdentifier(int c) {\n\treturn c < 128 && (character_classification[c] & 4);\n}\n\nstatic bool IsDigit(int c) {\n\treturn c < 128 && (character_classification[c] & 8);\n}\n\nstatic bool IsHexDigit(int c) {\n\treturn c < 128 && (character_classification[c] & 16);\n}\n\nstatic bool IsBinDigit(int c) {\n\treturn c < 128 && (character_classification[c] & 32);\n}\n\nstatic bool IsLetter(int c) {\n\treturn c < 128 && (character_classification[c] & 64);\n}\n\nstatic int LowerCase(int c)\n{\n\tif (c >= 'A' && c <= 'Z')\n\t\treturn 'a' + c - 'A';\n\treturn c;\n}\n\nstatic int CheckBlitzFoldPoint(char const *token, int &level) {\n\tif (!strcmp(token, \"function\") ||\n\t\t!strcmp(token, \"type\")) {\n\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\treturn 1;\n\t}\n\tif (!strcmp(token, \"end function\") ||\n\t\t!strcmp(token, \"end type\")) {\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nstatic int CheckPureFoldPoint(char const *token, int &level) {\n\tif (!strcmp(token, \"procedure\") ||\n\t\t!strcmp(token, \"enumeration\") ||\n\t\t!strcmp(token, \"interface\") ||\n\t\t!strcmp(token, \"structure\")) {\n\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\treturn 1;\n\t}\n\tif (!strcmp(token, \"endprocedure\") ||\n\t\t!strcmp(token, \"endenumeration\") ||\n\t\t!strcmp(token, \"endinterface\") ||\n\t\t!strcmp(token, \"endstructure\")) {\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nstatic int CheckFreeFoldPoint(char const *token, int &level) {\n\tif (!strcmp(token, \"function\") ||\n\t\t!strcmp(token, \"sub\") ||\n\t\t!strcmp(token, \"enum\") ||\n\t\t!strcmp(token, \"type\") ||\n\t\t!strcmp(token, \"union\") ||\n\t\t!strcmp(token, \"property\") ||\n\t\t!strcmp(token, \"destructor\") ||\n\t\t!strcmp(token, \"constructor\")) {\n\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\treturn 1;\n\t}\n\tif (!strcmp(token, \"end function\") ||\n\t\t!strcmp(token, \"end sub\") ||\n\t\t!strcmp(token, \"end enum\") ||\n\t\t!strcmp(token, \"end type\") ||\n\t\t!strcmp(token, \"end union\") ||\n\t\t!strcmp(token, \"end property\") ||\n\t\t!strcmp(token, \"end destructor\") ||\n\t\t!strcmp(token, \"end constructor\")) {\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n// An individual named option for use in an OptionSet\n\n// Options used for LexerBasic\nstruct OptionsBasic {\n\tbool fold;\n\tbool foldSyntaxBased;\n\tbool foldCommentExplicit;\n\tstd::string foldExplicitStart;\n\tstd::string foldExplicitEnd;\n\tbool foldExplicitAnywhere;\n\tbool foldCompact;\n\tOptionsBasic() {\n\t\tfold = false;\n\t\tfoldSyntaxBased = true;\n\t\tfoldCommentExplicit = false;\n\t\tfoldExplicitStart = \"\";\n\t\tfoldExplicitEnd   = \"\";\n\t\tfoldExplicitAnywhere = false;\n\t\tfoldCompact = true;\n\t}\n};\n\nstatic const char * const blitzbasicWordListDesc[] = {\n\t\"BlitzBasic Keywords\",\n\t\"user1\",\n\t\"user2\",\n\t\"user3\",\n\t0\n};\n\nstatic const char * const purebasicWordListDesc[] = {\n\t\"PureBasic Keywords\",\n\t\"PureBasic PreProcessor Keywords\",\n\t\"user defined 1\",\n\t\"user defined 2\",\n\t0\n};\n\nstatic const char * const freebasicWordListDesc[] = {\n\t\"FreeBasic Keywords\",\n\t\"FreeBasic PreProcessor Keywords\",\n\t\"user defined 1\",\n\t\"user defined 2\",\n\t0\n};\n\nstruct OptionSetBasic : public OptionSet<OptionsBasic> {\n\tOptionSetBasic(const char * const wordListDescriptions[]) {\n\t\tDefineProperty(\"fold\", &OptionsBasic::fold);\n\n\t\tDefineProperty(\"fold.basic.syntax.based\", &OptionsBasic::foldSyntaxBased,\n\t\t\t\"Set this property to 0 to disable syntax based folding.\");\n\n\t\tDefineProperty(\"fold.basic.comment.explicit\", &OptionsBasic::foldCommentExplicit,\n\t\t\t\"This option enables folding explicit fold points when using the Basic lexer. \"\n\t\t\t\"Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start \"\n\t\t\t\"and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.\");\n\n\t\tDefineProperty(\"fold.basic.explicit.start\", &OptionsBasic::foldExplicitStart,\n\t\t\t\"The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).\");\n\n\t\tDefineProperty(\"fold.basic.explicit.end\", &OptionsBasic::foldExplicitEnd,\n\t\t\t\"The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).\");\n\n\t\tDefineProperty(\"fold.basic.explicit.anywhere\", &OptionsBasic::foldExplicitAnywhere,\n\t\t\t\"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\");\n\n\t\tDefineProperty(\"fold.compact\", &OptionsBasic::foldCompact);\n\n\t\tDefineWordListSets(wordListDescriptions);\n\t}\n};\n\nclass LexerBasic : public DefaultLexer {\n\tchar comment_char;\n\tint (*CheckFoldPoint)(char const *, int &);\n\tWordList keywordlists[4];\n\tOptionsBasic options;\n\tOptionSetBasic osBasic;\npublic:\n\tLexerBasic(const char *languageName_, int language_, char comment_char_,\n\t\tint (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :\n\t\t\t\t\t\t DefaultLexer(languageName_, language_),\n\t\t\t\t\t\t comment_char(comment_char_),\n\t\t\t\t\t\t CheckFoldPoint(CheckFoldPoint_),\n\t\t\t\t\t\t osBasic(wordListDescriptions) {\n\t}\n\tvirtual ~LexerBasic() {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char * SCI_METHOD PropertyNames() override {\n\t\treturn osBasic.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osBasic.PropertyType(name);\n\t}\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osBasic.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osBasic.PropertyGet(key);\n\t}\n\tconst char * SCI_METHOD DescribeWordListSets() override {\n\t\treturn osBasic.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid * SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn 0;\n\t}\n\tstatic ILexer5 *LexerFactoryBlitzBasic() {\n\t\treturn new LexerBasic(\"blitzbasic\", SCLEX_BLITZBASIC, ';', CheckBlitzFoldPoint, blitzbasicWordListDesc);\n\t}\n\tstatic ILexer5 *LexerFactoryPureBasic() {\n\t\treturn new LexerBasic(\"purebasic\", SCLEX_PUREBASIC, ';', CheckPureFoldPoint, purebasicWordListDesc);\n\t}\n\tstatic ILexer5 *LexerFactoryFreeBasic() {\n\t\treturn new LexerBasic(\"freebasic\", SCLEX_FREEBASIC, '\\'', CheckFreeFoldPoint, freebasicWordListDesc );\n\t}\n};\n\nSci_Position SCI_METHOD LexerBasic::PropertySet(const char *key, const char *val) {\n\tif (osBasic.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerBasic::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = 0;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywordlists[0];\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywordlists[1];\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywordlists[2];\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywordlists[3];\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tWordList wlNew;\n\t\twlNew.Set(wl);\n\t\tif (*wordListN != wlNew) {\n\t\t\twordListN->Set(wl);\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid SCI_METHOD LexerBasic::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\n\tbool wasfirst = true, isfirst = true; // true if first token in a line\n\tstyler.StartAt(startPos);\n\tint styleBeforeKeyword = SCE_B_DEFAULT;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\t// Can't use sc.More() here else we miss the last character\n\tfor (; ; sc.Forward()) {\n\t\tif (sc.state == SCE_B_IDENTIFIER) {\n\t\t\tif (!IsIdentifier(sc.ch)) {\n\t\t\t\t// Labels\n\t\t\t\tif (wasfirst && sc.Match(':')) {\n\t\t\t\t\tsc.ChangeState(SCE_B_LABEL);\n\t\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tchar s[100];\n\t\t\t\t\tint kstates[4] = {\n\t\t\t\t\t\tSCE_B_KEYWORD,\n\t\t\t\t\t\tSCE_B_KEYWORD2,\n\t\t\t\t\t\tSCE_B_KEYWORD3,\n\t\t\t\t\t\tSCE_B_KEYWORD4,\n\t\t\t\t\t};\n\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t\tfor (int i = 0; i < 4; i++) {\n\t\t\t\t\t\tif (keywordlists[i].InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(kstates[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Types, must set them as operator else they will be\n\t\t\t\t\t// matched as number/constant\n\t\t\t\t\tif (sc.Match('.') || sc.Match('$') || sc.Match('%') ||\n\t\t\t\t\t\tsc.Match('#')) {\n\t\t\t\t\t\tsc.SetState(SCE_B_OPERATOR);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_OPERATOR) {\n\t\t\tif (!IsOperator(sc.ch) || sc.Match('#'))\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t} else if (sc.state == SCE_B_LABEL) {\n\t\t\tif (!IsIdentifier(sc.ch))\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t} else if (sc.state == SCE_B_CONSTANT) {\n\t\t\tif (!IsIdentifier(sc.ch))\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t} else if (sc.state == SCE_B_NUMBER) {\n\t\t\tif (!IsDigit(sc.ch))\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t} else if (sc.state == SCE_B_HEXNUMBER) {\n\t\t\tif (!IsHexDigit(sc.ch))\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t} else if (sc.state == SCE_B_BINNUMBER) {\n\t\t\tif (!IsBinDigit(sc.ch))\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t} else if (sc.state == SCE_B_STRING) {\n\t\t\tif (sc.ch == '\"') {\n\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_B_ERROR);\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_COMMENT || sc.state == SCE_B_PREPROCESSOR) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_DOCLINE) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t\t} else if (sc.ch == '\\\\' || sc.ch == '@') {\n\t\t\t\tif (IsLetter(sc.chNext) && sc.chPrev != '\\\\') {\n\t\t\t\t\tstyleBeforeKeyword = sc.state;\n\t\t\t\t\tsc.SetState(SCE_B_DOCKEYWORD);\n\t\t\t\t};\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_DOCKEYWORD) {\n\t\t\tif (IsSpace(sc.ch)) {\n\t\t\t\tsc.SetState(styleBeforeKeyword);\n\t\t\t}\telse if (sc.atLineEnd && styleBeforeKeyword == SCE_B_DOCLINE) {\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_COMMENTBLOCK) {\n\t\t\tif (sc.Match(\"\\'/\")) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_DOCBLOCK) {\n\t\t\tif (sc.Match(\"\\'/\")) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t} else if (sc.ch == '\\\\' || sc.ch == '@') {\n\t\t\t\tif (IsLetter(sc.chNext) && sc.chPrev != '\\\\') {\n\t\t\t\t\tstyleBeforeKeyword = sc.state;\n\t\t\t\t\tsc.SetState(SCE_B_DOCKEYWORD);\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineStart)\n\t\t\tisfirst = true;\n\n\t\tif (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {\n\t\t\tif (isfirst && sc.Match('.') && comment_char != '\\'') {\n\t\t\t\t\tsc.SetState(SCE_B_LABEL);\n\t\t\t} else if (isfirst && sc.Match('#')) {\n\t\t\t\twasfirst = isfirst;\n\t\t\t\tsc.SetState(SCE_B_IDENTIFIER);\n\t\t\t} else if (sc.Match(comment_char)) {\n\t\t\t\t// Hack to make deprecated QBASIC '$Include show\n\t\t\t\t// up in freebasic with SCE_B_PREPROCESSOR.\n\t\t\t\tif (comment_char == '\\'' && sc.Match(comment_char, '$'))\n\t\t\t\t\tsc.SetState(SCE_B_PREPROCESSOR);\n\t\t\t\telse if (sc.Match(\"\\'*\") || sc.Match(\"\\'!\")) {\n\t\t\t\t\tsc.SetState(SCE_B_DOCLINE);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_B_COMMENT);\n\t\t\t\t}\n\t\t\t} else if (sc.Match(\"/\\'\")) {\n\t\t\t\tif (sc.Match(\"/\\'*\") || sc.Match(\"/\\'!\")) {\t// Support of gtk-doc/Doxygen doc. style\n\t\t\t\t\tsc.SetState(SCE_B_DOCBLOCK);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_B_COMMENTBLOCK);\n\t\t\t\t}\n\t\t\t\tsc.Forward();\t// Eat the ' so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('\"')) {\n\t\t\t\tsc.SetState(SCE_B_STRING);\n\t\t\t} else if (IsDigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_B_NUMBER);\n\t\t\t} else if (sc.Match('$') || sc.Match(\"&h\") || sc.Match(\"&H\") || sc.Match(\"&o\") || sc.Match(\"&O\")) {\n\t\t\t\tsc.SetState(SCE_B_HEXNUMBER);\n\t\t\t} else if (sc.Match('%') || sc.Match(\"&b\") || sc.Match(\"&B\")) {\n\t\t\t\tsc.SetState(SCE_B_BINNUMBER);\n\t\t\t} else if (sc.Match('#')) {\n\t\t\t\tsc.SetState(SCE_B_CONSTANT);\n\t\t\t} else if (IsOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_B_OPERATOR);\n\t\t\t} else if (IsIdentifier(sc.ch)) {\n\t\t\t\twasfirst = isfirst;\n\t\t\t\tsc.SetState(SCE_B_IDENTIFIER);\n\t\t\t} else if (!IsSpace(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_B_ERROR);\n\t\t\t}\n\t\t}\n\n\t\tif (!IsSpace(sc.ch))\n\t\t\tisfirst = false;\n\n\t\tif (!sc.More())\n\t\t\tbreak;\n\t}\n\tsc.Complete();\n}\n\n\nvoid SCI_METHOD LexerBasic::Fold(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {\n\n\tif (!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\n\tSci_Position line = styler.GetLine(startPos);\n\tint level = styler.LevelAt(line);\n\tint go = 0, done = 0;\n\tSci_Position endPos = startPos + length;\n\tchar word[256];\n\tint wordlen = 0;\n\tconst bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();\n\tint cNext = styler[startPos];\n\n\t// Scan for tokens at the start of the line (they may include\n\t// whitespace, for tokens like \"End Function\"\n\tfor (Sci_Position i = startPos; i < endPos; i++) {\n\t\tint c = cNext;\n\t\tcNext = styler.SafeGetCharAt(i + 1);\n\t\tbool atEOL = (c == '\\r' && cNext != '\\n') || (c == '\\n');\n\t\tif (options.foldSyntaxBased && !done && !go) {\n\t\t\tif (wordlen) { // are we scanning a token already?\n\t\t\t\tword[wordlen] = static_cast<char>(LowerCase(c));\n\t\t\t\tif (!IsIdentifier(c)) { // done with token\n\t\t\t\t\tword[wordlen] = '\\0';\n\t\t\t\t\tgo = CheckFoldPoint(word, level);\n\t\t\t\t\tif (!go) {\n\t\t\t\t\t\t// Treat any whitespace as single blank, for\n\t\t\t\t\t\t// things like \"End   Function\".\n\t\t\t\t\t\tif (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {\n\t\t\t\t\t\t\tword[wordlen] = ' ';\n\t\t\t\t\t\t\tif (wordlen < 255)\n\t\t\t\t\t\t\t\twordlen++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse // done with this line\n\t\t\t\t\t\t\tdone = 1;\n\t\t\t\t\t}\n\t\t\t\t} else if (wordlen < 255) {\n\t\t\t\t\twordlen++;\n\t\t\t\t}\n\t\t\t} else { // start scanning at first non-whitespace character\n\t\t\t\tif (!IsSpace(c)) {\n\t\t\t\t\tif (IsIdentifier(c)) {\n\t\t\t\t\t\tword[0] = static_cast<char>(LowerCase(c));\n\t\t\t\t\t\twordlen = 1;\n\t\t\t\t\t} else // done with this line\n\t\t\t\t\t\tdone = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) {\n\t\t\tif (userDefinedFoldMarkers) {\n\t\t\t\tif (styler.Match(i, options.foldExplicitStart.c_str())) {\n \t\t\t\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t\tgo = 1;\n\t\t\t\t} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {\n \t\t\t\t\tgo = -1;\n \t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (c == comment_char) {\n\t\t\t\t\tif (cNext == '{') {\n\t\t\t\t\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t\t\tgo = 1;\n\t\t\t\t\t} else if (cNext == '}') {\n\t\t\t\t\t\tgo = -1;\n\t\t\t\t\t}\n\t\t\t\t}\n \t\t\t}\n \t\t}\n\t\tif (atEOL) { // line end\n\t\t\tif (!done && wordlen == 0 && options.foldCompact) // line was only space\n\t\t\t\tlevel |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (level != styler.LevelAt(line))\n\t\t\t\tstyler.SetLevel(line, level);\n\t\t\tlevel += go;\n\t\t\tline++;\n\t\t\t// reset state\n\t\t\twordlen = 0;\n\t\t\tlevel &= ~SC_FOLDLEVELHEADERFLAG;\n\t\t\tlevel &= ~SC_FOLDLEVELWHITEFLAG;\n\t\t\tgo = 0;\n\t\t\tdone = 0;\n\t\t}\n\t}\n}\n\nextern const LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, \"blitzbasic\", blitzbasicWordListDesc);\n\nextern const LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, \"purebasic\", purebasicWordListDesc);\n\nextern const LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, \"freebasic\", freebasicWordListDesc);\n"
  },
  {
    "path": "lexers/LexBatch.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexBatch.cxx\n ** Lexer for batch files.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <initializer_list>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"InList.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\nconst char *const batchWordListDesc[] = {\n\t\"Internal Commands\",\n\t\"External Commands\",\n\tnullptr\n};\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer batch SCLEX_BATCH SCE_BAT_\n\t0, \"SCE_BAT_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_BAT_COMMENT\", \"comment\", \"Line comment\",\n\t2, \"SCE_BAT_WORD\", \"keyword\", \"Keyword\",\n\t3, \"SCE_BAT_LABEL\", \"label\", \"Label\",\n\t4, \"SCE_BAT_HIDE\", \"preprocessor\", \"Hide line @\",\n\t5, \"SCE_BAT_COMMAND\", \"identifier\", \"Command\",\n\t6, \"SCE_BAT_IDENTIFIER\", \"identifier\", \"Identifier\",\n\t7, \"SCE_BAT_OPERATOR\", \"operator\", \"Operator\",\n\t8, \"SCE_BAT_AFTER_LABEL\", \"comment\",\"After label\",\n};\n\nclass LexerBatch : public DefaultLexer {\n\tWordList keywords;\n\tWordList keywords2;\n\tstd::string wordLists;\npublic:\n\texplicit LexerBatch() :\n\t\tDefaultLexer(\"batch\", SCLEX_BATCH, lexicalClasses, std::size(lexicalClasses)) {\n\t\twordLists = JoinWordListDescriptions(batchWordListDesc);\n\t}\n\tLexerBatch(const LexerBatch &) = delete;\n\tLexerBatch(LexerBatch &&) = delete;\n\tLexerBatch &operator=(const LexerBatch &) = delete;\n\tLexerBatch &operator=(LexerBatch &&) = delete;\n\t~LexerBatch() override = default;\n\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn wordLists.c_str();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, Scintilla::IDocument *pAccess) override;\n\n\tstatic ILexer5 *LexerFactoryBatch() {\n\t\treturn new LexerBatch();\n\t}\n};\n\nconstexpr bool Is0To9(char ch) noexcept {\n\treturn (ch >= '0') && (ch <= '9');\n}\n\nconstexpr bool IsAlphabetic(int ch) noexcept {\n\treturn IsUpperOrLowerCase(ch);\n}\n\nbool AtEOL(LexAccessor &styler, Sci_PositionU i) {\n\treturn (styler[i] == '\\n') ||\n\t       ((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n'));\n}\n\n// Tests for BATCH Operators\nconstexpr bool IsBOperator(char ch) noexcept {\n\treturn AnyOf(ch, '=', '+', '>', '<', '|', '?', '*', '&', '(', ')');\n}\n\n// Tests for BATCH Separators\nconstexpr bool IsBSeparator(char ch) noexcept {\n\treturn AnyOf(ch, '\\\\', '.', ';', '\\\"', '\\'', '/');\n}\n\n// Both operators and separators -- words often ended with these characters.\nconstexpr bool IsBPunctuation(char ch) noexcept {\n\treturn IsBOperator(ch) || IsBSeparator(ch);\n}\n\n// These characters end words.\nconstexpr bool IsBEndWord(char ch) noexcept {\n\treturn IsBPunctuation(ch) || AnyOf(ch, '%', '!');\n}\n\nconstexpr void SkipSpace(Sci_PositionU &i, std::string_view sv) noexcept {\n\twhile (i < sv.length() && isspacechar(sv[i])) {\n\t\ti++;\n\t}\n}\n\nconstexpr void SkipNonSpace(Sci_PositionU &i, std::string_view sv) noexcept {\n\twhile (i < sv.length() && !isspacechar(sv[i])) {\n\t\ti++;\n\t}\n}\n\nconstexpr Sci_PositionU WordLength(std::string_view word) {\n\tSci_PositionU i = 0;\n\twhile ((i < word.length()) && (!IsBEndWord(word[i]))) {\n\t\ti++;\n\t}\n\treturn i;\n}\n\n// Tests for escape character\nconstexpr bool IsEscaped(std::string_view wordStr, Sci_PositionU pos) noexcept {\n\tbool isQoted=false;\n\twhile (pos>0){\n\t\tpos--;\n\t\tif (wordStr[pos]=='^')\n\t\t\tisQoted=!isQoted;\n\t\telse\n\t\t\tbreak;\n\t}\n\treturn isQoted;\n}\n\nconstexpr bool IsQuotedBy(std::string_view svBuffer, char quote) noexcept {\n\tbool CurrentStatus = false;\n\tsize_t pQuote = svBuffer.find(quote);\n\twhile (pQuote != std::string_view::npos) {\n\t\tif (!IsEscaped(svBuffer, pQuote)) {\n\t\t\tCurrentStatus = !CurrentStatus;\n\t\t}\n\t\tpQuote = svBuffer.find(quote, pQuote + 1);\n\t}\n\treturn CurrentStatus;\n}\n\n// Tests for quote character\nconstexpr bool textQuoted(std::string_view lineBuffer, Sci_PositionU endPos) noexcept {\n\tconst std::string_view svBuffer = lineBuffer.substr(0, endPos);\n\treturn IsQuotedBy(svBuffer, '\\\"') || IsQuotedBy(svBuffer, '\\'');\n}\n\nbool IsContinuation(const std::string &lineBuffer) noexcept {\n\tif ((lineBuffer.length() <= 1) || (lineBuffer == \"\\r\\n\")) // empty line on Unix and Mac or on Windows\n\t\treturn false;\n\tSci_PositionU lineContinuationPos = lineBuffer.length() - 2; // Unix or Mac EOL\n\tif ((lineBuffer.length() > 2) && lineBuffer[lineBuffer.length() - 2] == '\\r') // Windows EOL\n\t\tlineContinuationPos = lineBuffer.length() - 3;\n\t// Reset continueProcessing if line continuation was not found\n\tif ((lineBuffer[lineContinuationPos] != '^')\n\t\t|| IsEscaped(lineBuffer, lineContinuationPos)\n\t\t|| textQuoted(lineBuffer, lineContinuationPos))\n\t\treturn false;\n\treturn true;\n}\n\nSci_Position SCI_METHOD LexerBatch::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywords2;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid LexerBatch::Lex(Sci_PositionU startPos, Sci_Position length, int, Scintilla::IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\n\t// Always backtracks to the start of a line that is not a continuation\n\t// of the previous line\n\tif (startPos > 0) {\n\t\tSci_Position ln = styler.GetLine(startPos); // Current line number\n\t\twhile (startPos > 0) {\n\t\t\tln--;\n\t\t\tif ((styler.SafeGetCharAt(startPos-3) == '^' && styler.SafeGetCharAt(startPos-2) == '\\r' && styler.SafeGetCharAt(startPos-1) == '\\n')\n\t\t\t|| styler.SafeGetCharAt(startPos-2) == '^') {\t// handle '^' line continuation\n\t\t\t\t// When the line continuation is found,\n\t\t\t\t// set the Start Position to the Start of the previous line\n\t\t\t\tlength+=startPos-styler.LineStart(ln);\n\t\t\t\tstartPos=styler.LineStart(ln);\n\t\t\t}\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tstd::string lineBuffer;\n\tstd::string word;\n\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tSci_PositionU startLine = startPos;\n\tbool continueProcessing = true;\t// Used to toggle Regular Keyword Checking\n\tbool isNotAssigned=false; // Used to flag Assignment in Set operation\n\n\tfor (Sci_PositionU i = startPos; i < startPos + length; i++) {\n\t\t// All testing is performed on a lower case version of the line since batch is case-insensitive\n\t\tlineBuffer.push_back(MakeLowerCase(styler[i]));\n\t\tif (AtEOL(styler, i) || (i==startPos + length-1)) {\n\t\t\t// End of line (or of line buffer) (or End of Last Line) met, colourise it\n\t\t\tconst Sci_PositionU lengthLine = lineBuffer.length();\n\t\t\tconst Sci_PositionU endPos=i;\n\n\t\t\t// CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords\n\t\t\t//   Toggling Regular Keyword Checking off improves readability\n\t\t\t// Other Regular Keywords and External Commands / Programs might also benefit from toggling\n\t\t\t//   Need a more robust algorithm to properly toggle Regular Keyword Checking\n\t\t\tbool stopLineProcessing=false;  // Used to stop line processing if Comment or Drive Change found\n\n\t\t\tSci_PositionU offset = 0;\t// Line Buffer Offset\n\t\t\t// Skip initial spaces\n\t\t\tSkipSpace(offset, lineBuffer);\n\t\t\t// Colorize Default Text\n\t\t\tstyler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);\n\t\t\t// Set External Command / Program Location\n\t\t\tSci_PositionU cmdLoc = offset;\n\n\t\t\t// Check for Fake Label (Comment) or Real Label - return if found\n\t\t\tif (lineBuffer[offset] == ':') {\n\t\t\t\tif (lineBuffer[offset + 1] == ':') {\n\t\t\t\t\t// Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm\n\t\t\t\t\tstyler.ColourTo(endPos, SCE_BAT_COMMENT);\n\t\t\t\t} else {\n\t\t\t\t\t// Colorize Real Label\n\t\t\t\t\t// :[\\t ]*[^\\t &+:<>|]+\n\t\t\t\t\tconst size_t whitespaceEnd = lineBuffer.find_first_not_of(\"\\t \", offset + 1);\n\t\t\t\t\tconst size_t whitespaceLength = (whitespaceEnd == std::string::npos) ? 0 : whitespaceEnd;\n\t\t\t\t\t// Set of label-terminating characters determined experimentally\n\t\t\t\t\tconst size_t labelEnd = lineBuffer.find_first_of(\"\\t &+:<>|\", whitespaceLength);\n\t\t\t\t\tif (labelEnd != std::string::npos) {\n\t\t\t\t\t\tstyler.ColourTo(startLine + labelEnd - 1, SCE_BAT_LABEL);\n\t\t\t\t\t\tstyler.ColourTo(endPos, SCE_BAT_AFTER_LABEL);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyler.ColourTo(endPos, SCE_BAT_LABEL);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstopLineProcessing=true;\n\t\t\t// Check for Drive Change (Drive Change is internal command) - return if found\n\t\t\t} else if ((IsAlphabetic(lineBuffer[offset])) &&\n\t\t\t\t(lineBuffer[offset + 1] == ':') &&\n\t\t\t\t((isspacechar(lineBuffer[offset + 2])) ||\n\t\t\t\t(((lineBuffer[offset + 2] == '\\\\')) &&\n\t\t\t\t(isspacechar(lineBuffer[offset + 3]))))) {\n\t\t\t\t// Colorize Regular Keyword\n\t\t\t\tstyler.ColourTo(endPos, SCE_BAT_WORD);\n\t\t\t\tstopLineProcessing=true;\n\t\t\t}\n\n\t\t\t// Check for Hide Command (@ECHO OFF/ON)\n\t\t\tif (lineBuffer[offset] == '@') {\n\t\t\t\tstyler.ColourTo(startLine + offset, SCE_BAT_HIDE);\n\t\t\t\toffset++;\n\t\t\t}\n\t\t\t// Skip next spaces\n\t\t\tSkipSpace(offset, lineBuffer);\n\n\t\t\t// Read remainder of line word-at-a-time or remainder-of-word-at-a-time\n\t\t\twhile (offset < lengthLine  && !stopLineProcessing) {\n\t\t\t\tif (offset > startLine) {\n\t\t\t\t\t// Colorize Default Text\n\t\t\t\t\tstyler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);\n\t\t\t\t}\n\t\t\t\t// Copy word from Line Buffer\n\t\t\t\tconst Sci_PositionU wordStart = offset;\n\t\t\t\tSkipNonSpace(offset, lineBuffer);\n\t\t\t\tconst Sci_PositionU wbl = offset - wordStart;\t\t// Word Buffer Length\n\t\t\t\t// Using assign to prevent new allocations\n\t\t\t\tword.assign(lineBuffer, wordStart, wbl);\n\t\t\t\tconst char first = word.front();\n\t\t\t\tSci_PositionU wbo = 0;\t\t// Word Buffer Offset - also Special Keyword Buffer Length\n\n\t\t\t\t// Check for Comment - return if found\n\t\t\t\tif (continueProcessing) {\n\t\t\t\t\tif ((word == \"rem\") || (word.substr(0,2) == \"::\")) {\n\t\t\t\t\t\tif ((offset == wbl) || !textQuoted(lineBuffer, wordStart)) {\n\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart - 1, SCE_BAT_DEFAULT);\n\t\t\t\t\t\t\tstyler.ColourTo(endPos, SCE_BAT_COMMENT);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Check for Separator\n\t\t\t\tif (IsBSeparator(first)) {\n\t\t\t\t\t// Check for External Command / Program\n\t\t\t\t\tint style = SCE_BAT_DEFAULT;\n\t\t\t\t\tif ((cmdLoc == wordStart) &&\n\t\t\t\t\t\t(AnyOf(first, ':', '\\\\', '.'))) {\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + 1;\n\t\t\t\t\t\t// Colorize External Command / Program\n\t\t\t\t\t\tif ((!keywords2) || (keywords2.InList(word))) {\n\t\t\t\t\t\t\tstyle = SCE_BAT_COMMAND;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Reset External Command / Program Location\n\t\t\t\t\t\tcmdLoc = offset;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + 1;\n\t\t\t\t\t}\n\t\t\t\t\t// Colorize Text\n\t\t\t\t\tstyler.ColourTo(startLine + offset - 1, style);\n\t\t\t\t// Check for Regular Keyword in list\n\t\t\t\t} else if ((keywords.InList(word)) && (continueProcessing)) {\n\t\t\t\t\t// ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking\n\t\t\t\t\tif (InList(word, {\"echo\", \"goto\", \"prompt\"})) {\n\t\t\t\t\t\tcontinueProcessing = false;\n\t\t\t\t\t}\n\t\t\t\t\t// SET requires additional processing for the assignment operator\n\t\t\t\t\tif (word == \"set\") {\n\t\t\t\t\t\tcontinueProcessing = false;\n\t\t\t\t\t\tisNotAssigned=true;\n\t\t\t\t\t}\n\t\t\t\t\t// Identify External Command / Program Location for ERRORLEVEL, and EXIST\n\t\t\t\t\tif (InList(word, {\"errorlevel\", \"exist\"})) {\n\t\t\t\t\t\t// Reset External Command / Program Location\n\t\t\t\t\t\tcmdLoc = offset;\n\t\t\t\t\t\t// Skip next spaces\n\t\t\t\t\t\tSkipSpace(cmdLoc, lineBuffer);\n\t\t\t\t\t\t// Skip comparison\n\t\t\t\t\t\tSkipNonSpace(cmdLoc, lineBuffer);\n\t\t\t\t\t\t// Skip next spaces\n\t\t\t\t\t\tSkipSpace(cmdLoc, lineBuffer);\n\t\t\t\t\t// Identify External Command / Program Location for CALL, DO, LOADHIGH and LH\n\t\t\t\t\t} else if (InList(word, {\"call\", \"do\", \"loadhigh\", \"lh\"})) {\n\t\t\t\t\t\t// Reset External Command / Program Location\n\t\t\t\t\t\tcmdLoc = offset;\n\t\t\t\t\t\t// Skip next spaces\n\t\t\t\t\t\tSkipSpace(cmdLoc, lineBuffer);\n\t\t\t\t\t\t// Check if call is followed by a label\n\t\t\t\t\t\tif ((lineBuffer[cmdLoc] == ':') &&\n\t\t\t\t\t\t\t(word == \"call\")) {\n\t\t\t\t\t\t\tcontinueProcessing = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Colorize Regular keyword\n\t\t\t\t\tstyler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);\n\t\t\t\t\t// No need to Reset Offset\n\t\t\t\t// Check for Special Keyword in list, External Command / Program, or Default Text\n\t\t\t\t} else if (\n\t\t\t\t\t(!(IsBOperator(first) || AnyOf(first, '%', '!'))) &&\n\t\t\t\t\t(continueProcessing)) {\n\t\t\t\t\t// Check for Special Keyword\n\t\t\t\t\t//     Affected Commands are in Length range 2-6\n\t\t\t\t\t//     Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected\n\t\t\t\t\tbool sKeywordFound = false;\t\t// Exit Special Keyword for-loop if found\n\t\t\t\t\tfor (Sci_PositionU keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {\n\t\t\t\t\t\t// Special Keywords are those that allow certain characters without whitespace after the command\n\t\t\t\t\t\t// Examples are: cd. cd\\ md. rd. dir| dir> echo: echo. path=\n\t\t\t\t\t\t// Special Keyword used to determine if the first n characters is a Keyword\n\t\t\t\t\t\twbo = keywordLength;\n\t\t\t\t\t\tconst std::string sKeyword = word.substr(0, keywordLength);\n\t\t\t\t\t\t// Check for Special Keyword in list\n\t\t\t\t\t\tif ((keywords.InList(sKeyword)) &&\n\t\t\t\t\t\t\t((IsBPunctuation(word[wbo])) ||\n\t\t\t\t\t\t\t(word[wbo] == ':' && (InList(sKeyword, {\"call\", \"echo\", \"goto\"}) )))) {\n\t\t\t\t\t\t\tsKeywordFound = true;\n\t\t\t\t\t\t\t// ECHO requires no further Regular Keyword Checking\n\t\t\t\t\t\t\tif (sKeyword== \"echo\") {\n\t\t\t\t\t\t\t\tcontinueProcessing = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Colorize Special Keyword as Regular Keyword\n\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + wbo - 1, SCE_BAT_WORD);\n\t\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\t\toffset = wordStart + wbo;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Check for External Command / Program or Default Text\n\t\t\t\t\tif (!sKeywordFound) {\n\t\t\t\t\t\tint style = SCE_BAT_DEFAULT;\n\t\t\t\t\t\t// Read up to %, !, Operator or Separator\n\t\t\t\t\t\tconst Sci_PositionU lengthWord = WordLength(word);\n\t\t\t\t\t\t// Check for External Command / Program\n\t\t\t\t\t\tif (cmdLoc == wordStart) {\n\t\t\t\t\t\t\t// Reset External Command / Program Location\n\t\t\t\t\t\t\tcmdLoc = wordStart + lengthWord;\n\t\t\t\t\t\t\t// CHOICE requires no further Regular Keyword Checking\n\t\t\t\t\t\t\tif (word == \"choice\") {\n\t\t\t\t\t\t\t\tcontinueProcessing = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Check for START (and its switches) - What follows is External Command \\ Program\n\t\t\t\t\t\t\tif (word == \"start\") {\n\t\t\t\t\t\t\t\t// Skip next spaces\n\t\t\t\t\t\t\t\tSkipSpace(cmdLoc, lineBuffer);\n\t\t\t\t\t\t\t\t// Reset External Command / Program Location if command switch detected\n\t\t\t\t\t\t\t\tif (lineBuffer[cmdLoc] == '/') {\n\t\t\t\t\t\t\t\t\t// Skip command switch\n\t\t\t\t\t\t\t\t\tSkipNonSpace(cmdLoc, lineBuffer);\n\t\t\t\t\t\t\t\t\t// Skip next spaces\n\t\t\t\t\t\t\t\t\tSkipSpace(cmdLoc, lineBuffer);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Colorize External Command / Program\n\t\t\t\t\t\t\tif ((!keywords2) || (keywords2.InList(word))) {\n\t\t\t\t\t\t\t\tstyle = SCE_BAT_COMMAND;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + lengthWord - 1, style);\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + lengthWord;\n\t\t\t\t\t}\n\t\t\t\t// Check for Argument  (%n), Environment Variable (%x...%) or Local Variable (%%a)\n\t\t\t\t} else if (first == '%') {\n\t\t\t\t\t// Colorize Default Text\n\t\t\t\t\tstyler.ColourTo(startLine + wordStart - 1, SCE_BAT_DEFAULT);\n\t\t\t\t\twbo++;\n\t\t\t\t\t// Search to end of word for second % (can be a long path)\n\t\t\t\t\twhile ((wbo < wbl) && (word[wbo] != '%')) {\n\t\t\t\t\t\twbo++;\n\t\t\t\t\t}\n\t\t\t\t\t// Check for Argument (%n) or (%*)\n\t\t\t\t\tif (((Is0To9(word[1])) || (word[1] == '*')) &&\n\t\t\t\t\t\t(word[wbo] != '%')) {\n\t\t\t\t\t\t// Check for External Command / Program\n\t\t\t\t\t\tif (cmdLoc == wordStart) {\n\t\t\t\t\t\t\tcmdLoc = wordStart + 2;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Colorize Argument\n\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + 1, SCE_BAT_IDENTIFIER);\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + 2;\n\t\t\t\t\t// Check for Expanded Argument (%~...) / Variable (%%~...)\n\t\t\t\t\t// Expanded Argument: %~[<path-operators>]<single digit>\n\t\t\t\t\t// Expanded Variable: %%~[<path-operators>]<single identifier character>\n\t\t\t\t\t// Path operators are exclusively alphabetic.\n\t\t\t\t\t// Expanded arguments have a single digit at the end.\n\t\t\t\t\t// Expanded variables have a single identifier character as variable name.\n\t\t\t\t\t} else if (((wbl > 1) && (word[1] == '~')) ||\n\t\t\t\t\t\t((wbl > 2) && (word[1] == '%') && (word[2] == '~'))) {\n\t\t\t\t\t\t// Check for External Command / Program\n\t\t\t\t\t\tif (cmdLoc == wordStart) {\n\t\t\t\t\t\t\tcmdLoc = wordStart + wbo;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst bool isArgument = (word[1] == '~');\n\t\t\t\t\t\tif (isArgument) {\n\t\t\t\t\t\t\tSci_PositionU expansionStopOffset = 2;\n\t\t\t\t\t\t\tbool isValid = false;\n\t\t\t\t\t\t\tfor (; expansionStopOffset < wbl; expansionStopOffset++) {\n\t\t\t\t\t\t\t\tif (Is0To9(word[expansionStopOffset])) {\n\t\t\t\t\t\t\t\t\texpansionStopOffset++;\n\t\t\t\t\t\t\t\t\tisValid = true;\n\t\t\t\t\t\t\t\t\twbo = expansionStopOffset;\n\t\t\t\t\t\t\t\t\t// Colorize Expanded Argument\n\t\t\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + wbo - 1, SCE_BAT_IDENTIFIER);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\t\t\t// not a valid expanded argument or variable\n\t\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + wbo - 1, SCE_BAT_DEFAULT);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t// Expanded Variable\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// start after ~\n\t\t\t\t\t\t\twbo = 3;\n\t\t\t\t\t\t\t// Search to end of word for another % (can be a long path)\n\t\t\t\t\t\t\twhile ((wbo < wbl) && (!(IsBPunctuation(word[wbo]) || (word[wbo] == '%')))) {\n\t\t\t\t\t\t\t\twbo++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (wbo > 3) {\n\t\t\t\t\t\t\t\t// Colorize Expanded Variable\n\t\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + wbo - 1, SCE_BAT_IDENTIFIER);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// not a valid expanded argument or variable\n\t\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + wbo - 1, SCE_BAT_DEFAULT);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + wbo;\n\t\t\t\t\t// Check for Environment Variable (%x...%)\n\t\t\t\t\t} else if ((word[1] != '%') && (word[wbo] == '%')) {\n\t\t\t\t\t\twbo++;\n\t\t\t\t\t\t// Check for External Command / Program\n\t\t\t\t\t\tif (cmdLoc == wordStart) {\n\t\t\t\t\t\t\tcmdLoc = wordStart + wbo;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Colorize Environment Variable\n\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + wbo - 1, SCE_BAT_IDENTIFIER);\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + wbo;\n\t\t\t\t\t// Check for Local Variable (%%a)\n\t\t\t\t\t} else if (\n\t\t\t\t\t\t(wbl > 2) &&\n\t\t\t\t\t\t(word[1] == '%') &&\n\t\t\t\t\t\t(word[2] != '%') &&\n\t\t\t\t\t\t(!IsBPunctuation(word[2]))) {\n\t\t\t\t\t\t// Check for External Command / Program\n\t\t\t\t\t\tif (cmdLoc == wordStart) {\n\t\t\t\t\t\t\tcmdLoc = wordStart + 3;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Colorize Local Variable\n\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + 2, SCE_BAT_IDENTIFIER);\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + 3;\n\t\t\t\t\t// escaped %\n\t\t\t\t\t} else if (\n\t\t\t\t\t\t(wbl > 1) &&\n\t\t\t\t\t\t(word[1] == '%')) {\n\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + 1, SCE_BAT_DEFAULT);\n\t\t\t\t\t\toffset = wordStart + 2;\n\t\t\t\t\t}\n\t\t\t\t// Check for Environment Variable (!x...!)\n\t\t\t\t} else if (first == '!') {\n\t\t\t\t\t// Colorize Default Text\n\t\t\t\t\tstyler.ColourTo(startLine + wordStart - 1, SCE_BAT_DEFAULT);\n\t\t\t\t\tconst size_t nextExclamation = word.find('!', 1);\n\t\t\t\t\tif (nextExclamation != std::string::npos) {\n\t\t\t\t\t\t// Check for External Command / Program\n\t\t\t\t\t\tif (cmdLoc == wordStart) {\n\t\t\t\t\t\t\tcmdLoc = wordStart + nextExclamation + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Colorize Environment Variable\n\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + nextExclamation, SCE_BAT_IDENTIFIER);\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + nextExclamation + 1;\n\t\t\t\t\t}\n\t\t\t\t// Check for Operator\n\t\t\t\t} else if (IsBOperator(first)) {\n\t\t\t\t\t// Colorize Default Text\n\t\t\t\t\tstyler.ColourTo(startLine + wordStart - 1, SCE_BAT_DEFAULT);\n\t\t\t\t\t// Check for Comparison Operator\n\t\t\t\t\tif ((first == '=') && (word[1] == '=')) {\n\t\t\t\t\t\t// Identify External Command / Program Location for IF\n\t\t\t\t\t\tcmdLoc = offset;\n\t\t\t\t\t\t// Skip next spaces\n\t\t\t\t\t\tSkipSpace(cmdLoc, lineBuffer);\n\t\t\t\t\t\t// Colorize Comparison Operator\n\t\t\t\t\t\tif (continueProcessing)\n\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + 1, SCE_BAT_OPERATOR);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart + 1, SCE_BAT_DEFAULT);\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + 2;\n\t\t\t\t\t// Check for Pipe Operator\n\t\t\t\t\t} else if ((first == '|') &&\n\t\t\t\t\t\t\t\t!(IsEscaped(lineBuffer, wordStart + wbo) || textQuoted(lineBuffer, wordStart))) {\n\t\t\t\t\t\t// Reset External Command / Program Location\n\t\t\t\t\t\tcmdLoc = wordStart + 1;\n\t\t\t\t\t\t// Skip next spaces\n\t\t\t\t\t\tSkipSpace(cmdLoc, lineBuffer);\n\t\t\t\t\t\t// Colorize Pipe Operator\n\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart, SCE_BAT_OPERATOR);\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + 1;\n\t\t\t\t\t\tcontinueProcessing = true;\n\t\t\t\t\t// Check for Other Operator\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Check for Operators: >, |, &\n\t\t\t\t\t\tif ((AnyOf(first, '>', ')', '(', '&')) &&\n\t\t\t\t\t\t   !(!continueProcessing && (IsEscaped(lineBuffer, wordStart + wbo)\n\t\t\t\t\t\t   || textQuoted(lineBuffer, wordStart)))){\n\t\t\t\t\t\t\t// Turn Keyword and External Command / Program checking back on\n\t\t\t\t\t\t\tcontinueProcessing = true;\n\t\t\t\t\t\t\tisNotAssigned=false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Colorize Other Operators\n\t\t\t\t\t\t// Do not Colorize Parenthesis, quoted text and escaped operators\n\t\t\t\t\t\tif ((!AnyOf(first, ')', '(')\n\t\t\t\t\t\t&& !textQuoted(lineBuffer, wordStart) && !IsEscaped(lineBuffer, wordStart + wbo))\n\t\t\t\t\t\t&& !((first == '=') && !isNotAssigned))\n\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart, SCE_BAT_OPERATOR);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstyler.ColourTo(startLine + wordStart, SCE_BAT_DEFAULT);\n\t\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\t\toffset = wordStart + 1;\n\n\t\t\t\t\t\tif ((first == '=') && isNotAssigned){\n\t\t\t\t\t\t\tisNotAssigned=false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t// Check for Default Text\n\t\t\t\t} else {\n\t\t\t\t\t// Read up to %, !, Operator or Separator\n\t\t\t\t\tconst Sci_PositionU lengthWord = WordLength(word);\n\t\t\t\t\t// Colorize Default Text\n\t\t\t\t\tstyler.ColourTo(startLine + wordStart + lengthWord - 1, SCE_BAT_DEFAULT);\n\t\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\t\toffset = wordStart + lengthWord;\n\t\t\t\t}\n\t\t\t\t// Skip next spaces - nothing happens if Offset was Reset\n\t\t\t\tSkipSpace(offset, lineBuffer);\n\t\t\t}\n\t\t\t// Colorize Default Text for remainder of line - currently not lexed\n\t\t\tstyler.ColourTo(endPos, SCE_BAT_DEFAULT);\n\n\t\t\t// handle line continuation for SET and ECHO commands except the last line\n\t\t\tif (!continueProcessing && (i<startPos + length-1)) {\n\t\t\t\t// Reset continueProcessing if line continuation was not found\n\t\t\t\tcontinueProcessing = !IsContinuation(lineBuffer);\n\t\t\t}\n\n\t\t\tlineBuffer.clear();\n\t\t\tstartLine = i + 1;\n\t\t}\n\t}\n\tstyler.Flush();\n}\n\n}\n\nextern const LexerModule lmBatch(SCLEX_BATCH, LexerBatch::LexerFactoryBatch, \"batch\", batchWordListDesc);\n"
  },
  {
    "path": "lexers/LexBibTeX.cxx",
    "content": "// Copyright 2008-2010 Sergiu Dotenco. The License.txt file describes the\n// conditions under which this software may be distributed.\n\n/**\n * @file LexBibTeX.cxx\n * @brief General BibTeX coloring scheme.\n * @author Sergiu Dotenco\n * @date April 18, 2009\n */\n\n#include <stdlib.h>\n#include <string.h>\n\n#include <cassert>\n#include <cctype>\n\n#include <string>\n#include <string_view>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\tbool IsAlphabetic(unsigned int ch)\n\t{\n\t\treturn IsASCII(ch) && std::isalpha(ch) != 0;\n\t}\n\tbool IsAlphaNumeric(char ch)\n\t{\n\t    return IsASCII(ch) && std::isalnum(ch);\n\t}\n\n\tbool EqualCaseInsensitive(const char* a, const char* b)\n\t{\n\t\treturn CompareCaseInsensitive(a, b) == 0;\n\t}\n\n\tbool EntryWithoutKey(const char* name)\n\t{\n\t\treturn EqualCaseInsensitive(name,\"string\");\n\t}\n\n\tchar GetClosingBrace(char openbrace)\n\t{\n\t\tchar result = openbrace;\n\n\t\tswitch (openbrace) {\n\t\t\tcase '(': result = ')'; break;\n\t\t\tcase '{': result = '}'; break;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tbool IsEntryStart(char prev, char ch)\n\t{\n\t\treturn prev != '\\\\' && ch == '@';\n\t}\n\n\tbool IsEntryStart(const StyleContext& sc)\n\t{\n\t\treturn IsEntryStart(sc.chPrev, sc.ch);\n\t}\n\n\tvoid ColorizeBibTeX(Sci_PositionU start_pos, Sci_Position length, int /*init_style*/, WordList* keywordlists[], Accessor& styler)\n\t{\n\t    WordList &EntryNames = *keywordlists[0];\n\t\tbool fold_compact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\n\t\tstd::string buffer;\n\t\tbuffer.reserve(25);\n\n\t\t// We always colorize a section from the beginning, so let's\n\t\t// search for the @ character which isn't escaped, i.e. \\@\n\t\twhile (start_pos > 0 && !IsEntryStart(styler.SafeGetCharAt(start_pos - 1),\n\t\t\tstyler.SafeGetCharAt(start_pos))) {\n\t\t\t--start_pos; ++length;\n\t\t}\n\n\t\tstyler.StartAt(start_pos);\n\t\tstyler.StartSegment(start_pos);\n\n\t\tSci_Position current_line = styler.GetLine(start_pos);\n\t\tint prev_level = styler.LevelAt(current_line) & SC_FOLDLEVELNUMBERMASK;\n\t\tint current_level = prev_level;\n\t\tint visible_chars = 0;\n\n\t\tbool in_comment = false ;\n\t\tStyleContext sc(start_pos, length, SCE_BIBTEX_DEFAULT, styler);\n\n\t\tbool going = sc.More(); // needed because of a fuzzy end of file state\n\t\tchar closing_brace = 0;\n\t\tbool collect_entry_name = false;\n\n\t\tfor (; going; sc.Forward()) {\n\t\t\tif (!sc.More())\n\t\t\t\tgoing = false; // we need to go one behind the end of text\n\n\t\t\tif (in_comment) {\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.SetState(SCE_BIBTEX_DEFAULT);\n\t\t\t\t\tin_comment = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Found @entry\n\t\t\t\tif (IsEntryStart(sc)) {\n\t\t\t\t\tsc.SetState(SCE_BIBTEX_UNKNOWN_ENTRY);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\t++current_level;\n\n\t\t\t\t\tbuffer.clear();\n\t\t\t\t\tcollect_entry_name = true;\n\t\t\t\t}\n\t\t\t\telse if ((sc.state == SCE_BIBTEX_ENTRY || sc.state == SCE_BIBTEX_UNKNOWN_ENTRY)\n\t\t\t\t\t&& (sc.ch == '{' || sc.ch == '(')) {\n\t\t\t\t\t// Entry name colorization done\n\t\t\t\t\t// Found either a { or a ( after entry's name, e.g. @entry(...) @entry{...}\n\t\t\t\t\t// Closing counterpart needs to be stored.\n\t\t\t\t\tclosing_brace = GetClosingBrace(sc.ch);\n\n\t\t\t\t\tsc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize { (\n\n\t\t\t\t\t// @string doesn't have any key\n\t\t\t\t\tif (EntryWithoutKey(buffer.c_str()))\n\t\t\t\t\t\tsc.ForwardSetState(SCE_BIBTEX_PARAMETER);\n\t\t\t\t\telse\n\t\t\t\t\t\tsc.ForwardSetState(SCE_BIBTEX_KEY); // Key/label colorization\n\t\t\t\t}\n\n\t\t\t\t// Need to handle the case where entry's key is empty\n\t\t\t\t// e.g. @book{,...}\n\t\t\t\tif (sc.state == SCE_BIBTEX_KEY && sc.ch == ',') {\n\t\t\t\t\t// Key/label colorization done\n\t\t\t\t\tsc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize the ,\n\t\t\t\t\tsc.ForwardSetState(SCE_BIBTEX_PARAMETER); // Parameter colorization\n\t\t\t\t}\n\t\t\t\telse if (sc.state == SCE_BIBTEX_PARAMETER && sc.ch == '=') {\n\t\t\t\t\tsc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize the =\n\t\t\t\t\tsc.ForwardSetState(SCE_BIBTEX_VALUE); // Parameter value colorization\n\n\t\t\t\t\tSci_Position start = sc.currentPos;\n\n\t\t\t\t\t// We need to handle multiple situations:\n\t\t\t\t\t// 1. name\"one two {three}\"\n\t\t\t\t\t// 2. name={one {one two {two}} three}\n\t\t\t\t\t// 3. year=2005\n\n\t\t\t\t\t// Skip \", { until we encounter the first alphanumerical character\n\t\t\t\t\twhile (sc.More() && !(IsAlphaNumeric(sc.ch) || sc.ch == '\"' || sc.ch == '{'))\n\t\t\t\t\t\tsc.Forward();\n\n\t\t\t\t\tif (sc.More()) {\n\t\t\t\t\t\t// Store \" or {\n\t\t\t\t\t\tchar ch = sc.ch;\n\n\t\t\t\t\t\t// Not interested in alphanumerical characters\n\t\t\t\t\t\tif (IsAlphaNumeric(ch))\n\t\t\t\t\t\t\tch = 0;\n\n\t\t\t\t\t\tint skipped = 0;\n\n\t\t\t\t\t\tif (ch) {\n\t\t\t\t\t\t\t// Skip preceding \" or { such as in name={{test}}.\n\t\t\t\t\t\t\t// Remember how many characters have been skipped\n\t\t\t\t\t\t\t// Make sure that empty values, i.e. \"\" are also handled correctly\n\t\t\t\t\t\t\twhile (sc.More() && (sc.ch == ch && (ch != '\"' || skipped < 1))) {\n\t\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t\t\t++skipped;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Closing counterpart for \" is the same character\n\t\t\t\t\t\tif (ch == '{')\n\t\t\t\t\t\t\tch = '}';\n\n\t\t\t\t\t\t// We have reached the parameter value\n\t\t\t\t\t\t// In case the open character was a alnum char, skip until , is found\n\t\t\t\t\t\t// otherwise until skipped == 0\n\t\t\t\t\t\twhile (sc.More() && (skipped > 0 || (!ch && !(sc.ch == ',' || sc.ch == closing_brace)))) {\n\t\t\t\t\t\t\t// Make sure the character isn't escaped\n\t\t\t\t\t\t\tif (sc.chPrev != '\\\\') {\n\t\t\t\t\t\t\t\t// Parameter value contains a { which is the 2nd case described above\n\t\t\t\t\t\t\t\tif (sc.ch == '{')\n\t\t\t\t\t\t\t\t\t++skipped; // Remember it\n\t\t\t\t\t\t\t\telse if (sc.ch == '}')\n\t\t\t\t\t\t\t\t\t--skipped;\n\t\t\t\t\t\t\t\telse if (skipped == 1 && sc.ch == ch && ch == '\"') // Don't ignore cases like {\"o}\n\t\t\t\t\t\t\t\t\tskipped = 0;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Don't colorize the ,\n\t\t\t\t\tsc.SetState(SCE_BIBTEX_DEFAULT);\n\n\t\t\t\t\t// Skip until the , or entry's closing closing_brace is found\n\t\t\t\t\t// since this parameter might be the last one\n\t\t\t\t\twhile (sc.More() && !(sc.ch == ',' || sc.ch == closing_brace))\n\t\t\t\t\t\tsc.Forward();\n\n\t\t\t\t\tint state = SCE_BIBTEX_PARAMETER; // The might be more parameters\n\n\t\t\t\t\t// We've reached the closing closing_brace for the bib entry\n\t\t\t\t\t// in case no \" or {} has been used to enclose the value,\n\t\t\t\t\t// as in 3rd case described above\n\t\t\t\t\tif (sc.ch == closing_brace) {\n\t\t\t\t\t\t--current_level;\n\t\t\t\t\t\t// Make sure the text between entries is not colored\n\t\t\t\t\t\t// using parameter's style\n\t\t\t\t\t\tstate = SCE_BIBTEX_DEFAULT;\n\t\t\t\t\t}\n\n\t\t\t\t\tSci_Position end = sc.currentPos;\n\t\t\t\t\tcurrent_line = styler.GetLine(end);\n\n\t\t\t\t\t// We have possibly skipped some lines, so the folding levels\n\t\t\t\t\t// have to be adjusted separately\n\t\t\t\t\tfor (Sci_Position i = styler.GetLine(start); i <= styler.GetLine(end); ++i)\n\t\t\t\t\t\tstyler.SetLevel(i, prev_level);\n\n\t\t\t\t\tsc.ForwardSetState(state);\n\t\t\t\t}\n\n\t\t\t\tif (sc.state == SCE_BIBTEX_PARAMETER && sc.ch == closing_brace) {\n\t\t\t\t\tsc.SetState(SCE_BIBTEX_DEFAULT);\n\t\t\t\t\t--current_level;\n\t\t\t\t}\n\n\t\t\t\t// Non escaped % found which represents a comment until the end of the line\n\t\t\t\tif (sc.chPrev != '\\\\' && sc.ch == '%') {\n\t\t\t\t\tin_comment = true;\n\t\t\t\t\tsc.SetState(SCE_BIBTEX_COMMENT);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (sc.state == SCE_BIBTEX_UNKNOWN_ENTRY || sc.state == SCE_BIBTEX_ENTRY) {\n\t\t\t\tif (!IsAlphabetic(sc.ch) && collect_entry_name)\n\t\t\t\t\tcollect_entry_name = false;\n\n\t\t\t\tif (collect_entry_name) {\n\t\t\t\t\tbuffer += static_cast<char>(tolower(sc.ch));\n                    if (EntryNames.InList(buffer.c_str()))\n                        sc.ChangeState(SCE_BIBTEX_ENTRY);\n                    else\n                        sc.ChangeState(SCE_BIBTEX_UNKNOWN_ENTRY);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tint level = prev_level;\n\n\t\t\t\tif (visible_chars == 0 && fold_compact)\n\t\t\t\t\tlevel |= SC_FOLDLEVELWHITEFLAG;\n\n\t\t\t\tif ((current_level > prev_level))\n\t\t\t\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t// else if (current_level < prev_level)\n\t\t\t\t//\tlevel |= SC_FOLDLEVELBOXFOOTERFLAG; // Deprecated\n\n\t\t\t\tif (level != styler.LevelAt(current_line)) {\n\t\t\t\t\tstyler.SetLevel(current_line, level);\n\t\t\t\t}\n\n\t\t\t\t++current_line;\n\t\t\t\tprev_level = current_level;\n\t\t\t\tvisible_chars = 0;\n\t\t\t}\n\n\t\t\tif (!isspacechar(sc.ch))\n\t\t\t\t++visible_chars;\n\t\t}\n\n\t\tsc.Complete();\n\n\t\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\t\tint flagsNext = styler.LevelAt(current_line) & ~SC_FOLDLEVELNUMBERMASK;\n\t\tstyler.SetLevel(current_line, prev_level | flagsNext);\n\t}\n}\nstatic const char * const BibTeXWordLists[] = {\n            \"Entry Names\",\n            0,\n};\n\n\nextern const LexerModule lmBibTeX(SCLEX_BIBTEX, ColorizeBibTeX, \"bib\", 0, BibTeXWordLists);\n\n// Entry Names\n//    article, book, booklet, conference, inbook,\n//    incollection, inproceedings, manual, mastersthesis,\n//    misc, phdthesis, proceedings, techreport, unpublished,\n//    string, url\n\n"
  },
  {
    "path": "lexers/LexBullant.cxx",
    "content": "// SciTE - Scintilla based Text Editor\n// LexBullant.cxx - lexer for Bullant\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic int classifyWordBullant(Sci_PositionU start, Sci_PositionU end, WordList &keywords, Accessor &styler) {\n\tchar s[100];\n\ts[0] = '\\0';\n\tfor (Sci_PositionU i = 0; i < end - start + 1 && i < 30; i++) {\n\t\ts[i] = static_cast<char>(tolower(styler[start + i]));\n\t\ts[i + 1] = '\\0';\n\t}\n\tint lev= 0;\n\tchar chAttr = SCE_C_IDENTIFIER;\n\tif (isdigit(s[0]) || (s[0] == '.')){\n\t\tchAttr = SCE_C_NUMBER;\n\t}\n\telse {\n\t\tif (keywords.InList(s)) {\n\t\t\tchAttr = SCE_C_WORD;\n\t\t\tif (strcmp(s, \"end\") == 0)\n\t\t\t\tlev = -1;\n\t\t\telse if (strcmp(s, \"method\") == 0 ||\n\t\t\t\tstrcmp(s, \"case\") == 0 ||\n\t\t\t\tstrcmp(s, \"class\") == 0 ||\n\t\t\t\tstrcmp(s, \"debug\") == 0 ||\n\t\t\t\tstrcmp(s, \"test\") == 0 ||\n\t\t\t\tstrcmp(s, \"if\") == 0 ||\n\t\t\t\tstrcmp(s, \"lock\") == 0 ||\n\t\t\t\tstrcmp(s, \"transaction\") == 0 ||\n\t\t\t\tstrcmp(s, \"trap\") == 0 ||\n\t\t\t\tstrcmp(s, \"until\") == 0 ||\n\t\t\t\tstrcmp(s, \"while\") == 0)\n\t\t\t\tlev = 1;\n\t\t}\n\t}\n\tstyler.ColourTo(end, chAttr);\n\treturn lev;\n}\n\nstatic void ColouriseBullantDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n\tAccessor &styler) {\n\tWordList &keywords = *keywordlists[0];\n\n\tstyler.StartAt(startPos);\n\n\tbool fold = styler.GetPropertyInt(\"fold\") != 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\n\tint state = initStyle;\n\tif (state == SCE_C_STRINGEOL)\t// Does not leak onto next line\n\t\tstate = SCE_C_DEFAULT;\n\tchar chPrev = ' ';\n\tchar chNext = styler[startPos];\n\tSci_PositionU lengthDoc = startPos + length;\n\tint visibleChars = 0;\n\tstyler.StartSegment(startPos);\n\tint endFoundThisLine = 0;\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n')) {\n\t\t\t// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)\n\t\t\t// Avoid triggering two times on Dos/Win\n\t\t\t// End of line\n\t\t\tendFoundThisLine = 0;\n\t\t\tif (state == SCE_C_STRINGEOL) {\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t}\n\t\t\tif (fold) {\n\t\t\t\tint lev = levelPrev;\n\t\t\t\tif (visibleChars == 0)\n\t\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t\tlineCurrent++;\n\t\t\t\tlevelPrev = levelCurrent;\n\t\t\t}\n\t\t\tvisibleChars = 0;\n\n/*\t\t\tint indentBlock = GetLineIndentation(lineCurrent);\n\t\t\tif (blockChange==1){\n\t\t\t\tlineCurrent++;\n\t\t\t\tint pos=SetLineIndentation(lineCurrent, indentBlock + indentSize);\n\t\t\t} else if (blockChange==-1) {\n\t\t\t\tindentBlock -= indentSize;\n\t\t\t\tif (indentBlock < 0)\n\t\t\t\t\tindentBlock = 0;\n\t\t\t\tSetLineIndentation(lineCurrent, indentBlock);\n\t\t\t\tlineCurrent++;\n\t\t\t}\n\t\t\tblockChange=0;\n*/\t\t}\n\t\tif (!(IsASCII(ch) && isspace(ch)))\n\t\t\tvisibleChars++;\n\n\t\tif (styler.IsLeadByte(ch)) {\n\t\t\tchNext = styler.SafeGetCharAt(i + 2);\n\t\t\tchPrev = ' ';\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (state == SCE_C_DEFAULT) {\n\t\t\tif (iswordstart(ch)) {\n\t\t\t\tstyler.ColourTo(i-1, state);\n\t\t\t\t\tstate = SCE_C_IDENTIFIER;\n\t\t\t} else if (ch == '@' && chNext == 'o') {\n\t\t\t\tif ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) {\n\t\t\t\t\tstyler.ColourTo(i-1, state);\n\t\t\t\t\tstate = SCE_C_COMMENT;\n\t\t\t\t}\n\t\t\t} else if (ch == '#') {\n\t\t\t\tstyler.ColourTo(i-1, state);\n\t\t\t\tstate = SCE_C_COMMENTLINE;\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i-1, state);\n\t\t\t\tstate = SCE_C_STRING;\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i-1, state);\n\t\t\t\tstate = SCE_C_CHARACTER;\n\t\t\t} else if (isoperator(ch)) {\n\t\t\t\tstyler.ColourTo(i-1, state);\n\t\t\t\tstyler.ColourTo(i, SCE_C_OPERATOR);\n\t\t\t}\n\t\t} else if (state == SCE_C_IDENTIFIER) {\n\t\t\tif (!iswordchar(ch)) {\n\t\t\t\tint levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler);\n\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\tif (ch == '#') {\n\t\t\t\t\tstate = SCE_C_COMMENTLINE;\n\t\t\t\t} else if (ch == '\\\"') {\n\t\t\t\t\tstate = SCE_C_STRING;\n\t\t\t\t} else if (ch == '\\'') {\n\t\t\t\t\tstate = SCE_C_CHARACTER;\n\t\t\t\t} else if (isoperator(ch)) {\n\t\t\t\t\tstyler.ColourTo(i, SCE_C_OPERATOR);\n\t\t\t\t}\n\t\t\t\tif (endFoundThisLine == 0)\n\t\t\t\t\tlevelCurrent+=levelChange;\n\t\t\t\tif (levelChange == -1)\n\t\t\t\t\tendFoundThisLine=1;\n\t\t\t}\n\t\t} else if (state == SCE_C_COMMENT) {\n\t\t\tif (ch == '@' && chNext == 'o') {\n\t\t\t\tif (styler.SafeGetCharAt(i+2) == 'n') {\n\t\t\t\t\tstyler.ColourTo(i+2, state);\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t\ti+=2;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (state == SCE_C_COMMENTLINE) {\n\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\tendFoundThisLine = 0;\n\t\t\t\tstyler.ColourTo(i-1, state);\n\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t}\n\t\t} else if (state == SCE_C_STRING) {\n\t\t\tif (ch == '\\\\') {\n\t\t\t\tif (chNext == '\\\"' || chNext == '\\'' || chNext == '\\\\') {\n\t\t\t\t\ti++;\n\t\t\t\t\tch = chNext;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t}\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t} else if (chNext == '\\r' || chNext == '\\n') {\n\t\t\t\tendFoundThisLine = 0;\n\t\t\t\tstyler.ColourTo(i-1, SCE_C_STRINGEOL);\n\t\t\t\tstate = SCE_C_STRINGEOL;\n\t\t\t}\n\t\t} else if (state == SCE_C_CHARACTER) {\n\t\t\tif ((ch == '\\r' || ch == '\\n') && (chPrev != '\\\\')) {\n\t\t\t\tendFoundThisLine = 0;\n\t\t\t\tstyler.ColourTo(i-1, SCE_C_STRINGEOL);\n\t\t\t\tstate = SCE_C_STRINGEOL;\n\t\t\t} else if (ch == '\\\\') {\n\t\t\t\tif (chNext == '\\\"' || chNext == '\\'' || chNext == '\\\\') {\n\t\t\t\t\ti++;\n\t\t\t\t\tch = chNext;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t}\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t}\n\t\t}\n\t\tchPrev = ch;\n\t}\n\tstyler.ColourTo(lengthDoc - 1, state);\n\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tif (fold) {\n\t\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\t\t//styler.SetLevel(lineCurrent, levelCurrent | flagsNext);\n\t\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n\n\t}\n}\n\nstatic const char * const bullantWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, \"bullant\", 0, bullantWordListDesc);\n"
  },
  {
    "path": "lexers/LexCIL.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexCIL.cxx\n ** Lexer for Common Intermediate Language\n ** Written by Jad Altahan (github.com/xv)\n ** CIL manual: https://www.ecma-international.org/publications/standards/Ecma-335.htm\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"StringCopy.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n    // Use an unnamed namespace to protect the functions and classes from name conflicts\n\nbool IsAWordChar(const int ch) {\n    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');\n}\n\nbool IsOperator(const int ch) {\n    if ((ch < 0x80) && (isalnum(ch)))\n        return false;\n\n    if (strchr(\"!%&*+-/<=>@^|~()[]{}\", ch)) {\n        return true;\n    }\n\n    return false;\n}\n\nconstexpr bool IsStreamCommentStyle(const int style) noexcept {\n    return style == SCE_CIL_COMMENT;\n}\n\nstruct OptionsCIL {\n    bool fold;\n    bool foldComment;\n    bool foldCommentMultiline;\n    bool foldCompact;\n\n    OptionsCIL() {\n        fold = true;\n        foldComment = false;\n        foldCommentMultiline = true;\n        foldCompact = true;\n    }\n};\n\nstatic const char *const cilWordListDesc[] = {\n    \"Primary CIL keywords\",\n    \"Metadata\",\n    \"Opcode instructions\",\n    0\n};\n\nstruct OptionSetCIL : public OptionSet<OptionsCIL> {\n    OptionSetCIL() {\n        DefineProperty(\"fold\", &OptionsCIL::fold);\n        DefineProperty(\"fold.comment\", &OptionsCIL::foldComment);\n\n        DefineProperty(\"fold.cil.comment.multiline\", &OptionsCIL::foldCommentMultiline,\n            \"Set this property to 0 to disable folding multi-line comments when fold.comment=1.\");\n\n        DefineProperty(\"fold.compact\", &OptionsCIL::foldCompact);\n\n        DefineWordListSets(cilWordListDesc);\n    }\n};\n\nLexicalClass lexicalClasses[] = {\n    // Lexer CIL SCLEX_CIL SCE_CIL_:\n    0,  \"SCE_CIL_DEFAULT\",     \"default\",              \"White space\",\n    1,  \"SCE_CIL_COMMENT\",     \"comment\",              \"Multi-line comment\",\n    2,  \"SCE_CIL_COMMENTLINE\", \"comment line\",         \"Line comment\",\n    3,  \"SCE_CIL_WORD\",        \"keyword\",              \"Keyword 1\",\n    4,  \"SCE_CIL_WORD2\",       \"keyword\",              \"Keyword 2\",\n    5,  \"SCE_CIL_WORD3\",       \"keyword\",              \"Keyword 3\",\n    6,  \"SCE_CIL_STRING\",      \"literal string\",       \"Double quoted string\",\n    7,  \"SCE_CIL_LABEL\",       \"label\",                \"Code label\",\n    8,  \"SCE_CIL_OPERATOR\",    \"operator\",             \"Operators\",\n    9, \"SCE_CIL_IDENTIFIER\",  \"identifier\",           \"Identifiers\",\n    10,  \"SCE_CIL_STRINGEOL\",   \"error literal string\", \"String is not closed\",\n};\n\n}\n\nclass LexerCIL : public DefaultLexer {\n    WordList keywords, keywords2, keywords3;\n    OptionsCIL options;\n    OptionSetCIL osCIL;\n\npublic:\n    LexerCIL() : DefaultLexer(\"cil\", SCLEX_CIL, lexicalClasses, ELEMENTS(lexicalClasses)) { }\n\n    virtual ~LexerCIL() { }\n\n    void SCI_METHOD Release() override {\n        delete this;\n    }\n\n    int SCI_METHOD Version() const override {\n        return lvRelease5;\n    }\n\n    const char * SCI_METHOD PropertyNames() override {\n        return osCIL.PropertyNames();\n    }\n\n    int SCI_METHOD PropertyType(const char *name) override {\n        return osCIL.PropertyType(name);\n    }\n\n    const char * SCI_METHOD DescribeProperty(const char *name) override {\n        return osCIL.DescribeProperty(name);\n    }\n\n    Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\n\tconst char * SCI_METHOD PropertyGet(const char* key) override {\n\t\treturn osCIL.PropertyGet(key);\n\t}\n\n    const char * SCI_METHOD DescribeWordListSets() override {\n        return osCIL.DescribeWordListSets();\n    }\n\n    Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n    void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n    void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n    void * SCI_METHOD PrivateCall(int, void *) override {\n        return 0;\n    }\n\n    int SCI_METHOD LineEndTypesSupported() override {\n        return SC_LINE_END_TYPE_UNICODE;\n    }\n\n    int SCI_METHOD PrimaryStyleFromStyle(int style) override {\n        return style;\n    }\n\n    static ILexer5 *LexerFactoryCIL() {\n        return new LexerCIL();\n    }\n};\n\nSci_Position SCI_METHOD LexerCIL::PropertySet(const char *key, const char *val) {\n    if (osCIL.PropertySet(&options, key, val)) {\n        return 0;\n    }\n\n    return -1;\n}\n\nSci_Position SCI_METHOD LexerCIL::WordListSet(int n, const char *wl) {\n    WordList *wordListN = 0;\n\n    switch (n) {\n        case 0:\n            wordListN = &keywords;\n            break;\n        case 1:\n            wordListN = &keywords2;\n            break;\n        case 2:\n            wordListN = &keywords3;\n            break;\n    }\n\n    Sci_Position firstModification = -1;\n\n    if (wordListN) {\n        WordList wlNew;\n        wlNew.Set(wl);\n\n        if (*wordListN != wlNew) {\n            wordListN->Set(wl);\n            firstModification = 0;\n        }\n    }\n\n    return firstModification;\n}\n\nvoid SCI_METHOD LexerCIL::Lex(Sci_PositionU startPos, Sci_Position length,\n                              int initStyle, IDocument *pAccess) {\n    if (initStyle == SCE_CIL_STRINGEOL) {\n        initStyle = SCE_CIL_DEFAULT;\n    }\n\n    Accessor styler(pAccess, NULL);\n    StyleContext sc(startPos, length, initStyle, styler);\n\n    bool identAtLineStart = false, // Checks if an identifier is at line start (ignoring spaces)\n         canStyleLabels = false;   // Checks if conditions are met to style SCE_CIL_LABEL\n\n    for (; sc.More(); sc.Forward()) {\n        if (sc.atLineStart) {\n            if (sc.state == SCE_CIL_STRING) {\n                sc.SetState(SCE_CIL_STRING);\n            }\n\n            identAtLineStart = true;\n        }\n\n        // Handle string line continuation\n        if (sc.ch == '\\\\' && (sc.chNext == '\\n' || sc.chNext == '\\r') &&\n           (sc.state == SCE_CIL_STRING)) {\n            sc.Forward();\n\n            if (sc.ch == '\\r' && sc.chNext == '\\n') {\n                sc.Forward();\n            }\n\n            continue;\n        }\n\n        switch (sc.state) {\n            case SCE_CIL_OPERATOR:\n                sc.SetState(SCE_CIL_DEFAULT);\n                break;\n            case SCE_CIL_IDENTIFIER:\n                if (!IsAWordChar(sc.ch)) {\n                    if (canStyleLabels && (sc.ch == ':' && sc.chNext != ':')) {\n                        sc.ChangeState(SCE_CIL_LABEL);\n                        sc.ForwardSetState(SCE_CIL_DEFAULT);\n                    } else {\n                        char kwSize[100];\n                        sc.GetCurrent(kwSize, sizeof(kwSize));\n                        int style = SCE_CIL_IDENTIFIER;\n\n                        if (keywords.InList(kwSize)) {\n                            style = SCE_CIL_WORD;\n                        } else if (keywords2.InList(kwSize)) {\n                            style = SCE_CIL_WORD2;\n                        } else if (keywords3.InList(kwSize)) {\n                            style = SCE_CIL_WORD3;\n                        }\n\n                        sc.ChangeState(style);\n                        sc.SetState(SCE_CIL_DEFAULT);\n                    }\n                }\n                break;\n            case SCE_CIL_COMMENT:\n                if (sc.Match('*', '/')) {\n                    sc.Forward();\n                    sc.ForwardSetState(SCE_CIL_DEFAULT);\n                }\n                break;\n            case SCE_CIL_COMMENTLINE:\n                if (sc.atLineStart) {\n                    sc.SetState(SCE_CIL_DEFAULT);\n                }\n                break;\n            case SCE_CIL_STRING:\n                if (sc.ch == '\\\\') {\n                    if (sc.chNext == '\"' || sc.chNext == '\\\\') {\n                        sc.Forward();\n                    }\n                } else if (sc.ch == '\"') {\n                    sc.ForwardSetState(SCE_CIL_DEFAULT);\n                } else if (sc.atLineEnd) {\n                    sc.ChangeState(SCE_CIL_STRINGEOL);\n                    sc.ForwardSetState(SCE_CIL_DEFAULT);\n                }\n                break;\n        }\n\n        if (sc.state == SCE_CIL_DEFAULT) {\n            // String\n            if (sc.ch == '\"') {\n                sc.SetState(SCE_CIL_STRING);\n            }\n            // Keyword\n            else if (IsAWordChar(sc.ch)) {\n                // Allow setting SCE_CIL_LABEL style only if the label is the\n                // first token in the line and does not start with a dot or a digit\n                canStyleLabels = identAtLineStart && !(sc.ch == '.' || IsADigit(sc.ch));\n                sc.SetState(SCE_CIL_IDENTIFIER);\n            }\n            // Multi-line comment\n            else if (sc.Match('/', '*')) {\n                sc.SetState(SCE_CIL_COMMENT);\n                sc.Forward();\n            }\n            // Line comment\n            else if (sc.Match('/', '/')) {\n                sc.SetState(SCE_CIL_COMMENTLINE);\n            }\n            // Operators\n            else if (IsOperator(sc.ch)) {\n                sc.SetState(SCE_CIL_OPERATOR);\n            }\n        }\n\n        if (!IsASpace(sc.ch)) {\n            identAtLineStart = false;\n        }\n    }\n\n    sc.Complete();\n}\n\nvoid SCI_METHOD LexerCIL::Fold(Sci_PositionU startPos, Sci_Position length, \n                               int initStyle, IDocument *pAccess) {\n    if (!options.fold) {\n        return;\n    }\n\n    LexAccessor styler(pAccess);\n\n    const Sci_PositionU endPos = startPos + length;\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n\n    int levelCurrent = SC_FOLDLEVELBASE;\n    if (lineCurrent > 0)\n        levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;\n    \n    int style = initStyle;\n    int styleNext = styler.StyleAt(startPos);\n    int levelNext = levelCurrent;\n    int visibleChars = 0;\n\n    char chNext = styler[startPos];\n\n    for (Sci_PositionU i = startPos; i < endPos; i++) {\n        const char ch = chNext;\n        int stylePrev = style;\n\n        chNext = styler.SafeGetCharAt(i + 1);\n        style = styleNext;\n        styleNext = styler.StyleAt(i + 1);\n\n        const bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n        if (options.foldComment && \n            options.foldCommentMultiline && IsStreamCommentStyle(style)) {\n            if (!IsStreamCommentStyle(stylePrev)) {\n                levelNext++;\n            } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n                levelNext--;\n            }\n        }\n\n        if (style == SCE_CIL_OPERATOR) {\n            if (ch == '{') {\n                levelNext++;\n            } else if (ch == '}') {\n                levelNext--;\n            }\n        }\n\n        if (!IsASpace(ch)) {\n            visibleChars++;\n        }\n\n        if (atEOL || (i == endPos - 1)) {\n            int lev = levelCurrent | levelNext << 16;\n            if (visibleChars == 0 && options.foldCompact)\n                lev |= SC_FOLDLEVELWHITEFLAG;\n            if (levelCurrent < levelNext)\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            if (lev != styler.LevelAt(lineCurrent)) {\n                styler.SetLevel(lineCurrent, lev);\n            }\n            \n            lineCurrent++;\n            levelCurrent = levelNext;\n            \n            if (options.foldCompact &&\n                i == static_cast<Sci_PositionU>(styler.Length() - 1)) {\n                styler.SetLevel(lineCurrent, lev | SC_FOLDLEVELWHITEFLAG);\n            }\n\n            visibleChars = 0;\n        }\n    }\n}\n\nextern const LexerModule lmCIL(SCLEX_CIL, LexerCIL::LexerFactoryCIL, \"cil\", cilWordListDesc);"
  },
  {
    "path": "lexers/LexCLW.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexCLW.cxx\n ** Lexer for Clarion.\n ** 2004/12/17 Updated Lexer\n **/\n// Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// Is an end of line character\ninline bool IsEOL(const int ch) {\n\n\treturn(ch == '\\n');\n}\n\n// Convert character to uppercase\nstatic char CharacterUpper(char chChar) {\n\n\tif (chChar < 'a' || chChar > 'z') {\n\t\treturn(chChar);\n\t}\n\telse {\n\t\treturn(static_cast<char>(chChar - 'a' + 'A'));\n\t}\n}\n\n// Convert string to uppercase\nstatic void StringUpper(char *szString) {\n\n\twhile (*szString) {\n\t\t*szString = CharacterUpper(*szString);\n\t\tszString++;\n\t}\n}\n\n// Is a label start character\ninline bool IsALabelStart(const int iChar) {\n\n\treturn(isalpha(iChar) || iChar == '_');\n}\n\n// Is a label character\ninline bool IsALabelCharacter(const int iChar) {\n\n\treturn(isalnum(iChar) || iChar == '_' || iChar == ':');\n}\n\n// Is the character is a ! and the the next character is not a !\ninline bool IsACommentStart(const int iChar) {\n\n\treturn(iChar == '!');\n}\n\n// Is the character a Clarion hex character (ABCDEF)\ninline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {\n\n\t// Case insensitive.\n\tif (!bCaseSensitive) {\n\t\tif (strchr(\"ABCDEFabcdef\", iChar) != NULL) {\n\t\t\treturn(true);\n\t\t}\n\t}\n\t// Case sensitive\n\telse {\n\t\tif (strchr(\"ABCDEF\", iChar) != NULL) {\n\t\t\treturn(true);\n\t\t}\n\t}\n\treturn(false);\n}\n\n// Is the character a Clarion base character (B=Binary, O=Octal, H=Hex)\ninline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) {\n\n\t// Case insensitive.\n\tif (!bCaseSensitive) {\n\t\t// If character is a numeric base character\n\t\tif (strchr(\"BOHboh\", iChar) != NULL) {\n\t\t\treturn(true);\n\t\t}\n\t}\n\t// Case sensitive\n\telse {\n\t\t// If character is a numeric base character\n\t\tif (strchr(\"BOH\", iChar) != NULL) {\n\t\t\treturn(true);\n\t\t}\n\t}\n\treturn(false);\n}\n\n// Set the correct numeric constant state\ninline bool SetNumericConstantState(StyleContext &scDoc) {\n\n\tint iPoints = 0;\t\t\t// Point counter\n\tchar cNumericString[512];\t// Numeric string buffer\n\n\t// Buffer the current numberic string\n\tscDoc.GetCurrent(cNumericString, sizeof(cNumericString));\n\t// Loop through the string until end of string (NULL termination)\n\tfor (int iIndex = 0; cNumericString[iIndex] != '\\0'; iIndex++) {\n\t\t// Depending on the character\n\t\tswitch (cNumericString[iIndex]) {\n\t\t\t// Is a . (point)\n\t\t\tcase '.' :\n\t\t\t\t// Increment point counter\n\t\t\t\tiPoints++;\n\t\t\t\tbreak;\n\t\t\tdefault :\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t// If points found (can be more than one for improper formatted number\n\tif (iPoints > 0) {\n\t\treturn(true);\n\t}\n\t// Else no points found\n\telse {\n\t\treturn(false);\n\t}\n}\n\n// Get the next word in uppercase from the current position (keyword lookahead)\ninline bool GetNextWordUpper(Accessor &styler, Sci_PositionU uiStartPos, Sci_Position iLength, char *cWord) {\n\n\tSci_PositionU iIndex = 0;\t\t// Buffer Index\n\n\t// Loop through the remaining string from the current position\n\tfor (Sci_Position iOffset = uiStartPos; iOffset < iLength; iOffset++) {\n\t\t// Get the character from the buffer using the offset\n\t\tchar cCharacter = styler[iOffset];\n\t\tif (IsEOL(cCharacter)) {\n\t\t\tbreak;\n\t\t}\n\t\t// If the character is alphabet character\n\t\tif (isalpha(cCharacter)) {\n\t\t\t// Add UPPERCASE character to the word buffer\n\t\t\tcWord[iIndex++] = CharacterUpper(cCharacter);\n\t\t}\n\t}\n\t// Add null termination\n\tcWord[iIndex] = '\\0';\n\t// If no word was found\n\tif (iIndex == 0) {\n\t\t// Return failure\n\t\treturn(false);\n\t}\n\t// Else word was found\n\telse {\n\t\t// Return success\n\t\treturn(true);\n\t}\n}\n\n// Clarion Language Colouring Procedure\nstatic void ColouriseClarionDoc(Sci_PositionU uiStartPos, Sci_Position iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {\n\n\tint iParenthesesLevel = 0;\t\t// Parenthese Level\n\tint iColumn1Label = false;\t\t// Label starts in Column 1\n\n\tWordList &wlClarionKeywords = *wlKeywords[0];\t\t\t// Clarion Keywords\n\tWordList &wlCompilerDirectives = *wlKeywords[1];\t\t// Compiler Directives\n\tWordList &wlRuntimeExpressions = *wlKeywords[2];\t\t// Runtime Expressions\n\tWordList &wlBuiltInProcsFuncs = *wlKeywords[3];\t\t\t// Builtin Procedures and Functions\n\tWordList &wlStructsDataTypes = *wlKeywords[4];\t\t\t// Structures and Data Types\n\tWordList &wlAttributes = *wlKeywords[5];\t\t\t\t// Procedure Attributes\n\tWordList &wlStandardEquates = *wlKeywords[6];\t\t\t// Standard Equates\n\tWordList &wlLabelReservedWords = *wlKeywords[7];\t\t// Clarion Reserved Keywords (Labels)\n\tWordList &wlProcLabelReservedWords = *wlKeywords[8];\t// Clarion Reserved Keywords (Procedure Labels)\n\n\tconst char wlProcReservedKeywordList[] =\n\t\"PROCEDURE FUNCTION\";\n\tWordList wlProcReservedKeywords;\n\twlProcReservedKeywords.Set(wlProcReservedKeywordList);\n\n\tconst char wlCompilerKeywordList[] =\n\t\"COMPILE OMIT\";\n\tWordList wlCompilerKeywords;\n\twlCompilerKeywords.Set(wlCompilerKeywordList);\n\n\tconst char wlLegacyStatementsList[] =\n\t\"BOF EOF FUNCTION POINTER SHARE\";\n\tWordList wlLegacyStatements;\n\twlLegacyStatements.Set(wlLegacyStatementsList);\n\n\tStyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);\n\n\t// lex source code\n    for (; scDoc.More(); scDoc.Forward())\n\t{\n\t\t//\n\t\t// Determine if the current state should terminate.\n\t\t//\n\n\t\t// Label State Handling\n\t\tif (scDoc.state == SCE_CLW_LABEL) {\n\t\t\t// If the character is not a valid label\n\t\t\tif (!IsALabelCharacter(scDoc.ch)) {\n\t\t\t\t// If the character is a . (dot syntax)\n\t\t\t\tif (scDoc.ch == '.') {\n\t\t\t\t\t// Turn off column 1 label flag as label now cannot be reserved work\n\t\t\t\t\tiColumn1Label = false;\n\t\t\t\t\t// Uncolour the . (dot) to default state, move forward one character,\n\t\t\t\t\t// and change back to the label state.\n\t\t\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t\t\t\tscDoc.Forward();\n\t\t\t\t\tscDoc.SetState(SCE_CLW_LABEL);\n\t\t\t\t}\n\t\t\t\t// Else check label\n\t\t\t\telse {\n\t\t\t\t\tchar cLabel[512];\t\t// Label buffer\n\t\t\t\t\t// Buffer the current label string\n\t\t\t\t\tscDoc.GetCurrent(cLabel,sizeof(cLabel));\n\t\t\t\t\t// If case insensitive, convert string to UPPERCASE to match passed keywords.\n\t\t\t\t\tif (!bCaseSensitive) {\n\t\t\t\t\t\tStringUpper(cLabel);\n\t\t\t\t\t}\n\t\t\t\t\t// Else if UPPERCASE label string is in the Clarion compiler keyword list\n\t\t\t\t\tif (wlCompilerKeywords.InList(cLabel) && iColumn1Label){\n\t\t\t\t\t\t// change the label to error state\n\t\t\t\t\t\tscDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);\n\t\t\t\t\t}\n\t\t\t\t\t// Else if UPPERCASE label string is in the Clarion reserved keyword list\n\t\t\t\t\telse if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){\n\t\t\t\t\t\t// change the label to error state\n\t\t\t\t\t\tscDoc.ChangeState(SCE_CLW_ERROR);\n\t\t\t\t\t}\n\t\t\t\t\t// Else if UPPERCASE label string is\n\t\t\t\t\telse if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {\n\t\t\t\t\t\tchar cWord[512];\t// Word buffer\n\t\t\t\t\t\t// Get the next word from the current position\n\t\t\t\t\t\tif (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) {\n\t\t\t\t\t\t\t// If the next word is a procedure reserved word\n\t\t\t\t\t\t\tif (wlProcReservedKeywords.InList(cWord)) {\n\t\t\t\t\t\t\t\t// Change the label to error state\n\t\t\t\t\t\t\t\tscDoc.ChangeState(SCE_CLW_ERROR);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Else if label string is in the compiler directive keyword list\n\t\t\t\t\telse if (wlCompilerDirectives.InList(cLabel)) {\n\t\t\t\t\t\t// change the state to compiler directive state\n\t\t\t\t\t\tscDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);\n\t\t\t\t\t}\n\t\t\t\t\t// Terminate the label state and set to default state\n\t\t\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Keyword State Handling\n\t\telse if (scDoc.state == SCE_CLW_KEYWORD) {\n\t\t\t// If character is : (colon)\n\t\t\tif (scDoc.ch == ':') {\n\t\t\t\tchar cEquate[512];\t\t// Equate buffer\n\t\t\t\t// Move forward to include : (colon) in buffer\n\t\t\t\tscDoc.Forward();\n\t\t\t\t// Buffer the equate string\n\t\t\t\tscDoc.GetCurrent(cEquate,sizeof(cEquate));\n\t\t\t\t// If case insensitive, convert string to UPPERCASE to match passed keywords.\n\t\t\t\tif (!bCaseSensitive) {\n\t\t\t\t\tStringUpper(cEquate);\n\t\t\t\t}\n\t\t\t\t// If statement string is in the equate list\n\t\t\t\tif (wlStandardEquates.InList(cEquate)) {\n\t\t\t\t\t// Change to equate state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If the character is not a valid label character\n\t\t\telse if (!IsALabelCharacter(scDoc.ch)) {\n\t\t\t\tchar cStatement[512];\t\t// Statement buffer\n\t\t\t\t// Buffer the statement string\n\t\t\t\tscDoc.GetCurrent(cStatement,sizeof(cStatement));\n\t\t\t\t// If case insensitive, convert string to UPPERCASE to match passed keywords.\n\t\t\t\tif (!bCaseSensitive) {\n\t\t\t\t\tStringUpper(cStatement);\n\t\t\t\t}\n\t\t\t\t// If statement string is in the Clarion keyword list\n\t\t\t\tif (wlClarionKeywords.InList(cStatement)) {\n\t\t\t\t\t// Change the statement string to the Clarion keyword state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_KEYWORD);\n\t\t\t\t}\n\t\t\t\t// Else if statement string is in the compiler directive keyword list\n\t\t\t\telse if (wlCompilerDirectives.InList(cStatement)) {\n\t\t\t\t\t// Change the statement string to the compiler directive state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);\n\t\t\t\t}\n\t\t\t\t// Else if statement string is in the runtime expressions keyword list\n\t\t\t\telse if (wlRuntimeExpressions.InList(cStatement)) {\n\t\t\t\t\t// Change the statement string to the runtime expressions state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS);\n\t\t\t\t}\n\t\t\t\t// Else if statement string is in the builtin procedures and functions keyword list\n\t\t\t\telse if (wlBuiltInProcsFuncs.InList(cStatement)) {\n\t\t\t\t\t// Change the statement string to the builtin procedures and functions state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION);\n\t\t\t\t}\n\t\t\t\t// Else if statement string is in the tructures and data types keyword list\n\t\t\t\telse if (wlStructsDataTypes.InList(cStatement)) {\n\t\t\t\t\t// Change the statement string to the structures and data types state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE);\n\t\t\t\t}\n\t\t\t\t// Else if statement string is in the procedure attribute keyword list\n\t\t\t\telse if (wlAttributes.InList(cStatement)) {\n\t\t\t\t\t// Change the statement string to the procedure attribute state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_ATTRIBUTE);\n\t\t\t\t}\n\t\t\t\t// Else if statement string is in the standard equate keyword list\n\t\t\t\telse if (wlStandardEquates.InList(cStatement)) {\n\t\t\t\t\t// Change the statement string to the standard equate state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);\n\t\t\t\t}\n\t\t\t\t// Else if statement string is in the deprecated or legacy keyword list\n\t\t\t\telse if (wlLegacyStatements.InList(cStatement)) {\n\t\t\t\t\t// Change the statement string to the standard equate state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_DEPRECATED);\n\t\t\t\t}\n\t\t\t\t// Else the statement string doesn't match any work list\n\t\t\t\telse {\n\t\t\t\t\t// Change the statement string to the default state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_DEFAULT);\n\t\t\t\t}\n\t\t\t\t// Terminate the keyword state and set to default state\n\t\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t\t}\n\t\t}\n\t\t// String State Handling\n\t\telse if (scDoc.state == SCE_CLW_STRING) {\n\t\t\t// If the character is an ' (single quote)\n\t\t\tif (scDoc.ch == '\\'') {\n\t\t\t\t// Set the state to default and move forward colouring\n\t\t\t\t// the ' (single quote) as default state\n\t\t\t\t// terminating the string state\n\t\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t\t\tscDoc.Forward();\n\t\t\t}\n\t\t\t// If the next character is an ' (single quote)\n\t\t\tif (scDoc.chNext == '\\'') {\n\t\t\t\t// Move forward one character and set to default state\n\t\t\t\t// colouring the next ' (single quote) as default state\n\t\t\t\t// terminating the string state\n\t\t\t\tscDoc.ForwardSetState(SCE_CLW_DEFAULT);\n\t\t\t\tscDoc.Forward();\n\t\t\t}\n\t\t}\n\t\t// Picture String State Handling\n\t\telse if (scDoc.state == SCE_CLW_PICTURE_STRING) {\n\t\t\t// If the character is an ( (open parenthese)\n\t\t\tif (scDoc.ch == '(') {\n\t\t\t\t// Increment the parenthese level\n\t\t\t\tiParenthesesLevel++;\n\t\t\t}\n\t\t\t// Else if the character is a ) (close parenthese)\n\t\t\telse if (scDoc.ch == ')') {\n\t\t\t\t// If the parenthese level is set to zero\n\t\t\t\t// parentheses matched\n\t\t\t\tif (!iParenthesesLevel) {\n\t\t\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t\t\t}\n\t\t\t\t// Else parenthese level is greater than zero\n\t\t\t\t// still looking for matching parentheses\n\t\t\t\telse {\n\t\t\t\t\t// Decrement the parenthese level\n\t\t\t\t\tiParenthesesLevel--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Standard Equate State Handling\n\t\telse if (scDoc.state == SCE_CLW_STANDARD_EQUATE) {\n\t\t\tif (!isalnum(scDoc.ch)) {\n\t\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t\t}\n\t\t}\n\t\t// Integer Constant State Handling\n\t\telse if (scDoc.state == SCE_CLW_INTEGER_CONSTANT) {\n\t\t\t// If the character is not a digit (0-9)\n\t\t\t// or character is not a hexidecimal character (A-F)\n\t\t\t// or character is not a . (point)\n\t\t\t// or character is not a numberic base character (B,O,H)\n\t\t\tif (!(isdigit(scDoc.ch)\n\t\t\t|| IsAHexCharacter(scDoc.ch, bCaseSensitive)\n\t\t\t|| scDoc.ch == '.'\n\t\t\t|| IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {\n\t\t\t\t// If the number was a real\n\t\t\t\tif (SetNumericConstantState(scDoc)) {\n\t\t\t\t\t// Colour the matched string to the real constant state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_REAL_CONSTANT);\n\t\t\t\t}\n\t\t\t\t// Else the number was an integer\n\t\t\t\telse {\n\t\t\t\t\t// Colour the matched string to an integer constant state\n\t\t\t\t\tscDoc.ChangeState(SCE_CLW_INTEGER_CONSTANT);\n\t\t\t\t}\n\t\t\t\t// Terminate the integer constant state and set to default state\n\t\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t//\n\t\t// Determine if a new state should be entered.\n\t\t//\n\n\t\t// Beginning of Line Handling\n\t\tif (scDoc.atLineStart) {\n\t\t\t// Reset the column 1 label flag\n\t\t\tiColumn1Label = false;\n\t\t\t// If column 1 character is a label start character\n\t\t\tif (IsALabelStart(scDoc.ch)) {\n\t\t\t\t// Label character is found in column 1\n\t\t\t\t// so set column 1 label flag and clear last column 1 label\n\t\t\t\tiColumn1Label = true;\n\t\t\t\t// Set the state to label\n\t\t\t\tscDoc.SetState(SCE_CLW_LABEL);\n\t\t\t}\n\t\t\t// else if character is a space or tab\n\t\t\telse if (IsASpace(scDoc.ch)){\n\t\t\t\t// Set to default state\n\t\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t\t}\n\t\t\t// else if comment start (!) or is an * (asterisk)\n\t\t\telse if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) {\n\t\t\t\t// then set the state to comment.\n\t\t\t\tscDoc.SetState(SCE_CLW_COMMENT);\n\t\t\t}\n\t\t\t// else the character is a ? (question mark)\n\t\t\telse if (scDoc.ch == '?') {\n\t\t\t\t// Change to the compiler directive state, move forward,\n\t\t\t\t// colouring the ? (question mark), change back to default state.\n\t\t\t\tscDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);\n\t\t\t\tscDoc.Forward();\n\t\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t\t}\n\t\t\t// else an invalid character in column 1\n\t\t\telse {\n\t\t\t\t// Set to error state\n\t\t\t\tscDoc.SetState(SCE_CLW_ERROR);\n\t\t\t}\n\t\t}\n\t\t// End of Line Handling\n\t\telse if (scDoc.atLineEnd) {\n\t\t\t// Reset to the default state at the end of each line.\n\t\t\tscDoc.SetState(SCE_CLW_DEFAULT);\n\t\t}\n\t\t// Default Handling\n\t\telse {\n\t\t\t// If in default state\n\t\t\tif (scDoc.state == SCE_CLW_DEFAULT) {\n\t\t\t\t// If is a letter could be a possible statement\n\t\t\t\tif (isalpha(scDoc.ch)) {\n\t\t\t\t\t// Set the state to Clarion Keyword and verify later\n\t\t\t\t\tscDoc.SetState(SCE_CLW_KEYWORD);\n\t\t\t\t}\n\t\t\t\t// else is a number\n\t\t\t\telse if (isdigit(scDoc.ch)) {\n\t\t\t\t\t// Set the state to Integer Constant and verify later\n\t\t\t\t\tscDoc.SetState(SCE_CLW_INTEGER_CONSTANT);\n\t\t\t\t}\n\t\t\t\t// else if the start of a comment or a | (line continuation)\n\t\t\t\telse if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {\n\t\t\t\t\t// then set the state to comment.\n\t\t\t\t\tscDoc.SetState(SCE_CLW_COMMENT);\n\t\t\t\t}\n\t\t\t\t// else if the character is a ' (single quote)\n\t\t\t\telse if (scDoc.ch == '\\'') {\n\t\t\t\t\t// If the character is also a ' (single quote)\n\t\t\t\t\t// Embedded Apostrophe\n\t\t\t\t\tif (scDoc.chNext == '\\'') {\n\t\t\t\t\t\t// Move forward colouring it as default state\n\t\t\t\t\t\tscDoc.ForwardSetState(SCE_CLW_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t// move to the next character and then set the state to comment.\n\t\t\t\t\t\tscDoc.ForwardSetState(SCE_CLW_STRING);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// else the character is an @ (ampersand)\n\t\t\t\telse if (scDoc.ch == '@') {\n\t\t\t\t\t// Case insensitive.\n\t\t\t\t\tif (!bCaseSensitive) {\n\t\t\t\t\t\t// If character is a valid picture token character\n\t\t\t\t\t\tif (strchr(\"DEKNPSTdeknpst\", scDoc.chNext) != NULL) {\n\t\t\t\t\t\t\t// Set to the picture string state\n\t\t\t\t\t\t\tscDoc.SetState(SCE_CLW_PICTURE_STRING);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Case sensitive\n\t\t\t\t\telse {\n\t\t\t\t\t\t// If character is a valid picture token character\n\t\t\t\t\t\tif (strchr(\"DEKNPST\", scDoc.chNext) != NULL) {\n\t\t\t\t\t\t\t// Set the picture string state\n\t\t\t\t\t\t\tscDoc.SetState(SCE_CLW_PICTURE_STRING);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// lexing complete\n\tscDoc.Complete();\n}\n\n// Clarion Language Case Sensitive Colouring Procedure\nstatic void ColouriseClarionDocSensitive(Sci_PositionU uiStartPos, Sci_Position iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {\n\n\tColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);\n}\n\n// Clarion Language Case Insensitive Colouring Procedure\nstatic void ColouriseClarionDocInsensitive(Sci_PositionU uiStartPos, Sci_Position iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {\n\n\tColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);\n}\n\n// Fill Buffer\n\nstatic void FillBuffer(Sci_PositionU uiStart, Sci_PositionU uiEnd, Accessor &accStyler, char *szBuffer, Sci_PositionU uiLength) {\n\n\tSci_PositionU uiPos = 0;\n\n\twhile ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {\n\t\tszBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));\n\t\tuiPos++;\n\t}\n\tszBuffer[uiPos] = '\\0';\n}\n\n// Classify Clarion Fold Point\n\nstatic int ClassifyClarionFoldPoint(int iLevel, const char* szString) {\n\n\tif (!(isdigit(szString[0]) || (szString[0] == '.'))) {\n\t\tif (strcmp(szString, \"PROCEDURE\") == 0) {\n\t//\t\tiLevel = SC_FOLDLEVELBASE + 1;\n\t\t}\n\t\telse if (strcmp(szString, \"MAP\") == 0 ||\n\t\t\tstrcmp(szString,\"ACCEPT\") == 0 ||\n\t\t\tstrcmp(szString,\"BEGIN\") == 0 ||\n\t\t\tstrcmp(szString,\"CASE\") == 0 ||\n\t\t\tstrcmp(szString,\"EXECUTE\") == 0 ||\n\t\t\tstrcmp(szString,\"IF\") == 0 ||\n\t\t\tstrcmp(szString,\"ITEMIZE\") == 0 ||\n\t\t\tstrcmp(szString,\"INTERFACE\") == 0 ||\n\t\t\tstrcmp(szString,\"JOIN\") == 0 ||\n\t\t\tstrcmp(szString,\"LOOP\") == 0 ||\n\t\t\tstrcmp(szString,\"MODULE\") == 0 ||\n\t\t\tstrcmp(szString,\"RECORD\") == 0) {\n\t\t\tiLevel++;\n\t\t}\n\t\telse if (strcmp(szString, \"APPLICATION\") == 0 ||\n\t\t\tstrcmp(szString, \"CLASS\") == 0 ||\n\t\t\tstrcmp(szString, \"DETAIL\") == 0 ||\n\t\t\tstrcmp(szString, \"FILE\") == 0 ||\n\t\t\tstrcmp(szString, \"FOOTER\") == 0 ||\n\t\t\tstrcmp(szString, \"FORM\") == 0 ||\n\t\t\tstrcmp(szString, \"GROUP\") == 0 ||\n\t\t\tstrcmp(szString, \"HEADER\") == 0 ||\n\t\t\tstrcmp(szString, \"INTERFACE\") == 0 ||\n\t\t\tstrcmp(szString, \"MENU\") == 0 ||\n\t\t\tstrcmp(szString, \"MENUBAR\") == 0 ||\n\t\t\tstrcmp(szString, \"OLE\") == 0 ||\n\t\t\tstrcmp(szString, \"OPTION\") == 0 ||\n\t\t\tstrcmp(szString, \"QUEUE\") == 0 ||\n\t\t\tstrcmp(szString, \"REPORT\") == 0 ||\n\t\t\tstrcmp(szString, \"SHEET\") == 0 ||\n\t\t\tstrcmp(szString, \"TAB\") == 0 ||\n\t\t\tstrcmp(szString, \"TOOLBAR\") == 0 ||\n\t\t\tstrcmp(szString, \"VIEW\") == 0 ||\n\t\t\tstrcmp(szString, \"WINDOW\") == 0) {\n\t\t\tiLevel++;\n\t\t}\n\t\telse if (strcmp(szString, \"END\") == 0 ||\n\t\t\tstrcmp(szString, \"UNTIL\") == 0 ||\n\t\t\tstrcmp(szString, \"WHILE\") == 0) {\n\t\t\tiLevel--;\n\t\t}\n\t}\n\treturn(iLevel);\n}\n\n// Clarion Language Folding Procedure\nstatic void FoldClarionDoc(Sci_PositionU uiStartPos, Sci_Position iLength, int iInitStyle, WordList *[], Accessor &accStyler) {\n\n\tSci_PositionU uiEndPos = uiStartPos + iLength;\n\tSci_Position iLineCurrent = accStyler.GetLine(uiStartPos);\n\tint iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint iLevelCurrent = iLevelPrev;\n\tchar chNext = accStyler[uiStartPos];\n\tint iStyle = iInitStyle;\n\tint iStyleNext = accStyler.StyleAt(uiStartPos);\n\tint iVisibleChars = 0;\n\tSci_Position iLastStart = 0;\n\n\tfor (Sci_PositionU uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {\n\n\t\tchar chChar = chNext;\n\t\tchNext = accStyler.SafeGetCharAt(uiPos + 1);\n\t\tint iStylePrev = iStyle;\n\t\tiStyle = iStyleNext;\n\t\tiStyleNext = accStyler.StyleAt(uiPos + 1);\n\t\tbool bEOL = (chChar == '\\r' && chNext != '\\n') || (chChar == '\\n');\n\n\t\tif (iStylePrev == SCE_CLW_DEFAULT) {\n\t\t\tif (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {\n\t\t\t\t// Store last word start point.\n\t\t\t\tiLastStart = uiPos;\n\t\t\t}\n\t\t}\n\n\t\tif (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) {\n\t\t\tif(iswordchar(chChar) && !iswordchar(chNext)) {\n\t\t\t\tchar chBuffer[100];\n\t\t\t\tFillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer));\n\t\t\t\tiLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer);\n\t\t\t//\tif ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) {\n\t\t\t//\t\taccStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE);\n\t\t\t//\t\tiLevelPrev = SC_FOLDLEVELBASE;\n\t\t\t//\t}\n\t\t\t}\n\t\t}\n\n\t\tif (bEOL) {\n\t\t\tint iLevel = iLevelPrev;\n\t\t\tif ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0))\n\t\t\t\tiLevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (iLevel != accStyler.LevelAt(iLineCurrent)) {\n\t\t\t\taccStyler.SetLevel(iLineCurrent,iLevel);\n\t\t\t}\n\t\t\tiLineCurrent++;\n\t\t\tiLevelPrev = iLevelCurrent;\n\t\t\tiVisibleChars = 0;\n\t\t}\n\n\t\tif (!isspacechar(chChar))\n\t\t\tiVisibleChars++;\n\t}\n\n\t// Fill in the real level of the next line, keeping the current flags\n\t// as they will be filled in later.\n\tint iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\taccStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext);\n}\n\n// Word List Descriptions\nstatic const char * const rgWordListDescriptions[] = {\n\t\"Clarion Keywords\",\n\t\"Compiler Directives\",\n\t\"Built-in Procedures and Functions\",\n\t\"Runtime Expressions\",\n\t\"Structure and Data Types\",\n\t\"Attributes\",\n\t\"Standard Equates\",\n\t\"Reserved Words (Labels)\",\n\t\"Reserved Words (Procedure Labels)\",\n\t0,\n};\n\n// Case Sensitive Clarion Language Lexer\nextern const LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, \"clarion\", FoldClarionDoc, rgWordListDescriptions);\n\n// Case Insensitive Clarion Language Lexer\nextern const LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, \"clarionnocase\", FoldClarionDoc, rgWordListDescriptions);\n"
  },
  {
    "path": "lexers/LexCOBOL.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexCOBOL.cxx\n ** Lexer for COBOL\n ** Based on LexPascal.cxx\n ** Written by Laurent le Tynevez\n ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002\n ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)\n ** Updated by Rod Falck, Aug 2006 Converted to COBOL\n **/\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n#include <cstdio>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n#define IN_DIVISION 0x01\n#define IN_DECLARATIVES 0x02\n#define IN_SECTION 0x04\n#define IN_PARAGRAPH 0x08\n#define IN_FLAGS 0xF\n#define NOT_HEADER 0x10\n\nnamespace {\n\nbool isCOBOLoperator(char ch)\n    {\n    return isoperator(ch);\n    }\n\nbool isCOBOLwordchar(char ch)\n    {\n    return IsASCII(ch) && (isalnum(ch) || ch == '-');\n\n    }\n\nbool isCOBOLwordstart(char ch)\n    {\n    return IsASCII(ch) && isalnum(ch);\n    }\n\nint CountBits(int nBits)\n    {\n    int count = 0;\n    for (int i = 0; i < 32; ++i)\n        {\n        count += nBits & 1;\n        nBits >>= 1;\n        }\n    return count;\n    }\n\nvoid getRange(Sci_PositionU start,\n        Sci_PositionU end,\n        Accessor &styler,\n        char *s,\n        Sci_PositionU len) {\n    Sci_PositionU i = 0;\n    while ((i < end - start + 1) && (i < len-1)) {\n        s[i] = static_cast<char>(tolower(styler[start + i]));\n        i++;\n    }\n    s[i] = '\\0';\n}\n\nvoid ColourTo(Accessor &styler, Sci_PositionU end, unsigned int attr) {\n    styler.ColourTo(end, attr);\n}\n\n\nint classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) {\n    int ret = 0;\n\n    char s[100];\n    s[0] = '\\0';\n    s[1] = '\\0';\n    getRange(start, end, styler, s, sizeof(s));\n\n    int chAttr = SCE_COBOL_IDENTIFIER;\n    if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) {\n        chAttr = SCE_COBOL_NUMBER;\n        char *p = s + 1;\n        while (*p) {\n            if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) {\n                chAttr = SCE_COBOL_IDENTIFIER;\n                break;\n            }\n            ++p;\n        }\n    }\n    if (chAttr == SCE_COBOL_IDENTIFIER) {\n        WordList& a_keywords = *keywordlists[0];\n        WordList& b_keywords = *keywordlists[1];\n        WordList& c_keywords = *keywordlists[2];\n\n        if (a_keywords.InList(s)) {\n            chAttr = SCE_COBOL_WORD;\n        }\n        else if (b_keywords.InList(s)) {\n            chAttr = SCE_COBOL_WORD2;\n        }\n        else if (c_keywords.InList(s)) {\n            chAttr = SCE_COBOL_WORD3;\n        }\n    }\n    if (*bAarea) {\n        if (strcmp(s, \"division\") == 0) {\n            ret = IN_DIVISION;\n            // we've determined the containment, anything else is just ignored for those purposes\n            *bAarea = false;\n        } else if (strcmp(s, \"declaratives\") == 0) {\n            ret = IN_DIVISION | IN_DECLARATIVES;\n            if (nContainment & IN_DECLARATIVES)\n                ret |= NOT_HEADER | IN_SECTION;\n            // we've determined the containment, anything else is just ignored for those purposes\n            *bAarea = false;\n        } else if (strcmp(s, \"section\") == 0) {\n            ret = (nContainment &~ IN_PARAGRAPH) | IN_SECTION;\n            // we've determined the containment, anything else is just ignored for those purposes\n            *bAarea = false;\n        } else if (strcmp(s, \"end\") == 0 && (nContainment & IN_DECLARATIVES)) {\n            ret = IN_DIVISION | IN_DECLARATIVES | IN_SECTION | NOT_HEADER;\n        } else {\n            ret = nContainment | IN_PARAGRAPH;\n        }\n    }\n    ColourTo(styler, end, chAttr);\n    return ret;\n}\n\nvoid ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n    Accessor &styler) {\n\n    styler.StartAt(startPos);\n\n    int state = initStyle;\n    if (state == SCE_COBOL_CHARACTER)   // Does not leak onto next line\n        state = SCE_COBOL_DEFAULT;\n    char chPrev = ' ';\n    char chNext = styler[startPos];\n    Sci_PositionU lengthDoc = startPos + length;\n\n    int nContainment;\n\n    Sci_Position currentLine = styler.GetLine(startPos);\n    if (currentLine > 0) {\n        styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));\n        nContainment = styler.GetLineState(currentLine);\n        nContainment &= ~NOT_HEADER;\n    } else {\n        styler.SetLineState(currentLine, 0);\n        nContainment = 0;\n    }\n\n    styler.StartSegment(startPos);\n    bool bNewLine = true;\n    bool bAarea = !isspacechar(chNext);\n    int column = 0;\n    for (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n        char ch = chNext;\n\n        chNext = styler.SafeGetCharAt(i + 1);\n\n        ++column;\n\n        if (bNewLine) {\n            column = 0;\n        }\n        if (column <= 1 && !bAarea) {\n            bAarea = !isspacechar(ch);\n        }\n        bool bSetNewLine = false;\n        if ((ch == '\\r' && chNext != '\\n') || (ch == '\\n')) {\n            // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)\n            // Avoid triggering two times on Dos/Win\n            // End of line\n            if (state == SCE_COBOL_CHARACTER) {\n                ColourTo(styler, i, state);\n                state = SCE_COBOL_DEFAULT;\n            }\n            styler.SetLineState(currentLine, nContainment);\n            currentLine++;\n            bSetNewLine = true;\n            if (nContainment & NOT_HEADER)\n                nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION);\n        }\n\n        if (styler.IsLeadByte(ch)) {\n            chNext = styler.SafeGetCharAt(i + 2);\n            chPrev = ' ';\n            i += 1;\n            continue;\n        }\n\n        if (state == SCE_COBOL_DEFAULT) {\n            if (isCOBOLwordstart(ch) || (ch == '$' && IsASCII(chNext) && isalpha(chNext))) {\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_IDENTIFIER;\n            } else if (column == 6 && (ch == '*' || ch == '/')) {\n            // Cobol comment line: asterisk in column 7.\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_COMMENTLINE;\n            } else if (ch == '*' && chNext == '>') {\n            // Cobol inline comment: asterisk, followed by greater than.\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_COMMENTLINE;\n            } else if (column == 0 && ch == '*' && chNext != '*') {\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_COMMENTLINE;\n            } else if (column == 0 && ch == '/' && chNext != '*') {\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_COMMENTLINE;\n            } else if (column == 0 && ch == '*' && chNext == '*') {\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_COMMENTDOC;\n            } else if (column == 0 && ch == '/' && chNext == '*') {\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_COMMENTDOC;\n            } else if (ch == '\"') {\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_STRING;\n            } else if (ch == '\\'') {\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_CHARACTER;\n            } else if (ch == '?' && column == 0) {\n                ColourTo(styler, i-1, state);\n                state = SCE_COBOL_PREPROCESSOR;\n            } else if (isCOBOLoperator(ch)) {\n                ColourTo(styler, i-1, state);\n                ColourTo(styler, i, SCE_COBOL_OPERATOR);\n            }\n        } else if (state == SCE_COBOL_IDENTIFIER) {\n            if (!isCOBOLwordchar(ch)) {\n                int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea);\n\n                if(lStateChange != 0) {\n                    styler.SetLineState(currentLine, lStateChange);\n                    nContainment = lStateChange;\n                }\n\n                state = SCE_COBOL_DEFAULT;\n                chNext = styler.SafeGetCharAt(i + 1);\n                if (column == 6 && (ch == '*' || ch == '/')) {\n                    state = SCE_COBOL_COMMENTLINE;\n                } else if (ch == '\"') {\n                    state = SCE_COBOL_STRING;\n                } else if (ch == '\\'') {\n                    state = SCE_COBOL_CHARACTER;\n                } else if (isCOBOLoperator(ch)) {\n                    ColourTo(styler, i, SCE_COBOL_OPERATOR);\n                }\n            }\n        } else {\n            if (state == SCE_COBOL_PREPROCESSOR) {\n                if ((ch == '\\r' || ch == '\\n') && !(chPrev == '\\\\' || chPrev == '\\r')) {\n                    ColourTo(styler, i-1, state);\n                    state = SCE_COBOL_DEFAULT;\n                }\n            } else if (state == SCE_COBOL_COMMENT) {\n                if (ch == '\\r' || ch == '\\n') {\n                    ColourTo(styler, i-1, state);\n                    state = SCE_COBOL_DEFAULT;\n                }\n            } else if (state == SCE_COBOL_COMMENTDOC) {\n                if (ch == '\\r' || ch == '\\n') {\n                    if (((i > styler.GetStartSegment() + 2) || (\n                        (initStyle == SCE_COBOL_COMMENTDOC) &&\n                        (styler.GetStartSegment() == static_cast<Sci_PositionU>(startPos))))) {\n                            ColourTo(styler, i-1, state);\n                            state = SCE_COBOL_DEFAULT;\n                    }\n                }\n            } else if (state == SCE_COBOL_COMMENTLINE) {\n                if (ch == '\\r' || ch == '\\n') {\n                    ColourTo(styler, i-1, state);\n                    state = SCE_COBOL_DEFAULT;\n                }\n            } else if (state == SCE_COBOL_STRING) {\n                if (ch == '\"') {\n                    ColourTo(styler, i, state);\n                    state = SCE_COBOL_DEFAULT;\n                } else if (ch == '\\r' || ch == '\\n') {\n                    ColourTo(styler, i-1, state);\n                    state = SCE_COBOL_DEFAULT;\n                }\n            } else if (state == SCE_COBOL_CHARACTER) {\n                if (ch == '\\'') {\n                    ColourTo(styler, i, state);\n                    state = SCE_COBOL_DEFAULT;\n                }\n            }\n        }\n        chPrev = ch;\n        bNewLine = bSetNewLine;\n        if (bNewLine)\n            {\n            bAarea = false;\n            }\n    }\n    ColourTo(styler, lengthDoc - 1, state);\n}\n\nvoid FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],\n                            Accessor &styler) {\n    bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n    Sci_PositionU endPos = startPos + length;\n    int visibleChars = 0;\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK : 0xFFF;\n    char chNext = styler[startPos];\n\n    bool bNewLine = true;\n    bool bAarea = !isspacechar(chNext);\n    int column = 0;\n    bool bComment = false;\n    for (Sci_PositionU i = startPos; i < endPos; i++) {\n        char ch = chNext;\n        chNext = styler.SafeGetCharAt(i + 1);\n        ++column;\n\n        if (bNewLine) {\n            column = 0;\n            bComment = (ch == '*' || ch == '/' || ch == '?');\n        }\n        if (column <= 1 && !bAarea) {\n            bAarea = !isspacechar(ch);\n        }\n        bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n        if (atEOL) {\n            int nContainment = styler.GetLineState(lineCurrent);\n            int lev = CountBits(nContainment & IN_FLAGS) | SC_FOLDLEVELBASE;\n            if (bAarea && !bComment)\n                --lev;\n            if (visibleChars == 0 && foldCompact)\n                lev |= SC_FOLDLEVELWHITEFLAG;\n            if ((bAarea) && (visibleChars > 0) && !(nContainment & NOT_HEADER) && !bComment)\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            if (lev != styler.LevelAt(lineCurrent)) {\n                styler.SetLevel(lineCurrent, lev);\n            }\n            if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) {\n                // this level is at the same level or less than the previous line\n                // therefore these is nothing for the previous header to collapse, so remove the header\n                styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);\n            }\n            levelPrev = lev;\n            visibleChars = 0;\n            bAarea = false;\n            bNewLine = true;\n            lineCurrent++;\n        } else {\n            bNewLine = false;\n        }\n\n\n        if (!isspacechar(ch))\n            visibleChars++;\n    }\n\n    // Fill in the real level of the next line, keeping the current flags as they will be filled in later\n    int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n    styler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nconst char * const COBOLWordListDesc[] = {\n    \"A Keywords\",\n    \"B Keywords\",\n    \"Extended Keywords\",\n    nullptr\n};\n\n}\n\nextern const LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, \"COBOL\", FoldCOBOLDoc, COBOLWordListDesc);\n"
  },
  {
    "path": "lexers/LexCPP.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexCPP.cxx\n ** Lexer for C++, C, Java, and JavaScript.\n ** Further folding features and configuration properties added by \"Udo Lechner\" <dlchnr(at)gmx(dot)net>\n **/\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <utility>\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <iterator>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"StringCopy.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"SparseState.h\"\n#include \"SubStyles.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\t// Use an unnamed namespace to protect the functions and classes from name conflicts\n\nconstexpr bool IsSpaceEquiv(int state) noexcept {\n\treturn (state <= SCE_C_COMMENTDOC) ||\n\t\t// including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE\n\t\t(state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||\n\t\t(state == SCE_C_COMMENTDOCKEYWORDERROR);\n}\n\n// Preconditions: sc.currentPos points to a character after '+' or '-'.\n// The test for pos reaching 0 should be redundant,\n// and is in only for safety measures.\n// Limitation: this code will give the incorrect answer for code like\n// a = b+++/ptn/...\n// Putting a space between the '++' post-inc operator and the '+' binary op\n// fixes this, and is highly recommended for readability anyway.\nbool FollowsPostfixOperator(const StyleContext &sc, LexAccessor &styler) {\n\tSci_Position pos = sc.currentPos;\n\twhile (--pos > 0) {\n\t\tconst char ch = styler[pos];\n\t\tif (ch == '+' || ch == '-') {\n\t\t\treturn styler[pos - 1] == ch;\n\t\t}\n\t}\n\treturn false;\n}\n\nbool followsReturnKeyword(const StyleContext &sc, LexAccessor &styler) {\n\t// Don't look at styles, so no need to flush.\n\tSci_Position pos = sc.currentPos;\n\tconst Sci_Position currentLine = styler.GetLine(pos);\n\tconst Sci_Position lineStartPos = styler.LineStart(currentLine);\n\twhile (--pos > lineStartPos) {\n\t\tconst char ch = styler.SafeGetCharAt(pos);\n\t\tif (ch != ' ' && ch != '\\t') {\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst char *retBack = \"nruter\";\n\tconst char *s = retBack;\n\twhile (*s\n\t\t&& pos >= lineStartPos\n\t\t&& styler.SafeGetCharAt(pos) == *s) {\n\t\ts++;\n\t\tpos--;\n\t}\n\treturn !*s;\n}\n\nconstexpr bool IsOperatorOrSpace(int ch) noexcept {\n\treturn isoperator(ch) || IsASpace(ch);\n}\n\nbool OnlySpaceOrTab(std::string_view s) noexcept {\n\tfor (const char ch : s) {\n\t\tif (!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nusing Tokens = std::vector<std::string>;\n\nTokens StringSplit(const std::string &text, int separator) {\n\tTokens vs(text.empty() ? 0 : 1);\n\tfor (const char ch : text) {\n\t\tif (ch == separator) {\n\t\t\tvs.emplace_back();\n\t\t} else {\n\t\t\tvs.back() += ch;\n\t\t}\n\t}\n\treturn vs;\n}\n\nstruct BracketPair {\n\tTokens::iterator itBracket;\n\tTokens::iterator itEndBracket;\n};\n\nBracketPair FindBracketPair(Tokens &tokens) {\n\tconst Tokens::iterator itBracket = std::find(tokens.begin(), tokens.end(), \"(\");\n\tif (itBracket != tokens.end()) {\n\t\tptrdiff_t nest = 0;\n\t\tfor (Tokens::iterator itTok = itBracket; itTok != tokens.end(); ++itTok) {\n\t\t\tif (*itTok == \"(\") {\n\t\t\t\tnest++;\n\t\t\t} else if (*itTok == \")\") {\n\t\t\t\tnest--;\n\t\t\t\tif (nest == 0) {\n\t\t\t\t\treturn { itBracket, itTok };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn { tokens.end(), tokens.end() };\n}\n\nvoid highlightTaskMarker(StyleContext &sc, LexAccessor &styler,\n\t\tint activity, const WordList &markerList, bool caseSensitive) {\n\tif (IsOperatorOrSpace(sc.chPrev) && !IsOperatorOrSpace(sc.ch) && markerList.Length()) {\n\t\tstd::string marker;\n\t\tfor (Sci_PositionU currPos = sc.currentPos; true; currPos++) {\n\t\t\tconst char ch = styler.SafeGetCharAt(currPos);\n\t\t\tif (IsOperatorOrSpace(ch)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (caseSensitive)\n\t\t\t\tmarker.push_back(ch);\n\t\t\telse\n\t\t\t\tmarker.push_back(MakeLowerCase(ch));\n\t\t}\n\t\tif (markerList.InList(marker)) {\n\t\t\tsc.SetState(SCE_C_TASKMARKER|activity);\n\t\t}\n\t}\n}\n\nconst CharacterSet setHexDigits(CharacterSet::setDigits, \"ABCDEFabcdef\");\nconst CharacterSet setOctDigits(\"01234567\");\nconst CharacterSet setNoneNumeric;\n\nclass EscapeSequence {\n\tconst CharacterSet *escapeSetValid = nullptr;\n\tint digitsLeft = 0;\npublic:\n\tint outerState = SCE_C_DEFAULT;\n\tEscapeSequence() = default;\n\tvoid resetEscapeState(int state, int nextChar) noexcept {\n\t\tdigitsLeft = 0;\n\t\touterState = state;\n\t\tescapeSetValid = &setNoneNumeric;\n\t\tif (nextChar == 'U') {\n\t\t\tdigitsLeft = 9;\n\t\t\tescapeSetValid = &setHexDigits;\n\t\t} else if (nextChar == 'u') {\n\t\t\tdigitsLeft = 5;\n\t\t\tescapeSetValid = &setHexDigits;\n\t\t} else if (nextChar == 'x') {\n\t\t\tdigitsLeft = 5;\n\t\t\tescapeSetValid = &setHexDigits;\n\t\t} else if (setOctDigits.Contains(nextChar)) {\n\t\t\tdigitsLeft = 3;\n\t\t\tescapeSetValid = &setOctDigits;\n\t\t}\n\t}\n\t[[nodiscard]] bool atEscapeEnd(int currChar) const noexcept {\n\t\treturn (digitsLeft <= 0) || !escapeSetValid->Contains(currChar);\n\t}\n\tvoid consumeDigit() noexcept {\n\t\tdigitsLeft--;\n\t}\n};\n\nstd::string GetRestOfLine(LexAccessor &styler, Sci_Position start, bool allowSpace) {\n\tstd::string restOfLine;\n\tSci_Position line = styler.GetLine(start);\n\tSci_Position pos = start;\n\tSci_Position endLine = styler.LineEnd(line);\n\tchar ch = styler.SafeGetCharAt(start, '\\n');\n\twhile (pos < endLine) {\n\t\tif (ch == '\\\\' && ((pos + 1) == endLine)) {\n\t\t\t// Continuation line\n\t\t\tline++;\n\t\t\tpos = styler.LineStart(line);\n\t\t\tendLine = styler.LineEnd(line);\n\t\t\tch = styler.SafeGetCharAt(pos, '\\n');\n\t\t} else {\n\t\t\tconst char chNext = styler.SafeGetCharAt(pos + 1, '\\n');\n\t\t\tif (ch == '/' && (chNext == '/' || chNext == '*'))\n\t\t\t\tbreak;\n\t\t\tif (allowSpace || (ch != ' ')) {\n\t\t\t\trestOfLine += ch;\n\t\t\t}\n\t\t\tpos++;\n\t\t\tch = chNext;\n\t\t}\n\t}\n\treturn restOfLine;\n}\n\nconstexpr bool IsStreamCommentStyle(int style) noexcept {\n\treturn style == SCE_C_COMMENT ||\n\t\tstyle == SCE_C_COMMENTDOC ||\n\t\tstyle == SCE_C_COMMENTDOCKEYWORD ||\n\t\tstyle == SCE_C_COMMENTDOCKEYWORDERROR;\n}\n\nstruct PPDefinition {\n\tSci_Position line;\n\tstd::string key;\n\tstd::string value;\n\tbool isUndef;\n\tstd::string arguments;\n\tPPDefinition(Sci_Position line_, std::string_view key_, std::string_view value_, bool isUndef_, std::string_view arguments_) :\n\t\tline(line_), key(key_), value(value_), isUndef(isUndef_), arguments(arguments_) {\n\t}\n};\n\nconstexpr int inactiveFlag = 0x40;\n\nclass LinePPState {\n\t// Track the state of preprocessor conditionals to allow showing active and inactive\n\t// code in different styles.\n\t// Only works up to 31 levels of conditional nesting.\n\n\t// state is a bit mask with 1 bit per level\n\t// bit is 1 for level if section inactive, so any bits set = inactive style\n\tint state = 0;\n\t// ifTaken is a bit mask with 1 bit per level\n\t// bit is 1 for level if some branch at this level has been taken\n\tint ifTaken = 0;\n\t// level is the nesting level of #if constructs\n\tint level = -1;\n\tstatic const int maximumNestingLevel = 31;\n\t[[nodiscard]] int maskLevel() const noexcept {\n\t\tif (level >= 0) {\n\t\t\treturn 1 << level;\n\t\t}\n\t\treturn 1;\n\t}\npublic:\n\tLinePPState() noexcept = default;\n\t[[nodiscard]] bool ValidLevel() const noexcept {\n\t\treturn level >= 0 && level < maximumNestingLevel;\n\t}\n\t[[nodiscard]] bool IsActive() const noexcept {\n\t\treturn state == 0;\n\t}\n\t[[nodiscard]] bool IsInactive() const noexcept {\n\t\treturn state != 0;\n\t}\n\t[[nodiscard]] int ActiveState() const noexcept {\n\t\treturn state ? inactiveFlag : 0;\n\t}\n\t[[nodiscard]] bool CurrentIfTaken() const noexcept {\n\t\treturn (ifTaken & maskLevel()) != 0;\n\t}\n\tvoid StartSection(bool on) noexcept {\n\t\tlevel++;\n\t\tif (ValidLevel()) {\n\t\t\tif (on) {\n\t\t\t\tstate &= ~maskLevel();\n\t\t\t\tifTaken |= maskLevel();\n\t\t\t} else {\n\t\t\t\tstate |= maskLevel();\n\t\t\t\tifTaken &= ~maskLevel();\n\t\t\t}\n\t\t}\n\t}\n\tvoid EndSection() noexcept {\n\t\tif (ValidLevel()) {\n\t\t\tstate &= ~maskLevel();\n\t\t\tifTaken &= ~maskLevel();\n\t\t}\n\t\tlevel--;\n\t}\n\tvoid InvertCurrentLevel() noexcept {\n\t\tif (ValidLevel()) {\n\t\t\tstate ^= maskLevel();\n\t\t\tifTaken |= maskLevel();\n\t\t}\n\t}\n};\n\n// Hold the preprocessor state for each line seen.\n// Currently one entry per line but could become sparse with just one entry per preprocessor line.\nclass PPStates {\n\tstd::vector<LinePPState> vlls;\npublic:\n\t[[nodiscard]] LinePPState ForLine(Sci_Position line) const noexcept {\n\t\tif ((line > 0) && (vlls.size() > static_cast<size_t>(line))) {\n\t\t\treturn vlls[line];\n\t\t}\n\t\treturn {};\n\t}\n\tvoid Add(Sci_Position line, LinePPState lls) {\n\t\tvlls.resize(line+1);\n\t\tvlls[line] = lls;\n\t}\n};\n\nenum class BackQuotedString : int {\n\tNone,\n\tRawString,\n\tTemplateLiteral,\n};\n\n// string interpolating state\nstruct InterpolatingState {\n\tint state;\n\tint braceCount;\n};\n\nstruct Definition {\n\tstd::string_view name;\n\tstd::string_view value;\n\tstd::string_view arguments;\n};\n\nconstexpr std::string_view TrimSpaceTab(std::string_view sv) noexcept {\n\twhile (!sv.empty() && IsASpaceOrTab(sv.front())) {\n\t\tsv.remove_prefix(1);\n\t}\n\treturn sv;\n}\n\n// Parse a macro definition, either from a #define line in a file or from keywords.\n// Either an object macro <NAME> <VALUE> or a function macro <NAME>(<ARGUMENTS>) <VALUE>.\n// VALUE is optional and is treated as \"1\" if missing.\n// #define ALLOW_PRINT\n// #define VERSION 37\n// #define VER(a,b) a*10+b\n// Whitespace separates macro and value in files but keywords use '=' separator.\n// 'endName' contains a set of characters that terminate the name of the macro.\n\nconstexpr Definition ParseDefine(std::string_view definition, std::string_view endName) {\n\tDefinition ret;\n\tdefinition = TrimSpaceTab(definition);\n\tconst size_t afterName = definition.find_first_of(endName);\n\tif (afterName != std::string_view::npos) {\n\t\tret.name = definition.substr(0, afterName);\n\t\tif (definition.at(afterName) == '(') {\n\t\t\t// Macro\n\t\t\tdefinition.remove_prefix(afterName+1);\n\t\t\tconst size_t closeBracket = definition.find(')');\n\t\t\tif (closeBracket != std::string_view::npos) {\n\t\t\t\tret.arguments = definition.substr(0, closeBracket);\n\t\t\t\tdefinition.remove_prefix(closeBracket+1);\n\t\t\t\tif (!definition.empty() && (endName.find(definition.front()) != std::string_view::npos)) {\n\t\t\t\t\tdefinition.remove_prefix(1);\n\t\t\t\t}\n\t\t\t\tret.value = definition;\n\t\t\t} // else malformed as requires closing bracket\n\t\t} else {\n\t\t\tret.value = definition.substr(afterName+1);\n\t\t}\n\t} else {\n\t\tret.name = definition;\n\t\tret.value = \"1\";\n\t}\n\treturn ret;\n}\n\n// An individual named option for use in an OptionSet\n\n// Options used for LexerCPP\nstruct OptionsCPP {\n\tbool stylingWithinPreprocessor = false;\n\tbool identifiersAllowDollars = true;\n\tbool identifiersAllowHashes = false;\n\tbool enablePreprocessor = true;\n\tbool trackPreprocessor = true;\n\tbool updatePreprocessor = true;\n\tbool verbatimStringsAllowEscapes = false;\n\tbool triplequotedStrings = false;\n\tbool hashquotedStrings = false;\n\tBackQuotedString backQuotedStrings = BackQuotedString::None;\n\tbool escapeSequence = false;\n\tbool fold = false;\n\tbool foldSyntaxBased = true;\n\tbool foldComment = false;\n\tbool foldCommentMultiline = true;\n\tbool foldCommentExplicit = true;\n\tstd::string foldExplicitStart;\n\tstd::string foldExplicitEnd;\n\tbool foldExplicitAnywhere = false;\n\tbool foldPreprocessor = false;\n\tbool foldPreprocessorAtElse = false;\n\tbool foldCompact = false;\n\tbool foldAtElse = false;\n};\n\nconst char *const cppWordLists[] = {\n            \"Primary keywords and identifiers\",\n            \"Secondary keywords and identifiers\",\n            \"Documentation comment keywords\",\n            \"Global classes and typedefs\",\n            \"Preprocessor definitions\",\n            \"Task marker and error marker keywords\",\n            nullptr,\n};\n\nstruct OptionSetCPP : public OptionSet<OptionsCPP> {\n\tOptionSetCPP() {\n\t\tDefineProperty(\"styling.within.preprocessor\", &OptionsCPP::stylingWithinPreprocessor,\n\t\t\t\"For C++ code, determines whether all preprocessor code is styled in the \"\n\t\t\t\"preprocessor style (0, the default) or only from the initial # to the end \"\n\t\t\t\"of the command word(1).\");\n\n\t\tDefineProperty(\"lexer.cpp.allow.dollars\", &OptionsCPP::identifiersAllowDollars,\n\t\t\t\"Set to 0 to disallow the '$' character in identifiers with the cpp lexer.\");\n\n\t\tDefineProperty(\"lexer.cpp.allow.hashes\", &OptionsCPP::identifiersAllowHashes,\n\t\t\t\"Set to 1 to allow the '#' character in identifiers.\");\n\n\t\tDefineProperty(\"lexer.cpp.enable.preprocessor\", &OptionsCPP::enablePreprocessor,\n\t\t\t\"Set to 0 to disable recognition of preprocessor directives.\");\n\n\t\tDefineProperty(\"lexer.cpp.track.preprocessor\", &OptionsCPP::trackPreprocessor,\n\t\t\t\"Set to 1 to interpret #if/#else/#endif to grey out code that is not active.\");\n\n\t\tDefineProperty(\"lexer.cpp.update.preprocessor\", &OptionsCPP::updatePreprocessor,\n\t\t\t\"Set to 1 to update preprocessor definitions when #define found.\");\n\n\t\tDefineProperty(\"lexer.cpp.verbatim.strings.allow.escapes\", &OptionsCPP::verbatimStringsAllowEscapes,\n\t\t\t\"Set to 1 to allow verbatim strings to contain escape sequences.\");\n\n\t\tDefineProperty(\"lexer.cpp.triplequoted.strings\", &OptionsCPP::triplequotedStrings,\n\t\t\t\"Set to 1 to enable highlighting of triple-quoted strings.\");\n\n\t\tDefineProperty(\"lexer.cpp.hashquoted.strings\", &OptionsCPP::hashquotedStrings,\n\t\t\t\"Set to 1 to enable highlighting of hash-quoted strings.\");\n\n\t\tDefineProperty(\"lexer.cpp.backquoted.strings\", &OptionsCPP::backQuotedStrings,\n\t\t\t\"Set how to highlighting back-quoted strings. \"\n\t\t\t\"0 (the default) no highlighting. \"\n\t\t\t\"1 highlighted as Go raw string. \"\n\t\t\t\"2 highlighted as JavaScript template literal.\");\n\n\t\tDefineProperty(\"lexer.cpp.escape.sequence\", &OptionsCPP::escapeSequence,\n\t\t\t\"Set to 1 to enable highlighting of escape sequences in strings\");\n\n\t\tDefineProperty(\"fold\", &OptionsCPP::fold);\n\n\t\tDefineProperty(\"fold.cpp.syntax.based\", &OptionsCPP::foldSyntaxBased,\n\t\t\t\"Set this property to 0 to disable syntax based folding.\");\n\n\t\tDefineProperty(\"fold.comment\", &OptionsCPP::foldComment,\n\t\t\t\"This option enables folding multi-line comments and explicit fold points when using the C++ lexer. \"\n\t\t\t\"Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} \"\n\t\t\t\"at the end of a section that should fold.\");\n\n\t\tDefineProperty(\"fold.cpp.comment.multiline\", &OptionsCPP::foldCommentMultiline,\n\t\t\t\"Set this property to 0 to disable folding multi-line comments when fold.comment=1.\");\n\n\t\tDefineProperty(\"fold.cpp.comment.explicit\", &OptionsCPP::foldCommentExplicit,\n\t\t\t\"Set this property to 0 to disable folding explicit fold points when fold.comment=1.\");\n\n\t\tDefineProperty(\"fold.cpp.explicit.start\", &OptionsCPP::foldExplicitStart,\n\t\t\t\"The string to use for explicit fold start points, replacing the standard //{.\");\n\n\t\tDefineProperty(\"fold.cpp.explicit.end\", &OptionsCPP::foldExplicitEnd,\n\t\t\t\"The string to use for explicit fold end points, replacing the standard //}.\");\n\n\t\tDefineProperty(\"fold.cpp.explicit.anywhere\", &OptionsCPP::foldExplicitAnywhere,\n\t\t\t\"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\");\n\n\t\tDefineProperty(\"fold.cpp.preprocessor.at.else\", &OptionsCPP::foldPreprocessorAtElse,\n\t\t\t\"This option enables folding on a preprocessor #else or #endif line of an #if statement.\");\n\n\t\tDefineProperty(\"fold.preprocessor\", &OptionsCPP::foldPreprocessor,\n\t\t\t\"This option enables folding preprocessor directives when using the C++ lexer. \"\n\t\t\t\"Includes C#'s explicit #region and #endregion folding directives.\");\n\n\t\tDefineProperty(\"fold.compact\", &OptionsCPP::foldCompact);\n\n\t\tDefineProperty(\"fold.at.else\", &OptionsCPP::foldAtElse,\n\t\t\t\"This option enables C++ folding on a \\\"} else {\\\" line of an if statement.\");\n\n\t\tDefineWordListSets(cppWordLists);\n\t}\n};\n\nconst char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0};\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer Cpp SCLEX_CPP SCE_C_:\n\t0, \"SCE_C_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_C_COMMENT\", \"comment\", \"Comment: /* */.\",\n\t2, \"SCE_C_COMMENTLINE\", \"comment line\", \"Line Comment: //.\",\n\t3, \"SCE_C_COMMENTDOC\", \"comment documentation\", \"Doc comment: block comments beginning with /** or /*!\",\n\t4, \"SCE_C_NUMBER\", \"literal numeric\", \"Number\",\n\t5, \"SCE_C_WORD\", \"keyword\", \"Keyword\",\n\t6, \"SCE_C_STRING\", \"literal string\", \"Double quoted string\",\n\t7, \"SCE_C_CHARACTER\", \"literal string character\", \"Single quoted string\",\n\t8, \"SCE_C_UUID\", \"literal uuid\", \"UUIDs (only in IDL)\",\n\t9, \"SCE_C_PREPROCESSOR\", \"preprocessor\", \"Preprocessor\",\n\t10, \"SCE_C_OPERATOR\", \"operator\", \"Operators\",\n\t11, \"SCE_C_IDENTIFIER\", \"identifier\", \"Identifiers\",\n\t12, \"SCE_C_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n\t13, \"SCE_C_VERBATIM\", \"literal string multiline raw\", \"Verbatim strings for C#\",\n\t14, \"SCE_C_REGEX\", \"literal regex\", \"Regular expressions for JavaScript\",\n\t15, \"SCE_C_COMMENTLINEDOC\", \"comment documentation line\", \"Doc Comment Line: line comments beginning with /// or //!.\",\n\t16, \"SCE_C_WORD2\", \"identifier\", \"Keywords2\",\n\t17, \"SCE_C_COMMENTDOCKEYWORD\", \"comment documentation keyword\", \"Comment keyword\",\n\t18, \"SCE_C_COMMENTDOCKEYWORDERROR\", \"error comment documentation keyword\", \"Comment keyword error\",\n\t19, \"SCE_C_GLOBALCLASS\", \"identifier\", \"Global class\",\n\t20, \"SCE_C_STRINGRAW\", \"literal string multiline raw\", \"Raw strings for C++0x\",\n\t21, \"SCE_C_TRIPLEVERBATIM\", \"literal string multiline raw\", \"Triple-quoted strings for Vala\",\n\t22, \"SCE_C_HASHQUOTEDSTRING\", \"literal string\", \"Hash-quoted strings for Pike\",\n\t23, \"SCE_C_PREPROCESSORCOMMENT\", \"comment preprocessor\", \"Preprocessor stream comment\",\n\t24, \"SCE_C_PREPROCESSORCOMMENTDOC\", \"comment preprocessor documentation\", \"Preprocessor stream doc comment\",\n\t25, \"SCE_C_USERLITERAL\", \"literal\", \"User defined literals\",\n\t26, \"SCE_C_TASKMARKER\", \"comment taskmarker\", \"Task Marker\",\n\t27, \"SCE_C_ESCAPESEQUENCE\", \"literal string escapesequence\", \"Escape sequence\",\n};\n\nconstexpr int sizeLexicalClasses = static_cast<int>(std::size(lexicalClasses));\n\n}\n\nclass LexerCPP : public ILexer5 {\n\tbool caseSensitive;\n\tCharacterSet setWord;\n\tCharacterSet setNegationOp;\n\tCharacterSet setAddOp;\n\tCharacterSet setMultOp;\n\tCharacterSet setRelOp;\n\tCharacterSet setLogicalOp;\n\tCharacterSet setWordStart;\n\tPPStates vlls;\n\tstd::vector<PPDefinition> ppDefineHistory;\n\tstd::map<Sci_Position, std::vector<InterpolatingState>> interpolatingAtEol;\n\tWordList keywords;\n\tWordList keywords2;\n\tWordList keywords3;\n\tWordList keywords4;\n\tWordList ppDefinitions;\n\tWordList markerList;\n\tstruct SymbolValue {\n\t\tstd::string value;\n\t\tstd::string arguments;\n\t\tSymbolValue() noexcept = default;\n\t\tSymbolValue(std::string_view value_, std::string_view arguments_) : value(value_), arguments(arguments_) {\n\t\t}\n\t\tSymbolValue &operator = (const std::string &value_) {\n\t\t\tvalue = value_;\n\t\t\targuments.clear();\n\t\t\treturn *this;\n\t\t}\n\t\t[[nodiscard]] bool IsMacro() const noexcept {\n\t\t\treturn !arguments.empty();\n\t\t}\n\t};\n\tusing SymbolTable = std::map<std::string, SymbolValue>;\n\tSymbolTable preprocessorDefinitionsStart;\n\tOptionsCPP options;\n\tOptionSetCPP osCPP;\n\tEscapeSequence escapeSeq;\n\tSparseState<std::string> rawStringTerminators;\n\tenum { ssIdentifier, ssDocKeyword };\n\tSubStyles subStyles{ styleSubable, SubStylesFirst, SubStylesAvailable, inactiveFlag };\n\tstd::string returnBuffer;\npublic:\n\texplicit LexerCPP(bool caseSensitive_) :\n\t\tcaseSensitive(caseSensitive_),\n\t\tsetWord(CharacterSet::setAlphaNum, \"._\", true),\n\t\tsetNegationOp(\"!\"),\n\t\tsetAddOp(\"+-\"),\n\t\tsetMultOp(\"*/%\"),\n\t\tsetRelOp(\"=!<>\"),\n\t\tsetLogicalOp(\"|&\") {\n\t}\n\t// Deleted so LexerCPP objects can not be copied.\n\tLexerCPP(const LexerCPP &) = delete;\n\tLexerCPP(LexerCPP &&) = delete;\n\tvoid operator=(const LexerCPP &) = delete;\n\tvoid operator=(LexerCPP &&) = delete;\n\tvirtual ~LexerCPP() = default;\n\tvoid SCI_METHOD Release() noexcept override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const noexcept override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osCPP.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osCPP.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osCPP.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osCPP.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid *SCI_METHOD PrivateCall(int, void *) noexcept override {\n\t\treturn nullptr;\n\t}\n\n\tint SCI_METHOD LineEndTypesSupported() noexcept override {\n\t\treturn SC_LINE_END_TYPE_UNICODE;\n\t}\n\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {\n\t\treturn subStyles.Allocate(styleBase, numberStyles);\n\t}\n\tint SCI_METHOD SubStylesStart(int styleBase) override {\n\t\treturn subStyles.Start(styleBase);\n\t}\n\tint SCI_METHOD SubStylesLength(int styleBase) override {\n\t\treturn subStyles.Length(styleBase);\n\t}\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override {\n\t\tconst int styleBase = subStyles.BaseStyle(MaskActive(subStyle));\n\t\tconst int inactive = subStyle & inactiveFlag;\n\t\treturn styleBase | inactive;\n\t}\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) noexcept override {\n\t\treturn MaskActive(style);\n\t}\n\tvoid SCI_METHOD FreeSubStyles() override {\n\t\tsubStyles.Free();\n\t}\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {\n\t\tsubStyles.SetIdentifiers(style, identifiers);\n\t}\n\tint SCI_METHOD DistanceToSecondaryStyles() noexcept override {\n\t\treturn inactiveFlag;\n\t}\n\tconst char *SCI_METHOD GetSubStyleBases() noexcept override {\n\t\treturn styleSubable;\n\t}\n\tint SCI_METHOD NamedStyles() override {\n\t\treturn std::max(subStyles.LastAllocated() + 1,\n\t\t\tsizeLexicalClasses) +\n\t\t\tinactiveFlag;\n\t}\n\tconst char *SCI_METHOD NameOfStyle(int style) override {\n\t\tif (style >= NamedStyles())\n\t\t\treturn \"\";\n\t\tif (style < sizeLexicalClasses)\n\t\t\treturn lexicalClasses[style].name;\n\t\t// TODO: inactive and substyles\n\t\treturn \"\";\n\t}\n\tconst char *SCI_METHOD TagsOfStyle(int style) override {\n\t\tif (style >= NamedStyles())\n\t\t\treturn \"Excess\";\n\t\treturnBuffer.clear();\n\t\tconst int firstSubStyle = subStyles.FirstAllocated();\n\t\tif (firstSubStyle >= 0) {\n\t\t\tconst int lastSubStyle = subStyles.LastAllocated();\n\t\t\tif (((style >= firstSubStyle) && (style <= (lastSubStyle))) ||\n\t\t\t\t((style >= firstSubStyle + inactiveFlag) && (style <= (lastSubStyle + inactiveFlag)))) {\n\t\t\t\tint styleActive = style;\n\t\t\t\tif (style > lastSubStyle) {\n\t\t\t\t\treturnBuffer = \"inactive \";\n\t\t\t\t\tstyleActive -= inactiveFlag;\n\t\t\t\t}\n\t\t\t\tconst int styleMain = StyleFromSubStyle(styleActive);\n\t\t\t\treturnBuffer += lexicalClasses[styleMain].tags;\n\t\t\t\treturn returnBuffer.c_str();\n\t\t\t}\n\t\t}\n\t\tif (style < sizeLexicalClasses)\n\t\t\treturn lexicalClasses[style].tags;\n\t\tif (style >= inactiveFlag) {\n\t\t\treturnBuffer = \"inactive \";\n\t\t\tconst int styleActive = style - inactiveFlag;\n\t\t\tif (styleActive < sizeLexicalClasses)\n\t\t\t\treturnBuffer += lexicalClasses[styleActive].tags;\n\t\t\telse\n\t\t\t\treturnBuffer.clear();\n\t\t\treturn returnBuffer.c_str();\n\t\t}\n\t\treturn \"\";\n\t}\n\tconst char *SCI_METHOD DescriptionOfStyle(int style) override {\n\t\tif (style >= NamedStyles())\n\t\t\treturn \"\";\n\t\tif (style < sizeLexicalClasses)\n\t\t\treturn lexicalClasses[style].description;\n\t\t// TODO: inactive and substyles\n\t\treturn \"\";\n\t}\n\n\t// ILexer5 methods\n\tconst char *SCI_METHOD GetName() override {\n\t\treturn caseSensitive ? \"cpp\" : \"cppnocase\";\n\t}\n\tint SCI_METHOD  GetIdentifier() override {\n\t\treturn caseSensitive ? SCLEX_CPP : SCLEX_CPPNOCASE;\n\t}\n\tconst char *SCI_METHOD PropertyGet(const char *key) override;\n\n\tstatic ILexer5 *LexerFactoryCPP() {\n\t\treturn new LexerCPP(true);\n\t}\n\tstatic ILexer5 *LexerFactoryCPPInsensitive() {\n\t\treturn new LexerCPP(false);\n\t}\n\tconstexpr static int MaskActive(int style) noexcept {\n\t\treturn style & ~inactiveFlag;\n\t}\n\tvoid EvaluateTokens(Tokens &tokens, const SymbolTable &preprocessorDefinitions);\n\t[[nodiscard]] Tokens Tokenize(const std::string &expr) const;\n\tbool EvaluateExpression(const std::string &expr, const SymbolTable &preprocessorDefinitions);\n};\n\nSci_Position SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) {\n\tif (osCPP.PropertySet(&options, key, val)) {\n\t\tconst std::string_view keyView(key);\n\t\tif ((keyView == \"lexer.cpp.allow.dollars\") || (keyView == \"lexer.cpp.allow.hashes\")) {\n\t\t\tsetWord = CharacterSet(CharacterSet::setAlphaNum, \"._\", true);\n\t\t\tif (options.identifiersAllowDollars) {\n\t\t\t\tsetWord.Add('$');\n\t\t\t}\n\t\t\tif (options.identifiersAllowHashes) {\n\t\t\t\tsetWord.Add('#');\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nconst char *SCI_METHOD LexerCPP::PropertyGet(const char *key) {\n\treturn osCPP.PropertyGet(key);\n}\n\nSci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywords2;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywords3;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywords4;\n\t\tbreak;\n\tcase 4:\n\t\twordListN = &ppDefinitions;\n\t\tbreak;\n\tcase 5:\n\t\twordListN = &markerList;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t\tif (n == 4) {\n\t\t\t\t// Rebuild preprocessorDefinitions\n\t\t\t\tpreprocessorDefinitionsStart.clear();\n\t\t\t\tfor (int nDefinition = 0; nDefinition < ppDefinitions.Length(); nDefinition++) {\n\t\t\t\t\tconst Definition def = ParseDefine(ppDefinitions.WordAt(nDefinition), \"(=\");\n\t\t\t\t\tpreprocessorDefinitionsStart[std::string(def.name)] = SymbolValue(def.value, def.arguments);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\n\tconst StyleContext::Transform transform = caseSensitive ?\n\t\tStyleContext::Transform::none : StyleContext::Transform::lower;\n\n\tconst CharacterSet setOKBeforeRE(\"([{=,:;!%^&*|?~+-> \");\n\tconst CharacterSet setCouldBePostOp(\"+-\");\n\n\tconst CharacterSet setDoxygen(CharacterSet::setAlpha, \"$@\\\\&<>#{}[]\");\n\n\tsetWordStart = CharacterSet(CharacterSet::setAlpha, \"_\", true);\n\n\tconst CharacterSet setInvalidRawFirst(\" )\\\\\\t\\v\\f\\n\");\n\n\tif (options.identifiersAllowDollars) {\n\t\tsetWordStart.Add('$');\n\t}\n\tif (options.identifiersAllowHashes) {\n\t\tsetWordStart.Add('#');\n\t}\n\n\tint chPrevNonWhite = ' ';\n\tint visibleChars = 0;\n\tbool lastWordWasUUID = false;\n\tint styleBeforeDCKeyword = SCE_C_DEFAULT;\n\tint styleBeforeTaskMarker = SCE_C_DEFAULT;\n\tbool continuationLine = false;\n\tbool isIncludePreprocessor = false;\n\tbool isStringInPreprocessor = false;\n\tbool inRERange = false;\n\tbool seenDocKeyBrace = false;\n\n\tstd::vector<InterpolatingState> interpolatingStack;\n\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (options.backQuotedStrings == BackQuotedString::TemplateLiteral) {\n\t\t// code copied from LexPython\n\t\tauto it = interpolatingAtEol.find(lineCurrent - 1);\n\t\tif (it != interpolatingAtEol.end()) {\n\t\t\tinterpolatingStack = it->second;\n\t\t}\n\t\tit = interpolatingAtEol.lower_bound(lineCurrent);\n\t\tif (it != interpolatingAtEol.end()) {\n\t\t\tinterpolatingAtEol.erase(it, interpolatingAtEol.end());\n\t\t}\n\t}\n\n\tif ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) ||\n      (MaskActive(initStyle) == SCE_C_COMMENTLINE) ||\n      (MaskActive(initStyle) == SCE_C_COMMENTLINEDOC)) {\n\t\t// Set continuationLine if last character of previous line is '\\'\n\t\tif (lineCurrent > 0) {\n\t\t\tconst Sci_Position endLinePrevious = styler.LineEnd(lineCurrent - 1);\n\t\t\tif (endLinePrevious > 0) {\n\t\t\t\tcontinuationLine = styler.SafeGetCharAt(endLinePrevious-1) == '\\\\';\n\t\t\t}\n\t\t}\n\t}\n\n\t// look back to set chPrevNonWhite properly for better regex colouring\n\tif (startPos > 0) {\n\t\tSci_Position back = startPos;\n\t\twhile (--back && IsSpaceEquiv(MaskActive(styler.StyleAt(back))))\n\t\t\t;\n\t\tif (MaskActive(styler.StyleAt(back)) == SCE_C_OPERATOR) {\n\t\t\tchPrevNonWhite = styler.SafeGetCharAt(back);\n\t\t}\n\t}\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tLinePPState preproc = vlls.ForLine(lineCurrent);\n\n\tbool definitionsChanged = false;\n\n\t// Truncate ppDefineHistory before current line\n\n\tif (!options.updatePreprocessor)\n\t\tppDefineHistory.clear();\n\n\tconst std::vector<PPDefinition>::iterator itInvalid = std::find_if(\n\t\tppDefineHistory.begin(), ppDefineHistory.end(),\n\t\t[lineCurrent](const PPDefinition &p) noexcept { return p.line >= lineCurrent; });\n\tif (itInvalid != ppDefineHistory.end()) {\n\t\tppDefineHistory.erase(itInvalid, ppDefineHistory.end());\n\t\tdefinitionsChanged = true;\n\t}\n\n\tSymbolTable preprocessorDefinitions = preprocessorDefinitionsStart;\n\tfor (const PPDefinition &ppDef : ppDefineHistory) {\n\t\tif (ppDef.isUndef)\n\t\t\tpreprocessorDefinitions.erase(ppDef.key);\n\t\telse\n\t\t\tpreprocessorDefinitions[ppDef.key] = SymbolValue(ppDef.value, ppDef.arguments);\n\t}\n\n\tstd::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);\n\tSparseState<std::string> rawSTNew(lineCurrent);\n\n\tstd::string currentText;\n\n\tint activitySet = preproc.ActiveState();\n\n\tconst WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_C_IDENTIFIER);\n\tconst WordClassifier &classifierDocKeyWords = subStyles.Classifier(SCE_C_COMMENTDOCKEYWORD);\n\n\tSci_PositionU lineEndNext = styler.LineEnd(lineCurrent);\n\n\tif (sc.currentPos == 0 && sc.Match('#', '!')) {\n\t\t// Shell Shebang at beginning of file\n\t\tsc.SetState(SCE_C_COMMENTLINE);\n\t\tsc.Forward();\n\t}\n\n\tfor (; sc.More();) {\n\n\t\tif (sc.atLineStart) {\n\t\t\t// Using MaskActive() is not needed in the following statement.\n\t\t\t// Inside inactive preprocessor declaration, state will be reset anyway at the end of this block.\n\t\t\tif ((sc.state == SCE_C_STRING) || (sc.state == SCE_C_CHARACTER)) {\n\t\t\t\t// Prevent SCE_C_STRINGEOL from leaking back to previous line which\n\t\t\t\t// ends with a line continuation by locking in the state up to this position.\n\t\t\t\tsc.SetState(sc.state);\n\t\t\t}\n\t\t\tif ((MaskActive(sc.state) == SCE_C_PREPROCESSOR) && (!continuationLine)) {\n\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t}\n\t\t\t// Reset states to beginning of colourise so no surprises\n\t\t\t// if different sets of lines lexed.\n\t\t\tvisibleChars = 0;\n\t\t\tlastWordWasUUID = false;\n\t\t\tisIncludePreprocessor = false;\n\t\t\tinRERange = false;\n\t\t\tif (preproc.IsInactive()) {\n\t\t\t\tactivitySet = inactiveFlag;\n\t\t\t\tsc.SetState(sc.state | activitySet);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\tlineCurrent++;\n\t\t\tlineEndNext = styler.LineEnd(lineCurrent);\n\t\t\tvlls.Add(lineCurrent, preproc);\n\t\t\tif (!rawStringTerminator.empty()) {\n\t\t\t\trawSTNew.Set(lineCurrent-1, rawStringTerminator);\n\t\t\t}\n\t\t\tif (!interpolatingStack.empty()) {\n\t\t\t\tinterpolatingAtEol[sc.currentLine] = interpolatingStack;\n\t\t\t}\n\t\t}\n\n\t\t// Handle line continuation generically.\n\t\tif (sc.ch == '\\\\') {\n\t\t\tif ((sc.currentPos+1) >= lineEndNext) {\n\t\t\t\tlineCurrent++;\n\t\t\t\tlineEndNext = styler.LineEnd(lineCurrent);\n\t\t\t\tvlls.Add(lineCurrent, preproc);\n\t\t\t\tif (!rawStringTerminator.empty()) {\n\t\t\t\t\trawSTNew.Set(lineCurrent-1, rawStringTerminator);\n\t\t\t\t}\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\t// Even in UTF-8, \\r and \\n are separate\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tcontinuationLine = true;\n\t\t\t\tsc.Forward();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tconst bool atLineEndBeforeSwitch = sc.atLineEnd;\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (MaskActive(sc.state)) {\n\t\t\tcase SCE_C_OPERATOR:\n\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_NUMBER:\n\t\t\t\t// We accept almost anything because of hex. and number suffixes\n\t\t\t\tif (sc.ch == '_') {\n\t\t\t\t\tsc.ChangeState(SCE_C_USERLITERAL|activitySet);\n\t\t\t\t} else if (!(setWord.Contains(sc.ch)\n\t\t\t\t   || (sc.ch == '\\'')\n\t\t\t\t   || (AnyOf(sc.chPrev, 'e', 'E', 'p', 'P') && AnyOf(sc.ch, '+', '-')))) {\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_USERLITERAL:\n\t\t\t\tif (!(setWord.Contains(sc.ch)))\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_IDENTIFIER:\n\t\t\t\tif (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch) || (sc.ch == '.')) {\n\t\t\t\t\tsc.GetCurrentString(currentText, transform);\n\t\t\t\t\tif (keywords.InList(currentText)) {\n\t\t\t\t\t\tlastWordWasUUID = currentText == \"uuid\";\n\t\t\t\t\t\tsc.ChangeState(SCE_C_WORD|activitySet);\n\t\t\t\t\t} else if (keywords2.InList(currentText)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_C_WORD2|activitySet);\n\t\t\t\t\t} else if (keywords4.InList(currentText)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_C_GLOBALCLASS|activitySet);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst int subStyle = classifierIdentifiers.ValueFor(currentText);\n\t\t\t\t\t\tif (subStyle >= 0) {\n\t\t\t\t\t\t\tsc.ChangeState(subStyle|activitySet);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst bool literalString = sc.ch == '\\\"';\n\t\t\t\t\tif (literalString || sc.ch == '\\'') {\n\t\t\t\t\t\tstd::string_view s = currentText;\n\t\t\t\t\t\tsize_t lenS = s.length();\n\t\t\t\t\t\tconst bool raw = literalString && sc.chPrev == 'R' && !setInvalidRawFirst.Contains(sc.chNext);\n\t\t\t\t\t\tif (raw) {\n\t\t\t\t\t\t\ts.remove_suffix(1);\n\t\t\t\t\t\t\tlenS--;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst bool valid =\n\t\t\t\t\t\t\t(lenS == 0) ||\n\t\t\t\t\t\t\t((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) ||\n\t\t\t\t\t\t\t((lenS == 2) && literalString && (s[0] == 'u') && (s[1] == '8'));\n\t\t\t\t\t\tif (valid) {\n\t\t\t\t\t\t\tif (literalString) {\n\t\t\t\t\t\t\t\tif (raw) {\n\t\t\t\t\t\t\t\t\t// Set the style of the string prefix to SCE_C_STRINGRAW but then change to\n\t\t\t\t\t\t\t\t\t// SCE_C_DEFAULT as that allows the raw string start code to run.\n\t\t\t\t\t\t\t\t\tsc.ChangeState(SCE_C_STRINGRAW|activitySet);\n\t\t\t\t\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tsc.ChangeState(SCE_C_STRING|activitySet);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsc.ChangeState(SCE_C_CHARACTER|activitySet);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState(SCE_C_DEFAULT | activitySet);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_PREPROCESSOR:\n\t\t\t\tif (options.stylingWithinPreprocessor) {\n\t\t\t\t\tif (IsASpace(sc.ch) || (sc.ch == '(')) {\n\t\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\t}\n\t\t\t\t} else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\\\"') || sc.atLineEnd)) {\n\t\t\t\t\tisStringInPreprocessor = false;\n\t\t\t\t} else if (!isStringInPreprocessor) {\n\t\t\t\t\tif ((isIncludePreprocessor && sc.Match('<')) || sc.Match('\\\"')) {\n\t\t\t\t\t\tisStringInPreprocessor = true;\n\t\t\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\t\t\tif (sc.Match(\"/**\") || sc.Match(\"/*!\")) {\n\t\t\t\t\t\t\tsc.SetState(SCE_C_PREPROCESSORCOMMENTDOC|activitySet);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState(SCE_C_PREPROCESSORCOMMENT|activitySet);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsc.Forward();\t// Eat the *\n\t\t\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_PREPROCESSORCOMMENT:\n\t\t\tcase SCE_C_PREPROCESSORCOMMENTDOC:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_C_PREPROCESSOR|activitySet);\n\t\t\t\t\tcontinue;\t// Without advancing in case of '\\'.\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_COMMENT:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t} else {\n\t\t\t\t\tstyleBeforeTaskMarker = SCE_C_COMMENT;\n\t\t\t\t\thighlightTaskMarker(sc, styler, activitySet, markerList, caseSensitive);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_COMMENTDOC:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t} else if (sc.ch == '@' || sc.ch == '\\\\') { // JavaDoc and Doxygen support\n\t\t\t\t\t// Verify that we have the conditions to mark a comment-doc-keyword\n\t\t\t\t\tif ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {\n\t\t\t\t\t\tstyleBeforeDCKeyword = SCE_C_COMMENTDOC;\n\t\t\t\t\t\tsc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);\n\t\t\t\t\t}\n\t\t\t\t} else if ((sc.ch == '<' && !(IsASpace(sc.chNext) || sc.chNext == '/'))\n\t\t\t\t\t\t\t|| (sc.ch == '/' && sc.chPrev == '<')) { // XML comment style\n\t\t\t\t\tstyleBeforeDCKeyword = SCE_C_COMMENTDOC;\n\t\t\t\t\tsc.ForwardSetState(SCE_C_COMMENTDOCKEYWORD | activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart && !continuationLine) {\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t} else {\n\t\t\t\t\tstyleBeforeTaskMarker = SCE_C_COMMENTLINE;\n\t\t\t\t\thighlightTaskMarker(sc, styler, activitySet, markerList, caseSensitive);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_COMMENTLINEDOC:\n\t\t\t\tif (sc.atLineStart && !continuationLine) {\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t} else if (sc.ch == '@' || sc.ch == '\\\\') { // JavaDoc and Doxygen support\n\t\t\t\t\t// Verify that we have the conditions to mark a comment-doc-keyword\n\t\t\t\t\tif ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {\n\t\t\t\t\t\tstyleBeforeDCKeyword = SCE_C_COMMENTLINEDOC;\n\t\t\t\t\t\tsc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);\n\t\t\t\t\t}\n\t\t\t\t} else if ((sc.ch == '<' && sc.chNext != '/')\n\t\t\t\t\t\t\t|| (sc.ch == '/' && sc.chPrev == '<')) { // XML comment style\n\t\t\t\t\tstyleBeforeDCKeyword = SCE_C_COMMENTLINEDOC;\n\t\t\t\t\tsc.ForwardSetState(SCE_C_COMMENTDOCKEYWORD | activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_COMMENTDOCKEYWORD:\n\t\t\t\tif ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {\n\t\t\t\t\tsc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\tseenDocKeyBrace = false;\n\t\t\t\t} else if (sc.ch == '[' || sc.ch == '{') {\n\t\t\t\t\tseenDocKeyBrace = true;\n\t\t\t\t} else if (!setDoxygen.Contains(sc.ch)\n\t\t\t\t           && !(seenDocKeyBrace && AnyOf(sc.ch, ',', '.'))) {\n\t\t\t\t\tif (!(IsASpace(sc.ch) || (sc.ch == 0))) {\n\t\t\t\t\t\tsc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.GetCurrentString(currentText, transform);\n\t\t\t\t\t\tassert(!currentText.empty());\n\t\t\t\t\t\tconst std::string currentSuffix = currentText.substr(1);\n\t\t\t\t\t\tif (!keywords3.InList(currentSuffix) && !keywords3.InList(currentText)) {\n\t\t\t\t\t\t\tconst int subStyleCDKW = classifierDocKeyWords.ValueFor(currentSuffix);\n\t\t\t\t\t\t\tif (subStyleCDKW >= 0) {\n\t\t\t\t\t\t\t\tsc.ChangeState(subStyleCDKW | activitySet);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR | activitySet);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(styleBeforeDCKeyword|activitySet);\n\t\t\t\t\tseenDocKeyBrace = false;\n\t\t\t\t} else if (sc.ch == '>') {\n\t\t\t\t\tsc.GetCurrentString(currentText, transform);\n\t\t\t\t\tif (!keywords3.InList(currentText)) {\n\t\t\t\t\t\tconst int subStyleCDKW = classifierDocKeyWords.ValueFor(currentText.substr(1));\n\t\t\t\t\t\tif (subStyleCDKW >= 0) {\n\t\t\t\t\t\t\tsc.ChangeState(subStyleCDKW | activitySet);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR | activitySet);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(styleBeforeDCKeyword | activitySet);\n\t\t\t\t\tseenDocKeyBrace = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_STRING:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_C_STRINGEOL|activitySet);\n\t\t\t\t} else if (isIncludePreprocessor) {\n\t\t\t\t\tif (sc.ch == '>') {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\t\tisIncludePreprocessor = false;\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (options.escapeSequence) {\n\t\t\t\t\t\tescapeSeq.resetEscapeState(sc.state, sc.chNext);\n\t\t\t\t\t\tsc.SetState(SCE_C_ESCAPESEQUENCE|activitySet);\n\t\t\t\t\t}\n\t\t\t\t\tsc.Forward(); // Skip all characters after the backslash\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tif (sc.chNext == '_') {\n\t\t\t\t\t\tsc.ChangeState(SCE_C_USERLITERAL|activitySet);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_ESCAPESEQUENCE:\n\t\t\t\tescapeSeq.consumeDigit();\n\t\t\t\tif (escapeSeq.atEscapeEnd(sc.ch)) {\n\t\t\t\t\tsc.SetState(escapeSeq.outerState);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_HASHQUOTEDSTRING:\n\t\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tsc.ForwardSetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_STRINGRAW:\n\t\t\t\tif (sc.Match(rawStringTerminator.c_str())) {\n\t\t\t\t\tfor (size_t termPos=rawStringTerminator.size(); termPos; termPos--)\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\tif (interpolatingStack.empty()) {\n\t\t\t\t\t\trawStringTerminator.clear();\n\t\t\t\t\t}\n\t\t\t\t} else if (options.backQuotedStrings == BackQuotedString::TemplateLiteral) {\n\t\t\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t\t\tif (options.escapeSequence) {\n\t\t\t\t\t\t\tescapeSeq.resetEscapeState(sc.state, sc.chNext);\n\t\t\t\t\t\t\tsc.SetState(SCE_C_ESCAPESEQUENCE|activitySet);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsc.Forward(); // Skip all characters after the backslash\n\t\t\t\t\t} else if (sc.Match('$', '{')) {\n\t\t\t\t\t\tinterpolatingStack.push_back({sc.state, 1});\n\t\t\t\t\t\tsc.SetState(SCE_C_OPERATOR|activitySet);\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_CHARACTER:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_C_STRINGEOL|activitySet);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\tif (sc.chNext == '_') {\n\t\t\t\t\t\tsc.ChangeState(SCE_C_USERLITERAL|activitySet);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_REGEX:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t} else if (!inRERange && sc.ch == '/') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\twhile (IsLowerCase(sc.ch))\n\t\t\t\t\t\tsc.Forward();    // gobble regex flags\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t} else if (sc.ch == '\\\\' && ((sc.currentPos+1) < lineEndNext)) {\n\t\t\t\t\t// Gobble up the escaped character\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (sc.ch == '[') {\n\t\t\t\t\tinRERange = true;\n\t\t\t\t} else if (sc.ch == ']') {\n\t\t\t\t\tinRERange = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_STRINGEOL:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_VERBATIM:\n\t\t\t\tif (options.verbatimStringsAllowEscapes && (sc.ch == '\\\\')) {\n\t\t\t\t\tsc.Forward(); // Skip all characters after the backslash\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tif (sc.chNext == '\\\"') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_TRIPLEVERBATIM:\n\t\t\t\tif (sc.Match(R\"(\"\"\")\")) {\n\t\t\t\t\twhile (sc.Match('\"')) {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_UUID:\n\t\t\t\tif (sc.atLineEnd || sc.ch == ')') {\n\t\t\t\t\tsc.SetState(SCE_C_DEFAULT|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_C_TASKMARKER:\n\t\t\t\tif (IsOperatorOrSpace(sc.ch)) {\n\t\t\t\t\tsc.SetState(styleBeforeTaskMarker|activitySet);\n\t\t\t\t\tstyleBeforeTaskMarker = SCE_C_DEFAULT;\n\t\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd && !atLineEndBeforeSwitch) {\n\t\t\t// State exit processing consumed characters up to end of line.\n\t\t\tlineCurrent++;\n\t\t\tlineEndNext = styler.LineEnd(lineCurrent);\n\t\t\tvlls.Add(lineCurrent, preproc);\n\t\t}\n\n\t\tconst bool atLineEndBeforeStateEntry = sc.atLineEnd;\n\n\t\t// Determine if a new state should be entered.\n\t\tif (MaskActive(sc.state) == SCE_C_DEFAULT) {\n\t\t\tif (sc.Match('@', '\\\"')) {\n\t\t\t\tsc.SetState(SCE_C_VERBATIM|activitySet);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (options.triplequotedStrings && sc.Match(R\"(\"\"\")\")) {\n\t\t\t\tsc.SetState(SCE_C_TRIPLEVERBATIM|activitySet);\n\t\t\t\tsc.Forward(2);\n\t\t\t} else if (options.hashquotedStrings && sc.Match('#', '\\\"')) {\n\t\t\t\tsc.SetState(SCE_C_HASHQUOTEDSTRING|activitySet);\n\t\t\t\tsc.Forward();\n\t\t\t} else if ((options.backQuotedStrings != BackQuotedString::None) && sc.Match('`')) {\n\t\t\t\tsc.SetState(SCE_C_STRINGRAW|activitySet);\n\t\t\t\trawStringTerminator = \"`\";\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tif (lastWordWasUUID) {\n\t\t\t\t\tsc.SetState(SCE_C_UUID|activitySet);\n\t\t\t\t\tlastWordWasUUID = false;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_C_NUMBER|activitySet);\n\t\t\t\t}\n\t\t\t} else if (!sc.atLineEnd && (setWordStart.Contains(sc.ch) || (sc.ch == '@'))) {\n\t\t\t\tif (lastWordWasUUID) {\n\t\t\t\t\tsc.SetState(SCE_C_UUID|activitySet);\n\t\t\t\t\tlastWordWasUUID = false;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_C_IDENTIFIER|activitySet);\n\t\t\t\t}\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tif (sc.Match(\"/**\") || sc.Match(\"/*!\")) {\t// Support of Qt/Doxygen doc. style\n\t\t\t\t\tsc.SetState(SCE_C_COMMENTDOC|activitySet);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_C_COMMENT|activitySet);\n\t\t\t\t}\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tif ((sc.Match(\"///\") && !sc.Match(\"////\")) || sc.Match(\"//!\"))\n\t\t\t\t\t// Support of Qt/Doxygen doc. style\n\t\t\t\t\tsc.SetState(SCE_C_COMMENTLINEDOC|activitySet);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_C_COMMENTLINE|activitySet);\n\t\t\t} else if (sc.ch == '/'\n\t\t\t\t   && (setOKBeforeRE.Contains(chPrevNonWhite)\n\t\t\t\t       || followsReturnKeyword(sc, styler))\n\t\t\t\t   && (!setCouldBePostOp.Contains(chPrevNonWhite)\n\t\t\t\t       || !FollowsPostfixOperator(sc, styler))) {\n\t\t\t\tsc.SetState(SCE_C_REGEX|activitySet);\t// JavaScript's RegEx\n\t\t\t\tinRERange = false;\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tif (sc.chPrev == 'R') {\n\t\t\t\t\tstyler.Flush();\n\t\t\t\t\tif (MaskActive(styler.StyleAt(sc.currentPos - 1)) == SCE_C_STRINGRAW) {\n\t\t\t\t\t\tsc.SetState(SCE_C_STRINGRAW|activitySet);\n\t\t\t\t\t\trawStringTerminator = \")\";\n\t\t\t\t\t\tfor (Sci_Position termPos = sc.currentPos + 1;; termPos++) {\n\t\t\t\t\t\t\tconst char chTerminator = styler.SafeGetCharAt(termPos, '(');\n\t\t\t\t\t\t\tif (chTerminator == '(')\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\trawStringTerminator += chTerminator;\n\t\t\t\t\t\t}\n\t\t\t\t\t\trawStringTerminator += '\\\"';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_C_STRING|activitySet);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_C_STRING|activitySet);\n\t\t\t\t}\n\t\t\t\tisIncludePreprocessor = false;\t// ensure that '>' won't end the string\n\t\t\t} else if (isIncludePreprocessor && sc.ch == '<') {\n\t\t\t\tsc.SetState(SCE_C_STRING|activitySet);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_C_CHARACTER|activitySet);\n\t\t\t} else if (sc.ch == '#' && visibleChars == 0 && options.enablePreprocessor) {\n\t\t\t\t// Preprocessor commands are alone on their line\n\t\t\t\tsc.SetState(SCE_C_PREPROCESSOR|activitySet);\n\t\t\t\t// Skip whitespace between # and preprocessor word\n\t\t\t\tdo {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} while ((sc.ch == ' ' || sc.ch == '\\t') && sc.More());\n\t\t\t\tif (sc.Match(\"include\")) {\n\t\t\t\t\tisIncludePreprocessor = true;\n\t\t\t\t} else {\n\t\t\t\t\tif (options.trackPreprocessor && IsAlphaNumeric(sc.ch)) {\n\t\t\t\t\t\t// If #if is nested too deeply (>31 levels) the active/inactive appearance\n\t\t\t\t\t\t// will stop reflecting the code.\n\t\t\t\t\t\tif (sc.Match(\"ifdef\") || sc.Match(\"ifndef\")) {\n\t\t\t\t\t\t\tconst bool isIfDef = sc.Match(\"ifdef\");\n\t\t\t\t\t\t\tconst int startRest = isIfDef ? 5 : 6;\n\t\t\t\t\t\t\tconst std::string restOfLine = GetRestOfLine(styler, sc.currentPos + startRest + 1, false);\n\t\t\t\t\t\t\tconst bool foundDef = preprocessorDefinitions.find(restOfLine) != preprocessorDefinitions.end();\n\t\t\t\t\t\t\tpreproc.StartSection(isIfDef == foundDef);\n\t\t\t\t\t\t} else if (sc.Match(\"if\")) {\n\t\t\t\t\t\t\tconst std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true);\n\t\t\t\t\t\t\tconst bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);\n\t\t\t\t\t\t\tpreproc.StartSection(ifGood);\n\t\t\t\t\t\t} else if (sc.Match(\"else\")) {\n\t\t\t\t\t\t\t// #else is shown as active if either preceding or following section is active\n\t\t\t\t\t\t\t// as that means that it contributed to the result.\n\t\t\t\t\t\t\tif (preproc.ValidLevel()) {\n\t\t\t\t\t\t\t\t// If #else has no corresponding #if then take no action as invalid\n\t\t\t\t\t\t\t\tif (!preproc.CurrentIfTaken()) {\n\t\t\t\t\t\t\t\t\t// Inactive, may become active if parent scope active\n\t\t\t\t\t\t\t\t\tassert(sc.state == (SCE_C_PREPROCESSOR | inactiveFlag));\n\t\t\t\t\t\t\t\t\tpreproc.InvertCurrentLevel();\n\t\t\t\t\t\t\t\t\tactivitySet = preproc.ActiveState();\n\t\t\t\t\t\t\t\t\t// If following is active then show \"else\" as active\n\t\t\t\t\t\t\t\t\tif (!activitySet)\n\t\t\t\t\t\t\t\t\t\tsc.ChangeState(SCE_C_PREPROCESSOR);\n\t\t\t\t\t\t\t\t} else if (preproc.IsActive()) {\n\t\t\t\t\t\t\t\t\t// Active -> inactive\n\t\t\t\t\t\t\t\t\tassert(sc.state == SCE_C_PREPROCESSOR);\n\t\t\t\t\t\t\t\t\tpreproc.InvertCurrentLevel();\n\t\t\t\t\t\t\t\t\tactivitySet = preproc.ActiveState();\n\t\t\t\t\t\t\t\t\t// Continue to show \"else\" as active as it ends active section.\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.Match(\"elif\")) {\n\t\t\t\t\t\t\t// Ensure only one chosen out of #if .. #elif .. #elif .. #else .. #endif\n\t\t\t\t\t\t\t// #elif is shown as active if either preceding or following section is active\n\t\t\t\t\t\t\t// as that means that it contributed to the result.\n\t\t\t\t\t\t\tif (preproc.ValidLevel()) {\n\t\t\t\t\t\t\t\tif (!preproc.CurrentIfTaken()) {\n\t\t\t\t\t\t\t\t\t// Inactive, if expression true then may become active if parent scope active\n\t\t\t\t\t\t\t\t\tassert(sc.state == (SCE_C_PREPROCESSOR | inactiveFlag));\n\t\t\t\t\t\t\t\t\t// Similar to #if\n\t\t\t\t\t\t\t\t\tconst std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 4, true);\n\t\t\t\t\t\t\t\t\tconst bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);\n\t\t\t\t\t\t\t\t\tif (ifGood) {\n\t\t\t\t\t\t\t\t\t\tpreproc.InvertCurrentLevel();\n\t\t\t\t\t\t\t\t\t\tactivitySet = preproc.ActiveState();\n\t\t\t\t\t\t\t\t\t\tif (!activitySet)\n\t\t\t\t\t\t\t\t\t\t\tsc.ChangeState(SCE_C_PREPROCESSOR);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else if (preproc.IsActive()) {\n\t\t\t\t\t\t\t\t\t// Active -> inactive\n\t\t\t\t\t\t\t\t\tassert(sc.state == SCE_C_PREPROCESSOR);\n\t\t\t\t\t\t\t\t\tpreproc.InvertCurrentLevel();\n\t\t\t\t\t\t\t\t\tactivitySet = preproc.ActiveState();\n\t\t\t\t\t\t\t\t\t// Continue to show \"elif\" as active as it ends active section.\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.Match(\"endif\")) {\n\t\t\t\t\t\t\tpreproc.EndSection();\n\t\t\t\t\t\t\tactivitySet = preproc.ActiveState();\n\t\t\t\t\t\t\tsc.ChangeState(SCE_C_PREPROCESSOR|activitySet);\n\t\t\t\t\t\t} else if (sc.Match(\"define\")) {\n\t\t\t\t\t\t\tif (options.updatePreprocessor && preproc.IsActive()) {\n\t\t\t\t\t\t\t\tconst std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true);\n\t\t\t\t\t\t\t\tconst Definition def = ParseDefine(restOfLine, \"( \\t\");\n\t\t\t\t\t\t\t\tpreprocessorDefinitions[std::string(def.name)] = SymbolValue(def.value, def.arguments);\n\t\t\t\t\t\t\t\tppDefineHistory.emplace_back(lineCurrent, def.name, def.value, false, def.arguments);\n\t\t\t\t\t\t\t\tdefinitionsChanged = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.Match(\"undef\")) {\n\t\t\t\t\t\t\tif (options.updatePreprocessor && preproc.IsActive()) {\n\t\t\t\t\t\t\t\tconst std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, false);\n\t\t\t\t\t\t\t\tTokens tokens = Tokenize(restOfLine);\n\t\t\t\t\t\t\t\tif (!tokens.empty()) {\n\t\t\t\t\t\t\t\t\tconst std::string key = tokens[0];\n\t\t\t\t\t\t\t\t\tpreprocessorDefinitions.erase(key);\n\t\t\t\t\t\t\t\t\tppDefineHistory.emplace_back(lineCurrent, key, \"\", true, \"\");\n\t\t\t\t\t\t\t\t\tdefinitionsChanged = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (isoperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_C_OPERATOR|activitySet);\n\t\t\t\tif (!interpolatingStack.empty() && AnyOf(sc.ch, '{', '}')) {\n\t\t\t\t\tInterpolatingState &current = interpolatingStack.back();\n\t\t\t\t\tif (sc.ch == '{') {\n\t\t\t\t\t\tcurrent.braceCount += 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent.braceCount -= 1;\n\t\t\t\t\t\tif (current.braceCount == 0) {\n\t\t\t\t\t\t\tsc.ForwardSetState(current.state);\n\t\t\t\t\t\t\tinterpolatingStack.pop_back();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd && !atLineEndBeforeStateEntry) {\n\t\t\t// State entry processing consumed characters up to end of line.\n\t\t\tlineCurrent++;\n\t\t\tlineEndNext = styler.LineEnd(lineCurrent);\n\t\t\tvlls.Add(lineCurrent, preproc);\n\t\t}\n\n\t\tif (!IsASpace(sc.ch) && !IsSpaceEquiv(MaskActive(sc.state))) {\n\t\t\tchPrevNonWhite = sc.ch;\n\t\t\tvisibleChars++;\n\t\t}\n\t\tcontinuationLine = false;\n\t\tsc.Forward();\n\t}\n\tconst bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent);\n\tif (definitionsChanged || rawStringsChanged)\n\t\tstyler.ChangeLexerState(startPos, startPos + length);\n\tsc.Complete();\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\n\nvoid SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\n\tif (!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\n\tconst Sci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tbool inLineComment = false;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = FoldLevelStart(styler.LevelAt(lineCurrent-1));\n\tSci_PositionU lineStartNext = styler.LineStart(lineCurrent+1);\n\tint levelMinCurrent = levelCurrent;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = MaskActive(styler.StyleAt(startPos));\n\tint style = MaskActive(initStyle);\n\tconst bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = MaskActive(styler.StyleAt(i + 1));\n\t\tconst bool atEOL = i == (lineStartNext-1);\n\t\tif ((style == SCE_C_COMMENTLINE) || (style == SCE_C_COMMENTLINEDOC))\n\t\t\tinLineComment = true;\n\t\tif (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_COMMENTLINE) || options.foldExplicitAnywhere)) {\n\t\t\tif (userDefinedFoldMarkers) {\n\t\t\t\tif (styler.Match(i, options.foldExplicitStart.c_str())) {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ((ch == '/') && (chNext == '/')) {\n\t\t\t\t\tconst char chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {\n\t\t\tif (ch == '#') {\n\t\t\t\tSci_PositionU j = i + 1;\n\t\t\t\twhile ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tif (styler.Match(j, \"region\") || styler.Match(j, \"if\")) {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (styler.Match(j, \"end\")) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t} else if (styler.Match(j, \"pragma\")) {\n\t\t\t\t\tconstexpr size_t lenPragma = 6;\n\t\t\t\t\tj += lenPragma;\n\t\t\t\t\tif (IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\t\twhile ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (styler.Match(j, \"region\")) {\n\t\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t\t} else if (styler.Match(j, \"endregion\")) {\n\t\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (options.foldPreprocessorAtElse && (styler.Match(j, \"else\") || styler.Match(j, \"elif\"))) {\n\t\t\t\t\tlevelMinCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (options.foldSyntaxBased && (style == SCE_C_OPERATOR)) {\n\t\t\tif (ch == '{' || ch == '[' || ch == '(') {\n\t\t\t\t// Measure the minimum before a '{' to allow\n\t\t\t\t// folding on \"} else {\"\n\t\t\t\tif (options.foldAtElse && levelMinCurrent > levelNext) {\n\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t}\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}' || ch == ']' || ch == ')') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\t\tif (atEOL || (i == endPos-1)) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tif ((options.foldSyntaxBased && options.foldAtElse) ||\n\t\t\t\t(options.foldPreprocessor && options.foldPreprocessorAtElse)\n\t\t\t) {\n\t\t\t\tlevelUse = levelMinCurrent;\n\t\t\t}\n\t\t\tconst int lev = FoldLevelForCurrentNext(levelUse, levelNext) |\n\t\t\t\tFoldLevelFlags(levelUse, levelNext, visibleChars == 0 && options.foldCompact);\n\t\t\tstyler.SetLevelIfDifferent(lineCurrent, lev);\n\t\t\tlineCurrent++;\n\t\t\tlineStartNext = styler.LineStart(lineCurrent+1);\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelMinCurrent = levelCurrent;\n\t\t\tif (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) {\n\t\t\t\t// There is an empty line at end of file so give it same level and empty\n\t\t\t\tstyler.SetLevel(lineCurrent, FoldLevelForCurrent(levelCurrent) | SC_FOLDLEVELWHITEFLAG);\n\t\t\t}\n\t\t\tvisibleChars = 0;\n\t\t\tinLineComment = false;\n\t\t}\n\t}\n}\n\nvoid LexerCPP::EvaluateTokens(Tokens &tokens, const SymbolTable &preprocessorDefinitions) {\n\n\t// Remove whitespace tokens\n\ttokens.erase(std::remove_if(tokens.begin(), tokens.end(), OnlySpaceOrTab), tokens.end());\n\n\t// Evaluate defined statements to either 0 or 1\n\tfor (size_t i=0; (i+1)<tokens.size();) {\n\t\tif (tokens[i] == \"defined\") {\n\t\t\tconst char *val = \"0\";\n\t\t\tif (tokens[i+1] == \"(\") {\n\t\t\t\tif (((i + 2)<tokens.size()) && (tokens[i + 2] == \")\")) {\n\t\t\t\t\t// defined()\n\t\t\t\t\ttokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 3);\n\t\t\t\t} else if (((i+3)<tokens.size()) && (tokens[i+3] == \")\")) {\n\t\t\t\t\t// defined(<identifier>)\n\t\t\t\t\tconst SymbolTable::const_iterator it = preprocessorDefinitions.find(tokens[i+2]);\n\t\t\t\t\tif (it != preprocessorDefinitions.end()) {\n\t\t\t\t\t\tval = \"1\";\n\t\t\t\t\t}\n\t\t\t\t\ttokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 4);\n\t\t\t\t} else {\n\t\t\t\t\t// Spurious '(' so erase as more likely to result in false\n\t\t\t\t\ttokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 2);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// defined <identifier>\n\t\t\t\tconst SymbolTable::const_iterator it = preprocessorDefinitions.find(tokens[i+1]);\n\t\t\t\tif (it != preprocessorDefinitions.end()) {\n\t\t\t\t\tval = \"1\";\n\t\t\t\t}\n\t\t\t\ttokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 2);\n\t\t\t}\n\t\t\ttokens[i] = val;\n\t\t} else {\n\t\t\ti++;\n\t\t}\n\t}\n\n\t// Evaluate identifiers\n\tconstexpr size_t maxIterations = 100;\n\tsize_t iterations = 0;\t// Limit number of iterations in case there is a recursive macro.\n\tfor (size_t i = 0; (i<tokens.size()) && (iterations < maxIterations);) {\n\t\titerations++;\n\t\tif (setWordStart.Contains(tokens[i][0])) {\n\t\t\tconst SymbolTable::const_iterator it = preprocessorDefinitions.find(tokens[i]);\n\t\t\tif (it != preprocessorDefinitions.end()) {\n\t\t\t\t// Tokenize value\n\t\t\t\tTokens macroTokens = Tokenize(it->second.value);\n\t\t\t\tif (it->second.IsMacro()) {\n\t\t\t\t\tif ((i + 1 < tokens.size()) && (tokens.at(i + 1) == \"(\")) {\n\t\t\t\t\t\t// Create map of argument name to value\n\t\t\t\t\t\tconst Tokens argumentNames = StringSplit(it->second.arguments, ',');\n\t\t\t\t\t\tstd::map<std::string, std::string> arguments;\n\t\t\t\t\t\tsize_t arg = 0;\n\t\t\t\t\t\tsize_t tok = i+2;\n\t\t\t\t\t\twhile ((tok < tokens.size()) && (arg < argumentNames.size()) && (tokens.at(tok) != \")\")) {\n\t\t\t\t\t\t\tif (tokens.at(tok) != \",\") {\n\t\t\t\t\t\t\t\targuments[argumentNames.at(arg)] = tokens.at(tok);\n\t\t\t\t\t\t\t\targ++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttok++;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Remove invocation\n\t\t\t\t\t\ttokens.erase(tokens.begin() + i, tokens.begin() + tok + 1);\n\n\t\t\t\t\t\t// Substitute values into macro\n\t\t\t\t\t\tmacroTokens.erase(std::remove_if(macroTokens.begin(), macroTokens.end(), OnlySpaceOrTab), macroTokens.end());\n\n\t\t\t\t\t\tfor (size_t iMacro = 0; iMacro < macroTokens.size();) {\n\t\t\t\t\t\t\tif (setWordStart.Contains(macroTokens[iMacro][0])) {\n\t\t\t\t\t\t\t\tconst std::map<std::string, std::string>::const_iterator itFind =\n\t\t\t\t\t\t\t\t\targuments.find(macroTokens[iMacro]);\n\t\t\t\t\t\t\t\tif (itFind != arguments.end()) {\n\t\t\t\t\t\t\t\t\t// TODO: Possible that value will be expression so should insert tokenized form\n\t\t\t\t\t\t\t\t\tmacroTokens[iMacro] = itFind->second;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tiMacro++;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Insert results back into tokens\n\t\t\t\t\t\ttokens.insert(tokens.begin() + i, macroTokens.begin(), macroTokens.end());\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Remove invocation\n\t\t\t\t\ttokens.erase(tokens.begin() + i);\n\t\t\t\t\t// Insert results back into tokens\n\t\t\t\t\ttokens.insert(tokens.begin() + i, macroTokens.begin(), macroTokens.end());\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Identifier not found and value defaults to zero\n\t\t\t\ttokens[i] = \"0\";\n\t\t\t}\n\t\t} else {\n\t\t\ti++;\n\t\t}\n\t}\n\n\t// Find bracketed subexpressions and recurse on them\n\tBracketPair bracketPair = FindBracketPair(tokens);\n\twhile (bracketPair.itBracket != tokens.end()) {\n\t\tTokens inBracket(bracketPair.itBracket + 1, bracketPair.itEndBracket);\n\t\tEvaluateTokens(inBracket, preprocessorDefinitions);\n\n\t\t// The insertion is done before the removal because there were failures with the opposite approach\n\t\ttokens.insert(bracketPair.itBracket, inBracket.begin(), inBracket.end());\n\n\t\t// insert invalidated bracketPair. Use a new variable to avoid warning from Coverity.\n\t\tconst BracketPair pairToErase = FindBracketPair(tokens);\n\t\ttokens.erase(pairToErase.itBracket, pairToErase.itEndBracket + 1);\n\n\t\tbracketPair = FindBracketPair(tokens);\n\t}\n\n\t// Evaluate logical negations\n\tfor (size_t j=0; (j+1)<tokens.size();) {\n\t\tif (setNegationOp.Contains(tokens[j][0]) && (tokens[j] != \"!=\")) {\n\t\t\tint isTrue = atoi(tokens[j+1].c_str());\n\t\t\tif (tokens[j] == \"!\")\n\t\t\t\tisTrue = !isTrue;\n\t\t\tconst Tokens::iterator itInsert =\n\t\t\t\ttokens.erase(tokens.begin() + j, tokens.begin() + j + 2);\n\t\t\ttokens.insert(itInsert, isTrue ? \"1\" : \"0\");\n\t\t} else {\n\t\t\tj++;\n\t\t}\n\t}\n\n\t// Evaluate expressions in precedence order\n\tenum precedence { precMult, precAdd, precRelative\n\t\t, precLogical, /* end marker */ precLast };\n\tfor (int prec = precMult; prec < precLast; prec++) {\n\t\t// Looking at 3 tokens at a time so end at 2 before end\n\t\tfor (size_t k=0; (k+2)<tokens.size();) {\n\t\t\tconst char chOp = tokens[k+1][0];\n\t\t\tif (\n\t\t\t\t((prec==precMult) && setMultOp.Contains(chOp)) ||\n\t\t\t\t((prec==precAdd) && setAddOp.Contains(chOp)) ||\n\t\t\t\t((prec==precRelative) && setRelOp.Contains(chOp)) ||\n\t\t\t\t((prec==precLogical) && setLogicalOp.Contains(chOp))\n\t\t\t\t) {\n\t\t\t\tconst int valA = atoi(tokens[k].c_str());\n\t\t\t\tconst int valB = atoi(tokens[k+2].c_str());\n\t\t\t\tint result = 0;\n\t\t\t\tif (tokens[k+1] == \"+\")\n\t\t\t\t\tresult = valA + valB;\n\t\t\t\telse if (tokens[k+1] == \"-\")\n\t\t\t\t\tresult = valA - valB;\n\t\t\t\telse if (tokens[k+1] == \"*\")\n\t\t\t\t\tresult = valA * valB;\n\t\t\t\telse if (tokens[k+1] == \"/\")\n\t\t\t\t\tresult = valA / (valB ? valB : 1);\n\t\t\t\telse if (tokens[k+1] == \"%\")\n\t\t\t\t\tresult = valA % (valB ? valB : 1);\n\t\t\t\telse if (tokens[k+1] == \"<\")\n\t\t\t\t\tresult = valA < valB;\n\t\t\t\telse if (tokens[k+1] == \"<=\")\n\t\t\t\t\tresult = valA <= valB;\n\t\t\t\telse if (tokens[k+1] == \">\")\n\t\t\t\t\tresult = valA > valB;\n\t\t\t\telse if (tokens[k+1] == \">=\")\n\t\t\t\t\tresult = valA >= valB;\n\t\t\t\telse if (tokens[k+1] == \"==\")\n\t\t\t\t\tresult = valA == valB;\n\t\t\t\telse if (tokens[k+1] == \"!=\")\n\t\t\t\t\tresult = valA != valB;\n\t\t\t\telse if (tokens[k+1] == \"||\")\n\t\t\t\t\tresult = valA || valB;\n\t\t\t\telse if (tokens[k+1] == \"&&\")\n\t\t\t\t\tresult = valA && valB;\n\t\t\t\tconst Tokens::iterator itInsert =\n\t\t\t\t\ttokens.erase(tokens.begin() + k, tokens.begin() + k + 3);\n\t\t\t\ttokens.insert(itInsert, std::to_string(result));\n\t\t\t} else {\n\t\t\t\tk++;\n\t\t\t}\n\t\t}\n\t}\n}\n\nTokens LexerCPP::Tokenize(const std::string &expr) const {\n\t// Break into tokens\n\tTokens tokens;\n\tconst char *cp = expr.c_str();\n\twhile (*cp) {\n\t\tstd::string word;\n\t\tif (setWord.Contains(*cp)) {\n\t\t\t// Identifiers and numbers\n\t\t\twhile (setWord.Contains(*cp)) {\n\t\t\t\tword += *cp;\n\t\t\t\tcp++;\n\t\t\t}\n\t\t} else if (IsASpaceOrTab(*cp)) {\n\t\t\twhile (IsASpaceOrTab(*cp)) {\n\t\t\t\tword += *cp;\n\t\t\t\tcp++;\n\t\t\t}\n\t\t} else if (setRelOp.Contains(*cp)) {\n\t\t\tword += *cp;\n\t\t\tcp++;\n\t\t\tif (setRelOp.Contains(*cp)) {\n\t\t\t\tword += *cp;\n\t\t\t\tcp++;\n\t\t\t}\n\t\t} else if (setLogicalOp.Contains(*cp)) {\n\t\t\tword += *cp;\n\t\t\tcp++;\n\t\t\tif (setLogicalOp.Contains(*cp)) {\n\t\t\t\tword += *cp;\n\t\t\t\tcp++;\n\t\t\t}\n\t\t} else {\n\t\t\t// Should handle strings, characters, and comments here\n\t\t\tword += *cp;\n\t\t\tcp++;\n\t\t}\n\t\ttokens.push_back(std::move(word));\n\t}\n\treturn tokens;\n}\n\nbool LexerCPP::EvaluateExpression(const std::string &expr, const SymbolTable &preprocessorDefinitions) {\n\tTokens tokens = Tokenize(expr);\n\n\tEvaluateTokens(tokens, preprocessorDefinitions);\n\n\t// \"0\" or \"\" -> false else true\n\tconst bool isFalse = tokens.empty() ||\n\t\t((tokens.size() == 1) && (tokens[0].empty() || tokens[0] == \"0\"));\n\treturn !isFalse;\n}\n\nextern const LexerModule lmCPP(SCLEX_CPP, LexerCPP::LexerFactoryCPP, \"cpp\", cppWordLists);\nextern const LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, LexerCPP::LexerFactoryCPPInsensitive, \"cppnocase\", cppWordLists);\n"
  },
  {
    "path": "lexers/LexCSS.cxx",
    "content": "// Scintilla source code edit control\n// Encoding: UTF-8\n/** @file LexCSS.cxx\n ** Lexer for Cascading Style Sheets\n ** Written by Jakub Vrána\n ** Improved by Philippe Lhoste (CSS2)\n ** Improved by Ross McKay (SCSS mode; see http://sass-lang.com/ )\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// TODO: handle SCSS nested properties like font: { weight: bold; size: 1em; }\n// TODO: handle SCSS interpolation: #{}\n// TODO: add features for Less if somebody feels like contributing; http://lesscss.org/\n// TODO: refactor this monster so that the next poor slob can read it!\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\nstatic inline bool IsAWordChar(const unsigned int ch) {\n\t/* FIXME:\n\t * The CSS spec allows \"ISO 10646 characters U+00A1 and higher\" to be treated as word chars.\n\t * Unfortunately, we are only getting string bytes here, and not full unicode characters. We cannot guarantee\n\t * that our byte is between U+0080 - U+00A0 (to return false), so we have to allow all characters U+0080 and higher\n\t */\n\treturn ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';\n}\n\ninline bool IsCssOperator(const int ch) {\n\tif (!((ch < 0x80) && isalnum(ch)) &&\n\t\t(ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' ||\n\t\t ch == '.' || ch == '#' || ch == '!' || ch == '@' ||\n\t\t /* CSS2 */\n\t\t ch == '*' || ch == '>' || ch == '+' || ch == '=' || ch == '~' || ch == '|' ||\n\t\t ch == '[' || ch == ']' || ch == '(' || ch == ')')) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n// look behind (from start of document to our start position) to determine current nesting level\ninline int NestingLevelLookBehind(Sci_PositionU startPos, Accessor &styler) {\n\tint ch;\n\tint nestingLevel = 0;\n\n\tfor (Sci_PositionU i = 0; i < startPos; i++) {\n\t\tch = styler.SafeGetCharAt(i);\n\t\tif (ch == '{')\n\t\t\tnestingLevel++;\n\t\telse if (ch == '}')\n\t\t\tnestingLevel--;\n\t}\n\n\treturn nestingLevel;\n}\n\nstatic void ColouriseCssDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) {\n\tWordList &css1Props = *keywordlists[0];\n\tWordList &pseudoClasses = *keywordlists[1];\n\tWordList &css2Props = *keywordlists[2];\n\tWordList &css3Props = *keywordlists[3];\n\tWordList &pseudoElements = *keywordlists[4];\n\tWordList &exProps = *keywordlists[5];\n\tWordList &exPseudoClasses = *keywordlists[6];\n\tWordList &exPseudoElements = *keywordlists[7];\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tint lastState = -1; // before operator\n\tint lastStateC = -1; // before comment\n\tint lastStateS = -1; // before single-quoted/double-quoted string\n\tint lastStateVar = -1; // before variable (SCSS)\n\tint lastStateVal = -1; // before value (SCSS)\n\tint op = ' '; // last operator\n\tint opPrev = ' '; // last operator\n\tbool insideParentheses = false; // true if currently in a CSS url() or similar construct\n\n\t// property lexer.css.scss.language\n\t//\tSet to 1 for Sassy CSS (.scss)\n\tbool isScssDocument = styler.GetPropertyInt(\"lexer.css.scss.language\") != 0;\n\n\t// property lexer.css.less.language\n\t// Set to 1 for Less CSS (.less)\n\tbool isLessDocument = styler.GetPropertyInt(\"lexer.css.less.language\") != 0;\n\n\t// property lexer.css.hss.language\n\t// Set to 1 for HSS (.hss)\n\tbool isHssDocument = styler.GetPropertyInt(\"lexer.css.hss.language\") != 0;\n\n\t// SCSS/LESS/HSS have the concept of variable\n\tbool hasVariables = isScssDocument || isLessDocument || isHssDocument;\n\tchar varPrefix = 0;\n\tif (hasVariables)\n\t\tvarPrefix = isLessDocument ? '@' : '$';\n\n\t// SCSS/LESS/HSS support single-line comments\n\ttypedef enum _CommentModes { eCommentBlock = 0, eCommentLine = 1} CommentMode;\n\tCommentMode comment_mode = eCommentBlock;\n\tbool hasSingleLineComments = isScssDocument || isLessDocument || isHssDocument;\n\n\t// must keep track of nesting level in document types that support it (SCSS/LESS/HSS)\n\tbool hasNesting = false;\n\tint nestingLevel = 0;\n\tif (isScssDocument || isLessDocument || isHssDocument) {\n\t\thasNesting = true;\n\t\tnestingLevel = NestingLevelLookBehind(startPos, styler);\n\t}\n\n\t// \"the loop\"\n\tfor (; sc.More(); sc.Forward()) {\n\t\tif (sc.state == SCE_CSS_COMMENT && ((comment_mode == eCommentBlock && sc.Match('*', '/')) || (comment_mode == eCommentLine && sc.atLineEnd))) {\n\t\t\tif (lastStateC == -1) {\n\t\t\t\t// backtrack to get last state:\n\t\t\t\t// comments are like whitespace, so we must return to the previous state\n\t\t\t\tSci_PositionU i = startPos;\n\t\t\t\tfor (; i > 0; i--) {\n\t\t\t\t\tif ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) {\n\t\t\t\t\t\tif (lastStateC == SCE_CSS_OPERATOR) {\n\t\t\t\t\t\t\top = styler.SafeGetCharAt(i-1);\n\t\t\t\t\t\t\topPrev = styler.SafeGetCharAt(i-2);\n\t\t\t\t\t\t\twhile (--i) {\n\t\t\t\t\t\t\t\tlastState = styler.StyleAt(i-1);\n\t\t\t\t\t\t\t\tif (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (i == 0)\n\t\t\t\t\t\t\t\tlastState = SCE_CSS_DEFAULT;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (i == 0)\n\t\t\t\t\tlastStateC = SCE_CSS_DEFAULT;\n\t\t\t}\n\t\t\tif (comment_mode == eCommentBlock) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(lastStateC);\n\t\t\t} else /* eCommentLine */ {\n\t\t\t\tsc.SetState(lastStateC);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.state == SCE_CSS_COMMENT)\n\t\t\tcontinue;\n\n\t\tif (sc.state == SCE_CSS_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) {\n\t\t\tif (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\\\"' : '\\''))\n\t\t\t\tcontinue;\n\t\t\tSci_PositionU i = sc.currentPos;\n\t\t\twhile (i && styler[i-1] == '\\\\')\n\t\t\t\ti--;\n\t\t\tif ((sc.currentPos - i) % 2 == 1)\n\t\t\t\tcontinue;\n\t\t\tsc.ForwardSetState(lastStateS);\n\t\t}\n\n\t\tif (sc.state == SCE_CSS_OPERATOR) {\n\t\t\tif (op == ' ') {\n\t\t\t\tSci_PositionU i = startPos;\n\t\t\t\top = styler.SafeGetCharAt(i-1);\n\t\t\t\topPrev = styler.SafeGetCharAt(i-2);\n\t\t\t\twhile (--i) {\n\t\t\t\t\tlastState = styler.StyleAt(i-1);\n\t\t\t\t\tif (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch (op) {\n\t\t\tcase '@':\n\t\t\t\tif (lastState == SCE_CSS_DEFAULT || hasNesting)\n\t\t\t\t\tsc.SetState(SCE_CSS_DIRECTIVE);\n\t\t\t\tbreak;\n\t\t\tcase '>':\n\t\t\tcase '+':\n\t\t\t\tif (lastState == SCE_CSS_TAG || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||\n\t\t\t\t\tlastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)\n\t\t\t\t\tsc.SetState(SCE_CSS_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase '[':\n\t\t\t\tif (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||\n\t\t\t\t\tlastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)\n\t\t\t\t\tsc.SetState(SCE_CSS_ATTRIBUTE);\n\t\t\t\tbreak;\n\t\t\tcase ']':\n\t\t\t\tif (lastState == SCE_CSS_ATTRIBUTE)\n\t\t\t\t\tsc.SetState(SCE_CSS_TAG);\n\t\t\t\tbreak;\n\t\t\tcase '{':\n\t\t\t\tnestingLevel++;\n\t\t\t\tswitch (lastState) {\n\t\t\t\tcase SCE_CSS_GROUP_RULE:\n\t\t\t\t\tsc.SetState(SCE_CSS_DEFAULT);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SCE_CSS_TAG:\n\t\t\t\tcase SCE_CSS_DIRECTIVE:\n\t\t\t\t\tsc.SetState(SCE_CSS_IDENTIFIER);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '}':\n\t\t\t\tif (--nestingLevel < 0)\n\t\t\t\t\tnestingLevel = 0;\n\t\t\t\tswitch (lastState) {\n\t\t\t\tcase SCE_CSS_DEFAULT:\n\t\t\t\tcase SCE_CSS_VALUE:\n\t\t\t\tcase SCE_CSS_IMPORTANT:\n\t\t\t\tcase SCE_CSS_IDENTIFIER:\n\t\t\t\tcase SCE_CSS_IDENTIFIER2:\n\t\t\t\tcase SCE_CSS_IDENTIFIER3:\n\t\t\t\t\tif (hasNesting)\n\t\t\t\t\t\tsc.SetState(nestingLevel > 0 ? SCE_CSS_IDENTIFIER : SCE_CSS_DEFAULT);\n\t\t\t\t\telse\n\t\t\t\t\t\tsc.SetState(SCE_CSS_DEFAULT);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '(':\n\t\t\t\tif (lastState == SCE_CSS_PSEUDOCLASS)\n\t\t\t\t\tsc.SetState(SCE_CSS_TAG);\n\t\t\t\telse if (lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)\n\t\t\t\t\tsc.SetState(SCE_CSS_EXTENDED_PSEUDOCLASS);\n\t\t\t\tbreak;\n\t\t\tcase ')':\n\t\t\t\tif (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||\n\t\t\t\t\tlastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS ||\n\t\t\t\t\tlastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT)\n\t\t\t\t\tsc.SetState(SCE_CSS_TAG);\n\t\t\t\tbreak;\n\t\t\tcase ':':\n\t\t\t\tswitch (lastState) {\n\t\t\t\tcase SCE_CSS_TAG:\n\t\t\t\tcase SCE_CSS_DEFAULT:\n\t\t\t\tcase SCE_CSS_CLASS:\n\t\t\t\tcase SCE_CSS_ID:\n\t\t\t\tcase SCE_CSS_PSEUDOCLASS:\n\t\t\t\tcase SCE_CSS_EXTENDED_PSEUDOCLASS:\n\t\t\t\tcase SCE_CSS_UNKNOWN_PSEUDOCLASS:\n\t\t\t\tcase SCE_CSS_PSEUDOELEMENT:\n\t\t\t\tcase SCE_CSS_EXTENDED_PSEUDOELEMENT:\n\t\t\t\t\tsc.SetState(SCE_CSS_PSEUDOCLASS);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SCE_CSS_IDENTIFIER:\n\t\t\t\tcase SCE_CSS_IDENTIFIER2:\n\t\t\t\tcase SCE_CSS_IDENTIFIER3:\n\t\t\t\tcase SCE_CSS_EXTENDED_IDENTIFIER:\n\t\t\t\tcase SCE_CSS_UNKNOWN_IDENTIFIER:\n\t\t\t\tcase SCE_CSS_VARIABLE:\n\t\t\t\t\tsc.SetState(SCE_CSS_VALUE);\n\t\t\t\t\tlastStateVal = lastState;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '.':\n\t\t\t\tif (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||\n\t\t\t\t\tlastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)\n\t\t\t\t\tsc.SetState(SCE_CSS_CLASS);\n\t\t\t\tbreak;\n\t\t\tcase '#':\n\t\t\t\tif (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||\n\t\t\t\t\tlastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)\n\t\t\t\t\tsc.SetState(SCE_CSS_ID);\n\t\t\t\tbreak;\n\t\t\tcase ',':\n\t\t\tcase '|':\n\t\t\tcase '~':\n\t\t\t\tif (lastState == SCE_CSS_TAG)\n\t\t\t\t\tsc.SetState(SCE_CSS_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase ';':\n\t\t\t\tswitch (lastState) {\n\t\t\t\tcase SCE_CSS_DIRECTIVE:\n\t\t\t\t\tif (hasNesting) {\n\t\t\t\t\t\tsc.SetState(nestingLevel > 0 ? SCE_CSS_IDENTIFIER : SCE_CSS_DEFAULT);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_CSS_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase SCE_CSS_VALUE:\n\t\t\t\tcase SCE_CSS_IMPORTANT:\n\t\t\t\t\t// data URLs can have semicolons; simplistically check for wrapping parentheses and move along\n\t\t\t\t\tif (insideParentheses) {\n\t\t\t\t\t\tsc.SetState(lastState);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (lastStateVal == SCE_CSS_VARIABLE) {\n\t\t\t\t\t\t\tsc.SetState(SCE_CSS_DEFAULT);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState(SCE_CSS_IDENTIFIER);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase SCE_CSS_VARIABLE:\n\t\t\t\t\tif (lastStateVar == SCE_CSS_VALUE) {\n\t\t\t\t\t\t// data URLs can have semicolons; simplistically check for wrapping parentheses and move along\n\t\t\t\t\t\tif (insideParentheses) {\n\t\t\t\t\t\t\tsc.SetState(SCE_CSS_VALUE);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState(SCE_CSS_IDENTIFIER);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_CSS_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '!':\n\t\t\t\tif (lastState == SCE_CSS_VALUE)\n\t\t\t\t\tsc.SetState(SCE_CSS_IMPORTANT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (sc.ch == '*' && sc.state == SCE_CSS_DEFAULT) {\n\t\t\tsc.SetState(SCE_CSS_TAG);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// check for inside parentheses (whether part of an \"operator\" or not)\n\t\tif (sc.ch == '(')\n\t\t\tinsideParentheses = true;\n\t\telse if (sc.ch == ')')\n\t\t\tinsideParentheses = false;\n\n\t\t// SCSS special modes\n\t\tif (hasVariables) {\n\t\t\t// variable name\n\t\t\tif (sc.ch == varPrefix) {\n\t\t\t\tswitch (sc.state) {\n\t\t\t\tcase SCE_CSS_DEFAULT:\n\t\t\t\t\tif (isLessDocument) // give priority to pseudo elements\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t// Falls through.\n\t\t\t\tcase SCE_CSS_VALUE:\n\t\t\t\t\tlastStateVar = sc.state;\n\t\t\t\t\tsc.SetState(SCE_CSS_VARIABLE);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (sc.state == SCE_CSS_VARIABLE) {\n\t\t\t\tif (IsAWordChar(sc.ch)) {\n\t\t\t\t\t// still looking at the variable name\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (lastStateVar == SCE_CSS_VALUE) {\n\t\t\t\t\t// not looking at the variable name any more, and it was part of a value\n\t\t\t\t\tsc.SetState(SCE_CSS_VALUE);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// nested rule parent selector\n\t\t\tif (sc.ch == '&') {\n\t\t\t\tswitch (sc.state) {\n\t\t\t\tcase SCE_CSS_DEFAULT:\n\t\t\t\tcase SCE_CSS_IDENTIFIER:\n\t\t\t\t\tsc.SetState(SCE_CSS_TAG);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// nesting rules that apply to SCSS and Less\n\t\tif (hasNesting) {\n\t\t\t// check for nested rule selector\n\t\t\tif (sc.state == SCE_CSS_IDENTIFIER && (IsAWordChar(sc.ch) || sc.ch == ':' || sc.ch == '.' || sc.ch == '#')) {\n\t\t\t\t// look ahead to see whether { comes before next ; and }\n\t\t\t\tSci_PositionU endPos = startPos + length;\n\t\t\t\tint ch;\n\n\t\t\t\tfor (Sci_PositionU i = sc.currentPos; i < endPos; i++) {\n\t\t\t\t\tch = styler.SafeGetCharAt(i);\n\t\t\t\t\tif (ch == ';' || ch == '}')\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (ch == '{') {\n\t\t\t\t\t\tsc.SetState(SCE_CSS_DEFAULT);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif (IsAWordChar(sc.ch)) {\n\t\t\tif (sc.state == SCE_CSS_DEFAULT)\n\t\t\t\tsc.SetState(SCE_CSS_TAG);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (IsAWordChar(sc.chPrev) && (\n\t\t\tsc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_IDENTIFIER2 ||\n\t\t\tsc.state == SCE_CSS_IDENTIFIER3 || sc.state == SCE_CSS_EXTENDED_IDENTIFIER ||\n\t\t\tsc.state == SCE_CSS_UNKNOWN_IDENTIFIER ||\n\t\t\tsc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||\n\t\t\tsc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||\n\t\t\tsc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS ||\n\t\t\tsc.state == SCE_CSS_IMPORTANT ||\n\t\t\tsc.state == SCE_CSS_DIRECTIVE\n\t\t)) {\n\t\t\tchar s[100];\n\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\tchar *s2 = s;\n\t\t\twhile (*s2 && !IsAWordChar(*s2))\n\t\t\t\ts2++;\n\t\t\tswitch (sc.state) {\n\t\t\tcase SCE_CSS_IDENTIFIER:\n\t\t\tcase SCE_CSS_IDENTIFIER2:\n\t\t\tcase SCE_CSS_IDENTIFIER3:\n\t\t\tcase SCE_CSS_EXTENDED_IDENTIFIER:\n\t\t\tcase SCE_CSS_UNKNOWN_IDENTIFIER:\n\t\t\t\tif (css1Props.InList(s2))\n\t\t\t\t\tsc.ChangeState(SCE_CSS_IDENTIFIER);\n\t\t\t\telse if (css2Props.InList(s2))\n\t\t\t\t\tsc.ChangeState(SCE_CSS_IDENTIFIER2);\n\t\t\t\telse if (css3Props.InList(s2))\n\t\t\t\t\tsc.ChangeState(SCE_CSS_IDENTIFIER3);\n\t\t\t\telse if (exProps.InList(s2))\n\t\t\t\t\tsc.ChangeState(SCE_CSS_EXTENDED_IDENTIFIER);\n\t\t\t\telse\n\t\t\t\t\tsc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER);\n\t\t\t\tbreak;\n\t\t\tcase SCE_CSS_PSEUDOCLASS:\n\t\t\tcase SCE_CSS_PSEUDOELEMENT:\n\t\t\tcase SCE_CSS_EXTENDED_PSEUDOCLASS:\n\t\t\tcase SCE_CSS_EXTENDED_PSEUDOELEMENT:\n\t\t\tcase SCE_CSS_UNKNOWN_PSEUDOCLASS:\n\t\t\t\tif (op == ':' && opPrev != ':' && pseudoClasses.InList(s2))\n\t\t\t\t\tsc.ChangeState(SCE_CSS_PSEUDOCLASS);\n\t\t\t\telse if (opPrev == ':' && pseudoElements.InList(s2))\n\t\t\t\t\tsc.ChangeState(SCE_CSS_PSEUDOELEMENT);\n\t\t\t\telse if ((op == ':' || (op == '(' && lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)) && opPrev != ':' && exPseudoClasses.InList(s2))\n\t\t\t\t\tsc.ChangeState(SCE_CSS_EXTENDED_PSEUDOCLASS);\n\t\t\t\telse if (opPrev == ':' && exPseudoElements.InList(s2))\n\t\t\t\t\tsc.ChangeState(SCE_CSS_EXTENDED_PSEUDOELEMENT);\n\t\t\t\telse\n\t\t\t\t\tsc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS);\n\t\t\t\tbreak;\n\t\t\tcase SCE_CSS_IMPORTANT:\n\t\t\t\tif (strcmp(s2, \"important\") != 0)\n\t\t\t\t\tsc.ChangeState(SCE_CSS_VALUE);\n\t\t\t\tbreak;\n\t\t\tcase SCE_CSS_DIRECTIVE:\n\t\t\t\tif (op == '@' && (strcmp(s2, \"media\") == 0 || strcmp(s2, \"supports\") == 0 || strcmp(s2, \"document\") == 0 || strcmp(s2, \"-moz-document\") == 0))\n\t\t\t\t\tsc.ChangeState(SCE_CSS_GROUP_RULE);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && (\n\t\t\tsc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_ID ||\n\t\t\t(sc.ch != '(' && sc.ch != ')' && ( /* This line of the condition makes it possible to extend pseudo-classes with parentheses */\n\t\t\t\tsc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||\n\t\t\t\tsc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||\n\t\t\t\tsc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS\n\t\t\t))\n\t\t))\n\t\t\tsc.SetState(SCE_CSS_TAG);\n\n\t\tif (sc.Match('/', '*')) {\n\t\t\tlastStateC = sc.state;\n\t\t\tcomment_mode = eCommentBlock;\n\t\t\tsc.SetState(SCE_CSS_COMMENT);\n\t\t\tsc.Forward();\n\t\t} else if (hasSingleLineComments && sc.Match('/', '/') && !insideParentheses) {\n\t\t\t// note that we've had to treat ([...]// as the start of a URL not a comment, e.g. url(http://example.com), url(//example.com)\n\t\t\tlastStateC = sc.state;\n\t\t\tcomment_mode = eCommentLine;\n\t\t\tsc.SetState(SCE_CSS_COMMENT);\n\t\t\tsc.Forward();\n\t\t} else if ((sc.state == SCE_CSS_VALUE || sc.state == SCE_CSS_ATTRIBUTE)\n\t\t\t&& (sc.ch == '\\\"' || sc.ch == '\\'')) {\n\t\t\tlastStateS = sc.state;\n\t\t\tsc.SetState((sc.ch == '\\\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));\n\t\t} else if (IsCssOperator(sc.ch)\n\t\t\t&& (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')\n\t\t\t&& (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')\n\t\t\t&& ((sc.state != SCE_CSS_DIRECTIVE && sc.state != SCE_CSS_GROUP_RULE) || sc.ch == ';' || sc.ch == '{')\n\t\t) {\n\t\t\tif (sc.state != SCE_CSS_OPERATOR)\n\t\t\t\tlastState = sc.state;\n\t\t\tsc.SetState(SCE_CSS_OPERATOR);\n\t\t\top = sc.ch;\n\t\t\topPrev = sc.chPrev;\n\t\t}\n\t}\n\n\tsc.Complete();\n}\n\nstatic void FoldCSSDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tbool inComment = (styler.StyleAt(startPos-1) == SCE_CSS_COMMENT);\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styler.StyleAt(i);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (foldComment) {\n\t\t\tif (!inComment && (style == SCE_CSS_COMMENT))\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (inComment && (style != SCE_CSS_COMMENT))\n\t\t\t\tlevelCurrent--;\n\t\t\tinComment = (style == SCE_CSS_COMMENT);\n\t\t}\n\t\tif (style == SCE_CSS_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const cssWordListDesc[] = {\n\t\"CSS1 Properties\",\n\t\"Pseudo-classes\",\n\t\"CSS2 Properties\",\n\t\"CSS3 Properties\",\n\t\"Pseudo-elements\",\n\t\"Browser-Specific CSS Properties\",\n\t\"Browser-Specific Pseudo-classes\",\n\t\"Browser-Specific Pseudo-elements\",\n\t0\n};\n\nextern const LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, \"css\", FoldCSSDoc, cssWordListDesc);\n"
  },
  {
    "path": "lexers/LexCaml.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexCaml.cxx\n ** Lexer for Objective Caml.\n **/\n// Copyright 2005-2009 by Robert Roessler <robertr@rftp.com>\n// The License.txt file describes the conditions under which this software may be distributed.\n/*\tRelease History\n\t20050204 Initial release.\n\t20050205 Quick compiler standards/\"cleanliness\" adjustment.\n\t20050206 Added cast for IsLeadByte().\n\t20050209 Changes to \"external\" build support.\n\t20050306 Fix for 1st-char-in-doc \"corner\" case.\n\t20050502 Fix for [harmless] one-past-the-end coloring.\n\t20050515 Refined numeric token recognition logic.\n\t20051125 Added 2nd \"optional\" keywords class.\n\t20051129 Support \"magic\" (read-only) comments for RCaml.\n\t20051204 Swtich to using StyleContext infrastructure.\n\t20090629 Add full Standard ML '97 support.\n*/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\n#if defined(__clang__)\n#pragma clang diagnostic ignored \"-Wcomma\"\n#endif\n\n//\tSince the Microsoft __iscsym[f] funcs are not ANSI...\ninline int  iscaml(int c) {return isalnum(c) || c == '_';}\ninline int iscamlf(int c) {return isalpha(c) || c == '_';}\n\nstatic const int baseT[24] = {\n\t0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\t/* A - L */\n\t0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16\t/* M - X */\n};\n\nusing namespace Lexilla;\n\nstatic void ColouriseCamlDoc(\n\tSci_PositionU startPos, Sci_Position length,\n\tint initStyle,\n\tWordList *keywordlists[],\n\tAccessor &styler)\n{\n\t// initialize styler\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tSci_PositionU chToken = 0;\n\tint chBase = 0, chLit = 0;\n\tWordList& keywords  = *keywordlists[0];\n\tWordList& keywords2 = *keywordlists[1];\n\tWordList& keywords3 = *keywordlists[2];\n\tconst bool isSML = keywords.InList(\"andalso\");\n\tconst int useMagic = styler.GetPropertyInt(\"lexer.caml.magic\", 0);\n\n\t// set up [initial] state info (terminating states that shouldn't \"bleed\")\n\tconst int state_ = sc.state & 0x0f;\n\tif (state_ <= SCE_CAML_CHAR\n\t\t|| (isSML && state_ == SCE_CAML_STRING))\n\t\tsc.state = SCE_CAML_DEFAULT;\n\tint nesting = (state_ >= SCE_CAML_COMMENT)? (state_ - SCE_CAML_COMMENT): 0;\n\n\t// foreach char in range...\n\twhile (sc.More()) {\n\t\t// set up [per-char] state info\n\t\tint state2 = -1;\t\t\t\t// (ASSUME no state change)\n\t\tSci_Position chColor = sc.currentPos - 1;// (ASSUME standard coloring range)\n\t\tbool advance = true;\t\t\t// (ASSUME scanner \"eats\" 1 char)\n\n\t\t// step state machine\n\t\tswitch (sc.state & 0x0f) {\n\t\tcase SCE_CAML_DEFAULT:\n\t\t\tchToken = sc.currentPos;\t// save [possible] token start (JIC)\n\t\t\t// it's wide open; what do we have?\n\t\t\tif (iscamlf(sc.ch))\n\t\t\t\tstate2 = SCE_CAML_IDENTIFIER;\n\t\t\telse if (!isSML && sc.Match('`') && iscamlf(sc.chNext))\n\t\t\t\tstate2 = SCE_CAML_TAGNAME;\n\t\t\telse if (!isSML && sc.Match('#') && isdigit(sc.chNext))\n\t\t\t\tstate2 = SCE_CAML_LINENUM;\n\t\t\telse if (isdigit(sc.ch)) {\n\t\t\t\t// it's a number, assume base 10\n\t\t\t\tstate2 = SCE_CAML_NUMBER, chBase = 10;\n\t\t\t\tif (sc.Match('0')) {\n\t\t\t\t\t// there MAY be a base specified...\n\t\t\t\t\tconst char* baseC = \"bBoOxX\";\n\t\t\t\t\tif (isSML) {\n\t\t\t\t\t\tif (sc.chNext == 'w')\n\t\t\t\t\t\t\tsc.Forward();\t// (consume SML \"word\" indicator)\n\t\t\t\t\t\tbaseC = \"x\";\n\t\t\t\t\t}\n\t\t\t\t\t// ... change to specified base AS REQUIRED\n\t\t\t\t\tif (strchr(baseC, sc.chNext))\n\t\t\t\t\t\tchBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward();\n\t\t\t\t}\n\t\t\t} else if (!isSML && sc.Match('\\''))\t// (Caml char literal?)\n\t\t\t\tstate2 = SCE_CAML_CHAR, chLit = 0;\n\t\t\telse if (isSML && sc.Match('#', '\"'))\t// (SML char literal?)\n\t\t\t\tstate2 = SCE_CAML_CHAR, sc.Forward();\n\t\t\telse if (sc.Match('\"'))\n\t\t\t\tstate2 = SCE_CAML_STRING;\n\t\t\telse if (sc.Match('(', '*'))\n\t\t\t\tstate2 = SCE_CAML_COMMENT, sc.Forward(), sc.ch = ' '; // (*)...\n\t\t\telse if (strchr(\"!?~\"\t\t\t/* Caml \"prefix-symbol\" */\n\t\t\t\t\t\"=<>@^|&+-*/$%\"\t\t\t/* Caml \"infix-symbol\" */\n\t\t\t\t\t\"()[]{};,:.#\", sc.ch)\t// Caml \"bracket\" or ;,:.#\n\t\t\t\t\t\t\t\t\t\t\t// SML \"extra\" ident chars\n\t\t\t\t|| (isSML && (sc.Match('\\\\') || sc.Match('`'))))\n\t\t\t\tstate2 = SCE_CAML_OPERATOR;\n\t\t\tbreak;\n\n\t\tcase SCE_CAML_IDENTIFIER:\n\t\t\t// [try to] interpret as [additional] identifier char\n\t\t\tif (!(iscaml(sc.ch) || sc.Match('\\''))) {\n\t\t\t\tconst Sci_Position n = sc.currentPos - chToken;\n\t\t\t\tif (n < 24) {\n\t\t\t\t\t// length is believable as keyword, [re-]construct token\n\t\t\t\t\tchar t[24];\n\t\t\t\t\tfor (Sci_Position i = -n; i < 0; i++)\n\t\t\t\t\t\tt[n + i] = static_cast<char>(sc.GetRelative(i));\n\t\t\t\t\tt[n] = '\\0';\n\t\t\t\t\t// special-case \"_\" token as KEYWORD\n\t\t\t\t\tif ((n == 1 && sc.chPrev == '_') || keywords.InList(t))\n\t\t\t\t\t\tsc.ChangeState(SCE_CAML_KEYWORD);\n\t\t\t\t\telse if (keywords2.InList(t))\n\t\t\t\t\t\tsc.ChangeState(SCE_CAML_KEYWORD2);\n\t\t\t\t\telse if (keywords3.InList(t))\n\t\t\t\t\t\tsc.ChangeState(SCE_CAML_KEYWORD3);\n\t\t\t\t}\n\t\t\t\tstate2 = SCE_CAML_DEFAULT, advance = false;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_CAML_TAGNAME:\n\t\t\t// [try to] interpret as [additional] tagname char\n\t\t\tif (!(iscaml(sc.ch) || sc.Match('\\'')))\n\t\t\t\tstate2 = SCE_CAML_DEFAULT, advance = false;\n\t\t\tbreak;\n\n\t\t/*case SCE_CAML_KEYWORD:\n\t\tcase SCE_CAML_KEYWORD2:\n\t\tcase SCE_CAML_KEYWORD3:\n\t\t\t// [try to] interpret as [additional] keyword char\n\t\t\tif (!iscaml(ch))\n\t\t\t\tstate2 = SCE_CAML_DEFAULT, advance = false;\n\t\t\tbreak;*/\n\n\t\tcase SCE_CAML_LINENUM:\n\t\t\t// [try to] interpret as [additional] linenum directive char\n\t\t\tif (!isdigit(sc.ch))\n\t\t\t\tstate2 = SCE_CAML_DEFAULT, advance = false;\n\t\t\tbreak;\n\n\t\tcase SCE_CAML_OPERATOR: {\n\t\t\t// [try to] interpret as [additional] operator char\n\t\t\tconst char* o = 0;\n\t\t\tif (iscaml(sc.ch) || isspace(sc.ch)\t\t\t// ident or whitespace\n\t\t\t\t|| (o = strchr(\")]};,\\'\\\"#\", sc.ch),o)\t// \"termination\" chars\n\t\t\t\t|| (!isSML && sc.Match('`'))\t\t\t// Caml extra term char\n\t\t\t\t|| (!strchr(\"!$%&*+-./:<=>?@^|~\", sc.ch)// \"operator\" chars\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// SML extra ident chars\n\t\t\t\t\t&& !(isSML && (sc.Match('\\\\') || sc.Match('`'))))) {\n\t\t\t\t// check for INCLUSIVE termination\n\t\t\t\tif (o && strchr(\")]};,\", sc.ch)) {\n\t\t\t\t\tif ((sc.Match(')') && sc.chPrev == '(')\n\t\t\t\t\t\t|| (sc.Match(']') && sc.chPrev == '['))\n\t\t\t\t\t\t// special-case \"()\" and \"[]\" tokens as KEYWORDS\n\t\t\t\t\t\tsc.ChangeState(SCE_CAML_KEYWORD);\n\t\t\t\t\tchColor++;\n\t\t\t\t} else\n\t\t\t\t\tadvance = false;\n\t\t\t\tstate2 = SCE_CAML_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase SCE_CAML_NUMBER:\n\t\t\t// [try to] interpret as [additional] numeric literal char\n\t\t\tif ((!isSML && sc.Match('_')) || IsADigit(sc.ch, chBase))\n\t\t\t\tbreak;\n\t\t\t// how about an integer suffix?\n\t\t\tif (!isSML && (sc.Match('l') || sc.Match('L') || sc.Match('n'))\n\t\t\t\t&& (sc.chPrev == '_' || IsADigit(sc.chPrev, chBase)))\n\t\t\t\tbreak;\n\t\t\t// or a floating-point literal?\n\t\t\tif (chBase == 10) {\n\t\t\t\t// with a decimal point?\n\t\t\t\tif (sc.Match('.')\n\t\t\t\t\t&& ((!isSML && sc.chPrev == '_')\n\t\t\t\t\t\t|| IsADigit(sc.chPrev, chBase)))\n\t\t\t\t\tbreak;\n\t\t\t\t// with an exponent? (I)\n\t\t\t\tif ((sc.Match('e') || sc.Match('E'))\n\t\t\t\t\t&& ((!isSML && (sc.chPrev == '.' || sc.chPrev == '_'))\n\t\t\t\t\t\t|| IsADigit(sc.chPrev, chBase)))\n\t\t\t\t\tbreak;\n\t\t\t\t// with an exponent? (II)\n\t\t\t\tif (((!isSML && (sc.Match('+') || sc.Match('-')))\n\t\t\t\t\t\t|| (isSML && sc.Match('~')))\n\t\t\t\t\t&& (sc.chPrev == 'e' || sc.chPrev == 'E'))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// it looks like we have run out of number\n\t\t\tstate2 = SCE_CAML_DEFAULT, advance = false;\n\t\t\tbreak;\n\n\t\tcase SCE_CAML_CHAR:\n\t\t\tif (!isSML) {\n\t\t\t\t// [try to] interpret as [additional] char literal char\n\t\t\t\tif (sc.Match('\\\\')) {\n\t\t\t\t\tchLit = 1;\t// (definitely IS a char literal)\n\t\t\t\t\tif (sc.chPrev == '\\\\')\n\t\t\t\t\t\tsc.ch = ' ';\t// (...\\\\')\n\t\t\t\t// should we be terminating - one way or another?\n\t\t\t\t} else if ((sc.Match('\\'') && sc.chPrev != '\\\\')\n\t\t\t\t\t|| sc.atLineEnd) {\n\t\t\t\t\tstate2 = SCE_CAML_DEFAULT;\n\t\t\t\t\tif (sc.Match('\\''))\n\t\t\t\t\t\tchColor++;\n\t\t\t\t\telse\n\t\t\t\t\t\tsc.ChangeState(SCE_CAML_IDENTIFIER);\n\t\t\t\t// ... maybe a char literal, maybe not\n\t\t\t\t} else if (chLit < 1 && sc.currentPos - chToken >= 2)\n\t\t\t\t\tsc.ChangeState(SCE_CAML_IDENTIFIER), advance = false;\n\t\t\t\tbreak;\n\t\t\t}/* else\n\t\t\t\t// fall through for SML char literal (handle like string) */\n\t\t\t// Falls through.\n\n\t\tcase SCE_CAML_STRING:\n\t\t\t// [try to] interpret as [additional] [SML char/] string literal char\n\t\t\tif (isSML && sc.Match('\\\\') && sc.chPrev != '\\\\' && isspace(sc.chNext))\n\t\t\t\tstate2 = SCE_CAML_WHITE;\n\t\t\telse if (sc.Match('\\\\') && sc.chPrev == '\\\\')\n\t\t\t\tsc.ch = ' ';\t// (...\\\\\")\n\t\t\t// should we be terminating - one way or another?\n\t\t\telse if ((sc.Match('\"') && sc.chPrev != '\\\\')\n\t\t\t\t|| (isSML && sc.atLineEnd)) {\n\t\t\t\tstate2 = SCE_CAML_DEFAULT;\n\t\t\t\tif (sc.Match('\"'))\n\t\t\t\t\tchColor++;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_CAML_WHITE:\n\t\t\t// [try to] interpret as [additional] SML embedded whitespace char\n\t\t\tif (sc.Match('\\\\')) {\n\t\t\t\t// style this puppy NOW...\n\t\t\t\tstate2 = SCE_CAML_STRING, sc.ch = ' ' /* (...\\\") */, chColor++,\n\t\t\t\t\tstyler.ColourTo(chColor, SCE_CAML_WHITE), styler.Flush();\n\t\t\t\t// ... then backtrack to determine original SML literal type\n\t\t\t\tSci_Position p = chColor - 2;\n\t\t\t\tfor (; p >= 0 && styler.StyleAt(p) == SCE_CAML_WHITE; p--) ;\n\t\t\t\tif (p >= 0)\n\t\t\t\t\tstate2 = static_cast<int>(styler.StyleAt(p));\n\t\t\t\t// take care of state change NOW\n\t\t\t\tsc.ChangeState(state2), state2 = -1;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_CAML_COMMENT:\n\t\tcase SCE_CAML_COMMENT1:\n\t\tcase SCE_CAML_COMMENT2:\n\t\tcase SCE_CAML_COMMENT3:\n\t\t\t// we're IN a comment - does this start a NESTED comment?\n\t\t\tif (sc.Match('(', '*'))\n\t\t\t\tstate2 = sc.state + 1, chToken = sc.currentPos,\n\t\t\t\t\tsc.Forward(), sc.ch = ' ' /* (*)... */, nesting++;\n\t\t\t// [try to] interpret as [additional] comment char\n\t\t\telse if (sc.Match(')') && sc.chPrev == '*') {\n\t\t\t\tif (nesting)\n\t\t\t\t\tstate2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;\n\t\t\t\telse\n\t\t\t\t\tstate2 = SCE_CAML_DEFAULT;\n\t\t\t\tchColor++;\n\t\t\t// enable \"magic\" (read-only) comment AS REQUIRED\n\t\t\t} else if (useMagic && sc.currentPos - chToken == 4\n\t\t\t\t&& sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')\n\t\t\t\tsc.state |= 0x10;\t// (switch to read-only comment style)\n\t\t\tbreak;\n\t\t}\n\n\t\t// handle state change and char coloring AS REQUIRED\n\t\tif (state2 >= 0)\n\t\t\tstyler.ColourTo(chColor, sc.state), sc.ChangeState(state2);\n\t\t// move to next char UNLESS re-scanning current char\n\t\tif (advance)\n\t\t\tsc.Forward();\n\t}\n\n\t// do any required terminal char coloring (JIC)\n\tsc.Complete();\n}\n\nstatic\nvoid FoldCamlDoc(\n\tSci_PositionU, Sci_Position,\n\tint,\n\tWordList *[],\n\tAccessor &)\n{\n}\n\nstatic const char * const camlWordListDesc[] = {\n\t\"Keywords\",\t\t// primary Objective Caml keywords\n\t\"Keywords2\",\t// \"optional\" keywords (typically from Pervasives)\n\t\"Keywords3\",\t// \"optional\" keywords (typically typenames)\n\t0\n};\n\nextern const LexerModule lmCaml(SCLEX_CAML, ColouriseCamlDoc, \"caml\", FoldCamlDoc, camlWordListDesc);\n"
  },
  {
    "path": "lexers/LexCmake.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexCmake.cxx\n ** Lexer for Cmake\n **/\n// Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net>\n// based on the NSIS lexer\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic bool isCmakeNumber(char ch)\n{\n    return(ch >= '0' && ch <= '9');\n}\n\nstatic bool isCmakeChar(char ch)\n{\n    return(ch == '.' ) || (ch == '_' ) || isCmakeNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');\n}\n\nstatic bool isCmakeLetter(char ch)\n{\n    return(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');\n}\n\nstatic bool CmakeNextLineHasElse(Sci_PositionU start, Sci_PositionU end, Accessor &styler)\n{\n    Sci_Position nNextLine = -1;\n    for ( Sci_PositionU i = start; i < end; i++ ) {\n        char cNext = styler.SafeGetCharAt( i );\n        if ( cNext == '\\n' ) {\n            nNextLine = i+1;\n            break;\n        }\n    }\n\n    if ( nNextLine == -1 ) // We never foudn the next line...\n        return false;\n\n    for ( Sci_PositionU firstChar = nNextLine; firstChar < end; firstChar++ ) {\n        char cNext = styler.SafeGetCharAt( firstChar );\n        if ( cNext == ' ' )\n            continue;\n        if ( cNext == '\\t' )\n            continue;\n        if ( styler.Match(firstChar, \"ELSE\")  || styler.Match(firstChar, \"else\"))\n            return true;\n        break;\n    }\n\n    return false;\n}\n\nstatic int calculateFoldCmake(Sci_PositionU start, Sci_PositionU end, int foldlevel, Accessor &styler, bool bElse)\n{\n    // If the word is too long, it is not what we are looking for\n    if ( end - start > 20 )\n        return foldlevel;\n\n    int newFoldlevel = foldlevel;\n\n    char s[20]; // The key word we are looking for has atmost 13 characters\n    for (unsigned int i = 0; i < end - start + 1 && i < 19; i++) {\n        s[i] = static_cast<char>( styler[ start + i ] );\n        s[i + 1] = '\\0';\n    }\n\n    if ( CompareCaseInsensitive(s, \"IF\") == 0 || CompareCaseInsensitive(s, \"WHILE\") == 0\n         || CompareCaseInsensitive(s, \"MACRO\") == 0 || CompareCaseInsensitive(s, \"FOREACH\") == 0\n         || CompareCaseInsensitive(s, \"FUNCTION\") == 0)\n        newFoldlevel++;\n    else if ( CompareCaseInsensitive(s, \"ENDIF\") == 0 || CompareCaseInsensitive(s, \"ENDWHILE\") == 0\n              || CompareCaseInsensitive(s, \"ENDMACRO\") == 0 || CompareCaseInsensitive(s, \"ENDFOREACH\") == 0\n              || CompareCaseInsensitive(s, \"ENDFUNCTION\") == 0)\n        newFoldlevel--;\n    else if ( bElse && CompareCaseInsensitive(s, \"ELSEIF\") == 0 )\n        newFoldlevel++;\n    else if ( bElse && CompareCaseInsensitive(s, \"ELSE\") == 0 )\n        newFoldlevel++;\n\n    return newFoldlevel;\n}\n\nstatic int classifyWordCmake(Sci_PositionU start, Sci_PositionU end, WordList *keywordLists[], Accessor &styler )\n{\n    char word[100] = {0};\n    char lowercaseWord[100] = {0};\n\n    WordList &Commands = *keywordLists[0];\n    WordList &Parameters = *keywordLists[1];\n    WordList &UserDefined = *keywordLists[2];\n\n    for (Sci_PositionU i = 0; i < end - start + 1 && i < 99; i++) {\n        word[i] = static_cast<char>( styler[ start + i ] );\n        lowercaseWord[i] = static_cast<char>(tolower(word[i]));\n    }\n\n    // Check for special words...\n    if ( CompareCaseInsensitive(word, \"MACRO\") == 0 || CompareCaseInsensitive(word, \"ENDMACRO\") == 0 )\n        return SCE_CMAKE_MACRODEF;\n\n    if ( CompareCaseInsensitive(word, \"IF\") == 0 ||  CompareCaseInsensitive(word, \"ENDIF\") == 0 )\n        return SCE_CMAKE_IFDEFINEDEF;\n\n    if ( CompareCaseInsensitive(word, \"ELSEIF\") == 0  || CompareCaseInsensitive(word, \"ELSE\") == 0 )\n        return SCE_CMAKE_IFDEFINEDEF;\n\n    if ( CompareCaseInsensitive(word, \"WHILE\") == 0 || CompareCaseInsensitive(word, \"ENDWHILE\") == 0)\n        return SCE_CMAKE_WHILEDEF;\n\n    if ( CompareCaseInsensitive(word, \"FOREACH\") == 0 || CompareCaseInsensitive(word, \"ENDFOREACH\") == 0)\n        return SCE_CMAKE_FOREACHDEF;\n\n    if ( Commands.InList(lowercaseWord) )\n        return SCE_CMAKE_COMMANDS;\n\n    if ( Parameters.InList(word) )\n        return SCE_CMAKE_PARAMETERS;\n\n\n    if ( UserDefined.InList(word) )\n        return SCE_CMAKE_USERDEFINED;\n\n    if ( strlen(word) > 3 ) {\n        if ( word[1] == '{' && word[strlen(word)-1] == '}' )\n            return SCE_CMAKE_VARIABLE;\n    }\n\n    // To check for numbers\n    if ( isCmakeNumber( word[0] ) ) {\n        bool bHasSimpleCmakeNumber = true;\n        for (unsigned int j = 1; j < end - start + 1 && j < 99; j++) {\n            if ( !isCmakeNumber( word[j] ) ) {\n                bHasSimpleCmakeNumber = false;\n                break;\n            }\n        }\n\n        if ( bHasSimpleCmakeNumber )\n            return SCE_CMAKE_NUMBER;\n    }\n\n    return SCE_CMAKE_DEFAULT;\n}\n\nstatic void ColouriseCmakeDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler)\n{\n    int state = SCE_CMAKE_DEFAULT;\n    if ( startPos > 0 )\n        state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox\n\n    styler.StartAt( startPos );\n    styler.GetLine( startPos );\n\n    Sci_PositionU nLengthDoc = startPos + length;\n    styler.StartSegment( startPos );\n\n    char cCurrChar;\n    bool bVarInString = false;\n    bool bClassicVarInString = false;\n\n    Sci_PositionU i;\n    for ( i = startPos; i < nLengthDoc; i++ ) {\n        cCurrChar = styler.SafeGetCharAt( i );\n        char cNextChar = styler.SafeGetCharAt(i+1);\n\n        switch (state) {\n        case SCE_CMAKE_DEFAULT:\n            if ( cCurrChar == '#' ) { // we have a comment line\n                styler.ColourTo(i-1, state );\n                state = SCE_CMAKE_COMMENT;\n                break;\n            }\n            if ( cCurrChar == '\"' ) {\n                styler.ColourTo(i-1, state );\n                state = SCE_CMAKE_STRINGDQ;\n                bVarInString = false;\n                bClassicVarInString = false;\n                break;\n            }\n            if ( cCurrChar == '\\'' ) {\n                styler.ColourTo(i-1, state );\n                state = SCE_CMAKE_STRINGRQ;\n                bVarInString = false;\n                bClassicVarInString = false;\n                break;\n            }\n            if ( cCurrChar == '`' ) {\n                styler.ColourTo(i-1, state );\n                state = SCE_CMAKE_STRINGLQ;\n                bVarInString = false;\n                bClassicVarInString = false;\n                break;\n            }\n\n            // CMake Variable\n            if ( cCurrChar == '$' || isCmakeChar(cCurrChar)) {\n                styler.ColourTo(i-1,state);\n                state = SCE_CMAKE_VARIABLE;\n\n                // If it is a number, we must check and set style here first...\n                if ( isCmakeNumber(cCurrChar) && (cNextChar == '\\t' || cNextChar == ' ' || cNextChar == '\\r' || cNextChar == '\\n' ) )\n                    styler.ColourTo( i, SCE_CMAKE_NUMBER);\n\n                break;\n            }\n\n            break;\n        case SCE_CMAKE_COMMENT:\n            if ( cCurrChar == '\\n' || cCurrChar == '\\r' ) {\n                if ( styler.SafeGetCharAt(i-1) == '\\\\' ) {\n                    styler.ColourTo(i-2,state);\n                    styler.ColourTo(i-1,SCE_CMAKE_DEFAULT);\n                }\n                else {\n                    styler.ColourTo(i-1,state);\n                    state = SCE_CMAKE_DEFAULT;\n                }\n            }\n            break;\n        case SCE_CMAKE_STRINGDQ:\n        case SCE_CMAKE_STRINGLQ:\n        case SCE_CMAKE_STRINGRQ:\n\n            if ( styler.SafeGetCharAt(i-1) == '\\\\' && styler.SafeGetCharAt(i-2) == '$' )\n                break; // Ignore the next character, even if it is a quote of some sort\n\n            if ( cCurrChar == '\"' && state == SCE_CMAKE_STRINGDQ ) {\n                styler.ColourTo(i,state);\n                state = SCE_CMAKE_DEFAULT;\n                break;\n            }\n\n            if ( cCurrChar == '`' && state == SCE_CMAKE_STRINGLQ ) {\n                styler.ColourTo(i,state);\n                state = SCE_CMAKE_DEFAULT;\n                break;\n            }\n\n            if ( cCurrChar == '\\'' && state == SCE_CMAKE_STRINGRQ ) {\n                styler.ColourTo(i,state);\n                state = SCE_CMAKE_DEFAULT;\n                break;\n            }\n\n            if ( cNextChar == '\\r' || cNextChar == '\\n' ) {\n                Sci_Position nCurLine = styler.GetLine(i+1);\n                Sci_Position nBack = i;\n                // We need to check if the previous line has a \\ in it...\n                bool bNextLine = false;\n\n                while ( nBack > 0 ) {\n                    if ( styler.GetLine(nBack) != nCurLine )\n                        break;\n\n                    char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here\n\n                    if ( cTemp == '\\\\' ) {\n                        bNextLine = true;\n                        break;\n                    }\n                    if ( cTemp != '\\r' && cTemp != '\\n' && cTemp != '\\t' && cTemp != ' ' )\n                        break;\n\n                    nBack--;\n                }\n\n                if ( bNextLine ) {\n                    styler.ColourTo(i+1,state);\n                }\n                if ( bNextLine == false ) {\n                    styler.ColourTo(i,state);\n                    state = SCE_CMAKE_DEFAULT;\n                }\n            }\n            break;\n\n        case SCE_CMAKE_VARIABLE:\n\n            // CMake Variable:\n            if ( cCurrChar == '$' )\n                state = SCE_CMAKE_DEFAULT;\n            else if ( cCurrChar == '\\\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )\n                state = SCE_CMAKE_DEFAULT;\n            else if ( (isCmakeChar(cCurrChar) && !isCmakeChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' ) {\n                state = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler );\n                styler.ColourTo( i, state);\n                state = SCE_CMAKE_DEFAULT;\n            }\n            else if ( !isCmakeChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' ) {\n                if ( classifyWordCmake( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_CMAKE_NUMBER )\n                    styler.ColourTo( i-1, SCE_CMAKE_NUMBER );\n\n                state = SCE_CMAKE_DEFAULT;\n\n                if ( cCurrChar == '\"' ) {\n                    state = SCE_CMAKE_STRINGDQ;\n                    bVarInString = false;\n                    bClassicVarInString = false;\n                }\n                else if ( cCurrChar == '`' ) {\n                    state = SCE_CMAKE_STRINGLQ;\n                    bVarInString = false;\n                    bClassicVarInString = false;\n                }\n                else if ( cCurrChar == '\\'' ) {\n                    state = SCE_CMAKE_STRINGRQ;\n                    bVarInString = false;\n                    bClassicVarInString = false;\n                }\n                else if ( cCurrChar == '#' ) {\n                    state = SCE_CMAKE_COMMENT;\n                }\n            }\n            break;\n        }\n\n        if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) {\n            bool bIngoreNextDollarSign = false;\n\n            if ( bVarInString && cCurrChar == '$' ) {\n                bVarInString = false;\n                bIngoreNextDollarSign = true;\n            }\n            else if ( bVarInString && cCurrChar == '\\\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '\"' || cNextChar == '`' || cNextChar == '\\'' ) ) {\n                styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);\n                bVarInString = false;\n                bIngoreNextDollarSign = false;\n            }\n\n            else if ( bVarInString && !isCmakeChar(cNextChar) ) {\n                int nWordState = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler);\n                if ( nWordState == SCE_CMAKE_VARIABLE )\n                    styler.ColourTo( i, SCE_CMAKE_STRINGVAR);\n                bVarInString = false;\n            }\n            // Covers \"${TEST}...\"\n            else if ( bClassicVarInString && cNextChar == '}' ) {\n                styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);\n                bClassicVarInString = false;\n            }\n\n            // Start of var in string\n            if ( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' ) {\n                styler.ColourTo( i-1, state);\n                bClassicVarInString = true;\n                bVarInString = false;\n            }\n            else if ( !bIngoreNextDollarSign && cCurrChar == '$' ) {\n                styler.ColourTo( i-1, state);\n                bVarInString = true;\n                bClassicVarInString = false;\n            }\n        }\n    }\n\n    // Colourise remaining document\n    styler.ColourTo(nLengthDoc-1,state);\n}\n\nstatic void FoldCmakeDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)\n{\n    // No folding enabled, no reason to continue...\n    if ( styler.GetPropertyInt(\"fold\") == 0 )\n        return;\n\n    bool foldAtElse = styler.GetPropertyInt(\"fold.at.else\", 0) == 1;\n\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    Sci_PositionU safeStartPos = styler.LineStart( lineCurrent );\n\n    bool bArg1 = true;\n    Sci_Position nWordStart = -1;\n\n    int levelCurrent = SC_FOLDLEVELBASE;\n    if (lineCurrent > 0)\n        levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n    int levelNext = levelCurrent;\n\n    for (Sci_PositionU i = safeStartPos; i < startPos + length; i++) {\n        char chCurr = styler.SafeGetCharAt(i);\n\n        if ( bArg1 ) {\n            if ( nWordStart == -1 && (isCmakeLetter(chCurr)) ) {\n                nWordStart = i;\n            }\n            else if ( isCmakeLetter(chCurr) == false && nWordStart > -1 ) {\n                int newLevel = calculateFoldCmake( nWordStart, i-1, levelNext, styler, foldAtElse);\n\n                if ( newLevel == levelNext ) {\n                    if ( foldAtElse ) {\n                        if ( CmakeNextLineHasElse(i, startPos + length, styler) )\n                            levelNext--;\n                    }\n                }\n                else\n                    levelNext = newLevel;\n                bArg1 = false;\n            }\n        }\n\n        if ( chCurr == '\\n' ) {\n            if ( bArg1 && foldAtElse) {\n                if ( CmakeNextLineHasElse(i, startPos + length, styler) )\n                    levelNext--;\n            }\n\n            // If we are on a new line...\n            int levelUse = levelCurrent;\n            int lev = levelUse | levelNext << 16;\n            if (levelUse < levelNext )\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            if (lev != styler.LevelAt(lineCurrent))\n                styler.SetLevel(lineCurrent, lev);\n\n            lineCurrent++;\n            levelCurrent = levelNext;\n            bArg1 = true; // New line, lets look at first argument again\n            nWordStart = -1;\n        }\n    }\n\n    int levelUse = levelCurrent;\n    int lev = levelUse | levelNext << 16;\n    if (levelUse < levelNext)\n        lev |= SC_FOLDLEVELHEADERFLAG;\n    if (lev != styler.LevelAt(lineCurrent))\n        styler.SetLevel(lineCurrent, lev);\n}\n\nstatic const char * const cmakeWordLists[] = {\n    \"Commands\",\n    \"Parameters\",\n    \"UserDefined\",\n    0,\n    0,};\n\nextern const LexerModule lmCmake(SCLEX_CMAKE, ColouriseCmakeDoc, \"cmake\", FoldCmakeDoc, cmakeWordLists);\n"
  },
  {
    "path": "lexers/LexCoffeeScript.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexCoffeeScript.cxx\n ** Lexer for CoffeeScript.\n **/\n// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>\n// Based on the Scintilla C++ Lexer\n// Written by Eric Promislow <ericp@activestate.com> in 2011 for the Komodo IDE\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include <algorithm>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic bool IsSpaceEquiv(int state) {\n\treturn (state == SCE_COFFEESCRIPT_DEFAULT\n\t    || state == SCE_COFFEESCRIPT_COMMENTLINE\n\t    || state == SCE_COFFEESCRIPT_COMMENTBLOCK\n\t    || state == SCE_COFFEESCRIPT_VERBOSE_REGEX\n\t    || state == SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT\n\t    || state == SCE_COFFEESCRIPT_WORD\n\t    || state == SCE_COFFEESCRIPT_REGEX);\n}\n\n// Store the current lexer state and brace count prior to starting a new\n// `#{}` interpolation level.\n// Based on LexRuby.cxx.\nstatic void enterInnerExpression(int  *p_inner_string_types,\n                                 int  *p_inner_expn_brace_counts,\n                                 int&  inner_string_count,\n                                 int   state,\n                                 int&  brace_counts\n                                 ) {\n\tp_inner_string_types[inner_string_count] = state;\n\tp_inner_expn_brace_counts[inner_string_count] = brace_counts;\n\tbrace_counts = 0;\n\t++inner_string_count;\n}\n\n// Restore the lexer state and brace count for the previous `#{}` interpolation\n// level upon returning to it.\n// Note the previous lexer state is the return value and needs to be restored\n// manually by the StyleContext.\n// Based on LexRuby.cxx.\nstatic int exitInnerExpression(int  *p_inner_string_types,\n                               int  *p_inner_expn_brace_counts,\n                               int&  inner_string_count,\n                               int&  brace_counts\n                              ) {\n\t--inner_string_count;\n\tbrace_counts = p_inner_expn_brace_counts[inner_string_count];\n\treturn p_inner_string_types[inner_string_count];\n}\n\n// Preconditions: sc.currentPos points to a character after '+' or '-'.\n// The test for pos reaching 0 should be redundant,\n// and is in only for safety measures.\n// Limitation: this code will give the incorrect answer for code like\n// a = b+++/ptn/...\n// Putting a space between the '++' post-inc operator and the '+' binary op\n// fixes this, and is highly recommended for readability anyway.\nstatic bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {\n\tSci_Position pos = (Sci_Position) sc.currentPos;\n\twhile (--pos > 0) {\n\t\tchar ch = styler[pos];\n\t\tif (ch == '+' || ch == '-') {\n\t\t\treturn styler[pos - 1] == ch;\n\t\t}\n\t}\n\treturn false;\n}\n\nstatic bool followsKeyword(StyleContext &sc, Accessor &styler) {\n\tSci_Position pos = (Sci_Position) sc.currentPos;\n\tSci_Position currentLine = styler.GetLine(pos);\n\tSci_Position lineStartPos = styler.LineStart(currentLine);\n\twhile (--pos > lineStartPos) {\n\t\tchar ch = styler.SafeGetCharAt(pos);\n\t\tif (ch != ' ' && ch != '\\t') {\n\t\t\tbreak;\n\t\t}\n\t}\n\tstyler.Flush();\n\treturn styler.StyleAt(pos) == SCE_COFFEESCRIPT_WORD;\n}\n\n#if defined(__clang__)\n#if __has_warning(\"-Wunused-but-set-variable\")\n// Disable warning for visibleChars\n#pragma clang diagnostic ignored \"-Wunused-but-set-variable\"\n#endif\n#endif\n\nstatic void ColouriseCoffeeScriptDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords4 = *keywordlists[3];\n\n\tCharacterSet setOKBeforeRE(CharacterSet::setNone, \"([{=,:;!%^&*|?~+-\");\n\tCharacterSet setCouldBePostOp(CharacterSet::setNone, \"+-\");\n\n\tCharacterSet setWordStart(CharacterSet::setAlpha, \"_$@\", 0x80, true);\n\tCharacterSet setWord(CharacterSet::setAlphaNum, \"._$\", 0x80, true);\n\n\tint chPrevNonWhite = ' ';\n\tint visibleChars = 0;\n\n\t// String/Regex interpolation variables, based on LexRuby.cxx.\n\t// In most cases a value of 2 should be ample for the code the user is\n\t// likely to enter. For example,\n\t//   \"Filling the #{container} with #{liquid}...\"\n\t// from the CoffeeScript homepage nests to a level of 2\n\t// If the user actually hits a 6th occurrence of '#{' in a double-quoted\n\t// string (including regexes), it will stay as a string.  The problem with\n\t// this is that quotes might flip, a 7th '#{' will look like a comment,\n\t// and code-folding might be wrong.\n#define INNER_STRINGS_MAX_COUNT 5\n\t// These vars track our instances of \"...#{,,,'..#{,,,}...',,,}...\"\n\tint inner_string_types[INNER_STRINGS_MAX_COUNT];\n\t// Track # braces when we push a new #{ thing\n\tint inner_expn_brace_counts[INNER_STRINGS_MAX_COUNT];\n\tint inner_string_count = 0;\n\tint brace_counts = 0;   // Number of #{ ... } things within an expression\n\tfor (int i = 0; i < INNER_STRINGS_MAX_COUNT; i++) {\n\t\tinner_string_types[i] = 0;\n\t\tinner_expn_brace_counts[i] = 0;\n\t}\n\n\t// look back to set chPrevNonWhite properly for better regex colouring\n\tSci_Position endPos = startPos + length;\n        if (startPos > 0 && IsSpaceEquiv(initStyle)) {\n\t\tSci_PositionU back = startPos;\n\t\tstyler.Flush();\n\t\twhile (back > 0 && IsSpaceEquiv(styler.StyleAt(--back)))\n\t\t\t;\n\t\tif (styler.StyleAt(back) == SCE_COFFEESCRIPT_OPERATOR) {\n\t\t\tchPrevNonWhite = styler.SafeGetCharAt(back);\n\t\t}\n\t\tif (startPos != back) {\n\t\t\tinitStyle = styler.StyleAt(back);\n\t\t\tif (IsSpaceEquiv(initStyle)) {\n\t\t\t\tinitStyle = SCE_COFFEESCRIPT_DEFAULT;\n\t\t\t}\n\t\t}\n\t\tstartPos = back;\n\t}\n\n\tStyleContext sc(startPos, endPos - startPos, initStyle, styler);\n\n\tfor (; sc.More();) {\n\n\t\tif (sc.atLineStart) {\n\t\t\t// Reset states to beginning of colourise so no surprises\n\t\t\t// if different sets of lines lexed.\n\t\t\tvisibleChars = 0;\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_COFFEESCRIPT_OPERATOR:\n\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_NUMBER:\n\t\t\t\t// We accept almost anything because of hex. and number suffixes\n\t\t\t\tif (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_IDENTIFIER:\n\t\t\t\tif (!setWord.Contains(sc.ch) || (sc.ch == '.') || (sc.ch == '$')) {\n\t\t\t\t\tchar s[1000];\n\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_COFFEESCRIPT_WORD);\n\t\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_COFFEESCRIPT_WORD2);\n\t\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_COFFEESCRIPT_GLOBALCLASS);\n\t\t\t\t\t} else if (sc.LengthCurrent() > 0 && s[0] == '@') {\n\t\t\t\t\t\tsc.ChangeState(SCE_COFFEESCRIPT_INSTANCEPROPERTY);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_WORD:\n\t\t\tcase SCE_COFFEESCRIPT_WORD2:\n\t\t\tcase SCE_COFFEESCRIPT_GLOBALCLASS:\n\t\t\tcase SCE_COFFEESCRIPT_INSTANCEPROPERTY:\n\t\t\t\tif (!setWord.Contains(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_STRING:\n\t\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tsc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t} else if (sc.ch == '#' && sc.chNext == '{' && inner_string_count < INNER_STRINGS_MAX_COUNT) {\n\t\t\t\t\t// process interpolated code #{ ... }\n\t\t\t\t\tenterInnerExpression(inner_string_types,\n\t\t\t\t\t                     inner_expn_brace_counts,\n\t\t\t\t\t                     inner_string_count,\n\t\t\t\t\t                     sc.state,\n\t\t\t\t\t                     brace_counts);\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_OPERATOR);\n\t\t\t\t\tsc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_CHARACTER:\n\t\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\tsc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_REGEX:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t} else if (sc.ch == '/') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\twhile ((sc.ch < 0x80) && islower(sc.ch))\n\t\t\t\t\t\tsc.Forward();    // gobble regex flags\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\t// Gobble up the quoted character\n\t\t\t\t\tif (sc.chNext == '\\\\' || sc.chNext == '/') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_STRINGEOL:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_COMMENTBLOCK:\n\t\t\t\tif (sc.Match(\"###\")) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_VERBOSE_REGEX:\n\t\t\t\tif (sc.Match(\"///\")) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);\n\t\t\t\t} else if (sc.Match('#')) {\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_COFFEESCRIPT_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_NUMBER);\n\t\t\t} else if (setWordStart.Contains(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_IDENTIFIER);\n\t\t\t} else if (sc.Match(\"///\")) {\n\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '/'\n\t\t\t\t   && (setOKBeforeRE.Contains(chPrevNonWhite)\n\t\t\t\t       || followsKeyword(sc, styler))\n\t\t\t\t   && (!setCouldBePostOp.Contains(chPrevNonWhite)\n\t\t\t\t       || !FollowsPostfixOperator(sc, styler))) {\n\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_REGEX);\t// JavaScript's RegEx\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_CHARACTER);\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tif (sc.Match(\"###\")) {\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_COMMENTBLOCK);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_COMMENTLINE);\n\t\t\t\t}\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_COFFEESCRIPT_OPERATOR);\n\t\t\t\t// Handle '..' and '...' operators correctly.\n\t\t\t\tif (sc.ch == '.') {\n\t\t\t\t\tfor (int i = 0; i < 2 && sc.chNext == '.'; i++, sc.Forward()) ;\n\t\t\t\t} else if (sc.ch == '{') {\n\t\t\t\t\t++brace_counts;\n\t\t\t\t} else if (sc.ch == '}' && --brace_counts <= 0 && inner_string_count > 0) {\n\t\t\t\t\t// Return to previous state before #{ ... }\n\t\t\t\t\tsc.ForwardSetState(exitInnerExpression(inner_string_types,\n\t\t\t\t\t                                       inner_expn_brace_counts,\n\t\t\t\t\t                                       inner_string_count,\n\t\t\t\t\t                                       brace_counts));\n\t\t\t\t\tcontinue; // skip sc.Forward() at loop end\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {\n\t\t\tchPrevNonWhite = sc.ch;\n\t\t\tvisibleChars++;\n\t\t}\n\t\tsc.Forward();\n\t}\n\tsc.Complete();\n}\n\nstatic bool IsCommentLine(Sci_Position line, Accessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tif (ch == '#')\n\t\t\treturn true;\n\t\telse if (ch != ' ' && ch != '\\t')\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nstatic void FoldCoffeeScriptDoc(Sci_PositionU startPos, Sci_Position length, int,\n\t\t\t\tWordList *[], Accessor &styler) {\n\t// A simplified version of FoldPyDoc\n\tconst Sci_Position maxPos = startPos + length;\n\tconst Sci_Position maxLines = styler.GetLine(maxPos - 1);             // Requested last line\n\tconst Sci_Position docLines = styler.GetLine(styler.Length() - 1);  // Available last line\n\n\t// property fold.coffeescript.comment\n\t// Set to 1 to allow folding of comment blocks in CoffeeScript.\n\tconst bool foldComment = styler.GetPropertyInt(\"fold.coffeescript.comment\") != 0;\n\n\tconst bool foldCompact = styler.GetPropertyInt(\"fold.compact\") != 0;\n\n\t// Backtrack to previous non-blank line so we can determine indent level\n\t// for any white space lines\n\t// and so we can fix any preceding fold level (which is why we go back\n\t// at least one line in all cases)\n\tint spaceFlags = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);\n\twhile (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tindentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);\n\t\tif (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)\n\t\t    && !IsCommentLine(lineCurrent, styler))\n\t\t\tbreak;\n\t}\n\tint indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\n\t// Set up initial loop state\n\tint prevComment = 0;\n\tif (lineCurrent >= 1)\n\t\tprevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);\n\n\t// Process all characters to end of requested range\n\t// or comment that hangs over the end of the range.  Cap processing in all cases\n\t// to end of document (in case of comment at end).\n\twhile ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) {\n\n\t\t// Gather info\n\t\tint lev = indentCurrent;\n\t\tSci_Position lineNext = lineCurrent + 1;\n\t\tint indentNext = indentCurrent;\n\t\tif (lineNext <= docLines) {\n\t\t\t// Information about next line is only available if not at end of document\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);\n\t\t}\n\t\tconst int comment = foldComment && IsCommentLine(lineCurrent, styler);\n\t\tconst int comment_start = (comment && !prevComment && (lineNext <= docLines) &&\n\t\t                           IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));\n\t\tconst int comment_continue = (comment && prevComment);\n\t\tif (!comment)\n\t\t\tindentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\t\tif (indentNext & SC_FOLDLEVELWHITEFLAG)\n\t\t\tindentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;\n\n\t\tif (comment_start) {\n\t\t\t// Place fold point at start of a block of comments\n\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t} else if (comment_continue) {\n\t\t\t// Add level to rest of lines in the block\n\t\t\tlev = lev + 1;\n\t\t}\n\n\t\t// Skip past any blank lines for next indent level info; we skip also\n\t\t// comments (all comments, not just those starting in column 0)\n\t\t// which effectively folds them into surrounding code rather\n\t\t// than screwing up folding.\n\n\t\twhile ((lineNext < docLines) &&\n\t\t        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||\n\t\t         (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {\n\n\t\t\tlineNext++;\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);\n\t\t}\n\n\t\tconst int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;\n\t\tconst int levelBeforeComments = std::max(indentCurrentLevel,levelAfterComments);\n\n\t\t// Now set all the indent levels on the lines we skipped\n\t\t// Do this from end to start.  Once we encounter one line\n\t\t// which is indented more than the line after the end of\n\t\t// the comment-block, use the level of the block before\n\n\t\tSci_Position skipLine = lineNext;\n\t\tint skipLevel = levelAfterComments;\n\n\t\twhile (--skipLine > lineCurrent) {\n\t\t\tint skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);\n\n\t\t\tif (foldCompact) {\n\t\t\t\tif ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)\n\t\t\t\t\tskipLevel = levelBeforeComments;\n\n\t\t\t\tint whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;\n\n\t\t\t\tstyler.SetLevel(skipLine, skipLevel | whiteFlag);\n\t\t\t} else {\n\t\t\t\tif ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&\n\t\t\t\t\t!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&\n\t\t\t\t\t!IsCommentLine(skipLine, styler))\n\t\t\t\t\tskipLevel = levelBeforeComments;\n\n\t\t\t\tstyler.SetLevel(skipLine, skipLevel);\n\t\t\t}\n\t\t}\n\n\t\t// Set fold header on non-comment line\n\t\tif (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t}\n\n\t\t// Keep track of block comment state of previous line\n\t\tprevComment = comment_start || comment_continue;\n\n\t\t// Set fold level for this line and move to next line\n\t\tstyler.SetLevel(lineCurrent, lev);\n\t\tindentCurrent = indentNext;\n\t\tlineCurrent = lineNext;\n\t}\n}\n\nstatic const char *const csWordLists[] = {\n            \"Keywords\",\n            \"Secondary keywords\",\n            \"Unused\",\n            \"Global classes\",\n            0,\n};\n\nextern const LexerModule lmCoffeeScript(SCLEX_COFFEESCRIPT, ColouriseCoffeeScriptDoc, \"coffeescript\", FoldCoffeeScriptDoc, csWordLists);\n"
  },
  {
    "path": "lexers/LexConf.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexConf.cxx\n ** Lexer for Apache Configuration Files.\n **\n ** First working version contributed by Ahmad Zawawi <ahmad.zawawi@gmail.com> on October 28, 2000.\n ** i created this lexer because i needed something pretty when dealing\n ** when Apache Configuration files...\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ColouriseConfDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler)\n{\n\tint state = SCE_CONF_DEFAULT;\n\tchar chNext = styler[startPos];\n\tSci_Position lengthDoc = startPos + length;\n\t// create a buffer large enough to take the largest chunk...\n\tchar *buffer = new char[length+1];\n\tSci_Position bufferCount = 0;\n\n\t// this assumes that we have 2 keyword list in conf.properties\n\tWordList &directives = *keywordLists[0];\n\tWordList &params = *keywordLists[1];\n\n\t// go through all provided text segment\n\t// using the hand-written state machine shown below\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tfor (Sci_Position i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif (styler.IsLeadByte(ch)) {\n\t\t\tchNext = styler.SafeGetCharAt(i + 2);\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tswitch(state) {\n\t\t\tcase SCE_CONF_DEFAULT:\n\t\t\t\tif( ch == '\\n' || ch == '\\r' || ch == '\\t' || ch == ' ') {\n\t\t\t\t\t// whitespace is simply ignored here...\n\t\t\t\t\tstyler.ColourTo(i,SCE_CONF_DEFAULT);\n\t\t\t\t\tbreak;\n\t\t\t\t} else if( ch == '#' ) {\n\t\t\t\t\t// signals the start of a comment...\n\t\t\t\t\tstate = SCE_CONF_COMMENT;\n\t\t\t\t\tstyler.ColourTo(i,SCE_CONF_COMMENT);\n\t\t\t\t} else if( ch == '.' /*|| ch == '/'*/) {\n\t\t\t\t\t// signals the start of a file...\n\t\t\t\t\tstate = SCE_CONF_EXTENSION;\n\t\t\t\t\tstyler.ColourTo(i,SCE_CONF_EXTENSION);\n\t\t\t\t} else if( ch == '\"') {\n\t\t\t\t\tstate = SCE_CONF_STRING;\n\t\t\t\t\tstyler.ColourTo(i,SCE_CONF_STRING);\n\t\t\t\t} else if( IsASCII(ch) && ispunct(ch) ) {\n\t\t\t\t\t// signals an operator...\n\t\t\t\t\t// no state jump necessary for this\n\t\t\t\t\t// simple case...\n\t\t\t\t\tstyler.ColourTo(i,SCE_CONF_OPERATOR);\n\t\t\t\t} else if( IsASCII(ch) && isalpha(ch) ) {\n\t\t\t\t\t// signals the start of an identifier\n\t\t\t\t\tbufferCount = 0;\n\t\t\t\t\tbuffer[bufferCount++] = static_cast<char>(tolower(ch));\n\t\t\t\t\tstate = SCE_CONF_IDENTIFIER;\n\t\t\t\t} else if( IsASCII(ch) && isdigit(ch) ) {\n\t\t\t\t\t// signals the start of a number\n\t\t\t\t\tbufferCount = 0;\n\t\t\t\t\tbuffer[bufferCount++] = ch;\n\t\t\t\t\t//styler.ColourTo(i,SCE_CONF_NUMBER);\n\t\t\t\t\tstate = SCE_CONF_NUMBER;\n\t\t\t\t} else {\n\t\t\t\t\t// style it the default style..\n\t\t\t\t\tstyler.ColourTo(i,SCE_CONF_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_CONF_COMMENT:\n\t\t\t\t// if we find a newline here,\n\t\t\t\t// we simply go to default state\n\t\t\t\t// else continue to work on it...\n\t\t\t\tif( ch == '\\n' || ch == '\\r' ) {\n\t\t\t\t\tstate = SCE_CONF_DEFAULT;\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i,SCE_CONF_COMMENT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_CONF_EXTENSION:\n\t\t\t\t// if we find a non-alphanumeric char,\n\t\t\t\t// we simply go to default state\n\t\t\t\t// else we're still dealing with an extension...\n\t\t\t\tif( (IsASCII(ch) && isalnum(ch)) || (ch == '_') ||\n\t\t\t\t\t(ch == '-') || (ch == '$') ||\n\t\t\t\t\t(ch == '/') || (ch == '.') || (ch == '*') )\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(i,SCE_CONF_EXTENSION);\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_CONF_DEFAULT;\n\t\t\t\t\tchNext = styler[i--];\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_CONF_STRING:\n\t\t\t\t// if we find the end of a string char, we simply go to default state\n\t\t\t\t// else we're still dealing with an string...\n\t\t\t\tif( (ch == '\"' && styler.SafeGetCharAt(i-1)!='\\\\') || (ch == '\\n') || (ch == '\\r') ) {\n\t\t\t\t\tstate = SCE_CONF_DEFAULT;\n\t\t\t\t}\n\t\t\t\tstyler.ColourTo(i,SCE_CONF_STRING);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_CONF_IDENTIFIER:\n\t\t\t\t// stay  in CONF_IDENTIFIER state until we find a non-alphanumeric\n\t\t\t\tif( (IsASCII(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {\n\t\t\t\t\tbuffer[bufferCount++] = static_cast<char>(tolower(ch));\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_CONF_DEFAULT;\n\t\t\t\t\tbuffer[bufferCount] = '\\0';\n\n\t\t\t\t\t// check if the buffer contains a keyword, and highlight it if it is a keyword...\n\t\t\t\t\tif(directives.InList(buffer)) {\n\t\t\t\t\t\tstyler.ColourTo(i-1,SCE_CONF_DIRECTIVE );\n\t\t\t\t\t} else if(params.InList(buffer)) {\n\t\t\t\t\t\tstyler.ColourTo(i-1,SCE_CONF_PARAMETER );\n\t\t\t\t\t} else if(strchr(buffer,'/') || strchr(buffer,'.')) {\n\t\t\t\t\t\tstyler.ColourTo(i-1,SCE_CONF_EXTENSION);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyler.ColourTo(i-1,SCE_CONF_DEFAULT);\n\t\t\t\t\t}\n\n\t\t\t\t\t// push back the faulty character\n\t\t\t\t\tchNext = styler[i--];\n\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_CONF_NUMBER:\n\t\t\t\t// stay  in CONF_NUMBER state until we find a non-numeric\n\t\t\t\tif( (IsASCII(ch) && isdigit(ch)) || ch == '.') {\n\t\t\t\t\tbuffer[bufferCount++] = ch;\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_CONF_DEFAULT;\n\t\t\t\t\tbuffer[bufferCount] = '\\0';\n\n\t\t\t\t\t// Colourize here...\n\t\t\t\t\tif( strchr(buffer,'.') ) {\n\t\t\t\t\t\t// it is an IP address...\n\t\t\t\t\t\tstyler.ColourTo(i-1,SCE_CONF_IP);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// normal number\n\t\t\t\t\t\tstyler.ColourTo(i-1,SCE_CONF_NUMBER);\n\t\t\t\t\t}\n\n\t\t\t\t\t// push back a character\n\t\t\t\t\tchNext = styler[i--];\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t}\n\t}\n\tdelete []buffer;\n}\n\nstatic const char * const confWordListDesc[] = {\n\t\"Directives\",\n\t\"Parameters\",\n\t0\n};\n\nextern const LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, \"conf\", 0, confWordListDesc);\n"
  },
  {
    "path": "lexers/LexCrontab.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexCrontab.cxx\n ** Lexer to use with extended crontab files used by a powerful\n ** Windows scheduler/event monitor/automation manager nnCron.\n ** (http://nemtsev.eserv.ru/)\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ColouriseNncrontabDoc(Sci_PositionU startPos, Sci_Position length, int, WordList\n*keywordLists[], Accessor &styler)\n{\n\tint state = SCE_NNCRONTAB_DEFAULT;\n\tchar chNext = styler[startPos];\n\tSci_Position lengthDoc = startPos + length;\n\t// create a buffer large enough to take the largest chunk...\n\tchar *buffer = new char[length+1];\n\tSci_Position bufferCount = 0;\n\t// used when highliting environment variables inside quoted string:\n\tbool insideString = false;\n\n\t// this assumes that we have 3 keyword list in conf.properties\n\tWordList &section = *keywordLists[0];\n\tWordList &keyword = *keywordLists[1];\n\tWordList &modifier = *keywordLists[2];\n\n\t// go through all provided text segment\n\t// using the hand-written state machine shown below\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tfor (Sci_Position i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif (styler.IsLeadByte(ch)) {\n\t\t\tchNext = styler.SafeGetCharAt(i + 2);\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tswitch(state) {\n\t\t\tcase SCE_NNCRONTAB_DEFAULT:\n\t\t\t\tif( ch == '\\n' || ch == '\\r' || ch == '\\t' || ch == ' ') {\n\t\t\t\t\t// whitespace is simply ignored here...\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);\n\t\t\t\t\tbreak;\n\t\t\t\t} else if( ch == '#' && styler.SafeGetCharAt(i+1) == '(') {\n\t\t\t\t\t// signals the start of a task...\n\t\t\t\t\tstate = SCE_NNCRONTAB_TASK;\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_TASK);\n\t\t\t\t}\n\t\t\t\t  else if( ch == '\\\\' && (styler.SafeGetCharAt(i+1) == ' ' ||\n\t\t\t\t\t\t\t\t\t\t styler.SafeGetCharAt(i+1) == '\\t')) {\n\t\t\t\t\t// signals the start of an extended comment...\n\t\t\t\t\tstate = SCE_NNCRONTAB_COMMENT;\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_COMMENT);\n\t\t\t\t} else if( ch == '#' ) {\n\t\t\t\t\t// signals the start of a plain comment...\n\t\t\t\t\tstate = SCE_NNCRONTAB_COMMENT;\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_COMMENT);\n\t\t\t\t} else if( ch == ')' && styler.SafeGetCharAt(i+1) == '#') {\n\t\t\t\t\t// signals the end of a task...\n\t\t\t\t\tstate = SCE_NNCRONTAB_TASK;\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_TASK);\n\t\t\t\t} else if( ch == '\"') {\n\t\t\t\t\tstate = SCE_NNCRONTAB_STRING;\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_STRING);\n\t\t\t\t} else if( ch == '%') {\n\t\t\t\t\t// signals environment variables\n\t\t\t\t\tstate = SCE_NNCRONTAB_ENVIRONMENT;\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);\n\t\t\t\t} else if( ch == '<' && styler.SafeGetCharAt(i+1) == '%') {\n\t\t\t\t\t// signals environment variables\n\t\t\t\t\tstate = SCE_NNCRONTAB_ENVIRONMENT;\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);\n\t\t\t\t} else if( ch == '*' ) {\n\t\t\t\t\t// signals an asterisk\n\t\t\t\t\t// no state jump necessary for this simple case...\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_ASTERISK);\n\t\t\t\t} else if( (IsASCII(ch) && isalpha(ch)) || ch == '<' ) {\n\t\t\t\t\t// signals the start of an identifier\n\t\t\t\t\tbufferCount = 0;\n\t\t\t\t\tbuffer[bufferCount++] = ch;\n\t\t\t\t\tstate = SCE_NNCRONTAB_IDENTIFIER;\n\t\t\t\t} else if( IsASCII(ch) && isdigit(ch) ) {\n\t\t\t\t\t// signals the start of a number\n\t\t\t\t\tbufferCount = 0;\n\t\t\t\t\tbuffer[bufferCount++] = ch;\n\t\t\t\t\tstate = SCE_NNCRONTAB_NUMBER;\n\t\t\t\t} else {\n\t\t\t\t\t// style it the default style..\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_NNCRONTAB_COMMENT:\n\t\t\t\t// if we find a newline here,\n\t\t\t\t// we simply go to default state\n\t\t\t\t// else continue to work on it...\n\t\t\t\tif( ch == '\\n' || ch == '\\r' ) {\n\t\t\t\t\tstate = SCE_NNCRONTAB_DEFAULT;\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_COMMENT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_NNCRONTAB_TASK:\n\t\t\t\t// if we find a newline here,\n\t\t\t\t// we simply go to default state\n\t\t\t\t// else continue to work on it...\n\t\t\t\tif( ch == '\\n' || ch == '\\r' ) {\n\t\t\t\t\tstate = SCE_NNCRONTAB_DEFAULT;\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_TASK);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_NNCRONTAB_STRING:\n\t\t\t\tif( ch == '%' ) {\n\t\t\t\t\tstate = SCE_NNCRONTAB_ENVIRONMENT;\n\t\t\t\t\tinsideString = true;\n\t\t\t\t\tstyler.ColourTo(i-1,SCE_NNCRONTAB_STRING);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// if we find the end of a string char, we simply go to default state\n\t\t\t\t// else we're still dealing with an string...\n\t\t\t\tif( (ch == '\"' && styler.SafeGetCharAt(i-1)!='\\\\') ||\n\t\t\t\t\t(ch == '\\n') || (ch == '\\r') ) {\n\t\t\t\t\tstate = SCE_NNCRONTAB_DEFAULT;\n\t\t\t\t}\n\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_STRING);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_NNCRONTAB_ENVIRONMENT:\n\t\t\t\t// if we find the end of a string char, we simply go to default state\n\t\t\t\t// else we're still dealing with an string...\n\t\t\t\tif( ch == '%' && insideString ) {\n\t\t\t\t\tstate = SCE_NNCRONTAB_STRING;\n\t\t\t\t\tinsideString = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif( (ch == '%' && styler.SafeGetCharAt(i-1)!='\\\\')\n\t\t\t\t\t|| (ch == '\\n') || (ch == '\\r') || (ch == '>') ) {\n\t\t\t\t\tstate = SCE_NNCRONTAB_DEFAULT;\n\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tstyler.ColourTo(i+1,SCE_NNCRONTAB_ENVIRONMENT);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_NNCRONTAB_IDENTIFIER:\n\t\t\t\t// stay  in CONF_IDENTIFIER state until we find a non-alphanumeric\n\t\t\t\tif( (IsASCII(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') ||\n\t\t\t\t\t(ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') ||\n\t\t\t\t\t(ch == '@') ) {\n\t\t\t\t\tbuffer[bufferCount++] = ch;\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_NNCRONTAB_DEFAULT;\n\t\t\t\t\tbuffer[bufferCount] = '\\0';\n\n\t\t\t\t\t// check if the buffer contains a keyword,\n\t\t\t\t\t// and highlight it if it is a keyword...\n\t\t\t\t\tif(section.InList(buffer)) {\n\t\t\t\t\t\tstyler.ColourTo(i,SCE_NNCRONTAB_SECTION );\n\t\t\t\t\t} else if(keyword.InList(buffer)) {\n\t\t\t\t\t\tstyler.ColourTo(i-1,SCE_NNCRONTAB_KEYWORD );\n\t\t\t\t\t} // else if(strchr(buffer,'/') || strchr(buffer,'.')) {\n\t\t\t\t\t//\tstyler.ColourTo(i-1,SCE_NNCRONTAB_EXTENSION);\n\t\t\t\t\t// }\n\t\t\t\t\t  else if(modifier.InList(buffer)) {\n\t\t\t\t\t\tstyler.ColourTo(i-1,SCE_NNCRONTAB_MODIFIER );\n\t\t\t\t\t  }\telse {\n\t\t\t\t\t\tstyler.ColourTo(i-1,SCE_NNCRONTAB_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t\t// push back the faulty character\n\t\t\t\t\tchNext = styler[i--];\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_NNCRONTAB_NUMBER:\n\t\t\t\t// stay  in CONF_NUMBER state until we find a non-numeric\n\t\t\t\tif( IsASCII(ch) && isdigit(ch) /* || ch == '.' */ ) {\n\t\t\t\t\tbuffer[bufferCount++] = ch;\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_NNCRONTAB_DEFAULT;\n\t\t\t\t\tbuffer[bufferCount] = '\\0';\n\t\t\t\t\t// Colourize here... (normal number)\n\t\t\t\t\tstyler.ColourTo(i-1,SCE_NNCRONTAB_NUMBER);\n\t\t\t\t\t// push back a character\n\t\t\t\t\tchNext = styler[i--];\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tdelete []buffer;\n}\n\nstatic const char * const cronWordListDesc[] = {\n\t\"Section keywords and Forth words\",\n\t\"nnCrontab keywords\",\n\t\"Modifiers\",\n\t0\n};\n\nextern const LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, \"nncrontab\", 0, cronWordListDesc);\n"
  },
  {
    "path": "lexers/LexCsound.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexCsound.cxx\n ** Lexer for Csound (Orchestra & Score)\n ** Written by Georg Ritter - <ritterfuture A T gmail D O T com>\n **/\n// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '.' ||\n\t\tch == '_' || ch == '?');\n}\n\nstatic inline bool IsAWordStart(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||\n\t\tch == '%' || ch == '@' || ch == '$' || ch == '?');\n}\n\nstatic inline bool IsCsoundOperator(char ch) {\n\tif (IsASCII(ch) && isalnum(ch))\n\t\treturn false;\n\t// '.' left out as it is used to make up numbers\n\tif (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||\n\t\tch == '(' || ch == ')' || ch == '=' || ch == '^' ||\n\t\tch == '[' || ch == ']' || ch == '<' || ch == '&' ||\n\t\tch == '>' || ch == ',' || ch == '|' || ch == '~' ||\n\t\tch == '%' || ch == ':')\n\t\treturn true;\n\treturn false;\n}\n\nstatic void ColouriseCsoundDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n\t\t\t\tAccessor &styler) {\n\n\tWordList &opcode = *keywordlists[0];\n\tWordList &headerStmt = *keywordlists[1];\n\tWordList &otherKeyword = *keywordlists[2];\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_CSOUND_STRINGEOL)\n\t\tinitStyle = SCE_CSOUND_DEFAULT;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward())\n\t{\n\t\t// Handle line continuation generically.\n\t\tif (sc.ch == '\\\\') {\n\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_CSOUND_OPERATOR) {\n\t\t\tif (!IsCsoundOperator(static_cast<char>(sc.ch))) {\n\t\t\t    sc.SetState(SCE_CSOUND_DEFAULT);\n\t\t\t}\n\t\t}else if (sc.state == SCE_CSOUND_NUMBER) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_CSOUND_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_CSOUND_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch) ) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\n\t\t\t\tif (opcode.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_CSOUND_OPCODE);\n\t\t\t\t} else if (headerStmt.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_CSOUND_HEADERSTMT);\n\t\t\t\t} else if (otherKeyword.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_CSOUND_USERKEYWORD);\n\t\t\t\t} else if (s[0] == 'p') {\n\t\t\t\t\tsc.ChangeState(SCE_CSOUND_PARAM);\n\t\t\t\t} else if (s[0] == 'a') {\n\t\t\t\t\tsc.ChangeState(SCE_CSOUND_ARATE_VAR);\n\t\t\t\t} else if (s[0] == 'k') {\n\t\t\t\t\tsc.ChangeState(SCE_CSOUND_KRATE_VAR);\n\t\t\t\t} else if (s[0] == 'i') { // covers both i-rate variables and i-statements\n\t\t\t\t\tsc.ChangeState(SCE_CSOUND_IRATE_VAR);\n\t\t\t\t} else if (s[0] == 'g') {\n\t\t\t\t\tsc.ChangeState(SCE_CSOUND_GLOBAL_VAR);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_CSOUND_DEFAULT);\n\t\t\t}\n\t\t}\n\t\telse if (sc.state == SCE_CSOUND_COMMENT ) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_CSOUND_DEFAULT);\n\t\t\t}\n\t\t}\n\t\telse if ((sc.state == SCE_CSOUND_ARATE_VAR) ||\n\t\t\t(sc.state == SCE_CSOUND_KRATE_VAR) ||\n\t\t(sc.state == SCE_CSOUND_IRATE_VAR)) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_CSOUND_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_CSOUND_DEFAULT) {\n\t\t\tif (sc.ch == ';'){\n\t\t\t\tsc.SetState(SCE_CSOUND_COMMENT);\n\t\t\t} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_CSOUND_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_CSOUND_IDENTIFIER);\n\t\t\t} else if (IsCsoundOperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_CSOUND_OPERATOR);\n\t\t\t} else if (sc.ch == 'p') {\n\t\t\t\tsc.SetState(SCE_CSOUND_PARAM);\n\t\t\t} else if (sc.ch == 'a') {\n\t\t\t\tsc.SetState(SCE_CSOUND_ARATE_VAR);\n\t\t\t} else if (sc.ch == 'k') {\n\t\t\t\tsc.SetState(SCE_CSOUND_KRATE_VAR);\n\t\t\t} else if (sc.ch == 'i') { // covers both i-rate variables and i-statements\n\t\t\t\tsc.SetState(SCE_CSOUND_IRATE_VAR);\n\t\t\t} else if (sc.ch == 'g') {\n\t\t\t\tsc.SetState(SCE_CSOUND_GLOBAL_VAR);\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void FoldCsoundInstruments(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],\n\t\tAccessor &styler) {\n\tSci_PositionU lengthDoc = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint stylePrev = 0;\n\tint styleNext = styler.StyleAt(startPos);\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif ((stylePrev != SCE_CSOUND_OPCODE) && (style == SCE_CSOUND_OPCODE)) {\n\t\t\tchar s[20];\n\t\t\tunsigned int j = 0;\n\t\t\twhile ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {\n\t\t\t\ts[j] = styler[i + j];\n\t\t\t\tj++;\n\t\t\t}\n\t\t\ts[j] = '\\0';\n\n\t\t\tif (strcmp(s, \"instr\") == 0)\n\t\t\t\tlevelCurrent++;\n\t\t\tif (strcmp(s, \"endin\") == 0)\n\t\t\t\tlevelCurrent--;\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t\tstylePrev = style;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\n\nstatic const char * const csoundWordListDesc[] = {\n\t\"Opcodes\",\n\t\"Header Statements\",\n\t\"User keywords\",\n\t0\n};\n\nextern const LexerModule lmCsound(SCLEX_CSOUND, ColouriseCsoundDoc, \"csound\", FoldCsoundInstruments, csoundWordListDesc);\n"
  },
  {
    "path": "lexers/LexD.cxx",
    "content": "/** @file LexD.cxx\n ** Lexer for D.\n **\n ** Copyright (c) 2006 by Waldemar Augustyn <waldemar@wdmsys.com>\n ** Converted to lexer object and added further folding features/properties by \"Udo Lechner\" <dlchnr(at)gmx(dot)net>\n **/\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\n/* Nested comments require keeping the value of the nesting level for every\n   position in the document.  But since scintilla always styles line by line,\n   we only need to store one value per line. The non-negative number indicates\n   nesting level at the end of the line.\n*/\n\n// Underscore, letter, digit and universal alphas from C99 Appendix D.\n\nstatic bool IsWordStart(int ch) {\n\treturn (IsASCII(ch) && (isalpha(ch) || ch == '_')) || !IsASCII(ch);\n}\n\nstatic bool IsWord(int ch) {\n\treturn (IsASCII(ch) && (isalnum(ch) || ch == '_')) || !IsASCII(ch);\n}\n\nstatic bool IsDoxygen(int ch) {\n\tif (IsASCII(ch) && islower(ch))\n\t\treturn true;\n\tif (ch == '$' || ch == '@' || ch == '\\\\' ||\n\t\tch == '&' || ch == '#' || ch == '<' || ch == '>' ||\n\t\tch == '{' || ch == '}' || ch == '[' || ch == ']')\n\t\treturn true;\n\treturn false;\n}\n\nstatic bool IsStringSuffix(int ch) {\n\treturn ch == 'c' || ch == 'w' || ch == 'd';\n}\n\nstatic bool IsStreamCommentStyle(int style) {\n\treturn style == SCE_D_COMMENT ||\n\t\tstyle == SCE_D_COMMENTDOC ||\n\t\tstyle == SCE_D_COMMENTDOCKEYWORD ||\n\t\tstyle == SCE_D_COMMENTDOCKEYWORDERROR;\n}\n\n// An individual named option for use in an OptionSet\n\n// Options used for LexerD\nstruct OptionsD {\n\tbool fold;\n\tbool foldSyntaxBased;\n\tbool foldComment;\n\tbool foldCommentMultiline;\n\tbool foldCommentExplicit;\n\tstd::string foldExplicitStart;\n\tstd::string foldExplicitEnd;\n\tbool foldExplicitAnywhere;\n\tbool foldCompact;\n\tint  foldAtElseInt;\n\tbool foldAtElse;\n\tOptionsD() {\n\t\tfold = false;\n\t\tfoldSyntaxBased = true;\n\t\tfoldComment = false;\n\t\tfoldCommentMultiline = true;\n\t\tfoldCommentExplicit = true;\n\t\tfoldExplicitStart = \"\";\n\t\tfoldExplicitEnd   = \"\";\n\t\tfoldExplicitAnywhere = false;\n\t\tfoldCompact = true;\n\t\tfoldAtElseInt = -1;\n\t\tfoldAtElse = false;\n\t}\n};\n\nstatic const char * const dWordLists[] = {\n\t\t\t\"Primary keywords and identifiers\",\n\t\t\t\"Secondary keywords and identifiers\",\n\t\t\t\"Documentation comment keywords\",\n\t\t\t\"Type definitions and aliases\",\n\t\t\t\"Keywords 5\",\n\t\t\t\"Keywords 6\",\n\t\t\t\"Keywords 7\",\n\t\t\t0,\n\t\t};\n\nstruct OptionSetD : public OptionSet<OptionsD> {\n\tOptionSetD() {\n\t\tDefineProperty(\"fold\", &OptionsD::fold);\n\n\t\tDefineProperty(\"fold.d.syntax.based\", &OptionsD::foldSyntaxBased,\n\t\t\t\"Set this property to 0 to disable syntax based folding.\");\n\n\t\tDefineProperty(\"fold.comment\", &OptionsD::foldComment);\n\n\t\tDefineProperty(\"fold.d.comment.multiline\", &OptionsD::foldCommentMultiline,\n\t\t\t\"Set this property to 0 to disable folding multi-line comments when fold.comment=1.\");\n\n\t\tDefineProperty(\"fold.d.comment.explicit\", &OptionsD::foldCommentExplicit,\n\t\t\t\"Set this property to 0 to disable folding explicit fold points when fold.comment=1.\");\n\n\t\tDefineProperty(\"fold.d.explicit.start\", &OptionsD::foldExplicitStart,\n\t\t\t\"The string to use for explicit fold start points, replacing the standard //{.\");\n\n\t\tDefineProperty(\"fold.d.explicit.end\", &OptionsD::foldExplicitEnd,\n\t\t\t\"The string to use for explicit fold end points, replacing the standard //}.\");\n\n\t\tDefineProperty(\"fold.d.explicit.anywhere\", &OptionsD::foldExplicitAnywhere,\n\t\t\t\"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\");\n\n\t\tDefineProperty(\"fold.compact\", &OptionsD::foldCompact);\n\n\t\tDefineProperty(\"lexer.d.fold.at.else\", &OptionsD::foldAtElseInt,\n\t\t\t\"This option enables D folding on a \\\"} else {\\\" line of an if statement.\");\n\n\t\tDefineProperty(\"fold.at.else\", &OptionsD::foldAtElse);\n\n\t\tDefineWordListSets(dWordLists);\n\t}\n};\n\nclass LexerD : public DefaultLexer {\n\tbool caseSensitive;\n\tWordList keywords;\n\tWordList keywords2;\n\tWordList keywords3;\n\tWordList keywords4;\n\tWordList keywords5;\n\tWordList keywords6;\n\tWordList keywords7;\n\tOptionsD options;\n\tOptionSetD osD;\npublic:\n\tLexerD(bool caseSensitive_) :\n\t\tDefaultLexer(\"D\", SCLEX_D),\n\t\tcaseSensitive(caseSensitive_) {\n\t}\n\tvirtual ~LexerD() {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char * SCI_METHOD PropertyNames() override {\n\t\treturn osD.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osD.PropertyType(name);\n\t}\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osD.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osD.PropertyGet(key);\n\t}\n\tconst char * SCI_METHOD DescribeWordListSets() override {\n\t\treturn osD.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid * SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn 0;\n\t}\n\n\tstatic ILexer5 *LexerFactoryD() {\n\t\treturn new LexerD(true);\n\t}\n};\n\nSci_Position SCI_METHOD LexerD::PropertySet(const char *key, const char *val) {\n\tif (osD.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerD::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = 0;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywords2;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywords3;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywords4;\n\t\tbreak;\n\tcase 4:\n\t\twordListN = &keywords5;\n\t\tbreak;\n\tcase 5:\n\t\twordListN = &keywords6;\n\t\tbreak;\n\tcase 6:\n\t\twordListN = &keywords7;\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tWordList wlNew;\n\t\twlNew.Set(wl);\n\t\tif (*wordListN != wlNew) {\n\t\t\twordListN->Set(wl);\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid SCI_METHOD LexerD::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\n\tint styleBeforeDCKeyword = SCE_D_DEFAULT;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tSci_Position curLine = styler.GetLine(startPos);\n\tint curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0;\n\tbool numFloat = false; // Float literals have '+' and '-' signs\n\tbool numHex = false;\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.atLineStart) {\n\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\tstyler.SetLineState(curLine, curNcLevel);\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_D_OPERATOR:\n\t\t\t\tsc.SetState(SCE_D_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_NUMBER:\n\t\t\t\t// We accept almost anything because of hex. and number suffixes\n\t\t\t\tif (IsASCII(sc.ch) && (isalnum(sc.ch) || sc.ch == '_')) {\n\t\t\t\t\tcontinue;\n\t\t\t\t} else if (sc.ch == '.' && sc.chNext != '.' && !numFloat) {\n\t\t\t\t\t// Don't parse 0..2 as number.\n\t\t\t\t\tnumFloat=true;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else if ( ( sc.ch == '-' || sc.ch == '+' ) && (\t\t/*sign and*/\n\t\t\t\t\t( !numHex && ( sc.chPrev == 'e' || sc.chPrev == 'E' ) ) || /*decimal or*/\n\t\t\t\t\t( sc.chPrev == 'p' || sc.chPrev == 'P' ) ) ) {\t\t/*hex*/\n\t\t\t\t\t// Parse exponent sign in float literals: 2e+10 0x2e+10\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_D_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_IDENTIFIER:\n\t\t\t\tif (!IsWord(sc.ch)) {\n\t\t\t\t\tchar s[1000];\n\t\t\t\t\tif (caseSensitive) {\n\t\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t\t}\n\t\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_D_WORD);\n\t\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_D_WORD2);\n\t\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_D_TYPEDEF);\n\t\t\t\t\t} else if (keywords5.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_D_WORD5);\n\t\t\t\t\t} else if (keywords6.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_D_WORD6);\n\t\t\t\t\t} else if (keywords7.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_D_WORD7);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_D_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_COMMENT:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_D_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_COMMENTDOC:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_D_DEFAULT);\n\t\t\t\t} else if (sc.ch == '@' || sc.ch == '\\\\') { // JavaDoc and Doxygen support\n\t\t\t\t\t// Verify that we have the conditions to mark a comment-doc-keyword\n\t\t\t\t\tif ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {\n\t\t\t\t\t\tstyleBeforeDCKeyword = SCE_D_COMMENTDOC;\n\t\t\t\t\t\tsc.SetState(SCE_D_COMMENTDOCKEYWORD);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_D_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_COMMENTLINEDOC:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_D_DEFAULT);\n\t\t\t\t} else if (sc.ch == '@' || sc.ch == '\\\\') { // JavaDoc and Doxygen support\n\t\t\t\t\t// Verify that we have the conditions to mark a comment-doc-keyword\n\t\t\t\t\tif ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {\n\t\t\t\t\t\tstyleBeforeDCKeyword = SCE_D_COMMENTLINEDOC;\n\t\t\t\t\t\tsc.SetState(SCE_D_COMMENTDOCKEYWORD);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_COMMENTDOCKEYWORD:\n\t\t\t\tif ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) {\n\t\t\t\t\tsc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_D_DEFAULT);\n\t\t\t\t} else if (!IsDoxygen(sc.ch)) {\n\t\t\t\t\tchar s[100];\n\t\t\t\t\tif (caseSensitive) {\n\t\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t\t}\n\t\t\t\t\tif (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(styleBeforeDCKeyword);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_COMMENTNESTED:\n\t\t\t\tif (sc.Match('+', '/')) {\n\t\t\t\t\tif (curNcLevel > 0)\n\t\t\t\t\t\tcurNcLevel -= 1;\n\t\t\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\t\t\tstyler.SetLineState(curLine, curNcLevel);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tif (curNcLevel == 0) {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_D_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.Match('/','+')) {\n\t\t\t\t\tcurNcLevel += 1;\n\t\t\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\t\t\tstyler.SetLineState(curLine, curNcLevel);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_STRING:\n\t\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\"' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\"') {\n\t\t\t\t\tif(IsStringSuffix(sc.chNext))\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_D_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_CHARACTER:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_D_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\t// Char has no suffixes\n\t\t\t\t\tsc.ForwardSetState(SCE_D_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_STRINGEOL:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_D_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_STRINGB:\n\t\t\t\tif (sc.ch == '`') {\n\t\t\t\t\tif(IsStringSuffix(sc.chNext))\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_D_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_D_STRINGR:\n\t\t\t\tif (sc.ch == '\"') {\n\t\t\t\t\tif(IsStringSuffix(sc.chNext))\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_D_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_D_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_D_NUMBER);\n\t\t\t\tnumFloat = sc.ch == '.';\n\t\t\t\t// Remember hex literal\n\t\t\t\tnumHex = sc.ch == '0' && ( sc.chNext == 'x' || sc.chNext == 'X' );\n\t\t\t} else if ( (sc.ch == 'r' || sc.ch == 'x' || sc.ch == 'q')\n\t\t\t\t&& sc.chNext == '\"' ) {\n\t\t\t\t// Limited support for hex and delimited strings: parse as r\"\"\n\t\t\t\tsc.SetState(SCE_D_STRINGR);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (IsWordStart(sc.ch) || sc.ch == '$') {\n\t\t\t\tsc.SetState(SCE_D_IDENTIFIER);\n\t\t\t} else if (sc.Match('/','+')) {\n\t\t\t\tcurNcLevel += 1;\n\t\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\t\tstyler.SetLineState(curLine, curNcLevel);\n\t\t\t\tsc.SetState(SCE_D_COMMENTNESTED);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tif (sc.Match(\"/**\") || sc.Match(\"/*!\")) {   // Support of Qt/Doxygen doc. style\n\t\t\t\t\tsc.SetState(SCE_D_COMMENTDOC);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_D_COMMENT);\n\t\t\t\t}\n\t\t\t\tsc.Forward();   // Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tif ((sc.Match(\"///\") && !sc.Match(\"////\")) || sc.Match(\"//!\"))\n\t\t\t\t\t// Support of Qt/Doxygen doc. style\n\t\t\t\t\tsc.SetState(SCE_D_COMMENTLINEDOC);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_D_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\"') {\n\t\t\t\tsc.SetState(SCE_D_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_D_CHARACTER);\n\t\t\t} else if (sc.ch == '`') {\n\t\t\t\tsc.SetState(SCE_D_STRINGB);\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_D_OPERATOR);\n\t\t\t\tif (sc.ch == '.' && sc.chNext == '.') sc.Forward(); // Range operator\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\n\nvoid SCI_METHOD LexerD::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\n\tif (!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelMinCurrent = levelCurrent;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tbool foldAtElse = options.foldAtElseInt >= 0 ? options.foldAtElseInt != 0 : options.foldAtElse;\n\tconst bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (options.foldComment && options.foldCommentExplicit && ((style == SCE_D_COMMENTLINE) || options.foldExplicitAnywhere)) {\n\t\t\tif (userDefinedFoldMarkers) {\n\t\t\t\tif (styler.Match(i, options.foldExplicitStart.c_str())) {\n \t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {\n \t\t\t\t\tlevelNext--;\n \t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ((ch == '/') && (chNext == '/')) {\n\t\t\t\t\tchar chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t}\n\t\t\t\t}\n \t\t\t}\n \t\t}\n\t\tif (options.foldSyntaxBased && (style == SCE_D_OPERATOR)) {\n\t\t\tif (ch == '{') {\n\t\t\t\t// Measure the minimum before a '{' to allow\n\t\t\t\t// folding on \"} else {\"\n\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t}\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL || (i == endPos-1)) {\n\t\t\tif (options.foldComment && options.foldCommentMultiline) {  // Handle nested comments\n\t\t\t\tint nc;\n\t\t\t\tnc =  styler.GetLineState(lineCurrent);\n\t\t\t\tnc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;\n\t\t\t\tlevelNext += nc;\n\t\t\t}\n\t\t\tint levelUse = levelCurrent;\n\t\t\tif (options.foldSyntaxBased && foldAtElse) {\n\t\t\t\tlevelUse = levelMinCurrent;\n\t\t\t}\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && options.foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelMinCurrent = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\t}\n}\n\nextern const LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, \"d\", dWordLists);\n"
  },
  {
    "path": "lexers/LexDMAP.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexDMAP.cxx\n ** Lexer for MSC Nastran DMAP.\n ** Written by Mark Robinson, based on the Fortran lexer by Chuan-jian Shen, Last changed Aug. 2013\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n/***************************************/\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n/***************************************/\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n/***************************************/\n\n#if defined(__clang__)\n#if __has_warning(\"-Wunused-but-set-variable\")\n// Disable warning for numNonBlank\n#pragma clang diagnostic ignored \"-Wunused-but-set-variable\"\n#endif\n#endif\n\nusing namespace Lexilla;\n\n/***********************************************/\nstatic inline bool IsAWordChar(const int ch) {\n    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');\n}\n/**********************************************/\nstatic inline bool IsAWordStart(const int ch) {\n    return (ch < 0x80) && (isalnum(ch));\n}\n/***************************************/\nstatic void ColouriseDMAPDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n            WordList *keywordlists[], Accessor &styler) {\n    WordList &keywords = *keywordlists[0];\n    WordList &keywords2 = *keywordlists[1];\n    WordList &keywords3 = *keywordlists[2];\n    /***************************************/\n    Sci_Position posLineStart = 0, numNonBlank = 0;\n    Sci_Position endPos = startPos + length;\n    /***************************************/\n    // backtrack to the nearest keyword\n    while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_DMAP_WORD)) {\n        startPos--;\n    }\n    startPos = styler.LineStart(styler.GetLine(startPos));\n    initStyle = styler.StyleAt(startPos - 1);\n    StyleContext sc(startPos, endPos-startPos, initStyle, styler);\n    /***************************************/\n    for (; sc.More(); sc.Forward()) {\n        // remember the start position of the line\n        if (sc.atLineStart) {\n            posLineStart = sc.currentPos;\n            numNonBlank = 0;\n            sc.SetState(SCE_DMAP_DEFAULT);\n        }\n        if (!IsASpaceOrTab(sc.ch)) numNonBlank ++;\n        /***********************************************/\n        // Handle data appearing after column 72; it is ignored\n        Sci_Position toLineStart = sc.currentPos - posLineStart;\n        if (toLineStart >= 72 || sc.ch == '$') {\n            sc.SetState(SCE_DMAP_COMMENT);\n            while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end\n            continue;\n        }\n        /***************************************/\n        // Determine if the current state should terminate.\n        if (sc.state == SCE_DMAP_OPERATOR) {\n            sc.SetState(SCE_DMAP_DEFAULT);\n        } else if (sc.state == SCE_DMAP_NUMBER) {\n            if (!(IsAWordChar(sc.ch) || sc.ch=='\\'' || sc.ch=='\\\"' || sc.ch=='.')) {\n                sc.SetState(SCE_DMAP_DEFAULT);\n            }\n        } else if (sc.state == SCE_DMAP_IDENTIFIER) {\n            if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {\n                char s[100];\n                sc.GetCurrentLowered(s, sizeof(s));\n                if (keywords.InList(s)) {\n                    sc.ChangeState(SCE_DMAP_WORD);\n                } else if (keywords2.InList(s)) {\n                    sc.ChangeState(SCE_DMAP_WORD2);\n                } else if (keywords3.InList(s)) {\n                    sc.ChangeState(SCE_DMAP_WORD3);\n                }\n                sc.SetState(SCE_DMAP_DEFAULT);\n            }\n        } else if (sc.state == SCE_DMAP_COMMENT) {\n            if (sc.ch == '\\r' || sc.ch == '\\n') {\n                sc.SetState(SCE_DMAP_DEFAULT);\n            }\n        } else if (sc.state == SCE_DMAP_STRING1) {\n            if (sc.ch == '\\'') {\n                if (sc.chNext == '\\'') {\n                    sc.Forward();\n                } else {\n                    sc.ForwardSetState(SCE_DMAP_DEFAULT);\n                }\n            } else if (sc.atLineEnd) {\n                sc.ChangeState(SCE_DMAP_STRINGEOL);\n                sc.ForwardSetState(SCE_DMAP_DEFAULT);\n            }\n        } else if (sc.state == SCE_DMAP_STRING2) {\n            if (sc.atLineEnd) {\n                sc.ChangeState(SCE_DMAP_STRINGEOL);\n                sc.ForwardSetState(SCE_DMAP_DEFAULT);\n            } else if (sc.ch == '\\\"') {\n                if (sc.chNext == '\\\"') {\n                    sc.Forward();\n                } else {\n                    sc.ForwardSetState(SCE_DMAP_DEFAULT);\n                }\n            }\n        }\n        /***************************************/\n        // Determine if a new state should be entered.\n        if (sc.state == SCE_DMAP_DEFAULT) {\n            if (sc.ch == '$') {\n                sc.SetState(SCE_DMAP_COMMENT);\n            } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)) || (sc.ch == '-' && IsADigit(sc.chNext))) {\n                sc.SetState(SCE_F_NUMBER);\n            } else if (IsAWordStart(sc.ch)) {\n                sc.SetState(SCE_DMAP_IDENTIFIER);\n            } else if (sc.ch == '\\\"') {\n                sc.SetState(SCE_DMAP_STRING2);\n            } else if (sc.ch == '\\'') {\n                sc.SetState(SCE_DMAP_STRING1);\n            } else if (isoperator(static_cast<char>(sc.ch))) {\n                sc.SetState(SCE_DMAP_OPERATOR);\n            }\n        }\n    }\n    sc.Complete();\n}\n/***************************************/\n// To determine the folding level depending on keywords\nstatic int classifyFoldPointDMAP(const char* s, const char* prevWord) {\n    int lev = 0;\n    if ((strcmp(prevWord, \"else\") == 0 && strcmp(s, \"if\") == 0) || strcmp(s, \"enddo\") == 0 || strcmp(s, \"endif\") == 0) {\n        lev = -1;\n    } else if ((strcmp(prevWord, \"do\") == 0 && strcmp(s, \"while\") == 0) || strcmp(s, \"then\") == 0) {\n        lev = 1;\n    }\n    return lev;\n}\n// Folding the code\nstatic void FoldDMAPDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                           WordList *[], Accessor &styler) {\n    //\n    // bool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n    // Do not know how to fold the comment at the moment.\n    //\n    bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n    Sci_PositionU endPos = startPos + length;\n    int visibleChars = 0;\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n    int levelCurrent = levelPrev;\n    char chNext = styler[startPos];\n    int styleNext = styler.StyleAt(startPos);\n    int style = initStyle;\n    /***************************************/\n    Sci_Position lastStart = 0;\n    char prevWord[32] = \"\";\n    /***************************************/\n    for (Sci_PositionU i = startPos; i < endPos; i++) {\n        char ch = chNext;\n        chNext = styler.SafeGetCharAt(i + 1);\n        int stylePrev = style;\n        style = styleNext;\n        styleNext = styler.StyleAt(i + 1);\n        bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n        //\n        if ((stylePrev == SCE_DMAP_DEFAULT || stylePrev == SCE_DMAP_OPERATOR || stylePrev == SCE_DMAP_COMMENT) && (style == SCE_DMAP_WORD)) {\n            // Store last word and label start point.\n            lastStart = i;\n        }\n        /***************************************/\n        if (style == SCE_DMAP_WORD) {\n            if(iswordchar(ch) && !iswordchar(chNext)) {\n                char s[32];\n                Sci_PositionU k;\n                for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {\n                    s[k] = static_cast<char>(tolower(styler[lastStart+k]));\n                }\n                s[k] = '\\0';\n                levelCurrent += classifyFoldPointDMAP(s, prevWord);\n                strcpy(prevWord, s);\n            }\n        }\n        if (atEOL) {\n            int lev = levelPrev;\n            if (visibleChars == 0 && foldCompact)\n                lev |= SC_FOLDLEVELWHITEFLAG;\n            if ((levelCurrent > levelPrev) && (visibleChars > 0))\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            if (lev != styler.LevelAt(lineCurrent)) {\n                styler.SetLevel(lineCurrent, lev);\n            }\n            lineCurrent++;\n            levelPrev = levelCurrent;\n            visibleChars = 0;\n            strcpy(prevWord, \"\");\n        }\n        /***************************************/\n        if (!isspacechar(ch)) visibleChars++;\n    }\n    /***************************************/\n    // Fill in the real level of the next line, keeping the current flags as they will be filled in later\n    int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n    styler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n/***************************************/\nstatic const char * const DMAPWordLists[] = {\n    \"Primary keywords and identifiers\",\n    \"Intrinsic functions\",\n    \"Extended and user defined functions\",\n    0,\n};\n/***************************************/\nextern const LexerModule lmDMAP(SCLEX_DMAP, ColouriseDMAPDoc, \"DMAP\", FoldDMAPDoc, DMAPWordLists);\n"
  },
  {
    "path": "lexers/LexDMIS.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexDMIS.cxx\n ** Lexer for DMIS.\n  **/\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// Copyright 2013-2014 by Andreas Tscharner <andy@vis.ethz.ch>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Lexilla;\n\n\nstatic const char *const DMISWordListDesc[] = {\n\t\"DMIS Major Words\",\n\t\"DMIS Minor Words\",\n\t\"Unsupported DMIS Major Words\",\n\t\"Unsupported DMIS Minor Words\",\n\t\"Keywords for code folding start\",\n\t\"Corresponding keywords for code folding end\",\n\t0\n};\n\n\nclass LexerDMIS : public DefaultLexer\n{\n\tprivate:\n\t\tchar *m_wordListSets;\n\t\tWordList m_majorWords;\n\t\tWordList m_minorWords;\n\t\tWordList m_unsupportedMajor;\n\t\tWordList m_unsupportedMinor;\n\t\tWordList m_codeFoldingStart;\n\t\tWordList m_codeFoldingEnd;\n\n\t\tchar * SCI_METHOD UpperCase(char *item);\n\t\tvoid SCI_METHOD InitWordListSets(void);\n\n\tpublic:\n\t\tLexerDMIS(void);\n\t\tvirtual ~LexerDMIS(void);\n\n\t\tint SCI_METHOD Version() const override {\n\t\t\treturn Scintilla::lvRelease5;\n\t\t}\n\n\t\tvoid SCI_METHOD Release() override {\n\t\t\tdelete this;\n\t\t}\n\n\t\tconst char * SCI_METHOD PropertyNames() override {\n\t\t\treturn NULL;\n\t\t}\n\n\t\tint SCI_METHOD PropertyType(const char *) override {\n\t\t\treturn -1;\n\t\t}\n\n\t\tconst char * SCI_METHOD DescribeProperty(const char *) override {\n\t\t\treturn NULL;\n\t\t}\n\n\t\tSci_Position SCI_METHOD PropertySet(const char *, const char *) override {\n\t\t\treturn -1;\n\t\t}\n\n\t\tconst char * SCI_METHOD PropertyGet(const char *) override {\n\t\t\treturn NULL;\n\t\t}\n\n\t\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n\t\tvoid * SCI_METHOD PrivateCall(int, void *) override {\n\t\t\treturn NULL;\n\t\t}\n\n\t\tstatic ILexer5 *LexerFactoryDMIS() {\n\t\t\treturn new LexerDMIS;\n\t\t}\n\n\t\tconst char * SCI_METHOD DescribeWordListSets() override;\n\t\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override;\n\t\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override;\n};\n\n\nchar * SCI_METHOD LexerDMIS::UpperCase(char *item)\n{\n\tchar *itemStart;\n\n\n\titemStart = item;\n\twhile (item && *item) {\n\t\t*item = toupper(*item);\n\t\titem++;\n\t};\n\treturn itemStart;\n}\n\nvoid SCI_METHOD LexerDMIS::InitWordListSets(void)\n{\n\tsize_t totalLen = 0;\n\n\n\tfor (int i=0; DMISWordListDesc[i]; i++) {\n\t\ttotalLen += strlen(DMISWordListDesc[i]);\n\t\ttotalLen++;\n\t};\n\n\ttotalLen++;\n\tthis->m_wordListSets = new char[totalLen];\n\tmemset(this->m_wordListSets, 0, totalLen);\n\n\tfor (int i=0; DMISWordListDesc[i]; i++) {\n\t\tstrcat(this->m_wordListSets, DMISWordListDesc[i]);\n\t\tstrcat(this->m_wordListSets, \"\\n\");\n\t};\n}\n\n\nLexerDMIS::LexerDMIS(void) : DefaultLexer(\"DMIS\", SCLEX_DMIS) {\n\tthis->InitWordListSets();\n\n\tthis->m_majorWords.Clear();\n\tthis->m_minorWords.Clear();\n\tthis->m_unsupportedMajor.Clear();\n\tthis->m_unsupportedMinor.Clear();\n\tthis->m_codeFoldingStart.Clear();\n\tthis->m_codeFoldingEnd.Clear();\n}\n\nLexerDMIS::~LexerDMIS(void) {\n\tdelete[] this->m_wordListSets;\n}\n\nSci_Position SCI_METHOD LexerDMIS::WordListSet(int n, const char *wl)\n{\n\tswitch (n) {\n\t\tcase 0:\n\t\t\tthis->m_majorWords.Clear();\n\t\t\tthis->m_majorWords.Set(wl);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tthis->m_minorWords.Clear();\n\t\t\tthis->m_minorWords.Set(wl);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tthis->m_unsupportedMajor.Clear();\n\t\t\tthis->m_unsupportedMajor.Set(wl);\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tthis->m_unsupportedMinor.Clear();\n\t\t\tthis->m_unsupportedMinor.Set(wl);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tthis->m_codeFoldingStart.Clear();\n\t\t\tthis->m_codeFoldingStart.Set(wl);\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tthis->m_codeFoldingEnd.Clear();\n\t\t\tthis->m_codeFoldingEnd.Set(wl);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn -1;\n\t\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nconst char * SCI_METHOD LexerDMIS::DescribeWordListSets()\n{\n\treturn this->m_wordListSets;\n}\n\nvoid SCI_METHOD LexerDMIS::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess)\n{\n\tconst Sci_PositionU MAX_STR_LEN = 100;\n\n\tLexAccessor styler(pAccess);\n\tStyleContext scCTX(startPos, lengthDoc, initStyle, styler);\n\tCharacterSet setDMISNumber(CharacterSet::setDigits, \".-+eE\");\n\tCharacterSet setDMISWordStart(CharacterSet::setAlpha, \"-234\", 0x80, true);\n\tCharacterSet setDMISWord(CharacterSet::setAlpha);\n\n\n\tbool isIFLine = false;\n\n\tfor (; scCTX.More(); scCTX.Forward()) {\n\t\tif (scCTX.atLineEnd) {\n\t\t\tisIFLine = false;\n\t\t};\n\n\t\tswitch (scCTX.state) {\n\t\t\tcase SCE_DMIS_DEFAULT:\n\t\t\t\tif (scCTX.Match('$', '$')) {\n\t\t\t\t\tscCTX.SetState(SCE_DMIS_COMMENT);\n\t\t\t\t\tscCTX.Forward();\n\t\t\t\t};\n\t\t\t\tif (scCTX.Match('\\'')) {\n\t\t\t\t\tscCTX.SetState(SCE_DMIS_STRING);\n\t\t\t\t};\n\t\t\t\tif (IsADigit(scCTX.ch) || ((scCTX.Match('-') || scCTX.Match('+')) && IsADigit(scCTX.chNext))) {\n\t\t\t\t\tscCTX.SetState(SCE_DMIS_NUMBER);\n\t\t\t\t\tbreak;\n\t\t\t\t};\n\t\t\t\tif (setDMISWordStart.Contains(scCTX.ch)) {\n\t\t\t\t\tscCTX.SetState(SCE_DMIS_KEYWORD);\n\t\t\t\t};\n\t\t\t\tif (scCTX.Match('(') && (!isIFLine)) {\n\t\t\t\t\tscCTX.SetState(SCE_DMIS_LABEL);\n\t\t\t\t};\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_DMIS_COMMENT:\n\t\t\t\tif (scCTX.atLineEnd) {\n\t\t\t\t\tscCTX.SetState(SCE_DMIS_DEFAULT);\n\t\t\t\t};\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_DMIS_STRING:\n\t\t\t\tif (scCTX.Match('\\'')) {\n\t\t\t\t\tscCTX.SetState(SCE_DMIS_DEFAULT);\n\t\t\t\t};\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_DMIS_NUMBER:\n\t\t\t\tif (!setDMISNumber.Contains(scCTX.ch)) {\n\t\t\t\t\tscCTX.SetState(SCE_DMIS_DEFAULT);\n\t\t\t\t};\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_DMIS_KEYWORD:\n\t\t\t\tif (!setDMISWord.Contains(scCTX.ch)) {\n\t\t\t\t\tchar tmpStr[MAX_STR_LEN];\n\t\t\t\t\tmemset(tmpStr, 0, MAX_STR_LEN*sizeof(char));\n\t\t\t\t\tscCTX.GetCurrent(tmpStr, (MAX_STR_LEN-1));\n\t\t\t\t\t// The following strncpy is copying from a string back onto itself which is weird and causes warnings\n\t\t\t\t\t// but is harmless so turn off the warning\n#if defined(__GNUC__) && !defined(__clang__)\n// Disable warning for strncpy\n#pragma GCC diagnostic ignored \"-Wrestrict\"\n#endif\n\t\t\t\t\tstrncpy(tmpStr, this->UpperCase(tmpStr), (MAX_STR_LEN-1));\n\n\t\t\t\t\tif (this->m_minorWords.InList(tmpStr)) {\n\t\t\t\t\t\tscCTX.ChangeState(SCE_DMIS_MINORWORD);\n\t\t\t\t\t};\n\t\t\t\t\tif (this->m_majorWords.InList(tmpStr)) {\n\t\t\t\t\t\tisIFLine = (strcmp(tmpStr, \"IF\") == 0);\n\t\t\t\t\t\tscCTX.ChangeState(SCE_DMIS_MAJORWORD);\n\t\t\t\t\t};\n\t\t\t\t\tif (this->m_unsupportedMajor.InList(tmpStr)) {\n\t\t\t\t\t\tscCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MAJOR);\n\t\t\t\t\t};\n\t\t\t\t\tif (this->m_unsupportedMinor.InList(tmpStr)) {\n\t\t\t\t\t\tscCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MINOR);\n\t\t\t\t\t};\n\n\t\t\t\t\tif (scCTX.Match('(') && (!isIFLine)) {\n\t\t\t\t\t\tscCTX.SetState(SCE_DMIS_LABEL);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tscCTX.SetState(SCE_DMIS_DEFAULT);\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_DMIS_LABEL:\n\t\t\t\tif (scCTX.Match(')')) {\n\t\t\t\t\tscCTX.SetState(SCE_DMIS_DEFAULT);\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t};\n\t};\n\tscCTX.Complete();\n}\n\nvoid SCI_METHOD LexerDMIS::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int, Scintilla::IDocument *pAccess)\n{\n\tconst int MAX_STR_LEN = 100;\n\n\tLexAccessor styler(pAccess);\n\tSci_PositionU endPos = startPos + lengthDoc;\n\tchar chNext = styler[startPos];\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tint strPos = 0;\n\tbool foldWordPossible = false;\n\tCharacterSet setDMISFoldWord(CharacterSet::setAlpha);\n\tchar *tmpStr;\n\n\n\ttmpStr = new char[MAX_STR_LEN];\n\tmemset(tmpStr, 0, MAX_STR_LEN*sizeof(char));\n\n\tfor (Sci_PositionU i=startPos; i<endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i+1);\n\n\t\tbool atEOL = ((ch == '\\r' && chNext != '\\n') || (ch == '\\n'));\n\n\t\tif (strPos >= (MAX_STR_LEN-1)) {\n\t\t\tstrPos = MAX_STR_LEN-1;\n\t\t};\n\n\t\tint style = styler.StyleAt(i);\n\t\tbool noFoldPos = ((style == SCE_DMIS_COMMENT) || (style == SCE_DMIS_STRING));\n\n\t\tif (foldWordPossible) {\n\t\t\tif (setDMISFoldWord.Contains(ch)) {\n\t\t\t\ttmpStr[strPos++] = ch;\n\t\t\t} else {\n\t\t\t\ttmpStr = this->UpperCase(tmpStr);\n\t\t\t\tif (this->m_codeFoldingStart.InList(tmpStr) && (!noFoldPos)) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t};\n\t\t\t\tif (this->m_codeFoldingEnd.InList(tmpStr) && (!noFoldPos)) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t};\n\t\t\t\tmemset(tmpStr, 0, MAX_STR_LEN*sizeof(char));\n\t\t\t\tstrPos = 0;\n\t\t\t\tfoldWordPossible = false;\n\t\t\t};\n\t\t} else {\n\t\t\tif (setDMISFoldWord.Contains(ch)) {\n\t\t\t\ttmpStr[strPos++] = ch;\n\t\t\t\tfoldWordPossible = true;\n\t\t\t};\n\t\t};\n\n\t\tif (atEOL || (i == (endPos-1))) {\n\t\t\tint lev = levelPrev;\n\n\t\t\tif (levelCurrent > levelPrev) {\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t};\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t};\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t};\n\t};\n\tdelete[] tmpStr;\n}\n\n\nextern const LexerModule lmDMIS(SCLEX_DMIS, LexerDMIS::LexerFactoryDMIS, \"DMIS\", DMISWordListDesc);\n"
  },
  {
    "path": "lexers/LexDart.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexDart.cxx\n ** Lexer for Dart.\n **/\n// Based on Zufu Liu's Notepad4 Dart lexer\n// Modified for Scintilla by Jiri Techet, 2024\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n// Use an unnamed namespace to protect the functions and classes from name conflicts\n\nconstexpr bool IsEOLChar(int ch) noexcept {\n\treturn ch == '\\r' || ch == '\\n';\n}\n\nconstexpr bool IsAGraphic(int ch) noexcept {\n\t// excludes C0 control characters and whitespace\n\treturn ch > 32 && ch < 127;\n}\n\nconstexpr bool IsIdentifierChar(int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '_';\n}\n\nconstexpr bool IsIdentifierStart(int ch) noexcept {\n\treturn IsUpperOrLowerCase(ch) || ch == '_';\n}\n\nconstexpr bool IsNumberContinue(int chPrev, int ch, int chNext) noexcept {\n\treturn ((ch == '+' || ch == '-') && (chPrev == 'e' || chPrev == 'E'))\n\t\t|| (ch == '.' && chNext != '.');\n}\n\nconstexpr bool IsNumberStart(int ch, int chNext) noexcept {\n\treturn IsADigit(ch) || (ch == '.' && IsADigit(chNext));\n}\n\nconstexpr bool IsDecimalNumber(int chPrev, int ch, int chNext) noexcept {\n\treturn IsIdentifierChar(ch) || IsNumberContinue(chPrev, ch, chNext);\n}\n\nstruct EscapeSequence {\n\tint outerState = SCE_DART_DEFAULT;\n\tint digitsLeft = 0;\n\tbool brace = false;\n\n\t// highlight any character as escape sequence.\n\tbool resetEscapeState(int state, int chNext) noexcept {\n\t\tif (IsEOLChar(chNext)) {\n\t\t\treturn false;\n\t\t}\n\t\touterState = state;\n\t\tbrace = false;\n\t\tdigitsLeft = (chNext == 'x')? 3 : ((chNext == 'u') ? 5 : 1);\n\t\treturn true;\n\t}\n\tbool atEscapeEnd(int ch) noexcept {\n\t\t--digitsLeft;\n\t\treturn digitsLeft <= 0 || !IsAHeXDigit(ch);\n\t}\n};\n\nconstexpr bool IsDartIdentifierStart(int ch) noexcept {\n\treturn IsIdentifierStart(ch) || ch == '$';\n}\n\nconstexpr bool IsDartIdentifierChar(int ch) noexcept {\n\treturn IsIdentifierChar(ch) || ch == '$';\n}\n\nconstexpr bool IsDefinableOperator(int ch) noexcept {\n\t// https://github.com/dart-lang/sdk/blob/main/sdk/lib/core/symbol.dart\n\treturn AnyOf(ch, '+', '-', '*', '/', '%', '~', '&', '|',\n\t\t\t\t\t '^', '<', '>', '=', '[', ']');\n}\n\nconstexpr bool IsSpaceEquiv(int state) noexcept {\n\treturn state == SCE_DART_DEFAULT ||\n\t\tstate == SCE_DART_COMMENTLINE ||\n\t\tstate == SCE_DART_COMMENTLINEDOC ||\n\t\tstate == SCE_DART_COMMENTBLOCK ||\n\t\tstate == SCE_DART_COMMENTBLOCKDOC;\n}\n\nconstexpr bool IsTripleString(int state) noexcept {\n\treturn state == SCE_DART_TRIPLE_STRING_SQ ||\n\t\tstate == SCE_DART_TRIPLE_STRING_DQ ||\n\t\tstate == SCE_DART_TRIPLE_RAWSTRING_SQ ||\n\t\tstate == SCE_DART_TRIPLE_RAWSTRING_DQ;\n}\n\nconstexpr bool IsDoubleQuoted(int state) noexcept {\n\treturn state == SCE_DART_STRING_DQ ||\n\t\tstate == SCE_DART_RAWSTRING_DQ ||\n\t\tstate == SCE_DART_TRIPLE_STRING_DQ ||\n\t\tstate == SCE_DART_TRIPLE_RAWSTRING_DQ;\n}\n\nconstexpr bool IsRaw(int state) noexcept {\n\treturn state == SCE_DART_RAWSTRING_SQ ||\n\t\tstate == SCE_DART_RAWSTRING_DQ ||\n\t\tstate == SCE_DART_TRIPLE_RAWSTRING_SQ ||\n\t\tstate == SCE_DART_TRIPLE_RAWSTRING_DQ;\n}\n\nconstexpr int GetStringQuote(int state) noexcept {\n\treturn IsDoubleQuoted(state) ? '\\\"' : '\\'';\n}\n\nenum {\n\tDartLineStateMaskLineComment = 1,\t\t\t// line comment\n\tDartLineStateMaskImport = (1 << 1),\t\t\t// import\n\tDartLineStateMaskInterpolation = (1 << 2),\t// string interpolation\n};\n\n// string interpolating state\nstruct InterpolatingState {\n\tint state;\n\tint braceCount;\n};\n\nstruct FoldLineState {\n\tint lineComment;\n\tint packageImport;\n\tconstexpr explicit FoldLineState(int lineState) noexcept:\n\t\tlineComment(lineState & DartLineStateMaskLineComment),\n\t\tpackageImport((lineState >> 1) & 1) {\n\t}\n};\n\n// Options used for LexerDart\nstruct OptionsDart {\n\tbool fold = false;\n};\n\nconst char * const dartWordListDesc[] = {\n\t\"Primary keywords\",\n\t\"Secondary keywords\",\n\t\"Tertiary keywords\",\n\t\"Global type definitions\",\n\tnullptr\n};\n\nstruct OptionSetDart : public OptionSet<OptionsDart> {\n\tOptionSetDart() {\n\t\tDefineProperty(\"fold\", &OptionsDart::fold);\n\n\t\tDefineWordListSets(dartWordListDesc);\n\t}\n};\n\n\nLexicalClass lexicalClasses[] = {\n\t// Lexer DART SCLEX_DART SCE_DART_:\n\t0, \"SCE_DART_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_DART_COMMENTLINE\", \"comment line\", \"Comment: //\",\n\t2, \"SCE_DART_COMMENTLINEDOC\", \"comment line documentation\", \"Comment: ///\",\n\t3, \"SCE_DART_COMMENTBLOCK\", \"comment\", \"Comment: /* */\",\n\t4, \"SCE_DART_COMMENTBLOCKDOC\", \"comment documentation\", \"Comment: /** */\",\n\t5, \"SCE_DART_STRING_SQ\", \"literal string\", \"Single quoted string\",\n\t6, \"SCE_DART_STRING_DQ\", \"literal string\", \"Double quoted string\",\n\t7, \"SCE_DART_TRIPLE_STRING_SQ\", \"literal string multiline\", \"Single quoted multiline string\",\n\t8, \"SCE_DART_TRIPLE_STRING_DQ\", \"literal string multiline\", \"Double quoted multiline string\",\n\t9, \"SCE_DART_RAWSTRING_SQ\", \"literal string raw\", \"Single quoted raw string\",\n\t10, \"SCE_DART_RAWSTRING_DQ\", \"literal string raw\", \"Double quoted raw string\",\n\t11, \"SCE_DART_TRIPLE_RAWSTRING_SQ\", \"literal string multiline raw\", \"Single quoted multiline raw string\",\n\t12, \"SCE_DART_TRIPLE_RAWSTRING_DQ\", \"literal string multiline raw\", \"Double quoted multiline raw string\",\n\t13, \"SCE_DART_ESCAPECHAR\", \"literal string escapesequence\", \"Escape sequence\",\n\t14, \"SCE_DART_IDENTIFIER\", \"identifier\", \"Identifier\",\n\t15, \"SCE_DART_IDENTIFIER_STRING\", \"identifier interpolated\", \"Identifier following $ inside strings\",\n\t16, \"SCE_DART_OPERATOR\", \"operator\", \"Operator\",\n\t17, \"SCE_DART_OPERATOR_STRING\", \"operator interpolated\", \"Braces following $ inside string\",\n\t18, \"SCE_DART_SYMBOL_IDENTIFIER\", \"identifier symbol\", \"Symbol name introduced by #\",\n\t19, \"SCE_DART_SYMBOL_OPERATOR\", \"operator symbol\", \"Operator introduced by #\",\n\t20, \"SCE_DART_NUMBER\", \"literal numeric\", \"Number\",\n\t21, \"SCE_DART_KEY\", \"key\", \"Keys preceding ':' and named parameters\",\n\t22, \"SCE_DART_METADATA\", \"preprocessor\", \"Metadata introduced by @\",\n\t23, \"SCE_DART_KW_PRIMARY\", \"keyword\", \"Primary keywords\",\n\t24, \"SCE_DART_KW_SECONDARY\", \"identifier\", \"Secondary keywords\",\n\t25, \"SCE_DART_KW_TERTIARY\", \"identifier\", \"Tertiary keywords\",\n\t26, \"SCE_DART_KW_TYPE\", \"identifier\", \"Global types\",\n\t27, \"SCE_DART_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n};\n\nclass LexerDart : public DefaultLexer {\n\tWordList keywordsPrimary;\n\tWordList keywordsSecondary;\n\tWordList keywordsTertiary;\n\tWordList keywordsTypes;\n\tOptionsDart options;\n\tOptionSetDart osDart;\npublic:\n\tLexerDart(const char *languageName_, int language_) :\n\t\tDefaultLexer(languageName_, language_, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\t// Deleted so LexerDart objects can not be copied.\n\tLexerDart(const LexerDart &) = delete;\n\tLexerDart(LexerDart &&) = delete;\n\tvoid operator=(const LexerDart &) = delete;\n\tvoid operator=(LexerDart &&) = delete;\n\t~LexerDart() override = default;\n\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osDart.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osDart.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osDart.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osDart.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osDart.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn nullptr;\n\t}\n\n\tvoid BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle);\n\tSci_PositionU LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite);\n\n\tstatic ILexer5 *LexerFactoryDart() {\n\t\treturn new LexerDart(\"dart\", SCLEX_DART);\n\t}\n};\n\nSci_Position SCI_METHOD LexerDart::PropertySet(const char *key, const char *val) {\n\tif (osDart.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerDart::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywordsPrimary;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywordsSecondary;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywordsTertiary;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywordsTypes;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN && wordListN->Set(wl, false)) {\n\t\tfirstModification = 0;\n\t}\n\treturn firstModification;\n}\n\nvoid LexerDart::BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle) {\n\tconst Sci_Position currentLine = styler.GetLine(startPos);\n\tif (currentLine != 0) {\n\t\tSci_Position line = currentLine - 1;\n\t\tint lineState = styler.GetLineState(line);\n\t\twhile ((lineState & stateMask) != 0 && line != 0) {\n\t\t\t--line;\n\t\t\tlineState = styler.GetLineState(line);\n\t\t}\n\t\tif ((lineState & stateMask) == 0) {\n\t\t\t++line;\n\t\t}\n\t\tif (line != currentLine) {\n\t\t\tconst Sci_PositionU endPos = startPos + lengthDoc;\n\t\t\tstartPos = (line == 0) ? 0 : styler.LineStart(line);\n\t\t\tlengthDoc = endPos - startPos;\n\t\t\tinitStyle = (startPos == 0) ? 0 : styler.StyleAt(startPos - 1);\n\t\t}\n\t}\n}\n\nSci_PositionU LexerDart::LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite) {\n\tdo {\n\t\t--startPos;\n\t\tconst unsigned style = styler.StyleAt(startPos);\n\t\tif (!IsSpaceEquiv(style)) {\n\t\t\tstylePrevNonWhite = style;\n\t\t\tchPrevNonWhite = static_cast<unsigned char>(styler[startPos]);\n\t\t\tbreak;\n\t\t}\n\t} while (startPos != 0);\n\treturn startPos;\n}\n\nvoid LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\n\tint lineStateLineType = 0;\n\tint commentLevel = 0;\t// nested block comment level\n\n\tstd::vector<InterpolatingState> interpolatingStack;\n\n\tint visibleChars = 0;\n\tint chBefore = 0;\n\tint chPrevNonWhite = 0;\n\tEscapeSequence escSeq;\n\n\tif (initStyle == SCE_DART_STRINGEOL) {\n\t\tinitStyle = SCE_DART_DEFAULT;\n\t}\n\n\tif (startPos != 0) {\n\t\t// backtrack to the line where interpolation starts\n\t\tBacktrackToStart(styler, DartLineStateMaskInterpolation, startPos, lengthDoc, initStyle);\n\t}\n\n\tStyleContext sc(startPos, lengthDoc, initStyle, styler);\n\tif (sc.currentLine > 0) {\n\t\tconst int lineState = styler.GetLineState(sc.currentLine - 1);\n\t\tcommentLevel = lineState >> 4;\n\t}\n\tif (startPos == 0) {\n\t\tif (sc.Match('#', '!')) {\n\t\t\t// Shell Shebang at beginning of file\n\t\t\tsc.SetState(SCE_DART_COMMENTLINE);\n\t\t\tsc.Forward();\n\t\t\tlineStateLineType = DartLineStateMaskLineComment;\n\t\t}\n\t} else if (IsSpaceEquiv(initStyle)) {\n\t\tLookbackNonWhite(styler, startPos, chPrevNonWhite, initStyle);\n\t\tchBefore = chPrevNonWhite;\n\t}\n\n\twhile (sc.More()) {\n\t\tswitch (sc.state) {\n\t\tcase SCE_DART_OPERATOR:\n\t\tcase SCE_DART_OPERATOR_STRING:\n\t\t\tsc.SetState(SCE_DART_DEFAULT);\n\t\t\tbreak;\n\n\t\tcase SCE_DART_NUMBER:\n\t\t\tif (!IsDecimalNumber(sc.chPrev, sc.ch, sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_DART_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_DART_IDENTIFIER:\n\t\tcase SCE_DART_IDENTIFIER_STRING:\n\t\tcase SCE_DART_METADATA:\n\t\tcase SCE_DART_SYMBOL_IDENTIFIER:\n\t\t\tif (!IsDartIdentifierChar(sc.ch) || (sc.ch == '$' && sc.state == SCE_DART_IDENTIFIER_STRING)) {\n\t\t\t\tif (sc.state == SCE_DART_METADATA || sc.state == SCE_DART_SYMBOL_IDENTIFIER) {\n\t\t\t\t\tif (sc.ch == '.') {\n\t\t\t\t\t\tconst int state = sc.state;\n\t\t\t\t\t\tsc.SetState(SCE_DART_OPERATOR);\n\t\t\t\t\t\tsc.ForwardSetState(state);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tchar s[64];\n\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\tconst int state = sc.state;\n\t\t\t\t\tif (state == SCE_DART_IDENTIFIER_STRING) {\n\t\t\t\t\t\tsc.SetState(escSeq.outerState);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else if (keywordsPrimary.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_DART_KW_PRIMARY);\n\t\t\t\t\t\tif (strcmp(s, \"import\") == 0 || strcmp(s, \"part\") == 0) {\n\t\t\t\t\t\t\tif (visibleChars == sc.LengthCurrent()) {\n\t\t\t\t\t\t\t\tlineStateLineType = DartLineStateMaskImport;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (keywordsSecondary.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_DART_KW_SECONDARY);\n\t\t\t\t\t} else if (keywordsTertiary.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_DART_KW_TERTIARY);\n\t\t\t\t\t} else if (keywordsTypes.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_DART_KW_TYPE);\n\t\t\t\t\t} else if (state == SCE_DART_IDENTIFIER && sc.ch == ':') {\n\t\t\t\t\t\tif (chBefore == ',' || chBefore == '{' || chBefore == '(') {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_DART_KEY); // map key or named parameter\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsc.SetState(SCE_DART_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_DART_SYMBOL_OPERATOR:\n\t\t\tif (!IsDefinableOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_DART_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_DART_COMMENTLINE:\n\t\tcase SCE_DART_COMMENTLINEDOC:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_DART_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_DART_COMMENTBLOCK:\n\t\tcase SCE_DART_COMMENTBLOCKDOC:\n\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\tsc.Forward();\n\t\t\t\t--commentLevel;\n\t\t\t\tif (commentLevel == 0) {\n\t\t\t\t\tsc.ForwardSetState(SCE_DART_DEFAULT);\n\t\t\t\t}\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tsc.Forward();\n\t\t\t\t++commentLevel;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_DART_STRING_SQ:\n\t\tcase SCE_DART_STRING_DQ:\n\t\tcase SCE_DART_TRIPLE_STRING_SQ:\n\t\tcase SCE_DART_TRIPLE_STRING_DQ:\n\t\tcase SCE_DART_RAWSTRING_SQ:\n\t\tcase SCE_DART_RAWSTRING_DQ:\n\t\tcase SCE_DART_TRIPLE_RAWSTRING_SQ:\n\t\tcase SCE_DART_TRIPLE_RAWSTRING_DQ:\n\t\t\tif (sc.atLineStart && !IsTripleString(sc.state)) {\n\t\t\t\tsc.SetState(SCE_DART_DEFAULT);\n\t\t\t} else if (sc.atLineEnd && !IsTripleString(sc.state)) {\n\t\t\t\tsc.ChangeState(SCE_DART_STRINGEOL);\n\t\t\t} else if (sc.ch == '\\\\' && !IsRaw(sc.state)) {\n\t\t\t\tif (escSeq.resetEscapeState(sc.state, sc.chNext)) {\n\t\t\t\t\tsc.SetState(SCE_DART_ESCAPECHAR);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tif (sc.Match('u', '{')) {\n\t\t\t\t\t\tescSeq.brace = true;\n\t\t\t\t\t\tescSeq.digitsLeft = 7; // Unicode code point\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '$' && !IsRaw(sc.state)) {\n\t\t\t\tescSeq.outerState = sc.state;\n\t\t\t\tsc.SetState(SCE_DART_OPERATOR_STRING);\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '{') {\n\t\t\t\t\tinterpolatingStack.push_back({escSeq.outerState, 1});\n\t\t\t\t} else if (sc.ch != '$' && IsDartIdentifierStart(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_DART_IDENTIFIER_STRING);\n\t\t\t\t} else { // error\n\t\t\t\t\tsc.SetState(escSeq.outerState);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else if (sc.ch == GetStringQuote(sc.state) &&\n\t\t\t\t\t(!IsTripleString(sc.state) || (sc.Match(IsDoubleQuoted(sc.state) ? R\"(\"\"\")\" : R\"(''')\")))) {\n\t\t\t\tif (IsTripleString(sc.state)) {\n\t\t\t\t\tsc.Forward(2);\n\t\t\t\t}\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState(SCE_DART_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_DART_STRINGEOL:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_DART_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_DART_ESCAPECHAR:\n\t\t\tif (escSeq.atEscapeEnd(sc.ch)) {\n\t\t\t\tif (escSeq.brace && sc.ch == '}') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.SetState(escSeq.outerState);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (sc.state == SCE_DART_DEFAULT) {\n\t\t\tif (sc.ch == '/' && (sc.chNext == '/' || sc.chNext == '*')) {\n\t\t\t\tconst int chNext = sc.chNext;\n\t\t\t\tsc.SetState((chNext == '/') ? SCE_DART_COMMENTLINE : SCE_DART_COMMENTBLOCK);\n\t\t\t\tsc.Forward(2);\n\t\t\t\tif (sc.ch == chNext && sc.chNext != chNext) {\n\t\t\t\t\tif (sc.state == SCE_DART_COMMENTLINE) {\n\t\t\t\t\t\tsc.ChangeState(SCE_DART_COMMENTLINEDOC);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ChangeState(SCE_DART_COMMENTBLOCKDOC);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (chNext == '/') {\n\t\t\t\t\tif (visibleChars == 0) {\n\t\t\t\t\t\tlineStateLineType = DartLineStateMaskLineComment;\n\t\t\t\t\t}\n\t\t\t\t } else {\n\t\t\t\t\tcommentLevel = 1;\n\t\t\t\t }\n\t\t\t\t continue;\n\t\t\t}\n\t\t\tif (sc.ch == 'r' && (sc.chNext == '\\'' || sc.chNext == '\"')) {\n\t\t\t\tsc.SetState((sc.chNext == '\\'') ? SCE_DART_RAWSTRING_SQ : SCE_DART_RAWSTRING_DQ);\n\t\t\t\tsc.Forward(2);\n\t\t\t\tif (sc.chPrev == '\\'' && sc.Match('\\'', '\\'')) {\n\t\t\t\t\tsc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_SQ);\n\t\t\t\t\tsc.Forward(2);\n\t\t\t\t} else if (sc.chPrev == '\"' && sc.Match('\"', '\"')) {\n\t\t\t\t\tsc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_DQ);\n\t\t\t\t\tsc.Forward(2);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (sc.ch == '\"') {\n\t\t\t\tif (sc.Match(R\"(\"\"\")\")) {\n\t\t\t\t\tsc.SetState(SCE_DART_TRIPLE_STRING_DQ);\n\t\t\t\t\tsc.Forward(2);\n\t\t\t\t} else {\n\t\t\t\t\tchBefore = chPrevNonWhite;\n\t\t\t\t\tsc.SetState(SCE_DART_STRING_DQ);\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tif (sc.Match(R\"(''')\")) {\n\t\t\t\t\tsc.SetState(SCE_DART_TRIPLE_STRING_SQ);\n\t\t\t\t\tsc.Forward(2);\n\t\t\t\t} else {\n\t\t\t\t\tchBefore = chPrevNonWhite;\n\t\t\t\t\tsc.SetState(SCE_DART_STRING_SQ);\n\t\t\t\t}\n\t\t\t} else if (IsNumberStart(sc.ch, sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_DART_NUMBER);\n\t\t\t} else if ((sc.ch == '@' || sc.ch == '#') && IsDartIdentifierStart(sc.chNext)) {\n\t\t\t\tsc.SetState((sc.ch == '@') ? SCE_DART_METADATA : SCE_DART_SYMBOL_IDENTIFIER);\n\t\t\t} else if (IsDartIdentifierStart(sc.ch)) {\n\t\t\t\tchBefore = chPrevNonWhite;\n\t\t\t\tsc.SetState(SCE_DART_IDENTIFIER);\n\t\t\t} else if (sc.ch == '#' && IsDefinableOperator(sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_DART_SYMBOL_OPERATOR);\n\t\t\t} else if (IsAGraphic(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_DART_OPERATOR);\n\t\t\t\tif (!interpolatingStack.empty() && AnyOf(sc.ch, '{', '}')) {\n\t\t\t\t\tInterpolatingState &current = interpolatingStack.back();\n\t\t\t\t\tif (sc.ch == '{') {\n\t\t\t\t\t\tcurrent.braceCount += 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent.braceCount -= 1;\n\t\t\t\t\t\tif (current.braceCount == 0) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_DART_OPERATOR_STRING);\n\t\t\t\t\t\t\tsc.ForwardSetState(current.state);\n\t\t\t\t\t\t\tinterpolatingStack.pop_back();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!isspacechar(sc.ch)) {\n\t\t\tvisibleChars++;\n\t\t\tif (!IsSpaceEquiv(sc.state)) {\n\t\t\t\tchPrevNonWhite = sc.ch;\n\t\t\t}\n\t\t}\n\t\tif (sc.atLineEnd) {\n\t\t\tint lineState = (commentLevel << 4) | lineStateLineType;\n\t\t\tif (!interpolatingStack.empty()) {\n\t\t\t\tlineState |= DartLineStateMaskInterpolation;\n\t\t\t}\n\t\t\tstyler.SetLineState(sc.currentLine, lineState);\n\t\t\tlineStateLineType = 0;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tsc.Forward();\n\t}\n\n\tsc.Complete();\n}\n\nvoid LexerDart::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {\n\tif (!options.fold)\n\t\treturn;\n\n\tAccessor styler(pAccess, nullptr);\n\tconst Sci_PositionU endPos = startPos + lengthDoc;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\twhile (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tstartPos = styler.LineStart(lineCurrent);\n\t\tinitStyle = (startPos > 0) ? styler.StyleIndexAt(startPos) : 0;\n\t\tif (initStyle != SCE_DART_COMMENTBLOCKDOC && initStyle != SCE_DART_COMMENTBLOCK &&\n\t\t\tinitStyle != SCE_DART_TRIPLE_RAWSTRING_SQ && initStyle != SCE_DART_TRIPLE_RAWSTRING_DQ &&\n\t\t\tinitStyle != SCE_DART_TRIPLE_STRING_SQ && initStyle != SCE_DART_TRIPLE_STRING_DQ)\n\t\t\tbreak;\n\t}\n\tFoldLineState foldPrev(0);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0) {\n\t\tlevelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;\n\t\tfoldPrev = FoldLineState(styler.GetLineState(lineCurrent - 1));\n\t}\n\n\tint levelNext = levelCurrent;\n\tFoldLineState foldCurrent(styler.GetLineState(lineCurrent));\n\tSci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1);\n\tlineStartNext = std::min(lineStartNext, endPos);\n\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleIndexAt(startPos);\n\tint style = initStyle;\n\n\twhile (startPos < endPos) {\n\t\tconst char ch = chNext;\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tchNext = styler[++startPos];\n\t\tstyleNext = styler.StyleIndexAt(startPos);\n\n\t\tswitch (style) {\n\t\tcase SCE_DART_COMMENTBLOCKDOC:\n\t\tcase SCE_DART_COMMENTBLOCK: {\n\t\t\tconst int level = (ch == '/' && chNext == '*') ? 1 : ((ch == '*' && chNext == '/') ? -1 : 0);\n\t\t\tif (level != 0) {\n\t\t\t\tlevelNext += level;\n\t\t\t\tstartPos++;\n\t\t\t\tchNext = styler[startPos];\n\t\t\t\tstyleNext = styler.StyleIndexAt(startPos);\n\t\t\t}\n\t\t} break;\n\n\t\tcase SCE_DART_TRIPLE_RAWSTRING_SQ:\n\t\tcase SCE_DART_TRIPLE_RAWSTRING_DQ:\n\t\tcase SCE_DART_TRIPLE_STRING_SQ:\n\t\tcase SCE_DART_TRIPLE_STRING_DQ:\n\t\t\tif (style != stylePrev && !AnyOf(stylePrev, SCE_DART_ESCAPECHAR, SCE_DART_OPERATOR_STRING, SCE_DART_IDENTIFIER_STRING)) {\n\t\t\t\tlevelNext++;\n\t\t\t}\n\t\t\tif (style != styleNext && !AnyOf(styleNext, SCE_DART_ESCAPECHAR, SCE_DART_OPERATOR_STRING, SCE_DART_IDENTIFIER_STRING)) {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_DART_OPERATOR:\n\t\tcase SCE_DART_OPERATOR_STRING:\n\t\t\tif (ch == '{' || ch == '[' || ch == '(') {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}' || ch == ']' || ch == ')') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (startPos == lineStartNext) {\n\t\t\tconst FoldLineState foldNext(styler.GetLineState(lineCurrent + 1));\n\t\t\tlevelNext = std::max(levelNext, SC_FOLDLEVELBASE);\n\t\t\tif (foldCurrent.lineComment) {\n\t\t\t\tlevelNext += foldNext.lineComment - foldPrev.lineComment;\n\t\t\t} else if (foldCurrent.packageImport) {\n\t\t\t\tlevelNext += foldNext.packageImport - foldPrev.packageImport;\n\t\t\t}\n\n\t\t\tconst int levelUse = levelCurrent;\n\t\t\tint lev = levelUse | (levelNext << 16);\n\t\t\tif (levelUse < levelNext) {\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tstyler.SetLevel(lineCurrent, lev);\n\n\t\t\tlineCurrent++;\n\t\t\tlineStartNext = styler.LineStart(lineCurrent + 1);\n\t\t\tlineStartNext = std::min(lineStartNext, endPos);\n\t\t\tlevelCurrent = levelNext;\n\t\t\tfoldPrev = foldCurrent;\n\t\t\tfoldCurrent = foldNext;\n\t\t}\n\t}\n}\n\n}  // unnamed namespace end\n\nextern const LexerModule lmDart(SCLEX_DART, LexerDart::LexerFactoryDart, \"dart\", dartWordListDesc);\n"
  },
  {
    "path": "lexers/LexDataflex.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexDataflex.cxx\n ** Lexer for DataFlex.\n ** Based on LexPascal.cxx\n ** Written by Wil van Antwerpen, June 2019\n **/\n\n/*\n// The License.txt file describes the conditions under which this software may be distributed.\n\nA few words about features of LexDataflex...\n\nGenerally speaking LexDataflex tries to support all available DataFlex features (up\nto DataFlex 19.1 at this time).\n\n~ FOLDING:\n\nFolding is supported in the following cases:\n\n- Folding of stream-like comments\n- Folding of groups of consecutive line comments\n- Folding of preprocessor blocks (the following preprocessor blocks are\nsupported: #IFDEF, #IFNDEF, #ENDIF and #HEADER / #ENDHEADER \nblocks), \n- Folding of code blocks on appropriate keywords (the following code blocks are\nsupported: \"begin, struct, type, case / end\" blocks, class & object\ndeclarations and interface declarations)\n\nRemarks:\n\n- We pass 4 arrays to the lexer:\n1. The DataFlex keyword list, these are normal DataFlex keywords\n2. The Scope Open list, for example, begin / procedure / while\n3. The Scope Close list, for example, end / end_procedure / loop\n4. Operator list, for ex. + / - / * / Lt / iand\nThese lists are all mutually exclusive, scope open words should not be in the keyword list and vice versa\n\n- Folding of code blocks tries to handle all special cases in which folding\nshould not occur. \n\n~ KEYWORDS:\n\nThe list of keywords that can be used in dataflex.properties file (up to DataFlex\n19.1):\n\n- Keywords: .. snipped .. see dataflex.properties file.\n\n*/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\nstatic void GetRangeLowered(Sci_PositionU start,\n\t\tSci_PositionU end,\n\t\tAccessor &styler,\n\t\tchar *s,\n\t\tSci_PositionU len) {\n\tSci_PositionU i = 0;\n\twhile ((i < end - start + 1) && (i < len-1)) {\n\t\ts[i] = static_cast<char>(tolower(styler[start + i]));\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n}\n\nstatic void GetForwardRangeLowered(Sci_PositionU start,\n\t\tCharacterSet &charSet,\n\t\tAccessor &styler,\n\t\tchar *s,\n\t\tSci_PositionU len) {\n\tSci_PositionU i = 0;\n\twhile ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) {\n\t\ts[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n\n}\n\nenum {\n\tstateInICode = 0x1000,\n\tstateSingleQuoteOpen = 0x2000,\n\tstateDoubleQuoteOpen = 0x4000,\n\tstateFoldInPreprocessor = 0x0100,\n\tstateFoldInCaseStatement = 0x0200,\n\tstateFoldInPreprocessorLevelMask = 0x00FF,\n\tstateFoldMaskAll = 0x0FFF\n};\n\n\nstatic bool IsFirstDataFlexWord(Sci_Position pos, Accessor &styler) {\n\tSci_Position line = styler.GetLine(pos);\n\tSci_Position start_pos = styler.LineStart(line);\n\tfor (Sci_Position i = start_pos; i < pos; i++) {\n\t\tchar ch = styler.SafeGetCharAt(i);\n\t\tif (!(ch == ' ' || ch == '\\t'))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\n\ninline bool IsADataFlexField(int ch) {\n\treturn (ch == '.');\n}\n\n\nstatic void ClassifyDataFlexWord(WordList *keywordlists[], StyleContext &sc, Accessor &styler) {\n\tWordList& keywords = *keywordlists[0];\n\tWordList& scopeOpen   = *keywordlists[1];\n\tWordList& scopeClosed = *keywordlists[2];\n\tWordList& operators   = *keywordlists[3];\n\n\tchar s[100];\n\tint oldState;\n\tint newState;\n\tsize_t tokenlen;\n\n    oldState = sc.state;\n\tnewState = oldState;\n\tsc.GetCurrentLowered(s, sizeof(s));\n\ttokenlen = strnlen(s,sizeof(s));\n\tif (keywords.InList(s)) {\n\t\t// keywords in DataFlex can be used as table column names (file.field) and as such they\n\t\t// should not be characterized as a keyword. So test for that.\n\t\t// for ex. somebody using date as field name.\n        if (!IsADataFlexField(sc.GetRelative(-static_cast<int>(tokenlen+1)))) {\n\t      newState = SCE_DF_WORD;\n\t    }\n\t}\n\tif (oldState == newState) {\n\t\tif ((scopeOpen.InList(s) || scopeClosed.InList(s)) && (strcmp(s, \"for\") != 0) && (strcmp(s, \"repeat\") != 0)) {\n\t\t\t// scope words in DataFlex can be used as table column names (file.field) and as such they\n\t\t\t// should not be characterized as a scope word. So test for that.\n\t\t\t// for ex. somebody using procedure for field name.\n\t\t\tif (!IsADataFlexField(sc.GetRelative(-static_cast<int>(tokenlen+1)))) {\n\t\t\t\tnewState = SCE_DF_SCOPEWORD;\n\t\t\t}\n\t\t} \n\t\t// no code folding on the next words, but just want to paint them like keywords (as they are) (??? doesn't the code to the opposite?)\n\t\tif (strcmp(s, \"if\") == 0 ||  \n\t\t\tstrcmp(s, \"ifnot\") == 0 ||\n\t\t\tstrcmp(s, \"case\") == 0 ||\n\t\t\tstrcmp(s, \"else\") == 0 ) {\n\t\t\t\tnewState = SCE_DF_SCOPEWORD;\n\t\t} \n\t}\n\tif (oldState != newState && newState == SCE_DF_WORD) {\n\t\t// a for loop must have for at the start of the line, for is also used in \"define abc for 123\"\n\t\tif ( (strcmp(s, \"for\") == 0) && (IsFirstDataFlexWord(sc.currentPos-3, styler)) ) {   \n\t\t\t\tnewState = SCE_DF_SCOPEWORD;\n\t\t} \n\t}\n\tif (oldState != newState && newState == SCE_DF_WORD) {\n\t\t// a repeat loop must have repeat at the start of the line, repeat is also used in 'move (repeat(\"d\",5)) to sFoo'\n\t\tif ( (strcmp(s, \"repeat\") == 0) && (IsFirstDataFlexWord(sc.currentPos-6, styler)) ) {   \n\t\t\t\tnewState = SCE_DF_SCOPEWORD;\n\t\t} \n\t}\n\tif (oldState == newState)  {\n\t  if (operators.InList(s)) {\n\t\t  newState = SCE_DF_OPERATOR;\n\t\t} \n\t}\n\n\tif (oldState != newState) {\n\t\tsc.ChangeState(newState);\n\t}\n\tsc.SetState(SCE_DF_DEFAULT);\n}\n\nstatic void ColouriseDataFlexDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n\t\tAccessor &styler) {\n//\tbool bSmartHighlighting = styler.GetPropertyInt(\"lexer.dataflex.smart.highlighting\", 1) != 0;\n\n\t\t\tCharacterSet setWordStart(CharacterSet::setAlpha, \"_$#@\", 0x80, true);\n\t\t\tCharacterSet setWord(CharacterSet::setAlphaNum, \"_$#@\", 0x80, true);\n\tCharacterSet setNumber(CharacterSet::setDigits, \".-+eE\");\n\tCharacterSet setHexNumber(CharacterSet::setDigits, \"abcdefABCDEF\");\n\tCharacterSet setOperator(CharacterSet::setNone, \"*+-/<=>^\");\n\n\tSci_Position curLine = styler.GetLine(startPos);\n\tint curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\tif (sc.atLineEnd) {\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\tstyler.SetLineState(curLine, curLineState);\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_DF_NUMBER:\n\t\t\t\tif (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) {\n\t\t\t\t\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\t} else if (sc.ch == '-' || sc.ch == '+') {\n\t\t\t\t\tif (sc.chPrev != 'E' && sc.chPrev != 'e') {\n\t\t\t\t\t\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_IDENTIFIER:\n\t\t\t\tif (!setWord.Contains(sc.ch)) {\n\t\t\t\t\tClassifyDataFlexWord(keywordlists, sc, styler);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_HEXNUMBER:\n\t\t\t\tif (!(setHexNumber.Contains(sc.ch) || sc.ch == 'I') ) { // in |CI$22a we also want to color the \"I\"\n\t\t\t\t\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_METATAG:\n\t\t\t\tif (sc.atLineStart || sc.chPrev == '}') {\n\t\t\t\t\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_PREPROCESSOR:\n\t\t\t\tif (sc.atLineStart || IsASpaceOrTab(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_IMAGE:\n\t\t\t\tif (sc.atLineStart && sc.Match(\"/*\")) {\n\t\t\t\t\tsc.Forward();  // these characters are still part of the DF Image\n\t\t\t\t\tsc.ForwardSetState(SCE_DF_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_PREPROCESSOR2:\n\t\t\t\t// we don't have inline comments or preprocessor2 commands\n\t\t\t\t//if (sc.Match('*', ')')) {\n\t\t\t\t//\tsc.Forward();\n\t\t\t\t//\tsc.ForwardSetState(SCE_DF_DEFAULT);\n\t\t\t\t//}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_STRING:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_DF_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\'' && sc.chNext == '\\'') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (sc.ch == '\\\"' && sc.chNext == '\\\"') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (sc.ch == '\\'' || sc.ch == '\\\"') {\n\t\t\t\t\tif (sc.ch == '\\'' && (curLineState & stateSingleQuoteOpen) ) {\n \t\t\t\t    curLineState &= ~(stateSingleQuoteOpen);\n\t\t\t\t\tsc.ForwardSetState(SCE_DF_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t\telse if (sc.ch == '\\\"' && (curLineState & stateDoubleQuoteOpen) ) {\n \t\t\t\t    curLineState &= ~(stateDoubleQuoteOpen);\n\t\t\t\t\tsc.ForwardSetState(SCE_DF_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_STRINGEOL:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_SCOPEWORD:\n\t\t\t\t//if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') {\n\t\t\t\t//\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\t//}\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_OPERATOR:\n//\t\t\t\tif (bSmartHighlighting && sc.chPrev == ';') {\n//\t\t\t\t\tcurLineState &= ~(stateInProperty | stateInExport);\n//\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_DF_ICODE:\n\t\t\t\tif (sc.atLineStart || IsASpace(sc.ch) || isoperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_DF_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_DF_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_DF_NUMBER);\n\t\t\t} else if (sc.Match('/', '/') || sc.Match(\"#REM\")) {\n\t\t\t\tsc.SetState(SCE_DF_COMMENTLINE);\n\t\t\t} else if ((sc.ch == '#' && !sc.Match(\"#REM\")) && IsFirstDataFlexWord(sc.currentPos, styler)) {\n\t\t\t\tsc.SetState(SCE_DF_PREPROCESSOR);\n\t\t\t// || (sc.ch == '|' && sc.chNext == 'C' && sc.GetRelativeCharacter(2) == 'I' && sc.GetRelativeCharacter(3) == '$') ) {\n\t\t\t} else if ((sc.ch == '$' && ((!setWord.Contains(sc.chPrev)) || sc.chPrev == 'I' ) ) || (sc.Match(\"|CI$\")) ) {\n\t\t\t\tsc.SetState(SCE_DF_HEXNUMBER); // start with $ and previous character not in a..zA..Z0..9 excluding \"I\" OR start with |CI$\n\t\t\t} else if (setWordStart.Contains(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_DF_IDENTIFIER);\n\t\t\t} else if (sc.ch == '{') {\n\t\t\t\tsc.SetState(SCE_DF_METATAG);\n\t\t\t//} else if (sc.Match(\"(*$\")) {\n\t\t\t//\tsc.SetState(SCE_DF_PREPROCESSOR2);\n\t\t\t} else if (sc.ch == '/' && setWord.Contains(sc.chNext) &&  sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_DF_IMAGE);\n\t\t\t//\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.ch == '\\'' || sc.ch == '\\\"') {\n\t\t\t\tif (sc.ch == '\\'' && !(curLineState & stateDoubleQuoteOpen)) {\n\t\t\t\t  curLineState |= stateSingleQuoteOpen;\n\t\t\t\t} else if (sc.ch == '\\\"' && !(curLineState & stateSingleQuoteOpen)) {\n\t\t\t\t  curLineState |= stateDoubleQuoteOpen;\n\t\t\t\t}\n\t\t\t    sc.SetState(SCE_DF_STRING);\n\t\t\t} else if (setOperator.Contains(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_DF_OPERATOR);\n//\t\t\t} else if (curLineState & stateInICode) {\n\t\t\t\t// ICode start ! in a string followed by close string mark is not icode\n\t\t\t} else if ((sc.ch == '!') && !(sc.ch == '!' && ((sc.chNext == '\\\"') || (sc.ch == '\\'')) )) {\n\t\t\t\tsc.SetState(SCE_DF_ICODE);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (sc.state == SCE_DF_IDENTIFIER && setWord.Contains(sc.chPrev)) {\n\t\tClassifyDataFlexWord(keywordlists, sc, styler);\n\t}\n\n\tsc.Complete();\n}\n\nstatic bool IsStreamCommentStyle(int style) {\n\treturn style == SCE_DF_IMAGE;\n}\n\nstatic bool IsCommentLine(Sci_Position line, Accessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eolPos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eolPos; i++) {\n\t\tchar ch = styler[i];\n\t\tchar chNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styler.StyleAt(i);\n\t\tif (ch == '/' && chNext == '/' && style == SCE_DF_COMMENTLINE) {\n\t\t\treturn true;\n\t\t} else if (!IsASpaceOrTab(ch)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn false;\n}\n\n\n\nstatic unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) {\n\treturn lineFoldStateCurrent & stateFoldInPreprocessorLevelMask;\n}\n\nstatic void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) {\n\tlineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask;\n\tlineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;\n}\n\nstatic int ClassifyDataFlexPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,\n\t\tSci_PositionU startPos, Accessor &styler) {\n\tCharacterSet setWord(CharacterSet::setAlpha);\n\n\tchar s[100];\t// Size of the longest possible keyword + one additional character + null\n\tGetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s));\n\tsize_t iLen = strnlen(s,sizeof(s));\n\tsize_t iWordSize = 0;\n\n\tunsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);\n\n\tif (strcmp(s, \"command\") == 0 ||\n\t\t// The #if/#ifdef etcetera commands are not currently foldable as it is easy to write code that\n\t\t// breaks the collaps logic, so we keep things simple and not include that for now.\n\t\tstrcmp(s, \"header\") == 0) {\n\t\tnestLevel++;\n\t\tSetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);\n\t\tlineFoldStateCurrent |= stateFoldInPreprocessor;\n\t\tlevelCurrent++;\n\t\tiWordSize = iLen;\n\t} else if (strcmp(s, \"endcommand\") == 0 ||\n\t\tstrcmp(s, \"endheader\") == 0) {\n\t\tnestLevel--;\n\t\tSetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);\n\t\tif (nestLevel == 0) {\n\t\t\tlineFoldStateCurrent &= ~stateFoldInPreprocessor;\n\t\t}\n\t\tlevelCurrent--;\n\t\tiWordSize = iLen;\n\t\tif (levelCurrent < SC_FOLDLEVELBASE) {\n\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t}\n\t}\n\treturn static_cast<int>(iWordSize);\n}\n\n\nstatic void ClassifyDataFlexWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,\n\t\tSci_PositionU lastStart, Sci_PositionU currentPos, WordList *[], Accessor &styler) {\n\tchar s[100];\n\n\t// property fold.dataflex.compilerlist\n\t//\tSet to 1 for enabling the code folding feature in *.prn files\n\tbool foldPRN = styler.GetPropertyInt(\"fold.dataflex.compilerlist\",0) != 0;\n\n\tGetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));\n\n\tif (strcmp(s, \"case\") == 0) {\n\t\tlineFoldStateCurrent |= stateFoldInCaseStatement;\n\t} else if (strcmp(s, \"begin\") == 0) {\n\t\tlevelCurrent++;\n\t} else if (strcmp(s, \"for\") == 0 ||\n\t\tstrcmp(s, \"while\") == 0 ||\n\t\tstrcmp(s, \"repeat\") == 0 ||\n\t\tstrcmp(s, \"for_all\") == 0 ||\n\t\tstrcmp(s, \"struct\") == 0 ||\n\t\tstrcmp(s, \"type\") == 0 ||\n\t\tstrcmp(s, \"begin_row\") == 0 ||\n\t\tstrcmp(s, \"item_list\") == 0 ||\n\t\tstrcmp(s, \"begin_constraints\") == 0 ||\n\t\tstrcmp(s, \"begin_transaction\") == 0 ||\n\t\tstrcmp(s, \"enum_list\") == 0 ||\n\t\tstrcmp(s, \"class\") == 0 || \n\t\tstrcmp(s, \"object\") == 0 ||\n\t\tstrcmp(s, \"cd_popup_object\") == 0 ||\n\t\tstrcmp(s, \"procedure\") == 0 ||\n\t\tstrcmp(s, \"procedure_section\") == 0 ||\n\t\tstrcmp(s, \"function\") == 0 ) {\n\t\t\tif ((IsFirstDataFlexWord(lastStart, styler )) || foldPRN) {\n\t\t\tlevelCurrent++;\n\t\t\t}\n\t} else if (strcmp(s, \"end\") == 0) {  // end is not always the first keyword, for example \"case end\"\n\t\tlevelCurrent--;\n\t\tif (levelCurrent < SC_FOLDLEVELBASE) {\n\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t}\n\t} else if (strcmp(s, \"loop\") == 0 ||\n\t\t\t\t   strcmp(s, \"until\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_class\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_object\") == 0 ||\n\t\t\t\t   strcmp(s, \"cd_end_object\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_procedure\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_function\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_for_all\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_struct\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_type\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_row\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_item_list\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_constraints\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_transaction\") == 0 ||\n\t\t\t\t   strcmp(s, \"end_enum_list\") == 0 ) {\n\t//\t\tlineFoldStateCurrent &= ~stateFoldInRecord;\n\t\t\tif ((IsFirstDataFlexWord(lastStart, styler )) || foldPRN) {\n\t\t\t\tlevelCurrent--;\n\t\t\t\tif (levelCurrent < SC_FOLDLEVELBASE) {\n\t\t\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t\t\t}\n\t\t\t}\n\t}\n\n}\n\n\nstatic void ClassifyDataFlexMetaDataFoldPoint(int &levelCurrent, \n\t\tSci_PositionU lastStart, Sci_PositionU currentPos, WordList *[], Accessor &styler) {\n\tchar s[100];\n\n\tGetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));\n\n    if (strcmp(s, \"#beginsection\") == 0) {\n\t\tlevelCurrent++;\n\t} else if (strcmp(s, \"#endsection\") == 0) {\n\t\t\tlevelCurrent--;\n\t\t\tif (levelCurrent < SC_FOLDLEVELBASE) {\n\t\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t\t}\n\t}\n\n}\n\nstatic void FoldDataFlexDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n\t\tAccessor &styler) {\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldPreprocessor = styler.GetPropertyInt(\"fold.preprocessor\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tint lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tint iWordSize;\n\n\tSci_Position lastStart = 0;\n\tCharacterSet setWord(CharacterSet::setAlphaNum, \"_$#@\", 0x80, true);\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (foldComment && IsStreamCommentStyle(style)) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext)) {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (foldComment && atEOL && IsCommentLine(lineCurrent, styler))\n\t\t{\n\t\t\tif (!IsCommentLine(lineCurrent - 1, styler)\n\t\t\t    && IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (IsCommentLine(lineCurrent - 1, styler)\n\t\t\t         && !IsCommentLine(lineCurrent+1, styler))\n\t\t\t\tlevelCurrent--;\n\t\t}\n\t\tif (foldPreprocessor) {\n\t\t\tif (style == SCE_DF_PREPROCESSOR) {\n\t\t\t\tiWordSize = ClassifyDataFlexPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 1, styler);\n\t\t\t//} else if (style == SCE_DF_PREPROCESSOR2 && ch == '(' && chNext == '*'\n\t\t\t//           && styler.SafeGetCharAt(i + 2) == '$') {\n\t\t\t//\tClassifyDataFlexPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);\n\t\t\t\ti = i + iWordSize;\n\t\t\t}\n\t\t}\n\n\t\tif (stylePrev != SCE_DF_SCOPEWORD && style == SCE_DF_SCOPEWORD)\n\t\t{\n\t\t\t// Store last word start point.\n\t\t\tlastStart = i;\n\t\t}\n\t\tif (stylePrev == SCE_DF_SCOPEWORD) {\n\t\t\tif(setWord.Contains(ch) && !setWord.Contains(chNext)) {\n\t\t\t\tClassifyDataFlexWordFoldPoint(levelCurrent, lineFoldStateCurrent, lastStart, i, keywordlists, styler);\n\t\t\t}\n\t\t}\n\n\t\tif (stylePrev == SCE_DF_METATAG && ch == '#')\n\t\t{\n\t\t\t// Store last word start point.\n\t\t\tlastStart = i;\n\t\t}\n\t\tif (stylePrev == SCE_DF_METATAG) {\n\t\t\tif(setWord.Contains(ch) && !setWord.Contains(chNext)) {\n\t\t\t\tClassifyDataFlexMetaDataFoldPoint(levelCurrent, lastStart, i, keywordlists, styler);\n\t\t\t}\n\t\t}\n\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tint newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent;\n\t\t\tstyler.SetLineState(lineCurrent, newLineState);\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t}\n\n\t// If we didn't reach the EOL in previous loop, store line level and whitespace information.\n\t// The rest will be filled in later...\n\tint lev = levelPrev;\n\tif (visibleChars == 0 && foldCompact)\n\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\tstyler.SetLevel(lineCurrent, lev);\n}\n\nstatic const char * const dataflexWordListDesc[] = {\n\t\"Keywords\",\n\t\"Scope open\",\n\t\"Scope close\",\n\t\"Operators\",\n\t0\n};\n\nextern const LexerModule lmDataflex(SCLEX_DATAFLEX, ColouriseDataFlexDoc, \"dataflex\", FoldDataFlexDoc, dataflexWordListDesc);\n"
  },
  {
    "path": "lexers/LexDiff.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexDiff.cxx\n ** Lexer for diff results.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\ninline bool AtEOL(Accessor &styler, Sci_PositionU i) {\n\treturn (styler[i] == '\\n') ||\n\t       ((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n'));\n}\n\nvoid ColouriseDiffLine(const char *lineBuffer, Sci_Position endLine, Accessor &styler) {\n\t// It is needed to remember the current state to recognize starting\n\t// comment lines before the first \"diff \" or \"--- \". If a real\n\t// difference starts then each line starting with ' ' is a whitespace\n\t// otherwise it is considered a comment (Only in..., Binary file...)\n\tif (0 == strncmp(lineBuffer, \"diff \", 5)) {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_COMMAND);\n\t} else if (0 == strncmp(lineBuffer, \"Index: \", 7)) {  // For subversion's diff\n\t\tstyler.ColourTo(endLine, SCE_DIFF_COMMAND);\n\t} else if (0 == strncmp(lineBuffer, \"---\", 3) && lineBuffer[3] != '-') {\n\t\t// In a context diff, --- appears in both the header and the position markers\n\t\tif (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))\n\t\t\tstyler.ColourTo(endLine, SCE_DIFF_POSITION);\n\t\telse if (lineBuffer[3] == '\\r' || lineBuffer[3] == '\\n')\n\t\t\tstyler.ColourTo(endLine, SCE_DIFF_POSITION);\n\t\telse if (lineBuffer[3] == ' ')\n\t\t\tstyler.ColourTo(endLine, SCE_DIFF_HEADER);\n\t\telse\n\t\t\tstyler.ColourTo(endLine, SCE_DIFF_DELETED);\n\t} else if (0 == strncmp(lineBuffer, \"+++ \", 4)) {\n\t\t// I don't know of any diff where \"+++ \" is a position marker, but for\n\t\t// consistency, do the same as with \"--- \" and \"*** \".\n\t\tif (atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))\n\t\t\tstyler.ColourTo(endLine, SCE_DIFF_POSITION);\n\t\telse\n\t\t\tstyler.ColourTo(endLine, SCE_DIFF_HEADER);\n\t} else if (0 == strncmp(lineBuffer, \"====\", 4)) {  // For p4's diff\n\t\tstyler.ColourTo(endLine, SCE_DIFF_HEADER);\n\t} else if (0 == strncmp(lineBuffer, \"***\", 3)) {\n\t\t// In a context diff, *** appears in both the header and the position markers.\n\t\t// Also ******** is a chunk header, but here it's treated as part of the\n\t\t// position marker since there is no separate style for a chunk header.\n\t\tif (lineBuffer[3] == ' ' && atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))\n\t\t\tstyler.ColourTo(endLine, SCE_DIFF_POSITION);\n\t\telse if (lineBuffer[3] == '*')\n\t\t\tstyler.ColourTo(endLine, SCE_DIFF_POSITION);\n\t\telse\n\t\t\tstyler.ColourTo(endLine, SCE_DIFF_HEADER);\n\t} else if (0 == strncmp(lineBuffer, \"? \", 2)) {    // For difflib\n\t\tstyler.ColourTo(endLine, SCE_DIFF_HEADER);\n\t} else if (lineBuffer[0] == '@') {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_POSITION);\n\t} else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_POSITION);\n\t} else if (0 == strncmp(lineBuffer, \"++\", 2)) {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_PATCH_ADD);\n\t} else if (0 == strncmp(lineBuffer, \"+-\", 2)) {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_PATCH_DELETE);\n\t} else if (0 == strncmp(lineBuffer, \"-+\", 2)) {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_REMOVED_PATCH_ADD);\n\t} else if (0 == strncmp(lineBuffer, \"--\", 2)) {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_REMOVED_PATCH_DELETE);\n\t} else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_DELETED);\n\t} else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_ADDED);\n\t} else if (lineBuffer[0] == '!') {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_CHANGED);\n\t} else if (lineBuffer[0] != ' ') {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_COMMENT);\n\t} else {\n\t\tstyler.ColourTo(endLine, SCE_DIFF_DEFAULT);\n\t}\n}\n\nvoid ColouriseDiffDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tstd::string lineBuffer;\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tfor (Sci_PositionU i = startPos; i < startPos + length; i++) {\n\t\tif (AtEOL(styler, i)) {\n\t\t\tColouriseDiffLine(lineBuffer.c_str(), i, styler);\n\t\t\tlineBuffer.clear();\n\t\t} else {\n\t\t\tlineBuffer.push_back(styler[i]);\n\t\t}\n\t}\n\tif (!lineBuffer.empty()) {\t// Last line does not have ending characters\n\t\tColouriseDiffLine(lineBuffer.c_str(), startPos + length - 1, styler);\n\t}\n}\n\nvoid FoldDiffDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tSci_Position curLine = styler.GetLine(startPos);\n\tSci_Position curLineStart = styler.LineStart(curLine);\n\tint prevLevel = curLine > 0 ? styler.LevelAt(curLine - 1) : SC_FOLDLEVELBASE;\n\n\tdo {\n\t\tint nextLevel = 0;\n\t\tconst int lineType = styler.StyleAt(curLineStart);\n\t\tif (lineType == SCE_DIFF_COMMAND)\n\t\t\tnextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\telse if (lineType == SCE_DIFF_HEADER)\n\t\t\tnextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;\n\t\telse if (lineType == SCE_DIFF_POSITION && styler[curLineStart] != '-')\n\t\t\tnextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;\n\t\telse if (prevLevel & SC_FOLDLEVELHEADERFLAG)\n\t\t\tnextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;\n\t\telse\n\t\t\tnextLevel = prevLevel;\n\n\t\tif ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))\n\t\t\tstyler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);\n\n\t\tstyler.SetLevel(curLine, nextLevel);\n\t\tprevLevel = nextLevel;\n\n\t\tcurLineStart = styler.LineStart(++curLine);\n\t} while (static_cast<Sci_Position>(startPos)+length > curLineStart);\n}\n\nconst char *const emptyWordListDesc[] = {\n\tnullptr\n};\n\n}\n\nextern const LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, \"diff\", FoldDiffDoc, emptyWordListDesc);\n"
  },
  {
    "path": "lexers/LexECL.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexECL.cxx\n ** Lexer for ECL.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#ifdef _MSC_VER\n#pragma warning(disable: 4786)\n#endif\n#ifdef __BORLANDC__\n// Borland C++ displays warnings in vector header without this\n#pragma option -w-ccc -w-rch\n#endif\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n\n#define SET_LOWER \"abcdefghijklmnopqrstuvwxyz\"\n#define SET_UPPER \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n#define SET_DIGITS \"0123456789\"\n\nusing namespace Lexilla;\n\nstatic bool IsSpaceEquiv(int state) {\n\tswitch (state) {\n\tcase SCE_ECL_DEFAULT:\n\tcase SCE_ECL_COMMENT:\n\tcase SCE_ECL_COMMENTLINE:\n\tcase SCE_ECL_COMMENTLINEDOC:\n\tcase SCE_ECL_COMMENTDOCKEYWORD:\n\tcase SCE_ECL_COMMENTDOCKEYWORDERROR:\n\tcase SCE_ECL_COMMENTDOC:\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nstatic void ColouriseEclDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler) {\n\tWordList &keywords0 = *keywordlists[0];\n\tWordList &keywords1 = *keywordlists[1];\n\tWordList &keywords2 = *keywordlists[2];\n\tWordList &keywords3 = *keywordlists[3]; //Value Types\n\tWordList &keywords4 = *keywordlists[4];\n\tWordList &keywords5 = *keywordlists[5];\n\tWordList &keywords6 = *keywordlists[6];\t//Javadoc Tags\n\tWordList cplusplus;\n\tcplusplus.Set(\"beginc endc\");\n\n\tbool stylingWithinPreprocessor = false;\n\n\tCharacterSet setOKBeforeRE(CharacterSet::setNone, \"(=,\");\n\tCharacterSet setDoxygen(CharacterSet::setLower, \"$@\\\\&<>#{}[]\");\n\tCharacterSet setWordStart(CharacterSet::setAlpha, \"_\", 0x80, true);\n\tCharacterSet setWord(CharacterSet::setAlphaNum, \"._\", 0x80, true);\n\tCharacterSet setQualified(CharacterSet::setNone, \"uUxX\");\n\n\tint chPrevNonWhite = ' ';\n\tint visibleChars = 0;\n\tbool lastWordWasUUID = false;\n\tint styleBeforeDCKeyword = SCE_ECL_DEFAULT;\n\tbool continuationLine = false;\n\n\tif (initStyle == SCE_ECL_PREPROCESSOR) {\n\t\t// Set continuationLine if last character of previous line is '\\'\n\t\tSci_Position lineCurrent = styler.GetLine(startPos);\n\t\tif (lineCurrent > 0) {\n\t\t\tint chBack = styler.SafeGetCharAt(startPos-1, 0);\n\t\t\tint chBack2 = styler.SafeGetCharAt(startPos-2, 0);\n\t\t\tint lineEndChar = '!';\n\t\t\tif (chBack2 == '\\r' && chBack == '\\n') {\n\t\t\t\tlineEndChar = styler.SafeGetCharAt(startPos-3, 0);\n\t\t\t} else if (chBack == '\\n' || chBack == '\\r') {\n\t\t\t\tlineEndChar = chBack2;\n\t\t\t}\n\t\t\tcontinuationLine = lineEndChar == '\\\\';\n\t\t}\n\t}\n\n\t// look back to set chPrevNonWhite properly for better regex colouring\n\tif (startPos > 0) {\n\t\tSci_Position back = startPos;\n\t\twhile (--back && IsSpaceEquiv(styler.StyleAt(back)))\n\t\t\t;\n\t\tif (styler.StyleAt(back) == SCE_ECL_OPERATOR) {\n\t\t\tchPrevNonWhite = styler.SafeGetCharAt(back);\n\t\t}\n\t}\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\tif (sc.atLineStart) {\n\t\t\tif (sc.state == SCE_ECL_STRING) {\n\t\t\t\t// Prevent SCE_ECL_STRINGEOL from leaking back to previous line which\n\t\t\t\t// ends with a line continuation by locking in the state upto this position.\n\t\t\t\tsc.SetState(SCE_ECL_STRING);\n\t\t\t}\n\t\t\t// Reset states to begining of colourise so no surprises\n\t\t\t// if different sets of lines lexed.\n\t\t\tvisibleChars = 0;\n\t\t\tlastWordWasUUID = false;\n\t\t}\n\n\t\t// Handle line continuation generically.\n\t\tif (sc.ch == '\\\\') {\n\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tcontinuationLine = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_ECL_ADDED:\n\t\t\tcase SCE_ECL_DELETED:\n\t\t\tcase SCE_ECL_CHANGED:\n\t\t\tcase SCE_ECL_MOVED:\n\t\t\tif (sc.atLineStart)\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_OPERATOR:\n\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_NUMBER:\n\t\t\t\t// We accept almost anything because of hex. and number suffixes\n\t\t\t\tif (!setWord.Contains(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_IDENTIFIER:\n\t\t\t\tif (!setWord.Contains(sc.ch) || (sc.ch == '.')) {\n\t\t\t\t\tchar s[1000];\n\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t\tif (keywords0.InList(s)) {\n\t\t\t\t\t\tlastWordWasUUID = strcmp(s, \"uuid\") == 0;\n\t\t\t\t\t\tsc.ChangeState(SCE_ECL_WORD0);\n\t\t\t\t\t} else if (keywords1.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ECL_WORD1);\n\t\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ECL_WORD2);\n\t\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ECL_WORD4);\n\t\t\t\t\t} else if (keywords5.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ECL_WORD5);\n\t\t\t\t\t}\n\t\t\t\t\telse\t//Data types are of from KEYWORD##\n\t\t\t\t\t{\n\t\t\t\t\t\tint i = static_cast<int>(strlen(s)) - 1;\n\t\t\t\t\t\twhile(i >= 0 && (isdigit(s[i]) || s[i] == '_'))\n\t\t\t\t\t\t\t--i;\n\n\t\t\t\t\t\tchar s2[1000];\n\t\t\t\t\t\tstrncpy(s2, s, i + 1);\n\t\t\t\t\t\ts2[i + 1] = 0;\n\t\t\t\t\t\tif (keywords3.InList(s2)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_ECL_WORD3);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_PREPROCESSOR:\n\t\t\t\tif (sc.atLineStart && !continuationLine) {\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t} else if (stylingWithinPreprocessor) {\n\t\t\t\t\tif (IsASpace(sc.ch)) {\n\t\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (sc.Match('/', '*') || sc.Match('/', '/')) {\n\t\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_COMMENT:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_ECL_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_COMMENTDOC:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_ECL_DEFAULT);\n\t\t\t\t} else if (sc.ch == '@' || sc.ch == '\\\\') { // JavaDoc and Doxygen support\n\t\t\t\t\t// Verify that we have the conditions to mark a comment-doc-keyword\n\t\t\t\t\tif ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {\n\t\t\t\t\t\tstyleBeforeDCKeyword = SCE_ECL_COMMENTDOC;\n\t\t\t\t\t\tsc.SetState(SCE_ECL_COMMENTDOCKEYWORD);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_COMMENTLINEDOC:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t} else if (sc.ch == '@' || sc.ch == '\\\\') { // JavaDoc and Doxygen support\n\t\t\t\t\t// Verify that we have the conditions to mark a comment-doc-keyword\n\t\t\t\t\tif ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {\n\t\t\t\t\t\tstyleBeforeDCKeyword = SCE_ECL_COMMENTLINEDOC;\n\t\t\t\t\t\tsc.SetState(SCE_ECL_COMMENTDOCKEYWORD);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_COMMENTDOCKEYWORD:\n\t\t\t\tif ((styleBeforeDCKeyword == SCE_ECL_COMMENTDOC) && sc.Match('*', '/')) {\n\t\t\t\t\tsc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_ECL_DEFAULT);\n\t\t\t\t} else if (!setDoxygen.Contains(sc.ch)) {\n\t\t\t\t\tchar s[1000];\n\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t\tif (!IsASpace(sc.ch) || !keywords6.InList(s+1)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(styleBeforeDCKeyword);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_STRING:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_ECL_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tsc.ForwardSetState(SCE_ECL_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_CHARACTER:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_ECL_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\tsc.ForwardSetState(SCE_ECL_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_REGEX:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t} else if (sc.ch == '/') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\twhile ((sc.ch < 0x80) && islower(sc.ch))\n\t\t\t\t\t\tsc.Forward();    // gobble regex flags\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\t// Gobble up the quoted character\n\t\t\t\t\tif (sc.chNext == '\\\\' || sc.chNext == '/') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_STRINGEOL:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_VERBATIM:\n\t\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\t\tif (sc.chNext == '\\\"') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_ECL_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_ECL_UUID:\n\t\t\t\tif (sc.ch == '\\r' || sc.ch == '\\n' || sc.ch == ')') {\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tSci_Position lineCurrent = styler.GetLine(sc.currentPos);\n\t\tint lineState = styler.GetLineState(lineCurrent);\n\t\tif (sc.state == SCE_ECL_DEFAULT) {\n\t\t\tif (lineState) {\n\t\t\t\tsc.SetState(lineState);\n\t\t\t}\n\t\t\telse if (sc.Match('@', '\\\"')) {\n\t\t\t\tsc.SetState(SCE_ECL_VERBATIM);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (setQualified.Contains(sc.ch) && sc.chNext == '\\'') {\n\t\t\t\tsc.SetState(SCE_ECL_CHARACTER);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tif (lastWordWasUUID) {\n\t\t\t\t\tsc.SetState(SCE_ECL_UUID);\n\t\t\t\t\tlastWordWasUUID = false;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_ECL_NUMBER);\n\t\t\t\t}\n\t\t\t} else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {\n\t\t\t\tif (lastWordWasUUID) {\n\t\t\t\t\tsc.SetState(SCE_ECL_UUID);\n\t\t\t\t\tlastWordWasUUID = false;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_ECL_IDENTIFIER);\n\t\t\t\t}\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tif (sc.Match(\"/**\") || sc.Match(\"/*!\")) {\t// Support of Qt/Doxygen doc. style\n\t\t\t\t\tsc.SetState(SCE_ECL_COMMENTDOC);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_ECL_COMMENT);\n\t\t\t\t}\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tif ((sc.Match(\"///\") && !sc.Match(\"////\")) || sc.Match(\"//!\"))\n\t\t\t\t\t// Support of Qt/Doxygen doc. style\n\t\t\t\t\tsc.SetState(SCE_ECL_COMMENTLINEDOC);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_ECL_COMMENTLINE);\n\t\t\t} else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite)) {\n\t\t\t\tsc.SetState(SCE_ECL_REGEX);\t// JavaScript's RegEx\n//\t\t\t} else if (sc.ch == '\\\"') {\n//\t\t\t\tsc.SetState(SCE_ECL_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_ECL_CHARACTER);\n\t\t\t} else if (sc.ch == '#' && visibleChars == 0) {\n\t\t\t\t// Preprocessor commands are alone on their line\n\t\t\t\tsc.SetState(SCE_ECL_PREPROCESSOR);\n\t\t\t\t// Skip whitespace between # and preprocessor word\n\t\t\t\tdo {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} while ((sc.ch == ' ' || sc.ch == '\\t') && sc.More());\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.SetState(SCE_ECL_DEFAULT);\n\t\t\t\t}\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_ECL_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t\tif (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {\n\t\t\tchPrevNonWhite = sc.ch;\n\t\t\tvisibleChars++;\n\t\t}\n\t\tcontinuationLine = false;\n\t}\n\tsc.Complete();\n\n}\n\nstatic bool IsStreamCommentStyle(int style) {\n\treturn style == SCE_ECL_COMMENT ||\n\t\tstyle == SCE_ECL_COMMENTDOC ||\n\t\tstyle == SCE_ECL_COMMENTDOCKEYWORD ||\n\t\tstyle == SCE_ECL_COMMENTDOCKEYWORDERROR;\n}\n\nstatic bool MatchNoCase(Accessor & styler, Sci_PositionU & pos, const char *s) {\n\tSci_Position i=0;\n\tfor (; *s; i++) {\n\t\tchar compare_char = tolower(*s);\n\t\tchar styler_char = tolower(styler.SafeGetCharAt(pos+i));\n\t\tif (compare_char != styler_char)\n\t\t\treturn false;\n\t\ts++;\n\t}\n\tpos+=i-1;\n\treturn true;\n}\n\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\nstatic void FoldEclDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\t\t\t\t   WordList *[], Accessor &styler) {\n\tbool foldComment = true;\n\tbool foldPreprocessor = true;\n\tbool foldCompact = true;\n\tbool foldAtElse = true;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelMinCurrent = levelCurrent;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (foldComment && IsStreamCommentStyle(style)) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_ECL_COMMENTLINEDOC)) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_ECL_COMMENTLINEDOC) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (foldComment && (style == SCE_ECL_COMMENTLINE)) {\n\t\t\tif ((ch == '/') && (chNext == '/')) {\n\t\t\t\tchar chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (foldPreprocessor && (style == SCE_ECL_PREPROCESSOR)) {\n\t\t\tif (ch == '#') {\n\t\t\t\tSci_PositionU j = i + 1;\n\t\t\t\twhile ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tif (MatchNoCase(styler, j, \"region\") || MatchNoCase(styler, j, \"if\")) {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (MatchNoCase(styler, j, \"endregion\") || MatchNoCase(styler, j, \"end\")) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (style == SCE_ECL_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\t// Measure the minimum before a '{' to allow\n\t\t\t\t// folding on \"} else {\"\n\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t}\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (style == SCE_ECL_WORD2) {\n\t\t\tif (MatchNoCase(styler, i, \"record\") || MatchNoCase(styler, i, \"transform\") || MatchNoCase(styler, i, \"type\") || MatchNoCase(styler, i, \"function\") ||\n\t\t\t\tMatchNoCase(styler, i, \"module\") || MatchNoCase(styler, i, \"service\") || MatchNoCase(styler, i, \"interface\") || MatchNoCase(styler, i, \"ifblock\") ||\n\t\t\t\tMatchNoCase(styler, i, \"macro\") || MatchNoCase(styler, i, \"beginc++\")) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (MatchNoCase(styler, i, \"endmacro\") || MatchNoCase(styler, i, \"endc++\") || MatchNoCase(styler, i, \"end\")) {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL || (i == endPos-1)) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tif (foldAtElse) {\n\t\t\t\tlevelUse = levelMinCurrent;\n\t\t\t}\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelMinCurrent = levelCurrent;\n\t\t\tif (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) {\n\t\t\t\t// There is an empty line at end of file so give it same level and empty\n\t\t\t\tstyler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);\n\t\t\t}\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\t}\n}\n\nstatic const char * const EclWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmECL(\n   SCLEX_ECL,\n   ColouriseEclDoc,\n   \"ecl\",\n   FoldEclDoc,\n   EclWordListDesc);\n"
  },
  {
    "path": "lexers/LexEDIFACT.cxx",
    "content": "// Scintilla Lexer for EDIFACT\n// @file LexEDIFACT.cxx\n// Written by Iain Clarke, IMCSoft & Inobiz AB.\n// EDIFACT documented here: https://www.unece.org/cefact/edifact/welcome.html\n// and more readably here: https://en.wikipedia.org/wiki/EDIFACT\n// This code is subject to the same license terms as the rest of the scintilla project:\n// The License.txt file describes the conditions under which this software may be distributed.\n//\n\n// Header order must match order in scripts/HeaderOrder.txt\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"LexAccessor.h\"\n#include \"LexerModule.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nclass LexerEDIFACT : public DefaultLexer\n{\npublic:\n\tLexerEDIFACT();\n\tvirtual ~LexerEDIFACT() {} // virtual destructor, as we inherit from ILexer\n\n\tstatic ILexer5 *Factory() {\n\t\treturn new LexerEDIFACT;\n\t}\n\n\tint SCI_METHOD Version() const override\n\t{\n\t\treturn lvRelease5;\n\t}\n\tvoid SCI_METHOD Release() override\n\t{\n\t\tdelete this;\n\t}\n\n\tconst char * SCI_METHOD PropertyNames() override\n\t{\n\t\treturn \"fold\\nlexer.edifact.highlight.un.all\";\n\t}\n\tint SCI_METHOD PropertyType(const char *) override\n\t{\n\t\treturn SC_TYPE_BOOLEAN; // Only one property!\n\t}\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override\n\t{\n\t\tif (!strcmp(name, \"fold\"))\n\t\t\treturn \"Whether to apply folding to document or not\";\n\t\tif (!strcmp(name, \"lexer.edifact.highlight.un.all\"))\n\t\t\treturn \"Whether to apply UN* highlighting to all UN segments, or just to UNH\";\n\t\treturn NULL;\n\t}\n\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override\n\t{\n\t\tif (!strcmp(key, \"fold\"))\n\t\t{\n\t\t\tm_bFold = strcmp(val, \"0\") ? true : false;\n\t\t\treturn 0;\n\t\t}\n\t\tif (!strcmp(key, \"lexer.edifact.highlight.un.all\"))\t// GetProperty\n\t\t{\n\t\t\tm_bHighlightAllUN = strcmp(val, \"0\") ? true : false;\n\t\t\treturn 0;\n\t\t}\n\t\treturn -1;\n\t}\n\n\tconst char * SCI_METHOD PropertyGet(const char *key) override\n\t{\n\t\tm_lastPropertyValue = \"\";\n\t\tif (!strcmp(key, \"fold\"))\n\t\t{\n\t\t\tm_lastPropertyValue = m_bFold ? \"1\" : \"0\";\n\t\t}\n\t\tif (!strcmp(key, \"lexer.edifact.highlight.un.all\"))\t// GetProperty\n\t\t{\n\t\t\tm_lastPropertyValue = m_bHighlightAllUN ? \"1\" : \"0\";\n\t\t}\n\t\treturn m_lastPropertyValue.c_str();\n\t}\n\n\tconst char * SCI_METHOD DescribeWordListSets() override\n\t{\n\t\treturn NULL;\n\t}\n\tSci_Position SCI_METHOD WordListSet(int, const char *) override\n\t{\n\t\treturn -1;\n\t}\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid * SCI_METHOD PrivateCall(int, void *) override\n\t{\n\t\treturn NULL;\n\t}\n\nprotected:\n\tSci_Position InitialiseFromUNA(IDocument *pAccess, Sci_PositionU MaxLength);\n\tSci_Position FindPreviousEnd(IDocument *pAccess, Sci_Position startPos) const;\n\tSci_Position ForwardPastWhitespace(IDocument *pAccess, Sci_Position startPos, Sci_Position MaxLength) const;\n\tint DetectSegmentHeader(char SegmentHeader[3]) const;\n\n\tbool m_bFold;\n\n\t// property lexer.edifact.highlight.un.all\n\t//\tSet to 0 to highlight only UNA segments, or 1 to highlight all UNx segments.\n\tbool m_bHighlightAllUN;\n\n\tchar m_chComponent;\n\tchar m_chData;\n\tchar m_chDecimal;\n\tchar m_chRelease;\n\tchar m_chSegment;\n\n\tstd::string m_lastPropertyValue;\n};\n\nextern const LexerModule lmEDIFACT(SCLEX_EDIFACT, LexerEDIFACT::Factory, \"edifact\");\n\n///////////////////////////////////////////////////////////////////////////////\n\n\n\n///////////////////////////////////////////////////////////////////////////////\n\nLexerEDIFACT::LexerEDIFACT() : DefaultLexer(\"edifact\", SCLEX_EDIFACT)\n{\n\tm_bFold = false;\n\tm_bHighlightAllUN = false;\n\tm_chComponent = ':';\n\tm_chData = '+';\n\tm_chDecimal = '.';\n\tm_chRelease = '?';\n\tm_chSegment = '\\'';\n}\n\nvoid LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess)\n{\n\tSci_PositionU posFinish = startPos + length;\n\tInitialiseFromUNA(pAccess, posFinish);\n\n\t// Look backwards for a ' or a document beginning\n\tSci_PositionU posCurrent = FindPreviousEnd(pAccess, startPos);\n\t// And jump past the ' if this was not the beginning of the document\n\tif (posCurrent != 0)\n\t\tposCurrent++;\n\n\t// Style buffer, so we're not issuing loads of notifications\n\tLexAccessor styler (pAccess);\n\tpAccess->StartStyling(posCurrent);\n\tstyler.StartSegment(posCurrent);\n\tSci_Position posSegmentStart = -1;\n\n\twhile ((posCurrent < posFinish) && (posSegmentStart == -1))\n\t{\n\t\tposCurrent = ForwardPastWhitespace(pAccess, posCurrent, posFinish);\n\t\t// Mark whitespace as default\n\t\tif (posCurrent > 0)\n\t\t\tstyler.ColourTo(posCurrent - 1, SCE_EDI_DEFAULT);\n\t\tif (posCurrent >= posFinish)\n\t\t\tbreak;\n\n\t\t// Does is start with 3 charaters? ie, UNH\n\t\tchar SegmentHeader[4] = { 0 };\n\t\tpAccess->GetCharRange(SegmentHeader, posCurrent, 3);\n\n\t\tint SegmentStyle = DetectSegmentHeader(SegmentHeader);\n\t\tif (SegmentStyle == SCE_EDI_BADSEGMENT)\n\t\t\tbreak;\n\t\tif (SegmentStyle == SCE_EDI_UNA)\n\t\t{\n\t\t\tposCurrent += 9;\n\t\t\tstyler.ColourTo(posCurrent - 1, SCE_EDI_UNA); // UNA\n\t\t\tcontinue;\n\t\t}\n\t\tposSegmentStart = posCurrent;\n\t\tposCurrent += 3;\n\n\t\tstyler.ColourTo(posCurrent - 1, SegmentStyle); // UNH etc\n\n\t\t// Colour in the rest of the segment\n\t\tfor (char c; posCurrent < posFinish; posCurrent++)\n\t\t{\n\t\t\tpAccess->GetCharRange(&c, posCurrent, 1);\n\n\t\t\tif (c == m_chRelease) // ? escape character, check first, in case of ?'\n\t\t\t\tposCurrent++;\n\t\t\telse if (c == m_chSegment) // '\n\t\t\t{\n\t\t\t\t// Make sure the whole segment is on one line. styler won't let us go back in time, so we'll settle for marking the ' as bad.\n\t\t\t\tSci_Position lineSegmentStart = pAccess->LineFromPosition(posSegmentStart);\n\t\t\t\tSci_Position lineSegmentEnd = pAccess->LineFromPosition(posCurrent);\n\t\t\t\tif (lineSegmentStart == lineSegmentEnd)\n\t\t\t\t\tstyler.ColourTo(posCurrent, SCE_EDI_SEGMENTEND);\n\t\t\t\telse\n\t\t\t\t\tstyler.ColourTo(posCurrent, SCE_EDI_BADSEGMENT);\n\t\t\t\tposSegmentStart = -1;\n\t\t\t\tposCurrent++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (c == m_chComponent) // :\n\t\t\t\tstyler.ColourTo(posCurrent, SCE_EDI_SEP_COMPOSITE);\n\t\t\telse if (c == m_chData) // +\n\t\t\t\tstyler.ColourTo(posCurrent, SCE_EDI_SEP_ELEMENT);\n\t\t\telse\n\t\t\t\tstyler.ColourTo(posCurrent, SCE_EDI_DEFAULT);\n\t\t}\n\t}\n\tstyler.Flush();\n\n\tif (posSegmentStart == -1)\n\t\treturn;\n\n\tpAccess->StartStyling(posSegmentStart);\n\tpAccess->SetStyleFor(posFinish - posSegmentStart, SCE_EDI_BADSEGMENT);\n}\n\nvoid LexerEDIFACT::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess)\n{\n\tif (!m_bFold)\n\t\treturn;\n\n\tSci_PositionU endPos = startPos + length;\n\tstartPos = FindPreviousEnd(pAccess, startPos);\n\tchar c;\n\tchar SegmentHeader[4] = { 0 };\n\n\tbool AwaitingSegment = true;\n\tSci_PositionU currLine = pAccess->LineFromPosition(startPos);\n\tint levelCurrentStyle = SC_FOLDLEVELBASE;\n\tif (currLine > 0)\n\t\tlevelCurrentStyle = pAccess->GetLevel(currLine - 1); // bottom 12 bits are level\n\tint indentCurrent = levelCurrentStyle & SC_FOLDLEVELNUMBERMASK;\n\tint indentNext = indentCurrent;\n\n\twhile (startPos < endPos)\n\t{\n\t\tpAccess->GetCharRange(&c, startPos, 1);\n\t\tswitch (c)\n\t\t{\n\t\tcase '\\t':\n\t\tcase '\\r':\n\t\tcase ' ':\n\t\t\tstartPos++;\n\t\t\tcontinue;\n\t\tcase '\\n':\n\t\t\tcurrLine = pAccess->LineFromPosition(startPos);\n\t\t\tpAccess->SetLevel(currLine, levelCurrentStyle | indentCurrent);\n\t\t\tstartPos++;\n\t\t\tlevelCurrentStyle = SC_FOLDLEVELBASE;\n\t\t\tindentCurrent = indentNext;\n\t\t\tcontinue;\n\t\t}\n\t\tif (c == m_chRelease)\n\t\t{\n\t\t\tstartPos += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (c == m_chSegment)\n\t\t{\n\t\t\tAwaitingSegment = true;\n\t\t\tstartPos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!AwaitingSegment)\n\t\t{\n\t\t\tstartPos++;\n\t\t\tcontinue;\n\t\t}\n\t\t\n\t\t// Segment!\n\t\tpAccess->GetCharRange(SegmentHeader, startPos, 3);\n\t\tif (SegmentHeader[0] != 'U' || SegmentHeader[1] != 'N')\n\t\t{\n\t\t\tstartPos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tAwaitingSegment = false;\n\t\tswitch (SegmentHeader[2])\n\t\t{\n\t\tcase 'H':\n\t\tcase 'G':\n\t\t\tindentNext++;\n\t\t\tlevelCurrentStyle = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\t\tbreak;\n\n\t\tcase 'T':\n\t\tcase 'E':\n\t\t\tif (indentNext > 0)\n\t\t\t\tindentNext--;\n\t\t\tbreak;\n\t\t}\n\n\t\tstartPos += 3;\n\t}\n}\n\nSci_Position LexerEDIFACT::InitialiseFromUNA(IDocument *pAccess, Sci_PositionU MaxLength)\n{\n\tMaxLength -= 9; // drop 9 chars, to give us room for UNA:+.? '\n\n\tSci_PositionU startPos = 0;\n\tstartPos += ForwardPastWhitespace(pAccess, 0, MaxLength);\n\tif (startPos < MaxLength)\n\t{\n\t\tchar bufUNA[9];\n\t\tpAccess->GetCharRange(bufUNA, startPos, 9);\n\n\t\t// Check it's UNA segment\n\t\tif (!memcmp(bufUNA, \"UNA\", 3))\n\t\t{\n\t\t\tm_chComponent = bufUNA[3];\n\t\t\tm_chData = bufUNA[4];\n\t\t\tm_chDecimal = bufUNA[5];\n\t\t\tm_chRelease = bufUNA[6];\n\t\t\t// bufUNA [7] should be space - reserved.\n\t\t\tm_chSegment = bufUNA[8];\n\n\t\t\treturn 0; // success!\n\t\t}\n\t}\n\n\t// We failed to find a UNA, so drop to defaults\n\tm_chComponent = ':';\n\tm_chData = '+';\n\tm_chDecimal = '.';\n\tm_chRelease = '?';\n\tm_chSegment = '\\'';\n\n\treturn -1;\n}\n\nSci_Position LexerEDIFACT::ForwardPastWhitespace(IDocument *pAccess, Sci_Position startPos, Sci_Position MaxLength) const\n{\n\tchar c;\n\n\twhile (startPos < MaxLength)\n\t{\n\t\tpAccess->GetCharRange(&c, startPos, 1);\n\t\tswitch (c)\n\t\t{\n\t\tcase '\\t':\n\t\tcase '\\r':\n\t\tcase '\\n':\n\t\tcase ' ':\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn startPos;\n\t\t}\n\n\t\tstartPos++;\n\t}\n\n\treturn MaxLength;\n}\n\nint LexerEDIFACT::DetectSegmentHeader(char SegmentHeader[3]) const\n{\n\tif (\n\t\tSegmentHeader[0] < 'A' || SegmentHeader[0] > 'Z' ||\n\t\tSegmentHeader[1] < 'A' || SegmentHeader[1] > 'Z' ||\n\t\tSegmentHeader[2] < 'A' || SegmentHeader[2] > 'Z')\n\t\treturn SCE_EDI_BADSEGMENT;\n\n\tif (!memcmp(SegmentHeader, \"UNA\", 3))\n\t\treturn SCE_EDI_UNA;\n\n\tif (m_bHighlightAllUN && !memcmp(SegmentHeader, \"UN\", 2))\n\t\treturn SCE_EDI_UNH;\n\telse if (!memcmp(SegmentHeader, \"UNH\", 3))\n\t\treturn SCE_EDI_UNH;\n\telse if (!memcmp(SegmentHeader, \"UNG\", 3))\n\t\treturn SCE_EDI_UNH;\n\n\treturn SCE_EDI_SEGMENTSTART;\n}\n\n// Look backwards for a ' or a document beginning\nSci_Position LexerEDIFACT::FindPreviousEnd(IDocument *pAccess, Sci_Position startPos) const\n{\n\tfor (char c; startPos > 0; startPos--)\n\t{\n\t\tpAccess->GetCharRange(&c, startPos, 1);\n\t\tif (c == m_chSegment)\n\t\t\treturn startPos;\n\t}\n\t// We didn't find a ', so just go with the beginning\n\treturn 0;\n}\n\n\n"
  },
  {
    "path": "lexers/LexEScript.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexEScript.cxx\n ** Lexer for ESCRIPT\n **/\n// Copyright 2003 by Patrizio Bekerle (patrizio@bekerle.com)\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');\n}\n\nstatic inline bool IsAWordStart(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\n\n\nstatic void ColouriseESCRIPTDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\n\t// Do not leak onto next line\n\t/*if (initStyle == SCE_ESCRIPT_STRINGEOL)\n\t\tinitStyle = SCE_ESCRIPT_DEFAULT;*/\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tbool caseSensitive = styler.GetPropertyInt(\"escript.case.sensitive\", 0) != 0;\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\t/*if (sc.atLineStart && (sc.state == SCE_ESCRIPT_STRING)) {\n\t\t\t// Prevent SCE_ESCRIPT_STRINGEOL from leaking back to previous line\n\t\t\tsc.SetState(SCE_ESCRIPT_STRING);\n\t\t}*/\n\n\t\t// Handle line continuation generically.\n\t\tif (sc.ch == '\\\\') {\n\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_ESCRIPT_OPERATOR || sc.state == SCE_ESCRIPT_BRACE) {\n\t\t\tsc.SetState(SCE_ESCRIPT_DEFAULT);\n\t\t} else if (sc.state == SCE_ESCRIPT_NUMBER) {\n\t\t\tif (!IsADigit(sc.ch) || sc.ch != '.') {\n\t\t\t\tsc.SetState(SCE_ESCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_ESCRIPT_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch) || (sc.ch == '.')) {\n\t\t\t\tchar s[100];\n\t\t\t\tif (caseSensitive) {\n\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t} else {\n\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t}\n\n//\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\n                                if (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_ESCRIPT_WORD);\n\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_ESCRIPT_WORD2);\n\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_ESCRIPT_WORD3);\n                                        // sc.state = SCE_ESCRIPT_IDENTIFIER;\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_ESCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_ESCRIPT_COMMENT) {\n\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_ESCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_ESCRIPT_COMMENTDOC) {\n\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_ESCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_ESCRIPT_COMMENTLINE) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_ESCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_ESCRIPT_STRING) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\\\') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_ESCRIPT_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_ESCRIPT_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_ESCRIPT_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch) || (sc.ch == '#')) {\n\t\t\t\tsc.SetState(SCE_ESCRIPT_IDENTIFIER);\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tsc.SetState(SCE_ESCRIPT_COMMENT);\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tsc.SetState(SCE_ESCRIPT_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_ESCRIPT_STRING);\n\t\t\t\t//} else if (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t} else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') {\n\t\t\t\tsc.SetState(SCE_ESCRIPT_OPERATOR);\n\t\t\t} else if (sc.ch == '{' || sc.ch == '}') {\n\t\t\t\tsc.SetState(SCE_ESCRIPT_BRACE);\n\t\t\t}\n\t\t}\n\n\t}\n\tsc.Complete();\n}\n\n\nstatic int classifyFoldPointESCRIPT(const char* s, const char* prevWord) {\n\tint lev = 0;\n\tif (strcmp(prevWord, \"end\") == 0) return lev;\n\tif ((strcmp(prevWord, \"else\") == 0 && strcmp(s, \"if\") == 0) || strcmp(s, \"elseif\") == 0)\n\t\treturn -1;\n\n        if (strcmp(s, \"for\") == 0 || strcmp(s, \"foreach\") == 0\n\t    || strcmp(s, \"program\") == 0 || strcmp(s, \"function\") == 0\n\t    || strcmp(s, \"while\") == 0 || strcmp(s, \"case\") == 0\n\t    || strcmp(s, \"if\") == 0 ) {\n\t\tlev = 1;\n\t} else if ( strcmp(s, \"endfor\") == 0 || strcmp(s, \"endforeach\") == 0\n\t    || strcmp(s, \"endprogram\") == 0 || strcmp(s, \"endfunction\") == 0\n\t    || strcmp(s, \"endwhile\") == 0 || strcmp(s, \"endcase\") == 0\n\t    || strcmp(s, \"endif\") == 0 ) {\n\t\tlev = -1;\n\t}\n\n\treturn lev;\n}\n\n\nstatic bool IsStreamCommentStyle(int style) {\n\treturn style == SCE_ESCRIPT_COMMENT ||\n\t       style == SCE_ESCRIPT_COMMENTDOC ||\n\t       style == SCE_ESCRIPT_COMMENTLINE;\n}\n\nstatic void FoldESCRIPTDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler) {\n\t//~ bool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\t// Do not know how to fold the comment at the moment.\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n        bool foldComment = true;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\n\tSci_Position lastStart = 0;\n\tchar prevWord[32] = \"\";\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\n\t\tif (foldComment && IsStreamCommentStyle(style)) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\tif (foldComment && (style == SCE_ESCRIPT_COMMENTLINE)) {\n\t\t\tif ((ch == '/') && (chNext == '/')) {\n\t\t\t\tchar chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (stylePrev == SCE_ESCRIPT_DEFAULT && style == SCE_ESCRIPT_WORD3)\n\t\t{\n\t\t\t// Store last word start point.\n\t\t\tlastStart = i;\n\t\t}\n\n\t\tif (style == SCE_ESCRIPT_WORD3) {\n\t\t\tif(iswordchar(ch) && !iswordchar(chNext)) {\n\t\t\t\tchar s[32];\n\t\t\t\tSci_PositionU j;\n\t\t\t\tfor(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {\n\t\t\t\t\ts[j] = static_cast<char>(tolower(styler[lastStart + j]));\n\t\t\t\t}\n\t\t\t\ts[j] = '\\0';\n\t\t\t\tlevelCurrent += classifyFoldPointESCRIPT(s, prevWord);\n\t\t\t\tstrcpy(prevWord, s);\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t\tstrcpy(prevWord, \"\");\n\t\t}\n\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\n\n\nstatic const char * const ESCRIPTWordLists[] = {\n\t\"Primary keywords and identifiers\",\n\t\"Intrinsic functions\",\n\t\"Extended and user defined functions\",\n\t0,\n};\n\nextern const LexerModule lmESCRIPT(SCLEX_ESCRIPT, ColouriseESCRIPTDoc, \"escript\", FoldESCRIPTDoc, ESCRIPTWordLists);\n"
  },
  {
    "path": "lexers/LexEiffel.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexEiffel.cxx\n ** Lexer for Eiffel.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool isEiffelOperator(unsigned int ch) {\n\t// '.' left out as it is used to make up numbers\n\treturn ch == '*' || ch == '/' || ch == '\\\\' || ch == '-' || ch == '+' ||\n\t        ch == '(' || ch == ')' || ch == '=' ||\n\t        ch == '{' || ch == '}' || ch == '~' ||\n\t        ch == '[' || ch == ']' || ch == ';' ||\n\t        ch == '<' || ch == '>' || ch == ',' ||\n\t        ch == '.' || ch == '^' || ch == '%' || ch == ':' ||\n\t\tch == '!' || ch == '@' || ch == '?';\n}\n\nstatic inline bool IsAWordChar(unsigned int  ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\nstatic inline bool IsAWordStart(unsigned int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\nstatic void ColouriseEiffelDoc(Sci_PositionU startPos,\n                            Sci_Position length,\n                            int initStyle,\n                            WordList *keywordlists[],\n                            Accessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.state == SCE_EIFFEL_STRINGEOL) {\n\t\t\tif (sc.ch != '\\r' && sc.ch != '\\n') {\n\t\t\t\tsc.SetState(SCE_EIFFEL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_EIFFEL_OPERATOR) {\n\t\t\tsc.SetState(SCE_EIFFEL_DEFAULT);\n\t\t} else if (sc.state == SCE_EIFFEL_WORD) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tif (!keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_EIFFEL_IDENTIFIER);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_EIFFEL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_EIFFEL_NUMBER) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_EIFFEL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_EIFFEL_COMMENTLINE) {\n\t\t\tif (sc.ch == '\\r' || sc.ch == '\\n') {\n\t\t\t\tsc.SetState(SCE_EIFFEL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_EIFFEL_STRING) {\n\t\t\tif (sc.ch == '%') {\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState(SCE_EIFFEL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_EIFFEL_CHARACTER) {\n\t\t\tif (sc.ch == '\\r' || sc.ch == '\\n') {\n\t\t\t\tsc.SetState(SCE_EIFFEL_STRINGEOL);\n\t\t\t} else if (sc.ch == '%') {\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState(SCE_EIFFEL_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.state == SCE_EIFFEL_DEFAULT) {\n\t\t\tif (sc.ch == '-' && sc.chNext == '-') {\n\t\t\t\tsc.SetState(SCE_EIFFEL_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_EIFFEL_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_EIFFEL_CHARACTER);\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.')) {\n\t\t\t\tsc.SetState(SCE_EIFFEL_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_EIFFEL_WORD);\n\t\t\t} else if (isEiffelOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_EIFFEL_OPERATOR);\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic bool IsEiffelComment(Accessor &styler, Sci_Position pos, Sci_Position len) {\n\treturn len>1 && styler[pos]=='-' && styler[pos+1]=='-';\n}\n\nstatic void FoldEiffelDocIndent(Sci_PositionU startPos, Sci_Position length, int,\n\t\t\t\t\t\t   WordList *[], Accessor &styler) {\n\tSci_Position lengthDoc = startPos + length;\n\n\t// Backtrack to previous line in case need to fix its fold status\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (startPos > 0) {\n\t\tif (lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t\t}\n\t}\n\tint spaceFlags = 0;\n\tint indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsEiffelComment);\n\tchar chNext = styler[startPos];\n\tfor (Sci_Position i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n') || (i == lengthDoc)) {\n\t\t\tint lev = indentCurrent;\n\t\t\tint indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsEiffelComment);\n\t\t\tif (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n\t\t\t\t// Only non whitespace lines can be headers\n\t\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {\n\t\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {\n\t\t\t\t\t// Line after is blank so check the next - maybe should continue further?\n\t\t\t\t\tint spaceFlags2 = 0;\n\t\t\t\t\tint indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsEiffelComment);\n\t\t\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {\n\t\t\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tindentCurrent = indentNext;\n\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\tlineCurrent++;\n\t\t}\n\t}\n}\n\nstatic void FoldEiffelDocKeyWords(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],\n                       Accessor &styler) {\n\tSci_PositionU lengthDoc = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint stylePrev = 0;\n\tint styleNext = styler.StyleAt(startPos);\n\t// lastDeferred should be determined by looking back to last keyword in case\n\t// the \"deferred\" is on a line before \"class\"\n\tbool lastDeferred = false;\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif ((stylePrev != SCE_EIFFEL_WORD) && (style == SCE_EIFFEL_WORD)) {\n\t\t\tchar s[20];\n\t\t\tSci_PositionU j = 0;\n\t\t\twhile ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {\n\t\t\t\ts[j] = styler[i + j];\n\t\t\t\tj++;\n\t\t\t}\n\t\t\ts[j] = '\\0';\n\n\t\t\tif (\n\t\t\t\t(strcmp(s, \"check\") == 0) ||\n\t\t\t\t(strcmp(s, \"debug\") == 0) ||\n\t\t\t\t(strcmp(s, \"deferred\") == 0) ||\n\t\t\t\t(strcmp(s, \"do\") == 0) ||\n\t\t\t\t(strcmp(s, \"from\") == 0) ||\n\t\t\t\t(strcmp(s, \"if\") == 0) ||\n\t\t\t\t(strcmp(s, \"inspect\") == 0) ||\n\t\t\t\t(strcmp(s, \"once\") == 0)\n\t\t\t)\n\t\t\t\tlevelCurrent++;\n\t\t\tif (!lastDeferred && (strcmp(s, \"class\") == 0))\n\t\t\t\tlevelCurrent++;\n\t\t\tif (strcmp(s, \"end\") == 0)\n\t\t\t\tlevelCurrent--;\n\t\t\tlastDeferred = strcmp(s, \"deferred\") == 0;\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t\tstylePrev = style;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const eiffelWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, \"eiffel\", FoldEiffelDocIndent, eiffelWordListDesc);\nextern const LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, \"eiffelkw\", FoldEiffelDocKeyWords, eiffelWordListDesc);\n"
  },
  {
    "path": "lexers/LexErlang.cxx",
    "content": "// Scintilla source code edit control\n// Encoding: UTF-8\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n/** @file LexErlang.cxx\n ** Lexer for Erlang.\n ** Enhanced by Etienne 'Lenain' Girondel (lenaing@gmail.com)\n ** Originally wrote by Peter-Henry Mander,\n ** based on Matlab lexer by José Fonseca.\n **/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic int is_radix(int radix, int ch) {\n\tint digit;\n\n\tif (36 < radix || 2 > radix)\n\t\treturn 0;\n\n\tif (isdigit(ch)) {\n\t\tdigit = ch - '0';\n\t} else if (isalnum(ch)) {\n\t\tdigit = toupper(ch) - 'A' + 10;\n\t} else {\n\t\treturn 0;\n\t}\n\n\treturn (digit < radix);\n}\n\ntypedef enum {\n\tSTATE_NULL,\n\tCOMMENT,\n\tCOMMENT_FUNCTION,\n\tCOMMENT_MODULE,\n\tCOMMENT_DOC,\n\tCOMMENT_DOC_MACRO,\n\tATOM_UNQUOTED,\n\tATOM_QUOTED,\n\tNODE_NAME_UNQUOTED,\n\tNODE_NAME_QUOTED,\n\tMACRO_START,\n\tMACRO_UNQUOTED,\n\tMACRO_QUOTED,\n\tRECORD_START,\n\tRECORD_UNQUOTED,\n\tRECORD_QUOTED,\n\tNUMERAL_START,\n\tNUMERAL_BASE_VALUE,\n\tNUMERAL_FLOAT,\n\tNUMERAL_EXPONENT,\n\tPREPROCESSOR\n} atom_parse_state_t;\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (ch != ' ') && (isalnum(ch) || ch == '_');\n}\n\nstatic void ColouriseErlangDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\t\t\t\t\t\t\tWordList *keywordlists[], Accessor &styler) {\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tWordList &reservedWords = *keywordlists[0];\n\tWordList &erlangBIFs = *keywordlists[1];\n\tWordList &erlangPreproc = *keywordlists[2];\n\tWordList &erlangModulesAtt = *keywordlists[3];\n\tWordList &erlangDoc = *keywordlists[4];\n\tWordList &erlangDocMacro = *keywordlists[5];\n\tint radix_digits = 0;\n\tint exponent_digits = 0;\n\tatom_parse_state_t parse_state = STATE_NULL;\n\tatom_parse_state_t old_parse_state = STATE_NULL;\n\tbool to_late_to_comment = false;\n\tchar cur[100];\n\tint old_style = SCE_ERLANG_DEFAULT;\n\n\tstyler.StartAt(startPos);\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\tint style = SCE_ERLANG_DEFAULT;\n\t\tif (STATE_NULL != parse_state) {\n\n\t\t\tswitch (parse_state) {\n\n\t\t\t\tcase STATE_NULL : sc.SetState(SCE_ERLANG_DEFAULT); break;\n\n\t\t\t/* COMMENTS ------------------------------------------------------*/\n\t\t\t\tcase COMMENT : {\n\t\t\t\t\tif (sc.ch != '%') {\n\t\t\t\t\t\tto_late_to_comment = true;\n\t\t\t\t\t} else if (!to_late_to_comment && sc.ch == '%') {\n\t\t\t\t\t\t// Switch to comment level 2 (Function)\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_COMMENT_FUNCTION);\n\t\t\t\t\t\told_style = SCE_ERLANG_COMMENT_FUNCTION;\n\t\t\t\t\t\tparse_state = COMMENT_FUNCTION;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// V--- Falling through!\n\t\t\t\t// Falls through.\n\t\t\t\tcase COMMENT_FUNCTION : {\n\t\t\t\t\tif (sc.ch != '%') {\n\t\t\t\t\t\tto_late_to_comment = true;\n\t\t\t\t\t} else if (!to_late_to_comment && sc.ch == '%') {\n\t\t\t\t\t\t// Switch to comment level 3 (Module)\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_COMMENT_MODULE);\n\t\t\t\t\t\told_style = SCE_ERLANG_COMMENT_MODULE;\n\t\t\t\t\t\tparse_state = COMMENT_MODULE;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// V--- Falling through!\n\t\t\t\t// Falls through.\n\t\t\t\tcase COMMENT_MODULE : {\n\t\t\t\t\tif (parse_state != COMMENT) {\n\t\t\t\t\t\t// Search for comment documentation\n\t\t\t\t\t\tif (sc.chNext == '@') {\n\t\t\t\t\t\t\told_parse_state = parse_state;\n\t\t\t\t\t\t\tparse_state = ('{' == sc.ch)\n\t\t\t\t\t\t\t\t\t\t\t? COMMENT_DOC_MACRO\n\t\t\t\t\t\t\t\t\t\t\t: COMMENT_DOC;\n\t\t\t\t\t\t\tsc.ForwardSetState(sc.state);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// All comments types fall here.\n\t\t\t\t\tif (sc.MatchLineEnd()) {\n\t\t\t\t\t\tto_late_to_comment = false;\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t\tcase COMMENT_DOC :\n\t\t\t\t// V--- Falling through!\n\t\t\t\tcase COMMENT_DOC_MACRO : {\n\n\t\t\t\t\tif (!isalnum(sc.ch)) {\n\t\t\t\t\t\t// Try to match documentation comment\n\t\t\t\t\t\tsc.GetCurrent(cur, sizeof(cur));\n\n\t\t\t\t\t\tif (parse_state == COMMENT_DOC_MACRO\n\t\t\t\t\t\t\t&& erlangDocMacro.InList(cur)) {\n\t\t\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);\n\t\t\t\t\t\t\t\twhile (sc.ch != '}' && !sc.atLineEnd)\n\t\t\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t} else if (erlangDoc.InList(cur)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_COMMENT_DOC);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.ChangeState(old_style);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Switch back to old state\n\t\t\t\t\t\tsc.SetState(old_style);\n\t\t\t\t\t\tparse_state = old_parse_state;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (sc.MatchLineEnd()) {\n\t\t\t\t\t\tto_late_to_comment = false;\n\t\t\t\t\t\tsc.ChangeState(old_style);\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t/* -------------------------------------------------------------- */\n\t\t\t/* Atoms ---------------------------------------------------------*/\n\t\t\t\tcase ATOM_UNQUOTED : {\n\t\t\t\t\tif ('@' == sc.ch){\n\t\t\t\t\t\tparse_state = NODE_NAME_UNQUOTED;\n\t\t\t\t\t} else if (sc.ch == ':') {\n\t\t\t\t\t\t// Searching for module name\n\t\t\t\t\t\tif (sc.chNext == ' ') {\n\t\t\t\t\t\t\t// error\n\t\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_UNKNOWN);\n\t\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t\tif (isalnum(sc.ch) || (sc.ch == '\\''))  {\n\t\t\t\t\t\t\t\tsc.GetCurrent(cur, sizeof(cur));\n\t\t\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_MODULES);\n\t\t\t\t\t\t\t\tsc.SetState(SCE_ERLANG_MODULES);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (sc.ch == '\\'') {\n\t\t\t\t\t\t\t\tparse_state = ATOM_QUOTED;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (!IsAWordChar(sc.ch)) {\n\n\t\t\t\t\t\tsc.GetCurrent(cur, sizeof(cur));\n\t\t\t\t\t\tif (reservedWords.InList(cur)) {\n\t\t\t\t\t\t\tstyle = SCE_ERLANG_KEYWORD;\n\t\t\t\t\t\t} else if (erlangBIFs.InList(cur)\n\t\t\t\t\t\t\t\t\t&& strcmp(cur,\"erlang:\")){\n\t\t\t\t\t\t\tstyle = SCE_ERLANG_BIFS;\n\t\t\t\t\t\t} else if (sc.ch == '(' || '/' == sc.ch){\n\t\t\t\t\t\t\tstyle = SCE_ERLANG_FUNCTION_NAME;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstyle = SCE_ERLANG_ATOM;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsc.ChangeState(style);\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\n\t\t\t\t} break;\n\n\t\t\t\tcase ATOM_QUOTED : {\n\t\t\t\t\tif ( '@' == sc.ch ){\n\t\t\t\t\t\tparse_state = NODE_NAME_QUOTED;\n\t\t\t\t\t} else if ('\\'' == sc.ch && '\\\\' != sc.chPrev) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_ATOM_QUOTED);\n\t\t\t\t\t\tsc.ForwardSetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t/* -------------------------------------------------------------- */\n\t\t\t/* Node names ----------------------------------------------------*/\n\t\t\t\tcase NODE_NAME_UNQUOTED : {\n\t\t\t\t\tif ('@' == sc.ch) {\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t} else if (!IsAWordChar(sc.ch)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_NODE_NAME);\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t\tcase NODE_NAME_QUOTED : {\n\t\t\t\t\tif ('@' == sc.ch) {\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t} else if ('\\'' == sc.ch && '\\\\' != sc.chPrev) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_NODE_NAME_QUOTED);\n\t\t\t\t\t\tsc.ForwardSetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t/* -------------------------------------------------------------- */\n\t\t\t/* Records -------------------------------------------------------*/\n\t\t\t\tcase RECORD_START : {\n\t\t\t\t\tif ('\\'' == sc.ch) {\n\t\t\t\t\t\tparse_state = RECORD_QUOTED;\n\t\t\t\t\t} else if (isalpha(sc.ch) && islower(sc.ch)) {\n\t\t\t\t\t\tparse_state = RECORD_UNQUOTED;\n\t\t\t\t\t} else { // error\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t\tcase RECORD_UNQUOTED : {\n\t\t\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_RECORD);\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t\tcase RECORD_QUOTED : {\n\t\t\t\t\tif ('\\'' == sc.ch && '\\\\' != sc.chPrev) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_RECORD_QUOTED);\n\t\t\t\t\t\tsc.ForwardSetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t/* -------------------------------------------------------------- */\n\t\t\t/* Macros --------------------------------------------------------*/\n\t\t\t\tcase MACRO_START : {\n\t\t\t\t\tif ('\\'' == sc.ch) {\n\t\t\t\t\t\tparse_state = MACRO_QUOTED;\n\t\t\t\t\t} else if (isalpha(sc.ch)) {\n\t\t\t\t\t\tparse_state = MACRO_UNQUOTED;\n\t\t\t\t\t} else { // error\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t\tcase MACRO_UNQUOTED : {\n\t\t\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_MACRO);\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t\tcase MACRO_QUOTED : {\n\t\t\t\t\tif ('\\'' == sc.ch && '\\\\' != sc.chPrev) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_MACRO_QUOTED);\n\t\t\t\t\t\tsc.ForwardSetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t/* -------------------------------------------------------------- */\n\t\t\t/* Numerics ------------------------------------------------------*/\n\t\t\t/* Simple integer */\n\t\t\t\tcase NUMERAL_START : {\n\t\t\t\t\tif (isdigit(sc.ch)) {\n\t\t\t\t\t\tradix_digits *= 10;\n\t\t\t\t\t\tradix_digits += sc.ch - '0'; // Assuming ASCII here!\n\t\t\t\t\t} else if ('#' == sc.ch) {\n\t\t\t\t\t\tif (2 > radix_digits || 36 < radix_digits) {\n\t\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tparse_state = NUMERAL_BASE_VALUE;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if ('.' == sc.ch && isdigit(sc.chNext)) {\n\t\t\t\t\t\tradix_digits = 0;\n\t\t\t\t\t\tparse_state = NUMERAL_FLOAT;\n\t\t\t\t\t} else if ('e' == sc.ch || 'E' == sc.ch) {\n\t\t\t\t\t\texponent_digits = 0;\n\t\t\t\t\t\tparse_state = NUMERAL_EXPONENT;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tradix_digits = 0;\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_NUMBER);\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t/* Integer in other base than 10 (x#yyy) */\n\t\t\t\tcase NUMERAL_BASE_VALUE : {\n\t\t\t\t\tif (!is_radix(radix_digits,sc.ch)) {\n\t\t\t\t\t\tradix_digits = 0;\n\n\t\t\t\t\t\tif (!isalnum(sc.ch))\n\t\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_NUMBER);\n\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t/* Float (x.yyy) */\n\t\t\t\tcase NUMERAL_FLOAT : {\n\t\t\t\t\tif ('e' == sc.ch || 'E' == sc.ch) {\n\t\t\t\t\t\texponent_digits = 0;\n\t\t\t\t\t\tparse_state = NUMERAL_EXPONENT;\n\t\t\t\t\t} else if (!isdigit(sc.ch)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_NUMBER);\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t/* Exponent, either integer or float (xEyy, x.yyEzzz) */\n\t\t\t\tcase NUMERAL_EXPONENT : {\n\t\t\t\t\tif (('-' == sc.ch || '+' == sc.ch)\n\t\t\t\t\t\t\t&& (isdigit(sc.chNext))) {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else if (!isdigit(sc.ch)) {\n\t\t\t\t\t\tif (0 < exponent_digits)\n\t\t\t\t\t\t\tsc.ChangeState(SCE_ERLANG_NUMBER);\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t++exponent_digits;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t/* -------------------------------------------------------------- */\n\t\t\t/* Preprocessor --------------------------------------------------*/\n\t\t\t\tcase PREPROCESSOR : {\n\t\t\t\t\tif (!IsAWordChar(sc.ch)) {\n\n\t\t\t\t\t\tsc.GetCurrent(cur, sizeof(cur));\n\t\t\t\t\t\tif (erlangPreproc.InList(cur)) {\n\t\t\t\t\t\t\tstyle = SCE_ERLANG_PREPROC;\n\t\t\t\t\t\t} else if (erlangModulesAtt.InList(cur)) {\n\t\t\t\t\t\t\tstyle = SCE_ERLANG_MODULES_ATT;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsc.ChangeState(style);\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\tparse_state = STATE_NULL;\n\t\t\t\t\t}\n\t\t\t\t} break;\n\n\t\t\t}\n\n\t\t} /* End of : STATE_NULL != parse_state */\n\t\telse\n\t\t{\n\t\t\tswitch (sc.state) {\n\t\t\t\tcase SCE_ERLANG_VARIABLE : {\n\t\t\t\t\tif (!IsAWordChar(sc.ch))\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t} break;\n\t\t\t\tcase SCE_ERLANG_STRING : {\n\t\t\t\t\t if (sc.ch == '\\\"' && sc.chPrev != '\\\\')\n\t\t\t\t\t\tsc.ForwardSetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t} break;\n\t\t\t\tcase SCE_ERLANG_COMMENT : {\n\t\t\t\t\t if (sc.atLineEnd)\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t} break;\n\t\t\t\tcase SCE_ERLANG_CHARACTER : {\n\t\t\t\t\tif (sc.chPrev == '\\\\') {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t} else if (sc.ch != '\\\\') {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t} break;\n\t\t\t\tcase SCE_ERLANG_OPERATOR : {\n\t\t\t\t\tif (sc.chPrev == '.') {\n\t\t\t\t\t\tif (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\\\'\n\t\t\t\t\t\t\t|| sc.ch == '^') {\n\t\t\t\t\t\t\tsc.ForwardSetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\t\t\tsc.ForwardSetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t} break;\n\t\t\t}\n\t\t}\n\n\t\tif (sc.state == SCE_ERLANG_DEFAULT) {\n\t\t\tbool no_new_state = false;\n\n\t\t\tswitch (sc.ch) {\n\t\t\t\tcase '\\\"' : sc.SetState(SCE_ERLANG_STRING); break;\n\t\t\t\tcase '$' : sc.SetState(SCE_ERLANG_CHARACTER); break;\n\t\t\t\tcase '%' : {\n\t\t\t\t\tparse_state = COMMENT;\n\t\t\t\t\tsc.SetState(SCE_ERLANG_COMMENT);\n\t\t\t\t} break;\n\t\t\t\tcase '#' : {\n\t\t\t\t\tparse_state = RECORD_START;\n\t\t\t\t\tsc.SetState(SCE_ERLANG_UNKNOWN);\n\t\t\t\t} break;\n\t\t\t\tcase '?' : {\n\t\t\t\t\tparse_state = MACRO_START;\n\t\t\t\t\tsc.SetState(SCE_ERLANG_UNKNOWN);\n\t\t\t\t} break;\n\t\t\t\tcase '\\'' : {\n\t\t\t\t\tparse_state = ATOM_QUOTED;\n\t\t\t\t\tsc.SetState(SCE_ERLANG_UNKNOWN);\n\t\t\t\t} break;\n\t\t\t\tcase '+' :\n\t\t\t\tcase '-' : {\n\t\t\t\t\tif (IsADigit(sc.chNext)) {\n\t\t\t\t\t\tparse_state = NUMERAL_START;\n\t\t\t\t\t\tradix_digits = 0;\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_UNKNOWN);\n\t\t\t\t\t} else if (sc.ch != '+') {\n\t\t\t\t\t\tparse_state = PREPROCESSOR;\n\t\t\t\t\t\tsc.SetState(SCE_ERLANG_UNKNOWN);\n\t\t\t\t\t}\n\t\t\t\t} break;\n\t\t\t\tdefault : no_new_state = true;\n\t\t\t}\n\n\t\t\tif (no_new_state) {\n\t\t\t\tif (isdigit(sc.ch)) {\n\t\t\t\t\tparse_state = NUMERAL_START;\n\t\t\t\t\tradix_digits = sc.ch - '0';\n\t\t\t\t\tsc.SetState(SCE_ERLANG_UNKNOWN);\n\t\t\t\t} else if (isupper(sc.ch) || '_' == sc.ch) {\n\t\t\t\t\tsc.SetState(SCE_ERLANG_VARIABLE);\n\t\t\t\t} else if (isalpha(sc.ch)) {\n\t\t\t\t\tparse_state = ATOM_UNQUOTED;\n\t\t\t\t\tsc.SetState(SCE_ERLANG_UNKNOWN);\n\t\t\t\t} else if (isoperator(static_cast<char>(sc.ch))\n\t\t\t\t\t\t\t|| sc.ch == '\\\\') {\n\t\t\t\t\tsc.SetState(SCE_ERLANG_OPERATOR);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n\tsc.Complete();\n}\n\nstatic int ClassifyErlangFoldPoint(\n\tAccessor &styler,\n\tint styleNext,\n\tSci_Position keyword_start\n) {\n\tint lev = 0;\n\tif (styler.Match(keyword_start,\"case\")\n\t\t|| (\n\t\t\tstyler.Match(keyword_start,\"fun\")\n\t\t\t&& (SCE_ERLANG_FUNCTION_NAME != styleNext)\n\t\t\t)\n\t\t|| styler.Match(keyword_start,\"if\")\n\t\t|| styler.Match(keyword_start,\"query\")\n\t\t|| styler.Match(keyword_start,\"receive\")\n\t) {\n\t\t++lev;\n\t} else if (styler.Match(keyword_start,\"end\")) {\n\t\t--lev;\n\t}\n\n\treturn lev;\n}\n\nstatic void FoldErlangDoc(\n\tSci_PositionU startPos, Sci_Position length, int initStyle,\n\tWordList** /*keywordlists*/, Accessor &styler\n) {\n\tSci_PositionU endPos = startPos + length;\n\tSci_Position currentLine = styler.GetLine(startPos);\n\tint lev;\n\tint previousLevel = styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK;\n\tint currentLevel = previousLevel;\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tint stylePrev;\n\tSci_Position keyword_start = 0;\n\tchar ch;\n\tchar chNext = styler.SafeGetCharAt(startPos);\n\tbool atEOL;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\t// Get styles\n\t\tstylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tatEOL = ((ch == '\\r') && (chNext != '\\n')) || (ch == '\\n');\n\n\t\tif (stylePrev != SCE_ERLANG_KEYWORD\n\t\t\t&& style == SCE_ERLANG_KEYWORD) {\n\t\t\tkeyword_start = i;\n\t\t}\n\n\t\t// Fold on keywords\n\t\tif (stylePrev == SCE_ERLANG_KEYWORD\n\t\t\t&& style != SCE_ERLANG_KEYWORD\n\t\t\t&& style != SCE_ERLANG_ATOM\n\t\t) {\n\t\t\tcurrentLevel += ClassifyErlangFoldPoint(styler,\n\t\t\t\t\t\t\t\t\t\t\t\t\tstyleNext,\n\t\t\t\t\t\t\t\t\t\t\t\t\tkeyword_start);\n\t\t}\n\n\t\t// Fold on comments\n\t\tif (style == SCE_ERLANG_COMMENT\n\t\t\t|| style == SCE_ERLANG_COMMENT_MODULE\n\t\t\t|| style == SCE_ERLANG_COMMENT_FUNCTION) {\n\n\t\t\tif (ch == '%' && chNext == '{') {\n\t\t\t\tcurrentLevel++;\n\t\t\t} else if (ch == '%' && chNext == '}') {\n\t\t\t\tcurrentLevel--;\n\t\t\t}\n\t\t}\n\n\t\t// Fold on braces\n\t\tif (style == SCE_ERLANG_OPERATOR) {\n\t\t\tif (ch == '{' || ch == '(' || ch == '[') {\n\t\t\t\tcurrentLevel++;\n\t\t\t} else if (ch == '}' || ch == ')' || ch == ']') {\n\t\t\t\tcurrentLevel--;\n\t\t\t}\n\t\t}\n\n\n\t\tif (atEOL) {\n\t\t\tlev = previousLevel;\n\n\t\t\tif (currentLevel > previousLevel)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\n\t\t\tif (lev != styler.LevelAt(currentLine))\n\t\t\t\tstyler.SetLevel(currentLine, lev);\n\n\t\t\tcurrentLine++;\n\t\t\tpreviousLevel = currentLevel;\n\t\t}\n\n\t}\n\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tstyler.SetLevel(currentLine,\n\t\t\t\t\tpreviousLevel\n\t\t\t\t\t| (styler.LevelAt(currentLine) & ~SC_FOLDLEVELNUMBERMASK));\n}\n\nstatic const char * const erlangWordListDesc[] = {\n\t\"Erlang Reserved words\",\n\t\"Erlang BIFs\",\n\t\"Erlang Preprocessor\",\n\t\"Erlang Module Attributes\",\n\t\"Erlang Documentation\",\n\t\"Erlang Documentation Macro\",\n\t0\n};\n\nextern const LexerModule lmErlang(\n\tSCLEX_ERLANG,\n\tColouriseErlangDoc,\n\t\"erlang\",\n\tFoldErlangDoc,\n\terlangWordListDesc);\n"
  },
  {
    "path": "lexers/LexErrorList.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexErrorList.cxx\n ** Lexer for error lists. Used for the output pane in SciTE.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <initializer_list>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"InList.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\n// Options used for LexerErrorList\nstruct OptionsErrorList {\n\tbool valueSeparate = false;\n\tbool escapeSequences = false;\n};\n\nconst char *const emptyWordListDesc[] = {\n\tnullptr\n};\n\nstruct OptionSetErrorList : public OptionSet<OptionsErrorList> {\n\tOptionSetErrorList() {\n\t\tDefineProperty(\"lexer.errorlist.value.separate\", &OptionsErrorList::valueSeparate,\n\t\t\t\"For lines in the output pane that are matches from Find in Files or GCC-style\"\n\t\t\t\"diagnostics, style the path and line number separately from the rest of the\"\n\t\t\t\"line with style 21 used for the rest of the line.\"\n\t\t\t\"This allows matched text to be more easily distinguished from its location.\"\n\t\t);\n\n\t\tDefineProperty(\"lexer.errorlist.escape.sequences\", &OptionsErrorList::escapeSequences,\n\t\t\t\"Set to 1 to interpret escape sequences.\"\n\t\t);\n\t}\n};\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer errorlist SCLEX_ERRORLIST SCE_ERR_\n\t0, \"SCE_ERR_DEFAULT\", \"diagnostic\", \"Text\",\n\t1, \"SCE_ERR_PYTHON\", \"diagnostic\", \"Python Error\",\n\t2, \"SCE_ERR_GCC\", \"diagnostic\", \"GCC Error\",\n\t3, \"SCE_ERR_MS\", \"diagnostic\", \"Microsoft Error\",\n\t4, \"SCE_ERR_CMD\", \"default\", \"Command or return status\",\n\t5, \"SCE_ERR_BORLAND\", \"diagnostic\", \"Borland error and warning messages\",\n\t6, \"SCE_ERR_PERL\", \"diagnostic\", \"Perl error and warning messages\",\n\t7, \"SCE_ERR_NET\", \"diagnostic\", \".NET tracebacks\",\n\t8, \"SCE_ERR_LUA\", \"diagnostic\", \"Lua error and warning messages\",\n\t9, \"SCE_ERR_CTAG\", \"diagnostic\", \"ctags\",\n\t10, \"SCE_ERR_DIFF_CHANGED\", \"default\", \"Diff changed !\",\n\t11, \"SCE_ERR_DIFF_ADDITION\", \"default\", \"Diff addition +\",\n\t12, \"SCE_ERR_DIFF_DELETION\", \"default\", \"Diff deletion -\",\n\t13, \"SCE_ERR_DIFF_MESSAGE\", \"default\", \"Diff message ---\",\n\t14, \"SCE_ERR_PHP\", \"diagnostic\", \"PHP error\",\n\t15, \"SCE_ERR_ELF\", \"diagnostic\", \"Essential Lahey Fortran 90 error\",\n\t16, \"SCE_ERR_IFC\", \"diagnostic\", \"Intel Fortran Compiler error\",\n\t17, \"SCE_ERR_IFORT\", \"diagnostic\", \"Intel Fortran Compiler v8.0 error/warning\",\n\t18, \"SCE_ERR_ABSF\", \"diagnostic\", \"Absoft Pro Fortran 90/95 v8.2 error or warning\",\n\t19, \"SCE_ERR_TIDY\", \"diagnostic\", \"HTML Tidy\",\n\t20, \"SCE_ERR_JAVA_STACK\", \"diagnostic\", \"Java runtime stack trace\",\n\t21, \"SCE_ERR_VALUE\", \"default\", \"Text matched with find in files and message part of GCC errors\",\n\t22, \"SCE_ERR_GCC_INCLUDED_FROM\", \"diagnostic\", \"GCC showing include path to following error\",\n\t23, \"SCE_ERR_ESCSEQ\", \"escapesequence\", \"Escape sequence\",\n\t24, \"SCE_ERR_ESCSEQ_UNKNOWN\", \"escapesequence\", \"Escape sequence unknown\",\n\t25, \"SCE_ERR_GCC_EXCERPT\", \"diagnostic\", \"GCC showing excerpt of code with pointer\",\n\t26, \"SCE_ERR_BASH\", \"diagnostic\", \"Bash diagnostic\",\n\t27, \"\", \"unused\", \"\",\n\t28, \"\", \"unused\", \"\",\n\t29, \"\", \"unused\", \"\",\n\t30, \"\", \"unused\", \"\",\n\t31, \"\", \"unused\", \"\",\n\t32, \"\", \"predefined\", \"\",\n\t33, \"\", \"predefined\", \"\",\n\t34, \"\", \"predefined\", \"\",\n\t35, \"\", \"predefined\", \"\",\n\t36, \"\", \"predefined\", \"\",\n\t37, \"\", \"predefined\", \"\",\n\t38, \"\", \"predefined\", \"\",\n\t39, \"\", \"predefined\", \"\",\n\t40, \"SCE_ERR_ES_BLACK\", \"default\", \"Black\",\n\t41, \"SCE_ERR_ES_RED\", \"default\", \"Red\",\n\t42, \"SCE_ERR_ES_GREEN\", \"default\", \"Green\",\n\t43, \"SCE_ERR_ES_BROWN\", \"default\", \"Brown\",\n\t44, \"SCE_ERR_ES_BLUE\", \"default\", \"Blue\",\n\t45, \"SCE_ERR_ES_MAGENTA\", \"default\", \"Magenta\",\n\t46, \"SCE_ERR_ES_CYAN\", \"default\", \"Cyan\",\n\t47, \"SCE_ERR_ES_GRAY\", \"default\", \"Gray\",\n\t48, \"SCE_ERR_ES_DARK_GRAY\", \"default\", \"Dark Gray\",\n\t49, \"SCE_ERR_ES_BRIGHT_RED\", \"default\", \"Bright Red\",\n\t50, \"SCE_ERR_ES_BRIGHT_GREEN\", \"default\", \"Bright Green\",\n\t51, \"SCE_ERR_ES_YELLOW\", \"default\", \"Yellow\",\n\t52, \"SCE_ERR_ES_BRIGHT_BLUE\", \"default\", \"Bright Blue\",\n\t53, \"SCE_ERR_ES_BRIGHT_MAGENTA\", \"default\", \"Bright Magenta\",\n\t54, \"SCE_ERR_ES_BRIGHT_CYAN\", \"default\", \"Bright Cyan\",\n\t55, \"SCE_ERR_ES_WHITE\", \"default\", \"White\",\n};\n\nclass LexerErrorList : public DefaultLexer {\n\tOptionsErrorList options;\n\tOptionSetErrorList osErrorList;\npublic:\n\tLexerErrorList() :\n\t\tDefaultLexer(\"errorlist\", SCLEX_ERRORLIST, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osErrorList.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osErrorList.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osErrorList.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osErrorList.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osErrorList.DescribeWordListSets();\n\t}\n\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tstatic ILexer5 *LexerFactoryErrorList() {\n\t\treturn new LexerErrorList();\n\t}\n};\n\nSci_Position SCI_METHOD LexerErrorList::PropertySet(const char *key, const char *val) {\n\tif (osErrorList.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nconstexpr bool StartsWith(std::string_view haystack, std::string_view needle) noexcept {\n\treturn (needle.length() <= haystack.length()) &&\n\t\t(haystack.substr(0, needle.length()) == needle);\n}\n\nconstexpr bool Contains(std::string_view text, std::string_view a) noexcept {\n\tconst size_t pos = text.find(a);\n\treturn pos != std::string_view::npos;\n}\n\n// Does text contain both a and b with b after a\nconstexpr bool ContainsOrdered(std::string_view text, std::string_view a, std::string_view b) noexcept {\n\tconst size_t posA = text.find(a);\n\tif (posA == std::string_view::npos) {\n\t\treturn false;\n\t}\n\tconst size_t posB = text.find(b, posA + a.length());\n\treturn posB != std::string_view::npos;\n}\n\nconstexpr bool Is0To9(char ch) noexcept {\n\treturn (ch >= '0') && (ch <= '9');\n}\n\nconstexpr bool Is1To9(char ch) noexcept {\n\treturn (ch >= '1') && (ch <= '9');\n}\n\nbool AtEOL(Accessor &styler, Sci_Position i) {\n\treturn (styler[i] == '\\n') ||\n\t       ((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n'));\n}\n\nstd::string_view LetterPrefix(std::string_view sv) noexcept {\n\tSci_PositionU i = 0;\n\twhile (i < sv.length() && IsUpperOrLowerCase(sv[i]))\n\t\ti++;\n\treturn sv.substr(0, i);\n}\n\nbool IsGccExcerpt(std::string_view sv) noexcept {\n\twhile (!sv.empty()) {\n\t\tif ((sv.length() >= 3) && (sv[0] == ' ' && sv[1] == '|' && (sv[2] == ' ' || sv[2] == '+'))) {\n\t\t\treturn true;\n\t\t}\n\t\tif (!(sv[0] == ' ' || sv[0] == '+' || Is0To9(sv[0]))) {\n\t\t\treturn false;\n\t\t}\n\t\tsv.remove_prefix(1);\n\t}\n\treturn true;\n}\n\nconst std::string_view bashDiagnosticMark = \": line \";\nbool IsBashDiagnostic(std::string_view sv) {\n\tconst size_t mark = sv.find(bashDiagnosticMark);\n\tif (mark == std::string_view::npos) {\n\t\treturn false;\n\t}\n\tstd::string_view rest = sv.substr(mark + bashDiagnosticMark.length());\n\tif (rest.empty() || !Is0To9(rest.front())) {\n\t\treturn false;\n\t}\n\twhile (!rest.empty() && Is0To9(rest.front())) {\n\t\trest.remove_prefix(1);\n\t}\n\treturn !rest.empty() && (rest.front() == ':');\n}\n\n\nint RecogniseErrorListLine(std::string_view lineBuffer, Sci_Position &startValue) {\n\tif (lineBuffer.empty())\n\t\treturn SCE_ERR_DEFAULT;\n\n\tswitch (lineBuffer.front()) {\n\tcase '>':\n\t\t// Command or return status\n\t\treturn SCE_ERR_CMD;\n\tcase '<':\n\t\t// Diff removal.\n\t\treturn SCE_ERR_DIFF_DELETION;\n\tcase '!':\n\t\treturn SCE_ERR_DIFF_CHANGED;\n\tcase '+':\n\t\tif (StartsWith(lineBuffer, \"+++ \")) {\n\t\t\treturn SCE_ERR_DIFF_MESSAGE;\n\t\t} else {\n\t\t\treturn SCE_ERR_DIFF_ADDITION;\n\t\t}\n\tcase '-':\n\t\tif (StartsWith(lineBuffer, \"--- \")) {\n\t\t\treturn SCE_ERR_DIFF_MESSAGE;\n\t\t} else {\n\t\t\treturn SCE_ERR_DIFF_DELETION;\n\t\t}\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif (StartsWith(lineBuffer, \"cf90-\")) {\n\t\t// Absoft Pro Fortran 90/95 v8.2 error and/or warning message\n\t\treturn SCE_ERR_ABSF;\n\t} else if (StartsWith(lineBuffer, \"fortcom:\")) {\n\t\t// Intel Fortran Compiler v8.0 error/warning message\n\t\treturn SCE_ERR_IFORT;\n\t} else if (Contains(lineBuffer, \"File \\\"\") && Contains(lineBuffer, \", line \")) {\n\t\treturn SCE_ERR_PYTHON;\n\t} else if (Contains(lineBuffer, \" in \") && Contains(lineBuffer, \" on line \")) {\n\t\treturn SCE_ERR_PHP;\n\t} else if ((StartsWith(lineBuffer, \"Error \") ||\n\t            StartsWith(lineBuffer, \"Warning \")) &&\n\t           ContainsOrdered(lineBuffer, \" at (\", \") : \")) {\n\t\t// Intel Fortran Compiler error/warning message\n\t\treturn SCE_ERR_IFC;\n\t} else if (StartsWith(lineBuffer, \"Error \")) {\n\t\t// Borland error message\n\t\treturn SCE_ERR_BORLAND;\n\t} else if (StartsWith(lineBuffer, \"Warning \")) {\n\t\t// Borland warning message\n\t\treturn SCE_ERR_BORLAND;\n\t} else if (Contains(lineBuffer, \"at line \") &&\n\t           Contains(lineBuffer, \"file \")) {\n\t\t// Lua 4 error message\n\t\treturn SCE_ERR_LUA;\n\t} else if (ContainsOrdered(lineBuffer, \" at \", \" line \")) {\n\t\t// perl error message:\n\t\t// <message> at <file> line <line>\n\t\treturn SCE_ERR_PERL;\n\t} else if (StartsWith(lineBuffer, \"   at \") &&\n\t           Contains(lineBuffer, \":line \")) {\n\t\t// A .NET traceback\n\t\treturn SCE_ERR_NET;\n\t} else if (StartsWith(lineBuffer, \"Line \") &&\n\t           Contains(lineBuffer, \", file \")) {\n\t\t// Essential Lahey Fortran error message\n\t\treturn SCE_ERR_ELF;\n\t} else if (StartsWith(lineBuffer, \"line \") &&\n\t           Contains(lineBuffer, \" column \")) {\n\t\t// HTML tidy style: line 42 column 1\n\t\treturn SCE_ERR_TIDY;\n\t} else if (StartsWith(lineBuffer, \"\\tat \") &&\n\t           Contains(lineBuffer, \"(\") &&\n\t           Contains(lineBuffer, \".java:\")) {\n\t\t// Java stack back trace\n\t\treturn SCE_ERR_JAVA_STACK;\n\t} else if (StartsWith(lineBuffer, \"In file included from \") ||\n\t           StartsWith(lineBuffer, \"                 from \")) {\n\t\t// GCC showing include path to following error\n\t\treturn SCE_ERR_GCC_INCLUDED_FROM;\n\t} else if (StartsWith(lineBuffer, \"NMAKE : fatal error\")) {\n\t\t// Microsoft nmake fatal error:\n\t\t// NMAKE : fatal error <code>: <program> : return code <return>\n\t\treturn SCE_ERR_MS;\n\t} else if (Contains(lineBuffer, \"warning LNK\") ||\n\t\tContains(lineBuffer, \"error LNK\")) {\n\t\t// Microsoft linker warning:\n\t\t// {<object> : } (warning|error) LNK9999\n\t\treturn SCE_ERR_MS;\n\t} else if (IsBashDiagnostic(lineBuffer)) {\n\t\t// Bash diagnostic\n\t\t// <filename>: line <line>:<message>\n\t\treturn SCE_ERR_BASH;\n\t} else if (IsGccExcerpt(lineBuffer)) {\n\t\t// GCC code excerpt and pointer to issue\n\t\t//    73 |   GTimeVal last_popdown;\n\t\t//       |            ^~~~~~~~~~~~\n\t\treturn SCE_ERR_GCC_EXCERPT;\n\t} else {\n\t\t// Look for one of the following formats:\n\t\t// GCC: <filename>:<line>:<message>\n\t\t// Microsoft: <filename>(<line>) :<message>\n\t\t// Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal\n\t\t// Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal\n\t\t// Microsoft: <filename>(<line>,<column>)<message>\n\t\t// CTags: <identifier>\\t<filename>\\t<message>\n\t\t// Lua 5 traceback: \\t<filename>:<line>:<message>\n\t\t// Lua 5.1: <exe>: <filename>:<line>:<message>\n\t\tconst bool initialTab = (lineBuffer[0] == '\\t');\n\t\tbool initialColonPart = false;\n\t\tbool canBeCtags = !initialTab;\t// For ctags must have an identifier with no spaces then a tab\n\t\tenum { stInitial,\n\t\t\tstGccStart, stGccDigit, stGccColumn, stGcc,\n\t\t\tstMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet,\n\t\t\tstCtagsStart, stCtagsFile, stCtagsStartString, stCtagsStringDollar, stCtags,\n\t\t\tstUnrecognized\n\t\t} state = stInitial;\n\t\tfor (Sci_PositionU i = 0; i < lineBuffer.length(); i++) {\n\t\t\tconst char ch = lineBuffer[i];\n\t\t\tconst char chNext = ((i + 1) < lineBuffer.length()) ? lineBuffer[i + 1] : ' ';\n\t\t\tif (state == stInitial) {\n\t\t\t\tif (ch == ':') {\n\t\t\t\t\t// May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix)\n\t\t\t\t\tif ((chNext != '\\\\') && (chNext != '/') && (chNext != ' ')) {\n\t\t\t\t\t\t// This check is not completely accurate as may be on\n\t\t\t\t\t\t// GTK+ with a file name that includes ':'.\n\t\t\t\t\t\tstate = stGccStart;\n\t\t\t\t\t} else if (chNext == ' ') { // indicates a Lua 5.1 error message\n\t\t\t\t\t\tinitialColonPart = true;\n\t\t\t\t\t}\n\t\t\t\t} else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) {\n\t\t\t\t\t// May be Microsoft\n\t\t\t\t\t// Check against '0' often removes phone numbers\n\t\t\t\t\tstate = stMsStart;\n\t\t\t\t} else if ((ch == '\\t') && canBeCtags) {\n\t\t\t\t\t// May be CTags\n\t\t\t\t\tstate = stCtagsStart;\n\t\t\t\t} else if (ch == ' ') {\n\t\t\t\t\tcanBeCtags = false;\n\t\t\t\t}\n\t\t\t} else if (state == stGccStart) {\t// <filename>:\n\t\t\t\tstate = ((ch == '-') || Is0To9(ch)) ? stGccDigit : stUnrecognized;\n\t\t\t} else if (state == stGccDigit) {\t// <filename>:<line>\n\t\t\t\tif (ch == ':') {\n\t\t\t\t\tstate = stGccColumn;\t// :9.*: is GCC\n\t\t\t\t\tstartValue = i + 1;\n\t\t\t\t} else if (!Is0To9(ch)) {\n\t\t\t\t\tstate = stUnrecognized;\n\t\t\t\t}\n\t\t\t} else if (state == stGccColumn) {\t// <filename>:<line>:<column>\n\t\t\t\tif (!Is0To9(ch)) {\n\t\t\t\t\tstate = stGcc;\n\t\t\t\t\tif (ch == ':')\n\t\t\t\t\t\tstartValue = i + 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else if (state == stMsStart) {\t// <filename>(\n\t\t\t\tstate = Is0To9(ch) ? stMsDigit : stUnrecognized;\n\t\t\t} else if (state == stMsDigit) {\t// <filename>(<line>\n\t\t\t\tif (ch == ',') {\n\t\t\t\t\tstate = stMsDigitComma;\n\t\t\t\t} else if (ch == ')') {\n\t\t\t\t\tstate = stMsBracket;\n\t\t\t\t} else if ((ch != ' ') && !Is0To9(ch)) {\n\t\t\t\t\tstate = stUnrecognized;\n\t\t\t\t}\n\t\t\t} else if (state == stMsBracket) {\t// <filename>(<line>)\n\t\t\t\tif ((ch == ' ') && (chNext == ':')) {\n\t\t\t\t\tstate = stMsVc;\n\t\t\t\t} else if ((ch == ':' && chNext == ' ') || (ch == ' ')) {\n\t\t\t\t\t// Possibly Microsoft or Delphi.\n\t\t\t\t\t// Move past above prefix: \" \" -> 1, \": \" -> 2\n\t\t\t\t\t// \" \" is likely a Delphi diagnostic, \": \" a Microsoft diagnostic\n\t\t\t\t\tconst Sci_PositionU numstep = (ch == ' ') ? 1 : 2;\n\t\t\t\t\tconst std::string_view word = LetterPrefix(lineBuffer.substr(i + numstep));\n\t\t\t\t\tif (InListCaseInsensitive(word, {\"error\", \"warning\", \"fatal\", \"catastrophic\", \"note\", \"remark\"})) {\n\t\t\t\t\t\tstate = stMsVc;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate = stUnrecognized;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstate = stUnrecognized;\n\t\t\t\t}\n\t\t\t} else if (state == stMsDigitComma) {\t// <filename>(<line>,\n\t\t\t\tif (ch == ')') {\n\t\t\t\t\tstate = stMsDotNet;\n\t\t\t\t\tbreak;\n\t\t\t\t} else if ((ch != ' ') && !Is0To9(ch)) {\n\t\t\t\t\tstate = stUnrecognized;\n\t\t\t\t}\n\t\t\t} else if (state == stCtagsStart) {\n\t\t\t\tif (ch == '\\t') {\n\t\t\t\t\tstate = stCtagsFile;\n\t\t\t\t}\n\t\t\t} else if (state == stCtagsFile) {\n\t\t\t\tif ((lineBuffer[i - 1] == '\\t') &&\n\t\t\t\t        ((ch == '/' && chNext == '^') || Is0To9(ch))) {\n\t\t\t\t\tstate = stCtags;\n\t\t\t\t\tbreak;\n\t\t\t\t} else if ((ch == '/') && (chNext == '^')) {\n\t\t\t\t\tstate = stCtagsStartString;\n\t\t\t\t}\n\t\t\t} else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) {\n\t\t\t\tstate = stCtagsStringDollar;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (state == stGcc) {\n\t\t\treturn initialColonPart ? SCE_ERR_LUA : SCE_ERR_GCC;\n\t\t} else if ((state == stMsVc) || (state == stMsDotNet)) {\n\t\t\treturn SCE_ERR_MS;\n\t\t} else if ((state == stCtagsStringDollar) || (state == stCtags)) {\n\t\t\treturn SCE_ERR_CTAG;\n\t\t} else if (initialColonPart && Contains(lineBuffer, \": warning C\")) {\n\t\t\t// Microsoft warning without line number\n\t\t\t// <filename>: warning C9999\n\t\t\treturn SCE_ERR_MS;\n\t\t} else {\n\t\t\treturn SCE_ERR_DEFAULT;\n\t\t}\n\t}\n}\n\n#define CSI \"\\033[\"\n\nconstexpr bool SequenceEnd(int ch) noexcept {\n\treturn (ch == 0) || ((ch >= '@') && (ch <= '~'));\n}\n\nint StyleFromSequence(const char *seq) noexcept {\n\tint bold = 0;\n\tint style = 0;\n\twhile (!SequenceEnd(*seq)) {\n\t\tif (Is0To9(*seq)) {\n\t\t\tint base = *seq - '0';\n\t\t\tif (Is0To9(seq[1])) {\n\t\t\t\tbase = base * 10;\n\t\t\t\tbase += seq[1] - '0';\n\t\t\t\tseq++;\n\t\t\t}\n\t\t\tif (base == 0) {\n\t\t\t\t// Reset to default.\n\t\t\t\tstyle = 0;\n\t\t\t\tbold = 0;\n\t\t\t} else if (base == 1) {\n\t\t\t\t// Set style as bright.\n\t\t\t\tbold = 1;\n\t\t\t\tif (style == 0) {\n\t\t\t\t\tstyle = 40;\n\t\t\t\t}\n\t\t\t} else if (base >= 30 && base <= 37) {\n\t\t\t\t// Set dim style which starts at 40.\n\t\t\t\tstyle = base + 10;\n\t\t\t} else if (base >= 90 && base <= 97) {\n\t\t\t\t// Set bright style which starts at 48.\n\t\t\t\tstyle = base - 42;\n\t\t\t}\n\t\t}\n\t\tseq++;\n\t}\n\t// Set dim style as bright style if bold is set.\n\tif (bold && (style >= 40 && style <= 47)) {\n\t\tstyle += 8;\n\t}\n\t// Return the style which if 0 will be SCE_ERR_DEFAULT style.\n\treturn style;\n}\n\nvoid ColouriseErrorListLine(\n    const std::string &lineBuffer,\n    Sci_PositionU endPos,\n    Accessor &styler,\n\tbool valueSeparate,\n\tbool escapeSequences) {\n\tSci_Position startValue = -1;\n\tconst int style = RecogniseErrorListLine(lineBuffer, startValue);\n\tif (escapeSequences && Contains(lineBuffer, CSI)) {\n\t\tconst Sci_Position startPos = endPos - lineBuffer.length();\n\t\tconst char *linePortion = lineBuffer.c_str();\n\t\tSci_Position startPortion = startPos;\n\t\tint portionStyle = style;\n\t\twhile (const char *startSeq = strstr(linePortion, CSI)) {\n\t\t\tif (startSeq > linePortion) {\n\t\t\t\tstyler.ColourTo(startPortion + (startSeq - linePortion), portionStyle);\n\t\t\t}\n\t\t\tconst char *endSeq = startSeq + 2;\n\t\t\twhile (!SequenceEnd(*endSeq))\n\t\t\t\tendSeq++;\n\t\t\tconst Sci_Position endSeqPosition = startPortion + (endSeq - linePortion) + 1;\n\t\t\tswitch (*endSeq) {\n\t\t\tcase 0:\n\t\t\t\tstyler.ColourTo(endPos, SCE_ERR_ESCSEQ_UNKNOWN);\n\t\t\t\treturn;\n\t\t\tcase 'm':\t// Colour command\n\t\t\t\tstyler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ);\n\t\t\t\tportionStyle = StyleFromSequence(startSeq+2);\n\t\t\t\tbreak;\n\t\t\tcase 'K':\t// Erase to end of line -> ignore\n\t\t\t\tstyler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tstyler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ_UNKNOWN);\n\t\t\t\tportionStyle = style;\n\t\t\t}\n\t\t\tstartPortion = endSeqPosition;\n\t\t\tlinePortion = endSeq + 1;\n\t\t}\n\t\tstyler.ColourTo(endPos, portionStyle);\n\t} else {\n\t\tif (valueSeparate && (startValue >= 0)) {\n\t\t\tstyler.ColourTo(endPos - (lineBuffer.length() - startValue), style);\n\t\t\tstyler.ColourTo(endPos, SCE_ERR_VALUE);\n\t\t} else {\n\t\t\tstyler.ColourTo(endPos, style);\n\t\t}\n\t}\n}\n\nvoid LexerErrorList::Lex(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\tstd::string lineBuffer;\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\n\tfor (Sci_PositionU i = startPos; i < startPos + length; i++) {\n\t\tlineBuffer.push_back(styler[i]);\n\t\tif (AtEOL(styler, i)) {\n\t\t\t// End of line met, colourise it\n\t\t\tColouriseErrorListLine(lineBuffer, i, styler, options.valueSeparate, options.escapeSequences);\n\t\t\tlineBuffer.clear();\n\t\t}\n\t}\n\tif (!lineBuffer.empty()) {\t// Last line does not have ending characters\n\t\tColouriseErrorListLine(lineBuffer, startPos + length - 1, styler, options.valueSeparate, options.escapeSequences);\n\t}\n\n\tstyler.Flush();\n}\n\n}\n\nextern const LexerModule lmErrorList(SCLEX_ERRORLIST, LexerErrorList::LexerFactoryErrorList, \"errorlist\", emptyWordListDesc);\n"
  },
  {
    "path": "lexers/LexEscSeq.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexEscSeq.cxx\n ** Lexer for terminal escape sequences.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <initializer_list>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"InList.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\n#define CSI \"\\033[\"\n\n// Options used for LexerEscSeq\nstruct OptionsEscSeq {\n\tbool colourText = false;\n};\n\n\nconst char *const emptyWordListDesc[] = {\n\tnullptr\n};\n\n\nstruct OptionSetEscSeq : public OptionSet<OptionsEscSeq> {\n\tOptionSetEscSeq() {\n\t\tDefineProperty(\"lexer.escseq.colour.text\", &OptionsEscSeq::colourText,\n\t\t\t\"Set to 1 to colour text following the escape sequences.\"\n\t\t);\n\n\t\tDefineWordListSets(emptyWordListDesc);\n\t}\n};\n\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer escseq SCLEX_ESCSEQ SCE_ESCSEQ_\n\t0, \"SCE_ESCSEQ_DEFAULT\", \"default\", \"Default\",\n\t1, \"SCE_ESCSEQ_BLACK_DEFAULT\", \"default\", \"Black Default\",\n\t2, \"SCE_ESCSEQ_RED_DEFAULT\", \"default\", \"Red Default\",\n\t3, \"SCE_ESCSEQ_GREEN_DEFAULT\", \"default\", \"Green Default\",\n\t4, \"SCE_ESCSEQ_YELLOW_DEFAULT\", \"default\", \"Yellow Default\",\n\t5, \"SCE_ESCSEQ_BLUE_DEFAULT\", \"default\", \"Blue Default\",\n\t6, \"SCE_ESCSEQ_MAGENTA_DEFAULT\", \"default\", \"Magenta Default\",\n\t7, \"SCE_ESCSEQ_CYAN_DEFAULT\", \"default\", \"Cyan Default\",\n\t8, \"SCE_ESCSEQ_WHITE_DEFAULT\", \"default\", \"White Default\",\n\t9, \"SCE_ESCSEQ_DEFAULT_BLACK\", \"default\", \"Default Black\",\n\t10, \"SCE_ESCSEQ_BLACK_BLACK\", \"default\", \"Black Black\",\n\t11, \"SCE_ESCSEQ_RED_BLACK\", \"default\", \"Red Black\",\n\t12, \"SCE_ESCSEQ_GREEN_BLACK\", \"default\", \"Green Black\",\n\t13, \"SCE_ESCSEQ_YELLOW_BLACK\", \"default\", \"Yellow Black\",\n\t14, \"SCE_ESCSEQ_BLUE_BLACK\", \"default\", \"Blue Black\",\n\t15, \"SCE_ESCSEQ_MAGENTA_BLACK\", \"default\", \"Magenta Black\",\n\t16, \"SCE_ESCSEQ_CYAN_BLACK\", \"default\", \"Cyan Black\",\n\t17, \"SCE_ESCSEQ_WHITE_BLACK\", \"default\", \"White Black\",\n\t18, \"SCE_ESCSEQ_DEFAULT_RED\", \"default\", \"Default Red\",\n\t19, \"SCE_ESCSEQ_BLACK_RED\", \"default\", \"Black Red\",\n\t20, \"SCE_ESCSEQ_RED_RED\", \"default\", \"Red Red\",\n\t21, \"SCE_ESCSEQ_GREEN_RED\", \"default\", \"Green Red\",\n\t22, \"SCE_ESCSEQ_YELLOW_RED\", \"default\", \"Yellow Red\",\n\t23, \"SCE_ESCSEQ_BLUE_RED\", \"default\", \"Blue Red\",\n\t24, \"SCE_ESCSEQ_MAGENTA_RED\", \"default\", \"Magenta Red\",\n\t25, \"SCE_ESCSEQ_CYAN_RED\", \"default\", \"Cyan Red\",\n\t26, \"SCE_ESCSEQ_WHITE_RED\", \"default\", \"White Red\",\n\t27, \"SCE_ESCSEQ_DEFAULT_GREEN\", \"default\", \"Default Green\",\n\t28, \"SCE_ESCSEQ_BLACK_GREEN\", \"default\", \"Black Green\",\n\t29, \"SCE_ESCSEQ_RED_GREEN\", \"default\", \"Red Green\",\n\t30, \"SCE_ESCSEQ_GREEN_GREEN\", \"default\", \"Green Green\",\n\t31, \"\", \"unused\", \"\",\n\t32, \"\", \"predefined\", \"\",\n\t33, \"\", \"predefined\", \"\",\n\t34, \"\", \"predefined\", \"\",\n\t35, \"\", \"predefined\", \"\",\n\t36, \"\", \"predefined\", \"\",\n\t37, \"\", \"predefined\", \"\",\n\t38, \"\", \"predefined\", \"\",\n\t39, \"\", \"predefined\", \"\",\n\t40, \"SCE_ESCSEQ_YELLOW_GREEN\", \"default\", \"Yellow Green\",\n\t41, \"SCE_ESCSEQ_BLUE_GREEN\", \"default\", \"Blue Green\",\n\t42, \"SCE_ESCSEQ_MAGENTA_GREEN\", \"default\", \"Magenta Green\",\n\t43, \"SCE_ESCSEQ_CYAN_GREEN\", \"default\", \"Cyan Green\",\n\t44, \"SCE_ESCSEQ_WHITE_GREEN\", \"default\", \"White Green\",\n\t45, \"SCE_ESCSEQ_DEFAULT_YELLOW\", \"default\", \"Default Yellow\",\n\t46, \"SCE_ESCSEQ_BLACK_YELLOW\", \"default\", \"Black Yellow\",\n\t47, \"SCE_ESCSEQ_RED_YELLOW\", \"default\", \"Red Yellow\",\n\t48, \"SCE_ESCSEQ_GREEN_YELLOW\", \"default\", \"Green Yellow\",\n\t49, \"SCE_ESCSEQ_YELLOW_YELLOW\", \"default\", \"Yellow Yellow\",\n\t50, \"SCE_ESCSEQ_BLUE_YELLOW\", \"default\", \"Blue Yellow\",\n\t51, \"SCE_ESCSEQ_MAGENTA_YELLOW\", \"default\", \"Magenta Yellow\",\n\t52, \"SCE_ESCSEQ_CYAN_YELLOW\", \"default\", \"Cyan Yellow\",\n\t53, \"SCE_ESCSEQ_WHITE_YELLOW\", \"default\", \"White Yellow\",\n\t54, \"SCE_ESCSEQ_DEFAULT_BLUE\", \"default\", \"Default Blue\",\n\t55, \"SCE_ESCSEQ_BLACK_BLUE\", \"default\", \"Black Blue\",\n\t56, \"SCE_ESCSEQ_RED_BLUE\", \"default\", \"Red Blue\",\n\t57, \"SCE_ESCSEQ_GREEN_BLUE\", \"default\", \"Green Blue\",\n\t58, \"SCE_ESCSEQ_YELLOW_BLUE\", \"default\", \"Yellow Blue\",\n\t59, \"SCE_ESCSEQ_BLUE_BLUE\", \"default\", \"Blue Blue\",\n\t60, \"SCE_ESCSEQ_MAGENTA_BLUE\", \"default\", \"Magenta Blue\",\n\t61, \"SCE_ESCSEQ_CYAN_BLUE\", \"default\", \"Cyan Blue\",\n\t62, \"SCE_ESCSEQ_WHITE_BLUE\", \"default\", \"White Blue\",\n\t63, \"SCE_ESCSEQ_DEFAULT_MAGENTA\", \"default\", \"Default Magenta\",\n\t64, \"SCE_ESCSEQ_BLACK_MAGENTA\", \"default\", \"Black Magenta\",\n\t65, \"SCE_ESCSEQ_RED_MAGENTA\", \"default\", \"Red Magenta\",\n\t66, \"SCE_ESCSEQ_GREEN_MAGENTA\", \"default\", \"Green Magenta\",\n\t67, \"SCE_ESCSEQ_YELLOW_MAGENTA\", \"default\", \"Yellow Magenta\",\n\t68, \"SCE_ESCSEQ_BLUE_MAGENTA\", \"default\", \"Blue Magenta\",\n\t69, \"SCE_ESCSEQ_MAGENTA_MAGENTA\", \"default\", \"Magenta Magenta\",\n\t70, \"SCE_ESCSEQ_CYAN_MAGENTA\", \"default\", \"Cyan Magenta\",\n\t71, \"SCE_ESCSEQ_WHITE_MAGENTA\", \"default\", \"White Magenta\",\n\t72, \"SCE_ESCSEQ_DEFAULT_CYAN\", \"default\", \"Default Cyan\",\n\t73, \"SCE_ESCSEQ_BLACK_CYAN\", \"default\", \"Black Cyan\",\n\t74, \"SCE_ESCSEQ_RED_CYAN\", \"default\", \"Red Cyan\",\n\t75, \"SCE_ESCSEQ_GREEN_CYAN\", \"default\", \"Green Cyan\",\n\t76, \"SCE_ESCSEQ_YELLOW_CYAN\", \"default\", \"Yellow Cyan\",\n\t77, \"SCE_ESCSEQ_BLUE_CYAN\", \"default\", \"Blue Cyan\",\n\t78, \"SCE_ESCSEQ_MAGENTA_CYAN\", \"default\", \"Magenta Cyan\",\n\t79, \"SCE_ESCSEQ_CYAN_CYAN\", \"default\", \"Cyan Cyan\",\n\t80, \"SCE_ESCSEQ_WHITE_CYAN\", \"default\", \"White Cyan\",\n\t81, \"SCE_ESCSEQ_DEFAULT_WHITE\", \"default\", \"Default White\",\n\t82, \"SCE_ESCSEQ_BLACK_WHITE\", \"default\", \"Black White\",\n\t83, \"SCE_ESCSEQ_RED_WHITE\", \"default\", \"Red White\",\n\t84, \"SCE_ESCSEQ_GREEN_WHITE\", \"default\", \"Green White\",\n\t85, \"SCE_ESCSEQ_YELLOW_WHITE\", \"default\", \"Yellow White\",\n\t86, \"SCE_ESCSEQ_BLUE_WHITE\", \"default\", \"Blue White\",\n\t87, \"SCE_ESCSEQ_MAGENTA_WHITE\", \"default\", \"Magenta White\",\n\t88, \"SCE_ESCSEQ_CYAN_WHITE\", \"default\", \"Cyan White\",\n\t89, \"SCE_ESCSEQ_WHITE_WHITE\", \"default\", \"White White\",\n\t90, \"SCE_ESCSEQ_BOLD_DEFAULT\", \"default\", \"Bold Default\",\n\t91, \"SCE_ESCSEQ_BOLD_BLACK_DEFAULT\", \"default\", \"Bold Black Default\",\n\t92, \"SCE_ESCSEQ_BOLD_RED_DEFAULT\", \"default\", \"Bold Red Default\",\n\t93, \"SCE_ESCSEQ_BOLD_GREEN_DEFAULT\", \"default\", \"Bold Green Default\",\n\t94, \"SCE_ESCSEQ_BOLD_YELLOW_DEFAULT\", \"default\", \"Bold Yellow Default\",\n\t95, \"SCE_ESCSEQ_BOLD_BLUE_DEFAULT\", \"default\", \"Bold Blue Default\",\n\t96, \"SCE_ESCSEQ_BOLD_MAGENTA_DEFAULT\", \"default\", \"Bold Magenta Default\",\n\t97, \"SCE_ESCSEQ_BOLD_CYAN_DEFAULT\", \"default\", \"Bold Cyan Default\",\n\t98, \"SCE_ESCSEQ_BOLD_WHITE_DEFAULT\", \"default\", \"Bold White Default\",\n\t99, \"SCE_ESCSEQ_BOLD_DEFAULT_BLACK\", \"default\", \"Bold Default Black\",\n\t100, \"SCE_ESCSEQ_BOLD_BLACK_BLACK\", \"default\", \"Bold Black Black\",\n\t101, \"SCE_ESCSEQ_BOLD_RED_BLACK\", \"default\", \"Bold Red Black\",\n\t102, \"SCE_ESCSEQ_BOLD_GREEN_BLACK\", \"default\", \"Bold Green Black\",\n\t103, \"SCE_ESCSEQ_BOLD_YELLOW_BLACK\", \"default\", \"Bold Yellow Black\",\n\t104, \"SCE_ESCSEQ_BOLD_BLUE_BLACK\", \"default\", \"Bold Blue Black\",\n\t105, \"SCE_ESCSEQ_BOLD_MAGENTA_BLACK\", \"default\", \"Bold Magenta Black\",\n\t106, \"SCE_ESCSEQ_BOLD_CYAN_BLACK\", \"default\", \"Bold Cyan Black\",\n\t107, \"SCE_ESCSEQ_BOLD_WHITE_BLACK\", \"default\", \"Bold White Black\",\n\t108, \"SCE_ESCSEQ_BOLD_DEFAULT_RED\", \"default\", \"Bold Default Red\",\n\t109, \"SCE_ESCSEQ_BOLD_BLACK_RED\", \"default\", \"Bold Black Red\",\n\t110, \"SCE_ESCSEQ_BOLD_RED_RED\", \"default\", \"Bold Red Red\",\n\t111, \"SCE_ESCSEQ_BOLD_GREEN_RED\", \"default\", \"Bold Green Red\",\n\t112, \"SCE_ESCSEQ_BOLD_YELLOW_RED\", \"default\", \"Bold Yellow Red\",\n\t113, \"SCE_ESCSEQ_BOLD_BLUE_RED\", \"default\", \"Bold Blue Red\",\n\t114, \"SCE_ESCSEQ_BOLD_MAGENTA_RED\", \"default\", \"Bold Magenta Red\",\n\t115, \"SCE_ESCSEQ_BOLD_CYAN_RED\", \"default\", \"Bold Cyan Red\",\n\t116, \"SCE_ESCSEQ_BOLD_WHITE_RED\", \"default\", \"Bold White Red\",\n\t117, \"SCE_ESCSEQ_BOLD_DEFAULT_GREEN\", \"default\", \"Bold Default Green\",\n\t118, \"SCE_ESCSEQ_BOLD_BLACK_GREEN\", \"default\", \"Bold Black Green\",\n\t119, \"SCE_ESCSEQ_BOLD_RED_GREEN\", \"default\", \"Bold Red Green\",\n\t120, \"SCE_ESCSEQ_BOLD_GREEN_GREEN\", \"default\", \"Bold Green Green\",\n\t121, \"SCE_ESCSEQ_BOLD_YELLOW_GREEN\", \"default\", \"Bold Yellow Green\",\n\t122, \"SCE_ESCSEQ_BOLD_BLUE_GREEN\", \"default\", \"Bold Blue Green\",\n\t123, \"SCE_ESCSEQ_BOLD_MAGENTA_GREEN\", \"default\", \"Bold Magenta Green\",\n\t124, \"SCE_ESCSEQ_BOLD_CYAN_GREEN\", \"default\", \"Bold Cyan Green\",\n\t125, \"SCE_ESCSEQ_BOLD_WHITE_GREEN\", \"default\", \"Bold White Green\",\n\t126, \"SCE_ESCSEQ_BOLD_DEFAULT_YELLOW\", \"default\", \"Bold Default Yellow\",\n\t127, \"SCE_ESCSEQ_BOLD_BLACK_YELLOW\", \"default\", \"Bold Black Yellow\",\n\t128, \"SCE_ESCSEQ_BOLD_RED_YELLOW\", \"default\", \"Bold Red Yellow\",\n\t129, \"SCE_ESCSEQ_BOLD_GREEN_YELLOW\", \"default\", \"Bold Green Yellow\",\n\t130, \"SCE_ESCSEQ_BOLD_YELLOW_YELLOW\", \"default\", \"Bold Yellow Yellow\",\n\t131, \"SCE_ESCSEQ_BOLD_BLUE_YELLOW\", \"default\", \"Bold Blue Yellow\",\n\t132, \"SCE_ESCSEQ_BOLD_MAGENTA_YELLOW\", \"default\", \"Bold Magenta Yellow\",\n\t133, \"SCE_ESCSEQ_BOLD_CYAN_YELLOW\", \"default\", \"Bold Cyan Yellow\",\n\t134, \"SCE_ESCSEQ_BOLD_WHITE_YELLOW\", \"default\", \"Bold White Yellow\",\n\t135, \"SCE_ESCSEQ_BOLD_DEFAULT_BLUE\", \"default\", \"Bold Default Blue\",\n\t136, \"SCE_ESCSEQ_BOLD_BLACK_BLUE\", \"default\", \"Bold Black Blue\",\n\t137, \"SCE_ESCSEQ_BOLD_RED_BLUE\", \"default\", \"Bold Red Blue\",\n\t138, \"SCE_ESCSEQ_BOLD_GREEN_BLUE\", \"default\", \"Bold Green Blue\",\n\t139, \"SCE_ESCSEQ_BOLD_YELLOW_BLUE\", \"default\", \"Bold Yellow Blue\",\n\t140, \"SCE_ESCSEQ_BOLD_BLUE_BLUE\", \"default\", \"Bold Blue Blue\",\n\t141, \"SCE_ESCSEQ_BOLD_MAGENTA_BLUE\", \"default\", \"Bold Magenta Blue\",\n\t142, \"SCE_ESCSEQ_BOLD_CYAN_BLUE\", \"default\", \"Bold Cyan Blue\",\n\t143, \"SCE_ESCSEQ_BOLD_WHITE_BLUE\", \"default\", \"Bold White Blue\",\n\t144, \"SCE_ESCSEQ_BOLD_DEFAULT_MAGENTA\", \"default\", \"Bold Default Magenta\",\n\t145, \"SCE_ESCSEQ_BOLD_BLACK_MAGENTA\", \"default\", \"Bold Black Magenta\",\n\t146, \"SCE_ESCSEQ_BOLD_RED_MAGENTA\", \"default\", \"Bold Red Magenta\",\n\t147, \"SCE_ESCSEQ_BOLD_GREEN_MAGENTA\", \"default\", \"Bold Green Magenta\",\n\t148, \"SCE_ESCSEQ_BOLD_YELLOW_MAGENTA\", \"default\", \"Bold Yellow Magenta\",\n\t149, \"SCE_ESCSEQ_BOLD_BLUE_MAGENTA\", \"default\", \"Bold Blue Magenta\",\n\t150, \"SCE_ESCSEQ_BOLD_MAGENTA_MAGENTA\", \"default\", \"Bold Magenta Magenta\",\n\t151, \"SCE_ESCSEQ_BOLD_CYAN_MAGENTA\", \"default\", \"Bold Cyan Magenta\",\n\t152, \"SCE_ESCSEQ_BOLD_WHITE_MAGENTA\", \"default\", \"Bold White Magenta\",\n\t153, \"SCE_ESCSEQ_BOLD_DEFAULT_CYAN\", \"default\", \"Bold Default Cyan\",\n\t154, \"SCE_ESCSEQ_BOLD_BLACK_CYAN\", \"default\", \"Bold Black Cyan\",\n\t155, \"SCE_ESCSEQ_BOLD_RED_CYAN\", \"default\", \"Bold Red Cyan\",\n\t156, \"SCE_ESCSEQ_BOLD_GREEN_CYAN\", \"default\", \"Bold Green Cyan\",\n\t157, \"SCE_ESCSEQ_BOLD_YELLOW_CYAN\", \"default\", \"Bold Yellow Cyan\",\n\t158, \"SCE_ESCSEQ_BOLD_BLUE_CYAN\", \"default\", \"Bold Blue Cyan\",\n\t159, \"SCE_ESCSEQ_BOLD_MAGENTA_CYAN\", \"default\", \"Bold Magenta Cyan\",\n\t160, \"SCE_ESCSEQ_BOLD_CYAN_CYAN\", \"default\", \"Bold Cyan Cyan\",\n\t161, \"SCE_ESCSEQ_BOLD_WHITE_CYAN\", \"default\", \"Bold White Cyan\",\n\t162, \"SCE_ESCSEQ_BOLD_DEFAULT_WHITE\", \"default\", \"Bold Default White\",\n\t163, \"SCE_ESCSEQ_BOLD_BLACK_WHITE\", \"default\", \"Bold Black White\",\n\t164, \"SCE_ESCSEQ_BOLD_RED_WHITE\", \"default\", \"Bold Red White\",\n\t165, \"SCE_ESCSEQ_BOLD_GREEN_WHITE\", \"default\", \"Bold Green White\",\n\t166, \"SCE_ESCSEQ_BOLD_YELLOW_WHITE\", \"default\", \"Bold Yellow White\",\n\t167, \"SCE_ESCSEQ_BOLD_BLUE_WHITE\", \"default\", \"Bold Blue White\",\n\t168, \"SCE_ESCSEQ_BOLD_MAGENTA_WHITE\", \"default\", \"Bold Magenta White\",\n\t169, \"SCE_ESCSEQ_BOLD_CYAN_WHITE\", \"default\", \"Bold Cyan White\",\n\t170, \"SCE_ESCSEQ_BOLD_WHITE_WHITE\", \"default\", \"Bold White White\",\n\t171, \"SCE_ESCSEQ_IDENTIFIER\", \"default\", \"Sequence Identifier\",\n\t172, \"SCE_ESCSEQ_UNKNOWN\", \"default\", \"Sequence Unknown\",\n};\n\n\nclass LexerEscSeq : public DefaultLexer {\n\tOptionsEscSeq options;\n\tOptionSetEscSeq osEscSeq;\npublic:\n\tLexerEscSeq() :\n\t\tDefaultLexer(\"escseq\", SCLEX_ESCSEQ, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osEscSeq.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osEscSeq.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osEscSeq.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osEscSeq.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osEscSeq.DescribeWordListSets();\n\t}\n\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tstatic ILexer5 *LexerFactoryEscSeq() {\n\t\treturn new LexerEscSeq();\n\t}\n};\n\n\nSci_Position SCI_METHOD LexerEscSeq::PropertySet(const char *key, const char *val) {\n\tif (osEscSeq.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\n\nconstexpr bool Is0To9(char ch) noexcept {\n\treturn (ch >= '0') && (ch <= '9');\n}\n\n\nbool AtEOL(Accessor &styler, Sci_Position i) {\n\treturn (styler[i] == '\\n') ||\n\t       ((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n'));\n}\n\n\nconstexpr bool SequenceEnd(int ch) noexcept {\n\treturn (ch == 0) || ((ch >= '@') && (ch <= '~'));\n}\n\n\nint StyleFromSequence(const char *seq) noexcept {\n\tint fore = 0;\n\tint back = 0;\n\tint bold = 0;\n\n\twhile (!SequenceEnd(*seq)) {\n\t\tif (Is0To9(*seq)) {\n\t\t\t// Get up to 3 digits\n\t\t\tint base = *seq - '0';\n\n\t\t\tfor (int i = 0; i < 2; ++i) {\n\t\t\t\tif (!Is0To9(seq[1])) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tbase *= 10;\n\t\t\t\tbase += seq[1] - '0';\n\t\t\t\tseq++;\n\t\t\t}\n\n\t\t\tif (base == 0) {\n\t\t\t\t// Reset to default\n\t\t\t\tfore = 0;\n\t\t\t\tback = 0;\n\t\t\t\tbold = 0;\n\t\t\t} else if (base == 1) {\n\t\t\t\t// Set style as bright\n\t\t\t\tbold = 1;\n\t\t\t} else if (base == 22) {\n\t\t\t\t// Set style as not bright\n\t\t\t\tbold = 0;\n\t\t\t} else if (base >= 30 && base <= 37) {\n\t\t\t\t// Set dim fore style\n\t\t\t\tfore = base - 29;\n\t\t\t} else if (base >= 90 && base <= 97) {\n\t\t\t\t// Set bright fore style\n\t\t\t\tfore = base - 89;\n\t\t\t\tbold = 1;\n\t\t\t} else if (base >= 40 && base <= 47) {\n\t\t\t\t// Set dim back style\n\t\t\t\tback = base - 39;\n\t\t\t} else if (base >= 100 && base <= 107) {\n\t\t\t\t// Set dim back style\n\t\t\t\tback = base - 99;\n\t\t\t}\n\t\t}\n\n\t\tseq++;\n\t}\n\n\t// Set fore style as bright style if bold is set\n\tif (bold) {\n\t\tfore += 81;\n\t}\n\n\t// Set to a single style\n\tint style = fore + back * 9;\n\n\t// Skip the reserved style range between 30 and 40\n\tif (style >= 31) {\n\t\tstyle += 9;\n\t}\n\n\treturn style;\n}\n\n\nvoid ColouriseEscSeqLine(const std::string &lineBuffer,\n                         Sci_PositionU endPos,\n                         Accessor &styler,\n                         bool colourText) {\n\tconst Sci_PositionU lengthLine = lineBuffer.length();\n\tconst int style = SCE_ESCSEQ_DEFAULT;\n\n\tif (strstr(lineBuffer.c_str(), CSI)) {\n\t\tconst Sci_Position startPos = endPos - lengthLine;\n\t\tconst char *linePortion = lineBuffer.c_str();\n\t\tSci_Position startPortion = startPos;\n\t\tint portionStyle = style;\n\n\t\twhile (const char *startSeq = strstr(linePortion, CSI)) {\n\t\t\tif (startSeq > linePortion) {\n\t\t\t\tstyler.ColourTo(startPortion + (startSeq - linePortion), portionStyle);\n\t\t\t}\n\n\t\t\tconst char *endSeq = startSeq + 2;\n\n\t\t\twhile (!SequenceEnd(*endSeq))\n\t\t\t\tendSeq++;\n\n\t\t\tconst Sci_Position endSeqPosition = startPortion + (endSeq - linePortion) + 1;\n\n\t\t\tswitch (*endSeq) {\n\t\t\tcase 0:\n\t\t\t\tstyler.ColourTo(endPos, SCE_ESCSEQ_UNKNOWN);\n\t\t\t\treturn;\n\t\t\tcase 'm':  // Colour command\n\t\t\t\tstyler.ColourTo(endSeqPosition, SCE_ESCSEQ_IDENTIFIER);\n\t\t\t\tportionStyle = colourText ? StyleFromSequence(startSeq + 2) : style;\n\t\t\t\tbreak;\n\t\t\tcase 'K':  // Erase to end of line -> ignore\n\t\t\t\tstyler.ColourTo(endSeqPosition, SCE_ESCSEQ_IDENTIFIER);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tstyler.ColourTo(endSeqPosition, SCE_ESCSEQ_UNKNOWN);\n\t\t\t\tportionStyle = style;\n\t\t\t}\n\n\t\t\tstartPortion = endSeqPosition;\n\t\t\tlinePortion = endSeq + 1;\n\t\t}\n\n\t\tstyler.ColourTo(endPos, portionStyle);\n\t}\n}\n\n\nvoid LexerEscSeq::Lex(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\tstd::string lineBuffer;\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\n\tfor (Sci_PositionU i = startPos; i < startPos + length; i++) {\n\t\tlineBuffer.push_back(styler[i]);\n\n\t\t// End of line met, colourise it\n\t\tif (AtEOL(styler, i)) {\n\t\t\tColouriseEscSeqLine(lineBuffer, i, styler, options.colourText);\n\t\t\tlineBuffer.clear();\n\t\t}\n\t}\n\n\t// Last line does not have ending characters\n\tif (!lineBuffer.empty()) {\n\t\tColouriseEscSeqLine(lineBuffer, startPos + length - 1, styler, options.colourText);\n\t}\n\n\tstyler.Flush();\n}\n\n\n}\n\nextern const LexerModule lmEscSeq(SCLEX_ESCSEQ, LexerEscSeq::LexerFactoryEscSeq, \"escseq\", emptyWordListDesc);\n"
  },
  {
    "path": "lexers/LexFSharp.cxx",
    "content": "/**\n * @file LexFSharp.cxx\n * Lexer for F# 5.0\n * Copyright (c) 2021 Robert Di Pardo <dipardo.r@gmail.com>\n * Parts of LexerFSharp::Lex were adapted from LexCaml.cxx by Robert Roessler (\"RR\").\n * Parts of LexerFSharp::Fold were adapted from LexBash.cxx by Neil Hodgson and Kein-Hong Man.\n * The License.txt file describes the conditions under which this software may be distributed.\n */\n// clang-format off\n#include <cstdlib>\n#include <cassert>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n// clang-format on\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nstatic const char *const lexerName = \"fsharp\";\nstatic constexpr int WORDLIST_SIZE = 5;\nstatic const char *const fsharpWordLists[] = {\n\t\"standard language keywords\",\n\t\"core functions, including those in the FSharp.Collections namespace\",\n\t\"built-in types, core namespaces, modules\",\n\t\"optional\",\n\t\"optional\",\n\tnullptr,\n};\nstatic constexpr int keywordClasses[] = {\n\tSCE_FSHARP_KEYWORD, SCE_FSHARP_KEYWORD2, SCE_FSHARP_KEYWORD3, SCE_FSHARP_KEYWORD4, SCE_FSHARP_KEYWORD5,\n};\n\nnamespace {\n\nstruct OptionsFSharp {\n\tbool fold = true;\n\tbool foldCompact = true;\n\tbool foldComment = true;\n\tbool foldCommentStream = true;\n\tbool foldCommentMultiLine = true;\n\tbool foldPreprocessor = false;\n\tbool foldQuotes = false;\n\tbool foldImports = true;\n};\n\nstruct OptionSetFSharp : public OptionSet<OptionsFSharp> {\n\tOptionSetFSharp() {\n\t\tDefineProperty(\"fold\", &OptionsFSharp::fold);\n\t\tDefineProperty(\"fold.compact\", &OptionsFSharp::foldCompact);\n\t\tDefineProperty(\"fold.comment\", &OptionsFSharp::foldComment,\n\t\t\t\t   \"Setting this option to 0 disables comment folding in F# files.\");\n\n\t\tDefineProperty(\"fold.fsharp.comment.stream\", &OptionsFSharp::foldCommentStream,\n\t\t\t\t   \"Setting this option to 0 disables folding of ML-style comments in F# files when \"\n\t\t\t\t   \"fold.comment=1.\");\n\n\t\tDefineProperty(\"fold.fsharp.comment.multiline\", &OptionsFSharp::foldCommentMultiLine,\n\t\t\t\t   \"Setting this option to 0 disables folding of grouped line comments in F# files when \"\n\t\t\t\t   \"fold.comment=1.\");\n\n\t\tDefineProperty(\"fold.fsharp.preprocessor\", &OptionsFSharp::foldPreprocessor,\n\t\t\t\t   \"Setting this option to 1 enables folding of F# compiler directives.\");\n\n\t\tDefineProperty(\"fold.fsharp.quotes\", &OptionsFSharp::foldQuotes,\n\t\t\t\t   \"Setting this option to 1 enables folding of multi-line strings in F# files.\");\n\n\t\tDefineProperty(\"fold.fsharp.imports\", &OptionsFSharp::foldImports,\n\t\t\t\t   \"Setting this option to 0 disables folding of F# import declarations.\");\n\n\t\tDefineWordListSets(fsharpWordLists);\n\t}\n};\n\nclass UnicodeChar {\n\tenum class Notation { none, asciiDec, asciiHex, utf16, utf32 };\n\tNotation type = Notation::none;\n\t// single-byte Unicode char (000 - 255)\n\tint asciiDigits[3] = { 0 };\n\tint maxDigit = '9';\n\tint toEnd = 0;\n\tbool invalid = false;\n\npublic:\n\tUnicodeChar() noexcept = default;\n\texplicit UnicodeChar(const int prefix) {\n\t\tif (IsADigit(prefix)) {\n\t\t\t*asciiDigits = prefix;\n\t\t\tif (*asciiDigits >= '0' && *asciiDigits <= '2') {\n\t\t\t\ttype = Notation::asciiDec;\n\t\t\t\t// count first digit as \"prefix\"\n\t\t\t\ttoEnd = 2;\n\t\t\t}\n\t\t} else if (prefix == 'x' || prefix == 'u' || prefix == 'U') {\n\t\t\tswitch (prefix) {\n\t\t\t\tcase 'x':\n\t\t\t\t\ttype = Notation::asciiHex;\n\t\t\t\t\ttoEnd = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'u':\n\t\t\t\t\ttype = Notation::utf16;\n\t\t\t\t\ttoEnd = 4;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'U':\n\t\t\t\t\ttype = Notation::utf32;\n\t\t\t\t\ttoEnd = 8;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tvoid Parse(const int ch) {\n\t\tinvalid = false;\n\t\tswitch (type) {\n\t\t\tcase Notation::asciiDec: {\n\t\t\t\tmaxDigit = (*asciiDigits < '2') ? '9' : (asciiDigits[1] <= '4') ? '9' : '5';\n\t\t\t\tif (IsADigit(ch) && asciiDigits[1] <= maxDigit && ch <= maxDigit) {\n\t\t\t\t\tasciiDigits[1] = ch;\n\t\t\t\t\ttoEnd--;\n\t\t\t\t} else {\n\t\t\t\t\tinvalid = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase Notation::asciiHex:\n\t\t\tcase Notation::utf16:\n\t\t\t\tif (IsADigit(ch, 16)) {\n\t\t\t\t\ttoEnd--;\n\t\t\t\t} else {\n\t\t\t\t\tinvalid = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase Notation::utf32:\n\t\t\t\tif ((toEnd > 6 && ch == '0') || (toEnd <= 6 && IsADigit(ch, 16))) {\n\t\t\t\t\ttoEnd--;\n\t\t\t\t} else {\n\t\t\t\t\tinvalid = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase Notation::none:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tconstexpr bool AtEnd() noexcept {\n\t\treturn invalid || type == Notation::none || (type != Notation::none && toEnd < 0);\n\t}\n};\n\ninline bool MatchStreamCommentStart(StyleContext &cxt) {\n\t// match (* ... *), but allow point-free usage of the `*` operator,\n\t// e.g.  List.fold (*) 1 [ 1; 2; 3 ]\n\treturn (cxt.Match('(', '*') && cxt.GetRelative(2) != ')');\n}\n\ninline bool MatchStreamCommentEnd(const StyleContext &cxt) {\n\treturn (cxt.ch == ')' && cxt.chPrev == '*');\n}\n\ninline bool MatchLineComment(const StyleContext &cxt) {\n\t// style shebang lines as comments in F# scripts:\n\t// https://fsharp.org/specs/language-spec/4.1/FSharpSpec-4.1-latest.pdf#page=30&zoom=auto,-98,537\n\treturn cxt.Match('/', '/') || cxt.Match('#', '!');\n}\n\ninline bool MatchLineNumberStart(StyleContext &cxt) {\n\treturn cxt.atLineStart && (cxt.MatchIgnoreCase(\"#line\") ||\n\t\t(cxt.ch == '#' && (IsADigit(cxt.chNext) || IsADigit(cxt.GetRelative(2)))));\n}\n\ninline bool MatchPPDirectiveStart(const StyleContext &cxt) {\n\treturn (cxt.atLineStart && cxt.ch == '#' && iswordstart(cxt.chNext));\n}\n\ninline bool MatchTypeAttributeStart(const StyleContext &cxt) {\n\treturn cxt.Match('[', '<');\n}\n\ninline bool MatchTypeAttributeEnd(const StyleContext &cxt) {\n\treturn (cxt.ch == ']' && cxt.chPrev == '>');\n}\n\ninline bool MatchQuotedExpressionStart(const StyleContext &cxt) {\n\treturn cxt.Match('<', '@');\n}\n\ninline bool MatchQuotedExpressionEnd(const StyleContext &cxt) {\n\treturn (cxt.ch == '>' && cxt.chPrev == '@');\n}\n\ninline bool MatchStringStart(StyleContext &cxt) {\n\treturn (cxt.ch == '\"' || (cxt.chNext == '\"' && AnyOf(cxt.ch, '@', '$')) ||\n\t\t(cxt.GetRelative(2, '\"') && (cxt.Match('@', '$') || cxt.Match('$', '@'))));\n}\n\ninline bool FollowsEscapedBackslash(StyleContext &cxt) {\n\tint count = 0;\n\tfor (Sci_Position offset = 1; cxt.GetRelative(-offset) == '\\\\'; offset++)\n\t\tcount++;\n\treturn count % 2 != 0;\n}\n\ninline bool MatchStringEnd(StyleContext &cxt, bool &rawString) {\n\tbool result = false;\n\tswitch (cxt.state) {\n\t\tcase SCE_FSHARP_STRING:\n\t\t\tresult =\n\t\t\t    (rawString && cxt.Match(\"\\\"\\\"\\\"\") && cxt.chPrev != '$') ||\n\t\t\t    (!rawString && cxt.ch == '\"' &&\n\t\t\t     (cxt.chPrev != '\\\\' || (cxt.GetRelative(-2) == '\\\\' && !FollowsEscapedBackslash(cxt))));\n\t\t\tbreak;\n\t\tcase SCE_FSHARP_VERBATIM:\n\t\t\tresult =\n\t\t\t    // embedded quotes must be in pairs\n\t\t\t    cxt.ch == '\"' && cxt.chNext != '\"' &&\n\t\t\t    (cxt.chPrev != '\"' ||\n\t\t\t     // empty verbatim string?\n\t\t\t     (AnyOf(cxt.GetRelative(-2), '@', '$') ||\n\t\t\t      // pair of quotes at end of verbatim string?\n\t\t\t      (cxt.GetRelative(-2) == '\"' && !(AnyOf(cxt.GetRelative(-3), '@', '$')))));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\tif (rawString && result)\n\t\trawString = false;\n\treturn result;\n}\n\ninline bool MatchCharacterStart(StyleContext &cxt) {\n\t// don't style generic type parameters: 'a, 'b, 'T, etc.\n\treturn (cxt.ch == '\\'' && !(cxt.chPrev == ':' || cxt.GetRelative(-2) == ':'));\n}\n\ninline bool IsLineEnd(StyleContext &cxt, const Sci_Position offset) {\n\tconst int ch = cxt.GetRelative(offset, '\\n');\n\treturn (ch == '\\r' || ch == '\\n');\n}\n\nclass LexerFSharp : public DefaultLexer {\n\tWordList keywords[WORDLIST_SIZE];\n\tOptionsFSharp options;\n\tOptionSetFSharp optionSet;\n\tCharacterSet setOperators;\n\tCharacterSet setFormatSpecs;\n\tCharacterSet setDotNetFormatSpecs;\n\tCharacterSet setFormatFlags;\n\tCharacterSet numericMetaChars1;\n\tCharacterSet numericMetaChars2;\n\tstd::map<int, int> numericPrefixes = { { 'b', 2 }, { 'o', 8 }, { 'x', 16 } };\n\tstatic constexpr int rawStringMask = 0x10000;\n\tstatic constexpr int interpolatedStringMask = 0x20000;\n\npublic:\n\texplicit LexerFSharp()\n\t    : DefaultLexer(lexerName, SCLEX_FSHARP),\n\t      setOperators(CharacterSet::setNone, \"~^'-+*/%=@|&<>()[]{};,:!?\"),\n\t      setFormatSpecs(CharacterSet::setNone, \".%aAbBcdeEfFgGiMoOstuxX0123456789\"),\n\t      setDotNetFormatSpecs(CharacterSet::setNone, \"cCdDeEfFgGnNpPxX\"),\n\t      setFormatFlags(CharacterSet::setNone, \".-+0 \"),\n\t      numericMetaChars1(CharacterSet::setNone, \"_uU\"),\n\t      numericMetaChars2(CharacterSet::setNone, \"fFIlLmMnsy\") {\n\t\tSetOptionSet(&optionSet);\n\t}\n\tLexerFSharp(const LexerFSharp &) = delete;\n\tLexerFSharp(LexerFSharp &&) = delete;\n\tLexerFSharp &operator=(const LexerFSharp &) = delete;\n\tLexerFSharp &operator=(LexerFSharp &&) = delete;\n\t~LexerFSharp() override = default;\n\tstatic ILexer5 *LexerFactoryFSharp() {\n\t\treturn new LexerFSharp();\n\t}\n\tvoid SCI_METHOD Release() noexcept override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const noexcept override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD GetName() noexcept override {\n\t\treturn lexerName;\n\t}\n\tint SCI_METHOD GetIdentifier() noexcept override {\n\t\treturn SCLEX_FSHARP;\n\t}\n\tint SCI_METHOD LineEndTypesSupported() noexcept override {\n\t\treturn SC_LINE_END_TYPE_DEFAULT;\n\t}\n\tvoid *SCI_METHOD PrivateCall(int, void *) noexcept override {\n\t\treturn nullptr;\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override {\n\t\tif (optionSet.PropertySet(&options, key, val)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn INVALID_POSITION;\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU start, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU start, Sci_Position length, int initStyle,IDocument *pAccess) override;\n\nprivate:\n\tinline bool IsNumber(StyleContext &cxt, const int base = 10) {\n\t\treturn IsADigit(cxt.ch, base) || (IsADigit(cxt.chPrev, base) && numericMetaChars1.Contains(cxt.ch)) ||\n\t\t       (IsADigit(cxt.GetRelative(-2), base) && numericMetaChars2.Contains(cxt.ch));\n\t}\n\n\tinline bool IsFloat(StyleContext &cxt) {\n\t\tif (cxt.MatchIgnoreCase(\"e+\") || cxt.MatchIgnoreCase(\"e-\")) {\n\t\t\tcxt.Forward();\n\t\t\treturn true;\n\t\t}\n\t\treturn ((cxt.chPrev == '.' && IsADigit(cxt.ch)) ||\n\t\t\t(IsADigit(cxt.chPrev) && (cxt.ch == '.' || numericMetaChars2.Contains(cxt.ch))));\n\t}\n};\n\nSci_Position SCI_METHOD LexerFSharp::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tSci_Position firstModification = INVALID_POSITION;\n\n\tif (n < WORDLIST_SIZE) {\n\t\twordListN = &keywords[n];\n\t}\n\tif (wordListN && wordListN->Set(wl)) {\n\t\tfirstModification = 0;\n\t}\n\treturn firstModification;\n}\n\nvoid SCI_METHOD LexerFSharp::Lex(Sci_PositionU start, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\tStyleContext sc(start, static_cast<Sci_PositionU>(length), initStyle, styler);\n\tSci_Position lineCurrent = styler.GetLine(static_cast<Sci_Position>(start));\n\tSci_PositionU cursor = 0;\n\tUnicodeChar uniCh = UnicodeChar();\n\tstd::string token;\n\tconstexpr Sci_Position MAX_WORD_LEN = 64;\n\tconstexpr int SPACE = ' ';\n\tint currentBase = 10;\n\tint stringResumeState = SCE_FSHARP_STRING;\n\tint lineState = (lineCurrent >= 1) ? styler.GetLineState(lineCurrent - 1) : 0;\n\tint levelNesting = lineState & 0xff;\n\tbool isRawString = (lineState & rawStringMask) != 0;\n\tbool canInterpolate = (lineState & interpolatedStringMask) != 0;\n\tbool isInterpolated = false;\n\n\twhile (sc.More()) {\n\t\tSci_PositionU colorSpan = sc.currentPos - 1;\n\t\tint state = -1;\n\t\tbool advance = true;\n\n\t\tswitch (sc.state & 0xff) {\n\t\t\tcase SCE_FSHARP_DEFAULT:\n\t\t\t\tcursor = sc.currentPos;\n\n\t\t\t\tif (MatchLineNumberStart(sc)) {\n\t\t\t\t\tstate = SCE_FSHARP_LINENUM;\n\t\t\t\t} else if (MatchPPDirectiveStart(sc)) {\n\t\t\t\t\tstate = SCE_FSHARP_PREPROCESSOR;\n\t\t\t\t} else if (MatchLineComment(sc)) {\n\t\t\t\t\tstate = SCE_FSHARP_COMMENTLINE;\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ch = SPACE;\n\t\t\t\t} else if (MatchStreamCommentStart(sc)) {\n\t\t\t\t\tstate = SCE_FSHARP_COMMENT;\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ch = SPACE;\n\t\t\t\t} else if (MatchTypeAttributeStart(sc)) {\n\t\t\t\t\tstate = SCE_FSHARP_ATTRIBUTE;\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (MatchQuotedExpressionStart(sc)) {\n\t\t\t\t\tstate = SCE_FSHARP_QUOTATION;\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (MatchCharacterStart(sc)) {\n\t\t\t\t\tstate = SCE_FSHARP_CHARACTER;\n\t\t\t\t} else if (MatchStringStart(sc)) {\n\t\t\t\t\tbool isVerbatim = sc.ch == '@' || sc.Match('$', '@');\n\t\t\t\t\tcanInterpolate = sc.ch == '$' || sc.Match('@', '$');\n\t\t\t\t\t// allow unescaped double quotes inside literal or interpolated raw strings\n\t\t\t\t\tisRawString = sc.Match(\"$\\\"\\\"\\\"\") || sc.Match(\"\\\"\\\"\\\"\") ||\n\t\t\t\t\t\t      sc.Match(\"@$\\\"\\\"\\\"\") || sc.Match(\"$@\\\"\\\"\\\"\");\n\t\t\t\t\tstate = isVerbatim ? SCE_FSHARP_VERBATIM : SCE_FSHARP_STRING;\n\t\t\t\t} else if (IsADigit(sc.ch, currentBase) ||\n\t\t\t\t\t   ((sc.ch == '+' || sc.ch == '-') && IsADigit(sc.chNext))) {\n\t\t\t\t\tstate = SCE_FSHARP_NUMBER;\n\t\t\t\t} else if (setOperators.Contains(sc.ch) &&\n\t\t\t\t\t   // don't use operator style in async keywords (e.g. `return!`)\n\t\t\t\t\t   !(sc.ch == '!' && iswordstart(sc.chPrev)) &&\n\t\t\t\t\t   // don't use operator style in member access, array/string indexing\n\t\t\t\t\t   !(sc.ch == '.' && (sc.chPrev == '\\\"' || iswordstart(sc.chPrev)) &&\n\t\t\t\t\t     (iswordstart(sc.chNext) || sc.chNext == '['))) {\n\t\t\t\t\tstate = SCE_FSHARP_OPERATOR;\n\t\t\t\t} else if (sc.Match('`', '`')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tstate = SCE_FSHARP_QUOT_IDENTIFIER;\n\t\t\t\t} else if (iswordstart(sc.ch)) {\n\t\t\t\t\tstate = SCE_FSHARP_IDENTIFIER;\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_LINENUM:\n\t\t\tcase SCE_FSHARP_PREPROCESSOR:\n\t\t\t\tif (sc.MatchLineEnd()) {\n\t\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\t\tadvance = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_COMMENT:\n\t\t\t\tif (MatchStreamCommentStart(sc)) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ch = SPACE;\n\t\t\t\t\tlevelNesting++;\n\t\t\t\t} else if (MatchStreamCommentEnd(sc)) {\n\t\t\t\t\tif (levelNesting > 0)\n\t\t\t\t\t\tlevelNesting--;\n\t\t\t\t\telse {\n\t\t\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\t\t\tcolorSpan++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_ATTRIBUTE:\n\t\t\tcase SCE_FSHARP_QUOTATION:\n\t\t\t\tif (MatchTypeAttributeEnd(sc) || MatchQuotedExpressionEnd(sc)) {\n\t\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\t\tcolorSpan++;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_CHARACTER:\n\t\t\t\tif (sc.chPrev == '\\\\' && sc.GetRelative(-2) != '\\\\') {\n\t\t\t\t\tuniCh = UnicodeChar(sc.ch);\n\t\t\t\t} else if (sc.ch == '\\'' &&\n\t\t\t\t\t   ((sc.chPrev == ' ' && sc.GetRelative(-2) == '\\'') || sc.chPrev != '\\\\' ||\n\t\t\t\t\t\t(sc.chPrev == '\\\\' && sc.GetRelative(-2) == '\\\\'))) {\n\t\t\t\t\t// byte literal?\n\t\t\t\t\tif (sc.Match('\\'', 'B')) {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\tcolorSpan++;\n\t\t\t\t\t}\n\t\t\t\t\tif (!sc.atLineEnd) {\n\t\t\t\t\t\tcolorSpan++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ChangeState(SCE_FSHARP_IDENTIFIER);\n\t\t\t\t\t}\n\t\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\t} else {\n\t\t\t\t\tuniCh.Parse(sc.ch);\n\t\t\t\t\tif (uniCh.AtEnd() && (sc.currentPos - cursor) >= 2) {\n\t\t\t\t\t\t// terminate now, since we left the char behind\n\t\t\t\t\t\tsc.ChangeState(SCE_FSHARP_IDENTIFIER);\n\t\t\t\t\t\tadvance = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_STRING:\n\t\t\tcase SCE_FSHARP_VERBATIM:\n\t\t\t\tif (MatchStringEnd(sc, isRawString)) {\n\t\t\t\t\tconst Sci_Position strLen = static_cast<Sci_Position>(sc.currentPos - cursor);\n\t\t\t\t\t// backtrack to start of string\n\t\t\t\t\tfor (Sci_Position i = -strLen; i < 0; i++) {\n\t\t\t\t\t\tconst int startQuote = sc.GetRelative(i);\n\t\t\t\t\t\tif (startQuote == '\\\"') {\n\t\t\t\t\t\t\t// byte array?\n\t\t\t\t\t\t\tif (sc.Match('\\\"', 'B')) {\n\t\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t\t\tcolorSpan++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!sc.atLineEnd) {\n\t\t\t\t\t\t\t\tcolorSpan++;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsc.ChangeState(SCE_FSHARP_IDENTIFIER);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\t\t\t\tcanInterpolate = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '%' && !(sc.Match(\"%  \") || sc.Match(\"% \\\"\")) &&\n\t\t\t\t\t   (setFormatSpecs.Contains(sc.chNext) || setFormatFlags.Contains(sc.chNext))) {\n\t\t\t\t\tif (canInterpolate && sc.chNext != '%') {\n\t\t\t\t\t\tfor (Sci_Position i = 2; i < length && !IsLineEnd(sc, i); i++) {\n\t\t\t\t\t\t\tif (sc.GetRelative(i) == '{') {\n\t\t\t\t\t\t\t\tstate = setFormatSpecs.Contains(sc.GetRelative(i - 1))\n\t\t\t\t\t\t\t\t\t    ? SCE_FSHARP_FORMAT_SPEC\n\t\t\t\t\t\t\t\t\t    : state;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate = SCE_FSHARP_FORMAT_SPEC;\n\t\t\t\t\t}\n\t\t\t\t} else if (isInterpolated) {\n\t\t\t\t\tif (sc.ch == ',') {\n\t\t\t\t\t\t// .NET alignment specifier?\n\t\t\t\t\t\tstate = (sc.chNext == '+' || sc.chNext == '-' || IsADigit(sc.chNext))\n\t\t\t\t\t\t\t    ? SCE_FSHARP_FORMAT_SPEC\n\t\t\t\t\t\t\t    : state;\n\t\t\t\t\t} else if (sc.ch == ':') {\n\t\t\t\t\t\t// .NET format specifier?\n\t\t\t\t\t\tstate = setDotNetFormatSpecs.Contains(sc.chNext)\n\t\t\t\t\t\t\t    ? SCE_FSHARP_FORMAT_SPEC\n\t\t\t\t\t\t\t    : state;\n\t\t\t\t\t} else if (sc.chNext == '}') {\n\t\t\t\t\t\tisInterpolated = false;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (canInterpolate && sc.ch == '{') {\n\t\t\t\t\tisInterpolated = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_QUOT_IDENTIFIER:\n\t\t\t\tif (sc.ch == '`' && sc.chPrev == '`') {\n\t\t\t\t\tcolorSpan++;\n\t\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_IDENTIFIER:\n\t\t\t\tif (!(iswordstart(sc.ch) || AnyOf(sc.ch, '\\'', '!'))) {\n\t\t\t\t\tconst Sci_PositionU wordLen = sc.currentPos - cursor;\n\t\t\t\t\tif (wordLen < MAX_WORD_LEN) {\n\t\t\t\t\t\t// wordLength is believable as keyword, [re-]construct token - RR\n\t\t\t\t\t\ttoken = styler.GetRange(sc.currentPos - wordLen, sc.currentPos);\n\t\t\t\t\t\t// except for the standard source file macros,\n\t\t\t\t\t\t// a snake_case_identifier can never be a keyword\n\t\t\t\t\t\tif (token.find('_') == token.npos) {\n\t\t\t\t\t\t\tfor (int i = 0; i < WORDLIST_SIZE; i++) {\n\t\t\t\t\t\t\t\tif (keywords[i].InList(token)) {\n\t\t\t\t\t\t\t\t\tsc.ChangeState(keywordClasses[i]);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (token == \"__LINE__\" || token == \"__SOURCE_DIRECTORY__\" ||\n\t\t\t\t\t\t\t   token == \"__SOURCE_FILE__\") {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_FSHARP_KEYWORD);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\t\tadvance = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_OPERATOR:\n\t\t\t\t// special-case \"()\" and \"[]\" tokens as KEYWORDS - RR\n\t\t\t\tif ((sc.ch == ')' && sc.chPrev == '(') || (sc.ch == ']' && sc.chPrev == '[')) {\n\t\t\t\t\tsc.ChangeState(SCE_FSHARP_KEYWORD);\n\t\t\t\t\tcolorSpan++;\n\t\t\t\t} else {\n\t\t\t\t\tadvance = false;\n\t\t\t\t}\n\t\t\t\tstate = SCE_FSHARP_DEFAULT;\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_NUMBER:\n\t\t\t\tif ((setOperators.Contains(sc.chPrev) || IsASpaceOrTab(sc.chPrev)) && sc.ch == '0') {\n\t\t\t\t\tif (numericPrefixes.find(sc.chNext) != numericPrefixes.end()) {\n\t\t\t\t\t\tcurrentBase = numericPrefixes[sc.chNext];\n\t\t\t\t\t\tsc.Forward(2);\n\t\t\t\t\t}\n\t\t\t\t} else if ((setOperators.Contains(sc.GetRelative(-2)) || IsASpaceOrTab(sc.GetRelative(-2))) &&\n\t\t\t\t\t   sc.chPrev == '0') {\n\t\t\t\t\tif (numericPrefixes.find(sc.ch) != numericPrefixes.end()) {\n\t\t\t\t\t\tcurrentBase = numericPrefixes[sc.ch];\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstate = (IsNumber(sc, currentBase) || IsFloat(sc))\n\t\t\t\t\t? SCE_FSHARP_NUMBER\n\t\t\t\t\t// change style even when operators aren't spaced\n\t\t\t\t\t: setOperators.Contains(sc.ch) ? SCE_FSHARP_OPERATOR : SCE_FSHARP_DEFAULT;\n\t\t\t\tcurrentBase = (state == SCE_FSHARP_NUMBER) ? currentBase : 10;\n\t\t\t\tbreak;\n\t\t\tcase SCE_FSHARP_FORMAT_SPEC:\n\t\t\t\tif (!(isInterpolated && IsADigit(sc.chNext)) &&\n\t\t\t\t\t(!setFormatSpecs.Contains(sc.chNext) ||\n\t\t\t\t    !(setFormatFlags.Contains(sc.ch) || IsADigit(sc.ch)) ||\n\t\t\t\t    (setFormatFlags.Contains(sc.ch) && sc.ch == sc.chNext))) {\n\t\t\t\t\tcolorSpan++;\n\t\t\t\t\tstate = stringResumeState;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (sc.MatchLineEnd()) {\n\t\t\tlineState = (sc.state == SCE_FSHARP_COMMENT) ? levelNesting : 0;\n\t\t\tif (sc.state == SCE_FSHARP_STRING || sc.state == SCE_FSHARP_VERBATIM)\n\t\t\t\tlineState |= (sc.state << 8);\n\t\t\tif (isRawString)\n\t\t\t\tlineState |= rawStringMask;\n\t\t\tif (canInterpolate)\n\t\t\t\tlineState |= interpolatedStringMask;\n\t\t\tstyler.SetLineState(lineCurrent++, lineState);\n\t\t\tadvance = true;\n\t\t}\n\n\t\tif (state >= SCE_FSHARP_DEFAULT) {\n\t\t\tif (state == SCE_FSHARP_FORMAT_SPEC)\n\t\t\t\tstringResumeState = sc.state;\n\t\t\tstyler.ColourTo(colorSpan, sc.state);\n\t\t\tsc.ChangeState(state);\n\t\t}\n\n\t\tif (advance) {\n\t\t\tsc.Forward();\n\t\t}\n\t}\n\n\tsc.Complete();\n}\n\nbool LineContains(LexAccessor &styler, const char *word, const Sci_Position start,\n\t\t  const int chAttr = SCE_FSHARP_DEFAULT);\n\nvoid FoldLexicalGroup(LexAccessor &styler, int &levelNext, const Sci_Position lineCurrent, const char *word,\n\t\t      const int chAttr);\n\nvoid SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tif (!options.fold) {\n\t\treturn;\n\t}\n\n\tLexAccessor styler(pAccess);\n\tSci_Position startPos = static_cast<Sci_Position>(start);\n\tconst Sci_PositionU endPos = start + length;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tstartPos = styler.LineStart(lineCurrent);\n\t\tinitStyle = (startPos > 0) ? styler.StyleAt(startPos - 1) : SCE_FSHARP_DEFAULT;\n\t}\n\tSci_Position lineNext = lineCurrent + 1;\n\tSci_Position lineStartNext = styler.LineStart(lineNext);\n\tint style = initStyle;\n\tint styleNext = styler.StyleAt(startPos);\n\tchar chNext = styler[startPos];\n\tint levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelNext = levelCurrent;\n\tint visibleChars = 0;\n\n\tfor (Sci_PositionU i = static_cast<Sci_PositionU>(startPos); i < endPos; i++) {\n\t\tconst Sci_Position currentPos = static_cast<Sci_Position>(i);\n\t\tconst bool atEOL = (currentPos == (lineStartNext - 1));\n\t\tconst bool atLineOrDocEnd = (atEOL || (i == (endPos - 1)));\n\t\tconst int stylePrev = style;\n\t\tconst char ch = chNext;\n\t\tconst bool inLineComment = (stylePrev == SCE_FSHARP_COMMENTLINE);\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(currentPos + 1);\n\t\tchNext = styler.SafeGetCharAt(currentPos + 1);\n\n\t\tif (options.foldComment) {\n\t\t\tif (options.foldCommentMultiLine && inLineComment && atEOL) {\n\t\t\t\tFoldLexicalGroup(styler, levelNext, lineCurrent, \"//\", SCE_FSHARP_COMMENTLINE);\n\t\t\t}\n\n\t\t\tif (options.foldCommentStream && style == SCE_FSHARP_COMMENT && !inLineComment) {\n\t\t\t\tif (stylePrev != SCE_FSHARP_COMMENT ||\n\t\t\t\t    (styler.Match(currentPos, \"(*\") &&\n\t\t\t\t     !LineContains(styler, \"*)\", currentPos + 2, SCE_FSHARP_COMMENT))) {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if ((styleNext != SCE_FSHARP_COMMENT ||\n\t\t\t\t\t    ((styler.Match(currentPos, \"*)\") &&\n\t\t\t\t\t      !LineContains(styler, \"(*\", styler.LineStart(lineCurrent), SCE_FSHARP_COMMENT)) &&\n\t\t\t\t\t     styler.GetLineState(lineCurrent - 1) > 0)) &&\n\t\t\t\t\t   !atEOL) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (options.foldQuotes && atEOL) {\n\t\t\tconst int lineState = (styler.GetLineState(lineCurrent > 0 ? lineCurrent - 1 : lineCurrent) >> 8) & 0xff;\n\t\t\tconst bool isQuoted = (lineState == SCE_FSHARP_STRING || lineState == SCE_FSHARP_VERBATIM);\n\t\t\tconst bool isStringlike = (style == SCE_FSHARP_STRING || style == SCE_FSHARP_VERBATIM);\n\t\t\tif (isStringlike && (!isQuoted || lineCurrent == 0)) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (!isStringlike && isQuoted) {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\n\t\tif (options.foldPreprocessor && style == SCE_FSHARP_PREPROCESSOR) {\n\t\t\tif (styler.Match(currentPos, \"#if\")) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (styler.Match(currentPos, \"#endif\")) {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\n\t\tif (options.foldImports && styler.Match(currentPos, \"open \") && styleNext == SCE_FSHARP_KEYWORD) {\n\t\t\tFoldLexicalGroup(styler, levelNext, lineCurrent, \"open \", SCE_FSHARP_KEYWORD);\n\t\t}\n\n\t\tif (atLineOrDocEnd) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tint lev = levelUse | levelNext << 16;\n\n\t\t\tif (visibleChars == 0 && options.foldCompact) {\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\t}\n\t\t\tif ((levelUse < levelNext) && (visibleChars > 0)) {\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\n\t\t\tvisibleChars = 0;\n\t\t\tlineCurrent++;\n\t\t\tlineNext = lineCurrent + 1;\n\t\t\tlineStartNext = styler.LineStart(lineNext);\n\t\t\tlevelCurrent = levelNext;\n\t\t}\n\n\t\tif (!IsASpace(ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\tconst int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelCurrent | flagsNext);\n}\n\nbool LineContains(LexAccessor &styler, const char *word, const Sci_Position start, const int chAttr) {\n\tbool found = false;\n\tbool requireStyle = (chAttr > SCE_FSHARP_DEFAULT);\n\tfor (Sci_Position i = start; i < styler.LineStart(styler.GetLine(start) + 1) - 1; i++) {\n\t\tif (styler.Match(i, word)) {\n\t\t\tfound = requireStyle ? styler.StyleAt(i) == chAttr : true;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn found;\n}\n\nvoid FoldLexicalGroup(LexAccessor &styler, int &levelNext, const Sci_Position lineCurrent, const char *word,\n\t\t      const int chAttr) {\n\tconst Sci_Position linePrev = styler.LineStart(lineCurrent - 1);\n\tconst Sci_Position lineNext = styler.LineStart(lineCurrent + 1);\n\tconst bool follows = (lineCurrent > 0) && LineContains(styler, word, linePrev, chAttr);\n\tconst bool isFollowed = LineContains(styler, word, lineNext, chAttr);\n\n\tif (isFollowed && !follows) {\n\t\tlevelNext++;\n\t} else if (!isFollowed && follows && levelNext > SC_FOLDLEVELBASE) {\n\t\tlevelNext--;\n\t}\n}\n} // namespace\n\nextern const LexerModule lmFSharp(SCLEX_FSHARP, LexerFSharp::LexerFactoryFSharp, \"fsharp\", fsharpWordLists);\n"
  },
  {
    "path": "lexers/LexFlagship.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexFlagship.cxx\n ** Lexer for Harbour and FlagShip.\n ** (Syntactically compatible to other xBase dialects, like Clipper, dBase, Clip, FoxPro etc.)\n **/\n// Copyright 2005 by Randy Butler\n// Copyright 2010 by Xavi <jarabal/at/gmail.com> (Harbour)\n// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// Extended to accept accented characters\nstatic inline bool IsAWordChar(int ch)\n{\n\treturn ch >= 0x80 ||\n\t\t\t\t(isalnum(ch) || ch == '_');\n}\n\nstatic void ColouriseFlagShipDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                                 WordList *keywordlists[], Accessor &styler)\n{\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\tWordList &keywords4 = *keywordlists[3];\n\tWordList &keywords5 = *keywordlists[4];\n\n\t// property lexer.flagship.styling.within.preprocessor\n\t//\tFor Harbour code, determines whether all preprocessor code is styled in the preprocessor style (0) or only from the\n\t//\tinitial # to the end of the command word(1, the default). It also determines how to present text, dump, and disabled code.\n\tbool stylingWithinPreprocessor = styler.GetPropertyInt(\"lexer.flagship.styling.within.preprocessor\", 1) != 0;\n\n\tCharacterSet setDoxygen(CharacterSet::setAlpha, \"$@\\\\&<>#{}[]\");\n\n\tint visibleChars = 0;\n\tint closeStringChar = 0;\n\tint styleBeforeDCKeyword = SCE_FS_DEFAULT;\n\tbool bEnableCode = initStyle < SCE_FS_DISABLEDCODE;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_FS_OPERATOR:\n\t\t\tcase SCE_FS_OPERATOR_C:\n\t\t\tcase SCE_FS_WORDOPERATOR:\n\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_IDENTIFIER:\n\t\t\tcase SCE_FS_IDENTIFIER_C:\n\t\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\t\tchar s[64];\n\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(bEnableCode ? SCE_FS_KEYWORD : SCE_FS_KEYWORD_C);\n\t\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(bEnableCode ? SCE_FS_KEYWORD2 : SCE_FS_KEYWORD2_C);\n\t\t\t\t\t} else if (bEnableCode && keywords3.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_FS_KEYWORD3);\n\t\t\t\t\t} else if (bEnableCode && keywords4.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_FS_KEYWORD4);\n\t\t\t\t\t}// Else, it is really an identifier...\n\t\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_NUMBER:\n\t\t\t\tif (!IsAWordChar(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\t\tsc.SetState(SCE_FS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_NUMBER_C:\n\t\t\t\tif (!IsAWordChar(sc.ch) && sc.ch != '.') {\n\t\t\t\t\tsc.SetState(SCE_FS_DEFAULT_C);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_CONSTANT:\n\t\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_FS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_STRING:\n\t\t\tcase SCE_FS_STRING_C:\n\t\t\t\tif (sc.ch == closeStringChar) {\n\t\t\t\t\tsc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(bEnableCode ? SCE_FS_STRINGEOL : SCE_FS_STRINGEOL_C);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_STRINGEOL:\n\t\t\tcase SCE_FS_STRINGEOL_C:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_COMMENTDOC:\n\t\t\tcase SCE_FS_COMMENTDOC_C:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t} else if (sc.ch == '@' || sc.ch == '\\\\') { // JavaDoc and Doxygen support\n\t\t\t\t\t// Verify that we have the conditions to mark a comment-doc-keyword\n\t\t\t\t\tif ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {\n\t\t\t\t\t\tstyleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C;\n\t\t\t\t\t\tsc.SetState(SCE_FS_COMMENTDOCKEYWORD);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_COMMENT:\n\t\t\tcase SCE_FS_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_FS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_COMMENTLINEDOC:\n\t\t\tcase SCE_FS_COMMENTLINEDOC_C:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t} else if (sc.ch == '@' || sc.ch == '\\\\') { // JavaDoc and Doxygen support\n\t\t\t\t\t// Verify that we have the conditions to mark a comment-doc-keyword\n\t\t\t\t\tif ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {\n\t\t\t\t\t\tstyleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C;\n\t\t\t\t\t\tsc.SetState(SCE_FS_COMMENTDOCKEYWORD);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_COMMENTDOCKEYWORD:\n\t\t\t\tif ((styleBeforeDCKeyword == SCE_FS_COMMENTDOC || styleBeforeDCKeyword == SCE_FS_COMMENTDOC_C) &&\n\t\t\t\t\t\tsc.Match('*', '/')) {\n\t\t\t\t\tsc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t} else if (!setDoxygen.Contains(sc.ch)) {\n\t\t\t\t\tchar s[64];\n\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t\tif (!IsASpace(sc.ch) || !keywords5.InList(s + 1)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(styleBeforeDCKeyword);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_PREPROCESSOR:\n\t\t\tcase SCE_FS_PREPROCESSOR_C:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tif (!(sc.chPrev == ';' || sc.GetRelative(-2) == ';')) {\n\t\t\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t\t}\n\t\t\t\t} else if (stylingWithinPreprocessor) {\n\t\t\t\t\tif (IsASpaceOrTab(sc.ch)) {\n\t\t\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.Match('/', '*') || sc.Match('/', '/') || sc.Match('&', '&')) {\n\t\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_DISABLEDCODE:\n\t\t\t\tif (sc.ch == '#' && visibleChars == 0) {\n\t\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);\n\t\t\t\t\tdo {\t// Skip whitespace between # and preprocessor word\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} while (IsASpaceOrTab(sc.ch) && sc.More());\n\t\t\t\t\tif (sc.MatchIgnoreCase(\"pragma\")) {\n\t\t\t\t\t\tsc.Forward(6);\n\t\t\t\t\t\tdo {\t// Skip more whitespace until keyword\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t} while (IsASpaceOrTab(sc.ch) && sc.More());\n\t\t\t\t\t\tif (sc.MatchIgnoreCase(\"enddump\") || sc.MatchIgnoreCase(\"__endtext\")) {\n\t\t\t\t\t\t\tbEnableCode = true;\n\t\t\t\t\t\t\tsc.SetState(SCE_FS_DISABLEDCODE);\n\t\t\t\t\t\t\tsc.Forward(sc.ch == '_' ? 8 : 6);\n\t\t\t\t\t\t\tsc.ForwardSetState(SCE_FS_DEFAULT);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_FS_DISABLEDCODE);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ChangeState(SCE_FS_DISABLEDCODE);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_FS_DATE:\n\t\t\t\tif (sc.ch == '}') {\n\t\t\t\t\tsc.ForwardSetState(SCE_FS_DEFAULT);\n\t\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_FS_STRINGEOL);\n\t\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_FS_DEFAULT || sc.state == SCE_FS_DEFAULT_C) {\n\t\t\tif (bEnableCode &&\n\t\t\t\t\t(sc.MatchIgnoreCase(\".and.\") || sc.MatchIgnoreCase(\".not.\"))) {\n\t\t\t\tsc.SetState(SCE_FS_WORDOPERATOR);\n\t\t\t\tsc.Forward(4);\n\t\t\t} else if (bEnableCode && sc.MatchIgnoreCase(\".or.\")) {\n\t\t\t\tsc.SetState(SCE_FS_WORDOPERATOR);\n\t\t\t\tsc.Forward(3);\n\t\t\t} else if (bEnableCode &&\n\t\t\t\t\t(sc.MatchIgnoreCase(\".t.\") || sc.MatchIgnoreCase(\".f.\") ||\n\t\t\t\t\t(!IsAWordChar(sc.GetRelative(3)) && sc.MatchIgnoreCase(\"nil\")))) {\n\t\t\t\tsc.SetState(SCE_FS_CONSTANT);\n\t\t\t\tsc.Forward(2);\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (bEnableCode && sc.Match('&', '&')) {\n\t\t\t\tsc.SetState(SCE_FS_COMMENTLINE);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (bEnableCode && sc.ch == '*' && visibleChars == 0) {\n\t\t\t\tsc.SetState(SCE_FS_COMMENT);\n\t\t\t} else if (sc.ch == '\\\"' || sc.ch == '\\'') {\n\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);\n\t\t\t\tcloseStringChar = sc.ch;\n\t\t\t} else if (closeStringChar == '>' && sc.ch == '<') {\n\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);\n\t\t\t} else if (sc.ch == '#' && visibleChars == 0) {\n\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);\n\t\t\t\tdo {\t// Skip whitespace between # and preprocessor word\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} while (IsASpaceOrTab(sc.ch) && sc.More());\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);\n\t\t\t\t} else if (sc.MatchIgnoreCase(\"include\")) {\n\t\t\t\t\tif (stylingWithinPreprocessor) {\n\t\t\t\t\t\tcloseStringChar = '>';\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.MatchIgnoreCase(\"pragma\")) {\n\t\t\t\t\tsc.Forward(6);\n\t\t\t\t\tdo {\t// Skip more whitespace until keyword\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} while (IsASpaceOrTab(sc.ch) && sc.More());\n\t\t\t\t\tif (sc.MatchIgnoreCase(\"begindump\") || sc.MatchIgnoreCase(\"__cstream\")) {\n\t\t\t\t\t\tbEnableCode = false;\n\t\t\t\t\t\tif (stylingWithinPreprocessor) {\n\t\t\t\t\t\t\tsc.SetState(SCE_FS_DISABLEDCODE);\n\t\t\t\t\t\t\tsc.Forward(8);\n\t\t\t\t\t\t\tsc.ForwardSetState(SCE_FS_DEFAULT_C);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState(SCE_FS_DISABLEDCODE);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (sc.MatchIgnoreCase(\"enddump\") || sc.MatchIgnoreCase(\"__endtext\")) {\n\t\t\t\t\t\tbEnableCode = true;\n\t\t\t\t\t\tsc.SetState(SCE_FS_DISABLEDCODE);\n\t\t\t\t\t\tsc.Forward(sc.ch == '_' ? 8 : 6);\n\t\t\t\t\t\tsc.ForwardSetState(SCE_FS_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (bEnableCode && sc.ch == '{') {\n\t\t\t\tSci_Position p = 0;\n\t\t\t\tint chSeek;\n\t\t\t\tSci_PositionU endPos(startPos + length);\n\t\t\t\tdo {\t// Skip whitespace\n\t\t\t\t\tchSeek = sc.GetRelative(++p);\n\t\t\t\t} while (IsASpaceOrTab(chSeek) && (sc.currentPos + p < endPos));\n\t\t\t\tif (chSeek == '^') {\n\t\t\t\t\tsc.SetState(SCE_FS_DATE);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_FS_OPERATOR);\n\t\t\t\t}\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_NUMBER : SCE_FS_NUMBER_C);\n\t\t\t} else if (IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_IDENTIFIER : SCE_FS_IDENTIFIER_C);\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch)) || (bEnableCode && sc.ch == '@')) {\n\t\t\t\tsc.SetState(bEnableCode ? SCE_FS_OPERATOR : SCE_FS_OPERATOR_C);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\tvisibleChars = 0;\n\t\t\tcloseStringChar = 0;\n\t\t}\n\t\tif (!IsASpace(sc.ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void FoldFlagShipDoc(Sci_PositionU startPos, Sci_Position length, int,\n\t\t\t\t\t\t\t\t\tWordList *[], Accessor &styler)\n{\n\n\tSci_Position endPos = startPos + length;\n\n\t// Backtrack to previous line in case need to fix its fold status\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (startPos > 0 && lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t}\n\tint spaceFlags = 0;\n\tint indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);\n\tchar chNext = styler[startPos];\n\tfor (Sci_Position i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n') || (i == endPos-1)) {\n\t\t\tint lev = indentCurrent;\n\t\t\tint indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);\n\t\t\tif (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n\t\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {\n\t\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {\n\t\t\t\t\tint spaceFlags2 = 0;\n\t\t\t\t\tint indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2);\n\t\t\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {\n\t\t\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tindentCurrent = indentNext;\n\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\tlineCurrent++;\n\t\t}\n\t}\n}\n\nstatic const char * const FSWordListDesc[] = {\n\t\"Keywords Commands\",\n\t\"Std Library Functions\",\n\t\"Procedure, return, exit\",\n\t\"Class (oop)\",\n\t\"Doxygen keywords\",\n\t0\n};\n\nextern const LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, \"flagship\", FoldFlagShipDoc, FSWordListDesc);\n"
  },
  {
    "path": "lexers/LexForth.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexForth.cxx\n ** Lexer for FORTH\n **/\n// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordStart(int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) ||\n\t\t// symbolic standard words and word prefixes (https://forth-standard.org/standard/core)\n\t\tAnyOf(ch, '!', '#', '\\'', '(', '*', '+', ',', '-', '.', '/', '<', '=', '>', '?', '@', '[', '\\\\', ']', '_'));\n}\n\nstatic inline bool IsANumChar(int ch) {\n\treturn (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );\n}\n\nstatic inline bool IsASpaceChar(int ch) {\n\treturn (ch < 0x80) && isspace(ch);\n}\n\nstatic void ColouriseForthDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordLists[],\n                            Accessor &styler) {\n\n    WordList &control = *keywordLists[0];\n    WordList &keyword = *keywordLists[1];\n    WordList &defword = *keywordLists[2];\n    WordList &preword1 = *keywordLists[3];\n    WordList &preword2 = *keywordLists[4];\n    WordList &strings = *keywordLists[5];\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward())\n\t{\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_FORTH_COMMENT) {\n\t\t\tif (sc.MatchLineEnd()) {\n\t\t\t\tsc.SetState(SCE_FORTH_DEFAULT);\n\t\t\t}\n\t\t}else if (sc.state == SCE_FORTH_COMMENT_ML) {\n\t\t\tif (sc.ch == ')') {\n\t\t\t\tsc.ForwardSetState(SCE_FORTH_DEFAULT);\n\t\t\t}\n\t\t}else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {\n\t\t\t// handle numbers here too, because what we thought was a number might\n\t\t\t// turn out to be a keyword e.g. 2DUP\n\t\t\tif (IsASpaceChar(sc.ch) ) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tint newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;\n\t\t\t\tif (control.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_FORTH_CONTROL);\n\t\t\t\t} else if (keyword.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_FORTH_KEYWORD);\n\t\t\t\t} else if (defword.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_FORTH_DEFWORD);\n\t\t\t\t}  else if (preword1.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_FORTH_PREWORD1);\n\t\t\t\t} else if (preword2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_FORTH_PREWORD2);\n\t\t\t\t} else if (strings.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_FORTH_STRING);\n\t\t\t\t\tnewState = SCE_FORTH_STRING;\n\t\t\t\t}\n\t\t\t\tsc.SetState(newState);\n\t\t\t}\n\t\t\tif (sc.state == SCE_FORTH_NUMBER) {\n\t\t\t\tif (IsASpaceChar(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_FORTH_DEFAULT);\n\t\t\t\t} else if (!IsANumChar(sc.ch)) {\n\t\t\t\t\tsc.ChangeState(SCE_FORTH_IDENTIFIER);\n\t\t\t\t}\n\t\t\t}\n\t\t}else if (sc.state == SCE_FORTH_STRING) {\n\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_FORTH_DEFAULT);\n\t\t\t}\n\t\t}else if (sc.state == SCE_FORTH_LOCALE) {\n\t\t\tif (sc.ch == '}') {\n\t\t\t\tsc.ForwardSetState(SCE_FORTH_DEFAULT);\n\t\t\t}\n\t\t}else if (sc.state == SCE_FORTH_DEFWORD) {\n\t\t\tif (IsASpaceChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_FORTH_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_FORTH_DEFAULT) {\n\t\t\tif (sc.ch == '\\\\' && (sc.atLineStart || IsASpaceChar(sc.chPrev)) && IsASpaceChar(sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_FORTH_COMMENT);\n\t\t\t} else if (sc.ch == '(' &&\n\t\t\t\t\t(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&\n\t\t\t\t\t(sc.MatchLineEnd()   || IsASpaceChar(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_FORTH_COMMENT_ML);\n\t\t\t} else if (\t(sc.ch == '$' && (IsASCII(sc.chNext) && isxdigit(sc.chNext))) ) {\n\t\t\t\t// number starting with $ is a hex number\n\t\t\t\tsc.SetState(SCE_FORTH_NUMBER);\n\t\t\t\twhile(sc.More() && IsASCII(sc.chNext) && isxdigit(sc.chNext))\n\t\t\t\t\tsc.Forward();\n\t\t\t} else if ( (sc.ch == '%' && (IsASCII(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {\n\t\t\t\t// number starting with % is binary\n\t\t\t\tsc.SetState(SCE_FORTH_NUMBER);\n\t\t\t\twhile(sc.More() && IsASCII(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))\n\t\t\t\t\tsc.Forward();\n\t\t\t} else if (\tIsASCII(sc.ch) &&\n\t\t\t\t\t\t(isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && IsASCII(sc.chNext) && isxdigit(sc.chNext)) )\n\t\t\t\t\t){\n\t\t\t\tsc.SetState(SCE_FORTH_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_FORTH_IDENTIFIER);\n\t\t\t} else if (sc.ch == '{') {\n\t\t\t\tsc.SetState(SCE_FORTH_LOCALE);\n\t\t\t} else if (sc.ch == ':' && IsASCII(sc.chNext) && isspace(sc.chNext)) {\n\t\t\t\t// highlight word definitions e.g.  : GCD ( n n -- n ) ..... ;\n\t\t\t\t//                                  ^ ^^^\n\t\t\t\tsc.SetState(SCE_FORTH_DEFWORD);\n\t\t\t\twhile(sc.More() && IsASCII(sc.chNext) && isspace(sc.chNext))\n\t\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == ';' &&\n\t\t\t\t\t(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&\n\t\t\t\t\t(sc.MatchLineEnd()   || IsASpaceChar(sc.chNext))\t) {\n\t\t\t\t// mark the ';' that ends a word\n\t\t\t\tsc.SetState(SCE_FORTH_DEFWORD);\n\t\t\t\tsc.ForwardSetState(SCE_FORTH_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t}\n\tsc.Complete();\n}\n\nstatic void FoldForthDoc(Sci_PositionU, Sci_Position, int, WordList *[],\n\t\t\t\t\t\tAccessor &) {\n}\n\nstatic const char * const forthWordLists[] = {\n\t\t\t\"control keywords\",\n\t\t\t\"keywords\",\n\t\t\t\"definition words\",\n\t\t\t\"prewords with one argument\",\n\t\t\t\"prewords with two arguments\",\n\t\t\t\"string definition keywords\",\n\t\t\t0,\n\t\t};\n\nextern const LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, \"forth\", FoldForthDoc, forthWordLists);\n\n\n"
  },
  {
    "path": "lexers/LexFortran.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexFortran.cxx\n ** Lexer for Fortran.\n ** Written by Chuan-jian Shen, Last changed Sep. 2003\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n/***************************************/\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n/***************************************/\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n/***************************************/\n\nusing namespace Lexilla;\n\n/***********************************************/\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');\n}\n/**********************************************/\nstatic inline bool IsAWordStart(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch));\n}\n/***************************************/\nstatic inline bool IsABlank(unsigned int ch) {\n\treturn (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;\n}\n/***************************************/\nstatic inline bool IsALineEnd(char ch) {\n\treturn ((ch == '\\n') || (ch == '\\r')) ;\n}\n/***************************************/\nstatic Sci_PositionU GetContinuedPos(Sci_PositionU pos, Accessor &styler) {\n\twhile (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue;\n\tif (styler.SafeGetCharAt(pos) == '\\n') pos++;\n\twhile (IsABlank(styler.SafeGetCharAt(pos++))) continue;\n\tchar chCur = styler.SafeGetCharAt(pos);\n\tif (chCur == '&') {\n\t\twhile (IsABlank(styler.SafeGetCharAt(++pos))) continue;\n\t\treturn pos;\n\t} else {\n\t\treturn pos;\n\t}\n}\n/***************************************/\nstatic void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n        WordList *keywordlists[], Accessor &styler, bool isFixFormat) {\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\t/***************************************/\n\tSci_Position posLineStart = 0;\n\tint numNonBlank = 0, prevState = 0;\n\tSci_Position endPos = startPos + length;\n\t/***************************************/\n\t// backtrack to the nearest keyword\n\twhile ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) {\n\t\tstartPos--;\n\t}\n\tstartPos = styler.LineStart(styler.GetLine(startPos));\n\tinitStyle = styler.StyleAt(startPos - 1);\n\tStyleContext sc(startPos, endPos-startPos, initStyle, styler);\n\t/***************************************/\n\tfor (; sc.More(); sc.Forward()) {\n\t\t// remember the start position of the line\n\t\tif (sc.atLineStart) {\n\t\t\tposLineStart = sc.currentPos;\n\t\t\tnumNonBlank = 0;\n\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t}\n\t\tif (!IsASpaceOrTab(sc.ch)) numNonBlank ++;\n\t\t/***********************************************/\n\t\t// Handle the fix format generically\n\t\tSci_Position toLineStart = sc.currentPos - posLineStart;\n\t\tif (isFixFormat && (toLineStart < 6 || toLineStart >= 72)) {\n\t\t\tif ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {\n\t\t\t\tif (sc.MatchIgnoreCase(\"cdec$\") || sc.MatchIgnoreCase(\"*dec$\") || sc.MatchIgnoreCase(\"!dec$\") ||\n\t\t\t\t        sc.MatchIgnoreCase(\"cdir$\") || sc.MatchIgnoreCase(\"*dir$\") || sc.MatchIgnoreCase(\"!dir$\") ||\n\t\t\t\t        sc.MatchIgnoreCase(\"cms$\")  || sc.MatchIgnoreCase(\"*ms$\")  || sc.MatchIgnoreCase(\"!ms$\")  ||\n\t\t\t\t        sc.chNext == '$') {\n\t\t\t\t\tsc.SetState(SCE_F_PREPROCESSOR);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_F_COMMENT);\n\t\t\t\t}\n\n\t\t\t\twhile (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end\n\t\t\t} else if (toLineStart >= 72) {\n\t\t\t\tsc.SetState(SCE_F_COMMENT);\n\t\t\t\twhile (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end\n\t\t\t} else if (toLineStart < 5) {\n\t\t\t\tif (IsADigit(sc.ch))\n\t\t\t\t\tsc.SetState(SCE_F_LABEL);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t\t} else if (toLineStart == 5) {\n\t\t\t\t//if (!IsASpace(sc.ch) && sc.ch != '0') {\n\t\t\t\tif (sc.ch != '\\r' && sc.ch != '\\n') {\n\t\t\t\t\tsc.SetState(SCE_F_CONTINUATION);\n\t\t\t\t\tif (!IsASpace(sc.ch) && sc.ch != '0')\n\t\t\t\t\t\tsc.ForwardSetState(prevState);\n\t\t\t\t} else\n\t\t\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\t/***************************************/\n\t\t// Handle line continuation generically.\n\t\tif (!isFixFormat && sc.ch == '&' && sc.state != SCE_F_COMMENT) {\n\t\t\tchar chTemp = ' ';\n\t\t\tSci_Position j = 1;\n\t\t\twhile (IsABlank(chTemp) && j<132) {\n\t\t\t\tchTemp = static_cast<char>(sc.GetRelative(j));\n\t\t\t\tj++;\n\t\t\t}\n\t\t\tif (chTemp == '!') {\n\t\t\t\tsc.SetState(SCE_F_CONTINUATION);\n\t\t\t\tif (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT);\n\t\t\t} else if (chTemp == '\\r' || chTemp == '\\n') {\n\t\t\t\tint currentState = sc.state;\n\t\t\t\tsc.SetState(SCE_F_CONTINUATION);\n\t\t\t\tsc.ForwardSetState(SCE_F_DEFAULT);\n\t\t\t\twhile (IsASpace(sc.ch) && sc.More()) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tif (sc.atLineStart) numNonBlank = 0;\n\t\t\t\t\tif (!IsASpaceOrTab(sc.ch)) numNonBlank ++;\n\t\t\t\t}\n\t\t\t\tif (sc.ch == '&') {\n\t\t\t\t\tsc.SetState(SCE_F_CONTINUATION);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.SetState(currentState);\n\t\t\t}\n\t\t}\n\t\t/***************************************/\n\t\t// Hanndle preprocessor directives\n\t\tif (sc.ch == '#' && numNonBlank == 1)\n\t\t{\n\t\t\tsc.SetState(SCE_F_PREPROCESSOR);\n\t\t\twhile (!sc.atLineEnd && sc.More())\n\t\t\t\tsc.Forward(); // Until line end\n\t\t}\n\t\t/***************************************/\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_F_OPERATOR) {\n\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t} else if (sc.state == SCE_F_NUMBER) {\n\t\t\tif (!(IsAWordChar(sc.ch) || sc.ch=='\\'' || sc.ch=='\\\"' || sc.ch=='.')) {\n\t\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_F_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch) || (sc.ch == '%')) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_F_WORD);\n\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_F_WORD2);\n\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_F_WORD3);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_F_COMMENT || sc.state == SCE_F_PREPROCESSOR) {\n\t\t\tif (sc.ch == '\\r' || sc.ch == '\\n') {\n\t\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_F_STRING1) {\n\t\t\tprevState = sc.state;\n\t\t\tif (sc.ch == '\\'') {\n\t\t\t\tif (sc.chNext == '\\'') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tsc.ForwardSetState(SCE_F_DEFAULT);\n\t\t\t\t\tprevState = SCE_F_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_F_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_F_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_F_STRING2) {\n\t\t\tprevState = sc.state;\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_F_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_F_DEFAULT);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tif (sc.chNext == '\\\"') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tsc.ForwardSetState(SCE_F_DEFAULT);\n\t\t\t\t\tprevState = SCE_F_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (sc.state == SCE_F_OPERATOR2) {\n\t\t\tif (sc.ch == '.') {\n\t\t\t\tsc.ForwardSetState(SCE_F_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_F_CONTINUATION) {\n\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t} else if (sc.state == SCE_F_LABEL) {\n\t\t\tif (!IsADigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t\t} else {\n\t\t\t\tif (isFixFormat && sc.currentPos-posLineStart > 4)\n\t\t\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t\t\telse if (numNonBlank > 5)\n\t\t\t\t\tsc.SetState(SCE_F_DEFAULT);\n\t\t\t}\n\t\t}\n\t\t/***************************************/\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_F_DEFAULT) {\n\t\t\tif (sc.ch == '!') {\n\t\t\t\tif (sc.MatchIgnoreCase(\"!dec$\") || sc.MatchIgnoreCase(\"!dir$\") ||\n\t\t\t\t\tsc.MatchIgnoreCase(\"!ms$\") || sc.chNext == '$') {\n\t\t\t\t\tsc.SetState(SCE_F_PREPROCESSOR);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_F_COMMENT);\n\t\t\t\t}\n\t\t\t} else if ((!isFixFormat) && IsADigit(sc.ch) && numNonBlank == 1) {\n\t\t\t\tsc.SetState(SCE_F_LABEL);\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_F_NUMBER);\n\t\t\t} else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' ||\n\t\t\t\ttolower(sc.ch) == 'z') && (sc.chNext == '\\\"' || sc.chNext == '\\'')) {\n\t\t\t\tsc.SetState(SCE_F_NUMBER);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '.' && isalpha(sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_F_OPERATOR2);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_F_IDENTIFIER);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_F_STRING2);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_F_STRING1);\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_F_OPERATOR);\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n/***************************************/\nstatic void CheckLevelCommentLine(const unsigned int nComL,\n\t\t\t\t  Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position &nComCur,\n\t\t\t\t  bool comLineB[], bool comLineF[], bool &comLineCur,\n\t\t\t\t  int &levelDeltaNext) {\n\tlevelDeltaNext = 0;\n\tif (!comLineCur) {\n\t\treturn;\n\t}\n\n\tif (!comLineF[0] || nComColF[0] != nComCur) {\n\t\tunsigned int i=0;\n\t\tfor (; i<nComL; i++) {\n\t\t\tif (!comLineB[i] || nComColB[i] != nComCur) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (i == nComL) {\n\t\t\tlevelDeltaNext = -1;\n\t\t}\n\t}\n\telse if (!comLineB[0] || nComColB[0] != nComCur) {\n\t\tunsigned int i=0;\n\t\tfor (; i<nComL; i++) {\n\t\t\tif (!comLineF[i] || nComColF[i] != nComCur) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (i == nComL) {\n\t\t\tlevelDeltaNext = 1;\n\t\t}\n\t}\n}\n/***************************************/\nstatic void GetIfLineComment(Accessor &styler, bool isFixFormat, const Sci_Position line, bool &isComLine, Sci_Position &comCol) {\n\tSci_Position col = 0;\n\tisComLine = false;\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position len = styler.Length();\n\twhile(pos<len) {\n\t\tchar ch = styler.SafeGetCharAt(pos);\n\t\tif (ch == '!' || (isFixFormat && col == 0 && (tolower(ch) == 'c' || ch == '*'))) {\n\t\t\tisComLine = true;\n\t\t\tcomCol = col;\n\t\t\tbreak;\n\t\t}\n\t\telse if (!IsABlank(ch) || IsALineEnd(ch)) {\n\t\t\tbreak;\n\t\t}\n\t\tpos++;\n\t\tcol++;\n\t}\n}\n/***************************************/\nstatic void StepCommentLine(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,\n\t\t\t\t  Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position &nComCur,\n\t\t\t\t  bool comLineB[], bool comLineF[], bool &comLineCur) {\n\tSci_Position nLineTotal = styler.GetLine(styler.Length()-1) + 1;\n\tif (lineCurrent >= nLineTotal) {\n\t\treturn;\n\t}\n\n\tfor (int i=nComL-2; i>=0; i--) {\n\t\tnComColB[i+1] = nComColB[i];\n\t\tcomLineB[i+1] = comLineB[i];\n\t}\n\tnComColB[0] = nComCur;\n\tcomLineB[0] = comLineCur;\n\tnComCur = nComColF[0];\n\tcomLineCur = comLineF[0];\n\tfor (unsigned int i=0; i+1<nComL; i++) {\n\t\tnComColF[i] = nComColF[i+1];\n\t\tcomLineF[i] = comLineF[i+1];\n\t}\n\tSci_Position chL = lineCurrent + nComL;\n\tif (chL < nLineTotal) {\n\t\tGetIfLineComment(styler, isFixFormat, chL, comLineF[nComL-1], nComColF[nComL-1]);\n\t}\n\telse {\n\t\tcomLineF[nComL-1] = false;\n\t}\n}\n/***************************************/\nstatic void CheckBackComLines(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,\n\t\t\t\t  Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position nComCur,\n\t\t\t\t  bool comLineB[], bool comLineF[], bool &comLineCur) {\n\tunsigned int nLines = nComL + nComL + 1;\n\tbool* comL = new bool[nLines];\n\tSci_Position* nComCol = new Sci_Position[nLines];\n\tbool comL0;\n\tSci_Position nComCol0;\n\tGetIfLineComment(styler, isFixFormat, lineCurrent-nComL-1, comL0, nComCol0);\n\tfor (unsigned int i=0; i<nComL; i++) {\n\t\tunsigned copyTo = nComL - i - 1;\n\t\tcomL[copyTo]    = comLineB[i];\n\t\tnComCol[copyTo] = nComColB[i];\n\t}\n\tassert(nComL < nLines);\n\tcomL[nComL] = comLineCur;\n\tnComCol[nComL] = nComCur;\n\tfor (unsigned int i=0; i<nComL; i++) {\n\t\tunsigned copyTo = i + nComL + 1;\n\t\tcomL[copyTo]    = comLineF[i];\n\t\tnComCol[copyTo] = nComColF[i];\n\t}\n\t\n\tSci_Position lineC = lineCurrent - nComL + 1;\n\tSci_PositionU iStart;\n\tif (lineC <= 0) {\n\t\tlineC = 0;\n\t\tiStart = nComL - lineCurrent;\n\t}\n\telse {\n\t\tiStart = 1;\n\t}\n\tbool levChanged = false;\n\tint lev = styler.LevelAt(lineC) & SC_FOLDLEVELNUMBERMASK;\n\t\n\tfor (Sci_PositionU i=iStart; i<=nComL; i++) {\n\t\tif (comL[i] && (!comL[i-1] || nComCol[i] != nComCol[i-1])) {\n\t\t\tbool increase = true;\n\t\t\tSci_PositionU until = i + nComL;\n\t\t\tfor (Sci_PositionU j=i+1; j<=until; j++) {\n\t\t\t\tif (!comL[j] || nComCol[j] != nComCol[i]) {\n\t\t\t\t\tincrease = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlev = styler.LevelAt(lineC) & SC_FOLDLEVELNUMBERMASK;\n\t\t\tif (increase) {\n\t\t\t\tint levH = lev | SC_FOLDLEVELHEADERFLAG;\n\t\t\t\tlev += 1;\n\t\t\t\tif (levH != styler.LevelAt(lineC)) {\n\t\t\t\t\tstyler.SetLevel(lineC, levH);\n\t\t\t\t}\n\t\t\t\tfor (Sci_Position j=lineC+1; j<=lineCurrent; j++) {\n\t\t\t\t\tif (lev != styler.LevelAt(j)) {\n\t\t\t\t\t\tstyler.SetLevel(j, lev);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (lev != styler.LevelAt(lineC)) {\n\t\t\t\t\tstyler.SetLevel(lineC, lev);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlevChanged = true;\n\t\t}\n\t\telse if (levChanged && comL[i]) {\n\t\t\tif (lev != styler.LevelAt(lineC)) {\n\t\t\t\tstyler.SetLevel(lineC, lev);\n\t\t\t}\n\t\t}\n\t\tlineC++;\n\t}\n\tdelete[] comL;\n\tdelete[] nComCol;\n}\n/***************************************/\n// To determine the folding level depending on keywords\nstatic int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {\n\tint lev = 0;\n\n\tif ((strcmp(prevWord, \"module\") == 0 && strcmp(s, \"subroutine\") == 0)\n\t\t|| (strcmp(prevWord, \"module\") == 0 && strcmp(s, \"function\") == 0)) {\n\t\tlev = 0;\n\t} else if (strcmp(s, \"associate\") == 0 || strcmp(s, \"block\") == 0\n\t        || strcmp(s, \"blockdata\") == 0 || strcmp(s, \"select\") == 0\n\t        || strcmp(s, \"selecttype\") == 0 || strcmp(s, \"selectcase\") == 0\n\t        || strcmp(s, \"do\") == 0 || strcmp(s, \"enum\") ==0\n\t        || strcmp(s, \"function\") == 0 || strcmp(s, \"interface\") == 0\n\t        || strcmp(s, \"module\") == 0 || strcmp(s, \"program\") == 0\n\t        || strcmp(s, \"subroutine\") == 0 || strcmp(s, \"then\") == 0\n\t        || (strcmp(s, \"type\") == 0 && chNextNonBlank != '(')\n\t\t|| strcmp(s, \"critical\") == 0 || strcmp(s, \"submodule\") == 0){\n\t\tif (strcmp(prevWord, \"end\") == 0)\n\t\t\tlev = 0;\n\t\telse\n\t\t\tlev = 1;\n\t} else if ((strcmp(s, \"end\") == 0 && chNextNonBlank != '=')\n\t        || strcmp(s, \"endassociate\") == 0 || strcmp(s, \"endblock\") == 0\n\t        || strcmp(s, \"endblockdata\") == 0 || strcmp(s, \"endselect\") == 0\n\t        || strcmp(s, \"enddo\") == 0 || strcmp(s, \"endenum\") ==0\n\t        || strcmp(s, \"endif\") == 0 || strcmp(s, \"endforall\") == 0\n\t        || strcmp(s, \"endfunction\") == 0 || strcmp(s, \"endinterface\") == 0\n\t        || strcmp(s, \"endmodule\") == 0 || strcmp(s, \"endprogram\") == 0\n\t        || strcmp(s, \"endsubroutine\") == 0 || strcmp(s, \"endtype\") == 0\n\t        || strcmp(s, \"endwhere\") == 0 || strcmp(s, \"endcritical\") == 0\n\t\t|| (strcmp(prevWord, \"module\") == 0 && strcmp(s, \"procedure\") == 0)  // Take care of the \"module procedure\" statement\n\t\t|| strcmp(s, \"endsubmodule\") == 0 || strcmp(s, \"endteam\") == 0) {\n\t\tlev = -1;\n\t} else if (strcmp(prevWord, \"end\") == 0 && strcmp(s, \"if\") == 0){ // end if\n\t\tlev = 0;\n\t} else if (strcmp(prevWord, \"type\") == 0 && strcmp(s, \"is\") == 0){ // type is\n\t\tlev = -1;\n\t} else if ((strcmp(prevWord, \"end\") == 0 && strcmp(s, \"procedure\") == 0)\n\t\t\t   || strcmp(s, \"endprocedure\") == 0) {\n\t\t\tlev = 1; // level back to 0, because no folding support for \"module procedure\" in submodule\n\t} else if (strcmp(prevWord, \"change\") == 0 && strcmp(s, \"team\") == 0){ // change team\n\t\tlev = 1;\n\t}\n\treturn lev;\n}\n/***************************************/\n// Folding the code\nstatic void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n        Accessor &styler, bool isFixFormat) {\n\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\", 1) != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tbool isPrevLine;\n\tif (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tstartPos = styler.LineStart(lineCurrent);\n\t\tisPrevLine = true;\n\t} else {\n\t\tisPrevLine = false;\n\t}\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tint levelDeltaNext = 0;\n\n\tconst unsigned int nComL = 3; // defines how many comment lines should be before they are folded\n\tSci_Position nComColB[nComL] = {};\n\tSci_Position nComColF[nComL] = {};\n\tSci_Position nComCur = 0;\n\tbool comLineB[nComL] = {};\n\tbool comLineF[nComL] = {};\n\tbool comLineCur;\n\tSci_Position nLineTotal = styler.GetLine(styler.Length()-1) + 1;\n\tif (foldComment) {\n\t\tfor (unsigned int i=0; i<nComL; i++) {\n\t\t\tSci_Position chL = lineCurrent-(i+1);\n\t\t\tif (chL < 0) {\n\t\t\t\tcomLineB[i] = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tGetIfLineComment(styler, isFixFormat, chL, comLineB[i], nComColB[i]);\n\t\t\tif (!comLineB[i]) {\n\t\t\t\tfor (unsigned int j=i+1; j<nComL; j++) {\n\t\t\t\t\tcomLineB[j] = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfor (unsigned int i=0; i<nComL; i++) {\n\t\t\tSci_Position chL = lineCurrent+i+1;\n\t\t\tif (chL >= nLineTotal) {\n\t\t\t\tcomLineF[i] = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tGetIfLineComment(styler, isFixFormat, chL, comLineF[i], nComColF[i]);\n\t\t}\n\t\tGetIfLineComment(styler, isFixFormat, lineCurrent, comLineCur, nComCur);\n\t\tCheckBackComLines(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur, \n\t\t\t\tcomLineB, comLineF, comLineCur);\n\t}\n\tint levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\n\t/***************************************/\n\tSci_Position lastStart = 0;\n\tchar prevWord[32] = \"\";\n\t/***************************************/\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tchar chNextNonBlank = chNext;\n\t\tbool nextEOL = false;\n\t\tif (IsALineEnd(chNextNonBlank)) {\n\t\t\tnextEOL = true;\n\t\t}\n\t\tSci_PositionU j=i+1;\n\t\twhile(IsABlank(chNextNonBlank) && j<endPos) {\n\t\t\tj ++ ;\n\t\t\tchNextNonBlank = styler.SafeGetCharAt(j);\n\t\t\tif (IsALineEnd(chNextNonBlank)) {\n\t\t\t\tnextEOL = true;\n\t\t\t}\n\t\t}\n\t\tif (!nextEOL && j == endPos) {\n\t\t\tnextEOL = true;\n\t\t}\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\t//\n\t\tif (((isFixFormat && stylePrev == SCE_F_CONTINUATION) || stylePrev == SCE_F_DEFAULT\n\t\t\t|| stylePrev == SCE_F_OPERATOR) && (style == SCE_F_WORD || style == SCE_F_LABEL)) {\n\t\t\t// Store last word and label start point.\n\t\t\tlastStart = i;\n\t\t}\n\t\t/***************************************/\n\t\tif (style == SCE_F_WORD) {\n\t\t\tif(iswordchar(ch) && !iswordchar(chNext)) {\n\t\t\t\tchar s[32];\n\t\t\t\tSci_PositionU k;\n\t\t\t\tfor(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {\n\t\t\t\t\ts[k] = static_cast<char>(tolower(styler[lastStart+k]));\n\t\t\t\t}\n\t\t\t\ts[k] = '\\0';\n\t\t\t\t// Handle the forall and where statement and structure.\n\t\t\t\tif (strcmp(s, \"forall\") == 0 || (strcmp(s, \"where\") == 0 && strcmp(prevWord, \"else\") != 0)) {\n\t\t\t\t\tif (strcmp(prevWord, \"end\") != 0) {\n\t\t\t\t\t\tj = i + 1;\n\t\t\t\t\t\tchar chBrace = '(', chSeek = ')', ch1 = styler.SafeGetCharAt(j);\n\t\t\t\t\t\t// Find the position of the first (\n\t\t\t\t\t\twhile (ch1 != chBrace && j<endPos) {\n\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\tch1 = styler.SafeGetCharAt(j);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchar styBrace = styler.StyleAt(j);\n\t\t\t\t\t\tint depth = 1;\n\t\t\t\t\t\tchar chAtPos;\n\t\t\t\t\t\tchar styAtPos;\n\t\t\t\t\t\twhile (j<endPos) {\n\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\tchAtPos = styler.SafeGetCharAt(j);\n\t\t\t\t\t\t\tstyAtPos = styler.StyleAt(j);\n\t\t\t\t\t\t\tif (styAtPos == styBrace) {\n\t\t\t\t\t\t\t\tif (chAtPos == chBrace) depth++;\n\t\t\t\t\t\t\t\tif (chAtPos == chSeek) depth--;\n\t\t\t\t\t\t\t\tif (depth == 0) break;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tSci_Position tmpLineCurrent = lineCurrent;\n\t\t\t\t\t\twhile (j<endPos) {\n\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t\tchAtPos = styler.SafeGetCharAt(j);\n\t\t\t\t\t\t\tstyAtPos = styler.StyleAt(j);\n\t\t\t\t\t\t\tif (!IsALineEnd(chAtPos) && (styAtPos == SCE_F_COMMENT || IsABlank(chAtPos))) continue;\n\t\t\t\t\t\t\tif (isFixFormat) {\n\t\t\t\t\t\t\t\tif (!IsALineEnd(chAtPos)) {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tif (tmpLineCurrent < styler.GetLine(styler.Length()-1)) {\n\t\t\t\t\t\t\t\t\t\ttmpLineCurrent++;\n\t\t\t\t\t\t\t\t\t\tj = styler.LineStart(tmpLineCurrent);\n\t\t\t\t\t\t\t\t\t\tif (styler.StyleAt(j+5) == SCE_F_CONTINUATION\n\t\t\t\t\t\t\t\t\t\t\t&& !IsABlank(styler.SafeGetCharAt(j+5)) && styler.SafeGetCharAt(j+5) != '0') {\n\t\t\t\t\t\t\t\t\t\t\tj += 5;\n\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tlevelDeltaNext++;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (chAtPos == '&' && styler.StyleAt(j) == SCE_F_CONTINUATION) {\n\t\t\t\t\t\t\t\t\tj = GetContinuedPos(j+1, styler);\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t} else if (IsALineEnd(chAtPos)) {\n\t\t\t\t\t\t\t\t\tlevelDeltaNext++;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tint wordLevelDelta = classifyFoldPointFortran(s, prevWord, chNextNonBlank);\n\t\t\t\t\tlevelDeltaNext += wordLevelDelta;\n\t\t\t\t\tif (((strcmp(s, \"else\") == 0) && (nextEOL || chNextNonBlank == '!')) ||\n\t\t\t\t\t\t(strcmp(prevWord, \"else\") == 0 && strcmp(s, \"where\") == 0) || strcmp(s, \"elsewhere\") == 0) {\n\t\t\t\t\t\tif (!isPrevLine) {\n\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlevelDeltaNext++;\n\t\t\t\t\t} else if ((strcmp(prevWord, \"else\") == 0 && strcmp(s, \"if\") == 0) || strcmp(s, \"elseif\") == 0) {\n\t\t\t\t\t\tif (!isPrevLine) {\n\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if ((strcmp(prevWord, \"select\") == 0 && strcmp(s, \"case\") == 0) || strcmp(s, \"selectcase\") == 0 ||\n\t\t\t\t\t\t\t   (strcmp(prevWord, \"select\") == 0 && strcmp(s, \"type\") == 0) || strcmp(s, \"selecttype\") == 0) {\n\t\t\t\t\t\tlevelDeltaNext += 2;\n\t\t\t\t\t} else if ((strcmp(s, \"case\") == 0 && chNextNonBlank == '(') || (strcmp(prevWord, \"case\") == 0 && strcmp(s, \"default\") == 0) ||\n\t\t\t\t\t\t\t   (strcmp(prevWord, \"type\") == 0 && strcmp(s, \"is\") == 0) ||\n\t\t\t\t\t\t\t   (strcmp(prevWord, \"class\") == 0 && strcmp(s, \"is\") == 0) ||\n\t\t\t\t\t\t\t   (strcmp(prevWord, \"class\") == 0 && strcmp(s, \"default\") == 0) ) {\n\t\t\t\t\t\tif (!isPrevLine) {\n\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlevelDeltaNext++;\n\t\t\t\t\t} else if ((strcmp(prevWord, \"end\") == 0 && strcmp(s, \"select\") == 0) || strcmp(s, \"endselect\") == 0) {\n\t\t\t\t\t\tlevelDeltaNext -= 2;\n\t\t\t\t\t}\n\n\t\t\t\t\t// There are multiple forms of \"do\" loop. The older form with a label \"do 100 i=1,10\" would require matching\n\t\t\t\t\t// labels to ensure the folding level does not decrease too far when labels are used for other purposes.\n\t\t\t\t\t// Since this is difficult, do-label constructs are not folded.\n\t\t\t\t\tif (strcmp(s, \"do\") == 0 && IsADigit(chNextNonBlank)) {\n\t\t\t\t\t\t// Remove delta for do-label\n\t\t\t\t\t\tlevelDeltaNext -= wordLevelDelta;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstrcpy(prevWord, s);\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tif (foldComment) {\n\t\t\t\tint ldNext;\n\t\t\t\tCheckLevelCommentLine(nComL, nComColB, nComColF, nComCur, comLineB, comLineF, comLineCur, ldNext);\n\t\t\t\tlevelDeltaNext += ldNext;\n\t\t\t}\n\t\t\tint lev = levelCurrent;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelDeltaNext > 0) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent))\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent += levelDeltaNext;\n\t\t\tlevelDeltaNext = 0;\n\t\t\tvisibleChars = 0;\n\t\t\tstrcpy(prevWord, \"\");\n\t\t\tisPrevLine = false;\n\n\t\t\tif (foldComment) {\n\t\t\t\tStepCommentLine(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur,\n\t\t\t\t\t\tcomLineB, comLineF, comLineCur);\n\t\t\t}\n\t\t}\n\t\t/***************************************/\n\t\tif (!isspacechar(ch)) visibleChars++;\n\t}\n\t/***************************************/\n}\n/***************************************/\nstatic const char * const FortranWordLists[] = {\n\t\"Primary keywords and identifiers\",\n\t\"Intrinsic functions\",\n\t\"Extended and user defined functions\",\n\t0,\n};\n/***************************************/\nstatic void ColouriseFortranDocFreeFormat(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n        Accessor &styler) {\n\tColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);\n}\n/***************************************/\nstatic void ColouriseFortranDocFixFormat(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n        Accessor &styler) {\n\tColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);\n}\n/***************************************/\nstatic void FoldFortranDocFreeFormat(Sci_PositionU startPos, Sci_Position length, int initStyle,\n        WordList *[], Accessor &styler) {\n\tFoldFortranDoc(startPos, length, initStyle,styler, false);\n}\n/***************************************/\nstatic void FoldFortranDocFixFormat(Sci_PositionU startPos, Sci_Position length, int initStyle,\n        WordList *[], Accessor &styler) {\n\tFoldFortranDoc(startPos, length, initStyle,styler, true);\n}\n/***************************************/\nextern const LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, \"fortran\", FoldFortranDocFreeFormat, FortranWordLists);\nextern const LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, \"f77\", FoldFortranDocFixFormat, FortranWordLists);\n"
  },
  {
    "path": "lexers/LexGAP.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexGAP.cxx\n ** Lexer for the GAP language. (The GAP System for Computational Discrete Algebra)\n ** http://www.gap-system.org\n **/\n// Copyright 2007 by Istvan Szollosi ( szteven <at> gmail <dot> com )\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsGAPOperator(char ch) {\n\tif (IsASCII(ch) && isalnum(ch)) return false;\n\tif (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||\n\t\tch == '^' || ch == ',' || ch == '!' || ch == '.' ||\n\t\tch == '=' || ch == '<' || ch == '>' || ch == '(' ||\n\t\tch == ')' || ch == ';' || ch == '[' || ch == ']' ||\n\t\tch == '{' || ch == '}' || ch == ':' )\n\t\treturn true;\n\treturn false;\n}\n\nstatic void GetRange(Sci_PositionU start, Sci_PositionU end, Accessor &styler, char *s, Sci_PositionU len) {\n\tSci_PositionU i = 0;\n\twhile ((i < end - start + 1) && (i < len-1)) {\n\t\ts[i] = static_cast<char>(styler[start + i]);\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n}\n\nstatic void ColouriseGAPDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) {\n\n\tWordList &keywords1 = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\tWordList &keywords4 = *keywordlists[3];\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_GAP_STRINGEOL) initStyle = SCE_GAP_DEFAULT;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\t// Prevent SCE_GAP_STRINGEOL from leaking back to previous line\n\t\tif ( sc.atLineStart ) {\n\t\t\tif (sc.state == SCE_GAP_STRING) sc.SetState(SCE_GAP_STRING);\n\t\t\tif (sc.state == SCE_GAP_CHAR) sc.SetState(SCE_GAP_CHAR);\n\t\t}\n\n\t\t// Handle line continuation generically\n\t\tif (sc.ch == '\\\\' ) {\n\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_GAP_OPERATOR :\n\t\t\t\tsc.SetState(SCE_GAP_DEFAULT);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_GAP_NUMBER :\n\t\t\t\tif (!IsADigit(sc.ch)) {\n\t\t\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t\t\tif (!sc.atLineEnd) {\n\t\t\t\t\t\t\tif (!IsADigit(sc.chNext)) {\n\t\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t\t\tsc.ChangeState(SCE_GAP_IDENTIFIER);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (isalpha(sc.ch) || sc.ch == '_') {\n\t\t\t\t\t\tsc.ChangeState(SCE_GAP_IDENTIFIER);\n\t\t\t\t\t}\n\t\t\t\t\telse sc.SetState(SCE_GAP_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_GAP_IDENTIFIER :\n\t\t\t\tif (!(iswordstart(static_cast<char>(sc.ch)) || sc.ch == '$')) {\n\t\t\t\t\tif (sc.ch == '\\\\') sc.Forward();\n\t\t\t\t\telse {\n\t\t\t\t\t\tchar s[1000];\n\t\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\t\tif (keywords1.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_GAP_KEYWORD);\n\t\t\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_GAP_KEYWORD2);\n\t\t\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_GAP_KEYWORD3);\n\t\t\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_GAP_KEYWORD4);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsc.SetState(SCE_GAP_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_GAP_COMMENT :\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.SetState(SCE_GAP_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_GAP_STRING:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_GAP_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tsc.ForwardSetState(SCE_GAP_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_GAP_CHAR:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_GAP_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\tsc.ForwardSetState(SCE_GAP_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_GAP_STRINGEOL:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_GAP_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered\n\t\tif (sc.state == SCE_GAP_DEFAULT) {\n\t\t\tif (IsGAPOperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_GAP_OPERATOR);\n\t\t\t}\n\t\t\telse if (IsADigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_GAP_NUMBER);\n\t\t\t} else if (isalpha(sc.ch) || sc.ch == '_' || sc.ch == '\\\\' || sc.ch == '$' || sc.ch == '~') {\n\t\t\t\tsc.SetState(SCE_GAP_IDENTIFIER);\n\t\t\t\tif (sc.ch == '\\\\') sc.Forward();\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_GAP_COMMENT);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_GAP_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_GAP_CHAR);\n\t\t\t}\n\t\t}\n\n\t}\n\tsc.Complete();\n}\n\nstatic int ClassifyFoldPointGAP(const char* s) {\n\tint level = 0;\n\tif (strcmp(s, \"function\") == 0 ||\n\t\tstrcmp(s, \"do\") == 0 ||\n\t\tstrcmp(s, \"if\") == 0 ||\n\t\tstrcmp(s, \"repeat\") == 0 ) {\n\t\tlevel = 1;\n\t} else if (strcmp(s, \"end\") == 0 ||\n\t\t\tstrcmp(s, \"od\") == 0 ||\n\t\t\tstrcmp(s, \"fi\") == 0 ||\n\t\t\tstrcmp(s, \"until\") == 0 ) {\n\t\tlevel = -1;\n\t}\n\treturn level;\n}\n\nstatic void FoldGAPDoc( Sci_PositionU startPos, Sci_Position length, int initStyle,   WordList** , Accessor &styler) {\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\n\tSci_Position lastStart = 0;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (stylePrev != SCE_GAP_KEYWORD && style == SCE_GAP_KEYWORD) {\n\t\t\t// Store last word start point.\n\t\t\tlastStart = i;\n\t\t}\n\n\t\tif (stylePrev == SCE_GAP_KEYWORD) {\n\t\t\tif(iswordchar(ch) && !iswordchar(chNext)) {\n\t\t\t\tchar s[100];\n\t\t\t\tGetRange(lastStart, i, styler, s, sizeof(s));\n\t\t\t\tlevelCurrent += ClassifyFoldPointGAP(s);\n\t\t\t}\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const GAPWordListDesc[] = {\n\t\"Keywords 1\",\n\t\"Keywords 2\",\n\t\"Keywords 3 (unused)\",\n\t\"Keywords 4 (unused)\",\n\t0\n};\n\nextern const LexerModule lmGAP(\n   SCLEX_GAP,\n   ColouriseGAPDoc,\n   \"gap\",\n   FoldGAPDoc,\n   GAPWordListDesc);\n"
  },
  {
    "path": "lexers/LexGDScript.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexGDScript.cxx\n ** Lexer for GDScript.\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// Heavily modified later for GDScript\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"StringCopy.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"CharacterCategory.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"SubStyles.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\nenum kwType { kwOther, kwClass, kwDef, kwExtends};\n\nconstexpr int indicatorWhitespace = 1;\n\nbool IsGDStringStart(int ch) {\n    return (ch == '\\'' || ch == '\"');\n}\n\nbool IsGDComment(Accessor &styler, Sci_Position pos, Sci_Position len) {\n\treturn len > 0 && styler[pos] == '#';\n}\n\nconstexpr bool IsGDSingleQuoteStringState(int st) noexcept {\n\treturn ((st == SCE_GD_CHARACTER) || (st == SCE_GD_STRING));\n}\n\nconstexpr bool IsGDTripleQuoteStringState(int st) noexcept {\n\treturn ((st == SCE_GD_TRIPLE) || (st == SCE_GD_TRIPLEDOUBLE));\n}\n\nchar GetGDStringQuoteChar(int st) noexcept {\n\tif ((st == SCE_GD_CHARACTER) || (st == SCE_GD_TRIPLE))\n\t\treturn '\\'';\n\tif ((st == SCE_GD_STRING) || (st == SCE_GD_TRIPLEDOUBLE))\n\t\treturn '\"';\n\n\treturn '\\0';\n}\n\n/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */\nint GetGDStringState(Accessor &styler, Sci_Position i, Sci_PositionU *nextIndex) {\n\tchar ch = styler.SafeGetCharAt(i);\n\tchar chNext = styler.SafeGetCharAt(i + 1);\n\n\tif (ch != '\"' && ch != '\\'') {\n\t\t*nextIndex = i + 1;\n\t\treturn SCE_GD_DEFAULT;\n\t}\n\n\tif (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) {\n\t\t*nextIndex = i + 3;\n\n\t\tif (ch == '\"')\n\t\t\treturn SCE_GD_TRIPLEDOUBLE;\n\t\telse\n\t\t\treturn SCE_GD_TRIPLE;\n\t} else {\n\t\t*nextIndex = i + 1;\n\n\t\tif (ch == '\"')\n\t\t\treturn SCE_GD_STRING;\n\t\telse\n\t\t\treturn SCE_GD_CHARACTER;\n\t}\n}\n\nint GetGDStringState(int ch) {\n\tif (ch != '\"' && ch != '\\'')\n\t\treturn SCE_GD_DEFAULT;\n\n\tif (ch == '\"')\n\t\treturn SCE_GD_STRING;\n\telse\n\t\treturn SCE_GD_CHARACTER;\n}\n\ninline bool IsAWordChar(int ch, bool unicodeIdentifiers) {\n\tif (IsASCII(ch))\n\t\treturn (IsAlphaNumeric(ch) || ch == '.' || ch == '_');\n\n\tif (!unicodeIdentifiers)\n\t\treturn false;\n\n\treturn IsXidContinue(ch);\n}\n\ninline bool IsANodePathChar(int ch, bool unicodeIdentifiers) {\n\tif (IsASCII(ch))\n\t\treturn (IsAlphaNumeric(ch) || ch == '_' || ch == '/' || ch =='%');\n\n\tif (!unicodeIdentifiers)\n\t\treturn false;\n\n\treturn IsXidContinue(ch);\n}\n\ninline bool IsAWordStart(int ch, bool unicodeIdentifiers) {\n\tif (IsASCII(ch))\n\t\treturn (IsUpperOrLowerCase(ch) || ch == '_');\n\n\tif (!unicodeIdentifiers)\n\t\treturn false;\n\n\treturn IsXidStart(ch);\n}\n\nbool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) {\n\tconst Sci_Position line = styler.GetLine(pos);\n\tconst Sci_Position start_pos = styler.LineStart(line);\n\tfor (Sci_Position i = start_pos; i < pos; i++) {\n\t\tconst char ch = styler[i];\n\t\tif (!(ch == ' ' || ch == '\\t'))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\n// Options used for LexerGDScript\nstruct OptionsGDScript {\n\tint whingeLevel;\n\tbool base2or8Literals;\n\tbool stringsOverNewline;\n\tbool keywords2NoSubIdentifiers;\n\tbool fold;\n\tbool foldQuotes;\n\tbool foldCompact;\n\tbool unicodeIdentifiers;\n\n\tOptionsGDScript() noexcept {\n\t\twhingeLevel = 0;\n\t\tbase2or8Literals = true;\n\t\tstringsOverNewline = false;\n\t\tkeywords2NoSubIdentifiers = false;\n\t\tfold = false;\n\t\tfoldQuotes = false;\n\t\tfoldCompact = false;\n\t\tunicodeIdentifiers = true;\n\t}\n};\n\nconst char *const gdscriptWordListDesc[] = {\n\t\"Keywords\",\n\t\"Highlighted identifiers\",\n\tnullptr\n};\n\nstruct OptionSetGDScript : public OptionSet<OptionsGDScript> {\n\tOptionSetGDScript() {\n\t\tDefineProperty(\"lexer.gdscript.whinge.level\", &OptionsGDScript::whingeLevel,\n\t\t\t       \"For GDScript code, checks whether indenting is consistent. \"\n\t\t\t       \"The default, 0 turns off indentation checking, \"\n\t\t\t       \"1 checks whether each line is potentially inconsistent with the previous line, \"\n\t\t\t       \"2 checks whether any space characters occur before a tab character in the indentation, \"\n\t\t\t       \"3 checks whether any spaces are in the indentation, and \"\n\t\t\t       \"4 checks for any tab characters in the indentation. \"\n\t\t\t       \"1 is a good level to use.\");\n\n\t\tDefineProperty(\"lexer.gdscript.literals.binary\", &OptionsGDScript::base2or8Literals,\n\t\t\t       \"Set to 0 to not recognise binary and octal literals: 0b1011 0o712.\");\n\n\t\tDefineProperty(\"lexer.gdscript.strings.over.newline\", &OptionsGDScript::stringsOverNewline,\n\t\t\t       \"Set to 1 to allow strings to span newline characters.\");\n\n\t\tDefineProperty(\"lexer.gdscript.keywords2.no.sub.identifiers\", &OptionsGDScript::keywords2NoSubIdentifiers,\n\t\t\t       \"When enabled, it will not style keywords2 items that are used as a sub-identifier. \"\n\t\t\t       \"Example: when set, will not highlight \\\"foo.open\\\" when \\\"open\\\" is a keywords2 item.\");\n\n\t\tDefineProperty(\"fold\", &OptionsGDScript::fold);\n\n\t\tDefineProperty(\"fold.gdscript.quotes\", &OptionsGDScript::foldQuotes,\n\t\t\t       \"This option enables folding multi-line quoted strings when using the GDScript lexer.\");\n\n\t\tDefineProperty(\"fold.compact\", &OptionsGDScript::foldCompact);\n\n\t\tDefineProperty(\"lexer.gdscript.unicode.identifiers\", &OptionsGDScript::unicodeIdentifiers,\n\t\t\t       \"Set to 0 to not recognise Unicode identifiers.\");\n\n\t\tDefineWordListSets(gdscriptWordListDesc);\n\t}\n};\n\nconst char styleSubable[] = { SCE_GD_IDENTIFIER, 0 };\n\nLexicalClass lexicalClasses[] = {\n\t// Lexer GDScript SCLEX_GDSCRIPT SCE_GD_:\n\t0, \"SCE_GD_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_GD_COMMENTLINE\", \"comment line\", \"Comment\",\n\t2, \"SCE_GD_NUMBER\", \"literal numeric\", \"Number\",\n\t3, \"SCE_GD_STRING\", \"literal string\", \"String\",\n\t4, \"SCE_GD_CHARACTER\", \"literal string\", \"Single quoted string\",\n\t5, \"SCE_GD_WORD\", \"keyword\", \"Keyword\",\n\t6, \"SCE_GD_TRIPLE\", \"literal string\", \"Triple quotes\",\n\t7, \"SCE_GD_TRIPLEDOUBLE\", \"literal string\", \"Triple double quotes\",\n\t8, \"SCE_GD_CLASSNAME\", \"identifier\", \"Class name definition\",\n\t9, \"SCE_GD_FUNCNAME\", \"identifier\", \"Function or method name definition\",\n\t10, \"SCE_GD_OPERATOR\", \"operator\", \"Operators\",\n\t11, \"SCE_GD_IDENTIFIER\", \"identifier\", \"Identifiers\",\n\t12, \"SCE_GD_COMMENTBLOCK\", \"comment\", \"Comment-blocks\",\n\t13, \"SCE_GD_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n\t14, \"SCE_GD_WORD2\", \"identifier\", \"Highlighted identifiers\",\n\t15, \"SCE_GD_ANNOTATION\", \"annotation\", \"Annotations\",\n\t16, \"SCE_GD_NODEPATH\", \"path\", \"Node path\",\n};\n\n}\n\nclass LexerGDScript : public DefaultLexer {\n\tWordList keywords;\n\tWordList keywords2;\n\tOptionsGDScript options;\n\tOptionSetGDScript osGDScript;\n\tenum { ssIdentifier };\n\tSubStyles subStyles{styleSubable};\npublic:\n\texplicit LexerGDScript() :\n\t\tDefaultLexer(\"gdscript\", SCLEX_GDSCRIPT, lexicalClasses, ELEMENTS(lexicalClasses)) {\n\t}\n\t~LexerGDScript() override {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osGDScript.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osGDScript.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osGDScript.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osGDScript.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osGDScript.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn nullptr;\n\t}\n\n\tint SCI_METHOD LineEndTypesSupported() override {\n\t\treturn SC_LINE_END_TYPE_UNICODE;\n\t}\n\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {\n\t\treturn subStyles.Allocate(styleBase, numberStyles);\n\t}\n\tint SCI_METHOD SubStylesStart(int styleBase) override {\n\t\treturn subStyles.Start(styleBase);\n\t}\n\tint SCI_METHOD SubStylesLength(int styleBase) override {\n\t\treturn subStyles.Length(styleBase);\n\t}\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override {\n\t\tconst int styleBase = subStyles.BaseStyle(subStyle);\n\t\treturn styleBase;\n\t}\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) override {\n\t\treturn style;\n\t}\n\tvoid SCI_METHOD FreeSubStyles() override {\n\t\tsubStyles.Free();\n\t}\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {\n\t\tsubStyles.SetIdentifiers(style, identifiers);\n\t}\n\tint SCI_METHOD DistanceToSecondaryStyles() override {\n\t\treturn 0;\n\t}\n\tconst char *SCI_METHOD GetSubStyleBases() override {\n\t\treturn styleSubable;\n\t}\n\n\tstatic ILexer5 *LexerFactoryGDScript() {\n\t\treturn new LexerGDScript();\n\t}\n\nprivate:\n\tvoid ProcessLineEnd(StyleContext &sc, bool &inContinuedString);\n};\n\nSci_Position SCI_METHOD LexerGDScript::PropertySet(const char *key, const char *val) {\n\tif (osGDScript.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerGDScript::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywords2;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tWordList wlNew;\n\t\twlNew.Set(wl);\n\t\tif (*wordListN != wlNew) {\n\t\t\twordListN->Set(wl);\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid LexerGDScript::ProcessLineEnd(StyleContext &sc, bool &inContinuedString) {\n\tif ((sc.state == SCE_GD_DEFAULT)\n\t\t\t|| IsGDTripleQuoteStringState(sc.state)) {\n\t\t// Perform colourisation of white space and triple quoted strings at end of each line to allow\n\t\t// tab marking to work inside white space and triple quoted strings\n\t\tsc.SetState(sc.state);\n\t}\n\n\tif (IsGDSingleQuoteStringState(sc.state)) {\n\t\tif (inContinuedString || options.stringsOverNewline) {\n\t\t\tinContinuedString = false;\n\t\t} else {\n\t\t\tsc.ChangeState(SCE_GD_STRINGEOL);\n\t\t\tsc.ForwardSetState(SCE_GD_DEFAULT);\n\t\t}\n\t}\n}\n\nvoid SCI_METHOD LexerGDScript::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\n\tconst Sci_Position endPos = startPos + length;\n\n\t// Backtrack to previous line in case need to fix its tab whinging\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (startPos > 0) {\n\t\tif (lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\t// Look for backslash-continued lines\n\t\t\twhile (lineCurrent > 0) {\n\t\t\t\tconst Sci_Position eolPos = styler.LineStart(lineCurrent) - 1;\n\t\t\t\tconst int eolStyle = styler.StyleAt(eolPos);\n\t\t\t\tif (eolStyle == SCE_GD_STRING || eolStyle == SCE_GD_CHARACTER\n\t\t\t\t\t\t|| eolStyle == SCE_GD_STRINGEOL) {\n\t\t\t\t\tlineCurrent -= 1;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t\t}\n\t\tinitStyle = startPos == 0 ? SCE_GD_DEFAULT : styler.StyleAt(startPos - 1);\n\t}\n\n\tinitStyle = initStyle & 31;\n\tif (initStyle == SCE_GD_STRINGEOL) {\n\t\tinitStyle = SCE_GD_DEFAULT;\n\t}\n\n\tkwType kwLast = kwOther;\n\tint spaceFlags = 0;\n\tstyler.IndentAmount(lineCurrent, &spaceFlags, IsGDComment);\n\tbool base_n_number = false;\n\n\tconst WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_GD_IDENTIFIER);\n\n\tStyleContext sc(startPos, endPos - startPos, initStyle, styler);\n\n\tbool indentGood = true;\n\tSci_Position startIndicator = sc.currentPos;\n\tbool inContinuedString = false;\n\tbool percentIsNodePath = false;\n\tint nodePathStringState = SCE_GD_DEFAULT;\n\t\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.atLineStart) {\n\t\t\tstyler.IndentAmount(lineCurrent, &spaceFlags, IsGDComment);\n\t\t\tindentGood = true;\n\t\t\tif (options.whingeLevel == 1) {\n\t\t\t\tindentGood = (spaceFlags & wsInconsistent) == 0;\n\t\t\t} else if (options.whingeLevel == 2) {\n\t\t\t\tindentGood = (spaceFlags & wsSpaceTab) == 0;\n\t\t\t} else if (options.whingeLevel == 3) {\n\t\t\t\tindentGood = (spaceFlags & wsSpace) == 0;\n\t\t\t} else if (options.whingeLevel == 4) {\n\t\t\t\tindentGood = (spaceFlags & wsTab) == 0;\n\t\t\t}\n\t\t\tif (!indentGood) {\n\t\t\t\tstyler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);\n\t\t\t\tstartIndicator = sc.currentPos;\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\tpercentIsNodePath = false;\n\t\t\tProcessLineEnd(sc, inContinuedString);\n\t\t\tlineCurrent++;\n\t\t\tif (!sc.More())\n\t\t\t\tbreak;\n\t\t}\n\n\t\tbool needEOLCheck = false;\n\n\t\tif (sc.state == SCE_GD_OPERATOR) {\n\t\t\tkwLast = kwOther;\n\t\t\tsc.SetState(SCE_GD_DEFAULT);\n\t\t} else if (sc.state == SCE_GD_NUMBER) {\n\t\t\tif (!IsAWordChar(sc.ch, false) &&\n\t\t\t\t\t!(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {\n\t\t\t\tsc.SetState(SCE_GD_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_GD_IDENTIFIER) {\n\t\t\tif ((sc.ch == '.') || (!IsAWordChar(sc.ch, options.unicodeIdentifiers))) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\tint style = SCE_GD_IDENTIFIER;\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tstyle = SCE_GD_WORD;\n\t\t\t\t} else if (kwLast == kwClass) {\n\t\t\t\t\tstyle = SCE_GD_CLASSNAME;\n\t\t\t\t} else if (kwLast == kwDef) {\n\t\t\t\t\tstyle = SCE_GD_FUNCNAME;\n\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\tif (options.keywords2NoSubIdentifiers) {\n\t\t\t\t\t\t// We don't want to highlight keywords2\n\t\t\t\t\t\t// that are used as a sub-identifier,\n\t\t\t\t\t\t// i.e. not open in \"foo.open\".\n\t\t\t\t\t\tconst Sci_Position pos = styler.GetStartSegment() - 1;\n\t\t\t\t\t\tif (pos < 0 || (styler.SafeGetCharAt(pos, '\\0') != '.'))\n\t\t\t\t\t\t\tstyle = SCE_GD_WORD2;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyle = SCE_GD_WORD2;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst int subStyle = classifierIdentifiers.ValueFor(s);\n\t\t\t\t\tif (subStyle >= 0) {\n\t\t\t\t\t\tstyle = subStyle;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsc.ChangeState(style);\n\t\t\t\tsc.SetState(SCE_GD_DEFAULT);\n\t\t\t\tif (style == SCE_GD_WORD) {\n\t\t\t\t\tif (0 == strcmp(s, \"class\"))\n\t\t\t\t\t\tkwLast = kwClass;\n\t\t\t\t\telse if (0 == strcmp(s, \"func\"))\n\t\t\t\t\t\tkwLast = kwDef;\n\t\t\t\t\telse if (0 == strcmp(s, \"extends\"))\n\t\t\t\t\t\tkwLast = kwExtends;\n\t\t\t\t\telse\n\t\t\t\t\t\tkwLast = kwOther;\n\t\t\t\t} else {\n\t\t\t\t\tkwLast = kwOther;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ((sc.state == SCE_GD_COMMENTLINE) || (sc.state == SCE_GD_COMMENTBLOCK)) {\n\t\t\tif (sc.ch == '\\r' || sc.ch == '\\n') {\n\t\t\t\tsc.SetState(SCE_GD_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_GD_ANNOTATION) {\n\t\t\tif (!IsAWordStart(sc.ch, options.unicodeIdentifiers)) {\n\t\t\t\tsc.SetState(SCE_GD_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_GD_NODEPATH) {\n\t\t\tif (nodePathStringState != SCE_GD_DEFAULT) {\n\t\t\t\tif (sc.ch == GetGDStringQuoteChar(nodePathStringState) ) {\n\t\t\t\t\tnodePathStringState = SCE_GD_DEFAULT;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (IsGDStringStart(sc.ch)) {\n\t\t\t\t\tnodePathStringState = GetGDStringState(sc.ch);\n\t\t\t\t} else if (!IsANodePathChar(sc.ch, options.unicodeIdentifiers)) {\n\t\t\t\t\tsc.SetState(SCE_GD_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (IsGDSingleQuoteStringState(sc.state)) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif ((sc.chNext == '\\r') && (sc.GetRelative(2) == '\\n')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\t\tinContinuedString = true;\n\t\t\t\t} else {\n\t\t\t\t\t// Don't roll over the newline.\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == GetGDStringQuoteChar(sc.state)) {\n\t\t\t\tsc.ForwardSetState(SCE_GD_DEFAULT);\n\t\t\t\tneedEOLCheck = true;\n\t\t\t}\n\t\t} else if (sc.state == SCE_GD_TRIPLE) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match(R\"(''')\")) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_GD_DEFAULT);\n\t\t\t\tneedEOLCheck = true;\n\t\t\t}\n\t\t} else if (sc.state == SCE_GD_TRIPLEDOUBLE) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match(R\"(\"\"\")\")) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_GD_DEFAULT);\n\t\t\t\tneedEOLCheck = true;\n\t\t\t}\n\t\t}\n\n\t\tif (!indentGood && !IsASpaceOrTab(sc.ch)) {\n\t\t\tstyler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1);\n\t\t\tstartIndicator = sc.currentPos;\n\t\t\tindentGood = true;\n\t\t}\n\n\t\t// State exit code may have moved on to end of line\n\t\tif (needEOLCheck && sc.atLineEnd) {\n\t\t\tProcessLineEnd(sc, inContinuedString);\n\t\t\tlineCurrent++;\n\t\t\tstyler.IndentAmount(lineCurrent, &spaceFlags, IsGDComment);\n\t\t\tif (!sc.More())\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Check for a new state starting character\n\t\tif (sc.state == SCE_GD_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tif (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {\n\t\t\t\t\tbase_n_number = true;\n\t\t\t\t\tsc.SetState(SCE_GD_NUMBER);\n\t\t\t\t} else if (sc.ch == '0' &&\n\t\t\t\t\t\t(sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {\n\t\t\t\t\tif (options.base2or8Literals) {\n\t\t\t\t\t\tbase_n_number = true;\n\t\t\t\t\t\tsc.SetState(SCE_GD_NUMBER);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_GD_NUMBER);\n\t\t\t\t\t\tsc.ForwardSetState(SCE_GD_IDENTIFIER);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tbase_n_number = false;\n\t\t\t\t\tsc.SetState(SCE_GD_NUMBER);\n\t\t\t\t}\n\t\t\t} else if ((sc.ch == '$') || (sc.ch == '%' && (percentIsNodePath || IsFirstNonWhitespace(sc.currentPos, styler)))) {\n\t\t\t\tpercentIsNodePath = false;\n\t\t\t\tsc.SetState(SCE_GD_NODEPATH);\n\t\t\t} else if (isoperator(sc.ch) || sc.ch == '`') {\n\t\t\t\tpercentIsNodePath = !((sc.ch == ')') || (sc.ch == ']') || (sc.ch == '}'));\n\t\t\t\tsc.SetState(SCE_GD_OPERATOR);\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.SetState(sc.chNext == '#' ? SCE_GD_COMMENTBLOCK : SCE_GD_COMMENTLINE);\n\t\t\t} else if (sc.ch == '@') {\n\t\t\t\tif (IsFirstNonWhitespace(sc.currentPos, styler))\n\t\t\t\t\tsc.SetState(SCE_GD_ANNOTATION);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_GD_OPERATOR);\n\t\t\t} else if (IsGDStringStart(sc.ch)) {\n\t\t\t\tSci_PositionU nextIndex = 0;\n\t\t\t\tsc.SetState(GetGDStringState(styler, sc.currentPos, &nextIndex));\n\t\t\t\twhile (nextIndex > (sc.currentPos + 1) && sc.More()) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n            } else if (IsAWordStart(sc.ch, options.unicodeIdentifiers)) {\n\t\t\t\tsc.SetState(SCE_GD_IDENTIFIER);\n\t\t\t}\n\t\t}\n\t}\n\tstyler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);\n\tsc.Complete();\n}\n\nstatic bool IsCommentLine(Sci_Position line, Accessor &styler) {\n\tconst Sci_Position pos = styler.LineStart(line);\n\tconst Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tconst char ch = styler[i];\n\t\tif (ch == '#')\n\t\t\treturn true;\n\t\telse if (ch != ' ' && ch != '\\t')\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nstatic bool IsQuoteLine(Sci_Position line, const Accessor &styler) {\n\tconst int style = styler.StyleAt(styler.LineStart(line)) & 31;\n\treturn IsGDTripleQuoteStringState(style);\n}\n\n\nvoid SCI_METHOD LexerGDScript::Fold(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/, IDocument *pAccess) {\n\tif (!options.fold)\n\t\treturn;\n\n\tAccessor styler(pAccess, nullptr);\n\n\tconst Sci_Position maxPos = startPos + length;\n\tconst Sci_Position maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1);\t// Requested last line\n\tconst Sci_Position docLines = styler.GetLine(styler.Length());\t// Available last line\n\n\t// Backtrack to previous non-blank line so we can determine indent level\n\t// for any white space lines (needed esp. within triple quoted strings)\n\t// and so we can fix any preceding fold level (which is why we go back\n\t// at least one line in all cases)\n\tint spaceFlags = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);\n\twhile (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tindentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);\n\t\tif (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&\n\t\t\t\t(!IsCommentLine(lineCurrent, styler)) &&\n\t\t\t\t(!IsQuoteLine(lineCurrent, styler)))\n\t\t\tbreak;\n\t}\n\tint indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\n\t// Set up initial loop state\n\tstartPos = styler.LineStart(lineCurrent);\n\tint prev_state = SCE_GD_DEFAULT & 31;\n\tif (lineCurrent >= 1)\n\t\tprev_state = styler.StyleAt(startPos - 1) & 31;\n\tint prevQuote = options.foldQuotes && IsGDTripleQuoteStringState(prev_state);\n\n\t// Process all characters to end of requested range or end of any triple quote\n\t//that hangs over the end of the range.  Cap processing in all cases\n\t// to end of document (in case of unclosed quote at end).\n\twhile ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) {\n\n\t\t// Gather info\n\t\tint lev = indentCurrent;\n\t\tSci_Position lineNext = lineCurrent + 1;\n\t\tint indentNext = indentCurrent;\n\t\tint quote = false;\n\t\tif (lineNext <= docLines) {\n\t\t\t// Information about next line is only available if not at end of document\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);\n\t\t\tconst Sci_Position lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);\n\t\t\tconst int style = styler.StyleAt(lookAtPos) & 31;\n\t\t\tquote = options.foldQuotes && IsGDTripleQuoteStringState(style);\n\t\t}\n\t\tconst bool quote_start = (quote && !prevQuote);\n\t\tconst bool quote_continue = (quote && prevQuote);\n\t\tif (!quote || !prevQuote)\n\t\t\tindentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\t\tif (quote)\n\t\t\tindentNext = indentCurrentLevel;\n\t\tif (indentNext & SC_FOLDLEVELWHITEFLAG)\n\t\t\tindentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;\n\n\t\tif (quote_start) {\n\t\t\t// Place fold point at start of triple quoted string\n\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t} else if (quote_continue || prevQuote) {\n\t\t\t// Add level to rest of lines in the string\n\t\t\tlev = lev + 1;\n\t\t}\n\n\t\t// Skip past any blank lines for next indent level info; we skip also\n\t\t// comments (all comments, not just those starting in column 0)\n\t\t// which effectively folds them into surrounding code rather\n\t\t// than screwing up folding.  If comments end file, use the min\n\t\t// comment indent as the level after\n\n\t\tint minCommentLevel = indentCurrentLevel;\n\t\twhile (!quote &&\n\t\t\t\t(lineNext < docLines) &&\n\t\t\t\t((indentNext & SC_FOLDLEVELWHITEFLAG) || (IsCommentLine(lineNext, styler)))) {\n\n\t\t\tif (IsCommentLine(lineNext, styler) && indentNext < minCommentLevel) {\n\t\t\t\tminCommentLevel = indentNext;\n\t\t\t}\n\n\t\t\tlineNext++;\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);\n\t\t}\n\n\t\tconst int levelAfterComments = ((lineNext < docLines) ? indentNext & SC_FOLDLEVELNUMBERMASK : minCommentLevel);\n\t\tconst int levelBeforeComments = std::max(indentCurrentLevel, levelAfterComments);\n\n\t\t// Now set all the indent levels on the lines we skipped\n\t\t// Do this from end to start.  Once we encounter one line\n\t\t// which is indented more than the line after the end of\n\t\t// the comment-block, use the level of the block before\n\n\t\tSci_Position skipLine = lineNext;\n\t\tint skipLevel = levelAfterComments;\n\n\t\twhile (--skipLine > lineCurrent) {\n\t\t\tconst int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, nullptr);\n\n\t\t\tif (options.foldCompact) {\n\t\t\t\tif ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)\n\t\t\t\t\tskipLevel = levelBeforeComments;\n\n\t\t\t\tconst int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;\n\n\t\t\t\tstyler.SetLevel(skipLine, skipLevel | whiteFlag);\n\t\t\t} else {\n\t\t\t\tif ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&\n\t\t\t\t\t\t!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&\n\t\t\t\t\t\t!IsCommentLine(skipLine, styler))\n\t\t\t\t\tskipLevel = levelBeforeComments;\n\n\t\t\t\tstyler.SetLevel(skipLine, skipLevel);\n\t\t\t}\n\t\t}\n\n\t\t// Set fold header on non-quote line\n\t\tif (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t}\n\n\t\t// Keep track of triple quote state of previous line\n\t\tprevQuote = quote;\n\n\t\t// Set fold level for this line and move to next line\n\t\tstyler.SetLevel(lineCurrent, options.foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);\n\t\tindentCurrent = indentNext;\n\t\tlineCurrent = lineNext;\n\t}\n\n\t// NOTE: Cannot set level of last line here because indentCurrent doesn't have\n\t// header flag set; the loop above is crafted to take care of this case!\n\t//styler.SetLevel(lineCurrent, indentCurrent);\n}\n\nextern const LexerModule lmGDScript(SCLEX_GDSCRIPT, LexerGDScript::LexerFactoryGDScript, \"gdscript\",\n\t\t     gdscriptWordListDesc);\n"
  },
  {
    "path": "lexers/LexGui4Cli.cxx",
    "content": "// Scintilla source code edit control\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// @file LexGui4Cli.cxx\n/*\nThis is the Lexer for Gui4Cli, included in SciLexer.dll\n- by d. Keletsekis, 2/10/2003\n\nTo add to SciLexer.dll:\n1. Add the values below to INCLUDE\\Scintilla.iface\n2. Run the scripts/HFacer.py script\n3. Run the scripts/LexGen.py script\n\nval SCE_GC_DEFAULT=0\nval SCE_GC_COMMENTLINE=1\nval SCE_GC_COMMENTBLOCK=2\nval SCE_GC_GLOBAL=3\nval SCE_GC_EVENT=4\nval SCE_GC_ATTRIBUTE=5\nval SCE_GC_CONTROL=6\nval SCE_GC_COMMAND=7\nval SCE_GC_STRING=8\nval SCE_GC_OPERATOR=9\n*/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n#define debug Platform::DebugPrintf\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\\\');\n}\n\ninline bool isGCOperator(int ch)\n{\tif (isalnum(ch))\n\t\treturn false;\n\t// '.' left out as it is used to make up numbers\n\tif (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||\n\t\t ch == '(' || ch == ')' || ch == '=' || ch == '%' ||\n\t\t ch == '[' || ch == ']' || ch == '<' || ch == '>' ||\n\t\t ch == ',' || ch == ';' || ch == ':')\n\t\treturn true;\n\treturn false;\n}\n\n#define isSpace(x)\t\t((x)==' ' || (x)=='\\t')\n#define isNL(x)\t\t\t((x)=='\\n' || (x)=='\\r')\n#define isSpaceOrNL(x)  (isSpace(x) || isNL(x))\n#define BUFFSIZE 500\n#define isFoldPoint(x)  ((styler.LevelAt(x) & SC_FOLDLEVELNUMBERMASK) == 1024)\n\nstatic void colorFirstWord(WordList *keywordlists[], Accessor &styler,\n\t\t\t\t\t\t\t\t\tStyleContext *sc, char *buff, Sci_Position length, Sci_Position)\n{\n\tSci_Position c = 0;\n\twhile (sc->More() && isSpaceOrNL(sc->ch))\n\t{\tsc->Forward();\n\t}\n\tstyler.ColourTo(sc->currentPos - 1, sc->state);\n\n\tif (!IsAWordChar(sc->ch)) // comment, marker, etc..\n\t\treturn;\n\n\twhile (sc->More() && !isSpaceOrNL(sc->ch) && (c < length-1) && !isGCOperator(sc->ch))\n\t{\tbuff[c] = static_cast<char>(sc->ch);\n\t\t++c; sc->Forward();\n\t}\n\tbuff[c] = '\\0';\n\tchar *p = buff;\n\twhile (*p)\t// capitalize..\n\t{\tif (islower(*p)) *p = static_cast<char>(toupper(*p));\n\t\t++p;\n\t}\n\n\tWordList &kGlobal\t\t= *keywordlists[0];\t// keyword lists set by the user\n\tWordList &kEvent\t\t= *keywordlists[1];\n\tWordList &kAttribute\t= *keywordlists[2];\n\tWordList &kControl\t= *keywordlists[3];\n\tWordList &kCommand\t= *keywordlists[4];\n\n\tint state = 0;\n\t// int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;\n\t// debug (\"line = %d, level = %d\", line, level);\n\n\tif\t     (kGlobal.InList(buff))\t\tstate = SCE_GC_GLOBAL;\n\telse if (kAttribute.InList(buff))\tstate = SCE_GC_ATTRIBUTE;\n\telse if (kControl.InList(buff))\t\tstate = SCE_GC_CONTROL;\n\telse if (kCommand.InList(buff))\t\tstate = SCE_GC_COMMAND;\n\telse if (kEvent.InList(buff))\t\t\tstate = SCE_GC_EVENT;\n\n\tif (state)\n\t{\tsc->ChangeState(state);\n\t\tstyler.ColourTo(sc->currentPos - 1, sc->state);\n\t\tsc->ChangeState(SCE_GC_DEFAULT);\n\t}\n\telse\n\t{\tsc->ChangeState(SCE_GC_DEFAULT);\n\t\tstyler.ColourTo(sc->currentPos - 1, sc->state);\n\t}\n}\n\n// Main colorizing function called by Scintilla\nstatic void\nColouriseGui4CliDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                    WordList *keywordlists[], Accessor &styler)\n{\n\tstyler.StartAt(startPos);\n\n\tSci_Position currentline = styler.GetLine(startPos);\n\tint quotestart = 0, oldstate;\n\tstyler.StartSegment(startPos);\n\tbool noforward;\n\tchar buff[BUFFSIZE+1];\t// buffer for command name\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tbuff[0] = '\\0'; // cbuff = 0;\n\n\tif (sc.state != SCE_GC_COMMENTBLOCK) // colorize 1st word..\n\t\tcolorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);\n\n\twhile (sc.More())\n\t{\tnoforward = 0;\n\n\t\tswitch (sc.ch)\n\t\t{\n\t\t\tcase '/':\n\t\t\t\tif (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_STRING)\n\t\t\t\t\tbreak;\n\t\t\t\tif (sc.chNext == '/')\t// line comment\n\t\t\t\t{\tsc.SetState (SCE_GC_COMMENTLINE);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tstyler.ColourTo(sc.currentPos, sc.state);\n\t\t\t\t}\n\t\t\t\telse if (sc.chNext == '*')\t// block comment\n\t\t\t\t{\tsc.SetState(SCE_GC_COMMENTBLOCK);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tstyler.ColourTo(sc.currentPos, sc.state);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tstyler.ColourTo(sc.currentPos, sc.state);\n\t\t\t\tbreak;\n\n\t\t\tcase '*':\t// end of comment block, or operator..\n\t\t\t\tif (sc.state == SCE_GC_STRING)\n\t\t\t\t\tbreak;\n\t\t\t\tif (sc.state == SCE_GC_COMMENTBLOCK && sc.chNext == '/')\n\t\t\t\t{\tsc.Forward();\n\t\t\t\t\tstyler.ColourTo(sc.currentPos, sc.state);\n\t\t\t\t\tsc.ChangeState (SCE_GC_DEFAULT);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tstyler.ColourTo(sc.currentPos, sc.state);\n\t\t\t\tbreak;\n\n\t\t\tcase '\\'':\tcase '\\\"': // strings..\n\t\t\t\tif (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_COMMENTLINE)\n\t\t\t\t\tbreak;\n\t\t\t\tif (sc.state == SCE_GC_STRING)\n\t\t\t\t{\tif (sc.ch == quotestart)\t// match same quote char..\n\t\t\t\t\t{\tstyler.ColourTo(sc.currentPos, sc.state);\n\t\t\t\t\t\tsc.ChangeState(SCE_GC_DEFAULT);\n\t\t\t\t\t\tquotestart = 0;\n\t\t\t\t}\t}\n\t\t\t\telse\n\t\t\t\t{\tstyler.ColourTo(sc.currentPos - 1, sc.state);\n\t\t\t\t\tsc.ChangeState(SCE_GC_STRING);\n\t\t\t\t\tquotestart = sc.ch;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase ';':\t// end of commandline character\n\t\t\t\tif (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&\n\t\t\t\t\t sc.state != SCE_GC_STRING)\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(sc.currentPos - 1, sc.state);\n\t\t\t\t\tstyler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);\n\t\t\t\t\tsc.ChangeState(SCE_GC_DEFAULT);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tcolorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);\n\t\t\t\t\tnoforward = 1; // don't move forward - already positioned at next char..\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase '+': case '-': case '=':\tcase '!':\t// operators..\n\t\t\tcase '<': case '>': case '&': case '|': case '$':\n\t\t\t\tif (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&\n\t\t\t\t\t sc.state != SCE_GC_STRING)\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(sc.currentPos - 1, sc.state);\n\t\t\t\t\tstyler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);\n\t\t\t\t\tsc.ChangeState(SCE_GC_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase '\\\\':\t// escape - same as operator, but also mark in strings..\n\t\t\t\tif (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE)\n\t\t\t\t{\n\t\t\t\t\toldstate = sc.state;\n\t\t\t\t\tstyler.ColourTo(sc.currentPos - 1, sc.state);\n\t\t\t\t\tsc.Forward(); // mark also the next char..\n\t\t\t\t\tstyler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);\n\t\t\t\t\tsc.ChangeState(oldstate);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase '\\n': case '\\r':\n\t\t\t\t++currentline;\n\t\t\t\tif (sc.state == SCE_GC_COMMENTLINE)\n\t\t\t\t{\tstyler.ColourTo(sc.currentPos, sc.state);\n\t\t\t\t\tsc.ChangeState (SCE_GC_DEFAULT);\n\t\t\t\t}\n\t\t\t\telse if (sc.state != SCE_GC_COMMENTBLOCK)\n\t\t\t\t{\tcolorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);\n\t\t\t\t\tnoforward = 1; // don't move forward - already positioned at next char..\n\t\t\t\t}\n\t\t\t\tbreak;\n\n//\t\t\tcase ' ': case '\\t':\n//\t\t\tdefault :\n\t\t}\n\n\t\tif (!noforward) sc.Forward();\n\n\t}\n\tsc.Complete();\n}\n\n// Main folding function called by Scintilla - (based on props (.ini) files function)\nstatic void FoldGui4Cli(Sci_PositionU startPos, Sci_Position length, int,\n\t\t\t\t\t\t\t\tWordList *[], Accessor &styler)\n{\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tbool headerPoint = false;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++)\n\t{\n\t\tchar ch = chNext;\n\t\tchNext = styler[i+1];\n\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (style == SCE_GC_EVENT || style == SCE_GC_GLOBAL)\n\t\t{\theaderPoint = true; // fold at events and globals\n\t\t}\n\n\t\tif (atEOL)\n\t\t{\tint lev = SC_FOLDLEVELBASE+1;\n\n\t\t\tif (headerPoint)\n\t\t\t\tlev = SC_FOLDLEVELBASE;\n\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\n\t\t\tif (headerPoint)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) // set level, if not already correct\n\t\t\t{\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\n\t\t\tlineCurrent++;\t\t// re-initialize our flags\n\t\t\tvisibleChars = 0;\n\t\t\theaderPoint = false;\n\t\t}\n\n\t\tif (!(isspacechar(ch))) // || (style == SCE_GC_COMMENTLINE) || (style != SCE_GC_COMMENTBLOCK)))\n\t\t\tvisibleChars++;\n\t}\n\n\tint lev = headerPoint ? SC_FOLDLEVELBASE : SC_FOLDLEVELBASE+1;\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, lev | flagsNext);\n}\n\n// I have no idea what these are for.. probably accessible by some message.\nstatic const char * const gui4cliWordListDesc[] = {\n\t\"Globals\", \"Events\", \"Attributes\", \"Control\", \"Commands\",\n\t0\n};\n\n// Declare language & pass our function pointers to Scintilla\nextern const LexerModule lmGui4Cli(SCLEX_GUI4CLI, ColouriseGui4CliDoc, \"gui4cli\", FoldGui4Cli, gui4cliWordListDesc);\n\n#undef debug\n\n"
  },
  {
    "path": "lexers/LexHTML.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexHTML.cxx\n ** Lexer for HTML.\n **/\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <set>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n#include \"InList.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"SubStyles.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\n#define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START)\n#define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)\n#define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)\n\nenum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock, eScriptComment };\nenum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc };\n\nconstexpr bool IsAWordChar(int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '.' || ch == '_';\n}\n\nconstexpr bool IsAWordStart(int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '_';\n}\n\nbool IsOperator(int ch) noexcept {\n\tif (IsAlphaNumeric(ch))\n\t\treturn false;\n\t// '.' left out as it is used to make up numbers\n\tif (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||\n\t        ch == '(' || ch == ')' || ch == '-' || ch == '+' ||\n\t        ch == '=' || ch == '|' || ch == '{' || ch == '}' ||\n\t        ch == '[' || ch == ']' || ch == ':' || ch == ';' ||\n\t        ch == '<' || ch == '>' || ch == ',' || ch == '/' ||\n\t        ch == '?' || ch == '!' || ch == '.' || ch == '~')\n\t\treturn true;\n\treturn false;\n}\n\nunsigned char SafeGetUnsignedCharAt(Accessor &styler, Sci_Position position, char chDefault = ' ') {\n\treturn styler.SafeGetCharAt(position, chDefault);\n}\n\n// Put an upper limit to bound time taken for unexpected text.\nconstexpr Sci_PositionU maxLengthCheck = 200;\n\nstd::string GetNextWord(Accessor &styler, Sci_PositionU start) {\n\tstd::string ret;\n\tfor (Sci_PositionU i = 0; i < maxLengthCheck; i++) {\n\t\tconst char ch = styler.SafeGetCharAt(start + i);\n\t\tif ((i == 0) && !IsAWordStart(ch))\n\t\t\tbreak;\n\t\tif ((i > 0) && !IsAWordChar(ch))\n\t\t\tbreak;\n\t\tret.push_back(ch);\n\t}\n\treturn ret;\n}\n\nbool Contains(const std::string &s, std::string_view search) noexcept {\n\treturn s.find(search) != std::string::npos;\n}\n\nscript_type segIsScriptingIndicator(const Accessor &styler, Sci_PositionU start, Sci_PositionU end, script_type prevValue) {\n\tconst std::string s = styler.GetRangeLowered(start, end+1);\n\tif (Contains(s, \"vbs\"))\n\t\treturn eScriptVBS;\n\tif (Contains(s, \"pyth\"))\n\t\treturn eScriptPython;\n\t// https://html.spec.whatwg.org/multipage/scripting.html#attr-script-type\n\t// https://mimesniff.spec.whatwg.org/#javascript-mime-type\n\tif (Contains(s, \"javas\") || Contains(s, \"ecmas\") || Contains(s, \"module\") || Contains(s, \"jscr\"))\n\t\treturn eScriptJS;\n\tif (Contains(s, \"php\"))\n\t\treturn eScriptPHP;\n\n\tconst size_t xml = s.find(\"xml\");\n\tif (xml != std::string::npos) {\n\t\tfor (size_t t = 0; t < xml; t++) {\n\t\t\tif (!IsASpace(s[t])) {\n\t\t\t\treturn prevValue;\n\t\t\t}\n\t\t}\n\t\treturn eScriptXML;\n\t}\n\n\treturn prevValue;\n}\n\nconstexpr bool IsPHPScriptState(int state) noexcept {\n\treturn (state >= SCE_HPHP_DEFAULT && state <= SCE_HPHP_OPERATOR) || (state == SCE_HPHP_COMPLEX_VARIABLE);\n}\n\nscript_type ScriptOfState(int state) noexcept {\n\tif ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {\n\t\treturn eScriptPython;\n\t} else if ((state >= SCE_HB_START && state <= SCE_HB_STRINGEOL) || (state == SCE_H_ASPAT || state == SCE_H_XCCOMMENT)) {\n\t\treturn eScriptVBS;\n\t} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_TEMPLATELITERAL)) {\n\t\treturn eScriptJS;\n\t} else if (IsPHPScriptState(state)) {\n\t\treturn eScriptPHP;\n\t} else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) {\n\t\treturn eScriptSGML;\n\t} else if (state == SCE_H_SGML_BLOCK_DEFAULT) {\n\t\treturn eScriptSGMLblock;\n\t} else {\n\t\treturn eScriptNone;\n\t}\n}\n\nconstexpr int statePrintForState(int state, script_mode inScriptType) noexcept {\n\tint StateToPrint = state;\n\n\tif (state >= SCE_HJ_START) {\n\t\tif ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {\n\t\t\tStateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON);\n\t\t} else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {\n\t\t\tStateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS);\n\t\t} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_TEMPLATELITERAL)) {\n\t\t\tStateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS);\n\t\t}\n\t}\n\n\treturn StateToPrint;\n}\n\nconstexpr int stateForPrintState(int StateToPrint) noexcept {\n\tint state = StateToPrint;\n\n\tif ((StateToPrint >= SCE_HPA_START) && (StateToPrint <= SCE_HPA_IDENTIFIER)) {\n\t\tstate = StateToPrint - SCE_HA_PYTHON;\n\t} else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) {\n\t\tstate = StateToPrint - SCE_HA_VBS;\n\t} else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_TEMPLATELITERAL)) {\n\t\tstate = StateToPrint - SCE_HA_JS;\n\t}\n\n\treturn state;\n}\n\nconstexpr bool IsNumberChar(char ch) noexcept {\n\treturn IsADigit(ch) || ch == '.' || ch == '-' || ch == '#';\n}\n\nconstexpr bool isStringState(int state) noexcept {\n\tbool bResult = false;\n\n\tswitch (state) {\n\tcase SCE_HJ_DOUBLESTRING:\n\tcase SCE_HJ_SINGLESTRING:\n\tcase SCE_HJ_REGEX:\n\tcase SCE_HJ_TEMPLATELITERAL:\n\tcase SCE_HJA_DOUBLESTRING:\n\tcase SCE_HJA_SINGLESTRING:\n\tcase SCE_HJA_REGEX:\n\tcase SCE_HJA_TEMPLATELITERAL:\n\tcase SCE_HB_STRING:\n\tcase SCE_HBA_STRING:\n\tcase SCE_HP_STRING:\n\tcase SCE_HP_CHARACTER:\n\tcase SCE_HP_TRIPLE:\n\tcase SCE_HP_TRIPLEDOUBLE:\n\tcase SCE_HPA_STRING:\n\tcase SCE_HPA_CHARACTER:\n\tcase SCE_HPA_TRIPLE:\n\tcase SCE_HPA_TRIPLEDOUBLE:\n\tcase SCE_HPHP_HSTRING:\n\tcase SCE_HPHP_SIMPLESTRING:\n\tcase SCE_HPHP_HSTRING_VARIABLE:\n\tcase SCE_HPHP_COMPLEX_VARIABLE:\n\t\tbResult = true;\n\t\tbreak;\n\tdefault :\n\t\tbreak;\n\t}\n\treturn bResult;\n}\n\nconstexpr bool stateAllowsTermination(int state) noexcept {\n\tbool allowTermination = !isStringState(state);\n\tif (allowTermination) {\n\t\tswitch (state) {\n\t\tcase SCE_HPHP_COMMENT:\n\t\tcase SCE_HP_COMMENTLINE:\n\t\tcase SCE_HPA_COMMENTLINE:\n\t\t\tallowTermination = false;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn allowTermination;\n}\n\nbool isPreProcessorEndTag(int state, int ch) noexcept {\n\tconst script_type type = ScriptOfState(state);\n\tif (state == SCE_H_ASP || AnyOf(type, eScriptVBS, eScriptJS, eScriptPython)) {\n\t\treturn ch == '%';\n\t}\n\tif (type == eScriptPHP) {\n\t\treturn ch == '%' || ch == '?';\n\t}\n\treturn ch == '?';\n}\n\n// not really well done, since it's only comments that should lex the %> and <%\nconstexpr bool isCommentASPState(int state) noexcept {\n\tbool bResult = false;\n\n\tswitch (state) {\n\tcase SCE_HJ_COMMENT:\n\tcase SCE_HJ_COMMENTLINE:\n\tcase SCE_HJ_COMMENTDOC:\n\tcase SCE_HB_COMMENTLINE:\n\tcase SCE_HP_COMMENTLINE:\n\tcase SCE_HPHP_COMMENT:\n\tcase SCE_HPHP_COMMENTLINE:\n\t\tbResult = true;\n\t\tbreak;\n\tdefault :\n\t\tbreak;\n\t}\n\treturn bResult;\n}\n\nbool classifyAttribHTML(script_mode inScriptType, Sci_PositionU start, Sci_PositionU end, const WordList &keywords, const WordClassifier &classifier, Accessor &styler, const std::string &tag) {\n\tint chAttr = SCE_H_ATTRIBUTEUNKNOWN;\n\tbool isLanguageType = false;\n\tif (IsNumberChar(styler[start])) {\n\t\tchAttr = SCE_H_NUMBER;\n\t} else {\n\t\tconst std::string s = styler.GetRangeLowered(start, end+1);\n\t\tif (keywords.InList(s)) {\n\t\t\tchAttr = SCE_H_ATTRIBUTE;\n\t\t} else {\n\t\t\tint subStyle = classifier.ValueFor(s);\n\t\t\tif (subStyle < 0) {\n\t\t\t\t// Didn't find attribute, check for tag.attribute\n\t\t\t\tconst std::string tagAttribute = tag + \".\" + s;\n\t\t\t\tsubStyle = classifier.ValueFor(tagAttribute);\n\t\t\t}\n\t\t\tif (subStyle >= 0) {\n\t\t\t\tchAttr = subStyle;\n\t\t\t}\n\t\t}\n\n\t\tif (inScriptType == eNonHtmlScript) {\n\t\t\t// see https://html.spec.whatwg.org/multipage/scripting.html#script-processing-model\n\t\t\tif (s == \"type\" || s == \"language\") {\n\t\t\t\tisLanguageType = true;\n\t\t\t}\n\t\t}\n\t}\n\tif ((chAttr == SCE_H_ATTRIBUTEUNKNOWN) && !keywords)\n\t\t// No keywords -> all are known\n\t\tchAttr = SCE_H_ATTRIBUTE;\n\tstyler.ColourTo(end, chAttr);\n\treturn isLanguageType;\n}\n\n// https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-core-concepts\nbool isHTMLCustomElement(const std::string &tag) noexcept {\n\t// check valid HTML custom element name: starts with an ASCII lower alpha and contains hyphen.\n\t// IsUpperOrLowerCase() is used for `html.tags.case.sensitive=1`.\n\tif (tag.length() < 2 || !IsUpperOrLowerCase(tag[0])) {\n\t\treturn false;\n\t}\n\tif (tag.find('-') == std::string::npos) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nint classifyTagHTML(Sci_PositionU start, Sci_PositionU end,\n                    const WordList &keywords, const WordClassifier &classifier, Accessor &styler, bool &tagDontFold,\n                    bool caseSensitive, bool isXml, bool allowScripts,\n                    const std::set<std::string> &nonFoldingTags,\n                    std::string &tag) {\n\ttag.clear();\n\t// Copy after the '<' and stop before ' '\n\tfor (Sci_PositionU cPos = start; cPos <= end; cPos++) {\n\t\tconst char ch = styler[cPos];\n\t\tif (IsASpace(ch)) {\n\t\t\tbreak;\n\t\t}\n\t\tif ((ch != '<') && (ch != '/')) {\n\t\t\ttag.push_back(caseSensitive ? ch : MakeLowerCase(ch));\n\t\t}\n\t}\n\t// if the current language is XML, I can fold any tag\n\t// if the current language is HTML, I don't want to fold certain tags (input, meta, etc.)\n\t//...to find it in the list of no-container-tags\n\ttagDontFold = (!isXml) && (nonFoldingTags.count(tag) > 0);\n\t// No keywords -> all are known\n\tint chAttr = SCE_H_TAGUNKNOWN;\n\tif (!tag.empty() && (tag[0] == '!')) {\n\t\tchAttr = SCE_H_SGML_DEFAULT;\n\t} else if (!keywords || keywords.InList(tag)) {\n\t\tchAttr = SCE_H_TAG;\n\t} else if (!isXml && isHTMLCustomElement(tag)) {\n\t\tchAttr = SCE_H_TAG;\n\t} else {\n\t\tconst int subStyle = classifier.ValueFor(tag);\n\t\tif (subStyle >= 0) {\n\t\t\tchAttr = subStyle;\n\t\t}\n\t}\n\tif (chAttr != SCE_H_TAGUNKNOWN) {\n\t\tstyler.ColourTo(end, chAttr);\n\t}\n\tif (chAttr == SCE_H_TAG) {\n\t\tif (allowScripts && (tag == \"script\")) {\n\t\t\t// check to see if this is a self-closing tag by sniffing ahead\n\t\t\tbool isSelfClose = false;\n\t\t\tfor (Sci_PositionU cPos = end; cPos <= end + maxLengthCheck; cPos++) {\n\t\t\t\tconst char ch = styler.SafeGetCharAt(cPos, '\\0');\n\t\t\t\tif (ch == '\\0' || ch == '>')\n\t\t\t\t\tbreak;\n\t\t\t\tif (ch == '/' && styler.SafeGetCharAt(cPos + 1, '\\0') == '>') {\n\t\t\t\t\tisSelfClose = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// do not enter a script state if the tag self-closed\n\t\t\tif (!isSelfClose)\n\t\t\t\tchAttr = SCE_H_SCRIPT;\n\t\t} else if (!isXml && (tag == \"comment\")) {\n\t\t\tchAttr = SCE_H_COMMENT;\n\t\t}\n\t}\n\treturn chAttr;\n}\n\nvoid classifyWordHTJS(Sci_PositionU start, Sci_PositionU end,\n                             const WordList &keywords, const WordClassifier &classifier, const WordClassifier &classifierServer, Accessor &styler, script_mode inScriptType) {\n\tconst std::string s = styler.GetRange(start, end+1);\n\tint chAttr = SCE_HJ_WORD;\n\tconst bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1]));\n\tif (wordIsNumber) {\n\t\tchAttr = SCE_HJ_NUMBER;\n\t} else if (keywords.InList(s)) {\n\t\tchAttr = SCE_HJ_KEYWORD;\n\t} else {\n\t\tconst int subStyle = (inScriptType == eNonHtmlScript) ? classifier.ValueFor(s) : classifierServer.ValueFor(s);\n\t\tif (subStyle >= 0) {\n\t\t\tchAttr = subStyle;\n\t\t}\n\t}\n\n\tstyler.ColourTo(end, statePrintForState(chAttr, inScriptType));\n}\n\nint classifyWordHTVB(Sci_PositionU start, Sci_PositionU end, const WordList &keywords, const WordClassifier &classifier, Accessor &styler, script_mode inScriptType) {\n\tint chAttr = SCE_HB_IDENTIFIER;\n\tconst bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');\n\tif (wordIsNumber) {\n\t\tchAttr = SCE_HB_NUMBER;\n\t} else {\n\t\tconst std::string s = styler.GetRangeLowered(start, end+1);\n\t\tif (keywords.InList(s)) {\n\t\t\tchAttr = SCE_HB_WORD;\n\t\t\tif (s == \"rem\")\n\t\t\t\tchAttr = SCE_HB_COMMENTLINE;\n\t\t} else {\n\t\t\tconst int subStyle = classifier.ValueFor(s);\n\t\t\tif (subStyle >= 0) {\n\t\t\t\tchAttr = subStyle;\n\t\t\t}\n\t\t}\n\t}\n\tstyler.ColourTo(end, statePrintForState(chAttr, inScriptType));\n\tif (chAttr == SCE_HB_COMMENTLINE)\n\t\treturn SCE_HB_COMMENTLINE;\n\telse\n\t\treturn SCE_HB_DEFAULT;\n}\n\nvoid classifyWordHTPy(Sci_PositionU start, Sci_PositionU end, const WordList &keywords, const WordClassifier &classifier, Accessor &styler, std::string &prevWord, script_mode inScriptType, bool isMako) {\n\tconst bool wordIsNumber = IsADigit(styler[start]);\n\tconst std::string s = styler.GetRange(start, end + 1);\n\tint chAttr = SCE_HP_IDENTIFIER;\n\tif (prevWord == \"class\")\n\t\tchAttr = SCE_HP_CLASSNAME;\n\telse if (prevWord == \"def\")\n\t\tchAttr = SCE_HP_DEFNAME;\n\telse if (wordIsNumber)\n\t\tchAttr = SCE_HP_NUMBER;\n\telse if (keywords.InList(s))\n\t\tchAttr = SCE_HP_WORD;\n\telse if (isMako && (s == \"block\"))\n\t\tchAttr = SCE_HP_WORD;\n\telse {\n\t\tconst int subStyle = classifier.ValueFor(s);\n\t\tif (subStyle >= 0) {\n\t\t\tchAttr = subStyle;\n\t\t}\n\t}\n\tstyler.ColourTo(end, statePrintForState(chAttr, inScriptType));\n\tprevWord = s;\n}\n\n// Update the word colour to default or keyword\n// Called when in a PHP word\nvoid classifyWordHTPHP(Sci_PositionU start, Sci_PositionU end, const WordList &keywords, const WordClassifier &classifier, Accessor &styler) {\n\tint chAttr = SCE_HPHP_DEFAULT;\n\tconst bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.' && start+1 <= end && IsADigit(styler[start+1]));\n\tif (wordIsNumber) {\n\t\tchAttr = SCE_HPHP_NUMBER;\n\t} else {\n\t\tconst std::string s = styler.GetRangeLowered(start, end+1);;\n\t\tif (keywords.InList(s)) {\n\t\t\tchAttr = SCE_HPHP_WORD;\n\t\t} else {\n\t\t\tconst int subStyle = classifier.ValueFor(s);\n\t\t\tif (subStyle >= 0) {\n\t\t\t\tchAttr = subStyle;\n\t\t\t}\n\t\t}\n\t}\n\tstyler.ColourTo(end, chAttr);\n}\n\nbool isWordHSGML(Sci_PositionU start, Sci_PositionU end, const WordList &keywords, const Accessor &styler) {\n\tconst std::string s = styler.GetRange(start, end + 1);\n\treturn keywords.InList(s);\n}\n\nbool isWordCdata(Sci_PositionU start, Sci_PositionU end, const Accessor &styler) {\n\tconst std::string s = styler.GetRange(start, end + 1);\n\treturn s == \"[CDATA[\";\n}\n\n// Return the first state to reach when entering a scripting language\nconstexpr int StateForScript(script_type scriptLanguage) noexcept {\n\tint Result = SCE_HJ_START;\n\tswitch (scriptLanguage) {\n\tcase eScriptVBS:\n\t\tResult = SCE_HB_START;\n\t\tbreak;\n\tcase eScriptPython:\n\t\tResult = SCE_HP_START;\n\t\tbreak;\n\tcase eScriptPHP:\n\t\tResult = SCE_HPHP_DEFAULT;\n\t\tbreak;\n\tcase eScriptXML:\n\t\tResult = SCE_H_TAGUNKNOWN;\n\t\tbreak;\n\tcase eScriptSGML:\n\t\tResult = SCE_H_SGML_DEFAULT;\n\t\tbreak;\n\tcase eScriptComment:\n\t\tResult = SCE_H_COMMENT;\n\t\tbreak;\n\tdefault :\n\t\tbreak;\n\t}\n\treturn Result;\n}\n\nconstexpr int defaultStateForSGML(script_type scriptLanguage) noexcept {\n\treturn (scriptLanguage == eScriptSGMLblock)? SCE_H_SGML_BLOCK_DEFAULT : SCE_H_SGML_DEFAULT;\n}\n\nconstexpr bool issgmlwordchar(int ch) noexcept {\n\treturn !IsASCII(ch) ||\n\t\t(IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#');\n}\n\nconstexpr bool IsPhpWordStart(int ch) noexcept {\n\treturn (IsUpperOrLowerCase(ch) || (ch == '_')) || (ch >= 0x7f);\n}\n\nconstexpr bool IsPhpWordChar(int ch) noexcept {\n\treturn IsADigit(ch) || IsPhpWordStart(ch);\n}\n\nconstexpr bool InTagState(int state) noexcept {\n\treturn AnyOf(state, SCE_H_TAG, SCE_H_TAGUNKNOWN, SCE_H_SCRIPT,\n\t       SCE_H_ATTRIBUTE, SCE_H_ATTRIBUTEUNKNOWN,\n\t       SCE_H_NUMBER, SCE_H_OTHER,\n\t       SCE_H_DOUBLESTRING, SCE_H_SINGLESTRING);\n}\n\nconstexpr bool isLineEnd(int ch) noexcept {\n\treturn ch == '\\r' || ch == '\\n';\n}\n\nbool isMakoBlockEnd(const int ch, const int chNext, const std::string &blockType) noexcept {\n\tif (blockType.empty()) {\n\t\treturn ((ch == '%') && (chNext == '>'));\n\t} else if (InList(blockType, { \"inherit\", \"namespace\", \"include\", \"page\" })) {\n\t\treturn ((ch == '/') && (chNext == '>'));\n\t} else if (blockType == \"%\") {\n\t\tif (ch == '/' && isLineEnd(chNext))\n\t\t\treturn true;\n\t\telse\n\t\t\treturn isLineEnd(ch);\n\t} else if (blockType == \"{\") {\n\t\treturn ch == '}';\n\t} else {\n\t\treturn (ch == '>');\n\t}\n}\n\nbool isDjangoBlockEnd(const int ch, const int chNext, const std::string &blockType) noexcept {\n\tif (blockType.empty()) {\n\t\treturn false;\n\t} else if (blockType == \"%\") {\n\t\treturn ((ch == '%') && (chNext == '}'));\n\t} else if (blockType == \"{\") {\n\t\treturn ((ch == '}') && (chNext == '}'));\n\t} else {\n\t\treturn false;\n\t}\n}\n\nclass PhpNumberState {\n\tenum NumberBase { BASE_10 = 0, BASE_2, BASE_8, BASE_16 };\n\tstatic constexpr const char *const digitList[] = { \"_0123456789\", \"_01\", \"_01234567\", \"_0123456789abcdefABCDEF\" };\n\n\tNumberBase base = BASE_10;\n\tbool decimalPart = false;\n\tbool exponentPart = false;\n\tbool invalid = false;\n\tbool finished = false;\n\n\tbool leadingZero = false;\n\tbool invalidBase8 = false;\n\n\tbool betweenDigits = false;\n\tbool decimalChar = false;\n\tbool exponentChar = false;\n\npublic:\n\t[[nodiscard]] bool isInvalid() const noexcept { return invalid; }\n\t[[nodiscard]] bool isFinished() const noexcept { return finished; }\n\n\tbool init(int ch, int chPlus1, int chPlus2) noexcept {\n\t\tbase = BASE_10;\n\t\tdecimalPart = false;\n\t\texponentPart = false;\n\t\tinvalid = false;\n\t\tfinished = false;\n\n\t\tleadingZero = false;\n\t\tinvalidBase8 = false;\n\n\t\tbetweenDigits = false;\n\t\tdecimalChar = false;\n\t\texponentChar = false;\n\n\t\tif (ch == '.' && strchr(digitList[BASE_10] + !betweenDigits, chPlus1) != nullptr) {\n\t\t\tdecimalPart = true;\n\t\t\tbetweenDigits = true;\n\t\t} else if (ch == '0' && (chPlus1 == 'b' || chPlus1 == 'B')) {\n\t\t\tbase = BASE_2;\n\t\t} else if (ch == '0' && (chPlus1 == 'o' || chPlus1 == 'O')) {\n\t\t\tbase = BASE_8;\n\t\t} else if (ch == '0' && (chPlus1 == 'x' || chPlus1 == 'X')) {\n\t\t\tbase = BASE_16;\n\t\t} else if (strchr(digitList[BASE_10] + !betweenDigits, ch) != nullptr) {\n\t\t\tleadingZero = ch == '0';\n\t\t\tbetweenDigits = true;\n\t\t\tcheck(chPlus1, chPlus2);\n\t\t\tif (finished && leadingZero) {\n\t\t\t\t// single zero should be base 10\n\t\t\t\tbase = BASE_10;\n\t\t\t}\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tbool check(int ch, int chPlus1) noexcept {\n\t\tif (strchr(digitList[base] + !betweenDigits, ch) != nullptr) {\n\t\t\tif (leadingZero) {\n\t\t\t\tinvalidBase8 = invalidBase8 || strchr(digitList[BASE_8] + !betweenDigits, ch) == nullptr;\n\t\t\t}\n\n\t\t\tbetweenDigits = ch != '_';\n\t\t\tdecimalChar = false;\n\t\t\texponentChar = false;\n\t\t} else if (ch == '_') {\n\t\t\tinvalid = true;\n\n\t\t\tbetweenDigits = false;\n\t\t\tdecimalChar = false;\n\t\t\t// exponentChar is unchanged\n\t\t} else if (base == BASE_10 && ch == '.' && (\n\t\t\t\t\t!(decimalPart || exponentPart) || strchr(digitList[BASE_10] + !betweenDigits, chPlus1) != nullptr)\n\t\t\t  ) {\n\t\t\tinvalid = invalid || !betweenDigits || decimalPart || exponentPart;\n\t\t\tdecimalPart = true;\n\n\t\t\tbetweenDigits = false;\n\t\t\tdecimalChar = true;\n\t\t\texponentChar = false;\n\t\t} else if (base == BASE_10 && (ch == 'e' || ch == 'E')) {\n\t\t\tinvalid = invalid || !(betweenDigits || decimalChar) || exponentPart;\n\t\t\texponentPart = true;\n\n\t\t\tbetweenDigits = false;\n\t\t\tdecimalChar = false;\n\t\t\texponentChar = true;\n\t\t} else if (base == BASE_10 && (ch == '-' || ch == '+') && exponentChar) {\n\t\t\tinvalid = invalid || strchr(digitList[BASE_10] + !betweenDigits, chPlus1) == nullptr;\n\n\t\t\tbetweenDigits = false;\n\t\t\tdecimalChar = false;\n\t\t\t// exponentChar is unchanged\n\t\t} else if (IsPhpWordChar(ch)) {\n\t\t\tinvalid = true;\n\n\t\t\tbetweenDigits = false;\n\t\t\tdecimalChar = false;\n\t\t\texponentChar = false;\n\t\t} else {\n\t\t\tinvalid = invalid || !(betweenDigits || decimalChar);\n\t\t\tfinished = true;\n\t\t\tif (base == BASE_10 && leadingZero && !decimalPart && !exponentPart) {\n\t\t\t\tbase = BASE_8;\n\t\t\t\tinvalid = invalid || invalidBase8;\n\t\t\t}\n\t\t}\n\t\treturn finished;\n\t}\n};\n\nconstexpr bool isPHPStringState(int state) noexcept {\n\treturn\n\t    (state == SCE_HPHP_HSTRING) ||\n\t    (state == SCE_HPHP_SIMPLESTRING) ||\n\t    (state == SCE_HPHP_HSTRING_VARIABLE) ||\n\t    (state == SCE_HPHP_COMPLEX_VARIABLE);\n}\n\nconstexpr bool StyleNeedsBacktrack(int state) noexcept {\n\treturn InTagState(state) || isPHPStringState(state);\n}\n\nenum class AllowPHP : int {\n\tNone, // No PHP\n\tPHP, // <?php and <?=\n\tQuestion, // <?\n};\n\nenum class InstructionTag {\n\tNone,\n\tXML,\n\tOpen,// <? ?> short open tag\n\tEcho,// <?= ?> short echo tag\n\tPHP, // <?php ?> standard tag\n};\n\nInstructionTag segIsScriptInstruction(AllowPHP allowPHP, int state, const Accessor &styler, Sci_PositionU start, bool isXml) {\n\tconstexpr std::string_view phpTag = \"php\";\n\tconstexpr std::string_view xmlTag = \"xml\";\n\tconst std::string tag = styler.GetRangeLowered(start, start + phpTag.length());\n\tif (allowPHP != AllowPHP::None) {\n\t\t// Require <?php or <?=\n\t\tif (tag == phpTag) {\n\t\t\treturn InstructionTag::PHP;\n\t\t}\n\t\tif (!tag.empty() && (tag.front() == '=')) {\n\t\t\treturn InstructionTag::Echo;\n\t\t}\n\t}\n\tif (isXml || tag == xmlTag) {\n\t\treturn AnyOf(state, SCE_H_DEFAULT, SCE_H_SGML_BLOCK_DEFAULT)? InstructionTag::XML : InstructionTag::None;\n\t}\n\treturn (allowPHP == AllowPHP::Question) ? InstructionTag::Open : InstructionTag::None;\n}\n\nSci_Position FindPhpStringDelimiter(std::string &phpStringDelimiter, Sci_Position i, const Sci_Position lengthDoc, Accessor &styler, bool &isSimpleString) {\n\tconst Sci_Position beginning = i - 1;\n\tbool isQuoted = false;\n\n\twhile (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\\t'))\n\t\ti++;\n\tchar ch = styler.SafeGetCharAt(i);\n\tconst char chNext = styler.SafeGetCharAt(i + 1);\n\tphpStringDelimiter.clear();\n\tif (!IsPhpWordStart(ch)) {\n\t\tif ((ch == '\\'' || ch == '\\\"') && IsPhpWordStart(chNext)) {\n\t\t\tisSimpleString = ch == '\\'';\n\t\t\tisQuoted = true;\n\t\t\ti++;\n\t\t\tch = chNext;\n\t\t} else {\n\t\t\treturn beginning;\n\t\t}\n\t}\n\tphpStringDelimiter.push_back(ch);\n\ti++;\n\tSci_Position j = i;\n\tfor (; j < lengthDoc && !isLineEnd(styler[j]); j++) {\n\t\tif (!IsPhpWordChar(styler[j]) && isQuoted) {\n\t\t\tif (((isSimpleString && styler[j] == '\\'') || (!isSimpleString && styler[j] == '\\\"')) && isLineEnd(styler.SafeGetCharAt(j + 1))) {\n\t\t\t\tisQuoted = false;\n\t\t\t\tj++;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tphpStringDelimiter.clear();\n\t\t\t\treturn beginning;\n\t\t\t}\n\t\t}\n\t\tphpStringDelimiter.push_back(styler[j]);\n\t}\n\tif (isQuoted) {\n\t\tphpStringDelimiter.clear();\n\t\treturn beginning;\n\t}\n\treturn j - 1;\n}\n\n// Options used for LexerHTML\nstruct OptionsHTML {\n\tint aspDefaultLanguage = eScriptJS;\n\tbool caseSensitive = false;\n\tbool allowScripts = true;\n\tAllowPHP allowPHPinXML = AllowPHP::Question;\n\tAllowPHP allowPHPinHTML = AllowPHP::Question;\n\tbool isMako = false;\n\tbool isDjango = false;\n\tbool allowASPinXML = true;\n\tbool allowASPinHTML = true;\n\tbool fold = false;\n\tbool foldHTML = false;\n\tbool foldHTMLPreprocessor = true;\n\tbool foldCompact = true;\n\tbool foldComment = false;\n\tbool foldHeredoc = false;\n\tbool foldXmlAtTagOpen = false;\n};\n\nconst char * const htmlWordListDesc[] = {\n\t\"HTML elements and attributes\",\n\t\"JavaScript keywords\",\n\t\"VBScript keywords\",\n\t\"Python keywords\",\n\t\"PHP keywords\",\n\t\"SGML and DTD keywords\",\n\tnullptr,\n};\n\nconst char * const phpscriptWordListDesc[] = {\n\t\"\", //Unused\n\t\"\", //Unused\n\t\"\", //Unused\n\t\"\", //Unused\n\t\"PHP keywords\",\n\t\"\", //Unused\n\tnullptr,\n};\n\nstruct OptionSetHTML : public OptionSet<OptionsHTML> {\n\texplicit OptionSetHTML(bool isPHPScript_) {\n\n\t\tDefineProperty(\"asp.default.language\", &OptionsHTML::aspDefaultLanguage,\n\t\t\t\"Script in ASP code is initially assumed to be in JavaScript. \"\n\t\t\t\"To change this to VBScript set asp.default.language to 2. Python is 3.\");\n\n\t\tDefineProperty(\"html.tags.case.sensitive\", &OptionsHTML::caseSensitive,\n\t\t\t\"For XML and HTML, setting this property to 1 will make tags match in a case \"\n\t\t\t\"sensitive way which is the expected behaviour for XML and XHTML.\");\n\n\t\tDefineProperty(\"lexer.xml.allow.scripts\", &OptionsHTML::allowScripts,\n\t\t\t\"Set to 0 to disable scripts in XML.\");\n\n\t\tDefineProperty(\"lexer.xml.allow.php\", &OptionsHTML::allowPHPinXML,\n\t\t\t\"Set to 0 to disable PHP in XML, 1 to accept <?php and <?=, 2 to also accept <?.\"\n\t\t\t\"The default is 2.\");\n\n\t\tDefineProperty(\"lexer.html.allow.php\", &OptionsHTML::allowPHPinHTML,\n\t\t\t\"Set to 0 to disable PHP in HTML, 1 to accept <?php and <?=, 2 to also accept <?.\"\n\t\t\t\"The default is 2.\");\n\n\t\tDefineProperty(\"lexer.html.mako\", &OptionsHTML::isMako,\n\t\t\t\"Set to 1 to enable the mako template language.\");\n\n\t\tDefineProperty(\"lexer.html.django\", &OptionsHTML::isDjango,\n\t\t\t\"Set to 1 to enable the django template language.\");\n\n\t\tDefineProperty(\"lexer.xml.allow.asp\", &OptionsHTML::allowASPinXML,\n\t\t\t\"Set to 0 to disable ASP in XML.\");\n\n\t\tDefineProperty(\"lexer.html.allow.asp\", &OptionsHTML::allowASPinHTML,\n\t\t\t\"Set to 0 to disable ASP in HTML.\");\n\n\t\tDefineProperty(\"fold\", &OptionsHTML::fold);\n\n\t\tDefineProperty(\"fold.html\", &OptionsHTML::foldHTML,\n\t\t\t\"Folding is turned on or off for HTML and XML files with this option. \"\n\t\t\t\"The fold option must also be on for folding to occur.\");\n\n\t\tDefineProperty(\"fold.html.preprocessor\", &OptionsHTML::foldHTMLPreprocessor,\n\t\t\t\"Folding is turned on or off for scripts embedded in HTML files with this option. \"\n\t\t\t\"The default is on.\");\n\n\t\tDefineProperty(\"fold.compact\", &OptionsHTML::foldCompact);\n\n\t\tDefineProperty(\"fold.hypertext.comment\", &OptionsHTML::foldComment,\n\t\t\t\"Allow folding for comments in scripts embedded in HTML. \"\n\t\t\t\"The default is off.\");\n\n\t\tDefineProperty(\"fold.hypertext.heredoc\", &OptionsHTML::foldHeredoc,\n\t\t\t\"Allow folding for heredocs in scripts embedded in HTML. \"\n\t\t\t\"The default is off.\");\n\n\t\tDefineProperty(\"fold.xml.at.tag.open\", &OptionsHTML::foldXmlAtTagOpen,\n\t\t\t\"Enable folding for XML at the start of open tag. \"\n\t\t\t\"The default is off.\");\n\n\t\tDefineWordListSets(isPHPScript_ ? phpscriptWordListDesc : htmlWordListDesc);\n\t}\n};\n\nconstexpr char styleSubable[] = { SCE_H_TAG, SCE_H_ATTRIBUTE, SCE_HJ_WORD, SCE_HJA_WORD, SCE_HB_WORD, SCE_HP_WORD, SCE_HPHP_WORD, 0 };\n// Allow normal styles to be contiguous using 0x80 to 0xBF by assigning sub-styles from 0xC0 to 0xFF\nconstexpr int SubStylesHTML = 0xC0;\n\nconst LexicalClass lexicalClassesHTML[] = {\n\t// Lexer HTML SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_:\n\t0, \"SCE_H_DEFAULT\", \"default\", \"Text\",\n\t1, \"SCE_H_TAG\", \"tag\", \"Tags\",\n\t2, \"SCE_H_TAGUNKNOWN\", \"error tag\", \"Unknown Tags\",\n\t3, \"SCE_H_ATTRIBUTE\", \"attribute\", \"Attributes\",\n\t4, \"SCE_H_ATTRIBUTEUNKNOWN\", \"error attribute\", \"Unknown Attributes\",\n\t5, \"SCE_H_NUMBER\", \"literal numeric\", \"Numbers\",\n\t6, \"SCE_H_DOUBLESTRING\", \"literal string\", \"Double quoted strings\",\n\t7, \"SCE_H_SINGLESTRING\", \"literal string\", \"Single quoted strings\",\n\t8, \"SCE_H_OTHER\", \"tag operator\", \"Other inside tag, including space and '='\",\n\t9, \"SCE_H_COMMENT\", \"comment\", \"Comment\",\n\t10, \"SCE_H_ENTITY\", \"literal\", \"Entities\",\n\t11, \"SCE_H_TAGEND\", \"tag\", \"XML style tag ends '/>'\",\n\t12, \"SCE_H_XMLSTART\", \"identifier\", \"XML identifier start '<?'\",\n\t13, \"SCE_H_XMLEND\", \"identifier\", \"XML identifier end '?>'\",\n\t14, \"SCE_H_SCRIPT\", \"error\", \"Internal state which should never be visible\",\n\t15, \"SCE_H_ASP\", \"preprocessor\", \"ASP <% ... %>\",\n\t16, \"SCE_H_ASPAT\", \"preprocessor\", \"ASP <% ... %>\",\n\t17, \"SCE_H_CDATA\", \"literal\", \"CDATA\",\n\t18, \"SCE_H_QUESTION\", \"preprocessor\", \"PHP\",\n\t19, \"SCE_H_VALUE\", \"literal string\", \"Unquoted values\",\n\t20, \"SCE_H_XCCOMMENT\", \"comment\", \"ASP.NET, JSP Comment <%-- ... --%>\",\n\t21, \"SCE_H_SGML_DEFAULT\", \"default\", \"SGML tags <! ... >\",\n\t22, \"SCE_H_SGML_COMMAND\", \"preprocessor\", \"SGML command\",\n\t23, \"SCE_H_SGML_1ST_PARAM\", \"preprocessor\", \"SGML 1st param\",\n\t24, \"SCE_H_SGML_DOUBLESTRING\", \"literal string\", \"SGML double string\",\n\t25, \"SCE_H_SGML_SIMPLESTRING\", \"literal string\", \"SGML single string\",\n\t26, \"SCE_H_SGML_ERROR\", \"error\", \"SGML error\",\n\t27, \"SCE_H_SGML_SPECIAL\", \"literal\", \"SGML special (#XXXX type)\",\n\t28, \"SCE_H_SGML_ENTITY\", \"literal\", \"SGML entity\",\n\t29, \"SCE_H_SGML_COMMENT\", \"comment\", \"SGML comment\",\n\t30, \"SCE_H_SGML_1ST_PARAM_COMMENT\", \"error comment\", \"SGML first parameter - lexer internal. It is an error if any text is in this style.\",\n\t31, \"SCE_H_SGML_BLOCK_DEFAULT\", \"default\", \"SGML block\",\n\t32, \"\", \"predefined\", \"\",\n\t33, \"\", \"predefined\", \"\",\n\t34, \"\", \"predefined\", \"\",\n\t35, \"\", \"predefined\", \"\",\n\t36, \"\", \"predefined\", \"\",\n\t37, \"\", \"predefined\", \"\",\n\t38, \"\", \"predefined\", \"\",\n\t39, \"\", \"predefined\", \"\",\n\t40, \"SCE_HJ_START\", \"client javascript default\", \"JS Start - allows eol filled background to not start on same line as SCRIPT tag\",\n\t41, \"SCE_HJ_DEFAULT\", \"client javascript default\", \"JS Default\",\n\t42, \"SCE_HJ_COMMENT\", \"client javascript comment\", \"JS Comment\",\n\t43, \"SCE_HJ_COMMENTLINE\", \"client javascript comment line\", \"JS Line Comment\",\n\t44, \"SCE_HJ_COMMENTDOC\", \"client javascript comment documentation\", \"JS Doc comment\",\n\t45, \"SCE_HJ_NUMBER\", \"client javascript literal numeric\", \"JS Number\",\n\t46, \"SCE_HJ_WORD\", \"client javascript identifier\", \"JS Word\",\n\t47, \"SCE_HJ_KEYWORD\", \"client javascript keyword\", \"JS Keyword\",\n\t48, \"SCE_HJ_DOUBLESTRING\", \"client javascript literal string\", \"JS Double quoted string\",\n\t49, \"SCE_HJ_SINGLESTRING\", \"client javascript literal string\", \"JS Single quoted string\",\n\t50, \"SCE_HJ_SYMBOLS\", \"client javascript operator\", \"JS Symbols\",\n\t51, \"SCE_HJ_STRINGEOL\", \"client javascript error literal string\", \"JavaScript EOL\",\n\t52, \"SCE_HJ_REGEX\", \"client javascript literal regex\", \"JavaScript RegEx\",\n\t53, \"SCE_HJ_TEMPLATELITERAL\", \"client javascript literal template\", \"JS Template Literal\",\n\t54, \"\", \"unused\", \"\",\n\t55, \"SCE_HJA_START\", \"server javascript default\", \"JS Start - allows eol filled background to not start on same line as SCRIPT tag\",\n\t56, \"SCE_HJA_DEFAULT\", \"server javascript default\", \"JS Default\",\n\t57, \"SCE_HJA_COMMENT\", \"server javascript comment\", \"JS Comment\",\n\t58, \"SCE_HJA_COMMENTLINE\", \"server javascript comment line\", \"JS Line Comment\",\n\t59, \"SCE_HJA_COMMENTDOC\", \"server javascript comment documentation\", \"JS Doc comment\",\n\t60, \"SCE_HJA_NUMBER\", \"server javascript literal numeric\", \"JS Number\",\n\t61, \"SCE_HJA_WORD\", \"server javascript identifier\", \"JS Word\",\n\t62, \"SCE_HJA_KEYWORD\", \"server javascript keyword\", \"JS Keyword\",\n\t63, \"SCE_HJA_DOUBLESTRING\", \"server javascript literal string\", \"JS Double quoted string\",\n\t64, \"SCE_HJA_SINGLESTRING\", \"server javascript literal string\", \"JS Single quoted string\",\n\t65, \"SCE_HJA_SYMBOLS\", \"server javascript operator\", \"JS Symbols\",\n\t66, \"SCE_HJA_STRINGEOL\", \"server javascript error literal string\", \"JavaScript EOL\",\n\t67, \"SCE_HJA_REGEX\", \"server javascript literal regex\", \"JavaScript RegEx\",\n\t68, \"SCE_HJA_TEMPLATELITERAL\", \"server javascript literal template\", \"JS Template Literal\",\n\t69, \"\", \"unused\", \"\",\n\t70, \"SCE_HB_START\", \"client basic default\", \"Start\",\n\t71, \"SCE_HB_DEFAULT\", \"client basic default\", \"Default\",\n\t72, \"SCE_HB_COMMENTLINE\", \"client basic comment line\", \"Comment\",\n\t73, \"SCE_HB_NUMBER\", \"client basic literal numeric\", \"Number\",\n\t74, \"SCE_HB_WORD\", \"client basic keyword\", \"KeyWord\",\n\t75, \"SCE_HB_STRING\", \"client basic literal string\", \"String\",\n\t76, \"SCE_HB_IDENTIFIER\", \"client basic identifier\", \"Identifier\",\n\t77, \"SCE_HB_STRINGEOL\", \"client basic literal string\", \"Unterminated string\",\n\t78, \"\", \"unused\", \"\",\n\t79, \"\", \"unused\", \"\",\n\t80, \"SCE_HBA_START\", \"server basic default\", \"Start\",\n\t81, \"SCE_HBA_DEFAULT\", \"server basic default\", \"Default\",\n\t82, \"SCE_HBA_COMMENTLINE\", \"server basic comment line\", \"Comment\",\n\t83, \"SCE_HBA_NUMBER\", \"server basic literal numeric\", \"Number\",\n\t84, \"SCE_HBA_WORD\", \"server basic keyword\", \"KeyWord\",\n\t85, \"SCE_HBA_STRING\", \"server basic literal string\", \"String\",\n\t86, \"SCE_HBA_IDENTIFIER\", \"server basic identifier\", \"Identifier\",\n\t87, \"SCE_HBA_STRINGEOL\", \"server basic literal string\", \"Unterminated string\",\n\t88, \"\", \"unused\", \"\",\n\t89, \"\", \"unused\", \"\",\n\t90, \"SCE_HP_START\", \"client python default\", \"Embedded Python\",\n\t91, \"SCE_HP_DEFAULT\", \"client python default\", \"Embedded Python\",\n\t92, \"SCE_HP_COMMENTLINE\", \"client python comment line\", \"Comment\",\n\t93, \"SCE_HP_NUMBER\", \"client python literal numeric\", \"Number\",\n\t94, \"SCE_HP_STRING\", \"client python literal string\", \"String\",\n\t95, \"SCE_HP_CHARACTER\", \"client python literal string character\", \"Single quoted string\",\n\t96, \"SCE_HP_WORD\", \"client python keyword\", \"Keyword\",\n\t97, \"SCE_HP_TRIPLE\", \"client python literal string\", \"Triple quotes\",\n\t98, \"SCE_HP_TRIPLEDOUBLE\", \"client python literal string\", \"Triple double quotes\",\n\t99, \"SCE_HP_CLASSNAME\", \"client python identifier\", \"Class name definition\",\n\t100, \"SCE_HP_DEFNAME\", \"client python identifier\", \"Function or method name definition\",\n\t101, \"SCE_HP_OPERATOR\", \"client python operator\", \"Operators\",\n\t102, \"SCE_HP_IDENTIFIER\", \"client python identifier\", \"Identifiers\",\n\t103, \"\", \"unused\", \"\",\n\t104, \"SCE_HPHP_COMPLEX_VARIABLE\", \"server php identifier\", \"PHP complex variable\",\n\t105, \"SCE_HPA_START\", \"server python default\", \"ASP Python\",\n\t106, \"SCE_HPA_DEFAULT\", \"server python default\", \"ASP Python\",\n\t107, \"SCE_HPA_COMMENTLINE\", \"server python comment line\", \"Comment\",\n\t108, \"SCE_HPA_NUMBER\", \"server python literal numeric\", \"Number\",\n\t109, \"SCE_HPA_STRING\", \"server python literal string\", \"String\",\n\t110, \"SCE_HPA_CHARACTER\", \"server python literal string character\", \"Single quoted string\",\n\t111, \"SCE_HPA_WORD\", \"server python keyword\", \"Keyword\",\n\t112, \"SCE_HPA_TRIPLE\", \"server python literal string\", \"Triple quotes\",\n\t113, \"SCE_HPA_TRIPLEDOUBLE\", \"server python literal string\", \"Triple double quotes\",\n\t114, \"SCE_HPA_CLASSNAME\", \"server python identifier\", \"Class name definition\",\n\t115, \"SCE_HPA_DEFNAME\", \"server python identifier\", \"Function or method name definition\",\n\t116, \"SCE_HPA_OPERATOR\", \"server python operator\", \"Operators\",\n\t117, \"SCE_HPA_IDENTIFIER\", \"server python identifier\", \"Identifiers\",\n\t118, \"SCE_HPHP_DEFAULT\", \"server php default\", \"Default\",\n\t119, \"SCE_HPHP_HSTRING\", \"server php literal string\", \"Double quoted String\",\n\t120, \"SCE_HPHP_SIMPLESTRING\", \"server php literal string\", \"Single quoted string\",\n\t121, \"SCE_HPHP_WORD\", \"server php keyword\", \"Keyword\",\n\t122, \"SCE_HPHP_NUMBER\", \"server php literal numeric\", \"Number\",\n\t123, \"SCE_HPHP_VARIABLE\", \"server php identifier\", \"Variable\",\n\t124, \"SCE_HPHP_COMMENT\", \"server php comment\", \"Comment\",\n\t125, \"SCE_HPHP_COMMENTLINE\", \"server php comment line\", \"One line comment\",\n\t126, \"SCE_HPHP_HSTRING_VARIABLE\", \"server php literal string identifier\", \"PHP variable in double quoted string\",\n\t127, \"SCE_HPHP_OPERATOR\", \"server php operator\", \"PHP operator\",\n};\n\nconst LexicalClass lexicalClassesXML[] = {\n\t// Lexer.Secondary XML SCLEX_XML SCE_H_:\n\t0, \"SCE_H_DEFAULT\", \"default\", \"Default\",\n\t1, \"SCE_H_TAG\", \"tag\", \"Tags\",\n\t2, \"SCE_H_TAGUNKNOWN\", \"error tag\", \"Unknown Tags\",\n\t3, \"SCE_H_ATTRIBUTE\", \"attribute\", \"Attributes\",\n\t4, \"SCE_H_ATTRIBUTEUNKNOWN\", \"error attribute\", \"Unknown Attributes\",\n\t5, \"SCE_H_NUMBER\", \"literal numeric\", \"Numbers\",\n\t6, \"SCE_H_DOUBLESTRING\", \"literal string\", \"Double quoted strings\",\n\t7, \"SCE_H_SINGLESTRING\", \"literal string\", \"Single quoted strings\",\n\t8, \"SCE_H_OTHER\", \"tag operator\", \"Other inside tag, including space and '='\",\n\t9, \"SCE_H_COMMENT\", \"comment\", \"Comment\",\n\t10, \"SCE_H_ENTITY\", \"literal\", \"Entities\",\n\t11, \"SCE_H_TAGEND\", \"tag\", \"XML style tag ends '/>'\",\n\t12, \"SCE_H_XMLSTART\", \"identifier\", \"XML identifier start '<?'\",\n\t13, \"SCE_H_XMLEND\", \"identifier\", \"XML identifier end '?>'\",\n\t14, \"\", \"unused\", \"\",\n\t15, \"\", \"unused\", \"\",\n\t16, \"\", \"unused\", \"\",\n\t17, \"SCE_H_CDATA\", \"literal\", \"CDATA\",\n\t18, \"SCE_H_QUESTION\", \"preprocessor\", \"Question\",\n\t19, \"SCE_H_VALUE\", \"literal string\", \"Unquoted Value\",\n\t20, \"\", \"unused\", \"\",\n\t21, \"SCE_H_SGML_DEFAULT\", \"default\", \"SGML tags <! ... >\",\n\t22, \"SCE_H_SGML_COMMAND\", \"preprocessor\", \"SGML command\",\n\t23, \"SCE_H_SGML_1ST_PARAM\", \"preprocessor\", \"SGML 1st param\",\n\t24, \"SCE_H_SGML_DOUBLESTRING\", \"literal string\", \"SGML double string\",\n\t25, \"SCE_H_SGML_SIMPLESTRING\", \"literal string\", \"SGML single string\",\n\t26, \"SCE_H_SGML_ERROR\", \"error\", \"SGML error\",\n\t27, \"SCE_H_SGML_SPECIAL\", \"literal\", \"SGML special (#XXXX type)\",\n\t28, \"SCE_H_SGML_ENTITY\", \"literal\", \"SGML entity\",\n\t29, \"SCE_H_SGML_COMMENT\", \"comment\", \"SGML comment\",\n\t30, \"\", \"unused\", \"\",\n\t31, \"SCE_H_SGML_BLOCK_DEFAULT\", \"default\", \"SGML block\",\n};\n\nconst char * const tagsThatDoNotFold[] = {\n\t\"area\",\n\t\"base\",\n\t\"basefont\",\n\t\"br\",\n\t\"col\",\n\t\"command\",\n\t\"embed\",\n\t\"frame\",\n\t\"hr\",\n\t\"img\",\n\t\"input\",\n\t\"isindex\",\n\t\"keygen\",\n\t\"link\",\n\t\"meta\",\n\t\"param\",\n\t\"source\",\n\t\"track\",\n\t\"wbr\"\n};\n\n}\n\nclass LexerHTML : public DefaultLexer {\n\tbool isXml;\n\tbool isPHPScript;\n\tWordList keywordsHTML;\n\tWordList keywordsJS;\n\tWordList keywordsVB;\n\tWordList keywordsPy;\n\tWordList keywordsPHP;\n\tWordList keywordsSGML; // SGML (DTD) keywords\n\tOptionsHTML options;\n\tOptionSetHTML osHTML;\n\tstd::set<std::string> nonFoldingTags;\n\tSubStyles subStyles{styleSubable,SubStylesHTML,SubStylesAvailable,0};\npublic:\n\texplicit LexerHTML(bool isXml_, bool isPHPScript_) :\n\t\tDefaultLexer(\n\t\t\tisXml_ ? \"xml\" : (isPHPScript_ ? \"phpscript\" : \"hypertext\"),\n\t\t\tisXml_ ? SCLEX_XML : (isPHPScript_ ? SCLEX_PHPSCRIPT : SCLEX_HTML),\n\t\t\tisXml_ ?  lexicalClassesXML : lexicalClassesHTML,\n\t\t\tisXml_ ?  std::size(lexicalClassesXML) : std::size(lexicalClassesHTML)),\n\t\tisXml(isXml_),\n\t\tisPHPScript(isPHPScript_),\n\t\tosHTML(isPHPScript_),\n\t\tnonFoldingTags(std::begin(tagsThatDoNotFold), std::end(tagsThatDoNotFold)) {\n\t}\n\t~LexerHTML() override {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osHTML.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osHTML.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osHTML.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osHTML.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osHTML.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\t// No Fold as all folding performs in Lex.\n\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {\n\t\treturn subStyles.Allocate(styleBase, numberStyles);\n\t}\n\tint SCI_METHOD SubStylesStart(int styleBase) override {\n\t\treturn subStyles.Start(styleBase);\n\t}\n\tint SCI_METHOD SubStylesLength(int styleBase) override {\n\t\treturn subStyles.Length(styleBase);\n\t}\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override {\n\t\tconst int styleBase = subStyles.BaseStyle(subStyle);\n\t\treturn styleBase;\n\t}\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) override {\n\t\treturn style;\n\t}\n\tvoid SCI_METHOD FreeSubStyles() override {\n\t\tsubStyles.Free();\n\t}\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {\n\t\tconst int styleBase = subStyles.BaseStyle(style);\n\t\tconst bool lowerCase = AnyOf(styleBase, SCE_H_TAG, SCE_H_ATTRIBUTE, SCE_HB_WORD);\n\t\tsubStyles.SetIdentifiers(style, identifiers, lowerCase);\n\t}\n\tint SCI_METHOD DistanceToSecondaryStyles() override {\n\t\treturn 0;\n\t}\n\tconst char *SCI_METHOD GetSubStyleBases() override {\n\t\treturn styleSubable;\n\t}\n\n\tstatic ILexer5 *LexerFactoryHTML() {\n\t\treturn new LexerHTML(false, false);\n\t}\n\tstatic ILexer5 *LexerFactoryXML() {\n\t\treturn new LexerHTML(true, false);\n\t}\n\tstatic ILexer5 *LexerFactoryPHPScript() {\n\t\treturn new LexerHTML(false, true);\n\t}\n};\n\nSci_Position SCI_METHOD LexerHTML::PropertySet(const char *key, const char *val) {\n\tif (osHTML.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerHTML::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tbool lowerCase = false;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywordsHTML;\n\t\tlowerCase = true;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywordsJS;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywordsVB;\n\t\tlowerCase = true;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywordsPy;\n\t\tbreak;\n\tcase 4:\n\t\twordListN = &keywordsPHP;\n\t\tbreak;\n\tcase 5:\n\t\twordListN = &keywordsSGML;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl, lowerCase)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\n\tconst WordClassifier &classifierTags = subStyles.Classifier(SCE_H_TAG);\n\tconst WordClassifier &classifierAttributes = subStyles.Classifier(SCE_H_ATTRIBUTE);\n\tconst WordClassifier &classifierJavaScript = subStyles.Classifier(SCE_HJ_WORD);\n\tconst WordClassifier &classifierJavaScriptServer = subStyles.Classifier(SCE_HJA_WORD);\n\tconst WordClassifier &classifierBasic = subStyles.Classifier(SCE_HB_WORD);\n\tconst WordClassifier &classifierPython = subStyles.Classifier(SCE_HP_WORD);\n\tconst WordClassifier &classifierPHP = subStyles.Classifier(SCE_HPHP_WORD);\n\n\tif (isPHPScript && (startPos == 0)) {\n\t\tinitStyle = SCE_HPHP_DEFAULT;\n\t}\n\tstd::string lastTag;\n\tstd::string prevWord;\n\tPhpNumberState phpNumber;\n\tstd::string phpStringDelimiter;\n\tint StateToPrint = initStyle;\n\tint state = stateForPrintState(StateToPrint);\n\tstd::string makoBlockType;\n\tint makoComment = 0;\n\tstd::string djangoBlockType;\n\t// If inside a tag, it may be a script tag, so reread from the start of line starting tag to ensure any language tags are seen\n\t// PHP string can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState\n\tif (StyleNeedsBacktrack(state)) {\n\t\twhile ((startPos > 0) && (StyleNeedsBacktrack(styler.StyleIndexAt(startPos - 1)))) {\n\t\t\tconst Sci_Position backLineStart = styler.LineStart(styler.GetLine(startPos-1));\n\t\t\tlength += startPos - backLineStart;\n\t\t\tstartPos = backLineStart;\n\t\t}\n\t\tif (startPos > 0) {\n\t\t\tstate = styler.StyleIndexAt(startPos - 1);\n\t\t} else {\n\t\t\tstate = isPHPScript ? SCE_HPHP_DEFAULT : SCE_H_DEFAULT;\n\t\t}\n\t}\n\tstyler.StartAt(startPos);\n\n\t/* Nothing handles getting out of these, so we need not start in any of them.\n\t * As we're at line start and they can't span lines, we'll re-detect them anyway */\n\tswitch (state) {\n\t\tcase SCE_H_QUESTION:\n\t\tcase SCE_H_XMLSTART:\n\t\tcase SCE_H_XMLEND:\n\t\tcase SCE_H_ASP:\n\t\t\tstate = SCE_H_DEFAULT;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint lineState;\n\tif (lineCurrent > 0) {\n\t\tlineState = styler.GetLineState(lineCurrent-1);\n\t} else {\n\t\t// Default client and ASP scripting language is JavaScript\n\t\tlineState = eScriptJS << 8;\n\t\tlineState |= options.aspDefaultLanguage << 4;\n\t}\n\tscript_mode inScriptType = static_cast<script_mode>((lineState >> 0) & 0x03); // 2 bits of scripting mode\n\n\tbool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag\n\tbool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag\n\tbool tagDontFold = false; //some HTML tags should not be folded\n\tscript_type aspScript = static_cast<script_type>((lineState >> 4) & 0x0F); // 4 bits of script name\n\tscript_type clientScript = static_cast<script_type>((lineState >> 8) & 0x0F); // 4 bits of script name\n\tint beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state\n\tbool isLanguageType = (lineState >> 20) & 1; // type or language attribute for script tag\n\tint sgmlBlockLevel = (lineState >> 21);\n\n\tscript_type scriptLanguage = ScriptOfState(state);\n\t// If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment\n\tif (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) {\n\t\tscriptLanguage = eScriptComment;\n\t}\n\tscript_type beforeLanguage = ScriptOfState(beforePreProc);\n\tconst bool foldHTML = options.foldHTML;\n\tconst bool fold = foldHTML && options.fold;\n\tconst bool foldHTMLPreprocessor = foldHTML && options.foldHTMLPreprocessor;\n\tconst bool foldCompact = options.foldCompact;\n\tconst bool foldComment = fold && options.foldComment;\n\tconst bool foldHeredoc = fold && options.foldHeredoc;\n\tconst bool foldXmlAtTagOpen = isXml && fold && options.foldXmlAtTagOpen;\n\tconst bool caseSensitive = options.caseSensitive;\n\tconst bool allowScripts = options.allowScripts;\n\tconst AllowPHP allowPHP = isXml ? options.allowPHPinXML : options.allowPHPinHTML;\n\tconst bool isMako = options.isMako;\n\tconst bool isDjango = options.isDjango;\n\tconst bool allowASP = (isXml ? options.allowASPinXML : options.allowASPinHTML) && !isMako && !isDjango;\n\tconst CharacterSet setHTMLWord(CharacterSet::setAlphaNum, \".-_:!#\", true);\n\tconst CharacterSet setTagContinue(CharacterSet::setAlphaNum, \".-_:!#[\", true);\n\tconst CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, \".-_:!#/\", true);\n\t// TODO: also handle + and - (except if they're part of ++ or --) and return keywords\n\tconst CharacterSet setOKBeforeJSRE(CharacterSet::setNone, \"([{=,:;!%^&*|?~> \");\n\t// Only allow [A-Za-z0-9.#-_:] in entities\n\tconst CharacterSet setEntity(CharacterSet::setAlphaNum, \".#-_:\");\n\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tSci_Position visibleChars = 0;\n\tint lineStartVisibleChars = 0;\n\n\tint chPrev = ' ';\n\tint ch = ' ';\n\tint chPrevNonWhite = ' ';\n\t// look back to set chPrevNonWhite properly for better regex colouring\n\tif (scriptLanguage == eScriptJS && startPos > 0) {\n\t\tSci_Position back = startPos;\n\t\tint style = 0;\n\t\twhile (--back) {\n\t\t\tstyle = styler.StyleIndexAt(back);\n\t\t\tif (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC)\n\t\t\t\t// includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE\n\t\t\t\tbreak;\n\t\t}\n\t\tif (style == SCE_HJ_SYMBOLS) {\n\t\t\tchPrevNonWhite = SafeGetUnsignedCharAt(styler, back);\n\t\t}\n\t}\n\n\tstyler.StartSegment(startPos);\n\tconst Sci_Position lengthDoc = startPos + length;\n\tfor (Sci_Position i = startPos; i < lengthDoc; i++) {\n\t\tconst int chPrev2 = chPrev;\n\t\tchPrev = ch;\n\t\tif (!IsASpace(ch) && state != SCE_HJ_COMMENT &&\n\t\t\tstate != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC)\n\t\t\tchPrevNonWhite = ch;\n\t\tch = static_cast<unsigned char>(styler[i]);\n\t\tint chNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\tconst int chNext2 = SafeGetUnsignedCharAt(styler, i + 2);\n\n\t\t// Handle DBCS codepages\n\t\tif (styler.IsLeadByte(static_cast<char>(ch))) {\n\t\t\tchPrev = ' ';\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((!IsASpace(ch) || !foldCompact) && fold)\n\t\t\tvisibleChars++;\n\t\tif (!IsASpace(ch))\n\t\t\tlineStartVisibleChars++;\n\n\t\t// decide what is the current state to print (depending of the script tag)\n\t\tStateToPrint = statePrintForState(state, inScriptType);\n\n\t\t// handle script folding\n\t\tif (fold) {\n\t\t\tswitch (scriptLanguage) {\n\t\t\tcase eScriptJS:\n\t\t\tcase eScriptPHP:\n\t\t\t\t//not currently supported\t\t\t\tcase eScriptVBS:\n\n\t\t\t\tif (!AnyOf(state, SCE_HPHP_COMMENT, SCE_HPHP_COMMENTLINE, SCE_HJ_COMMENT, SCE_HJ_COMMENTLINE, SCE_HJ_COMMENTDOC) &&\n\t\t\t\t    !isStringState(state)) {\n\t\t\t\t//Platform::DebugPrintf(\"state=%d, StateToPrint=%d, initStyle=%d\\n\", state, StateToPrint, initStyle);\n\t\t\t\t//if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {\n\t\t\t\t\tif (ch == '#') {\n\t\t\t\t\t\tSci_Position j = i + 1;\n\t\t\t\t\t\twhile ((j < lengthDoc) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\t\t\tj++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (styler.Match(j, \"region\") || styler.Match(j, \"if\")) {\n\t\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t\t} else if (styler.Match(j, \"end\")) {\n\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {\n\t\t\t\t\t\tlevelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1);\n\t\t\t\t\t}\n\t\t\t\t} else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTDOC)) && foldComment && (ch == '*') && (chNext == '/')) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase eScriptPython:\n\t\t\t\tif (state != SCE_HP_COMMENTLINE && !isMako) {\n\t\t\t\t\tif ((ch == ':') && ((chNext == '\\n') || (chNext == '\\r' && chNext2 == '\\n'))) {\n\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t} else if ((ch == '\\n') && !((chNext == '\\r') && (chNext2 == '\\n')) && (chNext != '\\n')) {\n\t\t\t\t\t\t// check if the number of tabs is lower than the level\n\t\t\t\t\t\tconstexpr int tabWidth = 8;\n\t\t\t\t\t\tint Findlevel = (levelCurrent & ~SC_FOLDLEVELBASE) * tabWidth;\n\t\t\t\t\t\tfor (Sci_Position j = 0; Findlevel > 0; j++) {\n\t\t\t\t\t\t\tconst char chTmp = styler.SafeGetCharAt(i + j + 1);\n\t\t\t\t\t\t\tif (chTmp == '\\t') {\n\t\t\t\t\t\t\t\tFindlevel -= tabWidth;\n\t\t\t\t\t\t\t} else if (chTmp == ' ') {\n\t\t\t\t\t\t\t\tFindlevel--;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (Findlevel > 0) {\n\t\t\t\t\t\t\tlevelCurrent -= Findlevel / tabWidth;\n\t\t\t\t\t\t\tif (Findlevel % tabWidth)\n\t\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n')) {\n\t\t\t// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)\n\t\t\t// Avoid triggering two times on Dos/Win\n\t\t\t// New line -> record any line state onto /next/ line\n\t\t\tif (fold) {\n\t\t\t\tint lev = levelPrev;\n\t\t\t\tif (visibleChars == 0)\n\t\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t\tvisibleChars = 0;\n\t\t\t\tlevelPrev = levelCurrent;\n\t\t\t}\n\t\t\tstyler.SetLineState(lineCurrent,\n\t\t\t                    ((inScriptType & 0x03) << 0) |\n\t\t\t                    ((tagOpened ? 1 : 0) << 2) |\n\t\t\t                    ((tagClosing ? 1 : 0) << 3) |\n\t\t\t                    ((aspScript & 0x0F) << 4) |\n\t\t\t                    ((clientScript & 0x0F) << 8) |\n\t\t\t                    ((beforePreProc & 0xFF) << 12) |\n\t\t\t                    ((isLanguageType ? 1 : 0) << 20) |\n\t\t\t                    (sgmlBlockLevel << 21));\n\t\t\tlineCurrent++;\n\t\t\tlineStartVisibleChars = 0;\n\t\t}\n\n\t\t// handle start of Mako comment line\n\t\tif (isMako && ch == '#' && chNext == '#') {\n\t\t\tmakoComment = 1;\n\t\t\tstate = SCE_HP_COMMENTLINE;\n\t\t}\n\n\t\t// handle end of Mako comment line\n\t\telse if (isMako && makoComment && (ch == '\\r' || ch == '\\n')) {\n\t\t\tmakoComment = 0;\n\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\tif (scriptLanguage == eScriptPython) {\n\t\t\t\tstate = SCE_HP_DEFAULT;\n\t\t\t} else {\n\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t}\n\t\t}\n\t\t// Allow falling through to mako handling code if newline is going to end a block\n\t\tif (((ch == '\\r' && chNext != '\\n') || (ch == '\\n')) &&\n\t\t\t(!isMako || (makoBlockType != \"%\"))) {\n\t\t}\n\t\t// Ignore everything in mako comment until the line ends\n\t\telse if (isMako && makoComment) {\n\t\t}\n\n\t\t// generic end of script processing\n\t\telse if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) {\n\t\t\t// Check if it's the end of the script tag (or any other HTML tag)\n\t\t\tswitch (state) {\n\t\t\t\t// in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!)\n\t\t\tcase SCE_H_DOUBLESTRING:\n\t\t\tcase SCE_H_SINGLESTRING:\n\t\t\tcase SCE_HJ_COMMENT:\n\t\t\tcase SCE_HJ_COMMENTDOC:\n\t\t\t//case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide\n\t\t\t// the end of script marker from some JS interpreters.\n\t\t\t//case SCE_HB_COMMENTLINE:\n\t\t\tcase SCE_HBA_COMMENTLINE:\n\t\t\tcase SCE_HJ_DOUBLESTRING:\n\t\t\tcase SCE_HJ_SINGLESTRING:\n\t\t\tcase SCE_HJ_REGEX:\n\t\t\tcase SCE_HJ_TEMPLATELITERAL:\n\t\t\tcase SCE_HB_STRING:\n\t\t\tcase SCE_HBA_STRING:\n\t\t\tcase SCE_HP_STRING:\n\t\t\tcase SCE_HP_TRIPLE:\n\t\t\tcase SCE_HP_TRIPLEDOUBLE:\n\t\t\tcase SCE_HPHP_HSTRING:\n\t\t\tcase SCE_HPHP_SIMPLESTRING:\n\t\t\tcase SCE_HPHP_COMMENT:\n\t\t\tcase SCE_HPHP_COMMENTLINE:\n\t\t\t\tbreak;\n\t\t\tdefault :\n\t\t\t\t// check if the closing tag is a script tag\n\t\t\t\tif (const char *tag =\n\t\t\t\t\t\t(state == SCE_HJ_COMMENTLINE || state == SCE_HB_COMMENTLINE || isXml) ? \"script\" :\n\t\t\t\t\t\tstate == SCE_H_COMMENT ? \"comment\" : nullptr) {\n\t\t\t\t\tSci_Position j = i + 2;\n\t\t\t\t\tint chr;\n\t\t\t\t\tdo {\n\t\t\t\t\t\tchr = static_cast<int>(*tag++);\n\t\t\t\t\t} while (chr != 0 && chr == MakeLowerCase(styler.SafeGetCharAt(j++)));\n\t\t\t\t\tif (chr != 0) break;\n\t\t\t\t}\n\t\t\t\t// closing tag of the script (it's a closing HTML tag anyway)\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_H_TAGUNKNOWN;\n\t\t\t\tinScriptType = eHtml;\n\t\t\t\tscriptLanguage = eScriptNone;\n\t\t\t\tclientScript = eScriptJS;\n\t\t\t\tisLanguageType = false;\n\t\t\t\ti += 2;\n\t\t\t\tvisibleChars += 2;\n\t\t\t\ttagClosing = true;\n\t\t\t\tif (foldXmlAtTagOpen) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t/////////////////////////////////////\n\t\t// handle the start of PHP pre-processor = Non-HTML\n\t\telse if ((ch == '<') && (chNext == '?') && !IsPHPScriptState(state)) {\n \t\t\tconst InstructionTag tag = segIsScriptInstruction(allowPHP, state, styler, i + 2, isXml);\n \t\t\tif (tag != InstructionTag::None) {\n\t\t\t\tbeforeLanguage = scriptLanguage;\n\t\t\t\tscriptLanguage = (tag == InstructionTag::XML) ? eScriptXML : eScriptPHP;\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tbeforePreProc = state;\n\t\t\t\ti++;\n\t\t\t\tvisibleChars++;\n\t\t\t\tif (tag >= InstructionTag::Echo) {\n\t\t\t\t\ti += (tag == InstructionTag::Echo) ? 1 : 3;\n\t\t\t\t}\n\t\t\t\tif (scriptLanguage == eScriptXML)\n\t\t\t\t\tstyler.ColourTo(i, SCE_H_XMLSTART);\n\t\t\t\telse\n\t\t\t\t\tstyler.ColourTo(i, SCE_H_QUESTION);\n\t\t\t\tstate = StateForScript(scriptLanguage);\n\t\t\t\tif (inScriptType == eNonHtmlScript)\n\t\t\t\t\tinScriptType = eNonHtmlScriptPreProc;\n\t\t\t\telse\n\t\t\t\t\tinScriptType = eNonHtmlPreProc;\n\t\t\t\t// Fold whole script, but not if the XML first tag (all XML-like tags in this case)\n\t\t\t\tif (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t}\n\t\t\t\t// should be better\n\t\t\t\tch = SafeGetUnsignedCharAt(styler, i);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// handle the start Mako template Python code\n\t\telse if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t (lineStartVisibleChars == 1 && ch == '%') ||\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t (lineStartVisibleChars == 1 && ch == '/' && chNext == '%') ||\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t (ch == '$' && chNext == '{') ||\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t (ch == '<' && chNext == '/' && chNext2 == '%'))) {\n\t\t\tif (ch == '%' || ch == '/')\n\t\t\t\tmakoBlockType = \"%\";\n\t\t\telse if (ch == '$')\n\t\t\t\tmakoBlockType = \"{\";\n\t\t\telse if (chNext == '/')\n\t\t\t\tmakoBlockType = GetNextWord(styler, i+3);\t// Tag end: </%tag>\n\t\t\telse\n\t\t\t\tmakoBlockType = GetNextWord(styler, i+2);\t// Tag: <%tag...>\n\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\tbeforePreProc = state;\n\t\t\tif (inScriptType == eNonHtmlScript)\n\t\t\t\tinScriptType = eNonHtmlScriptPreProc;\n\t\t\telse\n\t\t\t\tinScriptType = eNonHtmlPreProc;\n\n\t\t\tif (chNext == '/') {\n\t\t\t\ti += 2;\n\t\t\t\tvisibleChars += 2;\n\t\t\t} else if (ch != '%') {\n\t\t\t\ti++;\n\t\t\t\tvisibleChars++;\n\t\t\t}\n\t\t\tstate = SCE_HP_START;\n\t\t\tscriptLanguage = eScriptPython;\n\t\t\tstyler.ColourTo(i, SCE_H_ASP);\n\t\t\tif (ch != '%' && ch != '$' && ch != '/') {\n\t\t\t\ti += makoBlockType.length();\n\t\t\t\tvisibleChars += makoBlockType.length();\n\t\t\t\tif (keywordsPy.InList(makoBlockType))\n\t\t\t\t\tstyler.ColourTo(i, SCE_HP_WORD);\n\t\t\t\telse\n\t\t\t\t\tstyler.ColourTo(i, SCE_H_TAGUNKNOWN);\n\t\t\t}\n\n\t\t\tch = SafeGetUnsignedCharAt(styler, i);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// handle the start/end of Django comment\n\t\telse if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) {\n\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\tbeforePreProc = state;\n\t\t\tbeforeLanguage = scriptLanguage;\n\t\t\tif (inScriptType == eNonHtmlScript)\n\t\t\t\tinScriptType = eNonHtmlScriptPreProc;\n\t\t\telse\n\t\t\t\tinScriptType = eNonHtmlPreProc;\n\t\t\ti += 1;\n\t\t\tvisibleChars += 1;\n\t\t\tscriptLanguage = eScriptComment;\n\t\t\tstate = SCE_H_COMMENT;\n\t\t\tstyler.ColourTo(i, SCE_H_ASP);\n\t\t\tch = SafeGetUnsignedCharAt(styler, i);\n\t\t\tcontinue;\n\t\t} else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) {\n\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\ti += 1;\n\t\t\tvisibleChars += 1;\n\t\t\tstyler.ColourTo(i, SCE_H_ASP);\n\t\t\tstate = beforePreProc;\n\t\t\tif (inScriptType == eNonHtmlScriptPreProc)\n\t\t\t\tinScriptType = eNonHtmlScript;\n\t\t\telse\n\t\t\t\tinScriptType = eHtml;\n\t\t\tscriptLanguage = beforeLanguage;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// handle the start Django template code\n\t\telse if (isDjango && scriptLanguage != eScriptPython && scriptLanguage != eScriptComment && (ch == '{' && (chNext == '%' ||  chNext == '{'))) {\n\t\t\tif (chNext == '%')\n\t\t\t\tdjangoBlockType = \"%\";\n\t\t\telse\n\t\t\t\tdjangoBlockType = \"{\";\n\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\tbeforePreProc = state;\n\t\t\tif (inScriptType == eNonHtmlScript)\n\t\t\t\tinScriptType = eNonHtmlScriptPreProc;\n\t\t\telse\n\t\t\t\tinScriptType = eNonHtmlPreProc;\n\n\t\t\ti += 1;\n\t\t\tvisibleChars += 1;\n\t\t\tstate = SCE_HP_START;\n\t\t\tbeforeLanguage = scriptLanguage;\n\t\t\tscriptLanguage = eScriptPython;\n\t\t\tstyler.ColourTo(i, SCE_H_ASP);\n\n\t\t\tch = SafeGetUnsignedCharAt(styler, i);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// handle the start of ASP pre-processor = Non-HTML\n\t\telse if ((ch == '<') && (chNext == '%') && allowASP && !isCommentASPState(state) && !isPHPStringState(state)) {\n\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\tbeforePreProc = state;\n\t\t\tif (inScriptType == eNonHtmlScript)\n\t\t\t\tinScriptType = eNonHtmlScriptPreProc;\n\t\t\telse\n\t\t\t\tinScriptType = eNonHtmlPreProc;\n\t\t\t// fold whole script\n\t\t\tif (foldHTMLPreprocessor)\n\t\t\t\tlevelCurrent++;\n\t\t\tif (chNext2 == '@') {\n\t\t\t\ti += 2; // place as if it was the second next char treated\n\t\t\t\tvisibleChars += 2;\n\t\t\t\tstate = SCE_H_ASPAT;\n\t\t\t\tscriptLanguage = eScriptVBS;\n\t\t\t} else if ((chNext2 == '-') && (styler.SafeGetCharAt(i + 3) == '-')) {\n\t\t\t\tstyler.ColourTo(i + 3, SCE_H_ASP);\n\t\t\t\tstate = SCE_H_XCCOMMENT;\n\t\t\t\tscriptLanguage = eScriptVBS;\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tif (chNext2 == '=') {\n\t\t\t\t\ti += 2; // place as if it was the second next char treated\n\t\t\t\t\tvisibleChars += 2;\n\t\t\t\t} else {\n\t\t\t\t\ti++; // place as if it was the next char treated\n\t\t\t\t\tvisibleChars++;\n\t\t\t\t}\n\n\t\t\t\tstate = StateForScript(aspScript);\n\t\t\t\tscriptLanguage = aspScript;\n\t\t\t}\n\t\t\tstyler.ColourTo(i, SCE_H_ASP);\n\t\t\t// should be better\n\t\t\tch = SafeGetUnsignedCharAt(styler, i);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/////////////////////////////////////\n\t\t// handle the start of SGML language (DTD)\n\t\telse if (AnyOf(scriptLanguage, eScriptNone, eScriptXML, eScriptSGMLblock) &&\n\t\t\t\t (chPrev == '<') &&\n\t\t\t\t (ch == '!') &&\n\t\t\t\t AnyOf(state, SCE_H_DEFAULT, SCE_H_SGML_BLOCK_DEFAULT)) {\n\t\t\tbeforePreProc = state;\n\t\t\tstyler.ColourTo(i - 2, StateToPrint);\n\t\t\tif ((state != SCE_H_SGML_BLOCK_DEFAULT) && (chNext == '-') && (chNext2 == '-')) {\n\t\t\t\tstate = SCE_H_COMMENT; // wait for a pending command\n\t\t\t\tstyler.ColourTo(i + 2, SCE_H_COMMENT);\n\t\t\t\ti += 2; // follow styling after the --\n\t\t\t\tif (!isXml) {\n\t\t\t\t\t// handle empty comment: <!-->, <!--->\n\t\t\t\t\t// https://html.spec.whatwg.org/multipage/parsing.html#parse-error-abrupt-closing-of-empty-comment\n\t\t\t\t\tchNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\t\t\t\tif ((chNext == '>') || (chNext == '-' && SafeGetUnsignedCharAt(styler, i + 2) == '>')) {\n\t\t\t\t\t\tif (chNext == '-') {\n\t\t\t\t\t\t\ti += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchPrev = '-';\n\t\t\t\t\t\tch = '-';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ((state != SCE_H_SGML_BLOCK_DEFAULT) && isWordCdata(i + 1, i + 7, styler)) {\n\t\t\t\tstate = SCE_H_CDATA;\n\t\t\t} else {\n\t\t\t\tstyler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default\n\t\t\t\tbeforeLanguage = scriptLanguage;\n\t\t\t\tscriptLanguage = eScriptSGML;\n\t\t\t\tif ((chNext == '-') && (chNext2 == '-')) {\n\t\t\t\t\ti += 2;\n\t\t\t\t\tstate = SCE_H_SGML_COMMENT;\n\t\t\t\t} else {\n\t\t\t\t\tstate = (chNext == '[') ? SCE_H_SGML_DEFAULT : SCE_H_SGML_COMMAND; // wait for a pending command\n\t\t\t\t}\n\t\t\t}\n\t\t\t// fold whole tag (-- when closing the tag)\n\t\t\tif (foldHTMLPreprocessor || state == SCE_H_COMMENT || state == SCE_H_CDATA)\n\t\t\t\tlevelCurrent++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// handle the end of Mako Python code\n\t\telse if (isMako &&\n\t\t\t     ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&\n\t\t\t\t (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&\n\t\t\t\t isMakoBlockEnd(ch, chNext, makoBlockType)) {\n\t\t\tif (state == SCE_H_ASPAT) {\n\t\t\t\taspScript = segIsScriptingIndicator(styler,\n\t\t\t\t                                    styler.GetStartSegment(), i - 1, aspScript);\n\t\t\t}\n\t\t\tif (state == SCE_HP_WORD) {\n\t\t\t\tclassifyWordHTPy(styler.GetStartSegment(), i - 1, keywordsPy, classifierPython, styler, prevWord, inScriptType, isMako);\n\t\t\t} else {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t}\n\t\t\tif ((makoBlockType != \"%\") && (makoBlockType != \"{\") && ch != '>') {\n\t\t\t\ti++;\n\t\t\t\tvisibleChars++;\n\t\t\t} else if ((makoBlockType == \"%\") && ch == '/') {\n\t\t\t\ti++;\n\t\t\t\tvisibleChars++;\n\t\t\t}\n\t\t\tif ((makoBlockType != \"%\") || ch == '/') {\n\t\t\t\tstyler.ColourTo(i, SCE_H_ASP);\n\t\t\t}\n\t\t\tstate = beforePreProc;\n\t\t\tif (inScriptType == eNonHtmlScriptPreProc)\n\t\t\t\tinScriptType = eNonHtmlScript;\n\t\t\telse\n\t\t\t\tinScriptType = eHtml;\n\t\t\tscriptLanguage = eScriptNone;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// handle the end of Django template code\n\t\telse if (isDjango &&\n\t\t\t     ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&\n\t\t\t\t (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&\n\t\t\t\t isDjangoBlockEnd(ch, chNext, djangoBlockType)) {\n\t\t\tif (state == SCE_H_ASPAT) {\n\t\t\t\taspScript = segIsScriptingIndicator(styler,\n\t\t\t\t                                    styler.GetStartSegment(), i - 1, aspScript);\n\t\t\t}\n\t\t\tif (state == SCE_HP_WORD) {\n\t\t\t\tclassifyWordHTPy(styler.GetStartSegment(), i - 1, keywordsPy, classifierPython, styler, prevWord, inScriptType, isMako);\n\t\t\t} else {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t}\n\t\t\ti += 1;\n\t\t\tvisibleChars += 1;\n\t\t\tstyler.ColourTo(i, SCE_H_ASP);\n\t\t\tstate = beforePreProc;\n\t\t\tif (inScriptType == eNonHtmlScriptPreProc)\n\t\t\t\tinScriptType = eNonHtmlScript;\n\t\t\telse\n\t\t\t\tinScriptType = eHtml;\n\t\t\tscriptLanguage = beforeLanguage;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// handle the end of a pre-processor = Non-HTML\n\t\telse if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&\n\t\t\t\t  (((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&\n\t\t\t\t  ((chNext == '>') && isPreProcessorEndTag(state, ch))) ||\n\t\t         ((scriptLanguage == eScriptSGML) && (ch == '>') && !AnyOf(state, SCE_H_SGML_COMMENT, SCE_H_SGML_DOUBLESTRING, SCE_H_SGML_SIMPLESTRING))) {\n\t\t\tif (state == SCE_H_ASPAT) {\n\t\t\t\taspScript = segIsScriptingIndicator(styler,\n\t\t\t\t                                    styler.GetStartSegment(), i - 1, aspScript);\n\t\t\t}\n\t\t\t// Bounce out of any ASP mode\n\t\t\tswitch (state) {\n\t\t\tcase SCE_HJ_WORD:\n\t\t\t\tclassifyWordHTJS(styler.GetStartSegment(), i - 1, keywordsJS, classifierJavaScript, classifierJavaScriptServer, styler, inScriptType);\n\t\t\t\tbreak;\n\t\t\tcase SCE_HB_WORD:\n\t\t\t\tclassifyWordHTVB(styler.GetStartSegment(), i - 1, keywordsVB, classifierBasic, styler, inScriptType);\n\t\t\t\tbreak;\n\t\t\tcase SCE_HP_WORD:\n\t\t\t\tclassifyWordHTPy(styler.GetStartSegment(), i - 1, keywordsPy, classifierPython, styler, prevWord, inScriptType, isMako);\n\t\t\t\tbreak;\n\t\t\tcase SCE_HPHP_WORD:\n\t\t\t\tclassifyWordHTPHP(styler.GetStartSegment(), i - 1, keywordsPHP, classifierPHP, styler);\n\t\t\t\tbreak;\n\t\t\tcase SCE_H_XCCOMMENT:\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tbreak;\n\t\t\tdefault :\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (scriptLanguage != eScriptSGML) {\n\t\t\t\ti++;\n\t\t\t\tvisibleChars++;\n\t\t\t}\n\t\t\tif (ch == '%')\n\t\t\t\tstyler.ColourTo(i, SCE_H_ASP);\n\t\t\telse if (scriptLanguage == eScriptXML)\n\t\t\t\tstyler.ColourTo(i, SCE_H_XMLEND);\n\t\t\telse if (scriptLanguage == eScriptSGML)\n\t\t\t\tstyler.ColourTo(i, SCE_H_SGML_DEFAULT);\n\t\t\telse\n\t\t\t\tstyler.ColourTo(i, SCE_H_QUESTION);\n\t\t\tstate = beforePreProc;\n\t\t\tif (inScriptType == eNonHtmlScriptPreProc)\n\t\t\t\tinScriptType = eNonHtmlScript;\n\t\t\telse\n\t\t\t\tinScriptType = eHtml;\n\t\t\t// Unfold all scripting languages, except for XML tag\n\t\t\tif (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t\tscriptLanguage = beforeLanguage;\n\t\t\tcontinue;\n\t\t}\n\t\t/////////////////////////////////////\n\n\t\tswitch (state) {\n\t\tcase SCE_H_DEFAULT:\n\t\t\tif (ch == '<') {\n\t\t\t\t// in HTML, fold on tag open and unfold on tag close\n\t\t\t\ttagOpened = true;\n\t\t\t\ttagClosing = (chNext == '/');\n\t\t\t\tif (foldXmlAtTagOpen && !AnyOf(chNext, '/', '?', '!', '-', '%')) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t}\n\t\t\t\tif (foldXmlAtTagOpen && chNext == '/') {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tif (chNext != '!')\n\t\t\t\t\tstate = SCE_H_TAGUNKNOWN;\n\t\t\t} else if (ch == '&') {\n\t\t\t\tstyler.ColourTo(i - 1, SCE_H_DEFAULT);\n\t\t\t\tstate = SCE_H_ENTITY;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_DEFAULT:\n\t\tcase SCE_H_SGML_BLOCK_DEFAULT:\n//\t\t\tif (scriptLanguage == eScriptSGMLblock)\n//\t\t\t\tStateToPrint = SCE_H_SGML_BLOCK_DEFAULT;\n\n\t\t\tif (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_H_SGML_DOUBLESTRING;\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_H_SGML_SIMPLESTRING;\n\t\t\t} else if ((ch == '-') && (chPrev == '-')) {\n\t\t\t\tif (static_cast<Sci_Position>(styler.GetStartSegment()) <= (i - 2)) {\n\t\t\t\t\tstyler.ColourTo(i - 2, StateToPrint);\n\t\t\t\t}\n\t\t\t\tstate = SCE_H_SGML_COMMENT;\n\t\t\t} else if (ch == '%' && IsUpperOrLowerCase(chNext)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_H_SGML_ENTITY;\n\t\t\t} else if (ch == '#') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_H_SGML_SPECIAL;\n\t\t\t} else if (ch == '[') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstyler.ColourTo(i, SCE_H_SGML_DEFAULT);\n\t\t\t\t++sgmlBlockLevel;\n\t\t\t\tscriptLanguage = eScriptSGMLblock;\n\t\t\t\tstate = SCE_H_SGML_BLOCK_DEFAULT;\n\t\t\t} else if (ch == ']') {\n\t\t\t\tif (sgmlBlockLevel > 0) {\n\t\t\t\t\t--sgmlBlockLevel;\n\t\t\t\t\tif (sgmlBlockLevel == 0) {\n\t\t\t\t\t\tbeforePreProc = SCE_H_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\t\tstyler.ColourTo(i, SCE_H_SGML_DEFAULT);\n\t\t\t\t\tscriptLanguage = eScriptSGML;\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\t\tstyler.ColourTo(i, SCE_H_SGML_ERROR);\n\t\t\t\t}\n\t\t\t\tstate = SCE_H_SGML_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_COMMAND:\n\t\t\tif (!issgmlwordchar(ch)) {\n\t\t\t\tif (isWordHSGML(styler.GetStartSegment(), i - 1, keywordsSGML, styler)) {\n\t\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\t\tstate = SCE_H_SGML_1ST_PARAM;\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_H_SGML_ERROR;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_1ST_PARAM:\n\t\t\t// wait for the beginning of the word\n\t\t\tif ((ch == '-') && (chPrev == '-')) {\n\t\t\t\tstyler.ColourTo(i - 2, SCE_H_SGML_DEFAULT);\n\t\t\t\tstate = SCE_H_SGML_1ST_PARAM_COMMENT;\n\t\t\t} else if (issgmlwordchar(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, SCE_H_SGML_DEFAULT);\n\t\t\t\t// find the length of the word\n\t\t\t\tSci_Position size = 1;\n\t\t\t\twhile (setHTMLWord.Contains(SafeGetUnsignedCharAt(styler, i + size)))\n\t\t\t\t\tsize++;\n\t\t\t\tstyler.ColourTo(i + size - 1, StateToPrint);\n\t\t\t\ti += size - 1;\n\t\t\t\tvisibleChars += size - 1;\n\t\t\t\tch = SafeGetUnsignedCharAt(styler, i);\n\t\t\t\tstate = SCE_H_SGML_DEFAULT;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_ERROR:\n\t\t\tif ((ch == '-') && (chPrev == '-')) {\n\t\t\t\tstyler.ColourTo(i - 2, StateToPrint);\n\t\t\t\tstate = SCE_H_SGML_COMMENT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_DOUBLESTRING:\n\t\t\tif (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_H_SGML_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_SIMPLESTRING:\n\t\t\tif (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_H_SGML_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_COMMENT:\n\t\t\tif ((ch == '-') && (chPrev == '-')) {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_H_SGML_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_CDATA:\n\t\t\tif ((chPrev2 == ']') && (chPrev == ']') && (ch == '>')) {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_COMMENT:\n\t\t\tif ((scriptLanguage != eScriptComment) && (chPrev2 == '-') && (chPrev == '-') && (ch == '>' || (!isXml && ch == '!' && chNext == '>'))) {\n\t\t\t\t// close HTML comment with --!>\n\t\t\t\t// https://html.spec.whatwg.org/multipage/parsing.html#parse-error-incorrectly-closed-comment\n\t\t\t\tif (ch == '!') {\n\t\t\t\t\ti += 1;\n\t\t\t\t}\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_1ST_PARAM_COMMENT:\n\t\t\tif ((ch == '-') && (chPrev == '-')) {\n\t\t\t\tstyler.ColourTo(i, SCE_H_SGML_COMMENT);\n\t\t\t\tstate = SCE_H_SGML_1ST_PARAM;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_SPECIAL:\n\t\t\tif (!IsUpperCase(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tif (IsAlphaNumeric(ch)) {\n\t\t\t\t\tstate = SCE_H_SGML_ERROR;\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_H_SGML_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SGML_ENTITY:\n\t\t\tif (!(IsAlphaNumeric(ch)) && ch != '-' && ch != '.' && ch != '_') {\n\t\t\t\tstyler.ColourTo(i, ((ch == ';') ? StateToPrint : SCE_H_SGML_ERROR));\n\t\t\t\tstate = defaultStateForSGML(scriptLanguage);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_ENTITY:\n\t\t\tif (ch == ';') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t} else if (!setEntity.Contains(ch)) {\n\t\t\t\tstyler.ColourTo(i-1, SCE_H_TAGUNKNOWN);\n\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t\tif (!isLineEnd(ch)) {\n\t\t\t\t\t// Retreat one byte so the character that is invalid inside entity\n\t\t\t\t\t// may start something else like a tag.\n\t\t\t\t\t--i;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_TAGUNKNOWN:\n\t\t\tif (!setTagContinue.Contains(ch) && !((ch == '/') && (chPrev == '<'))) {\n\t\t\t\tint eClass = classifyTagHTML(styler.GetStartSegment(),\n\t\t\t\t\ti - 1, keywordsHTML, classifierTags, styler, tagDontFold, caseSensitive, isXml, allowScripts, nonFoldingTags, lastTag);\n\t\t\t\tif (eClass == SCE_H_SCRIPT || eClass == SCE_H_COMMENT) {\n\t\t\t\t\tif (!tagClosing) {\n\t\t\t\t\t\tinScriptType = eNonHtmlScript;\n\t\t\t\t\t\tscriptLanguage = eClass == SCE_H_SCRIPT ? clientScript : eScriptComment;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tscriptLanguage = eScriptNone;\n\t\t\t\t\t}\n\t\t\t\t\tisLanguageType = false;\n\t\t\t\t\teClass = SCE_H_TAG;\n\t\t\t\t}\n\t\t\t\tif (ch == '>') {\n\t\t\t\t\tstyler.ColourTo(i, eClass);\n\t\t\t\t\tif (inScriptType == eNonHtmlScript) {\n\t\t\t\t\t\tstate = StateForScript(scriptLanguage);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t\ttagOpened = false;\n\t\t\t\t\tif (!(foldXmlAtTagOpen || tagDontFold)) {\n\t\t\t\t\t\tif (tagClosing) {\n\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ttagClosing = false;\n\t\t\t\t} else if (ch == '/' && chNext == '>') {\n\t\t\t\t\tif (eClass == SCE_H_TAGUNKNOWN) {\n\t\t\t\t\t\tstyler.ColourTo(i + 1, SCE_H_TAGUNKNOWN);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\t\t\tstyler.ColourTo(i + 1, SCE_H_TAGEND);\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t\tch = chNext;\n\t\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t\t\ttagOpened = false;\n\t\t\t\t\tif (foldXmlAtTagOpen) {\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (eClass != SCE_H_TAGUNKNOWN) {\n\t\t\t\t\t\tif (eClass == SCE_H_SGML_DEFAULT) {\n\t\t\t\t\t\t\tstate = SCE_H_SGML_DEFAULT;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstate = SCE_H_OTHER;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_ATTRIBUTE:\n\t\t\tif (!setAttributeContinue.Contains(ch)) {\n\t\t\t\tisLanguageType = classifyAttribHTML(inScriptType, styler.GetStartSegment(), i - 1, keywordsHTML, classifierAttributes, styler, lastTag);\n\t\t\t\tif (ch == '>') {\n\t\t\t\t\tstyler.ColourTo(i, SCE_H_TAG);\n\t\t\t\t\tif (inScriptType == eNonHtmlScript) {\n\t\t\t\t\t\tstate = StateForScript(scriptLanguage);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t\ttagOpened = false;\n\t\t\t\t\tif (!(foldXmlAtTagOpen || tagDontFold)) {\n\t\t\t\t\t\tif (tagClosing) {\n\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ttagClosing = false;\n\t\t\t\t} else if (ch == '=') {\n\t\t\t\t\tstyler.ColourTo(i, SCE_H_OTHER);\n\t\t\t\t\tstate = SCE_H_VALUE;\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_H_OTHER;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_OTHER:\n\t\t\tif (ch == '>') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstyler.ColourTo(i, SCE_H_TAG);\n\t\t\t\tif (inScriptType == eNonHtmlScript) {\n\t\t\t\t\tstate = StateForScript(scriptLanguage);\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t\t}\n\t\t\t\ttagOpened = false;\n\t\t\t\tif (!(foldXmlAtTagOpen || tagDontFold)) {\n\t\t\t\t\tif (tagClosing) {\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttagClosing = false;\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_H_DOUBLESTRING;\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_H_SINGLESTRING;\n\t\t\t} else if (ch == '=') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_H_VALUE;\n\t\t\t} else if (ch == '/' && chNext == '>') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstyler.ColourTo(i + 1, SCE_H_TAGEND);\n\t\t\t\ti++;\n\t\t\t\tch = chNext;\n\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t\ttagOpened = false;\n\t\t\t\tif (foldXmlAtTagOpen) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t} else if (ch == '?' && chNext == '>') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstyler.ColourTo(i + 1, SCE_H_XMLEND);\n\t\t\t\ti++;\n\t\t\t\tch = chNext;\n\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t} else if (setHTMLWord.Contains(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_H_ATTRIBUTE;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_DOUBLESTRING:\n\t\t\tif (ch == '\\\"') {\n\t\t\t\tif (isLanguageType) {\n\t\t\t\t\tscriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);\n\t\t\t\t\tclientScript = scriptLanguage;\n\t\t\t\t\tisLanguageType = false;\n\t\t\t\t}\n\t\t\t\tstyler.ColourTo(i, SCE_H_DOUBLESTRING);\n\t\t\t\tstate = SCE_H_OTHER;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_SINGLESTRING:\n\t\t\tif (ch == '\\'') {\n\t\t\t\tif (isLanguageType) {\n\t\t\t\t\tscriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);\n\t\t\t\t\tclientScript = scriptLanguage;\n\t\t\t\t\tisLanguageType = false;\n\t\t\t\t}\n\t\t\t\tstyler.ColourTo(i, SCE_H_SINGLESTRING);\n\t\t\t\tstate = SCE_H_OTHER;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_H_VALUE:\n\t\t\tif (!setHTMLWord.Contains(ch)) {\n\t\t\t\tif (ch == '\\\"' && chPrev == '=') {\n\t\t\t\t\t// Should really test for being first character\n\t\t\t\t\tstate = SCE_H_DOUBLESTRING;\n\t\t\t\t} else if (ch == '\\'' && chPrev == '=') {\n\t\t\t\t\tstate = SCE_H_SINGLESTRING;\n\t\t\t\t} else {\n\t\t\t\t\tif (IsNumberChar(styler[styler.GetStartSegment()])) {\n\t\t\t\t\t\tstyler.ColourTo(i - 1, SCE_H_NUMBER);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\t\t}\n\t\t\t\t\tif (ch == '>') {\n\t\t\t\t\t\tstyler.ColourTo(i, SCE_H_TAG);\n\t\t\t\t\t\tif (inScriptType == eNonHtmlScript) {\n\t\t\t\t\t\t\tstate = StateForScript(scriptLanguage);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstate = SCE_H_DEFAULT;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttagOpened = false;\n\t\t\t\t\t\tif (!tagDontFold) {\n\t\t\t\t\t\t\tif (tagClosing) {\n\t\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttagClosing = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate = SCE_H_OTHER;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HJ_DEFAULT:\n\t\tcase SCE_HJ_START:\n\t\tcase SCE_HJ_SYMBOLS:\n\t\t\tif (IsAWordStart(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_WORD;\n\t\t\t} else if (ch == '/' && chNext == '*') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\ti++;\n\t\t\t\tif (chNext2 == '*')\n\t\t\t\t\tstate = SCE_HJ_COMMENTDOC;\n\t\t\t\telse\n\t\t\t\t\tstate = SCE_HJ_COMMENT;\n\t\t\t} else if (ch == '/' && chNext == '/') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_COMMENTLINE;\n\t\t\t} else if (ch == '/' && setOKBeforeJSRE.Contains(chPrevNonWhite)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_REGEX;\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_DOUBLESTRING;\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_SINGLESTRING;\n\t\t\t} else if (ch == '`') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_TEMPLATELITERAL;\n\t\t\t} else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&\n\t\t\t           styler.SafeGetCharAt(i + 3) == '-') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_COMMENTLINE;\n\t\t\t} else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_COMMENTLINE;\n\t\t\t\ti += 2;\n\t\t\t} else if (IsOperator(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstyler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t} else if ((ch == ' ') || (ch == '\\t')) {\n\t\t\t\tif (state == SCE_HJ_START) {\n\t\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HJ_WORD:\n\t\t\tif (!IsAWordChar(ch)) {\n\t\t\t\tclassifyWordHTJS(styler.GetStartSegment(), i - 1, keywordsJS,\n\t\t\t\t\tclassifierJavaScript, classifierJavaScriptServer, styler, inScriptType);\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HJ_COMMENT:\n\t\tcase SCE_HJ_COMMENTDOC:\n\t\t\tif (ch == '/' && chPrev == '*') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t\tch = ' ';\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HJ_COMMENTLINE:\n\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\tstyler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType));\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t\tch = ' ';\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HJ_DOUBLESTRING:\n\t\t\tif (ch == '\\\\') {\n\t\t\t\tif (chNext == '\\\"' || chNext == '\\'' || chNext == '\\\\') {\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i, statePrintForState(SCE_HJ_DOUBLESTRING, inScriptType));\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t\tcontinue;\n\t\t\t} else if (isLineEnd(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tif (chPrev != '\\\\' && (chPrev2 != '\\\\' || chPrev != '\\r' || ch != '\\n')) {\n\t\t\t\t\tstate = SCE_HJ_STRINGEOL;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HJ_SINGLESTRING:\n\t\t\tif (ch == '\\\\') {\n\t\t\t\tif (chNext == '\\\"' || chNext == '\\'' || chNext == '\\\\') {\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i, statePrintForState(SCE_HJ_SINGLESTRING, inScriptType));\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t\tcontinue;\n\t\t\t} else if (isLineEnd(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tif (chPrev != '\\\\' && (chPrev2 != '\\\\' || chPrev != '\\r' || ch != '\\n')) {\n\t\t\t\t\tstate = SCE_HJ_STRINGEOL;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HJ_TEMPLATELITERAL:\n\t\t\tif (ch == '\\\\') {\n\t\t\t\tif (chNext == '$' || chNext == '`' || chNext == '\\\\') {\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t} else if (ch == '`') {\n\t\t\t\tstyler.ColourTo(i, statePrintForState(SCE_HJ_TEMPLATELITERAL, inScriptType));\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HJ_STRINGEOL:\n\t\t\tif (!isLineEnd(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t} else if (!isLineEnd(chNext)) {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HJ_REGEX:\n\t\t\tif (ch == '\\r' || ch == '\\n' || ch == '/') {\n\t\t\t\tif (ch == '/') {\n\t\t\t\t\twhile (IsLowerCase(chNext)) {   // gobble regex flags\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\tch = chNext;\n\t\t\t\t\t\tchNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HJ_DEFAULT;\n\t\t\t\tcontinue;\n\t\t\t} else if (ch == '\\\\') {\n\t\t\t\t// Gobble up the quoted character\n\t\t\t\tif (chNext == '\\\\' || chNext == '/') {\n\t\t\t\t\ti++;\n\t\t\t\t\tch = chNext;\n\t\t\t\t\tchNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HB_DEFAULT:\n\t\tcase SCE_HB_START:\n\t\t\tif (IsAWordStart(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HB_WORD;\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HB_COMMENTLINE;\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HB_STRING;\n\t\t\t} else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&\n\t\t\t           styler.SafeGetCharAt(i + 3) == '-') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HB_COMMENTLINE;\n\t\t\t} else if (IsOperator(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstyler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));\n\t\t\t\tstate = SCE_HB_DEFAULT;\n\t\t\t} else if ((ch == ' ') || (ch == '\\t')) {\n\t\t\t\tif (state == SCE_HB_START) {\n\t\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\t\tstate = SCE_HB_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HB_WORD:\n\t\t\tif (!IsAWordChar(ch)) {\n\t\t\t\tstate = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywordsVB, classifierBasic, styler, inScriptType);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HB_STRING:\n\t\t\tif (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HB_DEFAULT;\n\t\t\t\tcontinue;\n\t\t\t} else if (ch == '\\r' || ch == '\\n') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HB_STRINGEOL;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HB_COMMENTLINE:\n\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HB_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HB_STRINGEOL:\n\t\t\tif (!isLineEnd(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HB_DEFAULT;\n\t\t\t} else if (!isLineEnd(chNext)) {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HB_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HP_DEFAULT:\n\t\tcase SCE_HP_START:\n\t\t\tif (IsAWordStart(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HP_WORD;\n\t\t\t} else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&\n\t\t\t           styler.SafeGetCharAt(i + 3) == '-') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HP_COMMENTLINE;\n\t\t\t} else if (ch == '#') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HP_COMMENTLINE;\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tif (chNext == '\\\"' && chNext2 == '\\\"') {\n\t\t\t\t\ti += 2;\n\t\t\t\t\tstate = SCE_HP_TRIPLEDOUBLE;\n\t\t\t\t\tch = ' ';\n\t\t\t\t\tchPrev = ' ';\n\t\t\t\t\tchNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\t\t\t} else {\n\t\t\t\t\t//\t\t\t\t\tstate = statePrintForState(SCE_HP_STRING,inScriptType);\n\t\t\t\t\tstate = SCE_HP_STRING;\n\t\t\t\t}\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tif (chNext == '\\'' && chNext2 == '\\'') {\n\t\t\t\t\ti += 2;\n\t\t\t\t\tstate = SCE_HP_TRIPLE;\n\t\t\t\t\tch = ' ';\n\t\t\t\t\tchPrev = ' ';\n\t\t\t\t\tchNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_HP_CHARACTER;\n\t\t\t\t}\n\t\t\t} else if (IsOperator(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstyler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));\n\t\t\t} else if ((ch == ' ') || (ch == '\\t')) {\n\t\t\t\tif (state == SCE_HP_START) {\n\t\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\t\tstate = SCE_HP_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HP_WORD:\n\t\t\tif (!IsAWordChar(ch)) {\n\t\t\t\tclassifyWordHTPy(styler.GetStartSegment(), i - 1, keywordsPy, classifierPython, styler, prevWord, inScriptType, isMako);\n\t\t\t\tstate = SCE_HP_DEFAULT;\n\t\t\t\tif (ch == '#') {\n\t\t\t\t\tstate = SCE_HP_COMMENTLINE;\n\t\t\t\t} else if (ch == '\\\"') {\n\t\t\t\t\tif (chNext == '\\\"' && chNext2 == '\\\"') {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tstate = SCE_HP_TRIPLEDOUBLE;\n\t\t\t\t\t\tch = ' ';\n\t\t\t\t\t\tchPrev = ' ';\n\t\t\t\t\t\tchNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate = SCE_HP_STRING;\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == '\\'') {\n\t\t\t\t\tif (chNext == '\\'' && chNext2 == '\\'') {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tstate = SCE_HP_TRIPLE;\n\t\t\t\t\t\tch = ' ';\n\t\t\t\t\t\tchPrev = ' ';\n\t\t\t\t\t\tchNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate = SCE_HP_CHARACTER;\n\t\t\t\t\t}\n\t\t\t\t} else if (IsOperator(ch)) {\n\t\t\t\t\tstyler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HP_COMMENTLINE:\n\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HP_STRING:\n\t\t\tif (ch == '\\\\') {\n\t\t\t\tif (chNext == '\\\"' || chNext == '\\'' || chNext == '\\\\') {\n\t\t\t\t\ti++;\n\t\t\t\t\tch = chNext;\n\t\t\t\t\tchNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\t\t\t}\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HP_CHARACTER:\n\t\t\tif (ch == '\\\\') {\n\t\t\t\tif (chNext == '\\\"' || chNext == '\\'' || chNext == '\\\\') {\n\t\t\t\t\ti++;\n\t\t\t\t\tch = chNext;\n\t\t\t\t\tchNext = SafeGetUnsignedCharAt(styler, i + 1);\n\t\t\t\t}\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HP_TRIPLE:\n\t\t\tif (ch == '\\'' && chPrev == '\\'' && chPrev2 == '\\'') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HP_TRIPLEDOUBLE:\n\t\t\tif (ch == '\\\"' && chPrev == '\\\"' && chPrev2 == '\\\"') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\t\t///////////// start - PHP state handling\n\t\tcase SCE_HPHP_WORD:\n\t\t\tif (!IsPhpWordChar(ch)) {\n\t\t\t\tclassifyWordHTPHP(styler.GetStartSegment(), i - 1, keywordsPHP, classifierPHP, styler);\n\t\t\t\tif (ch == '/' && chNext == '*') {\n\t\t\t\t\ti++;\n\t\t\t\t\tstate = SCE_HPHP_COMMENT;\n\t\t\t\t} else if (ch == '/' && chNext == '/') {\n\t\t\t\t\ti++;\n\t\t\t\t\tstate = SCE_HPHP_COMMENTLINE;\n\t\t\t\t} else if (ch == '#' && chNext != '[') {\n\t\t\t\t\tstate = SCE_HPHP_COMMENTLINE;\n\t\t\t\t} else if (ch == '\\\"') {\n\t\t\t\t\tstate = SCE_HPHP_HSTRING;\n\t\t\t\t\tphpStringDelimiter = \"\\\"\";\n\t\t\t\t} else if (styler.Match(i, \"<<<\")) {\n\t\t\t\t\tbool isSimpleString = false;\n\t\t\t\t\ti = FindPhpStringDelimiter(phpStringDelimiter, i + 3, lengthDoc, styler, isSimpleString);\n\t\t\t\t\tif (!phpStringDelimiter.empty()) {\n\t\t\t\t\t\tstate = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);\n\t\t\t\t\t\tif (foldHeredoc) levelCurrent++;\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == '\\'') {\n\t\t\t\t\tstate = SCE_HPHP_SIMPLESTRING;\n\t\t\t\t\tphpStringDelimiter = \"\\'\";\n\t\t\t\t} else if (ch == '$' && IsPhpWordStart(chNext)) {\n\t\t\t\t\tstate = SCE_HPHP_VARIABLE;\n\t\t\t\t} else if (IsOperator(ch)) {\n\t\t\t\t\tstate = SCE_HPHP_OPERATOR;\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HPHP_NUMBER:\n\t\t\tif (phpNumber.check(chNext, chNext2)) {\n\t\t\t\tstyler.ColourTo(i, phpNumber.isInvalid() ? SCE_HPHP_DEFAULT : SCE_HPHP_NUMBER);\n\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HPHP_VARIABLE:\n\t\t\tif (!IsPhpWordChar(chNext)) {\n\t\t\t\tstyler.ColourTo(i, SCE_HPHP_VARIABLE);\n\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HPHP_COMMENT:\n\t\t\tif (ch == '/' && chPrev == '*') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HPHP_COMMENTLINE:\n\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HPHP_HSTRING:\n\t\t\tif (ch == '\\\\' && ((phpStringDelimiter == \"\\\"\") || chNext == '$' || chNext == '{')) {\n\t\t\t\t// skip the next char\n\t\t\t\ti++;\n\t\t\t} else if (((ch == '{' && chNext == '$') || (ch == '$' && chNext == '{'))\n\t\t\t\t&& IsPhpWordStart(chNext2)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HPHP_COMPLEX_VARIABLE;\n\t\t\t} else if (ch == '$' && IsPhpWordStart(chNext)) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HPHP_HSTRING_VARIABLE;\n\t\t\t} else if (styler.Match(i, phpStringDelimiter.c_str())) {\n\t\t\t\tif (phpStringDelimiter == \"\\\"\") {\n\t\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t\t} else if (lineStartVisibleChars == 1) {\n\t\t\t\t\tconst int psdLength = static_cast<int>(phpStringDelimiter.length());\n\t\t\t\t\tif (!IsPhpWordChar(styler.SafeGetCharAt(i + psdLength))) {\n\t\t\t\t\t\ti += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;\n\t\t\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t\t\t\tif (foldHeredoc) levelCurrent--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HPHP_SIMPLESTRING:\n\t\t\tif (phpStringDelimiter == \"\\'\") {\n\t\t\t\tif (ch == '\\\\') {\n\t\t\t\t\t// skip the next char\n\t\t\t\t\ti++;\n\t\t\t\t} else if (ch == '\\'') {\n\t\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (lineStartVisibleChars == 1 && styler.Match(i, phpStringDelimiter.c_str())) {\n\t\t\t\tconst int psdLength = static_cast<int>(phpStringDelimiter.length());\n\t\t\t\tif (!IsPhpWordChar(styler.SafeGetCharAt(i + psdLength))) {\n\t\t\t\t\ti += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;\n\t\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t\t\tif (foldHeredoc) levelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HPHP_HSTRING_VARIABLE:\n\t\t\tif (!IsPhpWordChar(chNext)) {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HPHP_HSTRING;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HPHP_COMPLEX_VARIABLE:\n\t\t\tif (ch == '}') {\n\t\t\t\tstyler.ColourTo(i, StateToPrint);\n\t\t\t\tstate = SCE_HPHP_HSTRING;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_HPHP_OPERATOR:\n\t\tcase SCE_HPHP_DEFAULT:\n\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\tif (phpNumber.init(ch, chNext, chNext2)) {\n\t\t\t\tif (phpNumber.isFinished()) {\n\t\t\t\t\tstyler.ColourTo(i, phpNumber.isInvalid() ? SCE_HPHP_DEFAULT : SCE_HPHP_NUMBER);\n\t\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_HPHP_NUMBER;\n\t\t\t\t}\n\t\t\t} else if (IsAWordStart(ch)) {\n\t\t\t\tstate = SCE_HPHP_WORD;\n\t\t\t} else if (ch == '/' && chNext == '*') {\n\t\t\t\ti++;\n\t\t\t\tstate = SCE_HPHP_COMMENT;\n\t\t\t} else if (ch == '/' && chNext == '/') {\n\t\t\t\ti++;\n\t\t\t\tstate = SCE_HPHP_COMMENTLINE;\n\t\t\t} else if (ch == '#' && chNext != '[') {\n\t\t\t\tstate = SCE_HPHP_COMMENTLINE;\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstate = SCE_HPHP_HSTRING;\n\t\t\t\tphpStringDelimiter = \"\\\"\";\n\t\t\t} else if (styler.Match(i, \"<<<\")) {\n\t\t\t\tbool isSimpleString = false;\n\t\t\t\ti = FindPhpStringDelimiter(phpStringDelimiter, i + 3, lengthDoc, styler, isSimpleString);\n\t\t\t\tif (!phpStringDelimiter.empty()) {\n\t\t\t\t\tstate = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);\n\t\t\t\t\tif (foldHeredoc) levelCurrent++;\n\t\t\t\t}\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstate = SCE_HPHP_SIMPLESTRING;\n\t\t\t\tphpStringDelimiter = \"\\'\";\n\t\t\t} else if (ch == '$' && IsPhpWordStart(chNext)) {\n\t\t\t\tstate = SCE_HPHP_VARIABLE;\n\t\t\t} else if (IsOperator(ch)) {\n\t\t\t\tstate = SCE_HPHP_OPERATOR;\n\t\t\t} else if ((state == SCE_HPHP_OPERATOR) && (IsASpace(ch))) {\n\t\t\t\tstate = SCE_HPHP_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\t\t///////////// end - PHP state handling\n\t\t}\n\n\t\t// Some of the above terminated their lexeme\n\n\t\tif (state == SCE_HB_DEFAULT) {    // One of the above succeeded\n\t\t\tif (ch == '\\\"') {\n\t\t\t\tstate = SCE_HB_STRING;\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstate = SCE_HB_COMMENTLINE;\n\t\t\t} else if (IsAWordStart(ch)) {\n\t\t\t\tstate = SCE_HB_WORD;\n\t\t\t} else if (IsOperator(ch)) {\n\t\t\t\tstyler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));\n\t\t\t}\n\t\t} else if (state == SCE_HJ_DEFAULT) {    // One of the above succeeded\n\t\t\tif (ch == '/' && chNext == '*') {\n\t\t\t\ti++;\n\t\t\t\tif (chNext2 == '*')\n\t\t\t\t\tstate = SCE_HJ_COMMENTDOC;\n\t\t\t\telse\n\t\t\t\t\tstate = SCE_HJ_COMMENT;\n\t\t\t} else if (ch == '/' && chNext == '/') {\n\t\t\t\tstate = SCE_HJ_COMMENTLINE;\n\t\t\t} else if (ch == '\\\"') {\n\t\t\t\tstate = SCE_HJ_DOUBLESTRING;\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstate = SCE_HJ_SINGLESTRING;\n\t\t\t} else if (ch == '`') {\n\t\t\t\tstate = SCE_HJ_TEMPLATELITERAL;\n\t\t\t} else if (IsAWordStart(ch)) {\n\t\t\t\tstate = SCE_HJ_WORD;\n\t\t\t} else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {\n\t\t\t\tstyler.ColourTo(i - 1, StateToPrint);\n\t\t\t\tstate = SCE_HJ_COMMENTLINE;\n\t\t\t\ti += 2;\n\t\t\t} else if (IsOperator(ch)) {\n\t\t\t\tstyler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch (state) {\n\tcase SCE_HJ_WORD:\n\t\tclassifyWordHTJS(styler.GetStartSegment(), lengthDoc - 1, keywordsJS,\n\t\t\tclassifierJavaScript, classifierJavaScriptServer, styler, inScriptType);\n\t\tbreak;\n\tcase SCE_HB_WORD:\n\t\tclassifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywordsVB, classifierBasic, styler, inScriptType);\n\t\tbreak;\n\tcase SCE_HP_WORD:\n\t\tclassifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywordsPy, classifierPython, styler, prevWord, inScriptType, isMako);\n\t\tbreak;\n\tcase SCE_HPHP_WORD:\n\t\tclassifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywordsPHP, classifierPHP, styler);\n\t\tbreak;\n\tdefault:\n\t\tStateToPrint = statePrintForState(state, inScriptType);\n\t\tif (static_cast<Sci_Position>(styler.GetStartSegment()) < lengthDoc)\n\t\t\tstyler.ColourTo(lengthDoc - 1, StateToPrint);\n\t\tbreak;\n\t}\n\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tif (fold) {\n\t\tconst int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\t\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n\t}\n\tstyler.Flush();\n}\n\nextern const LexerModule lmHTML(SCLEX_HTML, LexerHTML::LexerFactoryHTML, \"hypertext\", htmlWordListDesc);\nextern const LexerModule lmXML(SCLEX_XML, LexerHTML::LexerFactoryXML, \"xml\", htmlWordListDesc);\nextern const LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, LexerHTML::LexerFactoryPHPScript, \"phpscript\", phpscriptWordListDesc);\n"
  },
  {
    "path": "lexers/LexHaskell.cxx",
    "content": "/******************************************************************\n *    LexHaskell.cxx\n *\n *    A haskell lexer for the scintilla code control.\n *    Some stuff \"lended\" from LexPython.cxx and LexCPP.cxx.\n *    External lexer stuff inspired from the caml external lexer.\n *    Folder copied from Python's.\n *\n *    Written by Tobias Engvall - tumm at dtek dot chalmers dot se\n *\n *    Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com\n *\n *    Improved by kudah <kudahkukarek@gmail.com>\n *\n *    TODO:\n *    * A proper lexical folder to fold group declarations, comments, pragmas,\n *      #ifdefs, explicit layout, lists, tuples, quasi-quotes, splces, etc, etc,\n *      etc.\n *\n *****************************************************************/\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"CharacterCategory.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\n// See https://github.com/ghc/ghc/blob/master/compiler/parser/Lexer.x#L1682\n// Note, letter modifiers are prohibited.\n\nstatic int u_iswupper (int ch) {\n   CharacterCategory c = CategoriseCharacter(ch);\n   return c == ccLu || c == ccLt;\n}\n\nstatic int u_iswalpha (int ch) {\n   CharacterCategory c = CategoriseCharacter(ch);\n   return c == ccLl || c == ccLu || c == ccLt || c == ccLo;\n}\n\nstatic int u_iswalnum (int ch) {\n   CharacterCategory c = CategoriseCharacter(ch);\n   return c == ccLl || c == ccLu || c == ccLt || c == ccLo\n       || c == ccNd || c == ccNo;\n}\n\nstatic int u_IsHaskellSymbol(int ch) {\n   CharacterCategory c = CategoriseCharacter(ch);\n   return c == ccPc || c == ccPd || c == ccPo\n       || c == ccSm || c == ccSc || c == ccSk || c == ccSo;\n}\n\nstatic inline bool IsHaskellLetter(const int ch) {\n   if (IsASCII(ch)) {\n      return (ch >= 'a' && ch <= 'z')\n          || (ch >= 'A' && ch <= 'Z');\n   } else {\n      return u_iswalpha(ch) != 0;\n   }\n}\n\nstatic inline bool IsHaskellAlphaNumeric(const int ch) {\n   if (IsASCII(ch)) {\n      return IsAlphaNumeric(ch);\n   } else {\n      return u_iswalnum(ch) != 0;\n   }\n}\n\nstatic inline bool IsHaskellUpperCase(const int ch) {\n   if (IsASCII(ch)) {\n      return ch >= 'A' && ch <= 'Z';\n   } else {\n      return u_iswupper(ch) != 0;\n   }\n}\n\nstatic inline bool IsAnHaskellOperatorChar(const int ch) {\n   if (IsASCII(ch)) {\n      return\n         (  ch == '!' || ch == '#' || ch == '$' || ch == '%'\n         || ch == '&' || ch == '*' || ch == '+' || ch == '-'\n         || ch == '.' || ch == '/' || ch == ':' || ch == '<'\n         || ch == '=' || ch == '>' || ch == '?' || ch == '@'\n         || ch == '^' || ch == '|' || ch == '~' || ch == '\\\\');\n   } else {\n      return u_IsHaskellSymbol(ch) != 0;\n   }\n}\n\nstatic inline bool IsAHaskellWordStart(const int ch) {\n   return IsHaskellLetter(ch) || ch == '_';\n}\n\nstatic inline bool IsAHaskellWordChar(const int ch) {\n   return (  IsHaskellAlphaNumeric(ch)\n          || ch == '_'\n          || ch == '\\'');\n}\n\nstatic inline bool IsCommentBlockStyle(int style) {\n   return (style >= SCE_HA_COMMENTBLOCK && style <= SCE_HA_COMMENTBLOCK3);\n}\n\nstatic inline bool IsCommentStyle(int style) {\n   return (style >= SCE_HA_COMMENTLINE && style <= SCE_HA_COMMENTBLOCK3)\n       || ( style == SCE_HA_LITERATE_COMMENT\n         || style == SCE_HA_LITERATE_CODEDELIM);\n}\n\n// styles which do not belong to Haskell, but to external tools\nstatic inline bool IsExternalStyle(int style) {\n   return ( style == SCE_HA_PREPROCESSOR\n         || style == SCE_HA_LITERATE_COMMENT\n         || style == SCE_HA_LITERATE_CODEDELIM);\n}\n\nstatic inline int CommentBlockStyleFromNestLevel(const unsigned int nestLevel) {\n   return SCE_HA_COMMENTBLOCK + (nestLevel % 3);\n}\n\n// Mangled version of lexlib/Accessor.cxx IndentAmount.\n// Modified to treat comment blocks as whitespace\n// plus special case for commentline/preprocessor.\nstatic int HaskellIndentAmount(Accessor &styler, const Sci_Position line) {\n\n   // Determines the indentation level of the current line\n   // Comment blocks are treated as whitespace\n\n   Sci_Position pos = styler.LineStart(line);\n   Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\n   char ch = styler[pos];\n   int style = styler.StyleAt(pos);\n\n   int indent = 0;\n   bool inPrevPrefix = line > 0;\n\n   Sci_Position posPrev = inPrevPrefix ? styler.LineStart(line-1) : 0;\n\n   while ((  ch == ' ' || ch == '\\t'\n          || IsCommentBlockStyle(style)\n          || style == SCE_HA_LITERATE_CODEDELIM)\n         && (pos < eol_pos)) {\n      if (inPrevPrefix) {\n         char chPrev = styler[posPrev++];\n         if (chPrev != ' ' && chPrev != '\\t') {\n            inPrevPrefix = false;\n         }\n      }\n      if (ch == '\\t') {\n         indent = (indent / 8 + 1) * 8;\n      } else { // Space or comment block\n         indent++;\n      }\n      pos++;\n      ch = styler[pos];\n      style = styler.StyleAt(pos);\n   }\n\n   indent += SC_FOLDLEVELBASE;\n   // if completely empty line or the start of a comment or preprocessor...\n   if (  styler.LineStart(line) == styler.Length()\n      || ch == ' '\n      || ch == '\\t'\n      || ch == '\\n'\n      || ch == '\\r'\n      || IsCommentStyle(style)\n      || style == SCE_HA_PREPROCESSOR)\n      return indent | SC_FOLDLEVELWHITEFLAG;\n   else\n      return indent;\n}\n\nstruct OptionsHaskell {\n   bool magicHash;\n   bool allowQuotes;\n   bool implicitParams;\n   bool highlightSafe;\n   bool cpp;\n   bool stylingWithinPreprocessor;\n   bool fold;\n   bool foldComment;\n   bool foldCompact;\n   bool foldImports;\n   OptionsHaskell() {\n      magicHash = true;       // Widespread use, enabled by default.\n      allowQuotes = true;     // Widespread use, enabled by default.\n      implicitParams = false; // Fell out of favor, seldom used, disabled.\n      highlightSafe = true;   // Moderately used, doesn't hurt to enable.\n      cpp = true;             // Widespread use, enabled by default;\n      stylingWithinPreprocessor = false;\n      fold = false;\n      foldComment = false;\n      foldCompact = false;\n      foldImports = false;\n   }\n};\n\nstatic const char * const haskellWordListDesc[] = {\n   \"Keywords\",\n   \"FFI\",\n   \"Reserved operators\",\n   0\n};\n\nstruct OptionSetHaskell : public OptionSet<OptionsHaskell> {\n   OptionSetHaskell() {\n      DefineProperty(\"lexer.haskell.allow.hash\", &OptionsHaskell::magicHash,\n         \"Set to 0 to disallow the '#' character at the end of identifiers and \"\n         \"literals with the haskell lexer \"\n         \"(GHC -XMagicHash extension)\");\n\n      DefineProperty(\"lexer.haskell.allow.quotes\", &OptionsHaskell::allowQuotes,\n         \"Set to 0 to disable highlighting of Template Haskell name quotations \"\n         \"and promoted constructors \"\n         \"(GHC -XTemplateHaskell and -XDataKinds extensions)\");\n\n      DefineProperty(\"lexer.haskell.allow.questionmark\", &OptionsHaskell::implicitParams,\n         \"Set to 1 to allow the '?' character at the start of identifiers \"\n         \"with the haskell lexer \"\n         \"(GHC & Hugs -XImplicitParams extension)\");\n\n      DefineProperty(\"lexer.haskell.import.safe\", &OptionsHaskell::highlightSafe,\n         \"Set to 0 to disallow \\\"safe\\\" keyword in imports \"\n         \"(GHC -XSafe, -XTrustworthy, -XUnsafe extensions)\");\n\n      DefineProperty(\"lexer.haskell.cpp\", &OptionsHaskell::cpp,\n         \"Set to 0 to disable C-preprocessor highlighting \"\n         \"(-XCPP extension)\");\n\n      DefineProperty(\"styling.within.preprocessor\", &OptionsHaskell::stylingWithinPreprocessor,\n         \"For Haskell code, determines whether all preprocessor code is styled in the \"\n         \"preprocessor style (0, the default) or only from the initial # to the end \"\n         \"of the command word(1).\"\n         );\n\n      DefineProperty(\"fold\", &OptionsHaskell::fold);\n\n      DefineProperty(\"fold.comment\", &OptionsHaskell::foldComment);\n\n      DefineProperty(\"fold.compact\", &OptionsHaskell::foldCompact);\n\n      DefineProperty(\"fold.haskell.imports\", &OptionsHaskell::foldImports,\n         \"Set to 1 to enable folding of import declarations\");\n\n      DefineWordListSets(haskellWordListDesc);\n   }\n};\n\nclass LexerHaskell : public DefaultLexer {\n   bool literate;\n   Sci_Position firstImportLine;\n   int firstImportIndent;\n   WordList keywords;\n   WordList ffi;\n   WordList reserved_operators;\n   OptionsHaskell options;\n   OptionSetHaskell osHaskell;\n\n   enum HashCount {\n       oneHash\n      ,twoHashes\n      ,unlimitedHashes\n   };\n\n   enum KeywordMode {\n       HA_MODE_DEFAULT = 0\n      ,HA_MODE_IMPORT1 = 1 // after \"import\", before \"qualified\" or \"safe\" or package name or module name.\n      ,HA_MODE_IMPORT2 = 2 // after module name, before \"as\" or \"hiding\".\n      ,HA_MODE_IMPORT3 = 3 // after \"as\", before \"hiding\"\n      ,HA_MODE_MODULE  = 4 // after \"module\", before module name.\n      ,HA_MODE_FFI     = 5 // after \"foreign\", before FFI keywords\n      ,HA_MODE_TYPE    = 6 // after \"type\" or \"data\", before \"family\"\n   };\n\n   enum LiterateMode {\n       LITERATE_BIRD  = 0 // if '>' is the first character on the line,\n                          //   color '>' as a codedelim and the rest of\n                          //   the line as code.\n                          // else if \"\\begin{code}\" is the only word on the\n                          //    line except whitespace, switch to LITERATE_BLOCK\n                          // otherwise color the line as a literate comment.\n      ,LITERATE_BLOCK = 1 // if the string \"\\end{code}\" is encountered at column\n                          //   0 ignoring all later characters, color the line\n                          //   as a codedelim and switch to LITERATE_BIRD\n                          // otherwise color the line as code.\n   };\n\n   struct HaskellLineInfo {\n      unsigned int nestLevel; // 22 bits ought to be enough for anybody\n      unsigned int nonexternalStyle; // 5 bits, widen if number of styles goes\n                                     // beyond 31.\n      bool pragma;\n      LiterateMode lmode;\n      KeywordMode mode;\n\n      HaskellLineInfo(int state) :\n         nestLevel (state >> 10)\n       , nonexternalStyle ((state >> 5) & 0x1F)\n       , pragma ((state >> 4) & 0x1)\n       , lmode (static_cast<LiterateMode>((state >> 3) & 0x1))\n       , mode (static_cast<KeywordMode>(state & 0x7))\n         {}\n\n      int ToLineState() {\n         return\n              (nestLevel << 10)\n            | (nonexternalStyle << 5)\n            | (pragma << 4)\n            | (lmode << 3)\n            | mode;\n      }\n   };\n\n   inline void skipMagicHash(StyleContext &sc, const HashCount hashes) const {\n      if (options.magicHash && sc.ch == '#') {\n         sc.Forward();\n         if (hashes == twoHashes && sc.ch == '#') {\n            sc.Forward();\n         } else if (hashes == unlimitedHashes) {\n            while (sc.ch == '#') {\n               sc.Forward();\n            }\n         }\n      }\n   }\n\n   bool LineContainsImport(const Sci_Position line, Accessor &styler) const {\n      if (options.foldImports) {\n         Sci_Position currentPos = styler.LineStart(line);\n         int style = styler.StyleAt(currentPos);\n\n         Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\n         while (currentPos < eol_pos) {\n            int ch = styler[currentPos];\n            style = styler.StyleAt(currentPos);\n\n            if (ch == ' ' || ch == '\\t'\n             || IsCommentBlockStyle(style)\n             || style == SCE_HA_LITERATE_CODEDELIM) {\n               currentPos++;\n            } else {\n               break;\n            }\n         }\n\n         return (style == SCE_HA_KEYWORD\n              && styler.Match(currentPos, \"import\"));\n      } else {\n         return false;\n      }\n   }\n\n   inline int IndentAmountWithOffset(Accessor &styler, const Sci_Position line) const {\n      const int indent = HaskellIndentAmount(styler, line);\n      const int indentLevel = indent & SC_FOLDLEVELNUMBERMASK;\n      return indentLevel <= ((firstImportIndent - 1) + SC_FOLDLEVELBASE)\n               ? indent\n               : (indentLevel + firstImportIndent) | (indent & ~SC_FOLDLEVELNUMBERMASK);\n   }\n\n   inline int IndentLevelRemoveIndentOffset(const int indentLevel) const {\n      return indentLevel <= ((firstImportIndent - 1) + SC_FOLDLEVELBASE)\n            ? indentLevel\n            : indentLevel - firstImportIndent;\n   }\n\npublic:\n   LexerHaskell(bool literate_)\n      : DefaultLexer(literate_ ? \"literatehaskell\" : \"haskell\", literate_ ? SCLEX_LITERATEHASKELL : SCLEX_HASKELL)\n\t  , literate(literate_)\n      , firstImportLine(-1)\n      , firstImportIndent(0)\n      {}\n   virtual ~LexerHaskell() {}\n\n   void SCI_METHOD Release() override {\n      delete this;\n   }\n\n   int SCI_METHOD Version() const override {\n      return lvRelease5;\n   }\n\n   const char * SCI_METHOD PropertyNames() override {\n      return osHaskell.PropertyNames();\n   }\n\n   int SCI_METHOD PropertyType(const char *name) override {\n      return osHaskell.PropertyType(name);\n   }\n\n   const char * SCI_METHOD DescribeProperty(const char *name) override {\n      return osHaskell.DescribeProperty(name);\n   }\n\n   Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\n   const char * SCI_METHOD PropertyGet(const char *key) override {\n\t   return osHaskell.PropertyGet(key);\n   }\n\n   const char * SCI_METHOD DescribeWordListSets() override {\n      return osHaskell.DescribeWordListSets();\n   }\n\n   Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n   void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n   void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n   void * SCI_METHOD PrivateCall(int, void *) override {\n      return 0;\n   }\n\n   static ILexer5 *LexerFactoryHaskell() {\n      return new LexerHaskell(false);\n   }\n\n   static ILexer5 *LexerFactoryLiterateHaskell() {\n      return new LexerHaskell(true);\n   }\n};\n\nSci_Position SCI_METHOD LexerHaskell::PropertySet(const char *key, const char *val) {\n   if (osHaskell.PropertySet(&options, key, val)) {\n      return 0;\n   }\n   return -1;\n}\n\nSci_Position SCI_METHOD LexerHaskell::WordListSet(int n, const char *wl) {\n   WordList *wordListN = 0;\n   switch (n) {\n   case 0:\n      wordListN = &keywords;\n      break;\n   case 1:\n      wordListN = &ffi;\n      break;\n   case 2:\n      wordListN = &reserved_operators;\n      break;\n   }\n   Sci_Position firstModification = -1;\n   if (wordListN) {\n      WordList wlNew;\n      wlNew.Set(wl);\n      if (*wordListN != wlNew) {\n         wordListN->Set(wl);\n         firstModification = 0;\n      }\n   }\n   return firstModification;\n}\n\nvoid SCI_METHOD LexerHaskell::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle\n                                 ,IDocument *pAccess) {\n   LexAccessor styler(pAccess);\n\n   Sci_Position lineCurrent = styler.GetLine(startPos);\n\n   HaskellLineInfo hs = HaskellLineInfo(lineCurrent ? styler.GetLineState(lineCurrent-1) : 0);\n\n   // Do not leak onto next line\n   if (initStyle == SCE_HA_STRINGEOL)\n      initStyle = SCE_HA_DEFAULT;\n   else if (initStyle == SCE_HA_LITERATE_CODEDELIM)\n      initStyle = hs.nonexternalStyle;\n\n   StyleContext sc(startPos, length, initStyle, styler);\n\n   int base = 10;\n   bool dot = false;\n\n   bool inDashes = false;\n   bool alreadyInTheMiddleOfOperator = false;\n\n   assert(!(IsCommentBlockStyle(initStyle) && hs.nestLevel == 0));\n\n   while (sc.More()) {\n      // Check for state end\n\n      if (!IsExternalStyle(sc.state)) {\n         hs.nonexternalStyle = sc.state;\n      }\n\n      // For lexer to work, states should unconditionally forward at least one\n      // character.\n      // If they don't, they should still check if they are at line end and\n      // forward if so.\n      // If a state forwards more than one character, it should check every time\n      // that it is not a line end and cease forwarding otherwise.\n      if (sc.atLineEnd) {\n         // Remember the line state for future incremental lexing\n         styler.SetLineState(lineCurrent, hs.ToLineState());\n         lineCurrent++;\n      }\n\n      // Handle line continuation generically.\n      if (sc.ch == '\\\\' && (sc.chNext == '\\n' || sc.chNext == '\\r')\n         && (  sc.state == SCE_HA_STRING\n            || sc.state == SCE_HA_PREPROCESSOR)) {\n         // Remember the line state for future incremental lexing\n         styler.SetLineState(lineCurrent, hs.ToLineState());\n         lineCurrent++;\n\n         sc.Forward();\n         if (sc.ch == '\\r' && sc.chNext == '\\n') {\n            sc.Forward();\n         }\n         sc.Forward();\n\n         continue;\n      }\n\n      if (sc.atLineStart) {\n\n         if (sc.state == SCE_HA_STRING || sc.state == SCE_HA_CHARACTER) {\n            // Prevent SCE_HA_STRINGEOL from leaking back to previous line\n            sc.SetState(sc.state);\n         }\n\n         if (literate && hs.lmode == LITERATE_BIRD) {\n            if (!IsExternalStyle(sc.state)) {\n               sc.SetState(SCE_HA_LITERATE_COMMENT);\n            }\n         }\n      }\n\n      // External\n         // Literate\n      if (  literate && hs.lmode == LITERATE_BIRD && sc.atLineStart\n         && sc.ch == '>') {\n            sc.SetState(SCE_HA_LITERATE_CODEDELIM);\n            sc.ForwardSetState(hs.nonexternalStyle);\n      }\n      else if (literate && hs.lmode == LITERATE_BIRD && sc.atLineStart\n            && (  sc.ch == ' ' || sc.ch == '\\t'\n               || sc.Match(\"\\\\begin{code}\"))) {\n         sc.SetState(sc.state);\n\n         while ((sc.ch == ' ' || sc.ch == '\\t') && sc.More())\n            sc.Forward();\n\n         if (sc.Match(\"\\\\begin{code}\")) {\n            sc.Forward(static_cast<int>(strlen(\"\\\\begin{code}\")));\n\n            bool correct = true;\n\n            while (!sc.atLineEnd && sc.More()) {\n               if (sc.ch != ' ' && sc.ch != '\\t') {\n                  correct = false;\n               }\n               sc.Forward();\n            }\n\n            if (correct) {\n               sc.ChangeState(SCE_HA_LITERATE_CODEDELIM); // color the line end\n               hs.lmode = LITERATE_BLOCK;\n            }\n         }\n      }\n      else if (literate && hs.lmode == LITERATE_BLOCK && sc.atLineStart\n            && sc.Match(\"\\\\end{code}\")) {\n         sc.SetState(SCE_HA_LITERATE_CODEDELIM);\n\n         sc.Forward(static_cast<int>(strlen(\"\\\\end{code}\")));\n\n         while (!sc.atLineEnd && sc.More()) {\n            sc.Forward();\n         }\n\n         sc.SetState(SCE_HA_LITERATE_COMMENT);\n         hs.lmode = LITERATE_BIRD;\n      }\n         // Preprocessor\n      else if (sc.atLineStart && sc.ch == '#' && options.cpp\n            && (!options.stylingWithinPreprocessor || sc.state == SCE_HA_DEFAULT)) {\n         sc.SetState(SCE_HA_PREPROCESSOR);\n         sc.Forward();\n      }\n            // Literate\n      else if (sc.state == SCE_HA_LITERATE_COMMENT) {\n         sc.Forward();\n      }\n      else if (sc.state == SCE_HA_LITERATE_CODEDELIM) {\n         sc.ForwardSetState(hs.nonexternalStyle);\n      }\n            // Preprocessor\n      else if (sc.state == SCE_HA_PREPROCESSOR) {\n         if (sc.atLineEnd) {\n            sc.SetState(options.stylingWithinPreprocessor\n                        ? SCE_HA_DEFAULT\n                        : hs.nonexternalStyle);\n            sc.Forward(); // prevent double counting a line\n         } else if (options.stylingWithinPreprocessor && !IsHaskellLetter(sc.ch)) {\n            sc.SetState(SCE_HA_DEFAULT);\n         } else {\n            sc.Forward();\n         }\n      }\n      // Haskell\n         // Operator\n      else if (sc.state == SCE_HA_OPERATOR) {\n         int style = SCE_HA_OPERATOR;\n\n         if ( sc.ch == ':'\n            && !alreadyInTheMiddleOfOperator\n            // except \"::\"\n            && !( sc.chNext == ':'\n               && !IsAnHaskellOperatorChar(sc.GetRelative(2)))) {\n            style = SCE_HA_CAPITAL;\n         }\n\n         alreadyInTheMiddleOfOperator = false;\n\n         while (IsAnHaskellOperatorChar(sc.ch))\n               sc.Forward();\n\n         char s[100];\n         sc.GetCurrent(s, sizeof(s));\n\n         if (reserved_operators.InList(s))\n            style = SCE_HA_RESERVED_OPERATOR;\n\n         sc.ChangeState(style);\n         sc.SetState(SCE_HA_DEFAULT);\n      }\n         // String\n      else if (sc.state == SCE_HA_STRING) {\n         if (sc.atLineEnd) {\n            sc.ChangeState(SCE_HA_STRINGEOL);\n            sc.ForwardSetState(SCE_HA_DEFAULT);\n         } else if (sc.ch == '\\\"') {\n            sc.Forward();\n            skipMagicHash(sc, oneHash);\n            sc.SetState(SCE_HA_DEFAULT);\n         } else if (sc.ch == '\\\\') {\n            sc.Forward(2);\n         } else {\n            sc.Forward();\n         }\n      }\n         // Char\n      else if (sc.state == SCE_HA_CHARACTER) {\n         if (sc.atLineEnd) {\n            sc.ChangeState(SCE_HA_STRINGEOL);\n            sc.ForwardSetState(SCE_HA_DEFAULT);\n         } else if (sc.ch == '\\'') {\n            sc.Forward();\n            skipMagicHash(sc, oneHash);\n            sc.SetState(SCE_HA_DEFAULT);\n         } else if (sc.ch == '\\\\') {\n            sc.Forward(2);\n         } else {\n            sc.Forward();\n         }\n      }\n         // Number\n      else if (sc.state == SCE_HA_NUMBER) {\n         if (sc.atLineEnd) {\n            sc.SetState(SCE_HA_DEFAULT);\n            sc.Forward(); // prevent double counting a line\n         } else if (IsADigit(sc.ch, base)) {\n            sc.Forward();\n         } else if (sc.ch=='.' && dot && IsADigit(sc.chNext, base)) {\n            sc.Forward(2);\n            dot = false;\n         } else if ((base == 10) &&\n                    (sc.ch == 'e' || sc.ch == 'E') &&\n                    (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {\n            sc.Forward();\n            if (sc.ch == '+' || sc.ch == '-')\n                sc.Forward();\n         } else {\n            skipMagicHash(sc, twoHashes);\n            sc.SetState(SCE_HA_DEFAULT);\n         }\n      }\n         // Keyword or Identifier\n      else if (sc.state == SCE_HA_IDENTIFIER) {\n         int style = IsHaskellUpperCase(sc.ch) ? SCE_HA_CAPITAL : SCE_HA_IDENTIFIER;\n\n         assert(IsAHaskellWordStart(sc.ch));\n\n         sc.Forward();\n\n         while (sc.More()) {\n            if (IsAHaskellWordChar(sc.ch)) {\n               sc.Forward();\n            } else if (sc.ch == '.' && style == SCE_HA_CAPITAL) {\n               if (IsHaskellUpperCase(sc.chNext)) {\n                  sc.Forward();\n                  style = SCE_HA_CAPITAL;\n               } else if (IsAHaskellWordStart(sc.chNext)) {\n                  sc.Forward();\n                  style = SCE_HA_IDENTIFIER;\n               } else if (IsAnHaskellOperatorChar(sc.chNext)) {\n                  sc.Forward();\n                  style = sc.ch == ':' ? SCE_HA_CAPITAL : SCE_HA_OPERATOR;\n                  while (IsAnHaskellOperatorChar(sc.ch))\n                     sc.Forward();\n                  break;\n               } else {\n                  break;\n               }\n            } else {\n               break;\n            }\n         }\n\n         skipMagicHash(sc, unlimitedHashes);\n\n         char s[100];\n         sc.GetCurrent(s, sizeof(s));\n\n         KeywordMode new_mode = HA_MODE_DEFAULT;\n\n         if (keywords.InList(s)) {\n            style = SCE_HA_KEYWORD;\n         } else if (style == SCE_HA_CAPITAL) {\n            if (hs.mode == HA_MODE_IMPORT1 || hs.mode == HA_MODE_IMPORT3) {\n               style    = SCE_HA_MODULE;\n               new_mode = HA_MODE_IMPORT2;\n            } else if (hs.mode == HA_MODE_MODULE) {\n               style = SCE_HA_MODULE;\n            }\n         } else if (hs.mode == HA_MODE_IMPORT1 &&\n                    strcmp(s,\"qualified\") == 0) {\n             style    = SCE_HA_KEYWORD;\n             new_mode = HA_MODE_IMPORT1;\n         } else if (options.highlightSafe &&\n                    hs.mode == HA_MODE_IMPORT1 &&\n                    strcmp(s,\"safe\") == 0) {\n             style    = SCE_HA_KEYWORD;\n             new_mode = HA_MODE_IMPORT1;\n         } else if (hs.mode == HA_MODE_IMPORT2) {\n             if (strcmp(s,\"as\") == 0) {\n                style    = SCE_HA_KEYWORD;\n                new_mode = HA_MODE_IMPORT3;\n            } else if (strcmp(s,\"hiding\") == 0) {\n                style     = SCE_HA_KEYWORD;\n            }\n         } else if (hs.mode == HA_MODE_TYPE) {\n            if (strcmp(s,\"family\") == 0)\n               style    = SCE_HA_KEYWORD;\n         }\n\n         if (hs.mode == HA_MODE_FFI) {\n            if (ffi.InList(s)) {\n               style = SCE_HA_KEYWORD;\n               new_mode = HA_MODE_FFI;\n            }\n         }\n\n         sc.ChangeState(style);\n         sc.SetState(SCE_HA_DEFAULT);\n\n         if (strcmp(s,\"import\") == 0 && hs.mode != HA_MODE_FFI)\n            new_mode = HA_MODE_IMPORT1;\n         else if (strcmp(s,\"module\") == 0)\n            new_mode = HA_MODE_MODULE;\n         else if (strcmp(s,\"foreign\") == 0)\n            new_mode = HA_MODE_FFI;\n         else if (strcmp(s,\"type\") == 0\n               || strcmp(s,\"data\") == 0)\n            new_mode = HA_MODE_TYPE;\n\n         hs.mode = new_mode;\n      }\n\n         // Comments\n            // Oneliner\n      else if (sc.state == SCE_HA_COMMENTLINE) {\n         if (sc.atLineEnd) {\n            sc.SetState(hs.pragma ? SCE_HA_PRAGMA : SCE_HA_DEFAULT);\n            sc.Forward(); // prevent double counting a line\n         } else if (inDashes && sc.ch != '-' && !hs.pragma) {\n            inDashes = false;\n            if (IsAnHaskellOperatorChar(sc.ch)) {\n               alreadyInTheMiddleOfOperator = true;\n               sc.ChangeState(SCE_HA_OPERATOR);\n            }\n         } else {\n            sc.Forward();\n         }\n      }\n            // Nested\n      else if (IsCommentBlockStyle(sc.state)) {\n         if (sc.Match('{','-')) {\n            sc.SetState(CommentBlockStyleFromNestLevel(hs.nestLevel));\n            sc.Forward(2);\n            hs.nestLevel++;\n         } else if (sc.Match('-','}')) {\n            sc.Forward(2);\n            assert(hs.nestLevel > 0);\n            if (hs.nestLevel > 0)\n               hs.nestLevel--;\n            sc.SetState(\n               hs.nestLevel == 0\n                  ? (hs.pragma ? SCE_HA_PRAGMA : SCE_HA_DEFAULT)\n                  : CommentBlockStyleFromNestLevel(hs.nestLevel - 1));\n         } else {\n            sc.Forward();\n         }\n      }\n            // Pragma\n      else if (sc.state == SCE_HA_PRAGMA) {\n         if (sc.Match(\"#-}\")) {\n            hs.pragma = false;\n            sc.Forward(3);\n            sc.SetState(SCE_HA_DEFAULT);\n         } else if (sc.Match('-','-')) {\n            sc.SetState(SCE_HA_COMMENTLINE);\n            sc.Forward(2);\n            inDashes = false;\n         } else if (sc.Match('{','-')) {\n            sc.SetState(CommentBlockStyleFromNestLevel(hs.nestLevel));\n            sc.Forward(2);\n            hs.nestLevel = 1;\n         } else {\n            sc.Forward();\n         }\n      }\n            // New state?\n      else if (sc.state == SCE_HA_DEFAULT) {\n         // Digit\n         if (IsADigit(sc.ch)) {\n            hs.mode = HA_MODE_DEFAULT;\n\n            sc.SetState(SCE_HA_NUMBER);\n            if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) {\n               // Match anything starting with \"0x\" or \"0X\", too\n               sc.Forward(2);\n               base = 16;\n               dot = false;\n            } else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) {\n               // Match anything starting with \"0o\" or \"0O\", too\n               sc.Forward(2);\n               base = 8;\n               dot = false;\n            } else {\n               sc.Forward();\n               base = 10;\n               dot = true;\n            }\n         }\n         // Pragma\n         else if (sc.Match(\"{-#\")) {\n            hs.pragma = true;\n            sc.SetState(SCE_HA_PRAGMA);\n            sc.Forward(3);\n         }\n         // Comment line\n         else if (sc.Match('-','-')) {\n            sc.SetState(SCE_HA_COMMENTLINE);\n            sc.Forward(2);\n            inDashes = true;\n         }\n         // Comment block\n         else if (sc.Match('{','-')) {\n            sc.SetState(CommentBlockStyleFromNestLevel(hs.nestLevel));\n            sc.Forward(2);\n            hs.nestLevel = 1;\n         }\n         // String\n         else if (sc.ch == '\\\"') {\n            sc.SetState(SCE_HA_STRING);\n            sc.Forward();\n         }\n         // Character or quoted name or promoted term\n         else if (sc.ch == '\\'') {\n            hs.mode = HA_MODE_DEFAULT;\n\n            sc.SetState(SCE_HA_CHARACTER);\n            sc.Forward();\n\n            if (options.allowQuotes) {\n               // Quoted type ''T\n               if (sc.ch=='\\'' && IsAHaskellWordStart(sc.chNext)) {\n                  sc.Forward();\n                  sc.ChangeState(SCE_HA_IDENTIFIER);\n               } else if (sc.chNext != '\\'') {\n                  // Quoted name 'n or promoted constructor 'N\n                  if (IsAHaskellWordStart(sc.ch)) {\n                     sc.ChangeState(SCE_HA_IDENTIFIER);\n                  // Promoted constructor operator ':~>\n                  } else if (sc.ch == ':') {\n                     alreadyInTheMiddleOfOperator = false;\n                     sc.ChangeState(SCE_HA_OPERATOR);\n                  // Promoted list or tuple '[T]\n                  } else if (sc.ch == '[' || sc.ch== '(') {\n                     sc.ChangeState(SCE_HA_OPERATOR);\n                     sc.ForwardSetState(SCE_HA_DEFAULT);\n                  }\n               }\n            }\n         }\n         // Operator starting with '?' or an implicit parameter\n         else if (sc.ch == '?') {\n            hs.mode = HA_MODE_DEFAULT;\n\n            alreadyInTheMiddleOfOperator = false;\n            sc.SetState(SCE_HA_OPERATOR);\n\n            if (  options.implicitParams\n               && IsAHaskellWordStart(sc.chNext)\n               && !IsHaskellUpperCase(sc.chNext)) {\n               sc.Forward();\n               sc.ChangeState(SCE_HA_IDENTIFIER);\n            }\n         }\n         // Operator\n         else if (IsAnHaskellOperatorChar(sc.ch)) {\n            hs.mode = HA_MODE_DEFAULT;\n\n            sc.SetState(SCE_HA_OPERATOR);\n         }\n         // Braces and punctuation\n         else if (sc.ch == ',' || sc.ch == ';'\n               || sc.ch == '(' || sc.ch == ')'\n               || sc.ch == '[' || sc.ch == ']'\n               || sc.ch == '{' || sc.ch == '}') {\n            sc.SetState(SCE_HA_OPERATOR);\n            sc.ForwardSetState(SCE_HA_DEFAULT);\n         }\n         // Keyword or Identifier\n         else if (IsAHaskellWordStart(sc.ch)) {\n            sc.SetState(SCE_HA_IDENTIFIER);\n         // Something we don't care about\n         } else {\n            sc.Forward();\n         }\n      }\n            // This branch should never be reached.\n      else {\n         assert(false);\n         sc.Forward();\n      }\n   }\n   sc.Complete();\n}\n\nvoid SCI_METHOD LexerHaskell::Fold(Sci_PositionU startPos, Sci_Position length, int // initStyle\n                                  ,IDocument *pAccess) {\n   if (!options.fold)\n      return;\n\n   Accessor styler(pAccess, NULL);\n\n   Sci_Position lineCurrent = styler.GetLine(startPos);\n\n   if (lineCurrent <= firstImportLine) {\n      firstImportLine = -1; // readjust first import position\n      firstImportIndent = 0;\n   }\n\n   const Sci_Position maxPos = startPos + length;\n   const Sci_Position maxLines =\n      maxPos == styler.Length()\n         ? styler.GetLine(maxPos)\n         : styler.GetLine(maxPos - 1);  // Requested last line\n   const Sci_Position docLines = styler.GetLine(styler.Length()); // Available last line\n\n   // Backtrack to previous non-blank line so we can determine indent level\n   // for any white space lines\n   // and so we can fix any preceding fold level (which is why we go back\n   // at least one line in all cases)\n   bool importHere = LineContainsImport(lineCurrent, styler);\n   int indentCurrent = IndentAmountWithOffset(styler, lineCurrent);\n\n   while (lineCurrent > 0) {\n      lineCurrent--;\n      importHere = LineContainsImport(lineCurrent, styler);\n      indentCurrent = IndentAmountWithOffset(styler, lineCurrent);\n      if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))\n         break;\n   }\n\n   int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\n   if (importHere) {\n      indentCurrentLevel = IndentLevelRemoveIndentOffset(indentCurrentLevel);\n      if (firstImportLine == -1) {\n         firstImportLine = lineCurrent;\n         firstImportIndent = (1 + indentCurrentLevel) - SC_FOLDLEVELBASE;\n      }\n      if (firstImportLine != lineCurrent) {\n         indentCurrentLevel++;\n      }\n   }\n\n   indentCurrent = indentCurrentLevel | (indentCurrent & ~SC_FOLDLEVELNUMBERMASK);\n\n   // Process all characters to end of requested range\n   //that hangs over the end of the range.  Cap processing in all cases\n   // to end of document.\n   while (lineCurrent <= docLines && lineCurrent <= maxLines) {\n\n      // Gather info\n      Sci_Position lineNext = lineCurrent + 1;\n      importHere = false;\n      int indentNext = indentCurrent;\n\n      if (lineNext <= docLines) {\n         // Information about next line is only available if not at end of document\n         importHere = LineContainsImport(lineNext, styler);\n         indentNext = IndentAmountWithOffset(styler, lineNext);\n      }\n      if (indentNext & SC_FOLDLEVELWHITEFLAG)\n         indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;\n\n      // Skip past any blank lines for next indent level info; we skip also\n      // comments (all comments, not just those starting in column 0)\n      // which effectively folds them into surrounding code rather\n      // than screwing up folding.\n\n      while (lineNext < docLines && (indentNext & SC_FOLDLEVELWHITEFLAG)) {\n         lineNext++;\n         importHere = LineContainsImport(lineNext, styler);\n         indentNext = IndentAmountWithOffset(styler, lineNext);\n      }\n\n      int indentNextLevel = indentNext & SC_FOLDLEVELNUMBERMASK;\n\n      if (importHere) {\n         indentNextLevel = IndentLevelRemoveIndentOffset(indentNextLevel);\n         if (firstImportLine == -1) {\n            firstImportLine = lineNext;\n            firstImportIndent = (1 + indentNextLevel) - SC_FOLDLEVELBASE;\n         }\n         if (firstImportLine != lineNext) {\n            indentNextLevel++;\n         }\n      }\n\n      indentNext = indentNextLevel | (indentNext & ~SC_FOLDLEVELNUMBERMASK);\n\n      const int levelBeforeComments = Maximum(indentCurrentLevel,indentNextLevel);\n\n      // Now set all the indent levels on the lines we skipped\n      // Do this from end to start.  Once we encounter one line\n      // which is indented more than the line after the end of\n      // the comment-block, use the level of the block before\n\n      Sci_Position skipLine = lineNext;\n      int skipLevel = indentNextLevel;\n\n      while (--skipLine > lineCurrent) {\n         int skipLineIndent = IndentAmountWithOffset(styler, skipLine);\n\n         if (options.foldCompact) {\n            if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > indentNextLevel) {\n               skipLevel = levelBeforeComments;\n            }\n\n            int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;\n\n            styler.SetLevel(skipLine, skipLevel | whiteFlag);\n         } else {\n            if (  (skipLineIndent & SC_FOLDLEVELNUMBERMASK) > indentNextLevel\n               && !(skipLineIndent & SC_FOLDLEVELWHITEFLAG)) {\n               skipLevel = levelBeforeComments;\n            }\n\n            styler.SetLevel(skipLine, skipLevel);\n         }\n      }\n\n      int lev = indentCurrent;\n\n      if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n         if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))\n            lev |= SC_FOLDLEVELHEADERFLAG;\n      }\n\n      // Set fold level for this line and move to next line\n      styler.SetLevel(lineCurrent, options.foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);\n\n      indentCurrent = indentNext;\n      indentCurrentLevel = indentNextLevel;\n      lineCurrent = lineNext;\n   }\n\n   // NOTE: Cannot set level of last line here because indentCurrent doesn't have\n   // header flag set; the loop above is crafted to take care of this case!\n   //styler.SetLevel(lineCurrent, indentCurrent);\n}\n\nextern const LexerModule lmHaskell(SCLEX_HASKELL, LexerHaskell::LexerFactoryHaskell, \"haskell\", haskellWordListDesc);\nextern const LexerModule lmLiterateHaskell(SCLEX_LITERATEHASKELL, LexerHaskell::LexerFactoryLiterateHaskell, \"literatehaskell\", haskellWordListDesc);\n"
  },
  {
    "path": "lexers/LexHex.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexHex.cxx\n ** Lexers for Motorola S-Record, Intel HEX and Tektronix extended HEX.\n **\n ** Written by Markus Heidelberg\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n/*\n *  Motorola S-Record\n * ===============================\n *\n * Each record (line) is built as follows:\n *\n *    field       digits          states\n *\n *  +----------+\n *  | start    |  1 ('S')         SCE_HEX_RECSTART\n *  +----------+\n *  | type     |  1               SCE_HEX_RECTYPE, (SCE_HEX_RECTYPE_UNKNOWN)\n *  +----------+\n *  | count    |  2               SCE_HEX_BYTECOUNT, SCE_HEX_BYTECOUNT_WRONG\n *  +----------+\n *  | address  |  4/6/8           SCE_HEX_NOADDRESS, SCE_HEX_DATAADDRESS, SCE_HEX_RECCOUNT, SCE_HEX_STARTADDRESS, (SCE_HEX_ADDRESSFIELD_UNKNOWN)\n *  +----------+\n *  | data     |  0..504/502/500  SCE_HEX_DATA_ODD, SCE_HEX_DATA_EVEN, SCE_HEX_DATA_EMPTY, (SCE_HEX_DATA_UNKNOWN)\n *  +----------+\n *  | checksum |  2               SCE_HEX_CHECKSUM, SCE_HEX_CHECKSUM_WRONG\n *  +----------+\n *\n *\n *  Intel HEX\n * ===============================\n *\n * Each record (line) is built as follows:\n *\n *    field       digits          states\n *\n *  +----------+\n *  | start    |  1 (':')         SCE_HEX_RECSTART\n *  +----------+\n *  | count    |  2               SCE_HEX_BYTECOUNT, SCE_HEX_BYTECOUNT_WRONG\n *  +----------+\n *  | address  |  4               SCE_HEX_NOADDRESS, SCE_HEX_DATAADDRESS, (SCE_HEX_ADDRESSFIELD_UNKNOWN)\n *  +----------+\n *  | type     |  2               SCE_HEX_RECTYPE, (SCE_HEX_RECTYPE_UNKNOWN)\n *  +----------+\n *  | data     |  0..510          SCE_HEX_DATA_ODD, SCE_HEX_DATA_EVEN, SCE_HEX_DATA_EMPTY, SCE_HEX_EXTENDEDADDRESS, SCE_HEX_STARTADDRESS, (SCE_HEX_DATA_UNKNOWN)\n *  +----------+\n *  | checksum |  2               SCE_HEX_CHECKSUM, SCE_HEX_CHECKSUM_WRONG\n *  +----------+\n *\n *\n * Folding:\n *\n *   Data records (type 0x00), which follow an extended address record (type\n *   0x02 or 0x04), can be folded. The extended address record is the fold\n *   point at fold level 0, the corresponding data records are set to level 1.\n *\n *   Any record, which is not a data record, sets the fold level back to 0.\n *   Any line, which is not a record (blank lines and lines starting with a\n *   character other than ':'), leaves the fold level unchanged.\n *\n *\n *  Tektronix extended HEX\n * ===============================\n *\n * Each record (line) is built as follows:\n *\n *    field       digits          states\n *\n *  +----------+\n *  | start    |  1 ('%')         SCE_HEX_RECSTART\n *  +----------+\n *  | length   |  2               SCE_HEX_BYTECOUNT, SCE_HEX_BYTECOUNT_WRONG\n *  +----------+\n *  | type     |  1               SCE_HEX_RECTYPE, (SCE_HEX_RECTYPE_UNKNOWN)\n *  +----------+\n *  | checksum |  2               SCE_HEX_CHECKSUM, SCE_HEX_CHECKSUM_WRONG\n *  +----------+\n *  | address  |  9               SCE_HEX_DATAADDRESS, SCE_HEX_STARTADDRESS, (SCE_HEX_ADDRESSFIELD_UNKNOWN)\n *  +----------+\n *  | data     |  0..241          SCE_HEX_DATA_ODD, SCE_HEX_DATA_EVEN\n *  +----------+\n *\n *\n *  General notes for all lexers\n * ===============================\n *\n * - Depending on where the helper functions are invoked, some of them have to\n *   read beyond the current position. In case of malformed data (record too\n *   short), it has to be ensured that this either does not have bad influence\n *   or will be captured deliberately.\n *\n * - States in parentheses in the upper format descriptions indicate that they\n *   should not appear in a valid hex file.\n *\n * - State SCE_HEX_GARBAGE means garbage data after the intended end of the\n *   record, the line is too long then. This state is used in all lexers.\n */\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// prototypes for general helper functions\nstatic inline bool IsNewline(const int ch);\nstatic int GetHexaNibble(char hd);\nstatic int GetHexaChar(char hd1, char hd2);\nstatic int GetHexaChar(Sci_PositionU pos, Accessor &styler);\nstatic bool ForwardWithinLine(StyleContext &sc, Sci_Position nb = 1);\nstatic bool PosInSameRecord(Sci_PositionU pos1, Sci_PositionU pos2, Accessor &styler);\nstatic Sci_Position CountByteCount(Sci_PositionU startPos, Sci_Position uncountedDigits, Accessor &styler);\nstatic int CalcChecksum(Sci_PositionU startPos, Sci_Position cnt, bool twosCompl, Accessor &styler);\n\n// prototypes for file format specific helper functions\nstatic Sci_PositionU GetSrecRecStartPosition(Sci_PositionU pos, Accessor &styler);\nstatic int GetSrecByteCount(Sci_PositionU recStartPos, Accessor &styler);\nstatic Sci_Position CountSrecByteCount(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetSrecAddressFieldSize(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetSrecAddressFieldType(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetSrecDataFieldType(Sci_PositionU recStartPos, Accessor &styler);\nstatic Sci_Position GetSrecRequiredDataFieldSize(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetSrecChecksum(Sci_PositionU recStartPos, Accessor &styler);\nstatic int CalcSrecChecksum(Sci_PositionU recStartPos, Accessor &styler);\n\nstatic Sci_PositionU GetIHexRecStartPosition(Sci_PositionU pos, Accessor &styler);\nstatic int GetIHexByteCount(Sci_PositionU recStartPos, Accessor &styler);\nstatic Sci_Position CountIHexByteCount(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetIHexAddressFieldType(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetIHexDataFieldType(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetIHexRequiredDataFieldSize(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetIHexChecksum(Sci_PositionU recStartPos, Accessor &styler);\nstatic int CalcIHexChecksum(Sci_PositionU recStartPos, Accessor &styler);\n\nstatic int GetTEHexDigitCount(Sci_PositionU recStartPos, Accessor &styler);\nstatic Sci_Position CountTEHexDigitCount(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetTEHexAddressFieldType(Sci_PositionU recStartPos, Accessor &styler);\nstatic int GetTEHexChecksum(Sci_PositionU recStartPos, Accessor &styler);\nstatic int CalcTEHexChecksum(Sci_PositionU recStartPos, Accessor &styler);\n\nstatic inline bool IsNewline(const int ch)\n{\n    return (ch == '\\n' || ch == '\\r');\n}\n\nstatic int GetHexaNibble(char hd)\n{\n\tint hexValue = 0;\n\n\tif (hd >= '0' && hd <= '9') {\n\t\thexValue += hd - '0';\n\t} else if (hd >= 'A' && hd <= 'F') {\n\t\thexValue += hd - 'A' + 10;\n\t} else if (hd >= 'a' && hd <= 'f') {\n\t\thexValue += hd - 'a' + 10;\n\t} else {\n\t\treturn -1;\n\t}\n\n\treturn hexValue;\n}\n\nstatic int GetHexaChar(char hd1, char hd2)\n{\n\tint hexValue = 0;\n\n\tif (hd1 >= '0' && hd1 <= '9') {\n\t\thexValue += 16 * (hd1 - '0');\n\t} else if (hd1 >= 'A' && hd1 <= 'F') {\n\t\thexValue += 16 * (hd1 - 'A' + 10);\n\t} else if (hd1 >= 'a' && hd1 <= 'f') {\n\t\thexValue += 16 * (hd1 - 'a' + 10);\n\t} else {\n\t\treturn -1;\n\t}\n\n\tif (hd2 >= '0' && hd2 <= '9') {\n\t\thexValue += hd2 - '0';\n\t} else if (hd2 >= 'A' && hd2 <= 'F') {\n\t\thexValue += hd2 - 'A' + 10;\n\t} else if (hd2 >= 'a' && hd2 <= 'f') {\n\t\thexValue += hd2 - 'a' + 10;\n\t} else {\n\t\treturn -1;\n\t}\n\n\treturn hexValue;\n}\n\nstatic int GetHexaChar(Sci_PositionU pos, Accessor &styler)\n{\n\tchar highNibble, lowNibble;\n\n\thighNibble = styler.SafeGetCharAt(pos);\n\tlowNibble = styler.SafeGetCharAt(pos + 1);\n\n\treturn GetHexaChar(highNibble, lowNibble);\n}\n\n// Forward <nb> characters, but abort (and return false) if hitting the line\n// end. Return true if forwarding within the line was possible.\n// Avoids influence on highlighting of the subsequent line if the current line\n// is malformed (too short).\nstatic bool ForwardWithinLine(StyleContext &sc, Sci_Position nb)\n{\n\tfor (Sci_Position i = 0; i < nb; i++) {\n\t\tif (sc.atLineEnd) {\n\t\t\t// line is too short\n\t\t\tsc.SetState(SCE_HEX_DEFAULT);\n\t\t\tsc.Forward();\n\t\t\treturn false;\n\t\t} else {\n\t\t\tsc.Forward();\n\t\t}\n\t}\n\n\treturn true;\n}\n\n// Checks whether the given positions are in the same record.\nstatic bool PosInSameRecord(Sci_PositionU pos1, Sci_PositionU pos2, Accessor &styler)\n{\n\treturn styler.GetLine(pos1) == styler.GetLine(pos2);\n}\n\n// Count the number of digit pairs from <startPos> till end of record, ignoring\n// <uncountedDigits> digits.\n// If the record is too short, a negative count may be returned.\nstatic Sci_Position CountByteCount(Sci_PositionU startPos, Sci_Position uncountedDigits, Accessor &styler)\n{\n\tSci_Position cnt;\n\tSci_PositionU pos;\n\n\tpos = startPos;\n\n\twhile (!IsNewline(styler.SafeGetCharAt(pos, '\\n'))) {\n\t\tpos++;\n\t}\n\n\t// number of digits in this line minus number of digits of uncounted fields\n\tcnt = static_cast<Sci_Position>(pos - startPos) - uncountedDigits;\n\n\t// Prepare round up if odd (digit pair incomplete), this way the byte\n\t// count is considered to be valid if the checksum is incomplete.\n\tif (cnt >= 0) {\n\t\tcnt++;\n\t}\n\n\t// digit pairs\n\tcnt /= 2;\n\n\treturn cnt;\n}\n\n// Calculate the checksum of the record.\n// <startPos> is the position of the first character of the starting digit\n// pair, <cnt> is the number of digit pairs.\nstatic int CalcChecksum(Sci_PositionU startPos, Sci_Position cnt, bool twosCompl, Accessor &styler)\n{\n\tint cs = 0;\n\n\tfor (Sci_PositionU pos = startPos; pos < startPos + cnt; pos += 2) {\n\t\tint val = GetHexaChar(pos, styler);\n\n\t\tif (val < 0) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// overflow does not matter\n\t\tcs += val;\n\t}\n\n\tif (twosCompl) {\n\t\t// low byte of two's complement\n\t\treturn -cs & 0xFF;\n\t} else {\n\t\t// low byte of one's complement\n\t\treturn ~cs & 0xFF;\n\t}\n}\n\n// Get the position of the record \"start\" field (first character in line) in\n// the record around position <pos>.\nstatic Sci_PositionU GetSrecRecStartPosition(Sci_PositionU pos, Accessor &styler)\n{\n\twhile (styler.SafeGetCharAt(pos) != 'S') {\n\t\tpos--;\n\t}\n\n\treturn pos;\n}\n\n// Get the value of the \"byte count\" field, it counts the number of bytes in\n// the subsequent fields (\"address\", \"data\" and \"checksum\" fields).\nstatic int GetSrecByteCount(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tint val;\n\n\tval = GetHexaChar(recStartPos + 2, styler);\n\tif (val < 0) {\n\t       val = 0;\n\t}\n\n\treturn val;\n}\n\n// Count the number of digit pairs for the \"address\", \"data\" and \"checksum\"\n// fields in this record. Has to be equal to the \"byte count\" field value.\n// If the record is too short, a negative count may be returned.\nstatic Sci_Position CountSrecByteCount(Sci_PositionU recStartPos, Accessor &styler)\n{\n\treturn CountByteCount(recStartPos, 4, styler);\n}\n\n// Get the size of the \"address\" field.\nstatic int GetSrecAddressFieldSize(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tswitch (styler.SafeGetCharAt(recStartPos + 1)) {\n\t\tcase '0':\n\t\tcase '1':\n\t\tcase '5':\n\t\tcase '9':\n\t\t\treturn 2; // 16 bit\n\n\t\tcase '2':\n\t\tcase '6':\n\t\tcase '8':\n\t\t\treturn 3; // 24 bit\n\n\t\tcase '3':\n\t\tcase '7':\n\t\t\treturn 4; // 32 bit\n\n\t\tdefault:\n\t\t\treturn 0;\n\t}\n}\n\n// Get the type of the \"address\" field content.\nstatic int GetSrecAddressFieldType(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tswitch (styler.SafeGetCharAt(recStartPos + 1)) {\n\t\tcase '0':\n\t\t\treturn SCE_HEX_NOADDRESS;\n\n\t\tcase '1':\n\t\tcase '2':\n\t\tcase '3':\n\t\t\treturn SCE_HEX_DATAADDRESS;\n\n\t\tcase '5':\n\t\tcase '6':\n\t\t\treturn SCE_HEX_RECCOUNT;\n\n\t\tcase '7':\n\t\tcase '8':\n\t\tcase '9':\n\t\t\treturn SCE_HEX_STARTADDRESS;\n\n\t\tdefault: // handle possible format extension in the future\n\t\t\treturn SCE_HEX_ADDRESSFIELD_UNKNOWN;\n\t}\n}\n\n// Get the type of the \"data\" field content.\nstatic int GetSrecDataFieldType(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tswitch (styler.SafeGetCharAt(recStartPos + 1)) {\n\t\tcase '0':\n\t\tcase '1':\n\t\tcase '2':\n\t\tcase '3':\n\t\t\treturn SCE_HEX_DATA_ODD;\n\n\t\tcase '5':\n\t\tcase '6':\n\t\tcase '7':\n\t\tcase '8':\n\t\tcase '9':\n\t\t\treturn SCE_HEX_DATA_EMPTY;\n\n\t\tdefault: // handle possible format extension in the future\n\t\t\treturn SCE_HEX_DATA_UNKNOWN;\n\t}\n}\n\n// Get the required size of the \"data\" field. Useless for block header and\n// ordinary data records (type S0, S1, S2, S3), return the value calculated\n// from the \"byte count\" and \"address field\" size in this case.\nstatic Sci_Position GetSrecRequiredDataFieldSize(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tswitch (styler.SafeGetCharAt(recStartPos + 1)) {\n\t\tcase '5':\n\t\tcase '6':\n\t\tcase '7':\n\t\tcase '8':\n\t\tcase '9':\n\t\t\treturn 0;\n\n\t\tdefault:\n\t\t\treturn GetSrecByteCount(recStartPos, styler)\n\t\t\t\t- GetSrecAddressFieldSize(recStartPos, styler)\n\t\t\t\t- 1; // -1 for checksum field\n\t}\n}\n\n// Get the value of the \"checksum\" field.\nstatic int GetSrecChecksum(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tint byteCount;\n\n\tbyteCount = GetSrecByteCount(recStartPos, styler);\n\n\treturn GetHexaChar(recStartPos + 2 + byteCount * 2, styler);\n}\n\n// Calculate the checksum of the record.\nstatic int CalcSrecChecksum(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tSci_Position byteCount;\n\n\tbyteCount = GetSrecByteCount(recStartPos, styler);\n\n\t// sum over \"byte count\", \"address\" and \"data\" fields (6..510 digits)\n\treturn CalcChecksum(recStartPos + 2, byteCount * 2, false, styler);\n}\n\n// Get the position of the record \"start\" field (first character in line) in\n// the record around position <pos>.\nstatic Sci_PositionU GetIHexRecStartPosition(Sci_PositionU pos, Accessor &styler)\n{\n\twhile (styler.SafeGetCharAt(pos) != ':') {\n\t\tpos--;\n\t}\n\n\treturn pos;\n}\n\n// Get the value of the \"byte count\" field, it counts the number of bytes in\n// the \"data\" field.\nstatic int GetIHexByteCount(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tint val;\n\n\tval = GetHexaChar(recStartPos + 1, styler);\n\tif (val < 0) {\n\t       val = 0;\n\t}\n\n\treturn val;\n}\n\n// Count the number of digit pairs for the \"data\" field in this record. Has to\n// be equal to the \"byte count\" field value.\n// If the record is too short, a negative count may be returned.\nstatic Sci_Position CountIHexByteCount(Sci_PositionU recStartPos, Accessor &styler)\n{\n\treturn CountByteCount(recStartPos, 11, styler);\n}\n\n// Get the type of the \"address\" field content.\nstatic int GetIHexAddressFieldType(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tif (!PosInSameRecord(recStartPos, recStartPos + 7, styler)) {\n\t\t// malformed (record too short)\n\t\t// type cannot be determined\n\t\treturn SCE_HEX_ADDRESSFIELD_UNKNOWN;\n\t}\n\n\tswitch (GetHexaChar(recStartPos + 7, styler)) {\n\t\tcase 0x00:\n\t\t\treturn SCE_HEX_DATAADDRESS;\n\n\t\tcase 0x01:\n\t\tcase 0x02:\n\t\tcase 0x03:\n\t\tcase 0x04:\n\t\tcase 0x05:\n\t\t\treturn SCE_HEX_NOADDRESS;\n\n\t\tdefault: // handle possible format extension in the future\n\t\t\treturn SCE_HEX_ADDRESSFIELD_UNKNOWN;\n\t}\n}\n\n// Get the type of the \"data\" field content.\nstatic int GetIHexDataFieldType(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tswitch (GetHexaChar(recStartPos + 7, styler)) {\n\t\tcase 0x00:\n\t\t\treturn SCE_HEX_DATA_ODD;\n\n\t\tcase 0x01:\n\t\t\treturn SCE_HEX_DATA_EMPTY;\n\n\t\tcase 0x02:\n\t\tcase 0x04:\n\t\t\treturn SCE_HEX_EXTENDEDADDRESS;\n\n\t\tcase 0x03:\n\t\tcase 0x05:\n\t\t\treturn SCE_HEX_STARTADDRESS;\n\n\t\tdefault: // handle possible format extension in the future\n\t\t\treturn SCE_HEX_DATA_UNKNOWN;\n\t}\n}\n\n// Get the required size of the \"data\" field. Useless for an ordinary data\n// record (type 00), return the \"byte count\" in this case.\nstatic int GetIHexRequiredDataFieldSize(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tswitch (GetHexaChar(recStartPos + 7, styler)) {\n\t\tcase 0x01:\n\t\t\treturn 0;\n\n\t\tcase 0x02:\n\t\tcase 0x04:\n\t\t\treturn 2;\n\n\t\tcase 0x03:\n\t\tcase 0x05:\n\t\t\treturn 4;\n\n\t\tdefault:\n\t\t\treturn GetIHexByteCount(recStartPos, styler);\n\t}\n}\n\n// Get the value of the \"checksum\" field.\nstatic int GetIHexChecksum(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tint byteCount;\n\n\tbyteCount = GetIHexByteCount(recStartPos, styler);\n\n\treturn GetHexaChar(recStartPos + 9 + byteCount * 2, styler);\n}\n\n// Calculate the checksum of the record.\nstatic int CalcIHexChecksum(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tint byteCount;\n\n\tbyteCount = GetIHexByteCount(recStartPos, styler);\n\n\t// sum over \"byte count\", \"address\", \"type\" and \"data\" fields (8..518 digits)\n\treturn CalcChecksum(recStartPos + 1, 8 + byteCount * 2, true, styler);\n}\n\n\n// Get the value of the \"record length\" field, it counts the number of digits in\n// the record excluding the percent.\nstatic int GetTEHexDigitCount(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tint val = GetHexaChar(recStartPos + 1, styler);\n\tif (val < 0)\n\t       val = 0;\n\n\treturn val;\n}\n\n// Count the number of digits in this record. Has to\n// be equal to the \"record length\" field value.\nstatic Sci_Position CountTEHexDigitCount(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tSci_PositionU pos;\n\n\tpos = recStartPos+1;\n\n\twhile (!IsNewline(styler.SafeGetCharAt(pos, '\\n'))) {\n\t\tpos++;\n\t}\n\n\treturn static_cast<Sci_Position>(pos - (recStartPos+1));\n}\n\n// Get the type of the \"address\" field content.\nstatic int GetTEHexAddressFieldType(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tswitch (styler.SafeGetCharAt(recStartPos + 3)) {\n\t\tcase '6':\n\t\t\treturn SCE_HEX_DATAADDRESS;\n\n\t\tcase '8':\n\t\t\treturn SCE_HEX_STARTADDRESS;\n\n\t\tdefault: // handle possible format extension in the future\n\t\t\treturn SCE_HEX_ADDRESSFIELD_UNKNOWN;\n\t}\n}\n\n// Get the value of the \"checksum\" field.\nstatic int GetTEHexChecksum(Sci_PositionU recStartPos, Accessor &styler)\n{\n\treturn GetHexaChar(recStartPos+4, styler);\n}\n\n// Calculate the checksum of the record (excluding the checksum field).\nstatic int CalcTEHexChecksum(Sci_PositionU recStartPos, Accessor &styler)\n{\n\tSci_PositionU pos = recStartPos +1;\n\tSci_PositionU length = GetTEHexDigitCount(recStartPos, styler);\n\n\tint cs = GetHexaNibble(styler.SafeGetCharAt(pos++));//length\n\tcs += GetHexaNibble(styler.SafeGetCharAt(pos++));//length\n\n\tcs += GetHexaNibble(styler.SafeGetCharAt(pos++));//type\n\n\tpos += 2;// jump over CS field\n\n\tfor (; pos <= recStartPos + length; ++pos) {\n\t\tint val = GetHexaNibble(styler.SafeGetCharAt(pos));\n\n\t\tif (val < 0) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// overflow does not matter\n\t\tcs += val;\n\t}\n\n\t// low byte\n\treturn cs & 0xFF;\n\n}\n\nstatic void ColouriseSrecDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler)\n{\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\twhile (sc.More()) {\n\t\tSci_PositionU recStartPos;\n\t\tSci_Position reqByteCount;\n\t\tSci_Position dataFieldSize;\n\t\tint byteCount, addrFieldSize, addrFieldType, dataFieldType;\n\t\tint cs1, cs2;\n\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_HEX_DEFAULT:\n\t\t\t\tif (sc.atLineStart && sc.Match('S')) {\n\t\t\t\t\tsc.SetState(SCE_HEX_RECSTART);\n\t\t\t\t}\n\t\t\t\tForwardWithinLine(sc);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_RECSTART:\n\t\t\t\trecStartPos = sc.currentPos - 1;\n\t\t\t\taddrFieldType = GetSrecAddressFieldType(recStartPos, styler);\n\n\t\t\t\tif (addrFieldType == SCE_HEX_ADDRESSFIELD_UNKNOWN) {\n\t\t\t\t\tsc.SetState(SCE_HEX_RECTYPE_UNKNOWN);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_HEX_RECTYPE);\n\t\t\t\t}\n\n\t\t\t\tForwardWithinLine(sc);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_RECTYPE:\n\t\t\tcase SCE_HEX_RECTYPE_UNKNOWN:\n\t\t\t\trecStartPos = sc.currentPos - 2;\n\t\t\t\tbyteCount = GetSrecByteCount(recStartPos, styler);\n\t\t\t\treqByteCount = GetSrecAddressFieldSize(recStartPos, styler)\n\t\t\t\t\t\t+ GetSrecRequiredDataFieldSize(recStartPos, styler)\n\t\t\t\t\t\t+ 1; // +1 for checksum field\n\n\t\t\t\tif (byteCount == CountSrecByteCount(recStartPos, styler)\n\t\t\t\t\t\t&& byteCount == reqByteCount) {\n\t\t\t\t\tsc.SetState(SCE_HEX_BYTECOUNT);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_HEX_BYTECOUNT_WRONG);\n\t\t\t\t}\n\n\t\t\t\tForwardWithinLine(sc, 2);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_BYTECOUNT:\n\t\t\tcase SCE_HEX_BYTECOUNT_WRONG:\n\t\t\t\trecStartPos = sc.currentPos - 4;\n\t\t\t\taddrFieldSize = GetSrecAddressFieldSize(recStartPos, styler);\n\t\t\t\taddrFieldType = GetSrecAddressFieldType(recStartPos, styler);\n\n\t\t\t\tsc.SetState(addrFieldType);\n\t\t\t\tForwardWithinLine(sc, addrFieldSize * 2);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_NOADDRESS:\n\t\t\tcase SCE_HEX_DATAADDRESS:\n\t\t\tcase SCE_HEX_RECCOUNT:\n\t\t\tcase SCE_HEX_STARTADDRESS:\n\t\t\tcase SCE_HEX_ADDRESSFIELD_UNKNOWN:\n\t\t\t\trecStartPos = GetSrecRecStartPosition(sc.currentPos, styler);\n\t\t\t\tdataFieldType = GetSrecDataFieldType(recStartPos, styler);\n\n\t\t\t\t// Using the required size here if possible has the effect that the\n\t\t\t\t// checksum is highlighted at a fixed position after this field for\n\t\t\t\t// specific record types, independent on the \"byte count\" value.\n\t\t\t\tdataFieldSize = GetSrecRequiredDataFieldSize(recStartPos, styler);\n\n\t\t\t\tsc.SetState(dataFieldType);\n\n\t\t\t\tif (dataFieldType == SCE_HEX_DATA_ODD) {\n\t\t\t\t\tfor (int i = 0; i < dataFieldSize * 2; i++) {\n\t\t\t\t\t\tif ((i & 0x3) == 0) {\n\t\t\t\t\t\t\tsc.SetState(SCE_HEX_DATA_ODD);\n\t\t\t\t\t\t} else if ((i & 0x3) == 2) {\n\t\t\t\t\t\t\tsc.SetState(SCE_HEX_DATA_EVEN);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!ForwardWithinLine(sc)) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tForwardWithinLine(sc, dataFieldSize * 2);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_DATA_ODD:\n\t\t\tcase SCE_HEX_DATA_EVEN:\n\t\t\tcase SCE_HEX_DATA_EMPTY:\n\t\t\tcase SCE_HEX_DATA_UNKNOWN:\n\t\t\t\trecStartPos = GetSrecRecStartPosition(sc.currentPos, styler);\n\t\t\t\tcs1 = CalcSrecChecksum(recStartPos, styler);\n\t\t\t\tcs2 = GetSrecChecksum(recStartPos, styler);\n\n\t\t\t\tif (cs1 != cs2 || cs1 < 0 || cs2 < 0) {\n\t\t\t\t\tsc.SetState(SCE_HEX_CHECKSUM_WRONG);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_HEX_CHECKSUM);\n\t\t\t\t}\n\n\t\t\t\tForwardWithinLine(sc, 2);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_CHECKSUM:\n\t\t\tcase SCE_HEX_CHECKSUM_WRONG:\n\t\t\tcase SCE_HEX_GARBAGE:\n\t\t\t\t// record finished or line too long\n\t\t\t\tsc.SetState(SCE_HEX_GARBAGE);\n\t\t\t\tForwardWithinLine(sc);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// prevent endless loop in faulty state\n\t\t\t\tsc.SetState(SCE_HEX_DEFAULT);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void ColouriseIHexDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler)\n{\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\twhile (sc.More()) {\n\t\tSci_PositionU recStartPos;\n\t\tint byteCount, addrFieldType, dataFieldSize, dataFieldType;\n\t\tint cs1, cs2;\n\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_HEX_DEFAULT:\n\t\t\t\tif (sc.atLineStart && sc.Match(':')) {\n\t\t\t\t\tsc.SetState(SCE_HEX_RECSTART);\n\t\t\t\t}\n\t\t\t\tForwardWithinLine(sc);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_RECSTART:\n\t\t\t\trecStartPos = sc.currentPos - 1;\n\t\t\t\tbyteCount = GetIHexByteCount(recStartPos, styler);\n\t\t\t\tdataFieldSize = GetIHexRequiredDataFieldSize(recStartPos, styler);\n\n\t\t\t\tif (byteCount == CountIHexByteCount(recStartPos, styler)\n\t\t\t\t\t\t&& byteCount == dataFieldSize) {\n\t\t\t\t\tsc.SetState(SCE_HEX_BYTECOUNT);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_HEX_BYTECOUNT_WRONG);\n\t\t\t\t}\n\n\t\t\t\tForwardWithinLine(sc, 2);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_BYTECOUNT:\n\t\t\tcase SCE_HEX_BYTECOUNT_WRONG:\n\t\t\t\trecStartPos = sc.currentPos - 3;\n\t\t\t\taddrFieldType = GetIHexAddressFieldType(recStartPos, styler);\n\n\t\t\t\tsc.SetState(addrFieldType);\n\t\t\t\tForwardWithinLine(sc, 4);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_NOADDRESS:\n\t\t\tcase SCE_HEX_DATAADDRESS:\n\t\t\tcase SCE_HEX_ADDRESSFIELD_UNKNOWN:\n\t\t\t\trecStartPos = sc.currentPos - 7;\n\t\t\t\taddrFieldType = GetIHexAddressFieldType(recStartPos, styler);\n\n\t\t\t\tif (addrFieldType == SCE_HEX_ADDRESSFIELD_UNKNOWN) {\n\t\t\t\t\tsc.SetState(SCE_HEX_RECTYPE_UNKNOWN);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_HEX_RECTYPE);\n\t\t\t\t}\n\n\t\t\t\tForwardWithinLine(sc, 2);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_RECTYPE:\n\t\t\tcase SCE_HEX_RECTYPE_UNKNOWN:\n\t\t\t\trecStartPos = sc.currentPos - 9;\n\t\t\t\tdataFieldType = GetIHexDataFieldType(recStartPos, styler);\n\n\t\t\t\t// Using the required size here if possible has the effect that the\n\t\t\t\t// checksum is highlighted at a fixed position after this field for\n\t\t\t\t// specific record types, independent on the \"byte count\" value.\n\t\t\t\tdataFieldSize = GetIHexRequiredDataFieldSize(recStartPos, styler);\n\n\t\t\t\tsc.SetState(dataFieldType);\n\n\t\t\t\tif (dataFieldType == SCE_HEX_DATA_ODD) {\n\t\t\t\t\tfor (int i = 0; i < dataFieldSize * 2; i++) {\n\t\t\t\t\t\tif ((i & 0x3) == 0) {\n\t\t\t\t\t\t\tsc.SetState(SCE_HEX_DATA_ODD);\n\t\t\t\t\t\t} else if ((i & 0x3) == 2) {\n\t\t\t\t\t\t\tsc.SetState(SCE_HEX_DATA_EVEN);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!ForwardWithinLine(sc)) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tForwardWithinLine(sc, dataFieldSize * 2);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_DATA_ODD:\n\t\t\tcase SCE_HEX_DATA_EVEN:\n\t\t\tcase SCE_HEX_DATA_EMPTY:\n\t\t\tcase SCE_HEX_EXTENDEDADDRESS:\n\t\t\tcase SCE_HEX_STARTADDRESS:\n\t\t\tcase SCE_HEX_DATA_UNKNOWN:\n\t\t\t\trecStartPos = GetIHexRecStartPosition(sc.currentPos, styler);\n\t\t\t\tcs1 = CalcIHexChecksum(recStartPos, styler);\n\t\t\t\tcs2 = GetIHexChecksum(recStartPos, styler);\n\n\t\t\t\tif (cs1 != cs2 || cs1 < 0 || cs2 < 0) {\n\t\t\t\t\tsc.SetState(SCE_HEX_CHECKSUM_WRONG);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_HEX_CHECKSUM);\n\t\t\t\t}\n\n\t\t\t\tForwardWithinLine(sc, 2);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_CHECKSUM:\n\t\t\tcase SCE_HEX_CHECKSUM_WRONG:\n\t\t\tcase SCE_HEX_GARBAGE:\n\t\t\t\t// record finished or line too long\n\t\t\t\tsc.SetState(SCE_HEX_GARBAGE);\n\t\t\t\tForwardWithinLine(sc);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// prevent endless loop in faulty state\n\t\t\t\tsc.SetState(SCE_HEX_DEFAULT);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void FoldIHexDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)\n{\n\tSci_PositionU endPos = startPos + length;\n\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent - 1);\n\n\tSci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1);\n\tint levelNext = SC_FOLDLEVELBASE; // default if no specific line found\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tbool atEOL = i == (lineStartNext - 1);\n\t\tint style = styler.StyleAt(i);\n\n\t\t// search for specific lines\n\t\tif (style == SCE_HEX_EXTENDEDADDRESS) {\n\t\t\t// extended addres record\n\t\t\tlevelNext = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\t} else if (style == SCE_HEX_DATAADDRESS\n\t\t\t|| (style == SCE_HEX_DEFAULT\n\t\t\t\t&& i == (Sci_PositionU)styler.LineStart(lineCurrent))) {\n\t\t\t// data record or no record start code at all\n\t\t\tif (levelCurrent & SC_FOLDLEVELHEADERFLAG) {\n\t\t\t\tlevelNext = SC_FOLDLEVELBASE + 1;\n\t\t\t} else {\n\t\t\t\t// continue level 0 or 1, no fold point\n\t\t\t\tlevelNext = levelCurrent;\n\t\t\t}\n\t\t}\n\n\t\tif (atEOL || (i == endPos - 1)) {\n\t\t\tstyler.SetLevel(lineCurrent, levelNext);\n\n\t\t\tlineCurrent++;\n\t\t\tlineStartNext = styler.LineStart(lineCurrent + 1);\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelNext = SC_FOLDLEVELBASE;\n\t\t}\n\t}\n}\n\nstatic void ColouriseTEHexDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler)\n{\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\twhile (sc.More()) {\n\t\tSci_PositionU recStartPos;\n\t\tint digitCount, addrFieldType;\n\t\tint cs1, cs2;\n\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_HEX_DEFAULT:\n\t\t\t\tif (sc.atLineStart && sc.Match('%')) {\n\t\t\t\t\tsc.SetState(SCE_HEX_RECSTART);\n\t\t\t\t}\n\t\t\t\tForwardWithinLine(sc);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_RECSTART:\n\n\t\t\t\trecStartPos = sc.currentPos - 1;\n\n\t\t\t\tif (GetTEHexDigitCount(recStartPos, styler) == CountTEHexDigitCount(recStartPos, styler)) {\n\t\t\t\t\tsc.SetState(SCE_HEX_BYTECOUNT);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_HEX_BYTECOUNT_WRONG);\n\t\t\t\t}\n\n\t\t\t\tForwardWithinLine(sc, 2);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_BYTECOUNT:\n\t\t\tcase SCE_HEX_BYTECOUNT_WRONG:\n\t\t\t\trecStartPos = sc.currentPos - 3;\n\t\t\t\taddrFieldType = GetTEHexAddressFieldType(recStartPos, styler);\n\n\t\t\t\tif (addrFieldType == SCE_HEX_ADDRESSFIELD_UNKNOWN) {\n\t\t\t\t\tsc.SetState(SCE_HEX_RECTYPE_UNKNOWN);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_HEX_RECTYPE);\n\t\t\t\t}\n\n\t\t\t\tForwardWithinLine(sc);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_RECTYPE:\n\t\t\tcase SCE_HEX_RECTYPE_UNKNOWN:\n\t\t\t\trecStartPos = sc.currentPos - 4;\n\t\t\t\tcs1 = CalcTEHexChecksum(recStartPos, styler);\n\t\t\t\tcs2 = GetTEHexChecksum(recStartPos, styler);\n\n\t\t\t\tif (cs1 != cs2 || cs1 < 0 || cs2 < 0) {\n\t\t\t\t\tsc.SetState(SCE_HEX_CHECKSUM_WRONG);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_HEX_CHECKSUM);\n\t\t\t\t}\n\n\t\t\t\tForwardWithinLine(sc, 2);\n\t\t\t\tbreak;\n\n\n\t\t\tcase SCE_HEX_CHECKSUM:\n\t\t\tcase SCE_HEX_CHECKSUM_WRONG:\n\t\t\t\trecStartPos = sc.currentPos - 6;\n\t\t\t\taddrFieldType = GetTEHexAddressFieldType(recStartPos, styler);\n\n\t\t\t\tsc.SetState(addrFieldType);\n\t\t\t\tForwardWithinLine(sc, 9);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_DATAADDRESS:\n\t\t\tcase SCE_HEX_STARTADDRESS:\n\t\t\tcase SCE_HEX_ADDRESSFIELD_UNKNOWN:\n\t\t\t\trecStartPos = sc.currentPos - 15;\n\t\t\t\tdigitCount = GetTEHexDigitCount(recStartPos, styler) - 14;\n\n\t\t\t\tsc.SetState(SCE_HEX_DATA_ODD);\n\n\t\t\t\tfor (int i = 0; i < digitCount; i++) {\n\t\t\t\t\tif ((i & 0x3) == 0) {\n\t\t\t\t\t\tsc.SetState(SCE_HEX_DATA_ODD);\n\t\t\t\t\t} else if ((i & 0x3) == 2) {\n\t\t\t\t\t\tsc.SetState(SCE_HEX_DATA_EVEN);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!ForwardWithinLine(sc)) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_HEX_DATA_ODD:\n\t\t\tcase SCE_HEX_DATA_EVEN:\n\t\t\tcase SCE_HEX_GARBAGE:\n\t\t\t\t// record finished or line too long\n\t\t\t\tsc.SetState(SCE_HEX_GARBAGE);\n\t\t\t\tForwardWithinLine(sc);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// prevent endless loop in faulty state\n\t\t\t\tsc.SetState(SCE_HEX_DEFAULT);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nextern const LexerModule lmSrec(SCLEX_SREC, ColouriseSrecDoc, \"srec\", 0, NULL);\nextern const LexerModule lmIHex(SCLEX_IHEX, ColouriseIHexDoc, \"ihex\", FoldIHexDoc, NULL);\nextern const LexerModule lmTEHex(SCLEX_TEHEX, ColouriseTEHexDoc, \"tehex\", 0, NULL);\n"
  },
  {
    "path": "lexers/LexHollywood.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexHollywood.cxx\n ** Lexer for Hollywood\n ** Written by Andreas Falkenhahn, based on the BlitzBasic/PureBasic/Lua lexers\n ** Thanks to Nicholai Benalal\n ** For more information on Hollywood, see http://www.hollywood-mal.com/\n ** Mail me (andreas <at> airsoftsoftwair <dot> de) for any bugs.\n ** This code is subject to the same license terms as the rest of the Scintilla project:\n ** The License.txt file describes the conditions under which this software may be distributed. \n **/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\n/* Bits:\n * 1  - whitespace\n * 2  - operator\n * 4  - identifier\n * 8  - decimal digit\n * 16 - hex digit\n * 32 - bin digit\n * 64 - letter\n */\nstatic int character_classification[128] =\n{\n\t0, // NUL ($0)\n\t0, // SOH ($1)\n\t0, // STX ($2)\n\t0, // ETX ($3)\n\t0, // EOT ($4)\n\t0, // ENQ ($5)\n\t0, // ACK ($6)\n\t0, // BEL ($7)\n\t0, // BS ($8)\n\t1, // HT ($9)\n\t1, // LF ($A)\n\t0, // VT ($B)\n\t0, // FF ($C)\n\t1, // CR ($D)\n\t0, // SO ($E)\n\t0, // SI ($F)\n\t0, // DLE ($10)\n\t0, // DC1 ($11)\n\t0, // DC2 ($12)\n\t0, // DC3 ($13)\n\t0, // DC4 ($14)\n\t0, // NAK ($15)\n\t0, // SYN ($16)\n\t0, // ETB ($17)\n\t0, // CAN ($18)\n\t0, // EM ($19)\n\t0, // SUB ($1A)\n\t0, // ESC ($1B)\n\t0, // FS ($1C)\n\t0, // GS ($1D)\n\t0, // RS ($1E)\n\t0, // US ($1F)\n\t1, // space ($20)\n\t4, // ! ($21)\n\t0, // \" ($22)\n\t0, // # ($23)\n\t4, // $ ($24)\n\t2, // % ($25)\n\t2, // & ($26)\n\t2, // ' ($27)\n\t2, // ( ($28)\n\t2, // ) ($29)\n\t2, // * ($2A)\n\t2, // + ($2B)\n\t2, // , ($2C)\n\t2, // - ($2D)\n\t// NB: we treat \".\" as an identifier although it is also an operator and a decimal digit\n\t// the reason why we treat it as an identifier is to support syntax highlighting for\n\t// plugin commands which always use a \".\" in their names, e.g. pdf.OpenDocument();\n\t// we handle the decimal digit case manually below so that 3.1415 and .123 is styled correctly\n\t// the collateral damage of treating \".\" as an identifier is that \".\" is never styled\n\t// SCE_HOLLYWOOD_OPERATOR\n\t4, // . ($2E) \n\t2, // / ($2F)\n\t28, // 0 ($30)\n\t28, // 1 ($31)\n\t28, // 2 ($32)\n\t28, // 3 ($33)\n\t28, // 4 ($34)\n\t28, // 5 ($35)\n\t28, // 6 ($36)\n\t28, // 7 ($37)\n\t28, // 8 ($38)\n\t28, // 9 ($39)\n\t2, // : ($3A)\n\t2, // ; ($3B)\n\t2, // < ($3C)\n\t2, // = ($3D)\n\t2, // > ($3E)\n\t2, // ? ($3F)\n\t0, // @ ($40)\n\t84, // A ($41)\n\t84, // B ($42)\n\t84, // C ($43)\n\t84, // D ($44)\n\t84, // E ($45)\n\t84, // F ($46)\n\t68, // G ($47)\n\t68, // H ($48)\n\t68, // I ($49)\n\t68, // J ($4A)\n\t68, // K ($4B)\n\t68, // L ($4C)\n\t68, // M ($4D)\n\t68, // N ($4E)\n\t68, // O ($4F)\n\t68, // P ($50)\n\t68, // Q ($51)\n\t68, // R ($52)\n\t68, // S ($53)\n\t68, // T ($54)\n\t68, // U ($55)\n\t68, // V ($56)\n\t68, // W ($57)\n\t68, // X ($58)\n\t68, // Y ($59)\n\t68, // Z ($5A)\n\t2, // [ ($5B)\n\t2, // \\ ($5C)\n\t2, // ] ($5D)\n\t2, // ^ ($5E)\n\t68, // _ ($5F)\n\t2, // ` ($60)\n\t84, // a ($61)\n\t84, // b ($62)\n\t84, // c ($63)\n\t84, // d ($64)\n\t84, // e ($65)\n\t84, // f ($66)\n\t68, // g ($67)\n\t68, // h ($68)\n\t68, // i ($69)\n\t68, // j ($6A)\n\t68, // k ($6B)\n\t68, // l ($6C)\n\t68, // m ($6D)\n\t68, // n ($6E)\n\t68, // o ($6F)\n\t68, // p ($70)\n\t68, // q ($71)\n\t68, // r ($72)\n\t68, // s ($73)\n\t68, // t ($74)\n\t68, // u ($75)\n\t68, // v ($76)\n\t68, // w ($77)\n\t68, // x ($78)\n\t68, // y ($79)\n\t68, // z ($7A)\n\t2, // { ($7B)\n\t2, // | ($7C)\n\t2, // } ($7D)\n\t2, // ~ ($7E)\n\t0, // &#127; ($7F)\n};\n\nstatic bool IsSpace(int c) {\n\treturn c < 128 && (character_classification[c] & 1);\n}\n\nstatic bool IsOperator(int c) {\n\treturn c < 128 && (character_classification[c] & 2);\n}\n\nstatic bool IsIdentifier(int c) {\n\treturn c < 128 && (character_classification[c] & 4);\n}\n\nstatic bool IsDigit(int c) {\n\treturn c < 128 && (character_classification[c] & 8);\n}\n\nstatic bool IsHexDigit(int c) {\n\treturn c < 128 && (character_classification[c] & 16);\n}\n\nstatic int LowerCase(int c)\n{\n\tif (c >= 'A' && c <= 'Z')\n\t\treturn 'a' + c - 'A';\n\treturn c;\n}\n\nstatic int CheckHollywoodFoldPoint(char const *token) {\n\tif (!strcmp(token, \"function\")) {\n\t\treturn 1;\n\t}\n\tif (!strcmp(token, \"endfunction\")) {\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n// An individual named option for use in an OptionSet\n\n// Options used for LexerHollywood\nstruct OptionsHollywood {\n\tbool fold;\n\tbool foldCompact;\n\tOptionsHollywood() {\n\t\tfold = false;\n\t\tfoldCompact = false;\n\t}\n};\n\nstatic const char * const hollywoodWordListDesc[] = {\n\t\"Hollywood keywords\",\n\t\"Hollywood standard API functions\",\n\t\"Hollywood plugin API functions\",\n\t\"Hollywood plugin methods\",\n\t0\n};\n\nstruct OptionSetHollywood : public OptionSet<OptionsHollywood> {\n\tOptionSetHollywood(const char * const wordListDescriptions[]) {\n\t\tDefineProperty(\"fold\", &OptionsHollywood::fold);\n\t\tDefineProperty(\"fold.compact\", &OptionsHollywood::foldCompact);\n\t\tDefineWordListSets(wordListDescriptions);\n\t}\n};\n\nclass LexerHollywood : public DefaultLexer {\n\tint (*CheckFoldPoint)(char const *);\n\tWordList keywordlists[4];\t\n\tOptionsHollywood options;\n\tOptionSetHollywood osHollywood;\npublic:\n\tLexerHollywood(int (*CheckFoldPoint_)(char const *), const char * const wordListDescriptions[]) :\n\t\t\t\t\t\t DefaultLexer(\"hollywood\", SCLEX_HOLLYWOOD),\n\t\t\t\t\t\t CheckFoldPoint(CheckFoldPoint_),\n\t\t\t\t\t\t osHollywood(wordListDescriptions) {\n\t}\n\tvirtual ~LexerHollywood() {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char * SCI_METHOD PropertyNames() override {\n\t\treturn osHollywood.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osHollywood.PropertyType(name);\n\t}\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osHollywood.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD PropertyGet(const char* key) override {\n\t\treturn osHollywood.PropertyGet(key);\n\t}\n\tconst char * SCI_METHOD DescribeWordListSets() override {\n\t\treturn osHollywood.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid * SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn 0;\n\t}\n\tstatic ILexer5 *LexerFactoryHollywood() {\n\t\treturn new LexerHollywood(CheckHollywoodFoldPoint, hollywoodWordListDesc);\n\t}\n};\n\nSci_Position SCI_METHOD LexerHollywood::PropertySet(const char *key, const char *val) {\n\tif (osHollywood.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerHollywood::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = 0;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywordlists[0];\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywordlists[1];\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywordlists[2];\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywordlists[3];\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tWordList wlNew;\n\t\twlNew.Set(wl);\n\t\tif (*wordListN != wlNew) {\n\t\t\twordListN->Set(wl);\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\t\n}\n\nvoid SCI_METHOD LexerHollywood::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\n\tstyler.StartAt(startPos);\n\tbool inString = false;\n\t\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\t// Can't use sc.More() here else we miss the last character\n\tfor (; ; sc.Forward())\n\t {\n\t \tif (sc.atLineStart) inString = false;\n\t \t\t\n\t \tif (sc.ch == '\\\"' && sc.chPrev != '\\\\') inString = !inString;\n\t \t\t\n\t\tif (sc.state == SCE_HOLLYWOOD_IDENTIFIER) {\n\t\t\tif (!IsIdentifier(sc.ch)) {\t\t\t\t\n\t\t\t\tchar s[100];\n\t\t\t\tint kstates[4] = {\n\t\t\t\t\tSCE_HOLLYWOOD_KEYWORD,\n\t\t\t\t\tSCE_HOLLYWOOD_STDAPI,\n\t\t\t\t\tSCE_HOLLYWOOD_PLUGINAPI,\n\t\t\t\t\tSCE_HOLLYWOOD_PLUGINMETHOD,\n\t\t\t\t};\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tfor (int i = 0; i < 4; i++) {\n\t\t\t\t\tif (keywordlists[i].InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(kstates[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_DEFAULT);\t\t\t\t\n\t\t\t}\n\t\t} else if (sc.state == SCE_HOLLYWOOD_OPERATOR) {\n\t\t\t\n\t\t\t// always reset to default on operators because otherwise\n\t\t\t// comments won't be recognized in sequences like \"+/* Hello*/\"\n\t\t\t// --> \"+/*\" would be recognized as a sequence of operators\n\t\t\t\n\t\t\t// if (!IsOperator(sc.ch)) sc.SetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t\tsc.SetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t\t\n\t\t} else if (sc.state == SCE_HOLLYWOOD_PREPROCESSOR) {\n\t\t\tif (!IsIdentifier(sc.ch))\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t} else if (sc.state == SCE_HOLLYWOOD_CONSTANT) {\n\t\t\tif (!IsIdentifier(sc.ch))\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t} else if (sc.state == SCE_HOLLYWOOD_NUMBER) {\n\t\t\tif (!IsDigit(sc.ch) && sc.ch != '.')\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t} else if (sc.state == SCE_HOLLYWOOD_HEXNUMBER) {\n\t\t\tif (!IsHexDigit(sc.ch))\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t} else if (sc.state == SCE_HOLLYWOOD_STRING) {\n\t\t\tif (sc.ch == '\"') {\n\t\t\t\tsc.ForwardSetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t\t}\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_HOLLYWOOD_COMMENT) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_HOLLYWOOD_COMMENTBLOCK) {\n\t\t\tif (sc.Match(\"*/\") && !inString) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_HOLLYWOOD_STRINGBLOCK) {\n\t\t\tif (sc.Match(\"]]\") && !inString) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_HOLLYWOOD_DEFAULT);\n\t\t\t}\t\t\t\n\t\t}\n\n\t\tif (sc.state == SCE_HOLLYWOOD_DEFAULT) {\n\t\t\tif (sc.Match(';')) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_COMMENT);\n\t\t\t} else if (sc.Match(\"/*\")) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_COMMENTBLOCK);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match(\"[[\")) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_STRINGBLOCK);\n\t\t\t\tsc.Forward();\t\t\t\t\n\t\t\t} else if (sc.Match('\"')) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_STRING);\n\t\t\t} else if (sc.Match('$')) { \n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_HEXNUMBER);\n\t\t\t} else if (sc.Match(\"0x\") || sc.Match(\"0X\")) {  // must be before IsDigit() because of 0x\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_HEXNUMBER);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '.' && (sc.chNext >= '0' && sc.chNext <= '9')) {  // \".1234\" style numbers\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_NUMBER);\n\t\t\t\tsc.Forward();\t\n\t\t\t} else if (IsDigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_NUMBER);\n\t\t\t} else if (sc.Match('#')) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_CONSTANT);\n\t\t\t} else if (sc.Match('@')) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_PREPROCESSOR);\t\n\t\t\t} else if (IsOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_OPERATOR);\n\t\t\t} else if (IsIdentifier(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_HOLLYWOOD_IDENTIFIER);\n\t\t\t}\n\t\t}\n\n\t\tif (!sc.More())\n\t\t\tbreak;\n\t}\n\tsc.Complete();\n}\n\nvoid SCI_METHOD LexerHollywood::Fold(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {\n\n\tif (!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\t\n\tSci_PositionU lengthDoc = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint done = 0;\n\tchar word[256];\n\tint wordlen = 0;\n\t\t\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (!done) {\n\t\t\tif (wordlen) { // are we scanning a token already?\n\t\t\t\tword[wordlen] = static_cast<char>(LowerCase(ch));\n\t\t\t\tif (!IsIdentifier(ch)) { // done with token\n\t\t\t\t\tword[wordlen] = '\\0';\n\t\t\t\t\tlevelCurrent += CheckFoldPoint(word);\n\t\t\t\t\tdone = 1;\n\t\t\t\t} else if (wordlen < 255) {\n\t\t\t\t\twordlen++;\n\t\t\t\t}\n\t\t\t} else { // start scanning at first non-whitespace character\n\t\t\t\tif (!IsSpace(ch)) {\n\t\t\t\t\tif (style != SCE_HOLLYWOOD_COMMENTBLOCK && IsIdentifier(ch)) {\n\t\t\t\t\t\tword[0] = static_cast<char>(LowerCase(ch));\n\t\t\t\t\t\twordlen = 1;\n\t\t\t\t\t} else // done with this line\n\t\t\t\t\t\tdone = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\t\t\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && options.foldCompact) {\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\t}\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0)) {\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t\tdone = 0;\n\t\t\twordlen = 0;\t\t\t\n\t\t}\n\t\tif (!IsSpace(ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\t\n}\n\nextern const LexerModule lmHollywood(SCLEX_HOLLYWOOD, LexerHollywood::LexerFactoryHollywood, \"hollywood\", hollywoodWordListDesc);\n"
  },
  {
    "path": "lexers/LexIndent.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexIndent.cxx\n ** Lexer for no language. Used for indentation-based folding of files.\n **/\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ColouriseIndentDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],\n                            Accessor &styler) {\n\t// Indent language means all style bytes are 0 so just mark the end - no need to fill in.\n\tif (length > 0) {\n\t\tstyler.StartAt(startPos + length - 1);\n\t\tstyler.StartSegment(startPos + length - 1);\n\t\tstyler.ColourTo(startPos + length - 1, 0);\n\t}\n}\n\nstatic void FoldIndentDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[], Accessor &styler) {\n\tint visibleCharsCurrent, visibleCharsNext;\n\tint levelCurrent, levelNext;\n\tSci_PositionU i, lineEnd;\n\tSci_PositionU lengthDoc   = startPos + length;\n\tSci_Position  lineCurrent = styler.GetLine(startPos);\n\n\ti       = styler.LineStart(lineCurrent  );\n\tlineEnd = styler.LineStart(lineCurrent+1)-1;\n\tif(lineEnd>=lengthDoc) lineEnd = lengthDoc-1;\n\twhile(styler[lineEnd]=='\\n' || styler[lineEnd]=='\\r') lineEnd--;\n\tfor(visibleCharsCurrent=0, levelCurrent=SC_FOLDLEVELBASE; !visibleCharsCurrent && i<=lineEnd; i++){\n\t\tif(isspacechar(styler[i])) levelCurrent++;\n\t\telse                       visibleCharsCurrent=1;\n\t}\n\n\tfor(; i<lengthDoc; lineCurrent++) {\n\t\ti       = styler.LineStart(lineCurrent+1);\n\t\tlineEnd = styler.LineStart(lineCurrent+2)-1;\n\t\tif(lineEnd>=lengthDoc) lineEnd = lengthDoc-1;\n\t\twhile(styler[lineEnd]=='\\n' || styler[lineEnd]=='\\r') lineEnd--;\n\t\tfor(visibleCharsNext=0, levelNext=SC_FOLDLEVELBASE; !visibleCharsNext && i<=lineEnd; i++){\n\t\t\tif(isspacechar(styler[i])) levelNext++;\n\t\t\telse                       visibleCharsNext=1;\n\t\t}\n\t\tint lev = levelCurrent;\n\t\tif(!visibleCharsCurrent) lev |= SC_FOLDLEVELWHITEFLAG;\n\t\telse if(levelNext > levelCurrent) lev |= SC_FOLDLEVELHEADERFLAG;\n\t\tstyler.SetLevel(lineCurrent, lev);\n\t\tlevelCurrent = levelNext;\n\t\tvisibleCharsCurrent = visibleCharsNext;\n\t}\n}\n\nextern const LexerModule lmIndent(SCLEX_INDENT, ColouriseIndentDoc, \"indent\", FoldIndentDoc);\n"
  },
  {
    "path": "lexers/LexInno.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexInno.cxx\n ** Lexer for Inno Setup scripts.\n **/\n// Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx.\n// Modified by Michael Heath.\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic bool innoIsBlank(int ch) {\n\treturn (ch == ' ') || (ch == '\\t');\n}\n\nstatic bool innoNextNotBlankIs(Sci_Position i, Accessor &styler, char needle) {\n\tchar ch;\n\n\twhile (i < styler.Length()) {\n\t\tch = styler.SafeGetCharAt(i);\n\n\t\tif (ch == needle)\n\t\t\treturn true;\n\n\t\tif (!innoIsBlank(ch))\n\t\t\treturn false;\n\n\t\ti++;\n\t}\n\treturn false;\n}\n\nstatic void ColouriseInnoDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler) {\n\tint state = SCE_INNO_DEFAULT;\n\tchar chPrev;\n\tchar ch = 0;\n\tchar chNext = styler[startPos];\n\tSci_Position lengthDoc = startPos + length;\n\tchar *buffer = new char[length + 1];\n\tSci_Position bufferCount = 0;\n\tbool isBOL, isEOL, isWS, isBOLWS = 0;\n\n\t// Save line state later with bitState and bitand with bit... to get line state\n\tint bitState = 0;\n\tint const bitCode = 1, bitMessages = 2, bitCommentCurly = 4, bitCommentRound = 8;\n\n\t// Get keyword lists\n\tWordList &sectionKeywords = *keywordLists[0];\n\tWordList &standardKeywords = *keywordLists[1];\n\tWordList &parameterKeywords = *keywordLists[2];\n\tWordList &preprocessorKeywords = *keywordLists[3];\n\tWordList &pascalKeywords = *keywordLists[4];\n\tWordList &userKeywords = *keywordLists[5];\n\n\t// Get line state\n\tSci_Position curLine = styler.GetLine(startPos);\n\tint curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;\n\tbool isCode = (curLineState & bitCode);\n\tbool isMessages = (curLineState & bitMessages);\n\tbool isCommentCurly = (curLineState & bitCommentCurly);\n\tbool isCommentRound = (curLineState & bitCommentRound);\n\tbool isCommentSlash = false;\n\n\t// Continue Pascal multline comment state\n\tif (isCommentCurly || isCommentRound)\n\t\tstate = SCE_INNO_COMMENT_PASCAL;\n\n\t// Go through all provided text segment\n\t// using the hand-written state machine shown below\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\n\tfor (Sci_Position i = startPos; i < lengthDoc; i++) {\n\t\tchPrev = ch;\n\t\tch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif (styler.IsLeadByte(ch)) {\n\t\t\tchNext = styler.SafeGetCharAt(i + 2);\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tisBOL = (chPrev == 0) || (chPrev == '\\n') || (chPrev == '\\r' && ch != '\\n');\n\t\tisBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\\t'));\n\t\tisEOL = (ch == '\\n' || ch == '\\r');\n\t\tisWS = (ch == ' ' || ch == '\\t');\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n')) {\n\t\t\t// Remember the line state for future incremental lexing\n\t\t\tcurLine = styler.GetLine(i);\n\t\t\tbitState = 0;\n\n\t\t\tif (isCode)\n\t\t\t\tbitState |= bitCode;\n\n\t\t\tif (isMessages)\n\t\t\t\tbitState |= bitMessages;\n\n\t\t\tif (isCommentCurly)\n\t\t\t\tbitState |= bitCommentCurly;\n\n\t\t\tif (isCommentRound)\n\t\t\t\tbitState |= bitCommentRound;\n\n\t\t\tstyler.SetLineState(curLine, bitState);\n\t\t}\n\n\t\tswitch(state) {\n\t\t\tcase SCE_INNO_DEFAULT:\n\t\t\t\tif (!isCode && ch == ';' && isBOLWS) {\n\t\t\t\t\t// Start of a comment\n\t\t\t\t\tstate = SCE_INNO_COMMENT;\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_COMMENT);\n\t\t\t\t} else if (ch == '[' && isBOLWS) {\n\t\t\t\t\t// Start of a section name\n\t\t\t\t\tstate = SCE_INNO_SECTION;\n\t\t\t\t\tbufferCount = 0;\n\t\t\t\t} else if (ch == '#' && isBOLWS) {\n\t\t\t\t\t// Start of a preprocessor directive\n\t\t\t\t\tstate = SCE_INNO_PREPROC;\n\t\t\t\t} else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {\n\t\t\t\t\t// Start of an inline expansion\n\t\t\t\t\tstate = SCE_INNO_INLINE_EXPANSION;\n\t\t\t\t} else if (isCode && ch == '{') {\n\t\t\t\t\t// Start of a Pascal comment\n\t\t\t\t\tstate = SCE_INNO_COMMENT_PASCAL;\n\t\t\t\t\tisCommentCurly = true;\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_COMMENT_PASCAL);\n\t\t\t\t} else if (isCode && (ch == '(' && chNext == '*')) {\n\t\t\t\t\t// Start of a Pascal comment\n\t\t\t\t\tstate = SCE_INNO_COMMENT_PASCAL;\n\t\t\t\t\tisCommentRound = true;\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_INNO_COMMENT_PASCAL);\n\t\t\t\t} else if (isCode && ch == '/' && chNext == '/') {\n\t\t\t\t\t// Start of C-style comment\n\t\t\t\t\tstate = SCE_INNO_COMMENT_PASCAL;\n\t\t\t\t\tisCommentSlash = true;\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_INNO_COMMENT_PASCAL);\n\t\t\t\t} else if (!isMessages && ch == '\"') {\n\t\t\t\t\t// Start of a double-quote string\n\t\t\t\t\tstate = SCE_INNO_STRING_DOUBLE;\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_STRING_DOUBLE);\n\t\t\t\t} else if (!isMessages && ch == '\\'') {\n\t\t\t\t\t// Start of a single-quote string\n\t\t\t\t\tstate = SCE_INNO_STRING_SINGLE;\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_STRING_SINGLE);\n\t\t\t\t} else if (!isMessages && IsASCII(ch) && (isalpha(ch) || (ch == '_'))) {\n\t\t\t\t\t// Start of an identifier\n\t\t\t\t\tstate = SCE_INNO_IDENTIFIER;\n\t\t\t\t\tbufferCount = 0;\n\t\t\t\t\tbuffer[bufferCount++] = static_cast<char>(tolower(ch));\n\t\t\t\t} else {\n\t\t\t\t\t// Style it the default style\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_INNO_COMMENT:\n\t\t\t\tif (isEOL) {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_COMMENT);\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_COMMENT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_INNO_IDENTIFIER:\n\t\t\t\tif (IsASCII(ch) && (isalnum(ch) || (ch == '_'))) {\n\t\t\t\t\tbuffer[bufferCount++] = static_cast<char>(tolower(ch));\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tbuffer[bufferCount] = '\\0';\n\n\t\t\t\t\t// Check if the buffer contains a keyword\n\t\t\t\t\tif (!isCode && standardKeywords.InList(buffer) && innoNextNotBlankIs(i, styler, '=')) {\n\t\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_KEYWORD);\n\t\t\t\t\t} else if (!isCode && parameterKeywords.InList(buffer) && innoNextNotBlankIs(i, styler, ':')) {\n\t\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_PARAMETER);\n\t\t\t\t\t} else if (isCode && pascalKeywords.InList(buffer)) {\n\t\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_KEYWORD_PASCAL);\n\t\t\t\t\t} else if (!isCode && userKeywords.InList(buffer)) {\n\t\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_KEYWORD_USER);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_DEFAULT);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Push back the faulty character\n\t\t\t\t\tchNext = styler[i--];\n\t\t\t\t\tch = chPrev;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_INNO_SECTION:\n\t\t\t\tif (ch == ']') {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tbuffer[bufferCount] = '\\0';\n\n\t\t\t\t\t// Check if the buffer contains a section name\n\t\t\t\t\tif (sectionKeywords.InList(buffer)) {\n\t\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_SECTION);\n\t\t\t\t\t\tisCode = !CompareCaseInsensitive(buffer, \"code\");\n\n\t\t\t\t\t\tisMessages = isCode ? false : (\n\t\t\t\t\t\t\t\t\t!CompareCaseInsensitive(buffer, \"custommessages\")\n\t\t\t\t\t\t\t\t\t|| !CompareCaseInsensitive(buffer, \"messages\"));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t} else if (IsASCII(ch) && (isalnum(ch) || (ch == '_'))) {\n\t\t\t\t\tbuffer[bufferCount++] = static_cast<char>(tolower(ch));\n\t\t\t\t} else {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_INNO_PREPROC:\n\t\t\t\tif (isWS || isEOL) {\n\t\t\t\t\tif (IsASCII(chPrev) && isalpha(chPrev)) {\n\t\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\t\tbuffer[bufferCount] = '\\0';\n\n\t\t\t\t\t\t// Check if the buffer contains a preprocessor directive\n\t\t\t\t\t\tif (preprocessorKeywords.InList(buffer)) {\n\t\t\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_PREPROC);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_DEFAULT);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Push back the faulty character\n\t\t\t\t\t\tchNext = styler[i--];\n\t\t\t\t\t\tch = chPrev;\n\t\t\t\t\t}\n\t\t\t\t} else if (IsASCII(ch) && isalpha(ch)) {\n\t\t\t\t\tif (chPrev == '#' || chPrev == ' ' || chPrev == '\\t')\n\t\t\t\t\t\tbufferCount = 0;\n\t\t\t\t\tbuffer[bufferCount++] = static_cast<char>(tolower(ch));\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_INNO_STRING_DOUBLE:\n\t\t\t\tif (ch == '\"') {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_STRING_DOUBLE);\n\t\t\t\t} else if (isEOL) {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_STRING_DOUBLE);\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_STRING_DOUBLE);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_INNO_STRING_SINGLE:\n\t\t\t\tif (ch == '\\'') {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_STRING_SINGLE);\n\t\t\t\t} else if (isEOL) {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_STRING_SINGLE);\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_STRING_SINGLE);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_INNO_INLINE_EXPANSION:\n\t\t\t\tif (ch == '}') {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_INLINE_EXPANSION);\n\t\t\t\t} else if (isEOL) {\n\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_INNO_COMMENT_PASCAL:\n\t\t\t\tif (isCommentSlash) {\n\t\t\t\t\tif (isEOL) {\n\t\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\t\tisCommentSlash = false;\n\t\t\t\t\t\tstyler.ColourTo(i - 1, SCE_INNO_COMMENT_PASCAL);\n\t\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_DEFAULT);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_COMMENT_PASCAL);\n\t\t\t\t\t}\n\t\t\t\t} else if (isCommentCurly) {\n\t\t\t\t\tif (ch == '}') {\n\t\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\t\tisCommentCurly = false;\n\t\t\t\t\t}\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_COMMENT_PASCAL);\n\t\t\t\t} else if (isCommentRound) {\n\t\t\t\t\tif (ch == ')' && chPrev == '*') {\n\t\t\t\t\t\tstate = SCE_INNO_DEFAULT;\n\t\t\t\t\t\tisCommentRound = false;\n\t\t\t\t\t}\n\t\t\t\t\tstyler.ColourTo(i, SCE_INNO_COMMENT_PASCAL);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t}\n\t}\n\tdelete []buffer;\n}\n\nstatic const char * const innoWordListDesc[] = {\n\t\"Sections\",\n\t\"Keywords\",\n\t\"Parameters\",\n\t\"Preprocessor directives\",\n\t\"Pascal keywords\",\n\t\"User defined keywords\",\n\t0\n};\n\nstatic void FoldInnoDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tSci_PositionU endPos = startPos + length;\n\tchar chNext = styler[startPos];\n\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\n\tbool sectionFlag = false;\n\tint levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;\n\tint level;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler[i + 1];\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tint style = styler.StyleAt(i);\n\n\t\tif (style == SCE_INNO_SECTION)\n\t\t\tsectionFlag = true;\n\n\t\tif (atEOL || i == endPos - 1) {\n\t\t\tif (sectionFlag) {\n\t\t\t\tlevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\t\t\tif (level == levelPrev)\n\t\t\t\t\tstyler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);\n\t\t\t} else {\n\t\t\t\tlevel = levelPrev & SC_FOLDLEVELNUMBERMASK;\n\t\t\t\tif (levelPrev & SC_FOLDLEVELHEADERFLAG)\n\t\t\t\t\tlevel++;\n\t\t\t}\n\n\t\t\tstyler.SetLevel(lineCurrent, level);\n\n\t\t\tlevelPrev = level;\n\t\t\tlineCurrent++;\n\t\t\tsectionFlag = false;\n\t\t}\n\t}\n}\n\nextern const LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, \"inno\", FoldInnoDoc, innoWordListDesc);\n"
  },
  {
    "path": "lexers/LexJSON.cxx",
    "content": "// Scintilla source code edit control\n/**\n * @file LexJSON.cxx\n * @date February 19, 2016\n * @brief Lexer for JSON and JSON-LD formats\n * @author nkmathew\n *\n * The License.txt file describes the conditions under which this software may\n * be distributed.\n *\n */\n\n#include <cstdlib>\n#include <cassert>\n#include <cctype>\n#include <cstdio>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\nconst char *const JSONWordListDesc[] = {\n\t\"JSON Keywords\",\n\t\"JSON-LD Keywords\",\n\tnullptr\n};\n\n/**\n * Used to detect compact IRI/URLs in JSON-LD without first looking ahead for the\n * colon separating the prefix and suffix\n *\n * https://www.w3.org/TR/json-ld/#dfn-compact-iri\n */\nstruct CompactIRI {\n\tint colonCount;\n\tbool foundInvalidChar;\n\tCharacterSet setCompactIRI;\n\tCompactIRI() {\n\t\tcolonCount = 0;\n\t\tfoundInvalidChar = false;\n\t\tsetCompactIRI = CharacterSet(CharacterSet::setAlpha, \"$_-\");\n\t}\n\tvoid resetState() noexcept {\n\t\tcolonCount = 0;\n\t\tfoundInvalidChar = false;\n\t}\n\tvoid checkChar(int ch) noexcept {\n\t\tif (ch == ':') {\n\t\t\tcolonCount++;\n\t\t} else {\n\t\t\tfoundInvalidChar |= !setCompactIRI.Contains(ch);\n\t\t}\n\t}\n\t[[nodiscard]] bool shouldHighlight() const noexcept {\n\t\treturn !foundInvalidChar && colonCount == 1;\n\t}\n};\n\n/**\n * Keeps track of escaped characters in strings as per:\n *\n * https://tools.ietf.org/html/rfc7159#section-7\n */\nstruct EscapeSequence {\n\tint digitsLeft;\n\tCharacterSet setHexDigits;\n\tCharacterSet setEscapeChars;\n\tEscapeSequence() {\n\t\tdigitsLeft = 0;\n\t\tsetHexDigits = CharacterSet(CharacterSet::setDigits, \"ABCDEFabcdef\");\n\t\tsetEscapeChars = CharacterSet(CharacterSet::setNone, \"\\\\\\\"tnbfru/\");\n\t}\n\t// Returns true if the following character is a valid escaped character\n\tbool newSequence(int nextChar) noexcept {\n\t\tdigitsLeft = 0;\n\t\tif (nextChar == 'u') {\n\t\t\tdigitsLeft = 5;\n\t\t} else if (!setEscapeChars.Contains(nextChar)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\t[[nodiscard]] bool atEscapeEnd() const noexcept {\n\t\treturn digitsLeft <= 0;\n\t}\n\t[[nodiscard]] bool isInvalidChar(int currChar) const noexcept {\n\t\treturn !setHexDigits.Contains(currChar);\n\t}\n};\n\nstruct OptionsJSON {\n\tbool foldCompact;\n\tbool fold;\n\tbool allowComments;\n\tbool escapeSequence;\n\tOptionsJSON() {\n\t\tfoldCompact = false;\n\t\tfold = false;\n\t\tallowComments = false;\n\t\tescapeSequence = false;\n\t}\n};\n\nstruct OptionSetJSON : public OptionSet<OptionsJSON> {\n\tOptionSetJSON() {\n\t\tDefineProperty(\"lexer.json.escape.sequence\", &OptionsJSON::escapeSequence,\n\t\t\t\t\t   \"Set to 1 to enable highlighting of escape sequences in strings\");\n\n\t\tDefineProperty(\"lexer.json.allow.comments\", &OptionsJSON::allowComments,\n\t\t\t\t\t   \"Set to 1 to enable highlighting of line/block comments in JSON\");\n\n\t\tDefineProperty(\"fold.compact\", &OptionsJSON::foldCompact);\n\t\tDefineProperty(\"fold\", &OptionsJSON::fold);\n\t\tDefineWordListSets(JSONWordListDesc);\n\t}\n};\n\nclass LexerJSON : public DefaultLexer {\n\tOptionsJSON options;\n\tOptionSetJSON optSetJSON;\n\tEscapeSequence escapeSeq;\n\tWordList keywordsJSON;\n\tWordList keywordsJSONLD;\n\tCharacterSet setOperators;\n\tCharacterSet setURL;\n\tCharacterSet setKeywordJSONLD;\n\tCharacterSet setKeywordJSON;\n\tCompactIRI compactIRI;\n\n\tstatic bool IsNextNonWhitespace(LexAccessor &styler, Sci_Position start, char ch) {\n\t\tSci_Position i = 0;\n\t\twhile (i < 50) {\n\t\t\ti++;\n\t\t\tconst char curr = styler.SafeGetCharAt(start+i, '\\0');\n\t\t\tconst char next = styler.SafeGetCharAt(start+i+1, '\\0');\n\t\t\tconst bool atEOL = (curr == '\\r' && next != '\\n') || (curr == '\\n');\n\t\t\tif (curr == ch) {\n\t\t\t\treturn true;\n\t\t\t} else if (!isspacechar(curr) || atEOL) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Looks for the colon following the end quote\n\t *\n\t * Assumes property names of lengths no longer than a 100 characters.\n\t * The colon is also expected to be less than 50 spaces after the end\n\t * quote for the string to be considered a property name\n\t */\n\tstatic bool AtPropertyName(LexAccessor &styler, Sci_Position start) {\n\t\tSci_Position i = 0;\n\t\tbool escaped = false;\n\t\twhile (i < 100) {\n\t\t\ti++;\n\t\t\tconst char curr = styler.SafeGetCharAt(start+i, '\\0');\n\t\t\tif (escaped) {\n\t\t\t\tescaped = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tescaped = curr == '\\\\';\n\t\t\tif (curr == '\"') {\n\t\t\t\treturn IsNextNonWhitespace(styler, start+i, ':');\n\t\t\t} else if (!curr) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tstatic bool IsNextWordInList(const WordList &keywordList, const CharacterSet &wordSet,\n\t\t\t\t\t\t\t\t const StyleContext &context, LexAccessor &styler) {\n\t\tchar word[51];\n\t\tconst Sci_Position currPos = static_cast<Sci_Position>(context.currentPos);\n\t\tint i = 0;\n\t\twhile (i < 50) {\n\t\t\tconst char ch = styler.SafeGetCharAt(currPos + i);\n\t\t\tif (!wordSet.Contains(ch)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tword[i] = ch;\n\t\t\ti++;\n\t\t}\n\t\tword[i] = '\\0';\n\t\treturn keywordList.InList(word);\n\t}\n\n\tpublic:\n\tLexerJSON() :\n\t\tDefaultLexer(\"json\", SCLEX_JSON),\n\t\tsetOperators(CharacterSet::setNone, \"[{}]:,\"),\n\t\tsetURL(CharacterSet::setAlphaNum, \"-._~:/?#[]@!$&'()*+,),=\"),\n\t\tsetKeywordJSONLD(CharacterSet::setAlpha, \":@\"),\n\t\tsetKeywordJSON(CharacterSet::setAlpha, \"$_\") {\n\t}\n\tvirtual ~LexerJSON() = default;\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn optSetJSON.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn optSetJSON.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn optSetJSON.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override {\n\t\tif (optSetJSON.PropertySet(&options, key, val)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn -1;\n\t}\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn optSetJSON.PropertyGet(key);\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override {\n\t\tWordList *wordListN = nullptr;\n\t\tswitch (n) {\n\t\t\tcase 0:\n\t\t\t\twordListN = &keywordsJSON;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\twordListN = &keywordsJSONLD;\n\t\t\t\tbreak;\n\t\t}\n\t\tSci_Position firstModification = -1;\n\t\tif (wordListN) {\n\t\t\tif (wordListN->Set(wl)) {\n\t\t\t\tfirstModification = 0;\n\t\t\t}\n\t\t}\n\t\treturn firstModification;\n\t}\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn nullptr;\n\t}\n\tstatic ILexer5 *LexerFactoryJSON() {\n\t\treturn new LexerJSON;\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn optSetJSON.DescribeWordListSets();\n\t}\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos,\n\t\t\t\t\t\t\t\tSci_Position length,\n\t\t\t\t\t\t\t\tint initStyle,\n\t\t\t\t\t\t\t\tIDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos,\n\t\t\t\t\t\t\t\t Sci_Position length,\n\t\t\t\t\t\t\t\t int initStyle,\n\t\t\t\t\t\t\t\t IDocument *pAccess) override;\n};\n\nvoid SCI_METHOD LexerJSON::Lex(Sci_PositionU startPos,\n\t\t\t\t\t\t\t   Sci_Position length,\n\t\t\t\t\t\t\t   int initStyle,\n\t\t\t\t\t\t\t   IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\tStyleContext context(startPos, length, initStyle, styler);\n\tint stringStyleBefore = SCE_JSON_STRING;\n\twhile (context.More()) {\n\t\tswitch (context.state) {\n\t\t\tcase SCE_JSON_BLOCKCOMMENT:\n\t\t\t\tif (context.Match(\"*/\")) {\n\t\t\t\t\tcontext.Forward();\n\t\t\t\t\tcontext.ForwardSetState(SCE_JSON_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_JSON_LINECOMMENT:\n\t\t\t\tif (context.MatchLineEnd()) {\n\t\t\t\t\tcontext.SetState(SCE_JSON_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_JSON_STRINGEOL:\n\t\t\t\tif (context.atLineStart) {\n\t\t\t\t\tcontext.SetState(SCE_JSON_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_JSON_ESCAPESEQUENCE:\n\t\t\t\tescapeSeq.digitsLeft--;\n\t\t\t\tif (!escapeSeq.atEscapeEnd()) {\n\t\t\t\t\tif (escapeSeq.isInvalidChar(context.ch)) {\n\t\t\t\t\t\tcontext.SetState(SCE_JSON_ERROR);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (context.ch == '\"') {\n\t\t\t\t\tcontext.SetState(stringStyleBefore);\n\t\t\t\t\tcontext.ForwardSetState(SCE_JSON_DEFAULT);\n\t\t\t\t} else if (context.ch == '\\\\') {\n\t\t\t\t\tif (!escapeSeq.newSequence(context.chNext)) {\n\t\t\t\t\t\tcontext.SetState(SCE_JSON_ERROR);\n\t\t\t\t\t}\n\t\t\t\t\tcontext.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tcontext.SetState(stringStyleBefore);\n\t\t\t\t\tif (context.atLineEnd) {\n\t\t\t\t\t\tcontext.ChangeState(SCE_JSON_STRINGEOL);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_JSON_PROPERTYNAME:\n\t\t\tcase SCE_JSON_STRING:\n\t\t\t\tif (context.ch == '\"') {\n\t\t\t\t\tif (compactIRI.shouldHighlight()) {\n\t\t\t\t\t\tcontext.ChangeState(SCE_JSON_COMPACTIRI);\n\t\t\t\t\t\tcontext.ForwardSetState(SCE_JSON_DEFAULT);\n\t\t\t\t\t\tcompactIRI.resetState();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.ForwardSetState(SCE_JSON_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t} else if (context.atLineEnd) {\n\t\t\t\t\tcontext.ChangeState(SCE_JSON_STRINGEOL);\n\t\t\t\t} else if (context.ch == '\\\\') {\n\t\t\t\t\tstringStyleBefore = context.state;\n\t\t\t\t\tif (options.escapeSequence) {\n\t\t\t\t\t\tcontext.SetState(SCE_JSON_ESCAPESEQUENCE);\n\t\t\t\t\t\tif (!escapeSeq.newSequence(context.chNext)) {\n\t\t\t\t\t\t\tcontext.SetState(SCE_JSON_ERROR);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcontext.Forward();\n\t\t\t\t} else if (context.Match(\"https://\") ||\n\t\t\t\t\t\t   context.Match(\"http://\") ||\n\t\t\t\t\t\t   context.Match(\"ssh://\") ||\n\t\t\t\t\t\t   context.Match(\"git://\") ||\n\t\t\t\t\t\t   context.Match(\"svn://\") ||\n\t\t\t\t\t\t   context.Match(\"ftp://\") ||\n\t\t\t\t\t\t   context.Match(\"mailto:\")) {\n\t\t\t\t\t// Handle most common URI schemes only\n\t\t\t\t\tstringStyleBefore = context.state;\n\t\t\t\t\tcontext.SetState(SCE_JSON_URI);\n\t\t\t\t} else if (context.ch == '@') {\n\t\t\t\t\t// https://www.w3.org/TR/json-ld/#dfn-keyword\n\t\t\t\t\tif (IsNextWordInList(keywordsJSONLD, setKeywordJSONLD, context, styler)) {\n\t\t\t\t\t\tstringStyleBefore = context.state;\n\t\t\t\t\t\tcontext.SetState(SCE_JSON_LDKEYWORD);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcompactIRI.checkChar(context.ch);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_JSON_LDKEYWORD:\n\t\t\tcase SCE_JSON_URI:\n\t\t\t\tif ((!setKeywordJSONLD.Contains(context.ch) &&\n\t\t\t\t\t (context.state == SCE_JSON_LDKEYWORD)) ||\n\t\t\t\t\t(!setURL.Contains(context.ch))) {\n\t\t\t\t\tcontext.SetState(stringStyleBefore);\n\t\t\t\t}\n\t\t\t\tif (context.ch == '\"') {\n\t\t\t\t\tcontext.ForwardSetState(SCE_JSON_DEFAULT);\n\t\t\t\t} else if (context.ch == '\\\\') {\n\t\t\t\t\tif (options.escapeSequence) {\n\t\t\t\t\t\tcontext.SetState(SCE_JSON_ESCAPESEQUENCE);\n\t\t\t\t\t\tif (!escapeSeq.newSequence(context.chNext)) {\n\t\t\t\t\t\t\tcontext.SetState(SCE_JSON_ERROR);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcontext.Forward();\n\t\t\t\t} else if (context.atLineEnd) {\n\t\t\t\t\tcontext.ChangeState(SCE_JSON_STRINGEOL);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_JSON_OPERATOR:\n\t\t\tcase SCE_JSON_NUMBER:\n\t\t\t\tcontext.SetState(SCE_JSON_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_JSON_ERROR:\n\t\t\t\tif (context.MatchLineEnd()) {\n\t\t\t\t\tcontext.SetState(SCE_JSON_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_JSON_KEYWORD:\n\t\t\t\tif (!setKeywordJSON.Contains(context.ch)) {\n\t\t\t\t\tcontext.SetState(SCE_JSON_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\tif (context.state == SCE_JSON_DEFAULT) {\n\t\t\tif (context.ch == '\"') {\n\t\t\t\tcompactIRI.resetState();\n\t\t\t\tcontext.SetState(SCE_JSON_STRING);\n\t\t\t\tconst Sci_Position currPos = static_cast<Sci_Position>(context.currentPos);\n\t\t\t\tif (AtPropertyName(styler, currPos)) {\n\t\t\t\t\tcontext.SetState(SCE_JSON_PROPERTYNAME);\n\t\t\t\t}\n\t\t\t} else if (setOperators.Contains(context.ch)) {\n\t\t\t\tcontext.SetState(SCE_JSON_OPERATOR);\n\t\t\t} else if (options.allowComments && context.Match(\"/*\")) {\n\t\t\t\tcontext.SetState(SCE_JSON_BLOCKCOMMENT);\n\t\t\t\tcontext.Forward();\n\t\t\t} else if (options.allowComments && context.Match(\"//\")) {\n\t\t\t\tcontext.SetState(SCE_JSON_LINECOMMENT);\n\t\t\t} else if (setKeywordJSON.Contains(context.ch)) {\n\t\t\t\tif (IsNextWordInList(keywordsJSON, setKeywordJSON, context, styler)) {\n\t\t\t\t\tcontext.SetState(SCE_JSON_KEYWORD);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst bool numberStart =\n\t\t\t\tIsADigit(context.ch) && (context.chPrev == '+'||\n\t\t\t\t\t\t\t\t\t\t context.chPrev == '-' ||\n\t\t\t\t\t\t\t\t\t\t context.atLineStart ||\n\t\t\t\t\t\t\t\t\t\t IsASpace(context.chPrev) ||\n\t\t\t\t\t\t\t\t\t\t setOperators.Contains(context.chPrev));\n\t\t\tconst bool exponentPart =\n\t\t\t\ttolower(context.ch) == 'e' &&\n\t\t\t\tIsADigit(context.chPrev) &&\n\t\t\t\t(IsADigit(context.chNext) ||\n\t\t\t\t context.chNext == '+' ||\n\t\t\t\t context.chNext == '-');\n\t\t\tconst bool signPart =\n\t\t\t\t(context.ch == '-' || context.ch == '+') &&\n\t\t\t\t((tolower(context.chPrev) == 'e' && IsADigit(context.chNext)) ||\n\t\t\t\t ((IsASpace(context.chPrev) || setOperators.Contains(context.chPrev))\n\t\t\t\t  && IsADigit(context.chNext)));\n\t\t\tconst bool adjacentDigit =\n\t\t\t\tIsADigit(context.ch) && IsADigit(context.chPrev);\n\t\t\tconst bool afterExponent = IsADigit(context.ch) && tolower(context.chPrev) == 'e';\n\t\t\tconst bool dotPart = context.ch == '.' &&\n\t\t\t\tIsADigit(context.chPrev) &&\n\t\t\t\tIsADigit(context.chNext);\n\t\t\tconst bool afterDot = IsADigit(context.ch) && context.chPrev == '.';\n\t\t\tif (numberStart ||\n\t\t\t\texponentPart ||\n\t\t\t\tsignPart ||\n\t\t\t\tadjacentDigit ||\n\t\t\t\tdotPart ||\n\t\t\t\tafterExponent ||\n\t\t\t\tafterDot) {\n\t\t\t\tcontext.SetState(SCE_JSON_NUMBER);\n\t\t\t} else if (context.state == SCE_JSON_DEFAULT && !IsASpace(context.ch)) {\n\t\t\t\tcontext.SetState(SCE_JSON_ERROR);\n\t\t\t}\n\t\t}\n\t\tcontext.Forward();\n\t}\n\tcontext.Complete();\n}\n\nvoid SCI_METHOD LexerJSON::Fold(Sci_PositionU startPos,\n\t\t\t\t\t\t\t\tSci_Position length,\n\t\t\t\t\t\t\t\tint,\n\t\t\t\t\t\t\t\tIDocument *pAccess) {\n\tif (!options.fold) {\n\t\treturn;\n\t}\n\tLexAccessor styler(pAccess);\n\tSci_PositionU currLine = styler.GetLine(startPos);\n\tconst Sci_PositionU endPos = startPos + length;\n\tint currLevel = SC_FOLDLEVELBASE;\n\tif (currLine > 0)\n\t\tcurrLevel = styler.LevelAt(currLine - 1) >> 16;\n\tint nextLevel = currLevel;\n\tint visibleChars = 0;\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tconst char curr = styler.SafeGetCharAt(i);\n\t\tconst char next = styler.SafeGetCharAt(i+1);\n\t\tconst bool atEOL = (curr == '\\r' && next != '\\n') || (curr == '\\n');\n\t\tif (styler.StyleAt(i) == SCE_JSON_OPERATOR) {\n\t\t\tif (curr == '{' || curr == '[') {\n\t\t\t\tnextLevel++;\n\t\t\t} else if (curr == '}' || curr == ']') {\n\t\t\t\tnextLevel--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL || i == (endPos-1)) {\n\t\t\tint level = currLevel | nextLevel << 16;\n\t\t\tif (!visibleChars && options.foldCompact) {\n\t\t\t\tlevel |= SC_FOLDLEVELWHITEFLAG;\n\t\t\t} else if (nextLevel > currLevel) {\n\t\t\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tif (level != styler.LevelAt(currLine)) {\n\t\t\t\tstyler.SetLevel(currLine, level);\n\t\t\t}\n\t\t\tcurrLine++;\n\t\t\tcurrLevel = nextLevel;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(curr)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n}\n\n}\n\nextern const LexerModule lmJSON(SCLEX_JSON,\n\t\t\t\t   LexerJSON::LexerFactoryJSON,\n\t\t\t\t   \"json\",\n\t\t\t\t   JSONWordListDesc);\n"
  },
  {
    "path": "lexers/LexJulia.cxx",
    "content": "// Scintilla source code edit control\n// Encoding: UTF-8\n/** @file LexJulia.cxx\n ** Lexer for Julia.\n ** Reusing code from LexMatlab, LexPython and LexRust\n **\n ** Written by Bertrand Lacoste\n **\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"StringCopy.h\"\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"CharacterCategory.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nstatic const int MAX_JULIA_IDENT_CHARS = 1023;\n\n// Options used for LexerJulia\nstruct OptionsJulia {\n    bool fold;\n    bool foldComment;\n    bool foldCompact;\n    bool foldDocstring;\n    bool foldSyntaxBased;\n    bool highlightTypeannotation;\n    bool highlightLexerror;\n\tOptionsJulia() {\n        fold = true;\n        foldComment = true;\n        foldCompact = false;\n        foldDocstring = true;\n        foldSyntaxBased = true;\n        highlightTypeannotation = false;\n        highlightLexerror = false;\n\t}\n};\n\nconst char * const juliaWordLists[] = {\n    \"Primary keywords and identifiers\",\n    \"Built in types\",\n    \"Other keywords\",\n    \"Built in functions\",\n    0,\n};\n\nstruct OptionSetJulia : public OptionSet<OptionsJulia> {\n\tOptionSetJulia() {\n\t\tDefineProperty(\"fold\", &OptionsJulia::fold);\n\n\t\tDefineProperty(\"fold.compact\", &OptionsJulia::foldCompact);\n\n\t\tDefineProperty(\"fold.comment\", &OptionsJulia::foldComment);\n\n\t\tDefineProperty(\"fold.julia.docstring\", &OptionsJulia::foldDocstring,\n\t\t\t\"Fold multiline triple-doublequote strings, usually used to document a function or type above the definition.\");\n\n\t\tDefineProperty(\"fold.julia.syntax.based\", &OptionsJulia::foldSyntaxBased,\n\t\t\t\"Set this property to 0 to disable syntax based folding.\");\n\n\t\tDefineProperty(\"lexer.julia.highlight.typeannotation\", &OptionsJulia::highlightTypeannotation,\n\t\t\t\"This option enables highlighting of the type identifier after `::`.\");\n\n\t\tDefineProperty(\"lexer.julia.highlight.lexerror\", &OptionsJulia::highlightLexerror,\n\t\t\t\"This option enables highlighting of syntax error int character or number definition.\");\n\n\t\tDefineWordListSets(juliaWordLists);\n\t}\n};\n\nLexicalClass juliaLexicalClasses[] = {\n\t// Lexer Julia SCLEX_JULIA SCE_JULIA_:\n\t0,  \"SCE_JULIA_DEFAULT\", \"default\", \"White space\",\n\t1,  \"SCE_JULIA_COMMENT\", \"comment\", \"Comment\",\n\t2,  \"SCE_JULIA_NUMBER\", \"literal numeric\", \"Number\",\n\t3,  \"SCE_JULIA_KEYWORD1\", \"keyword\", \"Reserved keywords\",\n\t4,  \"SCE_JULIA_KEYWORD2\", \"identifier\", \"Builtin type names\",\n\t5,  \"SCE_JULIA_KEYWORD3\", \"identifier\", \"Constants\",\n\t6,  \"SCE_JULIA_CHAR\", \"literal string character\", \"Single quoted string\",\n\t7,  \"SCE_JULIA_OPERATOR\", \"operator\", \"Operator\",\n\t8,  \"SCE_JULIA_BRACKET\", \"bracket operator\", \"Bracket operator\",\n\t9,  \"SCE_JULIA_IDENTIFIER\", \"identifier\", \"Identifier\",\n\t10, \"SCE_JULIA_STRING\", \"literal string\", \"Double quoted String\",\n\t11, \"SCE_JULIA_SYMBOL\", \"literal string symbol\", \"Symbol\",\n\t12, \"SCE_JULIA_MACRO\", \"macro preprocessor\", \"Macro\",\n\t13, \"SCE_JULIA_STRINGINTERP\", \"literal string interpolated\", \"String interpolation\",\n\t14, \"SCE_JULIA_DOCSTRING\", \"literal string documentation\", \"Docstring\",\n\t15, \"SCE_JULIA_STRINGLITERAL\", \"literal string\", \"String literal prefix\",\n\t16, \"SCE_JULIA_COMMAND\", \"literal string command\", \"Command\",\n\t17, \"SCE_JULIA_COMMANDLITERAL\", \"literal string command\", \"Command literal prefix\",\n\t18, \"SCE_JULIA_TYPEANNOT\", \"identifier type\", \"Type annotation identifier\",\n\t19, \"SCE_JULIA_LEXERROR\", \"lexer error\", \"Lexing error\",\n\t20, \"SCE_JULIA_KEYWORD4\", \"identifier\", \"Builtin function names\",\n\t21, \"SCE_JULIA_TYPEOPERATOR\", \"operator type\", \"Type annotation operator\",\n};\n\nclass LexerJulia : public DefaultLexer {\n\tWordList keywords;\n\tWordList identifiers2;\n\tWordList identifiers3;\n\tWordList identifiers4;\n\tOptionsJulia options;\n\tOptionSetJulia osJulia;\npublic:\n\texplicit LexerJulia() :\n\t\tDefaultLexer(\"julia\", SCLEX_JULIA, juliaLexicalClasses, ELEMENTS(juliaLexicalClasses)) {\n\t}\n\tvirtual ~LexerJulia() {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char * SCI_METHOD PropertyNames() override {\n\t\treturn osJulia.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osJulia.PropertyType(name);\n\t}\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osJulia.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osJulia.PropertyGet(key);\n\t}\n\tconst char * SCI_METHOD DescribeWordListSets() override {\n\t\treturn osJulia.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid * SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn 0;\n\t}\n\n\tstatic ILexer5 *LexerFactoryJulia() {\n\t\treturn new LexerJulia();\n\t}\n};\n\nSci_Position SCI_METHOD LexerJulia::PropertySet(const char *key, const char *val) {\n\tif (osJulia.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerJulia::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &identifiers2;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &identifiers3;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &identifiers4;\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nstatic inline bool IsJuliaOperator(int ch) {\n    if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||\n        ch == '-' || ch == '+' || ch == '=' || ch == '|' ||\n        ch == '<' || ch == '>' || ch == '/' || ch == '~' ||\n        ch == '\\\\' ) {\n        return true;\n    }\n    return false;\n}\n\n// The list contains non-ascii unary operators\nstatic inline bool IsJuliaUnaryOperator (int ch) {\n    if (ch == 0x00ac || ch == 0x221a || ch == 0x221b ||\n        ch == 0x221c || ch == 0x22c6 || ch == 0x00b1 ||\n        ch == 0x2213 ) {\n        return true;\n    }\n    return false;\n}\n\nstatic inline bool IsJuliaParen (int ch) {\n    if (ch == '(' || ch == ')' || ch == '{' || ch == '}' ||\n        ch == '[' || ch == ']' ) {\n        return true;\n    }\n    return false;\n}\n\n// Unicode parsing from Julia source code:\n// https://github.com/JuliaLang/julia/blob/master/src/flisp/julia_extensions.c\n// keep the same function name to be easy to find again\nstatic int is_wc_cat_id_start(uint32_t wc) {\n    const CharacterCategory cat = CategoriseCharacter((int) wc);\n\n    return (cat == ccLu || cat == ccLl ||\n            cat == ccLt || cat == ccLm ||\n            cat == ccLo || cat == ccNl ||\n            cat == ccSc ||  // allow currency symbols\n            // other symbols, but not arrows or replacement characters\n            (cat == ccSo && !(wc >= 0x2190 && wc <= 0x21FF) &&\n             wc != 0xfffc && wc != 0xfffd &&\n             wc != 0x233f &&  // notslash\n             wc != 0x00a6) || // broken bar\n\n            // math symbol (category Sm) whitelist\n            (wc >= 0x2140 && wc <= 0x2a1c &&\n             ((wc >= 0x2140 && wc <= 0x2144) || // ⅀, ⅁, ⅂, ⅃, ⅄\n              wc == 0x223f || wc == 0x22be || wc == 0x22bf || // ∿, ⊾, ⊿\n              wc == 0x22a4 || wc == 0x22a5 ||   // ⊤ ⊥\n\n              (wc >= 0x2200 && wc <= 0x2233 &&\n               (wc == 0x2202 || wc == 0x2205 || wc == 0x2206 || // ∂, ∅, ∆\n                wc == 0x2207 || wc == 0x220e || wc == 0x220f || // ∇, ∎, ∏\n                wc == 0x2200 || wc == 0x2203 || wc == 0x2204 || // ∀, ∃, ∄\n                wc == 0x2210 || wc == 0x2211 || // ∐, ∑\n                wc == 0x221e || wc == 0x221f || // ∞, ∟\n                wc >= 0x222b)) || // ∫, ∬, ∭, ∮, ∯, ∰, ∱, ∲, ∳\n\n              (wc >= 0x22c0 && wc <= 0x22c3) ||  // N-ary big ops: ⋀, ⋁, ⋂, ⋃\n              (wc >= 0x25F8 && wc <= 0x25ff) ||  // ◸, ◹, ◺, ◻, ◼, ◽, ◾, ◿\n\n              (wc >= 0x266f &&\n               (wc == 0x266f || wc == 0x27d8 || wc == 0x27d9 || // ♯, ⟘, ⟙\n                (wc >= 0x27c0 && wc <= 0x27c1) ||  // ⟀, ⟁\n                (wc >= 0x29b0 && wc <= 0x29b4) ||  // ⦰, ⦱, ⦲, ⦳, ⦴\n                (wc >= 0x2a00 && wc <= 0x2a06) ||  // ⨀, ⨁, ⨂, ⨃, ⨄, ⨅, ⨆\n                (wc >= 0x2a09 && wc <= 0x2a16) ||  // ⨉, ⨊, ⨋, ⨌, ⨍, ⨎, ⨏, ⨐, ⨑, ⨒, ⨓, ⨔, ⨕, ⨖\n                wc == 0x2a1b || wc == 0x2a1c)))) || // ⨛, ⨜\n\n            (wc >= 0x1d6c1 && // variants of \\nabla and \\partial\n             (wc == 0x1d6c1 || wc == 0x1d6db ||\n              wc == 0x1d6fb || wc == 0x1d715 ||\n              wc == 0x1d735 || wc == 0x1d74f ||\n              wc == 0x1d76f || wc == 0x1d789 ||\n              wc == 0x1d7a9 || wc == 0x1d7c3)) ||\n\n            // super- and subscript +-=()\n            (wc >= 0x207a && wc <= 0x207e) ||\n            (wc >= 0x208a && wc <= 0x208e) ||\n\n            // angle symbols\n            (wc >= 0x2220 && wc <= 0x2222) || // ∠, ∡, ∢\n            (wc >= 0x299b && wc <= 0x29af) || // ⦛, ⦜, ⦝, ⦞, ⦟, ⦠, ⦡, ⦢, ⦣, ⦤, ⦥, ⦦, ⦧, ⦨, ⦩, ⦪, ⦫, ⦬, ⦭, ⦮, ⦯\n\n            // Other_ID_Start\n            wc == 0x2118 || wc == 0x212E || // ℘, ℮\n            (wc >= 0x309B && wc <= 0x309C) || // katakana-hiragana sound marks\n\n            // bold-digits and double-struck digits\n            (wc >= 0x1D7CE && wc <= 0x1D7E1)); // 𝟎 through 𝟗 (inclusive), 𝟘 through 𝟡 (inclusive)\n}\n\nstatic inline bool IsIdentifierFirstCharacter (int ch) {\n    if (IsASCII(ch)) {\n        return (bool) (isalpha(ch) || ch == '_');\n    }\n    if (ch < 0xA1 || ch > 0x10ffff) {\n        return false;\n    }\n\n    return is_wc_cat_id_start((uint32_t) ch);\n}\n\nstatic inline bool IsIdentifierCharacter (int ch) {\n    if (IsASCII(ch)) {\n        return (bool) (isalnum(ch) || ch == '_' || ch == '!');\n    }\n    if (ch < 0xA1 || ch > 0x10ffff) {\n        return false;\n    }\n\n    if (is_wc_cat_id_start((uint32_t) ch)) {\n        return true;\n    }\n\n    const CharacterCategory cat = CategoriseCharacter(ch);\n\n    if (cat == ccMn || cat == ccMc ||\n        cat == ccNd || cat == ccPc ||\n        cat == ccSk || cat == ccMe ||\n        cat == ccNo ||\n        // primes (single, double, triple, their reverses, and quadruple)\n        (ch >= 0x2032 && ch <= 0x2037) || (ch == 0x2057)) {\n        return true;\n    }\n    return false;\n}\n\n// keep the same function name to be easy to find again\nstatic const uint32_t opsuffs[] = {\n   0x00b2, // ²\n   0x00b3, // ³\n   0x00b9, // ¹\n   0x02b0, // ʰ\n   0x02b2, // ʲ\n   0x02b3, // ʳ\n   0x02b7, // ʷ\n   0x02b8, // ʸ\n   0x02e1, // ˡ\n   0x02e2, // ˢ\n   0x02e3, // ˣ\n   0x1d2c, // ᴬ\n   0x1d2e, // ᴮ\n   0x1d30, // ᴰ\n   0x1d31, // ᴱ\n   0x1d33, // ᴳ\n   0x1d34, // ᴴ\n   0x1d35, // ᴵ\n   0x1d36, // ᴶ\n   0x1d37, // ᴷ\n   0x1d38, // ᴸ\n   0x1d39, // ᴹ\n   0x1d3a, // ᴺ\n   0x1d3c, // ᴼ\n   0x1d3e, // ᴾ\n   0x1d3f, // ᴿ\n   0x1d40, // ᵀ\n   0x1d41, // ᵁ\n   0x1d42, // ᵂ\n   0x1d43, // ᵃ\n   0x1d47, // ᵇ\n   0x1d48, // ᵈ\n   0x1d49, // ᵉ\n   0x1d4d, // ᵍ\n   0x1d4f, // ᵏ\n   0x1d50, // ᵐ\n   0x1d52, // ᵒ\n   0x1d56, // ᵖ\n   0x1d57, // ᵗ\n   0x1d58, // ᵘ\n   0x1d5b, // ᵛ\n   0x1d5d, // ᵝ\n   0x1d5e, // ᵞ\n   0x1d5f, // ᵟ\n   0x1d60, // ᵠ\n   0x1d61, // ᵡ\n   0x1d62, // ᵢ\n   0x1d63, // ᵣ\n   0x1d64, // ᵤ\n   0x1d65, // ᵥ\n   0x1d66, // ᵦ\n   0x1d67, // ᵧ\n   0x1d68, // ᵨ\n   0x1d69, // ᵩ\n   0x1d6a, // ᵪ\n   0x1d9c, // ᶜ\n   0x1da0, // ᶠ\n   0x1da5, // ᶥ\n   0x1da6, // ᶦ\n   0x1dab, // ᶫ\n   0x1db0, // ᶰ\n   0x1db8, // ᶸ\n   0x1dbb, // ᶻ\n   0x1dbf, // ᶿ\n   0x2032, // ′\n   0x2033, // ″\n   0x2034, // ‴\n   0x2035, // ‵\n   0x2036, // ‶\n   0x2037, // ‷\n   0x2057, // ⁗\n   0x2070, // ⁰\n   0x2071, // ⁱ\n   0x2074, // ⁴\n   0x2075, // ⁵\n   0x2076, // ⁶\n   0x2077, // ⁷\n   0x2078, // ⁸\n   0x2079, // ⁹\n   0x207a, // ⁺\n   0x207b, // ⁻\n   0x207c, // ⁼\n   0x207d, // ⁽\n   0x207e, // ⁾\n   0x207f, // ⁿ\n   0x2080, // ₀\n   0x2081, // ₁\n   0x2082, // ₂\n   0x2083, // ₃\n   0x2084, // ₄\n   0x2085, // ₅\n   0x2086, // ₆\n   0x2087, // ₇\n   0x2088, // ₈\n   0x2089, // ₉\n   0x208a, // ₊\n   0x208b, // ₋\n   0x208c, // ₌\n   0x208d, // ₍\n   0x208e, // ₎\n   0x2090, // ₐ\n   0x2091, // ₑ\n   0x2092, // ₒ\n   0x2093, // ₓ\n   0x2095, // ₕ\n   0x2096, // ₖ\n   0x2097, // ₗ\n   0x2098, // ₘ\n   0x2099, // ₙ\n   0x209a, // ₚ\n   0x209b, // ₛ\n   0x209c, // ₜ\n   0x2c7c, // ⱼ\n   0x2c7d, // ⱽ\n   0xa71b, // ꜛ\n   0xa71c, // ꜜ\n   0xa71d  // ꜝ\n};\nstatic const size_t opsuffs_len = sizeof(opsuffs) / (sizeof(uint32_t));\n\n// keep the same function name to be easy to find again\nstatic bool jl_op_suffix_char(uint32_t wc) {\n    if (wc < 0xA1 || wc > 0x10ffff) {\n        return false;\n    }\n    const CharacterCategory cat = CategoriseCharacter((int) wc);\n    if (cat == ccMn || cat == ccMc ||\n        cat == ccMe) {\n        return true;\n    }\n\n    for (size_t i = 0; i < opsuffs_len; ++i) {\n        if (wc == opsuffs[i]) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// keep the same function name to be easy to find again\nstatic bool never_id_char(uint32_t wc) {\n     const CharacterCategory cat = CategoriseCharacter((int) wc);\n     return (\n          // spaces and control characters:\n          (cat >= ccZs && cat <= ccCs) ||\n\n          // ASCII and Latin1 non-connector punctuation\n          (wc < 0xff &&\n           cat >= ccPd && cat <= ccPo) ||\n\n          wc == '`' ||\n\n          // mathematical brackets\n          (wc >= 0x27e6 && wc <= 0x27ef) ||\n          // angle, corner, and lenticular brackets\n          (wc >= 0x3008 && wc <= 0x3011) ||\n          // tortoise shell, square, and more lenticular brackets\n          (wc >= 0x3014 && wc <= 0x301b) ||\n          // fullwidth parens\n          (wc == 0xff08 || wc == 0xff09) ||\n          // fullwidth square brackets\n          (wc == 0xff3b || wc == 0xff3d));\n}\n\n\nstatic bool IsOperatorFirstCharacter (int ch) {\n    if (IsASCII(ch)) {\n        if (IsJuliaOperator(ch) ||\n            ch == '!' || ch == '?' ||\n            ch == ':' || ch == ';' ||\n            ch == ',' || ch == '.' ) {\n            return true;\n        }else {\n            return false;\n        }\n    } else if (is_wc_cat_id_start((uint32_t) ch)) {\n        return false;\n    } else if (IsJuliaUnaryOperator(ch) ||\n               ! never_id_char((uint32_t) ch)) {\n        return true;\n    }\n    return false;\n}\n\nstatic bool IsOperatorCharacter (int ch) {\n    if (IsOperatorFirstCharacter(ch) ||\n        (!IsASCII(ch) && jl_op_suffix_char((uint32_t) ch)) ) {\n        return true;\n    }\n    return false;\n}\n\nstatic bool CheckBoundsIndexing(char *str) {\n    if (strcmp(\"begin\", str) == 0 || strcmp(\"end\", str) == 0 ) {\n        return true;\n    }\n    return false;\n}\n\nstatic int CheckKeywordFoldPoint(char *str) {\n    if (strcmp (\"if\", str) == 0 ||\n        strcmp (\"for\", str) == 0 ||\n        strcmp (\"while\", str) == 0 ||\n        strcmp (\"try\", str) == 0 ||\n        strcmp (\"do\", str) == 0 ||\n        strcmp (\"begin\", str) == 0 ||\n        strcmp (\"let\", str) == 0 ||\n        strcmp (\"baremodule\", str) == 0 ||\n        strcmp (\"quote\", str) == 0 ||\n        strcmp (\"module\", str) == 0 ||\n        strcmp (\"struct\", str) == 0 ||\n        strcmp (\"type\", str) == 0 ||\n        strcmp (\"macro\", str) == 0 ||\n        strcmp (\"function\", str) == 0) {\n        return 1;\n    }\n    if (strcmp(\"end\", str) == 0) {\n        return -1;\n    }\n    return 0;\n}\n\nstatic bool IsNumberExpon(int ch, int base) {\n    if ((base == 10 && (ch == 'e' || ch == 'E' || ch == 'f')) ||\n        (base == 16 && (ch == 'p' || ch == 'P'))) {\n        return true;\n    }\n    return false;\n}\n\n/* Scans a sequence of digits, returning true if it found any. */\nstatic bool ScanDigits(StyleContext& sc, int base, bool allow_sep) {\n\tbool found = false;\n    for (;;) {\n\t\tif (IsADigit(sc.chNext, base) || (allow_sep && sc.chNext == '_')) {\n\t\t\tfound = true;\n            sc.Forward();\n\t\t} else {\n\t\t\tbreak;\n        }\n\t}\n\treturn found;\n}\n\nstatic inline bool ScanNHexas(StyleContext &sc, int max) {\n    int n = 0;\n    bool error = false;\n\n    sc.Forward();\n    if (!IsADigit(sc.ch, 16)) {\n        error = true;\n    } else {\n        while (IsADigit(sc.ch, 16) && n < max) {\n            sc.Forward();\n            n++;\n        }\n    }\n    return error;\n}\n\nstatic void resumeCharacter(StyleContext &sc, bool lexerror) {\n    bool error = false;\n\n    //  ''' case\n    if (sc.chPrev == '\\'' && sc.ch == '\\'' && sc.chNext == '\\'') {\n        sc.Forward();\n        sc.ForwardSetState(SCE_JULIA_DEFAULT);\n        return;\n    } else if (lexerror && sc.chPrev == '\\'' && sc.ch == '\\'') {\n        sc.ChangeState(SCE_JULIA_LEXERROR);\n        sc.ForwardSetState(SCE_JULIA_DEFAULT);\n\n    // Escape characters\n    } else if (sc.ch == '\\\\') {\n        sc.Forward();\n        if (sc.ch == '\\'' || sc.ch == '\\\\' ) {\n            sc.Forward();\n        } else if (sc.ch == 'n' || sc.ch == 't' || sc.ch == 'a' ||\n                   sc.ch == 'b' || sc.ch == 'e' || sc.ch == 'f' ||\n                   sc.ch == 'r' || sc.ch == 'v' ) {\n            sc.Forward();\n        } else if (sc.ch == 'x') {\n            error |= ScanNHexas(sc, 2);\n        } else if (sc.ch == 'u') {\n            error |= ScanNHexas(sc, 4);\n        } else if (sc.ch == 'U') {\n            error |= ScanNHexas(sc, 8);\n        } else if (IsADigit(sc.ch, 8)) {\n            int n = 1;\n            int max = 3;\n            sc.Forward();\n            while (IsADigit(sc.ch, 8) && n < max) {\n                sc.Forward();\n                n++;\n            }\n        }\n\n        if (lexerror) {\n            if (sc.ch != '\\'') {\n                error = true;\n                while (sc.ch != '\\'' &&\n                       sc.ch != '\\r' &&\n                       sc.ch != '\\n') {\n                    sc.Forward();\n                }\n            }\n\n            if (error) {\n                sc.ChangeState(SCE_JULIA_LEXERROR);\n                sc.ForwardSetState(SCE_JULIA_DEFAULT);\n            }\n        }\n    } else if (lexerror) {\n        if (sc.ch < 0x20 || sc.ch > 0x10ffff) {\n            error = true;\n        } else {\n            // single character\n            sc.Forward();\n\n            if (sc.ch != '\\'') {\n                error = true;\n                while (sc.ch != '\\'' &&\n                       sc.ch != '\\r' &&\n                       sc.ch != '\\n') {\n                    sc.Forward();\n                }\n            }\n        }\n\n        if (error) {\n            sc.ChangeState(SCE_JULIA_LEXERROR);\n            sc.ForwardSetState(SCE_JULIA_DEFAULT);\n        }\n    }\n\n    // closing quote\n    if (sc.ch == '\\'') {\n        if (sc.chNext == '\\'') {\n            sc.Forward();\n        } else {\n            sc.ForwardSetState(SCE_JULIA_DEFAULT);\n        }\n    }\n}\n\nstatic inline bool IsACharacter(StyleContext &sc) {\n    return (sc.chPrev == '\\'' && sc.chNext == '\\'');\n}\n\nstatic void ScanParenInterpolation(StyleContext &sc) {\n    // TODO: no syntax highlighting inside a string interpolation\n\n    // Level of nested parenthesis\n    int interp_level = 0;\n\n    // If true, it is inside a string and parenthesis are not counted.\n    bool allow_paren_string = false;\n\n\n    // check for end of states\n    for (; sc.More(); sc.Forward()) {\n        // TODO: check corner cases for nested string interpolation\n        // TODO: check corner cases with Command inside interpolation\n\n        if ( sc.ch == '\\\"' && sc.chPrev != '\\\\') {\n            // Toggle the string environment (parenthesis are not counted inside a string)\n            allow_paren_string = !allow_paren_string;\n        } else if ( !allow_paren_string ) {\n            if ( sc.ch == '(' && !IsACharacter(sc) ) {\n                interp_level ++;\n            } else if ( sc.ch == ')' && !IsACharacter(sc) && interp_level > 0 ) {\n                interp_level --;\n                if (interp_level == 0) {\n                    // Exit interpolation\n                    return;\n                }\n            }\n        }\n    }\n}\n/*\n * Start parsing a number, parse the base.\n */\nstatic void initNumber (StyleContext &sc, int &base, bool &with_dot) {\n    base = 10;\n    with_dot = false;\n    sc.SetState(SCE_JULIA_NUMBER);\n    if (sc.ch == '0') {\n        if (sc.chNext == 'x') {\n            sc.Forward();\n            base = 16;\n            if (sc.chNext == '.') {\n                sc.Forward();\n                with_dot = true;\n            }\n        } else if (sc.chNext == 'o') {\n            sc.Forward();\n            base = 8;\n        } else if (sc.chNext == 'b') {\n            sc.Forward();\n            base = 2;\n        }\n    } else if (sc.ch == '.') {\n        with_dot = true;\n    }\n}\n\n/*\n * Resume parsing a String or Command, bounded by the `quote` character (\\\" or \\`)\n * The `triple` argument specifies if it is a triple-quote String or Command.\n * Interpolation is detected (with `$`), and parsed if `allow_interp` is true.\n */\nstatic void resumeStringLike(StyleContext &sc, int quote, bool triple, bool allow_interp, bool full_highlight) {\n    int stylePrev = sc.state;\n    bool checkcurrent = false;\n\n    // Escape characters\n    if (sc.ch == '\\\\') {\n        if (sc.chNext == quote || sc.chNext == '\\\\' || sc.chNext == '$') {\n            sc.Forward();\n        }\n    } else if (allow_interp && sc.ch == '$') {\n        // If the interpolation is only of a variable, do not change state\n        if (sc.chNext == '(') {\n            if (full_highlight) {\n                sc.SetState(SCE_JULIA_STRINGINTERP);\n            } else {\n                sc.ForwardSetState(SCE_JULIA_STRINGINTERP);\n            }\n            ScanParenInterpolation(sc);\n            sc.ForwardSetState(stylePrev);\n\n            checkcurrent = true;\n\n        } else if (full_highlight && IsIdentifierFirstCharacter(sc.chNext)) {\n            sc.SetState(SCE_JULIA_STRINGINTERP);\n            sc.Forward();\n            sc.Forward();\n            for (; sc.More(); sc.Forward()) {\n                if (! IsIdentifierCharacter(sc.ch)) {\n                    break;\n                }\n            }\n            sc.SetState(stylePrev);\n\n            checkcurrent = true;\n        }\n\n        if (checkcurrent) {\n            // Check that the current character is not a special char,\n            // otherwise it will be skipped\n            resumeStringLike(sc, quote, triple, allow_interp, full_highlight);\n        }\n\n    } else if (sc.ch == quote) {\n        if (triple) {\n            if (sc.chNext == quote && sc.GetRelativeCharacter(2) == quote) {\n                // Move to the end of the triple quotes\n                Sci_PositionU nextIndex = sc.currentPos + 2;\n                while (nextIndex > sc.currentPos && sc.More()) {\n                    sc.Forward();\n                }\n                sc.ForwardSetState(SCE_JULIA_DEFAULT);\n            }\n        } else {\n            sc.ForwardSetState(SCE_JULIA_DEFAULT);\n        }\n    }\n}\n\nstatic void resumeCommand(StyleContext &sc, bool triple, bool allow_interp) {\n    return resumeStringLike(sc, '`', triple, allow_interp, true);\n}\n\nstatic void resumeString(StyleContext &sc, bool triple, bool allow_interp) {\n    return resumeStringLike(sc, '\"', triple, allow_interp, true);\n}\n\nstatic void resumeNumber (StyleContext &sc, int base, bool &with_dot, bool lexerror) {\n    if (IsNumberExpon(sc.ch, base)) {\n        if (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-') {\n            sc.Forward();\n            // Capture all digits\n            ScanDigits(sc, 10, false);\n            sc.Forward();\n        }\n        sc.SetState(SCE_JULIA_DEFAULT);\n    } else if (sc.ch == '.' && sc.chNext == '.') {\n        // Interval operator `..`\n        sc.SetState(SCE_JULIA_OPERATOR);\n        sc.Forward();\n        sc.ForwardSetState(SCE_JULIA_DEFAULT);\n    } else if (sc.ch == '.' && !with_dot) {\n        with_dot = true;\n        ScanDigits(sc, base, true);\n    } else if (IsADigit(sc.ch, base) || sc.ch == '_') {\n        ScanDigits(sc, base, true);\n    } else if (IsADigit(sc.ch) && !IsADigit(sc.ch, base)) {\n        if (lexerror) {\n            sc.ChangeState(SCE_JULIA_LEXERROR);\n        }\n        ScanDigits(sc, 10, false);\n        sc.ForwardSetState(SCE_JULIA_DEFAULT);\n    } else {\n        sc.SetState(SCE_JULIA_DEFAULT);\n    }\n}\n\nstatic void resumeOperator (StyleContext &sc) {\n    if (sc.chNext == ':' && (sc.ch == ':' || sc.ch == '<' ||\n                    (sc.ch == '>' && (sc.chPrev != '-' && sc.chPrev != '=')))) {\n        // Case `:a=>:b`\n        sc.Forward();\n        sc.ForwardSetState(SCE_JULIA_DEFAULT);\n    } else if (sc.ch == ':') {\n        // Case `foo(:baz,:baz)` or `:one+:two`\n        // Let the default case switch decide if it is a symbol\n        sc.SetState(SCE_JULIA_DEFAULT);\n    } else if (sc.ch == '\\'') {\n        sc.SetState(SCE_JULIA_DEFAULT);\n    } else if ((sc.ch == '.' && sc.chPrev != '.') || IsIdentifierFirstCharacter(sc.ch) ||\n               (! (sc.chPrev == '.' && IsOperatorFirstCharacter(sc.ch)) &&\n                ! IsOperatorCharacter(sc.ch)) ) {\n        sc.SetState(SCE_JULIA_DEFAULT);\n    }\n}\n\nvoid SCI_METHOD LexerJulia::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tPropSetSimple props;\n\tAccessor styler(pAccess, &props);\n\n\tSci_Position pos = startPos;\n\tstyler.StartAt(pos);\n\tstyler.StartSegment(pos);\n\n    // use the line state of each line to store block/multiline states\n    Sci_Position curLine = styler.GetLine(startPos);\n    // Default is false for everything and 0 counters.\n\tint lineState = (curLine > 0) ? styler.GetLineState(curLine-1) : 0;\n\n    bool transpose = (lineState >> 0) & 0x01;                // 1 bit to know if ' is allowed to mean transpose\n    bool istripledocstring = (lineState >> 1) & 0x01;        // 1 bit to know if we are in a triple doublequotes string\n\tbool triple_backtick = (lineState >> 2) & 0x01;          // 1 bit to know if we are in a triple backtick command\n\tbool israwstring = (lineState >> 3) & 0x01;              // 1 bit to know if we are in a raw string\n    int indexing_level = (int)((lineState >> 4) & 0x0F);     // 4 bits of bracket nesting counter\n    int list_comprehension = (int)((lineState >> 8) & 0x0F); // 4 bits of parenthesis nesting counter\n    int commentDepth = (int)((lineState >> 12) & 0x0F);      // 4 bits of nested comment counter\n\n    // base for parsing number\n    int base = 10;\n    // number has a float dot ?\n    bool with_dot = false;\n\n    StyleContext sc(startPos, length, initStyle, styler);\n\n    for (; sc.More(); sc.Forward()) {\n\n        //// check for end of states\n        switch (sc.state) {\n            case SCE_JULIA_BRACKET:\n                sc.SetState(SCE_JULIA_DEFAULT);\n                break;\n            case SCE_JULIA_OPERATOR:\n                resumeOperator(sc);\n                break;\n            case SCE_JULIA_TYPEOPERATOR:\n                sc.SetState(SCE_JULIA_DEFAULT);\n                break;\n            case SCE_JULIA_TYPEANNOT:\n                if (! IsIdentifierCharacter(sc.ch)) {\n                    sc.SetState(SCE_JULIA_DEFAULT);\n                }\n                break;\n            case SCE_JULIA_IDENTIFIER:\n                // String literal\n                if (sc.ch == '\\\"') {\n                    // If the string literal has a prefix, interpolation is disabled\n                    israwstring = true;\n                    sc.ChangeState(SCE_JULIA_STRINGLITERAL);\n                    sc.SetState(SCE_JULIA_DEFAULT);\n\n                } else if (sc.ch == '`') {\n                    // If the string literal has a prefix, interpolation is disabled\n                    israwstring = true;\n                    sc.ChangeState(SCE_JULIA_COMMANDLITERAL);\n                    sc.SetState(SCE_JULIA_DEFAULT);\n\n                // Continue if the character is an identifier character\n                } else if (! IsIdentifierCharacter(sc.ch)) {\n                    char s[MAX_JULIA_IDENT_CHARS + 1];\n                    sc.GetCurrent(s, sizeof(s));\n\n                    // Treat the keywords differently if we are indexing or not\n                    if ( indexing_level > 0 && CheckBoundsIndexing(s)) {\n                        // Inside [], (), `begin` and `end` are numbers not block keywords\n                        sc.ChangeState(SCE_JULIA_NUMBER);\n                        transpose = false;\n\n                    } else {\n                        if (keywords.InList(s)) {\n                            sc.ChangeState(SCE_JULIA_KEYWORD1);\n                            transpose = false;\n                        } else if (identifiers2.InList(s)) {\n                            sc.ChangeState(SCE_JULIA_KEYWORD2);\n                            transpose = false;\n                        } else if (identifiers3.InList(s)) {\n                            sc.ChangeState(SCE_JULIA_KEYWORD3);\n                            transpose = false;\n                        } else if (identifiers4.InList(s)) {\n                            sc.ChangeState(SCE_JULIA_KEYWORD4);\n                            // These identifiers can be used for variable names also,\n                            // so transpose is not forbidden.\n                            //transpose = false;\n                        }\n                    }\n                    sc.SetState(SCE_JULIA_DEFAULT);\n\n                    // TODO: recognize begin-end blocks inside list comprehension\n                    // b = [(begin n%2; n*2 end) for n in 1:10]\n                    // TODO: recognize better comprehension for-if to avoid problem with code-folding\n                    // c = [(if isempty(a); missing else first(b) end) for (a, b) in zip(l1, l2)]\n                }\n                break;\n            case SCE_JULIA_NUMBER:\n                resumeNumber(sc, base, with_dot, options.highlightLexerror);\n                break;\n            case SCE_JULIA_CHAR:\n                resumeCharacter(sc, options.highlightLexerror);\n                break;\n            case SCE_JULIA_DOCSTRING:\n                resumeString(sc, true, !israwstring);\n                if (sc.state == SCE_JULIA_DEFAULT && israwstring) {\n                    israwstring = false;\n                }\n                break;\n            case SCE_JULIA_STRING:\n                resumeString(sc, false, !israwstring);\n                if (sc.state == SCE_JULIA_DEFAULT && israwstring) {\n                    israwstring = false;\n                }\n                break;\n            case SCE_JULIA_COMMAND:\n                resumeCommand(sc, triple_backtick, !israwstring);\n                break;\n            case SCE_JULIA_MACRO:\n                if (IsASpace(sc.ch) || ! IsIdentifierCharacter(sc.ch)) {\n                    sc.SetState(SCE_JULIA_DEFAULT);\n                }\n                break;\n            case SCE_JULIA_SYMBOL:\n                if (! IsIdentifierCharacter(sc.ch)) {\n                    sc.SetState(SCE_JULIA_DEFAULT);\n                }\n                break;\n            case SCE_JULIA_COMMENT:\n                if( commentDepth > 0 ) {\n                    // end or start of a nested a block comment\n                    if ( sc.ch == '=' && sc.chNext == '#') {\n                        commentDepth --;\n                        sc.Forward();\n\n                        if (commentDepth == 0) {\n                            sc.ForwardSetState(SCE_JULIA_DEFAULT);\n                        }\n                    } else if( sc.ch == '#' && sc.chNext == '=') {\n                        commentDepth ++;\n                        sc.Forward();\n                    }\n                } else {\n                    // single line comment\n                    if (sc.atLineEnd || sc.ch == '\\r' || sc.ch == '\\n') {\n                        sc.SetState(SCE_JULIA_DEFAULT);\n                        transpose = false;\n                    }\n                }\n                break;\n        }\n\n        // check start of a new state\n        if (sc.state == SCE_JULIA_DEFAULT) {\n            if (sc.ch == '#') {\n                sc.SetState(SCE_JULIA_COMMENT);\n                // increment depth if we are a block comment\n                if(sc.chNext == '=') {\n                    commentDepth ++;\n                    sc.Forward();\n                }\n            } else if (sc.ch == '!') {\n                sc.SetState(SCE_JULIA_OPERATOR);\n                transpose = false;\n            } else if (sc.ch == '\\'') {\n                if (transpose) {\n                    sc.SetState(SCE_JULIA_OPERATOR);\n                } else {\n                    sc.SetState(SCE_JULIA_CHAR);\n                }\n            } else if (sc.ch == '\\\"') {\n                istripledocstring = (sc.chNext == '\\\"' && sc.GetRelativeCharacter(2) == '\\\"');\n                if (istripledocstring) {\n                    sc.SetState(SCE_JULIA_DOCSTRING);\n                    // Move to the end of the triple quotes\n                    Sci_PositionU nextIndex = sc.currentPos + 2;\n                    while (nextIndex > sc.currentPos && sc.More()) {\n                        sc.Forward();\n                    }\n                } else {\n                    sc.SetState(SCE_JULIA_STRING);\n                }\n            } else if (sc.ch == '`') {\n                triple_backtick = (sc.chNext == '`' && sc.GetRelativeCharacter(2) == '`');\n                sc.SetState(SCE_JULIA_COMMAND);\n                if (triple_backtick) {\n                    // Move to the end of the triple backticks\n                    Sci_PositionU nextIndex = sc.currentPos + 2;\n                    while (nextIndex > sc.currentPos && sc.More()) {\n                        sc.Forward();\n                    }\n                }\n            } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n                initNumber(sc, base, with_dot);\n            } else if (IsIdentifierFirstCharacter(sc.ch)) {\n                sc.SetState(SCE_JULIA_IDENTIFIER);\n                transpose = true;\n            } else if (sc.ch == '@') {\n                sc.SetState(SCE_JULIA_MACRO);\n                transpose = false;\n\n            // Several parsing of operators, should keep the order of `if` blocks\n            } else if ((sc.ch == ':' || sc.ch == '<' || sc.ch == '>') && sc.chNext == ':') {\n                sc.SetState(SCE_JULIA_TYPEOPERATOR);\n                sc.Forward();\n                // Highlight the next identifier, if option is set\n                if (options.highlightTypeannotation &&\n                    IsIdentifierFirstCharacter(sc.chNext)) {\n                    sc.ForwardSetState(SCE_JULIA_TYPEANNOT);\n                }\n            } else if (sc.ch == ':') {\n                // TODO: improve detection of range\n                // should be solved with begin-end parsing\n                // `push!(arr, s1 :s2)` and `a[begin :end]\n                if (IsIdentifierFirstCharacter(sc.chNext) &&\n                    ! IsIdentifierCharacter(sc.chPrev) &&\n                    sc.chPrev != ')' && sc.chPrev != ']' ) {\n                    sc.SetState(SCE_JULIA_SYMBOL);\n                } else {\n                    sc.SetState(SCE_JULIA_OPERATOR);\n                }\n            } else if (IsJuliaParen(sc.ch)) {\n                if (sc.ch == '[') {\n                    list_comprehension ++;\n                    indexing_level ++;\n                } else if (sc.ch == ']' && (indexing_level > 0)) {\n                    list_comprehension --;\n                    indexing_level --;\n                } else if (sc.ch == '(') {\n                    list_comprehension ++;\n                } else if (sc.ch == ')' && (list_comprehension > 0)) {\n                    list_comprehension --;\n                }\n\n                if (sc.ch == ')' || sc.ch == ']' || sc.ch == '}') {\n                    transpose = true;\n                } else {\n                    transpose = false;\n                }\n                sc.SetState(SCE_JULIA_BRACKET);\n            } else if (IsOperatorFirstCharacter(sc.ch)) {\n                transpose = false;\n                sc.SetState(SCE_JULIA_OPERATOR);\n            } else {\n                transpose = false;\n            }\n        }\n\n        // update the line information (used for line-by-line lexing and folding)\n        if (sc.atLineEnd) {\n            // set the line state to the current state\n            curLine = styler.GetLine(sc.currentPos);\n\n            lineState = ((transpose ? 1 : 0) << 0) |\n                        ((istripledocstring ? 1 : 0) << 1) |\n                        ((triple_backtick ? 1 : 0) << 2) |\n                        ((israwstring ? 1 : 0) << 3) |\n                        ((indexing_level & 0x0F) << 4) |\n                        ((list_comprehension & 0x0F) << 8) |\n                        ((commentDepth & 0x0F) << 12);\n            styler.SetLineState(curLine, lineState);\n        }\n    }\n    sc.Complete();\n}\n\nvoid SCI_METHOD LexerJulia::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\n\tif (!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n    int lineState = 0;\n\tif (lineCurrent > 0) {\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n        lineState = styler.GetLineState(lineCurrent-1);\n    }\n\n    // level of nested brackets\n    int indexing_level = (int)((lineState >> 4) & 0x0F);     // 4 bits of bracket nesting counter\n    // level of nested parenthesis or brackets\n    int list_comprehension = (int)((lineState >> 8) & 0x0F); // 4 bits of parenthesis nesting counter\n    //int commentDepth = (int)((lineState >> 12) & 0x0F);      // 4 bits of nested comment counter\n    \n\tSci_PositionU lineStartNext = styler.LineStart(lineCurrent+1);\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint stylePrev = styler.StyleAt(startPos - 1);\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n    char word[100];\n    int wordlen = 0;\n    for (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = i == (lineStartNext-1);\n\n        // a start/end of comment block\n        if (options.foldComment && style == SCE_JULIA_COMMENT) {\n            // start of block comment\n            if (ch == '#' && chNext == '=') {\n                levelNext ++;\n            }\n            // end of block comment\n            if (ch == '=' && chNext == '#' && levelNext > 0) {\n                levelNext --;\n            }\n        }\n\n        // Syntax based folding, accounts for list comprehension\n        if (options.foldSyntaxBased) {\n            // list comprehension allow `for`, `if` and `begin` without `end`\n            if (style == SCE_JULIA_BRACKET) {\n                if (ch == '[') {\n                    list_comprehension ++;\n                    indexing_level ++;\n                    levelNext ++;\n                } else if (ch == ']') {\n                    list_comprehension --;\n                    indexing_level --;\n                    levelNext --;\n                } else if (ch == '(') {\n                    list_comprehension ++;\n                    levelNext ++;\n                } else if (ch == ')') {\n                    list_comprehension --;\n                    levelNext --;\n                }\n                // check non-negative\n                if (indexing_level < 0) {\n                    indexing_level = 0;\n                }\n                if (list_comprehension < 0) {\n                    list_comprehension = 0;\n                }\n            }\n\n            // keyword\n            if (style == SCE_JULIA_KEYWORD1) {\n                word[wordlen++] = static_cast<char>(ch);\n                if (wordlen == 100) {  // prevent overflow\n                    word[0] = '\\0';\n                    wordlen = 1;\n                }\n                if (styleNext != SCE_JULIA_KEYWORD1) {\n                    word[wordlen] = '\\0';\n                    wordlen = 0;\n                    if (list_comprehension <= 0 && indexing_level <= 0) {\n                        levelNext += CheckKeywordFoldPoint(word);\n                    }\n                }\n            }\n        }\n\n        // Docstring\n        if (options.foldDocstring) {\n            if (stylePrev != SCE_JULIA_DOCSTRING && style == SCE_JULIA_DOCSTRING) {\n                levelNext ++;\n            } else if (style == SCE_JULIA_DOCSTRING && styleNext != SCE_JULIA_DOCSTRING) {\n                levelNext --;\n            }\n        }\n\n        // check non-negative level\n        if (levelNext < 0) {\n            levelNext = 0;\n        }\n\n        if (!IsASpace(ch)) {\n            visibleChars++;\n        }\n        stylePrev = style;\n\n        if (atEOL || (i == endPos-1)) {\n            int levelUse = levelCurrent;\n            int lev = levelUse | levelNext << 16;\n            if (visibleChars == 0 && options.foldCompact) {\n                lev |= SC_FOLDLEVELWHITEFLAG;\n            }\n            if (levelUse < levelNext) {\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            }\n            if (lev != styler.LevelAt(lineCurrent)) {\n                styler.SetLevel(lineCurrent, lev);\n            }\n            lineCurrent++;\n            lineStartNext = styler.LineStart(lineCurrent+1);\n            levelCurrent = levelNext;\n            if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length() - 1))) {\n                // There is an empty line at end of file so give it same level and empty\n                styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);\n            }\n            visibleChars = 0;\n        }\n    }\n}\n\nextern const LexerModule lmJulia(SCLEX_JULIA, LexerJulia::LexerFactoryJulia, \"julia\", juliaWordLists);\n"
  },
  {
    "path": "lexers/LexKVIrc.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexKVIrc.cxx\n ** Lexer for KVIrc script.\n **/\n// Copyright 2013 by OmegaPhil <OmegaPhil+scintilla@gmail.com>, based in\n// part from LexPython Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// and LexCmake Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net>\n\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\n/* KVIrc Script syntactic rules: http://www.kvirc.net/doc/doc_syntactic_rules.html */\n\n/* Utility functions */\nstatic inline bool IsAWordChar(int ch) {\n\n    /* Keyword list includes modules, i.e. words including '.', and\n     * alias namespaces include ':' */\n    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.'\n            || ch == ':');\n}\nstatic inline bool IsAWordStart(int ch) {\n\n    /* Functions (start with '$') are treated separately to keywords */\n    return (ch < 0x80) && (isalnum(ch) || ch == '_' );\n}\n\n/* Interface function called by Scintilla to request some text to be\n syntax highlighted */\nstatic void ColouriseKVIrcDoc(Sci_PositionU startPos, Sci_Position length,\n                              int initStyle, WordList *keywordlists[],\n                              Accessor &styler)\n{\n    /* Fetching style context */\n    StyleContext sc(startPos, length, initStyle, styler);\n\n    /* Accessing keywords and function-marking keywords */\n    WordList &keywords = *keywordlists[0];\n    WordList &functionKeywords = *keywordlists[1];\n\n    /* Looping for all characters - only automatically moving forward\n     * when asked for (transitions leaving strings and keywords do this\n     * already) */\n    bool next = true;\n    for( ; sc.More(); next ? sc.Forward() : (void)0 )\n    {\n        /* Resetting next */\n        next = true;\n\n        /* Dealing with different states */\n        switch (sc.state)\n        {\n            case SCE_KVIRC_DEFAULT:\n\n                /* Detecting single-line comments\n                 * Unfortunately KVIrc script allows raw '#<channel\n                 * name>' to be used, and appending # to an array returns\n                 * its length...\n                 * Going for a compromise where single line comments not\n                 * starting on a newline are allowed in all cases except\n                 * when they are preceeded with an opening bracket or comma\n                 * (this will probably be the most common style a valid\n                 * string-less channel name will be used with), with the\n                 * array length case included\n                 */\n                if (\n                    (sc.ch == '#' && sc.atLineStart) ||\n                    (sc.ch == '#' && (\n                        sc.chPrev != '(' && sc.chPrev != ',' &&\n                        sc.chPrev != ']')\n                    )\n                )\n                {\n                    sc.SetState(SCE_KVIRC_COMMENT);\n                    break;\n                }\n\n                /* Detecting multi-line comments */\n                if (sc.Match('/', '*'))\n                {\n                    sc.SetState(SCE_KVIRC_COMMENTBLOCK);\n                    break;\n                }\n\n                /* Detecting strings */\n                if (sc.ch == '\"')\n                {\n                    sc.SetState(SCE_KVIRC_STRING);\n                    break;\n                }\n\n                /* Detecting functions */\n                if (sc.ch == '$')\n                {\n                    sc.SetState(SCE_KVIRC_FUNCTION);\n                    break;\n                }\n\n                /* Detecting variables */\n                if (sc.ch == '%')\n                {\n                    sc.SetState(SCE_KVIRC_VARIABLE);\n                    break;\n                }\n\n                /* Detecting numbers - isdigit is unsafe as it does not\n                 * validate, use CharacterSet.h functions */\n                if (IsADigit(sc.ch))\n                {\n                    sc.SetState(SCE_KVIRC_NUMBER);\n                    break;\n                }\n\n                /* Detecting words */\n                if (IsAWordStart(sc.ch) && IsAWordChar(sc.chNext))\n                {\n                    sc.SetState(SCE_KVIRC_WORD);\n                    sc.Forward();\n                    break;\n                }\n\n                /* Detecting operators */\n                if (isoperator(sc.ch))\n                {\n                    sc.SetState(SCE_KVIRC_OPERATOR);\n                    break;\n                }\n\n                break;\n\n            case SCE_KVIRC_COMMENT:\n\n                /* Breaking out of single line comment when a newline\n                 * is introduced */\n                if (sc.ch == '\\r' || sc.ch == '\\n')\n                {\n                    sc.SetState(SCE_KVIRC_DEFAULT);\n                    break;\n                }\n\n                break;\n\n            case SCE_KVIRC_COMMENTBLOCK:\n\n                /* Detecting end of multi-line comment */\n                if (sc.Match('*', '/'))\n                {\n                    // Moving the current position forward two characters\n                    // so that '*/' is included in the comment\n                    sc.Forward(2);\n                    sc.SetState(SCE_KVIRC_DEFAULT);\n\n                    /* Comment has been exited and the current position\n                     * moved forward, yet the new current character\n                     * has yet to be defined - loop without moving\n                     * forward again */\n                    next = false;\n                    break;\n                }\n\n                break;\n\n            case SCE_KVIRC_STRING:\n\n                /* Detecting end of string - closing speechmarks */\n                if (sc.ch == '\"')\n                {\n                    /* Allowing escaped speechmarks to pass */\n                    if (sc.chPrev == '\\\\')\n                        break;\n\n                    /* Moving the current position forward to capture the\n                     * terminating speechmarks, and ending string */\n                    sc.ForwardSetState(SCE_KVIRC_DEFAULT);\n\n                    /* String has been exited and the current position\n                     * moved forward, yet the new current character\n                     * has yet to be defined - loop without moving\n                     * forward again */\n                    next = false;\n                    break;\n                }\n\n                /* Functions and variables are now highlighted in strings\n                 * Detecting functions */\n                if (sc.ch == '$')\n                {\n                    /* Allowing escaped functions to pass */\n                    if (sc.chPrev == '\\\\')\n                        break;\n\n                    sc.SetState(SCE_KVIRC_STRING_FUNCTION);\n                    break;\n                }\n\n                /* Detecting variables */\n                if (sc.ch == '%')\n                {\n                    /* Allowing escaped variables to pass */\n                    if (sc.chPrev == '\\\\')\n                        break;\n\n                    sc.SetState(SCE_KVIRC_STRING_VARIABLE);\n                    break;\n                }\n\n                /* Breaking out of a string when a newline is introduced */\n                if (sc.ch == '\\r' || sc.ch == '\\n')\n                {\n                    /* Allowing escaped newlines */\n                    if (sc.chPrev == '\\\\')\n                        break;\n\n                    sc.SetState(SCE_KVIRC_DEFAULT);\n                    break;\n                }\n\n                break;\n\n            case SCE_KVIRC_FUNCTION:\n            case SCE_KVIRC_VARIABLE:\n\n                /* Detecting the end of a function/variable (word) */\n                if (!IsAWordChar(sc.ch))\n                {\n                    sc.SetState(SCE_KVIRC_DEFAULT);\n\n                    /* Word has been exited yet the current character\n                     * has yet to be defined - loop without moving\n                     * forward again */\n                    next = false;\n                    break;\n                }\n\n                break;\n\n            case SCE_KVIRC_STRING_FUNCTION:\n            case SCE_KVIRC_STRING_VARIABLE:\n\n                /* A function or variable in a string\n                 * Detecting the end of a function/variable (word) */\n                if (!IsAWordChar(sc.ch))\n                {\n                    sc.SetState(SCE_KVIRC_STRING);\n\n                    /* Word has been exited yet the current character\n                     * has yet to be defined - loop without moving\n                     * forward again */\n                    next = false;\n                    break;\n                }\n\n                break;\n\n            case SCE_KVIRC_NUMBER:\n\n                /* Detecting the end of a number */\n                if (!IsADigit(sc.ch))\n                {\n                    sc.SetState(SCE_KVIRC_DEFAULT);\n\n                    /* Number has been exited yet the current character\n                     * has yet to be defined - loop without moving\n                     * forward */\n                    next = false;\n                    break;\n                }\n\n                break;\n\n            case SCE_KVIRC_OPERATOR:\n\n                /* Because '%' is an operator but is also the marker for\n                 * a variable, I need to always treat operators as single\n                 * character strings and therefore redo their detection\n                 * after every character */\n                sc.SetState(SCE_KVIRC_DEFAULT);\n\n                /* Operator has been exited yet the current character\n                 * has yet to be defined - loop without moving\n                 * forward */\n                next = false;\n                break;\n\n            case SCE_KVIRC_WORD:\n\n                /* Detecting the end of a word */\n                if (!IsAWordChar(sc.ch))\n                {\n                    /* Checking if the word was actually a keyword -\n                     * fetching the current word, NULL-terminated like\n                     * the keyword list */\n                    char s[100];\n                    Sci_Position wordLen = sc.currentPos - styler.GetStartSegment();\n                    if (wordLen > 99)\n                        wordLen = 99;  /* Include '\\0' in buffer */\n                    Sci_Position i;\n                    for( i = 0; i < wordLen; ++i )\n                    {\n                        s[i] = styler.SafeGetCharAt( styler.GetStartSegment() + i );\n                    }\n                    s[wordLen] = '\\0';\n\n                    /* Actually detecting keywords and fixing the state */\n                    if (keywords.InList(s))\n                    {\n                        /* The SetState call actually commits the\n                         * previous keyword state */\n                        sc.ChangeState(SCE_KVIRC_KEYWORD);\n                    }\n                    else if (functionKeywords.InList(s))\n                    {\n                        // Detecting function keywords and fixing the state\n                        sc.ChangeState(SCE_KVIRC_FUNCTION_KEYWORD);\n                    }\n\n                    /* Transitioning to default and committing the previous\n                     * word state */\n                    sc.SetState(SCE_KVIRC_DEFAULT);\n\n                    /* Word has been exited yet the current character\n                     * has yet to be defined - loop without moving\n                     * forward again */\n                    next = false;\n                    break;\n                }\n\n                break;\n        }\n    }\n\n    /* Indicating processing is complete */\n    sc.Complete();\n}\n\nstatic void FoldKVIrcDoc(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/,\n                      WordList *[], Accessor &styler)\n{\n    /* Based on CMake's folder */\n\n    /* Exiting if folding isnt enabled */\n    if ( styler.GetPropertyInt(\"fold\") == 0 )\n        return;\n\n    /* Obtaining current line number*/\n    Sci_Position currentLine = styler.GetLine(startPos);\n\n    /* Obtaining starting character - indentation is done on a line basis,\n     * not character */\n    Sci_PositionU safeStartPos = styler.LineStart( currentLine );\n\n    /* Initialising current level - this is defined as indentation level\n     * in the low 12 bits, with flag bits in the upper four bits.\n     * It looks like two indentation states are maintained in the returned\n     * 32bit value - 'nextLevel' in the most-significant bits, 'currentLevel'\n     * in the least-significant bits. Since the next level is the most\n     * up to date, this must refer to the current state of indentation.\n     * So the code bitshifts the old current level out of existence to\n     * get at the actual current state of indentation\n     * Based on the LexerCPP.cxx line 958 comment */\n    int currentLevel = SC_FOLDLEVELBASE;\n    if (currentLine > 0)\n        currentLevel = styler.LevelAt(currentLine - 1) >> 16;\n    int nextLevel = currentLevel;\n\n    // Looping for characters in range\n    for (Sci_PositionU i = safeStartPos; i < startPos + length; ++i)\n    {\n        /* Folding occurs after syntax highlighting, meaning Scintilla\n         * already knows where the comments are\n         * Fetching the current state */\n        int state = styler.StyleAt(i) & 31;\n\n        switch( styler.SafeGetCharAt(i) )\n        {\n            case '{':\n\n                /* Indenting only when the braces are not contained in\n                 * a comment */\n                if (state != SCE_KVIRC_COMMENT &&\n                    state != SCE_KVIRC_COMMENTBLOCK)\n                    ++nextLevel;\n                break;\n\n            case '}':\n\n                /* Outdenting only when the braces are not contained in\n                 * a comment */\n                if (state != SCE_KVIRC_COMMENT &&\n                    state != SCE_KVIRC_COMMENTBLOCK)\n                    --nextLevel;\n                break;\n\n            case '\\n':\n            case '\\r':\n\n                /* Preparing indentation information to return - combining\n                 * current and next level data */\n                int lev = currentLevel | nextLevel << 16;\n\n                /* If the next level increases the indent level, mark the\n                 * current line as a fold point - current level data is\n                 * in the least significant bits */\n                if (nextLevel > currentLevel )\n                    lev |= SC_FOLDLEVELHEADERFLAG;\n\n                /* Updating indentation level if needed */\n                if (lev != styler.LevelAt(currentLine))\n                    styler.SetLevel(currentLine, lev);\n\n                /* Updating variables */\n                ++currentLine;\n                currentLevel = nextLevel;\n\n                /* Dealing with problematic Windows newlines -\n                 * incrementing to avoid the extra newline breaking the\n                 * fold point */\n                if (styler.SafeGetCharAt(i) == '\\r' &&\n                    styler.SafeGetCharAt(i + 1) == '\\n')\n                    ++i;\n                break;\n        }\n    }\n\n    /* At this point the data has ended, so presumably the end of the line?\n     * Preparing indentation information to return - combining current\n     * and next level data */\n    int lev = currentLevel | nextLevel << 16;\n\n    /* If the next level increases the indent level, mark the current\n     * line as a fold point - current level data is in the least\n     * significant bits */\n    if (nextLevel > currentLevel )\n        lev |= SC_FOLDLEVELHEADERFLAG;\n\n    /* Updating indentation level if needed */\n    if (lev != styler.LevelAt(currentLine))\n        styler.SetLevel(currentLine, lev);\n}\n\n/* Registering wordlists */\nstatic const char *const kvircWordListDesc[] = {\n\t\"primary\",\n\t\"function_keywords\",\n\t0\n};\n\n\n/* Registering functions and wordlists */\nextern const LexerModule lmKVIrc(SCLEX_KVIRC, ColouriseKVIrcDoc, \"kvirc\", FoldKVIrcDoc,\n                    kvircWordListDesc);\n"
  },
  {
    "path": "lexers/LexKix.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexKix.cxx\n ** Lexer for KIX-Scripts.\n **/\n// Copyright 2004 by Manfred Becker <manfred@becker-trdf.de>\n// The License.txt file describes the conditions under which this software may be distributed.\n// Edited by Lee Wilmott (24-Jun-2014) added support for block comments\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// Extended to accept accented characters\nstatic inline bool IsAWordChar(int ch) {\n\treturn ch >= 0x80 || isalnum(ch) || ch == '_';\n}\n\nstatic inline bool IsOperator(const int ch) {\n\treturn (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '&' || ch == '|' || ch == '<' || ch == '>' || ch == '=');\n}\n\nstatic void ColouriseKixDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                           WordList *keywordlists[], Accessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n//\tWordList &keywords4 = *keywordlists[3];\n\n\tstyler.StartAt(startPos);\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.state == SCE_KIX_COMMENT) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_KIX_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_KIX_COMMENTSTREAM) {\n\t\t\tif (sc.ch == '/' && sc.chPrev == '*') {\n\t\t\t\tsc.ForwardSetState(SCE_KIX_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_KIX_STRING1) {\n\t\t\t// This is a doubles quotes string\n\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_KIX_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_KIX_STRING2) {\n\t\t\t// This is a single quote string\n\t\t\tif (sc.ch == '\\'') {\n\t\t\t\tsc.ForwardSetState(SCE_KIX_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_KIX_NUMBER) {\n\t\t\tif (!IsADigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_KIX_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_KIX_VAR) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_KIX_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_KIX_MACRO) {\n\t\t\tif (!IsAWordChar(sc.ch) && !IsADigit(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\n\t\t\t\tif (!keywords3.InList(&s[1])) {\n\t\t\t\t\tsc.ChangeState(SCE_KIX_DEFAULT);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_KIX_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_KIX_OPERATOR) {\n\t\t\tif (!IsOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_KIX_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_KIX_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_KIX_KEYWORD);\n\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_KIX_FUNCTIONS);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_KIX_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_KIX_DEFAULT) {\n\t\t\tif (sc.ch == ';') {\n\t\t\t\tsc.SetState(SCE_KIX_COMMENT);\n\t\t\t} else if (sc.ch == '/' && sc.chNext == '*') {\n\t\t\t\tsc.SetState(SCE_KIX_COMMENTSTREAM);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_KIX_STRING1);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_KIX_STRING2);\n\t\t\t} else if (sc.ch == '$') {\n\t\t\t\tsc.SetState(SCE_KIX_VAR);\n\t\t\t} else if (sc.ch == '@') {\n\t\t\t\tsc.SetState(SCE_KIX_MACRO);\n\t\t\t} else if (IsADigit(sc.ch) || ((sc.ch == '.' || sc.ch == '&') && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_KIX_NUMBER);\n\t\t\t} else if (IsOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_KIX_OPERATOR);\n\t\t\t} else if (IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_KIX_IDENTIFIER);\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\n\nextern const LexerModule lmKix(SCLEX_KIX, ColouriseKixDoc, \"kix\");\n\n"
  },
  {
    "path": "lexers/LexLaTeX.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexLaTeX.cxx\n ** Lexer for LaTeX2e.\n  **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// Modified by G. HU in 2013. Added folding, syntax highting inside math environments, and changed some minor behaviors.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <vector>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"DefaultLexer.h\"\n#include \"LexerBase.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nusing namespace std;\n\nstruct latexFoldSave {\n\tlatexFoldSave() : structLev(0) {\n\t\tfor (int i = 0; i < 8; ++i) openBegins[i] = 0;\n\t}\n\tlatexFoldSave(const latexFoldSave &save) : structLev(save.structLev) {\n\t\tfor (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i];\n\t}\n\tlatexFoldSave &operator=(const latexFoldSave &save) {\n\t\tif (this != &save) {\n\t\t\tstructLev = save.structLev;\n\t\t\tfor (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i];\n\t\t}\n\t\treturn *this;\n\t}\n\tint openBegins[8];\n\tSci_Position structLev;\n};\n\nclass LexerLaTeX : public LexerBase {\nprivate:\n\tvector<int> modes;\n\tvoid setMode(Sci_Position line, int mode) {\n\t\tif (line >= static_cast<Sci_Position>(modes.size())) modes.resize(line + 1, 0);\n\t\tmodes[line] = mode;\n\t}\n\tint getMode(Sci_Position line) {\n\t\tif (line >= 0 && line < static_cast<Sci_Position>(modes.size())) return modes[line];\n\t\treturn 0;\n\t}\n\tvoid truncModes(Sci_Position numLines) {\n\t\tif (static_cast<Sci_Position>(modes.size()) > numLines * 2 + 256)\n\t\t\tmodes.resize(numLines + 128);\n\t}\n\n\tvector<latexFoldSave> saves;\n\tvoid setSave(Sci_Position line, const latexFoldSave &save) {\n\t\tif (line >= static_cast<Sci_Position>(saves.size())) saves.resize(line + 1);\n\t\tsaves[line] = save;\n\t}\n\tvoid getSave(Sci_Position line, latexFoldSave &save) {\n\t\tif (line >= 0 && line < static_cast<Sci_Position>(saves.size())) save = saves[line];\n\t\telse {\n\t\t\tsave.structLev = 0;\n\t\t\tfor (int i = 0; i < 8; ++i) save.openBegins[i] = 0;\n\t\t}\n\t}\n\tvoid truncSaves(Sci_Position numLines) {\n\t\tif (static_cast<Sci_Position>(saves.size()) > numLines * 2 + 256)\n\t\t\tsaves.resize(numLines + 128);\n\t}\npublic:\n\tstatic ILexer5 *LexerFactoryLaTeX() {\n\t\treturn new LexerLaTeX();\n\t}\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\t// ILexer5 methods\n\tconst char * SCI_METHOD GetName() override {\n\t\treturn \"latex\";\n\t}\n\tint SCI_METHOD  GetIdentifier() override {\n\t\treturn SCLEX_LATEX;\n\t}\n};\n\nstatic bool latexIsSpecial(int ch) {\n\treturn (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||\n\t\t   (ch == '{') || (ch == '}') || (ch == ' ');\n}\n\nstatic bool latexIsBlank(int ch) {\n\treturn (ch == ' ') || (ch == '\\t');\n}\n\nstatic bool latexIsBlankAndNL(int ch) {\n\treturn (ch == ' ') || (ch == '\\t') || (ch == '\\r') || (ch == '\\n');\n}\n\nstatic bool latexIsLetter(int ch) {\n\treturn IsASCII(ch) && isalpha(ch);\n}\n\nstatic bool latexIsTagValid(Sci_Position &i, Sci_Position l, Accessor &styler) {\n\twhile (i < l) {\n\t\tif (styler.SafeGetCharAt(i) == '{') {\n\t\t\twhile (i < l) {\n\t\t\t\ti++;\n\t\t\t\tif (styler.SafeGetCharAt(i) == '}') {\n\t\t\t\t\treturn true;\n\t\t\t\t}\telse if (!latexIsLetter(styler.SafeGetCharAt(i)) &&\n                   styler.SafeGetCharAt(i)!='*') {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (!latexIsBlank(styler.SafeGetCharAt(i))) {\n\t\t\treturn false;\n\t\t}\n\t\ti++;\n\t}\n\treturn false;\n}\n\nstatic bool latexNextNotBlankIs(Sci_Position i, Accessor &styler, char needle) {\n  char ch;\n\twhile (i < styler.Length()) {\n    ch = styler.SafeGetCharAt(i);\n\t\tif (!latexIsBlankAndNL(ch) && ch != '*') {\n      if (ch == needle)\n        return true;\n      else\n        return false;\n\t\t}\n\t\ti++;\n\t}\n\treturn false;\n}\n\nstatic bool latexLastWordIs(Sci_Position start, Accessor &styler, const char *needle) {\n\tSci_PositionU i = 0;\n\tSci_PositionU l = static_cast<Sci_PositionU>(strlen(needle));\n\tSci_Position ini = start-l+1;\n\tchar s[32];\n\n\twhile (i < l && i < 31) {\n\t\ts[i] = styler.SafeGetCharAt(ini + i);\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n\n\treturn (strcmp(s, needle) == 0);\n}\n\nstatic bool latexLastWordIsMathEnv(Sci_Position pos, Accessor &styler) {\n\tSci_Position i, j;\n\tchar s[32];\n\tconst char *mathEnvs[] = { \"align\", \"alignat\", \"flalign\", \"gather\",\n\t\t\"multiline\", \"displaymath\", \"eqnarray\", \"equation\" };\n\tif (styler.SafeGetCharAt(pos) != '}') return false;\n\tfor (i = pos - 1; i >= 0; --i) {\n\t\tif (styler.SafeGetCharAt(i) == '{') break;\n\t\tif (pos - i >= 20) return false;\n\t}\n\tif (i < 0 || i == pos - 1) return false;\n\t++i;\n\tfor (j = 0; i + j < pos; ++j)\n\t\ts[j] = styler.SafeGetCharAt(i + j);\n\ts[j] = '\\0';\n\tif (j == 0) return false;\n\tif (s[j - 1] == '*') s[--j] = '\\0';\n\tfor (i = 0; i < static_cast<int>(sizeof(mathEnvs) / sizeof(const char *)); ++i)\n\t\tif (strcmp(s, mathEnvs[i]) == 0) return true;\n\treturn false;\n}\n\nstatic inline void latexStateReset(int &mode, int &state) {\n\tswitch (mode) {\n\tcase 1:     state = SCE_L_MATH; break;\n\tcase 2:     state = SCE_L_MATH2; break;\n\tdefault:    state = SCE_L_DEFAULT; break;\n\t}\n}\n\n// There are cases not handled correctly, like $abcd\\textrm{what is $x+y$}z+w$.\n// But I think it's already good enough.\nvoid SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\t// startPos is assumed to be the first character of a line\n\tAccessor styler(pAccess, &props);\n\tstyler.StartAt(startPos);\n\tint mode = getMode(styler.GetLine(startPos) - 1);\n\tint state = initStyle;\n\tif (state == SCE_L_ERROR || state == SCE_L_SHORTCMD || state == SCE_L_SPECIAL)   // should not happen\n\t\tlatexStateReset(mode, state);\n\n\tchar chNext = styler.SafeGetCharAt(startPos);\n\tchar chVerbatimDelim = '\\0';\n\tstyler.StartSegment(startPos);\n\tSci_Position lengthDoc = startPos + length;\n\n\tfor (Sci_Position i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif (styler.IsLeadByte(ch)) {\n\t\t\ti++;\n\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ch == '\\r' || ch == '\\n')\n\t\t\tsetMode(styler.GetLine(i), mode);\n\n\t\tswitch (state) {\n\t\tcase SCE_L_DEFAULT :\n\t\t\tswitch (ch) {\n\t\t\tcase '\\\\' :\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tif ((i + 1) >= styler.Length())\n\t\t\t\t\tbreak;\n\t\t\t\tif (latexIsLetter(chNext)) {\n\t\t\t\t\tstate = SCE_L_COMMAND;\n\t\t\t\t} else if (latexIsSpecial(chNext)) {\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_L_SPECIAL);\n\t\t\t\t\ti++;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t} else if (chNext == '\\r' || chNext == '\\n') {\n\t\t\t\t\tstyler.ColourTo(i, SCE_L_ERROR);\n\t\t\t\t} else if (IsASCII(chNext)) {\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_L_SHORTCMD);\n\t\t\t\t\tif (chNext == '(') {\n\t\t\t\t\t\tmode = 1;\n\t\t\t\t\t\tstate = SCE_L_MATH;\n\t\t\t\t\t} else if (chNext == '[') {\n\t\t\t\t\t\tmode = 2;\n\t\t\t\t\t\tstate = SCE_L_MATH2;\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '$' :\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tif (chNext == '$') {\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_L_SHORTCMD);\n\t\t\t\t\tmode = 2;\n\t\t\t\t\tstate = SCE_L_MATH2;\n\t\t\t\t\ti++;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i, SCE_L_SHORTCMD);\n\t\t\t\t\tmode = 1;\n\t\t\t\t\tstate = SCE_L_MATH;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '%' :\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_L_COMMENT;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t// These 3 will never be reached.\n\t\tcase SCE_L_ERROR:\n\t\tcase SCE_L_SPECIAL:\n\t\tcase SCE_L_SHORTCMD:\n\t\t\tbreak;\n\t\tcase SCE_L_COMMAND :\n\t\t\tif (!latexIsLetter(chNext)) {\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tif (latexNextNotBlankIs(i + 1, styler, '[' )) {\n\t\t\t\t\tstate = SCE_L_CMDOPT;\n\t\t\t\t} else if (latexLastWordIs(i, styler, \"\\\\begin\")) {\n\t\t\t\t\tstate = SCE_L_TAG;\n\t\t\t\t} else if (latexLastWordIs(i, styler, \"\\\\end\")) {\n\t\t\t\t\tstate = SCE_L_TAG2;\n\t\t\t\t} else if (latexLastWordIs(i, styler, \"\\\\verb\") && chNext != '*' && chNext != ' ') {\n\t\t\t\t\tchVerbatimDelim = chNext;\n\t\t\t\t\tstate = SCE_L_VERBATIM;\n\t\t\t\t} else {\n\t\t\t\t\tlatexStateReset(mode, state);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_L_CMDOPT :\n\t\t\tif (ch == ']') {\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tlatexStateReset(mode, state);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_L_TAG :\n\t\t\tif (latexIsTagValid(i, lengthDoc, styler)) {\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tlatexStateReset(mode, state);\n\t\t\t\tif (latexLastWordIs(i, styler, \"{verbatim}\")) {\n\t\t\t\t\tstate = SCE_L_VERBATIM;\n\t\t\t\t} else if (latexLastWordIs(i, styler, \"{lstlisting}\")) {\n\t\t\t\t\tstate = SCE_L_VERBATIM;\n\t\t\t\t} else if (latexLastWordIs(i, styler, \"{comment}\")) {\n\t\t\t\t\tstate = SCE_L_COMMENT2;\n\t\t\t\t} else if (latexLastWordIs(i, styler, \"{math}\") && mode == 0) {\n\t\t\t\t\tmode = 1;\n\t\t\t\t\tstate = SCE_L_MATH;\n\t\t\t\t} else if (latexLastWordIsMathEnv(i, styler) && mode == 0) {\n\t\t\t\t\tmode = 2;\n\t\t\t\t\tstate = SCE_L_MATH2;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstyler.ColourTo(i < styler.Length() ? i : styler.Length() - 1, SCE_L_ERROR);\n\t\t\t\tlatexStateReset(mode, state);\n\t\t\t\tch = styler.SafeGetCharAt(i);\n\t\t\t\tif (ch == '\\r' || ch == '\\n') setMode(styler.GetLine(i), mode);\n\t\t\t}\n\t\t\tchNext = styler.SafeGetCharAt(i+1);\n\t\t\tbreak;\n\t\tcase SCE_L_TAG2 :\n\t\t\tif (latexIsTagValid(i, lengthDoc, styler)) {\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tlatexStateReset(mode, state);\n\t\t\t} else {\n\t\t\t\tstyler.ColourTo(i < styler.Length() ? i : styler.Length() - 1, SCE_L_ERROR);\n\t\t\t\tlatexStateReset(mode, state);\n\t\t\t\tch = styler.SafeGetCharAt(i);\n\t\t\t\tif (ch == '\\r' || ch == '\\n') setMode(styler.GetLine(i), mode);\n\t\t\t}\n\t\t\tchNext = styler.SafeGetCharAt(i+1);\n\t\t\tbreak;\n\t\tcase SCE_L_MATH :\n\t\t\tswitch (ch) {\n\t\t\tcase '\\\\' :\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tif (latexIsLetter(chNext)) {\n\t\t\t\t\tSci_Position match = i + 3;\n\t\t\t\t\tif (latexLastWordIs(match, styler, \"\\\\end\")) {\n\t\t\t\t\t\tmatch++;\n\t\t\t\t\t\tif (latexIsTagValid(match, lengthDoc, styler)) {\n\t\t\t\t\t\t\tif (latexLastWordIs(match, styler, \"{math}\"))\n\t\t\t\t\t\t\t\tmode = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstate = SCE_L_COMMAND;\n\t\t\t\t} else if (latexIsSpecial(chNext)) {\n\t\t\t\t\tif ((i + 1) >= styler.Length())\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_L_SPECIAL);\n\t\t\t\t\ti++;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t} else if (chNext == '\\r' || chNext == '\\n') {\n\t\t\t\t\tstyler.ColourTo(i, SCE_L_ERROR);\n\t\t\t\t} else if (IsASCII(chNext)) {\n\t\t\t\t\tif (chNext == ')') {\n\t\t\t\t\t\tmode = 0;\n\t\t\t\t\t\tstate = SCE_L_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_L_SHORTCMD);\n\t\t\t\t\ti++;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '$' :\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstyler.ColourTo(i, SCE_L_SHORTCMD);\n\t\t\t\tmode = 0;\n\t\t\t\tstate = SCE_L_DEFAULT;\n\t\t\t\tbreak;\n\t\t\tcase '%' :\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_L_COMMENT;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_L_MATH2 :\n\t\t\tswitch (ch) {\n\t\t\tcase '\\\\' :\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tif (latexIsLetter(chNext)) {\n\t\t\t\t\tSci_Position match = i + 3;\n\t\t\t\t\tif (latexLastWordIs(match, styler, \"\\\\end\")) {\n\t\t\t\t\t\tmatch++;\n\t\t\t\t\t\tif (latexIsTagValid(match, lengthDoc, styler)) {\n\t\t\t\t\t\t\tif (latexLastWordIsMathEnv(match, styler))\n\t\t\t\t\t\t\t\tmode = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstate = SCE_L_COMMAND;\n\t\t\t\t} else if (latexIsSpecial(chNext)) {\n\t\t\t\t\tif ((i + 1) >= styler.Length())\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_L_SPECIAL);\n\t\t\t\t\ti++;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t} else if (chNext == '\\r' || chNext == '\\n') {\n\t\t\t\t\tstyler.ColourTo(i, SCE_L_ERROR);\n\t\t\t\t} else if (IsASCII(chNext)) {\n\t\t\t\t\tif (chNext == ']') {\n\t\t\t\t\t\tmode = 0;\n\t\t\t\t\t\tstate = SCE_L_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_L_SHORTCMD);\n\t\t\t\t\ti++;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '$' :\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tif (chNext == '$') {\n\t\t\t\t\tstyler.ColourTo(i + 1, SCE_L_SHORTCMD);\n\t\t\t\t\ti++;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t\tmode = 0;\n\t\t\t\t\tstate = SCE_L_DEFAULT;\n\t\t\t\t} else { // This may not be an error, e.g. \\begin{equation}\\text{$a$}\\end{equation}\n\t\t\t\t\tstyler.ColourTo(i, SCE_L_SHORTCMD);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '%' :\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_L_COMMENT;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_L_COMMENT :\n\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tlatexStateReset(mode, state);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_L_COMMENT2 :\n\t\t\tif (ch == '\\\\') {\n\t\t\t\tSci_Position match = i + 3;\n\t\t\t\tif (latexLastWordIs(match, styler, \"\\\\end\")) {\n\t\t\t\t\tmatch++;\n\t\t\t\t\tif (latexIsTagValid(match, lengthDoc, styler)) {\n\t\t\t\t\t\tif (latexLastWordIs(match, styler, \"{comment}\")) {\n\t\t\t\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\t\t\t\tstate = SCE_L_COMMAND;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_L_VERBATIM :\n\t\t\tif (ch == '\\\\') {\n\t\t\t\tSci_Position match = i + 3;\n\t\t\t\tif (latexLastWordIs(match, styler, \"\\\\end\")) {\n\t\t\t\t\tmatch++;\n\t\t\t\t\tif (latexIsTagValid(match, lengthDoc, styler)) {\n\t\t\t\t\t\tif (latexLastWordIs(match, styler, \"{verbatim}\")) {\n\t\t\t\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\t\t\t\tstate = SCE_L_COMMAND;\n\t\t\t\t\t\t} else if (latexLastWordIs(match, styler, \"{lstlisting}\")) {\n\t\t\t\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\t\t\t\tstate = SCE_L_COMMAND;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (chNext == chVerbatimDelim) {\n\t\t\t\tstyler.ColourTo(i + 1, state);\n\t\t\t\tlatexStateReset(mode, state);\n\t\t\t\tchVerbatimDelim = '\\0';\n\t\t\t\ti++;\n\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t} else if (chVerbatimDelim != '\\0' && (ch == '\\n' || ch == '\\r')) {\n\t\t\t\tstyler.ColourTo(i - 1, SCE_L_ERROR);\n\t\t\t\tlatexStateReset(mode, state);\n\t\t\t\tchVerbatimDelim = '\\0';\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (lengthDoc == styler.Length()) truncModes(styler.GetLine(lengthDoc - 1));\n\tstyler.ColourTo(lengthDoc - 1, state);\n\tstyler.Flush();\n}\n\nstatic int latexFoldSaveToInt(const latexFoldSave &save) {\n\tint sum = 0;\n\tfor (int i = 0; i <= save.structLev; ++i)\n\t\tsum += save.openBegins[i];\n\treturn ((sum + save.structLev + SC_FOLDLEVELBASE) & SC_FOLDLEVELNUMBERMASK);\n}\n\n// Change folding state while processing a line\n// Return the level before the first relevant command\nvoid SCI_METHOD LexerLaTeX::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) {\n\tconst char *structWords[7] = {\"part\", \"chapter\", \"section\", \"subsection\",\n\t\t\"subsubsection\", \"paragraph\", \"subparagraph\"};\n\tAccessor styler(pAccess, &props);\n\tSci_PositionU endPos = startPos + length;\n\tSci_Position curLine = styler.GetLine(startPos);\n\tlatexFoldSave save;\n\tgetSave(curLine - 1, save);\n\tdo {\n\t\tchar ch, buf[16];\n\t\tSci_Position i, j;\n\t\tint lev = -1;\n\t\tbool needFold = false;\n\t\tfor (i = static_cast<Sci_Position>(startPos); i < static_cast<Sci_Position>(endPos); ++i) {\n\t\t\tch = styler.SafeGetCharAt(i);\n\t\t\tif (ch == '\\r' || ch == '\\n') break;\n\t\t\tif (ch != '\\\\' || styler.StyleAt(i) != SCE_L_COMMAND) continue;\n\t\t\tfor (j = 0; j < 15 && i + 1 < static_cast<Sci_Position>(endPos); ++j, ++i) {\n\t\t\t\tbuf[j] = styler.SafeGetCharAt(i + 1);\n\t\t\t\tif (!latexIsLetter(buf[j])) break;\n\t\t\t}\n\t\t\tbuf[j] = '\\0';\n\t\t\tif (strcmp(buf, \"begin\") == 0) {\n\t\t\t\tif (lev < 0) lev = latexFoldSaveToInt(save);\n\t\t\t\t++save.openBegins[save.structLev];\n\t\t\t\tneedFold = true;\n\t\t\t}\n\t\t\telse if (strcmp(buf, \"end\") == 0) {\n\t\t\t\twhile (save.structLev > 0 && save.openBegins[save.structLev] == 0)\n\t\t\t\t\t--save.structLev;\n\t\t\t\tif (lev < 0) lev = latexFoldSaveToInt(save);\n\t\t\t\tif (save.openBegins[save.structLev] > 0) --save.openBegins[save.structLev];\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfor (j = 0; j < 7; ++j)\n\t\t\t\t\tif (strcmp(buf, structWords[j]) == 0) break;\n\t\t\t\tif (j >= 7) continue;\n\t\t\t\tsave.structLev = j;   // level before the command\n\t\t\t\tfor (j = save.structLev + 1; j < 8; ++j) {\n\t\t\t\t\tsave.openBegins[save.structLev] += save.openBegins[j];\n\t\t\t\t\tsave.openBegins[j] = 0;\n\t\t\t\t}\n\t\t\t\tif (lev < 0) lev = latexFoldSaveToInt(save);\n\t\t\t\t++save.structLev;   // level after the command\n\t\t\t\tneedFold = true;\n\t\t\t}\n\t\t}\n\t\tif (lev < 0) lev = latexFoldSaveToInt(save);\n\t\tif (needFold) lev |= SC_FOLDLEVELHEADERFLAG;\n\t\tstyler.SetLevel(curLine, lev);\n\t\tsetSave(curLine, save);\n\t\t++curLine;\n\t\tstartPos = styler.LineStart(curLine);\n\t\tif (static_cast<Sci_Position>(startPos) == styler.Length()) {\n\t\t\tlev = latexFoldSaveToInt(save);\n\t\t\tstyler.SetLevel(curLine, lev);\n\t\t\tsetSave(curLine, save);\n\t\t\ttruncSaves(curLine);\n\t\t}\n\t} while (startPos < endPos);\n\tstyler.Flush();\n}\n\nstatic const char *const emptyWordListDesc[] = {\n\t0\n};\n\nextern const LexerModule lmLatex(SCLEX_LATEX, LexerLaTeX::LexerFactoryLaTeX, \"latex\", emptyWordListDesc);\n"
  },
  {
    "path": "lexers/LexLisp.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexLisp.cxx\n ** Lexer for Lisp.\n ** Written by Alexey Yutkin.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n#define SCE_LISP_CHARACTER 29\n#define SCE_LISP_MACRO 30\n#define SCE_LISP_MACRO_DISPATCH 31\n\nstatic inline bool isLispoperator(char ch) {\n\tif (IsASCII(ch) && isalnum(ch))\n\t\treturn false;\n\tif (ch == '\\'' || ch == '`' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}')\n\t\treturn true;\n\treturn false;\n}\n\nstatic inline bool isLispwordstart(char ch) {\n\treturn IsASCII(ch) && ch != ';'  && !isspacechar(ch) && !isLispoperator(ch) &&\n\t\tch != '\\n' && ch != '\\r' &&  ch != '\\\"';\n}\n\n\nstatic void classifyWordLisp(Sci_PositionU start, Sci_PositionU end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {\n\tassert(end >= start);\n\tchar s[100];\n\tSci_PositionU i;\n\tbool digit_flag = true;\n\tfor (i = 0; (i < end - start + 1) && (i < 99); i++) {\n\t\ts[i] = styler[start + i];\n\t\ts[i + 1] = '\\0';\n\t\tif (!isdigit(s[i]) && (s[i] != '.')) digit_flag = false;\n\t}\n\tchar chAttr = SCE_LISP_IDENTIFIER;\n\n\tif(digit_flag) chAttr = SCE_LISP_NUMBER;\n\telse {\n\t\tif (keywords.InList(s)) {\n\t\t\tchAttr = SCE_LISP_KEYWORD;\n\t\t} else if (keywords_kw.InList(s)) {\n\t\t\tchAttr = SCE_LISP_KEYWORD_KW;\n\t\t} else if ((s[0] == '*' && s[i-1] == '*') ||\n\t\t\t   (s[0] == '+' && s[i-1] == '+')) {\n\t\t\tchAttr = SCE_LISP_SPECIAL;\n\t\t}\n\t}\n\tstyler.ColourTo(end, chAttr);\n\treturn;\n}\n\n\nstatic void ColouriseLispDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords_kw = *keywordlists[1];\n\n\tstyler.StartAt(startPos);\n\n\tint state = initStyle, radix = -1;\n\tchar chNext = styler[startPos];\n\tSci_PositionU lengthDoc = startPos + length;\n\tstyler.StartSegment(startPos);\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (styler.IsLeadByte(ch)) {\n\t\t\tchNext = styler.SafeGetCharAt(i + 2);\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (state == SCE_LISP_DEFAULT) {\n\t\t\tif (ch == '#') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tradix = -1;\n\t\t\t\tstate = SCE_LISP_MACRO_DISPATCH;\n\t\t\t} else if (ch == ':' && isLispwordstart(chNext)) {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_LISP_SYMBOL;\n\t\t\t} else if (isLispwordstart(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_LISP_IDENTIFIER;\n\t\t\t}\n\t\t\telse if (ch == ';') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_LISP_COMMENT;\n\t\t\t}\n\t\t\telse if (isLispoperator(ch) || ch=='\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstyler.ColourTo(i, SCE_LISP_OPERATOR);\n\t\t\t\tif (ch=='\\'' && isLispwordstart(chNext)) {\n\t\t\t\t\tstate = SCE_LISP_SYMBOL;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ch == '\\\"') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_LISP_STRING;\n\t\t\t}\n\t\t} else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {\n\t\t\tif (!isLispwordstart(ch)) {\n\t\t\t\tif (state == SCE_LISP_IDENTIFIER) {\n\t\t\t\t\tclassifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\t}\n\t\t\t\tstate = SCE_LISP_DEFAULT;\n\t\t\t} /*else*/\n\t\t\tif (isLispoperator(ch) || ch=='\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstyler.ColourTo(i, SCE_LISP_OPERATOR);\n\t\t\t\tif (ch=='\\'' && isLispwordstart(chNext)) {\n\t\t\t\t\tstate = SCE_LISP_SYMBOL;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (state == SCE_LISP_MACRO_DISPATCH) {\n\t\t\tif (!(IsASCII(ch) && isdigit(ch))) {\n\t\t\t\tif (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {\n\t\t\t\t\tstate = SCE_LISP_DEFAULT;\n\t\t\t\t} else {\n\t\t\t\t\tswitch (ch) {\n\t\t\t\t\t\tcase '|': state = SCE_LISP_MULTI_COMMENT; break;\n\t\t\t\t\t\tcase 'o':\n\t\t\t\t\t\tcase 'O': radix = 8; state = SCE_LISP_MACRO; break;\n\t\t\t\t\t\tcase 'x':\n\t\t\t\t\t\tcase 'X': radix = 16; state = SCE_LISP_MACRO; break;\n\t\t\t\t\t\tcase 'b':\n\t\t\t\t\t\tcase 'B': radix = 2; state = SCE_LISP_MACRO; break;\n\t\t\t\t\t\tcase '\\\\': state = SCE_LISP_CHARACTER; break;\n\t\t\t\t\t\tcase ':':\n\t\t\t\t\t\tcase '-':\n\t\t\t\t\t\tcase '+': state = SCE_LISP_MACRO; break;\n\t\t\t\t\t\tcase '\\'': if (isLispwordstart(chNext)) {\n\t\t\t\t\t\t\t\t   state = SCE_LISP_SPECIAL;\n\t\t\t\t\t\t\t   } else {\n\t\t\t\t\t\t\t\t   styler.ColourTo(i - 1, SCE_LISP_DEFAULT);\n\t\t\t\t\t\t\t\t   styler.ColourTo(i, SCE_LISP_OPERATOR);\n\t\t\t\t\t\t\t\t   state = SCE_LISP_DEFAULT;\n\t\t\t\t\t\t\t   }\n\t\t\t\t\t\t\t   break;\n\t\t\t\t\t\tdefault: if (isLispoperator(ch)) {\n\t\t\t\t\t\t\t\t styler.ColourTo(i - 1, SCE_LISP_DEFAULT);\n\t\t\t\t\t\t\t\t styler.ColourTo(i, SCE_LISP_OPERATOR);\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t state = SCE_LISP_DEFAULT;\n\t\t\t\t\t\t\t break;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (state == SCE_LISP_MACRO) {\n\t\t\tif (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {\n\t\t\t\tstate = SCE_LISP_SPECIAL;\n\t\t\t} else {\n\t\t\t\tstate = SCE_LISP_DEFAULT;\n\t\t\t}\n\t\t} else if (state == SCE_LISP_CHARACTER) {\n\t\t\tif (isLispoperator(ch)) {\n\t\t\t\tstyler.ColourTo(i, SCE_LISP_SPECIAL);\n\t\t\t\tstate = SCE_LISP_DEFAULT;\n\t\t\t} else if (isLispwordstart(ch)) {\n\t\t\t\tstyler.ColourTo(i, SCE_LISP_SPECIAL);\n\t\t\t\tstate = SCE_LISP_SPECIAL;\n\t\t\t} else {\n\t\t\t\tstate = SCE_LISP_DEFAULT;\n\t\t\t}\n\t\t} else if (state == SCE_LISP_SPECIAL) {\n\t\t\tif (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_LISP_DEFAULT;\n\t\t\t}\n\t\t\tif (isLispoperator(ch) || ch=='\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstyler.ColourTo(i, SCE_LISP_OPERATOR);\n\t\t\t\tif (ch=='\\'' && isLispwordstart(chNext)) {\n\t\t\t\t\tstate = SCE_LISP_SYMBOL;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (state == SCE_LISP_COMMENT) {\n\t\t\t\tif (atEOL) {\n\t\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\t\tstate = SCE_LISP_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (state == SCE_LISP_MULTI_COMMENT) {\n\t\t\t\tif (ch == '|' && chNext == '#') {\n\t\t\t\t\ti++;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\t\tstate = SCE_LISP_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (state == SCE_LISP_STRING) {\n\t\t\t\tif (ch == '\\\\') {\n\t\t\t\t\tif (chNext == '\\\"' || chNext == '\\'' || chNext == '\\\\') {\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == '\\\"') {\n\t\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\t\tstate = SCE_LISP_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n\tstyler.ColourTo(lengthDoc - 1, state);\n}\n\nstatic void FoldLispDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],\n                            Accessor &styler) {\n\tSci_PositionU lengthDoc = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (style == SCE_LISP_OPERATOR) {\n\t\t\tif (ch == '(' || ch == '[' || ch == '{') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == ')' || ch == ']' || ch == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const lispWordListDesc[] = {\n\t\"Functions and special operators\",\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, \"lisp\", FoldLispDoc, lispWordListDesc);\n"
  },
  {
    "path": "lexers/LexLout.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexLout.cxx\n ** Lexer for the Basser Lout (>= version 3) typesetting language\n **/\n// Copyright 2003 by Kein-Hong Man <mkh@pl.jaring.my>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');\n}\n\nstatic inline bool IsAnOther(const int ch) {\n\treturn (ch < 0x80) && (ch == '{' || ch == '}' ||\n\tch == '!' || ch == '$' || ch == '%' || ch == '&' || ch == '\\'' ||\n\tch == '(' || ch == ')' || ch == '*' || ch == '+' || ch == ',' ||\n\tch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == ';' ||\n\tch == '<' || ch == '=' || ch == '>' || ch == '?' || ch == '[' ||\n\tch == ']' || ch == '^' || ch == '`' || ch == '|' || ch == '~');\n}\n\nstatic void ColouriseLoutDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\t\t     WordList *keywordlists[], Accessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\n\tint visibleChars = 0;\n\tint firstWordInLine = 0;\n\tint leadingAtSign = 0;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.atLineStart && (sc.state == SCE_LOUT_STRING)) {\n\t\t\t// Prevent SCE_LOUT_STRINGEOL from leaking back to previous line\n\t\t\tsc.SetState(SCE_LOUT_STRING);\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_LOUT_COMMENT) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_LOUT_DEFAULT);\n\t\t\t\tvisibleChars = 0;\n\t\t\t}\n\t\t} else if (sc.state == SCE_LOUT_NUMBER) {\n\t\t\tif (!IsADigit(sc.ch) && sc.ch != '.') {\n\t\t\t\tsc.SetState(SCE_LOUT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_LOUT_STRING) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\\\') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_LOUT_DEFAULT);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_LOUT_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_LOUT_DEFAULT);\n\t\t\t\tvisibleChars = 0;\n\t\t\t}\n\t\t} else if (sc.state == SCE_LOUT_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\n\t\t\t\tif (leadingAtSign) {\n\t\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_LOUT_WORD);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ChangeState(SCE_LOUT_WORD4);\n\t\t\t\t\t}\n\t\t\t\t} else if (firstWordInLine && keywords3.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_LOUT_WORD3);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_LOUT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_LOUT_OPERATOR) {\n\t\t\tif (!IsAnOther(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\n\t\t\t\tif (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_LOUT_WORD2);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_LOUT_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_LOUT_DEFAULT) {\n\t\t\tif (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_LOUT_COMMENT);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_LOUT_STRING);\n\t\t\t} else if (IsADigit(sc.ch) ||\n\t\t\t\t  (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_LOUT_NUMBER);\n\t\t\t} else if (IsAWordChar(sc.ch)) {\n\t\t\t\tfirstWordInLine = (visibleChars == 0);\n\t\t\t\tleadingAtSign = (sc.ch == '@');\n\t\t\t\tsc.SetState(SCE_LOUT_IDENTIFIER);\n\t\t\t} else if (IsAnOther(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_LOUT_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\t// Reset states to begining of colourise so no surprises\n\t\t\t// if different sets of lines lexed.\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!IsASpace(sc.ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void FoldLoutDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],\n                        Accessor &styler) {\n\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tint styleNext = styler.StyleAt(startPos);\n\tchar s[10] = \"\";\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (style == SCE_LOUT_WORD) {\n\t\t\tif (ch == '@') {\n\t\t\t\tfor (Sci_PositionU j = 0; j < 8; j++) {\n\t\t\t\t\tif (!IsAWordChar(styler[i + j])) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ts[j] = styler[i + j];\n\t\t\t\t\ts[j + 1] = '\\0';\n\t\t\t\t}\n\t\t\t\tif (strcmp(s, \"@Begin\") == 0) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t} else if (strcmp(s, \"@End\") == 0) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (style == SCE_LOUT_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact) {\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\t}\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0)) {\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const loutWordLists[] = {\n            \"Predefined identifiers\",\n            \"Predefined delimiters\",\n            \"Predefined keywords\",\n            0,\n        };\n\nextern const LexerModule lmLout(SCLEX_LOUT, ColouriseLoutDoc, \"lout\", FoldLoutDoc, loutWordLists);\n"
  },
  {
    "path": "lexers/LexLua.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexLua.cxx\n ** Lexer for Lua language.\n **\n ** Written by Paul Winwood.\n ** Folder by Alexey Yutkin.\n ** Modified by Marcos E. Wurzius & Philippe Lhoste\n **/\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"SubStyles.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\n// Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ],\n// return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on.\n// The maximum number of '=' characters allowed is 254.\nint LongDelimCheck(StyleContext &sc) {\n\tconstexpr int maximumEqualCharacters = 254;\n\tint sep = 1;\n\twhile (sc.GetRelative(sep) == '=' && sep <= maximumEqualCharacters)\n\t\tsep++;\n\tif (sc.GetRelative(sep) == sc.ch)\n\t\treturn sep;\n\treturn 0;\n}\n\nconst char *const luaWordListDesc[] = {\n\t\"Keywords\",\n\t\"Basic functions\",\n\t\"String, (table) & math functions\",\n\t\"(coroutines), I/O & system facilities\",\n\t\"user1\",\n\t\"user2\",\n\t\"user3\",\n\t\"user4\",\n\tnullptr\n};\n\nconst char styleSubable[] = { SCE_LUA_IDENTIFIER, 0 };\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer Lua SCLEX_LUA SCE_LUA_:\n\t0, \"SCE_LUA_DEFAULT\", \"default\", \"White space: Visible only in View Whitespace mode (or if it has a back colour)\",\n\t1, \"SCE_LUA_COMMENT\", \"comment\", \"Block comment (Lua 5.0)\",\n\t2, \"SCE_LUA_COMMENTLINE\", \"comment line\", \"Line comment\",\n\t3, \"SCE_LUA_COMMENTDOC\", \"comment documentation\", \"Doc comment\",\n\t4, \"SCE_LUA_NUMBER\", \"literal numeric\", \"Number\",\n\t5, \"SCE_LUA_WORD\", \"keyword\", \"Keyword\",\n\t6, \"SCE_LUA_STRING\", \"literal string\", \"(Double quoted) String\",\n\t7, \"SCE_LUA_CHARACTER\", \"literal string character\", \"Character (Single quoted string)\",\n\t8, \"SCE_LUA_LITERALSTRING\", \"literal string\", \"Literal string\",\n\t9, \"SCE_LUA_PREPROCESSOR\", \"preprocessor\", \"Preprocessor (obsolete in Lua 4.0 and up)\",\n\t10, \"SCE_LUA_OPERATOR\", \"operator\", \"Operators\",\n\t11, \"SCE_LUA_IDENTIFIER\", \"identifier\", \"Identifier (everything else...)\",\n\t12, \"SCE_LUA_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n\t13, \"SCE_LUA_WORD2\", \"identifier\", \"Other keywords\",\n\t14, \"SCE_LUA_WORD3\", \"identifier\", \"Other keywords\",\n\t15, \"SCE_LUA_WORD4\", \"identifier\", \"Other keywords\",\n\t16, \"SCE_LUA_WORD5\", \"identifier\", \"Other keywords\",\n\t17, \"SCE_LUA_WORD6\", \"identifier\", \"Other keywords\",\n\t18, \"SCE_LUA_WORD7\", \"identifier\", \"Other keywords\",\n\t19, \"SCE_LUA_WORD8\", \"identifier\", \"Other keywords\",\n\t20, \"SCE_LUA_LABEL\", \"label\", \"Labels\",\n};\n\n// Options used for LexerLua\nstruct OptionsLua {\n\tbool foldCompact = true;\n};\n\nstruct OptionSetLua : public OptionSet<OptionsLua> {\n\tOptionSetLua() {\n\t\tDefineProperty(\"fold.compact\", &OptionsLua::foldCompact);\n\n\t\tDefineWordListSets(luaWordListDesc);\n\t}\n};\n\nclass LexerLua : public DefaultLexer {\n\tWordList keywords;\n\tWordList keywords2;\n\tWordList keywords3;\n\tWordList keywords4;\n\tWordList keywords5;\n\tWordList keywords6;\n\tWordList keywords7;\n\tWordList keywords8;\n\tOptionsLua options;\n\tOptionSetLua osLua;\n\tSubStyles subStyles{styleSubable};\npublic:\n\texplicit LexerLua() :\n\t\tDefaultLexer(\"lua\", SCLEX_LUA, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\tLexerLua(const LexerLua &) = delete;\n\tLexerLua(LexerLua &&) = delete;\n\tLexerLua &operator=(const LexerLua &) = delete;\n\tLexerLua &operator=(LexerLua &&) = delete;\n\t~LexerLua() override = default;\n\tvoid SCI_METHOD Release() noexcept override {\n\t\tdelete this;\n\t}\n\t[[nodiscard]] int SCI_METHOD Version() const noexcept override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() noexcept override {\n\t\treturn osLua.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osLua.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osLua.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osLua.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() noexcept override {\n\t\treturn osLua.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {\n\t\treturn subStyles.Allocate(styleBase, numberStyles);\n\t}\n\tint SCI_METHOD SubStylesStart(int styleBase) override {\n\t\treturn subStyles.Start(styleBase);\n\t}\n\tint SCI_METHOD SubStylesLength(int styleBase) override {\n\t\treturn subStyles.Length(styleBase);\n\t}\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override {\n\t\tconst int styleBase = subStyles.BaseStyle(subStyle);\n\t\treturn styleBase;\n\t}\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) override {\n\t\treturn style;\n\t}\n\tvoid SCI_METHOD FreeSubStyles() override {\n\t\tsubStyles.Free();\n\t}\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {\n\t\tsubStyles.SetIdentifiers(style, identifiers);\n\t}\n\tint SCI_METHOD DistanceToSecondaryStyles() override {\n\t\treturn 0;\n\t}\n\tconst char *SCI_METHOD GetSubStyleBases() override {\n\t\treturn styleSubable;\n\t}\n\n\tstatic ILexer5 *LexerFactoryLua() {\n\t\treturn new LexerLua();\n\t}\n};\n\nSci_Position SCI_METHOD LexerLua::PropertySet(const char *key, const char *val) {\n\tif (osLua.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerLua::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywords2;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywords3;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywords4;\n\t\tbreak;\n\tcase 4:\n\t\twordListN = &keywords5;\n\t\tbreak;\n\tcase 5:\n\t\twordListN = &keywords6;\n\t\tbreak;\n\tcase 6:\n\t\twordListN = &keywords7;\n\t\tbreak;\n\tcase 7:\n\t\twordListN = &keywords8;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nconstexpr int maskSeparator = 0xFF;\nconstexpr int maskStringWs = 0x100;\nconstexpr int maskDocComment = 0x200;\n\nvoid LexerLua::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\n\t// Accepts accented characters\n\tconst CharacterSet setWordStart(CharacterSet::setAlpha, \"_\", true);\n\tconst CharacterSet setWord(CharacterSet::setAlphaNum, \"_\", true);\n\t// Not exactly following number definition (several dots are seen as OK, etc.)\n\t// but probably enough in most cases. [pP] is for hex floats.\n\tconst CharacterSet setNumber(CharacterSet::setDigits, \".-+abcdefpABCDEFP\");\n\tconst CharacterSet setExponent(\"eEpP\");\n\tconst CharacterSet setLuaOperator(\"*/-+()={}~[];<>,.^%:#&|\");\n\tconst CharacterSet setEscapeSkip(\"\\\"'\\\\\");\n\n\tconst WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_LUA_IDENTIFIER);\n\n\tSci_Position currentLine = styler.GetLine(startPos);\n\t// Initialize long string [[ ... ]] or block comment --[[ ... ]],\n\t// if we are inside such a string. Block comment was introduced in Lua 5.0,\n\t// blocks with separators [=[ ... ]=] in Lua 5.1.\n\t// Continuation of a string (\\z whitespace escaping) is controlled by stringWs.\n\tint sepCount = 0;\n\tint stringWs = 0;\n\tint lastLineDocComment = 0;\n\tif ((currentLine > 0) &&\n\t\tAnyOf(initStyle, SCE_LUA_DEFAULT, SCE_LUA_LITERALSTRING, SCE_LUA_COMMENT, SCE_LUA_COMMENTDOC, SCE_LUA_STRING, SCE_LUA_CHARACTER)) {\n\t\tconst int lineState = styler.GetLineState(currentLine - 1);\n\t\tsepCount = lineState & maskSeparator;\n\t\tstringWs = lineState & maskStringWs;\n\t\tlastLineDocComment = lineState & maskDocComment;\n\t}\n\n\t// results of identifier/keyword matching\n\tSci_Position idenPos = 0;\n\tSci_Position idenStartCharWidth = 0;\n\tSci_Position idenWordPos = 0;\n\tint idenStyle = SCE_LUA_IDENTIFIER;\n\tbool foundGoto = false;\n\n\t// Do not leak onto next line\n\tif (AnyOf(initStyle, SCE_LUA_STRINGEOL, SCE_LUA_COMMENTLINE, SCE_LUA_COMMENTDOC, SCE_LUA_PREPROCESSOR)) {\n\t\tinitStyle = SCE_LUA_DEFAULT;\n\t}\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tif (startPos == 0 && sc.ch == '#' && sc.chNext == '!') {\n\t\t// shbang line: \"#!\" is a comment only if located at the start of the script\n\t\tsc.SetState(SCE_LUA_COMMENTLINE);\n\t}\n\tfor (; sc.More(); sc.Forward()) {\n\t\tif (sc.atLineEnd) {\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tcurrentLine = styler.GetLine(sc.currentPos);\n\t\t\tswitch (sc.state) {\n\t\t\tcase SCE_LUA_DEFAULT:\n\t\t\tcase SCE_LUA_LITERALSTRING:\n\t\t\tcase SCE_LUA_COMMENT:\n\t\t\tcase SCE_LUA_COMMENTDOC:\n\t\t\tcase SCE_LUA_STRING:\n\t\t\tcase SCE_LUA_CHARACTER:\n\t\t\t\t// Inside a literal string, block comment or string, we set the line state\n\t\t\t\tstyler.SetLineState(currentLine, lastLineDocComment | stringWs | sepCount);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Reset the line state\n\t\t\t\tstyler.SetLineState(currentLine, 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (sc.atLineStart && (sc.state == SCE_LUA_STRING)) {\n\t\t\t// Prevent SCE_LUA_STRINGEOL from leaking back to previous line\n\t\t\tsc.SetState(SCE_LUA_STRING);\n\t\t}\n\n\t\t// Handle string line continuation\n\t\tif ((sc.state == SCE_LUA_STRING || sc.state == SCE_LUA_CHARACTER) &&\n\t\t\t\tsc.ch == '\\\\') {\n\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_LUA_OPERATOR) {\n\t\t\tif (sc.ch == ':' && sc.chPrev == ':') {\t// :: <label> :: forward scan\n\t\t\t\tsc.Forward();\n\t\t\t\tSci_Position ln = 0;\n\t\t\t\twhile (IsASpaceOrTab(sc.GetRelativeChar(ln)))\t// skip over spaces/tabs\n\t\t\t\t\tln++;\n\t\t\t\tconst Sci_Position ws1 = ln;\n\t\t\t\tif (setWordStart.Contains(sc.GetRelativeChar(ln))) {\n\t\t\t\t\tchar cLabel = 0;\n\t\t\t\t\tstd::string s;\n\t\t\t\t\twhile (setWord.Contains(cLabel = sc.GetRelativeChar(ln))) {\t// get potential label\n\t\t\t\t\t\ts.push_back(cLabel);\n\t\t\t\t\t\tln++;\n\t\t\t\t\t}\n\t\t\t\t\tconst Sci_Position lbl = ln;\n\t\t\t\t\tif (!keywords.InList(s)) {\n\t\t\t\t\t\twhile (IsASpaceOrTab(sc.GetRelativeChar(ln)))\t// skip over spaces/tabs\n\t\t\t\t\t\t\tln++;\n\t\t\t\t\t\tconst Sci_Position ws2 = ln - lbl;\n\t\t\t\t\t\tif (sc.GetRelativeChar(ln) == ':' && sc.GetRelativeChar(ln + 1) == ':') {\n\t\t\t\t\t\t\t// final :: found, complete valid label construct\n\t\t\t\t\t\t\tsc.ChangeState(SCE_LUA_LABEL);\n\t\t\t\t\t\t\tif (ws1) {\n\t\t\t\t\t\t\t\tsc.SetState(SCE_LUA_DEFAULT);\n\t\t\t\t\t\t\t\tsc.ForwardBytes(ws1);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsc.SetState(SCE_LUA_LABEL);\n\t\t\t\t\t\t\tsc.ForwardBytes(lbl - ws1);\n\t\t\t\t\t\t\tif (ws2) {\n\t\t\t\t\t\t\t\tsc.SetState(SCE_LUA_DEFAULT);\n\t\t\t\t\t\t\t\tsc.ForwardBytes(ws2);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsc.SetState(SCE_LUA_LABEL);\n\t\t\t\t\t\t\tsc.ForwardBytes(2);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tsc.SetState(SCE_LUA_DEFAULT);\n\t\t} else if (sc.state == SCE_LUA_NUMBER) {\n\t\t\t// We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char\n\t\t\tif (!setNumber.Contains(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_LUA_DEFAULT);\n\t\t\t} else if (sc.ch == '-' || sc.ch == '+') {\n\t\t\t\tif (!setExponent.Contains(sc.chPrev))\n\t\t\t\t\tsc.SetState(SCE_LUA_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_LUA_IDENTIFIER) {\n\t\t\tidenPos -= idenStartCharWidth;\t\t\t// commit already-scanned identifier/word parts\n\t\t\tif (idenWordPos > 0) {\n\t\t\t\tidenWordPos--;\n\t\t\t\tsc.ChangeState(idenStyle);\n\t\t\t\tsc.ForwardBytes(idenWordPos);\n\t\t\t\tidenPos -= idenWordPos;\n\t\t\t\tif (idenPos > 0) {\n\t\t\t\t\tsc.SetState(SCE_LUA_IDENTIFIER);\n\t\t\t\t\tsc.ForwardBytes(idenPos);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsc.ForwardBytes(idenPos);\n\t\t\t}\n\t\t\tsc.SetState(SCE_LUA_DEFAULT);\n\t\t\tif (foundGoto) {\t\t\t\t\t// goto <label> forward scan\n\t\t\t\twhile (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)\n\t\t\t\t\tsc.Forward();\n\t\t\t\tif (setWordStart.Contains(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_LUA_LABEL);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\twhile (setWord.Contains(sc.ch))\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\tstd::string s;\n\t\t\t\t\tsc.GetCurrentString(s, StyleContext::Transform::none);\n\t\t\t\t\tif (keywords.InList(s))\t\t// labels cannot be keywords\n\t\t\t\t\t\tsc.ChangeState(SCE_LUA_WORD);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_LUA_DEFAULT);\n\t\t\t}\n\t\t} else if (AnyOf(sc.state, SCE_LUA_COMMENTLINE, SCE_LUA_COMMENTDOC, SCE_LUA_PREPROCESSOR)) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_LUA_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_LUA_STRING) {\n\t\t\tif (stringWs) {\n\t\t\t\tif (!IsASpace(sc.ch))\n\t\t\t\t\tstringWs = 0;\n\t\t\t}\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (setEscapeSkip.Contains(sc.chNext)) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (sc.chNext == 'z') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tstringWs = maskStringWs;\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_LUA_DEFAULT);\n\t\t\t} else if (stringWs == 0 && sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_LUA_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_LUA_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_LUA_CHARACTER) {\n\t\t\tif (stringWs) {\n\t\t\t\tif (!IsASpace(sc.ch))\n\t\t\t\t\tstringWs = 0;\n\t\t\t}\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (setEscapeSkip.Contains(sc.chNext)) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (sc.chNext == 'z') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tstringWs = maskStringWs;\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.ForwardSetState(SCE_LUA_DEFAULT);\n\t\t\t} else if (stringWs == 0 && sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_LUA_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_LUA_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.ch == ']' && (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT)) {\n\t\t\tconst int sep = LongDelimCheck(sc);\n\t\t\tif (sep == sepCount) {   // ]=]-style delim\n\t\t\t\tsc.Forward(sep);\n\t\t\t\tsc.ForwardSetState(SCE_LUA_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_LUA_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_LUA_NUMBER);\n\t\t\t\tif (sc.ch == '0' && AnyOf(sc.chNext, 'x', 'X')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (setWordStart.Contains(sc.ch)) {\n\t\t\t\t// For matching various identifiers with dots and colons, multiple\n\t\t\t\t// matches are done as identifier segments are added. Longest match is\n\t\t\t\t// set to a word style. The non-matched part is in identifier style.\n\t\t\t\tstd::string ident;\n\t\t\t\tidenPos = 0;\n\t\t\t\tidenStartCharWidth = sc.width;\n\t\t\t\tidenWordPos = 0;\n\t\t\t\tidenStyle = SCE_LUA_IDENTIFIER;\n\t\t\t\tfoundGoto = false;\n\t\t\t\tchar cNext = 0;\n\t\t\t\tdo {\n\t\t\t\t\tchar cIdent = 0;\n\t\t\t\t\tconst Sci_Position idenPosOld = idenPos;\n\t\t\t\t\tstd::string identSeg;\n\t\t\t\t\tidentSeg += sc.GetRelativeChar(idenPos++);\n\t\t\t\t\twhile (setWord.Contains(cIdent = sc.GetRelativeChar(idenPos))) {\n\t\t\t\t\t\tidentSeg += cIdent;\n\t\t\t\t\t\tidenPos++;\n\t\t\t\t\t}\n\t\t\t\t\tif (keywords.InList(identSeg) && (idenPosOld > 0)) {\n\t\t\t\t\t\tidenPos = idenPosOld - 1;\t// keywords cannot mix\n\t\t\t\t\t\tident.pop_back();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tident += identSeg;\n\t\t\t\t\tint newStyle = SCE_LUA_IDENTIFIER;\n\t\t\t\t\tif (keywords.InList(ident)) {\n\t\t\t\t\t\tnewStyle = SCE_LUA_WORD;\n\t\t\t\t\t} else if (keywords2.InList(ident)) {\n\t\t\t\t\t\tnewStyle = SCE_LUA_WORD2;\n\t\t\t\t\t} else if (keywords3.InList(ident)) {\n\t\t\t\t\t\tnewStyle = SCE_LUA_WORD3;\n\t\t\t\t\t} else if (keywords4.InList(ident)) {\n\t\t\t\t\t\tnewStyle = SCE_LUA_WORD4;\n\t\t\t\t\t} else if (keywords5.InList(ident)) {\n\t\t\t\t\t\tnewStyle = SCE_LUA_WORD5;\n\t\t\t\t\t} else if (keywords6.InList(ident)) {\n\t\t\t\t\t\tnewStyle = SCE_LUA_WORD6;\n\t\t\t\t\t} else if (keywords7.InList(ident)) {\n\t\t\t\t\t\tnewStyle = SCE_LUA_WORD7;\n\t\t\t\t\t} else if (keywords8.InList(ident)) {\n\t\t\t\t\t\tnewStyle = SCE_LUA_WORD8;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst int subStyle = classifierIdentifiers.ValueFor(ident);\n\t\t\t\t\t\tif (subStyle >= 0) {\n\t\t\t\t\t\t\tnewStyle = subStyle;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (newStyle != SCE_LUA_IDENTIFIER) {\n\t\t\t\t\t\tidenStyle = newStyle;\n\t\t\t\t\t\tidenWordPos = idenPos;\n\t\t\t\t\t}\n\t\t\t\t\tif (idenStyle == SCE_LUA_WORD)\t// keywords cannot mix\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcNext = sc.GetRelativeChar(idenPos + 1);\n\t\t\t\t\tif ((cIdent == '.' || cIdent == ':') && setWordStart.Contains(cNext)) {\n\t\t\t\t\t\tident += cIdent;\n\t\t\t\t\t\tidenPos++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcNext = 0;\n\t\t\t\t\t}\n\t\t\t\t} while (cNext);\n\t\t\t\tif ((idenStyle == SCE_LUA_WORD) && (ident == \"goto\")) {\n\t\t\t\t\tfoundGoto = true;\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_LUA_IDENTIFIER);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_LUA_STRING);\n\t\t\t\tstringWs = 0;\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_LUA_CHARACTER);\n\t\t\t\tstringWs = 0;\n\t\t\t} else if (sc.ch == '[') {\n\t\t\t\tsepCount = LongDelimCheck(sc);\n\t\t\t\tif (sepCount == 0) {\n\t\t\t\t\tsc.SetState(SCE_LUA_OPERATOR);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_LUA_LITERALSTRING);\n\t\t\t\t\tsc.Forward(sepCount);\n\t\t\t\t}\n\t\t\t} else if (sc.Match('-', '-')) {\n\t\t\t\tsc.SetState(lastLineDocComment ? SCE_LUA_COMMENTDOC : SCE_LUA_COMMENTLINE);\n\t\t\t\tif (sc.Match(\"--[\")) {\n\t\t\t\t\tsc.Forward(2);\n\t\t\t\t\tsepCount = LongDelimCheck(sc);\n\t\t\t\t\tif (sepCount > 0) {\n\t\t\t\t\t\tsc.ChangeState(SCE_LUA_COMMENT);\n\t\t\t\t\t\tsc.Forward(sepCount);\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.Match(\"---\")) {\n\t\t\t\t\tsc.SetState(SCE_LUA_COMMENTDOC);\n\t\t\t\t\tlastLineDocComment = maskDocComment;\n\t\t\t\t} else {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.atLineStart && sc.Match('$')) {\n\t\t\t\tsc.SetState(SCE_LUA_PREPROCESSOR);\t// Obsolete since Lua 4.0, but still in old code\n\t\t\t} else if (setLuaOperator.Contains(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_LUA_OPERATOR);\n\t\t\t}\n\t\t\tif (!AnyOf(sc.state, SCE_LUA_DEFAULT, SCE_LUA_COMMENTDOC)) {\n\t\t\t\tlastLineDocComment = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tsc.Complete();\n}\n\nvoid LexerLua::Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\tconst Sci_Position startPos = startPos_;\n\tconst Sci_Position lengthDoc = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tconst bool foldCompact = options.foldCompact;\n\tint style = initStyle;\n\tint styleNext = styler.StyleIndexAt(startPos);\n\n\tfor (Sci_Position i = startPos; i < lengthDoc; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tif ((i + 1) < lengthDoc) {\n\t\t\t// Only read styles that have been set, otherwise treat style as continuing\n\t\t\tstyleNext = styler.StyleIndexAt(i + 1);\n\t\t}\n\t\tconst bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (style == SCE_LUA_WORD) {\n\t\t\t// Fixed list of folding words: if, do, function, repeat, end, until\n\t\t\t// Must fix up next line with initial characters if any new words added.\n\t\t\tif ((style != stylePrev) && AnyOf(ch, 'i', 'd', 'f', 'e', 'r', 'u')) {\n\t\t\t\tconstexpr Sci_Position maxFoldWord = 9; // \"function\"sv.length() + 1\n\t\t\t\tstd::string s;\n\t\t\t\tfor (Sci_Position j = 0; j < maxFoldWord; j++) {\n\t\t\t\t\tif (!iswordchar(styler[i + j])) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ts.push_back(styler[i + j]);\n\t\t\t\t}\n\n\t\t\t\tif (s == \"if\" || s == \"do\" || s == \"function\" || s == \"repeat\") {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t}\n\t\t\t\tif (s == \"end\" || s == \"until\") {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (style == SCE_LUA_OPERATOR) {\n\t\t\tif (ch == '{' || ch == '(') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == '}' || ch == ')') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t} else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) {\n\t\t\tif (stylePrev != style) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (styleNext != style) {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tconst int lev = levelPrev |\n\t\t\t\tFoldLevelFlags(levelPrev, levelCurrent, visibleChars == 0 && foldCompact, visibleChars > 0);\n\t\t\tstyler.SetLevelIfDifferent(lineCurrent, lev);\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\n\tconst int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\n}\n\nextern const LexerModule lmLua(SCLEX_LUA, LexerLua::LexerFactoryLua, \"lua\", luaWordListDesc);\n"
  },
  {
    "path": "lexers/LexMMIXAL.cxx",
    "content": "// Scintilla source code edit control\n// Encoding: UTF-8\n/** @file LexMMIXAL.cxx\n ** Lexer for MMIX Assembler Language.\n ** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>\n ** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html\n **/\n// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');\n}\n\nstatic inline bool isMMIXALOperator(char ch) {\n\tif (IsASCII(ch) && isalnum(ch))\n\t\treturn false;\n\tif (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||\n\t\tch == '*' || ch == '/' ||\n\t\tch == '%' || ch == '<' || ch == '>' || ch == '&' ||\n\t\tch == '~' || ch == '$' ||\n\t\tch == ',' || ch == '(' || ch == ')' ||\n\t\tch == '[' || ch == ']')\n\t\treturn true;\n\treturn false;\n}\n\nstatic void ColouriseMMIXALDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler) {\n\n\tWordList &opcodes = *keywordlists[0];\n\tWordList &special_register = *keywordlists[1];\n\tWordList &predef_symbols = *keywordlists[2];\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward())\n\t{\n\t\t// No EOL continuation\n\t\tif (sc.atLineStart) {\n\t\t\tif (sc.ch ==  '@' && sc.chNext == 'i') {\n\t\t\t\tsc.SetState(SCE_MMIXAL_INCLUDE);\n\t\t\t} else {\n\t\t\t\tsc.SetState(SCE_MMIXAL_LEADWS);\n\t\t\t}\n\t\t}\n\n\t\t// Check if first non whitespace character in line is alphanumeric\n\t\tif (sc.state == SCE_MMIXAL_LEADWS && !isspace(sc.ch)) {\t// LEADWS\n\t\t\tif(!IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_COMMENT);\n\t\t\t} else {\n\t\t\t\tif(sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_MMIXAL_LABEL);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_MMIXAL_OPCODE_PRE);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_MMIXAL_OPERATOR) {\t\t\t// OPERATOR\n\t\t\tsc.SetState(SCE_MMIXAL_OPERANDS);\n\t\t} else if (sc.state == SCE_MMIXAL_NUMBER) {\t\t// NUMBER\n\t\t\tif (!isdigit(sc.ch)) {\n\t\t\t\tif (IsAWordChar(sc.ch)) {\n\t\t\t\t\tsc.ChangeState(SCE_MMIXAL_REF);\n\t\t\t\t\tsc.SetState(SCE_MMIXAL_REF);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_MMIXAL_OPERANDS);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (sc.state == SCE_MMIXAL_LABEL) {\t\t\t// LABEL\n\t\t\tif (!IsAWordChar(sc.ch) ) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_OPCODE_PRE);\n\t\t\t}\n\t\t} else if (sc.state == SCE_MMIXAL_REF) {\t\t\t// REF\n\t\t\tif (!IsAWordChar(sc.ch) ) {\n\t\t\t\tchar s0[100];\n\t\t\t\tsc.GetCurrent(s0, sizeof(s0));\n\t\t\t\tconst char *s = s0;\n\t\t\t\tif (*s == ':') {\t// ignore base prefix for match\n\t\t\t\t\t++s;\n\t\t\t\t}\n\t\t\t\tif (special_register.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_MMIXAL_REGISTER);\n\t\t\t\t} else if (predef_symbols.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_MMIXAL_SYMBOL);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_MMIXAL_OPERANDS);\n\t\t\t}\n\t\t} else if (sc.state == SCE_MMIXAL_OPCODE_PRE) {\t// OPCODE_PRE\n\t\t\t\tif (!isspace(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_MMIXAL_OPCODE);\n\t\t\t\t}\n\t\t} else if (sc.state == SCE_MMIXAL_OPCODE) {\t\t// OPCODE\n\t\t\tif (!IsAWordChar(sc.ch) ) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\tif (opcodes.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_MMIXAL_OPCODE_VALID);\n\t\t\t\t} else {\n\t\t\t\t\tsc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_MMIXAL_OPCODE_POST);\n\t\t\t}\n\t\t} else if (sc.state == SCE_MMIXAL_STRING) {\t\t// STRING\n\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_MMIXAL_OPERANDS);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_MMIXAL_OPERANDS);\n\t\t\t}\n\t\t} else if (sc.state == SCE_MMIXAL_CHAR) {\t\t\t// CHAR\n\t\t\tif (sc.ch == '\\'') {\n\t\t\t\tsc.ForwardSetState(SCE_MMIXAL_OPERANDS);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_MMIXAL_OPERANDS);\n\t\t\t}\n\t\t} else if (sc.state == SCE_MMIXAL_REGISTER) {\t\t// REGISTER\n\t\t\tif (!isdigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_OPERANDS);\n\t\t\t}\n\t\t} else if (sc.state == SCE_MMIXAL_HEX) {\t\t\t// HEX\n\t\t\tif (!isxdigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_OPERANDS);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_MMIXAL_OPCODE_POST ||\t\t// OPCODE_POST\n\t\t\tsc.state == SCE_MMIXAL_OPERANDS) {\t\t\t// OPERANDS\n\t\t\tif (sc.state == SCE_MMIXAL_OPERANDS && isspace(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_COMMENT);\n\t\t\t} else if (isdigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_NUMBER);\n\t\t\t} else if (IsAWordChar(sc.ch) || sc.Match('@')) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_REF);\n\t\t\t} else if (sc.Match('\\\"')) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_STRING);\n\t\t\t} else if (sc.Match('\\'')) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_CHAR);\n\t\t\t} else if (sc.Match('$')) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_REGISTER);\n\t\t\t} else if (sc.Match('#')) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_HEX);\n\t\t\t} else if (isMMIXALOperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_MMIXAL_OPERATOR);\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic const char * const MMIXALWordListDesc[] = {\n\t\"Operation Codes\",\n\t\"Special Register\",\n\t\"Predefined Symbols\",\n\t0\n};\n\nextern const LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, \"mmixal\", 0, MMIXALWordListDesc);\n\n"
  },
  {
    "path": "lexers/LexMPT.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexMPT.cxx\n ** Lexer for MPT specific files. Based on LexOthers.cxx\n ** LOT = the text log file created by the MPT application while running a test program\n ** Other MPT specific files to be added later.\n **/\n// Copyright 2003 by Marius Gheorghe <mgheorghe@cabletest.com>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic int GetLotLineState(std::string &line) {\n\tif (line.length()) {\n\t\t// Most of the time the first non-blank character in line determines that line's type\n\t\t// Now finds the first non-blank character\n\t\tunsigned i; // Declares counter here to make it persistent after the for loop\n\t\tfor (i = 0; i < line.length(); ++i) {\n\t\t\tif (!(IsASCII(line[i]) && isspace(line[i])))\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Checks if it was a blank line\n\t\tif (i == line.length())\n\t\t\treturn SCE_LOT_DEFAULT;\n\n\t\tswitch (line[i]) {\n\t\tcase '*': // Fail measurement\n\t\t\treturn SCE_LOT_FAIL;\n\n\t\tcase '+': // Header\n\t\tcase '|': // Header\n\t\t\treturn SCE_LOT_HEADER;\n\n\t\tcase ':': // Set test limits\n\t\t\treturn SCE_LOT_SET;\n\n\t\tcase '-': // Section break\n\t\t\treturn SCE_LOT_BREAK;\n\n\t\tdefault:  // Any other line\n\t\t\t// Checks for message at the end of lot file\n\t\t\tif (line.find(\"PASSED\") != std::string::npos) {\n\t\t\t\treturn SCE_LOT_PASS;\n\t\t\t}\n\t\t\telse if (line.find(\"FAILED\") != std::string::npos) {\n\t\t\t\treturn SCE_LOT_FAIL;\n\t\t\t}\n\t\t\telse if (line.find(\"ABORTED\") != std::string::npos) {\n\t\t\t\treturn SCE_LOT_ABORT;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;\n\t\t\t}\n\t\t}\n\t}\n\telse {\n\t\treturn SCE_LOT_DEFAULT;\n\t}\n}\n\nstatic void ColourizeLotDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tbool atLineStart = true;// Arms the 'at line start' flag\n\tchar chNext = styler.SafeGetCharAt(startPos);\n\tstd::string line(\"\");\n\tline.reserve(256);\t// Lot lines are less than 256 chars long most of the time. This should avoid reallocations\n\n\t// Styles LOT document\n\tSci_PositionU i;\t\t\t// Declared here because it's used after the for loop\n\tfor (i = startPos; i < startPos + length; ++i) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tline += ch;\n\t\tatLineStart = false;\n\n\t\t// LOT files are only used on the Win32 platform, thus EOL == CR+LF\n\t\t// Searches for the end of line\n\t\tif (ch == '\\r' && chNext == '\\n') {\n\t\t\tline += chNext; // Gets the '\\n'\n\t\t\t++i; // Advances past the '\\n'\n\t\t\tchNext = styler.SafeGetCharAt(i + 1); // Gets character of next line\n\t\t\tstyler.ColourTo(i, GetLotLineState(line));\n\t\t\tline = \"\";\n\t\t\tatLineStart = true; // Arms flag for next line\n\t\t}\n\t}\n\n\t// Last line may not have a line ending\n\tif (!atLineStart) {\n\t\tstyler.ColourTo(i - 1, GetLotLineState(line));\n\t}\n}\n\n// Folds an MPT LOT file: the blocks that can be folded are:\n// sections (headed by a set line)\n// passes (contiguous pass results within a section)\n// fails (contiguous fail results within a section)\nstatic void FoldLotDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 0) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\n\tchar chNext = styler.SafeGetCharAt(startPos);\n\tint style = SCE_LOT_DEFAULT;\n\tint styleNext = styler.StyleAt(startPos);\n\tint lev = SC_FOLDLEVELBASE;\n\n\t// Gets style of previous line if not at the beginning of the document\n\tif (startPos > 1)\n\t\tstyle = styler.StyleAt(startPos - 2);\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif (ch == '\\r' && chNext == '\\n') {\n\t\t\t// TO DO:\n\t\t\t// Should really get the state of the previous line from the styler\n\t\t\tint stylePrev = style;\n\t\t\tstyle = styleNext;\n\t\t\tstyleNext = styler.StyleAt(i + 2);\n\n\t\t\tswitch (style) {\n/*\n\t\t\tcase SCE_LOT_SET:\n\t\t\t\tlev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\t\t\tbreak;\n*/\n\t\t\tcase SCE_LOT_FAIL:\n/*\n\t\t\t\tif (stylePrev != SCE_LOT_FAIL)\n\t\t\t\t\tlev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\t\t\telse\n\t\t\t\t\tlev = SC_FOLDLEVELBASE + 1;\n*/\n\t\t\t\tlev = SC_FOLDLEVELBASE;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tif (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)\n\t\t\t\t\tlev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\t\t\telse\n\t\t\t\t\tlev = SC_FOLDLEVELBASE + 1;\n\n\t\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (lev != styler.LevelAt(lineCurrent))\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\n\t\t\tlineCurrent++;\n\t\t\tvisibleChars = 0;\n\t\t}\n\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, lev | flagsNext);\n}\n\nstatic const char * const emptyWordListDesc[] = {\n\t0\n};\n\nextern const LexerModule lmLot(SCLEX_LOT, ColourizeLotDoc, \"lot\", FoldLotDoc, emptyWordListDesc);\n"
  },
  {
    "path": "lexers/LexMSSQL.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexMSSQL.cxx\n ** Lexer for MSSQL.\n **/\n// By Filip Yaghob <fyaghob@gmail.com>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n#define KW_MSSQL_STATEMENTS         0\n#define KW_MSSQL_DATA_TYPES         1\n#define KW_MSSQL_SYSTEM_TABLES      2\n#define KW_MSSQL_GLOBAL_VARIABLES   3\n#define KW_MSSQL_FUNCTIONS          4\n#define KW_MSSQL_STORED_PROCEDURES  5\n#define KW_MSSQL_OPERATORS          6\n\nstatic char classifyWordSQL(Sci_PositionU start,\n                            Sci_PositionU end,\n                            WordList *keywordlists[],\n                            Accessor &styler,\n                            unsigned int actualState,\n\t\t\t\t\t\t\tunsigned int prevState) {\n\tchar s[256];\n\tbool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');\n\n\tWordList &kwStatements          = *keywordlists[KW_MSSQL_STATEMENTS];\n    WordList &kwDataTypes           = *keywordlists[KW_MSSQL_DATA_TYPES];\n    WordList &kwSystemTables        = *keywordlists[KW_MSSQL_SYSTEM_TABLES];\n    WordList &kwGlobalVariables     = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];\n    WordList &kwFunctions           = *keywordlists[KW_MSSQL_FUNCTIONS];\n    WordList &kwStoredProcedures    = *keywordlists[KW_MSSQL_STORED_PROCEDURES];\n    WordList &kwOperators           = *keywordlists[KW_MSSQL_OPERATORS];\n\n\tfor (Sci_PositionU i = 0; i < end - start + 1 && i < 128; i++) {\n\t\ts[i] = static_cast<char>(tolower(styler[start + i]));\n\t\ts[i + 1] = '\\0';\n\t}\n\tchar chAttr = SCE_MSSQL_IDENTIFIER;\n\n\tif (actualState == SCE_MSSQL_GLOBAL_VARIABLE) {\n\n        if (kwGlobalVariables.InList(&s[2]))\n            chAttr = SCE_MSSQL_GLOBAL_VARIABLE;\n\n\t} else if (wordIsNumber) {\n\t\tchAttr = SCE_MSSQL_NUMBER;\n\n\t} else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {\n\t\t// Look first in datatypes\n        if (kwDataTypes.InList(s))\n            chAttr = SCE_MSSQL_DATATYPE;\n\t\telse if (kwOperators.InList(s))\n\t\t\tchAttr = SCE_MSSQL_OPERATOR;\n\t\telse if (kwStatements.InList(s))\n\t\t\tchAttr = SCE_MSSQL_STATEMENT;\n\t\telse if (kwSystemTables.InList(s))\n\t\t\tchAttr = SCE_MSSQL_SYSTABLE;\n\t\telse if (kwFunctions.InList(s))\n            chAttr = SCE_MSSQL_FUNCTION;\n\t\telse if (kwStoredProcedures.InList(s))\n\t\t\tchAttr = SCE_MSSQL_STORED_PROCEDURE;\n\n\t} else {\n\t\tif (kwOperators.InList(s))\n\t\t\tchAttr = SCE_MSSQL_OPERATOR;\n\t\telse if (kwStatements.InList(s))\n\t\t\tchAttr = SCE_MSSQL_STATEMENT;\n\t\telse if (kwSystemTables.InList(s))\n\t\t\tchAttr = SCE_MSSQL_SYSTABLE;\n\t\telse if (kwFunctions.InList(s))\n\t\t\tchAttr = SCE_MSSQL_FUNCTION;\n\t\telse if (kwStoredProcedures.InList(s))\n\t\t\tchAttr = SCE_MSSQL_STORED_PROCEDURE;\n\t\telse if (kwDataTypes.InList(s))\n\t\t\tchAttr = SCE_MSSQL_DATATYPE;\n\t}\n\n\tstyler.ColourTo(end, chAttr);\n\n\treturn chAttr;\n}\n\nstatic void ColouriseMSSQLDoc(Sci_PositionU startPos, Sci_Position length,\n                              int initStyle, WordList *keywordlists[], Accessor &styler) {\n\n\n\tstyler.StartAt(startPos);\n\n\tbool fold = styler.GetPropertyInt(\"fold\") != 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint spaceFlags = 0;\n\n\tint state = initStyle;\n\tint prevState = initStyle;\n\tchar chPrev = ' ';\n\tchar chNext = styler[startPos];\n\tint nesting = 0;\n\n\tif (lineCurrent >= 1) {\n\t\tnesting = styler.GetLineState(lineCurrent - 1);\n\t}\n\n\tstyler.StartSegment(startPos);\n\tSci_PositionU lengthDoc = startPos + length;\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tconst Sci_Position lineStartNext = styler.LineStart(lineCurrent + 1);\n\t\tconst bool atEOL = (static_cast<Sci_Position>(i) == (lineStartNext - 1));\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n')) {\n\t\t\tint indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);\n\t\t\tint lev = indentCurrent;\n\t\t\tif (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n\t\t\t\t// Only non whitespace lines can be headers\n\t\t\t\tint indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);\n\t\t\t\tif (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {\n\t\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (fold) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t}\n\n\t\tif (styler.IsLeadByte(ch)) {\n\t\t\tchNext = styler.SafeGetCharAt(i + 2);\n\t\t\tchPrev = ' ';\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// When the last char isn't part of the state (have to deal with it too)...\n\t\tif ( (state == SCE_MSSQL_IDENTIFIER) ||\n                    (state == SCE_MSSQL_STORED_PROCEDURE) ||\n                    (state == SCE_MSSQL_DATATYPE) ||\n                    //~ (state == SCE_MSSQL_COLUMN_NAME) ||\n                    (state == SCE_MSSQL_FUNCTION) ||\n                    //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||\n                    (state == SCE_MSSQL_VARIABLE)) {\n\t\t\tif (!iswordchar(ch)) {\n\t\t\t\tint stateTmp;\n\n                if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) {\n                    styler.ColourTo(i - 1, state);\n\t\t\t\t\tstateTmp = state;\n                } else\n                    stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);\n\n\t\t\t\tprevState = state;\n\n\t\t\t\tif (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE)\n\t\t\t\t\tstate = SCE_MSSQL_DEFAULT_PREF_DATATYPE;\n\t\t\t\telse\n\t\t\t\t\tstate = SCE_MSSQL_DEFAULT;\n\t\t\t}\n\t\t} else if (state == SCE_MSSQL_LINE_COMMENT) {\n\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tprevState = state;\n\t\t\t\tstate = SCE_MSSQL_DEFAULT;\n\t\t\t}\n\t\t} else if (state == SCE_MSSQL_GLOBAL_VARIABLE) {\n\t\t\tif ((ch != '@') && !iswordchar(ch)) {\n\t\t\t\tclassifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);\n\t\t\t\tprevState = state;\n\t\t\t\tstate = SCE_MSSQL_DEFAULT;\n\t\t\t}\n\t\t}\n\n\t\t// If is the default or one of the above succeeded\n\t\tif (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {\n\t\t\tif (iswordstart(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tprevState = state;\n\t\t\t\tstate = SCE_MSSQL_IDENTIFIER;\n\t\t\t} else if (ch == '/' && chNext == '*') {\n\t\t\t\tstyler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);\n\t\t\t\tprevState = state;\n\t\t\t\tstate = SCE_MSSQL_COMMENT;\n\t\t\t} else if (ch == '-' && chNext == '-') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tprevState = state;\n\t\t\t\tstate = SCE_MSSQL_LINE_COMMENT;\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);\n\t\t\t\tprevState = state;\n\t\t\t\tstate = SCE_MSSQL_STRING;\n\t\t\t} else if (ch == '\"') {\n\t\t\t\tstyler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);\n\t\t\t\tprevState = state;\n\t\t\t\tstate = SCE_MSSQL_COLUMN_NAME;\n\t\t\t} else if (ch == '[') {\n\t\t\t\tstyler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);\n\t\t\t\tprevState = state;\n\t\t\t\tstate = SCE_MSSQL_COLUMN_NAME_2;\n\t\t\t} else if (isoperator(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstyler.ColourTo(i, SCE_MSSQL_OPERATOR);\n                //~ style = SCE_MSSQL_DEFAULT;\n\t\t\t\tprevState = state;\n\t\t\t\tstate = SCE_MSSQL_DEFAULT;\n\t\t\t} else if (ch == '@') {\n                styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);\n\t\t\t\tprevState = state;\n                if (chNext == '@') {\n                    state = SCE_MSSQL_GLOBAL_VARIABLE;\n//                    i += 2;\n                } else\n                    state = SCE_MSSQL_VARIABLE;\n            }\n\n\n\t\t// When the last char is part of the state...\n\t\t} else if (state == SCE_MSSQL_COMMENT) {\n\t\t\t\tif (ch == '/' && chNext == '*')\n\t\t\t\t\tnesting++;\n\t\t\t\telse if (ch == '/' && chPrev == '*') {\n\t\t\t\t\tif (nesting > 0)\n\t\t\t\t\t\tnesting--;\n\t\t\t\t\telse if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) &&\n\t\t\t\t\t    (styler.GetStartSegment() == startPos)))) {\n\t\t\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\t\t\t//~ state = SCE_MSSQL_COMMENT;\n\t\t\t\t\tprevState = state;\n                        state = SCE_MSSQL_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (state == SCE_MSSQL_STRING) {\n\t\t\t\tif (ch == '\\'') {\n\t\t\t\t\tif ( chNext == '\\'' ) {\n\t\t\t\t\t\ti++;\n\t\t\t\t\tch = chNext;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\t\tprevState = state;\n\t\t\t\t\t\tstate = SCE_MSSQL_DEFAULT;\n\t\t\t\t\t//i++;\n\t\t\t\t\t}\n\t\t\t\t//ch = chNext;\n\t\t\t\t//chNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t}\n\t\t\t} else if (state == SCE_MSSQL_COLUMN_NAME) {\n\t\t\t\tif (ch == '\"') {\n\t\t\t\t\tif (chNext == '\"') {\n\t\t\t\t\t\ti++;\n\t\t\t\t\tch = chNext;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t} else {\n                    styler.ColourTo(i, state);\n\t\t\t\t\tprevState = state;\n\t\t\t\t\tstate = SCE_MSSQL_DEFAULT_PREF_DATATYPE;\n\t\t\t\t\t//i++;\n                }\n                }\n\t\t} else if (state == SCE_MSSQL_COLUMN_NAME_2) {\n\t\t\tif (ch == ']') {\n                styler.ColourTo(i, state);\n\t\t\t\tprevState = state;\n                state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;\n                //i++;\n\t\t\t}\n\t\t}\n\n\t\tif (atEOL)\n\t\t\tstyler.SetLineState(lineCurrent++, (state == SCE_MSSQL_COMMENT) ? nesting : 0);\n\n\t\tchPrev = ch;\n\t}\n\tstyler.ColourTo(lengthDoc - 1, state);\n}\n\nstatic void FoldMSSQLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tbool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);\n    char s[10] = \"\";\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styler.StyleAt(i);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n        // Comment folding\n\t\tif (foldComment) {\n\t\t\tif (!inComment && (style == SCE_MSSQL_COMMENT))\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (inComment && (style != SCE_MSSQL_COMMENT))\n\t\t\t\tlevelCurrent--;\n\t\t\tinComment = (style == SCE_MSSQL_COMMENT);\n\t\t}\n        if (style == SCE_MSSQL_STATEMENT) {\n            // Folding between begin or case and end\n            if (ch == 'b' || ch == 'B' || ch == 'c' || ch == 'C' || ch == 'e' || ch == 'E') {\n                for (Sci_PositionU j = 0; j < 5; j++) {\n\t\t\t\t\tif (!iswordchar(styler[i + j])) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ts[j] = static_cast<char>(tolower(styler[i + j]));\n\t\t\t\t\ts[j + 1] = '\\0';\n                }\n\t\t\t\tif ((strcmp(s, \"begin\") == 0) || (strcmp(s, \"case\") == 0)) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t}\n\t\t\t\tif (strcmp(s, \"end\") == 0) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n            }\n        }\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const sqlWordListDesc[] = {\n\t\"Statements\",\n    \"Data Types\",\n    \"System tables\",\n    \"Global variables\",\n    \"Functions\",\n    \"System Stored Procedures\",\n    \"Operators\",\n\t0,\n};\n\nextern const LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, \"mssql\", FoldMSSQLDoc, sqlWordListDesc);\n"
  },
  {
    "path": "lexers/LexMagik.cxx",
    "content": "// Scintilla source code edit control\n/**\n * @file LexMagik.cxx\n * Lexer for GE(r) Smallworld(tm) MagikSF\n */\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n/**\n * Is it a core character (C isalpha(), exclamation and question mark)\n *\n * \\param  ch The character\n * \\return True if ch is a character, False otherwise\n */\nstatic inline bool IsAlphaCore(int ch) {\n    return (isalpha(ch) || ch == '!' || ch == '?');\n}\n\n/**\n * Is it a character (IsAlphaCore() and underscore)\n *\n * \\param  ch The character\n * \\return True if ch is a character, False otherwise\n */\nstatic inline bool IsAlpha(int ch) {\n    return (IsAlphaCore(ch) || ch == '_');\n}\n\n/**\n * Is it a symbolic character (IsAlpha() and colon)\n *\n * \\param  ch The character\n * \\return True if ch is a character, False otherwise\n */\nstatic inline bool IsAlphaSym(int ch) {\n    return (IsAlpha(ch) || ch == ':');\n}\n\n/**\n * Is it a numerical character (IsAlpha() and 0 - 9)\n *\n * \\param  ch The character\n * \\return True if ch is a character, False otherwise\n */\nstatic inline bool IsAlNum(int ch) {\n    return ((ch >= '0' && ch <= '9') || IsAlpha(ch));\n}\n\n/**\n * Is it a symbolic numerical character (IsAlNum() and colon)\n *\n * \\param  ch The character\n * \\return True if ch is a character, False otherwise\n */\nstatic inline bool IsAlNumSym(int ch) {\n    return (IsAlNum(ch) || ch == ':');\n}\n\n/**\n * The lexer function\n *\n * \\param  startPos Where to start scanning\n * \\param  length Where to scan to\n * \\param  initStyle The style at the initial point, not used in this folder\n * \\param  keywordlists The keywordslists, currently, number 5 is used\n * \\param  styler The styler\n */\nstatic void ColouriseMagikDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                           WordList *keywordlists[], Accessor &styler) {\n    styler.StartAt(startPos);\n\n    WordList &keywords = *keywordlists[0];\n    WordList &pragmatics = *keywordlists[1];\n    WordList &containers = *keywordlists[2];\n    WordList &flow = *keywordlists[3];\n    WordList &characters = *keywordlists[4];\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\n\tfor (; sc.More(); sc.Forward()) {\n\n    repeat:\n\n        if(sc.ch == '#') {\n            if (sc.chNext == '#') sc.SetState(SCE_MAGIK_HYPER_COMMENT);\n            else sc.SetState(SCE_MAGIK_COMMENT);\n            for(; sc.More() && !(sc.atLineEnd); sc.Forward());\n            sc.SetState(SCE_MAGIK_DEFAULT);\n            goto repeat;\n        }\n\n        if(sc.ch == '\"') {\n            sc.SetState(SCE_MAGIK_STRING);\n\n            if(sc.More())\n            {\n                sc.Forward();\n                for(; sc.More() && sc.ch != '\"'; sc.Forward());\n            }\n\n            sc.ForwardSetState(SCE_MAGIK_DEFAULT);\n            goto repeat;\n        }\n\n\t    // The default state\n\t    if(sc.state == SCE_MAGIK_DEFAULT) {\n\n\t        // A certain keyword has been detected\n\t        if (sc.ch == '_' && (\n                    sc.currentPos == 0 || !IsAlNum(sc.chPrev))) {\n\t            char keyword[50];\n\t            memset(keyword, '\\0', 50);\n\n\t            for(\n                    int scanPosition = 0;\n                    scanPosition < 50;\n                    scanPosition++) {\n\t                char keywordChar = static_cast<char>(\n                        tolower(styler.SafeGetCharAt(\n                            scanPosition +\n                                static_cast<Sci_Position>(sc.currentPos+1), ' ')));\n                    if(IsAlpha(keywordChar)) {\n                        keyword[scanPosition] = keywordChar;\n                    } else {\n                        break;\n                    }\n\t            }\n\n                // It is a pragma\n\t            if(pragmatics.InList(keyword)) {\n\t                sc.SetState(SCE_MAGIK_PRAGMA);\n\t            }\n\n\t            // it is a normal keyword like _local, _self, etc.\n\t            else if(keywords.InList(keyword)) {\n\t                sc.SetState(SCE_MAGIK_KEYWORD);\n\t            }\n\n                // It is a container keyword, such as _method, _proc, etc.\n\t            else if(containers.InList(keyword)) {\n\t                sc.SetState(SCE_MAGIK_CONTAINER);\n\t            }\n\n\t            // It is a flow keyword, such as _for, _if, _try, etc.\n\t            else if(flow.InList(keyword)) {\n\t                sc.SetState(SCE_MAGIK_FLOW);\n\t            }\n\n\t            // Interpret as unknown keyword\n\t            else {\n\t                sc.SetState(SCE_MAGIK_UNKNOWN_KEYWORD);\n\t            }\n\t        }\n\n            // Symbolic expression\n\t        else if(sc.ch == ':' && !IsAlNum(sc.chPrev)) {\n\t            sc.SetState(SCE_MAGIK_SYMBOL);\n\t            bool firstTrip = true;\n\t            for(sc.Forward(); sc.More(); sc.Forward()) {\n\t                if(firstTrip && IsAlphaSym(sc.ch));\n\t                else if(!firstTrip && IsAlNumSym(sc.ch));\n\t                else if(sc.ch == '|') {\n\t                    for(sc.Forward();\n                            sc.More() && sc.ch != '|';\n                            sc.Forward());\n\t                }\n\t                else break;\n\n\t                firstTrip = false;\n\t            }\n\t            sc.SetState(SCE_MAGIK_DEFAULT);\n\t            goto repeat;\n\t        }\n\n            // Identifier (label) expression\n\t        else if(sc.ch == '@') {\n\t            sc.SetState(SCE_MAGIK_IDENTIFIER);\n\t            bool firstTrip = true;\n\t            for(sc.Forward(); sc.More(); sc.Forward()) {\n\t                if(firstTrip && IsAlphaCore(sc.ch)) {\n\t                    firstTrip = false;\n\t                }\n\t                else if(!firstTrip && IsAlpha(sc.ch));\n\t                else break;\n\t            }\n\t            sc.SetState(SCE_MAGIK_DEFAULT);\n\t            goto repeat;\n\t        }\n\n\t        // Start of a character\n            else if(sc.ch == '%') {\n                sc.SetState(SCE_MAGIK_CHARACTER);\n                sc.Forward();\n                char keyword[50];\n\t            memset(keyword, '\\0', 50);\n\n\t            for(\n                    int scanPosition = 0;\n                    scanPosition < 50;\n                    scanPosition++) {\n\t                char keywordChar = static_cast<char>(\n                        tolower(styler.SafeGetCharAt(\n                            scanPosition +\n                                static_cast<int>(sc.currentPos), ' ')));\n                    if(IsAlpha(keywordChar)) {\n                        keyword[scanPosition] = keywordChar;\n                    } else {\n                        break;\n                    }\n\t            }\n\n\t            if(characters.InList(keyword)) {\n\t                sc.Forward(static_cast<int>(strlen(keyword)));\n\t            } else {\n\t                sc.Forward();\n\t            }\n\n                sc.SetState(SCE_MAGIK_DEFAULT);\n                goto repeat;\n            }\n\n            // Operators\n\t        else if(\n                sc.ch == '>' ||\n                sc.ch == '<' ||\n                sc.ch == '.' ||\n                sc.ch == ',' ||\n                sc.ch == '+' ||\n                sc.ch == '-' ||\n                sc.ch == '/' ||\n                sc.ch == '*' ||\n                sc.ch == '~' ||\n                sc.ch == '$' ||\n                sc.ch == '=') {\n                sc.SetState(SCE_MAGIK_OPERATOR);\n            }\n\n            // Braces\n            else if(sc.ch == '(' || sc.ch == ')') {\n                sc.SetState(SCE_MAGIK_BRACE_BLOCK);\n            }\n\n            // Brackets\n            else if(sc.ch == '{' || sc.ch == '}') {\n                sc.SetState(SCE_MAGIK_BRACKET_BLOCK);\n            }\n\n            // Square Brackets\n            else if(sc.ch == '[' || sc.ch == ']') {\n                sc.SetState(SCE_MAGIK_SQBRACKET_BLOCK);\n            }\n\n\n\t    }\n\n\t    // It is an operator\n\t    else if(\n            sc.state == SCE_MAGIK_OPERATOR ||\n            sc.state == SCE_MAGIK_BRACE_BLOCK ||\n            sc.state == SCE_MAGIK_BRACKET_BLOCK ||\n            sc.state == SCE_MAGIK_SQBRACKET_BLOCK) {\n\t        sc.SetState(SCE_MAGIK_DEFAULT);\n\t        goto repeat;\n\t    }\n\n\t    // It is the pragma state\n\t    else if(sc.state == SCE_MAGIK_PRAGMA) {\n\t        if(!IsAlpha(sc.ch)) {\n\t            sc.SetState(SCE_MAGIK_DEFAULT);\n                goto repeat;\n\t        }\n\t    }\n\n\t    // It is the keyword state\n\t    else if(\n            sc.state == SCE_MAGIK_KEYWORD ||\n            sc.state == SCE_MAGIK_CONTAINER ||\n            sc.state == SCE_MAGIK_FLOW ||\n            sc.state == SCE_MAGIK_UNKNOWN_KEYWORD) {\n\t        if(!IsAlpha(sc.ch)) {\n\t            sc.SetState(SCE_MAGIK_DEFAULT);\n\t            goto repeat;\n\t        }\n\t    }\n\t}\n\n\tsc.Complete();\n}\n\n/**\n * The word list description\n */\nstatic const char * const magikWordListDesc[] = {\n    \"Accessors (local, global, self, super, thisthread)\",\n    \"Pragmatic (pragma, private)\",\n    \"Containers (method, block, proc)\",\n    \"Flow (if, then, elif, else)\",\n    \"Characters (space, tab, newline, return)\",\n    \"Fold Containers (method, proc, block, if, loop)\",\n    0};\n\n/**\n * This function detects keywords which are able to have a body. Note that it\n * uses the Fold Containers word description, not the containers description. It\n * only works when the style at that particular position is set on Containers\n * or Flow (number 3 or 4).\n *\n * \\param  keywordslist The list of keywords that are scanned, they should only\n *         contain the start keywords, not the end keywords\n * \\param  keyword The actual keyword\n * \\return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword\n *         0 otherwise\n */\nstatic inline int IsFoldingContainer(WordList &keywordslist, char * keyword) {\n    if(\n        strlen(keyword) > 3 &&\n        keyword[0] == 'e' && keyword[1] == 'n' && keyword[2] == 'd') {\n        if (keywordslist.InList(keyword + 3)) {\n            return -1;\n        }\n\n    } else {\n        if(keywordslist.InList(keyword)) {\n            return 1;\n        }\n    }\n\n    return 0;\n}\n\n/**\n * The folding function\n *\n * \\param  startPos Where to start scanning\n * \\param  length Where to scan to\n * \\param  keywordslists The keywordslists, currently, number 5 is used\n * \\param  styler The styler\n */\nstatic void FoldMagikDoc(Sci_PositionU startPos, Sci_Position length, int,\n    WordList *keywordslists[], Accessor &styler) {\n\n    bool compact = styler.GetPropertyInt(\"fold.compact\") != 0;\n\n    WordList &foldingElements = *keywordslists[5];\n    Sci_Position endPos = startPos + length;\n    Sci_Position line = styler.GetLine(startPos);\n    int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;\n    int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;\n\n    for(\n        Sci_Position currentPos = startPos;\n        currentPos < endPos;\n        currentPos++) {\n            char currentState = styler.StyleAt(currentPos);\n            char c = styler.SafeGetCharAt(currentPos, ' ');\n            Sci_Position prevLine = styler.GetLine(currentPos - 1);\n            line = styler.GetLine(currentPos);\n\n            // Default situation\n            if(prevLine < line) {\n                styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG);\n                flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;\n            }\n\n            if(\n                (\n                    currentState == SCE_MAGIK_CONTAINER ||\n                    currentState == SCE_MAGIK_FLOW\n                ) &&\n                c == '_') {\n\n                char keyword[50];\n                memset(keyword, '\\0', 50);\n\n                for(\n                    int scanPosition = 0;\n                    scanPosition < 50;\n                    scanPosition++) {\n                    char keywordChar = static_cast<char>(\n                        tolower(styler.SafeGetCharAt(\n                            scanPosition +\n                                currentPos + 1, ' ')));\n                    if(IsAlpha(keywordChar)) {\n                        keyword[scanPosition] = keywordChar;\n                    } else {\n                        break;\n                    }\n                }\n\n                if(IsFoldingContainer(foldingElements, keyword) > 0) {\n                    styler.SetLevel(\n                        line,\n                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);\n                    level++;\n                } else if(IsFoldingContainer(foldingElements, keyword) < 0) {\n                    styler.SetLevel(line, styler.LevelAt(line));\n                    level--;\n                }\n            }\n\n            if(\n                compact && (\n                    currentState == SCE_MAGIK_BRACE_BLOCK ||\n                    currentState == SCE_MAGIK_BRACKET_BLOCK ||\n                    currentState == SCE_MAGIK_SQBRACKET_BLOCK)) {\n                if(c == '{' || c == '[' || c == '(') {\n                    styler.SetLevel(\n                        line,\n                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);\n                    level++;\n                } else if(c == '}' || c == ']' || c == ')') {\n                    styler.SetLevel(line, styler.LevelAt(line));\n                    level--;\n                }\n            }\n        }\n\n}\n\n/**\n * Injecting the module\n */\nextern const LexerModule lmMagikSF(\n    SCLEX_MAGIK, ColouriseMagikDoc, \"magiksf\", FoldMagikDoc, magikWordListDesc);\n\n"
  },
  {
    "path": "lexers/LexMake.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexMake.cxx\n ** Lexer for make files.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n#include <map>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\n// Options used for LexerMakeFile\nstruct OptionsMake {\n};\n\nconst char *const makeWordListDescription[] = {\n\t\"Directives\",\n\tnullptr\n};\n\nstruct OptionSetMake : public OptionSet<OptionsMake> {\n\tOptionSetMake() {\n\t\tDefineWordListSets(makeWordListDescription);\n\t}\n};\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer makefile SCLEX_MAKEFILE SCE_MAKE_\n\t0, \"SCE_MAKE_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_MAKE_COMMENT\", \"comment\", \"Comment\",\n\t2, \"SCE_MAKE_PREPROCESSOR\", \"preprocessor\", \"Preprocessor\",\n\t3, \"SCE_MAKE_IDENTIFIER\", \"identifier\", \"Identifiers\",\n\t4, \"SCE_MAKE_OPERATOR\", \"operator\", \"Operator\",\n\t5, \"SCE_MAKE_TARGET\", \"identifier\", \"Identifiers\",\n\t6, \"\", \"unused\", \"\",\n\t7, \"\", \"unused\", \"\",\n\t8, \"\", \"unused\", \"\",\n\t9, \"SCE_MAKE_IDEOL\", \"error identifier\", \"Incomplete identifier reference\",\n};\n\nbool AtEOL(Accessor &styler, Sci_PositionU i) {\n\treturn (styler[i] == '\\n') ||\n\t\t((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n'));\n}\n\nclass LexerMakeFile : public DefaultLexer {\n\tWordList directives;\n\tOptionsMake options;\n\tOptionSetMake osMake;\npublic:\n\tLexerMakeFile() :\n\t\tDefaultLexer(\"makefile\", SCLEX_MAKEFILE, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osMake.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osMake.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osMake.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osMake.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osMake.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n\tvoid ColouriseMakeLine(std::string_view lineBuffer,\n\t\tSci_PositionU startLine, Sci_PositionU endPos, Accessor &styler);\n\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tstatic ILexer5 *LexerFactoryMakeFile() {\n\t\treturn new LexerMakeFile();\n\t}\n};\n\nSci_Position SCI_METHOD LexerMakeFile::PropertySet(const char *key, const char *val) {\n\tif (osMake.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerMakeFile::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &directives;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN && wordListN->Set(wl)) {\n\t\tfirstModification = 0;\n\t}\n\treturn firstModification;\n}\n\nvoid LexerMakeFile::ColouriseMakeLine(\n\tconst std::string_view lineBuffer,\n\tSci_PositionU startLine,\n\tSci_PositionU endPos,\n\tAccessor &styler) {\n\n\tconst Sci_PositionU lengthLine = lineBuffer.length();\n\tSci_PositionU i = 0;\n\tSci_Position lastNonSpace = -1;\n\tunsigned int state = SCE_MAKE_DEFAULT;\n\tbool bSpecial = false;\n\n\t// check for a tab character in column 0 indicating a command\n\tconst bool bCommand = StartsWith(lineBuffer, '\\t');\n\n\t// Skip initial spaces\n\twhile ((i < lengthLine) && isspacechar(lineBuffer[i])) {\n\t\ti++;\n\t}\n\tif (i < lengthLine) {\n\t\tif (lineBuffer[i] == '#') {\t// Comment\n\t\t\tstyler.ColourTo(endPos, SCE_MAKE_COMMENT);\n\t\t\treturn;\n\t\t}\n\t\tif (lineBuffer[i] == '!') {\t// Special directive\n\t\t\tstyler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);\n\t\t\treturn;\n\t\t}\n\t\tif (IsUpperOrLowerCase(lineBuffer[i]) &&\n\t\t\t(lineBuffer.find_first_of(\":=\") == std::string::npos)) {\n\t\t\tconst std::string_view firstWord(lineBuffer.substr(i));\n\t\t\tsize_t endWord = 0;\n\t\t\twhile ((endWord < firstWord.length()) && IsUpperOrLowerCase(firstWord[endWord])) {\n\t\t\t\tendWord++;\n\t\t\t}\n\t\t\tif (directives.InList(firstWord.substr(0, endWord))) {\n\t\t\t\tstyler.ColourTo(startLine + i + endWord - 1, SCE_MAKE_PREPROCESSOR);\n\t\t\t\ti += endWord;\n\t\t\t}\n\t\t}\n\t}\n\tint varCount = 0;\n\tchar previous = 0;\n\twhile (i < lengthLine) {\n\t\tif (lineBuffer[i] == '#' && !bCommand && (varCount == 0) && (previous != '\\\\')) {\n\t\t\tstyler.ColourTo(startLine + i - 1, state);\n\t\t\tstyler.ColourTo(endPos, SCE_MAKE_COMMENT);\n\t\t\treturn;\n\t\t} else if (lineBuffer.substr(i, 2) == \"$(\") {\n\t\t\tstyler.ColourTo(startLine + i - 1, state);\n\t\t\tstate = SCE_MAKE_IDENTIFIER;\n\t\t\tvarCount++;\n\t\t} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {\n\t\t\tif (--varCount == 0) {\n\t\t\t\tstyler.ColourTo(startLine + i, state);\n\t\t\t\tstate = SCE_MAKE_DEFAULT;\n\t\t\t}\n\t\t}\n\n\t\t// skip identifier and target styling if this is a command line\n\t\tif (!bSpecial && !bCommand && AnyOf(lineBuffer[i], ':', '=')) {\n\t\t\t// Three cases:\n\t\t\t// : target\n\t\t\t// := immediate assignment\n\t\t\t// = lazy assignment\n\t\t\tconst bool colon = lineBuffer[i] == ':';\n\t\t\tconst bool immediate = colon && ((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=');\n\t\t\tconst Sci_PositionU lengthOperator = immediate ? 1 : 0;\n\t\t\tif (lastNonSpace >= 0) {\n\t\t\t\tconst int attribute = (colon && !immediate) ? SCE_MAKE_TARGET : SCE_MAKE_IDENTIFIER;\n\t\t\t\tstyler.ColourTo(startLine + lastNonSpace, attribute);\n\t\t\t}\n\t\t\tstyler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);\n\t\t\tstyler.ColourTo(startLine + i + lengthOperator, SCE_MAKE_OPERATOR);\n\t\t\tbSpecial = true;\t// Only react to the first ':' or '=' of the line\n\t\t\tstate = SCE_MAKE_DEFAULT;\n\t\t}\n\t\tif (!isspacechar(lineBuffer[i])) {\n\t\t\tlastNonSpace = i;\n\t\t}\n\t\tprevious = lineBuffer[i];\n\t\ti++;\n\t}\n\tif (state == SCE_MAKE_IDENTIFIER) {\n\t\tstyler.ColourTo(endPos, SCE_MAKE_IDEOL);\t// Error, variable reference not ended\n\t} else {\n\t\tstyler.ColourTo(endPos, SCE_MAKE_DEFAULT);\n\t}\n}\n\nvoid LexerMakeFile::Lex(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\tstd::string lineBuffer;\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tSci_PositionU startLine = startPos;\n\tfor (Sci_PositionU i = startPos; i < startPos + length; i++) {\n\t\tlineBuffer.push_back(styler[i]);\n\t\tif (AtEOL(styler, i)) {\n\t\t\t// End of line (or of line buffer) met, colourise it\n\t\t\tColouriseMakeLine(lineBuffer, startLine, i, styler);\n\t\t\tlineBuffer.clear();\n\t\t\tstartLine = i + 1;\n\t\t}\n\t}\n\tif (!lineBuffer.empty()) {\t// Last line does not have ending characters\n\t\tColouriseMakeLine(lineBuffer, startLine, startPos + length - 1, styler);\n\t}\n\tstyler.Flush();\n}\n\n}\n\nextern const LexerModule lmMake(SCLEX_MAKEFILE, LexerMakeFile::LexerFactoryMakeFile, \"makefile\", makeWordListDescription);\n"
  },
  {
    "path": "lexers/LexMarkdown.cxx",
    "content": "/******************************************************************\n *  LexMarkdown.cxx\n *\n *  A simple Markdown lexer for scintilla.\n *\n *  Includes highlighting for some extra features from the\n *  Pandoc implementation; strikeout, using '#.' as a default\n *  ordered list item marker, and delimited code blocks.\n *\n *  Limitations:\n *\n *  Standard indented code blocks are not highlighted at all,\n *  as it would conflict with other indentation schemes. Use\n *  delimited code blocks for blanket highlighting of an\n *  entire code block.  Embedded HTML is not highlighted either.\n *  Blanket HTML highlighting has issues, because some Markdown\n *  implementations allow Markdown markup inside of the HTML. Also,\n *  there is a following blank line issue that can't be ignored,\n *  explained in the next paragraph. Embedded HTML and code\n *  blocks would be better supported with language specific\n *  highlighting.\n *\n *  The highlighting aims to accurately reflect correct syntax,\n *  but a few restrictions are relaxed. Delimited code blocks are\n *  highlighted, even if the line following the code block is not blank.\n *  Requiring a blank line after a block, breaks the highlighting\n *  in certain cases, because of the way Scintilla ends up calling\n *  the lexer.\n *\n *  Written by Jon Strait - jstrait@moonloop.net\n *\n *  The License.txt file describes the conditions under which this\n *  software may be distributed.\n *\n *****************************************************************/\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\nconstexpr bool IsNewline(const int ch) {\n    // sc.GetRelative(i) returns '\\0' if out of range\n    return (ch == '\\n' || ch == '\\r' || ch == '\\0');\n}\n\n// True if can follow ch down to the end with possibly trailing whitespace\n// Does not set the state SCE_MARKDOWN_LINE_BEGIN as to allow further processing\nbool FollowToLineEnd(const int ch, const int state, const Sci_PositionU endPos, StyleContext &sc) {\n    Sci_Position i = 0;\n    while (sc.GetRelative(++i) == ch)\n        ;\n    // Skip over whitespace\n    while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)\n        ++i;\n    if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {\n        sc.SetState(state);\n        sc.Forward(i);\n        return true;\n    }\n    return false;\n}\n\n// Set the state on text section from current to length characters,\n// then set the rest until the newline to default, except for any characters matching token\nvoid SetStateAndZoom(const int state, const Sci_Position length, const int token, StyleContext &sc) {\n    sc.SetState(state);\n    sc.Forward(length);\n    sc.SetState(SCE_MARKDOWN_DEFAULT);\n    sc.Forward();\n    bool started = false;\n    while (sc.More() && !IsNewline(sc.ch)) {\n        if (sc.ch == token && !started) {\n            sc.SetState(state);\n            started = true;\n        }\n        else if (sc.ch != token) {\n            sc.SetState(SCE_MARKDOWN_DEFAULT);\n            started = false;\n        }\n        sc.Forward();\n    }\n    sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n}\n\n// Does the previous line have more than spaces and tabs?\nbool HasPrevLineContent(StyleContext &sc) {\n    Sci_Position i = 0;\n    // Go back to the previous newline\n    while ((--i + (Sci_Position)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i)))\n        ;\n    while ((--i + (Sci_Position)sc.currentPos) >= 0) {\n        const int ch = sc.GetRelative(i);\n        if (ch == '\\n')\n            break;\n        if (!((ch == '\\r' || IsASpaceOrTab(ch))))\n            return true;\n    }\n    return false;\n}\n\nbool AtTermStart(const StyleContext &sc) noexcept {\n    return sc.currentPos == 0 || sc.chPrev == 0 || isspacechar(sc.chPrev);\n}\n\nbool IsCompleteStyleRegion(StyleContext &sc, const char *token) {\n    bool found = false;\n    const size_t start = strlen(token);\n    Sci_Position i = static_cast<Sci_Position>(start);\n    while (!IsNewline(sc.GetRelative(i))) {\n        // make sure an empty pair of single-char tokens doesn't match\n        // with a longer token: {*}{*} != {**}\n        if (sc.GetRelative(i) == *token && sc.GetRelative(i - 1) != *token) {\n            found = start > 1U ? sc.GetRelative(i + 1) == token[1] : true;\n            break;\n        }\n        i++;\n    }\n    return AtTermStart(sc) && found;\n}\n\nbool IsValidHrule(const Sci_PositionU endPos, StyleContext &sc) {\n    int count = 1;\n    Sci_Position i = 0;\n    for (;;) {\n        ++i;\n        const int c = sc.GetRelative(i);\n        if (c == sc.ch)\n            ++count;\n        // hit a terminating character\n        else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {\n            // Are we a valid HRULE\n            if ((IsNewline(c) || sc.currentPos + i == endPos) &&\n                    count >= 3 && !HasPrevLineContent(sc)) {\n                sc.SetState(SCE_MARKDOWN_HRULE);\n                sc.Forward(i);\n                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n                return true;\n            }\n            sc.SetState(SCE_MARKDOWN_DEFAULT);\n            return false;\n        }\n    }\n}\n\nvoid ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                                WordList **, Accessor &styler) {\n    const Sci_PositionU endPos = startPos + length;\n    int precharCount = 0;\n    bool isLinkNameDetecting = false;\n    // Don't advance on a new loop iteration and retry at the same position.\n    // Useful in the corner case of having to start at the beginning file position\n    // in the default state.\n    bool freezeCursor = false;\n\n    // property lexer.markdown.header.eolfill\n    //  Set to 1 to highlight all ATX header text.\n    const bool headerEOLFill = styler.GetPropertyInt(\"lexer.markdown.header.eolfill\", 0) == 1;\n\n    StyleContext sc(startPos, static_cast<Sci_PositionU>(length), initStyle, styler);\n\n    while (sc.More()) {\n        // Skip past escaped characters\n        if (sc.ch == '\\\\') {\n            sc.Forward();\n            continue;\n        }\n\n        // A blockquotes resets the line semantics\n        if (sc.state == SCE_MARKDOWN_BLOCKQUOTE)\n            sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n\n        // Conditional state-based actions\n        if (sc.state == SCE_MARKDOWN_CODE2) {\n            if (sc.Match(\"``\")) {\n                const int closingSpan = (sc.GetRelative(2) == '`') ? 3 : 2;\n                sc.Forward(closingSpan);\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n        }\n        else if (sc.state == SCE_MARKDOWN_CODE) {\n            if (sc.ch == '`' && sc.chPrev != ' ')\n                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);\n        }\n        /* De-activated because it gets in the way of other valid indentation\n         * schemes, for example multiple paragraphs inside a list item.\n        // Code block\n        else if (sc.state == SCE_MARKDOWN_CODEBK) {\n            bool d = true;\n            if (IsNewline(sc.ch)) {\n                if (sc.chNext != '\\t') {\n                    for (int c = 1; c < 5; ++c) {\n                        if (sc.GetRelative(c) != ' ')\n                            d = false;\n                    }\n                }\n            }\n            else if (sc.atLineStart) {\n                if (sc.ch != '\\t' ) {\n                    for (int i = 0; i < 4; ++i) {\n                        if (sc.GetRelative(i) != ' ')\n                            d = false;\n                    }\n                }\n            }\n            if (!d)\n                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n        }\n        */\n        // Strong\n        else if (sc.state == SCE_MARKDOWN_STRONG1) {\n            if ((sc.Match(\"**\") && sc.chPrev != ' ') || IsNewline(sc.GetRelative(2))) {\n                sc.Forward(2);\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n        }\n        else if (sc.state == SCE_MARKDOWN_STRONG2) {\n            if ((sc.Match(\"__\") && sc.chPrev != ' ') || IsNewline(sc.GetRelative(2))) {\n                sc.Forward(2);\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n        }\n        // Emphasis\n        else if (sc.state == SCE_MARKDOWN_EM1) {\n            if ((sc.ch == '*' && sc.chPrev != ' ') || IsNewline(sc.chNext))\n                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);\n        }\n        else if (sc.state == SCE_MARKDOWN_EM2) {\n            if ((sc.ch == '_' && sc.chPrev != ' ') || IsNewline(sc.chNext))\n                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);\n        }\n        else if (sc.state == SCE_MARKDOWN_CODEBK) {\n            if (sc.atLineStart && sc.Match(\"~~~\")) {\n                Sci_Position i = 1;\n                while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)\n                    i++;\n                sc.Forward(i);\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n        }\n        else if (sc.state == SCE_MARKDOWN_STRIKEOUT) {\n            if ((sc.Match(\"~~\") && sc.chPrev != ' ') || IsNewline(sc.GetRelative(2))) {\n                sc.Forward(2);\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n        }\n        else if (sc.state == SCE_MARKDOWN_LINE_BEGIN) {\n            // Header\n            if (sc.Match(\"######\")) {\n                if (headerEOLFill)\n                    sc.SetState(SCE_MARKDOWN_HEADER6);\n                else\n                    SetStateAndZoom(SCE_MARKDOWN_HEADER6, 6, '#', sc);\n            }\n            else if (sc.Match(\"#####\")) {\n                if (headerEOLFill)\n                    sc.SetState(SCE_MARKDOWN_HEADER5);\n                else\n                    SetStateAndZoom(SCE_MARKDOWN_HEADER5, 5, '#', sc);\n            }\n            else if (sc.Match(\"####\")) {\n                if (headerEOLFill)\n                    sc.SetState(SCE_MARKDOWN_HEADER4);\n                else\n                    SetStateAndZoom(SCE_MARKDOWN_HEADER4, 4, '#', sc);\n            }\n            else if (sc.Match(\"###\")) {\n                if (headerEOLFill)\n                    sc.SetState(SCE_MARKDOWN_HEADER3);\n                else\n                    SetStateAndZoom(SCE_MARKDOWN_HEADER3, 3, '#', sc);\n            }\n            else if (sc.Match(\"##\")) {\n                if (headerEOLFill)\n                    sc.SetState(SCE_MARKDOWN_HEADER2);\n                else\n                    SetStateAndZoom(SCE_MARKDOWN_HEADER2, 2, '#', sc);\n            }\n            else if (sc.Match(\"#\")) {\n                // Catch the special case of an unordered list\n                if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {\n                    precharCount = 0;\n                    sc.SetState(SCE_MARKDOWN_PRECHAR);\n                }\n                else if (headerEOLFill) {\n                    sc.SetState(SCE_MARKDOWN_HEADER1);\n                }\n                else\n                    SetStateAndZoom(SCE_MARKDOWN_HEADER1, 1, '#', sc);\n            }\n            // Code block\n            else if (sc.Match(\"~~~\")) {\n                if (!HasPrevLineContent(sc))\n                    sc.SetState(SCE_MARKDOWN_CODEBK);\n                else\n                    sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n            else if (sc.ch == '=') {\n                if (HasPrevLineContent(sc) && FollowToLineEnd('=', SCE_MARKDOWN_HEADER1, endPos, sc)) {\n                    if (!headerEOLFill)\n                        sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n                }\n                else\n                    sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n            else if (sc.ch == '-') {\n                if (HasPrevLineContent(sc) && FollowToLineEnd('-', SCE_MARKDOWN_HEADER2, endPos, sc)) {\n                    if (!headerEOLFill)\n                        sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n                }\n                else {\n                    precharCount = 0;\n                    sc.SetState(SCE_MARKDOWN_PRECHAR);\n                }\n            }\n            else if (IsNewline(sc.ch))\n                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n            else {\n                precharCount = 0;\n                sc.SetState(SCE_MARKDOWN_PRECHAR);\n            }\n        }\n\n        // The header lasts until the newline\n        else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 ||\n                 sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 ||\n                 sc.state == SCE_MARKDOWN_HEADER5 || sc.state == SCE_MARKDOWN_HEADER6) {\n            if (headerEOLFill) {\n                if (sc.atLineStart) {\n                    sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n                    freezeCursor = true;\n                }\n            }\n            else if (IsNewline(sc.ch))\n                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n        }\n\n        // New state only within the initial whitespace\n        if (sc.state == SCE_MARKDOWN_PRECHAR) {\n            // Blockquote\n            if (sc.ch == '>' && precharCount < 5)\n                sc.SetState(SCE_MARKDOWN_BLOCKQUOTE);\n            /*\n            // Begin of code block\n            else if (!HasPrevLineContent(sc) && (sc.chPrev == '\\t' || precharCount >= 4))\n                sc.SetState(SCE_MARKDOWN_CODEBK);\n            */\n            // HRule - Total of three or more hyphens, asterisks, or underscores\n            // on a line by themselves\n            else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc))\n                ;\n            // Unordered list\n            else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '+') && IsASpaceOrTab(sc.chNext)) {\n                sc.SetState(SCE_MARKDOWN_ULIST_ITEM);\n                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);\n            }\n            // Ordered list\n            else if (IsADigit(sc.ch)) {\n                int digitCount = 0;\n                while (IsADigit(sc.GetRelative(++digitCount)))\n                    ;\n                if (sc.GetRelative(digitCount) == '.' &&\n                        IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {\n                    sc.SetState(SCE_MARKDOWN_OLIST_ITEM);\n                    sc.Forward(digitCount + 1);\n                    sc.SetState(SCE_MARKDOWN_DEFAULT);\n                } else {\n                    // a textual number at the margin should be plain text\n                    sc.SetState(SCE_MARKDOWN_DEFAULT);\n                }\n            }\n            // Alternate Ordered list\n            else if (sc.ch == '#' && sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {\n                sc.SetState(SCE_MARKDOWN_OLIST_ITEM);\n                sc.Forward(2);\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n            else if (sc.ch != ' ' || precharCount > 2)\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n            else\n                ++precharCount;\n        }\n\n        // Any link\n        if (sc.state == SCE_MARKDOWN_LINK) {\n            if (sc.Match(\"](\") && sc.GetRelative(-1) != '\\\\') {\n                sc.Forward(2);\n                isLinkNameDetecting = true;\n            }\n            else if (sc.Match(\"]:\") && sc.GetRelative(-1) != '\\\\') {\n                sc.Forward(2);\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n            else if (!isLinkNameDetecting && sc.ch == ']' && sc.GetRelative(-1) != '\\\\') {\n                sc.Forward();\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n            }\n            else if (isLinkNameDetecting && sc.ch == ')' && sc.GetRelative(-1) != '\\\\') {\n                sc.Forward();\n                sc.SetState(SCE_MARKDOWN_DEFAULT);\n                isLinkNameDetecting = false;\n            }\n        }\n\n        // New state anywhere in doc\n        if (sc.state == SCE_MARKDOWN_DEFAULT) {\n            if (sc.atLineStart && sc.ch == '#') {\n                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n                freezeCursor = true;\n            }\n            // Links and Images\n            if (sc.Match(\"![\")) {\n                sc.SetState(SCE_MARKDOWN_LINK);\n                sc.Forward(1);\n            }\n            else if (sc.ch == '[' && sc.GetRelative(-1) != '\\\\') {\n                sc.SetState(SCE_MARKDOWN_LINK);\n            }\n            // Code - also a special case for alternate inside spacing\n            else if (sc.Match(\"``\") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) {\n                const int openingSpan = (sc.GetRelative(2) == '`') ? 2 : 1;\n                sc.SetState(SCE_MARKDOWN_CODE2);\n                sc.Forward(openingSpan);\n            }\n            else if (sc.ch == '`' && sc.chNext != ' ' && IsCompleteStyleRegion(sc, \"`\")) {\n                sc.SetState(SCE_MARKDOWN_CODE);\n            }\n            // Strong\n            else if (sc.Match(\"**\") && sc.GetRelative(2) != ' ' && IsCompleteStyleRegion(sc, \"**\")) {\n                sc.SetState(SCE_MARKDOWN_STRONG1);\n                sc.Forward();\n            }\n            else if (sc.Match(\"__\") && sc.GetRelative(2) != ' ' && IsCompleteStyleRegion(sc, \"__\")) {\n                sc.SetState(SCE_MARKDOWN_STRONG2);\n                sc.Forward();\n            }\n            // Emphasis\n            else if (sc.ch == '*' && sc.chNext != ' ' && IsCompleteStyleRegion(sc, \"*\")) {\n                sc.SetState(SCE_MARKDOWN_EM1);\n            }\n            else if (sc.ch == '_' && sc.chNext != ' ' && IsCompleteStyleRegion(sc, \"_\")) {\n                sc.SetState(SCE_MARKDOWN_EM2);\n            }\n            // Strikeout\n            else if (sc.Match(\"~~\") && !(sc.GetRelative(2) == '~' || sc.GetRelative(2) == ' ') &&\n                     IsCompleteStyleRegion(sc, \"~~\")) {\n                sc.SetState(SCE_MARKDOWN_STRIKEOUT);\n                sc.Forward();\n            }\n            // Beginning of line\n            else if (IsNewline(sc.ch)) {\n                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);\n            }\n        }\n        // Advance if not holding back the cursor for this iteration.\n        if (!freezeCursor)\n            sc.Forward();\n        freezeCursor = false;\n    }\n    sc.Complete();\n}\n\n}\n\nextern const LexerModule lmMarkdown(SCLEX_MARKDOWN, ColorizeMarkdownDoc, \"markdown\");\n"
  },
  {
    "path": "lexers/LexMatlab.cxx",
    "content": "// Scintilla source code edit control\n// Encoding: UTF-8\n/** @file LexMatlab.cxx\n ** Lexer for Matlab.\n ** Written by José Fonseca\n **\n ** Changes by Christoph Dalitz 2003/12/04:\n **   - added support for Octave\n **   - Strings can now be included both in single or double quotes\n **\n ** Changes by John Donoghue 2012/04/02\n **   - added block comment (and nested block comments)\n **   - added ... displayed as a comment\n **   - removed unused IsAWord functions\n **   - added some comments\n **\n ** Changes by John Donoghue 2014/08/01\n **   - fix allowed transpose ' after {} operator\n **\n ** Changes by John Donoghue 2016/11/15\n **   - update matlab code folding\n **\n ** Changes by John Donoghue 2017/01/18\n **   - update matlab block comment detection\n **\n ** Changes by Andrey Smolyakov 2022/04/15\n **   - add support for \"arguments\" block and class definition syntax\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic bool IsMatlabCommentChar(int c) {\n\treturn (c == '%') ;\n}\n\nstatic bool IsOctaveCommentChar(int c) {\n\treturn (c == '%' || c == '#') ;\n}\n\nstatic inline int LowerCase(int c) {\n\tif (c >= 'A' && c <= 'Z')\n\t\treturn 'a' + c - 'A';\n\treturn c;\n}\n\nstatic int CheckKeywordFoldPoint(char *str) {\n\tif (strcmp (\"if\", str) == 0 ||\n\t\tstrcmp (\"for\", str) == 0 ||\n\t\tstrcmp (\"switch\", str) == 0 ||\n\t\tstrcmp (\"while\", str) == 0 ||\n\t\tstrcmp (\"try\", str) == 0 ||\n\t\tstrcmp (\"do\", str) == 0 ||\n\t\tstrcmp (\"parfor\", str) == 0 ||\n\t\tstrcmp (\"classdef\", str) == 0 ||\n\t\tstrcmp (\"spmd\", str) == 0 ||\n\t\tstrcmp (\"arguments\", str) == 0 ||\n\t\tstrcmp (\"methods\", str) == 0 ||\n\t\tstrcmp (\"properties\", str) == 0 ||\n\t\tstrcmp (\"events\", str) == 0 ||\n\t\tstrcmp (\"function\", str) == 0)\n\t\treturn 1;\n\tif (strncmp(\"end\", str, 3) == 0 ||\n\t\tstrcmp(\"until\", str) == 0)\n\t\treturn -1;\n\treturn 0;\n}\n\nstatic bool IsSpaceToEOL(Sci_Position startPos, Accessor &styler) {\n\tSci_Position line = styler.GetLine(startPos);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = startPos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tif(!IsASpace(ch)) return false;\n\t}\n\treturn true;\n}\n\n#define MATLAB_STATE_FOLD_LVL_OFFSET     8\n#define MATLAB_STATE_FOLD_LVL_MASK       (0xFF00)\n#define MATLAB_STATE_FLAGS_OFFSET        16\n#define MATLAB_STATE_COMM_DEPTH_OFFSET   0\n#define MATLAB_STATE_COMM_DEPTH_MASK     (0xFF)\n#define MATLAB_STATE_EXPECTING_ARG_BLOCK (1 << MATLAB_STATE_FLAGS_OFFSET)\n#define MATLAB_STATE_IN_CLASS_SCOPE      (1 <<(MATLAB_STATE_FLAGS_OFFSET+1))\n#define MATLAB_STATE_IN_ARGUMENTS_SCOPE  (1 <<(MATLAB_STATE_FLAGS_OFFSET+2))\n\nstatic int ComposeLineState(int commentDepth,\n\t\t\t\t\t\t\tint foldingLevel,\n\t\t\t\t\t\t\tint expectingArgumentsBlock,\n\t\t\t\t\t\t\tint inClassScope,\n\t\t\t\t\t\t\tint inArgumentsScope) {\n\n\treturn  ((commentDepth << MATLAB_STATE_COMM_DEPTH_OFFSET)\n\t\t\t\t& MATLAB_STATE_COMM_DEPTH_MASK)\t\t\t\t\t|\n\t\t\t((foldingLevel << MATLAB_STATE_FOLD_LVL_OFFSET)\n\t\t\t\t& MATLAB_STATE_FOLD_LVL_MASK)\t\t\t\t\t|\n\t\t\t(expectingArgumentsBlock\n\t\t\t\t& MATLAB_STATE_EXPECTING_ARG_BLOCK)\t\t\t\t|\n\t\t\t(inClassScope\n\t\t\t\t& MATLAB_STATE_IN_CLASS_SCOPE)\t\t\t\t\t|\n\t\t\t(inArgumentsScope\n\t\t\t\t& MATLAB_STATE_IN_ARGUMENTS_SCOPE);\n}\n\nstatic void ColouriseMatlabOctaveDoc(\n            Sci_PositionU startPos, Sci_Position length, int initStyle,\n            WordList *keywordlists[], Accessor &styler,\n            bool (*IsCommentChar)(int),\n            bool ismatlab) {\n\n\tWordList &keywords = *keywordlists[0];\n\n\tstyler.StartAt(startPos);\n\n\t// boolean for when the ' is allowed to be transpose vs the start/end\n\t// of a string\n\tbool transpose = false;\n\n\t// count of brackets as boolean for when end could be an operator not a keyword\n\tint allow_end_op = 0;\n\n\t// approximate position of first non space character in a line\n\tint nonSpaceColumn = -1;\n\t// approximate column position of the current character in a line\n\tint column = 0;\n\n\t// This line contains a function declaration\n\tbool funcDeclarationLine = false;\n\t// We've just seen \"function\" keyword, so now we may expect the \"arguments\"\n\t// keyword opening the corresponding code block\n\tint expectingArgumentsBlock = 0;\n    // We saw \"arguments\" keyword, but not the closing \"end\"\n    int inArgumentsScope = 0;\n\t// Current line's folding level\n\tint foldingLevel = 0;\n\t// Current line in in class scope\n\tint inClassScope = 0;\n\n\t// use the line state of each line to store the block comment depth\n\tSci_Position curLine = styler.GetLine(startPos);\n\tint commentDepth = 0;\n\t// Restore the previous line's state, if there was such a line\n\tif (curLine > 0) {\n\t\tint prevState = styler.GetLineState(curLine-1);\n\t\tcommentDepth = (prevState & MATLAB_STATE_COMM_DEPTH_MASK)\n\t\t\t\t\t\t\t>> MATLAB_STATE_COMM_DEPTH_OFFSET;\n\t\tfoldingLevel = (prevState & MATLAB_STATE_FOLD_LVL_MASK)\n\t\t\t\t\t\t\t>> MATLAB_STATE_FOLD_LVL_OFFSET;\n\t\texpectingArgumentsBlock = prevState & MATLAB_STATE_EXPECTING_ARG_BLOCK;\n\t\tinClassScope = prevState & MATLAB_STATE_IN_CLASS_SCOPE;\n\t\tinArgumentsScope = prevState & MATLAB_STATE_IN_ARGUMENTS_SCOPE;\n\t}\n\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward(), column++) {\n\n\t\tif(sc.atLineStart) {\n\t\t\t// set the line state to the current commentDepth\n\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\tstyler.SetLineState(curLine, ComposeLineState(\n\t\t\t\tcommentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));\n\n\t\t\t// reset the column to 0, nonSpace to -1 (not set)\n\t\t\tcolumn = 0;\n\t\t\tnonSpaceColumn = -1;\n\n\t\t\t// Reset the flag\n\t\t\tfuncDeclarationLine = false;\n\t\t}\n\n\t\t// Semicolon ends function declaration\n\t\t// This condition is for one line functions support\n\t\tif (sc.chPrev == ';') {\n\t\t\tfuncDeclarationLine = false;\n\t\t}\n\n\t\t// Only comments allowed between the function declaration and the\n\t\t// arguments code block\n\t\tif (expectingArgumentsBlock && !(funcDeclarationLine || inArgumentsScope)) {\n\t\t\tif ((sc.state != SCE_MATLAB_KEYWORD) &&\n\t\t\t\t\t(sc.state != SCE_MATLAB_COMMENT) &&\n\t\t\t\t\t(sc.state != SCE_MATLAB_DEFAULT) &&\n\t\t\t\t\t!(sc.state == SCE_MATLAB_OPERATOR && sc.chPrev == ';')) {\n\t\t\t\texpectingArgumentsBlock = 0;\n\t\t\t\tstyler.SetLineState(curLine, ComposeLineState(\n\t\t\t\t\tcommentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));\n\t\t\t}\n\t\t}\n\n\t\t// We've just left the class scope\n\t\tif ((foldingLevel ==0) && inClassScope) {\n\t\t\tinClassScope = 0;\n\t\t}\n\n\t\t// save the column position of first non space character in a line\n\t\tif((nonSpaceColumn == -1) && (! IsASpace(sc.ch))) {\n\t\t\tnonSpaceColumn = column;\n\t\t}\n\n\t\t// check for end of states\n\t\tif (sc.state == SCE_MATLAB_OPERATOR) {\n\t\t\tif (sc.chPrev == '.') {\n\t\t\t\tif (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\\\' || sc.ch == '^') {\n\t\t\t\t\tsc.ForwardSetState(SCE_MATLAB_DEFAULT);\n\t\t\t\t\ttranspose = false;\n\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\tsc.ForwardSetState(SCE_MATLAB_DEFAULT);\n\t\t\t\t\ttranspose = true;\n\t\t\t\t} else if(sc.ch == '.' && sc.chNext == '.') {\n\t\t\t\t\t// we werent an operator, but a '...'\n\t\t\t\t\tsc.ChangeState(SCE_MATLAB_COMMENT);\n\t\t\t\t\ttranspose = false;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_MATLAB_DEFAULT);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsc.SetState(SCE_MATLAB_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_MATLAB_KEYWORD) {\n\t\t\tif (!isalnum(sc.ch) && sc.ch != '_') {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\tbool notKeyword = false;\n\t\t\t\ttranspose = false;\n\n\t\t\t\tif (keywords.InList(s)) {\n\n\t\t\t\t\texpectingArgumentsBlock = (funcDeclarationLine || inArgumentsScope) ? expectingArgumentsBlock : 0;\n\n\t\t\t\t\tif (strcmp (\"end\", s) == 0 && allow_end_op) {\n\t\t\t\t\t\tsc.ChangeState(SCE_MATLAB_NUMBER);\n\t\t\t\t\t\tnotKeyword = true;\n\t\t\t\t\t} else if (strcmp(\"end\", s) == 0 && !allow_end_op) {\n\t\t\t\t\t\tinArgumentsScope = 0;\n\t\t\t\t\t} else if (strcmp(\"function\", s) == 0) {\n\t\t\t\t\t\t// Need this flag to handle \"arguments\" block correctly\n\t\t\t\t\t\tfuncDeclarationLine = true;\n\t\t\t\t\t\texpectingArgumentsBlock = ismatlab ? MATLAB_STATE_EXPECTING_ARG_BLOCK : 0;\n\t\t\t\t\t} else if (strcmp(\"classdef\", s) == 0) {\n\t\t\t\t\t\t// Need this flag to process \"events\", \"methods\" and \"properties\" blocks\n\t\t\t\t\t\tinClassScope = MATLAB_STATE_IN_CLASS_SCOPE;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// \"arguments\" is a keyword here, despite not being in the keywords list\n\t\t\t\t\tif (expectingArgumentsBlock && !(funcDeclarationLine || inArgumentsScope) && (strcmp(\"arguments\", s) == 0)) {\n\t\t\t\t\t\t// We've entered an \"arguments\" block\n\t\t\t\t\t\tinArgumentsScope = MATLAB_STATE_IN_ARGUMENTS_SCOPE;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Found an identifier or a keyword after the function declaration\n\t\t\t\t\t\t// No need to wait for the arguments block anymore\n\t\t\t\t\t\texpectingArgumentsBlock = (funcDeclarationLine || inArgumentsScope) ? expectingArgumentsBlock : 0;\n\n\t\t\t\t\t\t// \"properties\", \"methods\" and \"events\" are not keywords if they're declared\n\t\t\t\t\t\t// inside some function in methods block\n\t\t\t\t\t\t// To avoid tracking possible nested functions scopes, lexer considers everything\n\t\t\t\t\t\t// beyond level 2 of folding to be in a scope of some function declared in the\n\t\t\t\t\t\t// methods block. It is ok for the valid syntax: classes can only be declared in\n\t\t\t\t\t\t// a separate file, function - only in methods block. However, in case of the invalid\n\t\t\t\t\t\t// syntax lexer may erroneously ignore a keyword.\n\t\t\t\t\t\tif (!((inClassScope) && (foldingLevel <= 2) && (\n\t\t\t\t\t\t\t\tstrcmp(\"properties\", s) == 0 ||\n\t\t\t\t\t\t\t\tstrcmp(\"methods\",    s) == 0 ||\n\t\t\t\t\t\t\t\tstrcmp(\"events\",     s) == 0 ))) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_MATLAB_IDENTIFIER);\n\t\t\t\t\t\t\ttranspose = true;\n\t\t\t\t\t\t\tnotKeyword = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsc.SetState(SCE_MATLAB_DEFAULT);\n\t\t\t\tif (!notKeyword) {\n\t\t\t\t\tfoldingLevel += CheckKeywordFoldPoint(s);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstyler.SetLineState(curLine, ComposeLineState(\n\t\t\t\tcommentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));\n\t\t} else if (sc.state == SCE_MATLAB_NUMBER) {\n\t\t\tif (!isdigit(sc.ch) && sc.ch != '.'\n\t\t\t        && !(sc.ch == 'e' || sc.ch == 'E')\n\t\t\t        && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))\n\t\t\t        && !(((sc.ch == 'x' || sc.ch == 'X') && sc.chPrev == '0') || (sc.ch >= 'a' && sc.ch <= 'f') || (sc.ch >= 'A' && sc.ch <= 'F'))\n\t\t\t        && !(sc.ch == 's' || sc.ch == 'S' || sc.ch == 'u' || sc.ch == 'U')\n\t\t\t        && !(sc.ch == 'i' || sc.ch == 'I' || sc.ch == 'j' || sc.ch == 'J')\n\t\t\t        && !(sc.ch == '_')) {\n\t\t\t\tsc.SetState(SCE_MATLAB_DEFAULT);\n\t\t\t\ttranspose = true;\n\t\t\t}\n\t\t} else if (sc.state == SCE_MATLAB_STRING) {\n\t\t\tif (sc.ch == '\\'') {\n\t\t\t\tif (sc.chNext == '\\'') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tsc.ForwardSetState(SCE_MATLAB_DEFAULT);\n\t\t\t\t}\n\t\t\t} else if (sc.MatchLineEnd()) {\n\t\t\t\tsc.SetState(SCE_MATLAB_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {\n\t\t\tif (sc.ch == '\\\\' && !ismatlab) {\n\t\t\t\tsc.Forward(); // skip escape sequence, new line and others after backlash\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_MATLAB_DEFAULT);\n\t\t\t} else if (sc.MatchLineEnd()) {\n\t\t\t\tsc.SetState(SCE_MATLAB_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_MATLAB_COMMAND) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_MATLAB_DEFAULT);\n\t\t\t\ttranspose = false;\n\t\t\t}\n\t\t} else if (sc.state == SCE_MATLAB_COMMENT) {\n\t\t\t// end or start of a nested a block comment?\n\t\t\tif( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column && IsSpaceToEOL(sc.currentPos+2, styler)) {\n\t\t\t\tif(commentDepth > 0) commentDepth --;\n\n\t\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\t\tstyler.SetLineState(curLine, ComposeLineState(\n\t\t\t\t\tcommentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));\n\t\t\t\tsc.Forward();\n\n\t\t\t\tif (commentDepth == 0) {\n\t\t\t\t\tsc.ForwardSetState(SCE_MATLAB_DEFAULT);\n\t\t\t\t\ttranspose = false;\n\t\t\t\t}\n\t\t\t} else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column && IsSpaceToEOL(sc.currentPos+2, styler)) {\n\t\t\t\tcommentDepth ++;\n\n\t\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\t\tstyler.SetLineState(curLine, ComposeLineState(\n\t\t\t\t\tcommentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));\n\t\t\t\tsc.Forward();\n\t\t\t\ttranspose = false;\n\n\t\t\t} else if(commentDepth == 0) {\n\t\t\t\t// single line comment\n\t\t\t\tif (sc.atLineEnd || sc.ch == '\\r' || sc.ch == '\\n') {\n\t\t\t\t\tsc.SetState(SCE_MATLAB_DEFAULT);\n\t\t\t\t\ttranspose = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// check start of a new state\n\t\tif (sc.state == SCE_MATLAB_DEFAULT) {\n\t\t\tif (IsCommentChar(sc.ch)) {\n\t\t\t\t// ncrement depth if we are a block comment\n\t\t\t\tif(sc.chNext == '{' && nonSpaceColumn == column) {\n\t\t\t\t\tif(IsSpaceToEOL(sc.currentPos+2, styler)) {\n\t\t\t\t\t\tcommentDepth ++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\t\tstyler.SetLineState(curLine, ComposeLineState(\n\t\t\t\t\tcommentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));\n\t\t\t\tsc.SetState(SCE_MATLAB_COMMENT);\n\t\t\t} else if (sc.ch == '!' && sc.chNext != '=' ) {\n\t\t\t\tif(ismatlab) {\n\t\t\t\t\tsc.SetState(SCE_MATLAB_COMMAND);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_MATLAB_OPERATOR);\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tif (transpose) {\n\t\t\t\t\tsc.SetState(SCE_MATLAB_OPERATOR);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_MATLAB_STRING);\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\"') {\n\t\t\t\tsc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);\n\t\t\t} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_MATLAB_NUMBER);\n\t\t\t} else if (isalpha(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_MATLAB_KEYWORD);\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\\\') {\n\t\t\t\tif (sc.ch == '(' || sc.ch == '[' || sc.ch == '{') {\n\t\t\t\t\tallow_end_op ++;\n\t\t\t\t} else if ((sc.ch == ')' || sc.ch == ']' || sc.ch == '}') && (allow_end_op > 0)) {\n\t\t\t\t\tallow_end_op --;\n\t\t\t\t}\n\n\t\t\t\tif (sc.ch == ')' || sc.ch == ']' || sc.ch == '}') {\n\t\t\t\t\ttranspose = true;\n\t\t\t\t} else {\n\t\t\t\t\ttranspose = false;\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_MATLAB_OPERATOR);\n\t\t\t} else {\n\t\t\t\ttranspose = false;\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void ColouriseMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                               WordList *keywordlists[], Accessor &styler) {\n\tColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar, true);\n}\n\nstatic void ColouriseOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                               WordList *keywordlists[], Accessor &styler) {\n\tColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar, false);\n}\n\nstatic void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                                WordList *[], Accessor &styler,\n                                bool (*IsComment)(int ch)) {\n\n\tif (styler.GetPropertyInt(\"fold\") == 0)\n\t\treturn;\n\n\tconst bool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tconst bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tchar word[100];\n\tint wordlen = 0;\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\t// a line that starts with a comment\n\t\tif (foldComment && style == SCE_MATLAB_COMMENT && IsComment(ch) && visibleChars == 0) {\n\t\t\t// start/end of block comment\n\t\t\tif (chNext == '{' && IsSpaceToEOL(i+2, styler))\n\t\t\t\tlevelNext ++;\n\t\t\tif (chNext == '}' && IsSpaceToEOL(i+2, styler))\n\t\t\t\tlevelNext --;\n\t\t}\n\t\t// keyword\n\t\tif(style == SCE_MATLAB_KEYWORD) {\n\t\t\tword[wordlen++] = static_cast<char>(LowerCase(ch));\n\t\t\tif (wordlen == 100) {  // prevent overflow\n\t\t\t\tword[0] = '\\0';\n\t\t\t\twordlen = 1;\n\t\t\t}\n\t\t\tif (styleNext !=  SCE_MATLAB_KEYWORD) {\n\t\t\t\tword[wordlen] = '\\0';\n\t\t\t\twordlen = 0;\n\n\t\t\t\tlevelNext += CheckKeywordFoldPoint(word);\n\t\t\t}\n\t\t}\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\t\tif (atEOL || (i == endPos-1)) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tif (atEOL && (i == static_cast<Sci_PositionU>(styler.Length() - 1))) {\n\t\t\t\t// There is an empty line at end of file so give it same level and empty\n\t\t\t\tstyler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);\n\t\t\t}\n\t\t\tvisibleChars = 0;\n\t\t}\n\t}\n}\n\nstatic void FoldMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                          WordList *keywordlists[], Accessor &styler) {\n\tFoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);\n}\n\nstatic void FoldOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                          WordList *keywordlists[], Accessor &styler) {\n\tFoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);\n}\n\nstatic const char * const matlabWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nstatic const char * const octaveWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, \"matlab\", FoldMatlabDoc, matlabWordListDesc);\n\nextern const LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, \"octave\", FoldOctaveDoc, octaveWordListDesc);\n"
  },
  {
    "path": "lexers/LexMaxima.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexMaxima.cxx\n ** Lexer for Maxima (http://maxima.sourceforge.net).\n ** Written by Gunter Königsmann based on the lisp lexer by Alexey Yutkin and Neil Hodgson .\n **/\n// Copyright 2018 by Gunter Königsmann <wxMaxima@physikbuch.de>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\nusing namespace Lexilla;\n\nstatic inline bool isMaximaoperator(char ch) {\n  return (ch == '\\'' || ch == '`' || ch == '(' ||\n\t  ch == ')'  || ch == '[' || ch == ']' ||\n\t  ch == '{'  || ch == '}' || ch == '!' ||\n\t  ch == '*'  || ch == '/' || ch == '^' ||\n\t  ch == ','  || ch == ':' || ch == '+' ||\n\t  ch == '-');\n}\n\nstatic void ColouriseMaximaDoc(Sci_PositionU startPos, Sci_Position length, int lastStyle,\n\t\t\t       WordList *[],\n\t\t\t       Accessor &styler) {\n\n  styler.StartAt(startPos);\n\n  Sci_Position lengthDoc = startPos + length;\n  styler.StartSegment(startPos);\n\n  Sci_Position i = startPos;\n\n  // If we are in the middle of a comment we go back to its start before highlighting\n  if(lastStyle == SCE_MAXIMA_COMMENT)\n    {\n      while((i>0) &&\n\t    !((styler.SafeGetCharAt(i+1) == '*') && (styler.SafeGetCharAt(i) == '/')))\n\ti--;\n    }\n\n  for (; i < lengthDoc; i++) {\n    char ch = styler.SafeGetCharAt(i);\n    char chNext = styler.SafeGetCharAt(i + 1);\n\n    if (styler.IsLeadByte(ch))\n      continue;\n\n    // Handle comments.\n    // Comments start with /* and end with */\n    if((ch == '/') && (chNext == '*'))\n      {\n\ti++;i++;\n\n\tchNext = styler.SafeGetCharAt(i);\n\tfor (; i < lengthDoc; i++)\n\t  {\n\t    ch = chNext;\n\t    chNext = styler.SafeGetCharAt(i + 1);\n\t    if((ch == '*') && (chNext == '/'))\n\t      {\n\t\ti++;\n\t\ti++;\n\t\tbreak;\n\t      }\n\t  }\n\tif(i > lengthDoc)\n\t  i = lengthDoc;\n\ti--;\n\tstyler.ColourTo(i, SCE_MAXIMA_COMMENT);\n\tcontinue;\n      }\n\n    // Handle Operators\n    if(isMaximaoperator(ch))\n      {\n\tstyler.ColourTo(i, SCE_MAXIMA_OPERATOR);\n\tcontinue;\n      }\n\n    // Handle command endings.\n    if((ch == '$') || (ch == ';'))\n      {\n\tstyler.ColourTo(i, SCE_MAXIMA_COMMANDENDING);\n\tcontinue;\n      }\n\n    // Handle numbers. Numbers always begin with a digit.\n    if(IsASCII(ch) && isdigit(ch))\n      {\n\ti++;\n\tfor (; i < lengthDoc; i++)\n\t  {\n\t    ch = chNext;\n\t    chNext = styler.SafeGetCharAt(i + 1);\n\n\t    if(ch == '.')\n\t      continue;\n\n\t    // A \"e\" or similar can be followed by a \"+\" or a \"-\"\n\t    if(((ch == 'e') || (ch == 'b') || (ch == 'g') || (ch == 'f')) &&\n\t       ((chNext == '+') || (chNext == '-')))\n\t      {\n\t\ti++;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tcontinue;\n\t      }\n\n\t    if(!IsASCII(ch) || !(isdigit(ch) || islower(ch) || isupper(ch)))\n\t      {\n\t\ti--;\n\t\tbreak;\n\t      }\n\t  }\n\tstyler.ColourTo(i, SCE_MAXIMA_NUMBER);\n\tcontinue;\n      }\n\n    // Handle strings\n    if(ch == '\\\"')\n      {\n\ti++;\n\tfor (; i < lengthDoc; i++)\n\t  {\n\t    ch = chNext;\n\t    chNext = styler.SafeGetCharAt(i + 1);\n\t    if(ch == '\\\\')\n\t      i++;\n\t    else\n\t      {\n\t\tif(ch == '\\\"')\n\t\t  break;\n\t      }\n\t  }\n\tstyler.ColourTo(i, SCE_MAXIMA_STRING);\n\tcontinue;\n      }\n\n    // Handle keywords. Maxima treats Non-ASCII chars as ordinary letters.\n    if(((!IsASCII(ch))) || isalpha(ch) || (ch == '_'))\n      {\n\tchar cmd[100];\n\tint cmdidx = 0;\n\tmemset(cmd,0,100);\n\tcmd[cmdidx++] = ch;\n\ti++;\n\tfor (; i < lengthDoc; i++)\n\t  {\n\t    ch = chNext;\n\t    chNext = styler.SafeGetCharAt(i + 1);\n\t    if(ch == '\\\\')\n\t      {\n\t\tif(cmdidx < 99)\n\t\t  cmd[cmdidx++] = ch;\n\t\ti++;\n\t\tif(cmdidx < 99)\n\t\t  cmd[cmdidx++] = ch;\n\t\tcontinue;\n\t      }\n\t    if(isMaximaoperator(ch) || ((IsASCII(ch) && !isalpha(ch) && !isdigit(ch) && (ch != '_'))))\n\t      {\n\t\ti--;\n\t\tbreak;\n\t      }\n\t    if(cmdidx < 99)\n\t      cmd[cmdidx++] = ch;\n\t  }\n\n\t// A few known keywords\n\tif(\n\t   (strncmp(cmd,\"if\",99) == 0) ||\n\t   (strncmp(cmd,\"then\",99) == 0) ||\n\t   (strncmp(cmd,\"else\",99) == 0) ||\n\t   (strncmp(cmd,\"thru\",99) == 0) ||\n\t   (strncmp(cmd,\"for\",99) == 0) ||\n\t   (strncmp(cmd,\"while\",99) == 0) ||\n\t   (strncmp(cmd,\"do\",99) == 0)\n\t   )\n\t  {\n\t    styler.ColourTo(i, SCE_MAXIMA_COMMAND);\n\t    continue;\n\t  }\n\n\t// All other keywords are functions if they are followed\n\t// by an opening parenthesis\n\tchar nextNonwhitespace = ' ';\n\tfor (Sci_Position o = i + 1; o < lengthDoc; o++)\n\t  {\n\t    nextNonwhitespace = styler.SafeGetCharAt(o);\n\t    if(!IsASCII(nextNonwhitespace) || !isspacechar(nextNonwhitespace))\n\t      break;\n\t  }\n\tif(nextNonwhitespace == '(')\n\t  {\n\t    styler.ColourTo(i, SCE_MAXIMA_COMMAND);\n\t  }\n\telse\n\t  {\n\t    styler.ColourTo(i, SCE_MAXIMA_VARIABLE);\n\t  }\n\tcontinue;\n      }\n\n    styler.ColourTo(i-1, SCE_MAXIMA_UNKNOWN);\n  }\n}\n\nextern const LexerModule lmMaxima(SCLEX_MAXIMA, ColouriseMaximaDoc, \"maxima\", 0, 0);\n"
  },
  {
    "path": "lexers/LexMetapost.cxx",
    "content": "// Scintilla source code edit control\n\n// @file LexMetapost.cxx - general context conformant metapost coloring scheme\n// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com\n// Version: September 28, 2003\n// Modified by instanton: July 10, 2007\n// Folding based on keywordlists[]\n\n// Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// This lexer is derived from the one written for the texwork environment (1999++) which in\n// turn is inspired on texedit (1991++) which finds its roots in wdt (1986).\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// val SCE_METAPOST_DEFAULT = 0\n// val SCE_METAPOST_SPECIAL = 1\n// val SCE_METAPOST_GROUP = 2\n// val SCE_METAPOST_SYMBOL = 3\n// val SCE_METAPOST_COMMAND = 4\n// val SCE_METAPOST_TEXT = 5\n\n// Definitions in SciTEGlobal.properties:\n//\n// Metapost Highlighting\n//\n// # Default\n// style.metapost.0=fore:#7F7F00\n// # Special\n// style.metapost.1=fore:#007F7F\n// # Group\n// style.metapost.2=fore:#880000\n// # Symbol\n// style.metapost.3=fore:#7F7F00\n// # Command\n// style.metapost.4=fore:#008800\n// # Text\n// style.metapost.5=fore:#000000\n\n// lexer.tex.comment.process=0\n\n// Auxiliary functions:\n\nstatic inline bool endOfLine(Accessor &styler, Sci_PositionU i) {\n\treturn\n      (styler[i] == '\\n') || ((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n')) ;\n}\n\nstatic inline bool isMETAPOSTcomment(int ch) {\n\treturn\n      (ch == '%') ;\n}\n\nstatic inline bool isMETAPOSTone(int ch) {\n\treturn\n      (ch == '[') || (ch == ']') || (ch == '(') || (ch == ')') ||\n      (ch == ':') || (ch == '=') || (ch == '<') || (ch == '>') ||\n      (ch == '{') || (ch == '}') || (ch == '\\'') || (ch == '\\\"') ;\n}\n\nstatic inline bool isMETAPOSTtwo(int ch) {\n\treturn\n      (ch == ';') || (ch == '$') || (ch == '@') || (ch == '#');\n}\n\nstatic inline bool isMETAPOSTthree(int ch) {\n\treturn\n      (ch == '.') || (ch == '-') || (ch == '+') || (ch == '/') ||\n      (ch == '*') || (ch == ',') || (ch == '|') || (ch == '`') ||\n      (ch == '!') || (ch == '?') || (ch == '^') || (ch == '&') ||\n      (ch == '%') ;\n}\n\nstatic inline bool isMETAPOSTidentifier(int ch) {\n\treturn\n      ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||\n      (ch == '_') ;\n}\n\nstatic inline bool isMETAPOSTnumber(int ch) {\n\treturn\n      (ch >= '0') && (ch <= '9') ;\n}\n\nstatic inline bool isMETAPOSTstring(int ch) {\n\treturn\n      (ch == '\\\"') ;\n}\n\nstatic inline bool isMETAPOSTcolon(int ch) {\n\treturn\n\t\t(ch == ':') ;\n}\n\nstatic inline bool isMETAPOSTequal(int ch) {\n\treturn\n\t\t(ch == '=') ;\n}\n\nstatic int CheckMETAPOSTInterface(\n    Sci_PositionU startPos,\n    Sci_Position length,\n    Accessor &styler,\n\tint defaultInterface) {\n\n    char lineBuffer[1024] ;\n\tSci_PositionU linePos = 0 ;\n\n\t// some day we can make something lexer.metapost.mapping=(none,0)(metapost,1)(mp,1)(metafun,2)...\n\n    if (styler.SafeGetCharAt(0) == '%') {\n        for (Sci_PositionU i = 0; i < startPos + length; i++) {\n            lineBuffer[linePos++] = styler.SafeGetCharAt(i) ;\n            if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {\n                lineBuffer[linePos] = '\\0';\n\t\t\t\tif (strstr(lineBuffer, \"interface=none\")) {\n                    return 0 ;\n\t\t\t\t} else if (strstr(lineBuffer, \"interface=metapost\") || strstr(lineBuffer, \"interface=mp\")) {\n                    return 1 ;\n\t\t\t\t} else if (strstr(lineBuffer, \"interface=metafun\")) {\n                    return 2 ;\n\t\t\t\t} else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, \"%D \\\\module\")) {\n\t\t\t\t\t// better would be to limit the search to just one line\n\t\t\t\t\treturn 2 ;\n                } else {\n                    return defaultInterface ;\n                }\n            }\n\t\t}\n    }\n\n    return defaultInterface ;\n}\n\nstatic void ColouriseMETAPOSTDoc(\n    Sci_PositionU startPos,\n    Sci_Position length,\n    int,\n    WordList *keywordlists[],\n    Accessor &styler) {\n\n\tstyler.StartAt(startPos) ;\n\tstyler.StartSegment(startPos) ;\n\n\tbool processComment   = styler.GetPropertyInt(\"lexer.metapost.comment.process\",   0) == 1 ;\n    int  defaultInterface = styler.GetPropertyInt(\"lexer.metapost.interface.default\", 1) ;\n\n\tint currentInterface = CheckMETAPOSTInterface(startPos,length,styler,defaultInterface) ;\n\n\t// 0  no keyword highlighting\n\t// 1  metapost keyword hightlighting\n\t// 2+ metafun keyword hightlighting\n\n\tint extraInterface = 0 ;\n\n\tif (currentInterface != 0) {\n\t\textraInterface = currentInterface ;\n\t}\n\n\tWordList &keywords  = *keywordlists[0] ;\n\tWordList kwEmpty;\n\tWordList &keywords2 = (extraInterface > 0) ? *keywordlists[extraInterface - 1] : kwEmpty;\n\n\tStyleContext sc(startPos, length, SCE_METAPOST_TEXT, styler) ;\n\n\tchar key[100] ;\n\n    bool inTeX     = false ;\n\tbool inComment = false ;\n\tbool inString  = false ;\n\tbool inClause  = false ;\n\n\tbool going = sc.More() ; // needed because of a fuzzy end of file state\n\n\tfor (; going; sc.Forward()) {\n\n\t\tif (! sc.More()) { going = false ; } // we need to go one behind the end of text\n\n\t\tif (inClause) {\n\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\tinClause = false ;\n\t\t}\n\n\t\tif (inComment) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\tinTeX = false ;\n\t\t\t\tinComment = false ;\n\t\t\t\tinClause = false ;\n\t\t\t\tinString = false ; // not correct but we want to stimulate one-lines\n\t\t\t}\n\t\t} else if (inString) {\n\t\t\tif (isMETAPOSTstring(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_METAPOST_SPECIAL) ;\n\t\t\t\tsc.ForwardSetState(SCE_METAPOST_TEXT) ;\n\t\t\t\tinString = false ;\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\tinTeX = false ;\n\t\t\t\tinComment = false ;\n\t\t\t\tinClause = false ;\n\t\t\t\tinString = false ; // not correct but we want to stimulate one-lines\n\t\t\t}\n\t\t} else {\n\t\t\tif ((! isMETAPOSTidentifier(sc.ch)) && (sc.LengthCurrent() > 0)) {\n\t\t\t\tif (sc.state == SCE_METAPOST_COMMAND) {\n\t\t\t\t\tsc.GetCurrent(key, sizeof(key)) ;\n\t\t\t\t\tif ((strcmp(key,\"btex\") == 0) || (strcmp(key,\"verbatimtex\") == 0)) {\n    \t\t\t\t\tsc.ChangeState(SCE_METAPOST_GROUP) ;\n\t\t\t\t\t\tinTeX = true ;\n\t\t\t\t\t} else if (inTeX) {\n\t\t\t\t\t\tif (strcmp(key,\"etex\") == 0) {\n\t    \t\t\t\t\tsc.ChangeState(SCE_METAPOST_GROUP) ;\n\t\t\t\t\t\t\tinTeX = false ;\n\t\t\t\t\t\t} else {\n\t    \t\t\t\t\tsc.ChangeState(SCE_METAPOST_TEXT) ;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (keywords && keywords.InList(key)) {\n    \t\t\t\t\t\tsc.ChangeState(SCE_METAPOST_COMMAND) ;\n\t\t\t\t\t\t} else if (keywords2 && keywords2.InList(key)) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_METAPOST_EXTRA) ;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_METAPOST_TEXT) ;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (isMETAPOSTcomment(sc.ch)) {\n\t\t\t\tif (! inTeX) {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_SYMBOL) ;\n\t\t\t\t\tsc.ForwardSetState(SCE_METAPOST_DEFAULT) ;\n\t\t\t\t\tinComment = ! processComment ;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\t}\n\t\t\t} else if (isMETAPOSTstring(sc.ch)) {\n\t\t\t\tif (! inTeX) {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_SPECIAL) ;\n\t\t\t\t\tif (! isMETAPOSTstring(sc.chNext)) {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_METAPOST_TEXT) ;\n\t\t\t\t\t}\n\t\t\t\t\tinString = true ;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\t}\n\t\t\t} else if (isMETAPOSTcolon(sc.ch)) {\n\t\t\t\tif (! inTeX) {\n\t\t\t\t\tif (! isMETAPOSTequal(sc.chNext)) {\n\t\t\t\t\t\tsc.SetState(SCE_METAPOST_COMMAND) ;\n\t\t\t\t\t\tinClause = true ;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_METAPOST_SPECIAL) ;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\t}\n\t\t\t} else if (isMETAPOSTone(sc.ch)) {\n\t\t\t\tif (! inTeX) {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_SPECIAL) ;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\t}\n\t\t\t} else if (isMETAPOSTtwo(sc.ch)) {\n\t\t\t\tif (! inTeX) {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_GROUP) ;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\t}\n\t\t\t} else if (isMETAPOSTthree(sc.ch)) {\n\t\t\t\tif (! inTeX) {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_SYMBOL) ;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\t}\n\t\t\t} else if (isMETAPOSTidentifier(sc.ch)) {\n\t\t\t\tif (sc.state != SCE_METAPOST_COMMAND) {\n\t\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\t\tsc.ChangeState(SCE_METAPOST_COMMAND) ;\n\t\t\t\t}\n\t\t\t} else if (isMETAPOSTnumber(sc.ch)) {\n\t\t\t\t// rather redundant since for the moment we don't handle numbers\n\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t\tinTeX = false ;\n\t\t\t\tinComment = false ;\n\t\t\t\tinClause = false ;\n\t\t\t\tinString = false ;\n\t\t\t} else {\n\t\t\t\tsc.SetState(SCE_METAPOST_TEXT) ;\n\t\t\t}\n\t\t}\n\n\t}\n\n\tsc.Complete();\n\n}\n\n// Hooks info the system:\n\nstatic const char * const metapostWordListDesc[] = {\n\t\"MetaPost\",\n\t\"MetaFun\",\n\t0\n} ;\n\nstatic int classifyFoldPointMetapost(const char* s,WordList *keywordlists[]) {\n\tWordList& keywordsStart=*keywordlists[3];\n\tWordList& keywordsStop1=*keywordlists[4];\n\n\tif (keywordsStart.InList(s)) {return 1;}\n\telse if (keywordsStop1.InList(s)) {return -1;}\n\treturn 0;\n\n}\n\nstatic int ParseMetapostWord(Sci_PositionU pos, Accessor &styler, char *word)\n{\n  int length=0;\n  char ch=styler.SafeGetCharAt(pos);\n  *word=0;\n\n  while(isMETAPOSTidentifier(ch) && isalpha(ch) && length<100){\n          word[length]=ch;\n          length++;\n          ch=styler.SafeGetCharAt(pos+length);\n  }\n  word[length]=0;\n  return length;\n}\n\nstatic void FoldMetapostDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordlists[], Accessor &styler)\n{\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos+length;\n\tint visibleChars=0;\n\tSci_Position lineCurrent=styler.GetLine(startPos);\n\tint levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent=levelPrev;\n\tchar chNext=styler[startPos];\n\n\tchar buffer[100]=\"\";\n\n\tfor (Sci_PositionU i=startPos; i < endPos; i++) {\n\t\tchar ch=chNext;\n\t\tchNext=styler.SafeGetCharAt(i+1);\n\t\tchar chPrev=styler.SafeGetCharAt(i-1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif(i==0 || chPrev == '\\r' || chPrev=='\\n'|| chPrev==' '|| chPrev=='(' || chPrev=='$')\n\t\t{\n            ParseMetapostWord(i, styler, buffer);\n\t\t\tlevelCurrent += classifyFoldPointMetapost(buffer,keywordlists);\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n\n}\n\n\nextern const LexerModule lmMETAPOST(SCLEX_METAPOST, ColouriseMETAPOSTDoc, \"metapost\", FoldMetapostDoc, metapostWordListDesc);\n"
  },
  {
    "path": "lexers/LexModula.cxx",
    "content": "//\t-*- coding: utf-8 -*-\n//\tScintilla source code edit control\n/**\n *\t@file LexModula.cxx\n *\t@author Dariusz \"DKnoto\" Knociński\n *\t@date 2011/02/03\n *\t@brief Lexer for Modula-2/3 documents.\n */\n//\tThe License.txt file describes the conditions under which this software may\n//\tbe distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n#ifdef DEBUG_LEX_MODULA\n#define DEBUG_STATE( p, c )\\\n\t\tfprintf( stderr, \"Unknown state: currentPos = %u, char = '%c'\\n\", static_cast<unsigned int>(p), c );\n#else\n#define DEBUG_STATE( p, c )\n#endif\n\nstatic inline bool IsDigitOfBase( unsigned ch, unsigned base ) {\n\tif( ch < '0' || ch > 'f' ) return false;\n\tif( base <= 10 ) {\n\t\tif( ch >= ( '0' + base ) ) return false;\n\t} else {\n\t\tif( ch > '9' ) {\n\t\t\tunsigned nb = base - 10;\n\t\t\tif( ( ch < 'A' ) || ( ch >= ( 'A' + nb ) ) ) {\n\t\t\t\tif( ( ch < 'a' ) || ( ch >= ( 'a' + nb ) ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn true;\n}\n\nstatic inline unsigned IsOperator( StyleContext & sc, WordList & op ) {\n\tint i;\n\tchar s[3];\n\n\ts[0] = sc.ch;\n\ts[1] = sc.chNext;\n\ts[2] = 0;\n\tfor( i = 0; i < op.Length(); i++ ) {\n\t\tif( ( strlen( op.WordAt(i) ) == 2 ) &&\n\t\t\t( s[0] == op.WordAt(i)[0] && s[1] == op.WordAt(i)[1] ) ) {\n\t\t\treturn 2;\n\t\t}\n\t}\n\ts[1] = 0;\n\tfor( i = 0; i < op.Length(); i++ ) {\n\t\tif( ( strlen( op.WordAt(i) ) == 1 ) &&\n\t\t\t( s[0] == op.WordAt(i)[0] ) ) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nstatic inline bool IsEOL( Accessor &styler, Sci_PositionU curPos ) {\n\tunsigned ch = styler.SafeGetCharAt( curPos );\n\tif( ( ch == '\\r' && styler.SafeGetCharAt( curPos + 1 ) == '\\n' ) ||\n\t\t( ch == '\\n' && styler.SafeGetCharAt( curPos - 1 ) != '\\r' ) ) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic inline bool checkStatement(\n\tAccessor &styler,\n\tSci_Position &curPos,\n\tconst char *stt, bool spaceAfter = true ) {\n\tint len = static_cast<int>(strlen( stt ));\n\tint i;\n\tfor( i = 0; i < len; i++ ) {\n\t\tif( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\tif( spaceAfter ) {\n\t\tif( ! isspace( styler.SafeGetCharAt( curPos + i ) ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\tcurPos += ( len - 1 );\n\treturn true;\n}\n\nstatic inline bool checkEndSemicolon(\n\tAccessor &styler,\n\tSci_Position &curPos, Sci_Position endPos )\n{\n\tconst char *stt = \"END\";\n\tint len = static_cast<int>(strlen( stt ));\n\tint i;\n\tfor( i = 0; i < len; i++ ) {\n\t\tif( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\twhile( isspace( styler.SafeGetCharAt( curPos + i ) ) ) {\n\t\ti++;\n\t\tif( ( curPos + i ) >= endPos ) return false;\n\t}\n\tif( styler.SafeGetCharAt( curPos + i ) != ';' ) {\n\t\treturn false;\n\t}\n\tcurPos += ( i - 1 );\n\treturn true;\n}\n\nstatic inline bool checkKeyIdentOper(\n\n\tAccessor &styler,\n\tSci_Position &curPos, Sci_Position endPos,\n\tconst char *stt, const char etk ) {\n\tSci_Position newPos = curPos;\n\tif( ! checkStatement( styler, newPos, stt ) )\n\t\treturn false;\n\tnewPos++;\n\tif( newPos >= endPos )\n\t\treturn false;\n\tif( ! isspace( styler.SafeGetCharAt( newPos ) ) )\n\t\treturn false;\n\tnewPos++;\n\tif( newPos >= endPos )\n\t\treturn false;\n\twhile( isspace( styler.SafeGetCharAt( newPos ) ) ) {\n\t\tnewPos++;\n\t\tif( newPos >= endPos )\n\t\t\treturn false;\n\t}\n\tif( ! isalpha( styler.SafeGetCharAt( newPos ) ) )\n\t\treturn false;\n\tnewPos++;\n\tif( newPos >= endPos )\n\t\treturn false;\n\tchar ch;\n\tch = styler.SafeGetCharAt( newPos );\n\twhile( isalpha( ch ) || isdigit( ch ) || ch == '_' ) {\n\t\tnewPos++;\n\t\tif( newPos >= endPos ) return false;\n\t\tch = styler.SafeGetCharAt( newPos );\n\t}\n\twhile( isspace( styler.SafeGetCharAt( newPos ) ) ) {\n\t\tnewPos++;\n\t\tif( newPos >= endPos ) return false;\n\t}\n\tif( styler.SafeGetCharAt( newPos ) != etk )\n\t\treturn false;\n\tcurPos = newPos;\n\treturn true;\n}\n\nstatic void FoldModulaDoc( Sci_PositionU startPos,\n\t\t\t\t\t\t Sci_Position length,\n\t\t\t\t\t\t int , WordList *[],\n\t\t\t\t\t\t Accessor &styler)\n{\n\tSci_Position curLine = styler.GetLine(startPos);\n\tint curLevel = SC_FOLDLEVELBASE;\n\tSci_Position endPos = startPos + length;\n\tif( curLine > 0 )\n\t\tcurLevel = styler.LevelAt( curLine - 1 ) >> 16;\n\tSci_Position curPos = startPos;\n\tint style = styler.StyleAt( curPos );\n\tint visChars = 0;\n\tint nextLevel = curLevel;\n\n\twhile( curPos < endPos ) {\n\t\tif( ! isspace( styler.SafeGetCharAt( curPos ) ) ) visChars++;\n\n\t\tswitch( style ) {\n\t\tcase SCE_MODULA_COMMENT:\n\t\t\tif( checkStatement( styler, curPos, \"(*\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"*)\" ) )\n\t\t\t\tnextLevel--;\n\t\t\tbreak;\n\n\t\tcase SCE_MODULA_DOXYCOMM:\n\t\t\tif( checkStatement( styler, curPos, \"(**\", false ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"*)\" ) )\n\t\t\t\tnextLevel--;\n\t\t\tbreak;\n\n\t\tcase SCE_MODULA_KEYWORD:\n\t\t\tif( checkStatement( styler, curPos, \"IF\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"BEGIN\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"TRY\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"LOOP\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"FOR\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"WHILE\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"REPEAT\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"UNTIL\" ) )\n\t\t\t\tnextLevel--;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"WITH\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"CASE\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"TYPECASE\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkStatement( styler, curPos, \"LOCK\" ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkKeyIdentOper( styler, curPos, endPos, \"PROCEDURE\", '(' ) )\n\t\t\t\tnextLevel++;\n\t\t\telse\n\t\t\tif( checkKeyIdentOper( styler, curPos, endPos, \"END\", ';' ) ) {\n\t\t\t\tSci_Position cln = curLine;\n\t\t\t\tint clv_old = curLevel;\n\t\t\t\tSci_Position pos;\n\t\t\t\tchar ch;\n\t\t\t\tint clv_new;\n\t\t\t\twhile( cln > 0 ) {\n\t\t\t\t\tclv_new = styler.LevelAt( cln - 1 ) >> 16;\n\t\t\t\t\tif( clv_new < clv_old ) {\n\t\t\t\t\t\tnextLevel--;\n\t\t\t\t\t\tpos = styler.LineStart( cln );\n\t\t\t\t\t\twhile( ( ch = styler.SafeGetCharAt( pos, '\\n' )) != '\\n') {\n\t\t\t\t\t\t\tif( ch == 'P' ) {\n\t\t\t\t\t\t\t\tif( styler.StyleAt(pos) == SCE_MODULA_KEYWORD )\t{\n\t\t\t\t\t\t\t\t\tif( checkKeyIdentOper( styler, pos, endPos,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"PROCEDURE\", '(' ) ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpos++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tclv_old = clv_new;\n\t\t\t\t\t}\n\t\t\t\t\tcln--;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\tif( checkKeyIdentOper( styler, curPos, endPos, \"END\", '.' ) )\n\t\t\t\tnextLevel--;\n\t\t\telse\n\t\t\tif( checkEndSemicolon( styler, curPos, endPos ) )\n\t\t\t\tnextLevel--;\n\t\t\telse {\n\t\t\t\twhile( styler.StyleAt( curPos + 1 ) == SCE_MODULA_KEYWORD )\n\t\t\t\t\tcurPos++;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tif( IsEOL( styler, curPos ) || ( curPos == endPos - 1 ) ) {\n\t\t\tint efectiveLevel = curLevel | nextLevel << 16;\n\t\t\tif( visChars == 0 )\n\t\t\t\tefectiveLevel |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif( curLevel < nextLevel )\n\t\t\t\tefectiveLevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif( efectiveLevel != styler.LevelAt(curLine) ) {\n\t\t\t\tstyler.SetLevel(curLine, efectiveLevel );\n\t\t\t}\n\t\t\tcurLine++;\n\t\t\tcurLevel = nextLevel;\n\t\t\tif( IsEOL( styler, curPos ) && ( curPos == endPos - 1 ) ) {\n\t\t\t\tstyler.SetLevel( curLine, ( curLevel | curLevel << 16)\n\t\t\t\t\t\t\t\t| SC_FOLDLEVELWHITEFLAG);\n\t\t\t}\n\t\t\tvisChars = 0;\n\t\t}\n\t\tcurPos++;\n\t\tstyle = styler.StyleAt( curPos );\n\t}\n}\n\nstatic inline bool skipWhiteSpaces( StyleContext & sc ) {\n\twhile( isspace( sc.ch ) ) {\n\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\tif( sc.More() )\n\t\t\tsc.Forward();\n\t\telse\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nstatic void ColouriseModulaDoc(\tSci_PositionU startPos,\n\t\t\t\t\t\t\t\t\tSci_Position length,\n\t\t\t\t\t\t\t\t\tint initStyle,\n\t\t\t\t\t\t\t\t\tWordList *wl[],\n\t\t\t\t\t\t\t\t\tAccessor &styler ) {\n\tWordList& keyWords\t\t= *wl[0];\n\tWordList& reservedWords\t= *wl[1];\n\tWordList& operators \t= *wl[2];\n\tWordList& pragmaWords \t= *wl[3];\n\tWordList& escapeCodes\t= *wl[4];\n\tWordList& doxyKeys\t\t= *wl[5];\n\n\tconst int BUFLEN = 128;\n\n\tchar\tbuf[BUFLEN];\n\tint\t\ti, kl;\n\n\tSci_Position  charPos = 0;\n\n\tStyleContext sc( startPos, length, initStyle, styler );\n\n\twhile( sc.More() ) \t{\n\t\tswitch( sc.state )\t{\n\t\tcase SCE_MODULA_DEFAULT:\n\t\t\tif( ! skipWhiteSpaces( sc ) ) break;\n\n\t\t\tif( sc.ch == '(' && sc.chNext == '*' ) {\n\t\t\t\tif( sc.GetRelative(2) == '*' ) {\n\t\t\t\t\tsc.SetState( SCE_MODULA_DOXYCOMM );\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState( SCE_MODULA_COMMENT );\n\t\t\t\t}\n\t\t\t\tsc.Forward();\n\t\t\t}\n\t\t\telse\n\t\t\tif( isalpha( sc.ch ) ) {\n\t\t\t\tif( isupper( sc.ch ) && isupper( sc.chNext ) ) {\n\t\t\t\t\tfor( i = 0; i < BUFLEN - 1; i++ ) {\n\t\t\t\t\t\tbuf[i] = sc.GetRelative(i);\n\t\t\t\t\t\tif( !(IsAlphaNumeric( buf[i] ) || buf[i] == '_') )\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tkl = i;\n\t\t\t\t\tbuf[kl] = 0;\n\n\t\t\t\t\tif( keyWords.InList( buf ) ) {\n\t\t\t\t\t\tsc.SetState( SCE_MODULA_KEYWORD );\n\t\t\t\t\t\tsc.Forward( kl );\n\t\t\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif( reservedWords.InList( buf ) ) {\n\t\t\t\t\t\tsc.SetState( SCE_MODULA_RESERVED );\n\t\t\t\t\t\tsc.Forward( kl );\n\t\t\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/** check procedure identifier */\n\t\t\t\t\t\tsc.Forward( kl );\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor( i = 0; i < BUFLEN - 1; i++ ) {\n\t\t\t\t\t\tbuf[i] = sc.GetRelative(i);\n\t\t\t\t\t\tif( !isalpha( buf[i] ) &&\n\t\t\t\t\t\t\t!isdigit( buf[i] ) &&\n\t\t\t\t\t\t\t!(buf[i] == '_') )\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tkl = i;\n\t\t\t\t\tbuf[kl] = 0;\n\n\t\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\t\tsc.Forward( kl );\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\tif( isdigit( sc.ch ) ) {\n\t\t\t\tsc.SetState( SCE_MODULA_NUMBER );\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse\n\t\t\tif( sc.ch == '\\\"' ) {\n\t\t\t\tsc.SetState( SCE_MODULA_STRING );\n\t\t\t}\n\t\t\telse\n\t\t\tif( sc.ch == '\\'' ) {\n\t\t\t\tcharPos = sc.currentPos;\n\t\t\t\tsc.SetState( SCE_MODULA_CHAR );\n\t\t\t}\n\t\t\telse\n\t\t\tif( sc.ch == '<' && sc.chNext == '*' ) {\n\t\t\t\tsc.SetState( SCE_MODULA_PRAGMA );\n\t\t\t\tsc.Forward();\n\t\t\t} else {\n\t\t\t\tunsigned len = IsOperator( sc, operators );\n\t\t\t\tif( len > 0 ) {\n\t\t\t\t\tsc.SetState( SCE_MODULA_OPERATOR );\n\t\t\t\t\tsc.Forward( len );\n\t\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tDEBUG_STATE( sc.currentPos, sc.ch );\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_MODULA_COMMENT:\n\t\t\tif( sc.ch == '*' && sc.chNext == ')' ) {\n\t\t\t\tsc.Forward( 2 );\n\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_MODULA_DOXYCOMM:\n\t\t\tswitch( sc.ch ) {\n\t\t\tcase '*':\n\t\t\t\tif( sc.chNext == ')' ) {\n\t\t\t\t\tsc.Forward( 2 );\n\t\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase '@':\n\t\t\t\tif( islower( sc.chNext ) ) {\n\t\t\t\t\tfor( i = 0; i < BUFLEN - 1; i++ ) {\n\t\t\t\t\t\tbuf[i] = sc.GetRelative(i+1);\n\t\t\t\t\t\tif( isspace( buf[i] ) ) break;\n\t\t\t\t\t}\n\t\t\t\t\tbuf[i] = 0;\n\t\t\t\t\tkl = i;\n\n\t\t\t\t\tif( doxyKeys.InList( buf ) ) {\n\t\t\t\t\t\tsc.SetState( SCE_MODULA_DOXYKEY );\n\t\t\t\t\t\tsc.Forward( kl + 1 );\n\t\t\t\t\t\tsc.SetState( SCE_MODULA_DOXYCOMM );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_MODULA_NUMBER:\n\t\t\t{\n\t\t\t\tbuf[0] = sc.ch;\n\t\t\t\tfor( i = 1; i < BUFLEN - 1; i++ ) {\n\t\t\t\t\tbuf[i] = sc.GetRelative(i);\n\t\t\t\t\tif( ! isdigit( buf[i] ) )\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tkl = i;\n\t\t\t\tbuf[kl] = 0;\n\n\t\t\t\tswitch( sc.GetRelative(kl) ) {\n\t\t\t\tcase '_':\n\t\t\t\t\t{\n\t\t\t\t\t\tint base = atoi( buf );\n\t\t\t\t\t\tif( base < 2 || base > 16 ) {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tint imax;\n\n\t\t\t\t\t\t\tkl++;\n\t\t\t\t\t\t\tfor( i = 0; i < BUFLEN - 1; i++ ) {\n\t\t\t\t\t\t\t\tbuf[i] = sc.GetRelative(kl+i);\n\t\t\t\t\t\t\t\tif( ! IsDigitOfBase( buf[i], 16 ) ) {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\timax = i;\n\t\t\t\t\t\t\tfor( i = 0; i < imax; i++ ) {\n\t\t\t\t\t\t\t\tif( ! IsDigitOfBase( buf[i], base ) ) {\n\t\t\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tkl += imax;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsc.SetState( SCE_MODULA_BASENUM );\n\t\t\t\t\t\tfor( i = 0; i < kl; i++ ) {\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase '.':\n\t\t\t\t\tif( sc.GetRelative(kl+1) == '.' ) {\n\t\t\t\t\t\tkl--;\n\t\t\t\t\t\tfor( i = 0; i < kl; i++ ) {\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbool doNext = false;\n\n\t\t\t\t\t\tkl++;\n\n\t\t\t\t\t\tbuf[0] = sc.GetRelative(kl);\n\t\t\t\t\t\tif( isdigit( buf[0] ) ) {\n\t\t\t\t\t\t\tfor( i = 0;; i++ ) {\n\t\t\t\t\t\t\t\tif( !isdigit(sc.GetRelative(kl+i)) )\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tkl += i;\n\t\t\t\t\t\t\tbuf[0] = sc.GetRelative(kl);\n\n\t\t\t\t\t\t\tswitch( buf[0] )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase 'E':\n\t\t\t\t\t\t\tcase 'e':\n\t\t\t\t\t\t\tcase 'D':\n\t\t\t\t\t\t\tcase 'd':\n\t\t\t\t\t\t\tcase 'X':\n\t\t\t\t\t\t\tcase 'x':\n\t\t\t\t\t\t\t\tkl++;\n\t\t\t\t\t\t\t\tbuf[0] = sc.GetRelative(kl);\n\t\t\t\t\t\t\t\tif( buf[0] == '-' || buf[0] == '+' ) {\n\t\t\t\t\t\t\t\t\tkl++;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbuf[0] = sc.GetRelative(kl);\n\t\t\t\t\t\t\t\tif( isdigit( buf[0] ) ) {\n\t\t\t\t\t\t\t\t\tfor( i = 0;; i++ ) {\n\t\t\t\t\t\t\t\t\t\tif( !isdigit(sc.GetRelative(kl+i)) ) {\n\t\t\t\t\t\t\t\t\t\t\tbuf[0] = sc.GetRelative(kl+i);\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tkl += i;\n\t\t\t\t\t\t\t\t\tdoNext = true;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tdoNext = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( doNext ) {\n\t\t\t\t\t\t\tif( ! isspace( buf[0] ) &&\n\t\t\t\t\t\t\t\tbuf[0] != ')' &&\n\t\t\t\t\t\t\t\tbuf[0] != '>' &&\n\t\t\t\t\t\t\t\tbuf[0] != '<' &&\n\t\t\t\t\t\t\t\tbuf[0] != '=' &&\n\t\t\t\t\t\t\t\tbuf[0] != '#' &&\n\t\t\t\t\t\t\t\tbuf[0] != '+' &&\n\t\t\t\t\t\t\t\tbuf[0] != '-' &&\n\t\t\t\t\t\t\t\tbuf[0] != '*' &&\n\t\t\t\t\t\t\t\tbuf[0] != '/' &&\n\t\t\t\t\t\t\t\tbuf[0] != ',' &&\n\t\t\t\t\t\t\t\tbuf[0] != ';'\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tkl--;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState( SCE_MODULA_FLOAT );\n\t\t\t\t\tfor( i = 0; i < kl; i++ ) {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\t\tcontinue;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tfor( i = 0; i < kl; i++ ) {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_MODULA_STRING:\n\t\t\tif( sc.ch == '\\\"' ) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tif( sc.ch == '\\\\' ) {\n\t\t\t\t\ti = 1;\n\t\t\t\t\tif( IsDigitOfBase( sc.chNext, 8 ) ) {\n\t\t\t\t\t\tfor( i = 1; i < BUFLEN - 1; i++ ) {\n\t\t\t\t\t\t\tif( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif( i == 3 ) {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_STRSPEC );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuf[0] = sc.chNext;\n\t\t\t\t\t\tbuf[1] = 0;\n\n\t\t\t\t\t\tif( escapeCodes.InList( buf ) ) {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_STRSPEC );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsc.Forward(i+1);\n\t\t\t\t\tsc.SetState( SCE_MODULA_STRING );\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_MODULA_CHAR:\n\t\t\tif( sc.ch == '\\'' ) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse\n\t\t\tif( ( sc.currentPos - charPos ) == 1 ) {\n\t\t\t\tif( sc.ch == '\\\\' ) {\n\t\t\t\t\ti = 1;\n\t\t\t\t\tif( IsDigitOfBase( sc.chNext, 8 ) ) {\n\t\t\t\t\t\tfor( i = 1; i < BUFLEN - 1; i++ ) {\n\t\t\t\t\t\t\tif( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif( i == 3 ) {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_CHARSPEC );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuf[0] = sc.chNext;\n\t\t\t\t\t\tbuf[1] = 0;\n\n\t\t\t\t\t\tif( escapeCodes.InList( buf ) ) {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_CHARSPEC );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsc.Forward(i+1);\n\t\t\t\t\tsc.SetState( SCE_MODULA_CHAR );\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsc.SetState( SCE_MODULA_BADSTR );\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState( SCE_MODULA_CHAR );\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_MODULA_PRAGMA:\n\t\t\tif( sc.ch == '*' && sc.chNext == '>' ) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState( SCE_MODULA_DEFAULT );\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse\n\t\t\tif( isupper( sc.ch ) && isupper( sc.chNext ) ) {\n\t\t\t\tbuf[0] = sc.ch;\n\t\t\t\tbuf[1] = sc.chNext;\n\t\t\t\tfor( i = 2; i < BUFLEN - 1; i++ ) {\n\t\t\t\t\tbuf[i] = sc.GetRelative(i);\n\t\t\t\t\tif( !isupper( buf[i] ) )\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tkl = i;\n\t\t\t\tbuf[kl] = 0;\n\t\t\t\tif( pragmaWords.InList( buf ) ) {\n\t\t\t\t\tsc.SetState( SCE_MODULA_PRGKEY );\n\t\t\t\t\tsc.Forward( kl );\n\t\t\t\t\tsc.SetState( SCE_MODULA_PRAGMA );\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t\tsc.Forward();\n\t}\n\tsc.Complete();\n}\n\nstatic const char *const modulaWordListDesc[] =\n{\n\t\"Keywords\",\n\t\"ReservedKeywords\",\n\t\"Operators\",\n\t\"PragmaKeyswords\",\n\t\"EscapeCodes\",\n\t\"DoxygeneKeywords\",\n\t0\n};\n\nextern const LexerModule lmModula( SCLEX_MODULA, ColouriseModulaDoc, \"modula\", FoldModulaDoc,\n\t\t\t\t\t  modulaWordListDesc);\n"
  },
  {
    "path": "lexers/LexMySQL.cxx",
    "content": "/**\n * Scintilla source code edit control\n * @file LexMySQL.cxx\n * Lexer for MySQL\n *\n * Improved by Mike Lischke <mike.lischke@oracle.com>\n * Adopted from LexSQL.cxx by Anders Karlsson <anders@mysql.com>\n * Original work by Neil Hodgson <neilh@scintilla.org>\n * Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n * The License.txt file describes the conditions under which this software may be distributed.\n */\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordChar(int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\nstatic inline bool IsAWordStart(int ch) {\n\treturn (ch < 0x80) && (isalpha(ch) || ch == '_');\n}\n\nstatic inline bool IsANumberChar(int ch) {\n\t// Not exactly following number definition (several dots are seen as OK, etc.)\n\t// but probably enough in most cases.\n\treturn (ch < 0x80) &&\n\t        (isdigit(ch) || toupper(ch) == 'E' ||\n             ch == '.' || ch == '-' || ch == '+');\n}\n\n//--------------------------------------------------------------------------------------------------\n\n/**\n * Check if the current content context represent a keyword and set the context state if so.\n */\nstatic void CheckForKeyword(StyleContext& sc, WordList* keywordlists[], int activeState)\n{\n  Sci_Position length = sc.LengthCurrent() + 1; // +1 for the next char\n  char* s = new char[length];\n  sc.GetCurrentLowered(s, length);\n  if (keywordlists[0]->InList(s))\n    sc.ChangeState(SCE_MYSQL_MAJORKEYWORD | activeState);\n  else\n    if (keywordlists[1]->InList(s))\n      sc.ChangeState(SCE_MYSQL_KEYWORD | activeState);\n    else\n      if (keywordlists[2]->InList(s))\n        sc.ChangeState(SCE_MYSQL_DATABASEOBJECT | activeState);\n      else\n        if (keywordlists[3]->InList(s))\n          sc.ChangeState(SCE_MYSQL_FUNCTION | activeState);\n        else\n          if (keywordlists[5]->InList(s))\n            sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD | activeState);\n          else\n            if (keywordlists[6]->InList(s))\n              sc.ChangeState(SCE_MYSQL_USER1 | activeState);\n            else\n              if (keywordlists[7]->InList(s))\n                sc.ChangeState(SCE_MYSQL_USER2 | activeState);\n              else\n                if (keywordlists[8]->InList(s))\n                  sc.ChangeState(SCE_MYSQL_USER3 | activeState);\n  delete [] s;\n}\n\n//--------------------------------------------------------------------------------------------------\n\n#define HIDDENCOMMAND_STATE 0x40 // Offset for states within a hidden command.\n#define MASKACTIVE(style) (style & ~HIDDENCOMMAND_STATE)\n\nstatic void SetDefaultState(StyleContext& sc, int activeState)\n{\n  if (activeState == 0)\n    sc.SetState(SCE_MYSQL_DEFAULT);\n  else\n    sc.SetState(SCE_MYSQL_HIDDENCOMMAND);\n}\n\nstatic void ForwardDefaultState(StyleContext& sc, int activeState)\n{\n  if (activeState == 0)\n    sc.ForwardSetState(SCE_MYSQL_DEFAULT);\n  else\n    sc.ForwardSetState(SCE_MYSQL_HIDDENCOMMAND);\n}\n\nstatic void ColouriseMySQLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler)\n{\n\tStyleContext sc(startPos, length, initStyle, styler, 127);\n  int activeState = (initStyle == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : initStyle & HIDDENCOMMAND_STATE;\n\n\tfor (; sc.More(); sc.Forward())\n  {\n\t\t// Determine if the current state should terminate.\n\t\tswitch (MASKACTIVE(sc.state))\n    {\n      case SCE_MYSQL_OPERATOR:\n        SetDefaultState(sc, activeState);\n        break;\n      case SCE_MYSQL_NUMBER:\n        // We stop the number definition on non-numerical non-dot non-eE non-sign char.\n        if (!IsANumberChar(sc.ch))\n          SetDefaultState(sc, activeState);\n        break;\n      case SCE_MYSQL_IDENTIFIER:\n        // Switch from identifier to keyword state and open a new state for the new char.\n        if (!IsAWordChar(sc.ch))\n        {\n          CheckForKeyword(sc, keywordlists, activeState);\n\n          // Additional check for function keywords needed.\n          // A function name must be followed by an opening parenthesis.\n          if (MASKACTIVE(sc.state) == SCE_MYSQL_FUNCTION && sc.ch != '(')\n          {\n            if (activeState > 0)\n              sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND);\n            else\n              sc.ChangeState(SCE_MYSQL_DEFAULT);\n          }\n\n          SetDefaultState(sc, activeState);\n        }\n        break;\n      case SCE_MYSQL_VARIABLE:\n        if (!IsAWordChar(sc.ch))\n          SetDefaultState(sc, activeState);\n        break;\n      case SCE_MYSQL_SYSTEMVARIABLE:\n        if (!IsAWordChar(sc.ch))\n        {\n          Sci_Position length = sc.LengthCurrent() + 1;\n          char* s = new char[length];\n          sc.GetCurrentLowered(s, length);\n\n          // Check for known system variables here.\n          if (keywordlists[4]->InList(&s[2]))\n            sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE | activeState);\n          delete [] s;\n\n          SetDefaultState(sc, activeState);\n        }\n        break;\n      case SCE_MYSQL_QUOTEDIDENTIFIER:\n        if (sc.ch == '`')\n        {\n          if (sc.chNext == '`')\n            sc.Forward();\t// Ignore it\n          else\n            ForwardDefaultState(sc, activeState);\n\t\t\t\t}\n  \t\t\tbreak;\n      case SCE_MYSQL_COMMENT:\n        if (sc.Match('*', '/'))\n        {\n          sc.Forward();\n          ForwardDefaultState(sc, activeState);\n        }\n        break;\n      case SCE_MYSQL_COMMENTLINE:\n        if (sc.atLineStart)\n          SetDefaultState(sc, activeState);\n        break;\n      case SCE_MYSQL_SQSTRING:\n        if (sc.ch == '\\\\')\n          sc.Forward(); // Escape sequence\n        else\n          if (sc.ch == '\\'')\n          {\n            // End of single quoted string reached?\n            if (sc.chNext == '\\'')\n              sc.Forward();\n            else\n              ForwardDefaultState(sc, activeState);\n          }\n        break;\n      case SCE_MYSQL_DQSTRING:\n        if (sc.ch == '\\\\')\n          sc.Forward(); // Escape sequence\n        else\n          if (sc.ch == '\\\"')\n          {\n            // End of single quoted string reached?\n            if (sc.chNext == '\\\"')\n              sc.Forward();\n            else\n              ForwardDefaultState(sc, activeState);\n          }\n        break;\n      case SCE_MYSQL_PLACEHOLDER:\n        if (sc.Match('}', '>'))\n        {\n          sc.Forward();\n          ForwardDefaultState(sc, activeState);\n        }\n        break;\n    }\n\n    if (sc.state == SCE_MYSQL_HIDDENCOMMAND && sc.Match('*', '/'))\n    {\n      activeState = 0;\n      sc.Forward();\n      ForwardDefaultState(sc, activeState);\n    }\n\n    // Determine if a new state should be entered.\n    if (sc.state == SCE_MYSQL_DEFAULT || sc.state == SCE_MYSQL_HIDDENCOMMAND)\n    {\n      switch (sc.ch)\n      {\n        case '@':\n          if (sc.chNext == '@')\n          {\n            sc.SetState(SCE_MYSQL_SYSTEMVARIABLE | activeState);\n            sc.Forward(2); // Skip past @@.\n          }\n          else\n            if (IsAWordStart(sc.ch))\n            {\n              sc.SetState(SCE_MYSQL_VARIABLE | activeState);\n              sc.Forward(); // Skip past @.\n            }\n            else\n              sc.SetState(SCE_MYSQL_OPERATOR | activeState);\n          break;\n        case '`':\n          sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER | activeState);\n          break;\n        case '#':\n          sc.SetState(SCE_MYSQL_COMMENTLINE | activeState);\n          break;\n        case '\\'':\n          sc.SetState(SCE_MYSQL_SQSTRING | activeState);\n          break;\n        case '\\\"':\n          sc.SetState(SCE_MYSQL_DQSTRING | activeState);\n          break;\n        default:\n          if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))\n            sc.SetState(SCE_MYSQL_NUMBER | activeState);\n          else\n            if (IsAWordStart(sc.ch))\n              sc.SetState(SCE_MYSQL_IDENTIFIER | activeState);\n            else\n              if (sc.Match('/', '*'))\n              {\n                sc.SetState(SCE_MYSQL_COMMENT | activeState);\n\n                // Skip first char of comment introducer and check for hidden command.\n                // The second char is skipped by the outer loop.\n                sc.Forward();\n                if (sc.GetRelativeCharacter(1) == '!')\n                {\n                  // Version comment found. Skip * now.\n                  sc.Forward();\n                  activeState = HIDDENCOMMAND_STATE;\n                  sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND);\n                }\n              }\n              else if (sc.Match('<', '{'))\n              {\n                sc.SetState(SCE_MYSQL_PLACEHOLDER | activeState);\n              }\n              else\n                if (sc.Match(\"--\"))\n                {\n                  // Special MySQL single line comment.\n                  sc.SetState(SCE_MYSQL_COMMENTLINE | activeState);\n                  sc.Forward(2);\n\n                  // Check the third character too. It must be a space or EOL.\n                  if (sc.ch != ' ' && sc.ch != '\\n' && sc.ch != '\\r')\n                    sc.ChangeState(SCE_MYSQL_OPERATOR | activeState);\n                }\n                else\n                  if (isoperator(static_cast<char>(sc.ch)))\n                    sc.SetState(SCE_MYSQL_OPERATOR | activeState);\n      }\n    }\n  }\n\n  // Do a final check for keywords if we currently have an identifier, to highlight them\n  // also at the end of a line.\n  if (sc.state == SCE_MYSQL_IDENTIFIER)\n  {\n    CheckForKeyword(sc, keywordlists, activeState);\n\n    // Additional check for function keywords needed.\n    // A function name must be followed by an opening parenthesis.\n    if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')\n      SetDefaultState(sc, activeState);\n  }\n\n  sc.Complete();\n}\n\n//--------------------------------------------------------------------------------------------------\n\n/**\n * Helper function to determine if we have a foldable comment currently.\n */\nstatic bool IsStreamCommentStyle(int style)\n{\n\treturn MASKACTIVE(style) == SCE_MYSQL_COMMENT;\n}\n\n//--------------------------------------------------------------------------------------------------\n\n/**\n * Code copied from StyleContext and modified to work here. Should go into Accessor as a\n * companion to Match()...\n */\nstatic bool MatchIgnoreCase(Accessor &styler, Sci_Position currentPos, const char *s)\n{\n  for (Sci_Position n = 0; *s; n++)\n  {\n    if (*s != tolower(styler.SafeGetCharAt(currentPos + n)))\n      return false;\n    s++;\n  }\n  return true;\n}\n\n//--------------------------------------------------------------------------------------------------\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment.\nstatic void FoldMySQLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler)\n{\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tbool foldOnlyBegin = styler.GetPropertyInt(\"fold.sql.only.begin\", 0) != 0;\n\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;\n\tint levelNext = levelCurrent;\n\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n  int activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE;\n\n  bool endPending = false;\n\tbool whenPending = false;\n\tbool elseIfPending = false;\n\n  char nextChar = styler.SafeGetCharAt(startPos);\n  for (Sci_PositionU i = startPos; length > 0; i++, length--)\n  {\n\t\tint stylePrev = style;\n    int lastActiveState = activeState;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n    activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE;\n\n    char currentChar = nextChar;\n    nextChar = styler.SafeGetCharAt(i + 1);\n\t\tbool atEOL = (currentChar == '\\r' && nextChar != '\\n') || (currentChar == '\\n');\n\n    switch (MASKACTIVE(style))\n    {\n      case SCE_MYSQL_COMMENT:\n        if (foldComment)\n        {\n          // Multiline comment style /* .. */ just started or is still in progress.\n          if (IsStreamCommentStyle(style) && !IsStreamCommentStyle(stylePrev))\n            levelNext++;\n        }\n        break;\n      case SCE_MYSQL_COMMENTLINE:\n        if (foldComment)\n        {\n          // Not really a standard, but we add support for single line comments\n          // with special curly braces syntax as foldable comments too.\n          // MySQL needs -- comments to be followed by space or control char\n          if (styler.Match(i, \"--\"))\n          {\n            char chNext2 = styler.SafeGetCharAt(i + 2);\n            char chNext3 = styler.SafeGetCharAt(i + 3);\n            if (chNext2 == '{' || chNext3 == '{')\n              levelNext++;\n            else\n              if (chNext2 == '}' || chNext3 == '}')\n                levelNext--;\n          }\n        }\n        break;\n      case SCE_MYSQL_HIDDENCOMMAND:\n        /*\n        if (endPending)\n        {\n          // A conditional command is not a white space so it should end the current block\n          // before opening a new one.\n          endPending = false;\n          levelNext--;\n          if (levelNext < SC_FOLDLEVELBASE)\n            levelNext = SC_FOLDLEVELBASE;\n        }\n        }*/\n        if (activeState != lastActiveState)\n          levelNext++;\n        break;\n      case SCE_MYSQL_OPERATOR:\n        if (endPending)\n        {\n          endPending = false;\n          levelNext--;\n          if (levelNext < SC_FOLDLEVELBASE)\n            levelNext = SC_FOLDLEVELBASE;\n        }\n        if (currentChar == '(')\n          levelNext++;\n        else\n          if (currentChar == ')')\n          {\n            levelNext--;\n            if (levelNext < SC_FOLDLEVELBASE)\n              levelNext = SC_FOLDLEVELBASE;\n          }\n        break;\n      case SCE_MYSQL_MAJORKEYWORD:\n      case SCE_MYSQL_KEYWORD:\n      case SCE_MYSQL_FUNCTION:\n      case SCE_MYSQL_PROCEDUREKEYWORD:\n        // Reserved and other keywords.\n        if (style != stylePrev)\n        {\n          // END decreases the folding level, regardless which keyword follows.\n          bool endFound = MatchIgnoreCase(styler, i, \"end\");\n          if (endPending)\n          {\n            levelNext--;\n            if (levelNext < SC_FOLDLEVELBASE)\n              levelNext = SC_FOLDLEVELBASE;\n          }\n          else\n            if (!endFound)\n            {\n              if (MatchIgnoreCase(styler, i, \"begin\"))\n                levelNext++;\n              else\n              {\n                if (!foldOnlyBegin)\n                {\n                  bool whileFound = MatchIgnoreCase(styler, i, \"while\");\n                  bool loopFound = MatchIgnoreCase(styler, i, \"loop\");\n                  bool repeatFound = MatchIgnoreCase(styler, i, \"repeat\");\n                  bool caseFound = MatchIgnoreCase(styler, i, \"case\");\n\n                  if (whileFound || loopFound || repeatFound || caseFound)\n                    levelNext++;\n                  else\n                  {\n                    // IF alone does not increase the fold level as it is also used in non-block'ed\n                    // code like DROP PROCEDURE blah IF EXISTS.\n                    // Instead THEN opens the new level (if not part of an ELSEIF or WHEN (case) branch).\n                    if (MatchIgnoreCase(styler, i, \"then\"))\n                    {\n                      if (!elseIfPending && !whenPending)\n                        levelNext++;\n                      else\n                      {\n                        elseIfPending = false;\n                        whenPending = false;\n                      }\n                    }\n                    else\n                    {\n                      // Neither of if/then/while/loop/repeat/case, so check for\n                      // sub parts of IF and CASE.\n                      if (MatchIgnoreCase(styler, i, \"elseif\"))\n                        elseIfPending = true;\n                      if (MatchIgnoreCase(styler, i, \"when\"))\n                        whenPending = true;\n                    }\n                  }\n                }\n              }\n            }\n\n          // Keep the current end state for the next round.\n          endPending = endFound;\n        }\n        break;\n\n      default:\n        if (!isspacechar(currentChar) && endPending)\n        {\n          // END followed by a non-whitespace character (not covered by other cases like identifiers)\n          // also should end a folding block. Typical case: END followed by self defined delimiter.\n          levelNext--;\n          if (levelNext < SC_FOLDLEVELBASE)\n            levelNext = SC_FOLDLEVELBASE;\n        }\n        break;\n    }\n\n    // Go up one level if we just ended a multi line comment.\n    if (IsStreamCommentStyle(stylePrev) && !IsStreamCommentStyle(style))\n    {\n      levelNext--;\n      if (levelNext < SC_FOLDLEVELBASE)\n        levelNext = SC_FOLDLEVELBASE;\n    }\n\n    if (activeState == 0 && lastActiveState != 0)\n    {\n      // Decrease fold level when we left a hidden command.\n      levelNext--;\n      if (levelNext < SC_FOLDLEVELBASE)\n        levelNext = SC_FOLDLEVELBASE;\n    }\n\n    if (atEOL)\n    {\n      // Apply the new folding level to this line.\n      // Leave pending states as they are otherwise a line break will de-sync\n      // code folding and valid syntax.\n      int levelUse = levelCurrent;\n      int lev = levelUse | levelNext << 16;\n      if (visibleChars == 0 && foldCompact)\n        lev |= SC_FOLDLEVELWHITEFLAG;\n      if (levelUse < levelNext)\n        lev |= SC_FOLDLEVELHEADERFLAG;\n      if (lev != styler.LevelAt(lineCurrent))\n        styler.SetLevel(lineCurrent, lev);\n\n      lineCurrent++;\n      levelCurrent = levelNext;\n      visibleChars = 0;\n    }\n\n\t\tif (!isspacechar(currentChar))\n      visibleChars++;\n  }\n}\n\n//--------------------------------------------------------------------------------------------------\n\nstatic const char * const mysqlWordListDesc[] = {\n\t\"Major Keywords\",\n\t\"Keywords\",\n\t\"Database Objects\",\n\t\"Functions\",\n\t\"System Variables\",\n\t\"Procedure keywords\",\n\t\"User Keywords 1\",\n\t\"User Keywords 2\",\n\t\"User Keywords 3\",\n\t0\n};\n\nextern const LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, \"mysql\", FoldMySQLDoc, mysqlWordListDesc);\n"
  },
  {
    "path": "lexers/LexNim.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexNim.cxx\n** Lexer for Nim\n** Written by Jad Altahan (github.com/xv)\n** Nim manual: https://nim-lang.org/docs/manual.html\n**/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"StringCopy.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n    // Use an unnamed namespace to protect the functions and classes from name conflicts\n\nenum NumType {\n    Binary,\n    Octal,\n    Exponent,\n    Hexadecimal,\n    Decimal,\n    FormatError\n};\n\nint GetNumStyle(const int numType) noexcept {\n    if (numType == NumType::FormatError) {\n        return SCE_NIM_NUMERROR;\n    }\n\n    return SCE_NIM_NUMBER;\n}\n\nconstexpr bool IsLetter(const int ch) noexcept {\n    // 97 to 122 || 65 to 90\n    return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');\n}\n\nbool IsAWordChar(const int ch) noexcept {\n    return ch < 0x80 && (isalnum(ch) || ch == '_' || ch == '.');\n}\n\nint IsNumHex(const StyleContext &sc) noexcept {\n    return sc.chNext == 'x' || sc.chNext == 'X';\n}\n\nint IsNumBinary(const StyleContext &sc) noexcept {\n    return sc.chNext == 'b' || sc.chNext == 'B';\n}\n\nint IsNumOctal(const StyleContext &sc) {\n    return IsADigit(sc.chNext) || sc.chNext == 'o';\n}\n\nconstexpr bool IsNewline(const int ch) noexcept {\n    return (ch == '\\n' || ch == '\\r');\n}\n\nbool IsFuncName(const char *str) noexcept {\n    const char *identifiers[] = {\n        \"proc\",\n        \"func\",\n        \"macro\",\n        \"method\",\n        \"template\",\n        \"iterator\",\n        \"converter\"\n    };\n\n    for (const char *id : identifiers) {\n        if (strcmp(str, id) == 0) {\n            return true;\n        }\n    }\n\n    return false;\n}\n\nconstexpr bool IsTripleLiteral(const int style) noexcept {\n    return style == SCE_NIM_TRIPLE || style == SCE_NIM_TRIPLEDOUBLE;\n}\n\nconstexpr bool IsLineComment(const int style) noexcept {\n    return style == SCE_NIM_COMMENTLINE || style == SCE_NIM_COMMENTLINEDOC;\n}\n\nconstexpr bool IsStreamComment(const int style) noexcept {\n    return style == SCE_NIM_COMMENT || style == SCE_NIM_COMMENTDOC;\n}\n\n// Adopted from Accessor.cxx\nint GetIndent(const Sci_Position line, Accessor &styler) {\n    Sci_Position startPos = styler.LineStart(line);\n    const Sci_Position eolPos = styler.LineStart(line + 1) - 1;\n\n    char ch = styler[startPos];\n    int style = styler.StyleAt(startPos);\n\n    int indent = 0;\n    bool inPrevPrefix = line > 0;\n    Sci_Position posPrev = inPrevPrefix ? styler.LineStart(line - 1) : 0;\n\n    // No fold points inside triple literals\n    while ((IsASpaceOrTab(ch) || IsTripleLiteral(style)) && (startPos < eolPos)) {\n        if (inPrevPrefix) {\n            const char chPrev = styler[posPrev++];\n            if (chPrev != ' ' && chPrev != '\\t') {\n                inPrevPrefix = false;\n            }\n        }\n\n        if (ch == '\\t') {\n            indent = (indent / 8 + 1) * 8;\n        } else {\n            indent++;\n        }\n\n        startPos++;\n        ch = styler[startPos];\n        style = styler.StyleAt(startPos);\n    }\n\n    // Prevent creating fold lines for comments if indented\n    if (!(IsStreamComment(style) || IsLineComment(style)))\n        indent += SC_FOLDLEVELBASE;\n\n    if (styler.LineStart(line) == styler.Length() \n        || IsASpaceOrTab(ch) \n        || IsNewline(ch) \n        || IsStreamComment(style)\n        || IsLineComment(style)) {\n        return indent | SC_FOLDLEVELWHITEFLAG;\n    } else {\n        return indent;\n    }\n}\n\nint IndentAmount(const Sci_Position line, Accessor &styler) {\n    const int indent = GetIndent(line, styler);\n    const int indentLevel = indent & SC_FOLDLEVELNUMBERMASK;\n    return indentLevel <= SC_FOLDLEVELBASE ? indent : indentLevel | (indent & ~SC_FOLDLEVELNUMBERMASK);\n}\n\nstruct OptionsNim {\n    bool fold;\n    bool foldCompact;\n    bool highlightRawStrIdent;\n\n    OptionsNim() {\n        fold = true;\n        foldCompact = true;\n        highlightRawStrIdent = false;\n    }\n};\n\nstatic const char *const nimWordListDesc[] = {\n    \"Keywords\",\n    nullptr\n};\n\nstruct OptionSetNim : public OptionSet<OptionsNim> {\n    OptionSetNim() {\n        DefineProperty(\"lexer.nim.raw.strings.highlight.ident\", &OptionsNim::highlightRawStrIdent,\n            \"Set to 1 to enable highlighting generalized raw string identifiers. \"\n            \"Generalized raw string identifiers are anything other than r (or R).\");\n\n        DefineProperty(\"fold\", &OptionsNim::fold);\n        DefineProperty(\"fold.compact\", &OptionsNim::foldCompact);\n\n        DefineWordListSets(nimWordListDesc);\n    }\n};\n\nLexicalClass lexicalClasses[] = {\n    // Lexer Nim SCLEX_NIM SCE_NIM_:\n    0,  \"SCE_NIM_DEFAULT\",        \"default\",              \"White space\",\n    1,  \"SCE_NIM_COMMENT\",        \"comment block\",        \"Block comment\",\n    2,  \"SCE_NIM_COMMENTDOC\",     \"comment block doc\",    \"Block doc comment\",\n    3,  \"SCE_NIM_COMMENTLINE\",    \"comment line\",         \"Line comment\",\n    4,  \"SCE_NIM_COMMENTLINEDOC\", \"comment doc\",          \"Line doc comment\",\n    5,  \"SCE_NIM_NUMBER\",         \"literal numeric\",      \"Number\",\n    6,  \"SCE_NIM_STRING\",         \"literal string\",       \"String\",\n    7,  \"SCE_NIM_CHARACTER\",      \"literal string\",       \"Single quoted string\",\n    8,  \"SCE_NIM_WORD\",           \"keyword\",              \"Keyword\",\n    9,  \"SCE_NIM_TRIPLE\",         \"literal string\",       \"Triple quotes\",\n    10, \"SCE_NIM_TRIPLEDOUBLE\",   \"literal string\",       \"Triple double quotes\",\n    11, \"SCE_NIM_BACKTICKS\",      \"operator definition\",  \"Identifiers\",\n    12, \"SCE_NIM_FUNCNAME\",       \"identifier\",           \"Function name definition\",\n    13, \"SCE_NIM_STRINGEOL\",      \"error literal string\", \"String is not closed\",\n    14, \"SCE_NIM_NUMERROR\",       \"numeric error\",        \"Numeric format error\",\n    15, \"SCE_NIM_OPERATOR\",       \"operator\",             \"Operators\",\n    16, \"SCE_NIM_IDENTIFIER\",     \"identifier\",           \"Identifiers\",\n};\n\n}\n\nclass LexerNim : public DefaultLexer {\n    CharacterSet setWord;\n    WordList keywords;\n    OptionsNim options;\n    OptionSetNim osNim;\n\npublic:\n    LexerNim() :\n        DefaultLexer(\"nim\", SCLEX_NIM, lexicalClasses, ELEMENTS(lexicalClasses)),\n        setWord(CharacterSet::setAlphaNum, \"_\", 0x80, true) { }\n\n    virtual ~LexerNim() { }\n\n    void SCI_METHOD Release() noexcept override {\n        delete this;\n    }\n\n    int SCI_METHOD Version() const noexcept override {\n        return lvRelease5;\n    }\n\n    const char * SCI_METHOD PropertyNames() override {\n        return osNim.PropertyNames();\n    }\n\n    int SCI_METHOD PropertyType(const char *name) override {\n        return osNim.PropertyType(name);\n    }\n\n    const char * SCI_METHOD DescribeProperty(const char *name) override {\n        return osNim.DescribeProperty(name);\n    }\n\n    Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\n\tconst char * SCI_METHOD PropertyGet(const char* key) override {\n\t\treturn osNim.PropertyGet(key);\n\t}\n\n    const char * SCI_METHOD DescribeWordListSets() override {\n        return osNim.DescribeWordListSets();\n    }\n\n    Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n    void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n    void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n    void * SCI_METHOD PrivateCall(int, void *) noexcept override {\n        return nullptr;\n    }\n\n    int SCI_METHOD LineEndTypesSupported() noexcept override {\n        return SC_LINE_END_TYPE_UNICODE;\n    }\n\n    int SCI_METHOD PrimaryStyleFromStyle(int style) noexcept override {\n        return style;\n    }\n\n    static ILexer5 *LexerFactoryNim() {\n        return new LexerNim();\n    }\n};\n\nSci_Position SCI_METHOD LexerNim::PropertySet(const char *key, const char *val) {\n    if (osNim.PropertySet(&options, key, val)) {\n        return 0;\n    }\n\n    return -1;\n}\n\nSci_Position SCI_METHOD LexerNim::WordListSet(int n, const char *wl) {\n    WordList *wordListN = nullptr;\n\n    switch (n) {\n        case 0:\n            wordListN = &keywords;\n            break;\n    }\n\n    Sci_Position firstModification = -1;\n\n    if (wordListN) {\n        WordList wlNew;\n        wlNew.Set(wl);\n\n        if (*wordListN != wlNew) {\n            wordListN->Set(wl);\n            firstModification = 0;\n        }\n    }\n\n    return firstModification;\n}\n\nvoid SCI_METHOD LexerNim::Lex(Sci_PositionU startPos, Sci_Position length,\n                              int initStyle, IDocument *pAccess) {\n    // No one likes a leaky string\n    if (initStyle == SCE_NIM_STRINGEOL) {\n        initStyle = SCE_NIM_DEFAULT;\n    }\n\n    Accessor styler(pAccess, nullptr);\n    StyleContext sc(startPos, length, initStyle, styler);\n\n    // Nim supports nested block comments!\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int commentNestLevel = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) : 0;\n\n    int numType = NumType::Decimal;\n    int decimalCount = 0;\n\n    bool funcNameExists = false;\n    bool isStylingRawString = false;\n    bool isStylingRawStringIdent = false;\n\n    for (; sc.More(); sc.Forward()) {\n        if (sc.atLineStart) {\n            if (sc.state == SCE_NIM_STRING) {\n                sc.SetState(SCE_NIM_STRING);\n            }\n\n            lineCurrent = styler.GetLine(sc.currentPos);\n            styler.SetLineState(lineCurrent, commentNestLevel);\n        }\n\n        // Handle string line continuation\n        if (sc.ch == '\\\\' && (sc.chNext == '\\n' || sc.chNext == '\\r') &&\n           (sc.state == SCE_NIM_STRING || sc.state == SCE_NIM_CHARACTER) && !isStylingRawString) {\n            sc.Forward();\n\n            if (sc.ch == '\\r' && sc.chNext == '\\n') {\n                sc.Forward();\n            }\n\n            continue;\n        }\n\n        switch (sc.state) {\n            case SCE_NIM_OPERATOR:\n                funcNameExists = false;\n                sc.SetState(SCE_NIM_DEFAULT);\n                break;\n            case SCE_NIM_NUMBER:\n                // For a type suffix, such as 0x80'u8\n                if (sc.ch == '\\'') {\n                    if (sc.chNext == 'i' || sc.chNext == 'I' || \n                        sc.chNext == 'u' || sc.chNext == 'U' ||\n                        sc.chNext == 'f' || sc.chNext == 'F' || \n                        sc.chNext == 'd' || sc.chNext == 'D') {\n                        sc.Forward(2);\n                    }\n                } else if (sc.ch == '.') {\n                    if (IsADigit(sc.chNext)) {\n                        sc.Forward();\n                    } else if (numType <= NumType::Exponent) {\n                        sc.SetState(SCE_NIM_OPERATOR);\n                        break;\n                    } else {\n                        decimalCount++;\n\n                        if (numType == NumType::Decimal) {\n                            if (decimalCount <= 1 && !IsAWordChar(sc.chNext)) {\n                                break;\n                            }\n                        } else if (numType == NumType::Hexadecimal) {\n                            if (decimalCount <= 1 && IsADigit(sc.chNext, 16)) {\n                                break;\n                            }\n\n                            sc.SetState(SCE_NIM_OPERATOR);\n                            break;\n                        }\n                    }\n                } else if (sc.ch == '_') {\n                    // Accept only one underscore between digits\n                    if (IsADigit(sc.chNext)) {\n                        sc.Forward();\n                    }\n                } else if (numType == NumType::Decimal) {\n                    if (sc.chPrev != '\\'' && (sc.ch == 'e' || sc.ch == 'E')) {\n                        numType = NumType::Exponent;\n\n                        if (sc.chNext == '-' || sc.chNext == '+') {\n                            sc.Forward();\n                        }\n\n                        break;\n                    }\n\n                    if (IsADigit(sc.ch)) {\n                        break;\n                    }\n                } else if (numType == NumType::Hexadecimal) {\n                    if (IsADigit(sc.ch, 16)) {\n                        break;\n                    }\n                } else if (IsADigit(sc.ch)) {\n                    if (numType == NumType::Exponent) {\n                        break;\n                    }\n\n                    if (numType == NumType::Octal) {\n                        // Accept only 0-7\n                        if (sc.ch <= '7') {\n                            break;\n                        }\n                    } else if (numType == NumType::Binary) {\n                        // Accept only 0 and 1\n                        if (sc.ch <= '1') {\n                            break;\n                        }\n                    }\n\n                    numType = NumType::FormatError;\n                    break;\n                }\n\n                sc.ChangeState(GetNumStyle(numType));\n                sc.SetState(SCE_NIM_DEFAULT);\n                break;\n            case SCE_NIM_IDENTIFIER:\n                if (sc.ch == '.' || !IsAWordChar(sc.ch)) {\n                    char s[100];\n                    sc.GetCurrent(s, sizeof(s));\n                    int style = SCE_NIM_IDENTIFIER;\n\n                    if (keywords.InList(s) && !funcNameExists) {\n                        // Prevent styling keywords if they are sub-identifiers\n                        const Sci_Position segStart = styler.GetStartSegment() - 1;\n                        if (segStart < 0 || styler.SafeGetCharAt(segStart, '\\0') != '.') {\n                            style = SCE_NIM_WORD;\n                        }\n                    } else if (funcNameExists) {\n                        style = SCE_NIM_FUNCNAME;\n                    }\n\n                    sc.ChangeState(style);\n                    sc.SetState(SCE_NIM_DEFAULT);\n\n                    if (style == SCE_NIM_WORD) {\n                        funcNameExists = IsFuncName(s);\n                    } else {\n                        funcNameExists = false;\n                    }\n                }\n\n                if (IsAlphaNumeric(sc.ch) && sc.chNext == '\\\"') {\n                    isStylingRawStringIdent = true;\n\n                    if (options.highlightRawStrIdent) {\n                        if (styler.SafeGetCharAt(sc.currentPos + 2) == '\\\"' &&\n                            styler.SafeGetCharAt(sc.currentPos + 3) == '\\\"') {\n                            sc.ChangeState(SCE_NIM_TRIPLEDOUBLE);\n                        } else {\n                            sc.ChangeState(SCE_NIM_STRING);\n                        }\n                    }\n\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                }\n                break;\n            case SCE_NIM_FUNCNAME:\n                if (sc.ch == '`') {\n                    funcNameExists = false;\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                } else if (sc.atLineEnd) {\n                    // Prevent leaking the style to the next line if not closed\n                    funcNameExists = false;\n\n                    sc.ChangeState(SCE_NIM_STRINGEOL);\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                }\n                break;\n            case SCE_NIM_COMMENT:\n                if (sc.Match(']', '#')) {\n                    if (commentNestLevel > 0) {\n                        commentNestLevel--;\n                    }\n\n                    lineCurrent = styler.GetLine(sc.currentPos);\n                    styler.SetLineState(lineCurrent, commentNestLevel);\n                    sc.Forward();\n\n                    if (commentNestLevel == 0) {\n                        sc.ForwardSetState(SCE_NIM_DEFAULT);\n                    }\n                } else if (sc.Match('#', '[')) {\n                    commentNestLevel++;\n                    lineCurrent = styler.GetLine(sc.currentPos);\n                    styler.SetLineState(lineCurrent, commentNestLevel);\n                }\n                break;\n            case SCE_NIM_COMMENTDOC:\n                if (sc.Match(\"]##\")) {\n                    if (commentNestLevel > 0) {\n                        commentNestLevel--;\n                    }\n\n                    lineCurrent = styler.GetLine(sc.currentPos);\n                    styler.SetLineState(lineCurrent, commentNestLevel);\n                    sc.Forward(2);\n\n                    if (commentNestLevel == 0) {\n                        sc.ForwardSetState(SCE_NIM_DEFAULT);\n                    }\n                } else if (sc.Match(\"##[\")) {\n                    commentNestLevel++;\n                    lineCurrent = styler.GetLine(sc.currentPos);\n                    styler.SetLineState(lineCurrent, commentNestLevel);\n                }\n                break;\n            case SCE_NIM_COMMENTLINE:\n            case SCE_NIM_COMMENTLINEDOC:\n                if (sc.atLineStart) {\n                    sc.SetState(SCE_NIM_DEFAULT);\n                }\n                break;\n            case SCE_NIM_STRING:\n                if (!isStylingRawStringIdent && !isStylingRawString && sc.ch == '\\\\') {\n                    if (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n                        sc.Forward();\n                    }\n                } else if (isStylingRawString && sc.ch == '\\\"' && sc.chNext == '\\\"') {\n                    // Forward in situations such as r\"a\"\"bc\\\" so that \"bc\\\" wouldn't be\n                    // considered a string of its own\n                    sc.Forward();\n                } else if (sc.ch == '\\\"') {\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                } else if (sc.atLineEnd) {\n                    sc.ChangeState(SCE_NIM_STRINGEOL);\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                }\n                break;\n            case SCE_NIM_CHARACTER:\n                if (sc.ch == '\\\\') {\n                    if (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n                        sc.Forward();\n                    }\n                } else if (sc.ch == '\\'') {\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                } else if (sc.atLineEnd) {\n                    sc.ChangeState(SCE_NIM_STRINGEOL);\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                }\n                break;\n            case SCE_NIM_BACKTICKS:\n                if (sc.ch == '`' ) {\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                } else if (sc.atLineEnd) {\n                    sc.ChangeState(SCE_NIM_STRINGEOL);\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                }\n                break;\n            case SCE_NIM_TRIPLEDOUBLE:\n                if (sc.Match(R\"(\"\"\")\")) {\n\n                    // Outright forward all \" after the closing \"\"\" as a triple double\n                    //\n                    // A valid example where this is needed is: \"\"\"8 double quotes->\"\"\"\"\"\"\"\"\n                    // You can have as many \"\"\" at the end as you wish, as long as the actual\n                    // closing literal is there\n                    while (sc.ch == '\"') {\n                        sc.Forward();\n                    }\n\n                    sc.SetState(SCE_NIM_DEFAULT);\n                }\n                break;\n            case SCE_NIM_TRIPLE:\n                if (sc.Match(\"'''\")) {\n                    sc.Forward(2);\n                    sc.ForwardSetState(SCE_NIM_DEFAULT);\n                }\n                break;\n        }\n\n        if (sc.state == SCE_NIM_DEFAULT) {\n            // Number\n            if (IsADigit(sc.ch)) {\n                sc.SetState(SCE_NIM_NUMBER);\n\n                numType = NumType::Decimal;\n                decimalCount = 0;\n\n                if (sc.ch == '0') {\n                    if (IsNumHex(sc)) {\n                        numType = NumType::Hexadecimal;\n                    } else if (IsNumBinary(sc)) {\n                        numType = NumType::Binary;\n                    } else if (IsNumOctal(sc)) {\n                        numType = NumType::Octal;\n                    }\n\n                    if (numType != NumType::Decimal) {\n                        sc.Forward();\n                    }\n                }\n            }\n            // Raw string\n            else if (IsAlphaNumeric(sc.ch) && sc.chNext == '\\\"') {\n                isStylingRawString = true;\n\n                // Triple doubles can be raw strings too. How sweet\n                if (styler.SafeGetCharAt(sc.currentPos + 2) == '\\\"' &&\n                    styler.SafeGetCharAt(sc.currentPos + 3) == '\\\"') {\n                    sc.SetState(SCE_NIM_TRIPLEDOUBLE);\n                } else {\n                    sc.SetState(SCE_NIM_STRING);\n                }\n\n                const int rawStrStyle = options.highlightRawStrIdent ? IsLetter(sc.ch) :\n                                        (sc.ch == 'r' || sc.ch == 'R');\n\n                if (rawStrStyle) {\n                    sc.Forward();\n\n                    if (sc.state == SCE_NIM_TRIPLEDOUBLE) {\n                        sc.Forward(2);\n                    }\n                } else {\n                    // Anything other than r/R is considered a general raw string identifier\n                    isStylingRawStringIdent = true;\n                    sc.SetState(SCE_NIM_IDENTIFIER);\n                }\n            }\n            // String and triple double literal\n            else if (sc.ch == '\\\"') {\n                isStylingRawString = false;\n\n                if (sc.Match(R\"(\"\"\")\")) {\n                    sc.SetState(SCE_NIM_TRIPLEDOUBLE);\n                    \n                    // Keep forwarding until the total opening literal count is 5\n                    // A valid example where this is needed is: \"\"\"\"\"<-5 double quotes\"\"\"\n                    while (sc.ch == '\"') {\n                        sc.Forward();\n\n                        if (sc.Match(R\"(\"\"\")\")) {\n                            sc.Forward();\n                            break;\n                        }\n                    }\n                } else {\n                    sc.SetState(SCE_NIM_STRING);\n                }\n            }\n            // Charecter and triple literal\n            else if (sc.ch == '\\'') {\n                if (sc.Match(\"'''\")) {\n                    sc.SetState(SCE_NIM_TRIPLE);\n                } else {\n                    sc.SetState(SCE_NIM_CHARACTER);\n                }\n            }\n            // Operator definition\n            else if (sc.ch == '`') {\n                if (funcNameExists) {\n                    sc.SetState(SCE_NIM_FUNCNAME);\n                } else {\n                    sc.SetState(SCE_NIM_BACKTICKS);\n                }\n            }\n            // Keyword\n            else if (iswordstart(sc.ch)) {\n                sc.SetState(SCE_NIM_IDENTIFIER);\n            }\n            // Comments\n            else if (sc.ch == '#') {\n                if (sc.Match(\"##[\") || sc.Match(\"#[\")) {\n                    commentNestLevel++;\n                    lineCurrent = styler.GetLine(sc.currentPos);\n                    styler.SetLineState(lineCurrent, commentNestLevel);\n                }\n\n                if (sc.Match(\"##[\")) {\n                    sc.SetState(SCE_NIM_COMMENTDOC);\n                    sc.Forward();\n                } else if (sc.Match(\"#[\")) {\n                    sc.SetState(SCE_NIM_COMMENT);\n                    sc.Forward();\n                } else if (sc.Match(\"##\")) {\n                    sc.SetState(SCE_NIM_COMMENTLINEDOC);\n                } else {\n                    sc.SetState(SCE_NIM_COMMENTLINE);\n                }\n            }\n            // Operators\n            else if (strchr(\"()[]{}:=;-\\\\/&%$!+<>|^?,.*~@\", sc.ch)) {\n                sc.SetState(SCE_NIM_OPERATOR);\n            }\n        }\n\n        if (sc.atLineEnd) {\n            funcNameExists = false;\n            isStylingRawString = false;\n            isStylingRawStringIdent = false;\n        }\n    }\n\n    sc.Complete();\n}\n\nvoid SCI_METHOD LexerNim::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) {\n    if (!options.fold) {\n        return;\n    }\n\n    Accessor styler(pAccess, nullptr);\n\n    const Sci_Position docLines = styler.GetLine(styler.Length());\n    const Sci_Position maxPos = startPos + length;\n    const Sci_Position maxLines = styler.GetLine(maxPos == styler.Length() ? maxPos : maxPos - 1);\n\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int indentCurrent = IndentAmount(lineCurrent, styler);\n\n    while (lineCurrent > 0) {\n        lineCurrent--;\n        indentCurrent = IndentAmount(lineCurrent, styler);\n\n        if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n            break;\n        }\n    }\n\n    int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n    indentCurrent = indentCurrentLevel | (indentCurrent & ~SC_FOLDLEVELNUMBERMASK);\n\n    while (lineCurrent <= docLines && lineCurrent <= maxLines) {\n        Sci_Position lineNext = lineCurrent + 1;\n        int indentNext = indentCurrent;\n        int lev = indentCurrent;\n\n        if (lineNext <= docLines) {\n            indentNext = IndentAmount(lineNext, styler);\n        }\n\n        if (indentNext & SC_FOLDLEVELWHITEFLAG) {\n            indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;\n        }\n\n        while (lineNext < docLines && (indentNext & SC_FOLDLEVELWHITEFLAG)) {\n            lineNext++;\n            indentNext = IndentAmount(lineNext, styler);\n        }\n\n        const int indentNextLevel = indentNext & SC_FOLDLEVELNUMBERMASK;\n        indentNext = indentNextLevel | (indentNext & ~SC_FOLDLEVELNUMBERMASK);\n\n        const int levelBeforeComments = std::max(indentCurrentLevel, indentNextLevel);\n\n        Sci_Position skipLine = lineNext;\n        int skipLevel = indentNextLevel;\n\n        while (--skipLine > lineCurrent) {\n            const int skipLineIndent = IndentAmount(skipLine, styler);\n\n            if (options.foldCompact) {\n                if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > indentNextLevel) {\n                    skipLevel = levelBeforeComments;\n                }\n\n                const int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;\n                styler.SetLevel(skipLine, skipLevel | whiteFlag);\n            } else {\n                if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > indentNextLevel &&\n                   !(skipLineIndent & SC_FOLDLEVELWHITEFLAG)) {\n                    skipLevel = levelBeforeComments;\n                }\n\n                styler.SetLevel(skipLine, skipLevel);\n            }\n        }\n\n        if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n            if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            }\n        }\n\n        styler.SetLevel(lineCurrent, options.foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);\n\n        indentCurrent = indentNext;\n        indentCurrentLevel = indentNextLevel;\n        lineCurrent = lineNext;\n    }\n}\n\nextern const LexerModule lmNim(SCLEX_NIM, LexerNim::LexerFactoryNim, \"nim\", nimWordListDesc);"
  },
  {
    "path": "lexers/LexNimrod.cxx",
    "content": "// Scintilla source code edit control\n// Nimrod lexer\n// (c) 2009 Andreas Rumpf\n/** @file LexNimrod.cxx\n ** Lexer for Nimrod.\n ** This lexer has been superceded by the \"nim\" lexer in LexNim.cxx.\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordChar(int ch) {\n\treturn (ch >= 0x80) || isalnum(ch) || ch == '_';\n}\n\nstatic Sci_Position tillEndOfTripleQuote(Accessor &styler, Sci_Position pos, Sci_Position max) {\n  /* search for \"\"\" */\n  for (;;) {\n    if (styler.SafeGetCharAt(pos, '\\0') == '\\0') return pos;\n    if (pos >= max) return pos;\n    if (styler.Match(pos, \"\\\"\\\"\\\"\")) {\n      return pos + 2;\n    }\n    pos++;\n  }\n}\n\n#define CR 13 /* use both because Scite allows changing the line ending */\n#define LF 10\n\nstatic bool inline isNewLine(int ch) {\n  return ch == CR || ch == LF;\n}\n\nstatic Sci_Position scanString(Accessor &styler, Sci_Position pos, Sci_Position max, bool rawMode) {\n  for (;;) {\n    if (pos >= max) return pos;\n    char ch = styler.SafeGetCharAt(pos, '\\0');\n    if (ch == CR || ch == LF || ch == '\\0') return pos;\n    if (ch == '\"') return pos;\n    if (ch == '\\\\' && !rawMode) {\n      pos += 2;\n    } else {\n      pos++;\n    }\n  }\n}\n\nstatic Sci_Position scanChar(Accessor &styler, Sci_Position pos, Sci_Position max) {\n  for (;;) {\n    if (pos >= max) return pos;\n    char ch = styler.SafeGetCharAt(pos, '\\0');\n    if (ch == CR || ch == LF || ch == '\\0') return pos;\n    if (ch == '\\'' && !isalnum(styler.SafeGetCharAt(pos+1, '\\0')) )\n      return pos;\n    if (ch == '\\\\') {\n      pos += 2;\n    } else {\n      pos++;\n    }\n  }\n}\n\nstatic Sci_Position scanIdent(Accessor &styler, Sci_Position pos, WordList &keywords) {\n  char buf[100]; /* copy to lowercase and ignore underscores */\n  Sci_Position i = 0;\n\n  for (;;) {\n    char ch = styler.SafeGetCharAt(pos, '\\0');\n    if (!IsAWordChar(ch)) break;\n    if (ch != '_' && i < ((int)sizeof(buf))-1) {\n      buf[i] = static_cast<char>(tolower(ch));\n      i++;\n    }\n    pos++;\n  }\n  buf[i] = '\\0';\n  /* look for keyword */\n  if (keywords.InList(buf)) {\n    styler.ColourTo(pos-1, SCE_P_WORD);\n  } else {\n    styler.ColourTo(pos-1, SCE_P_IDENTIFIER);\n  }\n  return pos;\n}\n\nstatic Sci_Position scanNumber(Accessor &styler, Sci_Position pos) {\n  char ch, ch2;\n  ch = styler.SafeGetCharAt(pos, '\\0');\n  ch2 = styler.SafeGetCharAt(pos+1, '\\0');\n  if (ch == '0' && (ch2 == 'b' || ch2 == 'B')) {\n    /* binary number: */\n    pos += 2;\n    for (;;) {\n      ch = styler.SafeGetCharAt(pos, '\\0');\n      if (ch == '_' || (ch >= '0' && ch <= '1')) ++pos;\n      else break;\n    }\n  } else if (ch == '0' &&\n            (ch2 == 'o' || ch2 == 'O' || ch2 == 'c' || ch2 == 'C')) {\n    /* octal number: */\n    pos += 2;\n    for (;;) {\n      ch = styler.SafeGetCharAt(pos, '\\0');\n      if (ch == '_' || (ch >= '0' && ch <= '7')) ++pos;\n      else break;\n    }\n  } else if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) {\n    /* hexadecimal number: */\n    pos += 2;\n    for (;;) {\n      ch = styler.SafeGetCharAt(pos, '\\0');\n      if (ch == '_' || (ch >= '0' && ch <= '9')\n          || (ch >= 'a' && ch <= 'f')\n          || (ch >= 'A' && ch <= 'F')) ++pos;\n      else break;\n    }\n  } else {\n    // skip decimal part:\n    for (;;) {\n      ch = styler.SafeGetCharAt(pos, '\\0');\n      if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;\n      else break;\n    }\n    ch2 = styler.SafeGetCharAt(pos+1, '\\0');\n    if (ch == '.' && ch2 >= '0' && ch2 <= '9') {\n      ++pos; // skip '.'\n      for (;;) {\n        ch = styler.SafeGetCharAt(pos, '\\0');\n        if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;\n        else break;\n      }\n    }\n    if (ch == 'e' || ch == 'E') {\n      ++pos;\n      ch = styler.SafeGetCharAt(pos, '\\0');\n      if (ch == '-' || ch == '+') ++pos;\n      for (;;) {\n        ch = styler.SafeGetCharAt(pos, '\\0');\n        if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;\n        else break;\n      }\n    }\n  }\n  if (ch == '\\'') {\n    /* a type suffix: */\n    pos++;\n    for (;;) {\n      ch = styler.SafeGetCharAt(pos);\n      if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')\n         || (ch >= 'a' && ch <= 'z') || ch == '_') ++pos;\n      else break;\n    }\n  }\n  styler.ColourTo(pos-1, SCE_P_NUMBER);\n  return pos;\n}\n\n/* rewritten from scratch, because I couldn't get rid of the bugs...\n   (A character based approach sucks!)\n*/\nstatic void ColouriseNimrodDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                                WordList *keywordlists[], Accessor &styler) {\n  Sci_Position pos = startPos;\n  Sci_Position max = startPos + length;\n  char ch;\n  WordList &keywords = *keywordlists[0];\n\n  styler.StartAt(startPos);\n  styler.StartSegment(startPos);\n\n  switch (initStyle) {\n    /* check where we are: */\n    case SCE_P_TRIPLEDOUBLE:\n      pos = tillEndOfTripleQuote(styler, pos, max);\n      styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);\n      pos++;\n    break;\n    default: /* nothing to do: */\n    break;\n  }\n  while (pos < max) {\n    ch = styler.SafeGetCharAt(pos, '\\0');\n    switch (ch) {\n      case '\\0': return;\n      case '#': {\n        bool doccomment = (styler.SafeGetCharAt(pos+1) == '#');\n        while (pos < max && !isNewLine(styler.SafeGetCharAt(pos, LF))) pos++;\n        if (doccomment)\n          styler.ColourTo(pos, SCE_C_COMMENTLINEDOC);\n        else\n          styler.ColourTo(pos, SCE_P_COMMENTLINE);\n      } break;\n      case 'r': case 'R': {\n        if (styler.SafeGetCharAt(pos+1) == '\"') {\n          pos = scanString(styler, pos+2, max, true);\n          styler.ColourTo(pos, SCE_P_STRING);\n          pos++;\n        } else {\n          pos = scanIdent(styler, pos, keywords);\n        }\n      } break;\n      case '\"':\n        if (styler.Match(pos+1, \"\\\"\\\"\")) {\n          pos = tillEndOfTripleQuote(styler, pos+3, max);\n          styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);\n        } else {\n          pos = scanString(styler, pos+1, max, false);\n          styler.ColourTo(pos, SCE_P_STRING);\n        }\n        pos++;\n      break;\n      case '\\'':\n        pos = scanChar(styler, pos+1, max);\n        styler.ColourTo(pos, SCE_P_CHARACTER);\n        pos++;\n      break;\n      default: // identifers, numbers, operators, whitespace\n        if (ch >= '0' && ch <= '9') {\n          pos = scanNumber(styler, pos);\n        } else if (IsAWordChar(ch)) {\n          pos = scanIdent(styler, pos, keywords);\n        } else if (ch == '`') {\n          pos++;\n          while (pos < max) {\n            ch = styler.SafeGetCharAt(pos, LF);\n            if (ch == '`') {\n              ++pos;\n              break;\n            }\n            if (ch == CR || ch == LF) break;\n            ++pos;\n          }\n          styler.ColourTo(pos, SCE_P_IDENTIFIER);\n        } else if (strchr(\"()[]{}:=;-\\\\/&%$!+<>|^?,.*~@\", ch)) {\n          styler.ColourTo(pos, SCE_P_OPERATOR);\n          pos++;\n        } else {\n          styler.ColourTo(pos, SCE_P_DEFAULT);\n          pos++;\n        }\n      break;\n    }\n  }\n}\n\nstatic bool IsCommentLine(Sci_Position line, Accessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tif (ch == '#')\n\t\t\treturn true;\n\t\telse if (ch != ' ' && ch != '\\t')\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nstatic bool IsQuoteLine(Sci_Position line, Accessor &styler) {\n\tint style = styler.StyleAt(styler.LineStart(line)) & 31;\n\treturn ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));\n}\n\n\nstatic void FoldNimrodDoc(Sci_PositionU startPos, Sci_Position length,\n                          int /*initStyle - unused*/,\n                          WordList *[], Accessor &styler) {\n\tconst Sci_Position maxPos = startPos + length;\n\tconst Sci_Position maxLines = styler.GetLine(maxPos - 1); // Requested last line\n\tconst Sci_Position docLines = styler.GetLine(styler.Length() - 1); // Available last line\n\tconst bool foldComment = styler.GetPropertyInt(\"fold.comment.nimrod\") != 0;\n\tconst bool foldQuotes = styler.GetPropertyInt(\"fold.quotes.nimrod\") != 0;\n\n\t// Backtrack to previous non-blank line so we can determine indent level\n\t// for any white space lines (needed esp. within triple quoted strings)\n\t// and so we can fix any preceding fold level (which is why we go back\n\t// at least one line in all cases)\n\tint spaceFlags = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);\n\twhile (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tindentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);\n\t\tif (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&\n\t\t        (!IsCommentLine(lineCurrent, styler)) &&\n\t\t        (!IsQuoteLine(lineCurrent, styler)))\n\t\t\tbreak;\n\t}\n\tint indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\n\t// Set up initial loop state\n\tstartPos = styler.LineStart(lineCurrent);\n\tint prev_state = SCE_P_DEFAULT & 31;\n\tif (lineCurrent >= 1)\n\t\tprev_state = styler.StyleAt(startPos - 1) & 31;\n\tint prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) ||\n\t                               (prev_state == SCE_P_TRIPLEDOUBLE));\n\tint prevComment = 0;\n\tif (lineCurrent >= 1)\n\t\tprevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);\n\n\t// Process all characters to end of requested range or end of any triple quote\n\t// or comment that hangs over the end of the range.  Cap processing in all cases\n\t// to end of document (in case of unclosed quote or comment at end).\n\twhile ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) ||\n\t                                      prevQuote || prevComment)) {\n\n\t\t// Gather info\n\t\tint lev = indentCurrent;\n\t\tSci_Position lineNext = lineCurrent + 1;\n\t\tint indentNext = indentCurrent;\n\t\tint quote = false;\n\t\tif (lineNext <= docLines) {\n\t\t\t// Information about next line is only available if not at end of document\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);\n\t\t\tint style = styler.StyleAt(styler.LineStart(lineNext)) & 31;\n\t\t\tquote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));\n\t\t}\n\t\tconst int quote_start = (quote && !prevQuote);\n\t\tconst int quote_continue = (quote && prevQuote);\n\t\tconst int comment = foldComment && IsCommentLine(lineCurrent, styler);\n\t\tconst int comment_start = (comment && !prevComment && (lineNext <= docLines) &&\n\t\t                           IsCommentLine(lineNext, styler) &&\n\t\t                           (lev > SC_FOLDLEVELBASE));\n\t\tconst int comment_continue = (comment && prevComment);\n\t\tif ((!quote || !prevQuote) && !comment)\n\t\t\tindentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\t\tif (quote)\n\t\t\tindentNext = indentCurrentLevel;\n\t\tif (indentNext & SC_FOLDLEVELWHITEFLAG)\n\t\t\tindentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;\n\n\t\tif (quote_start) {\n\t\t\t// Place fold point at start of triple quoted string\n\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t} else if (quote_continue || prevQuote) {\n\t\t\t// Add level to rest of lines in the string\n\t\t\tlev = lev + 1;\n\t\t} else if (comment_start) {\n\t\t\t// Place fold point at start of a block of comments\n\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t} else if (comment_continue) {\n\t\t\t// Add level to rest of lines in the block\n\t\t\tlev = lev + 1;\n\t\t}\n\n\t\t// Skip past any blank lines for next indent level info; we skip also\n\t\t// comments (all comments, not just those starting in column 0)\n\t\t// which effectively folds them into surrounding code rather\n\t\t// than screwing up folding.\n\n\t\twhile (!quote &&\n\t\t        (lineNext < docLines) &&\n\t\t        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||\n\t\t         (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {\n\n\t\t\tlineNext++;\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);\n\t\t}\n\n\t\tconst int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;\n\t\tconst int levelBeforeComments =\n\t\t    Maximum(indentCurrentLevel,levelAfterComments);\n\n\t\t// Now set all the indent levels on the lines we skipped\n\t\t// Do this from end to start.  Once we encounter one line\n\t\t// which is indented more than the line after the end of\n\t\t// the comment-block, use the level of the block before\n\n\t\tSci_Position skipLine = lineNext;\n\t\tint skipLevel = levelAfterComments;\n\n\t\twhile (--skipLine > lineCurrent) {\n\t\t\tint skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);\n\n\t\t\tif ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)\n\t\t\t\tskipLevel = levelBeforeComments;\n\n\t\t\tint whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;\n\n\t\t\tstyler.SetLevel(skipLine, skipLevel | whiteFlag);\n\t\t}\n\n\t\t// Set fold header on non-quote/non-comment line\n\t\tif (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {\n\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) <\n\t\t\t     (indentNext & SC_FOLDLEVELNUMBERMASK))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t}\n\n\t\t// Keep track of triple quote and block comment state of previous line\n\t\tprevQuote = quote;\n\t\tprevComment = comment_start || comment_continue;\n\n\t\t// Set fold level for this line and move to next line\n\t\tstyler.SetLevel(lineCurrent, lev);\n\t\tindentCurrent = indentNext;\n\t\tlineCurrent = lineNext;\n\t}\n\n\t// NOTE: Cannot set level of last line here because indentCurrent doesn't have\n\t// header flag set; the loop above is crafted to take care of this case!\n\t//styler.SetLevel(lineCurrent, indentCurrent);\n}\n\nstatic const char * const nimrodWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmNimrod(SCLEX_NIMROD, ColouriseNimrodDoc, \"nimrod\", FoldNimrodDoc,\n\t\t\t\t     nimrodWordListDesc);\n"
  },
  {
    "path": "lexers/LexNix.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexNix.cxx\n ** Lexer for Nix.\n **/\n// Based on Zufu Liu's Notepad4 Dart lexer\n// Modified for Nix and Scintilla by Jiri Techet, 2024\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n// Use an unnamed namespace to protect the functions and classes from name conflicts\n\nconstexpr bool IsAGraphic(int ch) noexcept {\n\t// excludes C0 control characters and whitespace\n\treturn ch > 32 && ch < 127;\n}\n\nconstexpr bool IsIdentifierChar(int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '_' || ch == '\\'' || ch == '-';\n}\n\nconstexpr bool IsIdentifierStart(int ch) noexcept {\n\treturn IsUpperOrLowerCase(ch) || ch == '_';\n}\n\nconstexpr bool IsNumberContinue(int chPrev, int ch, int chNext) noexcept {\n\treturn ((ch == '+' || ch == '-') && (chPrev == 'e' || chPrev == 'E'))\n\t\t|| (ch == '.' && chNext != '.');\n}\n\nconstexpr bool IsNumberStart(int ch, int chNext) noexcept {\n\treturn IsADigit(ch) || (ch == '.' && IsADigit(chNext));\n}\n\nconstexpr bool IsDecimalNumber(int chPrev, int ch, int chNext) noexcept {\n\treturn IsIdentifierChar(ch) || IsNumberContinue(chPrev, ch, chNext);\n}\n\nconstexpr bool IsNixIdentifierStart(int ch) noexcept {\n\treturn IsIdentifierStart(ch);\n}\n\nconstexpr bool IsNixIdentifierChar(int ch) noexcept {\n\treturn IsIdentifierChar(ch);\n}\n\nconstexpr bool IsPathTerminator(int ch) noexcept {\n\treturn isspacechar(ch) || AnyOf(ch, ';', ',', ']', '}', ')');\n}\n\nbool IsKey(LexAccessor &styler, Sci_Position start) {\n\tfor (Sci_Position i = 0; i < 50; i++) {\n\t\tchar curr = styler.SafeGetCharAt(start+i, '\\0');\n\t\tchar next = styler.SafeGetCharAt(start+i+1, '\\0');\n\t\tbool atEOL = (curr == '\\r' && next != '\\n') || (curr == '\\n') || (curr == '\\0');\n\t\tif (curr == '=') {\n\t\t\treturn true;\n\t\t} else if (!isspacechar(curr) || atEOL) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn false;\n}\n\nbool IsPath(LexAccessor &styler, Sci_Position start) {\n\tfor (Sci_Position i = 0; i < 50; i++) {\n\t\tchar curr = styler.SafeGetCharAt(start+i, '\\0');\n\t\tchar next = styler.SafeGetCharAt(start+i+1, '\\0');\n\t\tbool atEOL = (curr == '\\r' && next != '\\n') || (curr == '\\n') || (curr == '\\0');\n\t\tif (curr == '/') {\n\t\t\treturn true;\n\t\t} else if (IsPathTerminator(curr) || curr == '$' || atEOL) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn false;\n}\n\nenum {\n\tNixLineStateMaskInterpolation = 1,\t// string interpolation\n};\n\n// string interpolating state\nstruct InterpolatingState {\n\tint state;\n\tint braceCount;\n};\n\n// Options used for LexerNix\nstruct OptionsNix {\n\tbool fold = false;\n};\n\nconst char * const nixWordListDesc[] = {\n\t\"Keywords 1\",\n\t\"Keywords 2\",\n\t\"Keywords 3\",\n\t\"Keywords 4\",\n\tnullptr\n};\n\nstruct OptionSetNix : public OptionSet<OptionsNix> {\n\tOptionSetNix() {\n\t\tDefineProperty(\"fold\", &OptionsNix::fold);\n\n\t\tDefineWordListSets(nixWordListDesc);\n\t}\n};\n\n\nLexicalClass lexicalClasses[] = {\n\t// Lexer NIX SCLEX_NIX SCE_NIX_:\n\t0, \"SCE_NIX_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_NIX_COMMENTLINE\", \"comment line\", \"Comment: //\",\n\t2, \"SCE_NIX_COMMENTBLOCK\", \"comment\", \"Comment: /* */\",\n\t3, \"SCE_NIX_STRING\", \"literal string\", \"Double quoted string\",\n\t4, \"SCE_NIX_STRING_MULTILINE\", \"literal string multiline\", \"Single quoted multiline string\",\n\t5, \"SCE_NIX_ESCAPECHAR\", \"literal string escapesequence\", \"Escape sequence\",\n\t6, \"SCE_NIX_IDENTIFIER\", \"identifier\", \"Identifier\",\n\t7, \"SCE_NIX_OPERATOR\", \"operator\", \"Operator\",\n\t8, \"SCE_NIX_OPERATOR_STRING\", \"operator interpolated\", \"Braces following $ inside string\",\n\t9, \"SCE_NIX_NUMBER\", \"literal numeric\", \"Number\",\n\t10, \"SCE_NIX_KEY\", \"key\", \"Keys preceding '='\",\n\t11, \"SCE_NIX_PATH\", \"identifier\", \"Path literal\",\n\t12, \"SCE_NIX_KEYWORD1\", \"keyword\", \"Primary keywords\",\n\t13, \"SCE_NIX_KEYWORD2\", \"identifier\", \"Keywords 2\",\n\t14, \"SCE_NIX_KEYWORD3\", \"identifier\", \"Keywords 3\",\n\t15, \"SCE_NIX_KEYWORD4\", \"identifier\", \"Keywords 4\",\n\t16, \"SCE_NIX_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n};\n\nclass LexerNix : public DefaultLexer {\n\tWordList keywordsPrimary;\n\tWordList keywordsSecondary;\n\tWordList keywordsTertiary;\n\tWordList keywordsTypes;\n\tOptionsNix options;\n\tOptionSetNix osNix;\npublic:\n\tLexerNix(const char *languageName_, int language_) :\n\t\tDefaultLexer(languageName_, language_, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\t// Deleted so LexerNix objects can not be copied.\n\tLexerNix(const LexerNix &) = delete;\n\tLexerNix(LexerNix &&) = delete;\n\tvoid operator=(const LexerNix &) = delete;\n\tvoid operator=(LexerNix &&) = delete;\n\t~LexerNix() override = default;\n\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osNix.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osNix.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osNix.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osNix.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osNix.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn nullptr;\n\t}\n\n\tvoid BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle);\n\n\tstatic ILexer5 *LexerFactoryNix() {\n\t\treturn new LexerNix(\"nix\", SCLEX_NIX);\n\t}\n};\n\nSci_Position SCI_METHOD LexerNix::PropertySet(const char *key, const char *val) {\n\tif (osNix.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerNix::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywordsPrimary;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywordsSecondary;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywordsTertiary;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywordsTypes;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN && wordListN->Set(wl/*, false*/)) {\n\t\tfirstModification = 0;\n\t}\n\treturn firstModification;\n}\n\nvoid LexerNix::BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle) {\n\tconst Sci_Position currentLine = styler.GetLine(startPos);\n\tif (currentLine != 0) {\n\t\tSci_Position line = currentLine - 1;\n\t\tint lineState = styler.GetLineState(line);\n\t\twhile ((lineState & stateMask) != 0 && line != 0) {\n\t\t\t--line;\n\t\t\tlineState = styler.GetLineState(line);\n\t\t}\n\t\tif ((lineState & stateMask) == 0) {\n\t\t\t++line;\n\t\t}\n\t\tif (line != currentLine) {\n\t\t\tconst Sci_PositionU endPos = startPos + lengthDoc;\n\t\t\tstartPos = (line == 0) ? 0 : styler.LineStart(line);\n\t\t\tlengthDoc = endPos - startPos;\n\t\t\tinitStyle = (startPos == 0) ? 0 : styler.StyleAt(startPos - 1);\n\t\t}\n\t}\n}\n\nvoid LexerNix::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\n\tstd::vector<InterpolatingState> interpolatingStack;\n\n\tif (initStyle == SCE_NIX_STRINGEOL) {\n\t\tinitStyle = SCE_NIX_DEFAULT;\n\t}\n\n\tif (startPos != 0) {\n\t\t// backtrack to the line where interpolation starts\n\t\tBacktrackToStart(styler, NixLineStateMaskInterpolation, startPos, lengthDoc, initStyle);\n\t}\n\n\tStyleContext sc(startPos, lengthDoc, initStyle, styler);\n\n\twhile (sc.More()) {\n\t\tswitch (sc.state) {\n\t\tcase SCE_NIX_OPERATOR:\n\t\tcase SCE_NIX_OPERATOR_STRING:\n\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_NUMBER:\n\t\t\tif (!IsDecimalNumber(sc.chPrev, sc.ch, sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_IDENTIFIER:\n\t\t\tif (sc.state == SCE_NIX_IDENTIFIER && !IsNixIdentifierChar(sc.ch)) {\n\t\t\t\tchar s[64];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\tif (IsKey(styler, sc.currentPos)) {\n\t\t\t\t\tsc.ChangeState(SCE_NIX_KEY);\n\t\t\t\t} else if (keywordsPrimary.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_NIX_KEYWORD1);\n\t\t\t\t} else if (keywordsSecondary.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_NIX_KEYWORD2);\n\t\t\t\t} else if (keywordsTertiary.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_NIX_KEYWORD3);\n\t\t\t\t} else if (keywordsTypes.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_NIX_KEYWORD4);\n\t\t\t\t}\n\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_COMMENTLINE:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_COMMENTBLOCK:\n\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\tsc.Forward(2);\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_STRING:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_NIX_STRINGEOL);\n\t\t\t} else if (sc.ch == '\\\\' && AnyOf(sc.chNext, '\"', '\\\\', 'n', 'r', 't', '$')) {\n\t\t\t\tsc.SetState(SCE_NIX_STRING);\n\t\t\t\tsc.ChangeState(SCE_NIX_ESCAPECHAR);\n\t\t\t\tsc.Forward(2);\n\t\t\t\tsc.SetState(SCE_NIX_STRING);\n\t\t\t\tcontinue;\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t\tcontinue;\n\t\t\t} else if (sc.Match('$','$')) {\n\t\t\t\tsc.Forward();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_STRINGEOL:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_PATH:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t} else if (sc.ch == '>') {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t\tcontinue;\n\t\t\t} else if (IsPathTerminator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_STRING_MULTILINE:\n\t\t\tif (sc.ch == '\\'' && sc.chNext == '\\'') {\n\t\t\t\tif (AnyOf(styler.SafeGetCharAt(sc.currentPos+2, '\\0'), '$', '\\'', '\\\\')) {\n\t\t\t\t\tsc.SetState(SCE_NIX_ESCAPECHAR);\n\t\t\t\t\tsc.Forward(2);\n\t\t\t\t\tif (sc.ch == '$' || sc.ch == '\\'') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\t\tsc.Forward(2);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_NIX_STRING_MULTILINE);\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tsc.Forward(2);\n\t\t\t\t\tsc.SetState(SCE_NIX_DEFAULT);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else if (sc.Match('$','$')) {\n\t\t\t\tsc.Forward();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (sc.state == SCE_NIX_DEFAULT)\n\t\t{\n\t\t\tif (sc.ch == '/' && sc.chNext == '*') {\n\t\t\t\tsc.SetState(SCE_NIX_COMMENTBLOCK);\n\t\t\t\tsc.Forward();\n\t\t\t\tcontinue;\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_NIX_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\"') {\n\t\t\t\tsc.SetState(SCE_NIX_STRING);\n\t\t\t} else if (sc.ch == '\\'' && sc.chNext == '\\'') {\n\t\t\t\tsc.SetState(SCE_NIX_STRING_MULTILINE);\n\t\t\t\tsc.Forward();\n\t\t\t\tcontinue;\n\t\t\t} else if (IsNumberStart(sc.ch, sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_NIX_NUMBER);\n\t\t\t} else if (sc.ch == '<') {\n\t\t\t\tsc.SetState(SCE_NIX_PATH);\n\t\t\t} else if ((IsNixIdentifierStart(sc.ch) || AnyOf(sc.ch, '~', '.', '/')) &&\n\t\t\t\t\tIsPath(styler, sc.currentPos)) {\n\t\t\t\tsc.SetState(SCE_NIX_PATH);\n\t\t\t} else if (IsNixIdentifierStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_NIX_IDENTIFIER);\n\t\t\t} else if (IsAGraphic(sc.ch) && sc.ch != '$') {\n\t\t\t\tsc.SetState(SCE_NIX_OPERATOR);\n\t\t\t\tif (!interpolatingStack.empty() && AnyOf(sc.ch, '{', '}')) {\n\t\t\t\t\tInterpolatingState &current = interpolatingStack.back();\n\t\t\t\t\tif (sc.ch == '{') {\n\t\t\t\t\t\tcurrent.braceCount += 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent.braceCount -= 1;\n\t\t\t\t\t\tif (current.braceCount == 0) {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_NIX_OPERATOR_STRING);\n\t\t\t\t\t\t\tsc.ForwardSetState(current.state);\n\t\t\t\t\t\t\tinterpolatingStack.pop_back();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// string interpolations\n\t\tif (AnyOf(sc.state, SCE_NIX_DEFAULT, SCE_NIX_STRING, SCE_NIX_STRING_MULTILINE, SCE_NIX_PATH)) {\n\t\t\tif (sc.Match('$','{')) {\n\t\t\t\tinterpolatingStack.push_back({sc.state, 1});\n\t\t\t\tsc.SetState(SCE_NIX_OPERATOR_STRING);\n\t\t\t\tsc.Forward();\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\tint lineState = 0;\n\t\t\tif (!interpolatingStack.empty()) {\n\t\t\t\tlineState |= NixLineStateMaskInterpolation;\n\t\t\t}\n\t\t\tstyler.SetLineState(sc.currentLine, lineState);\n\t\t}\n\n\t\tsc.Forward();\n\t}\n\n\tsc.Complete();\n}\n\nvoid LexerNix::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {\n\tif (!options.fold)\n\t\treturn;\n\n\tAccessor styler(pAccess, nullptr);\n\tconst Sci_PositionU endPos = startPos + lengthDoc;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\twhile (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tstartPos = styler.LineStart(lineCurrent);\n\t\tinitStyle = (startPos > 0) ? styler.StyleIndexAt(startPos) : 0;\n\t\tif (!AnyOf(initStyle, SCE_NIX_COMMENTBLOCK, SCE_NIX_STRING_MULTILINE)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0) {\n\t\tlevelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;\n\t}\n\n\tint levelNext = levelCurrent;\n\tSci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1);\n\tlineStartNext = std::min(lineStartNext, endPos);\n\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleIndexAt(startPos);\n\tint style = initStyle;\n\n\twhile (startPos < endPos) {\n\t\tconst char ch = chNext;\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tchNext = styler[++startPos];\n\t\tstyleNext = styler.StyleIndexAt(startPos);\n\n\t\tswitch (style) {\n\t\tcase SCE_NIX_COMMENTBLOCK:\n\t\t\tif (style != stylePrev) {\n\t\t\t\tlevelNext++;\n\t\t\t}\n\t\t\tif (style != styleNext) {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_STRING_MULTILINE:\n\t\t\tif (style != stylePrev && !AnyOf(stylePrev, SCE_NIX_ESCAPECHAR, SCE_NIX_OPERATOR_STRING)) {\n\t\t\t\tlevelNext++;\n\t\t\t}\n\t\t\tif (style != styleNext && !AnyOf(styleNext, SCE_NIX_ESCAPECHAR, SCE_NIX_OPERATOR_STRING)) {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_NIX_OPERATOR:\n\t\tcase SCE_NIX_OPERATOR_STRING:\n\t\t\tif (ch == '{' || ch == '[' || ch == '(') {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}' || ch == ']' || ch == ')') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (startPos == lineStartNext) {\n\t\t\tlevelNext = std::max(levelNext, SC_FOLDLEVELBASE);\n\n\t\t\tconst int levelUse = levelCurrent;\n\t\t\tint lev = levelUse | (levelNext << 16);\n\t\t\tif (levelUse < levelNext) {\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tstyler.SetLevel(lineCurrent, lev);\n\n\t\t\tlineCurrent++;\n\t\t\tlineStartNext = styler.LineStart(lineCurrent + 1);\n\t\t\tlineStartNext = std::min(lineStartNext, endPos);\n\t\t\tlevelCurrent = levelNext;\n\t\t}\n\t}\n}\n\n}  // unnamed namespace end\n\nextern const LexerModule lmNix(SCLEX_NIX, LexerNix::LexerFactoryNix, \"nix\", nixWordListDesc);\n"
  },
  {
    "path": "lexers/LexNsis.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexNsis.cxx\n ** Lexer for NSIS\n **/\n// Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>\n// Last Updated: 03/13/2005\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n/*\n// located in SciLexer.h\n#define SCLEX_NSIS 43\n\n#define SCE_NSIS_DEFAULT 0\n#define SCE_NSIS_COMMENT 1\n#define SCE_NSIS_STRINGDQ 2\n#define SCE_NSIS_STRINGLQ 3\n#define SCE_NSIS_STRINGRQ 4\n#define SCE_NSIS_FUNCTION 5\n#define SCE_NSIS_VARIABLE 6\n#define SCE_NSIS_LABEL 7\n#define SCE_NSIS_USERDEFINED 8\n#define SCE_NSIS_SECTIONDEF 9\n#define SCE_NSIS_SUBSECTIONDEF 10\n#define SCE_NSIS_IFDEFINEDEF 11\n#define SCE_NSIS_MACRODEF 12\n#define SCE_NSIS_STRINGVAR 13\n#define SCE_NSIS_NUMBER 14\n// ADDED for Scintilla v1.63\n#define SCE_NSIS_SECTIONGROUP 15\n#define SCE_NSIS_PAGEEX 16\n#define SCE_NSIS_FUNCTIONDEF 17\n#define SCE_NSIS_COMMENTBOX 18\n*/\n\nstatic bool isNsisNumber(char ch)\n{\n  return (ch >= '0' && ch <= '9');\n}\n\nstatic bool isNsisChar(char ch)\n{\n  return (ch == '.' ) || (ch == '_' ) || isNsisNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');\n}\n\nstatic bool isNsisLetter(char ch)\n{\n  return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');\n}\n\nstatic bool NsisNextLineHasElse(Sci_PositionU start, Sci_PositionU end, Accessor &styler)\n{\n  Sci_Position nNextLine = -1;\n  for( Sci_PositionU i = start; i < end; i++ )\n  {\n    char cNext = styler.SafeGetCharAt( i );\n    if( cNext == '\\n' )\n    {\n      nNextLine = i+1;\n      break;\n    }\n  }\n\n  if( nNextLine == -1 ) // We never found the next line...\n    return false;\n\n  for( Sci_PositionU firstChar = nNextLine; firstChar < end; firstChar++ )\n  {\n    char cNext = styler.SafeGetCharAt( firstChar );\n    if( cNext == ' ' )\n      continue;\n    if( cNext == '\\t' )\n      continue;\n    if( cNext == '!' )\n    {\n      if( styler.Match(firstChar, \"!else\") )\n        return true;\n    }\n    break;\n  }\n\n  return false;\n}\n\nstatic int NsisCmp( const char *s1, const char *s2, bool bIgnoreCase )\n{\n  if( bIgnoreCase )\n     return CompareCaseInsensitive( s1, s2);\n\n  return strcmp( s1, s2 );\n}\n\nstatic int calculateFoldNsis(Sci_PositionU start, Sci_PositionU end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )\n{\n  int style = styler.StyleAt(end);\n\n  // If the word is too long, it is not what we are looking for\n  if( end - start > 20 )\n    return foldlevel;\n\n  if( foldUtilityCmd )\n  {\n    // Check the style at this point, if it is not valid, then return zero\n    if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&\n        style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&\n        style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&\n        style != SCE_NSIS_PAGEEX )\n          return foldlevel;\n  }\n  else\n  {\n    if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&\n        style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&\n        style != SCE_NSIS_PAGEEX )\n          return foldlevel;\n  }\n\n  int newFoldlevel = foldlevel;\n  bool bIgnoreCase = false;\n  // property nsis.ignorecase\n  // Set to 1 to ignore case for NSIS.\n  if( styler.GetPropertyInt(\"nsis.ignorecase\") == 1 )\n    bIgnoreCase = true;\n\n  char s[20]; // The key word we are looking for has atmost 13 characters\n  s[0] = '\\0';\n  for (Sci_PositionU i = 0; i < end - start + 1 && i < 19; i++)\n\t{\n\t\ts[i] = static_cast<char>( styler[ start + i ] );\n\t\ts[i + 1] = '\\0';\n\t}\n\n  if( s[0] == '!' )\n  {\n    if( NsisCmp(s, \"!ifndef\", bIgnoreCase) == 0 || NsisCmp(s, \"!ifdef\", bIgnoreCase ) == 0 || NsisCmp(s, \"!ifmacrodef\", bIgnoreCase ) == 0 || NsisCmp(s, \"!ifmacrondef\", bIgnoreCase ) == 0 || NsisCmp(s, \"!if\", bIgnoreCase ) == 0 || NsisCmp(s, \"!macro\", bIgnoreCase ) == 0 )\n      newFoldlevel++;\n    else if( NsisCmp(s, \"!endif\", bIgnoreCase) == 0 || NsisCmp(s, \"!macroend\", bIgnoreCase ) == 0 )\n      newFoldlevel--;\n    else if( bElse && NsisCmp(s, \"!else\", bIgnoreCase) == 0 )\n      newFoldlevel++;\n  }\n  else\n  {\n    if( NsisCmp(s, \"Section\", bIgnoreCase ) == 0 || NsisCmp(s, \"SectionGroup\", bIgnoreCase ) == 0 || NsisCmp(s, \"Function\", bIgnoreCase) == 0 || NsisCmp(s, \"SubSection\", bIgnoreCase ) == 0 || NsisCmp(s, \"PageEx\", bIgnoreCase ) == 0 )\n      newFoldlevel++;\n    else if( NsisCmp(s, \"SectionGroupEnd\", bIgnoreCase ) == 0 || NsisCmp(s, \"SubSectionEnd\", bIgnoreCase ) == 0 || NsisCmp(s, \"FunctionEnd\", bIgnoreCase) == 0 || NsisCmp(s, \"SectionEnd\", bIgnoreCase ) == 0 || NsisCmp(s, \"PageExEnd\", bIgnoreCase ) == 0 )\n      newFoldlevel--;\n  }\n\n  return newFoldlevel;\n}\n\nstatic int classifyWordNsis(Sci_PositionU start, Sci_PositionU end, WordList *keywordLists[], Accessor &styler )\n{\n  bool bIgnoreCase = false;\n  if( styler.GetPropertyInt(\"nsis.ignorecase\") == 1 )\n    bIgnoreCase = true;\n\n  bool bUserVars = false;\n  // property nsis.uservars\n  // Set to 1 to recognise user defined variables in NSIS.\n  if( styler.GetPropertyInt(\"nsis.uservars\") == 1 )\n    bUserVars = true;\n\n\tchar s[100];\n\ts[0] = '\\0';\n\ts[1] = '\\0';\n\n\tWordList &Functions = *keywordLists[0];\n\tWordList &Variables = *keywordLists[1];\n\tWordList &Lables = *keywordLists[2];\n\tWordList &UserDefined = *keywordLists[3];\n\n\tfor (Sci_PositionU i = 0; i < end - start + 1 && i < 99; i++)\n\t{\n    if( bIgnoreCase )\n      s[i] = static_cast<char>( tolower(styler[ start + i ] ) );\n    else\n\t\t  s[i] = static_cast<char>( styler[ start + i ] );\n\t\ts[i + 1] = '\\0';\n\t}\n\n\t// Check for special words...\n\tif( NsisCmp(s, \"!macro\", bIgnoreCase ) == 0 || NsisCmp(s, \"!macroend\", bIgnoreCase) == 0 ) // Covers !macro and !macroend\n\t\treturn SCE_NSIS_MACRODEF;\n\n\tif( NsisCmp(s, \"!ifdef\", bIgnoreCase ) == 0 ||  NsisCmp(s, \"!ifndef\", bIgnoreCase) == 0 ||  NsisCmp(s, \"!endif\", bIgnoreCase) == 0 ) // Covers !ifdef, !ifndef and !endif\n\t\treturn SCE_NSIS_IFDEFINEDEF;\n\n\tif( NsisCmp(s, \"!if\", bIgnoreCase ) == 0 || NsisCmp(s, \"!else\", bIgnoreCase )  == 0 ) // Covers !if and else\n\t\treturn SCE_NSIS_IFDEFINEDEF;\n\n\tif (NsisCmp(s, \"!ifmacrodef\", bIgnoreCase ) == 0 || NsisCmp(s, \"!ifmacrondef\", bIgnoreCase )  == 0 ) // Covers !ifmacrodef and !ifnmacrodef\n\t\treturn SCE_NSIS_IFDEFINEDEF;\n\n  if( NsisCmp(s, \"SectionGroup\", bIgnoreCase) == 0 || NsisCmp(s, \"SectionGroupEnd\", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd\n    return SCE_NSIS_SECTIONGROUP;\n\n\tif( NsisCmp(s, \"Section\", bIgnoreCase ) == 0 || NsisCmp(s, \"SectionEnd\", bIgnoreCase) == 0 ) // Covers Section and SectionEnd\n\t\treturn SCE_NSIS_SECTIONDEF;\n\n\tif( NsisCmp(s, \"SubSection\", bIgnoreCase) == 0 || NsisCmp(s, \"SubSectionEnd\", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd\n\t\treturn SCE_NSIS_SUBSECTIONDEF;\n\n  if( NsisCmp(s, \"PageEx\", bIgnoreCase) == 0 || NsisCmp(s, \"PageExEnd\", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd\n    return SCE_NSIS_PAGEEX;\n\n\tif( NsisCmp(s, \"Function\", bIgnoreCase) == 0 || NsisCmp(s, \"FunctionEnd\", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd\n\t\treturn SCE_NSIS_FUNCTIONDEF;\n\n\tif ( Functions.InList(s) )\n\t\treturn SCE_NSIS_FUNCTION;\n\n\tif ( Variables.InList(s) )\n\t\treturn SCE_NSIS_VARIABLE;\n\n\tif ( Lables.InList(s) )\n\t\treturn SCE_NSIS_LABEL;\n\n\tif( UserDefined.InList(s) )\n\t\treturn SCE_NSIS_USERDEFINED;\n\n\tif( strlen(s) > 3 )\n\t{\n\t\tif( s[1] == '{' && s[strlen(s)-1] == '}' )\n\t\t\treturn SCE_NSIS_VARIABLE;\n\t}\n\n  // See if the variable is a user defined variable\n  if( s[0] == '$' && bUserVars )\n  {\n    bool bHasSimpleNsisChars = true;\n    for (Sci_PositionU j = 1; j < end - start + 1 && j < 99; j++)\n\t  {\n      if( !isNsisChar( s[j] ) )\n      {\n        bHasSimpleNsisChars = false;\n        break;\n      }\n\t  }\n\n    if( bHasSimpleNsisChars )\n      return SCE_NSIS_VARIABLE;\n  }\n\n  // To check for numbers\n  if( isNsisNumber( s[0] ) )\n  {\n    bool bHasSimpleNsisNumber = true;\n    for (Sci_PositionU j = 1; j < end - start + 1 && j < 99; j++)\n\t  {\n      if( !isNsisNumber( s[j] ) )\n      {\n        bHasSimpleNsisNumber = false;\n        break;\n      }\n\t  }\n\n    if( bHasSimpleNsisNumber )\n      return SCE_NSIS_NUMBER;\n  }\n\n\treturn SCE_NSIS_DEFAULT;\n}\n\nstatic void ColouriseNsisDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler)\n{\n\tint state = SCE_NSIS_DEFAULT;\n  if( startPos > 0 )\n    state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox\n\n\tstyler.StartAt( startPos );\n\tstyler.GetLine( startPos );\n\n\tSci_PositionU nLengthDoc = startPos + length;\n\tstyler.StartSegment( startPos );\n\n\tchar cCurrChar;\n\tbool bVarInString = false;\n  bool bClassicVarInString = false;\n\n\tSci_PositionU i;\n\tfor( i = startPos; i < nLengthDoc; i++ )\n\t{\n\t\tcCurrChar = styler.SafeGetCharAt( i );\n\t\tchar cNextChar = styler.SafeGetCharAt(i+1);\n\n\t\tswitch(state)\n\t\t{\n\t\t\tcase SCE_NSIS_DEFAULT:\n\t\t\t\tif( cCurrChar == ';' || cCurrChar == '#' ) // we have a comment line\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(i-1, state );\n\t\t\t\t\tstate = SCE_NSIS_COMMENT;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif( cCurrChar == '\"' )\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(i-1, state );\n\t\t\t\t\tstate = SCE_NSIS_STRINGDQ;\n\t\t\t\t\tbVarInString = false;\n          bClassicVarInString = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif( cCurrChar == '\\'' )\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(i-1, state );\n\t\t\t\t\tstate = SCE_NSIS_STRINGRQ;\n\t\t\t\t\tbVarInString = false;\n          bClassicVarInString = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif( cCurrChar == '`' )\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(i-1, state );\n\t\t\t\t\tstate = SCE_NSIS_STRINGLQ;\n\t\t\t\t\tbVarInString = false;\n          bClassicVarInString = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// NSIS KeyWord,Function, Variable, UserDefined:\n\t\t\t\tif( cCurrChar == '$' || isNsisChar(cCurrChar) || cCurrChar == '!' )\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(i-1,state);\n\t\t\t\t  state = SCE_NSIS_FUNCTION;\n\n          // If it is a number, we must check and set style here first...\n          if( isNsisNumber(cCurrChar) && (cNextChar == '\\t' || cNextChar == ' ' || cNextChar == '\\r' || cNextChar == '\\n' ) )\n              styler.ColourTo( i, SCE_NSIS_NUMBER);\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n        if( cCurrChar == '/' && cNextChar == '*' )\n        {\n          styler.ColourTo(i-1,state);\n          state = SCE_NSIS_COMMENTBOX;\n          break;\n        }\n\n\t\t\t\tbreak;\n\t\t\tcase SCE_NSIS_COMMENT:\n\t\t\t\tif( cNextChar == '\\n' || cNextChar == '\\r' )\n        {\n          // Special case:\n          if( cCurrChar == '\\\\' )\n          {\n            styler.ColourTo(i-2,state);\n            styler.ColourTo(i,SCE_NSIS_DEFAULT);\n          }\n          else\n          {\n\t\t\t\t    styler.ColourTo(i,state);\n            state = SCE_NSIS_DEFAULT;\n          }\n        }\n\t\t\t\tbreak;\n\t\t\tcase SCE_NSIS_STRINGDQ:\n      case SCE_NSIS_STRINGLQ:\n      case SCE_NSIS_STRINGRQ:\n\n        if( styler.SafeGetCharAt(i-1) == '\\\\' && styler.SafeGetCharAt(i-2) == '$' )\n          break; // Ignore the next character, even if it is a quote of some sort\n\n        if( cCurrChar == '\"' && state == SCE_NSIS_STRINGDQ )\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(i,state);\n\t\t\t\t  state = SCE_NSIS_DEFAULT;\n          break;\n\t\t\t\t}\n\n        if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )\n        {\n\t\t\t\t\tstyler.ColourTo(i,state);\n\t\t\t\t  state = SCE_NSIS_DEFAULT;\n          break;\n\t\t\t\t}\n\n        if( cCurrChar == '\\'' && state == SCE_NSIS_STRINGRQ )\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo(i,state);\n\t\t\t\t  state = SCE_NSIS_DEFAULT;\n          break;\n\t\t\t\t}\n\n        if( cNextChar == '\\r' || cNextChar == '\\n' )\n        {\n          Sci_Position nCurLine = styler.GetLine(i+1);\n          Sci_Position nBack = i;\n          // We need to check if the previous line has a \\ in it...\n          bool bNextLine = false;\n\n          while( nBack > 0 )\n          {\n            if( styler.GetLine(nBack) != nCurLine )\n              break;\n\n            char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here\n\n            if( cTemp == '\\\\' )\n            {\n              bNextLine = true;\n              break;\n            }\n            if( cTemp != '\\r' && cTemp != '\\n' && cTemp != '\\t' && cTemp != ' ' )\n              break;\n\n            nBack--;\n          }\n\n          if( bNextLine )\n          {\n            styler.ColourTo(i+1,state);\n          }\n          if( bNextLine == false )\n          {\n            styler.ColourTo(i,state);\n\t\t\t\t    state = SCE_NSIS_DEFAULT;\n          }\n        }\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_NSIS_FUNCTION:\n\n\t\t\t\t// NSIS KeyWord:\n        if( cCurrChar == '$' )\n          state = SCE_NSIS_DEFAULT;\n        else if( cCurrChar == '\\\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )\n          state = SCE_NSIS_DEFAULT;\n\t\t\t\telse if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )\n\t\t\t\t{\n\t\t\t\t\tstate = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );\n\t\t\t\t\tstyler.ColourTo( i, state);\n\t\t\t\t\tstate = SCE_NSIS_DEFAULT;\n\t\t\t\t}\n\t\t\t\telse if( !isNsisChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' )\n\t\t\t\t{\n          if( classifyWordNsis( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_NSIS_NUMBER )\n             styler.ColourTo( i-1, SCE_NSIS_NUMBER );\n\n\t\t\t\t\tstate = SCE_NSIS_DEFAULT;\n\n\t\t\t\t\tif( cCurrChar == '\"' )\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = SCE_NSIS_STRINGDQ;\n\t\t\t\t\t\tbVarInString = false;\n            bClassicVarInString = false;\n\t\t\t\t\t}\n\t\t\t\t\telse if( cCurrChar == '`' )\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = SCE_NSIS_STRINGLQ;\n\t\t\t\t\t\tbVarInString = false;\n            bClassicVarInString = false;\n\t\t\t\t\t}\n\t\t\t\t\telse if( cCurrChar == '\\'' )\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = SCE_NSIS_STRINGRQ;\n\t\t\t\t\t\tbVarInString = false;\n            bClassicVarInString = false;\n\t\t\t\t\t}\n\t\t\t\t\telse if( cCurrChar == '#' || cCurrChar == ';' )\n          {\n\t\t\t\t\t\tstate = SCE_NSIS_COMMENT;\n          }\n\t\t\t\t}\n\t\t\t\tbreak;\n      case SCE_NSIS_COMMENTBOX:\n\n        if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )\n        {\n          styler.ColourTo(i,state);\n          state = SCE_NSIS_DEFAULT;\n        }\n        break;\n\t\t}\n\n\t\tif( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )\n\t\t{\n\t\t\tstyler.ColourTo(i,state);\n\t\t}\n\t\telse if( state == SCE_NSIS_STRINGDQ || state == SCE_NSIS_STRINGLQ || state == SCE_NSIS_STRINGRQ )\n\t\t{\n      bool bIngoreNextDollarSign = false;\n      bool bUserVars = false;\n      if( styler.GetPropertyInt(\"nsis.uservars\") == 1 )\n        bUserVars = true;\n\n      if( bVarInString && cCurrChar == '$' )\n      {\n        bVarInString = false;\n        bIngoreNextDollarSign = true;\n      }\n      else if( bVarInString && cCurrChar == '\\\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '\"' || cNextChar == '`' || cNextChar == '\\'' ) )\n      {\n        styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);\n        bVarInString = false;\n        bIngoreNextDollarSign = false;\n      }\n\n      // Covers \"$INSTDIR and user vars like $MYVAR\"\n      else if( bVarInString && !isNsisChar(cNextChar) )\n      {\n        int nWordState = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);\n\t\t\t\tif( nWordState == SCE_NSIS_VARIABLE )\n\t\t\t\t\tstyler.ColourTo( i, SCE_NSIS_STRINGVAR);\n        else if( bUserVars )\n          styler.ColourTo( i, SCE_NSIS_STRINGVAR);\n        bVarInString = false;\n      }\n      // Covers \"${TEST}...\"\n      else if( bClassicVarInString && cNextChar == '}' )\n      {\n        styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);\n\t\t\t\tbClassicVarInString = false;\n      }\n\n      // Start of var in string\n\t\t\tif( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' )\n\t\t\t{\n\t\t\t\tstyler.ColourTo( i-1, state);\n\t\t\t\tbClassicVarInString = true;\n        bVarInString = false;\n\t\t\t}\n      else if( !bIngoreNextDollarSign && cCurrChar == '$' )\n      {\n        styler.ColourTo( i-1, state);\n        bVarInString = true;\n        bClassicVarInString = false;\n      }\n\t\t}\n\t}\n\n  // Colourise remaining document\n\tstyler.ColourTo(nLengthDoc-1,state);\n}\n\nstatic void FoldNsisDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)\n{\n\t// No folding enabled, no reason to continue...\n\tif( styler.GetPropertyInt(\"fold\") == 0 )\n\t\treturn;\n\n  bool foldAtElse = styler.GetPropertyInt(\"fold.at.else\", 0) == 1;\n  bool foldUtilityCmd = styler.GetPropertyInt(\"nsis.foldutilcmd\", 1) == 1;\n  bool blockComment = false;\n\n  Sci_Position lineCurrent = styler.GetLine(startPos);\n  Sci_PositionU safeStartPos = styler.LineStart( lineCurrent );\n\n  bool bArg1 = true;\n  Sci_Position nWordStart = -1;\n\n  int levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelNext = levelCurrent;\n  int style = styler.StyleAt(safeStartPos);\n  if( style == SCE_NSIS_COMMENTBOX )\n  {\n    if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )\n      levelNext++;\n    blockComment = true;\n  }\n\n  for (Sci_PositionU i = safeStartPos; i < startPos + length; i++)\n\t{\n    char chCurr = styler.SafeGetCharAt(i);\n    style = styler.StyleAt(i);\n    if( blockComment && style != SCE_NSIS_COMMENTBOX )\n    {\n      levelNext--;\n      blockComment = false;\n    }\n    else if( !blockComment && style == SCE_NSIS_COMMENTBOX )\n    {\n      levelNext++;\n      blockComment = true;\n    }\n\n    if( bArg1 && !blockComment)\n    {\n      if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )\n      {\n        nWordStart = i;\n      }\n      else if( isNsisLetter(chCurr) == false && nWordStart > -1 )\n      {\n        int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );\n\n        if( newLevel == levelNext )\n        {\n          if( foldAtElse && foldUtilityCmd )\n          {\n            if( NsisNextLineHasElse(i, startPos + length, styler) )\n              levelNext--;\n          }\n        }\n        else\n          levelNext = newLevel;\n        bArg1 = false;\n      }\n    }\n\n    if( chCurr == '\\n' )\n    {\n      if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )\n      {\n        if( NsisNextLineHasElse(i, startPos + length, styler) )\n          levelNext--;\n      }\n\n      // If we are on a new line...\n      int levelUse = levelCurrent;\n\t\t\tint lev = levelUse | levelNext << 16;\n      if (levelUse < levelNext )\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent))\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n      bArg1 = true; // New line, lets look at first argument again\n      nWordStart = -1;\n    }\n  }\n\n\tint levelUse = levelCurrent;\n\tint lev = levelUse | levelNext << 16;\n\tif (levelUse < levelNext)\n\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\tif (lev != styler.LevelAt(lineCurrent))\n\t\tstyler.SetLevel(lineCurrent, lev);\n}\n\nstatic const char * const nsisWordLists[] = {\n\t\"Functions\",\n\t\"Variables\",\n\t\"Lables\",\n\t\"UserDefined\",\n\t0, };\n\n\nextern const LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, \"nsis\", FoldNsisDoc, nsisWordLists);\n\n"
  },
  {
    "path": "lexers/LexNull.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexNull.cxx\n ** Lexer for no language. Used for plain text and unrecognized files.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ColouriseNullDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],\n                            Accessor &styler) {\n\t// Null language means all style bytes are 0 so just mark the end - no need to fill in.\n\tif (length > 0) {\n\t\tstyler.StartAt(startPos + length - 1);\n\t\tstyler.StartSegment(startPos + length - 1);\n\t\tstyler.ColourTo(startPos + length - 1, 0);\n\t}\n}\n\nextern const LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, \"null\");\n"
  },
  {
    "path": "lexers/LexOScript.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexOScript.cxx\n ** Lexer for OScript sources; ocx files and/or OSpace dumps.\n ** OScript is a programming language used to develop applications for the\n ** Livelink server platform.\n **/\n// Written by Ferdinand Prantl <prantlf@gmail.com>, inspired by the code from\n// LexVB.cxx and LexPascal.cxx. The License.txt file describes the conditions\n// under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// -----------------------------------------\n// Functions classifying a single character.\n\n// This function is generic and should be probably moved to CharSet.h where\n// IsAlphaNumeric the others reside.\ninline bool IsAlpha(int ch) {\n\treturn (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');\n}\n\nstatic inline bool IsIdentifierChar(int ch) {\n\t// Identifiers cannot contain non-ASCII letters; a word with non-English\n\t// language-specific characters cannot be an identifier.\n\treturn IsAlphaNumeric(ch) || ch == '_';\n}\n\nstatic inline bool IsIdentifierStart(int ch) {\n\t// Identifiers cannot contain non-ASCII letters; a word with non-English\n\t// language-specific characters cannot be an identifier.\n\treturn IsAlpha(ch) || ch == '_';\n}\n\nstatic inline bool IsNumberChar(int ch, int chNext) {\n\t// Numeric constructs are not checked for lexical correctness. They are\n\t// expected to look like +1.23-E9 but actually any bunch of the following\n\t// characters will be styled as number.\n\t// KNOWN PROBLEM: if you put + or - operators immediately after a number\n\t// and the next operand starts with the letter E, the operator will not be\n\t// recognized and it will be styled together with the preceding number.\n\t// This should not occur; at least not often. The coding style recommends\n\t// putting spaces around operators.\n\treturn IsADigit(ch) || toupper(ch) == 'E' || ch == '.' ||\n\t\t   ((ch == '-' || ch == '+') && toupper(chNext) == 'E');\n}\n\n// This function checks for the start or a natural number without any symbols\n// or operators as a prefix; the IsPrefixedNumberStart should be called\n// immediately after this one to cover all possible numeric constructs.\nstatic inline bool IsNaturalNumberStart(int ch) {\n\treturn IsADigit(ch) != 0;\n}\n\nstatic inline bool IsPrefixedNumberStart(int ch, int chNext) {\n\t// KNOWN PROBLEM: if you put + or - operators immediately before a number\n\t// the operator will not be recognized and it will be styled together with\n\t// the succeeding number. This should not occur; at least not often. The\n\t// coding style recommends putting spaces around operators.\n\treturn (ch == '.' || ch == '-' || ch == '+') && IsADigit(chNext);\n}\n\nstatic inline bool IsOperator(int ch) {\n\treturn strchr(\"%^&*()-+={}[]:;<>,/?!.~|\\\\\", ch) != NULL;\n}\n\n// ---------------------------------------------------------------\n// Functions classifying a token currently processed in the lexer.\n\n// Checks if the current line starts with the preprocessor directive used\n// usually to introduce documentation comments: #ifdef DOC. This method is\n// supposed to be called if the line has been recognized as a preprocessor\n// directive already.\nstatic bool IsDocCommentStart(StyleContext &sc) {\n\t// Check the line back to its start only if the end looks promising.\n\tif (sc.LengthCurrent() == 10 && !IsAlphaNumeric(sc.ch)) {\n\t\tchar s[11];\n\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\treturn strcmp(s, \"#ifdef doc\") == 0;\n\t}\n\treturn false;\n}\n\n// Checks if the current line starts with the preprocessor directive that\n// is complementary to the #ifdef DOC start: #endif. This method is supposed\n// to be called if the current state point to the documentation comment.\n// QUESTIONAL ASSUMPTION: The complete #endif directive is not checked; just\n// the starting #e. However, there is no other preprocessor directive with\n// the same starting letter and thus this optimization should always work.\nstatic bool IsDocCommentEnd(StyleContext &sc) {\n\treturn sc.ch == '#' && sc.chNext == 'e';\n}\n\nclass IdentifierClassifier {\n\tWordList &keywords;  // Passed from keywords property.\n\tWordList &constants; // Passed from keywords2 property.\n\tWordList &operators; // Passed from keywords3 property.\n\tWordList &types;     // Passed from keywords4 property.\n\tWordList &functions; // Passed from keywords5 property.\n\tWordList &objects;   // Passed from keywords6 property.\n\n\tIdentifierClassifier(IdentifierClassifier const&);\n\tIdentifierClassifier& operator=(IdentifierClassifier const&);\n\npublic:\n\tIdentifierClassifier(WordList *keywordlists[]) :\n\t\tkeywords(*keywordlists[0]), constants(*keywordlists[1]),\n\t\toperators(*keywordlists[2]), types(*keywordlists[3]),\n\t\tfunctions(*keywordlists[4]), objects(*keywordlists[5])\n\t{}\n\n\tvoid ClassifyIdentifier(StyleContext &sc) {\n\t\t// Opening parenthesis following an identifier makes it a possible\n\t\t// function call.\n\t\t// KNOWN PROBLEM: If some whitespace is inserted between the\n\t\t// identifier and the parenthesis they will not be able to be\n\t\t// recognized as a function call. This should not occur; at\n\t\t// least not often. Such coding style would be weird.\n\t\tif (sc.Match('(')) {\n\t\t\tchar s[100];\n\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t// Before an opening brace can be control statements and\n\t\t\t// operators too; function call is the last option.\n\t\t\tif (keywords.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_OSCRIPT_KEYWORD);\n\t\t\t} else if (operators.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_OSCRIPT_OPERATOR);\n\t\t\t} else if (functions.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_OSCRIPT_FUNCTION);\n\t\t\t} else {\n\t\t\t\tsc.ChangeState(SCE_OSCRIPT_METHOD);\n\t\t\t}\n\t\t\tsc.SetState(SCE_OSCRIPT_OPERATOR);\n\t\t} else {\n\t\t\tchar s[100];\n\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t// A dot following an identifier means an access to an object\n\t\t\t// member. The related object identifier can be special.\n\t\t\t// KNOWN PROBLEM: If there is whitespace between the identifier\n\t\t\t// and the following dot, the identifier will not be recognized\n\t\t\t// as an object in an object member access. If it is one of the\n\t\t\t// listed static objects it will not be styled.\n\t\t\tif (sc.Match('.') && objects.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_OSCRIPT_OBJECT);\n\t\t\t\tsc.SetState(SCE_OSCRIPT_OPERATOR);\n\t\t\t} else {\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_OSCRIPT_KEYWORD);\n\t\t\t\t} else if (constants.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_OSCRIPT_CONSTANT);\n\t\t\t\t} else if (operators.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_OSCRIPT_OPERATOR);\n\t\t\t\t} else if (types.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_OSCRIPT_TYPE);\n\t\t\t\t} else if (functions.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_OSCRIPT_FUNCTION);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t}\n\t}\n};\n\n// ------------------------------------------------\n// Function colourising an excerpt of OScript code.\n\nstatic void ColouriseOScriptDoc(Sci_PositionU startPos, Sci_Position length,\n\t\t\t\t\t\t\t\tint initStyle, WordList *keywordlists[],\n\t\t\t\t\t\t\t\tAccessor &styler) {\n\t// I wonder how whole-line styles ended by EOLN can escape the resetting\n\t// code in the loop below and overflow to the next line. Let us make sure\n\t// that a new line does not start with them carried from the previous one.\n\t// NOTE: An overflowing string is intentionally not checked; it reminds\n\t// the developer that the string must be ended on the same line.\n\tif (initStyle == SCE_OSCRIPT_LINE_COMMENT ||\n\t\t\tinitStyle == SCE_OSCRIPT_PREPROCESSOR) {\n\t\tinitStyle = SCE_OSCRIPT_DEFAULT;\n\t}\n\n\tstyler.StartAt(startPos);\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tIdentifierClassifier identifierClassifier(keywordlists);\n\n\t// It starts with true at the beginning of a line and changes to false as\n\t// soon as the first non-whitespace character has been processed.\n\tbool isFirstToken = true;\n\t// It starts with true at the beginning of a line and changes to false as\n\t// soon as the first identifier on the line is passed by.\n\tbool isFirstIdentifier = true;\n\t// It becomes false when #ifdef DOC (the preprocessor directive often\n\t// used to start a documentation comment) is encountered and remain false\n\t// until the end of the documentation block is not detected. This is done\n\t// by checking for the complementary #endif preprocessor directive.\n\tbool endDocComment = false;\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.atLineStart) {\n\t\t\tisFirstToken = true;\n\t\t\tisFirstIdentifier = true;\n\t\t// Detect the current state is neither whitespace nor identifier. It\n\t\t// means that no next identifier can be the first token on the line.\n\t\t} else if (isFirstIdentifier && sc.state != SCE_OSCRIPT_DEFAULT &&\n\t\t\t\t   sc.state != SCE_OSCRIPT_IDENTIFIER) {\n\t\t\tisFirstIdentifier = false;\n\t\t}\n\n\t\t// Check if the current state should be changed.\n\t\tif (sc.state == SCE_OSCRIPT_OPERATOR) {\n\t\t\t// Multiple-symbol operators are marked by single characters.\n\t\t\tsc.SetState(SCE_OSCRIPT_DEFAULT);\n\t\t} else if (sc.state == SCE_OSCRIPT_IDENTIFIER) {\n\t\t\tif (!IsIdentifierChar(sc.ch)) {\n\t\t\t\t// Colon after an identifier makes it a label if it is the\n\t\t\t\t// first token on the line.\n\t\t\t\t// KNOWN PROBLEM: If some whitespace is inserted between the\n\t\t\t\t// identifier and the colon they will not be recognized as a\n\t\t\t\t// label. This should not occur; at least not often. It would\n\t\t\t\t// make the code structure less legible and examples in the\n\t\t\t\t// Livelink documentation do not show it.\n\t\t\t\tif (sc.Match(':') && isFirstIdentifier) {\n\t\t\t\t\tsc.ChangeState(SCE_OSCRIPT_LABEL);\n\t\t\t\t\tsc.ForwardSetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tidentifierClassifier.ClassifyIdentifier(sc);\n\t\t\t\t}\n\t\t\t\t// Avoid a sequence of two words be mistaken for a label. A\n\t\t\t\t// switch case would be an example.\n\t\t\t\tisFirstIdentifier = false;\n\t\t\t}\n\t\t} else if (sc.state == SCE_OSCRIPT_GLOBAL) {\n\t\t\tif (!IsIdentifierChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_OSCRIPT_PROPERTY) {\n\t\t\tif (!IsIdentifierChar(sc.ch)) {\n\t\t\t\t// Any member access introduced by the dot operator is\n\t\t\t\t// initially marked as a property access. If an opening\n\t\t\t\t// parenthesis is detected later it is changed to method call.\n\t\t\t\t// KNOWN PROBLEM: The same as at the function call recognition\n\t\t\t\t// for SCE_OSCRIPT_IDENTIFIER above.\n\t\t\t\tif (sc.Match('(')) {\n\t\t\t\t\tsc.ChangeState(SCE_OSCRIPT_METHOD);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_OSCRIPT_NUMBER) {\n\t\t\tif (!IsNumberChar(sc.ch, sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_OSCRIPT_SINGLEQUOTE_STRING) {\n\t\t\tif (sc.ch == '\\'') {\n\t\t\t\t// Two consequential apostrophes convert to a single one.\n\t\t\t\tif (sc.chNext == '\\'') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tsc.ForwardSetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t\t}\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_OSCRIPT_DOUBLEQUOTE_STRING) {\n\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\t// Two consequential quotation marks convert to a single one.\n\t\t\t\tif (sc.chNext == '\\\"') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tsc.ForwardSetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t\t}\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_OSCRIPT_BLOCK_COMMENT) {\n\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_OSCRIPT_LINE_COMMENT) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_OSCRIPT_PREPROCESSOR) {\n\t\t\tif (IsDocCommentStart(sc)) {\n\t\t\t\tsc.ChangeState(SCE_OSCRIPT_DOC_COMMENT);\n\t\t\t\tendDocComment = false;\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_OSCRIPT_DOC_COMMENT) {\n\t\t\t// KNOWN PROBLEM: The first line detected that would close a\n\t\t\t// conditional preprocessor block (#endif) the documentation\n\t\t\t// comment block will end. (Nested #if-#endif blocks are not\n\t\t\t// supported. Hopefully it will not occur often that a line\n\t\t\t// within the text block would stat with #endif.\n\t\t\tif (isFirstToken && IsDocCommentEnd(sc)) {\n\t\t\t\tendDocComment = true;\n\t\t\t} else if (sc.atLineEnd && endDocComment) {\n\t\t\t\tsc.ForwardSetState(SCE_OSCRIPT_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Check what state starts with the current character.\n\t\tif (sc.state == SCE_OSCRIPT_DEFAULT) {\n\t\t\tif (sc.Match('\\'')) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_SINGLEQUOTE_STRING);\n\t\t\t} else if (sc.Match('\\\"')) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_DOUBLEQUOTE_STRING);\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_LINE_COMMENT);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_BLOCK_COMMENT);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (isFirstToken && sc.Match('#')) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_PREPROCESSOR);\n\t\t\t} else if (sc.Match('$')) {\n\t\t\t\t// Both process-global ($xxx) and thread-global ($$xxx)\n\t\t\t\t// variables are handled as one global.\n\t\t\t\tsc.SetState(SCE_OSCRIPT_GLOBAL);\n\t\t\t} else if (IsNaturalNumberStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_NUMBER);\n\t\t\t} else if (IsPrefixedNumberStart(sc.ch, sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_NUMBER);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match('.') && IsIdentifierStart(sc.chNext)) {\n\t\t\t\t// Every object member access is marked as a property access\n\t\t\t\t// initially. The decision between property and method is made\n\t\t\t\t// after parsing the identifier and looking what comes then.\n\t\t\t\t// KNOWN PROBLEM: If there is whitespace between the following\n\t\t\t\t// identifier and the dot, the dot will not be recognized\n\t\t\t\t// as a member accessing operator. In turn, the identifier\n\t\t\t\t// will not be recognizable as a property or a method too.\n\t\t\t\tsc.SetState(SCE_OSCRIPT_OPERATOR);\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState(SCE_OSCRIPT_PROPERTY);\n\t\t\t} else if (IsIdentifierStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_IDENTIFIER);\n\t\t\t} else if (IsOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_OSCRIPT_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t\tif (isFirstToken && !IsASpaceOrTab(sc.ch)) {\n\t\t\tisFirstToken = false;\n\t\t}\n\t}\n\n\tsc.Complete();\n}\n\n// ------------------------------------------\n// Functions supporting OScript code folding.\n\nstatic inline bool IsBlockComment(int style) {\n\treturn style == SCE_OSCRIPT_BLOCK_COMMENT;\n}\n\nstatic bool IsLineComment(Sci_Position line, Accessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eolPos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eolPos; i++) {\n\t\tchar ch = styler[i];\n\t\tchar chNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styler.StyleAt(i);\n\t\tif (ch == '/' && chNext == '/' && style == SCE_OSCRIPT_LINE_COMMENT) {\n\t\t\treturn true;\n\t\t} else if (!IsASpaceOrTab(ch)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn false;\n}\n\nstatic inline bool IsPreprocessor(int style) {\n\treturn style == SCE_OSCRIPT_PREPROCESSOR ||\n\t\t   style == SCE_OSCRIPT_DOC_COMMENT;\n}\n\nstatic void GetRangeLowered(Sci_PositionU start, Sci_PositionU end,\n\t\t\t\t\t\t\tAccessor &styler, char *s, Sci_PositionU len) {\n\tSci_PositionU i = 0;\n\twhile (i < end - start + 1 && i < len - 1) {\n\t\ts[i] = static_cast<char>(tolower(styler[start + i]));\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n}\n\nstatic void GetForwardWordLowered(Sci_PositionU start, Accessor &styler,\n\t\t\t\t\t\t\t\t  char *s, Sci_PositionU len) {\n\tSci_PositionU i = 0;\n\twhile (i < len - 1 && IsAlpha(styler.SafeGetCharAt(start + i))) {\n\t\ts[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n}\n\nstatic void UpdatePreprocessorFoldLevel(int &levelCurrent,\n\t\tSci_PositionU startPos, Accessor &styler) {\n\tchar s[7]; // Size of the longest possible keyword + null.\n\tGetForwardWordLowered(startPos, styler, s, sizeof(s));\n\n\tif (strcmp(s, \"ifdef\") == 0 ||\n\t\tstrcmp(s, \"ifndef\") == 0) {\n\t\tlevelCurrent++;\n\t} else if (strcmp(s, \"endif\") == 0) {\n\t\tlevelCurrent--;\n\t\tif (levelCurrent < SC_FOLDLEVELBASE) {\n\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t}\n\t}\n}\n\nstatic void UpdateKeywordFoldLevel(int &levelCurrent, Sci_PositionU lastStart,\n\t\tSci_PositionU currentPos, Accessor &styler) {\n\tchar s[9];\n\tGetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));\n\n\tif (strcmp(s, \"if\") == 0 || strcmp(s, \"for\") == 0 ||\n\t\tstrcmp(s, \"switch\") == 0 || strcmp(s, \"function\") == 0 ||\n\t\tstrcmp(s, \"while\") == 0 || strcmp(s, \"repeat\") == 0) {\n\t\tlevelCurrent++;\n\t} else if (strcmp(s, \"end\") == 0 || strcmp(s, \"until\") == 0) {\n\t\tlevelCurrent--;\n\t\tif (levelCurrent < SC_FOLDLEVELBASE) {\n\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t}\n\t}\n}\n\n// ------------------------------\n// Function folding OScript code.\n\nstatic void FoldOScriptDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\t\t\t\t\t   WordList *[], Accessor &styler) {\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldPreprocessor = styler.GetPropertyInt(\"fold.preprocessor\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_Position endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tSci_Position lastStart = 0;\n\n\tfor (Sci_Position i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atLineEnd = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (foldComment && IsBlockComment(style)) {\n\t\t\tif (!IsBlockComment(stylePrev)) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (!IsBlockComment(styleNext) && !atLineEnd) {\n\t\t\t\t// Comments do not end at end of line and the next character\n\t\t\t\t// may not be styled.\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (foldComment && atLineEnd && IsLineComment(lineCurrent, styler)) {\n\t\t\tif (!IsLineComment(lineCurrent - 1, styler) &&\n\t\t\t\tIsLineComment(lineCurrent + 1, styler))\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (IsLineComment(lineCurrent - 1, styler) &&\n\t\t\t\t\t !IsLineComment(lineCurrent+1, styler))\n\t\t\t\tlevelCurrent--;\n\t\t}\n\t\tif (foldPreprocessor) {\n\t\t\tif (ch == '#' && IsPreprocessor(style)) {\n\t\t\t\tUpdatePreprocessorFoldLevel(levelCurrent, i + 1, styler);\n\t\t\t}\n\t\t}\n\n\t\tif (stylePrev != SCE_OSCRIPT_KEYWORD && style == SCE_OSCRIPT_KEYWORD) {\n\t\t\tlastStart = i;\n\t\t}\n\t\tif (stylePrev == SCE_OSCRIPT_KEYWORD) {\n\t\t\tif(IsIdentifierChar(ch) && !IsIdentifierChar(chNext)) {\n\t\t\t\tUpdateKeywordFoldLevel(levelCurrent, lastStart, i, styler);\n\t\t\t}\n\t\t}\n\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\n\t\tif (atLineEnd) {\n\t\t\tint level = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlevel |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (level != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, level);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t}\n\n\t// If we did not reach EOLN in the previous loop, store the line level and\n\t// whitespace information. The rest will be filled in later.\n\tint lev = levelPrev;\n\tif (visibleChars == 0 && foldCompact)\n\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\tstyler.SetLevel(lineCurrent, lev);\n}\n\n// --------------------------------------------\n// Declaration of the OScript lexer descriptor.\n\nstatic const char * const oscriptWordListDesc[] = {\n\t\"Keywords and reserved words\",\n\t\"Literal constants\",\n\t\"Literal operators\",\n\t\"Built-in value and reference types\",\n\t\"Built-in global functions\",\n\t\"Built-in static objects\",\n\t0\n};\n\nextern const LexerModule lmOScript(SCLEX_OSCRIPT, ColouriseOScriptDoc, \"oscript\", FoldOScriptDoc, oscriptWordListDesc);\n"
  },
  {
    "path": "lexers/LexOpal.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexOpal.cxx\n ** Lexer for OPAL (functional language similar to Haskell)\n ** Written by Sebastian Pipping <webmaster@hartwork.org>\n **/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\ninline static void getRange( Sci_PositionU start, Sci_PositionU end, Accessor & styler, char * s, Sci_PositionU len )\n{\n\tSci_PositionU i = 0;\n\twhile( ( i < end - start + 1 ) && ( i < len - 1 ) )\n\t{\n\t\ts[i] = static_cast<char>( styler[ start + i ] );\n\t\ti++;\n\t}\n\ts[ i ] = '\\0';\n}\n\ninline bool HandleString( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler )\n{\n\tchar ch;\n\n\t// Wait for string to close\n\tbool even_backslash_count = true; // Without gaps in between\n\tcur++; // Skip initial quote\n\tfor( ; ; )\n\t{\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_STRING );\n\t\t\treturn false; // STOP\n\t\t}\n\n\t\tch = styler.SafeGetCharAt( cur );\n\t\tif( ( ch == '\\015' ) || ( ch == '\\012' ) ) // Deny multi-line strings\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_STRING );\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif( even_backslash_count )\n\t\t\t{\n\t\t\t\tif( ch == '\"' )\n\t\t\t\t{\n\t\t\t\t\tstyler.ColourTo( cur, SCE_OPAL_STRING );\n\t\t\t\t\tcur++;\n\t\t\t\t\tif( cur >= one_too_much )\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false; // STOP\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstyler.StartSegment( cur );\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( ch == '\\\\' )\n\t\t\t\t{\n\t\t\t\t\teven_backslash_count = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\teven_backslash_count = true;\n\t\t\t}\n\t\t}\n\n\t\tcur++;\n\t}\n}\n\ninline bool HandleCommentBlock( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler, bool could_fail )\n{\n\tchar ch;\n\n\tif( could_fail )\n\t{\n\t\tcur++;\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );\n\t\t\treturn false; // STOP\n\t\t}\n\n\t\tch = styler.SafeGetCharAt( cur );\n\t\tif( ch != '*' )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Wait for comment close\n\tcur++;\n\tbool star_found = false;\n\tfor( ; ; )\n\t{\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );\n\t\t\treturn false; // STOP\n\t\t}\n\n\t\tch = styler.SafeGetCharAt( cur );\n\t\tif( star_found )\n\t\t{\n\t\t\tif( ch == '/' )\n\t\t\t{\n\t\t\t\tstyler.ColourTo( cur, SCE_OPAL_COMMENT_BLOCK );\n\t\t\t\tcur++;\n\t\t\t\tif( cur >= one_too_much )\n\t\t\t\t{\n\t\t\t\t\treturn false; // STOP\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstyler.StartSegment( cur );\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if( ch != '*' )\n\t\t\t{\n\t\t\t\tstar_found = false;\n\t\t\t}\n\t\t}\n\t\telse if( ch == '*' )\n\t\t{\n\t\t\tstar_found = true;\n\t\t}\n\t\tcur++;\n\t}\n}\n\ninline bool HandleCommentLine( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler, bool could_fail )\n{\n\tchar ch;\n\n\tif( could_fail )\n\t{\n\t\tcur++;\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );\n\t\t\treturn false; // STOP\n\t\t}\n\n\t\tch = styler.SafeGetCharAt( cur );\n\t\tif( ch != '-' )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\n\t\tcur++;\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );\n\t\t\treturn false; // STOP\n\t\t}\n\n\t\tch = styler.SafeGetCharAt( cur );\n\t\tif( ( ch != ' ' ) && ( ch != '\\t' ) )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Wait for end of line\n\tbool fifteen_found = false;\n\n\tfor( ; ; )\n\t{\n\t\tcur++;\n\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );\n\t\t\treturn false; // STOP\n\t\t}\n\n\t\tch = styler.SafeGetCharAt( cur );\n\t\tif( fifteen_found )\n\t\t{\n/*\n\t\t\tif( ch == '\\012' )\n\t\t\t{\n\t\t\t\t// One newline on Windows (015, 012)\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// One newline on MAC (015) and another char\n\t\t\t}\n*/\n\t\t\tcur--;\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif( ch == '\\015' )\n\t\t\t{\n\t\t\t\tfifteen_found = true;\n\t\t\t}\n\t\t\telse if( ch == '\\012' )\n\t\t\t{\n\t\t\t\t// One newline on Linux (012)\n\t\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );\n\t\t\t\tstyler.StartSegment( cur );\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n}\n\ninline bool HandlePar( Sci_PositionU & cur, Accessor & styler )\n{\n\tstyler.ColourTo( cur, SCE_OPAL_PAR );\n\n\tcur++;\n\n\tstyler.StartSegment( cur );\n\treturn true;\n}\n\ninline bool HandleSpace( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler )\n{\n\tchar ch;\n\n\tcur++;\n\tfor( ; ; )\n\t{\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_SPACE );\n\t\t\treturn false;\n\t\t}\n\n\t\tch = styler.SafeGetCharAt( cur );\n\t\tswitch( ch )\n\t\t{\n\t\tcase ' ':\n\t\tcase '\\t':\n\t\tcase '\\015':\n\t\tcase '\\012':\n\t\t\tcur++;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_SPACE );\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t}\n}\n\ninline bool HandleInteger( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler )\n{\n\tchar ch;\n\n\tfor( ; ; )\n\t{\n\t\tcur++;\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_INTEGER );\n\t\t\treturn false; // STOP\n\t\t}\n\n\t\tch = styler.SafeGetCharAt( cur );\n\t\tif( !( IsASCII( ch ) && isdigit( ch ) ) )\n\t\t{\n\t\t\tstyler.ColourTo( cur - 1, SCE_OPAL_INTEGER );\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t}\n}\n\ninline bool HandleWord( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler, WordList * keywordlists[] )\n{\n\tchar ch;\n\tconst Sci_PositionU beg = cur;\n\n\tcur++;\n\tfor( ; ; )\n\t{\n\t\tch = styler.SafeGetCharAt( cur );\n\t\tif( ( ch != '_' ) && ( ch != '-' ) &&\n\t\t\t!( IsASCII( ch ) && ( islower( ch ) || isupper( ch ) || isdigit( ch ) ) ) ) break;\n\n\t\tcur++;\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst Sci_Position ide_len = cur - beg + 1;\n\tchar * ide = new char[ ide_len ];\n\tgetRange( beg, cur, styler, ide, ide_len );\n\n\tWordList & keywords    = *keywordlists[ 0 ];\n\tWordList & classwords  = *keywordlists[ 1 ];\n\n\tif( keywords.InList( ide ) ) // Keyword\n\t{\n\t\tdelete [] ide;\n\n\t\tstyler.ColourTo( cur - 1, SCE_OPAL_KEYWORD );\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\treturn false; // STOP\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t}\n\telse if( classwords.InList( ide ) ) // Sort\n\t{\n\t\tdelete [] ide;\n\n\t\tstyler.ColourTo( cur - 1, SCE_OPAL_SORT );\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\treturn false; // STOP\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t}\n\telse if( !strcmp( ide, \"true\" ) || !strcmp( ide, \"false\" ) ) // Bool const\n\t{\n\t\tdelete [] ide;\n\n\t\tstyler.ColourTo( cur - 1, SCE_OPAL_BOOL_CONST );\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\treturn false; // STOP\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t}\n\telse // Unknown keyword\n\t{\n\t\tdelete [] ide;\n\n\t\tstyler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );\n\t\tif( cur >= one_too_much )\n\t\t{\n\t\t\treturn false; // STOP\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstyler.StartSegment( cur );\n\t\t\treturn true;\n\t\t}\n\t}\n\n}\n\ninline bool HandleSkip( Sci_PositionU & cur, Sci_PositionU one_too_much, Accessor & styler )\n{\n\tcur++;\n\tstyler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );\n\tif( cur >= one_too_much )\n\t{\n\t\treturn false; // STOP\n\t}\n\telse\n\t{\n\t\tstyler.StartSegment( cur );\n\t\treturn true;\n\t}\n}\n\nstatic void ColouriseOpalDoc( Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor & styler )\n{\n\tstyler.StartAt( startPos );\n\tstyler.StartSegment( startPos );\n\n\tSci_PositionU & cur = startPos;\n\tconst Sci_PositionU one_too_much = startPos + length;\n\n\tint state = initStyle;\n\n\tfor( ; ; )\n\t{\n\t\tswitch( state )\n\t\t{\n\t\tcase SCE_OPAL_KEYWORD:\n\t\tcase SCE_OPAL_SORT:\n\t\t\tif( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;\n\t\t\tstate = SCE_OPAL_DEFAULT;\n\t\t\tbreak;\n\n\t\tcase SCE_OPAL_INTEGER:\n\t\t\tif( !HandleInteger( cur, one_too_much, styler ) ) return;\n\t\t\tstate = SCE_OPAL_DEFAULT;\n\t\t\tbreak;\n\n\t\tcase SCE_OPAL_COMMENT_BLOCK:\n\t\t\tif( !HandleCommentBlock( cur, one_too_much, styler, false ) ) return;\n\t\t\tstate = SCE_OPAL_DEFAULT;\n\t\t\tbreak;\n\n\t\tcase SCE_OPAL_COMMENT_LINE:\n\t\t\tif( !HandleCommentLine( cur, one_too_much, styler, false ) ) return;\n\t\t\tstate = SCE_OPAL_DEFAULT;\n\t\t\tbreak;\n\n\t\tcase SCE_OPAL_STRING:\n\t\t\tif( !HandleString( cur, one_too_much, styler ) ) return;\n\t\t\tstate = SCE_OPAL_DEFAULT;\n\t\t\tbreak;\n\n\t\tdefault: // SCE_OPAL_DEFAULT:\n\t\t\t{\n\t\t\t\tchar ch = styler.SafeGetCharAt( cur );\n\n\t\t\t\tswitch( ch )\n\t\t\t\t{\n\t\t\t\t// String\n\t\t\t\tcase '\"':\n\t\t\t\t\tif( !HandleString( cur, one_too_much, styler ) ) return;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Comment block\n\t\t\t\tcase '/':\n\t\t\t\t\tif( !HandleCommentBlock( cur, one_too_much, styler, true ) ) return;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Comment line\n\t\t\t\tcase '-':\n\t\t\t\t\tif( !HandleCommentLine( cur, one_too_much, styler, true ) ) return;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Par\n\t\t\t\tcase '(':\n\t\t\t\tcase ')':\n\t\t\t\tcase '[':\n\t\t\t\tcase ']':\n\t\t\t\tcase '{':\n\t\t\t\tcase '}':\n\t\t\t\t\tif( !HandlePar( cur, styler ) ) return;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Whitespace\n\t\t\t\tcase ' ':\n\t\t\t\tcase '\\t':\n\t\t\t\tcase '\\015':\n\t\t\t\tcase '\\012':\n\t\t\t\t\tif( !HandleSpace( cur, one_too_much, styler ) ) return;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\t{\n\t\t\t\t\t\t// Integer\n\t\t\t\t\t\tif( IsASCII( ch ) && isdigit( ch ) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif( !HandleInteger( cur, one_too_much, styler ) ) return;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Keyword\n\t\t\t\t\t\telse if( IsASCII( ch ) && ( islower( ch ) || isupper( ch ) ) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Skip\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif( !HandleSkip( cur, one_too_much, styler ) ) return;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic const char * const opalWordListDesc[] = {\n\t\"Keywords\",\n\t\"Sorts\",\n\t0\n};\n\nextern const LexerModule lmOpal(SCLEX_OPAL, ColouriseOpalDoc, \"opal\", NULL, opalWordListDesc);\n"
  },
  {
    "path": "lexers/LexPB.cxx",
    "content": "// Scintilla source code edit control\n// @file LexPB.cxx\n// Lexer for PowerBasic by Roland Walter, roland@rowalt.de (for PowerBasic see www.powerbasic.com)\n//\n// Changes:\n// 17.10.2003: Toggling of subs/functions now until next sub/function - this gives better results\n// 29.10.2003: 1. Bug: Toggling didn't work for subs/functions added in editor\n//             2. Own colors for PB constants and Inline Assembler SCE_B_CONSTANT and SCE_B_ASM\n//             3. Several smaller syntax coloring improvements and speed optimizations\n// 12.07.2004: 1. Toggling for macros added\n//             2. Further folding speed optimitations (for people dealing with very large listings)\n//\n// Necessary changes for the PB lexer in Scintilla project:\n//  - In SciLexer.h and Scintilla.iface:\n//\n//    #define SCLEX_POWERBASIC 51       //ID for PowerBasic lexer\n//    (...)\n//    #define SCE_B_DEFAULT 0           //in both VB and PB lexer\n//    #define SCE_B_COMMENT 1           //in both VB and PB lexer\n//    #define SCE_B_NUMBER 2            //in both VB and PB lexer\n//    #define SCE_B_KEYWORD 3           //in both VB and PB lexer\n//    #define SCE_B_STRING 4            //in both VB and PB lexer\n//    #define SCE_B_PREPROCESSOR 5      //VB lexer only, not in PB lexer\n//    #define SCE_B_OPERATOR 6          //in both VB and PB lexer\n//    #define SCE_B_IDENTIFIER 7        //in both VB and PB lexer\n//    #define SCE_B_DATE 8              //VB lexer only, not in PB lexer\n//    #define SCE_B_CONSTANT 13         //PB lexer only, not in VB lexer\n//    #define SCE_B_ASM 14              //PB lexer only, not in VB lexer\n\n//  - Statement added to KeyWords.cxx:      'LINK_LEXER(lmPB);'\n//  - Statement added to scintilla_vc6.mak: '$(DIR_O)\\LexPB.obj: ...\\src\\LexPB.cxx $(LEX_HEADERS)'\n//\n// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsTypeCharacter(const int ch)\n{\n    return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$' || ch == '?';\n}\n\nstatic inline bool IsAWordChar(const int ch)\n{\n    return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');\n}\n\nstatic inline bool IsAWordStart(const int ch)\n{\n    return (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\nstatic bool MatchUpperCase(Accessor &styler, Sci_Position pos, const char *s)   //Same as styler.Match() but uppercase comparison (a-z,A-Z and space only)\n{\n    char ch;\n    for (Sci_Position i=0; *s; i++)\n    {\n        ch=styler.SafeGetCharAt(pos+i);\n        if (ch > 0x60) ch -= '\\x20';\n        if (*s != ch) return false;\n        s++;\n    }\n    return true;\n}\n\nstatic void ColourisePBDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,WordList *keywordlists[],Accessor &styler) {\n\n    WordList &keywords = *keywordlists[0];\n\n    styler.StartAt(startPos);\n\n    StyleContext sc(startPos, length, initStyle, styler);\n\n    for (; sc.More(); sc.Forward()) {\n        switch (sc.state)\n        {\n            case SCE_B_OPERATOR:\n            {\n                sc.SetState(SCE_B_DEFAULT);\n                break;\n            }\n            case SCE_B_KEYWORD:\n            {\n                if (!IsAWordChar(sc.ch))\n                {\n                    if (!IsTypeCharacter(sc.ch))\n                    {\n                        char s[100];\n                        sc.GetCurrentLowered(s, sizeof(s));\n                        if (keywords.InList(s))\n                        {\n                            if (strcmp(s, \"rem\") == 0)\n                            {\n                                sc.ChangeState(SCE_B_COMMENT);\n                                if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}\n                            }\n                            else if (strcmp(s, \"asm\") == 0)\n                            {\n                                sc.ChangeState(SCE_B_ASM);\n                                if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}\n                            }\n                            else\n                            {\n                                sc.SetState(SCE_B_DEFAULT);\n                            }\n                        }\n                        else\n                        {\n                            sc.ChangeState(SCE_B_IDENTIFIER);\n                            sc.SetState(SCE_B_DEFAULT);\n                        }\n                    }\n                }\n                break;\n            }\n            case SCE_B_NUMBER:\n            {\n                if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_B_DEFAULT);}\n                break;\n            }\n            case SCE_B_STRING:\n            {\n                if (sc.ch == '\\\"'){sc.ForwardSetState(SCE_B_DEFAULT);}\n                break;\n            }\n            case SCE_B_CONSTANT:\n            {\n                if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_B_DEFAULT);}\n                break;\n            }\n            case SCE_B_COMMENT:\n            {\n                if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}\n                break;\n            }\n            case SCE_B_ASM:\n            {\n                if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}\n                break;\n            }\n        }  //switch (sc.state)\n\n        // Determine if a new state should be entered:\n        if (sc.state == SCE_B_DEFAULT)\n        {\n            if (sc.ch == '\\'') {sc.SetState(SCE_B_COMMENT);}\n            else if (sc.ch == '\\\"') {sc.SetState(SCE_B_STRING);}\n            else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {sc.SetState(SCE_B_NUMBER);}\n            else if (sc.ch == '&' && tolower(sc.chNext) == 'b') {sc.SetState(SCE_B_NUMBER);}\n            else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {sc.SetState(SCE_B_NUMBER);}\n            else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {sc.SetState(SCE_B_NUMBER);}\n            else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_B_KEYWORD);}\n            else if (sc.ch == '%') {sc.SetState(SCE_B_CONSTANT);}\n            else if (sc.ch == '$') {sc.SetState(SCE_B_CONSTANT);}\n            else if (sc.ch == '#') {sc.SetState(SCE_B_KEYWORD);}\n            else if (sc.ch == '!') {sc.SetState(SCE_B_ASM);}\n            else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\\\')) {sc.SetState(SCE_B_OPERATOR);}\n        }\n    }      //for (; sc.More(); sc.Forward())\n    sc.Complete();\n}\n\n//The folding routine for PowerBasic toggles SUBs and FUNCTIONs only. This was exactly what I wanted,\n//nothing more. I had worked with this kind of toggling for several years when I used the great good old\n//GFA Basic which is dead now. After testing the feature of toggling FOR-NEXT loops, WHILE-WEND loops\n//and so on too I found this is more disturbing then helping (for me). So if You think in another way\n//you can (or must) write Your own toggling routine ;-)\nstatic void FoldPBDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)\n{\n    // No folding enabled, no reason to continue...\n    if( styler.GetPropertyInt(\"fold\") == 0 )\n        return;\n\n    Sci_PositionU endPos = startPos + length;\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int levelCurrent = SC_FOLDLEVELBASE;\n    if (lineCurrent > 0)\n        levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n    int levelNext = levelCurrent;\n    char chNext = styler[startPos];\n\n    bool fNewLine=true;\n    bool fMightBeMultiLineMacro=false;\n    bool fBeginOfCommentFound=false;\n    for (Sci_PositionU i = startPos; i < endPos; i++)\n    {\n        char ch = chNext;\n        chNext = styler.SafeGetCharAt(i + 1);\n\n        if (fNewLine)            //Begin of a new line (The Sub/Function/Macro keywords may occur at begin of line only)\n        {\n            fNewLine=false;\n            fBeginOfCommentFound=false;\n            switch (ch)\n            {\n            case ' ':      //Most lines start with space - so check this first, the code is the same as for 'default:'\n            case '\\t':     //Handle tab too\n                {\n                    int levelUse = levelCurrent;\n                    int lev = levelUse | levelNext << 16;\n                    styler.SetLevel(lineCurrent, lev);\n                    break;\n                }\n            case 'F':\n            case 'f':\n                {\n\t\t\t\t\tswitch (chNext)\n\t\t\t\t\t{\n                    case 'U':\n                    case 'u':\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif( MatchUpperCase(styler,i,\"FUNCTION\") )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstyler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);\n\t\t\t\t\t\t\t\tlevelNext=SC_FOLDLEVELBASE+1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n                break;\n                }\n            case 'S':\n            case 's':\n                {\n\t\t\t\t\tswitch (chNext)\n\t\t\t\t\t{\n                    case 'U':\n                    case 'u':\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif( MatchUpperCase(styler,i,\"SUB\") )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstyler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);\n\t\t\t\t\t\t\t\tlevelNext=SC_FOLDLEVELBASE+1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n                    case 'T':\n                    case 't':\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif( MatchUpperCase(styler,i,\"STATIC FUNCTION\") )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstyler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);\n\t\t\t\t\t\t\t\tlevelNext=SC_FOLDLEVELBASE+1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if( MatchUpperCase(styler,i,\"STATIC SUB\") )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstyler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);\n\t\t\t\t\t\t\t\tlevelNext=SC_FOLDLEVELBASE+1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n                break;\n                }\n            case 'C':\n            case 'c':\n                {\n\t\t\t\t\tswitch (chNext)\n\t\t\t\t\t{\n                    case 'A':\n                    case 'a':\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif( MatchUpperCase(styler,i,\"CALLBACK FUNCTION\") )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstyler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);\n\t\t\t\t\t\t\t\tlevelNext=SC_FOLDLEVELBASE+1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n                break;\n                }\n            case 'M':\n            case 'm':\n                {\n\t\t\t\t\tswitch (chNext)\n\t\t\t\t\t{\n                    case 'A':\n                    case 'a':\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif( MatchUpperCase(styler,i,\"MACRO\") )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfMightBeMultiLineMacro=true;  //Set folder level at end of line, we have to check for single line macro\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n                break;\n                }\n            default:\n                {\n                    int levelUse = levelCurrent;\n                    int lev = levelUse | levelNext << 16;\n                    styler.SetLevel(lineCurrent, lev);\n                    break;\n                }\n            }  //switch (ch)\n        }  //if( fNewLine )\n\n        switch (ch)\n        {\n            case '=':                              //To test single line macros\n            {\n                if (fBeginOfCommentFound==false)\n                    fMightBeMultiLineMacro=false;  //The found macro is a single line macro only;\n                break;\n            }\n            case '\\'':                             //A comment starts\n            {\n                fBeginOfCommentFound=true;\n                break;\n            }\n            case '\\n':\n            {\n                if (fMightBeMultiLineMacro)        //The current line is the begin of a multi line macro\n                {\n                    fMightBeMultiLineMacro=false;\n                    styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);\n                    levelNext=SC_FOLDLEVELBASE+1;\n                }\n                lineCurrent++;\n                levelCurrent = levelNext;\n                fNewLine=true;\n                break;\n            }\n            case '\\r':\n            {\n                if (chNext != '\\n')\n                {\n                    lineCurrent++;\n                    levelCurrent = levelNext;\n                    fNewLine=true;\n                }\n                break;\n            }\n        }  //switch (ch)\n    }  //for (Sci_PositionU i = startPos; i < endPos; i++)\n}\n\nstatic const char * const pbWordListDesc[] = {\n    \"Keywords\",\n    0\n};\n\nextern const LexerModule lmPB(SCLEX_POWERBASIC, ColourisePBDoc, \"powerbasic\", FoldPBDoc, pbWordListDesc);\n"
  },
  {
    "path": "lexers/LexPLM.cxx",
    "content": "// Copyright (c) 1990-2007, Scientific Toolworks, Inc.\n// @file LexPLM.cxx\n// Author: Jason Haslam\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void GetRange(Sci_PositionU start,\n                     Sci_PositionU end,\n                     Accessor &styler,\n                     char *s,\n                     Sci_PositionU len) {\n\tSci_PositionU i = 0;\n\twhile ((i < end - start + 1) && (i < len-1)) {\n\t\ts[i] = static_cast<char>(tolower(styler[start + i]));\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n}\n\nstatic void ColourisePlmDoc(Sci_PositionU startPos,\n                            Sci_Position length,\n                            int initStyle,\n                            WordList *keywordlists[],\n                            Accessor &styler)\n{\n\tSci_PositionU endPos = startPos + length;\n\tint state = initStyle;\n\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = styler.SafeGetCharAt(i);\n\t\tchar chNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif (state == SCE_PLM_DEFAULT) {\n\t\t\tif (ch == '/' && chNext == '*') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_PLM_COMMENT;\n\t\t\t} else if (ch == '\\'') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_PLM_STRING;\n\t\t\t} else if (isdigit(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_PLM_NUMBER;\n\t\t\t} else if (isalpha(ch)) {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_PLM_IDENTIFIER;\n\t\t\t} else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||\n\t\t\t           ch == '=' || ch == '<' || ch == '>' || ch == ':') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_PLM_OPERATOR;\n\t\t\t} else if (ch == '$') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_PLM_CONTROL;\n\t\t\t}\n\t\t} else if (state == SCE_PLM_COMMENT) {\n\t\t\tif (ch == '*' && chNext == '/') {\n\t\t\t\ti++;\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tstate = SCE_PLM_DEFAULT;\n\t\t\t}\n\t\t} else if (state == SCE_PLM_STRING) {\n\t\t\tif (ch == '\\'') {\n\t\t\t\tif (chNext == '\\'') {\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\t\tstate = SCE_PLM_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (state == SCE_PLM_NUMBER) {\n\t\t\tif (!isdigit(ch) && !isalpha(ch) && ch != '$') {\n\t\t\t\ti--;\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tstate = SCE_PLM_DEFAULT;\n\t\t\t}\n\t\t} else if (state == SCE_PLM_IDENTIFIER) {\n\t\t\tif (!isdigit(ch) && !isalpha(ch) && ch != '$') {\n\t\t\t\t// Get the entire identifier.\n\t\t\t\tchar word[1024];\n\t\t\t\tSci_Position segmentStart = styler.GetStartSegment();\n\t\t\t\tGetRange(segmentStart, i - 1, styler, word, sizeof(word));\n\n\t\t\t\ti--;\n\t\t\t\tif (keywordlists[0]->InList(word))\n\t\t\t\t\tstyler.ColourTo(i, SCE_PLM_KEYWORD);\n\t\t\t\telse\n\t\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tstate = SCE_PLM_DEFAULT;\n\t\t\t}\n\t\t} else if (state == SCE_PLM_OPERATOR) {\n\t\t\tif (ch != '=' && ch != '>') {\n\t\t\t\ti--;\n\t\t\t\tstyler.ColourTo(i, state);\n\t\t\t\tstate = SCE_PLM_DEFAULT;\n\t\t\t}\n\t\t} else if (state == SCE_PLM_CONTROL) {\n\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\tstyler.ColourTo(i - 1, state);\n\t\t\t\tstate = SCE_PLM_DEFAULT;\n\t\t\t}\n\t\t}\n\t}\n\tstyler.ColourTo(endPos - 1, state);\n}\n\nstatic void FoldPlmDoc(Sci_PositionU startPos,\n                       Sci_Position length,\n                       int initStyle,\n                       WordList *[],\n                       Accessor &styler)\n{\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tSci_Position startKeyword = 0;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (stylePrev != SCE_PLM_KEYWORD && style == SCE_PLM_KEYWORD)\n\t\t\tstartKeyword = i;\n\n\t\tif (style == SCE_PLM_KEYWORD && styleNext != SCE_PLM_KEYWORD) {\n\t\t\tchar word[1024];\n\t\t\tGetRange(startKeyword, i, styler, word, sizeof(word));\n\n\t\t\tif (strcmp(word, \"procedure\") == 0 || strcmp(word, \"do\") == 0)\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (strcmp(word, \"end\") == 0)\n\t\t\t\tlevelCurrent--;\n\t\t}\n\n\t\tif (foldComment) {\n\t\t\tif (stylePrev != SCE_PLM_COMMENT && style == SCE_PLM_COMMENT)\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (stylePrev == SCE_PLM_COMMENT && style != SCE_PLM_COMMENT)\n\t\t\t\tlevelCurrent--;\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char *const plmWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmPLM(SCLEX_PLM, ColourisePlmDoc, \"PL/M\", FoldPlmDoc, plmWordListDesc);\n"
  },
  {
    "path": "lexers/LexPO.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexPO.cxx\n ** Lexer for GetText Translation (PO) files.\n **/\n// Copyright 2012 by Colomban Wendling <ban@herbesfolles.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// see https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files for the syntax reference\n// some details are taken from the GNU msgfmt behavior (like that indent is allows in front of lines)\n\n// TODO:\n// * add keywords for flags (fuzzy, c-format, ...)\n// * highlight formats inside c-format strings (%s, %d, etc.)\n// * style for previous untranslated string? (\"#|\" comment)\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ColourisePODoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler) {\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tbool escaped = false;\n\tSci_Position curLine = styler.GetLine(startPos);\n\t// the line state holds the last state on or before the line that isn't the default style\n\tint curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : SCE_PO_DEFAULT;\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\t// whether we should leave a state\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_PO_COMMENT:\n\t\t\tcase SCE_PO_PROGRAMMER_COMMENT:\n\t\t\tcase SCE_PO_REFERENCE:\n\t\t\tcase SCE_PO_FLAGS:\n\t\t\tcase SCE_PO_FUZZY:\n\t\t\t\tif (sc.atLineEnd)\n\t\t\t\t\tsc.SetState(SCE_PO_DEFAULT);\n\t\t\t\telse if (sc.state == SCE_PO_FLAGS && sc.Match(\"fuzzy\"))\n\t\t\t\t\t// here we behave like the previous parser, but this should probably be highlighted\n\t\t\t\t\t// on its own like a keyword rather than changing the whole flags style\n\t\t\t\t\tsc.ChangeState(SCE_PO_FUZZY);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_PO_MSGCTXT:\n\t\t\tcase SCE_PO_MSGID:\n\t\t\tcase SCE_PO_MSGSTR:\n\t\t\t\tif (isspacechar(sc.ch))\n\t\t\t\t\tsc.SetState(SCE_PO_DEFAULT);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_PO_ERROR:\n\t\t\t\tif (sc.atLineEnd)\n\t\t\t\t\tsc.SetState(SCE_PO_DEFAULT);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_PO_MSGCTXT_TEXT:\n\t\t\tcase SCE_PO_MSGID_TEXT:\n\t\t\tcase SCE_PO_MSGSTR_TEXT:\n\t\t\t\tif (sc.atLineEnd) { // invalid inside a string\n\t\t\t\t\tif (sc.state == SCE_PO_MSGCTXT_TEXT)\n\t\t\t\t\t\tsc.ChangeState(SCE_PO_MSGCTXT_TEXT_EOL);\n\t\t\t\t\telse if (sc.state == SCE_PO_MSGID_TEXT)\n\t\t\t\t\t\tsc.ChangeState(SCE_PO_MSGID_TEXT_EOL);\n\t\t\t\t\telse if (sc.state == SCE_PO_MSGSTR_TEXT)\n\t\t\t\t\t\tsc.ChangeState(SCE_PO_MSGSTR_TEXT_EOL);\n\t\t\t\t\tsc.SetState(SCE_PO_DEFAULT);\n\t\t\t\t\tescaped = false;\n\t\t\t\t} else {\n\t\t\t\t\tif (escaped)\n\t\t\t\t\t\tescaped = false;\n\t\t\t\t\telse if (sc.ch == '\\\\')\n\t\t\t\t\t\tescaped = true;\n\t\t\t\t\telse if (sc.ch == '\"')\n\t\t\t\t\t\tsc.ForwardSetState(SCE_PO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// whether we should enter a new state\n\t\tif (sc.state == SCE_PO_DEFAULT) {\n\t\t\t// forward to the first non-white character on the line\n\t\t\tbool atLineStart = sc.atLineStart;\n\t\t\tif (atLineStart) {\n\t\t\t\t// reset line state if it is set to comment state so empty lines don't get\n\t\t\t\t// comment line state, and the folding code folds comments separately,\n\t\t\t\t// and anyway the styling don't use line state for comments\n\t\t\t\tif (curLineState == SCE_PO_COMMENT)\n\t\t\t\t\tcurLineState = SCE_PO_DEFAULT;\n\n\t\t\t\twhile (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch))\n\t\t\t\t\tsc.Forward();\n\t\t\t}\n\n\t\t\tif (atLineStart && sc.ch == '#') {\n\t\t\t\tif (sc.chNext == '.')\n\t\t\t\t\tsc.SetState(SCE_PO_PROGRAMMER_COMMENT);\n\t\t\t\telse if (sc.chNext == ':')\n\t\t\t\t\tsc.SetState(SCE_PO_REFERENCE);\n\t\t\t\telse if (sc.chNext == ',')\n\t\t\t\t\tsc.SetState(SCE_PO_FLAGS);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_PO_COMMENT);\n\t\t\t} else if (atLineStart && sc.Match(\"msgid\")) { // includes msgid_plural\n\t\t\t\tsc.SetState(SCE_PO_MSGID);\n\t\t\t} else if (atLineStart && sc.Match(\"msgstr\")) { // includes [] suffixes\n\t\t\t\tsc.SetState(SCE_PO_MSGSTR);\n\t\t\t} else if (atLineStart && sc.Match(\"msgctxt\")) {\n\t\t\t\tsc.SetState(SCE_PO_MSGCTXT);\n\t\t\t} else if (sc.ch == '\"') {\n\t\t\t\tif (curLineState == SCE_PO_MSGCTXT || curLineState == SCE_PO_MSGCTXT_TEXT)\n\t\t\t\t\tsc.SetState(SCE_PO_MSGCTXT_TEXT);\n\t\t\t\telse if (curLineState == SCE_PO_MSGID || curLineState == SCE_PO_MSGID_TEXT)\n\t\t\t\t\tsc.SetState(SCE_PO_MSGID_TEXT);\n\t\t\t\telse if (curLineState == SCE_PO_MSGSTR || curLineState == SCE_PO_MSGSTR_TEXT)\n\t\t\t\t\tsc.SetState(SCE_PO_MSGSTR_TEXT);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_PO_ERROR);\n\t\t\t} else if (! isspacechar(sc.ch))\n\t\t\t\tsc.SetState(SCE_PO_ERROR);\n\n\t\t\tif (sc.state != SCE_PO_DEFAULT)\n\t\t\t\tcurLineState = sc.state;\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tcurLine = styler.GetLine(sc.currentPos);\n\t\t\tstyler.SetLineState(curLine, curLineState);\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic int FindNextNonEmptyLineState(Sci_PositionU startPos, Accessor &styler) {\n\tSci_PositionU length = styler.Length();\n\tfor (Sci_PositionU i = startPos; i < length; i++) {\n\t\tif (! isspacechar(styler[i])) {\n\t\t\treturn styler.GetLineState(styler.GetLine(i));\n\t\t}\n\t}\n\treturn 0;\n}\n\nstatic void FoldPODoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tif (! styler.GetPropertyInt(\"fold\"))\n\t\treturn;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\") != 0;\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\n\tSci_PositionU endPos = startPos + length;\n\tSci_Position curLine = styler.GetLine(startPos);\n\tint lineState = styler.GetLineState(curLine);\n\tint nextLineState;\n\tint level = styler.LevelAt(curLine) & SC_FOLDLEVELNUMBERMASK;\n\tint nextLevel;\n\tint visible = 0;\n\tint chNext = styler[startPos];\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tint ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i+1);\n\n\t\tif (! isspacechar(ch)) {\n\t\t\tvisible++;\n\t\t} else if ((ch == '\\r' && chNext != '\\n') || ch == '\\n' || i+1 >= endPos) {\n\t\t\tint lvl = level;\n\t\t\tSci_Position nextLine = curLine + 1;\n\n\t\t\tnextLineState = styler.GetLineState(nextLine);\n\t\t\tif ((lineState != SCE_PO_COMMENT || foldComment) &&\n\t\t\t\t\tnextLineState == lineState &&\n\t\t\t\t\tFindNextNonEmptyLineState(i, styler) == lineState)\n\t\t\t\tnextLevel = SC_FOLDLEVELBASE + 1;\n\t\t\telse\n\t\t\t\tnextLevel = SC_FOLDLEVELBASE;\n\n\t\t\tif (nextLevel > level)\n\t\t\t\tlvl |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (visible == 0 && foldCompact)\n\t\t\t\tlvl |= SC_FOLDLEVELWHITEFLAG;\n\n\t\t\tstyler.SetLevel(curLine, lvl);\n\n\t\t\tlineState = nextLineState;\n\t\t\tcurLine = nextLine;\n\t\t\tlevel = nextLevel;\n\t\t\tvisible = 0;\n\t\t}\n\t}\n}\n\nstatic const char *const poWordListDesc[] = {\n\t0\n};\n\nextern const LexerModule lmPO(SCLEX_PO, ColourisePODoc, \"po\", FoldPODoc, poWordListDesc);\n"
  },
  {
    "path": "lexers/LexPOV.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexPOV.cxx\n ** Lexer for POV-Ray SDL (Persistance of Vision Raytracer, Scene Description Language).\n ** Written by Philippe Lhoste but this is mostly a derivative of LexCPP...\n **/\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// Some points that distinguish from a simple C lexer:\n// Identifiers start only by a character.\n// No line continuation character.\n// Strings are limited to 256 characters.\n// Directives are similar to preprocessor commands,\n// but we match directive keywords and colorize incorrect ones.\n// Block comments can be nested (code stolen from my code in LexLua).\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordChar(int ch) {\n\treturn ch < 0x80 && (isalnum(ch) || ch == '_');\n}\n\nstatic inline bool IsAWordStart(int ch) {\n\treturn ch < 0x80 && isalpha(ch);\n}\n\nstatic inline bool IsANumberChar(int ch) {\n\t// Not exactly following number definition (several dots are seen as OK, etc.)\n\t// but probably enough in most cases.\n\treturn (ch < 0x80) &&\n\t        (isdigit(ch) || toupper(ch) == 'E' ||\n             ch == '.' || ch == '-' || ch == '+');\n}\n\nstatic void ColourisePovDoc(\n\tSci_PositionU startPos,\n\tSci_Position length,\n\tint initStyle,\n\tWordList *keywordlists[],\n    Accessor &styler) {\n\n\tWordList &keywords1 = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\tWordList &keywords4 = *keywordlists[3];\n\tWordList &keywords5 = *keywordlists[4];\n\tWordList &keywords6 = *keywordlists[5];\n\tWordList &keywords7 = *keywordlists[6];\n\tWordList &keywords8 = *keywordlists[7];\n\n\tSci_Position currentLine = styler.GetLine(startPos);\n\t// Initialize the block comment /* */ nesting level, if we are inside such a comment.\n\tint blockCommentLevel = 0;\n\tif (initStyle == SCE_POV_COMMENT) {\n\t\tblockCommentLevel = styler.GetLineState(currentLine - 1);\n\t}\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_POV_STRINGEOL || initStyle == SCE_POV_COMMENTLINE) {\n\t\tinitStyle = SCE_POV_DEFAULT;\n\t}\n\n\tshort stringLen = 0;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\tif (sc.atLineEnd) {\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tcurrentLine = styler.GetLine(sc.currentPos);\n\t\t\tif (sc.state == SCE_POV_COMMENT) {\n\t\t\t\t// Inside a block comment, we set the line state\n\t\t\t\tstyler.SetLineState(currentLine, blockCommentLevel);\n\t\t\t} else {\n\t\t\t\t// Reset the line state\n\t\t\t\tstyler.SetLineState(currentLine, 0);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineStart && (sc.state == SCE_POV_STRING)) {\n\t\t\t// Prevent SCE_POV_STRINGEOL from leaking back to previous line\n\t\t\tsc.SetState(SCE_POV_STRING);\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_POV_OPERATOR) {\n\t\t\tsc.SetState(SCE_POV_DEFAULT);\n\t\t} else if (sc.state == SCE_POV_NUMBER) {\n\t\t\t// We stop the number definition on non-numerical non-dot non-eE non-sign char\n\t\t\tif (!IsANumberChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_POV_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POV_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\tif (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POV_WORD2);\n\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POV_WORD3);\n\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POV_WORD4);\n\t\t\t\t} else if (keywords5.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POV_WORD5);\n\t\t\t\t} else if (keywords6.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POV_WORD6);\n\t\t\t\t} else if (keywords7.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POV_WORD7);\n\t\t\t\t} else if (keywords8.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POV_WORD8);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_POV_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POV_DIRECTIVE) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tchar *p;\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\tp = s;\n\t\t\t\t// Skip # and whitespace between # and directive word\n\t\t\t\tdo {\n\t\t\t\t\tp++;\n\t\t\t\t} while ((*p == ' ' || *p == '\\t') && *p != '\\0');\n\t\t\t\tif (!keywords1.InList(p)) {\n\t\t\t\t\tsc.ChangeState(SCE_POV_BADDIRECTIVE);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_POV_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POV_COMMENT) {\n\t\t\tif (sc.Match('/', '*')) {\n\t\t\t\tblockCommentLevel++;\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match('*', '/') && blockCommentLevel > 0) {\n\t\t\t\tblockCommentLevel--;\n\t\t\t\tsc.Forward();\n\t\t\t\tif (blockCommentLevel == 0) {\n\t\t\t\t\tsc.ForwardSetState(SCE_POV_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (sc.state == SCE_POV_COMMENTLINE) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_POV_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POV_STRING) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tstringLen++;\n\t\t\t\tif (strchr(\"abfnrtuv0'\\\"\", sc.chNext)) {\n\t\t\t\t\t// Compound characters are counted as one.\n\t\t\t\t\t// Note: for Unicode chars \\u, we shouldn't count the next 4 digits...\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_POV_DEFAULT);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_POV_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_POV_DEFAULT);\n\t\t\t} else {\n\t\t\t\tstringLen++;\n\t\t\t}\n\t\t\tif (stringLen > 256) {\n\t\t\t\t// Strings are limited to 256 chars\n\t\t\t\tsc.SetState(SCE_POV_STRINGEOL);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POV_STRINGEOL) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\\\') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_C_DEFAULT);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ForwardSetState(SCE_POV_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_POV_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_POV_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_POV_IDENTIFIER);\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tblockCommentLevel = 1;\n\t\t\t\tsc.SetState(SCE_POV_COMMENT);\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tsc.SetState(SCE_POV_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_POV_STRING);\n\t\t\t\tstringLen = 0;\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_POV_DIRECTIVE);\n\t\t\t\t// Skip whitespace between # and directive word\n\t\t\t\tdo {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} while ((sc.ch == ' ' || sc.ch == '\\t') && sc.More());\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.SetState(SCE_POV_DEFAULT);\n\t\t\t\t}\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_POV_OPERATOR);\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void FoldPovDoc(\n\tSci_PositionU startPos,\n\tSci_Position length,\n\tint initStyle,\n\tWordList *[],\n\tAccessor &styler) {\n\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldDirective = styler.GetPropertyInt(\"fold.directive\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (foldComment && (style == SCE_POV_COMMENT)) {\n\t\t\tif (stylePrev != SCE_POV_COMMENT) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if ((styleNext != SCE_POV_COMMENT) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (foldComment && (style == SCE_POV_COMMENTLINE)) {\n\t\t\tif ((ch == '/') && (chNext == '/')) {\n\t\t\t\tchar chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (foldDirective && (style == SCE_POV_DIRECTIVE)) {\n\t\t\tif (ch == '#') {\n\t\t\t\tSci_PositionU j=i+1;\n\t\t\t\twhile ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (style == SCE_POV_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const povWordLists[] = {\n\t\"Language directives\",\n\t\"Objects & CSG & Appearance\",\n\t\"Types & Modifiers & Items\",\n\t\"Predefined Identifiers\",\n\t\"Predefined Functions\",\n\t\"User defined 1\",\n\t\"User defined 2\",\n\t\"User defined 3\",\n\t0,\n};\n\nextern const LexerModule lmPOV(SCLEX_POV, ColourisePovDoc, \"pov\", FoldPovDoc, povWordLists);\n"
  },
  {
    "path": "lexers/LexPS.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexPS.cxx\n ** Lexer for PostScript\n **\n ** Written by Nigel Hathaway <nigel@bprj.co.uk>.\n ** The License.txt file describes the conditions under which this software may be distributed.\n **/\n\n// Previous releases of this lexer included support for marking token starts with\n// a style byte indicator. This was used by the wxGhostscript IDE/debugger.\n// Style byte indicators were removed in version 3.4.3.\n// Anyone wanting to restore this functionality for wxGhostscript using 'modern'\n// indicators can examine the earlier source in the Mercurial repository.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsASelfDelimitingChar(const int ch) {\n    return (ch == '[' || ch == ']' || ch == '{' || ch == '}' ||\n            ch == '/' || ch == '<' || ch == '>' ||\n            ch == '(' || ch == ')' || ch == '%');\n}\n\nstatic inline bool IsAWhitespaceChar(const int ch) {\n    return (ch == ' '  || ch == '\\t' || ch == '\\r' ||\n            ch == '\\n' || ch == '\\f' || ch == '\\0');\n}\n\nstatic bool IsABaseNDigit(const int ch, const int base) {\n    int maxdig = '9';\n    int letterext = -1;\n\n    if (base <= 10)\n        maxdig = '0' + base - 1;\n    else\n        letterext = base - 11;\n\n    return ((ch >= '0' && ch <= maxdig) ||\n            (ch >= 'A' && ch <= ('A' + letterext)) ||\n            (ch >= 'a' && ch <= ('a' + letterext)));\n}\n\nstatic inline bool IsABase85Char(const int ch) {\n    return ((ch >= '!' && ch <= 'u') || ch == 'z');\n}\n\nstatic void ColourisePSDoc(\n    Sci_PositionU startPos,\n    Sci_Position length,\n    int initStyle,\n    WordList *keywordlists[],\n    Accessor &styler) {\n\n    WordList &keywords1 = *keywordlists[0];\n    WordList &keywords2 = *keywordlists[1];\n    WordList &keywords3 = *keywordlists[2];\n    WordList &keywords4 = *keywordlists[3];\n    WordList &keywords5 = *keywordlists[4];\n\n    StyleContext sc(startPos, length, initStyle, styler);\n\n    // property ps.level\n    // Define level (0..3) of PostScript handled and thus set of keywords. Default is 3.\n    int pslevel = styler.GetPropertyInt(\"ps.level\", 3);\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int nestTextCurrent = 0;\n    if (lineCurrent > 0 && initStyle == SCE_PS_TEXT)\n        nestTextCurrent = styler.GetLineState(lineCurrent - 1);\n    int numRadix = 0;\n    bool numHasPoint = false;\n    bool numHasExponent = false;\n    bool numHasSign = false;\n\n    for (; sc.More(); sc.Forward()) {\n        if (sc.atLineStart)\n            lineCurrent = styler.GetLine(sc.currentPos);\n\n        // Determine if the current state should terminate.\n        if (sc.state == SCE_PS_COMMENT || sc.state == SCE_PS_DSC_VALUE) {\n            if (sc.atLineEnd) {\n                sc.SetState(SCE_C_DEFAULT);\n            }\n        } else if (sc.state == SCE_PS_DSC_COMMENT) {\n            if (sc.ch == ':') {\n                sc.Forward();\n                if (!sc.atLineEnd)\n                    sc.SetState(SCE_PS_DSC_VALUE);\n                else\n                    sc.SetState(SCE_C_DEFAULT);\n            } else if (sc.atLineEnd) {\n                sc.SetState(SCE_C_DEFAULT);\n            } else if (IsAWhitespaceChar(sc.ch) && sc.ch != '\\r') {\n                sc.ChangeState(SCE_PS_COMMENT);\n            }\n        } else if (sc.state == SCE_PS_NUMBER) {\n            if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) {\n                if ((sc.chPrev == '+' || sc.chPrev == '-' ||\n                     sc.chPrev == 'E' || sc.chPrev == 'e') && numRadix == 0)\n                    sc.ChangeState(SCE_PS_NAME);\n                sc.SetState(SCE_C_DEFAULT);\n            } else if (sc.ch == '#') {\n                if (numHasPoint || numHasExponent || numHasSign || numRadix != 0) {\n                    sc.ChangeState(SCE_PS_NAME);\n                } else {\n                    char szradix[5];\n                    sc.GetCurrent(szradix, 4);\n                    numRadix = atoi(szradix);\n                    if (numRadix < 2 || numRadix > 36)\n                        sc.ChangeState(SCE_PS_NAME);\n                }\n            } else if ((sc.ch == 'E' || sc.ch == 'e') && numRadix == 0) {\n                if (numHasExponent) {\n                    sc.ChangeState(SCE_PS_NAME);\n                } else {\n                    numHasExponent = true;\n                    if (sc.chNext == '+' || sc.chNext == '-')\n                        sc.Forward();\n                }\n            } else if (sc.ch == '.') {\n                if (numHasPoint || numHasExponent || numRadix != 0) {\n                    sc.ChangeState(SCE_PS_NAME);\n                } else {\n                    numHasPoint = true;\n                }\n            } else if (numRadix == 0) {\n                if (!IsABaseNDigit(sc.ch, 10))\n                    sc.ChangeState(SCE_PS_NAME);\n            } else {\n                if (!IsABaseNDigit(sc.ch, numRadix))\n                    sc.ChangeState(SCE_PS_NAME);\n            }\n        } else if (sc.state == SCE_PS_NAME || sc.state == SCE_PS_KEYWORD) {\n            if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) {\n                char s[100];\n                sc.GetCurrent(s, sizeof(s));\n                if ((pslevel >= 1 && keywords1.InList(s)) ||\n                    (pslevel >= 2 && keywords2.InList(s)) ||\n                    (pslevel >= 3 && keywords3.InList(s)) ||\n                    keywords4.InList(s) || keywords5.InList(s)) {\n                    sc.ChangeState(SCE_PS_KEYWORD);\n                }\n                sc.SetState(SCE_C_DEFAULT);\n            }\n        } else if (sc.state == SCE_PS_LITERAL || sc.state == SCE_PS_IMMEVAL) {\n            if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch))\n                sc.SetState(SCE_C_DEFAULT);\n        } else if (sc.state == SCE_PS_PAREN_ARRAY || sc.state == SCE_PS_PAREN_DICT ||\n                   sc.state == SCE_PS_PAREN_PROC) {\n            sc.SetState(SCE_C_DEFAULT);\n        } else if (sc.state == SCE_PS_TEXT) {\n            if (sc.ch == '(') {\n                nestTextCurrent++;\n            } else if (sc.ch == ')') {\n                if (--nestTextCurrent == 0)\n                   sc.ForwardSetState(SCE_PS_DEFAULT);\n            } else if (sc.ch == '\\\\') {\n                sc.Forward();\n            }\n        } else if (sc.state == SCE_PS_HEXSTRING) {\n            if (sc.ch == '>') {\n                sc.ForwardSetState(SCE_PS_DEFAULT);\n            } else if (!IsABaseNDigit(sc.ch, 16) && !IsAWhitespaceChar(sc.ch)) {\n                sc.SetState(SCE_PS_HEXSTRING);\n                styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);\n            }\n        } else if (sc.state == SCE_PS_BASE85STRING) {\n            if (sc.Match('~', '>')) {\n                sc.Forward();\n                sc.ForwardSetState(SCE_PS_DEFAULT);\n            } else if (!IsABase85Char(sc.ch) && !IsAWhitespaceChar(sc.ch)) {\n                sc.SetState(SCE_PS_BASE85STRING);\n                styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);\n            }\n        }\n\n        // Determine if a new state should be entered.\n        if (sc.state == SCE_C_DEFAULT) {\n\n            if (sc.ch == '[' || sc.ch == ']') {\n                sc.SetState(SCE_PS_PAREN_ARRAY);\n            } else if (sc.ch == '{' || sc.ch == '}') {\n                sc.SetState(SCE_PS_PAREN_PROC);\n            } else if (sc.ch == '/') {\n                if (sc.chNext == '/') {\n                    sc.SetState(SCE_PS_IMMEVAL);\n                    sc.Forward();\n                } else {\n                    sc.SetState(SCE_PS_LITERAL);\n                }\n            } else if (sc.ch == '<') {\n                if (sc.chNext == '<') {\n                    sc.SetState(SCE_PS_PAREN_DICT);\n                    sc.Forward();\n                } else if (sc.chNext == '~') {\n                    sc.SetState(SCE_PS_BASE85STRING);\n                    sc.Forward();\n                } else {\n                    sc.SetState(SCE_PS_HEXSTRING);\n                }\n            } else if (sc.ch == '>' && sc.chNext == '>') {\n                    sc.SetState(SCE_PS_PAREN_DICT);\n                    sc.Forward();\n            } else if (sc.ch == '>' || sc.ch == ')') {\n                sc.SetState(SCE_C_DEFAULT);\n                styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);\n            } else if (sc.ch == '(') {\n                sc.SetState(SCE_PS_TEXT);\n                nestTextCurrent = 1;\n            } else if (sc.ch == '%') {\n                if (sc.chNext == '%' && sc.atLineStart) {\n                    sc.SetState(SCE_PS_DSC_COMMENT);\n                    sc.Forward();\n                    if (sc.chNext == '+') {\n                        sc.Forward();\n                        sc.ForwardSetState(SCE_PS_DSC_VALUE);\n                    }\n                } else {\n                    sc.SetState(SCE_PS_COMMENT);\n                }\n            } else if ((sc.ch == '+' || sc.ch == '-' || sc.ch == '.') &&\n                       IsABaseNDigit(sc.chNext, 10)) {\n                sc.SetState(SCE_PS_NUMBER);\n                numRadix = 0;\n                numHasPoint = (sc.ch == '.');\n                numHasExponent = false;\n                numHasSign = (sc.ch == '+' || sc.ch == '-');\n            } else if ((sc.ch == '+' || sc.ch == '-') && sc.chNext == '.' &&\n                       IsABaseNDigit(sc.GetRelative(2), 10)) {\n                sc.SetState(SCE_PS_NUMBER);\n                numRadix = 0;\n                numHasPoint = false;\n                numHasExponent = false;\n                numHasSign = true;\n            } else if (IsABaseNDigit(sc.ch, 10)) {\n                sc.SetState(SCE_PS_NUMBER);\n                numRadix = 0;\n                numHasPoint = false;\n                numHasExponent = false;\n                numHasSign = false;\n            } else if (!IsAWhitespaceChar(sc.ch)) {\n                sc.SetState(SCE_PS_NAME);\n            }\n        }\n\n        if (sc.atLineEnd)\n            styler.SetLineState(lineCurrent, nestTextCurrent);\n    }\n\n    sc.Complete();\n}\n\nstatic void FoldPSDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],\n                       Accessor &styler) {\n    bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n    bool foldAtElse = styler.GetPropertyInt(\"fold.at.else\", 0) != 0;\n    Sci_PositionU endPos = startPos + length;\n    int visibleChars = 0;\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int levelCurrent = SC_FOLDLEVELBASE;\n    if (lineCurrent > 0)\n        levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n    int levelMinCurrent = levelCurrent;\n    int levelNext = levelCurrent;\n    char chNext = styler[startPos];\n    int styleNext = styler.StyleAt(startPos);\n    for (Sci_PositionU i = startPos; i < endPos; i++) {\n        char ch = chNext;\n        chNext = styler.SafeGetCharAt(i + 1);\n        int style = styleNext;\n        styleNext = styler.StyleAt(i + 1);\n        bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');  //mac??\n        if ((style & 31) == SCE_PS_PAREN_PROC) {\n            if (ch == '{') {\n                // Measure the minimum before a '{' to allow\n                // folding on \"} {\"\n                if (levelMinCurrent > levelNext) {\n                    levelMinCurrent = levelNext;\n                }\n                levelNext++;\n            } else if (ch == '}') {\n                levelNext--;\n            }\n        }\n        if (atEOL) {\n            int levelUse = levelCurrent;\n            if (foldAtElse) {\n                levelUse = levelMinCurrent;\n            }\n            int lev = levelUse | levelNext << 16;\n            if (visibleChars == 0 && foldCompact)\n                lev |= SC_FOLDLEVELWHITEFLAG;\n            if (levelUse < levelNext)\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            if (lev != styler.LevelAt(lineCurrent)) {\n                styler.SetLevel(lineCurrent, lev);\n            }\n            lineCurrent++;\n            levelCurrent = levelNext;\n            levelMinCurrent = levelCurrent;\n            visibleChars = 0;\n        }\n        if (!isspacechar(ch))\n            visibleChars++;\n    }\n}\n\nstatic const char * const psWordListDesc[] = {\n    \"PS Level 1 operators\",\n    \"PS Level 2 operators\",\n    \"PS Level 3 operators\",\n    \"RIP-specific operators\",\n    \"User-defined operators\",\n    0\n};\n\nextern const LexerModule lmPS(SCLEX_PS, ColourisePSDoc, \"ps\", FoldPSDoc, psWordListDesc);\n"
  },
  {
    "path": "lexers/LexPascal.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexPascal.cxx\n ** Lexer for Pascal.\n ** Written by Laurent le Tynevez\n ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002\n ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)\n ** Completely rewritten by Marko Njezic <sf@maxempire.com> October 2008\n **/\n\n/*\n\nA few words about features of the new completely rewritten LexPascal...\n\nGenerally speaking LexPascal tries to support all available Delphi features (up\nto Delphi XE4 at this time).\n\n~ HIGHLIGHTING:\n\nIf you enable \"lexer.pascal.smart.highlighting\" property, some keywords will\nonly be highlighted in appropriate context. As implemented those are keywords\nrelated to property and DLL exports declarations (similar to how Delphi IDE\nworks).\n\nFor example, keywords \"read\" and \"write\" will only be highlighted if they are in\nproperty declaration:\n\nproperty MyProperty: boolean read FMyProperty write FMyProperty;\n\n~ FOLDING:\n\nFolding is supported in the following cases:\n\n- Folding of stream-like comments\n- Folding of groups of consecutive line comments\n- Folding of preprocessor blocks (the following preprocessor blocks are\nsupported: IF / IFEND; IFDEF, IFNDEF, IFOPT / ENDIF and REGION / ENDREGION\nblocks), including nesting of preprocessor blocks up to 255 levels\n- Folding of code blocks on appropriate keywords (the following code blocks are\nsupported: \"begin, asm, record, try, case / end\" blocks, class & object\ndeclarations and interface declarations)\n\nRemarks:\n\n- Folding of code blocks tries to handle all special cases in which folding\nshould not occur. As implemented those are:\n\n1. Structure \"record case / end\" (there's only one \"end\" statement and \"case\" is\nignored as fold point)\n2. Forward class declarations (\"type TMyClass = class;\") and object method\ndeclarations (\"TNotifyEvent = procedure(Sender: TObject) of object;\") are\nignored as fold points\n3. Simplified complete class declarations (\"type TMyClass = class(TObject);\")\nare ignored as fold points\n4. Every other situation when class keyword doesn't actually start class\ndeclaration (\"class procedure\", \"class function\", \"class of\", \"class var\",\n\"class property\" and \"class operator\")\n5. Forward (disp)interface declarations (\"type IMyInterface = interface;\") are\nignored as fold points\n\n- Folding of code blocks inside preprocessor blocks is disabled (any comments\ninside them will be folded fine) because there is no guarantee that complete\ncode block will be contained inside folded preprocessor block in which case\nfolded code block could end prematurely at the end of preprocessor block if\nthere is no closing statement inside. This was done in order to properly process\ndocument that may contain something like this:\n\ntype\n{$IFDEF UNICODE}\n  TMyClass = class(UnicodeAncestor)\n{$ELSE}\n  TMyClass = class(AnsiAncestor)\n{$ENDIF}\n  private\n  ...\n  public\n  ...\n  published\n  ...\nend;\n\nIf class declarations were folded, then the second class declaration would end\nat \"$ENDIF\" statement, first class statement would end at \"end;\" statement and\npreprocessor \"$IFDEF\" block would go all the way to the end of document.\nHowever, having in mind all this, if you want to enable folding of code blocks\ninside preprocessor blocks, you can disable folding of preprocessor blocks by\nchanging \"fold.preprocessor\" property, in which case everything inside them\nwould be folded.\n\n~ KEYWORDS:\n\nThe list of keywords that can be used in pascal.properties file (up to Delphi\nXE4):\n\n- Keywords: absolute abstract and array as asm assembler automated begin case\ncdecl class const constructor delayed deprecated destructor dispid dispinterface\ndiv do downto dynamic else end except experimental export exports external far\nfile final finalization finally for forward function goto helper if\nimplementation in inherited initialization inline interface is label library\nmessage mod near nil not object of on operator or out overload override packed\npascal platform private procedure program property protected public published\nraise record reference register reintroduce repeat resourcestring safecall\nsealed set shl shr static stdcall strict string then threadvar to try type unit\nunsafe until uses var varargs virtual while winapi with xor\n\n- Keywords related to the \"smart highlithing\" feature: add default implements\nindex name nodefault read readonly remove stored write writeonly\n\n- Keywords related to Delphi packages (in addition to all above): package\ncontains requires\n\n*/\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <map>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\n// Options used for LexerPascal\nstruct OptionsPascal {\n\tbool bSmartHighlighting = true;\n\tbool fold = false;\n\tbool foldComment = false;\n\tbool foldPreprocessor = false;\n\tbool foldCompact = true;\n};\n\nconst char *const pascalWordListDesc[] = {\n\t\"Keywords\",\n\tnullptr\n};\n\nstruct OptionSetPascal : public OptionSet<OptionsPascal> {\n\tOptionSetPascal() {\n\t\tDefineProperty(\"lexer.pascal.smart.highlighting\", &OptionsPascal::bSmartHighlighting,\n\t\t\t\"Set to 0 to not completely handle some complex features like 'property'.\");\n\n\t\tDefineProperty(\"fold\", &OptionsPascal::fold);\n\n\t\tDefineProperty(\"fold.comment\", &OptionsPascal::foldComment);\n\n\t\tDefineProperty(\"fold.preprocessor\", &OptionsPascal::foldPreprocessor);\n\n\t\tDefineProperty(\"fold.compact\", &OptionsPascal::foldCompact);\n\n\t\tDefineWordListSets(pascalWordListDesc);\n\t}\n};\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer pascal SCLEX_PASCAL SCE_PAS_\n\t0, \"SCE_PAS_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_PAS_IDENTIFIER\", \"identifier\", \"Identifier\",\n\t2, \"SCE_PAS_COMMENT\", \"comment\", \"Comment: { ... }\",\n\t3, \"SCE_PAS_COMMENT2\", \"comment\", \"Comment: (* ... *)\",\n\t4, \"SCE_PAS_COMMENTLINE\",\"comment line\", \"Line Comment: // ...\",\n\t5, \"SCE_PAS_PREPROCESSOR\", \"preprocessor\", \"Preprocessor: {$ ... }\",\n\t6, \"SCE_PAS_PREPROCESSOR2\", \"preprocessor\", \"Preprocessor: (*$ ... *)\",\n\t7, \"SCE_PAS_NUMBER\", \"literal numeric\", \"Number\",\n\t8, \"SCE_PAS_HEXNUMBER\", \"literal numeric\", \"Hex Number\",\n\t9, \"SCE_PAS_WORD\", \"keyword\", \"Keyword\",\n\t10, \"SCE_PAS_STRING\", \"literal string\", \"Single quoted string\",\n\t11, \"SCE_PAS_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n\t12, \"SCE_PAS_CHARACTER\",\"literal string character\", \"Character\",\n\t13, \"SCE_PAS_OPERATOR\",\"operator\", \"Operator\",\n\t14, \"SCE_PAS_ASM\", \"assembler\", \"Inline Assembler\", \n\t15, \"SCE_PAS_MULTILINESTRING\", \"literal string multiline\", \"Triple quoted multiline string\",\n};\n\nclass LexerPascal : public DefaultLexer {\n\tWordList keywords;\n\tOptionsPascal options;\n\tOptionSetPascal osPascal;\npublic:\n\texplicit LexerPascal() :\n\t\tDefaultLexer(\"pascal\", SCLEX_PASCAL, lexicalClasses, std::size(lexicalClasses)) {\n\t\tSetOptionSet(&osPascal);\n\t}\n\tLexerPascal(const LexerPascal &) = delete;\n\tLexerPascal(LexerPascal &&) = delete;\n\tLexerPascal &operator=(const LexerPascal &) = delete;\n\tLexerPascal &operator=(LexerPascal &&) = delete;\n\t~LexerPascal() override = default;\n\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, Scintilla::IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, Scintilla::IDocument *pAccess) override;\n\n\tstatic ILexer5 *LexerFactoryPascal() {\n\t\treturn new LexerPascal();\n\t}\n};\n\nSci_Position SCI_METHOD LexerPascal::PropertySet(const char *key, const char *val) {\n\tif (osPascal.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerPascal::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid GetRangeLowered(Sci_Position start,\n\t\tSci_Position end,\n\t\tLexAccessor &styler,\n\t\tchar *s,\n\t\tSci_Position len) {\n\tSci_Position i = 0;\n\twhile ((i < end - start + 1) && (i < len-1)) {\n\t\ts[i] = MakeLowerCase(styler[start + i]);\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n}\n\nvoid GetForwardRangeLowered(Sci_Position start,\n\t\tconst CharacterSet &charSet,\n\t\tLexAccessor &styler,\n\t\tchar *s,\n\t\tSci_Position len) {\n\tSci_Position i = 0;\n\twhile ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) {\n\t\ts[i] = MakeLowerCase(styler.SafeGetCharAt(start + i));\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n\n}\n\nenum {\n\tstateInAsm = 0x1000,\n\tstateInProperty = 0x2000,\n\tstateInExport = 0x4000,\n\tstateFoldInPreprocessor = 0x0100,\n\tstateFoldInRecord = 0x0200,\n\tstateFoldInPreprocessorLevelMask = 0x00FF,\n\tstateFoldMaskAll = 0x0FFF\n};\n\nvoid ClassifyPascalWord(const WordList &keywords, StyleContext &sc, int &curLineState, bool bSmartHighlighting) {\n\tchar s[100];\n\tsc.GetCurrentLowered(s, sizeof(s));\n\tif (keywords.InList(s)) {\n\t\tif (curLineState & stateInAsm) {\n\t\t\tif (strcmp(s, \"end\") == 0 && sc.GetRelative(-4) != '@') {\n\t\t\t\tcurLineState &= ~stateInAsm;\n\t\t\t\tsc.ChangeState(SCE_PAS_WORD);\n\t\t\t} else {\n\t\t\t\tsc.ChangeState(SCE_PAS_ASM);\n\t\t\t}\n\t\t} else {\n\t\t\tbool ignoreKeyword = false;\n\t\t\tif (strcmp(s, \"asm\") == 0) {\n\t\t\t\tcurLineState |= stateInAsm;\n\t\t\t} else if (bSmartHighlighting) {\n\t\t\t\tif (strcmp(s, \"property\") == 0) {\n\t\t\t\t\tcurLineState |= stateInProperty;\n\t\t\t\t} else if (strcmp(s, \"exports\") == 0) {\n\t\t\t\t\tcurLineState |= stateInExport;\n\t\t\t\t} else if (!(curLineState & (stateInProperty | stateInExport)) && strcmp(s, \"index\") == 0) {\n\t\t\t\t\tignoreKeyword = true;\n\t\t\t\t} else if (!(curLineState & stateInExport) && strcmp(s, \"name\") == 0) {\n\t\t\t\t\tignoreKeyword = true;\n\t\t\t\t} else if (!(curLineState & stateInProperty) &&\n\t\t\t\t\t(strcmp(s, \"read\") == 0 || strcmp(s, \"write\") == 0 ||\n\t\t\t\t\t strcmp(s, \"default\") == 0 || strcmp(s, \"nodefault\") == 0 ||\n\t\t\t\t\t strcmp(s, \"stored\") == 0 || strcmp(s, \"implements\") == 0 ||\n\t\t\t\t\t strcmp(s, \"readonly\") == 0 || strcmp(s, \"writeonly\") == 0 ||\n\t\t\t\t\t strcmp(s, \"add\") == 0 || strcmp(s, \"remove\") == 0)) {\n\t\t\t\t\tignoreKeyword = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!ignoreKeyword) {\n\t\t\t\tsc.ChangeState(SCE_PAS_WORD);\n\t\t\t}\n\t\t}\n\t} else if (curLineState & stateInAsm) {\n\t\tsc.ChangeState(SCE_PAS_ASM);\n\t}\n\tsc.SetState(SCE_PAS_DEFAULT);\n}\n\nvoid LexerPascal::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, Scintilla::IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\n\tconst CharacterSet setWordStart(CharacterSet::setAlpha, \"_\", 0x80, true);\n\tconst CharacterSet setWord(CharacterSet::setAlphaNum, \"_\", 0x80, true);\n\tconst CharacterSet setNumber(CharacterSet::setDigits, \".-+eE\");\n\tconst CharacterSet setHexNumber(CharacterSet::setDigits, \"abcdefABCDEF\");\n\tconst CharacterSet setOperator(CharacterSet::setNone, \"#$&'()*+,-./:;<=>@[]^{}\");\n\n\t// To terminate SCE_PAS_MULTILINESTRING, need to know number of quotes at start so retreat to starting line. \n\tif ((initStyle == SCE_PAS_MULTILINESTRING) && (startPos > 0)) {\n\t\tconst Sci_Position endPos = startPos + length;\n\t\t// Look for line start not in SCE_PAS_MULTILINESTRING\n\t\tSci_Position line = std::max<Sci_Position>(styler.GetLine(startPos) - 1, 0);\n\t\twhile ((line > 0) && (styler.StyleIndexAt(styler.LineStart(line)) == SCE_PAS_MULTILINESTRING)) {\n\t\t\tline--;\n\t\t}\n\t\tstartPos = styler.LineStart(line);\n\t\tlength = endPos - startPos;\n\t\tinitStyle = startPos == 0 ? SCE_PAS_DEFAULT : styler.StyleIndexAt(startPos - 1);\n\t}\n\n\tint curLineState = 0;\n\tsize_t countQuotes = 0;\n\tbool inStringIndent = true;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tif (sc.currentLine > 0) {\n\t\tcurLineState = styler.GetLineState(sc.currentLine - 1);\n\t}\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\tif (sc.atLineStart) {\n\t\t\tinStringIndent = true;\n\t\t}\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_PAS_NUMBER:\n\t\t\t\tif (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) {\n\t\t\t\t\tsc.SetState(SCE_PAS_DEFAULT);\n\t\t\t\t} else if (sc.ch == '-' || sc.ch == '+') {\n\t\t\t\t\tif (sc.chPrev != 'E' && sc.chPrev != 'e') {\n\t\t\t\t\t\tsc.SetState(SCE_PAS_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_IDENTIFIER:\n\t\t\t\tif (!setWord.Contains(sc.ch)) {\n\t\t\t\t\tClassifyPascalWord(keywords, sc, curLineState, options.bSmartHighlighting);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_HEXNUMBER:\n\t\t\t\tif (!setHexNumber.Contains(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_PAS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_COMMENT:\n\t\t\tcase SCE_PAS_PREPROCESSOR:\n\t\t\t\tif (sc.ch == '}') {\n\t\t\t\t\tsc.ForwardSetState(SCE_PAS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_COMMENT2:\n\t\t\tcase SCE_PAS_PREPROCESSOR2:\n\t\t\t\tif (sc.Match('*', ')')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_PAS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_PAS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_STRING:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_PAS_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\'' && sc.chNext == '\\'') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\tsc.ForwardSetState(SCE_PAS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_STRINGEOL:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_PAS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_MULTILINESTRING:\n\t\t\t\tif (inStringIndent) {\n\t\t\t\t\t// Only terminate for first multi-quote on line\n\t\t\t\t\tinStringIndent = IsASpaceOrTab(sc.ch);\n\t\t\t\t\tif (sc.Match(\"'''\")) {\n\t\t\t\t\t\tsize_t foundQuotes = 3;\n\t\t\t\t\t\twhile (sc.GetRelativeChar(foundQuotes) == '\\'') {\n\t\t\t\t\t\t\tfoundQuotes++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (foundQuotes >= countQuotes) {\n\t\t\t\t\t\t\tsc.Forward(countQuotes);\n\t\t\t\t\t\t\tsc.SetState(SCE_PAS_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_CHARACTER:\n\t\t\t\tif (!setHexNumber.Contains(sc.ch) && sc.ch != '$') {\n\t\t\t\t\tsc.SetState(SCE_PAS_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_OPERATOR:\n\t\t\t\tif (options.bSmartHighlighting && sc.chPrev == ';') {\n\t\t\t\t\tcurLineState &= ~(stateInProperty | stateInExport);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_PAS_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_PAS_ASM:\n\t\t\t\tsc.SetState(SCE_PAS_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tdefault:\t// Only SCE_PAS_DEFAULT missing from cases\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_PAS_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) && !(curLineState & stateInAsm)) {\n\t\t\t\tsc.SetState(SCE_PAS_NUMBER);\n\t\t\t} else if (setWordStart.Contains(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_PAS_IDENTIFIER);\n\t\t\t} else if (sc.ch == '$' && !(curLineState & stateInAsm)) {\n\t\t\t\tsc.SetState(SCE_PAS_HEXNUMBER);\n\t\t\t} else if (sc.Match('{', '$')) {\n\t\t\t\tsc.SetState(SCE_PAS_PREPROCESSOR);\n\t\t\t} else if (sc.ch == '{') {\n\t\t\t\tsc.SetState(SCE_PAS_COMMENT);\n\t\t\t} else if (sc.Match(\"(*$\")) {\n\t\t\t\tsc.SetState(SCE_PAS_PREPROCESSOR2);\n\t\t\t} else if (sc.Match('(', '*')) {\n\t\t\t\tsc.SetState(SCE_PAS_COMMENT2);\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tsc.SetState(SCE_PAS_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tif (sc.Match(\"'''\")) {\n\t\t\t\t\t// Count quotes for handling 5-quote and 7-quote ... variants\n\t\t\t\t\tcountQuotes = 3;\n\t\t\t\t\twhile (sc.GetRelativeChar(countQuotes) == '\\'') {\n\t\t\t\t\t\tcountQuotes++;\n\t\t\t\t\t}\n\t\t\t\t\tif (((countQuotes % 2) == 1) && AnyOf(sc.GetRelativeChar(countQuotes), '\\r', '\\n')) {\n\t\t\t\t\t\tsc.SetState(SCE_PAS_MULTILINESTRING);\n\t\t\t\t\t\tsc.Forward(countQuotes);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_PAS_STRING);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_PAS_STRING);\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_PAS_CHARACTER);\n\t\t\t} else if (setOperator.Contains(sc.ch) && !(curLineState & stateInAsm)) {\n\t\t\t\tsc.SetState(SCE_PAS_OPERATOR);\n\t\t\t} else if (curLineState & stateInAsm) {\n\t\t\t\tsc.SetState(SCE_PAS_ASM);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tstyler.SetLineState(sc.currentLine, curLineState);\n\t\t}\n\t}\n\n\tif (sc.state == SCE_PAS_IDENTIFIER && setWord.Contains(sc.chPrev)) {\n\t\tClassifyPascalWord(keywords, sc, curLineState, options.bSmartHighlighting);\n\t}\n\n\tsc.Complete();\n}\n\nconstexpr bool IsStreamCommentStyle(int style) noexcept {\n\treturn style == SCE_PAS_COMMENT || style == SCE_PAS_COMMENT2;\n}\n\nbool IsCommentLine(Sci_Position line, LexAccessor &styler) {\n\tconst Sci_Position pos = styler.LineStart(line);\n\tconst Sci_Position eolPos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eolPos; i++) {\n\t\tconst char ch = styler[i];\n\t\tconst char chNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int style = styler.StyleIndexAt(i);\n\t\tif (ch == '/' && chNext == '/' && style == SCE_PAS_COMMENTLINE) {\n\t\t\treturn true;\n\t\t} else if (!IsASpaceOrTab(ch)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn false;\n}\n\nconstexpr unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) noexcept {\n\treturn lineFoldStateCurrent & stateFoldInPreprocessorLevelMask;\n}\n\nvoid SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) noexcept {\n\tlineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask;\n\tlineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;\n}\n\nvoid ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,\n\t\tSci_Position startPos, LexAccessor &styler) {\n\tconst CharacterSet setWord(CharacterSet::setAlpha);\n\n\tchar s[11];\t// Size of the longest possible keyword + one additional character + null\n\tGetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s));\n\n\tunsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);\n\n\tif (strcmp(s, \"if\") == 0 ||\n\t\tstrcmp(s, \"ifdef\") == 0 ||\n\t\tstrcmp(s, \"ifndef\") == 0 ||\n\t\tstrcmp(s, \"ifopt\") == 0 ||\n\t\tstrcmp(s, \"region\") == 0) {\n\t\tnestLevel++;\n\t\tSetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);\n\t\tlineFoldStateCurrent |= stateFoldInPreprocessor;\n\t\tlevelCurrent++;\n\t} else if (strcmp(s, \"endif\") == 0 ||\n\t\tstrcmp(s, \"ifend\") == 0 ||\n\t\tstrcmp(s, \"endregion\") == 0) {\n\t\tnestLevel--;\n\t\tSetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);\n\t\tif (nestLevel == 0) {\n\t\t\tlineFoldStateCurrent &= ~stateFoldInPreprocessor;\n\t\t}\n\t\tlevelCurrent--;\n\t\tif (levelCurrent < SC_FOLDLEVELBASE) {\n\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t}\n\t}\n}\n\nSci_Position SkipWhiteSpace(Sci_Position currentPos, Sci_Position endPos,\n\t\tLexAccessor &styler, bool includeChars = false) {\n\tconst CharacterSet setWord(CharacterSet::setAlphaNum, \"_\");\n\tSci_Position j = currentPos + 1;\n\tchar ch = styler.SafeGetCharAt(j);\n\twhile ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\\r' || ch == '\\n' ||\n\t\tIsStreamCommentStyle(styler.StyleAt(j)) || (includeChars && setWord.Contains(ch)))) {\n\t\tj++;\n\t\tch = styler.SafeGetCharAt(j);\n\t}\n\treturn j;\n}\n\nvoid ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,\n\t\tSci_Position startPos, Sci_Position endPos,\n\t\tSci_Position lastStart, Sci_Position currentPos, LexAccessor &styler) {\n\tchar s[100];\n\tGetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));\n\n\tif (strcmp(s, \"record\") == 0) {\n\t\tlineFoldStateCurrent |= stateFoldInRecord;\n\t\tlevelCurrent++;\n\t} else if (strcmp(s, \"begin\") == 0 ||\n\t\tstrcmp(s, \"asm\") == 0 ||\n\t\tstrcmp(s, \"try\") == 0 ||\n\t\t(strcmp(s, \"case\") == 0 && !(lineFoldStateCurrent & stateFoldInRecord))) {\n\t\tlevelCurrent++;\n\t} else if (strcmp(s, \"class\") == 0 || strcmp(s, \"object\") == 0) {\n\t\t// \"class\" & \"object\" keywords require special handling...\n\t\tbool ignoreKeyword = false;\n\t\tSci_Position j = SkipWhiteSpace(currentPos, endPos, styler);\n\t\tif (j < endPos) {\n\t\t\tconst CharacterSet setWordStart(CharacterSet::setAlpha, \"_\");\n\t\t\tconst CharacterSet setWord(CharacterSet::setAlphaNum, \"_\");\n\n\t\t\tif (styler.SafeGetCharAt(j) == ';') {\n\t\t\t\t// Handle forward class declarations (\"type TMyClass = class;\")\n\t\t\t\t// and object method declarations (\"TNotifyEvent = procedure(Sender: TObject) of object;\")\n\t\t\t\tignoreKeyword = true;\n\t\t\t} else if (strcmp(s, \"class\") == 0) {\n\t\t\t\t// \"class\" keyword has a few more special cases...\n\t\t\t\tif (styler.SafeGetCharAt(j) == '(') {\n\t\t\t\t\t// Handle simplified complete class declarations (\"type TMyClass = class(TObject);\")\n\t\t\t\t\tj = SkipWhiteSpace(j, endPos, styler, true);\n\t\t\t\t\tif (j < endPos && styler.SafeGetCharAt(j) == ')') {\n\t\t\t\t\t\tj = SkipWhiteSpace(j, endPos, styler);\n\t\t\t\t\t\tif (j < endPos && styler.SafeGetCharAt(j) == ';') {\n\t\t\t\t\t\t\tignoreKeyword = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (setWordStart.Contains(styler.SafeGetCharAt(j))) {\n\t\t\t\t\tchar s2[11];\t// Size of the longest possible keyword + one additional character + null\n\t\t\t\t\tGetForwardRangeLowered(j, setWord, styler, s2, sizeof(s2));\n\n\t\t\t\t\tif (strcmp(s2, \"procedure\") == 0 ||\n\t\t\t\t\t\tstrcmp(s2, \"function\") == 0 ||\n\t\t\t\t\t\tstrcmp(s2, \"of\") == 0 ||\n\t\t\t\t\t\tstrcmp(s2, \"var\") == 0 ||\n\t\t\t\t\t\tstrcmp(s2, \"property\") == 0 ||\n\t\t\t\t\t\tstrcmp(s2, \"operator\") == 0) {\n\t\t\t\t\t\tignoreKeyword = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!ignoreKeyword) {\n\t\t\tlevelCurrent++;\n\t\t}\n\t} else if (strcmp(s, \"interface\") == 0) {\n\t\t// \"interface\" keyword requires special handling...\n\t\tbool ignoreKeyword = true;\n\t\tSci_Position j = lastStart - 1;\n\t\tchar ch = styler.SafeGetCharAt(j);\n\t\twhile ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\\r' || ch == '\\n' ||\n\t\t\tIsStreamCommentStyle(styler.StyleAt(j)))) {\n\t\t\tj--;\n\t\t\tch = styler.SafeGetCharAt(j);\n\t\t}\n\t\tif (j >= startPos && styler.SafeGetCharAt(j) == '=') {\n\t\t\tignoreKeyword = false;\n\t\t}\n\t\tif (!ignoreKeyword) {\n\t\t\tconst Sci_Position k = SkipWhiteSpace(currentPos, endPos, styler);\n\t\t\tif (k < endPos && styler.SafeGetCharAt(k) == ';') {\n\t\t\t\t// Handle forward interface declarations (\"type IMyInterface = interface;\")\n\t\t\t\tignoreKeyword = true;\n\t\t\t}\n\t\t}\n\t\tif (!ignoreKeyword) {\n\t\t\tlevelCurrent++;\n\t\t}\n\t} else if (strcmp(s, \"dispinterface\") == 0) {\n\t\t// \"dispinterface\" keyword requires special handling...\n\t\tbool ignoreKeyword = false;\n\t\tconst Sci_Position j = SkipWhiteSpace(currentPos, endPos, styler);\n\t\tif (j < endPos && styler.SafeGetCharAt(j) == ';') {\n\t\t\t// Handle forward dispinterface declarations (\"type IMyInterface = dispinterface;\")\n\t\t\tignoreKeyword = true;\n\t\t}\n\t\tif (!ignoreKeyword) {\n\t\t\tlevelCurrent++;\n\t\t}\n\t} else if (strcmp(s, \"end\") == 0) {\n\t\tlineFoldStateCurrent &= ~stateFoldInRecord;\n\t\tlevelCurrent--;\n\t\tif (levelCurrent < SC_FOLDLEVELBASE) {\n\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t}\n\t}\n}\n\nvoid LexerPascal::Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, Scintilla::IDocument *pAccess) {\n\n\tif (!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\n\tSci_Position startPos = startPos_;\n\tconst Sci_Position endPos = startPos + length;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\t// Backtrack to previous line in case need to fix its fold status\n\tif (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tstartPos = styler.LineStart(lineCurrent);\n\t\tinitStyle = (startPos > 0) ? styler.StyleIndexAt(startPos - 1) : 0;\n\t}\n\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tint lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleIndexAt(startPos);\n\tint style = initStyle;\n\n\tint visibleChars = 0;\n\n\tSci_Position lastStart = 0;\n\tconst CharacterSet setWord(CharacterSet::setAlphaNum, \"_\", 0x80, true);\n\n\tfor (Sci_Position i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleIndexAt(i + 1);\n\t\tconst bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (options.foldComment && IsStreamCommentStyle(style)) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler))\n\t\t{\n\t\t\tif (!IsCommentLine(lineCurrent - 1, styler)\n\t\t\t    && IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (IsCommentLine(lineCurrent - 1, styler)\n\t\t\t         && !IsCommentLine(lineCurrent+1, styler))\n\t\t\t\tlevelCurrent--;\n\t\t}\n\t\tif (options.foldPreprocessor) {\n\t\t\tif (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') {\n\t\t\t\tClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler);\n\t\t\t} else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*'\n\t\t\t           && styler.SafeGetCharAt(i + 2) == '$') {\n\t\t\t\tClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);\n\t\t\t}\n\t\t}\n\n\t\tif (stylePrev != SCE_PAS_WORD && style == SCE_PAS_WORD)\n\t\t{\n\t\t\t// Store last word start point.\n\t\t\tlastStart = i;\n\t\t}\n\t\tif (stylePrev == SCE_PAS_WORD && !(lineFoldStateCurrent & stateFoldInPreprocessor)) {\n\t\t\tif(setWord.Contains(ch) && !setWord.Contains(chNext)) {\n\t\t\t\tClassifyPascalWordFoldPoint(levelCurrent, lineFoldStateCurrent, startPos, endPos, lastStart, i, styler);\n\t\t\t}\n\t\t}\n\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && options.foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tconst int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent;\n\t\t\tstyler.SetLineState(lineCurrent, newLineState);\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t}\n\n\t// If we didn't reach the EOL in previous loop, store line level and whitespace information.\n\t// The rest will be filled in later...\n\tint lev = levelPrev;\n\tif (visibleChars == 0 && options.foldCompact)\n\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\tstyler.SetLevel(lineCurrent, lev);\n}\n\n}\n\nextern const LexerModule lmPascal(SCLEX_PASCAL, LexerPascal::LexerFactoryPascal, \"pascal\", pascalWordListDesc);\n"
  },
  {
    "path": "lexers/LexPerl.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexPerl.cxx\n ** Lexer for Perl.\n ** Converted to lexer object by \"Udo Lechner\" <dlchnr(at)gmx(dot)net>\n **/\n// Copyright 1998-2008 by Neil Hodgson <neilh@scintilla.org>\n// Lexical analysis fixes by Kein-Hong Man <mkh@pl.jaring.my>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\n// Info for HERE document handling from perldata.pod (reformatted):\n// ----------------------------------------------------------------\n// A line-oriented form of quoting is based on the shell ``here-doc'' syntax.\n// Following a << you specify a string to terminate the quoted material, and\n// all lines following the current line down to the terminating string are\n// the value of the item.\n// Prefixing the terminating string with a \"~\" specifies that you want to\n// use \"Indented Here-docs\" (see below).\n// * The terminating string may be either an identifier (a word), or some\n//   quoted text.\n// * If quoted, the type of quotes you use determines the treatment of the\n//   text, just as in regular quoting.\n// * An unquoted identifier works like double quotes.\n// * There must be no space between the << and the identifier.\n//   (If you put a space it will be treated as a null identifier,\n//    which is valid, and matches the first empty line.)\n//   (This is deprecated, -w warns of this syntax)\n// * The terminating string must appear by itself (unquoted and\n//   with no surrounding whitespace) on the terminating line.\n//\n// Indented Here-docs\n// ------------------\n// The here-doc modifier \"~\" allows you to indent your here-docs to\n// make the code more readable.\n// The delimiter is used to determine the exact whitespace to remove\n// from the beginning of each line. All lines must have at least the\n// same starting whitespace (except lines only containing a newline)\n// or perl will croak. Tabs and spaces can be mixed, but are matched\n// exactly. One tab will not be equal to 8 spaces!\n// Additional beginning whitespace (beyond what preceded the\n// delimiter) will be preserved.\n\n#define HERE_DELIM_MAX 256\t\t// maximum length of HERE doc delimiter\n\n#define PERLNUM_BINARY\t\t1\t// order is significant: 1-3 cannot have a dot\n#define PERLNUM_OCTAL\t\t2\n#define PERLNUM_FLOAT_EXP\t3\t// exponent part only\n#define PERLNUM_HEX\t\t\t4\t// may be a hex float\n#define PERLNUM_DECIMAL\t\t5\t// 1-5 are numbers; 6-7 are strings\n#define PERLNUM_VECTOR\t\t6\n#define PERLNUM_V_VECTOR\t7\n#define PERLNUM_BAD\t\t\t8\n\n#define BACK_NONE\t\t0\t// lookback state for bareword disambiguation:\n#define BACK_OPERATOR\t1\t// whitespace/comments are insignificant\n#define BACK_KEYWORD\t2\t// operators/keywords are needed for disambiguation\n\n#define SUB_BEGIN\t\t0\t// states for subroutine prototype scan:\n#define SUB_HAS_PROTO\t1\t// only 'prototype' attribute allows prototypes\n#define SUB_HAS_ATTRIB\t2\t// other attributes can exist leftward\n#define SUB_HAS_MODULE\t3\t// sub name can have a ::identifier part\n#define SUB_HAS_SUB\t\t4\t// 'sub' (or 'method') keyword\n\n// all interpolated styles are different from their parent styles by a constant difference\n// we also assume SCE_PL_STRING_VAR is the interpolated style with the smallest value\n#define\tINTERPOLATE_SHIFT\t(SCE_PL_STRING_VAR - SCE_PL_STRING)\n\nbool isPerlKeyword(Sci_PositionU start, Sci_PositionU end, WordList &keywords, LexAccessor &styler) {\n\t// old-style keyword matcher; needed because GetCurrent() needs\n\t// current segment to be committed, but we may abandon early...\n\tchar s[100];\n\tSci_PositionU i, len = end - start;\n\tif (len > 30) { len = 30; }\n\tfor (i = 0; i < len; i++, start++) s[i] = styler[start];\n\ts[i] = '\\0';\n\treturn keywords.InList(s);\n}\n\nint disambiguateBareword(LexAccessor &styler, Sci_PositionU bk, Sci_PositionU fw,\n        int backFlag, Sci_PositionU backPos, Sci_PositionU endPos) {\n\t// identifiers are recognized by Perl as barewords under some\n\t// conditions, the following attempts to do the disambiguation\n\t// by looking backward and forward; result in 2 LSB\n\tint result = 0;\n\tbool moreback = false;\t\t// true if passed newline/comments\n\tbool brace = false;\t\t\t// true if opening brace found\n\t// if BACK_NONE, neither operator nor keyword, so skip test\n\tif (backFlag == BACK_NONE)\n\t\treturn result;\n\t// first look backwards past whitespace/comments to set EOL flag\n\t// (some disambiguation patterns must be on a single line)\n\tif (backPos <= static_cast<Sci_PositionU>(styler.LineStart(styler.GetLine(bk))))\n\t\tmoreback = true;\n\t// look backwards at last significant lexed item for disambiguation\n\tbk = backPos - 1;\n\tint ch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));\n\tif (ch == '{' && !moreback) {\n\t\t// {bareword: possible variable spec\n\t\tbrace = true;\n\t} else if ((ch == '&' && styler.SafeGetCharAt(bk - 1) != '&')\n\t        // &bareword: subroutine call\n\t        || styler.Match(bk - 1, \"->\")\n\t        // ->bareword: part of variable spec\n\t        || styler.Match(bk - 1, \"::\")\n\t        // ::bareword: part of module spec\n\t        || styler.Match(bk - 2, \"sub\")\n\t        || styler.Match(bk - 5, \"method\")) {\n\t        // 'sub' or 'method' bareword: subroutine declaration\n\t        // (implied BACK_KEYWORD, no keywords end in 'sub'!)\n\t\tresult |= 1;\n\t}\n\t// next, scan forward after word past tab/spaces only;\n\t// if ch isn't one of '[{(,' we can skip the test\n\tif ((ch == '{' || ch == '(' || ch == '['|| ch == ',')\n\t        && fw < endPos) {\n\t\twhile (IsASpaceOrTab(ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)))\n\t\t        && fw < endPos) {\n\t\t\tfw++;\n\t\t}\n\t\tif ((ch == '}' && brace)\n\t\t        // {bareword}: variable spec\n\t\t        || styler.Match(fw, \"=>\")) {\n\t\t        // [{(, bareword=>: hash literal\n\t\t\tresult |= 2;\n\t\t}\n\t}\n\treturn result;\n}\n\nvoid skipWhitespaceComment(LexAccessor &styler, Sci_PositionU &p) {\n\t// when backtracking, we need to skip whitespace and comments\n\twhile (p > 0) {\n\t\tconst int style = styler.StyleAt(p);\n\t\tif (style != SCE_PL_DEFAULT && style != SCE_PL_COMMENTLINE)\n\t\t\tbreak;\n\t\tp--;\n\t}\n}\n\nint findPrevLexeme(LexAccessor &styler, Sci_PositionU &bk, int &style) {\n\t// scan backward past whitespace and comments to find a lexeme\n\tskipWhitespaceComment(styler, bk);\n\tif (bk == 0)\n\t\treturn 0;\n\tint sz = 1;\n\tstyle = styler.StyleAt(bk);\n\twhile (bk > 0) {\t// find extent of lexeme\n\t\tif (styler.StyleAt(bk - 1) == style) {\n\t\t\tbk--; sz++;\n\t\t} else\n\t\t\tbreak;\n\t}\n\treturn sz;\n}\n\nint styleBeforeBracePair(LexAccessor &styler, Sci_PositionU bk) {\n\t// backtrack to find open '{' corresponding to a '}', balanced\n\t// return significant style to be tested for '/' disambiguation\n\tint braceCount = 1;\n\tif (bk == 0)\n\t\treturn SCE_PL_DEFAULT;\n\twhile (--bk > 0) {\n\t\tif (styler.StyleAt(bk) == SCE_PL_OPERATOR) {\n\t\t\tint bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));\n\t\t\tif (bkch == ';') {\t// early out\n\t\t\t\tbreak;\n\t\t\t} else if (bkch == '}') {\n\t\t\t\tbraceCount++;\n\t\t\t} else if (bkch == '{') {\n\t\t\t\tif (--braceCount == 0) break;\n\t\t\t}\n\t\t}\n\t}\n\tif (bk > 0 && braceCount == 0) {\n\t\t// balanced { found, bk > 0, skip more whitespace/comments\n\t\tbk--;\n\t\tskipWhitespaceComment(styler, bk);\n\t\treturn styler.StyleAt(bk);\n\t}\n\treturn SCE_PL_DEFAULT;\n}\n\nint styleCheckIdentifier(LexAccessor &styler, Sci_PositionU bk) {\n\t// backtrack to classify sub-styles of identifier under test\n\t// return sub-style to be tested for '/' disambiguation\n\tif (styler.SafeGetCharAt(bk) == '>')\t// inputsymbol, like <foo>\n\t\treturn 1;\n\t// backtrack to check for possible \"->\" or \"::\" before identifier\n\twhile (bk > 0 && styler.StyleAt(bk) == SCE_PL_IDENTIFIER) {\n\t\tbk--;\n\t}\n\twhile (bk > 0) {\n\t\tint bkstyle = styler.StyleAt(bk);\n\t\tif (bkstyle == SCE_PL_DEFAULT\n\t\t        || bkstyle == SCE_PL_COMMENTLINE) {\n\t\t\t// skip whitespace, comments\n\t\t} else if (bkstyle == SCE_PL_OPERATOR) {\n\t\t\t// test for \"->\" and \"::\"\n\t\t\tif (styler.Match(bk - 1, \"->\") || styler.Match(bk - 1, \"::\"))\n\t\t\t\treturn 2;\n\t\t} else\n\t\t\treturn 3;\t// bare identifier\n\t\tbk--;\n\t}\n\treturn 0;\n}\n\nint podLineScan(LexAccessor &styler, Sci_PositionU &pos, Sci_PositionU endPos) {\n\t// forward scan the current line to classify line for POD style\n\tint state = -1;\n\twhile (pos < endPos) {\n\t\tint ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));\n\t\tif (ch == '\\n' || ch == '\\r') {\n\t\t\tif (ch == '\\r' && styler.SafeGetCharAt(pos + 1) == '\\n') pos++;\n\t\t\tbreak;\n\t\t}\n\t\tif (IsASpaceOrTab(ch)) {\t// whitespace, take note\n\t\t\tif (state == -1)\n\t\t\t\tstate = SCE_PL_DEFAULT;\n\t\t} else if (state == SCE_PL_DEFAULT) {\t// verbatim POD line\n\t\t\tstate = SCE_PL_POD_VERB;\n\t\t} else if (state != SCE_PL_POD_VERB) {\t// regular POD line\n\t\t\tstate = SCE_PL_POD;\n\t\t}\n\t\tpos++;\n\t}\n\tif (state == -1)\n\t\tstate = SCE_PL_DEFAULT;\n\treturn state;\n}\n\nbool styleCheckSubPrototype(LexAccessor &styler, Sci_PositionU bk) {\n\t// backtrack to identify if we're starting a subroutine prototype\n\t// we also need to ignore whitespace/comments, format is like:\n\t//     sub abc::pqr :const :prototype(...)\n\t// lexemes are tested in pairs, e.g. '::'+'pqr', ':'+'const', etc.\n\t// and a state machine generates legal subroutine syntax matches\n\tstyler.Flush();\n\tint state = SUB_BEGIN;\n\tdo {\n\t\t// find two lexemes, lexeme 2 follows lexeme 1\n\t\tint style2 = SCE_PL_DEFAULT;\n\t\tSci_PositionU pos2 = bk;\n\t\tint len2 = findPrevLexeme(styler, pos2, style2);\n\t\tint style1 = SCE_PL_DEFAULT;\n\t\tSci_PositionU pos1 = pos2;\n\t\tif (pos1 > 0) pos1--;\n\t\tint len1 = findPrevLexeme(styler, pos1, style1);\n\t\tif (len1 == 0 || len2 == 0)\t\t// lexeme pair must exist\n\t\t\tbreak;\n\n\t\t// match parts of syntax, if invalid subroutine syntax, break off\n\t\tif (style1 == SCE_PL_OPERATOR && len1 == 1 &&\n\t\t    styler.SafeGetCharAt(pos1) == ':') {\t// ':'\n\t\t\tif (style2 == SCE_PL_IDENTIFIER || style2 == SCE_PL_WORD) {\n\t\t\t\tif (len2 == 9 && styler.Match(pos2, \"prototype\")) {\t// ':' 'prototype'\n\t\t\t\t\tif (state == SUB_BEGIN) {\n\t\t\t\t\t\tstate = SUB_HAS_PROTO;\n\t\t\t\t\t} else\n\t\t\t\t\t\tbreak;\n\t\t\t\t} else {\t// ':' <attribute>\n\t\t\t\t\tif (state == SUB_HAS_PROTO || state == SUB_HAS_ATTRIB) {\n\t\t\t\t\t\tstate = SUB_HAS_ATTRIB;\n\t\t\t\t\t} else\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else\n\t\t\t\tbreak;\n\t\t} else if (style1 == SCE_PL_OPERATOR && len1 == 2 &&\n\t\t           styler.Match(pos1, \"::\")) {\t// '::'\n\t\t\tif (style2 == SCE_PL_IDENTIFIER) {\t// '::' <identifier>\n\t\t\t\tstate = SUB_HAS_MODULE;\n\t\t\t} else\n\t\t\t\tbreak;\n\t\t} else if ((style1 == SCE_PL_WORD || style1 == SCE_PL_IDENTIFIER) &&\n\t\t           ((len1 == 3 && styler.Match(pos1, \"sub\")) || \t// 'sub'\n\t\t            (len1 == 6 && styler.Match(pos1, \"method\")))) {\t// or 'method\n\t\t\tif (style2 == SCE_PL_IDENTIFIER) {\t// ('sub' | 'method') <identifier>\n\t\t\t\tstate = SUB_HAS_SUB;\n\t\t\t} else\n\t\t\t\tbreak;\n\t\t} else\n\t\t\tbreak;\n\t\tbk = pos1;\t\t\t// set position for finding next lexeme pair\n\t\tif (bk > 0) bk--;\n\t} while (state != SUB_HAS_SUB);\n\treturn (state == SUB_HAS_SUB);\n}\n\nint actualNumStyle(int numberStyle) {\n\tif (numberStyle == PERLNUM_VECTOR || numberStyle == PERLNUM_V_VECTOR) {\n\t\treturn SCE_PL_STRING;\n\t} else if (numberStyle == PERLNUM_BAD) {\n\t\treturn SCE_PL_ERROR;\n\t}\n\treturn SCE_PL_NUMBER;\n}\n\nint opposite(int ch) {\n\tif (ch == '(') return ')';\n\tif (ch == '[') return ']';\n\tif (ch == '{') return '}';\n\tif (ch == '<') return '>';\n\treturn ch;\n}\n\nbool IsCommentLine(Sci_Position line, LexAccessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tint style = styler.StyleAt(i);\n\t\tif (ch == '#' && style == SCE_PL_COMMENTLINE)\n\t\t\treturn true;\n\t\telse if (!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nbool IsPackageLine(Sci_Position line, LexAccessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tint style = styler.StyleAt(pos);\n\tif (style == SCE_PL_WORD && styler.Match(pos, \"package\")) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nint PodHeadingLevel(Sci_Position pos, LexAccessor &styler) {\n\tint lvl = static_cast<unsigned char>(styler.SafeGetCharAt(pos + 5));\n\tif (lvl >= '1' && lvl <= '4') {\n\t\treturn lvl - '0';\n\t}\n\treturn 0;\n}\n\n// An individual named option for use in an OptionSet\n\n// Options used for LexerPerl\nstruct OptionsPerl {\n\tbool fold;\n\tbool foldComment;\n\tbool foldCompact;\n\t// Custom folding of POD and packages\n\tbool foldPOD;            // fold.perl.pod\n\t// Enable folding Pod blocks when using the Perl lexer.\n\tbool foldPackage;        // fold.perl.package\n\t// Enable folding packages when using the Perl lexer.\n\n\tbool foldCommentExplicit;\n\n\tbool foldAtElse;\n\n\tOptionsPerl() {\n\t\tfold = false;\n\t\tfoldComment = false;\n\t\tfoldCompact = true;\n\t\tfoldPOD = true;\n\t\tfoldPackage = true;\n\t\tfoldCommentExplicit = true;\n\t\tfoldAtElse = false;\n\t}\n};\n\nconst char *const perlWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nstruct OptionSetPerl : public OptionSet<OptionsPerl> {\n\tOptionSetPerl() {\n\t\tDefineProperty(\"fold\", &OptionsPerl::fold);\n\n\t\tDefineProperty(\"fold.comment\", &OptionsPerl::foldComment);\n\n\t\tDefineProperty(\"fold.compact\", &OptionsPerl::foldCompact);\n\n\t\tDefineProperty(\"fold.perl.pod\", &OptionsPerl::foldPOD,\n\t\t        \"Set to 0 to disable folding Pod blocks when using the Perl lexer.\");\n\n\t\tDefineProperty(\"fold.perl.package\", &OptionsPerl::foldPackage,\n\t\t        \"Set to 0 to disable folding packages when using the Perl lexer.\");\n\n\t\tDefineProperty(\"fold.perl.comment.explicit\", &OptionsPerl::foldCommentExplicit,\n\t\t        \"Set to 0 to disable explicit folding.\");\n\n\t\tDefineProperty(\"fold.perl.at.else\", &OptionsPerl::foldAtElse,\n\t\t               \"This option enables Perl folding on a \\\"} else {\\\" line of an if statement.\");\n\n\t\tDefineWordListSets(perlWordListDesc);\n\t}\n};\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer perl SCLEX_PERL SCE_PL_:\n\t0, \"SCE_PL_DEFAULT\", \"default\", \"white space\",\n\t1, \"SCE_PL_ERROR\", \"error\", \"error\",\n\t2, \"SCE_PL_COMMENTLINE\", \"comment line\", \"comment\",\n\t3, \"SCE_PL_POD\", \"data\", \"pod: = at beginning of line\",\n\t4, \"SCE_PL_NUMBER\", \"literal numeric\", \"number\",\n\t5, \"SCE_PL_WORD\", \"keyword\", \"keyword\",\n\t6, \"SCE_PL_STRING\", \"literal string interpolated\", \"double quoted string\",\n\t7, \"SCE_PL_CHARACTER\", \"literal string\", \"single quoted string\",\n\t8, \"SCE_PL_PUNCTUATION\", \"operator\", \"symbols / punctuation. currently not used\",\n\t9, \"SCE_PL_PREPROCESSOR\", \"preprocessor unused\", \"preprocessor. currently not used\",\n\t10, \"SCE_PL_OPERATOR\", \"operator\", \"operators\",\n\t11, \"SCE_PL_IDENTIFIER\", \"identifier\", \"identifiers (functions, etc.)\",\n\t12, \"SCE_PL_SCALAR\", \"identifier\", \"scalars: $var\",\n\t13, \"SCE_PL_ARRAY\", \"identifier\", \"array: @var\",\n\t14, \"SCE_PL_HASH\", \"identifier\", \"hash: %var\",\n\t15, \"SCE_PL_SYMBOLTABLE\", \"identifier\", \"symbol table: *var\",\n\t16, \"SCE_PL_VARIABLE_INDEXER\", \"identifier unused\", \"sce_pl_variable_indexer allocated but unused\",\n\t17, \"SCE_PL_REGEX\", \"literal regex\", \"regex: /re/ or m{re}\",\n\t18, \"SCE_PL_REGSUBST\", \"literal regex\", \"substitution: s/re/ore/\",\n\t19, \"SCE_PL_LONGQUOTE\", \"literal string\", \"long quote (qq, qr, qw, qx) -- obsolete: replaced by qq, qx, qr, qw\",\n\t20, \"SCE_PL_BACKTICKS\", \"literal string interpolated\", \"back ticks\",\n\t21, \"SCE_PL_DATASECTION\", \"data\", \"data section: __data__ or __end__ at beginning of line\",\n\t22, \"SCE_PL_HERE_DELIM\", \"here-doc literal string\", \"here-doc (delimiter)\",\n\t23, \"SCE_PL_HERE_Q\", \"here-doc literal string\", \"here-doc (single quoted, q)\",\n\t24, \"SCE_PL_HERE_QQ\", \"here-doc literal string interpolated\", \"here-doc (double quoted, qq)\",\n\t25, \"SCE_PL_HERE_QX\", \"here-doc literal interpolated\", \"here-doc (back ticks, qx)\",\n\t26, \"SCE_PL_STRING_Q\", \"literal string\", \"single quoted string, generic\",\n\t27, \"SCE_PL_STRING_QQ\", \"literal string interpolated\", \"qq = double quoted string\",\n\t28, \"SCE_PL_STRING_QX\", \"literal string interpolated\", \"qx = back ticks\",\n\t29, \"SCE_PL_STRING_QR\", \"literal regex\", \"qr = regex\",\n\t30, \"SCE_PL_STRING_QW\", \"literal string interpolated\", \"qw = array\",\n\t31, \"SCE_PL_POD_VERB\", \"data\", \"pod: verbatim paragraphs\",\n\t32, \"\", \"predefined\", \"\",\n\t33, \"\", \"predefined\", \"\",\n\t34, \"\", \"predefined\", \"\",\n\t35, \"\", \"predefined\", \"\",\n\t36, \"\", \"predefined\", \"\",\n\t37, \"\", \"predefined\", \"\",\n\t38, \"\", \"predefined\", \"\",\n\t39, \"\", \"predefined\", \"\",\n\t40, \"SCE_PL_SUB_PROTOTYPE\", \"identifier\", \"subroutine prototype\",\n\t41, \"SCE_PL_FORMAT_IDENT\", \"identifier\", \"format identifier\",\n\t42, \"SCE_PL_FORMAT\", \"literal string\", \"format body\",\n\t43, \"SCE_PL_STRING_VAR\", \"identifier interpolated\", \"double quoted string (interpolated variable)\",\n\t44, \"SCE_PL_XLAT\", \"literal string\", \"translation: tr{}{} y{}{}\",\n\t45, \"\", \"unused\", \"\",\n\t46, \"\", \"unused\", \"\",\n\t47, \"\", \"unused\", \"\",\n\t48, \"\", \"unused\", \"\",\n\t49, \"\", \"unused\", \"\",\n\t50, \"\", \"unused\", \"\",\n\t51, \"\", \"unused\", \"\",\n\t52, \"\", \"unused\", \"\",\n\t53, \"\", \"unused\", \"\",\n\t54, \"SCE_PL_REGEX_VAR\", \"identifier interpolated\", \"regex: /re/ or m{re} (interpolated variable)\",\n\t55, \"SCE_PL_REGSUBST_VAR\", \"identifier interpolated\", \"substitution: s/re/ore/ (interpolated variable)\",\n\t56, \"\", \"unused\", \"\",\n\t57, \"SCE_PL_BACKTICKS_VAR\", \"identifier interpolated\", \"back ticks (interpolated variable)\",\n\t58, \"\", \"unused\", \"\",\n\t59, \"\", \"unused\", \"\",\n\t60, \"\", \"unused\", \"\",\n\t61, \"SCE_PL_HERE_QQ_VAR\", \"identifier interpolated\", \"here-doc (double quoted, qq) (interpolated variable)\",\n\t62, \"SCE_PL_HERE_QX_VAR\", \"identifier interpolated\", \"here-doc (back ticks, qx) (interpolated variable)\",\n\t63, \"\", \"unused\", \"\",\n\t64, \"SCE_PL_STRING_QQ_VAR\", \"identifier interpolated\", \"qq = double quoted string (interpolated variable)\",\n\t65, \"SCE_PL_STRING_QX_VAR\", \"identifier interpolated\", \"qx = back ticks (interpolated variable)\",\n\t66, \"SCE_PL_STRING_QR_VAR\", \"identifier interpolated\", \"qr = regex (interpolated variable)\",\n};\n\nclass LexerPerl : public DefaultLexer {\n\tCharacterSet setWordStart;\n\tCharacterSet setWord;\n\tCharacterSet setSpecialVar;\n\tCharacterSet setControlVar;\n\tWordList keywords;\n\tOptionsPerl options;\n\tOptionSetPerl osPerl;\npublic:\n\tLexerPerl() :\n\t\tDefaultLexer(\"perl\", SCLEX_PERL, lexicalClasses, std::size(lexicalClasses)),\n\t\tsetWordStart(CharacterSet::setAlpha, \"_\", 0x80, true),\n\t\tsetWord(CharacterSet::setAlphaNum, \"_\", 0x80, true),\n\t\tsetSpecialVar(CharacterSet::setNone, \"\\\"$;<>&`'+,./\\\\%:=~!?@[]\"),\n\t\tsetControlVar(CharacterSet::setNone, \"ACDEFHILMNOPRSTVWX\") {\n\t}\n\tvirtual ~LexerPerl() {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osPerl.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osPerl.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osPerl.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osPerl.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osPerl.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn 0;\n\t}\n\n\tstatic ILexer5 *LexerFactoryPerl() {\n\t\treturn new LexerPerl();\n\t}\n\tint InputSymbolScan(StyleContext &sc);\n\tvoid InterpolateSegment(StyleContext &sc, int maxSeg, bool isPattern=false);\n};\n\nSci_Position SCI_METHOD LexerPerl::PropertySet(const char *key, const char *val) {\n\tif (osPerl.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerPerl::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = 0;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nint LexerPerl::InputSymbolScan(StyleContext &sc) {\n\t// forward scan for matching > on same line; file handles\n\tint c, sLen = 0;\n\twhile ((c = sc.GetRelativeCharacter(++sLen)) != 0) {\n\t\tif (c == '\\r' || c == '\\n') {\n\t\t\treturn 0;\n\t\t} else if (c == '>') {\n\t\t\tif (sc.Match(\"<=>\"))\t// '<=>' case\n\t\t\t\treturn 0;\n\t\t\treturn sLen;\n\t\t}\n\t}\n\treturn 0;\n}\n\nvoid LexerPerl::InterpolateSegment(StyleContext &sc, int maxSeg, bool isPattern) {\n\t// interpolate a segment (with no active backslashes or delimiters within)\n\t// switch in or out of an interpolation style or continue current style\n\t// commit variable patterns if found, trim segment, repeat until done\n\twhile (maxSeg > 0) {\n\t\tbool isVar = false;\n\t\tint sLen = 0;\n\t\tif ((maxSeg > 1) && (sc.ch == '$' || sc.ch == '@')) {\n\t\t\t// $#[$]*word [$@][$]*word (where word or {word} is always present)\n\t\t\tbool braces = false;\n\t\t\tsLen = 1;\n\t\t\tif (sc.ch == '$' && sc.chNext == '#') {\t// starts with $#\n\t\t\t\tsLen++;\n\t\t\t}\n\t\t\twhile ((maxSeg > sLen) && (sc.GetRelativeCharacter(sLen) == '$'))\t// >0 $ dereference within\n\t\t\t\tsLen++;\n\t\t\tif ((maxSeg > sLen) && (sc.GetRelativeCharacter(sLen) == '{')) {\t// { start for {word}\n\t\t\t\tsLen++;\n\t\t\t\tbraces = true;\n\t\t\t}\n\t\t\tif (maxSeg > sLen) {\n\t\t\t\tint c = sc.GetRelativeCharacter(sLen);\n\t\t\t\tif (setWordStart.Contains(c)) {\t// word (various)\n\t\t\t\t\tsLen++;\n\t\t\t\t\tisVar = true;\n\t\t\t\t\twhile (maxSeg > sLen) {\n\t\t\t\t\t\tif (!setWord.Contains(sc.GetRelativeCharacter(sLen)))\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tsLen++;\n\t\t\t\t\t}\n\t\t\t\t} else if (braces && IsADigit(c) && (sLen == 2)) {\t// digit for ${digit}\n\t\t\t\t\tsLen++;\n\t\t\t\t\tisVar = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (braces) {\n\t\t\t\tif ((maxSeg > sLen) && (sc.GetRelativeCharacter(sLen) == '}')) {\t// } end for {word}\n\t\t\t\t\tsLen++;\n\t\t\t\t} else\n\t\t\t\t\tisVar = false;\n\t\t\t}\n\t\t}\n\t\tif (!isVar && (maxSeg > 1)) {\t// $- or @-specific variable patterns\n\t\t\tint c = sc.chNext;\n\t\t\tif (sc.ch == '$') {\n\t\t\t\tsLen = 1;\n\t\t\t\tif (IsADigit(c)) {\t// $[0-9] and slurp trailing digits\n\t\t\t\t\tsLen++;\n\t\t\t\t\tisVar = true;\n\t\t\t\t\twhile ((maxSeg > sLen) && IsADigit(sc.GetRelativeCharacter(sLen)))\n\t\t\t\t\t\tsLen++;\n\t\t\t\t} else if (setSpecialVar.Contains(c)) {\t// $ special variables\n\t\t\t\t\tsLen++;\n\t\t\t\t\tisVar = true;\n\t\t\t\t} else if (!isPattern && ((c == '(') || (c == ')') || (c == '|'))) {\t// $ additional\n\t\t\t\t\tsLen++;\n\t\t\t\t\tisVar = true;\n\t\t\t\t} else if (c == '^') {\t// $^A control-char style\n\t\t\t\t\tsLen++;\n\t\t\t\t\tif ((maxSeg > sLen) && setControlVar.Contains(sc.GetRelativeCharacter(sLen))) {\n\t\t\t\t\t\tsLen++;\n\t\t\t\t\t\tisVar = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '@') {\n\t\t\t\tsLen = 1;\n\t\t\t\tif (!isPattern && ((c == '+') || (c == '-'))) {\t// @ specials non-pattern\n\t\t\t\t\tsLen++;\n\t\t\t\t\tisVar = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isVar) {\t// commit as interpolated variable or normal character\n\t\t\tif (sc.state < SCE_PL_STRING_VAR)\n\t\t\t\tsc.SetState(sc.state + INTERPOLATE_SHIFT);\n\t\t\tsc.Forward(sLen);\n\t\t\tmaxSeg -= sLen;\n\t\t} else {\n\t\t\tif (sc.state >= SCE_PL_STRING_VAR)\n\t\t\t\tsc.SetState(sc.state - INTERPOLATE_SHIFT);\n\t\t\tsc.Forward();\n\t\t\tmaxSeg--;\n\t\t}\n\t}\n\tif (sc.state >= SCE_PL_STRING_VAR)\n\t\tsc.SetState(sc.state - INTERPOLATE_SHIFT);\n}\n\nvoid SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\n\t// keywords that forces /PATTERN/ at all times; should track vim's behaviour\n\tWordList reWords;\n\treWords.Set(\"elsif if split while\");\n\n\t// charset classes\n\tCharacterSet setSingleCharOp(CharacterSet::setNone, \"rwxoRWXOezsfdlpSbctugkTBMAC\");\n\t// lexing of \"%*</\" operators is non-trivial; these are missing in the set below\n\tCharacterSet setPerlOperator(CharacterSet::setNone, \"^&\\\\()-+=|{}[]:;>,?!.~\");\n\tCharacterSet setQDelim(CharacterSet::setNone, \"qrwx\");\n\tCharacterSet setModifiers(CharacterSet::setAlpha);\n\tCharacterSet setPreferRE(CharacterSet::setNone, \"*/<%\");\n\t// setArray and setHash also accepts chars for special vars like $_,\n\t// which are then truncated when the next char does not match setVar\n\tCharacterSet setVar(CharacterSet::setAlphaNum, \"#$_'\", 0x80, true);\n\tCharacterSet setArray(CharacterSet::setAlpha, \"#$_+-\", 0x80, true);\n\tCharacterSet setHash(CharacterSet::setAlpha, \"#$_!^+-\", 0x80, true);\n\tCharacterSet &setPOD = setModifiers;\n\tCharacterSet setNonHereDoc(CharacterSet::setDigits, \"=$@\");\n\tCharacterSet setHereDocDelim(CharacterSet::setAlphaNum, \"_\");\n\tCharacterSet setSubPrototype(CharacterSet::setNone, \"\\\\[$@%&*+];_ \\t\");\n\tCharacterSet setRepetition(CharacterSet::setDigits, \")\\\"'\");\n\t// for format identifiers\n\tCharacterSet setFormatStart(CharacterSet::setAlpha, \"_=\");\n\tCharacterSet &setFormat = setHereDocDelim;\n\n\t// Lexer for perl often has to backtrack to start of current style to determine\n\t// which characters are being used as quotes, how deeply nested is the\n\t// start position and what the termination string is for HERE documents.\n\n\tclass HereDocCls {\t// Class to manage HERE doc sequence\n\tpublic:\n\t\tint State;\n\t\t// 0: '<<' encountered\n\t\t// 1: collect the delimiter\n\t\t// 2: here doc text (lines after the delimiter)\n\t\tint Quote;\t\t// the char after '<<'\n\t\tbool Quoted;\t\t// true if Quote in ('\\'','\"','`')\n\t\tbool StripIndent;\t// true if '<<~' requested to strip leading whitespace\n\t\tint DelimiterLength;\t// strlen(Delimiter)\n\t\tchar Delimiter[HERE_DELIM_MAX];\t// the Delimiter\n\t\tHereDocCls() {\n\t\t\tState = 0;\n\t\t\tQuote = 0;\n\t\t\tQuoted = false;\n\t\t\tStripIndent = false;\n\t\t\tDelimiterLength = 0;\n\t\t\tDelimiter[0] = '\\0';\n\t\t}\n\t\tvoid Append(int ch) {\n\t\t\tDelimiter[DelimiterLength++] = static_cast<char>(ch);\n\t\t\tDelimiter[DelimiterLength] = '\\0';\n\t\t}\n\t\t~HereDocCls() {\n\t\t}\n\t};\n\tHereDocCls HereDoc;\t\t// TODO: FIFO for stacked here-docs\n\n\tclass QuoteCls {\t// Class to manage quote pairs\n\tpublic:\n\t\tint Rep;\n\t\tint Count;\n\t\tint Up, Down;\n\t\tQuoteCls() {\n\t\t\tNew(1);\n\t\t}\n\t\tvoid New(int r = 1) {\n\t\t\tRep   = r;\n\t\t\tCount = 0;\n\t\t\tUp    = '\\0';\n\t\t\tDown  = '\\0';\n\t\t}\n\t\tvoid Open(int u) {\n\t\t\tCount++;\n\t\t\tUp    = u;\n\t\t\tDown  = opposite(Up);\n\t\t}\n\t};\n\tQuoteCls Quote;\n\n\t// additional state for number lexing\n\tint numState = PERLNUM_DECIMAL;\n\tint dotCount = 0;\n\n\tSci_PositionU endPos = startPos + length;\n\n\t// Backtrack to beginning of style if required...\n\t// If in a long distance lexical state, backtrack to find quote characters.\n\t// Includes strings (may be multi-line), numbers (additional state), format\n\t// bodies, as well as POD sections.\n\tif (initStyle == SCE_PL_HERE_Q\n\t    || initStyle == SCE_PL_HERE_QQ\n\t    || initStyle == SCE_PL_HERE_QX\n\t    || initStyle == SCE_PL_FORMAT\n\t    || initStyle == SCE_PL_HERE_QQ_VAR\n\t    || initStyle == SCE_PL_HERE_QX_VAR\n\t   ) {\n\t\t// backtrack through multiple styles to reach the delimiter start\n\t\tint delim = (initStyle == SCE_PL_FORMAT) ? SCE_PL_FORMAT_IDENT:SCE_PL_HERE_DELIM;\n\t\twhile ((startPos > 1) && (styler.StyleAt(startPos) != delim)) {\n\t\t\tstartPos--;\n\t\t}\n\t\tstartPos = styler.LineStart(styler.GetLine(startPos));\n\t\tinitStyle = styler.StyleAt(startPos - 1);\n\t}\n\tif (initStyle == SCE_PL_STRING\n\t    || initStyle == SCE_PL_STRING_QQ\n\t    || initStyle == SCE_PL_BACKTICKS\n\t    || initStyle == SCE_PL_STRING_QX\n\t    || initStyle == SCE_PL_REGEX\n\t    || initStyle == SCE_PL_STRING_QR\n\t    || initStyle == SCE_PL_REGSUBST\n\t    || initStyle == SCE_PL_STRING_VAR\n\t    || initStyle == SCE_PL_STRING_QQ_VAR\n\t    || initStyle == SCE_PL_BACKTICKS_VAR\n\t    || initStyle == SCE_PL_STRING_QX_VAR\n\t    || initStyle == SCE_PL_REGEX_VAR\n\t    || initStyle == SCE_PL_STRING_QR_VAR\n\t    || initStyle == SCE_PL_REGSUBST_VAR\n\t   ) {\n\t\t// for interpolation, must backtrack through a mix of two different styles\n\t\tint otherStyle = (initStyle >= SCE_PL_STRING_VAR) ?\n\t\t\tinitStyle - INTERPOLATE_SHIFT : initStyle + INTERPOLATE_SHIFT;\n\t\twhile (startPos > 1) {\n\t\t\tint st = styler.StyleAt(startPos - 1);\n\t\t\tif ((st != initStyle) && (st != otherStyle))\n\t\t\t\tbreak;\n\t\t\tstartPos--;\n\t\t}\n\t\tinitStyle = SCE_PL_DEFAULT;\n\t} else if (initStyle == SCE_PL_STRING_Q\n\t        || initStyle == SCE_PL_STRING_QW\n\t        || initStyle == SCE_PL_XLAT\n\t        || initStyle == SCE_PL_CHARACTER\n\t        || initStyle == SCE_PL_NUMBER\n\t        || initStyle == SCE_PL_IDENTIFIER\n\t        || initStyle == SCE_PL_ERROR\n\t        || initStyle == SCE_PL_SUB_PROTOTYPE\n\t   ) {\n\t\twhile ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {\n\t\t\tstartPos--;\n\t\t}\n\t\tinitStyle = SCE_PL_DEFAULT;\n\t} else if (initStyle == SCE_PL_POD\n\t        || initStyle == SCE_PL_POD_VERB\n\t          ) {\n\t\t// POD backtracking finds preceding blank lines and goes back past them\n\t\tSci_Position ln = styler.GetLine(startPos);\n\t\tif (ln > 0) {\n\t\t\tinitStyle = styler.StyleAt(styler.LineStart(--ln));\n\t\t\tif (initStyle == SCE_PL_POD || initStyle == SCE_PL_POD_VERB) {\n\t\t\t\twhile (ln > 0 && styler.GetLineState(ln) == SCE_PL_DEFAULT)\n\t\t\t\t\tln--;\n\t\t\t}\n\t\t\tstartPos = styler.LineStart(++ln);\n\t\t\tinitStyle = styler.StyleAt(startPos - 1);\n\t\t} else {\n\t\t\tstartPos = 0;\n\t\t\tinitStyle = SCE_PL_DEFAULT;\n\t\t}\n\t}\n\n\t// backFlag, backPos are additional state to aid identifier corner cases.\n\t// Look backwards past whitespace and comments in order to detect either\n\t// operator or keyword. Later updated as we go along.\n\tint backFlag = BACK_NONE;\n\tSci_PositionU backPos = startPos;\n\tif (backPos > 0) {\n\t\tbackPos--;\n\t\tskipWhitespaceComment(styler, backPos);\n\t\tif (styler.StyleAt(backPos) == SCE_PL_OPERATOR)\n\t\t\tbackFlag = BACK_OPERATOR;\n\t\telse if (styler.StyleAt(backPos) == SCE_PL_WORD)\n\t\t\tbackFlag = BACK_KEYWORD;\n\t\tbackPos++;\n\t}\n\n\tStyleContext sc(startPos, endPos - startPos, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\tcase SCE_PL_OPERATOR:\n\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\tbackFlag = BACK_OPERATOR;\n\t\t\tbackPos = sc.currentPos;\n\t\t\tbreak;\n\t\tcase SCE_PL_IDENTIFIER:\t\t// identifier, bareword, inputsymbol\n\t\t\tif ((!setWord.Contains(sc.ch) && sc.ch != '\\'')\n\t\t\t        || sc.Match('.', '.')\n\t\t\t        || sc.chPrev == '>') {\t// end of inputsymbol\n\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_WORD:\t\t// keyword, plus special cases\n\t\t\tif (!setWord.Contains(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\tif ((strcmp(s, \"__DATA__\") == 0) || (strcmp(s, \"__END__\") == 0)) {\n\t\t\t\t\tsc.ChangeState(SCE_PL_DATASECTION);\n\t\t\t\t} else {\n\t\t\t\t\tif ((strcmp(s, \"format\") == 0)) {\n\t\t\t\t\t\tsc.SetState(SCE_PL_FORMAT_IDENT);\n\t\t\t\t\t\tHereDoc.State = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t\tbackFlag = BACK_KEYWORD;\n\t\t\t\t\tbackPos = sc.currentPos;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_SCALAR:\n\t\tcase SCE_PL_ARRAY:\n\t\tcase SCE_PL_HASH:\n\t\tcase SCE_PL_SYMBOLTABLE:\n\t\t\tif (sc.Match(':', ':')) {\t// skip ::\n\t\t\t\tsc.Forward();\n\t\t\t} else if (!setVar.Contains(sc.ch)) {\n\t\t\t\tif (sc.LengthCurrent() == 1) {\n\t\t\t\t\t// Special variable: $(, $_ etc.\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_NUMBER:\n\t\t\t// if no early break, number style is terminated at \"(go through)\"\n\t\t\tif (sc.ch == '.') {\n\t\t\t\tif (sc.chNext == '.') {\n\t\t\t\t\t// double dot is always an operator (go through)\n\t\t\t\t} else if (numState <= PERLNUM_FLOAT_EXP) {\n\t\t\t\t\t// non-decimal number or float exponent, consume next dot\n\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\t// decimal or vectors allows dots\n\t\t\t\t\tdotCount++;\n\t\t\t\t\tif (numState == PERLNUM_DECIMAL) {\n\t\t\t\t\t\tif (dotCount <= 1)\t// number with one dot in it\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tif (IsADigit(sc.chNext)) {\t// really a vector\n\t\t\t\t\t\t\tnumState = PERLNUM_VECTOR;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// number then dot (go through)\n\t\t\t\t\t} else if (numState == PERLNUM_HEX) {\n\t\t\t\t\t\tif (dotCount <= 1 && IsADigit(sc.chNext, 16)) {\n\t\t\t\t\t\t\tbreak;\t// hex with one dot is a hex float\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// hex then dot (go through)\n\t\t\t\t\t} else if (IsADigit(sc.chNext))\t// vectors\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t// vector then dot (go through)\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '_') {\n\t\t\t\t// permissive underscoring for number and vector literals\n\t\t\t\tbreak;\n\t\t\t} else if (numState == PERLNUM_DECIMAL) {\n\t\t\t\tif (sc.ch == 'E' || sc.ch == 'e') {\t// exponent, sign\n\t\t\t\t\tnumState = PERLNUM_FLOAT_EXP;\n\t\t\t\t\tif (sc.chNext == '+' || sc.chNext == '-') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t} else if (IsADigit(sc.ch))\n\t\t\t\t\tbreak;\n\t\t\t\t// number then word (go through)\n\t\t\t} else if (numState == PERLNUM_HEX) {\n\t\t\t\tif (sc.ch == 'P' || sc.ch == 'p') {\t// hex float exponent, sign\n\t\t\t\t\tnumState = PERLNUM_FLOAT_EXP;\n\t\t\t\t\tif (sc.chNext == '+' || sc.chNext == '-') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t} else if (IsADigit(sc.ch, 16))\n\t\t\t\t\tbreak;\n\t\t\t\t// hex or hex float then word (go through)\n\t\t\t} else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {\n\t\t\t\tif (IsADigit(sc.ch))\t// vector\n\t\t\t\t\tbreak;\n\t\t\t\tif (setWord.Contains(sc.ch) && dotCount == 0) {\t// change to word\n\t\t\t\t\tsc.ChangeState(SCE_PL_IDENTIFIER);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// vector then word (go through)\n\t\t\t} else if (IsADigit(sc.ch)) {\n\t\t\t\tif (numState == PERLNUM_FLOAT_EXP) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else if (numState == PERLNUM_OCTAL) {\n\t\t\t\t\tif (sc.ch <= '7') break;\n\t\t\t\t} else if (numState == PERLNUM_BINARY) {\n\t\t\t\t\tif (sc.ch <= '1') break;\n\t\t\t\t}\n\t\t\t\t// mark invalid octal, binary numbers (go through)\n\t\t\t\tnumState = PERLNUM_BAD;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// complete current number or vector\n\t\t\tsc.ChangeState(actualNumStyle(numState));\n\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\tbreak;\n\t\tcase SCE_PL_COMMENTLINE:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_HERE_DELIM:\n\t\t\tif (HereDoc.State == 0) { // '<<' encountered\n\t\t\t\tint delim_ch = sc.chNext;\n\t\t\t\tSci_Position ws_skip = 0;\n\t\t\t\tHereDoc.State = 1;\t// pre-init HERE doc class\n\t\t\t\tHereDoc.Quote = sc.chNext;\n\t\t\t\tHereDoc.Quoted = false;\n\t\t\t\tHereDoc.StripIndent = false;\n\t\t\t\tHereDoc.DelimiterLength = 0;\n\t\t\t\tHereDoc.Delimiter[HereDoc.DelimiterLength] = '\\0';\n\t\t\t\tif (delim_ch == '~') { // was actually '<<~'\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tHereDoc.StripIndent = true;\n\t\t\t\t\tHereDoc.Quote = delim_ch = sc.chNext;\n\t\t\t\t}\n\t\t\t\tif (IsASpaceOrTab(delim_ch)) {\n\t\t\t\t\t// skip whitespace; legal only for quoted delimiters\n\t\t\t\t\tSci_PositionU i = sc.currentPos + 1;\n\t\t\t\t\twhile ((i < endPos) && IsASpaceOrTab(delim_ch)) {\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\tdelim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));\n\t\t\t\t\t}\n\t\t\t\t\tws_skip = i - sc.currentPos - 1;\n\t\t\t\t}\n\t\t\t\tif (delim_ch == '\\'' || delim_ch == '\"' || delim_ch == '`') {\n\t\t\t\t\t// a quoted here-doc delimiter; skip any whitespace\n\t\t\t\t\tsc.Forward(ws_skip + 1);\n\t\t\t\t\tHereDoc.Quote = delim_ch;\n\t\t\t\t\tHereDoc.Quoted = true;\n\t\t\t\t} else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))\n\t\t\t\t        || ws_skip > 0) {\n\t\t\t\t\t// left shift << or <<= operator cases\n\t\t\t\t\t// restore position if operator\n\t\t\t\t\tsc.ChangeState(SCE_PL_OPERATOR);\n\t\t\t\t\tsc.ForwardSetState(SCE_PL_DEFAULT);\n\t\t\t\t\tbackFlag = BACK_OPERATOR;\n\t\t\t\t\tbackPos = sc.currentPos;\n\t\t\t\t\tHereDoc.State = 0;\n\t\t\t\t} else {\n\t\t\t\t\t// specially handle initial '\\' for identifier\n\t\t\t\t\tif (ws_skip == 0 && HereDoc.Quote == '\\\\')\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t// an unquoted here-doc delimiter, no special handling\n\t\t\t\t\t// (cannot be prefixed by spaces/tabs), or\n\t\t\t\t\t// symbols terminates; deprecated zero-length delimiter\n\t\t\t\t}\n\t\t\t} else if (HereDoc.State == 1) { // collect the delimiter\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t\tif (HereDoc.Quoted) { // a quoted here-doc delimiter\n\t\t\t\t\tif (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter\n\t\t\t\t\t\tsc.ForwardSetState(SCE_PL_DEFAULT);\n\t\t\t\t\t} else if (!sc.atLineEnd) {\n\t\t\t\t\t\tif (sc.Match('\\\\', static_cast<char>(HereDoc.Quote))) { // escaped quote\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (sc.ch != '\\r') {\t// skip CR if CRLF\n\t\t\t\t\t\t\tint i = 0;\t\t\t// else append char, possibly an extended char\n\t\t\t\t\t\t\twhile (i < sc.width) {\n\t\t\t\t\t\t\t\tHereDoc.Append(static_cast<unsigned char>(styler.SafeGetCharAt(sc.currentPos + i)));\n\t\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else { // an unquoted here-doc delimiter, no extended charsets\n\t\t\t\t\tif (setHereDocDelim.Contains(sc.ch)) {\n\t\t\t\t\t\tHereDoc.Append(sc.ch);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {\n\t\t\t\t\tsc.SetState(SCE_PL_ERROR);\n\t\t\t\t\tHereDoc.State = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_HERE_Q:\n\t\tcase SCE_PL_HERE_QQ:\n\t\tcase SCE_PL_HERE_QX:\n\t\t\t// also implies HereDoc.State == 2\n\t\t\tsc.Complete();\n\t\t\tif (HereDoc.StripIndent) {\n\t\t\t\t// skip whitespace\n\t\t\t\twhile (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)\n\t\t\t\t\tsc.Forward();\n\t\t\t}\n\t\t\tif (HereDoc.DelimiterLength == 0 || sc.Match(HereDoc.Delimiter)) {\n\t\t\t\tint c = sc.GetRelative(HereDoc.DelimiterLength);\n\t\t\t\tif (c == '\\r' || c == '\\n') {\t// peek first, do not consume match\n\t\t\t\t\tsc.ForwardBytes(HereDoc.DelimiterLength);\n\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t\t\tHereDoc.State = 0;\n\t\t\t\t\tif (!sc.atLineEnd)\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (sc.state == SCE_PL_HERE_Q) {\t// \\EOF and 'EOF' non-interpolated\n\t\t\t\twhile (!sc.atLineEnd)\n\t\t\t\t\tsc.Forward();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\twhile (!sc.atLineEnd) {\t\t// \"EOF\" and `EOF` interpolated\n\t\t\t\tint c, sLen = 0, endType = 0;\n\t\t\t\twhile ((c = sc.GetRelativeCharacter(sLen)) != 0) {\n\t\t\t\t\t// scan to break string into segments\n\t\t\t\t\tif (c == '\\\\') {\n\t\t\t\t\t\tendType = 1; break;\n\t\t\t\t\t} else if (c == '\\r' || c == '\\n') {\n\t\t\t\t\t\tendType = 2; break;\n\t\t\t\t\t}\n\t\t\t\t\tsLen++;\n\t\t\t\t}\n\t\t\t\tif (sLen > 0)\t// process non-empty segments\n\t\t\t\t\tInterpolateSegment(sc, sLen);\n\t\t\t\tif (endType == 1) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\t// \\ at end-of-line does not appear to have any effect, skip\n\t\t\t\t\tif (sc.ch != '\\r' && sc.ch != '\\n')\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (endType == 2) {\n\t\t\t\t\tif (!sc.atLineEnd)\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_POD:\n\t\tcase SCE_PL_POD_VERB: {\n\t\t\t\tSci_PositionU fw = sc.currentPos;\n\t\t\t\tSci_Position ln = styler.GetLine(fw);\n\t\t\t\tif (sc.atLineStart && sc.Match(\"=cut\")) {\t// end of POD\n\t\t\t\t\tsc.SetState(SCE_PL_POD);\n\t\t\t\t\tsc.Forward(4);\n\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t\t\tstyler.SetLineState(ln, SCE_PL_POD);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tint pod = podLineScan(styler, fw, endPos);\t// classify POD line\n\t\t\t\tstyler.SetLineState(ln, pod);\n\t\t\t\tif (pod == SCE_PL_DEFAULT) {\n\t\t\t\t\tif (sc.state == SCE_PL_POD_VERB) {\n\t\t\t\t\t\tSci_PositionU fw2 = fw;\n\t\t\t\t\t\twhile (fw2 < (endPos - 1) && pod == SCE_PL_DEFAULT) {\n\t\t\t\t\t\t\tfw = fw2++;\t// penultimate line (last blank line)\n\t\t\t\t\t\t\tpod = podLineScan(styler, fw2, endPos);\n\t\t\t\t\t\t\tstyler.SetLineState(styler.GetLine(fw2), pod);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (pod == SCE_PL_POD) {\t// truncate verbatim POD early\n\t\t\t\t\t\t\tsc.SetState(SCE_PL_POD);\n\t\t\t\t\t\t} else\n\t\t\t\t\t\t\tfw = fw2;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (pod == SCE_PL_POD_VERB\t// still part of current paragraph\n\t\t\t\t\t        && (styler.GetLineState(ln - 1) == SCE_PL_POD)) {\n\t\t\t\t\t\tpod = SCE_PL_POD;\n\t\t\t\t\t\tstyler.SetLineState(ln, pod);\n\t\t\t\t\t} else if (pod == SCE_PL_POD\n\t\t\t\t\t        && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) {\n\t\t\t\t\t\tpod = SCE_PL_POD_VERB;\n\t\t\t\t\t\tstyler.SetLineState(ln, pod);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(pod);\n\t\t\t\t}\n\t\t\t\tsc.ForwardBytes(fw - sc.currentPos);\t// commit style\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_REGEX:\n\t\tcase SCE_PL_STRING_QR:\n\t\t\tif (Quote.Rep <= 0) {\n\t\t\t\tif (!setModifiers.Contains(sc.ch))\n\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t} else if (!Quote.Up && !IsASpace(sc.ch)) {\n\t\t\t\tQuote.Open(sc.ch);\n\t\t\t} else {\n\t\t\t\tint c, sLen = 0, endType = 0;\n\t\t\t\twhile ((c = sc.GetRelativeCharacter(sLen)) != 0) {\n\t\t\t\t\t// scan to break string into segments\n\t\t\t\t\tif (IsASpace(c)) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (c == '\\\\' && Quote.Up != '\\\\') {\n\t\t\t\t\t\tendType = 1; break;\n\t\t\t\t\t} else if (c == Quote.Down) {\n\t\t\t\t\t\tQuote.Count--;\n\t\t\t\t\t\tif (Quote.Count == 0) {\n\t\t\t\t\t\t\tQuote.Rep--;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (c == Quote.Up)\n\t\t\t\t\t\tQuote.Count++;\n\t\t\t\t\tsLen++;\n\t\t\t\t}\n\t\t\t\tif (sLen > 0) {\t// process non-empty segments\n\t\t\t\t\tif (Quote.Up != '\\'') {\n\t\t\t\t\t\tInterpolateSegment(sc, sLen, true);\n\t\t\t\t\t} else\t\t// non-interpolated path\n\t\t\t\t\t\tsc.Forward(sLen);\n\t\t\t\t}\n\t\t\t\tif (endType == 1)\n\t\t\t\t\tsc.Forward();\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_REGSUBST:\n\t\tcase SCE_PL_XLAT:\n\t\t\tif (Quote.Rep <= 0) {\n\t\t\t\tif (!setModifiers.Contains(sc.ch))\n\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t} else if (!Quote.Up && !IsASpace(sc.ch)) {\n\t\t\t\tQuote.Open(sc.ch);\n\t\t\t} else {\n\t\t\t\tint c, sLen = 0, endType = 0;\n\t\t\t\tbool isPattern = (Quote.Rep == 2);\n\t\t\t\twhile ((c = sc.GetRelativeCharacter(sLen)) != 0) {\n\t\t\t\t\t// scan to break string into segments\n\t\t\t\t\tif (c == '\\\\' && Quote.Up != '\\\\') {\n\t\t\t\t\t\tendType = 2; break;\n\t\t\t\t\t} else if (Quote.Count == 0 && Quote.Rep == 1) {\n\t\t\t\t\t\t// We matched something like s(...) or tr{...}, Perl 5.10\n\t\t\t\t\t\t// appears to allow almost any character for use as the\n\t\t\t\t\t\t// next delimiters. Whitespace and comments are accepted in\n\t\t\t\t\t\t// between, but we'll limit to whitespace here.\n\t\t\t\t\t\t// For '#', if no whitespace in between, it's a delimiter.\n\t\t\t\t\t\tif (IsASpace(c)) {\n\t\t\t\t\t\t\t// Keep going\n\t\t\t\t\t\t} else if (c == '#' && IsASpaceOrTab(sc.GetRelativeCharacter(sLen - 1))) {\n\t\t\t\t\t\t\tendType = 3;\n\t\t\t\t\t\t} else\n\t\t\t\t\t\t\tQuote.Open(c);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (c == Quote.Down) {\n\t\t\t\t\t\tQuote.Count--;\n\t\t\t\t\t\tif (Quote.Count == 0) {\n\t\t\t\t\t\t\tQuote.Rep--;\n\t\t\t\t\t\t\tendType = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Quote.Up == Quote.Down)\n\t\t\t\t\t\t\tQuote.Count++;\n\t\t\t\t\t\tif (endType == 1)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (c == Quote.Up) {\n\t\t\t\t\t\tQuote.Count++;\n\t\t\t\t\t} else if (IsASpace(c))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tsLen++;\n\t\t\t\t}\n\t\t\t\tif (sLen > 0) {\t// process non-empty segments\n\t\t\t\t\tif (sc.state == SCE_PL_REGSUBST && Quote.Up != '\\'') {\n\t\t\t\t\t\tInterpolateSegment(sc, sLen, isPattern);\n\t\t\t\t\t} else\t\t// non-interpolated path\n\t\t\t\t\t\tsc.Forward(sLen);\n\t\t\t\t}\n\t\t\t\tif (endType == 2) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (endType == 3)\n\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_STRING_Q:\n\t\tcase SCE_PL_STRING_QQ:\n\t\tcase SCE_PL_STRING_QX:\n\t\tcase SCE_PL_STRING_QW:\n\t\tcase SCE_PL_STRING:\n\t\tcase SCE_PL_CHARACTER:\n\t\tcase SCE_PL_BACKTICKS:\n\t\t\tif (!Quote.Down && !IsASpace(sc.ch)) {\n\t\t\t\tQuote.Open(sc.ch);\n\t\t\t} else {\n\t\t\t\tint c, sLen = 0, endType = 0;\n\t\t\t\twhile ((c = sc.GetRelativeCharacter(sLen)) != 0) {\n\t\t\t\t\t// scan to break string into segments\n\t\t\t\t\tif (IsASpace(c)) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (c == '\\\\' && Quote.Up != '\\\\') {\n\t\t\t\t\t\tendType = 2; break;\n\t\t\t\t\t} else if (c == Quote.Down) {\n\t\t\t\t\t\tQuote.Count--;\n\t\t\t\t\t\tif (Quote.Count == 0) {\n\t\t\t\t\t\t\tendType = 3; break;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (c == Quote.Up)\n\t\t\t\t\t\tQuote.Count++;\n\t\t\t\t\tsLen++;\n\t\t\t\t}\n\t\t\t\tif (sLen > 0) {\t// process non-empty segments\n\t\t\t\t\tswitch (sc.state) {\n\t\t\t\t\tcase SCE_PL_STRING:\n\t\t\t\t\tcase SCE_PL_STRING_QQ:\n\t\t\t\t\tcase SCE_PL_BACKTICKS:\n\t\t\t\t\t\tInterpolateSegment(sc, sLen);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SCE_PL_STRING_QX:\n\t\t\t\t\t\tif (Quote.Up != '\\'') {\n\t\t\t\t\t\t\tInterpolateSegment(sc, sLen);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// (continued for ' delim)\n\t\t\t\t\t\t// Falls through.\n\t\t\t\t\tdefault:\t// non-interpolated path\n\t\t\t\t\t\tsc.Forward(sLen);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (endType == 2) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else if (endType == 3)\n\t\t\t\t\tsc.ForwardSetState(SCE_PL_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_SUB_PROTOTYPE: {\n\t\t\t\tint i = 0;\n\t\t\t\t// forward scan; must all be valid proto characters\n\t\t\t\twhile (setSubPrototype.Contains(sc.GetRelative(i)))\n\t\t\t\t\ti++;\n\t\t\t\tif (sc.GetRelative(i) == ')') {\t// valid sub prototype\n\t\t\t\t\tsc.ForwardBytes(i);\n\t\t\t\t\tsc.ForwardSetState(SCE_PL_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\t// abandon prototype, restart from '('\n\t\t\t\t\tsc.ChangeState(SCE_PL_OPERATOR);\n\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_FORMAT: {\n\t\t\t\tsc.Complete();\n\t\t\t\tif (sc.Match('.')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tif (sc.atLineEnd || ((sc.ch == '\\r' && sc.chNext == '\\n')))\n\t\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t\t}\n\t\t\t\twhile (!sc.atLineEnd)\n\t\t\t\t\tsc.Forward();\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_PL_ERROR:\n\t\t\tbreak;\n\t\t}\n\t\t// Needed for specific continuation styles (one follows the other)\n\t\tswitch (sc.state) {\n\t\t\t// continued from SCE_PL_WORD\n\t\tcase SCE_PL_FORMAT_IDENT:\n\t\t\t// occupies HereDoc state 3 to avoid clashing with HERE docs\n\t\t\tif (IsASpaceOrTab(sc.ch)) {\t\t// skip whitespace\n\t\t\t\tsc.ChangeState(SCE_PL_DEFAULT);\n\t\t\t\twhile (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)\n\t\t\t\t\tsc.Forward();\n\t\t\t\tsc.SetState(SCE_PL_FORMAT_IDENT);\n\t\t\t}\n\t\t\tif (setFormatStart.Contains(sc.ch)) {\t// identifier or '='\n\t\t\t\tif (sc.ch != '=') {\n\t\t\t\t\tdo {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} while (setFormat.Contains(sc.ch));\n\t\t\t\t}\n\t\t\t\twhile (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)\n\t\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '=') {\n\t\t\t\t\tsc.ForwardSetState(SCE_PL_DEFAULT);\n\t\t\t\t\tHereDoc.State = 3;\n\t\t\t\t} else {\n\t\t\t\t\t// invalid identifier; inexact fallback, but hey\n\t\t\t\t\tsc.ChangeState(SCE_PL_IDENTIFIER);\n\t\t\t\t\tsc.SetState(SCE_PL_DEFAULT);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsc.ChangeState(SCE_PL_DEFAULT);\t// invalid identifier\n\t\t\t}\n\t\t\tbackFlag = BACK_NONE;\n\t\t\tbreak;\n\t\t}\n\n\t\t// Must check end of HereDoc states here before default state is handled\n\t\tif (HereDoc.State == 1 && sc.atLineEnd) {\n\t\t\t// Begin of here-doc (the line after the here-doc delimiter):\n\t\t\t// Lexically, the here-doc starts from the next line after the >>, but the\n\t\t\t// first line of here-doc seem to follow the style of the last EOL sequence\n\t\t\tint st_new = SCE_PL_HERE_QQ;\n\t\t\tHereDoc.State = 2;\n\t\t\tif (HereDoc.Quoted) {\n\t\t\t\tif (sc.state == SCE_PL_HERE_DELIM) {\n\t\t\t\t\t// Missing quote at end of string! We are stricter than perl.\n\t\t\t\t\t// Colour here-doc anyway while marking this bit as an error.\n\t\t\t\t\tsc.ChangeState(SCE_PL_ERROR);\n\t\t\t\t}\n\t\t\t\tswitch (HereDoc.Quote) {\n\t\t\t\tcase '\\'':\n\t\t\t\t\tst_new = SCE_PL_HERE_Q;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '\"' :\n\t\t\t\t\tst_new = SCE_PL_HERE_QQ;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '`' :\n\t\t\t\t\tst_new = SCE_PL_HERE_QX;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (HereDoc.Quote == '\\\\')\n\t\t\t\t\tst_new = SCE_PL_HERE_Q;\n\t\t\t}\n\t\t\tsc.SetState(st_new);\n\t\t}\n\t\tif (HereDoc.State == 3 && sc.atLineEnd) {\n\t\t\t// Start of format body.\n\t\t\tHereDoc.State = 0;\n\t\t\tsc.SetState(SCE_PL_FORMAT);\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_PL_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) ||\n\t\t\t        (IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) {\n\t\t\t\tsc.SetState(SCE_PL_NUMBER);\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t\tnumState = PERLNUM_DECIMAL;\n\t\t\t\tdotCount = 0;\n\t\t\t\tif (sc.ch == '0') {\t\t// hex,bin,octal\n\t\t\t\t\tif (sc.chNext == 'x' || sc.chNext == 'X') {\n\t\t\t\t\t\tnumState = PERLNUM_HEX;\n\t\t\t\t\t} else if (sc.chNext == 'b' || sc.chNext == 'B') {\n\t\t\t\t\t\tnumState = PERLNUM_BINARY;\n\t\t\t\t\t} else if (IsADigit(sc.chNext)) {\n\t\t\t\t\t\tnumState = PERLNUM_OCTAL;\n\t\t\t\t\t}\n\t\t\t\t\tif (numState != PERLNUM_DECIMAL) {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == 'v') {\t\t// vector\n\t\t\t\t\tnumState = PERLNUM_V_VECTOR;\n\t\t\t\t}\n\t\t\t} else if (setWord.Contains(sc.ch)) {\n\t\t\t\t// if immediately prefixed by '::', always a bareword\n\t\t\t\tsc.SetState(SCE_PL_WORD);\n\t\t\t\tif (sc.chPrev == ':' && sc.GetRelative(-2) == ':') {\n\t\t\t\t\tsc.ChangeState(SCE_PL_IDENTIFIER);\n\t\t\t\t}\n\t\t\t\tSci_PositionU bk = sc.currentPos;\n\t\t\t\tSci_PositionU fw = sc.currentPos + 1;\n\t\t\t\t// first check for possible quote-like delimiter\n\t\t\t\tif (sc.ch == 's' && !setWord.Contains(sc.chNext)) {\n\t\t\t\t\tsc.ChangeState(SCE_PL_REGSUBST);\n\t\t\t\t\tQuote.New(2);\n\t\t\t\t} else if (sc.ch == 'm' && !setWord.Contains(sc.chNext)) {\n\t\t\t\t\tsc.ChangeState(SCE_PL_REGEX);\n\t\t\t\t\tQuote.New();\n\t\t\t\t} else if (sc.ch == 'q' && !setWord.Contains(sc.chNext)) {\n\t\t\t\t\tsc.ChangeState(SCE_PL_STRING_Q);\n\t\t\t\t\tQuote.New();\n\t\t\t\t} else if (sc.ch == 'y' && !setWord.Contains(sc.chNext)) {\n\t\t\t\t\tsc.ChangeState(SCE_PL_XLAT);\n\t\t\t\t\tQuote.New(2);\n\t\t\t\t} else if (sc.Match('t', 'r') && !setWord.Contains(sc.GetRelative(2))) {\n\t\t\t\t\tsc.ChangeState(SCE_PL_XLAT);\n\t\t\t\t\tQuote.New(2);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tfw++;\n\t\t\t\t} else if (sc.ch == 'q' && setQDelim.Contains(sc.chNext)\n\t\t\t\t        && !setWord.Contains(sc.GetRelative(2))) {\n\t\t\t\t\tif (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ);\n\t\t\t\t\telse if (sc.chNext == 'x') sc.ChangeState(SCE_PL_STRING_QX);\n\t\t\t\t\telse if (sc.chNext == 'r') sc.ChangeState(SCE_PL_STRING_QR);\n\t\t\t\t\telse sc.ChangeState(SCE_PL_STRING_QW);\t// sc.chNext == 'w'\n\t\t\t\t\tQuote.New();\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tfw++;\n\t\t\t\t} else if (sc.ch == 'x' && (sc.chNext == '=' ||\t// repetition\n\t\t\t\t        !setWord.Contains(sc.chNext) ||\n\t\t\t\t        (setRepetition.Contains(sc.chPrev) && IsADigit(sc.chNext)))) {\n\t\t\t\t\tsc.ChangeState(SCE_PL_OPERATOR);\n\t\t\t\t}\n\t\t\t\t// if potentially a keyword, scan forward and grab word, then check\n\t\t\t\t// if it's really one; if yes, disambiguation test is performed\n\t\t\t\t// otherwise it is always a bareword and we skip a lot of scanning\n\t\t\t\tif (sc.state == SCE_PL_WORD) {\n\t\t\t\t\twhile (setWord.Contains(static_cast<unsigned char>(styler.SafeGetCharAt(fw))))\n\t\t\t\t\t\tfw++;\n\t\t\t\t\tif (!isPerlKeyword(styler.GetStartSegment(), fw, keywords, styler)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_PL_IDENTIFIER);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// if already SCE_PL_IDENTIFIER, then no ambiguity, skip this\n\t\t\t\t// for quote-like delimiters/keywords, attempt to disambiguate\n\t\t\t\t// to select for bareword, change state -> SCE_PL_IDENTIFIER\n\t\t\t\tif (sc.state != SCE_PL_IDENTIFIER && bk > 0) {\n\t\t\t\t\tif (disambiguateBareword(styler, bk, fw, backFlag, backPos, endPos))\n\t\t\t\t\t\tsc.ChangeState(SCE_PL_IDENTIFIER);\n\t\t\t\t}\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_PL_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_PL_STRING);\n\t\t\t\tQuote.New();\n\t\t\t\tQuote.Open(sc.ch);\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tif (sc.chPrev == '&' && setWordStart.Contains(sc.chNext)) {\n\t\t\t\t\t// Archaic call\n\t\t\t\t\tsc.SetState(SCE_PL_IDENTIFIER);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_PL_CHARACTER);\n\t\t\t\t\tQuote.New();\n\t\t\t\t\tQuote.Open(sc.ch);\n\t\t\t\t}\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t} else if (sc.ch == '`') {\n\t\t\t\tsc.SetState(SCE_PL_BACKTICKS);\n\t\t\t\tQuote.New();\n\t\t\t\tQuote.Open(sc.ch);\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t} else if (sc.ch == '$') {\n\t\t\t\tsc.SetState(SCE_PL_SCALAR);\n\t\t\t\tif (sc.chNext == '{') {\n\t\t\t\t\tsc.ForwardSetState(SCE_PL_OPERATOR);\n\t\t\t\t} else if (IsASpace(sc.chNext)) {\n\t\t\t\t\tsc.ForwardSetState(SCE_PL_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tif (sc.Match('`', '`') || sc.Match(':', ':')) {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t} else if (sc.ch == '@') {\n\t\t\t\tsc.SetState(SCE_PL_ARRAY);\n\t\t\t\tif (setArray.Contains(sc.chNext)) {\n\t\t\t\t\t// no special treatment\n\t\t\t\t} else if (sc.chNext == ':' && sc.GetRelative(2) == ':') {\n\t\t\t\t\tsc.ForwardBytes(2);\n\t\t\t\t} else if (sc.chNext == '{' || sc.chNext == '[') {\n\t\t\t\t\tsc.ForwardSetState(SCE_PL_OPERATOR);\n\t\t\t\t} else {\n\t\t\t\t\tsc.ChangeState(SCE_PL_OPERATOR);\n\t\t\t\t}\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t} else if (setPreferRE.Contains(sc.ch)) {\n\t\t\t\t// Explicit backward peeking to set a consistent preferRE for\n\t\t\t\t// any slash found, so no longer need to track preferRE state.\n\t\t\t\t// Find first previous significant lexed element and interpret.\n\t\t\t\t// A few symbols shares this code for disambiguation.\n\t\t\t\tbool preferRE = false;\n\t\t\t\tbool isHereDoc = sc.Match('<', '<');\n\t\t\t\tbool hereDocSpace = false;\t\t// for: SCALAR [whitespace] '<<'\n\t\t\t\tSci_PositionU bk = (sc.currentPos > 0) ? sc.currentPos - 1: 0;\n\t\t\t\tsc.Complete();\n\t\t\t\tstyler.Flush();\n\t\t\t\tif (styler.StyleAt(bk) == SCE_PL_DEFAULT)\n\t\t\t\t\thereDocSpace = true;\n\t\t\t\tskipWhitespaceComment(styler, bk);\n\t\t\t\tif (bk == 0) {\n\t\t\t\t\t// avoid backward scanning breakage\n\t\t\t\t\tpreferRE = true;\n\t\t\t\t} else {\n\t\t\t\t\tint bkstyle = styler.StyleAt(bk);\n\t\t\t\t\tint bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));\n\t\t\t\t\tswitch (bkstyle) {\n\t\t\t\t\tcase SCE_PL_OPERATOR:\n\t\t\t\t\t\tpreferRE = true;\n\t\t\t\t\t\tif (bkch == ')' || bkch == ']') {\n\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t} else if (bkch == '}') {\n\t\t\t\t\t\t\t// backtrack by counting balanced brace pairs\n\t\t\t\t\t\t\t// needed to test for variables like ${}, @{} etc.\n\t\t\t\t\t\t\tbkstyle = styleBeforeBracePair(styler, bk);\n\t\t\t\t\t\t\tif (bkstyle == SCE_PL_SCALAR\n\t\t\t\t\t\t\t        || bkstyle == SCE_PL_ARRAY\n\t\t\t\t\t\t\t        || bkstyle == SCE_PL_HASH\n\t\t\t\t\t\t\t        || bkstyle == SCE_PL_SYMBOLTABLE\n\t\t\t\t\t\t\t        || bkstyle == SCE_PL_OPERATOR) {\n\t\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (bkch == '+' || bkch == '-') {\n\t\t\t\t\t\t\tif (bkch == static_cast<unsigned char>(styler.SafeGetCharAt(bk - 1))\n\t\t\t\t\t\t\t        && bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2)))\n\t\t\t\t\t\t\t\t// exceptions for operators: unary suffixes ++, --\n\t\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SCE_PL_IDENTIFIER:\n\t\t\t\t\t\tpreferRE = true;\n\t\t\t\t\t\tbkstyle = styleCheckIdentifier(styler, bk);\n\t\t\t\t\t\tif ((bkstyle == 1) || (bkstyle == 2)) {\n\t\t\t\t\t\t\t// inputsymbol or var with \"->\" or \"::\" before identifier\n\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t} else if (bkstyle == 3) {\n\t\t\t\t\t\t\t// bare identifier, test cases follows:\n\t\t\t\t\t\t\tif (sc.ch == '/') {\n\t\t\t\t\t\t\t\t// if '/', /PATTERN/ unless digit/space immediately after '/'\n\t\t\t\t\t\t\t\t// if '//', always expect defined-or operator to follow identifier\n\t\t\t\t\t\t\t\tif (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/')\n\t\t\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t\t} else if (sc.ch == '*' || sc.ch == '%') {\n\t\t\t\t\t\t\t\tif (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*'))\n\t\t\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t\t} else if (sc.ch == '<') {\n\t\t\t\t\t\t\t\tif (IsASpace(sc.chNext) || sc.chNext == '=')\n\t\t\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SCE_PL_SCALAR:\t\t// for $var<< case:\n\t\t\t\t\t\tif (isHereDoc && hereDocSpace)\t// if SCALAR whitespace '<<', *always* a HERE doc\n\t\t\t\t\t\t\tpreferRE = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SCE_PL_WORD:\n\t\t\t\t\t\tpreferRE = true;\n\t\t\t\t\t\t// for HERE docs, always true\n\t\t\t\t\t\tif (sc.ch == '/') {\n\t\t\t\t\t\t\t// adopt heuristics similar to vim-style rules:\n\t\t\t\t\t\t\t// keywords always forced as /PATTERN/: split, if, elsif, while\n\t\t\t\t\t\t\t// everything else /PATTERN/ unless digit/space immediately after '/'\n\t\t\t\t\t\t\t// for '//', defined-or favoured unless special keywords\n\t\t\t\t\t\t\tSci_PositionU bkend = bk + 1;\n\t\t\t\t\t\t\twhile (bk > 0 && styler.StyleAt(bk - 1) == SCE_PL_WORD) {\n\t\t\t\t\t\t\t\tbk--;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (isPerlKeyword(bk, bkend, reWords, styler))\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tif (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/')\n\t\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t} else if (sc.ch == '*' || sc.ch == '%') {\n\t\t\t\t\t\t\tif (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*'))\n\t\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t} else if (sc.ch == '<') {\n\t\t\t\t\t\t\tif (IsASpace(sc.chNext) || sc.chNext == '=')\n\t\t\t\t\t\t\t\tpreferRE = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t// other styles uses the default, preferRE=false\n\t\t\t\t\tcase SCE_PL_POD:\n\t\t\t\t\tcase SCE_PL_HERE_Q:\n\t\t\t\t\tcase SCE_PL_HERE_QQ:\n\t\t\t\t\tcase SCE_PL_HERE_QX:\n\t\t\t\t\t\tpreferRE = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t\tif (isHereDoc) {\t// handle '<<', HERE doc\n\t\t\t\t\tif (sc.Match(\"<<>>\")) {\t\t// double-diamond operator (5.22)\n\t\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t\t\tsc.Forward(3);\n\t\t\t\t\t} else if (preferRE) {\n\t\t\t\t\t\tsc.SetState(SCE_PL_HERE_DELIM);\n\t\t\t\t\t\tHereDoc.State = 0;\n\t\t\t\t\t} else {\t\t// << operator\n\t\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '*') {\t// handle '*', typeglob\n\t\t\t\t\tif (preferRE) {\n\t\t\t\t\t\tsc.SetState(SCE_PL_SYMBOLTABLE);\n\t\t\t\t\t\tif (sc.chNext == ':' && sc.GetRelative(2) == ':') {\n\t\t\t\t\t\t\tsc.ForwardBytes(2);\n\t\t\t\t\t\t} else if (sc.chNext == '{') {\n\t\t\t\t\t\t\tsc.ForwardSetState(SCE_PL_OPERATOR);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t\t\tif (sc.chNext == '*') \t// exponentiation\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '%') {\t// handle '%', hash\n\t\t\t\t\tif (preferRE) {\n\t\t\t\t\t\tsc.SetState(SCE_PL_HASH);\n\t\t\t\t\t\tif (setHash.Contains(sc.chNext)) {\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t} else if (sc.chNext == ':' && sc.GetRelative(2) == ':') {\n\t\t\t\t\t\t\tsc.ForwardBytes(2);\n\t\t\t\t\t\t} else if (sc.chNext == '{') {\n\t\t\t\t\t\t\tsc.ForwardSetState(SCE_PL_OPERATOR);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_PL_OPERATOR);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '<') {\t// handle '<', inputsymbol\n\t\t\t\t\tif (preferRE) {\n\t\t\t\t\t\t// forward scan\n\t\t\t\t\t\tint i = InputSymbolScan(sc);\n\t\t\t\t\t\tif (i > 0) {\n\t\t\t\t\t\t\tsc.SetState(SCE_PL_IDENTIFIER);\n\t\t\t\t\t\t\tsc.Forward(i);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t\t}\n\t\t\t\t} else {\t\t\t// handle '/', regexp\n\t\t\t\t\tif (preferRE) {\n\t\t\t\t\t\tsc.SetState(SCE_PL_REGEX);\n\t\t\t\t\t\tQuote.New();\n\t\t\t\t\t\tQuote.Open(sc.ch);\n\t\t\t\t\t} else {\t\t// / and // operators\n\t\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t\t\tif (sc.chNext == '/') {\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '='\t\t// POD\n\t\t\t        && setPOD.Contains(sc.chNext)\n\t\t\t        && sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_PL_POD);\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t} else if (sc.ch == '-' && setWordStart.Contains(sc.chNext)) {\t// extended '-' cases\n\t\t\t\tSci_PositionU bk = sc.currentPos;\n\t\t\t\tSci_PositionU fw = 2;\n\t\t\t\tif (setSingleCharOp.Contains(sc.chNext) &&\t// file test operators\n\t\t\t\t        !setWord.Contains(sc.GetRelative(2))) {\n\t\t\t\t\tsc.SetState(SCE_PL_WORD);\n\t\t\t\t} else {\n\t\t\t\t\t// nominally a minus and bareword; find extent of bareword\n\t\t\t\t\twhile (setWord.Contains(sc.GetRelative(fw)))\n\t\t\t\t\t\tfw++;\n\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t}\n\t\t\t\t// force to bareword for hash key => or {variable literal} cases\n\t\t\t\tif (disambiguateBareword(styler, bk, bk + fw, backFlag, backPos, endPos) & 2) {\n\t\t\t\t\tsc.ChangeState(SCE_PL_IDENTIFIER);\n\t\t\t\t}\n\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t} else if (sc.ch == '(' && sc.currentPos > 0) {\t// '(' or subroutine prototype\n\t\t\t\tsc.Complete();\n\t\t\t\tif (styleCheckSubPrototype(styler, sc.currentPos - 1)) {\n\t\t\t\t\tsc.SetState(SCE_PL_SUB_PROTOTYPE);\n\t\t\t\t\tbackFlag = BACK_NONE;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\t}\n\t\t\t} else if (setPerlOperator.Contains(sc.ch)) {\t// operators\n\t\t\t\tsc.SetState(SCE_PL_OPERATOR);\n\t\t\t\tif (sc.Match('.', '.')) {\t// .. and ...\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tif (sc.chNext == '.') sc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == 4 || sc.ch == 26) {\t\t// ^D and ^Z ends valid perl source\n\t\t\t\tsc.SetState(SCE_PL_DATASECTION);\n\t\t\t} else {\n\t\t\t\t// keep colouring defaults\n\t\t\t\tsc.Complete();\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n\tif (sc.state == SCE_PL_HERE_Q\n\t        || sc.state == SCE_PL_HERE_QQ\n\t        || sc.state == SCE_PL_HERE_QX\n\t        || sc.state == SCE_PL_FORMAT) {\n\t\tstyler.ChangeLexerState(sc.currentPos, styler.Length());\n\t}\n\tsc.Complete();\n}\n\n#define PERL_HEADFOLD_SHIFT\t\t4\n#define PERL_HEADFOLD_MASK\t\t0xF0\n\nvoid SCI_METHOD LexerPerl::Fold(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {\n\n\tif (!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\n\t// Backtrack to previous line in case need to fix its fold status\n\tif (startPos > 0) {\n\t\tif (lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t\t}\n\t}\n\n\tint levelPrev = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelPrev = FoldLevelStart(styler.LevelAt(lineCurrent - 1));\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tchar chPrev = styler.SafeGetCharAt(startPos - 1);\n\tint styleNext = styler.StyleAt(startPos);\n\t// Used at end of line to determine if the line was a package definition\n\tbool isPackageLine = false;\n\tint podHeading = 0;\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tint stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tbool atLineStart = ((chPrev == '\\r') || (chPrev == '\\n')) || i == 0;\n\t\t// Comment folding\n\t\tif (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {\n\t\t\tif (!IsCommentLine(lineCurrent - 1, styler)\n\t\t\t        && IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (IsCommentLine(lineCurrent - 1, styler)\n\t\t\t        && !IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelCurrent--;\n\t\t}\n\t\t// {} [] block folding\n\t\tif (style == SCE_PL_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\tif (options.foldAtElse && levelCurrent < levelPrev)\n\t\t\t\t\t--levelPrev;\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t\tif (ch == '[') {\n\t\t\t\tif (options.foldAtElse && levelCurrent < levelPrev)\n\t\t\t\t\t--levelPrev;\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == ']') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t} else if (style == SCE_PL_STRING_QW) {\n\t\t\t// qw\n\t\t\tif (stylePrevCh != style)\n\t\t\t\tlevelCurrent++;\n\t\t\telse if (styleNext != style)\n\t\t\t\tlevelCurrent--;\n\t\t}\n\t\t// POD folding\n\t\tif (options.foldPOD && atLineStart) {\n\t\t\tif (style == SCE_PL_POD) {\n\t\t\t\tif (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB)\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\telse if (styler.Match(i, \"=cut\"))\n\t\t\t\t\tlevelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;\n\t\t\t\telse if (styler.Match(i, \"=head\"))\n\t\t\t\t\tpodHeading = PodHeadingLevel(i, styler);\n\t\t\t} else if (style == SCE_PL_DATASECTION) {\n\t\t\t\tif (ch == '=' && IsASCII(chNext) && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\telse if (styler.Match(i, \"=cut\") && levelCurrent > SC_FOLDLEVELBASE)\n\t\t\t\t\tlevelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;\n\t\t\t\telse if (styler.Match(i, \"=head\"))\n\t\t\t\t\tpodHeading = PodHeadingLevel(i, styler);\n\t\t\t\t// if package used or unclosed brace, level > SC_FOLDLEVELBASE!\n\t\t\t\t// reset needed as level test is vs. SC_FOLDLEVELBASE\n\t\t\t\telse if (stylePrevCh != SCE_PL_DATASECTION)\n\t\t\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t\t}\n\t\t}\n\t\t// package folding\n\t\tif (options.foldPackage && atLineStart) {\n\t\t\tif (IsPackageLine(lineCurrent, styler)\n\t\t\t        && !IsPackageLine(lineCurrent + 1, styler))\n\t\t\t\tisPackageLine = true;\n\t\t}\n\n\t\t//heredoc folding\n\t\tswitch (style) {\n\t\tcase SCE_PL_HERE_QQ :\n\t\tcase SCE_PL_HERE_Q :\n\t\tcase SCE_PL_HERE_QX :\n\t\t\tswitch (stylePrevCh) {\n\t\t\tcase SCE_PL_HERE_QQ :\n\t\t\tcase SCE_PL_HERE_Q :\n\t\t\tcase SCE_PL_HERE_QX :\n\t\t\t\t//do nothing;\n\t\t\t\tbreak;\n\t\t\tdefault :\n\t\t\t\tlevelCurrent++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tswitch (stylePrevCh) {\n\t\t\tcase SCE_PL_HERE_QQ :\n\t\t\tcase SCE_PL_HERE_Q :\n\t\t\tcase SCE_PL_HERE_QX :\n\t\t\t\tlevelCurrent--;\n\t\t\t\tbreak;\n\t\t\tdefault :\n\t\t\t\t//do nothing;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t//explicit folding\n\t\tif (options.foldCommentExplicit && style == SCE_PL_COMMENTLINE && ch == '#') {\n\t\t\tif (chNext == '{') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (levelCurrent > SC_FOLDLEVELBASE  && chNext == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\t// POD headings occupy bits 7-4, leaving some breathing room for\n\t\t\t// non-standard practice -- POD sections stuck in blocks, etc.\n\t\t\tif (podHeading > 0) {\n\t\t\t\tlevelCurrent = (lev & ~PERL_HEADFOLD_MASK) | (podHeading << PERL_HEADFOLD_SHIFT);\n\t\t\t\tlev = levelCurrent - 1;\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\tpodHeading = 0;\n\t\t\t}\n\t\t\t// Check if line was a package declaration\n\t\t\t// because packages need \"special\" treatment\n\t\t\tif (isPackageLine) {\n\t\t\t\tlev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\t\t\tlevelCurrent = SC_FOLDLEVELBASE + 1;\n\t\t\t\tisPackageLine = false;\n\t\t\t}\n\t\t\tlev |= levelCurrent << FoldLevelShift;\n\t\t\tlev |= FoldLevelFlags(levelPrev, levelCurrent, visibleChars == 0 && options.foldCompact, visibleChars > 0);\n\t\t\tstyler.SetLevelIfDifferent(lineCurrent, lev);\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t\tchPrev = ch;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tconst int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\n}\n\nextern const LexerModule lmPerl(SCLEX_PERL, LexerPerl::LexerFactoryPerl, \"perl\", perlWordListDesc);\n"
  },
  {
    "path": "lexers/LexPowerPro.cxx",
    "content": "// Scintilla source code edit control\n// @file LexPowerPro.cxx\n// PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com\n// PowerPro lexer is written by Christopher Bean (cbean@cb-software.net)\n//\n// Lexer code heavily borrowed from:\n//\tLexAU3.cxx by Jos van der Zande\n//\tLexCPP.cxx by Neil Hodgson\n//\tLexVB.cxx by Neil Hodgson\n//\n// Changes:\n// \t2008-10-25 - Initial release\n//\t2008-10-26 - Changed how <name> is hilighted in  'function <name>' so that\n//\t\t\t\t local isFunction = \"\" and local functions = \"\" don't get falsely highlighted\n//\t2008-12-14 - Added bounds checking for szFirstWord and szDo\n//\t\t\t   - Replaced SetOfCharacters with CharacterSet\n//\t\t\t   - Made sure that CharacterSet::Contains is passed only positive values\n//\t\t\t   - Made sure that the return value of Accessor::SafeGetCharAt is positive before\n//\t\t\t\t passing to functions that require positive values like isspacechar()\n//\t\t\t   - Removed unused visibleChars processing from ColourisePowerProDoc()\n//\t\t\t   - Fixed bug with folding logic where line continuations didn't end where\n//\t\t\t\t they were supposed to\n//\t\t\t   - Moved all helper functions to the top of the file\n//\t2010-06-03 - Added onlySpaces variable to allow the @function and ;comment styles to be indented\n//\t\t\t   - Modified HasFunction function to be a bit more robust\n//\t\t\t   - Renamed HasFunction function to IsFunction\n//\t\t\t   - Cleanup\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <string.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsStreamCommentStyle(int style) {\n\treturn style == SCE_POWERPRO_COMMENTBLOCK;\n}\n\nstatic inline bool IsLineEndChar(unsigned char ch) {\n\treturn \tch == 0x0a \t\t//LF\n\t\t\t|| ch == 0x0c\t//FF\n\t\t\t|| ch == 0x0d;\t//CR\n}\n\nstatic bool IsContinuationLine(Sci_PositionU szLine, Accessor &styler)\n{\n\tSci_Position startPos = styler.LineStart(szLine);\n\tSci_Position endPos = styler.LineStart(szLine + 1) - 2;\n\twhile (startPos < endPos)\n\t{\n\t\tchar stylech = styler.StyleAt(startPos);\n\t\tif (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) {\n\t\t\tchar ch = styler.SafeGetCharAt(endPos);\n\t\t\tchar chPrev = styler.SafeGetCharAt(endPos - 1);\n\t\t\tchar chPrevPrev = styler.SafeGetCharAt(endPos - 2);\n\t\t\tif (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) )\n\t\t\t\treturn (chPrevPrev == ';' && chPrev == ';' && ch == '+');\n\t\t\t}\n\t\tendPos--; // skip to next char\n\t}\n\treturn false;\n}\n\n// Routine to find first none space on the current line and return its Style\n// needed for comment lines not starting on pos 1\nstatic int GetStyleFirstWord(Sci_Position szLine, Accessor &styler)\n{\n\tSci_Position startPos = styler.LineStart(szLine);\n\tSci_Position endPos = styler.LineStart(szLine + 1) - 1;\n\tchar ch = styler.SafeGetCharAt(startPos);\n\n\twhile (ch > 0 && isspacechar(ch) && startPos < endPos)\n\t{\n\t\tstartPos++; // skip to next char\n\t\tch = styler.SafeGetCharAt(startPos);\n\t}\n\treturn styler.StyleAt(startPos);\n}\n\n//returns true if there is a function to highlight\n//used to highlight <name> in 'function <name>'\n//note:\n//\t\tsample line (without quotes): \"\\tfunction asdf()\n//\t\tcurrentPos will be the position of 'a'\nstatic bool IsFunction(Accessor &styler, Sci_PositionU currentPos) {\n\n\tconst char function[10] = \"function \"; //10 includes \\0\n\tunsigned int numberOfCharacters = sizeof(function) - 1;\n\tSci_PositionU position = currentPos - numberOfCharacters;\n\n\t//compare each character with the letters in the function array\n\t//return false if ALL don't match\n\tfor (Sci_PositionU i = 0; i < numberOfCharacters; i++) {\n\t\tchar c = styler.SafeGetCharAt(position++);\n\t\tif (c != function[i])\n\t\t\treturn false;\n\t}\n\n\t//make sure that there are only spaces (or tabs) between the beginning\n\t//of the line and the function declaration\n\tposition = currentPos - numberOfCharacters - 1; \t\t//-1 to move to char before 'function'\n\tfor (Sci_PositionU j = 0; j < 16; j++) {\t\t\t\t\t//check up to 16 preceeding characters\n\t\tchar c = styler.SafeGetCharAt(position--, '\\0');\t//if can't read char, return NUL (past beginning of document)\n\t\tif (c <= 0)\t//reached beginning of document\n\t\t\treturn true;\n\t\tif (c > 0 && IsLineEndChar(c))\n\t\t\treturn true;\n\t\telse if (c > 0 && !IsASpaceOrTab(c))\n\t\t\treturn false;\n\t}\n\n\t//fall-through\n\treturn false;\n}\n\nstatic void ColourisePowerProDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler, bool caseSensitive) {\n\n\tWordList &keywords  = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\tWordList &keywords4 = *keywordlists[3];\n\n\t//define the character sets\n\tCharacterSet setWordStart(CharacterSet::setAlpha, \"_@\", 0x80, true);\n\tCharacterSet setWord(CharacterSet::setAlphaNum, \"._\", 0x80, true);\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tchar s_save[100]; //for last line highlighting\n\n\t//are there only spaces between the first letter of the line and the beginning of the line\n\tbool onlySpaces = true;\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\t// save the total current word for eof processing\n\t\tchar s[100];\n\t\tsc.GetCurrentLowered(s, sizeof(s));\n\n\t\tif ((sc.ch > 0) && setWord.Contains(sc.ch))\n\t\t{\n\t\t\tstrcpy(s_save,s);\n\t\t\tint tp = static_cast<int>(strlen(s_save));\n\t\t\tif (tp < 99) {\n\t\t\t\ts_save[tp] = static_cast<char>(tolower(sc.ch));\n\t\t\t\ts_save[tp+1] = '\\0';\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineStart) {\n\t\t\tif (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) {\n\t\t\t\t// Prevent SCE_POWERPRO_STRINGEOL from leaking back to previous line which\n\t\t\t\t// ends with a line continuation by locking in the state upto this position.\n\t\t\t\tsc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_POWERPRO_OPERATOR:\n\t\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_NUMBER:\n\n\t\t\t\tif (!IsADigit(sc.ch))\n\t\t\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_IDENTIFIER:\n\t\t\t\t//if ((sc.ch > 0) && !setWord.Contains(sc.ch) || (sc.ch == '.')) { // use this line if don't want to match keywords with . in them. ie: win.debug will match both win and debug so win debug will also be colorized\n\t\t\t\tif ((sc.ch > 0) && !setWord.Contains(sc.ch)){  // || (sc.ch == '.')) { // use this line if you want to match keywords with a . ie: win.debug will only match win.debug neither win nor debug will be colorized separately\n\t\t\t\t\tchar s[1000];\n\t\t\t\t\tif (caseSensitive) {\n\t\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t\t}\n\n\t\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_POWERPRO_WORD);\n\t\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_POWERPRO_WORD2);\n\t\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_POWERPRO_WORD3);\n\t\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_POWERPRO_WORD4);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_LINECONTINUE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t} else if (sc.Match('/', '*') || sc.Match('/', '/')) {\n\t\t\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_COMMENTBLOCK:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_COMMENTLINE:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_DOUBLEQUOTEDSTRING:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_POWERPRO_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tsc.ForwardSetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_SINGLEQUOTEDSTRING:\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.ChangeState(SCE_POWERPRO_STRINGEOL);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\t\tsc.ForwardSetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_STRINGEOL:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_VERBATIM:\n\t\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\t\tif (sc.chNext == '\\\"') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_ALTQUOTE:\n\t\t\t\tif (sc.ch == '#') {\n\t\t\t\t\tif (sc.chNext == '#') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SCE_POWERPRO_FUNCTION:\n\t\t\t\tif (isspacechar(sc.ch) || sc.ch == '(') {\n\t\t\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_POWERPRO_DEFAULT) {\n\t\t\tif (sc.Match('?', '\\\"')) {\n\t\t\t\tsc.SetState(SCE_POWERPRO_VERBATIM);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_POWERPRO_NUMBER);\n\t\t\t}else if (sc.Match('?','#')) {\n\t\t\t\tif (sc.ch == '?' && sc.chNext == '#') {\n\t\t\t\t\tsc.SetState(SCE_POWERPRO_ALTQUOTE);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (IsFunction(styler, sc.currentPos)) {\t//highlight <name> in 'function <name>'\n\t\t\t\tsc.SetState(SCE_POWERPRO_FUNCTION);\n\t\t\t} else if (onlySpaces && sc.ch == '@') { \t\t//alternate function definition [label]\n\t\t\t\tsc.SetState(SCE_POWERPRO_FUNCTION);\n\t\t\t} else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) {\n\t\t\t\tsc.SetState(SCE_POWERPRO_IDENTIFIER);\n\t\t\t} else if (sc.Match(\";;+\")) {\n\t\t\t\tsc.SetState(SCE_POWERPRO_LINECONTINUE);\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tsc.SetState(SCE_POWERPRO_COMMENTBLOCK);\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tsc.SetState(SCE_POWERPRO_COMMENTLINE);\n\t\t\t} else if (onlySpaces && sc.ch == ';') {\t\t//legacy comment that can only have blank space in front of it\n\t\t\t\tsc.SetState(SCE_POWERPRO_COMMENTLINE);\n\t\t\t} else if (sc.Match(\";;\")) {\n\t\t\t\tsc.SetState(SCE_POWERPRO_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_POWERPRO_SINGLEQUOTEDSTRING);\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t\tsc.SetState(SCE_POWERPRO_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t\t//maintain a record of whether or not all the preceding characters on\n\t\t//a line are space characters\n\t\tif (onlySpaces && !IsASpaceOrTab(sc.ch))\n\t\t\tonlySpaces = false;\n\n\t\t//reset when starting a new line\n\t\tif (sc.atLineEnd)\n\t\t\tonlySpaces = true;\n\t}\n\n\t//*************************************\n\t// Colourize the last word correctly\n\t//*************************************\n\tif (sc.state == SCE_POWERPRO_IDENTIFIER)\n\t{\n\t\tif (keywords.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_POWERPRO_WORD);\n\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t}\n\t\telse if (keywords2.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_POWERPRO_WORD2);\n\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t}\n\t\telse if (keywords3.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_POWERPRO_WORD3);\n\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t}\n\t\telse if (keywords4.InList(s_save)) {\n\t\t\tsc.ChangeState(SCE_POWERPRO_WORD4);\n\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t}\n\t\telse {\n\t\t\tsc.SetState(SCE_POWERPRO_DEFAULT);\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic void FoldPowerProDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)\n{\n\t//define the character sets\n\tCharacterSet setWordStart(CharacterSet::setAlpha, \"_@\", 0x80, true);\n\tCharacterSet setWord(CharacterSet::setAlphaNum, \"._\", 0x80, true);\n\n\t//used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)\n\tbool isFoldingAll = true;\n\n\tSci_Position endPos = startPos + length;\n\tSci_Position lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly\n\n\t// get settings from the config files for folding comments and preprocessor lines\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldInComment = styler.GetPropertyInt(\"fold.comment\") == 2;\n\tbool foldCompact = true;\n\n\t// Backtrack to previous line in case need to fix its fold status\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (startPos > 0) {\n\t\tisFoldingAll = false;\n\t\tif (lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t\t}\n\t}\n\t// vars for style of previous/current/next lines\n\tint style = GetStyleFirstWord(lineCurrent,styler);\n\tint stylePrev = 0;\n\n\t// find the first previous line without continuation character at the end\n\twhile ((lineCurrent > 0 && IsContinuationLine(lineCurrent, styler))\n\t       || (lineCurrent > 1 && IsContinuationLine(lineCurrent - 1, styler))) {\n\t\tlineCurrent--;\n\t\tstartPos = styler.LineStart(lineCurrent);\n\t}\n\n\tif (lineCurrent > 0) {\n\t\tstylePrev = GetStyleFirstWord(lineCurrent-1,styler);\n\t}\n\n\t// vars for getting first word to check for keywords\n\tbool isFirstWordStarted = false;\n\tbool isFirstWordEnded = false;\n\n\tconst unsigned int FIRST_WORD_MAX_LEN = 10;\n\tchar szFirstWord[FIRST_WORD_MAX_LEN] = \"\";\n\tunsigned int firstWordLen = 0;\n\n\tchar szDo[3]=\"\";\n\tint\t szDolen = 0;\n\tbool isDoLastWord = false;\n\n\t// var for indentlevel\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelNext = levelCurrent;\n\n\tint\tvisibleChars = 0;\n\tint functionCount = 0;\n\n\tchar chNext = styler.SafeGetCharAt(startPos);\n\tchar chPrev = '\\0';\n\tchar chPrevPrev = '\\0';\n\tchar chPrevPrevPrev = '\\0';\n\n\tfor (Sci_Position i = startPos; i < endPos; i++) {\n\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif ((ch > 0) && setWord.Contains(ch))\n\t\t\tvisibleChars++;\n\n\t\t// get the syle for the current character neede to check in comment\n\t\tint stylech = styler.StyleAt(i);\n\n\t\t// start the capture of the first word\n\t\tif (!isFirstWordStarted && (ch > 0)) {\n\t\t\tif (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/') {\n\t\t\t\tisFirstWordStarted = true;\n\t\t\t\tif (firstWordLen < FIRST_WORD_MAX_LEN - 1) {\n\t\t\t\t\tszFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));\n\t\t\t\t\tszFirstWord[firstWordLen] = '\\0';\n\t\t\t\t}\n\t\t\t}\n\t\t} // continue capture of the first word on the line\n\t\telse if (isFirstWordStarted && !isFirstWordEnded && (ch > 0)) {\n\t\t\tif (!setWord.Contains(ch)) {\n\t\t\t\tisFirstWordEnded = true;\n\t\t\t}\n\t\t\telse if (firstWordLen < (FIRST_WORD_MAX_LEN - 1)) {\n\t\t\t\tszFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));\n\t\t\t\tszFirstWord[firstWordLen] = '\\0';\n\t\t\t}\n\t\t}\n\n\t\tif (stylech != SCE_POWERPRO_COMMENTLINE) {\n\n\t\t\t//reset isDoLastWord if we find a character(ignoring spaces) after 'do'\n\t\t\tif (isDoLastWord && (ch > 0) && setWord.Contains(ch))\n\t\t\t\tisDoLastWord = false;\n\n\t\t\t// --find out if the word \"do\" is the last on a \"if\" line--\n\t\t\t// collect each letter and put it into a buffer 2 chars long\n\t\t\t// if we end up with \"do\" in the buffer when we reach the end of\n\t\t\t// the line, \"do\" was the last word on the line\n\t\t\tif ((ch > 0) && isFirstWordEnded && strcmp(szFirstWord, \"if\") == 0) {\n\t\t\t\tif (szDolen == 2) {\n\t\t\t\t\tszDo[0] = szDo[1];\n\t\t\t\t\tszDo[1] = static_cast<char>(tolower(ch));\n\t\t\t\t\tszDo[2] = '\\0';\n\n\t\t\t\t\tif (strcmp(szDo, \"do\") == 0)\n\t\t\t\t\t\tisDoLastWord = true;\n\n\t\t\t\t} else if (szDolen < 2) {\n\t\t\t\t\tszDo[szDolen++] = static_cast<char>(tolower(ch));\n\t\t\t\t\tszDo[szDolen] = '\\0';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// End of Line found so process the information\n\t\t if ((ch == '\\r' && chNext != '\\n') // \\r\\n\n\t\t\t|| ch == '\\n' \t\t\t\t\t// \\n\n\t\t\t|| i == endPos) {\t\t\t\t// end of selection\n\n\t\t\t// **************************\n\t\t\t// Folding logic for Keywords\n\t\t\t// **************************\n\n\t\t\t// if a keyword is found on the current line and the line doesn't end with ;;+ (continuation)\n\t\t\t//    and we are not inside a commentblock.\n\t\t\tif (firstWordLen > 0\n\t\t\t\t&& chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev !=';'\n\t\t\t\t&& (!IsStreamCommentStyle(style) || foldInComment) ) {\n\n\t\t\t\t// only fold \"if\" last keyword is \"then\"  (else its a one line if)\n\t\t\t\tif (strcmp(szFirstWord, \"if\") == 0  && isDoLastWord)\n\t\t\t\t\t\tlevelNext++;\n\n\t\t\t\t// create new fold for these words\n\t\t\t\tif (strcmp(szFirstWord, \"for\") == 0)\n\t\t\t\t\tlevelNext++;\n\n\t\t\t\t//handle folding for functions/labels\n\t\t\t\t//Note: Functions and labels don't have an explicit end like [end function]\n\t\t\t\t//\t1. functions/labels end at the start of another function\n\t\t\t\t//\t2. functions/labels end at the end of the file\n\t\t\t\tif ((strcmp(szFirstWord, \"function\") == 0) || (firstWordLen > 0 && szFirstWord[0] == '@')) {\n\t\t\t\t\tif (isFoldingAll) { //if we're folding the whole document (recursivly by lua script)\n\n\t\t\t\t\t\tif (functionCount > 0) {\n\t\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfunctionCount++;\n\n\t\t\t\t\t} else { //if just folding a small piece (by clicking on the minus sign next to the word)\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// end the fold for these words before the current line\n\t\t\t\tif (strcmp(szFirstWord, \"endif\") == 0 || strcmp(szFirstWord, \"endfor\") == 0) {\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\n\t\t\t\t// end the fold for these words before the current line and Start new fold\n\t\t\t\tif (strcmp(szFirstWord, \"else\") == 0 || strcmp(szFirstWord, \"elseif\") == 0 )\n\t\t\t\t\t\tlevelCurrent--;\n\n\t\t\t}\n\t\t\t// Preprocessor and Comment folding\n\t\t\tint styleNext = GetStyleFirstWord(lineCurrent + 1,styler);\n\n\t\t\t// *********************************\n\t\t\t// Folding logic for Comment blocks\n\t\t\t// *********************************\n\t\t\tif (foldComment && IsStreamCommentStyle(style)) {\n\n\t\t\t\t// Start of a comment block\n\t\t\t\tif (stylePrev != style && IsStreamCommentStyle(styleNext) && styleNext == style) {\n\t\t\t\t    levelNext++;\n\t\t\t\t} // fold till the last line for normal comment lines\n\t\t\t\telse if (IsStreamCommentStyle(stylePrev)\n\t\t\t\t\t\t&& styleNext != SCE_POWERPRO_COMMENTLINE\n\t\t\t\t\t\t&& stylePrev == SCE_POWERPRO_COMMENTLINE\n\t\t\t\t\t\t&& style == SCE_POWERPRO_COMMENTLINE) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t} // fold till the one but last line for Blockcomment lines\n\t\t\t\telse if (IsStreamCommentStyle(stylePrev)\n\t\t\t\t\t\t&& styleNext != SCE_POWERPRO_COMMENTBLOCK\n\t\t\t\t\t\t&& style == SCE_POWERPRO_COMMENTBLOCK) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tint levelUse = levelCurrent;\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent))\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\n\t\t\t// reset values for the next line\n\t\t\tlineCurrent++;\n\t\t\tstylePrev = style;\n\t\t\tstyle = styleNext;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tvisibleChars = 0;\n\n\t\t\t// if the last characters are ;;+ then don't reset since the line continues on the next line.\n\t\t\tif (chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev != ';') {\n\t\t\t\tfirstWordLen = 0;\n\t\t\t\tszDolen = 0;\n\t\t\t\tisFirstWordStarted = false;\n\t\t\t\tisFirstWordEnded = false;\n\t\t\t\tisDoLastWord = false;\n\n\t\t\t\t//blank out first word\n\t\t\t\tfor (unsigned int i = 0; i < FIRST_WORD_MAX_LEN; i++)\n\t\t\t\t\tszFirstWord[i] = '\\0';\n\t\t\t}\n\t\t}\n\n\t\t// save the last processed characters\n\t\tif ((ch > 0) && !isspacechar(ch)) {\n\t\t\tchPrevPrevPrev = chPrevPrev;\n\t\t\tchPrevPrev = chPrev;\n\t\t\tchPrev = ch;\n\t\t}\n\t}\n\n\t//close folds on the last line - without this a 'phantom'\n\t//fold can appear when an open fold is on the last line\n\t//this can occur because functions and labels don't have an explicit end\n\tif (lineCurrent >= lastLine) {\n\t\tint lev = 0;\n\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\tstyler.SetLevel(lineCurrent, lev);\n\t}\n\n}\n\nstatic const char * const powerProWordLists[] = {\n            \"Keyword list 1\",\n            \"Keyword list 2\",\n            \"Keyword list 3\",\n            \"Keyword list 4\",\n            0,\n        };\n\nstatic void ColourisePowerProDocWrapper(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                                       Accessor &styler) {\n\tColourisePowerProDoc(startPos, length, initStyle, keywordlists, styler, false);\n}\n\nextern const LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, \"powerpro\", FoldPowerProDoc, powerProWordLists);\n\n\n"
  },
  {
    "path": "lexers/LexPowerShell.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexPowerShell.cxx\n ** Lexer for PowerShell scripts.\n **/\n// Copyright 2008 by Tim Gerundt <tim@gerundt.de>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// Extended to accept accented characters\nstatic inline bool IsAWordChar(int ch) noexcept {\n\treturn ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';\n}\n\nstatic bool IsNumericLiteral(int chPrev, int ch, int chNext) {\n\t// integers\n\tif (ch >= '0' && ch <= '9') {\n\t\treturn true;\n\t}\n\t// hex 0x or a-f\n\tif ((ch == 'x' && chPrev == '0') || (ch >= 'a' && ch <= 'f')) {\n\t\treturn true;\n\t}\n\t// decimal point\n\tif (ch == '.' && chNext != '.') {\n\t\treturn true;\n\t}\n\t// optional -/+ sign after exponent\n\tif ((ch == '+' || ch == '-') && chPrev == 'e') {\n\t\treturn true;\n\t}\n\t// suffix\n\tswitch (ch) {\n\t//case 'b': see hex\n\tcase 'g':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'p':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'y':\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\t\t\t   WordList *keywordlists[], Accessor &styler) {\n\n\tconst WordList &keywords = *keywordlists[0];\n\tconst WordList &keywords2 = *keywordlists[1];\n\tconst WordList &keywords3 = *keywordlists[2];\n\tconst WordList &keywords4 = *keywordlists[3];\n\tconst WordList &keywords5 = *keywordlists[4];\n\tconst WordList &keywords6 = *keywordlists[5];\n\n\tstyler.StartAt(startPos);\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.state == SCE_POWERSHELL_COMMENT) {\n\t\t\tif (sc.MatchLineEnd()) {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_COMMENTSTREAM) {\n\t\t\tif (sc.atLineStart) {\n\t\t\t\twhile (IsASpaceOrTab(sc.ch)) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tif (sc.ch == '.' && IsAWordChar(sc.chNext)) {\n\t\t\t\t\tsc.SetState(SCE_POWERSHELL_COMMENTDOCKEYWORD);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (sc.ch == '>' && sc.chPrev == '#') {\n\t\t\t\tsc.ForwardSetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_COMMENTDOCKEYWORD) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tif (!keywords6.InList(s + 1)) {\n\t\t\t\t\tsc.ChangeState(SCE_POWERSHELL_COMMENTSTREAM);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_POWERSHELL_COMMENTSTREAM);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_STRING) {\n\t\t\t// This is a doubles quotes string\n\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t} else if (sc.ch == '`') {\n\t\t\t\tsc.Forward(); // skip next escaped character\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_CHARACTER) {\n\t\t\t// This is a single quote string\n\t\t\tif (sc.ch == '\\'') {\n\t\t\t\tsc.ForwardSetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_HERE_STRING) {\n\t\t\t// This is a doubles quotes here-string\n\t\t\tif (sc.atLineStart && sc.ch == '\\\"' && sc.chNext == '@') {\n\t\t\t\tsc.Forward(2);\n\t\t\t\tsc.SetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_HERE_CHARACTER) {\n\t\t\t// This is a single quote here-string\n\t\t\tif (sc.atLineStart && sc.ch == '\\'' && sc.chNext == '@') {\n\t\t\t\tsc.Forward(2);\n\t\t\t\tsc.SetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_NUMBER) {\n\t\t\tif (!IsNumericLiteral(MakeLowerCase(sc.chPrev),\n\t\t\t\t\t      MakeLowerCase(sc.ch),\n\t\t\t\t\t      MakeLowerCase(sc.chNext))) {\n\t\t\t\tif (sc.MatchLineEnd() || IsASpaceOrTab(sc.ch) || isoperator(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tsc.ChangeState(SCE_POWERSHELL_IDENTIFIER);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_VARIABLE) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_OPERATOR) {\n\t\t\tif (!isoperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_POWERSHELL_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POWERSHELL_KEYWORD);\n\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POWERSHELL_CMDLET);\n\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POWERSHELL_ALIAS);\n\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POWERSHELL_FUNCTION);\n\t\t\t\t} else if (keywords5.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_POWERSHELL_USER1);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_POWERSHELL_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_POWERSHELL_DEFAULT) {\n\t\t\tif (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_COMMENT);\n\t\t\t} else if (sc.ch == '<' && sc.chNext == '#') {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_COMMENTSTREAM);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_CHARACTER);\n\t\t\t} else if (sc.ch == '@' && sc.chNext == '\\\"') {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_HERE_STRING);\n\t\t\t} else if (sc.ch == '@' && sc.chNext == '\\'') {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_HERE_CHARACTER);\n\t\t\t} else if (sc.ch == '$') {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_VARIABLE);\n\t\t\t} else if (IsADigit(sc.ch) || (sc.chPrev != '.' && sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_NUMBER);\n\t\t\t} else if (isoperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_OPERATOR);\n\t\t\t} else if (IsAWordChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_POWERSHELL_IDENTIFIER);\n\t\t\t} else if (sc.ch == '`') {\n\t\t\t\tsc.Forward(); // skip next escaped character\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\nstatic void FoldPowerShellDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\t\t      WordList *[], Accessor &styler) {\n\tconst bool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tconst bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tconst bool foldAtElse = styler.GetPropertyInt(\"fold.at.else\", 0) != 0;\n\tconst Sci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelMinCurrent = levelCurrent;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tconst bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (style == SCE_POWERSHELL_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\t// Measure the minimum before a '{' to allow\n\t\t\t\t// folding on \"} else {\"\n\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t}\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t} else if (foldComment && style == SCE_POWERSHELL_COMMENTSTREAM) {\n\t\t\tif (stylePrev != SCE_POWERSHELL_COMMENTSTREAM && stylePrev != SCE_POWERSHELL_COMMENTDOCKEYWORD) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (styleNext != SCE_POWERSHELL_COMMENTSTREAM && styleNext != SCE_POWERSHELL_COMMENTDOCKEYWORD) {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t} else if (foldComment && style == SCE_POWERSHELL_COMMENT) {\n\t\t\tif (ch == '#') {\n\t\t\t\tSci_PositionU j = i + 1;\n\t\t\t\twhile ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tif (styler.Match(j, \"region\")) {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (styler.Match(j, \"endregion\")) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\t\tif (atEOL || (i == endPos-1)) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tif (foldAtElse) {\n\t\t\t\tlevelUse = levelMinCurrent;\n\t\t\t}\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelMinCurrent = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t}\n}\n\nstatic const char *const powershellWordLists[] = {\n\t\"Commands\",\n\t\"Cmdlets\",\n\t\"Aliases\",\n\t\"Functions\",\n\t\"User1\",\n\t\"DocComment\",\n\t0\n};\n\nextern const LexerModule lmPowerShell(SCLEX_POWERSHELL, ColourisePowerShellDoc, \"powershell\", FoldPowerShellDoc, powershellWordLists);\n\n"
  },
  {
    "path": "lexers/LexProgress.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexProgress.cxx\n **  Lexer for Progress 4GL.\n ** Based on LexCPP.cxx of Neil Hodgson <neilh@scintilla.org>\n  **/\n// Copyright 2006-2016 by Yuval Papish <Yuval@YuvCom.com>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n/** TODO:\n\nSpeedScript support in html lexer\nDifferentiate between labels and variables\n  Option 1: By symbols table\n  Option 2: As a single unidentified symbol in a sytactical line\n\n**/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"SparseState.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\n// Intermediate style for compund identifiers; this style won't be seen in lexed documents\n#define SCE_ABL_IDENTIFIERCOMPOUND 30\n\nnamespace {\n   // Use an unnamed namespace to protect the functions and classes from name conflicts\n\n   void highlightTaskMarker(StyleContext &sc, LexAccessor &styler, WordList &markerList){\n      if ((isoperator(sc.chPrev) || IsASpace(sc.chPrev)) && markerList.Length()) {\n         const int lengthMarker = 50;\n         char marker[lengthMarker+1];\n         Sci_Position currPos = (Sci_Position) sc.currentPos;\n         Sci_Position i = 0;\n         while (i < lengthMarker) {\n            char ch = styler.SafeGetCharAt(currPos + i);\n            if (IsASpace(ch) || isoperator(ch)) {\n               break;\n            }\n            marker[i] = ch;\n            i++;\n         }\n         marker[i] = '\\0';\n         if (markerList.InListAbbreviated (marker,'(')) {\n            sc.SetState(SCE_ABL_TASKMARKER);\n         }\n      }\n   }\n\n   bool IsStreamCommentStyle(int style) {\n      return style == SCE_ABL_COMMENT;\n             // style == SCE_ABL_LINECOMMENT;  Only block comments are used for folding\n   }\n\n   // Options used for LexerABL\n   struct OptionsABL {\n      bool fold;\n      bool foldSyntaxBased;\n      bool foldComment;\n      bool foldCommentMultiline;\n      bool foldCompact;\n      OptionsABL() {\n         fold = false;\n         foldSyntaxBased = true;\n         foldComment = true;\n         foldCommentMultiline = true;\n         foldCompact = false;\n      }\n   };\n\n   const char *const ablWordLists[] = {\n               \"Primary keywords and identifiers\",\n               \"Keywords that opens a block, only when used to begin a syntactic line\",\n               \"Keywords that opens a block anywhere in a syntactic line\",\n               \"Task Marker\", /* \"END MODIFY START TODO\" */\n               0,\n   };\n\n   struct OptionSetABL : public OptionSet<OptionsABL> {\n      OptionSetABL() {\n         DefineProperty(\"fold\", &OptionsABL::fold);\n\n         DefineProperty(\"fold.abl.syntax.based\", &OptionsABL::foldSyntaxBased,\n            \"Set this property to 0 to disable syntax based folding.\");\n\n         DefineProperty(\"fold.comment\", &OptionsABL::foldComment,\n            \"This option enables folding multi-line comments and explicit fold points when using the ABL lexer. \");\n\n         DefineProperty(\"fold.abl.comment.multiline\", &OptionsABL::foldCommentMultiline,\n            \"Set this property to 0 to disable folding multi-line comments when fold.comment=1.\");\n\n         DefineProperty(\"fold.compact\", &OptionsABL::foldCompact);\n\n         DefineWordListSets(ablWordLists);\n      }\n   };\n}\n\nclass LexerABL : public DefaultLexer {\n   CharacterSet setWord;\n   CharacterSet setClassName;\n   CharacterSet setNegationOp;\n   CharacterSet setArithmethicOp;\n   CharacterSet setRelOp;\n   CharacterSet setLogicalOp;\n   CharacterSet setWordStart;\n   WordList keywords1;      // regular keywords\n   WordList keywords2;      // block opening keywords, only when isSentenceStart\n   WordList keywords3;      // block opening keywords\n   WordList keywords4;      // Task Marker\n   OptionsABL options;\n   OptionSetABL osABL;\npublic:\n   LexerABL() :\n      DefaultLexer(\"abl\", SCLEX_PROGRESS),\n      setWord(CharacterSet::setAlphaNum, \"_\", 0x80, true),\n      setClassName(CharacterSet::setAlphaNum, \"#$%_-\", 0x80, true),\n      setNegationOp(CharacterSet::setNone, \"!\"),\n      setArithmethicOp(CharacterSet::setNone, \"+-/*%\"),\n      setRelOp(CharacterSet::setNone, \"=!<>\"),\n      setLogicalOp(CharacterSet::setNone, \"|&\"){\n   }\n   virtual ~LexerABL() {\n   }\n   void SCI_METHOD Release() override {\n      delete this;\n   }\n   int SCI_METHOD Version() const override {\n      return lvRelease5;\n   }\n   const char * SCI_METHOD PropertyNames() override {\n      return osABL.PropertyNames();\n   }\n   int SCI_METHOD PropertyType(const char *name) override {\n      return osABL.PropertyType(name);\n   }\n   const char * SCI_METHOD DescribeProperty(const char *name) override {\n      return osABL.DescribeProperty(name);\n   }\n   Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override ;\n   const char * SCI_METHOD PropertyGet(const char *key) override {\n\t   return osABL.PropertyGet(key);\n   }\n\n   const char * SCI_METHOD DescribeWordListSets() override {\n      return osABL.DescribeWordListSets();\n   }\n   Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n   void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n   void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n   void * SCI_METHOD PrivateCall(int, void *) override {\n      return 0;\n   }\n   int SCI_METHOD LineEndTypesSupported() override {\n      return SC_LINE_END_TYPE_DEFAULT;\n   }\n   static ILexer5 *LexerFactoryABL() {\n      return new LexerABL();\n   }\n};\n\nSci_Position SCI_METHOD LexerABL::PropertySet(const char *key, const char *val) {\n   if (osABL.PropertySet(&options, key, val)) {\n      return 0;\n   }\n   return -1;\n}\n\nSci_Position SCI_METHOD LexerABL::WordListSet(int n, const char *wl) {\n   WordList *wordListN = 0;\n   switch (n) {\n   case 0:\n      wordListN = &keywords1;\n      break;\n   case 1:\n      wordListN = &keywords2;\n      break;\n   case 2:\n      wordListN = &keywords3;\n      break;\n   case 3:\n      wordListN = &keywords4;\n      break;\n   }\n   Sci_Position firstModification = -1;\n   if (wordListN) {\n      WordList wlNew;\n      wlNew.Set(wl);\n      if (*wordListN != wlNew) {\n         wordListN->Set(wl);\n         firstModification = 0;\n      }\n   }\n   return firstModification;\n}\n\nvoid SCI_METHOD LexerABL::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n   LexAccessor styler(pAccess);\n\n   setWordStart = CharacterSet(CharacterSet::setAlpha, \"_\", 0x80, true);\n\n   int visibleChars1 = 0;\n   int styleBeforeTaskMarker = SCE_ABL_DEFAULT;\n   bool continuationLine = false;\n   int commentNestingLevel = 0;\n   bool isSentenceStart = true;\n   bool possibleOOLChange = false;\n\n   Sci_Position lineCurrent = styler.GetLine(startPos);\n   if (initStyle == SCE_ABL_PREPROCESSOR) {\n      // Set continuationLine if last character of previous line is '~'\n      if (lineCurrent > 0) {\n         Sci_Position endLinePrevious = styler.LineEnd(lineCurrent-1);\n         if (endLinePrevious > 0) {\n            continuationLine = styler.SafeGetCharAt(endLinePrevious-1) == '~';\n         }\n      }\n   }\n\n   // Initialize the block comment /* */ nesting level if lexing is starting inside\n   // a block comment.\n   if (initStyle == SCE_ABL_COMMENT && lineCurrent > 0) {\n       commentNestingLevel = styler.GetLineState(lineCurrent - 1);\n   }\n\n    // Look back to set variables that are actually invisible secondary states. The reason to avoid formal states is to cut down on state's bits\n   if (startPos > 0) {\n      Sci_Position back = startPos;\n      bool checkIsSentenceStart = (initStyle == SCE_ABL_DEFAULT || initStyle == SCE_ABL_IDENTIFIER);\n      char ch;\n      char st;\n      char chPrev;\n      char chPrev_1;\n      char chPrev_2;\n      char chPrev_3;\n\n      while (back >= 0 && checkIsSentenceStart) {\n         ch = styler.SafeGetCharAt(back);\n         styler.Flush();  // looking at styles so need to flush\n         st = styler.StyleAt(back);\n\n         chPrev = styler.SafeGetCharAt(back-1);\n         // isSentenceStart is a non-visible state, used to identify where statements and preprocessor declerations can start\n         if (st != SCE_ABL_COMMENT && st != SCE_ABL_LINECOMMENT && st != SCE_ABL_CHARACTER  && st != SCE_ABL_STRING ) {\n            chPrev_1 = styler.SafeGetCharAt(back-2);\n            chPrev_2 = styler.SafeGetCharAt(back-3);\n            chPrev_3 = styler.SafeGetCharAt(back-4);\n            if ((chPrev == '.' || chPrev == ':' || chPrev == '}' ||\n               (chPrev_3 == 'e' && chPrev_2 == 'l' && chPrev_1 == 's' &&  chPrev == 'e') ||\n               (chPrev_3 == 't' && chPrev_2 == 'h' && chPrev_1 == 'e' &&  chPrev == 'n')) &&\n               (IsASpace(ch) || (ch == '/' && styler.SafeGetCharAt(back+1) == '*'))\n               ) {\n                  checkIsSentenceStart = false;\n                  isSentenceStart = true;\n            }\n            else if (IsASpace(chPrev) && ch == '{') {\n               checkIsSentenceStart = false;\n               isSentenceStart = false;\n            }\n         }\n         --back;\n      }\n   }\n\n   StyleContext sc(startPos, length, initStyle, styler, static_cast<unsigned char>(0xff));\n   Sci_Position lineEndNext = styler.LineEnd(lineCurrent);\n\n   for (; sc.More();) {\n\n      if (sc.atLineStart) {\n         visibleChars1 = 0;\n      }\n\n      if (sc.atLineEnd) {\n          // Update the line state, so it can be seen by next line\n          if (sc.state == SCE_ABL_COMMENT) {\n              // Inside a block comment; store the nesting level\n              styler.SetLineState(lineCurrent, commentNestingLevel);\n          }\n          else {\n              // Not inside a block comment; nesting level is 0\n              styler.SetLineState(lineCurrent, 0);\n          }\n\n          lineCurrent++;\n          lineEndNext = styler.LineEnd(lineCurrent);\n      }\n\n      // Handle line continuation generically.\n      if (sc.ch == '~') {\n         if (static_cast<Sci_Position>((sc.currentPos+1)) >= lineEndNext) {\n            lineCurrent++;\n            lineEndNext = styler.LineEnd(lineCurrent);\n            sc.Forward();\n            if (sc.ch == '\\r' && sc.chNext == '\\n') {\n               sc.Forward();\n            }\n            continuationLine = true;\n            sc.Forward();\n            continue;\n         }\n      }\n\n      const bool atLineEndBeforeSwitch = sc.atLineEnd;\n      // Determine if the current state should terminate.\n      switch (sc.state) {\n         case SCE_ABL_OPERATOR:\n            sc.SetState(SCE_ABL_DEFAULT);\n            break;\n         case SCE_ABL_NUMBER:\n            // We accept almost anything because of hex. and maybe number suffixes and scientific notations in the future\n            if (!(setWord.Contains(sc.ch)\n\t\t\t\t   || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E' ||\n\t\t\t\t                                          sc.chPrev == 'p' || sc.chPrev == 'P')))) {\n               sc.SetState(SCE_ABL_DEFAULT);\n            }\n            break;\n         case SCE_ABL_IDENTIFIER:\n            if (sc.atLineStart || sc.atLineEnd || (!setWord.Contains(sc.ch) && sc.ch != '-')) {\n               char s[1000];\n               sc.GetCurrentLowered(s, sizeof(s));\n               bool isLastWordEnd = (s[0] == 'e' && s[1] =='n' && s[2] == 'd' && !IsAlphaNumeric(s[3]) && s[3] != '-');  // helps to identify \"end trigger\" phrase\n               if (sc.ch == '.' && setWord.Contains(sc.chNext)) {\n                   // identifier.identifer[.identifier ...] - stay in the identifier state until not id char and not .\n                   // - is not included in the test above because it's not valid as the start of an identifier\n                   sc.Forward();\n                   sc.ChangeState(SCE_ABL_IDENTIFIERCOMPOUND);\n                   break;\n               }\n               else if ((isSentenceStart && keywords2.InListAbbreviated (s,'(')) || (!isLastWordEnd && keywords3.InListAbbreviated (s,'('))) {\n                  sc.ChangeState(SCE_ABL_BLOCK);\n                  isSentenceStart = false;\n               }\n               else if (keywords1.InListAbbreviated (s,'(')) {\n                  if (isLastWordEnd ||\n                     (s[0] == 'f' && s[1] =='o' && s[2] == 'r' && s[3] == 'w' && s[4] =='a' && s[5] == 'r' && s[6] == 'd'&& !IsAlphaNumeric(s[7]))) {\n                     sc.ChangeState(SCE_ABL_END);\n                     isSentenceStart = false;\n                  }\n                  else if ((s[0] == 'e' && s[1] =='l' && s[2] == 's' && s[3] == 'e') ||\n                         (s[0] == 't' && s[1] =='h' && s[2] == 'e' && s[3] == 'n')) {\n                     sc.ChangeState(SCE_ABL_WORD);\n                     isSentenceStart = true;\n                  }\n                  else {\n                     sc.ChangeState(SCE_ABL_WORD);\n                     isSentenceStart = false;\n                  }\n               }\n               sc.SetState(SCE_ABL_DEFAULT);\n            }\n            break;\n         case SCE_ABL_IDENTIFIERCOMPOUND:\n             // identifier.identifer[.identifier ...] - exit this state when we find something\n             // that's not a valid character in an identifier\n             // .* is included for cases like: USING System.Collections.*\n             if (sc.ch != '.' && sc.ch != '-' && !(sc.ch == '*' && sc.chPrev == '.') && !setWord.Contains(sc.ch)) {\n                 // change the entire compound identifier back to SCE_ABL_IDENTIFIER\n                 sc.ChangeState(SCE_ABL_IDENTIFIER);\n                 sc.SetState(SCE_ABL_DEFAULT);\n                 isSentenceStart = false;\n             }\n             break;\n         case SCE_ABL_PREPROCESSOR:\n            if (sc.atLineStart && !continuationLine) {\n               sc.SetState(SCE_ABL_DEFAULT);\n               // Force Scintilla to acknowledge changed stated even though this change might happen outside of the current line\n               possibleOOLChange = true;\n               isSentenceStart = true;\n            }\n            break;\n         case SCE_ABL_LINECOMMENT:\n            if (sc.atLineStart && !continuationLine) {\n               sc.SetState(SCE_ABL_DEFAULT);\n               isSentenceStart = true;\n            } else {\n               styleBeforeTaskMarker = SCE_ABL_LINECOMMENT;\n               highlightTaskMarker(sc, styler, keywords4);\n            }\n            break;\n         case SCE_ABL_TASKMARKER:\n            if (isoperator(sc.ch) || IsASpace(sc.ch)) {\n               sc.SetState(styleBeforeTaskMarker);\n               styleBeforeTaskMarker = SCE_ABL_DEFAULT;\n            }\n            // fall through\n         case SCE_ABL_COMMENT:\n            if (sc.Match('*', '/')) {\n               sc.Forward();\n               commentNestingLevel--;\n               if (commentNestingLevel == 0) {\n                  sc.ForwardSetState(SCE_ABL_DEFAULT);\n                  possibleOOLChange = true;\n               }\n            } else if (sc.Match('/', '*')) {\n               commentNestingLevel++;\n               sc.Forward();\n            }\n            if (commentNestingLevel > 0) {\n               styleBeforeTaskMarker = SCE_ABL_COMMENT;\n               possibleOOLChange = true;\n               highlightTaskMarker(sc, styler, keywords4);\n            }\n            break;\n         case SCE_ABL_STRING:\n            if (sc.ch == '~') {\n               sc.Forward(); // Skip a character after a tilde\n            } else if (sc.ch == '\\\"') {\n                  sc.ForwardSetState(SCE_ABL_DEFAULT);\n            }\n            break;\n         case SCE_ABL_CHARACTER:\n            if (sc.ch == '~') {\n               sc.Forward(); // Skip a character after a tilde\n            } else if (sc.ch == '\\'') {\n                  sc.ForwardSetState(SCE_ABL_DEFAULT);\n            }\n            break;\n         case SCE_ABL_ANNOTATION:\n         case SCE_ABL_TYPEDANNOTATION:\n            // annotation state persists until we see a character that can't be part of a class name\n            if (!setClassName.Contains(sc.ch)) {\n               sc.SetState(SCE_ABL_DEFAULT);\n            }\n            break;\n      }\n\n      if (sc.atLineEnd && !atLineEndBeforeSwitch) {\n         // State exit processing consumed characters up to end of line.\n         lineCurrent++;\n         lineEndNext = styler.LineEnd(lineCurrent);\n      }\n\n      // Determine if a new state should be entered.\n      if (sc.state == SCE_ABL_DEFAULT) {\n         if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n               sc.SetState(SCE_ABL_NUMBER);\n               isSentenceStart = false;\n         } else if (!sc.atLineEnd && (setWordStart.Contains(sc.ch)) && sc.chPrev != '&') {\n               sc.SetState(SCE_ABL_IDENTIFIER);\n         } else if (sc.Match('/', '*')) {\n            if (sc.chPrev == '.' || sc.chPrev == ':' || sc.chPrev == '}') {\n               isSentenceStart = true;\n            }\n            sc.SetState(SCE_ABL_COMMENT);\n            possibleOOLChange = true;\n            commentNestingLevel++;\n            sc.Forward();   // Eat the * so it isn't used for the end of the comment\n         } else if (sc.ch == '\\\"') {\n               sc.SetState(SCE_ABL_STRING);\n               isSentenceStart = false;\n         } else if (sc.ch == '\\'') {\n            sc.SetState(SCE_ABL_CHARACTER);\n            isSentenceStart = false;\n         } else if (sc.ch == '&' && visibleChars1 == 0 && isSentenceStart) {\n            // Preprocessor commands are alone on their line\n            sc.SetState(SCE_ABL_PREPROCESSOR);\n            // Force Scintilla to acknowledge changed stated even though this change might happen outside of the current line\n            possibleOOLChange = true;\n            // Skip whitespace between & and preprocessor word\n            do {\n               sc.Forward();\n            } while ((sc.ch == ' ' || sc.ch == '\\t') && sc.More());\n            if (sc.atLineEnd) {\n               sc.SetState(SCE_ABL_DEFAULT);\n            }\n         } else if (sc.Match('/','/') && (IsASpace(sc.chPrev) || isSentenceStart)) {\n            // Line comments are valid after a white space or EOL\n            sc.SetState(SCE_ABL_LINECOMMENT);\n            // Skip whitespace between // and preprocessor word\n            do {\n               sc.Forward();\n            } while ((sc.ch == ' ' || sc.ch == '\\t') && sc.More());\n            if (sc.atLineEnd) {\n               sc.SetState(SCE_ABL_DEFAULT);\n            }\n         } else if (sc.ch == '@') {\n            if (!setClassName.Contains(sc.chNext) && sc.chNext != '@') {\n               // not an annotation - it might be something like: display \"test\" @ a\n               sc.SetState(SCE_ABL_DEFAULT);\n            }\n            else if (sc.chNext == '@') {\n               // @@typedannotation\n               sc.SetState(SCE_ABL_TYPEDANNOTATION);\n               sc.Forward();\n            }\n            else {\n               // @annotation\n               sc.SetState(SCE_ABL_ANNOTATION);\n            }\n         } else if (isoperator(sc.ch)) {\n            sc.SetState(SCE_ABL_OPERATOR);\n            /*    This code allows highlight of handles. Alas, it would cause the phrase \"last-event:function\"\n               to be recognized as a BlockBegin */\n               isSentenceStart = false;\n         }\n         else if ((sc.chPrev == '.' || sc.chPrev == ':' || sc.chPrev == '}') && (IsASpace(sc.ch))) {\n            isSentenceStart = true;\n         }\n      }\n      if (!IsASpace(sc.ch)) {\n         visibleChars1++;\n      }\n      continuationLine = false;\n      sc.Forward();\n   }\n\tif (possibleOOLChange)\n\t\tstyler.ChangeLexerState(startPos, startPos + length);\n   sc.Complete();\n}\n\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\n\nvoid SCI_METHOD LexerABL::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\n   if (!options.fold)\n      return;\n\n   LexAccessor styler(pAccess);\n\n   Sci_PositionU endPos = startPos + length;\n   int visibleChars = 0;\n   Sci_Position lineCurrent = styler.GetLine(startPos);\n   int levelCurrent = SC_FOLDLEVELBASE;\n   if (lineCurrent > 0)\n      levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n   Sci_PositionU lineStartNext = styler.LineStart(lineCurrent+1);\n   int levelNext = levelCurrent;\n   char chNext = styler[startPos];\n   int styleNext = styler.StyleAt(startPos);\n   int style = initStyle;\n   for (Sci_PositionU i = startPos; i < endPos; i++) {\n      chNext = static_cast<char>(tolower(chNext));  // check tolower\n      char ch = chNext;\n      chNext = styler.SafeGetCharAt(i+1);\n      int stylePrev = style;\n      style = styleNext;\n      styleNext = styler.StyleAt(i+1);\n      bool atEOL = i == (lineStartNext-1);\n      if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {\n         if (!IsStreamCommentStyle(stylePrev)) {\n            levelNext++;\n         } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n            // Comments don't end at end of line and the next character may be unstyled.\n            levelNext--;\n         }\n      }\n      if (options.foldSyntaxBased) {\n         if (style == SCE_ABL_BLOCK && !IsAlphaNumeric(chNext)) {\n            levelNext++;\n         }\n         else if (style == SCE_ABL_END  && (ch == 'e' || ch == 'f')) {\n            levelNext--;\n         }\n      }\n      if (!IsASpace(ch))\n         visibleChars++;\n      if (atEOL || (i == endPos-1)) {\n         int lev = levelCurrent | levelNext << 16;\n         if (visibleChars == 0 && options.foldCompact)\n            lev |= SC_FOLDLEVELWHITEFLAG;\n         if (levelCurrent < levelNext)\n            lev |= SC_FOLDLEVELHEADERFLAG;\n         if (lev != styler.LevelAt(lineCurrent)) {\n            styler.SetLevel(lineCurrent, lev);\n         }\n         lineCurrent++;\n         lineStartNext = styler.LineStart(lineCurrent+1);\n         levelCurrent = levelNext;\n         if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) {\n            // There is an empty line at end of file so give it same level and empty\n            styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);\n         }\n         visibleChars = 0;\n      }\n   }\n}\n\nextern const LexerModule lmProgress(SCLEX_PROGRESS, LexerABL::LexerFactoryABL, \"abl\", ablWordLists);\n"
  },
  {
    "path": "lexers/LexProps.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexProps.cxx\n ** Lexer for properties files.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\nbool AtEOL(Accessor &styler, Sci_PositionU i) {\n\treturn (styler[i] == '\\n') ||\n\t       ((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n'));\n}\n\nconstexpr bool isAssignChar(char ch) noexcept {\n\treturn (ch == '=') || (ch == ':');\n}\n\nvoid ColourisePropsLine(\n\tconst char *lineBuffer,\n\tSci_PositionU lengthLine,\n\tSci_PositionU startLine,\n\tSci_PositionU endPos,\n\tAccessor &styler,\n\tbool allowInitialSpaces) {\n\n\tSci_PositionU i = 0;\n\tif (allowInitialSpaces) {\n\t\twhile ((i < lengthLine) && isspacechar(lineBuffer[i]))\t// Skip initial spaces\n\t\t\ti++;\n\t} else {\n\t\tif (isspacechar(lineBuffer[i])) // don't allow initial spaces\n\t\t\ti = lengthLine;\n\t}\n\n\tif (i < lengthLine) {\n\t\tif (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {\n\t\t\tstyler.ColourTo(endPos, SCE_PROPS_COMMENT);\n\t\t} else if (lineBuffer[i] == '[') {\n\t\t\tstyler.ColourTo(endPos, SCE_PROPS_SECTION);\n\t\t} else if (lineBuffer[i] == '@') {\n\t\t\tstyler.ColourTo(startLine + i, SCE_PROPS_DEFVAL);\n\t\t\tif (isAssignChar(lineBuffer[i++]))\n\t\t\t\tstyler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);\n\t\t\tstyler.ColourTo(endPos, SCE_PROPS_DEFAULT);\n\t\t} else {\n\t\t\t// Search for the '=' character\n\t\t\twhile ((i < lengthLine) && !isAssignChar(lineBuffer[i]))\n\t\t\t\ti++;\n\t\t\tif ((i < lengthLine) && isAssignChar(lineBuffer[i])) {\n\t\t\t\tstyler.ColourTo(startLine + i - 1, SCE_PROPS_KEY);\n\t\t\t\tstyler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);\n\t\t\t\tstyler.ColourTo(endPos, SCE_PROPS_DEFAULT);\n\t\t\t} else {\n\t\t\t\tstyler.ColourTo(endPos, SCE_PROPS_DEFAULT);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tstyler.ColourTo(endPos, SCE_PROPS_DEFAULT);\n\t}\n}\n\nvoid ColourisePropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tstd::string lineBuffer;\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tSci_PositionU startLine = startPos;\n\n\t// property lexer.props.allow.initial.spaces\n\t//\tFor properties files, set to 0 to style all lines that start with whitespace in the default style.\n\t//\tThis is not suitable for SciTE .properties files which use indentation for flow control but\n\t//\tcan be used for RFC2822 text where indentation is used for continuation lines.\n\tconst bool allowInitialSpaces = styler.GetPropertyInt(\"lexer.props.allow.initial.spaces\", 1) != 0;\n\n\tfor (Sci_PositionU i = startPos; i < startPos + length; i++) {\n\t\tlineBuffer.push_back(styler[i]);\n\t\tif (AtEOL(styler, i)) {\n\t\t\t// End of line (or of line buffer) met, colourise it\n\t\t\tColourisePropsLine(lineBuffer.c_str(), lineBuffer.length(), startLine, i, styler, allowInitialSpaces);\n\t\t\tlineBuffer.clear();\n\t\t\tstartLine = i + 1;\n\t\t}\n\t}\n\tif (lineBuffer.length() > 0) {\t// Last line does not have ending characters\n\t\tColourisePropsLine(lineBuffer.c_str(), lineBuffer.length(), startLine, startPos + length - 1, styler, allowInitialSpaces);\n\t}\n}\n\n// adaption by ksc, using the \"} else {\" trick of 1.53\n// 030721\nvoid FoldPropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\tconst bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\n\tconst Sci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\n\tchar chNext = styler[startPos];\n\tbool headerPoint = false;\n\tint levelPrevious = (lineCurrent > 0) ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler[i+1];\n\n\t\tconst int style = styler.StyleIndexAt(i);\n\t\tconst bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (style == SCE_PROPS_SECTION) {\n\t\t\theaderPoint = true;\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;\n\t\t\tif (headerPoint) {\n\t\t\t\tlev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\t\t\tif (levelPrevious & SC_FOLDLEVELHEADERFLAG) {\n\t\t\t\t\t// previous section is empty\n\t\t\t\t\tstyler.SetLevel(lineCurrent - 1, SC_FOLDLEVELBASE);\n\t\t\t\t}\n\t\t\t} else if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {\n\t\t\t\tlev += 1;\n\t\t\t}\n\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\n\t\t\tlineCurrent++;\n\t\t\tvisibleChars = 0;\n\t\t\theaderPoint = false;\n\t\t\tlevelPrevious = lev;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\n\tint level = levelPrevious & SC_FOLDLEVELNUMBERMASK;\n\tif (levelPrevious & SC_FOLDLEVELHEADERFLAG) {\n\t\tlevel += 1;\n\t}\n\tconst int flagsNext = styler.LevelAt(lineCurrent);\n\tstyler.SetLevel(lineCurrent, level | (flagsNext & ~SC_FOLDLEVELNUMBERMASK));\n}\n\nconst char *const emptyWordListDesc[] = {\n\tnullptr\n};\n\n}\n\nextern const LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, \"props\", FoldPropsDoc, emptyWordListDesc);\n"
  },
  {
    "path": "lexers/LexPython.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexPython.cxx\n ** Lexer for Python.\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"CharacterCategory.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"SubStyles.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n// Use an unnamed namespace to protect the functions and classes from name conflicts\n\n/* Notes on f-strings: f-strings are strings prefixed with f (e.g. f'') that may\n   have arbitrary expressions in {}.  The tokens in the expressions are lexed as if\n   they were outside of any string.  Expressions may contain { and } characters as\n   long as there is a closing } for every {, may be 2+ lines in a triple quoted\n   string, and may have a formatting specifier following a ! or :, but both !\n   and : are valid inside of a bracketed expression and != is a valid\n   expression token even outside of a bracketed expression.\n\n   When in an f-string expression, the lexer keeps track of the state value of\n   the f-string and the nesting count for the expression (# of [, (, { seen - # of\n   }, ), ] seen).  f-strings may be nested (e.g. f'{ a + f\"{1+2}\"') so a stack of\n   states and nesting counts is kept.  If a f-string expression continues beyond\n   the end of a line, this stack is saved in a std::map that maps a line number to\n   the stack at the end of that line.  std::vector is used for the stack.\n\n   The PEP for f-strings is at https://www.python.org/dev/peps/pep-0498/\n*/\n/* t-string are lexed identically to f-strings and use the stack of state values\n   and the lexer states for f-strings\n*/\nstruct SingleFStringExpState {\n\tint state;\n\tint nestingCount;\n};\n\n/* kwCDef, kwCTypeName only used for Cython */\nenum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };\n\nenum literalsAllowed { litNone = 0, litU = 1, litB = 2, litF = 4, litT = 8 };\n\nconstexpr int indicatorWhitespace = 1;\n\nbool IsPyComment(Accessor &styler, Sci_Position pos, Sci_Position len) {\n\treturn len > 0 && styler[pos] == '#';\n}\n\nconstexpr bool IsPyStringTypeChar(int ch, literalsAllowed allowed) noexcept {\n\treturn\n\t\t((allowed & litB) && (ch == 'b' || ch == 'B')) ||\n\t\t((allowed & litU) && (ch == 'u' || ch == 'U')) ||\n\t\t((allowed & litF) && (ch == 'f' || ch == 'F')) ||\n\t\t((allowed & litT) && (ch == 't' || ch == 'T'));\n}\n\nconstexpr bool IsQuote(int ch) {\n\treturn AnyOf(ch, '\"', '\\'');\n}\n\nconstexpr bool IsRawPrefix(int ch) {\n\treturn AnyOf(ch, 'r', 'R');\n}\n\nbool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) noexcept {\n\t// To cover both python2 and python3 lex character prefixes as --\n\t// ur'' is a string, but ru'' is not\n\t// fr'', rf'', br'', rb'', tr'', rt'' are all strings\n\tif (IsQuote(ch))\n\t\treturn true;\n\tif (IsPyStringTypeChar(ch, allowed)) {\n\t\tif (IsQuote(chNext))\n\t\t\treturn true;\n\t\tif (IsRawPrefix(chNext) && IsQuote(chNext2))\n\t\t\treturn true;\n\t}\n\tif (IsRawPrefix(ch)) {\n\t\tif (IsQuote(chNext))\n\t\t\treturn true;\n\t\tif (IsPyStringTypeChar(chNext, allowed) && !AnyOf(chNext, 'u', 'U') && IsQuote(chNext2))\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nconstexpr bool IsPyFStringState(int st) noexcept {\n\treturn AnyOf(st, SCE_P_FCHARACTER, SCE_P_FSTRING, SCE_P_FTRIPLE, SCE_P_FTRIPLEDOUBLE);\n}\n\nconstexpr bool IsPySingleQuoteStringState(int st) noexcept {\n\treturn AnyOf(st, SCE_P_CHARACTER, SCE_P_STRING, SCE_P_FCHARACTER, SCE_P_FSTRING);\n}\n\nconstexpr bool IsPyTripleQuoteStringState(int st) noexcept {\n\treturn AnyOf(st, SCE_P_TRIPLE, SCE_P_TRIPLEDOUBLE, SCE_P_FTRIPLE, SCE_P_FTRIPLEDOUBLE);\n}\n\nchar GetPyStringQuoteChar(int st) noexcept {\n\tif (AnyOf(st, SCE_P_CHARACTER, SCE_P_FCHARACTER, SCE_P_TRIPLE, SCE_P_FTRIPLE))\n\t\treturn '\\'';\n\tif (AnyOf(st, SCE_P_STRING, SCE_P_FSTRING, SCE_P_TRIPLEDOUBLE, SCE_P_FTRIPLEDOUBLE))\n\t\treturn '\"';\n\n\treturn '\\0';\n}\n\nvoid PushStateToStack(int state, std::vector<SingleFStringExpState> &stack, SingleFStringExpState *&currentFStringExp) {\n\tconst SingleFStringExpState single = {state, 0};\n\tstack.push_back(single);\n\n\tcurrentFStringExp = &stack.back();\n}\n\nint PopFromStateStack(std::vector<SingleFStringExpState> &stack, SingleFStringExpState *&currentFStringExp) noexcept {\n\tint state = 0;\n\n\tif (!stack.empty()) {\n\t\tstate = stack.back().state;\n\t\tstack.pop_back();\n\t}\n\n\tif (stack.empty()) {\n\t\tcurrentFStringExp = nullptr;\n\t} else {\n\t\tcurrentFStringExp = &stack.back();\n\t}\n\n\treturn state;\n}\n\n/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */\nint GetPyStringState(Accessor &styler, Sci_Position i, Sci_PositionU *nextIndex, literalsAllowed allowed) {\n\tchar ch = styler.SafeGetCharAt(i);\n\tchar chNext = styler.SafeGetCharAt(i + 1);\n\tbool isFString = false;\n\n\t// Advance beyond r, a type char, or both (in either order)\n\t// Note that this depends on IsPyStringStart to enforce ru'' not being a string\n\tif (IsRawPrefix(ch)) {\n\t\ti++;\n\t\tif (IsPyStringTypeChar(chNext, allowed)) {\n\t\t\tif (AnyOf(chNext, 'f', 'F', 't', 'T'))\n\t\t\t\tisFString = true;\n\t\t\ti++;\n\t\t}\n\t\tch = styler.SafeGetCharAt(i);\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t} else if (IsPyStringTypeChar(ch, allowed)) {\n\t\tif (AnyOf(ch, 'f', 'F', 't', 'T'))\n\t\t\tisFString = true;\n\t\tif (IsRawPrefix(chNext))\n\t\t\ti += 2;\n\t\telse\n\t\t\ti += 1;\n\t\tch = styler.SafeGetCharAt(i);\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t}\n\n\t// ch and i will be the first quote\n\tif (!IsQuote(ch)) {\n\t\t*nextIndex = i + 1;\n\t\treturn SCE_P_DEFAULT;\n\t}\n\n\tif (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) {\n\t\t*nextIndex = i + 3;\n\n\t\tif (ch == '\"')\n\t\t\treturn (isFString ? SCE_P_FTRIPLEDOUBLE : SCE_P_TRIPLEDOUBLE);\n\t\telse\n\t\t\treturn (isFString ? SCE_P_FTRIPLE : SCE_P_TRIPLE);\n\t} else {\n\t\t*nextIndex = i + 1;\n\n\t\tif (ch == '\"')\n\t\t\treturn (isFString ? SCE_P_FSTRING : SCE_P_STRING);\n\t\telse\n\t\t\treturn (isFString ? SCE_P_FCHARACTER : SCE_P_CHARACTER);\n\t}\n}\n\nbool IsAWordChar(int ch, bool unicodeIdentifiers) noexcept {\n\tif (IsASCII(ch))\n\t\treturn (IsAlphaNumeric(ch) || ch == '.' || ch == '_');\n\n\tif (!unicodeIdentifiers)\n\t\treturn false;\n\n\t// Python uses the XID_Continue set from Unicode data\n\treturn IsXidContinue(ch);\n}\n\nbool IsAWordStart(int ch, bool unicodeIdentifiers) noexcept {\n\tif (IsASCII(ch))\n\t\treturn (IsUpperOrLowerCase(ch) || ch == '_');\n\n\tif (!unicodeIdentifiers)\n\t\treturn false;\n\n\t// Python uses the XID_Start set from Unicode data\n\treturn IsXidStart(ch);\n}\n\nbool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) {\n\tconst Sci_Position line = styler.GetLine(pos);\n\tconst Sci_Position start_pos = styler.LineStart(line);\n\tfor (Sci_Position i = start_pos; i < pos; i++) {\n\t\tconst char ch = styler[i];\n\t\tif (!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nunsigned char GetNextNonWhitespaceChar(Accessor &styler, Sci_PositionU pos, Sci_PositionU maxPos, Sci_PositionU *charPosPtr = nullptr) {\n\twhile (pos < maxPos) {\n\t\tconst unsigned char ch = styler.SafeGetCharAt(pos, '\\0');\n\t\tif (!AnyOf(ch, ' ', '\\t', '\\n', '\\r')) {\n\t\t\tif (charPosPtr != nullptr) {\n\t\t\t\t*charPosPtr = pos;\n\t\t\t}\n\t\t\treturn ch;\n\t\t}\n\t\tpos++;\n\t}\n\n\treturn '\\0';\n}\n\n// Returns whether symbol is \"match\" or \"case\" and it is an identifier &\n// not a keyword. Does not require the line to end with : so \"match\\n\"\n// and \"match (x)\\n\" return false because match could be a keyword once\n// more text is added\nbool IsMatchOrCaseIdentifier(const StyleContext &sc, Accessor &styler, const char *symbol) {\n\tif (strcmp(symbol, \"match\") != 0 && strcmp(symbol, \"case\") != 0) {\n\t\treturn false;\n\t}\n\n\tif (!IsFirstNonWhitespace(sc.currentPos - strlen(symbol), styler)) {\n\t\treturn true;\n\t}\n\n\t// The match keyword can be followed by an expression; the case keyword\n\t// is a bit more restrictive but not much. Here, we look for the next\n\t// char and return false if the char cannot start an expression; for '.'\n\t// we look at the following char to see if it's a digit because .1 is a\n\t// number\n\tSci_PositionU nextCharPos = 0;\n\tconst unsigned char nextChar = GetNextNonWhitespaceChar(styler, sc.currentPos, sc.lineEnd, &nextCharPos);\n\tif (nextChar == '=' || nextChar == '#') {\n\t\treturn true;\n\t}\n\tif (nextChar == '.' && nextCharPos >= sc.currentPos) {\n\t\tconst unsigned char followingChar = GetNextNonWhitespaceChar(styler, nextCharPos+1, sc.lineEnd);\n\t\tif (!IsADigit(followingChar)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n// Options used for LexerPython\nstruct OptionsPython {\n\tint whingeLevel = 0;\n\tbool base2or8Literals = true;\n\tbool stringsU = true;\n\tbool stringsB = true;\n\tbool stringsF = true;\n\tbool stringsT = true;\n\tbool stringsOverNewline = false;\n\tbool keywords2NoSubIdentifiers = false;\n\tbool fold = false;\n\tbool foldQuotes = false;\n\tbool foldCompact = false;\n\tbool unicodeIdentifiers = true;\n\tint identifierAttributes = 0;\n\tint decoratorAttributes = 0;\n\tbool pep701StringsF = true;\n\n\t[[nodiscard]] literalsAllowed AllowedLiterals() const noexcept {\n\t\tliteralsAllowed allowedLiterals = stringsU ? litU : litNone;\n\t\tif (stringsB)\n\t\t\tallowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);\n\t\tif (stringsF)\n\t\t\tallowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litF);\n\t\tif (stringsT)\n\t\t\tallowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litT);\n\t\treturn allowedLiterals;\n\t}\n};\n\nconst char *const pythonWordListDesc[] = {\n\t\"Keywords\",\n\t\"Highlighted identifiers\",\n\tnullptr\n};\n\nstruct OptionSetPython : public OptionSet<OptionsPython> {\n\tOptionSetPython() {\n\t\tDefineProperty(\"tab.timmy.whinge.level\", &OptionsPython::whingeLevel,\n\t\t\t       \"For Python code, checks whether indenting is consistent. \"\n\t\t\t       \"The default, 0 turns off indentation checking, \"\n\t\t\t       \"1 checks whether each line is potentially inconsistent with the previous line, \"\n\t\t\t       \"2 checks whether any space characters occur before a tab character in the indentation, \"\n\t\t\t       \"3 checks whether any spaces are in the indentation, and \"\n\t\t\t       \"4 checks for any tab characters in the indentation. \"\n\t\t\t       \"1 is a good level to use.\");\n\n\t\tDefineProperty(\"lexer.python.literals.binary\", &OptionsPython::base2or8Literals,\n\t\t\t       \"Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.\");\n\n\t\tDefineProperty(\"lexer.python.strings.u\", &OptionsPython::stringsU,\n\t\t\t       \"Set to 0 to not recognise Python Unicode literals u\\\"x\\\" as used before Python 3.\");\n\n\t\tDefineProperty(\"lexer.python.strings.b\", &OptionsPython::stringsB,\n\t\t\t       \"Set to 0 to not recognise Python 3 bytes literals b\\\"x\\\".\");\n\n\t\tDefineProperty(\"lexer.python.strings.f\", &OptionsPython::stringsF,\n\t\t\t       \"Set to 0 to not recognise Python 3.6 f-string literals f\\\"var={var}\\\".\");\n\n\t\tDefineProperty(\"lexer.python.strings.f.pep.701\", &OptionsPython::pep701StringsF,\n\t\t\t       \"Set to 0 to use pre-PEP 701 / Python 3.12 f-string lexing.\");\n\n\t\tDefineProperty(\"lexer.python.strings.t\", &OptionsPython::stringsT,\n\t\t\t       \"Set to 0 to not recognise Python 3.14 t-string literals t\\\"var={var}\\\".\");\n\n\t\tDefineProperty(\"lexer.python.strings.over.newline\", &OptionsPython::stringsOverNewline,\n\t\t\t       \"Set to 1 to allow strings to span newline characters.\");\n\n\t\tDefineProperty(\"lexer.python.keywords2.no.sub.identifiers\", &OptionsPython::keywords2NoSubIdentifiers,\n\t\t\t       \"When enabled, it will not style keywords2 items that are used as a sub-identifier. \"\n\t\t\t       \"Example: when set, will not highlight \\\"foo.open\\\" when \\\"open\\\" is a keywords2 item.\");\n\n\t\tDefineProperty(\"fold\", &OptionsPython::fold);\n\n\t\tDefineProperty(\"fold.quotes.python\", &OptionsPython::foldQuotes,\n\t\t\t       \"This option enables folding multi-line quoted strings when using the Python lexer.\");\n\n\t\tDefineProperty(\"fold.compact\", &OptionsPython::foldCompact);\n\n\t\tDefineProperty(\"lexer.python.unicode.identifiers\", &OptionsPython::unicodeIdentifiers,\n\t\t\t       \"Set to 0 to not recognise Python 3 Unicode identifiers.\");\n\n\t\tDefineProperty(\"lexer.python.identifier.attributes\", &OptionsPython::identifierAttributes,\n\t\t\t       \"Set to 1 to recognise Python identifier attributes.\");\n\n\t\tDefineProperty(\"lexer.python.decorator.attributes\", &OptionsPython::decoratorAttributes,\n\t\t\t       \"Set to 1 to recognise Python decorator attributes.\");\n\n\t\tDefineWordListSets(pythonWordListDesc);\n\t}\n};\n\nconst char styleSubable[] = { SCE_P_IDENTIFIER, 0 };\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer Python SCLEX_PYTHON SCE_P_:\n\t0, \"SCE_P_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_P_COMMENTLINE\", \"comment line\", \"Comment\",\n\t2, \"SCE_P_NUMBER\", \"literal numeric\", \"Number\",\n\t3, \"SCE_P_STRING\", \"literal string\", \"String\",\n\t4, \"SCE_P_CHARACTER\", \"literal string\", \"Single quoted string\",\n\t5, \"SCE_P_WORD\", \"keyword\", \"Keyword\",\n\t6, \"SCE_P_TRIPLE\", \"literal string\", \"Triple quotes\",\n\t7, \"SCE_P_TRIPLEDOUBLE\", \"literal string\", \"Triple double quotes\",\n\t8, \"SCE_P_CLASSNAME\", \"identifier\", \"Class name definition\",\n\t9, \"SCE_P_DEFNAME\", \"identifier\", \"Function or method name definition\",\n\t10, \"SCE_P_OPERATOR\", \"operator\", \"Operators\",\n\t11, \"SCE_P_IDENTIFIER\", \"identifier\", \"Identifiers\",\n\t12, \"SCE_P_COMMENTBLOCK\", \"comment\", \"Comment-blocks\",\n\t13, \"SCE_P_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n\t14, \"SCE_P_WORD2\", \"identifier\", \"Highlighted identifiers\",\n\t15, \"SCE_P_DECORATOR\", \"preprocessor\", \"Decorators\",\n\t16, \"SCE_P_FSTRING\", \"literal string interpolated\", \"F-String\",\n\t17, \"SCE_P_FCHARACTER\", \"literal string interpolated\", \"Single quoted f-string\",\n\t18, \"SCE_P_FTRIPLE\", \"literal string interpolated\", \"Triple quoted f-string\",\n\t19, \"SCE_P_FTRIPLEDOUBLE\", \"literal string interpolated\", \"Triple double quoted f-string\",\n\t20, \"SCE_P_ATTRIBUTE\", \"identifier\", \"Attribute of identifier\",\n};\n\nclass LexerPython : public DefaultLexer {\n\tWordList keywords;\n\tWordList keywords2;\n\tOptionsPython options;\n\tOptionSetPython osPython;\n\tenum { ssIdentifier };\n\tSubStyles subStyles{styleSubable};\n\tstd::map<Sci_Position, std::vector<SingleFStringExpState> > ftripleStateAtEol;\npublic:\n\texplicit LexerPython() :\n\t\tDefaultLexer(\"python\", SCLEX_PYTHON, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osPython.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osPython.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osPython.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osPython.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osPython.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn nullptr;\n\t}\n\n\tint SCI_METHOD LineEndTypesSupported() override {\n\t\treturn SC_LINE_END_TYPE_UNICODE;\n\t}\n\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {\n\t\treturn subStyles.Allocate(styleBase, numberStyles);\n\t}\n\tint SCI_METHOD SubStylesStart(int styleBase) override {\n\t\treturn subStyles.Start(styleBase);\n\t}\n\tint SCI_METHOD SubStylesLength(int styleBase) override {\n\t\treturn subStyles.Length(styleBase);\n\t}\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override {\n\t\tconst int styleBase = subStyles.BaseStyle(subStyle);\n\t\treturn styleBase;\n\t}\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) override {\n\t\treturn style;\n\t}\n\tvoid SCI_METHOD FreeSubStyles() override {\n\t\tsubStyles.Free();\n\t}\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {\n\t\tsubStyles.SetIdentifiers(style, identifiers);\n\t}\n\tint SCI_METHOD DistanceToSecondaryStyles() override {\n\t\treturn 0;\n\t}\n\tconst char *SCI_METHOD GetSubStyleBases() override {\n\t\treturn styleSubable;\n\t}\n\n\tstatic ILexer5 *LexerFactoryPython() {\n\t\treturn new LexerPython();\n\t}\n\nprivate:\n\tvoid ProcessLineEnd(StyleContext &sc, std::vector<SingleFStringExpState> &fstringStateStack, SingleFStringExpState *&currentFStringExp, bool &inContinuedString);\n};\n\nSci_Position SCI_METHOD LexerPython::PropertySet(const char *key, const char *val) {\n\tif (osPython.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerPython::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywords2;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid LexerPython::ProcessLineEnd(StyleContext &sc, std::vector<SingleFStringExpState> &fstringStateStack, SingleFStringExpState *&currentFStringExp, bool &inContinuedString) {\n\t// Before pep 701 single quote f-string's could not continue to a 2nd+ line\n\t// Post pep 701, they can continue both with a trailing \\ and if a { field is\n\t// not ended with a }\n\tif (!options.pep701StringsF) {\n\t\tlong deepestSingleStateIndex = -1;\n\t\tunsigned long i;\n\n\t\t// Find the deepest single quote state because that string will end; no \\ continuation in f-string\n\t\tfor (i = 0; i < fstringStateStack.size(); i++) {\n\t\t\tif (IsPySingleQuoteStringState(fstringStateStack[i].state)) {\n\t\t\t\tdeepestSingleStateIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (deepestSingleStateIndex != -1) {\n\t\t\tsc.SetState(fstringStateStack[deepestSingleStateIndex].state);\n\t\t\twhile (fstringStateStack.size() > static_cast<unsigned long>(deepestSingleStateIndex)) {\n\t\t\t\tPopFromStateStack(fstringStateStack, currentFStringExp);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!fstringStateStack.empty()) {\n\t\tftripleStateAtEol.insert({sc.currentLine, fstringStateStack});\n\t}\n\n\tif ((sc.state == SCE_P_DEFAULT)\n\t\t\t|| IsPyTripleQuoteStringState(sc.state)) {\n\t\t// Perform colourisation of white space and triple quoted strings at end of each line to allow\n\t\t// tab marking to work inside white space and triple quoted strings\n\t\tsc.SetState(sc.state);\n\t}\n\tif (IsPySingleQuoteStringState(sc.state)) {\n\t\tif (inContinuedString || options.stringsOverNewline) {\n\t\t\tinContinuedString = false;\n\t\t} else {\n\t\t\tsc.ChangeState(SCE_P_STRINGEOL);\n\t\t\tsc.ForwardSetState(SCE_P_DEFAULT);\n\t\t}\n\t}\n}\n\nvoid SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\n\t// Track whether in f-string expression; vector is used for a stack to\n\t// handle nested f-strings such as f\"\"\"{f'''{f\"{f'{1}'}\"}'''}\"\"\"\n\tstd::vector<SingleFStringExpState> fstringStateStack;\n\tSingleFStringExpState *currentFStringExp = nullptr;\n\n\tconst Sci_Position endPos = startPos + length;\n\n\t// Backtrack to previous line in case need to fix its tab whinging\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (startPos > 0) {\n\t\tif (lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\t// Look for backslash-continued lines\n\t\t\twhile (lineCurrent > 0) {\n\t\t\t\tconst Sci_Position eolPos = styler.LineStart(lineCurrent) - 1;\n\t\t\t\tconst int eolStyle = styler.StyleIndexAt(eolPos);\n\t\t\t\tif (AnyOf(eolStyle, SCE_P_STRING, SCE_P_CHARACTER, SCE_P_STRINGEOL)) {\n\t\t\t\t\tlineCurrent -= 1;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t\t}\n\t\tinitStyle = startPos == 0 ? SCE_P_DEFAULT : styler.StyleIndexAt(startPos - 1);\n\t}\n\n\tconst literalsAllowed allowedLiterals = options.AllowedLiterals();\n\n\tif (initStyle == SCE_P_STRINGEOL) {\n\t\tinitStyle = SCE_P_DEFAULT;\n\t}\n\n\t// Set up fstate stack from last line and remove any subsequent ftriple at eol states\n\tstd::map<Sci_Position, std::vector<SingleFStringExpState> >::iterator it;\n\tit = ftripleStateAtEol.find(lineCurrent - 1);\n\tif (it != ftripleStateAtEol.end() && !it->second.empty()) {\n\t\tfstringStateStack = it->second;\n\t\tcurrentFStringExp = &fstringStateStack.back();\n\t}\n\tit = ftripleStateAtEol.lower_bound(lineCurrent);\n\tif (it != ftripleStateAtEol.end()) {\n\t\tftripleStateAtEol.erase(it, ftripleStateAtEol.end());\n\t}\n\n\tkwType kwLast = kwOther;\n\tint spaceFlags = 0;\n\tstyler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);\n\tbool base_n_number = false;\n\n\tconst WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_P_IDENTIFIER);\n\n\tStyleContext sc(startPos, endPos - startPos, initStyle, styler);\n\n\tbool indentGood = true;\n\tSci_Position startIndicator = sc.currentPos;\n\tbool inContinuedString = false;\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.atLineStart) {\n\t\t\tstyler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);\n\t\t\tindentGood = true;\n\t\t\tif (options.whingeLevel == 1) {\n\t\t\t\tindentGood = (spaceFlags & wsInconsistent) == 0;\n\t\t\t} else if (options.whingeLevel == 2) {\n\t\t\t\tindentGood = (spaceFlags & wsSpaceTab) == 0;\n\t\t\t} else if (options.whingeLevel == 3) {\n\t\t\t\tindentGood = (spaceFlags & wsSpace) == 0;\n\t\t\t} else if (options.whingeLevel == 4) {\n\t\t\t\tindentGood = (spaceFlags & wsTab) == 0;\n\t\t\t}\n\t\t\tif (!indentGood) {\n\t\t\t\tstyler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);\n\t\t\t\tstartIndicator = sc.currentPos;\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\tProcessLineEnd(sc, fstringStateStack, currentFStringExp, inContinuedString);\n\t\t\tlineCurrent++;\n\t\t\tif (!sc.More())\n\t\t\t\tbreak;\n\t\t}\n\n\t\tbool needEOLCheck = false;\n\n\n\t\tif (sc.state == SCE_P_OPERATOR) {\n\t\t\tkwLast = kwOther;\n\t\t\tsc.SetState(SCE_P_DEFAULT);\n\t\t} else if (sc.state == SCE_P_NUMBER) {\n\t\t\tif (!IsAWordChar(sc.ch, false) &&\n\t\t\t\t\t!(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {\n\t\t\t\tsc.SetState(SCE_P_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_P_IDENTIFIER) {\n\t\t\tif ((sc.ch == '.') || (!IsAWordChar(sc.ch, options.unicodeIdentifiers))) {\n\t\t\t\tchar identifier[100];\n\t\t\t\tsc.GetCurrent(identifier, sizeof(identifier));\n\t\t\t\tint style = SCE_P_IDENTIFIER;\n\t\t\t\tif ((kwLast == kwImport) && (strcmp(identifier, \"as\") == 0)) {\n\t\t\t\t\tstyle = SCE_P_WORD;\n\t\t\t\t} else if (keywords.InList(identifier) && !IsMatchOrCaseIdentifier(sc, styler, identifier)) {\n\t\t\t\t\tstyle = SCE_P_WORD;\n\t\t\t\t} else if (kwLast == kwClass) {\n\t\t\t\t\tstyle = SCE_P_CLASSNAME;\n\t\t\t\t} else if (kwLast == kwDef) {\n\t\t\t\t\tstyle = SCE_P_DEFNAME;\n\t\t\t\t} else if (kwLast == kwCDef || kwLast == kwCPDef) {\n\t\t\t\t\tSci_Position pos = sc.currentPos;\n\t\t\t\t\tunsigned char ch = styler.SafeGetCharAt(pos, '\\0');\n\t\t\t\t\twhile (ch != '\\0') {\n\t\t\t\t\t\tif (ch == '(') {\n\t\t\t\t\t\t\tstyle = SCE_P_DEFNAME;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} else if (ch == ':') {\n\t\t\t\t\t\t\tstyle = SCE_P_CLASSNAME;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} else if (ch == ' ' || ch == '\\t' || ch == '\\n' || ch == '\\r') {\n\t\t\t\t\t\t\tpos++;\n\t\t\t\t\t\t\tch = styler.SafeGetCharAt(pos, '\\0');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (keywords2.InList(identifier)) {\n\t\t\t\t\tif (options.keywords2NoSubIdentifiers) {\n\t\t\t\t\t\t// We don't want to highlight keywords2\n\t\t\t\t\t\t// that are used as a sub-identifier,\n\t\t\t\t\t\t// i.e. not open in \"foo.open\".\n\t\t\t\t\t\tconst Sci_Position pos = styler.GetStartSegment() - 1;\n\t\t\t\t\t\tif (pos < 0 || (styler.SafeGetCharAt(pos, '\\0') != '.'))\n\t\t\t\t\t\t\tstyle = SCE_P_WORD2;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstyle = SCE_P_WORD2;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst int subStyle = classifierIdentifiers.ValueFor(identifier);\n\t\t\t\t\tif (subStyle >= 0) {\n\t\t\t\t\t\tstyle = subStyle;\n\t\t\t\t\t}\n\t\t\t\t\tif (options.identifierAttributes > 0 || options.decoratorAttributes > 0) {\n\t\t\t\t\t\t// Does the user even want attributes styled?\n\t\t\t\t\t\tSci_Position pos = styler.GetStartSegment() - 1;\n\t\t\t\t\t\tunsigned char ch = styler.SafeGetCharAt(pos, '\\0');\n\t\t\t\t\t\twhile (ch != '\\0' && (ch == '.' || ch == ' ' || ch == '\\\\' || ch == '\\t' || ch == '\\n' || ch == '\\r')) {\n\t\t\t\t\t\t\t// Backwards search for a . while only allowing certain valid characters\n\t\t\t\t\t\t\tif (IsAWordChar(ch, options.unicodeIdentifiers)) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpos--;\n\t\t\t\t\t\t\tch = styler.SafeGetCharAt(pos, '\\0');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (ch == '.') {\n\t\t\t\t\t\t\t// Is this an attribute we could style? if it is, do as asked\n\t\t\t\t\t\t\tbool isComment = AnyOf(styler.BufferStyleAt(pos), SCE_P_COMMENTLINE, SCE_P_COMMENTBLOCK);\n\t\t\t\t\t\t\tbool isDecoratorAttribute = false;\n\t\t\t\t\t\t\tconst Sci_Position attrLine = styler.GetLine(pos);\n\t\t\t\t\t\t\tfor (Sci_Position i = styler.LineStart(attrLine); i < pos; i++) {\n\t\t\t\t\t\t\t\tconst char attrCh = styler[i];\n\t\t\t\t\t\t\t\tif (attrCh == '@')\n\t\t\t\t\t\t\t\t\tisDecoratorAttribute = true;\n\t\t\t\t\t\t\t\tif (attrCh == '#')\n\t\t\t\t\t\t\t\t\tisComment = true;\n\t\t\t\t\t\t\t\t// Detect if this attribute belongs to a decorator\n\t\t\t\t\t\t\t\tif (!IsASpaceOrTab(attrCh))\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (((isDecoratorAttribute) && (!isComment)) && (((options.decoratorAttributes == 1)  && (style == SCE_P_IDENTIFIER)) || (options.decoratorAttributes == 2))) {\n\t\t\t\t\t\t\t\t// Style decorator attributes as decorators but respect already styled identifiers (unless requested to ignore already styled identifiers)\n\t\t\t\t\t\t\t\tstyle = SCE_P_DECORATOR;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (((!isDecoratorAttribute) && (!isComment)) && (((options.identifierAttributes == 1) && (style == SCE_P_IDENTIFIER)) || (options.identifierAttributes == 2))) {\n\t\t\t\t\t\t\t\t// Style attributes and ignore decorator attributes but respect already styled identifiers (unless requested to ignore already styled identifiers)\n\t\t\t\t\t\t\t\tstyle = SCE_P_ATTRIBUTE;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsc.ChangeState(style);\n\t\t\t\tsc.SetState(SCE_P_DEFAULT);\n\t\t\t\tif (style == SCE_P_WORD) {\n\t\t\t\t\tif (0 == strcmp(identifier, \"class\"))\n\t\t\t\t\t\tkwLast = kwClass;\n\t\t\t\t\telse if (0 == strcmp(identifier, \"def\"))\n\t\t\t\t\t\tkwLast = kwDef;\n\t\t\t\t\telse if (0 == strcmp(identifier, \"import\"))\n\t\t\t\t\t\tkwLast = kwImport;\n\t\t\t\t\telse if (0 == strcmp(identifier, \"cdef\"))\n\t\t\t\t\t\tkwLast = kwCDef;\n\t\t\t\t\telse if (0 == strcmp(identifier, \"cpdef\"))\n\t\t\t\t\t\tkwLast = kwCPDef;\n\t\t\t\t\telse if (0 == strcmp(identifier, \"cimport\"))\n\t\t\t\t\t\tkwLast = kwImport;\n\t\t\t\t\telse if (kwLast != kwCDef && kwLast != kwCPDef)\n\t\t\t\t\t\tkwLast = kwOther;\n\t\t\t\t} else if (kwLast != kwCDef && kwLast != kwCPDef) {\n\t\t\t\t\tkwLast = kwOther;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ((sc.state == SCE_P_COMMENTLINE) || (sc.state == SCE_P_COMMENTBLOCK)) {\n\t\t\tif (sc.ch == '\\r' || sc.ch == '\\n') {\n\t\t\t\tsc.SetState(SCE_P_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_P_DECORATOR) {\n\t\t\tif (!IsAWordStart(sc.ch, options.unicodeIdentifiers)) {\n\t\t\t\tsc.SetState(SCE_P_DEFAULT);\n\t\t\t}\n\t\t} else if (IsPySingleQuoteStringState(sc.state)) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif ((sc.chNext == '\\r') && (sc.GetRelative(2) == '\\n')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\t\tinContinuedString = true;\n\t\t\t\t} else {\n\t\t\t\t\t// Don't roll over the newline.\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == GetPyStringQuoteChar(sc.state)) {\n\t\t\t\tsc.ForwardSetState(SCE_P_DEFAULT);\n\t\t\t\tneedEOLCheck = true;\n\t\t\t}\n\t\t} else if ((sc.state == SCE_P_TRIPLE) || (sc.state == SCE_P_FTRIPLE)) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match(R\"(''')\")) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_P_DEFAULT);\n\t\t\t\tneedEOLCheck = true;\n\t\t\t}\n\t\t} else if ((sc.state == SCE_P_TRIPLEDOUBLE) || (sc.state == SCE_P_FTRIPLEDOUBLE)) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.Match(R\"(\"\"\")\")) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_P_DEFAULT);\n\t\t\t\tneedEOLCheck = true;\n\t\t\t}\n\t\t}\n\n\t\t// Note if used and not if else because string states also match\n\t\t// some of the above clauses\n\t\tif (IsPyFStringState(sc.state) && sc.ch == '{') {\n\t\t\tif (sc.chNext == '{') {\n\t\t\t\tsc.Forward();\n\t\t\t} else {\n\t\t\t\tPushStateToStack(sc.state, fstringStateStack, currentFStringExp);\n\t\t\t\tsc.ForwardSetState(SCE_P_DEFAULT);\n\t\t\t}\n\t\t\tneedEOLCheck = true;\n\t\t}\n\n\t\t// If in an f-string expression and pre pep 701 lexing is used,\n\t\t// check for the ending quote(s) and end f-string to handle\n\t\t// syntactically incorrect cases like f'{' and f\"\"\"{\"\"\". Post\n\t\t// pep 701, a quote may appear in a { } field so cases like\n\t\t// f\"n = {\":\".join(seq)}\" is valid\n\t\tif (!options.pep701StringsF && !fstringStateStack.empty() && IsQuote(sc.ch)) {\n\t\t\tlong matching_stack_i = -1;\n\t\t\tfor (unsigned long stack_i = 0; stack_i < fstringStateStack.size() && matching_stack_i == -1; stack_i++) {\n\t\t\t\tconst int stack_state = fstringStateStack[stack_i].state;\n\t\t\t\tconst char quote = GetPyStringQuoteChar(stack_state);\n\t\t\t\tif (sc.ch == quote) {\n\t\t\t\t\tif (IsPySingleQuoteStringState(stack_state)) {\n\t\t\t\t\t\tmatching_stack_i = stack_i;\n\t\t\t\t\t} else if (quote == '\"' ? sc.Match(R\"(\"\"\")\") : sc.Match(\"'''\")) {\n\t\t\t\t\t\tmatching_stack_i = stack_i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matching_stack_i != -1) {\n\t\t\t\tsc.SetState(fstringStateStack[matching_stack_i].state);\n\t\t\t\tif (IsPyTripleQuoteStringState(fstringStateStack[matching_stack_i].state)) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.ForwardSetState(SCE_P_DEFAULT);\n\t\t\t\tneedEOLCheck = true;\n\n\t\t\t\twhile (fstringStateStack.size() > static_cast<unsigned long>(matching_stack_i)) {\n\t\t\t\t\tPopFromStateStack(fstringStateStack, currentFStringExp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// End of code to find the end of a state\n\n\t\tif (!indentGood && !IsASpaceOrTab(sc.ch)) {\n\t\t\tstyler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1);\n\t\t\tstartIndicator = sc.currentPos;\n\t\t\tindentGood = true;\n\t\t}\n\n\t\t// One cdef or cpdef line, clear kwLast only at end of line\n\t\tif ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {\n\t\t\tkwLast = kwOther;\n\t\t}\n\n\t\t// State exit code may have moved on to end of line\n\t\tif (needEOLCheck && sc.atLineEnd) {\n\t\t\tProcessLineEnd(sc, fstringStateStack, currentFStringExp, inContinuedString);\n\t\t\tlineCurrent++;\n\t\t\tstyler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);\n\t\t\tif (!sc.More())\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// If in f-string expression, check for }, :, ! to resume f-string state or update nesting count\n\t\tif (currentFStringExp && !IsPySingleQuoteStringState(sc.state) && !IsPyTripleQuoteStringState(sc.state)) {\n\t\t\tif (currentFStringExp->nestingCount == 0 && (sc.ch == '}' || sc.ch == ':' || (sc.ch == '!' && sc.chNext != '='))) {\n\t\t\t\tsc.SetState(PopFromStateStack(fstringStateStack, currentFStringExp));\n\t\t\t} else {\n\t\t\t\tif (sc.ch == '{' || sc.ch == '[' || sc.ch == '(') {\n\t\t\t\t\tcurrentFStringExp->nestingCount++;\n\t\t\t\t} else if (sc.ch == '}' || sc.ch == ']' || sc.ch == ')') {\n\t\t\t\t\tcurrentFStringExp->nestingCount--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check for a new state starting character\n\t\tif (sc.state == SCE_P_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tif (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {\n\t\t\t\t\tbase_n_number = true;\n\t\t\t\t\tsc.SetState(SCE_P_NUMBER);\n\t\t\t\t} else if (sc.ch == '0' &&\n\t\t\t\t\t\t(sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {\n\t\t\t\t\tif (options.base2or8Literals) {\n\t\t\t\t\t\tbase_n_number = true;\n\t\t\t\t\t\tsc.SetState(SCE_P_NUMBER);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_P_NUMBER);\n\t\t\t\t\t\tsc.ForwardSetState(SCE_P_IDENTIFIER);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tbase_n_number = false;\n\t\t\t\t\tsc.SetState(SCE_P_NUMBER);\n\t\t\t\t}\n\t\t\t} else if (isoperator(sc.ch) || sc.ch == '`') {\n\t\t\t\tsc.SetState(SCE_P_OPERATOR);\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);\n\t\t\t} else if (sc.ch == '@') {\n\t\t\t\tif (IsFirstNonWhitespace(sc.currentPos, styler))\n\t\t\t\t\tsc.SetState(SCE_P_DECORATOR);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_P_OPERATOR);\n\t\t\t} else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2), allowedLiterals)) {\n\t\t\t\tSci_PositionU nextIndex = 0;\n\t\t\t\tsc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex, allowedLiterals));\n\t\t\t\twhile (nextIndex > (sc.currentPos + 1) && sc.More()) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (IsAWordStart(sc.ch, options.unicodeIdentifiers)) {\n\t\t\t\tsc.SetState(SCE_P_IDENTIFIER);\n\t\t\t}\n\t\t}\n\t}\n\tstyler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);\n\tsc.Complete();\n}\n\nbool IsCommentLine(Sci_Position line, Accessor &styler) {\n\tconst Sci_Position pos = styler.LineStart(line);\n\tconst Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tconst char ch = styler[i];\n\t\tif (ch == '#')\n\t\t\treturn true;\n\t\tif (!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nbool IsQuoteLine(Sci_Position line, const Accessor &styler) {\n\tconst int style = styler.StyleIndexAt(styler.LineStart(line));\n\treturn IsPyTripleQuoteStringState(style);\n}\n\n\nvoid SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/, IDocument *pAccess) {\n\tif (!options.fold)\n\t\treturn;\n\n\tAccessor styler(pAccess, nullptr);\n\n\tconst Sci_Position maxPos = startPos + length;\n\tconst Sci_Position maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1);\t// Requested last line\n\tconst Sci_Position docLines = styler.GetLine(styler.Length());\t// Available last line\n\n\t// Backtrack to previous non-blank line so we can determine indent level\n\t// for any white space lines (needed esp. within triple quoted strings)\n\t// and so we can fix any preceding fold level (which is why we go back\n\t// at least one line in all cases)\n\tint spaceFlags = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);\n\twhile (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tindentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);\n\t\tif (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&\n\t\t\t\t(!IsCommentLine(lineCurrent, styler)) &&\n\t\t\t\t(!IsQuoteLine(lineCurrent, styler)))\n\t\t\tbreak;\n\t}\n\tint indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\n\t// Set up initial loop state\n\tstartPos = styler.LineStart(lineCurrent);\n\tint prev_state = SCE_P_DEFAULT;\n\tif (lineCurrent >= 1)\n\t\tprev_state = styler.StyleIndexAt(startPos - 1);\n\tint prevQuote = options.foldQuotes && IsPyTripleQuoteStringState(prev_state);\n\n\t// Process all characters to end of requested range or end of any triple quote\n\t//that hangs over the end of the range.  Cap processing in all cases\n\t// to end of document (in case of unclosed quote at end).\n\twhile ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) {\n\n\t\t// Gather info\n\t\tint lev = indentCurrent;\n\t\tSci_Position lineNext = lineCurrent + 1;\n\t\tint indentNext = indentCurrent;\n\t\tint quote = false;\n\t\tif (lineNext <= docLines) {\n\t\t\t// Information about next line is only available if not at end of document\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);\n\t\t\tconst Sci_Position lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);\n\t\t\tconst int style = styler.StyleIndexAt(lookAtPos);\n\t\t\tquote = options.foldQuotes && IsPyTripleQuoteStringState(style);\n\t\t}\n\t\tconst bool quote_start = (quote && !prevQuote);\n\t\tconst bool quote_continue = (quote && prevQuote);\n\t\tif (!quote || !prevQuote)\n\t\t\tindentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\t\tif (quote)\n\t\t\tindentNext = indentCurrentLevel;\n\t\tif (indentNext & SC_FOLDLEVELWHITEFLAG)\n\t\t\tindentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;\n\n\t\tif (quote_start) {\n\t\t\t// Place fold point at start of triple quoted string\n\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t} else if (quote_continue || prevQuote) {\n\t\t\t// Add level to rest of lines in the string\n\t\t\tlev = lev + 1;\n\t\t}\n\n\t\t// Skip past any blank lines for next indent level info; we skip also\n\t\t// comments (all comments, not just those starting in column 0)\n\t\t// which effectively folds them into surrounding code rather\n\t\t// than screwing up folding.  If comments end file, use the min\n\t\t// comment indent as the level after\n\n\t\tint minCommentLevel = indentCurrentLevel;\n\t\twhile (!quote &&\n\t\t\t\t(lineNext < docLines) &&\n\t\t\t\t((indentNext & SC_FOLDLEVELWHITEFLAG) || (IsCommentLine(lineNext, styler)))) {\n\n\t\t\tif (IsCommentLine(lineNext, styler) && indentNext < minCommentLevel) {\n\t\t\t\tminCommentLevel = indentNext;\n\t\t\t}\n\n\t\t\tlineNext++;\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);\n\t\t}\n\n\t\tconst int levelAfterComments = ((lineNext < docLines) ? indentNext & SC_FOLDLEVELNUMBERMASK : minCommentLevel);\n\t\tconst int levelBeforeComments = std::max(indentCurrentLevel, levelAfterComments);\n\n\t\t// Now set all the indent levels on the lines we skipped\n\t\t// Do this from end to start.  Once we encounter one line\n\t\t// which is indented more than the line after the end of\n\t\t// the comment-block, use the level of the block before\n\n\t\tSci_Position skipLine = lineNext;\n\t\tint skipLevel = levelAfterComments;\n\n\t\twhile (--skipLine > lineCurrent) {\n\t\t\tconst int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, nullptr);\n\n\t\t\tif (options.foldCompact) {\n\t\t\t\tif ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)\n\t\t\t\t\tskipLevel = levelBeforeComments;\n\n\t\t\t\tconst int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;\n\n\t\t\t\tstyler.SetLevel(skipLine, skipLevel | whiteFlag);\n\t\t\t} else {\n\t\t\t\tif ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&\n\t\t\t\t\t\t!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&\n\t\t\t\t\t\t!IsCommentLine(skipLine, styler))\n\t\t\t\t\tskipLevel = levelBeforeComments;\n\n\t\t\t\tstyler.SetLevel(skipLine, skipLevel);\n\t\t\t}\n\t\t}\n\n\t\t// Set fold header on non-quote line\n\t\tif (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t}\n\n\t\t// Keep track of triple quote state of previous line\n\t\tprevQuote = quote;\n\n\t\t// Set fold level for this line and move to next line\n\t\tstyler.SetLevel(lineCurrent, options.foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);\n\t\tindentCurrent = indentNext;\n\t\tlineCurrent = lineNext;\n\t}\n\n\t// NOTE: Cannot set level of last line here because indentCurrent doesn't have\n\t// header flag set; the loop above is crafted to take care of this case!\n\t//styler.SetLevel(lineCurrent, indentCurrent);\n}\n\n}\n\nextern const LexerModule lmPython(SCLEX_PYTHON, LexerPython::LexerFactoryPython, \"python\",\n\t\t     pythonWordListDesc);\n"
  },
  {
    "path": "lexers/LexR.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexR.cxx\n ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer).\n **\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cassert>\n#include <cctype>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\ninline bool IsAWordChar(int ch) noexcept {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');\n}\n\ninline bool IsAWordStart(int ch) noexcept {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\nconstexpr bool IsAnOperator(int ch) noexcept {\n\t// '.' left out as it is used to make up numbers\n\tif (ch == '-' || ch == '+' || ch == '!' || ch == '~' ||\n\t        ch == '?' || ch == ':' || ch == '*' || ch == '/' ||\n\t        ch == '^' || ch == '<' || ch == '>' || ch == '=' ||\n\t        ch == '&' || ch == '|' || ch == '$' || ch == '(' ||\n\t        ch == ')' || ch == '}' || ch == '{' || ch == '[' ||\n\t\tch == ']')\n\t\treturn true;\n\treturn false;\n}\n\nconstexpr bool IsOctalOrHex(int ch, bool hex) noexcept {\n\treturn IsAnOctalDigit(ch) || (hex && IsAHeXDigit(ch));\n}\n\n// https://search.r-project.org/R/refmans/base/html/Quotes.html\nstruct EscapeSequence {\n\tint outerState = SCE_R_DEFAULT;\n\tint digitsLeft = 0;\n\tbool hex = false;\n\tbool brace = false;\n\n\t// highlight any character as escape sequence, unrecognized escape sequence is syntax error.\n\tvoid resetEscapeState(int state, int chNext) noexcept {\n\t\touterState = state;\n\t\tdigitsLeft = 1;\n\t\thex = true;\n\t\tbrace = false;\n\t\tif (chNext == 'x') {\n\t\t\tdigitsLeft = 3;\n\t\t} else if (chNext == 'u') {\n\t\t\tdigitsLeft = 5;\n\t\t} else if (chNext == 'U') {\n\t\t\tdigitsLeft = 9;\n\t\t} else if (IsAnOctalDigit(chNext)) {\n\t\t\tdigitsLeft = 3;\n\t\t\thex = false;\n\t\t}\n\t}\n\tbool atEscapeEnd(int ch) noexcept {\n\t\t--digitsLeft;\n\t\treturn digitsLeft <= 0 || !IsOctalOrHex(ch, hex);\n\t}\n};\n\nint CheckRawString(LexAccessor &styler, Sci_Position pos, int &dashCount) {\n\tdashCount = 0;\n\twhile (true) {\n\t\tconst char ch = styler.SafeGetCharAt(pos++);\n\t\tswitch (ch) {\n\t\tcase '-':\n\t\t\t++dashCount;\n\t\t\tbreak;\n\t\tcase '(':\n\t\t\treturn ')';\n\t\tcase '[':\n\t\t\treturn ']';\n\t\tcase '{':\n\t\t\treturn '}';\n\t\tdefault:\n\t\t\tdashCount = 0;\n\t\t\treturn 0;\n\t\t}\n\t}\n}\n\nvoid ColouriseRDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler) {\n\n\tconst WordList &keywords   = *keywordlists[0];\n\tconst WordList &keywords2 = *keywordlists[1];\n\tconst WordList &keywords3 = *keywordlists[2];\n\t// state for raw string\n\tint matchingDelimiter = 0;\n\tint dashCount = 0;\n\n\t// property lexer.r.escape.sequence\n\t//\tSet to 1 to enable highlighting of escape sequences in strings.\n\tconst bool escapeSequence = styler.GetPropertyInt(\"lexer.r.escape.sequence\", 0) != 0;\n\tEscapeSequence escapeSeq;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tif (sc.currentLine > 0) {\n\t\tconst int lineState = styler.GetLineState(sc.currentLine - 1);\n\t\tmatchingDelimiter = lineState & 0xff;\n\t\tdashCount = lineState >> 8;\n\t}\n\n\twhile (sc.More()) {\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\tcase SCE_R_OPERATOR:\n\t\t\tsc.SetState(SCE_R_DEFAULT);\n\t\t\tbreak;\n\n\t\tcase SCE_R_NUMBER:\n\t\t\t// https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Literal-constants\n\t\t\tif (AnyOf(sc.ch, 'e', 'E', 'p', 'P') && (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {\n\t\t\t\tsc.Forward(); // exponent part\n\t\t\t} else if (!(IsAHeXDigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))) {\n\t\t\t\tif (AnyOf(sc.ch, 'L', 'i')) {\n\t\t\t\t\tsc.Forward(); // integer and complex qualifier\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_R_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_R_IDENTIFIER:\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_R_KWORD);\n\t\t\t\t} else if  (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_R_BASEKWORD);\n\t\t\t\t} else if  (keywords3.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_R_OTHERKWORD);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_R_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_R_COMMENT:\n\t\t\tif (sc.MatchLineEnd()) {\n\t\t\t\tsc.SetState(SCE_R_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_R_STRING:\n\t\tcase SCE_R_STRING2:\n\t\tcase SCE_R_BACKTICKS:\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (escapeSequence) {\n\t\t\t\t\tescapeSeq.resetEscapeState(sc.state, sc.chNext);\n\t\t\t\t\tsc.SetState(SCE_R_ESCAPESEQUENCE);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tif (sc.chNext == '{' && AnyOf(sc.ch, 'u', 'U')) {\n\t\t\t\t\t\tescapeSeq.brace = true;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else if (sc.MatchLineEnd()) {\n\t\t\t\t\t\t// don't highlight line ending as escape sequence:\n\t\t\t\t\t\t// escapeSeq.outerState is lost when editing on next line.\n\t\t\t\t\t\tsc.SetState(escapeSeq.outerState);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tsc.Forward(); // Skip all characters after the backslash\n\t\t\t\t}\n\t\t\t} else if ((sc.state == SCE_R_STRING && sc.ch == '\\\"')\n\t\t\t\t|| (sc.state == SCE_R_STRING2 && sc.ch == '\\'')\n\t\t\t\t|| (sc.state == SCE_R_BACKTICKS && sc.ch == '`')) {\n\t\t\t\tsc.ForwardSetState(SCE_R_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_R_ESCAPESEQUENCE:\n\t\t\tif (escapeSeq.atEscapeEnd(sc.ch)) {\n\t\t\t\tif (escapeSeq.brace && sc.ch == '}') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.SetState(escapeSeq.outerState);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_R_RAWSTRING:\n\t\tcase SCE_R_RAWSTRING2:\n\t\t\twhile (sc.ch == matchingDelimiter) {\n\t\t\t\tsc.Forward();\n\t\t\t\tint count = dashCount;\n\t\t\t\twhile (count != 0 && sc.ch == '-') {\n\t\t\t\t\t--count;\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tif (count == 0 && sc.ch == ((sc.state == SCE_R_RAWSTRING) ? '\\\"' : '\\'')) {\n\t\t\t\t\tmatchingDelimiter = 0;\n\t\t\t\t\tdashCount = 0;\n\t\t\t\t\tsc.ForwardSetState(SCE_R_DEFAULT);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_R_INFIX:\n\t\t\tif (sc.ch == '%') {\n\t\t\t\tsc.ForwardSetState(SCE_R_DEFAULT);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_R_INFIXEOL);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_R_INFIXEOL:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_R_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_R_DEFAULT) {\n\t\t\tif (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_R_NUMBER);\n\t\t\t\tif (sc.ch == '0' && AnyOf(sc.chNext, 'x', 'X')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (AnyOf(sc.ch, 'r', 'R') && AnyOf(sc.chNext, '\\\"', '\\'')) {\n\t\t\t\tconst int chNext = sc.chNext;\n\t\t\t\tmatchingDelimiter = CheckRawString(styler, sc.currentPos + 2, dashCount);\n\t\t\t\tif (matchingDelimiter) {\n\t\t\t\t\tsc.SetState((chNext == '\\\"') ? SCE_R_RAWSTRING : SCE_R_RAWSTRING2);\n\t\t\t\t\tsc.Forward(dashCount + 2);\n\t\t\t\t} else {\n\t\t\t\t\t// syntax error\n\t\t\t\t\tsc.SetState(SCE_R_IDENTIFIER);\n\t\t\t\t\tsc.ForwardSetState((chNext == '\\\"') ? SCE_R_STRING : SCE_R_STRING2);\n\t\t\t\t}\n\t\t\t} else if (IsAWordStart(sc.ch) ) {\n\t\t\t\tsc.SetState(SCE_R_IDENTIFIER);\n\t\t\t} else if (sc.Match('#')) {\n\t\t\t\tsc.SetState(SCE_R_COMMENT);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_R_STRING);\n\t\t\t} else if (sc.ch == '%') {\n\t\t\t\tsc.SetState(SCE_R_INFIX);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_R_STRING2);\n\t\t\t} else if (sc.ch == '`') {\n\t\t\t\tsc.SetState(SCE_R_BACKTICKS);\n\t\t\t} else if (IsAnOperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_R_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\tconst int lineState = matchingDelimiter | (dashCount << 8);\n\t\t\tstyler.SetLineState(sc.currentLine, lineState);\n\t\t}\n\t\tsc.Forward();\n\t}\n\tsc.Complete();\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\nvoid FoldRDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],\n                       Accessor &styler) {\n\tconst bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tconst bool foldAtElse = styler.GetPropertyInt(\"fold.at.else\", 0) != 0;\n\tconst Sci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelMinCurrent = levelCurrent;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tconst bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (style == SCE_R_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\t// Measure the minimum before a '{' to allow\n\t\t\t\t// folding on \"} else {\"\n\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t}\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tif (foldAtElse) {\n\t\t\t\tlevelUse = levelMinCurrent;\n\t\t\t}\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelMinCurrent = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n}\n\n\nconst char * const RWordLists[] = {\n\t\t\"Language Keywords\",\n\t\t\"Base / Default package function\",\n\t\t\"Other Package Functions\",\n\t\t\"Unused\",\n\t\t\"Unused\",\n\t\tnullptr,\n};\n\n}\n\nextern const LexerModule lmR(SCLEX_R, ColouriseRDoc, \"r\", FoldRDoc, RWordLists);\n"
  },
  {
    "path": "lexers/LexRaku.cxx",
    "content": "/** @file LexRaku.cxx\n ** Lexer for Raku\n **\n ** Copyright (c) 2019 Mark Reay <mark@reay.net.au>\n **/\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n/*\n * Raku (Perl6) Lexer for Scintilla\n * ---------------------------------\n * ---------------------------------\n * 06-Dec-2019: More Unicode support:\n *              - Added a full scope of allowed numbers and letters\n * 29-Nov-2019: More  highlighting / implemented basic folding:\n *              - Operators (blanket cover, no sequence checking)\n *              - Class / Grammar name highlighting\n *              - Folding:\n *                - Comments: line / multi-line\n *                - POD sections\n *                - Code blocks {}\n * 26-Nov-2019: Basic syntax highlighting covering the following:\n *              - Comments, both line and embedded (multi-line)\n *              - POD, no inline highlighting as yet...\n *              - Heredoc block string, with variable highlighting (with qq)\n *              - Strings, with variable highlighting (with \")\n *              - Q Language, including adverbs (also basic q and qq)\n *              - Regex, including adverbs\n *              - Numbers\n *              - Bareword / identifiers\n *              - Types\n *              - Variables: mu, positional, associative, callable\n * TODO:\n *       - POD inline\n *       - Better operator sequence coverage\n */\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"CharacterCategory.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace { // anonymous namespace to isolate any name clashes\n/*----------------------------------------------------------------------------*\n * --- DEFINITIONS: OPTIONS / CONSTANTS ---\n *----------------------------------------------------------------------------*/\n\n// Number types\n#define RAKUNUM_BINARY\t\t1\t// order is significant: 1-3 cannot have a dot\n#define RAKUNUM_OCTAL\t\t2\n#define RAKUNUM_FLOAT_EXP\t3\t// exponent part only\n#define RAKUNUM_HEX\t\t\t4\t// may be a hex float\n#define RAKUNUM_DECIMAL\t\t5\t// 1-5 are numbers; 6-7 are strings\n#define RAKUNUM_VECTOR\t\t6\n#define RAKUNUM_V_VECTOR\t7\n#define RAKUNUM_VERSION\t\t8\t// can contain multiple '.'s\n#define RAKUNUM_BAD\t\t\t9\n\n// Regex / Q string types\n#define RAKUTYPE_REGEX_NORM\t\t0\t// 0 char ident\n#define RAKUTYPE_REGEX_S\t\t1\t// order is significant:\n#define RAKUTYPE_REGEX_M\t\t2\t// 1 char ident\n#define RAKUTYPE_REGEX_Y\t\t3\t// 1 char ident\n#define RAKUTYPE_REGEX\t\t\t4\t// > RAKUTYPE_REGEX == 2 char identifiers\n#define RAKUTYPE_REGEX_RX\t\t5\t// 2 char ident\n#define RAKUTYPE_REGEX_TR\t\t6\t// 2 char ident\n#define RAKUTYPE_QLANG\t\t\t7\t// < RAKUTYPE_QLANG == RAKUTYPE_REGEX_?\n#define RAKUTYPE_STR_WQ\t\t\t8\t// 0 char ident < word quote >\n#define RAKUTYPE_STR_Q\t\t\t9\t// 1 char ident\n#define RAKUTYPE_STR_QX\t\t\t10\t// 2 char ident\n#define RAKUTYPE_STR_QW\t\t\t11\t// 2 char ident\n#define RAKUTYPE_STR_QQ\t\t\t12\t// 2 char ident\n#define RAKUTYPE_STR_QQX\t\t13\t// 3 char ident\n#define RAKUTYPE_STR_QQW\t\t14\t// 3 char ident\n#define RAKUTYPE_STR_QQWW\t\t15\t// 4 char ident\n\n// Delimiter types\n#define RAKUDELIM_BRACKET\t\t0\t// bracket: regex, Q language\n#define RAKUDELIM_QUOTE\t\t\t1\t// quote: normal string\n\n// rakuWordLists: keywords as defined in config\nconst char *const rakuWordLists[] = {\n\t\"Keywords and identifiers\",\n\t\"Functions\",\n\t\"Types basic\",\n\t\"Types composite\",\n\t\"Types domain-specific\",\n\t\"Types exception\",\n\t\"Adverbs\",\n\tnullptr,\n};\n\n// Options and defaults\nstruct OptionsRaku {\n\tbool fold;\n\tbool foldCompact;\n\tbool foldComment;\n\tbool foldCommentMultiline;\n\tbool foldCommentPOD;\n\tOptionsRaku() {\n\t\tfold\t\t\t\t\t= true;\n\t\tfoldCompact\t\t\t\t= false;\n\t\tfoldComment\t\t\t\t= true;\n\t\tfoldCommentMultiline\t= true;\n\t\tfoldCommentPOD\t\t\t= true;\n\t}\n};\n\n// init options and words\nstruct OptionSetRaku : public OptionSet<OptionsRaku> {\n\tOptionSetRaku() {\n\t\tDefineProperty(\"fold\",\t\t\t&OptionsRaku::fold);\n\t\tDefineProperty(\"fold.comment\",\t&OptionsRaku::foldComment);\n\t\tDefineProperty(\"fold.compact\",\t&OptionsRaku::foldCompact);\n\n\t\tDefineProperty(\"fold.raku.comment.multiline\",\t&OptionsRaku::foldCommentMultiline,\n\t\t\t\"Set this property to 0 to disable folding multi-line comments when fold.comment=1.\");\n\t\tDefineProperty(\"fold.raku.comment.pod\",\t\t\t&OptionsRaku::foldCommentPOD,\n\t\t\t\"Set this property to 0 to disable folding POD comments when fold.comment=1.\");\n\n\t\t// init word lists\n\t\tDefineWordListSets(rakuWordLists);\n\t}\n};\n\n// Delimiter pair\nstruct DelimPair {\n\tint opener;\t\t// opener char\n\tint closer[2];\t// closer chars\n\tbool interpol;\t// can variables be interpolated?\n\tshort count;\t// delimiter char count\n\tDelimPair() {\n\t\topener = 0;\n\t\tcloser[0] = 0;\n\t\tcloser[1] = 0;\n\t\tinterpol = false;\n\t\tcount = 0;\n\t}\n\tbool isCloser(int ch) const {\n\t\treturn ch == closer[0] || ch == closer[1];\n\t}\n};\n\n/*----------------------------------------------------------------------------*\n * --- FUNCTIONS ---\n *----------------------------------------------------------------------------*/\n\n/*\n * IsANewLine\n * - returns true if this is a new line char\n */\nconstexpr bool IsANewLine(int ch) noexcept {\n\treturn ch == '\\r' || ch == '\\n';\n}\n\n/*\n * IsAWhitespace\n * - returns true if this is a whitespace (or newline) char\n */\nbool IsAWhitespace(int ch) noexcept {\n\treturn IsASpaceOrTab(ch) || IsANewLine(ch);\n}\n\n/*\n * IsAlphabet\n * - returns true if this is an alphabetical char\n */\nconstexpr bool IsAlphabet(int ch) noexcept {\n\treturn (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');\n}\n\n/*\n * IsCommentLine\n * - returns true if this is a comment line\n *   - tests: SCE_RAKU_COMMENTLINE or SCE_RAKU_COMMENTEMBED\n * modified from: LexPerl.cxx\n */\nbool IsCommentLine(Sci_Position line, LexAccessor &styler, int type = SCE_RAKU_COMMENTLINE) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eol_pos; i++) {\n\t\tchar ch = styler[i];\n\t\tint style = styler.StyleAt(i);\n\t\tif (type == SCE_RAKU_COMMENTEMBED) {\n\t\t\tif (i == (eol_pos - 1) && style == type)\n\t\t\t\treturn true;\n\t\t} else { // make sure the line is NOT a SCE_RAKU_COMMENTEMBED\n\t\t\tif (ch == '#' && style == type && styler[i+1] != '`' )\n\t\t\t\treturn true;\n\t\t\telse if (!IsASpaceOrTab(ch))\n\t\t\t\treturn false;\n\t\t}\n\t}\n\treturn false;\n}\n\n/*\n * ContainsQTo\n * - returns true if this range contains \":to\" in style SCE_RAKU_ADVERB indicating the start\n * of a SCE_RAKU_HEREDOC_Q or SCE_RAKU_HEREDOC_QQ.\n */\nbool ContainsQTo(Sci_Position start, Sci_Position end, LexAccessor &styler) {\n\tstd::string adverb;\n\tfor (Sci_Position i = start; i < end; i++) {\n\t\tif (styler.StyleAt(i) == SCE_RAKU_ADVERB) {\n\t\t\tadverb.push_back(styler[i]);\n\t\t}\n\t}\n\treturn adverb.find(\":to\") != std::string::npos;\n}\n\n/*\n * GetBracketCloseChar\n * - returns the end bracket char: opposite of start\n *   - see: http://www.unicode.org/Public/5.1.0/ucd/BidiMirroring.txt (first section)\n * - Categories are general matches for valid BiDi types\n * - Most closer chars are opener + 1\n */\nint GetBracketCloseChar(const int ch) noexcept {\n\tconst CharacterCategory cc = CategoriseCharacter(ch);\n\tswitch (cc) {\n\t\tcase ccSm:\n\t\t\tswitch (ch) {\n\t\t\t\tcase 0x3C: return 0x3E; // LESS-THAN SIGN\n\t\t\t\tcase 0x2208: return 0x220B; // ELEMENT OF\n\t\t\t\tcase 0x2209: return 0x220C; // NOT AN ELEMENT OF\n\t\t\t\tcase 0x220A: return 0x220D; // SMALL ELEMENT OF\n\t\t\t\tcase 0x2215: return 0x29F5; // DIVISION SLASH\n\t\t\t\tcase 0x2243: return 0x22CD; // ASYMPTOTICALLY EQUAL TO\n\t\t\t\tcase 0x2298: return 0x29B8; // CIRCLED DIVISION SLASH\n\t\t\t\tcase 0x22A6: return 0x2ADE; // ASSERTION\n\t\t\t\tcase 0x22A8: return 0x2AE4; // TRUE\n\t\t\t\tcase 0x22A9: return 0x2AE3; // FORCES\n\t\t\t\tcase 0x22AB: return 0x2AE5; // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE\n\t\t\t\tcase 0x22F2: return 0x22FA; // ELEMENT OF WITH LONG HORIZONTAL STROKE\n\t\t\t\tcase 0x22F3: return 0x22FB; // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE\n\t\t\t\tcase 0x22F4: return 0x22FC; // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE\n\t\t\t\tcase 0x22F6: return 0x22FD; // ELEMENT OF WITH OVERBAR\n\t\t\t\tcase 0x22F7: return 0x22FE; // SMALL ELEMENT OF WITH OVERBAR\n\t\t\t\tcase 0xFF1C: return 0xFF1E; // FULLWIDTH LESS-THAN SIGN\n\t\t\t}\n\t\t\tbreak;\n\t\tcase ccPs:\n\t\t\tswitch (ch) {\n\t\t\t\tcase 0x5B: return 0x5D; // LEFT SQUARE BRACKET\n\t\t\t\tcase 0x7B: return 0x7D; // LEFT CURLY BRACKET\n\t\t\t\tcase 0x298D: return 0x2990; // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER\n\t\t\t\tcase 0x298F: return 0x298E; // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER\n\t\t\t\tcase 0xFF3B: return 0xFF3D; // FULLWIDTH LEFT SQUARE BRACKET\n\t\t\t\tcase 0xFF5B: return 0xFF5D; // FULLWIDTH LEFT CURLY BRACKET\n\t\t\t}\n\t\t\tbreak;\n\t\tcase ccPi:\n\t\t\tbreak;\n\t\tdefault: return 0;\n\t}\n\treturn ch + 1;\n}\n\n/*\n * IsValidQuoteOpener\n * -\n */\nbool IsValidQuoteOpener(const int ch, DelimPair &dp, int type = RAKUDELIM_BRACKET) noexcept {\n\tdp.closer[0] = 0;\n\tdp.closer[1] = 0;\n\tdp.interpol = true;\n\tif (type == RAKUDELIM_QUOTE) {\n\t\tswitch (ch) {\n\t\t\t//   Opener\t\tCloser\t\t\t\t\tDescription\n\t\t\tcase '\\'':\t\tdp.closer[0] = '\\'';\t// APOSTROPHE\n\t\t\t\tdp.interpol = false;\n\t\t\t\tbreak;\n\t\t\tcase '\"':\t\tdp.closer[0] = '\"';\t\t// QUOTATION MARK\n\t\t\t\tbreak;\n\t\t\tcase 0x2018:\tdp.closer[0] = 0x2019;\t// LEFT SINGLE QUOTATION MARK\n\t\t\t\tdp.interpol = false;\n\t\t\t\tbreak;\n\t\t\tcase 0x201C:\tdp.closer[0] = 0x201D;\t// LEFT DOUBLE QUOTATION MARK\n\t\t\t\tbreak;\n\t\t\tcase 0x201D:\tdp.closer[0] = 0x201C;\t// RIGHT DOUBLE QUOTATION MARK\n\t\t\t\tbreak;\n\t\t\tcase 0x201E:\tdp.closer[0] = 0x201C;\t// DOUBLE LOW-9 QUOTATION MARK\n\t\t\t\t\t\t\tdp.closer[1] = 0x201D;\n\t\t\t\tbreak;\n\t\t\tcase 0xFF62:\tdp.closer[0] = 0xFF63;\t// HALFWIDTH LEFT CORNER BRACKET\n\t\t\t\tdp.interpol = false;\n\t\t\t\tbreak;\n\t\t\tdefault:\t\treturn false;\n\t\t}\n\t} else if (type == RAKUDELIM_BRACKET) {\n\t\tdp.closer[0] = GetBracketCloseChar(ch);\n\t}\n\tdp.opener = ch;\n\tdp.count = 1;\n\treturn dp.closer[0] > 0;\n}\n\n/*\n * IsBracketOpenChar\n * - true if this is a valid start bracket character\n */\nbool IsBracketOpenChar(int ch) noexcept {\n\treturn GetBracketCloseChar(ch) > 0;\n}\n\n/*\n * IsValidRegOrQAdjacent\n * - returns true if ch is a valid character to put directly after Q / q\n *   * ref: Q Language: https://docs.raku.org/language/quoting\n */\nbool IsValidRegOrQAdjacent(int ch) noexcept {\n\treturn !(IsAlphaNumeric(ch) || ch == '_' || ch == '(' || ch == ')' || ch == '\\'' );\n}\n\n/*\n * IsValidRegOrQPrecede\n * - returns true if ch is a valid preceding character to put directly before Q / q\n *   * ref: Q Language: https://docs.raku.org/language/quoting\n */\nbool IsValidRegOrQPrecede(int ch) noexcept {\n\treturn !(IsAlphaNumeric(ch) || ch == '_');\n}\n\n/*\n * MatchCharInRange\n * - returns true if the mach character is found in range (of length)\n * - ignoreDelim (default false)\n */\nbool MatchCharInRange(StyleContext &sc, const Sci_Position length,\n\t\tconst int match, bool ignoreDelim = false) {\n\tSci_Position len = 0;\n\tint chPrev = sc.chPrev;\n\twhile (++len < length) {\n\t\tconst int ch = sc.GetRelativeCharacter(len);\n\t\tif (ch == match && (ignoreDelim || chPrev != '\\\\'))\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\n/*\n * PrevNonWhitespaceChar\n * - returns the last non-whitespace char\n */\nint PrevNonWhitespaceChar(StyleContext &sc) {\n\tSci_Position rel = 0;\n\tSci_Position max_back = 0 - sc.currentPos;\n\twhile (--rel > max_back) {\n\t\tconst int ch = sc.GetRelativeCharacter(rel);\n\t\tif (!IsAWhitespace(ch))\n\t\t\treturn ch;\n\t}\n\treturn 0; // no matching char\n}\n\n/*\n * IsQLangStartAtScPos\n * - returns true if this is a valid Q Language sc position\n *   - ref: https://docs.raku.org/language/quoting\n *   - Q :adverb :adverb //;\n *   - q,qx,qw,qq,qqx,qqw,qqww :adverb /:adverb /;\n */\nbool IsQLangStartAtScPos(StyleContext &sc, int &type, const Sci_Position length) {\n\tconst bool valid_adj = IsValidRegOrQAdjacent(sc.chNext);\n\tconst int chFw2 = sc.GetRelativeCharacter(2);\n\tconst int chFw3 = sc.GetRelativeCharacter(3);\n\ttype = -1;\n\tif (IsValidRegOrQPrecede(sc.chPrev)) {\n\t\tif (sc.ch == 'Q' && valid_adj) {\n\t\t\ttype = RAKUTYPE_QLANG;\n\t\t} else if (sc.ch == 'q') {\n\t\t\tswitch (sc.chNext) {\n\t\t\t\tcase 'x':\n\t\t\t\t\ttype = RAKUTYPE_STR_QX;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'w':\n\t\t\t\t\ttype = RAKUTYPE_STR_QW;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'q':\n\t\t\t\t\tif (chFw2 == 'x') {\n\t\t\t\t\t\ttype = RAKUTYPE_STR_QQX;\n\t\t\t\t\t} else if (chFw2 == 'w') {\n\t\t\t\t\t\tif (chFw3 == 'w') {\n\t\t\t\t\t\t\ttype = RAKUTYPE_STR_QQWW;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttype = RAKUTYPE_STR_QQW;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttype = RAKUTYPE_STR_QQ;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\ttype = RAKUTYPE_STR_Q;\n\t\t\t}\n\t\t} else if (sc.ch == '<' && MatchCharInRange(sc, length, '>')) {\n\t\t\ttype = RAKUTYPE_STR_WQ; // < word quote >\n\t\t}\n\t}\n\treturn type >= 0;\n}\n\n/*\n * IsRegexStartAtScPos\n * - returns true if this is a valid Regex sc position\n *   - ref: https://docs.raku.org/language/regexes\n *   - Regex: (rx/s/m/tr/y) :adverb /:adverb /;\n *   -              regex R :adverb //;\n *   -                     /:adverb /;\n */\nbool IsRegexStartAtScPos(StyleContext &sc, int &type, CharacterSet &set) {\n\tconst bool valid_adj = IsValidRegOrQAdjacent(sc.chNext);\n\ttype = -1;\n\tif (IsValidRegOrQPrecede(sc.chPrev)) {\n\t\tswitch (sc.ch) {\n\t\t\tcase 'r':\n\t\t\t\tif (sc.chNext == 'x')\n\t\t\t\t\ttype = RAKUTYPE_REGEX_RX;\n\t\t\t\tbreak;\n\t\t\tcase 't':\n\t\t\tcase 'T':\n\t\t\t\tif (sc.chNext == 'r' || sc.chNext == 'R')\n\t\t\t\t\ttype = RAKUTYPE_REGEX_TR;\n\t\t\t\tbreak;\n\t\t\tcase 'm':\n\t\t\t\tif (valid_adj)\n\t\t\t\t\ttype = RAKUTYPE_REGEX_M;\n\t\t\t\tbreak;\n\t\t\tcase 's':\n\t\t\tcase 'S':\n\t\t\t\tif (valid_adj)\n\t\t\t\t\ttype = RAKUTYPE_REGEX_S;\n\t\t\t\tbreak;\n\t\t\tcase 'y':\n\t\t\t\tif (valid_adj)\n\t\t\t\t\ttype = RAKUTYPE_REGEX_Y;\n\t\t\t\tbreak;\n\t\t\tcase '/':\n\t\t\t\tif (set.Contains(PrevNonWhitespaceChar(sc)))\n\t\t\t\t\ttype = RAKUTYPE_REGEX_NORM;\n\t\t}\n\t}\n\treturn type >= 0;\n}\n\n/*\n * IsValidIdentPrecede\n * - returns if ch is a valid preceding char to put directly before an identifier\n */\nbool IsValidIdentPrecede(int ch) noexcept {\n\treturn !(IsAlphaNumeric(ch) || ch == '_' || ch == '@' || ch == '$' || ch == '%');\n}\n\n/*\n * IsValidDelimiter\n * - returns if ch is a valid delimiter (most chars are valid)\n *   * ref: Q Language: https://docs.raku.org/language/quoting\n */\nbool IsValidDelimiter(int ch) noexcept {\n\treturn !(IsAlphaNumeric(ch) || ch == ':');\n}\n\n/*\n * GetDelimiterCloseChar\n * - returns the corresponding close char for a given delimiter (could be the same char)\n */\nint GetDelimiterCloseChar(int ch) noexcept {\n\tint ch_end = GetBracketCloseChar(ch);\n\tif (ch_end == 0 && IsValidDelimiter(ch)) {\n\t\tch_end = ch;\n\t}\n\treturn ch_end;\n}\n\n/*\n * GetRepeatCharCount\n * - returns the occurrence count of match\n */\nSci_Position GetRepeatCharCount(StyleContext &sc, int chMatch, Sci_Position length) {\n\tSci_Position cnt = 0;\n\twhile (cnt < length) {\n\t\tif (sc.GetRelativeCharacter(cnt) != chMatch) {\n\t\t\tbreak;\n\t\t}\n\t\tcnt++;\n\t}\n\treturn cnt;\n}\n\n/*\n * LengthToDelimiter\n * - returns the length until the end of a delimited string section\n *   - Ignores nested delimiters (if opener != closer)\n *   - no trailing char after last closer (default false)\n */\nSci_Position LengthToDelimiter(StyleContext &sc, const DelimPair &dp,\n\t\tSci_Position length, bool noTrailing = false) {\n\tshort cnt_open = 0;\t\t\t// count open bracket\n\tshort cnt_close = 0;\t\t// count close bracket\n\tbool is_escape = false;\t\t// has been escaped using '\\'?\n\tSci_Position len = 0;\t\t// count characters\n\tint chOpener = dp.opener;\t// look for nested opener / closer\n\tif (dp.opener == dp.closer[0])\n\t\tchOpener = 0;\t\t\t// no opening delimiter (no nesting possible)\n\n\twhile (len < length) {\n\t\tconst int chPrev = sc.GetRelativeCharacter(len - 1);\n\t\tconst int ch = sc.GetRelativeCharacter(len);\n\t\tconst int chNext = sc.GetRelativeCharacter(len+1);\n\n\t\tif (cnt_open == 0 && cnt_close == dp.count) {\n\t\t\treturn len;\t\t\t\t// end condition has been met\n\t\t} else if (is_escape) {\n\t\t\tis_escape = false;\n\t\t} else if (ch == '\\\\') {\n\t\t\tis_escape = true;\n\t\t} else {\n\t\t\tif (ch == chOpener) {\n\t\t\t\tcnt_open++;\t\t\t// open nested bracket\n\t\t\t} else if (dp.isCloser(ch)) {\n\t\t\t\tif ( cnt_open > 0 ) {\n\t\t\t\t\tcnt_open--;\t\t// close nested bracket\n\t\t\t\t} else if (dp.count > 1 && cnt_close < (dp.count - 1)) {\n\t\t\t\t\tif (cnt_close > 1) {\n\t\t\t\t\t\tif (dp.isCloser(chPrev)) {\n\t\t\t\t\t\t\tcnt_close++;\n\t\t\t\t\t\t} else {\t// reset if previous char was not close\n\t\t\t\t\t\t\tcnt_close = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcnt_close++;\n\t\t\t\t\t}\n\t\t\t\t} else if (!noTrailing || (IsAWhitespace(chNext))) {\n\t\t\t\t\tcnt_close++;\t\t// found last close\n\t\t\t\t\tif (cnt_close > 1 && !dp.isCloser(chPrev)) {\n\t\t\t\t\t\tcnt_close = 0;\t// reset if previous char was not close\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcnt_close = 0;\t\t// non handled close: reset\n\t\t\t\t}\n\t\t\t} else if (IsANewLine(ch)) {\n\t\t\t\tcnt_open = 0;\t\t\t// reset after each line\n\t\t\t\tcnt_close = 0;\n\t\t\t}\n\t\t}\n\t\tlen++;\n\t}\n\treturn -1; // end condition has NOT been met\n}\n\n/*\n * LengthToEndHeredoc\n * - returns the length until the end of a heredoc section\n *   - delimiter string MUST begin on a new line\n */\nSci_Position LengthToEndHeredoc(const StyleContext &sc, LexAccessor &styler,\n\t\tconst Sci_Position length, const char *delim) {\n\tbool on_new_ln = false;\n\tint i = 0; // str index\n\tfor (int n = 0; n < length; n++) {\n\t\tconst char ch = styler.SafeGetCharAt(sc.currentPos + n, 0);\n\t\tif (on_new_ln) {\n\t\t\tif (delim[i] == '\\0')\n\t\t\t\treturn n;\t// at end of str, match found!\n\t\t\tif (ch != delim[i++])\n\t\t\t\ti = 0;\t\t// no char match, reset 'i'ndex\n\t\t}\n\t\tif (i == 0)\t\t\t// detect new line\n\t\t\ton_new_ln = IsANewLine(ch);\n\t}\n\treturn -1;\t\t\t\t// no match found\n}\n\n/*\n * LengthToNextChar\n * - returns the length until the next character\n */\nSci_Position LengthToNextChar(StyleContext &sc, const Sci_Position length) {\n\tSci_Position len = 0;\n\twhile (++len < length) {\n\t\tconst int ch = sc.GetRelativeCharacter(len);\n\t\tif (!IsASpaceOrTab(ch) && !IsANewLine(ch)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn len;\n}\n\n/*\n * GetRelativeString\n * - gets a relative string and sets it in &str\n *   - resets string before setting\n */\nvoid GetRelativeString(StyleContext &sc, Sci_Position offset, Sci_Position length,\n\t\tstd::string &str) {\n\tSci_Position pos = offset;\n\tstr.clear();\n\twhile (pos < length) {\n\t\tstr += sc.GetRelativeCharacter(pos++);\n\t}\n}\n\n} // end anonymous namespace\n\n/*----------------------------------------------------------------------------*\n * --- class: LexerRaku ---\n *----------------------------------------------------------------------------*/\n//class LexerRaku : public ILexerWithMetaData {\nclass LexerRaku : public DefaultLexer {\n\tCharacterSet setWord;\n\tCharacterSet setSigil;\n\tCharacterSet setTwigil;\n\tCharacterSet setOperator;\n\tCharacterSet setSpecialVar;\n\tWordList regexIdent;\t\t\t// identifiers that specify a regex\n\tOptionsRaku options;\t\t\t// Options from config\n\tOptionSetRaku osRaku;\n\tWordList keywords;\t\t\t\t// Word Lists from config\n\tWordList functions;\n\tWordList typesBasic;\n\tWordList typesComposite;\n\tWordList typesDomainSpecific;\n\tWordList typesExceptions;\n\tWordList adverbs;\n\npublic:\n\t// Defined as explicit, so that constructor can not be copied\n\texplicit LexerRaku() :\n\t\tDefaultLexer(\"raku\", SCLEX_RAKU),\n\t\tsetWord(CharacterSet::setAlphaNum, \"-_\", 0x80),\n\t\tsetSigil(CharacterSet::setNone, \"$&%@\"),\n\t\tsetTwigil(CharacterSet::setNone, \"!*.:<=?^~\"),\n\t\tsetOperator(CharacterSet::setNone, \"^&\\\\()-+=|{}[]:;<>,?!.~\"),\n\t\tsetSpecialVar(CharacterSet::setNone, \"_/!\") {\n\t\tregexIdent.Set(\"regex rule token\");\n\t}\n\t// Deleted so LexerRaku objects can not be copied.\n\tLexerRaku(const LexerRaku &) = delete;\n\tLexerRaku(LexerRaku &&) = delete;\n\tvoid operator=(const LexerRaku &) = delete;\n\tvoid operator=(LexerRaku &&) = delete;\n\tvirtual ~LexerRaku() {\n\t}\n\tvoid SCI_METHOD Release() noexcept override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const noexcept override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osRaku.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osRaku.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osRaku.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osRaku.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osRaku.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tstatic ILexer5 *LexerFactoryRaku() {\n\t\treturn new LexerRaku();\n\t}\n\nprotected:\n\tbool IsOperatorChar(const int ch);\n\tbool IsWordChar(const int ch, bool allowNumber = true);\n\tbool IsWordStartChar(const int ch);\n\tbool IsNumberChar(const int ch, int base = 10);\n\tbool ProcessRegexTwinCapture(StyleContext &sc, const Sci_Position length,\n\t\tint &type, const DelimPair &dp);\n\tvoid ProcessStringVars(StyleContext &sc, const Sci_Position length, const int varState);\n\tbool ProcessValidRegQlangStart(StyleContext &sc, Sci_Position length, const int type,\n\t\tWordList &wordsAdverbs, DelimPair &dp);\n\tSci_Position LengthToNonWordChar(StyleContext &sc, Sci_Position length,\n\t\tchar *s, const int size, Sci_Position offset = 0);\n};\n\n/*----------------------------------------------------------------------------*\n * --- METHODS: LexerRaku ---\n *----------------------------------------------------------------------------*/\n\n/*\n * LexerRaku::IsOperatorChar\n * - Test for both ASCII and Unicode operators\n *   see: https://docs.raku.org/language/unicode_entry\n */\nbool LexerRaku::IsOperatorChar(const int ch) {\n\tif (ch > 0x7F) {\n\t\tswitch (ch) {\n\t\t\t//   Unicode\tASCII Equiv.\n\t\t\tcase 0x2208:\t// (elem)\n\t\t\tcase 0x2209:\t// !(elem)\n\t\t\tcase 0x220B:\t// (cont)\n\t\t\tcase 0x220C:\t// !(cont)\n\t\t\tcase 0x2216:\t// (-)\n\t\t\tcase 0x2229:\t// (&)\n\t\t\tcase 0x222A:\t// (|)\n\t\t\tcase 0x2282:\t// (<)\n\t\t\tcase 0x2283:\t// (>)\n\t\t\tcase 0x2284:\t// !(<)\n\t\t\tcase 0x2285:\t// !(>)\n\t\t\tcase 0x2286:\t// (<=)\n\t\t\tcase 0x2287:\t// (>=)\n\t\t\tcase 0x2288:\t// !(<=)\n\t\t\tcase 0x2289:\t// !(>=)\n\t\t\tcase 0x228D:\t// (.)\n\t\t\tcase 0x228E:\t// (+)\n\t\t\tcase 0x2296:\t// (^)\n\t\t\t\treturn true;\n\t\t}\n\t}\n\treturn setOperator.Contains(ch);\n}\n\n/*\n * LexerRaku::IsWordChar\n * - Test for both ASCII and Unicode identifier characters\n *   see: https://docs.raku.org/language/unicode_ascii\n *   also: ftp://ftp.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt\n *   FIXME: *still* may not contain all valid characters\n */\nbool LexerRaku::IsWordChar(const int ch, bool allowNumber) {\n\t// Unicode numbers should not appear in word identifiers\n\tif (ch > 0x7F) {\n\t\tconst CharacterCategory cc = CategoriseCharacter(ch);\n\t\tswitch (cc) {\n\t\t\t// Letters\n\t\t\tcase ccLu:\n\t\t\tcase ccLl:\n\t\t\tcase ccLt:\n\t\t\tcase ccLm:\n\t\t\tcase ccLo:\n\t\t\t\treturn true;\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\t} else if (allowNumber && IsADigit(ch)) {\n\t\treturn true; // an ASCII number type\n\t}\n\treturn setWord.Contains(ch);\n}\n\n/*\n * LexerRaku::IsWordStartChar\n * - Test for both ASCII and Unicode identifier \"start / first\" characters\n */\nbool LexerRaku::IsWordStartChar(const int ch) {\n\treturn ch != '-' && IsWordChar(ch, false); // no numbers allowed\n}\n\n/*\n * LexerRaku::IsNumberChar\n * - Test for both ASCII and Unicode identifier number characters\n *   see: https://docs.raku.org/language/unicode_ascii\n *   also: ftp://ftp.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt\n *   FILTERED by Unicode letters that are NUMBER\n *     and NOT PARENTHESIZED or CIRCLED\n *   FIXME: *still* may not contain all valid number characters\n */\nbool LexerRaku::IsNumberChar(const int ch, int base) {\n\tif (ch > 0x7F) {\n\t\tconst CharacterCategory cc = CategoriseCharacter(ch);\n\t\tswitch (cc) {\n\t\t\t// Numbers\n\t\t\tcase ccNd:\n\t\t\tcase ccNl:\n\t\t\tcase ccNo:\n\t\t\t\treturn true;\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\t}\n\treturn IsADigit(ch, base);\n}\n\n/*\n * LexerRaku::PropertySet\n * -\n */\nSci_Position SCI_METHOD LexerRaku::PropertySet(const char *key, const char *val) {\n\tif (osRaku.PropertySet(&options, key, val))\n\t\treturn 0;\n\treturn -1;\n}\n\n/*\n * LexerRaku::WordListSet\n * -\n */\nSci_Position SCI_METHOD LexerRaku::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\t\tcase 0:\n\t\t\twordListN = &keywords;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\twordListN = &functions;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\twordListN = &typesBasic;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\twordListN = &typesComposite;\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\twordListN = &typesDomainSpecific;\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\twordListN = &typesExceptions;\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\twordListN = &adverbs;\n\t\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\n/*\n * LexerRaku::ProcessRegexTwinCapture\n * - processes the transition between a regex pair (two sets of delimiters)\n * - moves to first new delimiter, if a bracket\n * - returns true when valid delimiter start found (if bracket)\n */\nbool LexerRaku::ProcessRegexTwinCapture(StyleContext &sc, const Sci_Position length,\n\t\tint &type, const DelimPair &dp) {\n\n\tif (type == RAKUTYPE_REGEX_S || type == RAKUTYPE_REGEX_TR || type == RAKUTYPE_REGEX_Y) {\n\t\ttype = -1; // clear type\n\n\t\t// move past chRegQClose if it was the previous char\n\t\tif (dp.isCloser(sc.chPrev))\n\t\t\tsc.Forward();\n\n\t\t// no processing needed for non-bracket\n\t\tif (dp.isCloser(dp.opener))\n\t\t\treturn true;\n\n\t\t// move to next opening bracket\n\t\tconst Sci_Position len = LengthToNextChar(sc, length);\n\t\tif (sc.GetRelativeCharacter(len) == dp.opener) {\n\t\t\tsc.Forward(len);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/*\n * LexerRaku::ProcessStringVars\n * - processes a string and highlights any valid variables\n */\nvoid LexerRaku::ProcessStringVars(StyleContext &sc, const Sci_Position length, const int varState) {\n\tconst int state = sc.state;\n\tfor (Sci_Position pos = 0; pos < length; pos++) {\n\t\tif (sc.state == varState && !IsWordChar(sc.ch)) {\n\t\t\tsc.SetState(state);\n\t\t} else if (sc.chPrev != '\\\\'\n\t\t\t\t&& (sc.ch == '$' || sc.ch == '@')\n\t\t\t\t&& IsWordStartChar(sc.chNext)) {\n\t\t\tsc.SetState(varState);\n\t\t}\n\t\tsc.Forward(); // Next character\n\t}\n}\n/*\n * LexerRaku::ProcessValidRegQlangStart\n * - processes a section of the document range from after a Regex / Q delimiter\n * - returns true on success\n *   - sets: adverbs, chOpen, chClose, chCount\n *  ref: https://docs.raku.org/language/regexes\n */\nbool LexerRaku::ProcessValidRegQlangStart(StyleContext &sc, Sci_Position length, const int type,\n\t\tWordList &wordsAdverbs, DelimPair &dp) {\n\tSci_Position startPos = sc.currentPos;\n\tSci_Position startLen = length;\n\tconst int target_state = sc.state;\n\tint state = SCE_RAKU_DEFAULT;\n\tstd::string str;\n\n\t// find our opening delimiter (and occurrences) / save any adverbs\n\tdp.opener = 0;\t\t\t\t\t// adverbs can be after the first delimiter\n\tbool got_all_adverbs = false;\t// in Regex statements\n\tbool got_ident = false;\t\t\t// regex can have an identifier: 'regex R'\n\tsc.SetState(state);\t\t\t\t// set state default to avoid pre-highlights\n\twhile ((dp.opener == 0 || !got_all_adverbs) && sc.More()) {\n\n\t\t// move to the next non-space character\n\t\tconst bool was_space = IsAWhitespace(sc.ch);\n\t\tif (!got_all_adverbs && was_space) {\n\t\t\tsc.Forward(LengthToNextChar(sc, length));\n\t\t}\n\t\tlength = startLen - (sc.currentPos - startPos); // update length remaining\n\n\t\t// parse / eat an identifier (if type == RAKUTYPE_REGEX)\n\t\tif (dp.opener == 0 && !got_ident && type == RAKUTYPE_REGEX && IsAlphabet(sc.ch)) {\n\n\t\t\t// eat identifier / account for special adverb :sym<name>\n\t\t\tbool got_sym = false;\n\t\t\twhile (sc.More()) {\n\t\t\t\tsc.SetState(SCE_RAKU_IDENTIFIER);\n\t\t\t\twhile (sc.More() && (IsAlphaNumeric(sc.chNext)\n\t\t\t\t\t\t|| sc.chNext == '_' || sc.chNext == '-')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.Forward();\n\t\t\t\tif (got_sym && sc.ch == '>') {\n\t\t\t\t\tsc.SetState(SCE_RAKU_OPERATOR);\t// '>'\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tbreak;\n\t\t\t\t} else if (type == RAKUTYPE_REGEX && sc.Match(\":sym<\")) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_ADVERB);\t// ':sym'\n\t\t\t\t\tsc.Forward(4);\n\t\t\t\t\tsc.SetState(SCE_RAKU_OPERATOR);\t// '<'\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tgot_sym = true;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tsc.SetState(state);\n\t\t\tgot_ident = true;\n\t\t}\n\n\t\t// parse / save an adverb: RAKUTYPE_REGEX only has adverbs after delim\n\t\t//                      >= RAKUTYPE_QLANG only has adverbs before delim\n\t\telse if (!got_all_adverbs && sc.ch == ':' && (!(dp.opener == 0 && got_ident)\n\t\t\t\t&& !(dp.opener > 0 && type >= RAKUTYPE_QLANG))) {\n\t\t\tsc.SetState(SCE_RAKU_ADVERB);\n\t\t\twhile (IsAlphaNumeric(sc.chNext) && sc.More()) {\n\t\t\t\tsc.Forward();\n\t\t\t\tstr += sc.ch;\n\t\t\t}\n\t\t\tstr += ' ';\n\t\t\tsc.Forward();\n\t\t\tsc.SetState(state);\n\t\t}\n\n\t\t// find starting delimiter\n\t\telse if (dp.opener == 0 && (was_space || IsValidRegOrQAdjacent(sc.ch))\n\t\t\t\t&& IsValidDelimiter(sc.ch)) {\t// make sure the delimiter is legal (most are)\n\t\t\tsc.SetState((state = target_state));// start state here...\n\t\t\tdp.opener = sc.ch;\t\t\t\t\t// this is our delimiter, get count\n\t\t\tif (type < RAKUTYPE_QLANG)\t\t\t// type is Regex\n\t\t\t\tdp.count = 1;\t\t\t\t\t// has only one delimiter\n\t\t\telse\n\t\t\t\tdp.count = GetRepeatCharCount(sc, dp.opener, length);\n\t\t\tsc.Forward(dp.count);\n\t\t}\n\n\t\t// we must have all the adverbs by now...\n\t\telse {\n\t\t\tif (got_all_adverbs)\n\t\t\t\tbreak; // prevent infinite loop: occurs on missing open char\n\t\t\tgot_all_adverbs = true;\n\t\t}\n\t}\n\n\t// set word list / find a valid closing delimiter (or bomb!)\n\twordsAdverbs.Set(str.c_str());\n\tdp.closer[0] = GetDelimiterCloseChar(dp.opener);\n\tdp.closer[1] = 0; // no other closer char\n\treturn dp.closer[0] > 0;\n}\n\n/*\n * LexerRaku::LengthToNonWordChar\n * - returns the length until the next non \"word\" character: AlphaNum + '_'\n *   - also sets all the parsed chars in 's'\n */\nSci_Position LexerRaku::LengthToNonWordChar(StyleContext &sc, Sci_Position length,\n\t\tchar *s, const int size, Sci_Position offset) {\n\tSci_Position len = 0;\n\tSci_Position max_length = size < length ? size : length;\n\twhile (len <= max_length) {\n\t\tconst int ch = sc.GetRelativeCharacter(len + offset);\n\t\tif (!IsWordChar(ch)) {\n\t\t\ts[len] = '\\0';\n\t\t\tbreak;\n\t\t}\n\t\ts[len] = ch;\n\t\tlen++;\n\t}\n\ts[len + 1] = '\\0';\n\treturn len;\n}\n\n/*\n * LexerRaku::Lex\n * - Main lexer method\n */\nvoid SCI_METHOD LexerRaku::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\tDelimPair dpEmbeded;\t\t\t// delimiter pair: embedded comments\n\tDelimPair dpString;\t\t\t\t// delimiter pair: string\n\tDelimPair dpRegQ;\t\t\t\t// delimiter pair: Regex / Q Lang\n\tstd::string hereDelim;\t\t\t// heredoc delimiter (if in heredoc)\n\tint hereState = 0;\t\t\t\t// heredoc state to use (Q / QQ)\n\tint numState = 0;\t\t\t\t// number state / type\n\tshort cntDecimal = 0;\t\t\t// number decimal count\n\tstd::string wordLast;\t\t\t// last word seen\n\tstd::string identLast;\t\t\t// last identifier seen\n\tstd::string adverbLast;\t\t\t// last (single) adverb seen\n\tWordList lastAdverbs;\t\t\t// last adverbs seen\n\tSci_Position len;\t\t\t\t// temp length value\n\tchar s[100];\t\t\t\t\t// temp char string\n\tint typeDetect = -1;\t\t\t// temp type detected (for regex and Q lang)\n\tSci_Position lengthToEnd;\t\t// length until the end of range\n\n\t// Backtrack to safe start position before complex quoted elements\n\n\tSci_PositionU newStartPos = startPos;\n\tif (initStyle != SCE_RAKU_DEFAULT) {\n\t\t// Backtrack to last SCE_RAKU_DEFAULT or 0\n\t\twhile (newStartPos > 0) {\n\t\t\tnewStartPos--;\n\t\t\tif (styler.StyleAt(newStartPos) == SCE_RAKU_DEFAULT)\n\t\t\t\tbreak;\n\t\t}\n\t\t// Backtrack to start of line before SCE_RAKU_HEREDOC_Q?\n\t\tif (initStyle == SCE_RAKU_HEREDOC_Q || initStyle == SCE_RAKU_HEREDOC_QQ) {\n\t\t\tif (newStartPos > 0) {\n\t\t\t\tnewStartPos = styler.LineStart(styler.GetLine(newStartPos));\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconst Sci_Position line = styler.GetLine(newStartPos);\n\t\tif (line > 0) {\n\t\t\t// If the previous line is a start of a q or qq heredoc, backtrack to start of line\n\t\t\tconst Sci_Position startPreviousLine = styler.LineStart(line-1);\n\t\t\tif (ContainsQTo(startPreviousLine, newStartPos, styler)) {\n\t\t\t\tnewStartPos = startPreviousLine;\n\t\t\t}\n\t\t}\n\t}\n\n\n\t// Re-calculate (any) changed startPos, length and initStyle state\n\tif (newStartPos < startPos) {\n\t\tinitStyle = SCE_RAKU_DEFAULT;\n\t\tlength += startPos - newStartPos;\n\t\tstartPos = newStartPos;\n\t}\n\n\t// init StyleContext\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\t// StyleContext Loop\n\tfor (; sc.More(); sc.Forward()) {\n\t\tlengthToEnd = (length - (sc.currentPos - startPos)); // end of range\n\n\t\t/* *** Determine if the current state should terminate ************** *\n\t\t * Everything within the 'switch' statement processes characters up\n\t\t * until the end of a syntax highlight section / state.\n\t\t * ****************************************************************** */\n\t\tswitch (sc.state) {\n\t\t\tcase SCE_RAKU_OPERATOR:\n\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\tbreak; // FIXME: better valid operator sequences needed?\n\t\t\tcase SCE_RAKU_COMMENTLINE:\n\t\t\t\tif (IsANewLine(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_RAKU_COMMENTEMBED:\n\t\t\t\tif ((len = LengthToDelimiter(sc, dpEmbeded, lengthToEnd)) >= 0) {\n\t\t\t\t\tsc.Forward(len);\t\t\t// Move to end delimiter\n\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tsc.Forward(lengthToEnd);\t// no end delimiter found\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_RAKU_POD:\n\t\t\t\tif (sc.atLineStart && sc.Match(\"=end pod\")) {\n\t\t\t\t\tsc.Forward(8);\n\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_RAKU_STRING:\n\n\t\t\t\t// Process the string for variables: move to end delimiter\n\t\t\t\tif ((len = LengthToDelimiter(sc, dpString, lengthToEnd)) >= 0) {\n\t\t\t\t\tif (dpString.interpol) {\n\t\t\t\t\t\tProcessStringVars(sc, len, SCE_RAKU_STRING_VAR);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.Forward(len);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tsc.Forward(lengthToEnd);\t// no end delimiter found\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_RAKU_STRING_Q:\n\t\t\tcase SCE_RAKU_STRING_QQ:\n\t\t\tcase SCE_RAKU_STRING_Q_LANG:\n\n\t\t\t\t// No string: previous char was the delimiter\n\t\t\t\tif (dpRegQ.count == 1 && dpRegQ.isCloser(sc.chPrev)) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t}\n\n\t\t\t\t// Process the string for variables: move to end delimiter\n\t\t\t\telse if ((len = LengthToDelimiter(sc, dpRegQ, lengthToEnd)) >= 0) {\n\n\t\t\t\t\t// set (any) heredoc delimiter string\n\t\t\t\t\tif (lastAdverbs.InList(\"to\")) {\n\t\t\t\t\t\tGetRelativeString(sc, -1, len - dpRegQ.count, hereDelim);\n\t\t\t\t\t\thereState = SCE_RAKU_HEREDOC_Q; // default heredoc state\n\t\t\t\t\t}\n\n\t\t\t\t\t// select variable identifiers\n\t\t\t\t\tif (sc.state == SCE_RAKU_STRING_QQ || lastAdverbs.InList(\"qq\")) {\n\t\t\t\t\t\tProcessStringVars(sc, len, SCE_RAKU_STRING_VAR);\n\t\t\t\t\t\thereState = SCE_RAKU_HEREDOC_QQ; // potential heredoc state\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.Forward(len);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tsc.Forward(lengthToEnd);\t// no end delimiter found\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_RAKU_HEREDOC_Q:\n\t\t\tcase SCE_RAKU_HEREDOC_QQ:\n\t\t\t\tif ((len = LengthToEndHeredoc(sc, styler, lengthToEnd, hereDelim.c_str())) >= 0) {\n\t\t\t\t\t// select variable identifiers\n\t\t\t\t\tif (sc.state == SCE_RAKU_HEREDOC_QQ) {\n\t\t\t\t\t\tProcessStringVars(sc, len, SCE_RAKU_STRING_VAR);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.Forward(len);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t} else {\n\t\t\t\t\tsc.Forward(lengthToEnd);\t// no end delimiter found\n\t\t\t\t}\n\t\t\t\thereDelim.clear();\t\t\t\t// clear heredoc delimiter\n\t\t\t\tbreak;\n\t\t\tcase SCE_RAKU_REGEX:\n\t\t\t\t// account for typeDetect = RAKUTYPE_REGEX_S/TR/Y\n\t\t\t\twhile (sc.state == SCE_RAKU_REGEX) {\n\n\t\t\t\t\t// No string: previous char was the delimiter\n\t\t\t\t\tif (dpRegQ.count == 1 && dpRegQ.isCloser(sc.chPrev)) {\n\t\t\t\t\t\tif (ProcessRegexTwinCapture(sc, lengthToEnd, typeDetect, dpRegQ))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Process the string for variables: move to end delimiter\n\t\t\t\t\telse if ((len = LengthToDelimiter(sc, dpRegQ, lengthToEnd)) >= 0) {\n\t\t\t\t\t\tProcessStringVars(sc, len, SCE_RAKU_REGEX_VAR);\n\t\t\t\t\t\tif (ProcessRegexTwinCapture(sc, lengthToEnd, typeDetect, dpRegQ))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.Forward(lengthToEnd); // no end delimiter found\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_RAKU_NUMBER:\n\t\t\t\tif (sc.ch == '.') {\n\t\t\t\t\tif (sc.chNext == '.') {\t\t// '..' is an operator\n\t\t\t\t\t\tsc.SetState(SCE_RAKU_OPERATOR);\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\tif (sc.chNext == '.')\t// '...' is also an operator\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (numState > RAKUNUM_FLOAT_EXP\n\t\t\t\t\t\t\t&& (cntDecimal < 1 || numState == RAKUNUM_VERSION)) {\n\t\t\t\t\t\tcntDecimal++;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t\t\tbreak; // too many decimal places\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tswitch (numState) {\n\t\t\t\t\tcase RAKUNUM_BINARY:\n\t\t\t\t\t\tif (!IsNumberChar(sc.ch, 2))\n\t\t\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase RAKUNUM_OCTAL:\n\t\t\t\t\t\tif (!IsNumberChar(sc.ch, 8))\n\t\t\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase RAKUNUM_HEX:\n\t\t\t\t\t\tif (!IsNumberChar(sc.ch, 16))\n\t\t\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase RAKUNUM_DECIMAL:\n\t\t\t\t\tcase RAKUNUM_VERSION:\n\t\t\t\t\t\tif (!IsNumberChar(sc.ch))\n\t\t\t\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_RAKU_WORD:\n\t\t\tcase SCE_RAKU_FUNCTION:\n\t\t\tcase SCE_RAKU_TYPEDEF:\n\t\t\tcase SCE_RAKU_ADVERB:\n\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_RAKU_MU:\n\t\t\tcase SCE_RAKU_POSITIONAL:\n\t\t\tcase SCE_RAKU_ASSOCIATIVE:\n\t\t\tcase SCE_RAKU_CALLABLE:\n\t\t\tcase SCE_RAKU_IDENTIFIER:\n\t\t\tcase SCE_RAKU_GRAMMAR:\n\t\t\tcase SCE_RAKU_CLASS:\n\t\t\t\tsc.SetState(SCE_RAKU_DEFAULT);\n\t\t\t\tbreak;\n\t\t}\n\n\t\t/* *** Determine if a new state should be entered ******************* *\n\t\t * Everything below here identifies the beginning of a state, all or part\n\t\t * of the characters within this state are processed here, the rest are\n\t\t * completed above in the terminate state section.\n\t\t * ****************************************************************** */\n\t\tif (sc.state == SCE_RAKU_DEFAULT) {\n\n\t\t\t// --- Single line comment\n\t\t\tif (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_RAKU_COMMENTLINE);\n\t\t\t}\n\n\t\t\t// --- POD block\n\t\t\telse if (sc.atLineStart && sc.Match(\"=begin pod\")) {\n\t\t\t\tsc.SetState(SCE_RAKU_POD);\n\t\t\t\tsc.Forward(10);\n\t\t\t}\n\n\t\t\t// --- String (normal)\n\t\t\telse if (sc.chPrev != '\\\\' && (IsValidQuoteOpener(sc.ch, dpString, RAKUDELIM_QUOTE))) {\n\t\t\t\tsc.SetState(SCE_RAKU_STRING);\n\t\t\t}\n\n\t\t\t// --- String (Q Language) ----------------------------------------\n\t\t\t//   - https://docs.raku.org/language/quoting\n\t\t\t//   - Q :adverb :adverb //;\n\t\t\t//   - q,qx,qw,qq,qqx,qqw,qqww :adverb :adverb //;\n\t\t\telse if (IsQLangStartAtScPos(sc, typeDetect, lengthToEnd)) {\n\t\t\t\tint state = SCE_RAKU_STRING_Q_LANG;\n\t\t\t\tSci_Position forward = 1;\t// single char ident (default)\n\t\t\t\tif (typeDetect > RAKUTYPE_QLANG) {\n\t\t\t\t\tstate = SCE_RAKU_STRING_Q;\n\t\t\t\t\tif (typeDetect == RAKUTYPE_STR_WQ)\n\t\t\t\t\t\tforward = 0;\t\t// no char ident\n\t\t\t\t}\n\t\t\t\tif (typeDetect > RAKUTYPE_STR_Q) {\n\t\t\t\t\tif (typeDetect == RAKUTYPE_STR_QQ)\n\t\t\t\t\t\tstate = SCE_RAKU_STRING_QQ;\n\t\t\t\t\tforward++;\t\t\t\t// two char ident\n\t\t\t\t}\n\t\t\t\tif (typeDetect > RAKUTYPE_STR_QQ)\n\t\t\t\t\tforward++;\t\t\t\t// three char ident\n\t\t\t\tif (typeDetect == RAKUTYPE_STR_QQWW)\n\t\t\t\t\tforward++;\t\t\t\t// four char ident\n\n\t\t\t\t// Proceed: check for a valid character after statement\n\t\t\t\tif (IsValidRegOrQAdjacent(sc.GetRelative(forward)) || typeDetect == RAKUTYPE_QLANG) {\n\t\t\t\t\tsc.SetState(state);\n\t\t\t\t\tsc.Forward(forward);\n\t\t\t\t\tlastAdverbs.Clear();\n\n\t\t\t\t\t// Process: adverbs / opening delimiter / adverbs after delim\n\t\t\t\t\tif (ProcessValidRegQlangStart(sc, lengthToEnd, typeDetect,\n\t\t\t\t\t\t\tlastAdverbs, dpRegQ))\n\t\t\t\t\t\tsc.SetState(state);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// --- Regex (rx/s/m/tr/y) ----------------------------------------\n\t\t\t//   - https://docs.raku.org/language/regexes\n\t\t\telse if ((IsRegexStartAtScPos(sc, typeDetect, setOperator) || regexIdent.InList(wordLast.c_str()))) {\n\t\t\t\tif (typeDetect == -1) { // must be a regex identifier word\n\t\t\t\t\twordLast.clear();\n\t\t\t\t\ttypeDetect = RAKUTYPE_REGEX;\n\t\t\t\t}\n\t\t\t\tSci_Position forward = 0;\t// no ident (RAKUTYPE_REGEX, RAKUTYPE_REGEX_NORM)\n\t\t\t\tif (typeDetect > 0 && typeDetect != RAKUTYPE_REGEX)\n\t\t\t\t\tforward++;\t\t\t\t// single char ident\n\t\t\t\tif (typeDetect > RAKUTYPE_REGEX)\n\t\t\t\t\tforward++;\t\t\t\t// two char ident\n\n\t\t\t\t// Proceed: check for a valid character after statement\n\t\t\t\tif (IsValidRegOrQAdjacent(sc.GetRelative(forward)) || typeDetect == RAKUTYPE_REGEX_NORM) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_REGEX);\n\t\t\t\t\tsc.Forward(forward);\n\t\t\t\t\tlastAdverbs.Clear();\n\n\t\t\t\t\t// Process: adverbs / opening delimiter / adverbs after delim\n\t\t\t\t\tif (ProcessValidRegQlangStart(sc, lengthToEnd, typeDetect,\n\t\t\t\t\t\t\tlastAdverbs, dpRegQ))\n\t\t\t\t\t\tsc.SetState(SCE_RAKU_REGEX);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// --- Numbers ----------------------------------------------------\n\t\t\telse if (IsValidIdentPrecede(sc.chPrev) && (IsNumberChar(sc.ch)\n\t\t\t\t\t|| (sc.ch == 'v' && IsNumberChar(sc.chNext) && wordLast == \"use\"))) {\n\t\t\t\tnumState = RAKUNUM_DECIMAL;\t// default: decimal (base 10)\n\t\t\t\tcntDecimal = 0;\n\t\t\t\tsc.SetState(SCE_RAKU_NUMBER);\n\t\t\t\tif (sc.ch == 'v')\t\t\t// forward past 'v'\n\t\t\t\t\tsc.Forward();\n\t\t\t\tif (wordLast == \"use\") {\t// package version number\n\t\t\t\t\tnumState = RAKUNUM_VERSION;\n\t\t\t\t} else if (sc.ch == '0') {\t// other type of number\n\t\t\t\t\tswitch (sc.chNext) {\n\t\t\t\t\t\tcase 'b':\t// binary (base 2)\n\t\t\t\t\t\t\tnumState = RAKUNUM_BINARY;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'o':\t// octal (base 8)\n\t\t\t\t\t\t\tnumState = RAKUNUM_OCTAL;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'x':\t// hexadecimal (base 16)\n\t\t\t\t\t\t\tnumState = RAKUNUM_HEX;\n\t\t\t\t\t}\n\t\t\t\t\tif (numState != RAKUNUM_DECIMAL)\n\t\t\t\t\t\tsc.Forward();\t\t// forward to number type char\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// --- Keywords / functions / types / barewords -------------------\n\t\t\telse if ((sc.currentPos == 0 || sc.atLineStart || IsValidIdentPrecede(sc.chPrev))\n\t\t\t\t\t&& IsWordStartChar(sc.ch)) {\n\t\t\t\tlen = LengthToNonWordChar(sc, lengthToEnd, s, sizeof(s));\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_WORD);\t\t// Keywords\n\t\t\t\t} else if(functions.InList(s)) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_FUNCTION);\t// Functions\n\t\t\t\t} else if(typesBasic.InList(s)) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_TYPEDEF);\t// Types (basic)\n\t\t\t\t} else if(typesComposite.InList(s)) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_TYPEDEF);\t// Types (composite)\n\t\t\t\t} else if(typesDomainSpecific.InList(s)) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_TYPEDEF);\t// Types (domain-specific)\n\t\t\t\t} else if(typesExceptions.InList(s)) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_TYPEDEF);\t// Types (exceptions)\n\t\t\t\t} else {\n\t\t\t\t\tif (wordLast == \"class\")\n\t\t\t\t\t\tsc.SetState(SCE_RAKU_CLASS);\t// a Class ident\n\t\t\t\t\telse if (wordLast == \"grammar\")\n\t\t\t\t\t\tsc.SetState(SCE_RAKU_GRAMMAR);\t// a Grammar ident\n\t\t\t\t\telse\n\t\t\t\t\t\tsc.SetState(SCE_RAKU_IDENTIFIER);\t// Bareword\n\t\t\t\t\tidentLast = s;\t\t\t\t\t\t// save identifier\n\t\t\t\t}\n\t\t\t\tif (adverbLast == \"sym\") {\t\t\t\t// special adverb \":sym\"\n\t\t\t\t\tsc.SetState(SCE_RAKU_IDENTIFIER);\t// treat as identifier\n\t\t\t\t\tidentLast = s;\t\t\t\t\t\t// save identifier\n\t\t\t\t}\n\t\t\t\tif (sc.state != SCE_RAKU_IDENTIFIER)\n\t\t\t\t\twordLast = s;\t\t\t\t\t// save word\n\t\t\t\tsc.Forward(len - 1);\t\t\t\t// ...forward past word\n\t\t\t}\n\n\t\t\t// --- Adverbs ----------------------------------------------------\n\t\t\telse if (sc.ch == ':' && IsWordStartChar(sc.chNext)) {\n\t\t\t\tlen = LengthToNonWordChar(sc, lengthToEnd, s, sizeof(s), 1);\n\t\t\t\tif (adverbs.InList(s)) {\n\t\t\t\t\tsc.SetState(SCE_RAKU_ADVERB);\t// Adverbs (begin with ':')\n\t\t\t\t\tadverbLast = s;\t\t\t\t\t// save word\n\t\t\t\t\tsc.Forward(len); // ...forward past word (less offset: 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// --- Identifiers: $mu / @positional / %associative / &callable --\n\t\t\t//     see: https://docs.raku.org/language/variables\n\t\t\telse if (setSigil.Contains(sc.ch) && (setTwigil.Contains(sc.chNext)\n\t\t\t\t\t|| setSpecialVar.Contains(sc.chNext)\n\t\t\t\t\t|| IsWordStartChar(sc.chNext))) {\n\n\t\t\t\t// State based on sigil\n\t\t\t\tswitch (sc.ch) {\n\t\t\t\t\tcase '$': sc.SetState(SCE_RAKU_MU);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '@': sc.SetState(SCE_RAKU_POSITIONAL);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '%': sc.SetState(SCE_RAKU_ASSOCIATIVE);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '&': sc.SetState(SCE_RAKU_CALLABLE);\n\t\t\t\t}\n\t\t\t\tconst int state = sc.state;\n\t\t\t\tsc.Forward();\n\t\t\t\tint ch_delim = 0;\n\t\t\t\tif (setSpecialVar.Contains(sc.ch)\n\t\t\t\t\t\t&& !setWord.Contains(sc.chNext)) {\t// Process Special Var\n\t\t\t\t\tch_delim = -1;\n\t\t\t\t} else if (setTwigil.Contains(sc.ch)) {\t\t// Process Twigil\n\t\t\t\t\tsc.SetState(SCE_RAKU_OPERATOR);\n\t\t\t\t\tif (sc.ch == '<' && setWord.Contains(sc.chNext))\n\t\t\t\t\t\tch_delim = '>';\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.SetState(state);\n\t\t\t\t}\n\n\t\t\t\t// Process (any) identifier\n\t\t\t\tif (ch_delim >= 0) {\n\t\t\t\t\tsc.Forward(LengthToNonWordChar(sc, lengthToEnd, s, sizeof(s)) - 1);\n\t\t\t\t\tif (ch_delim > 0 && sc.chNext == ch_delim) {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\tsc.SetState(SCE_RAKU_OPERATOR);\n\t\t\t\t\t}\n\t\t\t\t\tidentLast = s;\t// save identifier\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// --- Operators --------------------------------------------------\n\t\t\telse if (IsOperatorChar(sc.ch)) {\n\t\t\t\t// FIXME: better valid operator sequences needed?\n\t\t\t\tsc.SetState(SCE_RAKU_OPERATOR);\n\t\t\t}\n\n\t\t\t// --- Heredoc: begin ---------------------------------------------\n\t\t\telse if (!hereDelim.empty() && sc.atLineEnd) {\n\t\t\t\tif (IsANewLine(sc.ch))\n\t\t\t\t\tsc.Forward(); // skip a possible CRLF situation\n\t\t\t\tsc.SetState(hereState);\n\t\t\t}\n\n\t\t\t// Reset words: on operator semi-colon OR '}' (end of statement)\n\t\t\tif (sc.state == SCE_RAKU_OPERATOR && (sc.ch == ';' || sc.ch == '}')) {\n\t\t\t\twordLast.clear();\n\t\t\t\tidentLast.clear();\n\t\t\t\tadverbLast.clear();\n\t\t\t}\n\t\t}\n\n\t\t/* *** Determine if an \"embedded comment\" is to be entered ********** *\n\t\t * This type of embedded comment section, or multi-line comment comes\n\t\t * after a normal comment has begun... e.g: #`[ ... ]\n\t\t * ****************************************************************** */\n\t\telse if (sc.state == SCE_RAKU_COMMENTLINE && sc.chPrev == '#' && sc.ch == '`') {\n\t\t\tif (IsBracketOpenChar(sc.chNext)) {\n\t\t\t\tsc.Forward(); // Condition met for \"embedded comment\"\n\t\t\t\tdpEmbeded.opener = sc.ch;\n\n\t\t\t\t// Find the opposite (termination) closing bracket (if any)\n\t\t\t\tdpEmbeded.closer[0] = GetBracketCloseChar(dpEmbeded.opener);\n\t\t\t\tif (dpEmbeded.closer[0] > 0) { // Enter \"embedded comment\"\n\n\t\t\t\t\t// Find multiple opening character occurrence\n\t\t\t\t\tdpEmbeded.count = GetRepeatCharCount(sc, dpEmbeded.opener, lengthToEnd);\n\t\t\t\t\tsc.SetState(SCE_RAKU_COMMENTEMBED);\n\t\t\t\t\tsc.Forward(dpEmbeded.count - 1); // incremented in the next loop\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// And we're done...\n\tsc.Complete();\n}\n\n/*\n * LexerRaku::Lex\n * - Main fold method\n *   NOTE: although Raku uses and supports UNICODE characters, we're only looking\n *         at normal chars here, using 'SafeGetCharAt' - for folding purposes\n *         that is all we need.\n */\n#define RAKU_HEADFOLD_SHIFT\t4\n#define RAKU_HEADFOLD_MASK\t0xF0\nvoid SCI_METHOD LexerRaku::Fold(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {\n\n\t// init LexAccessor / return if fold option is off\n\tif (!options.fold) return;\n\tLexAccessor styler(pAccess);\n\n\t// init char and line positions\n\tconst Sci_PositionU endPos = startPos + length;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\n\t// Backtrack to last SCE_RAKU_DEFAULT line\n\tif (startPos > 0 && lineCurrent > 0) {\n\t\twhile (lineCurrent > 0 && styler.StyleAt(startPos) != SCE_RAKU_DEFAULT) {\n\t\t\tlineCurrent--;\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t\t}\n\t\tlineCurrent = styler.GetLine(startPos);\n\t}\n\tSci_PositionU lineStart = startPos;\n\tSci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1);\n\n\t// init line folding level\n\tint levelPrev = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelPrev = styler.LevelAt(lineCurrent - 1) >> 16;\n\tint levelCurrent = levelPrev;\n\n\t// init char and style variables\n\tchar chNext = styler[startPos];\n\tint stylePrev = startPos > 0 ? styler.StyleAt(startPos - 1) : 0;\n\tint styleNext = styler.StyleAt(startPos);\n\tint styleNextStartLine = styler.StyleAt(lineStartNext);\n\tint visibleChars = 0;\n\tbool wasCommentMulti = false;\n\n\t// main loop\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\n\t\t// next char, style and flags\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tconst bool atEOL = i == (lineStartNext - 1);\n\t\tconst bool atLineStart = i == lineStart;\n\n\t\t// --- Comments / Multi-line / POD ------------------------------------\n\t\tif (options.foldComment) {\n\n\t\t\t// Multi-line\n\t\t\tif (options.foldCommentMultiline) {\n\t\t\t\tif (style == SCE_RAKU_COMMENTLINE && atLineStart && ch == '#' && chNext == '`'\n\t\t\t\t\t\t&& styleNextStartLine == SCE_RAKU_COMMENTEMBED) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\twasCommentMulti = true; // don't confuse line comments\n\t\t\t\t} else if (style == SCE_RAKU_COMMENTEMBED && atLineStart\n\t\t\t\t\t\t&& styleNextStartLine != SCE_RAKU_COMMENTEMBED) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Line comments\n\t\t\tif (!wasCommentMulti && atEOL && stylePrev == SCE_RAKU_COMMENTLINE\n\t\t\t\t\t&& IsCommentLine(lineCurrent, styler)) {\n\t\t\t\tif (!IsCommentLine(lineCurrent - 1, styler)\n\t\t\t\t\t\t&& IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\telse if (IsCommentLine(lineCurrent - 1, styler)\n\t\t\t\t\t\t&& !IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\t\tlevelCurrent--;\n\t\t\t}\n\n\t\t\t// POD\n\t\t\tif (options.foldCommentPOD && atLineStart && style == SCE_RAKU_POD) {\n\t\t\t\tif (styler.Match(i, \"=begin\"))\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\telse if (styler.Match(i, \"=end\"))\n\t\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\t// --- Code block -----------------------------------------------------\n\t\tif (style == SCE_RAKU_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\tif (levelCurrent < levelPrev) levelPrev--;\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\t// --- at end of line / range / apply fold ----------------------------\n\t\tif (atEOL) {\n\t\t\tint level = levelPrev;\n\n\t\t\t// set level flags\n\t\t\tlevel |= levelCurrent << 16;\n\t\t\tif (visibleChars == 0 && options.foldCompact)\n\t\t\t\tlevel |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (level != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, level);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlineStart = lineStartNext;\n\t\t\tlineStartNext = styler.LineStart(lineCurrent + 1);\n\t\t\tstyleNextStartLine = styler.StyleAt(lineStartNext);\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t\twasCommentMulti = false;\n\t\t}\n\n\t\t// increment visibleChars / set previous char\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t\tstylePrev = style;\n\t}\n\n\t// Done: set real level of the next line\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\n/*----------------------------------------------------------------------------*\n * --- Scintilla: LexerModule ---\n *----------------------------------------------------------------------------*/\n\nextern const LexerModule lmRaku(SCLEX_RAKU, LexerRaku::LexerFactoryRaku, \"raku\", rakuWordLists);\n"
  },
  {
    "path": "lexers/LexRebol.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexRebol.cxx\n ** Lexer for REBOL.\n ** Written by Pascal Hurni, inspired from LexLua by Paul Winwood & Marcos E. Wurzius & Philippe Lhoste\n **\n ** History:\n **\t\t2005-04-07\tFirst release.\n **\t\t2005-04-10\tClosing parens and brackets go now in default style\n **\t\t\t\t\tString and comment nesting should be more safe\n **/\n// Copyright 2005 by Pascal Hurni <pascal_hurni@fastmail.fm>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (isalnum(ch) || ch == '?' || ch == '!' || ch == '.' || ch == '\\'' || ch == '+' || ch == '-' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');\n}\n\nstatic inline bool IsAWordStart(const int ch, const int ch2) {\n\treturn ((ch == '+' || ch == '-' || ch == '.') && !isdigit(ch2)) ||\n\t\t(isalpha(ch) || ch == '?' || ch == '!' || ch == '\\'' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');\n}\n\nstatic inline bool IsAnOperator(const int ch, const int ch2, const int ch3) {\n\t// One char operators\n\tif (IsASpaceOrTab(ch2)) {\n\t\treturn ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '<' || ch == '>' || ch == '=' || ch == '?';\n\t}\n\n\t// Two char operators\n\tif (IsASpaceOrTab(ch3)) {\n\t\treturn (ch == '*' && ch2 == '*') ||\n\t\t\t   (ch == '/' && ch2 == '/') ||\n\t\t\t   (ch == '<' && (ch2 == '=' || ch2 == '>')) ||\n\t\t\t   (ch == '>' && ch2 == '=') ||\n\t\t\t   (ch == '=' && (ch2 == '=' || ch2 == '?')) ||\n\t\t\t   (ch == '?' && ch2 == '?');\n\t}\n\n\treturn false;\n}\n\nstatic inline bool IsBinaryStart(const int ch, const int ch2, const int ch3, const int ch4) {\n\treturn (ch == '#' && ch2 == '{') ||\n\t\t   (IsADigit(ch) && ch2 == '#' && ch3 == '{' ) ||\n\t\t   (IsADigit(ch) && IsADigit(ch2) && ch3 == '#' && ch4 == '{' );\n}\n\n\nstatic void ColouriseRebolDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\tWordList &keywords4 = *keywordlists[3];\n\tWordList &keywords5 = *keywordlists[4];\n\tWordList &keywords6 = *keywordlists[5];\n\tWordList &keywords7 = *keywordlists[6];\n\tWordList &keywords8 = *keywordlists[7];\n\n\tSci_Position currentLine = styler.GetLine(startPos);\n\t// Initialize the braced string {.. { ... } ..} nesting level, if we are inside such a string.\n\tint stringLevel = 0;\n\tif (initStyle == SCE_REBOL_BRACEDSTRING || initStyle == SCE_REBOL_COMMENTBLOCK) {\n\t\tstringLevel = styler.GetLineState(currentLine - 1);\n\t}\n\n\tbool blockComment = initStyle == SCE_REBOL_COMMENTBLOCK;\n\tint dotCount = 0;\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_REBOL_COMMENTLINE) {\n\t\tinitStyle = SCE_REBOL_DEFAULT;\n\t}\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tif (startPos == 0) {\n\t\tsc.SetState(SCE_REBOL_PREFACE);\n\t}\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\t//--- What to do at line end ?\n\t\tif (sc.atLineEnd) {\n\t\t\t// Can be either inside a {} string or simply at eol\n\t\t\tif (sc.state != SCE_REBOL_BRACEDSTRING && sc.state != SCE_REBOL_COMMENTBLOCK &&\n\t\t\t\tsc.state != SCE_REBOL_BINARY && sc.state != SCE_REBOL_PREFACE)\n\t\t\t\tsc.SetState(SCE_REBOL_DEFAULT);\n\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tcurrentLine = styler.GetLine(sc.currentPos);\n\t\t\tswitch (sc.state) {\n\t\t\tcase SCE_REBOL_BRACEDSTRING:\n\t\t\tcase SCE_REBOL_COMMENTBLOCK:\n\t\t\t\t// Inside a braced string, we set the line state\n\t\t\t\tstyler.SetLineState(currentLine, stringLevel);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Reset the line state\n\t\t\t\tstyler.SetLineState(currentLine, 0);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// continue with next char\n\t\t\tcontinue;\n\t\t}\n\n\t\t//--- What to do on white-space ?\n\t\tif (IsASpaceOrTab(sc.ch))\n\t\t{\n\t\t\t// Return to default if any of these states\n\t\t\tif (sc.state == SCE_REBOL_OPERATOR || sc.state == SCE_REBOL_CHARACTER ||\n\t\t\t\tsc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR ||\n\t\t\t\tsc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_FILE ||\n\t\t\t\tsc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME ||\n\t\t\t\tsc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE ||\n\t\t\t\tsc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_EMAIL) {\n\t\t\t\tsc.SetState(SCE_REBOL_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t//--- Specialize state ?\n\t\t// URL, Email look like identifier\n\t\tif (sc.state == SCE_REBOL_IDENTIFIER)\n\t\t{\n\t\t\tif (sc.ch == ':' && !IsASpace(sc.chNext)) {\n\t\t\t\tsc.ChangeState(SCE_REBOL_URL);\n\t\t\t} else if (sc.ch == '@') {\n\t\t\t\tsc.ChangeState(SCE_REBOL_EMAIL);\n\t\t\t} else if (sc.ch == '$') {\n\t\t\t\tsc.ChangeState(SCE_REBOL_MONEY);\n\t\t\t}\n\t\t}\n\t\t// Words look like identifiers\n\t\tif (sc.state == SCE_REBOL_IDENTIFIER || (sc.state >= SCE_REBOL_WORD && sc.state <= SCE_REBOL_WORD8)) {\n\t\t\t// Keywords ?\n\t\t\tif (!IsAWordChar(sc.ch) || sc.Match('/')) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tblockComment = strcmp(s, \"comment\") == 0;\n\t\t\t\tif (keywords8.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_REBOL_WORD8);\n\t\t\t\t} else if (keywords7.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_REBOL_WORD7);\n\t\t\t\t} else if (keywords6.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_REBOL_WORD6);\n\t\t\t\t} else if (keywords5.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_REBOL_WORD5);\n\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_REBOL_WORD4);\n\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_REBOL_WORD3);\n\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_REBOL_WORD2);\n\t\t\t\t} else if (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_REBOL_WORD);\n\t\t\t\t}\n\t\t\t\t// Keep same style if there are refinements\n\t\t\t\tif (!sc.Match('/')) {\n\t\t\t\t\tsc.SetState(SCE_REBOL_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t// special numbers\n\t\t} else if (sc.state == SCE_REBOL_NUMBER) {\n\t\t\tswitch (sc.ch) {\n\t\t\tcase 'x':\tsc.ChangeState(SCE_REBOL_PAIR);\n\t\t\t\t\t\tbreak;\n\t\t\tcase ':':\tsc.ChangeState(SCE_REBOL_TIME);\n\t\t\t\t\t\tbreak;\n\t\t\tcase '-':\n\t\t\tcase '/':\tsc.ChangeState(SCE_REBOL_DATE);\n\t\t\t\t\t\tbreak;\n\t\t\tcase '.':\tif (++dotCount >= 2) sc.ChangeState(SCE_REBOL_TUPLE);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//--- Determine if the current state should terminate\n\t\tif (sc.state == SCE_REBOL_QUOTEDSTRING || sc.state == SCE_REBOL_CHARACTER) {\n\t\t\tif (sc.ch == '^' && sc.chNext == '\\\"') {\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_REBOL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_REBOL_BRACEDSTRING || sc.state == SCE_REBOL_COMMENTBLOCK) {\n\t\t\tif (sc.ch == '}') {\n\t\t\t\tif (--stringLevel == 0) {\n\t\t\t\t\tsc.ForwardSetState(SCE_REBOL_DEFAULT);\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '{') {\n\t\t\t\tstringLevel++;\n\t\t\t}\n\t\t} else if (sc.state == SCE_REBOL_BINARY) {\n\t\t\tif (sc.ch == '}') {\n\t\t\t\tsc.ForwardSetState(SCE_REBOL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_REBOL_TAG) {\n\t\t\tif (sc.ch == '>') {\n\t\t\t\tsc.ForwardSetState(SCE_REBOL_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_REBOL_PREFACE) {\n\t\t\tif (sc.MatchIgnoreCase(\"rebol\"))\n\t\t\t{\n\t\t\t\tint i;\n\t\t\t\tfor (i=5; IsASpaceOrTab(styler.SafeGetCharAt(sc.currentPos+i, 0)); i++);\n\t\t\t\tif (sc.GetRelative(i) == '[')\n\t\t\t\t\tsc.SetState(SCE_REBOL_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t//--- Parens and bracket changes to default style when the current is a number\n\t\tif (sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE ||\n\t\t\tsc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_EMAIL ||\n\t\t\tsc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME) {\n\t\t\tif (sc.ch == '(' || sc.ch == '[' || sc.ch == ')' || sc.ch == ']') {\n\t\t\t\tsc.SetState(SCE_REBOL_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\t//--- Determine if a new state should be entered.\n\t\tif (sc.state == SCE_REBOL_DEFAULT) {\n\t\t\tif (IsAnOperator(sc.ch, sc.chNext, sc.GetRelative(2))) {\n\t\t\t\tsc.SetState(SCE_REBOL_OPERATOR);\n\t\t\t} else if (IsBinaryStart(sc.ch, sc.chNext, sc.GetRelative(2), sc.GetRelative(3))) {\n\t\t\t\tsc.SetState(SCE_REBOL_BINARY);\n\t\t\t} else if (IsAWordStart(sc.ch, sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_REBOL_IDENTIFIER);\n\t\t\t} else if (IsADigit(sc.ch) || sc.ch == '+' || sc.ch == '-' || /*Decimal*/ sc.ch == '.' || sc.ch == ',') {\n\t\t\t\tdotCount = 0;\n\t\t\t\tsc.SetState(SCE_REBOL_NUMBER);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_REBOL_QUOTEDSTRING);\n\t\t\t} else if (sc.ch == '{') {\n\t\t\t\tsc.SetState(blockComment ? SCE_REBOL_COMMENTBLOCK : SCE_REBOL_BRACEDSTRING);\n\t\t\t\t++stringLevel;\n\t\t\t} else if (sc.ch == ';') {\n\t\t\t\tsc.SetState(SCE_REBOL_COMMENTLINE);\n\t\t\t} else if (sc.ch == '$') {\n\t\t\t\tsc.SetState(SCE_REBOL_MONEY);\n\t\t\t} else if (sc.ch == '%') {\n\t\t\t\tsc.SetState(SCE_REBOL_FILE);\n\t\t\t} else if (sc.ch == '<') {\n\t\t\t\tsc.SetState(SCE_REBOL_TAG);\n\t\t\t} else if (sc.ch == '#' && sc.chNext == '\"') {\n\t\t\t\tsc.SetState(SCE_REBOL_CHARACTER);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '#' && sc.chNext != '\"' && sc.chNext != '{' ) {\n\t\t\t\tsc.SetState(SCE_REBOL_ISSUE);\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\n\nstatic void FoldRebolDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],\n                            Accessor &styler) {\n\tSci_PositionU lengthDoc = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (style == SCE_REBOL_DEFAULT) {\n\t\t\tif (ch == '[') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == ']') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const rebolWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmREBOL(SCLEX_REBOL, ColouriseRebolDoc, \"rebol\", FoldRebolDoc, rebolWordListDesc);\n\n"
  },
  {
    "path": "lexers/LexRegistry.cxx",
    "content": "// Scintilla source code edit control\n/**\n * @file LexRegistry.cxx\n * @date July 26 2014\n * @brief Lexer for Windows registration files(.reg)\n * @author nkmathew\n *\n * The License.txt file describes the conditions under which this software may be\n * distributed.\n *\n */\n\n#include <cstdlib>\n#include <cassert>\n#include <cctype>\n#include <cstdio>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nstatic const char *const RegistryWordListDesc[] = {\n\t0\n};\n\nstruct OptionsRegistry {\n\tbool foldCompact = false;\n\tbool fold = false;\n};\n\nstruct OptionSetRegistry : public OptionSet<OptionsRegistry> {\n\tOptionSetRegistry() {\n\t\tDefineProperty(\"fold.compact\", &OptionsRegistry::foldCompact);\n\t\tDefineProperty(\"fold\", &OptionsRegistry::fold);\n\t\tDefineWordListSets(RegistryWordListDesc);\n\t}\n};\n\nclass LexerRegistry : public DefaultLexer {\n\tOptionsRegistry options;\n\tOptionSetRegistry optSetRegistry;\n\n\tstatic bool IsStringState(int state) {\n\t\treturn (state == SCE_REG_VALUENAME || state == SCE_REG_STRING);\n\t}\n\n\tstatic bool IsKeyPathState(int state) {\n\t\treturn (state == SCE_REG_ADDEDKEY || state == SCE_REG_DELETEDKEY);\n\t}\n\n\tstatic bool AtValueType(LexAccessor &styler, Sci_Position start) {\n\t\tSci_Position i = 0;\n\t\twhile (i < 10) {\n\t\t\ti++;\n\t\t\tchar curr = styler.SafeGetCharAt(start+i, '\\0');\n\t\t\tif (curr == ':') {\n\t\t\t\treturn true;\n\t\t\t} else if (!curr) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tstatic bool IsNextNonWhitespace(LexAccessor &styler, Sci_Position start, char ch) {\n\t\tSci_Position i = 0;\n\t\twhile (i < 100) {\n\t\t\ti++;\n\t\t\tchar curr = styler.SafeGetCharAt(start+i, '\\0');\n\t\t\tchar next = styler.SafeGetCharAt(start+i+1, '\\0');\n\t\t\tbool atEOL = (curr == '\\r' && next != '\\n') || (curr == '\\n');\n\t\t\tif (curr == ch) {\n\t\t\t\treturn true;\n\t\t\t} else if (!isspacechar(curr) || atEOL) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t// Looks for the equal sign at the end of the string\n\tstatic bool AtValueName(LexAccessor &styler, Sci_Position start) {\n\t\tbool atEOL = false;\n\t\tSci_Position i = 0;\n\t\tbool escaped = false;\n\t\twhile (!atEOL) {\n\t\t\ti++;\n\t\t\tchar curr = styler.SafeGetCharAt(start+i, '\\0');\n\t\t\tchar next = styler.SafeGetCharAt(start+i+1, '\\0');\n\t\t\tatEOL = (curr == '\\r' && next != '\\n') || (curr == '\\n');\n\t\t\tif (escaped) {\n\t\t\t\tescaped = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tescaped = curr == '\\\\';\n\t\t\tif (curr == '\"') {\n\t\t\t\treturn IsNextNonWhitespace(styler, start+i, '=');\n\t\t\t} else if (!curr) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tstatic bool AtKeyPathEnd(LexAccessor &styler, Sci_Position start) {\n\t\tbool atEOL = false;\n\t\tSci_Position i = 0;\n\t\twhile (!atEOL) {\n\t\t\ti++;\n\t\t\tchar curr = styler.SafeGetCharAt(start+i, '\\0');\n\t\t\tchar next = styler.SafeGetCharAt(start+i+1, '\\0');\n\t\t\tatEOL = (curr == '\\r' && next != '\\n') || (curr == '\\n');\n\t\t\tif (curr == ']' || !curr) {\n\t\t\t\t// There's still at least one or more square brackets ahead\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tstatic bool AtGUID(LexAccessor &styler, Sci_Position start) {\n\t\tint count = 8;\n\t\tint portion = 0;\n\t\tint offset = 1;\n\t\tchar digit = '\\0';\n\t\twhile (portion < 5) {\n\t\t\tint i = 0;\n\t\t\twhile (i < count) {\n\t\t\t\tdigit = styler.SafeGetCharAt(start+offset);\n\t\t\t\tif (!(isxdigit(digit) || digit == '-')) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\toffset++;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tportion++;\n\t\t\tcount = (portion == 4) ? 13 : 5;\n\t\t}\n\t\tdigit = styler.SafeGetCharAt(start+offset);\n\t\tif (digit == '}') {\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\npublic:\n\tLexerRegistry() : DefaultLexer(\"registry\", SCLEX_REGISTRY) {}\n\tvirtual ~LexerRegistry() {}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn optSetRegistry.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn optSetRegistry.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn optSetRegistry.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override {\n\t\tif (optSetRegistry.PropertySet(&options, key, val)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn -1;\n\t}\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn optSetRegistry.PropertyGet(key);\n\t}\n\n\tSci_Position SCI_METHOD WordListSet(int, const char *) override {\n\t\treturn -1;\n\t}\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn 0;\n\t}\n\tstatic ILexer5 *LexerFactoryRegistry() {\n\t\treturn new LexerRegistry;\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn optSetRegistry.DescribeWordListSets();\n\t}\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos,\n\t\t\t\t\t\t\t\tSci_Position length,\n\t\t\t\t\t\t\t\tint initStyle,\n\t\t\t\t\t\t\t\tIDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos,\n\t\t\t\t\t\t\t\t Sci_Position length,\n\t\t\t\t\t\t\t\t int initStyle,\n\t\t\t\t\t\t\t\t IDocument *pAccess) override;\n};\n\nvoid SCI_METHOD LexerRegistry::Lex(Sci_PositionU startPos,\n\t\t\t\t\t\t\t\t   Sci_Position length,\n\t\t\t\t\t\t\t\t   int initStyle,\n\t\t\t\t\t\t\t\t   IDocument *pAccess) {\n\tint beforeGUID = SCE_REG_DEFAULT;\n\tint beforeEscape = SCE_REG_DEFAULT;\n\tCharacterSet setOperators = CharacterSet(CharacterSet::setNone, \"-,.=:\\\\@()\");\n\tLexAccessor styler(pAccess);\n\tStyleContext context(startPos, length, initStyle, styler);\n\tbool highlight = true;\n\tbool afterEqualSign = false;\n\twhile (context.More()) {\n\t\tif (context.atLineStart) {\n\t\t\tSci_Position currPos = static_cast<Sci_Position>(context.currentPos);\n\t\t\tbool continued = styler[currPos-3] == '\\\\';\n\t\t\thighlight = continued ? true : false;\n\t\t}\n\t\tswitch (context.state) {\n\t\t\tcase SCE_REG_COMMENT:\n\t\t\t\tif (context.atLineEnd) {\n\t\t\t\t\tcontext.SetState(SCE_REG_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_REG_VALUENAME:\n\t\t\tcase SCE_REG_STRING: {\n\t\t\t\t\tSci_Position currPos = static_cast<Sci_Position>(context.currentPos);\n\t\t\t\t\tif (context.ch == '\"') {\n\t\t\t\t\t\tcontext.ForwardSetState(SCE_REG_DEFAULT);\n\t\t\t\t\t} else if (context.ch == '\\\\') {\n\t\t\t\t\t\tbeforeEscape = context.state;\n\t\t\t\t\t\tcontext.SetState(SCE_REG_ESCAPED);\n\t\t\t\t\t\tcontext.Forward();\n\t\t\t\t\t} else if (context.ch == '{') {\n\t\t\t\t\t\tif (AtGUID(styler, currPos)) {\n\t\t\t\t\t\t\tbeforeGUID = context.state;\n\t\t\t\t\t\t\tcontext.SetState(SCE_REG_STRING_GUID);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (context.state == SCE_REG_STRING &&\n\t\t\t\t\t\tcontext.ch == '%' &&\n\t\t\t\t\t\t(isdigit(context.chNext) || context.chNext == '*')) {\n\t\t\t\t\t\tcontext.SetState(SCE_REG_PARAMETER);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_REG_PARAMETER:\n\t\t\t\tcontext.ForwardSetState(SCE_REG_STRING);\n\t\t\t\tif (context.ch == '\"') {\n\t\t\t\t\tcontext.ForwardSetState(SCE_REG_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_REG_VALUETYPE:\n\t\t\t\tif (context.ch == ':') {\n\t\t\t\t\tcontext.SetState(SCE_REG_DEFAULT);\n\t\t\t\t\tafterEqualSign = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_REG_HEXDIGIT:\n\t\t\tcase SCE_REG_OPERATOR:\n\t\t\t\tcontext.SetState(SCE_REG_DEFAULT);\n\t\t\t\tbreak;\n\t\t\tcase SCE_REG_DELETEDKEY:\n\t\t\tcase SCE_REG_ADDEDKEY: {\n\t\t\t\t\tSci_Position currPos = static_cast<Sci_Position>(context.currentPos);\n\t\t\t\t\tif (context.ch == ']' && AtKeyPathEnd(styler, currPos)) {\n\t\t\t\t\t\tcontext.ForwardSetState(SCE_REG_DEFAULT);\n\t\t\t\t\t} else if (context.ch == '{') {\n\t\t\t\t\t\tif (AtGUID(styler, currPos)) {\n\t\t\t\t\t\t\tbeforeGUID = context.state;\n\t\t\t\t\t\t\tcontext.SetState(SCE_REG_KEYPATH_GUID);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_REG_ESCAPED:\n\t\t\t\tif (context.ch == '\"') {\n\t\t\t\t\tcontext.SetState(beforeEscape);\n\t\t\t\t\tcontext.ForwardSetState(SCE_REG_DEFAULT);\n\t\t\t\t} else if (context.ch == '\\\\') {\n\t\t\t\t\tcontext.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tcontext.SetState(beforeEscape);\n\t\t\t\t\tbeforeEscape = SCE_REG_DEFAULT;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_REG_STRING_GUID:\n\t\t\tcase SCE_REG_KEYPATH_GUID: {\n\t\t\t\t\tif (context.ch == '}') {\n\t\t\t\t\t\tcontext.ForwardSetState(beforeGUID);\n\t\t\t\t\t\tbeforeGUID = SCE_REG_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t\tSci_Position currPos = static_cast<Sci_Position>(context.currentPos);\n\t\t\t\t\tif (context.ch == '\"' && IsStringState(context.state)) {\n\t\t\t\t\t\tcontext.ForwardSetState(SCE_REG_DEFAULT);\n\t\t\t\t\t} else if (context.ch == ']' &&\n\t\t\t\t\t\t\t   AtKeyPathEnd(styler, currPos) &&\n\t\t\t\t\t\t\t   IsKeyPathState(context.state)) {\n\t\t\t\t\t\tcontext.ForwardSetState(SCE_REG_DEFAULT);\n\t\t\t\t\t} else if (context.ch == '\\\\' && IsStringState(context.state)) {\n\t\t\t\t\t\tbeforeEscape = context.state;\n\t\t\t\t\t\tcontext.SetState(SCE_REG_ESCAPED);\n\t\t\t\t\t\tcontext.Forward();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\t// Determine if a new state should be entered.\n\t\tif (context.state == SCE_REG_DEFAULT) {\n\t\t\tSci_Position currPos = static_cast<Sci_Position>(context.currentPos);\n\t\t\tif (context.ch == ';') {\n\t\t\t\tcontext.SetState(SCE_REG_COMMENT);\n\t\t\t} else if (context.ch == '\"') {\n\t\t\t\tif (AtValueName(styler, currPos)) {\n\t\t\t\t\tcontext.SetState(SCE_REG_VALUENAME);\n\t\t\t\t} else {\n\t\t\t\t\tcontext.SetState(SCE_REG_STRING);\n\t\t\t\t}\n\t\t\t} else if (context.ch == '[') {\n\t\t\t\tif (IsNextNonWhitespace(styler, currPos, '-')) {\n\t\t\t\t\tcontext.SetState(SCE_REG_DELETEDKEY);\n\t\t\t\t} else {\n\t\t\t\t\tcontext.SetState(SCE_REG_ADDEDKEY);\n\t\t\t\t}\n\t\t\t} else if (context.ch == '=') {\n\t\t\t\tafterEqualSign = true;\n\t\t\t\thighlight = true;\n\t\t\t} else if (afterEqualSign) {\n\t\t\t\tbool wordStart = isalpha(context.ch) && !isalpha(context.chPrev);\n\t\t\t\tif (wordStart && AtValueType(styler, currPos)) {\n\t\t\t\t\tcontext.SetState(SCE_REG_VALUETYPE);\n\t\t\t\t}\n\t\t\t} else if (isxdigit(context.ch) && highlight) {\n\t\t\t\tcontext.SetState(SCE_REG_HEXDIGIT);\n\t\t\t}\n\t\t\thighlight = (context.ch == '@') ? true : highlight;\n\t\t\tif (setOperators.Contains(context.ch) && highlight) {\n\t\t\t\tcontext.SetState(SCE_REG_OPERATOR);\n\t\t\t}\n\t\t}\n\t\tcontext.Forward();\n\t}\n\tcontext.Complete();\n}\n\n// Folding similar to that of FoldPropsDoc in LexOthers\nvoid SCI_METHOD LexerRegistry::Fold(Sci_PositionU startPos,\n\t\t\t\t\t\t\t\t\tSci_Position length,\n\t\t\t\t\t\t\t\t\tint,\n\t\t\t\t\t\t\t\t\tIDocument *pAccess) {\n\tif (!options.fold) {\n\t\treturn;\n\t}\n\tLexAccessor styler(pAccess);\n\tSci_Position currLine = styler.GetLine(startPos);\n\tint visibleChars = 0;\n\tSci_PositionU endPos = startPos + length;\n\tbool atKeyPath = false;\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tatKeyPath = IsKeyPathState(styler.StyleAt(i)) ? true : atKeyPath;\n\t\tchar curr = styler.SafeGetCharAt(i);\n\t\tchar next = styler.SafeGetCharAt(i+1);\n\t\tbool atEOL = (curr == '\\r' && next != '\\n') || (curr == '\\n');\n\t\tif (atEOL || i == (endPos-1)) {\n\t\t\tint level = SC_FOLDLEVELBASE;\n\t\t\tif (currLine > 0) {\n\t\t\t\tint prevLevel = styler.LevelAt(currLine-1);\n\t\t\t\tif (prevLevel & SC_FOLDLEVELHEADERFLAG) {\n\t\t\t\t\tlevel += 1;\n\t\t\t\t} else {\n\t\t\t\t\tlevel = prevLevel;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!visibleChars && options.foldCompact) {\n\t\t\t\tlevel |= SC_FOLDLEVELWHITEFLAG;\n\t\t\t} else if (atKeyPath) {\n\t\t\t\tlevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tif (level != styler.LevelAt(currLine)) {\n\t\t\t\tstyler.SetLevel(currLine, level);\n\t\t\t}\n\t\t\tcurrLine++;\n\t\t\tvisibleChars = 0;\n\t\t\tatKeyPath = false;\n\t\t}\n\t\tif (!isspacechar(curr)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\n\t// Make the folding reach the last line in the file\n\tint level = SC_FOLDLEVELBASE;\n\tif (currLine > 0) {\n\t\tint prevLevel = styler.LevelAt(currLine-1);\n\t\tif (prevLevel & SC_FOLDLEVELHEADERFLAG) {\n\t\t\tlevel += 1;\n\t\t} else {\n\t\t\tlevel = prevLevel;\n\t\t}\n\t}\n\tstyler.SetLevel(currLine, level);\n}\n\nextern const LexerModule lmRegistry(SCLEX_REGISTRY,\n\t\t\t\t\t   LexerRegistry::LexerFactoryRegistry,\n\t\t\t\t\t   \"registry\",\n\t\t\t\t\t   RegistryWordListDesc);\n\n"
  },
  {
    "path": "lexers/LexRuby.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexRuby.cxx\n ** Lexer for Ruby.\n **/\n// Copyright 2001- by Clemens Wyss <wys@helbling.ch>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"InList.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"SubStyles.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\n//XXX Identical to Perl, put in common area\nconstexpr bool isEOLChar(char ch) noexcept {\n    return (ch == '\\r') || (ch == '\\n');\n}\n\nconstexpr bool isSafeASCII(char ch) noexcept {\n    return static_cast<unsigned char>(ch) <= 127;\n}\n\n// This one's redundant, but makes for more readable code\nconstexpr bool isHighBitChar(char ch) noexcept {\n    return static_cast<unsigned char>(ch) > 127;\n}\n\nbool isSafeAlpha(char ch) noexcept {\n    return (isSafeASCII(ch) && isalpha(ch)) || ch == '_';\n}\n\nbool isSafeAlphaOrHigh(char ch) noexcept {\n\treturn isHighBitChar(ch) || isalpha(ch) || ch == '_';\n}\n\nbool isSafeAlnum(char ch) noexcept {\n    return (isSafeASCII(ch) && isalnum(ch)) || ch == '_';\n}\n\nbool isSafeAlnumOrHigh(char ch) noexcept {\n    return isHighBitChar(ch) || isalnum(ch) || ch == '_';\n}\n\nbool isSafeDigit(char ch) noexcept {\n    return isSafeASCII(ch) && isdigit(ch);\n}\n\nbool isSafeWordcharOrHigh(char ch) noexcept {\n    // Error: scintilla's KeyWords.h includes '.' as a word-char\n    // we want to separate things that can take methods from the\n    // methods.\n    return isHighBitChar(ch) || isalnum(ch) || ch == '_';\n}\n\nconstexpr bool isWhiteSpace(char ch) noexcept {\n    return ch == ' ' || ch == '\\t' || ch == '\\r' || ch == '\\n';\n}\n\nconstexpr bool isOperatorName(char ch) noexcept {\n    // see operator list at https://docs.ruby-lang.org/en/master/syntax/methods_rdoc.html#method-names\n    return AnyOf(ch, '[', '*', '!', '~', '+', '-', '*', '/', '%', '=', '<', '>', '&', '^', '|');\n}\n\nbool isQuestionMarkChar(char chNext, char chNext2) noexcept {\n    // followed by a single character or escape sequence that corresponds to a single codepoint\n    if (isSafeAlnum(chNext)) {\n        return !isSafeWordcharOrHigh(chNext2);\n    }\n    // multibyte character, escape sequence, punctuation\n    return !IsASpace(chNext);\n}\n\nSci_Position GetEscapeSequenceLength(LexAccessor &styler, Sci_Position pos, char &chNext, char chNext2) {\n    // https://docs.ruby-lang.org/en/master/syntax/literals_rdoc.html#escape-sequences\n    Sci_Position width = 1;\n    if (isHighBitChar(chNext)) {\n        styler.MultiByteAccess()->GetCharacterAndWidth(pos, &width);\n    } else {\n        Sci_Position digits = 3; // \\xHH, \\nnn\n        int base = 16;\n        if (chNext == 'u') {\n            if (chNext2 == '{') {\n                digits = 9; // \\u{HHHHHH}\n                width += 1;\n                pos += 1;\n            } else {\n                digits = 5; // \\uHHHH\n            }\n        } else if (IsAnOctalDigit(chNext)) {\n            base = 8;\n        } else if (chNext != 'x') {\n            return width;\n        }\n        do {\n            ++pos;\n            chNext2 = styler.SafeGetCharAt(pos);\n            if (!IsADigit(chNext2, base)) {\n                if (chNext2 == '}' && digits == 9) {\n                    ++width;\n                }\n                break;\n            }\n            ++width;\n        } while (width < digits);\n        chNext = chNext2;\n    }\n    return width;\n}\n\n// Options used for LexerRuby\nstruct OptionsRuby {\n\tbool foldCompact = true;\n\tbool foldComment = false;\n};\n\nconst char *const rubyWordListDesc[] = {\n    \"Keywords\",\n    nullptr\n};\n\nstruct OptionSetRuby : public OptionSet<OptionsRuby> {\n\tOptionSetRuby() {\n\t\tDefineProperty(\"fold.compact\", &OptionsRuby::foldCompact);\n\t\tDefineProperty(\"fold.comment\", &OptionsRuby::foldComment);\n\n\t\tDefineWordListSets(rubyWordListDesc);\n\t}\n};\n\nconst char styleSubable[] = { SCE_RB_IDENTIFIER, 0 };\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer ruby SCLEX_RUBY SCE_RB_\n\t0, \"SCE_RB_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_RB_ERROR\", \"error\", \"Error\",\n\t2, \"SCE_RB_COMMENTLINE\", \"comment\", \"Comment\",\n\t3, \"SCE_RB_POD\", \"data\", \"POD\",\n\t4, \"SCE_RB_NUMBER\", \"literal numeric\", \"Number\",\n\t5, \"SCE_RB_WORD\", \"keyword\", \"Keyword\",\n\t6, \"SCE_RB_STRING\", \"literal string\", \"Quoted string\",\n\t7, \"SCE_RB_CHARACTER\", \"literal string character\", \"Quoted string\",\n\t8, \"SCE_RB_CLASSNAME\", \"identifier\", \"Class name definition\",\n\t9, \"SCE_RB_DEFNAME\", \"identifier\", \"Function or method name definition\",\n\t10, \"SCE_RB_OPERATOR\", \"operator\", \"Operator\",\n\t11, \"SCE_RB_IDENTIFIER\", \"identifier\", \"Identifiers\",\n\t12, \"SCE_RB_REGEX\", \"literal regex\", \"RegEx\",\n\t13, \"SCE_RB_GLOBAL\", \"identifier\", \"Global\",\n\t14, \"SCE_RB_SYMBOL\", \"identifier symbol\", \"\",\n\t15, \"SCE_RB_MODULE_NAME\", \"identifier\", \"Module name\",\n\t16, \"SCE_RB_INSTANCE_VAR\", \"identifier\", \"Instance variable\",\n\t17, \"SCE_RB_CLASS_VAR\", \"identifier\", \"Class variable\",\n\t18, \"SCE_RB_BACKTICKS\", \"literal string interpolated\", \"Back ticks\",\n\t19, \"SCE_RB_DATASECTION\", \"data\", \"Data section\",\n\t20, \"SCE_RB_HERE_DELIM\", \"here-doc literal string\", \"Here-doc (delimiter)\",\n\t21, \"SCE_RB_HERE_Q\", \"here-doc literal string\", \"Here-doc (single quoted, q)\",\n\t22, \"SCE_RB_HERE_QQ\", \"here-doc literal string\", \"Here-doc (double quoted, qq)\",\n\t23, \"SCE_RB_HERE_QX\", \"here-doc literal string\", \"Here-doc (back ticks, qx)\",\n\t24, \"SCE_RB_STRING_Q\", \"literal string\", \"Single quoted string, generic\",\n\t25, \"SCE_RB_STRING_QQ\", \"literal string interpolated\", \"qq = double quoted string\",\n\t26, \"SCE_RB_STRING_QX\", \"literal string interpolated\", \"qx = back ticks\",\n\t27, \"SCE_RB_STRING_QR\", \"literal regex\", \"qr = regex\",\n\t28, \"SCE_RB_STRING_QW\", \"literal string interpolated\", \"qw = array\",\n\t29, \"SCE_RB_WORD_DEMOTED\", \"keyword\", \"Keyword demoted\",\n\t30, \"SCE_RB_STDIN\", \"file\", \"Standard input stream\",\n\t31, \"SCE_RB_STDOUT\", \"file\", \"Standard output stream\",\n\t32, \"\", \"predefined\", \"\",\n\t33, \"\", \"predefined\", \"\",\n\t34, \"\", \"predefined\", \"\",\n\t35, \"\", \"predefined\", \"\",\n\t36, \"\", \"predefined\", \"\",\n\t37, \"\", \"predefined\", \"\",\n\t38, \"\", \"predefined\", \"\",\n\t39, \"\", \"predefined\", \"\",\n\t40, \"SCE_RB_STDERR\", \"file\", \"Standard error stream\",\n\t41, \"SCE_RB_STRING_W\", \"literal string\", \"String array\",\n\t42, \"SCE_RB_STRING_I\", \"literal string\", \"Symbol array\",\n\t43, \"SCE_RB_STRING_QI\", \"literal string interpolated\", \"Interpolable symbol array\",\n\t44, \"SCE_RB_STRING_QS\", \"identifier symbol\", \"Symbol\",\n};\n\nclass LexerRuby : public DefaultLexer {\n\tWordList keywords;\n\tOptionsRuby options;\n\tOptionSetRuby osRuby;\n\tSubStyles subStyles{styleSubable};\npublic:\n\tLexerRuby() :\n\t\tDefaultLexer(\"ruby\", SCLEX_RUBY, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\t// Deleted so LexerRuby objects can not be copied.\n\tLexerRuby(const LexerRuby &) = delete;\n\tLexerRuby(LexerRuby &&) = delete;\n\tvoid operator=(const LexerRuby &) = delete;\n\tvoid operator=(LexerRuby &&) = delete;\n\t~LexerRuby() override = default;\n\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osRuby.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osRuby.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osRuby.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osRuby.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osRuby.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {\n\t\treturn subStyles.Allocate(styleBase, numberStyles);\n\t}\n\tint SCI_METHOD SubStylesStart(int styleBase) override {\n\t\treturn subStyles.Start(styleBase);\n\t}\n\tint SCI_METHOD SubStylesLength(int styleBase) override {\n\t\treturn subStyles.Length(styleBase);\n\t}\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override {\n\t\tconst int styleBase = subStyles.BaseStyle(subStyle);\n\t\treturn styleBase;\n\t}\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) override {\n\t\treturn style;\n\t}\n\tvoid SCI_METHOD FreeSubStyles() override {\n\t\tsubStyles.Free();\n\t}\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {\n\t\tsubStyles.SetIdentifiers(style, identifiers);\n\t}\n\tint SCI_METHOD DistanceToSecondaryStyles() override {\n\t\treturn 0;\n\t}\n\tconst char *SCI_METHOD GetSubStyleBases() override {\n\t\treturn styleSubable;\n\t}\n\n\tstatic ILexer5 *LexerFactoryRuby() {\n\t\treturn new LexerRuby();\n\t}\n};\n\nSci_Position SCI_METHOD LexerRuby::PropertySet(const char *key, const char *val) {\n\tif (osRuby.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerRuby::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN && wordListN->Set(wl)) {\n\t\tfirstModification = 0;\n\t}\n\treturn firstModification;\n}\n\nbool followsDot(Sci_PositionU pos, Accessor &styler) {\n    for (; pos >= 1; --pos) {\n        const int style = styler.BufferStyleAt(pos);\n        switch (style) {\n        case SCE_RB_DEFAULT:\n            if (IsASpaceOrTab(styler[pos])) {\n                //continue\n            } else {\n                return false;\n            }\n            break;\n\n        case SCE_RB_OPERATOR:\n            return styler[pos] == '.';\n\n        default:\n            return false;\n        }\n    }\n    return false;\n}\n\nconstexpr bool IsIdentifierStyle(int style) noexcept {\n    return style == SCE_RB_IDENTIFIER || style >= SubStylesFirst;\n}\n\n// Forward declarations\nbool keywordIsAmbiguous(const std::string &prevWord) noexcept;\nbool keywordDoStartsLoop(Sci_Position pos, Accessor &styler);\nbool keywordIsModifier(const std::string &word, Sci_Position pos, Accessor &styler);\n\n// pseudo style: prefer regex after identifier\n#define SCE_RB_IDENTIFIER_PREFERRE  SCE_RB_UPPER_BOUND\n\nint ClassifyWordRb(Sci_PositionU end, char ch, char chNext, const WordList &keywords, Accessor &styler, std::string &prevWord, const WordClassifier &idClasser) {\n    const Sci_PositionU start = styler.GetStartSegment();\n    const std::string s = styler.GetRange(start, end);\n    int chAttr = SCE_RB_IDENTIFIER;\n    int style = SCE_RB_DEFAULT;\n    if (prevWord == \"class\")\n        chAttr = SCE_RB_CLASSNAME;\n    else if (prevWord == \"module\")\n        chAttr = SCE_RB_MODULE_NAME;\n    else if (prevWord == \"def\") {\n        chAttr = SCE_RB_DEFNAME;\n        if (ch == '.' || (ch == ':' && chNext == ':')) {\n            if (s == \"self\") {\n                style = SCE_RB_WORD_DEMOTED;\n            } else {\n                style = SCE_RB_IDENTIFIER;\n                const int subStyle = idClasser.ValueFor(s);\n                if (subStyle >= 0) {\n                    style = subStyle;\n                }\n            }\n        }\n    } else if ((start == 0) || !followsDot(start - 1, styler)) {\n        if (keywords.InList(s)) {\n            if (keywordIsAmbiguous(s)\n                && keywordIsModifier(s, start, styler)) {\n\n                // Demoted keywords are colored as keywords,\n                // but do not affect changes in indentation.\n                //\n                // Consider the word 'if':\n                // 1. <<if test ...>> : normal\n                // 2. <<stmt if test>> : demoted\n                // 3. <<lhs = if ...>> : normal: start a new indent level\n                // 4. <<obj.if = 10>> : color as identifier, since it follows '.'\n\n                chAttr = SCE_RB_WORD_DEMOTED;\n            } else {\n                chAttr = SCE_RB_WORD;\n                style = SCE_RB_WORD;\n                prevWord = s;\n            }\n        } else {\n            const int subStyle = idClasser.ValueFor(s);\n            if (subStyle >= 0) {\n                style = subStyle;\n            }\n        }\n    }\n    if (style == SCE_RB_DEFAULT) {\n        style = chAttr;\n        prevWord.clear();\n    }\n    styler.ColourTo(end - 1, style);\n\n    if (chAttr == SCE_RB_IDENTIFIER) {\n        // find heredoc in lib/ruby folder: rg \"\\w+\\s+<<[\\w\\-~'\\\"`]\"\n        // Kernel methods\n        if (InList(s, { \"puts\", \"print\", \"warn\", \"eval\" } )) {\n            chAttr = SCE_RB_IDENTIFIER_PREFERRE;\n        }\n    }\n    return chAttr;\n}\n\n\n//XXX Identical to Perl, put in common area\nbool isMatch(Accessor &styler, Sci_Position lengthDoc, Sci_Position pos, const char *val) {\n    if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {\n        return false;\n    }\n    while (*val) {\n        if (*val != styler[pos++]) {\n            return false;\n        }\n        val++;\n    }\n    return true;\n}\n\n// Do Ruby better -- find the end of the line, work back,\n// and then check for leading white space\n\n// Precondition: the here-doc target can be indented\nbool lookingAtHereDocDelim(Accessor &styler, Sci_Position pos, Sci_Position lengthDoc, const char *HereDocDelim) {\n    if (!isMatch(styler, lengthDoc, pos, HereDocDelim)) {\n        return false;\n    }\n    while (--pos > 0) {\n        const char ch = styler[pos];\n        if (isEOLChar(ch)) {\n            return true;\n        } else if (ch != ' ' && ch != '\\t') {\n            return false;\n        }\n    }\n    return false;\n}\n\n//XXX Identical to Perl, put in common area\nconstexpr char opposite(char ch) noexcept {\n    if (ch == '(')\n        return ')';\n    if (ch == '[')\n        return ']';\n    if (ch == '{')\n        return '}';\n    if (ch == '<')\n        return '>';\n    return ch;\n}\n\n// Null transitions when we see we've reached the end\n// and need to re-lex the curr char.\n\nvoid redo_char(Sci_Position &i, char &ch, char &chNext, char &chNext2, int &state) noexcept {\n    i--;\n    chNext2 = chNext;\n    chNext = ch;\n    state = SCE_RB_DEFAULT;\n}\n\nvoid advance_char(Sci_Position &i, char &ch, char &chNext, char &chNext2) noexcept {\n    i++;\n    ch = chNext;\n    chNext = chNext2;\n}\n\n// precondition: startPos points to one after the EOL char\nbool currLineContainsHereDelims(Sci_Position &startPos, Accessor &styler) {\n    if (startPos <= 1)\n        return false;\n\n    Sci_Position pos = startPos - 1;\n    for (; pos > 0; pos--) {\n        const char ch = styler.SafeGetCharAt(pos);\n        if (isEOLChar(ch)) {\n            // Leave the pointers where they are -- there are no\n            // here doc delimiters on the current line, even if\n            // the EOL isn't default style\n\n            return false;\n        }\n        if (styler.StyleIndexAt(pos) == SCE_RB_HERE_DELIM) {\n            break;\n        }\n    }\n    if (pos == 0) {\n        return false;\n    }\n    // Update the pointers so we don't have to re-analyze the string\n    startPos = pos;\n    return true;\n}\n\n// This class is used by the enter and exit methods, so it needs\n// to be hoisted out of the function.\n\nclass QuoteCls {\npublic:\n    int  Count = 0;\n    char Up = '\\0';\n    char Down = '\\0';\n    QuoteCls() noexcept = default;\n    void New() noexcept {\n        Count = 0;\n        Up    = '\\0';\n        Down  = '\\0';\n    }\n    void Open(char u) noexcept {\n        Count++;\n        Up    = u;\n        Down  = opposite(Up);\n    }\n};\n\nconstexpr bool isPercentLiteral(int state) noexcept {\n    return state == SCE_RB_STRING_Q\n           || state == SCE_RB_STRING_QQ\n           // excluded SCE_RB_STRING_QR\n           || state == SCE_RB_STRING_W\n           || state == SCE_RB_STRING_QW\n           || state == SCE_RB_STRING_I\n           || state == SCE_RB_STRING_QI\n           || state == SCE_RB_STRING_QS\n           || state == SCE_RB_STRING_QX;\n}\n\nconstexpr bool isInterpolableLiteral(int state) noexcept {\n    return state != SCE_RB_STRING_Q\n           && state != SCE_RB_STRING_W\n           && state != SCE_RB_STRING_I\n           && state != SCE_RB_STRING_QS\n           && state != SCE_RB_CHARACTER;\n}\n\nconstexpr bool isSingleSpecialVariable(char ch) noexcept {\n    // https://docs.ruby-lang.org/en/master/globals_rdoc.html\n    return AnyOf(ch, '~', '*', '$', '?', '!', '@', '/', '\\\\', ';', ',', '.', '=', ':', '<', '>', '\"', '&', '`', '\\'', '+');\n}\n\nvoid InterpolateVariable(LexAccessor &styler, int state, Sci_Position &i, char &ch, char &chNext, char chNext2) {\n    Sci_Position pos = i;\n    styler.ColourTo(pos - 1, state);\n    styler.ColourTo(pos, SCE_RB_OPERATOR);\n    state = SCE_RB_GLOBAL;\n    pos += 2;\n    int len = 0;\n    if (chNext == '$') {\n        if (chNext2 == '-') {\n            ++pos;\n            len = 2;\n        } else if (isSingleSpecialVariable(chNext2)) {\n            ++pos;\n            len = 1;\n        }\n    } else {\n        state = SCE_RB_INSTANCE_VAR;\n        if (chNext2 == '@') {\n            state = SCE_RB_CLASS_VAR;\n            ++pos;\n        }\n    }\n    while (true) {\n        chNext2 = styler.SafeGetCharAt(pos);\n        --len;\n        if (len == 0 || !isSafeWordcharOrHigh(chNext2)) {\n            break;\n        }\n        ++pos;\n    }\n    --pos;\n    styler.ColourTo(pos, state);\n    i = pos;\n    ch = chNext;\n    chNext = chNext2;\n}\n\nbool isEmptyLine(Sci_Position pos, Accessor &styler) {\n    int spaceFlags = 0;\n    const Sci_Position lineCurrent = styler.GetLine(pos);\n    const int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);\n    return (indentCurrent & SC_FOLDLEVELWHITEFLAG) != 0;\n}\n\nbool RE_CanFollowKeyword(const std::string &keyword) noexcept {\n\treturn InList(keyword, {\n\t\t\"and\",\n\t\t\"begin\",\n\t\t\"break\",\n\t\t\"case\",\n\t\t\"do\",\n\t\t\"else\",\n\t\t\"elsif\",\n\t\t\"if\",\n\t\t\"next\",\n\t\t\"return\",\n\t\t\"when\",\n\t\t\"unless\",\n\t\t\"until\",\n\t\t\"not\",\n\t\t\"or\"\n\t\t});\n}\n\n// Look at chars up to but not including endPos\n// Don't look at styles in case we're looking forward\n\nSci_Position skipWhitespace(Sci_Position startPos, Sci_Position endPos, Accessor &styler) {\n    for (Sci_Position i = startPos; i < endPos; i++) {\n        if (!IsASpaceOrTab(styler[i])) {\n            return i;\n        }\n    }\n    return endPos;\n}\n\n// This routine looks for false positives like\n// undef foo, <<\n// There aren't too many.\n//\n// iPrev points to the start of <<\n\nbool sureThisIsHeredoc(Sci_Position iPrev, Accessor &styler, std::string &prevWord) {\n\n    // Not so fast, since Ruby's so dynamic.  Check the context\n    // to make sure we're OK.\n    const Sci_Position lineStart = styler.GetLine(iPrev);\n    const Sci_Position lineStartPosn = styler.LineStart(lineStart);\n    styler.Flush();\n\n    // Find the first word after some whitespace\n    const Sci_Position firstWordPosn = skipWhitespace(lineStartPosn, iPrev, styler);\n    if (firstWordPosn >= iPrev) {\n        // Have something like {^     <<}\n        //XXX Look at the first previous non-comment non-white line\n        // to establish the context.  Not too likely though.\n        return true;\n    }\n    const int prevStyle = styler.StyleIndexAt(firstWordPosn);\n    switch (prevStyle) {\n    case SCE_RB_WORD:\n    case SCE_RB_WORD_DEMOTED:\n    case SCE_RB_IDENTIFIER:\n        break;\n    default:\n        return true;\n    }\n    Sci_Position firstWordEndPosn = firstWordPosn;\n    prevWord.clear();\n    for (;;) {\n        if (firstWordEndPosn >= iPrev ||\n                styler.StyleIndexAt(firstWordEndPosn) != prevStyle) {\n            break;\n        }\n        prevWord.push_back(styler[firstWordEndPosn]);\n        firstWordEndPosn += 1;\n    }\n    //XXX Write a style-aware thing to regex scintilla buffer objects\n    // These keywords are what we were looking for\n    return !InList(prevWord, { \"undef\", \"def\", \"alias\" });\n}\n\n// Routine that saves us from allocating a buffer for the here-doc target\n// targetEndPos points one past the end of the current target\nbool haveTargetMatch(Sci_Position currPos, Sci_Position lengthDoc, Sci_Position targetStartPos, Sci_Position targetEndPos, Accessor &styler) {\n    if (lengthDoc - currPos < targetEndPos - targetStartPos) {\n        return false;\n    }\n    for (Sci_Position i = targetStartPos, j = currPos;\n            i < targetEndPos && j < lengthDoc;\n            i++, j++) {\n        if (styler[i] != styler[j]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Finds the start position of the expression containing @p pos\n// @p min_pos should be a known expression start, e.g. the start of the line\nSci_Position findExpressionStart(Sci_Position pos, Sci_Position min_pos, Accessor &styler) {\n    int depth = 0;\n    for (; pos > min_pos; pos -= 1) {\n        const int style = styler.StyleIndexAt(pos - 1);\n        if (style == SCE_RB_OPERATOR) {\n            const char ch = styler[pos - 1];\n            if (ch == '}' || ch == ')' || ch == ']') {\n                depth += 1;\n            } else if (ch == '{' || ch == '(' || ch == '[') {\n                if (depth == 0) {\n                    break;\n                }\n                depth -= 1;\n            } else if (ch == ';' && depth == 0) {\n                break;\n            }\n        }\n    }\n    return pos;\n}\n\n// We need a check because the form\n// [identifier] <<[target]\n// is ambiguous.  The Ruby lexer/parser resolves it by\n// looking to see if [identifier] names a variable or a\n// function.  If it's the first, it's the start of a here-doc.\n// If it's a var, it's an operator.  This lexer doesn't\n// maintain a symbol table, so it looks ahead to see what's\n// going on, in cases where we have\n// ^[white-space]*[identifier([.|::]identifier)*][white-space]*<<[target]\n//\n// If there's no occurrence of [target] on a line, assume we don't.\n\n// return true == yes, we have no heredocs\n\nbool sureThisIsNotHeredoc(Sci_Position lt2StartPos, Accessor &styler) {\n    // Use full document, not just part we're styling\n    const Sci_Position lengthDoc = styler.Length();\n    const Sci_Position lineStart = styler.GetLine(lt2StartPos);\n    const Sci_Position lineStartPosn = styler.LineStart(lineStart);\n    styler.Flush();\n    constexpr bool definitely_not_a_here_doc = true;\n    constexpr bool looks_like_a_here_doc = false;\n\n    // find the expression start rather than the line start\n    const Sci_Position exprStartPosn = findExpressionStart(lt2StartPos, lineStartPosn, styler);\n\n    // Find the first word after some whitespace\n    Sci_Position firstWordPosn = skipWhitespace(exprStartPosn, lt2StartPos, styler);\n    if (firstWordPosn >= lt2StartPos) {\n        return definitely_not_a_here_doc;\n    }\n    int prevStyle = styler.StyleIndexAt(firstWordPosn);\n    // If we have '<<' following a keyword, it's not a heredoc\n    if (!IsIdentifierStyle(prevStyle)\n            && prevStyle != SCE_RB_GLOBAL       // $stdout and $stderr\n            && prevStyle != SCE_RB_SYMBOL\n            && prevStyle != SCE_RB_INSTANCE_VAR\n            && prevStyle != SCE_RB_CLASS_VAR) {\n        return definitely_not_a_here_doc;\n    }\n    int newStyle = prevStyle;\n    // Some compilers incorrectly warn about uninit newStyle\n    for (firstWordPosn += 1; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {\n        // Inner loop looks at the name\n        for (; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {\n            newStyle = styler.StyleIndexAt(firstWordPosn);\n            if (newStyle != prevStyle) {\n                break;\n            }\n        }\n        // Do we have '::' or '.'?\n        if (firstWordPosn < lt2StartPos && newStyle == SCE_RB_OPERATOR) {\n            const char ch = styler[firstWordPosn];\n            if (ch == '.') {\n                // yes\n            } else if (ch == ':') {\n                if (styler.StyleIndexAt(++firstWordPosn) != SCE_RB_OPERATOR) {\n                    return definitely_not_a_here_doc;\n                } else if (styler[firstWordPosn] != ':') {\n                    return definitely_not_a_here_doc;\n                }\n            } else {\n                break;\n            }\n        } else {\n            break;\n        }\n        // on second and next passes, only identifiers may appear since\n        // class and instance variable are private\n        prevStyle = SCE_RB_IDENTIFIER;\n    }\n    // Skip next batch of white-space\n    firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler);\n    // possible symbol for an implicit hash argument\n    if (firstWordPosn < lt2StartPos && styler.StyleIndexAt(firstWordPosn) == SCE_RB_SYMBOL) {\n        for (; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {\n            if (styler.StyleIndexAt(firstWordPosn) != SCE_RB_SYMBOL) {\n                break;\n            }\n        }\n        // Skip next batch of white-space\n        firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler);\n    }\n    if (firstWordPosn != lt2StartPos) {\n        // Have [[^ws[identifier]ws[*something_else*]ws<<\n        return definitely_not_a_here_doc;\n    }\n    // OK, now 'j' will point to the current spot moving ahead\n    Sci_Position j = firstWordPosn + 1;\n    if (styler.StyleIndexAt(j) != SCE_RB_OPERATOR || styler[j] != '<') {\n        // This shouldn't happen\n        return definitely_not_a_here_doc;\n    }\n    const Sci_Position nextLineStartPosn = styler.LineStart(lineStart + 1);\n    if (nextLineStartPosn >= lengthDoc) {\n        return definitely_not_a_here_doc;\n    }\n    j = skipWhitespace(j + 1, nextLineStartPosn, styler);\n    if (j >= lengthDoc) {\n        return definitely_not_a_here_doc;\n    }\n    bool allow_indent = false;\n    Sci_Position target_start = 0;\n    Sci_Position target_end = 0;\n    // From this point on no more styling, since we're looking ahead\n    if (styler[j] == '-' || styler[j] == '~') {\n        allow_indent = true;\n        j++;\n    } else {\n        allow_indent = false;\n    }\n\n    // Allow for quoted targets.\n    char target_quote = 0;\n    switch (styler[j]) {\n    case '\\'':\n    case '\"':\n    case '`':\n        target_quote = styler[j];\n        j += 1;\n    }\n\n    if (isSafeAlnumOrHigh(styler[j])) {\n        // Initialize target_end because some compilers think it won't\n        // be initialized by the time it's used\n        target_start = target_end = j;\n        j++;\n    } else {\n        return definitely_not_a_here_doc;\n    }\n    for (; j < lengthDoc; j++) {\n        if (!isSafeAlnumOrHigh(styler[j])) {\n            if (target_quote && styler[j] != target_quote) {\n                // unquoted end\n                return definitely_not_a_here_doc;\n            }\n\n            // And for now make sure that it's a newline\n            // don't handle arbitrary expressions yet\n\n            target_end = j;\n            if (target_quote) {\n                // Now we can move to the character after the string delimiter.\n                j += 1;\n            }\n            j = skipWhitespace(j, lengthDoc, styler);\n            if (j >= lengthDoc) {\n                return definitely_not_a_here_doc;\n            }\n            const char ch = styler[j];\n            if (ch == '#' || isEOLChar(ch) || ch == '.' || ch == ',' || IsLowerCase(ch)) {\n                // This is OK, so break and continue;\n                break;\n            }\n            return definitely_not_a_here_doc;\n        }\n    }\n\n    // Just look at the start of each line\n    Sci_Position last_line = styler.GetLine(lengthDoc - 1);\n    // But don't go too far\n    if (last_line > lineStart + 50) {\n        last_line = lineStart + 50;\n    }\n    for (Sci_Position line_num = lineStart + 1; line_num <= last_line; line_num++) {\n        j = styler.LineStart(line_num);\n        if (allow_indent) {\n            j = skipWhitespace(j, lengthDoc, styler);\n        }\n        // target_end is one past the end\n        if (haveTargetMatch(j, lengthDoc, target_start, target_end, styler)) {\n            // We got it\n            return looks_like_a_here_doc;\n        }\n    }\n    return definitely_not_a_here_doc;\n}\n\n//todo: if we aren't looking at a stdio character,\n// move to the start of the first line that is not in a\n// multiline construct\n\nvoid synchronizeDocStart(Sci_PositionU &startPos, Sci_Position &length, int &initStyle, Accessor &styler, bool skipWhiteSpace=false) {\n    // Retreat one line to match function lexer\n    if (const Sci_Position lineCurrent = styler.GetLine(startPos); lineCurrent > 0) {\n        const Sci_Position endPos = startPos + length;\n        startPos = styler.LineStart(lineCurrent - 1);\n        length = endPos - startPos;\n        initStyle = (startPos > 0) ? styler.StyleIndexAt(startPos - 1) : 0;\n    }\n\n    const int style = styler.StyleIndexAt(startPos);\n    switch (style) {\n    case SCE_RB_STDIN:\n    case SCE_RB_STDOUT:\n    case SCE_RB_STDERR:\n        // Don't do anything else with these.\n        return;\n    }\n\n    Sci_Position pos = startPos;\n    // Quick way to characterize each line\n    Sci_Position lineStart = styler.GetLine(pos);\n    for (; lineStart > 0; lineStart--) {\n        // Now look at the style before the previous line's EOL\n        pos = styler.LineStart(lineStart) - 1;\n        if (pos <= 10) {\n            lineStart = 0;\n            break;\n        }\n        const char ch = styler.SafeGetCharAt(pos);\n        const char chPrev = styler.SafeGetCharAt(pos - 1);\n        if (ch == '\\n' && chPrev == '\\r') {\n            pos--;\n        }\n        if (styler.SafeGetCharAt(pos - 1) == '\\\\') {\n            // Continuation line -- keep going\n        } else if (styler.StyleIndexAt(pos) != SCE_RB_DEFAULT) {\n            // Part of multiline construct -- keep going\n        } else if (currLineContainsHereDelims(pos, styler)) {\n            // Keep going, with pos and length now pointing\n            // at the end of the here-doc delimiter\n        } else if (skipWhiteSpace && isEmptyLine(pos, styler)) {\n            // Keep going\n        } else {\n            break;\n        }\n    }\n    pos = styler.LineStart(lineStart);\n    length += (startPos - pos);\n    startPos = pos;\n    initStyle = SCE_RB_DEFAULT;\n}\n\nvoid LexerRuby::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n    Accessor styler(pAccess, nullptr);\n    styler.StartAt(startPos);\n\n    // Lexer for Ruby often has to backtrack to start of current style to determine\n    // which characters are being used as quotes, how deeply nested is the\n    // start position and what the termination string is for here documents\n\n    class HereDocCls {\n    public:\n        int State = 0;\n        // States\n        // 0: '<<' encountered\n        // 1: collect the delimiter\n        // 1b: text between the end of the delimiter and the EOL\n        // 2: here doc text (lines after the delimiter)\n        char Quote = 0;\t\t// the char after '<<'\n        bool Quoted = false;\t\t// true if Quote in ('\\'','\"','`')\n        int DelimiterLength = 0;\t// strlen(Delimiter)\n        char Delimiter[256] {};\t// the Delimiter, limit of 256: from Perl\n        bool CanBeIndented = false;\n    };\n    HereDocCls HereDoc;\n\n    QuoteCls Quote;\n\n    synchronizeDocStart(startPos, length, initStyle, styler, false);\n\n    const WordClassifier &idClasser = subStyles.Classifier(SCE_RB_IDENTIFIER);\n\n    bool preferRE = true;\n    bool afterDef = false;\n    int state = initStyle;\n    const Sci_Position lengthDoc = startPos + length;\n\n    std::string prevWord;\n    if (length == 0)\n        return;\n\n    char chPrev = styler.SafeGetCharAt(startPos - 1);\n    char chNext = styler.SafeGetCharAt(startPos);\n    bool is_real_number = true;   // Differentiate between constants and ?-sequences.\n    styler.StartAt(startPos);\n    styler.StartSegment(startPos);\n\n    static constexpr unsigned char q_states[] = {\n        SCE_RB_STRING_Q,\n        SCE_RB_STRING_QQ,\n        SCE_RB_STRING_QR,\n        SCE_RB_STRING_W,\n        SCE_RB_STRING_QW,\n        SCE_RB_STRING_QX,\n        SCE_RB_STRING_I,\n        SCE_RB_STRING_QI,\n        SCE_RB_STRING_QS,\n    };\n    constexpr const char *q_chars = \"qQrwWxiIs\";\n    constexpr size_t q_charsLen = std::size(q_states);\n\n    // In most cases a value of 2 should be ample for the code in the\n    // Ruby library, and the code the user is likely to enter.\n    // For example,\n    // fu_output_message \"mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}\"\n    //     if options[:verbose]\n    // from fileutils.rb nests to a level of 2\n    // If the user actually hits a 6th occurrence of '#{' in a double-quoted\n    // string (including regex'es, %Q, %<sym>, %w, and other strings\n    // that interpolate), it will stay as a string.  The problem with this\n    // is that quotes might flip, a 7th '#{' will look like a comment,\n    // and code-folding might be wrong.\n\n    // If anyone runs into this problem, I recommend raising this\n    // value slightly higher to replacing the fixed array with a linked\n    // list.  Keep in mind this code will be called every time the lexer\n    // is invoked.\n\n#define INNER_STRINGS_MAX_COUNT 5\n    class InnerExpression {\n        // These vars track our instances of \"...#{,,,%Q<..#{,,,}...>,,,}...\"\n        int inner_string_types[INNER_STRINGS_MAX_COUNT] {};\n        // Track # braces when we push a new #{ thing\n        int inner_expn_brace_counts[INNER_STRINGS_MAX_COUNT] {};\n        QuoteCls inner_quotes[INNER_STRINGS_MAX_COUNT];\n        int inner_string_count = 0;\n\n    public:\n        int brace_counts = 0;   // Number of #{ ... } things within an expression\n\n        [[nodiscard]] bool canEnter() const noexcept {\n            return inner_string_count < INNER_STRINGS_MAX_COUNT;\n        }\n        [[nodiscard]] bool canExit() const noexcept {\n            return inner_string_count > 0;\n        }\n        void enter(int &state, const QuoteCls &curr_quote) noexcept {\n            inner_string_types[inner_string_count] = state;\n            state = SCE_RB_DEFAULT;\n            inner_expn_brace_counts[inner_string_count] = brace_counts;\n            brace_counts = 0;\n            inner_quotes[inner_string_count] = curr_quote;\n            ++inner_string_count;\n        }\n        void exit(int &state, QuoteCls &curr_quote) noexcept {\n            --inner_string_count;\n            state = inner_string_types[inner_string_count];\n            brace_counts = inner_expn_brace_counts[inner_string_count];\n            curr_quote = inner_quotes[inner_string_count];\n        }\n    };\n    InnerExpression innerExpr;\n\n    for (Sci_Position i = startPos; i < lengthDoc; i++) {\n        char ch = chNext;\n        chNext = styler.SafeGetCharAt(i + 1);\n        char chNext2 = styler.SafeGetCharAt(i + 2);\n\n        if (styler.IsLeadByte(ch)) {\n            chNext = chNext2;\n            chPrev = ' ';\n            i += 1;\n            continue;\n        }\n\n        // skip on DOS/Windows\n        //No, don't, because some things will get tagged on,\n        // so we won't recognize keywords, for example\n#if 0\n        if (ch == '\\r' && chNext == '\\n') {\n            continue;\n        }\n#endif\n\n        if (HereDoc.State == 1 && isEOLChar(ch)) {\n            // Begin of here-doc (the line after the here-doc delimiter):\n            HereDoc.State = 2;\n            if (state == SCE_RB_WORD) {\n                ClassifyWordRb(i, ch, chNext, keywords, styler, prevWord, idClasser);\n            } else {\n                styler.ColourTo(i - 1, state);\n            }\n            // Don't check for a missing quote, just jump into\n            // the here-doc state\n            state = SCE_RB_HERE_QQ;\n            if (HereDoc.Quoted) {\n                if (HereDoc.Quote == '\\'') {\n                    state = SCE_RB_HERE_Q;\n                } else if (HereDoc.Quote == '`') {\n                    state = SCE_RB_HERE_QX;\n                }\n            }\n        }\n\n        // Regular transitions\n        if (state == SCE_RB_DEFAULT) {\n            if (isSafeDigit(ch)) {\n                styler.ColourTo(i - 1, state);\n                state = SCE_RB_NUMBER;\n                is_real_number = true;\n            } else if (isSafeAlphaOrHigh(ch)) {\n                styler.ColourTo(i - 1, state);\n                state = SCE_RB_WORD;\n            } else if (ch == '#') {\n                styler.ColourTo(i - 1, state);\n                state = SCE_RB_COMMENTLINE;\n            } else if (ch == '=') {\n                // =begin indicates the start of a comment (doc) block\n                if ((i == 0 || isEOLChar(chPrev))\n                        && chNext == 'b'\n                        && styler.SafeGetCharAt(i + 2) == 'e'\n                        && styler.SafeGetCharAt(i + 3) == 'g'\n                        && styler.SafeGetCharAt(i + 4) == 'i'\n                        && styler.SafeGetCharAt(i + 5) == 'n'\n                        && !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6))) {\n                    styler.ColourTo(i - 1, state);\n                    state = SCE_RB_POD;\n                } else {\n                    styler.ColourTo(i - 1, state);\n                    styler.ColourTo(i, SCE_RB_OPERATOR);\n                    preferRE = true;\n                }\n            } else if (ch == '\"') {\n                styler.ColourTo(i - 1, state);\n                state = SCE_RB_STRING;\n                Quote.New();\n                Quote.Open(ch);\n            } else if (ch == '\\'') {\n                styler.ColourTo(i - 1, state);\n                state = SCE_RB_CHARACTER;\n                Quote.New();\n                Quote.Open(ch);\n            } else if (ch == '`') {\n                styler.ColourTo(i - 1, state);\n                state = SCE_RB_BACKTICKS;\n                Quote.New();\n                Quote.Open(ch);\n            } else if (ch == '@') {\n                // Instance or class var\n                styler.ColourTo(i - 1, state);\n                if (chNext == '@') {\n                    state = SCE_RB_CLASS_VAR;\n                    advance_char(i, ch, chNext, chNext2); // pass by ref\n                } else {\n                    state = SCE_RB_INSTANCE_VAR;\n                }\n            } else if (ch == '$') {\n                // Check for a builtin global\n                styler.ColourTo(i - 1, state);\n                // Recognize it bit by bit\n                state = SCE_RB_GLOBAL;\n            } else if (ch == '/' && preferRE) {\n                // Ambiguous operator\n                styler.ColourTo(i - 1, state);\n                state = SCE_RB_REGEX;\n                Quote.New();\n                Quote.Open(ch);\n            } else if (ch == '<' && chNext == '<' && chNext2 != '=') {\n                if (afterDef) {\n                    afterDef = false;\n                    prevWord[0] = 0;\n                }\n                // Recognise the '<<' symbol - either a here document or a binary op\n                styler.ColourTo(i - 1, state);\n                i++;\n                chNext = chNext2;\n                styler.ColourTo(i, SCE_RB_OPERATOR);\n\n                if (!(AnyOf(chNext2, '\\\"', '\\'', '`', '-', '~') || isSafeAlphaOrHigh(chNext2))) {\n                    // It's definitely not a here-doc,\n                    // based on Ruby's lexer/parser in the\n                    // heredoc_identifier routine.\n                    // Nothing else to do.\n                } else if (preferRE) {\n                    if (sureThisIsHeredoc(i - 1, styler, prevWord)) {\n                        state = SCE_RB_HERE_DELIM;\n                        HereDoc.State = 0;\n                    }\n                    // else leave it in default state\n                } else {\n                    if (sureThisIsNotHeredoc(i - 1, styler)) {\n                        // leave state as default\n                        // We don't have all the heuristics Perl has for indications\n                        // of a here-doc, because '<<' is overloadable and used\n                        // for so many other classes.\n                    } else {\n                        state = SCE_RB_HERE_DELIM;\n                        HereDoc.State = 0;\n                    }\n                }\n                preferRE = (state != SCE_RB_HERE_DELIM);\n            } else if (ch == ':') {\n                afterDef = false;\n                styler.ColourTo(i - 1, state);\n                if (chNext == ':') {\n                    // Mark \"::\" as an operator, not symbol start\n                    styler.ColourTo(i + 1, SCE_RB_OPERATOR);\n                    advance_char(i, ch, chNext, chNext2); // pass by ref\n                    state = SCE_RB_DEFAULT;\n                    preferRE = false;\n                } else if (isSafeWordcharOrHigh(chNext)) {\n                    state = SCE_RB_SYMBOL;\n                } else if ((chNext == '@' || chNext == '$') &&\n                           isSafeWordcharOrHigh(chNext2)) {\n                    // instance and global variable followed by an identifier\n                    advance_char(i, ch, chNext, chNext2);\n                    state = SCE_RB_SYMBOL;\n                } else if (((chNext == '@' && chNext2 == '@')  ||\n                            (chNext == '$' && chNext2 == '-')) &&\n                           isSafeWordcharOrHigh(styler.SafeGetCharAt(i+3))) {\n                    // class variables and special global variable \"$-IDENTCHAR\"\n                    state = SCE_RB_SYMBOL;\n                    // $-IDENTCHAR doesn't continue past the IDENTCHAR\n                    if (chNext == '$') {\n                        styler.ColourTo(i+3, SCE_RB_SYMBOL);\n                        state = SCE_RB_DEFAULT;\n                    }\n                    i += 3;\n                    ch = styler.SafeGetCharAt(i);\n                    chNext = styler.SafeGetCharAt(i+1);\n                } else if (chNext == '$' && isSingleSpecialVariable(chNext2)) {\n                    // single-character special global variables\n                    i += 2;\n                    ch = chNext2;\n                    chNext = styler.SafeGetCharAt(i+1);\n                    styler.ColourTo(i, SCE_RB_SYMBOL);\n                    state = SCE_RB_DEFAULT;\n                } else if (isOperatorName(chNext)) {\n                    // Do the operator analysis in-line, looking ahead\n                    // Based on the table in pickaxe 2nd ed., page 339\n                    bool doColoring = true;\n                    switch (chNext) {\n                    case '[':\n                        if (chNext2 == ']') {\n                            const char ch_tmp = styler.SafeGetCharAt(i + 3);\n                            if (ch_tmp == '=') {\n                                i += 3;\n                                ch = ch_tmp;\n                                chNext = styler.SafeGetCharAt(i + 1);\n                            } else {\n                                i += 2;\n                                ch = chNext2;\n                                chNext = ch_tmp;\n                            }\n                        } else {\n                            doColoring = false;\n                        }\n                        break;\n\n                    case '*':\n                        if (chNext2 == '*') {\n                            i += 2;\n                            ch = chNext2;\n                            chNext = styler.SafeGetCharAt(i + 1);\n                        } else {\n                            advance_char(i, ch, chNext, chNext2);\n                        }\n                        break;\n\n                    case '!':\n                        if (chNext2 == '=' || chNext2 == '~') {\n                            i += 2;\n                            ch = chNext2;\n                            chNext = styler.SafeGetCharAt(i + 1);\n                        } else {\n                            advance_char(i, ch, chNext, chNext2);\n                        }\n                        break;\n\n                    case '<':\n                        if (chNext2 == '<') {\n                            i += 2;\n                            ch = chNext2;\n                            chNext = styler.SafeGetCharAt(i + 1);\n                        } else if (chNext2 == '=') {\n                            const char ch_tmp = styler.SafeGetCharAt(i + 3);\n                            if (ch_tmp == '>') {  // <=> operator\n                                i += 3;\n                                ch = ch_tmp;\n                                chNext = styler.SafeGetCharAt(i + 1);\n                            } else {\n                                i += 2;\n                                ch = chNext2;\n                                chNext = ch_tmp;\n                            }\n                        } else {\n                            advance_char(i, ch, chNext, chNext2);\n                        }\n                        break;\n\n                    default:\n                        // Simple one-character operators\n                        advance_char(i, ch, chNext, chNext2);\n                        break;\n                    }\n                    if (doColoring) {\n                        styler.ColourTo(i, SCE_RB_SYMBOL);\n                        state = SCE_RB_DEFAULT;\n                    }\n                } else if (!preferRE && !IsASpace(chNext)) {\n                    // Don't color symbol strings (yet)\n                    // Just color the \":\" and color rest as string\n                    styler.ColourTo(i, SCE_RB_SYMBOL);\n                    state = SCE_RB_DEFAULT;\n                } else {\n                    styler.ColourTo(i, SCE_RB_OPERATOR);\n                    state = SCE_RB_DEFAULT;\n                    preferRE = true;\n                }\n            } else if (ch == '%' && !afterDef) {\n                styler.ColourTo(i - 1, state);\n                bool have_string = false;\n                const char *hit = static_cast<const char *>(memchr(q_chars, static_cast<unsigned char>(chNext), q_charsLen));\n                if (hit != nullptr && !isSafeWordcharOrHigh(chNext2)) {\n                    Quote.New();\n                    state = q_states[hit - q_chars];\n                    Quote.Open(chNext2);\n                    i += 2;\n                    ch = chNext2;\n                    chNext = styler.SafeGetCharAt(i + 1);\n                    have_string = true;\n                } else if ((preferRE || (!isWhiteSpace(chNext) && chNext != '=')) && !isSafeWordcharOrHigh(chNext)) {\n                    // Ruby doesn't allow high bit chars here,\n                    // but the editor host might\n                    Quote.New();\n                    state = SCE_RB_STRING_QQ;\n                    Quote.Open(chNext);\n                    advance_char(i, ch, chNext, chNext2); // pass by ref\n                    have_string = true;\n                }\n                if (!have_string) {\n                    styler.ColourTo(i, SCE_RB_OPERATOR);\n                    // stay in default\n                    preferRE = true;\n                }\n            } else if (ch == '?') {\n                afterDef = false;\n                styler.ColourTo(i - 1, state);\n                if (isHighBitChar(chNext)) {\n                    preferRE = false;\n                    Sci_Position width = 1;\n                    styler.MultiByteAccess()->GetCharacterAndWidth(i + 1, &width);\n                    chNext = styler.SafeGetCharAt(i + 1 + width);\n                    if (isSafeWordcharOrHigh(chNext)) {\n                        styler.ColourTo(i, SCE_RB_OPERATOR);\n                        i += width;\n                        state = SCE_RB_WORD;\n                    } else {\n                        i += width;\n                        styler.ColourTo(i, SCE_RB_NUMBER);\n                    }\n                } else if (!isQuestionMarkChar(chNext, chNext2)) {\n                    styler.ColourTo(i, SCE_RB_OPERATOR);\n                    preferRE = chNext <= ' ';\n                } else {\n                    // It's the start of a character code escape sequence\n                    // Color it as a number.\n                    state = SCE_RB_NUMBER;\n                    is_real_number = false;\n                }\n            } else if (isoperator(ch) || ch == '.') {\n                styler.ColourTo(i - 1, state);\n                if (afterDef && ch != '.') {\n                    afterDef = false;\n                    prevWord[0] = 0;\n                    if (chNext == '@' && (ch == '+' || ch == '-' || ch == '!')) {\n                        // unary operator method\n                        ch = chNext;\n                        chNext = chNext2;\n                        i += 1;\n                    }\n                }\n                styler.ColourTo(i, SCE_RB_OPERATOR);\n                // If we're ending an expression or block,\n                // assume it ends an object, and the ambivalent\n                // constructs are binary operators\n                //\n                // So if we don't have one of these chars,\n                // we aren't ending an object expression, and ops\n                // like : << / are unary operators.\n\n                if (ch == '{') {\n                    ++innerExpr.brace_counts;\n                    preferRE = true;\n                } else if (ch == '}' && --innerExpr.brace_counts < 0\n                           && innerExpr.canExit()) {\n                    styler.ColourTo(i, SCE_RB_OPERATOR);\n                    innerExpr.exit(state, Quote);\n                } else {\n                    preferRE = !AnyOf(ch, ')', '}', ']', '.');\n                }\n                // Stay in default state\n            } else if (isEOLChar(ch)) {\n                afterDef = false;\n                // Make sure it's a true line-end, with no backslash\n                if ((ch == '\\r' || (ch == '\\n' && chPrev != '\\r'))\n                        && chPrev != '\\\\') {\n                    // Assume we've hit the end of the statement.\n                    preferRE = true;\n                }\n            }\n            if (afterDef && state != SCE_RB_DEFAULT) {\n                afterDef = false;\n            }\n        } else if (state == SCE_RB_WORD) {\n            if (ch == '.' || !isSafeWordcharOrHigh(ch)) {\n                // Words include x? in all contexts,\n                // and <letters>= after either 'def' or a dot\n                // Move along until a complete word is on our left\n\n                // Default accessor treats '.' as word-chars,\n                // but we don't for now.\n\n                if (ch == '='\n                        && isSafeWordcharOrHigh(chPrev)\n                        && (chNext == '('\n                            || isWhiteSpace(chNext))\n                        && ((prevWord == \"def\")\n                            || followsDot(styler.GetStartSegment(), styler))) {\n                    // <name>= is a name only when being defined -- Get it the next time\n                    // This means that <name>=<name> is always lexed as\n                    // <name>, (op, =), <name>\n                } else if (ch == ':'\n                           && isSafeWordcharOrHigh(chPrev)\n                           && isWhiteSpace(chNext)) {\n                    // keyword argument, symbol Hash key\n                    styler.ColourTo(i, SCE_RB_SYMBOL);\n                    state = SCE_RB_DEFAULT;\n                    preferRE = true;\n                } else if ((ch == '?' || ch == '!')\n                           && isSafeWordcharOrHigh(chPrev)\n                           && !isSafeWordcharOrHigh(chNext)) {\n                    // <name>? is a name -- Get it the next time\n                    // But <name>?<name> is always lexed as\n                    // <name>, (op, ?), <name>\n                    // Same with <name>! to indicate a method that\n                    // modifies its target\n                } else if (isEOLChar(ch)\n                           && isMatch(styler, lengthDoc, i - 7, \"__END__\")) {\n                    styler.ColourTo(i, SCE_RB_DATASECTION);\n                    state = SCE_RB_DATASECTION;\n                    // No need to handle this state -- we'll just move to the end\n                    preferRE = false;\n                } else {\n                    const int word_style = ClassifyWordRb(i, ch, chNext, keywords, styler, prevWord, idClasser);\n                    switch (word_style) {\n                    case SCE_RB_WORD:\n                        afterDef = prevWord == \"def\";\n                        preferRE = RE_CanFollowKeyword(prevWord);\n                        break;\n\n                    case SCE_RB_WORD_DEMOTED:\n                    case SCE_RB_DEFNAME:\n                    case SCE_RB_IDENTIFIER_PREFERRE:\n                        preferRE = true;\n                        break;\n\n                    case SCE_RB_IDENTIFIER:\n                        preferRE = isEOLChar(ch);\n                        break;\n\n                    default:\n                        preferRE = false;\n                    }\n                    if (ch == '.') {\n                        // We might be redefining an operator-method\n                        afterDef = word_style == SCE_RB_DEFNAME;\n                    }\n                    // And if it's the first\n                    redo_char(i, ch, chNext, chNext2, state); // pass by ref\n                }\n            }\n        } else if (state == SCE_RB_NUMBER) {\n            if (!is_real_number) {\n                if (ch != '\\\\' || isEOLChar(chNext)) {\n                    styler.ColourTo(i, state);\n                    state = SCE_RB_DEFAULT;\n                    preferRE = false;\n                } else if ((chNext == 'C' || chNext == 'M') && chNext2 == '-') {\n                    // Move from abc?\\C-x\n                    //               ^\n                    // to\n                    //                 ^\n                    i += 2;\n                    ch = chNext2;\n                    chNext = styler.SafeGetCharAt(i + 1);\n                } else if (chNext == 'c') {\n                    // Stay here, \\c is a combining sequence\n                    advance_char(i, ch, chNext, chNext2); // pass by ref\n                } else {\n                    // ?\\x, including ?\\\\ is final.\n                    const Sci_Position width = GetEscapeSequenceLength(styler, i + 1, chNext, chNext2);\n                    i += width;\n                    styler.ColourTo(std::min(i, lengthDoc - 1), state);\n                    state = SCE_RB_DEFAULT;\n                    preferRE = false;\n                    ch = chNext;\n                    chNext = styler.SafeGetCharAt(i + 1);\n                }\n            } else if (isSafeAlnumOrHigh(ch) || ch == '_' || (ch == '.' && isSafeDigit(chNext))) {\n                // Keep going\n            } else if (ch == '.' && chNext == '.') {\n                styler.ColourTo(i - 1, state);\n                redo_char(i, ch, chNext, chNext2, state); // pass by ref\n            } else {\n                styler.ColourTo(i - 1, state);\n                redo_char(i, ch, chNext, chNext2, state); // pass by ref\n                preferRE = false;\n            }\n        } else if (state == SCE_RB_COMMENTLINE) {\n            if (isEOLChar(ch)) {\n                styler.ColourTo(i - 1, state);\n                state = SCE_RB_DEFAULT;\n                // Use whatever setting we had going into the comment\n            }\n        } else if (state == SCE_RB_HERE_DELIM) {\n            // See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx\n            // Slightly different: if we find an immediate '-',\n            // the target can appear indented.\n\n            if (HereDoc.State == 0) { // '<<' encountered\n                HereDoc.State = 1;\n                HereDoc.DelimiterLength = 0;\n                if (ch == '-' || ch == '~') {\n                    HereDoc.CanBeIndented = true;\n                    advance_char(i, ch, chNext, chNext2); // pass by ref\n                } else {\n                    HereDoc.CanBeIndented = false;\n                }\n                if (isEOLChar(ch)) {\n                    // Bail out of doing a here doc if there's no target\n                    state = SCE_RB_DEFAULT;\n                    preferRE = false;\n                } else {\n                    HereDoc.Quote = ch;\n\n                    if (ch == '\\'' || ch == '\"' || ch == '`') {\n                        HereDoc.Quoted = true;\n                        HereDoc.Delimiter[0] = '\\0';\n                    } else {\n                        HereDoc.Quoted = false;\n                        HereDoc.Delimiter[0] = ch;\n                        HereDoc.Delimiter[1] = '\\0';\n                        HereDoc.DelimiterLength = 1;\n                    }\n                }\n            } else if (HereDoc.State == 1) { // collect the delimiter\n                if (isEOLChar(ch)) {\n                    // End the quote now, and go back for more\n                    styler.ColourTo(i - 1, state);\n                    state = SCE_RB_DEFAULT;\n                    i--;\n                    chNext = ch;\n                    preferRE = false;\n                } else if (HereDoc.Quoted) {\n                    if (ch == HereDoc.Quote) { // closing quote => end of delimiter\n                        styler.ColourTo(i, state);\n                        state = SCE_RB_DEFAULT;\n                        preferRE = false;\n                    } else {\n                        if (ch == '\\\\' && !isEOLChar(chNext)) {\n                            advance_char(i, ch, chNext, chNext2);\n                        }\n                        HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;\n                        HereDoc.Delimiter[HereDoc.DelimiterLength] = '\\0';\n                    }\n                } else { // an unquoted here-doc delimiter\n                    if (isSafeAlnumOrHigh(ch) || ch == '_') {\n                        HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;\n                        HereDoc.Delimiter[HereDoc.DelimiterLength] = '\\0';\n                    } else {\n                        styler.ColourTo(i - 1, state);\n                        redo_char(i, ch, chNext, chNext2, state);\n                        preferRE = false;\n                    }\n                }\n                if (HereDoc.DelimiterLength >= static_cast<int>(sizeof(HereDoc.Delimiter)) - 1) {\n                    styler.ColourTo(i - 1, state);\n                    state = SCE_RB_ERROR;\n                    preferRE = false;\n                }\n            }\n        } else if (state == SCE_RB_HERE_Q || state == SCE_RB_HERE_QQ || state == SCE_RB_HERE_QX) {\n            if (ch == '\\\\' && !isEOLChar(chNext)) {\n                advance_char(i, ch, chNext, chNext2);\n            } else if (ch == '#' && state != SCE_RB_HERE_Q\n                       && (chNext == '{' || chNext == '@' || chNext == '$')) {\n                if (chNext == '{') {\n                    if (innerExpr.canEnter()) {\n                        // process #{ ... }\n                        styler.ColourTo(i - 1, state);\n                        styler.ColourTo(i + 1, SCE_RB_OPERATOR);\n                        innerExpr.enter(state, Quote);\n                        preferRE = true;\n                        // Skip one\n                        advance_char(i, ch, chNext, chNext2);\n                    }\n                } else {\n                    InterpolateVariable(styler, state, i, ch, chNext, chNext2);\n                }\n            }\n\n            // Not needed: HereDoc.State == 2\n            // Indentable here docs: look backwards\n            // Non-indentable: look forwards, like in Perl\n            //\n            // Why: so we can quickly resolve things like <<-\" abc\"\n\n            else if (!HereDoc.CanBeIndented) {\n                if (isEOLChar(chPrev)\n                        && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) {\n                    styler.ColourTo(i - 1, state);\n                    i += static_cast<Sci_Position>(HereDoc.DelimiterLength) - 1;\n                    chNext = styler.SafeGetCharAt(i + 1);\n                    if (isEOLChar(chNext)) {\n                        styler.ColourTo(i, SCE_RB_HERE_DELIM);\n                        state = SCE_RB_DEFAULT;\n                        HereDoc.State = 0;\n                        preferRE = false;\n                    }\n                    // Otherwise we skipped through the here doc faster.\n                }\n            } else if (isEOLChar(chNext)\n                       && lookingAtHereDocDelim(styler,\n                                                i - HereDoc.DelimiterLength + 1,\n                                                lengthDoc,\n                                                HereDoc.Delimiter)) {\n                styler.ColourTo(i - HereDoc.DelimiterLength, state);\n                styler.ColourTo(i, SCE_RB_HERE_DELIM);\n                state = SCE_RB_DEFAULT;\n                preferRE = false;\n                HereDoc.State = 0;\n            }\n        } else if (state == SCE_RB_CLASS_VAR\n                   || state == SCE_RB_INSTANCE_VAR\n                   || state == SCE_RB_SYMBOL) {\n            if (state == SCE_RB_SYMBOL &&\n                    // FIDs suffices '?' and '!'\n                    (((ch == '!' || ch == '?') && chNext != '=') ||\n                     // identifier suffix '='\n                     (ch == '=' && (chNext != '~' && chNext != '>' &&\n                                    (chNext != '=' || chNext2 == '>'))))) {\n                styler.ColourTo(i, state);\n                state = SCE_RB_DEFAULT;\n                preferRE = false;\n            } else if (!isSafeWordcharOrHigh(ch)) {\n                styler.ColourTo(i - 1, state);\n                redo_char(i, ch, chNext, chNext2, state); // pass by ref\n                preferRE = false;\n            }\n        } else if (state == SCE_RB_GLOBAL) {\n            if (!isSafeWordcharOrHigh(ch)) {\n                // handle special globals here as well\n                if (chPrev == '$') {\n                    if (ch == '-') {\n                        // Include the next char, like $-a\n                        advance_char(i, ch, chNext, chNext2);\n                    }\n                    styler.ColourTo(i, state);\n                    state = SCE_RB_DEFAULT;\n                } else {\n                    styler.ColourTo(i - 1, state);\n                    redo_char(i, ch, chNext, chNext2, state); // pass by ref\n                }\n                preferRE = false;\n            }\n        } else if (state == SCE_RB_POD) {\n            // PODs end with ^=end\\s, -- any whitespace can follow =end\n            if (isWhiteSpace(ch)\n                    && i > 5\n                    && isEOLChar(styler[i - 5])\n                    && isMatch(styler, lengthDoc, i - 4, \"=end\")) {\n                styler.ColourTo(i - 1, state);\n                state = SCE_RB_DEFAULT;\n                preferRE = false;\n            }\n        } else if (state == SCE_RB_REGEX || state == SCE_RB_STRING_QR) {\n            if (ch == '\\\\' && Quote.Up != '\\\\') {\n                // Skip one\n                advance_char(i, ch, chNext, chNext2);\n            } else if (ch == Quote.Down) {\n                Quote.Count--;\n                if (Quote.Count == 0) {\n                    // Include the options\n                    while (isSafeAlpha(chNext)) {\n                        i++;\n                        ch = chNext;\n                        chNext = styler.SafeGetCharAt(i + 1);\n                    }\n                    styler.ColourTo(i, state);\n                    state = SCE_RB_DEFAULT;\n                    preferRE = false;\n                }\n            } else if (ch == Quote.Up) {\n                // Only if close quoter != open quoter\n                Quote.Count++;\n\n            } else if (ch == '#') {\n                if (chNext == '{') {\n                    if (innerExpr.canEnter()) {\n                        // process #{ ... }\n                        styler.ColourTo(i - 1, state);\n                        styler.ColourTo(i + 1, SCE_RB_OPERATOR);\n                        innerExpr.enter(state, Quote);\n                        preferRE = true;\n                        // Skip one\n                        advance_char(i, ch, chNext, chNext2);\n                    }\n                } else if (chNext == '@' || chNext == '$') {\n                    InterpolateVariable(styler, state, i, ch, chNext, chNext2);\n                } else {\n                    //todo: distinguish comments from pound chars\n                    // for now, handle as comment\n                    styler.ColourTo(i - 1, state);\n                    bool inEscape = false;\n                    while (++i < lengthDoc) {\n                        ch = styler.SafeGetCharAt(i);\n                        if (ch == '\\\\') {\n                            inEscape = true;\n                        } else if (isEOLChar(ch)) {\n                            // Comment inside a regex\n                            styler.ColourTo(i - 1, SCE_RB_COMMENTLINE);\n                            break;\n                        } else if (inEscape) {\n                            inEscape = false;  // don't look at char\n                        } else if (ch == Quote.Down) {\n                            // Have the regular handler deal with this\n                            // to get trailing modifiers.\n                            i--;\n                            ch = styler[i];\n                            break;\n                        }\n                    }\n                    chNext = styler.SafeGetCharAt(i + 1);\n                }\n            }\n            // Quotes of all kinds...\n        } else if (isPercentLiteral(state) ||\n                   state == SCE_RB_STRING || state == SCE_RB_CHARACTER ||\n                   state == SCE_RB_BACKTICKS) {\n            if (!Quote.Down && !isspacechar(ch)) {\n                Quote.Open(ch);\n            } else if (ch == '\\\\' && Quote.Up != '\\\\') {\n                //Riddle me this: Is it safe to skip *every* escaped char?\n                advance_char(i, ch, chNext, chNext2);\n            } else if (ch == Quote.Down) {\n                Quote.Count--;\n                if (Quote.Count == 0) {\n                    styler.ColourTo(i, state);\n                    state = SCE_RB_DEFAULT;\n                    preferRE = false;\n                }\n            } else if (ch == Quote.Up) {\n                Quote.Count++;\n            } else if (ch == '#' && isInterpolableLiteral(state)) {\n                if (chNext == '{') {\n                    if (innerExpr.canEnter()) {\n                        // process #{ ... }\n                        styler.ColourTo(i - 1, state);\n                        styler.ColourTo(i + 1, SCE_RB_OPERATOR);\n                        innerExpr.enter(state, Quote);\n                        preferRE = true;\n                        // Skip one\n                        advance_char(i, ch, chNext, chNext2);\n                    }\n                } else if (chNext == '@' || chNext == '$') {\n                    InterpolateVariable(styler, state, i, ch, chNext, chNext2);\n                }\n            }\n        }\n\n        if (state == SCE_RB_ERROR) {\n            break;\n        }\n        chPrev = ch;\n    }\n    if (state == SCE_RB_WORD) {\n        // We've ended on a word, possibly at EOF, and need to\n        // classify it.\n        ClassifyWordRb(lengthDoc, '\\0', '\\0', keywords, styler, prevWord, idClasser);\n    } else {\n        styler.ColourTo(lengthDoc - 1, state);\n    }\n    styler.Flush();\n}\n\n// Helper functions for folding, disambiguation keywords\n// Assert that there are no high-bit chars\n\nstd::string getPrevWord(Sci_Position pos, Accessor &styler, int word_state) {\n    Sci_Position i = pos - 1;\n    for (; i > 0; i--) {\n        if (styler.StyleIndexAt(i) != word_state) {\n            i++;\n            break;\n        }\n    }\n    std::string prevWord;\n    for (; i <= pos; i++) {\n        prevWord.push_back(styler[i]);\n    }\n    return prevWord;\n}\n\nbool keywordIsAmbiguous(const std::string &prevWord) noexcept {\n    // Order from most likely used to least likely\n    // Lots of ways to do a loop in Ruby besides 'while/until'\n    return InList(prevWord, { \"if\", \"do\", \"while\", \"unless\", \"until\", \"for\" });\n}\n\n// Demote keywords in the following conditions:\n// if, while, unless, until modify a statement\n// do after a while or until, as a noise word (like then after if)\n\nbool keywordIsModifier(const std::string &word, Sci_Position pos, Accessor &styler) {\n    if (word[0] == 'd' && word[1] == 'o' && !word[2]) {\n        return keywordDoStartsLoop(pos, styler);\n    }\n    int style = SCE_RB_DEFAULT;\n    Sci_Position lineStart = styler.GetLine(pos);\n    Sci_Position lineStartPosn = styler.LineStart(lineStart);\n    // We want to step backwards until we don't care about the current\n    // position. But first move lineStartPosn back behind any\n    // continuations immediately above word.\n    while (lineStartPosn > 0) {\n        const char ch = styler[lineStartPosn-1];\n        if (ch == '\\n' || ch == '\\r') {\n            const char chPrev  = styler.SafeGetCharAt(lineStartPosn-2);\n            const char chPrev2 = styler.SafeGetCharAt(lineStartPosn-3);\n            lineStart = styler.GetLine(lineStartPosn-1);\n            // If we find a continuation line, include it in our analysis.\n            if (chPrev == '\\\\') {\n                lineStartPosn = styler.LineStart(lineStart);\n            } else if (ch == '\\n' && chPrev == '\\r' && chPrev2 == '\\\\') {\n                lineStartPosn = styler.LineStart(lineStart);\n            } else {\n                break;\n            }\n        } else {\n            break;\n        }\n    }\n\n    styler.Flush();\n    while (--pos >= lineStartPosn) {\n        style = styler.StyleIndexAt(pos);\n        if (style == SCE_RB_DEFAULT) {\n            const char ch = styler[pos];\n            if (IsASpaceOrTab(ch)) {\n                //continue\n            } else if (ch == '\\r' || ch == '\\n') {\n                // Scintilla's LineStart() and GetLine() routines aren't\n                // platform-independent, so if we have text prepared with\n                // a different system we can't rely on it.\n\n                // Also, lineStartPosn may have been moved to more than one\n                // line above word's line while pushing past continuations.\n                const char chPrev = styler.SafeGetCharAt(pos - 1);\n                const char chPrev2 = styler.SafeGetCharAt(pos - 2);\n                if (chPrev == '\\\\') {\n                    pos-=1;  // gloss over the \"\\\\\"\n                    //continue\n                } else if (ch == '\\n' && chPrev == '\\r' && chPrev2 == '\\\\') {\n                    pos-=2;  // gloss over the \"\\\\\\r\"\n                    //continue\n                } else {\n                    return false;\n                }\n            }\n        } else {\n            break;\n        }\n    }\n    if (pos < lineStartPosn) {\n        return false;\n    }\n    // First things where the action is unambiguous\n    switch (style) {\n    case SCE_RB_DEFAULT:\n    case SCE_RB_COMMENTLINE:\n    case SCE_RB_POD:\n    case SCE_RB_CLASSNAME:\n    case SCE_RB_DEFNAME:\n    case SCE_RB_MODULE_NAME:\n        return false;\n    case SCE_RB_OPERATOR:\n        break;\n    case SCE_RB_WORD:\n        // Watch out for uses of 'else if'\n        //XXX: Make a list of other keywords where 'if' isn't a modifier\n        //     and can appear legitimately\n        // Formulate this to avoid warnings from most compilers\n        if (word == \"if\") {\n            const std::string prevWord = getPrevWord(pos, styler, SCE_RB_WORD);\n            return prevWord != \"else\";\n        }\n        return true;\n    default:\n        return true;\n    }\n    // Assume that if the keyword follows an operator,\n    // usually it's a block assignment, like\n    // a << if x then y else z\n\n    switch (styler[pos]) {\n    case ')':\n    case ']':\n    case '}':\n        return true;\n    default:\n        return false;\n    }\n}\n\n#define WHILE_BACKWARDS \"elihw\"\n#define UNTIL_BACKWARDS \"litnu\"\n#define FOR_BACKWARDS \"rof\"\n\n// Nothing fancy -- look to see if we follow a while/until somewhere\n// on the current line\n\nbool keywordDoStartsLoop(Sci_Position pos, Accessor &styler) {\n    const Sci_Position lineStart = styler.GetLine(pos);\n    const Sci_Position lineStartPosn = styler.LineStart(lineStart);\n    styler.Flush();\n    while (--pos >= lineStartPosn) {\n        const int style = styler.StyleIndexAt(pos);\n        if (style == SCE_RB_DEFAULT) {\n            const char ch = styler[pos];\n            if (ch == '\\r' || ch == '\\n') {\n                // Scintilla's LineStart() and GetLine() routines aren't\n                // platform-independent, so if we have text prepared with\n                // a different system we can't rely on it.\n                return false;\n            }\n        } else if (style == SCE_RB_WORD) {\n            // Check for while or until, but write the word in backwards\n            std::string prevWord;\n            Sci_Position start_word = pos;\n            for (;\n                    start_word >= lineStartPosn && styler.StyleIndexAt(start_word) == SCE_RB_WORD;\n                    start_word--) {\n                prevWord.push_back(styler[start_word]);\n            }\n            // Did we see our keyword?\n            if (InList(prevWord, { WHILE_BACKWARDS, UNTIL_BACKWARDS, FOR_BACKWARDS } )) {\n                return true;\n            }\n            // We can move pos to the beginning of the keyword, and then\n            // accept another decrement, as we can never have two contiguous\n            // keywords:\n            // word1 word2\n            //           ^\n            //        <-  move to start_word\n            //      ^\n            //      <- loop decrement\n            //     ^  # pointing to end of word1 is fine\n            pos = start_word;\n        }\n    }\n    return false;\n}\n\nbool IsCommentLine(Sci_Position line, Accessor &styler) {\n    const Sci_Position pos = styler.LineStart(line);\n    const Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n    for (Sci_Position i = pos; i < eol_pos; i++) {\n        const char ch = styler[i];\n        if (ch == '#')\n            return true;\n        else if (ch != ' ' && ch != '\\t')\n            return false;\n    }\n    return false;\n}\n\n/*\n *  Folding Ruby\n *\n *  The language is quite complex to analyze without a full parse.\n *  For example, this line shouldn't affect fold level:\n *\n *   print \"hello\" if feeling_friendly?\n *\n *  Neither should this:\n *\n *   print \"hello\" \\\n *      if feeling_friendly?\n *\n *\n *  But this should:\n *\n *   if feeling_friendly?  #++\n *     print \"hello\" \\\n *     print \"goodbye\"\n *   end                   #--\n *\n *  So we cheat, by actually looking at the existing indentation\n *  levels for each line, and just echoing it back.  Like Python.\n *  Then if we get better at it, we'll take braces into consideration,\n *  which always affect folding levels.\n\n *  How the keywords should work:\n *  No effect:\n *  __FILE__ __LINE__ BEGIN END alias and\n *  defined? false in nil not or self super then\n *  true undef\n\n *  Always increment:\n *  begin  class def do for module when {\n *\n *  Always decrement:\n *  end }\n *\n *  Increment if these start a statement\n *  if unless until while -- do nothing if they're modifiers\n\n *  These end a block if there's no modifier, but don't bother\n *  break next redo retry return yield\n *\n *  These temporarily de-indent, but re-indent\n *  case else elsif ensure rescue\n *\n *  This means that the folder reflects indentation rather\n *  than setting it.  The language-service updates indentation\n *  when users type return and finishes entering de-denters.\n *\n *  Later offer to fold POD, here-docs, strings, and blocks of comments\n */\n\nvoid LexerRuby::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n    Accessor styler(pAccess, nullptr);\n\n    synchronizeDocStart(startPos, length, initStyle, styler, false);\n    const Sci_PositionU endPos = startPos + length;\n    int visibleChars = 0;\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int levelPrev = startPos == 0 ? 0 : (styler.LevelAt(lineCurrent)\n                                         & SC_FOLDLEVELNUMBERMASK\n                                         & ~SC_FOLDLEVELBASE);\n    int levelCurrent = levelPrev;\n    char chPrev = '\\0';\n    char chNext = styler[startPos];\n    int styleNext = styler.StyleIndexAt(startPos);\n    int stylePrev = startPos <= 1 ? SCE_RB_DEFAULT : styler.StyleIndexAt(startPos - 1);\n    // detect endless method definition to fix up code folding\n    enum class MethodDefinition {\n        None,\n        Define,\n        Operator,\n        Name,\n        Argument,\n    };\n    MethodDefinition method_definition = MethodDefinition::None;\n    int argument_paren_count = 0;\n    bool heredocOpen = false;\n\n    for (Sci_PositionU i = startPos; i < endPos; i++) {\n        const char ch = chNext;\n        chNext = styler.SafeGetCharAt(i + 1);\n        const int style = styleNext;\n        styleNext = styler.StyleIndexAt(i + 1);\n        const bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n        /* Multiline comment patch */\n        if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {\n            if (!IsCommentLine(lineCurrent - 1, styler)\n                    && IsCommentLine(lineCurrent + 1, styler))\n                levelCurrent++;\n            else if (IsCommentLine(lineCurrent - 1, styler)\n                     && !IsCommentLine(lineCurrent + 1, styler))\n                levelCurrent--;\n        }\n\n        if (style == SCE_RB_COMMENTLINE) {\n            if (options.foldComment && stylePrev != SCE_RB_COMMENTLINE) {\n                if (chNext == '{') {\n                    levelCurrent++;\n                } else if (chNext == '}' && levelCurrent > 0) {\n                    levelCurrent--;\n                }\n            }\n        } else if (style == SCE_RB_OPERATOR) {\n            if (AnyOf(ch, '[', '{', '(')) {\n                levelCurrent++;\n            } else if (AnyOf(ch, ']', '}', ')')) {\n                // Don't decrement below 0\n                if (levelCurrent > 0)\n                    levelCurrent--;\n            }\n        } else if (style == SCE_RB_WORD && styleNext != SCE_RB_WORD) {\n            // Look at the keyword on the left and decide what to do\n            const std::string prevWord = getPrevWord(i, styler, SCE_RB_WORD);\n            if (prevWord == \"end\") {\n                // Don't decrement below 0\n                if (levelCurrent > 0)\n                    levelCurrent--;\n            } else if (prevWord == \"def\") {\n                levelCurrent++;\n                method_definition = MethodDefinition::Define;\n\t\t\t} else if (InList(prevWord, {\n                    \"if\",\n                    \"class\",\n                    \"module\",\n                    \"begin\",\n                    \"case\",\n                    \"do\",\n                    \"while\",\n                    \"unless\",\n                    \"until\",\n                    \"for\"\n\t\t\t\t})) {\n\t\t\t\tlevelCurrent++;\n\t\t\t}\n        } else if (style == SCE_RB_HERE_DELIM && !heredocOpen) {\n            if (stylePrev == SCE_RB_OPERATOR && chPrev == '<' && styler.SafeGetCharAt(i - 2) == '<') {\n                levelCurrent++;\n                heredocOpen = true;\n            } else if (styleNext != SCE_RB_HERE_DELIM) {\n                levelCurrent--;\n            }\n        } else if (style == SCE_RB_STRING_QW || style == SCE_RB_STRING_W) {\n            if (stylePrev != style) {\n                levelCurrent++;\n            }\n            if (styleNext != style) {\n                levelCurrent--;\n            }\n        }\n        if (method_definition != MethodDefinition::None) {\n            switch (method_definition) {\n            case MethodDefinition::Define:\n                if (style == SCE_RB_OPERATOR) {\n                    method_definition = MethodDefinition::Operator;\n                } else if (style == SCE_RB_DEFNAME || style == SCE_RB_WORD_DEMOTED || style == SCE_RB_CLASSNAME || IsIdentifierStyle(style)) {\n                    method_definition = MethodDefinition::Name;\n                } else if (!(style == SCE_RB_WORD || IsASpaceOrTab(ch))) {\n                    method_definition = MethodDefinition::None;\n                }\n                if (method_definition <= MethodDefinition::Define) {\n                    break;\n                }\n                // fall through for unary operator or single letter name\n                [[fallthrough]];\n            case MethodDefinition::Operator:\n            case MethodDefinition::Name:\n                if (isEOLChar(chNext) || chNext == '#') {\n                    method_definition = MethodDefinition::None;\n                } else if (chNext == '(' || chNext <= ' ') {\n                    // setter method cannot be defined in an endless method definition.\n                    if (ch == '=' && (method_definition == MethodDefinition::Name || chPrev == ']')) {\n                        method_definition = MethodDefinition::None;\n                    } else {\n                        method_definition = MethodDefinition::Argument;\n                        argument_paren_count = 0;\n                    }\n                }\n                break;\n            case MethodDefinition::Argument:\n                if (style == SCE_RB_OPERATOR) {\n                    if (ch == '(') {\n                        ++argument_paren_count;\n                    } else if (ch == ')') {\n                        --argument_paren_count;\n                    } else if (argument_paren_count == 0) {\n                        method_definition = MethodDefinition::None;\n                        if (ch == '=' && levelCurrent > 0) {\n                            levelCurrent--;\n                        }\n                    }\n                } else if (argument_paren_count == 0 && !IsASpaceOrTab(ch)) {\n                    // '=' must be first character after method name or right parenthesis\n                    method_definition = MethodDefinition::None;\n                }\n                break;\n            default:\n                break;\n            }\n        }\n        if (atEOL || (i == endPos - 1)) {\n            int lev = levelPrev;\n            if (visibleChars == 0 && options.foldCompact)\n                lev |= SC_FOLDLEVELWHITEFLAG;\n            if ((levelCurrent > levelPrev) && (visibleChars > 0))\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            styler.SetLevel(lineCurrent, lev|SC_FOLDLEVELBASE);\n            lineCurrent++;\n            levelPrev = levelCurrent;\n            visibleChars = 0;\n            method_definition = MethodDefinition::None;\n            argument_paren_count = 0;\n            heredocOpen = false;\n        } else if (!isspacechar(ch)) {\n            visibleChars++;\n        }\n        chPrev = ch;\n        stylePrev = style;\n    }\n}\n\n}\n\nextern const LexerModule lmRuby(SCLEX_RUBY, LexerRuby::LexerFactoryRuby, \"ruby\", rubyWordListDesc);\n"
  },
  {
    "path": "lexers/LexRust.cxx",
    "content": "/** @file LexRust.cxx\n ** Lexer for Rust.\n **\n ** Copyright (c) 2013 by SiegeLord <slabode@aim.com>\n ** Converted to lexer object and added further folding features/properties by \"Udo Lechner\" <dlchnr(at)gmx(dot)net>\n **/\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\nconstexpr int NUM_RUST_KEYWORD_LISTS = 7;\nconstexpr int MAX_RUST_IDENT_CHARS = 1023;\n\n\nenum class StringType : int {\n\tSTRING = SCE_RUST_STRING,\n\tBYTESTRING = SCE_RUST_BYTESTRING,\n\tCSTRING = SCE_RUST_CSTRING,\n\n\tRAW_STRING = SCE_RUST_STRINGR,\n\tRAW_BYTESTRING = SCE_RUST_BYTESTRINGR,\n\tRAW_CSTRING = SCE_RUST_CSTRINGR\n};\n\nstatic bool IsStreamCommentStyle(int style) noexcept {\n\treturn style == SCE_RUST_COMMENTBLOCK ||\n\t\t   style == SCE_RUST_COMMENTBLOCKDOC;\n}\n\n// Options used for LexerRust\nstruct OptionsRust {\n\tbool fold;\n\tbool foldSyntaxBased;\n\tbool foldComment;\n\tbool foldCommentMultiline;\n\tbool foldCommentExplicit;\n\tstd::string foldExplicitStart;\n\tstd::string foldExplicitEnd;\n\tbool foldExplicitAnywhere;\n\tbool foldCompact;\n\tint  foldAtElseInt;\t// This variable is not used\n\tbool foldAtElse;\n\tOptionsRust() {\n\t\tfold = false;\n\t\tfoldSyntaxBased = true;\n\t\tfoldComment = false;\n\t\tfoldCommentMultiline = true;\n\t\tfoldCommentExplicit = true;\n\t\tfoldExplicitStart = \"\";\n\t\tfoldExplicitEnd   = \"\";\n\t\tfoldExplicitAnywhere = false;\n\t\tfoldCompact = true;\n\t\tfoldAtElseInt = -1;\n\t\tfoldAtElse = false;\n\t}\n};\n\nstatic const char * const rustWordLists[NUM_RUST_KEYWORD_LISTS + 1] = {\n\t\"Primary keywords and identifiers\",\n\t\"Built in types\",\n\t\"Other keywords\",\n\t\"Keywords 4\",\n\t\"Keywords 5\",\n\t\"Keywords 6\",\n\t\"Keywords 7\",\n\tnullptr,\n};\n\nstruct OptionSetRust : public OptionSet<OptionsRust> {\n\tOptionSetRust() {\n\t\tDefineProperty(\"fold\", &OptionsRust::fold);\n\n\t\tDefineProperty(\"fold.comment\", &OptionsRust::foldComment);\n\n\t\tDefineProperty(\"fold.compact\", &OptionsRust::foldCompact);\n\n\t\tDefineProperty(\"fold.at.else\", &OptionsRust::foldAtElse);\n\n\t\tDefineProperty(\"fold.rust.syntax.based\", &OptionsRust::foldSyntaxBased,\n\t\t\t\"Set this property to 0 to disable syntax based folding.\");\n\n\t\tDefineProperty(\"fold.rust.comment.multiline\", &OptionsRust::foldCommentMultiline,\n\t\t\t\"Set this property to 0 to disable folding multi-line comments when fold.comment=1.\");\n\n\t\tDefineProperty(\"fold.rust.comment.explicit\", &OptionsRust::foldCommentExplicit,\n\t\t\t\"Set this property to 0 to disable folding explicit fold points when fold.comment=1.\");\n\n\t\tDefineProperty(\"fold.rust.explicit.start\", &OptionsRust::foldExplicitStart,\n\t\t\t\"The string to use for explicit fold start points, replacing the standard //{.\");\n\n\t\tDefineProperty(\"fold.rust.explicit.end\", &OptionsRust::foldExplicitEnd,\n\t\t\t\"The string to use for explicit fold end points, replacing the standard //}.\");\n\n\t\tDefineProperty(\"fold.rust.explicit.anywhere\", &OptionsRust::foldExplicitAnywhere,\n\t\t\t\"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\");\n\n\t\tDefineProperty(\"lexer.rust.fold.at.else\", &OptionsRust::foldAtElseInt,\n\t\t\t\"This option enables Rust folding on a \\\"} else {\\\" line of an if statement.\");\n\n\t\tDefineWordListSets(rustWordLists);\n\t}\n};\n\nconst LexicalClass lexicalClasses[] = {\n\t// Lexer rust SCLEX_RUST SCE_RUST_:\n\t0, \"SCE_RUST_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_RUST_COMMENTBLOCK\", \"comment\", \"Comment\",\n\t2, \"SCE_RUST_COMMENTLINE\", \"comment line\", \"Line comment\",\n\t3, \"SCE_RUST_COMMENTBLOCKDOC\", \"comment documentation\", \"Doc comment\",\n\t4, \"SCE_RUST_COMMENTLINEDOC\", \"comment documentation line\", \"Doc comment line\",\n\t5, \"SCE_RUST_NUMBER\", \"literal numeric\", \"Number\",\n\t6, \"SCE_RUST_WORD\", \"keyword\", \"Keywords\",\n\t7, \"SCE_RUST_WORD2\", \"identifier\", \"Keywords 2\",\n\t8, \"SCE_RUST_WORD3\", \"identifier\", \"Keywords 3\",\n\t9, \"SCE_RUST_WORD4\", \"identifier\", \"Keywords 4\",\n\t10, \"SCE_RUST_WORD5\", \"identifier\", \"Keywords 5\",\n\t11, \"SCE_RUST_WORD6\", \"identifier\", \"Keywords 6\",\n\t12, \"SCE_RUST_WORD7\", \"identifier\", \"Keywords 7\",\n\t13, \"SCE_RUST_STRING\", \"literal string\", \"Regular string\",\n\t14, \"SCE_RUST_STRINGR\", \"literal string raw\", \"Raw string\",\n\t15, \"SCE_RUST_CHARACTER\", \"literal string character\", \"Character\",\n\t16, \"SCE_RUST_OPERATOR\", \"operator\", \"Operator\",\n\t17, \"SCE_RUST_IDENTIFIER\", \"identifier\", \"Identifier\",\n\t18, \"SCE_RUST_LIFETIME\", \"annotation\", \"Lifetime\",\n\t19, \"SCE_RUST_MACRO\", \"macro preprocessor\", \"Macro\",\n\t20, \"SCE_RUST_LEXERROR\", \"error\", \"Lexical error\",\n\t21, \"SCE_RUST_BYTESTRING\", \"literal string\", \"Byte string\",\n\t22, \"SCE_RUST_BYTESTRINGR\", \"literal string raw\", \"Raw byte string\",\n\t23, \"SCE_RUST_BYTECHARACTER\", \"literal string character\", \"Byte character\",\n\t24, \"SCE_RUST_CSTRING\", \"literal string\", \"C string\",\n\t25, \"SCE_RUST_CSTRINGR\", \"literal string raw\", \"Raw C string\",\n};\n\nclass LexerRust : public DefaultLexer {\n\tWordList keywords[NUM_RUST_KEYWORD_LISTS];\n\tOptionsRust options;\n\tOptionSetRust osRust;\npublic:\n\tLexerRust() : DefaultLexer(\"rust\", SCLEX_RUST, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\tvirtual ~LexerRust() {\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char * SCI_METHOD PropertyNames() override {\n\t\treturn osRust.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osRust.PropertyType(name);\n\t}\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osRust.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osRust.PropertyGet(key);\n\t}\n\tconst char * SCI_METHOD DescribeWordListSets() override {\n\t\treturn osRust.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid * SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn nullptr;\n\t}\n\tstatic ILexer5 *LexerFactoryRust() {\n\t\treturn new LexerRust();\n\t}\n};\n\nSci_Position SCI_METHOD LexerRust::PropertySet(const char *key, const char *val) {\n\tif (osRust.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerRust::WordListSet(int n, const char *wl) {\n\tSci_Position firstModification = -1;\n\tif (n < NUM_RUST_KEYWORD_LISTS) {\n\t\tWordList *wordListN = &keywords[n];\n\t\tif (wordListN->Set(wl)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nstatic bool IsWhitespace(int c) {\n    return c == ' ' || c == '\\t' || c == '\\r' || c == '\\n';\n}\n\n/* This isn't quite right for Unicode identifiers */\nstatic bool IsIdentifierStart(int ch) {\n\treturn (IsASCII(ch) && (isalpha(ch) || ch == '_')) || !IsASCII(ch);\n}\n\n/* This isn't quite right for Unicode identifiers */\nstatic bool IsIdentifierContinue(int ch) {\n\treturn (IsASCII(ch) && (isalnum(ch) || ch == '_')) || !IsASCII(ch);\n}\n\nstatic void ScanWhitespace(Accessor& styler, Sci_Position& pos, Sci_Position max) {\n\twhile (IsWhitespace(styler.SafeGetCharAt(pos, '\\0')) && pos < max) {\n\t\tif (pos == styler.LineEnd(styler.GetLine(pos)))\n\t\t\tstyler.SetLineState(styler.GetLine(pos), 0);\n\t\tpos++;\n\t}\n\tstyler.ColourTo(pos-1, SCE_RUST_DEFAULT);\n}\n\nstatic void GrabString(char* s, Accessor& styler, Sci_Position start, Sci_Position len) {\n\tfor (Sci_Position ii = 0; ii < len; ii++)\n\t\ts[ii] = styler[ii + start];\n\ts[len] = '\\0';\n}\n\nstatic void ScanRawIdentifier(Accessor& styler, Sci_Position& pos) {\n\tconst Sci_Position start = pos;\n\twhile (IsIdentifierContinue(styler.SafeGetCharAt(pos, '\\0')))\n\t\tpos++;\n\n\tchar s[MAX_RUST_IDENT_CHARS + 1];\n\tSci_Position len = pos - start;\n\tlen = len > MAX_RUST_IDENT_CHARS ? MAX_RUST_IDENT_CHARS : len;\n\tGrabString(s, styler, start, len);\n\t// restricted values https://doc.rust-lang.org/reference/identifiers.html#raw-identifiers\n\tif (strcmp(s, \"crate\") != 0 && strcmp(s, \"self\") != 0 &&\n\t\tstrcmp(s, \"super\") != 0 && strcmp(s, \"Self\") != 0) {\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_IDENTIFIER);\n\t} else {\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_LEXERROR);\n\t}\n}\n\nstatic void ScanIdentifier(Accessor& styler, Sci_Position& pos, WordList *keywords) {\n\tconst Sci_Position start = pos;\n\twhile (IsIdentifierContinue(styler.SafeGetCharAt(pos, '\\0')))\n\t\tpos++;\n\n\tif (styler.SafeGetCharAt(pos, '\\0') == '!') {\n\t\tpos++;\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_MACRO);\n\t} else {\n\t\tchar s[MAX_RUST_IDENT_CHARS + 1];\n\t\tSci_Position len = pos - start;\n\t\tlen = len > MAX_RUST_IDENT_CHARS ? MAX_RUST_IDENT_CHARS : len;\n\t\tGrabString(s, styler, start, len);\n\t\tbool keyword = false;\n\t\tfor (int ii = 0; ii < NUM_RUST_KEYWORD_LISTS; ii++) {\n\t\t\tif (keywords[ii].InList(s)) {\n\t\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_WORD + ii);\n\t\t\t\tkeyword = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!keyword) {\n\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_IDENTIFIER);\n\t\t}\n\t}\n}\n\n/* Scans a sequence of digits, returning true if it found any. */\nstatic bool ScanDigits(Accessor& styler, Sci_Position& pos, int base) {\n\tconst Sci_Position old_pos = pos;\n\tfor (;;) {\n\t\tconst int c = styler.SafeGetCharAt(pos, '\\0');\n\t\tif (IsADigit(c, base) || c == '_')\n\t\t\tpos++;\n\t\telse\n\t\t\tbreak;\n\t}\n\treturn old_pos != pos;\n}\n\n/* Scans an integer and floating point literals. */\nstatic void ScanNumber(Accessor& styler, Sci_Position& pos) {\n\tint base = 10;\n\tint c = styler.SafeGetCharAt(pos, '\\0');\n\tint n = styler.SafeGetCharAt(pos + 1, '\\0');\n\tbool error = false;\n\t/* Scan the prefix, thus determining the base.\n\t * 10 is default if there's no prefix. */\n\tif (c == '0' && n == 'x') {\n\t\tpos += 2;\n\t\tbase = 16;\n\t} else if (c == '0' && n == 'b') {\n\t\tpos += 2;\n\t\tbase = 2;\n\t} else if (c == '0' && n == 'o') {\n\t\tpos += 2;\n\t\tbase = 8;\n\t}\n\n\t/* Scan initial digits. The literal is malformed if there are none. */\n\terror |= !ScanDigits(styler, pos, base);\n\t/* See if there's an integer suffix. We mimic the Rust's lexer\n\t * and munch it even if there was an error above. */\n\tc = styler.SafeGetCharAt(pos, '\\0');\n\tif (c == 'u' || c == 'i') {\n\t\tpos++;\n\t\tc = styler.SafeGetCharAt(pos, '\\0');\n\t\tn = styler.SafeGetCharAt(pos + 1, '\\0');\n\t\tif (c == '8') {\n\t\t\tpos++;\n\t\t} else if (c == '1' && n == '6') {\n\t\t\tpos += 2;\n\t\t} else if (c == '3' && n == '2') {\n\t\t\tpos += 2;\n\t\t} else if (c == '6' && n == '4') {\n\t\t\tpos += 2;\n\t\t} else if (styler.Match(pos, \"128\")) {\n\t\t\tpos += 3;\n\t\t} else if (styler.Match(pos, \"size\")) {\n\t\t\tpos += 4;\n\t\t} else {\n\t\t\terror = true;\n\t\t}\n\t/* See if it's a floating point literal. These literals have to be base 10.\n\t */\n\t} else if (!error) {\n\t\t/* If there's a period, it's a floating point literal unless it's\n\t\t * followed by an identifier (meaning this is a method call, e.g.\n\t\t * `1.foo()`) or another period, in which case it's a range (e.g. 1..2)\n\t\t */\n\t\tn = styler.SafeGetCharAt(pos + 1, '\\0');\n\t\tif (c == '.' && !(IsIdentifierStart(n) || n == '.')) {\n\t\t\terror |= base != 10;\n\t\t\tpos++;\n\t\t\t/* It's ok to have no digits after the period. */\n\t\t\tScanDigits(styler, pos, 10);\n\t\t}\n\n\t\t/* Look for the exponentiation. */\n\t\tc = styler.SafeGetCharAt(pos, '\\0');\n\t\tif (c == 'e' || c == 'E') {\n\t\t\terror |= base != 10;\n\t\t\tpos++;\n\t\t\tc = styler.SafeGetCharAt(pos, '\\0');\n\t\t\tif (c == '-' || c == '+')\n\t\t\t\tpos++;\n\t\t\t/* It is invalid to have no digits in the exponent. */\n\t\t\terror |= !ScanDigits(styler, pos, 10);\n\t\t}\n\n\t\t/* Scan the floating point suffix. */\n\t\tc = styler.SafeGetCharAt(pos, '\\0');\n\t\tif (c == 'f') {\n\t\t\terror |= base != 10;\n\t\t\tpos++;\n\t\t\tc = styler.SafeGetCharAt(pos, '\\0');\n\t\t\tn = styler.SafeGetCharAt(pos + 1, '\\0');\n\t\t\tif (c == '3' && n == '2') {\n\t\t\t\tpos += 2;\n\t\t\t} else if (c == '6' && n == '4') {\n\t\t\t\tpos += 2;\n\t\t\t} else {\n\t\t\t\terror = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (error)\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_LEXERROR);\n\telse\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_NUMBER);\n}\n\nstatic bool IsOneCharOperator(int c) {\n\treturn c == ';' || c == ',' || c == '(' || c == ')'\n\t    || c == '{' || c == '}' || c == '[' || c == ']'\n\t    || c == '@' || c == '#' || c == '~' || c == '+'\n\t    || c == '*' || c == '/' || c == '^' || c == '%'\n\t    || c == '.' || c == ':' || c == '!' || c == '<'\n\t    || c == '>' || c == '=' || c == '-' || c == '&'\n\t    || c == '|' || c == '$' || c == '?';\n}\n\nstatic bool IsTwoCharOperator(int c, int n) {\n\treturn (c == '.' && n == '.') || (c == ':' && n == ':')\n\t    || (c == '!' && n == '=') || (c == '<' && n == '<')\n\t    || (c == '<' && n == '=') || (c == '>' && n == '>')\n\t    || (c == '>' && n == '=') || (c == '=' && n == '=')\n\t    || (c == '=' && n == '>') || (c == '-' && n == '>')\n\t    || (c == '&' && n == '&') || (c == '|' && n == '|')\n\t    || (c == '-' && n == '=') || (c == '&' && n == '=')\n\t    || (c == '|' && n == '=') || (c == '+' && n == '=')\n\t    || (c == '*' && n == '=') || (c == '/' && n == '=')\n\t    || (c == '^' && n == '=') || (c == '%' && n == '=');\n}\n\nstatic bool IsThreeCharOperator(int c, int n, int n2) {\n\treturn (c == '<' && n == '<' && n2 == '=')\n\t    || (c == '>' && n == '>' && n2 == '=');\n}\n\nstatic bool IsValidCharacterEscape(int c) {\n\treturn c == 'n'  || c == 'r' || c == 't' || c == '\\\\'\n\t    || c == '\\'' || c == '\"' || c == '0';\n}\n\nstatic bool IsValidStringEscape(int c) {\n\treturn IsValidCharacterEscape(c) || c == '\\n' || c == '\\r';\n}\n\nstatic bool ScanNumericEscape(Accessor &styler, Sci_Position& pos, Sci_Position num_digits, bool stop_asap) {\n\tfor (;;) {\n\t\tconst int c = styler.SafeGetCharAt(pos, '\\0');\n\t\tif (!IsADigit(c, 16))\n\t\t\tbreak;\n\t\tnum_digits--;\n\t\tpos++;\n\t\tif (num_digits == 0 && stop_asap)\n\t\t\treturn true;\n\t}\n\tif (num_digits == 0) {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n}\n\n/* This is overly permissive for character literals in order to accept UTF-8 encoded\n * character literals. */\nstatic void ScanCharacterLiteralOrLifetime(Accessor &styler, Sci_Position& pos, bool ascii_only) {\n\tpos++;\n\tint c = styler.SafeGetCharAt(pos, '\\0');\n\tint n = styler.SafeGetCharAt(pos + 1, '\\0');\n\tbool done = false;\n\tbool valid_lifetime = !ascii_only && IsIdentifierStart(c);\n\tbool valid_char = true;\n\tbool first = true;\n\twhile (!done) {\n\t\tswitch (c) {\n\t\t\tcase '\\\\':\n\t\t\t\tdone = true;\n\t\t\t\tif (IsValidCharacterEscape(n)) {\n\t\t\t\t\tpos += 2;\n\t\t\t\t} else if (n == 'x') {\n\t\t\t\t\tpos += 2;\n\t\t\t\t\tvalid_char = ScanNumericEscape(styler, pos, 2, false);\n\t\t\t\t} else if (n == 'u' && !ascii_only) {\n\t\t\t\t\tpos += 2;\n\t\t\t\t\tif (styler.SafeGetCharAt(pos, '\\0') != '{') {\n\t\t\t\t\t\t// old-style\n\t\t\t\t\t\tvalid_char = ScanNumericEscape(styler, pos, 4, false);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tint n_digits = 0;\n\t\t\t\t\t\twhile (IsADigit(styler.SafeGetCharAt(++pos, '\\0'), 16) && n_digits++ < 6) {\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n_digits > 0 && styler.SafeGetCharAt(pos, '\\0') == '}')\n\t\t\t\t\t\t\tpos++;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tvalid_char = false;\n\t\t\t\t\t}\n\t\t\t\t} else if (n == 'U' && !ascii_only) {\n\t\t\t\t\tpos += 2;\n\t\t\t\t\tvalid_char = ScanNumericEscape(styler, pos, 8, false);\n\t\t\t\t} else {\n\t\t\t\t\tvalid_char = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '\\'':\n\t\t\t\tvalid_char = !first;\n\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\t\t\tcase '\\t':\n\t\t\tcase '\\n':\n\t\t\tcase '\\r':\n\t\t\tcase '\\0':\n\t\t\t\tvalid_char = false;\n\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (ascii_only && !IsASCII((char)c)) {\n\t\t\t\t\tdone = true;\n\t\t\t\t\tvalid_char = false;\n\t\t\t\t} else if (!IsIdentifierContinue(c) && !first) {\n\t\t\t\t\tdone = true;\n\t\t\t\t} else {\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\tc = styler.SafeGetCharAt(pos, '\\0');\n\t\tn = styler.SafeGetCharAt(pos + 1, '\\0');\n\n\t\tfirst = false;\n\t}\n\tif (styler.SafeGetCharAt(pos, '\\0') == '\\'') {\n\t\tvalid_lifetime = false;\n\t} else {\n\t\tvalid_char = false;\n\t}\n\tif (valid_lifetime) {\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_LIFETIME);\n\t} else if (valid_char) {\n\t\tpos++;\n\t\tstyler.ColourTo(pos - 1, ascii_only ? SCE_RUST_BYTECHARACTER : SCE_RUST_CHARACTER);\n\t} else {\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_LEXERROR);\n\t}\n}\n\nenum CommentState {\n\tUnknownComment,\n\tDocComment,\n\tNotDocComment\n};\n\n/*\n * The rule for block-doc comments is as follows: /xxN and /x! (where x is an asterisk, N is a non-asterisk) start doc comments.\n * Otherwise it's a regular comment.\n */\nstatic void ResumeBlockComment(Accessor &styler, Sci_Position& pos, Sci_Position max, CommentState state, int level) {\n\tint c = styler.SafeGetCharAt(pos, '\\0');\n\tbool maybe_doc_comment = false;\n\tif (c == '*') {\n\t\tconst int n = styler.SafeGetCharAt(pos + 1, '\\0');\n\t\tif (n != '*' && n != '/') {\n\t\t\tmaybe_doc_comment = true;\n\t\t}\n\t} else if (c == '!') {\n\t\tmaybe_doc_comment = true;\n\t}\n\n\tfor (;;) {\n\t\tconst int n = styler.SafeGetCharAt(pos + 1, '\\0');\n\t\tif (pos == styler.LineEnd(styler.GetLine(pos)))\n\t\t\tstyler.SetLineState(styler.GetLine(pos), level);\n\t\tif (c == '*') {\n\t\t\tpos++;\n\t\t\tif (n == '/') {\n\t\t\t\tpos++;\n\t\t\t\tlevel--;\n\t\t\t\tif (level == 0) {\n\t\t\t\t\tstyler.SetLineState(styler.GetLine(pos), 0);\n\t\t\t\t\tif (state == DocComment || (state == UnknownComment && maybe_doc_comment))\n\t\t\t\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCKDOC);\n\t\t\t\t\telse\n\t\t\t\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCK);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (c == '/') {\n\t\t\tpos++;\n\t\t\tif (n == '*') {\n\t\t\t\tpos++;\n\t\t\t\tlevel++;\n\t\t\t}\n\t\t}\n\t\telse if (pos < max) {\n\t\t\tpos++;\n\t\t}\n\t\tif (pos >= max) {\n\t\t\tif (state == DocComment || (state == UnknownComment && maybe_doc_comment))\n\t\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCKDOC);\n\t\t\telse\n\t\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCK);\n\t\t\tbreak;\n\t\t}\n\t\tc = styler.SafeGetCharAt(pos, '\\0');\n\t}\n}\n\n/*\n * The rule for line-doc comments is as follows... ///N and //! (where N is a non slash) start doc comments.\n * Otherwise it's a normal line comment.\n */\nstatic void ResumeLineComment(Accessor &styler, Sci_Position& pos, Sci_Position max, CommentState state) {\n\tbool maybe_doc_comment = false;\n\tint c = styler.SafeGetCharAt(pos, '\\0');\n\tif (c == '/') {\n\t\tif (pos < max) {\n\t\t\tpos++;\n\t\t\tc = styler.SafeGetCharAt(pos, '\\0');\n\t\t\tif (c != '/') {\n\t\t\t\tmaybe_doc_comment = true;\n\t\t\t}\n\t\t}\n\t} else if (c == '!') {\n\t\tmaybe_doc_comment = true;\n\t}\n\n\tpos = styler.LineEnd(styler.GetLine(pos));\n\tstyler.SetLineState(styler.GetLine(pos), SCE_RUST_DEFAULT);\n\n\tif (state == DocComment || (state == UnknownComment && maybe_doc_comment))\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_COMMENTLINEDOC);\n\telse\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_COMMENTLINE);\n}\n\nstatic void ScanComments(Accessor &styler, Sci_Position& pos, Sci_Position max) {\n\tpos++;\n\tconst int c = styler.SafeGetCharAt(pos, '\\0');\n\tpos++;\n\tif (c == '/')\n\t\tResumeLineComment(styler, pos, max, UnknownComment);\n\telse if (c == '*')\n\t\tResumeBlockComment(styler, pos, max, UnknownComment, 1);\n}\n\nstatic void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max, StringType string_type) {\n\tint c = styler.SafeGetCharAt(pos, '\\0');\n\tbool error = false;\n\twhile (c != '\"' && !error) {\n\t\tif (pos >= max) {\n\t\t\terror = true;\n\t\t\tbreak;\n\t\t}\n\t\tif (pos == styler.LineEnd(styler.GetLine(pos)))\n\t\t\tstyler.SetLineState(styler.GetLine(pos), 0);\n\t\tif (c == '\\\\') {\n\t\t\tconst int n = styler.SafeGetCharAt(pos + 1, '\\0');\n\t\t\tif (IsValidStringEscape(n)) {\n\t\t\t\tpos += 2;\n\t\t\t} else if (n == 'x') {\n\t\t\t\tpos += 2;\n\t\t\t\terror = !ScanNumericEscape(styler, pos, 2, true);\n\t\t\t} else if (n == 'u' && (string_type != StringType::BYTESTRING)) {\n\t\t\t\tpos += 2;\n\t\t\t\tif (styler.SafeGetCharAt(pos, '\\0') != '{') {\n\t\t\t\t\t// old-style\n\t\t\t\t\terror = !ScanNumericEscape(styler, pos, 4, true);\n\t\t\t\t} else {\n\t\t\t\t\tint n_digits = 0;\n\t\t\t\t\twhile (IsADigit(styler.SafeGetCharAt(++pos, '\\0'), 16) && n_digits++ < 6) {\n\t\t\t\t\t}\n\t\t\t\t\tif (n_digits > 0 && styler.SafeGetCharAt(pos, '\\0') == '}')\n\t\t\t\t\t\tpos++;\n\t\t\t\t\telse\n\t\t\t\t\t\terror = true;\n\t\t\t\t}\n\t\t\t} else if (n == 'U' && (string_type != StringType::BYTESTRING)) {\n\t\t\t\tpos += 2;\n\t\t\t\terror = !ScanNumericEscape(styler, pos, 8, true);\n\t\t\t} else {\n\t\t\t\tpos += 1;\n\t\t\t\terror = true;\n\t\t\t}\n\t\t} else {\n\t\t\tif (string_type == StringType::BYTESTRING && !IsASCII((char)c))\n\t\t\t\terror = true;\n\t\t\telse\n\t\t\t\tpos++;\n\t\t}\n\t\tc = styler.SafeGetCharAt(pos, '\\0');\n\t}\n\tif (!error)\n\t\tpos++;\n\n\tstyler.ColourTo(pos - 1, static_cast<int>(string_type));\n}\n\nstatic void ResumeRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, int num_hashes, StringType string_type) {\n\tfor (;;) {\n\t\tif (pos == styler.LineEnd(styler.GetLine(pos)))\n\t\t\tstyler.SetLineState(styler.GetLine(pos), num_hashes);\n\n\t\tconst int c = styler.SafeGetCharAt(pos, '\\0');\n\t\tif (c == '\"') {\n\t\t\tpos++;\n\t\t\tint trailing_num_hashes = 0;\n\t\t\twhile (styler.SafeGetCharAt(pos, '\\0') == '#' && trailing_num_hashes < num_hashes) {\n\t\t\t\ttrailing_num_hashes++;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tif (trailing_num_hashes == num_hashes) {\n\t\t\t\tstyler.SetLineState(styler.GetLine(pos), 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if (pos >= max) {\n\t\t\tbreak;\n\t\t} else {\n\t\t\tif ((string_type == StringType::RAW_BYTESTRING) && !IsASCII((char)c))\n\t\t\t\tbreak;\n\t\t\tpos++;\n\t\t}\n\t}\n\n\tstyler.ColourTo(pos - 1, static_cast<int>(string_type));\n}\n\nstatic void ScanRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, StringType string_type) {\n\tpos++;\n\tint num_hashes = 0;\n\twhile (styler.SafeGetCharAt(pos, '\\0') == '#') {\n\t\tnum_hashes++;\n\t\tpos++;\n\t}\n\tif (styler.SafeGetCharAt(pos, '\\0') != '\"') {\n\t\tstyler.ColourTo(pos - 1, SCE_RUST_LEXERROR);\n\t} else {\n\t\tpos++;\n\t\tResumeRawString(styler, pos, max, num_hashes, string_type);\n\t}\n}\n\nvoid SCI_METHOD LexerRust::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tPropSetSimple props;\n\tAccessor styler(pAccess, &props);\n\tSci_Position pos = startPos;\n\tconst Sci_Position max = pos + length;\n\n\tstyler.StartAt(pos);\n\tstyler.StartSegment(pos);\n\n\tif (initStyle == SCE_RUST_COMMENTBLOCK || initStyle == SCE_RUST_COMMENTBLOCKDOC) {\n\t\tResumeBlockComment(styler, pos, max, initStyle == SCE_RUST_COMMENTBLOCKDOC ? DocComment : NotDocComment, styler.GetLineState(styler.GetLine(pos) - 1));\n\t} else if (initStyle == SCE_RUST_COMMENTLINE || initStyle == SCE_RUST_COMMENTLINEDOC) {\n\t\tResumeLineComment(styler, pos, max, initStyle == SCE_RUST_COMMENTLINEDOC ? DocComment : NotDocComment);\n\t} else if (initStyle == SCE_RUST_STRING) {\n\t\tResumeString(styler, pos, max, StringType::STRING);\n\t} else if (initStyle == SCE_RUST_BYTESTRING) {\n\t\tResumeString(styler, pos, max, StringType::BYTESTRING);\n\t} else if (initStyle == SCE_RUST_STRINGR) {\n\t\tResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), StringType::RAW_STRING);\n\t} else if (initStyle == SCE_RUST_BYTESTRINGR) {\n\t\tResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), StringType::RAW_BYTESTRING);\n\t} else if (initStyle == SCE_RUST_CSTRING) {\n\t\tResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), StringType::CSTRING);\n\t} else if (initStyle == SCE_RUST_CSTRINGR) {\n\t\tResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), StringType::RAW_CSTRING);\n\t}\n\twhile (pos < max) {\n\t\tconst int c = styler.SafeGetCharAt(pos, '\\0');\n\t\tconst int n = styler.SafeGetCharAt(pos + 1, '\\0');\n\t\tconst int n2 = styler.SafeGetCharAt(pos + 2, '\\0');\n\n\t\tif (pos == 0 && c == '#' && n == '!' && n2 != '[') {\n\t\t\tpos += 2;\n\t\t\tResumeLineComment(styler, pos, max, NotDocComment);\n\t\t} else if (IsWhitespace(c)) {\n\t\t\tScanWhitespace(styler, pos, max);\n\t\t} else if (c == '/' && (n == '/' || n == '*')) {\n\t\t\tScanComments(styler, pos, max);\n\t\t} else if (c == 'r' && (n == '#' && IsIdentifierStart(n2))) {\n\t\t\tpos += 2;\n\t\t\tScanRawIdentifier(styler, pos);\n\t\t} else if (c == 'r' && (n == '#' || n == '\"')) {\n\t\t\tScanRawString(styler, pos, max, StringType::RAW_STRING);\n\t\t} else if (c == 'b' && n == 'r' && (n2 == '#' || n2 == '\"')) {\n\t\t\tpos++;\n\t\t\tScanRawString(styler, pos, max, StringType::RAW_BYTESTRING);\n\t\t} else if (c == 'b' && n == '\"') {\n\t\t\tpos += 2;\n\t\t\tResumeString(styler, pos, max, StringType::BYTESTRING);\n\t\t} else if (c == 'c' && n == 'r' && (n2 == '#' || n2 == '\"')) {\n\t\t\tpos++;\n\t\t\tScanRawString(styler, pos, max, StringType::RAW_CSTRING);\n\t\t} else if (c == 'c' && n == '\"') {\n\t\t\tpos += 2;\n\t\t\tResumeString(styler, pos, max, StringType::CSTRING);\n\t\t} else if (c == 'b' && n == '\\'') {\n\t\t\tpos++;\n\t\t\tScanCharacterLiteralOrLifetime(styler, pos, true);\n\t\t} else if (IsIdentifierStart(c)) {\n\t\t\tScanIdentifier(styler, pos, keywords);\n\t\t} else if (IsADigit(c)) {\n\t\t\tScanNumber(styler, pos);\n\t\t} else if (IsThreeCharOperator(c, n, n2)) {\n\t\t\tpos += 3;\n\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_OPERATOR);\n\t\t} else if (IsTwoCharOperator(c, n)) {\n\t\t\tpos += 2;\n\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_OPERATOR);\n\t\t} else if (IsOneCharOperator(c)) {\n\t\t\tpos++;\n\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_OPERATOR);\n\t\t} else if (c == '\\'') {\n\t\t\tScanCharacterLiteralOrLifetime(styler, pos, false);\n\t\t} else if (c == '\"') {\n\t\t\tpos++;\n\t\t\tResumeString(styler, pos, max, StringType::STRING);\n\t\t} else {\n\t\t\tpos++;\n\t\t\tstyler.ColourTo(pos - 1, SCE_RUST_LEXERROR);\n\t\t}\n\t}\n\tstyler.ColourTo(pos - 1, SCE_RUST_DEFAULT);\n\tstyler.Flush();\n}\n\nvoid SCI_METHOD LexerRust::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\n\tif (!options.fold)\n\t\treturn;\n\n\tLexAccessor styler(pAccess);\n\n\tconst Sci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tbool inLineComment = false;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tSci_PositionU lineStartNext = styler.LineStart(lineCurrent+1);\n\tint levelMinCurrent = levelCurrent;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tconst bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tconst bool atEOL = i == (lineStartNext-1);\n\t\tif ((style == SCE_RUST_COMMENTLINE) || (style == SCE_RUST_COMMENTLINEDOC))\n\t\t\tinLineComment = true;\n\t\tif (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (options.foldComment && options.foldCommentExplicit && ((style == SCE_RUST_COMMENTLINE) || options.foldExplicitAnywhere)) {\n\t\t\tif (userDefinedFoldMarkers) {\n\t\t\t\tif (styler.Match(i, options.foldExplicitStart.c_str())) {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ((ch == '/') && (chNext == '/')) {\n\t\t\t\t\tconst char chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (options.foldSyntaxBased && (style == SCE_RUST_OPERATOR)) {\n\t\t\tif (ch == '{') {\n\t\t\t\t// Measure the minimum before a '{' to allow\n\t\t\t\t// folding on \"} else {\"\n\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t}\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (!IsASpace(ch))\n\t\t\tvisibleChars++;\n\t\tif (atEOL || (i == endPos-1)) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tif (options.foldSyntaxBased && options.foldAtElse) {\n\t\t\t\tlevelUse = levelMinCurrent;\n\t\t\t}\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && options.foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlineStartNext = styler.LineStart(lineCurrent+1);\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelMinCurrent = levelCurrent;\n\t\t\tif (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) {\n\t\t\t\t// There is an empty line at end of file so give it same level and empty\n\t\t\t\tstyler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);\n\t\t\t}\n\t\t\tvisibleChars = 0;\n\t\t\tinLineComment = false;\n\t\t}\n\t}\n}\n\n}\n\nextern const LexerModule lmRust(SCLEX_RUST, LexerRust::LexerFactoryRust, \"rust\", rustWordLists);\n"
  },
  {
    "path": "lexers/LexSAS.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexSAS.cxx\n ** Lexer for SAS\n **/\n// Author: Luke Rasmussen (luke.rasmussen@gmail.com)\n//\n// The License.txt file describes the conditions under which this software may\n// be distributed.\n//\n// Developed as part of the StatTag project at Northwestern University Feinberg\n// School of Medicine with funding from Northwestern University Clinical and\n// Translational Sciences Institute through CTSA grant UL1TR001422.  This work\n// has not been reviewed or endorsed by NCATS or the NIH.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ColouriseSASDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n    Accessor &styler) {\n\n    WordList &keywords = *keywordlists[0];\n    WordList &blockKeywords = *keywordlists[1];\n    WordList &functionKeywords = *keywordlists[2];\n    WordList &statements = *keywordlists[3];\n\n    CharacterSet setCouldBePostOp(CharacterSet::setNone, \"+-\");\n    CharacterSet setMacroStart(CharacterSet::setNone, \"%\");\n    CharacterSet setWordStart(CharacterSet::setAlpha, \"_\", 0x80, true);\n    CharacterSet setWord(CharacterSet::setAlphaNum, \"._\", 0x80, true);\n\n    StyleContext sc(startPos, length, initStyle, styler);\n    bool lineHasNonCommentChar = false;\n    for (; sc.More(); sc.Forward()) {\n        if (sc.atLineStart) {\n            lineHasNonCommentChar = false;\n        }\n\n        // Determine if the current state should terminate.\n        switch (sc.state) {\n            case SCE_SAS_OPERATOR:\n                sc.SetState(SCE_SAS_DEFAULT);\n                break;\n            case SCE_SAS_NUMBER:\n                // We accept almost anything because of hex. and number suffixes\n                if (!setWord.Contains(sc.ch)) {\n                    sc.SetState(SCE_SAS_DEFAULT);\n                }\n                break;\n            case SCE_SAS_MACRO:\n              if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {\n                char s[1000];\n                sc.GetCurrentLowered(s, sizeof(s));\n                if (keywords.InList(s)) {\n                  sc.ChangeState(SCE_SAS_MACRO_KEYWORD);\n                }\n                else if (blockKeywords.InList(s)) {\n                  sc.ChangeState(SCE_SAS_BLOCK_KEYWORD);\n                }\n                else if (functionKeywords.InList(s)) {\n                  sc.ChangeState(SCE_SAS_MACRO_FUNCTION);\n                }\n                sc.SetState(SCE_SAS_DEFAULT);\n              }\n              break;\n            case SCE_SAS_IDENTIFIER:\n                if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {\n                    char s[1000];\n                    sc.GetCurrentLowered(s, sizeof(s));\n                    if (statements.InList(s)) {\n                      sc.ChangeState(SCE_SAS_STATEMENT);\n                    }\n                    else if(blockKeywords.InList(s)) {\n                      sc.ChangeState(SCE_SAS_BLOCK_KEYWORD);\n                    }\n                    sc.SetState(SCE_SAS_DEFAULT);\n                }\n                break;\n            case SCE_SAS_COMMENTBLOCK:\n                if (sc.Match('*', '/')) {\n                    sc.Forward();\n                    sc.ForwardSetState(SCE_SAS_DEFAULT);\n                }\n                break;\n            case SCE_SAS_COMMENT:\n            case SCE_SAS_COMMENTLINE:\n                if (sc.Match(';')) {\n                    sc.Forward();\n                    sc.SetState(SCE_SAS_DEFAULT);\n                }\n                break;\n            case SCE_SAS_STRING:\n                if (sc.ch == '\\\"') {\n                    sc.ForwardSetState(SCE_SAS_DEFAULT);\n                }\n                break;\n        }\n\n        // Determine if a new state should be entered.\n        if (sc.state == SCE_SAS_DEFAULT) {\n            if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n                lineHasNonCommentChar = true;\n                sc.SetState(SCE_SAS_NUMBER);\n            }\n            else if (setWordStart.Contains(sc.ch)) {\n                lineHasNonCommentChar = true;\n                sc.SetState(SCE_SAS_IDENTIFIER);\n            }\n            else if (sc.Match('*') && !lineHasNonCommentChar) {\n                sc.SetState(SCE_SAS_COMMENT);\n            }\n            else if (sc.Match('/', '*')) {\n                sc.SetState(SCE_SAS_COMMENTBLOCK);\n                sc.Forward();\t// Eat the * so it isn't used for the end of the comment\n            }\n            else if (sc.Match('/', '/')) {\n                sc.SetState(SCE_SAS_COMMENTLINE);\n            }\n            else if (sc.ch == '\\\"') {\n                lineHasNonCommentChar = true;\n                sc.SetState(SCE_SAS_STRING);\n            }\n            else if (setMacroStart.Contains(sc.ch)) {\n              lineHasNonCommentChar = true;\n              sc.SetState(SCE_SAS_MACRO);\n            }\n            else if (isoperator(static_cast<char>(sc.ch))) {\n                lineHasNonCommentChar = true;\n                sc.SetState(SCE_SAS_OPERATOR);\n            }\n        }\n    }\n\n    sc.Complete();\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\nstatic void FoldSASDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],\n    Accessor &styler) {\n    bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n    bool foldAtElse = styler.GetPropertyInt(\"fold.at.else\", 0) != 0;\n    Sci_PositionU endPos = startPos + length;\n    int visibleChars = 0;\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int levelCurrent = SC_FOLDLEVELBASE;\n    if (lineCurrent > 0)\n        levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;\n    int levelMinCurrent = levelCurrent;\n    int levelNext = levelCurrent;\n    char chNext = styler[startPos];\n    int styleNext = styler.StyleAt(startPos);\n    for (Sci_PositionU i = startPos; i < endPos; i++) {\n        char ch = chNext;\n        chNext = styler.SafeGetCharAt(i + 1);\n        int style = styleNext;\n        styleNext = styler.StyleAt(i + 1);\n        bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n        if (style == SCE_R_OPERATOR) {\n            if (ch == '{') {\n                // Measure the minimum before a '{' to allow\n                // folding on \"} else {\"\n                if (levelMinCurrent > levelNext) {\n                    levelMinCurrent = levelNext;\n                }\n                levelNext++;\n            }\n            else if (ch == '}') {\n                levelNext--;\n            }\n        }\n        if (atEOL) {\n            int levelUse = levelCurrent;\n            if (foldAtElse) {\n                levelUse = levelMinCurrent;\n            }\n            int lev = levelUse | levelNext << 16;\n            if (visibleChars == 0 && foldCompact)\n                lev |= SC_FOLDLEVELWHITEFLAG;\n            if (levelUse < levelNext)\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            if (lev != styler.LevelAt(lineCurrent)) {\n                styler.SetLevel(lineCurrent, lev);\n            }\n            lineCurrent++;\n            levelCurrent = levelNext;\n            levelMinCurrent = levelCurrent;\n            visibleChars = 0;\n        }\n        if (!isspacechar(ch))\n            visibleChars++;\n    }\n}\n\n\nstatic const char * const SASWordLists[] = {\n    \"Language Keywords\",\n\t  \"Macro Keywords\",\n    \"Types\",\n    0,\n};\n\nextern const LexerModule lmSAS(SCLEX_SAS, ColouriseSASDoc, \"sas\", FoldSASDoc, SASWordLists);\n"
  },
  {
    "path": "lexers/LexSINEX.cxx",
    "content": "// Scintilla source code edit control\n// Encoding: UTF-8\n/** @file LexSINEX.cxx\n ** Lexer for SINEX (Solution INdependent EXchange format) files\n ** https://www.iers.org/SharedDocs/Publikationen/EN/IERS/Documents/ac/sinex/sinex_v202_pdf.pdf\n **\n ** Written by Franck Reinquin\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n// Use an unnamed namespace to protect the functions and classes from name conflicts\n\n\n// States when parsing a real number\ntypedef enum {\n\t\tNOTHING=0,    // parsing no started\n\t\tSIGN_1=1,     // a sign (+/-) was encountered for the first time\n\t\tMANTISSA_1=2, // one or more consecutive digits were encountered for the first time\n\t\tDOT=3,        // the scientific notation letter (e,E,d,D) was encountered\n\t\tMANTISSA_2=4, // one or more consecutive digits were encountered after a dot\n\t\tD_OR_E=5,     // the scientific notation letter (e,E,d,D) was encountered\n\t\tSIGN_2=6,     // a sign (+/-) was encountered for the second time\n\t\tEXPONENT=7    // one or more consecutive digits were encountered \n} E_REAL_PARSING_STATE ;\n\n\n// Check if end of line encountered. Possible terminators : '\\n', '\\r', '\\r\\n'\n// For '\\r\\n' terminators, the EOL is reached at the '\\n' character.\ninline bool AtEOL(Accessor &styler, Sci_PositionU i) {\n\treturn (styler[i] == '\\n') ||\n\t       ((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n'));\n}\n\n\ninline bool IsCommentLine(Accessor &styler, Sci_Position line) {\n\tSci_Position pos = styler.LineStart(line);\n\treturn (styler.StyleAt(pos) == SCE_SINEX_COMMENTLINE);\n}\n\n\n// Check whether the string is number, either integer or float ; the\n// scientific representation is also accepted.\n// Implemented as a finite-state machine\n// Mostly equivalent to REGEX : ^[+-]?\\d*\\.?\\d+([eE][+-]?\\d+)?$\ninline bool IsSINEXNumber(const char *text, Sci_PositionU len) {\n\n\tE_REAL_PARSING_STATE\tparsingState = NOTHING ;\n\tbool   firstDigitsFound = false;\n\t\n\tif (len == 0)\n\t\treturn false;\n\n\tfor (Sci_PositionU i = 0 ; i < len ; i++) {\n\t\tif ((text[i] == '-') || (text[i] == '+')) {\n\t\t\t// valid only at the beginning and after an exponent letter\n\t\t\tif (parsingState == NOTHING) {\n\t\t\t\tparsingState = SIGN_1 ;\n\t\t\t} else if (parsingState == D_OR_E) {\n\t\t\t\tparsingState = SIGN_2;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t} else if (text[i] == '.') {\n\t\t\t// valid only after the first digits, which can be absent (e.g. '-.12')\n\t\t\tif ((parsingState == NOTHING) || (parsingState == SIGN_1) \\\n\t\t\t || (parsingState == MANTISSA_1)) {\n\t\t\t\tparsingState = DOT;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t} else if ((text[i] == 'e') || (text[i] == 'E') || (text[i] == 'd') \\\n\t\t     || (text[i] == 'D')) {\n\t\t\t// valid only after the first digits ('.e+7' is NOK)\n\t\t\tif (! firstDigitsFound) return false;\n\t\t\tif ((parsingState == MANTISSA_1) || (parsingState == MANTISSA_2) \\\n             || (parsingState == DOT)) {\n\t\t\t\tparsingState = D_OR_E;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t} else if (isdigit(text[i])) {\n\t\t\tif ((parsingState == NOTHING) || (parsingState == SIGN_1) \\\n\t\t\t|| (parsingState == MANTISSA_1)) {\n\t\t\t\tparsingState = MANTISSA_1;\n                firstDigitsFound = true;\n\t\t\t} else if ((parsingState == DOT) || (parsingState == MANTISSA_2)) {\n\t\t\t\tparsingState = MANTISSA_2;\n                firstDigitsFound = true;\n\t\t\t} else if ((parsingState == D_OR_E) || (parsingState == SIGN_2) \\\n\t\t\t       || (parsingState == EXPONENT)) {\n\t\t\t\tparsingState = EXPONENT;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\n\t\t} else {\n\t\t\t// other characters are not valid\n\t\t\treturn false ;\n\t\t}\n\t}\n\treturn (firstDigitsFound && (parsingState != D_OR_E) && (parsingState != SIGN_2));\n}\n\n\n// Check whether the string is a SINEX date (YY:DDD:SSSSS)\n// For the record : YY = 2-digit year (!), DDD = Day Of Year, SSSSS = seconds\n// in the day\ninline bool IsSINEXDate(const char *text, Sci_PositionU len) {\n\n\tif (len < 11) return false;\n\treturn (IsADigit(text[0]) && IsADigit(text[1]) && text[2] == ':' &&\n\t        IsADigit(text[3]) && IsADigit(text[4]) && IsADigit(text[5]) && text[6] == ':' &&\n\t        IsADigit(text[7]) && IsADigit(text[8]) && IsADigit(text[9]) && \n\t        IsADigit(text[10]) && IsADigit(text[11]));\n}\n\n// Find next space in the string : return an offset in the string >= start\n// or len if not found\nstatic Sci_PositionU FindNextSpace(const char *text, \n                                   Sci_PositionU start, Sci_PositionU len) {\n\tSci_PositionU  pos ;\n\tfor (pos = start ; pos < len ; pos ++ ) {\n\t\tif (IsASpace(text[pos]))\n\t\t\treturn pos;\n\t}\n    return pos;\n}\n\n// Colourization logic for one line\nvoid ColouriseSinexLine(\n\tconst char *lineBuffer,\n\tSci_PositionU lengthLine,\n\tSci_PositionU startLine,\n\tSci_PositionU endPos,\n\tAccessor &styler) {\n\n\tif (lengthLine == 0) \n\t\treturn;\n\n\t// comment line\n\tif (lineBuffer[0] == '*') {\n\t\tstyler.ColourTo(endPos, SCE_SINEX_COMMENTLINE);\n\n\t// block start (+BLOCK_NAME)\n\t} else if (lineBuffer[0] == '+') {\n\t\tstyler.ColourTo(endPos, SCE_SINEX_BLOCK_START);\n\n\t// block end (-BLOCK_NAME)\n\t} else if (lineBuffer[0] == '-') {\n\t\tstyler.ColourTo(endPos, SCE_SINEX_BLOCK_END);\n\n\t// Other lines : parse content\n\t} else {\n\t\tSci_PositionU i = 0 ;\n\t\tSci_PositionU nextSpace ;\n\t\t\n\t\t// process word by word\n\t\twhile ((nextSpace = FindNextSpace(lineBuffer,i,lengthLine)) < lengthLine) {\n\t\t\t// Detect dates YY:DDD:SSSSS (first test aims at speeding up detection)\n\t\t\tif (IsADigit(lineBuffer[i]) && IsSINEXDate(&lineBuffer[i], nextSpace-i)) {\n\t\t\t\tstyler.ColourTo(startLine+nextSpace-1, SCE_SINEX_DATE);\n\t\t\t// Numbers (integers or floats, including scientific notation)\n\t\t\t} else if (IsSINEXNumber(&lineBuffer[i], nextSpace-i)) {\n\t\t\t\tstyler.ColourTo(startLine+nextSpace-1, SCE_SINEX_NUMBER);\n\t\t\t}\n\t\t\t// consume all spaces\n\t\t\tfor (i=nextSpace ; (i < lengthLine) && IsASpace(lineBuffer[i]) ; i++)\n\t\t\t\t;\n\t\t\tstyler.ColourTo(startLine+i-1, SCE_SINEX_DEFAULT);\n\t\t}\n\t\tstyler.ColourTo(endPos, SCE_SINEX_DEFAULT);\n\t}\n}\n\n\n// Colourization logic for a whole area\n// The area is split into lines which are separately processed\nvoid ColouriseSinexDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n    // initStyle not needed as each line is independent\n\tstd::string lineBuffer;\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tSci_PositionU startLine = startPos;\n\n\tfor (Sci_PositionU i = startPos; i < startPos + length; i++) {\n\t\tlineBuffer.push_back(styler[i]);\n\t\tif (AtEOL(styler, i)) {\n\t\t\t// End of line (or of line buffer) met, colourise it\n\t\t\tColouriseSinexLine(lineBuffer.c_str(), lineBuffer.length(), startLine, i, styler);\n\t\t\tlineBuffer.clear();\n\t\t\tstartLine = i + 1;\n\t\t}\n\t}\n\tif (!lineBuffer.empty()) {\t// Last line does not have ending characters\n\t\tColouriseSinexLine(lineBuffer.c_str(), lineBuffer.length(), startLine, startPos + length - 1, styler);\n\t}\n}\n\n\n// Folding logic\nvoid FoldSinexDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {\n\n\tif (AtEOL(styler, startPos)) \n\t\treturn ;\n\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint styleCurrent;\n\n\t// One-line comments are not folded, multi-line comments may be folded\n\t// (see \"fold.comment\" property) : we  need to check the lines before the\n\t// first line.\n\t// Possible cases :\n\t// *  start of a comment block : first line = comment, 1 comment line before\n\t// *  continuation of a comment block : first line = comment , >1 comment\n\t//    lines before\n\t// * end of a comment line : first line != comment, >1 comment lines before\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint nbCommentLines = 0 ;\n\twhile (lineCurrent > 0) {\n\t\tif (!IsCommentLine(styler, lineCurrent-1))\n\t\t\tbreak ;\n\t\tnbCommentLines++;\n\t\tlineCurrent--;\n\t}\n\n\t// Go back to the start of the comment block, if any. Level at that line\n\t// is known\n\tSci_Position newStartPos = (nbCommentLines == 0) ? startPos : styler.LineStart(lineCurrent);\n\n\t// Now go through the provided text\n\tint levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelPrev = levelCurrent;\n\tint levelNext = levelCurrent;\n\tint indComment = 0;\n\n\tfor (Sci_PositionU i = newStartPos; i < endPos; i++) {\n\t\tif (AtEOL(styler, i)) {\n\t\t\tlevelCurrent = levelNext ;\n\t\t\tstyleCurrent  = styler.StyleAt(i);\n\t\t\tif (foldComment) {\n\t\t\t\tif (styleCurrent == SCE_SINEX_COMMENTLINE) {\n\t\t\t\t\tindComment++ ;\n\t\t\t\t\tif (indComment==2) {\n\t\t\t\t\t\t// second comment line ->increase level\n\t\t\t\t\t\t// (do nothing for single comment lines)\n\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// not a comment line : decrease level if it follows a\n\t\t\t\t\t// multi-line comment\n\t\t\t\t\tif (indComment >= 2) {\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t}\n\t\t\t\t\tindComment = 0;\n\t\t\t\t}\n\t\t\t\tlevelNext = levelCurrent ;\n\t\t\t}\n\t\t\tswitch (styleCurrent) {\n\t\t\tcase SCE_SINEX_BLOCK_START:\n\t\t\t\tlevelNext++;\n\t\t\t\tbreak;\n\t\t\tcase SCE_SINEX_BLOCK_END:\n\t\t\t\tlevelNext--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tstyler.SetLevel(lineCurrent, levelCurrent);\n\n\t\t\t// now update previous line state (if header)\n\t\t\tif (levelCurrent > levelPrev) {\n\t\t\t\tint lev = levelPrev;\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t//lev |= 1<<16;\n\t\t\t\tif (lev != styler.LevelAt(lineCurrent-1)) {\n\t\t\t\t\tstyler.SetLevel(lineCurrent-1, lev);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent ;\n\t\t}\n\n\t}\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelNext | flagsNext);\n}\n\nconst char * const sinexWordListDesc[] = {\n\t\"SNX\",\n\t0\n};\n\n}  // unnamed namespace end\n\nextern const LexerModule lmSINEX(SCLEX_SINEX, ColouriseSinexDoc, \"sinex\", FoldSinexDoc, sinexWordListDesc);\n"
  },
  {
    "path": "lexers/LexSML.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexSML.cxx\n ** Lexer for SML.\n **/\n// Copyright 2009 by James Moffatt and Yuzhou Xin\n// Modified from LexCaml.cxx by Robert Roessler <robertr@rftp.com> Copyright 2005\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\n#if defined(__clang__)\n#pragma clang diagnostic ignored \"-Wcomma\"\n#endif\n\ninline int  issml(int c) {return isalnum(c) || c == '_';}\ninline int issmlf(int c) {return isalpha(c) || c == '_';}\ninline int issmld(int c) {return isdigit(c) || c == '_';}\n\n\nusing namespace Lexilla;\n\nstatic void ColouriseSMLDoc(\n\tSci_PositionU startPos, Sci_Position length,\n\tint initStyle,\n\tWordList *keywordlists[],\n\tAccessor &styler)\n{\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tint nesting = 0;\n\tif (sc.state < SCE_SML_STRING)\n\t\tsc.state = SCE_SML_DEFAULT;\n\tif (sc.state >= SCE_SML_COMMENT)\n\t\tnesting = (sc.state & 0x0f) - SCE_SML_COMMENT;\n\n\tSci_PositionU chToken = 0;\n\tint chBase = 0, chLit = 0;\n\tWordList& keywords  = *keywordlists[0];\n\tWordList& keywords2 = *keywordlists[1];\n\tWordList& keywords3 = *keywordlists[2];\n\tconst int useMagic = styler.GetPropertyInt(\"lexer.caml.magic\", 0);\n\n\twhile (sc.More()) {\n\t\tint state2 = -1;\n\t\tSci_Position chColor = sc.currentPos - 1;\n\t\tbool advance = true;\n\n\t\tswitch (sc.state & 0x0f) {\n\t\tcase SCE_SML_DEFAULT:\n\t\t\tchToken = sc.currentPos;\n\t\t\tif (issmlf(sc.ch))\n\t\t\t\tstate2 = SCE_SML_IDENTIFIER;\n\t\t\telse if (sc.Match('`') && issmlf(sc.chNext))\n\t\t\t\tstate2 = SCE_SML_TAGNAME;\n\t\t\telse if (sc.Match('#')&&isdigit(sc.chNext))\n\t\t\t\t\tstate2 = SCE_SML_LINENUM;\n\t\t\telse if (sc.Match('#','\\\"')){\n\t\t\t\t\tstate2 = SCE_SML_CHAR,chLit = 0;\n\t\t\t\t\tsc.Forward();\n\n\t\t\t\t}\n\t\t\telse if (isdigit(sc.ch)) {\n\t\t\t\tstate2 = SCE_SML_NUMBER, chBase = 10;\n\t\t\t\tif (sc.Match('0') && strchr(\"xX\", sc.chNext))\n\t\t\t\t\tchBase = 16, sc.Forward();}\n\t\t\telse if (sc.Match('\\\"')&&sc.chPrev!='#')\n\t\t\t\tstate2 = SCE_SML_STRING;\n\t\t\telse if (sc.Match('(', '*')){\n\t\t\t\tstate2 = SCE_SML_COMMENT,\n\t\t\t\t\tsc.ch = ' ',\n\t\t\t\t\tsc.Forward();}\n\t\t\telse if (strchr(\"!~\"\n\t\t\t\t\t\"=<>@^+-*/\"\n\t\t\t\t\t\"()[];,:.#\", sc.ch))\n\t\t\t\tstate2 = SCE_SML_OPERATOR;\n\t\t\tbreak;\n\n\t\tcase SCE_SML_IDENTIFIER:\n\t\t\tif (!(issml(sc.ch) || sc.Match('\\''))) {\n\t\t\t\tconst Sci_Position n = sc.currentPos - chToken;\n\t\t\t\tif (n < 24) {\n\t\t\t\t\tchar t[24];\n\t\t\t\t\tfor (Sci_Position i = -n; i < 0; i++)\n\t\t\t\t\t\tt[n + i] = static_cast<char>(sc.GetRelative(i));\n\t\t\t\t\tt[n] = '\\0';\n\t\t\t\t\tif ((n == 1 && sc.chPrev == '_') || keywords.InList(t))\n\t\t\t\t\t\tsc.ChangeState(SCE_SML_KEYWORD);\n\t\t\t\t\telse if (keywords2.InList(t))\n\t\t\t\t\t\tsc.ChangeState(SCE_SML_KEYWORD2);\n\t\t\t\t\telse if (keywords3.InList(t))\n\t\t\t\t\t\tsc.ChangeState(SCE_SML_KEYWORD3);\n\t\t\t\t}\n\t\t\t\tstate2 = SCE_SML_DEFAULT, advance = false;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_SML_TAGNAME:\n\t\t\tif (!(issml(sc.ch) || sc.Match('\\'')))\n\t\t\t\tstate2 = SCE_SML_DEFAULT, advance = false;\n\t\t\tbreak;\n\n\t\tcase SCE_SML_LINENUM:\n\t\t\tif (!isdigit(sc.ch))\n\t\t\t\tstate2 = SCE_SML_DEFAULT, advance = false;\n\t\t\tbreak;\n\n\t\tcase SCE_SML_OPERATOR: {\n\t\t\tconst char* o = 0;\n\t\t\tif (issml(sc.ch) || isspace(sc.ch)\n\t\t\t\t|| (o = strchr(\")]};,\\'\\\"`#\", sc.ch),o)\n\t\t\t\t|| !strchr(\"!$%&*+-./:<=>?@^|~\", sc.ch)) {\n\t\t\t\tif (o && strchr(\")]};,\", sc.ch)) {\n\t\t\t\t\tif ((sc.Match(')') && sc.chPrev == '(')\n\t\t\t\t\t\t|| (sc.Match(']') && sc.chPrev == '['))\n\t\t\t\t\t\tsc.ChangeState(SCE_SML_KEYWORD);\n\t\t\t\t\tchColor++;\n\t\t\t\t} else\n\t\t\t\t\tadvance = false;\n\t\t\t\tstate2 = SCE_SML_DEFAULT;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase SCE_SML_NUMBER:\n\t\t\tif (issmld(sc.ch) || IsADigit(sc.ch, chBase))\n\t\t\t\tbreak;\n\t\t\tif ((sc.Match('l') || sc.Match('L') || sc.Match('n'))\n\t\t\t\t&& (issmld(sc.chPrev) || IsADigit(sc.chPrev, chBase)))\n\t\t\t\tbreak;\n\t\t\tif (chBase == 10) {\n\t\t\t\tif (sc.Match('.') && issmld(sc.chPrev))\n\t\t\t\t\tbreak;\n\t\t\t\tif ((sc.Match('e') || sc.Match('E'))\n\t\t\t\t\t&& (issmld(sc.chPrev) || sc.chPrev == '.'))\n\t\t\t\t\tbreak;\n\t\t\t\tif ((sc.Match('+') || sc.Match('-'))\n\t\t\t\t\t&& (sc.chPrev == 'e' || sc.chPrev == 'E'))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tstate2 = SCE_SML_DEFAULT, advance = false;\n\t\t\tbreak;\n\n\t\tcase SCE_SML_CHAR:\n\t\t\tif (sc.Match('\\\\')) {\n\t\t\t\tchLit = 1;\n\t\t\t\tif (sc.chPrev == '\\\\')\n\t\t\t\t\tsc.ch = ' ';\n\t\t\t} else if ((sc.Match('\\\"') && sc.chPrev != '\\\\') || sc.atLineEnd) {\n\t\t\t\tstate2 = SCE_SML_DEFAULT;\n\t\t\t\tchLit = 1;\n\t\t\t\tif (sc.Match('\\\"'))\n\t\t\t\t\tchColor++;\n\t\t\t\telse\n\t\t\t\t\tsc.ChangeState(SCE_SML_IDENTIFIER);\n\t\t\t} else if (chLit < 1 && sc.currentPos - chToken >= 3)\n\t\t\t\tsc.ChangeState(SCE_SML_IDENTIFIER), advance = false;\n\t\t\tbreak;\n\n\t\tcase SCE_SML_STRING:\n\t\t\tif (sc.Match('\\\\') && sc.chPrev == '\\\\')\n\t\t\t\tsc.ch = ' ';\n\t\t\telse if (sc.Match('\\\"') && sc.chPrev != '\\\\')\n\t\t\t\tstate2 = SCE_SML_DEFAULT, chColor++;\n\t\t\tbreak;\n\n\t\tcase SCE_SML_COMMENT:\n\t\tcase SCE_SML_COMMENT1:\n\t\tcase SCE_SML_COMMENT2:\n\t\tcase SCE_SML_COMMENT3:\n\t\t\tif (sc.Match('(', '*'))\n\t\t\t\tstate2 = sc.state + 1, chToken = sc.currentPos,\n\t\t\t\t\tsc.ch = ' ',\n\t\t\t\t\tsc.Forward(), nesting++;\n\t\t\telse if (sc.Match(')') && sc.chPrev == '*') {\n\t\t\t\tif (nesting)\n\t\t\t\t\tstate2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;\n\t\t\t\telse\n\t\t\t\t\tstate2 = SCE_SML_DEFAULT;\n\t\t\t\tchColor++;\n\t\t\t} else if (useMagic && sc.currentPos - chToken == 4\n\t\t\t\t&& sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')\n\t\t\t\tsc.state |= 0x10;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (state2 >= 0)\n\t\t\tstyler.ColourTo(chColor, sc.state), sc.ChangeState(state2);\n\t\tif (advance)\n\t\t\tsc.Forward();\n\t}\n\n\tsc.Complete();\n}\n\nstatic void FoldSMLDoc(\n\tSci_PositionU, Sci_Position,\n\tint,\n\tWordList *[],\n\tAccessor &)\n{\n}\n\nstatic const char * const SMLWordListDesc[] = {\n\t\"Keywords\",\n\t\"Keywords2\",\n\t\"Keywords3\",\n\t0\n};\n\nextern const LexerModule lmSML(SCLEX_SML, ColouriseSMLDoc, \"SML\", FoldSMLDoc, SMLWordListDesc);\n\n"
  },
  {
    "path": "lexers/LexSQL.cxx",
    "content": "//-*- coding: utf-8 -*-\n// Scintilla source code edit control\n/** @file LexSQL.cxx\n ** Lexer for SQL, including PL/SQL and SQL*Plus.\n ** Improved by Jérôme LAFORGE <jerome.laforge_AT_gmail_DOT_com> from 2010 to 2012.\n **/\n// Copyright 1998-2012 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"SparseState.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\nbool IsAWordChar(int ch, bool sqlAllowDottedWord) noexcept {\n\tif (!sqlAllowDottedWord)\n\t\treturn (ch < 0x80) && (isalnum(ch) || ch == '_');\n\telse\n\t\treturn (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');\n}\n\nbool IsAWordStart(int ch) noexcept {\n\treturn (ch < 0x80) && (isalpha(ch) || ch == '_');\n}\n\nbool IsADoxygenChar(int ch) noexcept {\n\treturn (islower(ch) || ch == '$' || ch == '@' ||\n\t        ch == '\\\\' || ch == '&' || ch == '<' ||\n\t        ch == '>' || ch == '#' || ch == '{' ||\n\t        ch == '}' || ch == '[' || ch == ']');\n}\n\nbool IsANumberChar(int ch, int chPrev) noexcept {\n\t// Not exactly following number definition (several dots are seen as OK, etc.)\n\t// but probably enough in most cases.\n\treturn (ch < 0x80) &&\n\t       (isdigit(ch) || toupper(ch) == 'E' ||\n\t        ch == '.' || ((ch == '-' || ch == '+') && chPrev < 0x80 && toupper(chPrev) == 'E'));\n}\n\ntypedef unsigned int sql_state_t;\n\nclass SQLStates {\npublic :\n\tvoid Set(Sci_Position lineNumber, unsigned short int sqlStatesLine) {\n\t\tsqlStatement.Set(lineNumber, sqlStatesLine);\n\t}\n\n\tsql_state_t IgnoreWhen (sql_state_t sqlStatesLine, bool enable) noexcept {\n\t\tif (enable)\n\t\t\tsqlStatesLine |= MASK_IGNORE_WHEN;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_IGNORE_WHEN;\n\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t IntoCondition (sql_state_t sqlStatesLine, bool enable) noexcept {\n\t\tif (enable)\n\t\t\tsqlStatesLine |= MASK_INTO_CONDITION;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_INTO_CONDITION;\n\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t IntoExceptionBlock (sql_state_t sqlStatesLine, bool enable) noexcept {\n\t\tif (enable)\n\t\t\tsqlStatesLine |= MASK_INTO_EXCEPTION;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_INTO_EXCEPTION;\n\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t IntoDeclareBlock (sql_state_t sqlStatesLine, bool enable) noexcept {\n\t\tif (enable)\n\t\t\tsqlStatesLine |= MASK_INTO_DECLARE;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_INTO_DECLARE;\n\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t IntoMergeStatement (sql_state_t sqlStatesLine, bool enable) noexcept {\n\t\tif (enable)\n\t\t\tsqlStatesLine |= MASK_MERGE_STATEMENT;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_MERGE_STATEMENT;\n\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t CaseMergeWithoutWhenFound (sql_state_t sqlStatesLine, bool found) noexcept {\n\t\tif (found)\n\t\t\tsqlStatesLine |= MASK_CASE_MERGE_WITHOUT_WHEN_FOUND;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_CASE_MERGE_WITHOUT_WHEN_FOUND;\n\n\t\treturn sqlStatesLine;\n\t}\n\tsql_state_t IntoSelectStatementOrAssignment (sql_state_t sqlStatesLine, bool found) noexcept {\n\t\tif (found)\n\t\t\tsqlStatesLine |= MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT;\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t BeginCaseBlock (sql_state_t sqlStatesLine) noexcept {\n\t\tif ((sqlStatesLine & MASK_NESTED_CASES) < MASK_NESTED_CASES) {\n\t\t\tsqlStatesLine++;\n\t\t}\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t EndCaseBlock (sql_state_t sqlStatesLine) noexcept {\n\t\tif ((sqlStatesLine & MASK_NESTED_CASES) > 0) {\n\t\t\tsqlStatesLine--;\n\t\t}\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t IntoCreateStatement (sql_state_t sqlStatesLine, bool enable) noexcept {\n\t\tif (enable)\n\t\t\tsqlStatesLine |= MASK_INTO_CREATE;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_INTO_CREATE;\n\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t IntoCreateViewStatement (sql_state_t sqlStatesLine, bool enable) noexcept {\n\t\tif (enable)\n\t\t\tsqlStatesLine |= MASK_INTO_CREATE_VIEW;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_INTO_CREATE_VIEW;\n\n\t\treturn sqlStatesLine;\n\t}\n\n\tsql_state_t IntoCreateViewAsStatement (sql_state_t sqlStatesLine, bool enable) noexcept {\n\t\tif (enable)\n\t\t\tsqlStatesLine |= MASK_INTO_CREATE_VIEW_AS_STATEMENT;\n\t\telse\n\t\t\tsqlStatesLine &= ~MASK_INTO_CREATE_VIEW_AS_STATEMENT;\n\n\t\treturn sqlStatesLine;\n\t}\n\n\tbool IsIgnoreWhen (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_IGNORE_WHEN) != 0;\n\t}\n\n\tbool IsIntoCondition (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_INTO_CONDITION) != 0;\n\t}\n\n\tbool IsIntoCaseBlock (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_NESTED_CASES) != 0;\n\t}\n\n\tbool IsIntoExceptionBlock (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;\n\t}\n\tbool IsIntoSelectStatementOrAssignment (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT) != 0;\n\t}\n\tbool IsCaseMergeWithoutWhenFound (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_CASE_MERGE_WITHOUT_WHEN_FOUND) != 0;\n\t}\n\n\tbool IsIntoDeclareBlock (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_INTO_DECLARE) != 0;\n\t}\n\n\tbool IsIntoMergeStatement (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_MERGE_STATEMENT) != 0;\n\t}\n\n\tbool IsIntoCreateStatement (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_INTO_CREATE) != 0;\n\t}\n\n\tbool IsIntoCreateViewStatement (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_INTO_CREATE_VIEW) != 0;\n\t}\n\n\tbool IsIntoCreateViewAsStatement (sql_state_t sqlStatesLine) noexcept {\n\t\treturn (sqlStatesLine & MASK_INTO_CREATE_VIEW_AS_STATEMENT) != 0;\n\t}\n\n\tsql_state_t ForLine(Sci_Position lineNumber) {\n\t\treturn sqlStatement.ValueAt(lineNumber);\n\t}\n\n\tSQLStates() {}\n\nprivate :\n\tSparseState <sql_state_t> sqlStatement;\n\tenum {\n\t\tMASK_NESTED_CASES                         = 0x0001FF,\n\t\tMASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT = 0x000200,\n\t\tMASK_CASE_MERGE_WITHOUT_WHEN_FOUND        = 0x000400,\n\t\tMASK_MERGE_STATEMENT                      = 0x000800,\n\t\tMASK_INTO_DECLARE                         = 0x001000,\n\t\tMASK_INTO_EXCEPTION                       = 0x002000,\n\t\tMASK_INTO_CONDITION                       = 0x004000,\n\t\tMASK_IGNORE_WHEN                          = 0x008000,\n\t\tMASK_INTO_CREATE                          = 0x010000,\n\t\tMASK_INTO_CREATE_VIEW                     = 0x020000,\n\t\tMASK_INTO_CREATE_VIEW_AS_STATEMENT        = 0x040000\n\t};\n};\n\n// Options used for LexerSQL\nstruct OptionsSQL {\n\tbool fold;\n\tbool foldAtElse;\n\tbool foldComment;\n\tbool foldCompact;\n\tbool foldOnlyBegin;\n\tbool sqlBackticksIdentifier;\n\tbool sqlNumbersignComment;\n\tbool sqlBackslashEscapes;\n\tbool sqlAllowDottedWord;\n\tOptionsSQL() {\n\t\tfold = false;\n\t\tfoldAtElse = false;\n\t\tfoldComment = false;\n\t\tfoldCompact = false;\n\t\tfoldOnlyBegin = false;\n\t\tsqlBackticksIdentifier = false;\n\t\tsqlNumbersignComment = false;\n\t\tsqlBackslashEscapes = false;\n\t\tsqlAllowDottedWord = false;\n\t}\n};\n\nconst char * const sqlWordListDesc[] = {\n\t\"Keywords\",\n\t\"Database Objects\",\n\t\"PLDoc\",\n\t\"SQL*Plus\",\n\t\"User Keywords 1\",\n\t\"User Keywords 2\",\n\t\"User Keywords 3\",\n\t\"User Keywords 4\",\n\tnullptr\n};\n\nstruct OptionSetSQL : public OptionSet<OptionsSQL> {\n\tOptionSetSQL() {\n\t\tDefineProperty(\"fold\", &OptionsSQL::fold);\n\n\t\tDefineProperty(\"fold.sql.at.else\", &OptionsSQL::foldAtElse,\n\t\t               \"This option enables SQL folding on a \\\"ELSE\\\" and \\\"ELSIF\\\" line of an IF statement.\");\n\n\t\tDefineProperty(\"fold.comment\", &OptionsSQL::foldComment);\n\n\t\tDefineProperty(\"fold.compact\", &OptionsSQL::foldCompact);\n\n\t\tDefineProperty(\"fold.sql.only.begin\", &OptionsSQL::foldOnlyBegin,\n\t\t               \"Set to 1 to only fold on 'begin' but not other keywords.\");\n\n\t\tDefineProperty(\"lexer.sql.backticks.identifier\", &OptionsSQL::sqlBackticksIdentifier,\n\t\t               \"Recognise backtick quoting of identifiers.\");\n\n\t\tDefineProperty(\"lexer.sql.numbersign.comment\", &OptionsSQL::sqlNumbersignComment,\n\t\t               \"If \\\"lexer.sql.numbersign.comment\\\" property is set to 0 a line beginning with '#' will not be a comment.\");\n\n\t\tDefineProperty(\"sql.backslash.escapes\", &OptionsSQL::sqlBackslashEscapes,\n\t\t               \"Enables backslash as an escape character in SQL.\");\n\n\t\tDefineProperty(\"lexer.sql.allow.dotted.word\", &OptionsSQL::sqlAllowDottedWord,\n\t\t               \"Set to 1 to colourise recognized words with dots \"\n\t\t               \"(recommended for Oracle PL/SQL objects).\");\n\n\t\tDefineWordListSets(sqlWordListDesc);\n\t}\n};\n\nclass LexerSQL : public DefaultLexer {\npublic :\n\tLexerSQL() : DefaultLexer(\"sql\", SCLEX_SQL) {}\n\n\tvirtual ~LexerSQL() {}\n\n\tint SCI_METHOD Version () const override {\n\t\treturn lvRelease5;\n\t}\n\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\n\tconst char * SCI_METHOD PropertyNames() override {\n\t\treturn osSQL.PropertyNames();\n\t}\n\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osSQL.PropertyType(name);\n\t}\n\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osSQL.DescribeProperty(name);\n\t}\n\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override {\n\t\tif (osSQL.PropertySet(&options, key, val)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn -1;\n\t}\n\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osSQL.PropertyGet(key);\n\t}\n\n\tconst char * SCI_METHOD DescribeWordListSets() override {\n\t\treturn osSQL.DescribeWordListSets();\n\t}\n\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid * SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn 0;\n\t}\n\n\tstatic ILexer5 *LexerFactorySQL() {\n\t\treturn new LexerSQL();\n\t}\nprivate:\n\tbool IsStreamCommentStyle(int style) noexcept {\n\t\treturn style == SCE_SQL_COMMENT ||\n\t\t       style == SCE_SQL_COMMENTDOC ||\n\t\t       style == SCE_SQL_COMMENTDOCKEYWORD ||\n\t\t       style == SCE_SQL_COMMENTDOCKEYWORDERROR;\n\t}\n\n\tbool IsCommentStyle (int style) noexcept {\n\t\tswitch (style) {\n\t\tcase SCE_SQL_COMMENT :\n\t\tcase SCE_SQL_COMMENTDOC :\n\t\tcase SCE_SQL_COMMENTLINE :\n\t\tcase SCE_SQL_COMMENTLINEDOC :\n\t\tcase SCE_SQL_COMMENTDOCKEYWORD :\n\t\tcase SCE_SQL_COMMENTDOCKEYWORDERROR :\n\t\t\treturn true;\n\t\tdefault :\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tbool IsCommentLine (Sci_Position line, LexAccessor &styler) {\n\t\tconst Sci_Position pos = styler.LineStart(line);\n\t\tconst Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\t\tfor (Sci_Position i = pos; i + 1 < eol_pos; i++) {\n\t\t\tconst int style = styler.StyleAt(i);\n\t\t\t// MySQL needs -- comments to be followed by space or control char\n\t\t\tif (style == SCE_SQL_COMMENTLINE && styler.Match(i, \"--\"))\n\t\t\t\treturn true;\n\t\t\telse if (!IsASpaceOrTab(styler[i]))\n\t\t\t\treturn false;\n\t\t}\n\t\treturn false;\n\t}\n\n\tOptionsSQL options;\n\tOptionSetSQL osSQL;\n\tSQLStates sqlStates;\n\n\tWordList keywords1;\n\tWordList keywords2;\n\tWordList kw_pldoc;\n\tWordList kw_sqlplus;\n\tWordList kw_user1;\n\tWordList kw_user2;\n\tWordList kw_user3;\n\tWordList kw_user4;\n};\n\nSci_Position SCI_METHOD LexerSQL::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = 0;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords1;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywords2;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &kw_pldoc;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &kw_sqlplus;\n\t\tbreak;\n\tcase 4:\n\t\twordListN = &kw_user1;\n\t\tbreak;\n\tcase 5:\n\t\twordListN = &kw_user2;\n\t\tbreak;\n\tcase 6:\n\t\twordListN = &kw_user3;\n\t\tbreak;\n\tcase 7:\n\t\twordListN = &kw_user4;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tif (wordListN->Set(wl, true)) {\n\t\t\tfirstModification = 0;\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nvoid SCI_METHOD LexerSQL::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tLexAccessor styler(pAccess);\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tint styleBeforeDCKeyword = SCE_SQL_DEFAULT;\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\t// Determine if the current state should terminate.\n\t\tswitch (sc.state) {\n\t\tcase SCE_SQL_OPERATOR:\n\t\t\tsc.SetState(SCE_SQL_DEFAULT);\n\t\t\tbreak;\n\t\tcase SCE_SQL_NUMBER:\n\t\t\t// We stop the number definition on non-numerical non-dot non-eE non-sign char\n\t\t\tif (!IsANumberChar(sc.ch, sc.chPrev)) {\n\t\t\t\tsc.SetState(SCE_SQL_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SQL_IDENTIFIER:\n\t\t\tif (!IsAWordChar(sc.ch, options.sqlAllowDottedWord)) {\n\t\t\t\tint nextState = SCE_SQL_DEFAULT;\n\t\t\t\tchar s[1000];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tif (keywords1.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_SQL_WORD);\n\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_SQL_WORD2);\n\t\t\t\t} else if (kw_sqlplus.InListAbbreviated(s, '~')) {\n\t\t\t\t\tsc.ChangeState(SCE_SQL_SQLPLUS);\n\t\t\t\t\tif (strncmp(s, \"rem\", 3) == 0) {\n\t\t\t\t\t\tnextState = SCE_SQL_SQLPLUS_COMMENT;\n\t\t\t\t\t} else if (strncmp(s, \"pro\", 3) == 0) {\n\t\t\t\t\t\tnextState = SCE_SQL_SQLPLUS_PROMPT;\n\t\t\t\t\t}\n\t\t\t\t} else if (kw_user1.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_SQL_USER1);\n\t\t\t\t} else if (kw_user2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_SQL_USER2);\n\t\t\t\t} else if (kw_user3.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_SQL_USER3);\n\t\t\t\t} else if (kw_user4.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_SQL_USER4);\n\t\t\t\t}\n\t\t\t\tsc.SetState(nextState);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SQL_QUOTEDIDENTIFIER:\n\t\t\tif (sc.ch == 0x60) {\n\t\t\t\tif (sc.chNext == 0x60) {\n\t\t\t\t\tsc.Forward();\t// Ignore it\n\t\t\t\t} else {\n\t\t\t\t\tsc.ForwardSetState(SCE_SQL_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SQL_COMMENT:\n\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_SQL_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SQL_COMMENTDOC:\n\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_SQL_DEFAULT);\n\t\t\t} else if (sc.ch == '@' || sc.ch == '\\\\') { // Doxygen support\n\t\t\t\t// Verify that we have the conditions to mark a comment-doc-keyword\n\t\t\t\tif ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {\n\t\t\t\t\tstyleBeforeDCKeyword = SCE_SQL_COMMENTDOC;\n\t\t\t\t\tsc.SetState(SCE_SQL_COMMENTDOCKEYWORD);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SQL_COMMENTLINE:\n\t\tcase SCE_SQL_COMMENTLINEDOC:\n\t\tcase SCE_SQL_SQLPLUS_COMMENT:\n\t\tcase SCE_SQL_SQLPLUS_PROMPT:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_SQL_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SQL_COMMENTDOCKEYWORD:\n\t\t\tif ((styleBeforeDCKeyword == SCE_SQL_COMMENTDOC) && sc.Match('*', '/')) {\n\t\t\t\tsc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_SQL_DEFAULT);\n\t\t\t} else if (!IsADoxygenChar(sc.ch)) {\n\t\t\t\tchar s[100];\n\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\tif (!isspace(sc.ch) || !kw_pldoc.InList(s + 1)) {\n\t\t\t\t\tsc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);\n\t\t\t\t}\n\t\t\t\tsc.SetState(styleBeforeDCKeyword);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SQL_CHARACTER:\n\t\t\tif (options.sqlBackslashEscapes && sc.ch == '\\\\') {\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tif (sc.chNext == '\\'') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tsc.ForwardSetState(SCE_SQL_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SQL_STRING:\n\t\t\tif (options.sqlBackslashEscapes && sc.ch == '\\\\') {\n\t\t\t\t// Escape sequence\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tif (sc.chNext == '\\\"') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tsc.ForwardSetState(SCE_SQL_DEFAULT);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SCE_SQL_QOPERATOR:\n\t\t\t// Locate the unique Q operator character\n\t\t\tsc.Complete();\n\t\t\tchar qOperator = 0x00;\n\t\t\tfor (Sci_Position styleStartPos = sc.currentPos; styleStartPos > 0; --styleStartPos) {\n\t\t\t\tif (styler.StyleAt(styleStartPos - 1) != SCE_SQL_QOPERATOR) {\n\t\t\t\t\tqOperator = styler.SafeGetCharAt(styleStartPos + 2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchar qComplement = 0x00;\n\n\t\t\tif (qOperator == '<') {\n\t\t\t\tqComplement = '>';\n\t\t\t} else if (qOperator == '(') {\n\t\t\t\tqComplement = ')';\n\t\t\t} else if (qOperator == '{') {\n\t\t\t\tqComplement = '}';\n\t\t\t} else if (qOperator == '[') {\n\t\t\t\tqComplement = ']';\n\t\t\t} else {\n\t\t\t\tqComplement = qOperator;\n\t\t\t}\n\n\t\t\tif (sc.Match(qComplement, '\\'')) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_SQL_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_SQL_DEFAULT) {\n\t\t\tif (sc.Match('q', '\\'') || sc.Match('Q', '\\'')) {\n\t\t\t\tsc.SetState(SCE_SQL_QOPERATOR);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)) ||\n\t\t\t          ((sc.ch == '-' || sc.ch == '+') && IsADigit(sc.chNext) && !IsADigit(sc.chPrev))) {\n\t\t\t\tsc.SetState(SCE_SQL_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_SQL_IDENTIFIER);\n\t\t\t} else if (sc.ch == 0x60 && options.sqlBackticksIdentifier) {\n\t\t\t\tsc.SetState(SCE_SQL_QUOTEDIDENTIFIER);\n\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\tif (sc.Match(\"/**\") || sc.Match(\"/*!\")) {\t// Support of Doxygen doc. style\n\t\t\t\t\tsc.SetState(SCE_SQL_COMMENTDOC);\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_SQL_COMMENT);\n\t\t\t\t}\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('-', '-')) {\n\t\t\t\t// MySQL requires a space or control char after --\n\t\t\t\t// http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html\n\t\t\t\t// Perhaps we should enforce that with proper property:\n\t\t\t\t//~ \t\t\t} else if (sc.Match(\"-- \")) {\n\t\t\t\tsc.SetState(SCE_SQL_COMMENTLINE);\n\t\t\t} else if (sc.ch == '#' && options.sqlNumbersignComment) {\n\t\t\t\tsc.SetState(SCE_SQL_COMMENTLINEDOC);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_SQL_CHARACTER);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_SQL_STRING);\n\t\t\t} else if (isoperator(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_SQL_OPERATOR);\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nvoid SCI_METHOD LexerSQL::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tif (!options.fold)\n\t\treturn;\n\tLexAccessor styler(pAccess);\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\n\tif (lineCurrent > 0) {\n\t\t// Backtrack to previous line in case need to fix its fold status for folding block of single-line comments (i.e. '--').\n\t\tSci_Position lastNLPos = -1;\n\t\t// And keep going back until we find an operator ';' followed\n\t\t// by white-space and/or comments. This will improve folding.\n\t\twhile (--startPos > 0) {\n\t\t\tconst char ch = styler[startPos];\n\t\t\tif (ch == '\\n' || (ch == '\\r' && styler[startPos + 1] != '\\n')) {\n\t\t\t\tlastNLPos = startPos;\n\t\t\t} else if (ch == ';' &&\n\t\t\t\t   styler.StyleAt(startPos) == SCE_SQL_OPERATOR) {\n\t\t\t\tbool isAllClear = true;\n\t\t\t\tfor (Sci_Position tempPos = startPos + 1;\n\t\t\t\t     tempPos < lastNLPos;\n\t\t\t\t     ++tempPos) {\n\t\t\t\t\tconst int tempStyle = styler.StyleAt(tempPos);\n\t\t\t\t\tif (!IsCommentStyle(tempStyle)\n\t\t\t\t\t    && tempStyle != SCE_SQL_DEFAULT) {\n\t\t\t\t\t\tisAllClear = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (isAllClear) {\n\t\t\t\t\tstartPos = lastNLPos + 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlineCurrent = styler.GetLine(startPos);\n\t\tif (lineCurrent > 0)\n\t\t\tlevelCurrent = FoldLevelStart(styler.LevelAt(lineCurrent - 1));\n\t}\n\t// And because folding ends at ';', keep going until we find one\n\t// Otherwise if create ... view ... as is split over multiple\n\t// lines the folding won't always update immediately.\n\tconst Sci_PositionU docLength = styler.Length();\n\tfor (; endPos < docLength; ++endPos) {\n\t\tif (styler.SafeGetCharAt(endPos) == ';') {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tbool endFound = false;\n\tbool isUnfoldingIgnored = false;\n\t// this statementFound flag avoids to fold when the statement is on only one line by ignoring ELSE or ELSIF\n\t// eg. \"IF condition1 THEN ... ELSIF condition2 THEN ... ELSE ... END IF;\"\n\tbool statementFound = false;\n\tsql_state_t sqlStatesCurrentLine = 0;\n\tif (!options.foldOnlyBegin) {\n\t\tsqlStatesCurrentLine = sqlStates.ForLine(lineCurrent);\n\t}\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tconst int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tconst bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (atEOL || (!IsCommentStyle(style) && ch == ';')) {\n\t\t\tif (endFound) {\n\t\t\t\t//Maybe this is the end of \"EXCEPTION\" BLOCK (eg. \"BEGIN ... EXCEPTION ... END;\")\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);\n\t\t\t}\n\t\t\t// set endFound and isUnfoldingIgnored to false if EOL is reached or ';' is found\n\t\t\tendFound = false;\n\t\t\tisUnfoldingIgnored = false;\n\t\t}\n\t\tif ((!IsCommentStyle(style) && ch == ';')) {\n\t\t\tif (sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine)) {\n\t\t\t\t// This is the end of \"MERGE\" statement.\n\t\t\t\tif (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))\n\t\t\t\t\tlevelNext--;\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, false);\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t\tif (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine))\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, false);\n\t\t\tif (sqlStates.IsIntoCreateStatement(sqlStatesCurrentLine)) {\n\t\t\t\tif (sqlStates.IsIntoCreateViewStatement(sqlStatesCurrentLine)) {\n\t\t\t\t\tif (sqlStates.IsIntoCreateViewAsStatement(sqlStatesCurrentLine)) {\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCreateViewAsStatement(sqlStatesCurrentLine, false);\n\t\t\t\t\t}\n\t\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCreateViewStatement(sqlStatesCurrentLine, false);\n\t\t\t\t}\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCreateStatement(sqlStatesCurrentLine, false);\n\t\t\t}\n\t\t}\n\t\tif (ch == ':' && chNext == '=' && !IsCommentStyle(style))\n\t\t\tsqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true);\n\n\t\tif (options.foldComment && IsStreamCommentStyle(style)) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (options.foldComment && (style == SCE_SQL_COMMENTLINE)) {\n\t\t\t// MySQL needs -- comments to be followed by space or control char\n\t\t\tif ((ch == '-') && (chNext == '-')) {\n\t\t\t\tconst char chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\tconst char chNext3 = styler.SafeGetCharAt(i + 3);\n\t\t\t\tif (chNext2 == '{' || chNext3 == '{') {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (chNext2 == '}' || chNext3 == '}') {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Fold block of single-line comments (i.e. '--').\n\t\tif (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {\n\t\t\tif (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelNext++;\n\t\t\telse if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\tlevelNext--;\n\t\t}\n\t\tif (style == SCE_SQL_OPERATOR) {\n\t\t\tif (ch == '(') {\n\t\t\t\tif (levelCurrent > levelNext)\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == ')') {\n\t\t\t\tlevelNext--;\n\t\t\t} else if ((!options.foldOnlyBegin) && ch == ';') {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, false);\n\t\t\t}\n\t\t}\n\t\t// If new keyword (cannot trigger on elseif or nullif, does less tests)\n\t\tif (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {\n\t\t\tconstexpr int MAX_KW_LEN = 9;\t// Maximum length of folding keywords\n\t\t\tchar s[MAX_KW_LEN + 2]{};\n\t\t\tunsigned int j = 0;\n\t\t\tfor (; j < MAX_KW_LEN + 1; j++) {\n\t\t\t\tif (!iswordchar(styler[i + j])) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ts[j] = MakeLowerCase(styler[i + j]);\n\t\t\t}\n\t\t\tif (j == MAX_KW_LEN + 1) {\n\t\t\t\t// Keyword too long, don't test it\n\t\t\t\ts[0] = '\\0';\n\t\t\t} else {\n\t\t\t\ts[j] = '\\0';\n\t\t\t}\n\t\t\tif (!options.foldOnlyBegin &&\n\t\t\t        strcmp(s, \"select\") == 0) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true);\n\t\t\t} else if (strcmp(s, \"if\") == 0) {\n\t\t\t\tif (endFound) {\n\t\t\t\t\tendFound = false;\n\t\t\t\t\tif (options.foldOnlyBegin && !isUnfoldingIgnored) {\n\t\t\t\t\t\t// this end isn't for begin block, but for if block (\"end if;\")\n\t\t\t\t\t\t// so ignore previous \"end\" by increment levelNext.\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (!options.foldOnlyBegin)\n\t\t\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);\n\t\t\t\t\tif (levelCurrent > levelNext) {\n\t\t\t\t\t\t// doesn't include this line into the folding block\n\t\t\t\t\t\t// because doesn't hide IF (eg \"END; IF\")\n\t\t\t\t\t\tlevelCurrent = levelNext;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (!options.foldOnlyBegin &&\n\t\t\t           strcmp(s, \"then\") == 0 &&\n\t\t\t           sqlStates.IsIntoCondition(sqlStatesCurrentLine)) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, false);\n\t\t\t\tif (!options.foldOnlyBegin) {\n\t\t\t\t\tif (levelCurrent > levelNext) {\n\t\t\t\t\t\tlevelCurrent = levelNext;\n\t\t\t\t\t}\n\t\t\t\t\tif (!statementFound)\n\t\t\t\t\t\tlevelNext++;\n\n\t\t\t\t\tstatementFound = true;\n\t\t\t\t} else if (levelCurrent > levelNext) {\n\t\t\t\t\t// doesn't include this line into the folding block\n\t\t\t\t\t// because doesn't hide LOOP or CASE (eg \"END; LOOP\" or \"END; CASE\")\n\t\t\t\t\tlevelCurrent = levelNext;\n\t\t\t\t}\n\t\t\t} else if (strcmp(s, \"loop\") == 0 ||\n\t\t\t           strcmp(s, \"case\") == 0) {\n\t\t\t\tif (endFound) {\n\t\t\t\t\tendFound = false;\n\t\t\t\t\tif (options.foldOnlyBegin && !isUnfoldingIgnored) {\n\t\t\t\t\t\t// this end isn't for begin block, but for loop block (\"end loop;\") or case block (\"end case;\")\n\t\t\t\t\t\t// so ignore previous \"end\" by increment levelNext.\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t}\n\t\t\t\t\tif ((!options.foldOnlyBegin) && strcmp(s, \"case\") == 0) {\n\t\t\t\t\t\tsqlStatesCurrentLine = sqlStates.EndCaseBlock(sqlStatesCurrentLine);\n\t\t\t\t\t\tif (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))\n\t\t\t\t\t\t\tlevelNext--; //again for the \"end case;\" and block when\n\t\t\t\t\t}\n\t\t\t\t} else if (!options.foldOnlyBegin) {\n\t\t\t\t\tif (strcmp(s, \"case\") == 0) {\n\t\t\t\t\t\tsqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine);\n\t\t\t\t\t\tsqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (levelCurrent > levelNext)\n\t\t\t\t\t\tlevelCurrent = levelNext;\n\n\t\t\t\t\tif (!statementFound)\n\t\t\t\t\t\tlevelNext++;\n\n\t\t\t\t\tstatementFound = true;\n\t\t\t\t} else if (levelCurrent > levelNext) {\n\t\t\t\t\t// doesn't include this line into the folding block\n\t\t\t\t\t// because doesn't hide LOOP or CASE (eg \"END; LOOP\" or \"END; CASE\")\n\t\t\t\t\tlevelCurrent = levelNext;\n\t\t\t\t}\n\t\t\t} else if ((!options.foldOnlyBegin) && (\n\t\t\t               // folding for ELSE and ELSIF block only if foldAtElse is set\n\t\t\t               // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)\n\t\t\t               options.foldAtElse && !statementFound) && strcmp(s, \"elsif\") == 0) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);\n\t\t\t\tlevelCurrent--;\n\t\t\t\tlevelNext--;\n\t\t\t} else if ((!options.foldOnlyBegin) && (\n\t\t\t               // folding for ELSE and ELSIF block only if foldAtElse is set\n\t\t\t               // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)\n\t\t\t               options.foldAtElse && !statementFound) && strcmp(s, \"else\") == 0) {\n\t\t\t\t// prevent also ELSE is on the same line (eg. \"ELSE ... END IF;\")\n\t\t\t\tstatementFound = true;\n\t\t\t\tif (sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine) && sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) {\n\t\t\t\t\tsqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false);\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else {\n\t\t\t\t\t// we are in same case \"} ELSE {\" in C language\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t} else if (strcmp(s, \"begin\") == 0) {\n\t\t\t\tlevelNext++;\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, false);\n\t\t\t} else if ((strcmp(s, \"end\") == 0) ||\n\t\t\t           // SQL Anywhere permits IF ... ELSE ... ENDIF\n\t\t\t           // will only be active if \"endif\" appears in the\n\t\t\t           // keyword list.\n\t\t\t           (strcmp(s, \"endif\") == 0)) {\n\t\t\t\tendFound = true;\n\t\t\t\tlevelNext--;\n\t\t\t\tif (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine) && !sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))\n\t\t\t\t\tlevelNext--;\n\t\t\t\tif (levelNext < SC_FOLDLEVELBASE) {\n\t\t\t\t\tlevelNext = SC_FOLDLEVELBASE;\n\t\t\t\t\tisUnfoldingIgnored = true;\n\t\t\t\t}\n\t\t\t} else if ((!options.foldOnlyBegin) &&\n\t\t\t           strcmp(s, \"when\") == 0 &&\n\t\t\t           !sqlStates.IsIgnoreWhen(sqlStatesCurrentLine) &&\n\t\t\t           !sqlStates.IsIntoExceptionBlock(sqlStatesCurrentLine) && (\n\t\t\t               sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine) ||\n\t\t\t               sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine)\n\t\t\t               )\n\t\t\t           ) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);\n\n\t\t\t\t// Don't foldind when CASE and WHEN are on the same line (with flag statementFound) (eg. \"CASE selector WHEN expression1 THEN sequence_of_statements1;\\n\")\n\t\t\t\t// and same way for MERGE statement.\n\t\t\t\tif (!statementFound) {\n\t\t\t\t\tif (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) {\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t}\n\t\t\t\t\tsqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false);\n\t\t\t\t}\n\t\t\t} else if ((!options.foldOnlyBegin) && strcmp(s, \"exit\") == 0) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, true);\n\t\t\t} else if ((!options.foldOnlyBegin) && !sqlStates.IsIntoDeclareBlock(sqlStatesCurrentLine) && strcmp(s, \"exception\") == 0) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, true);\n\t\t\t} else if ((!options.foldOnlyBegin) &&\n\t\t\t           (strcmp(s, \"declare\") == 0 ||\n\t\t\t            strcmp(s, \"function\") == 0 ||\n\t\t\t            strcmp(s, \"procedure\") == 0 ||\n\t\t\t            strcmp(s, \"package\") == 0)) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, true);\n\t\t\t} else if ((!options.foldOnlyBegin) &&\n\t\t\t           strcmp(s, \"merge\") == 0) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, true);\n\t\t\t\tsqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);\n\t\t\t\tlevelNext++;\n\t\t\t\tstatementFound = true;\n\t\t\t} else if ((!options.foldOnlyBegin) &&\n\t\t\t\t   strcmp(s, \"create\") == 0) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCreateStatement(sqlStatesCurrentLine, true);\n\t\t\t} else if ((!options.foldOnlyBegin) &&\n\t\t\t\t   strcmp(s, \"view\") == 0 &&\n\t\t\t\t   sqlStates.IsIntoCreateStatement(sqlStatesCurrentLine)) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCreateViewStatement(sqlStatesCurrentLine, true);\n\t\t\t} else if ((!options.foldOnlyBegin) &&\n\t\t\t\t   strcmp(s, \"as\") == 0 &&\n\t\t\t\t   sqlStates.IsIntoCreateViewStatement(sqlStatesCurrentLine) &&\n\t\t\t\t   ! sqlStates.IsIntoCreateViewAsStatement(sqlStatesCurrentLine)) {\n\t\t\t\tsqlStatesCurrentLine = sqlStates.IntoCreateViewAsStatement(sqlStatesCurrentLine, true);\n\t\t\t\tlevelNext++;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tconst int lev = FoldLevelForCurrentNext(levelCurrent, levelNext) |\n\t\t\t\tFoldLevelFlags(levelCurrent, levelNext, visibleChars == 0 && options.foldCompact);\n\t\t\tstyler.SetLevelIfDifferent(lineCurrent, lev);\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tvisibleChars = 0;\n\t\t\tstatementFound = false;\n\t\t\tif (!options.foldOnlyBegin)\n\t\t\t\tsqlStates.Set(lineCurrent, sqlStatesCurrentLine);\n\t\t}\n\t\tif (!isspacechar(ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n}\n\n}\n\nextern const LexerModule lmSQL(SCLEX_SQL, LexerSQL::LexerFactorySQL, \"sql\", sqlWordListDesc);\n"
  },
  {
    "path": "lexers/LexSTTXT.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexSTTXT.cxx\n ** Lexer for Structured Text language.\n ** Written by Pavel Bulochkin\n **/\n// The License.txt file describes the conditions under which this software may be distributed.\n\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ClassifySTTXTWord(WordList *keywordlists[], StyleContext &sc)\n{\n\tchar s[256] = { 0 };\n\tsc.GetCurrentLowered(s, sizeof(s));\n\n \tif ((*keywordlists[0]).InList(s)) {\n \t\tsc.ChangeState(SCE_STTXT_KEYWORD);\n \t}\n\n\telse if ((*keywordlists[1]).InList(s)) {\n\t\tsc.ChangeState(SCE_STTXT_TYPE);\n\t}\n\n\telse if ((*keywordlists[2]).InList(s)) {\n\t\tsc.ChangeState(SCE_STTXT_FUNCTION);\n\t}\n\n\telse if ((*keywordlists[3]).InList(s)) {\n\t\tsc.ChangeState(SCE_STTXT_FB);\n\t}\n\n\telse if ((*keywordlists[4]).InList(s)) {\n\t\tsc.ChangeState(SCE_STTXT_VARS);\n\t}\n\n\telse if ((*keywordlists[5]).InList(s)) {\n\t\tsc.ChangeState(SCE_STTXT_PRAGMAS);\n\t}\n\n\tsc.SetState(SCE_STTXT_DEFAULT);\n}\n\nstatic void ColouriseSTTXTDoc (Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\t\t\t\t\t\t  WordList *keywordlists[], Accessor &styler)\n{\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tCharacterSet setWord(CharacterSet::setAlphaNum, \"_\", 0x80, true);\n\tCharacterSet setWordStart(CharacterSet::setAlpha, \"_\", 0x80, true);\n\tCharacterSet setNumber(CharacterSet::setDigits, \"_.eE\");\n\tCharacterSet setHexNumber(CharacterSet::setDigits, \"_abcdefABCDEF\");\n\tCharacterSet setOperator(CharacterSet::setNone,\",.+-*/:;<=>[]()%&\");\n\tCharacterSet setDataTime(CharacterSet::setDigits,\"_.-:dmshDMSH\");\n\n \tfor ( ; sc.More() ; sc.Forward())\n \t{\n\t\tif(sc.atLineStart && sc.state != SCE_STTXT_COMMENT)\n\t\t\tsc.SetState(SCE_STTXT_DEFAULT);\n\n\t\tswitch(sc.state)\n\t\t{\n\t\t\tcase SCE_STTXT_NUMBER: {\n\t\t\t\tif(!setNumber.Contains(sc.ch))\n\t\t\t\t\tsc.SetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_HEXNUMBER: {\n\t\t\t\tif (setHexNumber.Contains(sc.ch))\n\t\t\t\t\tcontinue;\n\t\t\t\telse if(setDataTime.Contains(sc.ch))\n\t\t\t\t\tsc.ChangeState(SCE_STTXT_DATETIME);\n\t\t\t\telse if(setWord.Contains(sc.ch))\n\t\t\t\t\tsc.ChangeState(SCE_STTXT_DEFAULT);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_DATETIME: {\n\t\t\t\tif (setDataTime.Contains(sc.ch))\n\t\t\t\t\tcontinue;\n\t\t\t\telse if(setWord.Contains(sc.ch))\n\t\t\t\t\tsc.ChangeState(SCE_STTXT_DEFAULT);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_OPERATOR: {\n\t\t\t\tsc.SetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_PRAGMA: {\n\t\t\t\tif (sc.ch == '}')\n\t\t\t\t\tsc.ForwardSetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_COMMENTLINE: {\n\t\t\t\tif (sc.atLineStart)\n\t\t\t\t\tsc.SetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_COMMENT: {\n\t\t\t\tif(sc.Match('*',')'))\n\t\t\t\t{\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_STTXT_DEFAULT);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_STRING1: {\n\t\t\t\tif(sc.atLineEnd)\n\t\t\t\t\tsc.SetState(SCE_STTXT_STRINGEOL);\n\t\t\t\telse if(sc.ch == '\\'' && sc.chPrev != '$')\n\t\t\t\t\tsc.ForwardSetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_STRING2: {\n\t\t\t\tif (sc.atLineEnd)\n\t\t\t\t\tsc.SetState(SCE_STTXT_STRINGEOL);\n\t\t\t\telse if(sc.ch == '\\\"' && sc.chPrev != '$')\n\t\t\t\t\tsc.ForwardSetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_STRINGEOL: {\n\t\t\t\tif(sc.atLineStart)\n\t\t\t\t\tsc.SetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_CHARACTER: {\n\t\t\t\tif(setHexNumber.Contains(sc.ch))\n\t\t\t\t\tsc.SetState(SCE_STTXT_HEXNUMBER);\n\t\t\t\telse if(setDataTime.Contains(sc.ch))\n\t\t\t\t\tsc.SetState(SCE_STTXT_DATETIME);\n\t\t\t\telse sc.SetState(SCE_STTXT_DEFAULT);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SCE_STTXT_IDENTIFIER: {\n\t\t\t\tif(!setWord.Contains(sc.ch))\n\t\t\t\t\tClassifySTTXTWord(keywordlists, sc);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif(sc.state == SCE_STTXT_DEFAULT)\n\t\t{\n\t\t\tif(IsADigit(sc.ch))\n\t\t\t\tsc.SetState(SCE_STTXT_NUMBER);\n\t\t\telse if (setWordStart.Contains(sc.ch))\n\t\t\t\tsc.SetState(SCE_STTXT_IDENTIFIER);\n\t\t\telse if (sc.Match('/', '/'))\n\t\t\t\tsc.SetState(SCE_STTXT_COMMENTLINE);\n\t\t\telse if(sc.Match('(', '*'))\n\t\t\t\tsc.SetState(SCE_STTXT_COMMENT);\n\t\t\telse if (sc.ch == '{')\n\t\t\t\tsc.SetState(SCE_STTXT_PRAGMA);\n\t\t\telse if (sc.ch == '\\'')\n\t\t\t\tsc.SetState(SCE_STTXT_STRING1);\n\t\t\telse if (sc.ch == '\\\"')\n\t\t\t\tsc.SetState(SCE_STTXT_STRING2);\n\t\t\telse if(sc.ch == '#')\n\t\t\t\tsc.SetState(SCE_STTXT_CHARACTER);\n\t\t\telse if (setOperator.Contains(sc.ch))\n\t\t\t\tsc.SetState(SCE_STTXT_OPERATOR);\n\t\t}\n \t}\n\n\tif (sc.state == SCE_STTXT_IDENTIFIER && setWord.Contains(sc.chPrev))\n\t\tClassifySTTXTWord(keywordlists, sc);\n\n\tsc.Complete();\n}\n\nstatic const char * const STTXTWordListDesc[] = {\n\t\"Keywords\",\n\t\"Types\",\n\t\"Functions\",\n\t\"FB\",\n\t\"Local_Var\",\n\t\"Local_Pragma\",\n\t0\n};\n\nstatic bool IsCommentLine(Sci_Position line, Accessor &styler, bool type)\n{\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eolPos = styler.LineStart(line + 1) - 1;\n\n\tfor (Sci_Position i = pos; i < eolPos; i++)\n\t{\n\t\tchar ch = styler[i];\n\t\tchar chNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styler.StyleAt(i);\n\n\t\tif(type) {\n\t\t\t if (ch == '/' && chNext == '/' && style == SCE_STTXT_COMMENTLINE)\n\t\t\t\treturn true;\n\t\t}\n\t\telse if (ch == '(' && chNext == '*' && style == SCE_STTXT_COMMENT)\n\t\t\tbreak;\n\n\t\tif (!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\n\tfor (Sci_Position i = eolPos-2; i>pos; i--)\n\t{\n\t\tchar ch = styler[i];\n\t\tchar chPrev = styler.SafeGetCharAt(i-1);\n\t\tint style = styler.StyleAt(i);\n\n\t\tif(ch == ')' && chPrev == '*' && style == SCE_STTXT_COMMENT)\n\t\t\treturn true;\n\t\tif(!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\n\treturn false;\n}\n\nstatic bool IsPragmaLine(Sci_Position line, Accessor &styler)\n{\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eolPos = styler.LineStart(line+1) - 1;\n\n\tfor (Sci_Position i = pos ; i < eolPos ; i++)\n\t{\n\t\tchar ch = styler[i];\n\t\tint style = styler.StyleAt(i);\n\n\t\tif(ch == '{' && style == SCE_STTXT_PRAGMA)\n\t\t\treturn true;\n\t\telse if (!IsASpaceOrTab(ch))\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nstatic void GetRangeUpper(Sci_PositionU start,Sci_PositionU end,Accessor &styler,char *s,Sci_PositionU len)\n{\n\tSci_PositionU i = 0;\n\twhile ((i < end - start + 1) && (i < len-1)) {\n\t\ts[i] = static_cast<char>(toupper(styler[start + i]));\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n}\n\nstatic void ClassifySTTXTWordFoldPoint(int &levelCurrent,Sci_PositionU lastStart,\n\t\t\t\t\t\t\t\t\t Sci_PositionU currentPos, Accessor &styler)\n{\n\tchar s[256];\n\tGetRangeUpper(lastStart, currentPos, styler, s, sizeof(s));\n\n\t// See Table C.2 - Keywords\n\tif (!strcmp(s, \"ACTION\") ||\n\t\t!strcmp(s, \"CASE\") ||\n\t\t!strcmp(s, \"CONFIGURATION\") ||\n\t\t!strcmp(s, \"FOR\") ||\n\t\t!strcmp(s, \"FUNCTION\") ||\n\t\t!strcmp(s, \"FUNCTION_BLOCK\") ||\n\t\t!strcmp(s, \"IF\") ||\n\t\t!strcmp(s, \"INITIAL_STEP\") ||\n\t\t!strcmp(s, \"REPEAT\") ||\n\t\t!strcmp(s, \"RESOURCE\") ||\n\t\t!strcmp(s, \"STEP\") ||\n\t\t!strcmp(s, \"STRUCT\") ||\n\t\t!strcmp(s, \"TRANSITION\") ||\n\t\t!strcmp(s, \"TYPE\") ||\n\t\t!strcmp(s, \"VAR\") ||\n\t\t!strcmp(s, \"VAR_INPUT\") ||\n\t\t!strcmp(s, \"VAR_OUTPUT\") ||\n\t\t!strcmp(s, \"VAR_IN_OUT\") ||\n\t\t!strcmp(s, \"VAR_TEMP\") ||\n\t\t!strcmp(s, \"VAR_EXTERNAL\") ||\n\t\t!strcmp(s, \"VAR_ACCESS\") ||\n\t\t!strcmp(s, \"VAR_CONFIG\") ||\n\t\t!strcmp(s, \"VAR_GLOBAL\") ||\n\t\t!strcmp(s, \"WHILE\"))\n\t{\n\t\tlevelCurrent++;\n\t}\n\telse if (!strcmp(s, \"END_ACTION\") ||\n\t\t!strcmp(s, \"END_CASE\") ||\n\t\t!strcmp(s, \"END_CONFIGURATION\") ||\n\t\t!strcmp(s, \"END_FOR\") ||\n\t\t!strcmp(s, \"END_FUNCTION\") ||\n\t\t!strcmp(s, \"END_FUNCTION_BLOCK\") ||\n\t\t!strcmp(s, \"END_IF\") ||\n\t\t!strcmp(s, \"END_REPEAT\") ||\n\t\t!strcmp(s, \"END_RESOURCE\") ||\n\t\t!strcmp(s, \"END_STEP\") ||\n\t\t!strcmp(s, \"END_STRUCT\") ||\n\t\t!strcmp(s, \"END_TRANSITION\") ||\n\t\t!strcmp(s, \"END_TYPE\") ||\n\t\t!strcmp(s, \"END_VAR\") ||\n\t\t!strcmp(s, \"END_WHILE\"))\n\t{\n\t\tlevelCurrent--;\n\t\tif (levelCurrent < SC_FOLDLEVELBASE) {\n\t\t\tlevelCurrent = SC_FOLDLEVELBASE;\n\t\t}\n\t}\n}\n\nstatic void FoldSTTXTDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[],Accessor &styler)\n{\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldPreprocessor = styler.GetPropertyInt(\"fold.preprocessor\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tSci_Position lastStart = 0;\n\n\tCharacterSet setWord(CharacterSet::setAlphaNum, \"_\", 0x80, true);\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++)\n\t{\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (foldComment && style == SCE_STTXT_COMMENT) {\n\t\t\tif(stylePrev != SCE_STTXT_COMMENT)\n\t\t\t\tlevelCurrent++;\n\t\t\telse if(styleNext != SCE_STTXT_COMMENT && !atEOL)\n\t\t\t\tlevelCurrent--;\n\t\t}\n\t\tif ( foldComment && atEOL && ( IsCommentLine(lineCurrent, styler,false)\n\t\t\t|| IsCommentLine(lineCurrent,styler,true))) {\n \t\t\tif(!IsCommentLine(lineCurrent-1, styler,true) && IsCommentLine(lineCurrent+1, styler,true))\n\t\t\t\tlevelCurrent++;\n\t\t\tif (IsCommentLine(lineCurrent-1, styler,true) && !IsCommentLine(lineCurrent+1, styler,true))\n\t\t\t\tlevelCurrent--;\n\t\t\tif (!IsCommentLine(lineCurrent-1, styler,false) && IsCommentLine(lineCurrent+1, styler,false))\n\t\t\t\tlevelCurrent++;\n\t\t\tif (IsCommentLine(lineCurrent-1, styler,false) && !IsCommentLine(lineCurrent+1, styler,false))\n\t\t\t\tlevelCurrent--;\n\t\t}\n\t\tif(foldPreprocessor && atEOL && IsPragmaLine(lineCurrent, styler)) {\n\t\t\tif(!IsPragmaLine(lineCurrent-1, styler) && IsPragmaLine(lineCurrent+1, styler ))\n\t\t\t\tlevelCurrent++;\n\t\t\telse if(IsPragmaLine(lineCurrent-1, styler) && !IsPragmaLine(lineCurrent+1, styler))\n\t\t\t\tlevelCurrent--;\n\t\t}\n\t\tif (stylePrev != SCE_STTXT_KEYWORD && style == SCE_STTXT_KEYWORD) {\n\t\t\t\tlastStart = i;\n\t\t}\n\t\tif(stylePrev == SCE_STTXT_KEYWORD) {\n\t\t\tif(setWord.Contains(ch) && !setWord.Contains(chNext))\n\t\t\t\tClassifySTTXTWordFoldPoint(levelCurrent,lastStart, i, styler);\n\t\t}\n\t\tif (!IsASpace(ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent))\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\n\t\t// If we didn't reach the EOL in previous loop, store line level and whitespace information.\n\t\t// The rest will be filled in later...\n\t\tint lev = levelPrev;\n\t\tif (visibleChars == 0 && foldCompact)\n\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\tstyler.SetLevel(lineCurrent, lev);\n\t}\n}\n\nextern const LexerModule lmSTTXT(SCLEX_STTXT, ColouriseSTTXTDoc, \"fcST\", FoldSTTXTDoc, STTXTWordListDesc);\n"
  },
  {
    "path": "lexers/LexScriptol.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexScriptol.cxx\n ** Lexer for Scriptol.\n **/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ClassifyWordSol(Sci_PositionU start, Sci_PositionU end, WordList &keywords, Accessor &styler, char *prevWord)\n{\n    char s[100] = \"\";\n    bool wordIsNumber = isdigit(styler[start]) != 0;\n    for (Sci_PositionU i = 0; i < end - start + 1 && i < 30; i++)\n     {\n           s[i] = styler[start + i];\n           s[i + 1] = '\\0';\n     }\n    char chAttr = SCE_SCRIPTOL_IDENTIFIER;\n    if (0 == strcmp(prevWord, \"class\"))       chAttr = SCE_SCRIPTOL_CLASSNAME;\n    else if (wordIsNumber)                    chAttr = SCE_SCRIPTOL_NUMBER;\n    else if (keywords.InList(s))              chAttr = SCE_SCRIPTOL_KEYWORD;\n    else for (Sci_PositionU i = 0; i < end - start + 1; i++)  // test dotted idents\n    {\n        if (styler[start + i] == '.')\n        {\n            styler.ColourTo(start + i - 1, chAttr);\n            styler.ColourTo(start + i, SCE_SCRIPTOL_OPERATOR);\n        }\n    }\n    styler.ColourTo(end, chAttr);\n    strcpy(prevWord, s);\n}\n\nstatic bool IsSolComment(Accessor &styler, Sci_Position pos, Sci_Position len)\n{\n   if(len > 0)\n   {\n     char c = styler[pos];\n     if(c == '`') return true;\n     if(len > 1)\n     {\n        if(c == '/')\n        {\n          c = styler[pos + 1];\n          if(c == '/') return true;\n          if(c == '*') return true;\n        }\n     }\n   }\n   return false;\n}\n\nstatic bool IsSolStringStart(char ch)\n{\n    if (ch == '\\'' || ch == '\"')  return true;\n    return false;\n}\n\nstatic bool IsSolWordStart(char ch)\n{\n    return (iswordchar(ch) && !IsSolStringStart(ch));\n}\n\n\nstatic int GetSolStringState(Accessor &styler, Sci_Position i, Sci_Position *nextIndex)\n{\n\tchar ch = styler.SafeGetCharAt(i);\n\tchar chNext = styler.SafeGetCharAt(i + 1);\n\n        if (ch != '\\\"' && ch != '\\'')\n        {\n            *nextIndex = i + 1;\n            return SCE_SCRIPTOL_DEFAULT;\n\t}\n        // ch is either single or double quotes in string\n        // code below seem non-sense but is here for future extensions\n\tif (ch == chNext && ch == styler.SafeGetCharAt(i + 2))\n        {\n          *nextIndex = i + 3;\n          if(ch == '\\\"') return SCE_SCRIPTOL_TRIPLE;\n          if(ch == '\\'') return SCE_SCRIPTOL_TRIPLE;\n          return SCE_SCRIPTOL_STRING;\n\t}\n        else\n        {\n          *nextIndex = i + 1;\n          if (ch == '\"') return SCE_SCRIPTOL_STRING;\n          else           return SCE_SCRIPTOL_STRING;\n\t}\n}\n\n\nstatic void ColouriseSolDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                            WordList *keywordlists[], Accessor &styler)\n {\n\n\tSci_Position lengthDoc = startPos + length;\n        char stringType = '\\\"';\n\n\tif (startPos > 0)\n        {\n            Sci_Position lineCurrent = styler.GetLine(startPos);\n            if (lineCurrent > 0)\n            {\n              startPos = styler.LineStart(lineCurrent-1);\n              if (startPos == 0) initStyle = SCE_SCRIPTOL_DEFAULT;\n              else               initStyle = styler.StyleAt(startPos-1);\n            }\n\t}\n\n\tstyler.StartAt(startPos);\n\n\tWordList &keywords = *keywordlists[0];\n\n\tchar prevWord[200];\n\tprevWord[0] = '\\0';\n        if (length == 0)  return;\n\n\tint state = initStyle & 31;\n\n\tSci_Position nextIndex = 0;\n        char chPrev  = ' ';\n        char chPrev2 = ' ';\n        char chNext  = styler[startPos];\n\tstyler.StartSegment(startPos);\n\tfor (Sci_Position i = startPos; i < lengthDoc; i++)\n        {\n\n       char ch = chNext;\n       chNext = styler.SafeGetCharAt(i + 1);\n\n       if ((ch == '\\r' && chNext != '\\n') || (ch == '\\n') || (i == lengthDoc))\n       {\n          if ((state == SCE_SCRIPTOL_DEFAULT) ||\n              (state == SCE_SCRIPTOL_TRIPLE) ||\n              (state == SCE_SCRIPTOL_COMMENTBLOCK))\n          {\n              styler.ColourTo(i, state);\n          }\n        }\n\n        if (styler.IsLeadByte(ch))\n         {\n             chNext = styler.SafeGetCharAt(i + 2);\n             chPrev  = ' ';\n             chPrev2 = ' ';\n             i += 1;\n             continue;\n         }\n\n        if (state == SCE_SCRIPTOL_STRINGEOL)\n         {\n             if (ch != '\\r' && ch != '\\n')\n             {\n                    styler.ColourTo(i - 1, state);\n                    state = SCE_SCRIPTOL_DEFAULT;\n             }\n         }\n\n        if (state == SCE_SCRIPTOL_DEFAULT)\n         {\n            if (IsSolWordStart(ch))\n            {\n                 styler.ColourTo(i - 1, state);\n                 state = SCE_SCRIPTOL_KEYWORD;\n            }\n            else if (ch == '`')\n            {\n                styler.ColourTo(i - 1, state);\n                state = SCE_SCRIPTOL_COMMENTLINE;\n            }\n            else if (ch == '/')\n            {\n                styler.ColourTo(i - 1, state);\n                if(chNext == '/') state = SCE_SCRIPTOL_CSTYLE;\n                if(chNext == '*') state = SCE_SCRIPTOL_COMMENTBLOCK;\n            }\n\n            else if (IsSolStringStart(ch))\n            {\n               styler.ColourTo(i - 1, state);\n               state = GetSolStringState(styler, i, &nextIndex);\n               if(state == SCE_SCRIPTOL_STRING)\n               {\n                 stringType = ch;\n               }\n               if (nextIndex != i + 1)\n               {\n                   i = nextIndex - 1;\n                   ch = ' ';\n                   chPrev = ' ';\n                   chNext = styler.SafeGetCharAt(i + 1);\n               }\n           }\n            else if (isoperator(ch))\n            {\n                 styler.ColourTo(i - 1, state);\n                 styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);\n            }\n          }\n          else if (state == SCE_SCRIPTOL_KEYWORD)\n          {\n              if (!iswordchar(ch))\n              {\n                 ClassifyWordSol(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);\n                 state = SCE_SCRIPTOL_DEFAULT;\n                 if (ch == '`')\n                 {\n                     state = chNext == '`' ? SCE_SCRIPTOL_PERSISTENT : SCE_SCRIPTOL_COMMENTLINE;\n                 }\n                 else if (IsSolStringStart(ch))\n                 {\n                    styler.ColourTo(i - 1, state);\n                    state = GetSolStringState(styler, i, &nextIndex);\n                    if (nextIndex != i + 1)\n                    {\n                       i = nextIndex - 1;\n                       ch = ' ';\n                       chPrev = ' ';\n                       chNext = styler.SafeGetCharAt(i + 1);\n                     }\n                 }\n                 else if (isoperator(ch))\n                 {\n                     styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);\n                 }\n             }\n          }\n          else\n          {\n            if (state == SCE_SCRIPTOL_COMMENTLINE ||\n                state == SCE_SCRIPTOL_PERSISTENT ||\n                state == SCE_SCRIPTOL_CSTYLE)\n            {\n                 if (ch == '\\r' || ch == '\\n')\n                 {\n                     styler.ColourTo(i - 1, state);\n                     state = SCE_SCRIPTOL_DEFAULT;\n                 }\n            }\n            else if(state == SCE_SCRIPTOL_COMMENTBLOCK)\n            {\n              if(chPrev == '*' && ch == '/')\n              {\n                styler.ColourTo(i, state);\n                state = SCE_SCRIPTOL_DEFAULT;\n              }\n            }\n            else if ((state == SCE_SCRIPTOL_STRING) ||\n                     (state == SCE_SCRIPTOL_CHARACTER))\n            {\n               if ((ch == '\\r' || ch == '\\n') && (chPrev != '\\\\'))\n                {\n                    styler.ColourTo(i - 1, state);\n                    state = SCE_SCRIPTOL_STRINGEOL;\n                }\n                else if (ch == '\\\\')\n                {\n                   if (chNext == '\\\"' || chNext == '\\'' || chNext == '\\\\')\n                   {\n                        i++;\n                        ch = chNext;\n                        chNext = styler.SafeGetCharAt(i + 1);\n                   }\n                 }\n                else if ((ch == '\\\"') || (ch == '\\''))\n                {\n                    // must match the entered quote type\n                    if(ch == stringType)\n                    {\n                      styler.ColourTo(i, state);\n                      state = SCE_SCRIPTOL_DEFAULT;\n                    }\n                 }\n             }\n             else if (state == SCE_SCRIPTOL_TRIPLE)\n             {\n                if ((ch == '\\'' && chPrev == '\\'' && chPrev2 == '\\'') ||\n                    (ch == '\\\"' && chPrev == '\\\"' && chPrev2 == '\\\"'))\n                 {\n                    styler.ColourTo(i, state);\n                    state = SCE_SCRIPTOL_DEFAULT;\n                 }\n             }\n\n           }\n          chPrev2 = chPrev;\n          chPrev = ch;\n\t}\n        if (state == SCE_SCRIPTOL_KEYWORD)\n        {\n            ClassifyWordSol(styler.GetStartSegment(),\n                 lengthDoc-1, keywords, styler, prevWord);\n\t}\n        else\n        {\n            styler.ColourTo(lengthDoc-1, state);\n\t}\n}\n\nstatic void FoldSolDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n\t\t\t\t\t\t   WordList *[], Accessor &styler)\n {\n\tSci_Position lengthDoc = startPos + length;\n\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (startPos > 0)\n        {\n          if (lineCurrent > 0)\n          {\n               lineCurrent--;\n               startPos = styler.LineStart(lineCurrent);\n               if (startPos == 0)\n                    initStyle = SCE_SCRIPTOL_DEFAULT;\n               else\n                    initStyle = styler.StyleAt(startPos-1);\n           }\n\t}\n\tint state = initStyle & 31;\n\tint spaceFlags = 0;\n        int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment);\n        if (state == SCE_SCRIPTOL_TRIPLE)\n             indentCurrent |= SC_FOLDLEVELWHITEFLAG;\n\tchar chNext = styler[startPos];\n\tfor (Sci_Position i = startPos; i < lengthDoc; i++)\n         {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styler.StyleAt(i) & 31;\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n') || (i == lengthDoc))\n                {\n                   int lev = indentCurrent;\n                   int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsSolComment);\n                   if (style == SCE_SCRIPTOL_TRIPLE)\n                        indentNext |= SC_FOLDLEVELWHITEFLAG;\n                   if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))\n                    {\n                        // Only non whitespace lines can be headers\n                        if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))\n                        {\n                              lev |= SC_FOLDLEVELHEADERFLAG;\n                        }\n                        else if (indentNext & SC_FOLDLEVELWHITEFLAG)\n                        {\n                             // Line after is blank so check the next - maybe should continue further?\n                             int spaceFlags2 = 0;\n                             int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsSolComment);\n                             if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK))\n                             {\n                                   lev |= SC_FOLDLEVELHEADERFLAG;\n                              }\n                        }\n                    }\n                   indentCurrent = indentNext;\n                   styler.SetLevel(lineCurrent, lev);\n                   lineCurrent++;\n\t\t}\n\t}\n}\n\nextern const LexerModule lmScriptol(SCLEX_SCRIPTOL, ColouriseSolDoc, \"scriptol\", FoldSolDoc);\n"
  },
  {
    "path": "lexers/LexSmalltalk.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexSmalltalk.cxx\n ** Lexer for Smalltalk language.\n ** Written by Sergey Philippov, sphilippov-at-gmail-dot-com\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n/*\n| lexTable classificationBlock charClasses |\ncharClasses := #(#DecDigit #Letter #Special #Upper #BinSel).\nlexTable := ByteArray new: 128.\nclassificationBlock := [ :charClass :chars |\n    | flag |\n    flag := 1 bitShift: (charClasses indexOf: charClass) - 1.\n    chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].\n\nclassificationBlock\n    value: #DecDigit value: '0123456789';\n    value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n    value: #Special value: '()[]{};.^:';\n    value: #BinSel value: '~@%&*-+=|\\/,<>?!';\n    value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n\n((String new: 500) streamContents: [ :stream |\n    stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.\n    lexTable keysAndValuesDo: [ :index :value |\n        ((index - 1) rem: 16) == 0 ifTrue: [\n            stream crLf; tab]\n        ifFalse: [\n            stream space].\n        stream print: value.\n        index ~= 256 ifTrue: [\n            stream nextPut: $,]].\n    stream crLf; nextPutAll: '};'; crLf.\n\n    charClasses keysAndValuesDo: [ :index :name |\n        stream\n            crLf;\n            nextPutAll: (\n                ('static inline bool is<1s>(int ch) {return (ch > 0) && (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')\n                    expandMacrosWith: name with: (1 bitShift: (index - 1)))\n    ]]) edit\n*/\n\n// autogenerated {{{{\n\nstatic int ClassificationTable[256] = {\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 16, 0, 0, 0, 16, 16, 0, 4, 4, 16, 16, 16, 16, 4, 16,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 16, 16, 16, 16,\n    16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 16, 4, 4, 2,\n    0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 16, 4, 16, 0,\n};\n\nstatic inline bool isDecDigit(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 1) != 0);}\nstatic inline bool isLetter(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 2) != 0);}\nstatic inline bool isSpecial(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 4) != 0);}\nstatic inline bool isUpper(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 8) != 0);}\nstatic inline bool isBinSel(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 16) != 0);}\n// autogenerated }}}}\n\nstatic inline bool isAlphaNumeric(int ch) {\n    return isDecDigit(ch) || isLetter(ch);\n}\n\nstatic inline bool isDigitOfRadix(int ch, int radix)\n{\n    if (isDecDigit(ch))\n        return (ch - '0') < radix;\n    else if (!isUpper(ch))\n        return false;\n    else\n        return (ch - 'A' + 10) < radix;\n}\n\nstatic inline void skipComment(StyleContext& sc)\n{\n    while (sc.More() && sc.ch != '\\\"')\n        sc.Forward();\n}\n\nstatic inline void skipString(StyleContext& sc)\n{\n    while (sc.More()) {\n        if (sc.ch == '\\'') {\n            if (sc.chNext != '\\'')\n                return;\n            sc.Forward();\n        }\n        sc.Forward();\n    }\n}\n\nstatic void handleHash(StyleContext& sc)\n{\n    if (isSpecial(sc.chNext)) {\n        sc.SetState(SCE_ST_SPECIAL);\n        return;\n    }\n\n    sc.SetState(SCE_ST_SYMBOL);\n    sc.Forward();\n    if (sc.ch == '\\'') {\n        sc.Forward();\n        skipString(sc);\n    }\n    else {\n        if (isLetter(sc.ch)) {\n            while (isAlphaNumeric(sc.chNext) || sc.chNext == ':')\n                sc.Forward();\n        }\n        else if (isBinSel(sc.ch)) {\n            while (isBinSel(sc.chNext))\n                sc.Forward();\n        }\n    }\n}\n\nstatic inline void handleSpecial(StyleContext& sc)\n{\n    if (sc.ch == ':' && sc.chNext == '=') {\n        sc.SetState(SCE_ST_ASSIGN);\n        sc.Forward();\n    }\n    else {\n        if (sc.ch == '^')\n            sc.SetState(SCE_ST_RETURN);\n        else\n            sc.SetState(SCE_ST_SPECIAL);\n    }\n}\n\nstatic inline void skipInt(StyleContext& sc, int radix)\n{\n    while (isDigitOfRadix(sc.chNext, radix))\n        sc.Forward();\n}\n\nstatic void handleNumeric(StyleContext& sc)\n{\n    char num[256];\n    int nl;\n    int radix;\n\n    sc.SetState(SCE_ST_NUMBER);\n    num[0] = static_cast<char>(sc.ch);\n    nl = 1;\n    while (isDecDigit(sc.chNext)) {\n        num[nl++] = static_cast<char>(sc.chNext);\n        sc.Forward();\n        if (nl+1 == sizeof(num)/sizeof(num[0])) // overrun check\n            break;\n    }\n    if (sc.chNext == 'r') {\n        num[nl] = 0;\n        if (num[0] == '-')\n            radix = atoi(num + 1);\n        else\n            radix = atoi(num);\n        sc.Forward();\n        if (sc.chNext == '-')\n            sc.Forward();\n        skipInt(sc, radix);\n    }\n    else\n        radix = 10;\n    if (sc.chNext == '.') {\n        if (!isDigitOfRadix(sc.GetRelative(2), radix))\n            return;\n        sc.Forward();\n        skipInt(sc, radix);\n    }\n    \n    if (sc.chNext == 's') {\n        // ScaledDecimal\n        sc.Forward();\n        while (isDecDigit(sc.chNext))\n            sc.Forward();\n        return;\n    }\n    else if (sc.chNext != 'e' && sc.chNext != 'd' && sc.chNext != 'q')\n        return;\n    sc.Forward();\n    if (sc.chNext == '+' || sc.chNext == '-')\n        sc.Forward();\n    skipInt(sc, radix);\n}\n\nstatic inline void handleBinSel(StyleContext& sc)\n{\n    sc.SetState(SCE_ST_BINARY);\n    while (isBinSel(sc.chNext))\n        sc.Forward();\n}\n\nstatic void handleLetter(StyleContext& sc, WordList* specialSelectorList)\n{\n    char ident[256];\n    int il;\n    int state;\n    bool doubleColonPresent;\n\n    sc.SetState(SCE_ST_DEFAULT);\n\n    ident[0] = static_cast<char>(sc.ch);\n    il = 1;\n    while (isAlphaNumeric(sc.chNext)) {\n        ident[il++] = static_cast<char>(sc.chNext);\n        sc.Forward();\n        if (il+2 == sizeof(ident)/sizeof(ident[0])) // overrun check\n            break;\n    }\n\n    if (sc.chNext == ':') {\n        doubleColonPresent = true;\n        ident[il++] = ':';\n        sc.Forward();\n    }\n    else\n        doubleColonPresent = false;\n    ident[il] = 0;\n\n    if (specialSelectorList->InList(ident))\n            state = SCE_ST_SPEC_SEL;\n    else if (doubleColonPresent)\n            state = SCE_ST_KWSEND;\n    else if (isUpper(ident[0]))\n        state = SCE_ST_GLOBAL;\n    else {\n        if (!strcmp(ident, \"self\"))\n            state = SCE_ST_SELF;\n        else if (!strcmp(ident, \"super\"))\n            state = SCE_ST_SUPER;\n        else if (!strcmp(ident, \"nil\"))\n            state = SCE_ST_NIL;\n        else if (!strcmp(ident, \"true\") || !strcmp(ident, \"false\"))\n            state = SCE_ST_BOOL;\n        else\n            state = SCE_ST_DEFAULT;\n    }\n\n    sc.ChangeState(state);\n}\n\nstatic void colorizeSmalltalkDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *wordLists[], Accessor &styler)\n{\n    StyleContext sc(startPos, length, initStyle, styler);\n\n    if (initStyle == SCE_ST_COMMENT) {\n        skipComment(sc);\n        if (sc.More())\n            sc.Forward();\n    }\n    else if (initStyle == SCE_ST_STRING) {\n        skipString(sc);\n        if (sc.More())\n            sc.Forward();\n    }\n\n    for (; sc.More(); sc.Forward()) {\n        int ch;\n\n        ch = sc.ch;\n        if (ch == '\\\"') {\n            sc.SetState(SCE_ST_COMMENT);\n            sc.Forward();\n            skipComment(sc);\n        }\n        else if (ch == '\\'') {\n            sc.SetState(SCE_ST_STRING);\n            sc.Forward();\n            skipString(sc);\n        }\n        else if (ch == '#')\n            handleHash(sc);\n        else if (ch == '$') {\n            sc.SetState(SCE_ST_CHARACTER);\n            sc.Forward();\n        }\n        else if (isSpecial(ch))\n            handleSpecial(sc);\n        else if (isDecDigit(ch))\n            handleNumeric(sc);\n        else if (isLetter(ch))\n            handleLetter(sc, wordLists[0]);\n        else if (isBinSel(ch)) {\n            if (ch == '-' && isDecDigit(sc.chNext))\n                handleNumeric(sc);\n            else\n                handleBinSel(sc);\n        }\n        else\n            sc.SetState(SCE_ST_DEFAULT);\n    }\n    sc.Complete();\n}\n\nstatic const char* const smalltalkWordListDesc[] = {\n    \"Special selectors\",\n    0\n};\n\nextern const LexerModule lmSmalltalk(SCLEX_SMALLTALK, colorizeSmalltalkDoc, \"smalltalk\", NULL, smalltalkWordListDesc);\n"
  },
  {
    "path": "lexers/LexSorcus.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexSorcus.cxx\n** Lexer for SORCUS installation files\n** Written by Eugen Bitter and Christoph Baumann at SORCUS Computer, Heidelberg Germany\n** Based on the ASM Lexer by The Black Horus\n**/\n\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\n//each character a..z and A..Z + '_' can be part of a keyword\n//additionally numbers that follow 'M' can be contained in a keyword\nstatic inline bool IsSWordStart(const int ch, const int prev_ch)\n{\n    if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M')))\n        return true;\n\n    return false;\n}\n\n\n//only digits that are not preceded by 'M' count as a number\nstatic inline bool IsSorcusNumber(const int ch, const int prev_ch)\n{\n    if ((isdigit(ch)) && (prev_ch != 'M'))\n        return true;\n\n    return false;\n}\n\n\n//only = is a valid operator\nstatic inline bool IsSorcusOperator(const int ch)\n{\n    if (ch == '=')\n        return true;\n\n    return false;\n}\n\n\nstatic void ColouriseSorcusDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                               Accessor &styler)\n{\n\n    WordList &Command = *keywordlists[0];\n    WordList &Parameter = *keywordlists[1];\n    WordList &Constant = *keywordlists[2];\n\n    // Do not leak onto next line\n    if (initStyle == SCE_SORCUS_STRINGEOL)\n        initStyle = SCE_SORCUS_DEFAULT;\n\n    StyleContext sc(startPos, length, initStyle, styler);\n\n    for (; sc.More(); sc.Forward())\n    {\n\n        // Prevent SCE_SORCUS_STRINGEOL from leaking back to previous line\n        if (sc.atLineStart && (sc.state == SCE_SORCUS_STRING))\n        {\n            sc.SetState(SCE_SORCUS_STRING);\n        }\n\n        // Determine if the current state should terminate.\n        if (sc.state == SCE_SORCUS_OPERATOR)\n        {\n            if (!IsSorcusOperator(sc.ch))\n            {\n                sc.SetState(SCE_SORCUS_DEFAULT);\n            }\n        }\n        else if(sc.state == SCE_SORCUS_NUMBER)\n        {\n            if(!IsSorcusNumber(sc.ch, sc.chPrev))\n            {\n                sc.SetState(SCE_SORCUS_DEFAULT);\n            }\n        }\n        else if (sc.state == SCE_SORCUS_IDENTIFIER)\n        {\n            if (!IsSWordStart(sc.ch, sc.chPrev))\n            {\n                char s[100];\n\n                sc.GetCurrent(s, sizeof(s));\n\n                if (Command.InList(s))\n                {\n                    sc.ChangeState(SCE_SORCUS_COMMAND);\n                }\n                else if (Parameter.InList(s))\n                {\n                    sc.ChangeState(SCE_SORCUS_PARAMETER);\n                }\n                else if (Constant.InList(s))\n                {\n                    sc.ChangeState(SCE_SORCUS_CONSTANT);\n                }\n\n                sc.SetState(SCE_SORCUS_DEFAULT);\n            }\n        }\n        else if (sc.state == SCE_SORCUS_COMMENTLINE )\n        {\n            if (sc.atLineEnd)\n            {\n                sc.SetState(SCE_SORCUS_DEFAULT);\n            }\n        }\n        else if (sc.state == SCE_SORCUS_STRING)\n        {\n            if (sc.ch == '\\\"')\n            {\n                sc.ForwardSetState(SCE_SORCUS_DEFAULT);\n            }\n            else if (sc.atLineEnd)\n            {\n                sc.ChangeState(SCE_SORCUS_STRINGEOL);\n                sc.ForwardSetState(SCE_SORCUS_DEFAULT);\n            }\n        }\n\n        // Determine if a new state should be entered.\n        if (sc.state == SCE_SORCUS_DEFAULT)\n        {\n            if ((sc.ch == ';') || (sc.ch == '\\''))\n            {\n                sc.SetState(SCE_SORCUS_COMMENTLINE);\n            }\n            else if (IsSWordStart(sc.ch, sc.chPrev))\n            {\n                sc.SetState(SCE_SORCUS_IDENTIFIER);\n            }\n            else if (sc.ch == '\\\"')\n            {\n                sc.SetState(SCE_SORCUS_STRING);\n            }\n            else if (IsSorcusOperator(sc.ch))\n            {\n                sc.SetState(SCE_SORCUS_OPERATOR);\n            }\n            else if (IsSorcusNumber(sc.ch, sc.chPrev))\n            {\n                sc.SetState(SCE_SORCUS_NUMBER);\n            }\n        }\n\n    }\n    sc.Complete();\n}\n\n\nstatic const char* const SorcusWordListDesc[] = {\"Command\",\"Parameter\", \"Constant\", 0};\n\nextern const LexerModule lmSorc(SCLEX_SORCUS, ColouriseSorcusDoc, \"sorcins\", 0, SorcusWordListDesc);\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "lexers/LexSpecman.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexSpecman.cxx\n ** Lexer for Specman E language.\n ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\\'');\n}\n\nstatic inline bool IsANumberChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '\\'');\n}\n\nstatic inline bool IsAWordStart(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '`');\n}\n\nstatic void ColouriseSpecmanDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                            Accessor &styler, bool caseSensitive) {\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\tWordList &keywords4 = *keywordlists[3];\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_SN_STRINGEOL)\n\t\tinitStyle = SCE_SN_CODE;\n\n\tint visibleChars = 0;\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.atLineStart && (sc.state == SCE_SN_STRING)) {\n\t\t\t// Prevent SCE_SN_STRINGEOL from leaking back to previous line\n\t\t\tsc.SetState(SCE_SN_STRING);\n\t\t}\n\n\t\t// Handle line continuation generically.\n\t\tif (sc.ch == '\\\\') {\n\t\t\tif (sc.chNext == '\\n' || sc.chNext == '\\r') {\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the current state should terminate.\n\t\tif (sc.state == SCE_SN_OPERATOR) {\n\t\t\tsc.SetState(SCE_SN_CODE);\n\t\t} else if (sc.state == SCE_SN_NUMBER) {\n\t\t\tif (!IsANumberChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_SN_CODE);\n\t\t\t}\n\t\t} else if (sc.state == SCE_SN_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch) || (sc.ch == '.')) {\n\t\t\t\tchar s[100];\n\t\t\t\tif (caseSensitive) {\n\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t} else {\n\t\t\t\t\tsc.GetCurrentLowered(s, sizeof(s));\n\t\t\t\t}\n\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_SN_WORD);\n\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_SN_WORD2);\n\t\t\t\t} else if (keywords3.InList(s)) {\n                                        sc.ChangeState(SCE_SN_WORD3);\n\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\tsc.ChangeState(SCE_SN_USER);\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_SN_CODE);\n\t\t\t}\n\t\t} else if (sc.state == SCE_SN_PREPROCESSOR) {\n                        if (IsASpace(sc.ch)) {\n                                sc.SetState(SCE_SN_CODE);\n                        }\n\t\t} else if (sc.state == SCE_SN_DEFAULT) {\n\t\t\tif (sc.Match('<', '\\'')) {\n\t\t\t\tsc.Forward();\n\t\t\t\tsc.ForwardSetState(SCE_SN_CODE);\n\t\t\t}\n\t\t} else if (sc.state == SCE_SN_COMMENTLINE || sc.state == SCE_SN_COMMENTLINEBANG) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_SN_CODE);\n\t\t\t\tvisibleChars = 0;\n\t\t\t}\n\t\t} else if (sc.state == SCE_SN_STRING) {\n\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.ForwardSetState(SCE_SN_CODE);\n\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_SN_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_SN_CODE);\n\t\t\t\tvisibleChars = 0;\n\t\t\t}\n\t\t} else if (sc.state == SCE_SN_SIGNAL) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.ChangeState(SCE_SN_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_SN_CODE);\n\t\t\t\tvisibleChars = 0;\n\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.ForwardSetState(SCE_SN_CODE);\n\t\t\t}\n\t\t} else if (sc.state == SCE_SN_REGEXTAG) {\n\t\t\tif (!IsADigit(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_SN_CODE);\n\t\t\t}\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_SN_CODE) {\n\t\t\tif (sc.ch == '$' && IsADigit(sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_SN_REGEXTAG);\n                                sc.Forward();\n\t\t\t} else if (IsADigit(sc.ch)) {\n                                sc.SetState(SCE_SN_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_SN_IDENTIFIER);\n\t\t\t} else if (sc.Match('\\'', '>')) {\n                                sc.SetState(SCE_SN_DEFAULT);\n\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\tif (sc.Match(\"//!\"))\t// Nice to have a different comment style\n\t\t\t\t\tsc.SetState(SCE_SN_COMMENTLINEBANG);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_SN_COMMENTLINE);\n\t\t\t} else if (sc.Match('-', '-')) {\n\t\t\t\tif (sc.Match(\"--!\"))\t// Nice to have a different comment style\n\t\t\t\t\tsc.SetState(SCE_SN_COMMENTLINEBANG);\n\t\t\t\telse\n\t\t\t\t\tsc.SetState(SCE_SN_COMMENTLINE);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_SN_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_SN_SIGNAL);\n\t\t\t} else if (sc.ch == '#' && visibleChars == 0) {\n\t\t\t\t// Preprocessor commands are alone on their line\n\t\t\t\tsc.SetState(SCE_SN_PREPROCESSOR);\n\t\t\t\t// Skip whitespace between # and preprocessor word\n\t\t\t\tdo {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} while ((sc.ch == ' ' || sc.ch == '\\t') && sc.More());\n\t\t\t\tif (sc.atLineEnd) {\n\t\t\t\t\tsc.SetState(SCE_SN_CODE);\n\t\t\t\t}\n\t\t\t} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@') {\n\t\t\t\tsc.SetState(SCE_SN_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\t// Reset states to begining of colourise so no surprises\n\t\t\t// if different sets of lines lexed.\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!IsASpace(sc.ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\tsc.Complete();\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\nstatic void FoldNoBoxSpecmanDoc(Sci_PositionU startPos, Sci_Position length, int,\n                            Accessor &styler) {\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tbool foldAtElse = styler.GetPropertyInt(\"fold.at.else\", 0) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelMinCurrent = levelCurrent;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style;\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t//int stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (foldComment && (style == SCE_SN_COMMENTLINE)) {\n\t\t\tif (((ch == '/') && (chNext == '/')) ||\n                            ((ch == '-') && (chNext == '-'))) {\n\t\t\t\tchar chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (style == SCE_SN_OPERATOR) {\n\t\t\tif (ch == '{') {\n\t\t\t\t// Measure the minimum before a '{' to allow\n\t\t\t\t// folding on \"} else {\"\n\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t}\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tif (foldAtElse) {\n\t\t\t\tlevelUse = levelMinCurrent;\n\t\t\t}\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelMinCurrent = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n}\n\nstatic void FoldSpecmanDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[],\n                       Accessor &styler) {\n\tFoldNoBoxSpecmanDoc(startPos, length, initStyle, styler);\n}\n\nstatic const char * const specmanWordLists[] = {\n            \"Primary keywords and identifiers\",\n            \"Secondary keywords and identifiers\",\n            \"Sequence keywords and identifiers\",\n            \"User defined keywords and identifiers\",\n            \"Unused\",\n            0,\n        };\n\nstatic void ColouriseSpecmanDocSensitive(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n                                     Accessor &styler) {\n\tColouriseSpecmanDoc(startPos, length, initStyle, keywordlists, styler, true);\n}\n\n\nextern const LexerModule lmSpecman(SCLEX_SPECMAN, ColouriseSpecmanDocSensitive, \"specman\", FoldSpecmanDoc, specmanWordLists);\n"
  },
  {
    "path": "lexers/LexSpice.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexSpice.cxx\n ** Lexer for Spice\n **/\n// Copyright 2006 by Fabien Proriol\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n/*\n * Interface\n */\n\nstatic void ColouriseDocument(\n    Sci_PositionU startPos,\n    Sci_Position length,\n    int initStyle,\n    WordList *keywordlists[],\n    Accessor &styler);\n\nstatic const char * const spiceWordListDesc[] = {\n    \"Keywords\",        // SPICE command\n    \"Keywords2\",    // SPICE functions\n    \"Keywords3\",    // SPICE params\n    0\n};\n\nextern const LexerModule lmSpice(SCLEX_SPICE, ColouriseDocument, \"spice\", NULL, spiceWordListDesc);\n\n/*\n * Implementation\n */\n\nstatic void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);\nstatic void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute);\n\nstatic inline bool IsDelimiterCharacter(int ch);\nstatic inline bool IsSeparatorOrDelimiterCharacter(int ch);\n\nstatic void ColouriseComment(StyleContext& sc, bool&) {\n    sc.SetState(SCE_SPICE_COMMENTLINE);\n    while (!sc.atLineEnd) {\n        sc.Forward();\n    }\n}\n\nstatic void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {\n    apostropheStartsAttribute = sc.Match (')');\n    sc.SetState(SCE_SPICE_DELIMITER);\n    sc.ForwardSetState(SCE_SPICE_DEFAULT);\n}\n\nstatic void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {\n    apostropheStartsAttribute = true;\n    std::string number;\n    sc.SetState(SCE_SPICE_NUMBER);\n    // Get all characters up to a delimiter or a separator, including points, but excluding\n    // double points (ranges).\n    while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {\n        number += static_cast<char>(sc.ch);\n        sc.Forward();\n    }\n    // Special case: exponent with sign\n    if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&\n            (sc.ch == '+' || sc.ch == '-')) {\n        number += static_cast<char>(sc.ch);\n        sc.Forward ();\n        while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {\n            number += static_cast<char>(sc.ch);\n            sc.Forward();\n        }\n    }\n    sc.SetState(SCE_SPICE_DEFAULT);\n}\n\nstatic void ColouriseWhiteSpace(StyleContext& sc, bool& ) {\n    sc.SetState(SCE_SPICE_DEFAULT);\n    sc.ForwardSetState(SCE_SPICE_DEFAULT);\n}\n\nstatic void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {\n    apostropheStartsAttribute = true;\n    sc.SetState(SCE_SPICE_IDENTIFIER);\n    std::string word;\n    while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {\n        word += static_cast<char>(tolower(sc.ch));\n        sc.Forward();\n    }\n    if (keywords.InList(word.c_str())) {\n        sc.ChangeState(SCE_SPICE_KEYWORD);\n        if (word != \"all\") {\n            apostropheStartsAttribute = false;\n        }\n    }\n    else if (keywords2.InList(word.c_str())) {\n        sc.ChangeState(SCE_SPICE_KEYWORD2);\n        if (word != \"all\") {\n            apostropheStartsAttribute = false;\n        }\n    }\n    else if (keywords3.InList(word.c_str())) {\n        sc.ChangeState(SCE_SPICE_KEYWORD3);\n        if (word != \"all\") {\n            apostropheStartsAttribute = false;\n        }\n    }\n    sc.SetState(SCE_SPICE_DEFAULT);\n}\n\n//\n// ColouriseDocument\n//\nstatic void ColouriseDocument(\n    Sci_PositionU startPos,\n    Sci_Position length,\n    int initStyle,\n    WordList *keywordlists[],\n    Accessor &styler) {\n    WordList &keywords = *keywordlists[0];\n    WordList &keywords2 = *keywordlists[1];\n    WordList &keywords3 = *keywordlists[2];\n    StyleContext sc(startPos, length, initStyle, styler);\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;\n    while (sc.More()) {\n        if (sc.atLineEnd) {\n            // Go to the next line\n            sc.Forward();\n            lineCurrent++;\n            // Remember the line state for future incremental lexing\n            styler.SetLineState(lineCurrent, apostropheStartsAttribute);\n            // Don't continue any styles on the next line\n            sc.SetState(SCE_SPICE_DEFAULT);\n        }\n        // Comments\n        if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) {\n            ColouriseComment(sc, apostropheStartsAttribute);\n        // Whitespace\n        } else if (IsASpace(sc.ch)) {\n            ColouriseWhiteSpace(sc, apostropheStartsAttribute);\n        // Delimiters\n        } else if (IsDelimiterCharacter(sc.ch)) {\n            ColouriseDelimiter(sc, apostropheStartsAttribute);\n        // Numbers\n        } else if (IsADigit(sc.ch) || sc.ch == '#') {\n            ColouriseNumber(sc, apostropheStartsAttribute);\n        // Keywords or identifiers\n        } else {\n            ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute);\n        }\n    }\n    sc.Complete();\n}\n\nstatic inline bool IsDelimiterCharacter(int ch) {\n    switch (ch) {\n    case '&':\n    case '\\'':\n    case '(':\n    case ')':\n    case '*':\n    case '+':\n    case ',':\n    case '-':\n    case '.':\n    case '/':\n    case ':':\n    case ';':\n    case '<':\n    case '=':\n    case '>':\n    case '|':\n        return true;\n    default:\n        return false;\n    }\n}\n\nstatic inline bool IsSeparatorOrDelimiterCharacter(int ch) {\n    return IsASpace(ch) || IsDelimiterCharacter(ch);\n}\n"
  },
  {
    "path": "lexers/LexStata.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexStata.cxx\n ** Lexer for Stata\n **/\n// Author: Luke Rasmussen (luke.rasmussen@gmail.com)\n//\n// The License.txt file describes the conditions under which this software may\n// be distributed.\n//\n// Developed as part of the StatTag project at Northwestern University Feinberg\n// School of Medicine with funding from Northwestern University Clinical and\n// Translational Sciences Institute through CTSA grant UL1TR001422.  This work\n// has not been reviewed or endorsed by NCATS or the NIH.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ColouriseStataDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n    Accessor &styler) {\n\n    WordList &keywords = *keywordlists[0];\n    WordList &types = *keywordlists[1];\n    \n    CharacterSet setCouldBePostOp(CharacterSet::setNone, \"+-\");\n    CharacterSet setWordStart(CharacterSet::setAlpha, \"_\", 0x80, true);\n    CharacterSet setWord(CharacterSet::setAlphaNum, \"._\", 0x80, true);\n\n    StyleContext sc(startPos, length, initStyle, styler);\n    bool lineHasNonCommentChar = false;\n    for (; sc.More(); sc.Forward()) {\n        if (sc.atLineStart) {\n          lineHasNonCommentChar = false;\n        }\n\n        // Determine if the current state should terminate.\n        switch (sc.state) {\n            case SCE_STATA_OPERATOR:\n                sc.SetState(SCE_STATA_DEFAULT);\n                break;\n            case SCE_STATA_NUMBER:\n                // We accept almost anything because of hex. and number suffixes\n                if (!setWord.Contains(sc.ch)) {\n                    sc.SetState(SCE_STATA_DEFAULT);\n                }\n                break;\n            case SCE_STATA_IDENTIFIER:\n                if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {\n                    char s[1000];\n                    sc.GetCurrent(s, sizeof(s));\n                    if (keywords.InList(s)) {\n                        sc.ChangeState(SCE_STATA_WORD);\n                    }\n                    else if (types.InList(s)) {\n                        sc.ChangeState(SCE_STATA_TYPE);\n                    }\n                    sc.SetState(SCE_STATA_DEFAULT);\n                }\n                break;\n            case SCE_STATA_COMMENTBLOCK:\n                if (sc.Match('*', '/')) {\n                    sc.Forward();\n                    sc.ForwardSetState(SCE_STATA_DEFAULT);\n                }\n                break;\n            case SCE_STATA_COMMENT:\n            case SCE_STATA_COMMENTLINE:\n                if (sc.atLineStart) {\n                    sc.SetState(SCE_STATA_DEFAULT);\n                }\n                break;\n            case SCE_STATA_STRING:\n                if (sc.ch == '\\\\') {\n                    // Per Stata documentation, the following characters are the only ones that can\n                    // be escaped (not our typical set of quotes, etc.):\n                    // https://www.stata.com/support/faqs/programming/backslashes-and-macros/\n                    if (sc.chNext == '$' || sc.chNext == '`' || sc.chNext == '\\\\') {\n                        sc.Forward();\n                    }\n                }\n                else if (sc.ch == '\\\"') {\n                    sc.ForwardSetState(SCE_STATA_DEFAULT);\n                }\n                break;\n        }\n\n        // Determine if a new state should be entered.\n        if (sc.state == SCE_STATA_DEFAULT) {\n            if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n                lineHasNonCommentChar = true;\n                sc.SetState(SCE_STATA_NUMBER);\n            }\n            else if (setWordStart.Contains(sc.ch)) {\n                lineHasNonCommentChar = true;\n                sc.SetState(SCE_STATA_IDENTIFIER);\n            }\n            else if (sc.Match('*') && !lineHasNonCommentChar) {\n                sc.SetState(SCE_STATA_COMMENT);\n            }\n            else if (sc.Match('/', '*')) {\n                sc.SetState(SCE_STATA_COMMENTBLOCK);\n                sc.Forward();\t// Eat the * so it isn't used for the end of the comment\n            }\n            else if (sc.Match('/', '/')) {\n                sc.SetState(SCE_STATA_COMMENTLINE);\n            }\n            else if (sc.ch == '\\\"') {\n                lineHasNonCommentChar = true;\n                sc.SetState(SCE_STATA_STRING);\n            }\n            else if (isoperator(sc.ch)) {\n                lineHasNonCommentChar = true;\n                sc.SetState(SCE_STATA_OPERATOR);\n            }\n        }\n    }\n\n    sc.Complete();\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\nstatic void FoldStataDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],\n    Accessor &styler) {\n    bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n    bool foldAtElse = styler.GetPropertyInt(\"fold.at.else\", 0) != 0;\n    Sci_PositionU endPos = startPos + length;\n    int visibleChars = 0;\n    Sci_Position lineCurrent = styler.GetLine(startPos);\n    int levelCurrent = SC_FOLDLEVELBASE;\n    if (lineCurrent > 0)\n        levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;\n    int levelMinCurrent = levelCurrent;\n    int levelNext = levelCurrent;\n    char chNext = styler[startPos];\n    int styleNext = styler.StyleAt(startPos);\n    for (Sci_PositionU i = startPos; i < endPos; i++) {\n        char ch = chNext;\n        chNext = styler.SafeGetCharAt(i + 1);\n        int style = styleNext;\n        styleNext = styler.StyleAt(i + 1);\n        bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n        if (style == SCE_R_OPERATOR) {\n            if (ch == '{') {\n                // Measure the minimum before a '{' to allow\n                // folding on \"} else {\"\n                if (levelMinCurrent > levelNext) {\n                    levelMinCurrent = levelNext;\n                }\n                levelNext++;\n            }\n            else if (ch == '}') {\n                levelNext--;\n            }\n        }\n        if (atEOL) {\n            int levelUse = levelCurrent;\n            if (foldAtElse) {\n                levelUse = levelMinCurrent;\n            }\n            int lev = levelUse | levelNext << 16;\n            if (visibleChars == 0 && foldCompact)\n                lev |= SC_FOLDLEVELWHITEFLAG;\n            if (levelUse < levelNext)\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            if (lev != styler.LevelAt(lineCurrent)) {\n                styler.SetLevel(lineCurrent, lev);\n            }\n            lineCurrent++;\n            levelCurrent = levelNext;\n            levelMinCurrent = levelCurrent;\n            visibleChars = 0;\n        }\n        if (!isspacechar(ch))\n            visibleChars++;\n    }\n}\n\n\nstatic const char * const StataWordLists[] = {\n    \"Language Keywords\",\n    \"Types\",\n    0,\n};\n\nextern const LexerModule lmStata(SCLEX_STATA, ColouriseStataDoc, \"stata\", FoldStataDoc, StataWordLists);\n"
  },
  {
    "path": "lexers/LexTACL.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexTACL.cxx\n ** Lexer for TACL\n ** Based on LexPascal.cxx\n ** Written by Laurent le Tynevez\n ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002\n ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)\n ** Updated by Rod Falck, Aug 2006 Converted to TACL\n **/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\ninline bool isTACLoperator(char ch)\n\t{\n\treturn ch == '\\'' || isoperator(ch);\n\t}\n\ninline bool isTACLwordchar(char ch)\n\t{\n\treturn ch == '#' || ch == '^' || ch == '|' || ch == '_' || iswordchar(ch);\n\t}\n\ninline bool isTACLwordstart(char ch)\n\t{\n\treturn ch == '#' || ch == '|' || ch == '_' || iswordstart(ch);\n\t}\n\nstatic void getRange(Sci_PositionU start,\n\t\tSci_PositionU end,\n\t\tAccessor &styler,\n\t\tchar *s,\n\t\tSci_PositionU len) {\n\tSci_PositionU i = 0;\n\twhile ((i < end - start + 1) && (i < len-1)) {\n\t\ts[i] = static_cast<char>(tolower(styler[start + i]));\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n}\n\nstatic bool IsStreamCommentStyle(int style) {\n\treturn style == SCE_C_COMMENT ||\n\t\tstyle == SCE_C_COMMENTDOC ||\n\t\tstyle == SCE_C_COMMENTDOCKEYWORD ||\n\t\tstyle == SCE_C_COMMENTDOCKEYWORDERROR;\n}\n\nstatic void ColourTo(Accessor &styler, Sci_PositionU end, unsigned int attr, bool bInAsm) {\n\tif ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {\n\t\tstyler.ColourTo(end, SCE_C_REGEX);\n\t} else\n\t\tstyler.ColourTo(end, attr);\n}\n\n// returns 1 if the item starts a class definition, and -1 if the word is \"end\", and 2 if the word is \"asm\"\nstatic int classifyWordTACL(Sci_PositionU start, Sci_PositionU end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {\n\tint ret = 0;\n\n\tWordList& keywords = *keywordlists[0];\n\tWordList& builtins = *keywordlists[1];\n\tWordList& commands = *keywordlists[2];\n\n\tchar s[100];\n\tgetRange(start, end, styler, s, sizeof(s));\n\n\tchar chAttr = SCE_C_IDENTIFIER;\n\tif (isdigit(s[0]) || (s[0] == '.')) {\n\t\tchAttr = SCE_C_NUMBER;\n\t}\n\telse {\n\t\tif (s[0] == '#' || keywords.InList(s)) {\n\t\t\tchAttr = SCE_C_WORD;\n\n\t\t\tif (strcmp(s, \"asm\") == 0) {\n\t\t\t\tret = 2;\n\t\t\t}\n\t\t\telse if (strcmp(s, \"end\") == 0) {\n\t\t\t\tret = -1;\n\t\t\t}\n\t\t}\n\t\telse if (s[0] == '|' || builtins.InList(s)) {\n\t\t\tchAttr = SCE_C_WORD2;\n\t\t}\n\t\telse if (commands.InList(s)) {\n\t\t\tchAttr = SCE_C_UUID;\n\t\t}\n\t\telse if (strcmp(s, \"comment\") == 0) {\n\t\t\tchAttr = SCE_C_COMMENTLINE;\n\t\t\tret = 3;\n\t\t}\n\t}\n\tColourTo(styler, end, chAttr, (bInAsm && ret != -1));\n\treturn ret;\n}\n\nstatic int classifyFoldPointTACL(const char* s) {\n\tint lev = 0;\n\tif (s[0] == '[')\n\t\tlev=1;\n\telse if (s[0] == ']')\n\t\tlev=-1;\n\treturn lev;\n}\n\nstatic void ColouriseTACLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n\tAccessor &styler) {\n\n\tstyler.StartAt(startPos);\n\n\tint state = initStyle;\n\tif (state == SCE_C_CHARACTER)\t// Does not leak onto next line\n\t\tstate = SCE_C_DEFAULT;\n\tchar chPrev = ' ';\n\tchar chNext = styler[startPos];\n\tSci_PositionU lengthDoc = startPos + length;\n\n\tbool bInClassDefinition;\n\n\tSci_Position currentLine = styler.GetLine(startPos);\n\tif (currentLine > 0) {\n\t\tstyler.SetLineState(currentLine, styler.GetLineState(currentLine-1));\n\t\tbInClassDefinition = (styler.GetLineState(currentLine) == 1);\n\t} else {\n\t\tstyler.SetLineState(currentLine, 0);\n\t\tbInClassDefinition = false;\n\t}\n\n\tbool bInAsm = (state == SCE_C_REGEX);\n\tif (bInAsm)\n\t\tstate = SCE_C_DEFAULT;\n\n\tstyler.StartSegment(startPos);\n\tint visibleChars = 0;\n\tSci_PositionU i;\n\tfor (i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n')) {\n\t\t\t// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)\n\t\t\t// Avoid triggering two times on Dos/Win\n\t\t\t// End of line\n\t\t\tif (state == SCE_C_CHARACTER) {\n\t\t\t\tColourTo(styler, i, state, bInAsm);\n\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t}\n\t\t\tvisibleChars = 0;\n\t\t\tcurrentLine++;\n\t\t\tstyler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));\n\t\t}\n\n\t\tif (styler.IsLeadByte(ch)) {\n\t\t\tchNext = styler.SafeGetCharAt(i + 2);\n\t\t\tchPrev = ' ';\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (state == SCE_C_DEFAULT) {\n\t\t\tif (isTACLwordstart(ch)) {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_IDENTIFIER;\n\t\t\t} else if (ch == '{') {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_COMMENT;\n\t\t\t} else if (ch == '{' && chNext == '*') {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_COMMENTDOC;\n\t\t\t} else if (ch == '=' && chNext == '=') {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_COMMENTLINE;\n\t\t\t} else if (ch == '\"') {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_STRING;\n\t\t\t} else if (ch == '?' && visibleChars == 0) {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_PREPROCESSOR;\n\t\t\t} else if (isTACLoperator(ch)) {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tColourTo(styler, i, SCE_C_OPERATOR, bInAsm);\n\t\t\t}\n\t\t} else if (state == SCE_C_IDENTIFIER) {\n\t\t\tif (!isTACLwordchar(ch)) {\n\t\t\t\tint lStateChange = classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);\n\n\t\t\t\tif(lStateChange == 1) {\n\t\t\t\t\tstyler.SetLineState(currentLine, 1);\n\t\t\t\t\tbInClassDefinition = true;\n\t\t\t\t} else if(lStateChange == 2) {\n\t\t\t\t\tbInAsm = true;\n\t\t\t\t} else if(lStateChange == -1) {\n\t\t\t\t\tstyler.SetLineState(currentLine, 0);\n\t\t\t\t\tbInClassDefinition = false;\n\t\t\t\t\tbInAsm = false;\n\t\t\t\t}\n\n\t\t\t\tif (lStateChange == 3) {\n\t\t\t\t\t state = SCE_C_COMMENTLINE;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\t\tif (ch == '{') {\n\t\t\t\t\t\tstate = SCE_C_COMMENT;\n\t\t\t\t\t} else if (ch == '{' && chNext == '*') {\n\t\t\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\t\t\tstate = SCE_C_COMMENTDOC;\n\t\t\t\t\t} else if (ch == '=' && chNext == '=') {\n\t\t\t\t\t\tstate = SCE_C_COMMENTLINE;\n\t\t\t\t\t} else if (ch == '\"') {\n\t\t\t\t\t\tstate = SCE_C_STRING;\n\t\t\t\t\t} else if (isTACLoperator(ch)) {\n\t\t\t\t\t\tColourTo(styler, i, SCE_C_OPERATOR, bInAsm);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (state == SCE_C_PREPROCESSOR) {\n\t\t\t\tif ((ch == '\\r' || ch == '\\n') && !(chPrev == '\\\\' || chPrev == '\\r')) {\n\t\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (state == SCE_C_COMMENT) {\n\t\t\t\tif (ch == '}' || (ch == '\\r' || ch == '\\n') ) {\n\t\t\t\t\tColourTo(styler, i, state, bInAsm);\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (state == SCE_C_COMMENTDOC) {\n\t\t\t\tif (ch == '}' || (ch == '\\r' || ch == '\\n')) {\n\t\t\t\t\tif (((i > styler.GetStartSegment() + 2) || (\n\t\t\t\t\t\t(initStyle == SCE_C_COMMENTDOC) &&\n\t\t\t\t\t\t(styler.GetStartSegment() == static_cast<Sci_PositionU>(startPos))))) {\n\t\t\t\t\t\t\tColourTo(styler, i, state, bInAsm);\n\t\t\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (state == SCE_C_COMMENTLINE) {\n\t\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (state == SCE_C_STRING) {\n\t\t\t\tif (ch == '\"' || ch == '\\r' || ch == '\\n') {\n\t\t\t\t\tColourTo(styler, i, state, bInAsm);\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        if (!isspacechar(ch))\n            visibleChars++;\n\t\tchPrev = ch;\n\t}\n\n\t// Process to end of document\n\tif (state == SCE_C_IDENTIFIER) {\n\t\tclassifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);\n\t\t}\n\telse\n\t\tColourTo(styler, lengthDoc - 1, state, bInAsm);\n}\n\nstatic void FoldTACLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[],\n                            Accessor &styler) {\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldPreprocessor = styler.GetPropertyInt(\"fold.preprocessor\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tbool section = false;\n\n\tSci_Position lastStart = 0;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_PREPROCESSOR))\n\t\t{\n\t\t\t// Store last word start point.\n\t\t\tlastStart = i;\n\t\t}\n\n\t\tif (stylePrev == SCE_C_WORD || stylePrev == SCE_C_PREPROCESSOR) {\n\t\t\tif(isTACLwordchar(ch) && !isTACLwordchar(chNext)) {\n\t\t\t\tchar s[100];\n\t\t\t\tgetRange(lastStart, i, styler, s, sizeof(s));\n\t\t\t\tif (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, \"?section\") == 0)\n\t\t\t\t\t{\n\t\t\t\t\tsection = true;\n\t\t\t\t\tlevelCurrent = 1;\n\t\t\t\t\tlevelPrev = 0;\n\t\t\t\t\t}\n\t\t\t\telse if (stylePrev == SCE_C_WORD)\n\t\t\t\t\tlevelCurrent += classifyFoldPointTACL(s);\n\t\t\t}\n\t\t}\n\n\t\tif (style == SCE_C_OPERATOR) {\n\t\t\tif (ch == '[') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (ch == ']') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (foldComment && (style == SCE_C_COMMENTLINE)) {\n\t\t\tif ((ch == '/') && (chNext == '/')) {\n\t\t\t\tchar chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {\n\t\t\tif (ch == '{' && chNext == '$') {\n\t\t\t\tSci_PositionU j=i+2; // skip {$\n\t\t\t\twhile ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tif (styler.Match(j, \"region\") || styler.Match(j, \"if\")) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t} else if (styler.Match(j, \"end\")) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (foldComment && IsStreamCommentStyle(style)) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev | SC_FOLDLEVELBASE;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev || section) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t\tsection = false;\n\t\t}\n\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const TACLWordListDesc[] = {\n\t\"Builtins\",\n\t\"Labels\",\n\t\"Commands\",\n\t0\n};\n\nextern const LexerModule lmTACL(SCLEX_TACL, ColouriseTACLDoc, \"TACL\", FoldTACLDoc, TACLWordListDesc);\n"
  },
  {
    "path": "lexers/LexTADS3.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexTADS3.cxx\n ** Lexer for TADS3.\n **/\n// Copyright 1998-2006 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n/*\n * TADS3 is a language designed by Michael J. Roberts for the writing of text\n * based games.  TADS comes from Text Adventure Development System.  It has good\n * support for the processing and outputting of formatted text and much of a\n * TADS program listing consists of strings.\n *\n * TADS has two types of strings, those enclosed in single quotes (') and those\n * enclosed in double quotes (\").  These strings have different symantics and\n * can be given different highlighting if desired.\n *\n * There can be embedded within both types of strings html tags\n * ( <tag key=value> ), library directives ( <.directive> ), and message\n * parameters ( {The doctor's/his} ).\n *\n * Double quoted strings can also contain interpolated expressions\n * ( << rug.moved ? ' and a hole in the floor. ' : nil >> ).  These expressions\n * may themselves contain single or double quoted strings, although the double\n * quoted strings may not contain interpolated expressions.\n *\n * These embedded constructs influence the output and formatting and are an\n * important part of a program and require highlighting.\n *\n * LINKS\n * http://www.tads.org/\n */\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic const int T3_SINGLE_QUOTE = 1;\nstatic const int T3_INT_EXPRESSION = 2;\nstatic const int T3_INT_EXPRESSION_IN_TAG = 4;\nstatic const int T3_HTML_SQUOTE = 8;\n\nstatic inline bool IsEOL(const int ch, const int chNext) {\n        return (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n}\n\n/*\n *   Test the current character to see if it's the START of an EOL sequence;\n *   if so, skip ahead to the last character of the sequence and return true,\n *   and if not just return false.  There are a few places where we want to\n *   check to see if a newline sequence occurs at a particular point, but\n *   where a caller expects a subroutine to stop only upon reaching the END\n *   of a newline sequence (in particular, CR-LF on Windows).  That's why\n *   IsEOL() above only returns true on CR if the CR isn't followed by an LF\n *   - it doesn't want to admit that there's a newline until reaching the END\n *   of the sequence.  We meet both needs by saying that there's a newline\n *   when we see the CR in a CR-LF, but skipping the CR before returning so\n *   that the caller's caller will see that we've stopped at the LF.\n */\nstatic inline bool IsEOLSkip(StyleContext &sc)\n{\n    /* test for CR-LF */\n    if (sc.ch == '\\r' && sc.chNext == '\\n')\n    {\n        /* got CR-LF - skip the CR and indicate that we're at a newline */\n        sc.Forward();\n        return true;\n    }\n\n    /*\n     *   in other cases, we have at most a 1-character newline, so do the\n     *   normal IsEOL test\n     */\n    return IsEOL(sc.ch, sc.chNext);\n}\n\nstatic inline bool IsATADS3Operator(const int ch) {\n        return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')'\n                || ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';'\n                || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%'\n                || ch == '?' || ch == '!' || ch == '<' || ch == '>' || ch == '|'\n                || ch == '@' || ch == '&' || ch == '~';\n}\n\nstatic inline bool IsAWordChar(const int ch) {\n        return isalnum(ch) || ch == '_';\n}\n\nstatic inline bool IsAWordStart(const int ch) {\n        return isalpha(ch) || ch == '_';\n}\n\nstatic inline bool IsAHexDigit(const int ch) {\n        int lch = tolower(ch);\n        return isdigit(lch) || lch == 'a' || lch == 'b' || lch == 'c'\n                || lch == 'd' || lch == 'e' || lch == 'f';\n}\n\nstatic inline bool IsAnHTMLChar(int ch) {\n        return isalnum(ch) || ch == '-' || ch == '_' || ch == '.';\n}\n\nstatic inline bool IsADirectiveChar(int ch) {\n        return isalnum(ch) || isspace(ch) || ch == '-' || ch == '/';\n}\n\nstatic inline bool IsANumberStart(StyleContext &sc) {\n        return isdigit(sc.ch)\n                || (!isdigit(sc.chPrev) && sc.ch == '.' && isdigit(sc.chNext));\n}\n\ninline static void ColouriseTADS3Operator(StyleContext &sc) {\n        int initState = sc.state;\n        int c = sc.ch;\n        sc.SetState(c == '{' || c == '}' ? SCE_T3_BRACE : SCE_T3_OPERATOR);\n        sc.ForwardSetState(initState);\n}\n\nstatic void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) {\n        int endState = sc.state;\n        int chQuote = sc.ch;\n        int chString = (lineState & T3_SINGLE_QUOTE) ? '\\'' : '\"';\n        if (endState == SCE_T3_HTML_STRING) {\n                if (lineState&T3_SINGLE_QUOTE) {\n                        endState = SCE_T3_S_STRING;\n                        chString = '\\'';\n                } else if (lineState&T3_INT_EXPRESSION) {\n                        endState = SCE_T3_X_STRING;\n                        chString = '\"';\n                } else {\n                        endState = SCE_T3_HTML_DEFAULT;\n                        chString = '\"';\n                }\n                chQuote = (lineState & T3_HTML_SQUOTE) ? '\\'' : '\"';\n        } else {\n                sc.SetState(SCE_T3_HTML_STRING);\n                sc.Forward();\n        }\n        if (chQuote == '\"')\n                lineState &= ~T3_HTML_SQUOTE;\n        else\n                lineState |= T3_HTML_SQUOTE;\n\n        while (sc.More()) {\n                if (IsEOL(sc.ch, sc.chNext)) {\n                        return;\n                }\n                if (sc.ch == chQuote) {\n                        sc.ForwardSetState(endState);\n                        return;\n                }\n                if (sc.Match('\\\\', static_cast<char>(chQuote))) {\n                        sc.Forward(2);\n                        sc.SetState(endState);\n                        return;\n                }\n                if (sc.ch == chString) {\n                        sc.SetState(SCE_T3_DEFAULT);\n                        return;\n                }\n\n                if (sc.Match('<', '<')) {\n                        lineState |= T3_INT_EXPRESSION | T3_INT_EXPRESSION_IN_TAG;\n                        sc.SetState(SCE_T3_X_DEFAULT);\n                        sc.Forward(2);\n                        return;\n                }\n\n                if (sc.Match('\\\\', static_cast<char>(chQuote))\n                        || sc.Match('\\\\', static_cast<char>(chString))\n                        || sc.Match('\\\\', '\\\\')) {\n                        sc.Forward(2);\n                } else {\n                        sc.Forward();\n                }\n        }\n}\n\nstatic void ColouriseTADS3HTMLTagStart(StyleContext &sc) {\n        sc.SetState(SCE_T3_HTML_TAG);\n        sc.Forward();\n        if (sc.ch == '/') {\n                sc.Forward();\n        }\n        while (IsAnHTMLChar(sc.ch)) {\n                sc.Forward();\n        }\n}\n\nstatic void ColouriseTADS3HTMLTag(StyleContext &sc, int &lineState) {\n        int endState = sc.state;\n        int chQuote = '\"';\n        int chString = '\\'';\n        switch (endState) {\n                case SCE_T3_S_STRING:\n                        ColouriseTADS3HTMLTagStart(sc);\n                        sc.SetState(SCE_T3_HTML_DEFAULT);\n                        chQuote = '\\'';\n                        chString = '\"';\n                        break;\n                case SCE_T3_D_STRING:\n                case SCE_T3_X_STRING:\n                        ColouriseTADS3HTMLTagStart(sc);\n                        sc.SetState(SCE_T3_HTML_DEFAULT);\n                        break;\n                case SCE_T3_HTML_DEFAULT:\n                        if (lineState&T3_SINGLE_QUOTE) {\n                                endState = SCE_T3_S_STRING;\n                                chQuote = '\\'';\n                                chString = '\"';\n                        } else if (lineState&T3_INT_EXPRESSION) {\n                                endState = SCE_T3_X_STRING;\n                        } else {\n                                endState = SCE_T3_D_STRING;\n                        }\n                        break;\n        }\n\n        while (sc.More()) {\n                if (IsEOL(sc.ch, sc.chNext)) {\n                        return;\n                }\n                if (sc.Match('/', '>')) {\n                        sc.SetState(SCE_T3_HTML_TAG);\n                        sc.Forward(2);\n                        sc.SetState(endState);\n                        return;\n                }\n                if (sc.ch == '>') {\n                        sc.SetState(SCE_T3_HTML_TAG);\n                        sc.ForwardSetState(endState);\n                        return;\n                }\n                if (sc.ch == chQuote) {\n                        sc.SetState(endState);\n                        return;\n                }\n                if (sc.Match('\\\\', static_cast<char>(chQuote))) {\n                        sc.Forward();\n                        ColouriseTADSHTMLString(sc, lineState);\n                        if (sc.state == SCE_T3_X_DEFAULT)\n                            break;\n                } else if (sc.ch == chString) {\n                        ColouriseTADSHTMLString(sc, lineState);\n                } else if (sc.ch == '=') {\n                        ColouriseTADS3Operator(sc);\n                } else {\n                        sc.Forward();\n                }\n        }\n}\n\nstatic void ColouriseTADS3Keyword(StyleContext &sc,\n                                                        WordList *keywordlists[],       Sci_PositionU endPos) {\n        char s[250];\n        WordList &keywords = *keywordlists[0];\n        WordList &userwords1 = *keywordlists[1];\n        WordList &userwords2 = *keywordlists[2];\n        WordList &userwords3 = *keywordlists[3];\n        int initState = sc.state;\n        sc.SetState(SCE_T3_IDENTIFIER);\n        while (sc.More() && (IsAWordChar(sc.ch))) {\n                sc.Forward();\n        }\n        sc.GetCurrent(s, sizeof(s));\n        if ( strcmp(s, \"is\") == 0 || strcmp(s, \"not\") == 0) {\n                // have to find if \"in\" is next\n                Sci_Position n = 1;\n                while (n + sc.currentPos < endPos && IsASpaceOrTab(sc.GetRelative(n)))\n                        n++;\n                if (sc.GetRelative(n) == 'i' && sc.GetRelative(n+1) == 'n') {\n                        sc.Forward(n+2);\n                        sc.ChangeState(SCE_T3_KEYWORD);\n                }\n        } else if (keywords.InList(s)) {\n                sc.ChangeState(SCE_T3_KEYWORD);\n        } else if (userwords3.InList(s)) {\n                sc.ChangeState(SCE_T3_USER3);\n        } else if (userwords2.InList(s)) {\n                sc.ChangeState(SCE_T3_USER2);\n        } else if (userwords1.InList(s)) {\n                sc.ChangeState(SCE_T3_USER1);\n        }\n        sc.SetState(initState);\n}\n\nstatic void ColouriseTADS3MsgParam(StyleContext &sc, int &lineState) {\n        int endState = sc.state;\n        int chQuote = '\"';\n        switch (endState) {\n                case SCE_T3_S_STRING:\n                        sc.SetState(SCE_T3_MSG_PARAM);\n                        sc.Forward();\n                        chQuote = '\\'';\n                        break;\n                case SCE_T3_D_STRING:\n                case SCE_T3_X_STRING:\n                        sc.SetState(SCE_T3_MSG_PARAM);\n                        sc.Forward();\n                        break;\n                case SCE_T3_MSG_PARAM:\n                        if (lineState&T3_SINGLE_QUOTE) {\n                                endState = SCE_T3_S_STRING;\n                                chQuote = '\\'';\n                        } else if (lineState&T3_INT_EXPRESSION) {\n                                endState = SCE_T3_X_STRING;\n                        } else {\n                                endState = SCE_T3_D_STRING;\n                        }\n                        break;\n        }\n        while (sc.More() && sc.ch != '}' && sc.ch != chQuote) {\n                if (IsEOL(sc.ch, sc.chNext)) {\n                        return;\n                }\n                if (sc.ch == '\\\\') {\n                        sc.Forward();\n                }\n                sc.Forward();\n        }\n        if (sc.ch == chQuote) {\n                sc.SetState(endState);\n        } else {\n                sc.ForwardSetState(endState);\n        }\n}\n\nstatic void ColouriseTADS3LibDirective(StyleContext &sc, int &lineState) {\n        int initState = sc.state;\n        int chQuote = '\"';\n        switch (initState) {\n                case SCE_T3_S_STRING:\n                        sc.SetState(SCE_T3_LIB_DIRECTIVE);\n                        sc.Forward(2);\n                        chQuote = '\\'';\n                        break;\n                case SCE_T3_D_STRING:\n                        sc.SetState(SCE_T3_LIB_DIRECTIVE);\n                        sc.Forward(2);\n                        break;\n                case SCE_T3_LIB_DIRECTIVE:\n                        if (lineState&T3_SINGLE_QUOTE) {\n                                initState = SCE_T3_S_STRING;\n                                chQuote = '\\'';\n                        } else {\n                                initState = SCE_T3_D_STRING;\n                        }\n                        break;\n        }\n        while (sc.More() && IsADirectiveChar(sc.ch)) {\n                if (IsEOL(sc.ch, sc.chNext)) {\n                        return;\n                }\n                sc.Forward();\n        };\n        if (sc.ch == '>' || !sc.More()) {\n                sc.ForwardSetState(initState);\n        } else if (sc.ch == chQuote) {\n                sc.SetState(initState);\n        } else {\n                sc.ChangeState(initState);\n                sc.Forward();\n        }\n}\n\nstatic void ColouriseTADS3String(StyleContext &sc, int &lineState) {\n        int chQuote = sc.ch;\n        int endState = sc.state;\n        switch (sc.state) {\n                case SCE_T3_DEFAULT:\n                case SCE_T3_X_DEFAULT:\n                        if (chQuote == '\"') {\n                                if (sc.state == SCE_T3_DEFAULT) {\n                                        sc.SetState(SCE_T3_D_STRING);\n                                } else {\n                                        sc.SetState(SCE_T3_X_STRING);\n                                }\n                                lineState &= ~T3_SINGLE_QUOTE;\n                        } else {\n                                sc.SetState(SCE_T3_S_STRING);\n                                lineState |= T3_SINGLE_QUOTE;\n                        }\n                        sc.Forward();\n                        break;\n                case SCE_T3_S_STRING:\n                        chQuote = '\\'';\n                        endState = lineState&T3_INT_EXPRESSION ?\n                                SCE_T3_X_DEFAULT : SCE_T3_DEFAULT;\n                        break;\n                case SCE_T3_D_STRING:\n                        chQuote = '\"';\n                        endState = SCE_T3_DEFAULT;\n                        break;\n                case SCE_T3_X_STRING:\n                        chQuote = '\"';\n                        endState = SCE_T3_X_DEFAULT;\n                        break;\n        }\n        while (sc.More()) {\n                if (IsEOL(sc.ch, sc.chNext)) {\n                        return;\n                }\n                if (sc.ch == chQuote) {\n                        sc.ForwardSetState(endState);\n                        return;\n                }\n                if (sc.state == SCE_T3_D_STRING && sc.Match('<', '<')) {\n                        lineState |= T3_INT_EXPRESSION;\n                        sc.SetState(SCE_T3_X_DEFAULT);\n                        sc.Forward(2);\n                        return;\n                }\n                if (sc.Match('\\\\', static_cast<char>(chQuote))\n                    || sc.Match('\\\\', '\\\\')) {\n                        sc.Forward(2);\n                } else if (sc.ch == '{') {\n                        ColouriseTADS3MsgParam(sc, lineState);\n                } else if (sc.Match('<', '.')) {\n                        ColouriseTADS3LibDirective(sc, lineState);\n                } else if (sc.ch == '<') {\n                        ColouriseTADS3HTMLTag(sc, lineState);\n                        if (sc.state == SCE_T3_X_DEFAULT)\n                                return;\n                } else {\n                        sc.Forward();\n                }\n        }\n}\n\nstatic void ColouriseTADS3Comment(StyleContext &sc, int endState) {\n        sc.SetState(SCE_T3_BLOCK_COMMENT);\n        while (sc.More()) {\n                if (IsEOL(sc.ch, sc.chNext)) {\n                        return;\n                }\n                if (sc.Match('*', '/')) {\n                        sc.Forward(2);\n                        sc.SetState(endState);\n                        return;\n                }\n                sc.Forward();\n        }\n}\n\nstatic void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) {\n        sc.SetState(initState);\n        while (sc.More()) {\n                if (sc.ch == '\\\\') {\n                        sc.Forward();\n                        if (IsEOLSkip(sc)) {\n                                        return;\n                        }\n                }\n                if (IsEOL(sc.ch, sc.chNext)) {\n                        sc.SetState(endState);\n                        return;\n                }\n                sc.Forward();\n        }\n}\n\nstatic void ColouriseTADS3Number(StyleContext &sc) {\n        int endState = sc.state;\n        bool inHexNumber = false;\n        bool seenE = false;\n        bool seenDot = sc.ch == '.';\n        sc.SetState(SCE_T3_NUMBER);\n        if (sc.More()) {\n                sc.Forward();\n        }\n        if (sc.chPrev == '0' && tolower(sc.ch) == 'x') {\n                inHexNumber = true;\n                sc.Forward();\n        }\n        while (sc.More()) {\n                if (inHexNumber) {\n                        if (!IsAHexDigit(sc.ch)) {\n                                break;\n                        }\n                } else if (!isdigit(sc.ch)) {\n                        if (!seenE && tolower(sc.ch) == 'e') {\n                                seenE = true;\n                                seenDot = true;\n                                if (sc.chNext == '+' || sc.chNext == '-') {\n                                        sc.Forward();\n                                }\n                        } else if (!seenDot && sc.ch == '.') {\n                                seenDot = true;\n                        } else {\n                                break;\n                        }\n                }\n                sc.Forward();\n        }\n        sc.SetState(endState);\n}\n\nstatic void ColouriseTADS3Doc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                                                           WordList *keywordlists[], Accessor &styler) {\n        int visibleChars = 0;\n        int bracketLevel = 0;\n        int lineState = 0;\n        Sci_PositionU endPos = startPos + length;\n        Sci_Position lineCurrent = styler.GetLine(startPos);\n        if (lineCurrent > 0) {\n                lineState = styler.GetLineState(lineCurrent-1);\n        }\n        StyleContext sc(startPos, length, initStyle, styler);\n\n        while (sc.More()) {\n\n                if (IsEOL(sc.ch, sc.chNext)) {\n                        styler.SetLineState(lineCurrent, lineState);\n                        lineCurrent++;\n                        visibleChars = 0;\n                        sc.Forward();\n                        if (sc.ch == '\\n') {\n                                sc.Forward();\n                        }\n                }\n\n                switch(sc.state) {\n                        case SCE_T3_PREPROCESSOR:\n                        case SCE_T3_LINE_COMMENT:\n                                ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ?\n                                        SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);\n                                break;\n                        case SCE_T3_S_STRING:\n                        case SCE_T3_D_STRING:\n                        case SCE_T3_X_STRING:\n                                ColouriseTADS3String(sc, lineState);\n                                visibleChars++;\n                                break;\n                        case SCE_T3_MSG_PARAM:\n                                ColouriseTADS3MsgParam(sc, lineState);\n                                break;\n                        case SCE_T3_LIB_DIRECTIVE:\n                                ColouriseTADS3LibDirective(sc, lineState);\n                                break;\n                        case SCE_T3_HTML_DEFAULT:\n                                ColouriseTADS3HTMLTag(sc, lineState);\n                                break;\n                        case SCE_T3_HTML_STRING:\n                                ColouriseTADSHTMLString(sc, lineState);\n                                break;\n                        case SCE_T3_BLOCK_COMMENT:\n                                ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ?\n                                        SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);\n                                break;\n                        case SCE_T3_DEFAULT:\n                        case SCE_T3_X_DEFAULT:\n                                if (IsASpaceOrTab(sc.ch)) {\n                                        sc.Forward();\n                                } else if (sc.ch == '#' && visibleChars == 0) {\n                                        ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state);\n                                } else if (sc.Match('/', '*')) {\n                                        ColouriseTADS3Comment(sc, sc.state);\n                                        visibleChars++;\n                                } else if (sc.Match('/', '/')) {\n                                        ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state);\n                                } else if (sc.ch == '\"') {\n                                        bracketLevel = 0;\n                                        ColouriseTADS3String(sc, lineState);\n                                        visibleChars++;\n                                } else if (sc.ch == '\\'') {\n                                        ColouriseTADS3String(sc, lineState);\n                                        visibleChars++;\n                                } else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0\n                                                   && sc.Match('>', '>')) {\n                                        sc.Forward(2);\n                                        sc.SetState(SCE_T3_D_STRING);\n                                        if (lineState & T3_INT_EXPRESSION_IN_TAG)\n                                                sc.SetState(SCE_T3_HTML_STRING);\n                                        lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION\n                                                       |T3_INT_EXPRESSION_IN_TAG);\n                                } else if (IsATADS3Operator(sc.ch)) {\n                                        if (sc.state == SCE_T3_X_DEFAULT) {\n                                                if (sc.ch == '(') {\n                                                        bracketLevel++;\n                                                } else if (sc.ch == ')' && bracketLevel > 0) {\n                                                        bracketLevel--;\n                                                }\n                                        }\n                                        ColouriseTADS3Operator(sc);\n                                        visibleChars++;\n                                } else if (IsANumberStart(sc)) {\n                                        ColouriseTADS3Number(sc);\n                                        visibleChars++;\n                                } else if (IsAWordStart(sc.ch)) {\n                                        ColouriseTADS3Keyword(sc, keywordlists, endPos);\n                                        visibleChars++;\n                                } else if (sc.Match(\"...\")) {\n                                        sc.SetState(SCE_T3_IDENTIFIER);\n                                        sc.Forward(3);\n                                        sc.SetState(SCE_T3_DEFAULT);\n                                } else {\n                                        sc.Forward();\n                                        visibleChars++;\n                                }\n                                break;\n                        default:\n                                sc.SetState(SCE_T3_DEFAULT);\n                                sc.Forward();\n                }\n        }\n        sc.Complete();\n}\n\n/*\n TADS3 has two styles of top level block (TLB). Eg\n\n // default style\n silverKey : Key 'small silver key' 'small silver key'\n        \"A small key glints in the sunlight. \"\n ;\n\n and\n\n silverKey : Key {\n        'small silver key'\n        'small silver key'\n        \"A small key glints in the sunlight. \"\n }\n\n Some constructs mandate one or the other, but usually the author has may choose\n either.\n\n T3_SEENSTART is used to indicate that a braceless TLB has been (potentially)\n seen and is also used to match the closing ';' of the default style.\n\n T3_EXPECTINGIDENTIFIER and T3_EXPECTINGPUNCTUATION are used to keep track of\n what characters may be seen without incrementing the block level.  The general\n pattern is identifier <punc> identifier, acceptable punctuation characters\n are ':', ',', '(' and ')'.  No attempt is made to ensure that punctuation\n characters are syntactically correct, eg parentheses match. A ')' always\n signifies the start of a block.  We just need to check if it is followed by a\n '{', in which case we let the brace handling code handle the folding level.\n\n expectingIdentifier == false && expectingIdentifier == false\n Before the start of a TLB.\n\n expectingIdentifier == true && expectingIdentifier == true\n Currently in an identifier.  Will accept identifier or punctuation.\n\n expectingIdentifier == true && expectingIdentifier == false\n Just seen a punctuation character & now waiting for an identifier to start.\n\n expectingIdentifier == false && expectingIdentifier == truee\n We were in an identifier and have seen space.  Now waiting to see a punctuation\n character\n\n Space, comments & preprocessor directives are always acceptable and are\n equivalent.\n*/\n\nstatic const int T3_SEENSTART = 1 << 12;\nstatic const int T3_EXPECTINGIDENTIFIER = 1 << 13;\nstatic const int T3_EXPECTINGPUNCTUATION = 1 << 14;\n\nstatic inline bool IsStringTransition(int s1, int s2) {\n        return s1 != s2\n                && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING\n                        || (s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT))\n                && s2 != SCE_T3_LIB_DIRECTIVE\n                && s2 != SCE_T3_MSG_PARAM\n                && s2 != SCE_T3_HTML_TAG\n                && s2 != SCE_T3_HTML_STRING;\n}\n\nstatic inline bool IsATADS3Punctuation(const int ch) {\n        return ch == ':' || ch == ',' || ch == '(' || ch == ')';\n}\n\nstatic inline bool IsAnIdentifier(const int style) {\n        return style == SCE_T3_IDENTIFIER\n                || style == SCE_T3_USER1\n                || style == SCE_T3_USER2\n                || style == SCE_T3_USER3;\n}\n\nstatic inline bool IsAnOperator(const int style) {\n    return style == SCE_T3_OPERATOR || style == SCE_T3_BRACE;\n}\n\nstatic inline bool IsSpaceEquivalent(const int ch, const int style) {\n        return isspace(ch)\n                || style == SCE_T3_BLOCK_COMMENT\n                || style == SCE_T3_LINE_COMMENT\n                || style == SCE_T3_PREPROCESSOR;\n}\n\nstatic char peekAhead(Sci_PositionU startPos, Sci_PositionU endPos,\n                                          Accessor &styler) {\n        for (Sci_PositionU i = startPos; i < endPos; i++) {\n                int style = styler.StyleAt(i);\n                char ch = styler[i];\n                if (!IsSpaceEquivalent(ch, style)) {\n                        if (IsAnIdentifier(style)) {\n                                return 'a';\n                        }\n                        if (IsATADS3Punctuation(ch)) {\n                                return ':';\n                        }\n                        if (ch == '{') {\n                                return '{';\n                        }\n                        return '*';\n                }\n        }\n        return ' ';\n}\n\nstatic void FoldTADS3Doc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                            WordList *[], Accessor &styler) {\n        Sci_PositionU endPos = startPos + length;\n        Sci_Position lineCurrent = styler.GetLine(startPos);\n        int levelCurrent = SC_FOLDLEVELBASE;\n        if (lineCurrent > 0)\n                levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n        int seenStart = levelCurrent & T3_SEENSTART;\n        int expectingIdentifier = levelCurrent & T3_EXPECTINGIDENTIFIER;\n        int expectingPunctuation = levelCurrent & T3_EXPECTINGPUNCTUATION;\n        levelCurrent &= SC_FOLDLEVELNUMBERMASK;\n        int levelMinCurrent = levelCurrent;\n        int levelNext = levelCurrent;\n        char chNext = styler[startPos];\n        int styleNext = styler.StyleAt(startPos);\n        int style = initStyle;\n        char ch = chNext;\n        int stylePrev = style;\n        bool redo = false;\n        for (Sci_PositionU i = startPos; i < endPos; i++) {\n                if (redo) {\n                        redo = false;\n                        i--;\n                } else {\n                        ch = chNext;\n                        chNext = styler.SafeGetCharAt(i + 1);\n                        stylePrev = style;\n                        style = styleNext;\n                        styleNext = styler.StyleAt(i + 1);\n                }\n                bool atEOL = IsEOL(ch, chNext);\n\n                if (levelNext == SC_FOLDLEVELBASE) {\n                        if (IsSpaceEquivalent(ch, style)) {\n                                if (expectingPunctuation) {\n                                        expectingIdentifier = 0;\n                                }\n                                if (style == SCE_T3_BLOCK_COMMENT) {\n                                        levelNext++;\n                                }\n                        } else if (ch == '{') {\n                                levelNext++;\n                                seenStart = 0;\n                        } else if (ch == '\\'' || ch == '\"' || ch == '[') {\n                                levelNext++;\n                                if (seenStart) {\n                                        redo = true;\n                                }\n                        } else if (ch == ';') {\n                                seenStart = 0;\n                                expectingIdentifier = 0;\n                                expectingPunctuation = 0;\n                        } else if (expectingIdentifier && expectingPunctuation) {\n                                if (IsATADS3Punctuation(ch)) {\n                                        if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {\n                                                levelNext++;\n                                        } else {\n                                                expectingPunctuation = 0;\n                                        }\n                                } else if (!IsAnIdentifier(style)) {\n                                        levelNext++;\n                                }\n                        } else if (expectingIdentifier && !expectingPunctuation) {\n                                if (!IsAnIdentifier(style)) {\n                                        levelNext++;\n                                } else {\n                                        expectingPunctuation = T3_EXPECTINGPUNCTUATION;\n                                }\n                        } else if (!expectingIdentifier && expectingPunctuation) {\n                                if (!IsATADS3Punctuation(ch)) {\n                                        levelNext++;\n                                } else {\n                                        if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {\n                                                levelNext++;\n                                        } else {\n                                                expectingIdentifier = T3_EXPECTINGIDENTIFIER;\n                                                expectingPunctuation = 0;\n                                        }\n                                }\n                        } else if (!expectingIdentifier && !expectingPunctuation) {\n                                if (IsAnIdentifier(style)) {\n                                        seenStart = T3_SEENSTART;\n                                        expectingIdentifier = T3_EXPECTINGIDENTIFIER;\n                                        expectingPunctuation = T3_EXPECTINGPUNCTUATION;\n                                }\n                        }\n\n                        if (levelNext != SC_FOLDLEVELBASE && style != SCE_T3_BLOCK_COMMENT) {\n                                expectingIdentifier = 0;\n                                expectingPunctuation = 0;\n                        }\n\n                } else if (levelNext == SC_FOLDLEVELBASE+1 && seenStart\n                                   && ch == ';' && IsAnOperator(style)) {\n                        levelNext--;\n                        seenStart = 0;\n                } else if (style == SCE_T3_BLOCK_COMMENT) {\n                        if (stylePrev != SCE_T3_BLOCK_COMMENT) {\n                                levelNext++;\n                        } else if (styleNext != SCE_T3_BLOCK_COMMENT && !atEOL) {\n                                // Comments don't end at end of line and the next character may be unstyled.\n                                levelNext--;\n                        }\n                } else if (ch == '\\'' || ch == '\"') {\n                        if (IsStringTransition(style, stylePrev)) {\n                                if (levelMinCurrent > levelNext) {\n                                        levelMinCurrent = levelNext;\n                                }\n                                levelNext++;\n                        } else if (IsStringTransition(style, styleNext)) {\n                                levelNext--;\n                        }\n                } else if (IsAnOperator(style)) {\n                        if (ch == '{' || ch == '[') {\n                                // Measure the minimum before a '{' to allow\n                                // folding on \"} else {\"\n                                if (levelMinCurrent > levelNext) {\n                                        levelMinCurrent = levelNext;\n                                }\n                                levelNext++;\n                        } else if (ch == '}' || ch == ']') {\n                                levelNext--;\n                        }\n                }\n\n                if (atEOL) {\n                        if (seenStart && levelNext == SC_FOLDLEVELBASE) {\n                                switch (peekAhead(i+1, endPos, styler)) {\n                                        case ' ':\n                                        case '{':\n                                                break;\n                                        case '*':\n                                                levelNext++;\n                                                break;\n                                        case 'a':\n                                                if (expectingPunctuation) {\n                                                        levelNext++;\n                                                }\n                                                break;\n                                        case ':':\n                                                if (expectingIdentifier) {\n                                                        levelNext++;\n                                                }\n                                                break;\n                                }\n                                if (levelNext != SC_FOLDLEVELBASE) {\n                                        expectingIdentifier = 0;\n                                        expectingPunctuation = 0;\n                                }\n                        }\n                        int lev = levelMinCurrent | (levelNext | expectingIdentifier\n                                | expectingPunctuation | seenStart) << 16;\n                        if (levelMinCurrent < levelNext)\n                                lev |= SC_FOLDLEVELHEADERFLAG;\n                        if (lev != styler.LevelAt(lineCurrent)) {\n                                styler.SetLevel(lineCurrent, lev);\n                        }\n                        lineCurrent++;\n                        levelCurrent = levelNext;\n                        levelMinCurrent = levelCurrent;\n                }\n        }\n}\n\nstatic const char * const tads3WordList[] = {\n        \"TADS3 Keywords\",\n        \"User defined 1\",\n        \"User defined 2\",\n        \"User defined 3\",\n        0\n};\n\nextern const LexerModule lmTADS3(SCLEX_TADS3, ColouriseTADS3Doc, \"tads3\", FoldTADS3Doc, tads3WordList);\n"
  },
  {
    "path": "lexers/LexTAL.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexTAL.cxx\n ** Lexer for TAL\n ** Based on LexPascal.cxx\n ** Written by Laurent le Tynevez\n ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002\n ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)\n ** Updated by Rod Falck, Aug 2006 Converted to TAL\n **/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\ninline bool isTALoperator(char ch)\n\t{\n\treturn ch == '\\'' || ch == '@' || ch == '#' || isoperator(ch);\n\t}\n\ninline bool isTALwordchar(char ch)\n\t{\n\treturn ch == '$' || ch == '^' || iswordchar(ch);\n\t}\n\ninline bool isTALwordstart(char ch)\n\t{\n\treturn ch == '$' || ch == '^' || iswordstart(ch);\n\t}\n\nstatic void getRange(Sci_PositionU start,\n\t\tSci_PositionU end,\n\t\tAccessor &styler,\n\t\tchar *s,\n\t\tSci_PositionU len) {\n\tSci_PositionU i = 0;\n\twhile ((i < end - start + 1) && (i < len-1)) {\n\t\ts[i] = static_cast<char>(tolower(styler[start + i]));\n\t\ti++;\n\t}\n\ts[i] = '\\0';\n}\n\nstatic bool IsStreamCommentStyle(int style) {\n\treturn style == SCE_C_COMMENT ||\n\t\tstyle == SCE_C_COMMENTDOC ||\n\t\tstyle == SCE_C_COMMENTDOCKEYWORD ||\n\t\tstyle == SCE_C_COMMENTDOCKEYWORDERROR;\n}\n\nstatic void ColourTo(Accessor &styler, Sci_PositionU end, unsigned int attr, bool bInAsm) {\n\tif ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {\n\t\tstyler.ColourTo(end, SCE_C_REGEX);\n\t} else\n\t\tstyler.ColourTo(end, attr);\n}\n\n// returns 1 if the item starts a class definition, and -1 if the word is \"end\", and 2 if the word is \"asm\"\nstatic int classifyWordTAL(Sci_PositionU start, Sci_PositionU end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {\n\tint ret = 0;\n\n\tWordList& keywords = *keywordlists[0];\n\tWordList& builtins = *keywordlists[1];\n\tWordList& nonreserved_keywords = *keywordlists[2];\n\n\tchar s[100];\n\tgetRange(start, end, styler, s, sizeof(s));\n\n\tchar chAttr = SCE_C_IDENTIFIER;\n\tif (isdigit(s[0]) || (s[0] == '.')) {\n\t\tchAttr = SCE_C_NUMBER;\n\t}\n\telse {\n\t\tif (keywords.InList(s)) {\n\t\t\tchAttr = SCE_C_WORD;\n\n\t\t\tif (strcmp(s, \"asm\") == 0) {\n\t\t\t\tret = 2;\n\t\t\t}\n\t\t\telse if (strcmp(s, \"end\") == 0) {\n\t\t\t\tret = -1;\n\t\t\t}\n\t\t}\n\t\telse if (s[0] == '$' || builtins.InList(s)) {\n\t\t\tchAttr = SCE_C_WORD2;\n\t\t}\n\t\telse if (nonreserved_keywords.InList(s)) {\n\t\t\tchAttr = SCE_C_UUID;\n\t\t}\n\t}\n\tColourTo(styler, end, chAttr, (bInAsm && ret != -1));\n\treturn ret;\n}\n\nstatic int classifyFoldPointTAL(const char* s) {\n\tint lev = 0;\n\tif (!(isdigit(s[0]) || (s[0] == '.'))) {\n\t\tif (strcmp(s, \"begin\") == 0 ||\n\t\t\tstrcmp(s, \"block\") == 0) {\n\t\t\tlev=1;\n\t\t} else if (strcmp(s, \"end\") == 0) {\n\t\t\tlev=-1;\n\t\t}\n\t}\n\treturn lev;\n}\n\nstatic void ColouriseTALDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],\n\tAccessor &styler) {\n\n\tstyler.StartAt(startPos);\n\n\tint state = initStyle;\n\tif (state == SCE_C_CHARACTER)\t// Does not leak onto next line\n\t\tstate = SCE_C_DEFAULT;\n\tchar chPrev = ' ';\n\tchar chNext = styler[startPos];\n\tSci_PositionU lengthDoc = startPos + length;\n\n\tbool bInClassDefinition;\n\n\tSci_Position currentLine = styler.GetLine(startPos);\n\tif (currentLine > 0) {\n\t\tstyler.SetLineState(currentLine, styler.GetLineState(currentLine-1));\n\t\tbInClassDefinition = (styler.GetLineState(currentLine) == 1);\n\t} else {\n\t\tstyler.SetLineState(currentLine, 0);\n\t\tbInClassDefinition = false;\n\t}\n\n\tbool bInAsm = (state == SCE_C_REGEX);\n\tif (bInAsm)\n\t\tstate = SCE_C_DEFAULT;\n\n\tstyler.StartSegment(startPos);\n\tint visibleChars = 0;\n\tfor (Sci_PositionU i = startPos; i < lengthDoc; i++) {\n\t\tchar ch = chNext;\n\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n')) {\n\t\t\t// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)\n\t\t\t// Avoid triggering two times on Dos/Win\n\t\t\t// End of line\n\t\t\tif (state == SCE_C_CHARACTER) {\n\t\t\t\tColourTo(styler, i, state, bInAsm);\n\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t}\n\t\t\tvisibleChars = 0;\n\t\t\tcurrentLine++;\n\t\t\tstyler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));\n\t\t}\n\n\t\tif (styler.IsLeadByte(ch)) {\n\t\t\tchNext = styler.SafeGetCharAt(i + 2);\n\t\t\tchPrev = ' ';\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (state == SCE_C_DEFAULT) {\n\t\t\tif (isTALwordstart(ch)) {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_IDENTIFIER;\n\t\t\t} else if (ch == '!' && chNext != '*') {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_COMMENT;\n\t\t\t} else if (ch == '!' && chNext == '*') {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_COMMENTDOC;\n\t\t\t} else if (ch == '-' && chNext == '-') {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_COMMENTLINE;\n\t\t\t} else if (ch == '\"') {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_STRING;\n\t\t\t} else if (ch == '?' && visibleChars == 0) {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tstate = SCE_C_PREPROCESSOR;\n\t\t\t} else if (isTALoperator(ch)) {\n\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\tColourTo(styler, i, SCE_C_OPERATOR, bInAsm);\n\t\t\t}\n\t\t} else if (state == SCE_C_IDENTIFIER) {\n\t\t\tif (!isTALwordchar(ch)) {\n\t\t\t\tint lStateChange = classifyWordTAL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);\n\n\t\t\t\tif(lStateChange == 1) {\n\t\t\t\t\tstyler.SetLineState(currentLine, 1);\n\t\t\t\t\tbInClassDefinition = true;\n\t\t\t\t} else if(lStateChange == 2) {\n\t\t\t\t\tbInAsm = true;\n\t\t\t\t} else if(lStateChange == -1) {\n\t\t\t\t\tstyler.SetLineState(currentLine, 0);\n\t\t\t\t\tbInClassDefinition = false;\n\t\t\t\t\tbInAsm = false;\n\t\t\t\t}\n\n\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\t\t\tif (ch == '!' && chNext != '*') {\n\t\t\t\t\tstate = SCE_C_COMMENT;\n\t\t\t\t} else if (ch == '!' && chNext == '*') {\n\t\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\t\tstate = SCE_C_COMMENTDOC;\n\t\t\t\t} else if (ch == '-' && chNext == '-') {\n\t\t\t\t\tstate = SCE_C_COMMENTLINE;\n\t\t\t\t} else if (ch == '\"') {\n\t\t\t\t\tstate = SCE_C_STRING;\n\t\t\t\t} else if (isTALoperator(ch)) {\n\t\t\t\t\tColourTo(styler, i, SCE_C_OPERATOR, bInAsm);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (state == SCE_C_PREPROCESSOR) {\n\t\t\t\tif ((ch == '\\r' || ch == '\\n') && !(chPrev == '\\\\' || chPrev == '\\r')) {\n\t\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (state == SCE_C_COMMENT) {\n\t\t\t\tif (ch == '!' || (ch == '\\r' || ch == '\\n') ) {\n\t\t\t\t\tColourTo(styler, i, state, bInAsm);\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (state == SCE_C_COMMENTDOC) {\n\t\t\t\tif (ch == '!' || (ch == '\\r' || ch == '\\n')) {\n\t\t\t\t\tif (((i > styler.GetStartSegment() + 2) || (\n\t\t\t\t\t\t(initStyle == SCE_C_COMMENTDOC) &&\n\t\t\t\t\t\t(styler.GetStartSegment() == static_cast<Sci_PositionU>(startPos))))) {\n\t\t\t\t\t\t\tColourTo(styler, i, state, bInAsm);\n\t\t\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (state == SCE_C_COMMENTLINE) {\n\t\t\t\tif (ch == '\\r' || ch == '\\n') {\n\t\t\t\t\tColourTo(styler, i-1, state, bInAsm);\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t}\n\t\t\t} else if (state == SCE_C_STRING) {\n\t\t\t\tif (ch == '\"') {\n\t\t\t\t\tColourTo(styler, i, state, bInAsm);\n\t\t\t\t\tstate = SCE_C_DEFAULT;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        if (!isspacechar(ch))\n            visibleChars++;\n\t\tchPrev = ch;\n\t}\n\tColourTo(styler, lengthDoc - 1, state, bInAsm);\n}\n\nstatic void FoldTALDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[],\n                            Accessor &styler) {\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tbool foldPreprocessor = styler.GetPropertyInt(\"fold.preprocessor\") != 0;\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tint styleNext = styler.StyleAt(startPos);\n\tint style = initStyle;\n\tbool was_end = false;\n\tbool section = false;\n\n\tSci_Position lastStart = 0;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n\t\tif (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_UUID || style == SCE_C_PREPROCESSOR))\n\t\t{\n\t\t\t// Store last word start point.\n\t\t\tlastStart = i;\n\t\t}\n\n\t\tif (stylePrev == SCE_C_WORD || style == SCE_C_UUID || stylePrev == SCE_C_PREPROCESSOR) {\n\t\t\tif(isTALwordchar(ch) && !isTALwordchar(chNext)) {\n\t\t\t\tchar s[100];\n\t\t\t\tgetRange(lastStart, i, styler, s, sizeof(s));\n\t\t\t\tif (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, \"?section\") == 0)\n\t\t\t\t\t{\n\t\t\t\t\tsection = true;\n\t\t\t\t\tlevelCurrent = 1;\n\t\t\t\t\tlevelPrev = 0;\n\t\t\t\t\t}\n\t\t\t\telse if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_UUID)\n\t\t\t\t\t{\n\t\t\t\t\tif (strcmp(s, \"block\") == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t// block keyword is ignored immediately after end keyword\n\t\t\t\t\t\tif (!was_end)\n\t\t\t\t\t\t\tlevelCurrent++;\n\t\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tlevelCurrent += classifyFoldPointTAL(s);\n\t\t\t\t\tif (strcmp(s, \"end\") == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\twas_end = true;\n\t\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\twas_end = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (foldComment && (style == SCE_C_COMMENTLINE)) {\n\t\t\tif ((ch == '/') && (chNext == '/')) {\n\t\t\t\tchar chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {\n\t\t\tif (ch == '{' && chNext == '$') {\n\t\t\t\tSci_PositionU j=i+2; // skip {$\n\t\t\t\twhile ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tif (styler.Match(j, \"region\") || styler.Match(j, \"if\")) {\n\t\t\t\t\tlevelCurrent++;\n\t\t\t\t} else if (styler.Match(j, \"end\")) {\n\t\t\t\t\tlevelCurrent--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (foldComment && IsStreamCommentStyle(style)) {\n\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t}\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev | SC_FOLDLEVELBASE;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev || section) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t\tsection = false;\n\t\t}\n\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const TALWordListDesc[] = {\n\t\"Keywords\",\n\t\"Builtins\",\n\t0\n};\n\nextern const LexerModule lmTAL(SCLEX_TAL, ColouriseTALDoc, \"TAL\", FoldTALDoc, TALWordListDesc);\n"
  },
  {
    "path": "lexers/LexTCL.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexTCL.cxx\n ** Lexer for TCL language.\n **/\n// Copyright 1998-2001 by Andre Arpin <arpin@kingston.net>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// Extended to accept accented characters\nstatic inline bool IsAWordChar(int ch) {\n\treturn ch >= 0x80 ||\n\t       (isalnum(ch) || ch == '_' || ch ==':' || ch=='.'); // : name space separator\n}\n\nstatic inline bool IsAWordStart(int ch) {\n\treturn ch >= 0x80 || (ch ==':' || isalpha(ch) || ch == '_');\n}\n\nstatic inline bool IsANumberChar(int ch) {\n\t// Not exactly following number definition (several dots are seen as OK, etc.)\n\t// but probably enough in most cases.\n\treturn (ch < 0x80) &&\n\t       (IsADigit(ch, 0x10) || toupper(ch) == 'E' ||\n\t        ch == '.' || ch == '-' || ch == '+');\n}\n\nstatic void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int , WordList *keywordlists[], Accessor &styler) {\n#define  isComment(s) (s==SCE_TCL_COMMENT || s==SCE_TCL_COMMENTLINE || s==SCE_TCL_COMMENT_BOX || s==SCE_TCL_BLOCK_COMMENT)\n\tconst bool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\tconst bool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tbool commentLevel = false;\n\tbool subBrace = false; // substitution begin with a brace ${.....}\n\tenum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_COMMENT_BOX, LS_MASK_STATE = 0xf,\n\t                 LS_COMMAND_EXPECTED = 16, LS_BRACE_ONLY = 32\n\t                } lineState = LS_DEFAULT;\n\tbool prevSlash = false;\n\tint currentLevel = 0;\n\tbool expected = 0;\n\tbool subParen = 0;\n\n\tSci_Position currentLine = styler.GetLine(startPos);\n\tif (currentLine > 0)\n\t\tcurrentLine--;\n\tlength += startPos - styler.LineStart(currentLine);\n\t// make sure lines overlap\n\tstartPos = styler.LineStart(currentLine);\n\n\tWordList &keywords = *keywordlists[0];\n\tWordList &keywords2 = *keywordlists[1];\n\tWordList &keywords3 = *keywordlists[2];\n\tWordList &keywords4 = *keywordlists[3];\n\tWordList &keywords5 = *keywordlists[4];\n\tWordList &keywords6 = *keywordlists[5];\n\tWordList &keywords7 = *keywordlists[6];\n\tWordList &keywords8 = *keywordlists[7];\n\tWordList &keywords9 = *keywordlists[8];\n\n\tif (currentLine > 0) {\n\t\tint ls = styler.GetLineState(currentLine - 1);\n\t\tlineState = tLineState(ls & LS_MASK_STATE);\n\t\texpected = LS_COMMAND_EXPECTED == tLineState(ls & LS_COMMAND_EXPECTED);\n\t\tsubBrace = LS_BRACE_ONLY == tLineState(ls & LS_BRACE_ONLY);\n\t\tcurrentLevel = styler.LevelAt(currentLine - 1) >> 17;\n\t\tcommentLevel = (styler.LevelAt(currentLine - 1) >> 16) & 1;\n\t} else\n\t\tstyler.SetLevel(0, SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG);\n\tbool visibleChars = false;\n\n\tint previousLevel = currentLevel;\n\tStyleContext sc(startPos, length, SCE_TCL_DEFAULT, styler);\n\tfor (; ; sc.Forward()) {\nnext:\n\t\tif (sc.ch=='\\r' && sc.chNext == '\\n') // only ignore \\r on PC process on the mac\n\t\t\tcontinue;\n\t\tbool atEnd = !sc.More();  // make sure we coloured the last word\n\t\tif (lineState != LS_DEFAULT) {\n\t\t\tsc.SetState(SCE_TCL_DEFAULT);\n\t\t\tif (lineState == LS_OPEN_COMMENT)\n\t\t\t\tsc.SetState(SCE_TCL_COMMENTLINE);\n\t\t\telse if (lineState == LS_OPEN_DOUBLE_QUOTE)\n\t\t\t\tsc.SetState(SCE_TCL_IN_QUOTE);\n\t\t\telse if (lineState == LS_COMMENT_BOX && (sc.ch == '#' || (sc.ch == ' ' && sc.chNext=='#')))\n\t\t\t\tsc.SetState(SCE_TCL_COMMENT_BOX);\n\t\t\tlineState = LS_DEFAULT;\n\t\t}\n\t\tif (subBrace) { // ${ overrides every thing even \\ except }\n\t\t\tif (sc.ch == '}') {\n\t\t\t\tsubBrace = false;\n\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);\n\t\t\t\tsc.ForwardSetState(SCE_TCL_DEFAULT);\n\t\t\t\tgoto next;\n\t\t\t} else\n\t\t\t\tsc.SetState(SCE_TCL_SUB_BRACE);\n\t\t\tif (!sc.atLineEnd)\n\t\t\t\tcontinue;\n\t\t} else if (sc.state == SCE_TCL_DEFAULT || sc.state ==SCE_TCL_OPERATOR) {\n\t\t\texpected &= isspacechar(static_cast<unsigned char>(sc.ch)) || IsAWordStart(sc.ch) || sc.ch =='#';\n\t\t} else if (sc.state == SCE_TCL_SUBSTITUTION) {\n\t\t\tswitch (sc.ch) {\n\t\t\tcase '(':\n\t\t\t\tsubParen=true;\n\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);\n\t\t\t\tsc.ForwardSetState(SCE_TCL_SUBSTITUTION);\n\t\t\t\tcontinue;\n\t\t\tcase ')':\n\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);\n\t\t\t\tsubParen=false;\n\t\t\t\tcontinue;\n\t\t\tcase '$':\n\t\t\t\tcontinue;\n\t\t\tcase ',':\n\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);\n\t\t\t\tif (subParen) {\n\t\t\t\t\tsc.ForwardSetState(SCE_TCL_SUBSTITUTION);\n\t\t\t\t\tgoto next;\t// Already forwarded so avoid loop's Forward()\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\tdefault :\n\t\t\t\t// maybe spaces should be allowed ???\n\t\t\t\tif (!IsAWordChar(sc.ch)) { // probably the code is wrong\n\t\t\t\t\tsc.SetState(SCE_TCL_DEFAULT);\n\t\t\t\t\tsubParen = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if (isComment(sc.state)) {\n\t\t} else if (!IsAWordChar(sc.ch)) {\n\t\t\tif ((sc.state == SCE_TCL_IDENTIFIER && expected) ||  sc.state == SCE_TCL_MODIFIER) {\n\t\t\t\tchar w[100];\n\t\t\t\tsc.GetCurrent(w, sizeof(w));\n\t\t\t\tchar *s=w;\n\t\t\t\tif (w[strlen(w)-1]=='\\r')\n\t\t\t\t\tw[strlen(w)-1]=0;\n\t\t\t\twhile (*s == ':') // ignore leading : like in ::set a 10\n\t\t\t\t\t++s;\n\t\t\t\tbool quote = sc.state == SCE_TCL_IN_QUOTE;\n\t\t\t\tif (commentLevel  || expected) {\n\t\t\t\t\tif (keywords.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD);\n\t\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD2);\n\t\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD3);\n\t\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD4);\n\t\t\t\t\t} else if (sc.GetRelative(-static_cast<Sci_Position>(strlen(s))-1) == '{' &&\n\t\t\t\t\t           keywords5.InList(s) && sc.ch == '}') { // {keyword} exactly no spaces\n\t\t\t\t\t\tsc.ChangeState(SCE_TCL_EXPAND);\n\t\t\t\t\t}\n\t\t\t\t\tif (keywords6.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_TCL_WORD5);\n\t\t\t\t\t} else if (keywords7.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_TCL_WORD6);\n\t\t\t\t\t} else if (keywords8.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_TCL_WORD7);\n\t\t\t\t\t} else if (keywords9.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_TCL_WORD8);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\texpected = false;\n\t\t\t\tsc.SetState(quote ? SCE_TCL_IN_QUOTE : SCE_TCL_DEFAULT);\n\t\t\t} else if (sc.state == SCE_TCL_MODIFIER || sc.state == SCE_TCL_IDENTIFIER) {\n\t\t\t\tsc.SetState(SCE_TCL_DEFAULT);\n\t\t\t}\n\t\t}\n\t\tif (atEnd)\n\t\t\tbreak;\n\t\tif (sc.atLineEnd) {\n\t\t\tlineState = LS_DEFAULT;\n\t\t\tcurrentLine = styler.GetLine(sc.currentPos);\n\t\t\tif (foldComment && sc.state!=SCE_TCL_COMMENT && isComment(sc.state)) {\n\t\t\t\tif (currentLevel == 0) {\n\t\t\t\t\t++currentLevel;\n\t\t\t\t\tcommentLevel = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (visibleChars && commentLevel) {\n\t\t\t\t\t--currentLevel;\n\t\t\t\t\t--previousLevel;\n\t\t\t\t\tcommentLevel = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tint flag = 0;\n\t\t\tif (!visibleChars && foldCompact)\n\t\t\t\tflag = SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (currentLevel > previousLevel)\n\t\t\t\tflag = SC_FOLDLEVELHEADERFLAG;\n\t\t\tstyler.SetLevel(currentLine, flag + previousLevel + SC_FOLDLEVELBASE + (currentLevel << 17) + (commentLevel << 16));\n\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tif (sc.state == SCE_TCL_IN_QUOTE) {\n\t\t\t\tlineState = LS_OPEN_DOUBLE_QUOTE;\n\t\t\t} else {\n\t\t\t\tif (prevSlash) {\n\t\t\t\t\tif (isComment(sc.state))\n\t\t\t\t\t\tlineState = LS_OPEN_COMMENT;\n\t\t\t\t} else if (sc.state == SCE_TCL_COMMENT_BOX)\n\t\t\t\t\tlineState = LS_COMMENT_BOX;\n\t\t\t}\n\t\t\tstyler.SetLineState(currentLine,\n\t\t\t                    (subBrace ? LS_BRACE_ONLY : 0) |\n\t\t\t                    (expected ? LS_COMMAND_EXPECTED : 0)  | lineState);\n\t\t\tif (lineState == LS_COMMENT_BOX)\n\t\t\t\tsc.ForwardSetState(SCE_TCL_COMMENT_BOX);\n\t\t\telse if (lineState == LS_OPEN_DOUBLE_QUOTE)\n\t\t\t\tsc.ForwardSetState(SCE_TCL_IN_QUOTE);\n\t\t\telse\n\t\t\t\tsc.ForwardSetState(SCE_TCL_DEFAULT);\n\t\t\tprevSlash = false;\n\t\t\tpreviousLevel = currentLevel;\n\t\t\tvisibleChars = false;\n\t\t\tgoto next;\n\t\t}\n\n\t\tif (prevSlash) {\n\t\t\tprevSlash = false;\n\t\t\tif (sc.ch == '#' && IsANumberChar(sc.chNext))\n\t\t\t\tsc.ForwardSetState(SCE_TCL_NUMBER);\n\t\t\tcontinue;\n\t\t}\n\t\tprevSlash = sc.ch == '\\\\';\n\t\tif (isComment(sc.state))\n\t\t\tcontinue;\n\t\tif (sc.atLineStart) {\n\t\t\tvisibleChars = false;\n\t\t\tif (sc.state!=SCE_TCL_IN_QUOTE && !isComment(sc.state))\n\t\t\t{\n\t\t\t\tsc.SetState(SCE_TCL_DEFAULT);\n\t\t\t\texpected = IsAWordStart(sc.ch)|| isspacechar(static_cast<unsigned char>(sc.ch));\n\t\t\t}\n\t\t}\n\n\t\tswitch (sc.state) {\n\t\tcase SCE_TCL_NUMBER:\n\t\t\tif (!IsANumberChar(sc.ch))\n\t\t\t\tsc.SetState(SCE_TCL_DEFAULT);\n\t\t\tbreak;\n\t\tcase SCE_TCL_IN_QUOTE:\n\t\t\tif (sc.ch == '\"') {\n\t\t\t\tsc.ForwardSetState(SCE_TCL_DEFAULT);\n\t\t\t\tvisibleChars = true; // necessary if a \" is the first and only character on a line\n\t\t\t\tgoto next;\n\t\t\t} else if (sc.ch == '[' || sc.ch == ']' || sc.ch == '$') {\n\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);\n\t\t\t\texpected = sc.ch == '[';\n\t\t\t\tsc.ForwardSetState(SCE_TCL_IN_QUOTE);\n\t\t\t\tgoto next;\n\t\t\t}\n\t\t\tcontinue;\n\t\tcase SCE_TCL_OPERATOR:\n\t\t\tsc.SetState(SCE_TCL_DEFAULT);\n\t\t\tbreak;\n\t\t}\n\n\t\tif (sc.ch == '#') {\n\t\t\tif (visibleChars) {\n\t\t\t\tif (sc.state != SCE_TCL_IN_QUOTE && expected)\n\t\t\t\t\tsc.SetState(SCE_TCL_COMMENT);\n\t\t\t} else {\n\t\t\t\tsc.SetState(SCE_TCL_COMMENTLINE);\n\t\t\t\tif (sc.chNext == '~')\n\t\t\t\t\tsc.SetState(SCE_TCL_BLOCK_COMMENT);\n\t\t\t\tif (sc.atLineStart && (sc.chNext == '#' || sc.chNext == '-'))\n\t\t\t\t\tsc.SetState(SCE_TCL_COMMENT_BOX);\n\t\t\t}\n\t\t}\n\n\t\tif (!isspacechar(static_cast<unsigned char>(sc.ch))) {\n\t\t\tvisibleChars = true;\n\t\t}\n\n\t\tif (sc.ch == '\\\\') {\n\t\t\tprevSlash = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (sc.state == SCE_TCL_DEFAULT) {\n\t\t\tif (IsAWordStart(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_TCL_IDENTIFIER);\n\t\t\t} else if (IsADigit(sc.ch) && !IsAWordChar(sc.chPrev)) {\n\t\t\t\tsc.SetState(SCE_TCL_NUMBER);\n\t\t\t} else {\n\t\t\t\tswitch (sc.ch) {\n\t\t\t\tcase '\\\"':\n\t\t\t\t\tsc.SetState(SCE_TCL_IN_QUOTE);\n\t\t\t\t\tbreak;\n\t\t\t\tcase '{':\n\t\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);\n\t\t\t\t\texpected = true;\n\t\t\t\t\t++currentLevel;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '}':\n\t\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);\n\t\t\t\t\texpected = true;\n\t\t\t\t\t--currentLevel;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '[':\n\t\t\t\t\texpected = true;\n\t\t\t\t\t[[fallthrough]];\n\t\t\t\tcase ']':\n\t\t\t\tcase '(':\n\t\t\t\tcase ')':\n\t\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ';':\n\t\t\t\t\texpected = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '$':\n\t\t\t\t\tsubParen = 0;\n\t\t\t\t\tif (sc.chNext != '{') {\n\t\t\t\t\t\tsc.SetState(SCE_TCL_SUBSTITUTION);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);  // $\n\t\t\t\t\t\tsc.Forward();  // {\n\t\t\t\t\t\tsc.ForwardSetState(SCE_TCL_SUB_BRACE);\n\t\t\t\t\t\tsubBrace = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase '#':\n\t\t\t\t\tif ((isspacechar(static_cast<unsigned char>(sc.chPrev))||\n\t\t\t\t\t        isoperator(static_cast<char>(sc.chPrev))) && IsADigit(sc.chNext,0x10))\n\t\t\t\t\t\tsc.SetState(SCE_TCL_NUMBER);\n\t\t\t\t\tbreak;\n\t\t\t\tcase '-':\n\t\t\t\t\tsc.SetState(IsADigit(sc.chNext)? SCE_TCL_NUMBER: SCE_TCL_MODIFIER);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif (isoperator(static_cast<char>(sc.ch))) {\n\t\t\t\t\t\tsc.SetState(SCE_TCL_OPERATOR);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tsc.Complete();\n}\n\nstatic const char *const tclWordListDesc[] = {\n\t\"TCL Keywords\",\n\t\"TK Keywords\",\n\t\"iTCL Keywords\",\n\t\"tkCommands\",\n\t\"expand\",\n\t\"user1\",\n\t\"user2\",\n\t\"user3\",\n\t\"user4\",\n\t0\n};\n\n// this code supports folding in the colourizer\nextern const LexerModule lmTCL(SCLEX_TCL, ColouriseTCLDoc, \"tcl\", 0, tclWordListDesc);\n"
  },
  {
    "path": "lexers/LexTCMD.cxx",
    "content": "// Scintilla\\ source code edit control\n/** @file LexTCMD.cxx\n ** Lexer for Take Command / TCC batch scripts (.bat, .btm, .cmd).\n **/\n// Written by Rex Conn (rconn [at] jpsoft [dot] com)\n// based on the CMD lexer\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\nstatic bool IsAlphabetic(int ch) {\n\treturn IsASCII(ch) && isalpha(ch);\n}\n\nstatic inline bool AtEOL(Accessor &styler, Sci_PositionU i) {\n\treturn (styler[i] == '\\n') || ((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n'));\n}\n\n// Tests for BATCH Operators\nstatic bool IsBOperator(char ch) {\n\treturn (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') || (ch == '|') || (ch == '&') || (ch == '!') || (ch == '?') || (ch == '*') || (ch == '(') || (ch == ')');\n}\n\n// Tests for BATCH Separators\nstatic bool IsBSeparator(char ch) {\n\treturn (ch == '\\\\') || (ch == '.') || (ch == ';') || (ch == ' ') || (ch == '\\t') || (ch == '[') || (ch == ']') || (ch == '\\\"') || (ch == '\\'') || (ch == '/');\n}\n\n// Find length of CMD FOR variable with modifier (%~...) or return 0\nstatic unsigned int GetBatchVarLen( char *wordBuffer )\n{\n\tint nLength = 0;\n\tif ( wordBuffer[0] == '%' ) {\n\n\t\tif ( wordBuffer[1] == '~' )\n\t\t\tnLength = 2;\n\t\telse if (( wordBuffer[1] == '%' ) && ( wordBuffer[2] == '~' ))\n\t\t\tnLength++;\n\t\telse\n\t\t\treturn 0;\n\n\t\tfor ( ; ( wordBuffer[nLength] ); nLength++ ) {\n\n\t\t\tswitch ( toupper(wordBuffer[nLength]) ) {\n\t\t\tcase 'A':\n\t\t\t\t// file attributes\n\t\t\tcase 'D':\n\t\t\t\t// drive letter only\n\t\t\tcase 'F':\n\t\t\t\t// fully qualified path name\n\t\t\tcase 'N':\n\t\t\t\t// filename only\n\t\t\tcase 'P':\n\t\t\t\t// path only\n\t\t\tcase 'S':\n\t\t\t\t// short name\n\t\t\tcase 'T':\n\t\t\t\t// date / time of file\n\t\t\tcase 'X':\n\t\t\t\t// file extension only\n\t\t\tcase 'Z':\n\t\t\t\t// file size\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn nLength;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nLength;\n}\n\n\nstatic void ColouriseTCMDLine( char *lineBuffer, Sci_PositionU lengthLine, Sci_PositionU startLine, Sci_PositionU endPos, WordList *keywordlists[], Accessor &styler)\n{\n\tSci_PositionU offset = 0;\t// Line Buffer Offset\n\tchar wordBuffer[260];\t\t// Word Buffer - large to catch long paths\n\tSci_PositionU wbl;\t\t\t// Word Buffer Length\n\tSci_PositionU wbo;\t\t\t// Word Buffer Offset - also Special Keyword Buffer Length\n\tWordList &keywords = *keywordlists[0];      // Internal Commands\n//\tWordList &keywords2 = *keywordlists[1];     // Aliases (optional)\n\tbool isDelayedExpansion = 1;\t\t\t\t// !var!\n\n\tbool continueProcessing = true;\t// Used to toggle Regular Keyword Checking\n\t// Special Keywords are those that allow certain characters without whitespace after the command\n\t// Examples are: cd. cd\\ echo: echo. path=\n\tbool inString = false; // Used for processing while \"\"\n\t// Special Keyword Buffer used to determine if the first n characters is a Keyword\n\tchar sKeywordBuffer[260] = \"\";\t// Special Keyword Buffer\n\tbool sKeywordFound;\t\t// Exit Special Keyword for-loop if found\n\n\t// Skip leading whitespace\n\twhile ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {\n\t\toffset++;\n\t}\n\t// Colorize Default Text\n\tstyler.ColourTo(startLine + offset - 1, SCE_TCMD_DEFAULT);\n\n\tif ( offset >= lengthLine )\n\t\treturn;\n\n\t// Check for Fake Label (Comment) or Real Label - return if found\n\tif (lineBuffer[offset] == ':') {\n\t\tif (lineBuffer[offset + 1] == ':') {\n\t\t\t// Colorize Fake Label (Comment) - :: is the same as REM\n\t\t\tstyler.ColourTo(endPos, SCE_TCMD_COMMENT);\n\t\t} else {\n\t\t\t// Colorize Real Label\n\t\t\tstyler.ColourTo(endPos, SCE_TCMD_LABEL);\n\t\t}\n\t\treturn;\n\n\t// Check for Comment - return if found\n\t} else if (( CompareNCaseInsensitive(lineBuffer+offset, \"rem\", 3) == 0 ) && (( lineBuffer[offset+3] == 0 ) || ( isspace(lineBuffer[offset+3] )))) {\n\t\t\tstyler.ColourTo(endPos, SCE_TCMD_COMMENT);\n\t\t\treturn;\n\n\t// Check for Drive Change (Drive Change is internal command) - return if found\n\t} else if ((IsAlphabetic(lineBuffer[offset])) &&\n\t\t(lineBuffer[offset + 1] == ':') &&\n\t\t((isspacechar(lineBuffer[offset + 2])) ||\n\t\t(((lineBuffer[offset + 2] == '\\\\')) &&\n\t\t(isspacechar(lineBuffer[offset + 3]))))) {\n\t\t// Colorize Regular Keyword\n\t\tstyler.ColourTo(endPos, SCE_TCMD_WORD);\n\t\treturn;\n\t}\n\n\t// Check for Hide Command (@ECHO OFF/ON)\n\tif (lineBuffer[offset] == '@') {\n\t\tstyler.ColourTo(startLine + offset, SCE_TCMD_HIDE);\n\t\toffset++;\n\t}\n\t// Skip whitespace\n\twhile ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {\n\t\toffset++;\n\t}\n\n\t// Read remainder of line word-at-a-time or remainder-of-word-at-a-time\n\twhile (offset < lengthLine) {\n\t\tif (offset > startLine) {\n\t\t\t// Colorize Default Text\n\t\t\tstyler.ColourTo(startLine + offset - 1, SCE_TCMD_DEFAULT);\n\t\t}\n\t\t// Copy word from Line Buffer into Word Buffer\n\t\twbl = 0;\n\t\tfor (; offset < lengthLine && ( wbl < 260 ) && !isspacechar(lineBuffer[offset]); wbl++, offset++) {\n\t\t\twordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));\n\t\t}\n\t\twordBuffer[wbl] = '\\0';\n\t\twbo = 0;\n\n\t\t// Check for Separator\n\t\tif (IsBSeparator(wordBuffer[0])) {\n\n\t\t\t// Reset Offset to re-process remainder of word\n\t\t\toffset -= (wbl - 1);\n\t\t\t// Colorize Default Text\n\t\t\tstyler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);\n\n\t\t\tif (wordBuffer[0] == '\"')\n\t\t\t\tinString = !inString;\n\n\t\t// Check for Regular expression\n\t\t} else if (( wordBuffer[0] == ':' ) && ( wordBuffer[1] == ':' ) && (continueProcessing)) {\n\n\t\t\t// Colorize Regular exoressuin\n\t\t\tstyler.ColourTo(startLine + offset - 1, SCE_TCMD_DEFAULT);\n\t\t\t// No need to Reset Offset\n\n\t\t// Check for Labels in text (... :label)\n\t\t} else if (wordBuffer[0] == ':' && isspacechar(lineBuffer[offset - wbl - 1])) {\n\t\t\t// Colorize Default Text\n\t\t\tstyler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT);\n\t\t\t// Colorize Label\n\t\t\tstyler.ColourTo(startLine + offset - 1, SCE_TCMD_CLABEL);\n\t\t\t// No need to Reset Offset\n\t\t// Check for delayed expansion Variable (!x...!)\n\t\t} else if (isDelayedExpansion && wordBuffer[0] == '!') {\n\t\t\t// Colorize Default Text\n\t\t\tstyler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT);\n\t\t\twbo++;\n\t\t\t// Search to end of word for second !\n\t\t\twhile ((wbo < wbl) && (wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) {\n\t\t\t\twbo++;\n\t\t\t}\n\t\t\tif (wordBuffer[wbo] == '!') {\n\t\t\t\twbo++;\n\t\t\t\t// Colorize Environment Variable\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_EXPANSION);\n\t\t\t} else {\n\t\t\t\twbo = 1;\n\t\t\t\t// Colorize Symbol\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_DEFAULT);\n\t\t\t}\n\n\t\t\t// Reset Offset to re-process remainder of word\n\t\t\toffset -= (wbl - wbo);\n\n\t\t// Check for Regular Keyword in list\n\t\t} else if ((keywords.InList(wordBuffer)) &&\t(!inString) && (continueProcessing)) {\n\n\t\t\t// ECHO, PATH, and PROMPT require no further Regular Keyword Checking\n\t\t\tif ((CompareCaseInsensitive(wordBuffer, \"echo\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(sKeywordBuffer, \"echos\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(sKeywordBuffer, \"echoerr\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(sKeywordBuffer, \"echoserr\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(wordBuffer, \"path\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(wordBuffer, \"prompt\") == 0)) {\n\t\t\t\tcontinueProcessing = false;\n\t\t\t}\n\n\t\t\t// Colorize Regular keyword\n\t\t\tstyler.ColourTo(startLine + offset - 1, SCE_TCMD_WORD);\n\t\t\t// No need to Reset Offset\n\n\t\t} else if ((wordBuffer[0] != '%') && (wordBuffer[0] != '!') && (!IsBOperator(wordBuffer[0])) &&\t(!inString) && (continueProcessing)) {\n\n\t\t\t// a few commands accept \"illegal\" syntax -- cd\\, echo., etc.\n\t\t\tsscanf( wordBuffer, \"%[^.<>|&=\\\\/]\", sKeywordBuffer );\n\t\t\tsKeywordFound = false;\n\n\t\t\tif ((CompareCaseInsensitive(sKeywordBuffer, \"echo\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(sKeywordBuffer, \"echos\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(sKeywordBuffer, \"echoerr\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(sKeywordBuffer, \"echoserr\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(sKeywordBuffer, \"cd\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(sKeywordBuffer, \"path\") == 0) ||\n\t\t\t  (CompareCaseInsensitive(sKeywordBuffer, \"prompt\") == 0)) {\n\n\t\t\t\t// no further Regular Keyword Checking\n\t\t\t\tcontinueProcessing = false;\n\t\t\t\tsKeywordFound = true;\n\t\t\t\twbo = (Sci_PositionU)strlen( sKeywordBuffer );\n\n\t\t\t\t// Colorize Special Keyword as Regular Keyword\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_WORD);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - wbo);\n\t\t\t}\n\n\t\t\t// Check for Default Text\n\t\t\tif (!sKeywordFound) {\n\t\t\t\twbo = 0;\n\t\t\t\t// Read up to %, Operator or Separator\n\t\t\t\twhile ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!isDelayedExpansion || wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) &&\t(!IsBSeparator(wordBuffer[wbo]))) {\n\t\t\t\t\twbo++;\n\t\t\t\t}\n\t\t\t\t// Colorize Default Text\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_DEFAULT);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - wbo);\n\t\t\t}\n\n\t\t// Check for Argument  (%n), Environment Variable (%x...%) or Local Variable (%%a)\n\t\t} else if (wordBuffer[0] == '%') {\n\t\t\tunsigned int varlen;\n\t\t\tunsigned int n = 1;\n\t\t\t// Colorize Default Text\n\t\t\tstyler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT);\n\t\t\twbo++;\n\n\t\t\t// check for %[nn] syntax\n\t\t\tif ( wordBuffer[1] == '[' ) {\n\t\t\t\tn++;\n\t\t\t\twhile ((n < wbl) && (wordBuffer[n] != ']')) {\n\t\t\t\t\tn++;\n\t\t\t\t}\n\t\t\t\tif ( wordBuffer[n] == ']' )\n\t\t\t\t\tn++;\n\t\t\t\tgoto ColorizeArg;\n\t\t\t}\n\n\t\t\t// Search to end of word for second % or to the first terminator (can be a long path)\n\t\t\twhile ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) {\n\t\t\t\twbo++;\n\t\t\t}\n\n\t\t\t// Check for Argument (%n) or (%*)\n\t\t\tif (((isdigit(wordBuffer[1])) || (wordBuffer[1] == '*')) && (wordBuffer[wbo] != '%')) {\n\t\t\t\twhile (( wordBuffer[n] ) && ( strchr( \"%0123456789*#$\", wordBuffer[n] ) != NULL ))\n\t\t\t\t\tn++;\nColorizeArg:\n\t\t\t\t// Colorize Argument\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - n), SCE_TCMD_IDENTIFIER);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - n);\n\n\t\t\t// Check for Variable with modifiers (%~...)\n\t\t\t} else if ((varlen = GetBatchVarLen(wordBuffer)) != 0) {\n\n\t\t\t\t// Colorize Variable\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - varlen), SCE_TCMD_IDENTIFIER);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - varlen);\n\n\t\t\t// Check for Environment Variable (%x...%)\n\t\t\t} else if (( wordBuffer[1] ) && ( wordBuffer[1] != '%')) {\n\t\t\t\tif ( wordBuffer[wbo] == '%' )\n\t\t\t\t\twbo++;\n\n\t\t\t\t// Colorize Environment Variable\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_ENVIRONMENT);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - wbo);\n\n\t\t\t// Check for Local Variable (%%a)\n\t\t\t} else if (\t(wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] != '%') && (!IsBOperator(wordBuffer[2])) && (!IsBSeparator(wordBuffer[2]))) {\n\n\t\t\t\tn = 2;\n\t\t\t\twhile (( wordBuffer[n] ) && (!IsBOperator(wordBuffer[n])) && (!IsBSeparator(wordBuffer[n])))\n\t\t\t\t\tn++;\n\n\t\t\t\t// Colorize Local Variable\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - n), SCE_TCMD_IDENTIFIER);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - n);\n\n\t\t\t// Check for %%\n\t\t\t} else if ((wbl > 1) && (wordBuffer[1] == '%')) {\n\n\t\t\t\t// Colorize Symbols\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_TCMD_DEFAULT);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - 2);\n\t\t\t} else {\n\n\t\t\t\t// Colorize Symbol\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_DEFAULT);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - 1);\n\t\t\t}\n\n\t\t// Check for Operator\n\t\t} else if (IsBOperator(wordBuffer[0])) {\n\t\t\t// Colorize Default Text\n\t\t\tstyler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT);\n\n\t\t\t// Check for Pipe, compound, or conditional Operator\n\t\t\tif ((wordBuffer[0] == '|') || (wordBuffer[0] == '&')) {\n\n\t\t\t\t// Colorize Pipe Operator\n\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_OPERATOR);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - 1);\n\t\t\t\tcontinueProcessing = true;\n\n\t\t\t// Check for Other Operator\n\t\t\t} else {\n\t\t\t\t// Check for > Operator\n\t\t\t\tif ((wordBuffer[0] == '>') || (wordBuffer[0] == '<')) {\n\t\t\t\t\t// Turn Keyword and External Command / Program checking back on\n\t\t\t\t\tcontinueProcessing = true;\n\t\t\t\t}\n\t\t\t\t// Colorize Other Operator\n\t\t\t\tif (!inString || !(wordBuffer[0] == '(' || wordBuffer[0] == ')'))\n\t\t\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_OPERATOR);\n\t\t\t\t// Reset Offset to re-process remainder of word\n\t\t\t\toffset -= (wbl - 1);\n\t\t\t}\n\n\t\t// Check for Default Text\n\t\t} else {\n\t\t\t// Read up to %, Operator or Separator\n\t\t\twhile ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!isDelayedExpansion || wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) &&\t(!IsBSeparator(wordBuffer[wbo]))) {\n\t\t\t\twbo++;\n\t\t\t}\n\t\t\t// Colorize Default Text\n\t\t\tstyler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_DEFAULT);\n\t\t\t// Reset Offset to re-process remainder of word\n\t\t\toffset -= (wbl - wbo);\n\t\t}\n\n\t\t// Skip whitespace - nothing happens if Offset was Reset\n\t\twhile ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {\n\t\t\toffset++;\n\t\t}\n\t}\n\t// Colorize Default Text for remainder of line - currently not lexed\n\tstyler.ColourTo(endPos, SCE_TCMD_DEFAULT);\n}\n\nstatic void ColouriseTCMDDoc( Sci_PositionU startPos, Sci_Position length, int /*initStyle*/, WordList *keywordlists[], Accessor &styler )\n{\n\tchar lineBuffer[16384];\n\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tSci_PositionU linePos = 0;\n\tSci_PositionU startLine = startPos;\n\tfor (Sci_PositionU i = startPos; i < startPos + length; i++) {\n\t\tlineBuffer[linePos++] = styler[i];\n\t\tif (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {\n\t\t\t// End of line (or of line buffer) met, colourise it\n\t\t\tlineBuffer[linePos] = '\\0';\n\t\t\tColouriseTCMDLine(lineBuffer, linePos, startLine, i, keywordlists, styler);\n\t\t\tlinePos = 0;\n\t\t\tstartLine = i + 1;\n\t\t}\n\t}\n\tif (linePos > 0) {\t// Last line does not have ending characters\n\t\tlineBuffer[linePos] = '\\0';\n\t\tColouriseTCMDLine(lineBuffer, linePos, startLine, startPos + length - 1, keywordlists, styler);\n\t}\n}\n\n// Convert string to upper case\nstatic void StrUpr(char *s) {\n\twhile (*s) {\n\t\t*s = MakeUpperCase(*s);\n\t\ts++;\n\t}\n}\n\n// Folding support (for DO, IFF, SWITCH, TEXT, and command groups)\nstatic void FoldTCMDDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)\n{\n\tSci_Position line = styler.GetLine(startPos);\n\tint level = styler.LevelAt(line);\n\tint levelIndent = 0;\n\tSci_PositionU endPos = startPos + length;\n\tchar s[16] = \"\";\n\n    char chPrev = styler.SafeGetCharAt(startPos - 1);\n\n\t// Scan for ( and )\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\n\t\tint c = styler.SafeGetCharAt(i, '\\n');\n\t\tint style = styler.StyleAt(i);\n        bool bLineStart = ((chPrev == '\\r') || (chPrev == '\\n')) || i == 0;\n\n\t\tif (style == SCE_TCMD_OPERATOR) {\n\t\t\t// CheckFoldPoint\n\t\t\tif (c == '(') {\n\t\t\t\tlevelIndent += 1;\n\t\t\t} else if (c == ')') {\n\t\t\t\tlevelIndent -= 1;\n\t\t\t}\n\t\t}\n\n        if (( bLineStart ) && ( style == SCE_TCMD_WORD )) {\n            for (Sci_PositionU j = 0; j < 10; j++) {\n                if (!iswordchar(styler[i + j])) {\n                    break;\n                }\n                s[j] = styler[i + j];\n                s[j + 1] = '\\0';\n            }\n\n\t\t\tStrUpr( s );\n            if ((strcmp(s, \"DO\") == 0) || (strcmp(s, \"IFF\") == 0) || (strcmp(s, \"SWITCH\") == 0) || (strcmp(s, \"TEXT\") == 0)) {\n                levelIndent++;\n            } else if ((strcmp(s, \"ENDDO\") == 0) || (strcmp(s, \"ENDIFF\") == 0) || (strcmp(s, \"ENDSWITCH\") == 0) || (strcmp(s, \"ENDTEXT\") == 0)) {\n                levelIndent--;\n            }\n        }\n\n\t\tif (c == '\\n') { // line end\n\t\t\t\tif (levelIndent > 0) {\n\t\t\t\t\t\tlevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t}\n\t\t\t\tif (level != styler.LevelAt(line))\n\t\t\t\t\t\tstyler.SetLevel(line, level);\n\t\t\t\tlevel += levelIndent;\n\t\t\t\tif ((level & SC_FOLDLEVELNUMBERMASK) < SC_FOLDLEVELBASE)\n\t\t\t\t\t\tlevel = SC_FOLDLEVELBASE;\n\t\t\t\tline++;\n\t\t\t\t// reset state\n\t\t\t\tlevelIndent = 0;\n\t\t\t\tlevel &= ~SC_FOLDLEVELHEADERFLAG;\n\t\t\t\tlevel &= ~SC_FOLDLEVELWHITEFLAG;\n\t\t}\n\n\t\tchPrev = c;\n\t}\n}\n\nstatic const char *const tcmdWordListDesc[] = {\n\t\"Internal Commands\",\n\t\"Aliases\",\n\t0\n};\n\nextern const LexerModule lmTCMD(SCLEX_TCMD, ColouriseTCMDDoc, \"tcmd\", FoldTCMDDoc, tcmdWordListDesc);\n"
  },
  {
    "path": "lexers/LexTOML.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexTOML.cxx\n ** Lexer for TOML language.\n **/\n// Based on Zufu Liu's Notepad4 TOML lexer\n// Modified for Scintilla by Jiri Techet, 2024\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n// Use an unnamed namespace to protect the functions and classes from name conflicts\n\nconstexpr bool IsEOLChar(int ch) noexcept {\n\treturn ch == '\\r' || ch == '\\n';\n}\n\nconstexpr bool IsIdentifierChar(int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '_';\n}\n\nconstexpr bool IsNumberContinue(int chPrev, int ch, int chNext) noexcept {\n\treturn ((ch == '+' || ch == '-') && (chPrev == 'e' || chPrev == 'E'))\n\t\t|| (ch == '.' && chNext != '.');\n}\n\nconstexpr bool IsDecimalNumber(int chPrev, int ch, int chNext) noexcept {\n\treturn IsIdentifierChar(ch) || IsNumberContinue(chPrev, ch, chNext);\n}\n\nconstexpr bool IsISODateTime(int ch, int chNext) noexcept {\n\treturn ((ch == '+' || ch == '-' || ch == ':' || ch == '.') && IsADigit(chNext))\n\t\t|| (ch == ' ' && (chNext == '+' || chNext == '-' || IsADigit(chNext)));\n}\n\nstruct EscapeSequence {\n\tint outerState = SCE_TOML_DEFAULT;\n\tint digitsLeft = 0;\n\n\t// highlight any character as escape sequence.\n\tbool resetEscapeState(int state, int chNext) noexcept {\n\t\tif (IsEOLChar(chNext)) {\n\t\t\treturn false;\n\t\t}\n\t\touterState = state;\n\t\tdigitsLeft = 1;\n\t\tif (chNext == 'x') {\n\t\t\tdigitsLeft = 3;\n\t\t} else if (chNext == 'u') {\n\t\t\tdigitsLeft = 5;\n\t\t} else if (chNext == 'U') {\n\t\t\tdigitsLeft = 9;\n\t\t}\n\t\treturn true;\n\t}\n\tbool atEscapeEnd(int ch) noexcept {\n\t\t--digitsLeft;\n\t\treturn digitsLeft <= 0 || !IsAHeXDigit(ch);\n\t}\n};\n\nconstexpr bool IsTripleString(int state) noexcept {\n\treturn state == SCE_TOML_TRIPLE_STRING_SQ || state == SCE_TOML_TRIPLE_STRING_DQ;\n}\n\nconstexpr bool IsDoubleQuoted(int state) noexcept {\n\treturn state == SCE_TOML_STRING_DQ || state == SCE_TOML_TRIPLE_STRING_DQ;\n}\n\nconstexpr int GetStringQuote(int state) noexcept {\n\treturn IsDoubleQuoted(state) ? '\\\"' : '\\'';\n}\n\nconstexpr bool IsTOMLOperator(int ch) noexcept {\n\treturn AnyOf(ch, '[', ']', '{', '}', ',', '=', '.', '+', '-');\n}\n\nconstexpr bool IsTOMLUnquotedKey(int ch) noexcept {\n\treturn IsIdentifierChar(ch) || ch == '-';\n}\n\nconstexpr bool IsWhiteSpace(int ch) noexcept {\n\treturn (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));\n}\n\nint GetLineNextChar(StyleContext& sc) {\n\tif (!IsWhiteSpace(sc.ch)) {\n\t\treturn sc.ch;\n\t}\n\tif (static_cast<Sci_Position>(sc.currentPos) + 1 == sc.lineStartNext) {\n\t\treturn '\\0';\n\t}\n\tif (!IsWhiteSpace(sc.chNext)) {\n\t\treturn sc.chNext;\n\t}\n\tfor (Sci_Position pos = 2; pos < sc.lineStartNext; pos++) {\n\t\tconst unsigned char chPos = sc.GetRelative(pos);\n\t\tif (!IsWhiteSpace(chPos)) {\n\t\t\treturn chPos;\n\t\t}\n\t}\n\treturn '\\0';\n}\n\nbool IsTOMLKey(StyleContext& sc, int braceCount, const WordList *kwList) {\n\tif (braceCount) {\n\t\tconst int chNext = GetLineNextChar(sc);\n\t\tif (chNext == '=' || chNext == '.' || chNext == '-') {\n\t\t\tsc.ChangeState(SCE_TOML_KEY);\n\t\t\treturn true;\n\t\t}\n\t}\n\tif (sc.state == SCE_TOML_IDENTIFIER) {\n\t\tchar s[8];\n\t\tsc.GetCurrentLowered(s, sizeof(s));\n#if defined(__clang__)\n\t\t__builtin_assume(kwList != nullptr); // suppress [clang-analyzer-core.CallAndMessage]\n#endif\n\t\tif (kwList->InList(s)) {\n\t\t\tsc.ChangeState(SCE_TOML_KEYWORD);\n\t\t}\n\t}\n\tsc.SetState(SCE_TOML_DEFAULT);\n\treturn false;\n}\n\nenum class TOMLLineType {\n\tNone = 0,\n\tTable,\n\tCommentLine,\n};\n\nenum class TOMLKeyState {\n\tUnquoted = 0,\n\tLiteral, // single-quoted\n\tQuoted,  // double-quoted\n\tEnd,\n};\n\nvoid ColouriseTOMLDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, WordList *keywordLists[], Accessor &styler) {\n\tint visibleChars = 0;\n\tint chPrevNonWhite = 0;\n\tint tableLevel = 0;\n\tint braceCount = 0;\n\tTOMLLineType lineType = TOMLLineType::None;\n\tTOMLKeyState keyState = TOMLKeyState::Unquoted;\n\tEscapeSequence escSeq;\n\n\tif (initStyle == SCE_TOML_STRINGEOL) {\n\t\tinitStyle = SCE_TOML_DEFAULT;\n\t}\n\n\tStyleContext sc(startPos, lengthDoc, initStyle, styler);\n\tif (sc.currentLine > 0) {\n\t\tconst int lineState = styler.GetLineState(sc.currentLine - 1);\n\t\t/*\n\t\t2: lineType\n\t\t8: tableLevel\n\t\t8: braceCount\n\t\t*/\n\t\tbraceCount = (lineState >> 10) & 0xff;\n\t}\n\n\twhile (sc.More()) {\n\t\tswitch (sc.state) {\n\t\tcase SCE_TOML_OPERATOR:\n\t\t\tsc.SetState(SCE_TOML_DEFAULT);\n\t\t\tbreak;\n\n\t\tcase SCE_TOML_NUMBER:\n\t\t\tif (!IsDecimalNumber(sc.chPrev, sc.ch, sc.chNext)) {\n\t\t\t\tif (IsISODateTime(sc.ch, sc.chNext)) {\n\t\t\t\t\tsc.ChangeState(SCE_TOML_DATETIME);\n\t\t\t\t} else if (IsTOMLKey(sc, braceCount, nullptr)) {\n\t\t\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_TOML_DATETIME:\n\t\t\tif (!(IsIdentifierChar(sc.ch) || IsISODateTime(sc.ch, sc.chNext))) {\n\t\t\t\tif (IsTOMLKey(sc, braceCount, nullptr)) {\n\t\t\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_TOML_IDENTIFIER:\n\t\t\tif (!IsIdentifierChar(sc.ch)) {\n\t\t\t\tif (IsTOMLKey(sc, braceCount, keywordLists[0])) {\n\t\t\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_TOML_TABLE:\n\t\tcase SCE_TOML_KEY:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_TOML_DEFAULT);\n\t\t\t} else {\n\t\t\t\tswitch (keyState) {\n\t\t\t\tcase TOMLKeyState::Literal:\n\t\t\t\t\tif (sc.ch == '\\'') {\n\t\t\t\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOMLKeyState::Quoted:\n\t\t\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (keyState == TOMLKeyState::Unquoted) {\n\t\t\t\t\tif (sc.ch == '\\'') {\n\t\t\t\t\t\tkeyState = TOMLKeyState::Literal;\n\t\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\t\tkeyState = TOMLKeyState::Quoted;\n\t\t\t\t\t} else if (sc.ch == '.') {\n\t\t\t\t\t\tif (sc.state == SCE_TOML_TABLE) {\n\t\t\t\t\t\t\t++tableLevel;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tchPrevNonWhite = '.';\n\t\t\t\t\t\t\tsc.SetState(SCE_TOML_OPERATOR);\n\t\t\t\t\t\t\tsc.ForwardSetState(SCE_TOML_KEY);\n\t\t\t\t\t\t\t// TODO: skip space after dot\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (sc.state == SCE_TOML_TABLE && sc.ch == ']') {\n\t\t\t\t\t\tkeyState = TOMLKeyState::End;\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\tif (sc.ch == ']') {\n\t\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst int chNext = GetLineNextChar(sc);\n\t\t\t\t\t\tif (chNext == '#') {\n\t\t\t\t\t\t\tsc.SetState(SCE_TOML_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (sc.state == SCE_TOML_KEY && !IsTOMLUnquotedKey(sc.ch)) {\n\t\t\t\t\t\tconst int chNext = GetLineNextChar(sc);\n\t\t\t\t\t\tif (chNext == '=' || (chNext != '.' && chPrevNonWhite != '.')) {\n\t\t\t\t\t\t\tkeyState = TOMLKeyState::End;\n\t\t\t\t\t\t\tsc.SetState(SCE_TOML_DEFAULT);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_TOML_STRING_SQ:\n\t\tcase SCE_TOML_STRING_DQ:\n\t\tcase SCE_TOML_TRIPLE_STRING_SQ:\n\t\tcase SCE_TOML_TRIPLE_STRING_DQ:\n\t\t\tif (sc.atLineStart && !IsTripleString(sc.state)) {\n\t\t\t\tsc.SetState(SCE_TOML_DEFAULT);\n\t\t\t} else if (sc.atLineEnd && !IsTripleString(sc.state)) {\n\t\t\t\tsc.ChangeState(SCE_TOML_STRINGEOL);\n\t\t\t} else if (sc.ch == '\\\\' && IsDoubleQuoted(sc.state)) {\n\t\t\t\tif (escSeq.resetEscapeState(sc.state, sc.chNext)) {\n\t\t\t\t\tsc.SetState(SCE_TOML_ESCAPECHAR);\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if (sc.ch == GetStringQuote(sc.state) &&\n\t\t\t\t\t(!IsTripleString(sc.state) || (sc.Match(IsDoubleQuoted(sc.state) ? R\"(\"\"\")\" : R\"(''')\")))) {\n\t\t\t\twhile (sc.ch == sc.chNext) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.Forward();\n\t\t\t\tif (!IsTripleString(sc.state) && IsTOMLKey(sc, braceCount, nullptr)) {\n\t\t\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_TOML_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_TOML_STRINGEOL:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_TOML_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_TOML_ESCAPECHAR:\n\t\t\tif (escSeq.atEscapeEnd(sc.ch)) {\n\t\t\t\tsc.SetState(escSeq.outerState);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_TOML_ERROR:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_TOML_DEFAULT);\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_TOML_COMMENT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_TOML_COMMENT:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_TOML_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (sc.state == SCE_TOML_DEFAULT) {\n\t\t\tif (sc.ch == '#') {\n\t\t\t\tsc.SetState(SCE_TOML_COMMENT);\n\t\t\t\tif (visibleChars == 0) {\n\t\t\t\t\tlineType = TOMLLineType::CommentLine;\n\t\t\t\t}\n\t\t\t} else if (visibleChars == 0 && braceCount == 0) {\n\t\t\t\tif (sc.ch == '[') {\n\t\t\t\t\ttableLevel = 0;\n\t\t\t\t\tsc.SetState(SCE_TOML_TABLE);\n\t\t\t\t\tif (sc.chNext == '[') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t\t\t\tlineType = TOMLLineType::Table;\n\t\t\t\t} else if (sc.ch == '\\'' || sc.ch == '\\\"') {\n\t\t\t\t\tkeyState = (sc.ch == '\\'')? TOMLKeyState::Literal : TOMLKeyState::Quoted;\n\t\t\t\t\tsc.SetState(SCE_TOML_KEY);\n\t\t\t\t} else if (IsTOMLUnquotedKey(sc.ch)) {\n\t\t\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t\t\t\tsc.SetState(SCE_TOML_KEY);\n\t\t\t\t} else if (!isspacechar(sc.ch)) {\n\t\t\t\t\t// each line must be: key = value\n\t\t\t\t\tsc.SetState(SCE_TOML_ERROR);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t if (sc.ch == '\\'') {\n\t\t\t\t\tif (sc.Match(R\"(''')\")) {\n\t\t\t\t\t\tsc.SetState(SCE_TOML_TRIPLE_STRING_SQ);\n\t\t\t\t\t\tsc.Forward(2);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_TOML_STRING_SQ);\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\"') {\n\t\t\t\t\tif (sc.Match(R\"(\"\"\")\")) {\n\t\t\t\t\t\tsc.SetState(SCE_TOML_TRIPLE_STRING_DQ);\n\t\t\t\t\t\tsc.Forward(2);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.SetState(SCE_TOML_STRING_DQ);\n\t\t\t\t\t}\n\t\t\t\t} else if (IsADigit(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_TOML_NUMBER);\n\t\t\t\t} else if (IsLowerCase(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_TOML_IDENTIFIER);\n\t\t\t\t} else if (IsTOMLOperator(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_TOML_OPERATOR);\n\t\t\t\t\tif (sc.ch == '[' || sc.ch == '{') {\n\t\t\t\t\t\t++braceCount;\n\t\t\t\t\t} else if (sc.ch == ']' || sc.ch == '}') {\n\t\t\t\t\t\tif (braceCount > 0) {\n\t\t\t\t\t\t\t--braceCount;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (braceCount && IsTOMLUnquotedKey(sc.ch)) {\n\t\t\t\t\t// Inline Table\n\t\t\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t\t\t\tsc.SetState(SCE_TOML_KEY);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!isspacechar(sc.ch)) {\n\t\t\tchPrevNonWhite = sc.ch;\n\t\t\t++visibleChars;\n\t\t}\n\t\tif (sc.atLineEnd) {\n\t\t\tconst int lineState = (tableLevel << 2) | (braceCount << 10) | static_cast<int>(lineType);\n\t\t\tstyler.SetLineState(sc.currentLine, lineState);\n\t\t\tlineType = TOMLLineType::None;\n\t\t\tvisibleChars = 0;\n\t\t\tchPrevNonWhite = 0;\n\t\t\ttableLevel = 0;\n\t\t\tkeyState = TOMLKeyState::Unquoted;\n\t\t}\n\t\tsc.Forward();\n\t}\n\n\tsc.Complete();\n}\n\nconstexpr TOMLLineType GetLineType(int lineState) noexcept {\n\treturn static_cast<TOMLLineType>(lineState & 3);\n}\n\nconstexpr int GetTableLevel(int lineState) noexcept {\n\treturn (lineState >> 2) & 0xff;\n}\n\n// code folding based on LexProps\nvoid FoldTOMLDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int /*initStyle*/, WordList *[] /*keywordLists*/, Accessor &styler) {\n\tconst Sci_Position endPos = startPos + lengthDoc;\n\tconst Sci_Position maxLines = styler.GetLine((endPos == styler.Length()) ? endPos : endPos - 1);\n\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\n\tint prevLevel = SC_FOLDLEVELBASE;\n\tTOMLLineType prevType = TOMLLineType::None;\n\tTOMLLineType prev2Type = TOMLLineType::None;\n\tif (lineCurrent > 0) {\n\t\tprevLevel = styler.LevelAt(lineCurrent - 1);\n\t\tprevType = GetLineType(styler.GetLineState(lineCurrent - 1));\n\t\tif (lineCurrent >= 2) {\n\t\t\tprev2Type = GetLineType(styler.GetLineState(lineCurrent - 2));\n\t\t}\n\t}\n\n\tbool commentHead = (prevType == TOMLLineType::CommentLine) && (prevLevel & SC_FOLDLEVELHEADERFLAG);\n\twhile (lineCurrent <= maxLines) {\n\t\tint nextLevel;\n\t\tconst int lineState = styler.GetLineState(lineCurrent);\n\t\tconst TOMLLineType lineType = GetLineType(lineState);\n\n\t\tif (lineType == TOMLLineType::CommentLine) {\n\t\t\tif (prevLevel & SC_FOLDLEVELHEADERFLAG) {\n\t\t\t\tnextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;\n\t\t\t} else {\n\t\t\t\tnextLevel = prevLevel;\n\t\t\t}\n\t\t\tcommentHead = prevType != TOMLLineType::CommentLine;\n\t\t\tnextLevel |= commentHead ? SC_FOLDLEVELHEADERFLAG : 0;\n\t\t} else {\n\t\t\tif (lineType == TOMLLineType::Table) {\n\t\t\t\tnextLevel = SC_FOLDLEVELBASE + GetTableLevel(lineState);\n\t\t\t\tif ((prevType == TOMLLineType::CommentLine) && prevLevel <= nextLevel) {\n\t\t\t\t\t// comment above nested table\n\t\t\t\t\tcommentHead = true;\n\t\t\t\t\tprevLevel = nextLevel - 1;\n\t\t\t\t} else if ((prevType == TOMLLineType::Table) && (prevLevel & SC_FOLDLEVELNUMBERMASK) >= nextLevel) {\n\t\t\t\t\tcommentHead = true; // empty table\n\t\t\t\t}\n\t\t\t\tnextLevel |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t} else {\n\t\t\t\tif (commentHead) {\n\t\t\t\t\tnextLevel = prevLevel & SC_FOLDLEVELNUMBERMASK;\n\t\t\t\t} else if (prevLevel & SC_FOLDLEVELHEADERFLAG) {\n\t\t\t\t\tnextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;\n\t\t\t\t} else if ((prevType == TOMLLineType::CommentLine) && (prev2Type == TOMLLineType::CommentLine)) {\n\t\t\t\t\tnextLevel = prevLevel - 1;\n\t\t\t\t} else {\n\t\t\t\t\tnextLevel = prevLevel;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (commentHead) {\n\t\t\t\tcommentHead = false;\n\t\t\t\tstyler.SetLevel(lineCurrent - 1, prevLevel & SC_FOLDLEVELNUMBERMASK);\n\t\t\t}\n\t\t}\n\n\t\tstyler.SetLevel(lineCurrent, nextLevel);\n\t\tprevLevel = nextLevel;\n\t\tprev2Type = prevType;\n\t\tprevType = lineType;\n\t\tlineCurrent++;\n\t}\n}\n\n}  // unnamed namespace end\n\nstatic const char *const tomlWordListDesc[] = {\n\t\"Keywords\",\n\t0\n};\n\nextern const LexerModule lmTOML(SCLEX_TOML, ColouriseTOMLDoc, \"toml\", FoldTOMLDoc, tomlWordListDesc);\n"
  },
  {
    "path": "lexers/LexTeX.cxx",
    "content": "// Scintilla source code edit control\n\n// @file LexTeX.cxx - general context conformant tex coloring scheme\n// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com\n// Version: September 28, 2003\n\n// Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// This lexer is derived from the one written for the texwork environment (1999++) which in\n// turn is inspired on texedit (1991++) which finds its roots in wdt (1986).\n\n// If you run into strange boundary cases, just tell me and I'll look into it.\n\n\n// TeX Folding code added by instanton (soft_share@126.com) with borrowed code from VisualTeX source by Alex Romanenko.\n// Version: June 22, 2007\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// val SCE_TEX_DEFAULT = 0\n// val SCE_TEX_SPECIAL = 1\n// val SCE_TEX_GROUP   = 2\n// val SCE_TEX_SYMBOL  = 3\n// val SCE_TEX_COMMAND = 4\n// val SCE_TEX_TEXT    = 5\n\n// Definitions in SciTEGlobal.properties:\n//\n// TeX Highlighting\n//\n// # Default\n// style.tex.0=fore:#7F7F00\n// # Special\n// style.tex.1=fore:#007F7F\n// # Group\n// style.tex.2=fore:#880000\n// # Symbol\n// style.tex.3=fore:#7F7F00\n// # Command\n// style.tex.4=fore:#008800\n// # Text\n// style.tex.5=fore:#000000\n\n// lexer.tex.interface.default=0\n// lexer.tex.comment.process=0\n\n// todo: lexer.tex.auto.if\n\n// Auxiliary functions:\n\nstatic inline bool endOfLine(Accessor &styler, Sci_PositionU i) {\n\treturn\n      (styler[i] == '\\n') || ((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n')) ;\n}\n\nstatic inline bool isTeXzero(int ch) {\n\treturn\n      (ch == '%') ;\n}\n\nstatic inline bool isTeXone(int ch) {\n\treturn\n      (ch == '[') || (ch == ']') || (ch == '=') || (ch == '#') ||\n      (ch == '(') || (ch == ')') || (ch == '<') || (ch == '>') ||\n      (ch == '\"') ;\n}\n\nstatic inline bool isTeXtwo(int ch) {\n\treturn\n      (ch == '{') || (ch == '}') || (ch == '$') ;\n}\n\nstatic inline bool isTeXthree(int ch) {\n\treturn\n      (ch == '~') || (ch == '^') || (ch == '_') || (ch == '&') ||\n      (ch == '-') || (ch == '+') || (ch == '\\\"') || (ch == '`') ||\n      (ch == '/') || (ch == '|') || (ch == '%') ;\n}\n\nstatic inline bool isTeXfour(int ch) {\n\treturn\n      (ch == '\\\\') ;\n}\n\nstatic inline bool isTeXfive(int ch) {\n\treturn\n      ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||\n      (ch == '@') || (ch == '!') || (ch == '?') ;\n}\n\nstatic inline bool isTeXsix(int ch) {\n\treturn\n      (ch == ' ') ;\n}\n\nstatic inline bool isTeXseven(int ch) {\n\treturn\n      (ch == '^') ;\n}\n\n// Interface determination\n\nstatic int CheckTeXInterface(\n    Sci_PositionU startPos,\n    Sci_Position length,\n    Accessor &styler,\n\tint defaultInterface) {\n\n    char lineBuffer[1024] ;\n\tSci_PositionU linePos = 0 ;\n\n    // some day we can make something lexer.tex.mapping=(all,0)(nl,1)(en,2)...\n\n    if (styler.SafeGetCharAt(0) == '%') {\n        for (Sci_PositionU i = 0; i < startPos + length; i++) {\n            lineBuffer[linePos++] = styler.SafeGetCharAt(i) ;\n            if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {\n                lineBuffer[linePos] = '\\0';\n                if (strstr(lineBuffer, \"interface=all\")) {\n                    return 0 ;\n\t\t\t\t} else if (strstr(lineBuffer, \"interface=tex\")) {\n                    return 1 ;\n                } else if (strstr(lineBuffer, \"interface=nl\")) {\n                    return 2 ;\n                } else if (strstr(lineBuffer, \"interface=en\")) {\n                    return 3 ;\n                } else if (strstr(lineBuffer, \"interface=de\")) {\n                    return 4 ;\n                } else if (strstr(lineBuffer, \"interface=cz\")) {\n                    return 5 ;\n                } else if (strstr(lineBuffer, \"interface=it\")) {\n                    return 6 ;\n                } else if (strstr(lineBuffer, \"interface=ro\")) {\n                    return 7 ;\n                } else if (strstr(lineBuffer, \"interface=latex\")) {\n\t\t\t\t\t// we will move latex cum suis up to 91+ when more keyword lists are supported\n                    return 8 ;\n\t\t\t\t} else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, \"%D \\\\module\")) {\n\t\t\t\t\t// better would be to limit the search to just one line\n\t\t\t\t\treturn 3 ;\n                } else {\n                    return defaultInterface ;\n                }\n            }\n\t\t}\n    }\n\n    return defaultInterface ;\n}\n\nstatic void ColouriseTeXDoc(\n    Sci_PositionU startPos,\n    Sci_Position length,\n    int,\n    WordList *keywordlists[],\n    Accessor &styler) {\n\n\tstyler.StartAt(startPos) ;\n\tstyler.StartSegment(startPos) ;\n\n\tbool processComment   = styler.GetPropertyInt(\"lexer.tex.comment.process\",   0) == 1 ;\n\tbool useKeywords      = styler.GetPropertyInt(\"lexer.tex.use.keywords\",      1) == 1 ;\n\tbool autoIf           = styler.GetPropertyInt(\"lexer.tex.auto.if\",           1) == 1 ;\n\tint  defaultInterface = styler.GetPropertyInt(\"lexer.tex.interface.default\", 1) ;\n\n\tchar key[100] ;\n\tint  k ;\n\tbool newifDone = false ;\n\tbool inComment = false ;\n\n\tint currentInterface = CheckTeXInterface(startPos,length,styler,defaultInterface) ;\n\n    if (currentInterface == 0) {\n        useKeywords = false ;\n        currentInterface = 1 ;\n    }\n\n    WordList &keywords = *keywordlists[currentInterface-1] ;\n\n\tStyleContext sc(startPos, length, SCE_TEX_TEXT, styler);\n\n\tbool going = sc.More() ; // needed because of a fuzzy end of file state\n\n\tfor (; going; sc.Forward()) {\n\n\t\tif (! sc.More()) { going = false ; } // we need to go one behind the end of text\n\n\t\tif (inComment) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tsc.SetState(SCE_TEX_TEXT) ;\n\t\t\t\tnewifDone = false ;\n\t\t\t\tinComment = false ;\n\t\t\t}\n\t\t} else {\n\t\t\tif (! isTeXfive(sc.ch)) {\n\t\t\t\tif (sc.state == SCE_TEX_COMMAND) {\n\t\t\t\t\tif (sc.LengthCurrent() == 1) { // \\<noncstoken>\n\t\t\t\t\t\tif (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) {\n\t\t\t\t\t\t\tsc.Forward(2) ; // \\^^ and \\^^<token>\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsc.ForwardSetState(SCE_TEX_TEXT) ;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsc.GetCurrent(key, sizeof(key)-1) ;\n\t\t\t\t\t\tk = static_cast<int>(strlen(key)) ;\n\t\t\t\t\t\tmemmove(key,key+1,k) ; // shift left over escape token\n\t\t\t\t\t\tkey[k] = '\\0' ;\n\t\t\t\t\t\tk-- ;\n\t\t\t\t\t\tif (! keywords || ! useKeywords) {\n\t\t\t\t\t\t\tsc.SetState(SCE_TEX_COMMAND) ;\n\t\t\t\t\t\t\tnewifDone = false ;\n\t\t\t\t\t\t} else if (k == 1) { //\\<cstoken>\n\t\t\t\t\t\t\tsc.SetState(SCE_TEX_COMMAND) ;\n\t\t\t\t\t\t\tnewifDone = false ;\n\t\t\t\t\t\t} else if (keywords.InList(key)) {\n    \t\t\t\t\t\tsc.SetState(SCE_TEX_COMMAND) ;\n\t\t\t\t\t\t\tnewifDone = autoIf && (strcmp(key,\"newif\") == 0) ;\n\t\t\t\t\t\t} else if (autoIf && ! newifDone && (key[0] == 'i') && (key[1] == 'f') && keywords.InList(\"if\")) {\n\t    \t\t\t\t\tsc.SetState(SCE_TEX_COMMAND) ;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsc.ChangeState(SCE_TEX_TEXT) ;\n\t\t\t\t\t\t\tsc.SetState(SCE_TEX_TEXT) ;\n\t\t\t\t\t\t\tnewifDone = false ;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (isTeXzero(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_TEX_SYMBOL);\n\n\t\t\t\t\tif (!endOfLine(styler,sc.currentPos + 1))\n\t\t\t\t\t\tsc.ForwardSetState(SCE_TEX_DEFAULT) ;\n\n\t\t\t\t\tinComment = ! processComment ;\n\t\t\t\t\tnewifDone = false ;\n\t\t\t\t} else if (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) {\n\t\t\t\t\tsc.SetState(SCE_TEX_TEXT) ;\n\t\t\t\t\tsc.ForwardSetState(SCE_TEX_TEXT) ;\n\t\t\t\t} else if (isTeXone(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_TEX_SPECIAL) ;\n\t\t\t\t\tnewifDone = false ;\n\t\t\t\t} else if (isTeXtwo(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_TEX_GROUP) ;\n\t\t\t\t\tnewifDone = false ;\n\t\t\t\t} else if (isTeXthree(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_TEX_SYMBOL) ;\n\t\t\t\t\tnewifDone = false ;\n\t\t\t\t} else if (isTeXfour(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_TEX_COMMAND) ;\n\t\t\t\t} else if (isTeXsix(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_TEX_TEXT) ;\n\t\t\t\t} else if (sc.atLineEnd) {\n\t\t\t\t\tsc.SetState(SCE_TEX_TEXT) ;\n\t\t\t\t\tnewifDone = false ;\n\t\t\t\t\tinComment = false ;\n\t\t\t\t} else {\n\t\t\t\t\tsc.SetState(SCE_TEX_TEXT) ;\n\t\t\t\t}\n\t\t\t} else if (sc.state != SCE_TEX_COMMAND) {\n\t\t\t\tsc.SetState(SCE_TEX_TEXT) ;\n\t\t\t}\n\t\t}\n\t}\n\tsc.ChangeState(SCE_TEX_TEXT) ;\n\tsc.Complete();\n\n}\n\n\nstatic inline bool isNumber(int ch) {\n\treturn\n      (ch == '0') || (ch == '1') || (ch == '2') ||\n      (ch == '3') || (ch == '4') || (ch == '5') ||\n      (ch == '6') || (ch == '7') || (ch == '8') || (ch == '9');\n}\n\nstatic inline bool isWordChar(int ch) {\n\treturn ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'));\n}\n\nstatic Sci_Position ParseTeXCommand(Sci_PositionU pos, Accessor &styler, char *command)\n{\n  Sci_Position length=0;\n  char ch=styler.SafeGetCharAt(pos+1);\n\n  if(ch==',' || ch==':' || ch==';' || ch=='%'){\n      command[0]=ch;\n      command[1]=0;\n\t  return 1;\n  }\n\n  // find end\n     while(isWordChar(ch) && !isNumber(ch) && ch!='_' && ch!='.' && length<100){\n          command[length]=ch;\n          length++;\n          ch=styler.SafeGetCharAt(pos+length+1);\n     }\n\n  command[length]='\\0';\n  if(!length) return 0;\n  return length+1;\n}\n\nstatic int classifyFoldPointTeXPaired(const char* s) {\n\tint lev=0;\n\tif (!(isdigit(s[0]) || (s[0] == '.'))){\n\t\tif (strcmp(s, \"begin\")==0||strcmp(s,\"FoldStart\")==0||\n\t\t\tstrcmp(s,\"abstract\")==0||strcmp(s,\"unprotect\")==0||\n\t\t\tstrcmp(s,\"title\")==0||strncmp(s,\"start\",5)==0||strncmp(s,\"Start\",5)==0||\n\t\t\tstrcmp(s,\"documentclass\")==0||strncmp(s,\"if\",2)==0\n\t\t\t)\n\t\t\tlev=1;\n\t\tif (strcmp(s, \"end\")==0||strcmp(s,\"FoldStop\")==0||\n\t\t\tstrcmp(s,\"maketitle\")==0||strcmp(s,\"protect\")==0||\n\t\t\tstrncmp(s,\"stop\",4)==0||strncmp(s,\"Stop\",4)==0||\n\t\t\tstrcmp(s,\"fi\")==0\n\t\t\t)\n\t\tlev=-1;\n\t}\n\treturn lev;\n}\n\nstatic int classifyFoldPointTeXUnpaired(const char* s) {\n\tint lev=0;\n\tif (!(isdigit(s[0]) || (s[0] == '.'))){\n\t\tif (strcmp(s,\"part\")==0||\n\t\t\tstrcmp(s,\"chapter\")==0||\n\t\t\tstrcmp(s,\"section\")==0||\n\t\t\tstrcmp(s,\"subsection\")==0||\n\t\t\tstrcmp(s,\"subsubsection\")==0||\n\t\t\tstrcmp(s,\"CJKfamily\")==0||\n\t\t\tstrcmp(s,\"appendix\")==0||\n\t\t\tstrcmp(s,\"Topic\")==0||strcmp(s,\"topic\")==0||\n\t\t\tstrcmp(s,\"subject\")==0||strcmp(s,\"subsubject\")==0||\n\t\t\tstrcmp(s,\"def\")==0||strcmp(s,\"gdef\")==0||strcmp(s,\"edef\")==0||\n\t\t\tstrcmp(s,\"xdef\")==0||strcmp(s,\"framed\")==0||\n\t\t\tstrcmp(s,\"frame\")==0||\n\t\t\tstrcmp(s,\"foilhead\")==0||strcmp(s,\"overlays\")==0||strcmp(s,\"slide\")==0\n\t\t\t){\n\t\t\t    lev=1;\n\t\t\t}\n\t}\n\treturn lev;\n}\n\nstatic bool IsTeXCommentLine(Sci_Position line, Accessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\n\tSci_Position startpos = pos;\n\n\twhile (startpos<eol_pos){\n\t\tchar ch = styler[startpos];\n\t\tif (ch!='%' && ch!=' ') return false;\n\t\telse if (ch=='%') return true;\n\t\tstartpos++;\n\t}\n\n\treturn false;\n}\n\n// FoldTeXDoc: borrowed from VisualTeX with modifications\n\nstatic void FoldTexDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)\n{\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tSci_PositionU endPos = startPos+length;\n\tint visibleChars=0;\n\tSci_Position lineCurrent=styler.GetLine(startPos);\n\tint levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent=levelPrev;\n\tchar chNext=styler[startPos];\n\tchar buffer[100]=\"\";\n\n\tfor (Sci_PositionU i=startPos; i < endPos; i++) {\n\t\tchar ch=chNext;\n\t\tchNext=styler.SafeGetCharAt(i+1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n        if(ch=='\\\\') {\n            ParseTeXCommand(i, styler, buffer);\n\t\t\tlevelCurrent += classifyFoldPointTeXPaired(buffer)+classifyFoldPointTeXUnpaired(buffer);\n\t\t}\n\n\t\tif (levelCurrent > SC_FOLDLEVELBASE && ((ch == '\\r' || ch=='\\n') && (chNext == '\\\\'))) {\n            ParseTeXCommand(i+1, styler, buffer);\n\t\t\tlevelCurrent -= classifyFoldPointTeXUnpaired(buffer);\n\t\t}\n\n\tchar chNext2;\n\tchar chNext3;\n\tchar chNext4;\n\tchar chNext5;\n\tchNext2=styler.SafeGetCharAt(i+2);\n\tchNext3=styler.SafeGetCharAt(i+3);\n\tchNext4=styler.SafeGetCharAt(i+4);\n\tchNext5=styler.SafeGetCharAt(i+5);\n\n\tbool atEOfold = (ch == '%') &&\n\t\t\t(chNext == '%') && (chNext2=='}') &&\n\t\t\t\t(chNext3=='}')&& (chNext4=='-')&& (chNext5=='-');\n\n\tbool atBOfold = (ch == '%') &&\n\t\t\t(chNext == '%') && (chNext2=='-') &&\n\t\t\t\t(chNext3=='-')&& (chNext4=='{')&& (chNext5=='{');\n\n\tif(atBOfold){\n\t\tlevelCurrent+=1;\n\t}\n\n\tif(atEOfold){\n\t\tlevelCurrent-=1;\n\t}\n\n\tif(ch=='\\\\' && chNext=='['){\n\t\tlevelCurrent+=1;\n\t}\n\n\tif(ch=='\\\\' && chNext==']'){\n\t\tlevelCurrent-=1;\n\t}\n\n\tbool foldComment = styler.GetPropertyInt(\"fold.comment\") != 0;\n\n\tif (foldComment && atEOL && IsTeXCommentLine(lineCurrent, styler))\n        {\n            if (lineCurrent==0 && IsTeXCommentLine(lineCurrent + 1, styler)\n\t\t\t\t)\n                levelCurrent++;\n            else if (lineCurrent!=0 && !IsTeXCommentLine(lineCurrent - 1, styler)\n               && IsTeXCommentLine(lineCurrent + 1, styler)\n\t\t\t\t)\n                levelCurrent++;\n            else if (lineCurrent!=0 && IsTeXCommentLine(lineCurrent - 1, styler) &&\n                     !IsTeXCommentLine(lineCurrent+1, styler))\n                levelCurrent--;\n        }\n\n//---------------------------------------------------------------------------------------------\n\n\t\tif (atEOL) {\n\t\t\tint lev = levelPrev;\n\t\t\tif (visibleChars == 0 && foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif ((levelCurrent > levelPrev) && (visibleChars > 0))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelPrev = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\n\n\n\nstatic const char * const texWordListDesc[] = {\n    \"TeX, eTeX, pdfTeX, Omega\",\n    \"ConTeXt Dutch\",\n    \"ConTeXt English\",\n    \"ConTeXt German\",\n    \"ConTeXt Czech\",\n    \"ConTeXt Italian\",\n    \"ConTeXt Romanian\",\n\t0,\n} ;\n\nextern const LexerModule lmTeX(SCLEX_TEX,   ColouriseTeXDoc, \"tex\", FoldTexDoc, texWordListDesc);\n"
  },
  {
    "path": "lexers/LexTroff.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexTroff.cxx\n ** Lexer for the Troff typesetting language.\n ** This should work for Groff, Heirloom Troff and Neatroff and consequently\n ** for man pages.\n **\n ** There are a number of restrictions:\n ** Escapes are not interpreted everywhere e.g. as part of command names.\n ** For the same reasons, changing control characters via `.cc` or `.c2` will\n ** not affect lexing - subsequent requests will not be styled correctly.\n ** Luckily this feature is rarely used.\n ** Line feeds cannot be escaped everywhere - this would require a state machine\n ** for all parsing.\n ** However, the C lexer has the same restriction.\n ** It is impossible to predict which macro argument is a numeric expression or where\n ** the number is actually treated as text.\n ** Also, escapes with levels of indirection (eg. `\\\\$1`) cannot currently\n ** be highlighted, as it is impossible to predict the context in which an\n ** expansion will be used.\n ** Indirect blocks (.ami, .ami1, .dei and .dei1) cannot be folded.\n ** No effort is done to highlight any of the preprocessors (tbl, pic, grap...).\n **/\n// Copyright 2022-2024 by Robin Haberkorn <robin.haberkorn@googlemail.com>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <algorithm>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n// Can be used as the line state to detect continuations\n// across calls to ColouriseTroffDoc().\nenum TroffState {\n\tDEFAULT = 0,\n\t// REQUEST/COMMAND on a line means that it is a command line with continuation.\n\tREQUEST,\n\tCOMMAND,\n\t// Flow control request with continuation\n\tFLOW_CONTROL,\n\t// Inside \"ignore input\" block (usually .ig)\n\tIGNORE\n};\n\nstatic Sci_PositionU TroffEscapeBracketSize(Sci_PositionU startLine, Sci_PositionU endPos,\n                                            Accessor &styler);\nstatic Sci_PositionU TroffEscapeQuoteSize(Sci_PositionU startLine, Sci_PositionU endPos,\n                                            Accessor &styler);\n\nstatic Sci_PositionU ColouriseTroffEscape(Sci_PositionU startLine, Sci_PositionU endPos,\n                                          Accessor &styler, WordList *keywordlists[],\n                                          TroffState state);\nstatic void ColouriseTroffLine(Sci_PositionU startLine, Sci_PositionU endPos,\n                               Accessor &styler, WordList *keywordlists[],\n                               TroffState state);\n\n// For all escapes that take a one character (\\*x), two character (\\*(xy) or\n// arbitrary number of characters (\\*[...]).\nstatic Sci_PositionU TroffEscapeBracketSize(Sci_PositionU startLine, Sci_PositionU endPos,\n                                            Accessor &styler) {\n\tif (startLine > endPos) {\n\t\treturn 0;\n\t}\n\n\tif (styler[startLine] == '(') {\n\t\t// two character name\n\t\treturn std::min((Sci_PositionU)3, endPos-startLine+1);\n\t}\n\n\tif (styler[startLine] != '[') {\n\t\t// one character name\n\t\treturn 1;\n\t}\n\t// name with arbitrary size between [...]\n\n\tSci_PositionU i = startLine+1;\n\n\twhile (i <= endPos) {\n\t\tif (styler[i] == ']') {\n\t\t\treturn i-startLine+1;\n\t\t}\n\n\t\tif (styler[i] != '\\\\') {\n\t\t\t// not an escape\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (++i > endPos) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// NOTE: Other escapes are not interpreted within \\x[...].\n\t\tswitch (styler[i]) {\n\t\tcase '*': // string register\n\t\tcase '$': // macro argument\n\t\tcase 'V': // environment variable\n\t\tcase 'n': // numeric register\n\t\t\ti += 1;\n\t\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\t\tbreak;\n\t\tcase 'A': // Is there a string with this name?\n\t\tcase 'B': // Is there a register with this name?\n\t\tcase 'R': // register increase\n\t\t\ti += 1;\n\t\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\t}\n\t}\n\n\treturn endPos-startLine+1;\n}\n\n// For all escapes that take an argument in quotes, as in \\v'...'.\n// Actually, this works with any character as a delimiter.\nstatic Sci_PositionU TroffEscapeQuoteSize(Sci_PositionU startLine, Sci_PositionU endPos,\n                                          Accessor &styler) {\n\tif (startLine > endPos) {\n\t\treturn 0;\n\t}\n\n\tchar delim = styler[startLine];\n\n\tSci_PositionU i = startLine+1;\n\n\twhile (i <= endPos) {\n\t\tif (styler[i] == delim) {\n\t\t\treturn i-startLine+1;\n\t\t}\n\n\t\tif (styler[i] != '\\\\') {\n\t\t\t// not an escape\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (++i > endPos) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// NOTE: Other escapes are not interpreted within \\x'...'.\n\t\tswitch (styler[i]) {\n\t\tcase '*': // string register\n\t\tcase '$': // macro argument\n\t\tcase 'V': // environment variable\n\t\tcase 'n': // numeric register\n\t\t\ti += 1;\n\t\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\t\tbreak;\n\t\tcase 'A': // Is there a string with this name?\n\t\tcase 'B': // Is there a register with this name?\n\t\tcase 'R': // register increase\n\t\t\ti += 1;\n\t\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\t}\n\t}\n\t\n\treturn endPos-startLine+1;\n}\n\nstatic Sci_PositionU ColouriseTroffEscape(Sci_PositionU startLine, Sci_PositionU endPos,\n                                          Accessor &styler, WordList *keywordlists[],\n                                          TroffState state) {\n\tSci_PositionU i = startLine;\n\n\tSci_Position curLine = styler.GetLine(startLine);\n\n\tif (styler[i] != '\\\\') {\n\t\t// not an escape - still consume one character\n\t\treturn 1;\n\t}\n\tstyler.ColourTo(i-1, SCE_TROFF_DEFAULT);\n\ti++;\n\tif (i > endPos) {\n\t\treturn i-startLine;\n\t}\n\n\tswitch (styler[i]) {\n\tcase '\"':\n\t\t// ordinary end of line comment\n\t\tstyler.ColourTo(endPos, SCE_TROFF_COMMENT);\n\t\treturn endPos-startLine+1;\n\n\tcase '#':\n\t\t// \\# comments will also \"swallow\" the EOL characters similar to\n\t\t// an escape at the end of line.\n\t\t// They are usually used only to comment entire lines, but we support\n\t\t// them after command lines anyway.\n\t\tstyler.ColourTo(endPos, SCE_TROFF_COMMENT);\n\t\t// Next line will be a continuation\n\t\tstyler.SetLineState(curLine, state);\n\t\treturn endPos-startLine+1;\n\n\tcase '*':\n\t\t// String register\n\t\ti += 1;\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_STRING);\n\t\tbreak;\n\tcase '$':\n\t\t// Macro parameter\n\t\ti += 1;\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_MACRO);\n\t\tbreak;\n\tcase 'V':\n\t\t// Environment variable\n\t\ti += 1;\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_ENV);\n\t\tbreak;\n\tcase 'f':\n\tcase 'F':\n\t\t// Font change\n\t\ti += 1;\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_FONT);\n\t\tbreak;\n\tcase 'n':\n\t\t// Number register\n\t\ti += 1;\n\t\tif (styler[i] == '+' || styler[i] == '-') {\n\t\t\ti += 1;\n\t\t}\n\t\tif (i > endPos) {\n\t\t\tbreak;\n\t\t}\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_NUMBER);\n\t\tbreak;\n\tcase 'g':\n\tcase 'k':\n\t\ti += 1;\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_NUMBER);\n\t\tbreak;\n\tcase 'R':\n\t\t// Number register increase\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_NUMBER);\n\t\tbreak;\n\tcase 'm':\n\tcase 'M':\n\t\t// Colour change\n\t\ti += 1;\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_COLOUR);\n\t\tbreak;\n\tcase 'O':\n\t\t// Nested suppressions\n\t\ti += 1;\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_SUPPRESSION);\n\t\tbreak;\n\tcase 's':\n\t\t// Type size\n\t\t// This is special in supporting both a +/- prefix directly\n\t\t// after \\s and both the [...] and '...' syntax.\n\t\ti += 1;\n\t\tif (i > endPos) {\n\t\t\tbreak;\n\t\t}\n\t\tif (styler[i] == '+' || styler[i] == '-') {\n\t\t\ti += 1;\n\t\t}\n\t\tif (styler[i] == '\\'') {\n\t\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\t} else if (styler[i] == '(') {\n\t\t\t// You can place a +/- even after the opening brace as in \\s(+12.\n\t\t\t// Otherwise this could be handled by TroffEscapeBracketSize().\n\t\t\ti += 1;\n\t\t\tif (i > endPos) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (styler[i] == '+' || styler[i] == '-') {\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t\ti += std::min((Sci_PositionU)2, endPos-i);\n\t\t} else {\n\t\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\t}\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_SIZE);\n\t\tbreak;\n\tcase '{':\n\t\t// Opening code block\n\t\ti += 1;\n\t\tstyler.ColourTo(i-1, SCE_TROFF_OPERATOR);\n\t\t// Groff actually supports commands immediately\n\t\t// following the opening brace as in `\\{.tm`.\n\t\t// That's only why \\{\\ will actually treat the next line\n\t\t// as an ordinary command again.\n\t\tColouriseTroffLine(i, endPos, styler, keywordlists, state);\n\t\treturn endPos-startLine+1;\n\tcase '}':\n\t\t// Closing code block\n\t\t// This exists only for the rare case of closing a\n\t\t// block in the middle of a line. \n\t\ti += 1;\n\t\tstyler.ColourTo(i-1, SCE_TROFF_OPERATOR);\n\t\tbreak;\n\tcase '\\n':\n\tcase '\\r':\n\t\t// Escape newline\n\t\tstyler.ColourTo(endPos, SCE_TROFF_ESCAPE_GLYPH);\n\t\ti += 1;\n\t\t// Next line will be a continuation\n\t\tstyler.SetLineState(curLine, state);\n\t\tbreak;\n\tcase '!':\n\t\t// transparent line\n\t\tstyler.ColourTo(endPos, SCE_TROFF_ESCAPE_TRANSPARENT);\n\t\treturn endPos-startLine+1;\n\tcase '?':\n\t\t// Transparent embed until \\?\n\t\ti++;\n\t\twhile (i <= endPos) {\n\t\t\tif (styler.Match(i, \"\\\\?\")) {\n\t\t\t\ti += 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ti++;\n\t\t}\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_TRANSPARENT);\n\t\tbreak;\n\tcase 'b':\n\t\t// pile of chars\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_GLYPH);\n\t\tbreak;\n\tcase 'A':\n\tcase 'B':\n\t\t// Valid identifier or register?\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_ISVALID);\n\t\tbreak;\n\tcase 'C':\n\tcase 'N':\n\t\t// additional glyphs\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_GLYPH);\n\t\tbreak;\n\tcase 'D':\n\tcase 'l':\n\tcase 'L':\n\t\t// drawing commands\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_DRAW);\n\t\tbreak;\n\tcase 'h':\n\tcase 'v':\n\t\t// horizontal/vertical movement\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_MOVE);\n\t\tbreak;\n\tcase 'H':\n\t\t// font height\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_HEIGHT);\n\t\tbreak;\n\tcase 'o':\n\t\t// overstrike\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_OVERSTRIKE);\n\t\tbreak;\n\tcase 'S':\n\t\t// slant\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_SLANT);\n\t\tbreak;\n\tcase 'w':\n\t\t// width of string\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_WIDTH);\n\t\tbreak;\n\tcase 'x':\n\t\t// increase vertical spacing\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_VSPACING);\n\t\tbreak;\n\tcase 'X':\n\t\t// device control commands\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_DEVICE);\n\t\tbreak;\n\tcase 'Y':\n\t\t// device control commands\n\t\ti += 1;\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_DEVICE);\n\t\tbreak;\n\tcase 'Z':\n\t\t// format string without moving\n\t\ti += 1;\n\t\ti += TroffEscapeQuoteSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_NOMOVE);\n\t\tbreak;\n\tcase 'z':\n\t\t// Zero-width format\n\t\ti += std::min((Sci_PositionU)2, endPos-i);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_NOMOVE);\n\t\tbreak;\n\tdefault:\n\t\ti += TroffEscapeBracketSize(i, endPos, styler);\n\t\tstyler.ColourTo(i-1, SCE_TROFF_ESCAPE_GLYPH);\n\t}\n\n\treturn i-startLine;\n}\n\nstatic Sci_PositionU ColouriseTroffNumber(Sci_PositionU startLine, Sci_PositionU endPos,\n                                          Accessor &styler) {\n\tSci_PositionU i = startLine;\n\n\tif (!isdigit(styler[i])) {\n\t\t// not a digit\n\t\treturn 0;\n\t}\n\n\tstyler.ColourTo(i-1, SCE_TROFF_DEFAULT);\n\n\ti++;\n\twhile (i <= endPos && isdigit(styler[i])) {\n\t\ti++;\n\t}\n\tif (i > endPos) {\n\t\tgoto done;\n\t}\n\tif (styler[i] == '.') {\n\t\ti++;\n\t\twhile (i <= endPos && isdigit(styler[i])) {\n\t\t\ti++;\n\t\t}\n\t\tif (i > endPos) {\n\t\t\tgoto done;\n\t\t}\n\t}\n\n\t// Unit is part of number\n\tif (strchr(\"ciPpmMnuvsf\", styler[i])) {\n\t\ti++;\n\t}\n\ndone:\n\tstyler.ColourTo(i-1, SCE_TROFF_NUMBER);\n\treturn i-startLine;\n}\n\nstatic void ColouriseTroffLine(Sci_PositionU startLine, Sci_PositionU endPos,\n                               Accessor &styler, WordList *keywordlists[],\n                               TroffState state) {\n\tWordList &requests = *keywordlists[0];\n\tWordList &flowControlCond = *keywordlists[1];\n\tWordList &flowControlNocond = *keywordlists[2];\n\tWordList &ignoreBlocks = *keywordlists[3];\n\tSci_PositionU i = startLine;\n\n\tif (startLine > endPos) {\n\t\treturn;\n\t}\n\n\tSci_Position curLine = styler.GetLine(startLine);\n\t// If the line state was not DEFAULT (i.e. the line had a continuation)\n\t// and the corresponding escape is erased, we must make sure that\n\t// the line state becomes DEFAULT again.\n\tstyler.SetLineState(curLine, TroffState::DEFAULT);\n\n\tif (state == TroffState::IGNORE) {\n\t\t// Inside \"ignore input\" blocks\n\t\tif (styler[i] == '.') {\n\t\t\ti++;\n\t\t\t// Groff does not appear to allow spaces after the dot on\n\t\t\t// lines ending ignore blocks.\n#if 0\n\t\t\twhile (i <= endPos && isspacechar(styler[i])) {\n\t\t\t\ti++;\n\t\t\t}\n#endif\n\n\t\t\tSci_PositionU startCommand = i;\n\t\t\twhile (i <= endPos && !isspacechar(styler[i])) {\n\t\t\t\ti++;\n\t\t\t}\n\n\t\t\t// Check whether this is the end of the block by backtracking.\n\t\t\t// The alternative would be to maintain a per-lexer data structure\n\t\t\t// of ignore blocks along with their \"end-mac\" parameters.\n\t\t\tif (i > startCommand) {\n\t\t\t\tstd::string endmac = styler.GetRange(startCommand, i);\n\t\t\t\tif (endmac == \".\") {\n\t\t\t\t\tendmac.clear();\n\t\t\t\t}\n\t\t\t\t// We styled right up to the \"end-mac\" argument or EOL.\n\t\t\t\tSci_PositionU startEndmac = startLine;\n\t\t\t\tint style;\n\t\t\t\twhile ((style = styler.BufferStyleAt(startEndmac-1)) != SCE_TROFF_REQUEST &&\n\t\t\t\t       style != SCE_TROFF_COMMAND) {\n\t\t\t\t\tstartEndmac--;\n\t\t\t\t}\n\t\t\t\tSci_PositionU endEndmac = startEndmac;\n\t\t\t\twhile (!isspacechar(styler.SafeGetCharAt(endEndmac))) {\n\t\t\t\t\tendEndmac++;\n\t\t\t\t}\n\n\t\t\t\tstd::string buf = endEndmac > startEndmac ?\n\t\t\t\t\t\t\tstyler.GetRange(startEndmac, endEndmac) : \"\";\n\t\t\t\tif (buf == endmac) {\n\t\t\t\t\t// Found the end of the ignore block.\n\t\t\t\t\t// This line can be an ordinary request or macro,\n\t\t\t\t\t// so we completely restyle it.\n\t\t\t\t\tstate = TroffState::DEFAULT;\n\t\t\t\t\tColouriseTroffLine(startLine, endPos, styler, keywordlists, state);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstyler.ColourTo(endPos, SCE_TROFF_IGNORE);\n\t\tstyler.SetLineState(curLine, TroffState::IGNORE);\n\t\treturn;\n\t}\n\n\tif (state == TroffState::FLOW_CONTROL) {\n\t\t// Allow leading spaces only in continuations of flow control requests.\n\t\twhile (i <= endPos && isspacechar(styler[i])) {\n\t\t\ti++;\n\t\t}\n\t}\n\n\t// NOTE: The control characters can theoretically be changed via `.cc` and `.c2`.\n\t// This is seldom done and in principle it makes Roff unparseable since there is\n\t// no way to determine whether one of those commands has been executed without\n\t// executing the entire code which may run forever (halting problem).\n\t// So not supporting alternate control characters is simply a necessary restriction of this lexer.\n\tif ((state == TroffState::DEFAULT || state == TroffState::FLOW_CONTROL) &&\n\t    (styler[i] == '.' || styler[i] == '\\'')) {\n\t\t// Control line\n\t\t// TODO: It may make sense to highlight the non-breaking control character (') in\n\t\t// a separate style.\n\t\ti++;\n\n\t\twhile (i <= endPos && isspacechar(styler[i])) {\n\t\t\ti++;\n\t\t}\n\t\tSci_PositionU startCommand = i;\n\t\twhile (i <= endPos && !isspacechar(styler[i])) {\n\t\t\ti++;\n\t\t\t// FIXME: Highlight escapes in this position?\n\t\t}\n\n\t\tif (startCommand == i) {\n\t\t\t// lone dot without anything following\n\t\t\tstyler.ColourTo(endPos, SCE_TROFF_REQUEST);\n\t\t\treturn;\n\t\t}\n\n\t\tstd::string buf = styler.GetRange(startCommand, i);\n\n\t\tif (buf == \"\\\\\\\"\") {\n\t\t\t// Handling .\\\" separately makes sure that the entire line including\n\t\t\t// the leading dot is highlighted as a comment\n\t\t\tstyler.ColourTo(endPos, SCE_TROFF_COMMENT);\n\t\t\treturn;\n\t\t}\n\n\t\tif (buf == \"\\\\}\") {\n\t\t\t// Handling .\\} separately makes sure it is styled like\n\t\t\t// the opening \\{ braces.\n\t\t\tstyler.ColourTo(endPos, SCE_TROFF_OPERATOR);\n\t\t\treturn;\n\t\t}\n\n\t\t// Ignore blocks\n\t\tif (ignoreBlocks.InList(buf)) {\n\t\t\t// It's important to style right up to the optional end-mac argument,\n\t\t\t// since we use the SCE_TROFF_REQUEST/COMMAND style to check for block ends (see above).\n\t\t\twhile (i <= endPos && isspacechar(styler[i]) &&\n\t\t\t       styler[i] != '\\n' && styler[i] != '\\r') {\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tstyler.ColourTo(i-1, requests.InList(buf) ? SCE_TROFF_REQUEST : SCE_TROFF_COMMAND);\n\t\t\tstyler.ColourTo(endPos, SCE_TROFF_DEFAULT);\n\t\t\t// Next line will be an ignore block\n\t\t\tstyler.SetLineState(curLine, TroffState::IGNORE);\n\t\t\treturn;\n\t\t}\n\n\t\t// Flow control without conditionals\n\t\tif (flowControlNocond.InList(buf)) {\n\t\t\tstyler.ColourTo(i-1, requests.InList(buf) ? SCE_TROFF_REQUEST : SCE_TROFF_COMMAND);\n\n\t\t\tstate = TroffState::FLOW_CONTROL;\n\t\t\tstyler.ColourTo(i-1, SCE_TROFF_DEFAULT);\n\t\t\tColouriseTroffLine(i, endPos, styler, keywordlists, state);\n\t\t\treturn;\n\t\t}\n\n\t\t// It is tempting to treat flow control requests like ordinary requests,\n\t\t// but you cannot really predict the beginning of the next command.\n\t\t// Eg. .if 'FOO'.tm' .tm BAR\n\t\t// We therefore have to parse at least the apostrophe expressions\n\t\t// and keep track of escapes.\n\t\tif (flowControlCond.InList(buf)) {\n\t\t\tstyler.ColourTo(i-1, requests.InList(buf) ? SCE_TROFF_REQUEST : SCE_TROFF_COMMAND);\n\n\t\t\twhile (i <= endPos && isspacechar(styler[i])) {\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tif (i > endPos) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (styler[i] == '!') {\n\t\t\t\ti++;\n\t\t\t\tstyler.ColourTo(i-1, SCE_TROFF_OPERATOR);\n\t\t\t}\n\t\t\tif (i > endPos) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (styler[i] == '\\'') {\n\t\t\t\t// string comparison: 's1's2'\n\t\t\t\t// FIXME: Should be highlighted?\n\t\t\t\t// However, none of the conditionals are currently highlighted.\n\t\t\t\ti++;\n\t\t\t\twhile (i <= endPos && styler[i] != '\\'') {\n\t\t\t\t\ti += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);\n\t\t\t\t}\n\t\t\t\tif (i > endPos) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t\twhile (i <= endPos && styler[i] != '\\'') {\n\t\t\t\t\ti += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);\n\t\t\t\t}\n\t\t\t\tif (i > endPos) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t} else {\n\t\t\t\t// Everything else - including numeric expressions -\n\t\t\t\t// can contain spaces only in escapes and inside balanced round braces.\n\t\t\t\tint braceLevel = 0;\n\t\t\t\twhile (i <= endPos && (braceLevel > 0 || !isspacechar(styler[i]))) {\n\t\t\t\t\tSci_PositionU numLen;\n\n\t\t\t\t\tswitch (styler[i]) {\n\t\t\t\t\tcase '(':\n\t\t\t\t\t\tbraceLevel++;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ')':\n\t\t\t\t\t\tbraceLevel--;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tnumLen = ColouriseTroffNumber(i, endPos, styler);\n\t\t\t\t\t\ti += numLen;\n\t\t\t\t\t\tif (numLen > 0) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ti += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstate = TroffState::FLOW_CONTROL;\n\t\t\tstyler.ColourTo(i-1, SCE_TROFF_DEFAULT);\n\t\t\tColouriseTroffLine(i, endPos, styler, keywordlists, state);\n\t\t\treturn;\n\t\t}\n\n\t\t// remaining non-flow-control requests and commands\n\t\tstate = requests.InList(buf) ? TroffState::REQUEST : TroffState::COMMAND;\n\t\tstyler.ColourTo(i-1, state == TroffState::REQUEST\n\t\t\t\t\t? SCE_TROFF_REQUEST : SCE_TROFF_COMMAND);\n\t}\n\n\t// Text line, request/command parameters including continuations\n\twhile (i <= endPos) {\n\t\tif (state == TroffState::COMMAND && styler[i] == '\"') {\n\t\t\t// Macro or misc command line arguments - assume that double-quoted strings\n\t\t\t// actually denote arguments.\n\t\t\t// FIXME: Allow escape linebreaks on the end of strings?\n\t\t\t// This would require another TroffState.\n\t\t\tstyler.ColourTo(i-1, SCE_TROFF_DEFAULT);\n\n\t\t\ti++;\n\t\t\twhile (i <= endPos && styler[i] != '\"') {\n\t\t\t\tstyler.ColourTo(i-1, SCE_TROFF_STRING);\n\t\t\t\ti += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);\n\t\t\t}\n\t\t\tif (styler[i] == '\"') {\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tstyler.ColourTo(i-1, SCE_TROFF_STRING);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (state == TroffState::COMMAND || state == TroffState::REQUEST) {\n\t\t\t// Numbers are supposed to be highlighted on every command line.\n\t\t\t// FIXME: Not all requests actually treat numbers specially.\n\t\t\t// Theoretically, we have to parse on a per-request basis.\n\t\t\tSci_PositionU numLen;\n\t\t\tnumLen = ColouriseTroffNumber(i, endPos, styler);\n\t\t\ti += numLen;\n\t\t\tif (numLen > 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\ti += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);\n\t}\n\n\tstyler.ColourTo(endPos, SCE_TROFF_DEFAULT);\n}\n\nstatic void ColouriseTroffDoc(Sci_PositionU startPos, Sci_Position length, int,\n                              WordList *keywordlists[], Accessor &styler) {\n\tstyler.StartAt(startPos);\n\tSci_PositionU startLine = startPos;\n\tSci_Position curLine = styler.GetLine(startLine);\n\n\tstyler.StartSegment(startLine);\n\n\t// NOTE: startPos will always be at the beginning of a line\n\tfor (Sci_PositionU i = startPos; i < startPos + length; i++) {\n\t\t// NOTE: The CR in CRLF counts into the current line.\n\t\tbool atEOL = (styler[i] == '\\r' && styler.SafeGetCharAt(i+1) != '\\n') || styler[i] == '\\n';\n\n\t\tif (atEOL || i == startPos + length - 1) {\n\t\t\t// If the previous line had a continuation, the current line\n\t\t\t// is parsed like an argument to the command that had that continuation.\n\t\t\tTroffState state = curLine > 0 ? (TroffState)styler.GetLineState(curLine-1)\n\t\t\t                               : TroffState::DEFAULT;\n\n\t\t\t// End of line (or of line buffer) met, colourise it\n\t\t\tColouriseTroffLine(startLine, i, styler, keywordlists, state);\n\t\t\tstartLine = i + 1;\n\t\t\tcurLine++;\n\t\t}\n\t}\n}\n\nstatic void FoldTroffDoc(Sci_PositionU startPos, Sci_Position length, int,\n                         WordList *keywordlists[], Accessor &styler) {\n\tWordList &endmacBlocks = *keywordlists[4];\n\n\tSci_PositionU endPos = startPos + length;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;\n\tint levelCurrent = levelPrev;\n\tchar chNext = styler[startPos];\n\tbool foldCompact = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n\tint styleNext = styler.StyleAt(startPos);\n\tstd::string requestName;\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styleNext;\n\t\tstyleNext = styler.StyleAt(i + 1);\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || ch == '\\n';\n\n\t\tif (style == SCE_TROFF_OPERATOR && ch == '\\\\') {\n\t\t\tif (chNext == '{') {\n\t\t\t\tlevelCurrent++;\n\t\t\t} else if (chNext == '}') {\n\t\t\t\tlevelCurrent--;\n\t\t\t}\n\t\t} else if (style != SCE_TROFF_IGNORE && styleNext == SCE_TROFF_IGNORE) {\n\t\t\t// Beginning of ignore block\n\t\t\tlevelCurrent++;\n\t\t} else if (style == SCE_TROFF_IGNORE && styleNext != SCE_TROFF_IGNORE) {\n\t\t\t// End of ignore block\n\t\t\t// The end-mac line will not be folded, which is probably okay\n\t\t\t// since it could start the next ignore block or could be any command that is\n\t\t\t// executed.\n\t\t\t// This is not handled by the endmac block handling below\n\t\t\t// since the `.ig` syntax is different.\n\t\t\t// FIXME: Fold at least `..` lines.\n\t\t\tlevelCurrent--;\n\t\t} else if ((style == SCE_TROFF_REQUEST || style == SCE_TROFF_COMMAND) &&\n\t\t           !isspacechar(ch)) {\n\t\t\trequestName.push_back(ch);\n\t\t}\n\n\t\tif (!atEOL) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tint lev = levelPrev;\n\n\t\tif (requestName.length() > 1) {\n\t\t\tif (endmacBlocks.InList(requestName.substr(1))) {\n\t\t\t\t// beginning of block\n\t\t\t\tlevelCurrent++;\n\t\t\t} else {\n\t\t\t\t// potential end of block\n\t\t\t\t// This parsing could be avoided if we kept a list\n\t\t\t\t// line numbers and end-mac strings.\n\t\t\t\t// The parsing here could also be simplified if\n\t\t\t\t// we highlighted the end-mac strings in ColouriseTroffLine().\n\t\t\t\tstd::string endmac = requestName.substr(1);\n\t\t\t\tif (endmac == \".\") {\n\t\t\t\t\tendmac.clear();\n\t\t\t\t}\n\n\t\t\t\t// find start of block\n\t\t\t\tSci_Position startLine = lineCurrent;\n\t\t\t\twhile (startLine > 0 && styler.LevelAt(startLine-1) >= levelCurrent) {\n\t\t\t\t\tstartLine--;\n\t\t\t\t}\n\t\t\t\tif (startLine) {\n\t\t\t\t\tSci_Position startEndmac = styler.LineStart(startLine);\n\t\t\t\t\tint reqStyle;\n\t\t\t\t\t// skip the request/command name\n\t\t\t\t\twhile ((reqStyle = styler.StyleAt(startEndmac)) == SCE_TROFF_REQUEST ||\n\t\t\t\t\t       reqStyle == SCE_TROFF_COMMAND) {\n\t\t\t\t\t\tstartEndmac++;\n\t\t\t\t\t}\n\t\t\t\t\twhile (isspacechar(styler.SafeGetCharAt(startEndmac))) {\n\t\t\t\t\t\tstartEndmac++;\n\t\t\t\t\t}\n\t\t\t\t\t// skip the macro name\n\t\t\t\t\twhile (!isspacechar(styler.SafeGetCharAt(startEndmac))) {\n\t\t\t\t\t\tstartEndmac++;\n\t\t\t\t\t}\n\t\t\t\t\twhile (isspacechar(styler.SafeGetCharAt(startEndmac)) &&\n\t\t\t\t\t       styler[startEndmac] != '\\n' && styler[startEndmac] != '\\r') {\n\t\t\t\t\t\tstartEndmac++;\n\t\t\t\t\t}\n\t\t\t\t\tSci_Position endEndmac = startEndmac;\n\t\t\t\t\twhile (!isspacechar(styler.SafeGetCharAt(endEndmac))) {\n\t\t\t\t\t\tendEndmac++;\n\t\t\t\t\t}\n\t\t\t\t\tstd::string buf = endEndmac > startEndmac ?\n\t\t\t\t\t\t\t\tstyler.GetRange(startEndmac, endEndmac) : \"\";\n\t\t\t\t\tif (buf == endmac) {\n\t\t\t\t\t\t// FIXME: Better fold the previous line unless it is `..`.\n\t\t\t\t\t\tlevelCurrent--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (foldCompact && requestName == \".\") {\n\t\t\t// lone dot ona line has no effect\n\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t}\n\t\tif (levelCurrent > levelPrev) {\n\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t}\n\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t}\n\t\tlineCurrent++;\n\t\tlevelPrev = levelCurrent;\n\t\trequestName.clear();\n\t}\n\n\t// Fill in the real level of the next line, keeping the current flags as they will be filled in later\n\tint flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\n\tstyler.SetLevel(lineCurrent, levelPrev | flagsNext);\n}\n\nstatic const char * const troffWordLists[] = {\n            \"Predefined requests\",\n            \"Flow control requests/commands with conditionals\",\n            \"Flow control requests/commands without conditionals\",\n            \"Requests and commands, initiating ignore blocks\",\n            \"Requests and commands with end-macros\",\n            NULL,\n        };\n\nextern const LexerModule lmTroff(SCLEX_TROFF, ColouriseTroffDoc, \"troff\", FoldTroffDoc, troffWordLists);\n"
  },
  {
    "path": "lexers/LexTxt2tags.cxx",
    "content": "/******************************************************************\n *  LexTxt2tags.cxx\n *\n *  A simple Txt2tags lexer for scintilla.\n *\n *\n *  Adapted by Eric Forgeot\n *  Based on the LexMarkdown.cxx by Jon Strait - jstrait@moonloop.net\n *\n *  What could be improved:\n *   - Verbatim lines could be like for raw lines : when there is no space between the ``` and the following text, the first letter should be colored so the user would understand there must be a space for a valid tag.\n *   - marks such as bold, italic, strikeout, underline should begin to be highlighted only when they are closed and valid.\n *   - verbatim and raw area should be highlighted too.\n *\n *  The License.txt file describes the conditions under which this\n *  software may be distributed.\n *\n *****************************************************************/\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\n\n\nstatic inline bool IsNewline(const int ch) {\n    return (ch == '\\n' || ch == '\\r');\n}\n\n// True if can follow ch down to the end with possibly trailing whitespace\nstatic bool FollowToLineEnd(const int ch, const int state, const Sci_PositionU endPos, StyleContext &sc) {\n    Sci_PositionU i = 0;\n    while (sc.GetRelative(++i) == ch)\n        ;\n    // Skip over whitespace\n    while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)\n        ++i;\n    if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {\n        sc.Forward(i);\n        sc.ChangeState(state);\n        sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n        return true;\n    }\n    else return false;\n}\n\n// Does the previous line have more than spaces and tabs?\nstatic bool HasPrevLineContent(StyleContext &sc) {\n    Sci_Position i = 0;\n    // Go back to the previous newline\n    while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i)))\n        ;\n    while (--i + sc.currentPos) {\n        if (IsNewline(sc.GetRelative(i)))\n            break;\n        if (!IsASpaceOrTab(sc.GetRelative(i)))\n            return true;\n    }\n    return false;\n}\n\n// Separator line\nstatic bool IsValidHrule(const Sci_PositionU endPos, StyleContext &sc) {\n    int count = 1;\n    Sci_PositionU i = 0;\n    for (;;) {\n        ++i;\n        int c = sc.GetRelative(i);\n        if (c == sc.ch)\n            ++count;\n        // hit a terminating character\n        else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {\n            // Are we a valid HRULE\n            if ((IsNewline(c) || sc.currentPos + i == endPos) &&\n                    count >= 20 && !HasPrevLineContent(sc)) {\n                sc.SetState(SCE_TXT2TAGS_HRULE);\n                sc.Forward(i);\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n                return true;\n            }\n            else {\n                sc.SetState(SCE_TXT2TAGS_DEFAULT);\n\t\treturn false;\n            }\n        }\n    }\n}\n\nstatic void ColorizeTxt2tagsDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,\n                               WordList **, Accessor &styler) {\n    Sci_PositionU endPos = startPos + length;\n    int precharCount = 0;\n    // Don't advance on a new loop iteration and retry at the same position.\n    // Useful in the corner case of having to start at the beginning file position\n    // in the default state.\n    bool freezeCursor = false;\n\n    StyleContext sc(startPos, length, initStyle, styler);\n\n    while (sc.More()) {\n        // Skip past escaped characters\n        if (sc.ch == '\\\\') {\n            sc.Forward();\n            continue;\n        }\n\n        // A blockquotes resets the line semantics\n        if (sc.state == SCE_TXT2TAGS_BLOCKQUOTE){\n            sc.Forward(2);\n            sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n        }\n        // An option colors the whole line\n        if (sc.state == SCE_TXT2TAGS_OPTION){\n            FollowToLineEnd('%', SCE_TXT2TAGS_OPTION, endPos, sc);\n        }\n        if (sc.state == SCE_TXT2TAGS_POSTPROC){\n            FollowToLineEnd('%', SCE_TXT2TAGS_POSTPROC, endPos, sc);\n        }\n        if (sc.state == SCE_TXT2TAGS_PREPROC){\n            FollowToLineEnd('%', SCE_TXT2TAGS_PREPROC, endPos, sc);\n        }\n        // A comment colors the whole line\n        if (sc.state == SCE_TXT2TAGS_COMMENT){\n            FollowToLineEnd('%', SCE_TXT2TAGS_COMMENT, endPos, sc);\n        }\n        // Conditional state-based actions\n        if (sc.state == SCE_TXT2TAGS_CODE2) {\n        if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n            if (sc.Match(\"``\") && sc.GetRelative(-2) != ' ') {\n                sc.Forward(2);\n                sc.SetState(SCE_TXT2TAGS_DEFAULT);\n            }\n        }\n        // Table\n        else if (sc.state == SCE_TXT2TAGS_CODE) {\n        if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n            if (sc.ch == '|' && sc.chPrev != ' ')\n                sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);\n        }\n        // Strong\n        else if (sc.state == SCE_TXT2TAGS_STRONG1) {\n        if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n            if (sc.Match(\"**\") && sc.chPrev != ' ') {\n                sc.Forward(2);\n                sc.SetState(SCE_TXT2TAGS_DEFAULT);\n            }\n        }\n        // Emphasis\n        else if (sc.state == SCE_TXT2TAGS_EM1) {\n        if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n            if (sc.Match(\"//\") && sc.chPrev != ' ') {\n                sc.Forward(2);\n                sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);\n           }\n        }\n        // Underline\n        else if (sc.state == SCE_TXT2TAGS_EM2) {\n        if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n            if (sc.Match(\"__\") && sc.chPrev != ' ') {\n                sc.Forward(2);\n                sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);\n           }\n        }\n        // codeblock\n        else if (sc.state == SCE_TXT2TAGS_CODEBK) {\n                if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n            if (sc.atLineStart && sc.Match(\"```\")) {\n                Sci_Position i = 1;\n                while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)\n                    i++;\n                sc.Forward(i);\n                sc.SetState(SCE_TXT2TAGS_DEFAULT);\n            }\n        }\n        // strikeout\n        else if (sc.state == SCE_TXT2TAGS_STRIKEOUT) {\n        if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n            if (sc.Match(\"--\") && sc.chPrev != ' ') {\n                sc.Forward(2);\n                sc.SetState(SCE_TXT2TAGS_DEFAULT);\n            }\n        }\n        // Headers\n        else if (sc.state == SCE_TXT2TAGS_LINE_BEGIN) {\n            if (sc.Match(\"======\"))\n                {\n                sc.SetState(SCE_TXT2TAGS_HEADER6);\n                sc.Forward();\n                }\n            else if (sc.Match(\"=====\"))\n                {\n                sc.SetState(SCE_TXT2TAGS_HEADER5);\n                sc.Forward();\n                }\n            else if (sc.Match(\"====\"))\n                {\n                sc.SetState(SCE_TXT2TAGS_HEADER4);\n                sc.Forward();\n                }\n            else if (sc.Match(\"===\"))\n                {\n                sc.SetState(SCE_TXT2TAGS_HEADER3);\n                sc.Forward();\n                }\n                //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '=', sc);\n            else if (sc.Match(\"==\")) {\n                sc.SetState(SCE_TXT2TAGS_HEADER2);\n                sc.Forward();\n                }\n                //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '=', sc);\n            else if (sc.Match(\"=\")) {\n                // Catch the special case of an unordered list\n                if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {\n                    precharCount = 0;\n                    sc.SetState(SCE_TXT2TAGS_PRECHAR);\n                }\n                else\n                    {\n                    sc.SetState(SCE_TXT2TAGS_HEADER1);\n                    sc.Forward();\n                    }\n                    //SetStateAndZoom(SCE_TXT2TAGS_HEADER1, 1, '=', sc);\n            }\n\n            // Numbered title\n            else if (sc.Match(\"++++++\"))\n                {\n                sc.SetState(SCE_TXT2TAGS_HEADER6);\n                sc.Forward();\n                }\n            else if (sc.Match(\"+++++\"))\n                {\n                sc.SetState(SCE_TXT2TAGS_HEADER5);\n                sc.Forward();\n                }\n            else if (sc.Match(\"++++\"))\n                {\n                sc.SetState(SCE_TXT2TAGS_HEADER4);\n                sc.Forward();\n                }\n            else if (sc.Match(\"+++\"))\n                {\n                sc.SetState(SCE_TXT2TAGS_HEADER3);\n                sc.Forward();\n                }\n                //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '+', sc);\n            else if (sc.Match(\"++\")) {\n                sc.SetState(SCE_TXT2TAGS_HEADER2);\n                sc.Forward();\n                }\n                //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '+', sc);\n            else if (sc.Match(\"+\")) {\n                // Catch the special case of an unordered list\n                if (sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(1))) {\n                 //    if (IsNewline(sc.ch)) {\n                     \t//precharCount = 0;\n                //\t\tsc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n                \t\t//sc.SetState(SCE_TXT2TAGS_PRECHAR);\n\t\t\t\t//\t}\n                //    else {\n                //    precharCount = 0;\n                    sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);\n                    sc.Forward(2);\n                    sc.SetState(SCE_TXT2TAGS_DEFAULT);\n               //     sc.SetState(SCE_TXT2TAGS_PRECHAR);\n\t\t\t\t//\t}\n                }\n                else\n                    {\n                    sc.SetState(SCE_TXT2TAGS_HEADER1);\n                    sc.Forward();\n                    }\n            }\n\n\n            // Codeblock\n            else if (sc.Match(\"```\")) {\n                if (!HasPrevLineContent(sc))\n              //  if (!FollowToLineEnd(sc))\n                    sc.SetState(SCE_TXT2TAGS_CODEBK);\n                else\n                    sc.SetState(SCE_TXT2TAGS_DEFAULT);\n            }\n\n            // Preproc\n            else if (sc.Match(\"%!preproc\")) {\n                sc.SetState(SCE_TXT2TAGS_PREPROC);\n            }\n            // Postproc\n            else if (sc.Match(\"%!postproc\")) {\n                sc.SetState(SCE_TXT2TAGS_POSTPROC);\n            }\n            // Option\n            else if (sc.Match(\"%!\")) {\n                sc.SetState(SCE_TXT2TAGS_OPTION);\n            }\n\n             // Comment\n            else if (sc.ch == '%') {\n                sc.SetState(SCE_TXT2TAGS_COMMENT);\n            }\n            // list\n            else if (sc.ch == '-') {\n                    precharCount = 0;\n                    sc.SetState(SCE_TXT2TAGS_PRECHAR);\n            }\n            // def list\n            else if (sc.ch == ':') {\n                    precharCount = 0;\n                   sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);\n                   sc.Forward(1);\n                   sc.SetState(SCE_TXT2TAGS_PRECHAR);\n            }\n            else if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n            else {\n                precharCount = 0;\n                sc.SetState(SCE_TXT2TAGS_PRECHAR);\n            }\n        }\n\n        // The header lasts until the newline\n        else if (sc.state == SCE_TXT2TAGS_HEADER1 || sc.state == SCE_TXT2TAGS_HEADER2 ||\n                sc.state == SCE_TXT2TAGS_HEADER3 || sc.state == SCE_TXT2TAGS_HEADER4 ||\n                sc.state == SCE_TXT2TAGS_HEADER5 || sc.state == SCE_TXT2TAGS_HEADER6) {\n            if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n        }\n\n        // New state only within the initial whitespace\n        if (sc.state == SCE_TXT2TAGS_PRECHAR) {\n            // Blockquote\n            if (sc.Match(\"\\\"\\\"\\\"\") && precharCount < 5){\n\n                sc.SetState(SCE_TXT2TAGS_BLOCKQUOTE);\n                sc.Forward(1);\n                }\n            /*\n            // Begin of code block\n            else if (!HasPrevLineContent(sc) && (sc.chPrev == '\\t' || precharCount >= 4))\n                sc.SetState(SCE_TXT2TAGS_CODEBK);\n            */\n            // HRule - Total of 20 or more hyphens, asterisks, or underscores\n            // on a line by themselves\n            else if ((sc.ch == '-' ) && IsValidHrule(endPos, sc))\n                ;\n            // Unordered list\n            else if ((sc.ch == '-') && IsASpaceOrTab(sc.chNext)) {\n                sc.SetState(SCE_TXT2TAGS_ULIST_ITEM);\n                sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);\n            }\n            // Ordered list\n            else if (IsADigit(sc.ch)) {\n                Sci_Position digitCount = 0;\n                while (IsADigit(sc.GetRelative(++digitCount)))\n                    ;\n                if (sc.GetRelative(digitCount) == '.' &&\n                        IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {\n                    sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);\n                    sc.Forward(digitCount + 1);\n                    sc.SetState(SCE_TXT2TAGS_DEFAULT);\n                }\n            }\n            // Alternate Ordered list\n            else if (sc.ch == '+' && sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(2))) {\n            //    sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);\n            //    sc.Forward(2);\n             //   sc.SetState(SCE_TXT2TAGS_DEFAULT);\n            }\n            else if (sc.ch != ' ' || precharCount > 2)\n                sc.SetState(SCE_TXT2TAGS_DEFAULT);\n            else\n                ++precharCount;\n        }\n\n        // New state anywhere in doc\n        if (sc.state == SCE_TXT2TAGS_DEFAULT) {\n         //   if (sc.atLineStart && sc.ch == '#') {\n         //       sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n         //       freezeCursor = true;\n         //   }\n            // Links and Images\n            if (sc.Match(\"![\") || sc.ch == '[') {\n                Sci_Position i = 0, j = 0, k = 0;\n                Sci_Position len = endPos - sc.currentPos;\n                while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\\\'))\n                    ;\n                if (sc.GetRelative(i) == ']') {\n                    j = i;\n                    if (sc.GetRelative(++i) == '(') {\n                        while (i < len && (sc.GetRelative(++i) != '(' || sc.GetRelative(i - 1) == '\\\\'))\n                            ;\n                        if (sc.GetRelative(i) == '(')\n                            k = i;\n                    }\n\n                    else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') {\n                        while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\\\'))\n                            ;\n                        if (sc.GetRelative(i) == ']')\n                            k = i;\n                    }\n                }\n                // At least a link text\n                if (j) {\n                    sc.SetState(SCE_TXT2TAGS_LINK);\n                    sc.Forward(j);\n                    // Also has a URL or reference portion\n                    if (k)\n                        sc.Forward(k - j);\n                    sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);\n                }\n            }\n            // Code - also a special case for alternate inside spacing\n            if (sc.Match(\"``\") && sc.GetRelative(3) != ' ') {\n                sc.SetState(SCE_TXT2TAGS_CODE2);\n                sc.Forward();\n            }\n            else if (sc.ch == '|' && sc.GetRelative(3) != ' ') {\n                sc.SetState(SCE_TXT2TAGS_CODE);\n            }\n            // Strong\n            else if (sc.Match(\"**\") && sc.GetRelative(2) != ' ') {\n                sc.SetState(SCE_TXT2TAGS_STRONG1);\n                sc.Forward();\n           }\n            // Emphasis\n            else if (sc.Match(\"//\") && sc.GetRelative(2) != ' ') {\n                sc.SetState(SCE_TXT2TAGS_EM1);\n                sc.Forward();\n            }\n            else if (sc.Match(\"__\") && sc.GetRelative(2) != ' ') {\n                sc.SetState(SCE_TXT2TAGS_EM2);\n                sc.Forward();\n            }\n            // Strikeout\n            else if (sc.Match(\"--\") && sc.GetRelative(2) != ' ') {\n                sc.SetState(SCE_TXT2TAGS_STRIKEOUT);\n                sc.Forward();\n            }\n\n            // Beginning of line\n            else if (IsNewline(sc.ch))\n                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);\n        }\n        // Advance if not holding back the cursor for this iteration.\n        if (!freezeCursor)\n            sc.Forward();\n        freezeCursor = false;\n    }\n    sc.Complete();\n}\n\nextern const LexerModule lmTxt2tags(SCLEX_TXT2TAGS, ColorizeTxt2tagsDoc, \"txt2tags\");\n\n\n"
  },
  {
    "path": "lexers/LexVB.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexVB.cxx\n ** Lexer for Visual Basic and VBScript.\n **/\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <map>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\n// Internal state, highlighted as number\nconstexpr int SCE_B_FILENUMBER = SCE_B_DEFAULT + 100;\n\nbool IsVBComment(Accessor &styler, Sci_Position pos, Sci_Position len) {\n\treturn len > 0 && styler[pos] == '\\'';\n}\n\nconstexpr bool IsTypeCharacter(int ch) noexcept {\n\treturn ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';\n}\n\n// Extended to accept accented characters\nconstexpr bool IsAWordChar(int ch) noexcept {\n\treturn !IsASCII(ch) ||\n\t       (IsAlphaNumeric(ch) || ch == '.' || ch == '_');\n}\n\nconstexpr bool IsAWordStart(int ch) noexcept {\n\treturn !IsASCII(ch) ||\n\t       (IsUpperOrLowerCase(ch) || ch == '_');\n}\n\nconstexpr bool IsANumberChar(int ch) noexcept {\n\t// Not exactly following number definition (several dots are seen as OK, etc.)\n\t// but probably enough in most cases.\n\treturn IsAHeXDigit(ch) || AnyOf(ch, '.', '-', '+', '_');\n}\n\n// Options used for LexerVB\nstruct OptionsVB {\n\tbool fold = false;\n\tbool allowMultilineStr = false;\n};\n\nconst char * const vbWordListDesc[] = {\n\t\"Keywords\",\n\t\"user1\",\n\t\"user2\",\n\t\"user3\",\n\tnullptr\n};\n\nstruct OptionSetVB : public OptionSet<OptionsVB> {\n\tOptionSetVB() {\n\t\tDefineProperty(\"fold\", &OptionsVB::fold);\n\n\t\tDefineProperty(\"lexer.vb.strings.multiline\", &OptionsVB::allowMultilineStr,\n\t\t\t\"Set to 1 to allow strings to continue over line ends.\");\n\n\t\tDefineWordListSets(vbWordListDesc);\n\t}\n};\n\nLexicalClass lexicalClasses[] = {\n\t// Lexer vb SCLEX_VB SCE_B_:\n\t0, \"SCE_B_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_B_COMMENT\", \"comment\", \"Comment: '\",\n\t2, \"SCE_B_NUMBER\", \"literal numeric\", \"Number\",\n\t3, \"SCE_B_KEYWORD\", \"keyword\", \"Keyword\",\n\t4, \"SCE_B_STRING\", \"literal string\", \"Double quoted string\",\n\t5, \"SCE_B_PREPROCESSOR\", \"preprocessor\", \"Preprocessor\",\n\t6, \"SCE_B_OPERATOR\", \"operator\", \"Operators\",\n\t7, \"SCE_B_IDENTIFIER\", \"identifier\", \"Identifiers\",\n\t8, \"SCE_B_DATE\", \"literal date\", \"Date\",\n\t9, \"SCE_B_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n\t10, \"SCE_B_KEYWORD2\", \"identifier\", \"Keywords2\",\n\t11, \"SCE_B_KEYWORD3\", \"identifier\", \"Keywords3\",\n\t12, \"SCE_B_KEYWORD4\", \"identifier\", \"Keywords4\",\n};\n\nclass LexerVB : public DefaultLexer {\n\tbool vbScriptSyntax;\n\tWordList keywords;\n\tWordList keywords2;\n\tWordList keywords3;\n\tWordList keywords4;\n\tOptionsVB options;\n\tOptionSetVB osVB;\npublic:\n\tLexerVB(const char *languageName_, int language_, bool vbScriptSyntax_) :\n\t\tDefaultLexer(languageName_, language_, lexicalClasses, std::size(lexicalClasses)),\n\t\tvbScriptSyntax(vbScriptSyntax_) {\n\t}\n\t// Deleted so LexerVB objects can not be copied.\n\tLexerVB(const LexerVB &) = delete;\n\tLexerVB(LexerVB &&) = delete;\n\tvoid operator=(const LexerVB &) = delete;\n\tvoid operator=(LexerVB &&) = delete;\n\t~LexerVB() override = default;\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osVB.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osVB.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osVB.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osVB.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osVB.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n\tvoid CheckIdentifier(Lexilla::StyleContext &sc);\n\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn nullptr;\n\t}\n\tstatic ILexer5 *LexerFactoryVB() {\n\t\treturn new LexerVB(\"vb\", SCLEX_VB, false);\n\t}\n\tstatic ILexer5 *LexerFactoryVBScript() {\n\t\treturn new LexerVB(\"vbscript\", SCLEX_VBSCRIPT, true);\n\t}\n};\n\nSci_Position SCI_METHOD LexerVB::PropertySet(const char *key, const char *val) {\n\tif (osVB.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerVB::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywords2;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywords3;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywords4;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN && wordListN->Set(wl, true)) {\n\t\tfirstModification = 0;\n\t}\n\treturn firstModification;\n}\n\nvoid LexerVB::CheckIdentifier(StyleContext &sc) {\n\t// In Basic (except VBScript), a variable name or a function name\n\t// can end with a special character indicating the type of the value\n\t// held or returned.\n\tbool skipType = false;\n\tif (!vbScriptSyntax && IsTypeCharacter(sc.ch)) {\n\t\tsc.Forward();\t// Skip it\n\t\tskipType = true;\n\t}\n\tif (sc.ch == ']') {\n\t\tsc.Forward();\n\t}\n\tchar s[100];\n\tsc.GetCurrentLowered(s, sizeof(s));\n\tif (skipType) {\n\t\ts[strlen(s) - 1] = '\\0';\n\t}\n\tif (strcmp(s, \"rem\") == 0) {\n\t\tsc.ChangeState(SCE_B_COMMENT);\n\t} else {\n\t\tif (keywords.InList(s)) {\n\t\t\tsc.ChangeState(SCE_B_KEYWORD);\n\t\t} else if (keywords2.InList(s)) {\n\t\t\tsc.ChangeState(SCE_B_KEYWORD2);\n\t\t} else if (keywords3.InList(s)) {\n\t\t\tsc.ChangeState(SCE_B_KEYWORD3);\n\t\t} else if (keywords4.InList(s)) {\n\t\t\tsc.ChangeState(SCE_B_KEYWORD4);\n\t\t}\t// Else, it is really an identifier...\n\t\tsc.SetState(SCE_B_DEFAULT);\n\t}\n}\n\nvoid LexerVB::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\n\tstyler.StartAt(startPos);\n\n\tint visibleChars = 0;\n\tint fileNbDigits = 0;\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) {\n\t\tinitStyle = SCE_B_DEFAULT;\n\t}\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\n\tfor (; sc.More(); sc.Forward()) {\n\n\t\tif (sc.state == SCE_B_OPERATOR) {\n\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t} else if (sc.state == SCE_B_IDENTIFIER) {\n\t\t\tif (!IsAWordChar(sc.ch)) {\n\t\t\t\tCheckIdentifier(sc);\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_NUMBER) {\n\t\t\t// We stop the number definition on non-numerical non-dot non-eE non-sign char\n\t\t\t// Also accepts A-F for hex. numbers\n\t\t\tif (!IsANumberChar(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_STRING) {\n\t\t\t// VB doubles quotes to preserve them, so just end this string\n\t\t\t// state now as a following quote will start again\n\t\t\tif (sc.ch == '\\\"') {\n\t\t\t\tif (sc.chNext == '\\\"') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} else {\n\t\t\t\t\tif (MakeLowerCase(sc.chNext) == 'c') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t\t}\n\t\t\t} else if (sc.atLineEnd && !options.allowMultilineStr) {\n\t\t\t\tvisibleChars = 0;\n\t\t\t\tsc.ChangeState(SCE_B_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_COMMENT) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tvisibleChars = 0;\n\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_PREPROCESSOR) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tvisibleChars = 0;\n\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_FILENUMBER) {\n\t\t\tif (IsADigit(sc.ch)) {\n\t\t\t\tfileNbDigits++;\n\t\t\t\tif (fileNbDigits > 3) {\n\t\t\t\t\tsc.ChangeState(SCE_B_DATE);\n\t\t\t\t}\n\t\t\t} else if (sc.ch == '\\r' || sc.ch == '\\n' || sc.ch == ',') {\n\t\t\t\t// Regular uses: Close #1; Put #1, ...; Get #1, ... etc.\n\t\t\t\t// Too bad if date is format #27, Oct, 2003# or something like that...\n\t\t\t\t// Use regular number state\n\t\t\t\tsc.ChangeState(SCE_B_NUMBER);\n\t\t\t\tsc.SetState(SCE_B_DEFAULT);\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.ChangeState(SCE_B_DATE);\n\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t} else {\n\t\t\t\tsc.ChangeState(SCE_B_DATE);\n\t\t\t}\n\t\t\tif (sc.state != SCE_B_FILENUMBER) {\n\t\t\t\tfileNbDigits = 0;\n\t\t\t}\n\t\t} else if (sc.state == SCE_B_DATE) {\n\t\t\tif (sc.atLineEnd) {\n\t\t\t\tvisibleChars = 0;\n\t\t\t\tsc.ChangeState(SCE_B_STRINGEOL);\n\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\tsc.ForwardSetState(SCE_B_DEFAULT);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.state == SCE_B_DEFAULT) {\n\t\t\tif (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_B_COMMENT);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_B_STRING);\n\t\t\t} else if (sc.ch == '#' && visibleChars == 0) {\n\t\t\t\t// Preprocessor commands are alone on their line\n\t\t\t\tsc.SetState(SCE_B_PREPROCESSOR);\n\t\t\t} else if (sc.ch == '#') {\n\t\t\t\t// It can be a date literal, ending with #, or a file number, from 1 to 511\n\t\t\t\t// The date literal depends on the locale, so anything can go between #'s.\n\t\t\t\t// Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc.\n\t\t\t\t// So we set the FILENUMBER state, and switch to DATE if it isn't a file number\n\t\t\t\tsc.SetState(SCE_B_FILENUMBER);\n\t\t\t} else if (sc.ch == '&' && MakeLowerCase(sc.chNext) == 'h') {\n\t\t\t\t// Hexadecimal number\n\t\t\t\tsc.SetState(SCE_B_NUMBER);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '&' && MakeLowerCase(sc.chNext) == 'o') {\n\t\t\t\t// Octal number\n\t\t\t\tsc.SetState(SCE_B_NUMBER);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (sc.ch == '&' && MakeLowerCase(sc.chNext) == 'b') {\n\t\t\t\t// Binary number\n\t\t\t\tsc.SetState(SCE_B_NUMBER);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\tsc.SetState(SCE_B_NUMBER);\n\t\t\t} else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {\n\t\t\t\tsc.SetState(SCE_B_IDENTIFIER);\n\t\t\t} else if (isoperator(sc.ch) || (sc.ch == '\\\\')) {\t// Integer division\n\t\t\t\tsc.SetState(SCE_B_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.atLineEnd) {\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!IsASpace(sc.ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t}\n\n\tif (sc.state == SCE_B_IDENTIFIER && !IsAWordChar(sc.ch)) {\n\t\tCheckIdentifier(sc);\n\t}\n\n\tsc.Complete();\n}\n\nvoid LexerVB::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) {\n\tif (!options.fold)\n\t\treturn;\n\n\tAccessor styler(pAccess, nullptr);\n\tconst Sci_Position endPos = startPos + length;\n\n\t// Backtrack to previous line in case need to fix its fold status\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tif (startPos > 0) {\n\t\tif (lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\tstartPos = styler.LineStart(lineCurrent);\n\t\t}\n\t}\n\tint spaceFlags = 0;\n\tint indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsVBComment);\n\tchar chNext = styler[startPos];\n\tfor (Sci_Position i = startPos; i < endPos; i++) {\n\t\tconst char ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\n\t\tif ((ch == '\\r' && chNext != '\\n') || (ch == '\\n') || (i == endPos)) {\n\t\t\tint lev = indentCurrent;\n\t\t\tconst int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsVBComment);\n\t\t\tif (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {\n\t\t\t\t// Only non whitespace lines can be headers\n\t\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {\n\t\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {\n\t\t\t\t\t// Line after is blank so check the next - maybe should continue further?\n\t\t\t\t\tint spaceFlags2 = 0;\n\t\t\t\t\tconst int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsVBComment);\n\t\t\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {\n\t\t\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tindentCurrent = indentNext;\n\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\tlineCurrent++;\n\t\t}\n\t}\n}\n\n}\n\nextern const LexerModule lmVB(SCLEX_VB, LexerVB::LexerFactoryVB, \"vb\", vbWordListDesc);\nextern const LexerModule lmVBScript(SCLEX_VBSCRIPT, LexerVB::LexerFactoryVBScript, \"vbscript\", vbWordListDesc);\n"
  },
  {
    "path": "lexers/LexVHDL.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexVHDL.cxx\n ** Lexer for VHDL\n ** Written by Phil Reid,\n ** Based on:\n **  - The Verilog Lexer by Avi Yegudin\n **  - The Fortran Lexer by Chuan-jian Shen\n **  - The C++ lexer by Neil Hodgson\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nstatic void ColouriseVHDLDoc(\n  Sci_PositionU startPos,\n  Sci_Position length,\n  int initStyle,\n  WordList *keywordlists[],\n  Accessor &styler);\n\n\n/***************************************/\nstatic inline bool IsAWordChar(const int ch) {\n  return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' );\n}\n\n/***************************************/\nstatic inline bool IsAWordStart(const int ch) {\n  return (ch < 0x80) && (isalnum(ch) || ch == '_');\n}\n\n/***************************************/\nstatic inline bool IsABlank(unsigned int ch) {\n  return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;\n}\n\n/***************************************/\nstatic void ColouriseVHDLDoc(\n  Sci_PositionU startPos,\n  Sci_Position length,\n  int initStyle,\n  WordList *keywordlists[],\n  Accessor &styler)\n{\n  WordList &Keywords   = *keywordlists[0];\n  WordList &Operators  = *keywordlists[1];\n  WordList &Attributes = *keywordlists[2];\n  WordList &Functions  = *keywordlists[3];\n  WordList &Packages   = *keywordlists[4];\n  WordList &Types      = *keywordlists[5];\n  WordList &User       = *keywordlists[6];\n\n  StyleContext sc(startPos, length, initStyle, styler);\n  bool isExtendedId = false;    // true when parsing an extended identifier\n\n  while (sc.More())\n  {\n    bool advance = true;\n\n    // Determine if the current state should terminate.\n    if (sc.state == SCE_VHDL_OPERATOR) {\n      sc.SetState(SCE_VHDL_DEFAULT);\n    } else if (sc.state == SCE_VHDL_NUMBER) {\n      if (!IsAWordChar(sc.ch) && (sc.ch != '#')) {\n        sc.SetState(SCE_VHDL_DEFAULT);\n      }\n    } else if (sc.state == SCE_VHDL_IDENTIFIER) {\n      if (!isExtendedId && (!IsAWordChar(sc.ch) || (sc.ch == '.'))) {\n        char s[100];\n        sc.GetCurrentLowered(s, sizeof(s));\n        if (Keywords.InList(s)) {\n          sc.ChangeState(SCE_VHDL_KEYWORD);\n        } else if (Operators.InList(s)) {\n          sc.ChangeState(SCE_VHDL_STDOPERATOR);\n        } else if (Attributes.InList(s)) {\n          sc.ChangeState(SCE_VHDL_ATTRIBUTE);\n        } else if (Functions.InList(s)) {\n          sc.ChangeState(SCE_VHDL_STDFUNCTION);\n        } else if (Packages.InList(s)) {\n          sc.ChangeState(SCE_VHDL_STDPACKAGE);\n        } else if (Types.InList(s)) {\n          sc.ChangeState(SCE_VHDL_STDTYPE);\n        } else if (User.InList(s)) {\n          sc.ChangeState(SCE_VHDL_USERWORD);\n        }\n        sc.SetState(SCE_VHDL_DEFAULT);\n      } else if (isExtendedId && ((sc.ch == '\\\\') || sc.atLineEnd)) {\n        // extended identifiers are terminated by backslash, check for end of line in case we have invalid syntax\n        isExtendedId = false;\n        sc.ForwardSetState(SCE_VHDL_DEFAULT);\n        advance = false;\n      }\n    } else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_VHDL_COMMENTLINEBANG) {\n      if (sc.atLineEnd) {\n        sc.SetState(SCE_VHDL_DEFAULT);\n      }\n    } else if (sc.state == SCE_VHDL_STRING) {\n      if (sc.ch == '\"') {\n        advance = false;\n        sc.Forward();\n        if (sc.ch == '\"')\n          sc.Forward();\n        else\n          sc.SetState(SCE_VHDL_DEFAULT);\n      } else if (sc.atLineEnd) {\n        advance = false;\n        sc.ChangeState(SCE_VHDL_STRINGEOL);\n        sc.ForwardSetState(SCE_VHDL_DEFAULT);\n      }\n    } else if (sc.state == SCE_VHDL_BLOCK_COMMENT){\n      if(sc.ch == '*' && sc.chNext == '/'){\n        advance = false;\n        sc.Forward();\n        sc.ForwardSetState(SCE_VHDL_DEFAULT);\n      }\n    }\n\n    // Determine if a new state should be entered.\n    if (sc.state == SCE_VHDL_DEFAULT) {\n      if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\n        sc.SetState(SCE_VHDL_NUMBER);\n      } else if (IsAWordStart(sc.ch)) {\n        sc.SetState(SCE_VHDL_IDENTIFIER);\n      } else if (sc.Match('-', '-')) {\n        if (sc.Match(\"--!\"))  // Nice to have a different comment style\n          sc.SetState(SCE_VHDL_COMMENTLINEBANG);\n        else\n          sc.SetState(SCE_VHDL_COMMENT);\n      } else if (sc.Match('/', '*')){\n        sc.SetState(SCE_VHDL_BLOCK_COMMENT);\n      } else if (sc.ch == '\"') {\n        sc.SetState(SCE_VHDL_STRING);\n      } else if (sc.ch == '\\'') {\n        if (sc.GetRelative(2) == '\\''){\n          if (sc.chNext != '(' || sc.GetRelative(4) != '\\''){\n            // Can only be a character literal\n            sc.SetState(SCE_VHDL_STRING);\n            sc.Forward();\n            sc.Forward();\n            sc.ForwardSetState(SCE_VHDL_DEFAULT);\n            advance = false;\n          } // else can be a tick or a character literal, need more context, eg.: identifier'('x')\n        } // else can only be a tick\n      } else if (sc.ch == '\\\\') {\n        isExtendedId = true;\n        sc.SetState(SCE_VHDL_IDENTIFIER);\n      } else if (isoperator(static_cast<char>(sc.ch))) {\n        sc.SetState(SCE_VHDL_OPERATOR);\n      }\n    }\n\n    if (advance)\n      sc.Forward();\n  }\n  sc.Complete();\n}\n//=============================================================================\nstatic bool IsCommentLine(Sci_Position line, Accessor &styler) {\n  Sci_Position pos = styler.LineStart(line);\n  Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n  for (Sci_Position i = pos; i < eol_pos; i++) {\n    char ch = styler[i];\n    char chNext = styler[i+1];\n    if ((ch == '-') && (chNext == '-'))\n      return true;\n    else if (ch != ' ' && ch != '\\t')\n      return false;\n  }\n  return false;\n}\nstatic bool IsCommentBlockStart(Sci_Position line, Accessor &styler)\n{\n  Sci_Position pos = styler.LineStart(line);\n  Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n  for (Sci_Position i = pos; i < eol_pos; i++) {\n    char ch = styler[i];\n    char chNext = styler[i+1];\n    char style = styler.StyleAt(i);\n    if ((style == SCE_VHDL_BLOCK_COMMENT) && (ch == '/') && (chNext == '*'))\n      return true;\n  }\n  return false;\n}\n\nstatic bool IsCommentBlockEnd(Sci_Position line, Accessor &styler)\n{\n  Sci_Position pos = styler.LineStart(line);\n  Sci_Position eol_pos = styler.LineStart(line + 1) - 1;\n\n  for (Sci_Position i = pos; i < eol_pos; i++) {\n    char ch = styler[i];\n    char chNext = styler[i+1];\n    char style = styler.StyleAt(i);\n    if ((style == SCE_VHDL_BLOCK_COMMENT) && (ch == '*') && (chNext == '/'))\n      return true;\n  }\n  return false;\n}\n\nstatic bool IsCommentStyle(char style)\n{\n  return style == SCE_VHDL_BLOCK_COMMENT || style == SCE_VHDL_COMMENT || style == SCE_VHDL_COMMENTLINEBANG;\n}\n\n//=============================================================================\n// Folding the code\nstatic void FoldNoBoxVHDLDoc(\n  Sci_PositionU startPos,\n  Sci_Position length,\n  int,\n  Accessor &styler)\n{\n  // Decided it would be smarter to have the lexer have all keywords included. Therefore I\n  // don't check if the style for the keywords that I use to adjust the levels.\n  char words[] =\n    \"architecture begin block case component else elsif end entity for generate loop package process record then \"\n    \"procedure protected function when units\";\n  WordList keywords;\n  keywords.Set(words);\n\n  bool foldComment      = styler.GetPropertyInt(\"fold.comment\", 1) != 0;\n  bool foldCompact      = styler.GetPropertyInt(\"fold.compact\", 1) != 0;\n  bool foldAtElse       = styler.GetPropertyInt(\"fold.at.else\", 1) != 0;\n  bool foldAtBegin      = styler.GetPropertyInt(\"fold.at.Begin\", 1) != 0;\n  bool foldAtParenthese = styler.GetPropertyInt(\"fold.at.Parenthese\", 1) != 0;\n  //bool foldAtWhen       = styler.GetPropertyInt(\"fold.at.When\", 1) != 0;  //< fold at when in case statements\n\n  int  visibleChars     = 0;\n  Sci_PositionU endPos   = startPos + length;\n\n  Sci_Position lineCurrent       = styler.GetLine(startPos);\n  int levelCurrent      = SC_FOLDLEVELBASE;\n  if(lineCurrent > 0)\n    levelCurrent        = styler.LevelAt(lineCurrent-1) >> 16;\n  //int levelMinCurrent   = levelCurrent;\n  int levelMinCurrentElse = levelCurrent;   ///< Used for folding at 'else'\n  int levelMinCurrentBegin = levelCurrent;  ///< Used for folding at 'begin'\n  int levelNext         = levelCurrent;\n\n  /***************************************/\n  Sci_Position lastStart         = 0;\n  char prevWord[32]     = \"\";\n\n  /***************************************/\n  // Find prev word\n  // The logic for going up or down a level depends on a the previous keyword\n  // This code could be cleaned up.\n  Sci_Position end = 0;\n  Sci_PositionU j;\n  for(j = startPos; j>0; j--)\n  {\n    char ch       = styler.SafeGetCharAt(j);\n    char chPrev   = styler.SafeGetCharAt(j-1);\n    int style     = styler.StyleAt(j);\n    int stylePrev = styler.StyleAt(j-1);\n    if ((!IsCommentStyle(style)) && (stylePrev != SCE_VHDL_STRING))\n    {\n      if(IsAWordChar(chPrev) && !IsAWordChar(ch))\n      {\n        end = j-1;\n      }\n    }\n    if ((!IsCommentStyle(style)) && (style != SCE_VHDL_STRING))\n    {\n      if(!IsAWordChar(chPrev) && IsAWordStart(ch) && (end != 0))\n      {\n        char s[32];\n        Sci_PositionU k;\n        for(k=0; (k<31 ) && (k<end-j+1 ); k++) {\n          s[k] = static_cast<char>(tolower(styler[j+k]));\n        }\n        s[k] = '\\0';\n\n        if(keywords.InList(s)) {\n          strcpy(prevWord, s);\n          break;\n        }\n      }\n    }\n  }\n  for(j=j+static_cast<Sci_PositionU>(strlen(prevWord)); j<endPos; j++)\n  {\n    char ch       = styler.SafeGetCharAt(j);\n    int style     = styler.StyleAt(j);\n    if ((!IsCommentStyle(style)) && (style != SCE_VHDL_STRING))\n    {\n      if((ch == ';') && (strcmp(prevWord, \"end\") == 0))\n      {\n        strcpy(prevWord, \";\");\n      }\n    }\n  }\n\n  char  chNext          = styler[startPos];\n  char  chPrev          = '\\0';\n  char  chNextNonBlank;\n  int   styleNext       = styler.StyleAt(startPos);\n  //Platform::DebugPrintf(\"Line[%04d] Prev[%20s] ************************* Level[%x]\\n\", lineCurrent+1, prevWord, levelCurrent);\n\n  /***************************************/\n  for (Sci_PositionU i = startPos; i < endPos; i++)\n  {\n    char ch         = chNext;\n    chNext          = styler.SafeGetCharAt(i + 1);\n    chPrev          = styler.SafeGetCharAt(i - 1);\n    chNextNonBlank  = chNext;\n    Sci_PositionU j  = i+1;\n    while(IsABlank(chNextNonBlank) && j<endPos)\n    {\n      j ++ ;\n      chNextNonBlank = styler.SafeGetCharAt(j);\n    }\n    int style           = styleNext;\n    styleNext       = styler.StyleAt(i + 1);\n    bool atEOL      = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\n    if (foldComment && atEOL)\n    {\n      if(IsCommentLine(lineCurrent, styler))\n      {\n        if(!IsCommentLine(lineCurrent-1, styler) && IsCommentLine(lineCurrent+1, styler))\n        {\n          levelNext++;\n        }\n        else if(IsCommentLine(lineCurrent-1, styler) && !IsCommentLine(lineCurrent+1, styler))\n        {\n          levelNext--;\n        }\n      }\n      else\n      {\n        if (IsCommentBlockStart(lineCurrent, styler) && !IsCommentBlockEnd(lineCurrent, styler))\n        {\n          levelNext++;\n        }\n        else if (IsCommentBlockEnd(lineCurrent, styler) && !IsCommentBlockStart(lineCurrent, styler))\n        {\n          levelNext--;\n        }\n      }\n    }\n\n    if ((style == SCE_VHDL_OPERATOR) && foldAtParenthese)\n    {\n      if(ch == '(') {\n        levelNext++;\n      } else if (ch == ')') {\n        levelNext--;\n      }\n    }\n\n    if ((!IsCommentStyle(style)) && (style != SCE_VHDL_STRING))\n    {\n      if((ch == ';') && (strcmp(prevWord, \"end\") == 0))\n      {\n        strcpy(prevWord, \";\");\n      }\n\n      if(!IsAWordChar(chPrev) && IsAWordStart(ch))\n      {\n        lastStart = i;\n      }\n\n      if(IsAWordChar(ch) && !IsAWordChar(chNext)) {\n        char s[32];\n        Sci_PositionU k;\n        for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {\n          s[k] = static_cast<char>(tolower(styler[lastStart+k]));\n        }\n        s[k] = '\\0';\n\n        if(keywords.InList(s))\n        {\n          if (\n            strcmp(s, \"architecture\") == 0  ||\n            strcmp(s, \"case\") == 0          ||\n            strcmp(s, \"block\") == 0         ||\n            strcmp(s, \"loop\") == 0          ||\n            strcmp(s, \"package\") ==0        ||\n            strcmp(s, \"process\") == 0       ||\n            strcmp(s, \"protected\") == 0     ||\n            strcmp(s, \"record\") == 0        ||\n            strcmp(s, \"then\") == 0          ||\n            strcmp(s, \"units\") == 0)\n          {\n            if (strcmp(prevWord, \"end\") != 0)\n            {\n              if (levelMinCurrentElse > levelNext) {\n                levelMinCurrentElse = levelNext;\n              }\n              levelNext++;\n            }\n          } else if (strcmp(s, \"generate\") == 0){\n            if (strcmp(prevWord, \"end\") != 0 &&\n                strcmp(prevWord, \"else\") != 0 && // vhdl08 else generate\n                strcmp(prevWord, \"case\") != 0)   // vhdl08 case generate\n            {\n              if (levelMinCurrentElse > levelNext) {\n                levelMinCurrentElse = levelNext;\n              }\n              levelNext++;\n            }\n          } else if (\n            strcmp(s, \"component\") == 0      ||\n            strcmp(s, \"entity\") == 0         ||\n            strcmp(s, \"configuration\") == 0 )\n          {\n            if (strcmp(prevWord, \"end\") != 0)\n            { // check for instantiated unit by backward searching for the colon.\n              Sci_PositionU pos = lastStart;\n              char chAtPos=0, styleAtPos;\n              do{// skip white spaces\n                if(!pos)\n                  break;\n                pos--;\n                styleAtPos = styler.StyleAt(pos);\n                chAtPos = styler.SafeGetCharAt(pos);\n              }while(pos &&\n                     (chAtPos == ' ' || chAtPos == '\\t' ||\n                      chAtPos == '\\n' || chAtPos == '\\r' ||\n                      IsCommentStyle(styleAtPos)));\n\n              // check for a colon (':') before the instantiated units \"entity\", \"component\" or \"configuration\". Don't fold thereafter.\n              if (chAtPos != ':')\n              {\n                if (levelMinCurrentElse > levelNext) {\n                  levelMinCurrentElse = levelNext;\n                }\n                levelNext++;\n              }\n            }\n          } else if (\n            strcmp(s, \"procedure\") == 0     ||\n            strcmp(s, \"function\") == 0)\n          {\n            if (strcmp(prevWord, \"end\") != 0) // check for \"end procedure\" etc.\n            { // This code checks to see if the procedure / function is a definition within a \"package\"\n              // rather than the actual code in the body.\n              int BracketLevel = 0;\n              for(Sci_Position pos=i+1; pos<styler.Length(); pos++)\n              {\n                int styleAtPos = styler.StyleAt(pos);\n                char chAtPos = styler.SafeGetCharAt(pos);\n                if(chAtPos == '(') BracketLevel++;\n                if(chAtPos == ')') BracketLevel--;\n                if(\n                  (BracketLevel == 0) &&\n                  (!IsCommentStyle(styleAtPos)) &&\n                  (styleAtPos != SCE_VHDL_STRING) &&\n                  !iswordchar(styler.SafeGetCharAt(pos-1)) &&\n                  (chAtPos|' ')=='i' && (styler.SafeGetCharAt(pos+1)|' ')=='s' &&\n                  !iswordchar(styler.SafeGetCharAt(pos+2)))\n                {\n                  if (levelMinCurrentElse > levelNext) {\n                    levelMinCurrentElse = levelNext;\n                  }\n                  levelNext++;\n                  break;\n                }\n                if((BracketLevel == 0) && (chAtPos == ';'))\n                {\n                  break;\n                }\n              }\n            }\n\n          } else if (strcmp(s, \"end\") == 0) {\n            levelNext--;\n          }  else if(strcmp(s, \"elsif\") == 0) { // elsif is followed by then or generate so folding occurs correctly\n            levelNext--;\n          } else if (strcmp(s, \"else\") == 0) {\n            if(strcmp(prevWord, \"when\") != 0)  // ignore a <= x when y else z;\n            {\n              levelMinCurrentElse = levelNext - 1;  // VHDL else is all on its own so just dec. the min level\n            }\n          } else if(\n            ((strcmp(s, \"begin\") == 0) && (strcmp(prevWord, \"architecture\") == 0)) ||\n            ((strcmp(s, \"begin\") == 0) && (strcmp(prevWord, \"function\") == 0)) ||\n            ((strcmp(s, \"begin\") == 0) && (strcmp(prevWord, \"procedure\") == 0)) ||\n            ((strcmp(s, \"begin\") == 0) && (strcmp(prevWord, \"generate\") == 0)))\n          {\n            levelMinCurrentBegin = levelNext - 1;\n          }\n          //Platform::DebugPrintf(\"Line[%04d] Prev[%20s] Cur[%20s] Level[%x]\\n\", lineCurrent+1, prevWord, s, levelCurrent);\n          strcpy(prevWord, s);\n        }\n      }\n    }\n    if (atEOL) {\n      int levelUse = levelCurrent;\n\n      if (foldAtElse && (levelMinCurrentElse < levelUse)) {\n        levelUse = levelMinCurrentElse;\n      }\n      if (foldAtBegin && (levelMinCurrentBegin < levelUse)) {\n        levelUse = levelMinCurrentBegin;\n      }\n      int lev = levelUse | levelNext << 16;\n      if (visibleChars == 0 && foldCompact)\n        lev |= SC_FOLDLEVELWHITEFLAG;\n\n      if (levelUse < levelNext)\n        lev |= SC_FOLDLEVELHEADERFLAG;\n      if (lev != styler.LevelAt(lineCurrent)) {\n        styler.SetLevel(lineCurrent, lev);\n      }\n      //Platform::DebugPrintf(\"Line[%04d] ---------------------------------------------------- Level[%x]\\n\", lineCurrent+1, levelCurrent);\n      lineCurrent++;\n      levelCurrent = levelNext;\n      //levelMinCurrent = levelCurrent;\n      levelMinCurrentElse = levelCurrent;\n      levelMinCurrentBegin = levelCurrent;\n      visibleChars = 0;\n    }\n    /***************************************/\n    if (!isspacechar(ch)) visibleChars++;\n  }\n\n  /***************************************/\n//  Platform::DebugPrintf(\"Line[%04d] ---------------------------------------------------- Level[%x]\\n\", lineCurrent+1, levelCurrent);\n}\n\n//=============================================================================\nstatic void FoldVHDLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[],\n                       Accessor &styler) {\n  FoldNoBoxVHDLDoc(startPos, length, initStyle, styler);\n}\n\n//=============================================================================\nstatic const char * const VHDLWordLists[] = {\n            \"Keywords\",\n            \"Operators\",\n            \"Attributes\",\n            \"Standard Functions\",\n            \"Standard Packages\",\n            \"Standard Types\",\n            \"User Words\",\n            0,\n        };\n\n\nextern const LexerModule lmVHDL(SCLEX_VHDL, ColouriseVHDLDoc, \"vhdl\", FoldVHDLDoc, VHDLWordLists);\n\n\n// Keyword:\n//    access after alias all architecture array assert attribute begin block body buffer bus case component\n//    configuration constant disconnect downto else elsif end entity exit file for function generate generic\n//    group guarded if impure in inertial inout is label library linkage literal loop map new next null of\n//    on open others out package port postponed procedure process pure range record register reject report\n//    return select severity shared signal subtype then to transport type unaffected units until use variable\n//    wait when while with\n//\n// Operators:\n//    abs and mod nand nor not or rem rol ror sla sll sra srl xnor xor\n//\n// Attributes:\n//    left right low high ascending image value pos val succ pred leftof rightof base range reverse_range\n//    length delayed stable quiet transaction event active last_event last_active last_value driving\n//    driving_value simple_name path_name instance_name\n//\n// Std Functions:\n//    now readline read writeline write endfile resolved to_bit to_bitvector to_stdulogic to_stdlogicvector\n//    to_stdulogicvector to_x01 to_x01z to_UX01 rising_edge falling_edge is_x shift_left shift_right rotate_left\n//    rotate_right resize to_integer to_unsigned to_signed std_match to_01\n//\n// Std Packages:\n//    std ieee work standard textio std_logic_1164 std_logic_arith std_logic_misc std_logic_signed\n//    std_logic_textio std_logic_unsigned numeric_bit numeric_std math_complex math_real vital_primitives\n//    vital_timing\n//\n// Std Types:\n//    boolean bit character severity_level integer real time delay_length natural positive string bit_vector\n//    file_open_kind file_open_status line text side width std_ulogic std_ulogic_vector std_logic\n//    std_logic_vector X01 X01Z UX01 UX01Z unsigned signed\n//\n\n"
  },
  {
    "path": "lexers/LexVerilog.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexVerilog.cxx\n ** Lexer for Verilog.\n ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\n#include \"OptionSet.h\"\n#include \"SubStyles.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n\t// Use an unnamed namespace to protect the functions and classes from name conflicts\n\nstruct PPDefinition {\n\tSci_Position line;\n\tstd::string key;\n\tstd::string value;\n\tbool isUndef;\n\tstd::string arguments;\n\tPPDefinition(Sci_Position line_, const std::string &key_, const std::string &value_, bool isUndef_ = false, const std::string &arguments_ = \"\") :\n\t\tline(line_), key(key_), value(value_), isUndef(isUndef_), arguments(arguments_) {\n\t}\n};\n\nclass LinePPState {\n\tint state;\n\tint ifTaken;\n\tint level;\n\tbool ValidLevel() const {\n\t\treturn level >= 0 && level < 32;\n\t}\n\tint maskLevel() const {\n\t\tif (level >= 0) {\n\t\t\treturn 1 << level;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n\t}\npublic:\n\tLinePPState() : state(0), ifTaken(0), level(-1) {\n\t}\n\tbool IsInactive() const {\n\t\treturn state != 0;\n\t}\n\tbool CurrentIfTaken() const {\n\t\treturn (ifTaken & maskLevel()) != 0;\n\t}\n\tvoid StartSection(bool on) {\n\t\tlevel++;\n\t\tif (ValidLevel()) {\n\t\t\tif (on) {\n\t\t\t\tstate &= ~maskLevel();\n\t\t\t\tifTaken |= maskLevel();\n\t\t\t} else {\n\t\t\t\tstate |= maskLevel();\n\t\t\t\tifTaken &= ~maskLevel();\n\t\t\t}\n\t\t}\n\t}\n\tvoid EndSection() {\n\t\tif (ValidLevel()) {\n\t\t\tstate &= ~maskLevel();\n\t\t\tifTaken &= ~maskLevel();\n\t\t}\n\t\tlevel--;\n\t}\n\tvoid InvertCurrentLevel() {\n\t\tif (ValidLevel()) {\n\t\t\tstate ^= maskLevel();\n\t\t\tifTaken |= maskLevel();\n\t\t}\n\t}\n};\n\n// Hold the preprocessor state for each line seen.\n// Currently one entry per line but could become sparse with just one entry per preprocessor line.\nclass PPStates {\n\tstd::vector<LinePPState> vlls;\npublic:\n\tLinePPState ForLine(Sci_Position line) const {\n\t\tif ((line > 0) && (vlls.size() > static_cast<size_t>(line))) {\n\t\t\treturn vlls[line];\n\t\t} else {\n\t\t\treturn LinePPState();\n\t\t}\n\t}\n\tvoid Add(Sci_Position line, LinePPState lls) {\n\t\tvlls.resize(line+1);\n\t\tvlls[line] = lls;\n\t}\n};\n\n// Options used for LexerVerilog\nstruct OptionsVerilog {\n\tbool foldComment;\n\tbool foldPreprocessor;\n\tbool foldPreprocessorElse;\n\tbool foldCompact;\n\tbool foldAtElse;\n\tbool foldAtModule;\n\tbool trackPreprocessor;\n\tbool updatePreprocessor;\n\tbool portStyling;\n\tbool allUppercaseDocKeyword;\n\tOptionsVerilog() {\n\t\tfoldComment = false;\n\t\tfoldPreprocessor = false;\n\t\tfoldPreprocessorElse = false;\n\t\tfoldCompact = false;\n\t\tfoldAtElse = false;\n\t\tfoldAtModule = false;\n\t\t// for backwards compatibility, preprocessor functionality is disabled by default\n\t\ttrackPreprocessor = false;\n\t\tupdatePreprocessor = false;\n\t\t// for backwards compatibility, treat input/output/inout as regular keywords\n\t\tportStyling = false;\n\t\t// for backwards compatibility, don't treat all uppercase identifiers as documentation keywords\n\t\tallUppercaseDocKeyword = false;\n\t}\n};\n\nstruct OptionSetVerilog : public OptionSet<OptionsVerilog> {\n\tOptionSetVerilog() {\n\t\tDefineProperty(\"fold.comment\", &OptionsVerilog::foldComment,\n\t\t\t\"This option enables folding multi-line comments when using the Verilog lexer.\");\n\t\tDefineProperty(\"fold.preprocessor\", &OptionsVerilog::foldPreprocessor,\n\t\t\t\"This option enables folding preprocessor directives when using the Verilog lexer.\");\n\t\tDefineProperty(\"fold.compact\", &OptionsVerilog::foldCompact);\n\t\tDefineProperty(\"fold.at.else\", &OptionsVerilog::foldAtElse,\n\t\t\t\"This option enables folding on the else line of an if statement.\");\n\t\tDefineProperty(\"fold.verilog.flags\", &OptionsVerilog::foldAtModule,\n\t\t\t\"This option enables folding module definitions. Typically source files \"\n\t\t\t\"contain only one module definition so this option is somewhat useless.\");\n\t\tDefineProperty(\"lexer.verilog.track.preprocessor\", &OptionsVerilog::trackPreprocessor,\n\t\t\t\"Set to 1 to interpret `if/`else/`endif to grey out code that is not active.\");\n\t\tDefineProperty(\"lexer.verilog.update.preprocessor\", &OptionsVerilog::updatePreprocessor,\n\t\t\t\"Set to 1 to update preprocessor definitions when `define, `undef, or `undefineall found.\");\n\t\tDefineProperty(\"lexer.verilog.portstyling\", &OptionsVerilog::portStyling,\n\t\t\t\"Set to 1 to style input, output, and inout ports differently from regular keywords.\");\n\t\tDefineProperty(\"lexer.verilog.allupperkeywords\", &OptionsVerilog::allUppercaseDocKeyword,\n\t\t\t\"Set to 1 to style identifiers that are all uppercase as documentation keyword.\");\n\t\tDefineProperty(\"lexer.verilog.fold.preprocessor.else\", &OptionsVerilog::foldPreprocessorElse,\n\t\t\t\"This option enables folding on `else and `elsif preprocessor directives.\");\n\t}\n};\n\nconst char styleSubable[] = {0};\n\n}\n\nclass LexerVerilog : public DefaultLexer {\n\tCharacterSet setWord;\n\tWordList keywords;\n\tWordList keywords2;\n\tWordList keywords3;\n\tWordList keywords4;\n\tWordList keywords5;\n\tWordList ppDefinitions;\n\tPPStates vlls;\n\tstd::vector<PPDefinition> ppDefineHistory;\n\tstruct SymbolValue {\n\t\tstd::string value;\n\t\tstd::string arguments;\n\t\tSymbolValue(const std::string &value_=\"\", const std::string &arguments_=\"\") : value(value_), arguments(arguments_) {\n\t\t}\n\t\tSymbolValue &operator = (const std::string &value_) {\n\t\t\tvalue = value_;\n\t\t\targuments.clear();\n\t\t\treturn *this;\n\t\t}\n\t\tbool IsMacro() const {\n\t\t\treturn !arguments.empty();\n\t\t}\n\t};\n\ttypedef std::map<std::string, SymbolValue> SymbolTable;\n\tSymbolTable preprocessorDefinitionsStart;\n\tOptionsVerilog options;\n\tOptionSetVerilog osVerilog;\n\tenum { activeFlag = 0x40 };\n\tSubStyles subStyles;\n\n\t// states at end of line (EOL) during fold operations:\n\t//\t\tfoldExternFlag: EOL while parsing an extern function/task declaration terminated by ';'\n\t//\t\tfoldWaitDisableFlag: EOL while parsing wait or disable statement, terminated by \"fork\" or '('\n\t//\t\ttypdefFlag: EOL while parsing typedef statement, terminated by ';'\n\tenum {foldExternFlag = 0x01, foldWaitDisableFlag = 0x02, typedefFlag = 0x04, protectedFlag = 0x08};\n\t// map using line number as key to store fold state information\n\tstd::map<Sci_Position, int> foldState;\n\npublic:\n\tLexerVerilog() :\n\t\tDefaultLexer(\"verilog\", SCLEX_VERILOG),\n\t\tsetWord(CharacterSet::setAlphaNum, \"._\", 0x80, true),\n\t\tsubStyles(styleSubable, 0x80, 0x40, activeFlag) {\n\t\t}\n\tvirtual ~LexerVerilog() {}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tconst char* SCI_METHOD PropertyNames() override {\n\t\treturn osVerilog.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char* name) override {\n\t\treturn osVerilog.PropertyType(name);\n\t}\n\tconst char* SCI_METHOD DescribeProperty(const char* name) override {\n\t\treturn osVerilog.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char* key, const char* val) override {\n\t    return osVerilog.PropertySet(&options, key, val);\n\t}\n\tconst char * SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osVerilog.PropertyGet(key);\n\t}\n\tconst char* SCI_METHOD DescribeWordListSets() override {\n\t\treturn osVerilog.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char* wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid* SCI_METHOD PrivateCall(int, void*) override {\n\t\treturn 0;\n\t}\n\tint SCI_METHOD LineEndTypesSupported() override {\n\t\treturn SC_LINE_END_TYPE_UNICODE;\n\t}\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {\n\t\treturn subStyles.Allocate(styleBase, numberStyles);\n\t}\n\tint SCI_METHOD SubStylesStart(int styleBase) override {\n\t\treturn subStyles.Start(styleBase);\n\t}\n\tint SCI_METHOD SubStylesLength(int styleBase) override {\n\t\treturn subStyles.Length(styleBase);\n\t}\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override {\n\t\tint styleBase = subStyles.BaseStyle(MaskActive(subStyle));\n\t\tint active = subStyle & activeFlag;\n\t\treturn styleBase | active;\n\t}\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) override {\n\t\treturn MaskActive(style);\n \t}\n\tvoid SCI_METHOD FreeSubStyles() override {\n\t\tsubStyles.Free();\n\t}\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {\n\t\tsubStyles.SetIdentifiers(style, identifiers);\n\t}\n\tint SCI_METHOD DistanceToSecondaryStyles() override {\n\t\treturn activeFlag;\n\t}\n\tconst char * SCI_METHOD GetSubStyleBases() override {\n\t\treturn styleSubable;\n\t}\n\tstatic ILexer5* LexerFactoryVerilog() {\n\t\treturn new LexerVerilog();\n\t}\n\tstatic int MaskActive(int style) {\n\t\treturn style & ~activeFlag;\n\t}\n\tstd::vector<std::string> Tokenize(const std::string &expr) const;\n};\n\nSci_Position SCI_METHOD LexerVerilog::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = 0;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywords;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywords2;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywords3;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywords4;\n\t\tbreak;\n\tcase 4:\n\t\twordListN = &keywords5;\n\t\tbreak;\n\tcase 5:\n\t\twordListN = &ppDefinitions;\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN) {\n\t\tWordList wlNew;\n\t\twlNew.Set(wl);\n\t\tif (*wordListN != wlNew) {\n\t\t\twordListN->Set(wl);\n\t\t\tfirstModification = 0;\n\t\t\tif (n == 5) {\n\t\t\t\t// Rebuild preprocessorDefinitions\n\t\t\t\tpreprocessorDefinitionsStart.clear();\n\t\t\t\tfor (int nDefinition = 0; nDefinition < ppDefinitions.Length(); nDefinition++) {\n\t\t\t\t\tconst char *cpDefinition = ppDefinitions.WordAt(nDefinition);\n\t\t\t\t\tconst char *cpEquals = strchr(cpDefinition, '=');\n\t\t\t\t\tif (cpEquals) {\n\t\t\t\t\t\tstd::string name(cpDefinition, cpEquals - cpDefinition);\n\t\t\t\t\t\tstd::string val(cpEquals+1);\n\t\t\t\t\t\tsize_t bracket = name.find('(');\n\t\t\t\t\t\tsize_t bracketEnd = name.find(')');\n\t\t\t\t\t\tif ((bracket != std::string::npos) && (bracketEnd != std::string::npos)) {\n\t\t\t\t\t\t\t// Macro\n\t\t\t\t\t\t\tstd::string args = name.substr(bracket + 1, bracketEnd - bracket - 1);\n\t\t\t\t\t\t\tname = name.substr(0, bracket);\n\t\t\t\t\t\t\tpreprocessorDefinitionsStart[name] = SymbolValue(val, args);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpreprocessorDefinitionsStart[name] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstd::string name(cpDefinition);\n\t\t\t\t\t\tstd::string val(\"1\");\n\t\t\t\t\t\tpreprocessorDefinitionsStart[name] = val;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn firstModification;\n}\n\nstatic inline bool IsAWordChar(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '\\''|| ch == '$');\n}\n\nstatic inline bool IsAWordStart(const int ch) {\n\treturn (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '$');\n}\n\nstatic inline bool AllUpperCase(const char *a) {\n\twhile (*a) {\n\t\tif (*a >= 'a' && *a <= 'z') return false;\n\t\ta++;\n\t}\n\treturn true;\n}\n\n// Functor used to truncate history\nstruct After {\n\tSci_Position line;\n\texplicit After(Sci_Position line_) : line(line_) {}\n\tbool operator()(PPDefinition &p) const {\n\t\treturn p.line > line;\n\t}\n};\n\nstatic std::string GetRestOfLine(LexAccessor &styler, Sci_Position start, bool allowSpace) {\n\tstd::string restOfLine;\n\tSci_Position i =0;\n\tchar ch = styler.SafeGetCharAt(start, '\\n');\n\tSci_Position endLine = styler.LineEnd(styler.GetLine(start));\n\twhile (((start+i) < endLine) && (ch != '\\r')) {\n\t\tchar chNext = styler.SafeGetCharAt(start + i + 1, '\\n');\n\t\tif (ch == '/' && (chNext == '/' || chNext == '*'))\n\t\t\tbreak;\n\t\tif (allowSpace || (ch != ' '))\n\t\t\trestOfLine += ch;\n\t\ti++;\n\t\tch = chNext;\n\t}\n\treturn restOfLine;\n}\n\nstatic bool IsSpaceOrTab(int ch) {\n\treturn ch == ' ' || ch == '\\t';\n}\n\nvoid SCI_METHOD LexerVerilog::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess)\n{\n\tLexAccessor styler(pAccess);\n\n\tconst int kwOther=0, kwDot=0x100, kwInput=0x200, kwOutput=0x300, kwInout=0x400, kwProtected=0x800;\n\tint lineState = kwOther;\n\tbool continuationLine = false;\n\n\tSci_Position curLine = styler.GetLine(startPos);\n\tif (curLine > 0) lineState = styler.GetLineState(curLine - 1);\n\n\t// Do not leak onto next line\n\tif (initStyle == SCE_V_STRINGEOL)\n\t\tinitStyle = SCE_V_DEFAULT;\n\n\tif ((MaskActive(initStyle) == SCE_V_PREPROCESSOR) ||\n\t\t\t(MaskActive(initStyle) == SCE_V_COMMENTLINE) ||\n\t\t\t(MaskActive(initStyle) == SCE_V_COMMENTLINEBANG)) {\n\t\t// Set continuationLine if last character of previous line is '\\'\n\t\tif (curLine > 0) {\n\t\t\tSci_Position endLinePrevious = styler.LineEnd(curLine - 1);\n\t\t\tif (endLinePrevious > 0) {\n\t\t\t\tcontinuationLine = styler.SafeGetCharAt(endLinePrevious-1) == '\\\\';\n\t\t\t}\n\t\t}\n\t}\n\n\tStyleContext sc(startPos, length, initStyle, styler);\n\tLinePPState preproc = vlls.ForLine(curLine);\n\n\tbool definitionsChanged = false;\n\n\t// Truncate ppDefineHistory before current line\n\n\tif (!options.updatePreprocessor)\n\t\tppDefineHistory.clear();\n\n\tstd::vector<PPDefinition>::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(), After(curLine-1));\n\tif (itInvalid != ppDefineHistory.end()) {\n\t\tppDefineHistory.erase(itInvalid, ppDefineHistory.end());\n\t\tdefinitionsChanged = true;\n\t}\n\n\tSymbolTable preprocessorDefinitions = preprocessorDefinitionsStart;\n\tfor (std::vector<PPDefinition>::iterator itDef = ppDefineHistory.begin(); itDef != ppDefineHistory.end(); ++itDef) {\n\t\tif (itDef->isUndef)\n\t\t\tpreprocessorDefinitions.erase(itDef->key);\n\t\telse\n\t\t\tpreprocessorDefinitions[itDef->key] = SymbolValue(itDef->value, itDef->arguments);\n\t}\n\n\tint activitySet = preproc.IsInactive() ? activeFlag : 0;\n\tSci_Position lineEndNext = styler.LineEnd(curLine);\n\tbool isEscapedId = false;    // true when parsing an escaped Identifier\n\tbool isProtected = (lineState&kwProtected) != 0;\t// true when parsing a protected region\n\n\tfor (; sc.More(); sc.Forward()) {\n\t\tif (sc.atLineStart) {\n\t\t\tif (sc.state == SCE_V_STRING) {\n\t\t\t\t// Prevent SCE_V_STRINGEOL from leaking back to previous line\n\t\t\t\tsc.SetState(SCE_V_STRING);\n\t\t\t}\n\t\t\tif ((MaskActive(sc.state) == SCE_V_PREPROCESSOR) && (!continuationLine)) {\n\t\t\t\tsc.SetState(SCE_V_DEFAULT|activitySet);\n\t\t\t}\n\t\t\tif (preproc.IsInactive()) {\n\t\t\t\tactivitySet = activeFlag;\n\t\t\t\tsc.SetState(sc.state | activitySet);\n\t\t\t}\n\t\t}\n\n\t\tif (sc.MatchLineEnd()) {\n\t\t\tcurLine++;\n\t\t\tlineEndNext = styler.LineEnd(curLine);\n\t\t\tvlls.Add(curLine, preproc);\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tstyler.SetLineState(curLine, lineState);\n\t\t\tisEscapedId = false;    // EOL terminates an escaped Identifier\n\t\t}\n\n\t\t// Handle line continuation generically.\n\t\tif (sc.ch == '\\\\') {\n\t\t\tif (static_cast<Sci_Position>((sc.currentPos+1)) >= lineEndNext) {\n\t\t\t\tcurLine++;\n\t\t\t\tlineEndNext = styler.LineEnd(curLine);\n\t\t\t\tvlls.Add(curLine, preproc);\n\t\t\t\t// Update the line state, so it can be seen by next line\n\t\t\t\tstyler.SetLineState(curLine, lineState);\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.ch == '\\r' && sc.chNext == '\\n') {\n\t\t\t\t\t// Even in UTF-8, \\r and \\n are separate\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tcontinuationLine = true;\n\t\t\t\tsc.Forward();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// for comment keyword\n\t\tif (MaskActive(sc.state) == SCE_V_COMMENT_WORD && !IsAWordChar(sc.ch)) {\n\t\t\tchar s[100];\n\t\t\tint state = lineState & 0xff;\n\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\tif (keywords5.InList(s)) {\n\t\t\t\tsc.ChangeState(SCE_V_COMMENT_WORD|activitySet);\n\t\t\t} else {\n\t\t\t\tsc.ChangeState(state|activitySet);\n\t\t\t}\n\t\t\tsc.SetState(state|activitySet);\n\t\t}\n\n\t\tconst bool atLineEndBeforeSwitch = sc.MatchLineEnd();\n\n\t\t// Determine if the current state should terminate.\n\t\tswitch (MaskActive(sc.state)) {\n\t\t\tcase SCE_V_OPERATOR:\n\t\t\t\tsc.SetState(SCE_V_DEFAULT|activitySet);\n\t\t\t\tbreak;\n\t\t\tcase SCE_V_NUMBER:\n\t\t\t\tif (!(IsAWordChar(sc.ch) || (sc.ch == '?'))) {\n\t\t\t\t\tsc.SetState(SCE_V_DEFAULT|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_V_IDENTIFIER:\n\t\t\t\tif (!isEscapedId &&(!IsAWordChar(sc.ch) || (sc.ch == '.'))) {\n\t\t\t\t\tchar s[100];\n\t\t\t\t\tlineState &= 0xff00;\n\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\tif (options.portStyling && (strcmp(s, \"input\") == 0)) {\n\t\t\t\t\t\tlineState = kwInput;\n\t\t\t\t\t\tsc.ChangeState(SCE_V_INPUT|activitySet);\n\t\t\t\t\t} else if (options.portStyling && (strcmp(s, \"output\") == 0)) {\n\t\t\t\t\t\tlineState = kwOutput;\n\t\t\t\t\t\tsc.ChangeState(SCE_V_OUTPUT|activitySet);\n\t\t\t\t\t} else if (options.portStyling && (strcmp(s, \"inout\") == 0)) {\n\t\t\t\t\t\tlineState = kwInout;\n\t\t\t\t\t\tsc.ChangeState(SCE_V_INOUT|activitySet);\n\t\t\t\t\t} else if (lineState == kwInput) {\n\t\t\t\t\t\tsc.ChangeState(SCE_V_INPUT|activitySet);\n\t\t\t\t\t} else if (lineState == kwOutput) {\n\t\t\t\t\t\tsc.ChangeState(SCE_V_OUTPUT|activitySet);\n\t\t\t\t\t} else if (lineState == kwInout) {\n\t\t\t\t\t\tsc.ChangeState(SCE_V_INOUT|activitySet);\n\t\t\t\t\t} else if (lineState == kwDot) {\n\t\t\t\t\t\tlineState = kwOther;\n\t\t\t\t\t\tif (options.portStyling)\n\t\t\t\t\t\t\tsc.ChangeState(SCE_V_PORT_CONNECT|activitySet);\n\t\t\t\t\t} else if (keywords.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_V_WORD|activitySet);\n\t\t\t\t\t} else if (keywords2.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_V_WORD2|activitySet);\n\t\t\t\t\t} else if (keywords3.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_V_WORD3|activitySet);\n\t\t\t\t\t} else if (keywords4.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_V_USER|activitySet);\n\t\t\t\t\t} else if (options.allUppercaseDocKeyword && AllUpperCase(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_V_USER|activitySet);\n\t\t\t\t\t}\n\t\t\t\t\tsc.SetState(SCE_V_DEFAULT|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_V_PREPROCESSOR:\n\t\t\t\tif (!IsAWordChar(sc.ch) || sc.MatchLineEnd()) {\n\t\t\t\t\tsc.SetState(SCE_V_DEFAULT|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_V_COMMENT:\n\t\t\t\tif (sc.Match('*', '/')) {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_V_DEFAULT|activitySet);\n\t\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\t\tlineState = sc.state | (lineState & 0xff00);\n\t\t\t\t\tsc.SetState(SCE_V_COMMENT_WORD|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_V_COMMENTLINE:\n\t\t\tcase SCE_V_COMMENTLINEBANG:\n\t\t\t\tif (sc.atLineStart) {\n\t\t\t\t\tsc.SetState(SCE_V_DEFAULT|activitySet);\n\t\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\t\tlineState = sc.state | (lineState & 0xff00);\n\t\t\t\t\tsc.SetState(SCE_V_COMMENT_WORD|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SCE_V_STRING:\n\t\t\t\tif (sc.ch == '\\\\') {\n\t\t\t\t\tif (sc.chNext == '\\\"' || sc.chNext == '\\'' || sc.chNext == '\\\\') {\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\t}\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tsc.ForwardSetState(SCE_V_DEFAULT|activitySet);\n\t\t\t\t} else if (sc.MatchLineEnd()) {\n\t\t\t\t\tsc.ChangeState(SCE_V_STRINGEOL|activitySet);\n\t\t\t\t\tif (sc.Match('\\r', '\\n'))\n\t\t\t\t\t\tsc.Forward();\n\t\t\t\t\tsc.ForwardSetState(SCE_V_DEFAULT|activitySet);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (sc.MatchLineEnd() && !atLineEndBeforeSwitch) {\n\t\t\t// State exit processing consumed characters up to end of line.\n\t\t\tcurLine++;\n\t\t\tlineEndNext = styler.LineEnd(curLine);\n\t\t\tvlls.Add(curLine, preproc);\n\t\t\t// Update the line state, so it can be seen by next line\n\t\t\tstyler.SetLineState(curLine, lineState);\n\t\t\tisEscapedId = false;    // EOL terminates an escaped Identifier\n\t\t}\n\n\t\t// Determine if a new state should be entered.\n\t\tif (MaskActive(sc.state) == SCE_V_DEFAULT) {\n\t\t\tif (sc.ch == '`') {\n\t\t\t\tsc.SetState(SCE_V_PREPROCESSOR|activitySet);\n\t\t\t\t// Skip whitespace between ` and preprocessor word\n\t\t\t\tdo {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t} while ((sc.ch == ' ' || sc.ch == '\\t') && sc.More());\n\t\t\t\tif (sc.MatchLineEnd()) {\n\t\t\t\t\tsc.SetState(SCE_V_DEFAULT|activitySet);\n\t\t\t\t\tstyler.SetLineState(curLine, lineState);\n\t\t\t\t} else {\n\t\t\t\t\tif (sc.Match(\"protected\")) {\n\t\t\t\t\t\tisProtected = true;\n\t\t\t\t\t\tlineState |= kwProtected;\n\t\t\t\t\t\tstyler.SetLineState(curLine, lineState);\n\t\t\t\t\t} else if (sc.Match(\"endprotected\")) {\n\t\t\t\t\t\tisProtected = false;\n\t\t\t\t\t\tlineState &= ~kwProtected;\n\t\t\t\t\t\tstyler.SetLineState(curLine, lineState);\n\t\t\t\t\t} else if (!isProtected && options.trackPreprocessor) {\n\t\t\t\t\t\tif (sc.Match(\"ifdef\") || sc.Match(\"ifndef\")) {\n\t\t\t\t\t\t\tbool isIfDef = sc.Match(\"ifdef\");\n\t\t\t\t\t\t\tint i = isIfDef ? 5 : 6;\n\t\t\t\t\t\t\tstd::string restOfLine = GetRestOfLine(styler, sc.currentPos + i + 1, false);\n\t\t\t\t\t\t\tbool foundDef = preprocessorDefinitions.find(restOfLine) != preprocessorDefinitions.end();\n\t\t\t\t\t\t\tpreproc.StartSection(isIfDef == foundDef);\n\t\t\t\t\t\t} else if (sc.Match(\"else\")) {\n\t\t\t\t\t\t\tif (!preproc.CurrentIfTaken()) {\n\t\t\t\t\t\t\t\tpreproc.InvertCurrentLevel();\n\t\t\t\t\t\t\t\tactivitySet = preproc.IsInactive() ? activeFlag : 0;\n\t\t\t\t\t\t\t\tif (!activitySet) {\n\t\t\t\t\t\t\t\t\tsc.ChangeState(SCE_V_PREPROCESSOR|activitySet);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (!preproc.IsInactive()) {\n\t\t\t\t\t\t\t\tpreproc.InvertCurrentLevel();\n\t\t\t\t\t\t\t\tactivitySet = preproc.IsInactive() ? activeFlag : 0;\n\t\t\t\t\t\t\t\tif (!activitySet) {\n\t\t\t\t\t\t\t\t\tsc.ChangeState(SCE_V_PREPROCESSOR|activitySet);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.Match(\"elsif\")) {\n\t\t\t\t\t\t\t// Ensure only one chosen out of `if .. `elsif .. `elsif .. `else .. `endif\n\t\t\t\t\t\t\tif (!preproc.CurrentIfTaken()) {\n\t\t\t\t\t\t\t\t// Similar to `ifdef\n\t\t\t\t\t\t\t\tstd::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true);\n\t\t\t\t\t\t\t\tbool ifGood = preprocessorDefinitions.find(restOfLine) != preprocessorDefinitions.end();\n\t\t\t\t\t\t\t\tif (ifGood) {\n\t\t\t\t\t\t\t\t\tpreproc.InvertCurrentLevel();\n\t\t\t\t\t\t\t\t\tactivitySet = preproc.IsInactive() ? activeFlag : 0;\n\t\t\t\t\t\t\t\t\tif (!activitySet)\n\t\t\t\t\t\t\t\t\t\tsc.ChangeState(SCE_V_PREPROCESSOR|activitySet);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (!preproc.IsInactive()) {\n\t\t\t\t\t\t\t\tpreproc.InvertCurrentLevel();\n\t\t\t\t\t\t\t\tactivitySet = preproc.IsInactive() ? activeFlag : 0;\n\t\t\t\t\t\t\t\tif (!activitySet)\n\t\t\t\t\t\t\t\t\tsc.ChangeState(SCE_V_PREPROCESSOR|activitySet);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.Match(\"endif\")) {\n\t\t\t\t\t\t\tpreproc.EndSection();\n\t\t\t\t\t\t\tactivitySet = preproc.IsInactive() ? activeFlag : 0;\n\t\t\t\t\t\t\tsc.ChangeState(SCE_V_PREPROCESSOR|activitySet);\n\t\t\t\t\t\t} else if (sc.Match(\"define\")) {\n\t\t\t\t\t\t\tif (options.updatePreprocessor && !preproc.IsInactive()) {\n\t\t\t\t\t\t\t\tstd::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true);\n\t\t\t\t\t\t\t\tsize_t startName = 0;\n\t\t\t\t\t\t\t\twhile ((startName < restOfLine.length()) && IsSpaceOrTab(restOfLine[startName]))\n\t\t\t\t\t\t\t\t\tstartName++;\n\t\t\t\t\t\t\t\tsize_t endName = startName;\n\t\t\t\t\t\t\t\twhile ((endName < restOfLine.length()) && setWord.Contains(static_cast<unsigned char>(restOfLine[endName])))\n\t\t\t\t\t\t\t\t\tendName++;\n\t\t\t\t\t\t\t\tstd::string key = restOfLine.substr(startName, endName-startName);\n\t\t\t\t\t\t\t\tif ((endName < restOfLine.length()) && (restOfLine.at(endName) == '(')) {\n\t\t\t\t\t\t\t\t\t// Macro\n\t\t\t\t\t\t\t\t\tsize_t endArgs = endName;\n\t\t\t\t\t\t\t\t\twhile ((endArgs < restOfLine.length()) && (restOfLine[endArgs] != ')'))\n\t\t\t\t\t\t\t\t\t\tendArgs++;\n\t\t\t\t\t\t\t\t\tstd::string args = restOfLine.substr(endName + 1, endArgs - endName - 1);\n\t\t\t\t\t\t\t\t\tsize_t startValue = endArgs+1;\n\t\t\t\t\t\t\t\t\twhile ((startValue < restOfLine.length()) && IsSpaceOrTab(restOfLine[startValue]))\n\t\t\t\t\t\t\t\t\t\tstartValue++;\n\t\t\t\t\t\t\t\t\tstd::string value;\n\t\t\t\t\t\t\t\t\tif (startValue < restOfLine.length())\n\t\t\t\t\t\t\t\t\t\tvalue = restOfLine.substr(startValue);\n\t\t\t\t\t\t\t\t\tpreprocessorDefinitions[key] = SymbolValue(value, args);\n\t\t\t\t\t\t\t\t\tppDefineHistory.push_back(PPDefinition(curLine, key, value, false, args));\n\t\t\t\t\t\t\t\t\tdefinitionsChanged = true;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// Value\n\t\t\t\t\t\t\t\t\tsize_t startValue = endName;\n\t\t\t\t\t\t\t\t\twhile ((startValue < restOfLine.length()) && IsSpaceOrTab(restOfLine[startValue]))\n\t\t\t\t\t\t\t\t\t\tstartValue++;\n\t\t\t\t\t\t\t\t\tstd::string value = restOfLine.substr(startValue);\n\t\t\t\t\t\t\t\t\tpreprocessorDefinitions[key] = value;\n\t\t\t\t\t\t\t\t\tppDefineHistory.push_back(PPDefinition(curLine, key, value));\n\t\t\t\t\t\t\t\t\tdefinitionsChanged = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.Match(\"undefineall\")) {\n\t\t\t\t\t\t\tif (options.updatePreprocessor && !preproc.IsInactive()) {\n\t\t\t\t\t\t\t\t// remove all preprocessor definitions\n\t\t\t\t\t\t\t\tstd::map<std::string, SymbolValue>::iterator itDef;\n\t\t\t\t\t\t\t\tfor(itDef = preprocessorDefinitions.begin(); itDef != preprocessorDefinitions.end(); ++itDef) {\n\t\t\t\t\t\t\t\t\tppDefineHistory.push_back(PPDefinition(curLine, itDef->first, \"\", true));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tpreprocessorDefinitions.clear();\n\t\t\t\t\t\t\t\tdefinitionsChanged = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (sc.Match(\"undef\")) {\n\t\t\t\t\t\t\tif (options.updatePreprocessor && !preproc.IsInactive()) {\n\t\t\t\t\t\t\t\tstd::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, true);\n\t\t\t\t\t\t\t\tstd::vector<std::string> tokens = Tokenize(restOfLine);\n\t\t\t\t\t\t\t\tstd::string key;\n\t\t\t\t\t\t\t\tif (tokens.size() >= 1) {\n\t\t\t\t\t\t\t\t\tkey = tokens[0];\n\t\t\t\t\t\t\t\t\tpreprocessorDefinitions.erase(key);\n\t\t\t\t\t\t\t\t\tppDefineHistory.push_back(PPDefinition(curLine, key, \"\", true));\n\t\t\t\t\t\t\t\t\tdefinitionsChanged = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (!isProtected) {\n\t\t\t\tif (IsADigit(sc.ch) || (sc.ch == '\\'') || (sc.ch == '.' && IsADigit(sc.chNext))) {\n\t\t\t\t\tsc.SetState(SCE_V_NUMBER|activitySet);\n\t\t\t\t} else if (IsAWordStart(sc.ch)) {\n\t\t\t\t\tsc.SetState(SCE_V_IDENTIFIER|activitySet);\n\t\t\t\t} else if (sc.Match('/', '*')) {\n\t\t\t\t\tsc.SetState(SCE_V_COMMENT|activitySet);\n\t\t\t\t\tsc.Forward();\t// Eat the * so it isn't used for the end of the comment\n\t\t\t\t} else if (sc.Match('/', '/')) {\n\t\t\t\t\tif (sc.Match(\"//!\"))\t// Nice to have a different comment style\n\t\t\t\t\t\tsc.SetState(SCE_V_COMMENTLINEBANG|activitySet);\n\t\t\t\t\telse\n\t\t\t\t\t\tsc.SetState(SCE_V_COMMENTLINE|activitySet);\n\t\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\t\tsc.SetState(SCE_V_STRING|activitySet);\n\t\t\t\t} else if (sc.ch == '\\\\') {\n\t\t\t\t\t// escaped identifier, everything is ok up to whitespace\n\t\t\t\t\tisEscapedId = true;\n\t\t\t\t\tsc.SetState(SCE_V_IDENTIFIER|activitySet);\n\t\t\t\t} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '#') {\n\t\t\t\t\tsc.SetState(SCE_V_OPERATOR|activitySet);\n\t\t\t\t\tif (sc.ch == '.') lineState = kwDot;\n\t\t\t\t\tif (sc.ch == ';') lineState = kwOther;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isEscapedId && isspacechar(sc.ch)) {\n\t\t\tisEscapedId = false;\n\t\t}\n\t}\n\tif (definitionsChanged) {\n\t\tstyler.ChangeLexerState(startPos, startPos + length);\n\t}\n\tsc.Complete();\n}\n\nstatic bool IsStreamCommentStyle(int style) {\n\treturn style == SCE_V_COMMENT;\n}\n\nstatic bool IsCommentLine(Sci_Position line, LexAccessor &styler) {\n\tSci_Position pos = styler.LineStart(line);\n\tSci_Position eolPos = styler.LineStart(line + 1) - 1;\n\tfor (Sci_Position i = pos; i < eolPos; i++) {\n\t\tchar ch = styler[i];\n\t\tchar chNext = styler.SafeGetCharAt(i + 1);\n\t\tint style = styler.StyleAt(i);\n\t\tif (ch == '/' && chNext == '/' &&\n\t\t   (style == SCE_V_COMMENTLINE || style == SCE_V_COMMENTLINEBANG)) {\n\t\t\treturn true;\n\t\t} else if (!IsASpaceOrTab(ch)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn false;\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\nvoid SCI_METHOD LexerVerilog::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess)\n{\n\tLexAccessor styler(pAccess);\n\tbool foldAtBrace  = 1;\n\tbool foldAtParenthese  = 1;\n\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\t// Move back one line to be compatible with LexerModule::Fold behavior, fixes problem with foldComment behavior\n\tif (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tSci_Position newStartPos = styler.LineStart(lineCurrent);\n\t\tlength += startPos - newStartPos;\n\t\tstartPos = newStartPos;\n\t\tinitStyle = 0;\n\t\tif (startPos > 0) {\n\t\t\tinitStyle = styler.StyleAt(startPos - 1);\n\t\t}\n\t}\n\tSci_PositionU endPos = startPos + length;\n\tint visibleChars = 0;\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0)\n\t\tlevelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\n\tint levelMinCurrent = levelCurrent;\n\tint levelNext = levelCurrent;\n\tchar chNext = styler[startPos];\n\tint styleNext = MaskActive(styler.StyleAt(startPos));\n\tint style = MaskActive(initStyle);\n\n\t// restore fold state (if it exists) for prior line\n\tint stateCurrent = 0;\n\tstd::map<Sci_Position,int>::iterator foldStateIterator = foldState.find(lineCurrent-1);\n\tif (foldStateIterator != foldState.end()) {\n\t\tstateCurrent = foldStateIterator->second;\n\t}\n\n\t// remove all foldState entries after lineCurrent-1\n\tfoldStateIterator = foldState.upper_bound(lineCurrent-1);\n\tif (foldStateIterator != foldState.end()) {\n\t\tfoldState.erase(foldStateIterator, foldState.end());\n\t}\n\n\tfor (Sci_PositionU i = startPos; i < endPos; i++) {\n\t\tchar ch = chNext;\n\t\tchNext = styler.SafeGetCharAt(i + 1);\n\t\tint stylePrev = style;\n\t\tstyle = styleNext;\n\t\tstyleNext = MaskActive(styler.StyleAt(i + 1));\n\t\tbool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n\t\tif (!(stateCurrent & protectedFlag)) {\n\t\t\tif (options.foldComment && IsStreamCommentStyle(style)) {\n\t\t\t\tif (!IsStreamCommentStyle(stylePrev)) {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {\n\t\t\t\t\t// Comments don't end at end of line and the next character may be unstyled.\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler))\n\t\t\t{\n\t\t\t\tif (!IsCommentLine(lineCurrent - 1, styler)\n\t\t\t\t\t&& IsCommentLine(lineCurrent + 1, styler))\n\t\t\t\t\tlevelNext++;\n\t\t\t\telse if (IsCommentLine(lineCurrent - 1, styler)\n\t\t\t\t\t\t && !IsCommentLine(lineCurrent+1, styler))\n\t\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t\tif (options.foldComment && (style == SCE_V_COMMENTLINE)) {\n\t\t\t\tif ((ch == '/') && (chNext == '/')) {\n\t\t\t\t\tchar chNext2 = styler.SafeGetCharAt(i + 2);\n\t\t\t\t\tif (chNext2 == '{') {\n\t\t\t\t\t\tlevelNext++;\n\t\t\t\t\t} else if (chNext2 == '}') {\n\t\t\t\t\t\tlevelNext--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (ch == '`') {\n\t\t\tSci_PositionU j = i + 1;\n\t\t\twhile ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {\n\t\t\t\tj++;\n\t\t\t}\n\t\t\tif (styler.Match(j, \"protected\")) {\n\t\t\t\tstateCurrent |= protectedFlag;\n\t\t\t\tlevelNext++;\n\t\t\t} else if (styler.Match(j, \"endprotected\")) {\n\t\t\t\tstateCurrent &= ~protectedFlag;\n\t\t\t\tlevelNext--;\n\t\t\t} else if (!(stateCurrent & protectedFlag) && options.foldPreprocessor && (style == SCE_V_PREPROCESSOR)) {\n\t\t\t\tif (styler.Match(j, \"if\")) {\n\t\t\t\t\tif (options.foldPreprocessorElse) {\n\t\t\t\t\t\t// Measure the minimum before a begin to allow\n\t\t\t\t\t\t// folding on \"end else begin\"\n\t\t\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (options.foldPreprocessorElse && styler.Match(j, \"else\")) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t\t}\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (options.foldPreprocessorElse && styler.Match(j, \"elsif\")) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t\t// Measure the minimum before a begin to allow\n\t\t\t\t\t// folding on \"end else begin\"\n\t\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t\t}\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (styler.Match(j, \"endif\")) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (style == SCE_V_OPERATOR) {\n\t\t\tif (foldAtParenthese) {\n\t\t\t\tif (ch == '(') {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (ch == ')') {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// semicolons terminate external declarations\n\t\t\tif (ch == ';') {\n\t\t\t\t// extern and pure virtual declarations terminated by semicolon\n\t\t\t\tif (stateCurrent & foldExternFlag) {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t\tstateCurrent &= ~foldExternFlag;\n\t\t\t\t}\n\t\t\t\t// wait and disable statements terminated by semicolon\n\t\t\t\tif (stateCurrent & foldWaitDisableFlag) {\n\t\t\t\t\tstateCurrent &= ~foldWaitDisableFlag;\n\t\t\t\t}\n\t\t\t\t// typedef statements terminated by semicolon\n\t\t\t\tif (stateCurrent & typedefFlag) {\n\t\t\t\t\tstateCurrent &= ~typedefFlag;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// wait and disable statements containing '(' will not contain \"fork\" keyword, special processing is not needed\n\t\t\tif (ch == '(') {\n\t\t\t\tif (stateCurrent & foldWaitDisableFlag) {\n\t\t\t\t\tstateCurrent &= ~foldWaitDisableFlag;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (style == SCE_V_OPERATOR) {\n\t\t\tif (foldAtBrace) {\n\t\t\t\tif (ch == '{') {\n\t\t\t\t\tlevelNext++;\n\t\t\t\t} else if (ch == '}') {\n\t\t\t\t\tlevelNext--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (style == SCE_V_WORD && stylePrev != SCE_V_WORD) {\n\t\t\tSci_PositionU j = i;\n\t\t\tif (styler.Match(j, \"case\") ||\n\t\t\t\tstyler.Match(j, \"casex\") ||\n\t\t\t\tstyler.Match(j, \"casez\") ||\n\t\t\t\tstyler.Match(j, \"covergroup\") ||\n\t\t\t\tstyler.Match(j, \"function\") ||\n\t\t\t\tstyler.Match(j, \"generate\") ||\n\t\t\t\tstyler.Match(j, \"interface\") ||\n\t\t\t\tstyler.Match(j, \"package\") ||\n\t\t\t\tstyler.Match(j, \"primitive\") ||\n\t\t\t\tstyler.Match(j, \"program\") ||\n\t\t\t\tstyler.Match(j, \"sequence\") ||\n\t\t\t\tstyler.Match(j, \"specify\") ||\n\t\t\t\tstyler.Match(j, \"table\") ||\n\t\t\t\tstyler.Match(j, \"task\") ||\n\t\t\t\t(styler.Match(j, \"module\") && options.foldAtModule)) {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (styler.Match(j, \"begin\")) {\n\t\t\t\t// Measure the minimum before a begin to allow\n\t\t\t\t// folding on \"end else begin\"\n\t\t\t\tif (levelMinCurrent > levelNext) {\n\t\t\t\t\tlevelMinCurrent = levelNext;\n\t\t\t\t}\n\t\t\t\tlevelNext++;\n\t\t\t} else if (styler.Match(j, \"class\")) {\n\t\t\t\t// class does not introduce a block when used in a typedef statement\n\t\t\t\tif (!(stateCurrent & typedefFlag))\n\t\t\t\t\tlevelNext++;\n\t\t\t} else if (styler.Match(j, \"fork\")) {\n\t\t\t\t// fork does not introduce a block when used in a wait or disable statement\n\t\t\t\tif (stateCurrent & foldWaitDisableFlag) {\n\t\t\t\t\tstateCurrent &= ~foldWaitDisableFlag;\n\t\t\t\t} else\n\t\t\t\t\tlevelNext++;\n\t\t\t} else if (styler.Match(j, \"endcase\") ||\n\t\t\t\tstyler.Match(j, \"endclass\") ||\n\t\t\t\tstyler.Match(j, \"endfunction\") ||\n\t\t\t\tstyler.Match(j, \"endgenerate\") ||\n\t\t\t\tstyler.Match(j, \"endgroup\") ||\n\t\t\t\tstyler.Match(j, \"endinterface\") ||\n\t\t\t\tstyler.Match(j, \"endpackage\") ||\n\t\t\t\tstyler.Match(j, \"endprimitive\") ||\n\t\t\t\tstyler.Match(j, \"endprogram\") ||\n\t\t\t\tstyler.Match(j, \"endsequence\") ||\n\t\t\t\tstyler.Match(j, \"endspecify\") ||\n\t\t\t\tstyler.Match(j, \"endtable\") ||\n\t\t\t\tstyler.Match(j, \"endtask\") ||\n\t\t\t\tstyler.Match(j, \"join\") ||\n\t\t\t\tstyler.Match(j, \"join_any\") ||\n\t\t\t\tstyler.Match(j, \"join_none\") ||\n\t\t\t\t(styler.Match(j, \"endmodule\") && options.foldAtModule) ||\n\t\t\t\t(styler.Match(j, \"end\") && !IsAWordChar(styler.SafeGetCharAt(j + 3)))) {\n\t\t\t\tlevelNext--;\n\t\t\t} else if (styler.Match(j, \"extern\") ||\n\t\t\t\tstyler.Match(j, \"pure\")) {\n\t\t\t\t// extern and pure virtual functions/tasks are terminated by ';' not endfunction/endtask\n\t\t\t\tstateCurrent |= foldExternFlag;\n\t\t\t} else if (styler.Match(j, \"disable\") ||\n\t\t\t\tstyler.Match(j, \"wait\")) {\n\t\t\t\t// fork does not introduce a block when used in a wait or disable statement\n\t\t\t\tstateCurrent |= foldWaitDisableFlag;\n\t\t\t} else if (styler.Match(j, \"typedef\")) {\n\t\t\t\tstateCurrent |= typedefFlag;\n\t\t\t}\n\t\t}\n\t\tif (atEOL) {\n\t\t\tint levelUse = levelCurrent;\n\t\t\tif (options.foldAtElse||options.foldPreprocessorElse) {\n\t\t\t\tlevelUse = levelMinCurrent;\n\t\t\t}\n\t\t\tint lev = levelUse | levelNext << 16;\n\t\t\tif (visibleChars == 0 && options.foldCompact)\n\t\t\t\tlev |= SC_FOLDLEVELWHITEFLAG;\n\t\t\tif (levelUse < levelNext)\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\tif (stateCurrent) {\n\t\t\t\tfoldState[lineCurrent] = stateCurrent;\n\t\t\t}\n\t\t\tif (lev != styler.LevelAt(lineCurrent)) {\n\t\t\t\tstyler.SetLevel(lineCurrent, lev);\n\t\t\t}\n\t\t\tlineCurrent++;\n\t\t\tlevelCurrent = levelNext;\n\t\t\tlevelMinCurrent = levelCurrent;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tif (!isspacechar(ch))\n\t\t\tvisibleChars++;\n\t}\n}\n\nstd::vector<std::string> LexerVerilog::Tokenize(const std::string &expr) const {\n\t// Break into tokens\n\tstd::vector<std::string> tokens;\n\tconst char *cp = expr.c_str();\n\twhile (*cp) {\n\t\tstd::string word;\n\t\tif (setWord.Contains(static_cast<unsigned char>(*cp))) {\n\t\t\t// Identifiers and numbers\n\t\t\twhile (setWord.Contains(static_cast<unsigned char>(*cp))) {\n\t\t\t\tword += *cp;\n\t\t\t\tcp++;\n\t\t\t}\n\t\t} else if (IsSpaceOrTab(*cp)) {\n\t\t\twhile (IsSpaceOrTab(*cp)) {\n\t\t\t\tcp++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t} else {\n\t\t\t// Should handle strings, characters, and comments here\n\t\t\tword += *cp;\n\t\t\tcp++;\n\t\t}\n\t\ttokens.push_back(word);\n\t}\n\treturn tokens;\n}\n\nstatic const char * const verilogWordLists[] = {\n            \"Primary keywords and identifiers\",\n            \"Secondary keywords and identifiers\",\n            \"System Tasks\",\n            \"User defined tasks and identifiers\",\n            \"Documentation comment keywords\",\n            \"Preprocessor definitions\",\n            0,\n        };\n\nextern const LexerModule lmVerilog(SCLEX_VERILOG, LexerVerilog::LexerFactoryVerilog, \"verilog\", verilogWordLists);\n"
  },
  {
    "path": "lexers/LexVisualProlog.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexVisualProlog.cxx\n** Lexer for Visual Prolog.\n**/\n// Author Thomas Linder Puls, PDC A/S, http://www.visual-prolog.com\n// Based on Lexer for C++, C, Java, and JavaScript.\n// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// The line state contains:\n// In SCE_VISUALPROLOG_STRING: The closing quote and information about verbatim string.\n// and a stack of nesting kinds: comment, embedded (syntax) and (syntax) place holder\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n#ifdef _MSC_VER\n#pragma warning(disable: 4786)\n#endif\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <functional>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"CharacterCategory.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n// Options used for LexerVisualProlog\nstruct OptionsVisualProlog {\n    bool verbatimStrings;\n    bool backQuotedStrings;\n    OptionsVisualProlog() {\n        verbatimStrings = true;\n        backQuotedStrings = false;\n    }\n};\n\nstatic const char* const visualPrologWordLists[] = {\n    \"Major keywords (class, predicates, ...)\",\n    \"Minor keywords (if, then, try, ...)\",\n    \"Directive keywords without the '#' (include, requires, ...)\",\n    \"Documentation keywords without the '@' (short, detail, ...)\",\n    0,\n};\n\nstruct OptionSetVisualProlog : public OptionSet<OptionsVisualProlog> {\n    OptionSetVisualProlog() {\n        DefineProperty(\"lexer.visualprolog.verbatim.strings\", &OptionsVisualProlog::verbatimStrings,\n            \"Set to 0 to disable highlighting verbatim strings using '@'.\");\n        DefineProperty(\"lexer.visualprolog.backquoted.strings\", &OptionsVisualProlog::backQuotedStrings,\n            \"Set to 1 to enable using back quotes (``) to delimit strings.\");\n        DefineWordListSets(visualPrologWordLists);\n    }\n};\n\nLexicalClass lexicalClasses[] = {\n    0, \"SCE_VISUALPROLOG_DEFAULT\", \"default\", \"Default style\",\n    1, \"SCE_VISUALPROLOG_KEY_MAJOR\", \"keyword major\", \"Major keyword\",\n    2, \"SCE_VISUALPROLOG_KEY_MINOR\", \"keyword minor\", \"Minor keyword\",\n    3, \"SCE_VISUALPROLOG_KEY_DIRECTIVE\", \"keyword preprocessor\", \"Directove keyword\",\n    4, \"SCE_VISUALPROLOG_COMMENT_BLOCK\", \"comment\", \"Multiline comment /* */\",\n    5, \"SCE_VISUALPROLOG_COMMENT_LINE\", \"comment line\", \"Line comment % ...\",\n    6, \"SCE_VISUALPROLOG_COMMENT_KEY\", \"comment documentation keyword\", \"Doc keyword in comment % @short ...\",\n    7, \"SCE_VISUALPROLOG_COMMENT_KEY_ERROR\", \"comment\", \"A non recognized doc keyword % @qqq ...\",\n    8, \"SCE_VISUALPROLOG_IDENTIFIER\", \"identifier\", \"Identifier (black)\",\n    9, \"SCE_VISUALPROLOG_VARIABLE\", \"variable identifier\", \"Variable (green)\",\n    10, \"SCE_VISUALPROLOG_ANONYMOUS\", \"variable anonymous identifier\", \"Anonymous Variable _XXX (dimmed green)\",\n    11, \"SCE_VISUALPROLOG_NUMBER\", \"numeric\", \"Number\",\n    12, \"SCE_VISUALPROLOG_OPERATOR\", \"operator\", \"Operator\",\n    13, \"SCE_VISUALPROLOG_UNUSED1\", \"unused\", \"\",\n    14, \"SCE_VISUALPROLOG_UNUSED2\", \"unused\", \"\",\n    15, \"SCE_VISUALPROLOG_UNUSED3\", \"unused\", \"\",\n    16, \"SCE_VISUALPROLOG_STRING_QUOTE\", \"literal string quote\", \"Quotes surrounding string literals\",\n    17, \"SCE_VISUALPROLOG_STRING_ESCAPE\", \"literal string escapesequence\", \"Escape sequence in string literal\",\n    18, \"SCE_VISUALPROLOG_STRING_ESCAPE_ERROR\", \"error literal string escapesequence\", \"Error in escape sequence in string literal\",\n    19, \"SCE_VISUALPROLOG_UNUSED4\", \"unused\", \"\",\n    20, \"SCE_VISUALPROLOG_STRING\", \"literal string\", \"String literal\",\n    21, \"SCE_VISUALPROLOG_UNUSED5\", \"unused\", \"\",\n    22, \"SCE_VISUALPROLOG_STRING_EOL\", \"literal string multiline raw escapesequence\", \"Verbatim/multiline string literal EOL\",\n    23, \"SCE_VISUALPROLOG_EMBEDDED\", \"literal string embedded\", \"Embedded syntax [| ... |]\",\n    24, \"SCE_VISUALPROLOG_PLACEHOLDER\", \"operator embedded\", \"Syntax place holder {| ... |}:ident in embedded syntax\"\n};\n\nLexicalClass getLexicalClass(int style) {\n    for (auto lc : lexicalClasses) {\n        if (style == lc.value) {\n            return lc;\n        }\n    }\n    return {style, \"\", \"unused\", \"\"};\n}\n\n\nclass LexerVisualProlog : public DefaultLexer {\n    WordList majorKeywords;\n    WordList minorKeywords;\n    WordList directiveKeywords;\n    WordList docKeywords;\n    OptionsVisualProlog options;\n    OptionSetVisualProlog osVisualProlog;\npublic:\n    LexerVisualProlog() : DefaultLexer(\"visualprolog\", SCLEX_VISUALPROLOG) {\n    }\n    virtual ~LexerVisualProlog() {\n    }\n    void SCI_METHOD Release() override {\n        delete this;\n    }\n    int SCI_METHOD Version() const override {\n        return lvRelease5;\n    }\n    const char* SCI_METHOD PropertyNames() override {\n        return osVisualProlog.PropertyNames();\n    }\n    int SCI_METHOD PropertyType(const char* name) override {\n        return osVisualProlog.PropertyType(name);\n    }\n    const char* SCI_METHOD DescribeProperty(const char* name) override {\n        return osVisualProlog.DescribeProperty(name);\n    }\n    Sci_Position SCI_METHOD PropertySet(const char* key, const char* val) override;\n    const char* SCI_METHOD PropertyGet(const char* key) override {\n        return osVisualProlog.PropertyGet(key);\n    }\n    const char* SCI_METHOD DescribeWordListSets() override {\n        return osVisualProlog.DescribeWordListSets();\n    }\n    Sci_Position SCI_METHOD WordListSet(int n, const char* wl) override;\n    void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument* pAccess) override;\n    void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument* pAccess) override;\n\n    void* SCI_METHOD PrivateCall(int, void*) override {\n        return 0;\n    }\n\n    int SCI_METHOD NamedStyles() override {\n        int namedStyles = 0;\n        for (auto lc : lexicalClasses) {\n            if (namedStyles < lc.value) {\n                namedStyles = lc.value;\n            }\n        }\n        return namedStyles;\n    }\n    const char* SCI_METHOD NameOfStyle(int style) override {\n        return getLexicalClass(style).name;\n    }\n    const char* SCI_METHOD TagsOfStyle(int style) override {\n        return getLexicalClass(style).tags;\n    }\n    const char* SCI_METHOD DescriptionOfStyle(int style) override {\n        return getLexicalClass(style).description;\n    }\n\n    static ILexer5* LexerFactoryVisualProlog() {\n        return new LexerVisualProlog();\n    }\n};\n\nSci_Position SCI_METHOD LexerVisualProlog::PropertySet(const char* key, const char* val) {\n    if (osVisualProlog.PropertySet(&options, key, val)) {\n        return 0;\n    }\n    return -1;\n}\n\nSci_Position SCI_METHOD LexerVisualProlog::WordListSet(int n, const char* wl) {\n    WordList* wordListN = 0;\n    switch (n) {\n        case 0:\n            wordListN = &majorKeywords;\n            break;\n        case 1:\n            wordListN = &minorKeywords;\n            break;\n        case 2:\n            wordListN = &directiveKeywords;\n            break;\n        case 3:\n            wordListN = &docKeywords;\n            break;\n    }\n    Sci_Position firstModification = -1;\n    if (wordListN) {\n        WordList wlNew;\n        wlNew.Set(wl);\n        if (*wordListN != wlNew) {\n            wordListN->Set(wl);\n            firstModification = 0;\n        }\n    }\n    return firstModification;\n}\n\nstatic bool isLowerLetter(int ch) {\n    return ccLl == CategoriseCharacter(ch);\n}\n\nstatic bool isUpperLetter(int ch) {\n    return ccLu == CategoriseCharacter(ch);\n}\n\nstatic bool isAlphaNum(int ch) {\n    CharacterCategory cc = CategoriseCharacter(ch);\n    return (ccLu == cc || ccLl == cc || ccLt == cc || ccLm == cc || ccLo == cc || ccNd == cc || ccNl == cc || ccNo == cc);\n}\n\nstatic bool isStringVerbatimOpenClose(int ch) {\n    CharacterCategory cc = CategoriseCharacter(ch);\n    return (ccPc <= cc && cc <= ccSo);\n}\n\nstatic bool isIdChar(int ch) {\n    return ('_') == ch || isAlphaNum(ch);\n}\n\n// Look ahead to see which colour \"end\" should have (takes colour after the following keyword)\nstatic void endLookAhead(char s[], LexAccessor& styler, Sci_Position start) {\n    char ch = styler.SafeGetCharAt(start, '\\n');\n    while (' ' == ch) {\n        start++;\n        ch = styler.SafeGetCharAt(start, '\\n');\n    }\n    Sci_Position i = 0;\n    while (i < 100 && isLowerLetter(ch)) {\n        s[i] = ch;\n        i++;\n        ch = styler.SafeGetCharAt(start + i, '\\n');\n    }\n    s[i] = '\\0';\n}\n\n\nclass lineState {\npublic:\n    bool verbatim = false;\n    int closingQuote = 0;\n    int kindStack = 0;\n\n    bool isOpenStringVerbatim(int next) {\n        if (next > 0x7FFF) {\n            return false;\n        }\n        switch (next) {\n            case L'<':\n                closingQuote = L'>';\n                return true;\n            case L'>':\n                closingQuote = L'<';\n                return true;\n            case L'(':\n                closingQuote = L')';\n                return true;\n            case L')':\n                closingQuote = L'(';\n                return true;\n            case L'[':\n                closingQuote = L']';\n                return true;\n            case L']':\n                closingQuote = L'[';\n                return true;\n            case L'{':\n                closingQuote = L'}';\n                return true;\n            case L'}':\n                closingQuote = L'{';\n                return true;\n            case L'_':\n            case L'.':\n            case L',':\n            case L';':\n                return false;\n            default:\n                if (isStringVerbatimOpenClose(next)) {\n                    closingQuote = next;\n                    return true;\n                } else {\n                    return false;\n                }\n        }\n    }\n\n    enum kind {\n        none = 0,\n        comment = 1,\n        embedded = 2,\n        placeholder = 3\n    };\n\n    void setState(int state) {\n        verbatim = state >> 31;\n        closingQuote = state >> 16 & 0x7FFF;\n        kindStack = state & 0xFFFF;\n    }\n\n    int getState() {\n        return verbatim << 31 | closingQuote << 16 | (kindStack & 0xFFFF);\n    }\n\n    void enter(kind k) {\n        kindStack = kindStack << 2 | k;\n    }\n\n    void leave(kind k) {\n        if (k == currentKind()) {\n            kindStack = kindStack >> 2;\n        }\n    }\n    kind currentKind() {\n        return static_cast<kind>(kindStack & 0x3);\n    }\n    kind stateKind2(int ks) {\n        if (0 == ks) {\n            return none;\n        } else {\n            kind k1 = stateKind2(ks >> 2);\n            kind k2 = static_cast<kind>(ks & 0x3);\n            if (embedded == k1 && k2 == comment) {\n                return embedded;\n            } else {\n                return k2;\n            }\n        }\n    }\n    kind stateKind() {\n        return stateKind2(kindStack);\n    }\n};\n\nvoid SCI_METHOD LexerVisualProlog::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument* pAccess) {\n    LexAccessor styler(pAccess);\n    CharacterSet setDoxygen(CharacterSet::setAlpha, \"\");\n    CharacterSet setNumber(CharacterSet::setNone, \"0123456789abcdefABCDEFxoXO_\");\n\n    StyleContext sc(startPos, length, initStyle, styler, 0x7f);\n\n    int styleBeforeDocKeyword = SCE_VISUALPROLOG_DEFAULT;\n\n    lineState ls;\n    if (sc.currentLine >= 1) {\n        ls.setState(styler.GetLineState(sc.currentLine - 1));\n    }\n\n    bool newState = false;\n\n    for (; sc.More(); sc.Forward()) {\n\n        Sci_Position currentLineEntry = sc.currentLine;\n\n        if (newState) {\n            newState = false;\n            int state;\n            switch (ls.stateKind()) {\n                case lineState::comment:\n                    state = SCE_VISUALPROLOG_COMMENT_BLOCK;\n                    break;\n                case lineState::embedded:\n                    state = SCE_VISUALPROLOG_EMBEDDED;\n                    break;\n                case lineState::placeholder:\n                    state = SCE_VISUALPROLOG_PLACEHOLDER;\n                    break;\n                default:\n                    state = SCE_VISUALPROLOG_DEFAULT;\n                    break;\n            }\n            sc.SetState(state);\n        }\n\n        // Determine if the current state should terminate.\n        switch (sc.state) {\n            case SCE_VISUALPROLOG_OPERATOR:\n                sc.SetState(SCE_VISUALPROLOG_DEFAULT);\n                break;\n            case SCE_VISUALPROLOG_NUMBER:\n                // We accept almost anything because of hex, '.' and number suffixes\n                if (!(setNumber.Contains(sc.ch)) || (sc.Match('.') && IsADigit(sc.chNext))) {\n                    sc.SetState(SCE_VISUALPROLOG_DEFAULT);\n                }\n                break;\n            case SCE_VISUALPROLOG_IDENTIFIER:\n                if (!isIdChar(sc.ch)) {\n                    char s[1000];\n                    sc.GetCurrent(s, sizeof(s));\n                    if (0 == strcmp(s, \"end\")) {\n                        endLookAhead(s, styler, sc.currentPos);\n                    }\n                    if (majorKeywords.InList(s)) {\n                        sc.ChangeState(SCE_VISUALPROLOG_KEY_MAJOR);\n                    } else if (minorKeywords.InList(s)) {\n                        sc.ChangeState(SCE_VISUALPROLOG_KEY_MINOR);\n                    }\n                    sc.SetState(SCE_VISUALPROLOG_DEFAULT);\n                }\n                break;\n            case SCE_VISUALPROLOG_VARIABLE:\n            case SCE_VISUALPROLOG_ANONYMOUS:\n                if (!isIdChar(sc.ch)) {\n                    sc.SetState(SCE_VISUALPROLOG_DEFAULT);\n                }\n                break;\n            case SCE_VISUALPROLOG_KEY_DIRECTIVE:\n                if (!isLowerLetter(sc.ch)) {\n                    char s[1000];\n                    sc.GetCurrent(s, sizeof(s));\n                    if (!directiveKeywords.InList(s + 1)) {\n                        sc.ChangeState(SCE_VISUALPROLOG_IDENTIFIER);\n                    }\n                    sc.SetState(SCE_VISUALPROLOG_DEFAULT);\n                }\n                break;\n            case SCE_VISUALPROLOG_COMMENT_LINE:\n                if (sc.MatchLineEnd()) {\n                    int nextState = (lineState::comment == ls.currentKind()) ? SCE_VISUALPROLOG_COMMENT_BLOCK : SCE_VISUALPROLOG_DEFAULT;\n                    sc.SetState(nextState);\n                } else if (sc.Match('@')) {\n                    styleBeforeDocKeyword = SCE_VISUALPROLOG_COMMENT_LINE;\n                    sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR);\n                }\n                break;\n            case SCE_VISUALPROLOG_COMMENT_BLOCK:\n                if (sc.Match('*', '/')) {\n                    sc.Forward();\n                    ls.leave(lineState::comment);\n                    newState = true;\n                } else if (sc.Match('/', '*')) {\n                    sc.Forward();\n                    ls.enter(lineState::comment);\n                } else if (sc.Match('@')) {\n                    styleBeforeDocKeyword = SCE_VISUALPROLOG_COMMENT_BLOCK;\n                    sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR);\n                }\n                break;\n            case SCE_VISUALPROLOG_COMMENT_KEY_ERROR:\n                if (!setDoxygen.Contains(sc.ch) || sc.MatchLineEnd()) {\n                    char s[1000];\n                    sc.GetCurrent(s, sizeof(s));\n                    if (docKeywords.InList(s + 1)) {\n                        sc.ChangeState(SCE_VISUALPROLOG_COMMENT_KEY);\n                    }\n                    if (SCE_VISUALPROLOG_COMMENT_LINE == styleBeforeDocKeyword && sc.MatchLineEnd()) {\n                        // end line comment\n                        int nextState = (lineState::comment == ls.currentKind()) ? SCE_VISUALPROLOG_COMMENT_BLOCK : SCE_VISUALPROLOG_DEFAULT;\n                        sc.SetState(nextState);\n                    } else {\n                        sc.SetState(styleBeforeDocKeyword);\n                        if (SCE_VISUALPROLOG_COMMENT_BLOCK == styleBeforeDocKeyword && sc.Match('*', '/')) {\n                            // we have consumed the '*' if it comes immediately after the docKeyword\n                            sc.Forward();\n                            ls.leave(lineState::comment);\n                            newState = true;\n                        }\n                    }\n                }\n                break;\n            case SCE_VISUALPROLOG_STRING_ESCAPE_ERROR:\n                if (sc.atLineStart) {\n                    sc.SetState(SCE_VISUALPROLOG_DEFAULT);\n                    break;\n                }\n                [[fallthrough]];\n            case SCE_VISUALPROLOG_STRING_ESCAPE:\n            case SCE_VISUALPROLOG_STRING_QUOTE:\n            case SCE_VISUALPROLOG_STRING_EOL:\n                // return to SCE_VISUALPROLOG_STRING and treat as such (fallthrough)\n                sc.SetState(SCE_VISUALPROLOG_STRING);\n                [[fallthrough]];\n            case SCE_VISUALPROLOG_STRING:\n                if (sc.MatchLineEnd() | sc.atLineEnd) {\n                    if (ls.verbatim) {\n                        sc.SetState(SCE_VISUALPROLOG_STRING_EOL);\n                    } else {\n                        ls.closingQuote = 0;\n                        sc.SetState(SCE_VISUALPROLOG_STRING_ESCAPE_ERROR);\n                    }\n                } else if (sc.Match(ls.closingQuote)) {\n                    if (ls.verbatim && ls.closingQuote == sc.chNext) {\n                        sc.SetState(SCE_VISUALPROLOG_STRING_ESCAPE);\n                        sc.Forward();\n                    } else {\n                        ls.closingQuote = 0;\n                        sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);\n                        sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);\n                    }\n                } else if (!ls.verbatim && sc.Match('\\\\')) {\n                    sc.SetState(SCE_VISUALPROLOG_STRING_ESCAPE_ERROR);\n                    sc.Forward();\n                    if (sc.MatchLineEnd()) {\n                        sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);\n                    } else {\n                        if (sc.Match('\"') || sc.Match('\\'') || sc.Match('\\\\') || sc.Match('n') || sc.Match('l') || sc.Match('r') || sc.Match('t')) {\n                            sc.ChangeState(SCE_VISUALPROLOG_STRING_ESCAPE);\n                        } else if (sc.Match('u')) {\n                            if (IsADigit(sc.chNext, 16)) {\n                                sc.Forward();\n                                if (IsADigit(sc.chNext, 16)) {\n                                    sc.Forward();\n                                    if (IsADigit(sc.chNext, 16)) {\n                                        sc.Forward();\n                                        if (IsADigit(sc.chNext, 16)) {\n                                            sc.Forward();\n                                            sc.ChangeState(SCE_VISUALPROLOG_STRING_ESCAPE);\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n                break;\n            case SCE_VISUALPROLOG_EMBEDDED:\n                if (sc.Match('|', ']')) {\n                    sc.Forward();\n                    ls.leave(lineState::embedded);\n                    newState = true;\n                } else if (sc.Match('[', '|')) {\n                    sc.Forward();\n                    ls.enter(lineState::embedded);\n                } else if (sc.Match('{', '|') && lineState::comment != ls.currentKind()) {\n                    sc.SetState(SCE_VISUALPROLOG_DEFAULT);\n                } else if (sc.Match('/', '*')) {\n                    sc.Forward();\n                    ls.enter(lineState::comment);\n                } else if (sc.Match('*', '/')) {\n                    sc.Forward();\n                    ls.leave(lineState::comment);\n                    newState = true;\n                }\n                break;\n            case SCE_VISUALPROLOG_PLACEHOLDER:\n                if (lineState::embedded == ls.currentKind()) {\n                    sc.SetState(SCE_VISUALPROLOG_EMBEDDED);\n                } else {\n                    sc.SetState(SCE_VISUALPROLOG_DEFAULT);\n                }\n                break;\n        }\n\n        if (currentLineEntry != sc.currentLine) {\n            styler.SetLineState(currentLineEntry, ls.getState());\n        }\n        if (sc.MatchLineEnd() | sc.atLineEnd) {\n            if (sc.More()) { // currentLine can be outside the document \n                styler.SetLineState(sc.currentLine, ls.getState());\n            }\n        }\n\n        // Determine if a new state should be entered.\n        if (sc.state == SCE_VISUALPROLOG_DEFAULT) {\n            if (options.verbatimStrings && sc.Match('@') && ls.isOpenStringVerbatim(sc.chNext)) {\n                ls.verbatim = true;\n                sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);\n                sc.Forward();\n            } else if (IsADigit(sc.ch) || (sc.Match('.') && IsADigit(sc.chNext))) {\n                sc.SetState(SCE_VISUALPROLOG_NUMBER);\n            } else if (isLowerLetter(sc.ch)) {\n                sc.SetState(SCE_VISUALPROLOG_IDENTIFIER);\n            } else if (isUpperLetter(sc.ch)) {\n                sc.SetState(SCE_VISUALPROLOG_VARIABLE);\n            } else if (sc.Match('_')) {\n                sc.SetState(SCE_VISUALPROLOG_ANONYMOUS);\n            } else if (sc.Match('/', '*')) {\n                sc.SetState(SCE_VISUALPROLOG_COMMENT_BLOCK);\n                ls.enter(lineState::comment);\n                sc.Forward();\n            } else if (sc.Match('%')) {\n                sc.SetState(SCE_VISUALPROLOG_COMMENT_LINE);\n            } else if (sc.Match('[', '|')) {\n                sc.SetState(SCE_VISUALPROLOG_EMBEDDED);\n                ls.enter(lineState::embedded);\n                sc.Forward();\n            } else if (sc.Match('{', '|')) {\n                sc.SetState(SCE_VISUALPROLOG_PLACEHOLDER);\n                ls.enter(lineState::placeholder);\n                sc.Forward();\n            } else if (sc.Match('|', '}')) {\n                sc.SetState(SCE_VISUALPROLOG_PLACEHOLDER);\n                sc.Forward();\n                if (':' == sc.chNext) {\n                    sc.Forward();\n                    for (; isIdChar(sc.chNext); sc.Forward()) {\n                    }\n                }\n                ls.leave(lineState::placeholder);\n                newState = true;\n            } else if (sc.Match('\\'')) {\n                ls.verbatim = false;\n                ls.closingQuote = '\\'';\n                sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);\n            } else if (sc.Match('\"')) {\n                ls.verbatim = false;\n                ls.closingQuote = '\"';\n                sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);\n            } else if (options.backQuotedStrings && sc.Match('`')) {\n                ls.verbatim = false;\n                ls.closingQuote = '`';\n                sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);\n            } else if (sc.Match('#')) {\n                sc.SetState(SCE_VISUALPROLOG_KEY_DIRECTIVE);\n            } else if (isoperator(static_cast<char>(sc.ch)) || sc.Match('\\\\') ||\n                (!options.verbatimStrings && sc.Match('@'))) {\n                sc.SetState(SCE_VISUALPROLOG_OPERATOR);\n            }\n        }\n    }\n    sc.Complete();\n    styler.Flush();\n}\n\n// Store both the current line's fold level and the next lines in the\n// level store to make it easy to pick up with each increment\n// and to make it possible to fiddle the current level for \"} else {\".\n\n#if defined(__clang__)\n#if __has_warning(\"-Wunused-but-set-variable\")\n// Disable warning for visibleChars\n#pragma clang diagnostic ignored \"-Wunused-but-set-variable\"\n#endif\n#endif\n\nvoid SCI_METHOD LexerVisualProlog::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument* pAccess) {\n\n    LexAccessor styler(pAccess);\n\n    Sci_PositionU endPos = startPos + length;\n    int visibleChars = 0;\n    Sci_Position currentLine = styler.GetLine(startPos);\n    int levelCurrent = SC_FOLDLEVELBASE;\n    if (currentLine > 0)\n        levelCurrent = styler.LevelAt(currentLine - 1) >> 16;\n    int levelMinCurrent = levelCurrent;\n    int levelNext = levelCurrent;\n    char chNext = styler[startPos];\n    int styleNext = styler.StyleAt(startPos);\n    int style = initStyle;\n    for (Sci_PositionU i = startPos; i < endPos; i++) {\n        char ch = chNext;\n        chNext = styler.SafeGetCharAt(i + 1);\n        style = styleNext;\n        styleNext = styler.StyleAt(i + 1);\n        bool atEOL = (ch == '\\r' && chNext != '\\n') || (ch == '\\n');\n        if (style == SCE_VISUALPROLOG_OPERATOR) {\n            if (ch == '{') {\n                // Measure the minimum before a '{' to allow\n                // folding on \"} else {\"\n                if (levelMinCurrent > levelNext) {\n                    levelMinCurrent = levelNext;\n                }\n                levelNext++;\n            } else if (ch == '}') {\n                levelNext--;\n            }\n        }\n        if (!IsASpace(ch))\n            visibleChars++;\n        if (atEOL || (i == endPos - 1)) {\n            int levelUse = levelCurrent;\n            int lev = levelUse | levelNext << 16;\n            if (levelUse < levelNext)\n                lev |= SC_FOLDLEVELHEADERFLAG;\n            if (lev != styler.LevelAt(currentLine)) {\n                styler.SetLevel(currentLine, lev);\n            }\n            currentLine++;\n            levelCurrent = levelNext;\n            levelMinCurrent = levelCurrent;\n            if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length() - 1))) {\n                // There is an empty line at end of file so give it same level and empty\n                styler.SetLevel(currentLine, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);\n            }\n            visibleChars = 0;\n        }\n    }\n}\n}\n\nextern const LexerModule lmVisualProlog(SCLEX_VISUALPROLOG, LexerVisualProlog::LexerFactoryVisualProlog, \"visualprolog\", visualPrologWordLists);\n"
  },
  {
    "path": "lexers/LexX12.cxx",
    "content": "// Scintilla Lexer for X12\n// @file LexX12.cxx\n// Written by Iain Clarke, IMCSoft & Inobiz AB.\n// X12 official documentation is behind a paywall, but there's a description of the syntax here:\n// http://www.rawlinsecconsulting.com/x12tutorial/x12syn.html\n// This code is subject to the same license terms as the rest of the scintilla project:\n// The License.txt file describes the conditions under which this software may be distributed.\n//\n\n// Header order must match order in scripts/HeaderOrder.txt\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n\n#include <string>\n#include <string_view>\n\n#include <vector>\n#include <algorithm>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n#include \"LexerModule.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nclass LexerX12 : public DefaultLexer\n{\npublic:\n\tLexerX12();\n\tvirtual ~LexerX12() {} // virtual destructor, as we inherit from ILexer\n\n\tstatic ILexer5 *Factory() {\n\t\treturn new LexerX12;\n\t}\n\n\tint SCI_METHOD Version() const override\n\t{\n\t\treturn lvRelease5;\n\t}\n\tvoid SCI_METHOD Release() override\n\t{\n\t\tdelete this;\n\t}\n\n\tconst char * SCI_METHOD PropertyNames() override\n\t{\n\t\treturn \"fold\";\n\t}\n\tint SCI_METHOD PropertyType(const char *) override\n\t{\n\t\treturn SC_TYPE_BOOLEAN; // Only one property!\n\t}\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override\n\t{\n\t\tif (!strcmp(name, \"fold\"))\n\t\t\treturn \"Whether to apply folding to document or not\";\n\t\treturn \"\";\n\t}\n\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override\n\t{\n\t\tif (!strcmp(key, \"fold\"))\n\t\t{\n\t\t\tm_bFold = strcmp(val, \"0\") ? true : false;\n\t\t\treturn 0;\n\t\t}\n\t\treturn -1;\n\t}\n\tconst char * SCI_METHOD PropertyGet(const char *) override {\n\t\treturn \"\";\n\t}\n\tconst char * SCI_METHOD DescribeWordListSets() override\n\t{\n\t\treturn \"\";\n\t}\n\tSci_Position SCI_METHOD WordListSet(int, const char *) override\n\t{\n\t\treturn -1;\n\t}\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid * SCI_METHOD PrivateCall(int, void *) override\n\t{\n\t\treturn NULL;\n\t}\n\nprotected:\n\tstruct Terminator\n\t{\n\t\tint Style = SCE_X12_BAD;\n\t\tSci_PositionU pos = 0;\n\t\tSci_PositionU length = 0;\n\t\tint FoldChange = 0;\n\t};\n\tTerminator InitialiseFromISA(IDocument *pAccess);\n\tSci_PositionU FindPreviousSegmentStart(IDocument *pAccess, Sci_Position startPos) const;\n\tTerminator DetectSegmentHeader(IDocument *pAccess, Sci_PositionU pos) const;\n\tTerminator FindNextTerminator(IDocument *pAccess, Sci_PositionU pos, bool bJustSegmentTerminator = false) const;\n\n\tbool m_bFold = false;\n\tchar m_SeparatorSubElement = 0;\n\tchar m_SeparatorElement = 0;\n\tstd::string m_SeparatorSegment; // might be multiple characters\n\tstd::string m_LineFeed;\n};\n\nextern const LexerModule lmX12(SCLEX_X12, LexerX12::Factory, \"x12\");\n\n///////////////////////////////////////////////////////////////////////////////\n\n\n\n///////////////////////////////////////////////////////////////////////////////\n\nLexerX12::LexerX12() : DefaultLexer(\"x12\", SCLEX_X12)\n{\n}\n\nvoid LexerX12::Lex(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess)\n{\n\tSci_PositionU posFinish = startPos + length;\n\n\tTerminator T = InitialiseFromISA(pAccess);\n\n\tif (T.Style == SCE_X12_BAD)\n\t{\n\t\tif (T.pos < startPos)\n\t\t\tT.pos = startPos; // we may be colouring in batches.\n\t\tpAccess->StartStyling(startPos);\n\t\tpAccess->SetStyleFor(T.pos - startPos, SCE_X12_ENVELOPE);\n\t\tpAccess->SetStyleFor(posFinish - T.pos, SCE_X12_BAD);\n\t\treturn;\n\t}\n\n\t// Look backwards for a segment start or a document beginning\n\tSci_PositionU posCurrent = FindPreviousSegmentStart (pAccess, startPos);\n\n\t// Style buffer, so we're not issuing loads of notifications\n\tpAccess->StartStyling(posCurrent);\n\n\twhile (posCurrent < posFinish)\n\t{\n\t\t// Look for first element marker, so we can denote segment\n\t\tT = DetectSegmentHeader(pAccess, posCurrent);\n\t\tif (T.Style == SCE_X12_BAD)\n\t\t\tbreak;\n\n\t\tpAccess->SetStyleFor(T.pos - posCurrent, T.Style);\n\t\tpAccess->SetStyleFor(T.length, SCE_X12_SEP_ELEMENT);\n\t\tposCurrent = T.pos + T.length;\n\n\t\twhile (T.Style != SCE_X12_BAD && T.Style != SCE_X12_SEGMENTEND) // Break on bad or segment ending\n\t\t{\n\t\t\tT = FindNextTerminator(pAccess, posCurrent, false);\n\t\t\tif (T.Style == SCE_X12_BAD)\n\t\t\t\tbreak;\n\n\t\t\tint Style = T.Style;\n\n\t\t\tpAccess->SetStyleFor(T.pos - posCurrent, SCE_X12_DEFAULT);\n\t\t\tpAccess->SetStyleFor(T.length, Style);\n\t\t\tposCurrent = T.pos + T.length;\n\t\t}\n\t\tif (T.Style == SCE_X12_BAD)\n\t\t\tbreak;\n\t}\n\n\tpAccess->SetStyleFor(posFinish - posCurrent, SCE_X12_BAD);\n}\n\nvoid LexerX12::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess)\n{\n\tif (!m_bFold)\n\t\treturn;\n\n\t// Are we even foldable?\n\t// check for cr,lf,cr+lf.\n\tif (m_LineFeed.empty())\n\t\treturn;\n\n\tSci_PositionU posFinish = startPos + length;\n\n\t// Look backwards for a segment start or a document beginning\n\tstartPos = FindPreviousSegmentStart(pAccess, startPos);\n\tTerminator T;\n\n\tSci_PositionU currLine = pAccess->LineFromPosition(startPos);\n\tint levelCurrentStyle = SC_FOLDLEVELBASE;\n\tint indentCurrent = 0;\n\tif (currLine > 0)\n\t{\n\t\tlevelCurrentStyle = pAccess->GetLevel(currLine - 1); // bottom 12 bits are level\n\t\tindentCurrent = levelCurrentStyle & (SC_FOLDLEVELBASE - 1); // indent from previous line\n\t\tSci_PositionU posLine = pAccess->LineStart(currLine - 1);\n\t\tT = DetectSegmentHeader(pAccess, posLine);\n\t\tindentCurrent += T.FoldChange;\n\t}\n\n\twhile (startPos < posFinish)\n\t{\n\t\tT = DetectSegmentHeader(pAccess, startPos);\n\t\tint indentNext = indentCurrent + T.FoldChange;\n\t\tif (indentNext < 0)\n\t\t\tindentNext = 0;\n\n\t\tlevelCurrentStyle = (T.FoldChange > 0) ? (SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG) : SC_FOLDLEVELBASE;\n\n\t\tcurrLine = pAccess->LineFromPosition(startPos);\n\t\tpAccess->SetLevel(currLine, levelCurrentStyle | indentCurrent);\n\n\t\tT = FindNextTerminator(pAccess, startPos, true);\n\n\t\tif (T.Style == SCE_X12_BAD)\n\t\t\tbreak;\n\n\t\tstartPos = T.pos + T.length;\n\t\tindentCurrent = indentNext;\n\t}\n}\n\nLexerX12::Terminator LexerX12::InitialiseFromISA(IDocument *pAccess)\n{\n\tSci_Position length = pAccess->Length();\n\tif (length <= 108)\n\t\treturn { SCE_X12_BAD, 0 };\n\n\tpAccess->GetCharRange(&m_SeparatorElement, 3, 1);\n\tpAccess->GetCharRange(&m_SeparatorSubElement, 104, 1);\n\n\t// Look for GS, as that's the next segment. Anything between 105 and GS/IEA is our segment separator.\n\tSci_Position posNextSegment;\n\tchar bufSegment[3] = { 0 };\n\tfor (posNextSegment = 105; posNextSegment < length - 3; posNextSegment++)\n\t{\n\t\tpAccess->GetCharRange(bufSegment, posNextSegment, 3);\n\t\tif (!memcmp (bufSegment, \"GS\", 2) || !memcmp(bufSegment, \"IEA\", 3))\n\t\t{\n\t\t\tm_SeparatorSegment.resize(posNextSegment - 105);\n\t\t\tpAccess->GetCharRange(&m_SeparatorSegment.at(0), 105, posNextSegment - 105);\n\n\t\t\t// Is some of that CR+LF?\n\t\t\tsize_t nPos = m_SeparatorSegment.find_last_not_of(\"\\r\\n\");\n\t\t\tm_LineFeed = m_SeparatorSegment.substr(nPos + 1);\n\t\t\tm_SeparatorSegment = m_SeparatorSegment.substr(0, nPos + 1);\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (m_SeparatorSegment.empty() && m_LineFeed.empty())\n\t{\n\t\treturn { SCE_X12_BAD, 105 };\n\t}\n\n\t// Validate we have an element separator, and it's not silly!\n\tif (m_SeparatorElement == '\\0' || m_SeparatorElement == '\\n' || m_SeparatorElement == '\\r')\n\t\treturn { SCE_X12_BAD, 3 };\n\n\t// Validate we have an element separator, and it's not silly!\n\tif (m_SeparatorSubElement == '\\0' || m_SeparatorSubElement == '\\n' || m_SeparatorSubElement == '\\r')\n\t\treturn { SCE_X12_BAD, 103 };\n\tif (m_SeparatorElement == m_SeparatorSubElement)\n\t\treturn { SCE_X12_BAD, 104 };\n\tfor (auto& c : m_SeparatorSegment)\n\t{\n\t\tif (m_SeparatorElement == c)\n\t\t\treturn { SCE_X12_BAD, 105 };\n\t\tif (m_SeparatorSubElement == c)\n\t\t\treturn { SCE_X12_BAD, 105 };\n\t}\n\n\t// Check we have element markers at all the right places! ISA element has fixed entries.\n\tstd::vector<Sci_PositionU> ElementMarkers = { 3, 6, 17, 20, 31, 34, 50, 53, 69, 76, 81, 83, 89, 99, 101, 103 };\n\tfor (auto i : ElementMarkers)\n\t{\n\t\tchar c;\n\t\tpAccess->GetCharRange(&c, i, 1);\n\t\tif (c != m_SeparatorElement)\n\t\t\treturn { SCE_X12_BAD, i };\n\t}\n\t// Check we have no element markers anywhere else!\n\tfor (Sci_PositionU i = 0; i < 105; i++)\n\t{\n\t\tif (std::find(ElementMarkers.begin(), ElementMarkers.end(), i) != ElementMarkers.end())\n\t\t\tcontinue;\n\n\t\tchar c;\n\t\tpAccess->GetCharRange(&c, i, 1);\n\t\tif (c == m_SeparatorElement)\n\t\t\treturn { SCE_X12_BAD, i };\n\t}\n\n\treturn { SCE_X12_ENVELOPE };\n}\n\nSci_PositionU LexerX12::FindPreviousSegmentStart(IDocument *pAccess, Sci_Position startPos) const\n{\n\tSci_PositionU length = pAccess->Length();\n\tstd::string bufTest = m_SeparatorSegment + m_LineFeed; // quick way of making the lengths the same\n\tstd::string bufCompare = bufTest;\n\n\tfor (; startPos > 0; startPos--)\n\t{\n\t\tif (startPos + bufTest.size() > length)\n\t\t\tcontinue;\n\n\t\tpAccess->GetCharRange(&bufTest.at(0), startPos, bufTest.size());\n\t\tif (bufTest == bufCompare)\n\t\t{\n\t\t\treturn startPos + bufTest.size();\n\t\t}\n\t}\n\t// We didn't find a ', so just go with the beginning\n\treturn 0;\n}\n\nLexerX12::Terminator LexerX12::DetectSegmentHeader(IDocument *pAccess, Sci_PositionU pos) const\n{\n\tSci_PositionU Length = pAccess->Length();\n\tLength -= pos;\n\tchar c, Buf[4] = { 0 }; // max 3 + separator\n\tfor (Sci_PositionU posOffset = 0; posOffset < std::size(Buf) && posOffset < Length; posOffset++)\n\t{\n\t\tpAccess->GetCharRange(&c, pos + posOffset, 1);\n\t\tif (c != m_SeparatorElement)\n\t\t{\n\t\t\tBuf[posOffset] = c;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// check for special segments, involved in folding start/stop.\n\t\tif (memcmp(Buf, \"ISA\", 3) == 0)\n\t\t\treturn { SCE_X12_ENVELOPE, pos + posOffset, 1, +1 };\n\t\tif (memcmp(Buf, \"IEA\", 3) == 0)\n\t\t\treturn { SCE_X12_ENVELOPE, pos + posOffset, 1, -1 };\n\t\tif (memcmp(Buf, \"GS\", 2) == 0)\n\t\t\treturn { SCE_X12_FUNCTIONGROUP, pos + posOffset, 1, +1 };\n\t\tif (memcmp(Buf, \"GE\", 2) == 0)\n\t\t\treturn { SCE_X12_FUNCTIONGROUP, pos + posOffset, 1, -1 };\n\t\tif (memcmp(Buf, \"ST\", 2) == 0)\n\t\t\treturn { SCE_X12_TRANSACTIONSET, pos + posOffset, 1, +1 };\n\t\tif (memcmp(Buf, \"SE\", 2) == 0)\n\t\t\treturn { SCE_X12_TRANSACTIONSET, pos + posOffset, 1, -1 };\n\t\treturn { SCE_X12_SEGMENTHEADER, pos + posOffset, 1, 0 };\n\t}\n\treturn { SCE_X12_BAD, pos, 0, 0 };\n}\n\nLexerX12::Terminator LexerX12::FindNextTerminator(IDocument *pAccess, Sci_PositionU pos, bool bJustSegmentTerminator) const\n{\n\tchar c;\n\tSci_PositionU length = pAccess->Length();\n\tstd::string bufTestSegment = m_SeparatorSegment; // quick way of making the lengths the same\n\tstd::string bufTestLineFeed = m_LineFeed; // quick way of making the lengths the same\n\n\n\twhile (pos < (Sci_PositionU)length)\n\t{\n\t\tpAccess->GetCharRange(&c, pos, 1);\n\t\tif (pos + m_SeparatorSegment.size() > length)\n\t\t\tbufTestSegment.clear(); // going up - so once we can't get this, we're done with the buffer.\n\t\telse if (!bufTestSegment.empty())\n\t\t\tpAccess->GetCharRange(&bufTestSegment.at(0), pos, bufTestSegment.size());\n\t\tif (pos + m_LineFeed.size() > length)\n\t\t\tbufTestLineFeed.clear(); // going up - so once we can't get this, we're done with the buffer.\n\t\telse if (!bufTestLineFeed.empty())\n\t\t\tpAccess->GetCharRange(&bufTestLineFeed.at(0), pos, bufTestLineFeed.size());\n\n\t\tif (!bJustSegmentTerminator && c == m_SeparatorElement)\n\t\t\treturn { SCE_X12_SEP_ELEMENT, pos, 1 };\n\t\telse if (!bJustSegmentTerminator && c == m_SeparatorSubElement)\n\t\t\treturn { SCE_X12_SEP_SUBELEMENT, pos, 1 };\n\t\telse if (!m_SeparatorSegment.empty() && bufTestSegment == m_SeparatorSegment)\n\t\t{\n\t\t\tif (m_LineFeed.empty())\n\t\t\t\treturn { SCE_X12_SEGMENTEND, pos, m_SeparatorSegment.size() };\n\t\t\t// is this the end?\n\t\t\tif (pos + m_SeparatorSegment.size() == length)\n\t\t\t\treturn { SCE_X12_SEGMENTEND, pos, m_SeparatorSegment.size() };\n\t\t\t// Check if we're followed by a linefeed.\n\t\t\tif (pos + m_SeparatorSegment.size() + m_LineFeed.size() > length)\n\t\t\t\treturn { SCE_X12_BAD, pos };\n\t\t\tbufTestSegment = m_LineFeed;\n\t\t\tpAccess->GetCharRange(&bufTestSegment.at(0), pos + m_SeparatorSegment.size(), bufTestSegment.size());\n\t\t\tif (bufTestSegment == m_LineFeed)\n\t\t\t\treturn { SCE_X12_SEGMENTEND, pos, m_SeparatorSegment.size() + m_LineFeed.size() };\n\t\t\tbreak;\n\t\t}\n\t\telse if (m_SeparatorSegment.empty() && bufTestLineFeed == m_LineFeed)\n\t\t{\n\t\t\treturn { SCE_X12_SEGMENTEND, pos, m_LineFeed.size() };\n\t\t}\n\t\tpos++;\n\t}\n\n\treturn { SCE_X12_BAD, pos };\n}\n"
  },
  {
    "path": "lexers/LexYAML.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexYAML.cxx\n ** Lexer for YAML.\n **/\n// Copyright 2003- by Sean O'Dell <sean@celsoft.com>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n#include <cstdio>\n#include <cstdarg>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\nconst char * const yamlWordListDesc[] = {\n\t\"Keywords\",\n\tnullptr\n};\n\ninline bool AtEOL(Accessor &styler, Sci_PositionU i) {\n\treturn (styler[i] == '\\n') ||\n\t\t((styler[i] == '\\r') && (styler.SafeGetCharAt(i + 1) != '\\n'));\n}\n\n/**\n * Check for space, tab, line feed, or carriage return.\n * See YAML 1.2 spec sections 5.4. Line Break Characters and 5.5. White Space Characters.\n */\nconstexpr bool IsWhiteSpaceOrEOL(char ch) noexcept {\n\treturn ch == ' ' || ch == '\\t' || ch == '\\n' || ch == '\\r';\n}\n\nunsigned int SpaceCount(const char* lineBuffer) noexcept {\n\tif (lineBuffer == nullptr)\n\t\treturn 0;\n\n\tconst char* headBuffer = lineBuffer;\n\n\twhile (*headBuffer == ' ')\n\t\theadBuffer++;\n\n\treturn static_cast<unsigned int>(headBuffer - lineBuffer);\n}\n\nbool KeywordAtChar(const char* lineBuffer, const char* startComment, const WordList &keywords) noexcept {\n\tif (lineBuffer == nullptr || startComment <= lineBuffer)\n\t\treturn false;\n\tconst char* endValue = startComment - 1;\n\twhile (endValue >= lineBuffer && *endValue == ' ')\n\t\tendValue--;\n\tSci_PositionU len = static_cast<Sci_PositionU>(endValue - lineBuffer) + 1;\n\tchar s[100];\n\tif (len > (sizeof(s) / sizeof(s[0]) - 1))\n\t\treturn false;\n\tstrncpy(s, lineBuffer, len);\n\ts[len] = '\\0';\n\treturn (keywords.InList(s));\n}\n\n#define YAML_STATE_BITSIZE\t\t16\n#define YAML_STATE_MASK\t\t\t(0xFFFF0000)\n#define YAML_STATE_DOCUMENT\t\t(1 << YAML_STATE_BITSIZE)\n#define YAML_STATE_VALUE\t\t(2 << YAML_STATE_BITSIZE)\n#define YAML_STATE_COMMENT\t\t(3 << YAML_STATE_BITSIZE)\n#define YAML_STATE_TEXT_PARENT\t(4 << YAML_STATE_BITSIZE)\n#define YAML_STATE_TEXT\t\t\t(5 << YAML_STATE_BITSIZE)\n\nvoid ColouriseYAMLLine(\n\tchar *lineBuffer,\n\tSci_PositionU currentLine,\n\tSci_PositionU lengthLine,\n\tSci_PositionU startLine,\n\tSci_PositionU endPos,\n\tconst WordList &keywords,\n\tAccessor &styler) {\n\n\tSci_PositionU i = 0;\n\tbool bInQuotes = false;\n\tconst unsigned int indentAmount = SpaceCount(lineBuffer);\n\n\tif (currentLine > 0) {\n\t\tconst int parentLineState = styler.GetLineState(currentLine - 1);\n\n\t\tif ((parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT || (parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT_PARENT) {\n\t\t\tconst unsigned int parentIndentAmount = parentLineState&(~YAML_STATE_MASK);\n\t\t\tif (indentAmount > parentIndentAmount) {\n\t\t\t\tstyler.SetLineState(currentLine, YAML_STATE_TEXT | parentIndentAmount);\n\t\t\t\tstyler.ColourTo(endPos, SCE_YAML_TEXT);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\tstyler.SetLineState(currentLine, 0);\n\tif (strncmp(lineBuffer, \"---\", 3) == 0 || strncmp(lineBuffer, \"...\", 3) == 0) {\t// Document marker\n\t\tstyler.SetLineState(currentLine, YAML_STATE_DOCUMENT);\n\t\tstyler.ColourTo(endPos, SCE_YAML_DOCUMENT);\n\t\treturn;\n\t}\n\t// Skip initial spaces\n\twhile ((i < lengthLine) && lineBuffer[i] == ' ') { // YAML always uses space, never TABS or anything else\n\t\ti++;\n\t}\n\tif (lineBuffer[i] == '\\t') { // if we skipped all spaces, and we are NOT inside a text block, this is wrong\n\t\tstyler.ColourTo(endPos, SCE_YAML_ERROR);\n\t\treturn;\n\t}\n\tif (lineBuffer[i] == '#') {\t// Comment\n\t\tstyler.SetLineState(currentLine, YAML_STATE_COMMENT);\n\t\tstyler.ColourTo(endPos, SCE_YAML_COMMENT);\n\t\treturn;\n\t}\n\twhile (i < lengthLine) {\n\t\tif (lineBuffer[i] == '\\'' || lineBuffer[i] == '\\\"') {\n\t\t\tbInQuotes = !bInQuotes;\n\t\t} else if (lineBuffer[i] == '#' && isspacechar(lineBuffer[i - 1]) && !bInQuotes) {\n\t\t\tstyler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT);\n\t\t\tstyler.ColourTo(endPos, SCE_YAML_COMMENT);\n\t\t\treturn;\n\t\t} else if (lineBuffer[i] == ':' && !bInQuotes && (IsWhiteSpaceOrEOL(lineBuffer[i + 1]) || i == lengthLine - 1)) {\n\t\t\tstyler.ColourTo(startLine + i - 1, SCE_YAML_IDENTIFIER);\n\t\t\tstyler.ColourTo(startLine + i, SCE_YAML_OPERATOR);\n\t\t\t// Non-folding scalar\n\t\t\ti++;\n\t\t\twhile ((i < lengthLine) && isspacechar(lineBuffer[i]))\n\t\t\t\ti++;\n\t\t\tSci_PositionU endValue = lengthLine - 1;\n\t\t\twhile ((endValue >= i) && isspacechar(lineBuffer[endValue]))\n\t\t\t\tendValue--;\n\t\t\tlineBuffer[endValue + 1] = '\\0';\n\t\t\tif (lineBuffer[i] == '|' || lineBuffer[i] == '>') {\n\t\t\t\ti++;\n\t\t\t\tif (lineBuffer[i] == '+' || lineBuffer[i] == '-')\n\t\t\t\t\ti++;\n\t\t\t\twhile ((i < lengthLine) && isspacechar(lineBuffer[i]))\n\t\t\t\t\ti++;\n\t\t\t\tif (lineBuffer[i] == '\\0') {\n\t\t\t\t\tstyler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount);\n\t\t\t\t\tstyler.ColourTo(endPos, SCE_YAML_DEFAULT);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (lineBuffer[i] == '#') {\n\t\t\t\t\tstyler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount);\n\t\t\t\t\tstyler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT);\n\t\t\t\t\tstyler.ColourTo(endPos, SCE_YAML_COMMENT);\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tstyler.ColourTo(endPos, SCE_YAML_ERROR);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (lineBuffer[i] == '#') {\n\t\t\t\tstyler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT);\n\t\t\t\tstyler.ColourTo(endPos, SCE_YAML_COMMENT);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tSci_PositionU startComment = i;\n\t\t\tbInQuotes = false;\n\t\t\twhile (startComment < lengthLine) { // Comment must be space padded\n\t\t\t\tif (lineBuffer[startComment] == '\\'' || lineBuffer[startComment] == '\\\"')\n\t\t\t\t\tbInQuotes = !bInQuotes;\n\t\t\t\tif (lineBuffer[startComment] == '#' && isspacechar(lineBuffer[startComment - 1]) && !bInQuotes)\n\t\t\t\t\tbreak;\n\t\t\t\tstartComment++;\n\t\t\t}\n\t\t\tstyler.SetLineState(currentLine, YAML_STATE_VALUE);\n\t\t\tif (lineBuffer[i] == '&' || lineBuffer[i] == '*') {\n\t\t\t\tstyler.ColourTo(startLine + startComment - 1, SCE_YAML_REFERENCE);\n\t\t\t\tif (startComment < lengthLine)\n\t\t\t\t\tstyler.ColourTo(endPos, SCE_YAML_COMMENT);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (KeywordAtChar(&lineBuffer[i], &lineBuffer[startComment], keywords)) { // Convertible value (true/false, etc.)\n\t\t\t\tstyler.ColourTo(startLine + startComment - 1, SCE_YAML_KEYWORD);\n\t\t\t\tif (startComment < lengthLine)\n\t\t\t\t\tstyler.ColourTo(endPos, SCE_YAML_COMMENT);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst Sci_PositionU i2 = i;\n\t\t\twhile ((i < startComment) && lineBuffer[i]) {\n\t\t\t\tif (!(IsASCII(lineBuffer[i]) && isdigit(lineBuffer[i])) && lineBuffer[i] != '-'\n\t\t\t\t        && lineBuffer[i] != '.' && lineBuffer[i] != ',' && lineBuffer[i] != ' ') {\n\t\t\t\t\tstyler.ColourTo(startLine + startComment - 1, SCE_YAML_DEFAULT);\n\t\t\t\t\tif (startComment < lengthLine)\n\t\t\t\t\t\tstyler.ColourTo(endPos, SCE_YAML_COMMENT);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tif (i > i2) {\n\t\t\t\tstyler.ColourTo(startLine + startComment - 1, SCE_YAML_NUMBER);\n\t\t\t\tif (startComment < lengthLine)\n\t\t\t\t\tstyler.ColourTo(endPos, SCE_YAML_COMMENT);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tbreak; // shouldn't get here, but just in case, the rest of the line is coloured the default\n\t\t}\n\t\ti++;\n\t}\n\tstyler.ColourTo(endPos, SCE_YAML_DEFAULT);\n}\n\nvoid ColouriseYAMLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler) {\n\tstd::string lineBuffer;\n\tstyler.StartAt(startPos);\n\tstyler.StartSegment(startPos);\n\tSci_PositionU startLine = startPos;\n\tconst Sci_PositionU endPos = startPos + length;\n\tconst Sci_PositionU maxPos = styler.Length();\n\tSci_PositionU lineCurrent = styler.GetLine(startPos);\n\n\tfor (Sci_PositionU i = startPos; i < maxPos && i < endPos; i++) {\n\t\tlineBuffer.push_back(styler[i]);\n\t\tif (AtEOL(styler, i)) {\n\t\t\t// End of line (or of line buffer) met, colourise it\n\t\t\tColouriseYAMLLine(lineBuffer.data(), lineCurrent, lineBuffer.length(), startLine, i, *keywordLists[0], styler);\n\t\t\tlineBuffer.clear();\n\t\t\tstartLine = i + 1;\n\t\t\tlineCurrent++;\n\t\t}\n\t}\n\tif (!lineBuffer.empty()) {\t// Last line does not have ending characters\n\t\tColouriseYAMLLine(lineBuffer.data(), lineCurrent, lineBuffer.length(), startLine, startPos + length - 1, *keywordLists[0], styler);\n\t}\n}\n\nbool IsCommentLine(Sci_Position line, Accessor &styler) {\n\tconst Sci_Position pos = styler.LineStart(line);\n\tif (styler[pos] == '#')\n\t\treturn true;\n\treturn false;\n}\n\nvoid FoldYAMLDoc(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/,\n                      WordList *[], Accessor &styler) {\n\tconst Sci_Position maxPos = startPos + length;\n\tconst Sci_Position maxLines = styler.GetLine(maxPos - 1);             // Requested last line\n\tconst Sci_Position docLines = styler.GetLine(styler.Length() - 1);  // Available last line\n\n\t// property fold.comment.yaml\n\t// Set to 1 to allow folding of comment blocks in YAML.\n\tconst bool foldComment = styler.GetPropertyInt(\"fold.comment.yaml\") != 0;\n\n\t// Backtrack to previous non-blank line so we can determine indent level\n\t// for any white space lines\n\t// and so we can fix any preceding fold level (which is why we go back\n\t// at least one line in all cases)\n\tint spaceFlags = 0;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\tint indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);\n\twhile (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tindentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);\n\t\tif (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&\n\t\t        (!IsCommentLine(lineCurrent, styler)))\n\t\t\tbreak;\n\t}\n\tint indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\n\t// Set up initial loop state\n\tint prevComment = 0;\n\tif (lineCurrent >= 1)\n\t\tprevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);\n\n\t// Process all characters to end of requested range\n\t// or comment that hangs over the end of the range.  Cap processing in all cases\n\t// to end of document (in case of unclosed comment at end).\n\twhile ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) {\n\n\t\t// Gather info\n\t\tint lev = indentCurrent;\n\t\tSci_Position lineNext = lineCurrent + 1;\n\t\tint indentNext = indentCurrent;\n\t\tif (lineNext <= docLines) {\n\t\t\t// Information about next line is only available if not at end of document\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);\n\t\t}\n\t\tconst int comment = foldComment && IsCommentLine(lineCurrent, styler);\n\t\tconst int comment_start = (comment && !prevComment && (lineNext <= docLines) &&\n\t\t                           IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));\n\t\tconst int comment_continue = (comment && prevComment);\n\t\tif (!comment)\n\t\t\tindentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;\n\t\tif (indentNext & SC_FOLDLEVELWHITEFLAG)\n\t\t\tindentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;\n\n\t\tif (comment_start) {\n\t\t\t// Place fold point at start of a block of comments\n\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t} else if (comment_continue) {\n\t\t\t// Add level to rest of lines in the block\n\t\t\tlev = lev + 1;\n\t\t}\n\n\t\t// Skip past any blank lines for next indent level info; we skip also\n\t\t// comments (all comments, not just those starting in column 0)\n\t\t// which effectively folds them into surrounding code rather\n\t\t// than screwing up folding.\n\n\t\twhile ((lineNext < docLines) &&\n\t\t        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||\n\t\t         (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {\n\n\t\t\tlineNext++;\n\t\t\tindentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);\n\t\t}\n\n\t\tconst int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;\n\t\tconst int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments);\n\n\t\t// Now set all the indent levels on the lines we skipped\n\t\t// Do this from end to start.  Once we encounter one line\n\t\t// which is indented more than the line after the end of\n\t\t// the comment-block, use the level of the block before\n\n\t\tSci_Position skipLine = lineNext;\n\t\tint skipLevel = levelAfterComments;\n\n\t\twhile (--skipLine > lineCurrent) {\n\t\t\tconst int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, nullptr);\n\n\t\t\tif ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)\n\t\t\t\tskipLevel = levelBeforeComments;\n\n\t\t\tconst int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;\n\n\t\t\tstyler.SetLevel(skipLine, skipLevel | whiteFlag);\n\t\t}\n\n\t\t// Set fold header on non-comment line\n\t\tif (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {\n\t\t\tif ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t}\n\n\t\t// Keep track of block comment state of previous line\n\t\tprevComment = comment_start || comment_continue;\n\n\t\t// Set fold level for this line and move to next line\n\t\tstyler.SetLevel(lineCurrent, lev);\n\t\tindentCurrent = indentNext;\n\t\tlineCurrent = lineNext;\n\t}\n\n\t// NOTE: Cannot set level of last line here because indentCurrent doesn't have\n\t// header flag set; the loop above is crafted to take care of this case!\n\t//styler.SetLevel(lineCurrent, indentCurrent);\n}\n\n}\n\nextern const LexerModule lmYAML(SCLEX_YAML, ColouriseYAMLDoc, \"yaml\", FoldYAMLDoc, yamlWordListDesc);\n"
  },
  {
    "path": "lexers/LexZig.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexZig.cxx\n ** Lexer for Zig language.\n **/\n// Based on Zufu Liu's Notepad4 Zig lexer\n// Modified for Scintilla by Jiri Techet, 2024\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <algorithm>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Scintilla;\nusing namespace Lexilla;\n\nnamespace {\n// Use an unnamed namespace to protect the functions and classes from name conflicts\n\nconstexpr bool IsAGraphic(int ch) noexcept {\n\t// excludes C0 control characters and whitespace\n\treturn ch > 32 && ch < 127;\n}\n\nconstexpr bool IsIdentifierStart(int ch) noexcept {\n\treturn IsUpperOrLowerCase(ch) || ch == '_';\n}\n\nconstexpr bool IsIdentifierStartEx(int ch) noexcept {\n\treturn IsIdentifierStart(ch) || ch >= 0x80;\n}\n\nconstexpr bool IsNumberStart(int ch, int chNext) noexcept {\n\treturn IsADigit(ch) || (ch == '.' && IsADigit(chNext));\n}\n\nconstexpr bool IsIdentifierChar(int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '_';\n}\n\nconstexpr bool IsNumberContinue(int chPrev, int ch, int chNext) noexcept {\n\treturn ((ch == '+' || ch == '-') && (chPrev == 'e' || chPrev == 'E'))\n\t\t|| (ch == '.' && chNext != '.');\n}\n\nconstexpr bool IsDecimalNumber(int chPrev, int ch, int chNext) noexcept {\n\treturn IsIdentifierChar(ch) || IsNumberContinue(chPrev, ch, chNext);\n}\n\nconstexpr bool IsIdentifierCharEx(int ch) noexcept {\n\treturn IsIdentifierChar(ch) || ch >= 0x80;\n}\n\n// https://ziglang.org/documentation/master/#Escape-Sequences\nstruct EscapeSequence {\n\tint outerState = SCE_ZIG_DEFAULT;\n\tint digitsLeft = 0;\n\tbool brace = false;\n\n\t// highlight any character as escape sequence.\n\tvoid resetEscapeState(int state, int chNext) noexcept {\n\t\touterState = state;\n\t\tdigitsLeft = 1;\n\t\tbrace = false;\n\t\tif (chNext == 'x') {\n\t\t\tdigitsLeft = 3;\n\t\t} else if (chNext == 'u') {\n\t\t\tdigitsLeft = 5;\n\t\t}\n\t}\n\tvoid resetEscapeState(int state) noexcept {\n\t\touterState = state;\n\t\tdigitsLeft = 1;\n\t\tbrace = false;\n\t}\n\tbool atEscapeEnd(int ch) noexcept {\n\t\t--digitsLeft;\n\t\treturn digitsLeft <= 0 || !IsAHeXDigit(ch);\n\t}\n};\n\nenum {\n\tZigLineStateMaskLineComment = 1, // line comment\n\tZigLineStateMaskMultilineString = 1 << 1, // multiline string\n};\n\nstruct FoldLineState {\n\tint lineComment;\n\tint multilineString;\n\tconstexpr explicit FoldLineState(int lineState) noexcept:\n\t\tlineComment(lineState & ZigLineStateMaskLineComment),\n\t\tmultilineString((lineState >> 1) & 1) {\n\t}\n};\n\nenum class KeywordType {\n\tNone = SCE_ZIG_DEFAULT,\n\tFunction = SCE_ZIG_FUNCTION,\n};\n\nenum {\n\tKeywordIndex_Primary = 0,\n\tKeywordIndex_Secondary = 1,\n\tKeywordIndex_Tertiary = 2,\n\tKeywordIndex_Type = 3,\n};\n\n// Options used for LexerZig\nstruct OptionsZig {\n\tbool fold = false;\n};\n\nconst char *const zigWordListDesc[] = {\n\t\"Primary keywords\",\n\t\"Secondary keywords\",\n\t\"Tertiary keywords\",\n\t\"Global type definitions\",\n\tnullptr\n};\n\nstruct OptionSetZig : public OptionSet<OptionsZig> {\n\tOptionSetZig() {\n\t\tDefineProperty(\"fold\", &OptionsZig::fold);\n\n\t\tDefineWordListSets(zigWordListDesc);\n\t}\n};\n\nLexicalClass lexicalClasses[] = {\n\t// Lexer ZIG SCLEX_ZIG SCE_ZIG_:\n\t0, \"SCE_ZIG_DEFAULT\", \"default\", \"White space\",\n\t1, \"SCE_ZIG_COMMENTLINE\", \"comment line\", \"Comment: //\",\n\t2, \"SCE_ZIG_COMMENTLINEDOC\", \"comment line documentation\", \"Comment: ///\",\n\t3, \"SCE_ZIG_COMMENTLINETOP\", \"comment line documentation\", \"Comment: //!\",\n\t4, \"SCE_ZIG_NUMBER\", \"literal numeric\", \"Number\",\n\t5, \"SCE_ZIG_OPERATOR\", \"operator\", \"Operator\",\n\t6, \"SCE_ZIG_CHARACTER\", \"literal string character\", \"Single quoted string\",\n\t7, \"SCE_ZIG_STRING\", \"literal string\", \"Double quoted string\",\n\t8, \"SCE_ZIG_MULTISTRING\", \"literal string multiline\", \"Multiline string introduced by two backslashes\",\n\t9, \"SCE_ZIG_ESCAPECHAR\", \"literal string escapesequence\", \"Escape sequence\",\n\t10, \"SCE_ZIG_IDENTIFIER\", \"identifier\", \"Identifier\",\n\t11, \"SCE_ZIG_FUNCTION\", \"identifier\", \"Function definition\",\n\t12, \"SCE_ZIG_BUILTIN_FUNCTION\", \"identifier\", \"Builtin function\",\n\t13, \"SCE_ZIG_KW_PRIMARY\", \"keyword\", \"Primary keywords\",\n\t14, \"SCE_ZIG_KW_SECONDARY\", \"identifier\", \"Secondary keywords\",\n\t15, \"SCE_ZIG_KW_TERTIARY\", \"identifier\", \"Tertiary keywords\",\n\t16, \"SCE_ZIG_KW_TYPE\", \"identifier\", \"Global types\",\n\t17, \"SCE_ZIG_IDENTIFIER_STRING\", \"identifier\", \"Identifier using @\\\"\\\" syntax\",\n\t18, \"SCE_ZIG_STRINGEOL\", \"error literal string\", \"End of line where string is not closed\",\n};\n\nclass LexerZig : public DefaultLexer {\n\tWordList keywordsPrimary;\n\tWordList keywordsSecondary;\n\tWordList keywordsTertiary;\n\tWordList keywordsTypes;\n\tOptionsZig options;\n\tOptionSetZig osZig;\npublic:\n\tLexerZig(const char *languageName_, int language_) :\n\t\tDefaultLexer(languageName_, language_, lexicalClasses, std::size(lexicalClasses)) {\n\t}\n\t// Deleted so LexerZig objects can not be copied.\n\tLexerZig(const LexerZig &) = delete;\n\tLexerZig(LexerZig &&) = delete;\n\tvoid operator=(const LexerZig &) = delete;\n\tvoid operator=(LexerZig &&) = delete;\n\t~LexerZig() override = default;\n\n\tvoid SCI_METHOD Release() override {\n\t\tdelete this;\n\t}\n\tint SCI_METHOD Version() const override {\n\t\treturn lvRelease5;\n\t}\n\tconst char *SCI_METHOD PropertyNames() override {\n\t\treturn osZig.PropertyNames();\n\t}\n\tint SCI_METHOD PropertyType(const char *name) override {\n\t\treturn osZig.PropertyType(name);\n\t}\n\tconst char *SCI_METHOD DescribeProperty(const char *name) override {\n\t\treturn osZig.DescribeProperty(name);\n\t}\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override {\n\t\treturn osZig.PropertyGet(key);\n\t}\n\tconst char *SCI_METHOD DescribeWordListSets() override {\n\t\treturn osZig.DescribeWordListSets();\n\t}\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;\n\n\tvoid *SCI_METHOD PrivateCall(int, void *) override {\n\t\treturn nullptr;\n\t}\n\n\tvoid BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle);\n\tSci_PositionU LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite);\n\n\tstatic ILexer5 *LexerFactoryZig() {\n\t\treturn new LexerZig(\"zig\", SCLEX_ZIG);\n\t}\n};\n\nSci_Position SCI_METHOD LexerZig::PropertySet(const char *key, const char *val) {\n\tif (osZig.PropertySet(&options, key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nSci_Position SCI_METHOD LexerZig::WordListSet(int n, const char *wl) {\n\tWordList *wordListN = nullptr;\n\tswitch (n) {\n\tcase 0:\n\t\twordListN = &keywordsPrimary;\n\t\tbreak;\n\tcase 1:\n\t\twordListN = &keywordsSecondary;\n\t\tbreak;\n\tcase 2:\n\t\twordListN = &keywordsTertiary;\n\t\tbreak;\n\tcase 3:\n\t\twordListN = &keywordsTypes;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tSci_Position firstModification = -1;\n\tif (wordListN && wordListN->Set(wl, false)) {\n\t\tfirstModification = 0;\n\t}\n\treturn firstModification;\n}\n\nvoid LexerZig::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {\n\tAccessor styler(pAccess, nullptr);\n\n\tKeywordType kwType = KeywordType::None;\n\tint visibleChars = 0;\n\tint lineState = 0;\n\tEscapeSequence escSeq;\n\n\tif (initStyle == SCE_ZIG_STRINGEOL) {\n\t\tinitStyle = SCE_ZIG_DEFAULT;\n\t}\n\n\tStyleContext sc(startPos, lengthDoc, initStyle, styler);\n\n\twhile (sc.More()) {\n\t\tswitch (sc.state) {\n\t\tcase SCE_ZIG_OPERATOR:\n\t\t\tsc.SetState(SCE_ZIG_DEFAULT);\n\t\t\tbreak;\n\n\t\tcase SCE_ZIG_NUMBER:\n\t\t\tif (!IsDecimalNumber(sc.chPrev, sc.ch, sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_ZIG_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ZIG_IDENTIFIER:\n\t\tcase SCE_ZIG_BUILTIN_FUNCTION:\n\t\t\tif (!IsIdentifierCharEx(sc.ch)) {\n\t\t\t\tif (sc.state == SCE_ZIG_IDENTIFIER) {\n\t\t\t\t\tchar s[64];\n\t\t\t\t\tsc.GetCurrent(s, sizeof(s));\n\t\t\t\t\tif (kwType != KeywordType::None) {\n\t\t\t\t\t\tsc.ChangeState(static_cast<int>(kwType));\n\t\t\t\t\t} else if (keywordsPrimary.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ZIG_KW_PRIMARY);\n\t\t\t\t\t\tkwType = KeywordType::None;\n\t\t\t\t\t\tif (strcmp(s, \"fn\") == 0) {\n\t\t\t\t\t\t\tkwType = KeywordType::Function;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (keywordsSecondary.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ZIG_KW_SECONDARY);\n\t\t\t\t\t} else if (keywordsTertiary.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ZIG_KW_TERTIARY);\n\t\t\t\t\t} else if (keywordsTypes.InList(s)) {\n\t\t\t\t\t\tsc.ChangeState(SCE_ZIG_KW_TYPE);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (sc.state != SCE_ZIG_KW_PRIMARY) {\n\t\t\t\t\tkwType = KeywordType::None;\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_ZIG_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ZIG_CHARACTER:\n\t\tcase SCE_ZIG_STRING:\n\t\tcase SCE_ZIG_MULTISTRING:\n\t\tcase SCE_ZIG_IDENTIFIER_STRING:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_ZIG_DEFAULT);\n\t\t\t} else if (sc.atLineEnd && sc.state != SCE_ZIG_MULTISTRING) {\n\t\t\t\tsc.ChangeState(SCE_ZIG_STRINGEOL);\n\t\t\t} else if (sc.ch == '\\\\' && sc.state != SCE_ZIG_MULTISTRING) {\n\t\t\t\tescSeq.resetEscapeState(sc.state, sc.chNext);\n\t\t\t\tsc.SetState(SCE_ZIG_ESCAPECHAR);\n\t\t\t\tsc.Forward();\n\t\t\t\tif (sc.Match('u', '{')) {\n\t\t\t\t\tescSeq.brace = true;\n\t\t\t\t\tescSeq.digitsLeft = 9;\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t} else if ((sc.ch == '\\'' && sc.state == SCE_ZIG_CHARACTER) ||\n\t\t\t\t\t(sc.ch == '\\\"' && (sc.state == SCE_ZIG_STRING || sc.state == SCE_ZIG_IDENTIFIER_STRING))) {\n\t\t\t\tsc.ForwardSetState(SCE_ZIG_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ZIG_STRINGEOL:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_ZIG_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ZIG_ESCAPECHAR:\n\t\t\tif (escSeq.atEscapeEnd(sc.ch)) {\n\t\t\t\tif (escSeq.brace && sc.ch == '}') {\n\t\t\t\t\tsc.Forward();\n\t\t\t\t}\n\t\t\t\tsc.SetState(escSeq.outerState);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SCE_ZIG_COMMENTLINE:\n\t\tcase SCE_ZIG_COMMENTLINEDOC:\n\t\tcase SCE_ZIG_COMMENTLINETOP:\n\t\t\tif (sc.atLineStart) {\n\t\t\t\tsc.SetState(SCE_ZIG_DEFAULT);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (sc.state == SCE_ZIG_DEFAULT) {\n\t\t\tif (sc.Match('/', '/')) {\n\t\t\t\tif (visibleChars == 0) {\n\t\t\t\t\tlineState = ZigLineStateMaskLineComment;\n\t\t\t\t}\n\t\t\t\tsc.SetState(SCE_ZIG_COMMENTLINE);\n\t\t\t\tsc.Forward(2);\n\t\t\t\tif (sc.ch == '!') {\n\t\t\t\t\tsc.ChangeState(SCE_ZIG_COMMENTLINETOP);\n\t\t\t\t} else if (sc.ch == '/' && sc.chNext != '/') {\n\t\t\t\t\tsc.ChangeState(SCE_ZIG_COMMENTLINEDOC);\n\t\t\t\t}\n\t\t\t} else if (sc.Match('\\\\', '\\\\')) {\n\t\t\t\tlineState = ZigLineStateMaskMultilineString;\n\t\t\t\tsc.SetState(SCE_ZIG_MULTISTRING);\n\t\t\t} else if (sc.ch == '\\\"') {\n\t\t\t\tsc.SetState(SCE_ZIG_STRING);\n\t\t\t} else if (sc.ch == '\\'') {\n\t\t\t\tsc.SetState(SCE_ZIG_CHARACTER);\n\t\t\t} else if (IsNumberStart(sc.ch, sc.chNext)) {\n\t\t\t\tsc.SetState(SCE_ZIG_NUMBER);\n\t\t\t} else if ((sc.ch == '@' && IsIdentifierStartEx(sc.chNext)) || IsIdentifierStartEx(sc.ch)) {\n\t\t\t\tsc.SetState((sc.ch == '@') ? SCE_ZIG_BUILTIN_FUNCTION : SCE_ZIG_IDENTIFIER);\n\t\t\t} else if (sc.ch == '@' && sc.chNext == '\"') {\n\t\t\t\tsc.SetState(SCE_ZIG_IDENTIFIER_STRING);\n\t\t\t\tsc.Forward();\n\t\t\t} else if (IsAGraphic(sc.ch)) {\n\t\t\t\tsc.SetState(SCE_ZIG_OPERATOR);\n\t\t\t}\n\t\t}\n\n\t\tif (visibleChars == 0 && !isspacechar(sc.ch)) {\n\t\t\tvisibleChars++;\n\t\t}\n\t\tif (sc.atLineEnd) {\n\t\t\tstyler.SetLineState(sc.currentLine, lineState);\n\t\t\tlineState = 0;\n\t\t\tkwType = KeywordType::None;\n\t\t\tvisibleChars = 0;\n\t\t}\n\t\tsc.Forward();\n\t}\n\n\tsc.Complete();\n}\n\nvoid LexerZig::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {\n\tif (!options.fold)\n\t\treturn;\n\n\tAccessor styler(pAccess, nullptr);\n\tconst Sci_PositionU endPos = startPos + lengthDoc;\n\tSci_Position lineCurrent = styler.GetLine(startPos);\n\twhile (lineCurrent > 0) {\n\t\tlineCurrent--;\n\t\tstartPos = styler.LineStart(lineCurrent);\n\t\tinitStyle = (startPos > 0) ? styler.StyleIndexAt(startPos) : 0;\n\t\tif (!AnyOf(initStyle, SCE_ZIG_MULTISTRING,\n\t\t\t\tSCE_ZIG_COMMENTLINE, SCE_ZIG_COMMENTLINEDOC, SCE_ZIG_COMMENTLINETOP)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tFoldLineState foldPrev(0);\n\tint levelCurrent = SC_FOLDLEVELBASE;\n\tif (lineCurrent > 0) {\n\t\tlevelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;\n\t\tfoldPrev = FoldLineState(styler.GetLineState(lineCurrent - 1));\n\t}\n\n\tint levelNext = levelCurrent;\n\tFoldLineState foldCurrent(styler.GetLineState(lineCurrent));\n\tSci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1);\n\tlineStartNext = std::min(lineStartNext, endPos);\n\n\twhile (startPos < endPos) {\n\t\tinitStyle = styler.StyleIndexAt(startPos);\n\n\t\tif (initStyle == SCE_ZIG_OPERATOR) {\n\t\t\tconst char ch = styler[startPos];\n\t\t\tif (ch == '{' || ch == '[' || ch == '(') {\n\t\t\t\tlevelNext++;\n\t\t\t} else if (ch == '}' || ch == ']' || ch == ')') {\n\t\t\t\tlevelNext--;\n\t\t\t}\n\t\t}\n\n\t\t++startPos;\n\t\tif (startPos == lineStartNext) {\n\t\t\tconst FoldLineState foldNext(styler.GetLineState(lineCurrent + 1));\n\t\t\tlevelNext = std::max(levelNext, SC_FOLDLEVELBASE);\n\t\t\tif (foldCurrent.lineComment) {\n\t\t\t\tlevelNext += foldNext.lineComment - foldPrev.lineComment;\n\t\t\t} else if (foldCurrent.multilineString) {\n\t\t\t\tlevelNext += foldNext.multilineString - foldPrev.multilineString;\n\t\t\t}\n\n\t\t\tconst int levelUse = levelCurrent;\n\t\t\tint lev = levelUse | (levelNext << 16);\n\t\t\tif (levelUse < levelNext) {\n\t\t\t\tlev |= SC_FOLDLEVELHEADERFLAG;\n\t\t\t}\n\t\t\tstyler.SetLevel(lineCurrent, lev);\n\n\t\t\tlineCurrent++;\n\t\t\tlineStartNext = styler.LineStart(lineCurrent + 1);\n\t\t\tlineStartNext = std::min(lineStartNext, endPos);\n\t\t\tlevelCurrent = levelNext;\n\t\t\tfoldPrev = foldCurrent;\n\t\t\tfoldCurrent = foldNext;\n\t\t}\n\t}\n}\n\n}  // unnamed namespace end\n\nextern const LexerModule lmZig(SCLEX_ZIG, LexerZig::LexerFactoryZig, \"zig\", zigWordListDesc);\n"
  },
  {
    "path": "lexlib/Accessor.cxx",
    "content": "// Scintilla source code edit control\n/** @file Accessor.cxx\n ** Interfaces between Scintilla and lexers.\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n\nusing namespace Lexilla;\n\nAccessor::Accessor(Scintilla::IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) {\n}\n\nint Accessor::GetPropertyInt(std::string_view key, int defaultValue) const {\n\treturn pprops->GetInt(key, defaultValue);\n}\n\nint Accessor::IndentAmount(Sci_Position line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {\n\tconst Sci_Position end = Length();\n\tint spaceFlags = 0;\n\n\t// Determines the indentation level of the current line and also checks for consistent\n\t// indentation compared to the previous line.\n\t// Indentation is judged consistent when the indentation whitespace of each line lines\n\t// the same or the indentation of one line is a prefix of the other.\n\n\tSci_Position pos = LineStart(line);\n\tchar ch = (*this)[pos];\n\tint indent = 0;\n\tbool inPrevPrefix = line > 0;\n\tSci_Position posPrev = inPrevPrefix ? LineStart(line-1) : 0;\n\twhile ((ch == ' ' || ch == '\\t') && (pos < end)) {\n\t\tif (inPrevPrefix) {\n\t\t\tconst char chPrev = (*this)[posPrev++];\n\t\t\tif (chPrev == ' ' || chPrev == '\\t') {\n\t\t\t\tif (chPrev != ch)\n\t\t\t\t\tspaceFlags |= wsInconsistent;\n\t\t\t} else {\n\t\t\t\tinPrevPrefix = false;\n\t\t\t}\n\t\t}\n\t\tif (ch == ' ') {\n\t\t\tspaceFlags |= wsSpace;\n\t\t\tindent++;\n\t\t} else {\t// Tab\n\t\t\tspaceFlags |= wsTab;\n\t\t\tif (spaceFlags & wsSpace)\n\t\t\t\tspaceFlags |= wsSpaceTab;\n\t\t\tconstexpr int defaultTabSpaces = 8;\n\t\t\tindent = (indent / defaultTabSpaces + 1) * defaultTabSpaces;\n\t\t}\n\t\tch = (*this)[++pos];\n\t}\n\n\t*flags = spaceFlags;\n\tindent += SC_FOLDLEVELBASE;\n\t// if completely empty line or the start of a comment...\n\tif ((LineStart(line) == Length()) || (ch == ' ' || ch == '\\t' || ch == '\\n' || ch == '\\r') ||\n\t\t\t(pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)))\n\t\treturn indent | SC_FOLDLEVELWHITEFLAG;\n\treturn indent;\n}\n"
  },
  {
    "path": "lexlib/Accessor.h",
    "content": "// Scintilla source code edit control\n/** @file Accessor.h\n ** Interfaces between Scintilla and lexers.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef ACCESSOR_H\n#define ACCESSOR_H\n\nnamespace Lexilla {\n\nenum { wsSpace=1, wsTab=2, wsSpaceTab=4, wsInconsistent=8 };\n\nclass Accessor;\nclass WordList;\nclass PropSetSimple;\n\ntypedef bool (*PFNIsCommentLeader)(Accessor &styler, Sci_Position pos, Sci_Position len);\n\nclass Accessor : public LexAccessor {\npublic:\n\tPropSetSimple *pprops;\n\tAccessor(Scintilla::IDocument *pAccess_, PropSetSimple *pprops_);\n\tint GetPropertyInt(std::string_view key, int defaultValue=0) const;\n\tint IndentAmount(Sci_Position line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = nullptr);\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/CatalogueModules.h",
    "content": "// Scintilla source code edit control\n/** @file CatalogueModules.h\n ** Lexer infrastructure.\n ** Contains a list of LexerModules which can be searched to find a module appropriate for a\n ** particular language.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef CATALOGUEMODULES_H\n#define CATALOGUEMODULES_H\n\nnamespace Lexilla {\n\nclass CatalogueModules {\n\tstd::vector<const LexerModule *> lexerCatalogue;\npublic:\n\tconst LexerModule *Find(int language) const noexcept {\n\t\tfor (const LexerModule *lm : lexerCatalogue) {\n\t\t\tif (lm->GetLanguage() == language) {\n\t\t\t\treturn lm;\n\t\t\t}\n\t\t}\n\t\treturn nullptr;\n\t}\n\n\tconst LexerModule *Find(const char *languageName) const noexcept {\n\t\tif (languageName) {\n\t\t\tfor (const LexerModule *lm : lexerCatalogue) {\n\t\t\t\tif (lm->languageName && (0 == strcmp(lm->languageName, languageName))) {\n\t\t\t\t\treturn lm;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn nullptr;\n\t}\n\n\tvoid AddLexerModule(const LexerModule *plm) {\n\t\tlexerCatalogue.push_back(plm);\n\t}\n\n\tvoid AddLexerModules(std::initializer_list<const LexerModule *> modules) {\n\t\tlexerCatalogue.insert(lexerCatalogue.end(), modules);\n\t}\n\n\tsize_t Count() const noexcept {\n\t\treturn lexerCatalogue.size();\n\t}\n\n\tconst char *Name(size_t index) const noexcept {\n\t\tif (index < lexerCatalogue.size()) {\n\t\t\treturn lexerCatalogue[index]->languageName;\n\t\t}\n\t\treturn \"\";\n\t}\n\n\tLexerFactoryFunction Factory(size_t index) const noexcept {\n\t\t// Works for object lexers but not for function lexers\n\t\treturn lexerCatalogue[index]->fnFactory;\n\t}\n\n\tScintilla::ILexer5 *Create(size_t index) const {\n\t\tconst LexerModule *plm = lexerCatalogue[index];\n\t\tif (!plm) {\n\t\t\treturn nullptr;\n\t\t}\n\t\treturn plm->Create();\n\t}\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/CharacterCategory.cxx",
    "content": "// Scintilla source code edit control\n/** @file CharacterCategory.cxx\n ** Returns the Unicode general category of a character.\n ** Table automatically regenerated by scripts/GenerateCharacterCategory.py\n ** Should only be rarely regenerated for new versions of Unicode.\n **/\n// Copyright 2013 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <vector>\n#include <algorithm>\n#include <iterator>\n\n#include \"CharacterCategory.h\"\n\nnamespace Lexilla {\n\nnamespace {\n\t// Use an unnamed namespace to protect the declarations from name conflicts\n\nconst int catRanges[] = {\n//++Autogenerated -- start of section automatically generated\n// Created with Python 3.14.0,  Unicode 16.0.0\n25,\n1046,\n1073,\n1171,\n1201,\n1293,\n1326,\n1361,\n1394,\n1425,\n1452,\n1489,\n1544,\n1873,\n1938,\n2033,\n2080,\n2925,\n2961,\n2990,\n3028,\n3051,\n3092,\n3105,\n3949,\n3986,\n4014,\n4050,\n4089,\n5142,\n5169,\n5203,\n5333,\n5361,\n5396,\n5429,\n5444,\n5487,\n5522,\n5562,\n5589,\n5620,\n5653,\n5682,\n5706,\n5780,\n5793,\n5841,\n5908,\n5930,\n5956,\n6000,\n6026,\n6129,\n6144,\n6898,\n6912,\n7137,\n7922,\n7937,\n8192,\n8225,\n8256,\n8289,\n8320,\n8353,\n8384,\n8417,\n8448,\n8481,\n8512,\n8545,\n8576,\n8609,\n8640,\n8673,\n8704,\n8737,\n8768,\n8801,\n8832,\n8865,\n8896,\n8929,\n8960,\n8993,\n9024,\n9057,\n9088,\n9121,\n9152,\n9185,\n9216,\n9249,\n9280,\n9313,\n9344,\n9377,\n9408,\n9441,\n9472,\n9505,\n9536,\n9569,\n9600,\n9633,\n9664,\n9697,\n9728,\n9761,\n9792,\n9825,\n9856,\n9889,\n9920,\n9953,\n10016,\n10049,\n10080,\n10113,\n10144,\n10177,\n10208,\n10241,\n10272,\n10305,\n10336,\n10369,\n10400,\n10433,\n10464,\n10497,\n10560,\n10593,\n10624,\n10657,\n10688,\n10721,\n10752,\n10785,\n10816,\n10849,\n10880,\n10913,\n10944,\n10977,\n11008,\n11041,\n11072,\n11105,\n11136,\n11169,\n11200,\n11233,\n11264,\n11297,\n11328,\n11361,\n11392,\n11425,\n11456,\n11489,\n11520,\n11553,\n11584,\n11617,\n11648,\n11681,\n11712,\n11745,\n11776,\n11809,\n11840,\n11873,\n11904,\n11937,\n11968,\n12001,\n12032,\n12097,\n12128,\n12161,\n12192,\n12225,\n12320,\n12385,\n12416,\n12449,\n12480,\n12545,\n12576,\n12673,\n12736,\n12865,\n12896,\n12961,\n12992,\n13089,\n13184,\n13249,\n13280,\n13345,\n13376,\n13409,\n13440,\n13473,\n13504,\n13569,\n13600,\n13633,\n13696,\n13729,\n13760,\n13825,\n13856,\n13953,\n13984,\n14017,\n14048,\n14113,\n14180,\n14208,\n14241,\n14340,\n14464,\n14498,\n14529,\n14560,\n14594,\n14625,\n14656,\n14690,\n14721,\n14752,\n14785,\n14816,\n14849,\n14880,\n14913,\n14944,\n14977,\n15008,\n15041,\n15072,\n15105,\n15136,\n15169,\n15200,\n15233,\n15296,\n15329,\n15360,\n15393,\n15424,\n15457,\n15488,\n15521,\n15552,\n15585,\n15616,\n15649,\n15680,\n15713,\n15744,\n15777,\n15808,\n15841,\n15904,\n15938,\n15969,\n16000,\n16033,\n16064,\n16161,\n16192,\n16225,\n16256,\n16289,\n16320,\n16353,\n16384,\n16417,\n16448,\n16481,\n16512,\n16545,\n16576,\n16609,\n16640,\n16673,\n16704,\n16737,\n16768,\n16801,\n16832,\n16865,\n16896,\n16929,\n16960,\n16993,\n17024,\n17057,\n17088,\n17121,\n17152,\n17185,\n17216,\n17249,\n17280,\n17313,\n17344,\n17377,\n17408,\n17441,\n17472,\n17505,\n17536,\n17569,\n17600,\n17633,\n17664,\n17697,\n17728,\n17761,\n17792,\n17825,\n17856,\n17889,\n17920,\n17953,\n17984,\n18017,\n18240,\n18305,\n18336,\n18401,\n18464,\n18497,\n18528,\n18657,\n18688,\n18721,\n18752,\n18785,\n18816,\n18849,\n18880,\n18913,\n21124,\n21153,\n22019,\n22612,\n22723,\n23124,\n23555,\n23732,\n23939,\n23988,\n24003,\n24052,\n24581,\n28160,\n28193,\n28224,\n28257,\n28291,\n28340,\n28352,\n28385,\n28445,\n28483,\n28513,\n28625,\n28640,\n28701,\n28820,\n28864,\n28913,\n28928,\n29053,\n29056,\n29117,\n29120,\n29185,\n29216,\n29789,\n29792,\n30081,\n31200,\n31233,\n31296,\n31393,\n31488,\n31521,\n31552,\n31585,\n31616,\n31649,\n31680,\n31713,\n31744,\n31777,\n31808,\n31841,\n31872,\n31905,\n31936,\n31969,\n32000,\n32033,\n32064,\n32097,\n32128,\n32161,\n32192,\n32225,\n32384,\n32417,\n32466,\n32480,\n32513,\n32544,\n32609,\n32672,\n34305,\n35840,\n35873,\n35904,\n35937,\n35968,\n36001,\n36032,\n36065,\n36096,\n36129,\n36160,\n36193,\n36224,\n36257,\n36288,\n36321,\n36352,\n36385,\n36416,\n36449,\n36480,\n36513,\n36544,\n36577,\n36608,\n36641,\n36672,\n36705,\n36736,\n36769,\n36800,\n36833,\n36864,\n36897,\n36949,\n36965,\n37127,\n37184,\n37217,\n37248,\n37281,\n37312,\n37345,\n37376,\n37409,\n37440,\n37473,\n37504,\n37537,\n37568,\n37601,\n37632,\n37665,\n37696,\n37729,\n37760,\n37793,\n37824,\n37857,\n37888,\n37921,\n37952,\n37985,\n38016,\n38049,\n38080,\n38113,\n38144,\n38177,\n38208,\n38241,\n38272,\n38305,\n38336,\n38369,\n38400,\n38433,\n38464,\n38497,\n38528,\n38561,\n38592,\n38625,\n38656,\n38689,\n38720,\n38753,\n38784,\n38817,\n38848,\n38881,\n38912,\n38977,\n39008,\n39041,\n39072,\n39105,\n39136,\n39169,\n39200,\n39233,\n39264,\n39297,\n39328,\n39361,\n39424,\n39457,\n39488,\n39521,\n39552,\n39585,\n39616,\n39649,\n39680,\n39713,\n39744,\n39777,\n39808,\n39841,\n39872,\n39905,\n39936,\n39969,\n40000,\n40033,\n40064,\n40097,\n40128,\n40161,\n40192,\n40225,\n40256,\n40289,\n40320,\n40353,\n40384,\n40417,\n40448,\n40481,\n40512,\n40545,\n40576,\n40609,\n40640,\n40673,\n40704,\n40737,\n40768,\n40801,\n40832,\n40865,\n40896,\n40929,\n40960,\n40993,\n41024,\n41057,\n41088,\n41121,\n41152,\n41185,\n41216,\n41249,\n41280,\n41313,\n41344,\n41377,\n41408,\n41441,\n41472,\n41505,\n41536,\n41569,\n41600,\n41633,\n41664,\n41697,\n41728,\n41761,\n41792,\n41825,\n41856,\n41889,\n41920,\n41953,\n41984,\n42017,\n42048,\n42081,\n42112,\n42145,\n42176,\n42209,\n42240,\n42273,\n42304,\n42337,\n42368,\n42401,\n42432,\n42465,\n42525,\n42528,\n43773,\n43811,\n43857,\n44033,\n45361,\n45388,\n45437,\n45493,\n45555,\n45597,\n45605,\n47052,\n47077,\n47121,\n47141,\n47217,\n47237,\n47313,\n47333,\n47389,\n47620,\n48509,\n48612,\n48753,\n48829,\n49178,\n49362,\n49457,\n49523,\n49553,\n49621,\n49669,\n50033,\n50074,\n50097,\n50180,\n51203,\n51236,\n51557,\n52232,\n52561,\n52676,\n52741,\n52772,\n55953,\n55972,\n56005,\n56250,\n56277,\n56293,\n56483,\n56549,\n56629,\n56645,\n56772,\n56840,\n57156,\n57269,\n57316,\n57361,\n57821,\n57850,\n57860,\n57893,\n57924,\n58885,\n59773,\n59812,\n62661,\n63012,\n63069,\n63496,\n63812,\n64869,\n65155,\n65237,\n65265,\n65347,\n65405,\n65445,\n65491,\n65540,\n66245,\n66371,\n66405,\n66691,\n66725,\n66819,\n66853,\n67037,\n67089,\n67581,\n67588,\n68389,\n68509,\n68561,\n68605,\n68612,\n68989,\n69124,\n69908,\n69924,\n70141,\n70170,\n70237,\n70373,\n70660,\n71971,\n72005,\n72794,\n72805,\n73830,\n73860,\n75589,\n75622,\n75653,\n75684,\n75718,\n75813,\n76070,\n76197,\n76230,\n76292,\n76325,\n76548,\n76869,\n76945,\n77000,\n77329,\n77347,\n77380,\n77861,\n77894,\n77981,\n77988,\n78269,\n78308,\n78397,\n78436,\n79165,\n79172,\n79421,\n79428,\n79485,\n79556,\n79709,\n79749,\n79780,\n79814,\n79909,\n80061,\n80102,\n80189,\n80230,\n80293,\n80324,\n80381,\n80614,\n80669,\n80772,\n80861,\n80868,\n80965,\n81053,\n81096,\n81412,\n81491,\n81546,\n81749,\n81779,\n81796,\n81841,\n81861,\n81917,\n81957,\n82022,\n82077,\n82084,\n82301,\n82404,\n82493,\n82532,\n83261,\n83268,\n83517,\n83524,\n83613,\n83620,\n83709,\n83716,\n83805,\n83845,\n83901,\n83910,\n84005,\n84093,\n84197,\n84285,\n84325,\n84445,\n84517,\n84573,\n84772,\n84925,\n84932,\n84989,\n85192,\n85509,\n85572,\n85669,\n85713,\n85757,\n86053,\n86118,\n86173,\n86180,\n86493,\n86500,\n86621,\n86628,\n87357,\n87364,\n87613,\n87620,\n87709,\n87716,\n87901,\n87941,\n87972,\n88006,\n88101,\n88285,\n88293,\n88358,\n88413,\n88422,\n88485,\n88541,\n88580,\n88637,\n89092,\n89157,\n89245,\n89288,\n89617,\n89651,\n89693,\n89892,\n89925,\n90141,\n90149,\n90182,\n90269,\n90276,\n90557,\n90596,\n90685,\n90724,\n91453,\n91460,\n91709,\n91716,\n91805,\n91812,\n91997,\n92037,\n92068,\n92102,\n92133,\n92166,\n92197,\n92349,\n92390,\n92477,\n92518,\n92581,\n92637,\n92837,\n92902,\n92957,\n93060,\n93149,\n93156,\n93253,\n93341,\n93384,\n93717,\n93732,\n93770,\n93981,\n94277,\n94308,\n94365,\n94372,\n94589,\n94660,\n94781,\n94788,\n94941,\n95012,\n95101,\n95108,\n95165,\n95172,\n95261,\n95332,\n95421,\n95492,\n95613,\n95684,\n96093,\n96198,\n96261,\n96294,\n96381,\n96454,\n96573,\n96582,\n96677,\n96733,\n96772,\n96829,\n96998,\n97053,\n97480,\n97802,\n97909,\n98099,\n98133,\n98173,\n98309,\n98342,\n98437,\n98468,\n98749,\n98756,\n98877,\n98884,\n99645,\n99652,\n100189,\n100229,\n100260,\n100293,\n100390,\n100541,\n100549,\n100669,\n100677,\n100829,\n101029,\n101117,\n101124,\n101245,\n101284,\n101341,\n101380,\n101445,\n101533,\n101576,\n101917,\n102129,\n102154,\n102389,\n102404,\n102437,\n102470,\n102545,\n102564,\n102845,\n102852,\n102973,\n102980,\n103741,\n103748,\n104093,\n104100,\n104285,\n104325,\n104356,\n104390,\n104421,\n104454,\n104637,\n104645,\n104678,\n104765,\n104774,\n104837,\n104925,\n105126,\n105213,\n105380,\n105469,\n105476,\n105541,\n105629,\n105672,\n106013,\n106020,\n106086,\n106141,\n106501,\n106566,\n106628,\n106941,\n106948,\n107069,\n107076,\n108389,\n108452,\n108486,\n108581,\n108733,\n108742,\n108861,\n108870,\n108965,\n108996,\n109045,\n109085,\n109188,\n109286,\n109322,\n109540,\n109637,\n109725,\n109768,\n110090,\n110389,\n110404,\n110621,\n110629,\n110662,\n110749,\n110756,\n111357,\n111428,\n112221,\n112228,\n112541,\n112548,\n112605,\n112644,\n112893,\n112965,\n113021,\n113126,\n113221,\n113341,\n113349,\n113405,\n113414,\n113693,\n113864,\n114205,\n114246,\n114321,\n114365,\n114724,\n116261,\n116292,\n116357,\n116605,\n116723,\n116740,\n116931,\n116965,\n117233,\n117256,\n117585,\n117661,\n118820,\n118909,\n118916,\n118973,\n118980,\n119165,\n119172,\n119965,\n119972,\n120029,\n120036,\n120357,\n120388,\n120453,\n120740,\n120797,\n120836,\n121021,\n121027,\n121085,\n121093,\n121341,\n121352,\n121693,\n121732,\n121885,\n122884,\n122933,\n123025,\n123509,\n123537,\n123573,\n123653,\n123733,\n123912,\n124234,\n124565,\n124581,\n124629,\n124645,\n124693,\n124709,\n124749,\n124782,\n124813,\n124846,\n124870,\n124932,\n125213,\n125220,\n126397,\n126501,\n126950,\n126981,\n127153,\n127173,\n127236,\n127397,\n127773,\n127781,\n128957,\n128981,\n129221,\n129269,\n129469,\n129493,\n129553,\n129717,\n129841,\n129917,\n131076,\n132454,\n132517,\n132646,\n132677,\n132870,\n132901,\n132966,\n133029,\n133092,\n133128,\n133457,\n133636,\n133830,\n133893,\n133956,\n134085,\n134180,\n134214,\n134308,\n134374,\n134596,\n134693,\n134820,\n135237,\n135270,\n135333,\n135398,\n135589,\n135620,\n135654,\n135688,\n136006,\n136101,\n136149,\n136192,\n137437,\n137440,\n137501,\n137632,\n137693,\n137729,\n139121,\n139139,\n139169,\n139268,\n149821,\n149828,\n149981,\n150020,\n150269,\n150276,\n150333,\n150340,\n150493,\n150532,\n151869,\n151876,\n152029,\n152068,\n153149,\n153156,\n153309,\n153348,\n153597,\n153604,\n153661,\n153668,\n153821,\n153860,\n154365,\n154372,\n156221,\n156228,\n156381,\n156420,\n158589,\n158629,\n158737,\n159018,\n159677,\n159748,\n160277,\n160605,\n160768,\n163549,\n163585,\n163805,\n163852,\n163876,\n183733,\n183761,\n183780,\n184342,\n184356,\n185197,\n185230,\n185277,\n185348,\n187761,\n187849,\n187940,\n188221,\n188420,\n188997,\n189094,\n189149,\n189412,\n190021,\n190086,\n190129,\n190205,\n190468,\n191045,\n191133,\n191492,\n191933,\n191940,\n192061,\n192069,\n192157,\n192516,\n194181,\n194246,\n194277,\n194502,\n194757,\n194790,\n194853,\n195217,\n195299,\n195345,\n195443,\n195460,\n195493,\n195549,\n195592,\n195933,\n196106,\n196445,\n196625,\n196812,\n196849,\n196965,\n197082,\n197093,\n197128,\n197469,\n197636,\n198755,\n198788,\n200509,\n200708,\n200869,\n200932,\n202021,\n202052,\n202109,\n202244,\n204509,\n204804,\n205821,\n205829,\n205926,\n206053,\n206118,\n206237,\n206342,\n206405,\n206438,\n206629,\n206749,\n206869,\n206909,\n206993,\n207048,\n207364,\n208349,\n208388,\n208573,\n208900,\n210333,\n210436,\n211293,\n211464,\n211786,\n211837,\n211925,\n212996,\n213733,\n213798,\n213861,\n213917,\n213969,\n214020,\n215718,\n215749,\n215782,\n215813,\n216061,\n216069,\n216102,\n216133,\n216166,\n216229,\n216486,\n216677,\n217021,\n217061,\n217096,\n217437,\n217608,\n217949,\n218129,\n218339,\n218385,\n218589,\n218629,\n219079,\n219109,\n219645,\n221189,\n221318,\n221348,\n222853,\n222886,\n222917,\n223078,\n223109,\n223142,\n223301,\n223334,\n223396,\n223677,\n223697,\n223752,\n224081,\n224309,\n224613,\n224917,\n225201,\n225285,\n225350,\n225380,\n226342,\n226373,\n226502,\n226565,\n226630,\n226661,\n226756,\n226824,\n227140,\n228549,\n228582,\n228613,\n228678,\n228773,\n228806,\n228837,\n228934,\n229021,\n229265,\n229380,\n230534,\n230789,\n231046,\n231109,\n231197,\n231281,\n231432,\n231773,\n231844,\n231944,\n232260,\n233219,\n233425,\n233473,\n233760,\n233793,\n233853,\n233984,\n235389,\n235424,\n235537,\n235805,\n236037,\n236145,\n236165,\n236582,\n236613,\n236836,\n236965,\n236996,\n237189,\n237220,\n237286,\n237317,\n237380,\n237437,\n237569,\n238979,\n240993,\n241411,\n241441,\n242531,\n243717,\n245760,\n245793,\n245824,\n245857,\n245888,\n245921,\n245952,\n245985,\n246016,\n246049,\n246080,\n246113,\n246144,\n246177,\n246208,\n246241,\n246272,\n246305,\n246336,\n246369,\n246400,\n246433,\n246464,\n246497,\n246528,\n246561,\n246592,\n246625,\n246656,\n246689,\n246720,\n246753,\n246784,\n246817,\n246848,\n246881,\n246912,\n246945,\n246976,\n247009,\n247040,\n247073,\n247104,\n247137,\n247168,\n247201,\n247232,\n247265,\n247296,\n247329,\n247360,\n247393,\n247424,\n247457,\n247488,\n247521,\n247552,\n247585,\n247616,\n247649,\n247680,\n247713,\n247744,\n247777,\n247808,\n247841,\n247872,\n247905,\n247936,\n247969,\n248000,\n248033,\n248064,\n248097,\n248128,\n248161,\n248192,\n248225,\n248256,\n248289,\n248320,\n248353,\n248384,\n248417,\n248448,\n248481,\n248512,\n248545,\n248576,\n248609,\n248640,\n248673,\n248704,\n248737,\n248768,\n248801,\n248832,\n248865,\n248896,\n248929,\n248960,\n248993,\n249024,\n249057,\n249088,\n249121,\n249152,\n249185,\n249216,\n249249,\n249280,\n249313,\n249344,\n249377,\n249408,\n249441,\n249472,\n249505,\n249536,\n249569,\n249600,\n249633,\n249664,\n249697,\n249728,\n249761,\n249792,\n249825,\n249856,\n249889,\n249920,\n249953,\n249984,\n250017,\n250048,\n250081,\n250112,\n250145,\n250176,\n250209,\n250240,\n250273,\n250304,\n250337,\n250368,\n250401,\n250432,\n250465,\n250496,\n250529,\n250816,\n250849,\n250880,\n250913,\n250944,\n250977,\n251008,\n251041,\n251072,\n251105,\n251136,\n251169,\n251200,\n251233,\n251264,\n251297,\n251328,\n251361,\n251392,\n251425,\n251456,\n251489,\n251520,\n251553,\n251584,\n251617,\n251648,\n251681,\n251712,\n251745,\n251776,\n251809,\n251840,\n251873,\n251904,\n251937,\n251968,\n252001,\n252032,\n252065,\n252096,\n252129,\n252160,\n252193,\n252224,\n252257,\n252288,\n252321,\n252352,\n252385,\n252416,\n252449,\n252480,\n252513,\n252544,\n252577,\n252608,\n252641,\n252672,\n252705,\n252736,\n252769,\n252800,\n252833,\n252864,\n252897,\n252928,\n252961,\n252992,\n253025,\n253056,\n253089,\n253120,\n253153,\n253184,\n253217,\n253248,\n253281,\n253312,\n253345,\n253376,\n253409,\n253440,\n253473,\n253504,\n253537,\n253568,\n253601,\n253632,\n253665,\n253696,\n253729,\n253760,\n253793,\n253824,\n253857,\n253888,\n253921,\n254208,\n254465,\n254685,\n254720,\n254941,\n254977,\n255232,\n255489,\n255744,\n256001,\n256221,\n256256,\n256477,\n256513,\n256797,\n256800,\n256861,\n256864,\n256925,\n256928,\n256989,\n256992,\n257025,\n257280,\n257537,\n258013,\n258049,\n258306,\n258561,\n258818,\n259073,\n259330,\n259585,\n259773,\n259777,\n259840,\n259970,\n260020,\n260033,\n260084,\n260161,\n260285,\n260289,\n260352,\n260482,\n260532,\n260609,\n260765,\n260801,\n260864,\n261021,\n261044,\n261121,\n261376,\n261556,\n261661,\n261697,\n261821,\n261825,\n261888,\n262018,\n262068,\n262141,\n262166,\n262522,\n262668,\n262865,\n262927,\n262960,\n262989,\n263023,\n263088,\n263117,\n263151,\n263185,\n263447,\n263480,\n263514,\n263670,\n263697,\n263983,\n264016,\n264049,\n264171,\n264241,\n264338,\n264365,\n264398,\n264433,\n264786,\n264817,\n264843,\n264881,\n265206,\n265242,\n265405,\n265434,\n265738,\n265763,\n265821,\n265866,\n266066,\n266157,\n266190,\n266211,\n266250,\n266578,\n266669,\n266702,\n266749,\n266755,\n267197,\n267283,\n268349,\n268805,\n269223,\n269349,\n269383,\n269477,\n269885,\n270357,\n270400,\n270453,\n270560,\n270613,\n270657,\n270688,\n270785,\n270848,\n270945,\n270997,\n271008,\n271061,\n271122,\n271136,\n271317,\n271488,\n271541,\n271552,\n271605,\n271616,\n271669,\n271680,\n271829,\n271841,\n271872,\n272001,\n272036,\n272161,\n272213,\n272257,\n272320,\n272402,\n272544,\n272577,\n272725,\n272754,\n272789,\n272833,\n272885,\n272906,\n273417,\n274528,\n274561,\n274601,\n274730,\n274773,\n274845,\n274962,\n275125,\n275282,\n275349,\n275474,\n275509,\n275570,\n275605,\n275666,\n275701,\n275922,\n275957,\n276946,\n277013,\n277074,\n277109,\n277138,\n277173,\n278162,\n286741,\n286989,\n287022,\n287053,\n287086,\n287125,\n287762,\n287829,\n288045,\n288078,\n288117,\n290706,\n290741,\n291698,\n292501,\n293778,\n293973,\n296285,\n296981,\n297341,\n297994,\n299925,\n302410,\n303125,\n308978,\n309013,\n309298,\n309333,\n311058,\n311317,\n314866,\n314901,\n322829,\n322862,\n322893,\n322926,\n322957,\n322990,\n323021,\n323054,\n323085,\n323118,\n323149,\n323182,\n323213,\n323246,\n323274,\n324245,\n325650,\n325805,\n325838,\n325874,\n326861,\n326894,\n326925,\n326958,\n326989,\n327022,\n327053,\n327086,\n327117,\n327150,\n327186,\n327701,\n335890,\n340077,\n340110,\n340141,\n340174,\n340205,\n340238,\n340269,\n340302,\n340333,\n340366,\n340397,\n340430,\n340461,\n340494,\n340525,\n340558,\n340589,\n340622,\n340653,\n340686,\n340717,\n340750,\n340786,\n342797,\n342830,\n342861,\n342894,\n342930,\n343949,\n343982,\n344018,\n352277,\n353810,\n354485,\n354546,\n354741,\n355997,\n356053,\n357085,\n357109,\n360448,\n361985,\n363520,\n363553,\n363584,\n363681,\n363744,\n363777,\n363808,\n363841,\n363872,\n363905,\n363936,\n364065,\n364096,\n364129,\n364192,\n364225,\n364419,\n364480,\n364577,\n364608,\n364641,\n364672,\n364705,\n364736,\n364769,\n364800,\n364833,\n364864,\n364897,\n364928,\n364961,\n364992,\n365025,\n365056,\n365089,\n365120,\n365153,\n365184,\n365217,\n365248,\n365281,\n365312,\n365345,\n365376,\n365409,\n365440,\n365473,\n365504,\n365537,\n365568,\n365601,\n365632,\n365665,\n365696,\n365729,\n365760,\n365793,\n365824,\n365857,\n365888,\n365921,\n365952,\n365985,\n366016,\n366049,\n366080,\n366113,\n366144,\n366177,\n366208,\n366241,\n366272,\n366305,\n366336,\n366369,\n366400,\n366433,\n366464,\n366497,\n366528,\n366561,\n366592,\n366625,\n366656,\n366689,\n366720,\n366753,\n366784,\n366817,\n366848,\n366881,\n366912,\n366945,\n366976,\n367009,\n367040,\n367073,\n367104,\n367137,\n367168,\n367201,\n367232,\n367265,\n367296,\n367329,\n367360,\n367393,\n367424,\n367457,\n367488,\n367521,\n367552,\n367585,\n367616,\n367649,\n367680,\n367713,\n367797,\n367968,\n368001,\n368032,\n368065,\n368101,\n368192,\n368225,\n368285,\n368433,\n368554,\n368593,\n368641,\n369885,\n369889,\n369949,\n370081,\n370141,\n370180,\n371997,\n372195,\n372241,\n372285,\n372709,\n372740,\n373501,\n373764,\n374013,\n374020,\n374269,\n374276,\n374525,\n374532,\n374781,\n374788,\n375037,\n375044,\n375293,\n375300,\n375549,\n375556,\n375805,\n375813,\n376849,\n376911,\n376944,\n376975,\n377008,\n377041,\n377135,\n377168,\n377201,\n377231,\n377264,\n377297,\n377580,\n377617,\n377676,\n377713,\n377743,\n377776,\n377809,\n377871,\n377904,\n377933,\n377966,\n377997,\n378030,\n378061,\n378094,\n378125,\n378158,\n378193,\n378339,\n378385,\n378700,\n378769,\n378892,\n378929,\n378957,\n378993,\n379413,\n379473,\n379565,\n379598,\n379629,\n379662,\n379693,\n379726,\n379757,\n379790,\n379820,\n379869,\n380949,\n381789,\n381813,\n384669,\n385045,\n391901,\n392725,\n393238,\n393265,\n393365,\n393379,\n393412,\n393449,\n393485,\n393518,\n393549,\n393582,\n393613,\n393646,\n393677,\n393710,\n393741,\n393774,\n393813,\n393869,\n393902,\n393933,\n393966,\n393997,\n394030,\n394061,\n394094,\n394124,\n394157,\n394190,\n394261,\n394281,\n394565,\n394694,\n394764,\n394787,\n394965,\n395017,\n395107,\n395140,\n395185,\n395221,\n395293,\n395300,\n398077,\n398117,\n398196,\n398243,\n398308,\n398348,\n398372,\n401265,\n401283,\n401380,\n401437,\n401572,\n402973,\n402980,\n406013,\n406037,\n406090,\n406229,\n406532,\n407573,\n408797,\n409077,\n409092,\n409621,\n410621,\n410634,\n410965,\n411914,\n412181,\n412202,\n412693,\n413706,\n414037,\n415274,\n415765,\n425988,\n636949,\n638980,\n1311395,\n1311428,\n1348029,\n1348117,\n1349885,\n1350148,\n1351427,\n1351633,\n1351684,\n1360259,\n1360305,\n1360388,\n1360904,\n1361220,\n1361309,\n1361920,\n1361953,\n1361984,\n1362017,\n1362048,\n1362081,\n1362112,\n1362145,\n1362176,\n1362209,\n1362240,\n1362273,\n1362304,\n1362337,\n1362368,\n1362401,\n1362432,\n1362465,\n1362496,\n1362529,\n1362560,\n1362593,\n1362624,\n1362657,\n1362688,\n1362721,\n1362752,\n1362785,\n1362816,\n1362849,\n1362880,\n1362913,\n1362944,\n1362977,\n1363008,\n1363041,\n1363072,\n1363105,\n1363136,\n1363169,\n1363200,\n1363233,\n1363264,\n1363297,\n1363328,\n1363361,\n1363396,\n1363429,\n1363463,\n1363569,\n1363589,\n1363921,\n1363939,\n1363968,\n1364001,\n1364032,\n1364065,\n1364096,\n1364129,\n1364160,\n1364193,\n1364224,\n1364257,\n1364288,\n1364321,\n1364352,\n1364385,\n1364416,\n1364449,\n1364480,\n1364513,\n1364544,\n1364577,\n1364608,\n1364641,\n1364672,\n1364705,\n1364736,\n1364769,\n1364800,\n1364833,\n1364867,\n1364933,\n1364996,\n1367241,\n1367557,\n1367633,\n1367837,\n1368084,\n1368803,\n1369108,\n1369152,\n1369185,\n1369216,\n1369249,\n1369280,\n1369313,\n1369344,\n1369377,\n1369408,\n1369441,\n1369472,\n1369505,\n1369536,\n1369569,\n1369664,\n1369697,\n1369728,\n1369761,\n1369792,\n1369825,\n1369856,\n1369889,\n1369920,\n1369953,\n1369984,\n1370017,\n1370048,\n1370081,\n1370112,\n1370145,\n1370176,\n1370209,\n1370240,\n1370273,\n1370304,\n1370337,\n1370368,\n1370401,\n1370432,\n1370465,\n1370496,\n1370529,\n1370560,\n1370593,\n1370624,\n1370657,\n1370688,\n1370721,\n1370752,\n1370785,\n1370816,\n1370849,\n1370880,\n1370913,\n1370944,\n1370977,\n1371008,\n1371041,\n1371072,\n1371105,\n1371136,\n1371169,\n1371200,\n1371233,\n1371264,\n1371297,\n1371328,\n1371361,\n1371392,\n1371425,\n1371456,\n1371489,\n1371520,\n1371553,\n1371584,\n1371617,\n1371651,\n1371681,\n1371936,\n1371969,\n1372000,\n1372033,\n1372064,\n1372129,\n1372160,\n1372193,\n1372224,\n1372257,\n1372288,\n1372321,\n1372352,\n1372385,\n1372419,\n1372468,\n1372512,\n1372545,\n1372576,\n1372609,\n1372644,\n1372672,\n1372705,\n1372736,\n1372769,\n1372864,\n1372897,\n1372928,\n1372961,\n1372992,\n1373025,\n1373056,\n1373089,\n1373120,\n1373153,\n1373184,\n1373217,\n1373248,\n1373281,\n1373312,\n1373345,\n1373376,\n1373409,\n1373440,\n1373473,\n1373504,\n1373665,\n1373696,\n1373857,\n1373888,\n1373921,\n1373952,\n1373985,\n1374016,\n1374049,\n1374080,\n1374113,\n1374144,\n1374177,\n1374208,\n1374241,\n1374272,\n1374305,\n1374336,\n1374465,\n1374496,\n1374529,\n1374560,\n1374625,\n1374685,\n1374720,\n1374753,\n1374813,\n1374817,\n1374877,\n1374881,\n1374912,\n1374945,\n1374976,\n1375009,\n1375040,\n1375073,\n1375104,\n1375165,\n1375811,\n1375904,\n1375937,\n1375972,\n1376003,\n1376065,\n1376100,\n1376325,\n1376356,\n1376453,\n1376484,\n1376613,\n1376644,\n1377382,\n1377445,\n1377510,\n1377557,\n1377669,\n1377725,\n1377802,\n1378005,\n1378067,\n1378101,\n1378141,\n1378308,\n1379985,\n1380125,\n1380358,\n1380420,\n1382022,\n1382533,\n1382621,\n1382865,\n1382920,\n1383261,\n1383429,\n1384004,\n1384209,\n1384292,\n1384337,\n1384356,\n1384421,\n1384456,\n1384772,\n1385669,\n1385937,\n1385988,\n1386725,\n1387078,\n1387165,\n1387505,\n1387524,\n1388477,\n1388549,\n1388646,\n1388676,\n1390181,\n1390214,\n1390277,\n1390406,\n1390469,\n1390534,\n1390641,\n1391069,\n1391075,\n1391112,\n1391453,\n1391569,\n1391620,\n1391781,\n1391811,\n1391844,\n1392136,\n1392452,\n1392637,\n1392644,\n1393957,\n1394150,\n1394213,\n1394278,\n1394341,\n1394429,\n1394692,\n1394789,\n1394820,\n1395077,\n1395110,\n1395165,\n1395208,\n1395549,\n1395601,\n1395716,\n1396227,\n1396260,\n1396469,\n1396548,\n1396582,\n1396613,\n1396646,\n1396676,\n1398277,\n1398308,\n1398341,\n1398436,\n1398501,\n1398564,\n1398725,\n1398788,\n1398821,\n1398852,\n1398909,\n1399652,\n1399715,\n1399761,\n1399812,\n1400166,\n1400197,\n1400262,\n1400337,\n1400388,\n1400419,\n1400486,\n1400517,\n1400573,\n1400868,\n1401085,\n1401124,\n1401341,\n1401380,\n1401597,\n1401860,\n1402109,\n1402116,\n1402365,\n1402369,\n1403764,\n1403779,\n1403905,\n1404195,\n1404244,\n1404317,\n1404417,\n1406980,\n1408102,\n1408165,\n1408198,\n1408261,\n1408294,\n1408369,\n1408390,\n1408421,\n1408477,\n1408520,\n1408861,\n1409028,\n1766557,\n1766916,\n1767677,\n1767780,\n1769373,\n1769499,\n1835036,\n2039812,\n2051549,\n2051588,\n2055005,\n2056193,\n2056445,\n2056801,\n2056989,\n2057124,\n2057157,\n2057188,\n2057522,\n2057540,\n2057981,\n2057988,\n2058173,\n2058180,\n2058237,\n2058244,\n2058333,\n2058340,\n2058429,\n2058436,\n2061908,\n2062461,\n2062948,\n2074574,\n2074605,\n2074645,\n2075140,\n2077213,\n2077252,\n2079005,\n2079221,\n2079261,\n2080260,\n2080659,\n2080693,\n2080773,\n2081297,\n2081517,\n2081550,\n2081585,\n2081629,\n2081797,\n2082321,\n2082348,\n2082411,\n2082477,\n2082510,\n2082541,\n2082574,\n2082605,\n2082638,\n2082669,\n2082702,\n2082733,\n2082766,\n2082797,\n2082830,\n2082861,\n2082894,\n2082925,\n2082958,\n2082993,\n2083053,\n2083086,\n2083121,\n2083243,\n2083345,\n2083453,\n2083473,\n2083596,\n2083629,\n2083662,\n2083693,\n2083726,\n2083757,\n2083790,\n2083825,\n2083922,\n2083948,\n2083986,\n2084093,\n2084113,\n2084147,\n2084177,\n2084253,\n2084356,\n2084541,\n2084548,\n2088893,\n2088954,\n2088989,\n2089009,\n2089107,\n2089137,\n2089229,\n2089262,\n2089297,\n2089330,\n2089361,\n2089388,\n2089425,\n2089480,\n2089809,\n2089874,\n2089969,\n2090016,\n2090861,\n2090897,\n2090926,\n2090964,\n2090987,\n2091028,\n2091041,\n2091885,\n2091922,\n2091950,\n2091986,\n2092013,\n2092046,\n2092081,\n2092109,\n2092142,\n2092177,\n2092228,\n2092547,\n2092580,\n2094019,\n2094084,\n2095101,\n2095172,\n2095389,\n2095428,\n2095645,\n2095684,\n2095901,\n2095940,\n2096061,\n2096147,\n2096210,\n2096244,\n2096277,\n2096307,\n2096381,\n2096405,\n2096434,\n2096565,\n2096637,\n2096954,\n2097045,\n2097117,\n2097156,\n2097565,\n2097572,\n2098429,\n2098436,\n2099069,\n2099076,\n2099165,\n2099172,\n2099677,\n2099716,\n2100189,\n2101252,\n2105213,\n2105361,\n2105469,\n2105578,\n2107037,\n2107125,\n2107401,\n2109098,\n2109237,\n2109770,\n2109845,\n2109949,\n2109973,\n2110397,\n2110485,\n2110525,\n2112021,\n2113445,\n2113501,\n2117636,\n2118589,\n2118660,\n2120253,\n2120709,\n2120746,\n2121629,\n2121732,\n2122762,\n2122909,\n2123172,\n2123817,\n2123844,\n2124105,\n2124157,\n2124292,\n2125509,\n2125693,\n2125828,\n2126813,\n2126833,\n2126852,\n2128029,\n2128132,\n2128401,\n2128425,\n2128605,\n2129920,\n2131201,\n2132484,\n2135005,\n2135048,\n2135389,\n2135552,\n2136733,\n2136833,\n2138013,\n2138116,\n2139421,\n2139652,\n2141341,\n2141681,\n2141696,\n2142077,\n2142080,\n2142589,\n2142592,\n2142845,\n2142848,\n2142941,\n2142945,\n2143325,\n2143329,\n2143837,\n2143841,\n2144093,\n2144097,\n2144189,\n2144260,\n2145949,\n2146308,\n2156285,\n2156548,\n2157277,\n2157572,\n2157853,\n2158595,\n2158813,\n2158819,\n2160189,\n2160195,\n2160509,\n2162692,\n2162909,\n2162948,\n2163005,\n2163012,\n2164445,\n2164452,\n2164541,\n2164612,\n2164669,\n2164708,\n2165469,\n2165489,\n2165514,\n2165764,\n2166517,\n2166570,\n2166788,\n2167805,\n2168042,\n2168349,\n2169860,\n2170493,\n2170500,\n2170589,\n2170730,\n2170884,\n2171594,\n2171805,\n2171889,\n2171908,\n2172765,\n2172913,\n2172957,\n2174980,\n2176797,\n2176906,\n2176964,\n2177034,\n2177565,\n2177610,\n2179076,\n2179109,\n2179229,\n2179237,\n2179325,\n2179461,\n2179588,\n2179741,\n2179748,\n2179869,\n2179876,\n2180829,\n2180869,\n2180989,\n2181093,\n2181130,\n2181437,\n2181649,\n2181949,\n2182148,\n2183082,\n2183153,\n2183172,\n2184106,\n2184221,\n2185220,\n2185493,\n2185508,\n2186405,\n2186493,\n2186602,\n2186769,\n2187005,\n2187268,\n2189021,\n2189105,\n2189316,\n2190045,\n2190090,\n2190340,\n2190973,\n2191114,\n2191364,\n2191965,\n2192177,\n2192317,\n2192682,\n2192925,\n2195460,\n2197821,\n2199552,\n2201213,\n2201601,\n2203261,\n2203466,\n2203652,\n2204805,\n2204957,\n2205192,\n2205533,\n2205704,\n2206020,\n2206147,\n2206180,\n2206208,\n2206941,\n2207013,\n2207180,\n2207203,\n2207233,\n2207965,\n2208210,\n2208285,\n2214922,\n2215933,\n2215940,\n2217309,\n2217317,\n2217388,\n2217437,\n2217476,\n2217565,\n2218052,\n2218173,\n2219909,\n2220036,\n2220970,\n2221284,\n2221341,\n2221572,\n2222277,\n2222634,\n2222769,\n2222941,\n2223620,\n2224197,\n2224337,\n2224477,\n2225668,\n2226346,\n2226589,\n2227204,\n2227965,\n2228230,\n2228261,\n2228294,\n2228324,\n2230021,\n2230513,\n2230749,\n2230858,\n2231496,\n2231813,\n2231844,\n2231909,\n2231972,\n2232029,\n2232293,\n2232390,\n2232420,\n2233862,\n2233957,\n2234086,\n2234149,\n2234225,\n2234298,\n2234321,\n2234437,\n2234493,\n2234810,\n2234845,\n2234884,\n2235709,\n2235912,\n2236253,\n2236421,\n2236516,\n2237669,\n2237830,\n2237861,\n2238141,\n2238152,\n2238481,\n2238596,\n2238630,\n2238692,\n2238749,\n2238980,\n2240101,\n2240145,\n2240196,\n2240253,\n2240517,\n2240582,\n2240612,\n2242150,\n2242245,\n2242534,\n2242596,\n2242737,\n2242853,\n2242993,\n2243014,\n2243045,\n2243080,\n2243396,\n2243441,\n2243460,\n2243505,\n2243613,\n2243626,\n2244285,\n2244612,\n2245213,\n2245220,\n2246022,\n2246117,\n2246214,\n2246277,\n2246310,\n2246341,\n2246417,\n2246597,\n2246628,\n2246693,\n2246749,\n2248708,\n2248957,\n2248964,\n2249021,\n2249028,\n2249181,\n2249188,\n2249693,\n2249700,\n2250033,\n2250077,\n2250244,\n2251749,\n2251782,\n2251877,\n2252157,\n2252296,\n2252637,\n2252805,\n2252870,\n2252957,\n2252964,\n2253245,\n2253284,\n2253373,\n2253412,\n2254141,\n2254148,\n2254397,\n2254404,\n2254493,\n2254500,\n2254685,\n2254693,\n2254756,\n2254790,\n2254853,\n2254886,\n2255037,\n2255078,\n2255165,\n2255206,\n2255325,\n2255364,\n2255421,\n2255590,\n2255645,\n2255780,\n2255942,\n2256029,\n2256069,\n2256317,\n2256389,\n2256573,\n2256900,\n2257245,\n2257252,\n2257309,\n2257348,\n2257405,\n2257412,\n2258653,\n2258660,\n2258694,\n2258789,\n2259005,\n2259014,\n2259069,\n2259110,\n2259165,\n2259174,\n2259325,\n2259334,\n2259397,\n2259430,\n2259461,\n2259492,\n2259525,\n2259556,\n2259601,\n2259677,\n2259697,\n2259773,\n2260005,\n2260093,\n2260996,\n2262694,\n2262789,\n2263046,\n2263109,\n2263206,\n2263237,\n2263268,\n2263409,\n2263560,\n2263889,\n2263965,\n2263985,\n2264005,\n2264036,\n2264157,\n2265092,\n2266630,\n2266725,\n2266918,\n2266949,\n2266982,\n2267109,\n2267174,\n2267205,\n2267268,\n2267345,\n2267364,\n2267421,\n2267656,\n2267997,\n2273284,\n2274790,\n2274885,\n2275037,\n2275078,\n2275205,\n2275270,\n2275301,\n2275377,\n2276100,\n2276229,\n2276317,\n2277380,\n2278918,\n2279013,\n2279270,\n2279333,\n2279366,\n2279397,\n2279473,\n2279556,\n2279613,\n2279944,\n2280285,\n2280465,\n2280893,\n2281476,\n2282853,\n2282886,\n2282917,\n2282950,\n2283013,\n2283206,\n2283237,\n2283268,\n2283313,\n2283357,\n2283528,\n2283869,\n2284040,\n2284701,\n2285572,\n2286461,\n2286501,\n2286534,\n2286565,\n2286598,\n2286661,\n2286790,\n2286821,\n2287005,\n2287112,\n2287434,\n2287505,\n2287605,\n2287620,\n2287869,\n2293764,\n2295174,\n2295269,\n2295558,\n2295589,\n2295665,\n2295709,\n2298880,\n2299905,\n2300936,\n2301258,\n2301565,\n2301924,\n2302205,\n2302244,\n2302301,\n2302340,\n2302621,\n2302628,\n2302717,\n2302724,\n2303494,\n2303709,\n2303718,\n2303805,\n2303845,\n2303910,\n2303941,\n2303972,\n2304006,\n2304036,\n2304070,\n2304101,\n2304145,\n2304253,\n2304520,\n2304861,\n2307076,\n2307357,\n2307396,\n2308646,\n2308741,\n2308893,\n2308933,\n2308998,\n2309125,\n2309156,\n2309201,\n2309220,\n2309254,\n2309309,\n2310148,\n2310181,\n2310500,\n2311781,\n2311974,\n2312004,\n2312037,\n2312177,\n2312421,\n2312477,\n2312708,\n2312741,\n2312934,\n2312997,\n2313092,\n2314565,\n2314982,\n2315013,\n2315089,\n2315172,\n2315217,\n2315389,\n2315780,\n2318141,\n2318353,\n2318685,\n2324484,\n2325553,\n2325597,\n2326024,\n2326365,\n2326532,\n2326845,\n2326852,\n2328038,\n2328069,\n2328317,\n2328325,\n2328518,\n2328549,\n2328580,\n2328625,\n2328797,\n2329096,\n2329418,\n2330045,\n2330129,\n2330180,\n2331165,\n2331205,\n2331933,\n2331942,\n2331973,\n2332198,\n2332229,\n2332294,\n2332325,\n2332413,\n2334724,\n2334973,\n2334980,\n2335069,\n2335076,\n2336293,\n2336509,\n2336581,\n2336637,\n2336645,\n2336733,\n2336741,\n2336964,\n2336997,\n2337053,\n2337288,\n2337629,\n2337796,\n2338013,\n2338020,\n2338109,\n2338116,\n2339142,\n2339325,\n2339333,\n2339421,\n2339430,\n2339493,\n2339526,\n2339557,\n2339588,\n2339645,\n2339848,\n2340189,\n2350084,\n2350693,\n2350758,\n2350833,\n2350909,\n2351109,\n2351172,\n2351206,\n2351236,\n2351677,\n2351684,\n2352774,\n2352837,\n2353021,\n2353094,\n2353157,\n2353190,\n2353221,\n2353265,\n2353672,\n2353989,\n2354045,\n2356740,\n2356797,\n2357258,\n2357941,\n2358195,\n2358325,\n2358877,\n2359281,\n2359300,\n2388829,\n2392073,\n2395645,\n2395665,\n2395837,\n2396164,\n2402461,\n2486788,\n2489905,\n2489981,\n2490372,\n2524698,\n2525189,\n2525220,\n2525413,\n2525917,\n2526212,\n2654077,\n2654212,\n2672893,\n2891780,\n2892741,\n2893126,\n2893221,\n2893320,\n2893661,\n2949124,\n2967357,\n2967556,\n2968573,\n2968584,\n2968925,\n2969041,\n2969092,\n2971645,\n2971656,\n2971997,\n2972164,\n2973149,\n2973189,\n2973361,\n2973405,\n2973700,\n2975237,\n2975473,\n2975637,\n2975747,\n2975889,\n2975925,\n2975965,\n2976264,\n2976605,\n2976618,\n2976861,\n2976868,\n2977565,\n2977700,\n2978333,\n2992131,\n2992228,\n2993507,\n2993585,\n2993672,\n2994013,\n3000320,\n3001345,\n3002378,\n3003121,\n3003261,\n3006468,\n3008893,\n3008997,\n3009028,\n3009062,\n3010845,\n3011045,\n3011171,\n3011613,\n3013635,\n3013713,\n3013731,\n3013765,\n3013821,\n3014150,\n3014237,\n3014660,\n3211037,\n3211268,\n3250909,\n3252196,\n3252541,\n3538435,\n3538589,\n3538595,\n3538845,\n3538851,\n3538941,\n3538948,\n3548285,\n3548740,\n3548797,\n3549700,\n3549821,\n3549860,\n3549917,\n3550340,\n3550493,\n3550724,\n3563421,\n3637252,\n3640701,\n3640836,\n3641277,\n3641348,\n3641661,\n3641860,\n3642205,\n3642261,\n3642277,\n3642353,\n3642394,\n3642525,\n3768341,\n3776008,\n3776349,\n3776533,\n3790493,\n3792901,\n3794397,\n3794437,\n3795197,\n3795477,\n3799197,\n3801109,\n3808989,\n3809301,\n3810557,\n3810613,\n3812518,\n3812581,\n3812693,\n3812774,\n3812986,\n3813221,\n3813493,\n3813541,\n3813781,\n3814725,\n3814869,\n3816829,\n3817493,\n3819589,\n3819701,\n3819741,\n3823626,\n3824285,\n3824650,\n3825309,\n3825685,\n3828477,\n3828746,\n3829565,\n3833856,\n3834689,\n3835520,\n3836353,\n3836605,\n3836609,\n3837184,\n3838017,\n3838848,\n3838909,\n3838912,\n3839005,\n3839040,\n3839101,\n3839136,\n3839229,\n3839264,\n3839421,\n3839424,\n3839681,\n3839837,\n3839841,\n3839901,\n3839905,\n3840157,\n3840161,\n3840512,\n3841345,\n3842176,\n3842269,\n3842272,\n3842429,\n3842464,\n3842749,\n3842752,\n3843005,\n3843009,\n3843840,\n3843933,\n3843936,\n3844093,\n3844096,\n3844285,\n3844288,\n3844349,\n3844416,\n3844669,\n3844673,\n3845504,\n3846337,\n3847168,\n3848001,\n3848832,\n3849665,\n3850496,\n3851329,\n3852160,\n3852993,\n3853824,\n3854657,\n3855581,\n3855616,\n3856434,\n3856449,\n3857266,\n3857281,\n3857472,\n3858290,\n3858305,\n3859122,\n3859137,\n3859328,\n3860146,\n3860161,\n3860978,\n3860993,\n3861184,\n3862002,\n3862017,\n3862834,\n3862849,\n3863040,\n3863858,\n3863873,\n3864690,\n3864705,\n3864896,\n3864929,\n3864989,\n3865032,\n3866645,\n3883013,\n3884789,\n3884901,\n3886517,\n3886757,\n3886805,\n3887237,\n3887285,\n3887345,\n3887517,\n3887973,\n3888157,\n3888165,\n3888669,\n3923969,\n3924292,\n3924321,\n3924989,\n3925153,\n3925373,\n3932165,\n3932413,\n3932421,\n3932989,\n3933029,\n3933277,\n3933285,\n3933373,\n3933381,\n3933565,\n3933699,\n3935709,\n3936741,\n3936797,\n3940356,\n3941821,\n3941893,\n3942115,\n3942365,\n3942408,\n3942749,\n3942852,\n3942901,\n3942941,\n3953156,\n3954117,\n3954173,\n3954692,\n3956101,\n3956232,\n3956573,\n3956723,\n3956765,\n3971588,\n3972451,\n3972485,\n3972616,\n3972957,\n3979780,\n3980741,\n3980804,\n3980840,\n3981181,\n3981297,\n3981341,\n3996676,\n3996925,\n3996932,\n3997085,\n3997092,\n3997181,\n3997188,\n3997693,\n3997700,\n4004029,\n4004074,\n4004357,\n4004605,\n4005888,\n4006977,\n4008069,\n4008291,\n4008349,\n4008456,\n4008797,\n4008913,\n4008989,\n4034090,\n4035989,\n4036010,\n4036115,\n4036138,\n4036285,\n4038698,\n4040149,\n4040170,\n4040669,\n4046852,\n4047005,\n4047012,\n4047901,\n4047908,\n4047997,\n4048004,\n4048061,\n4048100,\n4048157,\n4048164,\n4048509,\n4048516,\n4048669,\n4048676,\n4048733,\n4048740,\n4048797,\n4048964,\n4049021,\n4049124,\n4049181,\n4049188,\n4049245,\n4049252,\n4049309,\n4049316,\n4049437,\n4049444,\n4049533,\n4049540,\n4049597,\n4049636,\n4049693,\n4049700,\n4049757,\n4049764,\n4049821,\n4049828,\n4049885,\n4049892,\n4049949,\n4049956,\n4050045,\n4050052,\n4050109,\n4050148,\n4050301,\n4050308,\n4050557,\n4050564,\n4050717,\n4050724,\n4050877,\n4050884,\n4050941,\n4050948,\n4051293,\n4051300,\n4051869,\n4052004,\n4052125,\n4052132,\n4052317,\n4052324,\n4052893,\n4054546,\n4054621,\n4063253,\n4064669,\n4064789,\n4067997,\n4068373,\n4068861,\n4068917,\n4069405,\n4069429,\n4069917,\n4069941,\n4071133,\n4071434,\n4071861,\n4077021,\n4078805,\n4079741,\n4080149,\n4081565,\n4081685,\n4081981,\n4082197,\n4082269,\n4082709,\n4082909,\n4087829,\n4095860,\n4096021,\n4119325,\n4119445,\n4119997,\n4120085,\n4120509,\n4120597,\n4124413,\n4124533,\n4127581,\n4127765,\n4128157,\n4128277,\n4128317,\n4128789,\n4129181,\n4129301,\n4131101,\n4131349,\n4131677,\n4131861,\n4133149,\n4133397,\n4134365,\n4134421,\n4134813,\n4134933,\n4135005,\n4136981,\n4147869,\n4148245,\n4148701,\n4148757,\n4149181,\n4149269,\n4149597,\n4149749,\n4151549,\n4151765,\n4152253,\n4152309,\n4152669,\n4152853,\n4153149,\n4153365,\n4158077,\n4158101,\n4161032,\n4161373,\n4194308,\n5561373,\n5562372,\n5695325,\n5695492,\n5702621,\n5702660,\n5887069,\n5887492,\n6126653,\n6127108,\n6147037,\n6225924,\n6243293,\n6291460,\n6449533,\n6449668,\n6583837,\n29360186,\n29360221,\n29361178,\n29364253,\n29368325,\n29376029,\n31457308,\n33554397,\n33554460,\n35651549,\n35651613,\n//--Autogenerated -- end of section automatically generated\n};\n\nconstexpr int maxUnicode = 0x10ffff;\nconstexpr int maskCategory = 0x1F;\n\n}\n\n// Each element in catRanges is the start of a range of Unicode characters in\n// one general category.\n// The value is comprised of a 21-bit character value shifted 5 bits and a 5 bit\n// category matching the CharacterCategory enumeration.\n// Initial version has 3249 entries and adds about 13K to the executable.\n// The array is in ascending order so can be searched using binary search.\n// Therefore the average call takes log2(3249) = 12 comparisons.\n// For speed, it may be useful to make a linear table for the common values,\n// possibly for 0..0xff for most Western European text or 0..0xfff for most\n// alphabetic languages.\n\nCharacterCategory CategoriseCharacter(int character) noexcept {\n\tif (character < 0 || character > maxUnicode)\n\t\treturn ccCn;\n\tconst int baseValue = character * (maskCategory+1) + maskCategory;\n\ttry {\n\t\t// lower_bound will never throw with these args but its not marked noexcept so add catch to pretend.\n\t\tconst int *placeAfter = std::lower_bound(catRanges, std::end(catRanges), baseValue);\n\t\treturn static_cast<CharacterCategory>(*(placeAfter - 1) & maskCategory);\n\t} catch (...) {\n\t\treturn ccCn;\n\t}\n}\n\n// Implementation of character sets recommended for identifiers in Unicode Standard Annex #31.\n// http://unicode.org/reports/tr31/\n\nnamespace {\n\nenum class OtherID { oidNone, oidStart, oidContinue };\n\n// Some characters are treated as valid for identifiers even\n// though most characters from their category are not.\n// Values copied from http://www.unicode.org/Public/9.0.0/ucd/PropList.txt\nOtherID OtherIDOfCharacter(int character) noexcept {\n\tif (\n\t\t(character == 0x1885) ||\t// MONGOLIAN LETTER ALI GALI BALUDA\n\t\t(character == 0x1886) ||\t// MONGOLIAN LETTER ALI GALI THREE BALUDA\n\t\t(character == 0x2118) ||\t// SCRIPT CAPITAL P\n\t\t(character == 0x212E) ||\t// ESTIMATED SYMBOL\n\t\t(character == 0x309B) ||\t// KATAKANA-HIRAGANA VOICED SOUND MARK\n\t\t(character == 0x309C)) {\t// KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK\n\t\treturn OtherID::oidStart;\n\t} else if (\n\t\t(character == 0x00B7) ||\t// MIDDLE DOT\n\t\t(character == 0x0387) ||\t// GREEK ANO TELEIA\n\t\t((character >= 0x1369) && (character <= 0x1371)) ||\t// ETHIOPIC DIGIT ONE..ETHIOPIC DIGIT NINE\n\t\t(character == 0x19DA)) {\t// NEW TAI LUE THAM DIGIT ONE\n\t\treturn OtherID::oidContinue;\n\t} else {\n\t\treturn OtherID::oidNone;\n\t}\n}\n\n// Determine if a character is in  Ll|Lu|Lt|Lm|Lo|Nl|Mn|Mc|Nd|Pc and has\n// Pattern_Syntax|Pattern_White_Space.\n// As of Unicode 9, only VERTICAL TILDE which is in Lm and has Pattern_Syntax matches.\n// Should really generate from PropList.txt a list of Pattern_Syntax and Pattern_White_Space.\nconstexpr bool IsIdPattern(int character) noexcept {\n\treturn character == 0x2E2F;\n}\n\nbool OmitXidStart(int character) noexcept {\n\tswitch (character) {\n\tcase 0x037A:\t// GREEK YPOGEGRAMMENI\n\tcase 0x0E33:\t// THAI CHARACTER SARA AM\n\tcase 0x0EB3:\t// LAO VOWEL SIGN AM\n\tcase 0x309B:\t// KATAKANA-HIRAGANA VOICED SOUND MARK\n\tcase 0x309C:\t// KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK\n\tcase 0xFC5E:\t// ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM\n\tcase 0xFC5F:\t// ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM\n\tcase 0xFC60:\t// ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM\n\tcase 0xFC61:\t// ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM\n\tcase 0xFC62:\t// ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM\n\tcase 0xFC63:\t// ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM\n\tcase 0xFDFA:\t// ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM\n\tcase 0xFDFB:\t// ARABIC LIGATURE JALLAJALALOUHOU\n\tcase 0xFE70:\t// ARABIC FATHATAN ISOLATED FORM\n\tcase 0xFE72:\t// ARABIC DAMMATAN ISOLATED FORM\n\tcase 0xFE74:\t// ARABIC KASRATAN ISOLATED FORM\n\tcase 0xFE76:\t// ARABIC FATHA ISOLATED FORM\n\tcase 0xFE78:\t// ARABIC DAMMA ISOLATED FORM\n\tcase 0xFE7A:\t// ARABIC KASRA ISOLATED FORM\n\tcase 0xFE7C:\t// ARABIC SHADDA ISOLATED FORM\n\tcase 0xFE7E:\t// ARABIC SUKUN ISOLATED FORM\n\tcase 0xFF9E:\t// HALFWIDTH KATAKANA VOICED SOUND MARK\n\tcase 0xFF9F:\t// HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool OmitXidContinue(int character) noexcept {\n\tswitch (character) {\n\tcase 0x037A:\t// GREEK YPOGEGRAMMENI\n\tcase 0x309B:\t// KATAKANA-HIRAGANA VOICED SOUND MARK\n\tcase 0x309C:\t// KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK\n\tcase 0xFC5E:\t// ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM\n\tcase 0xFC5F:\t// ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM\n\tcase 0xFC60:\t// ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM\n\tcase 0xFC61:\t// ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM\n\tcase 0xFC62:\t// ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM\n\tcase 0xFC63:\t// ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM\n\tcase 0xFDFA:\t// ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM\n\tcase 0xFDFB:\t// ARABIC LIGATURE JALLAJALALOUHOU\n\tcase 0xFE70:\t// ARABIC FATHATAN ISOLATED FORM\n\tcase 0xFE72:\t// ARABIC DAMMATAN ISOLATED FORM\n\tcase 0xFE74:\t// ARABIC KASRATAN ISOLATED FORM\n\tcase 0xFE76:\t// ARABIC FATHA ISOLATED FORM\n\tcase 0xFE78:\t// ARABIC DAMMA ISOLATED FORM\n\tcase 0xFE7A:\t// ARABIC KASRA ISOLATED FORM\n\tcase 0xFE7C:\t// ARABIC SHADDA ISOLATED FORM\n\tcase 0xFE7E:\t// ARABIC SUKUN ISOLATED FORM\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\n}\n\n// UAX #31 defines ID_Start as\n// [[:L:][:Nl:][:Other_ID_Start:]--[:Pattern_Syntax:]--[:Pattern_White_Space:]]\nbool IsIdStart(int character) noexcept {\n\tif (IsIdPattern(character)) {\n\t\treturn false;\n\t}\n\tconst OtherID oid = OtherIDOfCharacter(character);\n\tif (oid == OtherID::oidStart) {\n\t\treturn true;\n\t}\n\tconst CharacterCategory c = CategoriseCharacter(character);\n\treturn (c == ccLl || c == ccLu || c == ccLt || c == ccLm || c == ccLo\n\t\t|| c == ccNl);\n}\n\n// UAX #31 defines ID_Continue as\n// [[:ID_Start:][:Mn:][:Mc:][:Nd:][:Pc:][:Other_ID_Continue:]--[:Pattern_Syntax:]--[:Pattern_White_Space:]]\nbool IsIdContinue(int character) noexcept {\n\tif (IsIdPattern(character)) {\n\t\treturn false;\n\t}\n\tconst OtherID oid = OtherIDOfCharacter(character);\n\tif (oid != OtherID::oidNone) {\n\t\treturn true;\n\t}\n\tconst CharacterCategory c = CategoriseCharacter(character);\n\treturn (c == ccLl || c == ccLu || c == ccLt || c == ccLm || c == ccLo\n\t\t|| c == ccNl || c == ccMn || c == ccMc || c == ccNd || c == ccPc);\n}\n\n// XID_Start is ID_Start modified for Normalization Form KC in UAX #31\nbool IsXidStart(int character) noexcept {\n\tif (OmitXidStart(character)) {\n\t\treturn false;\n\t}\n\treturn IsIdStart(character);\n}\n\n// XID_Continue is ID_Continue modified for Normalization Form KC in UAX #31\nbool IsXidContinue(int character) noexcept {\n\tif (OmitXidContinue(character)) {\n\t\treturn false;\n\t}\n\treturn IsIdContinue(character);\n}\n\nCharacterCategoryMap::CharacterCategoryMap() {\n\tOptimize(256);\n}\n\nint CharacterCategoryMap::Size() const noexcept {\n\treturn static_cast<int>(dense.size());\n}\n\nvoid CharacterCategoryMap::Optimize(int countCharacters) {\n\tconst int characters = std::clamp(countCharacters, 256, maxUnicode + 1);\n\tdense.resize(characters);\n\n\tint end = 0;\n\tint index = 0;\n\tint current = catRanges[index];\n\t++index;\n\tdo {\n\t\tconst int next = catRanges[index];\n\t\tconst unsigned char category = current & maskCategory;\n\t\tcurrent >>= 5;\n\t\tend = std::min(characters, next >> 5);\n\t\twhile (current < end) {\n\t\t\tdense[current++] = category;\n\t\t}\n\t\tcurrent = next;\n\t\t++index;\n\t} while (characters > end);\n}\n\n}\n"
  },
  {
    "path": "lexlib/CharacterCategory.h",
    "content": "// Scintilla source code edit control\n/** @file CharacterCategory.h\n ** Returns the Unicode general category of a character.\n **/\n// Copyright 2013 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef CHARACTERCATEGORY_H\n#define CHARACTERCATEGORY_H\n\nnamespace Lexilla {\n\nenum CharacterCategory {\n\tccLu, ccLl, ccLt, ccLm, ccLo,\n\tccMn, ccMc, ccMe,\n\tccNd, ccNl, ccNo,\n\tccPc, ccPd, ccPs, ccPe, ccPi, ccPf, ccPo,\n\tccSm, ccSc, ccSk, ccSo,\n\tccZs, ccZl, ccZp,\n\tccCc, ccCf, ccCs, ccCo, ccCn\n};\n\nCharacterCategory CategoriseCharacter(int character) noexcept;\n\n// Common definitions of allowable characters in identifiers from UAX #31.\nbool IsIdStart(int character) noexcept;\nbool IsIdContinue(int character) noexcept;\nbool IsXidStart(int character) noexcept;\nbool IsXidContinue(int character) noexcept;\n\nclass CharacterCategoryMap {\nprivate:\n\tstd::vector<unsigned char> dense;\npublic:\n\tCharacterCategoryMap();\n\tCharacterCategory CategoryFor(int character) const noexcept {\n\t\tif (static_cast<size_t>(character) < dense.size()) {\n\t\t\treturn static_cast<CharacterCategory>(dense[character]);\n\t\t} else {\n\t\t\t// binary search through ranges\n\t\t\treturn CategoriseCharacter(character);\n\t\t}\n\t}\n\tint Size() const noexcept;\n\tvoid Optimize(int countCharacters);\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/CharacterSet.cxx",
    "content": "// Scintilla source code edit control\n/** @file CharacterSet.cxx\n ** Simple case functions for ASCII.\n ** Lexer infrastructure.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n\n#include <string_view>\n\n#include \"CharacterSet.h\"\n\nusing namespace Lexilla;\n\nnamespace Lexilla {\n\nint CompareCaseInsensitive(const char *a, const char *b) noexcept {\n\twhile (*a && *b) {\n\t\tif (*a != *b) {\n\t\t\tconst char upperA = MakeUpperCase(*a);\n\t\t\tconst char upperB = MakeUpperCase(*b);\n\t\t\tif (upperA != upperB)\n\t\t\t\treturn upperA - upperB;\n\t\t}\n\t\ta++;\n\t\tb++;\n\t}\n\t// Either *a or *b is nul\n\treturn *a - *b;\n}\n\nbool EqualCaseInsensitive(std::string_view a, std::string_view b) noexcept {\n\tif (a.length() != b.length()) {\n\t\treturn false;\n\t}\n\tfor (size_t i = 0; i < a.length(); i++) {\n\t\tif (MakeUpperCase(a[i]) != MakeUpperCase(b[i])) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nint CompareNCaseInsensitive(const char *a, const char *b, size_t len) noexcept {\n\twhile (*a && *b && len) {\n\t\tif (*a != *b) {\n\t\t\tconst char upperA = MakeUpperCase(*a);\n\t\t\tconst char upperB = MakeUpperCase(*b);\n\t\t\tif (upperA != upperB)\n\t\t\t\treturn upperA - upperB;\n\t\t}\n\t\ta++;\n\t\tb++;\n\t\tlen--;\n\t}\n\tif (len == 0)\n\t\treturn 0;\n\t// Either *a or *b is nul\n\treturn *a - *b;\n}\n\n}\n"
  },
  {
    "path": "lexlib/CharacterSet.h",
    "content": "// Scintilla source code edit control\n/** @file CharacterSet.h\n ** Encapsulates a set of characters. Used to test if a character is within a set.\n **/\n// Copyright 2007 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef CHARACTERSET_H\n#define CHARACTERSET_H\n\nnamespace Lexilla {\n\ntemplate<int N>\nclass CharacterSetArray {\n\tstatic constexpr int bitsPerChar = 8;\n\tstatic constexpr int mask3Bits = 7;\n\tunsigned char bset[((N-1)/bitsPerChar) + 1] = {};\n\tbool valueAfter = false;\npublic:\n\tenum setBase {\n\t\tsetNone=0,\n\t\tsetLower=1,\n\t\tsetUpper=2,\n\t\tsetDigits=4,\n\t\tsetAlpha=setLower|setUpper,\n\t\tsetAlphaNum=setAlpha|setDigits\n\t};\n\texplicit CharacterSetArray(setBase base=setNone, const char *initialSet=\"\", bool valueAfter_=false) noexcept {\n\t\tvalueAfter = valueAfter_;\n\t\tAddString(initialSet);\n\t\tif (base & setLower)\n\t\t\tAddString(\"abcdefghijklmnopqrstuvwxyz\");\n\t\tif (base & setUpper)\n\t\t\tAddString(\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\");\n\t\tif (base & setDigits)\n\t\t\tAddString(\"0123456789\");\n\t}\n\texplicit CharacterSetArray(const char *initialSet, bool valueAfter_=false) noexcept :\n\t\tCharacterSetArray(setNone, initialSet, valueAfter_) {\n\t}\n\t// For compatibility with previous version but should not be used in new code.\n\tCharacterSetArray(setBase base, const char *initialSet, [[maybe_unused]]int size_, bool valueAfter_=false) noexcept :\n\t\tCharacterSetArray(base, initialSet, valueAfter_) {\n\t\tassert(size_ == N);\n\t}\n\tvoid Add(int val) noexcept {\n\t\tassert(val >= 0);\n\t\tassert(val < N);\n\t\tbset[val >> 3] |= 1 << (val & mask3Bits);\n\t}\n\tvoid AddString(const char *setToAdd) noexcept {\n\t\tfor (const char *cp=setToAdd; *cp; cp++) {\n\t\t\tconst unsigned char uch = *cp;\n\t\t\tassert(uch < N);\n\t\t\tAdd(uch);\n\t\t}\n\t}\n\t[[nodiscard]] bool Contains(int val) const noexcept {\n\t\tassert(val >= 0);\n\t\tif (val < 0) return false;\n\t\tif (val >= N) return valueAfter;\n\t\treturn bset[val >> 3] & (1 << (val & mask3Bits));\n\t}\n\t[[nodiscard]] bool Contains(char ch) const noexcept {\n\t\t// Overload char as char may be signed\n\t\tconst unsigned char uch = ch;\n\t\treturn Contains(uch);\n\t}\n};\n\nconstexpr int countASCII = 0x80;\nusing CharacterSet = CharacterSetArray<countASCII>;\n\n// Functions for classifying characters\n\ntemplate <typename T, typename... Args>\nconstexpr bool AnyOf(T t, Args... args) noexcept {\n#if defined(__clang__)\n\tstatic_assert(__is_integral(T) || __is_enum(T));\n#endif\n\treturn ((t == args) || ...);\n}\n\n// prevent pointer without <type_traits>\ntemplate <typename T, typename... Args>\nconstexpr void AnyOf([[maybe_unused]] T *t, [[maybe_unused]] Args... args) noexcept {}\ntemplate <typename T, typename... Args>\nconstexpr void AnyOf([[maybe_unused]] const T *t, [[maybe_unused]] Args... args) noexcept {}\n\nconstexpr int charTab = 0x09;\nconstexpr int charCarriageReturn = 0x0D;\n\nconstexpr bool IsASpace(int ch) noexcept {\n    return (ch == ' ') || ((ch >= charTab) && (ch <= charCarriageReturn));\n}\n\nconstexpr bool IsASpaceOrTab(int ch) noexcept {\n\treturn (ch == ' ') || (ch == '\\t');\n}\n\nconstexpr bool IsADigit(int ch) noexcept {\n\treturn (ch >= '0') && (ch <= '9');\n}\n\nconstexpr bool IsAHeXDigit(int ch) noexcept {\n\treturn (ch >= '0' && ch <= '9')\n\t\t|| (ch >= 'A' && ch <= 'F')\n\t\t|| (ch >= 'a' && ch <= 'f');\n}\n\nconstexpr bool IsAnOctalDigit(int ch) noexcept {\n\treturn ch >= '0' && ch <= '7';\n}\n\nconstexpr bool IsADigit(int ch, int base) noexcept {\n\tconstexpr int digits = 10;\n\tif (base <= digits) {\n\t\treturn (ch >= '0') && (ch < '0' + base);\n\t}\n\treturn ((ch >= '0') && (ch <= '9')) ||\n\t\t    ((ch >= 'A') && (ch < 'A' + base - digits)) ||\n\t\t    ((ch >= 'a') && (ch < 'a' + base - digits));\n}\n\nconstexpr bool IsASCII(int ch) noexcept {\n\tconstexpr int lastASCII = 0x7F;\n\treturn (ch >= 0) && (ch <= lastASCII);\n}\n\nconstexpr bool IsLowerCase(int ch) noexcept {\n\treturn (ch >= 'a') && (ch <= 'z');\n}\n\nconstexpr bool IsUpperCase(int ch) noexcept {\n\treturn (ch >= 'A') && (ch <= 'Z');\n}\n\nconstexpr bool IsUpperOrLowerCase(int ch) noexcept {\n\treturn IsUpperCase(ch) || IsLowerCase(ch);\n}\n\nconstexpr bool IsAlphaNumeric(int ch) noexcept {\n\treturn\n\t\t((ch >= '0') && (ch <= '9')) ||\n\t\t((ch >= 'a') && (ch <= 'z')) ||\n\t\t((ch >= 'A') && (ch <= 'Z'));\n}\n\n/**\n * Check if a character is a space.\n * This is ASCII specific but is safe with chars >= 0x80.\n */\nconstexpr bool isspacechar(int ch) noexcept {\n    return (ch == ' ') || ((ch >= charTab) && (ch <= charCarriageReturn));\n}\n\nconstexpr bool iswordchar(int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '.' || ch == '_';\n}\n\nconstexpr bool iswordstart(int ch) noexcept {\n\treturn IsAlphaNumeric(ch) || ch == '_';\n}\n\nconstexpr bool isoperator(int ch) noexcept {\n\tif (IsAlphaNumeric(ch))\n\t\treturn false;\n\tif (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||\n\t        ch == '(' || ch == ')' || ch == '-' || ch == '+' ||\n\t        ch == '=' || ch == '|' || ch == '{' || ch == '}' ||\n\t        ch == '[' || ch == ']' || ch == ':' || ch == ';' ||\n\t        ch == '<' || ch == '>' || ch == ',' || ch == '/' ||\n\t        ch == '?' || ch == '!' || ch == '.' || ch == '~')\n\t\treturn true;\n\treturn false;\n}\n\n// Simple case functions for ASCII supersets.\n\ntemplate <typename T>\nconstexpr T MakeUpperCase(T ch) noexcept {\n\tif (ch < 'a' || ch > 'z')\n\t\treturn ch;\n\treturn ch - 'a' + 'A';\n}\n\ntemplate <typename T>\nconstexpr T MakeLowerCase(T ch) noexcept {\n\tif (ch < 'A' || ch > 'Z')\n\t\treturn ch;\n\treturn ch - 'A' + 'a';\n}\n\nint CompareCaseInsensitive(const char *a, const char *b) noexcept;\nbool EqualCaseInsensitive(std::string_view a, std::string_view b) noexcept;\nint CompareNCaseInsensitive(const char *a, const char *b, size_t len) noexcept;\n\nconstexpr bool StartsWith(std::string_view s, char start) noexcept {\n\treturn !s.empty() && (s.front() == start);\n}\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/DefaultLexer.cxx",
    "content": "// Scintilla source code edit control\n/** @file DefaultLexer.cxx\n ** A lexer base class that provides reasonable default behaviour.\n **/\n// Copyright 2017 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <map>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"LexerModule.h\"\n#include \"OptionSet.h\"\n#include \"DefaultLexer.h\"\n\nusing namespace Lexilla;\n\nstatic const char styleSubable[] = { 0 };\n\nDefaultLexer::DefaultLexer(const char *languageName_, int language_,\n\tconst LexicalClass *lexClasses_, size_t nClasses_) :\n\tlanguageName(languageName_),\n\tlanguage(language_),\n\tlexClasses(lexClasses_),\n\tnClasses(nClasses_) {\n}\n\nDefaultLexer::~DefaultLexer() = default;\n\nvoid SCI_METHOD DefaultLexer::Release() {\n\tdelete this;\n}\n\nint SCI_METHOD DefaultLexer::Version() const {\n\treturn Scintilla::lvRelease5;\n}\n\nconst char * SCI_METHOD DefaultLexer::PropertyNames() {\n\tif (osi)\n\t\treturn osi->PropertyNames();\n\treturn \"\";\n}\n\nint SCI_METHOD DefaultLexer::PropertyType(const char *name) {\n\tif (osi)\n\t\treturn osi->PropertyType(name);\n\treturn SC_TYPE_BOOLEAN;\n}\n\nconst char * SCI_METHOD DefaultLexer::DescribeProperty(const char *name) {\n\tif (osi)\n\t\treturn osi->DescribeProperty(name);\n\treturn \"\";\n}\n\nSci_Position SCI_METHOD DefaultLexer::PropertySet(const char *, const char *) {\n\treturn -1;\n}\n\nconst char * SCI_METHOD DefaultLexer::DescribeWordListSets() {\n\tif (osi)\n\t\treturn osi->DescribeWordListSets();\n\treturn \"\";\n}\n\nSci_Position SCI_METHOD DefaultLexer::WordListSet(int, const char *) {\n\treturn -1;\n}\n\nvoid SCI_METHOD DefaultLexer::Fold(Sci_PositionU, Sci_Position, int, Scintilla::IDocument *) {\n}\n\nvoid * SCI_METHOD DefaultLexer::PrivateCall(int, void *) {\n\treturn nullptr;\n}\n\nint SCI_METHOD DefaultLexer::LineEndTypesSupported() {\n\treturn SC_LINE_END_TYPE_DEFAULT;\n}\n\nint SCI_METHOD DefaultLexer::AllocateSubStyles(int, int) {\n\treturn -1;\n}\n\nint SCI_METHOD DefaultLexer::SubStylesStart(int) {\n\treturn -1;\n}\n\nint SCI_METHOD DefaultLexer::SubStylesLength(int) {\n\treturn 0;\n}\n\nint SCI_METHOD DefaultLexer::StyleFromSubStyle(int subStyle) {\n\treturn subStyle;\n}\n\nint SCI_METHOD DefaultLexer::PrimaryStyleFromStyle(int style) {\n\treturn style;\n}\n\nvoid SCI_METHOD DefaultLexer::FreeSubStyles() {\n}\n\nvoid SCI_METHOD DefaultLexer::SetIdentifiers(int, const char *) {\n}\n\nint SCI_METHOD DefaultLexer::DistanceToSecondaryStyles() {\n\treturn 0;\n}\n\nconst char * SCI_METHOD DefaultLexer::GetSubStyleBases() {\n\treturn styleSubable;\n}\n\nint SCI_METHOD DefaultLexer::NamedStyles() {\n\treturn static_cast<int>(nClasses);\n}\n\nconst char * SCI_METHOD DefaultLexer::NameOfStyle(int style) {\n\treturn (style < NamedStyles()) ? lexClasses[style].name : \"\";\n}\n\nconst char * SCI_METHOD DefaultLexer::TagsOfStyle(int style) {\n\treturn (style < NamedStyles()) ? lexClasses[style].tags : \"\";\n}\n\nconst char * SCI_METHOD DefaultLexer::DescriptionOfStyle(int style) {\n\treturn (style < NamedStyles()) ? lexClasses[style].description : \"\";\n}\n\n// ILexer5 methods\nconst char * SCI_METHOD DefaultLexer::GetName() {\n\treturn languageName;\n}\n\nint SCI_METHOD DefaultLexer::GetIdentifier() {\n\treturn language;\n}\n\nconst char *SCI_METHOD DefaultLexer::PropertyGet(const char *key) {\n\tif (osi)\n\t\treturn osi->PropertyGet(key);\n\treturn nullptr;\n}\n"
  },
  {
    "path": "lexlib/DefaultLexer.h",
    "content": "// Scintilla source code edit control\n/** @file DefaultLexer.h\n ** A lexer base class with default empty implementations of methods.\n ** For lexers that do not support all features so do not need real implementations.\n ** Does have real implementation for style metadata.\n **/\n// Copyright 2017 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef DEFAULTLEXER_H\n#define DEFAULTLEXER_H\n\nnamespace Lexilla {\n\nstruct OptionSetInterface;\t// Forward declaration\n\n// A simple lexer with no state\nclass DefaultLexer : public Scintilla::ILexer5 {\n\tconst char *languageName;\n\tint language;\n\tconst LexicalClass *lexClasses;\n\tsize_t nClasses;\n\tOptionSetInterface *osi = nullptr;\npublic:\n\tDefaultLexer(const char *languageName_, int language_,\n\t\tconst LexicalClass *lexClasses_ = nullptr, size_t nClasses_ = 0);\n\tvirtual ~DefaultLexer();\n\tvoid SetOptionSet(OptionSetInterface *osi_) noexcept {\n\t\tthis->osi = osi_;\n\t}\n\n\tvoid SCI_METHOD Release() override;\n\tint SCI_METHOD Version() const override;\n\tconst char * SCI_METHOD PropertyNames() override;\n\tint SCI_METHOD PropertyType(const char *name) override;\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override;\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD DescribeWordListSets() override;\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override = 0;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override;\n\tvoid * SCI_METHOD PrivateCall(int operation, void *pointer) override;\n\tint SCI_METHOD LineEndTypesSupported() override;\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override;\n\tint SCI_METHOD SubStylesStart(int styleBase) override;\n\tint SCI_METHOD SubStylesLength(int styleBase) override;\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override;\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) override;\n\tvoid SCI_METHOD FreeSubStyles() override;\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override;\n\tint SCI_METHOD DistanceToSecondaryStyles() override;\n\tconst char * SCI_METHOD GetSubStyleBases() override;\n\tint SCI_METHOD NamedStyles() override;\n\tconst char * SCI_METHOD NameOfStyle(int style) override;\n\tconst char * SCI_METHOD TagsOfStyle(int style) override;\n\tconst char * SCI_METHOD DescriptionOfStyle(int style) override;\n\t// ILexer5 methods\n\tconst char * SCI_METHOD GetName() override;\n\tint SCI_METHOD GetIdentifier() override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override;\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/InList.cxx",
    "content": "// Scintilla source code edit control\n/** @file InList.cxx\n ** Check if a string is in a list.\n **/\n// Copyright 2024 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cassert>\n\n#include <string>\n#include <string_view>\n#include <initializer_list>\n\n#include \"InList.h\"\n#include \"CharacterSet.h\"\n\nnamespace Lexilla {\n\nbool InList(std::string_view value, std::initializer_list<std::string_view> list) noexcept {\n\tfor (const std::string_view element : list) {\n\t\tif (value == element) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nbool InListCaseInsensitive(std::string_view value, std::initializer_list<std::string_view> list) noexcept {\n\tfor (const std::string_view element : list) {\n\t\tif (EqualCaseInsensitive(value, element)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n}\n"
  },
  {
    "path": "lexlib/InList.h",
    "content": "// Scintilla source code edit control\n/** @file InList.h\n ** Check if a string is in a list.\n **/\n// Copyright 2024 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef INLIST_H\n#define INLIST_H\n\nnamespace Lexilla {\n\nbool InList(std::string_view value, std::initializer_list<std::string_view> list) noexcept;\nbool InListCaseInsensitive(std::string_view value, std::initializer_list<std::string_view> list) noexcept;\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/LexAccessor.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexAccessor.cxx\n ** Interfaces between Scintilla and lexers.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <algorithm>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n\n#include \"LexAccessor.h\"\n#include \"CharacterSet.h\"\n\nusing namespace Lexilla;\n\nnamespace Lexilla {\n\nbool LexAccessor::MatchIgnoreCase(Sci_Position pos, const char *s) {\n\tassert(s);\n\tfor (; *s; s++, pos++) {\n\t\tif (*s != MakeLowerCase(SafeGetCharAt(pos))) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nvoid LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) const {\n\tassert(s);\n\tassert(startPos_ <= endPos_ && len != 0);\n\tmemset(s, '\\0', len);\n\tendPos_ = std::min(endPos_, startPos_ + len - 1);\n\tendPos_ = std::min(endPos_, static_cast<Sci_PositionU>(lenDoc));\n\tlen = endPos_ - startPos_;\n\tif (startPos_ >= static_cast<Sci_PositionU>(startPos) && endPos_ <= static_cast<Sci_PositionU>(endPos)) {\n\t\tconst char * const p = buf + (startPos_ - startPos);\n\t\tmemcpy(s, p, len);\n\t} else {\n\t\tpAccess->GetCharRange(s, startPos_, len);\n\t}\n}\n\nvoid LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) const {\n\tassert(s);\n\tGetRange(startPos_, endPos_, s, len);\n\twhile (*s) {\n\t\tif (*s >= 'A' && *s <= 'Z') {\n\t\t\t*s += 'a' - 'A';\n\t\t}\n\t\t++s;\n\t}\n}\n\nstd::string LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_) const {\n\tassert(startPos_ <= endPos_);\n\tendPos_ = std::min(endPos_, static_cast<Sci_PositionU>(lenDoc));\n\tconst Sci_PositionU len = endPos_ - startPos_;\n\tstd::string s(len, '\\0');\n\tGetRange(startPos_, endPos_, s.data(), len + 1);\n\treturn s;\n}\n\nstd::string LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_) const {\n\tassert(startPos_ <= endPos_);\n\tendPos_ = std::min(endPos_, static_cast<Sci_PositionU>(lenDoc));\n\tconst Sci_PositionU len = endPos_ - startPos_;\n\tstd::string s(len, '\\0');\n\tGetRangeLowered(startPos_, endPos_, s.data(), len + 1);\n\treturn s;\n}\n\nvoid LexAccessor::SetLevelIfDifferent(Sci_Position line, int level) {\n\tif (level != pAccess->GetLevel(line)) {\n\t\tpAccess->SetLevel(line, level);\n\t}\n}\n\nint FoldLevelFlags(int levelLine, int levelNext, bool white, bool headerPermitted) noexcept {\n\tint flags = 0;\n\tif (white) {\n\t\tflags |= SC_FOLDLEVELWHITEFLAG;\n\t}\n\tif ((levelLine < levelNext) && (headerPermitted)) {\n\t\tflags |= SC_FOLDLEVELHEADERFLAG;\n\t}\n\treturn flags;\n}\n\n}\n"
  },
  {
    "path": "lexlib/LexAccessor.h",
    "content": "// Scintilla source code edit control\n/** @file LexAccessor.h\n ** Interfaces between Scintilla and lexers.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef LEXACCESSOR_H\n#define LEXACCESSOR_H\n\nnamespace Lexilla {\n\nenum class EncodingType { eightBit, unicode, dbcs };\n\nclass LexAccessor {\nprivate:\n\tScintilla::IDocument *pAccess;\n\tenum {extremePosition=0x7FFFFFFF};\n\t/** @a bufferSize is a trade off between time taken to copy the characters\n\t * and retrieval overhead.\n\t * @a slopSize positions the buffer before the desired position\n\t * in case there is some backtracking. */\n\tenum {bufferSize=4000, slopSize=bufferSize/8};\n\tchar buf[bufferSize+1];\n\tSci_Position startPos;\n\tSci_Position endPos;\n\tint codePage;\n\tenum EncodingType encodingType;\n\tSci_Position lenDoc;\n\tchar styleBuf[bufferSize];\n\tSci_Position validLen;\n\tSci_PositionU startSeg;\n\tSci_Position startPosStyling;\n\tint documentVersion;\n\n\tvoid Fill(Sci_Position position) {\n\t\tstartPos = position - slopSize;\n\t\tif (startPos + bufferSize > lenDoc)\n\t\t\tstartPos = lenDoc - bufferSize;\n\t\tif (startPos < 0)\n\t\t\tstartPos = 0;\n\t\tendPos = startPos + bufferSize;\n\t\tif (endPos > lenDoc)\n\t\t\tendPos = lenDoc;\n\n\t\tpAccess->GetCharRange(buf, startPos, endPos-startPos);\n\t\tbuf[endPos-startPos] = '\\0';\n\t}\n\npublic:\n\texplicit LexAccessor(Scintilla::IDocument *pAccess_) :\n\t\tpAccess(pAccess_), startPos(extremePosition), endPos(0),\n\t\tcodePage(pAccess->CodePage()),\n\t\tencodingType(EncodingType::eightBit),\n\t\tlenDoc(pAccess->Length()),\n\t\tvalidLen(0),\n\t\tstartSeg(0), startPosStyling(0),\n\t\tdocumentVersion(pAccess->Version()) {\n\t\t// Prevent warnings by static analyzers about uninitialized buf and styleBuf.\n\t\tbuf[0] = 0;\n\t\tstyleBuf[0] = 0;\n\t\tswitch (codePage) {\n\t\tcase 65001:\n\t\t\tencodingType = EncodingType::unicode;\n\t\t\tbreak;\n\t\tcase 932:\n\t\tcase 936:\n\t\tcase 949:\n\t\tcase 950:\n\t\tcase 1361:\n\t\t\tencodingType = EncodingType::dbcs;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\tchar operator[](Sci_Position position) {\n\t\tif (position < startPos || position >= endPos) {\n\t\t\tFill(position);\n\t\t}\n\t\treturn buf[position - startPos];\n\t}\n\tScintilla::IDocument *MultiByteAccess() const noexcept {\n\t\treturn pAccess;\n\t}\n\t/** Safe version of operator[], returning a defined value for invalid position. */\n\tchar SafeGetCharAt(Sci_Position position, char chDefault=' ') {\n\t\tif (position < startPos || position >= endPos) {\n\t\t\tFill(position);\n\t\t\tif (position < startPos || position >= endPos) {\n\t\t\t\t// Position is outside range of document\n\t\t\t\treturn chDefault;\n\t\t\t}\n\t\t}\n\t\treturn buf[position - startPos];\n\t}\n\tbool IsLeadByte(char ch) const {\n\t\tconst unsigned char uch = ch;\n\t\treturn\n\t\t\t(uch >= 0x80) &&\t// non-ASCII\n\t\t\t(encodingType == EncodingType::dbcs) &&\t\t// IsDBCSLeadByte only for DBCS\n\t\t\tpAccess->IsDBCSLeadByte(ch);\n\t}\n\tEncodingType Encoding() const noexcept {\n\t\treturn encodingType;\n\t}\n\tbool Match(Sci_Position pos, const char *s) {\n\t\tassert(s);\n\t\tfor (int i=0; *s; i++) {\n\t\t\tif (*s != SafeGetCharAt(pos+i))\n\t\t\t\treturn false;\n\t\t\ts++;\n\t\t}\n\t\treturn true;\n\t}\n\tbool MatchIgnoreCase(Sci_Position pos, const char *s);\n\n\t// Get first len - 1 characters in range [startPos_, endPos_).\n\tvoid GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) const;\n\tvoid GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) const;\n\t// Get all characters in range [startPos_, endPos_).\n\tstd::string GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_) const;\n\tstd::string GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_) const;\n\n\tchar StyleAt(Sci_Position position) const {\n\t\treturn pAccess->StyleAt(position);\n\t}\n\tint StyleIndexAt(Sci_Position position) const {\n\t\tconst unsigned char style = pAccess->StyleAt(position);\n\t\treturn style;\n\t}\n\t// Return style value from buffer when in buffer, else retrieve from document.\n\t// This is faster and can avoid calls to Flush() as that may be expensive.\n\tint BufferStyleAt(Sci_Position position) const {\n\t\tconst Sci_Position index = position - startPosStyling;\n\t\tif (index >= 0 && index < validLen) {\n\t\t\tconst unsigned char style = styleBuf[index];\n\t\t\treturn style;\n\t\t}\n\t\tconst unsigned char style = pAccess->StyleAt(position);\n\t\treturn style;\n\t}\n\tSci_Position GetLine(Sci_Position position) const {\n\t\treturn pAccess->LineFromPosition(position);\n\t}\n\tSci_Position LineStart(Sci_Position line) const {\n\t\treturn pAccess->LineStart(line);\n\t}\n\tSci_Position LineEnd(Sci_Position line) const {\n\t\treturn pAccess->LineEnd(line);\n\t}\n\tint LevelAt(Sci_Position line) const {\n\t\treturn pAccess->GetLevel(line);\n\t}\n\tSci_Position Length() const noexcept {\n\t\treturn lenDoc;\n\t}\n\tvoid Flush() {\n\t\tif (validLen > 0) {\n\t\t\tpAccess->SetStyles(validLen, styleBuf);\n\t\t\tstartPosStyling += validLen;\n\t\t\tvalidLen = 0;\n\t\t}\n\t}\n\tint GetLineState(Sci_Position line) const {\n\t\treturn pAccess->GetLineState(line);\n\t}\n\tint SetLineState(Sci_Position line, int state) {\n\t\treturn pAccess->SetLineState(line, state);\n\t}\n\t// Style setting\n\tvoid StartAt(Sci_PositionU start) {\n\t\tpAccess->StartStyling(start);\n\t\tstartPosStyling = start;\n\t}\n\tSci_PositionU GetStartSegment() const noexcept {\n\t\treturn startSeg;\n\t}\n\tvoid StartSegment(Sci_PositionU pos) noexcept {\n\t\tstartSeg = pos;\n\t}\n\tvoid ColourTo(Sci_PositionU pos, int chAttr) {\n\t\t// Only perform styling for non empty range [startSeg, pos + 1)\n\t\tpos += 1; // pos could be -1\n\t\tassert(pos >= startSeg && pos <= static_cast<Sci_PositionU>(Length()));\n\t\tif (pos > startSeg) {\n\t\t\tconst Sci_PositionU len = pos - startSeg;\n\t\t\tif (validLen + len >= bufferSize) {\n\t\t\t\tFlush();\n\t\t\t}\n\t\t\tassert((startPosStyling + validLen + len) <= static_cast<Sci_PositionU>(Length()));\n\t\t\tconst unsigned char attr = chAttr & 0xffU;\n\t\t\tstartSeg += len;\n\t\t\tif (validLen + len < bufferSize) {\n\t\t\t\tfor (Sci_PositionU i = 0; i < len; i++) {\n\t\t\t\t\tstyleBuf[validLen++] = attr;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Too big for buffer so send directly\n\t\t\t\tpAccess->SetStyleFor(len, attr);\n\t\t\t}\n\t\t}\n\t}\n\tvoid SetLevel(Sci_Position line, int level) {\n\t\tpAccess->SetLevel(line, level);\n\t}\n\t// Avoids some overhead when level same as before\n\tvoid SetLevelIfDifferent(Sci_Position line, int level);\n\tvoid IndicatorFill(Sci_Position start, Sci_Position end, int indicator, int value) {\n\t\tpAccess->DecorationSetCurrentIndicator(indicator);\n\t\tpAccess->DecorationFillRange(start, value, end - start);\n\t}\n\n\tvoid ChangeLexerState(Sci_Position start, Sci_Position end) {\n\t\tpAccess->ChangeLexerState(start, end);\n\t}\n};\n\nstruct LexicalClass {\n\tint value;\n\tconst char *name;\n\tconst char *tags;\n\tconst char *description;\n};\n\n// Fold level setting\n\nconstexpr int FoldLevelShift = 16;\nconstexpr int FoldLevelStart(int levelPrevious) noexcept {\n\treturn levelPrevious >> FoldLevelShift;\n}\nconstexpr int FoldLevelForCurrentNext(int levelCurrent, int levelNext) noexcept {\n\treturn levelCurrent | levelNext << FoldLevelShift;\n}\n// Where lexer uses current/next but only has one value, commonly at end of range\nconstexpr int FoldLevelForCurrent(int levelCurrent) noexcept {\n\treturn FoldLevelForCurrentNext(levelCurrent, levelCurrent);\n}\nint FoldLevelFlags(int levelLine, int levelNext, bool white, bool headerPermitted=true) noexcept;\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/LexerBase.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexerBase.cxx\n ** A simple lexer with no state.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"LexerModule.h\"\n#include \"LexerBase.h\"\n\nusing namespace Lexilla;\n\nstatic const char styleSubable[] = { 0 };\n\nLexerBase::LexerBase(const LexicalClass *lexClasses_, size_t nClasses_) :\n\tlexClasses(lexClasses_), nClasses(nClasses_) {\n\tfor (int wl = 0; wl < numWordLists; wl++)\n\t\tkeyWordLists[wl] = new WordList;\n\tkeyWordLists[numWordLists] = nullptr;\n}\n\nLexerBase::~LexerBase() {\n\tfor (int wl = 0; wl < numWordLists; wl++) {\n\t\tdelete keyWordLists[wl];\n\t\tkeyWordLists[wl] = nullptr;\n\t}\n\tkeyWordLists[numWordLists] = nullptr;\n}\n\nvoid SCI_METHOD LexerBase::Release() {\n\tdelete this;\n}\n\nint SCI_METHOD LexerBase::Version() const {\n\treturn Scintilla::lvRelease5;\n}\n\nconst char * SCI_METHOD LexerBase::PropertyNames() {\n\treturn \"\";\n}\n\nint SCI_METHOD LexerBase::PropertyType(const char *) {\n\treturn SC_TYPE_BOOLEAN;\n}\n\nconst char * SCI_METHOD LexerBase::DescribeProperty(const char *) {\n\treturn \"\";\n}\n\nSci_Position SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) {\n\tif (props.Set(key, val)) {\n\t\treturn 0;\n\t}\n\treturn -1;\n}\n\nconst char *SCI_METHOD LexerBase::PropertyGet(const char *key) {\n\treturn props.Get(key);\n}\n\nconst char * SCI_METHOD LexerBase::DescribeWordListSets() {\n\treturn \"\";\n}\n\nSci_Position SCI_METHOD LexerBase::WordListSet(int n, const char *wl) {\n\tif (n < numWordLists) {\n\t\tif (keyWordLists[n]->Set(wl)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\treturn -1;\n}\n\nvoid * SCI_METHOD LexerBase::PrivateCall(int, void *) {\n\treturn nullptr;\n}\n\nint SCI_METHOD LexerBase::LineEndTypesSupported() {\n\treturn SC_LINE_END_TYPE_DEFAULT;\n}\n\nint SCI_METHOD LexerBase::AllocateSubStyles(int, int) {\n\treturn -1;\n}\n\nint SCI_METHOD LexerBase::SubStylesStart(int) {\n\treturn -1;\n}\n\nint SCI_METHOD LexerBase::SubStylesLength(int) {\n\treturn 0;\n}\n\nint SCI_METHOD LexerBase::StyleFromSubStyle(int subStyle) {\n\treturn subStyle;\n}\n\nint SCI_METHOD LexerBase::PrimaryStyleFromStyle(int style) {\n\treturn style;\n}\n\nvoid SCI_METHOD LexerBase::FreeSubStyles() {\n}\n\nvoid SCI_METHOD LexerBase::SetIdentifiers(int, const char *) {\n}\n\nint SCI_METHOD LexerBase::DistanceToSecondaryStyles() {\n\treturn 0;\n}\n\nconst char * SCI_METHOD LexerBase::GetSubStyleBases() {\n\treturn styleSubable;\n}\n\nint SCI_METHOD LexerBase::NamedStyles() {\n\treturn static_cast<int>(nClasses);\n}\n\nconst char * SCI_METHOD LexerBase::NameOfStyle(int style) {\n\treturn (style < NamedStyles()) ? lexClasses[style].name : \"\";\n}\n\nconst char * SCI_METHOD LexerBase::TagsOfStyle(int style) {\n\treturn (style < NamedStyles()) ? lexClasses[style].tags : \"\";\n}\n\nconst char * SCI_METHOD LexerBase::DescriptionOfStyle(int style) {\n\treturn (style < NamedStyles()) ? lexClasses[style].description : \"\";\n}\n\n// ILexer5 methods\n\nconst char *SCI_METHOD LexerBase::GetName() {\n\treturn \"\";\n}\n\nint SCI_METHOD LexerBase::GetIdentifier() {\n\treturn SCLEX_AUTOMATIC;\n}\n"
  },
  {
    "path": "lexlib/LexerBase.h",
    "content": "// Scintilla source code edit control\n/** @file LexerBase.h\n ** A simple lexer with no state.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef LEXERBASE_H\n#define LEXERBASE_H\n\nnamespace Lexilla {\n\n// A simple lexer with no state\nclass LexerBase : public Scintilla::ILexer5 {\nprotected:\n\tconst LexicalClass *lexClasses;\n\tsize_t nClasses;\n\tPropSetSimple props;\n\tenum {numWordLists=KEYWORDSET_MAX+1};\n\tWordList *keyWordLists[numWordLists+1]{};\npublic:\n\tLexerBase(const LexicalClass *lexClasses_=nullptr, size_t nClasses_=0);\n\tvirtual ~LexerBase();\n\tvoid SCI_METHOD Release() override;\n\tint SCI_METHOD Version() const override;\n\tconst char * SCI_METHOD PropertyNames() override;\n\tint SCI_METHOD PropertyType(const char *name) override;\n\tconst char * SCI_METHOD DescribeProperty(const char *name) override;\n\tSci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;\n\tconst char * SCI_METHOD DescribeWordListSets() override;\n\tSci_Position SCI_METHOD WordListSet(int n, const char *wl) override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override = 0;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override = 0;\n\tvoid * SCI_METHOD PrivateCall(int operation, void *pointer) override;\n\tint SCI_METHOD LineEndTypesSupported() override;\n\tint SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override;\n\tint SCI_METHOD SubStylesStart(int styleBase) override;\n\tint SCI_METHOD SubStylesLength(int styleBase) override;\n\tint SCI_METHOD StyleFromSubStyle(int subStyle) override;\n\tint SCI_METHOD PrimaryStyleFromStyle(int style) override;\n\tvoid SCI_METHOD FreeSubStyles() override;\n\tvoid SCI_METHOD SetIdentifiers(int style, const char *identifiers) override;\n\tint SCI_METHOD DistanceToSecondaryStyles() override;\n\tconst char * SCI_METHOD GetSubStyleBases() override;\n\tint SCI_METHOD NamedStyles() override;\n\tconst char * SCI_METHOD NameOfStyle(int style) override;\n\tconst char * SCI_METHOD TagsOfStyle(int style) override;\n\tconst char * SCI_METHOD DescriptionOfStyle(int style) override;\n\t// ILexer5 methods\n\tconst char * SCI_METHOD GetName() override;\n\tint SCI_METHOD GetIdentifier() override;\n\tconst char *SCI_METHOD PropertyGet(const char *key) override;\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/LexerModule.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexerModule.cxx\n ** Colourise for particular languages.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"LexerModule.h\"\n#include \"LexerBase.h\"\n#include \"LexerSimple.h\"\n\nusing namespace Lexilla;\n\nLexerModule::LexerModule(int language_,\n\tLexerFunction fnLexer_,\n\tconst char *languageName_,\n\tLexerFunction fnFolder_,\n\tconst char *const wordListDescriptions_[],\n\tconst LexicalClass *lexClasses_,\n\tsize_t nClasses_) noexcept :\n\tlanguage(language_),\n\tfnLexer(fnLexer_),\n\tfnFolder(fnFolder_),\n\tfnFactory(nullptr),\n\twordListDescriptions(wordListDescriptions_),\n\tlexClasses(lexClasses_),\n\tnClasses(nClasses_),\n\tlanguageName(languageName_) {\n}\n\nLexerModule::LexerModule(int language_,\n\tLexerFactoryFunction fnFactory_,\n\tconst char *languageName_,\n\tconst char * const wordListDescriptions_[]) noexcept :\n\tlanguage(language_),\n\tfnLexer(nullptr),\n\tfnFolder(nullptr),\n\tfnFactory(fnFactory_),\n\twordListDescriptions(wordListDescriptions_),\n\tlexClasses(nullptr),\n\tnClasses(0),\n\tlanguageName(languageName_) {\n}\n\nint LexerModule::GetLanguage() const noexcept {\n\treturn language;\n}\n\nint LexerModule::GetNumWordLists() const noexcept {\n\tif (!wordListDescriptions) {\n\t\treturn -1;\n\t}\n\tint numWordLists = 0;\n\n\twhile (wordListDescriptions[numWordLists]) {\n\t\t++numWordLists;\n\t}\n\n\treturn numWordLists;\n}\n\nconst char *LexerModule::GetWordListDescription(int index) const noexcept {\n\tassert(index < GetNumWordLists());\n\tif (!wordListDescriptions || (index >= GetNumWordLists())) {\n\t\treturn \"\";\n\t}\n\treturn wordListDescriptions[index];\n}\n\nconst LexicalClass *LexerModule::LexClasses() const noexcept {\n\treturn lexClasses;\n}\n\nsize_t LexerModule::NamedStyles() const noexcept {\n\treturn nClasses;\n}\n\nScintilla::ILexer5 *LexerModule::Create() const {\n\tif (fnFactory)\n\t\treturn fnFactory();\n\treturn new LexerSimple(this);\n}\n\nvoid LexerModule::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle,\n\t  WordList *keywordlists[], Accessor &styler) const {\n\tif (fnLexer)\n\t\tfnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);\n}\n\nvoid LexerModule::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle,\n\t  WordList *keywordlists[], Accessor &styler) const {\n\tif (fnFolder) {\n\t\tSci_Position lineCurrent = styler.GetLine(startPos);\n\t\t// Move back one line in case deletion wrecked current line fold state\n\t\tif (lineCurrent > 0) {\n\t\t\tlineCurrent--;\n\t\t\tconst Sci_Position newStartPos = styler.LineStart(lineCurrent);\n\t\t\tlengthDoc += startPos - newStartPos;\n\t\t\tstartPos = newStartPos;\n\t\t\tinitStyle = 0;\n\t\t\tif (startPos > 0) {\n\t\t\t\tinitStyle = styler.StyleIndexAt(startPos - 1);\n\t\t\t}\n\t\t}\n\t\tfnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);\n\t}\n}\n"
  },
  {
    "path": "lexlib/LexerModule.h",
    "content": "// Scintilla source code edit control\n/** @file LexerModule.h\n ** Colourise for particular languages.\n **/\n// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef LEXERMODULE_H\n#define LEXERMODULE_H\n\nnamespace Lexilla {\n\nclass Accessor;\nclass WordList;\nstruct LexicalClass;\n\ntypedef void (*LexerFunction)(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle,\n                  WordList *keywordlists[], Accessor &styler);\ntypedef Scintilla::ILexer5 *(*LexerFactoryFunction)();\n\n/**\n * A LexerModule is responsible for lexing and folding a particular language.\n * The Catalogue class maintains a list of LexerModules which can be searched to find a\n * module appropriate to a particular language.\n * The ExternalLexerModule subclass holds lexers loaded from DLLs or shared libraries.\n */\nclass LexerModule {\nprotected:\n\tint language;\n\tLexerFunction fnLexer;\n\tLexerFunction fnFolder;\n\tLexerFactoryFunction fnFactory;\n\tconst char * const * wordListDescriptions;\n\tconst LexicalClass *lexClasses;\n\tsize_t nClasses;\n\npublic:\n\tconst char *languageName;\n\tLexerModule(\n\t\tint language_,\n\t\tLexerFunction fnLexer_,\n\t\tconst char *languageName_=nullptr,\n\t\tLexerFunction fnFolder_= nullptr,\n\t\tconst char * const wordListDescriptions_[]=nullptr,\n\t\tconst LexicalClass *lexClasses_=nullptr,\n\t\tsize_t nClasses_=0) noexcept;\n\tLexerModule(\n\t\tint language_,\n\t\tLexerFactoryFunction fnFactory_,\n\t\tconst char *languageName_,\n\t\tconst char * const wordListDescriptions_[]=nullptr) noexcept;\n\tint GetLanguage() const noexcept;\n\n\t// -1 is returned if no WordList information is available\n\tint GetNumWordLists() const noexcept;\n\tconst char *GetWordListDescription(int index) const noexcept;\n\tconst LexicalClass *LexClasses() const noexcept;\n\tsize_t NamedStyles() const noexcept;\n\n\tScintilla::ILexer5 *Create() const;\n\n\tvoid Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle,\n                  WordList *keywordlists[], Accessor &styler) const;\n\tvoid Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle,\n                  WordList *keywordlists[], Accessor &styler) const;\n\n\tfriend class CatalogueModules;\n};\n\nconstexpr int Maximum(int a, int b) noexcept {\n\treturn (a > b) ? a : b;\n}\n\n// Shut up annoying Visual C++ warnings:\n#if defined(_MSC_VER)\n#pragma warning(disable: 4244 4456 4457)\n#endif\n\n// Turn off shadow warnings for lexers as may be maintained by others\n#if defined(__GNUC__)\n#pragma GCC diagnostic ignored \"-Wshadow\"\n#endif\n\n// Clang doesn't like omitting braces in array initialization but they just add\n// noise to LexicalClass arrays in lexers\n#if defined(__clang__)\n#pragma clang diagnostic ignored \"-Wmissing-braces\"\n#endif\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/LexerSimple.cxx",
    "content": "// Scintilla source code edit control\n/** @file LexerSimple.cxx\n ** A simple lexer with no state.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"SciLexer.h\"\n\n#include \"PropSetSimple.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"LexerModule.h\"\n#include \"LexerBase.h\"\n#include \"LexerSimple.h\"\n\nusing namespace Lexilla;\n\nLexerSimple::LexerSimple(const LexerModule *module_) :\n\tLexerBase(module_->LexClasses(), module_->NamedStyles()),\n\tlexerModule(module_) {\n\tfor (int wl = 0; wl < lexerModule->GetNumWordLists(); wl++) {\n\t\tif (!wordLists.empty())\n\t\t\twordLists += \"\\n\";\n\t\twordLists += lexerModule->GetWordListDescription(wl);\n\t}\n}\n\nconst char * SCI_METHOD LexerSimple::DescribeWordListSets() {\n\treturn wordLists.c_str();\n}\n\nvoid SCI_METHOD LexerSimple::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) {\n\tAccessor astyler(pAccess, &props);\n\tlexerModule->Lex(startPos, lengthDoc, initStyle, keyWordLists, astyler);\n\tastyler.Flush();\n}\n\nvoid SCI_METHOD LexerSimple::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) {\n\tif (props.GetInt(\"fold\")) {\n\t\tAccessor astyler(pAccess, &props);\n\t\tlexerModule->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler);\n\t\tastyler.Flush();\n\t}\n}\n\nconst char * SCI_METHOD LexerSimple::GetName() {\n\treturn lexerModule->languageName;\n}\n\nint SCI_METHOD LexerSimple::GetIdentifier() {\n\treturn lexerModule->GetLanguage();\n}\n"
  },
  {
    "path": "lexlib/LexerSimple.h",
    "content": "// Scintilla source code edit control\n/** @file LexerSimple.h\n ** A simple lexer with no state.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef LEXERSIMPLE_H\n#define LEXERSIMPLE_H\n\nnamespace Lexilla {\n\n// A simple lexer with no state\nclass LexerSimple : public LexerBase {\n\tconst LexerModule *lexerModule;\n\tstd::string wordLists;\npublic:\n\texplicit LexerSimple(const LexerModule *lexerModule_);\n\tconst char * SCI_METHOD DescribeWordListSets() override;\n\tvoid SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override;\n\tvoid SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override;\n\t// ILexer5 methods\n\tconst char * SCI_METHOD GetName() override;\n\tint SCI_METHOD  GetIdentifier() override;\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/OptionSet.h",
    "content": "// Scintilla source code edit control\n/** @file OptionSet.h\n ** Manage descriptive information about an options struct for a lexer.\n ** Hold the names, positions, and descriptions of boolean, integer and string options and\n ** allow setting options and retrieving metadata about the options.\n **/\n// Copyright 2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef OPTIONSET_H\n#define OPTIONSET_H\n\nnamespace Lexilla {\n\ninline std::string JoinWordListDescriptions(const char *const wordListDescriptions[]) {\n\tstd::string wordLists;\n\tif (wordListDescriptions) {\n\t\tfor (size_t wl = 0; wordListDescriptions[wl]; wl++) {\n\t\t\tif (wl > 0)\n\t\t\t\twordLists += \"\\n\";\n\t\t\twordLists += wordListDescriptions[wl];\n\t\t}\n\t}\n\treturn wordLists;\n}\n\n// Allow OptionSet<T> to be called without knowing T\nstruct OptionSetInterface {\n\t[[nodiscard]] virtual const char *PropertyNames() const noexcept = 0;\n\t[[nodiscard]] virtual int PropertyType(const char *name) const = 0;\n\t[[nodiscard]] virtual const char *DescribeProperty(const char *name) const = 0;\n\t[[nodiscard]] virtual const char *PropertyGet(const char *name) const = 0;\n\t[[nodiscard]] virtual const char *DescribeWordListSets() const noexcept = 0;\n};\n\ntemplate <typename T>\nclass OptionSet : public OptionSetInterface {\n\tusing Target = T;\n\tusing plcob = bool T::*;\n\tusing plcoi = int T::*;\n\tusing plcos = std::string T::*;\n\tstruct Option {\n\t\tint opType;\n\t\tunion {\n\t\t\tplcob pb;\n\t\t\tplcoi pi;\n\t\t\tplcos ps;\n\t\t};\n\t\tstd::string value;\n\t\tstd::string description;\n\t\tOption() :\n\t\t\topType(SC_TYPE_BOOLEAN), pb(nullptr) {\n\t\t}\n\t\tOption(plcob pb_, std::string_view description_=\"\") :\n\t\t\topType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) {\n\t\t}\n\t\tOption(plcoi pi_, std::string_view description_) :\n\t\t\topType(SC_TYPE_INTEGER), pi(pi_), description(description_) {\n\t\t}\n\t\tOption(plcos ps_, std::string_view description_) :\n\t\t\topType(SC_TYPE_STRING), ps(ps_), description(description_) {\n\t\t}\n\t\tbool Set(T *base, const char *val) {\n\t\t\tvalue = val;\n\t\t\tswitch (opType) {\n\t\t\tcase SC_TYPE_BOOLEAN: {\n\t\t\t\t\tconst bool option = atoi(val) != 0;\n\t\t\t\t\tif ((*base).*pb != option) {\n\t\t\t\t\t\t(*base).*pb = option;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\tcase SC_TYPE_INTEGER: {\n\t\t\t\t\tconst int option = atoi(val);\n\t\t\t\t\tif ((*base).*pi != option) {\n\t\t\t\t\t\t(*base).*pi = option;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\tcase SC_TYPE_STRING: {\n\t\t\t\t\tif ((*base).*ps != val) {\n\t\t\t\t\t\t(*base).*ps = val;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t[[nodiscard]] const char *Get() const noexcept {\n\t\t\treturn value.c_str();\n\t\t}\n\t};\n\tusing OptionMap = std::map<std::string, Option, std::less<>> ;\n\tOptionMap nameToDef;\n\tstd::string names;\n\tstd::string wordLists;\n\n\tvoid AppendName(const char *name) {\n\t\tif (!names.empty())\n\t\t\tnames += \"\\n\";\n\t\tnames += name;\n\t}\npublic:\n\tvirtual ~OptionSet() = default;\n\n\tvoid DefineProperty(const char *name, plcob pb, std::string_view description=\"\") {\n\t\tnameToDef[name] = Option(pb, description);\n\t\tAppendName(name);\n\t}\n\tvoid DefineProperty(const char *name, plcoi pi, std::string_view description=\"\") {\n\t\tnameToDef[name] = Option(pi, description);\n\t\tAppendName(name);\n\t}\n\tvoid DefineProperty(const char *name, plcos ps, std::string_view description=\"\") {\n\t\tnameToDef[name] = Option(ps, description);\n\t\tAppendName(name);\n\t}\n\ttemplate <typename E>\n\tvoid DefineProperty(const char *name, E T::*pe, std::string_view description=\"\") {\n\t\tstatic_assert(std::is_enum<E>::value);\n\t\tplcoi pi {};\n\t\tstatic_assert(sizeof(pe) == sizeof(pi));\n\t\tmemcpy(&pi, &pe, sizeof(pe));\n\t\tnameToDef[name] = Option(pi, description);\n\t\tAppendName(name);\n\t}\n\t[[nodiscard]] const char *PropertyNames() const noexcept final {\n\t\treturn names.c_str();\n\t}\n\t[[nodiscard]] int PropertyType(const char *name) const final {\n\t\ttypename OptionMap::const_iterator const it = nameToDef.find(name);\n\t\tif (it != nameToDef.end()) {\n\t\t\treturn it->second.opType;\n\t\t}\n\t\treturn SC_TYPE_BOOLEAN;\n\t}\n\t[[nodiscard]] const char *DescribeProperty(const char *name) const final {\n\t\ttypename OptionMap::const_iterator const it = nameToDef.find(name);\n\t\tif (it != nameToDef.end()) {\n\t\t\treturn it->second.description.c_str();\n\t\t}\n\t\treturn \"\";\n\t}\n\n\tbool PropertySet(T *base, const char *name, const char *val) {\n\t\ttypename OptionMap::iterator const it = nameToDef.find(name);\n\t\tif (it != nameToDef.end()) {\n\t\t\treturn it->second.Set(base, val);\n\t\t}\n\t\treturn false;\n\t}\n\n\t[[nodiscard]] const char *PropertyGet(const char *name) const final {\n\t\ttypename OptionMap::const_iterator const it = nameToDef.find(name);\n\t\tif (it != nameToDef.end()) {\n\t\t\treturn it->second.Get();\n\t\t}\n\t\treturn nullptr;\n\t}\n\n\tvoid DefineWordListSets(const char * const wordListDescriptions[]) {\n\t\twordLists = JoinWordListDescriptions(wordListDescriptions);\n\t}\n\n\t[[nodiscard]] const char *DescribeWordListSets() const noexcept final {\n\t\treturn wordLists.c_str();\n\t}\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/PropSetSimple.cxx",
    "content": "// Scintilla source code edit control\n/** @file PropSetSimple.cxx\n ** A basic string to string map.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n// Maintain a dictionary of properties\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <string_view>\n#include <map>\n#include <functional>\n\n#include \"PropSetSimple.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\nusing mapss = std::map<std::string, std::string, std::less<>>;\n\nmapss *PropsFromPointer(void *impl) noexcept {\n\treturn static_cast<mapss *>(impl);\n}\n\n}\n\nPropSetSimple::PropSetSimple() {\n\tmapss *props = new mapss;\n\timpl = static_cast<void *>(props);\n}\n\nPropSetSimple::~PropSetSimple() {\n\tmapss *props = PropsFromPointer(impl);\n\tdelete props;\n\timpl = nullptr;\n}\n\nbool PropSetSimple::Set(std::string_view key, std::string_view val) {\n\tmapss *props = PropsFromPointer(impl);\n\tif (!props)\n\t\treturn false;\n\tmapss::iterator const it = props->find(key);\n\tif (it != props->end()) {\n\t\tif (val == it->second)\n\t\t\treturn false;\n\t\tit->second = val;\n\t} else {\n\t\tprops->emplace(key, val);\n\t}\n\treturn true;\n}\n\nconst char *PropSetSimple::Get(std::string_view key) const {\n\tmapss *props = PropsFromPointer(impl);\n\tif (props) {\n\t\tmapss::const_iterator const keyPos = props->find(key);\n\t\tif (keyPos != props->end()) {\n\t\t\treturn keyPos->second.c_str();\n\t\t}\n\t}\n\treturn \"\";\n}\n\nint PropSetSimple::GetInt(std::string_view key, int defaultValue) const {\n\tconst char *val = Get(key);\n\tassert(val);\n\tif (*val) {\n\t\treturn atoi(val);\n\t}\n\treturn defaultValue;\n}\n"
  },
  {
    "path": "lexlib/PropSetSimple.h",
    "content": "// Scintilla source code edit control\n/** @file PropSetSimple.h\n ** A basic string to string map.\n **/\n// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef PROPSETSIMPLE_H\n#define PROPSETSIMPLE_H\n\nnamespace Lexilla {\n\nclass PropSetSimple {\n\tvoid *impl;\npublic:\n\tPropSetSimple();\n\t// Deleted so PropSetSimple objects can not be copied.\n\tPropSetSimple(const PropSetSimple&) = delete;\n\tPropSetSimple(PropSetSimple&&) = delete;\n\tPropSetSimple &operator=(const PropSetSimple&) = delete;\n\tPropSetSimple &operator=(PropSetSimple&&) = delete;\n\tvirtual ~PropSetSimple();\n\n\tbool Set(std::string_view key, std::string_view val);\n\tconst char *Get(std::string_view key) const;\n\tint GetInt(std::string_view key, int defaultValue=0) const;\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/SparseState.h",
    "content": "// Scintilla source code edit control\n/** @file SparseState.h\n ** Hold lexer state that may change rarely.\n ** This is often per-line state such as whether a particular type of section has been entered.\n ** A state continues until it is changed.\n **/\n// Copyright 2011 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef SPARSESTATE_H\n#define SPARSESTATE_H\n\nnamespace Lexilla {\n\ntemplate <typename T>\nclass SparseState {\n\tstruct State {\n\t\tSci_Position position;\n\t\tT value;\n\t\tconstexpr State(Sci_Position position_, T value_) noexcept :\n\t\t\tposition(position_), value(std::move(value_)) {\n\t\t}\n\t\tinline bool operator<(const State &other) const noexcept {\n\t\t\treturn position < other.position;\n\t\t}\n\t\tinline bool operator==(const State &other) const noexcept {\n\t\t\treturn (position == other.position) && (value == other.value);\n\t\t}\n\t};\n\tSci_Position positionFirst;\n\ttypedef std::vector<State> stateVector;\n\tstateVector states;\n\n\ttypename stateVector::iterator Find(Sci_Position position) {\n\t\tconst State searchValue(position, T());\n\t\treturn std::lower_bound(states.begin(), states.end(), searchValue);\n\t}\n\npublic:\n\texplicit SparseState(Sci_Position positionFirst_=-1) {\n\t\tpositionFirst = positionFirst_;\n\t}\n\tvoid Set(Sci_Position position, T value) {\n\t\tDelete(position);\n\t\tif (states.empty() || (value != states[states.size()-1].value)) {\n\t\t\tstates.emplace_back(position, value);\n\t\t}\n\t}\n\tT ValueAt(Sci_Position position) {\n\t\tif (states.empty())\n\t\t\treturn T();\n\t\tif (position < states[0].position)\n\t\t\treturn T();\n\t\ttypename stateVector::iterator low = Find(position);\n\t\tif (low == states.end()) {\n\t\t\treturn states[states.size()-1].value;\n\t\t} else {\n\t\t\tif (low->position > position) {\n\t\t\t\t--low;\n\t\t\t}\n\t\t\treturn low->value;\n\t\t}\n\t}\n\tbool Delete(Sci_Position position) {\n\t\tconst typename stateVector::iterator low = Find(position);\n\t\tif (low != states.end()) {\n\t\t\tstates.erase(low, states.end());\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\tsize_t size() const {\n\t\treturn states.size();\n\t}\n\n\t// Returns true if Merge caused a significant change\n\tbool Merge(const SparseState<T> &other, Sci_Position ignoreAfter) {\n\t\t// Changes caused beyond ignoreAfter are not significant\n\t\tDelete(ignoreAfter+1);\n\n\t\tbool different = true;\n\t\tbool changed = false;\n\t\tconst typename stateVector::iterator low = Find(other.positionFirst);\n\t\tif (static_cast<size_t>(states.end() - low) == other.states.size()) {\n\t\t\t// Same number in other as after positionFirst in this\n\t\t\tdifferent = !std::equal(low, states.end(), other.states.begin());\n\t\t}\n\t\tif (different) {\n\t\t\tif (low != states.end()) {\n\t\t\t\tstates.erase(low, states.end());\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t\ttypename stateVector::const_iterator startOther = other.states.begin();\n\t\t\tif (!states.empty() && !other.states.empty() && states.back().value == startOther->value)\n\t\t\t\t++startOther;\n\t\t\tif (startOther != other.states.end()) {\n\t\t\t\tstates.insert(states.end(), startOther, other.states.end());\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\t\treturn changed;\n\t}\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/StringCopy.h",
    "content": "// Scintilla source code edit control\n/** @file StringCopy.h\n ** Safe string copy function which always NUL terminates.\n ** ELEMENTS macro for determining array sizes.\n **/\n// Copyright 2013 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef STRINGCOPY_H\n#define STRINGCOPY_H\n\nnamespace Lexilla {\n\n// Safer version of string copy functions like strcpy, wcsncpy, etc.\n// Instantiate over fixed length strings of both char and wchar_t.\n// May truncate if source doesn't fit into dest with room for NUL.\n\ntemplate <typename T, size_t count>\nvoid StringCopy(T (&dest)[count], const T* source) {\n\tfor (size_t i=0; i<count; i++) {\n\t\tdest[i] = source[i];\n\t\tif (!source[i])\n\t\t\tbreak;\n\t}\n\tdest[count-1] = 0;\n}\n\n#define ELEMENTS(a) (sizeof(a) / sizeof(a[0]))\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/StyleContext.cxx",
    "content": "// Scintilla source code edit control\n/** @file StyleContext.cxx\n ** Lexer infrastructure.\n **/\n// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>\n// This file is in the public domain.\n\n#include <cstdlib>\n#include <cstdint>\n#include <cassert>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n\nusing namespace Lexilla;\n\nStyleContext::StyleContext(Sci_PositionU startPos, Sci_PositionU length,\n\tint initStyle, LexAccessor &styler_, char chMask) :\n\tstyler(styler_),\n\tmultiByteAccess((styler.Encoding() == EncodingType::eightBit) ? nullptr : styler.MultiByteAccess()),\n\tlengthDocument(static_cast<Sci_PositionU>(styler.Length())),\n\tendPos(((startPos + length) < lengthDocument) ? (startPos + length) : (lengthDocument+1)),\n\tlineDocEnd(styler.GetLine(lengthDocument)),\n\tcurrentPosLastRelative(SIZE_MAX),\n\tcurrentPos(startPos),\n\tcurrentLine(styler.GetLine(startPos)),\n\tlineEnd(styler.LineEnd(currentLine)),\n\tlineStartNext(styler.LineStart(currentLine + 1)),\n\tatLineStart(static_cast<Sci_PositionU>(styler.LineStart(currentLine)) == startPos),\n\t// Mask off all bits which aren't in the chMask.\n\tstate(initStyle &chMask) {\n\n\tstyler.StartAt(startPos /*, chMask*/);\n\tstyler.StartSegment(startPos);\n\n\tchPrev = GetRelativeCharacter(-1);\n\n\t// Variable width is now 0 so GetNextChar gets the char at currentPos into chNext/widthNext\n\tGetNextChar();\n\tch = chNext;\n\twidth = widthNext;\n\n\tGetNextChar();\n}\n\nbool StyleContext::MatchIgnoreCase(const char *s) {\n\tif (MakeLowerCase(ch) != static_cast<unsigned char>(*s))\n\t\treturn false;\n\ts++;\n\tif (!*s)\n\t\treturn true;\n\tif (MakeLowerCase(chNext) != static_cast<unsigned char>(*s))\n\t\treturn false;\n\ts++;\n\tfor (int n = 2; *s; n++) {\n\t\tif (*s !=\n\t\t\tMakeLowerCase(styler.SafeGetCharAt(currentPos + n, 0)))\n\t\t\treturn false;\n\t\ts++;\n\t}\n\treturn true;\n}\n\nvoid StyleContext::GetCurrent(char *s, Sci_PositionU len) const {\n\tstyler.GetRange(styler.GetStartSegment(), currentPos, s, len);\n}\n\nvoid StyleContext::GetCurrentLowered(char *s, Sci_PositionU len) const {\n\tstyler.GetRangeLowered(styler.GetStartSegment(), currentPos, s, len);\n}\n\nvoid StyleContext::GetCurrentString(std::string &string, Transform transform) const {\n\tconst Sci_PositionU startPos = styler.GetStartSegment();\n\tconst Sci_PositionU len = currentPos - styler.GetStartSegment();\n\tstring.resize(len);\n\tif (transform == Transform::lower) {\n\t\tstyler.GetRangeLowered(startPos, currentPos, string.data(), len + 1);\n\t} else {\n\t\tstyler.GetRange(startPos, currentPos, string.data(), len + 1);\n\t}\n}\n"
  },
  {
    "path": "lexlib/StyleContext.h",
    "content": "// Scintilla source code edit control\n/** @file StyleContext.h\n ** Lexer infrastructure.\n **/\n// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>\n// This file is in the public domain.\n\n#ifndef STYLECONTEXT_H\n#define STYLECONTEXT_H\n\nnamespace Lexilla {\n\n// All languages handled so far can treat all characters >= 0x80 as one class\n// which just continues the current token or starts an identifier if in default.\n// DBCS treated specially as the second character can be < 0x80 and hence\n// syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80\nclass StyleContext {\n\tLexAccessor &styler;\n\tScintilla::IDocument * const multiByteAccess;\n\tconst Sci_PositionU lengthDocument;\n\tconst Sci_PositionU endPos;\n\tconst Sci_Position lineDocEnd;\n\n\t// Used for optimizing GetRelativeCharacter\n\tSci_PositionU posRelative = 0;\n\tSci_PositionU currentPosLastRelative;\n\tSci_Position offsetRelative = 0;\n\n\tvoid GetNextChar() {\n\t\tif (multiByteAccess) {\n\t\t\tchNext = multiByteAccess->GetCharacterAndWidth(currentPos+width, &widthNext);\n\t\t} else {\n\t\t\tconst unsigned char charNext = styler.SafeGetCharAt(currentPos + width, 0);\n\t\t\tchNext = charNext;\n\t\t}\n\t\t// End of line determined from line end position, allowing CR, LF,\n\t\t// CRLF and Unicode line ends as set by document.\n\t\tconst Sci_Position currentPosSigned = currentPos;\n\t\tif (currentLine < lineDocEnd)\n\t\t\tatLineEnd = currentPosSigned >= (lineStartNext-1);\n\t\telse // Last line\n\t\t\tatLineEnd = currentPosSigned >= lineStartNext;\n\t}\n\npublic:\n\tSci_PositionU currentPos;\n\tSci_Position currentLine;\n\tSci_Position lineEnd;\n\tSci_Position lineStartNext;\n\tbool atLineStart;\n\tbool atLineEnd = false;\n\tint state;\n\tint chPrev = 0;\n\tint ch = 0;\n\tSci_Position width = 0;\n\tint chNext = 0;\n\tSci_Position widthNext = 1;\n\n\tStyleContext(Sci_PositionU startPos, Sci_PositionU length,\n                        int initStyle, LexAccessor &styler_, char chMask = '\\377');\n\t// Deleted so StyleContext objects can not be copied.\n\tStyleContext(const StyleContext &) = delete;\n\tStyleContext &operator=(const StyleContext &) = delete;\n\tvoid Complete() {\n\t\tstyler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);\n\t\tstyler.Flush();\n\t}\n\tbool More() const noexcept {\n\t\treturn currentPos < endPos;\n\t}\n\tvoid Forward() {\n\t\tif (currentPos < endPos) {\n\t\t\tatLineStart = atLineEnd;\n\t\t\tif (atLineStart) {\n\t\t\t\tcurrentLine++;\n\t\t\t\tlineEnd = styler.LineEnd(currentLine);\n\t\t\t\tlineStartNext = styler.LineStart(currentLine+1);\n\t\t\t}\n\t\t\tchPrev = ch;\n\t\t\tcurrentPos += width;\n\t\t\tch = chNext;\n\t\t\twidth = widthNext;\n\t\t\tGetNextChar();\n\t\t} else {\n\t\t\tatLineStart = false;\n\t\t\tchPrev = ' ';\n\t\t\tch = ' ';\n\t\t\tchNext = ' ';\n\t\t\tatLineEnd = true;\n\t\t}\n\t}\n\tvoid Forward(Sci_Position nb) {\n\t\tfor (Sci_Position i = 0; i < nb; i++) {\n\t\t\tForward();\n\t\t}\n\t}\n\tvoid ForwardBytes(Sci_Position nb) {\n\t\tconst Sci_PositionU forwardPos = currentPos + nb;\n\t\twhile (forwardPos > currentPos) {\n\t\t\tconst Sci_PositionU currentPosStart = currentPos;\n\t\t\tForward();\n\t\t\tif (currentPos == currentPosStart) {\n\t\t\t\t// Reached end\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\tvoid ChangeState(int state_) noexcept {\n\t\tstate = state_;\n\t}\n\tvoid SetState(int state_) {\n\t\tstyler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);\n\t\tstate = state_;\n\t}\n\tvoid ForwardSetState(int state_) {\n\t\tForward();\n\t\tstyler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);\n\t\tstate = state_;\n\t}\n\tSci_Position LengthCurrent() const noexcept {\n\t\treturn currentPos - styler.GetStartSegment();\n\t}\n\tchar GetRelativeChar(Sci_Position n, char chDefault='\\0') {\n\t\treturn styler.SafeGetCharAt(currentPos + n, chDefault);\n\t}\n\tint GetRelative(Sci_Position n, char chDefault='\\0') {\n\t\tconst unsigned char chRelative = styler.SafeGetCharAt(currentPos + n, chDefault);\n\t\treturn chRelative;\n\t}\n\tint GetRelativeCharacter(Sci_Position n) {\n\t\tif (n == 0)\n\t\t\treturn ch;\n\t\tif (multiByteAccess) {\n\t\t\tif ((currentPosLastRelative != currentPos) ||\n\t\t\t\t((n > 0) && ((offsetRelative < 0) || (n < offsetRelative))) ||\n\t\t\t\t((n < 0) && ((offsetRelative > 0) || (n > offsetRelative)))) {\n\t\t\t\tposRelative = currentPos;\n\t\t\t\toffsetRelative = 0;\n\t\t\t}\n\t\t\tconst Sci_Position diffRelative = n - offsetRelative;\n\t\t\tconst Sci_Position posNew = multiByteAccess->GetRelativePosition(posRelative, diffRelative);\n\t\t\tconst int chReturn = multiByteAccess->GetCharacterAndWidth(posNew, nullptr);\n\t\t\tposRelative = posNew;\n\t\t\tcurrentPosLastRelative = currentPos;\n\t\t\toffsetRelative = n;\n\t\t\treturn chReturn;\n\t\t} else {\n\t\t\t// fast version for single byte encodings\n\t\t\tconst unsigned char chRelative = styler.SafeGetCharAt(currentPos + n, 0);\n\t\t\treturn chRelative;\n\t\t}\n\t}\n\tbool MatchLineEnd() const noexcept {\n\t\tconst Sci_Position currentPosSigned = currentPos;\n\t\treturn currentPosSigned == lineEnd;\n\t}\n\tbool Match(char ch0) const noexcept {\n\t\tconst unsigned char uch0 = ch0;\n\t\treturn ch == uch0;\n\t}\n\tbool Match(char ch0, char ch1) const noexcept {\n\t\tconst unsigned char uch0 = ch0;\n\t\tconst unsigned char uch1 = ch1;\n\t\treturn (ch == uch0) && (chNext == uch1);\n\t}\n\tbool Match(const char *s) {\n\t\tconst unsigned char su = *s;\n\t\tif (ch != su)\n\t\t\treturn false;\n\t\ts++;\n\t\tif (!*s)\n\t\t\treturn true;\n\t\tconst unsigned char sNext = *s;\n\t\tif (chNext != sNext)\n\t\t\treturn false;\n\t\ts++;\n\t\tfor (int n=2; *s; n++) {\n\t\t\tif (*s != styler.SafeGetCharAt(currentPos+n, 0))\n\t\t\t\treturn false;\n\t\t\ts++;\n\t\t}\n\t\treturn true;\n\t}\n\t// Non-inline\n\tbool MatchIgnoreCase(const char *s);\n\tvoid GetCurrent(char *s, Sci_PositionU len) const;\n\tvoid GetCurrentLowered(char *s, Sci_PositionU len) const;\n\tenum class Transform { none, lower };\n\tvoid GetCurrentString(std::string &string, Transform transform) const;\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/SubStyles.h",
    "content": "// Scintilla source code edit control\n/** @file SubStyles.h\n ** Manage substyles for a lexer.\n **/\n// Copyright 2012 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef SUBSTYLES_H\n#define SUBSTYLES_H\n\nnamespace Lexilla {\n\nclass WordClassifier {\n\tint baseStyle;\n\tint firstStyle;\n\tint lenStyles;\n\tusing WordStyleMap = std::map<std::string, int, std::less<>>;\n\tWordStyleMap wordToStyle;\n\npublic:\n\n\texplicit WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) {\n\t}\n\n\tvoid Allocate(int firstStyle_, int lenStyles_) noexcept {\n\t\tfirstStyle = firstStyle_;\n\t\tlenStyles = lenStyles_;\n\t\twordToStyle.clear();\n\t}\n\n\tint Base() const noexcept {\n\t\treturn baseStyle;\n\t}\n\n\tint Start() const noexcept {\n\t\treturn firstStyle;\n\t}\n\n\tint Last() const noexcept {\n\t\treturn firstStyle + lenStyles - 1;\n\t}\n\n\tint Length() const noexcept {\n\t\treturn lenStyles;\n\t}\n\n\tvoid Clear() noexcept {\n\t\tfirstStyle = 0;\n\t\tlenStyles = 0;\n\t\twordToStyle.clear();\n\t}\n\n\tint ValueFor(std::string_view s) const {\n\t\tWordStyleMap::const_iterator const it = wordToStyle.find(s);\n\t\tif (it != wordToStyle.end())\n\t\t\treturn it->second;\n\t\telse\n\t\t\treturn -1;\n\t}\n\n\tbool IncludesStyle(int style) const noexcept {\n\t\treturn (style >= firstStyle) && (style < (firstStyle + lenStyles));\n\t}\n\n\tvoid RemoveStyle(int style) noexcept {\n\t\tWordStyleMap::iterator it = wordToStyle.begin();\n\t\twhile (it != wordToStyle.end()) {\n\t\t\tif (it->second == style) {\n\t\t\t\tit = wordToStyle.erase(it);\n\t\t\t} else {\n\t\t\t\t++it;\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid SetIdentifiers(int style, const char *identifiers, bool lowerCase) {\n\t\tRemoveStyle(style);\n\t\tif (!identifiers)\n\t\t\treturn;\n\t\twhile (*identifiers) {\n\t\t\tconst char *cpSpace = identifiers;\n\t\t\twhile (*cpSpace && !(*cpSpace == ' ' || *cpSpace == '\\t' || *cpSpace == '\\r' || *cpSpace == '\\n'))\n\t\t\t\tcpSpace++;\n\t\t\tif (cpSpace > identifiers) {\n\t\t\t\tstd::string word(identifiers, cpSpace - identifiers);\n\t\t\t\tif (lowerCase) {\n\t\t\t\t\tfor (char &ch : word) {\n\t\t\t\t\t\tch = MakeLowerCase(ch);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\twordToStyle[word] = style;\n\t\t\t}\n\t\t\tidentifiers = cpSpace;\n\t\t\tif (*identifiers)\n\t\t\t\tidentifiers++;\n\t\t}\n\t}\n};\n\n// This is the common configuration: 64 sub-styles allocated from 128 to 191\nconstexpr int SubStylesFirst = 0x80;\nconstexpr int SubStylesAvailable = 0x40;\n\nclass SubStyles {\n\tint classifications;\n\tconst char *baseStyles;\n\tint styleFirst;\n\tint stylesAvailable;\n\tint secondaryDistance;\n\tint allocated;\n\tstd::vector<WordClassifier> classifiers;\n\n\tint BlockFromBaseStyle(int baseStyle) const noexcept {\n\t\tfor (int b=0; b < classifications; b++) {\n\t\t\tif (baseStyle == baseStyles[b])\n\t\t\t\treturn b;\n\t\t}\n\t\treturn -1;\n\t}\n\n\tint BlockFromStyle(int style) const noexcept {\n\t\tint b = 0;\n\t\tfor (const WordClassifier &wc : classifiers) {\n\t\t\tif (wc.IncludesStyle(style))\n\t\t\t\treturn b;\n\t\t\tb++;\n\t\t}\n\t\treturn -1;\n\t}\n\npublic:\n\n\tSubStyles(const char *baseStyles_, int styleFirst_=SubStylesFirst, int stylesAvailable_=SubStylesAvailable, int secondaryDistance_=0) :\n\t\tclassifications(0),\n\t\tbaseStyles(baseStyles_),\n\t\tstyleFirst(styleFirst_),\n\t\tstylesAvailable(stylesAvailable_),\n\t\tsecondaryDistance(secondaryDistance_),\n\t\tallocated(0) {\n\t\twhile (baseStyles[classifications]) {\n\t\t\tclassifiers.push_back(WordClassifier(baseStyles[classifications]));\n\t\t\tclassifications++;\n\t\t}\n\t}\n\n\tint Allocate(int styleBase, int numberStyles) noexcept {\n\t\tconst int block = BlockFromBaseStyle(styleBase);\n\t\tif (block >= 0) {\n\t\t\tif ((allocated + numberStyles) > stylesAvailable)\n\t\t\t\treturn -1;\n\t\t\tconst int startBlock = styleFirst + allocated;\n\t\t\tallocated += numberStyles;\n\t\t\tclassifiers[block].Allocate(startBlock, numberStyles);\n\t\t\treturn startBlock;\n\t\t} else {\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tint Start(int styleBase) noexcept {\n\t\tconst int block = BlockFromBaseStyle(styleBase);\n\t\treturn (block >= 0) ? classifiers[block].Start() : -1;\n\t}\n\n\tint Length(int styleBase) noexcept {\n\t\tconst int block = BlockFromBaseStyle(styleBase);\n\t\treturn (block >= 0) ? classifiers[block].Length() : 0;\n\t}\n\n\tint BaseStyle(int subStyle) const noexcept {\n\t\tconst int block = BlockFromStyle(subStyle);\n\t\tif (block >= 0)\n\t\t\treturn classifiers[block].Base();\n\t\telse\n\t\t\treturn subStyle;\n\t}\n\n\tint DistanceToSecondaryStyles() const noexcept {\n\t\treturn secondaryDistance;\n\t}\n\n\tint FirstAllocated() const noexcept {\n\t\tint start = 257;\n\t\tfor (const WordClassifier &wc : classifiers) {\n\t\t\tif ((wc.Length() > 0) && (start > wc.Start()))\n\t\t\t\tstart = wc.Start();\n\t\t}\n\t\treturn (start < 256) ? start : -1;\n\t}\n\n\tint LastAllocated() const noexcept {\n\t\tint last = -1;\n\t\tfor (const WordClassifier &wc : classifiers) {\n\t\t\tif ((wc.Length() > 0) && (last < wc.Last()))\n\t\t\t\tlast = wc.Last();\n\t\t}\n\t\treturn last;\n\t}\n\n\tvoid SetIdentifiers(int style, const char *identifiers, bool lowerCase=false) {\n\t\tconst int block = BlockFromStyle(style);\n\t\tif (block >= 0)\n\t\t\tclassifiers[block].SetIdentifiers(style, identifiers, lowerCase);\n\t}\n\n\tvoid Free() noexcept {\n\t\tallocated = 0;\n\t\tfor (WordClassifier &wc : classifiers) {\n\t\t\twc.Clear();\n\t\t}\n\t}\n\n\tconst WordClassifier &Classifier(int baseStyle) const noexcept {\n\t\tconst int block = BlockFromBaseStyle(baseStyle);\n\t\treturn classifiers[block >= 0 ? block : 0];\n\t}\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "lexlib/WordList.cxx",
    "content": "// Scintilla source code edit control\n/** @file WordList.cxx\n ** Hold a list of words.\n **/\n// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstdlib>\n#include <cassert>\n#include <cstring>\n\n#include <string>\n#include <algorithm>\n#include <iterator>\n#include <memory>\n\n#include \"WordList.h\"\n#include \"CharacterSet.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\n/**\n * Creates an array that points into each word in the string and puts \\0 terminators\n * after each word.\n */\nstd::unique_ptr<char *[]> ArrayFromWordList(char *wordlist, size_t slen, size_t *len, bool onlyLineEnds = false) {\n\tassert(wordlist);\n\tsize_t words = 0;\n\t// For rapid determination of whether a character is a separator, build\n\t// a look up table.\n\tbool wordSeparator[256] = {};\t// Initialise all to false.\n\twordSeparator[static_cast<unsigned int>('\\r')] = true;\n\twordSeparator[static_cast<unsigned int>('\\n')] = true;\n\tif (!onlyLineEnds) {\n\t\twordSeparator[static_cast<unsigned int>(' ')] = true;\n\t\twordSeparator[static_cast<unsigned int>('\\t')] = true;\n\t}\n\tunsigned char prev = '\\n';\n\tfor (int j = 0; wordlist[j]; j++) {\n\t\tconst unsigned char curr = wordlist[j];\n\t\tif (!wordSeparator[curr] && wordSeparator[prev])\n\t\t\twords++;\n\t\tprev = curr;\n\t}\n\tstd::unique_ptr<char *[]> keywords = std::make_unique<char *[]>(words + 1);\n\tsize_t wordsStore = 0;\n\tif (words) {\n\t\tunsigned char previous = '\\0';\n\t\tfor (size_t k = 0; k < slen; k++) {\n\t\t\tif (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {\n\t\t\t\tif (!previous) {\n\t\t\t\t\tkeywords[wordsStore] = &wordlist[k];\n\t\t\t\t\twordsStore++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twordlist[k] = '\\0';\n\t\t\t}\n\t\t\tprevious = wordlist[k];\n\t\t}\n\t}\n\tassert(wordsStore < (words + 1));\n\tkeywords[wordsStore] = &wordlist[slen];\n\t*len = wordsStore;\n\treturn keywords;\n}\n\nbool cmpWords(const char *a, const char *b) noexcept {\n\treturn strcmp(a, b) < 0;\n}\n\n}\n\nWordList::WordList(bool onlyLineEnds_) noexcept :\n\twords(nullptr), list(nullptr), len(0), onlyLineEnds(onlyLineEnds_) {\n\t// Prevent warnings by static analyzers about uninitialized starts.\n\tstarts[0] = -1;\n}\n\nWordList::~WordList() {\n\tClear();\n}\n\nWordList::operator bool() const noexcept {\n\treturn len != 0;\n}\n\nbool WordList::operator!=(const WordList &other) const noexcept {\n\tif (len != other.len)\n\t\treturn true;\n\tfor (size_t i=0; i<len; i++) {\n\t\tif (strcmp(words[i], other.words[i]) != 0)\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nint WordList::Length() const noexcept {\n\treturn static_cast<int>(len);\n}\n\nvoid WordList::Clear() noexcept {\n\tdelete []list;\n\tlist = nullptr;\n\tdelete []words;\n\twords = nullptr;\n\tlen = 0;\n}\n\nbool WordList::Set(const char *s, bool lowerCase) {\n\tconst size_t lenS = strlen(s) + 1;\n\tstd::unique_ptr<char[]> listTemp = std::make_unique<char[]>(lenS);\n\tmemcpy(listTemp.get(), s, lenS);\n\tif (lowerCase) {\n\t\tfor (size_t i = 0; i < lenS; i++) {\n\t\t\tlistTemp[i] = MakeLowerCase(listTemp[i]);\n\t\t}\n\t}\n\tsize_t lenTemp = 0;\n\tstd::unique_ptr<char *[]> wordsTemp = ArrayFromWordList(listTemp.get(), lenS - 1, &lenTemp, onlyLineEnds);\n\tstd::sort(wordsTemp.get(), wordsTemp.get() + lenTemp, cmpWords);\n\n\tif (lenTemp == len) {\n\t\tbool changed = false;\n\t\tfor (size_t i = 0; i < lenTemp; i++) {\n\t\t\tif (strcmp(words[i], wordsTemp[i]) != 0) {\n\t\t\t\tchanged = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!changed) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tClear();\n\twords = wordsTemp.release();\n\tlist = listTemp.release();\n\tlen = lenTemp;\n\tstd::fill(starts, std::end(starts), -1);\n\tfor (int l = static_cast<int>(len - 1); l >= 0; l--) {\n\t\tunsigned char const indexChar = words[l][0];\n\t\tstarts[indexChar] = l;\n\t}\n\treturn true;\n}\n\n/** Check whether a string is in the list.\n * List elements are either exact matches or prefixes.\n * Prefix elements start with '^' and match all strings that start with the rest of the element\n * so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'.\n */\nbool WordList::InList(const char *s) const noexcept {\n\tif (!words)\n\t\treturn false;\n\tconst char first = s[0];\n\tconst unsigned char firstChar = first;\n\tint j = starts[firstChar];\n\tif (j >= 0) {\n\t\twhile (words[j][0] == first) {\n\t\t\tif (s[1] == words[j][1]) {\n\t\t\t\tconst char *a = words[j] + 1;\n\t\t\t\tconst char *b = s + 1;\n\t\t\t\twhile (*a && *a == *b) {\n\t\t\t\t\ta++;\n\t\t\t\t\tb++;\n\t\t\t\t}\n\t\t\t\tif (!*a && !*b)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\tj++;\n\t\t}\n\t}\n\tj = starts[static_cast<unsigned int>('^')];\n\tif (j >= 0) {\n\t\twhile (words[j][0] == '^') {\n\t\t\tconst char *a = words[j] + 1;\n\t\t\tconst char *b = s;\n\t\t\twhile (*a && *a == *b) {\n\t\t\t\ta++;\n\t\t\t\tb++;\n\t\t\t}\n\t\t\tif (!*a)\n\t\t\t\treturn true;\n\t\t\tj++;\n\t\t}\n\t}\n\treturn false;\n}\n\n/** convenience overload so can easily call with std::string.\n */\n\nbool WordList::InList(std::string_view sv) const noexcept {\n\tif (!words || sv.empty())\n\t\treturn false;\n\tconst char first = sv[0];\n\tconst unsigned char firstChar = first;\n\tif (int j = starts[firstChar]; j >= 0) {\n\t\tconst std::string_view after = sv.substr(1);\n\t\tfor (; words[j][0] == first; j++) {\n\t\t\tif (std::string_view(words[j] + 1) == after) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\tif (int j = starts[static_cast<unsigned int>('^')]; j >= 0) {\n\t\tfor (; words[j][0] == '^';j++) {\n\t\t\t// Use rfind with 0 position to act like C++20 starts_with for C++17\n\t\t\tif (sv.rfind(words[j] + 1, 0) == 0) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\n/** similar to InList, but word s can be a substring of keyword.\n * eg. the keyword define is defined as def~ine. This means the word must start\n * with def to be a keyword, but also defi, defin and define are valid.\n * The marker is ~ in this case.\n */\nbool WordList::InListAbbreviated(const char *s, const char marker) const noexcept {\n\tif (!words)\n\t\treturn false;\n\tconst char first = s[0];\n\tconst unsigned char firstChar = first;\n\tint j = starts[firstChar];\n\tif (j >= 0) {\n\t\twhile (words[j][0] == first) {\n\t\t\tbool isSubword = false;\n\t\t\tint start = 1;\n\t\t\tif (words[j][1] == marker) {\n\t\t\t\tisSubword = true;\n\t\t\t\tstart++;\n\t\t\t}\n\t\t\tif (s[1] == words[j][start]) {\n\t\t\t\tconst char *a = words[j] + start;\n\t\t\t\tconst char *b = s + 1;\n\t\t\t\twhile (*a && *a == *b) {\n\t\t\t\t\ta++;\n\t\t\t\t\tif (*a == marker) {\n\t\t\t\t\t\tisSubword = true;\n\t\t\t\t\t\ta++;\n\t\t\t\t\t}\n\t\t\t\t\tb++;\n\t\t\t\t}\n\t\t\t\tif ((!*a || isSubword) && !*b)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\tj++;\n\t\t}\n\t}\n\tj = starts[static_cast<unsigned int>('^')];\n\tif (j >= 0) {\n\t\twhile (words[j][0] == '^') {\n\t\t\tconst char *a = words[j] + 1;\n\t\t\tconst char *b = s;\n\t\t\twhile (*a && *a == *b) {\n\t\t\t\ta++;\n\t\t\t\tb++;\n\t\t\t}\n\t\t\tif (!*a)\n\t\t\t\treturn true;\n\t\t\tj++;\n\t\t}\n\t}\n\treturn false;\n}\n\n/** similar to InListAbbreviated, but word s can be an abridged version of a keyword.\n* eg. the keyword is defined as \"after.~:\". This means the word must have a prefix (begins with) of\n* \"after.\" and suffix (ends with) of \":\" to be a keyword, Hence \"after.field:\" , \"after.form.item:\" are valid.\n* Similarly \"~.is.valid\" keyword is suffix only... hence \"field.is.valid\" , \"form.is.valid\" are valid.\n* The marker is ~ in this case.\n* No multiple markers check is done and wont work.\n*/\nbool WordList::InListAbridged(const char *s, const char marker) const noexcept {\n\tif (!words)\n\t\treturn false;\n\tconst char first = s[0];\n\tconst unsigned char firstChar = first;\n\tint j = starts[firstChar];\n\tif (j >= 0) {\n\t\twhile (words[j][0] == first) {\n\t\t\tconst char *a = words[j];\n\t\t\tconst char *b = s;\n\t\t\twhile (*a && *a == *b) {\n\t\t\t\ta++;\n\t\t\t\tif (*a == marker) {\n\t\t\t\t\ta++;\n\t\t\t\t\tconst size_t suffixLengthA = strlen(a);\n\t\t\t\t\tconst size_t suffixLengthB = strlen(b);\n\t\t\t\t\tif (suffixLengthA >= suffixLengthB)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tb = b + suffixLengthB - suffixLengthA - 1;\n\t\t\t\t}\n\t\t\t\tb++;\n\t\t\t}\n\t\t\tif (!*a  && !*b)\n\t\t\t\treturn true;\n\t\t\tj++;\n\t\t}\n\t}\n\n\tj = starts[static_cast<unsigned int>(marker)];\n\tif (j >= 0) {\n\t\twhile (words[j][0] == marker) {\n\t\t\tconst char *a = words[j] + 1;\n\t\t\tconst char *b = s;\n\t\t\tconst size_t suffixLengthA = strlen(a);\n\t\t\tconst size_t suffixLengthB = strlen(b);\n\t\t\tif (suffixLengthA > suffixLengthB) {\n\t\t\t\tj++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tb = b + suffixLengthB - suffixLengthA;\n\n\t\t\twhile (*a && *a == *b) {\n\t\t\t\ta++;\n\t\t\t\tb++;\n\t\t\t}\n\t\t\tif (!*a && !*b)\n\t\t\t\treturn true;\n\t\t\tj++;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nconst char *WordList::WordAt(int n) const noexcept {\n\treturn words[n];\n}\n\n"
  },
  {
    "path": "lexlib/WordList.h",
    "content": "// Scintilla source code edit control\n/** @file WordList.h\n ** Hold a list of words.\n **/\n// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef WORDLIST_H\n#define WORDLIST_H\n\nnamespace Lexilla {\n\n/**\n */\nclass WordList {\n\t// Each word contains at least one character - an empty word acts as sentinel at the end.\n\tchar **words;\n\tchar *list;\n\tsize_t len;\n\tbool onlyLineEnds;\t///< Delimited by any white space or only line ends\n\tint starts[256];\npublic:\n\texplicit WordList(bool onlyLineEnds_ = false) noexcept;\n\t// Deleted so WordList objects can not be copied.\n\tWordList(const WordList &) = delete;\n\tWordList(WordList &&) = delete;\n\tWordList &operator=(const WordList &) = delete;\n\tWordList &operator=(WordList &&) = delete;\n\t~WordList();\n\toperator bool() const noexcept;\n\tbool operator!=(const WordList &other) const noexcept;\n\tint Length() const noexcept;\n\tvoid Clear() noexcept;\n\tbool Set(const char *s, bool lowerCase=false);\n\tbool InList(const char *s) const noexcept;\n\tbool InList(std::string_view sv) const noexcept;\n\tbool InListAbbreviated(const char *s, const char marker) const noexcept;\n\tbool InListAbridged(const char *s, const char marker) const noexcept;\n\tconst char *WordAt(int n) const noexcept;\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "scripts/HeaderOrder.txt",
    "content": "// Define the standard order in which to include header files\n// All platform headers should be included before Scintilla headers\n// and each of these groups are then divided into directory groups.\n\n// Base of the repository relative to this file\n\n//base:..\n\n// File patterns to check:\n\n//source:include/*.h\n//source:src/*.cxx\n//source:lexlib/*.cxx\n//source:lexers/*.cxx\n//source:access/*.cxx\n//source:test/*.cxx\n//source:test/unit/*.cxx\n\n// C standard library\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <ctype.h>\n\n// C++ wrappers of C standard library\n#include <cstdlib>\n#include <cstdint>\n#include <cassert>\n#include <cstring>\n#include <cctype>\n#include <cstdio>\n#include <cstdarg>\n\n// C++ standard library\n#include <utility>\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <set>\n#include <optional>\n#include <initializer_list>\n#include <algorithm>\n#include <iterator>\n#include <functional>\n#include <memory>\n#include <regex>\n#include <iostream>\n#include <sstream>\n#include <fstream>\n#include <iomanip>\n#include <filesystem>\n\n// POSIX\n#include <dlfcn.h>\n\n// Windows header needed for loading DLL\n#include <windows.h>\n\n// Scintilla/Lexilla headers\n\n// Non-platform-specific headers\n\n// Scintilla include\n\n#include \"Sci_Position.h\"\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n\n// Lexilla include\n\n#include \"SciLexer.h\"\n#include \"Lexilla.h\"\n\n// access\n\n#include \"LexillaAccess.h\"\n\n// lexlib\n#include \"StringCopy.h\"\n#include \"PropSetSimple.h\"\n#include \"InList.h\"\n#include \"WordList.h\"\n#include \"LexAccessor.h\"\n#include \"Accessor.h\"\n#include \"StyleContext.h\"\n#include \"CharacterSet.h\"\n#include \"CharacterCategory.h\"\n#include \"LexerModule.h\"\n#include \"CatalogueModules.h\"\n#include \"OptionSet.h\"\n#include \"SparseState.h\"\n#include \"SubStyles.h\"\n#include \"DefaultLexer.h\"\n#include \"LexerBase.h\"\n#include \"LexerSimple.h\"\n\n// test\n\n#include \"TestDocument.h\"\n\n// Catch testing framework\n#include \"catch.hpp\"\n\n"
  },
  {
    "path": "scripts/LexFacer.py",
    "content": "#!/usr/bin/env python3\n# LexFacer.py - regenerate the SciLexer.h files from the LexicalStyles.iface interface\n# definition file.\n# Implemented 2000 by Neil Hodgson neilh@scintilla.org\n# Requires Python 3.6 or later\n\nimport os, pathlib, sys\n\nsys.path.append(os.path.join(\"..\", \"..\", \"scintilla\", \"scripts\"))\n\nimport Face\nimport FileGenerator\n\ndef printLexHFile(f):\n\tout = []\n\tfor name in f.order:\n\t\tv = f.features[name]\n\t\tif v[\"FeatureType\"] in [\"val\"]:\n\t\t\tif \"SCE_\" in name or \"SCLEX_\" in name:\n\t\t\t\tout.append(\"#define \" + name + \" \" + v[\"Value\"])\n\treturn out\n\ndef RegenerateAll(root, _showMaxID):\n\tf = Face.Face()\n\tf.ReadFromFile(root / \"include/LexicalStyles.iface\")\n\tFileGenerator.Regenerate(root / \"include/SciLexer.h\", \"/* \", printLexHFile(f))\n\nif __name__ == \"__main__\":\n\tRegenerateAll(pathlib.Path(__file__).resolve().parent.parent, True)\n"
  },
  {
    "path": "scripts/LexillaData.py",
    "content": "#!/usr/bin/env python3\n# LexillaData.py - implemented 2013 by Neil Hodgson neilh@scintilla.org\n# Released to the public domain.\n\n\"\"\"\nCommon code used by Lexilla and SciTE for source file regeneration.\n\"\"\"\n\n# The LexillaData object exposes information about Lexilla as properties:\n# Version properties\n#     version\n#     versionDotted\n#     versionCommad\n#\n# Date last modified\n#     dateModified\n#     yearModified\n#     mdyModified\n#     dmyModified\n#     myModified\n#\n# Information about lexers and properties defined in lexers\n#     lexFiles\n#         sorted list of lexer file stems like LexAbaqus\n#     lexerModules\n#         sorted list of module names like lmAbaqus\n#     lexerProperties\n#         sorted list of lexer properties like lexer.bash.command.substitution\n#     propertyDocuments\n#         dictionary of property documentation { name: document string }\n#         like lexer.bash.special.parameter: Set shell (default is Bash) special parameters.\n#     sclexFromName\n#         dictionary of SCLEX_* IDs { name: SCLEX_ID } like ave: SCLEX_AVE\n#     fileFromSclex\n#         dictionary of file names { SCLEX_ID: file name } like SCLEX_AU3: LexAU3.cxx\n#     lexersXcode\n#         dictionary of project file UUIDs { file name: [build UUID, file UUID] }\n#         like  LexTCL: [28BA733B24E34D9700272C2D,28BA72C924E34D9100272C2D]\n#     credits\n#         list of names of contributors like Atsuo Ishimoto\n\n# This file can be run to see the data it provides.\n# Requires Python 3.6 or later\n\nimport datetime, pathlib, sys, textwrap\n\nneutralEncoding = \"iso-8859-1\"\t# Each byte value is valid in iso-8859-1\n\ndef ReadFileAsList(path):\n    \"\"\"Read all the lnes in the file and return as a list of strings without line ends.\n    \"\"\"\n    with path.open(encoding=\"utf-8\") as f:\n        return [line.rstrip('\\n') for line in f]\n\ndef FindModules(lexFile):\n    \"\"\" Return a list of modules found within a lexer implementation file. \"\"\"\n    modules = []\n    partLine = \"\"\n    with lexFile.open(encoding=neutralEncoding) as f:\n        lineNum = 0\n        for line in f:\n            lineNum += 1\n            line = line.rstrip()\n            if partLine or line.startswith(\"extern const LexerModule\"):\n                if \")\" in line:\n                    line = partLine + line\n                    original = line\n                    line = line.replace(\"(\", \" \")\n                    line = line.replace(\")\", \" \")\n                    line = line.replace(\",\", \" \")\n                    parts = line.split()[2:]\n                    lexerName = parts[4]\n                    if not (lexerName.startswith('\"') and lexerName.endswith('\"')):\n                        print(f\"{lexFile}:{lineNum}: Bad LexerModule statement:\\n{original}\")\n                        sys.exit(1)\n                    lexerName = lexerName.strip('\"')\n                    modules.append([parts[1], parts[2], lexerName])\n                    partLine = \"\"\n                else:\n                    partLine = partLine + line\n    return modules\n\ndef FindSectionInList(lines, markers):\n    \"\"\"Find a section defined by an initial start marker, an optional secondary\n    marker and an end marker.\n    The section is between the secondary/initial start and the end.\n    Report as a slice object so the section can be extracted or replaced.\n    Raises an exception if the markers can't be found.\n    Currently only used for Xcode project files.\n    \"\"\"\n    start = -1\n    end = -1\n    state = 0\n    for i, line in enumerate(lines):\n        if markers[0] in line:\n            if markers[1]:\n                state = 1\n            else:\n                start = i+1\n                state = 2\n        elif state == 1:\n            if markers[1] in line:\n                start = i+1\n                state = 2\n        elif state == 2:\n            if markers[2] in line:\n                end = i\n                state = 3\n    # Check that section was found\n    if start == -1:\n        raise ValueError(\"Could not find start marker(s) |\" + markers[0] + \"|\" + markers[1] + \"|\")\n    if end == -1:\n        raise ValueError(\"Could not find end marker \" + markers[2])\n    return slice(start, end)\n\ndef FindLexersInXcode(xCodeProject):\n    \"\"\" Return a dictionary { file name: [build UUID, file UUID] } of lexers in Xcode project. \"\"\"\n    lines = ReadFileAsList(xCodeProject)\n\n    # PBXBuildFile section is a list of all buildable files in the project so extract the file\n    # basename and its build and file IDs\n    uidsOfBuild = {}\n    markersPBXBuildFile = [\"Begin PBXBuildFile section\", \"\", \"End PBXBuildFile section\"]\n    for buildLine in lines[FindSectionInList(lines, markersPBXBuildFile)]:\n        # Occurs for each file in the build. Find the UIDs used for the file.\n        #\\t\\t[0-9A-F]+ /* [a-zA-Z]+.cxx in sources */ = {isa = PBXBuildFile; fileRef = [0-9A-F]+ /* [a-zA-Z]+ */; };\n        pieces = buildLine.split()\n        uid1 = pieces[0]\n        filename = pieces[2].split(\".\")[0]\n        uid2 = pieces[12]\n        uidsOfBuild[filename] = [uid1, uid2]\n\n    # PBXGroup section contains the folders (Lexilla, Lexers, LexLib, ...) so is used to find the lexers\n    lexers = {}\n    markersLexers = [\"/* Lexers */ =\", \"children\", \");\"]\n    for lexerLine in lines[FindSectionInList(lines, markersLexers)]:\n        #\\t\\t\\t\\t[0-9A-F]+ /* [a-zA-Z]+.cxx */,\n        uid, _, rest = lexerLine.partition(\"/* \")\n        uid = uid.strip()\n        lexer, _, _ = rest.partition(\".\")\n        lexers[lexer] = uidsOfBuild[lexer]\n\n    return lexers\n\n# Properties that start with lexer. or fold. are automatically found but there are some\n# older properties that don't follow this pattern so must be explicitly listed.\nknownIrregularProperties = [\n    \"fold\",\n    \"styling.within.preprocessor\",\n    \"tab.timmy.whinge.level\",\n    \"asp.default.language\",\n    \"html.tags.case.sensitive\",\n    \"ps.level\",\n    \"ps.tokenize\",\n    \"sql.backslash.escapes\",\n    \"nsis.uservars\",\n    \"nsis.ignorecase\"\n]\n\ndef FindProperties(lexFile):\n    \"\"\" Return a set of property names in a lexer implementation file. \"\"\"\n    properties = set()\n    with open(lexFile, encoding=neutralEncoding) as f:\n        for s in f:\n            if (\"GetProperty\" in s or \"DefineProperty\" in s) and \"\\\"\" in s:\n                s = s.strip()\n                if not s.startswith(\"//\"):\t# Drop comments\n                    propertyName = s.split(\"\\\"\")[1]\n                    if propertyName.lower() == propertyName:\n                        # Only allow lower case property names\n                        if propertyName in knownIrregularProperties or \\\n                            propertyName.startswith(\"fold.\") or \\\n                            propertyName.startswith(\"lexer.\"):\n                            properties.add(propertyName)\n    return properties\n\ndef FindPropertyDocumentation(lexFile):\n    \"\"\" Return a dictionary { name: document string } of property documentation in a lexer. \"\"\"\n    documents = {}\n    with lexFile.open(encoding=neutralEncoding) as f:\n        name = \"\"\n        for line in f:\n            line = line.strip()\n            if \"// property \" in line:\n                propertyName = line.split()[2]\n                if propertyName.lower() == propertyName:\n                    # Only allow lower case property names\n                    name = propertyName\n                    documents[name] = \"\"\n            elif \"DefineProperty\" in line and \"\\\"\" in line:\n                propertyName = line.split(\"\\\"\")[1]\n                if propertyName.lower() == propertyName:\n                    # Only allow lower case property names\n                    name = propertyName\n                    documents[name] = \"\"\n            elif name:\n                if line.startswith(\"//\"):\n                    if documents[name]:\n                        documents[name] += \" \"\n                    documents[name] += line[2:].strip()\n                elif line.startswith(\"\\\"\"):\n                    line = line[1:].strip()\n                    if line.endswith(\";\"):\n                        line = line[:-1].strip()\n                    if line.endswith(\")\"):\n                        line = line[:-1].strip()\n                    if line.endswith(\"\\\"\"):\n                        line = line[:-1]\n                    # Fix escaped double quotes\n                    line = line.replace(\"\\\\\\\"\", \"\\\"\")\n                    documents[name] += line\n                else:\n                    name = \"\"\n    for name in list(documents.keys()):\n        if documents[name] == \"\":\n            del documents[name]\n    return documents\n\ndef FindCredits(historyFile):\n    \"\"\" Return a list of contributors in a history file. \"\"\"\n    credits = []\n    stage = 0\n    with historyFile.open(encoding=\"utf-8\") as f:\n        for line in f:\n            s = line.strip()\n            if stage == 0 and s == \"<table>\":\n                stage = 1\n            elif stage == 1 and s == \"</table>\":\n                stage = 2\n            if stage == 1 and s.startswith(\"<td>\"):\n                credit = s[4:-5]\n                if \"<a\" in s:\n                    title, _, rest = credit.partition(\"<a href=\")\n                    urlplus, _bracket, end = rest.partition(\">\")\n                    name = end.split(\"<\")[0]\n                    url = urlplus[1:-1]\n                    credit = title.strip()\n                    if credit:\n                        credit += \" \"\n                    credit += name + \" \" + url\n                credits.append(credit)\n    return credits\n\ndef ciKey(a):\n    \"\"\" Return a string lowered to be used when sorting. \"\"\"\n    return str(a).lower()\n\ndef SortListInsensitive(l):\n    \"\"\" Sort a list of strings case insensitively. \"\"\"\n    l.sort(key=ciKey)\n\nclass LexillaData:\n    \"\"\" Expose information about Lexilla as properties. \"\"\"\n\n    def __init__(self, scintillaRoot):\n        # Discover version information\n        self.version = (scintillaRoot / \"version.txt\").read_text().strip()\n        self.versionDotted = self.version[0:-2] + '.' + self.version[-2] + '.' + \\\n            self.version[-1]\n        self.versionCommad = self.versionDotted.replace(\".\", \", \") + ', 0'\n\n        with (scintillaRoot / \"doc\" / \"Lexilla.html\").open() as f:\n            self.dateModified = [d for d in f if \"Date.Modified\" in d]\\\n                [0].split('\\\"')[3]\n            # 20130602\n            # Lexilla.html\n            dtModified = datetime.datetime.strptime(self.dateModified, \"%Y%m%d\")\n            self.yearModified = self.dateModified[0:4]\n            monthModified = dtModified.strftime(\"%B\")\n            dayModified = f\"{dtModified.day}\"\n            self.mdyModified = monthModified + \" \" + dayModified + \" \" + self.yearModified\n            # May 22 2013\n            # Lexilla.html, SciTE.html\n            self.dmyModified = dayModified + \" \" + monthModified + \" \" + self.yearModified\n            # 22 May 2013\n            # LexillaHistory.html -- only first should change\n            self.myModified = monthModified + \" \" + self.yearModified\n\n        # Find all the lexer source code files\n        lexFilePaths = list((scintillaRoot / \"lexers\").glob(\"Lex*.cxx\"))\n        SortListInsensitive(lexFilePaths)\n        self.lexFiles = [f.stem for f in lexFilePaths]\n        self.lexerModules = []\n        lexerProperties = set()\n        self.propertyDocuments = {}\n        self.sclexFromName = {}\n        self.fileFromSclex = {}\n        for lexFile in lexFilePaths:\n            modules = FindModules(lexFile)\n            for module in modules:\n                self.sclexFromName[module[2]] = module[1]\n                self.fileFromSclex[module[1]] = lexFile\n                self.lexerModules.append(module[0])\n            for prop in FindProperties(lexFile):\n                lexerProperties.add(prop)\n            documents = FindPropertyDocumentation(lexFile)\n            for prop, doc in documents.items():\n                if prop not in self.propertyDocuments:\n                    self.propertyDocuments[prop] = doc\n        SortListInsensitive(self.lexerModules)\n        self.lexerProperties = list(lexerProperties)\n        SortListInsensitive(self.lexerProperties)\n\n        self.lexersXcode = FindLexersInXcode(scintillaRoot /\n            \"src/Lexilla/Lexilla.xcodeproj/project.pbxproj\")\n        self.credits = FindCredits(scintillaRoot / \"doc\" / \"LexillaHistory.html\")\n\ndef printWrapped(text):\n    \"\"\" Print string wrapped with subsequent lines indented. \"\"\"\n    print(textwrap.fill(text, subsequent_indent=\"    \"))\n\nif __name__==\"__main__\":\n    sci = LexillaData(pathlib.Path(__file__).resolve().parent.parent)\n    print(f\"Version   {sci.version}   {sci.versionDotted}   {sci.versionCommad}\")\n    print(f\"Date last modified    {sci.dateModified}   {sci.yearModified}   {sci.mdyModified}\"\n        f\"   {sci.dmyModified}   {sci.myModified}\")\n    printWrapped(str(len(sci.lexFiles)) + \" lexer files: \" + \", \".join(sci.lexFiles))\n    printWrapped(str(len(sci.lexerModules)) + \" lexer modules: \" + \", \".join(sci.lexerModules))\n    #~ printWrapped(str(len(sci.lexersXcode)) + \" Xcode lexer references: \" + \", \".join(\n        #~ [lex+\":\"+uids[0]+\",\"+uids[1] for lex, uids in sci.lexersXcode.items()]))\n    print(\"Lexer name to ID:\")\n    lexNames = sorted(sci.sclexFromName.keys())\n    for lexName in lexNames:\n        sclex = sci.sclexFromName[lexName]\n        fileName = sci.fileFromSclex[sclex].name\n        print(\"    \" + lexName + \" -> \" + sclex + \" in \" + fileName)\n    printWrapped(\"Lexer properties: \" + \", \".join(sci.lexerProperties))\n    print(\"Lexer property documentation:\")\n    documentProperties = list(sci.propertyDocuments.keys())\n    SortListInsensitive(documentProperties)\n    for k in documentProperties:\n        print(\"    \" + k)\n        print(textwrap.fill(sci.propertyDocuments[k], initial_indent=\"        \",\n            subsequent_indent=\"        \"))\n    print(\"Credits:\")\n    for c in sci.credits:\n        sys.stdout.buffer.write(b\"    \" + c.encode(\"utf-8\") + b\"\\n\")\n"
  },
  {
    "path": "scripts/LexillaGen.py",
    "content": "#!/usr/bin/env python3\n# LexillaGen.py - implemented 2019 by Neil Hodgson neilh@scintilla.org\n# Released to the public domain.\n\n\"\"\"\nRegenerate the Lexilla source files that list all the lexers.\n\"\"\"\n\n# Should be run whenever a new lexer is added or removed.\n# Requires Python 3.6 or later\n# Files are regenerated in place with templates stored in comments.\n# The format of generation comments is documented in FileGenerator.py.\n\nimport os, pathlib, sys, uuid\n\nthisPath = pathlib.Path(__file__).resolve()\n\nsys.path.append(str(thisPath.parent.parent.parent / \"scintilla\" / \"scripts\"))\n\nfrom FileGenerator import Regenerate, UpdateLineInFile, \\\n    ReplaceREInFile, UpdateLineInPlistFile, UpdateFileFromLines\nimport LexillaData\nimport LexFacer\n\nsys.path.append(str(thisPath.parent.parent / \"src\"))\nimport DepGen\n\n# RegenerateXcodeProject and associated functions are copied from scintilla/scripts/LexGen.py\n\ndef uid24():\n    \"\"\" Last 24 digits of UUID, used for item IDs in Xcode. \"\"\"\n    return str(uuid.uuid4()).replace(\"-\", \"\").upper()[-24:]\n\ndef ciLexerKey(a):\n    \"\"\" Return 3rd element of string lowered to be used when sorting. \"\"\"\n    return a.split()[2].lower()\n\n\n\"\"\"\n\t\t11F35FDB12AEFAF100F0236D /* LexA68k.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */; };\n\t\t11F35FDA12AEFAF100F0236D /* LexA68k.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexA68k.cxx; path = ../../lexers/LexA68k.cxx; sourceTree = SOURCE_ROOT; };\n\t\t\t\t11F35FDA12AEFAF100F0236D /* LexA68k.cxx */,\n\t\t\t\t11F35FDB12AEFAF100F0236D /* LexA68k.cxx in Sources */,\n\"\"\"\ndef RegenerateXcodeProject(path, lexers, lexerReferences):\n    \"\"\" Regenerate project to include any new lexers. \"\"\"\n    # Build 4 blocks for insertion:\n    # Each markers contains a unique section start, an optional wait string, and a section end\n\n    markersPBXBuildFile = [\"Begin PBXBuildFile section\", \"\", \"End PBXBuildFile section\"]\n    sectionPBXBuildFile = []\n\n    markersPBXFileReference = [\"Begin PBXFileReference section\", \"\", \"End PBXFileReference section\"]\n    sectionPBXFileReference = []\n\n    markersLexers = [\"/* Lexers */ =\", \"children\", \");\"]\n    sectionLexers = []\n\n    markersPBXSourcesBuildPhase = [\"Begin PBXSourcesBuildPhase section\", \"files\", \");\"]\n    sectionPBXSourcesBuildPhase = []\n\n    for lexer in lexers:\n        if lexer not in lexerReferences:\n            uid1 = uid24()\n            uid2 = uid24()\n            print(\"Lexer\", lexer, \"is not in Xcode project. Use IDs\", uid1, uid2)\n            lexerReferences[lexer] = [uid1, uid2]\n            linePBXBuildFile = f\"\\t\\t{uid1} /* {lexer}.cxx in Sources */ = {{isa = PBXBuildFile; fileRef = {uid2} /* {lexer}.cxx */; }};\"\n            linePBXFileReference = f\"\\t\\t{uid2} /* {lexer}.cxx */ = {{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = {lexer}.cxx; path = ../../lexers/{lexer}.cxx; sourceTree = SOURCE_ROOT; }};\"\n            lineLexers = f\"\\t\\t\\t\\t{uid2} /* {lexer}.cxx */,\"\n            linePBXSourcesBuildPhase = f\"\\t\\t\\t\\t{uid1} /* {lexer}.cxx in Sources */,\"\n            sectionPBXBuildFile.append(linePBXBuildFile)\n            sectionPBXFileReference.append(linePBXFileReference)\n            sectionLexers.append(lineLexers)\n            sectionPBXSourcesBuildPhase.append(linePBXSourcesBuildPhase)\n\n    lines = LexillaData.ReadFileAsList(path)\n\n    sli = LexillaData.FindSectionInList(lines, markersPBXBuildFile)\n    lines[sli.stop:sli.stop] = sectionPBXBuildFile\n\n    sli = LexillaData.FindSectionInList(lines, markersPBXFileReference)\n    lines[sli.stop:sli.stop] = sectionPBXFileReference\n\n    sli = LexillaData.FindSectionInList(lines, markersLexers)\n    # This section is shown in the project outline so sort it to make it easier to navigate.\n    allLexers = sorted(lines[sli.start:sli.stop] + sectionLexers, key=ciLexerKey)\n    lines[sli] = allLexers\n\n    sli = LexillaData.FindSectionInList(lines, markersPBXSourcesBuildPhase)\n    lines[sli.stop:sli.stop] = sectionPBXSourcesBuildPhase\n\n    UpdateFileFromLines(path, lines, os.linesep)\n\ndef RegenerateAll(rootDirectory):\n    \"\"\" Regenerate all the files. \"\"\"\n\n    root = pathlib.Path(rootDirectory)\n\n    lexillaBase = root.resolve()\n\n    lex = LexillaData.LexillaData(lexillaBase)\n\n    lexillaDir = lexillaBase\n    srcDir = lexillaDir / \"src\"\n    docDir = lexillaDir / \"doc\"\n\n    Regenerate(srcDir / \"Lexilla.cxx\", \"//\", lex.lexerModules)\n    Regenerate(srcDir / \"lexilla.mak\", \"#\", lex.lexFiles)\n\n    # Discover version information\n    version = (lexillaDir / \"version.txt\").read_text().strip()\n    versionDotted = version[0:-2] + '.' + version[-2] + '.' + version[-1]\n    versionCommad = versionDotted.replace(\".\", \", \") + ', 0'\n\n    rcPath = srcDir / \"LexillaVersion.rc\"\n    UpdateLineInFile(rcPath, \"#define VERSION_LEXILLA\",\n        \"#define VERSION_LEXILLA \\\"\" + versionDotted + \"\\\"\")\n    UpdateLineInFile(rcPath, \"#define VERSION_WORDS\",\n        \"#define VERSION_WORDS \" + versionCommad)\n    UpdateLineInFile(docDir / \"LexillaDownload.html\", \"       Release\",\n        \"       Release \" + versionDotted)\n    ReplaceREInFile(docDir / \"LexillaDownload.html\",\n        r\"/www.scintilla.org/([a-zA-Z]+)\\d{3,5}\",\n        r\"/www.scintilla.org/\\g<1>\" +  version,\n        0)\n\n    pathMain = lexillaDir / \"doc\" / \"Lexilla.html\"\n    UpdateLineInFile(pathMain,\n        '          <font color=\"#FFCC99\" size=\"3\">Release version',\n        '          <font color=\"#FFCC99\" size=\"3\">Release version ' + \\\n        versionDotted + '<br />')\n    UpdateLineInFile(pathMain,\n        '           Site last modified',\n        '           Site last modified ' + lex.mdyModified + '</font>')\n    UpdateLineInFile(pathMain,\n        '    <meta name=\"Date.Modified\"',\n        '    <meta name=\"Date.Modified\" content=\"' + lex.dateModified + '\" />')\n    UpdateLineInFile(lexillaDir / \"doc\" / \"LexillaHistory.html\",\n        '\tReleased ',\n        '\tReleased ' + lex.dmyModified + '.')\n\n    lexillaXcode = lexillaDir / \"src\" / \"Lexilla\"\n    lexillaXcodeProject = lexillaXcode / \"Lexilla.xcodeproj\" / \"project.pbxproj\"\n\n    lexerReferences = LexillaData.FindLexersInXcode(lexillaXcodeProject)\n\n    UpdateLineInPlistFile(lexillaXcode / \"Info.plist\",\n        \"CFBundleShortVersionString\", versionDotted)\n\n    ReplaceREInFile(lexillaXcodeProject, \"CURRENT_PROJECT_VERSION = [0-9.]+;\",\n        f'CURRENT_PROJECT_VERSION = {versionDotted};',\n        0)\n\n    RegenerateXcodeProject(lexillaXcodeProject, lex.lexFiles, lexerReferences)\n\n    LexFacer.RegenerateAll(root, False)\n\n    currentDirectory = pathlib.Path.cwd()\n    os.chdir(srcDir)\n    DepGen.Generate()\n    os.chdir(currentDirectory)\n\nif __name__==\"__main__\":\n    RegenerateAll(pathlib.Path(__file__).resolve().parent.parent)\n"
  },
  {
    "path": "scripts/LexillaLogo.py",
    "content": "﻿# LexillaLogo.py\n# Requires Python 3.6.\n# Requires Pillow https://python-pillow.org/, tested with 7.2.0 on Windows 10\n\nimport random\nfrom PIL import Image, ImageDraw, ImageFont\n\ncolours = [\n(136,0,21,255),\n(237,28,36,255),\n(255,127,39,255),\n(255,201,14,255),\n(185,122,87,255),\n(255,174,201,255),\n(181,230,29,255),\n(34,177,76,255),\n(153,217,234,255),\n(0,162,232,255),\n(112,146,190,255),\n(63,72,204,255),\n(200,191,231,255),\n]\n\nwidth = 1280\nheight = 150\n\ndef drawLines(dr):\n\tfor y in range(0,height, 2):\n\t\tx = 0\n\t\twhile x < width:\n\t\t\t#lexeme = random.randint(2, 20)\n\t\t\tlexeme = int(random.expovariate(0.3))\n\t\t\tcolour = random.choice(colours)\n\t\t\tstrokeRectangle = (x, y, x+lexeme, y)\n\t\t\tdr.rectangle(strokeRectangle, fill=colour)\n\t\t\tx += lexeme + 3\n\ndef drawGuide(dr):\n\tfor y in range(0,height, 2):\n\t\tx = 0\n\t\twhile x < width:\n\t\t\tlexeme = int(random.expovariate(0.3))\n\t\t\tcolour = (0x30, 0x30, 0x30)\n\t\t\tstrokeRectangle = (x, y, x+lexeme, y)\n\t\t\tdr.rectangle(strokeRectangle, fill=colour)\n\t\t\tx += lexeme + 3\n\ndef drawLogo():\n\t# Ensure same image each time\n\trandom.seed(1)\n\n\t# Georgia bold italic\n\tfont = ImageFont.truetype(font=\"georgiaz.ttf\", size=190)\n\n\timageMask = Image.new(\"L\", (width, height), color=(0xff))\n\tdrMask = ImageDraw.Draw(imageMask)\n\tdrMask.text((30, -29), \"Lexilla\", font=font, fill=(0))\n\n\timageBack = Image.new(\"RGB\", (width, height), color=(0,0,0))\n\tdrBack = ImageDraw.Draw(imageBack)\n\tdrawGuide(drBack)\n\n\timageLines = Image.new(\"RGB\", (width, height), color=(0,0,0))\n\tdr = ImageDraw.Draw(imageLines)\n\tdrawLines(dr)\n\n\timageOut = Image.composite(imageBack, imageLines, imageMask)\n\n\timageOut.save(\"../doc/LexillaLogo.png\", \"png\")\n\n\timageDoubled = imageOut.resize((width*2, height * 2), Image.NEAREST)\n\n\timageDoubled.save(\"../doc/LexillaLogo2x.png\", \"png\")\n\ndrawLogo()\n"
  },
  {
    "path": "scripts/PromoteNew.bat",
    "content": "@echo off\nrem Promote new result files.\nrem Find all the *.new files under test\\examples and copy them to their expected name without \".new\".\nrem Run after RunTest.bat if \".new\" result files are correct.\npushd ..\\test\\examples\nfor /R %%f in (*.new) do (call :moveFile %%f)\npopd\ngoto :eof\n\n:moveFile\nset pathWithNew=%1\nset directory=%~dp1\nset fileWithNew=%~nx1\nset fileNoNew=%~n1\nset pathNoNew=%pathWithNew:~0,-4%\n\nif exist %pathNoNew% (\n   echo Move %fileWithNew% to %fileNoNew% in %directory%\n) else (\n   echo New %fileWithNew% to %fileNoNew% in %directory%\n)\nmove %pathWithNew% %pathNoNew%\ngoto :eof\n"
  },
  {
    "path": "scripts/RunTest.bat",
    "content": "rem Test lexers\nrem build lexilla.dll and TestLexers.exe then run TestLexers.exe\ncd ../src\nmake --jobs=%NUMBER_OF_PROCESSORS% DEBUG=1\ncd ../test\nmake DEBUG=1\nmake test\n"
  },
  {
    "path": "scripts/RunTest.sh",
    "content": "# Test lexers\n# build lexilla.so and TestLexers then run TestLexers\nJOBS=\"--jobs=$(getconf _NPROCESSORS_ONLN)\"\n(\ncd ../src\nmake \"$JOBS\" DEBUG=1\n)\n(\ncd ../test\nmake DEBUG=1\nmake test\n)\n"
  },
  {
    "path": "src/DepGen.py",
    "content": "#!/usr/bin/env python3\n# DepGen.py - produce a make dependencies file for Scintilla\n# Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n# The License.txt file describes the conditions under which this software may be distributed.\n# Requires Python 3.6 or later\n\nimport os, sys\n\nscintilla = os.path.join(\"..\", \"..\", \"scintilla\")\nsys.path.append(scintilla)\n\nfrom scripts import Dependencies\n\ntopComment = \"# Created by DepGen.py. To recreate, run DepGen.py.\\n\"\n\ndef Generate():\n\tlexilla = os.path.join(\"..\")\n\tsources = [\n\t\tos.path.join(lexilla, \"src\", \"Lexilla.cxx\"),\n\t\tos.path.join(lexilla, \"lexlib\", \"*.cxx\"),\n\t\tos.path.join(lexilla, \"lexers\", \"*.cxx\")]\n\tincludes = [\n\t\tos.path.join(lexilla, \"include\"),\n\t\tos.path.join(scintilla, \"include\"),\n\t\tos.path.join(lexilla, \"lexlib\")]\n\n\t# Create the dependencies file for g++\n\tdeps = Dependencies.FindDependencies(sources,  includes, \".o\", \"../lexilla/\")\n\n\t# Place the objects in $(DIR_O)\n\tdeps = [[\"$(DIR_O)/\"+obj, headers] for obj, headers in deps]\n\n\tDependencies.UpdateDependencies(os.path.join(lexilla, \"src\", \"deps.mak\"), deps, topComment)\n\n\t# Create the dependencies file for MSVC\n\n\t# Place the objects in $(DIR_O) and change extension from \".o\" to \".obj\"\n\tdeps = [[\"$(DIR_O)/\"+Dependencies.PathStem(obj)+\".obj\", headers] for obj, headers in deps]\n\n\tDependencies.UpdateDependencies(os.path.join(lexilla, \"src\", \"nmdeps.mak\"), deps, topComment)\n\nif __name__ == \"__main__\":\n\tGenerate()"
  },
  {
    "path": "src/Lexilla/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>5.4.9</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(CURRENT_PROJECT_VERSION)</string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string>Copyright © 2020 Neil Hodgson. All rights reserved.</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/Lexilla/Lexilla.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t00D544CC992062D2E3CD4BF6 /* LexGDScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = A383409E9A994F461550FEC1 /* LexGDScript.cxx */; };\n\t\t283639BC268FD4EA009D58A1 /* LexAccessor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 283639BB268FD4EA009D58A1 /* LexAccessor.cxx */; };\n\t\t283A17AE2B47E61100DF5C82 /* InList.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 283A17AC2B47E61100DF5C82 /* InList.cxx */; };\n\t\t283A17AF2B47E61100DF5C82 /* InList.h in Headers */ = {isa = PBXBuildFile; fileRef = 283A17AD2B47E61100DF5C82 /* InList.h */; };\n\t\t28BA72AB24E34D5B00272C2D /* LexerBase.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA728F24E34D5A00272C2D /* LexerBase.cxx */; };\n\t\t28BA72AC24E34D5B00272C2D /* LexAccessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA729024E34D5A00272C2D /* LexAccessor.h */; };\n\t\t28BA72AD24E34D5B00272C2D /* DefaultLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA729124E34D5A00272C2D /* DefaultLexer.h */; };\n\t\t28BA72AE24E34D5B00272C2D /* SubStyles.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA729224E34D5A00272C2D /* SubStyles.h */; };\n\t\t28BA72B024E34D5B00272C2D /* LexerModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA729424E34D5A00272C2D /* LexerModule.h */; };\n\t\t28BA72B124E34D5B00272C2D /* CharacterCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA729524E34D5A00272C2D /* CharacterCategory.cxx */; };\n\t\t28BA72B224E34D5B00272C2D /* LexerSimple.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA729624E34D5A00272C2D /* LexerSimple.h */; };\n\t\t28BA72B324E34D5B00272C2D /* Accessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA729724E34D5A00272C2D /* Accessor.h */; };\n\t\t28BA72B424E34D5B00272C2D /* PropSetSimple.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA729824E34D5A00272C2D /* PropSetSimple.cxx */; };\n\t\t28BA72B524E34D5B00272C2D /* CharacterSet.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA729924E34D5A00272C2D /* CharacterSet.cxx */; };\n\t\t28BA72B624E34D5B00272C2D /* SparseState.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA729A24E34D5A00272C2D /* SparseState.h */; };\n\t\t28BA72B724E34D5B00272C2D /* WordList.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA729B24E34D5A00272C2D /* WordList.h */; };\n\t\t28BA72B824E34D5B00272C2D /* DefaultLexer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA729C24E34D5A00272C2D /* DefaultLexer.cxx */; };\n\t\t28BA72BA24E34D5B00272C2D /* WordList.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA729E24E34D5A00272C2D /* WordList.cxx */; };\n\t\t28BA72BB24E34D5B00272C2D /* OptionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA729F24E34D5A00272C2D /* OptionSet.h */; };\n\t\t28BA72BC24E34D5B00272C2D /* CatalogueModules.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA72A024E34D5B00272C2D /* CatalogueModules.h */; };\n\t\t28BA72BD24E34D5B00272C2D /* CharacterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA72A124E34D5B00272C2D /* CharacterSet.h */; };\n\t\t28BA72BE24E34D5B00272C2D /* StyleContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA72A224E34D5B00272C2D /* StyleContext.h */; };\n\t\t28BA72BF24E34D5B00272C2D /* PropSetSimple.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA72A324E34D5B00272C2D /* PropSetSimple.h */; };\n\t\t28BA72C024E34D5B00272C2D /* StringCopy.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA72A424E34D5B00272C2D /* StringCopy.h */; };\n\t\t28BA72C124E34D5B00272C2D /* LexerModule.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72A524E34D5B00272C2D /* LexerModule.cxx */; };\n\t\t28BA72C224E34D5B00272C2D /* LexerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA72A624E34D5B00272C2D /* LexerBase.h */; };\n\t\t28BA72C324E34D5B00272C2D /* LexerSimple.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72A724E34D5B00272C2D /* LexerSimple.cxx */; };\n\t\t28BA72C424E34D5B00272C2D /* StyleContext.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72A824E34D5B00272C2D /* StyleContext.cxx */; };\n\t\t28BA72C524E34D5B00272C2D /* CharacterCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA72A924E34D5B00272C2D /* CharacterCategory.h */; };\n\t\t28BA72C624E34D5B00272C2D /* Accessor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72AA24E34D5B00272C2D /* Accessor.cxx */; };\n\t\t28BA733924E34D9700272C2D /* LexBasic.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72C724E34D9100272C2D /* LexBasic.cxx */; };\n\t\t28BA733A24E34D9700272C2D /* LexCIL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72C824E34D9100272C2D /* LexCIL.cxx */; };\n\t\t28BA733B24E34D9700272C2D /* LexTCL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72C924E34D9100272C2D /* LexTCL.cxx */; };\n\t\t28BA733C24E34D9700272C2D /* LexMetapost.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72CA24E34D9100272C2D /* LexMetapost.cxx */; };\n\t\t28BA733D24E34D9700272C2D /* LexForth.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72CB24E34D9100272C2D /* LexForth.cxx */; };\n\t\t28BA733E24E34D9700272C2D /* LexSML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72CC24E34D9100272C2D /* LexSML.cxx */; };\n\t\t28BA733F24E34D9700272C2D /* LexOScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72CD24E34D9100272C2D /* LexOScript.cxx */; };\n\t\t28BA734024E34D9700272C2D /* LexTACL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72CE24E34D9100272C2D /* LexTACL.cxx */; };\n\t\t28BA734124E34D9700272C2D /* LexGui4Cli.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72CF24E34D9100272C2D /* LexGui4Cli.cxx */; };\n\t\t28BA734224E34D9700272C2D /* LexCLW.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D024E34D9200272C2D /* LexCLW.cxx */; };\n\t\t28BA734324E34D9700272C2D /* LexRebol.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D124E34D9200272C2D /* LexRebol.cxx */; };\n\t\t28BA734424E34D9700272C2D /* LexSAS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D224E34D9200272C2D /* LexSAS.cxx */; };\n\t\t28BA734524E34D9700272C2D /* LexNim.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D324E34D9200272C2D /* LexNim.cxx */; };\n\t\t28BA734624E34D9700272C2D /* LexSmalltalk.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D424E34D9200272C2D /* LexSmalltalk.cxx */; };\n\t\t28BA734724E34D9700272C2D /* LexModula.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D524E34D9200272C2D /* LexModula.cxx */; };\n\t\t28BA734824E34D9700272C2D /* LexBullant.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D624E34D9200272C2D /* LexBullant.cxx */; };\n\t\t28BA734924E34D9700272C2D /* LexASY.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D724E34D9200272C2D /* LexASY.cxx */; };\n\t\t28BA734A24E34D9700272C2D /* LexBash.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D824E34D9200272C2D /* LexBash.cxx */; };\n\t\t28BA734B24E34D9700272C2D /* LexEiffel.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72D924E34D9200272C2D /* LexEiffel.cxx */; };\n\t\t28BA734C24E34D9700272C2D /* LexVHDL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72DA24E34D9200272C2D /* LexVHDL.cxx */; };\n\t\t28BA734D24E34D9700272C2D /* LexAsn1.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72DB24E34D9200272C2D /* LexAsn1.cxx */; };\n\t\t28BA734E24E34D9700272C2D /* LexCoffeeScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72DC24E34D9200272C2D /* LexCoffeeScript.cxx */; };\n\t\t28BA734F24E34D9700272C2D /* LexDiff.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72DD24E34D9200272C2D /* LexDiff.cxx */; };\n\t\t28BA735024E34D9700272C2D /* LexSorcus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72DE24E34D9200272C2D /* LexSorcus.cxx */; };\n\t\t28BA735124E34D9700272C2D /* LexAPDL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72DF24E34D9200272C2D /* LexAPDL.cxx */; };\n\t\t28BA735224E34D9700272C2D /* LexD.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E024E34D9200272C2D /* LexD.cxx */; };\n\t\t28BA735324E34D9700272C2D /* LexMySQL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E124E34D9200272C2D /* LexMySQL.cxx */; };\n\t\t28BA735424E34D9700272C2D /* LexHollywood.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E224E34D9200272C2D /* LexHollywood.cxx */; };\n\t\t28BA735524E34D9700272C2D /* LexProgress.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E324E34D9200272C2D /* LexProgress.cxx */; };\n\t\t28BA735624E34D9700272C2D /* LexLisp.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E424E34D9200272C2D /* LexLisp.cxx */; };\n\t\t28BA735724E34D9700272C2D /* LexPowerShell.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E524E34D9200272C2D /* LexPowerShell.cxx */; };\n\t\t28BA735824E34D9700272C2D /* LexPS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E624E34D9200272C2D /* LexPS.cxx */; };\n\t\t28BA735924E34D9700272C2D /* LexYAML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E724E34D9200272C2D /* LexYAML.cxx */; };\n\t\t28BA735A24E34D9700272C2D /* LexErlang.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E824E34D9200272C2D /* LexErlang.cxx */; };\n\t\t28BA735B24E34D9700272C2D /* LexRuby.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72E924E34D9300272C2D /* LexRuby.cxx */; };\n\t\t28BA735C24E34D9700272C2D /* LexIndent.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72EA24E34D9300272C2D /* LexIndent.cxx */; };\n\t\t28BA735D24E34D9700272C2D /* LexErrorList.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72EB24E34D9300272C2D /* LexErrorList.cxx */; };\n\t\t28BA735E24E34D9700272C2D /* LexFlagship.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72EC24E34D9300272C2D /* LexFlagship.cxx */; };\n\t\t28BA735F24E34D9700272C2D /* LexLaTeX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72ED24E34D9300272C2D /* LexLaTeX.cxx */; };\n\t\t28BA736024E34D9700272C2D /* LexAbaqus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72EE24E34D9300272C2D /* LexAbaqus.cxx */; };\n\t\t28BA736124E34D9700272C2D /* LexBatch.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72EF24E34D9300272C2D /* LexBatch.cxx */; };\n\t\t28BA736224E34D9700272C2D /* LexCPP.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F024E34D9300272C2D /* LexCPP.cxx */; };\n\t\t28BA736324E34D9700272C2D /* LexRaku.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F124E34D9300272C2D /* LexRaku.cxx */; };\n\t\t28BA736424E34D9700272C2D /* LexGAP.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F224E34D9300272C2D /* LexGAP.cxx */; };\n\t\t28BA736524E34D9700272C2D /* LexSQL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F324E34D9300272C2D /* LexSQL.cxx */; };\n\t\t28BA736624E34D9700272C2D /* LexNsis.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F424E34D9300272C2D /* LexNsis.cxx */; };\n\t\t28BA736724E34D9700272C2D /* LexEDIFACT.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F524E34D9300272C2D /* LexEDIFACT.cxx */; };\n\t\t28BA736824E34D9700272C2D /* LexEScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F624E34D9300272C2D /* LexEScript.cxx */; };\n\t\t28BA736924E34D9700272C2D /* LexPOV.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F724E34D9300272C2D /* LexPOV.cxx */; };\n\t\t28BA736A24E34D9700272C2D /* LexKVIrc.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F824E34D9300272C2D /* LexKVIrc.cxx */; };\n\t\t28BA736B24E34D9700272C2D /* LexSpecman.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72F924E34D9300272C2D /* LexSpecman.cxx */; };\n\t\t28BA736C24E34D9700272C2D /* LexHTML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72FA24E34D9300272C2D /* LexHTML.cxx */; };\n\t\t28BA736D24E34D9700272C2D /* LexFortran.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72FB24E34D9400272C2D /* LexFortran.cxx */; };\n\t\t28BA736E24E34D9700272C2D /* LexRegistry.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72FC24E34D9400272C2D /* LexRegistry.cxx */; };\n\t\t28BA736F24E34D9700272C2D /* LexPython.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72FD24E34D9400272C2D /* LexPython.cxx */; };\n\t\t28BA737024E34D9700272C2D /* LexCmake.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72FE24E34D9400272C2D /* LexCmake.cxx */; };\n\t\t28BA737124E34D9700272C2D /* LexAsm.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA72FF24E34D9400272C2D /* LexAsm.cxx */; };\n\t\t28BA737224E34D9700272C2D /* LexAda.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730024E34D9400272C2D /* LexAda.cxx */; };\n\t\t28BA737324E34D9700272C2D /* LexCrontab.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730124E34D9400272C2D /* LexCrontab.cxx */; };\n\t\t28BA737424E34D9700272C2D /* LexDMIS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730224E34D9400272C2D /* LexDMIS.cxx */; };\n\t\t28BA737524E34D9700272C2D /* LexTCMD.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730324E34D9400272C2D /* LexTCMD.cxx */; };\n\t\t28BA737624E34D9700272C2D /* LexConf.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730424E34D9400272C2D /* LexConf.cxx */; };\n\t\t28BA737724E34D9700272C2D /* LexInno.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730524E34D9400272C2D /* LexInno.cxx */; };\n\t\t28BA737824E34D9700272C2D /* LexA68k.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730624E34D9400272C2D /* LexA68k.cxx */; };\n\t\t28BA737924E34D9700272C2D /* LexMake.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730724E34D9400272C2D /* LexMake.cxx */; };\n\t\t28BA737A24E34D9700272C2D /* LexTeX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730824E34D9400272C2D /* LexTeX.cxx */; };\n\t\t28BA737B24E34D9700272C2D /* LexSpice.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730924E34D9400272C2D /* LexSpice.cxx */; };\n\t\t28BA737C24E34D9700272C2D /* LexX12.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730A24E34D9400272C2D /* LexX12.cxx */; };\n\t\t28BA737D24E34D9700272C2D /* LexAU3.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730B24E34D9400272C2D /* LexAU3.cxx */; };\n\t\t28BA737E24E34D9700272C2D /* LexBaan.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730C24E34D9400272C2D /* LexBaan.cxx */; };\n\t\t28BA737F24E34D9700272C2D /* LexMPT.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730D24E34D9500272C2D /* LexMPT.cxx */; };\n\t\t28BA738024E34D9700272C2D /* LexTADS3.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730E24E34D9500272C2D /* LexTADS3.cxx */; };\n\t\t28BA738124E34D9700272C2D /* LexTxt2tags.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA730F24E34D9500272C2D /* LexTxt2tags.cxx */; };\n\t\t28BA738224E34D9700272C2D /* LexMMIXAL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731024E34D9500272C2D /* LexMMIXAL.cxx */; };\n\t\t28BA738324E34D9700272C2D /* LexKix.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731124E34D9500272C2D /* LexKix.cxx */; };\n\t\t28BA738424E34D9700272C2D /* LexSTTXT.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731224E34D9500272C2D /* LexSTTXT.cxx */; };\n\t\t28BA738524E34D9700272C2D /* LexMagik.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731324E34D9500272C2D /* LexMagik.cxx */; };\n\t\t28BA738624E34D9700272C2D /* LexNull.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731424E34D9500272C2D /* LexNull.cxx */; };\n\t\t28BA738724E34D9700272C2D /* LexCsound.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731524E34D9500272C2D /* LexCsound.cxx */; };\n\t\t28BA738824E34D9700272C2D /* LexLua.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731624E34D9500272C2D /* LexLua.cxx */; };\n\t\t28BA738924E34D9700272C2D /* LexStata.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731724E34D9500272C2D /* LexStata.cxx */; };\n\t\t28BA738A24E34D9700272C2D /* LexOpal.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731824E34D9500272C2D /* LexOpal.cxx */; };\n\t\t28BA738B24E34D9700272C2D /* LexHex.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731924E34D9500272C2D /* LexHex.cxx */; };\n\t\t28BA738C24E34D9700272C2D /* LexVerilog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731A24E34D9500272C2D /* LexVerilog.cxx */; };\n\t\t28BA738D24E34D9700272C2D /* LexHaskell.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731B24E34D9500272C2D /* LexHaskell.cxx */; };\n\t\t28BA738E24E34D9700272C2D /* LexR.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731C24E34D9500272C2D /* LexR.cxx */; };\n\t\t28BA738F24E34D9700272C2D /* LexScriptol.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731D24E34D9500272C2D /* LexScriptol.cxx */; };\n\t\t28BA739024E34D9700272C2D /* LexVisualProlog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731E24E34D9500272C2D /* LexVisualProlog.cxx */; };\n\t\t28BA739124E34D9700272C2D /* LexVB.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA731F24E34D9600272C2D /* LexVB.cxx */; };\n\t\t28BA739224E34D9700272C2D /* LexDMAP.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732024E34D9600272C2D /* LexDMAP.cxx */; };\n\t\t28BA739324E34D9700272C2D /* LexAVS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732124E34D9600272C2D /* LexAVS.cxx */; };\n\t\t28BA739424E34D9700272C2D /* LexPB.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732224E34D9600272C2D /* LexPB.cxx */; };\n\t\t28BA739524E34D9700272C2D /* LexPO.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732324E34D9600272C2D /* LexPO.cxx */; };\n\t\t28BA739624E34D9700272C2D /* LexPowerPro.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732424E34D9600272C2D /* LexPowerPro.cxx */; };\n\t\t28BA739724E34D9700272C2D /* LexProps.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732524E34D9600272C2D /* LexProps.cxx */; };\n\t\t28BA739824E34D9700272C2D /* LexCOBOL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732624E34D9600272C2D /* LexCOBOL.cxx */; };\n\t\t28BA739924E34D9700272C2D /* LexPLM.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732724E34D9600272C2D /* LexPLM.cxx */; };\n\t\t28BA739A24E34D9700272C2D /* LexMSSQL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732824E34D9600272C2D /* LexMSSQL.cxx */; };\n\t\t28BA739B24E34D9700272C2D /* LexCSS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732924E34D9600272C2D /* LexCSS.cxx */; };\n\t\t28BA739C24E34D9700272C2D /* LexMaxima.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732A24E34D9600272C2D /* LexMaxima.cxx */; };\n\t\t28BA739D24E34D9700272C2D /* LexCaml.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732B24E34D9600272C2D /* LexCaml.cxx */; };\n\t\t28BA739E24E34D9700272C2D /* LexDataflex.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732C24E34D9600272C2D /* LexDataflex.cxx */; };\n\t\t28BA739F24E34D9700272C2D /* LexLout.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732D24E34D9600272C2D /* LexLout.cxx */; };\n\t\t28BA73A024E34D9700272C2D /* LexTAL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732E24E34D9600272C2D /* LexTAL.cxx */; };\n\t\t28BA73A124E34D9700272C2D /* LexMarkdown.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA732F24E34D9600272C2D /* LexMarkdown.cxx */; };\n\t\t28BA73A224E34D9700272C2D /* LexJSON.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA733024E34D9600272C2D /* LexJSON.cxx */; };\n\t\t28BA73A324E34D9700272C2D /* LexPascal.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA733124E34D9700272C2D /* LexPascal.cxx */; };\n\t\t28BA73A424E34D9700272C2D /* LexAVE.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA733224E34D9700272C2D /* LexAVE.cxx */; };\n\t\t28BA73A524E34D9700272C2D /* LexECL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA733324E34D9700272C2D /* LexECL.cxx */; };\n\t\t28BA73A624E34D9700272C2D /* LexMatlab.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA733424E34D9700272C2D /* LexMatlab.cxx */; };\n\t\t28BA73A724E34D9700272C2D /* LexBibTeX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA733524E34D9700272C2D /* LexBibTeX.cxx */; };\n\t\t28BA73A824E34D9700272C2D /* LexNimrod.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA733624E34D9700272C2D /* LexNimrod.cxx */; };\n\t\t28BA73A924E34D9700272C2D /* LexPerl.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA733724E34D9700272C2D /* LexPerl.cxx */; };\n\t\t28BA73AA24E34D9700272C2D /* LexRust.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA733824E34D9700272C2D /* LexRust.cxx */; };\n\t\t28BA73AD24E34DBC00272C2D /* Lexilla.h in Headers */ = {isa = PBXBuildFile; fileRef = 28BA73AB24E34DBC00272C2D /* Lexilla.h */; };\n\t\t28BA73AE24E34DBC00272C2D /* Lexilla.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 28BA73AC24E34DBC00272C2D /* Lexilla.cxx */; };\n\t\t510D44AFB91EE873E86ABDD4 /* LexAsciidoc.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 3AF14420BFC43876F16C5995 /* LexAsciidoc.cxx */; };\n\t\t70BF497C8D265026B77C97DA /* LexJulia.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 315E4E969868C52C125686B2 /* LexJulia.cxx */; };\n\t\tB32D4A2A9CEC222A5140E99F /* LexFSharp.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8E54626B22BD9493090F40B /* LexFSharp.cxx */; };\n\t\t3D044C4CA34C6FD7E58E0091 /* LexTOML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 42BC44CCB57D4E78DEE6E358 /* LexTOML.cxx */; };\n\t\t14314DCD945FDA90481F0A0D /* LexTroff.cxx in Sources */ = {isa = PBXBuildFile; fileRef = D2EF4913B8F91656C787F584 /* LexTroff.cxx */; };\n\t\t0DFB4F5F94B018794ADB389D /* LexDart.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1F274010A7943C43BA265511 /* LexDart.cxx */; };\n\t\tCEC8496B8D9712E6EEDBC301 /* LexZig.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 71684CF6BCC80369BCE2F893 /* LexZig.cxx */; };\n\t\t4A444CF5A75E52E2C5537328 /* LexNix.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 81E2488CB0A0DC6B67AA08DD /* LexNix.cxx */; };\n\t\tFE5F4B168F37B523E4D1EFCD /* LexSINEX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 0D814275A1A8A9FA6D10447C /* LexSINEX.cxx */; };\n\t\tB049435FAED389EA7C61E3C1 /* LexEscSeq.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F523432FAB6C14A16F12ECE8 /* LexEscSeq.cxx */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t280262A5246DF655000DF3B8 /* liblexilla.dylib */ = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.dylib\"; includeInIndex = 0; path = liblexilla.dylib; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t283639BB268FD4EA009D58A1 /* LexAccessor.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAccessor.cxx; path = ../../lexlib/LexAccessor.cxx; sourceTree = \"<group>\"; };\n\t\t283A17AC2B47E61100DF5C82 /* InList.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InList.cxx; path = ../../lexlib/InList.cxx; sourceTree = \"<group>\"; };\n\t\t283A17AD2B47E61100DF5C82 /* InList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InList.h; path = ../../lexlib/InList.h; sourceTree = \"<group>\"; };\n\t\t28BA728F24E34D5A00272C2D /* LexerBase.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexerBase.cxx; path = ../../lexlib/LexerBase.cxx; sourceTree = \"<group>\"; };\n\t\t28BA729024E34D5A00272C2D /* LexAccessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LexAccessor.h; path = ../../lexlib/LexAccessor.h; sourceTree = \"<group>\"; };\n\t\t28BA729124E34D5A00272C2D /* DefaultLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DefaultLexer.h; path = ../../lexlib/DefaultLexer.h; sourceTree = \"<group>\"; };\n\t\t28BA729224E34D5A00272C2D /* SubStyles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SubStyles.h; path = ../../lexlib/SubStyles.h; sourceTree = \"<group>\"; };\n\t\t28BA729424E34D5A00272C2D /* LexerModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LexerModule.h; path = ../../lexlib/LexerModule.h; sourceTree = \"<group>\"; };\n\t\t28BA729524E34D5A00272C2D /* CharacterCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharacterCategory.cxx; path = ../../lexlib/CharacterCategory.cxx; sourceTree = \"<group>\"; };\n\t\t28BA729624E34D5A00272C2D /* LexerSimple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LexerSimple.h; path = ../../lexlib/LexerSimple.h; sourceTree = \"<group>\"; };\n\t\t28BA729724E34D5A00272C2D /* Accessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Accessor.h; path = ../../lexlib/Accessor.h; sourceTree = \"<group>\"; };\n\t\t28BA729824E34D5A00272C2D /* PropSetSimple.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PropSetSimple.cxx; path = ../../lexlib/PropSetSimple.cxx; sourceTree = \"<group>\"; };\n\t\t28BA729924E34D5A00272C2D /* CharacterSet.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharacterSet.cxx; path = ../../lexlib/CharacterSet.cxx; sourceTree = \"<group>\"; };\n\t\t28BA729A24E34D5A00272C2D /* SparseState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SparseState.h; path = ../../lexlib/SparseState.h; sourceTree = \"<group>\"; };\n\t\t28BA729B24E34D5A00272C2D /* WordList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WordList.h; path = ../../lexlib/WordList.h; sourceTree = \"<group>\"; };\n\t\t28BA729C24E34D5A00272C2D /* DefaultLexer.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DefaultLexer.cxx; path = ../../lexlib/DefaultLexer.cxx; sourceTree = \"<group>\"; };\n\t\t28BA729E24E34D5A00272C2D /* WordList.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WordList.cxx; path = ../../lexlib/WordList.cxx; sourceTree = \"<group>\"; };\n\t\t28BA729F24E34D5A00272C2D /* OptionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OptionSet.h; path = ../../lexlib/OptionSet.h; sourceTree = \"<group>\"; };\n\t\t28BA72A024E34D5B00272C2D /* CatalogueModules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CatalogueModules.h; path = ../../lexlib/CatalogueModules.h; sourceTree = \"<group>\"; };\n\t\t28BA72A124E34D5B00272C2D /* CharacterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CharacterSet.h; path = ../../lexlib/CharacterSet.h; sourceTree = \"<group>\"; };\n\t\t28BA72A224E34D5B00272C2D /* StyleContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StyleContext.h; path = ../../lexlib/StyleContext.h; sourceTree = \"<group>\"; };\n\t\t28BA72A324E34D5B00272C2D /* PropSetSimple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PropSetSimple.h; path = ../../lexlib/PropSetSimple.h; sourceTree = \"<group>\"; };\n\t\t28BA72A424E34D5B00272C2D /* StringCopy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringCopy.h; path = ../../lexlib/StringCopy.h; sourceTree = \"<group>\"; };\n\t\t28BA72A524E34D5B00272C2D /* LexerModule.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexerModule.cxx; path = ../../lexlib/LexerModule.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72A624E34D5B00272C2D /* LexerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LexerBase.h; path = ../../lexlib/LexerBase.h; sourceTree = \"<group>\"; };\n\t\t28BA72A724E34D5B00272C2D /* LexerSimple.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexerSimple.cxx; path = ../../lexlib/LexerSimple.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72A824E34D5B00272C2D /* StyleContext.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StyleContext.cxx; path = ../../lexlib/StyleContext.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72A924E34D5B00272C2D /* CharacterCategory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CharacterCategory.h; path = ../../lexlib/CharacterCategory.h; sourceTree = \"<group>\"; };\n\t\t28BA72AA24E34D5B00272C2D /* Accessor.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Accessor.cxx; path = ../../lexlib/Accessor.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72C724E34D9100272C2D /* LexBasic.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBasic.cxx; path = ../../lexers/LexBasic.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72C824E34D9100272C2D /* LexCIL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCIL.cxx; path = ../../lexers/LexCIL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72C924E34D9100272C2D /* LexTCL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTCL.cxx; path = ../../lexers/LexTCL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72CA24E34D9100272C2D /* LexMetapost.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMetapost.cxx; path = ../../lexers/LexMetapost.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72CB24E34D9100272C2D /* LexForth.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexForth.cxx; path = ../../lexers/LexForth.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72CC24E34D9100272C2D /* LexSML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSML.cxx; path = ../../lexers/LexSML.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72CD24E34D9100272C2D /* LexOScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexOScript.cxx; path = ../../lexers/LexOScript.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72CE24E34D9100272C2D /* LexTACL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTACL.cxx; path = ../../lexers/LexTACL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72CF24E34D9100272C2D /* LexGui4Cli.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexGui4Cli.cxx; path = ../../lexers/LexGui4Cli.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D024E34D9200272C2D /* LexCLW.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCLW.cxx; path = ../../lexers/LexCLW.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D124E34D9200272C2D /* LexRebol.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexRebol.cxx; path = ../../lexers/LexRebol.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D224E34D9200272C2D /* LexSAS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSAS.cxx; path = ../../lexers/LexSAS.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D324E34D9200272C2D /* LexNim.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNim.cxx; path = ../../lexers/LexNim.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D424E34D9200272C2D /* LexSmalltalk.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSmalltalk.cxx; path = ../../lexers/LexSmalltalk.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D524E34D9200272C2D /* LexModula.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexModula.cxx; path = ../../lexers/LexModula.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D624E34D9200272C2D /* LexBullant.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBullant.cxx; path = ../../lexers/LexBullant.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D724E34D9200272C2D /* LexASY.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexASY.cxx; path = ../../lexers/LexASY.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D824E34D9200272C2D /* LexBash.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBash.cxx; path = ../../lexers/LexBash.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72D924E34D9200272C2D /* LexEiffel.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexEiffel.cxx; path = ../../lexers/LexEiffel.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72DA24E34D9200272C2D /* LexVHDL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVHDL.cxx; path = ../../lexers/LexVHDL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72DB24E34D9200272C2D /* LexAsn1.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAsn1.cxx; path = ../../lexers/LexAsn1.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72DC24E34D9200272C2D /* LexCoffeeScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCoffeeScript.cxx; path = ../../lexers/LexCoffeeScript.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72DD24E34D9200272C2D /* LexDiff.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexDiff.cxx; path = ../../lexers/LexDiff.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72DE24E34D9200272C2D /* LexSorcus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSorcus.cxx; path = ../../lexers/LexSorcus.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72DF24E34D9200272C2D /* LexAPDL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAPDL.cxx; path = ../../lexers/LexAPDL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E024E34D9200272C2D /* LexD.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexD.cxx; path = ../../lexers/LexD.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E124E34D9200272C2D /* LexMySQL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMySQL.cxx; path = ../../lexers/LexMySQL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E224E34D9200272C2D /* LexHollywood.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexHollywood.cxx; path = ../../lexers/LexHollywood.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E324E34D9200272C2D /* LexProgress.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexProgress.cxx; path = ../../lexers/LexProgress.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E424E34D9200272C2D /* LexLisp.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLisp.cxx; path = ../../lexers/LexLisp.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E524E34D9200272C2D /* LexPowerShell.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPowerShell.cxx; path = ../../lexers/LexPowerShell.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E624E34D9200272C2D /* LexPS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPS.cxx; path = ../../lexers/LexPS.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E724E34D9200272C2D /* LexYAML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexYAML.cxx; path = ../../lexers/LexYAML.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E824E34D9200272C2D /* LexErlang.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexErlang.cxx; path = ../../lexers/LexErlang.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72E924E34D9300272C2D /* LexRuby.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexRuby.cxx; path = ../../lexers/LexRuby.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72EA24E34D9300272C2D /* LexIndent.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexIndent.cxx; path = ../../lexers/LexIndent.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72EB24E34D9300272C2D /* LexErrorList.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexErrorList.cxx; path = ../../lexers/LexErrorList.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72EC24E34D9300272C2D /* LexFlagship.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexFlagship.cxx; path = ../../lexers/LexFlagship.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72ED24E34D9300272C2D /* LexLaTeX.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLaTeX.cxx; path = ../../lexers/LexLaTeX.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72EE24E34D9300272C2D /* LexAbaqus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAbaqus.cxx; path = ../../lexers/LexAbaqus.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72EF24E34D9300272C2D /* LexBatch.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBatch.cxx; path = ../../lexers/LexBatch.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F024E34D9300272C2D /* LexCPP.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCPP.cxx; path = ../../lexers/LexCPP.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F124E34D9300272C2D /* LexRaku.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexRaku.cxx; path = ../../lexers/LexRaku.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F224E34D9300272C2D /* LexGAP.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexGAP.cxx; path = ../../lexers/LexGAP.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F324E34D9300272C2D /* LexSQL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSQL.cxx; path = ../../lexers/LexSQL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F424E34D9300272C2D /* LexNsis.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNsis.cxx; path = ../../lexers/LexNsis.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F524E34D9300272C2D /* LexEDIFACT.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexEDIFACT.cxx; path = ../../lexers/LexEDIFACT.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F624E34D9300272C2D /* LexEScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexEScript.cxx; path = ../../lexers/LexEScript.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F724E34D9300272C2D /* LexPOV.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPOV.cxx; path = ../../lexers/LexPOV.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F824E34D9300272C2D /* LexKVIrc.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexKVIrc.cxx; path = ../../lexers/LexKVIrc.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72F924E34D9300272C2D /* LexSpecman.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSpecman.cxx; path = ../../lexers/LexSpecman.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72FA24E34D9300272C2D /* LexHTML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexHTML.cxx; path = ../../lexers/LexHTML.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72FB24E34D9400272C2D /* LexFortran.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexFortran.cxx; path = ../../lexers/LexFortran.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72FC24E34D9400272C2D /* LexRegistry.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexRegistry.cxx; path = ../../lexers/LexRegistry.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72FD24E34D9400272C2D /* LexPython.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPython.cxx; path = ../../lexers/LexPython.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72FE24E34D9400272C2D /* LexCmake.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCmake.cxx; path = ../../lexers/LexCmake.cxx; sourceTree = \"<group>\"; };\n\t\t28BA72FF24E34D9400272C2D /* LexAsm.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAsm.cxx; path = ../../lexers/LexAsm.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730024E34D9400272C2D /* LexAda.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAda.cxx; path = ../../lexers/LexAda.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730124E34D9400272C2D /* LexCrontab.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCrontab.cxx; path = ../../lexers/LexCrontab.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730224E34D9400272C2D /* LexDMIS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexDMIS.cxx; path = ../../lexers/LexDMIS.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730324E34D9400272C2D /* LexTCMD.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTCMD.cxx; path = ../../lexers/LexTCMD.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730424E34D9400272C2D /* LexConf.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexConf.cxx; path = ../../lexers/LexConf.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730524E34D9400272C2D /* LexInno.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexInno.cxx; path = ../../lexers/LexInno.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730624E34D9400272C2D /* LexA68k.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexA68k.cxx; path = ../../lexers/LexA68k.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730724E34D9400272C2D /* LexMake.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMake.cxx; path = ../../lexers/LexMake.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730824E34D9400272C2D /* LexTeX.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTeX.cxx; path = ../../lexers/LexTeX.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730924E34D9400272C2D /* LexSpice.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSpice.cxx; path = ../../lexers/LexSpice.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730A24E34D9400272C2D /* LexX12.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexX12.cxx; path = ../../lexers/LexX12.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730B24E34D9400272C2D /* LexAU3.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAU3.cxx; path = ../../lexers/LexAU3.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730C24E34D9400272C2D /* LexBaan.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBaan.cxx; path = ../../lexers/LexBaan.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730D24E34D9500272C2D /* LexMPT.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMPT.cxx; path = ../../lexers/LexMPT.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730E24E34D9500272C2D /* LexTADS3.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTADS3.cxx; path = ../../lexers/LexTADS3.cxx; sourceTree = \"<group>\"; };\n\t\t28BA730F24E34D9500272C2D /* LexTxt2tags.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTxt2tags.cxx; path = ../../lexers/LexTxt2tags.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731024E34D9500272C2D /* LexMMIXAL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMMIXAL.cxx; path = ../../lexers/LexMMIXAL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731124E34D9500272C2D /* LexKix.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexKix.cxx; path = ../../lexers/LexKix.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731224E34D9500272C2D /* LexSTTXT.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSTTXT.cxx; path = ../../lexers/LexSTTXT.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731324E34D9500272C2D /* LexMagik.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMagik.cxx; path = ../../lexers/LexMagik.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731424E34D9500272C2D /* LexNull.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNull.cxx; path = ../../lexers/LexNull.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731524E34D9500272C2D /* LexCsound.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCsound.cxx; path = ../../lexers/LexCsound.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731624E34D9500272C2D /* LexLua.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLua.cxx; path = ../../lexers/LexLua.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731724E34D9500272C2D /* LexStata.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexStata.cxx; path = ../../lexers/LexStata.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731824E34D9500272C2D /* LexOpal.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexOpal.cxx; path = ../../lexers/LexOpal.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731924E34D9500272C2D /* LexHex.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexHex.cxx; path = ../../lexers/LexHex.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731A24E34D9500272C2D /* LexVerilog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVerilog.cxx; path = ../../lexers/LexVerilog.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731B24E34D9500272C2D /* LexHaskell.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexHaskell.cxx; path = ../../lexers/LexHaskell.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731C24E34D9500272C2D /* LexR.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexR.cxx; path = ../../lexers/LexR.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731D24E34D9500272C2D /* LexScriptol.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexScriptol.cxx; path = ../../lexers/LexScriptol.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731E24E34D9500272C2D /* LexVisualProlog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVisualProlog.cxx; path = ../../lexers/LexVisualProlog.cxx; sourceTree = \"<group>\"; };\n\t\t28BA731F24E34D9600272C2D /* LexVB.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVB.cxx; path = ../../lexers/LexVB.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732024E34D9600272C2D /* LexDMAP.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexDMAP.cxx; path = ../../lexers/LexDMAP.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732124E34D9600272C2D /* LexAVS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAVS.cxx; path = ../../lexers/LexAVS.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732224E34D9600272C2D /* LexPB.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPB.cxx; path = ../../lexers/LexPB.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732324E34D9600272C2D /* LexPO.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPO.cxx; path = ../../lexers/LexPO.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732424E34D9600272C2D /* LexPowerPro.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPowerPro.cxx; path = ../../lexers/LexPowerPro.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732524E34D9600272C2D /* LexProps.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexProps.cxx; path = ../../lexers/LexProps.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732624E34D9600272C2D /* LexCOBOL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCOBOL.cxx; path = ../../lexers/LexCOBOL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732724E34D9600272C2D /* LexPLM.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPLM.cxx; path = ../../lexers/LexPLM.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732824E34D9600272C2D /* LexMSSQL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMSSQL.cxx; path = ../../lexers/LexMSSQL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732924E34D9600272C2D /* LexCSS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCSS.cxx; path = ../../lexers/LexCSS.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732A24E34D9600272C2D /* LexMaxima.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMaxima.cxx; path = ../../lexers/LexMaxima.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732B24E34D9600272C2D /* LexCaml.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCaml.cxx; path = ../../lexers/LexCaml.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732C24E34D9600272C2D /* LexDataflex.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexDataflex.cxx; path = ../../lexers/LexDataflex.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732D24E34D9600272C2D /* LexLout.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLout.cxx; path = ../../lexers/LexLout.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732E24E34D9600272C2D /* LexTAL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTAL.cxx; path = ../../lexers/LexTAL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA732F24E34D9600272C2D /* LexMarkdown.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMarkdown.cxx; path = ../../lexers/LexMarkdown.cxx; sourceTree = \"<group>\"; };\n\t\t28BA733024E34D9600272C2D /* LexJSON.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexJSON.cxx; path = ../../lexers/LexJSON.cxx; sourceTree = \"<group>\"; };\n\t\t28BA733124E34D9700272C2D /* LexPascal.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPascal.cxx; path = ../../lexers/LexPascal.cxx; sourceTree = \"<group>\"; };\n\t\t28BA733224E34D9700272C2D /* LexAVE.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAVE.cxx; path = ../../lexers/LexAVE.cxx; sourceTree = \"<group>\"; };\n\t\t28BA733324E34D9700272C2D /* LexECL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexECL.cxx; path = ../../lexers/LexECL.cxx; sourceTree = \"<group>\"; };\n\t\t28BA733424E34D9700272C2D /* LexMatlab.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMatlab.cxx; path = ../../lexers/LexMatlab.cxx; sourceTree = \"<group>\"; };\n\t\t28BA733524E34D9700272C2D /* LexBibTeX.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBibTeX.cxx; path = ../../lexers/LexBibTeX.cxx; sourceTree = \"<group>\"; };\n\t\t28BA733624E34D9700272C2D /* LexNimrod.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNimrod.cxx; path = ../../lexers/LexNimrod.cxx; sourceTree = \"<group>\"; };\n\t\t28BA733724E34D9700272C2D /* LexPerl.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPerl.cxx; path = ../../lexers/LexPerl.cxx; sourceTree = \"<group>\"; };\n\t\t28BA733824E34D9700272C2D /* LexRust.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexRust.cxx; path = ../../lexers/LexRust.cxx; sourceTree = \"<group>\"; };\n\t\t28BA73AB24E34DBC00272C2D /* Lexilla.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Lexilla.h; path = ../../include/Lexilla.h; sourceTree = \"<group>\"; };\n\t\t28BA73AC24E34DBC00272C2D /* Lexilla.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Lexilla.cxx; path = ../Lexilla.cxx; sourceTree = \"<group>\"; };\n\t\t28BA73B024E3510900272C2D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t315E4E969868C52C125686B2 /* LexJulia.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexJulia.cxx; path = ../../lexers/LexJulia.cxx; sourceTree = SOURCE_ROOT; };\n\t\t3AF14420BFC43876F16C5995 /* LexAsciidoc.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAsciidoc.cxx; path = ../../lexers/LexAsciidoc.cxx; sourceTree = SOURCE_ROOT; };\n\t\tA383409E9A994F461550FEC1 /* LexGDScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexGDScript.cxx; path = ../../lexers/LexGDScript.cxx; sourceTree = SOURCE_ROOT; };\n\t\tF8E54626B22BD9493090F40B /* LexFSharp.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexFSharp.cxx; path = ../../lexers/LexFSharp.cxx; sourceTree = SOURCE_ROOT; };\n\t\t42BC44CCB57D4E78DEE6E358 /* LexTOML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTOML.cxx; path = ../../lexers/LexTOML.cxx; sourceTree = SOURCE_ROOT; };\n\t\tD2EF4913B8F91656C787F584 /* LexTroff.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTroff.cxx; path = ../../lexers/LexTroff.cxx; sourceTree = SOURCE_ROOT; };\n\t\t1F274010A7943C43BA265511 /* LexDart.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexDart.cxx; path = ../../lexers/LexDart.cxx; sourceTree = SOURCE_ROOT; };\n\t\t71684CF6BCC80369BCE2F893 /* LexZig.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexZig.cxx; path = ../../lexers/LexZig.cxx; sourceTree = SOURCE_ROOT; };\n\t\t81E2488CB0A0DC6B67AA08DD /* LexNix.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNix.cxx; path = ../../lexers/LexNix.cxx; sourceTree = SOURCE_ROOT; };\n\t\t0D814275A1A8A9FA6D10447C /* LexSINEX.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSINEX.cxx; path = ../../lexers/LexSINEX.cxx; sourceTree = SOURCE_ROOT; };\n\t\tF523432FAB6C14A16F12ECE8 /* LexEscSeq.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexEscSeq.cxx; path = ../../lexers/LexEscSeq.cxx; sourceTree = SOURCE_ROOT; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t280262A3246DF655000DF3B8 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t2802629C246DF655000DF3B8 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28BA73B024E3510900272C2D /* Info.plist */,\n\t\t\t\t280262B8246DF776000DF3B8 /* LexLib */,\n\t\t\t\t280262B7246DF765000DF3B8 /* Lexers */,\n\t\t\t\t280262A7246DF655000DF3B8 /* Lexilla */,\n\t\t\t\t280262A6246DF655000DF3B8 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t280262A6246DF655000DF3B8 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t280262A5246DF655000DF3B8 /* liblexilla.dylib */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t280262A7246DF655000DF3B8 /* Lexilla */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28BA73AC24E34DBC00272C2D /* Lexilla.cxx */,\n\t\t\t\t28BA73AB24E34DBC00272C2D /* Lexilla.h */,\n\t\t\t);\n\t\t\tname = Lexilla;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t280262B7246DF765000DF3B8 /* Lexers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28BA730624E34D9400272C2D /* LexA68k.cxx */,\n\t\t\t\t28BA72EE24E34D9300272C2D /* LexAbaqus.cxx */,\n\t\t\t\t28BA730024E34D9400272C2D /* LexAda.cxx */,\n\t\t\t\t28BA72DF24E34D9200272C2D /* LexAPDL.cxx */,\n\t\t\t\t3AF14420BFC43876F16C5995 /* LexAsciidoc.cxx */,\n\t\t\t\t28BA72FF24E34D9400272C2D /* LexAsm.cxx */,\n\t\t\t\t28BA72DB24E34D9200272C2D /* LexAsn1.cxx */,\n\t\t\t\t28BA72D724E34D9200272C2D /* LexASY.cxx */,\n\t\t\t\t28BA730B24E34D9400272C2D /* LexAU3.cxx */,\n\t\t\t\t28BA733224E34D9700272C2D /* LexAVE.cxx */,\n\t\t\t\t28BA732124E34D9600272C2D /* LexAVS.cxx */,\n\t\t\t\t28BA730C24E34D9400272C2D /* LexBaan.cxx */,\n\t\t\t\t28BA72D824E34D9200272C2D /* LexBash.cxx */,\n\t\t\t\t28BA72C724E34D9100272C2D /* LexBasic.cxx */,\n\t\t\t\t28BA72EF24E34D9300272C2D /* LexBatch.cxx */,\n\t\t\t\t28BA733524E34D9700272C2D /* LexBibTeX.cxx */,\n\t\t\t\t28BA72D624E34D9200272C2D /* LexBullant.cxx */,\n\t\t\t\t28BA732B24E34D9600272C2D /* LexCaml.cxx */,\n\t\t\t\t28BA72C824E34D9100272C2D /* LexCIL.cxx */,\n\t\t\t\t28BA72D024E34D9200272C2D /* LexCLW.cxx */,\n\t\t\t\t28BA72FE24E34D9400272C2D /* LexCmake.cxx */,\n\t\t\t\t28BA732624E34D9600272C2D /* LexCOBOL.cxx */,\n\t\t\t\t28BA72DC24E34D9200272C2D /* LexCoffeeScript.cxx */,\n\t\t\t\t28BA730424E34D9400272C2D /* LexConf.cxx */,\n\t\t\t\t28BA72F024E34D9300272C2D /* LexCPP.cxx */,\n\t\t\t\t28BA730124E34D9400272C2D /* LexCrontab.cxx */,\n\t\t\t\t28BA731524E34D9500272C2D /* LexCsound.cxx */,\n\t\t\t\t28BA732924E34D9600272C2D /* LexCSS.cxx */,\n\t\t\t\t28BA72E024E34D9200272C2D /* LexD.cxx */,\n\t\t\t\t1F274010A7943C43BA265511 /* LexDart.cxx */,\n\t\t\t\t28BA732C24E34D9600272C2D /* LexDataflex.cxx */,\n\t\t\t\t28BA72DD24E34D9200272C2D /* LexDiff.cxx */,\n\t\t\t\t28BA732024E34D9600272C2D /* LexDMAP.cxx */,\n\t\t\t\t28BA730224E34D9400272C2D /* LexDMIS.cxx */,\n\t\t\t\t28BA733324E34D9700272C2D /* LexECL.cxx */,\n\t\t\t\t28BA72F524E34D9300272C2D /* LexEDIFACT.cxx */,\n\t\t\t\t28BA72D924E34D9200272C2D /* LexEiffel.cxx */,\n\t\t\t\t28BA72E824E34D9200272C2D /* LexErlang.cxx */,\n\t\t\t\t28BA72EB24E34D9300272C2D /* LexErrorList.cxx */,\n\t\t\t\t28BA72F624E34D9300272C2D /* LexEScript.cxx */,\n\t\t\t\tF523432FAB6C14A16F12ECE8 /* LexEscSeq.cxx */,\n\t\t\t\t28BA72EC24E34D9300272C2D /* LexFlagship.cxx */,\n\t\t\t\t28BA72CB24E34D9100272C2D /* LexForth.cxx */,\n\t\t\t\t28BA72FB24E34D9400272C2D /* LexFortran.cxx */,\n\t\t\t\tF8E54626B22BD9493090F40B /* LexFSharp.cxx */,\n\t\t\t\t28BA72F224E34D9300272C2D /* LexGAP.cxx */,\n\t\t\t\tA383409E9A994F461550FEC1 /* LexGDScript.cxx */,\n\t\t\t\t28BA72CF24E34D9100272C2D /* LexGui4Cli.cxx */,\n\t\t\t\t28BA731B24E34D9500272C2D /* LexHaskell.cxx */,\n\t\t\t\t28BA731924E34D9500272C2D /* LexHex.cxx */,\n\t\t\t\t28BA72E224E34D9200272C2D /* LexHollywood.cxx */,\n\t\t\t\t28BA72FA24E34D9300272C2D /* LexHTML.cxx */,\n\t\t\t\t28BA72EA24E34D9300272C2D /* LexIndent.cxx */,\n\t\t\t\t28BA730524E34D9400272C2D /* LexInno.cxx */,\n\t\t\t\t28BA733024E34D9600272C2D /* LexJSON.cxx */,\n\t\t\t\t315E4E969868C52C125686B2 /* LexJulia.cxx */,\n\t\t\t\t28BA731124E34D9500272C2D /* LexKix.cxx */,\n\t\t\t\t28BA72F824E34D9300272C2D /* LexKVIrc.cxx */,\n\t\t\t\t28BA72ED24E34D9300272C2D /* LexLaTeX.cxx */,\n\t\t\t\t28BA72E424E34D9200272C2D /* LexLisp.cxx */,\n\t\t\t\t28BA732D24E34D9600272C2D /* LexLout.cxx */,\n\t\t\t\t28BA731624E34D9500272C2D /* LexLua.cxx */,\n\t\t\t\t28BA731324E34D9500272C2D /* LexMagik.cxx */,\n\t\t\t\t28BA730724E34D9400272C2D /* LexMake.cxx */,\n\t\t\t\t28BA732F24E34D9600272C2D /* LexMarkdown.cxx */,\n\t\t\t\t28BA733424E34D9700272C2D /* LexMatlab.cxx */,\n\t\t\t\t28BA732A24E34D9600272C2D /* LexMaxima.cxx */,\n\t\t\t\t28BA72CA24E34D9100272C2D /* LexMetapost.cxx */,\n\t\t\t\t28BA731024E34D9500272C2D /* LexMMIXAL.cxx */,\n\t\t\t\t28BA72D524E34D9200272C2D /* LexModula.cxx */,\n\t\t\t\t28BA730D24E34D9500272C2D /* LexMPT.cxx */,\n\t\t\t\t28BA732824E34D9600272C2D /* LexMSSQL.cxx */,\n\t\t\t\t28BA72E124E34D9200272C2D /* LexMySQL.cxx */,\n\t\t\t\t28BA72D324E34D9200272C2D /* LexNim.cxx */,\n\t\t\t\t28BA733624E34D9700272C2D /* LexNimrod.cxx */,\n\t\t\t\t81E2488CB0A0DC6B67AA08DD /* LexNix.cxx */,\n\t\t\t\t28BA72F424E34D9300272C2D /* LexNsis.cxx */,\n\t\t\t\t28BA731424E34D9500272C2D /* LexNull.cxx */,\n\t\t\t\t28BA731824E34D9500272C2D /* LexOpal.cxx */,\n\t\t\t\t28BA72CD24E34D9100272C2D /* LexOScript.cxx */,\n\t\t\t\t28BA733124E34D9700272C2D /* LexPascal.cxx */,\n\t\t\t\t28BA732224E34D9600272C2D /* LexPB.cxx */,\n\t\t\t\t28BA733724E34D9700272C2D /* LexPerl.cxx */,\n\t\t\t\t28BA732724E34D9600272C2D /* LexPLM.cxx */,\n\t\t\t\t28BA732324E34D9600272C2D /* LexPO.cxx */,\n\t\t\t\t28BA72F724E34D9300272C2D /* LexPOV.cxx */,\n\t\t\t\t28BA732424E34D9600272C2D /* LexPowerPro.cxx */,\n\t\t\t\t28BA72E524E34D9200272C2D /* LexPowerShell.cxx */,\n\t\t\t\t28BA72E324E34D9200272C2D /* LexProgress.cxx */,\n\t\t\t\t28BA732524E34D9600272C2D /* LexProps.cxx */,\n\t\t\t\t28BA72E624E34D9200272C2D /* LexPS.cxx */,\n\t\t\t\t28BA72FD24E34D9400272C2D /* LexPython.cxx */,\n\t\t\t\t28BA731C24E34D9500272C2D /* LexR.cxx */,\n\t\t\t\t28BA72F124E34D9300272C2D /* LexRaku.cxx */,\n\t\t\t\t28BA72D124E34D9200272C2D /* LexRebol.cxx */,\n\t\t\t\t28BA72FC24E34D9400272C2D /* LexRegistry.cxx */,\n\t\t\t\t28BA72E924E34D9300272C2D /* LexRuby.cxx */,\n\t\t\t\t28BA733824E34D9700272C2D /* LexRust.cxx */,\n\t\t\t\t28BA72D224E34D9200272C2D /* LexSAS.cxx */,\n\t\t\t\t28BA731D24E34D9500272C2D /* LexScriptol.cxx */,\n\t\t\t\t0D814275A1A8A9FA6D10447C /* LexSINEX.cxx */,\n\t\t\t\t28BA72D424E34D9200272C2D /* LexSmalltalk.cxx */,\n\t\t\t\t28BA72CC24E34D9100272C2D /* LexSML.cxx */,\n\t\t\t\t28BA72DE24E34D9200272C2D /* LexSorcus.cxx */,\n\t\t\t\t28BA72F924E34D9300272C2D /* LexSpecman.cxx */,\n\t\t\t\t28BA730924E34D9400272C2D /* LexSpice.cxx */,\n\t\t\t\t28BA72F324E34D9300272C2D /* LexSQL.cxx */,\n\t\t\t\t28BA731724E34D9500272C2D /* LexStata.cxx */,\n\t\t\t\t28BA731224E34D9500272C2D /* LexSTTXT.cxx */,\n\t\t\t\t28BA72CE24E34D9100272C2D /* LexTACL.cxx */,\n\t\t\t\t28BA730E24E34D9500272C2D /* LexTADS3.cxx */,\n\t\t\t\t28BA732E24E34D9600272C2D /* LexTAL.cxx */,\n\t\t\t\t28BA72C924E34D9100272C2D /* LexTCL.cxx */,\n\t\t\t\t28BA730324E34D9400272C2D /* LexTCMD.cxx */,\n\t\t\t\t28BA730824E34D9400272C2D /* LexTeX.cxx */,\n\t\t\t\t42BC44CCB57D4E78DEE6E358 /* LexTOML.cxx */,\n\t\t\t\tD2EF4913B8F91656C787F584 /* LexTroff.cxx */,\n\t\t\t\t28BA730F24E34D9500272C2D /* LexTxt2tags.cxx */,\n\t\t\t\t28BA731F24E34D9600272C2D /* LexVB.cxx */,\n\t\t\t\t28BA731A24E34D9500272C2D /* LexVerilog.cxx */,\n\t\t\t\t28BA72DA24E34D9200272C2D /* LexVHDL.cxx */,\n\t\t\t\t28BA731E24E34D9500272C2D /* LexVisualProlog.cxx */,\n\t\t\t\t28BA730A24E34D9400272C2D /* LexX12.cxx */,\n\t\t\t\t28BA72E724E34D9200272C2D /* LexYAML.cxx */,\n\t\t\t\t71684CF6BCC80369BCE2F893 /* LexZig.cxx */,\n\t\t\t);\n\t\t\tname = Lexers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t280262B8246DF776000DF3B8 /* LexLib */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28BA72AA24E34D5B00272C2D /* Accessor.cxx */,\n\t\t\t\t28BA729724E34D5A00272C2D /* Accessor.h */,\n\t\t\t\t28BA72A024E34D5B00272C2D /* CatalogueModules.h */,\n\t\t\t\t28BA729524E34D5A00272C2D /* CharacterCategory.cxx */,\n\t\t\t\t28BA72A924E34D5B00272C2D /* CharacterCategory.h */,\n\t\t\t\t28BA729924E34D5A00272C2D /* CharacterSet.cxx */,\n\t\t\t\t28BA72A124E34D5B00272C2D /* CharacterSet.h */,\n\t\t\t\t28BA729C24E34D5A00272C2D /* DefaultLexer.cxx */,\n\t\t\t\t28BA729124E34D5A00272C2D /* DefaultLexer.h */,\n\t\t\t\t283A17AC2B47E61100DF5C82 /* InList.cxx */,\n\t\t\t\t283A17AD2B47E61100DF5C82 /* InList.h */,\n\t\t\t\t283639BB268FD4EA009D58A1 /* LexAccessor.cxx */,\n\t\t\t\t28BA729024E34D5A00272C2D /* LexAccessor.h */,\n\t\t\t\t28BA728F24E34D5A00272C2D /* LexerBase.cxx */,\n\t\t\t\t28BA72A624E34D5B00272C2D /* LexerBase.h */,\n\t\t\t\t28BA72A524E34D5B00272C2D /* LexerModule.cxx */,\n\t\t\t\t28BA729424E34D5A00272C2D /* LexerModule.h */,\n\t\t\t\t28BA72A724E34D5B00272C2D /* LexerSimple.cxx */,\n\t\t\t\t28BA729624E34D5A00272C2D /* LexerSimple.h */,\n\t\t\t\t28BA729F24E34D5A00272C2D /* OptionSet.h */,\n\t\t\t\t28BA729824E34D5A00272C2D /* PropSetSimple.cxx */,\n\t\t\t\t28BA72A324E34D5B00272C2D /* PropSetSimple.h */,\n\t\t\t\t28BA729A24E34D5A00272C2D /* SparseState.h */,\n\t\t\t\t28BA72A424E34D5B00272C2D /* StringCopy.h */,\n\t\t\t\t28BA72A824E34D5B00272C2D /* StyleContext.cxx */,\n\t\t\t\t28BA72A224E34D5B00272C2D /* StyleContext.h */,\n\t\t\t\t28BA729224E34D5A00272C2D /* SubStyles.h */,\n\t\t\t\t28BA729E24E34D5A00272C2D /* WordList.cxx */,\n\t\t\t\t28BA729B24E34D5A00272C2D /* WordList.h */,\n\t\t\t);\n\t\t\tname = LexLib;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\t280262A1246DF655000DF3B8 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t28BA73AD24E34DBC00272C2D /* Lexilla.h in Headers */,\n\t\t\t\t28BA72BF24E34D5B00272C2D /* PropSetSimple.h in Headers */,\n\t\t\t\t28BA72B224E34D5B00272C2D /* LexerSimple.h in Headers */,\n\t\t\t\t28BA72B724E34D5B00272C2D /* WordList.h in Headers */,\n\t\t\t\t28BA72C024E34D5B00272C2D /* StringCopy.h in Headers */,\n\t\t\t\t28BA72AD24E34D5B00272C2D /* DefaultLexer.h in Headers */,\n\t\t\t\t28BA72B324E34D5B00272C2D /* Accessor.h in Headers */,\n\t\t\t\t28BA72BE24E34D5B00272C2D /* StyleContext.h in Headers */,\n\t\t\t\t28BA72BB24E34D5B00272C2D /* OptionSet.h in Headers */,\n\t\t\t\t283A17AF2B47E61100DF5C82 /* InList.h in Headers */,\n\t\t\t\t28BA72B024E34D5B00272C2D /* LexerModule.h in Headers */,\n\t\t\t\t28BA72AC24E34D5B00272C2D /* LexAccessor.h in Headers */,\n\t\t\t\t28BA72C524E34D5B00272C2D /* CharacterCategory.h in Headers */,\n\t\t\t\t28BA72BD24E34D5B00272C2D /* CharacterSet.h in Headers */,\n\t\t\t\t28BA72AE24E34D5B00272C2D /* SubStyles.h in Headers */,\n\t\t\t\t28BA72BC24E34D5B00272C2D /* CatalogueModules.h in Headers */,\n\t\t\t\t28BA72C224E34D5B00272C2D /* LexerBase.h in Headers */,\n\t\t\t\t28BA72B624E34D5B00272C2D /* SparseState.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\t280262A4246DF655000DF3B8 /* lexilla */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 280262B0246DF655000DF3B8 /* Build configuration list for PBXNativeTarget \"lexilla\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t280262A1246DF655000DF3B8 /* Headers */,\n\t\t\t\t280262A2246DF655000DF3B8 /* Sources */,\n\t\t\t\t280262A3246DF655000DF3B8 /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = lexilla;\n\t\t\tproductName = lexilla;\n\t\t\tproductReference = 280262A5246DF655000DF3B8 /* liblexilla.dylib */;\n\t\t\tproductType = \"com.apple.product-type.library.dynamic\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t2802629D246DF655000DF3B8 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = YES;\n\t\t\t\tLastUpgradeCheck = 1500;\n\t\t\t\tORGANIZATIONNAME = \"Neil Hodgson\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t280262A4246DF655000DF3B8 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 11.4.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 280262A0246DF655000DF3B8 /* Build configuration list for PBXProject \"Lexilla\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 2802629C246DF655000DF3B8;\n\t\t\tproductRefGroup = 280262A6246DF655000DF3B8 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t280262A4246DF655000DF3B8 /* lexilla */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t280262A2246DF655000DF3B8 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t28BA739A24E34D9700272C2D /* LexMSSQL.cxx in Sources */,\n\t\t\t\t28BA735324E34D9700272C2D /* LexMySQL.cxx in Sources */,\n\t\t\t\t28BA738024E34D9700272C2D /* LexTADS3.cxx in Sources */,\n\t\t\t\t28BA73A924E34D9700272C2D /* LexPerl.cxx in Sources */,\n\t\t\t\t28BA733D24E34D9700272C2D /* LexForth.cxx in Sources */,\n\t\t\t\t28BA736824E34D9700272C2D /* LexEScript.cxx in Sources */,\n\t\t\t\t283639BC268FD4EA009D58A1 /* LexAccessor.cxx in Sources */,\n\t\t\t\t28BA737124E34D9700272C2D /* LexAsm.cxx in Sources */,\n\t\t\t\t28BA737B24E34D9700272C2D /* LexSpice.cxx in Sources */,\n\t\t\t\t28BA737024E34D9700272C2D /* LexCmake.cxx in Sources */,\n\t\t\t\t28BA734624E34D9700272C2D /* LexSmalltalk.cxx in Sources */,\n\t\t\t\t28BA72C424E34D5B00272C2D /* StyleContext.cxx in Sources */,\n\t\t\t\t28BA734C24E34D9700272C2D /* LexVHDL.cxx in Sources */,\n\t\t\t\t28BA737724E34D9700272C2D /* LexInno.cxx in Sources */,\n\t\t\t\t28BA739B24E34D9700272C2D /* LexCSS.cxx in Sources */,\n\t\t\t\t28BA734A24E34D9700272C2D /* LexBash.cxx in Sources */,\n\t\t\t\t28BA734224E34D9700272C2D /* LexCLW.cxx in Sources */,\n\t\t\t\t28BA734424E34D9700272C2D /* LexSAS.cxx in Sources */,\n\t\t\t\t28BA738E24E34D9700272C2D /* LexR.cxx in Sources */,\n\t\t\t\t28BA72C124E34D5B00272C2D /* LexerModule.cxx in Sources */,\n\t\t\t\t28BA735C24E34D9700272C2D /* LexIndent.cxx in Sources */,\n\t\t\t\t28BA736624E34D9700272C2D /* LexNsis.cxx in Sources */,\n\t\t\t\t28BA734724E34D9700272C2D /* LexModula.cxx in Sources */,\n\t\t\t\t28BA734924E34D9700272C2D /* LexASY.cxx in Sources */,\n\t\t\t\t28BA739024E34D9700272C2D /* LexVisualProlog.cxx in Sources */,\n\t\t\t\t28BA739524E34D9700272C2D /* LexPO.cxx in Sources */,\n\t\t\t\t28BA72BA24E34D5B00272C2D /* WordList.cxx in Sources */,\n\t\t\t\t28BA739624E34D9700272C2D /* LexPowerPro.cxx in Sources */,\n\t\t\t\t28BA733924E34D9700272C2D /* LexBasic.cxx in Sources */,\n\t\t\t\t28BA739D24E34D9700272C2D /* LexCaml.cxx in Sources */,\n\t\t\t\t28BA739724E34D9700272C2D /* LexProps.cxx in Sources */,\n\t\t\t\t28BA737424E34D9700272C2D /* LexDMIS.cxx in Sources */,\n\t\t\t\t28BA73A524E34D9700272C2D /* LexECL.cxx in Sources */,\n\t\t\t\t28BA736524E34D9700272C2D /* LexSQL.cxx in Sources */,\n\t\t\t\t28BA72AB24E34D5B00272C2D /* LexerBase.cxx in Sources */,\n\t\t\t\t28BA72B824E34D5B00272C2D /* DefaultLexer.cxx in Sources */,\n\t\t\t\t28BA73A024E34D9700272C2D /* LexTAL.cxx in Sources */,\n\t\t\t\t28BA733C24E34D9700272C2D /* LexMetapost.cxx in Sources */,\n\t\t\t\t28BA733A24E34D9700272C2D /* LexCIL.cxx in Sources */,\n\t\t\t\t28BA735D24E34D9700272C2D /* LexErrorList.cxx in Sources */,\n\t\t\t\t28BA737224E34D9700272C2D /* LexAda.cxx in Sources */,\n\t\t\t\t28BA737D24E34D9700272C2D /* LexAU3.cxx in Sources */,\n\t\t\t\t28BA734024E34D9700272C2D /* LexTACL.cxx in Sources */,\n\t\t\t\t28BA736724E34D9700272C2D /* LexEDIFACT.cxx in Sources */,\n\t\t\t\t28BA736024E34D9700272C2D /* LexAbaqus.cxx in Sources */,\n\t\t\t\t28BA734D24E34D9700272C2D /* LexAsn1.cxx in Sources */,\n\t\t\t\t28BA737A24E34D9700272C2D /* LexTeX.cxx in Sources */,\n\t\t\t\t28BA739124E34D9700272C2D /* LexVB.cxx in Sources */,\n\t\t\t\t28BA735E24E34D9700272C2D /* LexFlagship.cxx in Sources */,\n\t\t\t\t28BA735B24E34D9700272C2D /* LexRuby.cxx in Sources */,\n\t\t\t\t28BA735424E34D9700272C2D /* LexHollywood.cxx in Sources */,\n\t\t\t\t28BA736D24E34D9700272C2D /* LexFortran.cxx in Sources */,\n\t\t\t\t28BA738924E34D9700272C2D /* LexStata.cxx in Sources */,\n\t\t\t\t28BA737524E34D9700272C2D /* LexTCMD.cxx in Sources */,\n\t\t\t\t28BA72C624E34D5B00272C2D /* Accessor.cxx in Sources */,\n\t\t\t\t28BA733B24E34D9700272C2D /* LexTCL.cxx in Sources */,\n\t\t\t\t28BA739C24E34D9700272C2D /* LexMaxima.cxx in Sources */,\n\t\t\t\t28BA73AA24E34D9700272C2D /* LexRust.cxx in Sources */,\n\t\t\t\t28BA733F24E34D9700272C2D /* LexOScript.cxx in Sources */,\n\t\t\t\t28BA737324E34D9700272C2D /* LexCrontab.cxx in Sources */,\n\t\t\t\t28BA734E24E34D9700272C2D /* LexCoffeeScript.cxx in Sources */,\n\t\t\t\t28BA735624E34D9700272C2D /* LexLisp.cxx in Sources */,\n\t\t\t\t28BA735824E34D9700272C2D /* LexPS.cxx in Sources */,\n\t\t\t\t28BA735F24E34D9700272C2D /* LexLaTeX.cxx in Sources */,\n\t\t\t\t28BA736B24E34D9700272C2D /* LexSpecman.cxx in Sources */,\n\t\t\t\t28BA73A724E34D9700272C2D /* LexBibTeX.cxx in Sources */,\n\t\t\t\t28BA737E24E34D9700272C2D /* LexBaan.cxx in Sources */,\n\t\t\t\t28BA738124E34D9700272C2D /* LexTxt2tags.cxx in Sources */,\n\t\t\t\t28BA737F24E34D9700272C2D /* LexMPT.cxx in Sources */,\n\t\t\t\t28BA738424E34D9700272C2D /* LexSTTXT.cxx in Sources */,\n\t\t\t\t28BA734F24E34D9700272C2D /* LexDiff.cxx in Sources */,\n\t\t\t\t28BA735924E34D9700272C2D /* LexYAML.cxx in Sources */,\n\t\t\t\t28BA735524E34D9700272C2D /* LexProgress.cxx in Sources */,\n\t\t\t\t28BA736F24E34D9700272C2D /* LexPython.cxx in Sources */,\n\t\t\t\t28BA72B524E34D5B00272C2D /* CharacterSet.cxx in Sources */,\n\t\t\t\t28BA739E24E34D9700272C2D /* LexDataflex.cxx in Sources */,\n\t\t\t\t28BA738F24E34D9700272C2D /* LexScriptol.cxx in Sources */,\n\t\t\t\t28BA736C24E34D9700272C2D /* LexHTML.cxx in Sources */,\n\t\t\t\t28BA737924E34D9700272C2D /* LexMake.cxx in Sources */,\n\t\t\t\t28BA738524E34D9700272C2D /* LexMagik.cxx in Sources */,\n\t\t\t\t28BA72B124E34D5B00272C2D /* CharacterCategory.cxx in Sources */,\n\t\t\t\t28BA739424E34D9700272C2D /* LexPB.cxx in Sources */,\n\t\t\t\t28BA73A624E34D9700272C2D /* LexMatlab.cxx in Sources */,\n\t\t\t\t28BA736324E34D9700272C2D /* LexRaku.cxx in Sources */,\n\t\t\t\t28BA736224E34D9700272C2D /* LexCPP.cxx in Sources */,\n\t\t\t\t283A17AE2B47E61100DF5C82 /* InList.cxx in Sources */,\n\t\t\t\t28BA738A24E34D9700272C2D /* LexOpal.cxx in Sources */,\n\t\t\t\t28BA736E24E34D9700272C2D /* LexRegistry.cxx in Sources */,\n\t\t\t\t28BA738224E34D9700272C2D /* LexMMIXAL.cxx in Sources */,\n\t\t\t\t28BA736A24E34D9700272C2D /* LexKVIrc.cxx in Sources */,\n\t\t\t\t28BA73A224E34D9700272C2D /* LexJSON.cxx in Sources */,\n\t\t\t\t28BA738724E34D9700272C2D /* LexCsound.cxx in Sources */,\n\t\t\t\t28BA738824E34D9700272C2D /* LexLua.cxx in Sources */,\n\t\t\t\t28BA739824E34D9700272C2D /* LexCOBOL.cxx in Sources */,\n\t\t\t\t28BA73A824E34D9700272C2D /* LexNimrod.cxx in Sources */,\n\t\t\t\t28BA739324E34D9700272C2D /* LexAVS.cxx in Sources */,\n\t\t\t\t28BA737624E34D9700272C2D /* LexConf.cxx in Sources */,\n\t\t\t\t28BA734524E34D9700272C2D /* LexNim.cxx in Sources */,\n\t\t\t\t28BA73AE24E34DBC00272C2D /* Lexilla.cxx in Sources */,\n\t\t\t\t28BA72C324E34D5B00272C2D /* LexerSimple.cxx in Sources */,\n\t\t\t\t28BA735124E34D9700272C2D /* LexAPDL.cxx in Sources */,\n\t\t\t\t28BA736424E34D9700272C2D /* LexGAP.cxx in Sources */,\n\t\t\t\t28BA734324E34D9700272C2D /* LexRebol.cxx in Sources */,\n\t\t\t\t28BA733E24E34D9700272C2D /* LexSML.cxx in Sources */,\n\t\t\t\t28BA738C24E34D9700272C2D /* LexVerilog.cxx in Sources */,\n\t\t\t\t28BA738624E34D9700272C2D /* LexNull.cxx in Sources */,\n\t\t\t\t28BA736124E34D9700272C2D /* LexBatch.cxx in Sources */,\n\t\t\t\t28BA736924E34D9700272C2D /* LexPOV.cxx in Sources */,\n\t\t\t\t28BA734124E34D9700272C2D /* LexGui4Cli.cxx in Sources */,\n\t\t\t\t28BA734824E34D9700272C2D /* LexBullant.cxx in Sources */,\n\t\t\t\t28BA734B24E34D9700272C2D /* LexEiffel.cxx in Sources */,\n\t\t\t\t28BA73A424E34D9700272C2D /* LexAVE.cxx in Sources */,\n\t\t\t\t28BA738D24E34D9700272C2D /* LexHaskell.cxx in Sources */,\n\t\t\t\t28BA735024E34D9700272C2D /* LexSorcus.cxx in Sources */,\n\t\t\t\t28BA739F24E34D9700272C2D /* LexLout.cxx in Sources */,\n\t\t\t\t28BA73A124E34D9700272C2D /* LexMarkdown.cxx in Sources */,\n\t\t\t\t28BA739224E34D9700272C2D /* LexDMAP.cxx in Sources */,\n\t\t\t\t28BA737824E34D9700272C2D /* LexA68k.cxx in Sources */,\n\t\t\t\t28BA735A24E34D9700272C2D /* LexErlang.cxx in Sources */,\n\t\t\t\t28BA738B24E34D9700272C2D /* LexHex.cxx in Sources */,\n\t\t\t\t28BA735224E34D9700272C2D /* LexD.cxx in Sources */,\n\t\t\t\t28BA73A324E34D9700272C2D /* LexPascal.cxx in Sources */,\n\t\t\t\t28BA739924E34D9700272C2D /* LexPLM.cxx in Sources */,\n\t\t\t\t28BA735724E34D9700272C2D /* LexPowerShell.cxx in Sources */,\n\t\t\t\t28BA738324E34D9700272C2D /* LexKix.cxx in Sources */,\n\t\t\t\t28BA72B424E34D5B00272C2D /* PropSetSimple.cxx in Sources */,\n\t\t\t\t28BA737C24E34D9700272C2D /* LexX12.cxx in Sources */,\n\t\t\t\tB32D4A2A9CEC222A5140E99F /* LexFSharp.cxx in Sources */,\n\t\t\t\t70BF497C8D265026B77C97DA /* LexJulia.cxx in Sources */,\n\t\t\t\t510D44AFB91EE873E86ABDD4 /* LexAsciidoc.cxx in Sources */,\n\t\t\t\t00D544CC992062D2E3CD4BF6 /* LexGDScript.cxx in Sources */,\n\t\t\t\t3D044C4CA34C6FD7E58E0091 /* LexTOML.cxx in Sources */,\n\t\t\t\t14314DCD945FDA90481F0A0D /* LexTroff.cxx in Sources */,\n\t\t\t\t0DFB4F5F94B018794ADB389D /* LexDart.cxx in Sources */,\n\t\t\t\tCEC8496B8D9712E6EEDBC301 /* LexZig.cxx in Sources */,\n\t\t\t\t4A444CF5A75E52E2C5537328 /* LexNix.cxx in Sources */,\n\t\t\t\tFE5F4B168F37B523E4D1EFCD /* LexSINEX.cxx in Sources */,\n\t\t\t\tB049435FAED389EA7C61E3C1 /* LexEscSeq.cxx in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t280262AE246DF655000DF3B8 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\tDEBUG,\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.13;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t280262AF246DF655000DF3B8 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = NDEBUG;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.13;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t280262B1246DF655000DF3B8 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 5.4.9;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 4F446KW87E;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tEXECUTABLE_PREFIX = lib;\n\t\t\t\tGCC_ENABLE_CPP_EXCEPTIONS = YES;\n\t\t\t\tGCC_ENABLE_CPP_RTTI = YES;\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t../../include,\n\t\t\t\t\t../../../scintilla/include,\n\t\t\t\t\t../../lexlib,\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Lexilla/Info.plist\";\n\t\t\t\tINSTALL_PATH = \"@rpath\";\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.13;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = org.scintilla.Lexilla;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t280262B2246DF655000DF3B8 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 5.4.9;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 4F446KW87E;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tEXECUTABLE_PREFIX = lib;\n\t\t\t\tGCC_ENABLE_CPP_EXCEPTIONS = YES;\n\t\t\t\tGCC_ENABLE_CPP_RTTI = YES;\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t../../include,\n\t\t\t\t\t../../../scintilla/include,\n\t\t\t\t\t../../lexlib,\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Lexilla/Info.plist\";\n\t\t\t\tINSTALL_PATH = \"@rpath\";\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.13;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = org.scintilla.Lexilla;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t280262A0246DF655000DF3B8 /* Build configuration list for PBXProject \"Lexilla\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t280262AE246DF655000DF3B8 /* Debug */,\n\t\t\t\t280262AF246DF655000DF3B8 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t280262B0246DF655000DF3B8 /* Build configuration list for PBXNativeTarget \"lexilla\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t280262B1246DF655000DF3B8 /* Debug */,\n\t\t\t\t280262B2246DF655000DF3B8 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 2802629D246DF655000DF3B8 /* Project object */;\n}\n"
  },
  {
    "path": "src/Lexilla/Lexilla.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:Lexilla.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "src/Lexilla/Lexilla.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/Lexilla.cxx",
    "content": "// Lexilla lexer library\n/** @file Lexilla.cxx\n ** Lexer infrastructure.\n ** Provides entry points to shared library.\n **/\n// Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cstring>\n\n#include <vector>\n#include <initializer_list>\n\n#if defined(_WIN32)\n#define EXPORT_FUNCTION __declspec(dllexport)\n#define CALLING_CONVENTION __stdcall\n#else\n#define EXPORT_FUNCTION __attribute__((visibility(\"default\")))\n#define CALLING_CONVENTION\n#endif\n\n#include \"ILexer.h\"\n\n#include \"LexerModule.h\"\n#include \"CatalogueModules.h\"\n\nusing namespace Lexilla;\n\n//++Autogenerated -- run lexilla/scripts/LexillaGen.py to regenerate\n//**\\(extern const LexerModule \\*;\\n\\)\nextern const LexerModule lmA68k;\nextern const LexerModule lmAbaqus;\nextern const LexerModule lmAda;\nextern const LexerModule lmAPDL;\nextern const LexerModule lmAs;\nextern const LexerModule lmAsciidoc;\nextern const LexerModule lmAsm;\nextern const LexerModule lmAsn1;\nextern const LexerModule lmASY;\nextern const LexerModule lmAU3;\nextern const LexerModule lmAVE;\nextern const LexerModule lmAVS;\nextern const LexerModule lmBaan;\nextern const LexerModule lmBash;\nextern const LexerModule lmBatch;\nextern const LexerModule lmBibTeX;\nextern const LexerModule lmBlitzBasic;\nextern const LexerModule lmBullant;\nextern const LexerModule lmCaml;\nextern const LexerModule lmCIL;\nextern const LexerModule lmClw;\nextern const LexerModule lmClwNoCase;\nextern const LexerModule lmCmake;\nextern const LexerModule lmCOBOL;\nextern const LexerModule lmCoffeeScript;\nextern const LexerModule lmConf;\nextern const LexerModule lmCPP;\nextern const LexerModule lmCPPNoCase;\nextern const LexerModule lmCsound;\nextern const LexerModule lmCss;\nextern const LexerModule lmD;\nextern const LexerModule lmDart;\nextern const LexerModule lmDataflex;\nextern const LexerModule lmDiff;\nextern const LexerModule lmDMAP;\nextern const LexerModule lmDMIS;\nextern const LexerModule lmECL;\nextern const LexerModule lmEDIFACT;\nextern const LexerModule lmEiffel;\nextern const LexerModule lmEiffelkw;\nextern const LexerModule lmErlang;\nextern const LexerModule lmErrorList;\nextern const LexerModule lmESCRIPT;\nextern const LexerModule lmEscSeq;\nextern const LexerModule lmF77;\nextern const LexerModule lmFlagShip;\nextern const LexerModule lmForth;\nextern const LexerModule lmFortran;\nextern const LexerModule lmFreeBasic;\nextern const LexerModule lmFSharp;\nextern const LexerModule lmGAP;\nextern const LexerModule lmGDScript;\nextern const LexerModule lmGui4Cli;\nextern const LexerModule lmHaskell;\nextern const LexerModule lmHollywood;\nextern const LexerModule lmHTML;\nextern const LexerModule lmIHex;\nextern const LexerModule lmIndent;\nextern const LexerModule lmInno;\nextern const LexerModule lmJSON;\nextern const LexerModule lmJulia;\nextern const LexerModule lmKix;\nextern const LexerModule lmKVIrc;\nextern const LexerModule lmLatex;\nextern const LexerModule lmLISP;\nextern const LexerModule lmLiterateHaskell;\nextern const LexerModule lmLot;\nextern const LexerModule lmLout;\nextern const LexerModule lmLua;\nextern const LexerModule lmMagikSF;\nextern const LexerModule lmMake;\nextern const LexerModule lmMarkdown;\nextern const LexerModule lmMatlab;\nextern const LexerModule lmMaxima;\nextern const LexerModule lmMETAPOST;\nextern const LexerModule lmMMIXAL;\nextern const LexerModule lmModula;\nextern const LexerModule lmMSSQL;\nextern const LexerModule lmMySQL;\nextern const LexerModule lmNim;\nextern const LexerModule lmNimrod;\nextern const LexerModule lmNix;\nextern const LexerModule lmNncrontab;\nextern const LexerModule lmNsis;\nextern const LexerModule lmNull;\nextern const LexerModule lmOctave;\nextern const LexerModule lmOpal;\nextern const LexerModule lmOScript;\nextern const LexerModule lmPascal;\nextern const LexerModule lmPB;\nextern const LexerModule lmPerl;\nextern const LexerModule lmPHPSCRIPT;\nextern const LexerModule lmPLM;\nextern const LexerModule lmPO;\nextern const LexerModule lmPOV;\nextern const LexerModule lmPowerPro;\nextern const LexerModule lmPowerShell;\nextern const LexerModule lmProgress;\nextern const LexerModule lmProps;\nextern const LexerModule lmPS;\nextern const LexerModule lmPureBasic;\nextern const LexerModule lmPython;\nextern const LexerModule lmR;\nextern const LexerModule lmRaku;\nextern const LexerModule lmREBOL;\nextern const LexerModule lmRegistry;\nextern const LexerModule lmRuby;\nextern const LexerModule lmRust;\nextern const LexerModule lmSAS;\nextern const LexerModule lmScriptol;\nextern const LexerModule lmSINEX;\nextern const LexerModule lmSmalltalk;\nextern const LexerModule lmSML;\nextern const LexerModule lmSorc;\nextern const LexerModule lmSpecman;\nextern const LexerModule lmSpice;\nextern const LexerModule lmSQL;\nextern const LexerModule lmSrec;\nextern const LexerModule lmStata;\nextern const LexerModule lmSTTXT;\nextern const LexerModule lmTACL;\nextern const LexerModule lmTADS3;\nextern const LexerModule lmTAL;\nextern const LexerModule lmTCL;\nextern const LexerModule lmTCMD;\nextern const LexerModule lmTEHex;\nextern const LexerModule lmTeX;\nextern const LexerModule lmTOML;\nextern const LexerModule lmTroff;\nextern const LexerModule lmTxt2tags;\nextern const LexerModule lmVB;\nextern const LexerModule lmVBScript;\nextern const LexerModule lmVerilog;\nextern const LexerModule lmVHDL;\nextern const LexerModule lmVisualProlog;\nextern const LexerModule lmX12;\nextern const LexerModule lmXML;\nextern const LexerModule lmYAML;\nextern const LexerModule lmZig;\n\n//--Autogenerated -- end of automatically generated section\n\nnamespace {\n\nCatalogueModules catalogueLexilla;\n\nvoid AddEachLexer() {\n\n\tif (catalogueLexilla.Count() > 0) {\n\t\treturn;\n\t}\n\n\tcatalogueLexilla.AddLexerModules({\n//++Autogenerated -- run scripts/LexillaGen.py to regenerate\n//**\\(\\t\\t&\\*,\\n\\)\n\t\t&lmA68k,\n\t\t&lmAbaqus,\n\t\t&lmAda,\n\t\t&lmAPDL,\n\t\t&lmAs,\n\t\t&lmAsciidoc,\n\t\t&lmAsm,\n\t\t&lmAsn1,\n\t\t&lmASY,\n\t\t&lmAU3,\n\t\t&lmAVE,\n\t\t&lmAVS,\n\t\t&lmBaan,\n\t\t&lmBash,\n\t\t&lmBatch,\n\t\t&lmBibTeX,\n\t\t&lmBlitzBasic,\n\t\t&lmBullant,\n\t\t&lmCaml,\n\t\t&lmCIL,\n\t\t&lmClw,\n\t\t&lmClwNoCase,\n\t\t&lmCmake,\n\t\t&lmCOBOL,\n\t\t&lmCoffeeScript,\n\t\t&lmConf,\n\t\t&lmCPP,\n\t\t&lmCPPNoCase,\n\t\t&lmCsound,\n\t\t&lmCss,\n\t\t&lmD,\n\t\t&lmDart,\n\t\t&lmDataflex,\n\t\t&lmDiff,\n\t\t&lmDMAP,\n\t\t&lmDMIS,\n\t\t&lmECL,\n\t\t&lmEDIFACT,\n\t\t&lmEiffel,\n\t\t&lmEiffelkw,\n\t\t&lmErlang,\n\t\t&lmErrorList,\n\t\t&lmESCRIPT,\n\t\t&lmEscSeq,\n\t\t&lmF77,\n\t\t&lmFlagShip,\n\t\t&lmForth,\n\t\t&lmFortran,\n\t\t&lmFreeBasic,\n\t\t&lmFSharp,\n\t\t&lmGAP,\n\t\t&lmGDScript,\n\t\t&lmGui4Cli,\n\t\t&lmHaskell,\n\t\t&lmHollywood,\n\t\t&lmHTML,\n\t\t&lmIHex,\n\t\t&lmIndent,\n\t\t&lmInno,\n\t\t&lmJSON,\n\t\t&lmJulia,\n\t\t&lmKix,\n\t\t&lmKVIrc,\n\t\t&lmLatex,\n\t\t&lmLISP,\n\t\t&lmLiterateHaskell,\n\t\t&lmLot,\n\t\t&lmLout,\n\t\t&lmLua,\n\t\t&lmMagikSF,\n\t\t&lmMake,\n\t\t&lmMarkdown,\n\t\t&lmMatlab,\n\t\t&lmMaxima,\n\t\t&lmMETAPOST,\n\t\t&lmMMIXAL,\n\t\t&lmModula,\n\t\t&lmMSSQL,\n\t\t&lmMySQL,\n\t\t&lmNim,\n\t\t&lmNimrod,\n\t\t&lmNix,\n\t\t&lmNncrontab,\n\t\t&lmNsis,\n\t\t&lmNull,\n\t\t&lmOctave,\n\t\t&lmOpal,\n\t\t&lmOScript,\n\t\t&lmPascal,\n\t\t&lmPB,\n\t\t&lmPerl,\n\t\t&lmPHPSCRIPT,\n\t\t&lmPLM,\n\t\t&lmPO,\n\t\t&lmPOV,\n\t\t&lmPowerPro,\n\t\t&lmPowerShell,\n\t\t&lmProgress,\n\t\t&lmProps,\n\t\t&lmPS,\n\t\t&lmPureBasic,\n\t\t&lmPython,\n\t\t&lmR,\n\t\t&lmRaku,\n\t\t&lmREBOL,\n\t\t&lmRegistry,\n\t\t&lmRuby,\n\t\t&lmRust,\n\t\t&lmSAS,\n\t\t&lmScriptol,\n\t\t&lmSINEX,\n\t\t&lmSmalltalk,\n\t\t&lmSML,\n\t\t&lmSorc,\n\t\t&lmSpecman,\n\t\t&lmSpice,\n\t\t&lmSQL,\n\t\t&lmSrec,\n\t\t&lmStata,\n\t\t&lmSTTXT,\n\t\t&lmTACL,\n\t\t&lmTADS3,\n\t\t&lmTAL,\n\t\t&lmTCL,\n\t\t&lmTCMD,\n\t\t&lmTEHex,\n\t\t&lmTeX,\n\t\t&lmTOML,\n\t\t&lmTroff,\n\t\t&lmTxt2tags,\n\t\t&lmVB,\n\t\t&lmVBScript,\n\t\t&lmVerilog,\n\t\t&lmVHDL,\n\t\t&lmVisualProlog,\n\t\t&lmX12,\n\t\t&lmXML,\n\t\t&lmYAML,\n\t\t&lmZig,\n\n//--Autogenerated -- end of automatically generated section\n\t\t});\n\n}\n\n}\n\nextern \"C\" {\n\nEXPORT_FUNCTION int CALLING_CONVENTION GetLexerCount() {\n\tAddEachLexer();\n\treturn static_cast<int>(catalogueLexilla.Count());\n}\n\nEXPORT_FUNCTION void CALLING_CONVENTION GetLexerName(unsigned int index, char *name, int buflength) {\n\tAddEachLexer();\n\t*name = 0;\n\tconst char *lexerName = catalogueLexilla.Name(index);\n\tif (static_cast<size_t>(buflength) > strlen(lexerName)) {\n\t\tstrcpy(name, lexerName);\n\t}\n}\n\nEXPORT_FUNCTION LexerFactoryFunction CALLING_CONVENTION GetLexerFactory(unsigned int index) {\n\tAddEachLexer();\n\treturn catalogueLexilla.Factory(index);\n}\n\nEXPORT_FUNCTION Scintilla::ILexer5 * CALLING_CONVENTION CreateLexer(const char *name) {\n\tAddEachLexer();\n\tfor (size_t i = 0; i < catalogueLexilla.Count(); i++) {\n\t\tconst char *lexerName = catalogueLexilla.Name(i);\n\t\tif (0 == strcmp(lexerName, name)) {\n\t\t\treturn catalogueLexilla.Create(i);\n\t\t}\n\t}\n\treturn nullptr;\n}\n\nEXPORT_FUNCTION const char * CALLING_CONVENTION LexerNameFromID(int identifier) {\n\tAddEachLexer();\n\tconst LexerModule *pModule = catalogueLexilla.Find(identifier);\n\tif (pModule) {\n\t\treturn pModule->languageName;\n\t}\n\treturn nullptr;\n}\n\nEXPORT_FUNCTION const char * CALLING_CONVENTION GetLibraryPropertyNames() {\n\treturn \"\";\n}\n\nEXPORT_FUNCTION void CALLING_CONVENTION SetLibraryProperty(const char *, const char *) {\n\t// Null implementation\n}\n\nEXPORT_FUNCTION const char * CALLING_CONVENTION GetNameSpace() {\n\treturn \"lexilla\";\n}\n\n}\n\n// Not exported from binary as LexerModule must be built exactly the same as\n// modules listed above\nvoid AddStaticLexerModule(const LexerModule *plm) {\n\tAddEachLexer();\n\tcatalogueLexilla.AddLexerModule(plm);\n}\n"
  },
  {
    "path": "src/Lexilla.def",
    "content": "EXPORTS\n\tGetLexerCount\n\tGetLexerName\n\tGetLexerFactory\n\tCreateLexer\n\tLexerNameFromID\n\tGetLibraryPropertyNames\n\tSetLibraryProperty\n\tGetNameSpace\n"
  },
  {
    "path": "src/Lexilla.pro",
    "content": "# This Qt Creator project file is not meant for creating Lexilla libraries\n# but instead for easily running Clang-Tidy on lexers.\n\nQT       += core\n\nTARGET = Lexilla\nTEMPLATE = lib\nCONFIG += lib_bundle\nCONFIG += c++1z\n\nVERSION = 5.1.3\n\nSOURCES += \\\n    Lexilla.cxx \\\n    $$files(../lexlib/*.cxx, false) \\\n    $$files(../lexers/*.cxx, false)\n\nHEADERS  += \\\n    ../include/Lexilla.h \\\n    $$files(../lexlib/*.h, false) \\\n    $$files(../lexers/*.h, false)\n\nINCLUDEPATH += ../include ../lexlib ../../scintilla/include\n\nDEFINES += _CRT_SECURE_NO_DEPRECATE=1\nCONFIG(release, debug|release) {\n    DEFINES += NDEBUG=1\n}\n\nDESTDIR = ../bin\n\nmacx {\n\tQMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/\n}\n"
  },
  {
    "path": "src/Lexilla.ruleset",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RuleSet Name=\"Lexilla Rules\" Description=\"A set of rules for Lexilla. Don't check for owner, not_null, gsl::at, simple array access.\" ToolsVersion=\"17.0\">\r\n  <IncludeAll Action=\"Warning\" />\r\n  <Rules AnalyzerId=\"Microsoft.Analyzers.NativeCodeAnalysis\" RuleNamespace=\"Microsoft.Rules.Native\">\r\n    <Rule Id=\"C26400\" Action=\"None\" />\r\n    <Rule Id=\"C26429\" Action=\"None\" />\r\n    <Rule Id=\"C26446\" Action=\"None\" />\r\n    <Rule Id=\"C26455\" Action=\"None\" />\r\n    <Rule Id=\"C26481\" Action=\"None\" />\r\n    <Rule Id=\"C26482\" Action=\"None\" />\r\n    <Rule Id=\"C26485\" Action=\"None\" />\r\n  </Rules>\r\n</RuleSet>"
  },
  {
    "path": "src/Lexilla.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <ProjectGuid>{E541C9BE-13BC-4CE6-A0A4-31145F51A2C1}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>Lexilla</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup>\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v143</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup>\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis>\r\n    <CodeAnalysisRuleSet>Lexilla.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>..\\include;..\\..\\scintilla\\include;..\\lexlib;</AdditionalIncludeDirectories>\r\n      <BrowseInformation>false</BrowseInformation>\r\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\r\n      <MinimalRebuild>false</MinimalRebuild>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n      <LanguageStandard>stdcpp17</LanguageStandard>\r\n      <AdditionalOptions>/source-charset:utf-8 %(AdditionalOptions)</AdditionalOptions>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Windows</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r\n      <CETCompat>true</CETCompat>\r\n      <ModuleDefinitionFile>Lexilla.def</ModuleDefinitionFile>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>\r\n      <CETCompat>false</CETCompat>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <ClCompile>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <ClCompile>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <CETCompat>false</CETCompat>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\lexers\\*.cxx\" />\r\n    <ClCompile Include=\"..\\lexlib\\*.cxx\" />\r\n    <ClCompile Include=\"..\\src\\Lexilla.cxx\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"..\\include\\SciLexer.h\" />\r\n    <ClInclude Include=\"..\\lexlib\\*.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ResourceCompile Include=\"..\\src\\LexillaVersion.rc\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "src/LexillaVersion.rc",
    "content": "// Resource file for Lexilla - provides a version number\n// Copyright 2020 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#include <windows.h>\n\n#define VERSION_LEXILLA \"5.4.9\"\n#define VERSION_WORDS 5, 4, 9, 0\n\nVS_VERSION_INFO VERSIONINFO\nFILEVERSION\tVERSION_WORDS\nPRODUCTVERSION\tVERSION_WORDS\nFILEFLAGSMASK\t0x3fL\nFILEFLAGS 0\nFILEOS VOS_NT_WINDOWS32\nFILETYPE VFT_APP\nFILESUBTYPE VFT2_UNKNOWN\nBEGIN\n\tBLOCK\t\"VarFileInfo\"\n\tBEGIN\n\t\tVALUE\t\"Translation\",\t0x409,\t1200\n\tEND\n\tBLOCK\t\"StringFileInfo\"\n\tBEGIN\n\t\tBLOCK \"040904b0\"\n\t\tBEGIN\n\t\t\tVALUE\t\"CompanyName\",\t\"Neil Hodgson neilh@scintilla.org\\0\"\n\t\t\tVALUE\t\"FileDescription\",\t\"Lexilla.DLL - a Lexical Analysis Component\\0\"\n\t\t\tVALUE\t\"FileVersion\",\tVERSION_LEXILLA \"\\0\"\n\t\t\tVALUE\t\"InternalName\",\t\"Lexilla\\0\"\n\t\t\tVALUE\t\"LegalCopyright\",\t\"Copyright 2019 by Neil Hodgson\\0\"\n\t\t\tVALUE\t\"OriginalFilename\",\t\"Lexilla.DLL\\0\"\n\t\t\tVALUE\t\"ProductName\",\t\"Lexilla\\0\"\n\t\t\tVALUE\t\"ProductVersion\",\tVERSION_LEXILLA \"\\0\"\n\t\tEND\n\tEND\nEND\n"
  },
  {
    "path": "src/deps.mak",
    "content": "# Created by DepGen.py. To recreate, run DepGen.py.\n$(DIR_O)/Lexilla.o: \\\n\t../src/Lexilla.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/CatalogueModules.h\n$(DIR_O)/Accessor.o: \\\n\t../lexlib/Accessor.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h\n$(DIR_O)/CharacterCategory.o: \\\n\t../lexlib/CharacterCategory.cxx \\\n\t../lexlib/CharacterCategory.h\n$(DIR_O)/CharacterSet.o: \\\n\t../lexlib/CharacterSet.cxx \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/DefaultLexer.o: \\\n\t../lexlib/DefaultLexer.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/InList.o: \\\n\t../lexlib/InList.cxx \\\n\t../lexlib/InList.h \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/LexAccessor.o: \\\n\t../lexlib/LexAccessor.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/LexerBase.o: \\\n\t../lexlib/LexerBase.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/LexerBase.h\n$(DIR_O)/LexerModule.o: \\\n\t../lexlib/LexerModule.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/LexerBase.h \\\n\t../lexlib/LexerSimple.h\n$(DIR_O)/LexerSimple.o: \\\n\t../lexlib/LexerSimple.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/LexerBase.h \\\n\t../lexlib/LexerSimple.h\n$(DIR_O)/PropSetSimple.o: \\\n\t../lexlib/PropSetSimple.cxx \\\n\t../lexlib/PropSetSimple.h\n$(DIR_O)/StyleContext.o: \\\n\t../lexlib/StyleContext.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/WordList.o: \\\n\t../lexlib/WordList.cxx \\\n\t../lexlib/WordList.h \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/LexA68k.o: \\\n\t../lexers/LexA68k.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAbaqus.o: \\\n\t../lexers/LexAbaqus.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAda.o: \\\n\t../lexers/LexAda.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAPDL.o: \\\n\t../lexers/LexAPDL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAsciidoc.o: \\\n\t../lexers/LexAsciidoc.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAsm.o: \\\n\t../lexers/LexAsm.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexAsn1.o: \\\n\t../lexers/LexAsn1.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexASY.o: \\\n\t../lexers/LexASY.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAU3.o: \\\n\t../lexers/LexAU3.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAVE.o: \\\n\t../lexers/LexAVE.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAVS.o: \\\n\t../lexers/LexAVS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexBaan.o: \\\n\t../lexers/LexBaan.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexBash.o: \\\n\t../lexers/LexBash.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexBasic.o: \\\n\t../lexers/LexBasic.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexBatch.o: \\\n\t../lexers/LexBatch.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexBibTeX.o: \\\n\t../lexers/LexBibTeX.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexBullant.o: \\\n\t../lexers/LexBullant.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCaml.o: \\\n\t../lexers/LexCaml.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCIL.o: \\\n\t../lexers/LexCIL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexCLW.o: \\\n\t../lexers/LexCLW.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCmake.o: \\\n\t../lexers/LexCmake.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCOBOL.o: \\\n\t../lexers/LexCOBOL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCoffeeScript.o: \\\n\t../lexers/LexCoffeeScript.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexConf.o: \\\n\t../lexers/LexConf.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCPP.o: \\\n\t../lexers/LexCPP.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SparseState.h \\\n\t../lexlib/SubStyles.h\n$(DIR_O)/LexCrontab.o: \\\n\t../lexers/LexCrontab.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCsound.o: \\\n\t../lexers/LexCsound.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCSS.o: \\\n\t../lexers/LexCSS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexD.o: \\\n\t../lexers/LexD.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexDart.o: \\\n\t../lexers/LexDart.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexDataflex.o: \\\n\t../lexers/LexDataflex.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexDiff.o: \\\n\t../lexers/LexDiff.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexDMAP.o: \\\n\t../lexers/LexDMAP.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexDMIS.o: \\\n\t../lexers/LexDMIS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexECL.o: \\\n\t../lexers/LexECL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h\n$(DIR_O)/LexEDIFACT.o: \\\n\t../lexers/LexEDIFACT.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexEiffel.o: \\\n\t../lexers/LexEiffel.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexErlang.o: \\\n\t../lexers/LexErlang.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexErrorList.o: \\\n\t../lexers/LexErrorList.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexEScript.o: \\\n\t../lexers/LexEScript.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexEscSeq.o: \\\n\t../lexers/LexEscSeq.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexFlagship.o: \\\n\t../lexers/LexFlagship.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexForth.o: \\\n\t../lexers/LexForth.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexFortran.o: \\\n\t../lexers/LexFortran.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexFSharp.o: \\\n\t../lexers/LexFSharp.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexGAP.o: \\\n\t../lexers/LexGAP.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexGDScript.o: \\\n\t../lexers/LexGDScript.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexGui4Cli.o: \\\n\t../lexers/LexGui4Cli.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexHaskell.o: \\\n\t../lexers/LexHaskell.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexHex.o: \\\n\t../lexers/LexHex.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexHollywood.o: \\\n\t../lexers/LexHollywood.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexHTML.o: \\\n\t../lexers/LexHTML.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexIndent.o: \\\n\t../lexers/LexIndent.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexInno.o: \\\n\t../lexers/LexInno.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexJSON.o: \\\n\t../lexers/LexJSON.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexJulia.o: \\\n\t../lexers/LexJulia.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexKix.o: \\\n\t../lexers/LexKix.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexKVIrc.o: \\\n\t../lexers/LexKVIrc.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexLaTeX.o: \\\n\t../lexers/LexLaTeX.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/DefaultLexer.h \\\n\t../lexlib/LexerBase.h\n$(DIR_O)/LexLisp.o: \\\n\t../lexers/LexLisp.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexLout.o: \\\n\t../lexers/LexLout.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexLua.o: \\\n\t../lexers/LexLua.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexMagik.o: \\\n\t../lexers/LexMagik.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMake.o: \\\n\t../lexers/LexMake.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexMarkdown.o: \\\n\t../lexers/LexMarkdown.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMatlab.o: \\\n\t../lexers/LexMatlab.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMaxima.o: \\\n\t../lexers/LexMaxima.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMetapost.o: \\\n\t../lexers/LexMetapost.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMMIXAL.o: \\\n\t../lexers/LexMMIXAL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexModula.o: \\\n\t../lexers/LexModula.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMPT.o: \\\n\t../lexers/LexMPT.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMSSQL.o: \\\n\t../lexers/LexMSSQL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMySQL.o: \\\n\t../lexers/LexMySQL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexNim.o: \\\n\t../lexers/LexNim.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexNimrod.o: \\\n\t../lexers/LexNimrod.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexNix.o: \\\n\t../lexers/LexNix.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexNsis.o: \\\n\t../lexers/LexNsis.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexNull.o: \\\n\t../lexers/LexNull.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexOpal.o: \\\n\t../lexers/LexOpal.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexOScript.o: \\\n\t../lexers/LexOScript.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPascal.o: \\\n\t../lexers/LexPascal.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexPB.o: \\\n\t../lexers/LexPB.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPerl.o: \\\n\t../lexers/LexPerl.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexPLM.o: \\\n\t../lexers/LexPLM.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPO.o: \\\n\t../lexers/LexPO.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPOV.o: \\\n\t../lexers/LexPOV.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPowerPro.o: \\\n\t../lexers/LexPowerPro.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPowerShell.o: \\\n\t../lexers/LexPowerShell.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexProgress.o: \\\n\t../lexers/LexProgress.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SparseState.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexProps.o: \\\n\t../lexers/LexProps.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPS.o: \\\n\t../lexers/LexPS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPython.o: \\\n\t../lexers/LexPython.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexR.o: \\\n\t../lexers/LexR.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexRaku.o: \\\n\t../lexers/LexRaku.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexRebol.o: \\\n\t../lexers/LexRebol.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexRegistry.o: \\\n\t../lexers/LexRegistry.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexRuby.o: \\\n\t../lexers/LexRuby.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexRust.o: \\\n\t../lexers/LexRust.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexSAS.o: \\\n\t../lexers/LexSAS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexScriptol.o: \\\n\t../lexers/LexScriptol.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSINEX.o: \\\n\t../lexers/LexSINEX.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSmalltalk.o: \\\n\t../lexers/LexSmalltalk.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSML.o: \\\n\t../lexers/LexSML.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSorcus.o: \\\n\t../lexers/LexSorcus.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSpecman.o: \\\n\t../lexers/LexSpecman.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSpice.o: \\\n\t../lexers/LexSpice.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSQL.o: \\\n\t../lexers/LexSQL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SparseState.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexStata.o: \\\n\t../lexers/LexStata.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSTTXT.o: \\\n\t../lexers/LexSTTXT.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTACL.o: \\\n\t../lexers/LexTACL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTADS3.o: \\\n\t../lexers/LexTADS3.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTAL.o: \\\n\t../lexers/LexTAL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTCL.o: \\\n\t../lexers/LexTCL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTCMD.o: \\\n\t../lexers/LexTCMD.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTeX.o: \\\n\t../lexers/LexTeX.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTOML.o: \\\n\t../lexers/LexTOML.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTroff.o: \\\n\t../lexers/LexTroff.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTxt2tags.o: \\\n\t../lexers/LexTxt2tags.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexVB.o: \\\n\t../lexers/LexVB.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexVerilog.o: \\\n\t../lexers/LexVerilog.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexVHDL.o: \\\n\t../lexers/LexVHDL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexVisualProlog.o: \\\n\t../lexers/LexVisualProlog.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexX12.o: \\\n\t../lexers/LexX12.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexYAML.o: \\\n\t../lexers/LexYAML.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexZig.o: \\\n\t../lexers/LexZig.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n"
  },
  {
    "path": "src/lexilla.mak",
    "content": "# Make file for Lexilla on Windows Visual C++ version\n# Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n# The License.txt file describes the conditions under which this software may be distributed.\n# This makefile is for using Visual C++ with nmake.\n# Usage for Microsoft:\n#     nmake -f lexilla.mak\n# For debug versions define DEBUG on the command line:\n#     nmake DEBUG=1 -f lexilla.mak\n# To build with GCC or Clang, run makefile\n#\n# Command line options\n#     DEBUG Debug build.\n#     QUIET Avoid most compiler invocation output and copyright info.\n#     SUPPORT_XP Build for Windows XP.\n\n.SUFFIXES: .cxx\n\nDIR_O=obj\nDIR_BIN=..\\bin\n\nLEXILLA=$(DIR_BIN)\\lexilla.dll\nLIBLEXILLA=$(DIR_BIN)\\liblexilla.lib\n\nLD=link\n\n!IF \"$(PLATFORM:64=)\" == \"arm\"\nARM64=1\n!ENDIF\n\n!IFDEF SUPPORT_XP\nADD_DEFINE=-D_USING_V110_SDK71_\n# Different subsystems for 32-bit and 64-bit Windows XP so detect based on Platform\n# environment variable set by vcvars*.bat to be either x86 or x64\n!IF \"$(PLATFORM)\" == \"x64\"\nSUBSYSTEM=-SUBSYSTEM:WINDOWS,5.02\n!ELSE\nSUBSYSTEM=-SUBSYSTEM:WINDOWS,5.01\n!ENDIF\n!ELSE\n!IFDEF ARM64\nADD_DEFINE=-D_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1\nSUBSYSTEM=-SUBSYSTEM:WINDOWS,10.00\n!ELSE\nCETCOMPAT=-CETCOMPAT\n!ENDIF\n!ENDIF\n\nCRTFLAGS=-D_CRT_SECURE_NO_DEPRECATE=1 $(ADD_DEFINE)\nCXXFLAGS=-Zi -TP -MP -W4 -EHsc -std:c++17 -utf-8 $(CRTFLAGS)\nCXXDEBUG=-Od -MTd -DDEBUG\nCXXNDEBUG=-O2 -MT -DNDEBUG -GL\nNAME=-Fo\nLDFLAGS=-OPT:REF -LTCG -IGNORE:4197 -DEBUG $(SUBSYSTEM) $(CETCOMPAT)\nLDDEBUG=\nLIBS=\nNOLOGO=-nologo\n\n!IFDEF QUIET\nCXX=@$(CXX)\nCXXFLAGS=$(CXXFLAGS) $(NOLOGO)\nLDFLAGS=$(LDFLAGS) $(NOLOGO)\n!ENDIF\n\n!IFDEF DEBUG\nCXXFLAGS=$(CXXFLAGS) $(CXXDEBUG)\nLDFLAGS=$(LDDEBUG) $(LDFLAGS)\n!ELSE\nCXXFLAGS=$(CXXFLAGS) $(CXXNDEBUG)\n!ENDIF\n\nSCINTILLA_INCLUDE = ../../scintilla/include\n\nINCLUDEDIRS=-I../include -I$(SCINTILLA_INCLUDE) -I../lexlib\nCXXFLAGS=$(CXXFLAGS) $(INCLUDEDIRS)\n\nall:\t$(SCINTILLA_INCLUDE) $(DIR_O) $(LEXILLA) $(LIBLEXILLA)\n\n$(DIR_O):\n\tmkdir \"$(DIR_O)\" 2>NUL || cd .\n\nclean:\n\t-del /q $(DIR_O)\\*.obj $(DIR_O)\\*.o $(DIR_O)\\*.pdb \\\n\t$(DIR_O)\\*.res $(DIR_BIN)\\*.map $(DIR_BIN)\\*.exp $(DIR_BIN)\\*.pdb $(DIR_BIN)\\lexilla.lib \\\n\t$(LEXILLA) $(LIBLEXILLA)\n\ndepend:\n\tpyw DepGen.py\n\n$(SCINTILLA_INCLUDE):\n\t@echo Scintilla must be installed at ../../scintilla to provide access to Scintilla headers.\n\n#++Autogenerated -- run scripts/LexGen.py to regenerate\n#**LEX_OBJS=\\\\\\n\\(\\t$(DIR_O)\\\\\\*.obj \\\\\\n\\)\nLEX_OBJS=\\\n\t$(DIR_O)\\LexA68k.obj \\\n\t$(DIR_O)\\LexAbaqus.obj \\\n\t$(DIR_O)\\LexAda.obj \\\n\t$(DIR_O)\\LexAPDL.obj \\\n\t$(DIR_O)\\LexAsciidoc.obj \\\n\t$(DIR_O)\\LexAsm.obj \\\n\t$(DIR_O)\\LexAsn1.obj \\\n\t$(DIR_O)\\LexASY.obj \\\n\t$(DIR_O)\\LexAU3.obj \\\n\t$(DIR_O)\\LexAVE.obj \\\n\t$(DIR_O)\\LexAVS.obj \\\n\t$(DIR_O)\\LexBaan.obj \\\n\t$(DIR_O)\\LexBash.obj \\\n\t$(DIR_O)\\LexBasic.obj \\\n\t$(DIR_O)\\LexBatch.obj \\\n\t$(DIR_O)\\LexBibTeX.obj \\\n\t$(DIR_O)\\LexBullant.obj \\\n\t$(DIR_O)\\LexCaml.obj \\\n\t$(DIR_O)\\LexCIL.obj \\\n\t$(DIR_O)\\LexCLW.obj \\\n\t$(DIR_O)\\LexCmake.obj \\\n\t$(DIR_O)\\LexCOBOL.obj \\\n\t$(DIR_O)\\LexCoffeeScript.obj \\\n\t$(DIR_O)\\LexConf.obj \\\n\t$(DIR_O)\\LexCPP.obj \\\n\t$(DIR_O)\\LexCrontab.obj \\\n\t$(DIR_O)\\LexCsound.obj \\\n\t$(DIR_O)\\LexCSS.obj \\\n\t$(DIR_O)\\LexD.obj \\\n\t$(DIR_O)\\LexDart.obj \\\n\t$(DIR_O)\\LexDataflex.obj \\\n\t$(DIR_O)\\LexDiff.obj \\\n\t$(DIR_O)\\LexDMAP.obj \\\n\t$(DIR_O)\\LexDMIS.obj \\\n\t$(DIR_O)\\LexECL.obj \\\n\t$(DIR_O)\\LexEDIFACT.obj \\\n\t$(DIR_O)\\LexEiffel.obj \\\n\t$(DIR_O)\\LexErlang.obj \\\n\t$(DIR_O)\\LexErrorList.obj \\\n\t$(DIR_O)\\LexEScript.obj \\\n\t$(DIR_O)\\LexEscSeq.obj \\\n\t$(DIR_O)\\LexFlagship.obj \\\n\t$(DIR_O)\\LexForth.obj \\\n\t$(DIR_O)\\LexFortran.obj \\\n\t$(DIR_O)\\LexFSharp.obj \\\n\t$(DIR_O)\\LexGAP.obj \\\n\t$(DIR_O)\\LexGDScript.obj \\\n\t$(DIR_O)\\LexGui4Cli.obj \\\n\t$(DIR_O)\\LexHaskell.obj \\\n\t$(DIR_O)\\LexHex.obj \\\n\t$(DIR_O)\\LexHollywood.obj \\\n\t$(DIR_O)\\LexHTML.obj \\\n\t$(DIR_O)\\LexIndent.obj \\\n\t$(DIR_O)\\LexInno.obj \\\n\t$(DIR_O)\\LexJSON.obj \\\n\t$(DIR_O)\\LexJulia.obj \\\n\t$(DIR_O)\\LexKix.obj \\\n\t$(DIR_O)\\LexKVIrc.obj \\\n\t$(DIR_O)\\LexLaTeX.obj \\\n\t$(DIR_O)\\LexLisp.obj \\\n\t$(DIR_O)\\LexLout.obj \\\n\t$(DIR_O)\\LexLua.obj \\\n\t$(DIR_O)\\LexMagik.obj \\\n\t$(DIR_O)\\LexMake.obj \\\n\t$(DIR_O)\\LexMarkdown.obj \\\n\t$(DIR_O)\\LexMatlab.obj \\\n\t$(DIR_O)\\LexMaxima.obj \\\n\t$(DIR_O)\\LexMetapost.obj \\\n\t$(DIR_O)\\LexMMIXAL.obj \\\n\t$(DIR_O)\\LexModula.obj \\\n\t$(DIR_O)\\LexMPT.obj \\\n\t$(DIR_O)\\LexMSSQL.obj \\\n\t$(DIR_O)\\LexMySQL.obj \\\n\t$(DIR_O)\\LexNim.obj \\\n\t$(DIR_O)\\LexNimrod.obj \\\n\t$(DIR_O)\\LexNix.obj \\\n\t$(DIR_O)\\LexNsis.obj \\\n\t$(DIR_O)\\LexNull.obj \\\n\t$(DIR_O)\\LexOpal.obj \\\n\t$(DIR_O)\\LexOScript.obj \\\n\t$(DIR_O)\\LexPascal.obj \\\n\t$(DIR_O)\\LexPB.obj \\\n\t$(DIR_O)\\LexPerl.obj \\\n\t$(DIR_O)\\LexPLM.obj \\\n\t$(DIR_O)\\LexPO.obj \\\n\t$(DIR_O)\\LexPOV.obj \\\n\t$(DIR_O)\\LexPowerPro.obj \\\n\t$(DIR_O)\\LexPowerShell.obj \\\n\t$(DIR_O)\\LexProgress.obj \\\n\t$(DIR_O)\\LexProps.obj \\\n\t$(DIR_O)\\LexPS.obj \\\n\t$(DIR_O)\\LexPython.obj \\\n\t$(DIR_O)\\LexR.obj \\\n\t$(DIR_O)\\LexRaku.obj \\\n\t$(DIR_O)\\LexRebol.obj \\\n\t$(DIR_O)\\LexRegistry.obj \\\n\t$(DIR_O)\\LexRuby.obj \\\n\t$(DIR_O)\\LexRust.obj \\\n\t$(DIR_O)\\LexSAS.obj \\\n\t$(DIR_O)\\LexScriptol.obj \\\n\t$(DIR_O)\\LexSINEX.obj \\\n\t$(DIR_O)\\LexSmalltalk.obj \\\n\t$(DIR_O)\\LexSML.obj \\\n\t$(DIR_O)\\LexSorcus.obj \\\n\t$(DIR_O)\\LexSpecman.obj \\\n\t$(DIR_O)\\LexSpice.obj \\\n\t$(DIR_O)\\LexSQL.obj \\\n\t$(DIR_O)\\LexStata.obj \\\n\t$(DIR_O)\\LexSTTXT.obj \\\n\t$(DIR_O)\\LexTACL.obj \\\n\t$(DIR_O)\\LexTADS3.obj \\\n\t$(DIR_O)\\LexTAL.obj \\\n\t$(DIR_O)\\LexTCL.obj \\\n\t$(DIR_O)\\LexTCMD.obj \\\n\t$(DIR_O)\\LexTeX.obj \\\n\t$(DIR_O)\\LexTOML.obj \\\n\t$(DIR_O)\\LexTroff.obj \\\n\t$(DIR_O)\\LexTxt2tags.obj \\\n\t$(DIR_O)\\LexVB.obj \\\n\t$(DIR_O)\\LexVerilog.obj \\\n\t$(DIR_O)\\LexVHDL.obj \\\n\t$(DIR_O)\\LexVisualProlog.obj \\\n\t$(DIR_O)\\LexX12.obj \\\n\t$(DIR_O)\\LexYAML.obj \\\n\t$(DIR_O)\\LexZig.obj \\\n\n#--Autogenerated -- end of automatically generated section\n\n# Required by lexers\nLEXLIB_OBJS=\\\n\t$(DIR_O)\\Accessor.obj \\\n\t$(DIR_O)\\CharacterCategory.obj \\\n\t$(DIR_O)\\CharacterSet.obj \\\n\t$(DIR_O)\\DefaultLexer.obj \\\n\t$(DIR_O)\\InList.obj \\\n\t$(DIR_O)\\LexAccessor.obj \\\n\t$(DIR_O)\\LexerBase.obj \\\n\t$(DIR_O)\\LexerModule.obj \\\n\t$(DIR_O)\\LexerSimple.obj \\\n\t$(DIR_O)\\PropSetSimple.obj \\\n\t$(DIR_O)\\StyleContext.obj \\\n\t$(DIR_O)\\WordList.obj\n\n# Required by libraries and DLLs that include lexing\nLEXILLA_OBJS=\\\n\t$(DIR_O)\\Lexilla.obj \\\n\t$(LEXLIB_OBJS) \\\n\t$(LEX_OBJS)\n\n$(LEXILLA): $(LEXILLA_OBJS) $(DIR_O)\\LexillaVersion.res\n\t$(LD) $(LDFLAGS) -DEF:Lexilla.def -DLL -OUT:$@ $** $(LIBS)\n\n$(LIBLEXILLA): $(LEXILLA_OBJS)\n\tLIB -OUT:$@ $**\n\n# Define how to build all the objects and what they depend on\n\n{..\\lexlib}.cxx{$(DIR_O)}.obj::\n\t$(CXX) $(CXXFLAGS) -c $(NAME)$(DIR_O)\\ $<\n{..\\lexers}.cxx{$(DIR_O)}.obj::\n\t$(CXX) $(CXXFLAGS) -c $(NAME)$(DIR_O)\\ $<\n{.}.cxx{$(DIR_O)}.obj::\n\t$(CXX) $(CXXFLAGS) -c $(NAME)$(DIR_O)\\ $<\n\n.rc{$(DIR_O)}.res:\n\t$(RC) -fo$@ $**\n\n# Dependencies\n\n!IF EXISTS(nmdeps.mak)\n\n# Protect with !IF EXISTS to handle accidental deletion - just 'nmake -f lexilla.mak deps'\n\n!INCLUDE nmdeps.mak\n\n!ENDIF\n"
  },
  {
    "path": "src/makefile",
    "content": "# Make file for Lexilla\n# @file makefile\n# Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n# The License.txt file describes the conditions under which this software may be distributed.\n# This works on Windows or Linux using GCC 9.0+\n# This works on Windows, Linux, or macOS using Clang 9.0+\n# On Windows, it is tested with Mingw-w64 GCC and Clang.\n# on macOS, it always uses Clang\n# For debug versions define DEBUG on the command line:\n#     make DEBUG=1\n# On Windows, to build with MSVC, run lexilla.mak\n\n.PHONY: all clean analyze depend\n\n.SUFFIXES: .cxx\n\nDIR_O=.\nDIR_BIN=../bin\n\nWARNINGS = -Wpedantic -Wall -Wextra\n\nifdef windir\n    SHARED_NAME = lexilla\n    SHAREDEXTENSION = dll\n    WINDRES ?= windres\n    VERSION_RESOURCE = $(DIR_O)/LexillaVersion.o\nelse\n    SHARED_NAME = liblexilla\n    ifeq ($(shell uname),Darwin)\n        CLANG := 1\n        LDFLAGS += -dynamiclib\n        SHAREDEXTENSION = dylib\n        BASE_FLAGS += -arch arm64 -arch x86_64\n        LDFLAGS += -arch arm64 -arch x86_64\n    else\n        SHAREDEXTENSION = so\n    endif\n    BASE_FLAGS += -fvisibility=hidden\nendif\n\nLEXILLA=$(DIR_BIN)/$(SHARED_NAME).$(SHAREDEXTENSION)\nLIBLEXILLA=$(DIR_BIN)/liblexilla.a\n\nBASE_FLAGS += --std=c++17\n\nifdef CLANG\nCXX = clang++\nifdef windir\n# Clang on Win32 uses MSVC headers so will complain about strcpy without this\nDEFINES += -D_CRT_SECURE_NO_DEPRECATE=1\nendif\nendif\n\nifdef windir\n    LDFLAGS += -mwindows\n\tifndef CLANG\n\t    LDFLAGS += -Wl,--kill-at\n\tendif\nelse\n    BASE_FLAGS += -fPIC\nendif\n\n# Take care of changing Unix style '/' directory separator to '\\' on Windows\nnormalize = $(if $(windir),$(subst /,\\,$1),$1)\n\nPYTHON = $(if $(windir),pyw,python3)\n\nifdef windir\n    DEL = $(if $(wildcard $(dir $(SHELL))rm.exe), $(dir $(SHELL))rm.exe -f, del /q)\nelse\n    DEL = rm -f\nendif\n\nRANLIB ?= ranlib\n\nSCINTILLA_INCLUDE = ../../scintilla/include\n\nvpath %.h ../include ../../scintilla/include ../lexlib\nvpath %.cxx ../src ../lexlib ../lexers\n\nDEFINES += -D$(if $(DEBUG),DEBUG,NDEBUG)\nBASE_FLAGS += $(if $(DEBUG),-g,-O3)\n\nINCLUDES = -I ../include -I $(SCINTILLA_INCLUDE) -I ../lexlib\nLDFLAGS += -shared\n\nBASE_FLAGS += $(WARNINGS)\n\nall:\t$(SCINTILLA_INCLUDE) $(LEXILLA) $(LIBLEXILLA)\n\nclean:\n\t$(DEL) $(call normalize, $(addprefix $(DIR_O)/, *.o *.obj *.a *.res *.map *.plist) $(LEXILLA) $(LIBLEXILLA))\n\n$(DIR_O)/%.o: %.cxx\n\t$(CXX) $(DEFINES) $(INCLUDES) $(BASE_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@\n\n$(DIR_O)/%.o: %.rc\n\t$(WINDRES) $< $@\n\nanalyze:\n\t$(CXX) --analyze $(DEFINES) $(INCLUDES) $(BASE_FLAGS) $(CXXFLAGS) *.cxx ../lexlib/*.cxx ../lexers/*.cxx\n\ndepend deps.mak:\n\t$(PYTHON) DepGen.py\n\n$(SCINTILLA_INCLUDE):\n\t@echo Scintilla must be installed at ../../scintilla to provide access to Scintilla headers.\n\nLEXERS:=$(sort $(notdir $(wildcard ../lexers/Lex*.cxx)))\n\nOBJS = Lexilla.o\n\n# Required by lexers\nLEXLIB_OBJS=\\\n\tAccessor.o \\\n\tCharacterCategory.o \\\n\tCharacterSet.o \\\n\tDefaultLexer.o \\\n\tInList.o \\\n\tLexAccessor.o \\\n\tLexerBase.o \\\n\tLexerModule.o \\\n\tLexerSimple.o \\\n\tPropSetSimple.o \\\n\tStyleContext.o \\\n\tWordList.o\n\n# Required by libraries and DLLs that include lexing\nLEXILLA_OBJS := $(addprefix $(DIR_O)/, $(OBJS) $(LEXLIB_OBJS) $(LEXERS:.cxx=.o))\n\n$(LEXILLA): $(LEXILLA_OBJS) $(VERSION_RESOURCE)\n\t$(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@\n\n$(LIBLEXILLA):  $(LEXILLA_OBJS)\nifeq ($(SHAREDEXTENSION),dylib)\n\tlibtool -static -o $@ $^\nelse\n\t$(AR) rc $@ $^\n\t$(RANLIB) $@\nendif\n\n# Automatically generate dependencies for most files with \"make deps\"\ninclude deps.mak\n"
  },
  {
    "path": "src/nmdeps.mak",
    "content": "# Created by DepGen.py. To recreate, run DepGen.py.\n$(DIR_O)/Lexilla.obj: \\\n\t../src/Lexilla.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/CatalogueModules.h\n$(DIR_O)/Accessor.obj: \\\n\t../lexlib/Accessor.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h\n$(DIR_O)/CharacterCategory.obj: \\\n\t../lexlib/CharacterCategory.cxx \\\n\t../lexlib/CharacterCategory.h\n$(DIR_O)/CharacterSet.obj: \\\n\t../lexlib/CharacterSet.cxx \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/DefaultLexer.obj: \\\n\t../lexlib/DefaultLexer.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/InList.obj: \\\n\t../lexlib/InList.cxx \\\n\t../lexlib/InList.h \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/LexAccessor.obj: \\\n\t../lexlib/LexAccessor.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/LexerBase.obj: \\\n\t../lexlib/LexerBase.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/LexerBase.h\n$(DIR_O)/LexerModule.obj: \\\n\t../lexlib/LexerModule.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/LexerBase.h \\\n\t../lexlib/LexerSimple.h\n$(DIR_O)/LexerSimple.obj: \\\n\t../lexlib/LexerSimple.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/LexerBase.h \\\n\t../lexlib/LexerSimple.h\n$(DIR_O)/PropSetSimple.obj: \\\n\t../lexlib/PropSetSimple.cxx \\\n\t../lexlib/PropSetSimple.h\n$(DIR_O)/StyleContext.obj: \\\n\t../lexlib/StyleContext.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/WordList.obj: \\\n\t../lexlib/WordList.cxx \\\n\t../lexlib/WordList.h \\\n\t../lexlib/CharacterSet.h\n$(DIR_O)/LexA68k.obj: \\\n\t../lexers/LexA68k.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAbaqus.obj: \\\n\t../lexers/LexAbaqus.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAda.obj: \\\n\t../lexers/LexAda.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAPDL.obj: \\\n\t../lexers/LexAPDL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAsciidoc.obj: \\\n\t../lexers/LexAsciidoc.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAsm.obj: \\\n\t../lexers/LexAsm.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexAsn1.obj: \\\n\t../lexers/LexAsn1.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexASY.obj: \\\n\t../lexers/LexASY.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAU3.obj: \\\n\t../lexers/LexAU3.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAVE.obj: \\\n\t../lexers/LexAVE.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexAVS.obj: \\\n\t../lexers/LexAVS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexBaan.obj: \\\n\t../lexers/LexBaan.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexBash.obj: \\\n\t../lexers/LexBash.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexBasic.obj: \\\n\t../lexers/LexBasic.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexBatch.obj: \\\n\t../lexers/LexBatch.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexBibTeX.obj: \\\n\t../lexers/LexBibTeX.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexBullant.obj: \\\n\t../lexers/LexBullant.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCaml.obj: \\\n\t../lexers/LexCaml.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCIL.obj: \\\n\t../lexers/LexCIL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexCLW.obj: \\\n\t../lexers/LexCLW.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCmake.obj: \\\n\t../lexers/LexCmake.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCOBOL.obj: \\\n\t../lexers/LexCOBOL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCoffeeScript.obj: \\\n\t../lexers/LexCoffeeScript.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexConf.obj: \\\n\t../lexers/LexConf.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCPP.obj: \\\n\t../lexers/LexCPP.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SparseState.h \\\n\t../lexlib/SubStyles.h\n$(DIR_O)/LexCrontab.obj: \\\n\t../lexers/LexCrontab.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCsound.obj: \\\n\t../lexers/LexCsound.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexCSS.obj: \\\n\t../lexers/LexCSS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexD.obj: \\\n\t../lexers/LexD.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexDart.obj: \\\n\t../lexers/LexDart.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexDataflex.obj: \\\n\t../lexers/LexDataflex.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexDiff.obj: \\\n\t../lexers/LexDiff.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexDMAP.obj: \\\n\t../lexers/LexDMAP.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexDMIS.obj: \\\n\t../lexers/LexDMIS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexECL.obj: \\\n\t../lexers/LexECL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h\n$(DIR_O)/LexEDIFACT.obj: \\\n\t../lexers/LexEDIFACT.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexEiffel.obj: \\\n\t../lexers/LexEiffel.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexErlang.obj: \\\n\t../lexers/LexErlang.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexErrorList.obj: \\\n\t../lexers/LexErrorList.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexEScript.obj: \\\n\t../lexers/LexEScript.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexEscSeq.obj: \\\n\t../lexers/LexEscSeq.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexFlagship.obj: \\\n\t../lexers/LexFlagship.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexForth.obj: \\\n\t../lexers/LexForth.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexFortran.obj: \\\n\t../lexers/LexFortran.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexFSharp.obj: \\\n\t../lexers/LexFSharp.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexGAP.obj: \\\n\t../lexers/LexGAP.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexGDScript.obj: \\\n\t../lexers/LexGDScript.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexGui4Cli.obj: \\\n\t../lexers/LexGui4Cli.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexHaskell.obj: \\\n\t../lexers/LexHaskell.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexHex.obj: \\\n\t../lexers/LexHex.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexHollywood.obj: \\\n\t../lexers/LexHollywood.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexHTML.obj: \\\n\t../lexers/LexHTML.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexIndent.obj: \\\n\t../lexers/LexIndent.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexInno.obj: \\\n\t../lexers/LexInno.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexJSON.obj: \\\n\t../lexers/LexJSON.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexJulia.obj: \\\n\t../lexers/LexJulia.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexKix.obj: \\\n\t../lexers/LexKix.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexKVIrc.obj: \\\n\t../lexers/LexKVIrc.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexLaTeX.obj: \\\n\t../lexers/LexLaTeX.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/DefaultLexer.h \\\n\t../lexlib/LexerBase.h\n$(DIR_O)/LexLisp.obj: \\\n\t../lexers/LexLisp.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexLout.obj: \\\n\t../lexers/LexLout.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexLua.obj: \\\n\t../lexers/LexLua.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexMagik.obj: \\\n\t../lexers/LexMagik.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMake.obj: \\\n\t../lexers/LexMake.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexMarkdown.obj: \\\n\t../lexers/LexMarkdown.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMatlab.obj: \\\n\t../lexers/LexMatlab.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMaxima.obj: \\\n\t../lexers/LexMaxima.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMetapost.obj: \\\n\t../lexers/LexMetapost.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMMIXAL.obj: \\\n\t../lexers/LexMMIXAL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexModula.obj: \\\n\t../lexers/LexModula.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMPT.obj: \\\n\t../lexers/LexMPT.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMSSQL.obj: \\\n\t../lexers/LexMSSQL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexMySQL.obj: \\\n\t../lexers/LexMySQL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexNim.obj: \\\n\t../lexers/LexNim.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/StringCopy.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexNimrod.obj: \\\n\t../lexers/LexNimrod.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexNix.obj: \\\n\t../lexers/LexNix.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexNsis.obj: \\\n\t../lexers/LexNsis.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexNull.obj: \\\n\t../lexers/LexNull.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexOpal.obj: \\\n\t../lexers/LexOpal.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexOScript.obj: \\\n\t../lexers/LexOScript.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPascal.obj: \\\n\t../lexers/LexPascal.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexPB.obj: \\\n\t../lexers/LexPB.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPerl.obj: \\\n\t../lexers/LexPerl.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexPLM.obj: \\\n\t../lexers/LexPLM.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPO.obj: \\\n\t../lexers/LexPO.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPOV.obj: \\\n\t../lexers/LexPOV.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPowerPro.obj: \\\n\t../lexers/LexPowerPro.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPowerShell.obj: \\\n\t../lexers/LexPowerShell.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexProgress.obj: \\\n\t../lexers/LexProgress.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SparseState.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexProps.obj: \\\n\t../lexers/LexProps.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPS.obj: \\\n\t../lexers/LexPS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexPython.obj: \\\n\t../lexers/LexPython.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexR.obj: \\\n\t../lexers/LexR.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexRaku.obj: \\\n\t../lexers/LexRaku.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexRebol.obj: \\\n\t../lexers/LexRebol.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexRegistry.obj: \\\n\t../lexers/LexRegistry.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexRuby.obj: \\\n\t../lexers/LexRuby.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/InList.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexRust.obj: \\\n\t../lexers/LexRust.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/PropSetSimple.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexSAS.obj: \\\n\t../lexers/LexSAS.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexScriptol.obj: \\\n\t../lexers/LexScriptol.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSINEX.obj: \\\n\t../lexers/LexSINEX.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSmalltalk.obj: \\\n\t../lexers/LexSmalltalk.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSML.obj: \\\n\t../lexers/LexSML.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSorcus.obj: \\\n\t../lexers/LexSorcus.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSpecman.obj: \\\n\t../lexers/LexSpecman.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSpice.obj: \\\n\t../lexers/LexSpice.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSQL.obj: \\\n\t../lexers/LexSQL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SparseState.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexStata.obj: \\\n\t../lexers/LexStata.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexSTTXT.obj: \\\n\t../lexers/LexSTTXT.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTACL.obj: \\\n\t../lexers/LexTACL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTADS3.obj: \\\n\t../lexers/LexTADS3.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTAL.obj: \\\n\t../lexers/LexTAL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTCL.obj: \\\n\t../lexers/LexTCL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTCMD.obj: \\\n\t../lexers/LexTCMD.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTeX.obj: \\\n\t../lexers/LexTeX.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTOML.obj: \\\n\t../lexers/LexTOML.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTroff.obj: \\\n\t../lexers/LexTroff.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexTxt2tags.obj: \\\n\t../lexers/LexTxt2tags.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexVB.obj: \\\n\t../lexers/LexVB.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexVerilog.obj: \\\n\t../lexers/LexVerilog.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/SubStyles.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexVHDL.obj: \\\n\t../lexers/LexVHDL.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexVisualProlog.obj: \\\n\t../lexers/LexVisualProlog.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/CharacterCategory.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexX12.obj: \\\n\t../lexers/LexX12.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/DefaultLexer.h\n$(DIR_O)/LexYAML.obj: \\\n\t../lexers/LexYAML.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h\n$(DIR_O)/LexZig.obj: \\\n\t../lexers/LexZig.cxx \\\n\t../../scintilla/include/ILexer.h \\\n\t../../scintilla/include/Sci_Position.h \\\n\t../../scintilla/include/Scintilla.h \\\n\t../include/SciLexer.h \\\n\t../lexlib/WordList.h \\\n\t../lexlib/LexAccessor.h \\\n\t../lexlib/Accessor.h \\\n\t../lexlib/StyleContext.h \\\n\t../lexlib/CharacterSet.h \\\n\t../lexlib/LexerModule.h \\\n\t../lexlib/OptionSet.h \\\n\t../lexlib/DefaultLexer.h\n"
  },
  {
    "path": "test/Metadata/CheckMeta.py",
    "content": "#!/usr/bin/env python\n# CheckMeta.py\n# Released to the public domain.\n\n# Check that LexicalClass data in lexer source files is valid and matches LexicalStyles.iface.\n# Check that lexerMetadata.txt matches LexicalStyles.iface.\n# Requires Python 3.6 or later\n\nimport pathlib\n\nneutralEncoding = \"iso-8859-1\"\t# Each byte value is valid in iso-8859-1\n\ndef ShowAll(rootLexilla):\n\n\tsuccess = True\n\n\tstyles = {}\n\twith open(rootLexilla / \"include\" / \"LexicalStyles.iface\", encoding=neutralEncoding) as f:\n\t\tfor line in f:\n\t\t\tif line.startswith(\"val\") and \"SCE_\" in line:\n\t\t\t\t# val SCE_MAXIMA_OPERATOR=0\n\t\t\t\t_, nameVal = line.strip().split(\" \")\n\t\t\t\tname, val = nameVal.split(\"=\")\n\t\t\t\tstyles[name] = val\n\n\twith open(rootLexilla / \"test\" / \"Metadata\" / \"lexerMetadata.txt\", encoding=neutralEncoding) as f:\n\t\tfor line in f:\n\t\t\tif \" SCE_\" in line:\n\t\t\t\t# 0 SCE_C_DEFAULT [default] White space\n\t\t\t\tval, name, *_ = line.strip().split(\" \")\n\t\t\t\tif name in styles:\n\t\t\t\t\tif val != styles[name]:\n\t\t\t\t\t\tsuccess = False\n\t\t\t\t\t\tprint(f\"Different style {name} {val} {styles[name]}\")\n\t\t\t\telse:\n\t\t\t\t\tsuccess = False\n\t\t\t\t\tprint(f\"Missing style name {name}\")\n\n\tlexFilePaths = list((rootLexilla / \"lexers\").glob(\"Lex*.cxx\"))\n\tlexFilePaths.sort(key=lambda p: str(p).casefold())\n\n\tfor lexFile in lexFilePaths:\n\t\twith open(lexFile, encoding=neutralEncoding) as f:\n\t\t\tinsideLexicalClass = False\n\t\t\tfor line in f:\n\t\t\t\tif insideLexicalClass and '\"' in line and ',' in line:\n\t\t\t\t\t# 0, \"SCE_C_DEFAULT\", \"default\", \"White space\",\n\t\t\t\t\tval, name, *_ = line.strip().split(',')\n\t\t\t\t\tname = name.strip(' \\t\"')\n\t\t\t\t\tif name:\n\t\t\t\t\t\tif name not in styles:\n\t\t\t\t\t\t\tsuccess = False\n\t\t\t\t\t\t\tprint(f\"Missing name: {lexFile} {name}\")\n\t\t\t\t\t\telif val != styles[name]:\n\t\t\t\t\t\t\tsuccess = False\n\t\t\t\t\t\t\tprint(f\"Wrong value: {lexFile} {name} {val} {styles[name]}\")\n\t\t\t\tif \"LexicalClass\" in line:\n\t\t\t\t\tinsideLexicalClass = True\n\t\t\t\telif \"};\" in line:\n\t\t\t\t\tinsideLexicalClass = False\n\n\treturn success\n\nif __name__== \"__main__\":\n\tif not ShowAll(pathlib.Path(\"../..\")):\n\t\texit(1)\n"
  },
  {
    "path": "test/Metadata/Metadata.cxx",
    "content": "// Lexilla metadata list\n/** @file Metadata.cxx\n ** List metadata of Lexilla shared library or check that it is the same as before\n **/\n// Copyright 2026 by Neil Hodgson <neilh@scintilla.org>\n// This file is in the public domain.\n// If the public domain is not possible in your location then it can also be used under the same\n// license as Scintilla. https://www.scintilla.org/License.txt\n\n/*\n\nBuild\n\n    All platforms with g++ or clang\n        make\n\n    Win32 Visual C++\n        cl Metadata.cxx ../../access/LexillaAccess.cxx -EHsc -std:c++20 -I ../../include -I ../../access -I ../../../scintilla/include -Fe: Metadata\n\nUsing\n\n    List metadata of standard Lexilla shared library in lexilla/bin.\n        Metadata\n\n    List metadata of particular shared library conforming to Lexilla protocol\n        Metadata ../../examples/SimpleLexer/SimpleLexer.dll\n\n    Check that metadata of standard Lexilla is the same as lexerMetadata.txt.\n    If different, new version placed in lexerMetadata.txt.new.\n        Metadata -check\n\n*/\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <iostream>\n#include <sstream>\n#include <fstream>\n#include <iomanip>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n#include \"Lexilla.h\"\n\n#include \"LexillaAccess.h\"\n\nusing namespace Lexilla;\n\nnamespace {\n\nstd::vector<std::string> StringSplit(const std::string_view &text, int separator) {\n\tstd::vector<std::string> vs(text.empty() ? 0 : 1);\n\tfor (const char ch : text) {\n\t\tif (ch == separator) {\n\t\t\tvs.push_back(std::string());\n\t\t} else {\n\t\t\tvs.back() += ch;\n\t\t}\n\t}\n\treturn vs;\n}\n\nconst char *translateType(int n) {\n\tswitch(n) {\n\t\tcase SC_TYPE_BOOLEAN: return \"bool  \";\n\t\tcase SC_TYPE_INTEGER: return \"int   \";\n\t\tcase SC_TYPE_STRING: return \"string\";\n\t\tdefault: return \"error \";\n\t}\n}\n\nvoid ShowMetadata(std::ostringstream &os, ILexer5 *lexer) {\n\tconst int lineEnds = lexer->LineEndTypesSupported();\n\tif (lineEnds == SC_LINE_END_TYPE_UNICODE) {\n\t\tos << \"    UnicodeLineEnds\\n\";\n\t}\n\tconst char *propertyNames = lexer->PropertyNames();\n\tif (propertyNames && *propertyNames) {\n\t\tos << \"    Properties:\\n\";\n\t\tstd::vector<std::string> properties = StringSplit(propertyNames, '\\n');\n\t\tfor (const auto &p : properties) {\n\t\t\tconst char *type = translateType(lexer->PropertyType(p.c_str()));\n\t\t\tconst char *description = lexer->DescribeProperty(p.c_str());\n\t\t\tos << \"        \" << type << \" \" << p << \"\\n\";\n\t\t\tif (description && *description) {\n\t\t\t\tos << \"               \" << description << \"\\n\";\n\t\t\t}\n\t\t}\n\t}\n\tconst char *wordListSets = lexer->DescribeWordListSets();\n\tif (wordListSets && *wordListSets) {\n\t\tos << \"    Word Lists:\\n\";\n\t\tstd::vector<std::string> wordLists = StringSplit(wordListSets, '\\n');\n\t\tfor (const auto &wl : wordLists) {\n\t\t\tos << \"        \" << wl << \"\\n\";\n\t\t}\n\t}\n\tconst char *bases = lexer->GetSubStyleBases();\n\tif (bases && *bases) {\n\t\tos << \"    Sub-Style Bases:\\n\";\n\t\twhile (*bases) {\n\t\t\tos << \"        \" << std::setw(3) << static_cast<int>(*bases) << \"\\n\";\n\t\t\tbases++;\n\t\t}\n\t}\n\tconst int namedStyles = lexer->NamedStyles();\n\tif (namedStyles > 0) {\n\t\tos << \"    Styles:\\n\";\n\t\tfor (int s=0; s<namedStyles; s++) {\n\t\t\tconst char *nameStyle = lexer->NameOfStyle(s);\n\t\t\tconst char *tags = lexer->TagsOfStyle(s);\n\t\t\tconst char *description = lexer->DescriptionOfStyle(s);\n\t\t\tif (*nameStyle || *tags) {\n\t\t\t\tos << \"        \" << std::setw(3) << s << \" \" << nameStyle << \" [\" << tags << \"] \" << description << \"\\n\";\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid ShowAllMetadata(std::ostringstream &os, const std::vector<std::string> &lexers) {\n\tfor (const auto &name : lexers) {\n\t\tILexer5 *lexer = MakeLexer(name);\n\t\tif (lexer) {\n\t\t\tos << \"\\nLexer \" << name << \"\\n\";\n\t\t\tShowMetadata(os, lexer);\n\t\t\tlexer->Release();\n\t\t} else {\n\t\t\tos << \"\\n  \" << name << \" Missing\\n\";\n\t\t}\n\t}\n\tos << \"\\n\";\n}\n\n}\n\nint main(int argc, char *argv[]) {\n\tconst char szLexillaPath[] = \"../../bin/\" LEXILLA_LIB LEXILLA_EXTENSION;\n\tconst char *libPath = szLexillaPath;\n\tbool checking = false;\n\tif (argc > 1) {\n\t\tfor (int arg=1; arg<argc; arg++) {\n\t\t\tif (argv[arg][0] == '-') {\n\t\t\t\tif (std::string_view(argv[arg]) == \"-check\") {\n\t\t\t\t\tchecking = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlibPath = argv[arg];\n\t\t\t}\n\t\t}\n\t}\n\tif (!Load(libPath)) {\n\t\tstd::cerr << \"Could not load \" << libPath << \"\\n\";\n\t\treturn 1;\n\t}\n\tconst std::vector<std::string> lexers = Lexers();\n\tif (!lexers.empty()) {\n\t\tstd::ostringstream os(std::ios::binary);\n\t\tos << \"There are \" << lexers.size() << \" lexers.\\n\";\n\t\tfor (const auto &name : lexers) {\n\t\t\tos << \"    \" << name << \"\\n\";\n\t\t}\n\t\tos << \"\\n\";\n\n\t\tShowAllMetadata(os, lexers);\n\n\t\tconst std::string sMetadata = os.str();\n\t\tif (checking) {\n\t\t\tstd::ifstream ifs(\"lexerMetadata.txt\");\n\t\t\tstd::string content((std::istreambuf_iterator<char>(ifs)),\n\t\t\t\t(std::istreambuf_iterator<char>()));\n\t\t\tif (content != sMetadata) {\n\t\t\t\tstd::cerr << \"Different metadata\\n\";\n\t\t\t\tstd::ofstream ofs(\"lexerMetadata.txt.new\");\n\t\t\t\tofs << sMetadata;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t} else {\n\t\t\tstd::cout << sMetadata;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/Metadata/lexerMetadata.txt",
    "content": "There are 139 lexers.\n    a68k\n    abaqus\n    ada\n    apdl\n    as\n    asciidoc\n    asm\n    asn1\n    asy\n    au3\n    ave\n    avs\n    baan\n    bash\n    batch\n    bib\n    blitzbasic\n    bullant\n    caml\n    cil\n    clarion\n    clarionnocase\n    cmake\n    COBOL\n    coffeescript\n    conf\n    cpp\n    cppnocase\n    csound\n    css\n    d\n    dart\n    dataflex\n    diff\n    DMAP\n    DMIS\n    ecl\n    edifact\n    eiffel\n    eiffelkw\n    erlang\n    errorlist\n    escript\n    escseq\n    f77\n    flagship\n    forth\n    fortran\n    freebasic\n    fsharp\n    gap\n    gdscript\n    gui4cli\n    haskell\n    hollywood\n    hypertext\n    ihex\n    indent\n    inno\n    json\n    julia\n    kix\n    kvirc\n    latex\n    lisp\n    literatehaskell\n    lot\n    lout\n    lua\n    magiksf\n    makefile\n    markdown\n    matlab\n    maxima\n    metapost\n    mmixal\n    modula\n    mssql\n    mysql\n    nim\n    nimrod\n    nix\n    nncrontab\n    nsis\n    null\n    octave\n    opal\n    oscript\n    pascal\n    powerbasic\n    perl\n    phpscript\n    PL/M\n    po\n    pov\n    powerpro\n    powershell\n    abl\n    props\n    ps\n    purebasic\n    python\n    r\n    raku\n    rebol\n    registry\n    ruby\n    rust\n    sas\n    scriptol\n    sinex\n    smalltalk\n    SML\n    sorcins\n    specman\n    spice\n    sql\n    srec\n    stata\n    fcST\n    TACL\n    tads3\n    TAL\n    tcl\n    tcmd\n    tehex\n    tex\n    toml\n    troff\n    txt2tags\n    vb\n    vbscript\n    verilog\n    vhdl\n    visualprolog\n    x12\n    xml\n    yaml\n    zig\n\n\nLexer a68k\n    Word Lists:\n        CPU instructions\n        Registers\n        Directives\n        Extended instructions\n        Comment special words\n        Doxygen keywords\n\nLexer abaqus\n    Word Lists:\n        processors\n        commands\n        slashommands\n        starcommands\n        arguments\n        functions\n\nLexer ada\n    Word Lists:\n        Keywords\n\nLexer apdl\n    Word Lists:\n        processors\n        commands\n        slashommands\n        starcommands\n        arguments\n        functions\n\nLexer as\n    Properties:\n        string lexer.asm.comment.delimiter\n               Character used for COMMENT directive's delimiter, replacing the standard \"~\".\n        bool   fold\n        bool   fold.asm.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.asm.comment.multiline\n               Set this property to 1 to enable folding multi-line comments.\n        bool   fold.asm.comment.explicit\n               This option enables folding explicit fold points when using the Asm lexer. Explicit fold points allows adding extra folding by placing a ;{ comment at the start and a ;} at the end of a section that should fold.\n        string fold.asm.explicit.start\n               The string to use for explicit fold start points, replacing the standard ;{.\n        string fold.asm.explicit.end\n               The string to use for explicit fold end points, replacing the standard ;}.\n        bool   fold.asm.explicit.anywhere\n               Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\n        bool   fold.compact\n        string lexer.as.comment.character\n               Overrides the default comment character (which is ';' for asm and '#' for as).\n    Word Lists:\n        CPU instructions\n        FPU instructions\n        Registers\n        Directives\n        Directive operands\n        Extended instructions\n        Directives4Foldstart\n        Directives4Foldend\n    Styles:\n          0 SCE_ASM_DEFAULT [default] White space\n          1 SCE_ASM_COMMENT [comment line] Comment\n          2 SCE_ASM_NUMBER [literal numeric] Number\n          3 SCE_ASM_STRING [literal string] String\n          4 SCE_ASM_OPERATOR [operator] Operator\n          5 SCE_ASM_IDENTIFIER [identifier] Identifier\n          6 SCE_ASM_CPUINSTRUCTION [keyword] CPU Instruction\n          7 SCE_ASM_MATHINSTRUCTION [keyword] FPU Instruction\n          8 SCE_ASM_REGISTER [keyword identifier] Register\n          9 SCE_ASM_DIRECTIVE [keyword] Directive\n         10 SCE_ASM_DIRECTIVEOPERAND [keyword] Directive Operand\n         11 SCE_ASM_COMMENTBLOCK [comment] Comment block\n         12 SCE_ASM_CHARACTER [literal string] Single quoted string\n         13 SCE_ASM_STRINGEOL [error literal string] End of line where string is not closed\n         14 SCE_ASM_EXTINSTRUCTION [keyword] Extended Instruction\n         15 SCE_ASM_COMMENTDIRECTIVE [comment] Directive Comment\n         16 SCE_ASM_STRINGBACKQUOTE [literal string] Back quoted string\n\nLexer asciidoc\n\nLexer asm\n    Properties:\n        string lexer.asm.comment.delimiter\n               Character used for COMMENT directive's delimiter, replacing the standard \"~\".\n        bool   fold\n        bool   fold.asm.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.asm.comment.multiline\n               Set this property to 1 to enable folding multi-line comments.\n        bool   fold.asm.comment.explicit\n               This option enables folding explicit fold points when using the Asm lexer. Explicit fold points allows adding extra folding by placing a ;{ comment at the start and a ;} at the end of a section that should fold.\n        string fold.asm.explicit.start\n               The string to use for explicit fold start points, replacing the standard ;{.\n        string fold.asm.explicit.end\n               The string to use for explicit fold end points, replacing the standard ;}.\n        bool   fold.asm.explicit.anywhere\n               Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\n        bool   fold.compact\n        string lexer.as.comment.character\n               Overrides the default comment character (which is ';' for asm and '#' for as).\n    Word Lists:\n        CPU instructions\n        FPU instructions\n        Registers\n        Directives\n        Directive operands\n        Extended instructions\n        Directives4Foldstart\n        Directives4Foldend\n    Styles:\n          0 SCE_ASM_DEFAULT [default] White space\n          1 SCE_ASM_COMMENT [comment line] Comment\n          2 SCE_ASM_NUMBER [literal numeric] Number\n          3 SCE_ASM_STRING [literal string] String\n          4 SCE_ASM_OPERATOR [operator] Operator\n          5 SCE_ASM_IDENTIFIER [identifier] Identifier\n          6 SCE_ASM_CPUINSTRUCTION [keyword] CPU Instruction\n          7 SCE_ASM_MATHINSTRUCTION [keyword] FPU Instruction\n          8 SCE_ASM_REGISTER [keyword identifier] Register\n          9 SCE_ASM_DIRECTIVE [keyword] Directive\n         10 SCE_ASM_DIRECTIVEOPERAND [keyword] Directive Operand\n         11 SCE_ASM_COMMENTBLOCK [comment] Comment block\n         12 SCE_ASM_CHARACTER [literal string] Single quoted string\n         13 SCE_ASM_STRINGEOL [error literal string] End of line where string is not closed\n         14 SCE_ASM_EXTINSTRUCTION [keyword] Extended Instruction\n         15 SCE_ASM_COMMENTDIRECTIVE [comment] Directive Comment\n         16 SCE_ASM_STRINGBACKQUOTE [literal string] Back quoted string\n\nLexer asn1\n    Word Lists:\n        Keywords\n        Attributes\n        Descriptors\n        Types\n\nLexer asy\n    Word Lists:\n        Primary keywords and identifiers\n        Secondary keywords and identifiers\n\nLexer au3\n    Word Lists:\n        #autoit keywords\n        #autoit functions\n        #autoit macros\n        #autoit Sent keys\n        #autoit Pre-processors\n        #autoit Special\n        #autoit Expand\n        #autoit UDF\n\nLexer ave\n\nLexer avs\n    Word Lists:\n        Keywords\n        Filters\n        Plugins\n        Functions\n        Clip properties\n        User defined functions\n\nLexer baan\n    Properties:\n        bool   fold\n        bool   fold.comment\n        bool   fold.preprocessor\n        bool   fold.compact\n        bool   fold.baan.syntax.based\n               Set this property to 0 to disable syntax based folding, which is folding based on '{' & '('.\n        bool   fold.baan.keywords.based\n               Set this property to 0 to disable keywords based folding, which is folding based on  for, if, on (case), repeat, select, while and fold ends based on endfor, endif, endcase, until, endselect, endwhile respectively.Also folds declarations which are grouped together.\n        bool   fold.baan.sections\n               Set this property to 0 to disable folding of Main Sections as well as Sub Sections.\n        bool   fold.baan.inner.level\n               Set this property to 1 to enable folding of inner levels of select statements.Disabled by default. case and if statements are also eligible\n        bool   lexer.baan.styling.within.preprocessor\n               For Baan code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) or only from the initial # to the end of the command word(1).\n    Word Lists:\n        Baan & BaanSQL Reserved Keywords \n        Baan Standard functions\n        Baan Functions Abridged\n        Baan Main Sections \n        Baan Sub Sections\n        PreDefined Variables\n        PreDefined Attributes\n        Enumerates\n\nLexer bash\n    Properties:\n        bool   fold\n        bool   fold.comment\n        bool   fold.compact\n        bool   lexer.bash.styling.inside.string\n               Set this property to 1 to highlight shell expansions inside string.\n        bool   lexer.bash.styling.inside.backticks\n               Set this property to 1 to highlight shell expansions inside backticks.\n        bool   lexer.bash.styling.inside.parameter\n               Set this property to 1 to highlight shell expansions inside ${} parameter expansion.\n        bool   lexer.bash.styling.inside.heredoc\n               Set this property to 1 to highlight shell expansions inside here document.\n        int    lexer.bash.command.substitution\n               Set how to highlight $() command substitution. 0 (the default) highlighted as backticks. 1 highlighted inside. 2 highlighted inside with extra scope tracking.\n        bool   lexer.bash.nested.backticks\n               Set this property to 0 to disable nested backquoted command substitution.\n        string lexer.bash.special.parameter\n               Set shell (default is Bash) special parameters.\n    Word Lists:\n        Keywords\n    Sub-Style Bases:\n          8\n          9\n    Styles:\n          0 SCE_SH_DEFAULT [default] White space\n          1 SCE_SH_ERROR [error] Error\n          2 SCE_SH_COMMENTLINE [comment line] Line comment: #\n          3 SCE_SH_NUMBER [literal numeric] Number\n          4 SCE_SH_WORD [keyword] Keyword\n          5 SCE_SH_STRING [literal string] String\n          6 SCE_SH_CHARACTER [literal string] Single quoted string\n          7 SCE_SH_OPERATOR [operator] Operators\n          8 SCE_SH_IDENTIFIER [identifier] Identifiers\n          9 SCE_SH_SCALAR [identifier] Scalar variable\n         10 SCE_SH_PARAM [identifier] Parameter\n         11 SCE_SH_BACKTICKS [literal string] Backtick quoted command\n         12 SCE_SH_HERE_DELIM [operator] Heredoc delimiter\n         13 SCE_SH_HERE_Q [here-doc literal string] Heredoc quoted string\n\nLexer batch\n    Word Lists:\n        Internal Commands\n        External Commands\n    Styles:\n          0 SCE_BAT_DEFAULT [default] White space\n          1 SCE_BAT_COMMENT [comment] Line comment\n          2 SCE_BAT_WORD [keyword] Keyword\n          3 SCE_BAT_LABEL [label] Label\n          4 SCE_BAT_HIDE [preprocessor] Hide line @\n          5 SCE_BAT_COMMAND [identifier] Command\n          6 SCE_BAT_IDENTIFIER [identifier] Identifier\n          7 SCE_BAT_OPERATOR [operator] Operator\n          8 SCE_BAT_AFTER_LABEL [comment] After label\n\nLexer bib\n    Word Lists:\n        Entry Names\n\nLexer blitzbasic\n    Properties:\n        bool   fold\n        bool   fold.basic.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.basic.comment.explicit\n               This option enables folding explicit fold points when using the Basic lexer. Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.\n        string fold.basic.explicit.start\n               The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).\n        string fold.basic.explicit.end\n               The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).\n        bool   fold.basic.explicit.anywhere\n               Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\n        bool   fold.compact\n    Word Lists:\n        BlitzBasic Keywords\n        user1\n        user2\n        user3\n\nLexer bullant\n    Word Lists:\n        Keywords\n\nLexer caml\n    Word Lists:\n        Keywords\n        Keywords2\n        Keywords3\n\nLexer cil\n    UnicodeLineEnds\n    Properties:\n        bool   fold\n        bool   fold.comment\n        bool   fold.cil.comment.multiline\n               Set this property to 0 to disable folding multi-line comments when fold.comment=1.\n        bool   fold.compact\n    Word Lists:\n        Primary CIL keywords\n        Metadata\n        Opcode instructions\n    Styles:\n          0 SCE_CIL_DEFAULT [default] White space\n          1 SCE_CIL_COMMENT [comment] Multi-line comment\n          2 SCE_CIL_COMMENTLINE [comment line] Line comment\n          3 SCE_CIL_WORD [keyword] Keyword 1\n          4 SCE_CIL_WORD2 [keyword] Keyword 2\n          5 SCE_CIL_WORD3 [keyword] Keyword 3\n          6 SCE_CIL_STRING [literal string] Double quoted string\n          7 SCE_CIL_LABEL [label] Code label\n          8 SCE_CIL_OPERATOR [operator] Operators\n          9 SCE_CIL_IDENTIFIER [identifier] Identifiers\n         10 SCE_CIL_STRINGEOL [error literal string] String is not closed\n\nLexer clarion\n    Word Lists:\n        Clarion Keywords\n        Compiler Directives\n        Built-in Procedures and Functions\n        Runtime Expressions\n        Structure and Data Types\n        Attributes\n        Standard Equates\n        Reserved Words (Labels)\n        Reserved Words (Procedure Labels)\n\nLexer clarionnocase\n    Word Lists:\n        Clarion Keywords\n        Compiler Directives\n        Built-in Procedures and Functions\n        Runtime Expressions\n        Structure and Data Types\n        Attributes\n        Standard Equates\n        Reserved Words (Labels)\n        Reserved Words (Procedure Labels)\n\nLexer cmake\n    Word Lists:\n        Commands\n        Parameters\n        UserDefined\n\nLexer COBOL\n    Word Lists:\n        A Keywords\n        B Keywords\n        Extended Keywords\n\nLexer coffeescript\n    Word Lists:\n        Keywords\n        Secondary keywords\n        Unused\n        Global classes\n\nLexer conf\n    Word Lists:\n        Directives\n        Parameters\n\nLexer cpp\n    UnicodeLineEnds\n    Properties:\n        bool   styling.within.preprocessor\n               For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) or only from the initial # to the end of the command word(1).\n        bool   lexer.cpp.allow.dollars\n               Set to 0 to disallow the '$' character in identifiers with the cpp lexer.\n        bool   lexer.cpp.allow.hashes\n               Set to 1 to allow the '#' character in identifiers.\n        bool   lexer.cpp.enable.preprocessor\n               Set to 0 to disable recognition of preprocessor directives.\n        bool   lexer.cpp.track.preprocessor\n               Set to 1 to interpret #if/#else/#endif to grey out code that is not active.\n        bool   lexer.cpp.update.preprocessor\n               Set to 1 to update preprocessor definitions when #define found.\n        bool   lexer.cpp.verbatim.strings.allow.escapes\n               Set to 1 to allow verbatim strings to contain escape sequences.\n        bool   lexer.cpp.triplequoted.strings\n               Set to 1 to enable highlighting of triple-quoted strings.\n        bool   lexer.cpp.hashquoted.strings\n               Set to 1 to enable highlighting of hash-quoted strings.\n        int    lexer.cpp.backquoted.strings\n               Set how to highlighting back-quoted strings. 0 (the default) no highlighting. 1 highlighted as Go raw string. 2 highlighted as JavaScript template literal.\n        bool   lexer.cpp.escape.sequence\n               Set to 1 to enable highlighting of escape sequences in strings\n        bool   fold\n        bool   fold.cpp.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.comment\n               This option enables folding multi-line comments and explicit fold points when using the C++ lexer. Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} at the end of a section that should fold.\n        bool   fold.cpp.comment.multiline\n               Set this property to 0 to disable folding multi-line comments when fold.comment=1.\n        bool   fold.cpp.comment.explicit\n               Set this property to 0 to disable folding explicit fold points when fold.comment=1.\n        string fold.cpp.explicit.start\n               The string to use for explicit fold start points, replacing the standard //{.\n        string fold.cpp.explicit.end\n               The string to use for explicit fold end points, replacing the standard //}.\n        bool   fold.cpp.explicit.anywhere\n               Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\n        bool   fold.cpp.preprocessor.at.else\n               This option enables folding on a preprocessor #else or #endif line of an #if statement.\n        bool   fold.preprocessor\n               This option enables folding preprocessor directives when using the C++ lexer. Includes C#'s explicit #region and #endregion folding directives.\n        bool   fold.compact\n        bool   fold.at.else\n               This option enables C++ folding on a \"} else {\" line of an if statement.\n    Word Lists:\n        Primary keywords and identifiers\n        Secondary keywords and identifiers\n        Documentation comment keywords\n        Global classes and typedefs\n        Preprocessor definitions\n        Task marker and error marker keywords\n    Sub-Style Bases:\n         11\n         17\n    Styles:\n          0 SCE_C_DEFAULT [default] White space\n          1 SCE_C_COMMENT [comment] Comment: /* */.\n          2 SCE_C_COMMENTLINE [comment line] Line Comment: //.\n          3 SCE_C_COMMENTDOC [comment documentation] Doc comment: block comments beginning with /** or /*!\n          4 SCE_C_NUMBER [literal numeric] Number\n          5 SCE_C_WORD [keyword] Keyword\n          6 SCE_C_STRING [literal string] Double quoted string\n          7 SCE_C_CHARACTER [literal string character] Single quoted string\n          8 SCE_C_UUID [literal uuid] UUIDs (only in IDL)\n          9 SCE_C_PREPROCESSOR [preprocessor] Preprocessor\n         10 SCE_C_OPERATOR [operator] Operators\n         11 SCE_C_IDENTIFIER [identifier] Identifiers\n         12 SCE_C_STRINGEOL [error literal string] End of line where string is not closed\n         13 SCE_C_VERBATIM [literal string multiline raw] Verbatim strings for C#\n         14 SCE_C_REGEX [literal regex] Regular expressions for JavaScript\n         15 SCE_C_COMMENTLINEDOC [comment documentation line] Doc Comment Line: line comments beginning with /// or //!.\n         16 SCE_C_WORD2 [identifier] Keywords2\n         17 SCE_C_COMMENTDOCKEYWORD [comment documentation keyword] Comment keyword\n         18 SCE_C_COMMENTDOCKEYWORDERROR [error comment documentation keyword] Comment keyword error\n         19 SCE_C_GLOBALCLASS [identifier] Global class\n         20 SCE_C_STRINGRAW [literal string multiline raw] Raw strings for C++0x\n         21 SCE_C_TRIPLEVERBATIM [literal string multiline raw] Triple-quoted strings for Vala\n         22 SCE_C_HASHQUOTEDSTRING [literal string] Hash-quoted strings for Pike\n         23 SCE_C_PREPROCESSORCOMMENT [comment preprocessor] Preprocessor stream comment\n         24 SCE_C_PREPROCESSORCOMMENTDOC [comment preprocessor documentation] Preprocessor stream doc comment\n         25 SCE_C_USERLITERAL [literal] User defined literals\n         26 SCE_C_TASKMARKER [comment taskmarker] Task Marker\n         27 SCE_C_ESCAPESEQUENCE [literal string escapesequence] Escape sequence\n         64  [inactive default] \n         65  [inactive comment] \n         66  [inactive comment line] \n         67  [inactive comment documentation] \n         68  [inactive literal numeric] \n         69  [inactive keyword] \n         70  [inactive literal string] \n         71  [inactive literal string character] \n         72  [inactive literal uuid] \n         73  [inactive preprocessor] \n         74  [inactive operator] \n         75  [inactive identifier] \n         76  [inactive error literal string] \n         77  [inactive literal string multiline raw] \n         78  [inactive literal regex] \n         79  [inactive comment documentation line] \n         80  [inactive identifier] \n         81  [inactive comment documentation keyword] \n         82  [inactive error comment documentation keyword] \n         83  [inactive identifier] \n         84  [inactive literal string multiline raw] \n         85  [inactive literal string multiline raw] \n         86  [inactive literal string] \n         87  [inactive comment preprocessor] \n         88  [inactive comment preprocessor documentation] \n         89  [inactive literal] \n         90  [inactive comment taskmarker] \n         91  [inactive literal string escapesequence] \n\nLexer cppnocase\n    UnicodeLineEnds\n    Properties:\n        bool   styling.within.preprocessor\n               For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) or only from the initial # to the end of the command word(1).\n        bool   lexer.cpp.allow.dollars\n               Set to 0 to disallow the '$' character in identifiers with the cpp lexer.\n        bool   lexer.cpp.allow.hashes\n               Set to 1 to allow the '#' character in identifiers.\n        bool   lexer.cpp.enable.preprocessor\n               Set to 0 to disable recognition of preprocessor directives.\n        bool   lexer.cpp.track.preprocessor\n               Set to 1 to interpret #if/#else/#endif to grey out code that is not active.\n        bool   lexer.cpp.update.preprocessor\n               Set to 1 to update preprocessor definitions when #define found.\n        bool   lexer.cpp.verbatim.strings.allow.escapes\n               Set to 1 to allow verbatim strings to contain escape sequences.\n        bool   lexer.cpp.triplequoted.strings\n               Set to 1 to enable highlighting of triple-quoted strings.\n        bool   lexer.cpp.hashquoted.strings\n               Set to 1 to enable highlighting of hash-quoted strings.\n        int    lexer.cpp.backquoted.strings\n               Set how to highlighting back-quoted strings. 0 (the default) no highlighting. 1 highlighted as Go raw string. 2 highlighted as JavaScript template literal.\n        bool   lexer.cpp.escape.sequence\n               Set to 1 to enable highlighting of escape sequences in strings\n        bool   fold\n        bool   fold.cpp.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.comment\n               This option enables folding multi-line comments and explicit fold points when using the C++ lexer. Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} at the end of a section that should fold.\n        bool   fold.cpp.comment.multiline\n               Set this property to 0 to disable folding multi-line comments when fold.comment=1.\n        bool   fold.cpp.comment.explicit\n               Set this property to 0 to disable folding explicit fold points when fold.comment=1.\n        string fold.cpp.explicit.start\n               The string to use for explicit fold start points, replacing the standard //{.\n        string fold.cpp.explicit.end\n               The string to use for explicit fold end points, replacing the standard //}.\n        bool   fold.cpp.explicit.anywhere\n               Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\n        bool   fold.cpp.preprocessor.at.else\n               This option enables folding on a preprocessor #else or #endif line of an #if statement.\n        bool   fold.preprocessor\n               This option enables folding preprocessor directives when using the C++ lexer. Includes C#'s explicit #region and #endregion folding directives.\n        bool   fold.compact\n        bool   fold.at.else\n               This option enables C++ folding on a \"} else {\" line of an if statement.\n    Word Lists:\n        Primary keywords and identifiers\n        Secondary keywords and identifiers\n        Documentation comment keywords\n        Global classes and typedefs\n        Preprocessor definitions\n        Task marker and error marker keywords\n    Sub-Style Bases:\n         11\n         17\n    Styles:\n          0 SCE_C_DEFAULT [default] White space\n          1 SCE_C_COMMENT [comment] Comment: /* */.\n          2 SCE_C_COMMENTLINE [comment line] Line Comment: //.\n          3 SCE_C_COMMENTDOC [comment documentation] Doc comment: block comments beginning with /** or /*!\n          4 SCE_C_NUMBER [literal numeric] Number\n          5 SCE_C_WORD [keyword] Keyword\n          6 SCE_C_STRING [literal string] Double quoted string\n          7 SCE_C_CHARACTER [literal string character] Single quoted string\n          8 SCE_C_UUID [literal uuid] UUIDs (only in IDL)\n          9 SCE_C_PREPROCESSOR [preprocessor] Preprocessor\n         10 SCE_C_OPERATOR [operator] Operators\n         11 SCE_C_IDENTIFIER [identifier] Identifiers\n         12 SCE_C_STRINGEOL [error literal string] End of line where string is not closed\n         13 SCE_C_VERBATIM [literal string multiline raw] Verbatim strings for C#\n         14 SCE_C_REGEX [literal regex] Regular expressions for JavaScript\n         15 SCE_C_COMMENTLINEDOC [comment documentation line] Doc Comment Line: line comments beginning with /// or //!.\n         16 SCE_C_WORD2 [identifier] Keywords2\n         17 SCE_C_COMMENTDOCKEYWORD [comment documentation keyword] Comment keyword\n         18 SCE_C_COMMENTDOCKEYWORDERROR [error comment documentation keyword] Comment keyword error\n         19 SCE_C_GLOBALCLASS [identifier] Global class\n         20 SCE_C_STRINGRAW [literal string multiline raw] Raw strings for C++0x\n         21 SCE_C_TRIPLEVERBATIM [literal string multiline raw] Triple-quoted strings for Vala\n         22 SCE_C_HASHQUOTEDSTRING [literal string] Hash-quoted strings for Pike\n         23 SCE_C_PREPROCESSORCOMMENT [comment preprocessor] Preprocessor stream comment\n         24 SCE_C_PREPROCESSORCOMMENTDOC [comment preprocessor documentation] Preprocessor stream doc comment\n         25 SCE_C_USERLITERAL [literal] User defined literals\n         26 SCE_C_TASKMARKER [comment taskmarker] Task Marker\n         27 SCE_C_ESCAPESEQUENCE [literal string escapesequence] Escape sequence\n         64  [inactive default] \n         65  [inactive comment] \n         66  [inactive comment line] \n         67  [inactive comment documentation] \n         68  [inactive literal numeric] \n         69  [inactive keyword] \n         70  [inactive literal string] \n         71  [inactive literal string character] \n         72  [inactive literal uuid] \n         73  [inactive preprocessor] \n         74  [inactive operator] \n         75  [inactive identifier] \n         76  [inactive error literal string] \n         77  [inactive literal string multiline raw] \n         78  [inactive literal regex] \n         79  [inactive comment documentation line] \n         80  [inactive identifier] \n         81  [inactive comment documentation keyword] \n         82  [inactive error comment documentation keyword] \n         83  [inactive identifier] \n         84  [inactive literal string multiline raw] \n         85  [inactive literal string multiline raw] \n         86  [inactive literal string] \n         87  [inactive comment preprocessor] \n         88  [inactive comment preprocessor documentation] \n         89  [inactive literal] \n         90  [inactive comment taskmarker] \n         91  [inactive literal string escapesequence] \n\nLexer csound\n    Word Lists:\n        Opcodes\n        Header Statements\n        User keywords\n\nLexer css\n    Word Lists:\n        CSS1 Properties\n        Pseudo-classes\n        CSS2 Properties\n        CSS3 Properties\n        Pseudo-elements\n        Browser-Specific CSS Properties\n        Browser-Specific Pseudo-classes\n        Browser-Specific Pseudo-elements\n\nLexer d\n    Properties:\n        bool   fold\n        bool   fold.d.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.comment\n        bool   fold.d.comment.multiline\n               Set this property to 0 to disable folding multi-line comments when fold.comment=1.\n        bool   fold.d.comment.explicit\n               Set this property to 0 to disable folding explicit fold points when fold.comment=1.\n        string fold.d.explicit.start\n               The string to use for explicit fold start points, replacing the standard //{.\n        string fold.d.explicit.end\n               The string to use for explicit fold end points, replacing the standard //}.\n        bool   fold.d.explicit.anywhere\n               Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\n        bool   fold.compact\n        int    lexer.d.fold.at.else\n               This option enables D folding on a \"} else {\" line of an if statement.\n        bool   fold.at.else\n    Word Lists:\n        Primary keywords and identifiers\n        Secondary keywords and identifiers\n        Documentation comment keywords\n        Type definitions and aliases\n        Keywords 5\n        Keywords 6\n        Keywords 7\n\nLexer dart\n    Properties:\n        bool   fold\n    Word Lists:\n        Primary keywords\n        Secondary keywords\n        Tertiary keywords\n        Global type definitions\n    Styles:\n          0 SCE_DART_DEFAULT [default] White space\n          1 SCE_DART_COMMENTLINE [comment line] Comment: //\n          2 SCE_DART_COMMENTLINEDOC [comment line documentation] Comment: ///\n          3 SCE_DART_COMMENTBLOCK [comment] Comment: /* */\n          4 SCE_DART_COMMENTBLOCKDOC [comment documentation] Comment: /** */\n          5 SCE_DART_STRING_SQ [literal string] Single quoted string\n          6 SCE_DART_STRING_DQ [literal string] Double quoted string\n          7 SCE_DART_TRIPLE_STRING_SQ [literal string multiline] Single quoted multiline string\n          8 SCE_DART_TRIPLE_STRING_DQ [literal string multiline] Double quoted multiline string\n          9 SCE_DART_RAWSTRING_SQ [literal string raw] Single quoted raw string\n         10 SCE_DART_RAWSTRING_DQ [literal string raw] Double quoted raw string\n         11 SCE_DART_TRIPLE_RAWSTRING_SQ [literal string multiline raw] Single quoted multiline raw string\n         12 SCE_DART_TRIPLE_RAWSTRING_DQ [literal string multiline raw] Double quoted multiline raw string\n         13 SCE_DART_ESCAPECHAR [literal string escapesequence] Escape sequence\n         14 SCE_DART_IDENTIFIER [identifier] Identifier\n         15 SCE_DART_IDENTIFIER_STRING [identifier interpolated] Identifier following $ inside strings\n         16 SCE_DART_OPERATOR [operator] Operator\n         17 SCE_DART_OPERATOR_STRING [operator interpolated] Braces following $ inside string\n         18 SCE_DART_SYMBOL_IDENTIFIER [identifier symbol] Symbol name introduced by #\n         19 SCE_DART_SYMBOL_OPERATOR [operator symbol] Operator introduced by #\n         20 SCE_DART_NUMBER [literal numeric] Number\n         21 SCE_DART_KEY [key] Keys preceding ':' and named parameters\n         22 SCE_DART_METADATA [preprocessor] Metadata introduced by @\n         23 SCE_DART_KW_PRIMARY [keyword] Primary keywords\n         24 SCE_DART_KW_SECONDARY [identifier] Secondary keywords\n         25 SCE_DART_KW_TERTIARY [identifier] Tertiary keywords\n         26 SCE_DART_KW_TYPE [identifier] Global types\n         27 SCE_DART_STRINGEOL [error literal string] End of line where string is not closed\n\nLexer dataflex\n    Word Lists:\n        Keywords\n        Scope open\n        Scope close\n        Operators\n\nLexer diff\n\nLexer DMAP\n    Word Lists:\n        Primary keywords and identifiers\n        Intrinsic functions\n        Extended and user defined functions\n\nLexer DMIS\n    Word Lists:\n        DMIS Major Words\n        DMIS Minor Words\n        Unsupported DMIS Major Words\n        Unsupported DMIS Minor Words\n        Keywords for code folding start\n        Corresponding keywords for code folding end\n        \n\nLexer ecl\n    Word Lists:\n        Keywords\n\nLexer edifact\n    Properties:\n        bool   fold\n               Whether to apply folding to document or not\n        bool   lexer.edifact.highlight.un.all\n               Whether to apply UN* highlighting to all UN segments, or just to UNH\n\nLexer eiffel\n    Word Lists:\n        Keywords\n\nLexer eiffelkw\n    Word Lists:\n        Keywords\n\nLexer erlang\n    Word Lists:\n        Erlang Reserved words\n        Erlang BIFs\n        Erlang Preprocessor\n        Erlang Module Attributes\n        Erlang Documentation\n        Erlang Documentation Macro\n\nLexer errorlist\n    Properties:\n        bool   lexer.errorlist.value.separate\n               For lines in the output pane that are matches from Find in Files or GCC-stylediagnostics, style the path and line number separately from the rest of theline with style 21 used for the rest of the line.This allows matched text to be more easily distinguished from its location.\n        bool   lexer.errorlist.escape.sequences\n               Set to 1 to interpret escape sequences.\n    Styles:\n          0 SCE_ERR_DEFAULT [diagnostic] Text\n          1 SCE_ERR_PYTHON [diagnostic] Python Error\n          2 SCE_ERR_GCC [diagnostic] GCC Error\n          3 SCE_ERR_MS [diagnostic] Microsoft Error\n          4 SCE_ERR_CMD [default] Command or return status\n          5 SCE_ERR_BORLAND [diagnostic] Borland error and warning messages\n          6 SCE_ERR_PERL [diagnostic] Perl error and warning messages\n          7 SCE_ERR_NET [diagnostic] .NET tracebacks\n          8 SCE_ERR_LUA [diagnostic] Lua error and warning messages\n          9 SCE_ERR_CTAG [diagnostic] ctags\n         10 SCE_ERR_DIFF_CHANGED [default] Diff changed !\n         11 SCE_ERR_DIFF_ADDITION [default] Diff addition +\n         12 SCE_ERR_DIFF_DELETION [default] Diff deletion -\n         13 SCE_ERR_DIFF_MESSAGE [default] Diff message ---\n         14 SCE_ERR_PHP [diagnostic] PHP error\n         15 SCE_ERR_ELF [diagnostic] Essential Lahey Fortran 90 error\n         16 SCE_ERR_IFC [diagnostic] Intel Fortran Compiler error\n         17 SCE_ERR_IFORT [diagnostic] Intel Fortran Compiler v8.0 error/warning\n         18 SCE_ERR_ABSF [diagnostic] Absoft Pro Fortran 90/95 v8.2 error or warning\n         19 SCE_ERR_TIDY [diagnostic] HTML Tidy\n         20 SCE_ERR_JAVA_STACK [diagnostic] Java runtime stack trace\n         21 SCE_ERR_VALUE [default] Text matched with find in files and message part of GCC errors\n         22 SCE_ERR_GCC_INCLUDED_FROM [diagnostic] GCC showing include path to following error\n         23 SCE_ERR_ESCSEQ [escapesequence] Escape sequence\n         24 SCE_ERR_ESCSEQ_UNKNOWN [escapesequence] Escape sequence unknown\n         25 SCE_ERR_GCC_EXCERPT [diagnostic] GCC showing excerpt of code with pointer\n         26 SCE_ERR_BASH [diagnostic] Bash diagnostic\n         27  [unused] \n         28  [unused] \n         29  [unused] \n         30  [unused] \n         31  [unused] \n         32  [predefined] \n         33  [predefined] \n         34  [predefined] \n         35  [predefined] \n         36  [predefined] \n         37  [predefined] \n         38  [predefined] \n         39  [predefined] \n         40 SCE_ERR_ES_BLACK [default] Black\n         41 SCE_ERR_ES_RED [default] Red\n         42 SCE_ERR_ES_GREEN [default] Green\n         43 SCE_ERR_ES_BROWN [default] Brown\n         44 SCE_ERR_ES_BLUE [default] Blue\n         45 SCE_ERR_ES_MAGENTA [default] Magenta\n         46 SCE_ERR_ES_CYAN [default] Cyan\n         47 SCE_ERR_ES_GRAY [default] Gray\n         48 SCE_ERR_ES_DARK_GRAY [default] Dark Gray\n         49 SCE_ERR_ES_BRIGHT_RED [default] Bright Red\n         50 SCE_ERR_ES_BRIGHT_GREEN [default] Bright Green\n         51 SCE_ERR_ES_YELLOW [default] Yellow\n         52 SCE_ERR_ES_BRIGHT_BLUE [default] Bright Blue\n         53 SCE_ERR_ES_BRIGHT_MAGENTA [default] Bright Magenta\n         54 SCE_ERR_ES_BRIGHT_CYAN [default] Bright Cyan\n         55 SCE_ERR_ES_WHITE [default] White\n\nLexer escript\n    Word Lists:\n        Primary keywords and identifiers\n        Intrinsic functions\n        Extended and user defined functions\n\nLexer escseq\n    Properties:\n        bool   lexer.escseq.colour.text\n               Set to 1 to colour text following the escape sequences.\n    Styles:\n          0 SCE_ESCSEQ_DEFAULT [default] Default\n          1 SCE_ESCSEQ_BLACK_DEFAULT [default] Black Default\n          2 SCE_ESCSEQ_RED_DEFAULT [default] Red Default\n          3 SCE_ESCSEQ_GREEN_DEFAULT [default] Green Default\n          4 SCE_ESCSEQ_YELLOW_DEFAULT [default] Yellow Default\n          5 SCE_ESCSEQ_BLUE_DEFAULT [default] Blue Default\n          6 SCE_ESCSEQ_MAGENTA_DEFAULT [default] Magenta Default\n          7 SCE_ESCSEQ_CYAN_DEFAULT [default] Cyan Default\n          8 SCE_ESCSEQ_WHITE_DEFAULT [default] White Default\n          9 SCE_ESCSEQ_DEFAULT_BLACK [default] Default Black\n         10 SCE_ESCSEQ_BLACK_BLACK [default] Black Black\n         11 SCE_ESCSEQ_RED_BLACK [default] Red Black\n         12 SCE_ESCSEQ_GREEN_BLACK [default] Green Black\n         13 SCE_ESCSEQ_YELLOW_BLACK [default] Yellow Black\n         14 SCE_ESCSEQ_BLUE_BLACK [default] Blue Black\n         15 SCE_ESCSEQ_MAGENTA_BLACK [default] Magenta Black\n         16 SCE_ESCSEQ_CYAN_BLACK [default] Cyan Black\n         17 SCE_ESCSEQ_WHITE_BLACK [default] White Black\n         18 SCE_ESCSEQ_DEFAULT_RED [default] Default Red\n         19 SCE_ESCSEQ_BLACK_RED [default] Black Red\n         20 SCE_ESCSEQ_RED_RED [default] Red Red\n         21 SCE_ESCSEQ_GREEN_RED [default] Green Red\n         22 SCE_ESCSEQ_YELLOW_RED [default] Yellow Red\n         23 SCE_ESCSEQ_BLUE_RED [default] Blue Red\n         24 SCE_ESCSEQ_MAGENTA_RED [default] Magenta Red\n         25 SCE_ESCSEQ_CYAN_RED [default] Cyan Red\n         26 SCE_ESCSEQ_WHITE_RED [default] White Red\n         27 SCE_ESCSEQ_DEFAULT_GREEN [default] Default Green\n         28 SCE_ESCSEQ_BLACK_GREEN [default] Black Green\n         29 SCE_ESCSEQ_RED_GREEN [default] Red Green\n         30 SCE_ESCSEQ_GREEN_GREEN [default] Green Green\n         31  [unused] \n         32  [predefined] \n         33  [predefined] \n         34  [predefined] \n         35  [predefined] \n         36  [predefined] \n         37  [predefined] \n         38  [predefined] \n         39  [predefined] \n         40 SCE_ESCSEQ_YELLOW_GREEN [default] Yellow Green\n         41 SCE_ESCSEQ_BLUE_GREEN [default] Blue Green\n         42 SCE_ESCSEQ_MAGENTA_GREEN [default] Magenta Green\n         43 SCE_ESCSEQ_CYAN_GREEN [default] Cyan Green\n         44 SCE_ESCSEQ_WHITE_GREEN [default] White Green\n         45 SCE_ESCSEQ_DEFAULT_YELLOW [default] Default Yellow\n         46 SCE_ESCSEQ_BLACK_YELLOW [default] Black Yellow\n         47 SCE_ESCSEQ_RED_YELLOW [default] Red Yellow\n         48 SCE_ESCSEQ_GREEN_YELLOW [default] Green Yellow\n         49 SCE_ESCSEQ_YELLOW_YELLOW [default] Yellow Yellow\n         50 SCE_ESCSEQ_BLUE_YELLOW [default] Blue Yellow\n         51 SCE_ESCSEQ_MAGENTA_YELLOW [default] Magenta Yellow\n         52 SCE_ESCSEQ_CYAN_YELLOW [default] Cyan Yellow\n         53 SCE_ESCSEQ_WHITE_YELLOW [default] White Yellow\n         54 SCE_ESCSEQ_DEFAULT_BLUE [default] Default Blue\n         55 SCE_ESCSEQ_BLACK_BLUE [default] Black Blue\n         56 SCE_ESCSEQ_RED_BLUE [default] Red Blue\n         57 SCE_ESCSEQ_GREEN_BLUE [default] Green Blue\n         58 SCE_ESCSEQ_YELLOW_BLUE [default] Yellow Blue\n         59 SCE_ESCSEQ_BLUE_BLUE [default] Blue Blue\n         60 SCE_ESCSEQ_MAGENTA_BLUE [default] Magenta Blue\n         61 SCE_ESCSEQ_CYAN_BLUE [default] Cyan Blue\n         62 SCE_ESCSEQ_WHITE_BLUE [default] White Blue\n         63 SCE_ESCSEQ_DEFAULT_MAGENTA [default] Default Magenta\n         64 SCE_ESCSEQ_BLACK_MAGENTA [default] Black Magenta\n         65 SCE_ESCSEQ_RED_MAGENTA [default] Red Magenta\n         66 SCE_ESCSEQ_GREEN_MAGENTA [default] Green Magenta\n         67 SCE_ESCSEQ_YELLOW_MAGENTA [default] Yellow Magenta\n         68 SCE_ESCSEQ_BLUE_MAGENTA [default] Blue Magenta\n         69 SCE_ESCSEQ_MAGENTA_MAGENTA [default] Magenta Magenta\n         70 SCE_ESCSEQ_CYAN_MAGENTA [default] Cyan Magenta\n         71 SCE_ESCSEQ_WHITE_MAGENTA [default] White Magenta\n         72 SCE_ESCSEQ_DEFAULT_CYAN [default] Default Cyan\n         73 SCE_ESCSEQ_BLACK_CYAN [default] Black Cyan\n         74 SCE_ESCSEQ_RED_CYAN [default] Red Cyan\n         75 SCE_ESCSEQ_GREEN_CYAN [default] Green Cyan\n         76 SCE_ESCSEQ_YELLOW_CYAN [default] Yellow Cyan\n         77 SCE_ESCSEQ_BLUE_CYAN [default] Blue Cyan\n         78 SCE_ESCSEQ_MAGENTA_CYAN [default] Magenta Cyan\n         79 SCE_ESCSEQ_CYAN_CYAN [default] Cyan Cyan\n         80 SCE_ESCSEQ_WHITE_CYAN [default] White Cyan\n         81 SCE_ESCSEQ_DEFAULT_WHITE [default] Default White\n         82 SCE_ESCSEQ_BLACK_WHITE [default] Black White\n         83 SCE_ESCSEQ_RED_WHITE [default] Red White\n         84 SCE_ESCSEQ_GREEN_WHITE [default] Green White\n         85 SCE_ESCSEQ_YELLOW_WHITE [default] Yellow White\n         86 SCE_ESCSEQ_BLUE_WHITE [default] Blue White\n         87 SCE_ESCSEQ_MAGENTA_WHITE [default] Magenta White\n         88 SCE_ESCSEQ_CYAN_WHITE [default] Cyan White\n         89 SCE_ESCSEQ_WHITE_WHITE [default] White White\n         90 SCE_ESCSEQ_BOLD_DEFAULT [default] Bold Default\n         91 SCE_ESCSEQ_BOLD_BLACK_DEFAULT [default] Bold Black Default\n         92 SCE_ESCSEQ_BOLD_RED_DEFAULT [default] Bold Red Default\n         93 SCE_ESCSEQ_BOLD_GREEN_DEFAULT [default] Bold Green Default\n         94 SCE_ESCSEQ_BOLD_YELLOW_DEFAULT [default] Bold Yellow Default\n         95 SCE_ESCSEQ_BOLD_BLUE_DEFAULT [default] Bold Blue Default\n         96 SCE_ESCSEQ_BOLD_MAGENTA_DEFAULT [default] Bold Magenta Default\n         97 SCE_ESCSEQ_BOLD_CYAN_DEFAULT [default] Bold Cyan Default\n         98 SCE_ESCSEQ_BOLD_WHITE_DEFAULT [default] Bold White Default\n         99 SCE_ESCSEQ_BOLD_DEFAULT_BLACK [default] Bold Default Black\n        100 SCE_ESCSEQ_BOLD_BLACK_BLACK [default] Bold Black Black\n        101 SCE_ESCSEQ_BOLD_RED_BLACK [default] Bold Red Black\n        102 SCE_ESCSEQ_BOLD_GREEN_BLACK [default] Bold Green Black\n        103 SCE_ESCSEQ_BOLD_YELLOW_BLACK [default] Bold Yellow Black\n        104 SCE_ESCSEQ_BOLD_BLUE_BLACK [default] Bold Blue Black\n        105 SCE_ESCSEQ_BOLD_MAGENTA_BLACK [default] Bold Magenta Black\n        106 SCE_ESCSEQ_BOLD_CYAN_BLACK [default] Bold Cyan Black\n        107 SCE_ESCSEQ_BOLD_WHITE_BLACK [default] Bold White Black\n        108 SCE_ESCSEQ_BOLD_DEFAULT_RED [default] Bold Default Red\n        109 SCE_ESCSEQ_BOLD_BLACK_RED [default] Bold Black Red\n        110 SCE_ESCSEQ_BOLD_RED_RED [default] Bold Red Red\n        111 SCE_ESCSEQ_BOLD_GREEN_RED [default] Bold Green Red\n        112 SCE_ESCSEQ_BOLD_YELLOW_RED [default] Bold Yellow Red\n        113 SCE_ESCSEQ_BOLD_BLUE_RED [default] Bold Blue Red\n        114 SCE_ESCSEQ_BOLD_MAGENTA_RED [default] Bold Magenta Red\n        115 SCE_ESCSEQ_BOLD_CYAN_RED [default] Bold Cyan Red\n        116 SCE_ESCSEQ_BOLD_WHITE_RED [default] Bold White Red\n        117 SCE_ESCSEQ_BOLD_DEFAULT_GREEN [default] Bold Default Green\n        118 SCE_ESCSEQ_BOLD_BLACK_GREEN [default] Bold Black Green\n        119 SCE_ESCSEQ_BOLD_RED_GREEN [default] Bold Red Green\n        120 SCE_ESCSEQ_BOLD_GREEN_GREEN [default] Bold Green Green\n        121 SCE_ESCSEQ_BOLD_YELLOW_GREEN [default] Bold Yellow Green\n        122 SCE_ESCSEQ_BOLD_BLUE_GREEN [default] Bold Blue Green\n        123 SCE_ESCSEQ_BOLD_MAGENTA_GREEN [default] Bold Magenta Green\n        124 SCE_ESCSEQ_BOLD_CYAN_GREEN [default] Bold Cyan Green\n        125 SCE_ESCSEQ_BOLD_WHITE_GREEN [default] Bold White Green\n        126 SCE_ESCSEQ_BOLD_DEFAULT_YELLOW [default] Bold Default Yellow\n        127 SCE_ESCSEQ_BOLD_BLACK_YELLOW [default] Bold Black Yellow\n        128 SCE_ESCSEQ_BOLD_RED_YELLOW [default] Bold Red Yellow\n        129 SCE_ESCSEQ_BOLD_GREEN_YELLOW [default] Bold Green Yellow\n        130 SCE_ESCSEQ_BOLD_YELLOW_YELLOW [default] Bold Yellow Yellow\n        131 SCE_ESCSEQ_BOLD_BLUE_YELLOW [default] Bold Blue Yellow\n        132 SCE_ESCSEQ_BOLD_MAGENTA_YELLOW [default] Bold Magenta Yellow\n        133 SCE_ESCSEQ_BOLD_CYAN_YELLOW [default] Bold Cyan Yellow\n        134 SCE_ESCSEQ_BOLD_WHITE_YELLOW [default] Bold White Yellow\n        135 SCE_ESCSEQ_BOLD_DEFAULT_BLUE [default] Bold Default Blue\n        136 SCE_ESCSEQ_BOLD_BLACK_BLUE [default] Bold Black Blue\n        137 SCE_ESCSEQ_BOLD_RED_BLUE [default] Bold Red Blue\n        138 SCE_ESCSEQ_BOLD_GREEN_BLUE [default] Bold Green Blue\n        139 SCE_ESCSEQ_BOLD_YELLOW_BLUE [default] Bold Yellow Blue\n        140 SCE_ESCSEQ_BOLD_BLUE_BLUE [default] Bold Blue Blue\n        141 SCE_ESCSEQ_BOLD_MAGENTA_BLUE [default] Bold Magenta Blue\n        142 SCE_ESCSEQ_BOLD_CYAN_BLUE [default] Bold Cyan Blue\n        143 SCE_ESCSEQ_BOLD_WHITE_BLUE [default] Bold White Blue\n        144 SCE_ESCSEQ_BOLD_DEFAULT_MAGENTA [default] Bold Default Magenta\n        145 SCE_ESCSEQ_BOLD_BLACK_MAGENTA [default] Bold Black Magenta\n        146 SCE_ESCSEQ_BOLD_RED_MAGENTA [default] Bold Red Magenta\n        147 SCE_ESCSEQ_BOLD_GREEN_MAGENTA [default] Bold Green Magenta\n        148 SCE_ESCSEQ_BOLD_YELLOW_MAGENTA [default] Bold Yellow Magenta\n        149 SCE_ESCSEQ_BOLD_BLUE_MAGENTA [default] Bold Blue Magenta\n        150 SCE_ESCSEQ_BOLD_MAGENTA_MAGENTA [default] Bold Magenta Magenta\n        151 SCE_ESCSEQ_BOLD_CYAN_MAGENTA [default] Bold Cyan Magenta\n        152 SCE_ESCSEQ_BOLD_WHITE_MAGENTA [default] Bold White Magenta\n        153 SCE_ESCSEQ_BOLD_DEFAULT_CYAN [default] Bold Default Cyan\n        154 SCE_ESCSEQ_BOLD_BLACK_CYAN [default] Bold Black Cyan\n        155 SCE_ESCSEQ_BOLD_RED_CYAN [default] Bold Red Cyan\n        156 SCE_ESCSEQ_BOLD_GREEN_CYAN [default] Bold Green Cyan\n        157 SCE_ESCSEQ_BOLD_YELLOW_CYAN [default] Bold Yellow Cyan\n        158 SCE_ESCSEQ_BOLD_BLUE_CYAN [default] Bold Blue Cyan\n        159 SCE_ESCSEQ_BOLD_MAGENTA_CYAN [default] Bold Magenta Cyan\n        160 SCE_ESCSEQ_BOLD_CYAN_CYAN [default] Bold Cyan Cyan\n        161 SCE_ESCSEQ_BOLD_WHITE_CYAN [default] Bold White Cyan\n        162 SCE_ESCSEQ_BOLD_DEFAULT_WHITE [default] Bold Default White\n        163 SCE_ESCSEQ_BOLD_BLACK_WHITE [default] Bold Black White\n        164 SCE_ESCSEQ_BOLD_RED_WHITE [default] Bold Red White\n        165 SCE_ESCSEQ_BOLD_GREEN_WHITE [default] Bold Green White\n        166 SCE_ESCSEQ_BOLD_YELLOW_WHITE [default] Bold Yellow White\n        167 SCE_ESCSEQ_BOLD_BLUE_WHITE [default] Bold Blue White\n        168 SCE_ESCSEQ_BOLD_MAGENTA_WHITE [default] Bold Magenta White\n        169 SCE_ESCSEQ_BOLD_CYAN_WHITE [default] Bold Cyan White\n        170 SCE_ESCSEQ_BOLD_WHITE_WHITE [default] Bold White White\n        171 SCE_ESCSEQ_IDENTIFIER [default] Sequence Identifier\n        172 SCE_ESCSEQ_UNKNOWN [default] Sequence Unknown\n\nLexer f77\n    Word Lists:\n        Primary keywords and identifiers\n        Intrinsic functions\n        Extended and user defined functions\n\nLexer flagship\n    Word Lists:\n        Keywords Commands\n        Std Library Functions\n        Procedure, return, exit\n        Class (oop)\n        Doxygen keywords\n\nLexer forth\n    Word Lists:\n        control keywords\n        keywords\n        definition words\n        prewords with one argument\n        prewords with two arguments\n        string definition keywords\n\nLexer fortran\n    Word Lists:\n        Primary keywords and identifiers\n        Intrinsic functions\n        Extended and user defined functions\n\nLexer freebasic\n    Properties:\n        bool   fold\n        bool   fold.basic.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.basic.comment.explicit\n               This option enables folding explicit fold points when using the Basic lexer. Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.\n        string fold.basic.explicit.start\n               The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).\n        string fold.basic.explicit.end\n               The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).\n        bool   fold.basic.explicit.anywhere\n               Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\n        bool   fold.compact\n    Word Lists:\n        FreeBasic Keywords\n        FreeBasic PreProcessor Keywords\n        user defined 1\n        user defined 2\n\nLexer fsharp\n    Properties:\n        bool   fold\n        bool   fold.compact\n        bool   fold.comment\n               Setting this option to 0 disables comment folding in F# files.\n        bool   fold.fsharp.comment.stream\n               Setting this option to 0 disables folding of ML-style comments in F# files when fold.comment=1.\n        bool   fold.fsharp.comment.multiline\n               Setting this option to 0 disables folding of grouped line comments in F# files when fold.comment=1.\n        bool   fold.fsharp.preprocessor\n               Setting this option to 1 enables folding of F# compiler directives.\n        bool   fold.fsharp.quotes\n               Setting this option to 1 enables folding of multi-line strings in F# files.\n        bool   fold.fsharp.imports\n               Setting this option to 0 disables folding of F# import declarations.\n    Word Lists:\n        standard language keywords\n        core functions, including those in the FSharp.Collections namespace\n        built-in types, core namespaces, modules\n        optional\n        optional\n\nLexer gap\n    Word Lists:\n        Keywords 1\n        Keywords 2\n        Keywords 3 (unused)\n        Keywords 4 (unused)\n\nLexer gdscript\n    UnicodeLineEnds\n    Properties:\n        int    lexer.gdscript.whinge.level\n               For GDScript code, checks whether indenting is consistent. The default, 0 turns off indentation checking, 1 checks whether each line is potentially inconsistent with the previous line, 2 checks whether any space characters occur before a tab character in the indentation, 3 checks whether any spaces are in the indentation, and 4 checks for any tab characters in the indentation. 1 is a good level to use.\n        bool   lexer.gdscript.literals.binary\n               Set to 0 to not recognise binary and octal literals: 0b1011 0o712.\n        bool   lexer.gdscript.strings.over.newline\n               Set to 1 to allow strings to span newline characters.\n        bool   lexer.gdscript.keywords2.no.sub.identifiers\n               When enabled, it will not style keywords2 items that are used as a sub-identifier. Example: when set, will not highlight \"foo.open\" when \"open\" is a keywords2 item.\n        bool   fold\n        bool   fold.gdscript.quotes\n               This option enables folding multi-line quoted strings when using the GDScript lexer.\n        bool   fold.compact\n        bool   lexer.gdscript.unicode.identifiers\n               Set to 0 to not recognise Unicode identifiers.\n    Word Lists:\n        Keywords\n        Highlighted identifiers\n    Sub-Style Bases:\n         11\n    Styles:\n          0 SCE_GD_DEFAULT [default] White space\n          1 SCE_GD_COMMENTLINE [comment line] Comment\n          2 SCE_GD_NUMBER [literal numeric] Number\n          3 SCE_GD_STRING [literal string] String\n          4 SCE_GD_CHARACTER [literal string] Single quoted string\n          5 SCE_GD_WORD [keyword] Keyword\n          6 SCE_GD_TRIPLE [literal string] Triple quotes\n          7 SCE_GD_TRIPLEDOUBLE [literal string] Triple double quotes\n          8 SCE_GD_CLASSNAME [identifier] Class name definition\n          9 SCE_GD_FUNCNAME [identifier] Function or method name definition\n         10 SCE_GD_OPERATOR [operator] Operators\n         11 SCE_GD_IDENTIFIER [identifier] Identifiers\n         12 SCE_GD_COMMENTBLOCK [comment] Comment-blocks\n         13 SCE_GD_STRINGEOL [error literal string] End of line where string is not closed\n         14 SCE_GD_WORD2 [identifier] Highlighted identifiers\n         15 SCE_GD_ANNOTATION [annotation] Annotations\n         16 SCE_GD_NODEPATH [path] Node path\n\nLexer gui4cli\n    Word Lists:\n        Globals\n        Events\n        Attributes\n        Control\n        Commands\n\nLexer haskell\n    Properties:\n        bool   lexer.haskell.allow.hash\n               Set to 0 to disallow the '#' character at the end of identifiers and literals with the haskell lexer (GHC -XMagicHash extension)\n        bool   lexer.haskell.allow.quotes\n               Set to 0 to disable highlighting of Template Haskell name quotations and promoted constructors (GHC -XTemplateHaskell and -XDataKinds extensions)\n        bool   lexer.haskell.allow.questionmark\n               Set to 1 to allow the '?' character at the start of identifiers with the haskell lexer (GHC & Hugs -XImplicitParams extension)\n        bool   lexer.haskell.import.safe\n               Set to 0 to disallow \"safe\" keyword in imports (GHC -XSafe, -XTrustworthy, -XUnsafe extensions)\n        bool   lexer.haskell.cpp\n               Set to 0 to disable C-preprocessor highlighting (-XCPP extension)\n        bool   styling.within.preprocessor\n               For Haskell code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) or only from the initial # to the end of the command word(1).\n        bool   fold\n        bool   fold.comment\n        bool   fold.compact\n        bool   fold.haskell.imports\n               Set to 1 to enable folding of import declarations\n    Word Lists:\n        Keywords\n        FFI\n        Reserved operators\n\nLexer hollywood\n    Properties:\n        bool   fold\n        bool   fold.compact\n    Word Lists:\n        Hollywood keywords\n        Hollywood standard API functions\n        Hollywood plugin API functions\n        Hollywood plugin methods\n\nLexer hypertext\n    Properties:\n        int    asp.default.language\n               Script in ASP code is initially assumed to be in JavaScript. To change this to VBScript set asp.default.language to 2. Python is 3.\n        bool   html.tags.case.sensitive\n               For XML and HTML, setting this property to 1 will make tags match in a case sensitive way which is the expected behaviour for XML and XHTML.\n        bool   lexer.xml.allow.scripts\n               Set to 0 to disable scripts in XML.\n        int    lexer.xml.allow.php\n               Set to 0 to disable PHP in XML, 1 to accept <?php and <?=, 2 to also accept <?.The default is 2.\n        int    lexer.html.allow.php\n               Set to 0 to disable PHP in HTML, 1 to accept <?php and <?=, 2 to also accept <?.The default is 2.\n        bool   lexer.html.mako\n               Set to 1 to enable the mako template language.\n        bool   lexer.html.django\n               Set to 1 to enable the django template language.\n        bool   lexer.xml.allow.asp\n               Set to 0 to disable ASP in XML.\n        bool   lexer.html.allow.asp\n               Set to 0 to disable ASP in HTML.\n        bool   fold\n        bool   fold.html\n               Folding is turned on or off for HTML and XML files with this option. The fold option must also be on for folding to occur.\n        bool   fold.html.preprocessor\n               Folding is turned on or off for scripts embedded in HTML files with this option. The default is on.\n        bool   fold.compact\n        bool   fold.hypertext.comment\n               Allow folding for comments in scripts embedded in HTML. The default is off.\n        bool   fold.hypertext.heredoc\n               Allow folding for heredocs in scripts embedded in HTML. The default is off.\n        bool   fold.xml.at.tag.open\n               Enable folding for XML at the start of open tag. The default is off.\n    Word Lists:\n        HTML elements and attributes\n        JavaScript keywords\n        VBScript keywords\n        Python keywords\n        PHP keywords\n        SGML and DTD keywords\n    Sub-Style Bases:\n          1\n          3\n         46\n         61\n         74\n         96\n        121\n    Styles:\n          0 SCE_H_DEFAULT [default] Text\n          1 SCE_H_TAG [tag] Tags\n          2 SCE_H_TAGUNKNOWN [error tag] Unknown Tags\n          3 SCE_H_ATTRIBUTE [attribute] Attributes\n          4 SCE_H_ATTRIBUTEUNKNOWN [error attribute] Unknown Attributes\n          5 SCE_H_NUMBER [literal numeric] Numbers\n          6 SCE_H_DOUBLESTRING [literal string] Double quoted strings\n          7 SCE_H_SINGLESTRING [literal string] Single quoted strings\n          8 SCE_H_OTHER [tag operator] Other inside tag, including space and '='\n          9 SCE_H_COMMENT [comment] Comment\n         10 SCE_H_ENTITY [literal] Entities\n         11 SCE_H_TAGEND [tag] XML style tag ends '/>'\n         12 SCE_H_XMLSTART [identifier] XML identifier start '<?'\n         13 SCE_H_XMLEND [identifier] XML identifier end '?>'\n         14 SCE_H_SCRIPT [error] Internal state which should never be visible\n         15 SCE_H_ASP [preprocessor] ASP <% ... %>\n         16 SCE_H_ASPAT [preprocessor] ASP <% ... %>\n         17 SCE_H_CDATA [literal] CDATA\n         18 SCE_H_QUESTION [preprocessor] PHP\n         19 SCE_H_VALUE [literal string] Unquoted values\n         20 SCE_H_XCCOMMENT [comment] ASP.NET, JSP Comment <%-- ... --%>\n         21 SCE_H_SGML_DEFAULT [default] SGML tags <! ... >\n         22 SCE_H_SGML_COMMAND [preprocessor] SGML command\n         23 SCE_H_SGML_1ST_PARAM [preprocessor] SGML 1st param\n         24 SCE_H_SGML_DOUBLESTRING [literal string] SGML double string\n         25 SCE_H_SGML_SIMPLESTRING [literal string] SGML single string\n         26 SCE_H_SGML_ERROR [error] SGML error\n         27 SCE_H_SGML_SPECIAL [literal] SGML special (#XXXX type)\n         28 SCE_H_SGML_ENTITY [literal] SGML entity\n         29 SCE_H_SGML_COMMENT [comment] SGML comment\n         30 SCE_H_SGML_1ST_PARAM_COMMENT [error comment] SGML first parameter - lexer internal. It is an error if any text is in this style.\n         31 SCE_H_SGML_BLOCK_DEFAULT [default] SGML block\n         32  [predefined] \n         33  [predefined] \n         34  [predefined] \n         35  [predefined] \n         36  [predefined] \n         37  [predefined] \n         38  [predefined] \n         39  [predefined] \n         40 SCE_HJ_START [client javascript default] JS Start - allows eol filled background to not start on same line as SCRIPT tag\n         41 SCE_HJ_DEFAULT [client javascript default] JS Default\n         42 SCE_HJ_COMMENT [client javascript comment] JS Comment\n         43 SCE_HJ_COMMENTLINE [client javascript comment line] JS Line Comment\n         44 SCE_HJ_COMMENTDOC [client javascript comment documentation] JS Doc comment\n         45 SCE_HJ_NUMBER [client javascript literal numeric] JS Number\n         46 SCE_HJ_WORD [client javascript identifier] JS Word\n         47 SCE_HJ_KEYWORD [client javascript keyword] JS Keyword\n         48 SCE_HJ_DOUBLESTRING [client javascript literal string] JS Double quoted string\n         49 SCE_HJ_SINGLESTRING [client javascript literal string] JS Single quoted string\n         50 SCE_HJ_SYMBOLS [client javascript operator] JS Symbols\n         51 SCE_HJ_STRINGEOL [client javascript error literal string] JavaScript EOL\n         52 SCE_HJ_REGEX [client javascript literal regex] JavaScript RegEx\n         53 SCE_HJ_TEMPLATELITERAL [client javascript literal template] JS Template Literal\n         54  [unused] \n         55 SCE_HJA_START [server javascript default] JS Start - allows eol filled background to not start on same line as SCRIPT tag\n         56 SCE_HJA_DEFAULT [server javascript default] JS Default\n         57 SCE_HJA_COMMENT [server javascript comment] JS Comment\n         58 SCE_HJA_COMMENTLINE [server javascript comment line] JS Line Comment\n         59 SCE_HJA_COMMENTDOC [server javascript comment documentation] JS Doc comment\n         60 SCE_HJA_NUMBER [server javascript literal numeric] JS Number\n         61 SCE_HJA_WORD [server javascript identifier] JS Word\n         62 SCE_HJA_KEYWORD [server javascript keyword] JS Keyword\n         63 SCE_HJA_DOUBLESTRING [server javascript literal string] JS Double quoted string\n         64 SCE_HJA_SINGLESTRING [server javascript literal string] JS Single quoted string\n         65 SCE_HJA_SYMBOLS [server javascript operator] JS Symbols\n         66 SCE_HJA_STRINGEOL [server javascript error literal string] JavaScript EOL\n         67 SCE_HJA_REGEX [server javascript literal regex] JavaScript RegEx\n         68 SCE_HJA_TEMPLATELITERAL [server javascript literal template] JS Template Literal\n         69  [unused] \n         70 SCE_HB_START [client basic default] Start\n         71 SCE_HB_DEFAULT [client basic default] Default\n         72 SCE_HB_COMMENTLINE [client basic comment line] Comment\n         73 SCE_HB_NUMBER [client basic literal numeric] Number\n         74 SCE_HB_WORD [client basic keyword] KeyWord\n         75 SCE_HB_STRING [client basic literal string] String\n         76 SCE_HB_IDENTIFIER [client basic identifier] Identifier\n         77 SCE_HB_STRINGEOL [client basic literal string] Unterminated string\n         78  [unused] \n         79  [unused] \n         80 SCE_HBA_START [server basic default] Start\n         81 SCE_HBA_DEFAULT [server basic default] Default\n         82 SCE_HBA_COMMENTLINE [server basic comment line] Comment\n         83 SCE_HBA_NUMBER [server basic literal numeric] Number\n         84 SCE_HBA_WORD [server basic keyword] KeyWord\n         85 SCE_HBA_STRING [server basic literal string] String\n         86 SCE_HBA_IDENTIFIER [server basic identifier] Identifier\n         87 SCE_HBA_STRINGEOL [server basic literal string] Unterminated string\n         88  [unused] \n         89  [unused] \n         90 SCE_HP_START [client python default] Embedded Python\n         91 SCE_HP_DEFAULT [client python default] Embedded Python\n         92 SCE_HP_COMMENTLINE [client python comment line] Comment\n         93 SCE_HP_NUMBER [client python literal numeric] Number\n         94 SCE_HP_STRING [client python literal string] String\n         95 SCE_HP_CHARACTER [client python literal string character] Single quoted string\n         96 SCE_HP_WORD [client python keyword] Keyword\n         97 SCE_HP_TRIPLE [client python literal string] Triple quotes\n         98 SCE_HP_TRIPLEDOUBLE [client python literal string] Triple double quotes\n         99 SCE_HP_CLASSNAME [client python identifier] Class name definition\n        100 SCE_HP_DEFNAME [client python identifier] Function or method name definition\n        101 SCE_HP_OPERATOR [client python operator] Operators\n        102 SCE_HP_IDENTIFIER [client python identifier] Identifiers\n        103  [unused] \n        104 SCE_HPHP_COMPLEX_VARIABLE [server php identifier] PHP complex variable\n        105 SCE_HPA_START [server python default] ASP Python\n        106 SCE_HPA_DEFAULT [server python default] ASP Python\n        107 SCE_HPA_COMMENTLINE [server python comment line] Comment\n        108 SCE_HPA_NUMBER [server python literal numeric] Number\n        109 SCE_HPA_STRING [server python literal string] String\n        110 SCE_HPA_CHARACTER [server python literal string character] Single quoted string\n        111 SCE_HPA_WORD [server python keyword] Keyword\n        112 SCE_HPA_TRIPLE [server python literal string] Triple quotes\n        113 SCE_HPA_TRIPLEDOUBLE [server python literal string] Triple double quotes\n        114 SCE_HPA_CLASSNAME [server python identifier] Class name definition\n        115 SCE_HPA_DEFNAME [server python identifier] Function or method name definition\n        116 SCE_HPA_OPERATOR [server python operator] Operators\n        117 SCE_HPA_IDENTIFIER [server python identifier] Identifiers\n        118 SCE_HPHP_DEFAULT [server php default] Default\n        119 SCE_HPHP_HSTRING [server php literal string] Double quoted String\n        120 SCE_HPHP_SIMPLESTRING [server php literal string] Single quoted string\n        121 SCE_HPHP_WORD [server php keyword] Keyword\n        122 SCE_HPHP_NUMBER [server php literal numeric] Number\n        123 SCE_HPHP_VARIABLE [server php identifier] Variable\n        124 SCE_HPHP_COMMENT [server php comment] Comment\n        125 SCE_HPHP_COMMENTLINE [server php comment line] One line comment\n        126 SCE_HPHP_HSTRING_VARIABLE [server php literal string identifier] PHP variable in double quoted string\n        127 SCE_HPHP_OPERATOR [server php operator] PHP operator\n\nLexer ihex\n\nLexer indent\n\nLexer inno\n    Word Lists:\n        Sections\n        Keywords\n        Parameters\n        Preprocessor directives\n        Pascal keywords\n        User defined keywords\n\nLexer json\n    Properties:\n        bool   lexer.json.escape.sequence\n               Set to 1 to enable highlighting of escape sequences in strings\n        bool   lexer.json.allow.comments\n               Set to 1 to enable highlighting of line/block comments in JSON\n        bool   fold.compact\n        bool   fold\n    Word Lists:\n        JSON Keywords\n        JSON-LD Keywords\n\nLexer julia\n    Properties:\n        bool   fold\n        bool   fold.compact\n        bool   fold.comment\n        bool   fold.julia.docstring\n               Fold multiline triple-doublequote strings, usually used to document a function or type above the definition.\n        bool   fold.julia.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   lexer.julia.highlight.typeannotation\n               This option enables highlighting of the type identifier after `::`.\n        bool   lexer.julia.highlight.lexerror\n               This option enables highlighting of syntax error int character or number definition.\n    Word Lists:\n        Primary keywords and identifiers\n        Built in types\n        Other keywords\n        Built in functions\n    Styles:\n          0 SCE_JULIA_DEFAULT [default] White space\n          1 SCE_JULIA_COMMENT [comment] Comment\n          2 SCE_JULIA_NUMBER [literal numeric] Number\n          3 SCE_JULIA_KEYWORD1 [keyword] Reserved keywords\n          4 SCE_JULIA_KEYWORD2 [identifier] Builtin type names\n          5 SCE_JULIA_KEYWORD3 [identifier] Constants\n          6 SCE_JULIA_CHAR [literal string character] Single quoted string\n          7 SCE_JULIA_OPERATOR [operator] Operator\n          8 SCE_JULIA_BRACKET [bracket operator] Bracket operator\n          9 SCE_JULIA_IDENTIFIER [identifier] Identifier\n         10 SCE_JULIA_STRING [literal string] Double quoted String\n         11 SCE_JULIA_SYMBOL [literal string symbol] Symbol\n         12 SCE_JULIA_MACRO [macro preprocessor] Macro\n         13 SCE_JULIA_STRINGINTERP [literal string interpolated] String interpolation\n         14 SCE_JULIA_DOCSTRING [literal string documentation] Docstring\n         15 SCE_JULIA_STRINGLITERAL [literal string] String literal prefix\n         16 SCE_JULIA_COMMAND [literal string command] Command\n         17 SCE_JULIA_COMMANDLITERAL [literal string command] Command literal prefix\n         18 SCE_JULIA_TYPEANNOT [identifier type] Type annotation identifier\n         19 SCE_JULIA_LEXERROR [lexer error] Lexing error\n         20 SCE_JULIA_KEYWORD4 [identifier] Builtin function names\n         21 SCE_JULIA_TYPEOPERATOR [operator type] Type annotation operator\n\nLexer kix\n\nLexer kvirc\n    Word Lists:\n        primary\n        function_keywords\n\nLexer latex\n\nLexer lisp\n    Word Lists:\n        Functions and special operators\n        Keywords\n\nLexer literatehaskell\n    Properties:\n        bool   lexer.haskell.allow.hash\n               Set to 0 to disallow the '#' character at the end of identifiers and literals with the haskell lexer (GHC -XMagicHash extension)\n        bool   lexer.haskell.allow.quotes\n               Set to 0 to disable highlighting of Template Haskell name quotations and promoted constructors (GHC -XTemplateHaskell and -XDataKinds extensions)\n        bool   lexer.haskell.allow.questionmark\n               Set to 1 to allow the '?' character at the start of identifiers with the haskell lexer (GHC & Hugs -XImplicitParams extension)\n        bool   lexer.haskell.import.safe\n               Set to 0 to disallow \"safe\" keyword in imports (GHC -XSafe, -XTrustworthy, -XUnsafe extensions)\n        bool   lexer.haskell.cpp\n               Set to 0 to disable C-preprocessor highlighting (-XCPP extension)\n        bool   styling.within.preprocessor\n               For Haskell code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) or only from the initial # to the end of the command word(1).\n        bool   fold\n        bool   fold.comment\n        bool   fold.compact\n        bool   fold.haskell.imports\n               Set to 1 to enable folding of import declarations\n    Word Lists:\n        Keywords\n        FFI\n        Reserved operators\n\nLexer lot\n\nLexer lout\n    Word Lists:\n        Predefined identifiers\n        Predefined delimiters\n        Predefined keywords\n\nLexer lua\n    Properties:\n        bool   fold.compact\n    Word Lists:\n        Keywords\n        Basic functions\n        String, (table) & math functions\n        (coroutines), I/O & system facilities\n        user1\n        user2\n        user3\n        user4\n    Sub-Style Bases:\n         11\n    Styles:\n          0 SCE_LUA_DEFAULT [default] White space: Visible only in View Whitespace mode (or if it has a back colour)\n          1 SCE_LUA_COMMENT [comment] Block comment (Lua 5.0)\n          2 SCE_LUA_COMMENTLINE [comment line] Line comment\n          3 SCE_LUA_COMMENTDOC [comment documentation] Doc comment\n          4 SCE_LUA_NUMBER [literal numeric] Number\n          5 SCE_LUA_WORD [keyword] Keyword\n          6 SCE_LUA_STRING [literal string] (Double quoted) String\n          7 SCE_LUA_CHARACTER [literal string character] Character (Single quoted string)\n          8 SCE_LUA_LITERALSTRING [literal string] Literal string\n          9 SCE_LUA_PREPROCESSOR [preprocessor] Preprocessor (obsolete in Lua 4.0 and up)\n         10 SCE_LUA_OPERATOR [operator] Operators\n         11 SCE_LUA_IDENTIFIER [identifier] Identifier (everything else...)\n         12 SCE_LUA_STRINGEOL [error literal string] End of line where string is not closed\n         13 SCE_LUA_WORD2 [identifier] Other keywords\n         14 SCE_LUA_WORD3 [identifier] Other keywords\n         15 SCE_LUA_WORD4 [identifier] Other keywords\n         16 SCE_LUA_WORD5 [identifier] Other keywords\n         17 SCE_LUA_WORD6 [identifier] Other keywords\n         18 SCE_LUA_WORD7 [identifier] Other keywords\n         19 SCE_LUA_WORD8 [identifier] Other keywords\n         20 SCE_LUA_LABEL [label] Labels\n\nLexer magiksf\n    Word Lists:\n        Accessors (local, global, self, super, thisthread)\n        Pragmatic (pragma, private)\n        Containers (method, block, proc)\n        Flow (if, then, elif, else)\n        Characters (space, tab, newline, return)\n        Fold Containers (method, proc, block, if, loop)\n\nLexer makefile\n    Word Lists:\n        Directives\n    Styles:\n          0 SCE_MAKE_DEFAULT [default] White space\n          1 SCE_MAKE_COMMENT [comment] Comment\n          2 SCE_MAKE_PREPROCESSOR [preprocessor] Preprocessor\n          3 SCE_MAKE_IDENTIFIER [identifier] Identifiers\n          4 SCE_MAKE_OPERATOR [operator] Operator\n          5 SCE_MAKE_TARGET [identifier] Identifiers\n          6  [unused] \n          7  [unused] \n          8  [unused] \n          9 SCE_MAKE_IDEOL [error identifier] Incomplete identifier reference\n\nLexer markdown\n\nLexer matlab\n    Word Lists:\n        Keywords\n\nLexer maxima\n\nLexer metapost\n    Word Lists:\n        MetaPost\n        MetaFun\n\nLexer mmixal\n    Word Lists:\n        Operation Codes\n        Special Register\n        Predefined Symbols\n\nLexer modula\n    Word Lists:\n        Keywords\n        ReservedKeywords\n        Operators\n        PragmaKeyswords\n        EscapeCodes\n        DoxygeneKeywords\n\nLexer mssql\n    Word Lists:\n        Statements\n        Data Types\n        System tables\n        Global variables\n        Functions\n        System Stored Procedures\n        Operators\n\nLexer mysql\n    Word Lists:\n        Major Keywords\n        Keywords\n        Database Objects\n        Functions\n        System Variables\n        Procedure keywords\n        User Keywords 1\n        User Keywords 2\n        User Keywords 3\n\nLexer nim\n    UnicodeLineEnds\n    Properties:\n        bool   lexer.nim.raw.strings.highlight.ident\n               Set to 1 to enable highlighting generalized raw string identifiers. Generalized raw string identifiers are anything other than r (or R).\n        bool   fold\n        bool   fold.compact\n    Word Lists:\n        Keywords\n    Styles:\n          0 SCE_NIM_DEFAULT [default] White space\n          1 SCE_NIM_COMMENT [comment block] Block comment\n          2 SCE_NIM_COMMENTDOC [comment block doc] Block doc comment\n          3 SCE_NIM_COMMENTLINE [comment line] Line comment\n          4 SCE_NIM_COMMENTLINEDOC [comment doc] Line doc comment\n          5 SCE_NIM_NUMBER [literal numeric] Number\n          6 SCE_NIM_STRING [literal string] String\n          7 SCE_NIM_CHARACTER [literal string] Single quoted string\n          8 SCE_NIM_WORD [keyword] Keyword\n          9 SCE_NIM_TRIPLE [literal string] Triple quotes\n         10 SCE_NIM_TRIPLEDOUBLE [literal string] Triple double quotes\n         11 SCE_NIM_BACKTICKS [operator definition] Identifiers\n         12 SCE_NIM_FUNCNAME [identifier] Function name definition\n         13 SCE_NIM_STRINGEOL [error literal string] String is not closed\n         14 SCE_NIM_NUMERROR [numeric error] Numeric format error\n         15 SCE_NIM_OPERATOR [operator] Operators\n         16 SCE_NIM_IDENTIFIER [identifier] Identifiers\n\nLexer nimrod\n    Word Lists:\n        Keywords\n\nLexer nix\n    Properties:\n        bool   fold\n    Word Lists:\n        Keywords 1\n        Keywords 2\n        Keywords 3\n        Keywords 4\n    Styles:\n          0 SCE_NIX_DEFAULT [default] White space\n          1 SCE_NIX_COMMENTLINE [comment line] Comment: //\n          2 SCE_NIX_COMMENTBLOCK [comment] Comment: /* */\n          3 SCE_NIX_STRING [literal string] Double quoted string\n          4 SCE_NIX_STRING_MULTILINE [literal string multiline] Single quoted multiline string\n          5 SCE_NIX_ESCAPECHAR [literal string escapesequence] Escape sequence\n          6 SCE_NIX_IDENTIFIER [identifier] Identifier\n          7 SCE_NIX_OPERATOR [operator] Operator\n          8 SCE_NIX_OPERATOR_STRING [operator interpolated] Braces following $ inside string\n          9 SCE_NIX_NUMBER [literal numeric] Number\n         10 SCE_NIX_KEY [key] Keys preceding '='\n         11 SCE_NIX_PATH [identifier] Path literal\n         12 SCE_NIX_KEYWORD1 [keyword] Primary keywords\n         13 SCE_NIX_KEYWORD2 [identifier] Keywords 2\n         14 SCE_NIX_KEYWORD3 [identifier] Keywords 3\n         15 SCE_NIX_KEYWORD4 [identifier] Keywords 4\n         16 SCE_NIX_STRINGEOL [error literal string] End of line where string is not closed\n\nLexer nncrontab\n    Word Lists:\n        Section keywords and Forth words\n        nnCrontab keywords\n        Modifiers\n\nLexer nsis\n    Word Lists:\n        Functions\n        Variables\n        Lables\n        UserDefined\n\nLexer null\n\nLexer octave\n    Word Lists:\n        Keywords\n\nLexer opal\n    Word Lists:\n        Keywords\n        Sorts\n\nLexer oscript\n    Word Lists:\n        Keywords and reserved words\n        Literal constants\n        Literal operators\n        Built-in value and reference types\n        Built-in global functions\n        Built-in static objects\n\nLexer pascal\n    Properties:\n        bool   lexer.pascal.smart.highlighting\n               Set to 0 to not completely handle some complex features like 'property'.\n        bool   fold\n        bool   fold.comment\n        bool   fold.preprocessor\n        bool   fold.compact\n    Word Lists:\n        Keywords\n    Styles:\n          0 SCE_PAS_DEFAULT [default] White space\n          1 SCE_PAS_IDENTIFIER [identifier] Identifier\n          2 SCE_PAS_COMMENT [comment] Comment: { ... }\n          3 SCE_PAS_COMMENT2 [comment] Comment: (* ... *)\n          4 SCE_PAS_COMMENTLINE [comment line] Line Comment: // ...\n          5 SCE_PAS_PREPROCESSOR [preprocessor] Preprocessor: {$ ... }\n          6 SCE_PAS_PREPROCESSOR2 [preprocessor] Preprocessor: (*$ ... *)\n          7 SCE_PAS_NUMBER [literal numeric] Number\n          8 SCE_PAS_HEXNUMBER [literal numeric] Hex Number\n          9 SCE_PAS_WORD [keyword] Keyword\n         10 SCE_PAS_STRING [literal string] Single quoted string\n         11 SCE_PAS_STRINGEOL [error literal string] End of line where string is not closed\n         12 SCE_PAS_CHARACTER [literal string character] Character\n         13 SCE_PAS_OPERATOR [operator] Operator\n         14 SCE_PAS_ASM [assembler] Inline Assembler\n         15 SCE_PAS_MULTILINESTRING [literal string multiline] Triple quoted multiline string\n\nLexer powerbasic\n    Word Lists:\n        Keywords\n\nLexer perl\n    Properties:\n        bool   fold\n        bool   fold.comment\n        bool   fold.compact\n        bool   fold.perl.pod\n               Set to 0 to disable folding Pod blocks when using the Perl lexer.\n        bool   fold.perl.package\n               Set to 0 to disable folding packages when using the Perl lexer.\n        bool   fold.perl.comment.explicit\n               Set to 0 to disable explicit folding.\n        bool   fold.perl.at.else\n               This option enables Perl folding on a \"} else {\" line of an if statement.\n    Word Lists:\n        Keywords\n    Styles:\n          0 SCE_PL_DEFAULT [default] white space\n          1 SCE_PL_ERROR [error] error\n          2 SCE_PL_COMMENTLINE [comment line] comment\n          3 SCE_PL_POD [data] pod: = at beginning of line\n          4 SCE_PL_NUMBER [literal numeric] number\n          5 SCE_PL_WORD [keyword] keyword\n          6 SCE_PL_STRING [literal string interpolated] double quoted string\n          7 SCE_PL_CHARACTER [literal string] single quoted string\n          8 SCE_PL_PUNCTUATION [operator] symbols / punctuation. currently not used\n          9 SCE_PL_PREPROCESSOR [preprocessor unused] preprocessor. currently not used\n         10 SCE_PL_OPERATOR [operator] operators\n         11 SCE_PL_IDENTIFIER [identifier] identifiers (functions, etc.)\n         12 SCE_PL_SCALAR [identifier] scalars: $var\n         13 SCE_PL_ARRAY [identifier] array: @var\n         14 SCE_PL_HASH [identifier] hash: %var\n         15 SCE_PL_SYMBOLTABLE [identifier] symbol table: *var\n         16 SCE_PL_VARIABLE_INDEXER [identifier unused] sce_pl_variable_indexer allocated but unused\n         17 SCE_PL_REGEX [literal regex] regex: /re/ or m{re}\n         18 SCE_PL_REGSUBST [literal regex] substitution: s/re/ore/\n         19 SCE_PL_LONGQUOTE [literal string] long quote (qq, qr, qw, qx) -- obsolete: replaced by qq, qx, qr, qw\n         20 SCE_PL_BACKTICKS [literal string interpolated] back ticks\n         21 SCE_PL_DATASECTION [data] data section: __data__ or __end__ at beginning of line\n         22 SCE_PL_HERE_DELIM [here-doc literal string] here-doc (delimiter)\n         23 SCE_PL_HERE_Q [here-doc literal string] here-doc (single quoted, q)\n         24 SCE_PL_HERE_QQ [here-doc literal string interpolated] here-doc (double quoted, qq)\n         25 SCE_PL_HERE_QX [here-doc literal interpolated] here-doc (back ticks, qx)\n         26 SCE_PL_STRING_Q [literal string] single quoted string, generic\n         27 SCE_PL_STRING_QQ [literal string interpolated] qq = double quoted string\n         28 SCE_PL_STRING_QX [literal string interpolated] qx = back ticks\n         29 SCE_PL_STRING_QR [literal regex] qr = regex\n         30 SCE_PL_STRING_QW [literal string interpolated] qw = array\n         31 SCE_PL_POD_VERB [data] pod: verbatim paragraphs\n         32  [predefined] \n         33  [predefined] \n         34  [predefined] \n         35  [predefined] \n         36  [predefined] \n         37  [predefined] \n         38  [predefined] \n         39  [predefined] \n         40 SCE_PL_SUB_PROTOTYPE [identifier] subroutine prototype\n         41 SCE_PL_FORMAT_IDENT [identifier] format identifier\n         42 SCE_PL_FORMAT [literal string] format body\n         43 SCE_PL_STRING_VAR [identifier interpolated] double quoted string (interpolated variable)\n         44 SCE_PL_XLAT [literal string] translation: tr{}{} y{}{}\n         45  [unused] \n         46  [unused] \n         47  [unused] \n         48  [unused] \n         49  [unused] \n         50  [unused] \n         51  [unused] \n         52  [unused] \n         53  [unused] \n         54 SCE_PL_REGEX_VAR [identifier interpolated] regex: /re/ or m{re} (interpolated variable)\n         55 SCE_PL_REGSUBST_VAR [identifier interpolated] substitution: s/re/ore/ (interpolated variable)\n         56  [unused] \n         57 SCE_PL_BACKTICKS_VAR [identifier interpolated] back ticks (interpolated variable)\n         58  [unused] \n         59  [unused] \n         60  [unused] \n         61 SCE_PL_HERE_QQ_VAR [identifier interpolated] here-doc (double quoted, qq) (interpolated variable)\n         62 SCE_PL_HERE_QX_VAR [identifier interpolated] here-doc (back ticks, qx) (interpolated variable)\n         63  [unused] \n         64 SCE_PL_STRING_QQ_VAR [identifier interpolated] qq = double quoted string (interpolated variable)\n         65 SCE_PL_STRING_QX_VAR [identifier interpolated] qx = back ticks (interpolated variable)\n         66 SCE_PL_STRING_QR_VAR [identifier interpolated] qr = regex (interpolated variable)\n\nLexer phpscript\n    Properties:\n        int    asp.default.language\n               Script in ASP code is initially assumed to be in JavaScript. To change this to VBScript set asp.default.language to 2. Python is 3.\n        bool   html.tags.case.sensitive\n               For XML and HTML, setting this property to 1 will make tags match in a case sensitive way which is the expected behaviour for XML and XHTML.\n        bool   lexer.xml.allow.scripts\n               Set to 0 to disable scripts in XML.\n        int    lexer.xml.allow.php\n               Set to 0 to disable PHP in XML, 1 to accept <?php and <?=, 2 to also accept <?.The default is 2.\n        int    lexer.html.allow.php\n               Set to 0 to disable PHP in HTML, 1 to accept <?php and <?=, 2 to also accept <?.The default is 2.\n        bool   lexer.html.mako\n               Set to 1 to enable the mako template language.\n        bool   lexer.html.django\n               Set to 1 to enable the django template language.\n        bool   lexer.xml.allow.asp\n               Set to 0 to disable ASP in XML.\n        bool   lexer.html.allow.asp\n               Set to 0 to disable ASP in HTML.\n        bool   fold\n        bool   fold.html\n               Folding is turned on or off for HTML and XML files with this option. The fold option must also be on for folding to occur.\n        bool   fold.html.preprocessor\n               Folding is turned on or off for scripts embedded in HTML files with this option. The default is on.\n        bool   fold.compact\n        bool   fold.hypertext.comment\n               Allow folding for comments in scripts embedded in HTML. The default is off.\n        bool   fold.hypertext.heredoc\n               Allow folding for heredocs in scripts embedded in HTML. The default is off.\n        bool   fold.xml.at.tag.open\n               Enable folding for XML at the start of open tag. The default is off.\n    Word Lists:\n        \n        \n        \n        \n        PHP keywords\n        \n    Sub-Style Bases:\n          1\n          3\n         46\n         61\n         74\n         96\n        121\n    Styles:\n          0 SCE_H_DEFAULT [default] Text\n          1 SCE_H_TAG [tag] Tags\n          2 SCE_H_TAGUNKNOWN [error tag] Unknown Tags\n          3 SCE_H_ATTRIBUTE [attribute] Attributes\n          4 SCE_H_ATTRIBUTEUNKNOWN [error attribute] Unknown Attributes\n          5 SCE_H_NUMBER [literal numeric] Numbers\n          6 SCE_H_DOUBLESTRING [literal string] Double quoted strings\n          7 SCE_H_SINGLESTRING [literal string] Single quoted strings\n          8 SCE_H_OTHER [tag operator] Other inside tag, including space and '='\n          9 SCE_H_COMMENT [comment] Comment\n         10 SCE_H_ENTITY [literal] Entities\n         11 SCE_H_TAGEND [tag] XML style tag ends '/>'\n         12 SCE_H_XMLSTART [identifier] XML identifier start '<?'\n         13 SCE_H_XMLEND [identifier] XML identifier end '?>'\n         14 SCE_H_SCRIPT [error] Internal state which should never be visible\n         15 SCE_H_ASP [preprocessor] ASP <% ... %>\n         16 SCE_H_ASPAT [preprocessor] ASP <% ... %>\n         17 SCE_H_CDATA [literal] CDATA\n         18 SCE_H_QUESTION [preprocessor] PHP\n         19 SCE_H_VALUE [literal string] Unquoted values\n         20 SCE_H_XCCOMMENT [comment] ASP.NET, JSP Comment <%-- ... --%>\n         21 SCE_H_SGML_DEFAULT [default] SGML tags <! ... >\n         22 SCE_H_SGML_COMMAND [preprocessor] SGML command\n         23 SCE_H_SGML_1ST_PARAM [preprocessor] SGML 1st param\n         24 SCE_H_SGML_DOUBLESTRING [literal string] SGML double string\n         25 SCE_H_SGML_SIMPLESTRING [literal string] SGML single string\n         26 SCE_H_SGML_ERROR [error] SGML error\n         27 SCE_H_SGML_SPECIAL [literal] SGML special (#XXXX type)\n         28 SCE_H_SGML_ENTITY [literal] SGML entity\n         29 SCE_H_SGML_COMMENT [comment] SGML comment\n         30 SCE_H_SGML_1ST_PARAM_COMMENT [error comment] SGML first parameter - lexer internal. It is an error if any text is in this style.\n         31 SCE_H_SGML_BLOCK_DEFAULT [default] SGML block\n         32  [predefined] \n         33  [predefined] \n         34  [predefined] \n         35  [predefined] \n         36  [predefined] \n         37  [predefined] \n         38  [predefined] \n         39  [predefined] \n         40 SCE_HJ_START [client javascript default] JS Start - allows eol filled background to not start on same line as SCRIPT tag\n         41 SCE_HJ_DEFAULT [client javascript default] JS Default\n         42 SCE_HJ_COMMENT [client javascript comment] JS Comment\n         43 SCE_HJ_COMMENTLINE [client javascript comment line] JS Line Comment\n         44 SCE_HJ_COMMENTDOC [client javascript comment documentation] JS Doc comment\n         45 SCE_HJ_NUMBER [client javascript literal numeric] JS Number\n         46 SCE_HJ_WORD [client javascript identifier] JS Word\n         47 SCE_HJ_KEYWORD [client javascript keyword] JS Keyword\n         48 SCE_HJ_DOUBLESTRING [client javascript literal string] JS Double quoted string\n         49 SCE_HJ_SINGLESTRING [client javascript literal string] JS Single quoted string\n         50 SCE_HJ_SYMBOLS [client javascript operator] JS Symbols\n         51 SCE_HJ_STRINGEOL [client javascript error literal string] JavaScript EOL\n         52 SCE_HJ_REGEX [client javascript literal regex] JavaScript RegEx\n         53 SCE_HJ_TEMPLATELITERAL [client javascript literal template] JS Template Literal\n         54  [unused] \n         55 SCE_HJA_START [server javascript default] JS Start - allows eol filled background to not start on same line as SCRIPT tag\n         56 SCE_HJA_DEFAULT [server javascript default] JS Default\n         57 SCE_HJA_COMMENT [server javascript comment] JS Comment\n         58 SCE_HJA_COMMENTLINE [server javascript comment line] JS Line Comment\n         59 SCE_HJA_COMMENTDOC [server javascript comment documentation] JS Doc comment\n         60 SCE_HJA_NUMBER [server javascript literal numeric] JS Number\n         61 SCE_HJA_WORD [server javascript identifier] JS Word\n         62 SCE_HJA_KEYWORD [server javascript keyword] JS Keyword\n         63 SCE_HJA_DOUBLESTRING [server javascript literal string] JS Double quoted string\n         64 SCE_HJA_SINGLESTRING [server javascript literal string] JS Single quoted string\n         65 SCE_HJA_SYMBOLS [server javascript operator] JS Symbols\n         66 SCE_HJA_STRINGEOL [server javascript error literal string] JavaScript EOL\n         67 SCE_HJA_REGEX [server javascript literal regex] JavaScript RegEx\n         68 SCE_HJA_TEMPLATELITERAL [server javascript literal template] JS Template Literal\n         69  [unused] \n         70 SCE_HB_START [client basic default] Start\n         71 SCE_HB_DEFAULT [client basic default] Default\n         72 SCE_HB_COMMENTLINE [client basic comment line] Comment\n         73 SCE_HB_NUMBER [client basic literal numeric] Number\n         74 SCE_HB_WORD [client basic keyword] KeyWord\n         75 SCE_HB_STRING [client basic literal string] String\n         76 SCE_HB_IDENTIFIER [client basic identifier] Identifier\n         77 SCE_HB_STRINGEOL [client basic literal string] Unterminated string\n         78  [unused] \n         79  [unused] \n         80 SCE_HBA_START [server basic default] Start\n         81 SCE_HBA_DEFAULT [server basic default] Default\n         82 SCE_HBA_COMMENTLINE [server basic comment line] Comment\n         83 SCE_HBA_NUMBER [server basic literal numeric] Number\n         84 SCE_HBA_WORD [server basic keyword] KeyWord\n         85 SCE_HBA_STRING [server basic literal string] String\n         86 SCE_HBA_IDENTIFIER [server basic identifier] Identifier\n         87 SCE_HBA_STRINGEOL [server basic literal string] Unterminated string\n         88  [unused] \n         89  [unused] \n         90 SCE_HP_START [client python default] Embedded Python\n         91 SCE_HP_DEFAULT [client python default] Embedded Python\n         92 SCE_HP_COMMENTLINE [client python comment line] Comment\n         93 SCE_HP_NUMBER [client python literal numeric] Number\n         94 SCE_HP_STRING [client python literal string] String\n         95 SCE_HP_CHARACTER [client python literal string character] Single quoted string\n         96 SCE_HP_WORD [client python keyword] Keyword\n         97 SCE_HP_TRIPLE [client python literal string] Triple quotes\n         98 SCE_HP_TRIPLEDOUBLE [client python literal string] Triple double quotes\n         99 SCE_HP_CLASSNAME [client python identifier] Class name definition\n        100 SCE_HP_DEFNAME [client python identifier] Function or method name definition\n        101 SCE_HP_OPERATOR [client python operator] Operators\n        102 SCE_HP_IDENTIFIER [client python identifier] Identifiers\n        103  [unused] \n        104 SCE_HPHP_COMPLEX_VARIABLE [server php identifier] PHP complex variable\n        105 SCE_HPA_START [server python default] ASP Python\n        106 SCE_HPA_DEFAULT [server python default] ASP Python\n        107 SCE_HPA_COMMENTLINE [server python comment line] Comment\n        108 SCE_HPA_NUMBER [server python literal numeric] Number\n        109 SCE_HPA_STRING [server python literal string] String\n        110 SCE_HPA_CHARACTER [server python literal string character] Single quoted string\n        111 SCE_HPA_WORD [server python keyword] Keyword\n        112 SCE_HPA_TRIPLE [server python literal string] Triple quotes\n        113 SCE_HPA_TRIPLEDOUBLE [server python literal string] Triple double quotes\n        114 SCE_HPA_CLASSNAME [server python identifier] Class name definition\n        115 SCE_HPA_DEFNAME [server python identifier] Function or method name definition\n        116 SCE_HPA_OPERATOR [server python operator] Operators\n        117 SCE_HPA_IDENTIFIER [server python identifier] Identifiers\n        118 SCE_HPHP_DEFAULT [server php default] Default\n        119 SCE_HPHP_HSTRING [server php literal string] Double quoted String\n        120 SCE_HPHP_SIMPLESTRING [server php literal string] Single quoted string\n        121 SCE_HPHP_WORD [server php keyword] Keyword\n        122 SCE_HPHP_NUMBER [server php literal numeric] Number\n        123 SCE_HPHP_VARIABLE [server php identifier] Variable\n        124 SCE_HPHP_COMMENT [server php comment] Comment\n        125 SCE_HPHP_COMMENTLINE [server php comment line] One line comment\n        126 SCE_HPHP_HSTRING_VARIABLE [server php literal string identifier] PHP variable in double quoted string\n        127 SCE_HPHP_OPERATOR [server php operator] PHP operator\n\nLexer PL/M\n    Word Lists:\n        Keywords\n\nLexer po\n\nLexer pov\n    Word Lists:\n        Language directives\n        Objects & CSG & Appearance\n        Types & Modifiers & Items\n        Predefined Identifiers\n        Predefined Functions\n        User defined 1\n        User defined 2\n        User defined 3\n\nLexer powerpro\n    Word Lists:\n        Keyword list 1\n        Keyword list 2\n        Keyword list 3\n        Keyword list 4\n\nLexer powershell\n    Word Lists:\n        Commands\n        Cmdlets\n        Aliases\n        Functions\n        User1\n        DocComment\n\nLexer abl\n    Properties:\n        bool   fold\n        bool   fold.abl.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.comment\n               This option enables folding multi-line comments and explicit fold points when using the ABL lexer. \n        bool   fold.abl.comment.multiline\n               Set this property to 0 to disable folding multi-line comments when fold.comment=1.\n        bool   fold.compact\n    Word Lists:\n        Primary keywords and identifiers\n        Keywords that opens a block, only when used to begin a syntactic line\n        Keywords that opens a block anywhere in a syntactic line\n        Task Marker\n\nLexer props\n\nLexer ps\n    Word Lists:\n        PS Level 1 operators\n        PS Level 2 operators\n        PS Level 3 operators\n        RIP-specific operators\n        User-defined operators\n\nLexer purebasic\n    Properties:\n        bool   fold\n        bool   fold.basic.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.basic.comment.explicit\n               This option enables folding explicit fold points when using the Basic lexer. Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.\n        string fold.basic.explicit.start\n               The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).\n        string fold.basic.explicit.end\n               The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).\n        bool   fold.basic.explicit.anywhere\n               Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\n        bool   fold.compact\n    Word Lists:\n        PureBasic Keywords\n        PureBasic PreProcessor Keywords\n        user defined 1\n        user defined 2\n\nLexer python\n    UnicodeLineEnds\n    Properties:\n        int    tab.timmy.whinge.level\n               For Python code, checks whether indenting is consistent. The default, 0 turns off indentation checking, 1 checks whether each line is potentially inconsistent with the previous line, 2 checks whether any space characters occur before a tab character in the indentation, 3 checks whether any spaces are in the indentation, and 4 checks for any tab characters in the indentation. 1 is a good level to use.\n        bool   lexer.python.literals.binary\n               Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.\n        bool   lexer.python.strings.u\n               Set to 0 to not recognise Python Unicode literals u\"x\" as used before Python 3.\n        bool   lexer.python.strings.b\n               Set to 0 to not recognise Python 3 bytes literals b\"x\".\n        bool   lexer.python.strings.f\n               Set to 0 to not recognise Python 3.6 f-string literals f\"var={var}\".\n        bool   lexer.python.strings.f.pep.701\n               Set to 0 to use pre-PEP 701 / Python 3.12 f-string lexing.\n        bool   lexer.python.strings.t\n               Set to 0 to not recognise Python 3.14 t-string literals t\"var={var}\".\n        bool   lexer.python.strings.over.newline\n               Set to 1 to allow strings to span newline characters.\n        bool   lexer.python.keywords2.no.sub.identifiers\n               When enabled, it will not style keywords2 items that are used as a sub-identifier. Example: when set, will not highlight \"foo.open\" when \"open\" is a keywords2 item.\n        bool   fold\n        bool   fold.quotes.python\n               This option enables folding multi-line quoted strings when using the Python lexer.\n        bool   fold.compact\n        bool   lexer.python.unicode.identifiers\n               Set to 0 to not recognise Python 3 Unicode identifiers.\n        int    lexer.python.identifier.attributes\n               Set to 1 to recognise Python identifier attributes.\n        int    lexer.python.decorator.attributes\n               Set to 1 to recognise Python decorator attributes.\n    Word Lists:\n        Keywords\n        Highlighted identifiers\n    Sub-Style Bases:\n         11\n    Styles:\n          0 SCE_P_DEFAULT [default] White space\n          1 SCE_P_COMMENTLINE [comment line] Comment\n          2 SCE_P_NUMBER [literal numeric] Number\n          3 SCE_P_STRING [literal string] String\n          4 SCE_P_CHARACTER [literal string] Single quoted string\n          5 SCE_P_WORD [keyword] Keyword\n          6 SCE_P_TRIPLE [literal string] Triple quotes\n          7 SCE_P_TRIPLEDOUBLE [literal string] Triple double quotes\n          8 SCE_P_CLASSNAME [identifier] Class name definition\n          9 SCE_P_DEFNAME [identifier] Function or method name definition\n         10 SCE_P_OPERATOR [operator] Operators\n         11 SCE_P_IDENTIFIER [identifier] Identifiers\n         12 SCE_P_COMMENTBLOCK [comment] Comment-blocks\n         13 SCE_P_STRINGEOL [error literal string] End of line where string is not closed\n         14 SCE_P_WORD2 [identifier] Highlighted identifiers\n         15 SCE_P_DECORATOR [preprocessor] Decorators\n         16 SCE_P_FSTRING [literal string interpolated] F-String\n         17 SCE_P_FCHARACTER [literal string interpolated] Single quoted f-string\n         18 SCE_P_FTRIPLE [literal string interpolated] Triple quoted f-string\n         19 SCE_P_FTRIPLEDOUBLE [literal string interpolated] Triple double quoted f-string\n         20 SCE_P_ATTRIBUTE [identifier] Attribute of identifier\n\nLexer r\n    Word Lists:\n        Language Keywords\n        Base / Default package function\n        Other Package Functions\n        Unused\n        Unused\n\nLexer raku\n    Properties:\n        bool   fold\n        bool   fold.comment\n        bool   fold.compact\n        bool   fold.raku.comment.multiline\n               Set this property to 0 to disable folding multi-line comments when fold.comment=1.\n        bool   fold.raku.comment.pod\n               Set this property to 0 to disable folding POD comments when fold.comment=1.\n    Word Lists:\n        Keywords and identifiers\n        Functions\n        Types basic\n        Types composite\n        Types domain-specific\n        Types exception\n        Adverbs\n\nLexer rebol\n    Word Lists:\n        Keywords\n\nLexer registry\n    Properties:\n        bool   fold.compact\n        bool   fold\n\nLexer ruby\n    Properties:\n        bool   fold.compact\n        bool   fold.comment\n    Word Lists:\n        Keywords\n    Sub-Style Bases:\n         11\n    Styles:\n          0 SCE_RB_DEFAULT [default] White space\n          1 SCE_RB_ERROR [error] Error\n          2 SCE_RB_COMMENTLINE [comment] Comment\n          3 SCE_RB_POD [data] POD\n          4 SCE_RB_NUMBER [literal numeric] Number\n          5 SCE_RB_WORD [keyword] Keyword\n          6 SCE_RB_STRING [literal string] Quoted string\n          7 SCE_RB_CHARACTER [literal string character] Quoted string\n          8 SCE_RB_CLASSNAME [identifier] Class name definition\n          9 SCE_RB_DEFNAME [identifier] Function or method name definition\n         10 SCE_RB_OPERATOR [operator] Operator\n         11 SCE_RB_IDENTIFIER [identifier] Identifiers\n         12 SCE_RB_REGEX [literal regex] RegEx\n         13 SCE_RB_GLOBAL [identifier] Global\n         14 SCE_RB_SYMBOL [identifier symbol] \n         15 SCE_RB_MODULE_NAME [identifier] Module name\n         16 SCE_RB_INSTANCE_VAR [identifier] Instance variable\n         17 SCE_RB_CLASS_VAR [identifier] Class variable\n         18 SCE_RB_BACKTICKS [literal string interpolated] Back ticks\n         19 SCE_RB_DATASECTION [data] Data section\n         20 SCE_RB_HERE_DELIM [here-doc literal string] Here-doc (delimiter)\n         21 SCE_RB_HERE_Q [here-doc literal string] Here-doc (single quoted, q)\n         22 SCE_RB_HERE_QQ [here-doc literal string] Here-doc (double quoted, qq)\n         23 SCE_RB_HERE_QX [here-doc literal string] Here-doc (back ticks, qx)\n         24 SCE_RB_STRING_Q [literal string] Single quoted string, generic\n         25 SCE_RB_STRING_QQ [literal string interpolated] qq = double quoted string\n         26 SCE_RB_STRING_QX [literal string interpolated] qx = back ticks\n         27 SCE_RB_STRING_QR [literal regex] qr = regex\n         28 SCE_RB_STRING_QW [literal string interpolated] qw = array\n         29 SCE_RB_WORD_DEMOTED [keyword] Keyword demoted\n         30 SCE_RB_STDIN [file] Standard input stream\n         31 SCE_RB_STDOUT [file] Standard output stream\n         32  [predefined] \n         33  [predefined] \n         34  [predefined] \n         35  [predefined] \n         36  [predefined] \n         37  [predefined] \n         38  [predefined] \n         39  [predefined] \n         40 SCE_RB_STDERR [file] Standard error stream\n         41 SCE_RB_STRING_W [literal string] String array\n         42 SCE_RB_STRING_I [literal string] Symbol array\n         43 SCE_RB_STRING_QI [literal string interpolated] Interpolable symbol array\n         44 SCE_RB_STRING_QS [identifier symbol] Symbol\n\nLexer rust\n    Properties:\n        bool   fold\n        bool   fold.comment\n        bool   fold.compact\n        bool   fold.at.else\n        bool   fold.rust.syntax.based\n               Set this property to 0 to disable syntax based folding.\n        bool   fold.rust.comment.multiline\n               Set this property to 0 to disable folding multi-line comments when fold.comment=1.\n        bool   fold.rust.comment.explicit\n               Set this property to 0 to disable folding explicit fold points when fold.comment=1.\n        string fold.rust.explicit.start\n               The string to use for explicit fold start points, replacing the standard //{.\n        string fold.rust.explicit.end\n               The string to use for explicit fold end points, replacing the standard //}.\n        bool   fold.rust.explicit.anywhere\n               Set this property to 1 to enable explicit fold points anywhere, not just in line comments.\n        int    lexer.rust.fold.at.else\n               This option enables Rust folding on a \"} else {\" line of an if statement.\n    Word Lists:\n        Primary keywords and identifiers\n        Built in types\n        Other keywords\n        Keywords 4\n        Keywords 5\n        Keywords 6\n        Keywords 7\n    Styles:\n          0 SCE_RUST_DEFAULT [default] White space\n          1 SCE_RUST_COMMENTBLOCK [comment] Comment\n          2 SCE_RUST_COMMENTLINE [comment line] Line comment\n          3 SCE_RUST_COMMENTBLOCKDOC [comment documentation] Doc comment\n          4 SCE_RUST_COMMENTLINEDOC [comment documentation line] Doc comment line\n          5 SCE_RUST_NUMBER [literal numeric] Number\n          6 SCE_RUST_WORD [keyword] Keywords\n          7 SCE_RUST_WORD2 [identifier] Keywords 2\n          8 SCE_RUST_WORD3 [identifier] Keywords 3\n          9 SCE_RUST_WORD4 [identifier] Keywords 4\n         10 SCE_RUST_WORD5 [identifier] Keywords 5\n         11 SCE_RUST_WORD6 [identifier] Keywords 6\n         12 SCE_RUST_WORD7 [identifier] Keywords 7\n         13 SCE_RUST_STRING [literal string] Regular string\n         14 SCE_RUST_STRINGR [literal string raw] Raw string\n         15 SCE_RUST_CHARACTER [literal string character] Character\n         16 SCE_RUST_OPERATOR [operator] Operator\n         17 SCE_RUST_IDENTIFIER [identifier] Identifier\n         18 SCE_RUST_LIFETIME [annotation] Lifetime\n         19 SCE_RUST_MACRO [macro preprocessor] Macro\n         20 SCE_RUST_LEXERROR [error] Lexical error\n         21 SCE_RUST_BYTESTRING [literal string] Byte string\n         22 SCE_RUST_BYTESTRINGR [literal string raw] Raw byte string\n         23 SCE_RUST_BYTECHARACTER [literal string character] Byte character\n         24 SCE_RUST_CSTRING [literal string] C string\n         25 SCE_RUST_CSTRINGR [literal string raw] Raw C string\n\nLexer sas\n    Word Lists:\n        Language Keywords\n        Macro Keywords\n        Types\n\nLexer scriptol\n\nLexer sinex\n    Word Lists:\n        SNX\n\nLexer smalltalk\n    Word Lists:\n        Special selectors\n\nLexer SML\n    Word Lists:\n        Keywords\n        Keywords2\n        Keywords3\n\nLexer sorcins\n    Word Lists:\n        Command\n        Parameter\n        Constant\n\nLexer specman\n    Word Lists:\n        Primary keywords and identifiers\n        Secondary keywords and identifiers\n        Sequence keywords and identifiers\n        User defined keywords and identifiers\n        Unused\n\nLexer spice\n    Word Lists:\n        Keywords\n        Keywords2\n        Keywords3\n\nLexer sql\n    Properties:\n        bool   fold\n        bool   fold.sql.at.else\n               This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement.\n        bool   fold.comment\n        bool   fold.compact\n        bool   fold.sql.only.begin\n               Set to 1 to only fold on 'begin' but not other keywords.\n        bool   lexer.sql.backticks.identifier\n               Recognise backtick quoting of identifiers.\n        bool   lexer.sql.numbersign.comment\n               If \"lexer.sql.numbersign.comment\" property is set to 0 a line beginning with '#' will not be a comment.\n        bool   sql.backslash.escapes\n               Enables backslash as an escape character in SQL.\n        bool   lexer.sql.allow.dotted.word\n               Set to 1 to colourise recognized words with dots (recommended for Oracle PL/SQL objects).\n    Word Lists:\n        Keywords\n        Database Objects\n        PLDoc\n        SQL*Plus\n        User Keywords 1\n        User Keywords 2\n        User Keywords 3\n        User Keywords 4\n\nLexer srec\n\nLexer stata\n    Word Lists:\n        Language Keywords\n        Types\n\nLexer fcST\n    Word Lists:\n        Keywords\n        Types\n        Functions\n        FB\n        Local_Var\n        Local_Pragma\n\nLexer TACL\n    Word Lists:\n        Builtins\n        Labels\n        Commands\n\nLexer tads3\n    Word Lists:\n        TADS3 Keywords\n        User defined 1\n        User defined 2\n        User defined 3\n\nLexer TAL\n    Word Lists:\n        Keywords\n        Builtins\n\nLexer tcl\n    Word Lists:\n        TCL Keywords\n        TK Keywords\n        iTCL Keywords\n        tkCommands\n        expand\n        user1\n        user2\n        user3\n        user4\n\nLexer tcmd\n    Word Lists:\n        Internal Commands\n        Aliases\n\nLexer tehex\n\nLexer tex\n    Word Lists:\n        TeX, eTeX, pdfTeX, Omega\n        ConTeXt Dutch\n        ConTeXt English\n        ConTeXt German\n        ConTeXt Czech\n        ConTeXt Italian\n        ConTeXt Romanian\n\nLexer toml\n    Word Lists:\n        Keywords\n\nLexer troff\n    Word Lists:\n        Predefined requests\n        Flow control requests/commands with conditionals\n        Flow control requests/commands without conditionals\n        Requests and commands, initiating ignore blocks\n        Requests and commands with end-macros\n\nLexer txt2tags\n\nLexer vb\n    Properties:\n        bool   fold\n        bool   lexer.vb.strings.multiline\n               Set to 1 to allow strings to continue over line ends.\n    Word Lists:\n        Keywords\n        user1\n        user2\n        user3\n    Styles:\n          0 SCE_B_DEFAULT [default] White space\n          1 SCE_B_COMMENT [comment] Comment: '\n          2 SCE_B_NUMBER [literal numeric] Number\n          3 SCE_B_KEYWORD [keyword] Keyword\n          4 SCE_B_STRING [literal string] Double quoted string\n          5 SCE_B_PREPROCESSOR [preprocessor] Preprocessor\n          6 SCE_B_OPERATOR [operator] Operators\n          7 SCE_B_IDENTIFIER [identifier] Identifiers\n          8 SCE_B_DATE [literal date] Date\n          9 SCE_B_STRINGEOL [error literal string] End of line where string is not closed\n         10 SCE_B_KEYWORD2 [identifier] Keywords2\n         11 SCE_B_KEYWORD3 [identifier] Keywords3\n         12 SCE_B_KEYWORD4 [identifier] Keywords4\n\nLexer vbscript\n    Properties:\n        bool   fold\n        bool   lexer.vb.strings.multiline\n               Set to 1 to allow strings to continue over line ends.\n    Word Lists:\n        Keywords\n        user1\n        user2\n        user3\n    Styles:\n          0 SCE_B_DEFAULT [default] White space\n          1 SCE_B_COMMENT [comment] Comment: '\n          2 SCE_B_NUMBER [literal numeric] Number\n          3 SCE_B_KEYWORD [keyword] Keyword\n          4 SCE_B_STRING [literal string] Double quoted string\n          5 SCE_B_PREPROCESSOR [preprocessor] Preprocessor\n          6 SCE_B_OPERATOR [operator] Operators\n          7 SCE_B_IDENTIFIER [identifier] Identifiers\n          8 SCE_B_DATE [literal date] Date\n          9 SCE_B_STRINGEOL [error literal string] End of line where string is not closed\n         10 SCE_B_KEYWORD2 [identifier] Keywords2\n         11 SCE_B_KEYWORD3 [identifier] Keywords3\n         12 SCE_B_KEYWORD4 [identifier] Keywords4\n\nLexer verilog\n    UnicodeLineEnds\n    Properties:\n        bool   fold.comment\n               This option enables folding multi-line comments when using the Verilog lexer.\n        bool   fold.preprocessor\n               This option enables folding preprocessor directives when using the Verilog lexer.\n        bool   fold.compact\n        bool   fold.at.else\n               This option enables folding on the else line of an if statement.\n        bool   fold.verilog.flags\n               This option enables folding module definitions. Typically source files contain only one module definition so this option is somewhat useless.\n        bool   lexer.verilog.track.preprocessor\n               Set to 1 to interpret `if/`else/`endif to grey out code that is not active.\n        bool   lexer.verilog.update.preprocessor\n               Set to 1 to update preprocessor definitions when `define, `undef, or `undefineall found.\n        bool   lexer.verilog.portstyling\n               Set to 1 to style input, output, and inout ports differently from regular keywords.\n        bool   lexer.verilog.allupperkeywords\n               Set to 1 to style identifiers that are all uppercase as documentation keyword.\n        bool   lexer.verilog.fold.preprocessor.else\n               This option enables folding on `else and `elsif preprocessor directives.\n\nLexer vhdl\n    Word Lists:\n        Keywords\n        Operators\n        Attributes\n        Standard Functions\n        Standard Packages\n        Standard Types\n        User Words\n\nLexer visualprolog\n    Properties:\n        bool   lexer.visualprolog.verbatim.strings\n               Set to 0 to disable highlighting verbatim strings using '@'.\n        bool   lexer.visualprolog.backquoted.strings\n               Set to 1 to enable using back quotes (``) to delimit strings.\n    Word Lists:\n        Major keywords (class, predicates, ...)\n        Minor keywords (if, then, try, ...)\n        Directive keywords without the '#' (include, requires, ...)\n        Documentation keywords without the '@' (short, detail, ...)\n    Styles:\n          0 SCE_VISUALPROLOG_DEFAULT [default] Default style\n          1 SCE_VISUALPROLOG_KEY_MAJOR [keyword major] Major keyword\n          2 SCE_VISUALPROLOG_KEY_MINOR [keyword minor] Minor keyword\n          3 SCE_VISUALPROLOG_KEY_DIRECTIVE [keyword preprocessor] Directove keyword\n          4 SCE_VISUALPROLOG_COMMENT_BLOCK [comment] Multiline comment /* */\n          5 SCE_VISUALPROLOG_COMMENT_LINE [comment line] Line comment % ...\n          6 SCE_VISUALPROLOG_COMMENT_KEY [comment documentation keyword] Doc keyword in comment % @short ...\n          7 SCE_VISUALPROLOG_COMMENT_KEY_ERROR [comment] A non recognized doc keyword % @qqq ...\n          8 SCE_VISUALPROLOG_IDENTIFIER [identifier] Identifier (black)\n          9 SCE_VISUALPROLOG_VARIABLE [variable identifier] Variable (green)\n         10 SCE_VISUALPROLOG_ANONYMOUS [variable anonymous identifier] Anonymous Variable _XXX (dimmed green)\n         11 SCE_VISUALPROLOG_NUMBER [numeric] Number\n         12 SCE_VISUALPROLOG_OPERATOR [operator] Operator\n         13 SCE_VISUALPROLOG_UNUSED1 [unused] \n         14 SCE_VISUALPROLOG_UNUSED2 [unused] \n         15 SCE_VISUALPROLOG_UNUSED3 [unused] \n         16 SCE_VISUALPROLOG_STRING_QUOTE [literal string quote] Quotes surrounding string literals\n         17 SCE_VISUALPROLOG_STRING_ESCAPE [literal string escapesequence] Escape sequence in string literal\n         18 SCE_VISUALPROLOG_STRING_ESCAPE_ERROR [error literal string escapesequence] Error in escape sequence in string literal\n         19 SCE_VISUALPROLOG_UNUSED4 [unused] \n         20 SCE_VISUALPROLOG_STRING [literal string] String literal\n         21 SCE_VISUALPROLOG_UNUSED5 [unused] \n         22 SCE_VISUALPROLOG_STRING_EOL [literal string multiline raw escapesequence] Verbatim/multiline string literal EOL\n         23 SCE_VISUALPROLOG_EMBEDDED [literal string embedded] Embedded syntax [| ... |]\n\nLexer x12\n    Properties:\n        bool   fold\n               Whether to apply folding to document or not\n\nLexer xml\n    Properties:\n        int    asp.default.language\n               Script in ASP code is initially assumed to be in JavaScript. To change this to VBScript set asp.default.language to 2. Python is 3.\n        bool   html.tags.case.sensitive\n               For XML and HTML, setting this property to 1 will make tags match in a case sensitive way which is the expected behaviour for XML and XHTML.\n        bool   lexer.xml.allow.scripts\n               Set to 0 to disable scripts in XML.\n        int    lexer.xml.allow.php\n               Set to 0 to disable PHP in XML, 1 to accept <?php and <?=, 2 to also accept <?.The default is 2.\n        int    lexer.html.allow.php\n               Set to 0 to disable PHP in HTML, 1 to accept <?php and <?=, 2 to also accept <?.The default is 2.\n        bool   lexer.html.mako\n               Set to 1 to enable the mako template language.\n        bool   lexer.html.django\n               Set to 1 to enable the django template language.\n        bool   lexer.xml.allow.asp\n               Set to 0 to disable ASP in XML.\n        bool   lexer.html.allow.asp\n               Set to 0 to disable ASP in HTML.\n        bool   fold\n        bool   fold.html\n               Folding is turned on or off for HTML and XML files with this option. The fold option must also be on for folding to occur.\n        bool   fold.html.preprocessor\n               Folding is turned on or off for scripts embedded in HTML files with this option. The default is on.\n        bool   fold.compact\n        bool   fold.hypertext.comment\n               Allow folding for comments in scripts embedded in HTML. The default is off.\n        bool   fold.hypertext.heredoc\n               Allow folding for heredocs in scripts embedded in HTML. The default is off.\n        bool   fold.xml.at.tag.open\n               Enable folding for XML at the start of open tag. The default is off.\n    Word Lists:\n        HTML elements and attributes\n        JavaScript keywords\n        VBScript keywords\n        Python keywords\n        PHP keywords\n        SGML and DTD keywords\n    Sub-Style Bases:\n          1\n          3\n         46\n         61\n         74\n         96\n        121\n    Styles:\n          0 SCE_H_DEFAULT [default] Default\n          1 SCE_H_TAG [tag] Tags\n          2 SCE_H_TAGUNKNOWN [error tag] Unknown Tags\n          3 SCE_H_ATTRIBUTE [attribute] Attributes\n          4 SCE_H_ATTRIBUTEUNKNOWN [error attribute] Unknown Attributes\n          5 SCE_H_NUMBER [literal numeric] Numbers\n          6 SCE_H_DOUBLESTRING [literal string] Double quoted strings\n          7 SCE_H_SINGLESTRING [literal string] Single quoted strings\n          8 SCE_H_OTHER [tag operator] Other inside tag, including space and '='\n          9 SCE_H_COMMENT [comment] Comment\n         10 SCE_H_ENTITY [literal] Entities\n         11 SCE_H_TAGEND [tag] XML style tag ends '/>'\n         12 SCE_H_XMLSTART [identifier] XML identifier start '<?'\n         13 SCE_H_XMLEND [identifier] XML identifier end '?>'\n         14  [unused] \n         15  [unused] \n         16  [unused] \n         17 SCE_H_CDATA [literal] CDATA\n         18 SCE_H_QUESTION [preprocessor] Question\n         19 SCE_H_VALUE [literal string] Unquoted Value\n         20  [unused] \n         21 SCE_H_SGML_DEFAULT [default] SGML tags <! ... >\n         22 SCE_H_SGML_COMMAND [preprocessor] SGML command\n         23 SCE_H_SGML_1ST_PARAM [preprocessor] SGML 1st param\n         24 SCE_H_SGML_DOUBLESTRING [literal string] SGML double string\n         25 SCE_H_SGML_SIMPLESTRING [literal string] SGML single string\n         26 SCE_H_SGML_ERROR [error] SGML error\n         27 SCE_H_SGML_SPECIAL [literal] SGML special (#XXXX type)\n         28 SCE_H_SGML_ENTITY [literal] SGML entity\n         29 SCE_H_SGML_COMMENT [comment] SGML comment\n         30  [unused] \n         31 SCE_H_SGML_BLOCK_DEFAULT [default] SGML block\n\nLexer yaml\n    Word Lists:\n        Keywords\n\nLexer zig\n    Properties:\n        bool   fold\n    Word Lists:\n        Primary keywords\n        Secondary keywords\n        Tertiary keywords\n        Global type definitions\n    Styles:\n          0 SCE_ZIG_DEFAULT [default] White space\n          1 SCE_ZIG_COMMENTLINE [comment line] Comment: //\n          2 SCE_ZIG_COMMENTLINEDOC [comment line documentation] Comment: ///\n          3 SCE_ZIG_COMMENTLINETOP [comment line documentation] Comment: //!\n          4 SCE_ZIG_NUMBER [literal numeric] Number\n          5 SCE_ZIG_OPERATOR [operator] Operator\n          6 SCE_ZIG_CHARACTER [literal string character] Single quoted string\n          7 SCE_ZIG_STRING [literal string] Double quoted string\n          8 SCE_ZIG_MULTISTRING [literal string multiline] Multiline string introduced by two backslashes\n          9 SCE_ZIG_ESCAPECHAR [literal string escapesequence] Escape sequence\n         10 SCE_ZIG_IDENTIFIER [identifier] Identifier\n         11 SCE_ZIG_FUNCTION [identifier] Function definition\n         12 SCE_ZIG_BUILTIN_FUNCTION [identifier] Builtin function\n         13 SCE_ZIG_KW_PRIMARY [keyword] Primary keywords\n         14 SCE_ZIG_KW_SECONDARY [identifier] Secondary keywords\n         15 SCE_ZIG_KW_TERTIARY [identifier] Tertiary keywords\n         16 SCE_ZIG_KW_TYPE [identifier] Global types\n         17 SCE_ZIG_IDENTIFIER_STRING [identifier] Identifier using @\"\" syntax\n         18 SCE_ZIG_STRINGEOL [error literal string] End of line where string is not closed\n\n"
  },
  {
    "path": "test/Metadata/makefile",
    "content": ".PHONY: all check clean\n\nINCLUDES = -I ../../include -I ../../access -I ../../../scintilla/include\nEXE = $(if $(windir),Metadata.exe,Metadata)\n\nifdef windir\n\tRM = $(if $(wildcard $(dir $(SHELL))rm.exe), $(dir $(SHELL))rm.exe -f, del /q)\n\tCXX = g++\nelse\n\tLIBS += -ldl\nendif\n\nall: $(EXE)\n\ncheck: $(EXE)\n\t./$(EXE)\n\nclean:\n\t$(RM) $(EXE) *.o\n\nvpath %.cxx ../../access\n\n%.o: %.cxx\n\t$(CXX) --std=c++20 $(INCLUDES) -c $< -o $@\n\n$(EXE): Metadata.o LexillaAccess.o\n\t$(CXX) $^ $(LIBS) -o $@\n"
  },
  {
    "path": "test/README",
    "content": "README for testing lexers with lexilla/test.\r\n\r\nThe TestLexers application is run to test the lexing and folding of a set of example\r\nfiles and thus ensure that the lexers are working correctly.\r\n\r\nLexers are accessed through the Lexilla shared library which must be built first\r\nin the lexilla/src directory.\r\n\r\nTestLexers works on Windows, Linux, or macOS and requires a C++20 compiler.\r\nMSVC 2019.4, GCC 9.0, Clang 9.0, and Apple Clang 11.0 are known to work.\r\n\r\nMSVC is only available on Windows.\r\n\r\nGCC and Clang work on Windows and Linux.\r\n\r\nOn macOS, only Apple Clang is available.\r\n\r\nLexilla requires some headers from Scintilla to build and expects a directory named\r\n\"scintilla\" containing a copy of Scintilla 5+ to be a peer of the Lexilla top level\r\ndirectory conventionally called \"lexilla\".\r\n\r\nTo use GCC run lexilla/test/makefile:\r\n\tmake test\r\n\r\nTo use Clang run lexilla/test/makefile:\r\n\tmake CLANG=1 test\r\nOn macOS, CLANG is set automatically so this can just be\r\n\tmake test\r\n\r\nTo use MSVC:\r\n\tnmake -f testlexers.mak test\r\nThere is also a project file TestLexers.vcxproj that can be loaded into the Visual\r\nC++ IDE.\r\n\r\n\r\n\r\nAdding or Changing Tests\r\n\r\nThe lexilla/test/examples directory contains a set of tests located in a tree of\r\nsubdirectories.\r\n\r\nEach directory contains example files along with control files called\r\nSciTE.properties and expected result files with .styled and .folded suffixes.\r\nIf an unexpected result occurs then files with the additional suffix .new \r\n(that is .styled.new or .folded.new) may be created.\r\n\r\nEach file in the examples tree that does not have an extension of .properties, .styled,\r\n.folded or .new is an example file that will be lexed and folded according to settings\r\nfound in SciTE.properties.\r\n\r\nThe results of the lex will be compared to the corresponding .styled file and if different\r\nthe result will be saved to a .styled.new file for checking.\r\nSo, if x.cxx is the example, its lexed form will be checked against x.cxx.styled and a\r\nx.cxx.styled.new file may be created. The .styled.new and .styled files contain the text\r\nof the original file along with style number changes in {} like:\r\n\t{5}function{0} {11}first{10}(){0}\r\nAfter checking that the .styled.new file is correct, it can be promoted to .styled and\r\ncommitted to the repository.\r\n\r\nThe results of the fold will be compared to the corresponding .folded file and if different\r\nthe result will be saved to a .folded.new file for checking.\r\nSo, if x.cxx is the example, its folded form will be checked against x.cxx.folded and a\r\nx.cxx.folded.new file may be created. The folded.new and .folded files contain the text\r\nof the original file along with fold information to the left like:\r\n\r\n 2 400   0 + --[[ coding:UTF-8\r\n 0 402   0 | comment ]]\r\n\r\nThere are 4 columns before the file text representing the bits of the fold level:\r\n[flags (0xF000), level (0x0FFF), other (0xFFFF0000), picture].\r\nflags: may be 2 for header or 1 for whitespace.\r\nlevel: hexadecimal level number starting at 0x400. 'negative' level numbers like 0x3FF\r\nindicate errors in either the folder or in the input file, such as a C file that starts with #endif.\r\nother: can be used as the folder wants. Often used to hold the level of the next line.\r\npicture: gives a rough idea of the fold structure: '|' for level greater than 0x400,\r\n'+' for header, ' ' otherwise.\r\nAfter checking that the .folded.new file is correct, it can be promoted to .folded and\r\ncommitted to the repository.\r\n\r\nAn interactive file comparison program like WinMerge (https://winmerge.org/) on\r\nWindows or meld (https://meldmerge.org/) on Linux can help examine differences\r\nbetween the .styled and .styled.new files or .folded and .folded.new files.\r\n\r\nOn Windows, the scripts/PromoteNew.bat script can be run to promote all .new result\r\nfiles to their base names without .new.\r\n\r\nStyling and folding tests are first performed on the file as a whole, then the file is lexed\r\nand folded line-by-line. If there are differences between the whole file and line-by-line\r\nthen a message with 'per-line is different' for styling or 'per-line has different folds' will be\r\nprinted. Problems with line-by-line processing are often caused by local variables in the\r\nlexer or folder that are incorrectly initialised. Sometimes extra state can be inferred, but it\r\nmay have to be stored between runs (possibly with SetLineState) or the code may have to\r\nbacktrack to a previous safe line - often something like a line that starts with a character\r\nin the default style.\r\n\r\nThe SciTE.properties file is similar to properties files used for SciTE but are simpler.\r\nThe lexer to be run is defined with a lexer.{filepatterns} statement like:\r\n\tlexer.*.d=d\r\n\r\nKeywords may be defined with keywords settings like:\r\n\tkeywords.*.cxx;*.c=int char\r\n\tkeywords2.*.cxx=open\r\n\r\nSubstyles and substyle identifiers may be defined with settings like:\r\n\tsubstyles.cpp.11=1\r\n\tsubstylewords.11.1.*.cxx=map string vector\r\n\r\nOther settings are treated as lexer or folder properties and forwarded to the lexer/folder:\r\n\tlexer.cpp.track.preprocessor=1\r\n\tfold=1\r\n\r\nIt is often necessary to set 'fold' in SciTE.properties to cause folding.\r\n\r\nProperties can be set for a particular file with an \"if $(=\" or \"match\" expression like so:\r\nif $(= $(FileNameExt);HeaderEOLFill_1.md)\r\n    lexer.markdown.header.eolfill=1\r\nmatch Header*1.md\r\n    lexer.markdown.header.eolfill=1\r\n\r\nMore complex tests with additional configurations of keywords or properties can be performed\r\nby creating another subdirectory with the different settings in a new SciTE.properties.\r\n\r\nThere is some support for running benchmarks on lexers and folders. The properties\r\ntestlexers.repeat.lex and testlexers.repeat.fold specify the number of times example\r\ndocuments are lexed or folded. Set to a large number like testlexers.repeat.lex=10000\r\nthen run with a profiler.\r\n\r\nA list of styles used in a lex can be displayed with testlexers.list.styles=1.\r\n"
  },
  {
    "path": "test/TestDocument.cxx",
    "content": "// Lexilla lexer library\n/** @file TestDocument.cxx\n ** Lexer testing.\n **/\n // Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n // The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cassert>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <algorithm>\n\n#include <iostream>\n\n#include \"ILexer.h\"\n\n#include \"TestDocument.h\"\n\nnamespace {\n\n\tconst unsigned char UTF8BytesOfLead[256] = {\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 00 - 0F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10 - 1F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 20 - 2F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 30 - 3F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40 - 4F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 50 - 5F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60 - 6F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 70 - 7F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 80 - 8F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 90 - 9F\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A0 - AF\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B0 - BF\n\t1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0 - CF\n\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // D0 - DF\n\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // E0 - EF\n\t4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // F0 - FF\n\t};\n\n\tint UnicodeFromUTF8(const unsigned char *us) noexcept {\n\t\tassert(us);\n\t\tswitch (UTF8BytesOfLead[us[0]]) {\n\t\tcase 1:\n\t\t\treturn us[0];\n\t\tcase 2:\n\t\t\treturn ((us[0] & 0x1F) << 6) + (us[1] & 0x3F);\n\t\tcase 3:\n\t\t\treturn ((us[0] & 0xF) << 12) + ((us[1] & 0x3F) << 6) + (us[2] & 0x3F);\n\t\tdefault:\n\t\t\treturn ((us[0] & 0x7) << 18) + ((us[1] & 0x3F) << 12) + ((us[2] & 0x3F) << 6) + (us[3] & 0x3F);\n\t\t}\n\t}\n\n\tinline constexpr bool UTF8IsTrailByte(unsigned char ch) noexcept {\n\t\treturn (ch >= 0x80) && (ch < 0xc0);\n\t}\n\n\tconstexpr unsigned char TrailByteValue(unsigned char c) {\n\t\t// The top 2 bits are 0b10 to indicate a trail byte.\n\t\t// The lower 6 bits contain the value.\n\t\treturn c & 0b0011'1111;\n\t}\n}\n\nstd::u32string UTF32FromUTF8(std::string_view svu8) {\n\tstd::u32string ret;\n\tfor (size_t i = 0; i < svu8.length();) {\n\t\tunsigned char ch = svu8.at(i);\n\t\tconst unsigned int byteCount = UTF8BytesOfLead[ch];\n\t\tunsigned int value = 0;\n\n\t\tif (i + byteCount > svu8.length()) {\n\t\t\t// Trying to read past end\n\t\t\tret.push_back(ch);\n\t\t\tbreak;\n\t\t}\n\n\t\ti++;\n\t\tswitch (byteCount) {\n\t\tcase 1:\n\t\t\tvalue = ch;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tvalue = (ch & 0x1F) << 6;\n\t\t\tch = svu8.at(i++);\n\t\t\tvalue += TrailByteValue(ch);\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tvalue = (ch & 0xF) << 12;\n\t\t\tch = svu8.at(i++);\n\t\t\tvalue += TrailByteValue(ch) << 6;\n\t\t\tch = svu8.at(i++);\n\t\t\tvalue += TrailByteValue(ch);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tvalue = (ch & 0x7) << 18;\n\t\t\tch = svu8.at(i++);\n\t\t\tvalue += TrailByteValue(ch) << 12;\n\t\t\tch = svu8.at(i++);\n\t\t\tvalue += TrailByteValue(ch) << 6;\n\t\t\tch = svu8.at(i++);\n\t\t\tvalue += TrailByteValue(ch);\n\t\t\tbreak;\n\t\t}\n\t\tret.push_back(value);\n\t}\n\treturn ret;\n}\n\nvoid TestDocument::Set(std::string_view sv) {\n\ttext = sv;\n\ttextStyles.resize(text.size() + 1);\n\tlineStarts.clear();\n\tendStyled = 0;\n\tlineStarts.push_back(0);\n\tfor (size_t pos = 0; pos < text.length(); pos++) {\n\t\tif (text.at(pos) == '\\n') {\n\t\t\tlineStarts.push_back(pos + 1);\n\t\t}\n\t}\n\tif (lineStarts.back() != Length()) {\n\t\tlineStarts.push_back(Length());\n\t}\n\tlineStates.resize(lineStarts.size() + 1);\n\tlineLevels.resize(lineStarts.size(), 0x400);\n}\n\n#if defined(_MSC_VER)\n// IDocument interface does not specify noexcept so best to not add it to implementation\n#pragma warning(disable: 26440)\n#endif\n\nSci_Position TestDocument::MaxLine() const noexcept {\n\treturn lineStarts.size() - 1;\n}\n\nint SCI_METHOD TestDocument::Version() const {\n\treturn Scintilla::dvRelease4;\n}\n\nvoid SCI_METHOD TestDocument::SetErrorStatus(int) {\n}\n\nSci_Position SCI_METHOD TestDocument::Length() const {\n\treturn text.length();\n}\n\nvoid SCI_METHOD TestDocument::GetCharRange(char *buffer, Sci_Position position, Sci_Position lengthRetrieve) const {\n\ttext.copy(buffer, lengthRetrieve, position);\n}\n\nchar SCI_METHOD TestDocument::StyleAt(Sci_Position position) const {\n\tif (position < 0) {\n\t\treturn 0;\n\t}\n\treturn textStyles.at(position);\n}\n\nSci_Position SCI_METHOD TestDocument::LineFromPosition(Sci_Position position) const {\n\tif (position >= Length()) {\n\t\treturn MaxLine();\n\t}\n\n\tconst std::vector<Sci_Position>::const_iterator it = std::lower_bound(lineStarts.begin(), lineStarts.end(), position);\n\tSci_Position line = it - lineStarts.begin();\n\tif (*it > position)\n\t\tline--;\n\treturn line;\n}\n\nSci_Position SCI_METHOD TestDocument::LineStart(Sci_Position line) const {\n\tif (line < 0) {\n\t\treturn 0;\n\t}\n\tif (line >= static_cast<Sci_Position>(lineStarts.size())) {\n\t\treturn Length();\n\t}\n\treturn lineStarts.at(line);\n}\n\nint SCI_METHOD TestDocument::GetLevel(Sci_Position line) const {\n\treturn lineLevels.at(line);\n}\n\nint SCI_METHOD TestDocument::SetLevel(Sci_Position line, int level) {\n\tif (line == static_cast<Sci_Position>(lineLevels.size())) {\n\t\treturn 0x400;\n\t}\n\treturn lineLevels.at(line) = level;\n}\n\nint SCI_METHOD TestDocument::GetLineState(Sci_Position line) const {\n\treturn lineStates.at(line);\n}\n\nint SCI_METHOD TestDocument::SetLineState(Sci_Position line, int state) {\n\treturn lineStates.at(line) = state;\n}\n\nvoid SCI_METHOD TestDocument::StartStyling(Sci_Position position) {\n\tendStyled = position;\n}\n\nbool SCI_METHOD TestDocument::SetStyleFor(Sci_Position length, char style) {\n\ttextStyles.replace(endStyled, length, length, style);\n\tendStyled += length;\n\treturn true;\n}\n\nbool SCI_METHOD TestDocument::SetStyles(Sci_Position length, const char *styles) {\n\tassert(styles);\n\ttextStyles.replace(endStyled, length, styles, length);\n\tendStyled += length;\n\treturn true;\n}\n\nvoid SCI_METHOD TestDocument::DecorationSetCurrentIndicator(int) {\n\t// Not implemented as no way to read decorations\n}\n\nvoid SCI_METHOD TestDocument::DecorationFillRange(Sci_Position, int, Sci_Position) {\n\t// Not implemented as no way to read decorations\n}\n\nvoid SCI_METHOD TestDocument::ChangeLexerState(Sci_Position, Sci_Position) {\n\t// Not implemented as no watcher to trigger\n}\n\nint SCI_METHOD TestDocument::CodePage() const {\n\t// Always UTF-8 for now\n\treturn 65001;\n}\n\nbool SCI_METHOD TestDocument::IsDBCSLeadByte(char) const {\n\t// Always UTF-8 for now\n\treturn false;\n}\n\nconst char *SCI_METHOD TestDocument::BufferPointer() {\n\treturn text.c_str();\n}\n\nint SCI_METHOD TestDocument::GetLineIndentation(Sci_Position) {\n\t// Never actually called - lexers use Accessor::IndentAmount\n\treturn 0;\n}\n\nSci_Position SCI_METHOD TestDocument::LineEnd(Sci_Position line) const {\n\tconst Sci_Position maxLine = MaxLine();\n\tif (line == maxLine || line == maxLine+1) {\n\t\treturn text.length();\n\t}\n\tassert(line < maxLine);\n\tSci_Position position = LineStart(line + 1);\n\tposition--; // Back over CR or LF\n\t// When line terminator is CR+LF, may need to go back one more\n\tif ((position > LineStart(line)) && (text.at(position - 1) == '\\r')) {\n\t\tposition--;\n\t}\n\treturn position;\n}\n\nSci_Position SCI_METHOD TestDocument::GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const {\n\tSci_Position pos = positionStart;\n\tif (characterOffset < 0) {\n\t\twhile (characterOffset < 0) {\n\t\t\tif (pos <= 0) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tunsigned char previousByte = text.at(pos - 1);\n\t\t\tif (previousByte < 0x80) {\n\t\t\t\tpos--;\n\t\t\t\tcharacterOffset++;\n\t\t\t} else {\n\t\t\t\twhile ((pos > 1) && UTF8IsTrailByte(previousByte)) {\n\t\t\t\t\tpos--;\n\t\t\t\t\tpreviousByte = text.at(pos - 1);\n\t\t\t\t}\n\t\t\t\tpos--;\n\t\t\t\t// text[pos] is now a character start\n\t\t\t\tcharacterOffset++;\n\t\t\t}\n\t\t}\n\t\treturn pos;\n\t}\n\tassert(characterOffset >= 0);\n\t// TODO: invalid UTF-8\n\twhile (characterOffset > 0) {\n\t\tSci_Position width = 0;\n\t\tGetCharacterAndWidth(pos, &width);\n\t\tpos += width;\n\t\tcharacterOffset--;\n\t}\n\treturn pos;\n}\n\nint SCI_METHOD TestDocument::GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const {\n\t// TODO: invalid UTF-8\n\tif ((position < 0) || (position >= Length())) {\n\t\t// Return NULs before document start and after document end\n\t\tif (pWidth) {\n\t\t\t*pWidth = 1;\n\t\t}\n\t\treturn '\\0';\n\t}\n\tconst unsigned char leadByte = text.at(position);\n\tif (leadByte < 0x80) {\n\t\tif (pWidth) {\n\t\t\t*pWidth = 1;\n\t\t}\n\t\treturn leadByte;\n\t}\n\tconst int widthCharBytes = UTF8BytesOfLead[leadByte];\n\tunsigned char charBytes[] = { leadByte,0,0,0 };\n\tfor (int b = 1; b < widthCharBytes; b++) {\n\t\tcharBytes[b] = text.at(position + b);\n\t}\n\n\tif (pWidth) {\n\t\t*pWidth = widthCharBytes;\n\t}\n\treturn UnicodeFromUTF8(charBytes);\n}\n"
  },
  {
    "path": "test/TestDocument.h",
    "content": "// Lexilla lexer library\n/** @file TestDocument.h\n ** Lexer testing.\n **/\n// Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n// The License.txt file describes the conditions under which this software may be distributed.\n\n#ifndef TESTDOCUMENT_H\n#define TESTDOCUMENT_H\n\nstd::u32string UTF32FromUTF8(std::string_view svu8);\n\nclass TestDocument : public Scintilla::IDocument {\n\tstd::string text;\n\tstd::string textStyles;\n\tstd::vector<Sci_Position> lineStarts;\n\tstd::vector<int> lineStates;\n\tstd::vector<int> lineLevels;\n\tSci_Position endStyled=0;\npublic:\n\tvoid Set(std::string_view sv);\n\tTestDocument() = default;\n\t// Deleted so TestDocument objects can not be copied.\n\tTestDocument(const TestDocument&) = delete;\n\tTestDocument(TestDocument&&) = delete;\n\tTestDocument &operator=(const TestDocument&) = delete;\n\tTestDocument &operator=(TestDocument&&) = delete;\n\tvirtual ~TestDocument() = default;\n\n\tSci_Position MaxLine() const noexcept;\n\n\tint SCI_METHOD Version() const override;\n\tvoid SCI_METHOD SetErrorStatus(int status) override;\n\tSci_Position SCI_METHOD Length() const override;\n\tvoid SCI_METHOD GetCharRange(char *buffer, Sci_Position position, Sci_Position lengthRetrieve) const override;\n\tchar SCI_METHOD StyleAt(Sci_Position position) const override;\n\tSci_Position SCI_METHOD LineFromPosition(Sci_Position position) const override;\n\tSci_Position SCI_METHOD LineStart(Sci_Position line) const override;\n\tint SCI_METHOD GetLevel(Sci_Position line) const override;\n\tint SCI_METHOD SetLevel(Sci_Position line, int level) override;\n\tint SCI_METHOD GetLineState(Sci_Position line) const override;\n\tint SCI_METHOD SetLineState(Sci_Position line, int state) override;\n\tvoid SCI_METHOD StartStyling(Sci_Position position) override;\n\tbool SCI_METHOD SetStyleFor(Sci_Position length, char style) override;\n\tbool SCI_METHOD SetStyles(Sci_Position length, const char *styles) override;\n\tvoid SCI_METHOD DecorationSetCurrentIndicator(int indicator) override;\n\tvoid SCI_METHOD DecorationFillRange(Sci_Position position, int value, Sci_Position fillLength) override;\n\tvoid SCI_METHOD ChangeLexerState(Sci_Position start, Sci_Position end) override;\n\tint SCI_METHOD CodePage() const override;\n\tbool SCI_METHOD IsDBCSLeadByte(char ch) const override;\n\tconst char *SCI_METHOD BufferPointer() override;\n\tint SCI_METHOD GetLineIndentation(Sci_Position line) override;\n\tSci_Position SCI_METHOD LineEnd(Sci_Position line) const override;\n\tSci_Position SCI_METHOD GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const override;\n\tint SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const override;\n};\n\n#endif\n"
  },
  {
    "path": "test/TestLexers.cxx",
    "content": "// Lexilla lexer library\n/** @file TestLexers.cxx\n ** Test lexers through Lexilla.\n **/\n // Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n // The License.txt file describes the conditions under which this software may be distributed.\n\n#include <cassert>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n#include <optional>\n#include <algorithm>\n\n#include <iostream>\n#include <sstream>\n#include <fstream>\n#include <iomanip>\n#include <filesystem>\n\n#include \"ILexer.h\"\n\n#include \"Lexilla.h\"\n#include \"LexillaAccess.h\"\n\n#include \"TestDocument.h\"\n\nnamespace {\n\nconstexpr char MakeLowerCase(char c) noexcept {\n\tif (c >= 'A' && c <= 'Z') {\n\t\treturn c - 'A' + 'a';\n\t} else {\n\t\treturn c;\n\t}\n}\n\n[[maybe_unused]] void LowerCaseAZ(std::string &s) {\n\tstd::transform(s.begin(), s.end(), s.begin(), MakeLowerCase);\n}\n\nint IntFromString(std::u32string_view s) noexcept {\n\tif (s.empty()) {\n\t\treturn 0;\n\t}\n\tconst bool negate = s.front() == '-';\n\tif (negate) {\n\t\ts.remove_prefix(1);\n\t}\n\tint value = 0;\n\twhile (!s.empty()) {\n\t\tvalue = value * 10 + s.front() - '0';\n\t\ts.remove_prefix(1);\n\t}\n\treturn negate ? -value : value;\n}\n\nbool PatternMatch(std::u32string_view pattern, std::u32string_view text) noexcept {\n\tif (pattern == text) {\n\t\treturn true;\n\t} else if (pattern.empty()) {\n\t\treturn false;\n\t} else if (pattern.front() == '\\\\') {\n\t\tpattern.remove_prefix(1);\n\t\tif (pattern.empty()) {\n\t\t\t// Escape with nothing being escaped\n\t\t\treturn false;\n\t\t}\n\t\tif (text.empty()) {\n\t\t\treturn false;\n\t\t}\n\t\tif (pattern.front() == text.front()) {\n\t\t\tpattern.remove_prefix(1);\n\t\t\ttext.remove_prefix(1);\n\t\t\treturn PatternMatch(pattern, text);\n\t\t}\n\t\treturn false;\n\t} else if (pattern.front() == '*') {\n\t\tpattern.remove_prefix(1);\n\t\tif (!pattern.empty() && pattern.front() == '*') {\n\t\t\tpattern.remove_prefix(1);\n\t\t\t// \"**\" matches anything including \"/\"\n\t\t\twhile (!text.empty()) {\n\t\t\t\tif (PatternMatch(pattern, text)) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\ttext.remove_prefix(1);\n\t\t\t}\n\t\t} else {\n\t\t\twhile (!text.empty()) {\n\t\t\t\tif (PatternMatch(pattern, text)) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (text.front() == '/') {\n\t\t\t\t\t// \"/\" not matched by single \"*\"\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\ttext.remove_prefix(1);\n\t\t\t}\n\t\t}\n\t\tassert(text.empty());\n\t\t// Consumed whole text with wildcard so match if pattern consumed\n\t\treturn pattern.empty();\n\t} else if (text.empty()) {\n\t\treturn false;\n\t} else if (pattern.front() == '?') {\n\t\tif (text.front() == '/') {\n\t\t\treturn false;\n\t\t}\n\t\tpattern.remove_prefix(1);\n\t\ttext.remove_prefix(1);\n\t\treturn PatternMatch(pattern, text);\n\t} else if (pattern.front() == '[') {\n\t\tpattern.remove_prefix(1);\n\t\tif (pattern.empty()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst bool positive = pattern.front() != '!';\n\t\tif (!positive) {\n\t\t\tpattern.remove_prefix(1);\n\t\t\tif (pattern.empty()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tbool inSet = false;\n\t\tif (!pattern.empty() && pattern.front() == ']') {\n\t\t\t// First is allowed to be ']'\n\t\t\tif (pattern.front() == text.front()) {\n\t\t\t\tinSet = true;\n\t\t\t}\n\t\t\tpattern.remove_prefix(1);\n\t\t}\n\t\tchar32_t start = 0;\n\t\twhile (!pattern.empty() && pattern.front() != ']') {\n\t\t\tif (pattern.front() == '-') {\n\t\t\t\tpattern.remove_prefix(1);\n\t\t\t\tif (!pattern.empty()) {\n\t\t\t\t\tconst char32_t end = pattern.front();\n\t\t\t\t\tif ((text.front() >= start) && (text.front() <= end)) {\n\t\t\t\t\t\tinSet = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (pattern.front() == text.front()) {\n\t\t\t\tinSet = true;\n\t\t\t}\n\t\t\tif (!pattern.empty()) {\n\t\t\t\tstart = pattern.front();\n\t\t\t\tpattern.remove_prefix(1);\n\t\t\t}\n\t\t}\n\t\tif (!pattern.empty()) {\n\t\t\tpattern.remove_prefix(1);\n\t\t}\n\t\tif (inSet != positive) {\n\t\t\treturn false;\n\t\t}\n\t\ttext.remove_prefix(1);\n\t\treturn PatternMatch(pattern, text);\n\t} else if (pattern.front() == '{') {\n\t\tif (pattern.length() < 2) {\n\t\t\treturn false;\n\t\t}\n\t\tconst size_t endParen = pattern.find('}');\n\t\tif (endParen == std::u32string_view::npos) {\n\t\t\t// Malformed {x} pattern\n\t\t\treturn false;\n\t\t}\n\t\tstd::u32string_view parenExpression = pattern.substr(1, endParen - 1);\n\t\tbool inSet = false;\n\t\tconst size_t dotdot = parenExpression.find(U\"..\");\n\t\tif (dotdot != std::u32string_view::npos) {\n\t\t\t// Numeric range: {10..20}\n\t\t\tconst std::u32string_view firstRange = parenExpression.substr(0, dotdot);\n\t\t\tconst std::u32string_view lastRange = parenExpression.substr(dotdot+2);\n\t\t\tif (firstRange.empty() || lastRange.empty()) {\n\t\t\t\t// Malformed {s..e} range pattern\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst size_t endInteger = text.find_last_of(U\"-0123456789\");\n\t\t\tif (endInteger == std::u32string_view::npos) {\n\t\t\t\t// No integer in text\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst std::u32string_view intPart = text.substr(0, endInteger+1);\n\t\t\tconst int first = IntFromString(firstRange);\n\t\t\tconst int last = IntFromString(lastRange);\n\t\t\tconst int value = IntFromString(intPart);\n\t\t\tif ((value >= first) && (value <= last)) {\n\t\t\t\tinSet = true;\n\t\t\t\ttext.remove_prefix(intPart.length());\n\t\t\t}\n\t\t} else {\n\t\t\t// Alternates: {a,b,cd}\n\t\t\tsize_t comma = parenExpression.find(',');\n\t\t\tfor (;;) {\n\t\t\t\tconst bool finalAlt = comma == std::u32string_view::npos;\n\t\t\t\tconst std::u32string_view oneAlt = finalAlt ? parenExpression :\n\t\t\t\t\tparenExpression.substr(0, comma);\n\t\t\t\tif (oneAlt == text.substr(0, oneAlt.length())) {\n\t\t\t\t\t// match\n\t\t\t\t\tinSet = true;\n\t\t\t\t\ttext.remove_prefix(oneAlt.length());\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (finalAlt) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tparenExpression.remove_prefix(oneAlt.length() + 1);\n\t\t\t\tcomma = parenExpression.find(',');\n\t\t\t}\n\t\t}\n\t\tif (!inSet) {\n\t\t\treturn false;\n\t\t}\n\t\tpattern.remove_prefix(endParen + 1);\n\t\treturn PatternMatch(pattern, text);\n\t} else if (pattern.front() == text.front()) {\n\t\tpattern.remove_prefix(1);\n\t\ttext.remove_prefix(1);\n\t\treturn PatternMatch(pattern, text);\n\t}\n\treturn false;\n}\n\nbool PathMatch(std::string pattern, std::string relPath) {\n#if defined(_WIN32)\n\t// Convert Windows path separators to Unix\n\tstd::replace(relPath.begin(), relPath.end(), '\\\\', '/');\n#endif\n#if defined(_WIN32) || defined(__APPLE__)\n\t// Case-insensitive, only does ASCII but fine for test example files\n\tLowerCaseAZ(pattern);\n\tLowerCaseAZ(relPath);\n#endif\n\tconst std::u32string patternU32 = UTF32FromUTF8(pattern);\n\tconst std::u32string relPathU32 = UTF32FromUTF8(relPath);\n\tif (PatternMatch(patternU32, relPathU32)) {\n\t\treturn true;\n\t}\n\tconst size_t lastSlash = relPathU32.rfind('/');\n\tif (lastSlash == std::string::npos) {\n\t\treturn false;\n\t}\n\t// Match against just filename\n\tconst std::u32string fileNameU32 = relPathU32.substr(lastSlash+1);\n\treturn PatternMatch(patternU32, fileNameU32);\n}\n\nconstexpr std::string_view suffixStyled = \".styled\";\nconstexpr std::string_view suffixFolded = \".folded\";\nconstexpr std::string_view lexerPrefix = \"lexer.*\";\nconstexpr std::string_view prefixIf = \"if \";\nconstexpr std::string_view prefixMatch = \"match \";\nconstexpr std::string_view prefixEqual = \"= \";\nconstexpr std::string_view prefixComment = \"#\";\n\nstd::string ReadFile(std::filesystem::path path) {\n\tstd::ifstream ifs(path, std::ios::binary);\n\tstd::string content((std::istreambuf_iterator<char>(ifs)),\n\t\t(std::istreambuf_iterator<char>()));\n\treturn content;\n}\n\nstd::string MarkedDocument(const Scintilla::IDocument *pdoc) {\n\tassert(pdoc);\n\tstd::ostringstream os(std::ios::binary);\n\tchar prevStyle = -1;\n\tfor (Sci_Position pos = 0; pos < pdoc->Length(); pos++) {\n\t\tconst char styleNow = pdoc->StyleAt(pos);\n\t\tif (styleNow != prevStyle) {\n\t\t\tconst unsigned char uStyleNow = styleNow;\n\t\t\tconst unsigned int uiStyleNow = uStyleNow;\n\t\t\tos << \"{\" << uiStyleNow << \"}\";\n\t\t\tprevStyle = styleNow;\n\t\t}\n\t\tchar ch = '\\0';\n\t\tpdoc->GetCharRange(&ch, pos, 1);\n\t\tos << ch;\n\t}\n\treturn os.str();\n}\n\nvoid PrintLevel(std::ostringstream &os, int level) {\n\tconst int levelNow = level & 0xFFF;\n\tconst int levelNext = level >> 16;\n\tconst int levelFlags = (level >> 12) & 0xF;\n\tchar foldSymbol = ' ';\n\tif (level & 0x2000)\n\t\tfoldSymbol = '+';\n\telse if (levelNow > 0x400)\n\t\tfoldSymbol = '|';\n\tos << std::hex << \" \" << levelFlags << \" \"\n\t\t<< std::setw(3) << levelNow << \" \"\n\t\t<< std::setw(3) << levelNext << \" \"\n\t\t<< foldSymbol << \" \";\n}\n\nstd::string FoldedDocument(const Scintilla::IDocument *pdoc) {\n\tassert(pdoc);\n\tstd::ostringstream os(std::ios::binary);\n\tSci_Position linePrev = -1;\n\tchar ch = '\\0';\n\tfor (Sci_Position pos = 0; pos < pdoc->Length(); pos++) {\n\t\tconst Sci_Position lineNow = pdoc->LineFromPosition(pos);\n\t\tif (linePrev < lineNow) {\n\t\t\tPrintLevel(os, pdoc->GetLevel(lineNow));\n\t\t\tlinePrev = lineNow;\n\t\t}\n\t\tpdoc->GetCharRange(&ch, pos, 1);\n\t\tos << ch;\n\t}\n\tif (ch == '\\n') {\n\t\t// Extra empty line\n\t\tPrintLevel(os, pdoc->GetLevel(linePrev + 1));\n\t}\n\treturn os.str();\n}\n\nstd::pair<std::string, std::string> MarkedAndFoldedDocument(const Scintilla::IDocument *pdoc) {\n\treturn { MarkedDocument(pdoc), FoldedDocument(pdoc) };\n}\n\nstd::vector<std::string> StringSplit(const std::string_view &text, int separator) {\n\tstd::vector<std::string> vs(text.empty() ? 0 : 1);\n\tfor (const char ch : text) {\n\t\tif (ch == separator) {\n\t\t\tvs.push_back(std::string());\n\t\t} else {\n\t\t\tvs.back() += ch;\n\t\t}\n\t}\n\treturn vs;\n}\n\nconstexpr bool IsSpaceOrTab(char ch) noexcept {\n\treturn (ch == ' ') || (ch == '\\t');\n}\n\nvoid PrintRanges(const std::vector<bool> &v) {\n\tstd::cout << \"    \";\n\tstd::optional<size_t> startRange;\n\tfor (size_t style = 0; style <= v.size(); style++) {\n\t\t// Goes one past size so that final range is closed\n\t\tif ((style < v.size()) && v.at(style)) {\n\t\t\tif (!startRange) {\n\t\t\t\tstartRange = style;\n\t\t\t}\n\t\t} else if (startRange) {\n\t\t\tconst size_t endRange = style - 1;\n\t\t\tstd::cout << *startRange;\n\t\t\tif (*startRange != endRange) {\n\t\t\t\tstd::cout << \"-\" << endRange;\n\t\t\t}\n\t\t\tstd::cout << \" \";\n\t\t\tstartRange.reset();\n\t\t}\n\t}\n\tstd::cout << \"\\n\";\n}\n\nclass PropertyMap {\n\n\tstd::string Evaluate(std::string_view text) {\n\t\tif (text.find(' ') != std::string_view::npos) {\n\t\t\tif (text.starts_with(prefixEqual)) {\n\t\t\t\tconst std::string_view sExpressions = text.substr(prefixEqual.length());\n\t\t\t\tstd::vector<std::string> parts = StringSplit(sExpressions, ';');\n\t\t\t\tif (parts.size() > 1) {\n\t\t\t\t\tfor (size_t part = 1; part < parts.size(); part++) {\n\t\t\t\t\t\tif (parts.at(part) != parts.at(0)) {\n\t\t\t\t\t\t\treturn \"0\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn \"1\";\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {};\n\t\t} else {\n\t\t\tstd::optional<std::string> value = GetProperty(text);\n\t\t\tif (value) {\n\t\t\t\treturn *value;\n\t\t\t}\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tstd::string Expand(std::string withVars) {\n\t\tconstexpr size_t maxVars = 100;\n\t\tsize_t varStart = withVars.rfind(\"$(\");\n\t\tfor (size_t count = 0; (count < maxVars) && (varStart != std::string::npos); count++) {\n\t\t\tconst size_t varEnd = withVars.find(')', varStart + 2);\n\t\t\tif (varEnd == std::string::npos) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst std::string_view whole = withVars;\n\t\t\tconst std::string_view var = whole.substr(varStart + 2, varEnd - (varStart + 2));\n\t\t\tconst std::string val = Evaluate(var);\n\n\t\t\twithVars.erase(varStart, varEnd - varStart + 1);\n\t\t\twithVars.insert(varStart, val);\n\n\t\t\tvarStart = withVars.rfind(\"$(\");\n\t\t}\n\t\treturn withVars;\n\t}\n\n\tstatic std::vector<std::string> GetFilePatterns(const std::string &key) {\n\t\tstd::vector<std::string> exts;\n\t\t// Malformed patterns are skipped if we require the whole prefix here;\n\t\t// a fuzzy search lets us collect and report them\n\t\tconst size_t patternStart = key.find('*');\n\t\tif (patternStart == std::string::npos)\n\t\t\treturn exts;\n\n\t\tconst std::string patterns = key.substr(patternStart);\n\t\tfor (const std::string &pat : StringSplit(patterns, ';')) {\n\t\t\t// Only accept patterns in the form *.xyz\n\t\t\tif (pat.starts_with(\"*.\") && pat.length() > 2) {\n\t\t\t\texts.push_back(pat.substr(1));\n\t\t\t} else {\n\t\t\t\tstd::cout << \"\\n\"\n\t\t\t\t\t  << \"Ignoring bad file pattern '\" << pat << \"' in list \" << patterns << \"\\n\";\n\t\t\t}\n\t\t}\n\t\treturn exts;\n\t}\n\n\tbool ProcessLine(std::string_view text, bool ifIsTrue) {\n\t\t// If clause ends with first non-indented line\n\t\tif (!ifIsTrue && (text.empty() || IsSpaceOrTab(text.at(0)))) {\n\t\t\treturn false;\n\t\t}\n\t\tifIsTrue = true;\n\t\tif (text.starts_with(prefixIf)) {\n\t\t\tconst std::string value = Expand(std::string(text.substr(prefixIf.length())));\n\t\t\tif (value == \"0\" || value == \"\") {\n\t\t\t\tifIsTrue = false;\n\t\t\t}\n\t\t} else if (text.starts_with(prefixMatch)) {\n\t\t\tstd::optional<std::string> fileNameExt = GetProperty(\"FileNameExt\");\n\t\t\tif (fileNameExt) {\n\t\t\t\tstd::string pattern(text.substr(prefixMatch.length()));\n\t\t\t\t// Remove trailing white space\n\t\t\t\twhile (!pattern.empty() && IsSpaceOrTab(pattern.back())) {\n\t\t\t\t\tpattern.pop_back();\n\t\t\t\t}\n\t\t\t\tifIsTrue = PathMatch(pattern, *fileNameExt);\n\t\t\t} else {\n\t\t\t\tifIsTrue = false;\n\t\t\t}\n\t\t} else {\n\t\t\twhile (!text.empty() && IsSpaceOrTab(text.at(0))) {\n\t\t\t\ttext.remove_prefix(1);\n\t\t\t}\n\t\t\tif (text.starts_with(prefixComment)) {\n\t\t\t\treturn ifIsTrue;\n\t\t\t}\n\t\t\tconst size_t positionEquals = text.find(\"=\");\n\t\t\tif (positionEquals != std::string::npos) {\n\t\t\t\tconst std::string key(text.substr(0, positionEquals));\n\t\t\t\tconst std::string_view value = text.substr(positionEquals + 1);\n\t\t\t\tproperties[key] = value;\n\t\t\t}\n\t\t}\n\t\treturn ifIsTrue;\n\t}\n\npublic:\n\tusing PropMap = std::map<std::string, std::string>;\n\tPropMap properties;\n\n\tvoid ReadFromFile(std::filesystem::path path) {\n\t\tbool ifIsTrue = true;\n\t\tstd::ifstream ifs(path);\n\t\tstd::string line;\n\t\tstd::string logicalLine;\n\t\twhile (std::getline(ifs, line)) {\n\t\t\tif (line.ends_with(\"\\r\")) {\n\t\t\t\t// Accidentally have \\r\\n line ends on Unix system\n\t\t\t\tline.pop_back();\n\t\t\t}\n\t\t\tlogicalLine += line;\n\t\t\tif (logicalLine.ends_with(\"\\\\\")) {\n\t\t\t\tlogicalLine.pop_back();\n\t\t\t} else {\n\t\t\t\tifIsTrue = ProcessLine(logicalLine, ifIsTrue);\n\t\t\t\tlogicalLine.clear();\n\t\t\t}\n\t\t}\n\t}\n\n\tstd::optional<std::string> GetProperty(std::string_view key) const {\n\t\tconst PropMap::const_iterator prop = properties.find(std::string(key));\n\t\tif (prop == properties.end())\n\t\t\treturn std::nullopt;\n\t\telse\n\t\t\treturn prop->second;\n\t}\n\n\tstd::optional<std::string> GetPropertyForFile(std::string_view keyPrefix, std::string_view fileName) const {\n\t\tfor (auto const &[key, val] : properties) {\n\t\t\tif (key.starts_with(keyPrefix)) {\n\t\t\t\tconst std::string keySuffix = key.substr(keyPrefix.length());\n\t\t\t\tif (fileName.ends_with(keySuffix)) {\n\t\t\t\t\treturn val;\n\t\t\t\t} else if (key.find(';') != std::string::npos) {\n\t\t\t\t\t// It may be the case that a suite of test files with various extensions are\n\t\t\t\t\t// meant to share a common configuration, so try to find a matching\n\t\t\t\t\t// extension in a delimited list, e.g., lexer.*.html;*.php;*.asp=hypertext\n\t\t\t\t\tfor (const std::string &ext : GetFilePatterns(key)) {\n\t\t\t\t\t\tif (fileName.ends_with(ext)) {\n\t\t\t\t\t\t\treturn val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn std::nullopt;\n\t}\n\n\tstd::optional<int> GetPropertyValue(std::string_view key) const {\n\t\tstd::optional<std::string> value = GetProperty(key);\n\t\ttry {\n\t\t\tif (value)\n\t\t\t\treturn std::stoi(value->c_str());\n\t\t}\n\t\tcatch (std::invalid_argument &) {\n\t\t\t// Just return empty\n\t\t}\n\t\treturn {};\n\t}\n\n};\n\nsize_t FirstLineDifferent(std::string_view a, std::string_view b) {\n\tsize_t i = 0;\n\twhile (i < std::min(a.size(), b.size()) && a.at(i) == b.at(i)) {\n\t\ti++;\n\t}\n\treturn std::count(a.begin(), a.begin() + i, '\\n');\n}\n\nbool CheckSame(std::string_view augmentedText, std::string_view augmentedTextNew, std::string_view item, std::string_view suffix, const std::filesystem::path &path) {\n\tif (augmentedTextNew == augmentedText) {\n\t\treturn true;\n\t}\n\tconst size_t lineNumber = FirstLineDifferent(augmentedText, augmentedTextNew) + 1;\n\tstd::cout << \"\\n\" << path.string() << \":\" << lineNumber << \":\";\n\tconst std::string differenceType = augmentedText.empty() ? \"new\" : \"different\";\n\tstd::cout << \" has \" << differenceType << \" \" << item << \"\\n\\n\";\n\tstd::filesystem::path pathNew = path;\n\tpathNew += suffix;\n\tpathNew += \".new\";\n\tstd::ofstream ofs(pathNew, std::ios::binary);\n\tofs << augmentedTextNew;\n\treturn false;\n}\n\nint Substitute(std::string &s, const std::string &sFind, const std::string &sReplace) {\n\tint c = 0;\n\tconst size_t lenFind = sFind.size();\n\tconst size_t lenReplace = sReplace.size();\n\tsize_t posFound = s.find(sFind);\n\twhile (posFound != std::string::npos) {\n\t\ts.replace(posFound, lenFind, sReplace);\n\t\tposFound = s.find(sFind, posFound + lenReplace);\n\t\tc++;\n\t}\n\treturn c;\n}\n\nint WindowsToUnix(std::string &s) {\n\treturn Substitute(s, \"\\r\\n\", \"\\n\");\n}\n\nint UnixToWindows(std::string &s) {\n\treturn Substitute(s, \"\\n\", \"\\r\\n\");\n}\n\nconst std::string BOM = \"\\xEF\\xBB\\xBF\";\n\nvoid StyleLineByLine(TestDocument &doc, Scintilla::ILexer5 *plex) {\n\tassert(plex);\n\tScintilla::IDocument *pdoc = &doc;\n\tconst Sci_Position lines = doc.LineFromPosition(doc.Length());\n\tSci_Position startLine = 0;\n\tfor (Sci_Position line = 0; line <= lines; line++) {\n\t\tconst Sci_Position endLine = doc.LineStart(line + 1);\n\t\tint styleStart = 0;\n\t\tif (startLine > 0)\n\t\t\tstyleStart = doc.StyleAt(startLine - 1);\n\t\tplex->Lex(startLine, endLine - startLine, styleStart, pdoc);\n\t\tplex->Fold(startLine, endLine - startLine, styleStart, pdoc);\n\t\tstartLine = endLine;\n\t}\n}\n\nbool TestCRLF(std::filesystem::path path, const std::string s, Scintilla::ILexer5 *plex, bool disablePerLineTests) {\n\tassert(plex);\n\tbool success = true;\n\t// Convert all line ends to \\r\\n to check if styles change between \\r and \\n which makes\n\t// it difficult to test on different platforms when files may have line ends changed.\n\tstd::string text = s;\n\tWindowsToUnix(text);\n\tconst bool originalIsUnix = text == s;\n\tstd::string textUnix = text;\n\tUnixToWindows(text);\n\tTestDocument doc;\n\tdoc.Set(text);\n\tScintilla::IDocument *pdoc = &doc;\n\tassert(pdoc);\n\tplex->Lex(0, pdoc->Length(), 0, pdoc);\n\tplex->Fold(0, pdoc->Length(), 0, pdoc);\n\tconst auto [styledText, foldedText] = MarkedAndFoldedDocument(pdoc);\n\n\tint prevStyle = -1;\n\tSci_Position line = 1;\n\tfor (Sci_Position pos = 0; pos < pdoc->Length(); pos++) {\n\t\tconst int styleNow = pdoc->StyleAt(pos);\n\t\tchar ch = '\\0';\n\t\tpdoc->GetCharRange(&ch, pos, 1);\n\t\tif (ch == '\\n') {\n\t\t\tif (styleNow != prevStyle) {\n\t\t\t\tstd::cout << path.string() << \":\" << line << \":\" <<\n\t\t\t\t\t\" different styles between \\\\r and \\\\n at \" <<\n\t\t\t\t\tpos << \": \" << prevStyle << \", \" << styleNow << \"\\n\";\n\t\t\t\tsuccess = false;\n\t\t\t}\n\t\t\tline++;\n\t\t}\n\t\tprevStyle = styleNow;\n\t}\n\n\t// Lex and fold with \\n line ends then check result is same\n\n\tTestDocument docUnix;\n\tdocUnix.Set(textUnix);\n\tScintilla::IDocument *pdocUnix = &docUnix;\n\tassert(pdocUnix);\n\tplex->Lex(0, pdocUnix->Length(), 0, pdocUnix);\n\tplex->Fold(0, pdocUnix->Length(), 0, pdocUnix);\n\tauto [styledTextUnix, foldedTextUnix] = MarkedAndFoldedDocument(pdocUnix);\n\n\t// Convert results from \\n to \\r\\n run\n\tUnixToWindows(styledTextUnix);\n\tUnixToWindows(foldedTextUnix);\n\n\tif (styledText != styledTextUnix) {\n\t\tstd::cout << \"\\n\" << path.string() << \":1: has different styles with \\\\n versus \\\\r\\\\n line ends\\n\\n\";\n\t\tsuccess = false;\n\t}\n\tif (foldedText != foldedTextUnix) {\n\t\tstd::cout << \"\\n\" << path.string() << \":1: has different folds with \\\\n versus \\\\r\\\\n line ends\\n\\n\";\n\t\tsuccess = false;\n\t}\n\n\t// Test line by line lexing/folding with Unix \\n line ends\n\tif (!disablePerLineTests && !originalIsUnix) {\n\t\tStyleLineByLine(docUnix, plex);\n\t\tauto [styledTextNewPerLine, foldedTextNewPerLine] = MarkedAndFoldedDocument(pdocUnix);\n\t\t// Convert results from \\n to \\r\\n run\n\t\tUnixToWindows(styledTextNewPerLine);\n\t\tUnixToWindows(foldedTextNewPerLine);\n\t\tif (!CheckSame(styledTextUnix, styledTextNewPerLine, \"per-line styles \\\\n\", suffixStyled, path)) {\n\t\t\tsuccess = false;\n\t\t}\n\t\tif (!CheckSame(foldedTextUnix, foldedTextNewPerLine, \"per-line folds \\\\n\", suffixFolded, path)) {\n\t\t\tsuccess = false;\n\t\t}\n\t}\n\n\tplex->Release();\n\treturn success;\n}\n\nvoid TestILexer(Scintilla::ILexer5 *plex) {\n\tassert(plex);\n\n\t// Test each method of the ILexer interface.\n\t// Mostly ensures there are no crashes when calling methods.\n\t// Some methods are tested later (Release, Lex, Fold).\n\t// PrivateCall performs arbitrary actions so is not safe to call.\n\n\t[[maybe_unused]] const int version = plex->Version();\n\tassert(version == Scintilla::lvRelease5);\n\n\t[[maybe_unused]] const char *language = plex->GetName();\n\tassert(language);\n\n\t[[maybe_unused]] const int ident = plex->GetIdentifier();\n\tassert(ident >= 0);\n\n\t[[maybe_unused]] const char *propertyNames = plex->PropertyNames();\n\tassert(propertyNames);\n\n\t[[maybe_unused]] const int propertyType = plex->PropertyType(\"unknown\");\n\tassert(propertyType >= 0 && propertyType <= 2);\n\n\t[[maybe_unused]] const char *propertyDescription = plex->DescribeProperty(\"unknown\");\n\tassert(propertyDescription);\n\n\t[[maybe_unused]] const Sci_Position invalidation = plex->PropertySet(\"unknown\", \"unknown\");\n\tassert(invalidation == 0 || invalidation == -1);\n\n\t[[maybe_unused]] const char *wordListDescription = plex->DescribeWordListSets();\n\tassert(wordListDescription);\n\n\t[[maybe_unused]] const Sci_Position invalidationWordList = plex->WordListSet(9, \"unknown\");\n\tassert(invalidationWordList == 0 || invalidationWordList == -1);\n\n\t[[maybe_unused]] const int lineEndTypes = plex->LineEndTypesSupported();\n\tassert(lineEndTypes == 0 || lineEndTypes == 1);\n\n\tif (std::string_view bases = plex->GetSubStyleBases(); !bases.empty()) {\n\t\t// Allocate a substyle for each possible style\n\t\twhile (!bases.empty()) {\n\t\t\tconstexpr int newStyles = 3;\n\t\t\tconst int base = bases.front();\n\t\t\tconst int baseStyle = plex->AllocateSubStyles(base, newStyles);\n\t\t\t[[maybe_unused]] const int styleBack = plex->StyleFromSubStyle(baseStyle);\n\t\t\tassert(styleBack == base);\n\t\t\tplex->SetIdentifiers(baseStyle, \"int nullptr\");\n\t\t\t[[maybe_unused]] const int start = plex->SubStylesStart(base);\n\t\t\tassert(start == baseStyle);\n\t\t\t[[maybe_unused]] const int len = plex->SubStylesLength(base);\n\t\t\tassert(len == newStyles);\n\t\t\tbases.remove_prefix(1);\n\t\t}\n\t\tplex->FreeSubStyles();\n\t}\n\n\t[[maybe_unused]] const int primary = plex->PrimaryStyleFromStyle(2);\n\tassert(primary == 2);\n\n\t[[maybe_unused]] const int distance = plex->DistanceToSecondaryStyles();\n\tassert(distance >= 0);\n\n\t// Just see if crashes - nullptr is valid return to indicate not present.\n\t[[maybe_unused]] const char *propertyUnknownValue = plex->PropertyGet(\"unknown\");\n\n\tconst int styles = plex->NamedStyles();\n\tfor (int style = 0; style < styles; style++) {\n\t\t[[maybe_unused]] const char *name = plex->NameOfStyle(style);\n\t\tassert(name);\n\t\t[[maybe_unused]] const char *tags = plex->TagsOfStyle(style);\n\t\tassert(tags);\n\t\t[[maybe_unused]] const char *description = plex->DescriptionOfStyle(style);\n\t\tassert(description);\n\t}\n}\n\nbool SetProperties(Scintilla::ILexer5 *plex, const std::string &language, const PropertyMap &propertyMap, std::filesystem::path path) {\n\tassert(plex);\n\n\tconst std::string fileName = path.filename().string();\n\n\tif (std::string_view bases = plex->GetSubStyleBases(); !bases.empty()) {\n\t\t// Allocate a substyle for each possible style\n\t\twhile (!bases.empty()) {\n\t\t\tconst int baseStyle = bases.front();\n\t\t\t//\tsubstyles.cpp.11=2\n\t\t\tconst std::string base = std::to_string(baseStyle);\n\t\t\tconst std::string substylesForBase = \"substyles.\" + language + \".\" + base;\n\t\t\tstd::optional<std::string> substylesN = propertyMap.GetProperty(substylesForBase);\n\t\t\tif (substylesN) {\n\t\t\t\tconst int substyles = atoi(substylesN->c_str());\n\t\t\t\tconst int baseStyleNum = plex->AllocateSubStyles(baseStyle, substyles);\n\t\t\t\t//\tsubstylewords.11.1.$(file.patterns.cpp)=std map string vector\n\t\t\t\tfor (int kw = 0; kw < substyles; kw++) {\n\t\t\t\t\tconst std::string substyleWords = \"substylewords.\" + base + \".\" + std::to_string(kw + 1) + \".*\";\n\t\t\t\t\tconst std::optional<std::string> keywordN = propertyMap.GetPropertyForFile(substyleWords, fileName);\n\t\t\t\t\tif (keywordN) {\n\t\t\t\t\t\tplex->SetIdentifiers(baseStyleNum + kw, keywordN->c_str());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbases.remove_prefix(1);\n\t\t}\n\t}\n\n\t// Set keywords, keywords2, ... keywords9, for this file\n\tfor (int kw = 0; kw < 10; kw++) {\n\t\tstd::string kwChoice(\"keywords\");\n\t\tif (kw > 0) {\n\t\t\tkwChoice.push_back(static_cast<char>('1' + kw));\n\t\t}\n\t\tkwChoice.append(\".*\");\n\t\tstd::optional<std::string> keywordN = propertyMap.GetPropertyForFile(kwChoice, fileName);\n\t\tif (keywordN) {\n\t\t\t// New lexer object has all word lists empty so check null effect from setting empty\n\t\t\tconst Sci_Position changedEmpty = plex->WordListSet(kw, \"\");\n\t\t\tif (changedEmpty != -1) {\n\t\t\t\tstd::cout << path.string() << \":1: does not return -1 for null WordListSet(\" << kw << \")\\n\";\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst Sci_Position changedAt = plex->WordListSet(kw, keywordN->c_str());\n\t\t\tif (keywordN->empty()) {\n\t\t\t\tif (changedAt != -1) {\n\t\t\t\t\tstd::cout << path.string() << \":1: does not return -1 for WordListSet(\" << kw << \") to same empty\" << \"\\n\";\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (changedAt == -1) {\n\t\t\t\t\tstd::cout << path.string() << \":1: returns -1 for WordListSet(\" << kw << \")\\n\";\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set parameters of lexer\n\tfor (auto const &[key, val] : propertyMap.properties) {\n\t\tif (key.starts_with(\"lexer.*\")) {\n\t\t\t// Ignore as processed earlier\n\t\t} else if (key.starts_with(\"keywords\")) {\n\t\t\t// Ignore as processed earlier\n\t\t} else if (key.starts_with(\"substyle\")) {\n\t\t\t// Ignore as processed earlier\n\t\t} else {\n\t\t\tplex->PropertySet(key.c_str(), val.c_str());\n\t\t}\n\t}\n\n\treturn true;\n}\n\n\nbool TestFile(const std::filesystem::path &path, const PropertyMap &propertyMap) {\n\t// Find and create correct lexer\n\tstd::optional<std::string> language = propertyMap.GetPropertyForFile(lexerPrefix, path.filename().string());\n\tif (!language) {\n\t\tstd::cout << \"\\n\" << path.string() << \":1: has no language\\n\\n\";\n\t\treturn false;\n\t}\n\tScintilla::ILexer5 *plex = Lexilla::MakeLexer(*language);\n\tif (!plex) {\n\t\tstd::cout << \"\\n\" << path.string() << \":1: has no lexer for \" << *language << \"\\n\\n\";\n\t\treturn false;\n\t}\n\n\tTestILexer(plex);\n\n\tif (!SetProperties(plex, *language, propertyMap, path)) {\n\t\treturn false;\n\t}\n\n\tstd::string text = ReadFile(path);\n\tif (text.starts_with(BOM)) {\n\t\ttext.erase(0, BOM.length());\n\t}\n\n\tstd::filesystem::path pathStyled = path;\n\tpathStyled += suffixStyled;\n\tconst std::string styledText = ReadFile(pathStyled);\n\n\tstd::filesystem::path pathFolded = path;\n\tpathFolded += suffixFolded;\n\tconst std::string foldedText = ReadFile(pathFolded);\n\n\tconst int repeatLex = propertyMap.GetPropertyValue(\"testlexers.repeat.lex\").value_or(1);\n\tconst int repeatFold = propertyMap.GetPropertyValue(\"testlexers.repeat.fold\").value_or(1);\n\n\tTestDocument doc;\n\tdoc.Set(text);\n\tScintilla::IDocument *pdoc = &doc;\n\tassert(pdoc);\n\tfor (int i = 0; i < repeatLex; i++) {\n\t\tplex->Lex(0, pdoc->Length(), 0, pdoc);\n\t}\n\tfor (int i = 0; i < repeatFold; i++) {\n\t\tplex->Fold(0, pdoc->Length(), 0, pdoc);\n\t}\n\n\tbool success = true;\n\n\tconst auto [styledTextNew, foldedTextNew] = MarkedAndFoldedDocument(pdoc);\n\tif (!CheckSame(styledText, styledTextNew, \"styles\", suffixStyled, path)) {\n\t\tsuccess = false;\n\t}\n\tif (!CheckSame(foldedText, foldedTextNew, \"folds\", suffixFolded, path)) {\n\t\tsuccess = false;\n\t}\n\n\tif (propertyMap.GetPropertyValue(\"testlexers.list.styles\").value_or(0)) {\n\t\tstd::vector<bool> used(0x100);\n\t\tfor (Sci_Position pos = 0; pos < pdoc->Length(); pos++) {\n\t\t\tconst unsigned char uchStyle = pdoc->StyleAt(pos);\n\t\t\tconst unsigned style = uchStyle;\n\t\t\tused.at(style) = true;\n\t\t}\n\t\tPrintRanges(used);\n\t}\n\n\tconst std::optional<int> perLineDisable = propertyMap.GetPropertyValue(\"testlexers.per.line.disable\");\n\tconst bool disablePerLineTests = perLineDisable.value_or(false);\n\n\tplex->Release();\n\n\t// Test line by line lexing/folding\n\tif (success && !disablePerLineTests) {\n\t\tTestDocument docPerLine;\n\t\tdocPerLine.Set(text);\n\t\tScintilla::ILexer5 *plexPerLine = Lexilla::MakeLexer(*language);\n\t\tif (!SetProperties(plexPerLine, *language, propertyMap, path)) {\n\t\t\treturn false;\n\t\t}\n\t\tStyleLineByLine(docPerLine, plexPerLine);\n\t\tconst auto [styledTextNewPerLine, foldedTextNewPerLine] = MarkedAndFoldedDocument(&docPerLine);\n\t\tsuccess = success && CheckSame(styledText, styledTextNewPerLine, \"per-line styles\", suffixStyled, path);\n\t\tsuccess = success && CheckSame(foldedText, foldedTextNewPerLine, \"per-line folds\", suffixFolded, path);\n\t}\n\n\tif (success) {\n\t\tScintilla::ILexer5 *plexCRLF = Lexilla::MakeLexer(*language);\n\t\tSetProperties(plexCRLF, *language, propertyMap, path.filename().string());\n\t\tsuccess = TestCRLF(path, text, plexCRLF, disablePerLineTests);\n\t}\n\n\treturn success;\n}\n\nbool TestDirectory(std::filesystem::path directory, std::filesystem::path basePath) {\n\tbool success = true;\n\tfor (auto &p : std::filesystem::directory_iterator(directory)) {\n\t\tif (!p.is_directory()) {\n\t\t\tconst std::string extension = p.path().extension().string();\n\t\t\tif (extension != \".properties\" && extension != suffixStyled && extension != \".new\" &&\n\t\t\t\textension != suffixFolded) {\n\t\t\t\tconst std::filesystem::path relativePath = p.path().lexically_relative(basePath);\n\t\t\t\tstd::cout << \"Lexing \" << relativePath.string() << '\\n';\n\t\t\t\tPropertyMap properties;\n\t\t\t\tproperties.properties[\"FileNameExt\"] = p.path().filename().string();\n\t\t\t\tproperties.ReadFromFile(directory / \"SciTE.properties\");\n\t\t\t\tif (!TestFile(p, properties)) {\n\t\t\t\t\tsuccess = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn success;\n}\n\nbool AccessLexilla(std::filesystem::path basePath) {\n\tif (!std::filesystem::exists(basePath)) {\n\t\tstd::cout << \"No examples at \" << basePath.string() << \"\\n\";\n\t\treturn false;\n\t}\n\n\tbool success = true;\n\tsize_t count = 0;\n\tfor (auto &p : std::filesystem::recursive_directory_iterator(basePath)) {\n\t\tif (p.is_directory()) {\n\t\t\t//std::cout << p.path().string() << '\\n';\n\t\t\t++count;\n\t\t\tif (!TestDirectory(p, basePath)) {\n\t\t\t\tsuccess = false;\n\t\t\t}\n\t\t}\n\t}\n\tif (count == 0) {\n\t\tsuccess = TestDirectory(basePath, basePath.parent_path());\n\t}\n\treturn success;\n}\n\nstd::filesystem::path FindLexillaDirectory(std::filesystem::path startDirectory) {\n\t// Search up from startDirectory for a directory named \"lexilla\" or containing a \"bin\" subdirectory\n\tstd::filesystem::path directory = startDirectory;\n\twhile (!directory.empty()) {\n\t\t//std::cout << \"Searching \" << directory.string() << \"\\n\";\n\t\tconst std::filesystem::path parent = directory.parent_path();\n\t\tconst std::filesystem::path localLexilla = directory / \"lexilla\";\n\t\tconst std::filesystem::directory_entry entry(localLexilla);\n\t\tif (entry.is_directory()) {\n\t\t\tstd::cout << \"Found Lexilla at \" << entry.path().string() << \"\\n\";\n\t\t\treturn localLexilla;\n\t\t}\n\t\tconst std::filesystem::path localBin = directory / \"bin\";\n\t\tconst std::filesystem::directory_entry entryBin(localBin);\n\t\tif (entryBin.is_directory()) {\n\t\t\tstd::cout << \"Found Lexilla at \" << directory.string() << \"\\n\";\n\t\t\treturn directory;\n\t\t}\n\t\tif (parent == directory) {\n\t\t\tstd::cout << \"Reached root at \" << directory.string() << \"\\n\";\n\t\t\treturn std::filesystem::path();\n\t\t}\n\t\tdirectory = parent;\n\t}\n\treturn std::filesystem::path();\n}\n\nstruct LexerTestsDirectory {\n\tstd::filesystem::path path;\n\tstd::filesystem::path parent;\n\tbool singleLexer;\n};\n\nbool AccessLexilla(std::filesystem::path basePath, const std::vector<LexerTestsDirectory> &directoryList) {\n\tif (directoryList.empty()) {\n\t\treturn AccessLexilla(basePath);\n\t}\n\tbool success = true;\n\tfor (const LexerTestsDirectory &directory : directoryList) {\n\t\tif (directory.singleLexer) {\n\t\t\tif (!TestDirectory(directory.path, directory.parent)) {\n\t\t\t\tsuccess = false;\n\t\t\t}\n\t\t} else {\n\t\t\tif (!AccessLexilla(directory.path)) {\n\t\t\t\tsuccess = false;\n\t\t\t}\n\t\t}\n\t}\n\treturn success;\n}\n\n}\n\n\n\nint main(int argc, char **argv) {\n\tbool success = false;\n\tconst std::filesystem::path baseDirectory = FindLexillaDirectory(std::filesystem::current_path());\n\tif (!baseDirectory.empty()) {\n#if !defined(LEXILLA_STATIC)\n\t\tconst std::filesystem::path sharedLibrary = baseDirectory / \"bin\" / LEXILLA_LIB;\n\t\tif (!Lexilla::Load(sharedLibrary.string())) {\n\t\t\tstd::cout << \"Failed to load \" << sharedLibrary << \"\\n\";\n\t\t\treturn 1;\t// Indicate failure\n\t\t}\n#endif\n\t\tstd::filesystem::path examplesDirectory = baseDirectory / \"test\" / \"examples\";\n\t\tstd::vector<LexerTestsDirectory> directoryList;\n\t\tfor (int i = 1; i < argc; i++) {\n\t\t\tconst std::string_view arg = argv[i];\n\t\t\tif (!arg.starts_with('-')) {\n\t\t\t\tstd::filesystem::path path = arg;\n\t\t\t\tif (std::filesystem::is_directory(path)) {\n\t\t\t\t\tstd::filesystem::path parent = path.parent_path();\n\t\t\t\t\tconst bool singleLexer = std::filesystem::equivalent(examplesDirectory, parent);\n\t\t\t\t\tdirectoryList.push_back({path, parent, singleLexer});\n\t\t\t\t} else {\n\t\t\t\t\tpath = examplesDirectory / path;\n\t\t\t\t\tif (std::filesystem::is_directory(path)) {\n\t\t\t\t\t\tdirectoryList.push_back({path, examplesDirectory, true});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tsuccess = AccessLexilla(examplesDirectory, directoryList);\n\t}\n\treturn success ? 0 : 1;\n}\n"
  },
  {
    "path": "test/TestLexers.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <VCProjectVersion>16.0</VCProjectVersion>\r\n    <ProjectGuid>{2E0BBD6B-4BC8-4A6C-9DDA-199C27899335}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>lexillatest</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <CodeAnalysisRuleSet>..\\..\\..\\..\\..\\..\\..\\Users\\Neil\\NeilRules.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>\r\n    <EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <CodeAnalysisRuleSet>..\\..\\..\\..\\..\\..\\..\\Users\\Neil\\NeilRules.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <CodeAnalysisRuleSet>..\\..\\..\\..\\..\\..\\..\\Users\\Neil\\NeilRules.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <Optimization>Disabled</Optimization>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n      <AdditionalIncludeDirectories>..\\..\\scintilla\\include;..\\include;..\\access;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <LanguageStandard>stdcpplatest</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <Optimization>Disabled</Optimization>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n      <AdditionalIncludeDirectories>..\\..\\scintilla\\include;..\\include;..\\access;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <LanguageStandard>stdcpplatest</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n      <AdditionalIncludeDirectories>..\\..\\scintilla\\include;..\\include;..\\access;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <LanguageStandard>stdcpplatest</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n      <AdditionalIncludeDirectories>..\\..\\scintilla\\include;..\\include;..\\access;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <LanguageStandard>stdcpplatest</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"TestLexers.cxx\" />\r\n    <ClCompile Include=\"TestDocument.cxx\" />\r\n    <ClCompile Include=\"..\\access\\LexillaAccess.cxx\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"..\\bin\\Lexilla.dll\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "test/examples/asciidoc/AllStyles.adoc",
    "content": "Text=0\n*Strong Emphasis (bold) 1=1*\n**Strong Emphasis (bold) 2=2**\n_Emphasis (italic) 1=3_\n__Emphasis (italic) 2=4__\n= Heading level 1=5\n== Heading level 2=6\n=== Heading level 3=7\n==== Heading level 4=8\n===== Heading level 5=9\n====== Heading level 6=10\n* Unordered list item=11\n. Ordered list item=12\n> Block quote=13\nhttps://14.com[Link=14]\n----\nCode block=15\n----\n++++\nPassthrough block=16\n++++\n// Comment=17\n////\nComment Block=18\n////\n+Literal=19+\n....\nLiteral Block=20\n....\n:Attrib=21: Attrib Value=22\nifdef::Macro=23\nifeval::Macro=23\nifndef::Macro=23\nendif::Macro=23\naudio::Macro=23\ninclude::Macro=23\nimage::Macro=23\nvideo::Macro=23\nasciimath:Macro=23\nbtn:Macro=23\nimage:Macro=23\nkbd:Macro=23\nlatexmath:Macro=23\nlink:Macro=23\nmailto:Macro=23\nmenu:Macro=23\npass:Macro=23\nstem:Macro=23\nxref:Macro=23\nCAUTION:Macro=23\nIMPORTANT:Macro=23\nNOTE:Macro=23\nTIP:Macro=23\nWARNING:Macro=23\n"
  },
  {
    "path": "test/examples/asciidoc/AllStyles.adoc.folded",
    "content": " 0 400   0   Text=0\n 0 400   0   *Strong Emphasis (bold) 1=1*\n 0 400   0   **Strong Emphasis (bold) 2=2**\n 0 400   0   _Emphasis (italic) 1=3_\n 0 400   0   __Emphasis (italic) 2=4__\n 0 400   0   = Heading level 1=5\n 0 400   0   == Heading level 2=6\n 0 400   0   === Heading level 3=7\n 0 400   0   ==== Heading level 4=8\n 0 400   0   ===== Heading level 5=9\n 0 400   0   ====== Heading level 6=10\n 0 400   0   * Unordered list item=11\n 0 400   0   . Ordered list item=12\n 0 400   0   > Block quote=13\n 0 400   0   https://14.com[Link=14]\n 0 400   0   ----\n 0 400   0   Code block=15\n 0 400   0   ----\n 0 400   0   ++++\n 0 400   0   Passthrough block=16\n 0 400   0   ++++\n 0 400   0   // Comment=17\n 0 400   0   ////\n 0 400   0   Comment Block=18\n 0 400   0   ////\n 0 400   0   +Literal=19+\n 0 400   0   ....\n 0 400   0   Literal Block=20\n 0 400   0   ....\n 0 400   0   :Attrib=21: Attrib Value=22\n 0 400   0   ifdef::Macro=23\n 0 400   0   ifeval::Macro=23\n 0 400   0   ifndef::Macro=23\n 0 400   0   endif::Macro=23\n 0 400   0   audio::Macro=23\n 0 400   0   include::Macro=23\n 0 400   0   image::Macro=23\n 0 400   0   video::Macro=23\n 0 400   0   asciimath:Macro=23\n 0 400   0   btn:Macro=23\n 0 400   0   image:Macro=23\n 0 400   0   kbd:Macro=23\n 0 400   0   latexmath:Macro=23\n 0 400   0   link:Macro=23\n 0 400   0   mailto:Macro=23\n 0 400   0   menu:Macro=23\n 0 400   0   pass:Macro=23\n 0 400   0   stem:Macro=23\n 0 400   0   xref:Macro=23\n 0 400   0   CAUTION:Macro=23\n 0 400   0   IMPORTANT:Macro=23\n 0 400   0   NOTE:Macro=23\n 0 400   0   TIP:Macro=23\n 0 400   0   WARNING:Macro=23\n 0 400   0   "
  },
  {
    "path": "test/examples/asciidoc/AllStyles.adoc.styled",
    "content": "{0}Text=0\n{1}*Strong Emphasis (bold) 1=1*{0}\n{2}**Strong Emphasis (bold) 2=2**{0}\n{3}_Emphasis (italic) 1=3_{0}\n{4}__Emphasis (italic) 2=4__{0}\n{5}= Heading level 1=5{0}\n{6}== Heading level 2=6{0}\n{7}=== Heading level 3=7{0}\n{8}==== Heading level 4=8{0}\n{9}===== Heading level 5=9{0}\n{10}====== Heading level 6=10{0}\n{11}*{0} Unordered list item=11\n{12}.{0} Ordered list item=12\n{13}> Block quote=13{0}\nhttps://14.com[{14}Link=14{0}]\n{15}----\nCode block=15\n----{0}\n{16}++++\nPassthrough block=16\n++++{0}\n{17}// Comment=17{0}\n{18}////\nComment Block=18\n////{0}\n+{19}Literal=19{0}+\n{20}....\nLiteral Block=20\n....{0}\n{21}:Attrib=21:{22} Attrib Value=22{0}\n{23}ifdef{0}::Macro=23\n{23}ifeval{0}::Macro=23\n{23}ifndef{0}::Macro=23\n{23}endif{0}::Macro=23\n{23}audio{0}::Macro=23\n{23}include{0}::Macro=23\n{23}image{0}::Macro=23\n{23}video{0}::Macro=23\n{23}asciimat{0}h:Macro=23\n{23}btn{0}:Macro=23\n{23}image{0}:Macro=23\n{23}kbd{0}:Macro=23\n{23}latexmath{0}:Macro=23\n{23}link{0}:Macro=23\n{23}mailto{0}:Macro=23\n{23}menu{0}:Macro=23\n{23}pass{0}:Macro=23\n{23}stem{0}:Macro=23\n{23}xref{0}:Macro=23\n{23}CAUTION{0}:Macro=23\n{23}IMPORTANT{0}:Macro=23\n{23}NOTE{0}:Macro=23\n{23}TIP{0}:Macro=23\n{23}WARNING{0}:Macro=23\n"
  },
  {
    "path": "test/examples/asciidoc/SciTE.properties",
    "content": "code.page=65001\nlexer.*.adoc=asciidoc\nfold=1\n"
  },
  {
    "path": "test/examples/asm/AllStyles.asm",
    "content": "; Enumerate all styles: 0 to 15 except for 11(comment block) which is not yet implemented.\n; This is not a viable source file, it just illustrates the different states in isolation.\n\n; comment=1\n; Comment\n\n; whitespace=0\n\t; w\n\n; number=2\n11\n\n; string=3\n\"String\"\n\n; operator=4\n+\n\n; identifier=5\nidentifier\n\n; CPU instruction=6\nadd\n\n; math Instruction=7\nfadd\n\n; register=8\nECX\n\n; directive=9\nsection\n\n; directive operand=10\nrel\n\n; comment block=11 is for future expansion\n\n; character=12\n'character'\n\n; string EOL=13\n\"no line end\n\n; extended instruction=14\nmovq\n\n; comment directive=15\n comment ~ A multiple-line\n comment directive~\n\n; back quoted string=16\n`back-quoted-string`\n\n; test for folding from segment to ends\ndata segment\nhw db \"HW!\"\ndata ends\n\n;end\n"
  },
  {
    "path": "test/examples/asm/AllStyles.asm.folded",
    "content": " 0 400 400   ; Enumerate all styles: 0 to 15 except for 11(comment block) which is not yet implemented.\n 0 400 400   ; This is not a viable source file, it just illustrates the different states in isolation.\n 1 400 400   \n 0 400 400   ; comment=1\n 0 400 400   ; Comment\n 1 400 400   \n 0 400 400   ; whitespace=0\n 0 400 400   \t; w\n 1 400 400   \n 0 400 400   ; number=2\n 0 400 400   11\n 1 400 400   \n 0 400 400   ; string=3\n 0 400 400   \"String\"\n 1 400 400   \n 0 400 400   ; operator=4\n 0 400 400   +\n 1 400 400   \n 0 400 400   ; identifier=5\n 0 400 400   identifier\n 1 400 400   \n 0 400 400   ; CPU instruction=6\n 0 400 400   add\n 1 400 400   \n 0 400 400   ; math Instruction=7\n 0 400 400   fadd\n 1 400 400   \n 0 400 400   ; register=8\n 0 400 400   ECX\n 1 400 400   \n 0 400 400   ; directive=9\n 0 400 400   section\n 1 400 400   \n 0 400 400   ; directive operand=10\n 0 400 400   rel\n 1 400 400   \n 0 400 400   ; comment block=11 is for future expansion\n 1 400 400   \n 0 400 400   ; character=12\n 0 400 400   'character'\n 1 400 400   \n 0 400 400   ; string EOL=13\n 0 400 400   \"no line end\n 1 400 400   \n 0 400 400   ; extended instruction=14\n 0 400 400   movq\n 1 400 400   \n 0 400 400   ; comment directive=15\n 0 400 400    comment ~ A multiple-line\n 0 400 400    comment directive~\n 1 400 400   \n 0 400 400   ; back quoted string=16\n 0 400 400   `back-quoted-string`\n 1 400 400   \n 0 400 400   ; test for folding from segment to ends\n 2 400 401 + data segment\n 0 401 401 | hw db \"HW!\"\n 0 401 400 | data ends\n 1 400 400   \n 0 400 400   ;end\n 1 400 400   "
  },
  {
    "path": "test/examples/asm/AllStyles.asm.styled",
    "content": "{1}; Enumerate all styles: 0 to 15 except for 11(comment block) which is not yet implemented.\n; This is not a viable source file, it just illustrates the different states in isolation.\n{0}\n{1}; comment=1\n; Comment\n{0}\n{1}; whitespace=0\n{0}\t{1}; w\n{0}\n{1}; number=2\n{2}11{0}\n\n{1}; string=3\n{3}\"String\"{0}\n\n{1}; operator=4\n{4}+{0}\n\n{1}; identifier=5\n{5}identifier{0}\n\n{1}; CPU instruction=6\n{6}add{0}\n\n{1}; math Instruction=7\n{7}fadd{0}\n\n{1}; register=8\n{8}ECX{0}\n\n{1}; directive=9\n{9}section{0}\n\n{1}; directive operand=10\n{10}rel{0}\n\n{1}; comment block=11 is for future expansion\n{0}\n{1}; character=12\n{12}'character'{0}\n\n{1}; string EOL=13\n{13}\"no line end\n{0}\n{1}; extended instruction=14\n{14}movq{0}\n\n{1}; comment directive=15\n{0} {9}comment{0} {15}~ A multiple-line\n comment directive~{0}\n\n{1}; back quoted string=16\n{16}`back-quoted-string`{0}\n\n{1}; test for folding from segment to ends\n{5}data{0} {9}segment{0}\n{5}hw{0} {9}db{0} {3}\"HW!\"{0}\n{5}data{0} {9}ends{0}\n\n{1};end\n"
  },
  {
    "path": "test/examples/asm/SciTE.properties",
    "content": "lexer.*.asm=asm\n\nkeywords.*.asm=add sub xor mov lea call\nkeywords2.*.asm=fadd\nkeywords3.*.asm=rsp rax rcx rdx r8 r9 ecx\nkeywords4.*.asm=db section segment ends alignb resq resqdb global extern equ .bss .text .data start comment\nkeywords5.*.asm=qword rel\nkeywords6.*.asm=movd movq \nkeywords7.*.asm=segment\nkeywords8.*.asm=ends\n\nfold=1\n"
  },
  {
    "path": "test/examples/bash/197ArithmeticOperator.bsh",
    "content": "hello=\"hello, \"\nhello+=word\necho $hello\n\nfor ((i = 2; i > 0; i--)); do\n   echo postfix dec $i\ndone\nfor ((i = 2; i > 0; --i)); do\n   echo prefix dec $i\ndone\nfor ((i = 0; i < 2; i++)); do\n   echo postfix inc $i\ndone\nfor ((i = 0; i < 2; ++i)); do\n   echo prefix inc $i\ndone\n\n# issue 215\nfor ((i = 0; i < 2; i++)); do\n  echo $((((1)) << i))\ndone\n"
  },
  {
    "path": "test/examples/bash/197ArithmeticOperator.bsh.folded",
    "content": " 0 400   0   hello=\"hello, \"\n 0 400   0   hello+=word\n 0 400   0   echo $hello\n 1 400   0   \n 2 400   0 + for ((i = 2; i > 0; i--)); do\n 0 401   0 |    echo postfix dec $i\n 0 401   0 | done\n 2 400   0 + for ((i = 2; i > 0; --i)); do\n 0 401   0 |    echo prefix dec $i\n 0 401   0 | done\n 2 400   0 + for ((i = 0; i < 2; i++)); do\n 0 401   0 |    echo postfix inc $i\n 0 401   0 | done\n 2 400   0 + for ((i = 0; i < 2; ++i)); do\n 0 401   0 |    echo prefix inc $i\n 0 401   0 | done\n 1 400   0   \n 0 400   0   # issue 215\n 2 400   0 + for ((i = 0; i < 2; i++)); do\n 0 401   0 |   echo $((((1)) << i))\n 0 401   0 | done\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/197ArithmeticOperator.bsh.styled",
    "content": "{8}hello{7}={5}\"hello, \"{0}\n{8}hello{7}+={8}word{0}\n{4}echo{0} {9}$hello{0}\n\n{4}for{0} {7}(({8}i{0} {7}={0} {3}2{7};{0} {8}i{0} {7}>{0} {3}0{7};{0} {8}i{7}--));{0} {4}do{0}\n   {4}echo{0} {8}postfix{0} {8}dec{0} {9}$i{0}\n{4}done{0}\n{4}for{0} {7}(({8}i{0} {7}={0} {3}2{7};{0} {8}i{0} {7}>{0} {3}0{7};{0} {7}--{8}i{7}));{0} {4}do{0}\n   {4}echo{0} {8}prefix{0} {8}dec{0} {9}$i{0}\n{4}done{0}\n{4}for{0} {7}(({8}i{0} {7}={0} {3}0{7};{0} {8}i{0} {7}<{0} {3}2{7};{0} {8}i{7}++));{0} {4}do{0}\n   {4}echo{0} {8}postfix{0} {8}inc{0} {9}$i{0}\n{4}done{0}\n{4}for{0} {7}(({8}i{0} {7}={0} {3}0{7};{0} {8}i{0} {7}<{0} {3}2{7};{0} {7}++{8}i{7}));{0} {4}do{0}\n   {4}echo{0} {8}prefix{0} {8}inc{0} {9}$i{0}\n{4}done{0}\n\n{2}# issue 215{0}\n{4}for{0} {7}(({8}i{0} {7}={0} {3}0{7};{0} {8}i{0} {7}<{0} {3}2{7};{0} {8}i{7}++));{0} {4}do{0}\n  {4}echo{0} {7}$(((({3}1{7})){0} {7}<<{0} {8}i{7})){0}\n{4}done{0}\n"
  },
  {
    "path": "test/examples/bash/199Numbers.bsh",
    "content": "# Lexing numeric literals\n\n# From issue #199\n\n# UUIDs\n\nvirsh start 61a6a312-86d3-458c-824a-fa0adc2bd22c\nvirsh start 61969312-86d3-458c-8249-fa0adc2bd22c\nvirsh restore /opt/61a6a312-86d3-458c-824a-fa0adc2bd22c-suspend\n\n# Git items\n\ngit checkout 998d611b516b0e485803089ecd53fdf0ea707a8c\n\ngit log --no-walk 0e2ba9c\ngit log --no-walk rel-5-2-4-97-g7405d4e7\n\n# Arithmetic and character ranges\n\ndeclare -i a=1+1; echo $a\n[[ $a == [0-9] ]] && echo 1\n\n# Brace expansion\n\nfor i in {1..10..2}; do\n\techo $i\ndone\nfor a in {A..Z..2}; do\n\techo $a\ndone\n\n# From Kein-Hong Man\n\n#--------------------------------------------------------------------------\n# Bash number formats\n# (20070712)\n# Octal lexing relaxed to allow hex digits to avoid flagging unnecessary\n# and misleading number errors; radix-prefixed lexing behaviour is unchanged,\n# as those cases are uncommon (to get strict lexing, define PEDANTIC_OCTAL).\n\n# NOTE: Some people may want an entire non-number to be lexed in the normal\n# style and not as part-number part-normal. If the user thinks there is a\n# better case for the former, please lobby for it on the SF issue tracker.\n\n0123 0567\t# octal good\n08 0789 077ABC\t# octal bad (disabled 20070712, now lexed as numbers)\n066XYZ\t\t# octal bad\n0xDEAD 0X1234\t# hex good\n0xABCMNO 0XGHI\t# hex bad\n\n# extended \"[base#]n\" format where base is between 2-64\n# digits range are 0-9a-zA-Z@_\n# if base <= 36, then alphabets are case insensitive\n# this style isn't likely in non-number code, so the lexer currently\n# opts to colour the error in red -- send feedback if this is too\n# intrusive; 'invalid octals' (but valid text) in red proved annoying...\n\n2#10101\t\t# binary\n2#23456\t\t# error (in red)\n8#0123456789AB\t# error (in red)\n16#abcDEF123\n16#abcpqr\t# bad\n64#xyzXYZ@_789\t# full base-64\n99#xyzXYZ@_789\t# error (in red; invalid base)\n111#xyzXYZ@_789\t# error (in red; invalid base)\n\n567+0123*0xBCD\t# with operators\n(4#0123-3#012)\n\n# 20070712:\n# Octal lexing relaxed to avoid marking some number sequences as octal\n# errors. This is because the elements or apps controlled by bash may\n# have a different view of numbers, so we avoid flagging unnecessary\n# (and misleading) number errors. Radix-prefixed number lexing is\n# unchanged, as those cases are uncommon (no feedback on it yet.)\n\n# In the following, red-flagged 'octals' should now be lexed as normal\n# numbers, allowing hex digits.\n\n# flightgear missing.sh\nscriptversion=2004-09-07.08\n\n# git t/t0000/basic.sh\nP=087704a96baf1c2d1c869a8b084481e121c88b5b\n\n# openssh config.guess\n    *:procnto*:*:* | *:QNX:[0123456789]*:*)\n\n# with hex digits, the following will still be an invalid number\n066XYZ\n"
  },
  {
    "path": "test/examples/bash/199Numbers.bsh.folded",
    "content": " 0 400   0   # Lexing numeric literals\n 1 400   0   \n 0 400   0   # From issue #199\n 1 400   0   \n 0 400   0   # UUIDs\n 1 400   0   \n 0 400   0   virsh start 61a6a312-86d3-458c-824a-fa0adc2bd22c\n 0 400   0   virsh start 61969312-86d3-458c-8249-fa0adc2bd22c\n 0 400   0   virsh restore /opt/61a6a312-86d3-458c-824a-fa0adc2bd22c-suspend\n 1 400   0   \n 0 400   0   # Git items\n 1 400   0   \n 0 400   0   git checkout 998d611b516b0e485803089ecd53fdf0ea707a8c\n 1 400   0   \n 0 400   0   git log --no-walk 0e2ba9c\n 0 400   0   git log --no-walk rel-5-2-4-97-g7405d4e7\n 1 400   0   \n 0 400   0   # Arithmetic and character ranges\n 1 400   0   \n 0 400   0   declare -i a=1+1; echo $a\n 0 400   0   [[ $a == [0-9] ]] && echo 1\n 1 400   0   \n 0 400   0   # Brace expansion\n 1 400   0   \n 2 400   0 + for i in {1..10..2}; do\n 0 401   0 | \techo $i\n 0 401   0 | done\n 2 400   0 + for a in {A..Z..2}; do\n 0 401   0 | \techo $a\n 0 401   0 | done\n 1 400   0   \n 0 400   0   # From Kein-Hong Man\n 1 400   0   \n 2 400   0 + #--------------------------------------------------------------------------\n 0 401   0 | # Bash number formats\n 0 401   0 | # (20070712)\n 0 401   0 | # Octal lexing relaxed to allow hex digits to avoid flagging unnecessary\n 0 401   0 | # and misleading number errors; radix-prefixed lexing behaviour is unchanged,\n 0 401   0 | # as those cases are uncommon (to get strict lexing, define PEDANTIC_OCTAL).\n 1 400   0   \n 2 400   0 + # NOTE: Some people may want an entire non-number to be lexed in the normal\n 0 401   0 | # style and not as part-number part-normal. If the user thinks there is a\n 0 401   0 | # better case for the former, please lobby for it on the SF issue tracker.\n 1 400   0   \n 0 400   0   0123 0567\t# octal good\n 0 400   0   08 0789 077ABC\t# octal bad (disabled 20070712, now lexed as numbers)\n 0 400   0   066XYZ\t\t# octal bad\n 0 400   0   0xDEAD 0X1234\t# hex good\n 0 400   0   0xABCMNO 0XGHI\t# hex bad\n 1 400   0   \n 2 400   0 + # extended \"[base#]n\" format where base is between 2-64\n 0 401   0 | # digits range are 0-9a-zA-Z@_\n 0 401   0 | # if base <= 36, then alphabets are case insensitive\n 0 401   0 | # this style isn't likely in non-number code, so the lexer currently\n 0 401   0 | # opts to colour the error in red -- send feedback if this is too\n 0 401   0 | # intrusive; 'invalid octals' (but valid text) in red proved annoying...\n 1 400   0   \n 0 400   0   2#10101\t\t# binary\n 0 400   0   2#23456\t\t# error (in red)\n 0 400   0   8#0123456789AB\t# error (in red)\n 0 400   0   16#abcDEF123\n 0 400   0   16#abcpqr\t# bad\n 0 400   0   64#xyzXYZ@_789\t# full base-64\n 0 400   0   99#xyzXYZ@_789\t# error (in red; invalid base)\n 0 400   0   111#xyzXYZ@_789\t# error (in red; invalid base)\n 1 400   0   \n 0 400   0   567+0123*0xBCD\t# with operators\n 0 400   0   (4#0123-3#012)\n 1 400   0   \n 2 400   0 + # 20070712:\n 0 401   0 | # Octal lexing relaxed to avoid marking some number sequences as octal\n 0 401   0 | # errors. This is because the elements or apps controlled by bash may\n 0 401   0 | # have a different view of numbers, so we avoid flagging unnecessary\n 0 401   0 | # (and misleading) number errors. Radix-prefixed number lexing is\n 0 401   0 | # unchanged, as those cases are uncommon (no feedback on it yet.)\n 1 400   0   \n 2 400   0 + # In the following, red-flagged 'octals' should now be lexed as normal\n 0 401   0 | # numbers, allowing hex digits.\n 1 400   0   \n 0 400   0   # flightgear missing.sh\n 0 400   0   scriptversion=2004-09-07.08\n 1 400   0   \n 0 400   0   # git t/t0000/basic.sh\n 0 400   0   P=087704a96baf1c2d1c869a8b084481e121c88b5b\n 1 400   0   \n 0 400   0   # openssh config.guess\n 0 400   0       *:procnto*:*:* | *:QNX:[0123456789]*:*)\n 1 400   0   \n 0 400   0   # with hex digits, the following will still be an invalid number\n 0 400   0   066XYZ\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/199Numbers.bsh.styled",
    "content": "{2}# Lexing numeric literals{0}\n\n{2}# From issue #199{0}\n\n{2}# UUIDs{0}\n\n{8}virsh{0} {8}start{0} {8}61a6a312-86d3-458c-824a-fa0adc2bd22c{0}\n{8}virsh{0} {8}start{0} {8}61969312-86d3-458c-8249-fa0adc2bd22c{0}\n{8}virsh{0} {8}restore{0} {7}/{8}opt{7}/{8}61a6a312-86d3-458c-824a-fa0adc2bd22c-suspend{0}\n\n{2}# Git items{0}\n\n{8}git{0} {8}checkout{0} {8}998d611b516b0e485803089ecd53fdf0ea707a8c{0}\n\n{8}git{0} {8}log{0} {8}--no-walk{0} {8}0e2ba9c{0}\n{8}git{0} {8}log{0} {8}--no-walk{0} {8}rel-5-2-4-97-g7405d4e7{0}\n\n{2}# Arithmetic and character ranges{0}\n\n{8}declare{0} {8}-i{0} {8}a{7}={3}1{7}+{3}1{7};{0} {4}echo{0} {9}$a{0}\n{7}[[{0} {9}$a{0} {7}=={0} {7}[{8}0-9{7}]{0} {7}]]{0} {7}&&{0} {4}echo{0} {3}1{0}\n\n{2}# Brace expansion{0}\n\n{4}for{0} {8}i{0} {4}in{0} {7}{{3}1{7}..{3}10{7}..{3}2{7}};{0} {4}do{0}\n\t{4}echo{0} {9}$i{0}\n{4}done{0}\n{4}for{0} {8}a{0} {4}in{0} {7}{{8}A{7}..{8}Z{7}..{3}2{7}};{0} {4}do{0}\n\t{4}echo{0} {9}$a{0}\n{4}done{0}\n\n{2}# From Kein-Hong Man{0}\n\n{2}#--------------------------------------------------------------------------{0}\n{2}# Bash number formats{0}\n{2}# (20070712){0}\n{2}# Octal lexing relaxed to allow hex digits to avoid flagging unnecessary{0}\n{2}# and misleading number errors; radix-prefixed lexing behaviour is unchanged,{0}\n{2}# as those cases are uncommon (to get strict lexing, define PEDANTIC_OCTAL).{0}\n\n{2}# NOTE: Some people may want an entire non-number to be lexed in the normal{0}\n{2}# style and not as part-number part-normal. If the user thinks there is a{0}\n{2}# better case for the former, please lobby for it on the SF issue tracker.{0}\n\n{3}0123{0} {3}0567{0}\t{2}# octal good{0}\n{3}08{0} {3}0789{0} {8}077ABC{0}\t{2}# octal bad (disabled 20070712, now lexed as numbers){0}\n{8}066XYZ{0}\t\t{2}# octal bad{0}\n{3}0xDEAD{0} {3}0X1234{0}\t{2}# hex good{0}\n{8}0xABCMNO{0} {8}0XGHI{0}\t{2}# hex bad{0}\n\n{2}# extended \"[base#]n\" format where base is between 2-64{0}\n{2}# digits range are 0-9a-zA-Z@_{0}\n{2}# if base <= 36, then alphabets are case insensitive{0}\n{2}# this style isn't likely in non-number code, so the lexer currently{0}\n{2}# opts to colour the error in red -- send feedback if this is too{0}\n{2}# intrusive; 'invalid octals' (but valid text) in red proved annoying...{0}\n\n{3}2#10101{0}\t\t{2}# binary{0}\n{1}2#23456{0}\t\t{2}# error (in red){0}\n{1}8#0123456789{8}AB{0}\t{2}# error (in red){0}\n{3}16#abcDEF123{0}\n{8}16#abcpqr{0}\t{2}# bad{0}\n{3}64#xyzXYZ@_789{0}\t{2}# full base-64{0}\n{1}99{8}#xyzXYZ{7}@{8}_789{0}\t{2}# error (in red; invalid base){0}\n{1}111{8}#xyzXYZ{7}@{8}_789{0}\t{2}# error (in red; invalid base){0}\n\n{3}567{7}+{3}0123{7}*{3}0xBCD{0}\t{2}# with operators{0}\n{8}(4#0123-3#012){0}\n\n{2}# 20070712:{0}\n{2}# Octal lexing relaxed to avoid marking some number sequences as octal{0}\n{2}# errors. This is because the elements or apps controlled by bash may{0}\n{2}# have a different view of numbers, so we avoid flagging unnecessary{0}\n{2}# (and misleading) number errors. Radix-prefixed number lexing is{0}\n{2}# unchanged, as those cases are uncommon (no feedback on it yet.){0}\n\n{2}# In the following, red-flagged 'octals' should now be lexed as normal{0}\n{2}# numbers, allowing hex digits.{0}\n\n{2}# flightgear missing.sh{0}\n{8}scriptversion{7}={8}2004-09-07.08{0}\n\n{2}# git t/t0000/basic.sh{0}\n{8}P{7}={8}087704a96baf1c2d1c869a8b084481e121c88b5b{0}\n\n{2}# openssh config.guess{0}\n    {7}*:{8}procnto{7}*:*:*{0} {7}|{0} {7}*:{8}QNX{7}:[{3}0123456789{7}]*:*){0}\n\n{2}# with hex digits, the following will still be an invalid number{0}\n{8}066XYZ{0}\n"
  },
  {
    "path": "test/examples/bash/202LineStartOption.bsh",
    "content": "-a\n#\n-b\n#\n\ndeclare -A optionSet=([--help]=0)\nfor option in {-h,--help,--version,--verbose,-,--}; do\ncase $option in\n\t-h|--help)\n\t\toptionSet[--help]=1\n\t\techo help: $option\n\t\t;;\n\t-*-version)\n\t\techo version: $option\n\t\t;;\n\t--)\n\t\techo stop\n\t\t;;\n\t-)\n\t\techo stdin\n\t\t;;\n\t-*[-a-zA-Z0-9])\n\t\techo other: $option\n\t\t;;\nesac\ndone\n\noption=--help\n[[ $option == *-h* ]] && echo $option=${optionSet[$option]}\n\nfor gcc in gcc{,-1{4..0..-1}}; do\n\techo $gcc\ndone\n\nfor gcc in gcc{,{-14..-10}}; do\n\techo $gcc\ndone\n\n# Tilde-refix ~\n~+/foo\n~-/foo\n"
  },
  {
    "path": "test/examples/bash/202LineStartOption.bsh.folded",
    "content": " 0 400   0   -a\n 0 400   0   #\n 0 400   0   -b\n 0 400   0   #\n 1 400   0   \n 0 400   0   declare -A optionSet=([--help]=0)\n 2 400   0 + for option in {-h,--help,--version,--verbose,-,--}; do\n 2 401   0 + case $option in\n 0 402   0 | \t-h|--help)\n 0 402   0 | \t\toptionSet[--help]=1\n 0 402   0 | \t\techo help: $option\n 0 402   0 | \t\t;;\n 0 402   0 | \t-*-version)\n 0 402   0 | \t\techo version: $option\n 0 402   0 | \t\t;;\n 0 402   0 | \t--)\n 0 402   0 | \t\techo stop\n 0 402   0 | \t\t;;\n 0 402   0 | \t-)\n 0 402   0 | \t\techo stdin\n 0 402   0 | \t\t;;\n 0 402   0 | \t-*[-a-zA-Z0-9])\n 0 402   0 | \t\techo other: $option\n 0 402   0 | \t\t;;\n 0 402   0 | esac\n 0 401   0 | done\n 1 400   0   \n 0 400   0   option=--help\n 0 400   0   [[ $option == *-h* ]] && echo $option=${optionSet[$option]}\n 1 400   0   \n 2 400   0 + for gcc in gcc{,-1{4..0..-1}}; do\n 0 401   0 | \techo $gcc\n 0 401   0 | done\n 1 400   0   \n 2 400   0 + for gcc in gcc{,{-14..-10}}; do\n 0 401   0 | \techo $gcc\n 0 401   0 | done\n 1 400   0   \n 0 400   0   # Tilde-refix ~\n 0 400   0   ~+/foo\n 0 400   0   ~-/foo\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/202LineStartOption.bsh.styled",
    "content": "{8}-a{0}\n{2}#{0}\n{8}-b{0}\n{2}#{0}\n\n{8}declare{0} {8}-A{0} {8}optionSet{7}=([{8}--help{7}]={3}0{7}){0}\n{4}for{0} {8}option{0} {4}in{0} {7}{{8}-h{7},{8}--help{7},{8}--version{7},{8}--verbose{7},{8}-{7},{8}--{7}};{0} {4}do{0}\n{4}case{0} {9}$option{0} {4}in{0}\n\t{8}-h{7}|{8}--help{7}){0}\n\t\t{8}optionSet{7}[{8}--help{7}]={3}1{0}\n\t\t{4}echo{0} {8}help{7}:{0} {9}$option{0}\n\t\t{7};;{0}\n\t{8}-{7}*{8}-version{7}){0}\n\t\t{4}echo{0} {8}version{7}:{0} {9}$option{0}\n\t\t{7};;{0}\n\t{8}--{7}){0}\n\t\t{4}echo{0} {8}stop{0}\n\t\t{7};;{0}\n\t{8}-{7}){0}\n\t\t{4}echo{0} {8}stdin{0}\n\t\t{7};;{0}\n\t{8}-{7}*[{8}-a-zA-Z0-9{7}]){0}\n\t\t{4}echo{0} {8}other{7}:{0} {9}$option{0}\n\t\t{7};;{0}\n{4}esac{0}\n{4}done{0}\n\n{8}option{7}={8}--help{0}\n{7}[[{0} {9}$option{0} {7}=={0} {7}*{8}-h{7}*{0} {7}]]{0} {7}&&{0} {4}echo{0} {9}$option{7}={10}${optionSet[$option]}{0}\n\n{4}for{0} {8}gcc{0} {4}in{0} {8}gcc{7}{,-{3}1{7}{{3}4{7}..{3}0{7}..-{3}1{7}}};{0} {4}do{0}\n\t{4}echo{0} {9}$gcc{0}\n{4}done{0}\n\n{4}for{0} {8}gcc{0} {4}in{0} {8}gcc{7}{,{-{3}14{7}..-{3}10{7}}};{0} {4}do{0}\n\t{4}echo{0} {9}$gcc{0}\n{4}done{0}\n\n{2}# Tilde-refix ~{0}\n{7}~+/{8}foo{0}\n{7}~-/{8}foo{0}\n"
  },
  {
    "path": "test/examples/bash/203TestOption.bsh",
    "content": "[[ $1 == -e* ]] && echo e\n\nif [[ -d /usr/bin &&\n\t-e /usr/bin/bash ]]; then\n\techo find bash\nfi\n\nif [[ -d /usr/bin &&\t-e /usr/bin/bash ]]; then\n\techo find bash\nfi\n\nif [ -d /usr/bin && -e /usr/bin/bash ]; then\n\techo find bash\nfi\n\nif [ -d /usr/bin &&\n\t-e /usr/bin/bash ]; then\n\techo find bash\nfi\n\nif [ -d /usr/bin && \\\n\t-e /usr/bin/bash ]; then\n\techo find bash\nfi\n"
  },
  {
    "path": "test/examples/bash/203TestOption.bsh.folded",
    "content": " 0 400   0   [[ $1 == -e* ]] && echo e\n 1 400   0   \n 2 400   0 + if [[ -d /usr/bin &&\n 0 401   0 | \t-e /usr/bin/bash ]]; then\n 0 401   0 | \techo find bash\n 0 401   0 | fi\n 1 400   0   \n 2 400   0 + if [[ -d /usr/bin &&\t-e /usr/bin/bash ]]; then\n 0 401   0 | \techo find bash\n 0 401   0 | fi\n 1 400   0   \n 2 400   0 + if [ -d /usr/bin && -e /usr/bin/bash ]; then\n 0 401   0 | \techo find bash\n 0 401   0 | fi\n 1 400   0   \n 2 400   0 + if [ -d /usr/bin &&\n 0 401   0 | \t-e /usr/bin/bash ]; then\n 0 401   0 | \techo find bash\n 0 401   0 | fi\n 1 400   0   \n 2 400   0 + if [ -d /usr/bin && \\\n 0 401   0 | \t-e /usr/bin/bash ]; then\n 0 401   0 | \techo find bash\n 0 401   0 | fi\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/203TestOption.bsh.styled",
    "content": "{7}[[{0} {9}$1{0} {7}=={0} {8}-e{7}*{0} {7}]]{0} {7}&&{0} {4}echo{0} {8}e{0}\n\n{4}if{0} {7}[[{0} {4}-d{0} {7}/{8}usr{7}/{8}bin{0} {7}&&{0}\n\t{4}-e{0} {7}/{8}usr{7}/{8}bin{7}/{8}bash{0} {7}]];{0} {4}then{0}\n\t{4}echo{0} {8}find{0} {8}bash{0}\n{4}fi{0}\n\n{4}if{0} {7}[[{0} {4}-d{0} {7}/{8}usr{7}/{8}bin{0} {7}&&{0}\t{4}-e{0} {7}/{8}usr{7}/{8}bin{7}/{8}bash{0} {7}]];{0} {4}then{0}\n\t{4}echo{0} {8}find{0} {8}bash{0}\n{4}fi{0}\n\n{4}if{0} {7}[{0} {4}-d{0} {7}/{8}usr{7}/{8}bin{0} {7}&&{0} {8}-e{0} {7}/{8}usr{7}/{8}bin{7}/{8}bash{0} {7}];{0} {4}then{0}\n\t{4}echo{0} {8}find{0} {8}bash{0}\n{4}fi{0}\n\n{4}if{0} {7}[{0} {4}-d{0} {7}/{8}usr{7}/{8}bin{0} {7}&&{0}\n\t{8}-e{0} {7}/{8}usr{7}/{8}bin{7}/{8}bash{0} {7}];{0} {4}then{0}\n\t{4}echo{0} {8}find{0} {8}bash{0}\n{4}fi{0}\n\n{4}if{0} {7}[{0} {4}-d{0} {7}/{8}usr{7}/{8}bin{0} {7}&&{0} {7}\\{0}\n\t{8}-e{0} {7}/{8}usr{7}/{8}bin{7}/{8}bash{0} {7}];{0} {4}then{0}\n\t{4}echo{0} {8}find{0} {8}bash{0}\n{4}fi{0}\n"
  },
  {
    "path": "test/examples/bash/257Delimiter.bsh",
    "content": "cat <<A\\\"\n$(echo 00)\nA\"\n\ncat <<A\\\\\\\"\n$(echo 01)\nA\\\"\n\ncat <<A\\B\n$(echo 1)\nAB\n\ncat <<A\\\\B\n$(echo 2)\nA\\B\n\ncat <<A\\\\\\B\n$(echo 3)\nA\\B\n\ncat <<A\\\\\\\\B\n$(echo 4)\nA\\\\B\n\ncat <<A\\\\\\\\\\B\n$(echo 5)\nA\\\\B\n\ncat <<'A\\'\n$(echo 10)\nA\\\n\ncat <<'A\\B'\n$(echo 11)\nA\\B\n\ncat <<'A\\\\B'\n$(echo 12)\nA\\\\B\n\ncat <<'A\\\\\\B'\n$(echo 13)\nA\\\\\\B\n\ncat <<'A\\\\\\\\B'\n$(echo 14)\nA\\\\\\\\B\n\ncat <<\"A\\\"\"\n$(echo 20)\nA\"\n\ncat <<\"A\\B\"\n$(echo 21)\nA\\B\n\ncat <<\"A\\\\B\"\n$(echo 22)\nA\\B\n\ncat <<\"A\\\\\\B\"\n$(echo 23)\nA\\\\B\n\ncat <<\"A\\\\\\\\B\"\n$(echo 24)\nA\\\\B\n\ncat <<\"A\\\\\\\\\\B\"\n$(echo 25)\nA\\\\\\B\n\necho x\n"
  },
  {
    "path": "test/examples/bash/257Delimiter.bsh.folded",
    "content": " 2 400   0 + cat <<A\\\"\n 0 401   0 | $(echo 00)\n 0 401   0 | A\"\n 1 400   0   \n 2 400   0 + cat <<A\\\\\\\"\n 0 401   0 | $(echo 01)\n 0 401   0 | A\\\"\n 1 400   0   \n 2 400   0 + cat <<A\\B\n 0 401   0 | $(echo 1)\n 0 401   0 | AB\n 1 400   0   \n 2 400   0 + cat <<A\\\\B\n 0 401   0 | $(echo 2)\n 0 401   0 | A\\B\n 1 400   0   \n 2 400   0 + cat <<A\\\\\\B\n 0 401   0 | $(echo 3)\n 0 401   0 | A\\B\n 1 400   0   \n 2 400   0 + cat <<A\\\\\\\\B\n 0 401   0 | $(echo 4)\n 0 401   0 | A\\\\B\n 1 400   0   \n 2 400   0 + cat <<A\\\\\\\\\\B\n 0 401   0 | $(echo 5)\n 0 401   0 | A\\\\B\n 1 400   0   \n 2 400   0 + cat <<'A\\'\n 0 401   0 | $(echo 10)\n 0 401   0 | A\\\n 1 400   0   \n 2 400   0 + cat <<'A\\B'\n 0 401   0 | $(echo 11)\n 0 401   0 | A\\B\n 1 400   0   \n 2 400   0 + cat <<'A\\\\B'\n 0 401   0 | $(echo 12)\n 0 401   0 | A\\\\B\n 1 400   0   \n 2 400   0 + cat <<'A\\\\\\B'\n 0 401   0 | $(echo 13)\n 0 401   0 | A\\\\\\B\n 1 400   0   \n 2 400   0 + cat <<'A\\\\\\\\B'\n 0 401   0 | $(echo 14)\n 0 401   0 | A\\\\\\\\B\n 1 400   0   \n 2 400   0 + cat <<\"A\\\"\"\n 0 401   0 | $(echo 20)\n 0 401   0 | A\"\n 1 400   0   \n 2 400   0 + cat <<\"A\\B\"\n 0 401   0 | $(echo 21)\n 0 401   0 | A\\B\n 1 400   0   \n 2 400   0 + cat <<\"A\\\\B\"\n 0 401   0 | $(echo 22)\n 0 401   0 | A\\B\n 1 400   0   \n 2 400   0 + cat <<\"A\\\\\\B\"\n 0 401   0 | $(echo 23)\n 0 401   0 | A\\\\B\n 1 400   0   \n 2 400   0 + cat <<\"A\\\\\\\\B\"\n 0 401   0 | $(echo 24)\n 0 401   0 | A\\\\B\n 1 400   0   \n 2 400   0 + cat <<\"A\\\\\\\\\\B\"\n 0 401   0 | $(echo 25)\n 0 401   0 | A\\\\\\B\n 1 400   0   \n 0 400   0   echo x\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/257Delimiter.bsh.styled",
    "content": "{4}cat{0} {12}<<A\\\"{13}\n$(echo 00)\n{12}A\"{0}\n\n{4}cat{0} {12}<<A\\\\\\\"{13}\n$(echo 01)\n{12}A\\\"{0}\n\n{4}cat{0} {12}<<A\\B{13}\n$(echo 1)\n{12}AB{0}\n\n{4}cat{0} {12}<<A\\\\B{13}\n$(echo 2)\n{12}A\\B{0}\n\n{4}cat{0} {12}<<A\\\\\\B{13}\n$(echo 3)\n{12}A\\B{0}\n\n{4}cat{0} {12}<<A\\\\\\\\B{13}\n$(echo 4)\n{12}A\\\\B{0}\n\n{4}cat{0} {12}<<A\\\\\\\\\\B{13}\n$(echo 5)\n{12}A\\\\B{0}\n\n{4}cat{0} {12}<<'A\\'{13}\n$(echo 10)\n{12}A\\{0}\n\n{4}cat{0} {12}<<'A\\B'{13}\n$(echo 11)\n{12}A\\B{0}\n\n{4}cat{0} {12}<<'A\\\\B'{13}\n$(echo 12)\n{12}A\\\\B{0}\n\n{4}cat{0} {12}<<'A\\\\\\B'{13}\n$(echo 13)\n{12}A\\\\\\B{0}\n\n{4}cat{0} {12}<<'A\\\\\\\\B'{13}\n$(echo 14)\n{12}A\\\\\\\\B{0}\n\n{4}cat{0} {12}<<\"A\\\"\"{13}\n$(echo 20)\n{12}A\"{0}\n\n{4}cat{0} {12}<<\"A\\B\"{13}\n$(echo 21)\n{12}A\\B{0}\n\n{4}cat{0} {12}<<\"A\\\\B\"{13}\n$(echo 22)\n{12}A\\B{0}\n\n{4}cat{0} {12}<<\"A\\\\\\B\"{13}\n$(echo 23)\n{12}A\\\\B{0}\n\n{4}cat{0} {12}<<\"A\\\\\\\\B\"{13}\n$(echo 24)\n{12}A\\\\B{0}\n\n{4}cat{0} {12}<<\"A\\\\\\\\\\B\"{13}\n$(echo 25)\n{12}A\\\\\\B{0}\n\n{4}echo{0} {8}x{0}\n"
  },
  {
    "path": "test/examples/bash/AllStyles.bsh",
    "content": "# Enumerate all styles: 0 to 13\n\n# comment=2\n\n# whitespace=0\n\t# w\n\n# error=1\n0#0000\n\n# number=3\n123\n\n# keyword=4\nset\n\n# double-quoted-string=5\n\"string\"\n\n# single-quoted-string=6\n'str'\n\n# operator=7\n+\n\n# identifier=8\nidentifier\n\n# scalar=9\n$scalar\n$?Status\n\n# parameter-expansion=10\n${parameter}\n\n# back-ticks=11\n`ls`\n\n# here-doc-delimiter=12, here-doc=13\n<<EOF\n  Here-doc.\nEOF\n\n# other quoted types are mapped to current classes\n\n# double-quoted-string=5\n$\"string\"\n$'str'\n\n# back-ticks=11\n`ls`\n$`ls`\n$(ls)\n\n# Use substyles\n\n# Substyled identifier=128\nmap\n\n# Substyled scalar=129\n$CWD\n"
  },
  {
    "path": "test/examples/bash/AllStyles.bsh.folded",
    "content": " 0 400   0   # Enumerate all styles: 0 to 13\n 1 400   0   \n 0 400   0   # comment=2\n 1 400   0   \n 2 400   0 + # whitespace=0\n 0 401   0 | \t# w\n 1 400   0   \n 0 400   0   # error=1\n 0 400   0   0#0000\n 1 400   0   \n 0 400   0   # number=3\n 0 400   0   123\n 1 400   0   \n 0 400   0   # keyword=4\n 0 400   0   set\n 1 400   0   \n 0 400   0   # double-quoted-string=5\n 0 400   0   \"string\"\n 1 400   0   \n 0 400   0   # single-quoted-string=6\n 0 400   0   'str'\n 1 400   0   \n 0 400   0   # operator=7\n 0 400   0   +\n 1 400   0   \n 0 400   0   # identifier=8\n 0 400   0   identifier\n 1 400   0   \n 0 400   0   # scalar=9\n 0 400   0   $scalar\n 0 400   0   $?Status\n 1 400   0   \n 0 400   0   # parameter-expansion=10\n 0 400   0   ${parameter}\n 1 400   0   \n 0 400   0   # back-ticks=11\n 0 400   0   `ls`\n 1 400   0   \n 0 400   0   # here-doc-delimiter=12, here-doc=13\n 2 400   0 + <<EOF\n 0 401   0 |   Here-doc.\n 0 401   0 | EOF\n 1 400   0   \n 0 400   0   # other quoted types are mapped to current classes\n 1 400   0   \n 0 400   0   # double-quoted-string=5\n 0 400   0   $\"string\"\n 0 400   0   $'str'\n 1 400   0   \n 0 400   0   # back-ticks=11\n 0 400   0   `ls`\n 0 400   0   $`ls`\n 0 400   0   $(ls)\n 1 400   0   \n 0 400   0   # Use substyles\n 1 400   0   \n 0 400   0   # Substyled identifier=128\n 0 400   0   map\n 1 400   0   \n 0 400   0   # Substyled scalar=129\n 0 400   0   $CWD\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/AllStyles.bsh.styled",
    "content": "{2}# Enumerate all styles: 0 to 13{0}\n\n{2}# comment=2{0}\n\n{2}# whitespace=0{0}\n\t{2}# w{0}\n\n{2}# error=1{0}\n{1}0#0000{0}\n\n{2}# number=3{0}\n{3}123{0}\n\n{2}# keyword=4{0}\n{4}set{0}\n\n{2}# double-quoted-string=5{0}\n{5}\"string\"{0}\n\n{2}# single-quoted-string=6{0}\n{6}'str'{0}\n\n{2}# operator=7{0}\n{7}+{0}\n\n{2}# identifier=8{0}\n{8}identifier{0}\n\n{2}# scalar=9{0}\n{9}$scalar{0}\n{9}$?{8}Status{0}\n\n{2}# parameter-expansion=10{0}\n{10}${parameter}{0}\n\n{2}# back-ticks=11{0}\n{11}`ls`{0}\n\n{2}# here-doc-delimiter=12, here-doc=13{0}\n{12}<<EOF{13}\n  Here-doc.\n{12}EOF{0}\n\n{2}# other quoted types are mapped to current classes{0}\n\n{2}# double-quoted-string=5{0}\n{5}$\"string\"{0}\n{5}$'str'{0}\n\n{2}# back-ticks=11{0}\n{11}`ls`{0}\n${11}`ls`{0}\n{11}$(ls){0}\n\n{2}# Use substyles{0}\n\n{2}# Substyled identifier=128{0}\n{128}map{0}\n\n{2}# Substyled scalar=129{0}\n{129}$CWD{0}\n"
  },
  {
    "path": "test/examples/bash/Issue180.bsh",
    "content": "echo '$'\necho \"$\"\necho \"$\"\necho \"$\"x\"\"\necho x$'\\t'y\necho \"x$'\\t'y\"\necho \"x\\ty\"\n"
  },
  {
    "path": "test/examples/bash/Issue180.bsh.folded",
    "content": " 0 400   0   echo '$'\n 0 400   0   echo \"$\"\n 0 400   0   echo \"$\"\n 0 400   0   echo \"$\"x\"\"\n 0 400   0   echo x$'\\t'y\n 0 400   0   echo \"x$'\\t'y\"\n 0 400   0   echo \"x\\ty\"\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/Issue180.bsh.styled",
    "content": "{4}echo{0} {6}'$'{0}\n{4}echo{0} {5}\"$\"{0}\n{4}echo{0} {5}\"$\"{0}\n{4}echo{0} {5}\"$\"{8}x{5}\"\"{0}\n{4}echo{0} {8}x{5}$'\\t'{8}y{0}\n{4}echo{0} {5}\"x$'\\t'y\"{0}\n{4}echo{0} {5}\"x\\ty\"{0}\n"
  },
  {
    "path": "test/examples/bash/Issue182.bsh",
    "content": "if [ -n \"$eth\" -o -n \"$wlan\" ]; then\nfi\n\ntest $((1 + 1)) -eq 2 && echo yes\n[ $((1 + 1)) -eq 2 ] && echo yes\n\nls -a --directory\n"
  },
  {
    "path": "test/examples/bash/Issue182.bsh.folded",
    "content": " 2 400   0 + if [ -n \"$eth\" -o -n \"$wlan\" ]; then\n 0 401   0 | fi\n 1 400   0   \n 0 400   0   test $((1 + 1)) -eq 2 && echo yes\n 0 400   0   [ $((1 + 1)) -eq 2 ] && echo yes\n 1 400   0   \n 0 400   0   ls -a --directory\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/Issue182.bsh.styled",
    "content": "{4}if{0} {7}[{0} {4}-n{0} {5}\"{9}$eth{5}\"{0} {4}-o{0} {4}-n{0} {5}\"{9}$wlan{5}\"{0} {7}];{0} {4}then{0}\n{4}fi{0}\n\n{4}test{0} {7}$(({3}1{0} {7}+{0} {3}1{7})){0} {4}-eq{0} {3}2{0} {7}&&{0} {4}echo{0} {8}yes{0}\n{7}[{0} {7}$(({3}1{0} {7}+{0} {3}1{7})){0} {4}-eq{0} {3}2{0} {7}]{0} {7}&&{0} {4}echo{0} {8}yes{0}\n\n{8}ls{0} {8}-a{0} {8}--directory{0}\n"
  },
  {
    "path": "test/examples/bash/Issue184.bsh",
    "content": "echo $*\necho $@\necho $?\necho $-\necho $$\necho $!\necho $_\necho $%\necho $<\n\nifeth=$(ls /sys/class/net | grep ^\"$intf\" | grep \"$intf\"$)\n"
  },
  {
    "path": "test/examples/bash/Issue184.bsh.folded",
    "content": " 0 400   0   echo $*\n 0 400   0   echo $@\n 0 400   0   echo $?\n 0 400   0   echo $-\n 0 400   0   echo $$\n 0 400   0   echo $!\n 0 400   0   echo $_\n 0 400   0   echo $%\n 0 400   0   echo $<\n 1 400   0   \n 0 400   0   ifeth=$(ls /sys/class/net | grep ^\"$intf\" | grep \"$intf\"$)\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/Issue184.bsh.styled",
    "content": "{4}echo{0} {9}$*{0}\n{4}echo{0} {9}$@{0}\n{4}echo{0} {9}$?{0}\n{4}echo{0} {9}$-{0}\n{4}echo{0} {9}$${0}\n{4}echo{0} {9}$!{0}\n{4}echo{0} {9}$_{0}\n{4}echo{0} ${7}%{0}\n{4}echo{0} ${7}<{0}\n\n{8}ifeth{7}=$({8}ls{0} {7}/{8}sys{7}/{8}class{7}/{8}net{0} {7}|{0} {8}grep{0} {7}^{5}\"{9}$intf{5}\"{0} {7}|{0} {8}grep{0} {5}\"{9}$intf{5}\"{0}${7}){0}\n"
  },
  {
    "path": "test/examples/bash/Issue184Copy.bsh",
    "content": "echo $*\necho $@\necho $?\necho $-\necho $$\necho $!\necho $_\necho $%\necho $<\n\nifeth=$(ls /sys/class/net | grep ^\"$intf\" | grep \"$intf\"$)\n"
  },
  {
    "path": "test/examples/bash/Issue184Copy.bsh.folded",
    "content": " 0 400   0   echo $*\n 0 400   0   echo $@\n 0 400   0   echo $?\n 0 400   0   echo $-\n 0 400   0   echo $$\n 0 400   0   echo $!\n 0 400   0   echo $_\n 0 400   0   echo $%\n 0 400   0   echo $<\n 1 400   0   \n 0 400   0   ifeth=$(ls /sys/class/net | grep ^\"$intf\" | grep \"$intf\"$)\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/Issue184Copy.bsh.styled",
    "content": "{4}echo{0} {9}$*{0}\n{4}echo{0} {9}$@{0}\n{4}echo{0} {9}$?{0}\n{4}echo{0} {9}$-{0}\n{4}echo{0} {9}$${0}\n{4}echo{0} {9}$!{0}\n{4}echo{0} {9}$_{0}\n{4}echo{0} {9}$%{0}\n{4}echo{0} {9}$<{0}\n\n{8}ifeth{7}=$({8}ls{0} {7}/{8}sys{7}/{8}class{7}/{8}net{0} {7}|{0} {8}grep{0} {7}^{5}\"{9}$intf{5}\"{0} {7}|{0} {8}grep{0} {5}\"{9}$intf{5}\"{0}${7}){0}\n"
  },
  {
    "path": "test/examples/bash/Nested.bsh",
    "content": "# Nested elements and other complex cases\n\n# String with backtick inclusion\n\"x`ls`\"\n# Nested string\n\"x`ls \"*.c\"`\"\n# Not terminated at first \"\n\"x`ls\" # \"`\" #\n\n# String with command inclusion\n\"x$(ls)\"\n\n# Nested command\n$(ls -la$(ls *.c))\n\n# Check strings and backticks in command\necho $('ls' \".\" `ls` $'.' $\".\")\n\n# $( not terminated by ) if contains unterminated string\n$('x) # ') #\n$(\"x) # \") #\n$(`x) # `) # Bash doesn't like this\n$($'x) # ') #\n$($\"x) # \") #\n\n# Parameter expansion\nvar=abcdef\nsub=abc\nrep='& '\necho ${var/$sub/\"${rep}}\"} #\n# issue 216\noption=\"no[foo]\"\noption=${option%%[<{().[]*}\necho $option\n\n# '$' in variable\necho $$PID\necho $var${var}\n\n# Here-doc with internal elements\ncat <<EOF\n\t$scalar\n\t${var}\n\t$((1+2))\n\t$(pwd)\n\t`pwd`\nEOF\n\n# Quoted delimiter treats here-doc as simple string\ncat <<\"EOF\"\n\t$scalar\n\t${var}\n\t$((1+2))\n\t$(pwd)\n\t`pwd`\nEOF\n\n# Escaped same as quoted\ncat <<\\EOF\n\t$scalar\nEOF\n\n# Nesting\necho \"$((1 + 2))\" #\necho \"$[1 + 2]\" #\n\n# Multiple nesting levels\n$(ls -la$(ls $(c) $'*.c' ` $(${s})`))\n\n# Multi-line\n$(ls |\nmore)\n\n$(\n`x`\n\"x\"\n`ls`\n$'x'\n$\"x\"\n)\n#end -- checks termination of previous\n"
  },
  {
    "path": "test/examples/bash/Nested.bsh.folded",
    "content": " 0 400   0   # Nested elements and other complex cases\n 1 400   0   \n 0 400   0   # String with backtick inclusion\n 0 400   0   \"x`ls`\"\n 0 400   0   # Nested string\n 0 400   0   \"x`ls \"*.c\"`\"\n 0 400   0   # Not terminated at first \"\n 0 400   0   \"x`ls\" # \"`\" #\n 1 400   0   \n 0 400   0   # String with command inclusion\n 0 400   0   \"x$(ls)\"\n 1 400   0   \n 0 400   0   # Nested command\n 0 400   0   $(ls -la$(ls *.c))\n 1 400   0   \n 0 400   0   # Check strings and backticks in command\n 0 400   0   echo $('ls' \".\" `ls` $'.' $\".\")\n 1 400   0   \n 0 400   0   # $( not terminated by ) if contains unterminated string\n 0 400   0   $('x) # ') #\n 0 400   0   $(\"x) # \") #\n 0 400   0   $(`x) # `) # Bash doesn't like this\n 0 400   0   $($'x) # ') #\n 0 400   0   $($\"x) # \") #\n 1 400   0   \n 0 400   0   # Parameter expansion\n 0 400   0   var=abcdef\n 0 400   0   sub=abc\n 0 400   0   rep='& '\n 0 400   0   echo ${var/$sub/\"${rep}}\"} #\n 0 400   0   # issue 216\n 0 400   0   option=\"no[foo]\"\n 0 400   0   option=${option%%[<{().[]*}\n 0 400   0   echo $option\n 1 400   0   \n 0 400   0   # '$' in variable\n 0 400   0   echo $$PID\n 0 400   0   echo $var${var}\n 1 400   0   \n 0 400   0   # Here-doc with internal elements\n 2 400   0 + cat <<EOF\n 0 401   0 | \t$scalar\n 0 401   0 | \t${var}\n 0 401   0 | \t$((1+2))\n 0 401   0 | \t$(pwd)\n 0 401   0 | \t`pwd`\n 0 401   0 | EOF\n 1 400   0   \n 0 400   0   # Quoted delimiter treats here-doc as simple string\n 2 400   0 + cat <<\"EOF\"\n 0 401   0 | \t$scalar\n 0 401   0 | \t${var}\n 0 401   0 | \t$((1+2))\n 0 401   0 | \t$(pwd)\n 0 401   0 | \t`pwd`\n 0 401   0 | EOF\n 1 400   0   \n 0 400   0   # Escaped same as quoted\n 2 400   0 + cat <<\\EOF\n 0 401   0 | \t$scalar\n 0 401   0 | EOF\n 1 400   0   \n 0 400   0   # Nesting\n 0 400   0   echo \"$((1 + 2))\" #\n 0 400   0   echo \"$[1 + 2]\" #\n 1 400   0   \n 0 400   0   # Multiple nesting levels\n 0 400   0   $(ls -la$(ls $(c) $'*.c' ` $(${s})`))\n 1 400   0   \n 0 400   0   # Multi-line\n 0 400   0   $(ls |\n 0 400   0   more)\n 1 400   0   \n 0 400   0   $(\n 0 400   0   `x`\n 0 400   0   \"x\"\n 0 400   0   `ls`\n 0 400   0   $'x'\n 0 400   0   $\"x\"\n 0 400   0   )\n 0 400   0   #end -- checks termination of previous\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/Nested.bsh.styled",
    "content": "{2}# Nested elements and other complex cases{0}\n\n{2}# String with backtick inclusion{0}\n{5}\"x`ls`\"{0}\n{2}# Nested string{0}\n{5}\"x`ls \"*.c\"`\"{0}\n{2}# Not terminated at first \"{0}\n{5}\"x`ls\" # \"`\"{0} {2}#{0}\n\n{2}# String with command inclusion{0}\n{5}\"x$(ls)\"{0}\n\n{2}# Nested command{0}\n{11}$(ls -la$(ls *.c)){0}\n\n{2}# Check strings and backticks in command{0}\n{4}echo{0} {11}$('ls' \".\" `ls` $'.' $\".\"){0}\n\n{2}# $( not terminated by ) if contains unterminated string{0}\n{11}$('x) # '){0} {2}#{0}\n{11}$(\"x) # \"){0} {2}#{0}\n{11}$(`x) # `){0} {2}# Bash doesn't like this{0}\n{11}$($'x) # '){0} {2}#{0}\n{11}$($\"x) # \"){0} {2}#{0}\n\n{2}# Parameter expansion{0}\n{8}var{7}={8}abcdef{0}\n{8}sub{7}={8}abc{0}\n{8}rep{7}={6}'& '{0}\n{4}echo{0} {10}${var/$sub/\"${rep}}\"}{0} {2}#{0}\n{2}# issue 216{0}\n{8}option{7}={5}\"no[foo]\"{0}\n{8}option{7}={10}${option%%[<{().[]*}{0}\n{4}echo{0} {9}$option{0}\n\n{2}# '$' in variable{0}\n{4}echo{0} {9}$${8}PID{0}\n{4}echo{0} {9}$var{10}${var}{0}\n\n{2}# Here-doc with internal elements{0}\n{4}cat{0} {12}<<EOF{13}\n\t$scalar\n\t${var}\n\t$((1+2))\n\t$(pwd)\n\t`pwd`\n{12}EOF{0}\n\n{2}# Quoted delimiter treats here-doc as simple string{0}\n{4}cat{0} {12}<<\"EOF\"{13}\n\t$scalar\n\t${var}\n\t$((1+2))\n\t$(pwd)\n\t`pwd`\n{12}EOF{0}\n\n{2}# Escaped same as quoted{0}\n{4}cat{0} {12}<<\\EOF{13}\n\t$scalar\n{12}EOF{0}\n\n{2}# Nesting{0}\n{4}echo{0} {5}\"$((1 + 2))\"{0} {2}#{0}\n{4}echo{0} {5}\"$[1 + 2]\"{0} {2}#{0}\n\n{2}# Multiple nesting levels{0}\n{11}$(ls -la$(ls $(c) $'*.c' ` $(${s})`)){0}\n\n{2}# Multi-line{0}\n{11}$(ls |\nmore){0}\n\n{11}$(\n`x`\n\"x\"\n`ls`\n$'x'\n$\"x\"\n){0}\n{2}#end -- checks termination of previous{0}\n"
  },
  {
    "path": "test/examples/bash/NestedRich.bsh",
    "content": "# Use lexer.bash.command.substitution=2 to style command substitution\n# so that both the scope of the command and the internal structure are visible.\n\n# Nested command\n$(ls -la$(ls *.c))\n\n# Check strings and backticks in command\necho $('ls' \".\" `ls` $'.' $\".\")\n\nPROJECT_DIR=$(rlwrap -S \"Enter source path: \" -e '' -i -o cat)\n\n# Multiple nesting levels\n$(ls -la$(ls $(c) $'*.c' ` $(${s})`))\n\n# Multi-line\n$(ls |\nmore)\n\n$(\n`x`\n\"x\"\n`ls`\n$'x'\n$\"x\"\n)\n#end -- checks termination of previous\n"
  },
  {
    "path": "test/examples/bash/NestedRich.bsh.folded",
    "content": " 2 400   0 + # Use lexer.bash.command.substitution=2 to style command substitution\n 0 401   0 | # so that both the scope of the command and the internal structure are visible.\n 1 400   0   \n 0 400   0   # Nested command\n 0 400   0   $(ls -la$(ls *.c))\n 1 400   0   \n 0 400   0   # Check strings and backticks in command\n 0 400   0   echo $('ls' \".\" `ls` $'.' $\".\")\n 1 400   0   \n 0 400   0   PROJECT_DIR=$(rlwrap -S \"Enter source path: \" -e '' -i -o cat)\n 1 400   0   \n 0 400   0   # Multiple nesting levels\n 0 400   0   $(ls -la$(ls $(c) $'*.c' ` $(${s})`))\n 1 400   0   \n 0 400   0   # Multi-line\n 0 400   0   $(ls |\n 0 400   0   more)\n 1 400   0   \n 0 400   0   $(\n 0 400   0   `x`\n 0 400   0   \"x\"\n 0 400   0   `ls`\n 0 400   0   $'x'\n 0 400   0   $\"x\"\n 0 400   0   )\n 0 400   0   #end -- checks termination of previous\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/NestedRich.bsh.styled",
    "content": "{2}# Use lexer.bash.command.substitution=2 to style command substitution{0}\n{2}# so that both the scope of the command and the internal structure are visible.{0}\n\n{2}# Nested command{0}\n{71}$({72}ls{64} {72}-la{71}$({72}ls{64} {71}*.{72}c{71})){0}\n\n{2}# Check strings and backticks in command{0}\n{4}echo{0} {71}$({70}'ls'{64} {69}\".\"{64} {75}`ls`{64} {69}$'.'{64} {69}$\".\"{71}){0}\n\n{8}PROJECT_DIR{7}={71}$({72}rlwrap{64} {72}-S{64} {69}\"Enter source path: \"{64} {72}-e{64} {70}''{64} {72}-i{64} {72}-o{64} {72}cat{71}){0}\n\n{2}# Multiple nesting levels{0}\n{71}$({72}ls{64} {72}-la{71}$({72}ls{64} {71}$({72}c{71}){64} {69}$'*.c'{64} {75}` $(${s})`{71})){0}\n\n{2}# Multi-line{0}\n{71}$({72}ls{64} {71}|{64}\n{72}more{71}){0}\n\n{71}$({64}\n{75}`x`{64}\n{69}\"x\"{64}\n{75}`ls`{64}\n{69}$'x'{64}\n{69}$\"x\"{64}\n{71}){0}\n{2}#end -- checks termination of previous{0}\n"
  },
  {
    "path": "test/examples/bash/NestedStyledInside.bsh",
    "content": "# Nested elements and other complex cases\n\n# String with backtick inclusion\n\"x`ls`\"\n# Nested string\n\"x`ls \"*.c\"`\"\n# Not terminated at first \"\n\"x`ls\" # \"`\" #\n\n# String with command inclusion\n\"x$(ls)\"\n\n# Nested command\n$(ls -la$(ls *.c))\n\n# Check strings and backticks in command\necho $('ls' \".\" `ls` $'.' $\".\")\n\n# $( not terminated by ) if contains unterminated string\n$('x) # ') #\n$(\"x) # \") #\n$(`x) # `) # Bash doesn't like this\n$($'x) # ') #\n$($\"x) # \") #\n\n# Parameter expansion\nvar=abcdef\nsub=abc\nrep='& '\necho ${var/$sub/\"${rep}}\"} #\n\n# '$' in variable\necho $$PID\necho $var${var}\n\n# Here-doc with internal elements\ncat <<EOF\n\t$scalar\n\t${var}\n\t$((1+2))\n\t$(pwd)\n\t`pwd`\nEOF\n\n# Quoted delimiter treats here-doc as simple string\ncat <<\"EOF\"\n\t$scalar\n\t${var}\n\t$((1+2))\n\t$(pwd)\n\t`pwd`\nEOF\n\n# Escaped same as quoted\ncat <<\\EOF\n\t$scalar\nEOF\n\n# Nesting\necho \"$((1 + 2))\" #\necho \"$[1 + 2]\" #\n\n# Multiple nesting levels\n$(ls -la$(ls $(c) $'*.c' ` $(${s})`))\n\n# Multi-line\n$(ls |\nmore)\n\n$(\n`x`\n\"x\"\n`ls`\n$'x'\n$\"x\"\n)\n#end -- checks termination of previous\n"
  },
  {
    "path": "test/examples/bash/NestedStyledInside.bsh.folded",
    "content": " 0 400   0   # Nested elements and other complex cases\n 1 400   0   \n 0 400   0   # String with backtick inclusion\n 0 400   0   \"x`ls`\"\n 0 400   0   # Nested string\n 0 400   0   \"x`ls \"*.c\"`\"\n 0 400   0   # Not terminated at first \"\n 0 400   0   \"x`ls\" # \"`\" #\n 1 400   0   \n 0 400   0   # String with command inclusion\n 0 400   0   \"x$(ls)\"\n 1 400   0   \n 0 400   0   # Nested command\n 0 400   0   $(ls -la$(ls *.c))\n 1 400   0   \n 0 400   0   # Check strings and backticks in command\n 0 400   0   echo $('ls' \".\" `ls` $'.' $\".\")\n 1 400   0   \n 0 400   0   # $( not terminated by ) if contains unterminated string\n 0 400   0   $('x) # ') #\n 0 400   0   $(\"x) # \") #\n 0 400   0   $(`x) # `) # Bash doesn't like this\n 0 400   0   $($'x) # ') #\n 0 400   0   $($\"x) # \") #\n 1 400   0   \n 0 400   0   # Parameter expansion\n 0 400   0   var=abcdef\n 0 400   0   sub=abc\n 0 400   0   rep='& '\n 0 400   0   echo ${var/$sub/\"${rep}}\"} #\n 1 400   0   \n 0 400   0   # '$' in variable\n 0 400   0   echo $$PID\n 0 400   0   echo $var${var}\n 1 400   0   \n 0 400   0   # Here-doc with internal elements\n 2 400   0 + cat <<EOF\n 0 401   0 | \t$scalar\n 0 401   0 | \t${var}\n 0 401   0 | \t$((1+2))\n 0 401   0 | \t$(pwd)\n 0 401   0 | \t`pwd`\n 0 401   0 | EOF\n 1 400   0   \n 0 400   0   # Quoted delimiter treats here-doc as simple string\n 2 400   0 + cat <<\"EOF\"\n 0 401   0 | \t$scalar\n 0 401   0 | \t${var}\n 0 401   0 | \t$((1+2))\n 0 401   0 | \t$(pwd)\n 0 401   0 | \t`pwd`\n 0 401   0 | EOF\n 1 400   0   \n 0 400   0   # Escaped same as quoted\n 2 400   0 + cat <<\\EOF\n 0 401   0 | \t$scalar\n 0 401   0 | EOF\n 1 400   0   \n 0 400   0   # Nesting\n 0 400   0   echo \"$((1 + 2))\" #\n 0 400   0   echo \"$[1 + 2]\" #\n 1 400   0   \n 0 400   0   # Multiple nesting levels\n 0 400   0   $(ls -la$(ls $(c) $'*.c' ` $(${s})`))\n 1 400   0   \n 0 400   0   # Multi-line\n 0 400   0   $(ls |\n 0 400   0   more)\n 1 400   0   \n 0 400   0   $(\n 0 400   0   `x`\n 0 400   0   \"x\"\n 0 400   0   `ls`\n 0 400   0   $'x'\n 0 400   0   $\"x\"\n 0 400   0   )\n 0 400   0   #end -- checks termination of previous\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/NestedStyledInside.bsh.styled",
    "content": "{2}# Nested elements and other complex cases{0}\n\n{2}# String with backtick inclusion{0}\n{5}\"x{11}`ls`{5}\"{0}\n{2}# Nested string{0}\n{5}\"x{11}`ls {5}\"*.c\"{11}`{5}\"{0}\n{2}# Not terminated at first \"{0}\n{5}\"x{11}`ls{5}\" # \"{11}`{5}\"{0} {2}#{0}\n\n{2}# String with command inclusion{0}\n{5}\"x{7}$({8}ls{7}){5}\"{0}\n\n{2}# Nested command{0}\n{7}$({8}ls{0} {8}-la{7}$({8}ls{0} {7}*.{8}c{7})){0}\n\n{2}# Check strings and backticks in command{0}\n{4}echo{0} {7}$({6}'ls'{0} {5}\".\"{0} {11}`ls`{0} {5}$'.'{0} {5}$\".\"{7}){0}\n\n{2}# $( not terminated by ) if contains unterminated string{0}\n{7}$({6}'x) # '{7}){0} {2}#{0}\n{7}$({5}\"x) # \"{7}){0} {2}#{0}\n{7}$({11}`x) # `{7}){0} {2}# Bash doesn't like this{0}\n{7}$({5}$'x) # '{7}){0} {2}#{0}\n{7}$({5}$\"x) # \"{7}){0} {2}#{0}\n\n{2}# Parameter expansion{0}\n{8}var{7}={8}abcdef{0}\n{8}sub{7}={8}abc{0}\n{8}rep{7}={6}'& '{0}\n{4}echo{0} {10}${var/{9}$sub{10}/{5}\"{10}${rep}{5}}\"{10}}{0} {2}#{0}\n\n{2}# '$' in variable{0}\n{4}echo{0} {9}$${8}PID{0}\n{4}echo{0} {9}$var{10}${var}{0}\n\n{2}# Here-doc with internal elements{0}\n{4}cat{0} {12}<<EOF{13}\n\t{9}$scalar{13}\n\t{10}${var}{13}\n\t{7}$(({3}1{7}+{3}2{7})){13}\n\t{7}$({4}pwd{7}){13}\n\t{11}`pwd`{13}\n{12}EOF{0}\n\n{2}# Quoted delimiter treats here-doc as simple string{0}\n{4}cat{0} {12}<<\"EOF\"{13}\n\t$scalar\n\t${var}\n\t$((1+2))\n\t$(pwd)\n\t`pwd`\n{12}EOF{0}\n\n{2}# Escaped same as quoted{0}\n{4}cat{0} {12}<<\\EOF{13}\n\t$scalar\n{12}EOF{0}\n\n{2}# Nesting{0}\n{4}echo{0} {5}\"{7}$(({3}1{0} {7}+{0} {3}2{7})){5}\"{0} {2}#{0}\n{4}echo{0} {5}\"{7}$[{3}1{0} {7}+{0} {3}2{7}]{5}\"{0} {2}#{0}\n\n{2}# Multiple nesting levels{0}\n{7}$({8}ls{0} {8}-la{7}$({8}ls{0} {7}$({8}c{7}){0} {5}$'*.c'{0} {11}` {7}$({10}${s}{7}){11}`{7})){0}\n\n{2}# Multi-line{0}\n{7}$({8}ls{0} {7}|{0}\n{8}more{7}){0}\n\n{7}$({0}\n{11}`x`{0}\n{5}\"x\"{0}\n{11}`ls`{0}\n{5}$'x'{0}\n{5}$\"x\"{0}\n{7}){0}\n{2}#end -- checks termination of previous{0}\n"
  },
  {
    "path": "test/examples/bash/SciTE.properties",
    "content": "lexer.*.bsh;*.zsh=bash\nfold=1\nfold.comment=1\nkeywords.*.bsh;*.zsh=case cat do done echo else esac exit export fi find for if in print pwd set setopt then while\n\n# Can use substyles for identifiers and scalars\nsubstyles.bash.8=1\nsubstylewords.8.1.*.bsh=map\nsubstyles.bash.9=1\nsubstylewords.9.1.*.bsh=CWD\n\nlexer.bash.styling.inside.string=0\nlexer.bash.styling.inside.backticks=0\nlexer.bash.styling.inside.parameter=0\nlexer.bash.styling.inside.heredoc=0\nlexer.bash.command.substitution=0\n\nmatch Issue180.bsh\n\tlexer.bash.styling.inside.string=1\n\nmatch Issue182.bsh\n\tlexer.bash.styling.inside.string=1\n\nmatch Issue184.bsh\n\tlexer.bash.styling.inside.string=1\n\tlexer.bash.command.substitution=1\n\nmatch Issue184Copy.bsh\n\tlexer.bash.styling.inside.string=1\n\tlexer.bash.command.substitution=1\n\tlexer.bash.special.parameter=*@#?-$!%<\n\nmatch NestedStyledInside.bsh\n\tlexer.bash.styling.inside.string=1\n\tlexer.bash.styling.inside.backticks=1\n\tlexer.bash.styling.inside.parameter=1\n\tlexer.bash.styling.inside.heredoc=1\n\tlexer.bash.command.substitution=1\n\nmatch NestedRich.bsh\n\tlexer.bash.command.substitution=2\n"
  },
  {
    "path": "test/examples/bash/continuation.bsh",
    "content": "# Tests for line continuation.\n# Issue #195.\n\n#backslash1\\\necho 1\n#backslash2\\\\\necho 2\n\nif [ 1 ]; then\n    backslash1=A\\\nfi\n    backslash2=B\\\\\nfi\n\necho $backslash1, $backslash2\n"
  },
  {
    "path": "test/examples/bash/continuation.bsh.folded",
    "content": " 2 400   0 + # Tests for line continuation.\n 0 401   0 | # Issue #195.\n 1 400   0   \n 0 400   0   #backslash1\\\n 0 400   0   echo 1\n 0 400   0   #backslash2\\\\\n 0 400   0   echo 2\n 1 400   0   \n 2 400   0 + if [ 1 ]; then\n 0 401   0 |     backslash1=A\\\n 0 401   0 | fi\n 0 401   0 |     backslash2=B\\\\\n 0 401   0 | fi\n 1 400   0   \n 0 400   0   echo $backslash1, $backslash2\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/continuation.bsh.styled",
    "content": "{2}# Tests for line continuation.{0}\n{2}# Issue #195.{0}\n\n{2}#backslash1\\{0}\n{4}echo{0} {3}1{0}\n{2}#backslash2\\\\{0}\n{4}echo{0} {3}2{0}\n\n{4}if{0} {7}[{0} {3}1{0} {7}];{0} {4}then{0}\n    {8}backslash1{7}={8}A{7}\\{0}\n{8}fi{0}\n    {8}backslash2{7}={8}B\\\\{0}\n{4}fi{0}\n\n{4}echo{0} {9}$backslash1{7},{0} {9}$backslash2{0}\n"
  },
  {
    "path": "test/examples/bash/hash.zsh",
    "content": "#!/bin/zsh\n# Tests for zsh extensions\n# Can be executed by zsh with reasonable results\n# Some of these were implemented by commit [87286d] for Scintilla bug #1794\n# https://zsh.sourceforge.io/Doc/Release/Expansion.html\n\n# Where # does not start a comment\n\n\n## Formatting base\nprint $(( [#8] y = 33 ))\nprint $(( [##8] 32767 ))\n\n# Formatting base and grouping\nprint $(( [#16_4] 65536 ** 2 ))\n\n\n## Character values\nprint $(( ##T+0 ))\nprint $(( ##^G+0 ))\n# Failure: does not work when - included for bindkey syntax. \\M-\\C-x means Meta+Ctrl+x.\nprint $(( ##\\M-\\C-x+0 ))\n\n# Value of first character of variable in expression\nvar=Tree\nprint $(( #var+0 ))\n\n\n## Extended glob\nsetopt extended_glob\n\n# # is similar to *, ## similar to +\necho [A-Za-z]#.bsh\necho [A-Za-z]##.bsh\n\n# 13 character file names\necho **/[a-zA-Z.](#c13)\n# 13-15 character file names\necho **/[a-zA-Z.](#c13,15)\n\n\n## Glob flag\n\n# i=case-insensitive\necho (#i)a*\n\n# b=back-references\nfoo=\"a_string_with_a_message\"\nif [[ $foo = (a|an)_(#b)(*) ]]; then\n  print ${foo[$mbegin[1],$mend[1]]}\nfi\n"
  },
  {
    "path": "test/examples/bash/hash.zsh.folded",
    "content": " 2 400   0 + #!/bin/zsh\n 0 401   0 | # Tests for zsh extensions\n 0 401   0 | # Can be executed by zsh with reasonable results\n 0 401   0 | # Some of these were implemented by commit [87286d] for Scintilla bug #1794\n 0 401   0 | # https://zsh.sourceforge.io/Doc/Release/Expansion.html\n 1 400   0   \n 0 400   0   # Where # does not start a comment\n 1 400   0   \n 1 400   0   \n 0 400   0   ## Formatting base\n 0 400   0   print $(( [#8] y = 33 ))\n 0 400   0   print $(( [##8] 32767 ))\n 1 400   0   \n 0 400   0   # Formatting base and grouping\n 0 400   0   print $(( [#16_4] 65536 ** 2 ))\n 1 400   0   \n 1 400   0   \n 0 400   0   ## Character values\n 0 400   0   print $(( ##T+0 ))\n 0 400   0   print $(( ##^G+0 ))\n 0 400   0   # Failure: does not work when - included for bindkey syntax. \\M-\\C-x means Meta+Ctrl+x.\n 0 400   0   print $(( ##\\M-\\C-x+0 ))\n 1 400   0   \n 0 400   0   # Value of first character of variable in expression\n 0 400   0   var=Tree\n 0 400   0   print $(( #var+0 ))\n 1 400   0   \n 1 400   0   \n 0 400   0   ## Extended glob\n 0 400   0   setopt extended_glob\n 1 400   0   \n 0 400   0   # # is similar to *, ## similar to +\n 0 400   0   echo [A-Za-z]#.bsh\n 0 400   0   echo [A-Za-z]##.bsh\n 1 400   0   \n 0 400   0   # 13 character file names\n 0 400   0   echo **/[a-zA-Z.](#c13)\n 0 400   0   # 13-15 character file names\n 0 400   0   echo **/[a-zA-Z.](#c13,15)\n 1 400   0   \n 1 400   0   \n 0 400   0   ## Glob flag\n 1 400   0   \n 0 400   0   # i=case-insensitive\n 0 400   0   echo (#i)a*\n 1 400   0   \n 0 400   0   # b=back-references\n 0 400   0   foo=\"a_string_with_a_message\"\n 2 400   0 + if [[ $foo = (a|an)_(#b)(*) ]]; then\n 0 401   0 |   print ${foo[$mbegin[1],$mend[1]]}\n 0 401   0 | fi\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/hash.zsh.styled",
    "content": "{2}#!/bin/zsh{0}\n{2}# Tests for zsh extensions{0}\n{2}# Can be executed by zsh with reasonable results{0}\n{2}# Some of these were implemented by commit [87286d] for Scintilla bug #1794{0}\n{2}# https://zsh.sourceforge.io/Doc/Release/Expansion.html{0}\n\n{2}# Where # does not start a comment{0}\n\n\n{2}## Formatting base{0}\n{4}print{0} {7}$(({0} {7}[{8}#8{7}]{0} {8}y{0} {7}={0} {3}33{0} {7})){0}\n{4}print{0} {7}$(({0} {7}[{8}##8{7}]{0} {3}32767{0} {7})){0}\n\n{2}# Formatting base and grouping{0}\n{4}print{0} {7}$(({0} {7}[{8}#16_4{7}]{0} {3}65536{0} {7}**{0} {3}2{0} {7})){0}\n\n\n{2}## Character values{0}\n{4}print{0} {7}$(({0} {8}##T{7}+{3}0{0} {7})){0}\n{4}print{0} {7}$(({0} {8}##^G{7}+{3}0{0} {7})){0}\n{2}# Failure: does not work when - included for bindkey syntax. \\M-\\C-x means Meta+Ctrl+x.{0}\n{4}print{0} {7}$(({0} {8}##\\M{7}-{8}\\C{7}-{8}x{7}+{3}0{0} {7})){0}\n\n{2}# Value of first character of variable in expression{0}\n{8}var{7}={8}Tree{0}\n{4}print{0} {7}$(({0} {8}#var{7}+{3}0{0} {7})){0}\n\n\n{2}## Extended glob{0}\n{4}setopt{0} {8}extended_glob{0}\n\n{2}# # is similar to *, ## similar to +{0}\n{4}echo{0} {7}[{8}A-Za-z{7}]{8}#.bsh{0}\n{4}echo{0} {7}[{8}A-Za-z{7}]{8}##.bsh{0}\n\n{2}# 13 character file names{0}\n{4}echo{0} {7}**/[{8}a-zA-Z.{7}]{8}(#c13){0}\n{2}# 13-15 character file names{0}\n{4}echo{0} {7}**/[{8}a-zA-Z.{7}]{8}(#c13,15){0}\n\n\n{2}## Glob flag{0}\n\n{2}# i=case-insensitive{0}\n{4}echo{0} {8}(#i)a{7}*{0}\n\n{2}# b=back-references{0}\n{8}foo{7}={5}\"a_string_with_a_message\"{0}\n{4}if{0} {7}[[{0} {9}$foo{0} {7}={0} {7}({8}a{7}|{8}an{7}){8}_(#b){7}(*){0} {7}]];{0} {4}then{0}\n  {4}print{0} {10}${foo[$mbegin[1],$mend[1]]}{0}\n{4}fi{0}\n"
  },
  {
    "path": "test/examples/bash/x.bsh",
    "content": "#!/usr/bin/env bash\nset -e\n# -----------------------------------------------------------------------------\n# Voluptatem dolore magnam eius quisquam eius dolor labore. Porro dolor amet ut.\n# Numquam labore amet modi. Dolorem velit numquam porro est quiquia ipsum quisquam.\n# Magnam consectetur est voluptatem aliquam adipisci. Sed dolorem quaerat quiquia.\n# -----------------------------------------------------------------------------\nexport PYTHONPATH=\"scripts:$PYTHONPATH\"\n\nif [[ -z \"$1\" ]]; then\n  PROJECT_DIR=$(rlwrap -S \"Enter source path: \" -e '' -i -o cat)\n  PROJECT_PATH=\"$(pwd)/$PROJECT_DIR\"\nelse\n  PROJECT_PATH=\"$(pwd)/${1}\"\nfi\n\nOUT_FILE=${PROJECT_PATH}/testing.txt\n\n(cat<<EOF\n  Last run $(date +'%Y-%m-%d') at $(date +'%H:%M:%S.%2N')\nEOF\n) > $OUT_FILE\n\n# Issue 188, keyword before redirection operator\npwd>>$OUT_FILE\n\nfind \"$PROJECT_PATH/src\" -maxdepth 1 -type f |\\\nwhile read -r f; do\n  {\n    python3 -c \"print();print('='*50)\";\\\n    echo `basename \"$f\"` | tr -d 'x';\\\n    python3 -c \"print('='*50)\";\\\n    python3 \"$f\";\\\n  } >> $OUT_FILE\ndone\n\n# Issue 137, should be shift but here-doc was detected\necho $(( x << END ))\npwd\nEND\n\n# Issue 194, failed to understand character escaping so string unterminated\necho \"foo `echo foo \\\\\" bar` bar\"\necho \"xinput set-prop bla \\\"blub\\\" `grep bla $WRITE_APPENDIX/var/lib/path.txt | cut -d \\\\\" -f 4`\" >/some_file.sh\n\n# Issue 194, $ before end of backticks is literal\necho `echo \\$`\necho `echo \\$bar\\$`\necho `echo $`\necho `echo $bar$`\n\nINVALID_NUMBER=0#0000\n"
  },
  {
    "path": "test/examples/bash/x.bsh.folded",
    "content": " 0 400   0   #!/usr/bin/env bash\n 0 400   0   set -e\n 2 400   0 + # -----------------------------------------------------------------------------\n 0 401   0 | # Voluptatem dolore magnam eius quisquam eius dolor labore. Porro dolor amet ut.\n 0 401   0 | # Numquam labore amet modi. Dolorem velit numquam porro est quiquia ipsum quisquam.\n 0 401   0 | # Magnam consectetur est voluptatem aliquam adipisci. Sed dolorem quaerat quiquia.\n 0 401   0 | # -----------------------------------------------------------------------------\n 0 400   0   export PYTHONPATH=\"scripts:$PYTHONPATH\"\n 1 400   0   \n 2 400   0 + if [[ -z \"$1\" ]]; then\n 0 401   0 |   PROJECT_DIR=$(rlwrap -S \"Enter source path: \" -e '' -i -o cat)\n 0 401   0 |   PROJECT_PATH=\"$(pwd)/$PROJECT_DIR\"\n 0 401   0 | else\n 0 401   0 |   PROJECT_PATH=\"$(pwd)/${1}\"\n 0 401   0 | fi\n 1 400   0   \n 0 400   0   OUT_FILE=${PROJECT_PATH}/testing.txt\n 1 400   0   \n 2 400   0 + (cat<<EOF\n 0 401   0 |   Last run $(date +'%Y-%m-%d') at $(date +'%H:%M:%S.%2N')\n 0 401   0 | EOF\n 0 400   0   ) > $OUT_FILE\n 1 400   0   \n 0 400   0   # Issue 188, keyword before redirection operator\n 0 400   0   pwd>>$OUT_FILE\n 1 400   0   \n 0 400   0   find \"$PROJECT_PATH/src\" -maxdepth 1 -type f |\\\n 2 400   0 + while read -r f; do\n 2 401   0 +   {\n 0 402   0 |     python3 -c \"print();print('='*50)\";\\\n 0 402   0 |     echo `basename \"$f\"` | tr -d 'x';\\\n 0 402   0 |     python3 -c \"print('='*50)\";\\\n 0 402   0 |     python3 \"$f\";\\\n 0 402   0 |   } >> $OUT_FILE\n 0 401   0 | done\n 1 400   0   \n 0 400   0   # Issue 137, should be shift but here-doc was detected\n 0 400   0   echo $(( x << END ))\n 0 400   0   pwd\n 0 400   0   END\n 1 400   0   \n 0 400   0   # Issue 194, failed to understand character escaping so string unterminated\n 0 400   0   echo \"foo `echo foo \\\\\" bar` bar\"\n 0 400   0   echo \"xinput set-prop bla \\\"blub\\\" `grep bla $WRITE_APPENDIX/var/lib/path.txt | cut -d \\\\\" -f 4`\" >/some_file.sh\n 1 400   0   \n 0 400   0   # Issue 194, $ before end of backticks is literal\n 0 400   0   echo `echo \\$`\n 0 400   0   echo `echo \\$bar\\$`\n 0 400   0   echo `echo $`\n 0 400   0   echo `echo $bar$`\n 1 400   0   \n 0 400   0   INVALID_NUMBER=0#0000\n 0 400   0   "
  },
  {
    "path": "test/examples/bash/x.bsh.styled",
    "content": "{2}#!/usr/bin/env bash{0}\n{4}set{0} {8}-e{0}\n{2}# -----------------------------------------------------------------------------{0}\n{2}# Voluptatem dolore magnam eius quisquam eius dolor labore. Porro dolor amet ut.{0}\n{2}# Numquam labore amet modi. Dolorem velit numquam porro est quiquia ipsum quisquam.{0}\n{2}# Magnam consectetur est voluptatem aliquam adipisci. Sed dolorem quaerat quiquia.{0}\n{2}# -----------------------------------------------------------------------------{0}\n{4}export{0} {8}PYTHONPATH{7}={5}\"scripts:$PYTHONPATH\"{0}\n\n{4}if{0} {7}[[{0} {4}-z{0} {5}\"$1\"{0} {7}]];{0} {4}then{0}\n  {8}PROJECT_DIR{7}={11}$(rlwrap -S \"Enter source path: \" -e '' -i -o cat){0}\n  {8}PROJECT_PATH{7}={5}\"$(pwd)/$PROJECT_DIR\"{0}\n{4}else{0}\n  {8}PROJECT_PATH{7}={5}\"$(pwd)/${1}\"{0}\n{4}fi{0}\n\n{8}OUT_FILE{7}={10}${PROJECT_PATH}{7}/{8}testing.txt{0}\n\n{7}({4}cat{12}<<EOF{13}\n  Last run $(date +'%Y-%m-%d') at $(date +'%H:%M:%S.%2N')\n{12}EOF{0}\n{7}){0} {7}>{0} {9}$OUT_FILE{0}\n\n{2}# Issue 188, keyword before redirection operator{0}\n{4}pwd{7}>>{9}$OUT_FILE{0}\n\n{4}find{0} {5}\"$PROJECT_PATH/src\"{0} {8}-maxdepth{0} {3}1{0} {8}-type{0} {8}f{0} {7}|\\{0}\n{4}while{0} {8}read{0} {8}-r{0} {8}f{7};{0} {4}do{0}\n  {7}{{0}\n    {8}python3{0} {8}-c{0} {5}\"print();print('='*50)\"{7};\\{0}\n    {4}echo{0} {11}`basename \"$f\"`{0} {7}|{0} {8}tr{0} {8}-d{0} {6}'x'{7};\\{0}\n    {8}python3{0} {8}-c{0} {5}\"print('='*50)\"{7};\\{0}\n    {8}python3{0} {5}\"$f\"{7};\\{0}\n  {7}}{0} {7}>>{0} {9}$OUT_FILE{0}\n{4}done{0}\n\n{2}# Issue 137, should be shift but here-doc was detected{0}\n{4}echo{0} {7}$(({0} {8}x{0} {7}<<{0} {8}END{0} {7})){0}\n{4}pwd{0}\n{8}END{0}\n\n{2}# Issue 194, failed to understand character escaping so string unterminated{0}\n{4}echo{0} {5}\"foo `echo foo \\\\\" bar` bar\"{0}\n{4}echo{0} {5}\"xinput set-prop bla \\\"blub\\\" `grep bla $WRITE_APPENDIX/var/lib/path.txt | cut -d \\\\\" -f 4`\"{0} {7}>/{8}some_file.sh{0}\n\n{2}# Issue 194, $ before end of backticks is literal{0}\n{4}echo{0} {11}`echo \\$`{0}\n{4}echo{0} {11}`echo \\$bar\\$`{0}\n{4}echo{0} {11}`echo $`{0}\n{4}echo{0} {11}`echo $bar$`{0}\n\n{8}INVALID_NUMBER{7}={1}0#0000{0}\n"
  },
  {
    "path": "test/examples/batch/Issue115.bat",
    "content": "rem remark and comment bug\n\nfindstr /c:\"rem this\" \"file\"\nfindstr /c:\":: this\" \"file\"\n\n:: SingleQuoted command string\nfor /f %%A in ('rem this') do echo %%A\n\n:: DoubleQuoted string\nfor /f %%A in (\"rem this\") do echo %%A\n\n:: BackQuote command string\nfor /f \"usebackq\" %%A in (`rem this`) do echo %%A\n\n:: Test the handling of quotes ' and \" and escape ^\n:: Comment\n\n:: With quotes\n\":: Text\n\"\":: Comment\n':: Text\n'':: Comment\n:: Mixing quotes - likely incorrect as lexer tries ' and \" separately, leaving an active quote\n\"'\":: Text\n\n:: With escapes\n^:: Text\n^\":: Comment\n^\"\":: Text\n^\"\"\":: Comment\n^^\":: Text\n^^\"\":: Comment\n^^\"\"\":: Text\n\n:: With preceding command\nmkdir archive \":: Text\nmkdir archive \"\":: Comment\nmkdir archive ^\":: Comment\nmkdir archive ^\"\":: Text\n"
  },
  {
    "path": "test/examples/batch/Issue115.bat.folded",
    "content": " 0 400   0   rem remark and comment bug\n 0 400   0   \n 0 400   0   findstr /c:\"rem this\" \"file\"\n 0 400   0   findstr /c:\":: this\" \"file\"\n 0 400   0   \n 0 400   0   :: SingleQuoted command string\n 0 400   0   for /f %%A in ('rem this') do echo %%A\n 0 400   0   \n 0 400   0   :: DoubleQuoted string\n 0 400   0   for /f %%A in (\"rem this\") do echo %%A\n 0 400   0   \n 0 400   0   :: BackQuote command string\n 0 400   0   for /f \"usebackq\" %%A in (`rem this`) do echo %%A\n 0 400   0   \n 0 400   0   :: Test the handling of quotes ' and \" and escape ^\n 0 400   0   :: Comment\n 0 400   0   \n 0 400   0   :: With quotes\n 0 400   0   \":: Text\n 0 400   0   \"\":: Comment\n 0 400   0   ':: Text\n 0 400   0   '':: Comment\n 0 400   0   :: Mixing quotes - likely incorrect as lexer tries ' and \" separately, leaving an active quote\n 0 400   0   \"'\":: Text\n 0 400   0   \n 0 400   0   :: With escapes\n 0 400   0   ^:: Text\n 0 400   0   ^\":: Comment\n 0 400   0   ^\"\":: Text\n 0 400   0   ^\"\"\":: Comment\n 0 400   0   ^^\":: Text\n 0 400   0   ^^\"\":: Comment\n 0 400   0   ^^\"\"\":: Text\n 0 400   0   \n 0 400   0   :: With preceding command\n 0 400   0   mkdir archive \":: Text\n 0 400   0   mkdir archive \"\":: Comment\n 0 400   0   mkdir archive ^\":: Comment\n 0 400   0   mkdir archive ^\"\":: Text\n 0 400   0   "
  },
  {
    "path": "test/examples/batch/Issue115.bat.styled",
    "content": "{1}rem remark and comment bug\n{0}\n{5}findstr{0} /c:\"rem this\" \"file\"\n{5}findstr{0} /c:\":: this\" \"file\"\n\n{1}:: SingleQuoted command string\n{2}for{0} /f {6}%%A{2} in{0} ('rem this'){2} do echo{0} {6}%%A{0}\n\n{1}:: DoubleQuoted string\n{2}for{0} /f {6}%%A{2} in{0} (\"rem this\"){2} do echo{0} {6}%%A{0}\n\n{1}:: BackQuote command string\n{2}for{0} /f \"usebackq\" {6}%%A{2} in{0} (`rem this`){2} do echo{0} {6}%%A{0}\n\n{1}:: Test the handling of quotes ' and \" and escape ^\n:: Comment\n{0}\n{1}:: With quotes\n{0}\":: Text\n\"\"{1}:: Comment\n{0}':: Text\n''{1}:: Comment\n:: Mixing quotes - likely incorrect as lexer tries ' and \" separately, leaving an active quote\n{0}\"'\":: Text\n\n{1}:: With escapes\n{5}^::{0} Text\n{5}^{0}\"{1}:: Comment\n{5}^{0}\"\":: Text\n{5}^{0}\"\"\"{1}:: Comment\n{5}^^{0}\":: Text\n{5}^^{0}\"\"{1}:: Comment\n{5}^^{0}\"\"\":: Text\n\n{1}:: With preceding command\n{5}mkdir{0} archive \":: Text\n{5}mkdir{0} archive \"\"{1}:: Comment\n{5}mkdir{0} archive ^\"{1}:: Comment\n{5}mkdir{0} archive ^\"\":: Text\n"
  },
  {
    "path": "test/examples/batch/Issue222.bat",
    "content": "rem Keywords with colon\n\nrem with spacing\ncall file.bat arg1\ncall \"file.bat\" arg1\ncall :label arg1\ngoto :label\ngoto :eof\ngoto label\necho: %var%\necho: text\necho text\n\nrem no spacing\ncall:label arg1\ngoto:label\ngoto:eof\necho:%var%\necho:text\n(call)\n(echo:)\n(goto)\n\nrem call internal commands\ncall echo text\ncall set \"a=b\"\n"
  },
  {
    "path": "test/examples/batch/Issue222.bat.folded",
    "content": " 0 400   0   rem Keywords with colon\n 0 400   0   \n 0 400   0   rem with spacing\n 0 400   0   call file.bat arg1\n 0 400   0   call \"file.bat\" arg1\n 0 400   0   call :label arg1\n 0 400   0   goto :label\n 0 400   0   goto :eof\n 0 400   0   goto label\n 0 400   0   echo: %var%\n 0 400   0   echo: text\n 0 400   0   echo text\n 0 400   0   \n 0 400   0   rem no spacing\n 0 400   0   call:label arg1\n 0 400   0   goto:label\n 0 400   0   goto:eof\n 0 400   0   echo:%var%\n 0 400   0   echo:text\n 0 400   0   (call)\n 0 400   0   (echo:)\n 0 400   0   (goto)\n 0 400   0   \n 0 400   0   rem call internal commands\n 0 400   0   call echo text\n 0 400   0   call set \"a=b\"\n 0 400   0   "
  },
  {
    "path": "test/examples/batch/Issue222.bat.styled",
    "content": "{1}rem Keywords with colon\n{0}\n{1}rem with spacing\n{2}call{5} file.bat{0} arg1\n{2}call{0} \"file.bat\" arg1\n{2}call{0} :label arg1\n{2}goto{0} :label\n{2}goto{0} :eof\n{2}goto{0} label\n{2}echo{0}: {6}%var%{0}\n{2}echo{0}: text\n{2}echo{0} text\n\n{1}rem no spacing\n{2}call{0}:label arg1\n{2}goto{0}:label\n{2}goto{0}:eof\n{2}echo{0}:{6}%var%{0}\n{2}echo{0}:text\n({2}call{0})\n({2}echo{0}:)\n({2}goto{0})\n\n{1}rem call internal commands\n{2}call echo{0} text\n{2}call set{0} \"a=b\"\n"
  },
  {
    "path": "test/examples/batch/SciTE.properties",
    "content": "lexer.*.bat=batch\nkeywords.*.bat=call defined do echo else errorlevel exist exit for goto if in not set\n\n"
  },
  {
    "path": "test/examples/batch/x.bat",
    "content": "rem comment=1\nrem 'echo' is word=2, 'a' is default=0\necho a\nrem label=3\n:START\nrem '@' is hide=4\n@echo b\nrem 'gcc' is external command=5\ngcc --version\nrem '%PATH%' is variable=6\necho %PATH%\necho %ProgramFiles(x86)%\nrem operator=7 '='\n@set Q=A\n\n::comment=1\n\n:: Bug 1624: this construct produced inconsistent brackets in the past\nif ERRORLEVEL 2 goto END\n@if exist a (\necho exists\n) else (\necho not\n)\n\nFOR /L %%G IN (2,1,4) DO (echo %%G)\n\n:: Bug 1997: keywords not recognized when preceded by '('\nIF NOT DEFINED var (SET var=1)\n\n:: Bug 2065: keywords not recognized when followed by ')'\n@if exist a ( exit)\n\n:: Bug: with \\r or \\n, 'command' is seen as continuation\necho word ^\n1\ncommand\n\n:: Bug argument and variable expansion\necho %~dp0123\necho %%-~012\necho %%~%%~-abcd\nFOR /F %%I in (\"C:\\Test\\temp.txt\") do echo %%~dI\n\n:: Bug ending of argument and variable expansion\necho %~dp0\\123\necho \"%~dp0123\"\necho \"%%-~012\"\necho \"%%~%%~-abcd\"\nFOR /F %%I in (\"C:\\Test\\temp.txt\") do echo \"%%~dI\"\n\n:: Bug escaped %\necho %%0\necho %%%0\necho %%%%~-abcd\n\n:: Exclamation for delayed expansion\necho !delayed!\necho !delayed! !del!\necho !delayed!a!\n\n:TEST that after label style works\n: TEST2 space after :\n :TEST3 space before :\n:: Bug 2304: \"::\" comments not recognised when second command on line\nSet /A xxx=%xxx%+1 & :: Increment\nSet /A xxx=%xxx%+1 & ::Increment\nSet /A xxx=%xxx%+1 & rem Increment\n\n:END\n"
  },
  {
    "path": "test/examples/batch/x.bat.folded",
    "content": " 0 400   0   rem comment=1\n 0 400   0   rem 'echo' is word=2, 'a' is default=0\n 0 400   0   echo a\n 0 400   0   rem label=3\n 0 400   0   :START\n 0 400   0   rem '@' is hide=4\n 0 400   0   @echo b\n 0 400   0   rem 'gcc' is external command=5\n 0 400   0   gcc --version\n 0 400   0   rem '%PATH%' is variable=6\n 0 400   0   echo %PATH%\n 0 400   0   echo %ProgramFiles(x86)%\n 0 400   0   rem operator=7 '='\n 0 400   0   @set Q=A\n 0 400   0   \n 0 400   0   ::comment=1\n 0 400   0   \n 0 400   0   :: Bug 1624: this construct produced inconsistent brackets in the past\n 0 400   0   if ERRORLEVEL 2 goto END\n 0 400   0   @if exist a (\n 0 400   0   echo exists\n 0 400   0   ) else (\n 0 400   0   echo not\n 0 400   0   )\n 0 400   0   \n 0 400   0   FOR /L %%G IN (2,1,4) DO (echo %%G)\n 0 400   0   \n 0 400   0   :: Bug 1997: keywords not recognized when preceded by '('\n 0 400   0   IF NOT DEFINED var (SET var=1)\n 0 400   0   \n 0 400   0   :: Bug 2065: keywords not recognized when followed by ')'\n 0 400   0   @if exist a ( exit)\n 0 400   0   \n 0 400   0   :: Bug: with \\r or \\n, 'command' is seen as continuation\n 0 400   0   echo word ^\n 0 400   0   1\n 0 400   0   command\n 0 400   0   \n 0 400   0   :: Bug argument and variable expansion\n 0 400   0   echo %~dp0123\n 0 400   0   echo %%-~012\n 0 400   0   echo %%~%%~-abcd\n 0 400   0   FOR /F %%I in (\"C:\\Test\\temp.txt\") do echo %%~dI\n 0 400   0   \n 0 400   0   :: Bug ending of argument and variable expansion\n 0 400   0   echo %~dp0\\123\n 0 400   0   echo \"%~dp0123\"\n 0 400   0   echo \"%%-~012\"\n 0 400   0   echo \"%%~%%~-abcd\"\n 0 400   0   FOR /F %%I in (\"C:\\Test\\temp.txt\") do echo \"%%~dI\"\n 0 400   0   \n 0 400   0   :: Bug escaped %\n 0 400   0   echo %%0\n 0 400   0   echo %%%0\n 0 400   0   echo %%%%~-abcd\n 0 400   0   \n 0 400   0   :: Exclamation for delayed expansion\n 0 400   0   echo !delayed!\n 0 400   0   echo !delayed! !del!\n 0 400   0   echo !delayed!a!\n 0 400   0   \n 0 400   0   :TEST that after label style works\n 0 400   0   : TEST2 space after :\n 0 400   0    :TEST3 space before :\n 0 400   0   :: Bug 2304: \"::\" comments not recognised when second command on line\n 0 400   0   Set /A xxx=%xxx%+1 & :: Increment\n 0 400   0   Set /A xxx=%xxx%+1 & ::Increment\n 0 400   0   Set /A xxx=%xxx%+1 & rem Increment\n 0 400   0   \n 0 400   0   :END\n 0 400   0   "
  },
  {
    "path": "test/examples/batch/x.bat.styled",
    "content": "{1}rem comment=1\nrem 'echo' is word=2, 'a' is default=0\n{2}echo{0} a\n{1}rem label=3\n{3}:START\n{1}rem '@' is hide=4\n{4}@{2}echo{0} b\n{1}rem 'gcc' is external command=5\n{5}gcc{0} --version\n{1}rem '%PATH%' is variable=6\n{2}echo{0} {6}%PATH%{0}\n{2}echo{0} {6}%ProgramFiles(x86)%{0}\n{1}rem operator=7 '='\n{4}@{2}set{0} Q{7}={0}A\n\n{1}::comment=1\n{0}\n{1}:: Bug 1624: this construct produced inconsistent brackets in the past\n{2}if ERRORLEVEL{0} 2{2} goto{0} END\n{4}@{2}if exist{0} a (\n{2}echo{0} exists\n){2} else{0} (\n{2}echo{0} not\n)\n\n{2}FOR{0} /L {6}%%G{2} IN{0} (2,1,4){2} DO{0} ({2}echo{0} {6}%%G{0})\n\n{1}:: Bug 1997: keywords not recognized when preceded by '('\n{2}IF NOT DEFINED{0} var ({2}SET{0} var{7}={0}1)\n\n{1}:: Bug 2065: keywords not recognized when followed by ')'\n{4}@{2}if exist{0} a ({2} exit{0})\n\n{1}:: Bug: with \\r or \\n, 'command' is seen as continuation\n{2}echo{0} word ^\n1\n{5}command{0}\n\n{1}:: Bug argument and variable expansion\n{2}echo{0} {6}%~dp0{0}123\n{2}echo{0} {6}%%-{0}~012\n{2}echo{0} %%~{6}%%~-abcd{0}\n{2}FOR{0} /F {6}%%I{2} in{0} (\"C:\\Test\\temp.txt\"){2} do echo{0} {6}%%~dI{0}\n\n{1}:: Bug ending of argument and variable expansion\n{2}echo{0} {6}%~dp0{0}\\123\n{2}echo{0} \"{6}%~dp0{0}123\"\n{2}echo{0} \"{6}%%-{0}~012\"\n{2}echo{0} \"%%~{6}%%~-abcd{0}\"\n{2}FOR{0} /F {6}%%I{2} in{0} (\"C:\\Test\\temp.txt\"){2} do echo{0} \"{6}%%~dI{0}\"\n\n{1}:: Bug escaped %\n{2}echo{0} {6}%%0{0}\n{2}echo{0} %%{6}%0{0}\n{2}echo{0} %%{6}%%~-abcd{0}\n\n{1}:: Exclamation for delayed expansion\n{2}echo{0} {6}!delayed!{0}\n{2}echo{0} {6}!delayed!{0} {6}!del!{0}\n{2}echo{0} {6}!delayed!{0}a!\n\n{3}:TEST{8} that after label style works\n{3}: TEST2{8} space after :\n{0} {3}:TEST3{8} space before :\n{1}:: Bug 2304: \"::\" comments not recognised when second command on line\n{2}Set{0} /A xxx{7}={6}%xxx%{7}+{0}1 {7}&{0} {1}:: Increment\n{2}Set{0} /A xxx{7}={6}%xxx%{7}+{0}1 {7}&{0} {1}::Increment\n{2}Set{0} /A xxx{7}={6}%xxx%{7}+{0}1 {7}&{0} {1}rem Increment\n{0}\n{3}:END\n"
  },
  {
    "path": "test/examples/caml/AllStyles.ml",
    "content": "(* Enumerate all styles: 0 to 15 *)\n(* comment=12 *)\n\n(* whitespace=0 *)\n\t(* w *)\n\n(* identifier=1 *)\nident\n\n(* tagname=2 *)\n`ident\n\n(* keyword=3 *)\nand\n\n(* keyword2=4 *)\nNone\n\n(* keyword3=5 *)\nchar\n\n(* linenum=6 *)\n#12\n\n(* operator=7 *)\n*\n\n(* number=8 *)\n12\n\n(* char=9 *)\n'a'\n\n(* white=10 *)\n(* this state can not be reached in caml mode, only SML mode but that stops other states *)\n(* SML mode is triggered by \"andalso\" being in the keywords *)\n\"\\ \\x\"\n\n(* string=11 *)\n\"string\"\n\n(* comment1=13 *)\n(* (* comment 1 *) *)\n\n(* comment2=14 *)\n(* (* (* comment 2 *) *) *)\n\n(* comment3=15 *)\n(* (* (* (* comment 1 *) *) *)  *)\n"
  },
  {
    "path": "test/examples/caml/AllStyles.ml.folded",
    "content": " 0 400   0   (* Enumerate all styles: 0 to 15 *)\n 0 400   0   (* comment=12 *)\n 0 400   0   \n 0 400   0   (* whitespace=0 *)\n 0 400   0   \t(* w *)\n 0 400   0   \n 0 400   0   (* identifier=1 *)\n 0 400   0   ident\n 0 400   0   \n 0 400   0   (* tagname=2 *)\n 0 400   0   `ident\n 0 400   0   \n 0 400   0   (* keyword=3 *)\n 0 400   0   and\n 0 400   0   \n 0 400   0   (* keyword2=4 *)\n 0 400   0   None\n 0 400   0   \n 0 400   0   (* keyword3=5 *)\n 0 400   0   char\n 0 400   0   \n 0 400   0   (* linenum=6 *)\n 0 400   0   #12\n 0 400   0   \n 0 400   0   (* operator=7 *)\n 0 400   0   *\n 0 400   0   \n 0 400   0   (* number=8 *)\n 0 400   0   12\n 0 400   0   \n 0 400   0   (* char=9 *)\n 0 400   0   'a'\n 0 400   0   \n 0 400   0   (* white=10 *)\n 0 400   0   (* this state can not be reached in caml mode, only SML mode but that stops other states *)\n 0 400   0   (* SML mode is triggered by \"andalso\" being in the keywords *)\n 0 400   0   \"\\ \\x\"\n 0 400   0   \n 0 400   0   (* string=11 *)\n 0 400   0   \"string\"\n 0 400   0   \n 0 400   0   (* comment1=13 *)\n 0 400   0   (* (* comment 1 *) *)\n 0 400   0   \n 0 400   0   (* comment2=14 *)\n 0 400   0   (* (* (* comment 2 *) *) *)\n 0 400   0   \n 0 400   0   (* comment3=15 *)\n 0 400   0   (* (* (* (* comment 1 *) *) *)  *)\n 0 400   0   "
  },
  {
    "path": "test/examples/caml/AllStyles.ml.styled",
    "content": "{12}(* Enumerate all styles: 0 to 15 *){0}\n{12}(* comment=12 *){0}\n\n{12}(* whitespace=0 *){0}\n\t{12}(* w *){0}\n\n{12}(* identifier=1 *){0}\n{1}ident{0}\n\n{12}(* tagname=2 *){0}\n{2}`ident{0}\n\n{12}(* keyword=3 *){0}\n{3}and{0}\n\n{12}(* keyword2=4 *){0}\n{4}None{0}\n\n{12}(* keyword3=5 *){0}\n{5}char{0}\n\n{12}(* linenum=6 *){0}\n{6}#12{0}\n\n{12}(* operator=7 *){0}\n{7}*{0}\n\n{12}(* number=8 *){0}\n{8}12{0}\n\n{12}(* char=9 *){0}\n{9}'a'{0}\n\n{12}(* white=10 *){0}\n{12}(* this state can not be reached in caml mode, only SML mode but that stops other states *){0}\n{12}(* SML mode is triggered by \"andalso\" being in the keywords *){0}\n{11}\"\\ \\x\"{0}\n\n{12}(* string=11 *){0}\n{11}\"string\"{0}\n\n{12}(* comment1=13 *){0}\n{12}(* {13}(* comment 1 *){12} *){0}\n\n{12}(* comment2=14 *){0}\n{12}(* {13}(* {14}(* comment 2 *){13} *){12} *){0}\n\n{12}(* comment3=15 *){0}\n{12}(* {13}(* {14}(* {15}(* comment 1 *){14} *){13} *){12}  *){0}\n"
  },
  {
    "path": "test/examples/caml/SciTE.properties",
    "content": "lexer.*.ml=caml\nkeywords.*.ml=and xandalso\nkeywords2.*.ml=None\nkeywords3.*.ml=char\n"
  },
  {
    "path": "test/examples/cmake/Bug77_0.cmake",
    "content": "if(MSVC80)\n  # 1\nelseif(MSVC90)\n  # 2\nelseif(APPLE)\n  # 3\nelse()\n  # 4\nendif()\n\nif(MSVC80)\n  # 1\nelseif(MSVC90)\n  # 2\nendif()\n\nif(MSVC80)\n  # 1\nelse()\n  # 2\nendif()\n\nif(MSVC80)\n  # 1\nendif()\n"
  },
  {
    "path": "test/examples/cmake/Bug77_0.cmake.folded",
    "content": " 2 400 401 + if(MSVC80)\n 0 401 401 |   # 1\n 0 401 401 | elseif(MSVC90)\n 0 401 401 |   # 2\n 0 401 401 | elseif(APPLE)\n 0 401 401 |   # 3\n 0 401 401 | else()\n 0 401 401 |   # 4\n 0 401 400 | endif()\n 0 400 400   \n 2 400 401 + if(MSVC80)\n 0 401 401 |   # 1\n 0 401 401 | elseif(MSVC90)\n 0 401 401 |   # 2\n 0 401 400 | endif()\n 0 400 400   \n 2 400 401 + if(MSVC80)\n 0 401 401 |   # 1\n 0 401 401 | else()\n 0 401 401 |   # 2\n 0 401 400 | endif()\n 0 400 400   \n 2 400 401 + if(MSVC80)\n 0 401 401 |   # 1\n 0 401 400 | endif()\n 0 400 400   "
  },
  {
    "path": "test/examples/cmake/Bug77_0.cmake.styled",
    "content": "{11}if{0}({6}MSVC80{0})\n  {1}# 1{0}\n{11}elseif{0}({6}MSVC90{0})\n  {1}# 2{0}\n{11}elseif{0}({6}APPLE{0})\n  {1}# 3{0}\n{11}else{0}()\n  {1}# 4{0}\n{11}endif{0}()\n\n{11}if{0}({6}MSVC80{0})\n  {1}# 1{0}\n{11}elseif{0}({6}MSVC90{0})\n  {1}# 2{0}\n{11}endif{0}()\n\n{11}if{0}({6}MSVC80{0})\n  {1}# 1{0}\n{11}else{0}()\n  {1}# 2{0}\n{11}endif{0}()\n\n{11}if{0}({6}MSVC80{0})\n  {1}# 1{0}\n{11}endif{0}()\n"
  },
  {
    "path": "test/examples/cmake/Bug77_1.cmake",
    "content": "if(MSVC80)\n  # 1\nelseif(MSVC90)\n  # 2\nelseif(APPLE)\n  # 3\nelse()\n  # 4\nendif()\n\nif(MSVC80)\n  # 1\nelseif(MSVC90)\n  # 2\nendif()\n\nif(MSVC80)\n  # 1\nelse()\n  # 2\nendif()\n\nif(MSVC80)\n  # 1\nendif()\n"
  },
  {
    "path": "test/examples/cmake/Bug77_1.cmake.folded",
    "content": " 2 400 401 + if(MSVC80)\n 0 401 400 |   # 1\n 2 400 401 + elseif(MSVC90)\n 0 401 400 |   # 2\n 2 400 401 + elseif(APPLE)\n 0 401 400 |   # 3\n 2 400 401 + else()\n 0 401 401 |   # 4\n 0 401 400 | endif()\n 0 400 400   \n 2 400 401 + if(MSVC80)\n 0 401 400 |   # 1\n 2 400 401 + elseif(MSVC90)\n 0 401 401 |   # 2\n 0 401 400 | endif()\n 0 400 400   \n 2 400 401 + if(MSVC80)\n 0 401 400 |   # 1\n 2 400 401 + else()\n 0 401 401 |   # 2\n 0 401 400 | endif()\n 0 400 400   \n 2 400 401 + if(MSVC80)\n 0 401 401 |   # 1\n 0 401 400 | endif()\n 0 400 400   "
  },
  {
    "path": "test/examples/cmake/Bug77_1.cmake.styled",
    "content": "{11}if{0}({6}MSVC80{0})\n  {1}# 1{0}\n{11}elseif{0}({6}MSVC90{0})\n  {1}# 2{0}\n{11}elseif{0}({6}APPLE{0})\n  {1}# 3{0}\n{11}else{0}()\n  {1}# 4{0}\n{11}endif{0}()\n\n{11}if{0}({6}MSVC80{0})\n  {1}# 1{0}\n{11}elseif{0}({6}MSVC90{0})\n  {1}# 2{0}\n{11}endif{0}()\n\n{11}if{0}({6}MSVC80{0})\n  {1}# 1{0}\n{11}else{0}()\n  {1}# 2{0}\n{11}endif{0}()\n\n{11}if{0}({6}MSVC80{0})\n  {1}# 1{0}\n{11}endif{0}()\n"
  },
  {
    "path": "test/examples/cmake/SciTE.properties",
    "content": "lexer.*.cmake=cmake\nkeywords2.*.cmake=MSVC80 MSVC90 APPLE\nfold=1\nfold.at.else=0\n\nmatch Bug77_1.cmake\n\tfold.at.else=1\n"
  },
  {
    "path": "test/examples/cobol/229.cob",
    "content": "      * Fix string style to not continue to next line\n\n            DISPLAY MESSAGE BOX\n              \"The following process must be applied to Earnings, Deduct\n      -       \"ions and Company Contributions separately.\"\n\nLP61A            DISPLAY MESSAGE BOX \nlp61b            \"S*** strives to continually develop and improve its pr\nLP61B -          \"oducts and services to deliver more value to our custo\nLP61B -          \"mers.\" \n"
  },
  {
    "path": "test/examples/cobol/229.cob.folded",
    "content": " 0 400   0         * Fix string style to not continue to next line\n 0 400   0   \n 0 400   0               DISPLAY MESSAGE BOX\n 0 400   0                 \"The following process must be applied to Earnings, Deduct\n 0 400   0         -       \"ions and Company Contributions separately.\"\n 0 400   0   \n 0 400   0   LP61A            DISPLAY MESSAGE BOX \n 0 400   0   lp61b            \"S*** strives to continually develop and improve its pr\n 0 400   0   LP61B -          \"oducts and services to deliver more value to our custo\n 0 400   0   LP61B -          \"mers.\" \n 0 400   0   "
  },
  {
    "path": "test/examples/cobol/229.cob.styled",
    "content": "{0}      {2}* Fix string style to not continue to next line{0}\n\n            {11}DISPLAY{0} {11}MESSAGE{0} {11}BOX{0}\n              {6}\"The following process must be applied to Earnings, Deduct{0}\n      {10}-{0}       {6}\"ions and Company Contributions separately.\"{0}\n\n{11}LP61A{0}            {11}DISPLAY{0} {11}MESSAGE{0} {11}BOX{0} \n{11}lp61b{0}            {6}\"S*** strives to continually develop and improve its pr{0}\n{11}LP61B{0} {10}-{0}          {6}\"oducts and services to deliver more value to our custo{0}\n{11}LP61B{0} {10}-{0}          {6}\"mers.\"{0} \n"
  },
  {
    "path": "test/examples/cobol/230.cob",
    "content": "      * Keywords starting with V to be identified and styled\n\n      * in list keywords2\n            VARIANCE\n\n      * in list keywords3\n            VARYING\n"
  },
  {
    "path": "test/examples/cobol/230.cob.folded",
    "content": " 0 400   0         * Keywords starting with V to be identified and styled\n 0 400   0   \n 0 400   0         * in list keywords2\n 0 400   0               VARIANCE\n 0 400   0   \n 0 400   0         * in list keywords3\n 0 400   0               VARYING\n 0 400   0   "
  },
  {
    "path": "test/examples/cobol/230.cob.styled",
    "content": "{0}      {2}* Keywords starting with V to be identified and styled{0}\n\n      {2}* in list keywords2{0}\n            {16}VARIANCE{0}\n\n      {2}* in list keywords3{0}\n            {8}VARYING{0}\n"
  },
  {
    "path": "test/examples/cobol/231.cob",
    "content": "      * Comment preceded by 6 characters to be styled\n      * Include / to be styled as a comment\n\n      * Comment colored in green\nABCDE * Comment colored in green\nABCDEF* Comment NOT colored in green\n      / Comment NOT colored in green\nABCDE / Comment NOT colored in green\nABCDEF/ Comment NOT colored in green\n"
  },
  {
    "path": "test/examples/cobol/231.cob.folded",
    "content": " 0 400   0         * Comment preceded by 6 characters to be styled\n 0 400   0         * Include / to be styled as a comment\n 0 400   0   \n 0 400   0         * Comment colored in green\n 0 400   0   ABCDE * Comment colored in green\n 0 400   0   ABCDEF* Comment NOT colored in green\n 0 400   0         / Comment NOT colored in green\n 0 400   0   ABCDE / Comment NOT colored in green\n 0 400   0   ABCDEF/ Comment NOT colored in green\n 0 400   0   "
  },
  {
    "path": "test/examples/cobol/231.cob.styled",
    "content": "{0}      {2}* Comment preceded by 6 characters to be styled{0}\n      {2}* Include / to be styled as a comment{0}\n\n      {2}* Comment colored in green{0}\n{11}ABCDE{0} {2}* Comment colored in green{0}\n{11}ABCDEF{2}* Comment NOT colored in green{0}\n      {2}/ Comment NOT colored in green{0}\n{11}ABCDE{0} {2}/ Comment NOT colored in green{0}\n{11}ABCDEF{2}/ Comment NOT colored in green{0}\n"
  },
  {
    "path": "test/examples/cobol/AllStyles.cob",
    "content": "      *     Enumerate all styles: 0, 2 to 11, 16\n      *     SCE_C_COMMENTLINE=2\n\n      *     SCE_C_DEFAULT=0\n             \n\n      *     SCE_C_IDENTIFIER=11\n            identifier\n\n      *     SCE_C_NUMBER=4\n            4\n\n      *     SCE_C_WORD=5\n            data\n\n      *     SCE_C_WORD2=16\n            cancel\n\n      *     SCE_C_UUID=8\n            remarks\n\n      *     SCE_C_COMMENTDOC=3 not implemented\n** at line start\n\n      *     SCE_C_STRING=6\n            \"string\"\n\n      *     SCE_C_CHARACTER=7\n            'c'\n\n      *     SCE_C_PREPROCESSOR=9\n?preprocessor\n\n      *     SCE_C_OPERATOR=10\n            +\n"
  },
  {
    "path": "test/examples/cobol/AllStyles.cob.folded",
    "content": " 0 400   0         *     Enumerate all styles: 0, 2 to 11, 16\n 0 400   0         *     SCE_C_COMMENTLINE=2\n 0 400   0   \n 0 400   0         *     SCE_C_DEFAULT=0\n 0 400   0                \n 0 400   0   \n 0 400   0         *     SCE_C_IDENTIFIER=11\n 0 400   0               identifier\n 0 400   0   \n 0 400   0         *     SCE_C_NUMBER=4\n 0 400   0               4\n 0 400   0   \n 0 400   0         *     SCE_C_WORD=5\n 0 400   0               data\n 0 400   0   \n 0 400   0         *     SCE_C_WORD2=16\n 0 400   0               cancel\n 0 400   0   \n 0 400   0         *     SCE_C_UUID=8\n 0 400   0               remarks\n 0 400   0   \n 0 400   0         *     SCE_C_COMMENTDOC=3 not implemented\n 0 400   0   ** at line start\n 0 400   0   \n 0 400   0         *     SCE_C_STRING=6\n 0 400   0               \"string\"\n 0 400   0   \n 0 400   0         *     SCE_C_CHARACTER=7\n 0 400   0               'c'\n 0 400   0   \n 0 400   0         *     SCE_C_PREPROCESSOR=9\n 0 400   0   ?preprocessor\n 0 400   0   \n 0 400   0         *     SCE_C_OPERATOR=10\n 0 400   0               +\n 0 400   0   "
  },
  {
    "path": "test/examples/cobol/AllStyles.cob.styled",
    "content": "{0}      {2}*     Enumerate all styles: 0, 2 to 11, 16{0}\n      {2}*     SCE_C_COMMENTLINE=2{0}\n\n      {2}*     SCE_C_DEFAULT=0{0}\n             \n\n      {2}*     SCE_C_IDENTIFIER=11{0}\n            {11}identifier{0}\n\n      {2}*     SCE_C_NUMBER=4{0}\n            {4}4{0}\n\n      {2}*     SCE_C_WORD=5{0}\n            {5}data{0}\n\n      {2}*     SCE_C_WORD2=16{0}\n            {16}cancel{0}\n\n      {2}*     SCE_C_UUID=8{0}\n            {8}remarks{0}\n\n      {2}*     SCE_C_COMMENTDOC=3 not implemented{0}\n{3}** at line start{0}\n\n      {2}*     SCE_C_STRING=6{0}\n            {6}\"string\"{0}\n\n      {2}*     SCE_C_CHARACTER=7{0}\n            {7}'c'{0}\n\n      {2}*     SCE_C_PREPROCESSOR=9{0}\n{9}?preprocessor{0}\n\n      {2}*     SCE_C_OPERATOR=10{0}\n            {10}+{0}\n"
  },
  {
    "path": "test/examples/cobol/SciTE.properties",
    "content": "lexer.*.cob=COBOL\nkeywords.*.cob=data\nkeywords2.*.cob=cancel variance\nkeywords3.*.cob=remarks varying\n"
  },
  {
    "path": "test/examples/cpp/130NonAsciiKeyword.cxx",
    "content": "// coding: utf-8\n// All three following symbols should highlight as keywords\ncheese\nkäse\nсыр\n\n// Lookalikes with ASCII so should not highlight:\nсыp\ncыp\n"
  },
  {
    "path": "test/examples/cpp/130NonAsciiKeyword.cxx.folded",
    "content": " 0 400 400   // coding: utf-8\n 0 400 400   // All three following symbols should highlight as keywords\n 0 400 400   cheese\n 0 400 400   käse\n 0 400 400   сыр\n 1 400 400   \n 0 400 400   // Lookalikes with ASCII so should not highlight:\n 0 400 400   сыp\n 0 400 400   cыp\n 1 400 400   "
  },
  {
    "path": "test/examples/cpp/130NonAsciiKeyword.cxx.styled",
    "content": "{2}// coding: utf-8\n// All three following symbols should highlight as keywords\n{5}cheese{0}\n{5}käse{0}\n{5}сыр{0}\n\n{2}// Lookalikes with ASCII so should not highlight:\n{11}сыp{0}\n{11}cыp{0}\n"
  },
  {
    "path": "test/examples/cpp/149KeywordCase.cxx",
    "content": "// SCE_C_WORD2 (16)\nsecond\n\n// SCE_C_IDENTIFIER (11)\nSecond\n\n// SCE_C_IDENTIFIER (11)\nupper\n\n// SCE_C_WORD2 (16)\nUpper\n"
  },
  {
    "path": "test/examples/cpp/149KeywordCase.cxx.folded",
    "content": " 0 400 400   // SCE_C_WORD2 (16)\n 0 400 400   second\n 1 400 400   \n 0 400 400   // SCE_C_IDENTIFIER (11)\n 0 400 400   Second\n 1 400 400   \n 0 400 400   // SCE_C_IDENTIFIER (11)\n 0 400 400   upper\n 1 400 400   \n 0 400 400   // SCE_C_WORD2 (16)\n 0 400 400   Upper\n 1 400 400   "
  },
  {
    "path": "test/examples/cpp/149KeywordCase.cxx.styled",
    "content": "{2}// SCE_C_WORD2 (16)\n{16}second{0}\n\n{2}// SCE_C_IDENTIFIER (11)\n{11}Second{0}\n\n{2}// SCE_C_IDENTIFIER (11)\n{11}upper{0}\n\n{2}// SCE_C_WORD2 (16)\n{16}Upper{0}\n"
  },
  {
    "path": "test/examples/cpp/48HashNotPreProcessor.cxx",
    "content": "// Examples of JavaScript private elements that start with #\nclass C {\n  #x;\n  constructor(x) {\n    this.#x = x;\n  }\n  static getX(obj) {\n    if (#x in obj) return obj.#x;\n    return \"obj must be an instance of C\";\n  }\n}\n"
  },
  {
    "path": "test/examples/cpp/48HashNotPreProcessor.cxx.folded",
    "content": " 0 400 400   // Examples of JavaScript private elements that start with #\n 2 400 401 + class C {\n 0 401 401 |   #x;\n 2 401 402 +   constructor(x) {\n 0 402 402 |     this.#x = x;\n 0 402 401 |   }\n 2 401 402 +   static getX(obj) {\n 0 402 402 |     if (#x in obj) return obj.#x;\n 0 402 402 |     return \"obj must be an instance of C\";\n 0 402 401 |   }\n 0 401 400 | }\n 1 400 400   "
  },
  {
    "path": "test/examples/cpp/48HashNotPreProcessor.cxx.styled",
    "content": "{2}// Examples of JavaScript private elements that start with #\n{5}class{0} {11}C{0} {10}{{0}\n  {11}#x{10};{0}\n  {11}constructor{10}({11}x{10}){0} {10}{{0}\n    {11}this{10}.{11}#x{0} {10}={0} {11}x{10};{0}\n  {10}}{0}\n  {5}static{0} {11}getX{10}({11}obj{10}){0} {10}{{0}\n    {11}if{0} {10}({11}#x{0} {5}in{0} {11}obj{10}){0} {5}return{0} {11}obj{10}.{11}#x{10};{0}\n    {5}return{0} {6}\"obj must be an instance of C\"{10};{0}\n  {10}}{0}\n{10}}{0}\n"
  },
  {
    "path": "test/examples/cpp/94Template.cxx",
    "content": "// Test JavaScript template expressions for issue 94\n\n// Basic\nvar basic = `${identifier}`;\n\n// Nested\nvar nested = ` ${ ` ${ 1 } ` } `;\n\n// With escapes\nvar xxx = {\n    '1': `\\`\\u0020\\${a${1 + 1}b}`,\n    '2': `\\${a${ `b${1 + 2}c`.charCodeAt(2) }d}`,\n    '3': `\\${a${ `b${ `c${ JSON.stringify({\n        '4': {},\n        }) }d` }e` }f}`,\n};\n\n// Original request\nfetchOptions.body = `\n{\n\t\"accountNumber\" : \"248796\",\n\t\"customerType\" : \"Shipper\",\n\t\"destinationCity\" : \"${order.destination.city}\",\n\t\"destinationState\" : \"${order.destination.stateProvince}\",\n\t\"destinationZip\" : ${order.destination.postalCode},\n\t\"paymentType\" : \"Prepaid\",\n\t\"shipmentInfo\" :\n\t{\n\t\t\"items\" : [ { \"shipmentClass\" : \"50\", \"shipmentWeight\" : \"${order.totalWeight.toString()}\" } ]\n\t}\n}`;\n"
  },
  {
    "path": "test/examples/cpp/94Template.cxx.folded",
    "content": " 0 400 400   // Test JavaScript template expressions for issue 94\n 1 400 400   \n 0 400 400   // Basic\n 0 400 400   var basic = `${identifier}`;\n 1 400 400   \n 0 400 400   // Nested\n 0 400 400   var nested = ` ${ ` ${ 1 } ` } `;\n 1 400 400   \n 0 400 400   // With escapes\n 2 400 401 + var xxx = {\n 0 401 401 |     '1': `\\`\\u0020\\${a${1 + 1}b}`,\n 0 401 401 |     '2': `\\${a${ `b${1 + 2}c`.charCodeAt(2) }d}`,\n 2 401 406 +     '3': `\\${a${ `b${ `c${ JSON.stringify({\n 0 406 406 |         '4': {},\n 0 406 401 |         }) }d` }e` }f}`,\n 0 401 400 | };\n 1 400 400   \n 0 400 400   // Original request\n 0 400 400   fetchOptions.body = `\n 0 400 400   {\n 0 400 400   \t\"accountNumber\" : \"248796\",\n 0 400 400   \t\"customerType\" : \"Shipper\",\n 0 400 400   \t\"destinationCity\" : \"${order.destination.city}\",\n 0 400 400   \t\"destinationState\" : \"${order.destination.stateProvince}\",\n 0 400 400   \t\"destinationZip\" : ${order.destination.postalCode},\n 0 400 400   \t\"paymentType\" : \"Prepaid\",\n 0 400 400   \t\"shipmentInfo\" :\n 0 400 400   \t{\n 0 400 400   \t\t\"items\" : [ { \"shipmentClass\" : \"50\", \"shipmentWeight\" : \"${order.totalWeight.toString()}\" } ]\n 0 400 400   \t}\n 0 400 400   }`;\n 1 400 400   "
  },
  {
    "path": "test/examples/cpp/94Template.cxx.styled",
    "content": "{2}// Test JavaScript template expressions for issue 94\n{0}\n{2}// Basic\n{5}var{0} {11}basic{0} {10}={0} {20}`{10}${{11}identifier{10}}{20}`{10};{0}\n\n{2}// Nested\n{5}var{0} {11}nested{0} {10}={0} {20}` {10}${{0} {20}` {10}${{0} {4}1{0} {10}}{20} `{0} {10}}{20} `{10};{0}\n\n{2}// With escapes\n{5}var{0} {11}xxx{0} {10}={0} {10}{{0}\n    {7}'1'{10}:{0} {20}`{27}\\`\\u0020\\${20}{a{10}${{4}1{0} {10}+{0} {4}1{10}}{20}b}`{10},{0}\n    {7}'2'{10}:{0} {20}`{27}\\${20}{a{10}${{0} {20}`b{10}${{4}1{0} {10}+{0} {4}2{10}}{20}c`{10}.{16}charCodeAt{10}({4}2{10}){0} {10}}{20}d}`{10},{0}\n    {7}'3'{10}:{0} {20}`{27}\\${20}{a{10}${{0} {20}`b{10}${{0} {20}`c{10}${{0} {19}JSON{10}.{16}stringify{10}({{0}\n        {7}'4'{10}:{0} {10}{},{0}\n        {10}}){0} {10}}{20}d`{0} {10}}{20}e`{0} {10}}{20}f}`{10},{0}\n{10}};{0}\n\n{2}// Original request\n{11}fetchOptions{10}.{11}body{0} {10}={0} {20}`\n{\n\t\"accountNumber\" : \"248796\",\n\t\"customerType\" : \"Shipper\",\n\t\"destinationCity\" : \"{10}${{11}order{10}.{11}destination{10}.{11}city{10}}{20}\",\n\t\"destinationState\" : \"{10}${{11}order{10}.{11}destination{10}.{11}stateProvince{10}}{20}\",\n\t\"destinationZip\" : {10}${{11}order{10}.{11}destination{10}.{11}postalCode{10}}{20},\n\t\"paymentType\" : \"Prepaid\",\n\t\"shipmentInfo\" :\n\t{\n\t\t\"items\" : [ { \"shipmentClass\" : \"50\", \"shipmentWeight\" : \"{10}${{11}order{10}.{11}totalWeight{10}.{11}toString{10}()}{20}\" } ]\n\t}\n}`{10};{0}\n"
  },
  {
    "path": "test/examples/cpp/AllStyles.cxx",
    "content": "// Enumerate all primary styles: 0 to 27 and secondary styles 64 to 91\n\n// default=0\n   \n\n// comment=1\n/* */\n\n/* commentline=2 */\n// example line\n\n// commentdoc=3\n/** */\n\n// number=4\n123\n\n// word=5\nint\n\n// string=6\n\"string\"\n\n// character=7\n'c'\n\n// uuid=8\nuuid(3fd43029-1354-42f0-a5be-4a484c9c5250)\n\n// preprocessor=9\n#define xxx 1\n\n// operator=10\n{}\n\n// identifier=11\nidentifier\n\n// stringeol=12\n\"\n\n// verbatim=13\n@\"verbatim\"\n\n// regex=14\n(/regex/)\n\n// commentlinedoc=15\n/// example\n\n// word2=16\nsecond\n\n// commentdockeyword=17\n/** @file */\n\n// commentdockeyworderror=18\n/** @wrongkey */\n\n// globalclass=19\nglobal\n\n// stringraw=20\nR\"( )\"\n\n// tripleverbatim=21\n\"\"\" xx \"\"\"\n\n// hashquotedstring=22\n#\" xx \"\n\n// preprocessorcomment=23\n#define /* comment */\n\n// preprocessorcommentdoc=24\n#define /** comment */\n\n// userliteral=25\n1_date_\n\n// taskmarker=26\n/* TODO: sleep */\n\n// escapesequence=27\n\"\\001 \\b\"\n\n// identifier substyles.11.1=128\nvector\n\n// identifier substyles.11.2=129\nstd\n\n// commentdockeyword substyles.17.1=130\n/** @module */\n\n// Secondary styles inside preprocessor excluded section\n\n#if 0\n\n// default=0\n   \n\n// comment=1\n/* */\n\n/* commentline=2 */\n// example line\n\n// commentdoc=3\n/** */\n\n// number=4\n123\n\n// word=5\nint\n\n// string=6\n\"string\"\n\n// character=7\n'c'\n\n// uuid=8\nuuid(3fd43029-1354-42f0-a5be-4a484c9c5250)\n\n// preprocessor=9\n#define xxx 1\n\n// operator=10\n{}\n\n// identifier=11\nidentifier\n\n// stringeol=12\n\"\n\n// verbatim=13\n@\"verbatim\"\n\n// regex=14\n(/regex/)\n\n// commentlinedoc=15\n/// example\n\n// word2=16\nsecond\n\n// commentdockeyword=17\n/** @file */\n\n// commentdockeyworderror=18\n/** @wrongkey */\n\n// globalclass=19\nglobal\n\n// stringraw=20\nR\"( )\"\n\n// tripleverbatim=21\n\"\"\" xx \"\"\"\n\n// hashquotedstring=22\n#\" xx \"\n\n// preprocessorcomment=23\n#define /* comment */\n\n// preprocessorcommentdoc=24\n#define /** comment */\n\n// userliteral=25\n1_date_\n\n// taskmarker=26\n/* TODO: sleep */\n\n// escapesequence=27\n\"\\001 \\b\"\n\n// identifier substyles.75.1=192\nvector\n\n// identifier substyles.75.2=193\nstd\n\n// commentdockeyword substyles.81.1=194\n/** @module */\n\n#endif\n"
  },
  {
    "path": "test/examples/cpp/AllStyles.cxx.folded",
    "content": " 0 400 400   // Enumerate all primary styles: 0 to 27 and secondary styles 64 to 91\n 1 400 400   \n 0 400 400   // default=0\n 1 400 400      \n 1 400 400   \n 0 400 400   // comment=1\n 0 400 400   /* */\n 1 400 400   \n 0 400 400   /* commentline=2 */\n 0 400 400   // example line\n 1 400 400   \n 0 400 400   // commentdoc=3\n 0 400 400   /** */\n 1 400 400   \n 0 400 400   // number=4\n 0 400 400   123\n 1 400 400   \n 0 400 400   // word=5\n 0 400 400   int\n 1 400 400   \n 0 400 400   // string=6\n 0 400 400   \"string\"\n 1 400 400   \n 0 400 400   // character=7\n 0 400 400   'c'\n 1 400 400   \n 0 400 400   // uuid=8\n 0 400 400   uuid(3fd43029-1354-42f0-a5be-4a484c9c5250)\n 1 400 400   \n 0 400 400   // preprocessor=9\n 0 400 400   #define xxx 1\n 1 400 400   \n 0 400 400   // operator=10\n 0 400 400   {}\n 1 400 400   \n 0 400 400   // identifier=11\n 0 400 400   identifier\n 1 400 400   \n 0 400 400   // stringeol=12\n 0 400 400   \"\n 1 400 400   \n 0 400 400   // verbatim=13\n 0 400 400   @\"verbatim\"\n 1 400 400   \n 0 400 400   // regex=14\n 0 400 400   (/regex/)\n 1 400 400   \n 0 400 400   // commentlinedoc=15\n 0 400 400   /// example\n 1 400 400   \n 0 400 400   // word2=16\n 0 400 400   second\n 1 400 400   \n 0 400 400   // commentdockeyword=17\n 0 400 400   /** @file */\n 1 400 400   \n 0 400 400   // commentdockeyworderror=18\n 0 400 400   /** @wrongkey */\n 1 400 400   \n 0 400 400   // globalclass=19\n 0 400 400   global\n 1 400 400   \n 0 400 400   // stringraw=20\n 0 400 400   R\"( )\"\n 1 400 400   \n 0 400 400   // tripleverbatim=21\n 0 400 400   \"\"\" xx \"\"\"\n 1 400 400   \n 0 400 400   // hashquotedstring=22\n 0 400 400   #\" xx \"\n 1 400 400   \n 0 400 400   // preprocessorcomment=23\n 0 400 400   #define /* comment */\n 1 400 400   \n 0 400 400   // preprocessorcommentdoc=24\n 0 400 400   #define /** comment */\n 1 400 400   \n 0 400 400   // userliteral=25\n 0 400 400   1_date_\n 1 400 400   \n 0 400 400   // taskmarker=26\n 0 400 400   /* TODO: sleep */\n 1 400 400   \n 0 400 400   // escapesequence=27\n 0 400 400   \"\\001 \\b\"\n 1 400 400   \n 0 400 400   // identifier substyles.11.1=128\n 0 400 400   vector\n 1 400 400   \n 0 400 400   // identifier substyles.11.2=129\n 0 400 400   std\n 1 400 400   \n 0 400 400   // commentdockeyword substyles.17.1=130\n 0 400 400   /** @module */\n 1 400 400   \n 0 400 400   // Secondary styles inside preprocessor excluded section\n 1 400 400   \n 2 400 401 + #if 0\n 1 401 401 | \n 0 401 401 | // default=0\n 1 401 401 |    \n 1 401 401 | \n 0 401 401 | // comment=1\n 0 401 401 | /* */\n 1 401 401 | \n 0 401 401 | /* commentline=2 */\n 0 401 401 | // example line\n 1 401 401 | \n 0 401 401 | // commentdoc=3\n 0 401 401 | /** */\n 1 401 401 | \n 0 401 401 | // number=4\n 0 401 401 | 123\n 1 401 401 | \n 0 401 401 | // word=5\n 0 401 401 | int\n 1 401 401 | \n 0 401 401 | // string=6\n 0 401 401 | \"string\"\n 1 401 401 | \n 0 401 401 | // character=7\n 0 401 401 | 'c'\n 1 401 401 | \n 0 401 401 | // uuid=8\n 0 401 401 | uuid(3fd43029-1354-42f0-a5be-4a484c9c5250)\n 1 401 401 | \n 0 401 401 | // preprocessor=9\n 0 401 401 | #define xxx 1\n 1 401 401 | \n 0 401 401 | // operator=10\n 0 401 401 | {}\n 1 401 401 | \n 0 401 401 | // identifier=11\n 0 401 401 | identifier\n 1 401 401 | \n 0 401 401 | // stringeol=12\n 0 401 401 | \"\n 1 401 401 | \n 0 401 401 | // verbatim=13\n 0 401 401 | @\"verbatim\"\n 1 401 401 | \n 0 401 401 | // regex=14\n 0 401 401 | (/regex/)\n 1 401 401 | \n 0 401 401 | // commentlinedoc=15\n 0 401 401 | /// example\n 1 401 401 | \n 0 401 401 | // word2=16\n 0 401 401 | second\n 1 401 401 | \n 0 401 401 | // commentdockeyword=17\n 0 401 401 | /** @file */\n 1 401 401 | \n 0 401 401 | // commentdockeyworderror=18\n 0 401 401 | /** @wrongkey */\n 1 401 401 | \n 0 401 401 | // globalclass=19\n 0 401 401 | global\n 1 401 401 | \n 0 401 401 | // stringraw=20\n 0 401 401 | R\"( )\"\n 1 401 401 | \n 0 401 401 | // tripleverbatim=21\n 0 401 401 | \"\"\" xx \"\"\"\n 1 401 401 | \n 0 401 401 | // hashquotedstring=22\n 0 401 401 | #\" xx \"\n 1 401 401 | \n 0 401 401 | // preprocessorcomment=23\n 0 401 401 | #define /* comment */\n 1 401 401 | \n 0 401 401 | // preprocessorcommentdoc=24\n 0 401 401 | #define /** comment */\n 1 401 401 | \n 0 401 401 | // userliteral=25\n 0 401 401 | 1_date_\n 1 401 401 | \n 0 401 401 | // taskmarker=26\n 0 401 401 | /* TODO: sleep */\n 1 401 401 | \n 0 401 401 | // escapesequence=27\n 0 401 401 | \"\\001 \\b\"\n 1 401 401 | \n 0 401 401 | // identifier substyles.75.1=192\n 0 401 401 | vector\n 1 401 401 | \n 0 401 401 | // identifier substyles.75.2=193\n 0 401 401 | std\n 1 401 401 | \n 0 401 401 | // commentdockeyword substyles.81.1=194\n 0 401 401 | /** @module */\n 1 401 401 | \n 0 401 400 | #endif\n 1 400 400   "
  },
  {
    "path": "test/examples/cpp/AllStyles.cxx.styled",
    "content": "{2}// Enumerate all primary styles: 0 to 27 and secondary styles 64 to 91\n{0}\n{2}// default=0\n{0}   \n\n{2}// comment=1\n{1}/* */{0}\n\n{1}/* commentline=2 */{0}\n{2}// example line\n{0}\n{2}// commentdoc=3\n{3}/** */{0}\n\n{2}// number=4\n{4}123{0}\n\n{2}// word=5\n{5}int{0}\n\n{2}// string=6\n{6}\"string\"{0}\n\n{2}// character=7\n{7}'c'{0}\n\n{2}// uuid=8\n{5}uuid{10}({8}3fd43029-1354-42f0-a5be-4a484c9c5250{10}){0}\n\n{2}// preprocessor=9\n{9}#define xxx 1\n{0}\n{2}// operator=10\n{10}{}{0}\n\n{2}// identifier=11\n{11}identifier{0}\n\n{2}// stringeol=12\n{12}\"\n{0}\n{2}// verbatim=13\n{13}@\"verbatim\"{0}\n\n{2}// regex=14\n{10}({14}/regex/{10}){0}\n\n{2}// commentlinedoc=15\n{15}/// example\n{0}\n{2}// word2=16\n{16}second{0}\n\n{2}// commentdockeyword=17\n{3}/** {17}@file{3} */{0}\n\n{2}// commentdockeyworderror=18\n{3}/** {18}@wrongkey{3} */{0}\n\n{2}// globalclass=19\n{19}global{0}\n\n{2}// stringraw=20\n{20}R\"( )\"{0}\n\n{2}// tripleverbatim=21\n{21}\"\"\" xx \"\"\"{0}\n\n{2}// hashquotedstring=22\n{22}#\" xx \"{0}\n\n{2}// preprocessorcomment=23\n{9}#define {23}/* comment */{9}\n{0}\n{2}// preprocessorcommentdoc=24\n{9}#define {24}/** comment */{9}\n{0}\n{2}// userliteral=25\n{25}1_date_{0}\n\n{2}// taskmarker=26\n{1}/* {26}TODO{1}: sleep */{0}\n\n{2}// escapesequence=27\n{6}\"{27}\\001{6} {27}\\b{6}\"{0}\n\n{2}// identifier substyles.11.1=128\n{128}vector{0}\n\n{2}// identifier substyles.11.2=129\n{129}std{0}\n\n{2}// commentdockeyword substyles.17.1=130\n{3}/** {130}@module{3} */{0}\n\n{2}// Secondary styles inside preprocessor excluded section\n{0}\n{9}#if 0\n{64}\n{66}// default=0\n{64}   \n\n{66}// comment=1\n{65}/* */{64}\n\n{65}/* commentline=2 */{64}\n{66}// example line\n{64}\n{66}// commentdoc=3\n{67}/** */{64}\n\n{66}// number=4\n{68}123{64}\n\n{66}// word=5\n{69}int{64}\n\n{66}// string=6\n{70}\"string\"{64}\n\n{66}// character=7\n{71}'c'{64}\n\n{66}// uuid=8\n{69}uuid{74}({72}3fd43029-1354-42f0-a5be-4a484c9c5250{74}){64}\n\n{66}// preprocessor=9\n{73}#define xxx 1\n{64}\n{66}// operator=10\n{74}{}{64}\n\n{66}// identifier=11\n{75}identifier{64}\n\n{66}// stringeol=12\n{76}\"\n{64}\n{66}// verbatim=13\n{77}@\"verbatim\"{64}\n\n{66}// regex=14\n{74}({78}/regex/{74}){64}\n\n{66}// commentlinedoc=15\n{79}/// example\n{64}\n{66}// word2=16\n{80}second{64}\n\n{66}// commentdockeyword=17\n{67}/** {81}@file{67} */{64}\n\n{66}// commentdockeyworderror=18\n{67}/** {82}@wrongkey{67} */{64}\n\n{66}// globalclass=19\n{83}global{64}\n\n{66}// stringraw=20\n{84}R\"( )\"{64}\n\n{66}// tripleverbatim=21\n{85}\"\"\" xx \"\"\"{64}\n\n{66}// hashquotedstring=22\n{86}#\" xx \"{64}\n\n{66}// preprocessorcomment=23\n{73}#define {87}/* comment */{73}\n{64}\n{66}// preprocessorcommentdoc=24\n{73}#define {88}/** comment */{73}\n{64}\n{66}// userliteral=25\n{89}1_date_{64}\n\n{66}// taskmarker=26\n{65}/* {90}TODO{65}: sleep */{64}\n\n{66}// escapesequence=27\n{70}\"{91}\\001{70} {91}\\b{70}\"{64}\n\n{66}// identifier substyles.75.1=192\n{192}vector{64}\n\n{66}// identifier substyles.75.2=193\n{193}std{64}\n\n{66}// commentdockeyword substyles.81.1=194\n{67}/** {194}@module{67} */{64}\n\n{9}#endif\n"
  },
  {
    "path": "test/examples/cpp/Bug2245.cxx",
    "content": "int i;\n#if 1\ni=1;\n#\ni=2;\n#else\ni=3;\n#endif\ni=4;\n#elif 1\ni=5;\n#else\ni=6;\n"
  },
  {
    "path": "test/examples/cpp/Bug2245.cxx.folded",
    "content": " 0 400 400   int i;\n 2 400 401 + #if 1\n 0 401 401 | i=1;\n 0 401 401 | #\n 0 401 401 | i=2;\n 0 401 401 | #else\n 0 401 401 | i=3;\n 0 401 400 | #endif\n 0 400 400   i=4;\n 0 400 400   #elif 1\n 0 400 400   i=5;\n 0 400 400   #else\n 0 400 400   i=6;\n 1 400 400   "
  },
  {
    "path": "test/examples/cpp/Bug2245.cxx.styled",
    "content": "{5}int{0} {11}i{10};{0}\n{9}#if 1\n{11}i{10}={4}1{10};{0}\n{9}#\n{11}i{10}={4}2{10};{0}\n{9}#else\n{75}i{74}={68}3{74};{64}\n{9}#endif\n{11}i{10}={4}4{10};{0}\n{9}#elif 1\n{11}i{10}={4}5{10};{0}\n{9}#else\n{11}i{10}={4}6{10};{0}\n"
  },
  {
    "path": "test/examples/cpp/SciTE.properties",
    "content": "# coding: utf-8\nlexer.*.cxx=cpp\nkeywords.*.cxx=class in int let return static uuid var\nkeywords2.*.cxx=charCodeAt second stringify Upper\nkeywords3.*.cxx=file\nkeywords4.*.cxx=global JSON\nkeywords5.*.cxx=HAVE_COLOUR FEATURE=2 VERSION(a,b)=a+b\nkeywords6.*.cxx=TODO\n\nsubstyles.cpp.11=2\nsubstylewords.11.1.*.cxx=map string vector\nsubstylewords.11.2.*.cxx=std gsl\n\nsubstyles.cpp.17=1\nsubstylewords.17.1.*.cxx=module\n\nlexer.cpp.track.preprocessor=1\nlexer.cpp.escape.sequence=1\n# Set options so that AllStyles.cxx can show every style\nstyling.within.preprocessor=0\nlexer.cpp.triplequoted.strings=1\nlexer.cpp.hashquoted.strings=1\nlexer.cpp.backquoted.strings=2\n\nfold=1\nfold.preprocessor=1\nfold.comment=1\nfold.compact=1\n\nmatch 130NonAsciiKeyword.cxx\n\tkeywords.*.cxx=cheese käse сыр\n\nmatch 48HashNotPreProcessor.cxx\n\tlexer.cpp.enable.preprocessor=0\n\tlexer.cpp.allow.hashes=1\n"
  },
  {
    "path": "test/examples/cpp/x.cxx",
    "content": "#!/usr/bin/env node\n\n// A demonstration program\n#include <stdio.h>\n#if 0 /* */\n#define DUMMY() \\\n\tif (1);\n#endif\n\n// Test preprocessor expressions with parentheses \n#if ((0))\na\n#elif ((1))\nb\n#endif\n\n/** @file LexCPP.cxx\n <file>\n <file >filename</file>\n LexCPP.cxx.\n </file>\n **/\n\n/** Unknown doc keywords so in SCE_C_COMMENTDOCKEYWORDERROR:\n @wrong LexCPP.cxx\n <wrong>filename</wrong>\n Next line should not start a keyword but before 5.4.1 did and caused bad styling or a crash depending on range lexed\n <\n**/\n\n#define M\\\n\n\\\n \n\n// Test preprocessor active branches feature\n\n#if HAVE_COLOUR\n// Active\n#endif\n#if NOT_HAVE_COLOUR\n// Inactive\n#endif\n\n#if FEATURE==2\n// Active\n#endif\n#if FEATURE==3\n// Inactive\n#endif\n\n#if VERSION(1,2)==3\n// Active\n#endif\n#if VERSION(1,2)==4\n// Inactive\n#endif\n\n#undef HAVE_COLOUR\n#if HAVE_COLOUR\n// Inactive\n#endif\n\n#define MULTIPLY(a,b) a*b\n#if MULTIPLY(2,3)==6\n// Active\n#endif\n\n#define ONE 1\n#if ONE != 1\n// Inactive\n#endif\n\nint main() {\n#region array declarations\n\tdouble x[] = {3.14159,6.02e23,1.6e-19,1.0+1};\n\tint y[] = {75,0113,0x4b};\n#endregion\n\tprintf(\"hello world %d %g\\n\", y[0], x[0]);\n\n\t// JavaScript regular expression (14) tests\n\tlet a = /a/;\n\tlet b = /[a-z]+/gi;\n\t/a|b/i.test(\"baby\");\n\t// arrow function\n\t() => /a|b/i.test(\"baby\");\n\n#pragma region print tests\n\t// Escape sequence (27) tests\n\tprintf(\"\\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v \\P\");\n\tprintf(\"\\0a \\013a \\019\");\n\tprintf(\"\\x013ac \\xdz\");\n\tprintf(\"\\ua34df \\uz\");\n\tprintf(\"\\Ua34df7833 \\Uz\");\n#pragma endregion\n}\n"
  },
  {
    "path": "test/examples/cpp/x.cxx.folded",
    "content": " 0 400 400   #!/usr/bin/env node\n 1 400 400   \n 0 400 400   // A demonstration program\n 0 400 400   #include <stdio.h>\n 2 400 401 + #if 0 /* */\n 0 401 401 | #define DUMMY() \\\n 0 401 401 | \tif (1);\n 0 401 400 | #endif\n 1 400 400   \n 0 400 400   // Test preprocessor expressions with parentheses \n 2 400 401 + #if ((0))\n 0 401 401 | a\n 0 401 401 | #elif ((1))\n 0 401 401 | b\n 0 401 400 | #endif\n 1 400 400   \n 2 400 401 + /** @file LexCPP.cxx\n 0 401 401 |  <file>\n 0 401 401 |  <file >filename</file>\n 0 401 401 |  LexCPP.cxx.\n 0 401 401 |  </file>\n 0 401 400 |  **/\n 1 400 400   \n 2 400 401 + /** Unknown doc keywords so in SCE_C_COMMENTDOCKEYWORDERROR:\n 0 401 401 |  @wrong LexCPP.cxx\n 0 401 401 |  <wrong>filename</wrong>\n 0 401 401 |  Next line should not start a keyword but before 5.4.1 did and caused bad styling or a crash depending on range lexed\n 0 401 401 |  <\n 0 401 400 | **/\n 1 400 400   \n 0 400 400   #define M\\\n 1 400 400   \n 0 400 400   \\\n 1 400 400    \n 1 400 400   \n 0 400 400   // Test preprocessor active branches feature\n 1 400 400   \n 2 400 401 + #if HAVE_COLOUR\n 0 401 401 | // Active\n 0 401 400 | #endif\n 2 400 401 + #if NOT_HAVE_COLOUR\n 0 401 401 | // Inactive\n 0 401 400 | #endif\n 1 400 400   \n 2 400 401 + #if FEATURE==2\n 0 401 401 | // Active\n 0 401 400 | #endif\n 2 400 401 + #if FEATURE==3\n 0 401 401 | // Inactive\n 0 401 400 | #endif\n 1 400 400   \n 2 400 401 + #if VERSION(1,2)==3\n 0 401 401 | // Active\n 0 401 400 | #endif\n 2 400 401 + #if VERSION(1,2)==4\n 0 401 401 | // Inactive\n 0 401 400 | #endif\n 1 400 400   \n 0 400 400   #undef HAVE_COLOUR\n 2 400 401 + #if HAVE_COLOUR\n 0 401 401 | // Inactive\n 0 401 400 | #endif\n 1 400 400   \n 0 400 400   #define MULTIPLY(a,b) a*b\n 2 400 401 + #if MULTIPLY(2,3)==6\n 0 401 401 | // Active\n 0 401 400 | #endif\n 1 400 400   \n 0 400 400   #define ONE 1\n 2 400 401 + #if ONE != 1\n 0 401 401 | // Inactive\n 0 401 400 | #endif\n 1 400 400   \n 2 400 401 + int main() {\n 2 401 402 + #region array declarations\n 0 402 402 | \tdouble x[] = {3.14159,6.02e23,1.6e-19,1.0+1};\n 0 402 402 | \tint y[] = {75,0113,0x4b};\n 0 402 401 | #endregion\n 0 401 401 | \tprintf(\"hello world %d %g\\n\", y[0], x[0]);\n 1 401 401 | \n 0 401 401 | \t// JavaScript regular expression (14) tests\n 0 401 401 | \tlet a = /a/;\n 0 401 401 | \tlet b = /[a-z]+/gi;\n 0 401 401 | \t/a|b/i.test(\"baby\");\n 0 401 401 | \t// arrow function\n 0 401 401 | \t() => /a|b/i.test(\"baby\");\n 1 401 401 | \n 2 401 402 + #pragma region print tests\n 0 402 402 | \t// Escape sequence (27) tests\n 0 402 402 | \tprintf(\"\\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v \\P\");\n 0 402 402 | \tprintf(\"\\0a \\013a \\019\");\n 0 402 402 | \tprintf(\"\\x013ac \\xdz\");\n 0 402 402 | \tprintf(\"\\ua34df \\uz\");\n 0 402 402 | \tprintf(\"\\Ua34df7833 \\Uz\");\n 0 402 401 | #pragma endregion\n 0 401 400 | }\n 1 400 400   "
  },
  {
    "path": "test/examples/cpp/x.cxx.styled",
    "content": "{2}#!/usr/bin/env node\n{0}\n{2}// A demonstration program\n{9}#include <stdio.h>\n#if 0 {23}/* */{9}\n{73}#define DUMMY() \\\n\tif (1);\n{9}#endif\n{0}\n{2}// Test preprocessor expressions with parentheses \n{9}#if ((0))\n{75}a{64}\n{9}#elif ((1))\n{11}b{0}\n{9}#endif\n{0}\n{3}/** {17}@file{3} LexCPP.cxx\n <{17}file{3}>\n <{17}file{3} >filename</{17}file{3}>\n LexCPP.cxx.\n </{17}file{3}>\n **/{0}\n\n{3}/** Unknown doc keywords so in SCE_C_COMMENTDOCKEYWORDERROR:\n {18}@wrong{3} LexCPP.cxx\n <{18}wrong{3}>filename</{18}wrong{3}>\n Next line should not start a keyword but before 5.4.1 did and caused bad styling or a crash depending on range lexed\n <\n**/{0}\n\n{9}#define M\\\n\n{0}\\\n \n\n{2}// Test preprocessor active branches feature\n{0}\n{9}#if HAVE_COLOUR\n{2}// Active\n{9}#endif\n#if NOT_HAVE_COLOUR\n{66}// Inactive\n{9}#endif\n{0}\n{9}#if FEATURE==2\n{2}// Active\n{9}#endif\n#if FEATURE==3\n{66}// Inactive\n{9}#endif\n{0}\n{9}#if VERSION(1,2)==3\n{2}// Active\n{9}#endif\n#if VERSION(1,2)==4\n{66}// Inactive\n{9}#endif\n{0}\n{9}#undef HAVE_COLOUR\n#if HAVE_COLOUR\n{66}// Inactive\n{9}#endif\n{0}\n{9}#define MULTIPLY(a,b) a*b\n#if MULTIPLY(2,3)==6\n{2}// Active\n{9}#endif\n{0}\n{9}#define ONE 1\n#if ONE != 1\n{66}// Inactive\n{9}#endif\n{0}\n{5}int{0} {11}main{10}(){0} {10}{{0}\n{9}#region array declarations\n{0}\t{11}double{0} {11}x{10}[]{0} {10}={0} {10}{{4}3.14159{10},{4}6.02e23{10},{4}1.6e-19{10},{4}1.0{10}+{4}1{10}};{0}\n\t{5}int{0} {11}y{10}[]{0} {10}={0} {10}{{4}75{10},{4}0113{10},{4}0x4b{10}};{0}\n{9}#endregion\n{0}\t{11}printf{10}({6}\"hello world %d %g{27}\\n{6}\"{10},{0} {11}y{10}[{4}0{10}],{0} {11}x{10}[{4}0{10}]);{0}\n\n\t{2}// JavaScript regular expression (14) tests\n{0}\t{5}let{0} {11}a{0} {10}={0} {14}/a/{10};{0}\n\t{5}let{0} {11}b{0} {10}={0} {14}/[a-z]+/gi{10};{0}\n\t{14}/a|b/i{10}.{11}test{10}({6}\"baby\"{10});{0}\n\t{2}// arrow function\n{0}\t{10}(){0} {10}=>{0} {14}/a|b/i{10}.{11}test{10}({6}\"baby\"{10});{0}\n\n{9}#pragma region print tests\n{0}\t{2}// Escape sequence (27) tests\n{0}\t{11}printf{10}({6}\"{27}\\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v{6} {27}\\P{6}\"{10});{0}\n\t{11}printf{10}({6}\"{27}\\0{6}a {27}\\013{6}a {27}\\01{6}9\"{10});{0}\n\t{11}printf{10}({6}\"{27}\\x013a{6}c {27}\\xd{6}z\"{10});{0}\n\t{11}printf{10}({6}\"{27}\\ua34d{6}f {27}\\u{6}z\"{10});{0}\n\t{11}printf{10}({6}\"{27}\\Ua34df783{6}3 {27}\\U{6}z\"{10});{0}\n{9}#pragma endregion\n{10}}{0}\n"
  },
  {
    "path": "test/examples/css/AllStyles.css",
    "content": "/* Enumerate all styles: 0 to 23 */\n\n/* comment=9 */\n\n/* whitespace=0 */\n\t/* */\n\n/* tag=1 */\nhtml/**/\n{}\n\n/* class=2 */\n.hidden\n{}\n\n/* pseudoclass=3 */\n:link\n{}\n\n/* unknown pseudoclass=4 */\n:unknown\n{}\n\n/* operator=5 */\n#\n{}\n\n/* identifier=6 */\n*{margin:}\n\n/* unknown identifier=7 */\n*{unknown:}\n\n/* value=8 */\n*{:88}\n\n/* identifier=10 */\n#identifier\n{}\n\n/* important=11 */\n* { margin: 0 ! important; }\n\n/* directive=12 */\n@directive\n{ }\n\n/* doublestring=13 */\n* { font-family: \"doublestring\"; }\n\n/* singlestring=14 */\n* { font-family: 'singlestring'; }\n\n/* identifier2=15 */\n* { identifier2: 0}\n\n/* attribute=16 */\n[attribute]\n{}\n\n/* identifier3=17 */\n* { identifier3: 0}\n\n/* pseudoelement=18 */\n::pseudoelement\n{}\n\n/* extended_identifier=19 */\n* { extended_identifier: 0}\n\n/* extended_pseudoclass=20 */\n:extended_pseudoclass\n{}\n\n/* extended_pseudoelement=21 */\n::extended_pseudo_element\n{}\n\n/* media=22 */\n@media (orientation: portrait)\n{ }\n\n/* group rule=22 */\n@supports ( display: flex ) {\n  body { display: flex; }\n}\n\n/* variable=23 */\n$variable:#428bca;\n"
  },
  {
    "path": "test/examples/css/AllStyles.css.folded",
    "content": " 0 400   0   /* Enumerate all styles: 0 to 23 */\n 0 400   0   \n 0 400   0   /* comment=9 */\n 0 400   0   \n 0 400   0   /* whitespace=0 */\n 0 400   0   \t/* */\n 0 400   0   \n 0 400   0   /* tag=1 */\n 0 400   0   html/**/\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* class=2 */\n 0 400   0   .hidden\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* pseudoclass=3 */\n 0 400   0   :link\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* unknown pseudoclass=4 */\n 0 400   0   :unknown\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* operator=5 */\n 0 400   0   #\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* identifier=6 */\n 0 400   0   *{margin:}\n 0 400   0   \n 0 400   0   /* unknown identifier=7 */\n 0 400   0   *{unknown:}\n 0 400   0   \n 0 400   0   /* value=8 */\n 0 400   0   *{:88}\n 0 400   0   \n 0 400   0   /* identifier=10 */\n 0 400   0   #identifier\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* important=11 */\n 0 400   0   * { margin: 0 ! important; }\n 0 400   0   \n 0 400   0   /* directive=12 */\n 0 400   0   @directive\n 0 400   0   { }\n 0 400   0   \n 0 400   0   /* doublestring=13 */\n 0 400   0   * { font-family: \"doublestring\"; }\n 0 400   0   \n 0 400   0   /* singlestring=14 */\n 0 400   0   * { font-family: 'singlestring'; }\n 0 400   0   \n 0 400   0   /* identifier2=15 */\n 0 400   0   * { identifier2: 0}\n 0 400   0   \n 0 400   0   /* attribute=16 */\n 0 400   0   [attribute]\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* identifier3=17 */\n 0 400   0   * { identifier3: 0}\n 0 400   0   \n 0 400   0   /* pseudoelement=18 */\n 0 400   0   ::pseudoelement\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* extended_identifier=19 */\n 0 400   0   * { extended_identifier: 0}\n 0 400   0   \n 0 400   0   /* extended_pseudoclass=20 */\n 0 400   0   :extended_pseudoclass\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* extended_pseudoelement=21 */\n 0 400   0   ::extended_pseudo_element\n 0 400   0   {}\n 0 400   0   \n 0 400   0   /* media=22 */\n 0 400   0   @media (orientation: portrait)\n 0 400   0   { }\n 0 400   0   \n 0 400   0   /* group rule=22 */\n 0 400   0   @supports ( display: flex ) {\n 0 400   0     body { display: flex; }\n 0 400   0   }\n 0 400   0   \n 0 400   0   /* variable=23 */\n 0 400   0   $variable:#428bca;\n 0 400   0   "
  },
  {
    "path": "test/examples/css/AllStyles.css.styled",
    "content": "{9}/* Enumerate all styles: 0 to 23 */{0}\n\n{9}/* comment=9 */{0}\n\n{9}/* whitespace=0 */{0}\n\t{9}/* */{0}\n\n{9}/* tag=1 */{0}\n{1}html{9}/**/{1}\n{5}{}{0}\n\n{9}/* class=2 */{0}\n{5}.{2}hidden{1}\n{5}{}{0}\n\n{9}/* pseudoclass=3 */{0}\n{5}:{3}link{1}\n{5}{}{0}\n\n{9}/* unknown pseudoclass=4 */{0}\n{5}:{4}unknown{1}\n{5}{}{0}\n\n{9}/* operator=5 */{0}\n{5}#{1}\n{5}{}{0}\n\n{9}/* identifier=6 */{0}\n{1}*{5}{{6}margin{5}:}{0}\n\n{9}/* unknown identifier=7 */{0}\n{1}*{5}{{7}unknown{5}:}{0}\n\n{9}/* value=8 */{0}\n{1}*{5}{:{8}88{5}}{0}\n\n{9}/* identifier=10 */{0}\n{5}#{10}identifier{1}\n{5}{}{0}\n\n{9}/* important=11 */{0}\n{1}* {5}{{6} margin{5}:{8} 0 {5}!{11} important{5};{6} {5}}{0}\n\n{9}/* directive=12 */{0}\n{5}@{12}directive\n{5}{{6} {5}}{0}\n\n{9}/* doublestring=13 */{0}\n{1}* {5}{{7} font-family{5}:{8} {13}\"doublestring\"{5};{6} {5}}{0}\n\n{9}/* singlestring=14 */{0}\n{1}* {5}{{7} font-family{5}:{8} {14}'singlestring'{5};{6} {5}}{0}\n\n{9}/* identifier2=15 */{0}\n{1}* {5}{{15} identifier2{5}:{8} 0{5}}{0}\n\n{9}/* attribute=16 */{0}\n{5}[{16}attribute{5}]{1}\n{5}{}{0}\n\n{9}/* identifier3=17 */{0}\n{1}* {5}{{17} identifier3{5}:{8} 0{5}}{0}\n\n{9}/* pseudoelement=18 */{0}\n{5}::{18}pseudoelement{1}\n{5}{}{0}\n\n{9}/* extended_identifier=19 */{0}\n{1}* {5}{{19} extended_identifier{5}:{8} 0{5}}{0}\n\n{9}/* extended_pseudoclass=20 */{0}\n{5}:{20}extended_pseudoclass{1}\n{5}{}{0}\n\n{9}/* extended_pseudoelement=21 */{0}\n{5}::{21}extended_pseudo_element{1}\n{5}{}{0}\n\n{9}/* media=22 */{0}\n{5}@{22}media (orientation: portrait)\n{5}{{0} {5}}{0}\n\n{9}/* group rule=22 */{0}\n{5}@{22}supports ( display: flex ) {5}{{0}\n  {1}body {5}{{7} display{5}:{8} flex{5};{6} {5}}{6}\n{5}}{0}\n\n{9}/* variable=23 */{0}\n{23}$variable{5}:{8}#428bca{5};{0}\n"
  },
  {
    "path": "test/examples/css/SciTE.properties",
    "content": "lexer.*.css=css\n\n# identifier\nkeywords.*.css=margin\n\n# pseudoclass\nkeywords2.*.css=link\n\n# identifier 2\nkeywords3.*.css=identifier2\n\n# identifier 3\nkeywords4.*.css=identifier3\n\n# pseudo elements\nkeywords5.*.css=pseudoelement\n\n# extended identifier\nkeywords6.*.css=extended_identifier\n\n# extended pseudoclass\nkeywords7.*.css=extended_pseudoclass\n\n# extended pseudo elements\nkeywords8.*.css=extended_pseudo_element\n\n# enable SCSS language so $variable is recognized\nlexer.css.scss.language=1\n"
  },
  {
    "path": "test/examples/d/SciTE.properties",
    "content": "lexer.*.d=d\nkeywords.*.d=keyword1\nkeywords2.*.d=keyword2\nkeywords3.*.d=\nkeywords4.*.d=keyword4\nkeywords5.*.d=keyword5\nkeywords6.*.d=keyword6\nkeywords7.*.d=keyword7\n\nfold=1\n"
  },
  {
    "path": "test/examples/d/x.d",
    "content": "﻿$\n// /++ +/ doccomments are not yet supported\n/* */\n/** */\n/// drdr\n/+ /+ +/ +/\n//keyword test\nkeyword1\nkeyword2\nkeyword4\nkeyword5\nkeyword6\nkeyword7\n//unicode identifier test\nвапёasdÓΘΣαԷԸՑהכ拉麺とひシマイ단결을\n//strings test\n's\n'\nw's'w\n\"multiline\n\t\t\tstring\"w\ne\"zz\"e\nr\"asd\\\"e\nr\"multiline\n\t\t\tstring\"c\nr`asd\\`e\n`multiline\n\t\t\tstring`d\nx\"023 abc\"e\nx\"023\n\tabc\"w\n//numbers test\na[3..4]=3\n2.stringof\n2.0.stringof\n2.\n2.2e+2\n2.2e-2\n.2e+2\n.2\n2e+2\n0x2e+2\n0x2ep+10\n,.2.stringof,\n\nend\n \t  \t \n"
  },
  {
    "path": "test/examples/d/x.d.folded",
    "content": " 0 400 400   $\n 0 400 400   // /++ +/ doccomments are not yet supported\n 0 400 400   /* */\n 0 400 400   /** */\n 0 400 400   /// drdr\n 0 400 400   /+ /+ +/ +/\n 0 400 400   //keyword test\n 0 400 400   keyword1\n 0 400 400   keyword2\n 0 400 400   keyword4\n 0 400 400   keyword5\n 0 400 400   keyword6\n 0 400 400   keyword7\n 0 400 400   //unicode identifier test\n 0 400 400   вапёasdÓΘΣαԷԸՑהכ拉麺とひシマイ단결을\n 0 400 400   //strings test\n 0 400 400   's\n 0 400 400   '\n 0 400 400   w's'w\n 0 400 400   \"multiline\n 0 400 400   \t\t\tstring\"w\n 0 400 400   e\"zz\"e\n 0 400 400   r\"asd\\\"e\n 0 400 400   r\"multiline\n 0 400 400   \t\t\tstring\"c\n 0 400 400   r`asd\\`e\n 0 400 400   `multiline\n 0 400 400   \t\t\tstring`d\n 0 400 400   x\"023 abc\"e\n 0 400 400   x\"023\n 0 400 400   \tabc\"w\n 0 400 400   //numbers test\n 0 400 400   a[3..4]=3\n 0 400 400   2.stringof\n 0 400 400   2.0.stringof\n 0 400 400   2.\n 0 400 400   2.2e+2\n 0 400 400   2.2e-2\n 0 400 400   .2e+2\n 0 400 400   .2\n 0 400 400   2e+2\n 0 400 400   0x2e+2\n 0 400 400   0x2ep+10\n 0 400 400   ,.2.stringof,\n 1 400 400   \n 0 400 400   end\n 1 400 400    \t  \t \n 0 400   0   "
  },
  {
    "path": "test/examples/d/x.d.styled",
    "content": "{14}${0}\n{2}// /++ +/ doccomments are not yet supported\n{1}/* */{0}\n{3}/** */{0}\n{15}/// drdr\n{4}/+ /+ +/ +/{0}\n{2}//keyword test\n{6}keyword1{0}\n{7}keyword2{0}\n{9}keyword4{0}\n{20}keyword5{0}\n{21}keyword6{0}\n{22}keyword7{0}\n{2}//unicode identifier test\n{14}вапёasdÓΘΣαԷԸՑהכ拉麺とひシマイ단결을{0}\n{2}//strings test\n{11}'s\n'\n{14}w{12}'s'{14}w{0}\n{10}\"multiline\n\t\t\tstring\"w{0}\n{14}e{10}\"zz\"{14}e{0}\n{19}r\"asd\\\"{14}e{0}\n{19}r\"multiline\n\t\t\tstring\"c{0}\n{14}r{18}`asd\\`{14}e{0}\n{18}`multiline\n\t\t\tstring`d{0}\n{19}x\"023 abc\"{14}e{0}\n{19}x\"023\n\tabc\"w{0}\n{2}//numbers test\n{14}a{13}[{5}3{13}..{5}4{13}]={5}3{0}\n{5}2.stringof{0}\n{5}2.0{13}.{14}stringof{0}\n{5}2.{0}\n{5}2.2e+2{0}\n{5}2.2e-2{0}\n{5}.2e+2{0}\n{5}.2{0}\n{5}2e+2{0}\n{5}0x2e{13}+{5}2{0}\n{5}0x2ep+10{0}\n{13},{5}.2{13}.{14}stringof{13},{0}\n\n{14}end{0}\n \t  \t \n"
  },
  {
    "path": "test/examples/dart/AllStyles.dart",
    "content": "// coding:utf-8\n\nvoid main() {\n  print('Hello, World!');\n}\n\nvar name = 'Voyager I';\nvar url = 'url'\nvar year = 1977;\nvar antennaDiameter = 3.7;\nvar flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];\nvar image = {\n  'tags': ['saturn'],\n  url: '//path/to/saturn.jpg'\n};\n\n\nif (year >= 2001) {\n  print('21st century');\n} else if (year >= 1901) {\n  print('20th century');\n}\n\nfor (final object in flybyObjects) {\n  print(object);\n}\n\nfor (int month = 1; month <= 12; month++) {\n  print(month);\n}\n\nwhile (year < 2016) {\n  year += 1;\n}\n\nflybyObjects.where((name) => name.contains('turn')).forEach(print);\n\n// This is a normal, one-line comment.\n\n/// This is a documentation comment, used to document libraries,\n/// classes, and their members. Tools like IDEs and dartdoc treat\n/// doc comments specially.\n\n/* Comments like these are also supported. */\n\n/** Comment \n    block doc */\n\n// Importing core libraries\nimport 'dart:math';\n\n// Importing libraries from external packages\nimport 'package:test/test.dart';\n\n// Importing files\nimport 'path/to/my_other_file.dart';\n\nclass Spacecraft {\n  String name;\n  DateTime? launchDate;\n\n  // Read-only non-final property\n  int? get launchYear => launchDate?.year;\n\n  // Constructor, with syntactic sugar for assignment to members.\n  Spacecraft(this.name, this.launchDate) {\n    // Initialization code goes here.\n  }\n\n  // Named constructor that forwards to the default one.\n  Spacecraft.unlaunched(String name) : this(name, null);\n\n  // Method.\n  void describe() {\n    print('Spacecraft: $name');\n    // Type promotion doesn't work on getters.\n    var launchDate = this.launchDate;\n    if (launchDate != null) {\n      int years = DateTime.now().difference(launchDate).inDays ~/ 365;\n      print('Launched: $launchYear ($years years ago)');\n    } else {\n      print('Unlaunched');\n    }\n  }\n}\n\nvar voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));\nvoyager.describe();\n\nvar voyager3 = Spacecraft.unlaunched('Voyager III');\nvoyager3.describe();\n\nenum PlanetType { terrestrial, gas, ice }\n\n/// Enum that enumerates the different planets in our solar system\n/// and some of their properties.\nenum Planet {\n  mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),\n  venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),\n  // ···\n  uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),\n  neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);\n\n  /// A constant generating constructor\n  const Planet(\n      {required this.planetType, required this.moons, required this.hasRings});\n\n  /// All instance variables are final\n  final PlanetType planetType;\n  final int moons;\n  final bool hasRings;\n\n  /// Enhanced enums support getters and other methods\n  bool get isGiant =>\n      planetType == PlanetType.gas || planetType == PlanetType.ice;\n}\n\nfinal yourPlanet = Planet.earth;\n\nif (!yourPlanet.isGiant) {\n  print('Your planet is not a \"giant planet\".');\n}\n\nmixin Piloted {\n  int astronauts = 1;\n\n  void describeCrew() {\n    print('Number of astronauts: $astronauts');\n  }\n}\n\nconst oneSecond = Duration(seconds: 1);\n// ···\nFuture<void> printWithDelay(String message) async {\n  await Future.delayed(oneSecond);\n  print(message);\n}\n\n\nFuture<void> printWithDelay(String message) {\n  return Future.delayed(oneSecond).then((_) {\n    print(message);\n  });\n}\n\nFuture<void> createDescriptions(Iterable<String> objects) async {\n  for (final object in objects) {\n    try {\n      var file = File('$object.txt');\n      if (await file.exists()) {\n        var modified = await file.lastModified();\n        print(\n            'File for $object already exists. It was modified on $modified.');\n        continue;\n      }\n      await file.create();\n      await file.writeAsString('Start describing $object in this file.');\n    } on IOException catch (e) {\n      print('Cannot create description for $object: $e');\n    }\n  }\n}\n\nStream<String> report(Spacecraft craft, Iterable<String> objects) async* {\n  for (final object in objects) {\n    await Future.delayed(oneSecond);\n    yield '${craft.name} flies by $object';\n  }\n}\n\nFuture<void> describeFlybyObjects(List<String> flybyObjects) async {\n  try {\n    for (final object in flybyObjects) {\n      var description = await File('$object.txt').readAsString();\n      print(description);\n    }\n  } on IOException catch (e) {\n    print('Could not describe object: $e');\n  } finally {\n    flybyObjects.clear();\n  }\n}\n\nclass Television {\n  /// Use [turnOn] to turn the power on instead.\n  @Deprecated('Use turnOn instead')\n  void activate() {\n    turnOn();\n  }\n\n  /// Turns the TV's power on.\n  void turnOn() {...}\n  // ···\n}\n\nString? name  // Nullable type. Can be `null` or string.\n\nString name   // Non-nullable type. Cannot be `null` but can be string.\n\n\n/// A domesticated South American camelid (Lama glama).\n///\n/// Andean cultures have used llamas as meat and pack\n/// animals since pre-Hispanic times.\n///\n/// Just like any other animal, llamas need to eat,\n/// so don't forget to [feed] them some [Food].\nclass Llama {\n  String? name;\n\n  /** Feeds your llama [food].\n  /\n  / The typical llama eats one bale of hay per week. **/\n  void feed(Food food) {\n    // ...\n  }\n\n  /// Exercises your llama with an [activity] for\n  /// [timeLimit] minutes.\n  void exercise(Activity activity, int timeLimit) {\n    // ...\n  }\n}\n\nimport 'package:lib1/lib1.dart';\nimport 'package:lib2/lib2.dart' as lib2;\n// Import only foo.\nimport 'package:lib1/lib1.dart' show foo;\n// Import all names EXCEPT foo.\nimport 'package:lib2/lib2.dart' hide foo;\n\nprint(#mysymbol);\nSymbol symbol = #myMethod;\nSymbol symbol2 = #<;\nSymbol symbol2 = #void;\n\nvar x = 1;\nvar hex = 0xDEADBEEF;\nvar y = 1.1;\nvar exponents = 1.42e5;\n\nvar s1 = 'Single quotes work well for string literals.';\nvar s2 = \"Double quotes work just as well.\";\nvar s3 = 'It\\'s easy to escape the string delimiter.';\nvar s4 = \"It's even easier to use the other delimiter.\";\n\nvar s = 'string interpolation';\n\nassert('Dart has $s, which is very handy.' ==\n    'Dart has string interpolation, '\n        'which is very handy.');\nassert('That deserves all caps. '\n        '${s.toUpperCase()} is very handy!' ==\n    'That deserves all caps. '\n        'STRING INTERPOLATION is very handy!');\n        \nvar s1 = 'String '\n    'concatenation'\n    \" works even over line breaks.\";\nassert(s1 ==\n    'String concatenation works even over '\n        'line breaks.');\n\nvar s2 = 'The + operator ' + 'works, as well.';\nassert(s2 == 'The + operator works, as well.');\n\nvar s1 = '''\nYou can create\nmulti-line strings like this one.\n''';\n\nvar s2 = \"\"\"This is also a\nmulti-line string.\"\"\";\n\nvar s = r'In a raw string, not even \\n gets special treatment.';\nvar 2 = r\"In a raw string, not even \\n gets special treatment.\";\n\nvar s1 = r'''\nYou can create\nmulti-line strings like this one.\n''';\n\nvar s2 = r\"\"\"This is also a\nmulti-line string.\"\"\";\n\nvar record = ('first', a: 2, b: true, 'last');\n\nvar record = ('first', a: 2, b: true, 'last');\n\nprint(record.$1); // Prints 'first'\nprint(record.a); // Prints 2\nprint(record.b); // Prints true\nprint(record.$2); // Prints 'last'\n\n({String name, int age}) userInfo(Map<String, dynamic> json)\n// ···\n// Destructures using a record pattern with named fields:\nfinal (:name, :age) = userInfo(json);\n\nvar list = [1, 2, 3];\nvar list = [\n  'Car',\n  'Boat',\n  'Plane',\n];\nvar halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};\n\nvar nobleGases = {\n  2: 'helium',\n  10: 'neon',\n  18: 'argon',\n};\n\nvar s = \"\"\"This is also a\n${foo(\n\"$bar\"\n)}\nmulti-line string.\"\"\";\n\nvar s1 = \"\"\"multi\nline\n\\n\nstrings\n\"\"\";\n\nvar s2 = \"\"\"multi-line\n$x\nstrings\n\"\"\";\n\nvar s3 = \"\"\"multi-line\n${x}\nstrings\n\"\"\";\n\nvar s1 = 'Unterminated string;\nvar s2 = \"Unterminated string;\nvar s3 = r'Unterminated raw string;\nvar s4 = r'Unterminated raw string;\n"
  },
  {
    "path": "test/examples/dart/AllStyles.dart.folded",
    "content": " 0 400 400   // coding:utf-8\n 0 400 400   \n 2 400 401 + void main() {\n 0 401 401 |   print('Hello, World!');\n 0 401 400 | }\n 0 400 400   \n 0 400 400   var name = 'Voyager I';\n 0 400 400   var url = 'url'\n 0 400 400   var year = 1977;\n 0 400 400   var antennaDiameter = 3.7;\n 0 400 400   var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];\n 2 400 401 + var image = {\n 0 401 401 |   'tags': ['saturn'],\n 0 401 401 |   url: '//path/to/saturn.jpg'\n 0 401 400 | };\n 0 400 400   \n 0 400 400   \n 2 400 401 + if (year >= 2001) {\n 0 401 401 |   print('21st century');\n 0 401 401 | } else if (year >= 1901) {\n 0 401 401 |   print('20th century');\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + for (final object in flybyObjects) {\n 0 401 401 |   print(object);\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + for (int month = 1; month <= 12; month++) {\n 0 401 401 |   print(month);\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + while (year < 2016) {\n 0 401 401 |   year += 1;\n 0 401 400 | }\n 0 400 400   \n 0 400 400   flybyObjects.where((name) => name.contains('turn')).forEach(print);\n 0 400 400   \n 0 400 400   // This is a normal, one-line comment.\n 0 400 400   \n 2 400 401 + /// This is a documentation comment, used to document libraries,\n 0 401 401 | /// classes, and their members. Tools like IDEs and dartdoc treat\n 0 401 400 | /// doc comments specially.\n 0 400 400   \n 0 400 400   /* Comments like these are also supported. */\n 0 400 400   \n 2 400 401 + /** Comment \n 0 401 400 |     block doc */\n 0 400 400   \n 0 400 400   // Importing core libraries\n 0 400 400   import 'dart:math';\n 0 400 400   \n 0 400 400   // Importing libraries from external packages\n 0 400 400   import 'package:test/test.dart';\n 0 400 400   \n 0 400 400   // Importing files\n 0 400 400   import 'path/to/my_other_file.dart';\n 0 400 400   \n 2 400 401 + class Spacecraft {\n 0 401 401 |   String name;\n 0 401 401 |   DateTime? launchDate;\n 0 401 401 | \n 0 401 401 |   // Read-only non-final property\n 0 401 401 |   int? get launchYear => launchDate?.year;\n 0 401 401 | \n 0 401 401 |   // Constructor, with syntactic sugar for assignment to members.\n 2 401 402 +   Spacecraft(this.name, this.launchDate) {\n 0 402 402 |     // Initialization code goes here.\n 0 402 401 |   }\n 0 401 401 | \n 0 401 401 |   // Named constructor that forwards to the default one.\n 0 401 401 |   Spacecraft.unlaunched(String name) : this(name, null);\n 0 401 401 | \n 0 401 401 |   // Method.\n 2 401 402 +   void describe() {\n 0 402 402 |     print('Spacecraft: $name');\n 0 402 402 |     // Type promotion doesn't work on getters.\n 0 402 402 |     var launchDate = this.launchDate;\n 2 402 403 +     if (launchDate != null) {\n 0 403 403 |       int years = DateTime.now().difference(launchDate).inDays ~/ 365;\n 0 403 403 |       print('Launched: $launchYear ($years years ago)');\n 0 403 403 |     } else {\n 0 403 403 |       print('Unlaunched');\n 0 403 402 |     }\n 0 402 401 |   }\n 0 401 400 | }\n 0 400 400   \n 0 400 400   var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));\n 0 400 400   voyager.describe();\n 0 400 400   \n 0 400 400   var voyager3 = Spacecraft.unlaunched('Voyager III');\n 0 400 400   voyager3.describe();\n 0 400 400   \n 0 400 400   enum PlanetType { terrestrial, gas, ice }\n 0 400 400   \n 2 400 401 + /// Enum that enumerates the different planets in our solar system\n 0 401 400 | /// and some of their properties.\n 2 400 401 + enum Planet {\n 0 401 401 |   mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),\n 0 401 401 |   venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),\n 0 401 401 |   // ···\n 0 401 401 |   uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),\n 0 401 401 |   neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);\n 0 401 401 | \n 0 401 401 |   /// A constant generating constructor\n 2 401 402 +   const Planet(\n 0 402 401 |       {required this.planetType, required this.moons, required this.hasRings});\n 0 401 401 | \n 0 401 401 |   /// All instance variables are final\n 0 401 401 |   final PlanetType planetType;\n 0 401 401 |   final int moons;\n 0 401 401 |   final bool hasRings;\n 0 401 401 | \n 0 401 401 |   /// Enhanced enums support getters and other methods\n 0 401 401 |   bool get isGiant =>\n 0 401 401 |       planetType == PlanetType.gas || planetType == PlanetType.ice;\n 0 401 400 | }\n 0 400 400   \n 0 400 400   final yourPlanet = Planet.earth;\n 0 400 400   \n 2 400 401 + if (!yourPlanet.isGiant) {\n 0 401 401 |   print('Your planet is not a \"giant planet\".');\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + mixin Piloted {\n 0 401 401 |   int astronauts = 1;\n 0 401 401 | \n 2 401 402 +   void describeCrew() {\n 0 402 402 |     print('Number of astronauts: $astronauts');\n 0 402 401 |   }\n 0 401 400 | }\n 0 400 400   \n 0 400 400   const oneSecond = Duration(seconds: 1);\n 0 400 400   // ···\n 2 400 401 + Future<void> printWithDelay(String message) async {\n 0 401 401 |   await Future.delayed(oneSecond);\n 0 401 401 |   print(message);\n 0 401 400 | }\n 0 400 400   \n 0 400 400   \n 2 400 401 + Future<void> printWithDelay(String message) {\n 2 401 403 +   return Future.delayed(oneSecond).then((_) {\n 0 403 403 |     print(message);\n 0 403 401 |   });\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + Future<void> createDescriptions(Iterable<String> objects) async {\n 2 401 402 +   for (final object in objects) {\n 2 402 403 +     try {\n 0 403 403 |       var file = File('$object.txt');\n 2 403 404 +       if (await file.exists()) {\n 0 404 404 |         var modified = await file.lastModified();\n 2 404 405 +         print(\n 0 405 404 |             'File for $object already exists. It was modified on $modified.');\n 0 404 404 |         continue;\n 0 404 403 |       }\n 0 403 403 |       await file.create();\n 0 403 403 |       await file.writeAsString('Start describing $object in this file.');\n 0 403 403 |     } on IOException catch (e) {\n 0 403 403 |       print('Cannot create description for $object: $e');\n 0 403 402 |     }\n 0 402 401 |   }\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {\n 2 401 402 +   for (final object in objects) {\n 0 402 402 |     await Future.delayed(oneSecond);\n 0 402 402 |     yield '${craft.name} flies by $object';\n 0 402 401 |   }\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + Future<void> describeFlybyObjects(List<String> flybyObjects) async {\n 2 401 402 +   try {\n 2 402 403 +     for (final object in flybyObjects) {\n 0 403 403 |       var description = await File('$object.txt').readAsString();\n 0 403 403 |       print(description);\n 0 403 402 |     }\n 0 402 402 |   } on IOException catch (e) {\n 0 402 402 |     print('Could not describe object: $e');\n 0 402 402 |   } finally {\n 0 402 402 |     flybyObjects.clear();\n 0 402 401 |   }\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + class Television {\n 0 401 401 |   /// Use [turnOn] to turn the power on instead.\n 0 401 401 |   @Deprecated('Use turnOn instead')\n 2 401 402 +   void activate() {\n 0 402 402 |     turnOn();\n 0 402 401 |   }\n 0 401 401 | \n 0 401 401 |   /// Turns the TV's power on.\n 0 401 401 |   void turnOn() {...}\n 0 401 401 |   // ···\n 0 401 400 | }\n 0 400 400   \n 0 400 400   String? name  // Nullable type. Can be `null` or string.\n 0 400 400   \n 0 400 400   String name   // Non-nullable type. Cannot be `null` but can be string.\n 0 400 400   \n 0 400 400   \n 2 400 401 + /// A domesticated South American camelid (Lama glama).\n 0 401 401 | ///\n 0 401 401 | /// Andean cultures have used llamas as meat and pack\n 0 401 401 | /// animals since pre-Hispanic times.\n 0 401 401 | ///\n 0 401 401 | /// Just like any other animal, llamas need to eat,\n 0 401 400 | /// so don't forget to [feed] them some [Food].\n 2 400 401 + class Llama {\n 0 401 401 |   String? name;\n 0 401 401 | \n 2 401 402 +   /** Feeds your llama [food].\n 0 402 402 |   /\n 0 402 401 |   / The typical llama eats one bale of hay per week. **/\n 2 401 402 +   void feed(Food food) {\n 0 402 402 |     // ...\n 0 402 401 |   }\n 0 401 401 | \n 2 401 402 +   /// Exercises your llama with an [activity] for\n 0 402 401 |   /// [timeLimit] minutes.\n 2 401 402 +   void exercise(Activity activity, int timeLimit) {\n 0 402 402 |     // ...\n 0 402 401 |   }\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + import 'package:lib1/lib1.dart';\n 0 401 400 | import 'package:lib2/lib2.dart' as lib2;\n 0 400 400   // Import only foo.\n 0 400 400   import 'package:lib1/lib1.dart' show foo;\n 0 400 400   // Import all names EXCEPT foo.\n 0 400 400   import 'package:lib2/lib2.dart' hide foo;\n 0 400 400   \n 0 400 400   print(#mysymbol);\n 0 400 400   Symbol symbol = #myMethod;\n 0 400 400   Symbol symbol2 = #<;\n 0 400 400   Symbol symbol2 = #void;\n 0 400 400   \n 0 400 400   var x = 1;\n 0 400 400   var hex = 0xDEADBEEF;\n 0 400 400   var y = 1.1;\n 0 400 400   var exponents = 1.42e5;\n 0 400 400   \n 0 400 400   var s1 = 'Single quotes work well for string literals.';\n 0 400 400   var s2 = \"Double quotes work just as well.\";\n 0 400 400   var s3 = 'It\\'s easy to escape the string delimiter.';\n 0 400 400   var s4 = \"It's even easier to use the other delimiter.\";\n 0 400 400   \n 0 400 400   var s = 'string interpolation';\n 0 400 400   \n 2 400 401 + assert('Dart has $s, which is very handy.' ==\n 0 401 401 |     'Dart has string interpolation, '\n 0 401 400 |         'which is very handy.');\n 2 400 401 + assert('That deserves all caps. '\n 0 401 401 |         '${s.toUpperCase()} is very handy!' ==\n 0 401 401 |     'That deserves all caps. '\n 0 401 400 |         'STRING INTERPOLATION is very handy!');\n 0 400 400           \n 0 400 400   var s1 = 'String '\n 0 400 400       'concatenation'\n 0 400 400       \" works even over line breaks.\";\n 2 400 401 + assert(s1 ==\n 0 401 401 |     'String concatenation works even over '\n 0 401 400 |         'line breaks.');\n 0 400 400   \n 0 400 400   var s2 = 'The + operator ' + 'works, as well.';\n 0 400 400   assert(s2 == 'The + operator works, as well.');\n 0 400 400   \n 2 400 401 + var s1 = '''\n 0 401 401 | You can create\n 0 401 401 | multi-line strings like this one.\n 0 401 400 | ''';\n 0 400 400   \n 2 400 401 + var s2 = \"\"\"This is also a\n 0 401 400 | multi-line string.\"\"\";\n 0 400 400   \n 0 400 400   var s = r'In a raw string, not even \\n gets special treatment.';\n 0 400 400   var 2 = r\"In a raw string, not even \\n gets special treatment.\";\n 0 400 400   \n 2 400 401 + var s1 = r'''\n 0 401 401 | You can create\n 0 401 401 | multi-line strings like this one.\n 0 401 400 | ''';\n 0 400 400   \n 2 400 401 + var s2 = r\"\"\"This is also a\n 0 401 400 | multi-line string.\"\"\";\n 0 400 400   \n 0 400 400   var record = ('first', a: 2, b: true, 'last');\n 0 400 400   \n 0 400 400   var record = ('first', a: 2, b: true, 'last');\n 0 400 400   \n 0 400 400   print(record.$1); // Prints 'first'\n 0 400 400   print(record.a); // Prints 2\n 0 400 400   print(record.b); // Prints true\n 0 400 400   print(record.$2); // Prints 'last'\n 0 400 400   \n 0 400 400   ({String name, int age}) userInfo(Map<String, dynamic> json)\n 2 400 401 + // ···\n 0 401 400 | // Destructures using a record pattern with named fields:\n 0 400 400   final (:name, :age) = userInfo(json);\n 0 400 400   \n 0 400 400   var list = [1, 2, 3];\n 2 400 401 + var list = [\n 0 401 401 |   'Car',\n 0 401 401 |   'Boat',\n 0 401 401 |   'Plane',\n 0 401 400 | ];\n 0 400 400   var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};\n 0 400 400   \n 2 400 401 + var nobleGases = {\n 0 401 401 |   2: 'helium',\n 0 401 401 |   10: 'neon',\n 0 401 401 |   18: 'argon',\n 0 401 400 | };\n 0 400 400   \n 2 400 401 + var s = \"\"\"This is also a\n 2 401 403 + ${foo(\n 0 403 403 | \"$bar\"\n 0 403 401 | )}\n 0 401 400 | multi-line string.\"\"\";\n 0 400 400   \n 2 400 401 + var s1 = \"\"\"multi\n 0 401 401 | line\n 0 401 401 | \\n\n 0 401 401 | strings\n 0 401 400 | \"\"\";\n 0 400 400   \n 2 400 401 + var s2 = \"\"\"multi-line\n 0 401 401 | $x\n 0 401 401 | strings\n 0 401 400 | \"\"\";\n 0 400 400   \n 2 400 401 + var s3 = \"\"\"multi-line\n 0 401 401 | ${x}\n 0 401 401 | strings\n 0 401 400 | \"\"\";\n 0 400 400   \n 0 400 400   var s1 = 'Unterminated string;\n 0 400 400   var s2 = \"Unterminated string;\n 0 400 400   var s3 = r'Unterminated raw string;\n 0 400 400   var s4 = r'Unterminated raw string;\n 0 400   0   "
  },
  {
    "path": "test/examples/dart/AllStyles.dart.styled",
    "content": "{1}// coding:utf-8\n{0}\n{24}void{0} {14}main{16}(){0} {16}{{0}\n  {14}print{16}({5}'Hello, World!'{16});{0}\n{16}}{0}\n\n{23}var{0} {14}name{0} {16}={0} {5}'Voyager I'{16};{0}\n{23}var{0} {14}url{0} {16}={0} {5}'url'{0}\n{23}var{0} {14}year{0} {16}={0} {20}1977{16};{0}\n{23}var{0} {14}antennaDiameter{0} {16}={0} {20}3.7{16};{0}\n{23}var{0} {14}flybyObjects{0} {16}={0} {16}[{5}'Jupiter'{16},{0} {5}'Saturn'{16},{0} {5}'Uranus'{16},{0} {5}'Neptune'{16}];{0}\n{23}var{0} {14}image{0} {16}={0} {16}{{0}\n  {5}'tags'{16}:{0} {16}[{5}'saturn'{16}],{0}\n  {21}url{16}:{0} {5}'//path/to/saturn.jpg'{0}\n{16}};{0}\n\n\n{23}if{0} {16}({14}year{0} {16}>={0} {20}2001{16}){0} {16}{{0}\n  {14}print{16}({5}'21st century'{16});{0}\n{16}}{0} {23}else{0} {23}if{0} {16}({14}year{0} {16}>={0} {20}1901{16}){0} {16}{{0}\n  {14}print{16}({5}'20th century'{16});{0}\n{16}}{0}\n\n{23}for{0} {16}({23}final{0} {14}object{0} {23}in{0} {14}flybyObjects{16}){0} {16}{{0}\n  {14}print{16}({14}object{16});{0}\n{16}}{0}\n\n{23}for{0} {16}({24}int{0} {14}month{0} {16}={0} {20}1{16};{0} {14}month{0} {16}<={0} {20}12{16};{0} {14}month{16}++){0} {16}{{0}\n  {14}print{16}({14}month{16});{0}\n{16}}{0}\n\n{23}while{0} {16}({14}year{0} {16}<{0} {20}2016{16}){0} {16}{{0}\n  {14}year{0} {16}+={0} {20}1{16};{0}\n{16}}{0}\n\n{14}flybyObjects{16}.{14}where{16}(({14}name{16}){0} {16}=>{0} {14}name{16}.{14}contains{16}({5}'turn'{16})).{14}forEach{16}({14}print{16});{0}\n\n{1}// This is a normal, one-line comment.\n{0}\n{2}/// This is a documentation comment, used to document libraries,\n/// classes, and their members. Tools like IDEs and dartdoc treat\n/// doc comments specially.\n{0}\n{3}/* Comments like these are also supported. */{0}\n\n{4}/** Comment \n    block doc */{0}\n\n{1}// Importing core libraries\n{23}import{0} {5}'dart:math'{16};{0}\n\n{1}// Importing libraries from external packages\n{23}import{0} {5}'package:test/test.dart'{16};{0}\n\n{1}// Importing files\n{23}import{0} {5}'path/to/my_other_file.dart'{16};{0}\n\n{23}class{0} {26}Spacecraft{0} {16}{{0}\n  {25}String{0} {14}name{16};{0}\n  {25}DateTime{16}?{0} {14}launchDate{16};{0}\n\n  {1}// Read-only non-final property\n{0}  {24}int{16}?{0} {23}get{0} {14}launchYear{0} {16}=>{0} {14}launchDate{16}?.{14}year{16};{0}\n\n  {1}// Constructor, with syntactic sugar for assignment to members.\n{0}  {26}Spacecraft{16}({23}this{16}.{14}name{16},{0} {23}this{16}.{14}launchDate{16}){0} {16}{{0}\n    {1}// Initialization code goes here.\n{0}  {16}}{0}\n\n  {1}// Named constructor that forwards to the default one.\n{0}  {26}Spacecraft{16}.{14}unlaunched{16}({25}String{0} {14}name{16}){0} {16}:{0} {23}this{16}({14}name{16},{0} {23}null{16});{0}\n\n  {1}// Method.\n{0}  {24}void{0} {14}describe{16}(){0} {16}{{0}\n    {14}print{16}({5}'Spacecraft: {17}${15}name{5}'{16});{0}\n    {1}// Type promotion doesn't work on getters.\n{0}    {23}var{0} {14}launchDate{0} {16}={0} {23}this{16}.{14}launchDate{16};{0}\n    {23}if{0} {16}({14}launchDate{0} {16}!={0} {23}null{16}){0} {16}{{0}\n      {24}int{0} {14}years{0} {16}={0} {25}DateTime{16}.{14}now{16}().{14}difference{16}({14}launchDate{16}).{14}inDays{0} {16}~/{0} {20}365{16};{0}\n      {14}print{16}({5}'Launched: {17}${15}launchYear{5} ({17}${15}years{5} years ago)'{16});{0}\n    {16}}{0} {23}else{0} {16}{{0}\n      {14}print{16}({5}'Unlaunched'{16});{0}\n    {16}}{0}\n  {16}}{0}\n{16}}{0}\n\n{23}var{0} {14}voyager{0} {16}={0} {26}Spacecraft{16}({5}'Voyager I'{16},{0} {25}DateTime{16}({20}1977{16},{0} {20}9{16},{0} {20}5{16}));{0}\n{14}voyager{16}.{14}describe{16}();{0}\n\n{23}var{0} {14}voyager3{0} {16}={0} {26}Spacecraft{16}.{14}unlaunched{16}({5}'Voyager III'{16});{0}\n{14}voyager3{16}.{14}describe{16}();{0}\n\n{23}enum{0} {14}PlanetType{0} {16}{{0} {14}terrestrial{16},{0} {14}gas{16},{0} {14}ice{0} {16}}{0}\n\n{2}/// Enum that enumerates the different planets in our solar system\n/// and some of their properties.\n{23}enum{0} {14}Planet{0} {16}{{0}\n  {14}mercury{16}({21}planetType{16}:{0} {14}PlanetType{16}.{14}terrestrial{16},{0} {21}moons{16}:{0} {20}0{16},{0} {21}hasRings{16}:{0} {23}false{16}),{0}\n  {14}venus{16}({21}planetType{16}:{0} {14}PlanetType{16}.{14}terrestrial{16},{0} {21}moons{16}:{0} {20}0{16},{0} {21}hasRings{16}:{0} {23}false{16}),{0}\n  {1}// ···\n{0}  {14}uranus{16}({21}planetType{16}:{0} {14}PlanetType{16}.{14}ice{16},{0} {21}moons{16}:{0} {20}27{16},{0} {21}hasRings{16}:{0} {23}true{16}),{0}\n  {14}neptune{16}({21}planetType{16}:{0} {14}PlanetType{16}.{14}ice{16},{0} {21}moons{16}:{0} {20}14{16},{0} {21}hasRings{16}:{0} {23}true{16});{0}\n\n  {2}/// A constant generating constructor\n{0}  {23}const{0} {14}Planet{16}({0}\n      {16}{{23}required{0} {23}this{16}.{14}planetType{16},{0} {23}required{0} {23}this{16}.{14}moons{16},{0} {23}required{0} {23}this{16}.{14}hasRings{16}});{0}\n\n  {2}/// All instance variables are final\n{0}  {23}final{0} {14}PlanetType{0} {14}planetType{16};{0}\n  {23}final{0} {24}int{0} {14}moons{16};{0}\n  {23}final{0} {24}bool{0} {14}hasRings{16};{0}\n\n  {2}/// Enhanced enums support getters and other methods\n{0}  {24}bool{0} {23}get{0} {14}isGiant{0} {16}=>{0}\n      {14}planetType{0} {16}=={0} {14}PlanetType{16}.{14}gas{0} {16}||{0} {14}planetType{0} {16}=={0} {14}PlanetType{16}.{14}ice{16};{0}\n{16}}{0}\n\n{23}final{0} {14}yourPlanet{0} {16}={0} {14}Planet{16}.{14}earth{16};{0}\n\n{23}if{0} {16}(!{14}yourPlanet{16}.{14}isGiant{16}){0} {16}{{0}\n  {14}print{16}({5}'Your planet is not a \"giant planet\".'{16});{0}\n{16}}{0}\n\n{23}mixin{0} {14}Piloted{0} {16}{{0}\n  {24}int{0} {14}astronauts{0} {16}={0} {20}1{16};{0}\n\n  {24}void{0} {14}describeCrew{16}(){0} {16}{{0}\n    {14}print{16}({5}'Number of astronauts: {17}${15}astronauts{5}'{16});{0}\n  {16}}{0}\n{16}}{0}\n\n{23}const{0} {14}oneSecond{0} {16}={0} {25}Duration{16}({21}seconds{16}:{0} {20}1{16});{0}\n{1}// ···\n{25}Future{16}<{24}void{16}>{0} {14}printWithDelay{16}({25}String{0} {14}message{16}){0} {23}async{0} {16}{{0}\n  {23}await{0} {25}Future{16}.{14}delayed{16}({14}oneSecond{16});{0}\n  {14}print{16}({14}message{16});{0}\n{16}}{0}\n\n\n{25}Future{16}<{24}void{16}>{0} {14}printWithDelay{16}({25}String{0} {14}message{16}){0} {16}{{0}\n  {23}return{0} {25}Future{16}.{14}delayed{16}({14}oneSecond{16}).{14}then{16}(({14}_{16}){0} {16}{{0}\n    {14}print{16}({14}message{16});{0}\n  {16}});{0}\n{16}}{0}\n\n{25}Future{16}<{24}void{16}>{0} {14}createDescriptions{16}({25}Iterable{16}<{25}String{16}>{0} {14}objects{16}){0} {23}async{0} {16}{{0}\n  {23}for{0} {16}({23}final{0} {14}object{0} {23}in{0} {14}objects{16}){0} {16}{{0}\n    {23}try{0} {16}{{0}\n      {23}var{0} {14}file{0} {16}={0} {25}File{16}({5}'{17}${15}object{5}.txt'{16});{0}\n      {23}if{0} {16}({23}await{0} {14}file{16}.{14}exists{16}()){0} {16}{{0}\n        {23}var{0} {14}modified{0} {16}={0} {23}await{0} {14}file{16}.{14}lastModified{16}();{0}\n        {14}print{16}({0}\n            {5}'File for {17}${15}object{5} already exists. It was modified on {17}${15}modified{5}.'{16});{0}\n        {23}continue{16};{0}\n      {16}}{0}\n      {23}await{0} {14}file{16}.{14}create{16}();{0}\n      {23}await{0} {14}file{16}.{14}writeAsString{16}({5}'Start describing {17}${15}object{5} in this file.'{16});{0}\n    {16}}{0} {23}on{0} {25}IOException{0} {23}catch{0} {16}({14}e{16}){0} {16}{{0}\n      {14}print{16}({5}'Cannot create description for {17}${15}object{5}: {17}${15}e{5}'{16});{0}\n    {16}}{0}\n  {16}}{0}\n{16}}{0}\n\n{25}Stream{16}<{25}String{16}>{0} {14}report{16}({26}Spacecraft{0} {14}craft{16},{0} {25}Iterable{16}<{25}String{16}>{0} {14}objects{16}){0} {23}async{16}*{0} {16}{{0}\n  {23}for{0} {16}({23}final{0} {14}object{0} {23}in{0} {14}objects{16}){0} {16}{{0}\n    {23}await{0} {25}Future{16}.{14}delayed{16}({14}oneSecond{16});{0}\n    {23}yield{0} {5}'{17}${{14}craft{16}.{14}name{17}}{5} flies by {17}${15}object{5}'{16};{0}\n  {16}}{0}\n{16}}{0}\n\n{25}Future{16}<{24}void{16}>{0} {14}describeFlybyObjects{16}({25}List{16}<{25}String{16}>{0} {14}flybyObjects{16}){0} {23}async{0} {16}{{0}\n  {23}try{0} {16}{{0}\n    {23}for{0} {16}({23}final{0} {14}object{0} {23}in{0} {14}flybyObjects{16}){0} {16}{{0}\n      {23}var{0} {14}description{0} {16}={0} {23}await{0} {25}File{16}({5}'{17}${15}object{5}.txt'{16}).{14}readAsString{16}();{0}\n      {14}print{16}({14}description{16});{0}\n    {16}}{0}\n  {16}}{0} {23}on{0} {25}IOException{0} {23}catch{0} {16}({14}e{16}){0} {16}{{0}\n    {14}print{16}({5}'Could not describe object: {17}${15}e{5}'{16});{0}\n  {16}}{0} {23}finally{0} {16}{{0}\n    {14}flybyObjects{16}.{14}clear{16}();{0}\n  {16}}{0}\n{16}}{0}\n\n{23}class{0} {14}Television{0} {16}{{0}\n  {2}/// Use [turnOn] to turn the power on instead.\n{0}  {22}@Deprecated{16}({5}'Use turnOn instead'{16}){0}\n  {24}void{0} {14}activate{16}(){0} {16}{{0}\n    {14}turnOn{16}();{0}\n  {16}}{0}\n\n  {2}/// Turns the TV's power on.\n{0}  {24}void{0} {14}turnOn{16}(){0} {16}{...}{0}\n  {1}// ···\n{16}}{0}\n\n{25}String{16}?{0} {14}name{0}  {1}// Nullable type. Can be `null` or string.\n{0}\n{25}String{0} {14}name{0}   {1}// Non-nullable type. Cannot be `null` but can be string.\n{0}\n\n{2}/// A domesticated South American camelid (Lama glama).\n///\n/// Andean cultures have used llamas as meat and pack\n/// animals since pre-Hispanic times.\n///\n/// Just like any other animal, llamas need to eat,\n/// so don't forget to [feed] them some [Food].\n{23}class{0} {14}Llama{0} {16}{{0}\n  {25}String{16}?{0} {14}name{16};{0}\n\n  {4}/** Feeds your llama [food].\n  /\n  / The typical llama eats one bale of hay per week. **/{0}\n  {24}void{0} {14}feed{16}({14}Food{0} {14}food{16}){0} {16}{{0}\n    {1}// ...\n{0}  {16}}{0}\n\n  {2}/// Exercises your llama with an [activity] for\n{0}  {2}/// [timeLimit] minutes.\n{0}  {24}void{0} {14}exercise{16}({14}Activity{0} {14}activity{16},{0} {24}int{0} {14}timeLimit{16}){0} {16}{{0}\n    {1}// ...\n{0}  {16}}{0}\n{16}}{0}\n\n{23}import{0} {5}'package:lib1/lib1.dart'{16};{0}\n{23}import{0} {5}'package:lib2/lib2.dart'{0} {23}as{0} {14}lib2{16};{0}\n{1}// Import only foo.\n{23}import{0} {5}'package:lib1/lib1.dart'{0} {23}show{0} {14}foo{16};{0}\n{1}// Import all names EXCEPT foo.\n{23}import{0} {5}'package:lib2/lib2.dart'{0} {23}hide{0} {14}foo{16};{0}\n\n{14}print{16}({18}#mysymbol{16});{0}\n{25}Symbol{0} {14}symbol{0} {16}={0} {18}#myMethod{16};{0}\n{25}Symbol{0} {14}symbol2{0} {16}={0} {19}#<{16};{0}\n{25}Symbol{0} {14}symbol2{0} {16}={0} {18}#void{16};{0}\n\n{23}var{0} {14}x{0} {16}={0} {20}1{16};{0}\n{23}var{0} {14}hex{0} {16}={0} {20}0xDEADBEEF{16};{0}\n{23}var{0} {14}y{0} {16}={0} {20}1.1{16};{0}\n{23}var{0} {14}exponents{0} {16}={0} {20}1.42e5{16};{0}\n\n{23}var{0} {14}s1{0} {16}={0} {5}'Single quotes work well for string literals.'{16};{0}\n{23}var{0} {14}s2{0} {16}={0} {6}\"Double quotes work just as well.\"{16};{0}\n{23}var{0} {14}s3{0} {16}={0} {5}'It{13}\\'{5}s easy to escape the string delimiter.'{16};{0}\n{23}var{0} {14}s4{0} {16}={0} {6}\"It's even easier to use the other delimiter.\"{16};{0}\n\n{23}var{0} {14}s{0} {16}={0} {5}'string interpolation'{16};{0}\n\n{23}assert{16}({5}'Dart has {17}${15}s{5}, which is very handy.'{0} {16}=={0}\n    {5}'Dart has string interpolation, '{0}\n        {5}'which is very handy.'{16});{0}\n{23}assert{16}({5}'That deserves all caps. '{0}\n        {5}'{17}${{14}s{16}.{14}toUpperCase{16}(){17}}{5} is very handy!'{0} {16}=={0}\n    {5}'That deserves all caps. '{0}\n        {5}'STRING INTERPOLATION is very handy!'{16});{0}\n        \n{23}var{0} {14}s1{0} {16}={0} {5}'String '{0}\n    {5}'concatenation'{0}\n    {6}\" works even over line breaks.\"{16};{0}\n{23}assert{16}({14}s1{0} {16}=={0}\n    {5}'String concatenation works even over '{0}\n        {5}'line breaks.'{16});{0}\n\n{23}var{0} {14}s2{0} {16}={0} {5}'The + operator '{0} {16}+{0} {5}'works, as well.'{16};{0}\n{23}assert{16}({14}s2{0} {16}=={0} {5}'The + operator works, as well.'{16});{0}\n\n{23}var{0} {14}s1{0} {16}={0} {7}'''\nYou can create\nmulti-line strings like this one.\n'''{16};{0}\n\n{23}var{0} {14}s2{0} {16}={0} {8}\"\"\"This is also a\nmulti-line string.\"\"\"{16};{0}\n\n{23}var{0} {14}s{0} {16}={0} {9}r'In a raw string, not even \\n gets special treatment.'{16};{0}\n{23}var{0} {20}2{0} {16}={0} {10}r\"In a raw string, not even \\n gets special treatment.\"{16};{0}\n\n{23}var{0} {14}s1{0} {16}={0} {11}r'''\nYou can create\nmulti-line strings like this one.\n'''{16};{0}\n\n{23}var{0} {14}s2{0} {16}={0} {12}r\"\"\"This is also a\nmulti-line string.\"\"\"{16};{0}\n\n{23}var{0} {14}record{0} {16}={0} {16}({5}'first'{16},{0} {21}a{16}:{0} {20}2{16},{0} {21}b{16}:{0} {23}true{16},{0} {5}'last'{16});{0}\n\n{23}var{0} {14}record{0} {16}={0} {16}({5}'first'{16},{0} {21}a{16}:{0} {20}2{16},{0} {21}b{16}:{0} {23}true{16},{0} {5}'last'{16});{0}\n\n{14}print{16}({14}record{16}.{14}$1{16});{0} {1}// Prints 'first'\n{14}print{16}({14}record{16}.{14}a{16});{0} {1}// Prints 2\n{14}print{16}({14}record{16}.{14}b{16});{0} {1}// Prints true\n{14}print{16}({14}record{16}.{14}$2{16});{0} {1}// Prints 'last'\n{0}\n{16}({{25}String{0} {14}name{16},{0} {24}int{0} {14}age{16}}){0} {14}userInfo{16}({25}Map{16}<{25}String{16},{0} {24}dynamic{16}>{0} {14}json{16}){0}\n{1}// ···\n// Destructures using a record pattern with named fields:\n{23}final{0} {16}(:{14}name{16},{0} {16}:{14}age{16}){0} {16}={0} {14}userInfo{16}({14}json{16});{0}\n\n{23}var{0} {14}list{0} {16}={0} {16}[{20}1{16},{0} {20}2{16},{0} {20}3{16}];{0}\n{23}var{0} {14}list{0} {16}={0} {16}[{0}\n  {5}'Car'{16},{0}\n  {5}'Boat'{16},{0}\n  {5}'Plane'{16},{0}\n{16}];{0}\n{23}var{0} {14}halogens{0} {16}={0} {16}{{5}'fluorine'{16},{0} {5}'chlorine'{16},{0} {5}'bromine'{16},{0} {5}'iodine'{16},{0} {5}'astatine'{16}};{0}\n\n{23}var{0} {14}nobleGases{0} {16}={0} {16}{{0}\n  {20}2{16}:{0} {5}'helium'{16},{0}\n  {20}10{16}:{0} {5}'neon'{16},{0}\n  {20}18{16}:{0} {5}'argon'{16},{0}\n{16}};{0}\n\n{23}var{0} {14}s{0} {16}={0} {8}\"\"\"This is also a\n{17}${{14}foo{16}({0}\n{6}\"{17}${15}bar{6}\"{0}\n{16}){17}}{8}\nmulti-line string.\"\"\"{16};{0}\n\n{23}var{0} {14}s1{0} {16}={0} {8}\"\"\"multi\nline\n{13}\\n{8}\nstrings\n\"\"\"{16};{0}\n\n{23}var{0} {14}s2{0} {16}={0} {8}\"\"\"multi-line\n{17}${15}x{8}\nstrings\n\"\"\"{16};{0}\n\n{23}var{0} {14}s3{0} {16}={0} {8}\"\"\"multi-line\n{17}${{14}x{17}}{8}\nstrings\n\"\"\"{16};{0}\n\n{23}var{0} {14}s1{0} {16}={0} {27}'Unterminated string;\n{23}var{0} {14}s2{0} {16}={0} {27}\"Unterminated string;\n{23}var{0} {14}s3{0} {16}={0} {27}r'Unterminated raw string;\n{23}var{0} {14}s4{0} {16}={0} {27}r'Unterminated raw string;\n"
  },
  {
    "path": "test/examples/dart/SciTE.properties",
    "content": "lexer.*.dart=dart\nfold=1\nkeywords.*.dart=abstract as assert async await base break case catch class const \\\n continue covariant default deferred do else enum export extends extension external \\\n factory false final finally for get hide if implements import in interface is late \\\n library mixin native new null of on operator part required rethrow return sealed \\\n set show static super switch sync this throw true try type typedef var when while \\\n with yield\nkeywords2.*.dart=Function Never bool double dynamic int num void\nkeywords3.*.dart=fBigInt Comparable Comparator Completer DateTime Deprecated \\\n Directory DoubleLinkedQueue Duration Enum Error Exception Expando File FileLock \\\n FileMode FileStat FileSystemEntity FileSystemEvent Future FutureOr HashMap HashSet \\\n IOException Invocation Iterable IterableBase IterableMixin Iterator LinkedHashMap \\\n LinkedHashSet LinkedList LinkedListEntry List ListBase ListMixin ListQueue Map \\\n MapBase MapEntry MapMixin MapView Match Null OSError Object Pattern Platform \\\n Point Process Queue Random RawSocket RawSocketEvent Record Rectangle RegExp \\\n RegExpMatch RuneIterator Runes ServerSocket Set SetBase SetMixin Sink Socket \\\n SocketException SplayTreeMap SplayTreeSet StackTrace Stopwatch Stream String \\\n StringBuffer StringSink Symbol SystemHash Timer Type Uri UriData WeakReference\nkeywords4.*.dart=Spacecraft\n"
  },
  {
    "path": "test/examples/diff/AllStyles.diff",
    "content": "Default=0\n Default\n\nComment=1\nAnother comment\n\nCommand=2 diff\ndiff -u a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm\n\nHeader=3 ---\n--- a/cocoa/ScintillaCocoa.mm\t2016-12-30 14:38:22.000000000 -0600\n\nHeader=3 +++\n+++ b/cocoa/ScintillaCocoa.mm\t2017-02-15 08:20:12.000000000 -0600\n\nPosition=4 @@\n@@ -388,7 +388,8 @@\n\n - (void) idleTriggered: (NSNotification*) notification\n {\n #pragma unused(notification)\n\nDeleted=5 -\n-  static_cast<ScintillaCocoa*>(mTarget)->IdleTimerFired();\n\nAdded=6 +\n+  if (mTarget)\n+    static_cast<ScintillaCocoa*>(mTarget)->IdleTimerFired();\n }\n \n @end\n\nChanged=7 !\n! \t\tGdkColor white = { 0, 0xFFFF, 0xFFFF, 0xFFFF};\n\nPatchAdd=8 ++\n++  styler.ColourTo(i - 1, StateToPrint);\n\nPatchDelete=9 +-\n+-  styler.ColourTo(i - 1, StateToPrint);\n\nRemovedPatchAdd=10 -+\n-+  styler.ColourTo(i - 1, StateToPrint);\n\nRemovedPatchDelete=11 --\n--  styler.ColourTo(i - 1, StateToPrint);\n\ndiff -u a/cocoa/ScintillaCocoa.h b/cocoa/ScintillaCocoa.h\n\n"
  },
  {
    "path": "test/examples/diff/AllStyles.diff.folded",
    "content": " 0 400   0   Default=0\n 0 400   0    Default\n 0 400   0   \n 0 400   0   Comment=1\n 0 400   0   Another comment\n 0 400   0   \n 0 400   0   Command=2 diff\n 2 400   0 + diff -u a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm\n 0 401   0 | \n 0 401   0 | Header=3 ---\n 2 401   0 + --- a/cocoa/ScintillaCocoa.mm\t2016-12-30 14:38:22.000000000 -0600\n 0 402   0 | \n 0 402   0 | Header=3 +++\n 2 401   0 + +++ b/cocoa/ScintillaCocoa.mm\t2017-02-15 08:20:12.000000000 -0600\n 0 402   0 | \n 0 402   0 | Position=4 @@\n 2 402   0 + @@ -388,7 +388,8 @@\n 0 403   0 | \n 0 403   0 |  - (void) idleTriggered: (NSNotification*) notification\n 0 403   0 |  {\n 0 403   0 |  #pragma unused(notification)\n 0 403   0 | \n 0 403   0 | Deleted=5 -\n 0 403   0 | -  static_cast<ScintillaCocoa*>(mTarget)->IdleTimerFired();\n 0 403   0 | \n 0 403   0 | Added=6 +\n 0 403   0 | +  if (mTarget)\n 0 403   0 | +    static_cast<ScintillaCocoa*>(mTarget)->IdleTimerFired();\n 0 403   0 |  }\n 0 403   0 |  \n 0 403   0 |  @end\n 0 403   0 | \n 0 403   0 | Changed=7 !\n 0 403   0 | ! \t\tGdkColor white = { 0, 0xFFFF, 0xFFFF, 0xFFFF};\n 0 403   0 | \n 0 403   0 | PatchAdd=8 ++\n 0 403   0 | ++  styler.ColourTo(i - 1, StateToPrint);\n 0 403   0 | \n 0 403   0 | PatchDelete=9 +-\n 0 403   0 | +-  styler.ColourTo(i - 1, StateToPrint);\n 0 403   0 | \n 0 403   0 | RemovedPatchAdd=10 -+\n 0 403   0 | -+  styler.ColourTo(i - 1, StateToPrint);\n 0 403   0 | \n 0 403   0 | RemovedPatchDelete=11 --\n 0 403   0 | --  styler.ColourTo(i - 1, StateToPrint);\n 0 403   0 | \n 2 400   0 + diff -u a/cocoa/ScintillaCocoa.h b/cocoa/ScintillaCocoa.h\n 0 401   0 | \n 0 400   0   "
  },
  {
    "path": "test/examples/diff/AllStyles.diff.styled",
    "content": "{1}Default=0\n{0} Default\n{1}\nComment=1\nAnother comment\n\nCommand=2 diff\n{2}diff -u a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm\n{1}\nHeader=3 ---\n{3}--- a/cocoa/ScintillaCocoa.mm\t2016-12-30 14:38:22.000000000 -0600\n{1}\nHeader=3 +++\n{3}+++ b/cocoa/ScintillaCocoa.mm\t2017-02-15 08:20:12.000000000 -0600\n{1}\nPosition=4 @@\n{4}@@ -388,7 +388,8 @@\n{1}\n{0} - (void) idleTriggered: (NSNotification*) notification\n {\n #pragma unused(notification)\n{1}\nDeleted=5 -\n{5}-  static_cast<ScintillaCocoa*>(mTarget)->IdleTimerFired();\n{1}\nAdded=6 +\n{6}+  if (mTarget)\n+    static_cast<ScintillaCocoa*>(mTarget)->IdleTimerFired();\n{0} }\n \n @end\n{1}\nChanged=7 !\n{7}! \t\tGdkColor white = { 0, 0xFFFF, 0xFFFF, 0xFFFF};\n{1}\nPatchAdd=8 ++\n{8}++  styler.ColourTo(i - 1, StateToPrint);\n{1}\nPatchDelete=9 +-\n{9}+-  styler.ColourTo(i - 1, StateToPrint);\n{1}\nRemovedPatchAdd=10 -+\n{10}-+  styler.ColourTo(i - 1, StateToPrint);\n{1}\nRemovedPatchDelete=11 --\n{11}--  styler.ColourTo(i - 1, StateToPrint);\n{1}\n{2}diff -u a/cocoa/ScintillaCocoa.h b/cocoa/ScintillaCocoa.h\n{1}\n"
  },
  {
    "path": "test/examples/diff/LongLine.diff",
    "content": "+A 1026-byte line is longer than 1024-byte buffer but doesn't cause problems as diff state determine by short line prefix 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456\n\n"
  },
  {
    "path": "test/examples/diff/LongLine.diff.folded",
    "content": " 0 400   0   +A 1026-byte line is longer than 1024-byte buffer but doesn't cause problems as diff state determine by short line prefix 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456\n 0 400   0   \n 0 400   0   "
  },
  {
    "path": "test/examples/diff/LongLine.diff.styled",
    "content": "{6}+A 1026-byte line is longer than 1024-byte buffer but doesn't cause problems as diff state determine by short line prefix 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456\n{1}\n"
  },
  {
    "path": "test/examples/diff/SciTE.properties",
    "content": "lexer.*.diff=diff\nfold=1\n"
  },
  {
    "path": "test/examples/erlang/AllStyles.erl",
    "content": "% Enumerate all styles: 0..24 31\n\n% comment = 1\n\n% whitespace = 0\n    % 0\n\n% variable = 2\nA\n\n% number = 3\n3\n\n% keyword = 4\nlet\n\n% string = 5\n\"string\"\n\n% operator = 6\n*\n\n% atom = 7\natom\n\n% function_name = 8\nfunction()\n\n% character = 9\n$a\n\n% macro = 10\n?macro\n\n% record = 11\n#record\n\n% preproc = 12\n-define\n\n% node_name = 13\nnode@\n\n% comment_function = 14\n%% function\n\n% comment_module = 15\n%%% module\n\n% comment_doc = 16\n%% @todo\n \n% comment_doc_macro = 17\n%% {@module}\n\n% atom_quoted = 18 (fails)\n'fails'\n\n% macro_quoted = 19\n?'macro'\n\n% record_quoted = 20\n#'record'\n\n% node_name_quoted = 21\n'node@'\n\n% bifs = 22\natom_to_binary\n\n% modules = 23\nio:x\n\n% modules_att = 24\n-module().\n\n% unknown = 31 (this is an internal state and should not be output)\n\n"
  },
  {
    "path": "test/examples/erlang/AllStyles.erl.folded",
    "content": " 0 400   0   % Enumerate all styles: 0..24 31\n 0 400   0   \n 0 400   0   % comment = 1\n 0 400   0   \n 0 400   0   % whitespace = 0\n 0 400   0       % 0\n 0 400   0   \n 0 400   0   % variable = 2\n 0 400   0   A\n 0 400   0   \n 0 400   0   % number = 3\n 0 400   0   3\n 0 400   0   \n 0 400   0   % keyword = 4\n 0 400   0   let\n 0 400   0   \n 0 400   0   % string = 5\n 0 400   0   \"string\"\n 0 400   0   \n 0 400   0   % operator = 6\n 0 400   0   *\n 0 400   0   \n 0 400   0   % atom = 7\n 0 400   0   atom\n 0 400   0   \n 0 400   0   % function_name = 8\n 0 400   0   function()\n 0 400   0   \n 0 400   0   % character = 9\n 0 400   0   $a\n 0 400   0   \n 0 400   0   % macro = 10\n 0 400   0   ?macro\n 0 400   0   \n 0 400   0   % record = 11\n 0 400   0   #record\n 0 400   0   \n 0 400   0   % preproc = 12\n 0 400   0   -define\n 0 400   0   \n 0 400   0   % node_name = 13\n 0 400   0   node@\n 0 400   0   \n 0 400   0   % comment_function = 14\n 0 400   0   %% function\n 0 400   0   \n 0 400   0   % comment_module = 15\n 0 400   0   %%% module\n 0 400   0   \n 0 400   0   % comment_doc = 16\n 0 400   0   %% @todo\n 0 400   0    \n 0 400   0   % comment_doc_macro = 17\n 0 400   0   %% {@module}\n 0 400   0   \n 0 400   0   % atom_quoted = 18 (fails)\n 0 400   0   'fails'\n 0 400   0   \n 0 400   0   % macro_quoted = 19\n 0 400   0   ?'macro'\n 0 400   0   \n 0 400   0   % record_quoted = 20\n 0 400   0   #'record'\n 0 400   0   \n 0 400   0   % node_name_quoted = 21\n 0 400   0   'node@'\n 0 400   0   \n 0 400   0   % bifs = 22\n 0 400   0   atom_to_binary\n 0 400   0   \n 0 400   0   % modules = 23\n 0 400   0   io:x\n 0 400   0   \n 0 400   0   % modules_att = 24\n 0 400   0   -module().\n 0 400   0   \n 0 400   0   % unknown = 31 (this is an internal state and should not be output)\n 0 400   0   \n 0 400   0   "
  },
  {
    "path": "test/examples/erlang/AllStyles.erl.styled",
    "content": "{1}% Enumerate all styles: 0..24 31{0}\n\n{1}% comment = 1{0}\n\n{1}% whitespace = 0{0}\n    {1}% 0{0}\n\n{1}% variable = 2{0}\n{2}A{0}\n\n{1}% number = 3{0}\n{3}3{0}\n\n{1}% keyword = 4{0}\n{4}let{0}\n\n{1}% string = 5{0}\n{5}\"string\"{0}\n\n{1}% operator = 6{0}\n{6}*{0}\n\n{1}% atom = 7{0}\n{7}atom{0}\n\n{1}% function_name = 8{0}\n{8}function{6}(){0}\n\n{1}% character = 9{0}\n{9}$a{0}\n\n{1}% macro = 10{0}\n{10}?macro{0}\n\n{1}% record = 11{0}\n{11}#record{0}\n\n{1}% preproc = 12{0}\n{12}-define{0}\n\n{1}% node_name = 13{0}\n{13}node@{0}\n\n{1}% comment_function = 14{0}\n{14}%% function{0}\n\n{1}% comment_module = 15{0}\n{15}%%% module{0}\n\n{1}% comment_doc = 16{0}\n{14}%% {16}@todo{0}\n \n{1}% comment_doc_macro = 17{0}\n{14}%% {{17}@module{14}}{0}\n\n{1}% atom_quoted = 18 (fails){0}\n{18}'fails'{0}\n\n{1}% macro_quoted = 19{0}\n{19}?'macro'{0}\n\n{1}% record_quoted = 20{0}\n{20}#'record'{0}\n\n{1}% node_name_quoted = 21{0}\n{21}'node@'{0}\n\n{1}% bifs = 22{0}\n{22}atom_to_binary{0}\n\n{1}% modules = 23{0}\n{23}io:{7}x{0}\n\n{1}% modules_att = 24{0}\n{24}-module{6}().{0}\n\n{1}% unknown = 31 (this is an internal state and should not be output){0}\n\n"
  },
  {
    "path": "test/examples/erlang/SciTE.properties",
    "content": "lexer.*.erl=erlang\nkeywords.*.erl=let\nkeywords2.*.erl=atom_to_binary\nkeywords3.*.erl=-define\nkeywords4.*.erl=-module\nkeywords5.*.erl=@todo\nkeywords6.*.erl=@module\n"
  },
  {
    "path": "test/examples/errorlist/AllStyles.err",
    "content": "Default 0\nSome text in default\n\n\nPython Error 1\n  File \"x.err\", line 2\n\n\nGcc Error 2, Find In Files Match 21\nScintillaGTKAccessible.cxx:153:13: warning: Deprecated pre-processor symbol, replace with \n\n\nMicrosoft Error 3\nLexErrorList.cxx(15): fatal error C1083: Cannot open include file: 'ILexer.h': No such file or directory\n\nPlatQt.obj : error LNK2019: unresolved external symbol \"class Scintilla::PRectangle __cdecl Scintilla::PixelAlign(class Scintilla::PRectangle const &,int)\" (?PixelAlign@Scintilla@@YA?AVPRectangle@1@AEBV21@H@Z) referenced in function \"public: virtual void __cdecl Scintilla::SurfaceImpl::FillRectangleAligned(class Scintilla::PRectangle,class Scintilla::Fill)\" (?FillRectangleAligned@SurfaceImpl@Scintilla@@UEAAXVPRectangle@2@VFill@2@@Z)\n\nNMAKE : fatal error U1077: '\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29910\\bin\\HostX64\\x64\\link.EXE\"' : return code '0x460'\n\nDelphi diagnostic is similar so also uses style 3\nSee https://sourceforge.net/p/scintilla/feature-requests/175/\npackerunitPas.pas(22) Error: Unknown directive: 'functixon'\n\nCommand 4\n>pwd\n\n\nBorland Error 5\nError E2378 oddEven.c 16: For statement missing ; in function main()\n\n\nPerl Error 6\nBareword found where operator expected at LexMMIXAL.cxx line 1, near \"// Scintilla\"\n\n\nDotNET Traceback 7\n   at ExceptionTrace.Program.f4() in C:\\Ivan\\dev\\exp\\ExceptionTrace\\Program.cs:line 18\n\n\nLua Error 8\nlast token read: `result' at line 40 in file `Test.lua'\n\n\nCtags 9\nIsAWordChar\tLexMMIXAL.cxx\t/^static inline bool IsAWordChar(const int ch) {$/;\"\tf\tfile:\n\n\nDiff Changed ! 10\n! \t\tGdkColor white = { 0, 0xFFFF, 0xFFFF, 0xFFFF};\n\n\nDiff Addition + 11\n+    <PlatformToolset>v142</PlatformToolset>\n\n\nDiff Deletion - 12\n-    <PlatformToolset>v141</PlatformToolset>\n\n\nDiff Message --- 13\n--- a/win32/SciTE.vcxproj\tFri Jan 31 12:23:51 2020 +1100\n\n\nPHP error 14\nFatal error: Call to undefined function:  foo() in example.php on line 11\n\n\nEssential Lahey Fortran 90 Error 15\nLine 11, file c:\\fortran90\\codigo\\demo.f90\n\n\nIntel Fortran Compiler Error 16\nError 71 at (17:teste.f90) : The program unit has no name\n\n\nIntel Fortran Compiler v8.0 Error 17\nfortcom: Error: shf.f90, line 5602: This name does not have ...\n\n\nAbsoft Pro Fortran 90 Error 18\ncf90-113 f90fe: ERROR SHF3D, File = shf.f90, Line = 1101, Column = 19\n\n\nHTML Tidy 19\nline 8 column 1 - Error: unexpected </head> in <meta>\n\n\nJava Runtime Stack Trace 20\n\tat MethodName>(FileName.java:33)\n\n\nGCC Include Path 22\nIn file included from /usr/include/gtk-2.0/gtk/gtkobject.h:37,\n\n\nGCC Pointer 25\n  236 | void            gtk_type_init   (GTypeDebugFlags    debug_flags);\n      |                                                                ^\n\n\nBash Diagnostic 26\nechoer153.sh: line 22: [: missing `]'\n\n\nEscape Sequence 23\n\u001b[K\n\n\nEscape Sequence Unknown 24\n\u001b[1n\n\n\nEscape Sequence Colour 40\n\u001b[0mColour 0 is 40\n\n\nEscape Sequence Colour 41\n\u001b[31mColour 1 is 41\n\n\nCheck short reset after colour\n\u001b[31m41\u001b[m0\n"
  },
  {
    "path": "test/examples/errorlist/AllStyles.err.folded",
    "content": " 0 400   0   Default 0\n 0 400   0   Some text in default\n 0 400   0   \n 0 400   0   \n 0 400   0   Python Error 1\n 0 400   0     File \"x.err\", line 2\n 0 400   0   \n 0 400   0   \n 0 400   0   Gcc Error 2, Find In Files Match 21\n 0 400   0   ScintillaGTKAccessible.cxx:153:13: warning: Deprecated pre-processor symbol, replace with \n 0 400   0   \n 0 400   0   \n 0 400   0   Microsoft Error 3\n 0 400   0   LexErrorList.cxx(15): fatal error C1083: Cannot open include file: 'ILexer.h': No such file or directory\n 0 400   0   \n 0 400   0   PlatQt.obj : error LNK2019: unresolved external symbol \"class Scintilla::PRectangle __cdecl Scintilla::PixelAlign(class Scintilla::PRectangle const &,int)\" (?PixelAlign@Scintilla@@YA?AVPRectangle@1@AEBV21@H@Z) referenced in function \"public: virtual void __cdecl Scintilla::SurfaceImpl::FillRectangleAligned(class Scintilla::PRectangle,class Scintilla::Fill)\" (?FillRectangleAligned@SurfaceImpl@Scintilla@@UEAAXVPRectangle@2@VFill@2@@Z)\n 0 400   0   \n 0 400   0   NMAKE : fatal error U1077: '\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29910\\bin\\HostX64\\x64\\link.EXE\"' : return code '0x460'\n 0 400   0   \n 0 400   0   Delphi diagnostic is similar so also uses style 3\n 0 400   0   See https://sourceforge.net/p/scintilla/feature-requests/175/\n 0 400   0   packerunitPas.pas(22) Error: Unknown directive: 'functixon'\n 0 400   0   \n 0 400   0   Command 4\n 0 400   0   >pwd\n 0 400   0   \n 0 400   0   \n 0 400   0   Borland Error 5\n 0 400   0   Error E2378 oddEven.c 16: For statement missing ; in function main()\n 0 400   0   \n 0 400   0   \n 0 400   0   Perl Error 6\n 0 400   0   Bareword found where operator expected at LexMMIXAL.cxx line 1, near \"// Scintilla\"\n 0 400   0   \n 0 400   0   \n 0 400   0   DotNET Traceback 7\n 0 400   0      at ExceptionTrace.Program.f4() in C:\\Ivan\\dev\\exp\\ExceptionTrace\\Program.cs:line 18\n 0 400   0   \n 0 400   0   \n 0 400   0   Lua Error 8\n 0 400   0   last token read: `result' at line 40 in file `Test.lua'\n 0 400   0   \n 0 400   0   \n 0 400   0   Ctags 9\n 0 400   0   IsAWordChar\tLexMMIXAL.cxx\t/^static inline bool IsAWordChar(const int ch) {$/;\"\tf\tfile:\n 0 400   0   \n 0 400   0   \n 0 400   0   Diff Changed ! 10\n 0 400   0   ! \t\tGdkColor white = { 0, 0xFFFF, 0xFFFF, 0xFFFF};\n 0 400   0   \n 0 400   0   \n 0 400   0   Diff Addition + 11\n 0 400   0   +    <PlatformToolset>v142</PlatformToolset>\n 0 400   0   \n 0 400   0   \n 0 400   0   Diff Deletion - 12\n 0 400   0   -    <PlatformToolset>v141</PlatformToolset>\n 0 400   0   \n 0 400   0   \n 0 400   0   Diff Message --- 13\n 0 400   0   --- a/win32/SciTE.vcxproj\tFri Jan 31 12:23:51 2020 +1100\n 0 400   0   \n 0 400   0   \n 0 400   0   PHP error 14\n 0 400   0   Fatal error: Call to undefined function:  foo() in example.php on line 11\n 0 400   0   \n 0 400   0   \n 0 400   0   Essential Lahey Fortran 90 Error 15\n 0 400   0   Line 11, file c:\\fortran90\\codigo\\demo.f90\n 0 400   0   \n 0 400   0   \n 0 400   0   Intel Fortran Compiler Error 16\n 0 400   0   Error 71 at (17:teste.f90) : The program unit has no name\n 0 400   0   \n 0 400   0   \n 0 400   0   Intel Fortran Compiler v8.0 Error 17\n 0 400   0   fortcom: Error: shf.f90, line 5602: This name does not have ...\n 0 400   0   \n 0 400   0   \n 0 400   0   Absoft Pro Fortran 90 Error 18\n 0 400   0   cf90-113 f90fe: ERROR SHF3D, File = shf.f90, Line = 1101, Column = 19\n 0 400   0   \n 0 400   0   \n 0 400   0   HTML Tidy 19\n 0 400   0   line 8 column 1 - Error: unexpected </head> in <meta>\n 0 400   0   \n 0 400   0   \n 0 400   0   Java Runtime Stack Trace 20\n 0 400   0   \tat MethodName>(FileName.java:33)\n 0 400   0   \n 0 400   0   \n 0 400   0   GCC Include Path 22\n 0 400   0   In file included from /usr/include/gtk-2.0/gtk/gtkobject.h:37,\n 0 400   0   \n 0 400   0   \n 0 400   0   GCC Pointer 25\n 0 400   0     236 | void            gtk_type_init   (GTypeDebugFlags    debug_flags);\n 0 400   0         |                                                                ^\n 0 400   0   \n 0 400   0   \n 0 400   0   Bash Diagnostic 26\n 0 400   0   echoer153.sh: line 22: [: missing `]'\n 0 400   0   \n 0 400   0   \n 0 400   0   Escape Sequence 23\n 0 400   0   \u001b[K\n 0 400   0   \n 0 400   0   \n 0 400   0   Escape Sequence Unknown 24\n 0 400   0   \u001b[1n\n 0 400   0   \n 0 400   0   \n 0 400   0   Escape Sequence Colour 40\n 0 400   0   \u001b[0mColour 0 is 40\n 0 400   0   \n 0 400   0   \n 0 400   0   Escape Sequence Colour 41\n 0 400   0   \u001b[31mColour 1 is 41\n 0 400   0   \n 0 400   0   \n 0 400   0   Check short reset after colour\n 0 400   0   \u001b[31m41\u001b[m0\n 0 400   0   "
  },
  {
    "path": "test/examples/errorlist/AllStyles.err.styled",
    "content": "{0}Default 0\nSome text in default\n\n\nPython Error 1\n{1}  File \"x.err\", line 2\n{0}\n\nGcc Error 2, Find In Files Match 21\n{2}ScintillaGTKAccessible.cxx:153:13:{21} warning: Deprecated pre-processor symbol, replace with \n{0}\n\nMicrosoft Error 3\n{3}LexErrorList.cxx(15): fatal error C1083: Cannot open include file: 'ILexer.h': No such file or directory\n{0}\n{3}PlatQt.obj : error LNK2019: unresolved external symbol \"class Scintilla::PRectangle __cdecl Scintilla::PixelAlign(class Scintilla::PRectangle const &,int)\" (?PixelAlign@Scintilla@@YA?AVPRectangle@1@AEBV21@H@Z) referenced in function \"public: virtual void __cdecl Scintilla::SurfaceImpl::FillRectangleAligned(class Scintilla::PRectangle,class Scintilla::Fill)\" (?FillRectangleAligned@SurfaceImpl@Scintilla@@UEAAXVPRectangle@2@VFill@2@@Z)\n{0}\n{3}NMAKE : fatal error U1077: '\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29910\\bin\\HostX64\\x64\\link.EXE\"' : return code '0x460'\n{0}\nDelphi diagnostic is similar so also uses style 3\nSee https://sourceforge.net/p/scintilla/feature-requests/175/\n{3}packerunitPas.pas(22) Error: Unknown directive: 'functixon'\n{0}\nCommand 4\n{4}>pwd\n{0}\n\nBorland Error 5\n{5}Error E2378 oddEven.c 16: For statement missing ; in function main()\n{0}\n\nPerl Error 6\n{6}Bareword found where operator expected at LexMMIXAL.cxx line 1, near \"// Scintilla\"\n{0}\n\nDotNET Traceback 7\n{7}   at ExceptionTrace.Program.f4() in C:\\Ivan\\dev\\exp\\ExceptionTrace\\Program.cs:line 18\n{0}\n\nLua Error 8\n{8}last token read: `result' at line 40 in file `Test.lua'\n{0}\n\nCtags 9\n{9}IsAWordChar\tLexMMIXAL.cxx\t/^static inline bool IsAWordChar(const int ch) {$/;\"\tf\tfile:\n{0}\n\nDiff Changed ! 10\n{10}! \t\tGdkColor white = { 0, 0xFFFF, 0xFFFF, 0xFFFF};\n{0}\n\nDiff Addition + 11\n{11}+    <PlatformToolset>v142</PlatformToolset>\n{0}\n\nDiff Deletion - 12\n{12}-    <PlatformToolset>v141</PlatformToolset>\n{0}\n\nDiff Message --- 13\n{13}--- a/win32/SciTE.vcxproj\tFri Jan 31 12:23:51 2020 +1100\n{0}\n\nPHP error 14\n{14}Fatal error: Call to undefined function:  foo() in example.php on line 11\n{0}\n\nEssential Lahey Fortran 90 Error 15\n{15}Line 11, file c:\\fortran90\\codigo\\demo.f90\n{0}\n\nIntel Fortran Compiler Error 16\n{16}Error 71 at (17:teste.f90) : The program unit has no name\n{0}\n\nIntel Fortran Compiler v8.0 Error 17\n{17}fortcom: Error: shf.f90, line 5602: This name does not have ...\n{0}\n\nAbsoft Pro Fortran 90 Error 18\n{18}cf90-113 f90fe: ERROR SHF3D, File = shf.f90, Line = 1101, Column = 19\n{0}\n\nHTML Tidy 19\n{19}line 8 column 1 - Error: unexpected </head> in <meta>\n{0}\n\nJava Runtime Stack Trace 20\n{20}\tat MethodName>(FileName.java:33)\n{0}\n\nGCC Include Path 22\n{22}In file included from /usr/include/gtk-2.0/gtk/gtkobject.h:37,\n{0}\n\nGCC Pointer 25\n{25}  236 | void            gtk_type_init   (GTypeDebugFlags    debug_flags);\n      |                                                                ^\n{0}\n\nBash Diagnostic 26\n{26}echoer153.sh: line 22: [: missing `]'\n{0}\n\nEscape Sequence 23\n{23}\u001b[K{0}\n\n\nEscape Sequence Unknown 24\n{24}\u001b[1n{0}\n\n\nEscape Sequence Colour 40\n{23}\u001b[0m{0}Colour 0 is 40\n\n\nEscape Sequence Colour 41\n{23}\u001b[31m{41}Colour 1 is 41\n{0}\n\nCheck short reset after colour\n{23}\u001b[31m{41}41{23}\u001b[m{0}0\n"
  },
  {
    "path": "test/examples/errorlist/BoldOrBright.err",
    "content": "Escape Sequence 32m\n\u001b[32mColour 32 (Green)\u001b[0m\n\nEscape Sequence 1;32m\n\u001b[1;32mColour 32 (Green) + Bold\u001b[0m\n\nEscape Sequence 92m\n\u001b[92mColour 92 (Bright Green)\u001b[0m\n\nEscape Sequence 36m\n\u001b[36mColour 36 (Cyan)\u001b[0m\n\nEscape Sequence 1;36m\n\u001b[1;36mColour 36 (Cyan) + Bold\u001b[0m\n\nEscape Sequence 92m\n\u001b[96mColour 96 (Bright Cyan)\u001b[0m\n\nEscape Sequence 1m\n\u001b[1mBold\u001b[0m\n"
  },
  {
    "path": "test/examples/errorlist/BoldOrBright.err.folded",
    "content": " 0 400   0   Escape Sequence 32m\n 0 400   0   \u001b[32mColour 32 (Green)\u001b[0m\n 0 400   0   \n 0 400   0   Escape Sequence 1;32m\n 0 400   0   \u001b[1;32mColour 32 (Green) + Bold\u001b[0m\n 0 400   0   \n 0 400   0   Escape Sequence 92m\n 0 400   0   \u001b[92mColour 92 (Bright Green)\u001b[0m\n 0 400   0   \n 0 400   0   Escape Sequence 36m\n 0 400   0   \u001b[36mColour 36 (Cyan)\u001b[0m\n 0 400   0   \n 0 400   0   Escape Sequence 1;36m\n 0 400   0   \u001b[1;36mColour 36 (Cyan) + Bold\u001b[0m\n 0 400   0   \n 0 400   0   Escape Sequence 92m\n 0 400   0   \u001b[96mColour 96 (Bright Cyan)\u001b[0m\n 0 400   0   \n 0 400   0   Escape Sequence 1m\n 0 400   0   \u001b[1mBold\u001b[0m\n 0 400   0   "
  },
  {
    "path": "test/examples/errorlist/BoldOrBright.err.styled",
    "content": "{0}Escape Sequence 32m\n{23}\u001b[32m{42}Colour 32 (Green){23}\u001b[0m{0}\n\nEscape Sequence 1;32m\n{23}\u001b[1;32m{50}Colour 32 (Green) + Bold{23}\u001b[0m{0}\n\nEscape Sequence 92m\n{23}\u001b[92m{50}Colour 92 (Bright Green){23}\u001b[0m{0}\n\nEscape Sequence 36m\n{23}\u001b[36m{46}Colour 36 (Cyan){23}\u001b[0m{0}\n\nEscape Sequence 1;36m\n{23}\u001b[1;36m{54}Colour 36 (Cyan) + Bold{23}\u001b[0m{0}\n\nEscape Sequence 92m\n{23}\u001b[96m{54}Colour 96 (Bright Cyan){23}\u001b[0m{0}\n\nEscape Sequence 1m\n{23}\u001b[1m{48}Bold{23}\u001b[0m{0}\n"
  },
  {
    "path": "test/examples/errorlist/SciTE.properties",
    "content": "lexer.*.err=errorlist\nlexer.errorlist.value.separate=1\nlexer.errorlist.escape.sequences=1\nstyle.errorlist.23=fore:#000000,back:#FFFFFF,$(error.background)\nstyle.errorlist.25=fore:#CF008F,$(font.monospace.small)\n"
  },
  {
    "path": "test/examples/escseq/SciTE.properties",
    "content": "lexer.*.ans=escseq\n\n# Identifier and Unknown colour\nmatch colourText0.ans\n\tlexer.escseq.colour.text=0\n\tstyle.escseq.171=back:#EEFFEE,visible\n\tstyle.escseq.172=back:#FFEEEE,visible\n\n# Full colour\nmatch colourText1.ans\n\tlexer.escseq.colour.text=1\n\tstyle.escseq.171=back:#EEFFEE,notvisible\n\tstyle.escseq.172=back:#FFEEEE,notvisible\n"
  },
  {
    "path": "test/examples/escseq/colourText0.ans",
    "content": "\u001b[0u Seq Unknown\n\u001b[0m Seq 0\n\u001b[1m Seq 1\n\u001b[30m Seq 30\n\u001b[31m Seq 31\n\u001b[30;1m Seq 30;1\n\u001b[31;1m Seq 31;1\n\u001b[42m Seq 42\n\u001b[43m Seq 43\n\u001b[30;42m Seq 30;42\n\u001b[30;43m Seq 30;43\n\u001b[31;44m Seq 31;44\n\u001b[31;45m Seq 31;45\n\u001b[32;46m Seq 32;46\n\u001b[32;47m Seq 32;47\n\u001b[33;40m Seq 33;40\n\u001b[33;41m Seq 33;41\n\u001b[34;43m Seq 34;43\n\u001b[34;44m Seq 34;44\n\u001b[35;45m Seq 35;45\n\u001b[35;46m Seq 35;46\n\u001b[36;46m Seq 36;46\n\u001b[36;47m Seq 36;47\n\u001b[37;40m Seq 37;40\n\u001b[37;41m Seq 37;41\n\u001b[30;40;1m Seq 30;40;1\n\u001b[30;41;1m Seq 30;41;1\n\u001b[37;46;1m Seq 37;46;1\n\u001b[37;47;1m Seq 37;47;1\n\u001b[90;102m Seq 90;102\n\u001b[90;103m Seq 90;103\n\u001b[97;106m Seq 97;106\n\u001b[97;107m Seq 97;107\n\u001b[90;40m Seq 90;40\n\u001b[90;41m Seq 90;41\n\u001b[97;46m Seq 97;46\n\u001b[97;47m Seq 97;47\n"
  },
  {
    "path": "test/examples/escseq/colourText0.ans.folded",
    "content": " 0 400   0   \u001b[0u Seq Unknown\n 0 400   0   \u001b[0m Seq 0\n 0 400   0   \u001b[1m Seq 1\n 0 400   0   \u001b[30m Seq 30\n 0 400   0   \u001b[31m Seq 31\n 0 400   0   \u001b[30;1m Seq 30;1\n 0 400   0   \u001b[31;1m Seq 31;1\n 0 400   0   \u001b[42m Seq 42\n 0 400   0   \u001b[43m Seq 43\n 0 400   0   \u001b[30;42m Seq 30;42\n 0 400   0   \u001b[30;43m Seq 30;43\n 0 400   0   \u001b[31;44m Seq 31;44\n 0 400   0   \u001b[31;45m Seq 31;45\n 0 400   0   \u001b[32;46m Seq 32;46\n 0 400   0   \u001b[32;47m Seq 32;47\n 0 400   0   \u001b[33;40m Seq 33;40\n 0 400   0   \u001b[33;41m Seq 33;41\n 0 400   0   \u001b[34;43m Seq 34;43\n 0 400   0   \u001b[34;44m Seq 34;44\n 0 400   0   \u001b[35;45m Seq 35;45\n 0 400   0   \u001b[35;46m Seq 35;46\n 0 400   0   \u001b[36;46m Seq 36;46\n 0 400   0   \u001b[36;47m Seq 36;47\n 0 400   0   \u001b[37;40m Seq 37;40\n 0 400   0   \u001b[37;41m Seq 37;41\n 0 400   0   \u001b[30;40;1m Seq 30;40;1\n 0 400   0   \u001b[30;41;1m Seq 30;41;1\n 0 400   0   \u001b[37;46;1m Seq 37;46;1\n 0 400   0   \u001b[37;47;1m Seq 37;47;1\n 0 400   0   \u001b[90;102m Seq 90;102\n 0 400   0   \u001b[90;103m Seq 90;103\n 0 400   0   \u001b[97;106m Seq 97;106\n 0 400   0   \u001b[97;107m Seq 97;107\n 0 400   0   \u001b[90;40m Seq 90;40\n 0 400   0   \u001b[90;41m Seq 90;41\n 0 400   0   \u001b[97;46m Seq 97;46\n 0 400   0   \u001b[97;47m Seq 97;47\n 0 400   0   "
  },
  {
    "path": "test/examples/escseq/colourText0.ans.styled",
    "content": "{172}\u001b[0u{0} Seq Unknown\n{171}\u001b[0m{0} Seq 0\n{171}\u001b[1m{0} Seq 1\n{171}\u001b[30m{0} Seq 30\n{171}\u001b[31m{0} Seq 31\n{171}\u001b[30;1m{0} Seq 30;1\n{171}\u001b[31;1m{0} Seq 31;1\n{171}\u001b[42m{0} Seq 42\n{171}\u001b[43m{0} Seq 43\n{171}\u001b[30;42m{0} Seq 30;42\n{171}\u001b[30;43m{0} Seq 30;43\n{171}\u001b[31;44m{0} Seq 31;44\n{171}\u001b[31;45m{0} Seq 31;45\n{171}\u001b[32;46m{0} Seq 32;46\n{171}\u001b[32;47m{0} Seq 32;47\n{171}\u001b[33;40m{0} Seq 33;40\n{171}\u001b[33;41m{0} Seq 33;41\n{171}\u001b[34;43m{0} Seq 34;43\n{171}\u001b[34;44m{0} Seq 34;44\n{171}\u001b[35;45m{0} Seq 35;45\n{171}\u001b[35;46m{0} Seq 35;46\n{171}\u001b[36;46m{0} Seq 36;46\n{171}\u001b[36;47m{0} Seq 36;47\n{171}\u001b[37;40m{0} Seq 37;40\n{171}\u001b[37;41m{0} Seq 37;41\n{171}\u001b[30;40;1m{0} Seq 30;40;1\n{171}\u001b[30;41;1m{0} Seq 30;41;1\n{171}\u001b[37;46;1m{0} Seq 37;46;1\n{171}\u001b[37;47;1m{0} Seq 37;47;1\n{171}\u001b[90;102m{0} Seq 90;102\n{171}\u001b[90;103m{0} Seq 90;103\n{171}\u001b[97;106m{0} Seq 97;106\n{171}\u001b[97;107m{0} Seq 97;107\n{171}\u001b[90;40m{0} Seq 90;40\n{171}\u001b[90;41m{0} Seq 90;41\n{171}\u001b[97;46m{0} Seq 97;46\n{171}\u001b[97;47m{0} Seq 97;47\n"
  },
  {
    "path": "test/examples/escseq/colourText1.ans",
    "content": "\u001b[0u Seq Unknown\n\u001b[0m Seq 0\n\u001b[1m Seq 1\n\u001b[30m Seq 30\n\u001b[31m Seq 31\n\u001b[30;1m Seq 30;1\n\u001b[31;1m Seq 31;1\n\u001b[42m Seq 42\n\u001b[43m Seq 43\n\u001b[30;42m Seq 30;42\n\u001b[30;43m Seq 30;43\n\u001b[31;44m Seq 31;44\n\u001b[31;45m Seq 31;45\n\u001b[32;46m Seq 32;46\n\u001b[32;47m Seq 32;47\n\u001b[33;40m Seq 33;40\n\u001b[33;41m Seq 33;41\n\u001b[34;43m Seq 34;43\n\u001b[34;44m Seq 34;44\n\u001b[35;45m Seq 35;45\n\u001b[35;46m Seq 35;46\n\u001b[36;46m Seq 36;46\n\u001b[36;47m Seq 36;47\n\u001b[37;40m Seq 37;40\n\u001b[37;41m Seq 37;41\n\u001b[30;40;1m Seq 30;40;1\n\u001b[30;41;1m Seq 30;41;1\n\u001b[37;46;1m Seq 37;46;1\n\u001b[37;47;1m Seq 37;47;1\n\u001b[90;102m Seq 90;102\n\u001b[90;103m Seq 90;103\n\u001b[97;106m Seq 97;106\n\u001b[97;107m Seq 97;107\n\u001b[90;40m Seq 90;40\n\u001b[90;41m Seq 90;41\n\u001b[97;46m Seq 97;46\n\u001b[97;47m Seq 97;47\n"
  },
  {
    "path": "test/examples/escseq/colourText1.ans.folded",
    "content": " 0 400   0   \u001b[0u Seq Unknown\n 0 400   0   \u001b[0m Seq 0\n 0 400   0   \u001b[1m Seq 1\n 0 400   0   \u001b[30m Seq 30\n 0 400   0   \u001b[31m Seq 31\n 0 400   0   \u001b[30;1m Seq 30;1\n 0 400   0   \u001b[31;1m Seq 31;1\n 0 400   0   \u001b[42m Seq 42\n 0 400   0   \u001b[43m Seq 43\n 0 400   0   \u001b[30;42m Seq 30;42\n 0 400   0   \u001b[30;43m Seq 30;43\n 0 400   0   \u001b[31;44m Seq 31;44\n 0 400   0   \u001b[31;45m Seq 31;45\n 0 400   0   \u001b[32;46m Seq 32;46\n 0 400   0   \u001b[32;47m Seq 32;47\n 0 400   0   \u001b[33;40m Seq 33;40\n 0 400   0   \u001b[33;41m Seq 33;41\n 0 400   0   \u001b[34;43m Seq 34;43\n 0 400   0   \u001b[34;44m Seq 34;44\n 0 400   0   \u001b[35;45m Seq 35;45\n 0 400   0   \u001b[35;46m Seq 35;46\n 0 400   0   \u001b[36;46m Seq 36;46\n 0 400   0   \u001b[36;47m Seq 36;47\n 0 400   0   \u001b[37;40m Seq 37;40\n 0 400   0   \u001b[37;41m Seq 37;41\n 0 400   0   \u001b[30;40;1m Seq 30;40;1\n 0 400   0   \u001b[30;41;1m Seq 30;41;1\n 0 400   0   \u001b[37;46;1m Seq 37;46;1\n 0 400   0   \u001b[37;47;1m Seq 37;47;1\n 0 400   0   \u001b[90;102m Seq 90;102\n 0 400   0   \u001b[90;103m Seq 90;103\n 0 400   0   \u001b[97;106m Seq 97;106\n 0 400   0   \u001b[97;107m Seq 97;107\n 0 400   0   \u001b[90;40m Seq 90;40\n 0 400   0   \u001b[90;41m Seq 90;41\n 0 400   0   \u001b[97;46m Seq 97;46\n 0 400   0   \u001b[97;47m Seq 97;47\n 0 400   0   "
  },
  {
    "path": "test/examples/escseq/colourText1.ans.styled",
    "content": "{172}\u001b[0u{0} Seq Unknown\n{171}\u001b[0m{0} Seq 0\n{171}\u001b[1m{90} Seq 1\n{171}\u001b[30m{1} Seq 30\n{171}\u001b[31m{2} Seq 31\n{171}\u001b[30;1m{91} Seq 30;1\n{171}\u001b[31;1m{92} Seq 31;1\n{171}\u001b[42m{27} Seq 42\n{171}\u001b[43m{45} Seq 43\n{171}\u001b[30;42m{28} Seq 30;42\n{171}\u001b[30;43m{46} Seq 30;43\n{171}\u001b[31;44m{56} Seq 31;44\n{171}\u001b[31;45m{65} Seq 31;45\n{171}\u001b[32;46m{75} Seq 32;46\n{171}\u001b[32;47m{84} Seq 32;47\n{171}\u001b[33;40m{13} Seq 33;40\n{171}\u001b[33;41m{22} Seq 33;41\n{171}\u001b[34;43m{50} Seq 34;43\n{171}\u001b[34;44m{59} Seq 34;44\n{171}\u001b[35;45m{69} Seq 35;45\n{171}\u001b[35;46m{78} Seq 35;46\n{171}\u001b[36;46m{79} Seq 36;46\n{171}\u001b[36;47m{88} Seq 36;47\n{171}\u001b[37;40m{17} Seq 37;40\n{171}\u001b[37;41m{26} Seq 37;41\n{171}\u001b[30;40;1m{100} Seq 30;40;1\n{171}\u001b[30;41;1m{109} Seq 30;41;1\n{171}\u001b[37;46;1m{161} Seq 37;46;1\n{171}\u001b[37;47;1m{170} Seq 37;47;1\n{171}\u001b[90;102m{118} Seq 90;102\n{171}\u001b[90;103m{127} Seq 90;103\n{171}\u001b[97;106m{161} Seq 97;106\n{171}\u001b[97;107m{170} Seq 97;107\n{171}\u001b[90;40m{100} Seq 90;40\n{171}\u001b[90;41m{109} Seq 90;41\n{171}\u001b[97;46m{161} Seq 97;46\n{171}\u001b[97;47m{170} Seq 97;47\n"
  },
  {
    "path": "test/examples/forth/AllStyles.forth",
    "content": "\\ SCE_FORTH_DEFAULT=0\n    \n\n\\ SCE_FORTH_COMMENT=1\n\\ line comment\n\n\\ SCE_FORTH_COMMENT_ML=2\n( stream comment )\n\n\\ SCE_FORTH_IDENTIFIER=3\nFOO\n\n\\ SCE_FORTH_CONTROL=4\nDO\nLOOP\n\n\\ SCE_FORTH_KEYWORD=5\n.S\n2DUP\nCR\n\n\\ SCE_FORTH_DEFWORD=6\n: WORD ;\n\n\\ SCE_FORTH_PREWORD1=7\nPOSTPONE WORD\n\n\\ SCE_FORTH_PREWORD2=8\nINCLUDE S\" module.forth\"\n\n\\ SCE_FORTH_NUMBER=9\n$7F\n%01111111\n127\n\n\\ SCE_FORTH_STRING=10\n.\" Hello, world.\"\nABORT\" Aborting...\"\n\n\\ SCE_FORTH_LOCALE=11\n{ local-var }\n"
  },
  {
    "path": "test/examples/forth/AllStyles.forth.folded",
    "content": " 0 400   0   \\ SCE_FORTH_DEFAULT=0\n 0 400   0       \n 0 400   0   \n 0 400   0   \\ SCE_FORTH_COMMENT=1\n 0 400   0   \\ line comment\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_COMMENT_ML=2\n 0 400   0   ( stream comment )\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_IDENTIFIER=3\n 0 400   0   FOO\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_CONTROL=4\n 0 400   0   DO\n 0 400   0   LOOP\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_KEYWORD=5\n 0 400   0   .S\n 0 400   0   2DUP\n 0 400   0   CR\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_DEFWORD=6\n 0 400   0   : WORD ;\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_PREWORD1=7\n 0 400   0   POSTPONE WORD\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_PREWORD2=8\n 0 400   0   INCLUDE S\" module.forth\"\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_NUMBER=9\n 0 400   0   $7F\n 0 400   0   %01111111\n 0 400   0   127\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_STRING=10\n 0 400   0   .\" Hello, world.\"\n 0 400   0   ABORT\" Aborting...\"\n 0 400   0   \n 0 400   0   \\ SCE_FORTH_LOCALE=11\n 0 400   0   { local-var }\n 0 400   0   "
  },
  {
    "path": "test/examples/forth/AllStyles.forth.styled",
    "content": "{1}\\ SCE_FORTH_DEFAULT=0{0}\n    \n\n{1}\\ SCE_FORTH_COMMENT=1{0}\n{1}\\ line comment{0}\n\n{1}\\ SCE_FORTH_COMMENT_ML=2{0}\n{2}( stream comment ){0}\n\n{1}\\ SCE_FORTH_IDENTIFIER=3{0}\n{3}FOO{0}\n\n{1}\\ SCE_FORTH_CONTROL=4{0}\n{4}DO{0}\n{4}LOOP{0}\n\n{1}\\ SCE_FORTH_KEYWORD=5{0}\n{5}.S{0}\n{5}2DUP{0}\n{5}CR{0}\n\n{1}\\ SCE_FORTH_DEFWORD=6{0}\n{6}: WORD{0} {6};{0}\n\n{1}\\ SCE_FORTH_PREWORD1=7{0}\n{7}POSTPONE{0} {3}WORD{0}\n\n{1}\\ SCE_FORTH_PREWORD2=8{0}\n{8}INCLUDE{0} {10}S\" module.forth\"{0}\n\n{1}\\ SCE_FORTH_NUMBER=9{0}\n{9}$7F{0}\n{9}%01111111{0}\n{9}127{0}\n\n{1}\\ SCE_FORTH_STRING=10{0}\n{10}.\" Hello, world.\"{0}\n{10}ABORT\" Aborting...\"{0}\n\n{1}\\ SCE_FORTH_LOCALE=11{0}\n{11}{ local-var }{0}\n"
  },
  {
    "path": "test/examples/forth/Issue351.forth",
    "content": ": \\DUP ( n - n n ) DUP ;\n: DUP\\ ( n - ) \\DUP 2DROP ;\n: (DROP ( n - ) DUP\\ 2 DROP ;\n: DROP( ( n - ) \\DUP DUP\\ (DROP ;\n: !FOO ;\n: 'BAR ;\n: ,BAZ ;\n: -QUX ;\n: @QUUX ;\n: _CORGE ;\n\n: OP_PREFIXES ( -)\n    !\n    2!\n    !FOO\n    #\n    #S\n    '\n    'BAR\n    *\n    */MOD\n    +!\n    ,\n    ,BAZ\n    -\n    -QUX\n    .\n    .S\n    /\n    /MOD\n    <\n    0<\n    =\n    0=\n    >\n    >NUMBER\n    ?\n    ?DUP\n    @\n    2@\n    @QUUX\n    [\n    ]\n    _CORGE\n;\n\n\\ redefine '\\' as a newline\n: \\ CR ;\n"
  },
  {
    "path": "test/examples/forth/Issue351.forth.folded",
    "content": " 0 400   0   : \\DUP ( n - n n ) DUP ;\n 0 400   0   : DUP\\ ( n - ) \\DUP 2DROP ;\n 0 400   0   : (DROP ( n - ) DUP\\ 2 DROP ;\n 0 400   0   : DROP( ( n - ) \\DUP DUP\\ (DROP ;\n 0 400   0   : !FOO ;\n 0 400   0   : 'BAR ;\n 0 400   0   : ,BAZ ;\n 0 400   0   : -QUX ;\n 0 400   0   : @QUUX ;\n 0 400   0   : _CORGE ;\n 0 400   0   \n 0 400   0   : OP_PREFIXES ( -)\n 0 400   0       !\n 0 400   0       2!\n 0 400   0       !FOO\n 0 400   0       #\n 0 400   0       #S\n 0 400   0       '\n 0 400   0       'BAR\n 0 400   0       *\n 0 400   0       */MOD\n 0 400   0       +!\n 0 400   0       ,\n 0 400   0       ,BAZ\n 0 400   0       -\n 0 400   0       -QUX\n 0 400   0       .\n 0 400   0       .S\n 0 400   0       /\n 0 400   0       /MOD\n 0 400   0       <\n 0 400   0       0<\n 0 400   0       =\n 0 400   0       0=\n 0 400   0       >\n 0 400   0       >NUMBER\n 0 400   0       ?\n 0 400   0       ?DUP\n 0 400   0       @\n 0 400   0       2@\n 0 400   0       @QUUX\n 0 400   0       [\n 0 400   0       ]\n 0 400   0       _CORGE\n 0 400   0   ;\n 0 400   0   \n 0 400   0   \\ redefine '\\' as a newline\n 0 400   0   : \\ CR ;\n 0 400   0   "
  },
  {
    "path": "test/examples/forth/Issue351.forth.styled",
    "content": "{6}: \\DUP{0} {2}( n - n n ){0} {5}DUP{0} {6};{0}\n{6}: DUP\\{0} {2}( n - ){0} {3}\\DUP{0} {5}2DROP{0} {6};{0}\n{6}: (DROP{0} {2}( n - ){0} {3}DUP\\{0} {9}2{0} {5}DROP{0} {6};{0}\n{6}: DROP({0} {2}( n - ){0} {3}\\DUP{0} {3}DUP\\{0} {3}(DROP{0} {6};{0}\n{6}: !FOO{0} {6};{0}\n{6}: 'BAR{0} {6};{0}\n{6}: ,BAZ{0} {6};{0}\n{6}: -QUX{0} {6};{0}\n{6}: @QUUX{0} {6};{0}\n{6}: _CORGE{0} {6};{0}\n\n{6}: OP_PREFIXES{0} {2}( -){0}\n    {5}!{0}\n    {5}2!{0}\n    {3}!FOO{0}\n    {3}#{0}\n    {3}#S{0}\n    {3}'{0}\n    {3}'BAR{0}\n    {3}*{0}\n    {3}*/MOD{0}\n    {3}+!{0}\n    {3},{0}\n    {3},BAZ{0}\n    {3}-{0}\n    {3}-QUX{0}\n    {5}.{0}\n    {5}.S{0}\n    {3}/{0}\n    {3}/MOD{0}\n    {3}<{0}\n    {3}0<{0}\n    {3}={0}\n    {3}0={0}\n    {3}>{0}\n    {3}>NUMBER{0}\n    {3}?{0}\n    {5}?DUP{0}\n    {5}@{0}\n    {5}2@{0}\n    {3}@QUUX{0}\n    {3}[{0}\n    {3}]{0}\n    {3}_CORGE{0}\n{6};{0}\n\n{1}\\ redefine '\\' as a newline{0}\n{6}: \\{0} {5}CR{0} {6};{0}\n"
  },
  {
    "path": "test/examples/forth/SciTE.properties",
    "content": "lexer.*.forth=forth\nkeywords.*.forth=begin do else if loop +loop repeat then until while\nkeywords2.*.forth=! @ . .s >in ?dup 2@ 2! 2dup 2drop 2over 2swap bye cr dup drop emit over rot space swap\nkeywords3.*.forth=: ;\nkeywords4.*.forth=['] ascii char compile postpone to with\nkeywords5.*.forth=include require\nkeywords6.*.forth=\" .\" abort\" c\" s\" z\"\n"
  },
  {
    "path": "test/examples/fortran/AllStyles.f",
    "content": "! Enumerate all styles: 0 to 14\n! This is not a viable source file, it just illustrates the different states in isolation.\n\n! comment=1\n! Comment\n\n! default=0\n\t! w\n\n! number=2\n.37\n\n! string1=3\n'string'\n\n! string2=4\n\"string\"\n\n! stringeol=5\n\" unclosed\n\n! operator=6\n+\n\n! identifier=7\nvariable\n\n! word=8\nprogram\n\n! word2=9\nsystem_clock\n\n! word3=10\ndoublecomplex\n\n! preprocessor=11\n!DEC$ ATTRIBUTES DLLEXPORT::sr1\n\n! operator2=12\n.lt.\n\n! label=13\n999\n\n! continuation=14\n&\n"
  },
  {
    "path": "test/examples/fortran/AllStyles.f.folded",
    "content": " 0 400   0   ! Enumerate all styles: 0 to 14\n 0 400   0   ! This is not a viable source file, it just illustrates the different states in isolation.\n 1 400   0   \n 0 400   0   ! comment=1\n 0 400   0   ! Comment\n 1 400   0   \n 0 400   0   ! default=0\n 0 400   0   \t! w\n 1 400   0   \n 0 400   0   ! number=2\n 0 400   0   .37\n 1 400   0   \n 0 400   0   ! string1=3\n 0 400   0   'string'\n 1 400   0   \n 0 400   0   ! string2=4\n 0 400   0   \"string\"\n 1 400   0   \n 0 400   0   ! stringeol=5\n 0 400   0   \" unclosed\n 1 400   0   \n 0 400   0   ! operator=6\n 0 400   0   +\n 1 400   0   \n 0 400   0   ! identifier=7\n 0 400   0   variable\n 1 400   0   \n 0 400   0   ! word=8\n 2 400   0 + program\n 1 401   0 | \n 0 401   0 | ! word2=9\n 0 401   0 | system_clock\n 1 401   0 | \n 0 401   0 | ! word3=10\n 0 401   0 | doublecomplex\n 1 401   0 | \n 0 401   0 | ! preprocessor=11\n 0 401   0 | !DEC$ ATTRIBUTES DLLEXPORT::sr1\n 1 401   0 | \n 0 401   0 | ! operator2=12\n 0 401   0 | .lt.\n 1 401   0 | \n 0 401   0 | ! label=13\n 0 401   0 | 999\n 1 401   0 | \n 0 401   0 | ! continuation=14\n 0 401   0 | &\n 0 400   0   "
  },
  {
    "path": "test/examples/fortran/AllStyles.f.styled",
    "content": "{1}! Enumerate all styles: 0 to 14{0}\n{1}! This is not a viable source file, it just illustrates the different states in isolation.{0}\n\n{1}! comment=1{0}\n{1}! Comment{0}\n\n{1}! default=0{0}\n\t{1}! w{0}\n\n{1}! number=2{0}\n{2}.37{0}\n\n{1}! string1=3{0}\n{3}'string'{0}\n\n{1}! string2=4{0}\n{4}\"string\"{0}\n\n{1}! stringeol=5{0}\n{5}\" unclosed\n{0}\n{1}! operator=6{0}\n{6}+{0}\n\n{1}! identifier=7{0}\n{7}variable{0}\n\n{1}! word=8{0}\n{8}program{0}\n\n{1}! word2=9{0}\n{9}system_clock{0}\n\n{1}! word3=10{0}\n{10}doublecomplex{0}\n\n{1}! preprocessor=11{0}\n{11}!DEC$ ATTRIBUTES DLLEXPORT::sr1{0}\n\n{1}! operator2=12{0}\n{12}.lt.{0}\n\n{1}! label=13{0}\n{13}999{0}\n\n{1}! continuation=14{0}\n{14}&{0}\n"
  },
  {
    "path": "test/examples/fortran/SciTE.properties",
    "content": "lexer.*.f=fortran\nkeywords.*.f=do end if program\nkeywords2.*.f=system_clock\nkeywords3.*.f=doublecomplex\nfold=1\nfold.compact=1\n"
  },
  {
    "path": "test/examples/fsharp/FmtSpecs.fs",
    "content": "module FormatSpecifiersTest\n\nlet x = List.fold (*) 24.5 [ 1.; 2.; 3. ]\n\nlet template =\n    $\"\"\"<html>\n  <%%@language=VBScript%%>\n  <%%-- comment --%%>\n  <script type=\"text/javascript\">\n    console.info(`Access time: ${{new Date().toLocaleTimeString()}}`);\n  </script>\n  <script type=\"text/vbscript\">dim e=\"%.9g{System.Math.Exp 1.}>\"</script>\n  <%%response.write(\"Last mod time: %A{System.DateTime.Now.ToString(\"yyyy-MM-dd h:mm:ss tt\")}\")%%>\n  <%% 'comment%%>\n  <%%dim pi=\"{System.Math.PI,-16}\"'comment%%>\n</html>\"\"\"\n\nlet template' (date: System.DateTime) =\n    $@\"\"\"<html>\n  <%%@language=VBScript%%>\n  <%%-- comment --%%>\n  <script type=\"\"text/javascript\"\">\n    console.info(`Access time: ${{new Date().toLocaleTimeString()}}`);\n  </script>\n  <script type=\"\"text/vbscript\"\">dim e=\"\"%.9g{System.Math.Exp 1.}>\"\"</script>\n  <%%response.write(\"\"Last mod time: %A{date}\"\")%%>\n  <%% 'comment%%>\n  <%%dim pi=\"\"{System.Math.PI,-16}\"\"'comment%%>\n</html>\"\"\"\n\n// expect \"147.00\"\nprintfn \"Speed: %.2f m/s\" x\nprintfn $\"Speed: %.2f{x} m/s\"\nprintfn $\"Speed: {x:f2} m/s\"\nprintfn $@\"Speed: %.2f{x} m/s\"\nprintfn @$\"Speed: {x:f2} m/s\"\n\n// expect \" 147%\"\nprintfn \"\"\"%% increase:% .0F%% over last year\"\"\" x\nprintfn $\"\"\"%% increase:% .0F{x}%% over last year\"\"\"\nprintfn $\"\"\"%% increase:{x / 100.,5:P0} over last year\"\"\"\nprintfn $@\"\"\"%% increase:% .0F{x}%% over last year\"\"\"\nprintfn @$\"\"\"%% increase:{x / 100.,5:P0} over last year\"\"\"\n\n// expect \"1.5E+002\"\n// NB: units should look like text even without a space\nprintfn @\"Time: %-0.1Esecs\" x\nprintfn $\"Time: %-0.1E{x}secs\"\nprintfn $\"Time: {x:E1}secs\"\nprintfn $@\"Time: %-0.1E{x}secs\"\nprintfn @$\"Time: {x:E1}secs\"\n\n// expect \"\\\"         +147\\\"\"\nprintfn @\"\"\"Temp: %+12.3g K\"\"\" x\nprintfn $\"\"\"{'\"'}Temp: %+12.3g{x} K{'\"'}\"\"\"\nprintfn $\"\"\"{'\"'}Temp: {'+',9}{x:g3} K{'\"'}\"\"\"\nprintfn $@\"\"\"Temp: %+12.3g{x} K\"\"\"\nprintfn @$\"\"\"Temp: {'+',9}{x:g3} K\"\"\"\n\n// Since F# 6.0\nprintfn @\"%B\" 0b1_000_000\nprintfn \"%B\" \"\\x40\"B.[0]\nprintfn $\"\"\"%B{'\\064'B}\"\"\"\nprintfn $@\"\"\"%B{0b1_000_000}\"\"\"\nprintfn @$\"\"\"%B{'\\064'B}\"\"\"\n\n// These don't work\nprintfn ``%.2f`` x\nprintfn $\"%.2f\" x\nprintfn $@\"%.2f\" x\nprintfn @$\"%.2f\" x\nprintfn $\"%.2f {x}\"\nprintfn $@\"%.2f {x}\"\nprintfn @$\"%.2f {x}\"\nprintfn $\"\"\"%.2f {x}\"\"\"\nprintfn $@\"\"\"%.2f {x}\"\"\"\nprintfn @$\"\"\"%.2f {x}\"\"\"\n"
  },
  {
    "path": "test/examples/fsharp/FmtSpecs.fs.folded",
    "content": " 0 400 400   module FormatSpecifiersTest\n 1 400 400   \n 0 400 400   let x = List.fold (*) 24.5 [ 1.; 2.; 3. ]\n 1 400 400   \n 0 400 400   let template =\n 2 400 401 +     $\"\"\"<html>\n 0 401 401 |   <%%@language=VBScript%%>\n 0 401 401 |   <%%-- comment --%%>\n 0 401 401 |   <script type=\"text/javascript\">\n 0 401 401 |     console.info(`Access time: ${{new Date().toLocaleTimeString()}}`);\n 0 401 401 |   </script>\n 0 401 401 |   <script type=\"text/vbscript\">dim e=\"%.9g{System.Math.Exp 1.}>\"</script>\n 0 401 401 |   <%%response.write(\"Last mod time: %A{System.DateTime.Now.ToString(\"yyyy-MM-dd h:mm:ss tt\")}\")%%>\n 0 401 401 |   <%% 'comment%%>\n 0 401 401 |   <%%dim pi=\"{System.Math.PI,-16}\"'comment%%>\n 0 401 400 | </html>\"\"\"\n 1 400 400   \n 0 400 400   let template' (date: System.DateTime) =\n 2 400 401 +     $@\"\"\"<html>\n 0 401 401 |   <%%@language=VBScript%%>\n 0 401 401 |   <%%-- comment --%%>\n 0 401 401 |   <script type=\"\"text/javascript\"\">\n 0 401 401 |     console.info(`Access time: ${{new Date().toLocaleTimeString()}}`);\n 0 401 401 |   </script>\n 0 401 401 |   <script type=\"\"text/vbscript\"\">dim e=\"\"%.9g{System.Math.Exp 1.}>\"\"</script>\n 0 401 401 |   <%%response.write(\"\"Last mod time: %A{date}\"\")%%>\n 0 401 401 |   <%% 'comment%%>\n 0 401 401 |   <%%dim pi=\"\"{System.Math.PI,-16}\"\"'comment%%>\n 0 401 400 | </html>\"\"\"\n 1 400 400   \n 0 400 400   // expect \"147.00\"\n 0 400 400   printfn \"Speed: %.2f m/s\" x\n 0 400 400   printfn $\"Speed: %.2f{x} m/s\"\n 0 400 400   printfn $\"Speed: {x:f2} m/s\"\n 0 400 400   printfn $@\"Speed: %.2f{x} m/s\"\n 0 400 400   printfn @$\"Speed: {x:f2} m/s\"\n 1 400 400   \n 0 400 400   // expect \" 147%\"\n 0 400 400   printfn \"\"\"%% increase:% .0F%% over last year\"\"\" x\n 0 400 400   printfn $\"\"\"%% increase:% .0F{x}%% over last year\"\"\"\n 0 400 400   printfn $\"\"\"%% increase:{x / 100.,5:P0} over last year\"\"\"\n 0 400 400   printfn $@\"\"\"%% increase:% .0F{x}%% over last year\"\"\"\n 0 400 400   printfn @$\"\"\"%% increase:{x / 100.,5:P0} over last year\"\"\"\n 1 400 400   \n 2 400 401 + // expect \"1.5E+002\"\n 0 401 400 | // NB: units should look like text even without a space\n 0 400 400   printfn @\"Time: %-0.1Esecs\" x\n 0 400 400   printfn $\"Time: %-0.1E{x}secs\"\n 0 400 400   printfn $\"Time: {x:E1}secs\"\n 0 400 400   printfn $@\"Time: %-0.1E{x}secs\"\n 0 400 400   printfn @$\"Time: {x:E1}secs\"\n 1 400 400   \n 0 400 400   // expect \"\\\"         +147\\\"\"\n 0 400 400   printfn @\"\"\"Temp: %+12.3g K\"\"\" x\n 0 400 400   printfn $\"\"\"{'\"'}Temp: %+12.3g{x} K{'\"'}\"\"\"\n 0 400 400   printfn $\"\"\"{'\"'}Temp: {'+',9}{x:g3} K{'\"'}\"\"\"\n 0 400 400   printfn $@\"\"\"Temp: %+12.3g{x} K\"\"\"\n 0 400 400   printfn @$\"\"\"Temp: {'+',9}{x:g3} K\"\"\"\n 1 400 400   \n 0 400 400   // Since F# 6.0\n 0 400 400   printfn @\"%B\" 0b1_000_000\n 0 400 400   printfn \"%B\" \"\\x40\"B.[0]\n 0 400 400   printfn $\"\"\"%B{'\\064'B}\"\"\"\n 0 400 400   printfn $@\"\"\"%B{0b1_000_000}\"\"\"\n 0 400 400   printfn @$\"\"\"%B{'\\064'B}\"\"\"\n 1 400 400   \n 0 400 400   // These don't work\n 0 400 400   printfn ``%.2f`` x\n 0 400 400   printfn $\"%.2f\" x\n 0 400 400   printfn $@\"%.2f\" x\n 0 400 400   printfn @$\"%.2f\" x\n 0 400 400   printfn $\"%.2f {x}\"\n 0 400 400   printfn $@\"%.2f {x}\"\n 0 400 400   printfn @$\"%.2f {x}\"\n 0 400 400   printfn $\"\"\"%.2f {x}\"\"\"\n 0 400 400   printfn $@\"\"\"%.2f {x}\"\"\"\n 0 400 400   printfn @$\"\"\"%.2f {x}\"\"\"\n 0 400   0   "
  },
  {
    "path": "test/examples/fsharp/FmtSpecs.fs.styled",
    "content": "{1}module{0} {6}FormatSpecifiersTest{0}\n\n{1}let{0} {6}x{0} {12}={0} {3}List{0}.{2}fold{0} {12}(*){0} {13}24.5{0} {12}[{0} {13}1.{12};{0} {13}2.{12};{0} {13}3.{0} {12}]{0}\n\n{1}let{0} {6}template{0} {12}={0}\n    {15}$\"\"\"<html>\n  <{19}%%{15}@language=VBScript{19}%%{15}>\n  <{19}%%{15}-- comment --{19}%%{15}>\n  <script type=\"text/javascript\">\n    console.info(`Access time: ${{new Date().toLocaleTimeString()}}`);\n  </script>\n  <script type=\"text/vbscript\">dim e=\"{19}%.9g{15}{System.Math.Exp 1.}>\"</script>\n  <{19}%%{15}response.write(\"Last mod time: {19}%A{15}{System.DateTime.Now.ToString(\"yyyy-MM-dd h:mm:ss tt\")}\"){19}%%{15}>\n  <{19}%%{15} 'comment{19}%%{15}>\n  <{19}%%{15}dim pi=\"{System.Math.PI{19},-16{15}}\"'comment{19}%%{15}>\n</html>\"\"\"{0}\n\n{1}let{0} {6}template'{0} {12}({6}date{12}:{0} {3}System{0}.{3}DateTime{12}){0} {12}={0}\n    {16}$@\"\"\"<html>\n  <{19}%%{16}@language=VBScript{19}%%{16}>\n  <{19}%%{16}-- comment --{19}%%{16}>\n  <script type=\"\"text/javascript\"\">\n    console.info(`Access time: ${{new Date().toLocaleTimeString()}}`);\n  </script>\n  <script type=\"\"text/vbscript\"\">dim e=\"\"{19}%.9g{16}{System.Math.Exp 1.}>\"\"</script>\n  <{19}%%{16}response.write(\"\"Last mod time: {19}%A{16}{date}\"\"){19}%%{16}>\n  <{19}%%{16} 'comment{19}%%{16}>\n  <{19}%%{16}dim pi=\"\"{System.Math.PI{19},-16{16}}\"\"'comment{19}%%{16}>\n</html>\"\"\"{0}\n\n{9}// expect \"147.00\"\n{2}printfn{0} {15}\"Speed: {19}%.2f{15} m/s\"{0} {6}x{0}\n{2}printfn{0} {15}$\"Speed: {19}%.2f{15}{x} m/s\"{0}\n{2}printfn{0} {15}$\"Speed: {x{19}:f2{15}} m/s\"{0}\n{2}printfn{0} {16}$@\"Speed: {19}%.2f{16}{x} m/s\"{0}\n{2}printfn{0} {16}@$\"Speed: {x{19}:f2{16}} m/s\"{0}\n\n{9}// expect \" 147%\"\n{2}printfn{0} {15}\"\"\"{19}%%{15} increase:{19}% .0F%%{15} over last year\"\"\"{0} {6}x{0}\n{2}printfn{0} {15}$\"\"\"{19}%%{15} increase:{19}% .0F{15}{x}{19}%%{15} over last year\"\"\"{0}\n{2}printfn{0} {15}$\"\"\"{19}%%{15} increase:{x / 100.{19},5:P0{15}} over last year\"\"\"{0}\n{2}printfn{0} {16}$@\"\"\"{19}%%{16} increase:{19}% .0F{16}{x}{19}%%{16} over last year\"\"\"{0}\n{2}printfn{0} {16}@$\"\"\"{19}%%{16} increase:{x / 100.{19},5:P0{16}} over last year\"\"\"{0}\n\n{9}// expect \"1.5E+002\"\n// NB: units should look like text even without a space\n{2}printfn{0} {16}@\"Time: {19}%-0.1E{16}secs\"{0} {6}x{0}\n{2}printfn{0} {15}$\"Time: {19}%-0.1E{15}{x}secs\"{0}\n{2}printfn{0} {15}$\"Time: {x{19}:E1{15}}secs\"{0}\n{2}printfn{0} {16}$@\"Time: {19}%-0.1E{16}{x}secs\"{0}\n{2}printfn{0} {16}@$\"Time: {x{19}:E1{16}}secs\"{0}\n\n{9}// expect \"\\\"         +147\\\"\"\n{2}printfn{0} {16}@\"\"\"Temp: {19}%+12.3g{16} K\"\"\"{0} {6}x{0}\n{2}printfn{0} {15}$\"\"\"{'\"'}Temp: {19}%+12.3g{15}{x} K{'\"'}\"\"\"{0}\n{2}printfn{0} {15}$\"\"\"{'\"'}Temp: {'+'{19},9{15}}{x{19}:g3{15}} K{'\"'}\"\"\"{0}\n{2}printfn{0} {16}$@\"\"\"Temp: {19}%+12.3g{16}{x} K\"\"\"{0}\n{2}printfn{0} {16}@$\"\"\"Temp: {'+'{19},9{16}}{x{19}:g3{16}} K\"\"\"{0}\n\n{9}// Since F# 6.0\n{2}printfn{0} {16}@\"{19}%B{16}\"{0} {13}0b1_000_000{0}\n{2}printfn{0} {15}\"{19}%B{15}\"{0} {15}\"\\x40\"B{0}.{12}[{13}0{12}]{0}\n{2}printfn{0} {15}$\"\"\"{19}%B{15}{'\\064'B}\"\"\"{0}\n{2}printfn{0} {16}$@\"\"\"{19}%B{16}{0b1_000_000}\"\"\"{0}\n{2}printfn{0} {16}@$\"\"\"{19}%B{16}{'\\064'B}\"\"\"{0}\n\n{9}// These don't work\n{2}printfn{0} {7}``%.2f``{0} {6}x{0}\n{2}printfn{0} {15}$\"%.2f\"{0} {6}x{0}\n{2}printfn{0} {16}$@\"%.2f\"{0} {6}x{0}\n{2}printfn{0} {16}@$\"%.2f\"{0} {6}x{0}\n{2}printfn{0} {15}$\"%.2f {x}\"{0}\n{2}printfn{0} {16}$@\"%.2f {x}\"{0}\n{2}printfn{0} {16}@$\"%.2f {x}\"{0}\n{2}printfn{0} {15}$\"\"\"%.2f {x}\"\"\"{0}\n{2}printfn{0} {16}$@\"\"\"%.2f {x}\"\"\"{0}\n{2}printfn{0} {16}@$\"\"\"%.2f {x}\"\"\"{0}\n"
  },
  {
    "path": "test/examples/fsharp/Issue352.fs",
    "content": "module Issue352\n\nlet asyncFn() = async {\n    let expr = backgroundTask { return 4L }\n    let (|Even|Odd|) n = if n % 2L |> (=) 0L then Even n else Odd\n    match! task { return! expr } |> Async.AwaitTask with\n    | Even n ->\n        return [ yield! seq { for i in 0L..2L..n do yield i } ]\n    | Odd ->\n        let! val' = expr |> Async.AwaitTask\n        printfn \"%s(%s): %d is odd.\"\n        <| System.IO.Path.Combine(__SOURCE_DIRECTORY__, __SOURCE_FILE__)\n        <| __LINE__\n        <| val'\n        return []\n}\n"
  },
  {
    "path": "test/examples/fsharp/Issue352.fs.folded",
    "content": " 0 400 400   module Issue352\n 1 400 400   \n 0 400 400   let asyncFn() = async {\n 0 400 400       let expr = backgroundTask { return 4L }\n 0 400 400       let (|Even|Odd|) n = if n % 2L |> (=) 0L then Even n else Odd\n 0 400 400       match! task { return! expr } |> Async.AwaitTask with\n 0 400 400       | Even n ->\n 0 400 400           return [ yield! seq { for i in 0L..2L..n do yield i } ]\n 0 400 400       | Odd ->\n 0 400 400           let! val' = expr |> Async.AwaitTask\n 0 400 400           printfn \"%s(%s): %d is odd.\"\n 0 400 400           <| System.IO.Path.Combine(__SOURCE_DIRECTORY__, __SOURCE_FILE__)\n 0 400 400           <| __LINE__\n 0 400 400           <| val'\n 0 400 400           return []\n 0 400 400   }\n 0 400   0   "
  },
  {
    "path": "test/examples/fsharp/Issue352.fs.styled",
    "content": "{1}module{0} {6}Issue352{0}\n\n{1}let{0} {6}asyncFn{1}(){0} {12}={0} {1}async{0} {12}{{0}\n    {1}let{0} {6}expr{0} {12}={0} {1}backgroundTask{0} {12}{{0} {1}return{0} {13}4L{0} {12}}{0}\n    {1}let{0} {12}(|{6}Even{12}|{6}Odd{12}|){0} {6}n{0} {12}={0} {1}if{0} {6}n{0} {12}%{0} {13}2L{0} {12}|>{0} {12}(=){0} {13}0L{0} {1}then{0} {6}Even{0} {6}n{0} {1}else{0} {6}Odd{0}\n    {1}match!{0} {1}task{0} {12}{{0} {1}return!{0} {6}expr{0} {12}}{0} {12}|>{0} {6}Async{0}.{6}AwaitTask{0} {1}with{0}\n    {12}|{0} {6}Even{0} {6}n{0} {12}->{0}\n        {1}return{0} {12}[{0} {1}yield!{0} {2}seq{0} {12}{{0} {1}for{0} {6}i{0} {1}in{0} {13}0L{0}..{13}2L{0}..{6}n{0} {1}do{0} {1}yield{0} {6}i{0} {12}}{0} {12}]{0}\n    {12}|{0} {6}Odd{0} {12}->{0}\n        {1}let!{0} {6}val'{0} {12}={0} {6}expr{0} {12}|>{0} {6}Async{0}.{6}AwaitTask{0}\n        {2}printfn{0} {15}\"{19}%s{15}({19}%s{15}): {19}%d{15} is odd.\"{0}\n        {12}<|{0} {3}System{0}.{3}IO{0}.{6}Path{0}.{6}Combine{12}({1}__SOURCE_DIRECTORY__{12},{0} {1}__SOURCE_FILE__{12}){0}\n        {12}<|{0} {1}__LINE__{0}\n        {12}<|{0} {6}val'{0}\n        {1}return{0} {1}[]{0}\n{12}}{0}\n"
  },
  {
    "path": "test/examples/fsharp/Issue56.fs",
    "content": "// not folded\n\n// first line in comment fold\n// second . . .\n// third . . .\nnamespace Issue56\n\nopen System\n\nmodule LineBasedFoldingCheck =\n    open FSharp.Quotations\n    open FSharp.Reflection\n\n    () |> ignore\n"
  },
  {
    "path": "test/examples/fsharp/Issue56.fs.folded",
    "content": " 0 400 400   // not folded\n 1 400 400   \n 2 400 401 + // first line in comment fold\n 0 401 401 | // second . . .\n 0 401 400 | // third . . .\n 0 400 400   namespace Issue56\n 1 400 400   \n 0 400 400   open System\n 1 400 400   \n 0 400 400   module LineBasedFoldingCheck =\n 2 400 401 +     open FSharp.Quotations\n 0 401 400 |     open FSharp.Reflection\n 1 400 400   \n 0 400 400       () |> ignore\n 0 400   0   "
  },
  {
    "path": "test/examples/fsharp/Issue56.fs.styled",
    "content": "{9}// not folded\n{0}\n{9}// first line in comment fold\n// second . . .\n// third . . .\n{1}namespace{0} {6}Issue56{0}\n\n{1}open{0} {3}System{0}\n\n{1}module{0} {6}LineBasedFoldingCheck{0} {12}={0}\n    {1}open{0} {3}FSharp{0}.{6}Quotations{0}\n    {1}open{0} {3}FSharp{0}.{6}Reflection{0}\n\n    {1}(){0} {12}|>{0} {2}ignore{0}\n"
  },
  {
    "path": "test/examples/fsharp/Issue93.fs",
    "content": "(*\n    (**  nested comment 1 **)\n    (*\n        nested comment 2\n        (*\n            nested comment 3\n            (*\n                nested comment 4\n                (*\n                    nested comment 5\n                *)\n            *)\n        *)\n    *)\n*)\n// declare a namespace\n// for the module\nnamespace Issue93\n\nmodule NestedComments =\n    open FSharp.Quotations\n    open FSharp.Quotations.Patterns\n    // print the arguments\n    // of an evaluated expression\n    (* Example:\n        (*\n            printArgs <@ 1 + 2 @> ;;\n            // 1\n            // 2\n        *)\n    *)\n    let printArgs expr =\n        let getVal = function Value (v, _) -> downcast v | _ -> null\n        match expr with\n        | Call (_, _, args) ->\n            List.map getVal args |> List.iter (printfn \"%A\")\n        | _ ->\n            printfn \"not an evaluated expression\"\n    (* Example:\n        (*\n            let constExpr = <@ true @> ;;\n            printArgs constExpr ;;\n        *)\n    *)\n    // Prints:\n    // \"not an evaluated expression\"\n"
  },
  {
    "path": "test/examples/fsharp/Issue93.fs.folded",
    "content": " 2 400 401 + (*\n 0 401 401 |     (**  nested comment 1 **)\n 2 401 402 +     (*\n 0 402 402 |         nested comment 2\n 2 402 403 +         (*\n 0 403 403 |             nested comment 3\n 2 403 404 +             (*\n 0 404 404 |                 nested comment 4\n 2 404 405 +                 (*\n 0 405 405 |                     nested comment 5\n 0 405 404 |                 *)\n 0 404 403 |             *)\n 0 403 402 |         *)\n 0 402 401 |     *)\n 0 401 400 | *)\n 2 400 401 + // declare a namespace\n 0 401 400 | // for the module\n 0 400 400   namespace Issue93\n 1 400 400   \n 0 400 400   module NestedComments =\n 2 400 401 +     open FSharp.Quotations\n 0 401 400 |     open FSharp.Quotations.Patterns\n 2 400 401 +     // print the arguments\n 0 401 400 |     // of an evaluated expression\n 2 400 401 +     (* Example:\n 2 401 402 +         (*\n 0 402 402 |             printArgs <@ 1 + 2 @> ;;\n 0 402 402 |             // 1\n 0 402 402 |             // 2\n 0 402 401 |         *)\n 0 401 400 |     *)\n 0 400 400       let printArgs expr =\n 0 400 400           let getVal = function Value (v, _) -> downcast v | _ -> null\n 0 400 400           match expr with\n 0 400 400           | Call (_, _, args) ->\n 0 400 400               List.map getVal args |> List.iter (printfn \"%A\")\n 0 400 400           | _ ->\n 0 400 400               printfn \"not an evaluated expression\"\n 2 400 401 +     (* Example:\n 2 401 402 +         (*\n 0 402 402 |             let constExpr = <@ true @> ;;\n 0 402 402 |             printArgs constExpr ;;\n 0 402 401 |         *)\n 0 401 400 |     *)\n 2 400 401 +     // Prints:\n 0 401 400 |     // \"not an evaluated expression\"\n 0 400   0   "
  },
  {
    "path": "test/examples/fsharp/Issue93.fs.styled",
    "content": "{8}(*\n    (**  nested comment 1 **)\n    (*\n        nested comment 2\n        (*\n            nested comment 3\n            (*\n                nested comment 4\n                (*\n                    nested comment 5\n                *)\n            *)\n        *)\n    *)\n*){0}\n{9}// declare a namespace\n// for the module\n{1}namespace{0} {6}Issue93{0}\n\n{1}module{0} {6}NestedComments{0} {12}={0}\n    {1}open{0} {3}FSharp{0}.{6}Quotations{0}\n    {1}open{0} {3}FSharp{0}.{6}Quotations{0}.{6}Patterns{0}\n    {9}// print the arguments\n{0}    {9}// of an evaluated expression\n{0}    {8}(* Example:\n        (*\n            printArgs <@ 1 + 2 @> ;;\n            // 1\n            // 2\n        *)\n    *){0}\n    {1}let{0} {6}printArgs{0} {6}expr{0} {12}={0}\n        {1}let{0} {6}getVal{0} {12}={0} {1}function{0} {6}Value{0} {12}({6}v{12},{0} {6}_{12}){0} {12}->{0} {1}downcast{0} {6}v{0} {12}|{0} {6}_{0} {12}->{0} {1}null{0}\n        {1}match{0} {6}expr{0} {1}with{0}\n        {12}|{0} {6}Call{0} {12}({6}_{12},{0} {6}_{12},{0} {6}args{12}){0} {12}->{0}\n            {3}List{0}.{2}map{0} {6}getVal{0} {6}args{0} {12}|>{0} {3}List{0}.{2}iter{0} {12}({2}printfn{0} {15}\"{19}%A{15}\"{12}){0}\n        {12}|{0} {6}_{0} {12}->{0}\n            {2}printfn{0} {15}\"not an evaluated expression\"{0}\n    {8}(* Example:\n        (*\n            let constExpr = <@ true @> ;;\n            printArgs constExpr ;;\n        *)\n    *){0}\n    {9}// Prints:\n{0}    {9}// \"not an evaluated expression\"\n"
  },
  {
    "path": "test/examples/fsharp/Literals.fs",
    "content": "namespace Literals\n\nmodule Issue110 =\n    let hexA = +0xA1B2C3D4\n    let hexB = -0xCC100000\n\n    // regression checks\n    let hexC = 0xCC100000\n    let binA = +0b0000_1010\n    let binB = -0b1010_0000\n    let binC = 0b1010_0000\n    let octA = +0o1237777700\n    let octB = -0o1237777700\n    let octC = 0o1237777700\n    let i8a = +0001y\n    let i8b = -0001y\n    let u8 = 0001uy\n    let f32a = +0.001e-003\n    let f32b = -0.001E+003\n    let f32c = 0.001e-003\n    let f128a = +0.001m\n    let f128b = -0.001m\n    let f128c = 0.001m\n\n    // invalid literals\n    let hexD = 0xa0bcde0o\n    let hexE = +0xa0bcd0o\n    let hexF = -0xa0bcd0o\n    let binD = 0b1010_1110xf000\n    let binE = +0b1010_1110xf000\n    let binF = -0b1010_1110xf000\n    let binG = 0b1010_1110o\n    let binH = +0b1010_1110o\n    let binI = -0b1010_1110o\n    let octD = 0o3330xaBcDeF\n    let octE = +0o3330xaBcDe\n    let octF = -0o3330xaBcDe\n    let octG = 0o3330b\n    let octH = 0o3330b\n    let octI = 0o3330b\n\nmodule Issue111 =\n    // invalid literals\n    let a = 0000_123abc\n    let b = +000_123abc\n    let c = -0001_23abc\n    let d = 00123_000b\n    let e = +0123_000o\n    let f = -0123_000xcd\n\nmodule Issue112 =\n    let i64 = 0001L\n    let u64 = 001UL\n    let f32a = 001.F\n    let f32b = +01.0F\n    let f32c = -01.00000F\n    let f32d = 0b0000_0010lf\n    let f32e = 0o000_010lf\n    let f32f = 0x0000000000000010lf\n    let f64a = 0b0000_0010LF\n    let f64b = 0o000_010LF\n    let f64c = 0x0000000000000010LF\n    let f128a = 001.M\n    let f128b = +01.0M\n    let f128c = -01.00000M\n\n    // regression checks\n    let i32 = -0001l\n    let u32 = +001ul\n    let i128 = 9999999999999999999999999999I\n    let f32g = 001.f\n    let f32h = +01.0f\n    let f32i = -01.00000f\n    let f64d = 010000e+009\n    let f64e = +001.0e-009\n    let f64f = -001.e+009\n    let f128d = 001.m\n    let f128e = +01.0m\n    let f128f = -01.00000m\n\n    // arithmetic expressions\n    let a = -001.f+01.0F\n    let b = +0b0111_111UL-0x100UL\n    let c = -01.0F + +001.f\n    let d = -0x100UL - +0b0111_111UL\n"
  },
  {
    "path": "test/examples/fsharp/Literals.fs.folded",
    "content": " 0 400 400   namespace Literals\n 1 400 400   \n 0 400 400   module Issue110 =\n 0 400 400       let hexA = +0xA1B2C3D4\n 0 400 400       let hexB = -0xCC100000\n 1 400 400   \n 0 400 400       // regression checks\n 0 400 400       let hexC = 0xCC100000\n 0 400 400       let binA = +0b0000_1010\n 0 400 400       let binB = -0b1010_0000\n 0 400 400       let binC = 0b1010_0000\n 0 400 400       let octA = +0o1237777700\n 0 400 400       let octB = -0o1237777700\n 0 400 400       let octC = 0o1237777700\n 0 400 400       let i8a = +0001y\n 0 400 400       let i8b = -0001y\n 0 400 400       let u8 = 0001uy\n 0 400 400       let f32a = +0.001e-003\n 0 400 400       let f32b = -0.001E+003\n 0 400 400       let f32c = 0.001e-003\n 0 400 400       let f128a = +0.001m\n 0 400 400       let f128b = -0.001m\n 0 400 400       let f128c = 0.001m\n 1 400 400   \n 0 400 400       // invalid literals\n 0 400 400       let hexD = 0xa0bcde0o\n 0 400 400       let hexE = +0xa0bcd0o\n 0 400 400       let hexF = -0xa0bcd0o\n 0 400 400       let binD = 0b1010_1110xf000\n 0 400 400       let binE = +0b1010_1110xf000\n 0 400 400       let binF = -0b1010_1110xf000\n 0 400 400       let binG = 0b1010_1110o\n 0 400 400       let binH = +0b1010_1110o\n 0 400 400       let binI = -0b1010_1110o\n 0 400 400       let octD = 0o3330xaBcDeF\n 0 400 400       let octE = +0o3330xaBcDe\n 0 400 400       let octF = -0o3330xaBcDe\n 0 400 400       let octG = 0o3330b\n 0 400 400       let octH = 0o3330b\n 0 400 400       let octI = 0o3330b\n 1 400 400   \n 0 400 400   module Issue111 =\n 0 400 400       // invalid literals\n 0 400 400       let a = 0000_123abc\n 0 400 400       let b = +000_123abc\n 0 400 400       let c = -0001_23abc\n 0 400 400       let d = 00123_000b\n 0 400 400       let e = +0123_000o\n 0 400 400       let f = -0123_000xcd\n 1 400 400   \n 0 400 400   module Issue112 =\n 0 400 400       let i64 = 0001L\n 0 400 400       let u64 = 001UL\n 0 400 400       let f32a = 001.F\n 0 400 400       let f32b = +01.0F\n 0 400 400       let f32c = -01.00000F\n 0 400 400       let f32d = 0b0000_0010lf\n 0 400 400       let f32e = 0o000_010lf\n 0 400 400       let f32f = 0x0000000000000010lf\n 0 400 400       let f64a = 0b0000_0010LF\n 0 400 400       let f64b = 0o000_010LF\n 0 400 400       let f64c = 0x0000000000000010LF\n 0 400 400       let f128a = 001.M\n 0 400 400       let f128b = +01.0M\n 0 400 400       let f128c = -01.00000M\n 1 400 400   \n 0 400 400       // regression checks\n 0 400 400       let i32 = -0001l\n 0 400 400       let u32 = +001ul\n 0 400 400       let i128 = 9999999999999999999999999999I\n 0 400 400       let f32g = 001.f\n 0 400 400       let f32h = +01.0f\n 0 400 400       let f32i = -01.00000f\n 0 400 400       let f64d = 010000e+009\n 0 400 400       let f64e = +001.0e-009\n 0 400 400       let f64f = -001.e+009\n 0 400 400       let f128d = 001.m\n 0 400 400       let f128e = +01.0m\n 0 400 400       let f128f = -01.00000m\n 1 400 400   \n 0 400 400       // arithmetic expressions\n 0 400 400       let a = -001.f+01.0F\n 0 400 400       let b = +0b0111_111UL-0x100UL\n 0 400 400       let c = -01.0F + +001.f\n 0 400 400       let d = -0x100UL - +0b0111_111UL\n 0 400   0   "
  },
  {
    "path": "test/examples/fsharp/Literals.fs.styled",
    "content": "{1}namespace{0} {6}Literals{0}\n\n{1}module{0} {6}Issue110{0} {12}={0}\n    {1}let{0} {6}hexA{0} {12}={0} {13}+0xA1B2C3D4{0}\n    {1}let{0} {6}hexB{0} {12}={0} {13}-0xCC100000{0}\n\n    {9}// regression checks\n{0}    {1}let{0} {6}hexC{0} {12}={0} {13}0xCC100000{0}\n    {1}let{0} {6}binA{0} {12}={0} {13}+0b0000_1010{0}\n    {1}let{0} {6}binB{0} {12}={0} {13}-0b1010_0000{0}\n    {1}let{0} {6}binC{0} {12}={0} {13}0b1010_0000{0}\n    {1}let{0} {6}octA{0} {12}={0} {13}+0o1237777700{0}\n    {1}let{0} {6}octB{0} {12}={0} {13}-0o1237777700{0}\n    {1}let{0} {6}octC{0} {12}={0} {13}0o1237777700{0}\n    {1}let{0} {6}i8a{0} {12}={0} {13}+0001y{0}\n    {1}let{0} {6}i8b{0} {12}={0} {13}-0001y{0}\n    {1}let{0} {6}u8{0} {12}={0} {13}0001uy{0}\n    {1}let{0} {6}f32a{0} {12}={0} {13}+0.001e-003{0}\n    {1}let{0} {6}f32b{0} {12}={0} {13}-0.001E+003{0}\n    {1}let{0} {6}f32c{0} {12}={0} {13}0.001e-003{0}\n    {1}let{0} {6}f128a{0} {12}={0} {13}+0.001m{0}\n    {1}let{0} {6}f128b{0} {12}={0} {13}-0.001m{0}\n    {1}let{0} {6}f128c{0} {12}={0} {13}0.001m{0}\n\n    {9}// invalid literals\n{0}    {1}let{0} {6}hexD{0} {12}={0} {13}0xa0bcde0{0}o\n    {1}let{0} {6}hexE{0} {12}={0} {13}+0xa0bcd0{0}o\n    {1}let{0} {6}hexF{0} {12}={0} {13}-0xa0bcd0{0}o\n    {1}let{0} {6}binD{0} {12}={0} {13}0b1010_1110{0}x{6}f000{0}\n    {1}let{0} {6}binE{0} {12}={0} {13}+0b1010_1110{0}x{6}f000{0}\n    {1}let{0} {6}binF{0} {12}={0} {13}-0b1010_1110{0}x{6}f000{0}\n    {1}let{0} {6}binG{0} {12}={0} {13}0b1010_1110{0}o\n    {1}let{0} {6}binH{0} {12}={0} {13}+0b1010_1110{0}o\n    {1}let{0} {6}binI{0} {12}={0} {13}-0b1010_1110{0}o\n    {1}let{0} {6}octD{0} {12}={0} {13}0o3330{0}x{6}aBcDeF{0}\n    {1}let{0} {6}octE{0} {12}={0} {13}+0o3330{0}x{6}aBcDe{0}\n    {1}let{0} {6}octF{0} {12}={0} {13}-0o3330{0}x{6}aBcDe{0}\n    {1}let{0} {6}octG{0} {12}={0} {13}0o3330{0}b\n    {1}let{0} {6}octH{0} {12}={0} {13}0o3330{0}b\n    {1}let{0} {6}octI{0} {12}={0} {13}0o3330{0}b\n\n{1}module{0} {6}Issue111{0} {12}={0}\n    {9}// invalid literals\n{0}    {1}let{0} {6}a{0} {12}={0} {13}0000_123{0}a{6}bc{0}\n    {1}let{0} {6}b{0} {12}={0} {13}+000_123{0}a{6}bc{0}\n    {1}let{0} {6}c{0} {12}={0} {13}-0001_23{0}a{6}bc{0}\n    {1}let{0} {6}d{0} {12}={0} {13}00123_000{0}b\n    {1}let{0} {6}e{0} {12}={0} {13}+0123_000{0}o\n    {1}let{0} {6}f{0} {12}={0} {13}-0123_000{0}x{6}cd{0}\n\n{1}module{0} {6}Issue112{0} {12}={0}\n    {1}let{0} {6}i64{0} {12}={0} {13}0001L{0}\n    {1}let{0} {6}u64{0} {12}={0} {13}001UL{0}\n    {1}let{0} {6}f32a{0} {12}={0} {13}001.F{0}\n    {1}let{0} {6}f32b{0} {12}={0} {13}+01.0F{0}\n    {1}let{0} {6}f32c{0} {12}={0} {13}-01.00000F{0}\n    {1}let{0} {6}f32d{0} {12}={0} {13}0b0000_0010lf{0}\n    {1}let{0} {6}f32e{0} {12}={0} {13}0o000_010lf{0}\n    {1}let{0} {6}f32f{0} {12}={0} {13}0x0000000000000010lf{0}\n    {1}let{0} {6}f64a{0} {12}={0} {13}0b0000_0010LF{0}\n    {1}let{0} {6}f64b{0} {12}={0} {13}0o000_010LF{0}\n    {1}let{0} {6}f64c{0} {12}={0} {13}0x0000000000000010LF{0}\n    {1}let{0} {6}f128a{0} {12}={0} {13}001.M{0}\n    {1}let{0} {6}f128b{0} {12}={0} {13}+01.0M{0}\n    {1}let{0} {6}f128c{0} {12}={0} {13}-01.00000M{0}\n\n    {9}// regression checks\n{0}    {1}let{0} {6}i32{0} {12}={0} {13}-0001l{0}\n    {1}let{0} {6}u32{0} {12}={0} {13}+001ul{0}\n    {1}let{0} {6}i128{0} {12}={0} {13}9999999999999999999999999999I{0}\n    {1}let{0} {6}f32g{0} {12}={0} {13}001.f{0}\n    {1}let{0} {6}f32h{0} {12}={0} {13}+01.0f{0}\n    {1}let{0} {6}f32i{0} {12}={0} {13}-01.00000f{0}\n    {1}let{0} {6}f64d{0} {12}={0} {13}010000e+009{0}\n    {1}let{0} {6}f64e{0} {12}={0} {13}+001.0e-009{0}\n    {1}let{0} {6}f64f{0} {12}={0} {13}-001.e+009{0}\n    {1}let{0} {6}f128d{0} {12}={0} {13}001.m{0}\n    {1}let{0} {6}f128e{0} {12}={0} {13}+01.0m{0}\n    {1}let{0} {6}f128f{0} {12}={0} {13}-01.00000m{0}\n\n    {9}// arithmetic expressions\n{0}    {1}let{0} {6}a{0} {12}={0} {13}-001.f{12}+{13}01.0F{0}\n    {1}let{0} {6}b{0} {12}={0} {13}+0b0111_111UL{12}-{13}0x100UL{0}\n    {1}let{0} {6}c{0} {12}={0} {13}-01.0F{0} {12}+{0} {13}+001.f{0}\n    {1}let{0} {6}d{0} {12}={0} {13}-0x100UL{0} {12}-{0} {13}+0b0111_111UL{0}\n"
  },
  {
    "path": "test/examples/fsharp/SciTE.properties",
    "content": "lexer.*.fs=fsharp\n\nkeywords.*.fs= \\\nasync task backgroundTask \\\nabstract and as assert base begin class default delegate do done downcast \\\ndownto elif else end exception extern false finally fixed for fun function \\\nglobal if in inherit inline interface internal lazy let let! match match! \\\nmember module mutable namespace new null of open or override private public \\\nrec return return! select static struct then to true try type upcast use use! \\\nval void when while with yield yield! atomic break checked component const \\\nconstraint constructor continue eager event external fixed functor global \\\ninclude method mixin object parallel process protected pure sealed tailcall \\\ntrait virtual volatile\n\nkeywords2.*.fs= \\\nasr land lor lsl lsr lxor mod sig abs acos add allPairs append asin atan atan2 \\\naverage averageBy base1 base2 blit cache cast ceil choose \\\nchunkBySize collect compareWith concat contains containsKey copy cos cosh count \\\ncountBy create createBased delay difference distinct distinctBy empty eprintf except \\\nexists exists2 exactlyOne failwith fill filter find findBack findIndex findIndexBack \\\nfindKey floor fold fold2 foldBack foldBack2 forall forall2 fprintf fst get groupBy head ignore indexed \\\ninit initBased initInfinite intersect intersectMany invalidArg isEmpty isProperSubset \\\nisProperSuperset isSubset isSuperset item iter iter2 iteri iteri2 last length \\\nlength1 length2 length3 length4 map map2 map3 mapFold mapFoldBack mapi mapi2 \\\nmax maxBy maxElement min minBy minElement nameof not ofArray ofList ofSeq pairwise partition \\\npermute pick pown printf printfn raise readonly rebase reduce reduceBack remove replicate rev round scan \\\nscanBack seq set sin sinh singleton skip skipWhile snd sort sortBy sortByDescending sortDescending \\\nsortInPlace sortInPlaceBy sortInPlaceWith sortWith splitAt splitInto sprintf sqrt sub sum \\\nsumBy tail take takeWhile tan tanh toArray toList toSeq transpose truncate \\\ntryExactlyOne tryFind tryFindBack tryFindIndex tryFindIndexBack tryHead \\\ntryItem tryFindKey tryLast tryPick typeof unfold union unionMany unzip unzip3 where \\\nwindowed zeroCreate zeroCreateBased zip zip3\n\nkeywords3.*.fs= \\\nArgumentException Array Array2D Array3D Array4D BigInteger Boolean Byte Char Collections Core CultureInfo DateTime Decimal Double \\\nEnvironment Expr Float FSharp Globalization Int16 Int32 Int64 IntPtr IO Linq List Map Math Microsoft NumberStyles \\\nObject Parallel Printf Random ResizeArray SByte Seq Set Single String System UInt16 UInt32 UInt64 UIntPtr \\\narray bigint bool byte byref char comparison decimal double enum equality Error Exception exn float float32 inref int int8 int16 \\\nint32 int64 list nativeint nativeptr None obj Ok option Option outref ref Result sbyte Some single string unmanaged unativeint \\\nuint uint8 uint16 uint32 uint64 unit void voidptr voption\n\nfold.fsharp.preprocessor=1\nfold.fsharp.quotes=1\nfold.comment=1\n\n"
  },
  {
    "path": "test/examples/fsharp/x.fs",
    "content": "// x.fs\n// Sample source file to test F# syntax highlighting\n\n[<AutoOpen>]\nmodule Example\n\n#line 7 \"A compiler directive\"\n#if DEBUG\n  open System\n  open System.IO\n  open System.Diagnostics\n#endif\n\n# 14 @\"See: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/strings#remarks\"\n// verbatim string\nlet xmlFragment1 = @\"<book href=\"\"https://www.worldcat.org/title/paradise-lost/oclc/1083714070\"\" title=\"\"Paradise Lost\"\">\"\n\n// triple-quoted string\nlet xmlFragment2 = \"\"\"<book href=\"https://www.worldcat.org/title/paradise-lost/oclc/1083714070\" title=\"Paradise Lost\">\"\"\"\n\n(* you need .NET 5.0 to compile this:\n  https://docs.microsoft.com/en-us/dotnet/fsharp/whats-new/fsharp-50#string-interpolation\n*)\nlet interpolated = $\"\"\"C:\\{System.DateTime.Now.ToString(\"yyyy-MM-dd\")}\\\"\"\" + $\"{System.Random().Next(System.Int32.MaxValue)}.log\"\n\nlet ``a byte literal`` = '\\209'B\n\n// quoted expression\nlet expr =\n    <@@\n        let foo () = \"bar\"\n        foo ()\n    @@>\n\nlet bigNum (unused: 'a): float option =\n    Seq.init 10_000 (float >> (fun i -> i + 11.))\n    |> (List.ofSeq\n        >> List.take 5\n        >> List.fold (*) 1.0)\n    |> Some\n\nmatch bigNum () with\n| Some num -> sprintf \"%.2f > %u\" num ``a byte literal``\n| None -> sprintf \"%A\" \"Have a byte string!\"B\n|> printfn \"%s\"\n\n// GitHub Issue #38\nlet unescapeWinPath (path: string) =\n    path.Replace(\"\\\\\\\\\", \"\\\\\").Replace(\"\\\"\", \"\")\n\nunescapeWinPath \"\\\\\\\"Program Files (x86)\\\\Windows NT\\\\Accessories\\\\\\\"\"\n|> System.IO.Directory.GetFiles\n|> printfn \"%A\"\n"
  },
  {
    "path": "test/examples/fsharp/x.fs.folded",
    "content": " 2 400 401 + // x.fs\n 0 401 400 | // Sample source file to test F# syntax highlighting\n 1 400 400   \n 0 400 400   [<AutoOpen>]\n 0 400 400   module Example\n 1 400 400   \n 0 400 400   #line 7 \"A compiler directive\"\n 2 400 401 + #if DEBUG\n 2 401 402 +   open System\n 0 402 402 |   open System.IO\n 0 402 401 |   open System.Diagnostics\n 0 401 400 | #endif\n 1 400 400   \n 0 400 400   # 14 @\"See: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/strings#remarks\"\n 0 400 400   // verbatim string\n 0 400 400   let xmlFragment1 = @\"<book href=\"\"https://www.worldcat.org/title/paradise-lost/oclc/1083714070\"\" title=\"\"Paradise Lost\"\">\"\n 1 400 400   \n 0 400 400   // triple-quoted string\n 0 400 400   let xmlFragment2 = \"\"\"<book href=\"https://www.worldcat.org/title/paradise-lost/oclc/1083714070\" title=\"Paradise Lost\">\"\"\"\n 1 400 400   \n 2 400 401 + (* you need .NET 5.0 to compile this:\n 0 401 401 |   https://docs.microsoft.com/en-us/dotnet/fsharp/whats-new/fsharp-50#string-interpolation\n 0 401 400 | *)\n 0 400 400   let interpolated = $\"\"\"C:\\{System.DateTime.Now.ToString(\"yyyy-MM-dd\")}\\\"\"\" + $\"{System.Random().Next(System.Int32.MaxValue)}.log\"\n 1 400 400   \n 0 400 400   let ``a byte literal`` = '\\209'B\n 1 400 400   \n 0 400 400   // quoted expression\n 0 400 400   let expr =\n 0 400 400       <@@\n 0 400 400           let foo () = \"bar\"\n 0 400 400           foo ()\n 0 400 400       @@>\n 1 400 400   \n 0 400 400   let bigNum (unused: 'a): float option =\n 0 400 400       Seq.init 10_000 (float >> (fun i -> i + 11.))\n 0 400 400       |> (List.ofSeq\n 0 400 400           >> List.take 5\n 0 400 400           >> List.fold (*) 1.0)\n 0 400 400       |> Some\n 1 400 400   \n 0 400 400   match bigNum () with\n 0 400 400   | Some num -> sprintf \"%.2f > %u\" num ``a byte literal``\n 0 400 400   | None -> sprintf \"%A\" \"Have a byte string!\"B\n 0 400 400   |> printfn \"%s\"\n 1 400 400   \n 0 400 400   // GitHub Issue #38\n 0 400 400   let unescapeWinPath (path: string) =\n 0 400 400       path.Replace(\"\\\\\\\\\", \"\\\\\").Replace(\"\\\"\", \"\")\n 1 400 400   \n 0 400 400   unescapeWinPath \"\\\\\\\"Program Files (x86)\\\\Windows NT\\\\Accessories\\\\\\\"\"\n 0 400 400   |> System.IO.Directory.GetFiles\n 0 400 400   |> printfn \"%A\"\n 0 400   0   "
  },
  {
    "path": "test/examples/fsharp/x.fs.styled",
    "content": "{9}// x.fs\n// Sample source file to test F# syntax highlighting\n{0}\n{18}[<AutoOpen>]{0}\n{1}module{0} {6}Example{0}\n\n{11}#line 7 \"A compiler directive\"{0}\n{10}#if DEBUG{0}\n  {1}open{0} {3}System{0}\n  {1}open{0} {3}System{0}.{3}IO{0}\n  {1}open{0} {3}System{0}.{6}Diagnostics{0}\n{10}#endif{0}\n\n{11}# 14 @\"See: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/strings#remarks\"{0}\n{9}// verbatim string\n{1}let{0} {6}xmlFragment1{0} {12}={0} {16}@\"<book href=\"\"https://www.worldcat.org/title/paradise-lost/oclc/1083714070\"\" title=\"\"Paradise Lost\"\">\"{0}\n\n{9}// triple-quoted string\n{1}let{0} {6}xmlFragment2{0} {12}={0} {15}\"\"\"<book href=\"https://www.worldcat.org/title/paradise-lost/oclc/1083714070\" title=\"Paradise Lost\">\"\"\"{0}\n\n{8}(* you need .NET 5.0 to compile this:\n  https://docs.microsoft.com/en-us/dotnet/fsharp/whats-new/fsharp-50#string-interpolation\n*){0}\n{1}let{0} {6}interpolated{0} {12}={0} {15}$\"\"\"C:\\{System.DateTime.Now.ToString(\"yyyy-MM-dd\")}\\\"\"\"{0} {12}+{0} {15}$\"{System.Random().Next(System.Int32.MaxValue)}.log\"{0}\n\n{1}let{0} {7}``a byte literal``{0} {12}={0} {14}'\\209'B{0}\n\n{9}// quoted expression\n{1}let{0} {6}expr{0} {12}={0}\n    {17}<@@\n        let foo () = \"bar\"\n        foo ()\n    @@>{0}\n\n{1}let{0} {6}bigNum{0} {12}({6}unused{12}:{0} {12}'{6}a{12}):{0} {3}float{0} {3}option{0} {12}={0}\n    {3}Seq{0}.{2}init{0} {13}10_000{0} {12}({3}float{0} {12}>>{0} {12}({1}fun{0} {6}i{0} {12}->{0} {6}i{0} {12}+{0} {13}11.{12})){0}\n    {12}|>{0} {12}({3}List{0}.{2}ofSeq{0}\n        {12}>>{0} {3}List{0}.{2}take{0} {13}5{0}\n        {12}>>{0} {3}List{0}.{2}fold{0} {12}(*){0} {13}1.0{12}){0}\n    {12}|>{0} {3}Some{0}\n\n{1}match{0} {6}bigNum{0} {1}(){0} {1}with{0}\n{12}|{0} {3}Some{0} {6}num{0} {12}->{0} {2}sprintf{0} {15}\"{19}%.2f{15} > {19}%u{15}\"{0} {6}num{0} {7}``a byte literal``{0}\n{12}|{0} {3}None{0} {12}->{0} {2}sprintf{0} {15}\"{19}%A{15}\"{0} {15}\"Have a byte string!\"B{0}\n{12}|>{0} {2}printfn{0} {15}\"{19}%s{15}\"{0}\n\n{9}// GitHub Issue #38\n{1}let{0} {6}unescapeWinPath{0} {12}({6}path{12}:{0} {3}string{12}){0} {12}={0}\n    {6}path{0}.{6}Replace{12}({15}\"\\\\\\\\\"{12},{0} {15}\"\\\\\"{12}){0}.{6}Replace{12}({15}\"\\\"\"{12},{0} {15}\"\"{12}){0}\n\n{6}unescapeWinPath{0} {15}\"\\\\\\\"Program Files (x86)\\\\Windows NT\\\\Accessories\\\\\\\"\"{0}\n{12}|>{0} {3}System{0}.{3}IO{0}.{6}Directory{0}.{6}GetFiles{0}\n{12}|>{0} {2}printfn{0} {15}\"{19}%A{15}\"{0}\n"
  },
  {
    "path": "test/examples/gdscript/AllStyles.gd",
    "content": "# Enumerate all styles: 0 to 15\n# comment=1\n\n# whitespace=0\n\t# w\n\n# number=2\n37\n\n# double-quoted-string=3\n\"str\"\n\n# single-quoted-string=4\n'str'\n\n# keyword=5\npass\n\n# triple-quoted-string=6\n'''str'''\n\n# triple-double-quoted-string=7\n\"\"\"str\"\"\"\n\n# class-name=8\nclass ClassName:\n\tpass\n\n# function-name=9\nfunc function_name():\n\tpass\n\n# operator=10\n1 + 3\n\n# identifier=11\nvar identifier = 2\n\n# comment-block=12\n## block\n\n# unclosed-string=13\n\" unclosed\n\n# highlighted-identifier=14\nvar hilight = 2\n\n# annotation=15\n@onready\nvar a = 3\n@onready var b = 3\n\n# node-identifier=16\n%node\n$node\n"
  },
  {
    "path": "test/examples/gdscript/AllStyles.gd.folded",
    "content": " 0 400   0   # Enumerate all styles: 0 to 15\n 0 400   0   # comment=1\n 1 400   0   \n 0 400   0   # whitespace=0\n 0 400   0   \t# w\n 1 400   0   \n 0 400   0   # number=2\n 0 400   0   37\n 1 400   0   \n 0 400   0   # double-quoted-string=3\n 0 400   0   \"str\"\n 1 400   0   \n 0 400   0   # single-quoted-string=4\n 0 400   0   'str'\n 1 400   0   \n 0 400   0   # keyword=5\n 0 400   0   pass\n 1 400   0   \n 0 400   0   # triple-quoted-string=6\n 0 400   0   '''str'''\n 1 400   0   \n 0 400   0   # triple-double-quoted-string=7\n 0 400   0   \"\"\"str\"\"\"\n 1 400   0   \n 0 400   0   # class-name=8\n 2 400   0 + class ClassName:\n 0 408   0 | \tpass\n 1 400   0   \n 0 400   0   # function-name=9\n 2 400   0 + func function_name():\n 0 408   0 | \tpass\n 1 400   0   \n 0 400   0   # operator=10\n 0 400   0   1 + 3\n 1 400   0   \n 0 400   0   # identifier=11\n 0 400   0   var identifier = 2\n 1 400   0   \n 0 400   0   # comment-block=12\n 0 400   0   ## block\n 1 400   0   \n 0 400   0   # unclosed-string=13\n 0 400   0   \" unclosed\n 1 400   0   \n 0 400   0   # highlighted-identifier=14\n 0 400   0   var hilight = 2\n 1 400   0   \n 0 400   0   # annotation=15\n 0 400   0   @onready\n 0 400   0   var a = 3\n 0 400   0   @onready var b = 3\n 1 400   0   \n 0 400   0   # node-identifier=16\n 0 400   0   %node\n 0 400   0   $node\n 1 400   0   "
  },
  {
    "path": "test/examples/gdscript/AllStyles.gd.styled",
    "content": "{1}# Enumerate all styles: 0 to 15{0}\n{1}# comment=1{0}\n\n{1}# whitespace=0{0}\n\t{1}# w{0}\n\n{1}# number=2{0}\n{2}37{0}\n\n{1}# double-quoted-string=3{0}\n{3}\"str\"{0}\n\n{1}# single-quoted-string=4{0}\n{4}'str'{0}\n\n{1}# keyword=5{0}\n{5}pass{0}\n\n{1}# triple-quoted-string=6{0}\n{6}'''str'''{0}\n\n{1}# triple-double-quoted-string=7{0}\n{7}\"\"\"str\"\"\"{0}\n\n{1}# class-name=8{0}\n{5}class{0} {8}ClassName{10}:{0}\n\t{5}pass{0}\n\n{1}# function-name=9{0}\n{5}func{0} {9}function_name{10}():{0}\n\t{5}pass{0}\n\n{1}# operator=10{0}\n{2}1{0} {10}+{0} {2}3{0}\n\n{1}# identifier=11{0}\n{5}var{0} {11}identifier{0} {10}={0} {2}2{0}\n\n{1}# comment-block=12{0}\n{12}## block{0}\n\n{1}# unclosed-string=13{0}\n{13}\" unclosed\n{0}\n{1}# highlighted-identifier=14{0}\n{5}var{0} {14}hilight{0} {10}={0} {2}2{0}\n\n{1}# annotation=15{0}\n{15}@onready{0}\n{5}var{0} {11}a{0} {10}={0} {2}3{0}\n{15}@onready{0} {5}var{0} {11}b{0} {10}={0} {2}3{0}\n\n{1}# node-identifier=16{0}\n{16}%node{0}\n{16}$node{0}\n"
  },
  {
    "path": "test/examples/gdscript/NodePath.gd",
    "content": "# nodepath\n\n$Node\n\n%Node\n\n%node/\"n o d e\"/%'n o d e'\n\n%\"No de\"\n\n\n$/root/ThisNode/%Node % %test\n\n$MainMenuPanel/%Options % %test\n\n%Options % %test\n\n$Node % %test\n\n\nget_node(\"%Options\") % %test\n\n$\"Nod   se\" % %test\n\n$/test/\"No % de\"/test % %test\n\n%node/\"n o d e\"/'n o d e' % %\"No De\"\n\n\"%010d\" % 12345\n\n1 % 1\n\na % b\n"
  },
  {
    "path": "test/examples/gdscript/NodePath.gd.folded",
    "content": " 0 400   0   # nodepath\n 1 400   0   \n 0 400   0   $Node\n 1 400   0   \n 0 400   0   %Node\n 1 400   0   \n 0 400   0   %node/\"n o d e\"/%'n o d e'\n 1 400   0   \n 0 400   0   %\"No de\"\n 1 400   0   \n 1 400   0   \n 0 400   0   $/root/ThisNode/%Node % %test\n 1 400   0   \n 0 400   0   $MainMenuPanel/%Options % %test\n 1 400   0   \n 0 400   0   %Options % %test\n 1 400   0   \n 0 400   0   $Node % %test\n 1 400   0   \n 1 400   0   \n 0 400   0   get_node(\"%Options\") % %test\n 1 400   0   \n 0 400   0   $\"Nod   se\" % %test\n 1 400   0   \n 0 400   0   $/test/\"No % de\"/test % %test\n 1 400   0   \n 0 400   0   %node/\"n o d e\"/'n o d e' % %\"No De\"\n 1 400   0   \n 0 400   0   \"%010d\" % 12345\n 1 400   0   \n 0 400   0   1 % 1\n 1 400   0   \n 0 400   0   a % b\n 1 400   0   "
  },
  {
    "path": "test/examples/gdscript/NodePath.gd.styled",
    "content": "{1}# nodepath{0}\n\n{16}$Node{0}\n\n{16}%Node{0}\n\n{16}%node/\"n o d e\"/%'n o d e'{0}\n\n{16}%\"No de\"{0}\n\n\n{16}$/root/ThisNode/%Node{0} {10}%{0} {16}%test{0}\n\n{16}$MainMenuPanel/%Options{0} {10}%{0} {16}%test{0}\n\n{16}%Options{0} {10}%{0} {16}%test{0}\n\n{16}$Node{0} {10}%{0} {16}%test{0}\n\n\n{11}get_node{10}({3}\"%Options\"{10}){0} {10}%{0} {16}%test{0}\n\n{16}$\"Nod   se\"{0} {10}%{0} {16}%test{0}\n\n{16}$/test/\"No % de\"/test{0} {10}%{0} {16}%test{0}\n\n{16}%node/\"n o d e\"/'n o d e'{0} {10}%{0} {16}%\"No De\"{0}\n\n{3}\"%010d\"{0} {10}%{0} {2}12345{0}\n\n{2}1{0} {10}%{0} {2}1{0}\n\n{11}a{0} {10}%{0} {11}b{0}\n"
  },
  {
    "path": "test/examples/gdscript/SciTE.properties",
    "content": "lexer.*.gd=gdscript\nkeywords.*.gd=class func else for if extends in pass print return while var\nkeywords2.*.gd=hilight\nfold=1\nfold.compact=1\n"
  },
  {
    "path": "test/examples/gui4cli/AllStyles.gui",
    "content": "/* Comment (2), followed by Default (0) */\n\n/* File does not include Line Comment (1) as that causes \\r\\n failures in test runner */\n\n/* Global (3) 'G4C' */\nG4C MyGui\n\n/* String (8) */\nWindow 10 10 200 300 \"My window\"\n\n/* Event (4) */\nxOnLoad\n     /* Command (7) */\n     GuiOpen MyGui\n\nxButton 10 10 100 20 \"Double it!\"\n     /* Attribute (5) */\n     attr frame sunk\n     Input \"Enter a number\" var\n     /* Control (6) 'if', Operator (9) '$', '>', '=' */\n     if $var > 9999\n          var = 9999\n     endif\n     var2 = $($var * 2)\n     MsgBox \"$var times 2 equals $var2\" OK/INFO\n     GuiQuit #this\n"
  },
  {
    "path": "test/examples/gui4cli/AllStyles.gui.folded",
    "content": " 0 401   0 | /* Comment (2), followed by Default (0) */\n 1 401   0 | \n 0 401   0 | /* File does not include Line Comment (1) as that causes \\r\\n failures in test runner */\n 1 401   0 | \n 0 401   0 | /* Global (3) 'G4C' */\n 2 400   0 + G4C MyGui\n 1 401   0 | \n 0 401   0 | /* String (8) */\n 2 400   0 + Window 10 10 200 300 \"My window\"\n 1 401   0 | \n 0 401   0 | /* Event (4) */\n 2 400   0 + xOnLoad\n 0 401   0 |      /* Command (7) */\n 0 401   0 |      GuiOpen MyGui\n 1 401   0 | \n 2 400   0 + xButton 10 10 100 20 \"Double it!\"\n 0 401   0 |      /* Attribute (5) */\n 0 401   0 |      attr frame sunk\n 0 401   0 |      Input \"Enter a number\" var\n 0 401   0 |      /* Control (6) 'if', Operator (9) '$', '>', '=' */\n 0 401   0 |      if $var > 9999\n 0 401   0 |           var = 9999\n 0 401   0 |      endif\n 0 401   0 |      var2 = $($var * 2)\n 0 401   0 |      MsgBox \"$var times 2 equals $var2\" OK/INFO\n 0 401   0 |      GuiQuit #this\n 0 401   0 | "
  },
  {
    "path": "test/examples/gui4cli/AllStyles.gui.styled",
    "content": "{2}/* Comment (2), followed by Default (0) */{0}\n\n{2}/* File does not include Line Comment (1) as that causes \\r\\n failures in test runner */{0}\n\n{2}/* Global (3) 'G4C' */{0}\n{3}G4C{0} MyGui\n\n{2}/* String (8) */{0}\n{3}Window{0} 10 10 200 300 {8}\"My window\"{0}\n\n{2}/* Event (4) */{0}\n{4}xOnLoad{0}\n     {2}/* Command (7) */{0}\n     {7}GuiOpen{0} MyGui\n\n{3}xButton{0} 10 10 100 20 {8}\"Double it!\"{0}\n     {2}/* Attribute (5) */{0}\n     {5}attr{0} frame sunk\n     {7}Input{0} {8}\"Enter a number\"{0} var\n     {2}/* Control (6) 'if', Operator (9) '$', '>', '=' */{0}\n     {6}if{0} {9}${0}var {9}>{0} 9999\n          var {9}={0} 9999\n     {6}endif{0}\n     var2 {9}={0} {9}${0}({9}${0}var * 2)\n     {7}MsgBox{0} {8}\"$var times 2 equals $var2\"{0} OK/INFO\n     {7}GuiQuit{0} #this\n"
  },
  {
    "path": "test/examples/gui4cli/SciTE.properties",
    "content": "lexer.*.gui=gui4cli\nfold=1\n\n#global\nkeywords.*.gui=G4C WINDOW XBUTTON\n#event\nkeywords2.*.gui=XONCLOSE XONLVDIR XONLOAD\n#attribute\nkeywords3.*.gui=ATTR\n#control\nkeywords4.*.gui=IF ELSE ENDIF GOSUB\n#command\nkeywords5.*.gui=GUIOPEN GUIQUIT INPUT MSGBOX SETWINTITLE\n"
  },
  {
    "path": "test/examples/hypertext/Bug2207.html",
    "content": "<!DOCTYPE html>\n<html>\n<script>\n  var example = \"<!-- -->\";  // closing \"-->\" is string\n  var example2 = '<!-- -->';  // closing \"-->\" is string\n</script>\n</html>\n"
  },
  {
    "path": "test/examples/hypertext/Bug2207.html.folded",
    "content": " 0 400   0   <!DOCTYPE html>\n 2 400   0 + <html>\n 2 401   0 + <script>\n 0 402   0 |   var example = \"<!-- -->\";  // closing \"-->\" is string\n 0 402   0 |   var example2 = '<!-- -->';  // closing \"-->\" is string\n 0 402   0 | </script>\n 0 401   0 | </html>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Bug2207.html.styled",
    "content": "{21}<!{22}DOCTYPE{21} {23}html{21}>{0}\n{1}<html>{0}\n{1}<script>{40}\n{41}  {47}var{41} {46}example{41} {50}={41} {48}\"<!-- -->\"{50};{41}  {43}// closing \"-->\" is string{41}\n  {47}var{41} {46}example2{41} {50}={41} {49}'<!-- -->'{50};{41}  {43}// closing \"-->\" is string{41}\n{1}</script>{0}\n{1}</html>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Bug2219.html",
    "content": "<script>\n\n/**\n*/\n\n</script>\n"
  },
  {
    "path": "test/examples/hypertext/Bug2219.html.folded",
    "content": " 2 400   0 + <script>\n 1 401   0 | \n 2 401   0 + /**\n 0 402   0 | */\n 1 401   0 | \n 0 401   0 | </script>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Bug2219.html.styled",
    "content": "{1}<script>{40}\n\n{44}/**\n*/{41}\n\n{1}</script>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue19.php",
    "content": "<?php\n\n$number = 1_234;\n$var = 'variable value';\n$test = [\n\t<<<EOTEST\n\tstring $var string EOTEST\n\tEOTEST_NOT\n\tEOTEST,\n\t0b00_01,\n\t<<<\"EOTEST\"\n\t\"string\" \"$var\" \"string\" EOTEST\n\tEOTEST_NOT\n\tEOTEST,\n\t0x00_02,\n\t<<<'EOTEST'\n\t'string' '$var' 'string' EOTEST\n\tEOTEST_NOT\n\tEOTEST,\n\t0x00_03,\n];\nprint_r($test);\n\n# Attribute tests\n#[SingleLineAnnotation('string', 1, null)]\n#[\n\tMultiLineAnnotation('string', 1, null)\n]\n\n?>\n"
  },
  {
    "path": "test/examples/hypertext/Issue19.php.folded",
    "content": " 2 400   0 + <?php\n 1 401   0 | \n 0 401   0 | $number = 1_234;\n 0 401   0 | $var = 'variable value';\n 0 401   0 | $test = [\n 0 401   0 | \t<<<EOTEST\n 0 401   0 | \tstring $var string EOTEST\n 0 401   0 | \tEOTEST_NOT\n 0 401   0 | \tEOTEST,\n 0 401   0 | \t0b00_01,\n 0 401   0 | \t<<<\"EOTEST\"\n 0 401   0 | \t\"string\" \"$var\" \"string\" EOTEST\n 0 401   0 | \tEOTEST_NOT\n 0 401   0 | \tEOTEST,\n 0 401   0 | \t0x00_02,\n 0 401   0 | \t<<<'EOTEST'\n 0 401   0 | \t'string' '$var' 'string' EOTEST\n 0 401   0 | \tEOTEST_NOT\n 0 401   0 | \tEOTEST,\n 0 401   0 | \t0x00_03,\n 0 401   0 | ];\n 0 401   0 | print_r($test);\n 1 401   0 | \n 0 401   0 | # Attribute tests\n 0 401   0 | #[SingleLineAnnotation('string', 1, null)]\n 0 401   0 | #[\n 0 401   0 | \tMultiLineAnnotation('string', 1, null)\n 0 401   0 | ]\n 1 401   0 | \n 0 401   0 | ?>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue19.php.styled",
    "content": "{18}<?php{118}\n\n{123}$number{118} {127}={118} {122}1_234{127};{118}\n{123}$var{118} {127}={118} {120}'variable value'{127};{118}\n{123}$test{118} {127}={118} {127}[{118}\n\t{119}<<<EOTEST\n\tstring {126}$var{119} string EOTEST\n\tEOTEST_NOT\n\tEOTEST{127},{118}\n\t{122}0b00_01{127},{118}\n\t{119}<<<\"EOTEST\"\n\t\"string\" \"{126}$var{119}\" \"string\" EOTEST\n\tEOTEST_NOT\n\tEOTEST{127},{118}\n\t{122}0x00_02{127},{118}\n\t{120}<<<'EOTEST'\n\t'string' '$var' 'string' EOTEST\n\tEOTEST_NOT\n\tEOTEST{127},{118}\n\t{122}0x00_03{127},{118}\n{127}];{118}\nprint_r{127}({123}$test{127});{118}\n\n{125}# Attribute tests{118}\n#{127}[{118}SingleLineAnnotation{127}({120}'string'{127},{118} {122}1{127},{118} null{127})]{118}\n#{127}[{118}\n\tMultiLineAnnotation{127}({120}'string'{127},{118} {122}1{127},{118} null{127}){118}\n{127}]{118}\n\n{18}?>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue192.html",
    "content": "﻿&\n&1\n&A\n&中\n&amp<br />\n&1<br />\n&A<br />\n&中<br />\n&&amp;\n&#1;\n&#1;中\n&A;<br />\n&#1;<br />\n&#1;中<br />\n&amp\n&lt;\n&lt;<br />\n&b.eps;\n&b.eps!\n&—;\n"
  },
  {
    "path": "test/examples/hypertext/Issue192.html.folded",
    "content": " 0 400   0   &\n 0 400   0   &1\n 0 400   0   &A\n 0 400   0   &中\n 0 400   0   &amp<br />\n 0 400   0   &1<br />\n 0 400   0   &A<br />\n 0 400   0   &中<br />\n 0 400   0   &&amp;\n 0 400   0   &#1;\n 0 400   0   &#1;中\n 0 400   0   &A;<br />\n 0 400   0   &#1;<br />\n 0 400   0   &#1;中<br />\n 0 400   0   &amp\n 0 400   0   &lt;\n 0 400   0   &lt;<br />\n 0 400   0   &b.eps;\n 0 400   0   &b.eps!\n 0 400   0   &—;\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue192.html.styled",
    "content": "{2}&{0}\n{2}&1{0}\n{2}&A{0}\n{2}&{0}中\n{2}&amp{1}<br{8} {11}/>{0}\n{2}&1{1}<br{8} {11}/>{0}\n{2}&A{1}<br{8} {11}/>{0}\n{2}&{0}中{1}<br{8} {11}/>{0}\n{2}&{10}&amp;{0}\n{10}&#1;{0}\n{10}&#1;{0}中\n{10}&A;{1}<br{8} {11}/>{0}\n{10}&#1;{1}<br{8} {11}/>{0}\n{10}&#1;{0}中{1}<br{8} {11}/>{0}\n{2}&amp{0}\n{10}&lt;{0}\n{10}&lt;{1}<br{8} {11}/>{0}\n{10}&b.eps;{0}\n{2}&b.eps{0}!\n{2}&{0}—;\n"
  },
  {
    "path": "test/examples/hypertext/Issue20Numbers.php",
    "content": "<?php\n\n123456; 123_456; // +\n1234z6; 123456_; 123__456; // -\n\n0x89Ab; 0x89_aB; // +\n0x89zB; 0x89AB_; 0x_89AB; 0_x89AB; 0x89__AB; // -\n\n1234.; 1234.e-0; 1234e+0; 1234e0; 1234e0.PHP_EOL; // +\n1234._; 1234.e-; 1234e+; 1234e; // -\n\n.1234; .12e0; // +\n.12.0e0; .12e0.0; .12e0e0; // -\n\n1.234e-10; 1.2_34e-1_0; // +\n1.234e-_10; 1.234e_-10; 1.234_e-10; 1._234e-10; 1_.234e-10; // -\n1.234e-+10; 1.234e-_+10; // -\n\n01234567; 0_1234567; // +\n012345678; // -\n\n0...0; // 0. . .0\n.0..0; // .0 . .0\n0e+0+0e+0; // 0e+0 + 0e+0\n\n;0#comment\n;0//comment\n;0/*comment*/;\n\n?>\n"
  },
  {
    "path": "test/examples/hypertext/Issue20Numbers.php.folded",
    "content": " 2 400   0 + <?php\n 1 401   0 | \n 0 401   0 | 123456; 123_456; // +\n 0 401   0 | 1234z6; 123456_; 123__456; // -\n 1 401   0 | \n 0 401   0 | 0x89Ab; 0x89_aB; // +\n 0 401   0 | 0x89zB; 0x89AB_; 0x_89AB; 0_x89AB; 0x89__AB; // -\n 1 401   0 | \n 0 401   0 | 1234.; 1234.e-0; 1234e+0; 1234e0; 1234e0.PHP_EOL; // +\n 0 401   0 | 1234._; 1234.e-; 1234e+; 1234e; // -\n 1 401   0 | \n 0 401   0 | .1234; .12e0; // +\n 0 401   0 | .12.0e0; .12e0.0; .12e0e0; // -\n 1 401   0 | \n 0 401   0 | 1.234e-10; 1.2_34e-1_0; // +\n 0 401   0 | 1.234e-_10; 1.234e_-10; 1.234_e-10; 1._234e-10; 1_.234e-10; // -\n 0 401   0 | 1.234e-+10; 1.234e-_+10; // -\n 1 401   0 | \n 0 401   0 | 01234567; 0_1234567; // +\n 0 401   0 | 012345678; // -\n 1 401   0 | \n 0 401   0 | 0...0; // 0. . .0\n 0 401   0 | .0..0; // .0 . .0\n 0 401   0 | 0e+0+0e+0; // 0e+0 + 0e+0\n 1 401   0 | \n 0 401   0 | ;0#comment\n 0 401   0 | ;0//comment\n 0 401   0 | ;0/*comment*/;\n 1 401   0 | \n 0 401   0 | ?>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue20Numbers.php.styled",
    "content": "{18}<?php{118}\n\n{122}123456{127};{118} {122}123_456{127};{118} {125}// +{118}\n1234z6{127};{118} 123456_{127};{118} 123__456{127};{118} {125}// -{118}\n\n{122}0x89Ab{127};{118} {122}0x89_aB{127};{118} {125}// +{118}\n0x89zB{127};{118} 0x89AB_{127};{118} 0x_89AB{127};{118} 0_x89AB{127};{118} 0x89__AB{127};{118} {125}// -{118}\n\n{122}1234.{127};{118} {122}1234.e-0{127};{118} {122}1234e+0{127};{118} {122}1234e0{127};{118} {122}1234e0{127}.{118}PHP_EOL{127};{118} {125}// +{118}\n1234._{127};{118} 1234.e-{127};{118} 1234e+{127};{118} 1234e{127};{118} {125}// -{118}\n\n{122}.1234{127};{118} {122}.12e0{127};{118} {125}// +{118}\n.12.0e0{127};{118} .12e0.0{127};{118} .12e0e0{127};{118} {125}// -{118}\n\n{122}1.234e-10{127};{118} {122}1.2_34e-1_0{127};{118} {125}// +{118}\n1.234e-_10{127};{118} 1.234e_-10{127};{118} 1.234_e-10{127};{118} 1._234e-10{127};{118} 1_.234e-10{127};{118} {125}// -{118}\n1.234e-+10{127};{118} 1.234e-_+10{127};{118} {125}// -{118}\n\n{122}01234567{127};{118} {122}0_1234567{127};{118} {125}// +{118}\n012345678{127};{118} {125}// -{118}\n\n{122}0.{127}.{122}.0{127};{118} {125}// 0. . .0{118}\n{122}.0{127}.{122}.0{127};{118} {125}// .0 . .0{118}\n{122}0e+0{127}+{122}0e+0{127};{118} {125}// 0e+0 + 0e+0{118}\n\n{127};{122}0{125}#comment{118}\n{127};{122}0{125}//comment{118}\n{127};{122}0{124}/*comment*/{127};{118}\n\n{18}?>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue250RegEx.html",
    "content": "<script>\n/a|b/i.test(\"baby\");\n// arrow function\n() => /a|b/i.test(\"baby\");\n// Issue 289\n/a/g.test('a');\n/a/gm.test('a');\n'a'.replace(/a/g, 'b');\n'a'.replace(/a/gm, 'b');\n</script>\n"
  },
  {
    "path": "test/examples/hypertext/Issue250RegEx.html.folded",
    "content": " 2 400   0 + <script>\n 0 401   0 | /a|b/i.test(\"baby\");\n 0 401   0 | // arrow function\n 0 401   0 | () => /a|b/i.test(\"baby\");\n 0 401   0 | // Issue 289\n 0 401   0 | /a/g.test('a');\n 0 401   0 | /a/gm.test('a');\n 0 401   0 | 'a'.replace(/a/g, 'b');\n 0 401   0 | 'a'.replace(/a/gm, 'b');\n 0 401   0 | </script>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue250RegEx.html.styled",
    "content": "{1}<script>{40}\n{52}/a|b/i{50}.{46}test{50}({48}\"baby\"{50});{41}\n{43}// arrow function{41}\n{50}(){41} {50}=>{41} {52}/a|b/i{50}.{46}test{50}({48}\"baby\"{50});{41}\n{43}// Issue 289{41}\n{52}/a/g{50}.{46}test{50}({49}'a'{50});{41}\n{52}/a/gm{50}.{46}test{50}({49}'a'{50});{41}\n{49}'a'{50}.{46}replace{50}({52}/a/g{50},{41} {49}'b'{50});{41}\n{49}'a'{50}.{46}replace{50}({52}/a/gm{50},{41} {49}'b'{50});{41}\n{1}</script>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue252Tag.php",
    "content": "<!-- Check PHP start tags for issue 252 -->\n\n<!-- Full PHP tag: enabled -->\n<?php\necho __FILE__.__LINE__;\n?>\n\n<!-- Short echo tag: enabled -->\n<?= 'echo' ?>\n\n<!-- Short tag: disabled -->\n<?\necho 'short'\n?>\n\n<!-- ASP language selection: disabled -->\n<%@language=JScript%>\n\n<!-- ASP tag: disabled -->\n<%\nResponse.Write('short')\n%>\n"
  },
  {
    "path": "test/examples/hypertext/Issue252Tag.php.folded",
    "content": " 0 400   0   <!-- Check PHP start tags for issue 252 -->\n 1 400   0   \n 0 400   0   <!-- Full PHP tag: enabled -->\n 2 400   0 + <?php\n 0 401   0 | echo __FILE__.__LINE__;\n 0 401   0 | ?>\n 1 400   0   \n 0 400   0   <!-- Short echo tag: enabled -->\n 0 400   0   <?= 'echo' ?>\n 1 400   0   \n 0 400   0   <!-- Short tag: disabled -->\n 0 400   0   <?\n 0 400   0   echo 'short'\n 2 400   0 + ?>\n 1 401   0 | \n 0 401   0 | <!-- ASP language selection: disabled -->\n 2 401   0 + <%@language=JScript%>\n 1 402   0 | \n 0 402   0 | <!-- ASP tag: disabled -->\n 0 402   0 | <%\n 0 402   0 | Response.Write('short')\n 2 402   0 + %>\n 0 403   0 | "
  },
  {
    "path": "test/examples/hypertext/Issue252Tag.php.styled",
    "content": "{9}<!-- Check PHP start tags for issue 252 -->{0}\n\n{9}<!-- Full PHP tag: enabled -->{0}\n{18}<?php{118}\n{121}echo{118} {121}__FILE__{127}.{121}__LINE__{127};{118}\n{18}?>{0}\n\n{9}<!-- Short echo tag: enabled -->{0}\n{18}<?={118} {120}'echo'{118} {18}?>{0}\n\n{9}<!-- Short tag: disabled -->{0}\n{2}<?\necho 'short'\n?>{0}\n\n{9}<!-- ASP language selection: disabled -->{0}\n{2}<%@language=JScript%>{0}\n\n{9}<!-- ASP tag: disabled -->{0}\n{2}<%\nResponse.Write('short')\n%>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue259CaseLower.html",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- Check that HTML elements and attributes and VB keywords are matched case-insensitively -->\n<%@language=vbscript%>\n<% \nsub x 'comment \npeek 1024\n%>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n    <UNKNOWN>SinkWorld - Portability</unknown>\n    <img src=\"SciTEIco.png\" height=64 WIDTH=64 />\n    <LINK rel=\"stylesheet\" TYPE=\"text/css\" from=\"SW.css\">\n    <DESTINATION href=\"SW.css\" height=64 width=64></destination>\n</head>\n</html>\n"
  },
  {
    "path": "test/examples/hypertext/Issue259CaseLower.html.folded",
    "content": " 0 400   0   <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n 0 400   0   <!-- Check that HTML elements and attributes and VB keywords are matched case-insensitively -->\n 0 400   0   <%@language=vbscript%>\n 2 400   0 + <% \n 0 401   0 | sub x 'comment \n 0 401   0 | peek 1024\n 0 401   0 | %>\n 2 400   0 + <html xmlns=\"http://www.w3.org/1999/xhtml\">\n 2 401   0 + <head>\n 0 402   0 |     <UNKNOWN>SinkWorld - Portability</unknown>\n 0 402   0 |     <img src=\"SciTEIco.png\" height=64 WIDTH=64 />\n 0 402   0 |     <LINK rel=\"stylesheet\" TYPE=\"text/css\" from=\"SW.css\">\n 0 402   0 |     <DESTINATION href=\"SW.css\" height=64 width=64></destination>\n 0 402   0 | </head>\n 0 401   0 | </html>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue259CaseLower.html.styled",
    "content": "{12}<?{1}xml{8} {3}version{8}={6}\"1.0\"{8} {3}encoding{8}={6}\"UTF-8\"{13}?>{0}\n{9}<!-- Check that HTML elements and attributes and VB keywords are matched case-insensitively -->{0}\n{15}<%@{16}language=vbscript{15}%>{0}\n{15}<%{81} \n{84}sub{81} {86}x{81} {82}'comment {81}\n{196}peek{81} {83}1024{81}\n{15}%>{0}\n{1}<html{8} {3}xmlns{8}={6}\"http://www.w3.org/1999/xhtml\"{1}>{0}\n{1}<head>{0}\n    {2}<UNKNOWN>{0}SinkWorld - Portability{2}</unknown>{0}\n    {1}<img{8} {3}src{8}={6}\"SciTEIco.png\"{8} {193}height{8}={5}64{8} {193}WIDTH{8}={5}64{8} {11}/>{0}\n    {1}<LINK{8} {3}rel{8}={6}\"stylesheet\"{8} {3}TYPE{8}={6}\"text/css\"{8} {193}from{8}={6}\"SW.css\"{1}>{0}\n    {192}<DESTINATION{8} {3}href{8}={6}\"SW.css\"{8} {4}height{8}={5}64{8} {4}width{8}={5}64{1}>{192}</destination>{0}\n{1}</head>{0}\n{1}</html>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue272SGML.xml",
    "content": "<!DOCTYPE root [\n<!ELEMENT root (p)>\n<!ELEMENT p (#PCDATA)>\n<!-- Example 1 from XML spec 1.0 Appendix D -->\n<!ENTITY example \"<p>An ampersand (&#38;#38;) may be escaped\nnumerically (&#38;#38;#38) or with a general entity (&amp;amp;).</p>\" >\n]>\n<root>&example;</root>\n"
  },
  {
    "path": "test/examples/hypertext/Issue272SGML.xml.folded",
    "content": " 2 400   0 + <!DOCTYPE root [\n 0 401   0 | <!ELEMENT root (p)>\n 0 401   0 | <!ELEMENT p (#PCDATA)>\n 0 401   0 | <!-- Example 1 from XML spec 1.0 Appendix D -->\n 2 401   0 + <!ENTITY example \"<p>An ampersand (&#38;#38;) may be escaped\n 0 402   0 | numerically (&#38;#38;#38) or with a general entity (&amp;amp;).</p>\" >\n 0 401   0 | ]>\n 0 400   0   <root>&example;</root>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue272SGML.xml.styled",
    "content": "{21}<!{22}DOCTYPE{21} {23}root{21} [{31}\n{21}<!{22}ELEMENT{21} {23}root{21} (p)>{31}\n{21}<!{22}ELEMENT{21} {23}p{21} ({27}#PCDATA{21})>{31}\n{21}<!{29}-- Example 1 from XML spec 1.0 Appendix D --{21}>{31}\n{21}<!{22}ENTITY{21} {23}example{21} {24}\"<p>An ampersand (&#38;#38;) may be escaped\nnumerically (&#38;#38;#38) or with a general entity (&amp;amp;).</p>\"{21} >{31}\n{21}]>{0}\n{2}<root>{10}&example;{2}</root>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue273JavaScript.html",
    "content": "<script>\nvar pi/*/=3.1415/*/=3.14;\n/*\n<?xml>\n<!doctype>\n*/\n/**\n<?xml>\n<!doctype>\n*/\nvar template = `\n<?xml encoding='${encoding}'>\n<!doctype>\n`;\n/<?xml>/.test('<?xml>');\n/<!doctype>/.test(\"<!doctype>\");\n</script>\n"
  },
  {
    "path": "test/examples/hypertext/Issue273JavaScript.html.folded",
    "content": " 2 400   0 + <script>\n 0 401   0 | var pi/*/=3.1415/*/=3.14;\n 0 401   0 | /*\n 0 401   0 | <?xml>\n 0 401   0 | <!doctype>\n 0 401   0 | */\n 0 401   0 | /**\n 0 401   0 | <?xml>\n 0 401   0 | <!doctype>\n 0 401   0 | */\n 0 401   0 | var template = `\n 0 401   0 | <?xml encoding='${encoding}'>\n 0 401   0 | <!doctype>\n 0 401   0 | `;\n 0 401   0 | /<?xml>/.test('<?xml>');\n 0 401   0 | /<!doctype>/.test(\"<!doctype>\");\n 0 401   0 | </script>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue273JavaScript.html.styled",
    "content": "{1}<script>{40}\n{47}var{41} {46}pi{42}/*/=3.1415/*/{50}={45}3.14{50};{41}\n{42}/*\n<?xml>\n<!doctype>\n*/{41}\n{44}/**\n<?xml>\n<!doctype>\n*/{41}\n{47}var{41} {46}template{41} {50}={41} {53}`\n<?xml encoding='${encoding}'>\n<!doctype>\n`{50};{41}\n{52}/<?xml>/{50}.{46}test{50}({49}'<?xml>'{50});{41}\n{52}/<!doctype>/{50}.{46}test{50}({48}\"<!doctype>\"{50});{41}\n{1}</script>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue288.php",
    "content": "<?\nnl2br(\"\\n); // unterminated string\n?>\n\")\n"
  },
  {
    "path": "test/examples/hypertext/Issue288.php.folded",
    "content": " 2 400   0 + <?\n 0 401   0 | nl2br(\"\\n); // unterminated string\n 0 401   0 | ?>\n 0 401   0 | \")\n 0 401   0 | "
  },
  {
    "path": "test/examples/hypertext/Issue288.php.styled",
    "content": "{18}<?{118}\n{198}nl2br{127}({119}\"\\n); // unterminated string\n?>\n\"{127}){118}\n"
  },
  {
    "path": "test/examples/hypertext/Issue338.html",
    "content": "<script type=\"text/javascript\">\n// #338 Checking transitions from SCE_HJ_DEFAULT\nvar/**/b=1/***/;\n/1//**/;\n/1//***/;\n''\"\"/**/\n\"\"''/***/\n``''``/**/\n``\"\"``/***/\n// <!-- and -->\n''<!--\n\"\"-->\n``<!--\n``-->\n;\n/1/;<!--\n/1/;-->\n1<!--\n1-->\n</script>\n<script type=\"text/vbscript\">\n' #338 Checking transitions from SCE_HB_DEFAULT\na\"s\"\na'c\na/b\na 'c\na#c\n\"s\"\"s\"\n\"s\"'c\ndim\"s\"\ndim's\ndim/2\npeek\"s\"\npeek's\npeek/2\n\"s\"a\n\"s\"dim\n\"s\"'c\n\ndim a=1;''\n\"\"''\n1''\n' <!-- and -->\n\"\"<!--\n\"\"-->\n;<!--\n;-->\n1<!--\n1-->\n</script>\n"
  },
  {
    "path": "test/examples/hypertext/Issue338.html.folded",
    "content": " 2 400   0 + <script type=\"text/javascript\">\n 0 401   0 | // #338 Checking transitions from SCE_HJ_DEFAULT\n 0 401   0 | var/**/b=1/***/;\n 0 401   0 | /1//**/;\n 0 401   0 | /1//***/;\n 0 401   0 | ''\"\"/**/\n 0 401   0 | \"\"''/***/\n 0 401   0 | ``''``/**/\n 0 401   0 | ``\"\"``/***/\n 0 401   0 | // <!-- and -->\n 0 401   0 | ''<!--\n 0 401   0 | \"\"-->\n 0 401   0 | ``<!--\n 0 401   0 | ``-->\n 0 401   0 | ;\n 0 401   0 | /1/;<!--\n 0 401   0 | /1/;-->\n 0 401   0 | 1<!--\n 0 401   0 | 1-->\n 0 401   0 | </script>\n 2 400   0 + <script type=\"text/vbscript\">\n 0 401   0 | ' #338 Checking transitions from SCE_HB_DEFAULT\n 0 401   0 | a\"s\"\n 0 401   0 | a'c\n 0 401   0 | a/b\n 0 401   0 | a 'c\n 0 401   0 | a#c\n 0 401   0 | \"s\"\"s\"\n 0 401   0 | \"s\"'c\n 0 401   0 | dim\"s\"\n 0 401   0 | dim's\n 0 401   0 | dim/2\n 0 401   0 | peek\"s\"\n 0 401   0 | peek's\n 0 401   0 | peek/2\n 0 401   0 | \"s\"a\n 0 401   0 | \"s\"dim\n 0 401   0 | \"s\"'c\n 1 401   0 | \n 0 401   0 | dim a=1;''\n 0 401   0 | \"\"''\n 0 401   0 | 1''\n 0 401   0 | ' <!-- and -->\n 0 401   0 | \"\"<!--\n 0 401   0 | \"\"-->\n 0 401   0 | ;<!--\n 0 401   0 | ;-->\n 0 401   0 | 1<!--\n 0 401   0 | 1-->\n 0 401   0 | </script>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue338.html.styled",
    "content": "{1}<script{8} {3}type{8}={6}\"text/javascript\"{1}>{40}\n{43}// #338 Checking transitions from SCE_HJ_DEFAULT{41}\n{47}var{44}/**/{46}b{50}={45}1{44}/***/{50};{41}\n{52}/1/{44}/**/{50};{41}\n{52}/1/{44}/***/{50};{41}\n{49}''{48}\"\"{44}/**/{41}\n{48}\"\"{49}''{44}/***/{41}\n{53}``{49}''{53}``{44}/**/{41}\n{53}``{48}\"\"{53}``{44}/***/{41}\n{43}// <!-- and -->{41}\n{49}''{43}<!--{41}\n{48}\"\"{43}-->{41}\n{53}``{43}<!--{41}\n{53}``{43}-->{41}\n{50};{41}\n{52}/1/{50};{43}<!--{41}\n{52}/1/{50};{43}-->{41}\n{45}1{50}<!--{41}\n{45}1{43}-->{41}\n{1}</script>{0}\n{1}<script{8} {3}type{8}={6}\"text/vbscript\"{1}>{70}\n{72}' #338 Checking transitions from SCE_HB_DEFAULT{71}\n{76}a{75}\"s\"{71}\n{76}a{72}'c{71}\n{76}a{71}/{76}b{71}\n{76}a{71} {72}'c{71}\n{76}a{71}#{76}c{71}\n{75}\"s\"\"s\"{71}\n{75}\"s\"{72}'c{71}\n{74}dim{75}\"s\"{71}\n{74}dim{72}'s{71}\n{74}dim{71}/{73}2{71}\n{196}peek{75}\"s\"{71}\n{196}peek{72}'s{71}\n{196}peek{71}/{73}2{71}\n{75}\"s\"{76}a{71}\n{75}\"s\"{74}dim{71}\n{75}\"s\"{72}'c{71}\n\n{74}dim{71} {76}a{71}={73}1{71};{72}''{71}\n{75}\"\"{72}''{71}\n{73}1{72}''{71}\n{72}' <!-- and -->{71}\n{75}\"\"{72}<!--{71}\n{75}\"\"{71}-->\n;{72}<!--{71}\n;-->\n{73}1{71}<!--\n{73}1{71}-->\n{1}</script>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue340BadSGML.html",
    "content": "<!{2}>\n"
  },
  {
    "path": "test/examples/hypertext/Issue340BadSGML.html.folded",
    "content": " 0 400   0   <!{2}>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue340BadSGML.html.styled",
    "content": "{21}<!{26}{2}{21}>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue47.html",
    "content": "<script src=\"\">\n// comment\n</script>\n<script>\n{\n};\n</script>\n"
  },
  {
    "path": "test/examples/hypertext/Issue47.html.folded",
    "content": " 2 400   0 + <script src=\"\">\n 0 401   0 | // comment\n 0 401   0 | </script>\n 2 400   0 + <script>\n 2 401   0 + {\n 0 402   0 | };\n 0 401   0 | </script>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue47.html.styled",
    "content": "{1}<script{8} {3}src{8}={6}\"\"{1}>{40}\n{43}// comment{41}\n{1}</script>{0}\n{1}<script>{40}\n{50}{{41}\n{50}};{41}\n{1}</script>{0}\n"
  },
  {
    "path": "test/examples/hypertext/Issue53.html",
    "content": "<script>\n{\n    /\\d{1}\\}/.test('{0}')\n}\n</script>\n"
  },
  {
    "path": "test/examples/hypertext/Issue53.html.folded",
    "content": " 2 400   0 + <script>\n 2 401   0 + {\n 0 402   0 |     /\\d{1}\\}/.test('{0}')\n 0 402   0 | }\n 0 401   0 | </script>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/Issue53.html.styled",
    "content": "{1}<script>{40}\n{50}{{41}\n    {52}/\\d{1}\\}/{50}.{46}test{50}({49}'{0}'{50}){41}\n{50}}{41}\n{1}</script>{0}\n"
  },
  {
    "path": "test/examples/hypertext/SciTE.properties",
    "content": "lexer.*=hypertext\n# Tags and attributes\nkeywords.*=b br body content div encoding head href html IMG language li link meta \\\nname p rel runat script Src strong title type ul version xml xmlns\n# JavaScript\nkeywords2.*=function var\n# Basic\nkeywords3.*=dim sub\n# Python\nkeywords4.*=import pass\n# PHP\nkeywords5.*=echo __file__ __line__\n# SGML\nkeywords6.*=DOCTYPE ELEMENT ENTITY NOTATION\n\n# Tag\nsubstyles.hypertext.1=1\nsubstylewords.1.1.*=Destination\n# Attribute\nsubstyles.hypertext.3=1\nsubstylewords.3.1.*=from img.height img.Width\n# JavaScript\nsubstyles.hypertext.46=1\nsubstylewords.46.1.*=let\n# Server JavaScript\nsubstyles.hypertext.61=1\nsubstylewords.61.1.*=serve\n# Basic\nsubstyles.hypertext.74=1\nsubstylewords.74.1.*=PEEK\n# Python\nsubstyles.hypertext.96=1\nsubstylewords.96.1.*=parse\n# PHP\nsubstyles.hypertext.121=1\nsubstylewords.121.1.*=decrypt nl2br\n\nfold=1\nfold.html=1\nfold.html.preprocessor=1\nfold.hypertext.comment=1\n\nmatch Issue273JavaScript.html\n  fold.hypertext.comment=0\n\nmatch mako.html\n  lexer.html.mako=1\n\nmatch Issue252Tag.php\n  lexer.html.allow.php=1\n  lexer.html.allow.asp=0\n"
  },
  {
    "path": "test/examples/hypertext/ServerBasic.aspx",
    "content": "<%@ register tagprefix=\"uc1\" \n    tagname=\"CalendarUserControl\" \n    src=\"~/CalendarUserControl.ascx\" %>\n<!DOCTYPE html>\n<html>\n<%@language=VBScript%>\n<%-- comment --%>\n<script type=\"text/vbscript\">\n'1%>2\n'1?>2\n'%>\n'?>\n</script>\n<script type=\"text/vbscript\">\ndim e=\"%>\"\ndim f=\"?>\"\n</script>\nStart\n<%response.write(\"1\")%>\n<% 'comment%>\n<%dim x=\"2\"'comment%>\n<%response.write(x)%>\nEnd\n</html>\n"
  },
  {
    "path": "test/examples/hypertext/ServerBasic.aspx.folded",
    "content": " 2 400   0 + <%@ register tagprefix=\"uc1\" \n 0 401   0 |     tagname=\"CalendarUserControl\" \n 0 401   0 |     src=\"~/CalendarUserControl.ascx\" %>\n 0 400   0   <!DOCTYPE html>\n 2 400   0 + <html>\n 0 401   0 | <%@language=VBScript%>\n 0 401   0 | <%-- comment --%>\n 2 401   0 + <script type=\"text/vbscript\">\n 0 402   0 | '1%>2\n 0 402   0 | '1?>2\n 0 402   0 | '%>\n 0 402   0 | '?>\n 0 402   0 | </script>\n 2 401   0 + <script type=\"text/vbscript\">\n 0 402   0 | dim e=\"%>\"\n 0 402   0 | dim f=\"?>\"\n 0 402   0 | </script>\n 0 401   0 | Start\n 0 401   0 | <%response.write(\"1\")%>\n 0 401   0 | <% 'comment%>\n 0 401   0 | <%dim x=\"2\"'comment%>\n 0 401   0 | <%response.write(x)%>\n 0 401   0 | End\n 0 401   0 | </html>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/ServerBasic.aspx.styled",
    "content": "{15}<%@{16} register tagprefix=\"uc1\" \n    tagname=\"CalendarUserControl\" \n    src=\"~/CalendarUserControl.ascx\" {15}%>{0}\n{21}<!{22}DOCTYPE{21} {23}html{21}>{0}\n{1}<html>{0}\n{15}<%@{16}language=VBScript{15}%>{0}\n{15}<%--{20} comment --{15}%>{0}\n{1}<script{8} {3}type{8}={6}\"text/vbscript\"{1}>{70}\n{72}'1%>2{71}\n{72}'1?>2{71}\n{72}'%>{71}\n{72}'?>{71}\n{1}</script>{0}\n{1}<script{8} {3}type{8}={6}\"text/vbscript\"{1}>{70}\n{74}dim{71} {76}e{71}={75}\"%>\"{71}\n{74}dim{71} {76}f{71}={75}\"?>\"{71}\n{1}</script>{0}\nStart\n{15}<%{86}response.write{81}({85}\"1\"{81}){15}%>{0}\n{15}<%{81} {82}'comment{15}%>{0}\n{15}<%{84}dim{81} {86}x{81}={85}\"2\"{82}'comment{15}%>{0}\n{15}<%{86}response.write{81}({86}x{81}){15}%>{0}\nEnd\n{1}</html>{0}\n"
  },
  {
    "path": "test/examples/hypertext/ServerJavaScript.aspx",
    "content": "<!DOCTYPE html>\n<html>\n<%@language=JScript%>\n<%-- comment --%>\n<script type=\"text/javascript\">\n//%>\n//?>\n</script>\n<script type=\"text/javascript\">\ne=\"%>\";\nf=\"?>\";\n</script>\nStart\n<%Response.Write(\"1\")%>\n<%var x=3;//comment%>\n<%x=3;//comment ?> %>\n<%Response.Write(x)%>\n<%Response.Write(`template ${2+2}`)%>\nEnd\n</html>\n"
  },
  {
    "path": "test/examples/hypertext/ServerJavaScript.aspx.folded",
    "content": " 0 400   0   <!DOCTYPE html>\n 2 400   0 + <html>\n 0 401   0 | <%@language=JScript%>\n 0 401   0 | <%-- comment --%>\n 2 401   0 + <script type=\"text/javascript\">\n 0 402   0 | //%>\n 0 402   0 | //?>\n 0 402   0 | </script>\n 2 401   0 + <script type=\"text/javascript\">\n 0 402   0 | e=\"%>\";\n 0 402   0 | f=\"?>\";\n 0 402   0 | </script>\n 0 401   0 | Start\n 0 401   0 | <%Response.Write(\"1\")%>\n 0 401   0 | <%var x=3;//comment%>\n 0 401   0 | <%x=3;//comment ?> %>\n 0 401   0 | <%Response.Write(x)%>\n 0 401   0 | <%Response.Write(`template ${2+2}`)%>\n 0 401   0 | End\n 0 401   0 | </html>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/ServerJavaScript.aspx.styled",
    "content": "{21}<!{22}DOCTYPE{21} {23}html{21}>{0}\n{1}<html>{0}\n{15}<%@{16}language=JScript{15}%>{0}\n{15}<%--{20} comment --{15}%>{0}\n{1}<script{8} {3}type{8}={6}\"text/javascript\"{1}>{40}\n{43}//%>{41}\n{43}//?>{41}\n{1}</script>{0}\n{1}<script{8} {3}type{8}={6}\"text/javascript\"{1}>{40}\n{46}e{50}={48}\"%>\"{50};{41}\n{46}f{50}={48}\"?>\"{50};{41}\n{1}</script>{0}\nStart\n{15}<%{61}Response.Write{65}({63}\"1\"{65}){15}%>{0}\n{15}<%{62}var{56} {61}x{65}={60}3{65};{58}//comment{15}%>{0}\n{15}<%{61}x{65}={60}3{65};{58}//comment ?> {15}%>{0}\n{15}<%{61}Response.Write{65}({61}x{65}){15}%>{0}\n{15}<%{61}Response.Write{65}({68}`template ${2+2}`{65}){15}%>{0}\nEnd\n{1}</html>{0}\n"
  },
  {
    "path": "test/examples/hypertext/apostophe.php",
    "content": "<?php\n# Test that currently fails as comment style not started in a number.\n# line-comment\n// line-comment\n/* comment */\n$foo = 0#comment\n$foo = 0//comment\n$foo = 0/*'*/;\n?>\n\n<br />\n"
  },
  {
    "path": "test/examples/hypertext/apostophe.php.folded",
    "content": " 2 400   0 + <?php\n 0 401   0 | # Test that currently fails as comment style not started in a number.\n 0 401   0 | # line-comment\n 0 401   0 | // line-comment\n 0 401   0 | /* comment */\n 0 401   0 | $foo = 0#comment\n 0 401   0 | $foo = 0//comment\n 0 401   0 | $foo = 0/*'*/;\n 0 401   0 | ?>\n 1 400   0   \n 0 400   0   <br />\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/apostophe.php.styled",
    "content": "{18}<?php{118}\n{125}# Test that currently fails as comment style not started in a number.{118}\n{125}# line-comment{118}\n{125}// line-comment{118}\n{124}/* comment */{118}\n{123}$foo{118} {127}={118} {122}0{125}#comment{118}\n{123}$foo{118} {127}={118} {122}0{125}//comment{118}\n{123}$foo{118} {127}={118} {122}0{124}/*'*/{127};{118}\n{18}?>{0}\n\n{1}<br{8} {11}/>{0}\n"
  },
  {
    "path": "test/examples/hypertext/comment.html",
    "content": "<!----><p>1 normal comment</p>\n<!-- > and <!--><p>2 valid comment</p>\n<!--><p>3 abrupt-closing-of-empty-comment</p>\n<!---><p>4 abrupt-closing-of-empty-comment</p>\n<!----!><p>5 incorrectly-closed-comment</p>\n<!--!> <h1 value=\"--!><p>6 incorrectly-closed-comment</p>\n<!--<!---><p>7 nested-comment</p>\n<!--<!---!><p>8 nested-comment</p>\n"
  },
  {
    "path": "test/examples/hypertext/comment.html.folded",
    "content": " 0 400   0   <!----><p>1 normal comment</p>\n 0 400   0   <!-- > and <!--><p>2 valid comment</p>\n 0 400   0   <!--><p>3 abrupt-closing-of-empty-comment</p>\n 0 400   0   <!---><p>4 abrupt-closing-of-empty-comment</p>\n 0 400   0   <!----!><p>5 incorrectly-closed-comment</p>\n 0 400   0   <!--!> <h1 value=\"--!><p>6 incorrectly-closed-comment</p>\n 0 400   0   <!--<!---><p>7 nested-comment</p>\n 0 400   0   <!--<!---!><p>8 nested-comment</p>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/comment.html.styled",
    "content": "{9}<!---->{1}<p>{0}1 normal comment{1}</p>{0}\n{9}<!-- > and <!-->{1}<p>{0}2 valid comment{1}</p>{0}\n{9}<!-->{1}<p>{0}3 abrupt-closing-of-empty-comment{1}</p>{0}\n{9}<!--->{1}<p>{0}4 abrupt-closing-of-empty-comment{1}</p>{0}\n{9}<!----!>{1}<p>{0}5 incorrectly-closed-comment{1}</p>{0}\n{9}<!--!> <h1 value=\"--!>{1}<p>{0}6 incorrectly-closed-comment{1}</p>{0}\n{9}<!--<!--->{1}<p>{0}7 nested-comment{1}</p>{0}\n{9}<!--<!---!>{1}<p>{0}8 nested-comment{1}</p>{0}\n"
  },
  {
    "path": "test/examples/hypertext/mako.html",
    "content": "Mako examples extracted from https://docs.makotemplates.org/en/latest/syntax.html\n\nExpression\n${x}\n${}\n${pow(x,2) + pow(y,2)}\n\nExpression Escaping\n${\"this is some text\" | u}\n\nControl Structures\n% if x==5:\n    this is some output\n% endif\n\n% for a in ['one', 'two', 'three', 'four', 'five']:\n    % if a[0] == 't':\n    its two or three\n    % elif a[0] == 'f':\n    four/five\n    % else:\n    one\n    % endif\n% endfor\n\nThe % sign can also be escaped, if you actually want to emit a percent sign as the first non whitespace character on a line, by escaping it as in %%:\n%% some text\n    %% some more text\n\nThe Loop Context\nThe loop context provides additional information about a loop while inside of a % for structure:\n\n<ul>\n% for a in (\"one\", \"two\", \"three\"):\n    <li>Item ${loop.index}: ${a}</li>\n% endfor\n</ul>\n\nA multiline version exists using <%doc> ...text... </%doc>:\n<%doc>\n    these are comments\n    more comments\n</%doc>\n\nPython Blocks\nAny arbitrary block of python can be dropped in using the <% %> tags:\nthis is a template\n\n<%\n    x = db.get_resource('foo')\n    y = [z.element for z in x if x.frobnizzle==5]\n%>\n% for elem in y:\n    element: ${elem}\n% endfor\nWithin <% %>, youre writing a regular block of Python code. While the code can appear with an arbitrary level of preceding whitespace, it has to be consistently formatted with itself. Makos compiler will adjust the block of Python to be consistent with the surrounding generated Python code.\n\nModule-level Blocks\nA variant on <% %> is the module-level code block, denoted by <%! %>. Code within these tags is executed at the module level of the template, and not within the rendering function of the template. Therefore, this code does not have access to the templates context and is only executed when the template is loaded into memory (which can be only once per application, or more, depending on the runtime environment). Use the <%! %> tags to declare your templates imports, as well as any pure-Python functions you might want to declare:\n\n<%!\n    import mylib\n    import re\n\n    def filter(text):\n        return re.sub(r'^@', '', text)\n%>\n\nTags\nThe rest of what Mako offers takes place in the form of tags. All tags use the same syntax, which is similar to an XML tag except that the first character of the tag name is a % character. The tag is closed either by a contained slash character, or an explicit closing tag:\n\n<%include file=\"foo.txt\"/>\n\n<%def name=\"foo\" buffered=\"True\">\n    this is a def\n</%def>\n"
  },
  {
    "path": "test/examples/hypertext/mako.html.folded",
    "content": " 0 400   0   Mako examples extracted from https://docs.makotemplates.org/en/latest/syntax.html\n 1 400   0   \n 0 400   0   Expression\n 0 400   0   ${x}\n 0 400   0   ${}\n 0 400   0   ${pow(x,2) + pow(y,2)}\n 1 400   0   \n 0 400   0   Expression Escaping\n 0 400   0   ${\"this is some text\" | u}\n 1 400   0   \n 0 400   0   Control Structures\n 0 400   0   % if x==5:\n 0 400   0       this is some output\n 0 400   0   % endif\n 1 400   0   \n 0 400   0   % for a in ['one', 'two', 'three', 'four', 'five']:\n 0 400   0       % if a[0] == 't':\n 0 400   0       its two or three\n 0 400   0       % elif a[0] == 'f':\n 0 400   0       four/five\n 0 400   0       % else:\n 0 400   0       one\n 0 400   0       % endif\n 0 400   0   % endfor\n 1 400   0   \n 0 400   0   The % sign can also be escaped, if you actually want to emit a percent sign as the first non whitespace character on a line, by escaping it as in %%:\n 0 400   0   %% some text\n 0 400   0       %% some more text\n 1 400   0   \n 0 400   0   The Loop Context\n 0 400   0   The loop context provides additional information about a loop while inside of a % for structure:\n 1 400   0   \n 2 400   0 + <ul>\n 0 401   0 | % for a in (\"one\", \"two\", \"three\"):\n 0 401   0 |     <li>Item ${loop.index}: ${a}</li>\n 0 401   0 | % endfor\n 0 401   0 | </ul>\n 1 400   0   \n 0 400   0   A multiline version exists using <%doc> ...text... </%doc>:\n 0 400   0   <%doc>\n 0 400   0       these are comments\n 0 400   0       more comments\n 0 400   0   </%doc>\n 1 400   0   \n 0 400   0   Python Blocks\n 0 400   0   Any arbitrary block of python can be dropped in using the <% %> tags:\n 0 400   0   this is a template\n 1 400   0   \n 0 400   0   <%\n 0 400   0       x = db.get_resource('foo')\n 0 400   0       y = [z.element for z in x if x.frobnizzle==5]\n 0 400   0   %>\n 0 400   0   % for elem in y:\n 0 400   0       element: ${elem}\n 0 400   0   % endfor\n 0 400   0   Within <% %>, youre writing a regular block of Python code. While the code can appear with an arbitrary level of preceding whitespace, it has to be consistently formatted with itself. Makos compiler will adjust the block of Python to be consistent with the surrounding generated Python code.\n 1 400   0   \n 0 400   0   Module-level Blocks\n 0 400   0   A variant on <% %> is the module-level code block, denoted by <%! %>. Code within these tags is executed at the module level of the template, and not within the rendering function of the template. Therefore, this code does not have access to the templates context and is only executed when the template is loaded into memory (which can be only once per application, or more, depending on the runtime environment). Use the <%! %> tags to declare your templates imports, as well as any pure-Python functions you might want to declare:\n 1 400   0   \n 0 400   0   <%!\n 0 400   0       import mylib\n 0 400   0       import re\n 1 400   0   \n 0 400   0       def filter(text):\n 0 400   0           return re.sub(r'^@', '', text)\n 0 400   0   %>\n 1 400   0   \n 0 400   0   Tags\n 0 400   0   The rest of what Mako offers takes place in the form of tags. All tags use the same syntax, which is similar to an XML tag except that the first character of the tag name is a % character. The tag is closed either by a contained slash character, or an explicit closing tag:\n 1 400   0   \n 0 400   0   <%include file=\"foo.txt\"/>\n 1 400   0   \n 0 400   0   <%def name=\"foo\" buffered=\"True\">\n 0 400   0       this is a def\n 0 400   0   </%def>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/mako.html.styled",
    "content": "{0}Mako examples extracted from https://docs.makotemplates.org/en/latest/syntax.html\n\nExpression\n{15}${{117}x{15}}{0}\n{15}${}{0}\n{15}${{117}pow{116}({117}x{116},{108}2{116}){106} {116}+{106} {117}pow{116}({117}y{116},{108}2{116}){15}}{0}\n\nExpression Escaping\n{15}${{109}\"this is some text\"{106} {116}|{106} {117}u{15}}{0}\n\nControl Structures\n{15}%{106} {117}if{106} {117}x{116}=={108}5{116}:{0}\n    this is some output\n{15}%{106} {117}endif{0}\n\n{15}%{106} {117}for{106} {117}a{106} {117}in{106} {116}[{110}'one'{116},{106} {110}'two'{116},{106} {110}'three'{116},{106} {110}'four'{116},{106} {110}'five'{116}]:{0}\n    {15}%{106} {117}if{106} {117}a{116}[{108}0{116}]{106} {116}=={106} {110}'t'{116}:{0}\n    its two or three\n    {15}%{106} {117}elif{106} {117}a{116}[{108}0{116}]{106} {116}=={106} {110}'f'{116}:{0}\n    four/five\n    {15}%{106} {117}else{116}:{0}\n    one\n    {15}%{106} {117}endif{0}\n{15}%{106} {117}endfor{0}\n\nThe % sign can also be escaped, if you actually want to emit a percent sign as the first non whitespace character on a line, by escaping it as in %%:\n{15}%{116}%{106} {117}some{106} {117}text{0}\n    {15}%{116}%{106} {117}some{106} {117}more{106} {117}text{0}\n\nThe Loop Context\nThe loop context provides additional information about a loop while inside of a % for structure:\n\n{1}<ul>{0}\n{15}%{106} {117}for{106} {117}a{106} {117}in{106} {116}({109}\"one\"{116},{106} {109}\"two\"{116},{106} {109}\"three\"{116}):{0}\n    {1}<li>{0}Item {15}${{117}loop.index{15}}{0}: {15}${{117}a{15}}{1}</li>{0}\n{15}%{106} {117}endfor{0}\n{1}</ul>{0}\n\nA multiline version exists using {15}<%{2}doc{15}>{0} ...text... {15}</%{2}doc{15}>{0}:\n{15}<%{2}doc{15}>{0}\n    these are comments\n    more comments\n{15}</%{2}doc{15}>{0}\n\nPython Blocks\nAny arbitrary block of python can be dropped in using the {15}<%{106} {15}%>{0} tags:\nthis is a template\n\n{15}<%{105}\n{106}    {117}x{106} {116}={106} {117}db.get_resource{116}({110}'foo'{116}){106}\n    {117}y{106} {116}={106} {116}[{117}z.element{106} {117}for{106} {117}z{106} {117}in{106} {117}x{106} {117}if{106} {117}x.frobnizzle{116}=={108}5{116}]{106}\n{15}%>{0}\n{15}%{106} {117}for{106} {117}elem{106} {117}in{106} {117}y{116}:{0}\n    element: {15}${{117}elem{15}}{0}\n{15}%{106} {117}endfor{0}\nWithin {15}<%{106} {15}%>{0}, youre writing a regular block of Python code. While the code can appear with an arbitrary level of preceding whitespace, it has to be consistently formatted with itself. Makos compiler will adjust the block of Python to be consistent with the surrounding generated Python code.\n\nModule-level Blocks\nA variant on {15}<%{106} {15}%>{0} is the module-level code block, denoted by {15}<%{116}!{106} {15}%>{0}. Code within these tags is executed at the module level of the template, and not within the rendering function of the template. Therefore, this code does not have access to the templates context and is only executed when the template is loaded into memory (which can be only once per application, or more, depending on the runtime environment). Use the {15}<%{116}!{106} {15}%>{0} tags to declare your templates imports, as well as any pure-Python functions you might want to declare:\n\n{15}<%{116}!{105}\n{106}    {111}import{106} {117}mylib{106}\n    {111}import{106} {117}re{106}\n\n    {117}def{106} {115}filter{116}({117}text{116}):{106}\n        {117}return{106} {117}re.sub{116}({117}r{110}'^@'{116},{106} {110}''{116},{106} {117}text{116}){106}\n{15}%>{0}\n\nTags\nThe rest of what Mako offers takes place in the form of tags. All tags use the same syntax, which is similar to an XML tag except that the first character of the tag name is a % character. The tag is closed either by a contained slash character, or an explicit closing tag:\n\n{15}<%{2}include{106} {117}file{116}={109}\"foo.txt\"{15}/>{0}\n\n{15}<%{2}def{106} {117}name{116}={109}\"foo\"{106} {117}buffered{116}={109}\"True\"{15}>{0}\n    this is a def\n{15}</%{2}def{15}>{0}\n"
  },
  {
    "path": "test/examples/hypertext/x.asp",
    "content": "<%@language=javas%>\n<% \n#include \nserve x;\nfunction x() {\n}\n%>\n<%@language=vbscript%>\n<% \nsub x 'comment \npeek 1024\n%>\n<!-- Folding for Python is incorrect. See #235. -->\n<%@language=python%>\n<% \nimport random\nx = 'comment'\nparse \"x=8\"\n%>\n<head>\n<body></body>\n"
  },
  {
    "path": "test/examples/hypertext/x.asp.folded",
    "content": " 0 400   0   <%@language=javas%>\n 2 400   0 + <% \n 0 401   0 | #include \n 0 401   0 | serve x;\n 2 401   0 + function x() {\n 0 402   0 | }\n 0 401   0 | %>\n 0 400   0   <%@language=vbscript%>\n 2 400   0 + <% \n 0 401   0 | sub x 'comment \n 0 401   0 | peek 1024\n 0 401   0 | %>\n 0 400   0   <!-- Folding for Python is incorrect. See #235. -->\n 0 400   0   <%@language=python%>\n 0 400   0   <% \n 0 400   0   import random\n 0 400   0   x = 'comment'\n 0 400   0   parse \"x=8\"\n 0 400   0   %>\n 2 3ff   0 + <head>\n 0 400   0   <body></body>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/x.asp.styled",
    "content": "{15}<%@{16}language=javas{15}%>{0}\n{15}<%{56} \n#{61}include{56} \n{195}serve{56} {61}x{65};{56}\n{62}function{56} {61}x{65}(){56} {65}{{56}\n{65}}{56}\n{15}%>{0}\n{15}<%@{16}language=vbscript{15}%>{0}\n{15}<%{81} \n{84}sub{81} {86}x{81} {82}'comment {81}\n{196}peek{81} {83}1024{81}\n{15}%>{0}\n{9}<!-- Folding for Python is incorrect. See #235. -->{0}\n{15}<%@{16}language=python{15}%>{0}\n{15}<%{106} \n{111}import{106} {117}random{106}\n{117}x{106} {116}={106} {110}'comment'{106}\n{197}parse{106} {109}\"x=8\"{106}\n{15}%>{0}\n{1}<head>{0}\n{1}<body></body>{0}\n"
  },
  {
    "path": "test/examples/hypertext/x.html",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<script type=\"text/javascript\">\nvar b = /abc/i.test('abc');\nlet b = 1;\n'x\\\n</t>'\n// issue 214 fix to behave same as single quote escaped eol\n\"x\\\n</t>\"\n</script>\n<head>\n    <meta name=\"Date.Modified\" content=\"20010515\" />\n    <title>SinkWorld - Portability</title>\n    §\n    <unknown>SinkWorld - Portability</unknown>\n    <img src=\"SciTEIco.png\" height=64 width=64 />\n    <link rel=\"stylesheet\" type=\"text/css\" from=\"SW.css\">\n    <destination href=\"SW.css\" height=64 width=64></destination>\n</head>\n</html>\n"
  },
  {
    "path": "test/examples/hypertext/x.html.folded",
    "content": " 0 400   0   <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n 2 400   0 + <html xmlns=\"http://www.w3.org/1999/xhtml\">\n 2 401   0 + <script type=\"text/javascript\">\n 0 402   0 | var b = /abc/i.test('abc');\n 0 402   0 | let b = 1;\n 0 402   0 | 'x\\\n 0 402   0 | </t>'\n 0 402   0 | // issue 214 fix to behave same as single quote escaped eol\n 0 402   0 | \"x\\\n 0 402   0 | </t>\"\n 0 402   0 | </script>\n 2 401   0 + <head>\n 0 402   0 |     <meta name=\"Date.Modified\" content=\"20010515\" />\n 0 402   0 |     <title>SinkWorld - Portability</title>\n 0 402   0 |     §\n 0 402   0 |     <unknown>SinkWorld - Portability</unknown>\n 0 402   0 |     <img src=\"SciTEIco.png\" height=64 width=64 />\n 0 402   0 |     <link rel=\"stylesheet\" type=\"text/css\" from=\"SW.css\">\n 0 402   0 |     <destination href=\"SW.css\" height=64 width=64></destination>\n 0 402   0 | </head>\n 0 401   0 | </html>\n 0 400   0   "
  },
  {
    "path": "test/examples/hypertext/x.html.styled",
    "content": "{12}<?{1}xml{8} {3}version{8}={6}\"1.0\"{8} {3}encoding{8}={6}\"UTF-8\"{13}?>{0}\n{1}<html{8} {3}xmlns{8}={6}\"http://www.w3.org/1999/xhtml\"{1}>{0}\n{1}<script{8} {3}type{8}={6}\"text/javascript\"{1}>{40}\n{47}var{41} {46}b{41} {50}={41} {52}/abc/i{50}.{46}test{50}({49}'abc'{50});{41}\n{194}let{41} {46}b{41} {50}={41} {45}1{50};{41}\n{49}'x\\\n</t>'{41}\n{43}// issue 214 fix to behave same as single quote escaped eol{41}\n{48}\"x\\\n</t>\"{41}\n{1}</script>{0}\n{1}<head>{0}\n    {1}<meta{8} {3}name{8}={6}\"Date.Modified\"{8} {3}content{8}={6}\"20010515\"{8} {11}/>{0}\n    {1}<title>{0}SinkWorld - Portability{1}</title>{0}\n    §\n    {2}<unknown>{0}SinkWorld - Portability{2}</unknown>{0}\n    {1}<img{8} {3}src{8}={6}\"SciTEIco.png\"{8} {193}height{8}={5}64{8} {193}width{8}={5}64{8} {11}/>{0}\n    {1}<link{8} {3}rel{8}={6}\"stylesheet\"{8} {3}type{8}={6}\"text/css\"{8} {193}from{8}={6}\"SW.css\"{1}>{0}\n    {192}<destination{8} {3}href{8}={6}\"SW.css\"{8} {4}height{8}={5}64{8} {4}width{8}={5}64{1}>{192}</destination>{0}\n{1}</head>{0}\n{1}</html>{0}\n"
  },
  {
    "path": "test/examples/hypertext/x.php",
    "content": "<head> <!-- About to script -->\n<?php\ndecrypt \"xyzzy\";\necho __FILE__.__LINE__;\necho \"<!-- -->\\n\";\n/* ?> */\n?>\n<strong>for</strong><b>if</b>\n<?= 'short echo tag' ?>\n<? echo 'short tag' ?>\n<script>\n\talert(\"<?php echo \"PHP\" . ' Code'; ?>\");\n\talert('<?= 'PHP' . \"Code\"; ?>');\n\tvar xml =\n\t'<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><SO_GL>' +\n\t'<GLOBAL_LIST mode=\"complete\"><NAME>SO_SINGLE_MULTIPLE_COMMAND_BUILDER</NAME>' +\n\t'<LIST_ELEMENT><CODE>1</CODE><LIST_VALUE><![CDATA[RM QI WEB BOOKING]]></LIST_VALUE></LIST_ELEMENT>' +\n\t'<LIST_ELEMENT><CODE>1</CODE><LIST_VALUE><![CDATA[RM *PCC]]></LIST_VALUE></LIST_ELEMENT>' +\n\t'</GLOBAL_LIST></SO_GL>';\n</script>\n"
  },
  {
    "path": "test/examples/hypertext/x.php.folded",
    "content": " 2 400   0 + <head> <!-- About to script -->\n 2 401   0 + <?php\n 0 402   0 | decrypt \"xyzzy\";\n 0 402   0 | echo __FILE__.__LINE__;\n 0 402   0 | echo \"<!-- -->\\n\";\n 0 402   0 | /* ?> */\n 0 402   0 | ?>\n 0 401   0 | <strong>for</strong><b>if</b>\n 0 401   0 | <?= 'short echo tag' ?>\n 0 401   0 | <? echo 'short tag' ?>\n 2 401   0 + <script>\n 0 402   0 | \talert(\"<?php echo \"PHP\" . ' Code'; ?>\");\n 0 402   0 | \talert('<?= 'PHP' . \"Code\"; ?>');\n 0 402   0 | \tvar xml =\n 0 402   0 | \t'<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><SO_GL>' +\n 0 402   0 | \t'<GLOBAL_LIST mode=\"complete\"><NAME>SO_SINGLE_MULTIPLE_COMMAND_BUILDER</NAME>' +\n 0 402   0 | \t'<LIST_ELEMENT><CODE>1</CODE><LIST_VALUE><![CDATA[RM QI WEB BOOKING]]></LIST_VALUE></LIST_ELEMENT>' +\n 0 402   0 | \t'<LIST_ELEMENT><CODE>1</CODE><LIST_VALUE><![CDATA[RM *PCC]]></LIST_VALUE></LIST_ELEMENT>' +\n 0 402   0 | \t'</GLOBAL_LIST></SO_GL>';\n 0 402   0 | </script>\n 0 401   0 | "
  },
  {
    "path": "test/examples/hypertext/x.php.styled",
    "content": "{1}<head>{0} {9}<!-- About to script -->{0}\n{18}<?php{118}\n{198}decrypt{118} {119}\"xyzzy\"{127};{118}\n{121}echo{118} {121}__FILE__{127}.{121}__LINE__{127};{118}\n{121}echo{118} {119}\"<!-- -->\\n\"{127};{118}\n{124}/* ?> */{118}\n{18}?>{0}\n{1}<strong>{0}for{1}</strong><b>{0}if{1}</b>{0}\n{18}<?={118} {120}'short echo tag'{118} {18}?>{0}\n{18}<?{118} {121}echo{118} {120}'short tag'{118} {18}?>{0}\n{1}<script>{40}\n{41}\t{46}alert{50}({48}\"{18}<?php{118} {121}echo{118} {119}\"PHP\"{118} {127}.{118} {120}' Code'{127};{118} {18}?>{48}\"{50});{41}\n\t{46}alert{50}({49}'{18}<?={118} {120}'PHP'{118} {127}.{118} {119}\"Code\"{127};{118} {18}?>{49}'{50});{41}\n\t{47}var{41} {46}xml{41} {50}={41}\n\t{49}'<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><SO_GL>'{41} {50}+{41}\n\t{49}'<GLOBAL_LIST mode=\"complete\"><NAME>SO_SINGLE_MULTIPLE_COMMAND_BUILDER</NAME>'{41} {50}+{41}\n\t{49}'<LIST_ELEMENT><CODE>1</CODE><LIST_VALUE><![CDATA[RM QI WEB BOOKING]]></LIST_VALUE></LIST_ELEMENT>'{41} {50}+{41}\n\t{49}'<LIST_ELEMENT><CODE>1</CODE><LIST_VALUE><![CDATA[RM *PCC]]></LIST_VALUE></LIST_ELEMENT>'{41} {50}+{41}\n\t{49}'</GLOBAL_LIST></SO_GL>'{50};{41}\n{1}</script>{0}\n"
  },
  {
    "path": "test/examples/inno/SciTE.properties",
    "content": "lexer.*.iss=inno\nfold=1\nkeywords.*.iss=code custommessages files ini messages registry setup\nkeywords2.*.iss=appname appcopyright onlybelowversion wizardsmallimagefile\nkeywords3.*.iss=destdir key onlybelowversion root source string valuetype\nkeywords4.*.iss=define\nkeywords5.*.iss=\\\nand begin break case const continue do downto else end except exit \\\nfalse finally for function if not of on or procedure repeat then to \\\ntrue try type until uses var while with\nkeywords6.*.iss=\n"
  },
  {
    "path": "test/examples/inno/x.iss",
    "content": "#define app_copyright \"Copyright 1999, app corporation\"\n\n; comment\n\n[Setup]\nAppName=MyApp\nAppCopyright={#app_copyright}\nWizardSmallImageFile=WizardSmallImageFile.bmp\nOnlyBelowVersion=6.01\n\n[Files]\nSource: \"app.exe\"; DestDir: \"{tmp}\"; OnlyBelowVersion: 6.01\n\n[INI]\nKey: \"keyname1\"; String: \"unterminated\nKey: 'keyname2'; String: 'unterminated\n\n[Registry]\nRoot: HKLM; ValueType: string\n\n[CustomMessages]\nkeyname     =Other tasks:'not string\n\n[Messages]\nkeyname=\"{#app_copyright}\"not string\n\n[Code]\n\n// comment\n\n(* comment *)\n\n{ comment }\n\n{ *) comment }\n\n(* } comment *)\n\n(*\ncomment *)\n\n{\ncomment }\n\nfunction ShouldInstallComCtlUpdate: Boolean;\nbegin\n  Result := False;\n  Log('string');\n  IsEscaped('''good''', ''bad');\nend;\n"
  },
  {
    "path": "test/examples/inno/x.iss.folded",
    "content": " 0 400   0   #define app_copyright \"Copyright 1999, app corporation\"\n 0 400   0   \n 0 400   0   ; comment\n 0 400   0   \n 2 400   0 + [Setup]\n 0 401   0 | AppName=MyApp\n 0 401   0 | AppCopyright={#app_copyright}\n 0 401   0 | WizardSmallImageFile=WizardSmallImageFile.bmp\n 0 401   0 | OnlyBelowVersion=6.01\n 0 401   0 | \n 2 400   0 + [Files]\n 0 401   0 | Source: \"app.exe\"; DestDir: \"{tmp}\"; OnlyBelowVersion: 6.01\n 0 401   0 | \n 2 400   0 + [INI]\n 0 401   0 | Key: \"keyname1\"; String: \"unterminated\n 0 401   0 | Key: 'keyname2'; String: 'unterminated\n 0 401   0 | \n 2 400   0 + [Registry]\n 0 401   0 | Root: HKLM; ValueType: string\n 0 401   0 | \n 2 400   0 + [CustomMessages]\n 0 401   0 | keyname     =Other tasks:'not string\n 0 401   0 | \n 2 400   0 + [Messages]\n 0 401   0 | keyname=\"{#app_copyright}\"not string\n 0 401   0 | \n 2 400   0 + [Code]\n 0 401   0 | \n 0 401   0 | // comment\n 0 401   0 | \n 0 401   0 | (* comment *)\n 0 401   0 | \n 0 401   0 | { comment }\n 0 401   0 | \n 0 401   0 | { *) comment }\n 0 401   0 | \n 0 401   0 | (* } comment *)\n 0 401   0 | \n 0 401   0 | (*\n 0 401   0 | comment *)\n 0 401   0 | \n 0 401   0 | {\n 0 401   0 | comment }\n 0 401   0 | \n 0 401   0 | function ShouldInstallComCtlUpdate: Boolean;\n 0 401   0 | begin\n 0 401   0 |   Result := False;\n 0 401   0 |   Log('string');\n 0 401   0 |   IsEscaped('''good''', ''bad');\n 0 401   0 | end;\n 0 400   0   "
  },
  {
    "path": "test/examples/inno/x.iss.styled",
    "content": "{5}#define{0} app_copyright {10}\"Copyright 1999, app corporation\"{0}\n\n{1}; comment{0}\n\n{4}[Setup]{0}\n{2}AppName{0}=MyApp\n{2}AppCopyright{0}={6}{#app_copyright}{0}\n{2}WizardSmallImageFile{0}=WizardSmallImageFile.bmp\n{2}OnlyBelowVersion{0}=6.01\n\n{4}[Files]{0}\n{3}Source{0}: {10}\"app.exe\"{0}; {3}DestDir{0}: {10}\"{tmp}\"{0}; {3}OnlyBelowVersion{0}: 6.01\n\n{4}[INI]{0}\n{3}Key{0}: {10}\"keyname1\"{0}; {3}String{0}: {10}\"unterminated{0}\n{3}Key{0}: {11}'keyname2'{0}; {3}String{0}: {11}'unterminated{0}\n\n{4}[Registry]{0}\n{3}Root{0}: HKLM; {3}ValueType{0}: string\n\n{4}[CustomMessages]{0}\nkeyname     =Other tasks:'not string\n\n{4}[Messages]{0}\nkeyname=\"{6}{#app_copyright}{0}\"not string\n\n{4}[Code]{0}\n\n{7}// comment{0}\n\n{7}(* comment *){0}\n\n{7}{ comment }{0}\n\n{7}{ *) comment }{0}\n\n{7}(* } comment *){0}\n\n{7}(*\ncomment *){0}\n\n{7}{\ncomment }{0}\n\n{8}function{0} ShouldInstallComCtlUpdate: Boolean;\n{8}begin{0}\n  Result := {8}False{0};\n  Log({11}'string'{0});\n  IsEscaped({11}'''good'''{0}, {11}''{0}bad{11}');{0}\n{8}end{0};\n"
  },
  {
    "path": "test/examples/json/AllStyles.json",
    "content": "// Enumerate all styles: 0 to 13\n\n// default=0\n   \n\n// number=1\n1\n\n// string=2\n\"2\"\n\n// stringeol=3\n\"3\n\n// propertyname=4\n\"4\":\n\n// escapesequence=5\n\"\\n\"\n\n// linecomment=6\n// 6 Line Comment\n\n// blockcomment=7\n/* 7 Block Comment */\n\n// operator=8\n{}\n\n// uri=9\n\"http://9.org\"\n\n// compactiri=10\n\"x:y\"\n\n// keyword=11\ntrue\n\n// ldkeyword=12\n\"@id\"\n\n// error=13\n# 13 error\n"
  },
  {
    "path": "test/examples/json/AllStyles.json.folded",
    "content": " 0 400 400   // Enumerate all styles: 0 to 13\n 1 400 400   \n 0 400 400   // default=0\n 1 400 400      \n 1 400 400   \n 0 400 400   // number=1\n 0 400 400   1\n 1 400 400   \n 0 400 400   // string=2\n 0 400 400   \"2\"\n 1 400 400   \n 0 400 400   // stringeol=3\n 0 400 400   \"3\n 1 400 400   \n 0 400 400   // propertyname=4\n 0 400 400   \"4\":\n 1 400 400   \n 0 400 400   // escapesequence=5\n 0 400 400   \"\\n\"\n 1 400 400   \n 0 400 400   // linecomment=6\n 0 400 400   // 6 Line Comment\n 1 400 400   \n 0 400 400   // blockcomment=7\n 0 400 400   /* 7 Block Comment */\n 1 400 400   \n 0 400 400   // operator=8\n 0 400 400   {}\n 1 400 400   \n 0 400 400   // uri=9\n 0 400 400   \"http://9.org\"\n 1 400 400   \n 0 400 400   // compactiri=10\n 0 400 400   \"x:y\"\n 1 400 400   \n 0 400 400   // keyword=11\n 0 400 400   true\n 1 400 400   \n 0 400 400   // ldkeyword=12\n 0 400 400   \"@id\"\n 1 400 400   \n 0 400 400   // error=13\n 0 400 400   # 13 error\n 0 400   0   "
  },
  {
    "path": "test/examples/json/AllStyles.json.styled",
    "content": "{6}// Enumerate all styles: 0 to 13{0}\n\n{6}// default=0{0}\n   \n\n{6}// number=1{0}\n{1}1{0}\n\n{6}// string=2{0}\n{2}\"2\"{0}\n\n{6}// stringeol=3{0}\n{3}\"3\n{0}\n{6}// propertyname=4{0}\n{4}\"4\"{8}:{0}\n\n{6}// escapesequence=5{0}\n{2}\"{5}\\n{2}\"{0}\n\n{6}// linecomment=6{0}\n{6}// 6 Line Comment{0}\n\n{6}// blockcomment=7{0}\n{7}/* 7 Block Comment */{0}\n\n{6}// operator=8{0}\n{8}{}{0}\n\n{6}// uri=9{0}\n{2}\"{9}http://9.org{2}\"{0}\n\n{6}// compactiri=10{0}\n{10}\"x:y\"{0}\n\n{6}// keyword=11{0}\n{11}true{0}\n\n{6}// ldkeyword=12{0}\n{2}\"{12}@id{2}\"{0}\n\n{6}// error=13{0}\n{13}# 13 error{0}\n"
  },
  {
    "path": "test/examples/json/SciTE.properties",
    "content": "lexer.*.json=json\n\n# JSON keywords\nkeywords.*.json=false true null\n\n# JSON-LD keywords\nkeywords2.*.json=@id @context @type @value @language @container \\\n@list @set @reverse @index @base @vocab @graph\n\nlexer.json.escape.sequence=1\nlexer.json.allow.comments=1\nfold=1\nfold.compact=1\n\nmatch *_0.json\n\tlexer.json.escape.sequence=0\n\n"
  },
  {
    "path": "test/examples/json/embedded_0.json",
    "content": "{\n    \"k\": \"v\",\n    \"value\": \"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"https://domain.com/bin\\\"}]}\"\n    \"value\": \"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"@id\\\"}]}\"\n}\n"
  },
  {
    "path": "test/examples/json/embedded_0.json.folded",
    "content": " 2 400 401 + {\n 0 401 401 |     \"k\": \"v\",\n 0 401 401 |     \"value\": \"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"https://domain.com/bin\\\"}]}\"\n 0 401 401 |     \"value\": \"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"@id\\\"}]}\"\n 0 401 400 | }\n 0 400   0   "
  },
  {
    "path": "test/examples/json/embedded_0.json.styled",
    "content": "{8}{{0}\n    {4}\"k\"{8}:{0} {2}\"v\"{8},{0}\n    {4}\"value\"{8}:{0} {2}\"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"{9}https://domain.com/bin{2}\\\"}]}\"{0}\n    {4}\"value\"{8}:{0} {2}\"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"{12}@id{2}\\\"}]}\"{0}\n{8}}{0}\n"
  },
  {
    "path": "test/examples/json/embedded_1.json",
    "content": "{\n    \"k\": \"v\",\n    \"value\": \"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"https://domain.com/bin\\\"}]}\"\n    \"value\": \"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"@id\\\"}]}\"\n}\n"
  },
  {
    "path": "test/examples/json/embedded_1.json.folded",
    "content": " 2 400 401 + {\n 0 401 401 |     \"k\": \"v\",\n 0 401 401 |     \"value\": \"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"https://domain.com/bin\\\"}]}\"\n 0 401 401 |     \"value\": \"{\\\"k\\\":\\\"v\\\",\\\"list\\\":[{\\\"url\\\":\\\"@id\\\"}]}\"\n 0 401 400 | }\n 0 400   0   "
  },
  {
    "path": "test/examples/json/embedded_1.json.styled",
    "content": "{8}{{0}\n    {4}\"k\"{8}:{0} {2}\"v\"{8},{0}\n    {4}\"value\"{8}:{0} {2}\"{{5}\\\"{2}k{5}\\\"{2}:{5}\\\"{2}v{5}\\\"{2},{5}\\\"{2}list{5}\\\"{2}:[{{5}\\\"{2}url{5}\\\"{2}:{5}\\\"{2}https://domain.com/bin{5}\\\"{2}}]}\"{0}\n    {4}\"value\"{8}:{0} {2}\"{{5}\\\"{2}k{5}\\\"{2}:{5}\\\"{2}v{5}\\\"{2},{5}\\\"{2}list{5}\\\"{2}:[{{5}\\\"{2}url{5}\\\"{2}:{5}\\\"{2}@id{5}\\\"{2}}]}\"{0}\n{8}}{0}\n"
  },
  {
    "path": "test/examples/json/processed_0.json",
    "content": "{\n    \"k\": \"v\",\n    \"list\": [\n        {\n            \"url\": \"https://domain.com/bin\"\n            \"url\": \"@id\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/examples/json/processed_0.json.folded",
    "content": " 2 400 401 + {\n 0 401 401 |     \"k\": \"v\",\n 2 401 402 +     \"list\": [\n 2 402 403 +         {\n 0 403 403 |             \"url\": \"https://domain.com/bin\"\n 0 403 403 |             \"url\": \"@id\"\n 0 403 402 |         }\n 0 402 401 |     ]\n 0 401 400 | }\n 0 400   0   "
  },
  {
    "path": "test/examples/json/processed_0.json.styled",
    "content": "{8}{{0}\n    {4}\"k\"{8}:{0} {2}\"v\"{8},{0}\n    {4}\"list\"{8}:{0} {8}[{0}\n        {8}{{0}\n            {4}\"url\"{8}:{0} {2}\"{9}https://domain.com/bin{2}\"{0}\n            {4}\"url\"{8}:{0} {2}\"{12}@id{2}\"{0}\n        {8}}{0}\n    {8}]{0}\n{8}}{0}\n"
  },
  {
    "path": "test/examples/json/processed_esc_0.json",
    "content": "{\n    \"k\": \"v\",\n    \"list\": [\n        {\n            \"url\": \"https://domain.com/bin\\\"\"\n            \"url\": \"@id\\\"\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/examples/json/processed_esc_0.json.folded",
    "content": " 2 400 401 + {\n 0 401 401 |     \"k\": \"v\",\n 2 401 402 +     \"list\": [\n 2 402 403 +         {\n 0 403 403 |             \"url\": \"https://domain.com/bin\\\"\"\n 0 403 403 |             \"url\": \"@id\\\"\"\n 0 403 402 |         }\n 0 402 401 |     ]\n 0 401 400 | }\n 0 400   0   "
  },
  {
    "path": "test/examples/json/processed_esc_0.json.styled",
    "content": "{8}{{0}\n    {4}\"k\"{8}:{0} {2}\"v\"{8},{0}\n    {4}\"list\"{8}:{0} {8}[{0}\n        {8}{{0}\n            {4}\"url\"{8}:{0} {2}\"{9}https://domain.com/bin{2}\\\"\"{0}\n            {4}\"url\"{8}:{0} {2}\"{12}@id{2}\\\"\"{0}\n        {8}}{0}\n    {8}]{0}\n{8}}{0}\n"
  },
  {
    "path": "test/examples/json/processed_esc_1.json",
    "content": "{\n    \"k\": \"v\",\n    \"list\": [\n        {\n            \"url\": \"https://domain.com/bin\\\"\"\n            \"url\": \"@id\\\"\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/examples/json/processed_esc_1.json.folded",
    "content": " 2 400 401 + {\n 0 401 401 |     \"k\": \"v\",\n 2 401 402 +     \"list\": [\n 2 402 403 +         {\n 0 403 403 |             \"url\": \"https://domain.com/bin\\\"\"\n 0 403 403 |             \"url\": \"@id\\\"\"\n 0 403 402 |         }\n 0 402 401 |     ]\n 0 401 400 | }\n 0 400   0   "
  },
  {
    "path": "test/examples/json/processed_esc_1.json.styled",
    "content": "{8}{{0}\n    {4}\"k\"{8}:{0} {2}\"v\"{8},{0}\n    {4}\"list\"{8}:{0} {8}[{0}\n        {8}{{0}\n            {4}\"url\"{8}:{0} {2}\"{9}https://domain.com/bin{5}\\\"{2}\"{0}\n            {4}\"url\"{8}:{0} {2}\"{12}@id{5}\\\"{2}\"{0}\n        {8}}{0}\n    {8}]{0}\n{8}}{0}\n"
  },
  {
    "path": "test/examples/julia/SciTE.properties",
    "content": "lexer.*.jl=julia\nkeywords.*.jl=const end for function in where\nkeywords2.*.jl=Int Number\nkeywords3.*.jl=true\ntestlexers.per.line.disable=1\n"
  },
  {
    "path": "test/examples/julia/x.jl",
    "content": "\n# Comment here\nconst bar = '\\n'\n\n\"\"\"\n    test_fun(a::Int)\nFor test only\n\"\"\"\nfunction test_fun(a::Int, b::T) where T <: Number\n    println(a)\n    println(\"foo $(bar)\")\nend\n\n@enum Unicode α=1 β=2\n\nres = [√i for i in 1:10]\n∀=1; ∃=2; ∄=3;\n\nt!'#'\nt!='#'\nt[]!='#'\n\n#= Dummy function =#\ntest_fun²(:sym, true, raw\"test\", `echo 1`)\n"
  },
  {
    "path": "test/examples/julia/x.jl.folded",
    "content": " 0 400 400   \n 0 400 400   # Comment here\n 0 400 400   const bar = '\\n'\n 0 400 400   \n 2 400 401 + \"\"\"\n 0 401 401 |     test_fun(a::Int)\n 0 401 401 | For test only\n 0 401 400 | \"\"\"\n 2 400 401 + function test_fun(a::Int, b::T) where T <: Number\n 0 401 401 |     println(a)\n 0 401 401 |     println(\"foo $(bar)\")\n 0 401 400 | end\n 0 400 400   \n 0 400 400   @enum Unicode α=1 β=2\n 0 400 400   \n 0 400 400   res = [√i for i in 1:10]\n 0 400 400   ∀=1; ∃=2; ∄=3;\n 0 400 400   \n 0 400 400   t!'#'\n 0 400 400   t!='#'\n 0 400 400   t[]!='#'\n 0 400 400   \n 0 400 400   #= Dummy function =#\n 0 400 400   test_fun²(:sym, true, raw\"test\", `echo 1`)\n 1 400 400   "
  },
  {
    "path": "test/examples/julia/x.jl.styled",
    "content": "{0}\n{1}# Comment here{0}\n{3}const{0} {9}bar{0} {7}={0} {6}'\\n'{0}\n\n{14}\"\"\"\n    test_fun(a::Int)\nFor test only\n\"\"\"{0}\n{3}function{0} {9}test_fun{8}({9}a{21}::{4}Int{7},{0} {9}b{21}::{9}T{8}){0} {3}where{0} {9}T{0} {21}<:{0} {4}Number{0}\n    {9}println{8}({9}a{8}){0}\n    {9}println{8}({10}\"foo {13}$(bar){10}\"{8}){0}\n{3}end{0}\n\n{12}@enum{0} {9}Unicode{0} {9}α{7}={2}1{0} {9}β{7}={2}2{0}\n\n{9}res{0} {7}={0} {8}[{7}√{9}i{0} {3}for{0} {9}i{0} {3}in{0} {2}1{7}:{2}10{8}]{0}\n{9}∀{7}={2}1{7};{0} {9}∃{7}={2}2{7};{0} {9}∄{7}={2}3{7};{0}\n\n{9}t!{7}'{1}#'{0}\n{9}t!{7}={6}'#'{0}\n{9}t{8}[]{7}!={6}'#'{0}\n\n{1}#= Dummy function =#{0}\n{9}test_fun²{8}({11}:sym{7},{0} {5}true{7},{0} {15}raw{10}\"test\"{7},{0} {16}`echo 1`{8}){0}\n"
  },
  {
    "path": "test/examples/latex/AllStyles.tex",
    "content": "% Enumerate all styles: 0 to 12\n% Not a valid laTeX file as entities are unbalanced and not semantically correct\n% comment=4\n\n% whitespace=0\ntext\t%\n\n% command=1\n\\documentclass\n\n% tag=2\n\\begin{document}\n\n% tag closing=5\n\\end{document}\n\n% math=3\n\\begin{math}\nE &= mc^2\n\\end{math}\n\n% math block=6\n\\begin{align}\nE &= mc^2\n\\end{align}\n\n% comment block=7\n\\begin{comment}\nA block comment\n\\end{comment}\n\n% verbatim=8\n\\begin{verbatim}\nputs $foo\n\\end{verbatim}\n\n% short command=9\n\\(\\)\n\n% special=10\n\\#\n\n% command optional argument=11\n\\x[12pt]\n\n% error=12\n\\\n"
  },
  {
    "path": "test/examples/latex/AllStyles.tex.folded",
    "content": " 0 400   0   % Enumerate all styles: 0 to 12\n 0 400   0   % Not a valid laTeX file as entities are unbalanced and not semantically correct\n 0 400   0   % comment=4\n 0 400   0   \n 0 400   0   % whitespace=0\n 0 400   0   text\t%\n 0 400   0   \n 0 400   0   % command=1\n 0 400   0   \\documentclass\n 0 400   0   \n 0 400   0   % tag=2\n 2 400   0 + \\begin{document}\n 0 401   0 | \n 0 401   0 | % tag closing=5\n 0 401   0 | \\end{document}\n 0 400   0   \n 0 400   0   % math=3\n 2 400   0 + \\begin{math}\n 0 401   0 | E &= mc^2\n 0 401   0 | \\end{math}\n 0 400   0   \n 0 400   0   % math block=6\n 2 400   0 + \\begin{align}\n 0 401   0 | E &= mc^2\n 0 401   0 | \\end{align}\n 0 400   0   \n 0 400   0   % comment block=7\n 2 400   0 + \\begin{comment}\n 0 401   0 | A block comment\n 0 401   0 | \\end{comment}\n 0 400   0   \n 0 400   0   % verbatim=8\n 2 400   0 + \\begin{verbatim}\n 0 401   0 | puts $foo\n 0 401   0 | \\end{verbatim}\n 0 400   0   \n 0 400   0   % short command=9\n 0 400   0   \\(\\)\n 0 400   0   \n 0 400   0   % special=10\n 0 400   0   \\#\n 0 400   0   \n 0 400   0   % command optional argument=11\n 0 400   0   \\x[12pt]\n 0 400   0   \n 0 400   0   % error=12\n 0 400   0   \\\n 0 400   0   "
  },
  {
    "path": "test/examples/latex/AllStyles.tex.styled",
    "content": "{4}% Enumerate all styles: 0 to 12{0}\n{4}% Not a valid laTeX file as entities are unbalanced and not semantically correct{0}\n{4}% comment=4{0}\n\n{4}% whitespace=0{0}\ntext\t{4}%{0}\n\n{4}% command=1{0}\n{1}\\documentclass{0}\n\n{4}% tag=2{0}\n{1}\\begin{2}{document}{0}\n\n{4}% tag closing=5{0}\n{1}\\end{5}{document}{0}\n\n{4}% math=3{0}\n{1}\\begin{2}{math}{3}\nE &= mc^2\n{1}\\end{5}{math}{0}\n\n{4}% math block=6{0}\n{1}\\begin{2}{align}{6}\nE &= mc^2\n{1}\\end{5}{align}{0}\n\n{4}% comment block=7{0}\n{1}\\begin{2}{comment}{7}\nA block comment\n{1}\\end{5}{comment}{0}\n\n{4}% verbatim=8{0}\n{1}\\begin{2}{verbatim}{8}\nputs $foo\n{1}\\end{5}{verbatim}{0}\n\n{4}% short command=9{0}\n{9}\\(\\){0}\n\n{4}% special=10{0}\n{10}\\#{0}\n\n{4}% command optional argument=11{0}\n{1}\\x{11}[12pt]{0}\n\n{4}% error=12{0}\n{12}\\{0}\n"
  },
  {
    "path": "test/examples/latex/CornerCases.tex",
    "content": "$ \\ \\$ $\n$\\\n%comment\n$\n\\[ a \\]\n$$ b $$\n\\verb|c|\n\\[\n\\ \\text{$a$}\\\n% Comment\n\\]\n\\verb| a\n\\begin a\n"
  },
  {
    "path": "test/examples/latex/CornerCases.tex.folded",
    "content": " 0 400   0   $ \\ \\$ $\n 0 400   0   $\\\n 0 400   0   %comment\n 0 400   0   $\n 0 400   0   \\[ a \\]\n 0 400   0   $$ b $$\n 0 400   0   \\verb|c|\n 0 400   0   \\[\n 0 400   0   \\ \\text{$a$}\\\n 0 400   0   % Comment\n 0 400   0   \\]\n 0 400   0   \\verb| a\n 2 400   0 + \\begin a\n 0 401   0 | "
  },
  {
    "path": "test/examples/latex/CornerCases.tex.styled",
    "content": "{9}${3} {10}\\ \\${3} {9}${0}\n{9}${12}\\{3}\n{4}%comment{3}\n{9}${0}\n{9}\\[{6} a {9}\\]{0}\n{9}$${6} b {9}$${0}\n{1}\\verb{8}|c|{0}\n{9}\\[{6}\n{10}\\ {1}\\text{6}{{9}${6}a{9}${6}}{12}\\{6}\n{4}% Comment{6}\n{9}\\]{0}\n{1}\\verb{12}| a{0}\n{1}\\begin{12} a{0}\n"
  },
  {
    "path": "test/examples/latex/EndOfFile1.tex",
    "content": "% Checks for file end after \\ in SCE_L_DEFAULT\n\\"
  },
  {
    "path": "test/examples/latex/EndOfFile1.tex.folded",
    "content": " 0 400   0   % Checks for file end after \\ in SCE_L_DEFAULT\n 0 400   0   \\"
  },
  {
    "path": "test/examples/latex/EndOfFile1.tex.styled",
    "content": "{4}% Checks for file end after \\ in SCE_L_DEFAULT{0}\n\\"
  },
  {
    "path": "test/examples/latex/EndOfFile2.tex",
    "content": "% Checks for file end inside SCE_L_TAG\n\\begin{env"
  },
  {
    "path": "test/examples/latex/EndOfFile2.tex.folded",
    "content": " 0 400   0   % Checks for file end inside SCE_L_TAG\n 2 400   0 + \\begin{env"
  },
  {
    "path": "test/examples/latex/EndOfFile2.tex.styled",
    "content": "{4}% Checks for file end inside SCE_L_TAG{0}\n{1}\\begin{12}{env"
  },
  {
    "path": "test/examples/latex/EndOfFile3.tex",
    "content": "% Checks for file end inside SCE_L_TAG2\n\\end{env"
  },
  {
    "path": "test/examples/latex/EndOfFile3.tex.folded",
    "content": " 0 400   0   % Checks for file end inside SCE_L_TAG2\n 0 400   0   \\end{env"
  },
  {
    "path": "test/examples/latex/EndOfFile3.tex.styled",
    "content": "{4}% Checks for file end inside SCE_L_TAG2{0}\n{1}\\end{12}{env"
  },
  {
    "path": "test/examples/latex/EndOfFile4.tex",
    "content": "% Checks for file end after \\ in SCE_L_MATH\n$\\"
  },
  {
    "path": "test/examples/latex/EndOfFile4.tex.folded",
    "content": " 0 400   0   % Checks for file end after \\ in SCE_L_MATH\n 0 400   0   $\\"
  },
  {
    "path": "test/examples/latex/EndOfFile4.tex.styled",
    "content": "{4}% Checks for file end after \\ in SCE_L_MATH{0}\n{9}${3}\\"
  },
  {
    "path": "test/examples/latex/EndOfFile5.tex",
    "content": "% Checks for file end after \\ in SCE_L_MATH2\n\\begin{equation}\\"
  },
  {
    "path": "test/examples/latex/EndOfFile5.tex.folded",
    "content": " 0 400   0   % Checks for file end after \\ in SCE_L_MATH2\n 2 400   0 + \\begin{equation}\\"
  },
  {
    "path": "test/examples/latex/EndOfFile5.tex.styled",
    "content": "{4}% Checks for file end after \\ in SCE_L_MATH2{0}\n{1}\\begin{2}{equation}{6}\\"
  },
  {
    "path": "test/examples/latex/EndOfFile6.tex",
    "content": "% Checks for file end in SCE_L_COMMAND\n\\cmd"
  },
  {
    "path": "test/examples/latex/EndOfFile6.tex.folded",
    "content": " 0 400   0   % Checks for file end in SCE_L_COMMAND\n 0 400   0   \\cmd"
  },
  {
    "path": "test/examples/latex/EndOfFile6.tex.styled",
    "content": "{4}% Checks for file end in SCE_L_COMMAND{0}\n{1}\\cmd"
  },
  {
    "path": "test/examples/latex/EndOfFile7.tex",
    "content": "% Checks for file end while looking for SCE_L_TAG\n\\begin "
  },
  {
    "path": "test/examples/latex/EndOfFile7.tex.folded",
    "content": " 0 400   0   % Checks for file end while looking for SCE_L_TAG\n 2 400   0 + \\begin "
  },
  {
    "path": "test/examples/latex/EndOfFile7.tex.styled",
    "content": "{4}% Checks for file end while looking for SCE_L_TAG{0}\n{1}\\begin{12} "
  },
  {
    "path": "test/examples/latex/Feature1358.tex",
    "content": "\\begin{lstlisting}[language=make]\n# If no BOARD is found in the environment, use this default:\nBOARD ?= bluepill\n\n# To use chinese st-link v2 and ch340 dongle with bluepill\nifeq ($(BOARD),bluepill)\nSTLINK_VERSION=2\nPORT_LINUX=/dev/ttyUSB0\nendif\n\\end{lstlisting}\n"
  },
  {
    "path": "test/examples/latex/Feature1358.tex.folded",
    "content": " 2 400   0 + \\begin{lstlisting}[language=make]\n 0 401   0 | # If no BOARD is found in the environment, use this default:\n 0 401   0 | BOARD ?= bluepill\n 0 401   0 | \n 0 401   0 | # To use chinese st-link v2 and ch340 dongle with bluepill\n 0 401   0 | ifeq ($(BOARD),bluepill)\n 0 401   0 | STLINK_VERSION=2\n 0 401   0 | PORT_LINUX=/dev/ttyUSB0\n 0 401   0 | endif\n 0 401   0 | \\end{lstlisting}\n 0 400   0   "
  },
  {
    "path": "test/examples/latex/Feature1358.tex.styled",
    "content": "{1}\\begin{2}{lstlisting}{8}[language=make]\n# If no BOARD is found in the environment, use this default:\nBOARD ?= bluepill\n\n# To use chinese st-link v2 and ch340 dongle with bluepill\nifeq ($(BOARD),bluepill)\nSTLINK_VERSION=2\nPORT_LINUX=/dev/ttyUSB0\nendif\n{1}\\end{5}{lstlisting}{0}\n"
  },
  {
    "path": "test/examples/latex/SciTE.properties",
    "content": "lexer.*.tex=latex\n"
  },
  {
    "path": "test/examples/lua/AllStyles.lua",
    "content": "-- Enumerate all styles: 0 to 20\n-- 3 (comment doc) is not currently produced by lexer\n\n--[[ comment=1 ]]\n\n--[[ whitespace=0 ]]\n\t-- w\n\n-- comment line=2\n\n--- comment doc=3\n-- still comment doc\n\n-- still comment doc\n3\t-- comment doc broken only by code\n\n-- number=4\n37\n\n-- keyword=5\nlocal a\n\n-- double-quoted-string=6\n\"str\"\n\n-- single-quoted-string=7\n'str'\n\n-- literal string=8\n[[ literal ]]\n\n-- unused preprocessor=9\n$if\n\n-- operator=10\n*\n\n-- identifier=11\nidentifier=1\n\n-- string EOL=12\n\"unclosed\n\n-- keyword 2=13\nprint\n\n-- keyword 3=14\nkeyword3\n\n-- keyword 4=15\nkeyword4\n\n-- keyword 5=16\nkeyword5\n\n-- keyword 6=17\nkeyword6\n\n-- keyword 7=18\nkeyword7\n\n-- keyword 8=19\nkeyword8\n\n-- label=20\n::label::\n\n-- identifier substyles.11.1=128\nmoon\n"
  },
  {
    "path": "test/examples/lua/AllStyles.lua.folded",
    "content": " 0 400   0   -- Enumerate all styles: 0 to 20\n 0 400   0   -- 3 (comment doc) is not currently produced by lexer\n 1 400   0   \n 0 400   0   --[[ comment=1 ]]\n 1 400   0   \n 0 400   0   --[[ whitespace=0 ]]\n 0 400   0   \t-- w\n 1 400   0   \n 0 400   0   -- comment line=2\n 1 400   0   \n 0 400   0   --- comment doc=3\n 0 400   0   -- still comment doc\n 1 400   0   \n 0 400   0   -- still comment doc\n 0 400   0   3\t-- comment doc broken only by code\n 1 400   0   \n 0 400   0   -- number=4\n 0 400   0   37\n 1 400   0   \n 0 400   0   -- keyword=5\n 0 400   0   local a\n 1 400   0   \n 0 400   0   -- double-quoted-string=6\n 0 400   0   \"str\"\n 1 400   0   \n 0 400   0   -- single-quoted-string=7\n 0 400   0   'str'\n 1 400   0   \n 0 400   0   -- literal string=8\n 0 400   0   [[ literal ]]\n 1 400   0   \n 0 400   0   -- unused preprocessor=9\n 0 400   0   $if\n 1 400   0   \n 0 400   0   -- operator=10\n 0 400   0   *\n 1 400   0   \n 0 400   0   -- identifier=11\n 0 400   0   identifier=1\n 1 400   0   \n 0 400   0   -- string EOL=12\n 0 400   0   \"unclosed\n 1 400   0   \n 0 400   0   -- keyword 2=13\n 0 400   0   print\n 1 400   0   \n 0 400   0   -- keyword 3=14\n 0 400   0   keyword3\n 1 400   0   \n 0 400   0   -- keyword 4=15\n 0 400   0   keyword4\n 1 400   0   \n 0 400   0   -- keyword 5=16\n 0 400   0   keyword5\n 1 400   0   \n 0 400   0   -- keyword 6=17\n 0 400   0   keyword6\n 1 400   0   \n 0 400   0   -- keyword 7=18\n 0 400   0   keyword7\n 1 400   0   \n 0 400   0   -- keyword 8=19\n 0 400   0   keyword8\n 1 400   0   \n 0 400   0   -- label=20\n 0 400   0   ::label::\n 1 400   0   \n 0 400   0   -- identifier substyles.11.1=128\n 0 400   0   moon\n 0 400   0   "
  },
  {
    "path": "test/examples/lua/AllStyles.lua.styled",
    "content": "{2}-- Enumerate all styles: 0 to 20\n-- 3 (comment doc) is not currently produced by lexer\n{0}\n{1}--[[ comment=1 ]]{0}\n\n{1}--[[ whitespace=0 ]]{0}\n\t{2}-- w\n{0}\n{2}-- comment line=2\n{0}\n{3}--- comment doc=3\n-- still comment doc\n{0}\n{3}-- still comment doc\n{4}3{0}\t{2}-- comment doc broken only by code\n{0}\n{2}-- number=4\n{4}37{0}\n\n{2}-- keyword=5\n{5}local{0} {11}a{0}\n\n{2}-- double-quoted-string=6\n{6}\"str\"{0}\n\n{2}-- single-quoted-string=7\n{7}'str'{0}\n\n{2}-- literal string=8\n{8}[[ literal ]]{0}\n\n{2}-- unused preprocessor=9\n{9}$if\n{0}\n{2}-- operator=10\n{10}*{0}\n\n{2}-- identifier=11\n{11}identifier{10}={4}1{0}\n\n{2}-- string EOL=12\n{12}\"unclosed\n{0}\n{2}-- keyword 2=13\n{13}print{0}\n\n{2}-- keyword 3=14\n{14}keyword3{0}\n\n{2}-- keyword 4=15\n{15}keyword4{0}\n\n{2}-- keyword 5=16\n{16}keyword5{0}\n\n{2}-- keyword 6=17\n{17}keyword6{0}\n\n{2}-- keyword 7=18\n{18}keyword7{0}\n\n{2}-- keyword 8=19\n{19}keyword8{0}\n\n{2}-- label=20\n{20}::label::{0}\n\n{2}-- identifier substyles.11.1=128\n{128}moon{0}\n"
  },
  {
    "path": "test/examples/lua/Bug2205.lua",
    "content": "print(\"First\")\n--[[ Block comment start\nprint(\"Second\")\n--[[ Another block comment ]]\nprint(\"Third. If run through an actual program, this will be executed.\")\n"
  },
  {
    "path": "test/examples/lua/Bug2205.lua.folded",
    "content": " 0 400   0   print(\"First\")\n 2 400   0 + --[[ Block comment start\n 0 401   0 | print(\"Second\")\n 0 401   0 | --[[ Another block comment ]]\n 0 400   0   print(\"Third. If run through an actual program, this will be executed.\")\n 0 400   0   "
  },
  {
    "path": "test/examples/lua/Bug2205.lua.styled",
    "content": "{13}print{10}({6}\"First\"{10}){0}\n{1}--[[ Block comment start\nprint(\"Second\")\n--[[ Another block comment ]]{0}\n{13}print{10}({6}\"Third. If run through an actual program, this will be executed.\"{10}){0}\n"
  },
  {
    "path": "test/examples/lua/SciTE.properties",
    "content": "lexer.*.lua=lua\nkeywords.*.lua=do else elseif end for function if local repeat then until while\nkeywords2.*.lua=print\nkeywords3.*.lua=keyword3\nkeywords4.*.lua=keyword4\nkeywords5.*.lua=keyword5\nkeywords6.*.lua=keyword6\nkeywords7.*.lua=keyword7\nkeywords8.*.lua=keyword8\n\nsubstyles.lua.11=1\nsubstylewords.11.1.*.lua=moon\n\nfold=1\n"
  },
  {
    "path": "test/examples/lua/folding.lua",
    "content": "--[[ coding:UTF-8\nfolding structure examples ]]\n\n-- Use all the folding keywords:\n--    do end function if repeat until while\nfunction first()\n   -- Comment\n   if op == \"+\" then\n      r = a + b\n    elseif op == \"-\" then\n      r = a - b\n    elseif op == \"*\" then\n      r = a*b\n    elseif op == \"/\" then\n      r = a/b\n    else\n      error(\"invalid operation\")\n    end\n\n    for i=1,10 do\n      print(i)\n    end\n\n    while a[i] do\n      print(a[i])\n      i = i + 1\n    end\n\n    -- print the first non-empty line\n    repeat\n      line = io.read()\n    until line ~= \"\"\n    print(line)\n\nend\n\n-- { ... } folds\nmarkers = {\n     256,\n     128,\n}\n"
  },
  {
    "path": "test/examples/lua/folding.lua.folded",
    "content": " 2 400   0 + --[[ coding:UTF-8\n 0 401   0 | folding structure examples ]]\n 1 400   0   \n 0 400   0   -- Use all the folding keywords:\n 0 400   0   --    do end function if repeat until while\n 2 400   0 + function first()\n 0 401   0 |    -- Comment\n 2 401   0 +    if op == \"+\" then\n 0 402   0 |       r = a + b\n 0 402   0 |     elseif op == \"-\" then\n 0 402   0 |       r = a - b\n 0 402   0 |     elseif op == \"*\" then\n 0 402   0 |       r = a*b\n 0 402   0 |     elseif op == \"/\" then\n 0 402   0 |       r = a/b\n 0 402   0 |     else\n 0 402   0 |       error(\"invalid operation\")\n 0 402   0 |     end\n 1 401   0 | \n 2 401   0 +     for i=1,10 do\n 0 402   0 |       print(i)\n 0 402   0 |     end\n 1 401   0 | \n 2 401   0 +     while a[i] do\n 0 402   0 |       print(a[i])\n 0 402   0 |       i = i + 1\n 0 402   0 |     end\n 1 401   0 | \n 0 401   0 |     -- print the first non-empty line\n 2 401   0 +     repeat\n 0 402   0 |       line = io.read()\n 0 402   0 |     until line ~= \"\"\n 0 401   0 |     print(line)\n 1 401   0 | \n 0 401   0 | end\n 1 400   0   \n 0 400   0   -- { ... } folds\n 2 400   0 + markers = {\n 0 401   0 |      256,\n 0 401   0 |      128,\n 0 401   0 | }\n 0 400   0   "
  },
  {
    "path": "test/examples/lua/folding.lua.styled",
    "content": "{1}--[[ coding:UTF-8\nfolding structure examples ]]{0}\n\n{2}-- Use all the folding keywords:\n--    do end function if repeat until while\n{5}function{0} {11}first{10}(){0}\n   {2}-- Comment\n{0}   {5}if{0} {11}op{0} {10}=={0} {6}\"+\"{0} {5}then{0}\n      {11}r{0} {10}={0} {11}a{0} {10}+{0} {11}b{0}\n    {5}elseif{0} {11}op{0} {10}=={0} {6}\"-\"{0} {5}then{0}\n      {11}r{0} {10}={0} {11}a{0} {10}-{0} {11}b{0}\n    {5}elseif{0} {11}op{0} {10}=={0} {6}\"*\"{0} {5}then{0}\n      {11}r{0} {10}={0} {11}a{10}*{11}b{0}\n    {5}elseif{0} {11}op{0} {10}=={0} {6}\"/\"{0} {5}then{0}\n      {11}r{0} {10}={0} {11}a{10}/{11}b{0}\n    {5}else{0}\n      {11}error{10}({6}\"invalid operation\"{10}){0}\n    {5}end{0}\n\n    {5}for{0} {11}i{10}={4}1{10},{4}10{0} {5}do{0}\n      {13}print{10}({11}i{10}){0}\n    {5}end{0}\n\n    {5}while{0} {11}a{10}[{11}i{10}]{0} {5}do{0}\n      {13}print{10}({11}a{10}[{11}i{10}]){0}\n      {11}i{0} {10}={0} {11}i{0} {10}+{0} {4}1{0}\n    {5}end{0}\n\n    {2}-- print the first non-empty line\n{0}    {5}repeat{0}\n      {11}line{0} {10}={0} {11}io.read{10}(){0}\n    {5}until{0} {11}line{0} {10}~={0} {6}\"\"{0}\n    {13}print{10}({11}line{10}){0}\n\n{5}end{0}\n\n{2}-- { ... } folds\n{11}markers{0} {10}={0} {10}{{0}\n     {4}256{10},{0}\n     {4}128{10},{0}\n{10}}{0}\n"
  },
  {
    "path": "test/examples/lua/nonASCII242.lua",
    "content": "﻿-- Tests behaviour with non-ASCII identifiers joined with '.' or ':'\n输出栏选择夹:加入子夹(\"提示\"):加入子夹(\"输出\"):加入子夹(\"提示&输出\"):加入子夹(\"Log\")\n支持库管理器:置坐标(0,工具栏:取高度() + 资源栏选择夹:取高度()):置宽高(分隔条_X.x,分隔条_Y:取坐标()):显示()\n\n選択グリップ:に参加(10,\"グリップ\"):に参加(\"グリップ\")\n\n클립선택:가입(\"레이블\")\nδέλτα:ζήτα(\"δέλτα\")\nźdźbło.krnąbrność(0)\n🍣😂:💮(\"😂\")\n\nstring:rep(\"ddf\"):gsub(\"ddf\",\"ffd\")\n"
  },
  {
    "path": "test/examples/lua/nonASCII242.lua.folded",
    "content": " 0 400   0   -- Tests behaviour with non-ASCII identifiers joined with '.' or ':'\n 0 400   0   输出栏选择夹:加入子夹(\"提示\"):加入子夹(\"输出\"):加入子夹(\"提示&输出\"):加入子夹(\"Log\")\n 0 400   0   支持库管理器:置坐标(0,工具栏:取高度() + 资源栏选择夹:取高度()):置宽高(分隔条_X.x,分隔条_Y:取坐标()):显示()\n 1 400   0   \n 0 400   0   選択グリップ:に参加(10,\"グリップ\"):に参加(\"グリップ\")\n 1 400   0   \n 0 400   0   클립선택:가입(\"레이블\")\n 0 400   0   δέλτα:ζήτα(\"δέλτα\")\n 0 400   0   źdźbło.krnąbrność(0)\n 0 400   0   🍣😂:💮(\"😂\")\n 1 400   0   \n 0 400   0   string:rep(\"ddf\"):gsub(\"ddf\",\"ffd\")\n 0 400   0   "
  },
  {
    "path": "test/examples/lua/nonASCII242.lua.styled",
    "content": "{2}-- Tests behaviour with non-ASCII identifiers joined with '.' or ':'\n{11}输出栏选择夹:加入子夹{10}({6}\"提示\"{10}):{11}加入子夹{10}({6}\"输出\"{10}):{11}加入子夹{10}({6}\"提示&输出\"{10}):{11}加入子夹{10}({6}\"Log\"{10}){0}\n{11}支持库管理器:置坐标{10}({4}0{10},{11}工具栏:取高度{10}(){0} {10}+{0} {11}资源栏选择夹:取高度{10}()):{11}置宽高{10}({11}分隔条_X.x{10},{11}分隔条_Y:取坐标{10}()):{11}显示{10}(){0}\n\n{11}選択グリップ:に参加{10}({4}10{10},{6}\"グリップ\"{10}):{11}に参加{10}({6}\"グリップ\"{10}){0}\n\n{11}클립선택:가입{10}({6}\"레이블\"{10}){0}\n{11}δέλτα:ζήτα{10}({6}\"δέλτα\"{10}){0}\n{11}źdźbło.krnąbrność{10}({4}0{10}){0}\n{11}🍣😂:💮{10}({6}\"😂\"{10}){0}\n\n{11}string:rep{10}({6}\"ddf\"{10}):{11}gsub{10}({6}\"ddf\"{10},{6}\"ffd\"{10}){0}\n"
  },
  {
    "path": "test/examples/lua/x.lua",
    "content": "--[[ coding:UTF-8\ncomment ]]\nfunction first()\n::開::\n   -- Comment\n   func(SCI_ANNOTATIONSETTEXT, 'a', 0, \"LINE1\")\nend\n"
  },
  {
    "path": "test/examples/lua/x.lua.folded",
    "content": " 2 400   0 + --[[ coding:UTF-8\n 0 401   0 | comment ]]\n 2 400   0 + function first()\n 0 401   0 | ::開::\n 0 401   0 |    -- Comment\n 0 401   0 |    func(SCI_ANNOTATIONSETTEXT, 'a', 0, \"LINE1\")\n 0 401   0 | end\n 0 400   0   "
  },
  {
    "path": "test/examples/lua/x.lua.styled",
    "content": "{1}--[[ coding:UTF-8\ncomment ]]{0}\n{5}function{0} {11}first{10}(){0}\n{20}::開::{0}\n   {2}-- Comment\n{0}   {11}func{10}({11}SCI_ANNOTATIONSETTEXT{10},{0} {7}'a'{10},{0} {4}0{10},{0} {6}\"LINE1\"{10}){0}\n{5}end{0}\n"
  },
  {
    "path": "test/examples/makefile/40Comment.mak",
    "content": "# Comment\n\ntest = 5 # Comment\n\n$(info $(test)) # Comment\n\nclean: # Comment\n\techo # Not comment\n\n# Quoting a #\nHASH = \\#\n\n# Inside variable reference\nOUT = $(#SYM)\n\n# Inside function call\nX = $(subst /,#,$1)\n"
  },
  {
    "path": "test/examples/makefile/40Comment.mak.folded",
    "content": " 0 400   0   # Comment\n 0 400   0   \n 0 400   0   test = 5 # Comment\n 0 400   0   \n 0 400   0   $(info $(test)) # Comment\n 0 400   0   \n 0 400   0   clean: # Comment\n 0 400   0   \techo # Not comment\n 0 400   0   \n 0 400   0   # Quoting a #\n 0 400   0   HASH = \\#\n 0 400   0   \n 0 400   0   # Inside variable reference\n 0 400   0   OUT = $(#SYM)\n 0 400   0   \n 0 400   0   # Inside function call\n 0 400   0   X = $(subst /,#,$1)\n 0 400   0   "
  },
  {
    "path": "test/examples/makefile/40Comment.mak.styled",
    "content": "{1}# Comment\n{0}\n{3}test{0} {4}={0} 5 {1}# Comment\n{0}\n{3}$(info $(test)){0} {1}# Comment\n{0}\n{5}clean{4}:{0} {1}# Comment\n{0}\techo # Not comment\n\n{1}# Quoting a #\n{3}HASH{0} {4}={0} \\#\n\n{1}# Inside variable reference\n{3}OUT{0} {4}={0} {3}$(#SYM){0}\n\n{1}# Inside function call\n{3}X{0} {4}={0} {3}$(subst /,#,$1){0}\n"
  },
  {
    "path": "test/examples/makefile/SciTE.properties",
    "content": "lexer.*.mak=makefile\nkeywords.*.mak=ifdef\n"
  },
  {
    "path": "test/examples/makefile/longline.mak",
    "content": "# makefile lexer previously used fixed 1024-byte line buffer that would treat text after that as new line\n\n# Long line with 1025 bytes last 2 bytes colored as default 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678912345678\n\n"
  },
  {
    "path": "test/examples/makefile/longline.mak.folded",
    "content": " 0 400   0   # makefile lexer previously used fixed 1024-byte line buffer that would treat text after that as new line\n 0 400   0   \n 0 400   0   # Long line with 1025 bytes last 2 bytes colored as default 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678912345678\n 0 400   0   \n 0 400   0   "
  },
  {
    "path": "test/examples/makefile/longline.mak.styled",
    "content": "{1}# makefile lexer previously used fixed 1024-byte line buffer that would treat text after that as new line\n{0}\n{1}# Long line with 1025 bytes last 2 bytes colored as default 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678912345678\n{0}\n"
  },
  {
    "path": "test/examples/makefile/x.mak",
    "content": "# '# comment' comment=1\n# comment\n\n# '.SUFFIXES' target=5, ':' operator=4\n.SUFFIXES:\n\n# 'LD' identifier=3, '=' operator=4, 'link' default=0\nLD=link\n\n# '!IFDEF DEBUG' NMAKE preprocessor=2\n!IFDEF DEBUG\n\n# 'ifdef DEBUG' GNI make directive default=0\nifdef DEBUG\n\n# '$(' ID EOL=9\nX=$(\n\n# Recipe with variable reference $(CXX)\ncake.o: cake.cxx\n\t$(CXX) -c $< -o $@\n\n# End of file\n"
  },
  {
    "path": "test/examples/makefile/x.mak.folded",
    "content": " 0 400   0   # '# comment' comment=1\n 0 400   0   # comment\n 0 400   0   \n 0 400   0   # '.SUFFIXES' target=5, ':' operator=4\n 0 400   0   .SUFFIXES:\n 0 400   0   \n 0 400   0   # 'LD' identifier=3, '=' operator=4, 'link' default=0\n 0 400   0   LD=link\n 0 400   0   \n 0 400   0   # '!IFDEF DEBUG' NMAKE preprocessor=2\n 0 400   0   !IFDEF DEBUG\n 0 400   0   \n 0 400   0   # 'ifdef DEBUG' GNI make directive default=0\n 0 400   0   ifdef DEBUG\n 0 400   0   \n 0 400   0   # '$(' ID EOL=9\n 0 400   0   X=$(\n 0 400   0   \n 0 400   0   # Recipe with variable reference $(CXX)\n 0 400   0   cake.o: cake.cxx\n 0 400   0   \t$(CXX) -c $< -o $@\n 0 400   0   \n 0 400   0   # End of file\n 0 400   0   "
  },
  {
    "path": "test/examples/makefile/x.mak.styled",
    "content": "{1}# '# comment' comment=1\n# comment\n{0}\n{1}# '.SUFFIXES' target=5, ':' operator=4\n{5}.SUFFIXES{4}:{0}\n\n{1}# 'LD' identifier=3, '=' operator=4, 'link' default=0\n{3}LD{4}={0}link\n\n{1}# '!IFDEF DEBUG' NMAKE preprocessor=2\n{2}!IFDEF DEBUG\n{0}\n{1}# 'ifdef DEBUG' GNI make directive default=0\n{2}ifdef{0} DEBUG\n\n{1}# '$(' ID EOL=9\n{3}X{4}={9}$(\n{0}\n{1}# Recipe with variable reference $(CXX)\n{5}cake.o{4}:{0} cake.cxx\n\t{3}$(CXX){0} -c $< -o $@\n\n{1}# End of file\n"
  },
  {
    "path": "test/examples/markdown/AllStyles.md",
    "content": "Text=0\nLine end characters=1\n**Strong Emphasis (bold) 1=2**\n__Strong Emphasis (bold) 2=3__\n*Emphasis (italic) 1=4*\n_Emphasis (italic) 2=5_\n# Heading level 1=6\n## Heading level 2=7\n### Heading level 3=8\n#### Heading level 4=9\n##### Heading level 5=10\n###### Heading level 6=11\n   PreChar=12\n* Unordered list item=13\n1. Ordered list item=14\n>Block Quote=15\n~~Strike-out=16~~\n\n***\nPrevious line was horizontal rule=17\n[Link=18](https://18.com)\n`Inline Code=19`\n``Inline Code=20``\n\n~~~\nBlock code=21\n~~~\n\n## Issue 23\n`"
  },
  {
    "path": "test/examples/markdown/AllStyles.md.folded",
    "content": " 0 400   0   Text=0\n 0 400   0   Line end characters=1\n 0 400   0   **Strong Emphasis (bold) 1=2**\n 0 400   0   __Strong Emphasis (bold) 2=3__\n 0 400   0   *Emphasis (italic) 1=4*\n 0 400   0   _Emphasis (italic) 2=5_\n 0 400   0   # Heading level 1=6\n 0 400   0   ## Heading level 2=7\n 0 400   0   ### Heading level 3=8\n 0 400   0   #### Heading level 4=9\n 0 400   0   ##### Heading level 5=10\n 0 400   0   ###### Heading level 6=11\n 0 400   0      PreChar=12\n 0 400   0   * Unordered list item=13\n 0 400   0   1. Ordered list item=14\n 0 400   0   >Block Quote=15\n 0 400   0   ~~Strike-out=16~~\n 0 400   0   \n 0 400   0   ***\n 0 400   0   Previous line was horizontal rule=17\n 0 400   0   [Link=18](https://18.com)\n 0 400   0   `Inline Code=19`\n 0 400   0   ``Inline Code=20``\n 0 400   0   \n 0 400   0   ~~~\n 0 400   0   Block code=21\n 0 400   0   ~~~\n 0 400   0   \n 0 400   0   ## Issue 23\n 0 400   0   `"
  },
  {
    "path": "test/examples/markdown/AllStyles.md.styled",
    "content": "{0}Text=0{1}\n{0}Line end characters=1{1}\n{2}**Strong Emphasis (bold) 1=2**{1}\n{3}__Strong Emphasis (bold) 2=3__{1}\n{4}*Emphasis (italic) 1=4*{1}\n{5}_Emphasis (italic) 2=5_{1}\n{6}#{0} Heading level 1=6{1}\n{7}##{0} Heading level 2=7{1}\n{8}###{0} Heading level 3=8{1}\n{9}####{0} Heading level 4=9{1}\n{10}#####{0} Heading level 5=10{1}\n{11}######{0} Heading level 6=11{1}\n{12}   {0}PreChar=12{1}\n{13}*{0} Unordered list item=13{1}\n{14}1.{0} Ordered list item=14{1}\n{15}>{0}Block Quote=15{1}\n{16}~~Strike-out=16~~{1}\n\n{17}***{1}\n{0}Previous line was horizontal rule=17{1}\n{18}[Link=18](https://18.com){1}\n{19}`Inline Code=19`{1}\n{20}``Inline Code=20``{1}\n\n{21}~~~\nBlock code=21\n~~~{1}\n\n{7}##{0} Issue 23{1}\n{0}`"
  },
  {
    "path": "test/examples/markdown/Bug1216.md",
    "content": "# Checking resolution of bug 1216\n\n*This line is not emphasized\n\nThis is plain text with *inline emphasis*\n\n_This, too, is not emphasized\n\nAnd this is plain text with _inline emphasis_\n\n**This line is not in bold\n\nBut this is plain text with some words **in bold**\n\n__This line is also not in bold\n\nAnd this is plain text with __some words in bold__\n\n~~This line is not crossed out\n\nThis is plain text with ~~some words crossed out~~\n\n~~~\nthis is a code block\n~~~\n\nThis is a new paragraph\n"
  },
  {
    "path": "test/examples/markdown/Bug1216.md.folded",
    "content": " 0 400   0   # Checking resolution of bug 1216\n 0 400   0   \n 0 400   0   *This line is not emphasized\n 0 400   0   \n 0 400   0   This is plain text with *inline emphasis*\n 0 400   0   \n 0 400   0   _This, too, is not emphasized\n 0 400   0   \n 0 400   0   And this is plain text with _inline emphasis_\n 0 400   0   \n 0 400   0   **This line is not in bold\n 0 400   0   \n 0 400   0   But this is plain text with some words **in bold**\n 0 400   0   \n 0 400   0   __This line is also not in bold\n 0 400   0   \n 0 400   0   And this is plain text with __some words in bold__\n 0 400   0   \n 0 400   0   ~~This line is not crossed out\n 0 400   0   \n 0 400   0   This is plain text with ~~some words crossed out~~\n 0 400   0   \n 0 400   0   ~~~\n 0 400   0   this is a code block\n 0 400   0   ~~~\n 0 400   0   \n 0 400   0   This is a new paragraph\n 0 400   0   "
  },
  {
    "path": "test/examples/markdown/Bug1216.md.styled",
    "content": "{6}#{0} Checking resolution of bug 1216{1}\n\n{0}*This line is not emphasized{1}\n\n{0}This is plain text with {4}*inline emphasis*{1}\n\n{0}_This, too, is not emphasized{1}\n\n{0}And this is plain text with {5}_inline emphasis_{1}\n\n{0}**This line is not in bold{1}\n\n{0}But this is plain text with some words {2}**in bold**{1}\n\n{0}__This line is also not in bold{1}\n\n{0}And this is plain text with {3}__some words in bold__{1}\n\n{0}~~This line is not crossed out{1}\n\n{0}This is plain text with {16}~~some words crossed out~~{1}\n\n{21}~~~\nthis is a code block\n~~~{1}\n\n{0}This is a new paragraph{1}\n"
  },
  {
    "path": "test/examples/markdown/Bug2235.md",
    "content": "Po spuštění modulu je zobrazen hlavní dialog modulu:\n\n![](media\\image21.png)V tomto dialogu lze nastavit různé\nparametry vykreslení výsledného schématu. Doporučujeme pro většinu\npřípadů ponechat přednastavené hodnoty.\n\nZákladní parametry ne nacházejí v záložce *Obecné*:\n\n![SciTE224.png][]V tomto dialogu lze nastavit různé\nparametry vykreslení výsledného schématu. Doporučujeme pro většinu\npřípadů ponechat přednastavené hodnoty.\n\nZákladní parametry ne nacházejí v záložce _Obecné_\n\n[SciTE224.png]: https://www.scintilla.org/SciTE224.png\n"
  },
  {
    "path": "test/examples/markdown/Bug2235.md.folded",
    "content": " 0 400   0   Po spuštění modulu je zobrazen hlavní dialog modulu:\n 0 400   0   \n 0 400   0   ![](media\\image21.png)V tomto dialogu lze nastavit různé\n 0 400   0   parametry vykreslení výsledného schématu. Doporučujeme pro většinu\n 0 400   0   případů ponechat přednastavené hodnoty.\n 0 400   0   \n 0 400   0   Základní parametry ne nacházejí v záložce *Obecné*:\n 0 400   0   \n 0 400   0   ![SciTE224.png][]V tomto dialogu lze nastavit různé\n 0 400   0   parametry vykreslení výsledného schématu. Doporučujeme pro většinu\n 0 400   0   případů ponechat přednastavené hodnoty.\n 0 400   0   \n 0 400   0   Základní parametry ne nacházejí v záložce _Obecné_\n 0 400   0   \n 0 400   0   [SciTE224.png]: https://www.scintilla.org/SciTE224.png\n 0 400   0   "
  },
  {
    "path": "test/examples/markdown/Bug2235.md.styled",
    "content": "{0}Po spuštění modulu je zobrazen hlavní dialog modulu:{1}\n\n{18}![](media\\image21.png){0}V tomto dialogu lze nastavit různé{1}\n{0}parametry vykreslení výsledného schématu. Doporučujeme pro většinu{1}\n{0}případů ponechat přednastavené hodnoty.{1}\n\n{0}Základní parametry ne nacházejí v záložce {4}*Obecné*{0}:{1}\n\n{18}![SciTE224.png][]{0}V tomto dialogu lze nastavit různé{1}\n{0}parametry vykreslení výsledného schématu. Doporučujeme pro většinu{1}\n{0}případů ponechat přednastavené hodnoty.{1}\n\n{0}Základní parametry ne nacházejí v záložce {5}_Obecné_{1}\n\n{18}[SciTE224.png]:{0} https://www.scintilla.org/SciTE224.png{1}\n"
  },
  {
    "path": "test/examples/markdown/Bug2247.md",
    "content": "# Checking resolution of bug 2247\n\n~~~sql\nSELECT datetime() AS `date`;\n~~~\n\n```sql\nSELECT datetime() AS `date`;\n```\n\nList of examples:\n\n-   example *one*\n\n-   example _two_\n\n-   example `inline code without end\n\n    In case of **AAA**:\n    \n    ```sql\n    SELECT strftime('%Y-%m-%d %H:%M:%S', 'now') AS `date`;\n    ```\n    \n    or, in case of __BBB__:\n    . . .\n\n-   example *three*\n\nLast paragraph.\n"
  },
  {
    "path": "test/examples/markdown/Bug2247.md.folded",
    "content": " 0 400   0   # Checking resolution of bug 2247\n 0 400   0   \n 0 400   0   ~~~sql\n 0 400   0   SELECT datetime() AS `date`;\n 0 400   0   ~~~\n 0 400   0   \n 0 400   0   ```sql\n 0 400   0   SELECT datetime() AS `date`;\n 0 400   0   ```\n 0 400   0   \n 0 400   0   List of examples:\n 0 400   0   \n 0 400   0   -   example *one*\n 0 400   0   \n 0 400   0   -   example _two_\n 0 400   0   \n 0 400   0   -   example `inline code without end\n 0 400   0   \n 0 400   0       In case of **AAA**:\n 0 400   0       \n 0 400   0       ```sql\n 0 400   0       SELECT strftime('%Y-%m-%d %H:%M:%S', 'now') AS `date`;\n 0 400   0       ```\n 0 400   0       \n 0 400   0       or, in case of __BBB__:\n 0 400   0       . . .\n 0 400   0   \n 0 400   0   -   example *three*\n 0 400   0   \n 0 400   0   Last paragraph.\n 0 400   0   "
  },
  {
    "path": "test/examples/markdown/Bug2247.md.styled",
    "content": "{6}#{0} Checking resolution of bug 2247{1}\n\n{21}~~~sql\nSELECT datetime() AS `date`;\n~~~{1}\n\n{20}```sql\nSELECT datetime() AS `date`;\n```{1}\n\n{0}List of examples:{1}\n\n{13}-{0}   example {4}*one*{1}\n\n{13}-{0}   example {5}_two_{1}\n\n{13}-{0}   example `inline code without end{1}\n\n{12}   {0} In case of {2}**AAA**{0}:{1}\n{12}   {0} {1}\n{12}   {0} {20}```sql\n    SELECT strftime('%Y-%m-%d %H:%M:%S', 'now') AS `date`;\n    ```{1}\n{12}   {0} {1}\n{12}   {0} or, in case of {3}__BBB__{0}:{1}\n{12}   {0} . . .{1}\n\n{13}-{0}   example {4}*three*{1}\n\n{0}Last paragraph.{1}\n"
  },
  {
    "path": "test/examples/markdown/HeaderEOLFill_0.md",
    "content": "H1\n==\n\nH2\n--\n\n# H1\n\n## H2\n\nH1\n==\nH2\n--\n# H1\n## H2\n### H3\n#### H4\n##### H5\n###### H6\n"
  },
  {
    "path": "test/examples/markdown/HeaderEOLFill_0.md.folded",
    "content": " 0 400   0   H1\n 0 400   0   ==\n 0 400   0   \n 0 400   0   H2\n 0 400   0   --\n 0 400   0   \n 0 400   0   # H1\n 0 400   0   \n 0 400   0   ## H2\n 0 400   0   \n 0 400   0   H1\n 0 400   0   ==\n 0 400   0   H2\n 0 400   0   --\n 0 400   0   # H1\n 0 400   0   ## H2\n 0 400   0   ### H3\n 0 400   0   #### H4\n 0 400   0   ##### H5\n 0 400   0   ###### H6\n 0 400   0   "
  },
  {
    "path": "test/examples/markdown/HeaderEOLFill_0.md.styled",
    "content": "{0}H1{1}\n{6}=={1}\n\n{0}H2{1}\n{7}--{1}\n\n{6}#{0} H1{1}\n\n{7}##{0} H2{1}\n\n{0}H1{1}\n{6}=={1}\n{0}H2{1}\n{7}--{1}\n{6}#{0} H1{1}\n{7}##{0} H2{1}\n{8}###{0} H3{1}\n{9}####{0} H4{1}\n{10}#####{0} H5{1}\n{11}######{0} H6{1}\n"
  },
  {
    "path": "test/examples/markdown/HeaderEOLFill_1.md",
    "content": "H1\n==\n\nH2\n--\n\n# H1\n\n## H2\n\nH1\n==\nH2\n--\n# H1\n## H2\n### H3\n#### H4\n##### H5\n###### H6\n"
  },
  {
    "path": "test/examples/markdown/HeaderEOLFill_1.md.folded",
    "content": " 0 400   0   H1\n 0 400   0   ==\n 0 400   0   \n 0 400   0   H2\n 0 400   0   --\n 0 400   0   \n 0 400   0   # H1\n 0 400   0   \n 0 400   0   ## H2\n 0 400   0   \n 0 400   0   H1\n 0 400   0   ==\n 0 400   0   H2\n 0 400   0   --\n 0 400   0   # H1\n 0 400   0   ## H2\n 0 400   0   ### H3\n 0 400   0   #### H4\n 0 400   0   ##### H5\n 0 400   0   ###### H6\n 0 400   0   "
  },
  {
    "path": "test/examples/markdown/HeaderEOLFill_1.md.styled",
    "content": "{0}H1{1}\n{6}==\n{1}\n{0}H2{1}\n{7}--\n{1}\n{6}# H1\n{1}\n{7}## H2\n{1}\n{0}H1{1}\n{6}==\n{0}H2{1}\n{7}--\n{6}# H1\n{7}## H2\n{8}### H3\n{9}#### H4\n{10}##### H5\n{11}###### H6\n"
  },
  {
    "path": "test/examples/markdown/Issue117.md",
    "content": "The number:\n\n338269006135764734700913562171\n\nis prime. Therefore:\n\n  1. the only factors of 338269006135764734700913562171 are:\n\n    1\n    338269006135764734700913562171\n\n  2. 338269006135764734700913562171 is a natural number\n"
  },
  {
    "path": "test/examples/markdown/Issue117.md.folded",
    "content": " 0 400   0   The number:\n 0 400   0   \n 0 400   0   338269006135764734700913562171\n 0 400   0   \n 0 400   0   is prime. Therefore:\n 0 400   0   \n 0 400   0     1. the only factors of 338269006135764734700913562171 are:\n 0 400   0   \n 0 400   0       1\n 0 400   0       338269006135764734700913562171\n 0 400   0   \n 0 400   0     2. 338269006135764734700913562171 is a natural number\n 0 400   0   "
  },
  {
    "path": "test/examples/markdown/Issue117.md.styled",
    "content": "{0}The number:{1}\n\n{0}338269006135764734700913562171{1}\n\n{0}is prime. Therefore:{1}\n\n{12}  {14}1.{0} the only factors of 338269006135764734700913562171 are:{1}\n\n{12}   {0} 1{1}\n{12}   {0} 338269006135764734700913562171{1}\n\n{12}  {14}2.{0} 338269006135764734700913562171 is a natural number{1}\n"
  },
  {
    "path": "test/examples/markdown/SciTE.properties",
    "content": "code.page=65001\nlexer.*.md=markdown\nfold=1\n\n# Tests for the lexer.markdown.header.eolfill property, issue #62\nif $(= $(FileNameExt);HeaderEOLFill_0.md)\n    lexer.markdown.header.eolfill=0\nif $(= $(FileNameExt);HeaderEOLFill_1.md)\n    lexer.markdown.header.eolfill=1\n"
  },
  {
    "path": "test/examples/matlab/AllStyles.m.matlab",
    "content": "% Examples of each style 0..8 except for SCE_MATLAB_COMMAND(2) which has a line ending bug\n\n% White space=0\n   %\n\n% Comment=1\n% Line comment\n\n% Next line is comment in Ocatve but not Matlab\n# Octave comment\n\n%{\nBlock comment.\n%}\n\n% Command=2\n\n%{\nOmitted as this places a style transiton between \\r and \\n\n!rmdir oldtests\n%}\n\n% Number=3\n33.3\n\n% Keyword=4\nglobal x\n\n% Single Quoted String=5\n'string'\n\n% Operator=6\n[X,Y] = meshgrid(-10:0.25:10,-10:0.25:10);\n\n% Identifier=7\nidentifier = 2\n\n% Double Quoted String=8\n\"string\"\n\n% This loop should fold\nfor i = 1:5\n    x(i) = 3 * i;\nend\n"
  },
  {
    "path": "test/examples/matlab/AllStyles.m.matlab.folded",
    "content": " 0 400 400   % Examples of each style 0..8 except for SCE_MATLAB_COMMAND(2) which has a line ending bug\n 1 400 400   \n 0 400 400   % White space=0\n 0 400 400      %\n 1 400 400   \n 0 400 400   % Comment=1\n 0 400 400   % Line comment\n 1 400 400   \n 0 400 400   % Next line is comment in Ocatve but not Matlab\n 0 400 400   # Octave comment\n 1 400 400   \n 0 400 400   %{\n 0 400 400   Block comment.\n 0 400 400   %}\n 1 400 400   \n 0 400 400   % Command=2\n 1 400 400   \n 0 400 400   %{\n 0 400 400   Omitted as this places a style transiton between \\r and \\n\n 0 400 400   !rmdir oldtests\n 0 400 400   %}\n 1 400 400   \n 0 400 400   % Number=3\n 0 400 400   33.3\n 1 400 400   \n 0 400 400   % Keyword=4\n 0 400 400   global x\n 1 400 400   \n 0 400 400   % Single Quoted String=5\n 0 400 400   'string'\n 1 400 400   \n 0 400 400   % Operator=6\n 0 400 400   [X,Y] = meshgrid(-10:0.25:10,-10:0.25:10);\n 1 400 400   \n 0 400 400   % Identifier=7\n 0 400 400   identifier = 2\n 1 400 400   \n 0 400 400   % Double Quoted String=8\n 0 400 400   \"string\"\n 1 400 400   \n 0 400 400   % This loop should fold\n 2 400 401 + for i = 1:5\n 0 401 401 |     x(i) = 3 * i;\n 0 401 400 | end\n 1 400 400   "
  },
  {
    "path": "test/examples/matlab/AllStyles.m.matlab.styled",
    "content": "{1}% Examples of each style 0..8 except for SCE_MATLAB_COMMAND(2) which has a line ending bug{0}\n\n{1}% White space=0{0}\n   {1}%{0}\n\n{1}% Comment=1{0}\n{1}% Line comment{0}\n\n{1}% Next line is comment in Ocatve but not Matlab{0}\n# {7}Octave{0} {7}comment{0}\n\n{1}%{\nBlock comment.\n%}{0}\n\n{1}% Command=2{0}\n\n{1}%{\nOmitted as this places a style transiton between \\r and \\n\n!rmdir oldtests\n%}{0}\n\n{1}% Number=3{0}\n{3}33.3{0}\n\n{1}% Keyword=4{0}\n{4}global{0} {7}x{0}\n\n{1}% Single Quoted String=5{0}\n{5}'string'{0}\n\n{1}% Operator=6{0}\n{6}[{7}X{6},{7}Y{6}]{0} {6}={0} {7}meshgrid{6}(-{3}10{6}:{3}0.25{6}:{3}10{6},-{3}10{6}:{3}0.25{6}:{3}10{6});{0}\n\n{1}% Identifier=7{0}\n{7}identifier{0} {6}={0} {3}2{0}\n\n{1}% Double Quoted String=8{0}\n{8}\"string\"{0}\n\n{1}% This loop should fold{0}\n{4}for{0} {7}i{0} {6}={0} {3}1{6}:{3}5{0}\n    {7}x{6}({7}i{6}){0} {6}={0} {3}3{0} {6}*{0} {7}i{6};{0}\n{4}end{0}\n"
  },
  {
    "path": "test/examples/matlab/AllStyles.m.octave",
    "content": "% Examples of each style 0..8 except for SCE_MATLAB_COMMAND(2) which has a line ending bug\n\n% White space=0\n   %\n\n% Comment=1\n% Line comment\n\n% Next line is comment in Ocatve but not Matlab\n# Octave comment\n\n%{\nBlock comment.\n%}\n\n% Command=2\n\n%{\nOmitted as this places a style transiton between \\r and \\n\n!rmdir oldtests\n%}\n\n% Number=3\n33.3\n\n% Keyword=4\nglobal x\n\n% Single Quoted String=5\n'string'\n\n% Operator=6\n[X,Y] = meshgrid(-10:0.25:10,-10:0.25:10);\n\n% Identifier=7\nidentifier = 2\n\n% Double Quoted String=8\n\"string\"\n\n% This loop should fold\nfor i = 1:5\n    x(i) = 3 * i;\nend\n"
  },
  {
    "path": "test/examples/matlab/AllStyles.m.octave.folded",
    "content": " 0 400 400   % Examples of each style 0..8 except for SCE_MATLAB_COMMAND(2) which has a line ending bug\n 1 400 400   \n 0 400 400   % White space=0\n 0 400 400      %\n 1 400 400   \n 0 400 400   % Comment=1\n 0 400 400   % Line comment\n 1 400 400   \n 0 400 400   % Next line is comment in Ocatve but not Matlab\n 0 400 400   # Octave comment\n 1 400 400   \n 0 400 400   %{\n 0 400 400   Block comment.\n 0 400 400   %}\n 1 400 400   \n 0 400 400   % Command=2\n 1 400 400   \n 0 400 400   %{\n 0 400 400   Omitted as this places a style transiton between \\r and \\n\n 0 400 400   !rmdir oldtests\n 0 400 400   %}\n 1 400 400   \n 0 400 400   % Number=3\n 0 400 400   33.3\n 1 400 400   \n 0 400 400   % Keyword=4\n 0 400 400   global x\n 1 400 400   \n 0 400 400   % Single Quoted String=5\n 0 400 400   'string'\n 1 400 400   \n 0 400 400   % Operator=6\n 0 400 400   [X,Y] = meshgrid(-10:0.25:10,-10:0.25:10);\n 1 400 400   \n 0 400 400   % Identifier=7\n 0 400 400   identifier = 2\n 1 400 400   \n 0 400 400   % Double Quoted String=8\n 0 400 400   \"string\"\n 1 400 400   \n 0 400 400   % This loop should fold\n 2 400 401 + for i = 1:5\n 0 401 401 |     x(i) = 3 * i;\n 0 401 400 | end\n 1 400 400   "
  },
  {
    "path": "test/examples/matlab/AllStyles.m.octave.styled",
    "content": "{1}% Examples of each style 0..8 except for SCE_MATLAB_COMMAND(2) which has a line ending bug{0}\n\n{1}% White space=0{0}\n   {1}%{0}\n\n{1}% Comment=1{0}\n{1}% Line comment{0}\n\n{1}% Next line is comment in Ocatve but not Matlab{0}\n{1}# Octave comment{0}\n\n{1}%{\nBlock comment.\n%}{0}\n\n{1}% Command=2{0}\n\n{1}%{\nOmitted as this places a style transiton between \\r and \\n\n!rmdir oldtests\n%}{0}\n\n{1}% Number=3{0}\n{3}33.3{0}\n\n{1}% Keyword=4{0}\n{4}global{0} {7}x{0}\n\n{1}% Single Quoted String=5{0}\n{5}'string'{0}\n\n{1}% Operator=6{0}\n{6}[{7}X{6},{7}Y{6}]{0} {6}={0} {7}meshgrid{6}(-{3}10{6}:{3}0.25{6}:{3}10{6},-{3}10{6}:{3}0.25{6}:{3}10{6});{0}\n\n{1}% Identifier=7{0}\n{7}identifier{0} {6}={0} {3}2{0}\n\n{1}% Double Quoted String=8{0}\n{8}\"string\"{0}\n\n{1}% This loop should fold{0}\n{4}for{0} {7}i{0} {6}={0} {3}1{6}:{3}5{0}\n    {7}x{6}({7}i{6}){0} {6}={0} {3}3{0} {6}*{0} {7}i{6};{0}\n{4}end{0}\n"
  },
  {
    "path": "test/examples/matlab/ArgumentsBlock.m.matlab",
    "content": "%% Correctly defined arguments block\nfunction y = foo (x)\n% Some comment here\n% And, maybe, here\n\narguments\n    x (1,2) {mustBeReal(x)}\nend\n\ny = x*2;\narguments = 1;\ny = y + arguments;\nend\n\n%% No arguments block, \"arguments\" is used \n%  as a variable name (identifier)\n% Prevent arguments from folding with an identifier\nfunction y = foo (x)\n% Some comment here\nx = x + 1;\narguments = 10;\ny = x + arguments;\nend\n\n% Prevent arguments from folding with a number\nfunction y = foo (x)\n4\narguments = 10;\ny = x + arguments;\nend\n\n% With a double quote string\nfunction y = foo (x)\n\"test\"\narguments = 10;\ny = x + arguments;\nend\n\n% With a string\nfunction y = foo (x)\n'test'\narguments = 10;\ny = x + arguments;\nend\n\n% With a keyword\nfunction y = foo (x)\nif x == 0;\n    return 0;\nend\narguments = 10;\ny = x + arguments;\nend\n\n% With an operator (illegal syntax)\nfunction y = foo (x)\n*\narguments = 10;\ny = x + arguments;\nend\n\n% Semicolon is equivalent to a comment\nfunction y = foo(x)\n;;;;;;;\narguments\n    x\nend\ny = x + 2;\nend\n\n% Arguments block is illegal in nested functions,\n% but lexer should process it anyway\nfunction y = foo (x)\narguments\n    x (1,2) {mustBeReal(x)}\nend\n\n    function y = foo (x)\n    arguments\n        x (1,2) {mustBeReal(x)}\n    end\n    var = 0;\n    arguments = 5;\n    y = arguments + x;\n    end\n\n% Use as a variable, just in case\narguments = 10;\nend\n\n% Erroneous use of arguments block\nfunction y = foo(x)\n% Some comment\nx = x + 1;\narguments\n    x\nend\ny = x;\nend\n\n% \"arguments\" is an argument name too\nfunction r = foo(x, arguments)\narguments\n    x\n    arguments\nend\nr = bar(x, arguments{:});\nend\n\n% Multiple arguments blocks\nfunction [a, b] = foo(x, y, varargin)\n\narguments(Input)\n    x (1,4) {mustBeReal}\n    y (1,:) {mustBeInteger} = x(2:end);\nend\n\narguments(Input, Repeating)\n    varargin\nend\n\narguments(Output)\n    a (1,1) {mustBeReal}\n    b (1,1) {mustBeNonNegative}\nend\n\nvar = 10;\narguments = {\"now\", \"it's\", \"variable\"};\n\n[a, b] = bar(x, y, arguments);\n\nend\n\n% One line function with arguments block.\n% This code style is rarely used (if at all), but the\n% lexer shouldn't break\nfunction y = foo(x); arguments; x; end; y = bar(x); end\n"
  },
  {
    "path": "test/examples/matlab/ArgumentsBlock.m.matlab.folded",
    "content": " 0 400 400   %% Correctly defined arguments block\n 2 400 401 + function y = foo (x)\n 0 401 401 | % Some comment here\n 0 401 401 | % And, maybe, here\n 1 401 401 | \n 2 401 402 + arguments\n 0 402 402 |     x (1,2) {mustBeReal(x)}\n 0 402 401 | end\n 1 401 401 | \n 0 401 401 | y = x*2;\n 0 401 401 | arguments = 1;\n 0 401 401 | y = y + arguments;\n 0 401 400 | end\n 1 400 400   \n 0 400 400   %% No arguments block, \"arguments\" is used \n 0 400 400   %  as a variable name (identifier)\n 0 400 400   % Prevent arguments from folding with an identifier\n 2 400 401 + function y = foo (x)\n 0 401 401 | % Some comment here\n 0 401 401 | x = x + 1;\n 0 401 401 | arguments = 10;\n 0 401 401 | y = x + arguments;\n 0 401 400 | end\n 1 400 400   \n 0 400 400   % Prevent arguments from folding with a number\n 2 400 401 + function y = foo (x)\n 0 401 401 | 4\n 0 401 401 | arguments = 10;\n 0 401 401 | y = x + arguments;\n 0 401 400 | end\n 1 400 400   \n 0 400 400   % With a double quote string\n 2 400 401 + function y = foo (x)\n 0 401 401 | \"test\"\n 0 401 401 | arguments = 10;\n 0 401 401 | y = x + arguments;\n 0 401 400 | end\n 1 400 400   \n 0 400 400   % With a string\n 2 400 401 + function y = foo (x)\n 0 401 401 | 'test'\n 0 401 401 | arguments = 10;\n 0 401 401 | y = x + arguments;\n 0 401 400 | end\n 1 400 400   \n 0 400 400   % With a keyword\n 2 400 401 + function y = foo (x)\n 2 401 402 + if x == 0;\n 0 402 402 |     return 0;\n 0 402 401 | end\n 0 401 401 | arguments = 10;\n 0 401 401 | y = x + arguments;\n 0 401 400 | end\n 1 400 400   \n 0 400 400   % With an operator (illegal syntax)\n 2 400 401 + function y = foo (x)\n 0 401 401 | *\n 0 401 401 | arguments = 10;\n 0 401 401 | y = x + arguments;\n 0 401 400 | end\n 1 400 400   \n 0 400 400   % Semicolon is equivalent to a comment\n 2 400 401 + function y = foo(x)\n 0 401 401 | ;;;;;;;\n 2 401 402 + arguments\n 0 402 402 |     x\n 0 402 401 | end\n 0 401 401 | y = x + 2;\n 0 401 400 | end\n 1 400 400   \n 0 400 400   % Arguments block is illegal in nested functions,\n 0 400 400   % but lexer should process it anyway\n 2 400 401 + function y = foo (x)\n 2 401 402 + arguments\n 0 402 402 |     x (1,2) {mustBeReal(x)}\n 0 402 401 | end\n 1 401 401 | \n 2 401 402 +     function y = foo (x)\n 2 402 403 +     arguments\n 0 403 403 |         x (1,2) {mustBeReal(x)}\n 0 403 402 |     end\n 0 402 402 |     var = 0;\n 0 402 402 |     arguments = 5;\n 0 402 402 |     y = arguments + x;\n 0 402 401 |     end\n 1 401 401 | \n 0 401 401 | % Use as a variable, just in case\n 0 401 401 | arguments = 10;\n 0 401 400 | end\n 1 400 400   \n 0 400 400   % Erroneous use of arguments block\n 2 400 401 + function y = foo(x)\n 0 401 401 | % Some comment\n 0 401 401 | x = x + 1;\n 0 401 401 | arguments\n 0 401 401 |     x\n 0 401 400 | end\n 0 400 400   y = x;\n 0 400 3ff   end\n 1 3ff 3ff   \n 0 3ff 3ff   % \"arguments\" is an argument name too\n 2 3ff 400 + function r = foo(x, arguments)\n 2 400 401 + arguments\n 0 401 401 |     x\n 0 401 401 |     arguments\n 0 401 400 | end\n 0 400 400   r = bar(x, arguments{:});\n 0 400 3ff   end\n 1 3ff 3ff   \n 0 3ff 3ff   % Multiple arguments blocks\n 2 3ff 400 + function [a, b] = foo(x, y, varargin)\n 1 400 400   \n 2 400 401 + arguments(Input)\n 0 401 401 |     x (1,4) {mustBeReal}\n 0 401 401 |     y (1,:) {mustBeInteger} = x(2:end);\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + arguments(Input, Repeating)\n 0 401 401 |     varargin\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + arguments(Output)\n 0 401 401 |     a (1,1) {mustBeReal}\n 0 401 401 |     b (1,1) {mustBeNonNegative}\n 0 401 400 | end\n 1 400 400   \n 0 400 400   var = 10;\n 0 400 400   arguments = {\"now\", \"it's\", \"variable\"};\n 1 400 400   \n 0 400 400   [a, b] = bar(x, y, arguments);\n 1 400 400   \n 0 400 3ff   end\n 1 3ff 3ff   \n 0 3ff 3ff   % One line function with arguments block.\n 0 3ff 3ff   % This code style is rarely used (if at all), but the\n 0 3ff 3ff   % lexer shouldn't break\n 0 3ff 3ff   function y = foo(x); arguments; x; end; y = bar(x); end\n 1 3ff 3ff   "
  },
  {
    "path": "test/examples/matlab/ArgumentsBlock.m.matlab.styled",
    "content": "{1}%% Correctly defined arguments block{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}\n{1}% Some comment here{0}\n{1}% And, maybe, here{0}\n\n{4}arguments{0}\n    {7}x{0} {6}({3}1{6},{3}2{6}){0} {6}{{7}mustBeReal{6}({7}x{6})}{0}\n{4}end{0}\n\n{7}y{0} {6}={0} {7}x{6}*{3}2{6};{0}\n{7}arguments{0} {6}={0} {3}1{6};{0}\n{7}y{0} {6}={0} {7}y{0} {6}+{0} {7}arguments{6};{0}\n{4}end{0}\n\n{1}%% No arguments block, \"arguments\" is used {0}\n{1}%  as a variable name (identifier){0}\n{1}% Prevent arguments from folding with an identifier{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}\n{1}% Some comment here{0}\n{7}x{0} {6}={0} {7}x{0} {6}+{0} {3}1{6};{0}\n{7}arguments{0} {6}={0} {3}10{6};{0}\n{7}y{0} {6}={0} {7}x{0} {6}+{0} {7}arguments{6};{0}\n{4}end{0}\n\n{1}% Prevent arguments from folding with a number{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}\n{3}4{0}\n{7}arguments{0} {6}={0} {3}10{6};{0}\n{7}y{0} {6}={0} {7}x{0} {6}+{0} {7}arguments{6};{0}\n{4}end{0}\n\n{1}% With a double quote string{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}\n{8}\"test\"{0}\n{7}arguments{0} {6}={0} {3}10{6};{0}\n{7}y{0} {6}={0} {7}x{0} {6}+{0} {7}arguments{6};{0}\n{4}end{0}\n\n{1}% With a string{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}\n{5}'test'{0}\n{7}arguments{0} {6}={0} {3}10{6};{0}\n{7}y{0} {6}={0} {7}x{0} {6}+{0} {7}arguments{6};{0}\n{4}end{0}\n\n{1}% With a keyword{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}\n{4}if{0} {7}x{0} {6}=={0} {3}0{6};{0}\n    {4}return{0} {3}0{6};{0}\n{4}end{0}\n{7}arguments{0} {6}={0} {3}10{6};{0}\n{7}y{0} {6}={0} {7}x{0} {6}+{0} {7}arguments{6};{0}\n{4}end{0}\n\n{1}% With an operator (illegal syntax){0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}\n{6}*{0}\n{7}arguments{0} {6}={0} {3}10{6};{0}\n{7}y{0} {6}={0} {7}x{0} {6}+{0} {7}arguments{6};{0}\n{4}end{0}\n\n{1}% Semicolon is equivalent to a comment{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{6}({7}x{6}){0}\n{6};;;;;;;{0}\n{4}arguments{0}\n    {7}x{0}\n{4}end{0}\n{7}y{0} {6}={0} {7}x{0} {6}+{0} {3}2{6};{0}\n{4}end{0}\n\n{1}% Arguments block is illegal in nested functions,{0}\n{1}% but lexer should process it anyway{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}\n{4}arguments{0}\n    {7}x{0} {6}({3}1{6},{3}2{6}){0} {6}{{7}mustBeReal{6}({7}x{6})}{0}\n{4}end{0}\n\n    {4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}\n    {4}arguments{0}\n        {7}x{0} {6}({3}1{6},{3}2{6}){0} {6}{{7}mustBeReal{6}({7}x{6})}{0}\n    {4}end{0}\n    {7}var{0} {6}={0} {3}0{6};{0}\n    {7}arguments{0} {6}={0} {3}5{6};{0}\n    {7}y{0} {6}={0} {7}arguments{0} {6}+{0} {7}x{6};{0}\n    {4}end{0}\n\n{1}% Use as a variable, just in case{0}\n{7}arguments{0} {6}={0} {3}10{6};{0}\n{4}end{0}\n\n{1}% Erroneous use of arguments block{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{6}({7}x{6}){0}\n{1}% Some comment{0}\n{7}x{0} {6}={0} {7}x{0} {6}+{0} {3}1{6};{0}\n{7}arguments{0}\n    {7}x{0}\n{4}end{0}\n{7}y{0} {6}={0} {7}x{6};{0}\n{4}end{0}\n\n{1}% \"arguments\" is an argument name too{0}\n{4}function{0} {7}r{0} {6}={0} {7}foo{6}({7}x{6},{0} {7}arguments{6}){0}\n{4}arguments{0}\n    {7}x{0}\n    {7}arguments{0}\n{4}end{0}\n{7}r{0} {6}={0} {7}bar{6}({7}x{6},{0} {7}arguments{6}{:});{0}\n{4}end{0}\n\n{1}% Multiple arguments blocks{0}\n{4}function{0} {6}[{7}a{6},{0} {7}b{6}]{0} {6}={0} {7}foo{6}({7}x{6},{0} {7}y{6},{0} {7}varargin{6}){0}\n\n{4}arguments{6}({7}Input{6}){0}\n    {7}x{0} {6}({3}1{6},{3}4{6}){0} {6}{{7}mustBeReal{6}}{0}\n    {7}y{0} {6}({3}1{6},:){0} {6}{{7}mustBeInteger{6}}{0} {6}={0} {7}x{6}({3}2{6}:{3}end{6});{0}\n{4}end{0}\n\n{4}arguments{6}({7}Input{6},{0} {7}Repeating{6}){0}\n    {7}varargin{0}\n{4}end{0}\n\n{4}arguments{6}({7}Output{6}){0}\n    {7}a{0} {6}({3}1{6},{3}1{6}){0} {6}{{7}mustBeReal{6}}{0}\n    {7}b{0} {6}({3}1{6},{3}1{6}){0} {6}{{7}mustBeNonNegative{6}}{0}\n{4}end{0}\n\n{7}var{0} {6}={0} {3}10{6};{0}\n{7}arguments{0} {6}={0} {6}{{8}\"now\"{6},{0} {8}\"it's\"{6},{0} {8}\"variable\"{6}};{0}\n\n{6}[{7}a{6},{0} {7}b{6}]{0} {6}={0} {7}bar{6}({7}x{6},{0} {7}y{6},{0} {7}arguments{6});{0}\n\n{4}end{0}\n\n{1}% One line function with arguments block.{0}\n{1}% This code style is rarely used (if at all), but the{0}\n{1}% lexer shouldn't break{0}\n{4}function{0} {7}y{0} {6}={0} {7}foo{6}({7}x{6});{0} {4}arguments{6};{0} {7}x{6};{0} {4}end{6};{0} {7}y{0} {6}={0} {7}bar{6}({7}x{6});{0} {4}end{0}\n"
  },
  {
    "path": "test/examples/matlab/ClassDefinition.m.matlab",
    "content": "classdef Foo < handle\n\n    % A couple of properties blocks\n    properties (SetAccess = private)\n        Var1\n        Var2\n    end\n\n    properties\n        Var3\n        Var4\n    end\n\n    methods (Static)\n        function y = f1(x)\n            % events, properties and methods are the valid idenifiers\n            % in the function scope\n            events = 1;\n            properties = 2;\n            y = x + events * properties;\n        end\n\n        % Any of these words are also valid functions' names inside\n        % methods block\n        function y = events(x)\n            \n            arguments\n                x {mustBeNegative}\n            end\n\n            y = f2(x)*100;\n            function b = f2(a)\n                b = a + 5;\n            end\n        end\n    end\n\n    % Example events block\n    events\n        Event1\n        Event2\n    end\nend\n\n\n% Now, let's break some stuff\nclassdef Bar\n\n    properties\n        % Though MATLAB won't execute such a code, events, properties\n        % and methods are keywords here, because we're still in the class scope\n        events\n        end\n\n        methods\n        end        \n    end\n    \n    % Not allowed in MATLAB, but, technically, we're still in the class scope\n    if condition1\n        if condition2\n            % Though we're in the class scope, lexel will recognize no\n            % keywords here: to avoid the neccessaty to track nested scopes,\n            % it just considers everything beyond level 2 of folding to be\n            % a function scope\n            methods\n            events\n            properties\n        end\n    end\n\n\nend\n\n"
  },
  {
    "path": "test/examples/matlab/ClassDefinition.m.matlab.folded",
    "content": " 2 400 401 + classdef Foo < handle\n 1 401 401 | \n 0 401 401 |     % A couple of properties blocks\n 2 401 402 +     properties (SetAccess = private)\n 0 402 402 |         Var1\n 0 402 402 |         Var2\n 0 402 401 |     end\n 1 401 401 | \n 2 401 402 +     properties\n 0 402 402 |         Var3\n 0 402 402 |         Var4\n 0 402 401 |     end\n 1 401 401 | \n 2 401 402 +     methods (Static)\n 2 402 403 +         function y = f1(x)\n 0 403 403 |             % events, properties and methods are the valid idenifiers\n 0 403 403 |             % in the function scope\n 0 403 403 |             events = 1;\n 0 403 403 |             properties = 2;\n 0 403 403 |             y = x + events * properties;\n 0 403 402 |         end\n 1 402 402 | \n 0 402 402 |         % Any of these words are also valid functions' names inside\n 0 402 402 |         % methods block\n 2 402 403 +         function y = events(x)\n 1 403 403 |             \n 2 403 404 +             arguments\n 0 404 404 |                 x {mustBeNegative}\n 0 404 403 |             end\n 1 403 403 | \n 0 403 403 |             y = f2(x)*100;\n 2 403 404 +             function b = f2(a)\n 0 404 404 |                 b = a + 5;\n 0 404 403 |             end\n 0 403 402 |         end\n 0 402 401 |     end\n 1 401 401 | \n 0 401 401 |     % Example events block\n 2 401 402 +     events\n 0 402 402 |         Event1\n 0 402 402 |         Event2\n 0 402 401 |     end\n 0 401 400 | end\n 1 400 400   \n 1 400 400   \n 0 400 400   % Now, let's break some stuff\n 2 400 401 + classdef Bar\n 1 401 401 | \n 2 401 402 +     properties\n 0 402 402 |         % Though MATLAB won't execute such a code, events, properties\n 0 402 402 |         % and methods are keywords here, because we're still in the class scope\n 2 402 403 +         events\n 0 403 402 |         end\n 1 402 402 | \n 2 402 403 +         methods\n 0 403 402 |         end        \n 0 402 401 |     end\n 1 401 401 |     \n 0 401 401 |     % Not allowed in MATLAB, but, technically, we're still in the class scope\n 2 401 402 +     if condition1\n 2 402 403 +         if condition2\n 0 403 403 |             % Though we're in the class scope, lexel will recognize no\n 0 403 403 |             % keywords here: to avoid the neccessaty to track nested scopes,\n 0 403 403 |             % it just considers everything beyond level 2 of folding to be\n 0 403 403 |             % a function scope\n 0 403 403 |             methods\n 0 403 403 |             events\n 0 403 403 |             properties\n 0 403 402 |         end\n 0 402 401 |     end\n 1 401 401 | \n 1 401 401 | \n 0 401 400 | end\n 1 400 400   \n 1 400 400   "
  },
  {
    "path": "test/examples/matlab/ClassDefinition.m.matlab.styled",
    "content": "{4}classdef{0} {7}Foo{0} {6}<{0} {7}handle{0}\n\n    {1}% A couple of properties blocks{0}\n    {4}properties{0} {6}({7}SetAccess{0} {6}={0} {7}private{6}){0}\n        {7}Var1{0}\n        {7}Var2{0}\n    {4}end{0}\n\n    {4}properties{0}\n        {7}Var3{0}\n        {7}Var4{0}\n    {4}end{0}\n\n    {4}methods{0} {6}({7}Static{6}){0}\n        {4}function{0} {7}y{0} {6}={0} {7}f1{6}({7}x{6}){0}\n            {1}% events, properties and methods are the valid idenifiers{0}\n            {1}% in the function scope{0}\n            {7}events{0} {6}={0} {3}1{6};{0}\n            {7}properties{0} {6}={0} {3}2{6};{0}\n            {7}y{0} {6}={0} {7}x{0} {6}+{0} {7}events{0} {6}*{0} {7}properties{6};{0}\n        {4}end{0}\n\n        {1}% Any of these words are also valid functions' names inside{0}\n        {1}% methods block{0}\n        {4}function{0} {7}y{0} {6}={0} {7}events{6}({7}x{6}){0}\n            \n            {4}arguments{0}\n                {7}x{0} {6}{{7}mustBeNegative{6}}{0}\n            {4}end{0}\n\n            {7}y{0} {6}={0} {7}f2{6}({7}x{6})*{3}100{6};{0}\n            {4}function{0} {7}b{0} {6}={0} {7}f2{6}({7}a{6}){0}\n                {7}b{0} {6}={0} {7}a{0} {6}+{0} {3}5{6};{0}\n            {4}end{0}\n        {4}end{0}\n    {4}end{0}\n\n    {1}% Example events block{0}\n    {4}events{0}\n        {7}Event1{0}\n        {7}Event2{0}\n    {4}end{0}\n{4}end{0}\n\n\n{1}% Now, let's break some stuff{0}\n{4}classdef{0} {7}Bar{0}\n\n    {4}properties{0}\n        {1}% Though MATLAB won't execute such a code, events, properties{0}\n        {1}% and methods are keywords here, because we're still in the class scope{0}\n        {4}events{0}\n        {4}end{0}\n\n        {4}methods{0}\n        {4}end{0}        \n    {4}end{0}\n    \n    {1}% Not allowed in MATLAB, but, technically, we're still in the class scope{0}\n    {4}if{0} {7}condition1{0}\n        {4}if{0} {7}condition2{0}\n            {1}% Though we're in the class scope, lexel will recognize no{0}\n            {1}% keywords here: to avoid the neccessaty to track nested scopes,{0}\n            {1}% it just considers everything beyond level 2 of folding to be{0}\n            {1}% a function scope{0}\n            {7}methods{0}\n            {7}events{0}\n            {7}properties{0}\n        {4}end{0}\n    {4}end{0}\n\n\n{4}end{0}\n\n"
  },
  {
    "path": "test/examples/matlab/FoldPoints.m.matlab",
    "content": "% All the examples here should yield folding\n\nclassdef\n    % Some code\nend\n\nfor\n    % Some code\nend\n\nfunction\n    % Some code\nend\n\nif\n    % Some code\nelseif\n    % Some code\nelse\n    % Some code\nend\n\nparfor\n    % Some code\nend\n\nspmd\n    % Some code\nend\n\nswitch\n    case\n        % Some code\n    case\n        % Some code\n    otherwise\n        % Some code\nend\n\ntry\n    % Some code\ncatch\n    % Some code\nend\n\nwhile\n    % Some code\nend\n"
  },
  {
    "path": "test/examples/matlab/FoldPoints.m.matlab.folded",
    "content": " 0 400 400   % All the examples here should yield folding\n 1 400 400   \n 2 400 401 + classdef\n 0 401 401 |     % Some code\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + for\n 0 401 401 |     % Some code\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + function\n 0 401 401 |     % Some code\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + if\n 0 401 401 |     % Some code\n 0 401 401 | elseif\n 0 401 401 |     % Some code\n 0 401 401 | else\n 0 401 401 |     % Some code\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + parfor\n 0 401 401 |     % Some code\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + spmd\n 0 401 401 |     % Some code\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + switch\n 0 401 401 |     case\n 0 401 401 |         % Some code\n 0 401 401 |     case\n 0 401 401 |         % Some code\n 0 401 401 |     otherwise\n 0 401 401 |         % Some code\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + try\n 0 401 401 |     % Some code\n 0 401 401 | catch\n 0 401 401 |     % Some code\n 0 401 400 | end\n 1 400 400   \n 2 400 401 + while\n 0 401 401 |     % Some code\n 0 401 400 | end\n 1 400 400   "
  },
  {
    "path": "test/examples/matlab/FoldPoints.m.matlab.styled",
    "content": "{1}% All the examples here should yield folding{0}\n\n{4}classdef{0}\n    {1}% Some code{0}\n{4}end{0}\n\n{4}for{0}\n    {1}% Some code{0}\n{4}end{0}\n\n{4}function{0}\n    {1}% Some code{0}\n{4}end{0}\n\n{4}if{0}\n    {1}% Some code{0}\n{4}elseif{0}\n    {1}% Some code{0}\n{4}else{0}\n    {1}% Some code{0}\n{4}end{0}\n\n{4}parfor{0}\n    {1}% Some code{0}\n{4}end{0}\n\n{4}spmd{0}\n    {1}% Some code{0}\n{4}end{0}\n\n{4}switch{0}\n    {4}case{0}\n        {1}% Some code{0}\n    {4}case{0}\n        {1}% Some code{0}\n    {4}otherwise{0}\n        {1}% Some code{0}\n{4}end{0}\n\n{4}try{0}\n    {1}% Some code{0}\n{4}catch{0}\n    {1}% Some code{0}\n{4}end{0}\n\n{4}while{0}\n    {1}% Some code{0}\n{4}end{0}\n"
  },
  {
    "path": "test/examples/matlab/Issue18_EscapeSequence.m.matlab",
    "content": "a=\"\"\"\";\nb=1;\nc='\\';\nd=2;\ne=\"\\\";\nf=3;\n%\" this should be a comment (colored as such), instead it closes the string\ng=\"\nh=123;\n%\" this is a syntax error in Matlab (about 'g'),\n% followed by a valid assignment (of 'h')\n% Instead, 'h' is colored as part of the string\n\n% Octave terminates string at 3rd \", Matlab at 4th\ni=\"\\\" \"; % \" %\n\n% Matlab (unlike Octave) does not allow string continuation with an escape\nb = \"multi\\\nline\"\n\n% end\n"
  },
  {
    "path": "test/examples/matlab/Issue18_EscapeSequence.m.matlab.folded",
    "content": " 0 400 400   a=\"\"\"\";\n 0 400 400   b=1;\n 0 400 400   c='\\';\n 0 400 400   d=2;\n 0 400 400   e=\"\\\";\n 0 400 400   f=3;\n 0 400 400   %\" this should be a comment (colored as such), instead it closes the string\n 0 400 400   g=\"\n 0 400 400   h=123;\n 0 400 400   %\" this is a syntax error in Matlab (about 'g'),\n 0 400 400   % followed by a valid assignment (of 'h')\n 0 400 400   % Instead, 'h' is colored as part of the string\n 1 400 400   \n 0 400 400   % Octave terminates string at 3rd \", Matlab at 4th\n 0 400 400   i=\"\\\" \"; % \" %\n 1 400 400   \n 0 400 400   % Matlab (unlike Octave) does not allow string continuation with an escape\n 0 400 400   b = \"multi\\\n 0 400 400   line\"\n 1 400 400   \n 0 400 400   % end\n 1 400 400   "
  },
  {
    "path": "test/examples/matlab/Issue18_EscapeSequence.m.matlab.styled",
    "content": "{7}a{6}={8}\"\"\"\"{6};{0}\n{7}b{6}={3}1{6};{0}\n{7}c{6}={5}'\\'{6};{0}\n{7}d{6}={3}2{6};{0}\n{7}e{6}={8}\"\\\"{6};{0}\n{7}f{6}={3}3{6};{0}\n{1}%\" this should be a comment (colored as such), instead it closes the string{0}\n{7}g{6}={8}\"{0}\n{7}h{6}={3}123{6};{0}\n{1}%\" this is a syntax error in Matlab (about 'g'),{0}\n{1}% followed by a valid assignment (of 'h'){0}\n{1}% Instead, 'h' is colored as part of the string{0}\n\n{1}% Octave terminates string at 3rd \", Matlab at 4th{0}\n{7}i{6}={8}\"\\\"{0} {8}\"; % \"{0} {1}%{0}\n\n{1}% Matlab (unlike Octave) does not allow string continuation with an escape{0}\n{7}b{0} {6}={0} {8}\"multi\\{0}\n{7}line{8}\"{0}\n\n{1}% end{0}\n"
  },
  {
    "path": "test/examples/matlab/Issue18_EscapeSequence.m.octave",
    "content": "% Ensure escape sequences still work in octave\n% Octave terminates string at 3rd \", Matlab at 4th\ni=\"\\\" \"; % \" %\n\n\n% Octave allows string continuation with an escape\nb = \"multi\\\nline\"\n\n% No escape so string ends at line end \nc = \"multi\nline\"\n\n% end\n"
  },
  {
    "path": "test/examples/matlab/Issue18_EscapeSequence.m.octave.folded",
    "content": " 0 400 400   % Ensure escape sequences still work in octave\n 0 400 400   % Octave terminates string at 3rd \", Matlab at 4th\n 0 400 400   i=\"\\\" \"; % \" %\n 1 400 400   \n 1 400 400   \n 0 400 400   % Octave allows string continuation with an escape\n 0 400 400   b = \"multi\\\n 0 400 400   line\"\n 1 400 400   \n 0 400 400   % No escape so string ends at line end \n 0 400 400   c = \"multi\n 0 400 400   line\"\n 1 400 400   \n 0 400 400   % end\n 1 400 400   "
  },
  {
    "path": "test/examples/matlab/Issue18_EscapeSequence.m.octave.styled",
    "content": "{1}% Ensure escape sequences still work in octave{0}\n{1}% Octave terminates string at 3rd \", Matlab at 4th{0}\n{7}i{6}={8}\"\\\" \"{6};{0} {1}% \" %{0}\n\n\n{1}% Octave allows string continuation with an escape{0}\n{7}b{0} {6}={0} {8}\"multi\\\nline\"{0}\n\n{1}% No escape so string ends at line end {0}\n{7}c{0} {6}={0} {8}\"multi{0}\n{7}line{8}\"{0}\n\n{1}% end{0}\n"
  },
  {
    "path": "test/examples/matlab/NumericLiterals.m.matlab",
    "content": "d    = 123;\nx    = 0x123ABC;\nb    = 0b010101;\nxs64 = 0x2As64;\nxs32 = 0x2As32;\nxs16 = 0x2As16;\nxs8  = 0x2As8;\nxu64 = 0x2Au64;\nxu32 = 0x2Au32;\nxu16 = 0x2Au16;\nxu8  = 0x2Au8;\nbs64 = 0b10s64;\nbs32 = 0b10s32;\nbs16 = 0b10s16;\nbs8  = 0b10s8;\nbu64 = 0b10u64;\nbu32 = 0b10u32;\nbu16 = 0b10u16;\nbu8  = 0b10u8;\nc = .1;\nc = 1.1;\nc = .1e1;\nc = 1.1e1;\nc = 1e1;\nc = 1i;\nc = 1j;\nc = .1e2j;\nc = 1e2j;\n"
  },
  {
    "path": "test/examples/matlab/NumericLiterals.m.matlab.folded",
    "content": " 0 400 400   d    = 123;\n 0 400 400   x    = 0x123ABC;\n 0 400 400   b    = 0b010101;\n 0 400 400   xs64 = 0x2As64;\n 0 400 400   xs32 = 0x2As32;\n 0 400 400   xs16 = 0x2As16;\n 0 400 400   xs8  = 0x2As8;\n 0 400 400   xu64 = 0x2Au64;\n 0 400 400   xu32 = 0x2Au32;\n 0 400 400   xu16 = 0x2Au16;\n 0 400 400   xu8  = 0x2Au8;\n 0 400 400   bs64 = 0b10s64;\n 0 400 400   bs32 = 0b10s32;\n 0 400 400   bs16 = 0b10s16;\n 0 400 400   bs8  = 0b10s8;\n 0 400 400   bu64 = 0b10u64;\n 0 400 400   bu32 = 0b10u32;\n 0 400 400   bu16 = 0b10u16;\n 0 400 400   bu8  = 0b10u8;\n 0 400 400   c = .1;\n 0 400 400   c = 1.1;\n 0 400 400   c = .1e1;\n 0 400 400   c = 1.1e1;\n 0 400 400   c = 1e1;\n 0 400 400   c = 1i;\n 0 400 400   c = 1j;\n 0 400 400   c = .1e2j;\n 0 400 400   c = 1e2j;\n 1 400 400   "
  },
  {
    "path": "test/examples/matlab/NumericLiterals.m.matlab.styled",
    "content": "{7}d{0}    {6}={0} {3}123{6};{0}\n{7}x{0}    {6}={0} {3}0x123ABC{6};{0}\n{7}b{0}    {6}={0} {3}0b010101{6};{0}\n{7}xs64{0} {6}={0} {3}0x2As64{6};{0}\n{7}xs32{0} {6}={0} {3}0x2As32{6};{0}\n{7}xs16{0} {6}={0} {3}0x2As16{6};{0}\n{7}xs8{0}  {6}={0} {3}0x2As8{6};{0}\n{7}xu64{0} {6}={0} {3}0x2Au64{6};{0}\n{7}xu32{0} {6}={0} {3}0x2Au32{6};{0}\n{7}xu16{0} {6}={0} {3}0x2Au16{6};{0}\n{7}xu8{0}  {6}={0} {3}0x2Au8{6};{0}\n{7}bs64{0} {6}={0} {3}0b10s64{6};{0}\n{7}bs32{0} {6}={0} {3}0b10s32{6};{0}\n{7}bs16{0} {6}={0} {3}0b10s16{6};{0}\n{7}bs8{0}  {6}={0} {3}0b10s8{6};{0}\n{7}bu64{0} {6}={0} {3}0b10u64{6};{0}\n{7}bu32{0} {6}={0} {3}0b10u32{6};{0}\n{7}bu16{0} {6}={0} {3}0b10u16{6};{0}\n{7}bu8{0}  {6}={0} {3}0b10u8{6};{0}\n{7}c{0} {6}={0} {3}.1{6};{0}\n{7}c{0} {6}={0} {3}1.1{6};{0}\n{7}c{0} {6}={0} {3}.1e1{6};{0}\n{7}c{0} {6}={0} {3}1.1e1{6};{0}\n{7}c{0} {6}={0} {3}1e1{6};{0}\n{7}c{0} {6}={0} {3}1i{6};{0}\n{7}c{0} {6}={0} {3}1j{6};{0}\n{7}c{0} {6}={0} {3}.1e2j{6};{0}\n{7}c{0} {6}={0} {3}1e2j{6};{0}\n"
  },
  {
    "path": "test/examples/matlab/SciTE.properties",
    "content": "lexer.*.matlab=matlab\nkeywords.*.matlab=end for global if break case catch classdef continue else elseif function otherwise parfor persistent return spmd switch try while\n\nlexer.*.octave=octave\nkeywords.*.octave=end for global if\n\nfold=1\nfold.compact=1\n"
  },
  {
    "path": "test/examples/mmixal/AllStyles.mms",
    "content": "% Demonstrate each possible style. Does not make sense as code.\n\n% A comment 1\n% Comment\n\n\n% Whitespace 0\n        \n\n\n% Label 2\nlabel\n\n\n% Not Validated Opcode 3 appears to always validate to either 5 or 6\n% so is never seen on screen.\n\n\n% Division between Label and Opcode 4\nla      \n\n\n% Valid Opcode 5\n        TRAP\n\n\n% Invalid Opcode 6\n        UNKNOWN\n\n\n% Division between Opcode and Operands 7\n        LOC   \n\n\n% Division of Operands 8\n        LOC   0.\n\n\n% Number 9\n        BYTE  0\n\n\n% Reference 10\n        JMP @label\n\n\n% Char 11\n        BYTE 'a'\n\n\n% String 12\n        BYTE \"Hello, world!\"\n\n\n% Register 13\n        BYTE rA\n\n\n% Hexadecimal Number 14\n        BYTE #FF\n\n\n% Operator 15\n        BYTE  +\n\n\n% Symbol 16\n        TRAP  Fputs\n\n\n% Preprocessor 17\n@include a.mms\n\n\n"
  },
  {
    "path": "test/examples/mmixal/AllStyles.mms.folded",
    "content": " 0 400   0   % Demonstrate each possible style. Does not make sense as code.\n 0 400   0   \n 0 400   0   % A comment 1\n 0 400   0   % Comment\n 0 400   0   \n 0 400   0   \n 0 400   0   % Whitespace 0\n 0 400   0           \n 0 400   0   \n 0 400   0   \n 0 400   0   % Label 2\n 0 400   0   label\n 0 400   0   \n 0 400   0   \n 0 400   0   % Not Validated Opcode 3 appears to always validate to either 5 or 6\n 0 400   0   % so is never seen on screen.\n 0 400   0   \n 0 400   0   \n 0 400   0   % Division between Label and Opcode 4\n 0 400   0   la      \n 0 400   0   \n 0 400   0   \n 0 400   0   % Valid Opcode 5\n 0 400   0           TRAP\n 0 400   0   \n 0 400   0   \n 0 400   0   % Invalid Opcode 6\n 0 400   0           UNKNOWN\n 0 400   0   \n 0 400   0   \n 0 400   0   % Division between Opcode and Operands 7\n 0 400   0           LOC   \n 0 400   0   \n 0 400   0   \n 0 400   0   % Division of Operands 8\n 0 400   0           LOC   0.\n 0 400   0   \n 0 400   0   \n 0 400   0   % Number 9\n 0 400   0           BYTE  0\n 0 400   0   \n 0 400   0   \n 0 400   0   % Reference 10\n 0 400   0           JMP @label\n 0 400   0   \n 0 400   0   \n 0 400   0   % Char 11\n 0 400   0           BYTE 'a'\n 0 400   0   \n 0 400   0   \n 0 400   0   % String 12\n 0 400   0           BYTE \"Hello, world!\"\n 0 400   0   \n 0 400   0   \n 0 400   0   % Register 13\n 0 400   0           BYTE rA\n 0 400   0   \n 0 400   0   \n 0 400   0   % Hexadecimal Number 14\n 0 400   0           BYTE #FF\n 0 400   0   \n 0 400   0   \n 0 400   0   % Operator 15\n 0 400   0           BYTE  +\n 0 400   0   \n 0 400   0   \n 0 400   0   % Symbol 16\n 0 400   0           TRAP  Fputs\n 0 400   0   \n 0 400   0   \n 0 400   0   % Preprocessor 17\n 0 400   0   @include a.mms\n 0 400   0   \n 0 400   0   \n 0 400   0   "
  },
  {
    "path": "test/examples/mmixal/AllStyles.mms.styled",
    "content": "{1}% Demonstrate each possible style. Does not make sense as code.\n{0}\n{1}% A comment 1\n% Comment\n{0}\n\n{1}% Whitespace 0\n{0}        \n\n\n{1}% Label 2\n{2}label{4}\n{0}\n\n{1}% Not Validated Opcode 3 appears to always validate to either 5 or 6\n% so is never seen on screen.\n{0}\n\n{1}% Division between Label and Opcode 4\n{2}la{4}      \n{0}\n\n{1}% Valid Opcode 5\n{0}        {5}TRAP{7}\n{0}\n\n{1}% Invalid Opcode 6\n{0}        {6}UNKNOWN{7}\n{0}\n\n{1}% Division between Opcode and Operands 7\n{0}        {5}LOC{7}   \n{0}\n\n{1}% Division of Operands 8\n{0}        {5}LOC{7}   {9}0{8}.{1}\n{0}\n\n{1}% Number 9\n{0}        {5}BYTE{7}  {9}0{1}\n{0}\n\n{1}% Reference 10\n{0}        {5}JMP{7} {10}@label{1}\n{0}\n\n{1}% Char 11\n{0}        {5}BYTE{7} {11}'a'{1}\n{0}\n\n{1}% String 12\n{0}        {5}BYTE{7} {12}\"Hello, world!\"{1}\n{0}\n\n{1}% Register 13\n{0}        {5}BYTE{7} {13}rA{1}\n{0}\n\n{1}% Hexadecimal Number 14\n{0}        {5}BYTE{7} {14}#FF{1}\n{0}\n\n{1}% Operator 15\n{0}        {5}BYTE{7}  {15}+{1}\n{0}\n\n{1}% Symbol 16\n{0}        {5}TRAP{7}  {16}Fputs{1}\n{0}\n\n{1}% Preprocessor 17\n{17}@include a.mms\n{0}\n\n"
  },
  {
    "path": "test/examples/mmixal/SciTE.properties",
    "content": "lexer.*.mms=mmixal\nkeywords.*.mms=BYTE GETA JMP LOC PREFIX TRAP\nkeywords2.*.mms=rA\nkeywords3.*.mms=Fputs StdOut\n"
  },
  {
    "path": "test/examples/mmixal/references.mms",
    "content": "# Bug #2019 Buffer over-read in MMIXAL lexer\nlabel\n        PREFIX  Foo:\n% Relative reference (uses PREFIX)\n        JMP label\n%\n        JMP @label\n% Absolute reference (does not use PREFIX)\n        JMP :label\n% In register list so treated as register\n        JMP :rA\n% Too long for buffer so truncated\n        JMP l1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n% Too long for buffer so truncated then treated as absolute\n        JMP :l1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n%\n"
  },
  {
    "path": "test/examples/mmixal/references.mms.folded",
    "content": " 0 400   0   # Bug #2019 Buffer over-read in MMIXAL lexer\n 0 400   0   label\n 0 400   0           PREFIX  Foo:\n 0 400   0   % Relative reference (uses PREFIX)\n 0 400   0           JMP label\n 0 400   0   %\n 0 400   0           JMP @label\n 0 400   0   % Absolute reference (does not use PREFIX)\n 0 400   0           JMP :label\n 0 400   0   % In register list so treated as register\n 0 400   0           JMP :rA\n 0 400   0   % Too long for buffer so truncated\n 0 400   0           JMP l1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n 0 400   0   % Too long for buffer so truncated then treated as absolute\n 0 400   0           JMP :l1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n 0 400   0   %\n 0 400   0   "
  },
  {
    "path": "test/examples/mmixal/references.mms.styled",
    "content": "{1}# Bug #2019 Buffer over-read in MMIXAL lexer\n{2}label{4}\n{0}        {5}PREFIX{7}  {10}Foo:{1}\n% Relative reference (uses PREFIX)\n{0}        {5}JMP{7} {10}label{1}\n%\n{0}        {5}JMP{7} {10}@label{1}\n% Absolute reference (does not use PREFIX)\n{0}        {5}JMP{7} {10}:label{1}\n% In register list so treated as register\n{0}        {5}JMP{7} {13}:rA{1}\n% Too long for buffer so truncated\n{0}        {5}JMP{7} {10}l1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890{1}\n% Too long for buffer so truncated then treated as absolute\n{0}        {5}JMP{7} {10}:l1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890{1}\n%\n"
  },
  {
    "path": "test/examples/mmixal/x.mms",
    "content": "% Some example code\n\n        % Set the address of the program initially to 0x100.\n        LOC   #100\n\nMain    GETA  $255,string\n\n        TRAP  0,Fputs,StdOut\n\n        TRAP  0,Halt,0\n\nstring  BYTE  \"Hello, world!\",#a,0\n"
  },
  {
    "path": "test/examples/mmixal/x.mms.folded",
    "content": " 0 400   0   % Some example code\n 0 400   0   \n 0 400   0           % Set the address of the program initially to 0x100.\n 0 400   0           LOC   #100\n 0 400   0   \n 0 400   0   Main    GETA  $255,string\n 0 400   0   \n 0 400   0           TRAP  0,Fputs,StdOut\n 0 400   0   \n 0 400   0           TRAP  0,Halt,0\n 0 400   0   \n 0 400   0   string  BYTE  \"Hello, world!\",#a,0\n 0 400   0   "
  },
  {
    "path": "test/examples/mmixal/x.mms.styled",
    "content": "{1}% Some example code\n{0}\n        {1}% Set the address of the program initially to 0x100.\n{0}        {5}LOC{7}   {14}#100{1}\n{0}\n{2}Main{4}    {5}GETA{7}  {13}$255{15},{10}string{1}\n{0}\n        {5}TRAP{7}  {9}0{15},{16}Fputs{15},{16}StdOut{1}\n{0}\n        {5}TRAP{7}  {9}0{15},{10}Halt{15},{9}0{1}\n{0}\n{2}string{4}  {5}BYTE{7}  {12}\"Hello, world!\"{15},{14}#a{15},{9}0{1}\n"
  },
  {
    "path": "test/examples/modula/128Endless.m3",
    "content": "(* This file caused an infinite loop in the folder before #128 was fixed.*)\nMODULE Form;\n  IMPORT  \n\n  PROCEDURE (bf: ButtonForm) InitializeComponent(), NEW;\n  BEGIN\n    bf.SuspendLayout();\n    REGISTER(bf.button1.Click, bf.button1_Click);\n    bf.get_Controls().Add(bf.button2);\n  END InitializeComponent;\n\nBEGIN\n    NEW(bf);\n    Wfm.Application.Run(bf);\nEND Form.\n"
  },
  {
    "path": "test/examples/modula/128Endless.m3.folded",
    "content": " 0 400 400   (* This file caused an infinite loop in the folder before #128 was fixed.*)\n 0 400 400   MODULE Form;\n 0 400 400     IMPORT  \n 1 400 400   \n 0 400 400     PROCEDURE (bf: ButtonForm) InitializeComponent(), NEW;\n 2 400 401 +   BEGIN\n 0 401 401 |     bf.SuspendLayout();\n 0 401 401 |     REGISTER(bf.button1.Click, bf.button1_Click);\n 0 401 401 |     bf.get_Controls().Add(bf.button2);\n 0 401 400 |   END InitializeComponent;\n 1 400 400   \n 2 400 401 + BEGIN\n 0 401 401 |     NEW(bf);\n 0 401 401 |     Wfm.Application.Run(bf);\n 0 401 400 | END Form.\n 1 400 400   "
  },
  {
    "path": "test/examples/modula/128Endless.m3.styled",
    "content": "{1}(* This file caused an infinite loop in the folder before #128 was fixed.*){0}\n{4}MODULE{0} Form{16};{0}\n  {4}IMPORT{0}  \n\n  {4}PROCEDURE{0} {16}({0}bf{16}:{0} ButtonForm{16}){0} InitializeComponent{16}(),{0} {5}NEW{16};{0}\n  {4}BEGIN{0}\n    bf{16}.{0}SuspendLayout{16}();{0}\n    REGISTER{16}({0}bf{16}.{0}button1{16}.{0}Click{16},{0} bf{16}.{0}button1_Click{16});{0}\n    bf{16}.{0}get_Controls{16}().{0}Add{16}({0}bf{16}.{0}button2{16});{0}\n  {4}END{0} InitializeComponent{16};{0}\n\n{4}BEGIN{0}\n    {5}NEW{16}({0}bf{16});{0}\n    Wfm{16}.{0}Application{16}.{0}Run{16}({0}bf{16});{0}\n{4}END{0} Form{16}.{0}\n"
  },
  {
    "path": "test/examples/modula/Issue129.m3",
    "content": "INTERFACE Test;\n\nTYPE\n  (* Opaque types *)\n  HANDLE                  = ADDRESS;\n  HMOD(* Module handle *) = HANDLE;\n\nEND Test.\n"
  },
  {
    "path": "test/examples/modula/Issue129.m3.folded",
    "content": " 0 400 400   INTERFACE Test;\n 1 400 400   \n 0 400 400   TYPE\n 0 400 400     (* Opaque types *)\n 0 400 400     HANDLE                  = ADDRESS;\n 0 400 400     HMOD(* Module handle *) = HANDLE;\n 1 400 400   \n 0 400 3ff   END Test.\n 1 3ff 3ff   "
  },
  {
    "path": "test/examples/modula/Issue129.m3.styled",
    "content": "{4}INTERFACE{0} Test{16};{0}\n\n{4}TYPE{0}\n  {1}(* Opaque types *){0}\n  HANDLE                  {16}={0} {5}ADDRESS{16};{0}\n  HMOD{1}(* Module handle *){0} {16}={0} HANDLE{16};{0}\n\n{4}END{0} Test{16}.{0}\n"
  },
  {
    "path": "test/examples/modula/Issue297.m3",
    "content": "INTERFACE Issue297;\n\nTYPE\n  INTEGER32 = [-16_7fffffff-1 .. 16_7fffffff];\n\nEND Issue297.\n"
  },
  {
    "path": "test/examples/modula/Issue297.m3.folded",
    "content": " 0 400 400   INTERFACE Issue297;\n 1 400 400   \n 0 400 400   TYPE\n 0 400 400     INTEGER32 = [-16_7fffffff-1 .. 16_7fffffff];\n 1 400 400   \n 0 400 3ff   END Issue297.\n 1 3ff 3ff   "
  },
  {
    "path": "test/examples/modula/Issue297.m3.styled",
    "content": "{4}INTERFACE{0} Issue297{16};{0}\n\n{4}TYPE{0}\n  INTEGER32 {16}={0} {16}[-{7}16_7fffffff{16}-{6}1{0} {16}..{0} {7}16_7fffffff{16}];{0}\n\n{4}END{0} Issue297{16}.{0}\n"
  },
  {
    "path": "test/examples/modula/SciTE.properties",
    "content": "lexer.*.m3=modula\n#\tKeywords\nkeywords.*.m3=AND ANY ARRAY AS BEGIN BITS BRANDED BY CASE CONST\\\n\tDIV DO ELSE ELSIF END EVAL EXCEPT EXCEPTION EXIT EXPORTS FINALLY FOR FROM\\\n\tGENERIC IF IMPORT IN INTERFACE LOCK LOOP METHODS MOD MODULE NOT OBJECT OF\\\n\tOR OVERRIDES PROCEDURE RAISE RAISES READONLY RECORD REF REPEAT RETURN\\\n\tREVEAL ROOT SET THEN TO TRY TYPE TYPECASE UNSAFE UNTIL UNTRACED VALUE VAR\\\n\tWHILE WITH\n#\tReserved identifiers\nkeywords2.*.m3=ABS ADDRESS ADR ADRSIZE BITSIZE BOOLEAN BYTESIZE\\\n\tCARDINAL CEILING CHAR DEC DISPOSE EXTENDED FALSE FIRST FLOAT FLOOR INC\\\n\tINTEGER ISTYPE LAST LONGINT LONGREAL LOOPHOLE MAX MIN MUTEX NARROW NEW NIL\\\n\tNULL NUMBER ORD REAL REFANY ROUND SUBARRAY TEXT TRUE TRUNC TYPECODE VAL\\\n\tWIDECHAR\n#\tOperators\nkeywords3.*.m3= + < # = ; .. : - > { } | := <: * <= ( ) ^ , =>\\\n\t/ >= [ ] . &\n#\tPragmas keywords\nkeywords4.*.m3= EXTERNAL INLINE ASSERT TRACE FATAL UNUSED\\\n\tOBSOLETE NOWARN LINE PRAGMA\n#\tEscape sequences\nkeywords5.*.m3= f n r t \\ \" '\n#\tDoxygene keywords\nkeywords6.*.m3= author authors file brief date proc param result\n\nfold=1\n"
  },
  {
    "path": "test/examples/mssql/AllStyles.tsql",
    "content": "-- Enumerate all styles: 0 to 16\n\n/* block comment = 1*/\n\n-- whitespace = 0\n    -- spaces\n\n-- line comment = 2\n\n-- number = 3\n376\n\n-- string = 4\n'a string'\n\n-- operator = 5\n()\nINTERSECT\n\n-- identifier = 6\nProductID;\n\n-- variable = 7\n@Variable;\n\n-- column name = 8\n\"COLUMN\";\n\n-- statement = 9\nPRINT\n\n-- datatype = 10\nint\n\n-- systable = 11\nsysobjects\n\n-- global variable = 12\n@@ERROR\n\n-- function = 13\nobject_id\n\n-- stored procedure = 14\nsp_fulltext_database\n\n-- default (preferencing data type) = 15\nx --\n\n-- column name 2 = 16\n[COLUMN];\n\n"
  },
  {
    "path": "test/examples/mssql/AllStyles.tsql.folded",
    "content": " 0 400   0   -- Enumerate all styles: 0 to 16\n 1 400   0   \n 0 400   0   /* block comment = 1*/\n 1 400   0   \n 0 400   0   -- whitespace = 0\n 0 400   0       -- spaces\n 1 400   0   \n 0 400   0   -- line comment = 2\n 1 400   0   \n 0 400   0   -- number = 3\n 0 400   0   376\n 1 400   0   \n 0 400   0   -- string = 4\n 0 400   0   'a string'\n 1 400   0   \n 0 400   0   -- operator = 5\n 0 400   0   ()\n 0 400   0   INTERSECT\n 1 400   0   \n 0 400   0   -- identifier = 6\n 0 400   0   ProductID;\n 1 400   0   \n 0 400   0   -- variable = 7\n 0 400   0   @Variable;\n 1 400   0   \n 0 400   0   -- column name = 8\n 0 400   0   \"COLUMN\";\n 1 400   0   \n 0 400   0   -- statement = 9\n 0 400   0   PRINT\n 1 400   0   \n 0 400   0   -- datatype = 10\n 0 400   0   int\n 1 400   0   \n 0 400   0   -- systable = 11\n 0 400   0   sysobjects\n 1 400   0   \n 0 400   0   -- global variable = 12\n 0 400   0   @@ERROR\n 1 400   0   \n 0 400   0   -- function = 13\n 0 400   0   object_id\n 1 400   0   \n 0 400   0   -- stored procedure = 14\n 0 400   0   sp_fulltext_database\n 1 400   0   \n 0 400   0   -- default (preferencing data type) = 15\n 0 400   0   x --\n 1 400   0   \n 0 400   0   -- column name 2 = 16\n 0 400   0   [COLUMN];\n 1 400   0   \n 0 400   0   "
  },
  {
    "path": "test/examples/mssql/AllStyles.tsql.styled",
    "content": "{2}-- Enumerate all styles: 0 to 16{0}\n\n{1}/* block comment = 1*/{0}\n\n{2}-- whitespace = 0{0}\n    {2}-- spaces{0}\n\n{2}-- line comment = 2{0}\n\n{2}-- number = 3{0}\n{3}376{0}\n\n{2}-- string = 4{0}\n{4}'a string'{0}\n\n{2}-- operator = 5{0}\n{5}(){0}\n{5}INTERSECT{0}\n\n{2}-- identifier = 6{0}\n{6}ProductID{5};{0}\n\n{2}-- variable = 7{0}\n{7}@Variable{5};{0}\n\n{2}-- column name = 8{0}\n{8}\"COLUMN\"{5};{0}\n\n{2}-- statement = 9{0}\n{9}PRINT{0}\n\n{2}-- datatype = 10{0}\n{10}int{0}\n\n{2}-- systable = 11{0}\n{11}sysobjects{0}\n\n{2}-- global variable = 12{0}\n{12}@@ERROR{0}\n\n{2}-- function = 13{0}\n{13}object_id{0}\n\n{2}-- stored procedure = 14{0}\n{14}sp_fulltext_database{0}\n\n{2}-- default (preferencing data type) = 15{0}\n{6}x{15} {2}--{0}\n\n{2}-- column name 2 = 16{0}\n{16}[COLUMN]{5};{0}\n\n"
  },
  {
    "path": "test/examples/mssql/Issue87.tsql",
    "content": "/**\n /*\n  GitHub Issue 87\n  /*\n    /****** Object:  Table [dbo].[Issue87]    Script Date: 04/06/2022 8:07:57 PM ******/\n   */\n  */\n */\n"
  },
  {
    "path": "test/examples/mssql/Issue87.tsql.folded",
    "content": " 2 400   0 + /**\n 0 401   0 |  /*\n 0 401   0 |   GitHub Issue 87\n 0 401   0 |   /*\n 0 401   0 |     /****** Object:  Table [dbo].[Issue87]    Script Date: 04/06/2022 8:07:57 PM ******/\n 0 401   0 |    */\n 0 401   0 |   */\n 0 401   0 |  */\n 0 400   0   "
  },
  {
    "path": "test/examples/mssql/Issue87.tsql.styled",
    "content": "{1}/**\n /*\n  GitHub Issue 87\n  /*\n    /****** Object:  Table [dbo].[Issue87]    Script Date: 04/06/2022 8:07:57 PM ******/\n   */\n  */\n */{0}\n"
  },
  {
    "path": "test/examples/mssql/Issue90.tsql",
    "content": "CREATE TABLE TestTable (\n    col\n    CHAR(3)\n);\n"
  },
  {
    "path": "test/examples/mssql/Issue90.tsql.folded",
    "content": " 0 400   0   CREATE TABLE TestTable (\n 0 400   0       col\n 0 400   0       CHAR(3)\n 0 400   0   );\n 0 400   0   "
  },
  {
    "path": "test/examples/mssql/Issue90.tsql.styled",
    "content": "{9}CREATE{0} {9}TABLE{0} {6}TestTable{15} {5}({0}\n    {6}col{15}\n    {10}CHAR{5}({3}3{5}){0}\n{5});{0}\n"
  },
  {
    "path": "test/examples/mssql/SciTE.properties",
    "content": "lexer.*.tsql=mssql\nfold=1\nfold.comment=1\n\n# statement\nkeywords.*.tsql=and as begin by create declare distinct drop else end exists from go if in insert into is inner \\\njoin like not null on order print procedure return select set table use values where while\n\n# data type\nkeywords2.*.tsql=char int\n\n# System table\nkeywords3.*.tsql=sysobjects\n\n# global variables\nkeywords4.*.tsql=error\n\n# functions\nkeywords5.*.tsql=ascii char object_id\n\n# System stored procedures\nkeywords6.*.tsql=sp_fulltext_database\n\n# operators\nkeywords7.*.tsql=intersect\n"
  },
  {
    "path": "test/examples/mssql/Various.tsql",
    "content": "/* This file contains snippets of Transact-SQL that exercise various aspects of the language. */\n/**\n /*\n  AllStyles.tsql\n  /*\n    /****** Object:  Database [AllStyles]    Script Date: 06/16/2022 10:56:35 PM ******/\n   */\n  */\n */\nIF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))\nBEGIN\n    EXEC sp_fulltext_database @action = 'enable';\nEND\nUSE AllStyles;\nGO\nSELECT *\nFROM Production.Product\nORDER BY Name ASC;\n-- Alternate way.\nUSE AllStyles;\nGO\nSELECT p.*\nFROM Production.Product AS p\nORDER BY Name ASC;\nGO\n\nSELECT \"COLUMN\" FROM \"TABLE\"\nSELECT \"COLUMN\" int FROM \"TABLE\"\n\nSELECT schema_name\n    (tab.schema_id) AS schema_name\n    -- retrieve the name, too\n    ,tab.name\nFROM sys.tables AS tab;\n\nSELECT DISTINCT Name\nFROM Production.Product AS p\nWHERE EXISTS\n    (SELECT *\n     FROM Production.ProductModel AS pm\n     WHERE p.ProductModelID = pm.ProductModelID\n           AND pm.Name LIKE 'Long-Sleeve Logo Jersey%');\n\nSELECT DISTINCT p.LastName, p.FirstName\nFROM Person.Person AS p\nJOIN HumanResources.Employee AS e\n    ON e.BusinessEntityID = p.BusinessEntityID WHERE 5000.00 IN\n    (SELECT Bonus\n     FROM Sales.SalesPerson AS sp\n     WHERE e.BusinessEntityID = sp.BusinessEntityID);\n\nCREATE PROCEDURE findjobs @nm sysname = NULL\nAS\nIF @nm IS NULL\n    BEGIN\n        PRINT 'You must give a user name'\n        RETURN\n    END\nELSE\n    BEGIN\n        SELECT o.name, o.id, o.uid\n        FROM sysobjects o INNER JOIN master.syslogins l\n            ON o.uid = l.sid\n        WHERE l.name = @nm\n    END;\n\nCREATE TABLE TestTable (cola INT, colb CHAR(3));\n-- Declare the variable to be used.\nDECLARE @MyCounter INT;\n\n-- Initialize the variable.\nSET @MyCounter = 0;\nWHILE (@MyCounter < 26)\nBEGIN;\n   -- Insert a row into the table.\n   INSERT INTO TestTable VALUES\n       -- Use the variable to provide the integer value\n       -- for cola. Also use it to generate a unique letter\n       -- for each row. Use the ASCII function to get the\n       -- integer value of 'a'. Add @MyCounter. Use CHAR to\n       -- convert the sum back to the character @MyCounter\n       -- characters after 'a'.\n       (@MyCounter,\n        CHAR( ( @MyCounter + ASCII('a') ) )\n       );\n   -- Increment the variable to count this iteration\n   -- of the loop.\n   SET @MyCounter = @MyCounter + 1;\nEND;\n\nIF @@ERROR = 547\n    BEGIN\n    PRINT N'A check constraint violation occurred.';\n    END\nGO\n\nUSE [AllStyles].[dbo].[test]\nGO\n\nSELECT ProductID\nFROM Production.Product\nINTERSECT\nSELECT ProductID\nFROM Production.WorkOrder ;\n"
  },
  {
    "path": "test/examples/mssql/Various.tsql.folded",
    "content": " 0 400   0   /* This file contains snippets of Transact-SQL that exercise various aspects of the language. */\n 2 400   0 + /**\n 0 401   0 |  /*\n 0 401   0 |   AllStyles.tsql\n 0 401   0 |   /*\n 0 401   0 |     /****** Object:  Database [AllStyles]    Script Date: 06/16/2022 10:56:35 PM ******/\n 0 401   0 |    */\n 0 401   0 |   */\n 0 401   0 |  */\n 0 400   0   IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))\n 2 400   0 + BEGIN\n 0 401   0 |     EXEC sp_fulltext_database @action = 'enable';\n 0 401   0 | END\n 0 400   0   USE AllStyles;\n 0 400   0   GO\n 0 400   0   SELECT *\n 0 400   0   FROM Production.Product\n 0 400   0   ORDER BY Name ASC;\n 0 400   0   -- Alternate way.\n 0 400   0   USE AllStyles;\n 0 400   0   GO\n 0 400   0   SELECT p.*\n 0 400   0   FROM Production.Product AS p\n 0 400   0   ORDER BY Name ASC;\n 0 400   0   GO\n 1 400   0   \n 0 400   0   SELECT \"COLUMN\" FROM \"TABLE\"\n 0 400   0   SELECT \"COLUMN\" int FROM \"TABLE\"\n 1 400   0   \n 0 400   0   SELECT schema_name\n 0 400   0       (tab.schema_id) AS schema_name\n 0 400   0       -- retrieve the name, too\n 0 400   0       ,tab.name\n 0 400   0   FROM sys.tables AS tab;\n 1 400   0   \n 0 400   0   SELECT DISTINCT Name\n 0 400   0   FROM Production.Product AS p\n 0 400   0   WHERE EXISTS\n 0 400   0       (SELECT *\n 0 400   0        FROM Production.ProductModel AS pm\n 0 400   0        WHERE p.ProductModelID = pm.ProductModelID\n 0 400   0              AND pm.Name LIKE 'Long-Sleeve Logo Jersey%');\n 1 400   0   \n 0 400   0   SELECT DISTINCT p.LastName, p.FirstName\n 0 400   0   FROM Person.Person AS p\n 0 400   0   JOIN HumanResources.Employee AS e\n 0 400   0       ON e.BusinessEntityID = p.BusinessEntityID WHERE 5000.00 IN\n 0 400   0       (SELECT Bonus\n 0 400   0        FROM Sales.SalesPerson AS sp\n 0 400   0        WHERE e.BusinessEntityID = sp.BusinessEntityID);\n 1 400   0   \n 0 400   0   CREATE PROCEDURE findjobs @nm sysname = NULL\n 0 400   0   AS\n 0 400   0   IF @nm IS NULL\n 2 400   0 +     BEGIN\n 0 401   0 |         PRINT 'You must give a user name'\n 0 401   0 |         RETURN\n 0 401   0 |     END\n 0 400   0   ELSE\n 2 400   0 +     BEGIN\n 0 401   0 |         SELECT o.name, o.id, o.uid\n 0 401   0 |         FROM sysobjects o INNER JOIN master.syslogins l\n 0 401   0 |             ON o.uid = l.sid\n 0 401   0 |         WHERE l.name = @nm\n 0 401   0 |     END;\n 1 400   0   \n 0 400   0   CREATE TABLE TestTable (cola INT, colb CHAR(3));\n 0 400   0   -- Declare the variable to be used.\n 0 400   0   DECLARE @MyCounter INT;\n 1 400   0   \n 0 400   0   -- Initialize the variable.\n 0 400   0   SET @MyCounter = 0;\n 0 400   0   WHILE (@MyCounter < 26)\n 2 400   0 + BEGIN;\n 0 401   0 |    -- Insert a row into the table.\n 0 401   0 |    INSERT INTO TestTable VALUES\n 0 401   0 |        -- Use the variable to provide the integer value\n 0 401   0 |        -- for cola. Also use it to generate a unique letter\n 0 401   0 |        -- for each row. Use the ASCII function to get the\n 0 401   0 |        -- integer value of 'a'. Add @MyCounter. Use CHAR to\n 0 401   0 |        -- convert the sum back to the character @MyCounter\n 0 401   0 |        -- characters after 'a'.\n 0 401   0 |        (@MyCounter,\n 0 401   0 |         CHAR( ( @MyCounter + ASCII('a') ) )\n 0 401   0 |        );\n 0 401   0 |    -- Increment the variable to count this iteration\n 0 401   0 |    -- of the loop.\n 0 401   0 |    SET @MyCounter = @MyCounter + 1;\n 0 401   0 | END;\n 1 400   0   \n 0 400   0   IF @@ERROR = 547\n 2 400   0 +     BEGIN\n 0 401   0 |     PRINT N'A check constraint violation occurred.';\n 0 401   0 |     END\n 0 400   0   GO\n 1 400   0   \n 0 400   0   USE [AllStyles].[dbo].[test]\n 0 400   0   GO\n 1 400   0   \n 0 400   0   SELECT ProductID\n 0 400   0   FROM Production.Product\n 0 400   0   INTERSECT\n 0 400   0   SELECT ProductID\n 0 400   0   FROM Production.WorkOrder ;\n 0 400   0   "
  },
  {
    "path": "test/examples/mssql/Various.tsql.styled",
    "content": "{1}/* This file contains snippets of Transact-SQL that exercise various aspects of the language. */{0}\n{1}/**\n /*\n  AllStyles.tsql\n  /*\n    /****** Object:  Database [AllStyles]    Script Date: 06/16/2022 10:56:35 PM ******/\n   */\n  */\n */{0}\n{9}IF{0} {5}({3}1{0} {5}={0} {6}FULLTEXTSERVICEPROPERTY{5}({4}'IsFullTextInstalled'{5})){0}\n{9}BEGIN{0}\n    {6}EXEC{15} {14}sp_fulltext_database{0} {7}@action{15} {5}={0} {4}'enable'{5};{0}\n{9}END{0}\n{9}USE{0} {6}AllStyles{5};{0}\n{9}GO{0}\n{9}SELECT{0} {5}*{0}\n{9}FROM{0} {6}Production.Product{15}\n{9}ORDER{0} {9}BY{0} {6}Name{15} {6}ASC{5};{0}\n{2}-- Alternate way.{0}\n{9}USE{0} {6}AllStyles{5};{0}\n{9}GO{0}\n{9}SELECT{0} {6}p.{5}*{0}\n{9}FROM{0} {6}Production.Product{15} {9}AS{0} {6}p{15}\n{9}ORDER{0} {9}BY{0} {6}Name{15} {6}ASC{5};{0}\n{9}GO{0}\n\n{9}SELECT{0} {8}\"COLUMN\"{15} {9}FROM{0} {8}\"TABLE\"{15}\n{9}SELECT{0} {8}\"COLUMN\"{15} {10}int{0} {9}FROM{0} {8}\"TABLE\"{15}\n\n{9}SELECT{0} {6}schema_name{15}\n    {5}({6}tab.schema_id{5}){0} {9}AS{0} {6}schema_name{15}\n    {2}-- retrieve the name, too{0}\n    {5},{6}tab.name{15}\n{9}FROM{0} {6}sys.tables{15} {9}AS{0} {6}tab{5};{0}\n\n{9}SELECT{0} {9}DISTINCT{0} {6}Name{15}\n{9}FROM{0} {6}Production.Product{15} {9}AS{0} {6}p{15}\n{9}WHERE{0} {9}EXISTS{0}\n    {5}({9}SELECT{0} {5}*{0}\n     {9}FROM{0} {6}Production.ProductModel{15} {9}AS{0} {6}pm{15}\n     {9}WHERE{0} {6}p.ProductModelID{15} {5}={0} {6}pm.ProductModelID{15}\n           {9}AND{0} {6}pm.Name{15} {9}LIKE{0} {4}'Long-Sleeve Logo Jersey%'{5});{0}\n\n{9}SELECT{0} {9}DISTINCT{0} {6}p.LastName{5},{0} {6}p.FirstName{15}\n{9}FROM{0} {6}Person.Person{15} {9}AS{0} {6}p{15}\n{9}JOIN{0} {6}HumanResources.Employee{15} {9}AS{0} {6}e{15}\n    {9}ON{0} {6}e.BusinessEntityID{15} {5}={0} {6}p.BusinessEntityID{15} {9}WHERE{0} {3}5000.00{0} {9}IN{0}\n    {5}({9}SELECT{0} {6}Bonus{15}\n     {9}FROM{0} {6}Sales.SalesPerson{15} {9}AS{0} {6}sp{15}\n     {9}WHERE{0} {6}e.BusinessEntityID{15} {5}={0} {6}sp.BusinessEntityID{5});{0}\n\n{9}CREATE{0} {9}PROCEDURE{0} {6}findjobs{0} {7}@nm{15} {6}sysname{15} {5}={0} {9}NULL{0}\n{9}AS{0}\n{9}IF{0} {7}@nm{15} {9}IS{0} {9}NULL{0}\n    {9}BEGIN{0}\n        {9}PRINT{0} {4}'You must give a user name'{0}\n        {9}RETURN{0}\n    {9}END{0}\n{9}ELSE{0}\n    {9}BEGIN{0}\n        {9}SELECT{0} {6}o.name{5},{0} {6}o.id{5},{0} {6}o.uid{15}\n        {9}FROM{0} {11}sysobjects{0} {6}o{15} {9}INNER{0} {9}JOIN{0} {6}master.syslogins{15} {6}l{15}\n            {9}ON{0} {6}o.uid{15} {5}={0} {6}l.sid{15}\n        {9}WHERE{0} {6}l.name{15} {5}={0} {7}@nm{15}\n    {9}END{5};{0}\n\n{9}CREATE{0} {9}TABLE{0} {6}TestTable{15} {5}({6}cola{15} {10}INT{5},{0} {6}colb{15} {10}CHAR{5}({3}3{5}));{0}\n{2}-- Declare the variable to be used.{0}\n{9}DECLARE{0} {7}@MyCounter{15} {10}INT{5};{0}\n\n{2}-- Initialize the variable.{0}\n{9}SET{0} {7}@MyCounter{15} {5}={0} {3}0{5};{0}\n{9}WHILE{0} {5}({7}@MyCounter{15} {5}<{0} {3}26{5}){0}\n{9}BEGIN{5};{0}\n   {2}-- Insert a row into the table.{0}\n   {9}INSERT{0} {9}INTO{0} {6}TestTable{15} {9}VALUES{0}\n       {2}-- Use the variable to provide the integer value{0}\n       {2}-- for cola. Also use it to generate a unique letter{0}\n       {2}-- for each row. Use the ASCII function to get the{0}\n       {2}-- integer value of 'a'. Add @MyCounter. Use CHAR to{0}\n       {2}-- convert the sum back to the character @MyCounter{0}\n       {2}-- characters after 'a'.{0}\n       {5}({7}@MyCounter{5},{0}\n        {13}CHAR{5}({0} {5}({0} {7}@MyCounter{15} {5}+{0} {13}ASCII{5}({4}'a'{5}){0} {5}){0} {5}){0}\n       {5});{0}\n   {2}-- Increment the variable to count this iteration{0}\n   {2}-- of the loop.{0}\n   {9}SET{0} {7}@MyCounter{15} {5}={0} {7}@MyCounter{15} {5}+{0} {3}1{5};{0}\n{9}END{5};{0}\n\n{9}IF{0} {12}@@ERROR{0} {5}={0} {3}547{0}\n    {9}BEGIN{0}\n    {9}PRINT{0} {6}N{4}'A check constraint violation occurred.'{5};{0}\n    {9}END{0}\n{9}GO{0}\n\n{9}USE{0} {16}[AllStyles]{5}.{16}[dbo]{5}.{16}[test]{15}\n{9}GO{0}\n\n{9}SELECT{0} {6}ProductID{15}\n{9}FROM{0} {6}Production.Product{15}\n{5}INTERSECT{0}\n{9}SELECT{0} {6}ProductID{15}\n{9}FROM{0} {6}Production.WorkOrder{15} {5};{0}\n"
  },
  {
    "path": "test/examples/mysql/AllStyles.sql",
    "content": "-- Enumerate all styles: 0 to 22, except for 3 (variable) and 11 (string) which are not implemented\n-- Hidden commands with other states (ored with ox40) are also possible inside /*! ... */\n\n/* commentline=2 */\n# comment\n\n# default=0\n\t# w\n\n# comment=1\n/* comment */\n\n# variable=3 is not implemented\n@variable\n\n# systemvariable=4\n@@systemvariable\n\n# knownsystemvariable=5\n@@known\n\n# number=6\n6\n\n# majorkeyword=7\nselect\n\n# keyword=8\nin\n\n# databaseobject=9\nobject\n\n# procedurekeyword=10\nprocedure\n\n# string=11 is not implemented\n\n# sqstring=12\n'string'\n\n# dqstring=13\n\"string\"\n\n# operator=14\n+\n\n# function=15\nfunction()\n\n# identifier=16\nidentifier\n\n# quotedidentifier=17\n`quoted`\n\n# user1=18\nuser1\n\n# user2=19\nuser2\n\n# user3=20\nuser3\n\n# hiddencommand=21\n/*!*/\n\n# placeholder=22\n<{placeholder>}\n"
  },
  {
    "path": "test/examples/mysql/AllStyles.sql.folded",
    "content": " 0 400 400   -- Enumerate all styles: 0 to 22, except for 3 (variable) and 11 (string) which are not implemented\n 0 400 400   -- Hidden commands with other states (ored with ox40) are also possible inside /*! ... */\n 1 400 400   \n 0 400 400   /* commentline=2 */\n 0 400 400   # comment\n 1 400 400   \n 0 400 400   # default=0\n 0 400 400   \t# w\n 1 400 400   \n 0 400 400   # comment=1\n 0 400 400   /* comment */\n 1 400 400   \n 0 400 400   # variable=3 is not implemented\n 0 400 400   @variable\n 1 400 400   \n 0 400 400   # systemvariable=4\n 0 400 400   @@systemvariable\n 1 400 400   \n 0 400 400   # knownsystemvariable=5\n 0 400 400   @@known\n 1 400 400   \n 0 400 400   # number=6\n 0 400 400   6\n 1 400 400   \n 0 400 400   # majorkeyword=7\n 0 400 400   select\n 1 400 400   \n 0 400 400   # keyword=8\n 0 400 400   in\n 1 400 400   \n 0 400 400   # databaseobject=9\n 0 400 400   object\n 1 400 400   \n 0 400 400   # procedurekeyword=10\n 0 400 400   procedure\n 1 400 400   \n 0 400 400   # string=11 is not implemented\n 1 400 400   \n 0 400 400   # sqstring=12\n 0 400 400   'string'\n 1 400 400   \n 0 400 400   # dqstring=13\n 0 400 400   \"string\"\n 1 400 400   \n 0 400 400   # operator=14\n 0 400 400   +\n 1 400 400   \n 0 400 400   # function=15\n 0 400 400   function()\n 1 400 400   \n 0 400 400   # identifier=16\n 0 400 400   identifier\n 1 400 400   \n 0 400 400   # quotedidentifier=17\n 0 400 400   `quoted`\n 1 400 400   \n 0 400 400   # user1=18\n 0 400 400   user1\n 1 400 400   \n 0 400 400   # user2=19\n 0 400 400   user2\n 1 400 400   \n 0 400 400   # user3=20\n 0 400 400   user3\n 1 400 400   \n 0 400 400   # hiddencommand=21\n 0 400 400   /*!*/\n 1 400 400   \n 0 400 400   # placeholder=22\n 0 400 400   <{placeholder>}\n 0 400   0   "
  },
  {
    "path": "test/examples/mysql/AllStyles.sql.styled",
    "content": "{2}-- Enumerate all styles: 0 to 22, except for 3 (variable) and 11 (string) which are not implemented\n-- Hidden commands with other states (ored with ox40) are also possible inside /*! ... */\n{0}\n{1}/* commentline=2 */{0}\n{2}# comment\n{0}\n{2}# default=0\n{0}\t{2}# w\n{0}\n{2}# comment=1\n{1}/* comment */{0}\n\n{2}# variable=3 is not implemented\n{14}@{16}variable{0}\n\n{2}# systemvariable=4\n{4}@@systemvariable{0}\n\n{2}# knownsystemvariable=5\n{5}@@known{0}\n\n{2}# number=6\n{6}6{0}\n\n{2}# majorkeyword=7\n{7}select{0}\n\n{2}# keyword=8\n{8}in{0}\n\n{2}# databaseobject=9\n{9}object{0}\n\n{2}# procedurekeyword=10\n{10}procedure{0}\n\n{2}# string=11 is not implemented\n{0}\n{2}# sqstring=12\n{12}'string'{0}\n\n{2}# dqstring=13\n{13}\"string\"{0}\n\n{2}# operator=14\n{14}+{0}\n\n{2}# function=15\n{15}function{14}(){0}\n\n{2}# identifier=16\n{16}identifier{0}\n\n{2}# quotedidentifier=17\n{17}`quoted`{0}\n\n{2}# user1=18\n{18}user1{0}\n\n{2}# user2=19\n{19}user2{0}\n\n{2}# user3=20\n{20}user3{0}\n\n{2}# hiddencommand=21\n{21}/*!*/{0}\n\n{2}# placeholder=22\n{22}<{placeholder>}\n"
  },
  {
    "path": "test/examples/mysql/SciTE.properties",
    "content": "lexer.*.sql=mysql\n\nkeywords.*.sql=select\nkeywords2.*.sql=in\nkeywords3.*.sql=object\nkeywords4.*.sql=function\nkeywords5.*.sql=known\nkeywords6.*.sql=procedure\nkeywords7.*.sql=user1\nkeywords8.*.sql=user2\nkeywords9.*.sql=user3\n\nlexer.sql.backticks.identifier=1\nlexer.sql.numbersign.comment=1\nlexer.sql.allow.dotted.word=1\n\nfold=1\nfold.compact=1\n"
  },
  {
    "path": "test/examples/nim/SciTE.properties",
    "content": "lexer.*.nim=nim\nkeywords.*.nim=else end if let proc\n"
  },
  {
    "path": "test/examples/nim/x.nim",
    "content": "# Tests for Nim\nlet s = \"foobar\"\n\n# Feature #1260\n{.ident.}\nstdin.readLine.split.map(parseInt).max.`$`.echo(\" is the maximum!\")\n\n# Feature #1261\n# IsFuncName(\"proc\") so style ticks as SCE_NIM_FUNCNAME:\nproc `$` (x: myDataType): string = ...\n# Style ticks as SCE_NIM_BACKTICKS:\nif `==`( `+`(3,4),7): echo \"True\"\n\n# Feature #1262\n# Standard raw string identifier:\nlet standardDoubleLitRawStr = R\"A raw string\\\"\nlet standardTripleLitRawStr = R\"\"\"A triple-double raw string\\\"\"\"\"\n# Style of 'customIdent' is determined by lexer.nim.raw.strings.highlight.ident. 16 if false, 6 or 10 if true\nlet customDoubleLitRawStr = customIdent\"A string\\\"\nlet customTripleLitRawStr = customIdent\"\"\"A triple-double raw string\\\"\"\"\"\n\n# Feature #1268\n10_000\n10__000\n10_\n1....5\n1.ident\n1._ident\n"
  },
  {
    "path": "test/examples/nim/x.nim.folded",
    "content": " 1   0   0   # Tests for Nim\n 0 400   0   let s = \"foobar\"\n 1 400   0   \n 1 400   0   # Feature #1260\n 0 400   0   {.ident.}\n 0 400   0   stdin.readLine.split.map(parseInt).max.`$`.echo(\" is the maximum!\")\n 1 400   0   \n 1 400   0   # Feature #1261\n 1 400   0   # IsFuncName(\"proc\") so style ticks as SCE_NIM_FUNCNAME:\n 0 400   0   proc `$` (x: myDataType): string = ...\n 1 400   0   # Style ticks as SCE_NIM_BACKTICKS:\n 0 400   0   if `==`( `+`(3,4),7): echo \"True\"\n 1 400   0   \n 1 400   0   # Feature #1262\n 1 400   0   # Standard raw string identifier:\n 0 400   0   let standardDoubleLitRawStr = R\"A raw string\\\"\n 0 400   0   let standardTripleLitRawStr = R\"\"\"A triple-double raw string\\\"\"\"\"\n 1 400   0   # Style of 'customIdent' is determined by lexer.nim.raw.strings.highlight.ident. 16 if false, 6 or 10 if true\n 0 400   0   let customDoubleLitRawStr = customIdent\"A string\\\"\n 0 400   0   let customTripleLitRawStr = customIdent\"\"\"A triple-double raw string\\\"\"\"\"\n 1 400   0   \n 1 400   0   # Feature #1268\n 0 400   0   10_000\n 0 400   0   10__000\n 0 400   0   10_\n 0 400   0   1....5\n 0 400   0   1.ident\n 0 400   0   1._ident\n 1 400   0   "
  },
  {
    "path": "test/examples/nim/x.nim.styled",
    "content": "{3}# Tests for Nim\n{8}let{0} {16}s{0} {15}={0} {6}\"foobar\"{0}\n\n{3}# Feature #1260\n{15}{.{16}ident{15}.}{0}\n{16}stdin{15}.{16}readLine{15}.{16}split{15}.{16}map{15}({16}parseInt{15}).{16}max{15}.{11}`$`{15}.{16}echo{15}({6}\" is the maximum!\"{15}){0}\n\n{3}# Feature #1261\n# IsFuncName(\"proc\") so style ticks as SCE_NIM_FUNCNAME:\n{8}proc{0} {12}`$`{0} {15}({16}x{15}:{0} {16}myDataType{15}):{0} {16}string{0} {15}={0} {15}...{0}\n{3}# Style ticks as SCE_NIM_BACKTICKS:\n{8}if{0} {11}`==`{15}({0} {11}`+`{15}({5}3{15},{5}4{15}),{5}7{15}):{0} {16}echo{0} {6}\"True\"{0}\n\n{3}# Feature #1262\n# Standard raw string identifier:\n{8}let{0} {16}standardDoubleLitRawStr{0} {15}={0} {6}R\"A raw string\\\"{0}\n{8}let{0} {16}standardTripleLitRawStr{0} {15}={0} {10}R\"\"\"A triple-double raw string\\\"\"\"\"{0}\n{3}# Style of 'customIdent' is determined by lexer.nim.raw.strings.highlight.ident. 16 if false, 6 or 10 if true\n{8}let{0} {16}customDoubleLitRawStr{0} {15}={0} {16}customIdent{6}\"A string\\\"{0}\n{8}let{0} {16}customTripleLitRawStr{0} {15}={0} {16}customIdent{10}\"\"\"A triple-double raw string\\\"\"\"\"{0}\n\n{3}# Feature #1268\n{5}10_000{0}\n{5}10{16}__000{0}\n{5}10{16}_{0}\n{5}1{15}....{5}5{0}\n{5}1{15}.{16}ident{0}\n{5}1{15}.{16}_ident{0}\n"
  },
  {
    "path": "test/examples/nix/AllStyles.nix",
    "content": "# coding:utf-8\n\n1 + 2\n\nlet\n x = 1;\n y = 2;\nin x + y\n\nlet x=1;y=2;in x+y\n\n{\n  string = \"hello\";\n  integer = 1;\n  float = 3.141;\n  bool = true;\n  null = null;\n  list = [ 1 \"two\" false ];\n  attribute-set = {\n    a = \"hello\";\n    b = 2;\n    c = 2.718;\n    d = false;\n  }; # comments are supported\n}\n\nrec {\n  one = 1;\n  two = one + 1;\n  three = two + 1;\n}\n\n{ one = 1; three = 3; two = 2; }\n\nlet\n  a = 1;\nin\na + a\n\nlet\n  b = a + 1;\n  a = 1;\nin\na + b\n\n{\n  a = let x = 1; in x;\n  b = x;\n}\n\nlet\n  attrset = { x = 1; };\nin\nattrset.x\n\nlet\n  attrset = { a = { b = { c = 1; }; }; };\nin\nattrset.a.b.c\n\n{ a.b.c = 1; }\n\nlet\n  a = {\n    x = 1;\n    y = 2;\n    z = 3;\n  };\nin\nwith a; [ x y z ]\n\nlet\n  x = 1;\n  y = 2;\nin\n{\n  inherit x y;\n}\n\nlet\n  a = { x = 1; y = 2; };\nin\n{\n  inherit (a) x y;\n}\n\nlet\n  inherit ({ x = 1; y = 2; }) x y;\nin [ x y ]\n\nlet\n  name = \"Nix${}\";\nin\n\"hello ${name}\"\n\ngraphviz = (import ../tools/graphics/graphviz) {\n  inherit fetchurl stdenv libpng libjpeg expat x11 yacc;\n  inherit (xorg) libXaw;\n};\n\nlet negate = x: !x;\n    concat = x: y: x + y;\nin if negate true then concat \"foo\" \"bar\" else \"\"\n\n# A number\n# Equals 1 + 1\n# asd\n\n/* /*\nBlock comments\ncan span multiple lines.\n*/ \"hello\"\n\"hello\"\n\n/* /* nope */ 1\n\nmap (concat \"foo\") [ \"bar\" \"bla\" \"abc\" ]\n\n{ localServer ? false\n, httpServer ? false\n, sslSupport ? false\n, pythonBindings ? false\n, javaSwigBindings ? false\n, javahlBindings ? false\n, stdenv, fetchurl\n, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null\n}:\n\nassert localServer -> db4 != null;\nassert httpServer -> httpd != null && httpd.expat == expat;\nassert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl);\nassert pythonBindings -> swig != null && swig.pythonSupport;\nassert javaSwigBindings -> swig != null && swig.javaSupport;\nassert javahlBindings -> j2sdk != null;\n\nstdenv.mkDerivation {\n  name = \"subversion-1.1.1\";\n  openssl = if sslSupport then openssl else null;\n}\n\nconfigureFlags = ''\n  -system-zlib -system-libpng -system-libjpeg\n  ${if openglSupport then ''-dlopen-opengl\n    -L${mesa}/lib -I${mesa}/include\n    -L${libXmu}/lib -I${libXmu}/include'' else \"\"}\n  ${if threadSupport then \"-thread\" else \"-no-thread\"}\n'';\n\nlet\n  a = \"no\";\n  a.b.c.d = \"foo\"\nin\n\"${a + \" ${a + \" ${a}\"}\"}\"\n\nlet\n  out = \"Nix\";\nin\n\"echo ${out} > $out\"\n\n<nixpkgs/lib>\n\n''\nmulti\n''${}\n'''\nline\n''\\n\nstring\n''\n\n''\n  one\n   two\n    three\n''\n\nx: x + 1\n\nx: y: x + y\n\n{ a, b }: a + b\n\n{ a, b ? 0 }: a + b\n\n{ a, b, ...}: a + b\n\nargs@{ a, b, ... }: a + b + args.c\n\n{ a, b, ... }@args: a + b + args.c\n\nlet\n  f = x: x + 1;\nin f\n\nlet\n  f = x: x + 1;\nin f 1\n\nlet\n  f = x: x.a;\n  v = { a = 1; };\nin\nf v\n\n(x: x + 1) 1\n\nlet\n f = x: x + 1;\n a = 1;\nin [ (f a) ]\n\nlet\n f = x: x + 1;\n a = 1;\nin [ f a ]\n\nlet\n  f = x: y: x + y;\nin\nf 1 2\n\n{a, b}: a + b\n\nlet\n  f = {a, b}: a + b;\nin\nf { a = 1; b = 2; }\n\nlet\n  f = {a, b}: a + b;\nin\nf { a = 1; b = 2; c = 3; }\n\nlet\n  f = {a, b ? 0}: a + b;\nin\nf { a = 1; }\n\nlet\n  f = {a ? 0, b ? 0}: a + b;\nin\nf { } # empty attribute set\n\nlet\n  f = {a, b, ...}: a + b;\nin\nf { a = 1; b = 2; c = 3; }\n\n{a, b, ...}@args: a + b + args.c\n\nargs@{a, b, ...}: a + b + args.c\n\nlet\n  f = {a, b, ...}@args: a + b + args.c;\nin\nf { a = 1; b = 2; c = 3; }\n\n{ pkgs ? import <nixpkgs> {} }:\nlet\n  message = \"hello world\";\nin\npkgs.mkShellNoCC {\n  packages = with pkgs; [ cowsay ];\n  shellHook = ''\n    cowsay ${message}\n  '';\n}\n\n{ config, pkgs, ... }: {\n\n  imports = [ ./hardware-configuration.nix ];\n\n  environment.systemPackages = with pkgs; [ git ];\n\n  # ...\n}\n\n{ lib, stdenv, fetchurl }:\n\nstdenv.mkDerivation rec {\n\n  pname = \"hello\";\n\n  version = \"2.12\";\n\n  src = fetchurl {\n    url = \"mirror://gnu/${pname}/${pname}-${version}.tar.gz\";\n    sha256 = \"1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g\";\n  };\n\n  meta = with lib; {\n    license = licenses.gpl3Plus;\n  };\n\n}\n\n{\n  baseName = baseNameOf name;\n\n  pullImage =\n    let\n      fixName = name: builtins.replaceStrings [ \"/\" \":\" ] [ \"-\" \"-\" ] name;\n    in\n    { imageName\n      # To find the digest of an image, you can use skopeo:\n      # see doc/functions.xml\n    , imageDigest\n    , sha256\n    , os ? \"linux\"\n    , # Image architecture, defaults to the architecture of the `hostPlatform` when unset\n      arch ? defaultArchitecture\n      # This is used to set name to the pulled image\n    , finalImageName ? imageName\n      # This used to set a tag to the pulled image\n    , finalImageTag ? \"latest\"\n      # This is used to disable TLS certificate verification, allowing access to http registries on (hopefully) trusted networks\n    , tlsVerify ? true\n\n    , name ? fixName \"docker-image-${finalImageName}-${finalImageTag}.tar\"\n    }:\n\n    runCommand name\n      {\n        inherit imageDigest;\n        imageName = finalImageName;\n        imageTag = finalImageTag;\n        impureEnvVars = lib.fetchers.proxyImpureEnvVars;\n        outputHashMode = \"flat\";\n        outputHashAlgo = \"sha256\";\n        outputHash = sha256;\n\n        nativeBuildInputs = [ skopeo ];\n        SSL_CERT_FILE = \"${cacert.out}/etc/ssl/certs/ca-bundle.crt\";\n\n        sourceURL = \"docker://${imageName}@${imageDigest}\";\n        destNameTag = \"${finalImageName}:${finalImageTag}\";\n      } ''\n      skopeo \\\n        --insecure-policy \\\n        --tmpdir=$TMPDIR \\\n        --override-os ${os} \\\n        --override-arch ${arch} \\\n        copy \\\n        --src-tls-verify=${lib.boolToString tlsVerify} \\\n        \"$sourceURL\" \"docker-archive://$out:$destNameTag\" \\\n        | cat  # pipe through cat to force-disable progress bar\n    '';\n\n}\n\nmessage = \"unterminated string;\nmessage2 = \"unterminated string;\n"
  },
  {
    "path": "test/examples/nix/AllStyles.nix.folded",
    "content": " 0 400 400   # coding:utf-8\n 0 400 400   \n 0 400 400   1 + 2\n 0 400 400   \n 0 400 400   let\n 0 400 400    x = 1;\n 0 400 400    y = 2;\n 0 400 400   in x + y\n 0 400 400   \n 0 400 400   let x=1;y=2;in x+y\n 0 400 400   \n 2 400 401 + {\n 0 401 401 |   string = \"hello\";\n 0 401 401 |   integer = 1;\n 0 401 401 |   float = 3.141;\n 0 401 401 |   bool = true;\n 0 401 401 |   null = null;\n 0 401 401 |   list = [ 1 \"two\" false ];\n 2 401 402 +   attribute-set = {\n 0 402 402 |     a = \"hello\";\n 0 402 402 |     b = 2;\n 0 402 402 |     c = 2.718;\n 0 402 402 |     d = false;\n 0 402 401 |   }; # comments are supported\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + rec {\n 0 401 401 |   one = 1;\n 0 401 401 |   two = one + 1;\n 0 401 401 |   three = two + 1;\n 0 401 400 | }\n 0 400 400   \n 0 400 400   { one = 1; three = 3; two = 2; }\n 0 400 400   \n 0 400 400   let\n 0 400 400     a = 1;\n 0 400 400   in\n 0 400 400   a + a\n 0 400 400   \n 0 400 400   let\n 0 400 400     b = a + 1;\n 0 400 400     a = 1;\n 0 400 400   in\n 0 400 400   a + b\n 0 400 400   \n 2 400 401 + {\n 0 401 401 |   a = let x = 1; in x;\n 0 401 401 |   b = x;\n 0 401 400 | }\n 0 400 400   \n 0 400 400   let\n 0 400 400     attrset = { x = 1; };\n 0 400 400   in\n 0 400 400   attrset.x\n 0 400 400   \n 0 400 400   let\n 0 400 400     attrset = { a = { b = { c = 1; }; }; };\n 0 400 400   in\n 0 400 400   attrset.a.b.c\n 0 400 400   \n 0 400 400   { a.b.c = 1; }\n 0 400 400   \n 0 400 400   let\n 2 400 401 +   a = {\n 0 401 401 |     x = 1;\n 0 401 401 |     y = 2;\n 0 401 401 |     z = 3;\n 0 401 400 |   };\n 0 400 400   in\n 0 400 400   with a; [ x y z ]\n 0 400 400   \n 0 400 400   let\n 0 400 400     x = 1;\n 0 400 400     y = 2;\n 0 400 400   in\n 2 400 401 + {\n 0 401 401 |   inherit x y;\n 0 401 400 | }\n 0 400 400   \n 0 400 400   let\n 0 400 400     a = { x = 1; y = 2; };\n 0 400 400   in\n 2 400 401 + {\n 0 401 401 |   inherit (a) x y;\n 0 401 400 | }\n 0 400 400   \n 0 400 400   let\n 0 400 400     inherit ({ x = 1; y = 2; }) x y;\n 0 400 400   in [ x y ]\n 0 400 400   \n 0 400 400   let\n 0 400 400     name = \"Nix${}\";\n 0 400 400   in\n 0 400 400   \"hello ${name}\"\n 0 400 400   \n 2 400 401 + graphviz = (import ../tools/graphics/graphviz) {\n 0 401 401 |   inherit fetchurl stdenv libpng libjpeg expat x11 yacc;\n 0 401 401 |   inherit (xorg) libXaw;\n 0 401 400 | };\n 0 400 400   \n 0 400 400   let negate = x: !x;\n 0 400 400       concat = x: y: x + y;\n 0 400 400   in if negate true then concat \"foo\" \"bar\" else \"\"\n 0 400 400   \n 0 400 400   # A number\n 0 400 400   # Equals 1 + 1\n 0 400 400   # asd\n 0 400 400   \n 2 400 401 + /* /*\n 0 401 401 | Block comments\n 0 401 401 | can span multiple lines.\n 0 401 400 | */ \"hello\"\n 0 400 400   \"hello\"\n 0 400 400   \n 0 400 400   /* /* nope */ 1\n 0 400 400   \n 0 400 400   map (concat \"foo\") [ \"bar\" \"bla\" \"abc\" ]\n 0 400 400   \n 2 400 401 + { localServer ? false\n 0 401 401 | , httpServer ? false\n 0 401 401 | , sslSupport ? false\n 0 401 401 | , pythonBindings ? false\n 0 401 401 | , javaSwigBindings ? false\n 0 401 401 | , javahlBindings ? false\n 0 401 401 | , stdenv, fetchurl\n 0 401 401 | , openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null\n 0 401 400 | }:\n 0 400 400   \n 0 400 400   assert localServer -> db4 != null;\n 0 400 400   assert httpServer -> httpd != null && httpd.expat == expat;\n 0 400 400   assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl);\n 0 400 400   assert pythonBindings -> swig != null && swig.pythonSupport;\n 0 400 400   assert javaSwigBindings -> swig != null && swig.javaSupport;\n 0 400 400   assert javahlBindings -> j2sdk != null;\n 0 400 400   \n 2 400 401 + stdenv.mkDerivation {\n 0 401 401 |   name = \"subversion-1.1.1\";\n 0 401 401 |   openssl = if sslSupport then openssl else null;\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + configureFlags = ''\n 0 401 401 |   -system-zlib -system-libpng -system-libjpeg\n 2 401 403 +   ${if openglSupport then ''-dlopen-opengl\n 0 403 403 |     -L${mesa}/lib -I${mesa}/include\n 0 403 401 |     -L${libXmu}/lib -I${libXmu}/include'' else \"\"}\n 0 401 401 |   ${if threadSupport then \"-thread\" else \"-no-thread\"}\n 0 401 400 | '';\n 0 400 400   \n 0 400 400   let\n 0 400 400     a = \"no\";\n 0 400 400     a.b.c.d = \"foo\"\n 0 400 400   in\n 0 400 400   \"${a + \" ${a + \" ${a}\"}\"}\"\n 0 400 400   \n 0 400 400   let\n 0 400 400     out = \"Nix\";\n 0 400 400   in\n 0 400 400   \"echo ${out} > $out\"\n 0 400 400   \n 0 400 400   <nixpkgs/lib>\n 0 400 400   \n 2 400 401 + ''\n 0 401 401 | multi\n 0 401 401 | ''${}\n 0 401 401 | '''\n 0 401 401 | line\n 0 401 401 | ''\\n\n 0 401 401 | string\n 0 401 400 | ''\n 0 400 400   \n 2 400 401 + ''\n 0 401 401 |   one\n 0 401 401 |    two\n 0 401 401 |     three\n 0 401 400 | ''\n 0 400 400   \n 0 400 400   x: x + 1\n 0 400 400   \n 0 400 400   x: y: x + y\n 0 400 400   \n 0 400 400   { a, b }: a + b\n 0 400 400   \n 0 400 400   { a, b ? 0 }: a + b\n 0 400 400   \n 0 400 400   { a, b, ...}: a + b\n 0 400 400   \n 0 400 400   args@{ a, b, ... }: a + b + args.c\n 0 400 400   \n 0 400 400   { a, b, ... }@args: a + b + args.c\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = x: x + 1;\n 0 400 400   in f\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = x: x + 1;\n 0 400 400   in f 1\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = x: x.a;\n 0 400 400     v = { a = 1; };\n 0 400 400   in\n 0 400 400   f v\n 0 400 400   \n 0 400 400   (x: x + 1) 1\n 0 400 400   \n 0 400 400   let\n 0 400 400    f = x: x + 1;\n 0 400 400    a = 1;\n 0 400 400   in [ (f a) ]\n 0 400 400   \n 0 400 400   let\n 0 400 400    f = x: x + 1;\n 0 400 400    a = 1;\n 0 400 400   in [ f a ]\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = x: y: x + y;\n 0 400 400   in\n 0 400 400   f 1 2\n 0 400 400   \n 0 400 400   {a, b}: a + b\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = {a, b}: a + b;\n 0 400 400   in\n 0 400 400   f { a = 1; b = 2; }\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = {a, b}: a + b;\n 0 400 400   in\n 0 400 400   f { a = 1; b = 2; c = 3; }\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = {a, b ? 0}: a + b;\n 0 400 400   in\n 0 400 400   f { a = 1; }\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = {a ? 0, b ? 0}: a + b;\n 0 400 400   in\n 0 400 400   f { } # empty attribute set\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = {a, b, ...}: a + b;\n 0 400 400   in\n 0 400 400   f { a = 1; b = 2; c = 3; }\n 0 400 400   \n 0 400 400   {a, b, ...}@args: a + b + args.c\n 0 400 400   \n 0 400 400   args@{a, b, ...}: a + b + args.c\n 0 400 400   \n 0 400 400   let\n 0 400 400     f = {a, b, ...}@args: a + b + args.c;\n 0 400 400   in\n 0 400 400   f { a = 1; b = 2; c = 3; }\n 0 400 400   \n 0 400 400   { pkgs ? import <nixpkgs> {} }:\n 0 400 400   let\n 0 400 400     message = \"hello world\";\n 0 400 400   in\n 2 400 401 + pkgs.mkShellNoCC {\n 0 401 401 |   packages = with pkgs; [ cowsay ];\n 2 401 402 +   shellHook = ''\n 0 402 402 |     cowsay ${message}\n 0 402 401 |   '';\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + { config, pkgs, ... }: {\n 0 401 401 | \n 0 401 401 |   imports = [ ./hardware-configuration.nix ];\n 0 401 401 | \n 0 401 401 |   environment.systemPackages = with pkgs; [ git ];\n 0 401 401 | \n 0 401 401 |   # ...\n 0 401 400 | }\n 0 400 400   \n 0 400 400   { lib, stdenv, fetchurl }:\n 0 400 400   \n 2 400 401 + stdenv.mkDerivation rec {\n 0 401 401 | \n 0 401 401 |   pname = \"hello\";\n 0 401 401 | \n 0 401 401 |   version = \"2.12\";\n 0 401 401 | \n 2 401 402 +   src = fetchurl {\n 0 402 402 |     url = \"mirror://gnu/${pname}/${pname}-${version}.tar.gz\";\n 0 402 402 |     sha256 = \"1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g\";\n 0 402 401 |   };\n 0 401 401 | \n 2 401 402 +   meta = with lib; {\n 0 402 402 |     license = licenses.gpl3Plus;\n 0 402 401 |   };\n 0 401 401 | \n 0 401 400 | }\n 0 400 400   \n 2 400 401 + {\n 0 401 401 |   baseName = baseNameOf name;\n 0 401 401 | \n 0 401 401 |   pullImage =\n 0 401 401 |     let\n 0 401 401 |       fixName = name: builtins.replaceStrings [ \"/\" \":\" ] [ \"-\" \"-\" ] name;\n 0 401 401 |     in\n 2 401 402 +     { imageName\n 0 402 402 |       # To find the digest of an image, you can use skopeo:\n 0 402 402 |       # see doc/functions.xml\n 0 402 402 |     , imageDigest\n 0 402 402 |     , sha256\n 0 402 402 |     , os ? \"linux\"\n 0 402 402 |     , # Image architecture, defaults to the architecture of the `hostPlatform` when unset\n 0 402 402 |       arch ? defaultArchitecture\n 0 402 402 |       # This is used to set name to the pulled image\n 0 402 402 |     , finalImageName ? imageName\n 0 402 402 |       # This used to set a tag to the pulled image\n 0 402 402 |     , finalImageTag ? \"latest\"\n 0 402 402 |       # This is used to disable TLS certificate verification, allowing access to http registries on (hopefully) trusted networks\n 0 402 402 |     , tlsVerify ? true\n 0 402 402 | \n 0 402 402 |     , name ? fixName \"docker-image-${finalImageName}-${finalImageTag}.tar\"\n 0 402 401 |     }:\n 0 401 401 | \n 0 401 401 |     runCommand name\n 2 401 402 +       {\n 0 402 402 |         inherit imageDigest;\n 0 402 402 |         imageName = finalImageName;\n 0 402 402 |         imageTag = finalImageTag;\n 0 402 402 |         impureEnvVars = lib.fetchers.proxyImpureEnvVars;\n 0 402 402 |         outputHashMode = \"flat\";\n 0 402 402 |         outputHashAlgo = \"sha256\";\n 0 402 402 |         outputHash = sha256;\n 0 402 402 | \n 0 402 402 |         nativeBuildInputs = [ skopeo ];\n 0 402 402 |         SSL_CERT_FILE = \"${cacert.out}/etc/ssl/certs/ca-bundle.crt\";\n 0 402 402 | \n 0 402 402 |         sourceURL = \"docker://${imageName}@${imageDigest}\";\n 0 402 402 |         destNameTag = \"${finalImageName}:${finalImageTag}\";\n 0 402 402 |       } ''\n 0 402 402 |       skopeo \\\n 0 402 402 |         --insecure-policy \\\n 0 402 402 |         --tmpdir=$TMPDIR \\\n 0 402 402 |         --override-os ${os} \\\n 0 402 402 |         --override-arch ${arch} \\\n 0 402 402 |         copy \\\n 0 402 402 |         --src-tls-verify=${lib.boolToString tlsVerify} \\\n 0 402 402 |         \"$sourceURL\" \"docker-archive://$out:$destNameTag\" \\\n 0 402 402 |         | cat  # pipe through cat to force-disable progress bar\n 0 402 401 |     '';\n 0 401 401 | \n 0 401 400 | }\n 0 400 400   \n 0 400 400   message = \"unterminated string;\n 0 400 400   message2 = \"unterminated string;\n 0 400   0   "
  },
  {
    "path": "test/examples/nix/AllStyles.nix.styled",
    "content": "{1}# coding:utf-8\n{0}\n{9}1{0} {7}+{0} {9}2{0}\n\n{12}let{0}\n {10}x{0} {7}={0} {9}1{7};{0}\n {10}y{0} {7}={0} {9}2{7};{0}\n{12}in{0} {6}x{0} {7}+{0} {6}y{0}\n\n{12}let{0} {10}x{7}={9}1{7};{10}y{7}={9}2{7};{12}in{0} {6}x{7}+{6}y{0}\n\n{7}{{0}\n  {10}string{0} {7}={0} {3}\"hello\"{7};{0}\n  {10}integer{0} {7}={0} {9}1{7};{0}\n  {10}float{0} {7}={0} {9}3.141{7};{0}\n  {10}bool{0} {7}={0} {13}true{7};{0}\n  {10}null{0} {7}={0} {13}null{7};{0}\n  {10}list{0} {7}={0} {7}[{0} {9}1{0} {3}\"two\"{0} {13}false{0} {7}];{0}\n  {10}attribute-set{0} {7}={0} {7}{{0}\n    {10}a{0} {7}={0} {3}\"hello\"{7};{0}\n    {10}b{0} {7}={0} {9}2{7};{0}\n    {10}c{0} {7}={0} {9}2.718{7};{0}\n    {10}d{0} {7}={0} {13}false{7};{0}\n  {7}};{0} {1}# comments are supported\n{7}}{0}\n\n{12}rec{0} {7}{{0}\n  {10}one{0} {7}={0} {9}1{7};{0}\n  {10}two{0} {7}={0} {6}one{0} {7}+{0} {9}1{7};{0}\n  {10}three{0} {7}={0} {6}two{0} {7}+{0} {9}1{7};{0}\n{7}}{0}\n\n{7}{{0} {10}one{0} {7}={0} {9}1{7};{0} {10}three{0} {7}={0} {9}3{7};{0} {10}two{0} {7}={0} {9}2{7};{0} {7}}{0}\n\n{12}let{0}\n  {10}a{0} {7}={0} {9}1{7};{0}\n{12}in{0}\n{6}a{0} {7}+{0} {6}a{0}\n\n{12}let{0}\n  {10}b{0} {7}={0} {6}a{0} {7}+{0} {9}1{7};{0}\n  {10}a{0} {7}={0} {9}1{7};{0}\n{12}in{0}\n{6}a{0} {7}+{0} {6}b{0}\n\n{7}{{0}\n  {10}a{0} {7}={0} {12}let{0} {10}x{0} {7}={0} {9}1{7};{0} {12}in{0} {6}x{7};{0}\n  {10}b{0} {7}={0} {6}x{7};{0}\n{7}}{0}\n\n{12}let{0}\n  {10}attrset{0} {7}={0} {7}{{0} {10}x{0} {7}={0} {9}1{7};{0} {7}};{0}\n{12}in{0}\n{6}attrset{7}.{6}x{0}\n\n{12}let{0}\n  {10}attrset{0} {7}={0} {7}{{0} {10}a{0} {7}={0} {7}{{0} {10}b{0} {7}={0} {7}{{0} {10}c{0} {7}={0} {9}1{7};{0} {7}};{0} {7}};{0} {7}};{0}\n{12}in{0}\n{6}attrset{7}.{6}a{7}.{6}b{7}.{6}c{0}\n\n{7}{{0} {6}a{7}.{6}b{7}.{10}c{0} {7}={0} {9}1{7};{0} {7}}{0}\n\n{12}let{0}\n  {10}a{0} {7}={0} {7}{{0}\n    {10}x{0} {7}={0} {9}1{7};{0}\n    {10}y{0} {7}={0} {9}2{7};{0}\n    {10}z{0} {7}={0} {9}3{7};{0}\n  {7}};{0}\n{12}in{0}\n{12}with{0} {6}a{7};{0} {7}[{0} {6}x{0} {6}y{0} {6}z{0} {7}]{0}\n\n{12}let{0}\n  {10}x{0} {7}={0} {9}1{7};{0}\n  {10}y{0} {7}={0} {9}2{7};{0}\n{12}in{0}\n{7}{{0}\n  {12}inherit{0} {6}x{0} {6}y{7};{0}\n{7}}{0}\n\n{12}let{0}\n  {10}a{0} {7}={0} {7}{{0} {10}x{0} {7}={0} {9}1{7};{0} {10}y{0} {7}={0} {9}2{7};{0} {7}};{0}\n{12}in{0}\n{7}{{0}\n  {12}inherit{0} {7}({6}a{7}){0} {6}x{0} {6}y{7};{0}\n{7}}{0}\n\n{12}let{0}\n  {12}inherit{0} {7}({{0} {10}x{0} {7}={0} {9}1{7};{0} {10}y{0} {7}={0} {9}2{7};{0} {7}}){0} {6}x{0} {6}y{7};{0}\n{12}in{0} {7}[{0} {6}x{0} {6}y{0} {7}]{0}\n\n{12}let{0}\n  {10}name{0} {7}={0} {3}\"Nix{8}${}{3}\"{7};{0}\n{12}in{0}\n{3}\"hello {8}${{6}name{8}}{3}\"{0}\n\n{10}graphviz{0} {7}={0} {7}({14}import{0} {11}../tools/graphics/graphviz{7}){0} {7}{{0}\n  {12}inherit{0} {14}fetchurl{0} {6}stdenv{0} {6}libpng{0} {6}libjpeg{0} {6}expat{0} {6}x11{0} {6}yacc{7};{0}\n  {12}inherit{0} {7}({6}xorg{7}){0} {6}libXaw{7};{0}\n{7}};{0}\n\n{12}let{0} {10}negate{0} {7}={0} {6}x{7}:{0} {7}!{6}x{7};{0}\n    {10}concat{0} {7}={0} {6}x{7}:{0} {6}y{7}:{0} {6}x{0} {7}+{0} {6}y{7};{0}\n{12}in{0} {12}if{0} {6}negate{0} {13}true{0} {12}then{0} {6}concat{0} {3}\"foo\"{0} {3}\"bar\"{0} {12}else{0} {3}\"\"{0}\n\n{1}# A number\n# Equals 1 + 1\n# asd\n{0}\n{2}/* /*\nBlock comments\ncan span multiple lines.\n*/{0} {3}\"hello\"{0}\n{3}\"hello\"{0}\n\n{2}/* /* nope */{0} {9}1{0}\n\n{14}map{0} {7}({6}concat{0} {3}\"foo\"{7}){0} {7}[{0} {3}\"bar\"{0} {3}\"bla\"{0} {3}\"abc\"{0} {7}]{0}\n\n{7}{{0} {6}localServer{0} {7}?{0} {13}false{0}\n{7},{0} {6}httpServer{0} {7}?{0} {13}false{0}\n{7},{0} {6}sslSupport{0} {7}?{0} {13}false{0}\n{7},{0} {6}pythonBindings{0} {7}?{0} {13}false{0}\n{7},{0} {6}javaSwigBindings{0} {7}?{0} {13}false{0}\n{7},{0} {6}javahlBindings{0} {7}?{0} {13}false{0}\n{7},{0} {6}stdenv{7},{0} {14}fetchurl{0}\n{7},{0} {6}openssl{0} {7}?{0} {13}null{7},{0} {6}httpd{0} {7}?{0} {13}null{7},{0} {6}db4{0} {7}?{0} {13}null{7},{0} {6}expat{7},{0} {6}swig{0} {7}?{0} {13}null{7},{0} {6}j2sdk{0} {7}?{0} {13}null{0}\n{7}}:{0}\n\n{12}assert{0} {6}localServer{0} {7}->{0} {6}db4{0} {7}!={0} {13}null{7};{0}\n{12}assert{0} {6}httpServer{0} {7}->{0} {6}httpd{0} {7}!={0} {13}null{0} {7}&&{0} {6}httpd{7}.{10}expat{0} {7}=={0} {6}expat{7};{0}\n{12}assert{0} {6}sslSupport{0} {7}->{0} {6}openssl{0} {7}!={0} {13}null{0} {7}&&{0} {7}({6}httpServer{0} {7}->{0} {6}httpd{7}.{10}openssl{0} {7}=={0} {6}openssl{7});{0}\n{12}assert{0} {6}pythonBindings{0} {7}->{0} {6}swig{0} {7}!={0} {13}null{0} {7}&&{0} {6}swig{7}.{6}pythonSupport{7};{0}\n{12}assert{0} {6}javaSwigBindings{0} {7}->{0} {6}swig{0} {7}!={0} {13}null{0} {7}&&{0} {6}swig{7}.{6}javaSupport{7};{0}\n{12}assert{0} {6}javahlBindings{0} {7}->{0} {6}j2sdk{0} {7}!={0} {13}null{7};{0}\n\n{6}stdenv{7}.{6}mkDerivation{0} {7}{{0}\n  {10}name{0} {7}={0} {3}\"subversion-1.1.1\"{7};{0}\n  {10}openssl{0} {7}={0} {12}if{0} {6}sslSupport{0} {12}then{0} {6}openssl{0} {12}else{0} {13}null{7};{0}\n{7}}{0}\n\n{10}configureFlags{0} {7}={0} {4}''\n  -system-zlib -system-libpng -system-libjpeg\n  {8}${{12}if{0} {6}openglSupport{0} {12}then{0} {4}''-dlopen-opengl\n    -L{8}${{6}mesa{8}}{4}/lib -I{8}${{6}mesa{8}}{4}/include\n    -L{8}${{6}libXmu{8}}{4}/lib -I{8}${{6}libXmu{8}}{4}/include''{0} {12}else{0} {3}\"\"{8}}{4}\n  {8}${{12}if{0} {6}threadSupport{0} {12}then{0} {3}\"-thread\"{0} {12}else{0} {3}\"-no-thread\"{8}}{4}\n''{7};{0}\n\n{12}let{0}\n  {10}a{0} {7}={0} {3}\"no\"{7};{0}\n  {6}a{7}.{6}b{7}.{6}c{7}.{10}d{0} {7}={0} {3}\"foo\"{0}\n{12}in{0}\n{3}\"{8}${{6}a{0} {7}+{0} {3}\" {8}${{6}a{0} {7}+{0} {3}\" {8}${{6}a{8}}{3}\"{8}}{3}\"{8}}{3}\"{0}\n\n{12}let{0}\n  {10}out{0} {7}={0} {3}\"Nix\"{7};{0}\n{12}in{0}\n{3}\"echo {8}${{6}out{8}}{3} > $out\"{0}\n\n{11}<nixpkgs/lib>{0}\n\n{4}''\nmulti\n{5}''${4}{}\n{5}'''{4}\nline\n{5}''\\n{4}\nstring\n''{0}\n\n{4}''\n  one\n   two\n    three\n''{0}\n\n{6}x{7}:{0} {6}x{0} {7}+{0} {9}1{0}\n\n{6}x{7}:{0} {6}y{7}:{0} {6}x{0} {7}+{0} {6}y{0}\n\n{7}{{0} {6}a{7},{0} {6}b{0} {7}}:{0} {6}a{0} {7}+{0} {6}b{0}\n\n{7}{{0} {6}a{7},{0} {6}b{0} {7}?{0} {9}0{0} {7}}:{0} {6}a{0} {7}+{0} {6}b{0}\n\n{7}{{0} {6}a{7},{0} {6}b{7},{0} {7}...}:{0} {6}a{0} {7}+{0} {6}b{0}\n\n{6}args{7}@{{0} {6}a{7},{0} {6}b{7},{0} {7}...{0} {7}}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{0}\n\n{7}{{0} {6}a{7},{0} {6}b{7},{0} {7}...{0} {7}}@{6}args{7}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{0}\n\n{12}let{0}\n  {10}f{0} {7}={0} {6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7};{0}\n{12}in{0} {6}f{0}\n\n{12}let{0}\n  {10}f{0} {7}={0} {6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7};{0}\n{12}in{0} {6}f{0} {9}1{0}\n\n{12}let{0}\n  {10}f{0} {7}={0} {6}x{7}:{0} {6}x{7}.{6}a{7};{0}\n  {10}v{0} {7}={0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {7}};{0}\n{12}in{0}\n{6}f{0} {6}v{0}\n\n{7}({6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7}){0} {9}1{0}\n\n{12}let{0}\n {10}f{0} {7}={0} {6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7};{0}\n {10}a{0} {7}={0} {9}1{7};{0}\n{12}in{0} {7}[{0} {7}({6}f{0} {6}a{7}){0} {7}]{0}\n\n{12}let{0}\n {10}f{0} {7}={0} {6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7};{0}\n {10}a{0} {7}={0} {9}1{7};{0}\n{12}in{0} {7}[{0} {6}f{0} {6}a{0} {7}]{0}\n\n{12}let{0}\n  {10}f{0} {7}={0} {6}x{7}:{0} {6}y{7}:{0} {6}x{0} {7}+{0} {6}y{7};{0}\n{12}in{0}\n{6}f{0} {9}1{0} {9}2{0}\n\n{7}{{6}a{7},{0} {6}b{7}}:{0} {6}a{0} {7}+{0} {6}b{0}\n\n{12}let{0}\n  {10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{7}}:{0} {6}a{0} {7}+{0} {6}b{7};{0}\n{12}in{0}\n{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {10}b{0} {7}={0} {9}2{7};{0} {7}}{0}\n\n{12}let{0}\n  {10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{7}}:{0} {6}a{0} {7}+{0} {6}b{7};{0}\n{12}in{0}\n{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {10}b{0} {7}={0} {9}2{7};{0} {10}c{0} {7}={0} {9}3{7};{0} {7}}{0}\n\n{12}let{0}\n  {10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{0} {7}?{0} {9}0{7}}:{0} {6}a{0} {7}+{0} {6}b{7};{0}\n{12}in{0}\n{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {7}}{0}\n\n{12}let{0}\n  {10}f{0} {7}={0} {7}{{6}a{0} {7}?{0} {9}0{7},{0} {6}b{0} {7}?{0} {9}0{7}}:{0} {6}a{0} {7}+{0} {6}b{7};{0}\n{12}in{0}\n{6}f{0} {7}{{0} {7}}{0} {1}# empty attribute set\n{0}\n{12}let{0}\n  {10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{7},{0} {7}...}:{0} {6}a{0} {7}+{0} {6}b{7};{0}\n{12}in{0}\n{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {10}b{0} {7}={0} {9}2{7};{0} {10}c{0} {7}={0} {9}3{7};{0} {7}}{0}\n\n{7}{{6}a{7},{0} {6}b{7},{0} {7}...}@{6}args{7}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{0}\n\n{6}args{7}@{{6}a{7},{0} {6}b{7},{0} {7}...}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{0}\n\n{12}let{0}\n  {10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{7},{0} {7}...}@{6}args{7}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{7};{0}\n{12}in{0}\n{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {10}b{0} {7}={0} {9}2{7};{0} {10}c{0} {7}={0} {9}3{7};{0} {7}}{0}\n\n{7}{{0} {6}pkgs{0} {7}?{0} {14}import{0} {11}<nixpkgs>{0} {7}{}{0} {7}}:{0}\n{12}let{0}\n  {10}message{0} {7}={0} {3}\"hello world\"{7};{0}\n{12}in{0}\n{6}pkgs{7}.{6}mkShellNoCC{0} {7}{{0}\n  {10}packages{0} {7}={0} {12}with{0} {6}pkgs{7};{0} {7}[{0} {6}cowsay{0} {7}];{0}\n  {10}shellHook{0} {7}={0} {4}''\n    cowsay {8}${{6}message{8}}{4}\n  ''{7};{0}\n{7}}{0}\n\n{7}{{0} {6}config{7},{0} {6}pkgs{7},{0} {7}...{0} {7}}:{0} {7}{{0}\n\n  {10}imports{0} {7}={0} {7}[{0} {11}./hardware-configuration.nix{0} {7}];{0}\n\n  {6}environment{7}.{10}systemPackages{0} {7}={0} {12}with{0} {6}pkgs{7};{0} {7}[{0} {6}git{0} {7}];{0}\n\n  {1}# ...\n{7}}{0}\n\n{7}{{0} {6}lib{7},{0} {6}stdenv{7},{0} {14}fetchurl{0} {7}}:{0}\n\n{6}stdenv{7}.{6}mkDerivation{0} {12}rec{0} {7}{{0}\n\n  {10}pname{0} {7}={0} {3}\"hello\"{7};{0}\n\n  {10}version{0} {7}={0} {3}\"2.12\"{7};{0}\n\n  {10}src{0} {7}={0} {14}fetchurl{0} {7}{{0}\n    {10}url{0} {7}={0} {3}\"mirror://gnu/{8}${{6}pname{8}}{3}/{8}${{6}pname{8}}{3}-{8}${{6}version{8}}{3}.tar.gz\"{7};{0}\n    {10}sha256{0} {7}={0} {3}\"1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g\"{7};{0}\n  {7}};{0}\n\n  {10}meta{0} {7}={0} {12}with{0} {6}lib{7};{0} {7}{{0}\n    {10}license{0} {7}={0} {6}licenses{7}.{6}gpl3Plus{7};{0}\n  {7}};{0}\n\n{7}}{0}\n\n{7}{{0}\n  {10}baseName{0} {7}={0} {14}baseNameOf{0} {6}name{7};{0}\n\n  {10}pullImage{0} {7}={0}\n    {12}let{0}\n      {10}fixName{0} {7}={0} {6}name{7}:{0} {14}builtins{7}.{14}replaceStrings{0} {7}[{0} {3}\"/\"{0} {3}\":\"{0} {7}]{0} {7}[{0} {3}\"-\"{0} {3}\"-\"{0} {7}]{0} {6}name{7};{0}\n    {12}in{0}\n    {7}{{0} {6}imageName{0}\n      {1}# To find the digest of an image, you can use skopeo:\n{0}      {1}# see doc/functions.xml\n{0}    {7},{0} {6}imageDigest{0}\n    {7},{0} {6}sha256{0}\n    {7},{0} {6}os{0} {7}?{0} {3}\"linux\"{0}\n    {7},{0} {1}# Image architecture, defaults to the architecture of the `hostPlatform` when unset\n{0}      {6}arch{0} {7}?{0} {6}defaultArchitecture{0}\n      {1}# This is used to set name to the pulled image\n{0}    {7},{0} {6}finalImageName{0} {7}?{0} {6}imageName{0}\n      {1}# This used to set a tag to the pulled image\n{0}    {7},{0} {6}finalImageTag{0} {7}?{0} {3}\"latest\"{0}\n      {1}# This is used to disable TLS certificate verification, allowing access to http registries on (hopefully) trusted networks\n{0}    {7},{0} {6}tlsVerify{0} {7}?{0} {13}true{0}\n\n    {7},{0} {6}name{0} {7}?{0} {6}fixName{0} {3}\"docker-image-{8}${{6}finalImageName{8}}{3}-{8}${{6}finalImageTag{8}}{3}.tar\"{0}\n    {7}}:{0}\n\n    {15}runCommand{0} {6}name{0}\n      {7}{{0}\n        {12}inherit{0} {6}imageDigest{7};{0}\n        {10}imageName{0} {7}={0} {6}finalImageName{7};{0}\n        {10}imageTag{0} {7}={0} {6}finalImageTag{7};{0}\n        {10}impureEnvVars{0} {7}={0} {6}lib{7}.{6}fetchers{7}.{6}proxyImpureEnvVars{7};{0}\n        {10}outputHashMode{0} {7}={0} {3}\"flat\"{7};{0}\n        {10}outputHashAlgo{0} {7}={0} {3}\"sha256\"{7};{0}\n        {10}outputHash{0} {7}={0} {6}sha256{7};{0}\n\n        {10}nativeBuildInputs{0} {7}={0} {7}[{0} {6}skopeo{0} {7}];{0}\n        {10}SSL_CERT_FILE{0} {7}={0} {3}\"{8}${{6}cacert{7}.{6}out{8}}{3}/etc/ssl/certs/ca-bundle.crt\"{7};{0}\n\n        {10}sourceURL{0} {7}={0} {3}\"docker://{8}${{6}imageName{8}}{3}@{8}${{6}imageDigest{8}}{3}\"{7};{0}\n        {10}destNameTag{0} {7}={0} {3}\"{8}${{6}finalImageName{8}}{3}:{8}${{6}finalImageTag{8}}{3}\"{7};{0}\n      {7}}{0} {4}''\n      skopeo \\\n        --insecure-policy \\\n        --tmpdir=$TMPDIR \\\n        --override-os {8}${{6}os{8}}{4} \\\n        --override-arch {8}${{6}arch{8}}{4} \\\n        copy \\\n        --src-tls-verify={8}${{6}lib{7}.{6}boolToString{0} {6}tlsVerify{8}}{4} \\\n        \"$sourceURL\" \"docker-archive://$out:$destNameTag\" \\\n        | cat  # pipe through cat to force-disable progress bar\n    ''{7};{0}\n\n{7}}{0}\n\n{10}message{0} {7}={0} {16}\"unterminated string;\n{10}message2{0} {7}={0} {16}\"unterminated string;\n"
  },
  {
    "path": "test/examples/nix/SciTE.properties",
    "content": "lexer.*.nix=nix\nfold=1\n\nkeywords.*.nix=assert else if in inherit let or rec then with\nkeywords2.*.nix=false null true\nkeywords3.*.nix=abort add addDrvOutputDependencies all any attrNames attrValues baseNameOf bitAnd bitOr bitXor break builtins catAttrs ceil compareVersions concatLists concatMap concatStringsSep convertHash currentSystem currentTime deepSeq derivation dirOf div elem elemAt fetchClosure fetchGit fetchTarball fetchTree fetchurl filter filterSource findFile flakeRefToString floor foldl' fromJSON fromTOML functionArgs genList genericClosure getAttr getContext getEnv getFlake groupBy hasAttr hasContext hashFile hashString head import intersectAttrs isAttrs isBool isFloat isFunction isInt isList isNull isPath isString langVersion length lessThan listToAttrs map mapAttrs match mul nixPath nixVersion outputOf parseDrvName parseFlakeRef partition path pathExists placeholder readDir readFile readFileType removeAttrs replaceStrings seq sort split splitVersion storeDir storePath stringLength sub substring tail throw toFile toJSON toPath toString toXML trace traceVerbose tryEval typeOf unsafeDiscardOutputDependency unsafeDiscardStringContext warn zipAttrsWith\nkeywords4.*.nix=runCommand\n"
  },
  {
    "path": "test/examples/pascal/AllStyles.pas",
    "content": "// Enumerate all primary styles: 0 to 14\n\n{\n  SCE_PAS_DEFAULT=0\n  SCE_PAS_IDENTIFIER=1\n  SCE_PAS_COMMENT=2\n  SCE_PAS_COMMENT2=3\n  SCE_PAS_COMMENTLINE=4\n  SCE_PAS_PREPROCESSOR=5\n  SCE_PAS_PREPROCESSOR2=6\n  SCE_PAS_NUMBER=7\n  SCE_PAS_HEXNUMBER=8\n  SCE_PAS_WORD=9\n  SCE_PAS_STRING=10\n  SCE_PAS_STRINGEOL=11\n  SCE_PAS_CHARACTER=12\n  SCE_PAS_OPERATOR=13\n  SCE_PAS_ASM=14\n}\n\n// default=0\n   \n// identifier=1\nfunction functionname(var paramerter1: type1):result1;\nprocedure procedurename(const parameter2: type2);\n\n// comment=2\n{comment text}\n\n// comment2=3\n(* comment text *)\n\n// commentline=4\n// example line\n\n// preprocessor=5\n{$DEFINE xyz}\n\n{$IFDEF xyz}\n   codeblock 1\n{$else}\n   codeblock 2\n{$endif}\n\n// preprocessor2=6\n(*$DEFINE xyz*)\n\n// number=7\n123\n1.23\n-123\n-12.3\n+123\n123\n1.23e2\n-1.23E2\n\n// hexnumber=8\n$123\n$123ABCDEF\n$ABCDEF123\n\n// word=9\nabsolute abstract and array as\n\n// string=10\n'string'\n\n// stringeol=11\n'string\n\n// character=12\n#65\n\n// operator=13\n$ & * + / < = > ^\n\n// asm=14\nasm\n  this is\n  inside assembler\nend\n\n// multiline string=15\n'''\ntriple-quoted\n''';\n\n'''''\n5 quotes needs matching 5 quote end\n''' triple quotes allowed in 5 quote\n''''';\n"
  },
  {
    "path": "test/examples/pascal/AllStyles.pas.folded",
    "content": " 0 400   0   // Enumerate all primary styles: 0 to 14\n 1 400   0   \n 2 400   0 + {\n 0 401   0 |   SCE_PAS_DEFAULT=0\n 0 401   0 |   SCE_PAS_IDENTIFIER=1\n 0 401   0 |   SCE_PAS_COMMENT=2\n 0 401   0 |   SCE_PAS_COMMENT2=3\n 0 401   0 |   SCE_PAS_COMMENTLINE=4\n 0 401   0 |   SCE_PAS_PREPROCESSOR=5\n 0 401   0 |   SCE_PAS_PREPROCESSOR2=6\n 0 401   0 |   SCE_PAS_NUMBER=7\n 0 401   0 |   SCE_PAS_HEXNUMBER=8\n 0 401   0 |   SCE_PAS_WORD=9\n 0 401   0 |   SCE_PAS_STRING=10\n 0 401   0 |   SCE_PAS_STRINGEOL=11\n 0 401   0 |   SCE_PAS_CHARACTER=12\n 0 401   0 |   SCE_PAS_OPERATOR=13\n 0 401   0 |   SCE_PAS_ASM=14\n 0 401   0 | }\n 1 400   0   \n 0 400   0   // default=0\n 1 400   0      \n 0 400   0   // identifier=1\n 0 400   0   function functionname(var paramerter1: type1):result1;\n 0 400   0   procedure procedurename(const parameter2: type2);\n 1 400   0   \n 0 400   0   // comment=2\n 0 400   0   {comment text}\n 1 400   0   \n 0 400   0   // comment2=3\n 0 400   0   (* comment text *)\n 1 400   0   \n 2 400   0 + // commentline=4\n 0 401   0 | // example line\n 1 400   0   \n 0 400   0   // preprocessor=5\n 0 400   0   {$DEFINE xyz}\n 1 400   0   \n 2 400   0 + {$IFDEF xyz}\n 0 401   0 |    codeblock 1\n 0 401   0 | {$else}\n 0 401   0 |    codeblock 2\n 0 401   0 | {$endif}\n 1 400   0   \n 0 400   0   // preprocessor2=6\n 0 400   0   (*$DEFINE xyz*)\n 1 400   0   \n 0 400   0   // number=7\n 0 400   0   123\n 0 400   0   1.23\n 0 400   0   -123\n 0 400   0   -12.3\n 0 400   0   +123\n 0 400   0   123\n 0 400   0   1.23e2\n 0 400   0   -1.23E2\n 1 400   0   \n 0 400   0   // hexnumber=8\n 0 400   0   $123\n 0 400   0   $123ABCDEF\n 0 400   0   $ABCDEF123\n 1 400   0   \n 0 400   0   // word=9\n 0 400   0   absolute abstract and array as\n 1 400   0   \n 0 400   0   // string=10\n 0 400   0   'string'\n 1 400   0   \n 0 400   0   // stringeol=11\n 0 400   0   'string\n 1 400   0   \n 0 400   0   // character=12\n 0 400   0   #65\n 1 400   0   \n 0 400   0   // operator=13\n 0 400   0   $ & * + / < = > ^\n 1 400   0   \n 0 400   0   // asm=14\n 2 400   0 + asm\n 0 401   0 |   this is\n 0 401   0 |   inside assembler\n 0 401   0 | end\n 1 400   0   \n 0 400   0   // multiline string=15\n 0 400   0   '''\n 0 400   0   triple-quoted\n 0 400   0   ''';\n 1 400   0   \n 0 400   0   '''''\n 0 400   0   5 quotes needs matching 5 quote end\n 0 400   0   ''' triple quotes allowed in 5 quote\n 0 400   0   ''''';\n 1 400   0   "
  },
  {
    "path": "test/examples/pascal/AllStyles.pas.styled",
    "content": "{4}// Enumerate all primary styles: 0 to 14\n{0}\n{2}{\n  SCE_PAS_DEFAULT=0\n  SCE_PAS_IDENTIFIER=1\n  SCE_PAS_COMMENT=2\n  SCE_PAS_COMMENT2=3\n  SCE_PAS_COMMENTLINE=4\n  SCE_PAS_PREPROCESSOR=5\n  SCE_PAS_PREPROCESSOR2=6\n  SCE_PAS_NUMBER=7\n  SCE_PAS_HEXNUMBER=8\n  SCE_PAS_WORD=9\n  SCE_PAS_STRING=10\n  SCE_PAS_STRINGEOL=11\n  SCE_PAS_CHARACTER=12\n  SCE_PAS_OPERATOR=13\n  SCE_PAS_ASM=14\n}{0}\n\n{4}// default=0\n{0}   \n{4}// identifier=1\n{9}function{0} {1}functionname{13}({9}var{0} {1}paramerter1{13}:{0} {1}type1{13}):{1}result1{13};{0}\n{9}procedure{0} {1}procedurename{13}({9}const{0} {1}parameter2{13}:{0} {1}type2{13});{0}\n\n{4}// comment=2\n{2}{comment text}{0}\n\n{4}// comment2=3\n{3}(* comment text *){0}\n\n{4}// commentline=4\n// example line\n{0}\n{4}// preprocessor=5\n{5}{$DEFINE xyz}{0}\n\n{5}{$IFDEF xyz}{0}\n   {1}codeblock{0} {7}1{0}\n{5}{$else}{0}\n   {1}codeblock{0} {7}2{0}\n{5}{$endif}{0}\n\n{4}// preprocessor2=6\n{6}(*$DEFINE xyz*){0}\n\n{4}// number=7\n{7}123{0}\n{7}1.23{0}\n{13}-{7}123{0}\n{13}-{7}12.3{0}\n{13}+{7}123{0}\n{7}123{0}\n{7}1.23e2{0}\n{13}-{7}1.23E2{0}\n\n{4}// hexnumber=8\n{8}$123{0}\n{8}$123ABCDEF{0}\n{8}$ABCDEF123{0}\n\n{4}// word=9\n{9}absolute{0} {9}abstract{0} {9}and{0} {9}array{0} {9}as{0}\n\n{4}// string=10\n{10}'string'{0}\n\n{4}// stringeol=11\n{11}'string\n{0}\n{4}// character=12\n{12}#65{0}\n\n{4}// operator=13\n{8}${0} {13}&{0} {13}*{0} {13}+{0} {13}/{0} {13}<{0} {13}={0} {13}>{0} {13}^{0}\n\n{4}// asm=14\n{9}asm{14}\n  this is\n  inside assembler\n{9}end{0}\n\n{4}// multiline string=15\n{15}'''\ntriple-quoted\n'''{13};{0}\n\n{15}'''''\n5 quotes needs matching 5 quote end\n''' triple quotes allowed in 5 quote\n'''''{13};{0}\n"
  },
  {
    "path": "test/examples/pascal/CodeFolding.pas",
    "content": "// tests for code folding\n\n// multi line comments\n{ \nline1\nline2\n}\n\n// begin .. end\nbegin\nsome commands\nend;\n\nrecord test\n  var1: type1;\n  var2: type2;\n  end; //record\n  \n//asm\nasm\n  some statement\n  end; //asm\n  \n//try (from https://wiki.freepascal.org/Try)\ntry\n  // code that might generate an exception\nexcept\n  // will only be executed in case of an exception\n  on E: EDatabaseError do\n    ShowMessage( 'Database error: '+ E.ClassName + #13#10 + E.Message );\n  on E: Exception do\n    ShowMessage( 'Error: '+ E.ClassName + #13#10 + E.Message );\nend;\n  \n//try nested (from https://wiki.freepascal.org/Try)\ntry\n  try\n    // code dealing with database that might generate an exception\n  except\n    // will only be executed in case of an exception\n    on E: EDatabaseError do\n      ShowMessage( 'Database error: '+ E.ClassName + #13#10 + E.Message );\n    on E: Exception do\n      ShowMessage( 'Error: '+ E.ClassName + #13#10 + E.Message );\n  end;\nfinally\n  // clean up database-related resources\nend;\n\n//case\ncase x of\n  1: do something;\n  2: do some other thing;\nelse\n  do default;\n  end; //case\n  \n//if then else  \nif x=y then \n  do something;\nelse\n  do some other thing;\n  \n//for loop  \nfor i:=1 to 10 do\n  writeln(i)\n\n//do until\nrepeat\n  write(a);\n  i:=i+1;\nuntil i>10;\n\n//preprocessor if, else, endif\n{$DEFINE label}\n{$IFDEF label}\n  command 1\n{$ELSE}\n  command 2\n{$ENDIF}\n"
  },
  {
    "path": "test/examples/pascal/CodeFolding.pas.folded",
    "content": " 0 400   0   // tests for code folding\n 1 400   0   \n 0 400   0   // multi line comments\n 2 400   0 + { \n 0 401   0 | line1\n 0 401   0 | line2\n 0 401   0 | }\n 1 400   0   \n 0 400   0   // begin .. end\n 2 400   0 + begin\n 0 401   0 | some commands\n 0 401   0 | end;\n 1 400   0   \n 2 400   0 + record test\n 0 401   0 |   var1: type1;\n 0 401   0 |   var2: type2;\n 0 401   0 |   end; //record\n 1 400   0     \n 0 400   0   //asm\n 2 400   0 + asm\n 0 401   0 |   some statement\n 0 401   0 |   end; //asm\n 1 400   0     \n 0 400   0   //try (from https://wiki.freepascal.org/Try)\n 2 400   0 + try\n 0 401   0 |   // code that might generate an exception\n 0 401   0 | except\n 0 401   0 |   // will only be executed in case of an exception\n 0 401   0 |   on E: EDatabaseError do\n 0 401   0 |     ShowMessage( 'Database error: '+ E.ClassName + #13#10 + E.Message );\n 0 401   0 |   on E: Exception do\n 0 401   0 |     ShowMessage( 'Error: '+ E.ClassName + #13#10 + E.Message );\n 0 401   0 | end;\n 1 400   0     \n 0 400   0   //try nested (from https://wiki.freepascal.org/Try)\n 2 400   0 + try\n 2 401   0 +   try\n 0 402   0 |     // code dealing with database that might generate an exception\n 0 402   0 |   except\n 0 402   0 |     // will only be executed in case of an exception\n 0 402   0 |     on E: EDatabaseError do\n 0 402   0 |       ShowMessage( 'Database error: '+ E.ClassName + #13#10 + E.Message );\n 0 402   0 |     on E: Exception do\n 0 402   0 |       ShowMessage( 'Error: '+ E.ClassName + #13#10 + E.Message );\n 0 402   0 |   end;\n 0 401   0 | finally\n 0 401   0 |   // clean up database-related resources\n 0 401   0 | end;\n 1 400   0   \n 0 400   0   //case\n 2 400   0 + case x of\n 0 401   0 |   1: do something;\n 0 401   0 |   2: do some other thing;\n 0 401   0 | else\n 0 401   0 |   do default;\n 0 401   0 |   end; //case\n 1 400   0     \n 0 400   0   //if then else  \n 0 400   0   if x=y then \n 0 400   0     do something;\n 0 400   0   else\n 0 400   0     do some other thing;\n 1 400   0     \n 0 400   0   //for loop  \n 0 400   0   for i:=1 to 10 do\n 0 400   0     writeln(i)\n 1 400   0   \n 0 400   0   //do until\n 0 400   0   repeat\n 0 400   0     write(a);\n 0 400   0     i:=i+1;\n 0 400   0   until i>10;\n 1 400   0   \n 0 400   0   //preprocessor if, else, endif\n 0 400   0   {$DEFINE label}\n 2 400   0 + {$IFDEF label}\n 0 401   0 |   command 1\n 0 401   0 | {$ELSE}\n 0 401   0 |   command 2\n 0 401   0 | {$ENDIF}\n 1 400   0   "
  },
  {
    "path": "test/examples/pascal/CodeFolding.pas.styled",
    "content": "{4}// tests for code folding\n{0}\n{4}// multi line comments\n{2}{ \nline1\nline2\n}{0}\n\n{4}// begin .. end\n{9}begin{0}\n{1}some{0} {1}commands{0}\n{9}end{13};{0}\n\n{9}record{0} {1}test{0}\n  {1}var1{13}:{0} {1}type1{13};{0}\n  {1}var2{13}:{0} {1}type2{13};{0}\n  {9}end{13};{0} {4}//record\n{0}  \n{4}//asm\n{9}asm{14}\n  some statement\n  {9}end{13};{0} {4}//asm\n{0}  \n{4}//try (from https://wiki.freepascal.org/Try)\n{9}try{0}\n  {4}// code that might generate an exception\n{9}except{0}\n  {4}// will only be executed in case of an exception\n{0}  {9}on{0} {1}E{13}:{0} {1}EDatabaseError{0} {9}do{0}\n    {1}ShowMessage{13}({0} {10}'Database error: '{13}+{0} {1}E{13}.{1}ClassName{0} {13}+{0} {12}#13#10{0} {13}+{0} {1}E{13}.{9}Message{0} {13});{0}\n  {9}on{0} {1}E{13}:{0} {1}Exception{0} {9}do{0}\n    {1}ShowMessage{13}({0} {10}'Error: '{13}+{0} {1}E{13}.{1}ClassName{0} {13}+{0} {12}#13#10{0} {13}+{0} {1}E{13}.{9}Message{0} {13});{0}\n{9}end{13};{0}\n  \n{4}//try nested (from https://wiki.freepascal.org/Try)\n{9}try{0}\n  {9}try{0}\n    {4}// code dealing with database that might generate an exception\n{0}  {9}except{0}\n    {4}// will only be executed in case of an exception\n{0}    {9}on{0} {1}E{13}:{0} {1}EDatabaseError{0} {9}do{0}\n      {1}ShowMessage{13}({0} {10}'Database error: '{13}+{0} {1}E{13}.{1}ClassName{0} {13}+{0} {12}#13#10{0} {13}+{0} {1}E{13}.{9}Message{0} {13});{0}\n    {9}on{0} {1}E{13}:{0} {1}Exception{0} {9}do{0}\n      {1}ShowMessage{13}({0} {10}'Error: '{13}+{0} {1}E{13}.{1}ClassName{0} {13}+{0} {12}#13#10{0} {13}+{0} {1}E{13}.{9}Message{0} {13});{0}\n  {9}end{13};{0}\n{9}finally{0}\n  {4}// clean up database-related resources\n{9}end{13};{0}\n\n{4}//case\n{9}case{0} {1}x{0} {9}of{0}\n  {7}1{13}:{0} {9}do{0} {1}something{13};{0}\n  {7}2{13}:{0} {9}do{0} {1}some{0} {1}other{0} {1}thing{13};{0}\n{9}else{0}\n  {9}do{0} {1}default{13};{0}\n  {9}end{13};{0} {4}//case\n{0}  \n{4}//if then else  \n{9}if{0} {1}x{13}={1}y{0} {9}then{0} \n  {9}do{0} {1}something{13};{0}\n{9}else{0}\n  {9}do{0} {1}some{0} {1}other{0} {1}thing{13};{0}\n  \n{4}//for loop  \n{9}for{0} {1}i{13}:={7}1{0} {9}to{0} {7}10{0} {9}do{0}\n  {1}writeln{13}({1}i{13}){0}\n\n{4}//do until\n{9}repeat{0}\n  {1}write{13}({1}a{13});{0}\n  {1}i{13}:={1}i{13}+{7}1{13};{0}\n{9}until{0} {1}i{13}>{7}10{13};{0}\n\n{4}//preprocessor if, else, endif\n{5}{$DEFINE label}{0}\n{5}{$IFDEF label}{0}\n  {1}command{0} {7}1{0}\n{5}{$ELSE}{0}\n  {1}command{0} {7}2{0}\n{5}{$ENDIF}{0}\n"
  },
  {
    "path": "test/examples/pascal/SciTE.properties",
    "content": "# coding: utf-8\nlexer.*.pas=pascal\nkeywords.*.pas=absolute abstract and array as asm assembler automated begin case \\\ncdecl class const constructor delayed deprecated destructor dispid dispinterface \\\ndiv do downto dynamic else end except experimental export exports external far \\\nfile final finalization finally for forward function goto helper if \\\nimplementation in inherited initialization inline interface is label library \\\nmessage mod near nil not object of on operator or out overload override packed \\\npascal platform private procedure program property protected public published \\\nraise record reference register reintroduce repeat resourcestring safecall \\\nsealed set shl shr static stdcall strict string then threadvar to try type unit \\\nunsafe until uses var varargs virtual while winapi with xor\n\n\nlexer.pascal.smart.highlighting=1\n\nfold=1\nfold.preprocessor=1\nfold.comment=1\nfold.compact=1\n"
  },
  {
    "path": "test/examples/pascal/SomeExample.pas",
    "content": "// some example source code\n\n{\n  SCE_PAS_DEFAULT=0\n  SCE_PAS_IDENTIFIER=1\n  SCE_PAS_COMMENT=2\n  SCE_PAS_COMMENT2=3\n  SCE_PAS_COMMENTLINE=4\n  SCE_PAS_PREPROCESSOR=5\n  SCE_PAS_PREPROCESSOR2=6\n  SCE_PAS_NUMBER=7\n  SCE_PAS_HEXNUMBER=8\n  SCE_PAS_WORD=9\n  SCE_PAS_STRING=10\n  SCE_PAS_STRINGEOL=11\n  SCE_PAS_CHARACTER=12\n  SCE_PAS_OPERATOR=13\n  SCE_PAS_ASM=14\n}\n\n{ --------------------------------------------------------------------------- }\nfunction functionname(paramerter1: type1):result1;\n  var\n    i: LongInt;\n  begin\n  for i:=1 to 10 do\n    begin\n    writeln(i)\n    end;\n  result:=true;\n  end;\n{ --------------------------------------------------------------------------- }\nprocedure procedurename(parameter2: type2);\n  var\n    i: LongInt;\n  begin\n  for i:=1 to 10 do\n    begin\n    writeln(i)\n    end;\n  end;\n"
  },
  {
    "path": "test/examples/pascal/SomeExample.pas.folded",
    "content": " 0 400   0   // some example source code\n 1 400   0   \n 2 400   0 + {\n 0 401   0 |   SCE_PAS_DEFAULT=0\n 0 401   0 |   SCE_PAS_IDENTIFIER=1\n 0 401   0 |   SCE_PAS_COMMENT=2\n 0 401   0 |   SCE_PAS_COMMENT2=3\n 0 401   0 |   SCE_PAS_COMMENTLINE=4\n 0 401   0 |   SCE_PAS_PREPROCESSOR=5\n 0 401   0 |   SCE_PAS_PREPROCESSOR2=6\n 0 401   0 |   SCE_PAS_NUMBER=7\n 0 401   0 |   SCE_PAS_HEXNUMBER=8\n 0 401   0 |   SCE_PAS_WORD=9\n 0 401   0 |   SCE_PAS_STRING=10\n 0 401   0 |   SCE_PAS_STRINGEOL=11\n 0 401   0 |   SCE_PAS_CHARACTER=12\n 0 401   0 |   SCE_PAS_OPERATOR=13\n 0 401   0 |   SCE_PAS_ASM=14\n 0 401   0 | }\n 1 400   0   \n 0 400   0   { --------------------------------------------------------------------------- }\n 0 400   0   function functionname(paramerter1: type1):result1;\n 0 400   0     var\n 0 400   0       i: LongInt;\n 2 400   0 +   begin\n 0 401   0 |   for i:=1 to 10 do\n 2 401   0 +     begin\n 0 402   0 |     writeln(i)\n 0 402   0 |     end;\n 0 401   0 |   result:=true;\n 0 401   0 |   end;\n 0 400   0   { --------------------------------------------------------------------------- }\n 0 400   0   procedure procedurename(parameter2: type2);\n 0 400   0     var\n 0 400   0       i: LongInt;\n 2 400   0 +   begin\n 0 401   0 |   for i:=1 to 10 do\n 2 401   0 +     begin\n 0 402   0 |     writeln(i)\n 0 402   0 |     end;\n 0 401   0 |   end;\n 1 400   0   "
  },
  {
    "path": "test/examples/pascal/SomeExample.pas.styled",
    "content": "{4}// some example source code\n{0}\n{2}{\n  SCE_PAS_DEFAULT=0\n  SCE_PAS_IDENTIFIER=1\n  SCE_PAS_COMMENT=2\n  SCE_PAS_COMMENT2=3\n  SCE_PAS_COMMENTLINE=4\n  SCE_PAS_PREPROCESSOR=5\n  SCE_PAS_PREPROCESSOR2=6\n  SCE_PAS_NUMBER=7\n  SCE_PAS_HEXNUMBER=8\n  SCE_PAS_WORD=9\n  SCE_PAS_STRING=10\n  SCE_PAS_STRINGEOL=11\n  SCE_PAS_CHARACTER=12\n  SCE_PAS_OPERATOR=13\n  SCE_PAS_ASM=14\n}{0}\n\n{2}{ --------------------------------------------------------------------------- }{0}\n{9}function{0} {1}functionname{13}({1}paramerter1{13}:{0} {1}type1{13}):{1}result1{13};{0}\n  {9}var{0}\n    {1}i{13}:{0} {1}LongInt{13};{0}\n  {9}begin{0}\n  {9}for{0} {1}i{13}:={7}1{0} {9}to{0} {7}10{0} {9}do{0}\n    {9}begin{0}\n    {1}writeln{13}({1}i{13}){0}\n    {9}end{13};{0}\n  {1}result{13}:={1}true{13};{0}\n  {9}end{13};{0}\n{2}{ --------------------------------------------------------------------------- }{0}\n{9}procedure{0} {1}procedurename{13}({1}parameter2{13}:{0} {1}type2{13});{0}\n  {9}var{0}\n    {1}i{13}:{0} {1}LongInt{13};{0}\n  {9}begin{0}\n  {9}for{0} {1}i{13}:={7}1{0} {9}to{0} {7}10{0} {9}do{0}\n    {9}begin{0}\n    {1}writeln{13}({1}i{13}){0}\n    {9}end{13};{0}\n  {9}end{13};{0}\n"
  },
  {
    "path": "test/examples/perl/SciTE.properties",
    "content": "lexer.*.pl=perl\nkeywords.*.pl=\\\nADJUST AUTOLOAD BEGIN CHECK CORE DESTROY END EQ GE GT INIT LE LT NE NULL \\\nUNITCHECK __CLASS__ __DATA__ __END__ __FILE__ __LINE__ __PACKAGE__ \\\n__SUB__ abs accept alarm all and any atan2 attributes autodie autouse \\\nbase bigfloat bigint bignum bigrat bind binmode bless blib break builtin \\\nbytes caller catch charnames chdir chmod chomp chop chown chr chroot \\\nclass close closedir cmp connect constant continue cos crypt dbmclose \\\ndbmopen default defer defined delete deprecate diagnostics die do dump \\\neach else elseif elsif encoding endgrent endhostent endnetent \\\nendprotoent endpwent endservent eof eq eval evalbytes exec exists exit \\\nexp experimental fc fcntl feature field fields fileno filetest finally \\\nflock for foreach fork format formline ge getc getgrent getgrgid \\\ngetgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr \\\ngetnetbyname getnetent getpeername getpgrp getppid getpriority \\\ngetprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid \\\ngetservbyname getservbyport getservent getsockname getsockopt given glob \\\ngmtime goto grep gt hex if import index int integer ioctl isa join keys \\\nkill last lc lcfirst le length less lib link listen local locale \\\nlocaltime lock log lstat lt map meta_notation method mkdir mro msgctl \\\nmsgget msgrcv msgsnd my ne next no not oct ok open opendir ops or ord \\\nour overload overloading pack package parent perlfaq pipe pop pos print \\\nprintf prototype push qu quotemeta rand re read readdir readline \\\nreadlink readpipe recv redo ref rename require reset return reverse \\\nrewinddir rindex rmdir say scalar seek seekdir select semctl semget \\\nsemop send setgrent sethostent setnetent setpgrp setpriority setprotoent \\\nsetpwent setservent setsockopt shift shmctl shmget shmread shmwrite \\\nshutdown sigtrap sin size sleep socket socketpair sort splice split \\\nsprintf sqrt srand stable stat state strict study sub subs substr \\\nsymlink syscall sysopen sysread sysseek system syswrite tell telldir \\\nthreads tie tied time times truncate try uc ucfirst umask undef unless \\\nunlink unpack unshift untie until use utf8 utime values vars vec version \\\nvmsish wait waitpid wantarray warn warnings when while write xor\n\nfold=1\nfold.comment=1"
  },
  {
    "path": "test/examples/perl/class.pl",
    "content": "#!/usr/bin/env perl\nuse v5.38;\nuse feature 'class';\n\nclass MyClass::SubClass {\n    method inClass { return 1 }\n    method inClassProto($) { return $_[0] }\n    method inClassAttrib :prototype($) { return $_[0] }\n}\n"
  },
  {
    "path": "test/examples/perl/class.pl.folded",
    "content": " 0 400 400   #!/usr/bin/env perl\n 0 400 400   use v5.38;\n 0 400 400   use feature 'class';\n 1 400 400   \n 2 400 401 + class MyClass::SubClass {\n 0 401 401 |     method inClass { return 1 }\n 0 401 401 |     method inClassProto($) { return $_[0] }\n 0 401 401 |     method inClassAttrib :prototype($) { return $_[0] }\n 0 401 400 | }\n 0 400   0   "
  },
  {
    "path": "test/examples/perl/class.pl.styled",
    "content": "{2}#!/usr/bin/env perl\n{5}use{0} {6}v5.38{10};{0}\n{5}use{0} {5}feature{0} {7}'class'{10};{0}\n\n{5}class{0} {11}MyClass{10}::{11}SubClass{0} {10}{{0}\n    {5}method{0} {11}inClass{0} {10}{{0} {5}return{0} {4}1{0} {10}}{0}\n    {5}method{0} {11}inClassProto{40}($){0} {10}{{0} {5}return{0} {12}$_{10}[{4}0{10}]{0} {10}}{0}\n    {5}method{0} {11}inClassAttrib{0} {10}:{5}prototype{40}($){0} {10}{{0} {5}return{0} {12}$_{10}[{4}0{10}]{0} {10}}{0}\n{10}}{0}\n"
  },
  {
    "path": "test/examples/perl/perl-test-5220delta.pl",
    "content": "# -*- coding: utf-8 -*-\n#--------------------------------------------------------------------------\n# perl-test-5220delta.pl\n#--------------------------------------------------------------------------\n# REF: https://metacpan.org/pod/distribution/perl/pod/perldelta.pod\n# maybe future ref: https://metacpan.org/pod/distribution/perl/pod/perl5220delta.pod\n# also: http://perltricks.com/article/165/2015/4/10/A-preview-of-Perl-5-22\n#\n#--------------------------------------------------------------------------\n# Kein-Hong Man <keinhong@gmail.com> Public Domain 20151217\n#--------------------------------------------------------------------------\n# 20151217\tinitial document\n# 20151218\tupdated tests and comments\n#--------------------------------------------------------------------------\n\nuse v5.22;\t\t\t# may be needed\n\n#--------------------------------------------------------------------------\n# New bitwise operators\n#--------------------------------------------------------------------------\n\nuse feature 'bitwise'\t\t# enable feature, warning enabled\nuse experimental \"bitwise\";\t# enable feature, warning disabled\n\n# numerical operands\n10&20  10|20   10^20 ~10\n$a&\"8\" $a|\"8\" $a^\"8\" ~$a ~\"8\"\n\n# string operands\n'0'&.\"8\" '0'|.\"8\" '0'^.\"8\" ~.'0' ~.\"8\"\n# the following is AMBIGUOUS, perl sees 10 and not .10 only when bitwise feature is enabled\n# so it's feature-setting-dependent, no plans to change current behaviour\n $a&.10   $a|.10   $a^.10  ~.$a  ~.10\n\n# assignment variants\n$a&=10;    $a|=10;    $a^=10;\n$b&.='20'; $b|.='20'; $b^.='20';\n$c&=\"30\";  $c|=\"30\";  $c^=\"30\";\n$d&.=$e;   $d|.=$e;   $d^.=$e;\n\n#--------------------------------------------------------------------------\n# New double-diamond operator\n#--------------------------------------------------------------------------\n# <<>> is like <> but each element of @ARGV will be treated as an actual file name\n\n# example snippet from brian d foy's blog post\nwhile( <<>> ) {  # new, safe line input operator\n\t...;\n\t}\n\n#--------------------------------------------------------------------------\n# New \\b boundaries in regular expressions\n#--------------------------------------------------------------------------\n\nqr/\\b{gcb}/\nqr/\\b{wb}/\nqr/\\b{sb}/\n\n#--------------------------------------------------------------------------\n# Non-Capturing Regular Expression Flag\n#--------------------------------------------------------------------------\n# disables capturing and filling in $1, $2, etc\n\n\"hello\" =~ /(hi|hello)/n; # $1 is not set\n\n#--------------------------------------------------------------------------\n# Aliasing via reference\n#--------------------------------------------------------------------------\n# Variables and subroutines can now be aliased by assigning to a reference\n\n\\$c = \\$d;\n\\&x = \\&y;\n\n# Aliasing can also be applied to foreach iterator variables\n\nforeach \\%hash (@array_of_hash_refs) { ... }\n\n# example snippet from brian d foy's blog post\n\nuse feature qw(refaliasing);\n\n\\%other_hash = \\%hash;\n\nuse v5.22;\nuse feature qw(refaliasing);\n\nforeach \\my %hash ( @array_of_hashes ) { # named hash control variable\n\tforeach my $key ( keys %hash ) { # named hash now!\n\t\t...;\n\t\t}\n\t}\n\n#--------------------------------------------------------------------------\n# New :const subroutine attribute\n#--------------------------------------------------------------------------\n\nmy $x = 54321;\n*INLINED = sub : const { $x };\n$x++;\n\n# more examples of attributes\n# (not 5.22 stuff, but some general examples for study, useful for\n#  handling subroutine signature and subroutine prototype highlighting)\n\nsub foo : lvalue ;\n\npackage X;\nsub Y::x : lvalue { 1 }\n\npackage X;\nsub foo { 1 }\npackage Y;\nBEGIN { *bar = \\&X::foo; }\npackage Z;\nsub Y::bar : lvalue ;\n\n# built-in attributes for subroutines:\nlvalue method prototype(..) locked const\n\n#--------------------------------------------------------------------------\n# Repetition in list assignment\n#--------------------------------------------------------------------------\n\n# example snippet from brian d foy's blog post\nuse v5.22;\nmy(undef, $card_num, (undef)x3, $count) = split /:/;\n\n(undef,undef,$foo) = that_function()\n# is equivalent to \n((undef)x2, $foo) = that_function()\n\n#--------------------------------------------------------------------------\n# Floating point parsing has been improved\n#--------------------------------------------------------------------------\n# Hexadecimal floating point literals\n\n# some hex floats from a program by Rick Regan\n# appropriated and extended from Lua 5.2.x test cases\n# tested on perl 5.22/cygwin\n\n0x1p-1074;\n0x3.3333333333334p-5;\n0xcc.ccccccccccdp-11;\n0x1p+1;\n0x1p-6;\n0x1.b7p-1;\n0x1.fffffffffffffp+1023;\n0x1p-1022;\n0X1.921FB4D12D84AP+1;\n0x1.999999999999ap-4;\n\n# additional test cases for characterization\n0x1p-1074.\t\t# dot is a string operator\n0x.ABCDEFp10\t\t# legal, dot immediately after 0x\n0x.p10\t\t\t# perl allows 0x as a zero, then concat with p10 bareword\n0x.p 0x0.p\t\t# dot then bareword\n0x_0_.A_BC___DEF_p1_0\t# legal hex float, underscores are mostly allowed\n0x0._ABCDEFp10\t\t# _ABCDEFp10 is a bareword, no underscore allowed after dot\n\n# illegal, but does not use error highlighting\n0x0p1ABC\t\t# illegal, highlighted as 0x0p1 abut with bareword ABC \n\n# allowed to FAIL for now\n0x0.ABCDEFp_10\t\t# ABCDEFp_10 is a bareword, '_10' exponent not allowed\n0xp 0xp1 0x0.0p\t\t# syntax errors\n0x41.65.65 \t\t# hex dot number, but lexer now fails with 0x41.65 left as a partial hex float\n\n#--------------------------------------------------------------------------\n# Support for ?PATTERN? without explicit operator has been removed\n#--------------------------------------------------------------------------\n# ?PATTERN? must now be written as m?PATTERN?\n\n?PATTERN?\t# does not work in current LexPerl anyway, NO ACTION NEEDED\nm?PATTERN?\n\n#--------------------------------------------------------------------------\n# end of test file\n#--------------------------------------------------------------------------\n"
  },
  {
    "path": "test/examples/perl/perl-test-5220delta.pl.folded",
    "content": " 2 400 401 + # -*- coding: utf-8 -*-\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # perl-test-5220delta.pl\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # REF: https://metacpan.org/pod/distribution/perl/pod/perldelta.pod\n 0 401 401 | # maybe future ref: https://metacpan.org/pod/distribution/perl/pod/perl5220delta.pod\n 0 401 401 | # also: http://perltricks.com/article/165/2015/4/10/A-preview-of-Perl-5-22\n 0 401 401 | #\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # Kein-Hong Man <keinhong@gmail.com> Public Domain 20151217\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # 20151217\tinitial document\n 0 401 401 | # 20151218\tupdated tests and comments\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   use v5.22;\t\t\t# may be needed\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # New bitwise operators\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   use feature 'bitwise'\t\t# enable feature, warning enabled\n 0 400 400   use experimental \"bitwise\";\t# enable feature, warning disabled\n 1 400 400   \n 0 400 400   # numerical operands\n 0 400 400   10&20  10|20   10^20 ~10\n 0 400 400   $a&\"8\" $a|\"8\" $a^\"8\" ~$a ~\"8\"\n 1 400 400   \n 0 400 400   # string operands\n 0 400 400   '0'&.\"8\" '0'|.\"8\" '0'^.\"8\" ~.'0' ~.\"8\"\n 2 400 401 + # the following is AMBIGUOUS, perl sees 10 and not .10 only when bitwise feature is enabled\n 0 401 400 | # so it's feature-setting-dependent, no plans to change current behaviour\n 0 400 400    $a&.10   $a|.10   $a^.10  ~.$a  ~.10\n 1 400 400   \n 0 400 400   # assignment variants\n 0 400 400   $a&=10;    $a|=10;    $a^=10;\n 0 400 400   $b&.='20'; $b|.='20'; $b^.='20';\n 0 400 400   $c&=\"30\";  $c|=\"30\";  $c^=\"30\";\n 0 400 400   $d&.=$e;   $d|.=$e;   $d^.=$e;\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # New double-diamond operator\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 400 | # <<>> is like <> but each element of @ARGV will be treated as an actual file name\n 1 400 400   \n 0 400 400   # example snippet from brian d foy's blog post\n 2 400 401 + while( <<>> ) {  # new, safe line input operator\n 0 401 401 | \t...;\n 0 401 400 | \t}\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # New \\b boundaries in regular expressions\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   qr/\\b{gcb}/\n 0 400 400   qr/\\b{wb}/\n 0 400 400   qr/\\b{sb}/\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # Non-Capturing Regular Expression Flag\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 400 | # disables capturing and filling in $1, $2, etc\n 1 400 400   \n 0 400 400   \"hello\" =~ /(hi|hello)/n; # $1 is not set\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # Aliasing via reference\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 400 | # Variables and subroutines can now be aliased by assigning to a reference\n 1 400 400   \n 0 400 400   \\$c = \\$d;\n 0 400 400   \\&x = \\&y;\n 1 400 400   \n 0 400 400   # Aliasing can also be applied to foreach iterator variables\n 1 400 400   \n 0 400 400   foreach \\%hash (@array_of_hash_refs) { ... }\n 1 400 400   \n 0 400 400   # example snippet from brian d foy's blog post\n 1 400 400   \n 0 400 400   use feature qw(refaliasing);\n 1 400 400   \n 0 400 400   \\%other_hash = \\%hash;\n 1 400 400   \n 0 400 400   use v5.22;\n 0 400 400   use feature qw(refaliasing);\n 1 400 400   \n 2 400 401 + foreach \\my %hash ( @array_of_hashes ) { # named hash control variable\n 2 401 402 + \tforeach my $key ( keys %hash ) { # named hash now!\n 0 402 402 | \t\t...;\n 0 402 401 | \t\t}\n 0 401 400 | \t}\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # New :const subroutine attribute\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   my $x = 54321;\n 0 400 400   *INLINED = sub : const { $x };\n 0 400 400   $x++;\n 1 400 400   \n 2 400 401 + # more examples of attributes\n 0 401 401 | # (not 5.22 stuff, but some general examples for study, useful for\n 0 401 400 | #  handling subroutine signature and subroutine prototype highlighting)\n 1 400 400   \n 0 400 400   sub foo : lvalue ;\n 1 400 400   \n 2 400 401 + package X;\n 0 401 401 | sub Y::x : lvalue { 1 }\n 1 401 401 | \n 2 400 401 + package X;\n 0 401 401 | sub foo { 1 }\n 2 400 401 + package Y;\n 0 401 401 | BEGIN { *bar = \\&X::foo; }\n 2 400 401 + package Z;\n 0 401 401 | sub Y::bar : lvalue ;\n 1 401 401 | \n 0 401 401 | # built-in attributes for subroutines:\n 0 401 401 | lvalue method prototype(..) locked const\n 1 401 401 | \n 2 401 402 + #--------------------------------------------------------------------------\n 0 402 402 | # Repetition in list assignment\n 0 402 401 | #--------------------------------------------------------------------------\n 1 401 401 | \n 0 401 401 | # example snippet from brian d foy's blog post\n 0 401 401 | use v5.22;\n 0 401 401 | my(undef, $card_num, (undef)x3, $count) = split /:/;\n 1 401 401 | \n 0 401 401 | (undef,undef,$foo) = that_function()\n 0 401 401 | # is equivalent to \n 0 401 401 | ((undef)x2, $foo) = that_function()\n 1 401 401 | \n 2 401 402 + #--------------------------------------------------------------------------\n 0 402 402 | # Floating point parsing has been improved\n 0 402 402 | #--------------------------------------------------------------------------\n 0 402 401 | # Hexadecimal floating point literals\n 1 401 401 | \n 2 401 402 + # some hex floats from a program by Rick Regan\n 0 402 402 | # appropriated and extended from Lua 5.2.x test cases\n 0 402 401 | # tested on perl 5.22/cygwin\n 1 401 401 | \n 0 401 401 | 0x1p-1074;\n 0 401 401 | 0x3.3333333333334p-5;\n 0 401 401 | 0xcc.ccccccccccdp-11;\n 0 401 401 | 0x1p+1;\n 0 401 401 | 0x1p-6;\n 0 401 401 | 0x1.b7p-1;\n 0 401 401 | 0x1.fffffffffffffp+1023;\n 0 401 401 | 0x1p-1022;\n 0 401 401 | 0X1.921FB4D12D84AP+1;\n 0 401 401 | 0x1.999999999999ap-4;\n 1 401 401 | \n 0 401 401 | # additional test cases for characterization\n 0 401 401 | 0x1p-1074.\t\t# dot is a string operator\n 0 401 401 | 0x.ABCDEFp10\t\t# legal, dot immediately after 0x\n 0 401 401 | 0x.p10\t\t\t# perl allows 0x as a zero, then concat with p10 bareword\n 0 401 401 | 0x.p 0x0.p\t\t# dot then bareword\n 0 401 401 | 0x_0_.A_BC___DEF_p1_0\t# legal hex float, underscores are mostly allowed\n 0 401 401 | 0x0._ABCDEFp10\t\t# _ABCDEFp10 is a bareword, no underscore allowed after dot\n 1 401 401 | \n 0 401 401 | # illegal, but does not use error highlighting\n 0 401 401 | 0x0p1ABC\t\t# illegal, highlighted as 0x0p1 abut with bareword ABC \n 1 401 401 | \n 0 401 401 | # allowed to FAIL for now\n 0 401 401 | 0x0.ABCDEFp_10\t\t# ABCDEFp_10 is a bareword, '_10' exponent not allowed\n 0 401 401 | 0xp 0xp1 0x0.0p\t\t# syntax errors\n 0 401 401 | 0x41.65.65 \t\t# hex dot number, but lexer now fails with 0x41.65 left as a partial hex float\n 1 401 401 | \n 2 401 402 + #--------------------------------------------------------------------------\n 0 402 402 | # Support for ?PATTERN? without explicit operator has been removed\n 0 402 402 | #--------------------------------------------------------------------------\n 0 402 401 | # ?PATTERN? must now be written as m?PATTERN?\n 1 401 401 | \n 0 401 401 | ?PATTERN?\t# does not work in current LexPerl anyway, NO ACTION NEEDED\n 0 401 401 | m?PATTERN?\n 1 401 401 | \n 2 401 402 + #--------------------------------------------------------------------------\n 0 402 402 | # end of test file\n 0 402 401 | #--------------------------------------------------------------------------\n 0 401   0 | "
  },
  {
    "path": "test/examples/perl/perl-test-5220delta.pl.styled",
    "content": "{2}# -*- coding: utf-8 -*-\n#--------------------------------------------------------------------------\n# perl-test-5220delta.pl\n#--------------------------------------------------------------------------\n# REF: https://metacpan.org/pod/distribution/perl/pod/perldelta.pod\n# maybe future ref: https://metacpan.org/pod/distribution/perl/pod/perl5220delta.pod\n# also: http://perltricks.com/article/165/2015/4/10/A-preview-of-Perl-5-22\n#\n#--------------------------------------------------------------------------\n# Kein-Hong Man <keinhong@gmail.com> Public Domain 20151217\n#--------------------------------------------------------------------------\n# 20151217\tinitial document\n# 20151218\tupdated tests and comments\n#--------------------------------------------------------------------------\n{0}\n{5}use{0} {6}v5.22{10};{0}\t\t\t{2}# may be needed\n{0}\n{2}#--------------------------------------------------------------------------\n# New bitwise operators\n#--------------------------------------------------------------------------\n{0}\n{5}use{0} {5}feature{0} {7}'bitwise'{0}\t\t{2}# enable feature, warning enabled\n{5}use{0} {5}experimental{0} {6}\"bitwise\"{10};{0}\t{2}# enable feature, warning disabled\n{0}\n{2}# numerical operands\n{4}10{10}&{4}20{0}  {4}10{10}|{4}20{0}   {4}10{10}^{4}20{0} {10}~{4}10{0}\n{12}$a{10}&{6}\"8\"{0} {12}$a{10}|{6}\"8\"{0} {12}$a{10}^{6}\"8\"{0} {10}~{12}$a{0} {10}~{6}\"8\"{0}\n\n{2}# string operands\n{7}'0'{10}&.{6}\"8\"{0} {7}'0'{10}|.{6}\"8\"{0} {7}'0'{10}^.{6}\"8\"{0} {10}~.{7}'0'{0} {10}~.{6}\"8\"{0}\n{2}# the following is AMBIGUOUS, perl sees 10 and not .10 only when bitwise feature is enabled\n# so it's feature-setting-dependent, no plans to change current behaviour\n{0} {12}$a{10}&{4}.10{0}   {12}$a{10}|{4}.10{0}   {12}$a{10}^{4}.10{0}  {10}~.{12}$a{0}  {10}~{4}.10{0}\n\n{2}# assignment variants\n{12}$a{10}&={4}10{10};{0}    {12}$a{10}|={4}10{10};{0}    {12}$a{10}^={4}10{10};{0}\n{12}$b{10}&.={7}'20'{10};{0} {12}$b{10}|.={7}'20'{10};{0} {12}$b{10}^.={7}'20'{10};{0}\n{12}$c{10}&={6}\"30\"{10};{0}  {12}$c{10}|={6}\"30\"{10};{0}  {12}$c{10}^={6}\"30\"{10};{0}\n{12}$d{10}&.={12}$e{10};{0}   {12}$d{10}|.={12}$e{10};{0}   {12}$d{10}^.={12}$e{10};{0}\n\n{2}#--------------------------------------------------------------------------\n# New double-diamond operator\n#--------------------------------------------------------------------------\n# <<>> is like <> but each element of @ARGV will be treated as an actual file name\n{0}\n{2}# example snippet from brian d foy's blog post\n{5}while{10}({0} {10}<<>>{0} {10}){0} {10}{{0}  {2}# new, safe line input operator\n{0}\t{10}...;{0}\n\t{10}}{0}\n\n{2}#--------------------------------------------------------------------------\n# New \\b boundaries in regular expressions\n#--------------------------------------------------------------------------\n{0}\n{29}qr/\\b{gcb}/{0}\n{29}qr/\\b{wb}/{0}\n{29}qr/\\b{sb}/{0}\n\n{2}#--------------------------------------------------------------------------\n# Non-Capturing Regular Expression Flag\n#--------------------------------------------------------------------------\n# disables capturing and filling in $1, $2, etc\n{0}\n{6}\"hello\"{0} {10}=~{0} {17}/(hi|hello)/n{10};{0} {2}# $1 is not set\n{0}\n{2}#--------------------------------------------------------------------------\n# Aliasing via reference\n#--------------------------------------------------------------------------\n# Variables and subroutines can now be aliased by assigning to a reference\n{0}\n{10}\\{12}$c{0} {10}={0} {10}\\{12}$d{10};{0}\n{10}\\&{11}x{0} {10}={0} {10}\\&{11}y{10};{0}\n\n{2}# Aliasing can also be applied to foreach iterator variables\n{0}\n{5}foreach{0} {10}\\{14}%hash{0} {10}({13}@array_of_hash_refs{10}){0} {10}{{0} {10}...{0} {10}}{0}\n\n{2}# example snippet from brian d foy's blog post\n{0}\n{5}use{0} {5}feature{0} {30}qw(refaliasing){10};{0}\n\n{10}\\{14}%other_hash{0} {10}={0} {10}\\{14}%hash{10};{0}\n\n{5}use{0} {6}v5.22{10};{0}\n{5}use{0} {5}feature{0} {30}qw(refaliasing){10};{0}\n\n{5}foreach{0} {10}\\{5}my{0} {14}%hash{0} {10}({0} {13}@array_of_hashes{0} {10}){0} {10}{{0} {2}# named hash control variable\n{0}\t{5}foreach{0} {5}my{0} {12}$key{0} {10}({0} {5}keys{0} {14}%hash{0} {10}){0} {10}{{0} {2}# named hash now!\n{0}\t\t{10}...;{0}\n\t\t{10}}{0}\n\t{10}}{0}\n\n{2}#--------------------------------------------------------------------------\n# New :const subroutine attribute\n#--------------------------------------------------------------------------\n{0}\n{5}my{0} {12}$x{0} {10}={0} {4}54321{10};{0}\n{15}*INLINED{0} {10}={0} {5}sub{0} {10}:{0} {11}const{0} {10}{{0} {12}$x{0} {10}};{0}\n{12}$x{10}++;{0}\n\n{2}# more examples of attributes\n# (not 5.22 stuff, but some general examples for study, useful for\n#  handling subroutine signature and subroutine prototype highlighting)\n{0}\n{5}sub{0} {11}foo{0} {10}:{0} {11}lvalue{0} {10};{0}\n\n{5}package{0} {11}X{10};{0}\n{5}sub{0} {11}Y{10}::{11}x{0} {10}:{0} {11}lvalue{0} {10}{{0} {4}1{0} {10}}{0}\n\n{5}package{0} {11}X{10};{0}\n{5}sub{0} {11}foo{0} {10}{{0} {4}1{0} {10}}{0}\n{5}package{0} {11}Y{10};{0}\n{5}BEGIN{0} {10}{{0} {15}*bar{0} {10}={0} {10}\\&{11}X{10}::{11}foo{10};{0} {10}}{0}\n{5}package{0} {11}Z{10};{0}\n{5}sub{0} {11}Y{10}::{11}bar{0} {10}:{0} {11}lvalue{0} {10};{0}\n\n{2}# built-in attributes for subroutines:\n{11}lvalue{0} {5}method{0} {11}prototype{10}(..){0} {11}locked{0} {11}const{0}\n\n{2}#--------------------------------------------------------------------------\n# Repetition in list assignment\n#--------------------------------------------------------------------------\n{0}\n{2}# example snippet from brian d foy's blog post\n{5}use{0} {6}v5.22{10};{0}\n{5}my{10}({5}undef{10},{0} {12}$card_num{10},{0} {10}({5}undef{10})x{4}3{10},{0} {12}$count{10}){0} {10}={0} {5}split{0} {17}/:/{10};{0}\n\n{10}({5}undef{10},{5}undef{10},{12}$foo{10}){0} {10}={0} {11}that_function{10}(){0}\n{2}# is equivalent to \n{10}(({5}undef{10})x{4}2{10},{0} {12}$foo{10}){0} {10}={0} {11}that_function{10}(){0}\n\n{2}#--------------------------------------------------------------------------\n# Floating point parsing has been improved\n#--------------------------------------------------------------------------\n# Hexadecimal floating point literals\n{0}\n{2}# some hex floats from a program by Rick Regan\n# appropriated and extended from Lua 5.2.x test cases\n# tested on perl 5.22/cygwin\n{0}\n{4}0x1p-1074{10};{0}\n{4}0x3.3333333333334p-5{10};{0}\n{4}0xcc.ccccccccccdp-11{10};{0}\n{4}0x1p+1{10};{0}\n{4}0x1p-6{10};{0}\n{4}0x1.b7p-1{10};{0}\n{4}0x1.fffffffffffffp+1023{10};{0}\n{4}0x1p-1022{10};{0}\n{4}0X1.921FB4D12D84AP+1{10};{0}\n{4}0x1.999999999999ap-4{10};{0}\n\n{2}# additional test cases for characterization\n{4}0x1p-1074{10}.{0}\t\t{2}# dot is a string operator\n{4}0x.ABCDEFp10{0}\t\t{2}# legal, dot immediately after 0x\n{4}0x{10}.{11}p10{0}\t\t\t{2}# perl allows 0x as a zero, then concat with p10 bareword\n{4}0x{10}.{11}p{0} {4}0x0{10}.{11}p{0}\t\t{2}# dot then bareword\n{4}0x_0_.A_BC___DEF_p1_0{0}\t{2}# legal hex float, underscores are mostly allowed\n{4}0x0{10}.{11}_ABCDEFp10{0}\t\t{2}# _ABCDEFp10 is a bareword, no underscore allowed after dot\n{0}\n{2}# illegal, but does not use error highlighting\n{4}0x0p1{11}ABC{0}\t\t{2}# illegal, highlighted as 0x0p1 abut with bareword ABC \n{0}\n{2}# allowed to FAIL for now\n{4}0x0.ABCDEFp_10{0}\t\t{2}# ABCDEFp_10 is a bareword, '_10' exponent not allowed\n{4}0xp{0} {4}0xp1{0} {4}0x0.0p{0}\t\t{2}# syntax errors\n{4}0x41.65{10}.{4}65{0} \t\t{2}# hex dot number, but lexer now fails with 0x41.65 left as a partial hex float\n{0}\n{2}#--------------------------------------------------------------------------\n# Support for ?PATTERN? without explicit operator has been removed\n#--------------------------------------------------------------------------\n# ?PATTERN? must now be written as m?PATTERN?\n{0}\n{10}?{11}PATTERN{10}?{0}\t{2}# does not work in current LexPerl anyway, NO ACTION NEEDED\n{17}m?PATTERN?{0}\n\n{2}#--------------------------------------------------------------------------\n# end of test file\n#--------------------------------------------------------------------------\n"
  },
  {
    "path": "test/examples/perl/perl-test-sub-prototypes.pl",
    "content": "# -*- coding: utf-8 -*-\n#--------------------------------------------------------------------------\n# perl-test-sub-prototypes.pl\n#--------------------------------------------------------------------------\n# compiled all relevant subroutine prototype test cases\n#\n#--------------------------------------------------------------------------\n# Kein-Hong Man <keinhong@gmail.com> Public Domain\n#--------------------------------------------------------------------------\n# 20151227\tinitial document\n#--------------------------------------------------------------------------\n\n#--------------------------------------------------------------------------\n# test cases for sub syntax scanner\n#--------------------------------------------------------------------------\n# sub syntax: simple and with added module notation\n#--------------------------------------------------------------------------\n\nsub fish($) { 123; }\nsub fish::chips($) { 123; }\t\t\t# module syntax\nsub fish::chips::sauce($) { 123; }\t\t# multiple module syntax\n\nsub fish :: chips  ::\t\tsauce ($) { 123; }\t# added whitespace\n\nsub fish :: # embedded comment\nchips \t# embedded comment\n :: sauce ($) { 123; }\n\nsub fish :: ($) { 123; }\t# incomplete or bad syntax examples\nsub fish :: 123 ($) { 123; }\nsub fish :: chips 123 ($) { 123; }\nsub 123 ($) { 123; }\n\n#--------------------------------------------------------------------------\n# sub syntax: prototype attributes\n#--------------------------------------------------------------------------\n\nsub fish:prototype($) { 123; }\nsub fish : prototype\t($) { 123; }\t\t# added whitespace\n\nsub fish:salted($) { 123; }\t# wrong attribute example (must use 'prototype')\nsub fish :  123($) { 123; }\t# illegal attribute\nsub fish:prototype:salted($) { 123; }\t# wrong 'prototype' position\nsub fish:salted salt:prototype($) { 123; }\t# wrong attribute syntax\n\nsub fish:const:prototype($) { 123; }\t\t# extra attributes\nsub fish:const:lvalue:prototype($) { 123; }\nsub fish:const:prototype($):lvalue{ 123; }\t# might be legal too\nsub fish  :const\t:prototype($) { 123; }\t# extra whitespace\n\nsub fish  :const\t# embedded comment: a constant sub\n:prototype\t\t# embedded comment\n($) { 123; }\n\n#--------------------------------------------------------------------------\n# sub syntax: mixed\n#--------------------------------------------------------------------------\n\nsub fish::chips:prototype($) { 123; }\nsub fish::chips::sauce:prototype($) { 123; }\nsub fish  ::chips  ::sauce\t:prototype($) { 123; }\t# +whitespace\n\nsub fish::chips::sauce:const:prototype($) { 123; }\nsub fish::chips::sauce\t:const\t:prototype($) { 123; }\t# +whitespace\n\nsub fish\t\t# embedded comment\n::chips\t::sauce\t\t# embedded comment\n  : const\t\t# embedded comment\n\t: prototype ($) { 123; }\n\n# wrong syntax examples, parentheses must follow ':prototype'\nsub fish :prototype :const ($) { 123;}\nsub fish :prototype ::chips ($) { 123;}\n\n#--------------------------------------------------------------------------\n# perl-test-5200delta.pl\n#--------------------------------------------------------------------------\n# More consistent prototype parsing\n#--------------------------------------------------------------------------\n# - whitespace now allowed, lexer now allows spaces or tabs\n\nsub foo ( $ $ ) {}\nsub foo ( \t\t\t ) {}\t\t# spaces/tabs empty\nsub foo (  *  ) {}\nsub foo (@\t) {}\nsub foo (\t%) {}\n\n# untested, should probably be \\[ but scanner does not check this for now\nsub foo ( \\ [ $ @ % & * ] ) {}\n\n#--------------------------------------------------------------------------\n# perl-test-5140delta.pl\n#--------------------------------------------------------------------------\n# new + prototype character, acts like (\\[@%])\n#--------------------------------------------------------------------------\n\n# these samples work as before\nsub mylink ($$)          # mylink $old, $new\nsub myvec ($$$)          # myvec $var, $offset, 1\nsub myindex ($$;$)       # myindex &getstring, \"substr\"\nsub mysyswrite ($$$;$)   # mysyswrite $buf, 0, length($buf) - $off, $off\nsub myreverse (@)        # myreverse $a, $b, $c\nsub myjoin ($@)          # myjoin \":\", $a, $b, $c\nsub myopen (*;$)         # myopen HANDLE, $name\nsub mypipe (**)          # mypipe READHANDLE, WRITEHANDLE\nsub mygrep (&@)          # mygrep { /foo/ } $a, $b, $c\nsub myrand (;$)          # myrand 42\nsub mytime ()            # mytime\n\n# backslash group notation to specify more than one allowed argument type\nsub myref (\\[$@%&*]) {}\n\nsub mysub (_)            # underscore can be optionally used FIXED 20151211\n\n# these uses the new '+' prototype character\nsub mypop (+)            # mypop @array\nsub mysplice (+$$@)      # mysplice @array, 0, 2, @pushme\nsub mykeys (+)           # mykeys %{$hashref}\n\n#--------------------------------------------------------------------------\n# perl-test-5200delta.pl\n#--------------------------------------------------------------------------\n# Experimental Subroutine signatures (mostly works)\n#--------------------------------------------------------------------------\n# INCLUDED FOR COMPLETENESS ONLY\n# IMPORTANT NOTE the subroutine prototypes lexing implementation has\n# no effect on subroutine signature syntax highlighting\n\n# subroutine signatures mostly looks fine except for the @ and % slurpy\n# notation which are highlighted as operators (all other parameters are\n# highlighted as vars of some sort), a minor aesthetic issue\n\nuse feature 'signatures';\n\nsub foo ($left, $right) {\t\t# mandatory positional parameters\n    return $left + $right;\n}\nsub foo ($first, $, $third) {\t\t# ignore second argument\n    return \"first=$first, third=$third\";\n}\nsub foo ($left, $right = 0) {\t\t# optional parameter with default value\n    return $left + $right;\n}\nmy $auto_id = 0;\t\t\t# default value expression, evaluated if default used only\nsub foo ($thing, $id = $auto_id++) {\n    print \"$thing has ID $id\";\n}\nsub foo ($first_name, $surname, $nickname = $first_name) {\t# 3rd parm may depend on 1st parm\n    print \"$first_name $surname is known as \\\"$nickname\\\"\";\n}\nsub foo ($thing, $ = 1) {\t\t# nameless default parameter\n    print $thing;\n}\nsub foo ($thing, $=) {\t\t\t# (this does something, I'm not sure what...)\n    print $thing;\n}\nsub foo ($filter, @inputs) {\t\t# additional arguments (slurpy parameter)\n    print $filter->($_) foreach @inputs;\n}\nsub foo ($thing, @) {\t\t\t# nameless slurpy parameter FAILS for now\n    print $thing;\n}\nsub foo ($filter, %inputs) {\t\t# slurpy parameter, hash type\n    print $filter->($_, $inputs{$_}) foreach sort keys %inputs;\n}\nsub foo ($thing, %) {\t\t\t# nameless slurpy parm, hash type FAILS for now\n    print $thing;\n}\nsub foo () {\t\t\t\t# empty signature no arguments (styled as prototype)\n    return 123;\n}\n\n#--------------------------------------------------------------------------\n# perl-test-5200delta.pl\n#--------------------------------------------------------------------------\n# subs now take a prototype attribute\n#--------------------------------------------------------------------------\n\nsub foo :prototype($) { $_[0] }\n\nsub foo :prototype($$) ($left, $right) {\n    return $left + $right;\n}\n\nsub foo : prototype($$){}\t\t# whitespace allowed\n\n# additional samples from perl-test-cases.pl with ':prototype' added:\nsub mylink :prototype($$) {}\t\tsub myvec :prototype($$$) {}\nsub myindex :prototype($$;$) {}\t\tsub mysyswrite :prototype($$$;$) {}\nsub myreverse :prototype(@) {}\t\tsub myjoin :prototype($@) {}\nsub mypop :prototype(\\@) {}\t\tsub mysplice :prototype(\\@$$@) {}\nsub mykeys :prototype(\\%) {}\t\tsub myopen :prototype(*;$) {}\nsub mypipe :prototype(**) {}\t\tsub mygrep :prototype(&@) {}\nsub myrand :prototype($) {}\t\tsub mytime :prototype() {}\n# backslash group notation to specify more than one allowed argument type\nsub myref :prototype(\\[$@%&*]) {}\n\n# additional attributes may complicate scanning for prototype syntax,\n# for example (from https://metacpan.org/pod/perlsub):\n# Lvalue subroutines\n\nmy $val;\nsub canmod : lvalue {\n    $val;  # or:  return $val;\n}\ncanmod() = 5;   # assigns to $val\n\n#--------------------------------------------------------------------------\n# perl-test-5220delta.pl\n#--------------------------------------------------------------------------\n# New :const subroutine attribute\n#--------------------------------------------------------------------------\n\nmy $x = 54321;\n*INLINED = sub : const { $x };\n$x++;\n\n# more examples of attributes\n# (not 5.22 stuff, but some general examples for study, useful for\n#  handling subroutine signature and subroutine prototype highlighting)\n\nsub foo : lvalue ;\n\npackage X;\nsub Y::z : lvalue { 1 }\n\npackage X;\nsub foo { 1 }\npackage Y;\nBEGIN { *bar = \\&X::foo; }\npackage Z;\nsub Y::bar : lvalue ;\n\n# built-in attributes for subroutines:\nlvalue method prototype(..) locked const\n\n#--------------------------------------------------------------------------\n# end of test file\n#--------------------------------------------------------------------------\n"
  },
  {
    "path": "test/examples/perl/perl-test-sub-prototypes.pl.folded",
    "content": " 2 400 401 + # -*- coding: utf-8 -*-\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # perl-test-sub-prototypes.pl\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # compiled all relevant subroutine prototype test cases\n 0 401 401 | #\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # Kein-Hong Man <keinhong@gmail.com> Public Domain\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # 20151227\tinitial document\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # test cases for sub syntax scanner\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # sub syntax: simple and with added module notation\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   sub fish($) { 123; }\n 0 400 400   sub fish::chips($) { 123; }\t\t\t# module syntax\n 0 400 400   sub fish::chips::sauce($) { 123; }\t\t# multiple module syntax\n 1 400 400   \n 0 400 400   sub fish :: chips  ::\t\tsauce ($) { 123; }\t# added whitespace\n 1 400 400   \n 0 400 400   sub fish :: # embedded comment\n 0 400 400   chips \t# embedded comment\n 0 400 400    :: sauce ($) { 123; }\n 1 400 400   \n 0 400 400   sub fish :: ($) { 123; }\t# incomplete or bad syntax examples\n 0 400 400   sub fish :: 123 ($) { 123; }\n 0 400 400   sub fish :: chips 123 ($) { 123; }\n 0 400 400   sub 123 ($) { 123; }\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # sub syntax: prototype attributes\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   sub fish:prototype($) { 123; }\n 0 400 400   sub fish : prototype\t($) { 123; }\t\t# added whitespace\n 1 400 400   \n 0 400 400   sub fish:salted($) { 123; }\t# wrong attribute example (must use 'prototype')\n 0 400 400   sub fish :  123($) { 123; }\t# illegal attribute\n 0 400 400   sub fish:prototype:salted($) { 123; }\t# wrong 'prototype' position\n 0 400 400   sub fish:salted salt:prototype($) { 123; }\t# wrong attribute syntax\n 1 400 400   \n 0 400 400   sub fish:const:prototype($) { 123; }\t\t# extra attributes\n 0 400 400   sub fish:const:lvalue:prototype($) { 123; }\n 0 400 400   sub fish:const:prototype($):lvalue{ 123; }\t# might be legal too\n 0 400 400   sub fish  :const\t:prototype($) { 123; }\t# extra whitespace\n 1 400 400   \n 0 400 400   sub fish  :const\t# embedded comment: a constant sub\n 0 400 400   :prototype\t\t# embedded comment\n 0 400 400   ($) { 123; }\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # sub syntax: mixed\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   sub fish::chips:prototype($) { 123; }\n 0 400 400   sub fish::chips::sauce:prototype($) { 123; }\n 0 400 400   sub fish  ::chips  ::sauce\t:prototype($) { 123; }\t# +whitespace\n 1 400 400   \n 0 400 400   sub fish::chips::sauce:const:prototype($) { 123; }\n 0 400 400   sub fish::chips::sauce\t:const\t:prototype($) { 123; }\t# +whitespace\n 1 400 400   \n 0 400 400   sub fish\t\t# embedded comment\n 0 400 400   ::chips\t::sauce\t\t# embedded comment\n 0 400 400     : const\t\t# embedded comment\n 0 400 400   \t: prototype ($) { 123; }\n 1 400 400   \n 0 400 400   # wrong syntax examples, parentheses must follow ':prototype'\n 0 400 400   sub fish :prototype :const ($) { 123;}\n 0 400 400   sub fish :prototype ::chips ($) { 123;}\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # perl-test-5200delta.pl\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # More consistent prototype parsing\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 400 | # - whitespace now allowed, lexer now allows spaces or tabs\n 1 400 400   \n 0 400 400   sub foo ( $ $ ) {}\n 0 400 400   sub foo ( \t\t\t ) {}\t\t# spaces/tabs empty\n 0 400 400   sub foo (  *  ) {}\n 0 400 400   sub foo (@\t) {}\n 0 400 400   sub foo (\t%) {}\n 1 400 400   \n 0 400 400   # untested, should probably be \\[ but scanner does not check this for now\n 0 400 400   sub foo ( \\ [ $ @ % & * ] ) {}\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # perl-test-5140delta.pl\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # new + prototype character, acts like (\\[@%])\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   # these samples work as before\n 0 400 400   sub mylink ($$)          # mylink $old, $new\n 0 400 400   sub myvec ($$$)          # myvec $var, $offset, 1\n 0 400 400   sub myindex ($$;$)       # myindex &getstring, \"substr\"\n 0 400 400   sub mysyswrite ($$$;$)   # mysyswrite $buf, 0, length($buf) - $off, $off\n 0 400 400   sub myreverse (@)        # myreverse $a, $b, $c\n 0 400 400   sub myjoin ($@)          # myjoin \":\", $a, $b, $c\n 0 400 400   sub myopen (*;$)         # myopen HANDLE, $name\n 0 400 400   sub mypipe (**)          # mypipe READHANDLE, WRITEHANDLE\n 0 400 400   sub mygrep (&@)          # mygrep { /foo/ } $a, $b, $c\n 0 400 400   sub myrand (;$)          # myrand 42\n 0 400 400   sub mytime ()            # mytime\n 1 400 400   \n 0 400 400   # backslash group notation to specify more than one allowed argument type\n 0 400 400   sub myref (\\[$@%&*]) {}\n 1 400 400   \n 0 400 400   sub mysub (_)            # underscore can be optionally used FIXED 20151211\n 1 400 400   \n 0 400 400   # these uses the new '+' prototype character\n 0 400 400   sub mypop (+)            # mypop @array\n 0 400 400   sub mysplice (+$$@)      # mysplice @array, 0, 2, @pushme\n 0 400 400   sub mykeys (+)           # mykeys %{$hashref}\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # perl-test-5200delta.pl\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # Experimental Subroutine signatures (mostly works)\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # INCLUDED FOR COMPLETENESS ONLY\n 0 401 401 | # IMPORTANT NOTE the subroutine prototypes lexing implementation has\n 0 401 400 | # no effect on subroutine signature syntax highlighting\n 1 400 400   \n 2 400 401 + # subroutine signatures mostly looks fine except for the @ and % slurpy\n 0 401 401 | # notation which are highlighted as operators (all other parameters are\n 0 401 400 | # highlighted as vars of some sort), a minor aesthetic issue\n 1 400 400   \n 0 400 400   use feature 'signatures';\n 1 400 400   \n 2 400 401 + sub foo ($left, $right) {\t\t# mandatory positional parameters\n 0 401 401 |     return $left + $right;\n 0 401 400 | }\n 2 400 401 + sub foo ($first, $, $third) {\t\t# ignore second argument\n 0 401 401 |     return \"first=$first, third=$third\";\n 0 401 400 | }\n 2 400 401 + sub foo ($left, $right = 0) {\t\t# optional parameter with default value\n 0 401 401 |     return $left + $right;\n 0 401 400 | }\n 0 400 400   my $auto_id = 0;\t\t\t# default value expression, evaluated if default used only\n 2 400 401 + sub foo ($thing, $id = $auto_id++) {\n 0 401 401 |     print \"$thing has ID $id\";\n 0 401 400 | }\n 2 400 401 + sub foo ($first_name, $surname, $nickname = $first_name) {\t# 3rd parm may depend on 1st parm\n 0 401 401 |     print \"$first_name $surname is known as \\\"$nickname\\\"\";\n 0 401 400 | }\n 2 400 401 + sub foo ($thing, $ = 1) {\t\t# nameless default parameter\n 0 401 401 |     print $thing;\n 0 401 400 | }\n 2 400 401 + sub foo ($thing, $=) {\t\t\t# (this does something, I'm not sure what...)\n 0 401 401 |     print $thing;\n 0 401 400 | }\n 2 400 401 + sub foo ($filter, @inputs) {\t\t# additional arguments (slurpy parameter)\n 0 401 401 |     print $filter->($_) foreach @inputs;\n 0 401 400 | }\n 2 400 401 + sub foo ($thing, @) {\t\t\t# nameless slurpy parameter FAILS for now\n 0 401 401 |     print $thing;\n 0 401 400 | }\n 2 400 401 + sub foo ($filter, %inputs) {\t\t# slurpy parameter, hash type\n 0 401 401 |     print $filter->($_, $inputs{$_}) foreach sort keys %inputs;\n 0 401 400 | }\n 2 400 401 + sub foo ($thing, %) {\t\t\t# nameless slurpy parm, hash type FAILS for now\n 0 401 401 |     print $thing;\n 0 401 400 | }\n 2 400 401 + sub foo () {\t\t\t\t# empty signature no arguments (styled as prototype)\n 0 401 401 |     return 123;\n 0 401 400 | }\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # perl-test-5200delta.pl\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # subs now take a prototype attribute\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   sub foo :prototype($) { $_[0] }\n 1 400 400   \n 2 400 401 + sub foo :prototype($$) ($left, $right) {\n 0 401 401 |     return $left + $right;\n 0 401 400 | }\n 1 400 400   \n 0 400 400   sub foo : prototype($$){}\t\t# whitespace allowed\n 1 400 400   \n 0 400 400   # additional samples from perl-test-cases.pl with ':prototype' added:\n 0 400 400   sub mylink :prototype($$) {}\t\tsub myvec :prototype($$$) {}\n 0 400 400   sub myindex :prototype($$;$) {}\t\tsub mysyswrite :prototype($$$;$) {}\n 0 400 400   sub myreverse :prototype(@) {}\t\tsub myjoin :prototype($@) {}\n 0 400 400   sub mypop :prototype(\\@) {}\t\tsub mysplice :prototype(\\@$$@) {}\n 0 400 400   sub mykeys :prototype(\\%) {}\t\tsub myopen :prototype(*;$) {}\n 0 400 400   sub mypipe :prototype(**) {}\t\tsub mygrep :prototype(&@) {}\n 0 400 400   sub myrand :prototype($) {}\t\tsub mytime :prototype() {}\n 0 400 400   # backslash group notation to specify more than one allowed argument type\n 0 400 400   sub myref :prototype(\\[$@%&*]) {}\n 1 400 400   \n 2 400 401 + # additional attributes may complicate scanning for prototype syntax,\n 0 401 401 | # for example (from https://metacpan.org/pod/perlsub):\n 0 401 400 | # Lvalue subroutines\n 1 400 400   \n 0 400 400   my $val;\n 2 400 401 + sub canmod : lvalue {\n 0 401 401 |     $val;  # or:  return $val;\n 0 401 400 | }\n 0 400 400   canmod() = 5;   # assigns to $val\n 1 400 400   \n 2 400 401 + #--------------------------------------------------------------------------\n 0 401 401 | # perl-test-5220delta.pl\n 0 401 401 | #--------------------------------------------------------------------------\n 0 401 401 | # New :const subroutine attribute\n 0 401 400 | #--------------------------------------------------------------------------\n 1 400 400   \n 0 400 400   my $x = 54321;\n 0 400 400   *INLINED = sub : const { $x };\n 0 400 400   $x++;\n 1 400 400   \n 2 400 401 + # more examples of attributes\n 0 401 401 | # (not 5.22 stuff, but some general examples for study, useful for\n 0 401 400 | #  handling subroutine signature and subroutine prototype highlighting)\n 1 400 400   \n 0 400 400   sub foo : lvalue ;\n 1 400 400   \n 2 400 401 + package X;\n 0 401 401 | sub Y::z : lvalue { 1 }\n 1 401 401 | \n 2 400 401 + package X;\n 0 401 401 | sub foo { 1 }\n 2 400 401 + package Y;\n 0 401 401 | BEGIN { *bar = \\&X::foo; }\n 2 400 401 + package Z;\n 0 401 401 | sub Y::bar : lvalue ;\n 1 401 401 | \n 0 401 401 | # built-in attributes for subroutines:\n 0 401 401 | lvalue method prototype(..) locked const\n 1 401 401 | \n 2 401 402 + #--------------------------------------------------------------------------\n 0 402 402 | # end of test file\n 0 402 401 | #--------------------------------------------------------------------------\n 0 401   0 | "
  },
  {
    "path": "test/examples/perl/perl-test-sub-prototypes.pl.styled",
    "content": "{2}# -*- coding: utf-8 -*-\n#--------------------------------------------------------------------------\n# perl-test-sub-prototypes.pl\n#--------------------------------------------------------------------------\n# compiled all relevant subroutine prototype test cases\n#\n#--------------------------------------------------------------------------\n# Kein-Hong Man <keinhong@gmail.com> Public Domain\n#--------------------------------------------------------------------------\n# 20151227\tinitial document\n#--------------------------------------------------------------------------\n{0}\n{2}#--------------------------------------------------------------------------\n# test cases for sub syntax scanner\n#--------------------------------------------------------------------------\n# sub syntax: simple and with added module notation\n#--------------------------------------------------------------------------\n{0}\n{5}sub{0} {11}fish{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\n{5}sub{0} {11}fish{10}::{11}chips{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\t\t\t{2}# module syntax\n{5}sub{0} {11}fish{10}::{11}chips{10}::{11}sauce{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\t\t{2}# multiple module syntax\n{0}\n{5}sub{0} {11}fish{0} {10}::{0} {11}chips{0}  {10}::{0}\t\t{11}sauce{0} {40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\t{2}# added whitespace\n{0}\n{5}sub{0} {11}fish{0} {10}::{0} {2}# embedded comment\n{11}chips{0} \t{2}# embedded comment\n{0} {10}::{0} {11}sauce{0} {40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\n\n{5}sub{0} {11}fish{0} {10}::{0} {10}({12}$){0} {10}{{0} {4}123{10};{0} {10}}{0}\t{2}# incomplete or bad syntax examples\n{5}sub{0} {11}fish{0} {10}::{0} {4}123{0} {10}({12}$){0} {10}{{0} {4}123{10};{0} {10}}{0}\n{5}sub{0} {11}fish{0} {10}::{0} {11}chips{0} {4}123{0} {10}({12}$){0} {10}{{0} {4}123{10};{0} {10}}{0}\n{5}sub{0} {4}123{0} {10}({12}$){0} {10}{{0} {4}123{10};{0} {10}}{0}\n\n{2}#--------------------------------------------------------------------------\n# sub syntax: prototype attributes\n#--------------------------------------------------------------------------\n{0}\n{5}sub{0} {11}fish{10}:{5}prototype{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\n{5}sub{0} {11}fish{0} {10}:{0} {5}prototype{0}\t{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\t\t{2}# added whitespace\n{0}\n{5}sub{0} {11}fish{10}:{11}salted{10}({12}$){0} {10}{{0} {4}123{10};{0} {10}}{0}\t{2}# wrong attribute example (must use 'prototype')\n{5}sub{0} {11}fish{0} {10}:{0}  {4}123{10}({12}$){0} {10}{{0} {4}123{10};{0} {10}}{0}\t{2}# illegal attribute\n{5}sub{0} {11}fish{10}:{5}prototype{10}:{11}salted{10}({12}$){0} {10}{{0} {4}123{10};{0} {10}}{0}\t{2}# wrong 'prototype' position\n{5}sub{0} {11}fish{10}:{11}salted{0} {11}salt{10}:{5}prototype{10}({12}$){0} {10}{{0} {4}123{10};{0} {10}}{0}\t{2}# wrong attribute syntax\n{0}\n{5}sub{0} {11}fish{10}:{11}const{10}:{5}prototype{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\t\t{2}# extra attributes\n{5}sub{0} {11}fish{10}:{11}const{10}:{11}lvalue{10}:{5}prototype{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\n{5}sub{0} {11}fish{10}:{11}const{10}:{5}prototype{40}($){10}:{11}lvalue{10}{{0} {4}123{10};{0} {10}}{0}\t{2}# might be legal too\n{5}sub{0} {11}fish{0}  {10}:{11}const{0}\t{10}:{5}prototype{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\t{2}# extra whitespace\n{0}\n{5}sub{0} {11}fish{0}  {10}:{11}const{0}\t{2}# embedded comment: a constant sub\n{10}:{5}prototype{0}\t\t{2}# embedded comment\n{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\n\n{2}#--------------------------------------------------------------------------\n# sub syntax: mixed\n#--------------------------------------------------------------------------\n{0}\n{5}sub{0} {11}fish{10}::{11}chips{10}:{5}prototype{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\n{5}sub{0} {11}fish{10}::{11}chips{10}::{11}sauce{10}:{5}prototype{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\n{5}sub{0} {11}fish{0}  {10}::{11}chips{0}  {10}::{11}sauce{0}\t{10}:{5}prototype{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\t{2}# +whitespace\n{0}\n{5}sub{0} {11}fish{10}::{11}chips{10}::{11}sauce{10}:{11}const{10}:{5}prototype{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\n{5}sub{0} {11}fish{10}::{11}chips{10}::{11}sauce{0}\t{10}:{11}const{0}\t{10}:{5}prototype{40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\t{2}# +whitespace\n{0}\n{5}sub{0} {11}fish{0}\t\t{2}# embedded comment\n{10}::{11}chips{0}\t{10}::{11}sauce{0}\t\t{2}# embedded comment\n{0}  {10}:{0} {11}const{0}\t\t{2}# embedded comment\n{0}\t{10}:{0} {5}prototype{0} {40}($){0} {10}{{0} {4}123{10};{0} {10}}{0}\n\n{2}# wrong syntax examples, parentheses must follow ':prototype'\n{5}sub{0} {11}fish{0} {10}:{5}prototype{0} {10}:{11}const{0} {10}({12}$){0} {10}{{0} {4}123{10};}{0}\n{5}sub{0} {11}fish{0} {10}:{5}prototype{0} {10}::{11}chips{0} {10}({12}$){0} {10}{{0} {4}123{10};}{0}\n\n{2}#--------------------------------------------------------------------------\n# perl-test-5200delta.pl\n#--------------------------------------------------------------------------\n# More consistent prototype parsing\n#--------------------------------------------------------------------------\n# - whitespace now allowed, lexer now allows spaces or tabs\n{0}\n{5}sub{0} {11}foo{0} {40}( $ $ ){0} {10}{}{0}\n{5}sub{0} {11}foo{0} {40}( \t\t\t ){0} {10}{}{0}\t\t{2}# spaces/tabs empty\n{5}sub{0} {11}foo{0} {40}(  *  ){0} {10}{}{0}\n{5}sub{0} {11}foo{0} {40}(@\t){0} {10}{}{0}\n{5}sub{0} {11}foo{0} {40}(\t%){0} {10}{}{0}\n\n{2}# untested, should probably be \\[ but scanner does not check this for now\n{5}sub{0} {11}foo{0} {40}( \\ [ $ @ % & * ] ){0} {10}{}{0}\n\n{2}#--------------------------------------------------------------------------\n# perl-test-5140delta.pl\n#--------------------------------------------------------------------------\n# new + prototype character, acts like (\\[@%])\n#--------------------------------------------------------------------------\n{0}\n{2}# these samples work as before\n{5}sub{0} {11}mylink{0} {40}($$){0}          {2}# mylink $old, $new\n{5}sub{0} {11}myvec{0} {40}($$$){0}          {2}# myvec $var, $offset, 1\n{5}sub{0} {11}myindex{0} {40}($$;$){0}       {2}# myindex &getstring, \"substr\"\n{5}sub{0} {11}mysyswrite{0} {40}($$$;$){0}   {2}# mysyswrite $buf, 0, length($buf) - $off, $off\n{5}sub{0} {11}myreverse{0} {40}(@){0}        {2}# myreverse $a, $b, $c\n{5}sub{0} {11}myjoin{0} {40}($@){0}          {2}# myjoin \":\", $a, $b, $c\n{5}sub{0} {11}myopen{0} {40}(*;$){0}         {2}# myopen HANDLE, $name\n{5}sub{0} {11}mypipe{0} {40}(**){0}          {2}# mypipe READHANDLE, WRITEHANDLE\n{5}sub{0} {11}mygrep{0} {40}(&@){0}          {2}# mygrep { /foo/ } $a, $b, $c\n{5}sub{0} {11}myrand{0} {40}(;$){0}          {2}# myrand 42\n{5}sub{0} {11}mytime{0} {40}(){0}            {2}# mytime\n{0}\n{2}# backslash group notation to specify more than one allowed argument type\n{5}sub{0} {11}myref{0} {40}(\\[$@%&*]){0} {10}{}{0}\n\n{5}sub{0} {11}mysub{0} {40}(_){0}            {2}# underscore can be optionally used FIXED 20151211\n{0}\n{2}# these uses the new '+' prototype character\n{5}sub{0} {11}mypop{0} {40}(+){0}            {2}# mypop @array\n{5}sub{0} {11}mysplice{0} {40}(+$$@){0}      {2}# mysplice @array, 0, 2, @pushme\n{5}sub{0} {11}mykeys{0} {40}(+){0}           {2}# mykeys %{$hashref}\n{0}\n{2}#--------------------------------------------------------------------------\n# perl-test-5200delta.pl\n#--------------------------------------------------------------------------\n# Experimental Subroutine signatures (mostly works)\n#--------------------------------------------------------------------------\n# INCLUDED FOR COMPLETENESS ONLY\n# IMPORTANT NOTE the subroutine prototypes lexing implementation has\n# no effect on subroutine signature syntax highlighting\n{0}\n{2}# subroutine signatures mostly looks fine except for the @ and % slurpy\n# notation which are highlighted as operators (all other parameters are\n# highlighted as vars of some sort), a minor aesthetic issue\n{0}\n{5}use{0} {5}feature{0} {7}'signatures'{10};{0}\n\n{5}sub{0} {11}foo{0} {10}({12}$left{10},{0} {12}$right{10}){0} {10}{{0}\t\t{2}# mandatory positional parameters\n{0}    {5}return{0} {12}$left{0} {10}+{0} {12}$right{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {10}({12}$first{10},{0} {12}$,{0} {12}$third{10}){0} {10}{{0}\t\t{2}# ignore second argument\n{0}    {5}return{0} {6}\"first={43}$first{6}, third={43}$third{6}\"{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {10}({12}$left{10},{0} {12}$right{0} {10}={0} {4}0{10}){0} {10}{{0}\t\t{2}# optional parameter with default value\n{0}    {5}return{0} {12}$left{0} {10}+{0} {12}$right{10};{0}\n{10}}{0}\n{5}my{0} {12}$auto_id{0} {10}={0} {4}0{10};{0}\t\t\t{2}# default value expression, evaluated if default used only\n{5}sub{0} {11}foo{0} {10}({12}$thing{10},{0} {12}$id{0} {10}={0} {12}$auto_id{10}++){0} {10}{{0}\n    {5}print{0} {6}\"{43}$thing{6} has ID {43}$id{6}\"{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {10}({12}$first_name{10},{0} {12}$surname{10},{0} {12}$nickname{0} {10}={0} {12}$first_name{10}){0} {10}{{0}\t{2}# 3rd parm may depend on 1st parm\n{0}    {5}print{0} {6}\"{43}$first_name{6} {43}$surname{6} is known as \\\"{43}$nickname{6}\\\"\"{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {10}({12}$thing{10},{0} {12}${0} {10}={0} {4}1{10}){0} {10}{{0}\t\t{2}# nameless default parameter\n{0}    {5}print{0} {12}$thing{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {10}({12}$thing{10},{0} {12}$={10}){0} {10}{{0}\t\t\t{2}# (this does something, I'm not sure what...)\n{0}    {5}print{0} {12}$thing{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {10}({12}$filter{10},{0} {13}@inputs{10}){0} {10}{{0}\t\t{2}# additional arguments (slurpy parameter)\n{0}    {5}print{0} {12}$filter{10}->({12}$_{10}){0} {5}foreach{0} {13}@inputs{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {10}({12}$thing{10},{0} {10}@){0} {10}{{0}\t\t\t{2}# nameless slurpy parameter FAILS for now\n{0}    {5}print{0} {12}$thing{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {10}({12}$filter{10},{0} {14}%inputs{10}){0} {10}{{0}\t\t{2}# slurpy parameter, hash type\n{0}    {5}print{0} {12}$filter{10}->({12}$_{10},{0} {12}$inputs{10}{{12}$_{10}}){0} {5}foreach{0} {5}sort{0} {5}keys{0} {14}%inputs{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {10}({12}$thing{10},{0} {10}%){0} {10}{{0}\t\t\t{2}# nameless slurpy parm, hash type FAILS for now\n{0}    {5}print{0} {12}$thing{10};{0}\n{10}}{0}\n{5}sub{0} {11}foo{0} {40}(){0} {10}{{0}\t\t\t\t{2}# empty signature no arguments (styled as prototype)\n{0}    {5}return{0} {4}123{10};{0}\n{10}}{0}\n\n{2}#--------------------------------------------------------------------------\n# perl-test-5200delta.pl\n#--------------------------------------------------------------------------\n# subs now take a prototype attribute\n#--------------------------------------------------------------------------\n{0}\n{5}sub{0} {11}foo{0} {10}:{5}prototype{40}($){0} {10}{{0} {12}$_{10}[{4}0{10}]{0} {10}}{0}\n\n{5}sub{0} {11}foo{0} {10}:{5}prototype{40}($$){0} {10}({12}$left{10},{0} {12}$right{10}){0} {10}{{0}\n    {5}return{0} {12}$left{0} {10}+{0} {12}$right{10};{0}\n{10}}{0}\n\n{5}sub{0} {11}foo{0} {10}:{0} {5}prototype{40}($$){10}{}{0}\t\t{2}# whitespace allowed\n{0}\n{2}# additional samples from perl-test-cases.pl with ':prototype' added:\n{5}sub{0} {11}mylink{0} {10}:{5}prototype{40}($$){0} {10}{}{0}\t\t{5}sub{0} {11}myvec{0} {10}:{5}prototype{40}($$$){0} {10}{}{0}\n{5}sub{0} {11}myindex{0} {10}:{5}prototype{40}($$;$){0} {10}{}{0}\t\t{5}sub{0} {11}mysyswrite{0} {10}:{5}prototype{40}($$$;$){0} {10}{}{0}\n{5}sub{0} {11}myreverse{0} {10}:{5}prototype{40}(@){0} {10}{}{0}\t\t{5}sub{0} {11}myjoin{0} {10}:{5}prototype{40}($@){0} {10}{}{0}\n{5}sub{0} {11}mypop{0} {10}:{5}prototype{40}(\\@){0} {10}{}{0}\t\t{5}sub{0} {11}mysplice{0} {10}:{5}prototype{40}(\\@$$@){0} {10}{}{0}\n{5}sub{0} {11}mykeys{0} {10}:{5}prototype{40}(\\%){0} {10}{}{0}\t\t{5}sub{0} {11}myopen{0} {10}:{5}prototype{40}(*;$){0} {10}{}{0}\n{5}sub{0} {11}mypipe{0} {10}:{5}prototype{40}(**){0} {10}{}{0}\t\t{5}sub{0} {11}mygrep{0} {10}:{5}prototype{40}(&@){0} {10}{}{0}\n{5}sub{0} {11}myrand{0} {10}:{5}prototype{40}($){0} {10}{}{0}\t\t{5}sub{0} {11}mytime{0} {10}:{5}prototype{40}(){0} {10}{}{0}\n{2}# backslash group notation to specify more than one allowed argument type\n{5}sub{0} {11}myref{0} {10}:{5}prototype{40}(\\[$@%&*]){0} {10}{}{0}\n\n{2}# additional attributes may complicate scanning for prototype syntax,\n# for example (from https://metacpan.org/pod/perlsub):\n# Lvalue subroutines\n{0}\n{5}my{0} {12}$val{10};{0}\n{5}sub{0} {11}canmod{0} {10}:{0} {11}lvalue{0} {10}{{0}\n    {12}$val{10};{0}  {2}# or:  return $val;\n{10}}{0}\n{11}canmod{10}(){0} {10}={0} {4}5{10};{0}   {2}# assigns to $val\n{0}\n{2}#--------------------------------------------------------------------------\n# perl-test-5220delta.pl\n#--------------------------------------------------------------------------\n# New :const subroutine attribute\n#--------------------------------------------------------------------------\n{0}\n{5}my{0} {12}$x{0} {10}={0} {4}54321{10};{0}\n{15}*INLINED{0} {10}={0} {5}sub{0} {10}:{0} {11}const{0} {10}{{0} {12}$x{0} {10}};{0}\n{12}$x{10}++;{0}\n\n{2}# more examples of attributes\n# (not 5.22 stuff, but some general examples for study, useful for\n#  handling subroutine signature and subroutine prototype highlighting)\n{0}\n{5}sub{0} {11}foo{0} {10}:{0} {11}lvalue{0} {10};{0}\n\n{5}package{0} {11}X{10};{0}\n{5}sub{0} {11}Y{10}::{11}z{0} {10}:{0} {11}lvalue{0} {10}{{0} {4}1{0} {10}}{0}\n\n{5}package{0} {11}X{10};{0}\n{5}sub{0} {11}foo{0} {10}{{0} {4}1{0} {10}}{0}\n{5}package{0} {11}Y{10};{0}\n{5}BEGIN{0} {10}{{0} {15}*bar{0} {10}={0} {10}\\&{11}X{10}::{11}foo{10};{0} {10}}{0}\n{5}package{0} {11}Z{10};{0}\n{5}sub{0} {11}Y{10}::{11}bar{0} {10}:{0} {11}lvalue{0} {10};{0}\n\n{2}# built-in attributes for subroutines:\n{11}lvalue{0} {5}method{0} {11}prototype{10}(..){0} {11}locked{0} {11}const{0}\n\n{2}#--------------------------------------------------------------------------\n# end of test file\n#--------------------------------------------------------------------------\n"
  },
  {
    "path": "test/examples/perl/x.pl",
    "content": "use strict;\nwhile ( $r ) {\n  printf ( \"Example text \\n\" );\n  sleep 1;\n}"
  },
  {
    "path": "test/examples/perl/x.pl.folded",
    "content": " 0 400 400   use strict;\n 2 400 401 + while ( $r ) {\n 0 401 401 |   printf ( \"Example text \\n\" );\n 0 401 401 |   sleep 1;\n 0 401   0 | }"
  },
  {
    "path": "test/examples/perl/x.pl.styled",
    "content": "{5}use{0} {5}strict{10};{0}\n{5}while{0} {10}({0} {12}$r{0} {10}){0} {10}{{0}\n  {5}printf{0} {10}({0} {6}\"Example text \\n\"{0} {10});{0}\n  {5}sleep{0} {4}1{10};{0}\n{10}}"
  },
  {
    "path": "test/examples/powershell/AllStyles.ps1",
    "content": "# Enumerate all styles: 0 to 16\n\n# line comment = 1\n# more comment\n\n# whitespace = 0\n    # spaces\n\n# string = 2\n\"a string\"\n\n# character = 3\n'c'\n\n# number = 4\n123\n\n# variable = 5\n$variable\n\n# operator = 6\n();\n\n# identifier = 7\nidentifier\n\n# keyword = 8\nbreak\n;\n\n# cmdlet = 9\nWrite-Output \"test output\"\n\n# alias = 10\nchdir C:\\Temp\\\n\n# function = 11\nGet-Verb -Group Security\n\n# user-defined keyword = 12\nlexilla\n\n# multi-line comment = 13\n<#\nmulti-line comment\n#>\n\n# here string = 14\n@\"\nhere string double\n\"@\n\n# here string single quote = 15\n@'\nhere string single\n'@\n\n# comment keyword = 16\n<#\n.synopsis\nEnd of file.\n#>\n"
  },
  {
    "path": "test/examples/powershell/AllStyles.ps1.folded",
    "content": " 0 400 400   # Enumerate all styles: 0 to 16\n 1 400 400   \n 0 400 400   # line comment = 1\n 0 400 400   # more comment\n 1 400 400   \n 0 400 400   # whitespace = 0\n 0 400 400       # spaces\n 1 400 400   \n 0 400 400   # string = 2\n 0 400 400   \"a string\"\n 1 400 400   \n 0 400 400   # character = 3\n 0 400 400   'c'\n 1 400 400   \n 0 400 400   # number = 4\n 0 400 400   123\n 1 400 400   \n 0 400 400   # variable = 5\n 0 400 400   $variable\n 1 400 400   \n 0 400 400   # operator = 6\n 0 400 400   ();\n 1 400 400   \n 0 400 400   # identifier = 7\n 0 400 400   identifier\n 1 400 400   \n 0 400 400   # keyword = 8\n 0 400 400   break\n 0 400 400   ;\n 1 400 400   \n 0 400 400   # cmdlet = 9\n 0 400 400   Write-Output \"test output\"\n 1 400 400   \n 0 400 400   # alias = 10\n 0 400 400   chdir C:\\Temp\\\n 1 400 400   \n 0 400 400   # function = 11\n 0 400 400   Get-Verb -Group Security\n 1 400 400   \n 0 400 400   # user-defined keyword = 12\n 0 400 400   lexilla\n 1 400 400   \n 0 400 400   # multi-line comment = 13\n 0 400 400   <#\n 0 400 400   multi-line comment\n 0 400 400   #>\n 1 400 400   \n 0 400 400   # here string = 14\n 0 400 400   @\"\n 0 400 400   here string double\n 0 400 400   \"@\n 1 400 400   \n 0 400 400   # here string single quote = 15\n 0 400 400   @'\n 0 400 400   here string single\n 0 400 400   '@\n 1 400 400   \n 0 400 400   # comment keyword = 16\n 0 400 400   <#\n 0 400 400   .synopsis\n 0 400 400   End of file.\n 0 400 400   #>\n 0 400   0   "
  },
  {
    "path": "test/examples/powershell/AllStyles.ps1.styled",
    "content": "{1}# Enumerate all styles: 0 to 16{0}\n\n{1}# line comment = 1{0}\n{1}# more comment{0}\n\n{1}# whitespace = 0{0}\n    {1}# spaces{0}\n\n{1}# string = 2{0}\n{2}\"a string\"{0}\n\n{1}# character = 3{0}\n{3}'c'{0}\n\n{1}# number = 4{0}\n{4}123{0}\n\n{1}# variable = 5{0}\n{5}$variable{0}\n\n{1}# operator = 6{0}\n{6}();{0}\n\n{1}# identifier = 7{0}\n{7}identifier{0}\n\n{1}# keyword = 8{0}\n{8}break{0}\n{6};{0}\n\n{1}# cmdlet = 9{0}\n{9}Write-Output{0} {2}\"test output\"{0}\n\n{1}# alias = 10{0}\n{10}chdir{0} {7}C{6}:{0}\\{7}Temp{0}\\\n\n{1}# function = 11{0}\n{11}Get-Verb{0} {6}-{7}Group{0} {7}Security{0}\n\n{1}# user-defined keyword = 12{0}\n{12}lexilla{0}\n\n{1}# multi-line comment = 13{0}\n{13}<#\nmulti-line comment\n#>{0}\n\n{1}# here string = 14{0}\n{14}@\"\nhere string double\n\"@{0}\n\n{1}# here string single quote = 15{0}\n{15}@'\nhere string single\n'@{0}\n\n{1}# comment keyword = 16{0}\n{13}<#\n{16}.synopsis{13}\nEnd of file.\n#>{0}\n"
  },
  {
    "path": "test/examples/powershell/CharacterTruncation.ps1",
    "content": "# -*- coding: utf-8 -*-\n# Show problem with character value truncation causing U+0121 'ġ' (LATIN SMALL LETTER G WITH DOT ABOVE)\n# to be styled as an operator as static_cast<char>(0x121) = 0x21 == '!' which is an operator\n\n# Isolate\nġ\n\n# Continuing from operator\n(ġ)\n"
  },
  {
    "path": "test/examples/powershell/CharacterTruncation.ps1.folded",
    "content": " 0 400 400   # -*- coding: utf-8 -*-\n 0 400 400   # Show problem with character value truncation causing U+0121 'ġ' (LATIN SMALL LETTER G WITH DOT ABOVE)\n 0 400 400   # to be styled as an operator as static_cast<char>(0x121) = 0x21 == '!' which is an operator\n 1 400 400   \n 0 400 400   # Isolate\n 0 400 400   ġ\n 1 400 400   \n 0 400 400   # Continuing from operator\n 0 400 400   (ġ)\n 0 400   0   "
  },
  {
    "path": "test/examples/powershell/CharacterTruncation.ps1.styled",
    "content": "{1}# -*- coding: utf-8 -*-{0}\n{1}# Show problem with character value truncation causing U+0121 'ġ' (LATIN SMALL LETTER G WITH DOT ABOVE){0}\n{1}# to be styled as an operator as static_cast<char>(0x121) = 0x21 == '!' which is an operator{0}\n\n{1}# Isolate{0}\n{7}ġ{0}\n\n{1}# Continuing from operator{0}\n{6}({7}ġ{6}){0}\n"
  },
  {
    "path": "test/examples/powershell/NumericLiterals.ps1",
    "content": "# Treat any leading [-+] as default to reduce match complexity\n# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_numeric_literals?view=powershell-7.3#examples\n100\n100u\n100D\n100l\n100uL\n100us\n100uy\n100y\n1e2\n1.e2\n0x1e2\n0x1e2L\n0x1e2D\n482D\n482gb\n482ngb\n0x1e2lgb\n0b1011011\n0xFFFFs\n0xFFFFFFFF\n-0xFFFFFFFF\n0xFFFFFFFFu\n\n# Float\n0.5\n.5\n\n# Range\n1..100\n\n# Issue118: 7d is numeric while 7z is user defined keyword\n7d\n7z\n"
  },
  {
    "path": "test/examples/powershell/NumericLiterals.ps1.folded",
    "content": " 0 400 400   # Treat any leading [-+] as default to reduce match complexity\n 0 400 400   # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_numeric_literals?view=powershell-7.3#examples\n 0 400 400   100\n 0 400 400   100u\n 0 400 400   100D\n 0 400 400   100l\n 0 400 400   100uL\n 0 400 400   100us\n 0 400 400   100uy\n 0 400 400   100y\n 0 400 400   1e2\n 0 400 400   1.e2\n 0 400 400   0x1e2\n 0 400 400   0x1e2L\n 0 400 400   0x1e2D\n 0 400 400   482D\n 0 400 400   482gb\n 0 400 400   482ngb\n 0 400 400   0x1e2lgb\n 0 400 400   0b1011011\n 0 400 400   0xFFFFs\n 0 400 400   0xFFFFFFFF\n 0 400 400   -0xFFFFFFFF\n 0 400 400   0xFFFFFFFFu\n 1 400 400   \n 0 400 400   # Float\n 0 400 400   0.5\n 0 400 400   .5\n 1 400 400   \n 0 400 400   # Range\n 0 400 400   1..100\n 1 400 400   \n 0 400 400   # Issue118: 7d is numeric while 7z is user defined keyword\n 0 400 400   7d\n 0 400 400   7z\n 0 400   0   "
  },
  {
    "path": "test/examples/powershell/NumericLiterals.ps1.styled",
    "content": "{1}# Treat any leading [-+] as default to reduce match complexity{0}\n{1}# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_numeric_literals?view=powershell-7.3#examples{0}\n{4}100{0}\n{4}100u{0}\n{4}100D{0}\n{4}100l{0}\n{4}100uL{0}\n{4}100us{0}\n{4}100uy{0}\n{4}100y{0}\n{4}1e2{0}\n{4}1.e2{0}\n{4}0x1e2{0}\n{4}0x1e2L{0}\n{4}0x1e2D{0}\n{4}482D{0}\n{4}482gb{0}\n{4}482ngb{0}\n{4}0x1e2lgb{0}\n{4}0b1011011{0}\n{4}0xFFFFs{0}\n{4}0xFFFFFFFF{0}\n{6}-{4}0xFFFFFFFF{0}\n{4}0xFFFFFFFFu{0}\n\n{1}# Float{0}\n{4}0.5{0}\n{4}.5{0}\n\n{1}# Range{0}\n{4}1{6}..{4}100{0}\n\n{1}# Issue118: 7d is numeric while 7z is user defined keyword{0}\n{4}7d{0}\n{12}7z{0}\n"
  },
  {
    "path": "test/examples/powershell/Pull92.ps1",
    "content": "<# Tests for PowerShell #>\n\n<# Backticks should escape in double quoted strings #>\n$double_quote_str_esc_1 = \"`\"XXX`\"\"\n$double_quote_str_esc_2 = \"This `\"string`\" `$useses `r`n Backticks '``'\"\n\n<# Backticks should be ignored in quoted strings #>\n$single_quote_str_esc_1 = 'XXX`'\n$single_quote_str_esc_2 = 'XXX```'\n"
  },
  {
    "path": "test/examples/powershell/Pull92.ps1.folded",
    "content": " 0 400 400   <# Tests for PowerShell #>\n 1 400 400   \n 0 400 400   <# Backticks should escape in double quoted strings #>\n 0 400 400   $double_quote_str_esc_1 = \"`\"XXX`\"\"\n 0 400 400   $double_quote_str_esc_2 = \"This `\"string`\" `$useses `r`n Backticks '``'\"\n 1 400 400   \n 0 400 400   <# Backticks should be ignored in quoted strings #>\n 0 400 400   $single_quote_str_esc_1 = 'XXX`'\n 0 400 400   $single_quote_str_esc_2 = 'XXX```'\n 0 400   0   "
  },
  {
    "path": "test/examples/powershell/Pull92.ps1.styled",
    "content": "{13}<# Tests for PowerShell #>{0}\n\n{13}<# Backticks should escape in double quoted strings #>{0}\n{5}$double_quote_str_esc_1{0} {6}={0} {2}\"`\"XXX`\"\"{0}\n{5}$double_quote_str_esc_2{0} {6}={0} {2}\"This `\"string`\" `$useses `r`n Backticks '``'\"{0}\n\n{13}<# Backticks should be ignored in quoted strings #>{0}\n{5}$single_quote_str_esc_1{0} {6}={0} {3}'XXX`'{0}\n{5}$single_quote_str_esc_2{0} {6}={0} {3}'XXX```'{0}\n"
  },
  {
    "path": "test/examples/powershell/Pull99Comment.ps1",
    "content": "# End comment before \\r carriage return.\n"
  },
  {
    "path": "test/examples/powershell/Pull99Comment.ps1.folded",
    "content": " 0 400 400   # End comment before \\r carriage return.\n 0 400   0   "
  },
  {
    "path": "test/examples/powershell/Pull99Comment.ps1.styled",
    "content": "{1}# End comment before \\r carriage return.{0}\n"
  },
  {
    "path": "test/examples/powershell/SciTE.properties",
    "content": "lexer.*.ps1=powershell\nfold=1\n\nkeywords.*.ps1=break if else in local\nkeywords2.*.ps1=write-host write-output\nkeywords3.*.ps1=cd chdir cat\nkeywords4.*.ps1=mkdir prompt get-verb\nkeywords5.*.ps1=lexilla 7z\nkeywords6.*.ps1=synopsis\n"
  },
  {
    "path": "test/examples/progress/SciTE.properties",
    "content": "lexer.*.p=abl\nkeywords.*.p=as define display message name object progress run using variable visible\nfold=1\n"
  },
  {
    "path": "test/examples/progress/annotations.p",
    "content": "// @ used in the non-annotation sense\ndisplay \"test\" @ field.\n\n// source annotation examples\n@sourceannotation\n@source-annotation()\n@source_annotation(prop = \"abc\")\n@source#$%annotation(prop = \"abc\", prop2 = 123)\n\n// typed source annotation examples\n@@sourceannotation\n@@source-annotation()\n@@source_annotation(prop = \"abc\")\n@@source#$%annotation(prop = \"abc\", prop2 = 123)\n\n// poorly formed annotations\n@@@ThreeAtSigns // first two @ signs are typed, next is not typed\n@name[containsbadcharacter // annotation style stops at bad character\n@@name[containsbadcharacter // typed annotation style stops at bad character\n"
  },
  {
    "path": "test/examples/progress/annotations.p.folded",
    "content": " 0 400 400   // @ used in the non-annotation sense\n 0 400 400   display \"test\" @ field.\n 0 400 400   \n 0 400 400   // source annotation examples\n 0 400 400   @sourceannotation\n 0 400 400   @source-annotation()\n 0 400 400   @source_annotation(prop = \"abc\")\n 0 400 400   @source#$%annotation(prop = \"abc\", prop2 = 123)\n 0 400 400   \n 0 400 400   // typed source annotation examples\n 0 400 400   @@sourceannotation\n 0 400 400   @@source-annotation()\n 0 400 400   @@source_annotation(prop = \"abc\")\n 0 400 400   @@source#$%annotation(prop = \"abc\", prop2 = 123)\n 0 400 400   \n 0 400 400   // poorly formed annotations\n 0 400 400   @@@ThreeAtSigns // first two @ signs are typed, next is not typed\n 0 400 400   @name[containsbadcharacter // annotation style stops at bad character\n 0 400 400   @@name[containsbadcharacter // typed annotation style stops at bad character\n 1 400 400   "
  },
  {
    "path": "test/examples/progress/annotations.p.styled",
    "content": "{12}// @ used in the non-annotation sense\n{2}display{0} {3}\"test\"{0} @ {7}field{6}.{0}\n\n{12}// source annotation examples\n{13}@sourceannotation{0}\n{13}@source-annotation{6}(){0}\n{13}@source_annotation{6}({7}prop{0} {6}={0} {3}\"abc\"{6}){0}\n{13}@source#$%annotation{6}({7}prop{0} {6}={0} {3}\"abc\"{6},{0} {7}prop2{0} {6}={0} {1}123{6}){0}\n\n{12}// typed source annotation examples\n{14}@@sourceannotation{0}\n{14}@@source-annotation{6}(){0}\n{14}@@source_annotation{6}({7}prop{0} {6}={0} {3}\"abc\"{6}){0}\n{14}@@source#$%annotation{6}({7}prop{0} {6}={0} {3}\"abc\"{6},{0} {7}prop2{0} {6}={0} {1}123{6}){0}\n\n{12}// poorly formed annotations\n{14}@@{13}@ThreeAtSigns{0} {12}// first two @ signs are typed, next is not typed\n{13}@name{6}[{7}containsbadcharacter{0} {12}// annotation style stops at bad character\n{14}@@name{6}[{7}containsbadcharacter{0} {12}// typed annotation style stops at bad character\n"
  },
  {
    "path": "test/examples/progress/comment_test.p",
    "content": "//line comment\n\n/* block comment */\n\n/* block comment on \nmultiple lines */\n\n/* //line comment within block comment */\n\n// /*block comment within line comment */\n\n// using open-block-comment symbol alone on line comment /*\n\n/* /* nested block comment */ */\n\nDISPLAY \"this line of code is a test\". \nDISPLAY \"//this line of code is a test\".\nDISPLAY \"/* this line of code is a test */\".\n\n// using close-block-comment symbol alone on line comment */\n\n// /* improperly closed block comment within line comment */ */\n\n/* \n//line comment 1 in block comment\n//line comment 2 in block comment\n//line comment 3 in block comment\n*/\n\n/*\nblock comment text\n//line comment text\n/* inner block comment text*/\n*/\n\nDISPLAY \"This is a open-block-comment symbol /*\".\nDISPLAY \"This is a close-block-comment symbol */\".\n\n//* line comment plus * looks like open-block-comment\n\n\nDISPLAY \"this line of code is a test\".\n\n/*display statement within block comment\nDISPLAY \"this is a string\".\n*/\n\nDISPLAY \"//line comment within string\".\n\nDISPLAY \"/* //line comment within block comment within string */\".\n                                                                        \n/* Improperly closed block comment */ */\n\nDISPLAY \"this line of code is a test\".\n\nDISPLAY \"line comment with leading whitespace\". // this is a line comment\nDISPLAY \"line comment without leading whitespace\".// this is not a line comment\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "test/examples/progress/comment_test.p.folded",
    "content": " 0 400 400   //line comment\n 0 400 400   \n 0 400 400   /* block comment */\n 0 400 400   \n 2 400 401 + /* block comment on \n 0 401 400 | multiple lines */\n 0 400 400   \n 0 400 400   /* //line comment within block comment */\n 0 400 400   \n 0 400 400   // /*block comment within line comment */\n 0 400 400   \n 0 400 400   // using open-block-comment symbol alone on line comment /*\n 0 400 400   \n 0 400 400   /* /* nested block comment */ */\n 0 400 400   \n 0 400 400   DISPLAY \"this line of code is a test\". \n 0 400 400   DISPLAY \"//this line of code is a test\".\n 0 400 400   DISPLAY \"/* this line of code is a test */\".\n 0 400 400   \n 0 400 400   // using close-block-comment symbol alone on line comment */\n 0 400 400   \n 0 400 400   // /* improperly closed block comment within line comment */ */\n 0 400 400   \n 2 400 401 + /* \n 0 401 401 | //line comment 1 in block comment\n 0 401 401 | //line comment 2 in block comment\n 0 401 401 | //line comment 3 in block comment\n 0 401 400 | */\n 0 400 400   \n 2 400 401 + /*\n 0 401 401 | block comment text\n 0 401 401 | //line comment text\n 0 401 401 | /* inner block comment text*/\n 0 401 400 | */\n 0 400 400   \n 0 400 400   DISPLAY \"This is a open-block-comment symbol /*\".\n 0 400 400   DISPLAY \"This is a close-block-comment symbol */\".\n 0 400 400   \n 0 400 400   //* line comment plus * looks like open-block-comment\n 0 400 400   \n 0 400 400   \n 0 400 400   DISPLAY \"this line of code is a test\".\n 0 400 400   \n 2 400 401 + /*display statement within block comment\n 0 401 401 | DISPLAY \"this is a string\".\n 0 401 400 | */\n 0 400 400   \n 0 400 400   DISPLAY \"//line comment within string\".\n 0 400 400   \n 0 400 400   DISPLAY \"/* //line comment within block comment within string */\".\n 0 400 400                                                                           \n 0 400 400   /* Improperly closed block comment */ */\n 0 400 400   \n 0 400 400   DISPLAY \"this line of code is a test\".\n 0 400 400   \n 0 400 400   DISPLAY \"line comment with leading whitespace\". // this is a line comment\n 0 400 400   DISPLAY \"line comment without leading whitespace\".// this is not a line comment\n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 0 400 400   \n 1 400 400   "
  },
  {
    "path": "test/examples/progress/comment_test.p.styled",
    "content": "{12}//line comment\n{0}\n{10}/* block comment */{0}\n\n{10}/* block comment on \nmultiple lines */{0}\n\n{10}/* //line comment within block comment */{0}\n\n{12}// /*block comment within line comment */\n{0}\n{12}// using open-block-comment symbol alone on line comment /*\n{0}\n{10}/* /* nested block comment */ */{0}\n\n{2}DISPLAY{0} {3}\"this line of code is a test\"{6}.{0} \n{2}DISPLAY{0} {3}\"//this line of code is a test\"{6}.{0}\n{2}DISPLAY{0} {3}\"/* this line of code is a test */\"{6}.{0}\n\n{12}// using close-block-comment symbol alone on line comment */\n{0}\n{12}// /* improperly closed block comment within line comment */ */\n{0}\n{10}/* \n//line comment 1 in block comment\n//line comment 2 in block comment\n//line comment 3 in block comment\n*/{0}\n\n{10}/*\nblock comment text\n//line comment text\n/* inner block comment text*/\n*/{0}\n\n{2}DISPLAY{0} {3}\"This is a open-block-comment symbol /*\"{6}.{0}\n{2}DISPLAY{0} {3}\"This is a close-block-comment symbol */\"{6}.{0}\n\n{12}//* line comment plus * looks like open-block-comment\n{0}\n\n{2}DISPLAY{0} {3}\"this line of code is a test\"{6}.{0}\n\n{10}/*display statement within block comment\nDISPLAY \"this is a string\".\n*/{0}\n\n{2}DISPLAY{0} {3}\"//line comment within string\"{6}.{0}\n\n{2}DISPLAY{0} {3}\"/* //line comment within block comment within string */\"{6}.{0}\n                                                                        \n{10}/* Improperly closed block comment */{0} {6}*/{0}\n\n{2}DISPLAY{0} {3}\"this line of code is a test\"{6}.{0}\n\n{2}DISPLAY{0} {3}\"line comment with leading whitespace\"{6}.{0} {12}// this is a line comment\n{2}DISPLAY{0} {3}\"line comment without leading whitespace\"{6}.//{0} {7}this{0} {7}is{0} {7}not{0} {7}a{0} {7}line{0} {7}comment{0}\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "test/examples/progress/compound_id.p",
    "content": "// all of \"Progress.Lang.Object\" is styled as SCE_ABL_IDENTIFIER\nDEFINE VARIABLE obj1 AS Progress.Lang.Object.\n\n// \"Object\" by itself is styled as SCE_ABL_WORD when not part of a compound identifier\nDEFINE VARIABLE obj1 AS OBJECT.\n\n// \"Object2\" isn't a keyword so it's styled as SCE_ABL_IDENTIFIER\nDEFINE VARIABLE obj1 AS Object2.\n\n// \"name\" (which is a keyword) is styled as SCE_ABL_IDENTIFIER when part of a compound identifier\nDISPLAY customer.name.\nDISPLAY sports.customer.name.\n\n// \"name\" by itself is styled as SCE_ABL_WORD when not part of a compound identifier\nDISPLAY name.\n\n// make sure that SCE_ABL_IDENTIFIER spans an identifier which contains a hyphen\nDISPLAY customer.cust-num.\nDISPLAY customer.cust-name.\n\n// underscore is a valid character at the beginning of an identifier\nDISPLAY _user._user-id.\n\n// - is not a valid character at the beginning of an identifier\nDISPLAY sports.-address.\n\n// the attribute is styled as SCE_ABL_WORD\nMESSAGE customer.name:VISIBLE.\n\n// filename and extension is styled as SCE_ABL_IDENTIFIER\nRUN dir1/dir2/myprocedure.p.\nRUN dir1/dir2/name.p\nRUN myprocedure.p\nRUN name.p\n\n// .* in USING statement is styled as SCE_ABL_IDENTIFIER\nUSING System.Windows.Forms.*.\n\n// * in an identifier (not following . as above) is invalid\nDEFINE VARIABLE a AS Progress.Lang*.\n"
  },
  {
    "path": "test/examples/progress/compound_id.p.folded",
    "content": " 0 400 400   // all of \"Progress.Lang.Object\" is styled as SCE_ABL_IDENTIFIER\n 0 400 400   DEFINE VARIABLE obj1 AS Progress.Lang.Object.\n 0 400 400   \n 0 400 400   // \"Object\" by itself is styled as SCE_ABL_WORD when not part of a compound identifier\n 0 400 400   DEFINE VARIABLE obj1 AS OBJECT.\n 0 400 400   \n 0 400 400   // \"Object2\" isn't a keyword so it's styled as SCE_ABL_IDENTIFIER\n 0 400 400   DEFINE VARIABLE obj1 AS Object2.\n 0 400 400   \n 0 400 400   // \"name\" (which is a keyword) is styled as SCE_ABL_IDENTIFIER when part of a compound identifier\n 0 400 400   DISPLAY customer.name.\n 0 400 400   DISPLAY sports.customer.name.\n 0 400 400   \n 0 400 400   // \"name\" by itself is styled as SCE_ABL_WORD when not part of a compound identifier\n 0 400 400   DISPLAY name.\n 0 400 400   \n 0 400 400   // make sure that SCE_ABL_IDENTIFIER spans an identifier which contains a hyphen\n 0 400 400   DISPLAY customer.cust-num.\n 0 400 400   DISPLAY customer.cust-name.\n 0 400 400   \n 0 400 400   // underscore is a valid character at the beginning of an identifier\n 0 400 400   DISPLAY _user._user-id.\n 0 400 400   \n 0 400 400   // - is not a valid character at the beginning of an identifier\n 0 400 400   DISPLAY sports.-address.\n 0 400 400   \n 0 400 400   // the attribute is styled as SCE_ABL_WORD\n 0 400 400   MESSAGE customer.name:VISIBLE.\n 0 400 400   \n 0 400 400   // filename and extension is styled as SCE_ABL_IDENTIFIER\n 0 400 400   RUN dir1/dir2/myprocedure.p.\n 0 400 400   RUN dir1/dir2/name.p\n 0 400 400   RUN myprocedure.p\n 0 400 400   RUN name.p\n 0 400 400   \n 0 400 400   // .* in USING statement is styled as SCE_ABL_IDENTIFIER\n 0 400 400   USING System.Windows.Forms.*.\n 0 400 400   \n 0 400 400   // * in an identifier (not following . as above) is invalid\n 0 400 400   DEFINE VARIABLE a AS Progress.Lang*.\n 1 400 400   "
  },
  {
    "path": "test/examples/progress/compound_id.p.styled",
    "content": "{12}// all of \"Progress.Lang.Object\" is styled as SCE_ABL_IDENTIFIER\n{2}DEFINE{0} {2}VARIABLE{0} {7}obj1{0} {2}AS{0} {7}Progress.Lang.Object.{0}\n\n{12}// \"Object\" by itself is styled as SCE_ABL_WORD when not part of a compound identifier\n{2}DEFINE{0} {2}VARIABLE{0} {7}obj1{0} {2}AS{0} {2}OBJECT{6}.{0}\n\n{12}// \"Object2\" isn't a keyword so it's styled as SCE_ABL_IDENTIFIER\n{2}DEFINE{0} {2}VARIABLE{0} {7}obj1{0} {2}AS{0} {7}Object2{6}.{0}\n\n{12}// \"name\" (which is a keyword) is styled as SCE_ABL_IDENTIFIER when part of a compound identifier\n{2}DISPLAY{0} {7}customer.name.{0}\n{2}DISPLAY{0} {7}sports.customer.name.{0}\n\n{12}// \"name\" by itself is styled as SCE_ABL_WORD when not part of a compound identifier\n{2}DISPLAY{0} {2}name{6}.{0}\n\n{12}// make sure that SCE_ABL_IDENTIFIER spans an identifier which contains a hyphen\n{2}DISPLAY{0} {7}customer.cust-num.{0}\n{2}DISPLAY{0} {7}customer.cust-name.{0}\n\n{12}// underscore is a valid character at the beginning of an identifier\n{2}DISPLAY{0} {7}_user._user-id.{0}\n\n{12}// - is not a valid character at the beginning of an identifier\n{2}DISPLAY{0} {7}sports{6}.-{7}address{6}.{0}\n\n{12}// the attribute is styled as SCE_ABL_WORD\n{2}MESSAGE{0} {7}customer.name{6}:{2}VISIBLE{6}.{0}\n\n{12}// filename and extension is styled as SCE_ABL_IDENTIFIER\n{2}RUN{0} {7}dir1{6}/{7}dir2{6}/{7}myprocedure.p.{0}\n{2}RUN{0} {7}dir1{6}/{7}dir2{6}/{7}name.p{0}\n{2}RUN{0} {7}myprocedure.p{0}\n{2}RUN{0} {7}name.p{0}\n\n{12}// .* in USING statement is styled as SCE_ABL_IDENTIFIER\n{2}USING{0} {7}System.Windows.Forms.*.{0}\n\n{12}// * in an identifier (not following . as above) is invalid\n{2}DEFINE{0} {2}VARIABLE{0} {7}a{0} {2}AS{0} {7}Progress.Lang{6}*.{0}\n"
  },
  {
    "path": "test/examples/props/Issue96Folding.props",
    "content": "; comment\n[empty section]\n[normal section]\n@=default\nkey=value\n"
  },
  {
    "path": "test/examples/props/Issue96Folding.props.folded",
    "content": " 0 400   0   ; comment\n 0 400   0   [empty section]\n 2 400   0 + [normal section]\n 0 401   0 | @=default\n 0 401   0 | key=value\n 0 401   0 | "
  },
  {
    "path": "test/examples/props/Issue96Folding.props.styled",
    "content": "{1}; comment\n{2}[empty section]\n[normal section]\n{4}@{0}=default\n{5}key{3}={0}value\n"
  },
  {
    "path": "test/examples/props/SciTE.properties",
    "content": "lexer.*.session=props\nlexer.*.props=props\nfold=1\n"
  },
  {
    "path": "test/examples/props/example.session",
    "content": "# Default=0\na\n\n# Comment=1\n\n\n# Heading=2\n[heading]\n\n\n# Assignment=3\n=\n\n# Default Value=4\n@\n\n# Key=5\nkey=\n\n"
  },
  {
    "path": "test/examples/props/example.session.folded",
    "content": " 0 400   0   # Default=0\n 0 400   0   a\n 1 400   0   \n 0 400   0   # Comment=1\n 1 400   0   \n 1 400   0   \n 0 400   0   # Heading=2\n 2 400   0 + [heading]\n 1 401   0 | \n 1 401   0 | \n 0 401   0 | # Assignment=3\n 0 401   0 | =\n 1 401   0 | \n 0 401   0 | # Default Value=4\n 0 401   0 | @\n 1 401   0 | \n 0 401   0 | # Key=5\n 0 401   0 | key=\n 1 401   0 | \n 0 401   0 | "
  },
  {
    "path": "test/examples/props/example.session.styled",
    "content": "{1}# Default=0\n{0}a\n\n{1}# Comment=1\n{0}\n\n{1}# Heading=2\n{2}[heading]\n{0}\n\n{1}# Assignment=3\n{3}={0}\n\n{1}# Default Value=4\n{4}@{0}\n\n{1}# Key=5\n{5}key{3}={0}\n\n"
  },
  {
    "path": "test/examples/python/AllStyles.py",
    "content": "# Enumerate all styles: 0 to 19\n# comment=1\n\n# whitespace=0\n\t# w\n\n# number=2\n37\n\n# double-quoted-string=3\n\"str\"\n\n# single-quoted-string=4\n'str'\n\n# keyword=5\npass\n\n# triple-quoted-string=6\n'''str'''\n\n# triple-double-quoted-string=7\n\"\"\"str\"\"\"\n\n# class-name=8\nclass ClassName:\n\tpass\n\n# function-name=9\ndef function_name():\n\tpass\n\n# operator=10\n1 + 3\n\n# identifier=11\nidentifier = 2\n\n# comment-block=12\n## block\n\n# unclosed-string=13\n\" unclosed\n\n# highlighted-identifier=14\nhilight = 2\n\n# decorator=15\n@staticmethod\ndef fn(): pass\n\na = 1\n# double-quoted-f-string=16\nf\"{a}\"\n\n# single-quoted-f-string=17\nf'{a}'\n\n# triple-quoted-f-string=18\nf'''{a}'''\n\n# double-triple-quoted-f-string=19\nf\"\"\"{a}\"\"\"\n"
  },
  {
    "path": "test/examples/python/AllStyles.py.folded",
    "content": " 0 400   0   # Enumerate all styles: 0 to 19\n 0 400   0   # comment=1\n 1 400   0   \n 0 400   0   # whitespace=0\n 0 400   0   \t# w\n 1 400   0   \n 0 400   0   # number=2\n 0 400   0   37\n 1 400   0   \n 0 400   0   # double-quoted-string=3\n 0 400   0   \"str\"\n 1 400   0   \n 0 400   0   # single-quoted-string=4\n 0 400   0   'str'\n 1 400   0   \n 0 400   0   # keyword=5\n 0 400   0   pass\n 1 400   0   \n 0 400   0   # triple-quoted-string=6\n 0 400   0   '''str'''\n 1 400   0   \n 0 400   0   # triple-double-quoted-string=7\n 0 400   0   \"\"\"str\"\"\"\n 1 400   0   \n 0 400   0   # class-name=8\n 2 400   0 + class ClassName:\n 0 408   0 | \tpass\n 1 400   0   \n 0 400   0   # function-name=9\n 2 400   0 + def function_name():\n 0 408   0 | \tpass\n 1 400   0   \n 0 400   0   # operator=10\n 0 400   0   1 + 3\n 1 400   0   \n 0 400   0   # identifier=11\n 0 400   0   identifier = 2\n 1 400   0   \n 0 400   0   # comment-block=12\n 0 400   0   ## block\n 1 400   0   \n 0 400   0   # unclosed-string=13\n 0 400   0   \" unclosed\n 1 400   0   \n 0 400   0   # highlighted-identifier=14\n 0 400   0   hilight = 2\n 1 400   0   \n 0 400   0   # decorator=15\n 0 400   0   @staticmethod\n 0 400   0   def fn(): pass\n 1 400   0   \n 0 400   0   a = 1\n 0 400   0   # double-quoted-f-string=16\n 0 400   0   f\"{a}\"\n 1 400   0   \n 0 400   0   # single-quoted-f-string=17\n 0 400   0   f'{a}'\n 1 400   0   \n 0 400   0   # triple-quoted-f-string=18\n 0 400   0   f'''{a}'''\n 1 400   0   \n 0 400   0   # double-triple-quoted-f-string=19\n 0 400   0   f\"\"\"{a}\"\"\"\n 1 400   0   "
  },
  {
    "path": "test/examples/python/AllStyles.py.styled",
    "content": "{1}# Enumerate all styles: 0 to 19{0}\n{1}# comment=1{0}\n\n{1}# whitespace=0{0}\n\t{1}# w{0}\n\n{1}# number=2{0}\n{2}37{0}\n\n{1}# double-quoted-string=3{0}\n{3}\"str\"{0}\n\n{1}# single-quoted-string=4{0}\n{4}'str'{0}\n\n{1}# keyword=5{0}\n{5}pass{0}\n\n{1}# triple-quoted-string=6{0}\n{6}'''str'''{0}\n\n{1}# triple-double-quoted-string=7{0}\n{7}\"\"\"str\"\"\"{0}\n\n{1}# class-name=8{0}\n{5}class{0} {8}ClassName{10}:{0}\n\t{5}pass{0}\n\n{1}# function-name=9{0}\n{5}def{0} {9}function_name{10}():{0}\n\t{5}pass{0}\n\n{1}# operator=10{0}\n{2}1{0} {10}+{0} {2}3{0}\n\n{1}# identifier=11{0}\n{11}identifier{0} {10}={0} {2}2{0}\n\n{1}# comment-block=12{0}\n{12}## block{0}\n\n{1}# unclosed-string=13{0}\n{13}\" unclosed\n{0}\n{1}# highlighted-identifier=14{0}\n{14}hilight{0} {10}={0} {2}2{0}\n\n{1}# decorator=15{0}\n{15}@staticmethod{0}\n{5}def{0} {9}fn{10}():{0} {5}pass{0}\n\n{11}a{0} {10}={0} {2}1{0}\n{1}# double-quoted-f-string=16{0}\n{16}f\"{{11}a{16}}\"{0}\n\n{1}# single-quoted-f-string=17{0}\n{17}f'{{11}a{17}}'{0}\n\n{1}# triple-quoted-f-string=18{0}\n{18}f'''{{11}a{18}}'''{0}\n\n{1}# double-triple-quoted-f-string=19{0}\n{19}f\"\"\"{{11}a{19}}\"\"\"{0}\n"
  },
  {
    "path": "test/examples/python/SciTE.properties",
    "content": "lexer.*.py=python\nkeywords.*.py=case class def else for if import in match pass print return while with yield\nkeywords2.*.py=hilight\nfold=1\nfold.compact=1\n"
  },
  {
    "path": "test/examples/python/attributes/SciTE.properties",
    "content": "lexer.*.py=python\nkeywords.*.py=class def else for if import in pass print return while with yield\nkeywords2.*.py=hilight\nfold=1\nfold.compact=1\nlexer.python.identifier.attributes=1\nlexer.python.decorator.attributes=1\n\nsubstyles.python.11=3\nsubstylewords.11.3.$(file.patterns.py)=findall replace\nstyle.python.11.3=fore:#EEAA80,italics,bold\n"
  },
  {
    "path": "test/examples/python/attributes/attrib-decorator.py",
    "content": "# issue#294 also pointed out that decorator attributes behaved differently\n#   for left-justified decorators vs indented decorators\n\n@decorator.attribute\ndef foo():\n    @decorator.attribute\n    def bar():\n        pass\n    bar()\n"
  },
  {
    "path": "test/examples/python/attributes/attrib-decorator.py.folded",
    "content": " 0 400   0   # issue#294 also pointed out that decorator attributes behaved differently\n 0 400   0   #   for left-justified decorators vs indented decorators\n 1 400   0   \n 0 400   0   @decorator.attribute\n 2 400   0 + def foo():\n 0 404   0 |     @decorator.attribute\n 2 404   0 +     def bar():\n 0 408   0 |         pass\n 0 404   0 |     bar()\n 1 404   0 | "
  },
  {
    "path": "test/examples/python/attributes/attrib-decorator.py.styled",
    "content": "{1}# issue#294 also pointed out that decorator attributes behaved differently{0}\n{1}#   for left-justified decorators vs indented decorators{0}\n\n{15}@decorator{10}.{15}attribute{0}\n{5}def{0} {9}foo{10}():{0}\n    {15}@decorator{10}.{15}attribute{0}\n    {5}def{0} {9}bar{10}():{0}\n        {5}pass{0}\n    {11}bar{10}(){0}\n"
  },
  {
    "path": "test/examples/python/attributes/attrib-id.py",
    "content": "varname = 1\n# identifier in first line was mis-styled as attribute when bug existed\n\n# left comment ends with period.  this was okay before bug.\nvarname = 2\n\nx = 1 # comment after code ends with period. this failed when bug existed.\nvarname = 3\n\ndef dummy():\n    # indented comment ends with period.this failed when bug existed.\n    varname = 4\n\nx = 2 ## comment block is the same.\nvarname = 5\n\n# per issue#294, identifiers were mis-styled as attributes when at beginning of file\n# and when after a non-left-justifed comment\n"
  },
  {
    "path": "test/examples/python/attributes/attrib-id.py.folded",
    "content": " 0 400   0   varname = 1\n 0 400   0   # identifier in first line was mis-styled as attribute when bug existed\n 1 400   0   \n 0 400   0   # left comment ends with period.  this was okay before bug.\n 0 400   0   varname = 2\n 1 400   0   \n 0 400   0   x = 1 # comment after code ends with period. this failed when bug existed.\n 0 400   0   varname = 3\n 1 400   0   \n 2 400   0 + def dummy():\n 0 404   0 |     # indented comment ends with period.this failed when bug existed.\n 0 404   0 |     varname = 4\n 1 400   0   \n 0 400   0   x = 2 ## comment block is the same.\n 0 400   0   varname = 5\n 1 400   0   \n 0 400   0   # per issue#294, identifiers were mis-styled as attributes when at beginning of file\n 0 400   0   # and when after a non-left-justifed comment\n 1 400   0   "
  },
  {
    "path": "test/examples/python/attributes/attrib-id.py.styled",
    "content": "{11}varname{0} {10}={0} {2}1{0}\n{1}# identifier in first line was mis-styled as attribute when bug existed{0}\n\n{1}# left comment ends with period.  this was okay before bug.{0}\n{11}varname{0} {10}={0} {2}2{0}\n\n{11}x{0} {10}={0} {2}1{0} {1}# comment after code ends with period. this failed when bug existed.{0}\n{11}varname{0} {10}={0} {2}3{0}\n\n{5}def{0} {9}dummy{10}():{0}\n    {1}# indented comment ends with period.this failed when bug existed.{0}\n    {11}varname{0} {10}={0} {2}4{0}\n\n{11}x{0} {10}={0} {2}2{0} {12}## comment block is the same.{0}\n{11}varname{0} {10}={0} {2}5{0}\n\n{1}# per issue#294, identifiers were mis-styled as attributes when at beginning of file{0}\n{1}# and when after a non-left-justifed comment{0}\n"
  },
  {
    "path": "test/examples/python/attributes/attributes.py",
    "content": "# attributes=20\ns = \"thing thing\".findall(\"thing\")\na.very.complicated.expression.findall(\"test\")\n# fake out.\nb.very.complicated.expression.\n    findall(\"test2\")\nc.very.complicated.expression. \\\n    findall(\"test3\")\nd.very.complicated.expression.\\\n    findall(\"test4\")\n@staticmethod.attrtest\n@staticmethod.\nattrtest\n@staticmethod. \\\nattrtest\n@staticmethod.\\\nattrtest\n"
  },
  {
    "path": "test/examples/python/attributes/attributes.py.folded",
    "content": " 0 400   0   # attributes=20\n 0 400   0   s = \"thing thing\".findall(\"thing\")\n 0 400   0   a.very.complicated.expression.findall(\"test\")\n 0 400   0   # fake out.\n 2 400   0 + b.very.complicated.expression.\n 0 404   0 |     findall(\"test2\")\n 2 400   0 + c.very.complicated.expression. \\\n 0 404   0 |     findall(\"test3\")\n 2 400   0 + d.very.complicated.expression.\\\n 0 404   0 |     findall(\"test4\")\n 0 400   0   @staticmethod.attrtest\n 0 400   0   @staticmethod.\n 0 400   0   attrtest\n 0 400   0   @staticmethod. \\\n 0 400   0   attrtest\n 0 400   0   @staticmethod.\\\n 0 400   0   attrtest\n 1 400   0   "
  },
  {
    "path": "test/examples/python/attributes/attributes.py.styled",
    "content": "{1}# attributes=20{0}\n{11}s{0} {10}={0} {3}\"thing thing\"{10}.{20}findall{10}({3}\"thing\"{10}){0}\n{11}a{10}.{20}very{10}.{20}complicated{10}.{20}expression{10}.{20}findall{10}({3}\"test\"{10}){0}\n{1}# fake out.{0}\n{11}b{10}.{20}very{10}.{20}complicated{10}.{20}expression{10}.{0}\n    {20}findall{10}({3}\"test2\"{10}){0}\n{11}c{10}.{20}very{10}.{20}complicated{10}.{20}expression{10}.{0} \\\n    {20}findall{10}({3}\"test3\"{10}){0}\n{11}d{10}.{20}very{10}.{20}complicated{10}.{20}expression{10}.{0}\\\n    {20}findall{10}({3}\"test4\"{10}){0}\n{15}@staticmethod{10}.{15}attrtest{0}\n{15}@staticmethod{10}.{0}\n{15}attrtest{0}\n{15}@staticmethod{10}.{0} \\\n{15}attrtest{0}\n{15}@staticmethod{10}.{0}\\\n{15}attrtest{0}\n"
  },
  {
    "path": "test/examples/python/f-strings.py",
    "content": "# Simple nesting\nf\" { \"\" } \"\n\n# Multi-line field with comment\nf\" {\n\n\"\" # comment\n\n} \"\n\n# Single quoted continued with \\\nf\" \\\n\"\n\n# 4 nested f-strings\nf'Outer {f\"nested {1} {f\"nested {2} {f\"nested {3} {f\"nested {4}\"}\"}\"}\"}'\n"
  },
  {
    "path": "test/examples/python/f-strings.py.folded",
    "content": " 0 400   0   # Simple nesting\n 0 400   0   f\" { \"\" } \"\n 1 400   0   \n 0 400   0   # Multi-line field with comment\n 0 400   0   f\" {\n 1 400   0   \n 0 400   0   \"\" # comment\n 1 400   0   \n 0 400   0   } \"\n 1 400   0   \n 0 400   0   # Single quoted continued with \\\n 0 400   0   f\" \\\n 0 400   0   \"\n 1 400   0   \n 0 400   0   # 4 nested f-strings\n 0 400   0   f'Outer {f\"nested {1} {f\"nested {2} {f\"nested {3} {f\"nested {4}\"}\"}\"}\"}'\n 1 400   0   "
  },
  {
    "path": "test/examples/python/f-strings.py.styled",
    "content": "{1}# Simple nesting{0}\n{16}f\" {{0} {3}\"\"{0} {16}} \"{0}\n\n{1}# Multi-line field with comment{0}\n{16}f\" {{0}\n\n{3}\"\"{0} {1}# comment{0}\n\n{16}} \"{0}\n\n{1}# Single quoted continued with \\{0}\n{16}f\" \\\n\"{0}\n\n{1}# 4 nested f-strings{0}\n{17}f'Outer {{16}f\"nested {{2}1{16}} {f\"nested {{2}2{16}} {f\"nested {{2}3{16}} {f\"nested {{2}4{16}}\"}\"}\"}\"{17}}'{0}\n"
  },
  {
    "path": "test/examples/python/matchcase.py",
    "content": "# Match and case as keywords\nmatch (x):\n    case +1:\n        pass\n    case -1:\n        pass\n    case []:\n        pass\n    \n# Match and case as identifiers\nmatch = 1\ndef match():\n    pass\nmatch.group()\n1 + match\ncase.attribute\n\n# Unfortunately wrong classifications; should be rare in real code because\n# non-call expressions usually don't begin lines, the exceptions are match(x)\n# and case(x)\nmatch(x)\ncase(x)\nmatch + 1\ncase + 1\ncase[1]\n"
  },
  {
    "path": "test/examples/python/matchcase.py.folded",
    "content": " 0 400   0   # Match and case as keywords\n 2 400   0 + match (x):\n 2 404   0 +     case +1:\n 0 408   0 |         pass\n 2 404   0 +     case -1:\n 0 408   0 |         pass\n 2 404   0 +     case []:\n 0 408   0 |         pass\n 1 408   0 |     \n 0 400   0   # Match and case as identifiers\n 0 400   0   match = 1\n 2 400   0 + def match():\n 0 404   0 |     pass\n 0 400   0   match.group()\n 0 400   0   1 + match\n 0 400   0   case.attribute\n 1 400   0   \n 0 400   0   # Unfortunately wrong classifications; should be rare in real code because\n 0 400   0   # non-call expressions usually don't begin lines, the exceptions are match(x)\n 0 400   0   # and case(x)\n 0 400   0   match(x)\n 0 400   0   case(x)\n 0 400   0   match + 1\n 0 400   0   case + 1\n 0 400   0   case[1]\n 1 400   0   "
  },
  {
    "path": "test/examples/python/matchcase.py.styled",
    "content": "{1}# Match and case as keywords{0}\n{5}match{0} {10}({11}x{10}):{0}\n    {5}case{0} {10}+{2}1{10}:{0}\n        {5}pass{0}\n    {5}case{0} {10}-{2}1{10}:{0}\n        {5}pass{0}\n    {5}case{0} {10}[]:{0}\n        {5}pass{0}\n    \n{1}# Match and case as identifiers{0}\n{11}match{0} {10}={0} {2}1{0}\n{5}def{0} {9}match{10}():{0}\n    {5}pass{0}\n{11}match{10}.{11}group{10}(){0}\n{2}1{0} {10}+{0} {11}match{0}\n{11}case{10}.{11}attribute{0}\n\n{1}# Unfortunately wrong classifications; should be rare in real code because{0}\n{1}# non-call expressions usually don't begin lines, the exceptions are match(x){0}\n{1}# and case(x){0}\n{5}match{10}({11}x{10}){0}\n{5}case{10}({11}x{10}){0}\n{5}match{0} {10}+{0} {2}1{0}\n{5}case{0} {10}+{0} {2}1{0}\n{5}case{10}[{2}1{10}]{0}\n"
  },
  {
    "path": "test/examples/python/strings.py",
    "content": "# Simple raw string\nr''\n\n# Raw f-string\nrf''\nfr''\n\n# Raw byte string\nrb''\nbr''\n\n# Raw unicode strings: ur'' is valid in 2.7 (but not in 3) -- always lexed as\n# valid; ru'' is never valid\nru''\nur''\n\n"
  },
  {
    "path": "test/examples/python/strings.py.folded",
    "content": " 0 400   0   # Simple raw string\n 0 400   0   r''\n 1 400   0   \n 0 400   0   # Raw f-string\n 0 400   0   rf''\n 0 400   0   fr''\n 1 400   0   \n 0 400   0   # Raw byte string\n 0 400   0   rb''\n 0 400   0   br''\n 1 400   0   \n 0 400   0   # Raw unicode strings: ur'' is valid in 2.7 (but not in 3) -- always lexed as\n 0 400   0   # valid; ru'' is never valid\n 0 400   0   ru''\n 0 400   0   ur''\n 1 400   0   \n 1 400   0   "
  },
  {
    "path": "test/examples/python/strings.py.styled",
    "content": "{1}# Simple raw string{0}\n{4}r''{0}\n\n{1}# Raw f-string{0}\n{17}rf''{0}\n{17}fr''{0}\n\n{1}# Raw byte string{0}\n{4}rb''{0}\n{4}br''{0}\n\n{1}# Raw unicode strings: ur'' is valid in 2.7 (but not in 3) -- always lexed as{0}\n{1}# valid; ru'' is never valid{0}\n{11}ru{4}''{0}\n{4}ur''{0}\n\n"
  },
  {
    "path": "test/examples/python/t-strings.py",
    "content": "# Simple nesting\nt\" { \"\" } \"\n\n# Multi-line field with comment\nt\" {\n\n\"\" # comment\n\n} \"\n\n# Single quoted continued with \\\nt\" \\\n\"\n\n# 4 nested t-strings\nt'Outer {t\"nested {1} {t\"nested {2} {t\"nested {3} {t\"nested {4}\"}\"}\"}\"}'\n"
  },
  {
    "path": "test/examples/python/t-strings.py.folded",
    "content": " 0 400   0   # Simple nesting\n 0 400   0   t\" { \"\" } \"\n 1 400   0   \n 0 400   0   # Multi-line field with comment\n 0 400   0   t\" {\n 1 400   0   \n 0 400   0   \"\" # comment\n 1 400   0   \n 0 400   0   } \"\n 1 400   0   \n 0 400   0   # Single quoted continued with \\\n 0 400   0   t\" \\\n 0 400   0   \"\n 1 400   0   \n 0 400   0   # 4 nested t-strings\n 0 400   0   t'Outer {t\"nested {1} {t\"nested {2} {t\"nested {3} {t\"nested {4}\"}\"}\"}\"}'\n 1 400   0   "
  },
  {
    "path": "test/examples/python/t-strings.py.styled",
    "content": "{1}# Simple nesting{0}\n{16}t\" {{0} {3}\"\"{0} {16}} \"{0}\n\n{1}# Multi-line field with comment{0}\n{16}t\" {{0}\n\n{3}\"\"{0} {1}# comment{0}\n\n{16}} \"{0}\n\n{1}# Single quoted continued with \\{0}\n{16}t\" \\\n\"{0}\n\n{1}# 4 nested t-strings{0}\n{17}t'Outer {{16}t\"nested {{2}1{16}} {t\"nested {{2}2{16}} {t\"nested {{2}3{16}} {t\"nested {{2}4{16}}\"}\"}\"}\"{17}}'{0}\n"
  },
  {
    "path": "test/examples/python/x.py",
    "content": "# Convert all punctuation characters except '_', '*', and '.' into spaces.\ndef depunctuate(s):\n\t'''A docstring'''\n\t\"\"\"Docstring 2\"\"\"\n\td = \"\"\n\tfor ch in s:\n\t\tif ch in 'abcde':\n\t\t\td = d + ch\n\t\telse:\n\t\t\td = d + \" \"\n\treturn d\n\nimport contextlib\n\n@contextlib.contextmanager\ndef singleuse():\n\tprint(\"Before\")\n\tyield\nwith singleuse(): pass\n"
  },
  {
    "path": "test/examples/python/x.py.folded",
    "content": " 0 400   0   # Convert all punctuation characters except '_', '*', and '.' into spaces.\n 2 400   0 + def depunctuate(s):\n 0 408   0 | \t'''A docstring'''\n 0 408   0 | \t\"\"\"Docstring 2\"\"\"\n 0 408   0 | \td = \"\"\n 2 408   0 + \tfor ch in s:\n 2 410   0 + \t\tif ch in 'abcde':\n 0 418   0 | \t\t\td = d + ch\n 2 410   0 + \t\telse:\n 0 418   0 | \t\t\td = d + \" \"\n 0 408   0 | \treturn d\n 1 400   0   \n 0 400   0   import contextlib\n 1 400   0   \n 0 400   0   @contextlib.contextmanager\n 2 400   0 + def singleuse():\n 0 408   0 | \tprint(\"Before\")\n 0 408   0 | \tyield\n 0 400   0   with singleuse(): pass\n 1 400   0   "
  },
  {
    "path": "test/examples/python/x.py.styled",
    "content": "{1}# Convert all punctuation characters except '_', '*', and '.' into spaces.{0}\n{5}def{0} {9}depunctuate{10}({11}s{10}):{0}\n\t{6}'''A docstring'''{0}\n\t{7}\"\"\"Docstring 2\"\"\"{0}\n\t{11}d{0} {10}={0} {3}\"\"{0}\n\t{5}for{0} {11}ch{0} {5}in{0} {11}s{10}:{0}\n\t\t{5}if{0} {11}ch{0} {5}in{0} {4}'abcde'{10}:{0}\n\t\t\t{11}d{0} {10}={0} {11}d{0} {10}+{0} {11}ch{0}\n\t\t{5}else{10}:{0}\n\t\t\t{11}d{0} {10}={0} {11}d{0} {10}+{0} {3}\" \"{0}\n\t{5}return{0} {11}d{0}\n\n{5}import{0} {11}contextlib{0}\n\n{15}@contextlib{10}.{11}contextmanager{0}\n{5}def{0} {9}singleuse{10}():{0}\n\t{5}print{10}({3}\"Before\"{10}){0}\n\t{5}yield{0}\n{5}with{0} {11}singleuse{10}():{0} {5}pass{0}\n"
  },
  {
    "path": "test/examples/r/102Backticks.r",
    "content": "# ugly code to demonstrate multiline string.\n`Hello\nWorld` <- function(x, y, z) {\n\tprint(x);\n\tprint(y);\n\tprint(z);\n}\n`Hello\\nWorld`(\"Hello\\nMoon!\", \"Hello\nVenus\", 'Hello\\\nMars');\n"
  },
  {
    "path": "test/examples/r/102Backticks.r.folded",
    "content": " 0 400 400   # ugly code to demonstrate multiline string.\n 0 400 400   `Hello\n 2 400 401 + World` <- function(x, y, z) {\n 0 401 401 | \tprint(x);\n 0 401 401 | \tprint(y);\n 0 401 401 | \tprint(z);\n 0 401 400 | }\n 0 400 400   `Hello\\nWorld`(\"Hello\\nMoon!\", \"Hello\n 0 400 400   Venus\", 'Hello\\\n 0 400 400   Mars');\n 0 400   0   "
  },
  {
    "path": "test/examples/r/102Backticks.r.styled",
    "content": "{1}# ugly code to demonstrate multiline string.{0}\n{12}`Hello\nWorld`{0} {8}<-{0} {9}function{8}({9}x{0}, {9}y{0}, {9}z{8}){0} {8}{{0}\n\t{9}print{8}({9}x{8}){0};\n\t{9}print{8}({9}y{8}){0};\n\t{9}print{8}({9}z{8}){0};\n{8}}{0}\n{12}`Hello\\nWorld`{8}({6}\"Hello\\nMoon!\"{0}, {6}\"Hello\nVenus\"{0}, {7}'Hello\\\nMars'{8}){0};\n"
  },
  {
    "path": "test/examples/r/AllStyles.r",
    "content": "# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Reserved-words\nif\n\n# base keyword (3)\nabbreviate\n\n# other keyword (4)\nacme\n\n# infix operator\n# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Special-operators\n%x%\n\n# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Literal-constants\n# Valid integer constants\n1L, 0x10L, 1000000L, 1e6L\n\n# Valid numeric constants\n1 10 0.1 .2 1e-7 1.2e+7\n1.1L, 1e-3L, 0x1.1p-2\n\n# Valid complex constants\n2i 4.1i 1e-2i\n\n# https://search.r-project.org/R/refmans/base/html/Quotes.html\n# single quotes\n'\"It\\'s alive!\", he screamed.'\n\n# double quotes\n\"\\\"It's alive!\\\", he screamed.\"\n\n# escape sequence\n\"\\n0\\r1\\t2\\b3\\a4\\f5\\\\6\\'7\\\"8\\`9\"\n\"\\1230\\x121\\u12342\\U000123453\\u{1234}4\\U{00012345}5\\\n6\\ 7\"\n# issue #206\n\"\\n\"\n\"\\r\\n\"\n\n# Backticks\nd$`1st column`\n\n# double quoted raw string\nr\"---(\\1--)-)---\"\n\n# single quoted raw string\nR'---(\\1--)-)---'\n\n# infix EOL (11)\n%a\n#back to comment\n"
  },
  {
    "path": "test/examples/r/AllStyles.r.folded",
    "content": " 0 400 400   # https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Reserved-words\n 0 400 400   if\n 1 400 400   \n 0 400 400   # base keyword (3)\n 0 400 400   abbreviate\n 1 400 400   \n 0 400 400   # other keyword (4)\n 0 400 400   acme\n 1 400 400   \n 0 400 400   # infix operator\n 0 400 400   # https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Special-operators\n 0 400 400   %x%\n 1 400 400   \n 0 400 400   # https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Literal-constants\n 0 400 400   # Valid integer constants\n 0 400 400   1L, 0x10L, 1000000L, 1e6L\n 1 400 400   \n 0 400 400   # Valid numeric constants\n 0 400 400   1 10 0.1 .2 1e-7 1.2e+7\n 0 400 400   1.1L, 1e-3L, 0x1.1p-2\n 1 400 400   \n 0 400 400   # Valid complex constants\n 0 400 400   2i 4.1i 1e-2i\n 1 400 400   \n 0 400 400   # https://search.r-project.org/R/refmans/base/html/Quotes.html\n 0 400 400   # single quotes\n 0 400 400   '\"It\\'s alive!\", he screamed.'\n 1 400 400   \n 0 400 400   # double quotes\n 0 400 400   \"\\\"It's alive!\\\", he screamed.\"\n 1 400 400   \n 0 400 400   # escape sequence\n 0 400 400   \"\\n0\\r1\\t2\\b3\\a4\\f5\\\\6\\'7\\\"8\\`9\"\n 0 400 400   \"\\1230\\x121\\u12342\\U000123453\\u{1234}4\\U{00012345}5\\\n 0 400 400   6\\ 7\"\n 0 400 400   # issue #206\n 0 400 400   \"\\n\"\n 0 400 400   \"\\r\\n\"\n 1 400 400   \n 0 400 400   # Backticks\n 0 400 400   d$`1st column`\n 1 400 400   \n 0 400 400   # double quoted raw string\n 0 400 400   r\"---(\\1--)-)---\"\n 1 400 400   \n 0 400 400   # single quoted raw string\n 0 400 400   R'---(\\1--)-)---'\n 1 400 400   \n 0 400 400   # infix EOL (11)\n 0 400 400   %a\n 0 400 400   #back to comment\n 0 400   0   "
  },
  {
    "path": "test/examples/r/AllStyles.r.styled",
    "content": "{1}# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Reserved-words{0}\n{2}if{0}\n\n{1}# base keyword (3){0}\n{3}abbreviate{0}\n\n{1}# other keyword (4){0}\n{4}acme{0}\n\n{1}# infix operator{0}\n{1}# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Special-operators{0}\n{10}%x%{0}\n\n{1}# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Literal-constants{0}\n{1}# Valid integer constants{0}\n{5}1L{0}, {5}0x10L{0}, {5}1000000L{0}, {5}1e6L{0}\n\n{1}# Valid numeric constants{0}\n{5}1{0} {5}10{0} {5}0.1{0} {5}.2{0} {5}1e-7{0} {5}1.2e+7{0}\n{5}1.1L{0}, {5}1e-3L{0}, {5}0x1.1p-2{0}\n\n{1}# Valid complex constants{0}\n{5}2i{0} {5}4.1i{0} {5}1e-2i{0}\n\n{1}# https://search.r-project.org/R/refmans/base/html/Quotes.html{0}\n{1}# single quotes{0}\n{7}'\"It{15}\\'{7}s alive!\", he screamed.'{0}\n\n{1}# double quotes{0}\n{6}\"{15}\\\"{6}It's alive!{15}\\\"{6}, he screamed.\"{0}\n\n{1}# escape sequence{0}\n{6}\"{15}\\n{6}0{15}\\r{6}1{15}\\t{6}2{15}\\b{6}3{15}\\a{6}4{15}\\f{6}5{15}\\\\{6}6{15}\\'{6}7{15}\\\"{6}8{15}\\`{6}9\"{0}\n{6}\"{15}\\123{6}0{15}\\x12{6}1{15}\\u1234{6}2{15}\\U00012345{6}3{15}\\u{1234}{6}4{15}\\U{00012345}{6}5{15}\\{6}\n6{15}\\ {6}7\"{0}\n{1}# issue #206{0}\n{6}\"{15}\\n{6}\"{0}\n{6}\"{15}\\r\\n{6}\"{0}\n\n{1}# Backticks{0}\n{9}d{8}${12}`1st column`{0}\n\n{1}# double quoted raw string{0}\n{13}r\"---(\\1--)-)---\"{0}\n\n{1}# single quoted raw string{0}\n{14}R'---(\\1--)-)---'{0}\n\n{1}# infix EOL (11){0}\n{11}%a\n{1}#back to comment{0}\n"
  },
  {
    "path": "test/examples/r/SciTE.properties",
    "content": "lexer.*.r=r\nkeywords.*.r=if\nkeywords2.*.r=abbreviate\nkeywords3.*.r=acme\nfold=1\nfold.compact=1\n\nmatch AllStyles.r\n\tlexer.r.escape.sequence=1\n"
  },
  {
    "path": "test/examples/raku/SciTE.properties",
    "content": "lexer.*.p6=raku\n# Keywords (base)\nkeywords.*.p6=BEGIN CATCH CHECK CONTROL END ENTER EVAL FIRST \\\n INIT KEEP LAST LEAVE NEXT POST PRE START TEMP UNDO after also andthen as \\\n async augment bag before but category circumfix class cmp complex constant \\\n contend default defer div does dynamic else elsif enum eq eqv extra fail \\\n fatal ff fff for gather gcd ge given grammar gt handles has if infix is lcm \\\n le leave leg let lift loop lt macro make maybe method mix mod module multi \\\n ne not o only oo or orelse orwith postcircumfix postfix prefix proto regex \\\n repeat require return-rw returns role rule size_t slang start str submethod \\\n subset supersede take temp term token trusts try unit unless until when \\\n where while with without x xor xx\n# Keywords (functions)\nkeywords2.*.p6=ACCEPTS AT-KEY EVALFILE EXISTS-KEY Filetests \\\n IO STORE abs accept acos acosec acosech acosh acotan acotanh alarm and \\\n antipairs asec asech asin asinh atan atan2 atanh base bind binmode bless \\\n break caller ceiling chars chdir chmod chomp chop chr chroot chrs cis close \\\n closedir codes comb conj connect contains continue cos cosec cosech cosh \\\n cotan cotanh crypt dbm defined die do dump each elems eof exec exists exit \\\n exp expmod fc fcntl fileno flat flip flock floor fmt fork formats functions \\\n get getc getpeername getpgrp getppid getpriority getsock gist glob gmtime \\\n goto grep hyper import index int invert ioctl is-prime iterator join keyof \\\n keys kill kv last lazy lc lcfirst lines link list listen local localtime \\\n lock log log10 lsb lstat map match mkdir msb msg my narrow new next no of \\\n open ord ords our pack package pairs path pick pipe polymod pop pos pred \\\n print printf prototype push quoting race rand read readdir readline readlink \\\n readpipe recv redo ref rename requires reset return reverse rewinddir rindex \\\n rmdir roots round samecase say scalar sec sech seek seekdir select semctl \\\n semget semop send set setpgrp setpriority setsockopt shift shm shutdown sign \\\n sin sinh sleep sockets sort splice split sprintf sqrt srand stat state study \\\n sub subst substr substr-rw succ symlink sys syscall system syswrite tan tanh \\\n tc tclc tell telldir tie time times trans trim trim-leading trim-trailing \\\n truncate uc ucfirst unimatch uniname uninames uniprop uniprops unival unlink \\\n unpack unpolar unshift untie use utime values wait waitpid wantarray warn \\\n wordcase words write\n# Keywords (types)\nkeywords3.*.p6=AST Any Block Bool CallFrame Callable Code \\\n Collation Compiler Complex ComplexStr Cool CurrentThreadScheduler Date \\\n DateTime Dateish Distribution Distribution::Hash Distribution::Locally \\\n Distribution::Path Duration Encoding Encoding::Registry Endian FatRat \\\n ForeignCode HyperSeq HyperWhatever Instant Int IntStr Junction Label \\\n Lock::Async Macro Method Mu Nil Num NumStr Numeric ObjAt Parameter Perl \\\n PredictiveIterator Proxy RaceSeq Rat RatStr Rational Real Routine \\\n Routine::WrapHandle Scalar Sequence Signature Str StrDistance Stringy Sub \\\n Submethod Telemetry Telemetry::Instrument::Thread \\\n Telemetry::Instrument::ThreadPool Telemetry::Instrument::Usage \\\n Telemetry::Period Telemetry::Sampler UInt ValueObjAt Variable Version \\\n Whatever WhateverCode atomicint bit bool buf buf1 buf16 buf2 buf32 buf4 \\\n buf64 buf8 int int1 int16 int2 int32 int4 int64 int8 long longlong num \\\n num32 num64 rat rat1 rat16 rat2 rat32 rat4 rat64 rat8 uint uint1 uint16 \\\n uint2 uint32 uint4 uint64 uint8 utf16 utf32 utf8\n# Keywords (types composite)\nkeywords4.*.p6=Array Associative Bag BagHash Baggy Blob Buf \\\n Capture Enumeration Hash Iterable Iterator List Map Mix MixHash Mixy NFC NFD \\\n NFKC NFKD Pair Positional PositionalBindFailover PseudoStash QuantHash Range \\\n Seq Set SetHash Setty Slip Stash Uni utf8\n# Keywords (types domain specific)\nkeywords5.*.p6=Attribute Cancellation Channel CompUnit \\\n CompUnit::Repository CompUnit::Repository::FileSystem \\\n CompUnit::Repository::Installation Distro Grammar IO IO::ArgFiles \\\n IO::CatHandle IO::Handle IO::Notification IO::Path IO::Path::Cygwin \\\n IO::Path::QNX IO::Path::Unix IO::Path::Win32 IO::Pipe IO::Socket \\\n IO::Socket::Async IO::Socket::INET IO::Spec IO::Spec::Cygwin \\\n IO::Spec::QNX IO::Spec::Unix IO::Spec::Win32 IO::Special Kernel Lock \\\n Match Order Pod::Block Pod::Block::Code Pod::Block::Comment \\\n Pod::Block::Declarator Pod::Block::Named Pod::Block::Para Pod::Block::Table \\\n Pod::Defn Pod::FormattingCode Pod::Heading Pod::Item Proc Proc::Async \\\n Promise Regex Scheduler Semaphore Supplier Supplier::Preserving Supply \\\n Systemic Tap Thread ThreadPoolScheduler VM\n# Keywords (types domain exceptions)\nkeywords6.*.p6=Backtrace Backtrace::Frame CX::Done CX::Emit \\\n CX::Last CX::Next CX::Proceed CX::Redo CX::Return CX::Succeed CX::Take \\\n CX::Warn Exception Failure X::AdHoc X::Anon::Augment X::Anon::Multi \\\n X::Assignment::RO X::Attribute::NoPackage X::Attribute::Package \\\n X::Attribute::Required X::Attribute::Undeclared X::Augment::NoSuchType \\\n X::Bind X::Bind::NativeType X::Bind::Slice X::Caller::NotDynamic \\\n X::Channel::ReceiveOnClosed X::Channel::SendOnClosed X::Comp \\\n X::Composition::NotComposable X::Constructor::Positional X::Control \\\n X::ControlFlow X::ControlFlow::Return X::DateTime::TimezoneClash \\\n X::Declaration::Scope X::Declaration::Scope::Multi X::Does::TypeObject \\\n X::Dynamic::NotFound X::Eval::NoSuchLang X::Export::NameClash X::IO \\\n X::IO::Chdir X::IO::Chmod X::IO::Copy X::IO::Cwd X::IO::Dir X::IO::DoesNotExist \\\n X::IO::Link X::IO::Mkdir X::IO::Move X::IO::Rename X::IO::Rmdir \\\n X::IO::Symlink X::IO::Unlink X::Inheritance::NotComposed \\\n X::Inheritance::Unsupported X::Method::InvalidQualifier X::Method::NotFound \\\n X::Method::Private::Permission X::Method::Private::Unqualified \\\n X::Mixin::NotComposable X::NYI X::NoDispatcher X::Numeric::Real \\\n X::OS X::Obsolete X::OutOfRange X::Package::Stubbed X::Parameter::Default \\\n X::Parameter::MultipleTypeConstraints X::Parameter::Placeholder \\\n X::Parameter::Twigil X::Parameter::WrongOrder X::Phaser::Multiple \\\n X::Phaser::PrePost X::Placeholder::Block X::Placeholder::Mainline \\\n X::Pod X::Proc::Async X::Proc::Async::AlreadyStarted X::Proc::Async::BindOrUse \\\n X::Proc::Async::CharsOrBytes X::Proc::Async::MustBeStarted \\\n X::Proc::Async::OpenForWriting X::Proc::Async::TapBeforeSpawn \\\n X::Proc::Unsuccessful X::Promise::CauseOnlyValidOnBroken X::Promise::Vowed \\\n X::Redeclaration X::Role::Initialization X::Scheduler::CueInNaNSeconds \\\n X::Seq::Consumed X::Sequence::Deduction X::Signature::NameClash \\\n X::Signature::Placeholder X::Str::Numeric X::StubCode X::Syntax \\\n X::Syntax::Augment::WithoutMonkeyTyping X::Syntax::Comment::Embedded \\\n X::Syntax::Confused X::Syntax::InfixInTermPosition X::Syntax::Malformed \\\n X::Syntax::Missing X::Syntax::NegatedPair X::Syntax::NoSelf \\\n X::Syntax::Number::RadixOutOfRange X::Syntax::P5 X::Syntax::Perl5Var \\\n X::Syntax::Regex::Adverb X::Syntax::Regex::SolitaryQuantifier \\\n X::Syntax::Reserved X::Syntax::Self::WithoutObject \\\n X::Syntax::Signature::InvocantMarker X::Syntax::Term::MissingInitializer \\\n X::Syntax::UnlessElse X::Syntax::Variable::Match X::Syntax::Variable::Numeric \\\n X::Syntax::Variable::Twigil X::Temporal X::Temporal::InvalidFormat \\\n X::TypeCheck X::TypeCheck::Assignment X::TypeCheck::Binding \\\n X::TypeCheck::Return X::TypeCheck::Splice X::Undeclared\n# Keywords (adverbs)\nkeywords7.*.p6=D a array b backslash c closure delete double \\\n exec exists f function h hash heredoc k kv p q qq quotewords s scalar single \\\n sym to v val w words ww x\nfold.compact=1\n"
  },
  {
    "path": "test/examples/raku/x.p6",
    "content": "use v6;\n\n# Normal single line comment\nmy Int $i = 0;\nmy Rat $r = 3.142;\nmy Str $backslash = \"\\\\\";\nmy Str $s = \"Hello, world! \\$i == $i and \\$r == $r\";\nsay $s;\n\n#`{{\n*** This is a multi-line comment ***\n}}\n\nmy @array = #`[[ inline comment ]] <f fo foo food>;\nmy %hash = ( AAA => 1, BBB => 2 );\n\nsay q[This back\\slash stays];\nsay q[This back\\\\slash stays]; # Identical output\nsay Q:q!Just a literal \"\\n\" here!;\n\n=begin pod\nPOD Documentation...\n=end pod\n\nsay qq:to/END/;\nA multi-line\nstring with interpolated vars: $i, $r\nEND\n\nsub function {\n\treturn q:to/END/;\nHere is\nsome multi-line\nstring\nEND\n}\n\nmy $func = &function;\nsay $func();\n\ngrammar Calculator {\n\ttoken TOP\t\t\t\t\t{ <calc-op> }\n\tproto rule calc-op\t\t\t{*}\n\t\t  rule calc-op:sym<add>\t{ <num> '+' <num> }\n\t\t  rule calc-op:sym<sub>\t{ <num> '-' <num> }\n    token num\t\t\t\t\t{ \\d+ }\n}\n\nclass Calculations {\n\tmethod TOP              ($/) { make $<calc-op>.made; }\n\tmethod calc-op:sym<add> ($/) { make [+] $<num>; }\n\tmethod calc-op:sym<sub> ($/) { make [-] $<num>; }\n}\n\nsay Calculator.parse('2 + 3', actions => Calculations).made;\n"
  },
  {
    "path": "test/examples/raku/x.p6.folded",
    "content": " 0 400 400   use v6;\n 1 400 400   \n 0 400 400   # Normal single line comment\n 0 400 400   my Int $i = 0;\n 0 400 400   my Rat $r = 3.142;\n 0 400 400   my Str $backslash = \"\\\\\";\n 0 400 400   my Str $s = \"Hello, world! \\$i == $i and \\$r == $r\";\n 0 400 400   say $s;\n 1 400 400   \n 2 400 401 + #`{{\n 0 401 401 | *** This is a multi-line comment ***\n 0 401 400 | }}\n 1 400 400   \n 0 400 400   my @array = #`[[ inline comment ]] <f fo foo food>;\n 0 400 400   my %hash = ( AAA => 1, BBB => 2 );\n 1 400 400   \n 0 400 400   say q[This back\\slash stays];\n 0 400 400   say q[This back\\\\slash stays]; # Identical output\n 0 400 400   say Q:q!Just a literal \"\\n\" here!;\n 1 400 400   \n 2 400 401 + =begin pod\n 0 401 401 | POD Documentation...\n 0 401 400 | =end pod\n 1 400 400   \n 0 400 400   say qq:to/END/;\n 0 400 400   A multi-line\n 0 400 400   string with interpolated vars: $i, $r\n 0 400 400   END\n 1 400 400   \n 2 400 401 + sub function {\n 0 401 401 | \treturn q:to/END/;\n 0 401 401 | Here is\n 0 401 401 | some multi-line\n 0 401 401 | string\n 0 401 401 | END\n 0 401 400 | }\n 1 400 400   \n 0 400 400   my $func = &function;\n 0 400 400   say $func();\n 1 400 400   \n 2 400 401 + grammar Calculator {\n 0 401 401 | \ttoken TOP\t\t\t\t\t{ <calc-op> }\n 0 401 401 | \tproto rule calc-op\t\t\t{*}\n 0 401 401 | \t\t  rule calc-op:sym<add>\t{ <num> '+' <num> }\n 0 401 401 | \t\t  rule calc-op:sym<sub>\t{ <num> '-' <num> }\n 0 401 401 |     token num\t\t\t\t\t{ \\d+ }\n 0 401 400 | }\n 1 400 400   \n 2 400 401 + class Calculations {\n 0 401 401 | \tmethod TOP              ($/) { make $<calc-op>.made; }\n 0 401 401 | \tmethod calc-op:sym<add> ($/) { make [+] $<num>; }\n 0 401 401 | \tmethod calc-op:sym<sub> ($/) { make [-] $<num>; }\n 0 401 400 | }\n 1 400 400   \n 0 400 400   say Calculator.parse('2 + 3', actions => Calculations).made;\n 0 400   0   "
  },
  {
    "path": "test/examples/raku/x.p6.styled",
    "content": "{20}use{0} {16}v6{18};{0}\n\n{2}# Normal single line comment{0}\n{20}my{0} {22}Int{0} {23}$i{0} {18}={0} {16}0{18};{0}\n{20}my{0} {22}Rat{0} {23}$r{0} {18}={0} {16}3.142{18};{0}\n{20}my{0} {22}Str{0} {23}$backslash{0} {18}={0} {8}\"\\\\\"{18};{0}\n{20}my{0} {22}Str{0} {23}$s{0} {18}={0} {8}\"Hello, world! \\$i == {12}$i{8} and \\$r == {12}$r{8}\"{18};{0}\n{20}say{0} {23}$s{18};{0}\n\n{2}#`{3}{{\n*** This is a multi-line comment ***\n}}{0}\n\n{20}my{0} {24}@array{0} {18}={0} {2}#`{3}[[ inline comment ]]{0} {9}<f fo foo food>{18};{0}\n{20}my{0} {25}%hash{0} {18}={0} {18}({0} {21}AAA{0} {18}=>{0} {16}1{18},{0} {21}BBB{0} {18}=>{0} {16}2{0} {18});{0}\n\n{20}say{0} {9}q[This back\\slash stays]{18};{0}\n{20}say{0} {9}q[This back\\\\slash stays]{18};{0} {2}# Identical output{0}\n{20}say{0} {11}Q{15}:q{11}!Just a literal \"\\n\" here!{18};{0}\n\n{4}=begin pod\nPOD Documentation...\n=end pod{0}\n\n{20}say{0} {10}qq{15}:to{10}/END/{18};{0}\n{7}A multi-line\nstring with interpolated vars: {12}$i{7}, {12}$r{7}\nEND{0}\n\n{20}sub{0} {21}function{0} {18}{{0}\n\t{20}return{0} {9}q{15}:to{9}/END/{18};{0}\n{6}Here is\nsome multi-line\nstring\nEND{0}\n{18}}{0}\n\n{20}my{0} {23}$func{0} {18}={0} {26}&function{18};{0}\n{20}say{0} {23}$func{18}();{0}\n\n{19}grammar{0} {27}Calculator{0} {18}{{0}\n\t{19}token{0} {21}TOP{0}\t\t\t\t\t{13}{ <calc-op> }{0}\n\t{19}proto{0} {19}rule{0} {21}calc-op{0}\t\t\t{13}{*}{0}\n\t\t  {19}rule{0} {21}calc-op{15}:sym{18}<{21}add{18}>{0}\t{13}{ <num> '+' <num> }{0}\n\t\t  {19}rule{0} {21}calc-op{15}:sym{18}<{21}sub{18}>{0}\t{13}{ <num> '-' <num> }{0}\n    {19}token{0} {21}num{0}\t\t\t\t\t{13}{ \\d+ }{0}\n{18}}{0}\n\n{19}class{0} {28}Calculations{0} {18}{{0}\n\t{19}method{0} {21}TOP{0}              {18}({23}$/{18}){0} {18}{{0} {19}make{0} {23}${18}<{23}calc-op{18}>.{21}made{18};{0} {18}}{0}\n\t{19}method{0} {21}calc-op{15}:sym{18}<{21}add{18}>{0} {18}({23}$/{18}){0} {18}{{0} {21}make{0} {18}[+]{0} {23}${18}<{23}num{18}>;{0} {18}}{0}\n\t{19}method{0} {21}calc-op{15}:sym{18}<{21}sub{18}>{0} {18}({23}$/{18}){0} {18}{{0} {21}make{0} {18}[-]{0} {23}${18}<{23}num{18}>;{0} {18}}{0}\n{18}}{0}\n\n{20}say{0} {21}Calculator{18}.{21}parse{18}({8}'2 + 3'{18},{0} {21}actions{0} {18}=>{0} {21}Calculations{18}).{21}made{18};{0}\n"
  },
  {
    "path": "test/examples/ruby/225NumberDotMethod.rb",
    "content": "# Float Literals\n12.34\n1234e-2\n1.234E1\n# Range Literals\n(1..2)\n(2.0..3)\n# Method on number\n1.5.ceil\n1ri.abs\n3.times {|i| puts i}\n3. times {|i| puts i}\n"
  },
  {
    "path": "test/examples/ruby/225NumberDotMethod.rb.folded",
    "content": " 0 400   0   # Float Literals\n 0 400   0   12.34\n 0 400   0   1234e-2\n 0 400   0   1.234E1\n 0 400   0   # Range Literals\n 0 400   0   (1..2)\n 0 400   0   (2.0..3)\n 0 400   0   # Method on number\n 0 400   0   1.5.ceil\n 0 400   0   1ri.abs\n 0 400   0   3.times {|i| puts i}\n 0 400   0   3. times {|i| puts i}\n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/225NumberDotMethod.rb.styled",
    "content": "{2}# Float Literals{0}\n{4}12.34{0}\n{4}1234e{10}-{4}2{0}\n{4}1.234E1{0}\n{2}# Range Literals{0}\n{10}({4}1{10}..{4}2{10}){0}\n{10}({4}2.0{10}..{4}3{10}){0}\n{2}# Method on number{0}\n{4}1.5{10}.{11}ceil{0}\n{4}1ri{10}.{11}abs{0}\n{4}3{10}.{11}times{0} {10}{|{11}i{10}|{0} {11}puts{0} {11}i{10}}{0}\n{4}3{10}.{0} {11}times{0} {10}{|{11}i{10}|{0} {11}puts{0} {11}i{10}}{0}\n"
  },
  {
    "path": "test/examples/ruby/234HereDoc.rb",
    "content": "# encoding: utf-8\nputs <<A中\n#{1+2}\nA中\n\nputs <<中\n#{1+2}\n中\n\ndef STDERR::error(x) = puts(x)\ndef STDERR.error(x) = puts(x)\n\nSTDERR.error <<EOF\nSTDERR heredoc\nEOF\n"
  },
  {
    "path": "test/examples/ruby/234HereDoc.rb.folded",
    "content": " 0 400   0   # encoding: utf-8\n 2 400   0 + puts <<A中\n 0 401   0 | #{1+2}\n 0 401   0 | A中\n 1 400   0   \n 2 400   0 + puts <<中\n 0 401   0 | #{1+2}\n 0 401   0 | 中\n 1 400   0   \n 0 400   0   def STDERR::error(x) = puts(x)\n 0 400   0   def STDERR.error(x) = puts(x)\n 1 400   0   \n 2 400   0 + STDERR.error <<EOF\n 0 401   0 | STDERR heredoc\n 0 401   0 | EOF\n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/234HereDoc.rb.styled",
    "content": "{2}# encoding: utf-8{0}\n{11}puts{0} {10}<<{20}A中{22}\n{10}#{{4}1{10}+{4}2{10}}{22}\n{20}A中{0}\n\n{11}puts{0} {10}<<{20}中{22}\n{10}#{{4}1{10}+{4}2{10}}{22}\n{20}中{0}\n\n{5}def{0} {128}STDERR{10}::{9}error{10}({11}x{10}){0} {10}={0} {11}puts{10}({11}x{10}){0}\n{5}def{0} {128}STDERR{10}.{9}error{10}({11}x{10}){0} {10}={0} {11}puts{10}({11}x{10}){0}\n\n{128}STDERR{10}.{11}error{0} {10}<<{20}EOF{22}\nSTDERR heredoc\n{20}EOF{0}\n"
  },
  {
    "path": "test/examples/ruby/AllStyles.rb",
    "content": "# Enumerate all styles where possible: 0..31,40..45\n# 30,31,40,45 are never set and 1 switches rest of file to error state\n\n#0 whitespace\n    #\n\t#\n\n#1:error, can be set with a heredoc delimiter >256 characters but that can't be recovered from\n#<<ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789\n\n#2:comment line\n\n#3:POD\n=begin\n3:POD\n=end\n\n#4:number\n4\n\n#5:word\nsuper\n\n#6:string\n\"6:double quotes\"\n\n#7:single quoted string\n'7:single quotes'\n\n#8:class name\nclass ClassName end\n\n#9:def name\ndef Function end\n\n#10:operator\n&\n\n#11:identifier\nidentifier\n\n#12:regex\n/[12a-z]/\n\n#13:global\n$global13\n\n#14:symbol\n:symbol14\n\n#15:module name\nmodule Module15 end\n\n#16:instance var\n@instance16\n\n#17:class var\n@@class17\n\n#18:back ticks\n`18`\n\n#19:data section at end of file\n\n#20:here delimiter\n<<DELIMITER20\nDELIMITER20\n\n#21:single quoted heredoc\n<<'D'\n21:here doc #{1 + 1}\nD\n\n#22:double quoted heredoc\n<<\"D\"\n22:here doc #{1 + 1}\nD\n\n#23:back tick quoted heredoc\n<<`D`\n23:here doc #{1 + 1}\nD\n\n#24:q quoted string\n%q!24:quotes's!\n\n#25:Q quoted string\n%Q!25:quotes\"s!\n\n#26:executed string\n%x(echo 26)\n\n#27:regex\n%r(27[a-z]/[A-Z]+)\n\n#28:interpolable string array\n%W(28 cgi.rb complex.rb date.rb #{1} )\n\n#29:demoted keyword do\nwhile 1 do end\n\n# 30,31,40,45 never set\n\n#41:non-interpolable string array\n%w(#{1 + 1})\n\n#42:non-interpolable symbol array\n%i(#{1 + 1})\n\n#43:interpolable symbol array\n%I(#{1 + 1})\n\n#44:symbol\n%s(#{1 + 1})\n\n#128:user keywords 1\ndecrypt\n\n#129:user keywords 2\nencrypt\n\n#19:data section\n__END__\n\n"
  },
  {
    "path": "test/examples/ruby/AllStyles.rb.folded",
    "content": " 0 400   0   # Enumerate all styles where possible: 0..31,40..45\n 0 400   0   # 30,31,40,45 are never set and 1 switches rest of file to error state\n 1 400   0   \n 0 400   0   #0 whitespace\n 0 400   0       #\n 0 400   0   \t#\n 1 400   0   \n 0 400   0   #1:error, can be set with a heredoc delimiter >256 characters but that can't be recovered from\n 0 400   0   #<<ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789\n 1 400   0   \n 0 400   0   #2:comment line\n 1 400   0   \n 0 400   0   #3:POD\n 0 400   0   =begin\n 0 400   0   3:POD\n 0 400   0   =end\n 1 400   0   \n 0 400   0   #4:number\n 0 400   0   4\n 1 400   0   \n 0 400   0   #5:word\n 0 400   0   super\n 1 400   0   \n 0 400   0   #6:string\n 0 400   0   \"6:double quotes\"\n 1 400   0   \n 0 400   0   #7:single quoted string\n 0 400   0   '7:single quotes'\n 1 400   0   \n 0 400   0   #8:class name\n 0 400   0   class ClassName end\n 1 400   0   \n 0 400   0   #9:def name\n 0 400   0   def Function end\n 1 400   0   \n 0 400   0   #10:operator\n 0 400   0   &\n 1 400   0   \n 0 400   0   #11:identifier\n 0 400   0   identifier\n 1 400   0   \n 0 400   0   #12:regex\n 0 400   0   /[12a-z]/\n 1 400   0   \n 0 400   0   #13:global\n 0 400   0   $global13\n 1 400   0   \n 0 400   0   #14:symbol\n 0 400   0   :symbol14\n 1 400   0   \n 0 400   0   #15:module name\n 0 400   0   module Module15 end\n 1 400   0   \n 0 400   0   #16:instance var\n 0 400   0   @instance16\n 1 400   0   \n 0 400   0   #17:class var\n 0 400   0   @@class17\n 1 400   0   \n 0 400   0   #18:back ticks\n 0 400   0   `18`\n 1 400   0   \n 0 400   0   #19:data section at end of file\n 1 400   0   \n 0 400   0   #20:here delimiter\n 2 400   0 + <<DELIMITER20\n 0 401   0 | DELIMITER20\n 1 400   0   \n 0 400   0   #21:single quoted heredoc\n 2 400   0 + <<'D'\n 0 401   0 | 21:here doc #{1 + 1}\n 0 401   0 | D\n 1 400   0   \n 0 400   0   #22:double quoted heredoc\n 2 400   0 + <<\"D\"\n 0 401   0 | 22:here doc #{1 + 1}\n 0 401   0 | D\n 1 400   0   \n 0 400   0   #23:back tick quoted heredoc\n 2 400   0 + <<`D`\n 0 401   0 | 23:here doc #{1 + 1}\n 0 401   0 | D\n 1 400   0   \n 0 400   0   #24:q quoted string\n 0 400   0   %q!24:quotes's!\n 1 400   0   \n 0 400   0   #25:Q quoted string\n 0 400   0   %Q!25:quotes\"s!\n 1 400   0   \n 0 400   0   #26:executed string\n 0 400   0   %x(echo 26)\n 1 400   0   \n 0 400   0   #27:regex\n 0 400   0   %r(27[a-z]/[A-Z]+)\n 1 400   0   \n 0 400   0   #28:interpolable string array\n 0 400   0   %W(28 cgi.rb complex.rb date.rb #{1} )\n 1 400   0   \n 0 400   0   #29:demoted keyword do\n 0 400   0   while 1 do end\n 1 400   0   \n 0 400   0   # 30,31,40,45 never set\n 1 400   0   \n 0 400   0   #41:non-interpolable string array\n 0 400   0   %w(#{1 + 1})\n 1 400   0   \n 0 400   0   #42:non-interpolable symbol array\n 0 400   0   %i(#{1 + 1})\n 1 400   0   \n 0 400   0   #43:interpolable symbol array\n 0 400   0   %I(#{1 + 1})\n 1 400   0   \n 0 400   0   #44:symbol\n 0 400   0   %s(#{1 + 1})\n 1 400   0   \n 0 400   0   #128:user keywords 1\n 0 400   0   decrypt\n 1 400   0   \n 0 400   0   #129:user keywords 2\n 0 400   0   encrypt\n 1 400   0   \n 0 400   0   #19:data section\n 0 400   0   __END__\n 1 400   0   \n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/AllStyles.rb.styled",
    "content": "{2}# Enumerate all styles where possible: 0..31,40..45{0}\n{2}# 30,31,40,45 are never set and 1 switches rest of file to error state{0}\n\n{2}#0 whitespace{0}\n    {2}#{0}\n\t{2}#{0}\n\n{2}#1:error, can be set with a heredoc delimiter >256 characters but that can't be recovered from{0}\n{2}#<<ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789{0}\n\n{2}#2:comment line{0}\n\n{2}#3:POD{0}\n{3}=begin\n3:POD\n=end{0}\n\n{2}#4:number{0}\n{4}4{0}\n\n{2}#5:word{0}\n{5}super{0}\n\n{2}#6:string{0}\n{6}\"6:double quotes\"{0}\n\n{2}#7:single quoted string{0}\n{7}'7:single quotes'{0}\n\n{2}#8:class name{0}\n{5}class{0} {8}ClassName{0} {5}end{0}\n\n{2}#9:def name{0}\n{5}def{0} {9}Function{0} {5}end{0}\n\n{2}#10:operator{0}\n{10}&{0}\n\n{2}#11:identifier{0}\n{11}identifier{0}\n\n{2}#12:regex{0}\n{12}/[12a-z]/{0}\n\n{2}#13:global{0}\n{13}$global13{0}\n\n{2}#14:symbol{0}\n{14}:symbol14{0}\n\n{2}#15:module name{0}\n{5}module{0} {15}Module15{0} {5}end{0}\n\n{2}#16:instance var{0}\n{16}@instance16{0}\n\n{2}#17:class var{0}\n{17}@@class17{0}\n\n{2}#18:back ticks{0}\n{18}`18`{0}\n\n{2}#19:data section at end of file{0}\n\n{2}#20:here delimiter{0}\n{10}<<{20}DELIMITER20{22}\n{20}DELIMITER20{0}\n\n{2}#21:single quoted heredoc{0}\n{10}<<{20}'D'{21}\n21:here doc #{1 + 1}\n{20}D{0}\n\n{2}#22:double quoted heredoc{0}\n{10}<<{20}\"D\"{22}\n22:here doc {10}#{{4}1{0} {10}+{0} {4}1{10}}{22}\n{20}D{0}\n\n{2}#23:back tick quoted heredoc{0}\n{10}<<{20}`D`{23}\n23:here doc {10}#{{4}1{0} {10}+{0} {4}1{10}}{23}\n{20}D{0}\n\n{2}#24:q quoted string{0}\n{24}%q!24:quotes's!{0}\n\n{2}#25:Q quoted string{0}\n{25}%Q!25:quotes\"s!{0}\n\n{2}#26:executed string{0}\n{26}%x(echo 26){0}\n\n{2}#27:regex{0}\n{27}%r(27[a-z]/[A-Z]+){0}\n\n{2}#28:interpolable string array{0}\n{28}%W(28 cgi.rb complex.rb date.rb {10}#{{4}1{10}}{28} ){0}\n\n{2}#29:demoted keyword do{0}\n{5}while{0} {4}1{0} {29}do{0} {5}end{0}\n\n{2}# 30,31,40,45 never set{0}\n\n{2}#41:non-interpolable string array{0}\n{41}%w(#{1 + 1}){0}\n\n{2}#42:non-interpolable symbol array{0}\n{42}%i(#{1 + 1}){0}\n\n{2}#43:interpolable symbol array{0}\n{43}%I({10}#{{4}1{0} {10}+{0} {4}1{10}}{43}){0}\n\n{2}#44:symbol{0}\n{44}%s(#{1 + 1}){0}\n\n{2}#128:user keywords 1{0}\n{128}decrypt{0}\n\n{2}#129:user keywords 2{0}\n{129}encrypt{0}\n\n{2}#19:data section{0}\n{19}__END__\n\n"
  },
  {
    "path": "test/examples/ruby/Issue132.rb",
    "content": "# Bad folding when single character ')' in SCE_RB_STRING_QW #132\n%W(#{1 + 1})\n\n"
  },
  {
    "path": "test/examples/ruby/Issue132.rb.folded",
    "content": " 0 400   0   # Bad folding when single character ')' in SCE_RB_STRING_QW #132\n 0 400   0   %W(#{1 + 1})\n 1 400   0   \n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/Issue132.rb.styled",
    "content": "{2}# Bad folding when single character ')' in SCE_RB_STRING_QW #132{0}\n{28}%W({10}#{{4}1{0} {10}+{0} {4}1{10}}{28}){0}\n\n"
  },
  {
    "path": "test/examples/ruby/Issue135.rb",
    "content": "a = <<XXX # :nodoc:\nheredoc\nXXX\n\nputs(<<-ONE, <<-TWO)\ncontent for heredoc one\nONE\ncontent for heredoc two\nTWO\n"
  },
  {
    "path": "test/examples/ruby/Issue135.rb.folded",
    "content": " 2 400   0 + a = <<XXX # :nodoc:\n 0 401   0 | heredoc\n 0 401   0 | XXX\n 1 400   0   \n 2 400   0 + puts(<<-ONE, <<-TWO)\n 0 401   0 | content for heredoc one\n 0 401   0 | ONE\n 0 401   0 | content for heredoc two\n 0 401   0 | TWO\n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/Issue135.rb.styled",
    "content": "{11}a{0} {10}={0} {10}<<{20}XXX{0} {2}# :nodoc:{22}\nheredoc\n{20}XXX{0}\n\n{11}puts{10}(<<{20}-ONE{10},{0} {10}<<{20}-TWO{10}){22}\ncontent for heredoc one\nONE\ncontent for heredoc two\n{20}TWO{0}\n"
  },
  {
    "path": "test/examples/ruby/Issue136.rb",
    "content": "a = {r: /\\w+/, h: <<EOF\nheredoc\nEOF\n}\n\nputs a\n\ndef b # :nodoc:\n<<EOF\nheredoc\nEOF\nend\n\ndef c # :nodoc:\n/\\w+/\nend\n\nputs b\nputs c\n\n$stdout . puts <<EOF\nheredoc\nEOF\n"
  },
  {
    "path": "test/examples/ruby/Issue136.rb.folded",
    "content": " 2 400   0 + a = {r: /\\w+/, h: <<EOF\n 0 402   0 | heredoc\n 0 402   0 | EOF\n 0 401   0 | }\n 1 400   0   \n 0 400   0   puts a\n 1 400   0   \n 2 400   0 + def b # :nodoc:\n 2 401   0 + <<EOF\n 0 402   0 | heredoc\n 0 402   0 | EOF\n 0 401   0 | end\n 1 400   0   \n 2 400   0 + def c # :nodoc:\n 0 401   0 | /\\w+/\n 0 401   0 | end\n 1 400   0   \n 0 400   0   puts b\n 0 400   0   puts c\n 1 400   0   \n 2 400   0 + $stdout . puts <<EOF\n 0 401   0 | heredoc\n 0 401   0 | EOF\n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/Issue136.rb.styled",
    "content": "{11}a{0} {10}={0} {10}{{14}r:{0} {12}/\\w+/{10},{0} {14}h:{0} {10}<<{20}EOF{22}\nheredoc\n{20}EOF{0}\n{10}}{0}\n\n{11}puts{0} {11}a{0}\n\n{5}def{0} {9}b{0} {2}# :nodoc:{0}\n{10}<<{20}EOF{22}\nheredoc\n{20}EOF{0}\n{5}end{0}\n\n{5}def{0} {9}c{0} {2}# :nodoc:{0}\n{12}/\\w+/{0}\n{5}end{0}\n\n{11}puts{0} {11}b{0}\n{11}puts{0} {11}c{0}\n\n{13}$stdout{0} {10}.{0} {11}puts{0} {10}<<{20}EOF{22}\nheredoc\n{20}EOF{0}\n"
  },
  {
    "path": "test/examples/ruby/Issue140.rb",
    "content": "\"#{1}\"#\n\"#@a\"#\n\"#@@a\"#\n\"#$a\"#\n\"#$?\"#\n\"#$-a1\"#\n\"#$_a1\"#\n\"#$123\"#\n\"#$\\\"#\n\"#$\"\"#\na = /#$//#\n"
  },
  {
    "path": "test/examples/ruby/Issue140.rb.folded",
    "content": " 0 400   0   \"#{1}\"#\n 0 400   0   \"#@a\"#\n 0 400   0   \"#@@a\"#\n 0 400   0   \"#$a\"#\n 0 400   0   \"#$?\"#\n 0 400   0   \"#$-a1\"#\n 0 400   0   \"#$_a1\"#\n 0 400   0   \"#$123\"#\n 0 400   0   \"#$\\\"#\n 0 400   0   \"#$\"\"#\n 0 400   0   a = /#$//#\n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/Issue140.rb.styled",
    "content": "{6}\"{10}#{{4}1{10}}{6}\"{2}#{0}\n{6}\"{10}#{16}@a{6}\"{2}#{0}\n{6}\"{10}#{17}@@a{6}\"{2}#{0}\n{6}\"{10}#{13}$a{6}\"{2}#{0}\n{6}\"{10}#{13}$?{6}\"{2}#{0}\n{6}\"{10}#{13}$-a{6}1\"{2}#{0}\n{6}\"{10}#{13}$_a1{6}\"{2}#{0}\n{6}\"{10}#{13}$123{6}\"{2}#{0}\n{6}\"{10}#{13}$\\{6}\"{2}#{0}\n{6}\"{10}#{13}$\"{6}\"{2}#{0}\n{11}a{0} {10}={0} {12}/{10}#{13}$/{12}/{2}#{0}\n"
  },
  {
    "path": "test/examples/ruby/Issue65.rb",
    "content": "def dbg_args(a, b=1, c:, d: 6, &block) = puts(\"Args passed: #{[a, b, c, d, block.call]}\")\ndbg_args(0, c: 5) { 7 }\n\nclass A\n\tdef attr = @attr\n\tdef attr=(value)\n\t\t@attr = value\n\tend\n\tdef attr? = !!@attr\n\tdef attr! = @attr = true\n\t# unary operator\n\tdef -@ = 1\n\tdef +@ = 1\n\tdef ! = 1\n\tdef !@ = 1\n\t# binary operator\n\tdef +(value) = 1 + value\n\tdef -(value) = 1 - value\n\tdef *(value) = 1 * value\n\tdef **(value) = 1 ** value\n\tdef /(value) = 1 / value\n\tdef %(value) = 1 % value\n\tdef &(value) = 1 & value\n\tdef ^(value) = 1 ^ value\n\tdef >>(value) = 1 >> value\n\tdef <<(value) = 1 << value\n\tdef ==(other) = true\n\tdef !=(other) = true\n\tdef ===(other) = true\n\tdef =~(other) = true\n\tdef <=>(other) = true\n\tdef <(other) = true\n\tdef <=(other) = true\n\tdef >(other) = true\n\tdef >=(other) = true\n\t# element reference and assignment\n\tdef [](a, b) = puts(a + b)\n\tdef []=(a, b, c)\n\t\tputs a + b + c\n\tend\n\t# array decomposition\n\tdef dec(((a, b), c)) = puts(a + b + c)\n\t# class method\n\tdef self::say(*s) = puts(s)\n\tdef self.say(*s) = puts(s)\n\t# test short method name\n\tdef a = 1\n\tdef ab = 1\nend\n\n# class method\ndef String.hello\n  \"Hello, world!\"\nend\n# singleton method\ngreeting = \"Hello\"\ndef greeting.broaden\n  self + \", world!\"\nend\n# one line definition\ndef a(b, c) b; c end\n# parentheses omitted\ndef ab c\n\tputs c\nend\n\n# Test folding of multi-line SCE_RB_STRING_QW\nputs %W(\na\nb\nc\n)\n"
  },
  {
    "path": "test/examples/ruby/Issue65.rb.folded",
    "content": " 0 400   0   def dbg_args(a, b=1, c:, d: 6, &block) = puts(\"Args passed: #{[a, b, c, d, block.call]}\")\n 0 400   0   dbg_args(0, c: 5) { 7 }\n 1 400   0   \n 2 400   0 + class A\n 0 401   0 | \tdef attr = @attr\n 2 401   0 + \tdef attr=(value)\n 0 402   0 | \t\t@attr = value\n 0 402   0 | \tend\n 0 401   0 | \tdef attr? = !!@attr\n 0 401   0 | \tdef attr! = @attr = true\n 0 401   0 | \t# unary operator\n 0 401   0 | \tdef -@ = 1\n 0 401   0 | \tdef +@ = 1\n 0 401   0 | \tdef ! = 1\n 0 401   0 | \tdef !@ = 1\n 0 401   0 | \t# binary operator\n 0 401   0 | \tdef +(value) = 1 + value\n 0 401   0 | \tdef -(value) = 1 - value\n 0 401   0 | \tdef *(value) = 1 * value\n 0 401   0 | \tdef **(value) = 1 ** value\n 0 401   0 | \tdef /(value) = 1 / value\n 0 401   0 | \tdef %(value) = 1 % value\n 0 401   0 | \tdef &(value) = 1 & value\n 0 401   0 | \tdef ^(value) = 1 ^ value\n 0 401   0 | \tdef >>(value) = 1 >> value\n 0 401   0 | \tdef <<(value) = 1 << value\n 0 401   0 | \tdef ==(other) = true\n 0 401   0 | \tdef !=(other) = true\n 0 401   0 | \tdef ===(other) = true\n 0 401   0 | \tdef =~(other) = true\n 0 401   0 | \tdef <=>(other) = true\n 0 401   0 | \tdef <(other) = true\n 0 401   0 | \tdef <=(other) = true\n 0 401   0 | \tdef >(other) = true\n 0 401   0 | \tdef >=(other) = true\n 0 401   0 | \t# element reference and assignment\n 0 401   0 | \tdef [](a, b) = puts(a + b)\n 2 401   0 + \tdef []=(a, b, c)\n 0 402   0 | \t\tputs a + b + c\n 0 402   0 | \tend\n 0 401   0 | \t# array decomposition\n 0 401   0 | \tdef dec(((a, b), c)) = puts(a + b + c)\n 0 401   0 | \t# class method\n 0 401   0 | \tdef self::say(*s) = puts(s)\n 0 401   0 | \tdef self.say(*s) = puts(s)\n 0 401   0 | \t# test short method name\n 0 401   0 | \tdef a = 1\n 0 401   0 | \tdef ab = 1\n 0 401   0 | end\n 1 400   0   \n 0 400   0   # class method\n 2 400   0 + def String.hello\n 0 401   0 |   \"Hello, world!\"\n 0 401   0 | end\n 0 400   0   # singleton method\n 0 400   0   greeting = \"Hello\"\n 2 400   0 + def greeting.broaden\n 0 401   0 |   self + \", world!\"\n 0 401   0 | end\n 0 400   0   # one line definition\n 0 400   0   def a(b, c) b; c end\n 0 400   0   # parentheses omitted\n 2 400   0 + def ab c\n 0 401   0 | \tputs c\n 0 401   0 | end\n 1 400   0   \n 0 400   0   # Test folding of multi-line SCE_RB_STRING_QW\n 2 400   0 + puts %W(\n 0 401   0 | a\n 0 401   0 | b\n 0 401   0 | c\n 0 401   0 | )\n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/Issue65.rb.styled",
    "content": "{5}def{0} {9}dbg_args{10}({11}a{10},{0} {11}b{10}={4}1{10},{0} {11}c{14}:{10},{0} {14}d:{0} {4}6{10},{0} {10}&{11}block{10}){0} {10}={0} {11}puts{10}({6}\"Args passed: {10}#{[{11}a{10},{0} {11}b{10},{0} {11}c{10},{0} {11}d{10},{0} {11}block{10}.{11}call{10}]}{6}\"{10}){0}\n{11}dbg_args{10}({4}0{10},{0} {14}c:{0} {4}5{10}){0} {10}{{0} {4}7{0} {10}}{0}\n\n{5}class{0} {8}A{0}\n\t{5}def{0} {9}attr{0} {10}={0} {16}@attr{0}\n\t{5}def{0} {9}attr={10}({11}value{10}){0}\n\t\t{16}@attr{0} {10}={0} {11}value{0}\n\t{5}end{0}\n\t{5}def{0} {9}attr?{0} {10}={0} {10}!!{16}@attr{0}\n\t{5}def{0} {9}attr!{0} {10}={0} {16}@attr{0} {10}={0} {5}true{0}\n\t{2}# unary operator{0}\n\t{5}def{0} {10}-@{0} {10}={0} {4}1{0}\n\t{5}def{0} {10}+@{0} {10}={0} {4}1{0}\n\t{5}def{0} {10}!{0} {10}={0} {4}1{0}\n\t{5}def{0} {10}!@{0} {10}={0} {4}1{0}\n\t{2}# binary operator{0}\n\t{5}def{0} {10}+({11}value{10}){0} {10}={0} {4}1{0} {10}+{0} {11}value{0}\n\t{5}def{0} {10}-({11}value{10}){0} {10}={0} {4}1{0} {10}-{0} {11}value{0}\n\t{5}def{0} {10}*({11}value{10}){0} {10}={0} {4}1{0} {10}*{0} {11}value{0}\n\t{5}def{0} {10}**({11}value{10}){0} {10}={0} {4}1{0} {10}**{0} {11}value{0}\n\t{5}def{0} {10}/({11}value{10}){0} {10}={0} {4}1{0} {10}/{0} {11}value{0}\n\t{5}def{0} {10}%({11}value{10}){0} {10}={0} {4}1{0} {10}%{0} {11}value{0}\n\t{5}def{0} {10}&({11}value{10}){0} {10}={0} {4}1{0} {10}&{0} {11}value{0}\n\t{5}def{0} {10}^({11}value{10}){0} {10}={0} {4}1{0} {10}^{0} {11}value{0}\n\t{5}def{0} {10}>>({11}value{10}){0} {10}={0} {4}1{0} {10}>>{0} {11}value{0}\n\t{5}def{0} {10}<<({11}value{10}){0} {10}={0} {4}1{0} {10}<<{0} {11}value{0}\n\t{5}def{0} {10}==({11}other{10}){0} {10}={0} {5}true{0}\n\t{5}def{0} {10}!=({11}other{10}){0} {10}={0} {5}true{0}\n\t{5}def{0} {10}===({11}other{10}){0} {10}={0} {5}true{0}\n\t{5}def{0} {10}=~({11}other{10}){0} {10}={0} {5}true{0}\n\t{5}def{0} {10}<=>({11}other{10}){0} {10}={0} {5}true{0}\n\t{5}def{0} {10}<({11}other{10}){0} {10}={0} {5}true{0}\n\t{5}def{0} {10}<=({11}other{10}){0} {10}={0} {5}true{0}\n\t{5}def{0} {10}>({11}other{10}){0} {10}={0} {5}true{0}\n\t{5}def{0} {10}>=({11}other{10}){0} {10}={0} {5}true{0}\n\t{2}# element reference and assignment{0}\n\t{5}def{0} {10}[]({11}a{10},{0} {11}b{10}){0} {10}={0} {11}puts{10}({11}a{0} {10}+{0} {11}b{10}){0}\n\t{5}def{0} {10}[]=({11}a{10},{0} {11}b{10},{0} {11}c{10}){0}\n\t\t{11}puts{0} {11}a{0} {10}+{0} {11}b{0} {10}+{0} {11}c{0}\n\t{5}end{0}\n\t{2}# array decomposition{0}\n\t{5}def{0} {9}dec{10}((({11}a{10},{0} {11}b{10}),{0} {11}c{10})){0} {10}={0} {11}puts{10}({11}a{0} {10}+{0} {11}b{0} {10}+{0} {11}c{10}){0}\n\t{2}# class method{0}\n\t{5}def{0} {29}self{10}::{9}say{10}(*{11}s{10}){0} {10}={0} {11}puts{10}({11}s{10}){0}\n\t{5}def{0} {29}self{10}.{9}say{10}(*{11}s{10}){0} {10}={0} {11}puts{10}({11}s{10}){0}\n\t{2}# test short method name{0}\n\t{5}def{0} {9}a{0} {10}={0} {4}1{0}\n\t{5}def{0} {9}ab{0} {10}={0} {4}1{0}\n{5}end{0}\n\n{2}# class method{0}\n{5}def{0} {11}String{10}.{9}hello{0}\n  {6}\"Hello, world!\"{0}\n{5}end{0}\n{2}# singleton method{0}\n{11}greeting{0} {10}={0} {6}\"Hello\"{0}\n{5}def{0} {11}greeting{10}.{9}broaden{0}\n  {5}self{0} {10}+{0} {6}\", world!\"{0}\n{5}end{0}\n{2}# one line definition{0}\n{5}def{0} {9}a{10}({11}b{10},{0} {11}c{10}){0} {11}b{10};{0} {11}c{0} {5}end{0}\n{2}# parentheses omitted{0}\n{5}def{0} {9}ab{0} {11}c{0}\n\t{11}puts{0} {11}c{0}\n{5}end{0}\n\n{2}# Test folding of multi-line SCE_RB_STRING_QW{0}\n{11}puts{0} {28}%W(\na\nb\nc\n){0}\n"
  },
  {
    "path": "test/examples/ruby/Issue66.rb",
    "content": "# Test that final \\n in indented heredoc (2nd example) is styled as SCE_RB_HERE_Q not SCE_RB_HERE_DELIM\n<<T\nX\nT\n\n<<-T\nX\nT\n"
  },
  {
    "path": "test/examples/ruby/Issue66.rb.folded",
    "content": " 0 400   0   # Test that final \\n in indented heredoc (2nd example) is styled as SCE_RB_HERE_Q not SCE_RB_HERE_DELIM\n 2 400   0 + <<T\n 0 401   0 | X\n 0 401   0 | T\n 1 400   0   \n 2 400   0 + <<-T\n 0 401   0 | X\n 0 401   0 | T\n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/Issue66.rb.styled",
    "content": "{2}# Test that final \\n in indented heredoc (2nd example) is styled as SCE_RB_HERE_Q not SCE_RB_HERE_DELIM{0}\n{10}<<{20}T{22}\nX\n{20}T{0}\n\n{10}<<{20}-T{22}\nX\n{20}T{0}\n"
  },
  {
    "path": "test/examples/ruby/Issue67.rb",
    "content": "# heredoc method call, other argument\nputs <<~EOT.chomp\n\tsquiggly heredoc\nEOT\n\nputs <<ONE, __FILE__, __LINE__\ncontent for heredoc one\nONE\n\n# heredoc prevStyle == SCE_RB_GLOBAL\n$stdout.puts <<~EOT.chomp\n\tsquiggly heredoc\nEOT\n\n# Issue #236: modifier if, unless, while and until\nalias error puts\n\nerror <<EOF if true\nheredoc if true\nEOF\n\nerror <<EOF unless false\nheredoc unless false\nEOF\n\nerror <<EOF while false\nheredoc while false\nEOF\n\nerror <<EOF until true\nheredoc until true\nEOF\n"
  },
  {
    "path": "test/examples/ruby/Issue67.rb.folded",
    "content": " 0 400   0   # heredoc method call, other argument\n 2 400   0 + puts <<~EOT.chomp\n 0 401   0 | \tsquiggly heredoc\n 0 401   0 | EOT\n 1 400   0   \n 2 400   0 + puts <<ONE, __FILE__, __LINE__\n 0 401   0 | content for heredoc one\n 0 401   0 | ONE\n 1 400   0   \n 0 400   0   # heredoc prevStyle == SCE_RB_GLOBAL\n 2 400   0 + $stdout.puts <<~EOT.chomp\n 0 401   0 | \tsquiggly heredoc\n 0 401   0 | EOT\n 1 400   0   \n 0 400   0   # Issue #236: modifier if, unless, while and until\n 0 400   0   alias error puts\n 1 400   0   \n 2 400   0 + error <<EOF if true\n 0 401   0 | heredoc if true\n 0 401   0 | EOF\n 1 400   0   \n 2 400   0 + error <<EOF unless false\n 0 401   0 | heredoc unless false\n 0 401   0 | EOF\n 1 400   0   \n 2 400   0 + error <<EOF while false\n 0 401   0 | heredoc while false\n 0 401   0 | EOF\n 1 400   0   \n 2 400   0 + error <<EOF until true\n 0 401   0 | heredoc until true\n 0 401   0 | EOF\n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/Issue67.rb.styled",
    "content": "{2}# heredoc method call, other argument{0}\n{11}puts{0} {10}<<{20}~EOT{10}.{11}chomp{22}\n\tsquiggly heredoc\n{20}EOT{0}\n\n{11}puts{0} {10}<<{20}ONE{10},{0} {5}__FILE__{10},{0} {5}__LINE__{22}\ncontent for heredoc one\n{20}ONE{0}\n\n{2}# heredoc prevStyle == SCE_RB_GLOBAL{0}\n{13}$stdout{10}.{11}puts{0} {10}<<{20}~EOT{10}.{11}chomp{22}\n\tsquiggly heredoc\n{20}EOT{0}\n\n{2}# Issue #236: modifier if, unless, while and until{0}\n{11}alias{0} {11}error{0} {11}puts{0}\n\n{11}error{0} {10}<<{20}EOF{0} {29}if{0} {5}true{22}\nheredoc if true\n{20}EOF{0}\n\n{11}error{0} {10}<<{20}EOF{0} {29}unless{0} {5}false{22}\nheredoc unless false\n{20}EOF{0}\n\n{11}error{0} {10}<<{20}EOF{0} {29}while{0} {5}false{22}\nheredoc while false\n{20}EOF{0}\n\n{11}error{0} {10}<<{20}EOF{0} {29}until{0} {5}true{22}\nheredoc until true\n{20}EOF{0}\n"
  },
  {
    "path": "test/examples/ruby/Issue69.rb",
    "content": "# -*- coding: utf-8 -*-\n\n# single character strings\nputs ?a\nputs ?\\n\nputs ?\\s\nputs ?\\\\#\nputs ?\\u{41}\nputs ?\\C-a\nputs ?\\M-a\nputs ?\\M-\\C-a\nputs ?\\C-\\M-a\nputs ?あ\nputs ?\"\nputs ?/\nputs ?[[1, 2]\nputs ?/\\\n\nputs ?\\176.ord\nputs ?\\x7A.ord\nputs ?\\uAB12.ord\nputs ?\\u{A}.ord\nputs ?\\u{012345}.ord\nputs ?\\cA.bytes\nputs ?\\c\\x41.bytes\nputs ?\\C-\\x41.bytes\nputs ?\\M-\\x41.bytes\nputs ?\\M-\\C-\\x41.bytes\nputs ?\\M-\\c\\x41.bytes\nputs ?\\c\\M-\\x41.bytes\nputs ?\\c?.bytes\nputs ?\\C-?.bytes\n\n# symbol and ternary operator\nab = /\\d+/\ncd = /\\w+/\nputs :ab, :cd, :/, :[]\nputs :/\\\n\n# TODO: space after '?' and ':' is not needed\nputs true ?ab : cd\nputs true ? /\\d+/ : /\\w+/\nputs false ?ab : cd\nputs false ? /\\d+/ : /\\w+/\n\n# Issue #355\nputs ?\\あ.ord\nputs ?\\\n.ord\n# invalid, test out-of-bounds styling at document end\nputs ?\\"
  },
  {
    "path": "test/examples/ruby/Issue69.rb.folded",
    "content": " 0 400   0   # -*- coding: utf-8 -*-\n 1 400   0   \n 0 400   0   # single character strings\n 0 400   0   puts ?a\n 0 400   0   puts ?\\n\n 0 400   0   puts ?\\s\n 0 400   0   puts ?\\\\#\n 0 400   0   puts ?\\u{41}\n 0 400   0   puts ?\\C-a\n 0 400   0   puts ?\\M-a\n 0 400   0   puts ?\\M-\\C-a\n 0 400   0   puts ?\\C-\\M-a\n 0 400   0   puts ?あ\n 0 400   0   puts ?\"\n 0 400   0   puts ?/\n 0 400   0   puts ?[[1, 2]\n 0 400   0   puts ?/\\\n 1 400   0   \n 0 400   0   puts ?\\176.ord\n 0 400   0   puts ?\\x7A.ord\n 0 400   0   puts ?\\uAB12.ord\n 0 400   0   puts ?\\u{A}.ord\n 0 400   0   puts ?\\u{012345}.ord\n 0 400   0   puts ?\\cA.bytes\n 0 400   0   puts ?\\c\\x41.bytes\n 0 400   0   puts ?\\C-\\x41.bytes\n 0 400   0   puts ?\\M-\\x41.bytes\n 0 400   0   puts ?\\M-\\C-\\x41.bytes\n 0 400   0   puts ?\\M-\\c\\x41.bytes\n 0 400   0   puts ?\\c\\M-\\x41.bytes\n 0 400   0   puts ?\\c?.bytes\n 0 400   0   puts ?\\C-?.bytes\n 1 400   0   \n 0 400   0   # symbol and ternary operator\n 0 400   0   ab = /\\d+/\n 0 400   0   cd = /\\w+/\n 0 400   0   puts :ab, :cd, :/, :[]\n 0 400   0   puts :/\\\n 1 400   0   \n 0 400   0   # TODO: space after '?' and ':' is not needed\n 0 400   0   puts true ?ab : cd\n 0 400   0   puts true ? /\\d+/ : /\\w+/\n 0 400   0   puts false ?ab : cd\n 0 400   0   puts false ? /\\d+/ : /\\w+/\n 1 400   0   \n 0 400   0   # Issue #355\n 0 400   0   puts ?\\あ.ord\n 0 400   0   puts ?\\\n 0 400   0   .ord\n 0 400   0   # invalid, test out-of-bounds styling at document end\n 0 400   0   puts ?\\"
  },
  {
    "path": "test/examples/ruby/Issue69.rb.styled",
    "content": "{2}# -*- coding: utf-8 -*-{0}\n\n{2}# single character strings{0}\n{11}puts{0} {4}?a{0}\n{11}puts{0} {4}?\\n{0}\n{11}puts{0} {4}?\\s{0}\n{11}puts{0} {4}?\\\\{2}#{0}\n{11}puts{0} {4}?\\u{41}{0}\n{11}puts{0} {4}?\\C-a{0}\n{11}puts{0} {4}?\\M-a{0}\n{11}puts{0} {4}?\\M-\\C-a{0}\n{11}puts{0} {4}?\\C-\\M-a{0}\n{11}puts{0} {4}?あ{0}\n{11}puts{0} {4}?\"{0}\n{11}puts{0} {4}?/{0}\n{11}puts{0} {4}?[{10}[{4}1{10},{0} {4}2{10}]{0}\n{11}puts{0} {4}?/{0}\\\n\n{11}puts{0} {4}?\\176{10}.{11}ord{0}\n{11}puts{0} {4}?\\x7A{10}.{11}ord{0}\n{11}puts{0} {4}?\\uAB12{10}.{11}ord{0}\n{11}puts{0} {4}?\\u{A}{10}.{11}ord{0}\n{11}puts{0} {4}?\\u{012345}{10}.{11}ord{0}\n{11}puts{0} {4}?\\cA{10}.{11}bytes{0}\n{11}puts{0} {4}?\\c\\x41{10}.{11}bytes{0}\n{11}puts{0} {4}?\\C-\\x41{10}.{11}bytes{0}\n{11}puts{0} {4}?\\M-\\x41{10}.{11}bytes{0}\n{11}puts{0} {4}?\\M-\\C-\\x41{10}.{11}bytes{0}\n{11}puts{0} {4}?\\M-\\c\\x41{10}.{11}bytes{0}\n{11}puts{0} {4}?\\c\\M-\\x41{10}.{11}bytes{0}\n{11}puts{0} {4}?\\c?{10}.{11}bytes{0}\n{11}puts{0} {4}?\\C-?{10}.{11}bytes{0}\n\n{2}# symbol and ternary operator{0}\n{11}ab{0} {10}={0} {12}/\\d+/{0}\n{11}cd{0} {10}={0} {12}/\\w+/{0}\n{11}puts{0} {14}:ab{10},{0} {14}:cd{10},{0} {14}:/{10},{0} {14}:[]{0}\n{11}puts{0} {14}:/{0}\\\n\n{2}# TODO: space after '?' and ':' is not needed{0}\n{11}puts{0} {5}true{0} {10}?{11}ab{0} {10}:{0} {11}cd{0}\n{11}puts{0} {5}true{0} {10}?{0} {12}/\\d+/{0} {10}:{0} {12}/\\w+/{0}\n{11}puts{0} {5}false{0} {10}?{11}ab{0} {10}:{0} {11}cd{0}\n{11}puts{0} {5}false{0} {10}?{0} {12}/\\d+/{0} {10}:{0} {12}/\\w+/{0}\n\n{2}# Issue #355{0}\n{11}puts{0} {4}?\\あ{10}.{11}ord{0}\n{11}puts{0} {4}?\\{0}\n{10}.{11}ord{0}\n{2}# invalid, test out-of-bounds styling at document end{0}\n{11}puts{0} {4}?\\"
  },
  {
    "path": "test/examples/ruby/PercentEquals124.rb",
    "content": "# Issue 124, disambiguating %= which may be a quote or modulo assignment\n# %-quoting with '=' as the quote\ns = %=3=\nputs s\nx = 7\n# Modulo assignment, equivalent to x = x % 2\nx %=2\nputs x\n"
  },
  {
    "path": "test/examples/ruby/PercentEquals124.rb.folded",
    "content": " 0 400   0   # Issue 124, disambiguating %= which may be a quote or modulo assignment\n 0 400   0   # %-quoting with '=' as the quote\n 0 400   0   s = %=3=\n 0 400   0   puts s\n 0 400   0   x = 7\n 0 400   0   # Modulo assignment, equivalent to x = x % 2\n 0 400   0   x %=2\n 0 400   0   puts x\n 0 400   0   "
  },
  {
    "path": "test/examples/ruby/PercentEquals124.rb.styled",
    "content": "{2}# Issue 124, disambiguating %= which may be a quote or modulo assignment{0}\n{2}# %-quoting with '=' as the quote{0}\n{11}s{0} {10}={0} {25}%=3={0}\n{11}puts{0} {11}s{0}\n{11}x{0} {10}={0} {4}7{0}\n{2}# Modulo assignment, equivalent to x = x % 2{0}\n{11}x{0} {10}%={4}2{0}\n{11}puts{0} {11}x{0}\n"
  },
  {
    "path": "test/examples/ruby/SciTE.properties",
    "content": "lexer.*.rb=ruby\nkeywords.*.rb=begin class def do else end false if module return self super true unless until while \\\n__FILE__ __LINE__\nfold=1\n\nsubstyles.ruby.11=2\nsubstylewords.11.1.*=decrypt STDERR\nsubstylewords.11.2.*=encrypt\n"
  },
  {
    "path": "test/examples/ruby/x.rb",
    "content": "class Demo\n\tdef test # A test\n\t\ti = 1\n\t\tputs \"Example\"\n\tend\nend"
  },
  {
    "path": "test/examples/ruby/x.rb.folded",
    "content": " 2 400   0 + class Demo\n 2 401   0 + \tdef test # A test\n 0 402   0 | \t\ti = 1\n 0 402   0 | \t\tputs \"Example\"\n 0 402   0 | \tend\n 0 401   0 | end"
  },
  {
    "path": "test/examples/ruby/x.rb.styled",
    "content": "{5}class{0} {8}Demo{0}\n\t{5}def{0} {9}test{0} {2}# A test{0}\n\t\t{11}i{0} {10}={0} {4}1{0}\n\t\t{11}puts{0} {6}\"Example\"{0}\n\t{5}end{0}\n{5}end"
  },
  {
    "path": "test/examples/rust/Issue239.rs",
    "content": "fn main() {\n    let r#true = false;\n    println!(\"{}\", r#true);\n}"
  },
  {
    "path": "test/examples/rust/Issue239.rs.folded",
    "content": " 2 400 401 + fn main() {\n 0 401 401 |     let r#true = false;\n 0 401 401 |     println!(\"{}\", r#true);\n 0 401 400 | }"
  },
  {
    "path": "test/examples/rust/Issue239.rs.styled",
    "content": "{6}fn{0} {17}main{16}(){0} {16}{{0}\n    {6}let{0} {17}r#true{0} {16}={0} {6}false{16};{0}\n    {19}println!{16}({13}\"{}\"{16},{0} {17}r#true{16});{0}\n{16}}"
  },
  {
    "path": "test/examples/rust/Issue268.rs",
    "content": "// coding: utf-8\n\nb\"foo\"; br\"foo\"            // foo\nb\"\\\"foo\\\"\"; br#\"\"foo\"\"#;   // \"foo\"\n\nb\"foo #\\\"# bar\";\nbr##\"foo #\"# bar\"##;       // foo #\"# bar\n\nb\"\\x52\"; b\"R\"; br\"R\"       // R\nb\"\\\\x52\"; br\"\\x52\"         // \\x52\n\nc\"æ\"                       // LATIN SMALL LETTER AE (U+00E6)\nc\"\\u{00E6}\";\nc\"\\xC3\\xA6\";\n\nc\"foo\"; cr\"foo\"           // foo\nc\"\\\"foo\\\"\"; cr#\"\"foo\"\"#;  // \"foo\"\n\nc\"foo #\\\"# bar\";\ncr##\"foo #\"# bar\"##;      // foo #\"# bar\n\nc\"\\x52\"; c\"R\"; cr\"R\"      // R\nc\"\\\\x52\"; cr\"\\x52\"        // \\x52\n\n\"foo\"; r\"foo\"             // foo\n\"\\\"foo\\\"\"; r#\"\"foo\"\"#;    // \"foo\"\n\n\"foo #\\\"# bar\";\nr##\"foo #\"# bar\"##;       // foo #\"# bar\n\n\"\\x52\"; \"R\"; r\"R\"         // R\n\"\\\\x52\"; r\"\\x52\"          // \\x52\n\n\"æ\"                       // LATIN SMALL LETTER AE (U+00E6)\n\"\\u{00E6}\";\n\"\\xC3\\xA6\";"
  },
  {
    "path": "test/examples/rust/Issue268.rs.folded",
    "content": " 0 400 400   // coding: utf-8\n 1 400 400   \n 0 400 400   b\"foo\"; br\"foo\"            // foo\n 0 400 400   b\"\\\"foo\\\"\"; br#\"\"foo\"\"#;   // \"foo\"\n 1 400 400   \n 0 400 400   b\"foo #\\\"# bar\";\n 0 400 400   br##\"foo #\"# bar\"##;       // foo #\"# bar\n 1 400 400   \n 0 400 400   b\"\\x52\"; b\"R\"; br\"R\"       // R\n 0 400 400   b\"\\\\x52\"; br\"\\x52\"         // \\x52\n 1 400 400   \n 0 400 400   c\"æ\"                       // LATIN SMALL LETTER AE (U+00E6)\n 0 400 400   c\"\\u{00E6}\";\n 0 400 400   c\"\\xC3\\xA6\";\n 1 400 400   \n 0 400 400   c\"foo\"; cr\"foo\"           // foo\n 0 400 400   c\"\\\"foo\\\"\"; cr#\"\"foo\"\"#;  // \"foo\"\n 1 400 400   \n 0 400 400   c\"foo #\\\"# bar\";\n 0 400 400   cr##\"foo #\"# bar\"##;      // foo #\"# bar\n 1 400 400   \n 0 400 400   c\"\\x52\"; c\"R\"; cr\"R\"      // R\n 0 400 400   c\"\\\\x52\"; cr\"\\x52\"        // \\x52\n 1 400 400   \n 0 400 400   \"foo\"; r\"foo\"             // foo\n 0 400 400   \"\\\"foo\\\"\"; r#\"\"foo\"\"#;    // \"foo\"\n 1 400 400   \n 0 400 400   \"foo #\\\"# bar\";\n 0 400 400   r##\"foo #\"# bar\"##;       // foo #\"# bar\n 1 400 400   \n 0 400 400   \"\\x52\"; \"R\"; r\"R\"         // R\n 0 400 400   \"\\\\x52\"; r\"\\x52\"          // \\x52\n 1 400 400   \n 0 400 400   \"æ\"                       // LATIN SMALL LETTER AE (U+00E6)\n 0 400 400   \"\\u{00E6}\";\n 0 400 400   \"\\xC3\\xA6\";"
  },
  {
    "path": "test/examples/rust/Issue268.rs.styled",
    "content": "{2}// coding: utf-8{0}\n\n{21}b\"foo\"{16};{0} {22}br\"foo\"{0}            {2}// foo{0}\n{21}b\"\\\"foo\\\"\"{16};{0} {22}br#\"\"foo\"\"#{16};{0}   {2}// \"foo\"{0}\n\n{21}b\"foo #\\\"# bar\"{16};{0}\n{22}br##\"foo #\"# bar\"##{16};{0}       {2}// foo #\"# bar{0}\n\n{21}b\"\\x52\"{16};{0} {21}b\"R\"{16};{0} {22}br\"R\"{0}       {2}// R{0}\n{21}b\"\\\\x52\"{16};{0} {22}br\"\\x52\"{0}         {2}// \\x52{0}\n\n{24}c\"æ\"{0}                       {2}// LATIN SMALL LETTER AE (U+00E6){0}\n{24}c\"\\u{00E6}\"{16};{0}\n{24}c\"\\xC3\\xA6\"{16};{0}\n\n{24}c\"foo\"{16};{0} {25}cr\"foo\"{0}           {2}// foo{0}\n{24}c\"\\\"foo\\\"\"{16};{0} {25}cr#\"\"foo\"\"#{16};{0}  {2}// \"foo\"{0}\n\n{24}c\"foo #\\\"# bar\"{16};{0}\n{25}cr##\"foo #\"# bar\"##{16};{0}      {2}// foo #\"# bar{0}\n\n{24}c\"\\x52\"{16};{0} {24}c\"R\"{16};{0} {25}cr\"R\"{0}      {2}// R{0}\n{24}c\"\\\\x52\"{16};{0} {25}cr\"\\x52\"{0}        {2}// \\x52{0}\n\n{13}\"foo\"{16};{0} {14}r\"foo\"{0}             {2}// foo{0}\n{13}\"\\\"foo\\\"\"{16};{0} {14}r#\"\"foo\"\"#{16};{0}    {2}// \"foo\"{0}\n\n{13}\"foo #\\\"# bar\"{16};{0}\n{14}r##\"foo #\"# bar\"##{16};{0}       {2}// foo #\"# bar{0}\n\n{13}\"\\x52\"{16};{0} {13}\"R\"{16};{0} {14}r\"R\"{0}         {2}// R{0}\n{13}\"\\\\x52\"{16};{0} {14}r\"\\x52\"{0}          {2}// \\x52{0}\n\n{13}\"æ\"{0}                       {2}// LATIN SMALL LETTER AE (U+00E6){0}\n{13}\"\\u{00E6}\"{16};{0}\n{13}\"\\xC3\\xA6\"{16};"
  },
  {
    "path": "test/examples/rust/Issue33.rs",
    "content": "fn main() {\n    let a: i128 = 42i128;\n    let b: u128 = 1337u128;\n    println!(\"{} + {} = {}\", a, b, (a as u128) + b);\n}\n"
  },
  {
    "path": "test/examples/rust/Issue33.rs.folded",
    "content": " 2 400 401 + fn main() {\n 0 401 401 |     let a: i128 = 42i128;\n 0 401 401 |     let b: u128 = 1337u128;\n 0 401 401 |     println!(\"{} + {} = {}\", a, b, (a as u128) + b);\n 0 401 400 | }\n 1 400 400   "
  },
  {
    "path": "test/examples/rust/Issue33.rs.styled",
    "content": "{6}fn{0} {17}main{16}(){0} {16}{{0}\n    {6}let{0} {17}a{16}:{0} {7}i128{0} {16}={0} {5}42i128{16};{0}\n    {6}let{0} {17}b{16}:{0} {7}u128{0} {16}={0} {5}1337u128{16};{0}\n    {19}println!{16}({13}\"{} + {} = {}\"{16},{0} {17}a{16},{0} {17}b{16},{0} {16}({17}a{0} {6}as{0} {7}u128{16}){0} {16}+{0} {17}b{16});{0}\n{16}}{0}\n"
  },
  {
    "path": "test/examples/rust/Issue34.rs",
    "content": "/**\n * SCE_RUST_COMMENTBLOCKDOC\n */\nfn main() {\n    /// SCE_RUST_COMMENTLINEDOC\n    println!(\"Hello, World!\");\n}\n// SCE_RUST_COMMENTLINE\n/*\n * SCE_RUST_COMMENTBLOCK\n */\n"
  },
  {
    "path": "test/examples/rust/Issue34.rs.folded",
    "content": " 2 400 401 + /**\n 0 401 401 |  * SCE_RUST_COMMENTBLOCKDOC\n 0 401 400 |  */\n 2 400 401 + fn main() {\n 0 401 401 |     /// SCE_RUST_COMMENTLINEDOC\n 0 401 401 |     println!(\"Hello, World!\");\n 0 401 400 | }\n 0 400 400   // SCE_RUST_COMMENTLINE\n 2 400 401 + /*\n 0 401 401 |  * SCE_RUST_COMMENTBLOCK\n 0 401 400 |  */\n 1 400 400   "
  },
  {
    "path": "test/examples/rust/Issue34.rs.styled",
    "content": "{3}/**\n * SCE_RUST_COMMENTBLOCKDOC\n */{0}\n{6}fn{0} {17}main{16}(){0} {16}{{0}\n    {4}/// SCE_RUST_COMMENTLINEDOC{0}\n    {19}println!{16}({13}\"Hello, World!\"{16});{0}\n{16}}{0}\n{2}// SCE_RUST_COMMENTLINE{0}\n{1}/*\n * SCE_RUST_COMMENTBLOCK\n */{0}\n"
  },
  {
    "path": "test/examples/rust/Issue35.rs",
    "content": "/// GitHub Issue #35\nfn main() {}\n/*"
  },
  {
    "path": "test/examples/rust/Issue35.rs.folded",
    "content": " 0 400 400   /// GitHub Issue #35\n 0 400 400   fn main() {}\n 2 400 401 + /*"
  },
  {
    "path": "test/examples/rust/Issue35.rs.styled",
    "content": "{4}/// GitHub Issue #35{0}\n{6}fn{0} {17}main{16}(){0} {16}{}{0}\n{1}/*"
  },
  {
    "path": "test/examples/rust/SciTE.properties",
    "content": "lexer.*.rs=rust\n\nkeywords.*.rs= \\\nalignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self sizeof static struct super trait true type typeof unsafe unsized use virtual while yield\n\nkeywords2.*.rs= \\\nbool char f32 f64 i16 i32 i64 i128 i8 int str u16 u32 u64 u128 u8 uint\n\nkeywords3.*.rs=Self\n\nfold=1\nfold.comment=1\n"
  },
  {
    "path": "test/examples/sinex/AllStyles_comment_fold.snx",
    "content": "%=SNX 2.01 IGN 16:122:00000 IGN 79:215:00000 19:001:00000 C 00036 2 X V\n*-------------------------------------------------------------------------------\n+FILE/COMMENT\n* File created by CATREF software (Z.Altamimi)\n* 2-line comment\n-FILE/COMMENT\n*-------------------------------------------------------------------------------\n* out-of-block multi-line comment\n*-------------------------------------------------------------------------------\n+SITE/ID\n*CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n PERT  A 50133M001   Perth, Australia       115 53 06.9 -31 48 07.0    12.7\n TIDB  A 50103M108   Tidbinbilla, NSW, Aust 148 58 47.9 -35 23 57.1   665.3\n YAR1  A 50107M004   Mingenew, Australia    115 20 49.1 -29 02 47.5   241.3\n CEDU  A 50138M001   CEDU 50138M001         133 48 35.3 -31 51 59.9   144.7\n HOB2  A 50116M004   Hobart/Tasmania, Austr 147 26 19.4 -42 48 16.9    41.1\n-SITE/ID\n* out-of-block single line comment\n+SOLUTION/EPOCHS\n*Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n PERT  A    1 C 94:004:00000 94:113:00000 94:058:43200\n TIDB  A    1 C 94:004:00000 96:177:86389 95:090:86394\n YAR1  A    1 C 94:004:00000 97:230:00000 95:300:00000\n PERT  A    2 C 94:117:00000 01:030:00000 97:256:00000\n CEDU  A    1 C 94:136:00000 95:277:00000 95:024:00000\n HOB2  A    1 C 94:187:00000 97:137:00000 95:345:00000\n-SOLUTION/EPOCHS\n+SOLUTION/ESTIMATE\n*INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n1        STAX PERT  A    1 10:001:00000  m   2 -.236868757866128E+07 0.74048E-03\n2        STAY PERT  A    1 10:001:00000  m   2 0.488131661461247E+07 0.91864E-03\n3        STAZ PERT  A    1 10:001:00000  m   2 -.334179548710761E+07 0.84688E-03\n4        VELX PERT  A    1 10:001:00000  m/y 2 -.472916775593191E-01 0.39163E-04\n5        VELY PERT  A    1 10:001:00000  m/y 2 0.822689567578196E-02 0.41751E-04\n6        VELZ PERT  A    1 10:001:00000  m/y 2 0.508006951054042E-01 0.44388E-04\n29       VELY CEDU  A    1 10:001:00000  m/y 2 0.172935957701062E-02 0.38085E-04\n30       VELZ CEDU  A    1 10:001:00000  m/y 2 0.504090658972641E-01 0.42917E-04\n31       STAX HOB2  A    1 10:001:00000  m   2 -.395007186683046E+07 0.68502E-03\n32       STAY HOB2  A    1 10:001:00000  m   2 0.252241528744047E+07 0.60906E-03\n33       STAZ HOB2  A    1 10:001:00000  m   2 -.431163782526727E+07 0.78320E-03\n34       VELX HOB2  A    1 10:001:00000  m/y 2 -.387112208023018E-01 0.40249E-04\n35       VELY HOB2  A    1 10:001:00000  m/y 2 0.792637786129052E-02 0.37662E-04\n36       VELZ HOB2  A    1 10:001:00000  m/y 2 0.412562272254610E-01 0.45803E-04\n-SOLUTION/ESTIMATE\n"
  },
  {
    "path": "test/examples/sinex/AllStyles_comment_fold.snx.folded",
    "content": " 0 400   0   %=SNX 2.01 IGN 16:122:00000 IGN 79:215:00000 19:001:00000 C 00036 2 X V\n 0 400   0   *-------------------------------------------------------------------------------\n 2 400   0 + +FILE/COMMENT\n 2 401   0 + * File created by CATREF software (Z.Altamimi)\n 0 402   0 | * 2-line comment\n 0 401   0 | -FILE/COMMENT\n 2 400   0 + *-------------------------------------------------------------------------------\n 0 401   0 | * out-of-block multi-line comment\n 0 401   0 | *-------------------------------------------------------------------------------\n 2 400   0 + +SITE/ID\n 0 401   0 | *CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n 0 401   0 |  PERT  A 50133M001   Perth, Australia       115 53 06.9 -31 48 07.0    12.7\n 0 401   0 |  TIDB  A 50103M108   Tidbinbilla, NSW, Aust 148 58 47.9 -35 23 57.1   665.3\n 0 401   0 |  YAR1  A 50107M004   Mingenew, Australia    115 20 49.1 -29 02 47.5   241.3\n 0 401   0 |  CEDU  A 50138M001   CEDU 50138M001         133 48 35.3 -31 51 59.9   144.7\n 0 401   0 |  HOB2  A 50116M004   Hobart/Tasmania, Austr 147 26 19.4 -42 48 16.9    41.1\n 0 401   0 | -SITE/ID\n 0 400   0   * out-of-block single line comment\n 2 400   0 + +SOLUTION/EPOCHS\n 0 401   0 | *Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n 0 401   0 |  PERT  A    1 C 94:004:00000 94:113:00000 94:058:43200\n 0 401   0 |  TIDB  A    1 C 94:004:00000 96:177:86389 95:090:86394\n 0 401   0 |  YAR1  A    1 C 94:004:00000 97:230:00000 95:300:00000\n 0 401   0 |  PERT  A    2 C 94:117:00000 01:030:00000 97:256:00000\n 0 401   0 |  CEDU  A    1 C 94:136:00000 95:277:00000 95:024:00000\n 0 401   0 |  HOB2  A    1 C 94:187:00000 97:137:00000 95:345:00000\n 0 401   0 | -SOLUTION/EPOCHS\n 2 400   0 + +SOLUTION/ESTIMATE\n 0 401   0 | *INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n 0 401   0 | 1        STAX PERT  A    1 10:001:00000  m   2 -.236868757866128E+07 0.74048E-03\n 0 401   0 | 2        STAY PERT  A    1 10:001:00000  m   2 0.488131661461247E+07 0.91864E-03\n 0 401   0 | 3        STAZ PERT  A    1 10:001:00000  m   2 -.334179548710761E+07 0.84688E-03\n 0 401   0 | 4        VELX PERT  A    1 10:001:00000  m/y 2 -.472916775593191E-01 0.39163E-04\n 0 401   0 | 5        VELY PERT  A    1 10:001:00000  m/y 2 0.822689567578196E-02 0.41751E-04\n 0 401   0 | 6        VELZ PERT  A    1 10:001:00000  m/y 2 0.508006951054042E-01 0.44388E-04\n 0 401   0 | 29       VELY CEDU  A    1 10:001:00000  m/y 2 0.172935957701062E-02 0.38085E-04\n 0 401   0 | 30       VELZ CEDU  A    1 10:001:00000  m/y 2 0.504090658972641E-01 0.42917E-04\n 0 401   0 | 31       STAX HOB2  A    1 10:001:00000  m   2 -.395007186683046E+07 0.68502E-03\n 0 401   0 | 32       STAY HOB2  A    1 10:001:00000  m   2 0.252241528744047E+07 0.60906E-03\n 0 401   0 | 33       STAZ HOB2  A    1 10:001:00000  m   2 -.431163782526727E+07 0.78320E-03\n 0 401   0 | 34       VELX HOB2  A    1 10:001:00000  m/y 2 -.387112208023018E-01 0.40249E-04\n 0 401   0 | 35       VELY HOB2  A    1 10:001:00000  m/y 2 0.792637786129052E-02 0.37662E-04\n 0 401   0 | 36       VELZ HOB2  A    1 10:001:00000  m/y 2 0.412562272254610E-01 0.45803E-04\n 0 401   0 | -SOLUTION/ESTIMATE\n 0 400   0   "
  },
  {
    "path": "test/examples/sinex/AllStyles_comment_fold.snx.styled",
    "content": "{0}%=SNX {5}2.01{0} IGN {4}16:122:00000{0} IGN {4}79:215:00000{0} {4}19:001:00000{0} C {5}00036{0} {5}2{0} X V\n{1}*-------------------------------------------------------------------------------\n{2}+FILE/COMMENT\n{1}* File created by CATREF software (Z.Altamimi)\n* 2-line comment\n{3}-FILE/COMMENT\n{1}*-------------------------------------------------------------------------------\n* out-of-block multi-line comment\n*-------------------------------------------------------------------------------\n{2}+SITE/ID\n{1}*CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n{0} PERT  A 50133M001   Perth, Australia       {5}115{0} {5}53{0} {5}06.9{0} {5}-31{0} {5}48{0} {5}07.0{0}    {5}12.7{0}\n TIDB  A 50103M108   Tidbinbilla, NSW, Aust {5}148{0} {5}58{0} {5}47.9{0} {5}-35{0} {5}23{0} {5}57.1{0}   {5}665.3{0}\n YAR1  A 50107M004   Mingenew, Australia    {5}115{0} {5}20{0} {5}49.1{0} {5}-29{0} {5}02{0} {5}47.5{0}   {5}241.3{0}\n CEDU  A 50138M001   CEDU 50138M001         {5}133{0} {5}48{0} {5}35.3{0} {5}-31{0} {5}51{0} {5}59.9{0}   {5}144.7{0}\n HOB2  A 50116M004   Hobart/Tasmania, Austr {5}147{0} {5}26{0} {5}19.4{0} {5}-42{0} {5}48{0} {5}16.9{0}    {5}41.1{0}\n{3}-SITE/ID\n{1}* out-of-block single line comment\n{2}+SOLUTION/EPOCHS\n{1}*Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n{0} PERT  A    {5}1{0} C {4}94:004:00000{0} {4}94:113:00000{0} {4}94:058:43200{0}\n TIDB  A    {5}1{0} C {4}94:004:00000{0} {4}96:177:86389{0} {4}95:090:86394{0}\n YAR1  A    {5}1{0} C {4}94:004:00000{0} {4}97:230:00000{0} {4}95:300:00000{0}\n PERT  A    {5}2{0} C {4}94:117:00000{0} {4}01:030:00000{0} {4}97:256:00000{0}\n CEDU  A    {5}1{0} C {4}94:136:00000{0} {4}95:277:00000{0} {4}95:024:00000{0}\n HOB2  A    {5}1{0} C {4}94:187:00000{0} {4}97:137:00000{0} {4}95:345:00000{0}\n{3}-SOLUTION/EPOCHS\n{2}+SOLUTION/ESTIMATE\n{1}*INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n{5}1{0}        STAX PERT  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}-.236868757866128E+07{0} {5}0.74048E-03{0}\n{5}2{0}        STAY PERT  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}0.488131661461247E+07{0} {5}0.91864E-03{0}\n{5}3{0}        STAZ PERT  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}-.334179548710761E+07{0} {5}0.84688E-03{0}\n{5}4{0}        VELX PERT  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}-.472916775593191E-01{0} {5}0.39163E-04{0}\n{5}5{0}        VELY PERT  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.822689567578196E-02{0} {5}0.41751E-04{0}\n{5}6{0}        VELZ PERT  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.508006951054042E-01{0} {5}0.44388E-04{0}\n{5}29{0}       VELY CEDU  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.172935957701062E-02{0} {5}0.38085E-04{0}\n{5}30{0}       VELZ CEDU  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.504090658972641E-01{0} {5}0.42917E-04{0}\n{5}31{0}       STAX HOB2  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}-.395007186683046E+07{0} {5}0.68502E-03{0}\n{5}32{0}       STAY HOB2  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}0.252241528744047E+07{0} {5}0.60906E-03{0}\n{5}33{0}       STAZ HOB2  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}-.431163782526727E+07{0} {5}0.78320E-03{0}\n{5}34{0}       VELX HOB2  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}-.387112208023018E-01{0} {5}0.40249E-04{0}\n{5}35{0}       VELY HOB2  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.792637786129052E-02{0} {5}0.37662E-04{0}\n{5}36{0}       VELZ HOB2  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.412562272254610E-01{0} {5}0.45803E-04{0}\n{3}-SOLUTION/ESTIMATE\n"
  },
  {
    "path": "test/examples/sinex/AllStyles_no_comment_fold.snx",
    "content": "%=SNX 2.01 IGN 16:122:00000 IGN 79:215:00000 19:001:00000 C 00036 2 X V\n*-------------------------------------------------------------------------------\n+FILE/COMMENT\n* File created by CATREF software (Z.Altamimi)\n* 2-line comment\n-FILE/COMMENT\n*-------------------------------------------------------------------------------\n* out-of-block multi-line comment\n*-------------------------------------------------------------------------------\n+SITE/ID\n*CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n PERT  A 50133M001   Perth, Australia       115 53 06.9 -31 48 07.0    12.7\n TIDB  A 50103M108   Tidbinbilla, NSW, Aust 148 58 47.9 -35 23 57.1   665.3\n YAR1  A 50107M004   Mingenew, Australia    115 20 49.1 -29 02 47.5   241.3\n CEDU  A 50138M001   CEDU 50138M001         133 48 35.3 -31 51 59.9   144.7\n HOB2  A 50116M004   Hobart/Tasmania, Austr 147 26 19.4 -42 48 16.9    41.1\n-SITE/ID\n* out-of-block single line comment\n+SOLUTION/EPOCHS\n*Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n PERT  A    1 C 94:004:00000 94:113:00000 94:058:43200\n TIDB  A    1 C 94:004:00000 96:177:86389 95:090:86394\n YAR1  A    1 C 94:004:00000 97:230:00000 95:300:00000\n PERT  A    2 C 94:117:00000 01:030:00000 97:256:00000\n CEDU  A    1 C 94:136:00000 95:277:00000 95:024:00000\n HOB2  A    1 C 94:187:00000 97:137:00000 95:345:00000\n-SOLUTION/EPOCHS\n+SOLUTION/ESTIMATE\n*INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n1        STAX PERT  A    1 10:001:00000  m   2 -.236868757866128E+07 0.74048E-03\n2        STAY PERT  A    1 10:001:00000  m   2 0.488131661461247E+07 0.91864E-03\n3        STAZ PERT  A    1 10:001:00000  m   2 -.334179548710761E+07 0.84688E-03\n4        VELX PERT  A    1 10:001:00000  m/y 2 -.472916775593191E-01 0.39163E-04\n5        VELY PERT  A    1 10:001:00000  m/y 2 0.822689567578196E-02 0.41751E-04\n6        VELZ PERT  A    1 10:001:00000  m/y 2 0.508006951054042E-01 0.44388E-04\n29       VELY CEDU  A    1 10:001:00000  m/y 2 0.172935957701062E-02 0.38085E-04\n30       VELZ CEDU  A    1 10:001:00000  m/y 2 0.504090658972641E-01 0.42917E-04\n31       STAX HOB2  A    1 10:001:00000  m   2 -.395007186683046E+07 0.68502E-03\n32       STAY HOB2  A    1 10:001:00000  m   2 0.252241528744047E+07 0.60906E-03\n33       STAZ HOB2  A    1 10:001:00000  m   2 -.431163782526727E+07 0.78320E-03\n34       VELX HOB2  A    1 10:001:00000  m/y 2 -.387112208023018E-01 0.40249E-04\n35       VELY HOB2  A    1 10:001:00000  m/y 2 0.792637786129052E-02 0.37662E-04\n36       VELZ HOB2  A    1 10:001:00000  m/y 2 0.412562272254610E-01 0.45803E-04\n-SOLUTION/ESTIMATE\n"
  },
  {
    "path": "test/examples/sinex/AllStyles_no_comment_fold.snx.folded",
    "content": " 0 400   0   %=SNX 2.01 IGN 16:122:00000 IGN 79:215:00000 19:001:00000 C 00036 2 X V\n 0 400   0   *-------------------------------------------------------------------------------\n 2 400   0 + +FILE/COMMENT\n 0 401   0 | * File created by CATREF software (Z.Altamimi)\n 0 401   0 | * 2-line comment\n 0 401   0 | -FILE/COMMENT\n 0 400   0   *-------------------------------------------------------------------------------\n 0 400   0   * out-of-block multi-line comment\n 0 400   0   *-------------------------------------------------------------------------------\n 2 400   0 + +SITE/ID\n 0 401   0 | *CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n 0 401   0 |  PERT  A 50133M001   Perth, Australia       115 53 06.9 -31 48 07.0    12.7\n 0 401   0 |  TIDB  A 50103M108   Tidbinbilla, NSW, Aust 148 58 47.9 -35 23 57.1   665.3\n 0 401   0 |  YAR1  A 50107M004   Mingenew, Australia    115 20 49.1 -29 02 47.5   241.3\n 0 401   0 |  CEDU  A 50138M001   CEDU 50138M001         133 48 35.3 -31 51 59.9   144.7\n 0 401   0 |  HOB2  A 50116M004   Hobart/Tasmania, Austr 147 26 19.4 -42 48 16.9    41.1\n 0 401   0 | -SITE/ID\n 0 400   0   * out-of-block single line comment\n 2 400   0 + +SOLUTION/EPOCHS\n 0 401   0 | *Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n 0 401   0 |  PERT  A    1 C 94:004:00000 94:113:00000 94:058:43200\n 0 401   0 |  TIDB  A    1 C 94:004:00000 96:177:86389 95:090:86394\n 0 401   0 |  YAR1  A    1 C 94:004:00000 97:230:00000 95:300:00000\n 0 401   0 |  PERT  A    2 C 94:117:00000 01:030:00000 97:256:00000\n 0 401   0 |  CEDU  A    1 C 94:136:00000 95:277:00000 95:024:00000\n 0 401   0 |  HOB2  A    1 C 94:187:00000 97:137:00000 95:345:00000\n 0 401   0 | -SOLUTION/EPOCHS\n 2 400   0 + +SOLUTION/ESTIMATE\n 0 401   0 | *INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n 0 401   0 | 1        STAX PERT  A    1 10:001:00000  m   2 -.236868757866128E+07 0.74048E-03\n 0 401   0 | 2        STAY PERT  A    1 10:001:00000  m   2 0.488131661461247E+07 0.91864E-03\n 0 401   0 | 3        STAZ PERT  A    1 10:001:00000  m   2 -.334179548710761E+07 0.84688E-03\n 0 401   0 | 4        VELX PERT  A    1 10:001:00000  m/y 2 -.472916775593191E-01 0.39163E-04\n 0 401   0 | 5        VELY PERT  A    1 10:001:00000  m/y 2 0.822689567578196E-02 0.41751E-04\n 0 401   0 | 6        VELZ PERT  A    1 10:001:00000  m/y 2 0.508006951054042E-01 0.44388E-04\n 0 401   0 | 29       VELY CEDU  A    1 10:001:00000  m/y 2 0.172935957701062E-02 0.38085E-04\n 0 401   0 | 30       VELZ CEDU  A    1 10:001:00000  m/y 2 0.504090658972641E-01 0.42917E-04\n 0 401   0 | 31       STAX HOB2  A    1 10:001:00000  m   2 -.395007186683046E+07 0.68502E-03\n 0 401   0 | 32       STAY HOB2  A    1 10:001:00000  m   2 0.252241528744047E+07 0.60906E-03\n 0 401   0 | 33       STAZ HOB2  A    1 10:001:00000  m   2 -.431163782526727E+07 0.78320E-03\n 0 401   0 | 34       VELX HOB2  A    1 10:001:00000  m/y 2 -.387112208023018E-01 0.40249E-04\n 0 401   0 | 35       VELY HOB2  A    1 10:001:00000  m/y 2 0.792637786129052E-02 0.37662E-04\n 0 401   0 | 36       VELZ HOB2  A    1 10:001:00000  m/y 2 0.412562272254610E-01 0.45803E-04\n 0 401   0 | -SOLUTION/ESTIMATE\n 0 400   0   "
  },
  {
    "path": "test/examples/sinex/AllStyles_no_comment_fold.snx.styled",
    "content": "{0}%=SNX {5}2.01{0} IGN {4}16:122:00000{0} IGN {4}79:215:00000{0} {4}19:001:00000{0} C {5}00036{0} {5}2{0} X V\n{1}*-------------------------------------------------------------------------------\n{2}+FILE/COMMENT\n{1}* File created by CATREF software (Z.Altamimi)\n* 2-line comment\n{3}-FILE/COMMENT\n{1}*-------------------------------------------------------------------------------\n* out-of-block multi-line comment\n*-------------------------------------------------------------------------------\n{2}+SITE/ID\n{1}*CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n{0} PERT  A 50133M001   Perth, Australia       {5}115{0} {5}53{0} {5}06.9{0} {5}-31{0} {5}48{0} {5}07.0{0}    {5}12.7{0}\n TIDB  A 50103M108   Tidbinbilla, NSW, Aust {5}148{0} {5}58{0} {5}47.9{0} {5}-35{0} {5}23{0} {5}57.1{0}   {5}665.3{0}\n YAR1  A 50107M004   Mingenew, Australia    {5}115{0} {5}20{0} {5}49.1{0} {5}-29{0} {5}02{0} {5}47.5{0}   {5}241.3{0}\n CEDU  A 50138M001   CEDU 50138M001         {5}133{0} {5}48{0} {5}35.3{0} {5}-31{0} {5}51{0} {5}59.9{0}   {5}144.7{0}\n HOB2  A 50116M004   Hobart/Tasmania, Austr {5}147{0} {5}26{0} {5}19.4{0} {5}-42{0} {5}48{0} {5}16.9{0}    {5}41.1{0}\n{3}-SITE/ID\n{1}* out-of-block single line comment\n{2}+SOLUTION/EPOCHS\n{1}*Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n{0} PERT  A    {5}1{0} C {4}94:004:00000{0} {4}94:113:00000{0} {4}94:058:43200{0}\n TIDB  A    {5}1{0} C {4}94:004:00000{0} {4}96:177:86389{0} {4}95:090:86394{0}\n YAR1  A    {5}1{0} C {4}94:004:00000{0} {4}97:230:00000{0} {4}95:300:00000{0}\n PERT  A    {5}2{0} C {4}94:117:00000{0} {4}01:030:00000{0} {4}97:256:00000{0}\n CEDU  A    {5}1{0} C {4}94:136:00000{0} {4}95:277:00000{0} {4}95:024:00000{0}\n HOB2  A    {5}1{0} C {4}94:187:00000{0} {4}97:137:00000{0} {4}95:345:00000{0}\n{3}-SOLUTION/EPOCHS\n{2}+SOLUTION/ESTIMATE\n{1}*INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n{5}1{0}        STAX PERT  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}-.236868757866128E+07{0} {5}0.74048E-03{0}\n{5}2{0}        STAY PERT  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}0.488131661461247E+07{0} {5}0.91864E-03{0}\n{5}3{0}        STAZ PERT  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}-.334179548710761E+07{0} {5}0.84688E-03{0}\n{5}4{0}        VELX PERT  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}-.472916775593191E-01{0} {5}0.39163E-04{0}\n{5}5{0}        VELY PERT  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.822689567578196E-02{0} {5}0.41751E-04{0}\n{5}6{0}        VELZ PERT  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.508006951054042E-01{0} {5}0.44388E-04{0}\n{5}29{0}       VELY CEDU  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.172935957701062E-02{0} {5}0.38085E-04{0}\n{5}30{0}       VELZ CEDU  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.504090658972641E-01{0} {5}0.42917E-04{0}\n{5}31{0}       STAX HOB2  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}-.395007186683046E+07{0} {5}0.68502E-03{0}\n{5}32{0}       STAY HOB2  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}0.252241528744047E+07{0} {5}0.60906E-03{0}\n{5}33{0}       STAZ HOB2  A    {5}1{0} {4}10:001:00000{0}  m   {5}2{0} {5}-.431163782526727E+07{0} {5}0.78320E-03{0}\n{5}34{0}       VELX HOB2  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}-.387112208023018E-01{0} {5}0.40249E-04{0}\n{5}35{0}       VELY HOB2  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.792637786129052E-02{0} {5}0.37662E-04{0}\n{5}36{0}       VELZ HOB2  A    {5}1{0} {4}10:001:00000{0}  m/y {5}2{0} {5}0.412562272254610E-01{0} {5}0.45803E-04{0}\n{3}-SOLUTION/ESTIMATE\n"
  },
  {
    "path": "test/examples/sinex/SciTE.properties",
    "content": "lexer.*.snx=sinex\n\nfold=1\nfold.comment=0\n\nif $(= $(FileNameExt);AllStyles_comment_fold.snx)\n    fold.comment=1\n"
  },
  {
    "path": "test/examples/smalltalk/ClassificationTable.st",
    "content": "\" File contains examples of all SCE_ST_* lexical states 0-16 \"\n\" Smalltalk code from the lexer that generates the character classification table.\"\n| lexTable classificationBlock charClasses |\ncharClasses := #(#DecDigit #Letter #Special #Upper #BinSel).\nlexTable := ByteArray new: 128.\nclassificationBlock := [ :charClass :chars |\n    | flag |\n    flag := 1 bitShift: (charClasses indexOf: charClass) - 1.\n    chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].\n\nclassificationBlock\n    value: #DecDigit value: '0123456789';\n    value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n    value: #Special value: '()[]{};.^:';\n    value: #BinSel value: '~@%&*-+=|\\/,<>?!';\n    value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n\n((String new: 500) streamContents: [ :stream |\n    stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.\n    lexTable keysAndValuesDo: [ :index :value |\n        ((index - 1) rem: 16) == 0 ifTrue: [\n            stream crLf; tab]\n        ifFalse: [\n            stream space].\n        stream print: value.\n        index ~= 256 ifTrue: [\n            stream nextPut: $,]].\n    stream crLf; nextPutAll: '};'; crLf.\n\n    charClasses keysAndValuesDo: [ :index :name |\n        stream\n            crLf;\n            nextPutAll: (\n                ('static inline bool is<1s>(unsigned char ch) {return (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')\n                    expandMacrosWith: name with: (1 bitShift: (index - 1)))\n    ]]) edit\n\n\" Some more syntax examples:\n  ^ is return (SCE_ST_RETURN)\n  true or false is bool (SCE_ST_BOOL)\n  self (SCE_ST_SELF)\n  super (SCE_ST_SUPER)\n  nil (SCE_ST_NIL)\n\"\nfoo\n  ^ Array with: 1 with: 2 with: false with: self with: super with: nil.\n\n\" Issue 274: A decimal separator is not required for scaled decimal numbers\"\n32.0s2\n4.0e3\n32s2\n4e3\n"
  },
  {
    "path": "test/examples/smalltalk/ClassificationTable.st.folded",
    "content": " 0 400   0   \" File contains examples of all SCE_ST_* lexical states 0-16 \"\n 0 400   0   \" Smalltalk code from the lexer that generates the character classification table.\"\n 0 400   0   | lexTable classificationBlock charClasses |\n 0 400   0   charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).\n 0 400   0   lexTable := ByteArray new: 128.\n 0 400   0   classificationBlock := [ :charClass :chars |\n 0 400   0       | flag |\n 0 400   0       flag := 1 bitShift: (charClasses indexOf: charClass) - 1.\n 0 400   0       chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].\n 0 400   0   \n 0 400   0   classificationBlock\n 0 400   0       value: #DecDigit value: '0123456789';\n 0 400   0       value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n 0 400   0       value: #Special value: '()[]{};.^:';\n 0 400   0       value: #BinSel value: '~@%&*-+=|\\/,<>?!';\n 0 400   0       value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n 0 400   0   \n 0 400   0   ((String new: 500) streamContents: [ :stream |\n 0 400   0       stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.\n 0 400   0       lexTable keysAndValuesDo: [ :index :value |\n 0 400   0           ((index - 1) rem: 16) == 0 ifTrue: [\n 0 400   0               stream crLf; tab]\n 0 400   0           ifFalse: [\n 0 400   0               stream space].\n 0 400   0           stream print: value.\n 0 400   0           index ~= 256 ifTrue: [\n 0 400   0               stream nextPut: $,]].\n 0 400   0       stream crLf; nextPutAll: '};'; crLf.\n 0 400   0   \n 0 400   0       charClasses keysAndValuesDo: [ :index :name |\n 0 400   0           stream\n 0 400   0               crLf;\n 0 400   0               nextPutAll: (\n 0 400   0                   ('static inline bool is<1s>(unsigned char ch) {return (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')\n 0 400   0                       expandMacrosWith: name with: (1 bitShift: (index - 1)))\n 0 400   0       ]]) edit\n 0 400   0   \n 0 400   0   \" Some more syntax examples:\n 0 400   0     ^ is return (SCE_ST_RETURN)\n 0 400   0     true or false is bool (SCE_ST_BOOL)\n 0 400   0     self (SCE_ST_SELF)\n 0 400   0     super (SCE_ST_SUPER)\n 0 400   0     nil (SCE_ST_NIL)\n 0 400   0   \"\n 0 400   0   foo\n 0 400   0     ^ Array with: 1 with: 2 with: false with: self with: super with: nil.\n 0 400   0   \n 0 400   0   \" Issue 274: A decimal separator is not required for scaled decimal numbers\"\n 0 400   0   32.0s2\n 0 400   0   4.0e3\n 0 400   0   32s2\n 0 400   0   4e3\n 0 400   0   "
  },
  {
    "path": "test/examples/smalltalk/ClassificationTable.st.styled",
    "content": "{3}\" File contains examples of all SCE_ST_* lexical states 0-16 \"{0}\n{3}\" Smalltalk code from the lexer that generates the character classification table.\"{0}\n{5}|{0} lexTable classificationBlock charClasses {5}|{0}\ncharClasses {14}:={0} {12}#({4}#DecDigit{0} {4}#Letter{0} {4}#Special{0} {4}#Upper{0} {4}#BinSel{12}).{0}\nlexTable {14}:={0} {10}ByteArray{0} {13}new:{0} {2}128{12}.{0}\nclassificationBlock {14}:={0} {12}[{0} {12}:{0}charClass {12}:{0}chars {5}|{0}\n    {5}|{0} flag {5}|{0}\n    flag {14}:={0} {2}1{0} {13}bitShift:{0} {12}({0}charClasses {13}indexOf:{0} charClass{12}){0} {5}-{0} {2}1{12}.{0}\n    chars {13}do:{0} {12}[{0} {12}:{0}char {5}|{0} lexTable {13}at:{0} char codePoint {5}+{0} {2}1{0} {13}put:{0} {12}(({0}lexTable {13}at:{0} char codePoint {5}+{0} {2}1{12}){0} {13}bitOr:{0} flag{12})]].{0}\n\nclassificationBlock\n    {13}value:{0} {4}#DecDigit{0} {13}value:{0} {1}'0123456789'{12};{0}\n    {13}value:{0} {4}#Letter{0} {13}value:{0} {1}'_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'{12};{0}\n    {13}value:{0} {4}#Special{0} {13}value:{0} {1}'()[]{};.^:'{12};{0}\n    {13}value:{0} {4}#BinSel{0} {13}value:{0} {1}'~@%&*-+=|\\/,<>?!'{12};{0}\n    {13}value:{0} {4}#Upper{0} {13}value:{0} {1}'ABCDEFGHIJKLMNOPQRSTUVWXYZ'{12}.{0}\n\n{12}(({10}String{0} {13}new:{0} {2}500{12}){0} {13}streamContents:{0} {12}[{0} {12}:{0}stream {5}|{0}\n    stream crLf{12};{0} {13}nextPutAll:{0} {1}'static int ClassificationTable[256] = {'{12}.{0}\n    lexTable {13}keysAndValuesDo:{0} {12}[{0} {12}:{0}index {12}:{0}value {5}|{0}\n        {12}(({0}index {5}-{0} {2}1{12}){0} {13}rem:{0} {2}16{12}){0} {5}=={0} {2}0{0} {16}ifTrue:{0} {12}[{0}\n            stream crLf{12};{0} tab{12}]{0}\n        {16}ifFalse:{0} {12}[{0}\n            stream space{12}].{0}\n        stream {13}print:{0} value{12}.{0}\n        index {5}~={0} {2}256{0} {16}ifTrue:{0} {12}[{0}\n            stream {13}nextPut:{0} {15}$,{12}]].{0}\n    stream crLf{12};{0} {13}nextPutAll:{0} {1}'};'{12};{0} crLf{12}.{0}\n\n    charClasses {13}keysAndValuesDo:{0} {12}[{0} {12}:{0}index {12}:{0}name {5}|{0}\n        stream\n            crLf{12};{0}\n            {13}nextPutAll:{0} {12}({0}\n                {12}({1}'static inline bool is<1s>(unsigned char ch) {return (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}'{12}){0}\n                    {13}expandMacrosWith:{0} name {13}with:{0} {12}({2}1{0} {13}bitShift:{0} {12}({0}index {5}-{0} {2}1{12}))){0}\n    {12}]]){0} edit\n\n{3}\" Some more syntax examples:\n  ^ is return (SCE_ST_RETURN)\n  true or false is bool (SCE_ST_BOOL)\n  self (SCE_ST_SELF)\n  super (SCE_ST_SUPER)\n  nil (SCE_ST_NIL)\n\"{0}\nfoo\n  {11}^{0} {10}Array{0} {13}with:{0} {2}1{0} {13}with:{0} {2}2{0} {13}with:{0} {6}false{0} {13}with:{0} {7}self{0} {13}with:{0} {8}super{0} {13}with:{0} {9}nil{12}.{0}\n\n{3}\" Issue 274: A decimal separator is not required for scaled decimal numbers\"{0}\n{2}32.0s2{0}\n{2}4.0e3{0}\n{2}32s2{0}\n{2}4e3{0}\n"
  },
  {
    "path": "test/examples/smalltalk/SciTE.properties",
    "content": "lexer.*.st=smalltalk\nkeywords.*.st=ifTrue: ifFalse: whileTrue: whileFalse: ifNil: ifNotNil: whileTrue whileFalse repeat isNil notNil\n"
  },
  {
    "path": "test/examples/sql/AllStyles.sql",
    "content": "-- Enumerate all styles: 0 to 24\n\n-- comment=1\n/* comment */\n\n-- whitespace=0\n\t-- w\n\n/* commentline=2 */\n-- commentline\n\n-- commentdoc=3\n/** commentdoc */\n\n-- number=4\n4\n\n-- word=5\nselect\n\n-- string=6\n\"string\"\n\n-- character=7\n'character'\n\n-- sqlplus=8\nappend\n\n-- sqlplus_prompt=9\nprompt SQL+Prompt\n\n-- operator=10\n+\n\n-- identifier=11\nidentifier\n\n-- sqlplus_comment=13\nremark sqlplus comment\n\n-- commentlinedoc=15\n# commentlinedoc\n\n-- word2=16\nobject\n\n-- commentdockeyword=17\n/** @return */\n\n-- commentdockeyworderror=18\n/** @error */\n\n-- user1=19\ndbms_output.disable\n\n-- user2=20\nanalyze\n\n-- user3=21\narray\n\n-- user4=22\nfalse\n\n-- quotedidentifier=23\n`quotedidentifier`\n\n-- qoperator=24\nq'{ today's }'\n"
  },
  {
    "path": "test/examples/sql/AllStyles.sql.folded",
    "content": " 0 400 400   -- Enumerate all styles: 0 to 24\n 1 400 400   \n 0 400 400   -- comment=1\n 0 400 400   /* comment */\n 1 400 400   \n 0 400 400   -- whitespace=0\n 0 400 400   \t-- w\n 1 400 400   \n 0 400 400   /* commentline=2 */\n 0 400 400   -- commentline\n 1 400 400   \n 0 400 400   -- commentdoc=3\n 0 400 400   /** commentdoc */\n 1 400 400   \n 0 400 400   -- number=4\n 0 400 400   4\n 1 400 400   \n 0 400 400   -- word=5\n 0 400 400   select\n 1 400 400   \n 0 400 400   -- string=6\n 0 400 400   \"string\"\n 1 400 400   \n 0 400 400   -- character=7\n 0 400 400   'character'\n 1 400 400   \n 0 400 400   -- sqlplus=8\n 0 400 400   append\n 1 400 400   \n 0 400 400   -- sqlplus_prompt=9\n 0 400 400   prompt SQL+Prompt\n 1 400 400   \n 0 400 400   -- operator=10\n 0 400 400   +\n 1 400 400   \n 0 400 400   -- identifier=11\n 0 400 400   identifier\n 1 400 400   \n 0 400 400   -- sqlplus_comment=13\n 0 400 400   remark sqlplus comment\n 1 400 400   \n 0 400 400   -- commentlinedoc=15\n 0 400 400   # commentlinedoc\n 1 400 400   \n 0 400 400   -- word2=16\n 0 400 400   object\n 1 400 400   \n 0 400 400   -- commentdockeyword=17\n 0 400 400   /** @return */\n 1 400 400   \n 0 400 400   -- commentdockeyworderror=18\n 0 400 400   /** @error */\n 1 400 400   \n 0 400 400   -- user1=19\n 0 400 400   dbms_output.disable\n 1 400 400   \n 0 400 400   -- user2=20\n 0 400 400   analyze\n 1 400 400   \n 0 400 400   -- user3=21\n 0 400 400   array\n 1 400 400   \n 0 400 400   -- user4=22\n 0 400 400   false\n 1 400 400   \n 0 400 400   -- quotedidentifier=23\n 0 400 400   `quotedidentifier`\n 1 400 400   \n 0 400 400   -- qoperator=24\n 0 400 400   q'{ today's }'\n 0 400   0   "
  },
  {
    "path": "test/examples/sql/AllStyles.sql.styled",
    "content": "{2}-- Enumerate all styles: 0 to 24\n{0}\n{2}-- comment=1\n{1}/* comment */{0}\n\n{2}-- whitespace=0\n{0}\t{2}-- w\n{0}\n{1}/* commentline=2 */{0}\n{2}-- commentline\n{0}\n{2}-- commentdoc=3\n{3}/** commentdoc */{0}\n\n{2}-- number=4\n{4}4{0}\n\n{2}-- word=5\n{5}select{0}\n\n{2}-- string=6\n{6}\"string\"{0}\n\n{2}-- character=7\n{7}'character'{0}\n\n{2}-- sqlplus=8\n{8}append{0}\n\n{2}-- sqlplus_prompt=9\n{8}prompt{9} SQL+Prompt\n{0}\n{2}-- operator=10\n{10}+{0}\n\n{2}-- identifier=11\n{11}identifier{0}\n\n{2}-- sqlplus_comment=13\n{8}remark{13} sqlplus comment\n{0}\n{2}-- commentlinedoc=15\n{15}# commentlinedoc\n{0}\n{2}-- word2=16\n{16}object{0}\n\n{2}-- commentdockeyword=17\n{3}/** {17}@return{3} */{0}\n\n{2}-- commentdockeyworderror=18\n{3}/** {18}@error{3} */{0}\n\n{2}-- user1=19\n{19}dbms_output.disable{0}\n\n{2}-- user2=20\n{20}analyze{0}\n\n{2}-- user3=21\n{21}array{0}\n\n{2}-- user4=22\n{22}false{0}\n\n{2}-- quotedidentifier=23\n{23}`quotedidentifier`{0}\n\n{2}-- qoperator=24\n{24}q'{ today's }'{0}\n"
  },
  {
    "path": "test/examples/sql/SciTE.properties",
    "content": "lexer.*.sql=sql\n\nkeywords.*.sql=select\nkeywords2.*.sql=object\nkeywords3.*.sql=return\nkeywords4.*.sql=a~ppend pro~mpt rem~ark\nkeywords5.*.sql=dbms_output.disable\nkeywords6.*.sql=analyze\nkeywords7.*.sql=array\nkeywords8.*.sql=false\n\nlexer.sql.backticks.identifier=1\nlexer.sql.numbersign.comment=1\nlexer.sql.allow.dotted.word=1\n\nfold=1\nfold.compact=1\n"
  },
  {
    "path": "test/examples/tcl/SciTE.properties",
    "content": "lexer.*.tcl=tcl\nkeywords.*.tcl=proc set socket vwait\nfold.comment=1\nfold.compact=1\n"
  },
  {
    "path": "test/examples/tcl/x.tcl",
    "content": "# tcl tests\n\n#simple example\n\nproc Echo_Server {port} {\n    set s [socket -server EchoAccept $port]\n    vwait forever;\n}\n\n# Bug #1947\n\n$s($i,\"n\")\nset n $showArray($i,\"neighbor\")\n"
  },
  {
    "path": "test/examples/tcl/x.tcl.folded",
    "content": " 2 400   3 + # tcl tests\n 1 401   3 | \n 0 401   3 | #simple example\n 1 401   3 | \n 2 400   2 + proc Echo_Server {port} {\n 0 401   2 |     set s [socket -server EchoAccept $port]\n 0 401   2 |     vwait forever;\n 0 401   0 | }\n 1 400   0   \n 2 400   3 + # Bug #1947\n 1 401   3 | \n 0 400   0   $s($i,\"n\")\n 0 400   0   set n $showArray($i,\"neighbor\")\n 1 400   0   "
  },
  {
    "path": "test/examples/tcl/x.tcl.styled",
    "content": "{2}# tcl tests\n{0}\n{2}#simple example\n{0}\n{12}proc{0} {7}Echo_Server{0} {6}{{7}port{6}}{0} {6}{\n{0}    {12}set{0} {7}s{0} {6}[{12}socket{0} {10}-server{0} {7}EchoAccept{0} {8}$port{6}]\n{0}    {12}vwait{0} {7}forever{0};\n{6}}\n{0}\n{2}# Bug #1947\n{0}\n{8}$s{6}({8}$i{6},{5}\"n\"{6})\n{12}set{0} {7}n{0} {8}$showArray{6}({8}$i{6},{5}\"neighbor\"{6})\n"
  },
  {
    "path": "test/examples/toml/AllStyles.toml",
    "content": "# coding:utf-8\n# This is a full-line comment\nkey = \"value\"  # This is a comment at the end of a line\nanother = \"# This is not a comment\"\n\nkey = \"value\"\nbare_key = \"value\"\nbare-key = \"value\"\n1234 = \"value\"\n\n\"127.0.0.1\" = \"value\"\n\"character encoding\" = \"value\"\n\"ʎǝʞ\" = \"value\"\n'key2' = \"value\"\n'quoted \"value\"' = \"value\"\n\nfruit.name = \"banana\"     # this is best practice\nfruit. color = \"yellow\"    # same as fruit.color\nfruit . flavor = \"banana\"   # same as fruit.flavor\n\nname = \"Orange\"\nphysical.color = \"orange\"\nphysical.shape = \"round\"\nsite.\"google.com\" = true\n\nstr = \"I'm a string. \\\"You can quote me\\\". Name\\tJos\\u00E9\\nLocation\\tSF.\"\n\nstr1 = \"\"\"\nRoses are red\nViolets are blue\"\"\"\n\n# The following strings are byte-for-byte equivalent:\nstr1 = \"The quick brown fox jumps over the lazy dog.\"\nstr2 = \"\"\"\nThe quick brown \\\n\n\n  fox jumps over \\\n    the lazy dog.\"\"\"\nstr3 = \"\"\"\\\n       The quick brown \\\n       fox jumps over \\\n       the lazy dog.\\\n       \"\"\"\n\nstr4 = \"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"\n# str5 = \"\"\"Here are three quotation marks: \"\"\".\"\"\"  # INVALID\nstr5 = \"\"\"Here are three quotation marks: \"\"\\\".\"\"\"\nstr6 = \"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"\n# \"This,\" she said, \"is just a pointless statement.\"\nstr7 = \"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"\n\n# What you see is what you get.\nwinpath  = 'C:\\Users\\nodejs\\templates'\nwinpath2 = '\\\\ServerX\\admin$\\system32\\'\nquoted   = 'Tom \"Dubs\" Preston-Werner'\nregex    = '<\\i\\c*\\s*>'\n\nregex2 = '''I [dw]on't need \\d{2} apples'''\nlines  = '''\nThe first newline is\ntrimmed in raw strings.\n   All other whitespace\n   is preserved.\n'''\n\nquot15 = '''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"'''\n# 'That,' she said, 'is still pointless.'\nstr = ''''That,' she said, 'is still pointless.''''\n\nint1 = +99\nint2 = 42\nint3 = 0\nint4 = -17\n\nint5 = 1_000\nint6 = 5_349_221\nint7 = 53_49_221  # Indian number system grouping\nint8 = 1_2_3_4_5  # VALID but discouraged\n\n# hexadecimal with prefix `0x`\nhex1 = 0xDEADBEEF\nhex2 = 0xdeadbeef\nhex3 = 0xdead_beef\n\n# octal with prefix `0o`\noct1 = 0o01234567\noct2 = 0o755 # useful for Unix file permissions\n\n# binary with prefix `0b`\nbin1 = 0b11010110\n\n# fractional\nflt1 = +1.0\nflt2 = 3.1415\nflt3 = -0.01\n\n# exponent\nflt4 = 5e+22\nflt5 = 1e06\nflt6 = -2E-2\n\n# both\nflt7 = 6.626e-34\n\nflt8 = 224_617.445_991_228\n\n# infinity\nsf1 = inf  # positive infinity\nsf2 = +inf # positive infinity\nsf3 = -inf # negative infinity\n\n# not a number\nsf4 = nan  # actual sNaN/qNaN encoding is implementation-specific\nsf5 = +nan # same as `nan`\nsf6 = -nan # valid, actual encoding is implementation-specific\n\nbool1 = true\nbool2 = false\n\nodt1 = 1979-05-27T07:32:00Z\nodt2 = 1979-05-27T00:32:00-07:00\nodt3 = 1979-05-27T00:32:00.999999-07:00\nodt4 = 1979-05-27 07:32:00Z\n\nldt1 = 1979-05-27T07:32:00\nldt2 = 1979-05-27T00:32:00.999999\n\nld1 = 1979-05-27\n\nlt1 = 07:32:00\nlt2 = 00:32:00.999999\n\nintegers = [ 1, 2, 3 ]\ncolors = [ \"red\", \"yellow\", \"green\" ]\nnested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]\nnested_mixed_array = [ [ 1, 2 ], [\"a\", \"b\", \"c\"] ]\nstring_array = [ \"all\", 'strings', \"\"\"are the same\"\"\", '''type''' ]\n\n# Mixed-type arrays are allowed\nnumbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]\ncontributors = [\n  \"Foo Bar <foo@example.com>\",\n  { name = \"Baz Qux\", email = \"bazqux@example.com\", url = \"https://example.com/bazqux\" }\n]\n\nintegers2 = [\n  1, 2, 3\n]\n\nintegers3 = [\n  1,\n  2, # this is ok\n]\n\n[table-1]\nkey1 = \"some string\"\nkey2 = 123\n\n[table-2]\nkey1 = \"another string\"\nkey2 = 456\n\n[dog.\"tater.man\"]\ntype.name = \"pug\"\n\n[a.b.c]            # this is best practice\n[ d.e.f ]          # same as [d.e.f]\n[ g .  h  . i ]    # same as [g.h.i]\n[ j . \"ʞ\" . 'l' ]  # same as [j.\"ʞ\".'l']\n\n[product]\ntype = { name = \"Nail\" }\n\n[[products]]\nname = \"Hammer\"\nsku = 738594937\n\n[[products]]  # empty table within the array\n\n[[products]]\nname = \"Nail\"\nsku = 284758393\n\npoints = [ { x = 1, y = 2, z = 3 },\n           { x = 7, y = 8, z = 9 },\n           { x = 2, y = 4, z = 8 } ]\n\n~~~~ = true       # invalid character in key\ninvalid           # invalid, missing value\nkey = identifier  # also invalid, identifier must be one of true, false, inf, nan\nkey = \"unterminated string\nkey = 'other unterminated string\n"
  },
  {
    "path": "test/examples/toml/AllStyles.toml.folded",
    "content": " 2 400   0 + # coding:utf-8\n 0 401   0 | # This is a full-line comment\n 0 400   0   key = \"value\"  # This is a comment at the end of a line\n 0 400   0   another = \"# This is not a comment\"\n 0 400   0   \n 0 400   0   key = \"value\"\n 0 400   0   bare_key = \"value\"\n 0 400   0   bare-key = \"value\"\n 0 400   0   1234 = \"value\"\n 0 400   0   \n 0 400   0   \"127.0.0.1\" = \"value\"\n 0 400   0   \"character encoding\" = \"value\"\n 0 400   0   \"ʎǝʞ\" = \"value\"\n 0 400   0   'key2' = \"value\"\n 0 400   0   'quoted \"value\"' = \"value\"\n 0 400   0   \n 0 400   0   fruit.name = \"banana\"     # this is best practice\n 0 400   0   fruit. color = \"yellow\"    # same as fruit.color\n 0 400   0   fruit . flavor = \"banana\"   # same as fruit.flavor\n 0 400   0   \n 0 400   0   name = \"Orange\"\n 0 400   0   physical.color = \"orange\"\n 0 400   0   physical.shape = \"round\"\n 0 400   0   site.\"google.com\" = true\n 0 400   0   \n 0 400   0   str = \"I'm a string. \\\"You can quote me\\\". Name\\tJos\\u00E9\\nLocation\\tSF.\"\n 0 400   0   \n 0 400   0   str1 = \"\"\"\n 0 400   0   Roses are red\n 0 400   0   Violets are blue\"\"\"\n 0 400   0   \n 0 400   0   # The following strings are byte-for-byte equivalent:\n 0 400   0   str1 = \"The quick brown fox jumps over the lazy dog.\"\n 0 400   0   str2 = \"\"\"\n 0 400   0   The quick brown \\\n 0 400   0   \n 0 400   0   \n 0 400   0     fox jumps over \\\n 0 400   0       the lazy dog.\"\"\"\n 0 400   0   str3 = \"\"\"\\\n 0 400   0          The quick brown \\\n 0 400   0          fox jumps over \\\n 0 400   0          the lazy dog.\\\n 0 400   0          \"\"\"\n 0 400   0   \n 0 400   0   str4 = \"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"\n 0 400   0   # str5 = \"\"\"Here are three quotation marks: \"\"\".\"\"\"  # INVALID\n 0 400   0   str5 = \"\"\"Here are three quotation marks: \"\"\\\".\"\"\"\n 0 400   0   str6 = \"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"\n 0 400   0   # \"This,\" she said, \"is just a pointless statement.\"\n 0 400   0   str7 = \"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"\n 0 400   0   \n 0 400   0   # What you see is what you get.\n 0 400   0   winpath  = 'C:\\Users\\nodejs\\templates'\n 0 400   0   winpath2 = '\\\\ServerX\\admin$\\system32\\'\n 0 400   0   quoted   = 'Tom \"Dubs\" Preston-Werner'\n 0 400   0   regex    = '<\\i\\c*\\s*>'\n 0 400   0   \n 0 400   0   regex2 = '''I [dw]on't need \\d{2} apples'''\n 0 400   0   lines  = '''\n 0 400   0   The first newline is\n 0 400   0   trimmed in raw strings.\n 0 400   0      All other whitespace\n 0 400   0      is preserved.\n 0 400   0   '''\n 0 400   0   \n 0 400   0   quot15 = '''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"'''\n 0 400   0   # 'That,' she said, 'is still pointless.'\n 0 400   0   str = ''''That,' she said, 'is still pointless.''''\n 0 400   0   \n 0 400   0   int1 = +99\n 0 400   0   int2 = 42\n 0 400   0   int3 = 0\n 0 400   0   int4 = -17\n 0 400   0   \n 0 400   0   int5 = 1_000\n 0 400   0   int6 = 5_349_221\n 0 400   0   int7 = 53_49_221  # Indian number system grouping\n 0 400   0   int8 = 1_2_3_4_5  # VALID but discouraged\n 0 400   0   \n 0 400   0   # hexadecimal with prefix `0x`\n 0 400   0   hex1 = 0xDEADBEEF\n 0 400   0   hex2 = 0xdeadbeef\n 0 400   0   hex3 = 0xdead_beef\n 0 400   0   \n 0 400   0   # octal with prefix `0o`\n 0 400   0   oct1 = 0o01234567\n 0 400   0   oct2 = 0o755 # useful for Unix file permissions\n 0 400   0   \n 0 400   0   # binary with prefix `0b`\n 0 400   0   bin1 = 0b11010110\n 0 400   0   \n 0 400   0   # fractional\n 0 400   0   flt1 = +1.0\n 0 400   0   flt2 = 3.1415\n 0 400   0   flt3 = -0.01\n 0 400   0   \n 0 400   0   # exponent\n 0 400   0   flt4 = 5e+22\n 0 400   0   flt5 = 1e06\n 0 400   0   flt6 = -2E-2\n 0 400   0   \n 0 400   0   # both\n 0 400   0   flt7 = 6.626e-34\n 0 400   0   \n 0 400   0   flt8 = 224_617.445_991_228\n 0 400   0   \n 0 400   0   # infinity\n 0 400   0   sf1 = inf  # positive infinity\n 0 400   0   sf2 = +inf # positive infinity\n 0 400   0   sf3 = -inf # negative infinity\n 0 400   0   \n 0 400   0   # not a number\n 0 400   0   sf4 = nan  # actual sNaN/qNaN encoding is implementation-specific\n 0 400   0   sf5 = +nan # same as `nan`\n 0 400   0   sf6 = -nan # valid, actual encoding is implementation-specific\n 0 400   0   \n 0 400   0   bool1 = true\n 0 400   0   bool2 = false\n 0 400   0   \n 0 400   0   odt1 = 1979-05-27T07:32:00Z\n 0 400   0   odt2 = 1979-05-27T00:32:00-07:00\n 0 400   0   odt3 = 1979-05-27T00:32:00.999999-07:00\n 0 400   0   odt4 = 1979-05-27 07:32:00Z\n 0 400   0   \n 0 400   0   ldt1 = 1979-05-27T07:32:00\n 0 400   0   ldt2 = 1979-05-27T00:32:00.999999\n 0 400   0   \n 0 400   0   ld1 = 1979-05-27\n 0 400   0   \n 0 400   0   lt1 = 07:32:00\n 0 400   0   lt2 = 00:32:00.999999\n 0 400   0   \n 0 400   0   integers = [ 1, 2, 3 ]\n 0 400   0   colors = [ \"red\", \"yellow\", \"green\" ]\n 0 400   0   nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]\n 0 400   0   nested_mixed_array = [ [ 1, 2 ], [\"a\", \"b\", \"c\"] ]\n 0 400   0   string_array = [ \"all\", 'strings', \"\"\"are the same\"\"\", '''type''' ]\n 0 400   0   \n 0 400   0   # Mixed-type arrays are allowed\n 0 400   0   numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]\n 0 400   0   contributors = [\n 0 400   0     \"Foo Bar <foo@example.com>\",\n 0 400   0     { name = \"Baz Qux\", email = \"bazqux@example.com\", url = \"https://example.com/bazqux\" }\n 0 400   0   ]\n 0 400   0   \n 0 400   0   integers2 = [\n 0 400   0     1, 2, 3\n 0 400   0   ]\n 0 400   0   \n 0 400   0   integers3 = [\n 0 400   0     1,\n 0 400   0     2, # this is ok\n 0 400   0   ]\n 0 400   0   \n 2 400   0 + [table-1]\n 0 401   0 | key1 = \"some string\"\n 0 401   0 | key2 = 123\n 0 401   0 | \n 2 400   0 + [table-2]\n 0 401   0 | key1 = \"another string\"\n 0 401   0 | key2 = 456\n 0 401   0 | \n 2 401   0 + [dog.\"tater.man\"]\n 0 402   0 | type.name = \"pug\"\n 0 402   0 | \n 0 402   0 | [a.b.c]            # this is best practice\n 0 402   0 | [ d.e.f ]          # same as [d.e.f]\n 0 402   0 | [ g .  h  . i ]    # same as [g.h.i]\n 2 402   0 + [ j . \"ʞ\" . 'l' ]  # same as [j.\"ʞ\".'l']\n 0 403   0 | \n 2 400   0 + [product]\n 0 401   0 | type = { name = \"Nail\" }\n 0 401   0 | \n 2 400   0 + [[products]]\n 0 401   0 | name = \"Hammer\"\n 0 401   0 | sku = 738594937\n 0 401   0 | \n 2 400   0 + [[products]]  # empty table within the array\n 0 401   0 | \n 2 400   0 + [[products]]\n 0 401   0 | name = \"Nail\"\n 0 401   0 | sku = 284758393\n 0 401   0 | \n 0 401   0 | points = [ { x = 1, y = 2, z = 3 },\n 0 401   0 |            { x = 7, y = 8, z = 9 },\n 0 401   0 |            { x = 2, y = 4, z = 8 } ]\n 0 401   0 | \n 0 401   0 | ~~~~ = true       # invalid character in key\n 0 401   0 | invalid           # invalid, missing value\n 0 401   0 | key = identifier  # also invalid, identifier must be one of true, false, inf, nan\n 0 401   0 | key = \"unterminated string\n 0 401   0 | key = 'other unterminated string\n 0 401   0 | "
  },
  {
    "path": "test/examples/toml/AllStyles.toml.styled",
    "content": "{1}# coding:utf-8\n# This is a full-line comment\n{6}key{0} {8}={0} {10}\"value\"{0}  {1}# This is a comment at the end of a line\n{6}another{0} {8}={0} {10}\"# This is not a comment\"{0}\n\n{6}key{0} {8}={0} {10}\"value\"{0}\n{6}bare_key{0} {8}={0} {10}\"value\"{0}\n{6}bare-key{0} {8}={0} {10}\"value\"{0}\n{6}1234{0} {8}={0} {10}\"value\"{0}\n\n{6}\"127.0.0.1\"{0} {8}={0} {10}\"value\"{0}\n{6}\"character encoding\"{0} {8}={0} {10}\"value\"{0}\n{6}\"ʎǝʞ\"{0} {8}={0} {10}\"value\"{0}\n{6}'key2'{0} {8}={0} {10}\"value\"{0}\n{6}'quoted \"value\"'{0} {8}={0} {10}\"value\"{0}\n\n{6}fruit{8}.{6}name{0} {8}={0} {10}\"banana\"{0}     {1}# this is best practice\n{6}fruit{8}.{6} color{0} {8}={0} {10}\"yellow\"{0}    {1}# same as fruit.color\n{6}fruit {8}.{6} flavor{0} {8}={0} {10}\"banana\"{0}   {1}# same as fruit.flavor\n{0}\n{6}name{0} {8}={0} {10}\"Orange\"{0}\n{6}physical{8}.{6}color{0} {8}={0} {10}\"orange\"{0}\n{6}physical{8}.{6}shape{0} {8}={0} {10}\"round\"{0}\n{6}site{8}.{6}\"google.com\"{0} {8}={0} {3}true{0}\n\n{6}str{0} {8}={0} {10}\"I'm a string. {13}\\\"{10}You can quote me{13}\\\"{10}. Name{13}\\t{10}Jos{13}\\u00E9\\n{10}Location{13}\\t{10}SF.\"{0}\n\n{6}str1{0} {8}={0} {12}\"\"\"\nRoses are red\nViolets are blue\"\"\"{0}\n\n{1}# The following strings are byte-for-byte equivalent:\n{6}str1{0} {8}={0} {10}\"The quick brown fox jumps over the lazy dog.\"{0}\n{6}str2{0} {8}={0} {12}\"\"\"\nThe quick brown \\\n\n\n  fox jumps over \\\n    the lazy dog.\"\"\"{0}\n{6}str3{0} {8}={0} {12}\"\"\"\\\n       The quick brown \\\n       fox jumps over \\\n       the lazy dog.\\\n       \"\"\"{0}\n\n{6}str4{0} {8}={0} {12}\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"{0}\n{1}# str5 = \"\"\"Here are three quotation marks: \"\"\".\"\"\"  # INVALID\n{6}str5{0} {8}={0} {12}\"\"\"Here are three quotation marks: \"\"{13}\\\"{12}.\"\"\"{0}\n{6}str6{0} {8}={0} {12}\"\"\"Here are fifteen quotation marks: \"\"{13}\\\"{12}\"\"{13}\\\"{12}\"\"{13}\\\"{12}\"\"{13}\\\"{12}\"\"{13}\\\"{12}.\"\"\"{0}\n{1}# \"This,\" she said, \"is just a pointless statement.\"\n{6}str7{0} {8}={0} {12}\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"{0}\n\n{1}# What you see is what you get.\n{6}winpath{0}  {8}={0} {9}'C:\\Users\\nodejs\\templates'{0}\n{6}winpath2{0} {8}={0} {9}'\\\\ServerX\\admin$\\system32\\'{0}\n{6}quoted{0}   {8}={0} {9}'Tom \"Dubs\" Preston-Werner'{0}\n{6}regex{0}    {8}={0} {9}'<\\i\\c*\\s*>'{0}\n\n{6}regex2{0} {8}={0} {11}'''I [dw]on't need \\d{2} apples'''{0}\n{6}lines{0}  {8}={0} {11}'''\nThe first newline is\ntrimmed in raw strings.\n   All other whitespace\n   is preserved.\n'''{0}\n\n{6}quot15{0} {8}={0} {11}'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"'''{0}\n{1}# 'That,' she said, 'is still pointless.'\n{6}str{0} {8}={0} {11}''''That,' she said, 'is still pointless.''''{0}\n\n{6}int1{0} {8}={0} {8}+{4}99{0}\n{6}int2{0} {8}={0} {4}42{0}\n{6}int3{0} {8}={0} {4}0{0}\n{6}int4{0} {8}={0} {8}-{4}17{0}\n\n{6}int5{0} {8}={0} {4}1_000{0}\n{6}int6{0} {8}={0} {4}5_349_221{0}\n{6}int7{0} {8}={0} {4}53_49_221{0}  {1}# Indian number system grouping\n{6}int8{0} {8}={0} {4}1_2_3_4_5{0}  {1}# VALID but discouraged\n{0}\n{1}# hexadecimal with prefix `0x`\n{6}hex1{0} {8}={0} {4}0xDEADBEEF{0}\n{6}hex2{0} {8}={0} {4}0xdeadbeef{0}\n{6}hex3{0} {8}={0} {4}0xdead_beef{0}\n\n{1}# octal with prefix `0o`\n{6}oct1{0} {8}={0} {4}0o01234567{0}\n{6}oct2{0} {8}={0} {4}0o755{0} {1}# useful for Unix file permissions\n{0}\n{1}# binary with prefix `0b`\n{6}bin1{0} {8}={0} {4}0b11010110{0}\n\n{1}# fractional\n{6}flt1{0} {8}={0} {8}+{4}1.0{0}\n{6}flt2{0} {8}={0} {4}3.1415{0}\n{6}flt3{0} {8}={0} {8}-{4}0.01{0}\n\n{1}# exponent\n{6}flt4{0} {8}={0} {4}5e+22{0}\n{6}flt5{0} {8}={0} {4}1e06{0}\n{6}flt6{0} {8}={0} {8}-{4}2E-2{0}\n\n{1}# both\n{6}flt7{0} {8}={0} {4}6.626e-34{0}\n\n{6}flt8{0} {8}={0} {4}224_617.445_991_228{0}\n\n{1}# infinity\n{6}sf1{0} {8}={0} {3}inf{0}  {1}# positive infinity\n{6}sf2{0} {8}={0} {8}+{3}inf{0} {1}# positive infinity\n{6}sf3{0} {8}={0} {8}-{3}inf{0} {1}# negative infinity\n{0}\n{1}# not a number\n{6}sf4{0} {8}={0} {3}nan{0}  {1}# actual sNaN/qNaN encoding is implementation-specific\n{6}sf5{0} {8}={0} {8}+{3}nan{0} {1}# same as `nan`\n{6}sf6{0} {8}={0} {8}-{3}nan{0} {1}# valid, actual encoding is implementation-specific\n{0}\n{6}bool1{0} {8}={0} {3}true{0}\n{6}bool2{0} {8}={0} {3}false{0}\n\n{6}odt1{0} {8}={0} {14}1979-05-27T07:32:00Z{0}\n{6}odt2{0} {8}={0} {14}1979-05-27T00:32:00-07:00{0}\n{6}odt3{0} {8}={0} {14}1979-05-27T00:32:00.999999-07:00{0}\n{6}odt4{0} {8}={0} {14}1979-05-27 07:32:00Z{0}\n\n{6}ldt1{0} {8}={0} {14}1979-05-27T07:32:00{0}\n{6}ldt2{0} {8}={0} {14}1979-05-27T00:32:00.999999{0}\n\n{6}ld1{0} {8}={0} {14}1979-05-27{0}\n\n{6}lt1{0} {8}={0} {14}07:32:00{0}\n{6}lt2{0} {8}={0} {14}00:32:00.999999{0}\n\n{6}integers{0} {8}={0} {8}[{0} {4}1{8},{0} {4}2{8},{0} {4}3{0} {8}]{0}\n{6}colors{0} {8}={0} {8}[{0} {10}\"red\"{8},{0} {10}\"yellow\"{8},{0} {10}\"green\"{0} {8}]{0}\n{6}nested_arrays_of_ints{0} {8}={0} {8}[{0} {8}[{0} {4}1{8},{0} {4}2{0} {8}],{0} {8}[{4}3{8},{0} {4}4{8},{0} {4}5{8}]{0} {8}]{0}\n{6}nested_mixed_array{0} {8}={0} {8}[{0} {8}[{0} {4}1{8},{0} {4}2{0} {8}],{0} {8}[{10}\"a\"{8},{0} {10}\"b\"{8},{0} {10}\"c\"{8}]{0} {8}]{0}\n{6}string_array{0} {8}={0} {8}[{0} {10}\"all\"{8},{0} {9}'strings'{8},{0} {12}\"\"\"are the same\"\"\"{8},{0} {11}'''type'''{0} {8}]{0}\n\n{1}# Mixed-type arrays are allowed\n{6}numbers{0} {8}={0} {8}[{0} {4}0.1{8},{0} {4}0.2{8},{0} {4}0.5{8},{0} {4}1{8},{0} {4}2{8},{0} {4}5{0} {8}]{0}\n{6}contributors{0} {8}={0} {8}[{0}\n  {10}\"Foo Bar <foo@example.com>\"{8},{0}\n  {8}{{0} {6}name{0} {8}={0} {10}\"Baz Qux\"{8},{0} {6}email{0} {8}={0} {10}\"bazqux@example.com\"{8},{0} {6}url{0} {8}={0} {10}\"https://example.com/bazqux\"{0} {8}}{0}\n{8}]{0}\n\n{6}integers2{0} {8}={0} {8}[{0}\n  {4}1{8},{0} {4}2{8},{0} {4}3{0}\n{8}]{0}\n\n{6}integers3{0} {8}={0} {8}[{0}\n  {4}1{8},{0}\n  {4}2{8},{0} {1}# this is ok\n{8}]{0}\n\n{5}[table-1]\n{6}key1{0} {8}={0} {10}\"some string\"{0}\n{6}key2{0} {8}={0} {4}123{0}\n\n{5}[table-2]\n{6}key1{0} {8}={0} {10}\"another string\"{0}\n{6}key2{0} {8}={0} {4}456{0}\n\n{5}[dog.\"tater.man\"]\n{6}type{8}.{6}name{0} {8}={0} {10}\"pug\"{0}\n\n{5}[a.b.c]{0}            {1}# this is best practice\n{5}[ d.e.f ]{0}          {1}# same as [d.e.f]\n{5}[ g .  h  . i ]{0}    {1}# same as [g.h.i]\n{5}[ j . \"ʞ\" . 'l' ]{0}  {1}# same as [j.\"ʞ\".'l']\n{0}\n{5}[product]\n{6}type{0} {8}={0} {8}{{0} {6}name{0} {8}={0} {10}\"Nail\"{0} {8}}{0}\n\n{5}[[products]]\n{6}name{0} {8}={0} {10}\"Hammer\"{0}\n{6}sku{0} {8}={0} {4}738594937{0}\n\n{5}[[products]]{0}  {1}# empty table within the array\n{0}\n{5}[[products]]\n{6}name{0} {8}={0} {10}\"Nail\"{0}\n{6}sku{0} {8}={0} {4}284758393{0}\n\n{6}points{0} {8}={0} {8}[{0} {8}{{0} {6}x{0} {8}={0} {4}1{8},{0} {6}y{0} {8}={0} {4}2{8},{0} {6}z{0} {8}={0} {4}3{0} {8}},{0}\n           {8}{{0} {6}x{0} {8}={0} {4}7{8},{0} {6}y{0} {8}={0} {4}8{8},{0} {6}z{0} {8}={0} {4}9{0} {8}},{0}\n           {8}{{0} {6}x{0} {8}={0} {4}2{8},{0} {6}y{0} {8}={0} {4}4{8},{0} {6}z{0} {8}={0} {4}8{0} {8}}{0} {8}]{0}\n\n{7}~~~~ = true       {1}# invalid character in key\n{6}invalid{0}           {1}# invalid, missing value\n{6}key{0} {8}={0} {2}identifier{0}  {1}# also invalid, identifier must be one of true, false, inf, nan\n{6}key{0} {8}={0} {15}\"unterminated string\n{6}key{0} {8}={0} {15}'other unterminated string\n"
  },
  {
    "path": "test/examples/toml/SciTE.properties",
    "content": "lexer.*.toml=toml\nfold=1\nkeywords.*.toml=false inf nan true\n"
  },
  {
    "path": "test/examples/troff/AllStyles.roff",
    "content": ".tm Hello world \"FOO\"\n.if 'foo'b a r' .if 23 .FOO 2332 \"hell\\fBo\\fP\" \\\n foo \"Hello world\"\n.if (1 + 1) .nop\n.if 1 \\\n  .tm Bar\n.if 23+1 \\\n  .tm Bar\n.if 1 \\{\\\n.  tm TEST\n.  tm FOO\n.\\}\n.\n.\\\" Hello world\n.if 0 \\{\\\n.  tm Bar\n.  tm sffsdf\\}\n\\# Hello world\n.tm End\n.ig ig\nThis is \\fBignored\\fP.\n\nThis line as well.\n.ig\n.tm Hello world\n..\n.\n.de Macro END\n.  FOO\n.END\n\\*[FOO*\\[hello]fdsf]sdfsdf\n.END\n\\$1 \\\" will never be met in the wild...\n\\f[BI]Hello world\\fP\n\\na-\\n(ab-\\n[ab]-\n\\m[green]green text\\m[]\n\\(lqquoted text\\(rq\n$PATH=\\V[PATH]\n\\O0test\n\\s0small\\s+1larger\\s+[100]very large\\s-'100'smaller\n\\!transparent \\fBline\\fP\ntransparent\\?embed\\?\n\\A'id'\n\\D'c 10' \\l'10c' \\L'10c'\n\\h'12c' \\v'4'\n\\H@23@\n\\o#abc#\n\\S'45'\n\\w'width of'\n\\x'1'\n\\X'device control' \\Y[foo]\n\\Z\"No move\" \\zN\n"
  },
  {
    "path": "test/examples/troff/AllStyles.roff.folded",
    "content": " 0 400   0   .tm Hello world \"FOO\"\n 0 400   0   .if 'foo'b a r' .if 23 .FOO 2332 \"hell\\fBo\\fP\" \\\n 0 400   0    foo \"Hello world\"\n 0 400   0   .if (1 + 1) .nop\n 0 400   0   .if 1 \\\n 0 400   0     .tm Bar\n 0 400   0   .if 23+1 \\\n 0 400   0     .tm Bar\n 2 400   0 + .if 1 \\{\\\n 0 401   0 | .  tm TEST\n 0 401   0 | .  tm FOO\n 0 401   0 | .\\}\n 1 400   0   .\n 0 400   0   .\\\" Hello world\n 2 400   0 + .if 0 \\{\\\n 0 401   0 | .  tm Bar\n 0 401   0 | .  tm sffsdf\\}\n 0 400   0   \\# Hello world\n 0 400   0   .tm End\n 2 400   0 + .ig ig\n 0 401   0 | This is \\fBignored\\fP.\n 0 401   0 | \n 0 401   0 | This line as well.\n 2 400   0 + .ig\n 0 401   0 | .tm Hello world\n 0 400   0   ..\n 1 400   0   .\n 2 400   0 + .de Macro END\n 0 401   0 | .  FOO\n 0 401   0 | .END\n 0 400   0   \\*[FOO*\\[hello]fdsf]sdfsdf\n 0 400   0   .END\n 0 400   0   \\$1 \\\" will never be met in the wild...\n 0 400   0   \\f[BI]Hello world\\fP\n 0 400   0   \\na-\\n(ab-\\n[ab]-\n 0 400   0   \\m[green]green text\\m[]\n 0 400   0   \\(lqquoted text\\(rq\n 0 400   0   $PATH=\\V[PATH]\n 0 400   0   \\O0test\n 0 400   0   \\s0small\\s+1larger\\s+[100]very large\\s-'100'smaller\n 0 400   0   \\!transparent \\fBline\\fP\n 0 400   0   transparent\\?embed\\?\n 0 400   0   \\A'id'\n 0 400   0   \\D'c 10' \\l'10c' \\L'10c'\n 0 400   0   \\h'12c' \\v'4'\n 0 400   0   \\H@23@\n 0 400   0   \\o#abc#\n 0 400   0   \\S'45'\n 0 400   0   \\w'width of'\n 0 400   0   \\x'1'\n 0 400   0   \\X'device control' \\Y[foo]\n 0 400   0   \\Z\"No move\" \\zN\n 0 400   0   "
  },
  {
    "path": "test/examples/troff/AllStyles.roff.styled",
    "content": "{1}.tm{0} Hello world \"FOO\"\n{1}.if{0} 'foo'b a r'{1} .if{0} {3}23{2} .FOO{0} {3}2332{0} {5}\"hell{10}\\fB{5}o{10}\\fP{5}\"{0} {13}\\\n{0} foo {5}\"Hello world\"{0}\n{1}.if{0} ({3}1{0} + {3}1{0}){1} .nop\n.if{0} {3}1{0} {13}\\\n{1}  .tm{0} Bar\n{1}.if{0} {3}23{0}+{3}1{0} {13}\\\n{1}  .tm{0} Bar\n{1}.if{0} {3}1{0} {4}\\{{13}\\\n{1}.  tm{0} TEST\n{1}.  tm{0} FOO\n{4}.\\}\n{1}.\n{6}.\\\" Hello world\n{1}.if{0} {3}0{0} {4}\\{{13}\\\n{1}.  tm{0} Bar\n{1}.  tm{0} sffsdf{4}\\}{0}\n{6}\\# Hello world\n{1}.tm{0} End\n{1}.ig {0}ig\n{7}This is \\fBignored\\fP.\n\nThis line as well.\n{1}.ig{0}\n{7}.tm Hello world\n{1}..{0}\n{1}.\n.de{0} Macro END\n{2}.  FOO{0}\n{2}.END{0}\n{8}\\*[FOO*\\[hello]fdsf]{0}sdfsdf\n{2}.END{0}\n{9}\\$1{0} {6}\\\" will never be met in the wild...\n{10}\\f[BI]{0}Hello world{10}\\fP{0}\n{11}\\na{0}-{11}\\n(ab{0}-{11}\\n[ab]{0}-\n{12}\\m[green]{0}green text{12}\\m[]{0}\n{13}\\(lq{0}quoted text{13}\\(rq{0}\n$PATH={14}\\V[PATH]{0}\n{15}\\O0{0}test\n{16}\\s0{0}small{16}\\s+1{0}larger{16}\\s+[100]{0}very large{16}\\s-'100'{0}smaller\n{17}\\!transparent \\fBline\\fP\n{0}transparent{17}\\?embed\\?{0}\n{18}\\A'id'{0}\n{19}\\D'c 10'{0} {19}\\l'10c'{0} {19}\\L'10c'{0}\n{20}\\h'12c'{0} {20}\\v'4'{0}\n{21}\\H@23@{0}\n{22}\\o#abc#{0}\n{23}\\S'45'{0}\n{24}\\w'width of'{0}\n{25}\\x'1'{0}\n{26}\\X'device control'{0} {26}\\Y[foo]{0}\n{27}\\Z\"No move\"{0} {27}\\zN{0}\n"
  },
  {
    "path": "test/examples/troff/SciTE.properties",
    "content": "lexer.*.roff=troff\n\n# Predefined requests\nkeywords.*.roff= \\\nab ad af aln als am am1 ami ami1 as as1 asciify \\\nbacktrace bd blm box boxa bp br brp break \\\nc2 cc ce cf cflags ch char chop class close color composite continue cp cs cu \\\nda de de1 defcolor dei dei1 device devicem di do ds ds1 dt \\\nec ecr ecs el em eo ev evc ex \\\nfam fc fchar fcolor fi fl fp fschar fspecial ft ftr fzoom \\\ngcolor \\\nhc hcode hla hlm hpf hpfa hpfcode hw hy hym hys \\\nie if ig . in it itc \\\nkern \\\nlc length linetabs linetabs lf lg ll lsm ls lt \\\nmc mk mso \\\nna ne nf nh nm nn nop nr nroff ns nx \\\nopen opena os output \\\npc pev pi pl pm pn pnr po ps psbb pso ptr pvs pvs \\\nrchar rd return rfschar rj rm rn rnn rr rs rt \\\nschar shc shift sizes so sp special spreadwarn ss sty substring sv sy \\\nta tc ti tkf tl tm tm1 tmc tr trf trin trnt troff \\\nuf ul unformat \\\nvpt vs \\\nwarn warnscale wh while write writec writem\n# Flow control requests/commands with conditionals\nkeywords2.*.roff=if ie while\n# Flow control requests/commands without conditionals\nkeywords3.*.roff=el nop\n# Requests and commands, initiating ignore blocks\nkeywords4.*.roff=ig\n# Requests and commands with end-macros\nkeywords5.*.roff=am am1 de de1\n\nfold=1\n"
  },
  {
    "path": "test/examples/vb/AllStyles.vb",
    "content": "' coding: utf-8\n' Enumerate all styles: 0 .. 12\n\n' comment=1\n\n' whitespace=0\n\t' w\n\n' number=2\n37\n54.3345612e7\n&B01111100\n&O1163\n&H_E635_9A60\n\n' keyword=3\nstring\n\n' double-quoted-string=4\n\"str\"\n\"a\"c\n\n' preprocessor=5\n#Const preproc = True\n\n' operator=6\n- 1\n\n' identifier=7\nidentifier = 7\n' non-ASCII\nπ_is_pi_ω = 3.14\n' vb may add a type character like $ to identifiers; vbscript doesn't have this\nidentifier$ = \"s\"\n\n' date=8\nd=#05/11/2003#\n\n' unclosed-string=9\n\" unclosed\n\n' keyword2=10\nkey2\n\n' keyword3=11\nkey3\n\n' keyword4=12\nkey4\n"
  },
  {
    "path": "test/examples/vb/AllStyles.vb.folded",
    "content": " 1 400   0   ' coding: utf-8\n 1 400   0   ' Enumerate all styles: 0 .. 12\n 1 400   0   \n 1 400   0   ' comment=1\n 1 400   0   \n 1 400   0   ' whitespace=0\n 1 408   0 | \t' w\n 1 400   0   \n 1 400   0   ' number=2\n 0 400   0   37\n 0 400   0   54.3345612e7\n 0 400   0   &B01111100\n 0 400   0   &O1163\n 0 400   0   &H_E635_9A60\n 1 400   0   \n 1 400   0   ' keyword=3\n 0 400   0   string\n 1 400   0   \n 1 400   0   ' double-quoted-string=4\n 0 400   0   \"str\"\n 0 400   0   \"a\"c\n 1 400   0   \n 1 400   0   ' preprocessor=5\n 0 400   0   #Const preproc = True\n 1 400   0   \n 1 400   0   ' operator=6\n 0 400   0   - 1\n 1 400   0   \n 1 400   0   ' identifier=7\n 0 400   0   identifier = 7\n 1 400   0   ' non-ASCII\n 0 400   0   π_is_pi_ω = 3.14\n 1 400   0   ' vb may add a type character like $ to identifiers; vbscript doesn't have this\n 0 400   0   identifier$ = \"s\"\n 1 400   0   \n 1 400   0   ' date=8\n 0 400   0   d=#05/11/2003#\n 1 400   0   \n 1 400   0   ' unclosed-string=9\n 0 400   0   \" unclosed\n 1 400   0   \n 1 400   0   ' keyword2=10\n 0 400   0   key2\n 1 400   0   \n 1 400   0   ' keyword3=11\n 0 400   0   key3\n 1 400   0   \n 1 400   0   ' keyword4=12\n 0 400   0   key4\n 0 400   0   "
  },
  {
    "path": "test/examples/vb/AllStyles.vb.styled",
    "content": "{1}' coding: utf-8\n' Enumerate all styles: 0 .. 12\n{0}\n{1}' comment=1\n{0}\n{1}' whitespace=0\n{0}\t{1}' w\n{0}\n{1}' number=2\n{2}37{0}\n{2}54.3345612e7{0}\n{2}&B01111100{0}\n{2}&O1163{0}\n{2}&H_E635_9A60{0}\n\n{1}' keyword=3\n{3}string{0}\n\n{1}' double-quoted-string=4\n{4}\"str\"{0}\n{4}\"a\"c{0}\n\n{1}' preprocessor=5\n{5}#Const preproc = True\n{0}\n{1}' operator=6\n{6}-{0} {2}1{0}\n\n{1}' identifier=7\n{7}identifier{0} {6}={0} {2}7{0}\n{1}' non-ASCII\n{7}π_is_pi_ω{0} {6}={0} {2}3.14{0}\n{1}' vb may add a type character like $ to identifiers; vbscript doesn't have this\n{7}identifier${0} {6}={0} {4}\"s\"{0}\n\n{1}' date=8\n{7}d{6}={8}#05/11/2003#{0}\n\n{1}' unclosed-string=9\n{9}\" unclosed\n{0}\n{1}' keyword2=10\n{10}key2{0}\n\n{1}' keyword3=11\n{11}key3{0}\n\n{1}' keyword4=12\n{12}key4{0}\n"
  },
  {
    "path": "test/examples/vb/AllStyles.vbs",
    "content": "' coding: utf-8\n' Enumerate all styles: 0 .. 12\n\n' comment=1\n\n' whitespace=0\n\t' w\n\n' number=2\n37\n54.3345612e7\n&B01111100\n&O1163\n&H_E635_9A60\n\n' keyword=3\nstring\n\n' double-quoted-string=4\n\"str\"\n\"a\"c\n\n' preprocessor=5\n#Const preproc = True\n\n' operator=6\n- 1\n\n' identifier=7\nidentifier = 7\n' non-ASCII\nπ_is_pi_ω = 3.14\n' vb may add a type character like $ to identifiers; vbscript doesn't have this\nidentifier$ = \"s\"\n\n' date=8\nd=#05/11/2003#\n\n' unclosed-string=9\n\" unclosed\n\n' keyword2=10\nkey2\n\n' keyword3=11\nkey3\n\n' keyword4=12\nkey4\n"
  },
  {
    "path": "test/examples/vb/AllStyles.vbs.folded",
    "content": " 1 400   0   ' coding: utf-8\n 1 400   0   ' Enumerate all styles: 0 .. 12\n 1 400   0   \n 1 400   0   ' comment=1\n 1 400   0   \n 1 400   0   ' whitespace=0\n 1 408   0 | \t' w\n 1 400   0   \n 1 400   0   ' number=2\n 0 400   0   37\n 0 400   0   54.3345612e7\n 0 400   0   &B01111100\n 0 400   0   &O1163\n 0 400   0   &H_E635_9A60\n 1 400   0   \n 1 400   0   ' keyword=3\n 0 400   0   string\n 1 400   0   \n 1 400   0   ' double-quoted-string=4\n 0 400   0   \"str\"\n 0 400   0   \"a\"c\n 1 400   0   \n 1 400   0   ' preprocessor=5\n 0 400   0   #Const preproc = True\n 1 400   0   \n 1 400   0   ' operator=6\n 0 400   0   - 1\n 1 400   0   \n 1 400   0   ' identifier=7\n 0 400   0   identifier = 7\n 1 400   0   ' non-ASCII\n 0 400   0   π_is_pi_ω = 3.14\n 1 400   0   ' vb may add a type character like $ to identifiers; vbscript doesn't have this\n 0 400   0   identifier$ = \"s\"\n 1 400   0   \n 1 400   0   ' date=8\n 0 400   0   d=#05/11/2003#\n 1 400   0   \n 1 400   0   ' unclosed-string=9\n 0 400   0   \" unclosed\n 1 400   0   \n 1 400   0   ' keyword2=10\n 0 400   0   key2\n 1 400   0   \n 1 400   0   ' keyword3=11\n 0 400   0   key3\n 1 400   0   \n 1 400   0   ' keyword4=12\n 0 400   0   key4\n 0 400   0   "
  },
  {
    "path": "test/examples/vb/AllStyles.vbs.styled",
    "content": "{1}' coding: utf-8\n' Enumerate all styles: 0 .. 12\n{0}\n{1}' comment=1\n{0}\n{1}' whitespace=0\n{0}\t{1}' w\n{0}\n{1}' number=2\n{2}37{0}\n{2}54.3345612e7{0}\n{2}&B01111100{0}\n{2}&O1163{0}\n{2}&H_E635_9A60{0}\n\n{1}' keyword=3\n{3}string{0}\n\n{1}' double-quoted-string=4\n{4}\"str\"{0}\n{4}\"a\"c{0}\n\n{1}' preprocessor=5\n{5}#Const preproc = True\n{0}\n{1}' operator=6\n{6}-{0} {2}1{0}\n\n{1}' identifier=7\n{7}identifier{0} {6}={0} {2}7{0}\n{1}' non-ASCII\n{7}π_is_pi_ω{0} {6}={0} {2}3.14{0}\n{1}' vb may add a type character like $ to identifiers; vbscript doesn't have this\n{7}identifier{0}$ {6}={0} {4}\"s\"{0}\n\n{1}' date=8\n{7}d{6}={8}#05/11/2003#{0}\n\n{1}' unclosed-string=9\n{9}\" unclosed\n{0}\n{1}' keyword2=10\n{10}key2{0}\n\n{1}' keyword3=11\n{11}key3{0}\n\n{1}' keyword4=12\n{12}key4{0}\n"
  },
  {
    "path": "test/examples/vb/SciTE.properties",
    "content": "lexer.*.vb=vb\nkeywords.*.vb=as dim or string\nkeywords2.*.vb=key2\nkeywords3.*.vb=key3\nkeywords4.*.vb=key4\n\nlexer.*.vbs=vbscript\nkeywords.*.vbs=as dim or string\nkeywords2.*.vbs=key2\nkeywords3.*.vbs=key3\nkeywords4.*.vbs=key4\n\nfold=1\n\nmatch x.vb\n\tlexer.vb.strings.multiline=1\n"
  },
  {
    "path": "test/examples/vb/x.vb",
    "content": "' String\"\nDim a As String = \"hello, world\"\nDim b As String = \"hello    world\"\nDim c As String = \"Joe said \"\"Hello\"\" to me\"\nDim d As String = \"\\\\\\\\server\\\\share\\\\file.txt\"\nDim e As String = \"The brown fox\njumps over\nthe lazy dog\"\n' Character\n\"\"C \"c\"C \"cc\"C\n' Date\nd = #5/31/1993# or # 01/01/0001 12:00:00AM #\n' Number\n123_456___789\n123_\n&b10101_01010\n"
  },
  {
    "path": "test/examples/vb/x.vb.folded",
    "content": " 1 400   0   ' String\"\n 0 400   0   Dim a As String = \"hello, world\"\n 0 400   0   Dim b As String = \"hello    world\"\n 0 400   0   Dim c As String = \"Joe said \"\"Hello\"\" to me\"\n 0 400   0   Dim d As String = \"\\\\\\\\server\\\\share\\\\file.txt\"\n 0 400   0   Dim e As String = \"The brown fox\n 0 400   0   jumps over\n 0 400   0   the lazy dog\"\n 1 400   0   ' Character\n 0 400   0   \"\"C \"c\"C \"cc\"C\n 1 400   0   ' Date\n 0 400   0   d = #5/31/1993# or # 01/01/0001 12:00:00AM #\n 1 400   0   ' Number\n 0 400   0   123_456___789\n 0 400   0   123_\n 0 400   0   &b10101_01010\n 0 400   0   "
  },
  {
    "path": "test/examples/vb/x.vb.styled",
    "content": "{1}' String\"\n{3}Dim{0} {7}a{0} {3}As{0} {3}String{0} {6}={0} {4}\"hello, world\"{0}\n{3}Dim{0} {7}b{0} {3}As{0} {3}String{0} {6}={0} {4}\"hello    world\"{0}\n{3}Dim{0} {7}c{0} {3}As{0} {3}String{0} {6}={0} {4}\"Joe said \"\"Hello\"\" to me\"{0}\n{3}Dim{0} {7}d{0} {3}As{0} {3}String{0} {6}={0} {4}\"\\\\\\\\server\\\\share\\\\file.txt\"{0}\n{3}Dim{0} {7}e{0} {3}As{0} {3}String{0} {6}={0} {4}\"The brown fox\njumps over\nthe lazy dog\"{0}\n{1}' Character\n{4}\"\"C{0} {4}\"c\"C{0} {4}\"cc\"C{0}\n{1}' Date\n{7}d{0} {6}={0} {8}#5/31/1993#{0} {3}or{0} {8}# 01/01/0001 12:00:00AM #{0}\n{1}' Number\n{2}123_456___789{0}\n{2}123_{0}\n{2}&b10101_01010{0}\n"
  },
  {
    "path": "test/examples/verilog/AllStyles.vh",
    "content": "// Examples drawn from https://verilogams.com/refman/basics/index.html\n\n// SCE_V_DEFAULT {0}\n\n/*\n * SCE_V_COMMENT {1}\n */\n\n// SCE_V_COMMENTLINE {2}\n// multiple\n// comment lines\n// are folded\n\n//{ explicit folds\n//  are folded,\n//} too\n\n//! SCE_V_COMMENTLINEBANG {3}\n//! multiple\n//! bang comments\n//! are folded\n\n// SCE_V_NUMBER {4}\n1'b0\n8'hx\n8'hfffx\n12'hfx\n64'o0\n0x7f\n0o23\n0b1011\n42_839\n0.1\n1.3u\n5.46K\n1.2E12\n1.30e-2\n236.123_763e-12\n\n// SCE_V_WORD {5}\nalways\n\n// SCE_V_STRING {6}\n\"\\tsome\\ttext\\r\\n\"\n\n// SCE_V_WORD2 {7}\nspecial\n\n// SCE_V_WORD3 {8}\n$async$and$array\n\n// SCE_V_PREPROCESSOR {9}\n`define __VAMS_ENABLE__\n`ifdef __VAMS_ENABLE__\n    parameter integer del = 1 from [1:100];\n`else\n    parameter del = 1;\n`endif\n\n// SCE_V_OPERATOR {10}\n+-/=!@#%^&*()[]{}<|>~\n\n// SCE_V_IDENTIFIER {11}\nq\nx$z\n\\my_var\n\\/x1/n1\n\\\\x1\\n1\n\\{a,b}\n\\V(p,n)\n\n// SCE_V_STRINGEOL {12}\n\"\\n\n\n// SCE_V_USER {19}\nmy_var\n\n// SCE_V_COMMENT_WORD {20}\n// TODO write a comment\n\nmodule mod(clk, q, reset) // folded when fold.verilog.flags=1\n// SCE_V_INPUT {21}\n  input clk;\n\n// SCE_V_OUTPUT {22}\n  output q;\n\n// SCE_V_INOUT {23}\n  inout reset;\nendmodule\n\n// SCE_V_PORT_CONNECT {24}\nmod m1(\n  .clk(clk),\n  .q(q),\n  .reset(reset)\n);\n"
  },
  {
    "path": "test/examples/verilog/AllStyles.vh.folded",
    "content": " 0 400 400   // Examples drawn from https://verilogams.com/refman/basics/index.html\n 0 400 400   \n 0 400 400   // SCE_V_DEFAULT {0}\n 0 400 400   \n 2 400 401 + /*\n 0 401 401 |  * SCE_V_COMMENT {1}\n 0 401 400 |  */\n 0 400 400   \n 2 400 401 + // SCE_V_COMMENTLINE {2}\n 0 401 401 | // multiple\n 0 401 401 | // comment lines\n 0 401 400 | // are folded\n 0 400 400   \n 2 400 402 + //{ explicit folds\n 0 402 402 | //  are folded,\n 0 402 400 | //} too\n 0 400 400   \n 2 400 401 + //! SCE_V_COMMENTLINEBANG {3}\n 0 401 401 | //! multiple\n 0 401 401 | //! bang comments\n 0 401 400 | //! are folded\n 0 400 400   \n 0 400 400   // SCE_V_NUMBER {4}\n 0 400 400   1'b0\n 0 400 400   8'hx\n 0 400 400   8'hfffx\n 0 400 400   12'hfx\n 0 400 400   64'o0\n 0 400 400   0x7f\n 0 400 400   0o23\n 0 400 400   0b1011\n 0 400 400   42_839\n 0 400 400   0.1\n 0 400 400   1.3u\n 0 400 400   5.46K\n 0 400 400   1.2E12\n 0 400 400   1.30e-2\n 0 400 400   236.123_763e-12\n 0 400 400   \n 0 400 400   // SCE_V_WORD {5}\n 0 400 400   always\n 0 400 400   \n 0 400 400   // SCE_V_STRING {6}\n 0 400 400   \"\\tsome\\ttext\\r\\n\"\n 0 400 400   \n 0 400 400   // SCE_V_WORD2 {7}\n 0 400 400   special\n 0 400 400   \n 0 400 400   // SCE_V_WORD3 {8}\n 0 400 400   $async$and$array\n 0 400 400   \n 0 400 400   // SCE_V_PREPROCESSOR {9}\n 0 400 400   `define __VAMS_ENABLE__\n 2 400 401 + `ifdef __VAMS_ENABLE__\n 0 401 401 |     parameter integer del = 1 from [1:100];\n 2 400 401 + `else\n 0 401 401 |     parameter del = 1;\n 0 401 400 | `endif\n 0 400 400   \n 0 400 400   // SCE_V_OPERATOR {10}\n 0 400 400   +-/=!@#%^&*()[]{}<|>~\n 0 400 400   \n 0 400 400   // SCE_V_IDENTIFIER {11}\n 0 400 400   q\n 0 400 400   x$z\n 0 400 400   \\my_var\n 0 400 400   \\/x1/n1\n 0 400 400   \\\\x1\\n1\n 0 400 400   \\{a,b}\n 0 400 400   \\V(p,n)\n 0 400 400   \n 0 400 400   // SCE_V_STRINGEOL {12}\n 0 400 400   \"\\n\n 0 400 400   \n 0 400 400   // SCE_V_USER {19}\n 0 400 400   my_var\n 0 400 400   \n 2 400 401 + // SCE_V_COMMENT_WORD {20}\n 0 401 400 | // TODO write a comment\n 0 400 400   \n 2 400 401 + module mod(clk, q, reset) // folded when fold.verilog.flags=1\n 0 401 401 | // SCE_V_INPUT {21}\n 0 401 401 |   input clk;\n 0 401 401 | \n 0 401 401 | // SCE_V_OUTPUT {22}\n 0 401 401 |   output q;\n 0 401 401 | \n 0 401 401 | // SCE_V_INOUT {23}\n 0 401 401 |   inout reset;\n 0 401 400 | endmodule\n 0 400 400   \n 0 400 400   // SCE_V_PORT_CONNECT {24}\n 2 400 401 + mod m1(\n 0 401 401 |   .clk(clk),\n 0 401 401 |   .q(q),\n 0 401 401 |   .reset(reset)\n 0 401 400 | );\n 0 400   0   "
  },
  {
    "path": "test/examples/verilog/AllStyles.vh.styled",
    "content": "{2}// Examples drawn from https://verilogams.com/refman/basics/index.html\n{0}\n{2}// SCE_V_DEFAULT {0}\n{0}\n{1}/*\n * SCE_V_COMMENT {1}\n */{0}\n\n{2}// SCE_V_COMMENTLINE {2}\n// multiple\n// comment lines\n// are folded\n{0}\n{2}//{ explicit folds\n//  are folded,\n//} too\n{0}\n{3}//! SCE_V_COMMENTLINEBANG {3}\n//! multiple\n//! bang comments\n//! are folded\n{0}\n{2}// SCE_V_NUMBER {4}\n{4}1'b0{0}\n{4}8'hx{0}\n{4}8'hfffx{0}\n{4}12'hfx{0}\n{4}64'o0{0}\n{4}0x7f{0}\n{4}0o23{0}\n{4}0b1011{0}\n{4}42_839{0}\n{4}0.1{0}\n{4}1.3u{0}\n{4}5.46K{0}\n{4}1.2E12{0}\n{4}1.30e{10}-{4}2{0}\n{4}236.123_763e{10}-{4}12{0}\n\n{2}// SCE_V_WORD {5}\n{5}always{0}\n\n{2}// SCE_V_STRING {6}\n{6}\"\\tsome\\ttext\\r\\n\"{0}\n\n{2}// SCE_V_WORD2 {7}\n{7}special{0}\n\n{2}// SCE_V_WORD3 {8}\n{8}$async$and$array{0}\n\n{2}// SCE_V_PREPROCESSOR {9}\n{9}`define{0} {11}__VAMS_ENABLE__{0}\n{9}`ifdef{0} {11}__VAMS_ENABLE__{0}\n    {5}parameter{0} {5}integer{0} {11}del{0} {10}={0} {4}1{0} {11}from{0} {10}[{4}1{10}:{4}100{10}];{0}\n{9}`else{64}\n    {69}parameter{64} {75}del{64} {74}={64} {68}1{74};{64}\n{9}`endif{0}\n\n{2}// SCE_V_OPERATOR {10}\n{10}+-/=!@#%^&*()[]{}<|>~{0}\n\n{2}// SCE_V_IDENTIFIER {11}\n{11}q{0}\n{11}x$z{0}\n{11}\\my_var{0}\n{11}\\/x1/n1{0}\n{11}\\\\x1\\n1{0}\n{11}\\{a,b}{0}\n{11}\\V(p,n){0}\n\n{2}// SCE_V_STRINGEOL {12}\n{12}\"\\n\n{0}\n{2}// SCE_V_USER {19}\n{19}my_var{0}\n\n{2}// SCE_V_COMMENT_WORD {20}\n// {20}TODO{2} write a comment\n{0}\n{5}module{0} {11}mod{10}({11}clk{10},{0} {11}q{10},{0} {11}reset{10}){0} {2}// folded when fold.verilog.flags=1\n// SCE_V_INPUT {21}\n{0}  {21}input{0} {21}clk{10};{0}\n\n{2}// SCE_V_OUTPUT {22}\n{0}  {22}output{0} {22}q{10};{0}\n\n{2}// SCE_V_INOUT {23}\n{0}  {23}inout{0} {23}reset{10};{0}\n{5}endmodule{0}\n\n{2}// SCE_V_PORT_CONNECT {24}\n{11}mod{0} {11}m1{10}({0}\n  {10}.{24}clk{10}({11}clk{10}),{0}\n  {10}.{24}q{10}({11}q{10}),{0}\n  {10}.{24}reset{10}({11}reset{10}){0}\n{10});{0}\n"
  },
  {
    "path": "test/examples/verilog/SciTE.properties",
    "content": "lexer.*.vh=verilog\n\nkeywords.*.vh= \\\nalways and assign automatic \\\nbegin buf bufif0 bufif1 \\\ncase casex casez cell cmos config \\\ndeassign default defparam design disable \\\nedge else end endcase endconfig endfunction endgenerate endmodule endprimitive endspecify endtable endtask event \\\nfor force forever fork function \\\ngenerate genvar \\\nhighz0 highz1 \\\nif ifnone incdir include initial inout input instance integer \\\njoin \\\nlarge liblist library localparam \\\nmacromodule medium module \\\nnand negedge nmos nor noshowcancelled not notif0 notif1 \\\nor output \\\nparameter pmos posedge primitive pull0 pull1 pulldown pullup pulsestyle_ondetect pulsestyle_onevent \\\nrcmos real realtime reg release repeat rnmos rpmos rtran rtranif0 rtranif1 \\\nscalared showcancelled signed small specify specparam strong0 strong1 supply0 supply1 \\\ntable task time tran tranif0 tranif1 tri tri0 tri1 triand trior trireg \\\nunsigned use uwire \\\nvectored \\\nwait wand weak0 weak1 while wire wor \\\nxnor xor\nkeywords2.*.vh=special\nkeywords3.*.vh= \\\n$async$and$array $async$and$plane $async$nand$array $async$nand$plane $async$nor$array $async$nor$plane $async$or$array $async$or$plane \\\n$bitstoreal \\\n$countdrivers \\\n$display $displayb $displayh $displayo \\\n$dist_chi_square $dist_erlang $dist_exponential $dist_normal $dist_poisson $dist_t $dist_uniform \\\n$dumpall $dumpfile $dumpflush $dumplimit $dumpoff $dumpon $dumpportsall $dumpportsflush $dumpportslimit $dumpportsoff $dumpportson $dumpvars \\\n$fclose $fdisplayh $fdisplay $fdisplayf $fdisplayb $feof $ferror $fflush $fgetc $fgets $finish $fmonitorb $fmonitor $fmonitorf $fmonitorh $fopen $fread $fscanf $fseek $fsscanf $fstrobe $fstrobebb $fstrobef $fstrobeh $ftel $fullskew $fwriteb $fwritef $fwriteh $fwrite \\\n$getpattern \\\n$history $hold \\\n$incsave $input $itor \\\n$key \\\n$list $log \\\n$monitorb $monitorh $monitoroff $monitoron $monitor $monitoro \\\n$nochange $nokey $nolog \\\n$period $printtimescale \\\n$q_add $q_exam $q_full $q_initialize $q_remove \\\n$random $readmemb $readmemh $readmemh $realtime $realtobits $recovery $recrem $removal $reset_count $reset $reset_value $restart $rewind $rtoi \\\n$save $scale $scope $sdf_annotate $setup $setuphold $sformat $showscopes $showvariables $showvars $signed $skew $sreadmemb $sreadmemh $stime $stop $strobeb $strobe $strobeh $strobeo $swriteb $swriteh $swriteo $swrite $sync$and$array $sync$and$plane $sync$nand$array $sync$nand$plane $sync$nor$array $sync$nor$plane $sync$or$array $sync$or$plane \\\n$test$plusargs $time $timeformat $timeskew \\\n$ungetc $unsigned \\\n$value$plusargs \\\n$width $writeb $writeh $write $writeo\nkeywords4.*.vh=my_var\nkeywords5.*.vh=synopsys parallel_case infer_mux TODO\n\nfold=1\nfold.compact=0\nfold.comment=1\nfold.preprocessor=1\nfold.at.else=1\nfold.verilog.flags=1  # fold module definitions\nlexer.verilog.track.preprocessor=1\nlexer.verilog.update.preprocessor=1\nlexer.verilog.portstyling=1\nlexer.verilog.fold.preprocessor.else=1\n"
  },
  {
    "path": "test/examples/vhdl/SciTE.properties",
    "content": "lexer.*.vhd=vhdl\nfold=1\n\n"
  },
  {
    "path": "test/examples/vhdl/x.vhd",
    "content": "library ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.std_logic_arith.all;\n\nentity x is\n    port(\n        rst  : in  std_logic;\n        clk  : in  std_logic;\n        d    : in  std_logic;\n        q    : out std_logic_vector;\n        a, b : in  std_logic;\n        v    : out std_logic\n    );\nend x;\n\narchitecture behavioral of x is\n    signal q_i : std_logic_vector(q'range);\nbegin\n\n    v\t<= a when b = '1' else '0';\n\n    gen: for j in q'low to q'high generate\n        gen_first: if j = q'low generate\n            variable foo : boolean := false;\n        begin\n            stage1: process (rst, clk) begin\n                if rst = '1' then\n                    q_i(j) <= '0';\n                elsif rising_edge(clk) then\n                    q_i(j) <= d;\n                    case a is\n                    when 1 =>\n                    when 2 =>\n                    when others =>\n                    end case;\n                end if;\n            end process;\n        else generate\n            stages: process (rst, clk)\n            begin\n                if rst = '1' then\n                    q_i(j) <= '0';\n                elsif rising_edge(clk) then\n                    for u in 0 to 7 loop\n                        q_i(j) <= q_i(j - 1);\n                    end loop;\n                end if;\n            end process;\n        end generate;\n    end generate;\n\n    L: case expression generate\n    when choice1 =>\n    when choice2 =>\n    end generate L;\n\nend behavioral;\n"
  },
  {
    "path": "test/examples/vhdl/x.vhd.folded",
    "content": " 0 400 400   library ieee;\n 0 400 400   use ieee.std_logic_1164.all;\n 0 400 400   use ieee.std_logic_arith.all;\n 1 400 400   \n 2 400 401 + entity x is\n 2 401 402 +     port(\n 0 402 402 |         rst  : in  std_logic;\n 0 402 402 |         clk  : in  std_logic;\n 0 402 402 |         d    : in  std_logic;\n 0 402 402 |         q    : out std_logic_vector;\n 0 402 402 |         a, b : in  std_logic;\n 0 402 402 |         v    : out std_logic\n 0 402 401 |     );\n 0 401 400 | end x;\n 1 400 400   \n 2 400 401 + architecture behavioral of x is\n 0 401 401 |     signal q_i : std_logic_vector(q'range);\n 2 400 401 + begin\n 1 401 401 | \n 0 401 401 |     v\t<= a when b = '1' else '0';\n 1 401 401 | \n 2 401 402 +     gen: for j in q'low to q'high generate\n 2 402 403 +         gen_first: if j = q'low generate\n 0 403 403 |             variable foo : boolean := false;\n 2 402 403 +         begin\n 2 403 404 +             stage1: process (rst, clk) begin\n 2 404 405 +                 if rst = '1' then\n 0 405 405 |                     q_i(j) <= '0';\n 2 404 405 +                 elsif rising_edge(clk) then\n 0 405 405 |                     q_i(j) <= d;\n 2 405 406 +                     case a is\n 0 406 406 |                     when 1 =>\n 0 406 406 |                     when 2 =>\n 0 406 406 |                     when others =>\n 0 406 405 |                     end case;\n 0 405 404 |                 end if;\n 0 404 403 |             end process;\n 2 402 403 +         else generate\n 2 403 404 +             stages: process (rst, clk)\n 0 404 404 |             begin\n 2 404 405 +                 if rst = '1' then\n 0 405 405 |                     q_i(j) <= '0';\n 2 404 405 +                 elsif rising_edge(clk) then\n 2 405 406 +                     for u in 0 to 7 loop\n 0 406 406 |                         q_i(j) <= q_i(j - 1);\n 0 406 405 |                     end loop;\n 0 405 404 |                 end if;\n 0 404 403 |             end process;\n 0 403 402 |         end generate;\n 0 402 401 |     end generate;\n 1 401 401 | \n 2 401 402 +     L: case expression generate\n 0 402 402 |     when choice1 =>\n 0 402 402 |     when choice2 =>\n 0 402 401 |     end generate L;\n 1 401 401 | \n 0 401 400 | end behavioral;\n 0 400   0   "
  },
  {
    "path": "test/examples/vhdl/x.vhd.styled",
    "content": "{6}library{0} {6}ieee{5};{0}\n{6}use{0} {6}ieee{5}.{6}std_logic_1164{5}.{6}all{5};{0}\n{6}use{0} {6}ieee{5}.{6}std_logic_arith{5}.{6}all{5};{0}\n\n{6}entity{0} {6}x{0} {6}is{0}\n    {6}port{5}({0}\n        {6}rst{0}  {5}:{0} {6}in{0}  {6}std_logic{5};{0}\n        {6}clk{0}  {5}:{0} {6}in{0}  {6}std_logic{5};{0}\n        {6}d{0}    {5}:{0} {6}in{0}  {6}std_logic{5};{0}\n        {6}q{0}    {5}:{0} {6}out{0} {6}std_logic_vector{5};{0}\n        {6}a{5},{0} {6}b{0} {5}:{0} {6}in{0}  {6}std_logic{5};{0}\n        {6}v{0}    {5}:{0} {6}out{0} {6}std_logic{0}\n    {5});{0}\n{6}end{0} {6}x{5};{0}\n\n{6}architecture{0} {6}behavioral{0} {6}of{0} {6}x{0} {6}is{0}\n    {6}signal{0} {6}q_i{0} {5}:{0} {6}std_logic_vector{5}({6}q{0}'{6}range{5});{0}\n{6}begin{0}\n\n    {6}v{0}\t{5}<={0} {6}a{0} {6}when{0} {6}b{0} {5}={0} {4}'1'{0} {6}else{0} {4}'0'{5};{0}\n\n    {6}gen{5}:{0} {6}for{0} {6}j{0} {6}in{0} {6}q{0}'{6}low{0} {6}to{0} {6}q{0}'{6}high{0} {6}generate{0}\n        {6}gen_first{5}:{0} {6}if{0} {6}j{0} {5}={0} {6}q{0}'{6}low{0} {6}generate{0}\n            {6}variable{0} {6}foo{0} {5}:{0} {6}boolean{0} {5}:={0} {6}false{5};{0}\n        {6}begin{0}\n            {6}stage1{5}:{0} {6}process{0} {5}({6}rst{5},{0} {6}clk{5}){0} {6}begin{0}\n                {6}if{0} {6}rst{0} {5}={0} {4}'1'{0} {6}then{0}\n                    {6}q_i{5}({6}j{5}){0} {5}<={0} {4}'0'{5};{0}\n                {6}elsif{0} {6}rising_edge{5}({6}clk{5}){0} {6}then{0}\n                    {6}q_i{5}({6}j{5}){0} {5}<={0} {6}d{5};{0}\n                    {6}case{0} {6}a{0} {6}is{0}\n                    {6}when{0} {3}1{0} {5}=>{0}\n                    {6}when{0} {3}2{0} {5}=>{0}\n                    {6}when{0} {6}others{0} {5}=>{0}\n                    {6}end{0} {6}case{5};{0}\n                {6}end{0} {6}if{5};{0}\n            {6}end{0} {6}process{5};{0}\n        {6}else{0} {6}generate{0}\n            {6}stages{5}:{0} {6}process{0} {5}({6}rst{5},{0} {6}clk{5}){0}\n            {6}begin{0}\n                {6}if{0} {6}rst{0} {5}={0} {4}'1'{0} {6}then{0}\n                    {6}q_i{5}({6}j{5}){0} {5}<={0} {4}'0'{5};{0}\n                {6}elsif{0} {6}rising_edge{5}({6}clk{5}){0} {6}then{0}\n                    {6}for{0} {6}u{0} {6}in{0} {3}0{0} {6}to{0} {3}7{0} {6}loop{0}\n                        {6}q_i{5}({6}j{5}){0} {5}<={0} {6}q_i{5}({6}j{0} {5}-{0} {3}1{5});{0}\n                    {6}end{0} {6}loop{5};{0}\n                {6}end{0} {6}if{5};{0}\n            {6}end{0} {6}process{5};{0}\n        {6}end{0} {6}generate{5};{0}\n    {6}end{0} {6}generate{5};{0}\n\n    {6}L{5}:{0} {6}case{0} {6}expression{0} {6}generate{0}\n    {6}when{0} {6}choice1{0} {5}=>{0}\n    {6}when{0} {6}choice2{0} {5}=>{0}\n    {6}end{0} {6}generate{0} {6}L{5};{0}\n\n{6}end{0} {6}behavioral{5};{0}\n"
  },
  {
    "path": "test/examples/visualprolog/AllStyles.pl",
    "content": "% SCE_VISUALPROLOG_KEY_MAJOR (1)\n% No keywords in ISO/SWI-Prolog\ngoal\n\n% SCE_VISUALPROLOG_KEY_MINOR (2)\n% No minor keywords in ISO/SWI-Prolog\nprocedure\n\n% SCE_VISUALPROLOG_KEY_DIRECTIVE (3)\n% No directives in ISO/SWI-Prolog\n#include\n\n% SCE_VISUALPROLOG_COMMENT_BLOCK (4)\n/**\n   SCE_VISUALPROLOG_COMMENT_KEY (6)\n   @detail\n   SCE_VISUALPROLOG_COMMENT_KEY_ERROR (7)\n   @unknown\n /* SCE_VISUALPROLOG_IDENTIFIER (8)\n    SCE_VISUALPROLOG_VARIABLE (9)\n    SCE_VISUALPROLOG_ANONYMOUS (10)\n    SCE_VISUALPROLOG_NUMBER (11)\n    SCE_VISUALPROLOG_OPERATOR (12) */ */\nsingleton -->\n    [S],\n    {\n        string_lower(S, L),\n        atom_codes(L, Bytes),\n        sort(0, @=<, Bytes, [95, _discard])\n    }.\n\n% SCE_VISUALPROLOG_COMMENT_LINE (5)\n% comment line\n\n% SCE_VISUALPROLOG_STRING_QUOTE (16)\n\"\"\n\n% SCE_VISUALPROLOG_STRING (20)\n\"string\"\n'string'\n\n% ISO Prolog back-quoted string\n`string`\n\n% SCE_VISUALPROLOG_STRING_ESCAPE (17)\n\"\\n\"\n'\\uAB12'\n\n% SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18)\n\"\\ \"\n\"open string\n\n% Not implemented for ISO/SWI-Prolog:\n@\"verbatim string\"\n@[<div class=\"test\">]\n\n% SCE_VISUALPROLOG_STRING_EOL (22)\n@#multi-line\n  verbatim\n  string#\n\n% SCE_VISUALPROLOG_EMBEDDED (23)\n[| |]\n% SCE_VISUALPROLOG_PLACEHOLDER (24)\n{| |}:test\n"
  },
  {
    "path": "test/examples/visualprolog/AllStyles.pl.folded",
    "content": " 0 400 400   % SCE_VISUALPROLOG_KEY_MAJOR (1)\n 0 400 400   % No keywords in ISO/SWI-Prolog\n 0 400 400   goal\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_KEY_MINOR (2)\n 0 400 400   % No minor keywords in ISO/SWI-Prolog\n 0 400 400   procedure\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_KEY_DIRECTIVE (3)\n 0 400 400   % No directives in ISO/SWI-Prolog\n 0 400 400   #include\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_COMMENT_BLOCK (4)\n 0 400 400   /**\n 0 400 400      SCE_VISUALPROLOG_COMMENT_KEY (6)\n 0 400 400      @detail\n 0 400 400      SCE_VISUALPROLOG_COMMENT_KEY_ERROR (7)\n 0 400 400      @unknown\n 0 400 400    /* SCE_VISUALPROLOG_IDENTIFIER (8)\n 0 400 400       SCE_VISUALPROLOG_VARIABLE (9)\n 0 400 400       SCE_VISUALPROLOG_ANONYMOUS (10)\n 0 400 400       SCE_VISUALPROLOG_NUMBER (11)\n 0 400 400       SCE_VISUALPROLOG_OPERATOR (12) */ */\n 0 400 400   singleton -->\n 0 400 400       [S],\n 2 400 401 +     {\n 0 401 401 |         string_lower(S, L),\n 0 401 401 |         atom_codes(L, Bytes),\n 0 401 401 |         sort(0, @=<, Bytes, [95, _discard])\n 0 401 400 |     }.\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_COMMENT_LINE (5)\n 0 400 400   % comment line\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING_QUOTE (16)\n 0 400 400   \"\"\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING (20)\n 0 400 400   \"string\"\n 0 400 400   'string'\n 0 400 400   \n 0 400 400   % ISO Prolog back-quoted string\n 0 400 400   `string`\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING_ESCAPE (17)\n 0 400 400   \"\\n\"\n 0 400 400   '\\uAB12'\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18)\n 0 400 400   \"\\ \"\n 0 400 400   \"open string\n 0 400 400   \n 0 400 400   % Not implemented for ISO/SWI-Prolog:\n 0 400 400   @\"verbatim string\"\n 0 400 400   @[<div class=\"test\">]\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING_EOL (22)\n 0 400 400   @#multi-line\n 0 400 400     verbatim\n 0 400 400     string#\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_EMBEDDED (23)\n 0 400 400   [| |]\n 0 400 400   % SCE_VISUALPROLOG_PLACEHOLDER (24)\n 0 400 400   {| |}:test\n 1 400 400   "
  },
  {
    "path": "test/examples/visualprolog/AllStyles.pl.styled",
    "content": "{5}% SCE_VISUALPROLOG_KEY_MAJOR (1){0}\n{5}% No keywords in ISO/SWI-Prolog{0}\n{1}goal{0}\n\n{5}% SCE_VISUALPROLOG_KEY_MINOR (2){0}\n{5}% No minor keywords in ISO/SWI-Prolog{0}\n{2}procedure{0}\n\n{5}% SCE_VISUALPROLOG_KEY_DIRECTIVE (3){0}\n{5}% No directives in ISO/SWI-Prolog{0}\n{3}#include{0}\n\n{5}% SCE_VISUALPROLOG_COMMENT_BLOCK (4){0}\n{4}/**\n   SCE_VISUALPROLOG_COMMENT_KEY (6)\n   {6}@detail{4}\n   SCE_VISUALPROLOG_COMMENT_KEY_ERROR (7)\n   {7}@unknown{4}\n /* SCE_VISUALPROLOG_IDENTIFIER (8)\n    SCE_VISUALPROLOG_VARIABLE (9)\n    SCE_VISUALPROLOG_ANONYMOUS (10)\n    SCE_VISUALPROLOG_NUMBER (11)\n    SCE_VISUALPROLOG_OPERATOR (12) */ */{0}\n{8}singleton{0} {12}-->{0}\n    {12}[{9}S{12}],{0}\n    {12}{{0}\n        {1}string_lower{12}({9}S{12},{0} {9}L{12}),{0}\n        {1}atom_codes{12}({9}L{12},{0} {9}Bytes{12}),{0}\n        {1}sort{12}({11}0{12},{0} {12}@=<,{0} {9}Bytes{12},{0} {12}[{11}95{12},{0} {10}_discard{12}]){0}\n    {12}}.{0}\n\n{5}% SCE_VISUALPROLOG_COMMENT_LINE (5){0}\n{5}% comment line{0}\n\n{5}% SCE_VISUALPROLOG_STRING_QUOTE (16){0}\n{16}\"\"{0}\n\n{5}% SCE_VISUALPROLOG_STRING (20){0}\n{16}\"{20}string{16}\"{0}\n{16}'{20}string{16}'{0}\n\n{5}% ISO Prolog back-quoted string{0}\n{16}`{20}string{16}`{0}\n\n{5}% SCE_VISUALPROLOG_STRING_ESCAPE (17){0}\n{16}\"{17}\\n{16}\"{0}\n{16}'{17}\\uAB12{16}'{0}\n\n{5}% SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18){0}\n{16}\"{18}\\ {16}\"{0}\n{16}\"{20}open string{18}\n{0}\n{5}% Not implemented for ISO/SWI-Prolog:{0}\n{12}@{16}\"{20}verbatim string{16}\"{0}\n{12}@[<{2}div{0} {1}class{12}={16}\"{20}test{16}\"{12}>]{0}\n\n{5}% SCE_VISUALPROLOG_STRING_EOL (22){0}\n{12}@{8}#multi{12}-{8}line{0}\n  {8}verbatim{0}\n  {8}string#{0}\n\n{5}% SCE_VISUALPROLOG_EMBEDDED (23){0}\n{23}[| |]{0}\n{5}% SCE_VISUALPROLOG_PLACEHOLDER (24){0}\n{24}{|{0} {24}|}:test{0}\n"
  },
  {
    "path": "test/examples/visualprolog/AllStyles.pro",
    "content": "% SCE_VISUALPROLOG_KEY_MAJOR (1)\ngoal\n\n% SCE_VISUALPROLOG_KEY_MINOR (2)\nprocedure\n\n% SCE_VISUALPROLOG_KEY_DIRECTIVE (3)\n#include\n\n% SCE_VISUALPROLOG_COMMENT_BLOCK (4)\n/**\n   SCE_VISUALPROLOG_COMMENT_KEY (6)\n   @detail\n   SCE_VISUALPROLOG_COMMENT_KEY_ERROR (7)\n   @unknown\n /* SCE_VISUALPROLOG_IDENTIFIER (8)\n    SCE_VISUALPROLOG_VARIABLE (9)\n    SCE_VISUALPROLOG_ANONYMOUS (10)\n    SCE_VISUALPROLOG_NUMBER (11)\n    SCE_VISUALPROLOG_OPERATOR (12) */ */\nlambda = {\n  (A) = { (B, _discard) = A*B+1 }\n}.\n\n% SCE_VISUALPROLOG_COMMENT_LINE (5)\n% comment line\n\n% SCE_VISUALPROLOG_STRING_QUOTE (16)\n\"\"\n\n% SCE_VISUALPROLOG_STRING (20)\n\"string\"\n'string'\n@\"verbatim string\"\n@[<div class=\"test\">]\n\n% SCE_VISUALPROLOG_STRING_ESCAPE (17)\n\"\\n\"\n'\\uAB12'\n\n% SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18)\n\"\\ \"\n\"open string\n\n% SCE_VISUALPROLOG_STRING_EOL (22)\n@#multi-line\n  verbatim\n  string#\n\n% SCE_VISUALPROLOG_EMBEDDED (23)\n[| |]\n% SCE_VISUALPROLOG_PLACEHOLDER (24)\n{| |}:test\n% line state & nesting\n[|\n    {|\n        /*\n            % /* \n            */ \n        % */\n        [|\n            {|\n                @!string!\n                %\n                /*\n                */\n            |}\n        |]\n    |}\n|]\n"
  },
  {
    "path": "test/examples/visualprolog/AllStyles.pro.folded",
    "content": " 0 400 400   % SCE_VISUALPROLOG_KEY_MAJOR (1)\n 0 400 400   goal\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_KEY_MINOR (2)\n 0 400 400   procedure\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_KEY_DIRECTIVE (3)\n 0 400 400   #include\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_COMMENT_BLOCK (4)\n 0 400 400   /**\n 0 400 400      SCE_VISUALPROLOG_COMMENT_KEY (6)\n 0 400 400      @detail\n 0 400 400      SCE_VISUALPROLOG_COMMENT_KEY_ERROR (7)\n 0 400 400      @unknown\n 0 400 400    /* SCE_VISUALPROLOG_IDENTIFIER (8)\n 0 400 400       SCE_VISUALPROLOG_VARIABLE (9)\n 0 400 400       SCE_VISUALPROLOG_ANONYMOUS (10)\n 0 400 400       SCE_VISUALPROLOG_NUMBER (11)\n 0 400 400       SCE_VISUALPROLOG_OPERATOR (12) */ */\n 2 400 401 + lambda = {\n 0 401 401 |   (A) = { (B, _discard) = A*B+1 }\n 0 401 400 | }.\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_COMMENT_LINE (5)\n 0 400 400   % comment line\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING_QUOTE (16)\n 0 400 400   \"\"\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING (20)\n 0 400 400   \"string\"\n 0 400 400   'string'\n 0 400 400   @\"verbatim string\"\n 0 400 400   @[<div class=\"test\">]\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING_ESCAPE (17)\n 0 400 400   \"\\n\"\n 0 400 400   '\\uAB12'\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18)\n 0 400 400   \"\\ \"\n 0 400 400   \"open string\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_STRING_EOL (22)\n 0 400 400   @#multi-line\n 0 400 400     verbatim\n 0 400 400     string#\n 0 400 400   \n 0 400 400   % SCE_VISUALPROLOG_EMBEDDED (23)\n 0 400 400   [| |]\n 0 400 400   % SCE_VISUALPROLOG_PLACEHOLDER (24)\n 0 400 400   {| |}:test\n 0 400 400   % line state & nesting\n 0 400 400   [|\n 0 400 400       {|\n 0 400 400           /*\n 0 400 400               % /* \n 0 400 400               */ \n 0 400 400           % */\n 0 400 400           [|\n 0 400 400               {|\n 0 400 400                   @!string!\n 0 400 400                   %\n 0 400 400                   /*\n 0 400 400                   */\n 0 400 400               |}\n 0 400 400           |]\n 0 400 400       |}\n 0 400 400   |]\n 1 400 400   "
  },
  {
    "path": "test/examples/visualprolog/AllStyles.pro.styled",
    "content": "{5}% SCE_VISUALPROLOG_KEY_MAJOR (1){0}\n{1}goal{0}\n\n{5}% SCE_VISUALPROLOG_KEY_MINOR (2){0}\n{2}procedure{0}\n\n{5}% SCE_VISUALPROLOG_KEY_DIRECTIVE (3){0}\n{3}#include{0}\n\n{5}% SCE_VISUALPROLOG_COMMENT_BLOCK (4){0}\n{4}/**\n   SCE_VISUALPROLOG_COMMENT_KEY (6)\n   {6}@detail{4}\n   SCE_VISUALPROLOG_COMMENT_KEY_ERROR (7)\n   {7}@unknown{4}\n /* SCE_VISUALPROLOG_IDENTIFIER (8)\n    SCE_VISUALPROLOG_VARIABLE (9)\n    SCE_VISUALPROLOG_ANONYMOUS (10)\n    SCE_VISUALPROLOG_NUMBER (11)\n    SCE_VISUALPROLOG_OPERATOR (12) */ */{0}\n{8}lambda{0} {12}={0} {12}{{0}\n  {12}({9}A{12}){0} {12}={0} {12}{{0} {12}({9}B{12},{0} {10}_discard{12}){0} {12}={0} {9}A{12}*{9}B{12}+{11}1{0} {12}}{0}\n{12}}.{0}\n\n{5}% SCE_VISUALPROLOG_COMMENT_LINE (5){0}\n{5}% comment line{0}\n\n{5}% SCE_VISUALPROLOG_STRING_QUOTE (16){0}\n{16}\"\"{0}\n\n{5}% SCE_VISUALPROLOG_STRING (20){0}\n{16}\"{20}string{16}\"{0}\n{16}'{20}string{16}'{0}\n{16}@\"{20}verbatim string{16}\"{0}\n{16}@[{20}<div class=\"test\">{16}]{0}\n\n{5}% SCE_VISUALPROLOG_STRING_ESCAPE (17){0}\n{16}\"{17}\\n{16}\"{0}\n{16}'{17}\\uAB12{16}'{0}\n\n{5}% SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18){0}\n{16}\"{18}\\ {16}\"{0}\n{16}\"{20}open string{18}\n{0}\n{5}% SCE_VISUALPROLOG_STRING_EOL (22){0}\n{16}@#{20}multi-line{22}\n{20}  verbatim{22}\n{20}  string{16}#{0}\n\n{5}% SCE_VISUALPROLOG_EMBEDDED (23){0}\n{23}[| |]{0}\n{5}% SCE_VISUALPROLOG_PLACEHOLDER (24){0}\n{24}{|{0} {24}|}:test{0}\n{5}% line state & nesting{0}\n{23}[|\n    {24}{|{0}\n        {4}/*\n            % /* \n            */ \n        % */{0}\n        {23}[|\n            {24}{|{0}\n                {16}@!{20}string{16}!{0}\n                {5}%{0}\n                {4}/*\n                */{0}\n            {24}|}{23}\n        |]{0}\n    {24}|}{23}\n|]{0}\n"
  },
  {
    "path": "test/examples/visualprolog/SciTE.properties",
    "content": "lexer.*.pro;*.pl=visualprolog\nfold=1\n\n# Visual Prolog properties\nmatch AllStyles.pro\n  lexer.visualprolog.verbatim.strings=1\n  lexer.visualprolog.backquoted.strings=0\n\n# ISO/SWI-Prolog properties\nmatch AllStyles.pl\n  lexer.visualprolog.verbatim.strings=0\n  lexer.visualprolog.backquoted.strings=1\n\n# major keywords\nkeywords.*.pro;*.pl=goal namespace interface class implement open inherits supports resolve delegate \\\nmonitor constants domains predicates constructors properties clauses facts string_lower atom_codes sort\n\n# minor keywords\nkeywords2.*.pro;*.pl=any binary binaryNonAtomic boolean char compareResult factDB guard handle integer64 \\\nintegerNative language null pointer real real32 stdcall string8 symbol apicall c thiscall prolog \\\ndigits if then elseif else endif foreach do try catch finally erroneous failure procedure determ multi \\\nnondeterm anyflow and or externally from div mod rem quot in orelse otherwise unsigned unsigned64 \\\nunsignedNative\n\n# directives\nkeywords3.*.pro;*.pl=include bininclude requires orrequires error message export externally options\n\n# documentation keywords\nkeywords4.*.pro;*.pl=short detail end exception withdomain\n"
  },
  {
    "path": "test/examples/x12/SciTE.properties",
    "content": "lexer.*.x12=x12\nfold=1\n\n"
  },
  {
    "path": "test/examples/x12/empty.x12",
    "content": "ISA*00*          *00*          *01*0011223456     *01*999999999      *950120*0147*U*00300*000000007*0*P*~\nIEA*2*000000007\n"
  },
  {
    "path": "test/examples/x12/empty.x12.folded",
    "content": " 2 400   0 + ISA*00*          *00*          *01*0011223456     *01*999999999      *950120*0147*U*00300*000000007*0*P*~\n 0 401   0 | IEA*2*000000007\n 0 400   0   "
  },
  {
    "path": "test/examples/x12/empty.x12.styled",
    "content": "{2}ISA{7}*{0}00{7}*{0}          {7}*{0}00{7}*{0}          {7}*{0}01{7}*{0}0011223456     {7}*{0}01{7}*{0}999999999      {7}*{0}950120{7}*{0}0147{7}*{0}U{7}*{0}00300{7}*{0}000000007{7}*{0}0{7}*{0}P{7}*{8}~{6}\n{2}IEA{7}*{0}2{7}*{0}000000007{6}\n"
  },
  {
    "path": "test/examples/x12/x.x12",
    "content": "ISA*00*          *00*          *01*0011223456     *01*999999999      *950120*0147*U*00300*000000007*0*P*~\nGS*PO*0011223456*999999999*950120*0147*5*X*003040\nST*850*000000001\nBEG*00*SA*95018017***950118\nN1*SE*UNIVERSAL WIDGETS\nN3*375 PLYMOUTH PARK*SUITE 205\nN4*IRVING*TX*75061\nPO1*001*4*EA*330*TE*IN*525*VN*X357-W2\nPID*F****HIGH PERFORMANCE WIDGET\nSCH*4*EA****002*950322\nCTT*1*1\nSE*10*000000001\nST*850*000000002\nBEG*00*SA*95018017***950118\nN1*SE*UNIVERSAL WIDGETS\nPID*F****HIGH PERFORMANCE WIDGET\nSCH*4*EA****002*950322\nCTT*1*1\nSE*7*000000002\nGE*2*5\nGS*PO*0011223456*999999999*950120*0147*6*X*003040\nST*850*000000003\nBEG*00*SA*95018017***950118\nN1*SE*UNIVERSAL WIDGETS\nN3*375 PLYMOUTH PARK*SUITE 205\nN4*IRVING*TX*75061\nPO1*001*4*EA*330*TE*IN*525*VN*X357-W2\nPID*F****HIGH PERFORMANCE WIDGET\nSCH*4*EA****002*950322\nCTT*1*1\nSE*10*000000003\nGE*1*6\nIEA*2*000000007\n"
  },
  {
    "path": "test/examples/x12/x.x12.folded",
    "content": " 2 400   0 + ISA*00*          *00*          *01*0011223456     *01*999999999      *950120*0147*U*00300*000000007*0*P*~\n 2 401   0 + GS*PO*0011223456*999999999*950120*0147*5*X*003040\n 2 402   0 + ST*850*000000001\n 0 403   0 | BEG*00*SA*95018017***950118\n 0 403   0 | N1*SE*UNIVERSAL WIDGETS\n 0 403   0 | N3*375 PLYMOUTH PARK*SUITE 205\n 0 403   0 | N4*IRVING*TX*75061\n 0 403   0 | PO1*001*4*EA*330*TE*IN*525*VN*X357-W2\n 0 403   0 | PID*F****HIGH PERFORMANCE WIDGET\n 0 403   0 | SCH*4*EA****002*950322\n 0 403   0 | CTT*1*1\n 0 403   0 | SE*10*000000001\n 2 402   0 + ST*850*000000002\n 0 403   0 | BEG*00*SA*95018017***950118\n 0 403   0 | N1*SE*UNIVERSAL WIDGETS\n 0 403   0 | PID*F****HIGH PERFORMANCE WIDGET\n 0 403   0 | SCH*4*EA****002*950322\n 0 403   0 | CTT*1*1\n 0 403   0 | SE*7*000000002\n 0 402   0 | GE*2*5\n 2 401   0 + GS*PO*0011223456*999999999*950120*0147*6*X*003040\n 2 402   0 + ST*850*000000003\n 0 403   0 | BEG*00*SA*95018017***950118\n 0 403   0 | N1*SE*UNIVERSAL WIDGETS\n 0 403   0 | N3*375 PLYMOUTH PARK*SUITE 205\n 0 403   0 | N4*IRVING*TX*75061\n 0 403   0 | PO1*001*4*EA*330*TE*IN*525*VN*X357-W2\n 0 403   0 | PID*F****HIGH PERFORMANCE WIDGET\n 0 403   0 | SCH*4*EA****002*950322\n 0 403   0 | CTT*1*1\n 0 403   0 | SE*10*000000003\n 0 402   0 | GE*1*6\n 0 401   0 | IEA*2*000000007\n 0 400   0   "
  },
  {
    "path": "test/examples/x12/x.x12.styled",
    "content": "{2}ISA{7}*{0}00{7}*{0}          {7}*{0}00{7}*{0}          {7}*{0}01{7}*{0}0011223456     {7}*{0}01{7}*{0}999999999      {7}*{0}950120{7}*{0}0147{7}*{0}U{7}*{0}00300{7}*{0}000000007{7}*{0}0{7}*{0}P{7}*{8}~{6}\n{3}GS{7}*{0}PO{7}*{0}0011223456{7}*{0}999999999{7}*{0}950120{7}*{0}0147{7}*{0}5{7}*{0}X{7}*{0}003040{6}\n{4}ST{7}*{0}850{7}*{0}000000001{6}\n{5}BEG{7}*{0}00{7}*{0}SA{7}*{0}95018017{7}***{0}950118{6}\n{5}N1{7}*{0}SE{7}*{0}UNIVERSAL WIDGETS{6}\n{5}N3{7}*{0}375 PLYMOUTH PARK{7}*{0}SUITE 205{6}\n{5}N4{7}*{0}IRVING{7}*{0}TX{7}*{0}75061{6}\n{5}PO1{7}*{0}001{7}*{0}4{7}*{0}EA{7}*{0}330{7}*{0}TE{7}*{0}IN{7}*{0}525{7}*{0}VN{7}*{0}X357-W2{6}\n{5}PID{7}*{0}F{7}****{0}HIGH PERFORMANCE WIDGET{6}\n{5}SCH{7}*{0}4{7}*{0}EA{7}****{0}002{7}*{0}950322{6}\n{5}CTT{7}*{0}1{7}*{0}1{6}\n{4}SE{7}*{0}10{7}*{0}000000001{6}\n{4}ST{7}*{0}850{7}*{0}000000002{6}\n{5}BEG{7}*{0}00{7}*{0}SA{7}*{0}95018017{7}***{0}950118{6}\n{5}N1{7}*{0}SE{7}*{0}UNIVERSAL WIDGETS{6}\n{5}PID{7}*{0}F{7}****{0}HIGH PERFORMANCE WIDGET{6}\n{5}SCH{7}*{0}4{7}*{0}EA{7}****{0}002{7}*{0}950322{6}\n{5}CTT{7}*{0}1{7}*{0}1{6}\n{4}SE{7}*{0}7{7}*{0}000000002{6}\n{3}GE{7}*{0}2{7}*{0}5{6}\n{3}GS{7}*{0}PO{7}*{0}0011223456{7}*{0}999999999{7}*{0}950120{7}*{0}0147{7}*{0}6{7}*{0}X{7}*{0}003040{6}\n{4}ST{7}*{0}850{7}*{0}000000003{6}\n{5}BEG{7}*{0}00{7}*{0}SA{7}*{0}95018017{7}***{0}950118{6}\n{5}N1{7}*{0}SE{7}*{0}UNIVERSAL WIDGETS{6}\n{5}N3{7}*{0}375 PLYMOUTH PARK{7}*{0}SUITE 205{6}\n{5}N4{7}*{0}IRVING{7}*{0}TX{7}*{0}75061{6}\n{5}PO1{7}*{0}001{7}*{0}4{7}*{0}EA{7}*{0}330{7}*{0}TE{7}*{0}IN{7}*{0}525{7}*{0}VN{7}*{0}X357-W2{6}\n{5}PID{7}*{0}F{7}****{0}HIGH PERFORMANCE WIDGET{6}\n{5}SCH{7}*{0}4{7}*{0}EA{7}****{0}002{7}*{0}950322{6}\n{5}CTT{7}*{0}1{7}*{0}1{6}\n{4}SE{7}*{0}10{7}*{0}000000003{6}\n{3}GE{7}*{0}1{7}*{0}6{6}\n{2}IEA{7}*{0}2{7}*{0}000000007{6}\n"
  },
  {
    "path": "test/examples/yaml/326-textOverEmpty.yaml",
    "content": "# Failure case for issue #326\n# SCE_YAML_TEXT should extend over empty line\nmy_yaml_block: |+\n  This block is text\n\n  even if the line above is empty\n  these two text lines should also be highlighted as text.\n\n# End of example, should be the end of text rendering\n"
  },
  {
    "path": "test/examples/yaml/326-textOverEmpty.yaml.folded",
    "content": " 0 400   0   # Failure case for issue #326\n 0 400   0   # SCE_YAML_TEXT should extend over empty line\n 2 400   0 + my_yaml_block: |+\n 0 402   0 |   This block is text\n 1 402   0 | \n 0 402   0 |   even if the line above is empty\n 0 402   0 |   these two text lines should also be highlighted as text.\n 1 400   0   \n 0 400   0   # End of example, should be the end of text rendering\n 0 400   0   "
  },
  {
    "path": "test/examples/yaml/326-textOverEmpty.yaml.styled",
    "content": "{1}# Failure case for issue #326\n# SCE_YAML_TEXT should extend over empty line\n{2}my_yaml_block{9}:{0} |+\n{7}  This block is text\n{0}\n  even if the line above is empty\n  these two text lines should also be highlighted as text.\n\n{1}# End of example, should be the end of text rendering\n"
  },
  {
    "path": "test/examples/yaml/SciTE.properties",
    "content": "lexer.*.yaml=yaml\nkeywords.*.yaml=true false yes no\nfold=1\n"
  },
  {
    "path": "test/examples/yaml/longline.yaml",
    "content": "# makefile lexer previously used fixed 1024-byte line buffer that would treat text after that as new line\n\n# Long line with 1025 bytes last 2 bytes colored as default 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678912345678\n\n"
  },
  {
    "path": "test/examples/yaml/longline.yaml.folded",
    "content": " 0 400   0   # makefile lexer previously used fixed 1024-byte line buffer that would treat text after that as new line\n 1 400   0   \n 0 400   0   # Long line with 1025 bytes last 2 bytes colored as default 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678912345678\n 1 400   0   \n 0 400   0   "
  },
  {
    "path": "test/examples/yaml/longline.yaml.styled",
    "content": "{1}# makefile lexer previously used fixed 1024-byte line buffer that would treat text after that as new line\n{0}\n{1}# Long line with 1025 bytes last 2 bytes colored as default 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678912345678\n{0}\n"
  },
  {
    "path": "test/examples/yaml/x.yaml",
    "content": "# comment\n\nkey: value # comment\n\ncolon:in:key: value\n\nhanging_value:\n  value\n\n1: 1\n\ntrue: true\n"
  },
  {
    "path": "test/examples/yaml/x.yaml.folded",
    "content": " 0 400   0   # comment\n 1 400   0   \n 0 400   0   key: value # comment\n 1 400   0   \n 0 400   0   colon:in:key: value\n 1 400   0   \n 2 400   0 + hanging_value:\n 0 402   0 |   value\n 1 400   0   \n 0 400   0   1: 1\n 1 400   0   \n 0 400   0   true: true\n 0 400   0   "
  },
  {
    "path": "test/examples/yaml/x.yaml.styled",
    "content": "{1}# comment\n{0}\n{2}key{9}:{0} value {1}# comment\n{0}\n{2}colon:in:key{9}:{0} value\n\n{2}hanging_value{9}:{0}\n  value\n\n{2}1{9}:{4} 1\n{0}\n{2}true{9}:{3} true\n"
  },
  {
    "path": "test/examples/zig/AllStyles.zig",
    "content": "// coding:utf-8\n\n/// A structure for storing a timestamp, with nanosecond precision (this is a\n/// multiline doc comment).\nconst Timestamp = struct {\n    /// The number of seconds since the epoch (this is also a doc comment).\n    seconds: i64, // signed so we can represent pre-1970 (not a doc comment)\n    /// The number of nanoseconds past the second (doc comment again).\n    nanos: u32,\n\n    /// Returns a `Timestamp` struct representing the Unix epoch; that is, the\n    /// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too).\n    pub fn unixEpoch() Timestamp {\n        return Timestamp{\n            .seconds = 0,\n            .nanos = 0,\n        };\n    }\n};\n\n//! This module provides functions for retrieving the current date and\n//! time with varying degrees of precision and accuracy. It does not\n//! depend on libc, but will use functions from it if available.\n\nconst S = struct {\n    //! Top level comments are allowed inside a container other than a module,\n    //! but it is not very useful.  Currently, when producing the package\n    //! documentation, these comments are ignored.\n};\n\nconst std = @import(\"std\");\n\npub fn main() !void {\n    const stdout = std.io.getStdOut().writer();\n    try stdout.print(\"Hello, {s}!\\n\", .{\"world\"});\n}\n\n\n// Top-level declarations are order-independent:\nconst print = std.debug.print;\nconst std = @import(\"std\");\nconst os = std.os;\nconst assert = std.debug.assert;\n\npub fn main() void {\n    // integers\n    const one_plus_one: i32 = 1 + 1;\n    print(\"1 + 1 = {}\\n\", .{one_plus_one});\n\n    // floats\n    const seven_div_three: f32 = 7.0 / 3.0;\n    print(\"7.0 / 3.0 = {}\\n\", .{seven_div_three});\n\n    // boolean\n    print(\"{}\\n{}\\n{}\\n\", .{\n        true and false,\n        true or false,\n        !true,\n    });\n\n    // optional\n    var optional_value: ?[]const u8 = null;\n    assert(optional_value == null);\n\n    print(\"\\noptional 1\\ntype: {}\\nvalue: {?s}\\n\", .{\n        @TypeOf(optional_value), optional_value,\n    });\n\n    optional_value = \"hi\";\n    assert(optional_value != null);\n\n    print(\"\\noptional 2\\ntype: {}\\nvalue: {?s}\\n\", .{\n        @TypeOf(optional_value), optional_value,\n    });\n\n    // error union\n    var number_or_error: anyerror!i32 = error.ArgNotFound;\n\n    print(\"\\nerror union 1\\ntype: {}\\nvalue: {!}\\n\", .{\n        @TypeOf(number_or_error),\n        number_or_error,\n    });\n\n    number_or_error = 1234;\n\n    print(\"\\nerror union 2\\ntype: {}\\nvalue: {!}\\n\", .{\n        @TypeOf(number_or_error), number_or_error,\n    });\n}\n\nconst print = @import(\"std\").debug.print;\nconst mem = @import(\"std\").mem; // will be used to compare bytes\n\npub fn main() void {\n    const bytes = \"hello\\u{12345678}\";\n    print(\"{}\\n\", .{@TypeOf(bytes)}); // *const [5:0]u8\n    print(\"{d}\\n\", .{bytes.len}); // 5\n    print(\"{c}\\n\", .{bytes[1]}); // 'e'\n    print(\"{d}\\n\", .{bytes[5]}); // 0\n    print(\"{}\\n\", .{'e' == '\\x65'}); // true\n    print(\"{d}\\n\", .{'\\u{1f4a9}'}); // 128169\n    print(\"{d}\\n\", .{'💯'}); // 128175\n    print(\"{u}\\n\", .{'⚡'});\n    print(\"{}\\n\", .{mem.eql(u8, \"hello\", \"h\\x65llo\")}); // true\n    print(\"{}\\n\", .{mem.eql(u8, \"💯\", \"\\xf0\\x9f\\x92\\xaf\")}); // also true\n    const invalid_utf8 = \"\\xff\\xfe\"; // non-UTF-8 strings are possible with \\xNN notation.\n    print(\"0x{x}\\n\", .{invalid_utf8[1]}); // indexing them returns individual bytes...\n    print(\"0x{x}\\n\", .{\"💯\"[1]}); // ...as does indexing part-way through non-ASCII characters\n}\n\nconst hello_world_in_c =\n    \\\\#include <stdio.h>\n    \\\\\n    \\\\int main(int argc, char **argv) {\n    \\\\    printf(\"hello world\\n\");\n    \\\\    return 0;\n    \\\\}\n;\n\nconst std = @import(\"std\");\nconst assert = std.debug.assert;\n\nthreadlocal var x: i32 = 1234;\n\ntest \"thread local storage\" {\n    const thread1 = try std.Thread.spawn(.{}, testTls, .{});\n    const thread2 = try std.Thread.spawn(.{}, testTls, .{});\n    testTls();\n    thread1.join();\n    thread2.join();\n}\n\nfn testTls() void {\n    assert(x == 1234);\n    x += 1;\n    assert(x == 1235);\n}\n\nconst decimal_int = 98222;\nconst hex_int = 0xff;\nconst another_hex_int = 0xFF;\nconst octal_int = 0o755;\nconst binary_int = 0b11110000;\n\n// underscores may be placed between two digits as a visual separator\nconst one_billion = 1_000_000_000;\nconst binary_mask = 0b1_1111_1111;\nconst permissions = 0o7_5_5;\nconst big_address = 0xFF80_0000_0000_0000;\n\n\nconst floating_point = 123.0E+77;\nconst another_float = 123.0;\nconst yet_another = 123.0e+77;\n\nconst hex_floating_point = 0x103.70p-5;\nconst another_hex_float = 0x103.70;\nconst yet_another_hex_float = 0x103.70P-5;\n\n// underscores may be placed between two digits as a visual separator\nconst lightspeed = 299_792_458.000_000;\nconst nanosecond = 0.000_000_001;\nconst more_hex = 0x1234_5678.9ABC_CDEFp-10;\n\nconst Vec3 = struct {\n    x: f32,\n    y: f32,\n    z: f32,\n\n    pub fn init(x: f32, y: f32, z: f32) Vec3 {\n        return Vec3{\n            .x = x,\n            .y = y,\n            .z = z,\n        };\n    }\n\n    pub fn dot(self: Vec3, other: Vec3) f32 {\n        return self.x * other.x + self.y * other.y + self.z * other.z;\n    }\n};\n\nfn LinkedList(comptime T: type) type {\n    return struct {\n        pub const Node = struct {\n            prev: ?*Node,\n            next: ?*Node,\n            data: T,\n        };\n\n        first: ?*Node,\n        last: ?*Node,\n        len: usize,\n    };\n}\n\nconst Point = struct {\n    x: f32,\n    y: f32,\n};\n\n// Maybe we want to pass it to OpenGL so we want to be particular about\n// how the bytes are arranged.\nconst Point2 = packed struct {\n    x: f32,\n    y: f32,\n};\n\n\nconst std = @import(\"std\");\nconst expect = std.testing.expect;\n\nconst Color = enum {\n    auto,\n    off,\n    on,\n};\n\nconst std = @import(\"std\");\nconst builtin = @import(\"builtin\");\nconst expect = std.testing.expect;\n\ntest \"switch simple\" {\n    const a: u64 = 10;\n    const zz: u64 = 103;\n\n    // All branches of a switch expression must be able to be coerced to a\n    // common type.\n    //\n    // Branches cannot fallthrough. If fallthrough behavior is desired, combine\n    // the cases and use an if.\n    const b = switch (a) {\n        // Multiple cases can be combined via a ','\n        1, 2, 3 => 0,\n\n        // Ranges can be specified using the ... syntax. These are inclusive\n        // of both ends.\n        5...100 => 1,\n\n        // Branches can be arbitrarily complex.\n        101 => blk: {\n            const c: u64 = 5;\n            break :blk c * 2 + 1;\n        },\n\n        // Switching on arbitrary expressions is allowed as long as the\n        // expression is known at compile-time.\n        zz => zz,\n        blk: {\n            const d: u32 = 5;\n            const e: u32 = 100;\n            break :blk d + e;\n        } => 107,\n\n        // The else branch catches everything not already captured.\n        // Else branches are mandatory unless the entire range of values\n        // is handled.\n        else => 9,\n    };\n\n    try expect(b == 1);\n}\n\nfn charToDigit(c: u8) u8 {\n    return switch (c) {\n        '0'...'9' => c - '0',\n        'A'...'Z' => c - 'A' + 10,\n        'a'...'z' => c - 'a' + 10,\n        else => maxInt(u8),\n    };\n}\n\nconst optional_value: ?i32 = null;\n\n//! This module provides functions for retrieving the current date and\n//! time with varying degrees of precision and accuracy. It does not\n//! depend on libc, but will use functions from it if available.\n\nconst @\"identifier with spaces in it\" = 0xff;\nconst @\"1SmallStep4Man\" = 112358;\n\nconst c = @import(\"std\").c;\npub extern \"c\" fn @\"error\"() void;\npub extern \"c\" fn @\"fstat$INODE64\"(fd: c.fd_t, buf: *c.Stat) c_int;\n\nconst Color = enum {\n    red,\n    @\"really red\",\n};\nconst color: Color = .@\"really red\";\n\nconst s1 = \"Unterminated string\nconst s2 = 'Unterminated character\nconst s3 = @\"Unterminated identifier string\n"
  },
  {
    "path": "test/examples/zig/AllStyles.zig.folded",
    "content": " 0 400 400   // coding:utf-8\n 0 400 400   \n 2 400 401 + /// A structure for storing a timestamp, with nanosecond precision (this is a\n 0 401 400 | /// multiline doc comment).\n 2 400 401 + const Timestamp = struct {\n 0 401 401 |     /// The number of seconds since the epoch (this is also a doc comment).\n 0 401 401 |     seconds: i64, // signed so we can represent pre-1970 (not a doc comment)\n 0 401 401 |     /// The number of nanoseconds past the second (doc comment again).\n 0 401 401 |     nanos: u32,\n 0 401 401 | \n 2 401 402 +     /// Returns a `Timestamp` struct representing the Unix epoch; that is, the\n 0 402 401 |     /// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too).\n 2 401 402 +     pub fn unixEpoch() Timestamp {\n 2 402 403 +         return Timestamp{\n 0 403 403 |             .seconds = 0,\n 0 403 403 |             .nanos = 0,\n 0 403 402 |         };\n 0 402 401 |     }\n 0 401 400 | };\n 0 400 400   \n 2 400 401 + //! This module provides functions for retrieving the current date and\n 0 401 401 | //! time with varying degrees of precision and accuracy. It does not\n 0 401 400 | //! depend on libc, but will use functions from it if available.\n 0 400 400   \n 2 400 401 + const S = struct {\n 2 401 402 +     //! Top level comments are allowed inside a container other than a module,\n 0 402 402 |     //! but it is not very useful.  Currently, when producing the package\n 0 402 401 |     //! documentation, these comments are ignored.\n 0 401 400 | };\n 0 400 400   \n 0 400 400   const std = @import(\"std\");\n 0 400 400   \n 2 400 401 + pub fn main() !void {\n 0 401 401 |     const stdout = std.io.getStdOut().writer();\n 0 401 401 |     try stdout.print(\"Hello, {s}!\\n\", .{\"world\"});\n 0 401 400 | }\n 0 400 400   \n 0 400 400   \n 0 400 400   // Top-level declarations are order-independent:\n 0 400 400   const print = std.debug.print;\n 0 400 400   const std = @import(\"std\");\n 0 400 400   const os = std.os;\n 0 400 400   const assert = std.debug.assert;\n 0 400 400   \n 2 400 401 + pub fn main() void {\n 0 401 401 |     // integers\n 0 401 401 |     const one_plus_one: i32 = 1 + 1;\n 0 401 401 |     print(\"1 + 1 = {}\\n\", .{one_plus_one});\n 0 401 401 | \n 0 401 401 |     // floats\n 0 401 401 |     const seven_div_three: f32 = 7.0 / 3.0;\n 0 401 401 |     print(\"7.0 / 3.0 = {}\\n\", .{seven_div_three});\n 0 401 401 | \n 0 401 401 |     // boolean\n 2 401 403 +     print(\"{}\\n{}\\n{}\\n\", .{\n 0 403 403 |         true and false,\n 0 403 403 |         true or false,\n 0 403 403 |         !true,\n 0 403 401 |     });\n 0 401 401 | \n 0 401 401 |     // optional\n 0 401 401 |     var optional_value: ?[]const u8 = null;\n 0 401 401 |     assert(optional_value == null);\n 0 401 401 | \n 2 401 403 +     print(\"\\noptional 1\\ntype: {}\\nvalue: {?s}\\n\", .{\n 0 403 403 |         @TypeOf(optional_value), optional_value,\n 0 403 401 |     });\n 0 401 401 | \n 0 401 401 |     optional_value = \"hi\";\n 0 401 401 |     assert(optional_value != null);\n 0 401 401 | \n 2 401 403 +     print(\"\\noptional 2\\ntype: {}\\nvalue: {?s}\\n\", .{\n 0 403 403 |         @TypeOf(optional_value), optional_value,\n 0 403 401 |     });\n 0 401 401 | \n 0 401 401 |     // error union\n 0 401 401 |     var number_or_error: anyerror!i32 = error.ArgNotFound;\n 0 401 401 | \n 2 401 403 +     print(\"\\nerror union 1\\ntype: {}\\nvalue: {!}\\n\", .{\n 0 403 403 |         @TypeOf(number_or_error),\n 0 403 403 |         number_or_error,\n 0 403 401 |     });\n 0 401 401 | \n 0 401 401 |     number_or_error = 1234;\n 0 401 401 | \n 2 401 403 +     print(\"\\nerror union 2\\ntype: {}\\nvalue: {!}\\n\", .{\n 0 403 403 |         @TypeOf(number_or_error), number_or_error,\n 0 403 401 |     });\n 0 401 400 | }\n 0 400 400   \n 0 400 400   const print = @import(\"std\").debug.print;\n 0 400 400   const mem = @import(\"std\").mem; // will be used to compare bytes\n 0 400 400   \n 2 400 401 + pub fn main() void {\n 0 401 401 |     const bytes = \"hello\\u{12345678}\";\n 0 401 401 |     print(\"{}\\n\", .{@TypeOf(bytes)}); // *const [5:0]u8\n 0 401 401 |     print(\"{d}\\n\", .{bytes.len}); // 5\n 0 401 401 |     print(\"{c}\\n\", .{bytes[1]}); // 'e'\n 0 401 401 |     print(\"{d}\\n\", .{bytes[5]}); // 0\n 0 401 401 |     print(\"{}\\n\", .{'e' == '\\x65'}); // true\n 0 401 401 |     print(\"{d}\\n\", .{'\\u{1f4a9}'}); // 128169\n 0 401 401 |     print(\"{d}\\n\", .{'💯'}); // 128175\n 0 401 401 |     print(\"{u}\\n\", .{'⚡'});\n 0 401 401 |     print(\"{}\\n\", .{mem.eql(u8, \"hello\", \"h\\x65llo\")}); // true\n 0 401 401 |     print(\"{}\\n\", .{mem.eql(u8, \"💯\", \"\\xf0\\x9f\\x92\\xaf\")}); // also true\n 0 401 401 |     const invalid_utf8 = \"\\xff\\xfe\"; // non-UTF-8 strings are possible with \\xNN notation.\n 0 401 401 |     print(\"0x{x}\\n\", .{invalid_utf8[1]}); // indexing them returns individual bytes...\n 0 401 401 |     print(\"0x{x}\\n\", .{\"💯\"[1]}); // ...as does indexing part-way through non-ASCII characters\n 0 401 400 | }\n 0 400 400   \n 0 400 400   const hello_world_in_c =\n 2 400 401 +     \\\\#include <stdio.h>\n 0 401 401 |     \\\\\n 0 401 401 |     \\\\int main(int argc, char **argv) {\n 0 401 401 |     \\\\    printf(\"hello world\\n\");\n 0 401 401 |     \\\\    return 0;\n 0 401 400 |     \\\\}\n 0 400 400   ;\n 0 400 400   \n 0 400 400   const std = @import(\"std\");\n 0 400 400   const assert = std.debug.assert;\n 0 400 400   \n 0 400 400   threadlocal var x: i32 = 1234;\n 0 400 400   \n 2 400 401 + test \"thread local storage\" {\n 0 401 401 |     const thread1 = try std.Thread.spawn(.{}, testTls, .{});\n 0 401 401 |     const thread2 = try std.Thread.spawn(.{}, testTls, .{});\n 0 401 401 |     testTls();\n 0 401 401 |     thread1.join();\n 0 401 401 |     thread2.join();\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + fn testTls() void {\n 0 401 401 |     assert(x == 1234);\n 0 401 401 |     x += 1;\n 0 401 401 |     assert(x == 1235);\n 0 401 400 | }\n 0 400 400   \n 0 400 400   const decimal_int = 98222;\n 0 400 400   const hex_int = 0xff;\n 0 400 400   const another_hex_int = 0xFF;\n 0 400 400   const octal_int = 0o755;\n 0 400 400   const binary_int = 0b11110000;\n 0 400 400   \n 0 400 400   // underscores may be placed between two digits as a visual separator\n 0 400 400   const one_billion = 1_000_000_000;\n 0 400 400   const binary_mask = 0b1_1111_1111;\n 0 400 400   const permissions = 0o7_5_5;\n 0 400 400   const big_address = 0xFF80_0000_0000_0000;\n 0 400 400   \n 0 400 400   \n 0 400 400   const floating_point = 123.0E+77;\n 0 400 400   const another_float = 123.0;\n 0 400 400   const yet_another = 123.0e+77;\n 0 400 400   \n 0 400 400   const hex_floating_point = 0x103.70p-5;\n 0 400 400   const another_hex_float = 0x103.70;\n 0 400 400   const yet_another_hex_float = 0x103.70P-5;\n 0 400 400   \n 0 400 400   // underscores may be placed between two digits as a visual separator\n 0 400 400   const lightspeed = 299_792_458.000_000;\n 0 400 400   const nanosecond = 0.000_000_001;\n 0 400 400   const more_hex = 0x1234_5678.9ABC_CDEFp-10;\n 0 400 400   \n 2 400 401 + const Vec3 = struct {\n 0 401 401 |     x: f32,\n 0 401 401 |     y: f32,\n 0 401 401 |     z: f32,\n 0 401 401 | \n 2 401 402 +     pub fn init(x: f32, y: f32, z: f32) Vec3 {\n 2 402 403 +         return Vec3{\n 0 403 403 |             .x = x,\n 0 403 403 |             .y = y,\n 0 403 403 |             .z = z,\n 0 403 402 |         };\n 0 402 401 |     }\n 0 401 401 | \n 2 401 402 +     pub fn dot(self: Vec3, other: Vec3) f32 {\n 0 402 402 |         return self.x * other.x + self.y * other.y + self.z * other.z;\n 0 402 401 |     }\n 0 401 400 | };\n 0 400 400   \n 2 400 401 + fn LinkedList(comptime T: type) type {\n 2 401 402 +     return struct {\n 2 402 403 +         pub const Node = struct {\n 0 403 403 |             prev: ?*Node,\n 0 403 403 |             next: ?*Node,\n 0 403 403 |             data: T,\n 0 403 402 |         };\n 0 402 402 | \n 0 402 402 |         first: ?*Node,\n 0 402 402 |         last: ?*Node,\n 0 402 402 |         len: usize,\n 0 402 401 |     };\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + const Point = struct {\n 0 401 401 |     x: f32,\n 0 401 401 |     y: f32,\n 0 401 400 | };\n 0 400 400   \n 2 400 401 + // Maybe we want to pass it to OpenGL so we want to be particular about\n 0 401 400 | // how the bytes are arranged.\n 2 400 401 + const Point2 = packed struct {\n 0 401 401 |     x: f32,\n 0 401 401 |     y: f32,\n 0 401 400 | };\n 0 400 400   \n 0 400 400   \n 0 400 400   const std = @import(\"std\");\n 0 400 400   const expect = std.testing.expect;\n 0 400 400   \n 2 400 401 + const Color = enum {\n 0 401 401 |     auto,\n 0 401 401 |     off,\n 0 401 401 |     on,\n 0 401 400 | };\n 0 400 400   \n 0 400 400   const std = @import(\"std\");\n 0 400 400   const builtin = @import(\"builtin\");\n 0 400 400   const expect = std.testing.expect;\n 0 400 400   \n 2 400 401 + test \"switch simple\" {\n 0 401 401 |     const a: u64 = 10;\n 0 401 401 |     const zz: u64 = 103;\n 0 401 401 | \n 2 401 402 +     // All branches of a switch expression must be able to be coerced to a\n 0 402 402 |     // common type.\n 0 402 402 |     //\n 0 402 402 |     // Branches cannot fallthrough. If fallthrough behavior is desired, combine\n 0 402 401 |     // the cases and use an if.\n 2 401 402 +     const b = switch (a) {\n 0 402 402 |         // Multiple cases can be combined via a ','\n 0 402 402 |         1, 2, 3 => 0,\n 0 402 402 | \n 2 402 403 +         // Ranges can be specified using the ... syntax. These are inclusive\n 0 403 402 |         // of both ends.\n 0 402 402 |         5...100 => 1,\n 0 402 402 | \n 0 402 402 |         // Branches can be arbitrarily complex.\n 2 402 403 +         101 => blk: {\n 0 403 403 |             const c: u64 = 5;\n 0 403 403 |             break :blk c * 2 + 1;\n 0 403 402 |         },\n 0 402 402 | \n 2 402 403 +         // Switching on arbitrary expressions is allowed as long as the\n 0 403 402 |         // expression is known at compile-time.\n 0 402 402 |         zz => zz,\n 2 402 403 +         blk: {\n 0 403 403 |             const d: u32 = 5;\n 0 403 403 |             const e: u32 = 100;\n 0 403 403 |             break :blk d + e;\n 0 403 402 |         } => 107,\n 0 402 402 | \n 2 402 403 +         // The else branch catches everything not already captured.\n 0 403 403 |         // Else branches are mandatory unless the entire range of values\n 0 403 402 |         // is handled.\n 0 402 402 |         else => 9,\n 0 402 401 |     };\n 0 401 401 | \n 0 401 401 |     try expect(b == 1);\n 0 401 400 | }\n 0 400 400   \n 2 400 401 + fn charToDigit(c: u8) u8 {\n 2 401 402 +     return switch (c) {\n 0 402 402 |         '0'...'9' => c - '0',\n 0 402 402 |         'A'...'Z' => c - 'A' + 10,\n 0 402 402 |         'a'...'z' => c - 'a' + 10,\n 0 402 402 |         else => maxInt(u8),\n 0 402 401 |     };\n 0 401 400 | }\n 0 400 400   \n 0 400 400   const optional_value: ?i32 = null;\n 0 400 400   \n 2 400 401 + //! This module provides functions for retrieving the current date and\n 0 401 401 | //! time with varying degrees of precision and accuracy. It does not\n 0 401 400 | //! depend on libc, but will use functions from it if available.\n 0 400 400   \n 0 400 400   const @\"identifier with spaces in it\" = 0xff;\n 0 400 400   const @\"1SmallStep4Man\" = 112358;\n 0 400 400   \n 0 400 400   const c = @import(\"std\").c;\n 0 400 400   pub extern \"c\" fn @\"error\"() void;\n 0 400 400   pub extern \"c\" fn @\"fstat$INODE64\"(fd: c.fd_t, buf: *c.Stat) c_int;\n 0 400 400   \n 2 400 401 + const Color = enum {\n 0 401 401 |     red,\n 0 401 401 |     @\"really red\",\n 0 401 400 | };\n 0 400 400   const color: Color = .@\"really red\";\n 0 400 400   \n 0 400 400   const s1 = \"Unterminated string\n 0 400 400   const s2 = 'Unterminated character\n 0 400 400   const s3 = @\"Unterminated identifier string\n 0 400   0   "
  },
  {
    "path": "test/examples/zig/AllStyles.zig.styled",
    "content": "{1}// coding:utf-8\n{0}\n{2}/// A structure for storing a timestamp, with nanosecond precision (this is a\n/// multiline doc comment).\n{13}const{0} {15}Timestamp{0} {5}={0} {13}struct{0} {5}{{0}\n    {2}/// The number of seconds since the epoch (this is also a doc comment).\n{0}    {10}seconds{5}:{0} {14}i64{5},{0} {1}// signed so we can represent pre-1970 (not a doc comment)\n{0}    {2}/// The number of nanoseconds past the second (doc comment again).\n{0}    {10}nanos{5}:{0} {14}u32{5},{0}\n\n    {2}/// Returns a `Timestamp` struct representing the Unix epoch; that is, the\n{0}    {2}/// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too).\n{0}    {13}pub{0} {13}fn{0} {11}unixEpoch{5}(){0} {15}Timestamp{0} {5}{{0}\n        {13}return{0} {15}Timestamp{5}{{0}\n            {5}.{10}seconds{0} {5}={0} {4}0{5},{0}\n            {5}.{10}nanos{0} {5}={0} {4}0{5},{0}\n        {5}};{0}\n    {5}}{0}\n{5}};{0}\n\n{3}//! This module provides functions for retrieving the current date and\n//! time with varying degrees of precision and accuracy. It does not\n//! depend on libc, but will use functions from it if available.\n{0}\n{13}const{0} {10}S{0} {5}={0} {13}struct{0} {5}{{0}\n    {3}//! Top level comments are allowed inside a container other than a module,\n{0}    {3}//! but it is not very useful.  Currently, when producing the package\n{0}    {3}//! documentation, these comments are ignored.\n{5}};{0}\n\n{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}\"std\"{5});{0}\n\n{13}pub{0} {13}fn{0} {11}main{5}(){0} {5}!{14}void{0} {5}{{0}\n    {13}const{0} {10}stdout{0} {5}={0} {10}std{5}.{10}io{5}.{10}getStdOut{5}().{10}writer{5}();{0}\n    {13}try{0} {10}stdout{5}.{10}print{5}({7}\"Hello, {s}!{9}\\n{7}\"{5},{0} {5}.{{7}\"world\"{5}});{0}\n{5}}{0}\n\n\n{1}// Top-level declarations are order-independent:\n{13}const{0} {10}print{0} {5}={0} {10}std{5}.{10}debug{5}.{10}print{5};{0}\n{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}\"std\"{5});{0}\n{13}const{0} {10}os{0} {5}={0} {10}std{5}.{10}os{5};{0}\n{13}const{0} {13}assert{0} {5}={0} {10}std{5}.{10}debug{5}.{13}assert{5};{0}\n\n{13}pub{0} {13}fn{0} {11}main{5}(){0} {14}void{0} {5}{{0}\n    {1}// integers\n{0}    {13}const{0} {10}one_plus_one{5}:{0} {14}i32{0} {5}={0} {4}1{0} {5}+{0} {4}1{5};{0}\n    {10}print{5}({7}\"1 + 1 = {}{9}\\n{7}\"{5},{0} {5}.{{10}one_plus_one{5}});{0}\n\n    {1}// floats\n{0}    {13}const{0} {10}seven_div_three{5}:{0} {14}f32{0} {5}={0} {4}7.0{0} {5}/{0} {4}3.0{5};{0}\n    {10}print{5}({7}\"7.0 / 3.0 = {}{9}\\n{7}\"{5},{0} {5}.{{10}seven_div_three{5}});{0}\n\n    {1}// boolean\n{0}    {10}print{5}({7}\"{}{9}\\n{7}{}{9}\\n{7}{}{9}\\n{7}\"{5},{0} {5}.{{0}\n        {13}true{0} {13}and{0} {13}false{5},{0}\n        {13}true{0} {13}or{0} {13}false{5},{0}\n        {5}!{13}true{5},{0}\n    {5}});{0}\n\n    {1}// optional\n{0}    {13}var{0} {10}optional_value{5}:{0} {5}?[]{13}const{0} {14}u8{0} {5}={0} {13}null{5};{0}\n    {13}assert{5}({10}optional_value{0} {5}=={0} {13}null{5});{0}\n\n    {10}print{5}({7}\"{9}\\n{7}optional 1{9}\\n{7}type: {}{9}\\n{7}value: {?s}{9}\\n{7}\"{5},{0} {5}.{{0}\n        {12}@TypeOf{5}({10}optional_value{5}),{0} {10}optional_value{5},{0}\n    {5}});{0}\n\n    {10}optional_value{0} {5}={0} {7}\"hi\"{5};{0}\n    {13}assert{5}({10}optional_value{0} {5}!={0} {13}null{5});{0}\n\n    {10}print{5}({7}\"{9}\\n{7}optional 2{9}\\n{7}type: {}{9}\\n{7}value: {?s}{9}\\n{7}\"{5},{0} {5}.{{0}\n        {12}@TypeOf{5}({10}optional_value{5}),{0} {10}optional_value{5},{0}\n    {5}});{0}\n\n    {1}// error union\n{0}    {13}var{0} {10}number_or_error{5}:{0} {14}anyerror{5}!{14}i32{0} {5}={0} {13}error{5}.{10}ArgNotFound{5};{0}\n\n    {10}print{5}({7}\"{9}\\n{7}error union 1{9}\\n{7}type: {}{9}\\n{7}value: {!}{9}\\n{7}\"{5},{0} {5}.{{0}\n        {12}@TypeOf{5}({10}number_or_error{5}),{0}\n        {10}number_or_error{5},{0}\n    {5}});{0}\n\n    {10}number_or_error{0} {5}={0} {4}1234{5};{0}\n\n    {10}print{5}({7}\"{9}\\n{7}error union 2{9}\\n{7}type: {}{9}\\n{7}value: {!}{9}\\n{7}\"{5},{0} {5}.{{0}\n        {12}@TypeOf{5}({10}number_or_error{5}),{0} {10}number_or_error{5},{0}\n    {5}});{0}\n{5}}{0}\n\n{13}const{0} {10}print{0} {5}={0} {12}@import{5}({7}\"std\"{5}).{10}debug{5}.{10}print{5};{0}\n{13}const{0} {10}mem{0} {5}={0} {12}@import{5}({7}\"std\"{5}).{10}mem{5};{0} {1}// will be used to compare bytes\n{0}\n{13}pub{0} {13}fn{0} {11}main{5}(){0} {14}void{0} {5}{{0}\n    {13}const{0} {10}bytes{0} {5}={0} {7}\"hello{9}\\u{12345678}{7}\"{5};{0}\n    {10}print{5}({7}\"{}{9}\\n{7}\"{5},{0} {5}.{{12}@TypeOf{5}({10}bytes{5})});{0} {1}// *const [5:0]u8\n{0}    {10}print{5}({7}\"{d}{9}\\n{7}\"{5},{0} {5}.{{10}bytes{5}.{10}len{5}});{0} {1}// 5\n{0}    {10}print{5}({7}\"{c}{9}\\n{7}\"{5},{0} {5}.{{10}bytes{5}[{4}1{5}]});{0} {1}// 'e'\n{0}    {10}print{5}({7}\"{d}{9}\\n{7}\"{5},{0} {5}.{{10}bytes{5}[{4}5{5}]});{0} {1}// 0\n{0}    {10}print{5}({7}\"{}{9}\\n{7}\"{5},{0} {5}.{{6}'e'{0} {5}=={0} {6}'{9}\\x65{6}'{5}});{0} {1}// true\n{0}    {10}print{5}({7}\"{d}{9}\\n{7}\"{5},{0} {5}.{{6}'{9}\\u{1f4a9}{6}'{5}});{0} {1}// 128169\n{0}    {10}print{5}({7}\"{d}{9}\\n{7}\"{5},{0} {5}.{{6}'💯'{5}});{0} {1}// 128175\n{0}    {10}print{5}({7}\"{u}{9}\\n{7}\"{5},{0} {5}.{{6}'⚡'{5}});{0}\n    {10}print{5}({7}\"{}{9}\\n{7}\"{5},{0} {5}.{{10}mem{5}.{10}eql{5}({14}u8{5},{0} {7}\"hello\"{5},{0} {7}\"h{9}\\x65{7}llo\"{5})});{0} {1}// true\n{0}    {10}print{5}({7}\"{}{9}\\n{7}\"{5},{0} {5}.{{10}mem{5}.{10}eql{5}({14}u8{5},{0} {7}\"💯\"{5},{0} {7}\"{9}\\xf0\\x9f\\x92\\xaf{7}\"{5})});{0} {1}// also true\n{0}    {13}const{0} {10}invalid_utf8{0} {5}={0} {7}\"{9}\\xff\\xfe{7}\"{5};{0} {1}// non-UTF-8 strings are possible with \\xNN notation.\n{0}    {10}print{5}({7}\"0x{x}{9}\\n{7}\"{5},{0} {5}.{{10}invalid_utf8{5}[{4}1{5}]});{0} {1}// indexing them returns individual bytes...\n{0}    {10}print{5}({7}\"0x{x}{9}\\n{7}\"{5},{0} {5}.{{7}\"💯\"{5}[{4}1{5}]});{0} {1}// ...as does indexing part-way through non-ASCII characters\n{5}}{0}\n\n{13}const{0} {10}hello_world_in_c{0} {5}={0}\n    {8}\\\\#include <stdio.h>\n{0}    {8}\\\\\n{0}    {8}\\\\int main(int argc, char **argv) {\n{0}    {8}\\\\    printf(\"hello world\\n\");\n{0}    {8}\\\\    return 0;\n{0}    {8}\\\\}\n{5};{0}\n\n{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}\"std\"{5});{0}\n{13}const{0} {13}assert{0} {5}={0} {10}std{5}.{10}debug{5}.{13}assert{5};{0}\n\n{13}threadlocal{0} {13}var{0} {10}x{5}:{0} {14}i32{0} {5}={0} {4}1234{5};{0}\n\n{13}test{0} {7}\"thread local storage\"{0} {5}{{0}\n    {13}const{0} {10}thread1{0} {5}={0} {13}try{0} {10}std{5}.{10}Thread{5}.{10}spawn{5}(.{},{0} {10}testTls{5},{0} {5}.{});{0}\n    {13}const{0} {10}thread2{0} {5}={0} {13}try{0} {10}std{5}.{10}Thread{5}.{10}spawn{5}(.{},{0} {10}testTls{5},{0} {5}.{});{0}\n    {10}testTls{5}();{0}\n    {10}thread1{5}.{10}join{5}();{0}\n    {10}thread2{5}.{10}join{5}();{0}\n{5}}{0}\n\n{13}fn{0} {11}testTls{5}(){0} {14}void{0} {5}{{0}\n    {13}assert{5}({10}x{0} {5}=={0} {4}1234{5});{0}\n    {10}x{0} {5}+={0} {4}1{5};{0}\n    {13}assert{5}({10}x{0} {5}=={0} {4}1235{5});{0}\n{5}}{0}\n\n{13}const{0} {10}decimal_int{0} {5}={0} {4}98222{5};{0}\n{13}const{0} {10}hex_int{0} {5}={0} {4}0xff{5};{0}\n{13}const{0} {10}another_hex_int{0} {5}={0} {4}0xFF{5};{0}\n{13}const{0} {10}octal_int{0} {5}={0} {4}0o755{5};{0}\n{13}const{0} {10}binary_int{0} {5}={0} {4}0b11110000{5};{0}\n\n{1}// underscores may be placed between two digits as a visual separator\n{13}const{0} {10}one_billion{0} {5}={0} {4}1_000_000_000{5};{0}\n{13}const{0} {10}binary_mask{0} {5}={0} {4}0b1_1111_1111{5};{0}\n{13}const{0} {10}permissions{0} {5}={0} {4}0o7_5_5{5};{0}\n{13}const{0} {10}big_address{0} {5}={0} {4}0xFF80_0000_0000_0000{5};{0}\n\n\n{13}const{0} {10}floating_point{0} {5}={0} {4}123.0E+77{5};{0}\n{13}const{0} {10}another_float{0} {5}={0} {4}123.0{5};{0}\n{13}const{0} {10}yet_another{0} {5}={0} {4}123.0e+77{5};{0}\n\n{13}const{0} {10}hex_floating_point{0} {5}={0} {4}0x103.70p{5}-{4}5{5};{0}\n{13}const{0} {10}another_hex_float{0} {5}={0} {4}0x103.70{5};{0}\n{13}const{0} {10}yet_another_hex_float{0} {5}={0} {4}0x103.70P{5}-{4}5{5};{0}\n\n{1}// underscores may be placed between two digits as a visual separator\n{13}const{0} {10}lightspeed{0} {5}={0} {4}299_792_458.000_000{5};{0}\n{13}const{0} {10}nanosecond{0} {5}={0} {4}0.000_000_001{5};{0}\n{13}const{0} {10}more_hex{0} {5}={0} {4}0x1234_5678.9ABC_CDEFp{5}-{4}10{5};{0}\n\n{13}const{0} {16}Vec3{0} {5}={0} {13}struct{0} {5}{{0}\n    {10}x{5}:{0} {14}f32{5},{0}\n    {10}y{5}:{0} {14}f32{5},{0}\n    {10}z{5}:{0} {14}f32{5},{0}\n\n    {13}pub{0} {13}fn{0} {11}init{5}({10}x{5}:{0} {14}f32{5},{0} {10}y{5}:{0} {14}f32{5},{0} {10}z{5}:{0} {14}f32{5}){0} {16}Vec3{0} {5}{{0}\n        {13}return{0} {16}Vec3{5}{{0}\n            {5}.{10}x{0} {5}={0} {10}x{5},{0}\n            {5}.{10}y{0} {5}={0} {10}y{5},{0}\n            {5}.{10}z{0} {5}={0} {10}z{5},{0}\n        {5}};{0}\n    {5}}{0}\n\n    {13}pub{0} {13}fn{0} {11}dot{5}({10}self{5}:{0} {16}Vec3{5},{0} {10}other{5}:{0} {16}Vec3{5}){0} {14}f32{0} {5}{{0}\n        {13}return{0} {10}self{5}.{10}x{0} {5}*{0} {10}other{5}.{10}x{0} {5}+{0} {10}self{5}.{10}y{0} {5}*{0} {10}other{5}.{10}y{0} {5}+{0} {10}self{5}.{10}z{0} {5}*{0} {10}other{5}.{10}z{5};{0}\n    {5}}{0}\n{5}};{0}\n\n{13}fn{0} {11}LinkedList{5}({13}comptime{0} {10}T{5}:{0} {14}type{5}){0} {14}type{0} {5}{{0}\n    {13}return{0} {13}struct{0} {5}{{0}\n        {13}pub{0} {13}const{0} {10}Node{0} {5}={0} {13}struct{0} {5}{{0}\n            {10}prev{5}:{0} {5}?*{10}Node{5},{0}\n            {10}next{5}:{0} {5}?*{10}Node{5},{0}\n            {10}data{5}:{0} {10}T{5},{0}\n        {5}};{0}\n\n        {10}first{5}:{0} {5}?*{10}Node{5},{0}\n        {10}last{5}:{0} {5}?*{10}Node{5},{0}\n        {10}len{5}:{0} {14}usize{5},{0}\n    {5}};{0}\n{5}}{0}\n\n{13}const{0} {10}Point{0} {5}={0} {13}struct{0} {5}{{0}\n    {10}x{5}:{0} {14}f32{5},{0}\n    {10}y{5}:{0} {14}f32{5},{0}\n{5}};{0}\n\n{1}// Maybe we want to pass it to OpenGL so we want to be particular about\n// how the bytes are arranged.\n{13}const{0} {10}Point2{0} {5}={0} {13}packed{0} {13}struct{0} {5}{{0}\n    {10}x{5}:{0} {14}f32{5},{0}\n    {10}y{5}:{0} {14}f32{5},{0}\n{5}};{0}\n\n\n{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}\"std\"{5});{0}\n{13}const{0} {10}expect{0} {5}={0} {10}std{5}.{10}testing{5}.{10}expect{5};{0}\n\n{13}const{0} {10}Color{0} {5}={0} {13}enum{0} {5}{{0}\n    {10}auto{5},{0}\n    {10}off{5},{0}\n    {10}on{5},{0}\n{5}};{0}\n\n{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}\"std\"{5});{0}\n{13}const{0} {10}builtin{0} {5}={0} {12}@import{5}({7}\"builtin\"{5});{0}\n{13}const{0} {10}expect{0} {5}={0} {10}std{5}.{10}testing{5}.{10}expect{5};{0}\n\n{13}test{0} {7}\"switch simple\"{0} {5}{{0}\n    {13}const{0} {10}a{5}:{0} {14}u64{0} {5}={0} {4}10{5};{0}\n    {13}const{0} {10}zz{5}:{0} {14}u64{0} {5}={0} {4}103{5};{0}\n\n    {1}// All branches of a switch expression must be able to be coerced to a\n{0}    {1}// common type.\n{0}    {1}//\n{0}    {1}// Branches cannot fallthrough. If fallthrough behavior is desired, combine\n{0}    {1}// the cases and use an if.\n{0}    {13}const{0} {10}b{0} {5}={0} {13}switch{0} {5}({10}a{5}){0} {5}{{0}\n        {1}// Multiple cases can be combined via a ','\n{0}        {4}1{5},{0} {4}2{5},{0} {4}3{0} {5}=>{0} {4}0{5},{0}\n\n        {1}// Ranges can be specified using the ... syntax. These are inclusive\n{0}        {1}// of both ends.\n{0}        {4}5{5}..{4}.100{0} {5}=>{0} {4}1{5},{0}\n\n        {1}// Branches can be arbitrarily complex.\n{0}        {4}101{0} {5}=>{0} {10}blk{5}:{0} {5}{{0}\n            {13}const{0} {10}c{5}:{0} {14}u64{0} {5}={0} {4}5{5};{0}\n            {13}break{0} {5}:{10}blk{0} {10}c{0} {5}*{0} {4}2{0} {5}+{0} {4}1{5};{0}\n        {5}},{0}\n\n        {1}// Switching on arbitrary expressions is allowed as long as the\n{0}        {1}// expression is known at compile-time.\n{0}        {10}zz{0} {5}=>{0} {10}zz{5},{0}\n        {10}blk{5}:{0} {5}{{0}\n            {13}const{0} {10}d{5}:{0} {14}u32{0} {5}={0} {4}5{5};{0}\n            {13}const{0} {10}e{5}:{0} {14}u32{0} {5}={0} {4}100{5};{0}\n            {13}break{0} {5}:{10}blk{0} {10}d{0} {5}+{0} {10}e{5};{0}\n        {5}}{0} {5}=>{0} {4}107{5},{0}\n\n        {1}// The else branch catches everything not already captured.\n{0}        {1}// Else branches are mandatory unless the entire range of values\n{0}        {1}// is handled.\n{0}        {13}else{0} {5}=>{0} {4}9{5},{0}\n    {5}};{0}\n\n    {13}try{0} {10}expect{5}({10}b{0} {5}=={0} {4}1{5});{0}\n{5}}{0}\n\n{13}fn{0} {11}charToDigit{5}({10}c{5}:{0} {14}u8{5}){0} {14}u8{0} {5}{{0}\n    {13}return{0} {13}switch{0} {5}({10}c{5}){0} {5}{{0}\n        {6}'0'{5}...{6}'9'{0} {5}=>{0} {10}c{0} {5}-{0} {6}'0'{5},{0}\n        {6}'A'{5}...{6}'Z'{0} {5}=>{0} {10}c{0} {5}-{0} {6}'A'{0} {5}+{0} {4}10{5},{0}\n        {6}'a'{5}...{6}'z'{0} {5}=>{0} {10}c{0} {5}-{0} {6}'a'{0} {5}+{0} {4}10{5},{0}\n        {13}else{0} {5}=>{0} {10}maxInt{5}({14}u8{5}),{0}\n    {5}};{0}\n{5}}{0}\n\n{13}const{0} {10}optional_value{5}:{0} {5}?{14}i32{0} {5}={0} {13}null{5};{0}\n\n{3}//! This module provides functions for retrieving the current date and\n//! time with varying degrees of precision and accuracy. It does not\n//! depend on libc, but will use functions from it if available.\n{0}\n{13}const{0} {17}@\"identifier with spaces in it\"{0} {5}={0} {4}0xff{5};{0}\n{13}const{0} {17}@\"1SmallStep4Man\"{0} {5}={0} {4}112358{5};{0}\n\n{13}const{0} {10}c{0} {5}={0} {12}@import{5}({7}\"std\"{5}).{10}c{5};{0}\n{13}pub{0} {13}extern{0} {7}\"c\"{0} {13}fn{0} {17}@\"error\"{5}(){0} {11}void{5};{0}\n{13}pub{0} {13}extern{0} {7}\"c\"{0} {13}fn{0} {17}@\"fstat$INODE64\"{5}({11}fd{5}:{0} {10}c{5}.{10}fd_t{5},{0} {10}buf{5}:{0} {5}*{10}c{5}.{10}Stat{5}){0} {10}c_int{5};{0}\n\n{13}const{0} {10}Color{0} {5}={0} {13}enum{0} {5}{{0}\n    {10}red{5},{0}\n    {17}@\"really red\"{5},{0}\n{5}};{0}\n{13}const{0} {10}color{5}:{0} {10}Color{0} {5}={0} {5}.{17}@\"really red\"{5};{0}\n\n{13}const{0} {10}s1{0} {5}={0} {18}\"Unterminated string\n{13}const{0} {10}s2{0} {5}={0} {18}'Unterminated character\n{13}const{0} {10}s3{0} {5}={0} {18}@\"Unterminated identifier string\n"
  },
  {
    "path": "test/examples/zig/SciTE.properties",
    "content": "lexer.*.zig=zig\nfold=1\nkeywords.*.zig=False None True _ and as assert async await break case class continue def del elif else except finally for from global if import in is lambda match nonlocal not or pass raise return try while with yield addrspace align allowzero and anyframe anytype asm async await break callconv catch comptime const continue defer else enum errdefer error export extern false fn for if inline linksection noalias noinline nosuspend null opaque or orelse packed pub resume return struct suspend switch test threadlocal true try undefined union unreachable usingnamespace var volatile while\nkeywords2.*.zig=anyerror anyopaque bool f128 f16 f32 f64 f80 i128 i16 i32 i64 i8 isize noreturn type u128 u16 u32 u64 u8 usize void\nkeywords3.*.zig=Timestamp\nkeywords4.*.zig=Vec3\n"
  },
  {
    "path": "test/makefile",
    "content": "# Build all the lexer tests using GNU make and either g++ or Clang\n# @file makefile\n# Copyright 2019 by Neil Hodgson <neilh@scintilla.org>\n# The License.txt file describes the conditions under which this software may be distributed.\n# Should be run using mingw32-make on Windows, not nmake\n# On Windows g++ is used, on macOS clang, and on Linux g++ is used by default\n# but clang can be used by defining CLANG when invoking make\n# clang works only with libc++, not libstdc++\n\n.PHONY: all test clean\n\n.SUFFIXES: .cxx\n\nWARNINGS = -Wpedantic -Wall -Wextra\n\nifndef windir\nLIBS += -ldl\nifeq ($(shell uname),Darwin)\n# On macOS always use Clang\nCLANG = 1\nendif\nendif\n\nEXE = $(if $(windir),TestLexers.exe,TestLexers)\n\nBASE_FLAGS += --std=c++20\n\nifdef CLANG\n    CXX = clang++\n    BASE_FLAGS += -fsanitize=address\nendif\n\nifdef LEXILLA_STATIC\n    DEFINES += -D LEXILLA_STATIC\n    LIBS += ../bin/liblexilla.a\nendif\n\nifdef windir\n    DEL = $(if $(wildcard $(dir $(SHELL))rm.exe), $(dir $(SHELL))rm.exe -f, del /q)\nelse\n    DEL = rm -f\nendif\n\nvpath %.cxx ../access\n\nDEFINES += -D$(if $(DEBUG),DEBUG,NDEBUG)\nBASE_FLAGS += $(if $(DEBUG),-g,-O3)\n\nINCLUDES = -I ../../scintilla/include -I ../include -I ../access\nBASE_FLAGS += $(WARNINGS)\n\nall: $(EXE)\n\ntest: $(EXE)\n\t./$(EXE)\n\nclean:\n\t$(DEL) *.o *.obj $(EXE)\n\n%.o: %.cxx\n\t$(CXX) $(DEFINES) $(INCLUDES) $(BASE_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@\n\nOBJS = TestLexers.o TestDocument.o LexillaAccess.o\n\n$(EXE): $(OBJS)\n\t$(CXX) $(BASE_FLAGS) $(CPPFLAGS) $(CXXFLAGS) $^ $(LIBS) $(LDLIBS) -o $@\n\nTestLexers.o: TestLexers.cxx TestDocument.h\nTestDocument.o: TestDocument.cxx TestDocument.h\n"
  },
  {
    "path": "test/testlexers.mak",
    "content": "# Build the lexers test with Microsoft Visual C++ using nmake\n# Tested with Visual C++ 2022\n\nDEL = del /q\nEXE = TestLexers.exe\n\nINCLUDEDIRS = -I ../../scintilla/include -I ../include -I ../access\n\n!IFDEF LEXILLA_STATIC\nSTATIC_FLAG = -D LEXILLA_STATIC\nLIBS = ../bin/liblexilla.lib\n!ENDIF\n\n!IFDEF DEBUG\nDEBUG_OPTIONS = -Zi -DEBUG -Od -MTd -DDEBUG $(STATIC_FLAG)\n!ELSE\nDEBUG_OPTIONS = -O2 -MT -DNDEBUG $(STATIC_FLAG) -GL\n!ENDIF\n\nCXXFLAGS = /EHsc /std:c++20 $(DEBUG_OPTIONS) $(INCLUDEDIRS)\n\nOBJS = TestLexers.obj TestDocument.obj LexillaAccess.obj\n\nall: $(EXE)\n\ntest: $(EXE)\n\t$(EXE)\n\nclean:\n\t$(DEL) *.o *.obj *.exe\n\n$(EXE): $(OBJS) $(LIBS)\n\t$(CXX) $(CXXFLAGS) $(LIBS) /Fe$@ $**\n\n.cxx.obj::\n\t$(CXX) $(CXXFLAGS) -c $<\n{..\\access}.cxx.obj::\n\t$(CXX) $(CXXFLAGS) -c $<\n\nTestLexers.obj: $*.cxx TestDocument.h\nTestDocument.obj: $*.cxx $*.h\n"
  },
  {
    "path": "test/unit/LICENSE_1_0.txt",
    "content": "Boost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "test/unit/README",
    "content": "The test/unit directory contains unit tests for Scintilla data structures.\r\n\r\nThe tests can be run on Windows, macOS, or Linux using g++ and GNU make.\r\nThe Catch test framework is used.\r\nhttps://github.com/philsquared/Catch\r\nThe file catch.hpp is under the Boost Software License which is contained in LICENSE_1_0.txt\r\n\r\n   To run the tests on macOS or Linux:\r\nmake test\r\n\r\n   To run the tests on Windows:\r\nmingw32-make test\r\n\r\n   Visual C++ (2010+) and nmake can also be used on Windows:\r\nnmake -f test.mak test\r\n"
  },
  {
    "path": "test/unit/Sci.natvis",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<AutoVisualizer xmlns=\"http://schemas.microsoft.com/vstudio/debugger/natvis/2010\">\r\n  <Type Name=\"Scintilla::SplitVector&lt;*&gt;\">\r\n    <DisplayString>{{size = {lengthBody}}}</DisplayString>\r\n    <Expand>\r\n      <Item Name=\"[size]\">lengthBody</Item>\r\n      <Item Name=\"[part1Length]\">part1Length</Item>\r\n      <Item Name=\"[gap]\">gapLength</Item>\r\n      <IndexListItems>\r\n        <Size>lengthBody</Size>\r\n        <ValueNode>body[($i&lt;part1Length)?$i:$i+gapLength]</ValueNode>\r\n      </IndexListItems>\r\n    </Expand>\r\n  </Type>\r\n  <Type Name=\"Scintilla::Partitioning&lt;*&gt;\">\r\n    <DisplayString>{{size = {body->lengthBody}}}</DisplayString>\r\n    <Expand>\r\n      <IndexListItems>\r\n        <Size>body->lengthBody</Size>\r\n        <ValueNode>body->body[($i&lt;body->part1Length)?$i:$i+body->gapLength]+($i&gt;stepPartition?stepLength:0)</ValueNode>\r\n      </IndexListItems>\r\n    </Expand>\r\n  </Type>\r\n  <Type Name=\"std::unique_ptr&lt;*&gt;\">\r\n    <SmartPointer Usage=\"Minimal\">_Mypair._Myval2</SmartPointer>\r\n    <DisplayString Condition=\"_Mypair._Myval2 == 0\">empty</DisplayString>\r\n    <DisplayString Condition=\"_Mypair._Myval2 != 0\">unique_ptr {*_Mypair._Myval2}</DisplayString>\r\n    <Expand>\r\n      <ExpandedItem Condition=\"_Mypair._Myval2 != 0\">_Mypair._Myval2</ExpandedItem>\r\n      <ExpandedItem Condition=\"_Mypair._Myval2 != 0\">_Mypair</ExpandedItem>\r\n    </Expand>\r\n  </Type>\r\n</AutoVisualizer>\r\n"
  },
  {
    "path": "test/unit/SciTE.properties",
    "content": "command.go.*.cxx=./unitTest\nif PLAT_WIN\n\tmake.command=mingw32-make\n\tcommand.go.*.cxx=unitTest\ncommand.go.needs.$(file.patterns.cplusplus)=$(make.command)\n"
  },
  {
    "path": "test/unit/UnitTester.cxx",
    "content": "/** @file UnitTester.cxx\n ** UnitTester.cpp : Defines the entry point for the console application.\n **/\n\n// Catch uses std::uncaught_exception which is deprecated in C++17.\n// This define silences a warning from Visual C++.\n#define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING\n\n#include <cstdio>\n#include <cstdarg>\n\n#include <string_view>\n#include <vector>\n#include <memory>\n\n#define CATCH_CONFIG_WINDOWS_CRTDBG\n#define CATCH_CONFIG_RUNNER\n#include \"catch.hpp\"\n\nint main(int argc, char* argv[]) {\n\tconst int result = Catch::Session().run(argc, argv);\n\n\treturn result;\n}\n"
  },
  {
    "path": "test/unit/UnitTester.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <ProjectGuid>{35688A27-D91B-453A-8A05-65A7F28DEFBF}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>UnitTester</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS=1;_HAS_AUTO_PTR_ETC=1;_SCL_SECURE_NO_WARNINGS=1;CHECK_CORRECTNESS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>..\\..\\include\\;..\\..\\lexlib\\;..\\..\\..\\scintilla\\include\\</AdditionalIncludeDirectories>\r\n      <LanguageStandard>stdcpp17</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS=1;_HAS_AUTO_PTR_ETC=1;_SCL_SECURE_NO_WARNINGS=1;CHECK_CORRECTNESS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>..\\..\\include\\;..\\..\\lexlib\\;..\\..\\..\\scintilla\\include\\</AdditionalIncludeDirectories>\r\n      <LanguageStandard>stdcpp17</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS=1;_HAS_AUTO_PTR_ETC=1;_SCL_SECURE_NO_WARNINGS=1;CHECK_CORRECTNESS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>..\\..\\include\\;..\\..\\lexlib\\;..\\..\\..\\scintilla\\include\\</AdditionalIncludeDirectories>\r\n      <LanguageStandard>stdcpp17</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS=1;_HAS_AUTO_PTR_ETC=1;_SCL_SECURE_NO_WARNINGS=1;CHECK_CORRECTNESS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>..\\..\\include\\;..\\..\\lexlib\\;..\\..\\..\\scintilla\\include\\</AdditionalIncludeDirectories>\r\n      <LanguageStandard>stdcpp17</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\..\\lexlib\\Accessor.cxx\" />\r\n    <ClCompile Include=\"..\\..\\lexlib\\CharacterSet.cxx\" />\r\n    <ClCompile Include=\"..\\..\\lexlib\\InList.cxx\" />\r\n    <ClCompile Include=\"..\\..\\lexlib\\LexerBase.cxx\" />\r\n    <ClCompile Include=\"..\\..\\lexlib\\LexerModule.cxx\" />\r\n    <ClCompile Include=\"..\\..\\lexlib\\LexerSimple.cxx\" />\r\n    <ClCompile Include=\"..\\..\\lexlib\\PropSetSimple.cxx\" />\r\n    <ClCompile Include=\"..\\..\\lexlib\\WordList.cxx\" />\r\n    <ClCompile Include=\"test*.cxx\" />\r\n    <ClCompile Include=\"UnitTester.cxx\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Natvis Include=\"Sci.natvis\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "test/unit/catch.hpp",
    "content": "/*\n *  Catch v2.13.10\n *  Generated: 2022-10-16 11:01:23.452308\n *  ----------------------------------------------------------\n *  This file has been merged from multiple headers. Please don't edit it directly\n *  Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved.\n *\n *  Distributed under the Boost Software License, Version 1.0. (See accompanying\n *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n */\n#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n// start catch.hpp\n\n\n#define CATCH_VERSION_MAJOR 2\n#define CATCH_VERSION_MINOR 13\n#define CATCH_VERSION_PATCH 10\n\n#ifdef __clang__\n#    pragma clang system_header\n#elif defined __GNUC__\n#    pragma GCC system_header\n#endif\n\n// start catch_suppress_warnings.h\n\n#ifdef __clang__\n#   ifdef __ICC // icpc defines the __clang__ macro\n#       pragma warning(push)\n#       pragma warning(disable: 161 1682)\n#   else // __ICC\n#       pragma clang diagnostic push\n#       pragma clang diagnostic ignored \"-Wpadded\"\n#       pragma clang diagnostic ignored \"-Wswitch-enum\"\n#       pragma clang diagnostic ignored \"-Wcovered-switch-default\"\n#    endif\n#elif defined __GNUC__\n     // Because REQUIREs trigger GCC's -Wparentheses, and because still\n     // supported version of g++ have only buggy support for _Pragmas,\n     // Wparentheses have to be suppressed globally.\n#    pragma GCC diagnostic ignored \"-Wparentheses\" // See #674 for details\n\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wunused-variable\"\n#    pragma GCC diagnostic ignored \"-Wpadded\"\n#endif\n// end catch_suppress_warnings.h\n#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)\n#  define CATCH_IMPL\n#  define CATCH_CONFIG_ALL_PARTS\n#endif\n\n// In the impl file, we want to have access to all parts of the headers\n// Can also be used to sanely support PCHs\n#if defined(CATCH_CONFIG_ALL_PARTS)\n#  define CATCH_CONFIG_EXTERNAL_INTERFACES\n#  if defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#    undef CATCH_CONFIG_DISABLE_MATCHERS\n#  endif\n#  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)\n#    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n#  endif\n#endif\n\n#if !defined(CATCH_CONFIG_IMPL_ONLY)\n// start catch_platform.h\n\n// See e.g.:\n// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html\n#ifdef __APPLE__\n#  include <TargetConditionals.h>\n#  if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \\\n      (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)\n#    define CATCH_PLATFORM_MAC\n#  elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)\n#    define CATCH_PLATFORM_IPHONE\n#  endif\n\n#elif defined(linux) || defined(__linux) || defined(__linux__)\n#  define CATCH_PLATFORM_LINUX\n\n#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)\n#  define CATCH_PLATFORM_WINDOWS\n#endif\n\n// end catch_platform.h\n\n#ifdef CATCH_IMPL\n#  ifndef CLARA_CONFIG_MAIN\n#    define CLARA_CONFIG_MAIN_NOT_DEFINED\n#    define CLARA_CONFIG_MAIN\n#  endif\n#endif\n\n// start catch_user_interfaces.h\n\nnamespace Catch {\n    unsigned int rngSeed();\n}\n\n// end catch_user_interfaces.h\n// start catch_tag_alias_autoregistrar.h\n\n// start catch_common.h\n\n// start catch_compiler_capabilities.h\n\n// Detect a number of compiler features - by compiler\n// The following features are defined:\n//\n// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?\n// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?\n// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?\n// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?\n// ****************\n// Note to maintainers: if new toggles are added please document them\n// in configuration.md, too\n// ****************\n\n// In general each macro has a _NO_<feature name> form\n// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.\n// Many features, at point of detection, define an _INTERNAL_ macro, so they\n// can be combined, en-mass, with the _NO_ forms later.\n\n#ifdef __cplusplus\n\n#  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)\n#    define CATCH_CPP14_OR_GREATER\n#  endif\n\n#  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)\n#    define CATCH_CPP17_OR_GREATER\n#  endif\n\n#endif\n\n// Only GCC compiler should be used in this block, so other compilers trying to\n// mask themselves as GCC should be ignored.\n#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)\n#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( \"GCC diagnostic push\" )\n#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( \"GCC diagnostic pop\" )\n\n#    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)\n\n#endif\n\n#if defined(__clang__)\n\n#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( \"clang diagnostic push\" )\n#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( \"clang diagnostic pop\" )\n\n// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug\n// which results in calls to destructors being emitted for each temporary,\n// without a matching initialization. In practice, this can result in something\n// like `std::string::~string` being called on an uninitialized value.\n//\n// For example, this code will likely segfault under IBM XL:\n// ```\n// REQUIRE(std::string(\"12\") + \"34\" == \"1234\")\n// ```\n//\n// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.\n#  if !defined(__ibmxl__) && !defined(__CUDACC__)\n#    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */\n#  endif\n\n#    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wexit-time-destructors\\\"\" ) \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wglobal-constructors\\\"\")\n\n#    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wparentheses\\\"\" )\n\n#    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wunused-variable\\\"\" )\n\n#    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wgnu-zero-variadic-macro-arguments\\\"\" )\n\n#    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wunused-template\\\"\" )\n\n#endif // __clang__\n\n////////////////////////////////////////////////////////////////////////////////\n// Assume that non-Windows platforms support posix signals by default\n#if !defined(CATCH_PLATFORM_WINDOWS)\n    #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// We know some environments not to support full POSIX signals\n#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)\n    #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS\n#endif\n\n#ifdef __OS400__\n#       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS\n#       define CATCH_CONFIG_COLOUR_NONE\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// Android somehow still does not support std::to_string\n#if defined(__ANDROID__)\n#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING\n#    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// Not all Windows environments support SEH properly\n#if defined(__MINGW32__)\n#    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// PS4\n#if defined(__ORBIS__)\n#    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// Cygwin\n#ifdef __CYGWIN__\n\n// Required for some versions of Cygwin to declare gettimeofday\n// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin\n#   define _BSD_SOURCE\n// some versions of cygwin (most) do not support std::to_string. Use the libstd check.\n// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813\n# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \\\n           && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))\n\n#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING\n\n# endif\n#endif // __CYGWIN__\n\n////////////////////////////////////////////////////////////////////////////////\n// Visual C++\n#if defined(_MSC_VER)\n\n// Universal Windows platform does not support SEH\n// Or console colours (or console at all...)\n#  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)\n#    define CATCH_CONFIG_COLOUR_NONE\n#  else\n#    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH\n#  endif\n\n#  if !defined(__clang__) // Handle Clang masquerading for msvc\n\n// MSVC traditional preprocessor needs some workaround for __VA_ARGS__\n// _MSVC_TRADITIONAL == 0 means new conformant preprocessor\n// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor\n#    if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)\n#      define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#    endif // MSVC_TRADITIONAL\n\n// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop`\n#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )\n#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )\n#  endif // __clang__\n\n#endif // _MSC_VER\n\n#if defined(_REENTRANT) || defined(_MSC_VER)\n// Enable async processing, as -pthread is specified or no additional linking is required\n# define CATCH_INTERNAL_CONFIG_USE_ASYNC\n#endif // _MSC_VER\n\n////////////////////////////////////////////////////////////////////////////////\n// Check if we are compiled with -fno-exceptions or equivalent\n#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)\n#  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// DJGPP\n#ifdef __DJGPP__\n#  define CATCH_INTERNAL_CONFIG_NO_WCHAR\n#endif // __DJGPP__\n\n////////////////////////////////////////////////////////////////////////////////\n// Embarcadero C++Build\n#if defined(__BORLANDC__)\n    #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n\n// Use of __COUNTER__ is suppressed during code analysis in\n// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly\n// handled by it.\n// Otherwise all supported compilers support COUNTER macro,\n// but user still might want to turn it off\n#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )\n    #define CATCH_INTERNAL_CONFIG_COUNTER\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n\n// RTX is a special version of Windows that is real time.\n// This means that it is detected as Windows, but does not provide\n// the same set of capabilities as real Windows does.\n#if defined(UNDER_RTSS) || defined(RTX64_BUILD)\n    #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH\n    #define CATCH_INTERNAL_CONFIG_NO_ASYNC\n    #define CATCH_CONFIG_COLOUR_NONE\n#endif\n\n#if !defined(_GLIBCXX_USE_C99_MATH_TR1)\n#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER\n#endif\n\n// Various stdlib support checks that require __has_include\n#if defined(__has_include)\n  // Check if string_view is available and usable\n  #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)\n  #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW\n  #endif\n\n  // Check if optional is available and usable\n  #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)\n  #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL\n  #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)\n\n  // Check if byte is available and usable\n  #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)\n  #    include <cstddef>\n  #    if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)\n  #      define CATCH_INTERNAL_CONFIG_CPP17_BYTE\n  #    endif\n  #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)\n\n  // Check if variant is available and usable\n  #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)\n  #    if defined(__clang__) && (__clang_major__ < 8)\n         // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852\n         // fix should be in clang 8, workaround in libstdc++ 8.2\n  #      include <ciso646>\n  #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)\n  #        define CATCH_CONFIG_NO_CPP17_VARIANT\n  #      else\n  #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT\n  #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)\n  #    else\n  #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT\n  #    endif // defined(__clang__) && (__clang_major__ < 8)\n  #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)\n#endif // defined(__has_include)\n\n#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)\n#   define CATCH_CONFIG_COUNTER\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)\n#   define CATCH_CONFIG_WINDOWS_SEH\n#endif\n// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.\n#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)\n#   define CATCH_CONFIG_POSIX_SIGNALS\n#endif\n// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.\n#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)\n#   define CATCH_CONFIG_WCHAR\n#endif\n\n#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)\n#    define CATCH_CONFIG_CPP11_TO_STRING\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)\n#  define CATCH_CONFIG_CPP17_OPTIONAL\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)\n#  define CATCH_CONFIG_CPP17_STRING_VIEW\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)\n#  define CATCH_CONFIG_CPP17_VARIANT\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)\n#  define CATCH_CONFIG_CPP17_BYTE\n#endif\n\n#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)\n#  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)\n#  define CATCH_CONFIG_NEW_CAPTURE\n#endif\n\n#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n#  define CATCH_CONFIG_DISABLE_EXCEPTIONS\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)\n#  define CATCH_CONFIG_POLYFILL_ISNAN\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)\n#  define CATCH_CONFIG_USE_ASYNC\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)\n#  define CATCH_CONFIG_ANDROID_LOGWRITE\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)\n#  define CATCH_CONFIG_GLOBAL_NEXTAFTER\n#endif\n\n// Even if we do not think the compiler has that warning, we still have\n// to provide a macro that can be used by the code.\n#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)\n#   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION\n#endif\n#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)\n#   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS\n#endif\n\n// The goal of this macro is to avoid evaluation of the arguments, but\n// still have the compiler warn on problems inside...\n#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)\n#   define CATCH_INTERNAL_IGNORE_BUT_WARN(...)\n#endif\n\n#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)\n#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS\n#elif defined(__clang__) && (__clang_major__ < 5)\n#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS\n#endif\n\n#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS\n#endif\n\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n#define CATCH_TRY if ((true))\n#define CATCH_CATCH_ALL if ((false))\n#define CATCH_CATCH_ANON(type) if ((false))\n#else\n#define CATCH_TRY try\n#define CATCH_CATCH_ALL catch (...)\n#define CATCH_CATCH_ANON(type) catch (type)\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)\n#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#endif\n\n// end catch_compiler_capabilities.h\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )\n#ifdef CATCH_CONFIG_COUNTER\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )\n#else\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )\n#endif\n\n#include <iosfwd>\n#include <string>\n#include <cstdint>\n\n// We need a dummy global operator<< so we can bring it into Catch namespace later\nstruct Catch_global_namespace_dummy {};\nstd::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);\n\nnamespace Catch {\n\n    struct CaseSensitive { enum Choice {\n        Yes,\n        No\n    }; };\n\n    class NonCopyable {\n        NonCopyable( NonCopyable const& )              = delete;\n        NonCopyable( NonCopyable && )                  = delete;\n        NonCopyable& operator = ( NonCopyable const& ) = delete;\n        NonCopyable& operator = ( NonCopyable && )     = delete;\n\n    protected:\n        NonCopyable();\n        virtual ~NonCopyable();\n    };\n\n    struct SourceLineInfo {\n\n        SourceLineInfo() = delete;\n        SourceLineInfo( char const* _file, std::size_t _line ) noexcept\n        :   file( _file ),\n            line( _line )\n        {}\n\n        SourceLineInfo( SourceLineInfo const& other )            = default;\n        SourceLineInfo& operator = ( SourceLineInfo const& )     = default;\n        SourceLineInfo( SourceLineInfo&& )              noexcept = default;\n        SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;\n\n        bool empty() const noexcept { return file[0] == '\\0'; }\n        bool operator == ( SourceLineInfo const& other ) const noexcept;\n        bool operator < ( SourceLineInfo const& other ) const noexcept;\n\n        char const* file;\n        std::size_t line;\n    };\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );\n\n    // Bring in operator<< from global namespace into Catch namespace\n    // This is necessary because the overload of operator<< above makes\n    // lookup stop at namespace Catch\n    using ::operator<<;\n\n    // Use this in variadic streaming macros to allow\n    //    >> +StreamEndStop\n    // as well as\n    //    >> stuff +StreamEndStop\n    struct StreamEndStop {\n        std::string operator+() const;\n    };\n    template<typename T>\n    T const& operator + ( T const& value, StreamEndStop ) {\n        return value;\n    }\n}\n\n#define CATCH_INTERNAL_LINEINFO \\\n    ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )\n\n// end catch_common.h\nnamespace Catch {\n\n    struct RegistrarForTagAliases {\n        RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );\n    };\n\n} // end namespace Catch\n\n#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n    namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n// end catch_tag_alias_autoregistrar.h\n// start catch_test_registry.h\n\n// start catch_interfaces_testcase.h\n\n#include <vector>\n\nnamespace Catch {\n\n    class TestSpec;\n\n    struct ITestInvoker {\n        virtual void invoke () const = 0;\n        virtual ~ITestInvoker();\n    };\n\n    class TestCase;\n    struct IConfig;\n\n    struct ITestCaseRegistry {\n        virtual ~ITestCaseRegistry();\n        virtual std::vector<TestCase> const& getAllTests() const = 0;\n        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;\n    };\n\n    bool isThrowSafe( TestCase const& testCase, IConfig const& config );\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );\n\n}\n\n// end catch_interfaces_testcase.h\n// start catch_stringref.h\n\n#include <cstddef>\n#include <string>\n#include <iosfwd>\n#include <cassert>\n\nnamespace Catch {\n\n    /// A non-owning string class (similar to the forthcoming std::string_view)\n    /// Note that, because a StringRef may be a substring of another string,\n    /// it may not be null terminated.\n    class StringRef {\n    public:\n        using size_type = std::size_t;\n        using const_iterator = const char*;\n\n    private:\n        static constexpr char const* const s_empty = \"\";\n\n        char const* m_start = s_empty;\n        size_type m_size = 0;\n\n    public: // construction\n        constexpr StringRef() noexcept = default;\n\n        StringRef( char const* rawChars ) noexcept;\n\n        constexpr StringRef( char const* rawChars, size_type size ) noexcept\n        :   m_start( rawChars ),\n            m_size( size )\n        {}\n\n        StringRef( std::string const& stdString ) noexcept\n        :   m_start( stdString.c_str() ),\n            m_size( stdString.size() )\n        {}\n\n        explicit operator std::string() const {\n            return std::string(m_start, m_size);\n        }\n\n    public: // operators\n        auto operator == ( StringRef const& other ) const noexcept -> bool;\n        auto operator != (StringRef const& other) const noexcept -> bool {\n            return !(*this == other);\n        }\n\n        auto operator[] ( size_type index ) const noexcept -> char {\n            assert(index < m_size);\n            return m_start[index];\n        }\n\n    public: // named queries\n        constexpr auto empty() const noexcept -> bool {\n            return m_size == 0;\n        }\n        constexpr auto size() const noexcept -> size_type {\n            return m_size;\n        }\n\n        // Returns the current start pointer. If the StringRef is not\n        // null-terminated, throws std::domain_exception\n        auto c_str() const -> char const*;\n\n    public: // substrings and searches\n        // Returns a substring of [start, start + length).\n        // If start + length > size(), then the substring is [start, size()).\n        // If start > size(), then the substring is empty.\n        auto substr( size_type start, size_type length ) const noexcept -> StringRef;\n\n        // Returns the current start pointer. May not be null-terminated.\n        auto data() const noexcept -> char const*;\n\n        constexpr auto isNullTerminated() const noexcept -> bool {\n            return m_start[m_size] == '\\0';\n        }\n\n    public: // iterators\n        constexpr const_iterator begin() const { return m_start; }\n        constexpr const_iterator end() const { return m_start + m_size; }\n    };\n\n    auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;\n    auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;\n\n    constexpr auto operator \"\" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {\n        return StringRef( rawChars, size );\n    }\n} // namespace Catch\n\nconstexpr auto operator \"\" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {\n    return Catch::StringRef( rawChars, size );\n}\n\n// end catch_stringref.h\n// start catch_preprocessor.hpp\n\n\n#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__\n#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))\n\n#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__\n// MSVC needs more evaluations\n#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))\n#define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))\n#else\n#define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)\n#endif\n\n#define CATCH_REC_END(...)\n#define CATCH_REC_OUT\n\n#define CATCH_EMPTY()\n#define CATCH_DEFER(id) id CATCH_EMPTY()\n\n#define CATCH_REC_GET_END2() 0, CATCH_REC_END\n#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2\n#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1\n#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT\n#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)\n#define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)\n\n#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )\n\n#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...)   f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )\n\n// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,\n// and passes userdata as the first parameter to each invocation,\n// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)\n#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))\n\n#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))\n\n#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)\n#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__\n#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__\n#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF\n#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__\n#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))\n#else\n// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF\n#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)\n#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__\n#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)\n#endif\n\n#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__\n#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)\n\n#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())\n#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))\n#else\n#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))\n#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))\n#endif\n\n#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\\\n    CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)\n\n#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)\n#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)\n#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)\n#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)\n#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)\n#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)\n#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)\n#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)\n#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)\n#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)\n#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)\n\n#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N\n\n#define INTERNAL_CATCH_TYPE_GEN\\\n    template<typename...> struct TypeList {};\\\n    template<typename...Ts>\\\n    constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\\\n    template<template<typename...> class...> struct TemplateTypeList{};\\\n    template<template<typename...> class...Cs>\\\n    constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\\\n    template<typename...>\\\n    struct append;\\\n    template<typename...>\\\n    struct rewrap;\\\n    template<template<typename...> class, typename...>\\\n    struct create;\\\n    template<template<typename...> class, typename>\\\n    struct convert;\\\n    \\\n    template<typename T> \\\n    struct append<T> { using type = T; };\\\n    template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\\\n    struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\\\n    template< template<typename...> class L1, typename...E1, typename...Rest>\\\n    struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\\\n    \\\n    template< template<typename...> class Container, template<typename...> class List, typename...elems>\\\n    struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\\\n    template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\\\n    struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\\\n    \\\n    template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\\\n    struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\\\n    template<template <typename...> class Final, template <typename...> class List, typename...Ts>\\\n    struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };\n\n#define INTERNAL_CATCH_NTTP_1(signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \\\n    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\\\n    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\\\n    constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \\\n    \\\n    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\\\n    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\\\n    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\\\n    template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\\\n    struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };\n\n#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n\n#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n\n#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\\\n    template<typename Type>\\\n    void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\\\n    template<typename Type>\\\n    void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\\\n    template<typename TestType> \\\n    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \\\n        void test();\\\n    }\n\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \\\n    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \\\n        void test();\\\n    }\n\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\\\n    template<typename TestType> \\\n    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \\\n    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_NTTP_0\n#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)\n#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)\n#else\n#define INTERNAL_CATCH_NTTP_0(signature)\n#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))\n#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))\n#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))\n#endif\n\n// end catch_preprocessor.hpp\n// start catch_meta.hpp\n\n\n#include <type_traits>\n\nnamespace Catch {\n    template<typename T>\n    struct always_false : std::false_type {};\n\n    template <typename> struct true_given : std::true_type {};\n    struct is_callable_tester {\n        template <typename Fun, typename... Args>\n        true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);\n        template <typename...>\n        std::false_type static test(...);\n    };\n\n    template <typename T>\n    struct is_callable;\n\n    template <typename Fun, typename... Args>\n    struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};\n\n#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703\n    // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is\n    // replaced with std::invoke_result here.\n    template <typename Func, typename... U>\n    using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;\n#else\n    // Keep ::type here because we still support C++11\n    template <typename Func, typename... U>\n    using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;\n#endif\n\n} // namespace Catch\n\nnamespace mpl_{\n    struct na;\n}\n\n// end catch_meta.hpp\nnamespace Catch {\n\ntemplate<typename C>\nclass TestInvokerAsMethod : public ITestInvoker {\n    void (C::*m_testAsMethod)();\npublic:\n    TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}\n\n    void invoke() const override {\n        C obj;\n        (obj.*m_testAsMethod)();\n    }\n};\n\nauto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;\n\ntemplate<typename C>\nauto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {\n    return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );\n}\n\nstruct NameAndTags {\n    NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;\n    StringRef name;\n    StringRef tags;\n};\n\nstruct AutoReg : NonCopyable {\n    AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;\n    ~AutoReg();\n};\n\n} // end namespace Catch\n\n#if defined(CATCH_CONFIG_DISABLE)\n    #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \\\n        namespace{                        \\\n            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \\\n                void test();              \\\n            };                            \\\n        }                                 \\\n        void TestName::test()\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \\\n        namespace{                                                                                  \\\n            namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \\\n            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\\\n        }                                                                                           \\\n        }                                                                                           \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )\n    #endif\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )\n    #endif\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )\n    #endif\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )\n    #endif\n#endif\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \\\n        static void TestName(); \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE( ... ) \\\n        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, \"&\" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        namespace{ \\\n            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \\\n                void test(); \\\n            }; \\\n            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \\\n        } \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        void TestName::test()\n    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \\\n        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\\\n            INTERNAL_CATCH_TYPE_GEN\\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            template<typename...Types> \\\n            struct TestName{\\\n                TestName(){\\\n                    int index = 0;                                    \\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\\\n                    using expander = int[];\\\n                    (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n            TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\\\n            return 0;\\\n        }();\\\n        }\\\n        }\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \\\n        template<typename TestType> static void TestFuncName();       \\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \\\n            INTERNAL_CATCH_TYPE_GEN                                                  \\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \\\n            template<typename... Types>                               \\\n            struct TestName {                                         \\\n                void reg_tests() {                                          \\\n                    int index = 0;                                    \\\n                    using expander = int[];                           \\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\\\n                    constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\\\n                    constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\\\n                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index / num_types]) + \"<\" + std::string(types_list[index % num_types]) + \">\", Tags } ), index++)... };/* NOLINT */\\\n                }                                                     \\\n            };                                                        \\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \\\n                using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \\\n                TestInit t;                                           \\\n                t.reg_tests();                                        \\\n                return 0;                                             \\\n            }();                                                      \\\n        }                                                             \\\n        }                                                             \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \\\n        template<typename TestType>                                   \\\n        static void TestFuncName()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__)\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__)\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        template<typename TestType> static void TestFunc();       \\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\\\n        INTERNAL_CATCH_TYPE_GEN\\\n        template<typename... Types>                               \\\n        struct TestName {                                         \\\n            void reg_tests() {                                          \\\n                int index = 0;                                    \\\n                using expander = int[];                           \\\n                (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name \" - \" + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + \" - \" + std::to_string(index), Tags } ), index++)... };/* NOLINT */\\\n            }                                                     \\\n        };\\\n        static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \\\n                using TestInit = typename convert<TestName, TmplList>::type; \\\n                TestInit t;                                           \\\n                t.reg_tests();                                        \\\n                return 0;                                             \\\n            }();                                                      \\\n        }}\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \\\n        template<typename TestType>                                   \\\n        static void TestFunc()\n\n    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \\\n        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList )\n\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \\\n            INTERNAL_CATCH_TYPE_GEN\\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\\\n            INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            template<typename...Types> \\\n            struct TestNameClass{\\\n                TestNameClass(){\\\n                    int index = 0;                                    \\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\\\n                    using expander = int[];\\\n                    (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n                TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\\\n                return 0;\\\n        }();\\\n        }\\\n        }\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        template<typename TestType> \\\n            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \\\n                void test();\\\n            };\\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\\\n            INTERNAL_CATCH_TYPE_GEN                  \\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            template<typename...Types>\\\n            struct TestNameClass{\\\n                void reg_tests(){\\\n                    int index = 0;\\\n                    using expander = int[];\\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\\\n                    constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\\\n                    constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\\\n                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index / num_types]) + \"<\" + std::string(types_list[index % num_types]) + \">\", Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n                using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\\\n                TestInit t;\\\n                t.reg_tests();\\\n                return 0;\\\n            }(); \\\n        }\\\n        }\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        template<typename TestType> \\\n        void TestName<TestType>::test()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        template<typename TestType> \\\n        struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \\\n            void test();\\\n        };\\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \\\n            INTERNAL_CATCH_TYPE_GEN\\\n            template<typename...Types>\\\n            struct TestNameClass{\\\n                void reg_tests(){\\\n                    int index = 0;\\\n                    using expander = int[];\\\n                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name \" - \" + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + \" - \" + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n                using TestInit = typename convert<TestNameClass, TmplList>::type;\\\n                TestInit t;\\\n                t.reg_tests();\\\n                return 0;\\\n            }(); \\\n        }}\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        template<typename TestType> \\\n        void TestName<TestType>::test()\n\n#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \\\n        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList )\n\n// end catch_test_registry.h\n// start catch_capture.hpp\n\n// start catch_assertionhandler.h\n\n// start catch_assertioninfo.h\n\n// start catch_result_type.h\n\nnamespace Catch {\n\n    // ResultWas::OfType enum\n    struct ResultWas { enum OfType {\n        Unknown = -1,\n        Ok = 0,\n        Info = 1,\n        Warning = 2,\n\n        FailureBit = 0x10,\n\n        ExpressionFailed = FailureBit | 1,\n        ExplicitFailure = FailureBit | 2,\n\n        Exception = 0x100 | FailureBit,\n\n        ThrewException = Exception | 1,\n        DidntThrowException = Exception | 2,\n\n        FatalErrorCondition = 0x200 | FailureBit\n\n    }; };\n\n    bool isOk( ResultWas::OfType resultType );\n    bool isJustInfo( int flags );\n\n    // ResultDisposition::Flags enum\n    struct ResultDisposition { enum Flags {\n        Normal = 0x01,\n\n        ContinueOnFailure = 0x02,   // Failures fail test, but execution continues\n        FalseTest = 0x04,           // Prefix expression with !\n        SuppressFail = 0x08         // Failures are reported but do not fail the test\n    }; };\n\n    ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );\n\n    bool shouldContinueOnFailure( int flags );\n    inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }\n    bool shouldSuppressFailure( int flags );\n\n} // end namespace Catch\n\n// end catch_result_type.h\nnamespace Catch {\n\n    struct AssertionInfo\n    {\n        StringRef macroName;\n        SourceLineInfo lineInfo;\n        StringRef capturedExpression;\n        ResultDisposition::Flags resultDisposition;\n\n        // We want to delete this constructor but a compiler bug in 4.8 means\n        // the struct is then treated as non-aggregate\n        //AssertionInfo() = delete;\n    };\n\n} // end namespace Catch\n\n// end catch_assertioninfo.h\n// start catch_decomposer.h\n\n// start catch_tostring.h\n\n#include <vector>\n#include <cstddef>\n#include <type_traits>\n#include <string>\n// start catch_stream.h\n\n#include <iosfwd>\n#include <cstddef>\n#include <ostream>\n\nnamespace Catch {\n\n    std::ostream& cout();\n    std::ostream& cerr();\n    std::ostream& clog();\n\n    class StringRef;\n\n    struct IStream {\n        virtual ~IStream();\n        virtual std::ostream& stream() const = 0;\n    };\n\n    auto makeStream( StringRef const &filename ) -> IStream const*;\n\n    class ReusableStringStream : NonCopyable {\n        std::size_t m_index;\n        std::ostream* m_oss;\n    public:\n        ReusableStringStream();\n        ~ReusableStringStream();\n\n        auto str() const -> std::string;\n\n        template<typename T>\n        auto operator << ( T const& value ) -> ReusableStringStream& {\n            *m_oss << value;\n            return *this;\n        }\n        auto get() -> std::ostream& { return *m_oss; }\n    };\n}\n\n// end catch_stream.h\n// start catch_interfaces_enum_values_registry.h\n\n#include <vector>\n\nnamespace Catch {\n\n    namespace Detail {\n        struct EnumInfo {\n            StringRef m_name;\n            std::vector<std::pair<int, StringRef>> m_values;\n\n            ~EnumInfo();\n\n            StringRef lookup( int value ) const;\n        };\n    } // namespace Detail\n\n    struct IMutableEnumValuesRegistry {\n        virtual ~IMutableEnumValuesRegistry();\n\n        virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;\n\n        template<typename E>\n        Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {\n            static_assert(sizeof(int) >= sizeof(E), \"Cannot serialize enum to int\");\n            std::vector<int> intValues;\n            intValues.reserve( values.size() );\n            for( auto enumValue : values )\n                intValues.push_back( static_cast<int>( enumValue ) );\n            return registerEnum( enumName, allEnums, intValues );\n        }\n    };\n\n} // Catch\n\n// end catch_interfaces_enum_values_registry.h\n\n#ifdef CATCH_CONFIG_CPP17_STRING_VIEW\n#include <string_view>\n#endif\n\n#ifdef __OBJC__\n// start catch_objc_arc.hpp\n\n#import <Foundation/Foundation.h>\n\n#ifdef __has_feature\n#define CATCH_ARC_ENABLED __has_feature(objc_arc)\n#else\n#define CATCH_ARC_ENABLED 0\n#endif\n\nvoid arcSafeRelease( NSObject* obj );\nid performOptionalSelector( id obj, SEL sel );\n\n#if !CATCH_ARC_ENABLED\ninline void arcSafeRelease( NSObject* obj ) {\n    [obj release];\n}\ninline id performOptionalSelector( id obj, SEL sel ) {\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED\n#define CATCH_ARC_STRONG\n#else\ninline void arcSafeRelease( NSObject* ){}\ninline id performOptionalSelector( id obj, SEL sel ) {\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n#endif\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained\n#define CATCH_ARC_STRONG __strong\n#endif\n\n// end catch_objc_arc.hpp\n#endif\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless\n#endif\n\nnamespace Catch {\n    namespace Detail {\n\n        extern const std::string unprintableString;\n\n        std::string rawMemoryToString( const void *object, std::size_t size );\n\n        template<typename T>\n        std::string rawMemoryToString( const T& object ) {\n          return rawMemoryToString( &object, sizeof(object) );\n        }\n\n        template<typename T>\n        class IsStreamInsertable {\n            template<typename Stream, typename U>\n            static auto test(int)\n                -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());\n\n            template<typename, typename>\n            static auto test(...)->std::false_type;\n\n        public:\n            static const bool value = decltype(test<std::ostream, const T&>(0))::value;\n        };\n\n        template<typename E>\n        std::string convertUnknownEnumToString( E e );\n\n        template<typename T>\n        typename std::enable_if<\n            !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,\n        std::string>::type convertUnstreamable( T const& ) {\n            return Detail::unprintableString;\n        }\n        template<typename T>\n        typename std::enable_if<\n            !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,\n         std::string>::type convertUnstreamable(T const& ex) {\n            return ex.what();\n        }\n\n        template<typename T>\n        typename std::enable_if<\n            std::is_enum<T>::value\n        , std::string>::type convertUnstreamable( T const& value ) {\n            return convertUnknownEnumToString( value );\n        }\n\n#if defined(_MANAGED)\n        //! Convert a CLR string to a utf8 std::string\n        template<typename T>\n        std::string clrReferenceToString( T^ ref ) {\n            if (ref == nullptr)\n                return std::string(\"null\");\n            auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());\n            cli::pin_ptr<System::Byte> p = &bytes[0];\n            return std::string(reinterpret_cast<char const *>(p), bytes->Length);\n        }\n#endif\n\n    } // namespace Detail\n\n    // If we decide for C++14, change these to enable_if_ts\n    template <typename T, typename = void>\n    struct StringMaker {\n        template <typename Fake = T>\n        static\n        typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type\n            convert(const Fake& value) {\n                ReusableStringStream rss;\n                // NB: call using the function-like syntax to avoid ambiguity with\n                // user-defined templated operator<< under clang.\n                rss.operator<<(value);\n                return rss.str();\n        }\n\n        template <typename Fake = T>\n        static\n        typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type\n            convert( const Fake& value ) {\n#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)\n            return Detail::convertUnstreamable(value);\n#else\n            return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);\n#endif\n        }\n    };\n\n    namespace Detail {\n\n        // This function dispatches all stringification requests inside of Catch.\n        // Should be preferably called fully qualified, like ::Catch::Detail::stringify\n        template <typename T>\n        std::string stringify(const T& e) {\n            return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);\n        }\n\n        template<typename E>\n        std::string convertUnknownEnumToString( E e ) {\n            return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));\n        }\n\n#if defined(_MANAGED)\n        template <typename T>\n        std::string stringify( T^ e ) {\n            return ::Catch::StringMaker<T^>::convert(e);\n        }\n#endif\n\n    } // namespace Detail\n\n    // Some predefined specializations\n\n    template<>\n    struct StringMaker<std::string> {\n        static std::string convert(const std::string& str);\n    };\n\n#ifdef CATCH_CONFIG_CPP17_STRING_VIEW\n    template<>\n    struct StringMaker<std::string_view> {\n        static std::string convert(std::string_view str);\n    };\n#endif\n\n    template<>\n    struct StringMaker<char const *> {\n        static std::string convert(char const * str);\n    };\n    template<>\n    struct StringMaker<char *> {\n        static std::string convert(char * str);\n    };\n\n#ifdef CATCH_CONFIG_WCHAR\n    template<>\n    struct StringMaker<std::wstring> {\n        static std::string convert(const std::wstring& wstr);\n    };\n\n# ifdef CATCH_CONFIG_CPP17_STRING_VIEW\n    template<>\n    struct StringMaker<std::wstring_view> {\n        static std::string convert(std::wstring_view str);\n    };\n# endif\n\n    template<>\n    struct StringMaker<wchar_t const *> {\n        static std::string convert(wchar_t const * str);\n    };\n    template<>\n    struct StringMaker<wchar_t *> {\n        static std::string convert(wchar_t * str);\n    };\n#endif\n\n    // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,\n    //      while keeping string semantics?\n    template<int SZ>\n    struct StringMaker<char[SZ]> {\n        static std::string convert(char const* str) {\n            return ::Catch::Detail::stringify(std::string{ str });\n        }\n    };\n    template<int SZ>\n    struct StringMaker<signed char[SZ]> {\n        static std::string convert(signed char const* str) {\n            return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });\n        }\n    };\n    template<int SZ>\n    struct StringMaker<unsigned char[SZ]> {\n        static std::string convert(unsigned char const* str) {\n            return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });\n        }\n    };\n\n#if defined(CATCH_CONFIG_CPP17_BYTE)\n    template<>\n    struct StringMaker<std::byte> {\n        static std::string convert(std::byte value);\n    };\n#endif // defined(CATCH_CONFIG_CPP17_BYTE)\n    template<>\n    struct StringMaker<int> {\n        static std::string convert(int value);\n    };\n    template<>\n    struct StringMaker<long> {\n        static std::string convert(long value);\n    };\n    template<>\n    struct StringMaker<long long> {\n        static std::string convert(long long value);\n    };\n    template<>\n    struct StringMaker<unsigned int> {\n        static std::string convert(unsigned int value);\n    };\n    template<>\n    struct StringMaker<unsigned long> {\n        static std::string convert(unsigned long value);\n    };\n    template<>\n    struct StringMaker<unsigned long long> {\n        static std::string convert(unsigned long long value);\n    };\n\n    template<>\n    struct StringMaker<bool> {\n        static std::string convert(bool b);\n    };\n\n    template<>\n    struct StringMaker<char> {\n        static std::string convert(char c);\n    };\n    template<>\n    struct StringMaker<signed char> {\n        static std::string convert(signed char c);\n    };\n    template<>\n    struct StringMaker<unsigned char> {\n        static std::string convert(unsigned char c);\n    };\n\n    template<>\n    struct StringMaker<std::nullptr_t> {\n        static std::string convert(std::nullptr_t);\n    };\n\n    template<>\n    struct StringMaker<float> {\n        static std::string convert(float value);\n        static int precision;\n    };\n\n    template<>\n    struct StringMaker<double> {\n        static std::string convert(double value);\n        static int precision;\n    };\n\n    template <typename T>\n    struct StringMaker<T*> {\n        template <typename U>\n        static std::string convert(U* p) {\n            if (p) {\n                return ::Catch::Detail::rawMemoryToString(p);\n            } else {\n                return \"nullptr\";\n            }\n        }\n    };\n\n    template <typename R, typename C>\n    struct StringMaker<R C::*> {\n        static std::string convert(R C::* p) {\n            if (p) {\n                return ::Catch::Detail::rawMemoryToString(p);\n            } else {\n                return \"nullptr\";\n            }\n        }\n    };\n\n#if defined(_MANAGED)\n    template <typename T>\n    struct StringMaker<T^> {\n        static std::string convert( T^ ref ) {\n            return ::Catch::Detail::clrReferenceToString(ref);\n        }\n    };\n#endif\n\n    namespace Detail {\n        template<typename InputIterator, typename Sentinel = InputIterator>\n        std::string rangeToString(InputIterator first, Sentinel last) {\n            ReusableStringStream rss;\n            rss << \"{ \";\n            if (first != last) {\n                rss << ::Catch::Detail::stringify(*first);\n                for (++first; first != last; ++first)\n                    rss << \", \" << ::Catch::Detail::stringify(*first);\n            }\n            rss << \" }\";\n            return rss.str();\n        }\n    }\n\n#ifdef __OBJC__\n    template<>\n    struct StringMaker<NSString*> {\n        static std::string convert(NSString * nsstring) {\n            if (!nsstring)\n                return \"nil\";\n            return std::string(\"@\") + [nsstring UTF8String];\n        }\n    };\n    template<>\n    struct StringMaker<NSObject*> {\n        static std::string convert(NSObject* nsObject) {\n            return ::Catch::Detail::stringify([nsObject description]);\n        }\n\n    };\n    namespace Detail {\n        inline std::string stringify( NSString* nsstring ) {\n            return StringMaker<NSString*>::convert( nsstring );\n        }\n\n    } // namespace Detail\n#endif // __OBJC__\n\n} // namespace Catch\n\n//////////////////////////////////////////////////////\n// Separate std-lib types stringification, so it can be selectively enabled\n// This means that we do not bring in\n\n#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)\n#  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER\n#endif\n\n// Separate std::pair specialization\n#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)\n#include <utility>\nnamespace Catch {\n    template<typename T1, typename T2>\n    struct StringMaker<std::pair<T1, T2> > {\n        static std::string convert(const std::pair<T1, T2>& pair) {\n            ReusableStringStream rss;\n            rss << \"{ \"\n                << ::Catch::Detail::stringify(pair.first)\n                << \", \"\n                << ::Catch::Detail::stringify(pair.second)\n                << \" }\";\n            return rss.str();\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER\n\n#if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)\n#include <optional>\nnamespace Catch {\n    template<typename T>\n    struct StringMaker<std::optional<T> > {\n        static std::string convert(const std::optional<T>& optional) {\n            ReusableStringStream rss;\n            if (optional.has_value()) {\n                rss << ::Catch::Detail::stringify(*optional);\n            } else {\n                rss << \"{ }\";\n            }\n            return rss.str();\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER\n\n// Separate std::tuple specialization\n#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)\n#include <tuple>\nnamespace Catch {\n    namespace Detail {\n        template<\n            typename Tuple,\n            std::size_t N = 0,\n            bool = (N < std::tuple_size<Tuple>::value)\n            >\n            struct TupleElementPrinter {\n            static void print(const Tuple& tuple, std::ostream& os) {\n                os << (N ? \", \" : \" \")\n                    << ::Catch::Detail::stringify(std::get<N>(tuple));\n                TupleElementPrinter<Tuple, N + 1>::print(tuple, os);\n            }\n        };\n\n        template<\n            typename Tuple,\n            std::size_t N\n        >\n            struct TupleElementPrinter<Tuple, N, false> {\n            static void print(const Tuple&, std::ostream&) {}\n        };\n\n    }\n\n    template<typename ...Types>\n    struct StringMaker<std::tuple<Types...>> {\n        static std::string convert(const std::tuple<Types...>& tuple) {\n            ReusableStringStream rss;\n            rss << '{';\n            Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());\n            rss << \" }\";\n            return rss.str();\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER\n\n#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)\n#include <variant>\nnamespace Catch {\n    template<>\n    struct StringMaker<std::monostate> {\n        static std::string convert(const std::monostate&) {\n            return \"{ }\";\n        }\n    };\n\n    template<typename... Elements>\n    struct StringMaker<std::variant<Elements...>> {\n        static std::string convert(const std::variant<Elements...>& variant) {\n            if (variant.valueless_by_exception()) {\n                return \"{valueless variant}\";\n            } else {\n                return std::visit(\n                    [](const auto& value) {\n                        return ::Catch::Detail::stringify(value);\n                    },\n                    variant\n                );\n            }\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER\n\nnamespace Catch {\n    // Import begin/ end from std here\n    using std::begin;\n    using std::end;\n\n    namespace detail {\n        template <typename...>\n        struct void_type {\n            using type = void;\n        };\n\n        template <typename T, typename = void>\n        struct is_range_impl : std::false_type {\n        };\n\n        template <typename T>\n        struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type {\n        };\n    } // namespace detail\n\n    template <typename T>\n    struct is_range : detail::is_range_impl<T> {\n    };\n\n#if defined(_MANAGED) // Managed types are never ranges\n    template <typename T>\n    struct is_range<T^> {\n        static const bool value = false;\n    };\n#endif\n\n    template<typename Range>\n    std::string rangeToString( Range const& range ) {\n        return ::Catch::Detail::rangeToString( begin( range ), end( range ) );\n    }\n\n    // Handle vector<bool> specially\n    template<typename Allocator>\n    std::string rangeToString( std::vector<bool, Allocator> const& v ) {\n        ReusableStringStream rss;\n        rss << \"{ \";\n        bool first = true;\n        for( bool b : v ) {\n            if( first )\n                first = false;\n            else\n                rss << \", \";\n            rss << ::Catch::Detail::stringify( b );\n        }\n        rss << \" }\";\n        return rss.str();\n    }\n\n    template<typename R>\n    struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {\n        static std::string convert( R const& range ) {\n            return rangeToString( range );\n        }\n    };\n\n    template <typename T, int SZ>\n    struct StringMaker<T[SZ]> {\n        static std::string convert(T const(&arr)[SZ]) {\n            return rangeToString(arr);\n        }\n    };\n\n} // namespace Catch\n\n// Separate std::chrono::duration specialization\n#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)\n#include <ctime>\n#include <ratio>\n#include <chrono>\n\nnamespace Catch {\n\ntemplate <class Ratio>\nstruct ratio_string {\n    static std::string symbol();\n};\n\ntemplate <class Ratio>\nstd::string ratio_string<Ratio>::symbol() {\n    Catch::ReusableStringStream rss;\n    rss << '[' << Ratio::num << '/'\n        << Ratio::den << ']';\n    return rss.str();\n}\ntemplate <>\nstruct ratio_string<std::atto> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::femto> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::pico> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::nano> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::micro> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::milli> {\n    static std::string symbol();\n};\n\n    ////////////\n    // std::chrono::duration specializations\n    template<typename Value, typename Ratio>\n    struct StringMaker<std::chrono::duration<Value, Ratio>> {\n        static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';\n            return rss.str();\n        }\n    };\n    template<typename Value>\n    struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {\n        static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << \" s\";\n            return rss.str();\n        }\n    };\n    template<typename Value>\n    struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {\n        static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << \" m\";\n            return rss.str();\n        }\n    };\n    template<typename Value>\n    struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {\n        static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << \" h\";\n            return rss.str();\n        }\n    };\n\n    ////////////\n    // std::chrono::time_point specialization\n    // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>\n    template<typename Clock, typename Duration>\n    struct StringMaker<std::chrono::time_point<Clock, Duration>> {\n        static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {\n            return ::Catch::Detail::stringify(time_point.time_since_epoch()) + \" since epoch\";\n        }\n    };\n    // std::chrono::time_point<system_clock> specialization\n    template<typename Duration>\n    struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {\n        static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {\n            auto converted = std::chrono::system_clock::to_time_t(time_point);\n\n#ifdef _MSC_VER\n            std::tm timeInfo = {};\n            gmtime_s(&timeInfo, &converted);\n#else\n            std::tm* timeInfo = std::gmtime(&converted);\n#endif\n\n            auto const timeStampSize = sizeof(\"2017-01-16T17:06:45Z\");\n            char timeStamp[timeStampSize];\n            const char * const fmt = \"%Y-%m-%dT%H:%M:%SZ\";\n\n#ifdef _MSC_VER\n            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);\n#else\n            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);\n#endif\n            return std::string(timeStamp);\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n\n#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \\\nnamespace Catch { \\\n    template<> struct StringMaker<enumName> { \\\n        static std::string convert( enumName value ) { \\\n            static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \\\n            return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \\\n        } \\\n    }; \\\n}\n\n#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n// end catch_tostring.h\n#include <iosfwd>\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4389) // '==' : signed/unsigned mismatch\n#pragma warning(disable:4018) // more \"signed/unsigned mismatch\"\n#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)\n#pragma warning(disable:4180) // qualifier applied to function type has no meaning\n#pragma warning(disable:4800) // Forcing result to true or false\n#endif\n\nnamespace Catch {\n\n    struct ITransientExpression {\n        auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }\n        auto getResult() const -> bool { return m_result; }\n        virtual void streamReconstructedExpression( std::ostream &os ) const = 0;\n\n        ITransientExpression( bool isBinaryExpression, bool result )\n        :   m_isBinaryExpression( isBinaryExpression ),\n            m_result( result )\n        {}\n\n        // We don't actually need a virtual destructor, but many static analysers\n        // complain if it's not here :-(\n        virtual ~ITransientExpression();\n\n        bool m_isBinaryExpression;\n        bool m_result;\n\n    };\n\n    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );\n\n    template<typename LhsT, typename RhsT>\n    class BinaryExpr  : public ITransientExpression {\n        LhsT m_lhs;\n        StringRef m_op;\n        RhsT m_rhs;\n\n        void streamReconstructedExpression( std::ostream &os ) const override {\n            formatReconstructedExpression\n                    ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );\n        }\n\n    public:\n        BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )\n        :   ITransientExpression{ true, comparisonResult },\n            m_lhs( lhs ),\n            m_op( op ),\n            m_rhs( rhs )\n        {}\n\n        template<typename T>\n        auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n    };\n\n    template<typename LhsT>\n    class UnaryExpr : public ITransientExpression {\n        LhsT m_lhs;\n\n        void streamReconstructedExpression( std::ostream &os ) const override {\n            os << Catch::Detail::stringify( m_lhs );\n        }\n\n    public:\n        explicit UnaryExpr( LhsT lhs )\n        :   ITransientExpression{ false, static_cast<bool>(lhs) },\n            m_lhs( lhs )\n        {}\n    };\n\n    // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)\n    template<typename LhsT, typename RhsT>\n    auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }\n    template<typename T>\n    auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }\n    template<typename T>\n    auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }\n\n    template<typename LhsT, typename RhsT>\n    auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }\n    template<typename T>\n    auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }\n    template<typename T>\n    auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }\n\n    template<typename LhsT>\n    class ExprLhs {\n        LhsT m_lhs;\n    public:\n        explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}\n\n        template<typename RhsT>\n        auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { compareEqual( m_lhs, rhs ), m_lhs, \"==\", rhs };\n        }\n        auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {\n            return { m_lhs == rhs, m_lhs, \"==\", rhs };\n        }\n\n        template<typename RhsT>\n        auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { compareNotEqual( m_lhs, rhs ), m_lhs, \"!=\", rhs };\n        }\n        auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {\n            return { m_lhs != rhs, m_lhs, \"!=\", rhs };\n        }\n\n        template<typename RhsT>\n        auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs > rhs), m_lhs, \">\", rhs };\n        }\n        template<typename RhsT>\n        auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs < rhs), m_lhs, \"<\", rhs };\n        }\n        template<typename RhsT>\n        auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs >= rhs), m_lhs, \">=\", rhs };\n        }\n        template<typename RhsT>\n        auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs <= rhs), m_lhs, \"<=\", rhs };\n        }\n        template <typename RhsT>\n        auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs | rhs), m_lhs, \"|\", rhs };\n        }\n        template <typename RhsT>\n        auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs & rhs), m_lhs, \"&\", rhs };\n        }\n        template <typename RhsT>\n        auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs ^ rhs), m_lhs, \"^\", rhs };\n        }\n\n        template<typename RhsT>\n        auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<RhsT>::value,\n            \"operator&& is not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename RhsT>\n        auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<RhsT>::value,\n            \"operator|| is not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        auto makeUnaryExpr() const -> UnaryExpr<LhsT> {\n            return UnaryExpr<LhsT>{ m_lhs };\n        }\n    };\n\n    void handleExpression( ITransientExpression const& expr );\n\n    template<typename T>\n    void handleExpression( ExprLhs<T> const& expr ) {\n        handleExpression( expr.makeUnaryExpr() );\n    }\n\n    struct Decomposer {\n        template<typename T>\n        auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {\n            return ExprLhs<T const&>{ lhs };\n        }\n\n        auto operator <=( bool value ) -> ExprLhs<bool> {\n            return ExprLhs<bool>{ value };\n        }\n    };\n\n} // end namespace Catch\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n// end catch_decomposer.h\n// start catch_interfaces_capture.h\n\n#include <string>\n#include <chrono>\n\nnamespace Catch {\n\n    class AssertionResult;\n    struct AssertionInfo;\n    struct SectionInfo;\n    struct SectionEndInfo;\n    struct MessageInfo;\n    struct MessageBuilder;\n    struct Counts;\n    struct AssertionReaction;\n    struct SourceLineInfo;\n\n    struct ITransientExpression;\n    struct IGeneratorTracker;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    struct BenchmarkInfo;\n    template <typename Duration = std::chrono::duration<double, std::nano>>\n    struct BenchmarkStats;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    struct IResultCapture {\n\n        virtual ~IResultCapture();\n\n        virtual bool sectionStarted(    SectionInfo const& sectionInfo,\n                                        Counts& assertions ) = 0;\n        virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;\n        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;\n\n        virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        virtual void benchmarkPreparing( std::string const& name ) = 0;\n        virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;\n        virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;\n        virtual void benchmarkFailed( std::string const& error ) = 0;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        virtual void pushScopedMessage( MessageInfo const& message ) = 0;\n        virtual void popScopedMessage( MessageInfo const& message ) = 0;\n\n        virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;\n\n        virtual void handleFatalErrorCondition( StringRef message ) = 0;\n\n        virtual void handleExpr\n                (   AssertionInfo const& info,\n                    ITransientExpression const& expr,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleMessage\n                (   AssertionInfo const& info,\n                    ResultWas::OfType resultType,\n                    StringRef const& message,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleUnexpectedExceptionNotThrown\n                (   AssertionInfo const& info,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleUnexpectedInflightException\n                (   AssertionInfo const& info,\n                    std::string const& message,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleIncomplete\n                (   AssertionInfo const& info ) = 0;\n        virtual void handleNonExpr\n                (   AssertionInfo const &info,\n                    ResultWas::OfType resultType,\n                    AssertionReaction &reaction ) = 0;\n\n        virtual bool lastAssertionPassed() = 0;\n        virtual void assertionPassed() = 0;\n\n        // Deprecated, do not use:\n        virtual std::string getCurrentTestName() const = 0;\n        virtual const AssertionResult* getLastResult() const = 0;\n        virtual void exceptionEarlyReported() = 0;\n    };\n\n    IResultCapture& getResultCapture();\n}\n\n// end catch_interfaces_capture.h\nnamespace Catch {\n\n    struct TestFailureException{};\n    struct AssertionResultData;\n    struct IResultCapture;\n    class RunContext;\n\n    class LazyExpression {\n        friend class AssertionHandler;\n        friend struct AssertionStats;\n        friend class RunContext;\n\n        ITransientExpression const* m_transientExpression = nullptr;\n        bool m_isNegated;\n    public:\n        LazyExpression( bool isNegated );\n        LazyExpression( LazyExpression const& other );\n        LazyExpression& operator = ( LazyExpression const& ) = delete;\n\n        explicit operator bool() const;\n\n        friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;\n    };\n\n    struct AssertionReaction {\n        bool shouldDebugBreak = false;\n        bool shouldThrow = false;\n    };\n\n    class AssertionHandler {\n        AssertionInfo m_assertionInfo;\n        AssertionReaction m_reaction;\n        bool m_completed = false;\n        IResultCapture& m_resultCapture;\n\n    public:\n        AssertionHandler\n            (   StringRef const& macroName,\n                SourceLineInfo const& lineInfo,\n                StringRef capturedExpression,\n                ResultDisposition::Flags resultDisposition );\n        ~AssertionHandler() {\n            if ( !m_completed ) {\n                m_resultCapture.handleIncomplete( m_assertionInfo );\n            }\n        }\n\n        template<typename T>\n        void handleExpr( ExprLhs<T> const& expr ) {\n            handleExpr( expr.makeUnaryExpr() );\n        }\n        void handleExpr( ITransientExpression const& expr );\n\n        void handleMessage(ResultWas::OfType resultType, StringRef const& message);\n\n        void handleExceptionThrownAsExpected();\n        void handleUnexpectedExceptionNotThrown();\n        void handleExceptionNotThrownAsExpected();\n        void handleThrowingCallSkipped();\n        void handleUnexpectedInflightException();\n\n        void complete();\n        void setCompleted();\n\n        // query\n        auto allowThrows() const -> bool;\n    };\n\n    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );\n\n} // namespace Catch\n\n// end catch_assertionhandler.h\n// start catch_message.h\n\n#include <string>\n#include <vector>\n\nnamespace Catch {\n\n    struct MessageInfo {\n        MessageInfo(    StringRef const& _macroName,\n                        SourceLineInfo const& _lineInfo,\n                        ResultWas::OfType _type );\n\n        StringRef macroName;\n        std::string message;\n        SourceLineInfo lineInfo;\n        ResultWas::OfType type;\n        unsigned int sequence;\n\n        bool operator == ( MessageInfo const& other ) const;\n        bool operator < ( MessageInfo const& other ) const;\n    private:\n        static unsigned int globalCount;\n    };\n\n    struct MessageStream {\n\n        template<typename T>\n        MessageStream& operator << ( T const& value ) {\n            m_stream << value;\n            return *this;\n        }\n\n        ReusableStringStream m_stream;\n    };\n\n    struct MessageBuilder : MessageStream {\n        MessageBuilder( StringRef const& macroName,\n                        SourceLineInfo const& lineInfo,\n                        ResultWas::OfType type );\n\n        template<typename T>\n        MessageBuilder& operator << ( T const& value ) {\n            m_stream << value;\n            return *this;\n        }\n\n        MessageInfo m_info;\n    };\n\n    class ScopedMessage {\n    public:\n        explicit ScopedMessage( MessageBuilder const& builder );\n        ScopedMessage( ScopedMessage& duplicate ) = delete;\n        ScopedMessage( ScopedMessage&& old );\n        ~ScopedMessage();\n\n        MessageInfo m_info;\n        bool m_moved;\n    };\n\n    class Capturer {\n        std::vector<MessageInfo> m_messages;\n        IResultCapture& m_resultCapture = getResultCapture();\n        size_t m_captured = 0;\n    public:\n        Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );\n        ~Capturer();\n\n        void captureValue( size_t index, std::string const& value );\n\n        template<typename T>\n        void captureValues( size_t index, T const& value ) {\n            captureValue( index, Catch::Detail::stringify( value ) );\n        }\n\n        template<typename T, typename... Ts>\n        void captureValues( size_t index, T const& value, Ts const&... values ) {\n            captureValue( index, Catch::Detail::stringify(value) );\n            captureValues( index+1, values... );\n        }\n    };\n\n} // end namespace Catch\n\n// end catch_message.h\n#if !defined(CATCH_CONFIG_DISABLE)\n\n#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)\n  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__\n#else\n  #define CATCH_INTERNAL_STRINGIFY(...) \"Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION\"\n#endif\n\n#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n\n///////////////////////////////////////////////////////////////////////////////\n// Another way to speed-up compilation is to omit local try-catch for REQUIRE*\n// macros.\n#define INTERNAL_CATCH_TRY\n#define INTERNAL_CATCH_CATCH( capturer )\n\n#else // CATCH_CONFIG_FAST_COMPILE\n\n#define INTERNAL_CATCH_TRY try\n#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }\n\n#endif\n\n#define INTERNAL_CATCH_REACT( handler ) handler.complete();\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \\\n    do { \\\n        CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \\\n        INTERNAL_CATCH_TRY { \\\n            CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n            CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \\\n            catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \\\n            CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \\\n    INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \\\n    if( Catch::getResultCapture().lastAssertionPassed() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \\\n    INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \\\n    if( !Catch::getResultCapture().lastAssertionPassed() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \\\n        try { \\\n            static_cast<void>(__VA_ARGS__); \\\n            catchAssertionHandler.handleExceptionNotThrownAsExpected(); \\\n        } \\\n        catch( ... ) { \\\n            catchAssertionHandler.handleUnexpectedInflightException(); \\\n        } \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(__VA_ARGS__); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( ... ) { \\\n                catchAssertionHandler.handleExceptionThrownAsExpected(); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) \", \" CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(expr); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( exceptionType const& ) { \\\n                catchAssertionHandler.handleExceptionThrownAsExpected(); \\\n            } \\\n            catch( ... ) { \\\n                catchAssertionHandler.handleUnexpectedInflightException(); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \\\n        catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \\\n    auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \\\n    varName.captureValues( 0, __VA_ARGS__ )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_INFO( macroName, log ) \\\n    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \\\n    Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )\n\n///////////////////////////////////////////////////////////////////////////////\n// Although this is matcher-based, it can be used with just a string\n#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) \", \" CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(__VA_ARGS__); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( ... ) { \\\n                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n#endif // CATCH_CONFIG_DISABLE\n\n// end catch_capture.hpp\n// start catch_section.h\n\n// start catch_section_info.h\n\n// start catch_totals.h\n\n#include <cstddef>\n\nnamespace Catch {\n\n    struct Counts {\n        Counts operator - ( Counts const& other ) const;\n        Counts& operator += ( Counts const& other );\n\n        std::size_t total() const;\n        bool allPassed() const;\n        bool allOk() const;\n\n        std::size_t passed = 0;\n        std::size_t failed = 0;\n        std::size_t failedButOk = 0;\n    };\n\n    struct Totals {\n\n        Totals operator - ( Totals const& other ) const;\n        Totals& operator += ( Totals const& other );\n\n        Totals delta( Totals const& prevTotals ) const;\n\n        int error = 0;\n        Counts assertions;\n        Counts testCases;\n    };\n}\n\n// end catch_totals.h\n#include <string>\n\nnamespace Catch {\n\n    struct SectionInfo {\n        SectionInfo\n            (   SourceLineInfo const& _lineInfo,\n                std::string const& _name );\n\n        // Deprecated\n        SectionInfo\n            (   SourceLineInfo const& _lineInfo,\n                std::string const& _name,\n                std::string const& ) : SectionInfo( _lineInfo, _name ) {}\n\n        std::string name;\n        std::string description; // !Deprecated: this will always be empty\n        SourceLineInfo lineInfo;\n    };\n\n    struct SectionEndInfo {\n        SectionInfo sectionInfo;\n        Counts prevAssertions;\n        double durationInSeconds;\n    };\n\n} // end namespace Catch\n\n// end catch_section_info.h\n// start catch_timer.h\n\n#include <cstdint>\n\nnamespace Catch {\n\n    auto getCurrentNanosecondsSinceEpoch() -> uint64_t;\n    auto getEstimatedClockResolution() -> uint64_t;\n\n    class Timer {\n        uint64_t m_nanoseconds = 0;\n    public:\n        void start();\n        auto getElapsedNanoseconds() const -> uint64_t;\n        auto getElapsedMicroseconds() const -> uint64_t;\n        auto getElapsedMilliseconds() const -> unsigned int;\n        auto getElapsedSeconds() const -> double;\n    };\n\n} // namespace Catch\n\n// end catch_timer.h\n#include <string>\n\nnamespace Catch {\n\n    class Section : NonCopyable {\n    public:\n        Section( SectionInfo const& info );\n        ~Section();\n\n        // This indicates whether the section should be executed or not\n        explicit operator bool() const;\n\n    private:\n        SectionInfo m_info;\n\n        std::string m_name;\n        Counts m_assertions;\n        bool m_sectionIncluded;\n        Timer m_timer;\n    };\n\n} // end namespace Catch\n\n#define INTERNAL_CATCH_SECTION( ... ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \\\n    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \\\n    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n// end catch_section.h\n// start catch_interfaces_exception.h\n\n// start catch_interfaces_registry_hub.h\n\n#include <string>\n#include <memory>\n\nnamespace Catch {\n\n    class TestCase;\n    struct ITestCaseRegistry;\n    struct IExceptionTranslatorRegistry;\n    struct IExceptionTranslator;\n    struct IReporterRegistry;\n    struct IReporterFactory;\n    struct ITagAliasRegistry;\n    struct IMutableEnumValuesRegistry;\n\n    class StartupExceptionRegistry;\n\n    using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;\n\n    struct IRegistryHub {\n        virtual ~IRegistryHub();\n\n        virtual IReporterRegistry const& getReporterRegistry() const = 0;\n        virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;\n        virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;\n        virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;\n\n        virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;\n    };\n\n    struct IMutableRegistryHub {\n        virtual ~IMutableRegistryHub();\n        virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;\n        virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;\n        virtual void registerTest( TestCase const& testInfo ) = 0;\n        virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;\n        virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;\n        virtual void registerStartupException() noexcept = 0;\n        virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;\n    };\n\n    IRegistryHub const& getRegistryHub();\n    IMutableRegistryHub& getMutableRegistryHub();\n    void cleanUp();\n    std::string translateActiveException();\n\n}\n\n// end catch_interfaces_registry_hub.h\n#if defined(CATCH_CONFIG_DISABLE)\n    #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \\\n        static std::string translatorName( signature )\n#endif\n\n#include <exception>\n#include <string>\n#include <vector>\n\nnamespace Catch {\n    using exceptionTranslateFunction = std::string(*)();\n\n    struct IExceptionTranslator;\n    using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;\n\n    struct IExceptionTranslator {\n        virtual ~IExceptionTranslator();\n        virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;\n    };\n\n    struct IExceptionTranslatorRegistry {\n        virtual ~IExceptionTranslatorRegistry();\n\n        virtual std::string translateActiveException() const = 0;\n    };\n\n    class ExceptionTranslatorRegistrar {\n        template<typename T>\n        class ExceptionTranslator : public IExceptionTranslator {\n        public:\n\n            ExceptionTranslator( std::string(*translateFunction)( T& ) )\n            : m_translateFunction( translateFunction )\n            {}\n\n            std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n                return \"\";\n#else\n                try {\n                    if( it == itEnd )\n                        std::rethrow_exception(std::current_exception());\n                    else\n                        return (*it)->translate( it+1, itEnd );\n                }\n                catch( T& ex ) {\n                    return m_translateFunction( ex );\n                }\n#endif\n            }\n\n        protected:\n            std::string(*m_translateFunction)( T& );\n        };\n\n    public:\n        template<typename T>\n        ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {\n            getMutableRegistryHub().registerTranslator\n                ( new ExceptionTranslator<T>( translateFunction ) );\n        }\n    };\n}\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \\\n    static std::string translatorName( signature ); \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n    static std::string translatorName( signature )\n\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )\n\n// end catch_interfaces_exception.h\n// start catch_approx.h\n\n#include <type_traits>\n\nnamespace Catch {\nnamespace Detail {\n\n    class Approx {\n    private:\n        bool equalityComparisonImpl(double other) const;\n        // Validates the new margin (margin >= 0)\n        // out-of-line to avoid including stdexcept in the header\n        void setMargin(double margin);\n        // Validates the new epsilon (0 < epsilon < 1)\n        // out-of-line to avoid including stdexcept in the header\n        void setEpsilon(double epsilon);\n\n    public:\n        explicit Approx ( double value );\n\n        static Approx custom();\n\n        Approx operator-() const;\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx operator()( T const& value ) const {\n            Approx approx( static_cast<double>(value) );\n            approx.m_epsilon = m_epsilon;\n            approx.m_margin = m_margin;\n            approx.m_scale = m_scale;\n            return approx;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        explicit Approx( T const& value ): Approx(static_cast<double>(value))\n        {}\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator == ( const T& lhs, Approx const& rhs ) {\n            auto lhs_v = static_cast<double>(lhs);\n            return rhs.equalityComparisonImpl(lhs_v);\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator == ( Approx const& lhs, const T& rhs ) {\n            return operator==( rhs, lhs );\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator != ( T const& lhs, Approx const& rhs ) {\n            return !operator==( lhs, rhs );\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator != ( Approx const& lhs, T const& rhs ) {\n            return !operator==( rhs, lhs );\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator <= ( T const& lhs, Approx const& rhs ) {\n            return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator <= ( Approx const& lhs, T const& rhs ) {\n            return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator >= ( T const& lhs, Approx const& rhs ) {\n            return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator >= ( Approx const& lhs, T const& rhs ) {\n            return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx& epsilon( T const& newEpsilon ) {\n            double epsilonAsDouble = static_cast<double>(newEpsilon);\n            setEpsilon(epsilonAsDouble);\n            return *this;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx& margin( T const& newMargin ) {\n            double marginAsDouble = static_cast<double>(newMargin);\n            setMargin(marginAsDouble);\n            return *this;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx& scale( T const& newScale ) {\n            m_scale = static_cast<double>(newScale);\n            return *this;\n        }\n\n        std::string toString() const;\n\n    private:\n        double m_epsilon;\n        double m_margin;\n        double m_scale;\n        double m_value;\n    };\n} // end namespace Detail\n\nnamespace literals {\n    Detail::Approx operator \"\" _a(long double val);\n    Detail::Approx operator \"\" _a(unsigned long long val);\n} // end namespace literals\n\ntemplate<>\nstruct StringMaker<Catch::Detail::Approx> {\n    static std::string convert(Catch::Detail::Approx const& value);\n};\n\n} // end namespace Catch\n\n// end catch_approx.h\n// start catch_string_manip.h\n\n#include <string>\n#include <iosfwd>\n#include <vector>\n\nnamespace Catch {\n\n    bool startsWith( std::string const& s, std::string const& prefix );\n    bool startsWith( std::string const& s, char prefix );\n    bool endsWith( std::string const& s, std::string const& suffix );\n    bool endsWith( std::string const& s, char suffix );\n    bool contains( std::string const& s, std::string const& infix );\n    void toLowerInPlace( std::string& s );\n    std::string toLower( std::string const& s );\n    //! Returns a new string without whitespace at the start/end\n    std::string trim( std::string const& str );\n    //! Returns a substring of the original ref without whitespace. Beware lifetimes!\n    StringRef trim(StringRef ref);\n\n    // !!! Be aware, returns refs into original string - make sure original string outlives them\n    std::vector<StringRef> splitStringRef( StringRef str, char delimiter );\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );\n\n    struct pluralise {\n        pluralise( std::size_t count, std::string const& label );\n\n        friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );\n\n        std::size_t m_count;\n        std::string m_label;\n    };\n}\n\n// end catch_string_manip.h\n#ifndef CATCH_CONFIG_DISABLE_MATCHERS\n// start catch_capture_matchers.h\n\n// start catch_matchers.h\n\n#include <string>\n#include <vector>\n\nnamespace Catch {\nnamespace Matchers {\n    namespace Impl {\n\n        template<typename ArgT> struct MatchAllOf;\n        template<typename ArgT> struct MatchAnyOf;\n        template<typename ArgT> struct MatchNotOf;\n\n        class MatcherUntypedBase {\n        public:\n            MatcherUntypedBase() = default;\n            MatcherUntypedBase ( MatcherUntypedBase const& ) = default;\n            MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;\n            std::string toString() const;\n\n        protected:\n            virtual ~MatcherUntypedBase();\n            virtual std::string describe() const = 0;\n            mutable std::string m_cachedToString;\n        };\n\n#ifdef __clang__\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wnon-virtual-dtor\"\n#endif\n\n        template<typename ObjectT>\n        struct MatcherMethod {\n            virtual bool match( ObjectT const& arg ) const = 0;\n        };\n\n#if defined(__OBJC__)\n        // Hack to fix Catch GH issue #1661. Could use id for generic Object support.\n        // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation\n        template<>\n        struct MatcherMethod<NSString*> {\n            virtual bool match( NSString* arg ) const = 0;\n        };\n#endif\n\n#ifdef __clang__\n#    pragma clang diagnostic pop\n#endif\n\n        template<typename T>\n        struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {\n\n            MatchAllOf<T> operator && ( MatcherBase const& other ) const;\n            MatchAnyOf<T> operator || ( MatcherBase const& other ) const;\n            MatchNotOf<T> operator ! () const;\n        };\n\n        template<typename ArgT>\n        struct MatchAllOf : MatcherBase<ArgT> {\n            bool match( ArgT const& arg ) const override {\n                for( auto matcher : m_matchers ) {\n                    if (!matcher->match(arg))\n                        return false;\n                }\n                return true;\n            }\n            std::string describe() const override {\n                std::string description;\n                description.reserve( 4 + m_matchers.size()*32 );\n                description += \"( \";\n                bool first = true;\n                for( auto matcher : m_matchers ) {\n                    if( first )\n                        first = false;\n                    else\n                        description += \" and \";\n                    description += matcher->toString();\n                }\n                description += \" )\";\n                return description;\n            }\n\n            MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {\n                auto copy(*this);\n                copy.m_matchers.push_back( &other );\n                return copy;\n            }\n\n            std::vector<MatcherBase<ArgT> const*> m_matchers;\n        };\n        template<typename ArgT>\n        struct MatchAnyOf : MatcherBase<ArgT> {\n\n            bool match( ArgT const& arg ) const override {\n                for( auto matcher : m_matchers ) {\n                    if (matcher->match(arg))\n                        return true;\n                }\n                return false;\n            }\n            std::string describe() const override {\n                std::string description;\n                description.reserve( 4 + m_matchers.size()*32 );\n                description += \"( \";\n                bool first = true;\n                for( auto matcher : m_matchers ) {\n                    if( first )\n                        first = false;\n                    else\n                        description += \" or \";\n                    description += matcher->toString();\n                }\n                description += \" )\";\n                return description;\n            }\n\n            MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {\n                auto copy(*this);\n                copy.m_matchers.push_back( &other );\n                return copy;\n            }\n\n            std::vector<MatcherBase<ArgT> const*> m_matchers;\n        };\n\n        template<typename ArgT>\n        struct MatchNotOf : MatcherBase<ArgT> {\n\n            MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}\n\n            bool match( ArgT const& arg ) const override {\n                return !m_underlyingMatcher.match( arg );\n            }\n\n            std::string describe() const override {\n                return \"not \" + m_underlyingMatcher.toString();\n            }\n            MatcherBase<ArgT> const& m_underlyingMatcher;\n        };\n\n        template<typename T>\n        MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {\n            return MatchAllOf<T>() && *this && other;\n        }\n        template<typename T>\n        MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {\n            return MatchAnyOf<T>() || *this || other;\n        }\n        template<typename T>\n        MatchNotOf<T> MatcherBase<T>::operator ! () const {\n            return MatchNotOf<T>( *this );\n        }\n\n    } // namespace Impl\n\n} // namespace Matchers\n\nusing namespace Matchers;\nusing Matchers::Impl::MatcherBase;\n\n} // namespace Catch\n\n// end catch_matchers.h\n// start catch_matchers_exception.hpp\n\nnamespace Catch {\nnamespace Matchers {\nnamespace Exception {\n\nclass ExceptionMessageMatcher : public MatcherBase<std::exception> {\n    std::string m_message;\npublic:\n\n    ExceptionMessageMatcher(std::string const& message):\n        m_message(message)\n    {}\n\n    bool match(std::exception const& ex) const override;\n\n    std::string describe() const override;\n};\n\n} // namespace Exception\n\nException::ExceptionMessageMatcher Message(std::string const& message);\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_exception.hpp\n// start catch_matchers_floating.h\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace Floating {\n\n        enum class FloatingPointKind : uint8_t;\n\n        struct WithinAbsMatcher : MatcherBase<double> {\n            WithinAbsMatcher(double target, double margin);\n            bool match(double const& matchee) const override;\n            std::string describe() const override;\n        private:\n            double m_target;\n            double m_margin;\n        };\n\n        struct WithinUlpsMatcher : MatcherBase<double> {\n            WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);\n            bool match(double const& matchee) const override;\n            std::string describe() const override;\n        private:\n            double m_target;\n            uint64_t m_ulps;\n            FloatingPointKind m_type;\n        };\n\n        // Given IEEE-754 format for floats and doubles, we can assume\n        // that float -> double promotion is lossless. Given this, we can\n        // assume that if we do the standard relative comparison of\n        // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get\n        // the same result if we do this for floats, as if we do this for\n        // doubles that were promoted from floats.\n        struct WithinRelMatcher : MatcherBase<double> {\n            WithinRelMatcher(double target, double epsilon);\n            bool match(double const& matchee) const override;\n            std::string describe() const override;\n        private:\n            double m_target;\n            double m_epsilon;\n        };\n\n    } // namespace Floating\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n    Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);\n    Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);\n    Floating::WithinAbsMatcher WithinAbs(double target, double margin);\n    Floating::WithinRelMatcher WithinRel(double target, double eps);\n    // defaults epsilon to 100*numeric_limits<double>::epsilon()\n    Floating::WithinRelMatcher WithinRel(double target);\n    Floating::WithinRelMatcher WithinRel(float target, float eps);\n    // defaults epsilon to 100*numeric_limits<float>::epsilon()\n    Floating::WithinRelMatcher WithinRel(float target);\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_floating.h\n// start catch_matchers_generic.hpp\n\n#include <functional>\n#include <string>\n\nnamespace Catch {\nnamespace Matchers {\nnamespace Generic {\n\nnamespace Detail {\n    std::string finalizeDescription(const std::string& desc);\n}\n\ntemplate <typename T>\nclass PredicateMatcher : public MatcherBase<T> {\n    std::function<bool(T const&)> m_predicate;\n    std::string m_description;\npublic:\n\n    PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)\n        :m_predicate(std::move(elem)),\n        m_description(Detail::finalizeDescription(descr))\n    {}\n\n    bool match( T const& item ) const override {\n        return m_predicate(item);\n    }\n\n    std::string describe() const override {\n        return m_description;\n    }\n};\n\n} // namespace Generic\n\n    // The following functions create the actual matcher objects.\n    // The user has to explicitly specify type to the function, because\n    // inferring std::function<bool(T const&)> is hard (but possible) and\n    // requires a lot of TMP.\n    template<typename T>\n    Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = \"\") {\n        return Generic::PredicateMatcher<T>(predicate, description);\n    }\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_generic.hpp\n// start catch_matchers_string.h\n\n#include <string>\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace StdString {\n\n        struct CasedString\n        {\n            CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );\n            std::string adjustString( std::string const& str ) const;\n            std::string caseSensitivitySuffix() const;\n\n            CaseSensitive::Choice m_caseSensitivity;\n            std::string m_str;\n        };\n\n        struct StringMatcherBase : MatcherBase<std::string> {\n            StringMatcherBase( std::string const& operation, CasedString const& comparator );\n            std::string describe() const override;\n\n            CasedString m_comparator;\n            std::string m_operation;\n        };\n\n        struct EqualsMatcher : StringMatcherBase {\n            EqualsMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n        struct ContainsMatcher : StringMatcherBase {\n            ContainsMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n        struct StartsWithMatcher : StringMatcherBase {\n            StartsWithMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n        struct EndsWithMatcher : StringMatcherBase {\n            EndsWithMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n\n        struct RegexMatcher : MatcherBase<std::string> {\n            RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );\n            bool match( std::string const& matchee ) const override;\n            std::string describe() const override;\n\n        private:\n            std::string m_regex;\n            CaseSensitive::Choice m_caseSensitivity;\n        };\n\n    } // namespace StdString\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n\n    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_string.h\n// start catch_matchers_vector.h\n\n#include <algorithm>\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace Vector {\n        template<typename T, typename Alloc>\n        struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {\n\n            ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}\n\n            bool match(std::vector<T, Alloc> const &v) const override {\n                for (auto const& el : v) {\n                    if (el == m_comparator) {\n                        return true;\n                    }\n                }\n                return false;\n            }\n\n            std::string describe() const override {\n                return \"Contains: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n\n            T const& m_comparator;\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n\n            ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}\n\n            bool match(std::vector<T, AllocMatch> const &v) const override {\n                // !TBD: see note in EqualsMatcher\n                if (m_comparator.size() > v.size())\n                    return false;\n                for (auto const& comparator : m_comparator) {\n                    auto present = false;\n                    for (const auto& el : v) {\n                        if (el == comparator) {\n                            present = true;\n                            break;\n                        }\n                    }\n                    if (!present) {\n                        return false;\n                    }\n                }\n                return true;\n            }\n            std::string describe() const override {\n                return \"Contains: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n\n            std::vector<T, AllocComp> const& m_comparator;\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n\n            EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}\n\n            bool match(std::vector<T, AllocMatch> const &v) const override {\n                // !TBD: This currently works if all elements can be compared using !=\n                // - a more general approach would be via a compare template that defaults\n                // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc\n                // - then just call that directly\n                if (m_comparator.size() != v.size())\n                    return false;\n                for (std::size_t i = 0; i < v.size(); ++i)\n                    if (m_comparator[i] != v[i])\n                        return false;\n                return true;\n            }\n            std::string describe() const override {\n                return \"Equals: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n            std::vector<T, AllocComp> const& m_comparator;\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n\n            ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}\n\n            bool match(std::vector<T, AllocMatch> const &v) const override {\n                if (m_comparator.size() != v.size())\n                    return false;\n                for (std::size_t i = 0; i < v.size(); ++i)\n                    if (m_comparator[i] != approx(v[i]))\n                        return false;\n                return true;\n            }\n            std::string describe() const override {\n                return \"is approx: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n            ApproxMatcher& epsilon( T const& newEpsilon ) {\n                approx.epsilon(newEpsilon);\n                return *this;\n            }\n            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n            ApproxMatcher& margin( T const& newMargin ) {\n                approx.margin(newMargin);\n                return *this;\n            }\n            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n            ApproxMatcher& scale( T const& newScale ) {\n                approx.scale(newScale);\n                return *this;\n            }\n\n            std::vector<T, AllocComp> const& m_comparator;\n            mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n            UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}\n            bool match(std::vector<T, AllocMatch> const& vec) const override {\n                if (m_target.size() != vec.size()) {\n                    return false;\n                }\n                return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());\n            }\n\n            std::string describe() const override {\n                return \"UnorderedEquals: \" + ::Catch::Detail::stringify(m_target);\n            }\n        private:\n            std::vector<T, AllocComp> const& m_target;\n        };\n\n    } // namespace Vector\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {\n        return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator );\n    }\n\n    template<typename T, typename Alloc = std::allocator<T>>\n    Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {\n        return Vector::ContainsElementMatcher<T, Alloc>( comparator );\n    }\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {\n        return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator );\n    }\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {\n        return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator );\n    }\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {\n        return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target );\n    }\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_vector.h\nnamespace Catch {\n\n    template<typename ArgT, typename MatcherT>\n    class MatchExpr : public ITransientExpression {\n        ArgT const& m_arg;\n        MatcherT m_matcher;\n        StringRef m_matcherString;\n    public:\n        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )\n        :   ITransientExpression{ true, matcher.match( arg ) },\n            m_arg( arg ),\n            m_matcher( matcher ),\n            m_matcherString( matcherString )\n        {}\n\n        void streamReconstructedExpression( std::ostream &os ) const override {\n            auto matcherAsString = m_matcher.toString();\n            os << Catch::Detail::stringify( m_arg ) << ' ';\n            if( matcherAsString == Detail::unprintableString )\n                os << m_matcherString;\n            else\n                os << matcherAsString;\n        }\n    };\n\n    using StringMatcher = Matchers::Impl::MatcherBase<std::string>;\n\n    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );\n\n    template<typename ArgT, typename MatcherT>\n    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {\n        return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );\n    }\n\n} // namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) \", \" CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \\\n        INTERNAL_CATCH_TRY { \\\n            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \\\n        } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) \", \" CATCH_INTERNAL_STRINGIFY(exceptionType) \", \" CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(__VA_ARGS__ ); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( exceptionType const& ex ) { \\\n                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \\\n            } \\\n            catch( ... ) { \\\n                catchAssertionHandler.handleUnexpectedInflightException(); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n// end catch_capture_matchers.h\n#endif\n// start catch_generators.hpp\n\n// start catch_interfaces_generatortracker.h\n\n\n#include <memory>\n\nnamespace Catch {\n\n    namespace Generators {\n        class GeneratorUntypedBase {\n        public:\n            GeneratorUntypedBase() = default;\n            virtual ~GeneratorUntypedBase();\n            // Attempts to move the generator to the next element\n             //\n             // Returns true iff the move succeeded (and a valid element\n             // can be retrieved).\n            virtual bool next() = 0;\n        };\n        using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;\n\n    } // namespace Generators\n\n    struct IGeneratorTracker {\n        virtual ~IGeneratorTracker();\n        virtual auto hasGenerator() const -> bool = 0;\n        virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;\n        virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;\n    };\n\n} // namespace Catch\n\n// end catch_interfaces_generatortracker.h\n// start catch_enforce.h\n\n#include <exception>\n\nnamespace Catch {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n    template <typename Ex>\n    [[noreturn]]\n    void throw_exception(Ex const& e) {\n        throw e;\n    }\n#else // ^^ Exceptions are enabled //  Exceptions are disabled vv\n    [[noreturn]]\n    void throw_exception(std::exception const& e);\n#endif\n\n    [[noreturn]]\n    void throw_logic_error(std::string const& msg);\n    [[noreturn]]\n    void throw_domain_error(std::string const& msg);\n    [[noreturn]]\n    void throw_runtime_error(std::string const& msg);\n\n} // namespace Catch;\n\n#define CATCH_MAKE_MSG(...) \\\n    (Catch::ReusableStringStream() << __VA_ARGS__).str()\n\n#define CATCH_INTERNAL_ERROR(...) \\\n    Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << \": Internal Catch2 error: \" << __VA_ARGS__))\n\n#define CATCH_ERROR(...) \\\n    Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))\n\n#define CATCH_RUNTIME_ERROR(...) \\\n    Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))\n\n#define CATCH_ENFORCE( condition, ... ) \\\n    do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)\n\n// end catch_enforce.h\n#include <memory>\n#include <vector>\n#include <cassert>\n\n#include <utility>\n#include <exception>\n\nnamespace Catch {\n\nclass GeneratorException : public std::exception {\n    const char* const m_msg = \"\";\n\npublic:\n    GeneratorException(const char* msg):\n        m_msg(msg)\n    {}\n\n    const char* what() const noexcept override final;\n};\n\nnamespace Generators {\n\n    // !TBD move this into its own location?\n    namespace pf{\n        template<typename T, typename... Args>\n        std::unique_ptr<T> make_unique( Args&&... args ) {\n            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));\n        }\n    }\n\n    template<typename T>\n    struct IGenerator : GeneratorUntypedBase {\n        virtual ~IGenerator() = default;\n\n        // Returns the current element of the generator\n        //\n        // \\Precondition The generator is either freshly constructed,\n        // or the last call to `next()` returned true\n        virtual T const& get() const = 0;\n        using type = T;\n    };\n\n    template<typename T>\n    class SingleValueGenerator final : public IGenerator<T> {\n        T m_value;\n    public:\n        SingleValueGenerator(T&& value) : m_value(std::move(value)) {}\n\n        T const& get() const override {\n            return m_value;\n        }\n        bool next() override {\n            return false;\n        }\n    };\n\n    template<typename T>\n    class FixedValuesGenerator final : public IGenerator<T> {\n        static_assert(!std::is_same<T, bool>::value,\n            \"FixedValuesGenerator does not support bools because of std::vector<bool>\"\n            \"specialization, use SingleValue Generator instead.\");\n        std::vector<T> m_values;\n        size_t m_idx = 0;\n    public:\n        FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}\n\n        T const& get() const override {\n            return m_values[m_idx];\n        }\n        bool next() override {\n            ++m_idx;\n            return m_idx < m_values.size();\n        }\n    };\n\n    template <typename T>\n    class GeneratorWrapper final {\n        std::unique_ptr<IGenerator<T>> m_generator;\n    public:\n        GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):\n            m_generator(std::move(generator))\n        {}\n        T const& get() const {\n            return m_generator->get();\n        }\n        bool next() {\n            return m_generator->next();\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<T> value(T&& value) {\n        return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));\n    }\n    template <typename T>\n    GeneratorWrapper<T> values(std::initializer_list<T> values) {\n        return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));\n    }\n\n    template<typename T>\n    class Generators : public IGenerator<T> {\n        std::vector<GeneratorWrapper<T>> m_generators;\n        size_t m_current = 0;\n\n        void populate(GeneratorWrapper<T>&& generator) {\n            m_generators.emplace_back(std::move(generator));\n        }\n        void populate(T&& val) {\n            m_generators.emplace_back(value(std::forward<T>(val)));\n        }\n        template<typename U>\n        void populate(U&& val) {\n            populate(T(std::forward<U>(val)));\n        }\n        template<typename U, typename... Gs>\n        void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {\n            populate(std::forward<U>(valueOrGenerator));\n            populate(std::forward<Gs>(moreGenerators)...);\n        }\n\n    public:\n        template <typename... Gs>\n        Generators(Gs &&... moreGenerators) {\n            m_generators.reserve(sizeof...(Gs));\n            populate(std::forward<Gs>(moreGenerators)...);\n        }\n\n        T const& get() const override {\n            return m_generators[m_current].get();\n        }\n\n        bool next() override {\n            if (m_current >= m_generators.size()) {\n                return false;\n            }\n            const bool current_status = m_generators[m_current].next();\n            if (!current_status) {\n                ++m_current;\n            }\n            return m_current < m_generators.size();\n        }\n    };\n\n    template<typename... Ts>\n    GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {\n        return values<std::tuple<Ts...>>( tuples );\n    }\n\n    // Tag type to signal that a generator sequence should convert arguments to a specific type\n    template <typename T>\n    struct as {};\n\n    template<typename T, typename... Gs>\n    auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {\n        return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);\n    }\n    template<typename T>\n    auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {\n        return Generators<T>(std::move(generator));\n    }\n    template<typename T, typename... Gs>\n    auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {\n        return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );\n    }\n    template<typename T, typename U, typename... Gs>\n    auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {\n        return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );\n    }\n\n    auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;\n\n    template<typename L>\n    // Note: The type after -> is weird, because VS2015 cannot parse\n    //       the expression used in the typedef inside, when it is in\n    //       return type. Yeah.\n    auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {\n        using UnderlyingType = typename decltype(generatorExpression())::type;\n\n        IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );\n        if (!tracker.hasGenerator()) {\n            tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));\n        }\n\n        auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );\n        return generator.get();\n    }\n\n} // namespace Generators\n} // namespace Catch\n\n#define GENERATE( ... ) \\\n    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \\\n                                 CATCH_INTERNAL_LINEINFO, \\\n                                 [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)\n#define GENERATE_COPY( ... ) \\\n    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \\\n                                 CATCH_INTERNAL_LINEINFO, \\\n                                 [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)\n#define GENERATE_REF( ... ) \\\n    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \\\n                                 CATCH_INTERNAL_LINEINFO, \\\n                                 [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)\n\n// end catch_generators.hpp\n// start catch_generators_generic.hpp\n\nnamespace Catch {\nnamespace Generators {\n\n    template <typename T>\n    class TakeGenerator : public IGenerator<T> {\n        GeneratorWrapper<T> m_generator;\n        size_t m_returned = 0;\n        size_t m_target;\n    public:\n        TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):\n            m_generator(std::move(generator)),\n            m_target(target)\n        {\n            assert(target != 0 && \"Empty generators are not allowed\");\n        }\n        T const& get() const override {\n            return m_generator.get();\n        }\n        bool next() override {\n            ++m_returned;\n            if (m_returned >= m_target) {\n                return false;\n            }\n\n            const auto success = m_generator.next();\n            // If the underlying generator does not contain enough values\n            // then we cut short as well\n            if (!success) {\n                m_returned = m_target;\n            }\n            return success;\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));\n    }\n\n    template <typename T, typename Predicate>\n    class FilterGenerator : public IGenerator<T> {\n        GeneratorWrapper<T> m_generator;\n        Predicate m_predicate;\n    public:\n        template <typename P = Predicate>\n        FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):\n            m_generator(std::move(generator)),\n            m_predicate(std::forward<P>(pred))\n        {\n            if (!m_predicate(m_generator.get())) {\n                // It might happen that there are no values that pass the\n                // filter. In that case we throw an exception.\n                auto has_initial_value = nextImpl();\n                if (!has_initial_value) {\n                    Catch::throw_exception(GeneratorException(\"No valid value found in filtered generator\"));\n                }\n            }\n        }\n\n        T const& get() const override {\n            return m_generator.get();\n        }\n\n        bool next() override {\n            return nextImpl();\n        }\n\n    private:\n        bool nextImpl() {\n            bool success = m_generator.next();\n            if (!success) {\n                return false;\n            }\n            while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);\n            return success;\n        }\n    };\n\n    template <typename T, typename Predicate>\n    GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));\n    }\n\n    template <typename T>\n    class RepeatGenerator : public IGenerator<T> {\n        static_assert(!std::is_same<T, bool>::value,\n            \"RepeatGenerator currently does not support bools\"\n            \"because of std::vector<bool> specialization\");\n        GeneratorWrapper<T> m_generator;\n        mutable std::vector<T> m_returned;\n        size_t m_target_repeats;\n        size_t m_current_repeat = 0;\n        size_t m_repeat_index = 0;\n    public:\n        RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):\n            m_generator(std::move(generator)),\n            m_target_repeats(repeats)\n        {\n            assert(m_target_repeats > 0 && \"Repeat generator must repeat at least once\");\n        }\n\n        T const& get() const override {\n            if (m_current_repeat == 0) {\n                m_returned.push_back(m_generator.get());\n                return m_returned.back();\n            }\n            return m_returned[m_repeat_index];\n        }\n\n        bool next() override {\n            // There are 2 basic cases:\n            // 1) We are still reading the generator\n            // 2) We are reading our own cache\n\n            // In the first case, we need to poke the underlying generator.\n            // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache\n            if (m_current_repeat == 0) {\n                const auto success = m_generator.next();\n                if (!success) {\n                    ++m_current_repeat;\n                }\n                return m_current_repeat < m_target_repeats;\n            }\n\n            // In the second case, we need to move indices forward and check that we haven't run up against the end\n            ++m_repeat_index;\n            if (m_repeat_index == m_returned.size()) {\n                m_repeat_index = 0;\n                ++m_current_repeat;\n            }\n            return m_current_repeat < m_target_repeats;\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));\n    }\n\n    template <typename T, typename U, typename Func>\n    class MapGenerator : public IGenerator<T> {\n        // TBD: provide static assert for mapping function, for friendly error message\n        GeneratorWrapper<U> m_generator;\n        Func m_function;\n        // To avoid returning dangling reference, we have to save the values\n        T m_cache;\n    public:\n        template <typename F2 = Func>\n        MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :\n            m_generator(std::move(generator)),\n            m_function(std::forward<F2>(function)),\n            m_cache(m_function(m_generator.get()))\n        {}\n\n        T const& get() const override {\n            return m_cache;\n        }\n        bool next() override {\n            const auto success = m_generator.next();\n            if (success) {\n                m_cache = m_function(m_generator.get());\n            }\n            return success;\n        }\n    };\n\n    template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>\n    GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {\n        return GeneratorWrapper<T>(\n            pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))\n        );\n    }\n\n    template <typename T, typename U, typename Func>\n    GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {\n        return GeneratorWrapper<T>(\n            pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))\n        );\n    }\n\n    template <typename T>\n    class ChunkGenerator final : public IGenerator<std::vector<T>> {\n        std::vector<T> m_chunk;\n        size_t m_chunk_size;\n        GeneratorWrapper<T> m_generator;\n        bool m_used_up = false;\n    public:\n        ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :\n            m_chunk_size(size), m_generator(std::move(generator))\n        {\n            m_chunk.reserve(m_chunk_size);\n            if (m_chunk_size != 0) {\n                m_chunk.push_back(m_generator.get());\n                for (size_t i = 1; i < m_chunk_size; ++i) {\n                    if (!m_generator.next()) {\n                        Catch::throw_exception(GeneratorException(\"Not enough values to initialize the first chunk\"));\n                    }\n                    m_chunk.push_back(m_generator.get());\n                }\n            }\n        }\n        std::vector<T> const& get() const override {\n            return m_chunk;\n        }\n        bool next() override {\n            m_chunk.clear();\n            for (size_t idx = 0; idx < m_chunk_size; ++idx) {\n                if (!m_generator.next()) {\n                    return false;\n                }\n                m_chunk.push_back(m_generator.get());\n            }\n            return true;\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<std::vector<T>>(\n            pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))\n        );\n    }\n\n} // namespace Generators\n} // namespace Catch\n\n// end catch_generators_generic.hpp\n// start catch_generators_specific.hpp\n\n// start catch_context.h\n\n#include <memory>\n\nnamespace Catch {\n\n    struct IResultCapture;\n    struct IRunner;\n    struct IConfig;\n    struct IMutableContext;\n\n    using IConfigPtr = std::shared_ptr<IConfig const>;\n\n    struct IContext\n    {\n        virtual ~IContext();\n\n        virtual IResultCapture* getResultCapture() = 0;\n        virtual IRunner* getRunner() = 0;\n        virtual IConfigPtr const& getConfig() const = 0;\n    };\n\n    struct IMutableContext : IContext\n    {\n        virtual ~IMutableContext();\n        virtual void setResultCapture( IResultCapture* resultCapture ) = 0;\n        virtual void setRunner( IRunner* runner ) = 0;\n        virtual void setConfig( IConfigPtr const& config ) = 0;\n\n    private:\n        static IMutableContext *currentContext;\n        friend IMutableContext& getCurrentMutableContext();\n        friend void cleanUpContext();\n        static void createContext();\n    };\n\n    inline IMutableContext& getCurrentMutableContext()\n    {\n        if( !IMutableContext::currentContext )\n            IMutableContext::createContext();\n        // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)\n        return *IMutableContext::currentContext;\n    }\n\n    inline IContext& getCurrentContext()\n    {\n        return getCurrentMutableContext();\n    }\n\n    void cleanUpContext();\n\n    class SimplePcg32;\n    SimplePcg32& rng();\n}\n\n// end catch_context.h\n// start catch_interfaces_config.h\n\n// start catch_option.hpp\n\nnamespace Catch {\n\n    // An optional type\n    template<typename T>\n    class Option {\n    public:\n        Option() : nullableValue( nullptr ) {}\n        Option( T const& _value )\n        : nullableValue( new( storage ) T( _value ) )\n        {}\n        Option( Option const& _other )\n        : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )\n        {}\n\n        ~Option() {\n            reset();\n        }\n\n        Option& operator= ( Option const& _other ) {\n            if( &_other != this ) {\n                reset();\n                if( _other )\n                    nullableValue = new( storage ) T( *_other );\n            }\n            return *this;\n        }\n        Option& operator = ( T const& _value ) {\n            reset();\n            nullableValue = new( storage ) T( _value );\n            return *this;\n        }\n\n        void reset() {\n            if( nullableValue )\n                nullableValue->~T();\n            nullableValue = nullptr;\n        }\n\n        T& operator*() { return *nullableValue; }\n        T const& operator*() const { return *nullableValue; }\n        T* operator->() { return nullableValue; }\n        const T* operator->() const { return nullableValue; }\n\n        T valueOr( T const& defaultValue ) const {\n            return nullableValue ? *nullableValue : defaultValue;\n        }\n\n        bool some() const { return nullableValue != nullptr; }\n        bool none() const { return nullableValue == nullptr; }\n\n        bool operator !() const { return nullableValue == nullptr; }\n        explicit operator bool() const {\n            return some();\n        }\n\n    private:\n        T *nullableValue;\n        alignas(alignof(T)) char storage[sizeof(T)];\n    };\n\n} // end namespace Catch\n\n// end catch_option.hpp\n#include <chrono>\n#include <iosfwd>\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    enum class Verbosity {\n        Quiet = 0,\n        Normal,\n        High\n    };\n\n    struct WarnAbout { enum What {\n        Nothing = 0x00,\n        NoAssertions = 0x01,\n        NoTests = 0x02\n    }; };\n\n    struct ShowDurations { enum OrNot {\n        DefaultForReporter,\n        Always,\n        Never\n    }; };\n    struct RunTests { enum InWhatOrder {\n        InDeclarationOrder,\n        InLexicographicalOrder,\n        InRandomOrder\n    }; };\n    struct UseColour { enum YesOrNo {\n        Auto,\n        Yes,\n        No\n    }; };\n    struct WaitForKeypress { enum When {\n        Never,\n        BeforeStart = 1,\n        BeforeExit = 2,\n        BeforeStartAndExit = BeforeStart | BeforeExit\n    }; };\n\n    class TestSpec;\n\n    struct IConfig : NonCopyable {\n\n        virtual ~IConfig();\n\n        virtual bool allowThrows() const = 0;\n        virtual std::ostream& stream() const = 0;\n        virtual std::string name() const = 0;\n        virtual bool includeSuccessfulResults() const = 0;\n        virtual bool shouldDebugBreak() const = 0;\n        virtual bool warnAboutMissingAssertions() const = 0;\n        virtual bool warnAboutNoTests() const = 0;\n        virtual int abortAfter() const = 0;\n        virtual bool showInvisibles() const = 0;\n        virtual ShowDurations::OrNot showDurations() const = 0;\n        virtual double minDuration() const = 0;\n        virtual TestSpec const& testSpec() const = 0;\n        virtual bool hasTestFilters() const = 0;\n        virtual std::vector<std::string> const& getTestsOrTags() const = 0;\n        virtual RunTests::InWhatOrder runOrder() const = 0;\n        virtual unsigned int rngSeed() const = 0;\n        virtual UseColour::YesOrNo useColour() const = 0;\n        virtual std::vector<std::string> const& getSectionsToRun() const = 0;\n        virtual Verbosity verbosity() const = 0;\n\n        virtual bool benchmarkNoAnalysis() const = 0;\n        virtual int benchmarkSamples() const = 0;\n        virtual double benchmarkConfidenceInterval() const = 0;\n        virtual unsigned int benchmarkResamples() const = 0;\n        virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;\n    };\n\n    using IConfigPtr = std::shared_ptr<IConfig const>;\n}\n\n// end catch_interfaces_config.h\n// start catch_random_number_generator.h\n\n#include <cstdint>\n\nnamespace Catch {\n\n    // This is a simple implementation of C++11 Uniform Random Number\n    // Generator. It does not provide all operators, because Catch2\n    // does not use it, but it should behave as expected inside stdlib's\n    // distributions.\n    // The implementation is based on the PCG family (http://pcg-random.org)\n    class SimplePcg32 {\n        using state_type = std::uint64_t;\n    public:\n        using result_type = std::uint32_t;\n        static constexpr result_type (min)() {\n            return 0;\n        }\n        static constexpr result_type (max)() {\n            return static_cast<result_type>(-1);\n        }\n\n        // Provide some default initial state for the default constructor\n        SimplePcg32():SimplePcg32(0xed743cc4U) {}\n\n        explicit SimplePcg32(result_type seed_);\n\n        void seed(result_type seed_);\n        void discard(uint64_t skip);\n\n        result_type operator()();\n\n    private:\n        friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);\n        friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);\n\n        // In theory we also need operator<< and operator>>\n        // In practice we do not use them, so we will skip them for now\n\n        std::uint64_t m_state;\n        // This part of the state determines which \"stream\" of the numbers\n        // is chosen -- we take it as a constant for Catch2, so we only\n        // need to deal with seeding the main state.\n        // Picked by reading 8 bytes from `/dev/random` :-)\n        static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;\n    };\n\n} // end namespace Catch\n\n// end catch_random_number_generator.h\n#include <random>\n\nnamespace Catch {\nnamespace Generators {\n\ntemplate <typename Float>\nclass RandomFloatingGenerator final : public IGenerator<Float> {\n    Catch::SimplePcg32& m_rng;\n    std::uniform_real_distribution<Float> m_dist;\n    Float m_current_number;\npublic:\n\n    RandomFloatingGenerator(Float a, Float b):\n        m_rng(rng()),\n        m_dist(a, b) {\n        static_cast<void>(next());\n    }\n\n    Float const& get() const override {\n        return m_current_number;\n    }\n    bool next() override {\n        m_current_number = m_dist(m_rng);\n        return true;\n    }\n};\n\ntemplate <typename Integer>\nclass RandomIntegerGenerator final : public IGenerator<Integer> {\n    Catch::SimplePcg32& m_rng;\n    std::uniform_int_distribution<Integer> m_dist;\n    Integer m_current_number;\npublic:\n\n    RandomIntegerGenerator(Integer a, Integer b):\n        m_rng(rng()),\n        m_dist(a, b) {\n        static_cast<void>(next());\n    }\n\n    Integer const& get() const override {\n        return m_current_number;\n    }\n    bool next() override {\n        m_current_number = m_dist(m_rng);\n        return true;\n    }\n};\n\n// TODO: Ideally this would be also constrained against the various char types,\n//       but I don't expect users to run into that in practice.\ntemplate <typename T>\ntypename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,\nGeneratorWrapper<T>>::type\nrandom(T a, T b) {\n    return GeneratorWrapper<T>(\n        pf::make_unique<RandomIntegerGenerator<T>>(a, b)\n    );\n}\n\ntemplate <typename T>\ntypename std::enable_if<std::is_floating_point<T>::value,\nGeneratorWrapper<T>>::type\nrandom(T a, T b) {\n    return GeneratorWrapper<T>(\n        pf::make_unique<RandomFloatingGenerator<T>>(a, b)\n    );\n}\n\ntemplate <typename T>\nclass RangeGenerator final : public IGenerator<T> {\n    T m_current;\n    T m_end;\n    T m_step;\n    bool m_positive;\n\npublic:\n    RangeGenerator(T const& start, T const& end, T const& step):\n        m_current(start),\n        m_end(end),\n        m_step(step),\n        m_positive(m_step > T(0))\n    {\n        assert(m_current != m_end && \"Range start and end cannot be equal\");\n        assert(m_step != T(0) && \"Step size cannot be zero\");\n        assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && \"Step moves away from end\");\n    }\n\n    RangeGenerator(T const& start, T const& end):\n        RangeGenerator(start, end, (start < end) ? T(1) : T(-1))\n    {}\n\n    T const& get() const override {\n        return m_current;\n    }\n\n    bool next() override {\n        m_current += m_step;\n        return (m_positive) ? (m_current < m_end) : (m_current > m_end);\n    }\n};\n\ntemplate <typename T>\nGeneratorWrapper<T> range(T const& start, T const& end, T const& step) {\n    static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, \"Type must be numeric\");\n    return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));\n}\n\ntemplate <typename T>\nGeneratorWrapper<T> range(T const& start, T const& end) {\n    static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, \"Type must be an integer\");\n    return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));\n}\n\ntemplate <typename T>\nclass IteratorGenerator final : public IGenerator<T> {\n    static_assert(!std::is_same<T, bool>::value,\n        \"IteratorGenerator currently does not support bools\"\n        \"because of std::vector<bool> specialization\");\n\n    std::vector<T> m_elems;\n    size_t m_current = 0;\npublic:\n    template <typename InputIterator, typename InputSentinel>\n    IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {\n        if (m_elems.empty()) {\n            Catch::throw_exception(GeneratorException(\"IteratorGenerator received no valid values\"));\n        }\n    }\n\n    T const& get() const override {\n        return m_elems[m_current];\n    }\n\n    bool next() override {\n        ++m_current;\n        return m_current != m_elems.size();\n    }\n};\n\ntemplate <typename InputIterator,\n          typename InputSentinel,\n          typename ResultType = typename std::iterator_traits<InputIterator>::value_type>\nGeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {\n    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));\n}\n\ntemplate <typename Container,\n          typename ResultType = typename Container::value_type>\nGeneratorWrapper<ResultType> from_range(Container const& cnt) {\n    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));\n}\n\n} // namespace Generators\n} // namespace Catch\n\n// end catch_generators_specific.hpp\n\n// These files are included here so the single_include script doesn't put them\n// in the conditionally compiled sections\n// start catch_test_case_info.h\n\n#include <string>\n#include <vector>\n#include <memory>\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nnamespace Catch {\n\n    struct ITestInvoker;\n\n    struct TestCaseInfo {\n        enum SpecialProperties{\n            None = 0,\n            IsHidden = 1 << 1,\n            ShouldFail = 1 << 2,\n            MayFail = 1 << 3,\n            Throws = 1 << 4,\n            NonPortable = 1 << 5,\n            Benchmark = 1 << 6\n        };\n\n        TestCaseInfo(   std::string const& _name,\n                        std::string const& _className,\n                        std::string const& _description,\n                        std::vector<std::string> const& _tags,\n                        SourceLineInfo const& _lineInfo );\n\n        friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );\n\n        bool isHidden() const;\n        bool throws() const;\n        bool okToFail() const;\n        bool expectedToFail() const;\n\n        std::string tagsAsString() const;\n\n        std::string name;\n        std::string className;\n        std::string description;\n        std::vector<std::string> tags;\n        std::vector<std::string> lcaseTags;\n        SourceLineInfo lineInfo;\n        SpecialProperties properties;\n    };\n\n    class TestCase : public TestCaseInfo {\n    public:\n\n        TestCase( ITestInvoker* testCase, TestCaseInfo&& info );\n\n        TestCase withName( std::string const& _newName ) const;\n\n        void invoke() const;\n\n        TestCaseInfo const& getTestCaseInfo() const;\n\n        bool operator == ( TestCase const& other ) const;\n        bool operator < ( TestCase const& other ) const;\n\n    private:\n        std::shared_ptr<ITestInvoker> test;\n    };\n\n    TestCase makeTestCase(  ITestInvoker* testCase,\n                            std::string const& className,\n                            NameAndTags const& nameAndTags,\n                            SourceLineInfo const& lineInfo );\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_test_case_info.h\n// start catch_interfaces_runner.h\n\nnamespace Catch {\n\n    struct IRunner {\n        virtual ~IRunner();\n        virtual bool aborting() const = 0;\n    };\n}\n\n// end catch_interfaces_runner.h\n\n#ifdef __OBJC__\n// start catch_objc.hpp\n\n#import <objc/runtime.h>\n\n#include <string>\n\n// NB. Any general catch headers included here must be included\n// in catch.hpp first to make sure they are included by the single\n// header for non obj-usage\n\n///////////////////////////////////////////////////////////////////////////////\n// This protocol is really only here for (self) documenting purposes, since\n// all its methods are optional.\n@protocol OcFixture\n\n@optional\n\n-(void) setUp;\n-(void) tearDown;\n\n@end\n\nnamespace Catch {\n\n    class OcMethod : public ITestInvoker {\n\n    public:\n        OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}\n\n        virtual void invoke() const {\n            id obj = [[m_cls alloc] init];\n\n            performOptionalSelector( obj, @selector(setUp)  );\n            performOptionalSelector( obj, m_sel );\n            performOptionalSelector( obj, @selector(tearDown)  );\n\n            arcSafeRelease( obj );\n        }\n    private:\n        virtual ~OcMethod() {}\n\n        Class m_cls;\n        SEL m_sel;\n    };\n\n    namespace Detail{\n\n        inline std::string getAnnotation(   Class cls,\n                                            std::string const& annotationName,\n                                            std::string const& testCaseName ) {\n            NSString* selStr = [[NSString alloc] initWithFormat:@\"Catch_%s_%s\", annotationName.c_str(), testCaseName.c_str()];\n            SEL sel = NSSelectorFromString( selStr );\n            arcSafeRelease( selStr );\n            id value = performOptionalSelector( cls, sel );\n            if( value )\n                return [(NSString*)value UTF8String];\n            return \"\";\n        }\n    }\n\n    inline std::size_t registerTestMethods() {\n        std::size_t noTestMethods = 0;\n        int noClasses = objc_getClassList( nullptr, 0 );\n\n        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);\n        objc_getClassList( classes, noClasses );\n\n        for( int c = 0; c < noClasses; c++ ) {\n            Class cls = classes[c];\n            {\n                u_int count;\n                Method* methods = class_copyMethodList( cls, &count );\n                for( u_int m = 0; m < count ; m++ ) {\n                    SEL selector = method_getName(methods[m]);\n                    std::string methodName = sel_getName(selector);\n                    if( startsWith( methodName, \"Catch_TestCase_\" ) ) {\n                        std::string testCaseName = methodName.substr( 15 );\n                        std::string name = Detail::getAnnotation( cls, \"Name\", testCaseName );\n                        std::string desc = Detail::getAnnotation( cls, \"Description\", testCaseName );\n                        const char* className = class_getName( cls );\n\n                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo(\"\",0) ) );\n                        noTestMethods++;\n                    }\n                }\n                free(methods);\n            }\n        }\n        return noTestMethods;\n    }\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n\n    namespace Matchers {\n        namespace Impl {\n        namespace NSStringMatchers {\n\n            struct StringHolder : MatcherBase<NSString*>{\n                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}\n                StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}\n                StringHolder() {\n                    arcSafeRelease( m_substr );\n                }\n\n                bool match( NSString* str ) const override {\n                    return false;\n                }\n\n                NSString* CATCH_ARC_STRONG m_substr;\n            };\n\n            struct Equals : StringHolder {\n                Equals( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str isEqualToString:m_substr];\n                }\n\n                std::string describe() const override {\n                    return \"equals string: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n\n            struct Contains : StringHolder {\n                Contains( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location != NSNotFound;\n                }\n\n                std::string describe() const override {\n                    return \"contains string: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n\n            struct StartsWith : StringHolder {\n                StartsWith( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == 0;\n                }\n\n                std::string describe() const override {\n                    return \"starts with: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n            struct EndsWith : StringHolder {\n                EndsWith( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];\n                }\n\n                std::string describe() const override {\n                    return \"ends with: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n\n        } // namespace NSStringMatchers\n        } // namespace Impl\n\n        inline Impl::NSStringMatchers::Equals\n            Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }\n\n        inline Impl::NSStringMatchers::Contains\n            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }\n\n        inline Impl::NSStringMatchers::StartsWith\n            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }\n\n        inline Impl::NSStringMatchers::EndsWith\n            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }\n\n    } // namespace Matchers\n\n    using namespace Matchers;\n\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n} // namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix\n#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \\\n+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \\\n{ \\\nreturn @ name; \\\n} \\\n+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \\\n{ \\\nreturn @ desc; \\\n} \\\n-(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )\n\n#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )\n\n// end catch_objc.hpp\n#endif\n\n// Benchmarking needs the externally-facing parts of reporters to work\n#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n// start catch_external_interfaces.h\n\n// start catch_reporter_bases.hpp\n\n// start catch_interfaces_reporter.h\n\n// start catch_config.hpp\n\n// start catch_test_spec_parser.h\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// start catch_test_spec.h\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// start catch_wildcard_pattern.h\n\nnamespace Catch\n{\n    class WildcardPattern {\n        enum WildcardPosition {\n            NoWildcard = 0,\n            WildcardAtStart = 1,\n            WildcardAtEnd = 2,\n            WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd\n        };\n\n    public:\n\n        WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );\n        virtual ~WildcardPattern() = default;\n        virtual bool matches( std::string const& str ) const;\n\n    private:\n        std::string normaliseString( std::string const& str ) const;\n        CaseSensitive::Choice m_caseSensitivity;\n        WildcardPosition m_wildcard = NoWildcard;\n        std::string m_pattern;\n    };\n}\n\n// end catch_wildcard_pattern.h\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    struct IConfig;\n\n    class TestSpec {\n        class Pattern {\n        public:\n            explicit Pattern( std::string const& name );\n            virtual ~Pattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const = 0;\n            std::string const& name() const;\n        private:\n            std::string const m_name;\n        };\n        using PatternPtr = std::shared_ptr<Pattern>;\n\n        class NamePattern : public Pattern {\n        public:\n            explicit NamePattern( std::string const& name, std::string const& filterString );\n            bool matches( TestCaseInfo const& testCase ) const override;\n        private:\n            WildcardPattern m_wildcardPattern;\n        };\n\n        class TagPattern : public Pattern {\n        public:\n            explicit TagPattern( std::string const& tag, std::string const& filterString );\n            bool matches( TestCaseInfo const& testCase ) const override;\n        private:\n            std::string m_tag;\n        };\n\n        class ExcludedPattern : public Pattern {\n        public:\n            explicit ExcludedPattern( PatternPtr const& underlyingPattern );\n            bool matches( TestCaseInfo const& testCase ) const override;\n        private:\n            PatternPtr m_underlyingPattern;\n        };\n\n        struct Filter {\n            std::vector<PatternPtr> m_patterns;\n\n            bool matches( TestCaseInfo const& testCase ) const;\n            std::string name() const;\n        };\n\n    public:\n        struct FilterMatch {\n            std::string name;\n            std::vector<TestCase const*> tests;\n        };\n        using Matches = std::vector<FilterMatch>;\n        using vectorStrings = std::vector<std::string>;\n\n        bool hasFilters() const;\n        bool matches( TestCaseInfo const& testCase ) const;\n        Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;\n        const vectorStrings & getInvalidArgs() const;\n\n    private:\n        std::vector<Filter> m_filters;\n        std::vector<std::string> m_invalidArgs;\n        friend class TestSpecParser;\n    };\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_test_spec.h\n// start catch_interfaces_tag_alias_registry.h\n\n#include <string>\n\nnamespace Catch {\n\n    struct TagAlias;\n\n    struct ITagAliasRegistry {\n        virtual ~ITagAliasRegistry();\n        // Nullptr if not present\n        virtual TagAlias const* find( std::string const& alias ) const = 0;\n        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;\n\n        static ITagAliasRegistry const& get();\n    };\n\n} // end namespace Catch\n\n// end catch_interfaces_tag_alias_registry.h\nnamespace Catch {\n\n    class TestSpecParser {\n        enum Mode{ None, Name, QuotedName, Tag, EscapedName };\n        Mode m_mode = None;\n        Mode lastMode = None;\n        bool m_exclusion = false;\n        std::size_t m_pos = 0;\n        std::size_t m_realPatternPos = 0;\n        std::string m_arg;\n        std::string m_substring;\n        std::string m_patternName;\n        std::vector<std::size_t> m_escapeChars;\n        TestSpec::Filter m_currentFilter;\n        TestSpec m_testSpec;\n        ITagAliasRegistry const* m_tagAliases = nullptr;\n\n    public:\n        TestSpecParser( ITagAliasRegistry const& tagAliases );\n\n        TestSpecParser& parse( std::string const& arg );\n        TestSpec testSpec();\n\n    private:\n        bool visitChar( char c );\n        void startNewMode( Mode mode );\n        bool processNoneChar( char c );\n        void processNameChar( char c );\n        bool processOtherChar( char c );\n        void endMode();\n        void escape();\n        bool isControlChar( char c ) const;\n        void saveLastMode();\n        void revertBackToLastMode();\n        void addFilter();\n        bool separate();\n\n        // Handles common preprocessing of the pattern for name/tag patterns\n        std::string preprocessPattern();\n        // Adds the current pattern as a test name\n        void addNamePattern();\n        // Adds the current pattern as a tag\n        void addTagPattern();\n\n        inline void addCharToPattern(char c) {\n            m_substring += c;\n            m_patternName += c;\n            m_realPatternPos++;\n        }\n\n    };\n    TestSpec parseTestSpec( std::string const& arg );\n\n} // namespace Catch\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_test_spec_parser.h\n// Libstdc++ doesn't like incomplete classes for unique_ptr\n\n#include <memory>\n#include <vector>\n#include <string>\n\n#ifndef CATCH_CONFIG_CONSOLE_WIDTH\n#define CATCH_CONFIG_CONSOLE_WIDTH 80\n#endif\n\nnamespace Catch {\n\n    struct IStream;\n\n    struct ConfigData {\n        bool listTests = false;\n        bool listTags = false;\n        bool listReporters = false;\n        bool listTestNamesOnly = false;\n\n        bool showSuccessfulTests = false;\n        bool shouldDebugBreak = false;\n        bool noThrow = false;\n        bool showHelp = false;\n        bool showInvisibles = false;\n        bool filenamesAsTags = false;\n        bool libIdentify = false;\n\n        int abortAfter = -1;\n        unsigned int rngSeed = 0;\n\n        bool benchmarkNoAnalysis = false;\n        unsigned int benchmarkSamples = 100;\n        double benchmarkConfidenceInterval = 0.95;\n        unsigned int benchmarkResamples = 100000;\n        std::chrono::milliseconds::rep benchmarkWarmupTime = 100;\n\n        Verbosity verbosity = Verbosity::Normal;\n        WarnAbout::What warnings = WarnAbout::Nothing;\n        ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;\n        double minDuration = -1;\n        RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;\n        UseColour::YesOrNo useColour = UseColour::Auto;\n        WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;\n\n        std::string outputFilename;\n        std::string name;\n        std::string processName;\n#ifndef CATCH_CONFIG_DEFAULT_REPORTER\n#define CATCH_CONFIG_DEFAULT_REPORTER \"console\"\n#endif\n        std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;\n#undef CATCH_CONFIG_DEFAULT_REPORTER\n\n        std::vector<std::string> testsOrTags;\n        std::vector<std::string> sectionsToRun;\n    };\n\n    class Config : public IConfig {\n    public:\n\n        Config() = default;\n        Config( ConfigData const& data );\n        virtual ~Config() = default;\n\n        std::string const& getFilename() const;\n\n        bool listTests() const;\n        bool listTestNamesOnly() const;\n        bool listTags() const;\n        bool listReporters() const;\n\n        std::string getProcessName() const;\n        std::string const& getReporterName() const;\n\n        std::vector<std::string> const& getTestsOrTags() const override;\n        std::vector<std::string> const& getSectionsToRun() const override;\n\n        TestSpec const& testSpec() const override;\n        bool hasTestFilters() const override;\n\n        bool showHelp() const;\n\n        // IConfig interface\n        bool allowThrows() const override;\n        std::ostream& stream() const override;\n        std::string name() const override;\n        bool includeSuccessfulResults() const override;\n        bool warnAboutMissingAssertions() const override;\n        bool warnAboutNoTests() const override;\n        ShowDurations::OrNot showDurations() const override;\n        double minDuration() const override;\n        RunTests::InWhatOrder runOrder() const override;\n        unsigned int rngSeed() const override;\n        UseColour::YesOrNo useColour() const override;\n        bool shouldDebugBreak() const override;\n        int abortAfter() const override;\n        bool showInvisibles() const override;\n        Verbosity verbosity() const override;\n        bool benchmarkNoAnalysis() const override;\n        int benchmarkSamples() const override;\n        double benchmarkConfidenceInterval() const override;\n        unsigned int benchmarkResamples() const override;\n        std::chrono::milliseconds benchmarkWarmupTime() const override;\n\n    private:\n\n        IStream const* openStream();\n        ConfigData m_data;\n\n        std::unique_ptr<IStream const> m_stream;\n        TestSpec m_testSpec;\n        bool m_hasTestFilters = false;\n    };\n\n} // end namespace Catch\n\n// end catch_config.hpp\n// start catch_assertionresult.h\n\n#include <string>\n\nnamespace Catch {\n\n    struct AssertionResultData\n    {\n        AssertionResultData() = delete;\n\n        AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );\n\n        std::string message;\n        mutable std::string reconstructedExpression;\n        LazyExpression lazyExpression;\n        ResultWas::OfType resultType;\n\n        std::string reconstructExpression() const;\n    };\n\n    class AssertionResult {\n    public:\n        AssertionResult() = delete;\n        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );\n\n        bool isOk() const;\n        bool succeeded() const;\n        ResultWas::OfType getResultType() const;\n        bool hasExpression() const;\n        bool hasMessage() const;\n        std::string getExpression() const;\n        std::string getExpressionInMacro() const;\n        bool hasExpandedExpression() const;\n        std::string getExpandedExpression() const;\n        std::string getMessage() const;\n        SourceLineInfo getSourceInfo() const;\n        StringRef getTestMacroName() const;\n\n    //protected:\n        AssertionInfo m_info;\n        AssertionResultData m_resultData;\n    };\n\n} // end namespace Catch\n\n// end catch_assertionresult.h\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n// start catch_estimate.hpp\n\n // Statistics estimates\n\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct Estimate {\n            Duration point;\n            Duration lower_bound;\n            Duration upper_bound;\n            double confidence_interval;\n\n            template <typename Duration2>\n            operator Estimate<Duration2>() const {\n                return { point, lower_bound, upper_bound, confidence_interval };\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_estimate.hpp\n// start catch_outlier_classification.hpp\n\n// Outlier information\n\nnamespace Catch {\n    namespace Benchmark {\n        struct OutlierClassification {\n            int samples_seen = 0;\n            int low_severe = 0;     // more than 3 times IQR below Q1\n            int low_mild = 0;       // 1.5 to 3 times IQR below Q1\n            int high_mild = 0;      // 1.5 to 3 times IQR above Q3\n            int high_severe = 0;    // more than 3 times IQR above Q3\n\n            int total() const {\n                return low_severe + low_mild + high_mild + high_severe;\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_outlier_classification.hpp\n\n#include <iterator>\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n#include <string>\n#include <iosfwd>\n#include <map>\n#include <set>\n#include <memory>\n#include <algorithm>\n\nnamespace Catch {\n\n    struct ReporterConfig {\n        explicit ReporterConfig( IConfigPtr const& _fullConfig );\n\n        ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );\n\n        std::ostream& stream() const;\n        IConfigPtr fullConfig() const;\n\n    private:\n        std::ostream* m_stream;\n        IConfigPtr m_fullConfig;\n    };\n\n    struct ReporterPreferences {\n        bool shouldRedirectStdOut = false;\n        bool shouldReportAllAssertions = false;\n    };\n\n    template<typename T>\n    struct LazyStat : Option<T> {\n        LazyStat& operator=( T const& _value ) {\n            Option<T>::operator=( _value );\n            used = false;\n            return *this;\n        }\n        void reset() {\n            Option<T>::reset();\n            used = false;\n        }\n        bool used = false;\n    };\n\n    struct TestRunInfo {\n        TestRunInfo( std::string const& _name );\n        std::string name;\n    };\n    struct GroupInfo {\n        GroupInfo(  std::string const& _name,\n                    std::size_t _groupIndex,\n                    std::size_t _groupsCount );\n\n        std::string name;\n        std::size_t groupIndex;\n        std::size_t groupsCounts;\n    };\n\n    struct AssertionStats {\n        AssertionStats( AssertionResult const& _assertionResult,\n                        std::vector<MessageInfo> const& _infoMessages,\n                        Totals const& _totals );\n\n        AssertionStats( AssertionStats const& )              = default;\n        AssertionStats( AssertionStats && )                  = default;\n        AssertionStats& operator = ( AssertionStats const& ) = delete;\n        AssertionStats& operator = ( AssertionStats && )     = delete;\n        virtual ~AssertionStats();\n\n        AssertionResult assertionResult;\n        std::vector<MessageInfo> infoMessages;\n        Totals totals;\n    };\n\n    struct SectionStats {\n        SectionStats(   SectionInfo const& _sectionInfo,\n                        Counts const& _assertions,\n                        double _durationInSeconds,\n                        bool _missingAssertions );\n        SectionStats( SectionStats const& )              = default;\n        SectionStats( SectionStats && )                  = default;\n        SectionStats& operator = ( SectionStats const& ) = default;\n        SectionStats& operator = ( SectionStats && )     = default;\n        virtual ~SectionStats();\n\n        SectionInfo sectionInfo;\n        Counts assertions;\n        double durationInSeconds;\n        bool missingAssertions;\n    };\n\n    struct TestCaseStats {\n        TestCaseStats(  TestCaseInfo const& _testInfo,\n                        Totals const& _totals,\n                        std::string const& _stdOut,\n                        std::string const& _stdErr,\n                        bool _aborting );\n\n        TestCaseStats( TestCaseStats const& )              = default;\n        TestCaseStats( TestCaseStats && )                  = default;\n        TestCaseStats& operator = ( TestCaseStats const& ) = default;\n        TestCaseStats& operator = ( TestCaseStats && )     = default;\n        virtual ~TestCaseStats();\n\n        TestCaseInfo testInfo;\n        Totals totals;\n        std::string stdOut;\n        std::string stdErr;\n        bool aborting;\n    };\n\n    struct TestGroupStats {\n        TestGroupStats( GroupInfo const& _groupInfo,\n                        Totals const& _totals,\n                        bool _aborting );\n        TestGroupStats( GroupInfo const& _groupInfo );\n\n        TestGroupStats( TestGroupStats const& )              = default;\n        TestGroupStats( TestGroupStats && )                  = default;\n        TestGroupStats& operator = ( TestGroupStats const& ) = default;\n        TestGroupStats& operator = ( TestGroupStats && )     = default;\n        virtual ~TestGroupStats();\n\n        GroupInfo groupInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n    struct TestRunStats {\n        TestRunStats(   TestRunInfo const& _runInfo,\n                        Totals const& _totals,\n                        bool _aborting );\n\n        TestRunStats( TestRunStats const& )              = default;\n        TestRunStats( TestRunStats && )                  = default;\n        TestRunStats& operator = ( TestRunStats const& ) = default;\n        TestRunStats& operator = ( TestRunStats && )     = default;\n        virtual ~TestRunStats();\n\n        TestRunInfo runInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    struct BenchmarkInfo {\n        std::string name;\n        double estimatedDuration;\n        int iterations;\n        int samples;\n        unsigned int resamples;\n        double clockResolution;\n        double clockCost;\n    };\n\n    template <class Duration>\n    struct BenchmarkStats {\n        BenchmarkInfo info;\n\n        std::vector<Duration> samples;\n        Benchmark::Estimate<Duration> mean;\n        Benchmark::Estimate<Duration> standardDeviation;\n        Benchmark::OutlierClassification outliers;\n        double outlierVariance;\n\n        template <typename Duration2>\n        operator BenchmarkStats<Duration2>() const {\n            std::vector<Duration2> samples2;\n            samples2.reserve(samples.size());\n            std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });\n            return {\n                info,\n                std::move(samples2),\n                mean,\n                standardDeviation,\n                outliers,\n                outlierVariance,\n            };\n        }\n    };\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    struct IStreamingReporter {\n        virtual ~IStreamingReporter() = default;\n\n        // Implementing class must also provide the following static methods:\n        // static std::string getDescription();\n        // static std::set<Verbosity> getSupportedVerbosities()\n\n        virtual ReporterPreferences getPreferences() const = 0;\n\n        virtual void noMatchingTestCases( std::string const& spec ) = 0;\n\n        virtual void reportInvalidArguments(std::string const&) {}\n\n        virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;\n        virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;\n\n        virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;\n        virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        virtual void benchmarkPreparing( std::string const& ) {}\n        virtual void benchmarkStarting( BenchmarkInfo const& ) {}\n        virtual void benchmarkEnded( BenchmarkStats<> const& ) {}\n        virtual void benchmarkFailed( std::string const& ) {}\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;\n\n        // The return value indicates if the messages buffer should be cleared:\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;\n\n        virtual void sectionEnded( SectionStats const& sectionStats ) = 0;\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;\n        virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;\n\n        virtual void skipTest( TestCaseInfo const& testInfo ) = 0;\n\n        // Default empty implementation provided\n        virtual void fatalErrorEncountered( StringRef name );\n\n        virtual bool isMulti() const;\n    };\n    using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;\n\n    struct IReporterFactory {\n        virtual ~IReporterFactory();\n        virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;\n        virtual std::string getDescription() const = 0;\n    };\n    using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;\n\n    struct IReporterRegistry {\n        using FactoryMap = std::map<std::string, IReporterFactoryPtr>;\n        using Listeners = std::vector<IReporterFactoryPtr>;\n\n        virtual ~IReporterRegistry();\n        virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;\n        virtual FactoryMap const& getFactories() const = 0;\n        virtual Listeners const& getListeners() const = 0;\n    };\n\n} // end namespace Catch\n\n// end catch_interfaces_reporter.h\n#include <algorithm>\n#include <cstring>\n#include <cfloat>\n#include <cstdio>\n#include <cassert>\n#include <memory>\n#include <ostream>\n\nnamespace Catch {\n    void prepareExpandedExpression(AssertionResult& result);\n\n    // Returns double formatted as %.3f (format expected on output)\n    std::string getFormattedDuration( double duration );\n\n    //! Should the reporter show\n    bool shouldShowDuration( IConfig const& config, double duration );\n\n    std::string serializeFilters( std::vector<std::string> const& container );\n\n    template<typename DerivedT>\n    struct StreamingReporterBase : IStreamingReporter {\n\n        StreamingReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n            if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )\n                CATCH_ERROR( \"Verbosity level not supported by this reporter\" );\n        }\n\n        ReporterPreferences getPreferences() const override {\n            return m_reporterPrefs;\n        }\n\n        static std::set<Verbosity> getSupportedVerbosities() {\n            return { Verbosity::Normal };\n        }\n\n        ~StreamingReporterBase() override = default;\n\n        void noMatchingTestCases(std::string const&) override {}\n\n        void reportInvalidArguments(std::string const&) override {}\n\n        void testRunStarting(TestRunInfo const& _testRunInfo) override {\n            currentTestRunInfo = _testRunInfo;\n        }\n\n        void testGroupStarting(GroupInfo const& _groupInfo) override {\n            currentGroupInfo = _groupInfo;\n        }\n\n        void testCaseStarting(TestCaseInfo const& _testInfo) override  {\n            currentTestCaseInfo = _testInfo;\n        }\n        void sectionStarting(SectionInfo const& _sectionInfo) override {\n            m_sectionStack.push_back(_sectionInfo);\n        }\n\n        void sectionEnded(SectionStats const& /* _sectionStats */) override {\n            m_sectionStack.pop_back();\n        }\n        void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {\n            currentTestCaseInfo.reset();\n        }\n        void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {\n            currentGroupInfo.reset();\n        }\n        void testRunEnded(TestRunStats const& /* _testRunStats */) override {\n            currentTestCaseInfo.reset();\n            currentGroupInfo.reset();\n            currentTestRunInfo.reset();\n        }\n\n        void skipTest(TestCaseInfo const&) override {\n            // Don't do anything with this by default.\n            // It can optionally be overridden in the derived class.\n        }\n\n        IConfigPtr m_config;\n        std::ostream& stream;\n\n        LazyStat<TestRunInfo> currentTestRunInfo;\n        LazyStat<GroupInfo> currentGroupInfo;\n        LazyStat<TestCaseInfo> currentTestCaseInfo;\n\n        std::vector<SectionInfo> m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n    };\n\n    template<typename DerivedT>\n    struct CumulativeReporterBase : IStreamingReporter {\n        template<typename T, typename ChildNodeT>\n        struct Node {\n            explicit Node( T const& _value ) : value( _value ) {}\n            virtual ~Node() {}\n\n            using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;\n            T value;\n            ChildNodes children;\n        };\n        struct SectionNode {\n            explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}\n            virtual ~SectionNode() = default;\n\n            bool operator == (SectionNode const& other) const {\n                return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;\n            }\n            bool operator == (std::shared_ptr<SectionNode> const& other) const {\n                return operator==(*other);\n            }\n\n            SectionStats stats;\n            using ChildSections = std::vector<std::shared_ptr<SectionNode>>;\n            using Assertions = std::vector<AssertionStats>;\n            ChildSections childSections;\n            Assertions assertions;\n            std::string stdOut;\n            std::string stdErr;\n        };\n\n        struct BySectionInfo {\n            BySectionInfo( SectionInfo const& other ) : m_other( other ) {}\n            BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}\n            bool operator() (std::shared_ptr<SectionNode> const& node) const {\n                return ((node->stats.sectionInfo.name == m_other.name) &&\n                        (node->stats.sectionInfo.lineInfo == m_other.lineInfo));\n            }\n            void operator=(BySectionInfo const&) = delete;\n\n        private:\n            SectionInfo const& m_other;\n        };\n\n        using TestCaseNode = Node<TestCaseStats, SectionNode>;\n        using TestGroupNode = Node<TestGroupStats, TestCaseNode>;\n        using TestRunNode = Node<TestRunStats, TestGroupNode>;\n\n        CumulativeReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n            if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )\n                CATCH_ERROR( \"Verbosity level not supported by this reporter\" );\n        }\n        ~CumulativeReporterBase() override = default;\n\n        ReporterPreferences getPreferences() const override {\n            return m_reporterPrefs;\n        }\n\n        static std::set<Verbosity> getSupportedVerbosities() {\n            return { Verbosity::Normal };\n        }\n\n        void testRunStarting( TestRunInfo const& ) override {}\n        void testGroupStarting( GroupInfo const& ) override {}\n\n        void testCaseStarting( TestCaseInfo const& ) override {}\n\n        void sectionStarting( SectionInfo const& sectionInfo ) override {\n            SectionStats incompleteStats( sectionInfo, Counts(), 0, false );\n            std::shared_ptr<SectionNode> node;\n            if( m_sectionStack.empty() ) {\n                if( !m_rootSection )\n                    m_rootSection = std::make_shared<SectionNode>( incompleteStats );\n                node = m_rootSection;\n            }\n            else {\n                SectionNode& parentNode = *m_sectionStack.back();\n                auto it =\n                    std::find_if(   parentNode.childSections.begin(),\n                                    parentNode.childSections.end(),\n                                    BySectionInfo( sectionInfo ) );\n                if( it == parentNode.childSections.end() ) {\n                    node = std::make_shared<SectionNode>( incompleteStats );\n                    parentNode.childSections.push_back( node );\n                }\n                else\n                    node = *it;\n            }\n            m_sectionStack.push_back( node );\n            m_deepestSection = std::move(node);\n        }\n\n        void assertionStarting(AssertionInfo const&) override {}\n\n        bool assertionEnded(AssertionStats const& assertionStats) override {\n            assert(!m_sectionStack.empty());\n            // AssertionResult holds a pointer to a temporary DecomposedExpression,\n            // which getExpandedExpression() calls to build the expression string.\n            // Our section stack copy of the assertionResult will likely outlive the\n            // temporary, so it must be expanded or discarded now to avoid calling\n            // a destroyed object later.\n            prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );\n            SectionNode& sectionNode = *m_sectionStack.back();\n            sectionNode.assertions.push_back(assertionStats);\n            return true;\n        }\n        void sectionEnded(SectionStats const& sectionStats) override {\n            assert(!m_sectionStack.empty());\n            SectionNode& node = *m_sectionStack.back();\n            node.stats = sectionStats;\n            m_sectionStack.pop_back();\n        }\n        void testCaseEnded(TestCaseStats const& testCaseStats) override {\n            auto node = std::make_shared<TestCaseNode>(testCaseStats);\n            assert(m_sectionStack.size() == 0);\n            node->children.push_back(m_rootSection);\n            m_testCases.push_back(node);\n            m_rootSection.reset();\n\n            assert(m_deepestSection);\n            m_deepestSection->stdOut = testCaseStats.stdOut;\n            m_deepestSection->stdErr = testCaseStats.stdErr;\n        }\n        void testGroupEnded(TestGroupStats const& testGroupStats) override {\n            auto node = std::make_shared<TestGroupNode>(testGroupStats);\n            node->children.swap(m_testCases);\n            m_testGroups.push_back(node);\n        }\n        void testRunEnded(TestRunStats const& testRunStats) override {\n            auto node = std::make_shared<TestRunNode>(testRunStats);\n            node->children.swap(m_testGroups);\n            m_testRuns.push_back(node);\n            testRunEndedCumulative();\n        }\n        virtual void testRunEndedCumulative() = 0;\n\n        void skipTest(TestCaseInfo const&) override {}\n\n        IConfigPtr m_config;\n        std::ostream& stream;\n        std::vector<AssertionStats> m_assertions;\n        std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;\n        std::vector<std::shared_ptr<TestCaseNode>> m_testCases;\n        std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;\n\n        std::vector<std::shared_ptr<TestRunNode>> m_testRuns;\n\n        std::shared_ptr<SectionNode> m_rootSection;\n        std::shared_ptr<SectionNode> m_deepestSection;\n        std::vector<std::shared_ptr<SectionNode>> m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n    };\n\n    template<char C>\n    char const* getLineOfChars() {\n        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};\n        if( !*line ) {\n            std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );\n            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;\n        }\n        return line;\n    }\n\n    struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {\n        TestEventListenerBase( ReporterConfig const& _config );\n\n        static std::set<Verbosity> getSupportedVerbosities();\n\n        void assertionStarting(AssertionInfo const&) override;\n        bool assertionEnded(AssertionStats const&) override;\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_bases.hpp\n// start catch_console_colour.h\n\nnamespace Catch {\n\n    struct Colour {\n        enum Code {\n            None = 0,\n\n            White,\n            Red,\n            Green,\n            Blue,\n            Cyan,\n            Yellow,\n            Grey,\n\n            Bright = 0x10,\n\n            BrightRed = Bright | Red,\n            BrightGreen = Bright | Green,\n            LightGrey = Bright | Grey,\n            BrightWhite = Bright | White,\n            BrightYellow = Bright | Yellow,\n\n            // By intention\n            FileName = LightGrey,\n            Warning = BrightYellow,\n            ResultError = BrightRed,\n            ResultSuccess = BrightGreen,\n            ResultExpectedFailure = Warning,\n\n            Error = BrightRed,\n            Success = Green,\n\n            OriginalExpression = Cyan,\n            ReconstructedExpression = BrightYellow,\n\n            SecondaryText = LightGrey,\n            Headers = White\n        };\n\n        // Use constructed object for RAII guard\n        Colour( Code _colourCode );\n        Colour( Colour&& other ) noexcept;\n        Colour& operator=( Colour&& other ) noexcept;\n        ~Colour();\n\n        // Use static method for one-shot changes\n        static void use( Code _colourCode );\n\n    private:\n        bool m_moved = false;\n    };\n\n    std::ostream& operator << ( std::ostream& os, Colour const& );\n\n} // end namespace Catch\n\n// end catch_console_colour.h\n// start catch_reporter_registrars.hpp\n\n\nnamespace Catch {\n\n    template<typename T>\n    class ReporterRegistrar {\n\n        class ReporterFactory : public IReporterFactory {\n\n            IStreamingReporterPtr create( ReporterConfig const& config ) const override {\n                return std::unique_ptr<T>( new T( config ) );\n            }\n\n            std::string getDescription() const override {\n                return T::getDescription();\n            }\n        };\n\n    public:\n\n        explicit ReporterRegistrar( std::string const& name ) {\n            getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );\n        }\n    };\n\n    template<typename T>\n    class ListenerRegistrar {\n\n        class ListenerFactory : public IReporterFactory {\n\n            IStreamingReporterPtr create( ReporterConfig const& config ) const override {\n                return std::unique_ptr<T>( new T( config ) );\n            }\n            std::string getDescription() const override {\n                return std::string();\n            }\n        };\n\n    public:\n\n        ListenerRegistrar() {\n            getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );\n        }\n    };\n}\n\n#if !defined(CATCH_CONFIG_DISABLE)\n\n#define CATCH_REGISTER_REPORTER( name, reporterType ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \\\n    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n#define CATCH_REGISTER_LISTENER( listenerType ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \\\n    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n#else // CATCH_CONFIG_DISABLE\n\n#define CATCH_REGISTER_REPORTER(name, reporterType)\n#define CATCH_REGISTER_LISTENER(listenerType)\n\n#endif // CATCH_CONFIG_DISABLE\n\n// end catch_reporter_registrars.hpp\n// Allow users to base their work off existing reporters\n// start catch_reporter_compact.h\n\nnamespace Catch {\n\n    struct CompactReporter : StreamingReporterBase<CompactReporter> {\n\n        using StreamingReporterBase::StreamingReporterBase;\n\n        ~CompactReporter() override;\n\n        static std::string getDescription();\n\n        void noMatchingTestCases(std::string const& spec) override;\n\n        void assertionStarting(AssertionInfo const&) override;\n\n        bool assertionEnded(AssertionStats const& _assertionStats) override;\n\n        void sectionEnded(SectionStats const& _sectionStats) override;\n\n        void testRunEnded(TestRunStats const& _testRunStats) override;\n\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_compact.h\n// start catch_reporter_console.h\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch\n                              // Note that 4062 (not all labels are handled\n                              // and default is missing) is enabled\n#endif\n\nnamespace Catch {\n    // Fwd decls\n    struct SummaryColumn;\n    class TablePrinter;\n\n    struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {\n        std::unique_ptr<TablePrinter> m_tablePrinter;\n\n        ConsoleReporter(ReporterConfig const& config);\n        ~ConsoleReporter() override;\n        static std::string getDescription();\n\n        void noMatchingTestCases(std::string const& spec) override;\n\n        void reportInvalidArguments(std::string const&arg) override;\n\n        void assertionStarting(AssertionInfo const&) override;\n\n        bool assertionEnded(AssertionStats const& _assertionStats) override;\n\n        void sectionStarting(SectionInfo const& _sectionInfo) override;\n        void sectionEnded(SectionStats const& _sectionStats) override;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing(std::string const& name) override;\n        void benchmarkStarting(BenchmarkInfo const& info) override;\n        void benchmarkEnded(BenchmarkStats<> const& stats) override;\n        void benchmarkFailed(std::string const& error) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        void testCaseEnded(TestCaseStats const& _testCaseStats) override;\n        void testGroupEnded(TestGroupStats const& _testGroupStats) override;\n        void testRunEnded(TestRunStats const& _testRunStats) override;\n        void testRunStarting(TestRunInfo const& _testRunInfo) override;\n    private:\n\n        void lazyPrint();\n\n        void lazyPrintWithoutClosingBenchmarkTable();\n        void lazyPrintRunInfo();\n        void lazyPrintGroupInfo();\n        void printTestCaseAndSectionHeader();\n\n        void printClosedHeader(std::string const& _name);\n        void printOpenHeader(std::string const& _name);\n\n        // if string has a : in first line will set indent to follow it on\n        // subsequent lines\n        void printHeaderString(std::string const& _string, std::size_t indent = 0);\n\n        void printTotals(Totals const& totals);\n        void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);\n\n        void printTotalsDivider(Totals const& totals);\n        void printSummaryDivider();\n        void printTestFilters();\n\n    private:\n        bool m_headerPrinted = false;\n    };\n\n} // end namespace Catch\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n// end catch_reporter_console.h\n// start catch_reporter_junit.h\n\n// start catch_xmlwriter.h\n\n#include <vector>\n\nnamespace Catch {\n    enum class XmlFormatting {\n        None = 0x00,\n        Indent = 0x01,\n        Newline = 0x02,\n    };\n\n    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);\n    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);\n\n    class XmlEncode {\n    public:\n        enum ForWhat { ForTextNodes, ForAttributes };\n\n        XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );\n\n        void encodeTo( std::ostream& os ) const;\n\n        friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );\n\n    private:\n        std::string m_str;\n        ForWhat m_forWhat;\n    };\n\n    class XmlWriter {\n    public:\n\n        class ScopedElement {\n        public:\n            ScopedElement( XmlWriter* writer, XmlFormatting fmt );\n\n            ScopedElement( ScopedElement&& other ) noexcept;\n            ScopedElement& operator=( ScopedElement&& other ) noexcept;\n\n            ~ScopedElement();\n\n            ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );\n\n            template<typename T>\n            ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {\n                m_writer->writeAttribute( name, attribute );\n                return *this;\n            }\n\n        private:\n            mutable XmlWriter* m_writer = nullptr;\n            XmlFormatting m_fmt;\n        };\n\n        XmlWriter( std::ostream& os = Catch::cout() );\n        ~XmlWriter();\n\n        XmlWriter( XmlWriter const& ) = delete;\n        XmlWriter& operator=( XmlWriter const& ) = delete;\n\n        XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );\n\n        XmlWriter& writeAttribute( std::string const& name, bool attribute );\n\n        template<typename T>\n        XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {\n            ReusableStringStream rss;\n            rss << attribute;\n            return writeAttribute( name, rss.str() );\n        }\n\n        XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        void writeStylesheetRef( std::string const& url );\n\n        XmlWriter& writeBlankLine();\n\n        void ensureTagClosed();\n\n    private:\n\n        void applyFormatting(XmlFormatting fmt);\n\n        void writeDeclaration();\n\n        void newlineIfNecessary();\n\n        bool m_tagIsOpen = false;\n        bool m_needsNewline = false;\n        std::vector<std::string> m_tags;\n        std::string m_indent;\n        std::ostream& m_os;\n    };\n\n}\n\n// end catch_xmlwriter.h\nnamespace Catch {\n\n    class JunitReporter : public CumulativeReporterBase<JunitReporter> {\n    public:\n        JunitReporter(ReporterConfig const& _config);\n\n        ~JunitReporter() override;\n\n        static std::string getDescription();\n\n        void noMatchingTestCases(std::string const& /*spec*/) override;\n\n        void testRunStarting(TestRunInfo const& runInfo) override;\n\n        void testGroupStarting(GroupInfo const& groupInfo) override;\n\n        void testCaseStarting(TestCaseInfo const& testCaseInfo) override;\n        bool assertionEnded(AssertionStats const& assertionStats) override;\n\n        void testCaseEnded(TestCaseStats const& testCaseStats) override;\n\n        void testGroupEnded(TestGroupStats const& testGroupStats) override;\n\n        void testRunEndedCumulative() override;\n\n        void writeGroup(TestGroupNode const& groupNode, double suiteTime);\n\n        void writeTestCase(TestCaseNode const& testCaseNode);\n\n        void writeSection( std::string const& className,\n                           std::string const& rootName,\n                           SectionNode const& sectionNode,\n                           bool testOkToFail );\n\n        void writeAssertions(SectionNode const& sectionNode);\n        void writeAssertion(AssertionStats const& stats);\n\n        XmlWriter xml;\n        Timer suiteTimer;\n        std::string stdOutForSuite;\n        std::string stdErrForSuite;\n        unsigned int unexpectedExceptions = 0;\n        bool m_okToFail = false;\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_junit.h\n// start catch_reporter_xml.h\n\nnamespace Catch {\n    class XmlReporter : public StreamingReporterBase<XmlReporter> {\n    public:\n        XmlReporter(ReporterConfig const& _config);\n\n        ~XmlReporter() override;\n\n        static std::string getDescription();\n\n        virtual std::string getStylesheetRef() const;\n\n        void writeSourceInfo(SourceLineInfo const& sourceInfo);\n\n    public: // StreamingReporterBase\n\n        void noMatchingTestCases(std::string const& s) override;\n\n        void testRunStarting(TestRunInfo const& testInfo) override;\n\n        void testGroupStarting(GroupInfo const& groupInfo) override;\n\n        void testCaseStarting(TestCaseInfo const& testInfo) override;\n\n        void sectionStarting(SectionInfo const& sectionInfo) override;\n\n        void assertionStarting(AssertionInfo const&) override;\n\n        bool assertionEnded(AssertionStats const& assertionStats) override;\n\n        void sectionEnded(SectionStats const& sectionStats) override;\n\n        void testCaseEnded(TestCaseStats const& testCaseStats) override;\n\n        void testGroupEnded(TestGroupStats const& testGroupStats) override;\n\n        void testRunEnded(TestRunStats const& testRunStats) override;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing(std::string const& name) override;\n        void benchmarkStarting(BenchmarkInfo const&) override;\n        void benchmarkEnded(BenchmarkStats<> const&) override;\n        void benchmarkFailed(std::string const&) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    private:\n        Timer m_testCaseTimer;\n        XmlWriter m_xml;\n        int m_sectionDepth = 0;\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_xml.h\n\n// end catch_external_interfaces.h\n#endif\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n// start catch_benchmarking_all.hpp\n\n// A proxy header that includes all of the benchmarking headers to allow\n// concise include of the benchmarking features. You should prefer the\n// individual includes in standard use.\n\n// start catch_benchmark.hpp\n\n // Benchmark\n\n// start catch_chronometer.hpp\n\n// User-facing chronometer\n\n\n// start catch_clock.hpp\n\n// Clocks\n\n\n#include <chrono>\n#include <ratio>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Clock>\n        using ClockDuration = typename Clock::duration;\n        template <typename Clock>\n        using FloatDuration = std::chrono::duration<double, typename Clock::period>;\n\n        template <typename Clock>\n        using TimePoint = typename Clock::time_point;\n\n        using default_clock = std::chrono::steady_clock;\n\n        template <typename Clock>\n        struct now {\n            TimePoint<Clock> operator()() const {\n                return Clock::now();\n            }\n        };\n\n        using fp_seconds = std::chrono::duration<double, std::ratio<1>>;\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_clock.hpp\n// start catch_optimizer.hpp\n\n // Hinting the optimizer\n\n\n#if defined(_MSC_VER)\n#   include <atomic> // atomic_thread_fence\n#endif\n\nnamespace Catch {\n    namespace Benchmark {\n#if defined(__GNUC__) || defined(__clang__)\n        template <typename T>\n        inline void keep_memory(T* p) {\n            asm volatile(\"\" : : \"g\"(p) : \"memory\");\n        }\n        inline void keep_memory() {\n            asm volatile(\"\" : : : \"memory\");\n        }\n\n        namespace Detail {\n            inline void optimizer_barrier() { keep_memory(); }\n        } // namespace Detail\n#elif defined(_MSC_VER)\n\n#pragma optimize(\"\", off)\n        template <typename T>\n        inline void keep_memory(T* p) {\n            // thanks @milleniumbug\n            *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);\n        }\n        // TODO equivalent keep_memory()\n#pragma optimize(\"\", on)\n\n        namespace Detail {\n            inline void optimizer_barrier() {\n                std::atomic_thread_fence(std::memory_order_seq_cst);\n            }\n        } // namespace Detail\n\n#endif\n\n        template <typename T>\n        inline void deoptimize_value(T&& x) {\n            keep_memory(&x);\n        }\n\n        template <typename Fn, typename... Args>\n        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {\n            deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));\n        }\n\n        template <typename Fn, typename... Args>\n        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {\n            std::forward<Fn>(fn) (std::forward<Args...>(args...));\n        }\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_optimizer.hpp\n// start catch_complete_invoke.hpp\n\n// Invoke with a special case for void\n\n\n#include <type_traits>\n#include <utility>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename T>\n            struct CompleteType { using type = T; };\n            template <>\n            struct CompleteType<void> { struct type {}; };\n\n            template <typename T>\n            using CompleteType_t = typename CompleteType<T>::type;\n\n            template <typename Result>\n            struct CompleteInvoker {\n                template <typename Fun, typename... Args>\n                static Result invoke(Fun&& fun, Args&&... args) {\n                    return std::forward<Fun>(fun)(std::forward<Args>(args)...);\n                }\n            };\n            template <>\n            struct CompleteInvoker<void> {\n                template <typename Fun, typename... Args>\n                static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {\n                    std::forward<Fun>(fun)(std::forward<Args>(args)...);\n                    return {};\n                }\n            };\n\n            // invoke and not return void :(\n            template <typename Fun, typename... Args>\n            CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {\n                return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);\n            }\n\n            const std::string benchmarkErrorMsg = \"a benchmark failed to run successfully\";\n        } // namespace Detail\n\n        template <typename Fun>\n        Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {\n            CATCH_TRY{\n                return Detail::complete_invoke(std::forward<Fun>(fun));\n            } CATCH_CATCH_ALL{\n                getResultCapture().benchmarkFailed(translateActiveException());\n                CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);\n            }\n        }\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_complete_invoke.hpp\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            struct ChronometerConcept {\n                virtual void start() = 0;\n                virtual void finish() = 0;\n                virtual ~ChronometerConcept() = default;\n            };\n            template <typename Clock>\n            struct ChronometerModel final : public ChronometerConcept {\n                void start() override { started = Clock::now(); }\n                void finish() override { finished = Clock::now(); }\n\n                ClockDuration<Clock> elapsed() const { return finished - started; }\n\n                TimePoint<Clock> started;\n                TimePoint<Clock> finished;\n            };\n        } // namespace Detail\n\n        struct Chronometer {\n        public:\n            template <typename Fun>\n            void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }\n\n            int runs() const { return k; }\n\n            Chronometer(Detail::ChronometerConcept& meter, int k)\n                : impl(&meter)\n                , k(k) {}\n\n        private:\n            template <typename Fun>\n            void measure(Fun&& fun, std::false_type) {\n                measure([&fun](int) { return fun(); }, std::true_type());\n            }\n\n            template <typename Fun>\n            void measure(Fun&& fun, std::true_type) {\n                Detail::optimizer_barrier();\n                impl->start();\n                for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);\n                impl->finish();\n                Detail::optimizer_barrier();\n            }\n\n            Detail::ChronometerConcept* impl;\n            int k;\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_chronometer.hpp\n// start catch_environment.hpp\n\n// Environment information\n\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct EnvironmentEstimate {\n            Duration mean;\n            OutlierClassification outliers;\n\n            template <typename Duration2>\n            operator EnvironmentEstimate<Duration2>() const {\n                return { mean, outliers };\n            }\n        };\n        template <typename Clock>\n        struct Environment {\n            using clock_type = Clock;\n            EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;\n            EnvironmentEstimate<FloatDuration<Clock>> clock_cost;\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_environment.hpp\n// start catch_execution_plan.hpp\n\n // Execution plan\n\n\n// start catch_benchmark_function.hpp\n\n // Dumb std::function implementation for consistent call overhead\n\n\n#include <cassert>\n#include <type_traits>\n#include <utility>\n#include <memory>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename T>\n            using Decay = typename std::decay<T>::type;\n            template <typename T, typename U>\n            struct is_related\n                : std::is_same<Decay<T>, Decay<U>> {};\n\n            /// We need to reinvent std::function because every piece of code that might add overhead\n            /// in a measurement context needs to have consistent performance characteristics so that we\n            /// can account for it in the measurement.\n            /// Implementations of std::function with optimizations that aren't always applicable, like\n            /// small buffer optimizations, are not uncommon.\n            /// This is effectively an implementation of std::function without any such optimizations;\n            /// it may be slow, but it is consistently slow.\n            struct BenchmarkFunction {\n            private:\n                struct callable {\n                    virtual void call(Chronometer meter) const = 0;\n                    virtual callable* clone() const = 0;\n                    virtual ~callable() = default;\n                };\n                template <typename Fun>\n                struct model : public callable {\n                    model(Fun&& fun) : fun(std::move(fun)) {}\n                    model(Fun const& fun) : fun(fun) {}\n\n                    model<Fun>* clone() const override { return new model<Fun>(*this); }\n\n                    void call(Chronometer meter) const override {\n                        call(meter, is_callable<Fun(Chronometer)>());\n                    }\n                    void call(Chronometer meter, std::true_type) const {\n                        fun(meter);\n                    }\n                    void call(Chronometer meter, std::false_type) const {\n                        meter.measure(fun);\n                    }\n\n                    Fun fun;\n                };\n\n                struct do_nothing { void operator()() const {} };\n\n                template <typename T>\n                BenchmarkFunction(model<T>* c) : f(c) {}\n\n            public:\n                BenchmarkFunction()\n                    : f(new model<do_nothing>{ {} }) {}\n\n                template <typename Fun,\n                    typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>\n                    BenchmarkFunction(Fun&& fun)\n                    : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}\n\n                BenchmarkFunction(BenchmarkFunction&& that)\n                    : f(std::move(that.f)) {}\n\n                BenchmarkFunction(BenchmarkFunction const& that)\n                    : f(that.f->clone()) {}\n\n                BenchmarkFunction& operator=(BenchmarkFunction&& that) {\n                    f = std::move(that.f);\n                    return *this;\n                }\n\n                BenchmarkFunction& operator=(BenchmarkFunction const& that) {\n                    f.reset(that.f->clone());\n                    return *this;\n                }\n\n                void operator()(Chronometer meter) const { f->call(meter); }\n\n            private:\n                std::unique_ptr<callable> f;\n            };\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_benchmark_function.hpp\n// start catch_repeat.hpp\n\n// repeat algorithm\n\n\n#include <type_traits>\n#include <utility>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Fun>\n            struct repeater {\n                void operator()(int k) const {\n                    for (int i = 0; i < k; ++i) {\n                        fun();\n                    }\n                }\n                Fun fun;\n            };\n            template <typename Fun>\n            repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {\n                return { std::forward<Fun>(fun) };\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_repeat.hpp\n// start catch_run_for_at_least.hpp\n\n// Run a function for a minimum amount of time\n\n\n// start catch_measure.hpp\n\n// Measure\n\n\n// start catch_timing.hpp\n\n// Timing\n\n\n#include <tuple>\n#include <type_traits>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration, typename Result>\n        struct Timing {\n            Duration elapsed;\n            Result result;\n            int iterations;\n        };\n        template <typename Clock, typename Func, typename... Args>\n        using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_timing.hpp\n#include <utility>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Clock, typename Fun, typename... Args>\n            TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {\n                auto start = Clock::now();\n                auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);\n                auto end = Clock::now();\n                auto delta = end - start;\n                return { delta, std::forward<decltype(r)>(r), 1 };\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_measure.hpp\n#include <utility>\n#include <type_traits>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Clock, typename Fun>\n            TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {\n                return Detail::measure<Clock>(fun, iters);\n            }\n            template <typename Clock, typename Fun>\n            TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {\n                Detail::ChronometerModel<Clock> meter;\n                auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));\n\n                return { meter.elapsed(), std::move(result), iters };\n            }\n\n            template <typename Clock, typename Fun>\n            using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;\n\n            struct optimized_away_error : std::exception {\n                const char* what() const noexcept override {\n                    return \"could not measure benchmark, maybe it was optimized away\";\n                }\n            };\n\n            template <typename Clock, typename Fun>\n            TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {\n                auto iters = seed;\n                while (iters < (1 << 30)) {\n                    auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());\n\n                    if (Timing.elapsed >= how_long) {\n                        return { Timing.elapsed, std::move(Timing.result), iters };\n                    }\n                    iters *= 2;\n                }\n                Catch::throw_exception(optimized_away_error{});\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_run_for_at_least.hpp\n#include <algorithm>\n#include <iterator>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct ExecutionPlan {\n            int iterations_per_sample;\n            Duration estimated_duration;\n            Detail::BenchmarkFunction benchmark;\n            Duration warmup_time;\n            int warmup_iterations;\n\n            template <typename Duration2>\n            operator ExecutionPlan<Duration2>() const {\n                return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };\n            }\n\n            template <typename Clock>\n            std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {\n                // warmup a bit\n                Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));\n\n                std::vector<FloatDuration<Clock>> times;\n                times.reserve(cfg.benchmarkSamples());\n                std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {\n                    Detail::ChronometerModel<Clock> model;\n                    this->benchmark(Chronometer(model, iterations_per_sample));\n                    auto sample_time = model.elapsed() - env.clock_cost.mean;\n                    if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();\n                    return sample_time / iterations_per_sample;\n                });\n                return times;\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_execution_plan.hpp\n// start catch_estimate_clock.hpp\n\n // Environment measurement\n\n\n// start catch_stats.hpp\n\n// Statistical analysis tools\n\n\n#include <algorithm>\n#include <functional>\n#include <vector>\n#include <iterator>\n#include <numeric>\n#include <tuple>\n#include <cmath>\n#include <utility>\n#include <cstddef>\n#include <random>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            using sample = std::vector<double>;\n\n            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);\n\n            template <typename Iterator>\n            OutlierClassification classify_outliers(Iterator first, Iterator last) {\n                std::vector<double> copy(first, last);\n\n                auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());\n                auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());\n                auto iqr = q3 - q1;\n                auto los = q1 - (iqr * 3.);\n                auto lom = q1 - (iqr * 1.5);\n                auto him = q3 + (iqr * 1.5);\n                auto his = q3 + (iqr * 3.);\n\n                OutlierClassification o;\n                for (; first != last; ++first) {\n                    auto&& t = *first;\n                    if (t < los) ++o.low_severe;\n                    else if (t < lom) ++o.low_mild;\n                    else if (t > his) ++o.high_severe;\n                    else if (t > him) ++o.high_mild;\n                    ++o.samples_seen;\n                }\n                return o;\n            }\n\n            template <typename Iterator>\n            double mean(Iterator first, Iterator last) {\n                auto count = last - first;\n                double sum = std::accumulate(first, last, 0.);\n                return sum / count;\n            }\n\n            template <typename URng, typename Iterator, typename Estimator>\n            sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {\n                auto n = last - first;\n                std::uniform_int_distribution<decltype(n)> dist(0, n - 1);\n\n                sample out;\n                out.reserve(resamples);\n                std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {\n                    std::vector<double> resampled;\n                    resampled.reserve(n);\n                    std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });\n                    return estimator(resampled.begin(), resampled.end());\n                });\n                std::sort(out.begin(), out.end());\n                return out;\n            }\n\n            template <typename Estimator, typename Iterator>\n            sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {\n                auto n = last - first;\n                auto second = std::next(first);\n                sample results;\n                results.reserve(n);\n\n                for (auto it = first; it != last; ++it) {\n                    std::iter_swap(it, first);\n                    results.push_back(estimator(second, last));\n                }\n\n                return results;\n            }\n\n            inline double normal_cdf(double x) {\n                return std::erfc(-x / std::sqrt(2.0)) / 2.0;\n            }\n\n            double erfc_inv(double x);\n\n            double normal_quantile(double p);\n\n            template <typename Iterator, typename Estimator>\n            Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {\n                auto n_samples = last - first;\n\n                double point = estimator(first, last);\n                // Degenerate case with a single sample\n                if (n_samples == 1) return { point, point, point, confidence_level };\n\n                sample jack = jackknife(estimator, first, last);\n                double jack_mean = mean(jack.begin(), jack.end());\n                double sum_squares, sum_cubes;\n                std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {\n                    auto d = jack_mean - x;\n                    auto d2 = d * d;\n                    auto d3 = d2 * d;\n                    return { sqcb.first + d2, sqcb.second + d3 };\n                });\n\n                double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));\n                int n = static_cast<int>(resample.size());\n                double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;\n                // degenerate case with uniform samples\n                if (prob_n == 0) return { point, point, point, confidence_level };\n\n                double bias = normal_quantile(prob_n);\n                double z1 = normal_quantile((1. - confidence_level) / 2.);\n\n                auto cumn = [n](double x) -> int {\n                    return std::lround(normal_cdf(x) * n); };\n                auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };\n                double b1 = bias + z1;\n                double b2 = bias - z1;\n                double a1 = a(b1);\n                double a2 = a(b2);\n                auto lo = (std::max)(cumn(a1), 0);\n                auto hi = (std::min)(cumn(a2), n - 1);\n\n                return { point, resample[lo], resample[hi], confidence_level };\n            }\n\n            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);\n\n            struct bootstrap_analysis {\n                Estimate<double> mean;\n                Estimate<double> standard_deviation;\n                double outlier_variance;\n            };\n\n            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_stats.hpp\n#include <algorithm>\n#include <iterator>\n#include <tuple>\n#include <vector>\n#include <cmath>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Clock>\n            std::vector<double> resolution(int k) {\n                std::vector<TimePoint<Clock>> times;\n                times.reserve(k + 1);\n                std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});\n\n                std::vector<double> deltas;\n                deltas.reserve(k);\n                std::transform(std::next(times.begin()), times.end(), times.begin(),\n                    std::back_inserter(deltas),\n                    [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });\n\n                return deltas;\n            }\n\n            const auto warmup_iterations = 10000;\n            const auto warmup_time = std::chrono::milliseconds(100);\n            const auto minimum_ticks = 1000;\n            const auto warmup_seed = 10000;\n            const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);\n            const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);\n            const auto clock_cost_estimation_tick_limit = 100000;\n            const auto clock_cost_estimation_time = std::chrono::milliseconds(10);\n            const auto clock_cost_estimation_iterations = 10000;\n\n            template <typename Clock>\n            int warmup() {\n                return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)\n                    .iterations;\n            }\n            template <typename Clock>\n            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {\n                auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)\n                    .result;\n                return {\n                    FloatDuration<Clock>(mean(r.begin(), r.end())),\n                    classify_outliers(r.begin(), r.end()),\n                };\n            }\n            template <typename Clock>\n            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {\n                auto time_limit = (std::min)(\n                    resolution * clock_cost_estimation_tick_limit,\n                    FloatDuration<Clock>(clock_cost_estimation_time_limit));\n                auto time_clock = [](int k) {\n                    return Detail::measure<Clock>([k] {\n                        for (int i = 0; i < k; ++i) {\n                            volatile auto ignored = Clock::now();\n                            (void)ignored;\n                        }\n                    }).elapsed;\n                };\n                time_clock(1);\n                int iters = clock_cost_estimation_iterations;\n                auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);\n                std::vector<double> times;\n                int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));\n                times.reserve(nsamples);\n                std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {\n                    return static_cast<double>((time_clock(r.iterations) / r.iterations).count());\n                });\n                return {\n                    FloatDuration<Clock>(mean(times.begin(), times.end())),\n                    classify_outliers(times.begin(), times.end()),\n                };\n            }\n\n            template <typename Clock>\n            Environment<FloatDuration<Clock>> measure_environment() {\n                static Environment<FloatDuration<Clock>>* env = nullptr;\n                if (env) {\n                    return *env;\n                }\n\n                auto iters = Detail::warmup<Clock>();\n                auto resolution = Detail::estimate_clock_resolution<Clock>(iters);\n                auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);\n\n                env = new Environment<FloatDuration<Clock>>{ resolution, cost };\n                return *env;\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_estimate_clock.hpp\n// start catch_analyse.hpp\n\n // Run and analyse one benchmark\n\n\n// start catch_sample_analysis.hpp\n\n// Benchmark results\n\n\n#include <algorithm>\n#include <vector>\n#include <string>\n#include <iterator>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct SampleAnalysis {\n            std::vector<Duration> samples;\n            Estimate<Duration> mean;\n            Estimate<Duration> standard_deviation;\n            OutlierClassification outliers;\n            double outlier_variance;\n\n            template <typename Duration2>\n            operator SampleAnalysis<Duration2>() const {\n                std::vector<Duration2> samples2;\n                samples2.reserve(samples.size());\n                std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });\n                return {\n                    std::move(samples2),\n                    mean,\n                    standard_deviation,\n                    outliers,\n                    outlier_variance,\n                };\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_sample_analysis.hpp\n#include <algorithm>\n#include <iterator>\n#include <vector>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Duration, typename Iterator>\n            SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {\n                if (!cfg.benchmarkNoAnalysis()) {\n                    std::vector<double> samples;\n                    samples.reserve(last - first);\n                    std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });\n\n                    auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());\n                    auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());\n\n                    auto wrap_estimate = [](Estimate<double> e) {\n                        return Estimate<Duration> {\n                            Duration(e.point),\n                                Duration(e.lower_bound),\n                                Duration(e.upper_bound),\n                                e.confidence_interval,\n                        };\n                    };\n                    std::vector<Duration> samples2;\n                    samples2.reserve(samples.size());\n                    std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });\n                    return {\n                        std::move(samples2),\n                        wrap_estimate(analysis.mean),\n                        wrap_estimate(analysis.standard_deviation),\n                        outliers,\n                        analysis.outlier_variance,\n                    };\n                } else {\n                    std::vector<Duration> samples;\n                    samples.reserve(last - first);\n\n                    Duration mean = Duration(0);\n                    int i = 0;\n                    for (auto it = first; it < last; ++it, ++i) {\n                        samples.push_back(Duration(*it));\n                        mean += Duration(*it);\n                    }\n                    mean /= i;\n\n                    return {\n                        std::move(samples),\n                        Estimate<Duration>{mean, mean, mean, 0.0},\n                        Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},\n                        OutlierClassification{},\n                        0.0\n                    };\n                }\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_analyse.hpp\n#include <algorithm>\n#include <functional>\n#include <string>\n#include <vector>\n#include <cmath>\n\nnamespace Catch {\n    namespace Benchmark {\n        struct Benchmark {\n            Benchmark(std::string &&name)\n                : name(std::move(name)) {}\n\n            template <class FUN>\n            Benchmark(std::string &&name, FUN &&func)\n                : fun(std::move(func)), name(std::move(name)) {}\n\n            template <typename Clock>\n            ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {\n                auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;\n                auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));\n                auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);\n                int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));\n                return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };\n            }\n\n            template <typename Clock = default_clock>\n            void run() {\n                IConfigPtr cfg = getCurrentContext().getConfig();\n\n                auto env = Detail::measure_environment<Clock>();\n\n                getResultCapture().benchmarkPreparing(name);\n                CATCH_TRY{\n                    auto plan = user_code([&] {\n                        return prepare<Clock>(*cfg, env);\n                    });\n\n                    BenchmarkInfo info {\n                        name,\n                        plan.estimated_duration.count(),\n                        plan.iterations_per_sample,\n                        cfg->benchmarkSamples(),\n                        cfg->benchmarkResamples(),\n                        env.clock_resolution.mean.count(),\n                        env.clock_cost.mean.count()\n                    };\n\n                    getResultCapture().benchmarkStarting(info);\n\n                    auto samples = user_code([&] {\n                        return plan.template run<Clock>(*cfg, env);\n                    });\n\n                    auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());\n                    BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };\n                    getResultCapture().benchmarkEnded(stats);\n\n                } CATCH_CATCH_ALL{\n                    if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.\n                        std::rethrow_exception(std::current_exception());\n                }\n            }\n\n            // sets lambda to be used in fun *and* executes benchmark!\n            template <typename Fun,\n                typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>\n                Benchmark & operator=(Fun func) {\n                fun = Detail::BenchmarkFunction(func);\n                run();\n                return *this;\n            }\n\n            explicit operator bool() {\n                return true;\n            }\n\n        private:\n            Detail::BenchmarkFunction fun;\n            std::string name;\n        };\n    }\n} // namespace Catch\n\n#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1\n#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2\n\n#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\\\n    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \\\n        BenchmarkName = [&](int benchmarkIndex)\n\n#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\\\n    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \\\n        BenchmarkName = [&]\n\n// end catch_benchmark.hpp\n// start catch_constructor.hpp\n\n// Constructor and destructor helpers\n\n\n#include <type_traits>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename T, bool Destruct>\n            struct ObjectStorage\n            {\n                ObjectStorage() : data() {}\n\n                ObjectStorage(const ObjectStorage& other)\n                {\n                    new(&data) T(other.stored_object());\n                }\n\n                ObjectStorage(ObjectStorage&& other)\n                {\n                    new(&data) T(std::move(other.stored_object()));\n                }\n\n                ~ObjectStorage() { destruct_on_exit<T>(); }\n\n                template <typename... Args>\n                void construct(Args&&... args)\n                {\n                    new (&data) T(std::forward<Args>(args)...);\n                }\n\n                template <bool AllowManualDestruction = !Destruct>\n                typename std::enable_if<AllowManualDestruction>::type destruct()\n                {\n                    stored_object().~T();\n                }\n\n            private:\n                // If this is a constructor benchmark, destruct the underlying object\n                template <typename U>\n                void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }\n                // Otherwise, don't\n                template <typename U>\n                void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }\n\n                T& stored_object() {\n                    return *static_cast<T*>(static_cast<void*>(&data));\n                }\n\n                T const& stored_object() const {\n                    return *static_cast<T*>(static_cast<void*>(&data));\n                }\n\n                struct { alignas(T) unsigned char data[sizeof(T)]; }  data;\n            };\n        }\n\n        template <typename T>\n        using storage_for = Detail::ObjectStorage<T, true>;\n\n        template <typename T>\n        using destructable_object = Detail::ObjectStorage<T, false>;\n    }\n}\n\n// end catch_constructor.hpp\n// end catch_benchmarking_all.hpp\n#endif\n\n#endif // ! CATCH_CONFIG_IMPL_ONLY\n\n#ifdef CATCH_IMPL\n// start catch_impl.hpp\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wweak-vtables\"\n#endif\n\n// Keep these here for external reporters\n// start catch_test_case_tracker.h\n\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\nnamespace TestCaseTracking {\n\n    struct NameAndLocation {\n        std::string name;\n        SourceLineInfo location;\n\n        NameAndLocation( std::string const& _name, SourceLineInfo const& _location );\n        friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {\n            return lhs.name == rhs.name\n                && lhs.location == rhs.location;\n        }\n    };\n\n    class ITracker;\n\n    using ITrackerPtr = std::shared_ptr<ITracker>;\n\n    class  ITracker {\n        NameAndLocation m_nameAndLocation;\n\n    public:\n        ITracker(NameAndLocation const& nameAndLoc) :\n            m_nameAndLocation(nameAndLoc)\n        {}\n\n        // static queries\n        NameAndLocation const& nameAndLocation() const {\n            return m_nameAndLocation;\n        }\n\n        virtual ~ITracker();\n\n        // dynamic queries\n        virtual bool isComplete() const = 0; // Successfully completed or failed\n        virtual bool isSuccessfullyCompleted() const = 0;\n        virtual bool isOpen() const = 0; // Started but not complete\n        virtual bool hasChildren() const = 0;\n        virtual bool hasStarted() const = 0;\n\n        virtual ITracker& parent() = 0;\n\n        // actions\n        virtual void close() = 0; // Successfully complete\n        virtual void fail() = 0;\n        virtual void markAsNeedingAnotherRun() = 0;\n\n        virtual void addChild( ITrackerPtr const& child ) = 0;\n        virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;\n        virtual void openChild() = 0;\n\n        // Debug/ checking\n        virtual bool isSectionTracker() const = 0;\n        virtual bool isGeneratorTracker() const = 0;\n    };\n\n    class TrackerContext {\n\n        enum RunState {\n            NotStarted,\n            Executing,\n            CompletedCycle\n        };\n\n        ITrackerPtr m_rootTracker;\n        ITracker* m_currentTracker = nullptr;\n        RunState m_runState = NotStarted;\n\n    public:\n\n        ITracker& startRun();\n        void endRun();\n\n        void startCycle();\n        void completeCycle();\n\n        bool completedCycle() const;\n        ITracker& currentTracker();\n        void setCurrentTracker( ITracker* tracker );\n    };\n\n    class TrackerBase : public ITracker {\n    protected:\n        enum CycleState {\n            NotStarted,\n            Executing,\n            ExecutingChildren,\n            NeedsAnotherRun,\n            CompletedSuccessfully,\n            Failed\n        };\n\n        using Children = std::vector<ITrackerPtr>;\n        TrackerContext& m_ctx;\n        ITracker* m_parent;\n        Children m_children;\n        CycleState m_runState = NotStarted;\n\n    public:\n        TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );\n\n        bool isComplete() const override;\n        bool isSuccessfullyCompleted() const override;\n        bool isOpen() const override;\n        bool hasChildren() const override;\n        bool hasStarted() const override {\n            return m_runState != NotStarted;\n        }\n\n        void addChild( ITrackerPtr const& child ) override;\n\n        ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;\n        ITracker& parent() override;\n\n        void openChild() override;\n\n        bool isSectionTracker() const override;\n        bool isGeneratorTracker() const override;\n\n        void open();\n\n        void close() override;\n        void fail() override;\n        void markAsNeedingAnotherRun() override;\n\n    private:\n        void moveToParent();\n        void moveToThis();\n    };\n\n    class SectionTracker : public TrackerBase {\n        std::vector<std::string> m_filters;\n        std::string m_trimmed_name;\n    public:\n        SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );\n\n        bool isSectionTracker() const override;\n\n        bool isComplete() const override;\n\n        static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );\n\n        void tryOpen();\n\n        void addInitialFilters( std::vector<std::string> const& filters );\n        void addNextFilters( std::vector<std::string> const& filters );\n        //! Returns filters active in this tracker\n        std::vector<std::string> const& getFilters() const;\n        //! Returns whitespace-trimmed name of the tracked section\n        std::string const& trimmedName() const;\n    };\n\n} // namespace TestCaseTracking\n\nusing TestCaseTracking::ITracker;\nusing TestCaseTracking::TrackerContext;\nusing TestCaseTracking::SectionTracker;\n\n} // namespace Catch\n\n// end catch_test_case_tracker.h\n\n// start catch_leak_detector.h\n\nnamespace Catch {\n\n    struct LeakDetector {\n        LeakDetector();\n        ~LeakDetector();\n    };\n\n}\n// end catch_leak_detector.h\n// Cpp files will be included in the single-header file here\n// start catch_stats.cpp\n\n// Statistical analysis tools\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n\n#include <cassert>\n#include <random>\n\n#if defined(CATCH_CONFIG_USE_ASYNC)\n#include <future>\n#endif\n\nnamespace {\n    double erf_inv(double x) {\n        // Code accompanying the article \"Approximating the erfinv function\" in GPU Computing Gems, Volume 2\n        double w, p;\n\n        w = -log((1.0 - x) * (1.0 + x));\n\n        if (w < 6.250000) {\n            w = w - 3.125000;\n            p = -3.6444120640178196996e-21;\n            p = -1.685059138182016589e-19 + p * w;\n            p = 1.2858480715256400167e-18 + p * w;\n            p = 1.115787767802518096e-17 + p * w;\n            p = -1.333171662854620906e-16 + p * w;\n            p = 2.0972767875968561637e-17 + p * w;\n            p = 6.6376381343583238325e-15 + p * w;\n            p = -4.0545662729752068639e-14 + p * w;\n            p = -8.1519341976054721522e-14 + p * w;\n            p = 2.6335093153082322977e-12 + p * w;\n            p = -1.2975133253453532498e-11 + p * w;\n            p = -5.4154120542946279317e-11 + p * w;\n            p = 1.051212273321532285e-09 + p * w;\n            p = -4.1126339803469836976e-09 + p * w;\n            p = -2.9070369957882005086e-08 + p * w;\n            p = 4.2347877827932403518e-07 + p * w;\n            p = -1.3654692000834678645e-06 + p * w;\n            p = -1.3882523362786468719e-05 + p * w;\n            p = 0.0001867342080340571352 + p * w;\n            p = -0.00074070253416626697512 + p * w;\n            p = -0.0060336708714301490533 + p * w;\n            p = 0.24015818242558961693 + p * w;\n            p = 1.6536545626831027356 + p * w;\n        } else if (w < 16.000000) {\n            w = sqrt(w) - 3.250000;\n            p = 2.2137376921775787049e-09;\n            p = 9.0756561938885390979e-08 + p * w;\n            p = -2.7517406297064545428e-07 + p * w;\n            p = 1.8239629214389227755e-08 + p * w;\n            p = 1.5027403968909827627e-06 + p * w;\n            p = -4.013867526981545969e-06 + p * w;\n            p = 2.9234449089955446044e-06 + p * w;\n            p = 1.2475304481671778723e-05 + p * w;\n            p = -4.7318229009055733981e-05 + p * w;\n            p = 6.8284851459573175448e-05 + p * w;\n            p = 2.4031110387097893999e-05 + p * w;\n            p = -0.0003550375203628474796 + p * w;\n            p = 0.00095328937973738049703 + p * w;\n            p = -0.0016882755560235047313 + p * w;\n            p = 0.0024914420961078508066 + p * w;\n            p = -0.0037512085075692412107 + p * w;\n            p = 0.005370914553590063617 + p * w;\n            p = 1.0052589676941592334 + p * w;\n            p = 3.0838856104922207635 + p * w;\n        } else {\n            w = sqrt(w) - 5.000000;\n            p = -2.7109920616438573243e-11;\n            p = -2.5556418169965252055e-10 + p * w;\n            p = 1.5076572693500548083e-09 + p * w;\n            p = -3.7894654401267369937e-09 + p * w;\n            p = 7.6157012080783393804e-09 + p * w;\n            p = -1.4960026627149240478e-08 + p * w;\n            p = 2.9147953450901080826e-08 + p * w;\n            p = -6.7711997758452339498e-08 + p * w;\n            p = 2.2900482228026654717e-07 + p * w;\n            p = -9.9298272942317002539e-07 + p * w;\n            p = 4.5260625972231537039e-06 + p * w;\n            p = -1.9681778105531670567e-05 + p * w;\n            p = 7.5995277030017761139e-05 + p * w;\n            p = -0.00021503011930044477347 + p * w;\n            p = -0.00013871931833623122026 + p * w;\n            p = 1.0103004648645343977 + p * w;\n            p = 4.8499064014085844221 + p * w;\n        }\n        return p * x;\n    }\n\n    double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {\n        auto m = Catch::Benchmark::Detail::mean(first, last);\n        double variance = std::accumulate(first, last, 0., [m](double a, double b) {\n            double diff = b - m;\n            return a + diff * diff;\n            }) / (last - first);\n            return std::sqrt(variance);\n    }\n\n}\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n\n            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {\n                auto count = last - first;\n                double idx = (count - 1) * k / static_cast<double>(q);\n                int j = static_cast<int>(idx);\n                double g = idx - j;\n                std::nth_element(first, first + j, last);\n                auto xj = first[j];\n                if (g == 0) return xj;\n\n                auto xj1 = *std::min_element(first + (j + 1), last);\n                return xj + g * (xj1 - xj);\n            }\n\n            double erfc_inv(double x) {\n                return erf_inv(1.0 - x);\n            }\n\n            double normal_quantile(double p) {\n                static const double ROOT_TWO = std::sqrt(2.0);\n\n                double result = 0.0;\n                assert(p >= 0 && p <= 1);\n                if (p < 0 || p > 1) {\n                    return result;\n                }\n\n                result = -erfc_inv(2.0 * p);\n                // result *= normal distribution standard deviation (1.0) * sqrt(2)\n                result *= /*sd * */ ROOT_TWO;\n                // result += normal disttribution mean (0)\n                return result;\n            }\n\n            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {\n                double sb = stddev.point;\n                double mn = mean.point / n;\n                double mg_min = mn / 2.;\n                double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));\n                double sg2 = sg * sg;\n                double sb2 = sb * sb;\n\n                auto c_max = [n, mn, sb2, sg2](double x) -> double {\n                    double k = mn - x;\n                    double d = k * k;\n                    double nd = n * d;\n                    double k0 = -n * nd;\n                    double k1 = sb2 - n * sg2 + nd;\n                    double det = k1 * k1 - 4 * sg2 * k0;\n                    return (int)(-2. * k0 / (k1 + std::sqrt(det)));\n                };\n\n                auto var_out = [n, sb2, sg2](double c) {\n                    double nc = n - c;\n                    return (nc / n) * (sb2 - nc * sg2);\n                };\n\n                return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;\n            }\n\n            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {\n                CATCH_INTERNAL_START_WARNINGS_SUPPRESSION\n                CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS\n                static std::random_device entropy;\n                CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n                auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++\n\n                auto mean = &Detail::mean<std::vector<double>::iterator>;\n                auto stddev = &standard_deviation;\n\n#if defined(CATCH_CONFIG_USE_ASYNC)\n                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {\n                    auto seed = entropy();\n                    return std::async(std::launch::async, [=] {\n                        std::mt19937 rng(seed);\n                        auto resampled = resample(rng, n_resamples, first, last, f);\n                        return bootstrap(confidence_level, first, last, resampled, f);\n                    });\n                };\n\n                auto mean_future = Estimate(mean);\n                auto stddev_future = Estimate(stddev);\n\n                auto mean_estimate = mean_future.get();\n                auto stddev_estimate = stddev_future.get();\n#else\n                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {\n                    auto seed = entropy();\n                    std::mt19937 rng(seed);\n                    auto resampled = resample(rng, n_resamples, first, last, f);\n                    return bootstrap(confidence_level, first, last, resampled, f);\n                };\n\n                auto mean_estimate = Estimate(mean);\n                auto stddev_estimate = Estimate(stddev);\n#endif // CATCH_USE_ASYNC\n\n                double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);\n\n                return { mean_estimate, stddev_estimate, outlier_variance };\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n// end catch_stats.cpp\n// start catch_approx.cpp\n\n#include <cmath>\n#include <limits>\n\nnamespace {\n\n// Performs equivalent check of std::fabs(lhs - rhs) <= margin\n// But without the subtraction to allow for INFINITY in comparison\nbool marginComparison(double lhs, double rhs, double margin) {\n    return (lhs + margin >= rhs) && (rhs + margin >= lhs);\n}\n\n}\n\nnamespace Catch {\nnamespace Detail {\n\n    Approx::Approx ( double value )\n    :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),\n        m_margin( 0.0 ),\n        m_scale( 0.0 ),\n        m_value( value )\n    {}\n\n    Approx Approx::custom() {\n        return Approx( 0 );\n    }\n\n    Approx Approx::operator-() const {\n        auto temp(*this);\n        temp.m_value = -temp.m_value;\n        return temp;\n    }\n\n    std::string Approx::toString() const {\n        ReusableStringStream rss;\n        rss << \"Approx( \" << ::Catch::Detail::stringify( m_value ) << \" )\";\n        return rss.str();\n    }\n\n    bool Approx::equalityComparisonImpl(const double other) const {\n        // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value\n        // Thanks to Richard Harris for his help refining the scaled margin value\n        return marginComparison(m_value, other, m_margin)\n            || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));\n    }\n\n    void Approx::setMargin(double newMargin) {\n        CATCH_ENFORCE(newMargin >= 0,\n            \"Invalid Approx::margin: \" << newMargin << '.'\n            << \" Approx::Margin has to be non-negative.\");\n        m_margin = newMargin;\n    }\n\n    void Approx::setEpsilon(double newEpsilon) {\n        CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,\n            \"Invalid Approx::epsilon: \" << newEpsilon << '.'\n            << \" Approx::epsilon has to be in [0, 1]\");\n        m_epsilon = newEpsilon;\n    }\n\n} // end namespace Detail\n\nnamespace literals {\n    Detail::Approx operator \"\" _a(long double val) {\n        return Detail::Approx(val);\n    }\n    Detail::Approx operator \"\" _a(unsigned long long val) {\n        return Detail::Approx(val);\n    }\n} // end namespace literals\n\nstd::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {\n    return value.toString();\n}\n\n} // end namespace Catch\n// end catch_approx.cpp\n// start catch_assertionhandler.cpp\n\n// start catch_debugger.h\n\nnamespace Catch {\n    bool isDebuggerActive();\n}\n\n#ifdef CATCH_PLATFORM_MAC\n\n    #if defined(__i386__) || defined(__x86_64__)\n        #define CATCH_TRAP() __asm__(\"int $3\\n\" : : ) /* NOLINT */\n    #elif defined(__aarch64__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xd43e0000\")\n    #endif\n\n#elif defined(CATCH_PLATFORM_IPHONE)\n\n    // use inline assembler\n    #if defined(__i386__) || defined(__x86_64__)\n        #define CATCH_TRAP()  __asm__(\"int $3\")\n    #elif defined(__aarch64__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xd4200000\")\n    #elif defined(__arm__) && !defined(__thumb__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xe7f001f0\")\n    #elif defined(__arm__) &&  defined(__thumb__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xde01\")\n    #endif\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    // If we can use inline assembler, do it because this allows us to break\n    // directly at the location of the failing check instead of breaking inside\n    // raise() called from it, i.e. one stack frame below.\n    #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))\n        #define CATCH_TRAP() asm volatile (\"int $3\") /* NOLINT */\n    #else // Fall back to the generic way.\n        #include <signal.h>\n\n        #define CATCH_TRAP() raise(SIGTRAP)\n    #endif\n#elif defined(_MSC_VER)\n    #define CATCH_TRAP() __debugbreak()\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) void __stdcall DebugBreak();\n    #define CATCH_TRAP() DebugBreak()\n#endif\n\n#ifndef CATCH_BREAK_INTO_DEBUGGER\n    #ifdef CATCH_TRAP\n        #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()\n    #else\n        #define CATCH_BREAK_INTO_DEBUGGER() []{}()\n    #endif\n#endif\n\n// end catch_debugger.h\n// start catch_run_context.h\n\n// start catch_fatal_condition.h\n\n#include <cassert>\n\nnamespace Catch {\n\n    // Wrapper for platform-specific fatal error (signals/SEH) handlers\n    //\n    // Tries to be cooperative with other handlers, and not step over\n    // other handlers. This means that unknown structured exceptions\n    // are passed on, previous signal handlers are called, and so on.\n    //\n    // Can only be instantiated once, and assumes that once a signal\n    // is caught, the binary will end up terminating. Thus, there\n    class FatalConditionHandler {\n        bool m_started = false;\n\n        // Install/disengage implementation for specific platform.\n        // Should be if-defed to work on current platform, can assume\n        // engage-disengage 1:1 pairing.\n        void engage_platform();\n        void disengage_platform();\n    public:\n        // Should also have platform-specific implementations as needed\n        FatalConditionHandler();\n        ~FatalConditionHandler();\n\n        void engage() {\n            assert(!m_started && \"Handler cannot be installed twice.\");\n            m_started = true;\n            engage_platform();\n        }\n\n        void disengage() {\n            assert(m_started && \"Handler cannot be uninstalled without being installed first\");\n            m_started = false;\n            disengage_platform();\n        }\n    };\n\n    //! Simple RAII guard for (dis)engaging the FatalConditionHandler\n    class FatalConditionHandlerGuard {\n        FatalConditionHandler* m_handler;\n    public:\n        FatalConditionHandlerGuard(FatalConditionHandler* handler):\n            m_handler(handler) {\n            m_handler->engage();\n        }\n        ~FatalConditionHandlerGuard() {\n            m_handler->disengage();\n        }\n    };\n\n} // end namespace Catch\n\n// end catch_fatal_condition.h\n#include <string>\n\nnamespace Catch {\n\n    struct IMutableContext;\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class RunContext : public IResultCapture, public IRunner {\n\n    public:\n        RunContext( RunContext const& ) = delete;\n        RunContext& operator =( RunContext const& ) = delete;\n\n        explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );\n\n        ~RunContext() override;\n\n        void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );\n        void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );\n\n        Totals runTest(TestCase const& testCase);\n\n        IConfigPtr config() const;\n        IStreamingReporter& reporter() const;\n\n    public: // IResultCapture\n\n        // Assertion handlers\n        void handleExpr\n                (   AssertionInfo const& info,\n                    ITransientExpression const& expr,\n                    AssertionReaction& reaction ) override;\n        void handleMessage\n                (   AssertionInfo const& info,\n                    ResultWas::OfType resultType,\n                    StringRef const& message,\n                    AssertionReaction& reaction ) override;\n        void handleUnexpectedExceptionNotThrown\n                (   AssertionInfo const& info,\n                    AssertionReaction& reaction ) override;\n        void handleUnexpectedInflightException\n                (   AssertionInfo const& info,\n                    std::string const& message,\n                    AssertionReaction& reaction ) override;\n        void handleIncomplete\n                (   AssertionInfo const& info ) override;\n        void handleNonExpr\n                (   AssertionInfo const &info,\n                    ResultWas::OfType resultType,\n                    AssertionReaction &reaction ) override;\n\n        bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;\n\n        void sectionEnded( SectionEndInfo const& endInfo ) override;\n        void sectionEndedEarly( SectionEndInfo const& endInfo ) override;\n\n        auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing( std::string const& name ) override;\n        void benchmarkStarting( BenchmarkInfo const& info ) override;\n        void benchmarkEnded( BenchmarkStats<> const& stats ) override;\n        void benchmarkFailed( std::string const& error ) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        void pushScopedMessage( MessageInfo const& message ) override;\n        void popScopedMessage( MessageInfo const& message ) override;\n\n        void emplaceUnscopedMessage( MessageBuilder const& builder ) override;\n\n        std::string getCurrentTestName() const override;\n\n        const AssertionResult* getLastResult() const override;\n\n        void exceptionEarlyReported() override;\n\n        void handleFatalErrorCondition( StringRef message ) override;\n\n        bool lastAssertionPassed() override;\n\n        void assertionPassed() override;\n\n    public:\n        // !TBD We need to do this another way!\n        bool aborting() const final;\n\n    private:\n\n        void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );\n        void invokeActiveTestCase();\n\n        void resetAssertionInfo();\n        bool testForMissingAssertions( Counts& assertions );\n\n        void assertionEnded( AssertionResult const& result );\n        void reportExpr\n                (   AssertionInfo const &info,\n                    ResultWas::OfType resultType,\n                    ITransientExpression const *expr,\n                    bool negated );\n\n        void populateReaction( AssertionReaction& reaction );\n\n    private:\n\n        void handleUnfinishedSections();\n\n        TestRunInfo m_runInfo;\n        IMutableContext& m_context;\n        TestCase const* m_activeTestCase = nullptr;\n        ITracker* m_testCaseTracker = nullptr;\n        Option<AssertionResult> m_lastResult;\n\n        IConfigPtr m_config;\n        Totals m_totals;\n        IStreamingReporterPtr m_reporter;\n        std::vector<MessageInfo> m_messages;\n        std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */\n        AssertionInfo m_lastAssertionInfo;\n        std::vector<SectionEndInfo> m_unfinishedSections;\n        std::vector<ITracker*> m_activeSections;\n        TrackerContext m_trackerContext;\n        FatalConditionHandler m_fatalConditionhandler;\n        bool m_lastAssertionPassed = false;\n        bool m_shouldReportUnexpected = true;\n        bool m_includeSuccessfulResults;\n    };\n\n    void seedRng(IConfig const& config);\n    unsigned int rngSeed();\n} // end namespace Catch\n\n// end catch_run_context.h\nnamespace Catch {\n\n    namespace {\n        auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {\n            expr.streamReconstructedExpression( os );\n            return os;\n        }\n    }\n\n    LazyExpression::LazyExpression( bool isNegated )\n    :   m_isNegated( isNegated )\n    {}\n\n    LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}\n\n    LazyExpression::operator bool() const {\n        return m_transientExpression != nullptr;\n    }\n\n    auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {\n        if( lazyExpr.m_isNegated )\n            os << \"!\";\n\n        if( lazyExpr ) {\n            if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )\n                os << \"(\" << *lazyExpr.m_transientExpression << \")\";\n            else\n                os << *lazyExpr.m_transientExpression;\n        }\n        else {\n            os << \"{** error - unchecked empty expression requested **}\";\n        }\n        return os;\n    }\n\n    AssertionHandler::AssertionHandler\n        (   StringRef const& macroName,\n            SourceLineInfo const& lineInfo,\n            StringRef capturedExpression,\n            ResultDisposition::Flags resultDisposition )\n    :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },\n        m_resultCapture( getResultCapture() )\n    {}\n\n    void AssertionHandler::handleExpr( ITransientExpression const& expr ) {\n        m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );\n    }\n    void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {\n        m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );\n    }\n\n    auto AssertionHandler::allowThrows() const -> bool {\n        return getCurrentContext().getConfig()->allowThrows();\n    }\n\n    void AssertionHandler::complete() {\n        setCompleted();\n        if( m_reaction.shouldDebugBreak ) {\n\n            // If you find your debugger stopping you here then go one level up on the\n            // call-stack for the code that caused it (typically a failed assertion)\n\n            // (To go back to the test and change execution, jump over the throw, next)\n            CATCH_BREAK_INTO_DEBUGGER();\n        }\n        if (m_reaction.shouldThrow) {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n            throw Catch::TestFailureException();\n#else\n            CATCH_ERROR( \"Test failure requires aborting test!\" );\n#endif\n        }\n    }\n    void AssertionHandler::setCompleted() {\n        m_completed = true;\n    }\n\n    void AssertionHandler::handleUnexpectedInflightException() {\n        m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );\n    }\n\n    void AssertionHandler::handleExceptionThrownAsExpected() {\n        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);\n    }\n    void AssertionHandler::handleExceptionNotThrownAsExpected() {\n        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);\n    }\n\n    void AssertionHandler::handleUnexpectedExceptionNotThrown() {\n        m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );\n    }\n\n    void AssertionHandler::handleThrowingCallSkipped() {\n        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);\n    }\n\n    // This is the overload that takes a string and infers the Equals matcher from it\n    // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp\n    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {\n        handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );\n    }\n\n} // namespace Catch\n// end catch_assertionhandler.cpp\n// start catch_assertionresult.cpp\n\nnamespace Catch {\n    AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):\n        lazyExpression(_lazyExpression),\n        resultType(_resultType) {}\n\n    std::string AssertionResultData::reconstructExpression() const {\n\n        if( reconstructedExpression.empty() ) {\n            if( lazyExpression ) {\n                ReusableStringStream rss;\n                rss << lazyExpression;\n                reconstructedExpression = rss.str();\n            }\n        }\n        return reconstructedExpression;\n    }\n\n    AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )\n    :   m_info( info ),\n        m_resultData( data )\n    {}\n\n    // Result was a success\n    bool AssertionResult::succeeded() const {\n        return Catch::isOk( m_resultData.resultType );\n    }\n\n    // Result was a success, or failure is suppressed\n    bool AssertionResult::isOk() const {\n        return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );\n    }\n\n    ResultWas::OfType AssertionResult::getResultType() const {\n        return m_resultData.resultType;\n    }\n\n    bool AssertionResult::hasExpression() const {\n        return !m_info.capturedExpression.empty();\n    }\n\n    bool AssertionResult::hasMessage() const {\n        return !m_resultData.message.empty();\n    }\n\n    std::string AssertionResult::getExpression() const {\n        // Possibly overallocating by 3 characters should be basically free\n        std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);\n        if (isFalseTest(m_info.resultDisposition)) {\n            expr += \"!(\";\n        }\n        expr += m_info.capturedExpression;\n        if (isFalseTest(m_info.resultDisposition)) {\n            expr += ')';\n        }\n        return expr;\n    }\n\n    std::string AssertionResult::getExpressionInMacro() const {\n        std::string expr;\n        if( m_info.macroName.empty() )\n            expr = static_cast<std::string>(m_info.capturedExpression);\n        else {\n            expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );\n            expr += m_info.macroName;\n            expr += \"( \";\n            expr += m_info.capturedExpression;\n            expr += \" )\";\n        }\n        return expr;\n    }\n\n    bool AssertionResult::hasExpandedExpression() const {\n        return hasExpression() && getExpandedExpression() != getExpression();\n    }\n\n    std::string AssertionResult::getExpandedExpression() const {\n        std::string expr = m_resultData.reconstructExpression();\n        return expr.empty()\n                ? getExpression()\n                : expr;\n    }\n\n    std::string AssertionResult::getMessage() const {\n        return m_resultData.message;\n    }\n    SourceLineInfo AssertionResult::getSourceInfo() const {\n        return m_info.lineInfo;\n    }\n\n    StringRef AssertionResult::getTestMacroName() const {\n        return m_info.macroName;\n    }\n\n} // end namespace Catch\n// end catch_assertionresult.cpp\n// start catch_capture_matchers.cpp\n\nnamespace Catch {\n\n    using StringMatcher = Matchers::Impl::MatcherBase<std::string>;\n\n    // This is the general overload that takes a any string matcher\n    // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers\n    // the Equals matcher (so the header does not mention matchers)\n    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {\n        std::string exceptionMessage = Catch::translateActiveException();\n        MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );\n        handler.handleExpr( expr );\n    }\n\n} // namespace Catch\n// end catch_capture_matchers.cpp\n// start catch_commandline.cpp\n\n// start catch_commandline.h\n\n// start catch_clara.h\n\n// Use Catch's value for console width (store Clara's off to the side, if present)\n#ifdef CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#endif\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wweak-vtables\"\n#pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#pragma clang diagnostic ignored \"-Wshadow\"\n#endif\n\n// start clara.hpp\n// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.\n//\n// Distributed under the Boost Software License, Version 1.0. (See accompanying\n// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n// See https://github.com/philsquared/Clara for more details\n\n// Clara v1.1.5\n\n\n#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80\n#endif\n\n#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n\n#ifndef CLARA_CONFIG_OPTIONAL_TYPE\n#ifdef __has_include\n#if __has_include(<optional>) && __cplusplus >= 201703L\n#include <optional>\n#define CLARA_CONFIG_OPTIONAL_TYPE std::optional\n#endif\n#endif\n#endif\n\n// ----------- #included from clara_textflow.hpp -----------\n\n// TextFlowCpp\n//\n// A single-header library for wrapping and laying out basic text, by Phil Nash\n//\n// Distributed under the Boost Software License, Version 1.0. (See accompanying\n// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n// This project is hosted at https://github.com/philsquared/textflowcpp\n\n\n#include <cassert>\n#include <ostream>\n#include <sstream>\n#include <vector>\n\n#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80\n#endif\n\nnamespace Catch {\nnamespace clara {\nnamespace TextFlow {\n\ninline auto isWhitespace(char c) -> bool {\n\tstatic std::string chars = \" \\t\\n\\r\";\n\treturn chars.find(c) != std::string::npos;\n}\ninline auto isBreakableBefore(char c) -> bool {\n\tstatic std::string chars = \"[({<|\";\n\treturn chars.find(c) != std::string::npos;\n}\ninline auto isBreakableAfter(char c) -> bool {\n\tstatic std::string chars = \"])}>.,:;*+-=&/\\\\\";\n\treturn chars.find(c) != std::string::npos;\n}\n\nclass Columns;\n\nclass Column {\n\tstd::vector<std::string> m_strings;\n\tsize_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;\n\tsize_t m_indent = 0;\n\tsize_t m_initialIndent = std::string::npos;\n\npublic:\n\tclass iterator {\n\t\tfriend Column;\n\n\t\tColumn const& m_column;\n\t\tsize_t m_stringIndex = 0;\n\t\tsize_t m_pos = 0;\n\n\t\tsize_t m_len = 0;\n\t\tsize_t m_end = 0;\n\t\tbool m_suffix = false;\n\n\t\titerator(Column const& column, size_t stringIndex)\n\t\t\t: m_column(column),\n\t\t\tm_stringIndex(stringIndex) {}\n\n\t\tauto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }\n\n\t\tauto isBoundary(size_t at) const -> bool {\n\t\t\tassert(at > 0);\n\t\t\tassert(at <= line().size());\n\n\t\t\treturn at == line().size() ||\n\t\t\t\t(isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||\n\t\t\t\tisBreakableBefore(line()[at]) ||\n\t\t\t\tisBreakableAfter(line()[at - 1]);\n\t\t}\n\n\t\tvoid calcLength() {\n\t\t\tassert(m_stringIndex < m_column.m_strings.size());\n\n\t\t\tm_suffix = false;\n\t\t\tauto width = m_column.m_width - indent();\n\t\t\tm_end = m_pos;\n\t\t\tif (line()[m_pos] == '\\n') {\n\t\t\t\t++m_end;\n\t\t\t}\n\t\t\twhile (m_end < line().size() && line()[m_end] != '\\n')\n\t\t\t\t++m_end;\n\n\t\t\tif (m_end < m_pos + width) {\n\t\t\t\tm_len = m_end - m_pos;\n\t\t\t} else {\n\t\t\t\tsize_t len = width;\n\t\t\t\twhile (len > 0 && !isBoundary(m_pos + len))\n\t\t\t\t\t--len;\n\t\t\t\twhile (len > 0 && isWhitespace(line()[m_pos + len - 1]))\n\t\t\t\t\t--len;\n\n\t\t\t\tif (len > 0) {\n\t\t\t\t\tm_len = len;\n\t\t\t\t} else {\n\t\t\t\t\tm_suffix = true;\n\t\t\t\t\tm_len = width - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tauto indent() const -> size_t {\n\t\t\tauto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;\n\t\t\treturn initial == std::string::npos ? m_column.m_indent : initial;\n\t\t}\n\n\t\tauto addIndentAndSuffix(std::string const &plain) const -> std::string {\n\t\t\treturn std::string(indent(), ' ') + (m_suffix ? plain + \"-\" : plain);\n\t\t}\n\n\tpublic:\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing value_type = std::string;\n\t\tusing pointer = value_type * ;\n\t\tusing reference = value_type & ;\n\t\tusing iterator_category = std::forward_iterator_tag;\n\n\t\texplicit iterator(Column const& column) : m_column(column) {\n\t\t\tassert(m_column.m_width > m_column.m_indent);\n\t\t\tassert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);\n\t\t\tcalcLength();\n\t\t\tif (m_len == 0)\n\t\t\t\tm_stringIndex++; // Empty string\n\t\t}\n\n\t\tauto operator *() const -> std::string {\n\t\t\tassert(m_stringIndex < m_column.m_strings.size());\n\t\t\tassert(m_pos <= m_end);\n\t\t\treturn addIndentAndSuffix(line().substr(m_pos, m_len));\n\t\t}\n\n\t\tauto operator ++() -> iterator& {\n\t\t\tm_pos += m_len;\n\t\t\tif (m_pos < line().size() && line()[m_pos] == '\\n')\n\t\t\t\tm_pos += 1;\n\t\t\telse\n\t\t\t\twhile (m_pos < line().size() && isWhitespace(line()[m_pos]))\n\t\t\t\t\t++m_pos;\n\n\t\t\tif (m_pos == line().size()) {\n\t\t\t\tm_pos = 0;\n\t\t\t\t++m_stringIndex;\n\t\t\t}\n\t\t\tif (m_stringIndex < m_column.m_strings.size())\n\t\t\t\tcalcLength();\n\t\t\treturn *this;\n\t\t}\n\t\tauto operator ++(int) -> iterator {\n\t\t\titerator prev(*this);\n\t\t\toperator++();\n\t\t\treturn prev;\n\t\t}\n\n\t\tauto operator ==(iterator const& other) const -> bool {\n\t\t\treturn\n\t\t\t\tm_pos == other.m_pos &&\n\t\t\t\tm_stringIndex == other.m_stringIndex &&\n\t\t\t\t&m_column == &other.m_column;\n\t\t}\n\t\tauto operator !=(iterator const& other) const -> bool {\n\t\t\treturn !operator==(other);\n\t\t}\n\t};\n\tusing const_iterator = iterator;\n\n\texplicit Column(std::string const& text) { m_strings.push_back(text); }\n\n\tauto width(size_t newWidth) -> Column& {\n\t\tassert(newWidth > 0);\n\t\tm_width = newWidth;\n\t\treturn *this;\n\t}\n\tauto indent(size_t newIndent) -> Column& {\n\t\tm_indent = newIndent;\n\t\treturn *this;\n\t}\n\tauto initialIndent(size_t newIndent) -> Column& {\n\t\tm_initialIndent = newIndent;\n\t\treturn *this;\n\t}\n\n\tauto width() const -> size_t { return m_width; }\n\tauto begin() const -> iterator { return iterator(*this); }\n\tauto end() const -> iterator { return { *this, m_strings.size() }; }\n\n\tinline friend std::ostream& operator << (std::ostream& os, Column const& col) {\n\t\tbool first = true;\n\t\tfor (auto line : col) {\n\t\t\tif (first)\n\t\t\t\tfirst = false;\n\t\t\telse\n\t\t\t\tos << \"\\n\";\n\t\t\tos << line;\n\t\t}\n\t\treturn os;\n\t}\n\n\tauto operator + (Column const& other)->Columns;\n\n\tauto toString() const -> std::string {\n\t\tstd::ostringstream oss;\n\t\toss << *this;\n\t\treturn oss.str();\n\t}\n};\n\nclass Spacer : public Column {\n\npublic:\n\texplicit Spacer(size_t spaceWidth) : Column(\"\") {\n\t\twidth(spaceWidth);\n\t}\n};\n\nclass Columns {\n\tstd::vector<Column> m_columns;\n\npublic:\n\n\tclass iterator {\n\t\tfriend Columns;\n\t\tstruct EndTag {};\n\n\t\tstd::vector<Column> const& m_columns;\n\t\tstd::vector<Column::iterator> m_iterators;\n\t\tsize_t m_activeIterators;\n\n\t\titerator(Columns const& columns, EndTag)\n\t\t\t: m_columns(columns.m_columns),\n\t\t\tm_activeIterators(0) {\n\t\t\tm_iterators.reserve(m_columns.size());\n\n\t\t\tfor (auto const& col : m_columns)\n\t\t\t\tm_iterators.push_back(col.end());\n\t\t}\n\n\tpublic:\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing value_type = std::string;\n\t\tusing pointer = value_type * ;\n\t\tusing reference = value_type & ;\n\t\tusing iterator_category = std::forward_iterator_tag;\n\n\t\texplicit iterator(Columns const& columns)\n\t\t\t: m_columns(columns.m_columns),\n\t\t\tm_activeIterators(m_columns.size()) {\n\t\t\tm_iterators.reserve(m_columns.size());\n\n\t\t\tfor (auto const& col : m_columns)\n\t\t\t\tm_iterators.push_back(col.begin());\n\t\t}\n\n\t\tauto operator ==(iterator const& other) const -> bool {\n\t\t\treturn m_iterators == other.m_iterators;\n\t\t}\n\t\tauto operator !=(iterator const& other) const -> bool {\n\t\t\treturn m_iterators != other.m_iterators;\n\t\t}\n\t\tauto operator *() const -> std::string {\n\t\t\tstd::string row, padding;\n\n\t\t\tfor (size_t i = 0; i < m_columns.size(); ++i) {\n\t\t\t\tauto width = m_columns[i].width();\n\t\t\t\tif (m_iterators[i] != m_columns[i].end()) {\n\t\t\t\t\tstd::string col = *m_iterators[i];\n\t\t\t\t\trow += padding + col;\n\t\t\t\t\tif (col.size() < width)\n\t\t\t\t\t\tpadding = std::string(width - col.size(), ' ');\n\t\t\t\t\telse\n\t\t\t\t\t\tpadding = \"\";\n\t\t\t\t} else {\n\t\t\t\t\tpadding += std::string(width, ' ');\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn row;\n\t\t}\n\t\tauto operator ++() -> iterator& {\n\t\t\tfor (size_t i = 0; i < m_columns.size(); ++i) {\n\t\t\t\tif (m_iterators[i] != m_columns[i].end())\n\t\t\t\t\t++m_iterators[i];\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\t\tauto operator ++(int) -> iterator {\n\t\t\titerator prev(*this);\n\t\t\toperator++();\n\t\t\treturn prev;\n\t\t}\n\t};\n\tusing const_iterator = iterator;\n\n\tauto begin() const -> iterator { return iterator(*this); }\n\tauto end() const -> iterator { return { *this, iterator::EndTag() }; }\n\n\tauto operator += (Column const& col) -> Columns& {\n\t\tm_columns.push_back(col);\n\t\treturn *this;\n\t}\n\tauto operator + (Column const& col) -> Columns {\n\t\tColumns combined = *this;\n\t\tcombined += col;\n\t\treturn combined;\n\t}\n\n\tinline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {\n\n\t\tbool first = true;\n\t\tfor (auto line : cols) {\n\t\t\tif (first)\n\t\t\t\tfirst = false;\n\t\t\telse\n\t\t\t\tos << \"\\n\";\n\t\t\tos << line;\n\t\t}\n\t\treturn os;\n\t}\n\n\tauto toString() const -> std::string {\n\t\tstd::ostringstream oss;\n\t\toss << *this;\n\t\treturn oss.str();\n\t}\n};\n\ninline auto Column::operator + (Column const& other) -> Columns {\n\tColumns cols;\n\tcols += *this;\n\tcols += other;\n\treturn cols;\n}\n}\n\n}\n}\n\n// ----------- end of #include from clara_textflow.hpp -----------\n// ........... back in clara.hpp\n\n#include <cctype>\n#include <string>\n#include <memory>\n#include <set>\n#include <algorithm>\n\n#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )\n#define CATCH_PLATFORM_WINDOWS\n#endif\n\nnamespace Catch { namespace clara {\nnamespace detail {\n\n    // Traits for extracting arg and return type of lambdas (for single argument lambdas)\n    template<typename L>\n    struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};\n\n    template<typename ClassT, typename ReturnT, typename... Args>\n    struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {\n        static const bool isValid = false;\n    };\n\n    template<typename ClassT, typename ReturnT, typename ArgT>\n    struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {\n        static const bool isValid = true;\n        using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;\n        using ReturnType = ReturnT;\n    };\n\n    class TokenStream;\n\n    // Transport for raw args (copied from main args, or supplied via init list for testing)\n    class Args {\n        friend TokenStream;\n        std::string m_exeName;\n        std::vector<std::string> m_args;\n\n    public:\n        Args( int argc, char const* const* argv )\n            : m_exeName(argv[0]),\n              m_args(argv + 1, argv + argc) {}\n\n        Args( std::initializer_list<std::string> args )\n        :   m_exeName( *args.begin() ),\n            m_args( args.begin()+1, args.end() )\n        {}\n\n        auto exeName() const -> std::string {\n            return m_exeName;\n        }\n    };\n\n    // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string\n    // may encode an option + its argument if the : or = form is used\n    enum class TokenType {\n        Option, Argument\n    };\n    struct Token {\n        TokenType type;\n        std::string token;\n    };\n\n    inline auto isOptPrefix( char c ) -> bool {\n        return c == '-'\n#ifdef CATCH_PLATFORM_WINDOWS\n            || c == '/'\n#endif\n        ;\n    }\n\n    // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled\n    class TokenStream {\n        using Iterator = std::vector<std::string>::const_iterator;\n        Iterator it;\n        Iterator itEnd;\n        std::vector<Token> m_tokenBuffer;\n\n        void loadBuffer() {\n            m_tokenBuffer.resize( 0 );\n\n            // Skip any empty strings\n            while( it != itEnd && it->empty() )\n                ++it;\n\n            if( it != itEnd ) {\n                auto const &next = *it;\n                if( isOptPrefix( next[0] ) ) {\n                    auto delimiterPos = next.find_first_of( \" :=\" );\n                    if( delimiterPos != std::string::npos ) {\n                        m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );\n                        m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );\n                    } else {\n                        if( next[1] != '-' && next.size() > 2 ) {\n                            std::string opt = \"- \";\n                            for( size_t i = 1; i < next.size(); ++i ) {\n                                opt[1] = next[i];\n                                m_tokenBuffer.push_back( { TokenType::Option, opt } );\n                            }\n                        } else {\n                            m_tokenBuffer.push_back( { TokenType::Option, next } );\n                        }\n                    }\n                } else {\n                    m_tokenBuffer.push_back( { TokenType::Argument, next } );\n                }\n            }\n        }\n\n    public:\n        explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}\n\n        TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {\n            loadBuffer();\n        }\n\n        explicit operator bool() const {\n            return !m_tokenBuffer.empty() || it != itEnd;\n        }\n\n        auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }\n\n        auto operator*() const -> Token {\n            assert( !m_tokenBuffer.empty() );\n            return m_tokenBuffer.front();\n        }\n\n        auto operator->() const -> Token const * {\n            assert( !m_tokenBuffer.empty() );\n            return &m_tokenBuffer.front();\n        }\n\n        auto operator++() -> TokenStream & {\n            if( m_tokenBuffer.size() >= 2 ) {\n                m_tokenBuffer.erase( m_tokenBuffer.begin() );\n            } else {\n                if( it != itEnd )\n                    ++it;\n                loadBuffer();\n            }\n            return *this;\n        }\n    };\n\n    class ResultBase {\n    public:\n        enum Type {\n            Ok, LogicError, RuntimeError\n        };\n\n    protected:\n        ResultBase( Type type ) : m_type( type ) {}\n        virtual ~ResultBase() = default;\n\n        virtual void enforceOk() const = 0;\n\n        Type m_type;\n    };\n\n    template<typename T>\n    class ResultValueBase : public ResultBase {\n    public:\n        auto value() const -> T const & {\n            enforceOk();\n            return m_value;\n        }\n\n    protected:\n        ResultValueBase( Type type ) : ResultBase( type ) {}\n\n        ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {\n            if( m_type == ResultBase::Ok )\n                new( &m_value ) T( other.m_value );\n        }\n\n        ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {\n            new( &m_value ) T( value );\n        }\n\n        auto operator=( ResultValueBase const &other ) -> ResultValueBase & {\n            if( m_type == ResultBase::Ok )\n                m_value.~T();\n            ResultBase::operator=(other);\n            if( m_type == ResultBase::Ok )\n                new( &m_value ) T( other.m_value );\n            return *this;\n        }\n\n        ~ResultValueBase() override {\n            if( m_type == Ok )\n                m_value.~T();\n        }\n\n        union {\n            T m_value;\n        };\n    };\n\n    template<>\n    class ResultValueBase<void> : public ResultBase {\n    protected:\n        using ResultBase::ResultBase;\n    };\n\n    template<typename T = void>\n    class BasicResult : public ResultValueBase<T> {\n    public:\n        template<typename U>\n        explicit BasicResult( BasicResult<U> const &other )\n        :   ResultValueBase<T>( other.type() ),\n            m_errorMessage( other.errorMessage() )\n        {\n            assert( type() != ResultBase::Ok );\n        }\n\n        template<typename U>\n        static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }\n        static auto ok() -> BasicResult { return { ResultBase::Ok }; }\n        static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }\n        static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }\n\n        explicit operator bool() const { return m_type == ResultBase::Ok; }\n        auto type() const -> ResultBase::Type { return m_type; }\n        auto errorMessage() const -> std::string { return m_errorMessage; }\n\n    protected:\n        void enforceOk() const override {\n\n            // Errors shouldn't reach this point, but if they do\n            // the actual error message will be in m_errorMessage\n            assert( m_type != ResultBase::LogicError );\n            assert( m_type != ResultBase::RuntimeError );\n            if( m_type != ResultBase::Ok )\n                std::abort();\n        }\n\n        std::string m_errorMessage; // Only populated if resultType is an error\n\n        BasicResult( ResultBase::Type type, std::string const &message )\n        :   ResultValueBase<T>(type),\n            m_errorMessage(message)\n        {\n            assert( m_type != ResultBase::Ok );\n        }\n\n        using ResultValueBase<T>::ResultValueBase;\n        using ResultBase::m_type;\n    };\n\n    enum class ParseResultType {\n        Matched, NoMatch, ShortCircuitAll, ShortCircuitSame\n    };\n\n    class ParseState {\n    public:\n\n        ParseState( ParseResultType type, TokenStream const &remainingTokens )\n        : m_type(type),\n          m_remainingTokens( remainingTokens )\n        {}\n\n        auto type() const -> ParseResultType { return m_type; }\n        auto remainingTokens() const -> TokenStream { return m_remainingTokens; }\n\n    private:\n        ParseResultType m_type;\n        TokenStream m_remainingTokens;\n    };\n\n    using Result = BasicResult<void>;\n    using ParserResult = BasicResult<ParseResultType>;\n    using InternalParseResult = BasicResult<ParseState>;\n\n    struct HelpColumns {\n        std::string left;\n        std::string right;\n    };\n\n    template<typename T>\n    inline auto convertInto( std::string const &source, T& target ) -> ParserResult {\n        std::stringstream ss;\n        ss << source;\n        ss >> target;\n        if( ss.fail() )\n            return ParserResult::runtimeError( \"Unable to convert '\" + source + \"' to destination type\" );\n        else\n            return ParserResult::ok( ParseResultType::Matched );\n    }\n    inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {\n        target = source;\n        return ParserResult::ok( ParseResultType::Matched );\n    }\n    inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {\n        std::string srcLC = source;\n        std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );\n        if (srcLC == \"y\" || srcLC == \"1\" || srcLC == \"true\" || srcLC == \"yes\" || srcLC == \"on\")\n            target = true;\n        else if (srcLC == \"n\" || srcLC == \"0\" || srcLC == \"false\" || srcLC == \"no\" || srcLC == \"off\")\n            target = false;\n        else\n            return ParserResult::runtimeError( \"Expected a boolean value but did not recognise: '\" + source + \"'\" );\n        return ParserResult::ok( ParseResultType::Matched );\n    }\n#ifdef CLARA_CONFIG_OPTIONAL_TYPE\n    template<typename T>\n    inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {\n        T temp;\n        auto result = convertInto( source, temp );\n        if( result )\n            target = std::move(temp);\n        return result;\n    }\n#endif // CLARA_CONFIG_OPTIONAL_TYPE\n\n    struct NonCopyable {\n        NonCopyable() = default;\n        NonCopyable( NonCopyable const & ) = delete;\n        NonCopyable( NonCopyable && ) = delete;\n        NonCopyable &operator=( NonCopyable const & ) = delete;\n        NonCopyable &operator=( NonCopyable && ) = delete;\n    };\n\n    struct BoundRef : NonCopyable {\n        virtual ~BoundRef() = default;\n        virtual auto isContainer() const -> bool { return false; }\n        virtual auto isFlag() const -> bool { return false; }\n    };\n    struct BoundValueRefBase : BoundRef {\n        virtual auto setValue( std::string const &arg ) -> ParserResult = 0;\n    };\n    struct BoundFlagRefBase : BoundRef {\n        virtual auto setFlag( bool flag ) -> ParserResult = 0;\n        virtual auto isFlag() const -> bool { return true; }\n    };\n\n    template<typename T>\n    struct BoundValueRef : BoundValueRefBase {\n        T &m_ref;\n\n        explicit BoundValueRef( T &ref ) : m_ref( ref ) {}\n\n        auto setValue( std::string const &arg ) -> ParserResult override {\n            return convertInto( arg, m_ref );\n        }\n    };\n\n    template<typename T>\n    struct BoundValueRef<std::vector<T>> : BoundValueRefBase {\n        std::vector<T> &m_ref;\n\n        explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}\n\n        auto isContainer() const -> bool override { return true; }\n\n        auto setValue( std::string const &arg ) -> ParserResult override {\n            T temp;\n            auto result = convertInto( arg, temp );\n            if( result )\n                m_ref.push_back( temp );\n            return result;\n        }\n    };\n\n    struct BoundFlagRef : BoundFlagRefBase {\n        bool &m_ref;\n\n        explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}\n\n        auto setFlag( bool flag ) -> ParserResult override {\n            m_ref = flag;\n            return ParserResult::ok( ParseResultType::Matched );\n        }\n    };\n\n    template<typename ReturnType>\n    struct LambdaInvoker {\n        static_assert( std::is_same<ReturnType, ParserResult>::value, \"Lambda must return void or clara::ParserResult\" );\n\n        template<typename L, typename ArgType>\n        static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {\n            return lambda( arg );\n        }\n    };\n\n    template<>\n    struct LambdaInvoker<void> {\n        template<typename L, typename ArgType>\n        static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {\n            lambda( arg );\n            return ParserResult::ok( ParseResultType::Matched );\n        }\n    };\n\n    template<typename ArgType, typename L>\n    inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {\n        ArgType temp{};\n        auto result = convertInto( arg, temp );\n        return !result\n           ? result\n           : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );\n    }\n\n    template<typename L>\n    struct BoundLambda : BoundValueRefBase {\n        L m_lambda;\n\n        static_assert( UnaryLambdaTraits<L>::isValid, \"Supplied lambda must take exactly one argument\" );\n        explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}\n\n        auto setValue( std::string const &arg ) -> ParserResult override {\n            return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );\n        }\n    };\n\n    template<typename L>\n    struct BoundFlagLambda : BoundFlagRefBase {\n        L m_lambda;\n\n        static_assert( UnaryLambdaTraits<L>::isValid, \"Supplied lambda must take exactly one argument\" );\n        static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, \"flags must be boolean\" );\n\n        explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}\n\n        auto setFlag( bool flag ) -> ParserResult override {\n            return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );\n        }\n    };\n\n    enum class Optionality { Optional, Required };\n\n    struct Parser;\n\n    class ParserBase {\n    public:\n        virtual ~ParserBase() = default;\n        virtual auto validate() const -> Result { return Result::ok(); }\n        virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;\n        virtual auto cardinality() const -> size_t { return 1; }\n\n        auto parse( Args const &args ) const -> InternalParseResult {\n            return parse( args.exeName(), TokenStream( args ) );\n        }\n    };\n\n    template<typename DerivedT>\n    class ComposableParserImpl : public ParserBase {\n    public:\n        template<typename T>\n        auto operator|( T const &other ) const -> Parser;\n\n\t\ttemplate<typename T>\n        auto operator+( T const &other ) const -> Parser;\n    };\n\n    // Common code and state for Args and Opts\n    template<typename DerivedT>\n    class ParserRefImpl : public ComposableParserImpl<DerivedT> {\n    protected:\n        Optionality m_optionality = Optionality::Optional;\n        std::shared_ptr<BoundRef> m_ref;\n        std::string m_hint;\n        std::string m_description;\n\n        explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}\n\n    public:\n        template<typename T>\n        ParserRefImpl( T &ref, std::string const &hint )\n        :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),\n            m_hint( hint )\n        {}\n\n        template<typename LambdaT>\n        ParserRefImpl( LambdaT const &ref, std::string const &hint )\n        :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),\n            m_hint(hint)\n        {}\n\n        auto operator()( std::string const &description ) -> DerivedT & {\n            m_description = description;\n            return static_cast<DerivedT &>( *this );\n        }\n\n        auto optional() -> DerivedT & {\n            m_optionality = Optionality::Optional;\n            return static_cast<DerivedT &>( *this );\n        };\n\n        auto required() -> DerivedT & {\n            m_optionality = Optionality::Required;\n            return static_cast<DerivedT &>( *this );\n        };\n\n        auto isOptional() const -> bool {\n            return m_optionality == Optionality::Optional;\n        }\n\n        auto cardinality() const -> size_t override {\n            if( m_ref->isContainer() )\n                return 0;\n            else\n                return 1;\n        }\n\n        auto hint() const -> std::string { return m_hint; }\n    };\n\n    class ExeName : public ComposableParserImpl<ExeName> {\n        std::shared_ptr<std::string> m_name;\n        std::shared_ptr<BoundValueRefBase> m_ref;\n\n        template<typename LambdaT>\n        static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {\n            return std::make_shared<BoundLambda<LambdaT>>( lambda) ;\n        }\n\n    public:\n        ExeName() : m_name( std::make_shared<std::string>( \"<executable>\" ) ) {}\n\n        explicit ExeName( std::string &ref ) : ExeName() {\n            m_ref = std::make_shared<BoundValueRef<std::string>>( ref );\n        }\n\n        template<typename LambdaT>\n        explicit ExeName( LambdaT const& lambda ) : ExeName() {\n            m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );\n        }\n\n        // The exe name is not parsed out of the normal tokens, but is handled specially\n        auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {\n            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );\n        }\n\n        auto name() const -> std::string { return *m_name; }\n        auto set( std::string const& newName ) -> ParserResult {\n\n            auto lastSlash = newName.find_last_of( \"\\\\/\" );\n            auto filename = ( lastSlash == std::string::npos )\n                    ? newName\n                    : newName.substr( lastSlash+1 );\n\n            *m_name = filename;\n            if( m_ref )\n                return m_ref->setValue( filename );\n            else\n                return ParserResult::ok( ParseResultType::Matched );\n        }\n    };\n\n    class Arg : public ParserRefImpl<Arg> {\n    public:\n        using ParserRefImpl::ParserRefImpl;\n\n        auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {\n            auto validationResult = validate();\n            if( !validationResult )\n                return InternalParseResult( validationResult );\n\n            auto remainingTokens = tokens;\n            auto const &token = *remainingTokens;\n            if( token.type != TokenType::Argument )\n                return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );\n\n            assert( !m_ref->isFlag() );\n            auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );\n\n            auto result = valueRef->setValue( remainingTokens->token );\n            if( !result )\n                return InternalParseResult( result );\n            else\n                return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );\n        }\n    };\n\n    inline auto normaliseOpt( std::string const &optName ) -> std::string {\n#ifdef CATCH_PLATFORM_WINDOWS\n        if( optName[0] == '/' )\n            return \"-\" + optName.substr( 1 );\n        else\n#endif\n            return optName;\n    }\n\n    class Opt : public ParserRefImpl<Opt> {\n    protected:\n        std::vector<std::string> m_optNames;\n\n    public:\n        template<typename LambdaT>\n        explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}\n\n        explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}\n\n        template<typename LambdaT>\n        Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}\n\n        template<typename T>\n        Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}\n\n        auto operator[]( std::string const &optName ) -> Opt & {\n            m_optNames.push_back( optName );\n            return *this;\n        }\n\n        auto getHelpColumns() const -> std::vector<HelpColumns> {\n            std::ostringstream oss;\n            bool first = true;\n            for( auto const &opt : m_optNames ) {\n                if (first)\n                    first = false;\n                else\n                    oss << \", \";\n                oss << opt;\n            }\n            if( !m_hint.empty() )\n                oss << \" <\" << m_hint << \">\";\n            return { { oss.str(), m_description } };\n        }\n\n        auto isMatch( std::string const &optToken ) const -> bool {\n            auto normalisedToken = normaliseOpt( optToken );\n            for( auto const &name : m_optNames ) {\n                if( normaliseOpt( name ) == normalisedToken )\n                    return true;\n            }\n            return false;\n        }\n\n        using ParserBase::parse;\n\n        auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {\n            auto validationResult = validate();\n            if( !validationResult )\n                return InternalParseResult( validationResult );\n\n            auto remainingTokens = tokens;\n            if( remainingTokens && remainingTokens->type == TokenType::Option ) {\n                auto const &token = *remainingTokens;\n                if( isMatch(token.token ) ) {\n                    if( m_ref->isFlag() ) {\n                        auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );\n                        auto result = flagRef->setFlag( true );\n                        if( !result )\n                            return InternalParseResult( result );\n                        if( result.value() == ParseResultType::ShortCircuitAll )\n                            return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );\n                    } else {\n                        auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );\n                        ++remainingTokens;\n                        if( !remainingTokens )\n                            return InternalParseResult::runtimeError( \"Expected argument following \" + token.token );\n                        auto const &argToken = *remainingTokens;\n                        if( argToken.type != TokenType::Argument )\n                            return InternalParseResult::runtimeError( \"Expected argument following \" + token.token );\n                        auto result = valueRef->setValue( argToken.token );\n                        if( !result )\n                            return InternalParseResult( result );\n                        if( result.value() == ParseResultType::ShortCircuitAll )\n                            return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );\n                    }\n                    return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );\n                }\n            }\n            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );\n        }\n\n        auto validate() const -> Result override {\n            if( m_optNames.empty() )\n                return Result::logicError( \"No options supplied to Opt\" );\n            for( auto const &name : m_optNames ) {\n                if( name.empty() )\n                    return Result::logicError( \"Option name cannot be empty\" );\n#ifdef CATCH_PLATFORM_WINDOWS\n                if( name[0] != '-' && name[0] != '/' )\n                    return Result::logicError( \"Option name must begin with '-' or '/'\" );\n#else\n                if( name[0] != '-' )\n                    return Result::logicError( \"Option name must begin with '-'\" );\n#endif\n            }\n            return ParserRefImpl::validate();\n        }\n    };\n\n    struct Help : Opt {\n        Help( bool &showHelpFlag )\n        :   Opt([&]( bool flag ) {\n                showHelpFlag = flag;\n                return ParserResult::ok( ParseResultType::ShortCircuitAll );\n            })\n        {\n            static_cast<Opt &>( *this )\n                    (\"display usage information\")\n                    [\"-?\"][\"-h\"][\"--help\"]\n                    .optional();\n        }\n    };\n\n    struct Parser : ParserBase {\n\n        mutable ExeName m_exeName;\n        std::vector<Opt> m_options;\n        std::vector<Arg> m_args;\n\n        auto operator|=( ExeName const &exeName ) -> Parser & {\n            m_exeName = exeName;\n            return *this;\n        }\n\n        auto operator|=( Arg const &arg ) -> Parser & {\n            m_args.push_back(arg);\n            return *this;\n        }\n\n        auto operator|=( Opt const &opt ) -> Parser & {\n            m_options.push_back(opt);\n            return *this;\n        }\n\n        auto operator|=( Parser const &other ) -> Parser & {\n            m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());\n            m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());\n            return *this;\n        }\n\n        template<typename T>\n        auto operator|( T const &other ) const -> Parser {\n            return Parser( *this ) |= other;\n        }\n\n        // Forward deprecated interface with '+' instead of '|'\n        template<typename T>\n        auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }\n        template<typename T>\n        auto operator+( T const &other ) const -> Parser { return operator|( other ); }\n\n        auto getHelpColumns() const -> std::vector<HelpColumns> {\n            std::vector<HelpColumns> cols;\n            for (auto const &o : m_options) {\n                auto childCols = o.getHelpColumns();\n                cols.insert( cols.end(), childCols.begin(), childCols.end() );\n            }\n            return cols;\n        }\n\n        void writeToStream( std::ostream &os ) const {\n            if (!m_exeName.name().empty()) {\n                os << \"usage:\\n\" << \"  \" << m_exeName.name() << \" \";\n                bool required = true, first = true;\n                for( auto const &arg : m_args ) {\n                    if (first)\n                        first = false;\n                    else\n                        os << \" \";\n                    if( arg.isOptional() && required ) {\n                        os << \"[\";\n                        required = false;\n                    }\n                    os << \"<\" << arg.hint() << \">\";\n                    if( arg.cardinality() == 0 )\n                        os << \" ... \";\n                }\n                if( !required )\n                    os << \"]\";\n                if( !m_options.empty() )\n                    os << \" options\";\n                os << \"\\n\\nwhere options are:\" << std::endl;\n            }\n\n            auto rows = getHelpColumns();\n            size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;\n            size_t optWidth = 0;\n            for( auto const &cols : rows )\n                optWidth = (std::max)(optWidth, cols.left.size() + 2);\n\n            optWidth = (std::min)(optWidth, consoleWidth/2);\n\n            for( auto const &cols : rows ) {\n                auto row =\n                        TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +\n                        TextFlow::Spacer(4) +\n                        TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );\n                os << row << std::endl;\n            }\n        }\n\n        friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {\n            parser.writeToStream( os );\n            return os;\n        }\n\n        auto validate() const -> Result override {\n            for( auto const &opt : m_options ) {\n                auto result = opt.validate();\n                if( !result )\n                    return result;\n            }\n            for( auto const &arg : m_args ) {\n                auto result = arg.validate();\n                if( !result )\n                    return result;\n            }\n            return Result::ok();\n        }\n\n        using ParserBase::parse;\n\n        auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {\n\n            struct ParserInfo {\n                ParserBase const* parser = nullptr;\n                size_t count = 0;\n            };\n            const size_t totalParsers = m_options.size() + m_args.size();\n            assert( totalParsers < 512 );\n            // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do\n            ParserInfo parseInfos[512];\n\n            {\n                size_t i = 0;\n                for (auto const &opt : m_options) parseInfos[i++].parser = &opt;\n                for (auto const &arg : m_args) parseInfos[i++].parser = &arg;\n            }\n\n            m_exeName.set( exeName );\n\n            auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );\n            while( result.value().remainingTokens() ) {\n                bool tokenParsed = false;\n\n                for( size_t i = 0; i < totalParsers; ++i ) {\n                    auto&  parseInfo = parseInfos[i];\n                    if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {\n                        result = parseInfo.parser->parse(exeName, result.value().remainingTokens());\n                        if (!result)\n                            return result;\n                        if (result.value().type() != ParseResultType::NoMatch) {\n                            tokenParsed = true;\n                            ++parseInfo.count;\n                            break;\n                        }\n                    }\n                }\n\n                if( result.value().type() == ParseResultType::ShortCircuitAll )\n                    return result;\n                if( !tokenParsed )\n                    return InternalParseResult::runtimeError( \"Unrecognised token: \" + result.value().remainingTokens()->token );\n            }\n            // !TBD Check missing required options\n            return result;\n        }\n    };\n\n    template<typename DerivedT>\n    template<typename T>\n    auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {\n        return Parser() | static_cast<DerivedT const &>( *this ) | other;\n    }\n} // namespace detail\n\n// A Combined parser\nusing detail::Parser;\n\n// A parser for options\nusing detail::Opt;\n\n// A parser for arguments\nusing detail::Arg;\n\n// Wrapper for argc, argv from main()\nusing detail::Args;\n\n// Specifies the name of the executable\nusing detail::ExeName;\n\n// Convenience wrapper for option parser that specifies the help option\nusing detail::Help;\n\n// enum of result types from a parse\nusing detail::ParseResultType;\n\n// Result type for parser operation\nusing detail::ParserResult;\n\n}} // namespace Catch::clara\n\n// end clara.hpp\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// Restore Clara's value for console width, if present\n#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n\n// end catch_clara.h\nnamespace Catch {\n\n    clara::Parser makeCommandLineParser( ConfigData& config );\n\n} // end namespace Catch\n\n// end catch_commandline.h\n#include <fstream>\n#include <ctime>\n\nnamespace Catch {\n\n    clara::Parser makeCommandLineParser( ConfigData& config ) {\n\n        using namespace clara;\n\n        auto const setWarning = [&]( std::string const& warning ) {\n                auto warningSet = [&]() {\n                    if( warning == \"NoAssertions\" )\n                        return WarnAbout::NoAssertions;\n\n                    if ( warning == \"NoTests\" )\n                        return WarnAbout::NoTests;\n\n                    return WarnAbout::Nothing;\n                }();\n\n                if (warningSet == WarnAbout::Nothing)\n                    return ParserResult::runtimeError( \"Unrecognised warning: '\" + warning + \"'\" );\n                config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const loadTestNamesFromFile = [&]( std::string const& filename ) {\n                std::ifstream f( filename.c_str() );\n                if( !f.is_open() )\n                    return ParserResult::runtimeError( \"Unable to load input file: '\" + filename + \"'\" );\n\n                std::string line;\n                while( std::getline( f, line ) ) {\n                    line = trim(line);\n                    if( !line.empty() && !startsWith( line, '#' ) ) {\n                        if( !startsWith( line, '\"' ) )\n                            line = '\"' + line + '\"';\n                        config.testsOrTags.push_back( line );\n                        config.testsOrTags.emplace_back( \",\" );\n                    }\n                }\n                //Remove comma in the end\n                if(!config.testsOrTags.empty())\n                    config.testsOrTags.erase( config.testsOrTags.end()-1 );\n\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setTestOrder = [&]( std::string const& order ) {\n                if( startsWith( \"declared\", order ) )\n                    config.runOrder = RunTests::InDeclarationOrder;\n                else if( startsWith( \"lexical\", order ) )\n                    config.runOrder = RunTests::InLexicographicalOrder;\n                else if( startsWith( \"random\", order ) )\n                    config.runOrder = RunTests::InRandomOrder;\n                else\n                    return clara::ParserResult::runtimeError( \"Unrecognised ordering: '\" + order + \"'\" );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setRngSeed = [&]( std::string const& seed ) {\n                if( seed != \"time\" )\n                    return clara::detail::convertInto( seed, config.rngSeed );\n                config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setColourUsage = [&]( std::string const& useColour ) {\n                    auto mode = toLower( useColour );\n\n                    if( mode == \"yes\" )\n                        config.useColour = UseColour::Yes;\n                    else if( mode == \"no\" )\n                        config.useColour = UseColour::No;\n                    else if( mode == \"auto\" )\n                        config.useColour = UseColour::Auto;\n                    else\n                        return ParserResult::runtimeError( \"colour mode must be one of: auto, yes or no. '\" + useColour + \"' not recognised\" );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setWaitForKeypress = [&]( std::string const& keypress ) {\n                auto keypressLc = toLower( keypress );\n                if (keypressLc == \"never\")\n                    config.waitForKeypress = WaitForKeypress::Never;\n                else if( keypressLc == \"start\" )\n                    config.waitForKeypress = WaitForKeypress::BeforeStart;\n                else if( keypressLc == \"exit\" )\n                    config.waitForKeypress = WaitForKeypress::BeforeExit;\n                else if( keypressLc == \"both\" )\n                    config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;\n                else\n                    return ParserResult::runtimeError( \"keypress argument must be one of: never, start, exit or both. '\" + keypress + \"' not recognised\" );\n            return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setVerbosity = [&]( std::string const& verbosity ) {\n            auto lcVerbosity = toLower( verbosity );\n            if( lcVerbosity == \"quiet\" )\n                config.verbosity = Verbosity::Quiet;\n            else if( lcVerbosity == \"normal\" )\n                config.verbosity = Verbosity::Normal;\n            else if( lcVerbosity == \"high\" )\n                config.verbosity = Verbosity::High;\n            else\n                return ParserResult::runtimeError( \"Unrecognised verbosity, '\" + verbosity + \"'\" );\n            return ParserResult::ok( ParseResultType::Matched );\n        };\n        auto const setReporter = [&]( std::string const& reporter ) {\n            IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();\n\n            auto lcReporter = toLower( reporter );\n            auto result = factories.find( lcReporter );\n\n            if( factories.end() != result )\n                config.reporterName = lcReporter;\n            else\n                return ParserResult::runtimeError( \"Unrecognized reporter, '\" + reporter + \"'. Check available with --list-reporters\" );\n            return ParserResult::ok( ParseResultType::Matched );\n        };\n\n        auto cli\n            = ExeName( config.processName )\n            | Help( config.showHelp )\n            | Opt( config.listTests )\n                [\"-l\"][\"--list-tests\"]\n                ( \"list all/matching test cases\" )\n            | Opt( config.listTags )\n                [\"-t\"][\"--list-tags\"]\n                ( \"list all/matching tags\" )\n            | Opt( config.showSuccessfulTests )\n                [\"-s\"][\"--success\"]\n                ( \"include successful tests in output\" )\n            | Opt( config.shouldDebugBreak )\n                [\"-b\"][\"--break\"]\n                ( \"break into debugger on failure\" )\n            | Opt( config.noThrow )\n                [\"-e\"][\"--nothrow\"]\n                ( \"skip exception tests\" )\n            | Opt( config.showInvisibles )\n                [\"-i\"][\"--invisibles\"]\n                ( \"show invisibles (tabs, newlines)\" )\n            | Opt( config.outputFilename, \"filename\" )\n                [\"-o\"][\"--out\"]\n                ( \"output filename\" )\n            | Opt( setReporter, \"name\" )\n                [\"-r\"][\"--reporter\"]\n                ( \"reporter to use (defaults to console)\" )\n            | Opt( config.name, \"name\" )\n                [\"-n\"][\"--name\"]\n                ( \"suite name\" )\n            | Opt( [&]( bool ){ config.abortAfter = 1; } )\n                [\"-a\"][\"--abort\"]\n                ( \"abort at first failure\" )\n            | Opt( [&]( int x ){ config.abortAfter = x; }, \"no. failures\" )\n                [\"-x\"][\"--abortx\"]\n                ( \"abort after x failures\" )\n            | Opt( setWarning, \"warning name\" )\n                [\"-w\"][\"--warn\"]\n                ( \"enable warnings\" )\n            | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, \"yes|no\" )\n                [\"-d\"][\"--durations\"]\n                ( \"show test durations\" )\n            | Opt( config.minDuration, \"seconds\" )\n                [\"-D\"][\"--min-duration\"]\n                ( \"show test durations for tests taking at least the given number of seconds\" )\n            | Opt( loadTestNamesFromFile, \"filename\" )\n                [\"-f\"][\"--input-file\"]\n                ( \"load test names to run from a file\" )\n            | Opt( config.filenamesAsTags )\n                [\"-#\"][\"--filenames-as-tags\"]\n                ( \"adds a tag for the filename\" )\n            | Opt( config.sectionsToRun, \"section name\" )\n                [\"-c\"][\"--section\"]\n                ( \"specify section to run\" )\n            | Opt( setVerbosity, \"quiet|normal|high\" )\n                [\"-v\"][\"--verbosity\"]\n                ( \"set output verbosity\" )\n            | Opt( config.listTestNamesOnly )\n                [\"--list-test-names-only\"]\n                ( \"list all/matching test cases names only\" )\n            | Opt( config.listReporters )\n                [\"--list-reporters\"]\n                ( \"list all reporters\" )\n            | Opt( setTestOrder, \"decl|lex|rand\" )\n                [\"--order\"]\n                ( \"test case order (defaults to decl)\" )\n            | Opt( setRngSeed, \"'time'|number\" )\n                [\"--rng-seed\"]\n                ( \"set a specific seed for random numbers\" )\n            | Opt( setColourUsage, \"yes|no\" )\n                [\"--use-colour\"]\n                ( \"should output be colourised\" )\n            | Opt( config.libIdentify )\n                [\"--libidentify\"]\n                ( \"report name and version according to libidentify standard\" )\n            | Opt( setWaitForKeypress, \"never|start|exit|both\" )\n                [\"--wait-for-keypress\"]\n                ( \"waits for a keypress before exiting\" )\n            | Opt( config.benchmarkSamples, \"samples\" )\n                [\"--benchmark-samples\"]\n                ( \"number of samples to collect (default: 100)\" )\n            | Opt( config.benchmarkResamples, \"resamples\" )\n                [\"--benchmark-resamples\"]\n                ( \"number of resamples for the bootstrap (default: 100000)\" )\n            | Opt( config.benchmarkConfidenceInterval, \"confidence interval\" )\n                [\"--benchmark-confidence-interval\"]\n                ( \"confidence interval for the bootstrap (between 0 and 1, default: 0.95)\" )\n            | Opt( config.benchmarkNoAnalysis )\n                [\"--benchmark-no-analysis\"]\n                ( \"perform only measurements; do not perform any analysis\" )\n            | Opt( config.benchmarkWarmupTime, \"benchmarkWarmupTime\" )\n                [\"--benchmark-warmup-time\"]\n                ( \"amount of time in milliseconds spent on warming up each test (default: 100)\" )\n            | Arg( config.testsOrTags, \"test name|pattern|tags\" )\n                ( \"which test or tests to use\" );\n\n        return cli;\n    }\n\n} // end namespace Catch\n// end catch_commandline.cpp\n// start catch_common.cpp\n\n#include <cstring>\n#include <ostream>\n\nnamespace Catch {\n\n    bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {\n        return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);\n    }\n    bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {\n        // We can assume that the same file will usually have the same pointer.\n        // Thus, if the pointers are the same, there is no point in calling the strcmp\n        return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));\n    }\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {\n#ifndef __GNUG__\n        os << info.file << '(' << info.line << ')';\n#else\n        os << info.file << ':' << info.line;\n#endif\n        return os;\n    }\n\n    std::string StreamEndStop::operator+() const {\n        return std::string();\n    }\n\n    NonCopyable::NonCopyable() = default;\n    NonCopyable::~NonCopyable() = default;\n\n}\n// end catch_common.cpp\n// start catch_config.cpp\n\nnamespace Catch {\n\n    Config::Config( ConfigData const& data )\n    :   m_data( data ),\n        m_stream( openStream() )\n    {\n        // We need to trim filter specs to avoid trouble with superfluous\n        // whitespace (esp. important for bdd macros, as those are manually\n        // aligned with whitespace).\n\n        for (auto& elem : m_data.testsOrTags) {\n            elem = trim(elem);\n        }\n        for (auto& elem : m_data.sectionsToRun) {\n            elem = trim(elem);\n        }\n\n        TestSpecParser parser(ITagAliasRegistry::get());\n        if (!m_data.testsOrTags.empty()) {\n            m_hasTestFilters = true;\n            for (auto const& testOrTags : m_data.testsOrTags) {\n                parser.parse(testOrTags);\n            }\n        }\n        m_testSpec = parser.testSpec();\n    }\n\n    std::string const& Config::getFilename() const {\n        return m_data.outputFilename ;\n    }\n\n    bool Config::listTests() const          { return m_data.listTests; }\n    bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; }\n    bool Config::listTags() const           { return m_data.listTags; }\n    bool Config::listReporters() const      { return m_data.listReporters; }\n\n    std::string Config::getProcessName() const { return m_data.processName; }\n    std::string const& Config::getReporterName() const { return m_data.reporterName; }\n\n    std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }\n    std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }\n\n    TestSpec const& Config::testSpec() const { return m_testSpec; }\n    bool Config::hasTestFilters() const { return m_hasTestFilters; }\n\n    bool Config::showHelp() const { return m_data.showHelp; }\n\n    // IConfig interface\n    bool Config::allowThrows() const                   { return !m_data.noThrow; }\n    std::ostream& Config::stream() const               { return m_stream->stream(); }\n    std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; }\n    bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; }\n    bool Config::warnAboutMissingAssertions() const    { return !!(m_data.warnings & WarnAbout::NoAssertions); }\n    bool Config::warnAboutNoTests() const              { return !!(m_data.warnings & WarnAbout::NoTests); }\n    ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }\n    double Config::minDuration() const                 { return m_data.minDuration; }\n    RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }\n    unsigned int Config::rngSeed() const               { return m_data.rngSeed; }\n    UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }\n    bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }\n    int Config::abortAfter() const                     { return m_data.abortAfter; }\n    bool Config::showInvisibles() const                { return m_data.showInvisibles; }\n    Verbosity Config::verbosity() const                { return m_data.verbosity; }\n\n    bool Config::benchmarkNoAnalysis() const                      { return m_data.benchmarkNoAnalysis; }\n    int Config::benchmarkSamples() const                          { return m_data.benchmarkSamples; }\n    double Config::benchmarkConfidenceInterval() const            { return m_data.benchmarkConfidenceInterval; }\n    unsigned int Config::benchmarkResamples() const               { return m_data.benchmarkResamples; }\n    std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }\n\n    IStream const* Config::openStream() {\n        return Catch::makeStream(m_data.outputFilename);\n    }\n\n} // end namespace Catch\n// end catch_config.cpp\n// start catch_console_colour.cpp\n\n#if defined(__clang__)\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#endif\n\n// start catch_errno_guard.h\n\nnamespace Catch {\n\n    class ErrnoGuard {\n    public:\n        ErrnoGuard();\n        ~ErrnoGuard();\n    private:\n        int m_oldErrno;\n    };\n\n}\n\n// end catch_errno_guard.h\n// start catch_windows_h_proxy.h\n\n\n#if defined(CATCH_PLATFORM_WINDOWS)\n\n#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)\n#  define CATCH_DEFINED_NOMINMAX\n#  define NOMINMAX\n#endif\n#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)\n#  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN\n#  define WIN32_LEAN_AND_MEAN\n#endif\n\n#ifdef __AFXDLL\n#include <AfxWin.h>\n#else\n#include <windows.h>\n#endif\n\n#ifdef CATCH_DEFINED_NOMINMAX\n#  undef NOMINMAX\n#endif\n#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN\n#  undef WIN32_LEAN_AND_MEAN\n#endif\n\n#endif // defined(CATCH_PLATFORM_WINDOWS)\n\n// end catch_windows_h_proxy.h\n#include <sstream>\n\nnamespace Catch {\n    namespace {\n\n        struct IColourImpl {\n            virtual ~IColourImpl() = default;\n            virtual void use( Colour::Code _colourCode ) = 0;\n        };\n\n        struct NoColourImpl : IColourImpl {\n            void use( Colour::Code ) override {}\n\n            static IColourImpl* instance() {\n                static NoColourImpl s_instance;\n                return &s_instance;\n            }\n        };\n\n    } // anon namespace\n} // namespace Catch\n\n#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )\n#   ifdef CATCH_PLATFORM_WINDOWS\n#       define CATCH_CONFIG_COLOUR_WINDOWS\n#   else\n#       define CATCH_CONFIG_COLOUR_ANSI\n#   endif\n#endif\n\n#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////\n\nnamespace Catch {\nnamespace {\n\n    class Win32ColourImpl : public IColourImpl {\n    public:\n        Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )\n        {\n            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;\n            GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );\n            originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );\n            originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );\n        }\n\n        void use( Colour::Code _colourCode ) override {\n            switch( _colourCode ) {\n                case Colour::None:      return setTextAttribute( originalForegroundAttributes );\n                case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n                case Colour::Red:       return setTextAttribute( FOREGROUND_RED );\n                case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );\n                case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );\n                case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );\n                case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );\n                case Colour::Grey:      return setTextAttribute( 0 );\n\n                case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );\n                case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );\n                case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );\n                case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n                case Colour::BrightYellow:  return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );\n\n                case Colour::Bright: CATCH_INTERNAL_ERROR( \"not a colour\" );\n\n                default:\n                    CATCH_ERROR( \"Unknown colour requested\" );\n            }\n        }\n\n    private:\n        void setTextAttribute( WORD _textAttribute ) {\n            SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );\n        }\n        HANDLE stdoutHandle;\n        WORD originalForegroundAttributes;\n        WORD originalBackgroundAttributes;\n    };\n\n    IColourImpl* platformColourInstance() {\n        static Win32ColourImpl s_instance;\n\n        IConfigPtr config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = UseColour::Yes;\n        return colourMode == UseColour::Yes\n            ? &s_instance\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////\n\n#include <unistd.h>\n\nnamespace Catch {\nnamespace {\n\n    // use POSIX/ ANSI console terminal codes\n    // Thanks to Adam Strzelecki for original contribution\n    // (http://github.com/nanoant)\n    // https://github.com/philsquared/Catch/pull/131\n    class PosixColourImpl : public IColourImpl {\n    public:\n        void use( Colour::Code _colourCode ) override {\n            switch( _colourCode ) {\n                case Colour::None:\n                case Colour::White:     return setColour( \"[0m\" );\n                case Colour::Red:       return setColour( \"[0;31m\" );\n                case Colour::Green:     return setColour( \"[0;32m\" );\n                case Colour::Blue:      return setColour( \"[0;34m\" );\n                case Colour::Cyan:      return setColour( \"[0;36m\" );\n                case Colour::Yellow:    return setColour( \"[0;33m\" );\n                case Colour::Grey:      return setColour( \"[1;30m\" );\n\n                case Colour::LightGrey:     return setColour( \"[0;37m\" );\n                case Colour::BrightRed:     return setColour( \"[1;31m\" );\n                case Colour::BrightGreen:   return setColour( \"[1;32m\" );\n                case Colour::BrightWhite:   return setColour( \"[1;37m\" );\n                case Colour::BrightYellow:  return setColour( \"[1;33m\" );\n\n                case Colour::Bright: CATCH_INTERNAL_ERROR( \"not a colour\" );\n                default: CATCH_INTERNAL_ERROR( \"Unknown colour requested\" );\n            }\n        }\n        static IColourImpl* instance() {\n            static PosixColourImpl s_instance;\n            return &s_instance;\n        }\n\n    private:\n        void setColour( const char* _escapeCode ) {\n            getCurrentContext().getConfig()->stream()\n                << '\\033' << _escapeCode;\n        }\n    };\n\n    bool useColourOnPlatform() {\n        return\n#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)\n            !isDebuggerActive() &&\n#endif\n#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))\n            isatty(STDOUT_FILENO)\n#else\n            false\n#endif\n            ;\n    }\n    IColourImpl* platformColourInstance() {\n        ErrnoGuard guard;\n        IConfigPtr config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = useColourOnPlatform()\n                ? UseColour::Yes\n                : UseColour::No;\n        return colourMode == UseColour::Yes\n            ? PosixColourImpl::instance()\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#else  // not Windows or ANSI ///////////////////////////////////////////////\n\nnamespace Catch {\n\n    static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }\n\n} // end namespace Catch\n\n#endif // Windows/ ANSI/ None\n\nnamespace Catch {\n\n    Colour::Colour( Code _colourCode ) { use( _colourCode ); }\n    Colour::Colour( Colour&& other ) noexcept {\n        m_moved = other.m_moved;\n        other.m_moved = true;\n    }\n    Colour& Colour::operator=( Colour&& other ) noexcept {\n        m_moved = other.m_moved;\n        other.m_moved  = true;\n        return *this;\n    }\n\n    Colour::~Colour(){ if( !m_moved ) use( None ); }\n\n    void Colour::use( Code _colourCode ) {\n        static IColourImpl* impl = platformColourInstance();\n        // Strictly speaking, this cannot possibly happen.\n        // However, under some conditions it does happen (see #1626),\n        // and this change is small enough that we can let practicality\n        // triumph over purity in this case.\n        if (impl != nullptr) {\n            impl->use( _colourCode );\n        }\n    }\n\n    std::ostream& operator << ( std::ostream& os, Colour const& ) {\n        return os;\n    }\n\n} // end namespace Catch\n\n#if defined(__clang__)\n#    pragma clang diagnostic pop\n#endif\n\n// end catch_console_colour.cpp\n// start catch_context.cpp\n\nnamespace Catch {\n\n    class Context : public IMutableContext, NonCopyable {\n\n    public: // IContext\n        IResultCapture* getResultCapture() override {\n            return m_resultCapture;\n        }\n        IRunner* getRunner() override {\n            return m_runner;\n        }\n\n        IConfigPtr const& getConfig() const override {\n            return m_config;\n        }\n\n        ~Context() override;\n\n    public: // IMutableContext\n        void setResultCapture( IResultCapture* resultCapture ) override {\n            m_resultCapture = resultCapture;\n        }\n        void setRunner( IRunner* runner ) override {\n            m_runner = runner;\n        }\n        void setConfig( IConfigPtr const& config ) override {\n            m_config = config;\n        }\n\n        friend IMutableContext& getCurrentMutableContext();\n\n    private:\n        IConfigPtr m_config;\n        IRunner* m_runner = nullptr;\n        IResultCapture* m_resultCapture = nullptr;\n    };\n\n    IMutableContext *IMutableContext::currentContext = nullptr;\n\n    void IMutableContext::createContext()\n    {\n        currentContext = new Context();\n    }\n\n    void cleanUpContext() {\n        delete IMutableContext::currentContext;\n        IMutableContext::currentContext = nullptr;\n    }\n    IContext::~IContext() = default;\n    IMutableContext::~IMutableContext() = default;\n    Context::~Context() = default;\n\n    SimplePcg32& rng() {\n        static SimplePcg32 s_rng;\n        return s_rng;\n    }\n\n}\n// end catch_context.cpp\n// start catch_debug_console.cpp\n\n// start catch_debug_console.h\n\n#include <string>\n\nnamespace Catch {\n    void writeToDebugConsole( std::string const& text );\n}\n\n// end catch_debug_console.h\n#if defined(CATCH_CONFIG_ANDROID_LOGWRITE)\n#include <android/log.h>\n\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            __android_log_write( ANDROID_LOG_DEBUG, \"Catch\", text.c_str() );\n        }\n    }\n\n#elif defined(CATCH_PLATFORM_WINDOWS)\n\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            ::OutputDebugStringA( text.c_str() );\n        }\n    }\n\n#else\n\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            // !TBD: Need a version for Mac/ XCode and other IDEs\n            Catch::cout() << text;\n        }\n    }\n\n#endif // Platform\n// end catch_debug_console.cpp\n// start catch_debugger.cpp\n\n#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)\n\n#  include <cassert>\n#  include <sys/types.h>\n#  include <unistd.h>\n#  include <cstddef>\n#  include <ostream>\n\n#ifdef __apple_build_version__\n    // These headers will only compile with AppleClang (XCode)\n    // For other compilers (Clang, GCC, ... ) we need to exclude them\n#  include <sys/sysctl.h>\n#endif\n\n    namespace Catch {\n        #ifdef __apple_build_version__\n        // The following function is taken directly from the following technical note:\n        // https://developer.apple.com/library/archive/qa/qa1361/_index.html\n\n        // Returns true if the current process is being debugged (either\n        // running under the debugger or has a debugger attached post facto).\n        bool isDebuggerActive(){\n            int                 mib[4];\n            struct kinfo_proc   info;\n            std::size_t         size;\n\n            // Initialize the flags so that, if sysctl fails for some bizarre\n            // reason, we get a predictable result.\n\n            info.kp_proc.p_flag = 0;\n\n            // Initialize mib, which tells sysctl the info we want, in this case\n            // we're looking for information about a specific process ID.\n\n            mib[0] = CTL_KERN;\n            mib[1] = KERN_PROC;\n            mib[2] = KERN_PROC_PID;\n            mib[3] = getpid();\n\n            // Call sysctl.\n\n            size = sizeof(info);\n            if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {\n                Catch::cerr() << \"\\n** Call to sysctl failed - unable to determine if debugger is active **\\n\" << std::endl;\n                return false;\n            }\n\n            // We're being debugged if the P_TRACED flag is set.\n\n            return ( (info.kp_proc.p_flag & P_TRACED) != 0 );\n        }\n        #else\n        bool isDebuggerActive() {\n            // We need to find another way to determine this for non-appleclang compilers on macOS\n            return false;\n        }\n        #endif\n    } // namespace Catch\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    #include <fstream>\n    #include <string>\n\n    namespace Catch{\n        // The standard POSIX way of detecting a debugger is to attempt to\n        // ptrace() the process, but this needs to be done from a child and not\n        // this process itself to still allow attaching to this process later\n        // if wanted, so is rather heavy. Under Linux we have the PID of the\n        // \"debugger\" (which doesn't need to be gdb, of course, it could also\n        // be strace, for example) in /proc/$PID/status, so just get it from\n        // there instead.\n        bool isDebuggerActive(){\n            // Libstdc++ has a bug, where std::ifstream sets errno to 0\n            // This way our users can properly assert over errno values\n            ErrnoGuard guard;\n            std::ifstream in(\"/proc/self/status\");\n            for( std::string line; std::getline(in, line); ) {\n                static const int PREFIX_LEN = 11;\n                if( line.compare(0, PREFIX_LEN, \"TracerPid:\\t\") == 0 ) {\n                    // We're traced if the PID is not 0 and no other PID starts\n                    // with 0 digit, so it's enough to check for just a single\n                    // character.\n                    return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';\n                }\n            }\n\n            return false;\n        }\n    } // namespace Catch\n#elif defined(_MSC_VER)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#else\n    namespace Catch {\n       bool isDebuggerActive() { return false; }\n    }\n#endif // Platform\n// end catch_debugger.cpp\n// start catch_decomposer.cpp\n\nnamespace Catch {\n\n    ITransientExpression::~ITransientExpression() = default;\n\n    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {\n        if( lhs.size() + rhs.size() < 40 &&\n                lhs.find('\\n') == std::string::npos &&\n                rhs.find('\\n') == std::string::npos )\n            os << lhs << \" \" << op << \" \" << rhs;\n        else\n            os << lhs << \"\\n\" << op << \"\\n\" << rhs;\n    }\n}\n// end catch_decomposer.cpp\n// start catch_enforce.cpp\n\n#include <stdexcept>\n\nnamespace Catch {\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)\n    [[noreturn]]\n    void throw_exception(std::exception const& e) {\n        Catch::cerr() << \"Catch will terminate because it needed to throw an exception.\\n\"\n                      << \"The message was: \" << e.what() << '\\n';\n        std::terminate();\n    }\n#endif\n\n    [[noreturn]]\n    void throw_logic_error(std::string const& msg) {\n        throw_exception(std::logic_error(msg));\n    }\n\n    [[noreturn]]\n    void throw_domain_error(std::string const& msg) {\n        throw_exception(std::domain_error(msg));\n    }\n\n    [[noreturn]]\n    void throw_runtime_error(std::string const& msg) {\n        throw_exception(std::runtime_error(msg));\n    }\n\n} // namespace Catch;\n// end catch_enforce.cpp\n// start catch_enum_values_registry.cpp\n// start catch_enum_values_registry.h\n\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    namespace Detail {\n\n        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );\n\n        class EnumValuesRegistry : public IMutableEnumValuesRegistry {\n\n            std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;\n\n            EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;\n        };\n\n        std::vector<StringRef> parseEnums( StringRef enums );\n\n    } // Detail\n\n} // Catch\n\n// end catch_enum_values_registry.h\n\n#include <map>\n#include <cassert>\n\nnamespace Catch {\n\n    IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}\n\n    namespace Detail {\n\n        namespace {\n            // Extracts the actual name part of an enum instance\n            // In other words, it returns the Blue part of Bikeshed::Colour::Blue\n            StringRef extractInstanceName(StringRef enumInstance) {\n                // Find last occurrence of \":\"\n                size_t name_start = enumInstance.size();\n                while (name_start > 0 && enumInstance[name_start - 1] != ':') {\n                    --name_start;\n                }\n                return enumInstance.substr(name_start, enumInstance.size() - name_start);\n            }\n        }\n\n        std::vector<StringRef> parseEnums( StringRef enums ) {\n            auto enumValues = splitStringRef( enums, ',' );\n            std::vector<StringRef> parsed;\n            parsed.reserve( enumValues.size() );\n            for( auto const& enumValue : enumValues ) {\n                parsed.push_back(trim(extractInstanceName(enumValue)));\n            }\n            return parsed;\n        }\n\n        EnumInfo::~EnumInfo() {}\n\n        StringRef EnumInfo::lookup( int value ) const {\n            for( auto const& valueToName : m_values ) {\n                if( valueToName.first == value )\n                    return valueToName.second;\n            }\n            return \"{** unexpected enum value **}\"_sr;\n        }\n\n        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {\n            std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );\n            enumInfo->m_name = enumName;\n            enumInfo->m_values.reserve( values.size() );\n\n            const auto valueNames = Catch::Detail::parseEnums( allValueNames );\n            assert( valueNames.size() == values.size() );\n            std::size_t i = 0;\n            for( auto value : values )\n                enumInfo->m_values.emplace_back(value, valueNames[i++]);\n\n            return enumInfo;\n        }\n\n        EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {\n            m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));\n            return *m_enumInfos.back();\n        }\n\n    } // Detail\n} // Catch\n\n// end catch_enum_values_registry.cpp\n// start catch_errno_guard.cpp\n\n#include <cerrno>\n\nnamespace Catch {\n        ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}\n        ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }\n}\n// end catch_errno_guard.cpp\n// start catch_exception_translator_registry.cpp\n\n// start catch_exception_translator_registry.h\n\n#include <vector>\n#include <string>\n#include <memory>\n\nnamespace Catch {\n\n    class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {\n    public:\n        ~ExceptionTranslatorRegistry();\n        virtual void registerTranslator( const IExceptionTranslator* translator );\n        std::string translateActiveException() const override;\n        std::string tryTranslators() const;\n\n    private:\n        std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;\n    };\n}\n\n// end catch_exception_translator_registry.h\n#ifdef __OBJC__\n#import \"Foundation/Foundation.h\"\n#endif\n\nnamespace Catch {\n\n    ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {\n    }\n\n    void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {\n        m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );\n    }\n\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n    std::string ExceptionTranslatorRegistry::translateActiveException() const {\n        try {\n#ifdef __OBJC__\n            // In Objective-C try objective-c exceptions first\n            @try {\n                return tryTranslators();\n            }\n            @catch (NSException *exception) {\n                return Catch::Detail::stringify( [exception description] );\n            }\n#else\n            // Compiling a mixed mode project with MSVC means that CLR\n            // exceptions will be caught in (...) as well. However, these\n            // do not fill-in std::current_exception and thus lead to crash\n            // when attempting rethrow.\n            // /EHa switch also causes structured exceptions to be caught\n            // here, but they fill-in current_exception properly, so\n            // at worst the output should be a little weird, instead of\n            // causing a crash.\n            if (std::current_exception() == nullptr) {\n                return \"Non C++ exception. Possibly a CLR exception.\";\n            }\n            return tryTranslators();\n#endif\n        }\n        catch( TestFailureException& ) {\n            std::rethrow_exception(std::current_exception());\n        }\n        catch( std::exception& ex ) {\n            return ex.what();\n        }\n        catch( std::string& msg ) {\n            return msg;\n        }\n        catch( const char* msg ) {\n            return msg;\n        }\n        catch(...) {\n            return \"Unknown exception\";\n        }\n    }\n\n    std::string ExceptionTranslatorRegistry::tryTranslators() const {\n        if (m_translators.empty()) {\n            std::rethrow_exception(std::current_exception());\n        } else {\n            return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());\n        }\n    }\n\n#else // ^^ Exceptions are enabled // Exceptions are disabled vv\n    std::string ExceptionTranslatorRegistry::translateActiveException() const {\n        CATCH_INTERNAL_ERROR(\"Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!\");\n    }\n\n    std::string ExceptionTranslatorRegistry::tryTranslators() const {\n        CATCH_INTERNAL_ERROR(\"Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!\");\n    }\n#endif\n\n}\n// end catch_exception_translator_registry.cpp\n// start catch_fatal_condition.cpp\n\n#include <algorithm>\n\n#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )\n\nnamespace Catch {\n\n    // If neither SEH nor signal handling is required, the handler impls\n    // do not have to do anything, and can be empty.\n    void FatalConditionHandler::engage_platform() {}\n    void FatalConditionHandler::disengage_platform() {}\n    FatalConditionHandler::FatalConditionHandler() = default;\n    FatalConditionHandler::~FatalConditionHandler() = default;\n\n} // end namespace Catch\n\n#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS\n\n#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS )\n#error \"Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time\"\n#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS\n\n#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )\n\nnamespace {\n    //! Signals fatal error message to the run context\n    void reportFatal( char const * const message ) {\n        Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );\n    }\n\n    //! Minimal size Catch2 needs for its own fatal error handling.\n    //! Picked anecdotally, so it might not be sufficient on all\n    //! platforms, and for all configurations.\n    constexpr std::size_t minStackSizeForErrors = 32 * 1024;\n} // end unnamed namespace\n\n#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS\n\n#if defined( CATCH_CONFIG_WINDOWS_SEH )\n\nnamespace Catch {\n\n    struct SignalDefs { DWORD id; const char* name; };\n\n    // There is no 1-1 mapping between signals and windows exceptions.\n    // Windows can easily distinguish between SO and SigSegV,\n    // but SigInt, SigTerm, etc are handled differently.\n    static SignalDefs signalDefs[] = {\n        { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),  \"SIGILL - Illegal instruction signal\" },\n        { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), \"SIGSEGV - Stack overflow\" },\n        { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), \"SIGSEGV - Segmentation violation signal\" },\n        { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), \"Divide by zero error\" },\n    };\n\n    static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {\n        for (auto const& def : signalDefs) {\n            if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {\n                reportFatal(def.name);\n            }\n        }\n        // If its not an exception we care about, pass it along.\n        // This stops us from eating debugger breaks etc.\n        return EXCEPTION_CONTINUE_SEARCH;\n    }\n\n    // Since we do not support multiple instantiations, we put these\n    // into global variables and rely on cleaning them up in outlined\n    // constructors/destructors\n    static PVOID exceptionHandlerHandle = nullptr;\n\n    // For MSVC, we reserve part of the stack memory for handling\n    // memory overflow structured exception.\n    FatalConditionHandler::FatalConditionHandler() {\n        ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors);\n        if (!SetThreadStackGuarantee(&guaranteeSize)) {\n            // We do not want to fully error out, because needing\n            // the stack reserve should be rare enough anyway.\n            Catch::cerr()\n                << \"Failed to reserve piece of stack.\"\n                << \" Stack overflows will not be reported successfully.\";\n        }\n    }\n\n    // We do not attempt to unset the stack guarantee, because\n    // Windows does not support lowering the stack size guarantee.\n    FatalConditionHandler::~FatalConditionHandler() = default;\n\n    void FatalConditionHandler::engage_platform() {\n        // Register as first handler in current chain\n        exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);\n        if (!exceptionHandlerHandle) {\n            CATCH_RUNTIME_ERROR(\"Could not register vectored exception handler\");\n        }\n    }\n\n    void FatalConditionHandler::disengage_platform() {\n        if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {\n            CATCH_RUNTIME_ERROR(\"Could not unregister vectored exception handler\");\n        }\n        exceptionHandlerHandle = nullptr;\n    }\n\n} // end namespace Catch\n\n#endif // CATCH_CONFIG_WINDOWS_SEH\n\n#if defined( CATCH_CONFIG_POSIX_SIGNALS )\n\n#include <signal.h>\n\nnamespace Catch {\n\n    struct SignalDefs {\n        int id;\n        const char* name;\n    };\n\n    static SignalDefs signalDefs[] = {\n        { SIGINT,  \"SIGINT - Terminal interrupt signal\" },\n        { SIGILL,  \"SIGILL - Illegal instruction signal\" },\n        { SIGFPE,  \"SIGFPE - Floating point error signal\" },\n        { SIGSEGV, \"SIGSEGV - Segmentation violation signal\" },\n        { SIGTERM, \"SIGTERM - Termination request signal\" },\n        { SIGABRT, \"SIGABRT - Abort (abnormal termination) signal\" }\n    };\n\n// Older GCCs trigger -Wmissing-field-initializers for T foo = {}\n// which is zero initialization, but not explicit. We want to avoid\n// that.\n#if defined(__GNUC__)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n\n    static char* altStackMem = nullptr;\n    static std::size_t altStackSize = 0;\n    static stack_t oldSigStack{};\n    static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};\n\n    static void restorePreviousSignalHandlers() {\n        // We set signal handlers back to the previous ones. Hopefully\n        // nobody overwrote them in the meantime, and doesn't expect\n        // their signal handlers to live past ours given that they\n        // installed them after ours..\n        for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {\n            sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);\n        }\n        // Return the old stack\n        sigaltstack(&oldSigStack, nullptr);\n    }\n\n    static void handleSignal( int sig ) {\n        char const * name = \"<unknown signal>\";\n        for (auto const& def : signalDefs) {\n            if (sig == def.id) {\n                name = def.name;\n                break;\n            }\n        }\n        // We need to restore previous signal handlers and let them do\n        // their thing, so that the users can have the debugger break\n        // when a signal is raised, and so on.\n        restorePreviousSignalHandlers();\n        reportFatal( name );\n        raise( sig );\n    }\n\n    FatalConditionHandler::FatalConditionHandler() {\n        assert(!altStackMem && \"Cannot initialize POSIX signal handler when one already exists\");\n        if (altStackSize == 0) {\n            altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors);\n        }\n        altStackMem = new char[altStackSize]();\n    }\n\n    FatalConditionHandler::~FatalConditionHandler() {\n        delete[] altStackMem;\n        // We signal that another instance can be constructed by zeroing\n        // out the pointer.\n        altStackMem = nullptr;\n    }\n\n    void FatalConditionHandler::engage_platform() {\n        stack_t sigStack;\n        sigStack.ss_sp = altStackMem;\n        sigStack.ss_size = altStackSize;\n        sigStack.ss_flags = 0;\n        sigaltstack(&sigStack, &oldSigStack);\n        struct sigaction sa = { };\n\n        sa.sa_handler = handleSignal;\n        sa.sa_flags = SA_ONSTACK;\n        for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {\n            sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);\n        }\n    }\n\n#if defined(__GNUC__)\n#    pragma GCC diagnostic pop\n#endif\n\n    void FatalConditionHandler::disengage_platform() {\n        restorePreviousSignalHandlers();\n    }\n\n} // end namespace Catch\n\n#endif // CATCH_CONFIG_POSIX_SIGNALS\n// end catch_fatal_condition.cpp\n// start catch_generators.cpp\n\n#include <limits>\n#include <set>\n\nnamespace Catch {\n\nIGeneratorTracker::~IGeneratorTracker() {}\n\nconst char* GeneratorException::what() const noexcept {\n    return m_msg;\n}\n\nnamespace Generators {\n\n    GeneratorUntypedBase::~GeneratorUntypedBase() {}\n\n    auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {\n        return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );\n    }\n\n} // namespace Generators\n} // namespace Catch\n// end catch_generators.cpp\n// start catch_interfaces_capture.cpp\n\nnamespace Catch {\n    IResultCapture::~IResultCapture() = default;\n}\n// end catch_interfaces_capture.cpp\n// start catch_interfaces_config.cpp\n\nnamespace Catch {\n    IConfig::~IConfig() = default;\n}\n// end catch_interfaces_config.cpp\n// start catch_interfaces_exception.cpp\n\nnamespace Catch {\n    IExceptionTranslator::~IExceptionTranslator() = default;\n    IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;\n}\n// end catch_interfaces_exception.cpp\n// start catch_interfaces_registry_hub.cpp\n\nnamespace Catch {\n    IRegistryHub::~IRegistryHub() = default;\n    IMutableRegistryHub::~IMutableRegistryHub() = default;\n}\n// end catch_interfaces_registry_hub.cpp\n// start catch_interfaces_reporter.cpp\n\n// start catch_reporter_listening.h\n\nnamespace Catch {\n\n    class ListeningReporter : public IStreamingReporter {\n        using Reporters = std::vector<IStreamingReporterPtr>;\n        Reporters m_listeners;\n        IStreamingReporterPtr m_reporter = nullptr;\n        ReporterPreferences m_preferences;\n\n    public:\n        ListeningReporter();\n\n        void addListener( IStreamingReporterPtr&& listener );\n        void addReporter( IStreamingReporterPtr&& reporter );\n\n    public: // IStreamingReporter\n\n        ReporterPreferences getPreferences() const override;\n\n        void noMatchingTestCases( std::string const& spec ) override;\n\n        void reportInvalidArguments(std::string const&arg) override;\n\n        static std::set<Verbosity> getSupportedVerbosities();\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing(std::string const& name) override;\n        void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;\n        void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;\n        void benchmarkFailed(std::string const&) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        void testRunStarting( TestRunInfo const& testRunInfo ) override;\n        void testGroupStarting( GroupInfo const& groupInfo ) override;\n        void testCaseStarting( TestCaseInfo const& testInfo ) override;\n        void sectionStarting( SectionInfo const& sectionInfo ) override;\n        void assertionStarting( AssertionInfo const& assertionInfo ) override;\n\n        // The return value indicates if the messages buffer should be cleared:\n        bool assertionEnded( AssertionStats const& assertionStats ) override;\n        void sectionEnded( SectionStats const& sectionStats ) override;\n        void testCaseEnded( TestCaseStats const& testCaseStats ) override;\n        void testGroupEnded( TestGroupStats const& testGroupStats ) override;\n        void testRunEnded( TestRunStats const& testRunStats ) override;\n\n        void skipTest( TestCaseInfo const& testInfo ) override;\n        bool isMulti() const override;\n\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_listening.h\nnamespace Catch {\n\n    ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )\n    :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}\n\n    ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )\n    :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}\n\n    std::ostream& ReporterConfig::stream() const { return *m_stream; }\n    IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }\n\n    TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}\n\n    GroupInfo::GroupInfo(  std::string const& _name,\n                           std::size_t _groupIndex,\n                           std::size_t _groupsCount )\n    :   name( _name ),\n        groupIndex( _groupIndex ),\n        groupsCounts( _groupsCount )\n    {}\n\n     AssertionStats::AssertionStats( AssertionResult const& _assertionResult,\n                                     std::vector<MessageInfo> const& _infoMessages,\n                                     Totals const& _totals )\n    :   assertionResult( _assertionResult ),\n        infoMessages( _infoMessages ),\n        totals( _totals )\n    {\n        assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;\n\n        if( assertionResult.hasMessage() ) {\n            // Copy message into messages list.\n            // !TBD This should have been done earlier, somewhere\n            MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );\n            builder << assertionResult.getMessage();\n            builder.m_info.message = builder.m_stream.str();\n\n            infoMessages.push_back( builder.m_info );\n        }\n    }\n\n     AssertionStats::~AssertionStats() = default;\n\n    SectionStats::SectionStats(  SectionInfo const& _sectionInfo,\n                                 Counts const& _assertions,\n                                 double _durationInSeconds,\n                                 bool _missingAssertions )\n    :   sectionInfo( _sectionInfo ),\n        assertions( _assertions ),\n        durationInSeconds( _durationInSeconds ),\n        missingAssertions( _missingAssertions )\n    {}\n\n    SectionStats::~SectionStats() = default;\n\n    TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo,\n                                   Totals const& _totals,\n                                   std::string const& _stdOut,\n                                   std::string const& _stdErr,\n                                   bool _aborting )\n    : testInfo( _testInfo ),\n        totals( _totals ),\n        stdOut( _stdOut ),\n        stdErr( _stdErr ),\n        aborting( _aborting )\n    {}\n\n    TestCaseStats::~TestCaseStats() = default;\n\n    TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,\n                                    Totals const& _totals,\n                                    bool _aborting )\n    :   groupInfo( _groupInfo ),\n        totals( _totals ),\n        aborting( _aborting )\n    {}\n\n    TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )\n    :   groupInfo( _groupInfo ),\n        aborting( false )\n    {}\n\n    TestGroupStats::~TestGroupStats() = default;\n\n    TestRunStats::TestRunStats(   TestRunInfo const& _runInfo,\n                    Totals const& _totals,\n                    bool _aborting )\n    :   runInfo( _runInfo ),\n        totals( _totals ),\n        aborting( _aborting )\n    {}\n\n    TestRunStats::~TestRunStats() = default;\n\n    void IStreamingReporter::fatalErrorEncountered( StringRef ) {}\n    bool IStreamingReporter::isMulti() const { return false; }\n\n    IReporterFactory::~IReporterFactory() = default;\n    IReporterRegistry::~IReporterRegistry() = default;\n\n} // end namespace Catch\n// end catch_interfaces_reporter.cpp\n// start catch_interfaces_runner.cpp\n\nnamespace Catch {\n    IRunner::~IRunner() = default;\n}\n// end catch_interfaces_runner.cpp\n// start catch_interfaces_testcase.cpp\n\nnamespace Catch {\n    ITestInvoker::~ITestInvoker() = default;\n    ITestCaseRegistry::~ITestCaseRegistry() = default;\n}\n// end catch_interfaces_testcase.cpp\n// start catch_leak_detector.cpp\n\n#ifdef CATCH_CONFIG_WINDOWS_CRTDBG\n#include <crtdbg.h>\n\nnamespace Catch {\n\n    LeakDetector::LeakDetector() {\n        int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);\n        flag |= _CRTDBG_LEAK_CHECK_DF;\n        flag |= _CRTDBG_ALLOC_MEM_DF;\n        _CrtSetDbgFlag(flag);\n        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);\n        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);\n        // Change this to leaking allocation's number to break there\n        _CrtSetBreakAlloc(-1);\n    }\n}\n\n#else\n\n    Catch::LeakDetector::LeakDetector() {}\n\n#endif\n\nCatch::LeakDetector::~LeakDetector() {\n    Catch::cleanUp();\n}\n// end catch_leak_detector.cpp\n// start catch_list.cpp\n\n// start catch_list.h\n\n#include <set>\n\nnamespace Catch {\n\n    std::size_t listTests( Config const& config );\n\n    std::size_t listTestsNamesOnly( Config const& config );\n\n    struct TagInfo {\n        void add( std::string const& spelling );\n        std::string all() const;\n\n        std::set<std::string> spellings;\n        std::size_t count = 0;\n    };\n\n    std::size_t listTags( Config const& config );\n\n    std::size_t listReporters();\n\n    Option<std::size_t> list( std::shared_ptr<Config> const& config );\n\n} // end namespace Catch\n\n// end catch_list.h\n// start catch_text.h\n\nnamespace Catch {\n    using namespace clara::TextFlow;\n}\n\n// end catch_text.h\n#include <limits>\n#include <algorithm>\n#include <iomanip>\n\nnamespace Catch {\n\n    std::size_t listTests( Config const& config ) {\n        TestSpec const& testSpec = config.testSpec();\n        if( config.hasTestFilters() )\n            Catch::cout() << \"Matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available test cases:\\n\";\n        }\n\n        auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( auto const& testCaseInfo : matchedTestCases ) {\n            Colour::Code colour = testCaseInfo.isHidden()\n                ? Colour::SecondaryText\n                : Colour::None;\n            Colour colourGuard( colour );\n\n            Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << \"\\n\";\n            if( config.verbosity() >= Verbosity::High ) {\n                Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;\n                std::string description = testCaseInfo.description;\n                if( description.empty() )\n                    description = \"(NO DESCRIPTION)\";\n                Catch::cout() << Column( description ).indent(4) << std::endl;\n            }\n            if( !testCaseInfo.tags.empty() )\n                Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << \"\\n\";\n        }\n\n        if( !config.hasTestFilters() )\n            Catch::cout() << pluralise( matchedTestCases.size(), \"test case\" ) << '\\n' << std::endl;\n        else\n            Catch::cout() << pluralise( matchedTestCases.size(), \"matching test case\" ) << '\\n' << std::endl;\n        return matchedTestCases.size();\n    }\n\n    std::size_t listTestsNamesOnly( Config const& config ) {\n        TestSpec const& testSpec = config.testSpec();\n        std::size_t matchedTests = 0;\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( auto const& testCaseInfo : matchedTestCases ) {\n            matchedTests++;\n            if( startsWith( testCaseInfo.name, '#' ) )\n               Catch::cout() << '\"' << testCaseInfo.name << '\"';\n            else\n               Catch::cout() << testCaseInfo.name;\n            if ( config.verbosity() >= Verbosity::High )\n                Catch::cout() << \"\\t@\" << testCaseInfo.lineInfo;\n            Catch::cout() << std::endl;\n        }\n        return matchedTests;\n    }\n\n    void TagInfo::add( std::string const& spelling ) {\n        ++count;\n        spellings.insert( spelling );\n    }\n\n    std::string TagInfo::all() const {\n        size_t size = 0;\n        for (auto const& spelling : spellings) {\n            // Add 2 for the brackes\n            size += spelling.size() + 2;\n        }\n\n        std::string out; out.reserve(size);\n        for (auto const& spelling : spellings) {\n            out += '[';\n            out += spelling;\n            out += ']';\n        }\n        return out;\n    }\n\n    std::size_t listTags( Config const& config ) {\n        TestSpec const& testSpec = config.testSpec();\n        if( config.hasTestFilters() )\n            Catch::cout() << \"Tags for matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available tags:\\n\";\n        }\n\n        std::map<std::string, TagInfo> tagCounts;\n\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( auto const& testCase : matchedTestCases ) {\n            for( auto const& tagName : testCase.getTestCaseInfo().tags ) {\n                std::string lcaseTagName = toLower( tagName );\n                auto countIt = tagCounts.find( lcaseTagName );\n                if( countIt == tagCounts.end() )\n                    countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;\n                countIt->second.add( tagName );\n            }\n        }\n\n        for( auto const& tagCount : tagCounts ) {\n            ReusableStringStream rss;\n            rss << \"  \" << std::setw(2) << tagCount.second.count << \"  \";\n            auto str = rss.str();\n            auto wrapper = Column( tagCount.second.all() )\n                                                    .initialIndent( 0 )\n                                                    .indent( str.size() )\n                                                    .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );\n            Catch::cout() << str << wrapper << '\\n';\n        }\n        Catch::cout() << pluralise( tagCounts.size(), \"tag\" ) << '\\n' << std::endl;\n        return tagCounts.size();\n    }\n\n    std::size_t listReporters() {\n        Catch::cout() << \"Available reporters:\\n\";\n        IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();\n        std::size_t maxNameLen = 0;\n        for( auto const& factoryKvp : factories )\n            maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );\n\n        for( auto const& factoryKvp : factories ) {\n            Catch::cout()\n                    << Column( factoryKvp.first + \":\" )\n                            .indent(2)\n                            .width( 5+maxNameLen )\n                    +  Column( factoryKvp.second->getDescription() )\n                            .initialIndent(0)\n                            .indent(2)\n                            .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )\n                    << \"\\n\";\n        }\n        Catch::cout() << std::endl;\n        return factories.size();\n    }\n\n    Option<std::size_t> list( std::shared_ptr<Config> const& config ) {\n        Option<std::size_t> listedCount;\n        getCurrentMutableContext().setConfig( config );\n        if( config->listTests() )\n            listedCount = listedCount.valueOr(0) + listTests( *config );\n        if( config->listTestNamesOnly() )\n            listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );\n        if( config->listTags() )\n            listedCount = listedCount.valueOr(0) + listTags( *config );\n        if( config->listReporters() )\n            listedCount = listedCount.valueOr(0) + listReporters();\n        return listedCount;\n    }\n\n} // end namespace Catch\n// end catch_list.cpp\n// start catch_matchers.cpp\n\nnamespace Catch {\nnamespace Matchers {\n    namespace Impl {\n\n        std::string MatcherUntypedBase::toString() const {\n            if( m_cachedToString.empty() )\n                m_cachedToString = describe();\n            return m_cachedToString;\n        }\n\n        MatcherUntypedBase::~MatcherUntypedBase() = default;\n\n    } // namespace Impl\n} // namespace Matchers\n\nusing namespace Matchers;\nusing Matchers::Impl::MatcherBase;\n\n} // namespace Catch\n// end catch_matchers.cpp\n// start catch_matchers_exception.cpp\n\nnamespace Catch {\nnamespace Matchers {\nnamespace Exception {\n\nbool ExceptionMessageMatcher::match(std::exception const& ex) const {\n    return ex.what() == m_message;\n}\n\nstd::string ExceptionMessageMatcher::describe() const {\n    return \"exception message matches \\\"\" + m_message + \"\\\"\";\n}\n\n}\nException::ExceptionMessageMatcher Message(std::string const& message) {\n    return Exception::ExceptionMessageMatcher(message);\n}\n\n// namespace Exception\n} // namespace Matchers\n} // namespace Catch\n// end catch_matchers_exception.cpp\n// start catch_matchers_floating.cpp\n\n// start catch_polyfills.hpp\n\nnamespace Catch {\n    bool isnan(float f);\n    bool isnan(double d);\n}\n\n// end catch_polyfills.hpp\n// start catch_to_string.hpp\n\n#include <string>\n\nnamespace Catch {\n    template <typename T>\n    std::string to_string(T const& t) {\n#if defined(CATCH_CONFIG_CPP11_TO_STRING)\n        return std::to_string(t);\n#else\n        ReusableStringStream rss;\n        rss << t;\n        return rss.str();\n#endif\n    }\n} // end namespace Catch\n\n// end catch_to_string.hpp\n#include <algorithm>\n#include <cmath>\n#include <cstdlib>\n#include <cstdint>\n#include <cstring>\n#include <sstream>\n#include <type_traits>\n#include <iomanip>\n#include <limits>\n\nnamespace Catch {\nnamespace {\n\n    int32_t convert(float f) {\n        static_assert(sizeof(float) == sizeof(int32_t), \"Important ULP matcher assumption violated\");\n        int32_t i;\n        std::memcpy(&i, &f, sizeof(f));\n        return i;\n    }\n\n    int64_t convert(double d) {\n        static_assert(sizeof(double) == sizeof(int64_t), \"Important ULP matcher assumption violated\");\n        int64_t i;\n        std::memcpy(&i, &d, sizeof(d));\n        return i;\n    }\n\n    template <typename FP>\n    bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {\n        // Comparison with NaN should always be false.\n        // This way we can rule it out before getting into the ugly details\n        if (Catch::isnan(lhs) || Catch::isnan(rhs)) {\n            return false;\n        }\n\n        auto lc = convert(lhs);\n        auto rc = convert(rhs);\n\n        if ((lc < 0) != (rc < 0)) {\n            // Potentially we can have +0 and -0\n            return lhs == rhs;\n        }\n\n        // static cast as a workaround for IBM XLC\n        auto ulpDiff = std::abs(static_cast<FP>(lc - rc));\n        return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;\n    }\n\n#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)\n\n    float nextafter(float x, float y) {\n        return ::nextafterf(x, y);\n    }\n\n    double nextafter(double x, double y) {\n        return ::nextafter(x, y);\n    }\n\n#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^\n\ntemplate <typename FP>\nFP step(FP start, FP direction, uint64_t steps) {\n    for (uint64_t i = 0; i < steps; ++i) {\n#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)\n        start = Catch::nextafter(start, direction);\n#else\n        start = std::nextafter(start, direction);\n#endif\n    }\n    return start;\n}\n\n// Performs equivalent check of std::fabs(lhs - rhs) <= margin\n// But without the subtraction to allow for INFINITY in comparison\nbool marginComparison(double lhs, double rhs, double margin) {\n    return (lhs + margin >= rhs) && (rhs + margin >= lhs);\n}\n\ntemplate <typename FloatingPoint>\nvoid write(std::ostream& out, FloatingPoint num) {\n    out << std::scientific\n        << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)\n        << num;\n}\n\n} // end anonymous namespace\n\nnamespace Matchers {\nnamespace Floating {\n\n    enum class FloatingPointKind : uint8_t {\n        Float,\n        Double\n    };\n\n    WithinAbsMatcher::WithinAbsMatcher(double target, double margin)\n        :m_target{ target }, m_margin{ margin } {\n        CATCH_ENFORCE(margin >= 0, \"Invalid margin: \" << margin << '.'\n            << \" Margin has to be non-negative.\");\n    }\n\n    // Performs equivalent check of std::fabs(lhs - rhs) <= margin\n    // But without the subtraction to allow for INFINITY in comparison\n    bool WithinAbsMatcher::match(double const& matchee) const {\n        return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);\n    }\n\n    std::string WithinAbsMatcher::describe() const {\n        return \"is within \" + ::Catch::Detail::stringify(m_margin) + \" of \" + ::Catch::Detail::stringify(m_target);\n    }\n\n    WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)\n        :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {\n        CATCH_ENFORCE(m_type == FloatingPointKind::Double\n                   || m_ulps < (std::numeric_limits<uint32_t>::max)(),\n            \"Provided ULP is impossibly large for a float comparison.\");\n    }\n\n#if defined(__clang__)\n#pragma clang diagnostic push\n// Clang <3.5 reports on the default branch in the switch below\n#pragma clang diagnostic ignored \"-Wunreachable-code\"\n#endif\n\n    bool WithinUlpsMatcher::match(double const& matchee) const {\n        switch (m_type) {\n        case FloatingPointKind::Float:\n            return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);\n        case FloatingPointKind::Double:\n            return almostEqualUlps<double>(matchee, m_target, m_ulps);\n        default:\n            CATCH_INTERNAL_ERROR( \"Unknown FloatingPointKind value\" );\n        }\n    }\n\n#if defined(__clang__)\n#pragma clang diagnostic pop\n#endif\n\n    std::string WithinUlpsMatcher::describe() const {\n        std::stringstream ret;\n\n        ret << \"is within \" << m_ulps << \" ULPs of \";\n\n        if (m_type == FloatingPointKind::Float) {\n            write(ret, static_cast<float>(m_target));\n            ret << 'f';\n        } else {\n            write(ret, m_target);\n        }\n\n        ret << \" ([\";\n        if (m_type == FloatingPointKind::Double) {\n            write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));\n            ret << \", \";\n            write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));\n        } else {\n            // We have to cast INFINITY to float because of MinGW, see #1782\n            write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));\n            ret << \", \";\n            write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));\n        }\n        ret << \"])\";\n\n        return ret.str();\n    }\n\n    WithinRelMatcher::WithinRelMatcher(double target, double epsilon):\n        m_target(target),\n        m_epsilon(epsilon){\n        CATCH_ENFORCE(m_epsilon >= 0., \"Relative comparison with epsilon <  0 does not make sense.\");\n        CATCH_ENFORCE(m_epsilon  < 1., \"Relative comparison with epsilon >= 1 does not make sense.\");\n    }\n\n    bool WithinRelMatcher::match(double const& matchee) const {\n        const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));\n        return marginComparison(matchee, m_target,\n                                std::isinf(relMargin)? 0 : relMargin);\n    }\n\n    std::string WithinRelMatcher::describe() const {\n        Catch::ReusableStringStream sstr;\n        sstr << \"and \" << m_target << \" are within \" << m_epsilon * 100. << \"% of each other\";\n        return sstr.str();\n    }\n\n}// namespace Floating\n\nFloating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {\n    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);\n}\n\nFloating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {\n    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);\n}\n\nFloating::WithinAbsMatcher WithinAbs(double target, double margin) {\n    return Floating::WithinAbsMatcher(target, margin);\n}\n\nFloating::WithinRelMatcher WithinRel(double target, double eps) {\n    return Floating::WithinRelMatcher(target, eps);\n}\n\nFloating::WithinRelMatcher WithinRel(double target) {\n    return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);\n}\n\nFloating::WithinRelMatcher WithinRel(float target, float eps) {\n    return Floating::WithinRelMatcher(target, eps);\n}\n\nFloating::WithinRelMatcher WithinRel(float target) {\n    return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);\n}\n\n} // namespace Matchers\n} // namespace Catch\n// end catch_matchers_floating.cpp\n// start catch_matchers_generic.cpp\n\nstd::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {\n    if (desc.empty()) {\n        return \"matches undescribed predicate\";\n    } else {\n        return \"matches predicate: \\\"\" + desc + '\"';\n    }\n}\n// end catch_matchers_generic.cpp\n// start catch_matchers_string.cpp\n\n#include <regex>\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace StdString {\n\n        CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )\n        :   m_caseSensitivity( caseSensitivity ),\n            m_str( adjustString( str ) )\n        {}\n        std::string CasedString::adjustString( std::string const& str ) const {\n            return m_caseSensitivity == CaseSensitive::No\n                   ? toLower( str )\n                   : str;\n        }\n        std::string CasedString::caseSensitivitySuffix() const {\n            return m_caseSensitivity == CaseSensitive::No\n                   ? \" (case insensitive)\"\n                   : std::string();\n        }\n\n        StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )\n        : m_comparator( comparator ),\n          m_operation( operation ) {\n        }\n\n        std::string StringMatcherBase::describe() const {\n            std::string description;\n            description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +\n                                        m_comparator.caseSensitivitySuffix().size());\n            description += m_operation;\n            description += \": \\\"\";\n            description += m_comparator.m_str;\n            description += \"\\\"\";\n            description += m_comparator.caseSensitivitySuffix();\n            return description;\n        }\n\n        EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( \"equals\", comparator ) {}\n\n        bool EqualsMatcher::match( std::string const& source ) const {\n            return m_comparator.adjustString( source ) == m_comparator.m_str;\n        }\n\n        ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( \"contains\", comparator ) {}\n\n        bool ContainsMatcher::match( std::string const& source ) const {\n            return contains( m_comparator.adjustString( source ), m_comparator.m_str );\n        }\n\n        StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( \"starts with\", comparator ) {}\n\n        bool StartsWithMatcher::match( std::string const& source ) const {\n            return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );\n        }\n\n        EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( \"ends with\", comparator ) {}\n\n        bool EndsWithMatcher::match( std::string const& source ) const {\n            return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );\n        }\n\n        RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}\n\n        bool RegexMatcher::match(std::string const& matchee) const {\n            auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway\n            if (m_caseSensitivity == CaseSensitive::Choice::No) {\n                flags |= std::regex::icase;\n            }\n            auto reg = std::regex(m_regex, flags);\n            return std::regex_match(matchee, reg);\n        }\n\n        std::string RegexMatcher::describe() const {\n            return \"matches \" + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? \" case sensitively\" : \" case insensitively\");\n        }\n\n    } // namespace StdString\n\n    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n\n    StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {\n        return StdString::RegexMatcher(regex, caseSensitivity);\n    }\n\n} // namespace Matchers\n} // namespace Catch\n// end catch_matchers_string.cpp\n// start catch_message.cpp\n\n// start catch_uncaught_exceptions.h\n\nnamespace Catch {\n    bool uncaught_exceptions();\n} // end namespace Catch\n\n// end catch_uncaught_exceptions.h\n#include <cassert>\n#include <stack>\n\nnamespace Catch {\n\n    MessageInfo::MessageInfo(   StringRef const& _macroName,\n                                SourceLineInfo const& _lineInfo,\n                                ResultWas::OfType _type )\n    :   macroName( _macroName ),\n        lineInfo( _lineInfo ),\n        type( _type ),\n        sequence( ++globalCount )\n    {}\n\n    bool MessageInfo::operator==( MessageInfo const& other ) const {\n        return sequence == other.sequence;\n    }\n\n    bool MessageInfo::operator<( MessageInfo const& other ) const {\n        return sequence < other.sequence;\n    }\n\n    // This may need protecting if threading support is added\n    unsigned int MessageInfo::globalCount = 0;\n\n    ////////////////////////////////////////////////////////////////////////////\n\n    Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,\n                                           SourceLineInfo const& lineInfo,\n                                           ResultWas::OfType type )\n        :m_info(macroName, lineInfo, type) {}\n\n    ////////////////////////////////////////////////////////////////////////////\n\n    ScopedMessage::ScopedMessage( MessageBuilder const& builder )\n    : m_info( builder.m_info ), m_moved()\n    {\n        m_info.message = builder.m_stream.str();\n        getResultCapture().pushScopedMessage( m_info );\n    }\n\n    ScopedMessage::ScopedMessage( ScopedMessage&& old )\n    : m_info( old.m_info ), m_moved()\n    {\n        old.m_moved = true;\n    }\n\n    ScopedMessage::~ScopedMessage() {\n        if ( !uncaught_exceptions() && !m_moved ){\n            getResultCapture().popScopedMessage(m_info);\n        }\n    }\n\n    Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {\n        auto trimmed = [&] (size_t start, size_t end) {\n            while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {\n                ++start;\n            }\n            while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {\n                --end;\n            }\n            return names.substr(start, end - start + 1);\n        };\n        auto skipq = [&] (size_t start, char quote) {\n            for (auto i = start + 1; i < names.size() ; ++i) {\n                if (names[i] == quote)\n                    return i;\n                if (names[i] == '\\\\')\n                    ++i;\n            }\n            CATCH_INTERNAL_ERROR(\"CAPTURE parsing encountered unmatched quote\");\n        };\n\n        size_t start = 0;\n        std::stack<char> openings;\n        for (size_t pos = 0; pos < names.size(); ++pos) {\n            char c = names[pos];\n            switch (c) {\n            case '[':\n            case '{':\n            case '(':\n            // It is basically impossible to disambiguate between\n            // comparison and start of template args in this context\n//            case '<':\n                openings.push(c);\n                break;\n            case ']':\n            case '}':\n            case ')':\n//           case '>':\n                openings.pop();\n                break;\n            case '\"':\n            case '\\'':\n                pos = skipq(pos, c);\n                break;\n            case ',':\n                if (start != pos && openings.empty()) {\n                    m_messages.emplace_back(macroName, lineInfo, resultType);\n                    m_messages.back().message = static_cast<std::string>(trimmed(start, pos));\n                    m_messages.back().message += \" := \";\n                    start = pos;\n                }\n            }\n        }\n        assert(openings.empty() && \"Mismatched openings\");\n        m_messages.emplace_back(macroName, lineInfo, resultType);\n        m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));\n        m_messages.back().message += \" := \";\n    }\n    Capturer::~Capturer() {\n        if ( !uncaught_exceptions() ){\n            assert( m_captured == m_messages.size() );\n            for( size_t i = 0; i < m_captured; ++i  )\n                m_resultCapture.popScopedMessage( m_messages[i] );\n        }\n    }\n\n    void Capturer::captureValue( size_t index, std::string const& value ) {\n        assert( index < m_messages.size() );\n        m_messages[index].message += value;\n        m_resultCapture.pushScopedMessage( m_messages[index] );\n        m_captured++;\n    }\n\n} // end namespace Catch\n// end catch_message.cpp\n// start catch_output_redirect.cpp\n\n// start catch_output_redirect.h\n#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H\n#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H\n\n#include <cstdio>\n#include <iosfwd>\n#include <string>\n\nnamespace Catch {\n\n    class RedirectedStream {\n        std::ostream& m_originalStream;\n        std::ostream& m_redirectionStream;\n        std::streambuf* m_prevBuf;\n\n    public:\n        RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );\n        ~RedirectedStream();\n    };\n\n    class RedirectedStdOut {\n        ReusableStringStream m_rss;\n        RedirectedStream m_cout;\n    public:\n        RedirectedStdOut();\n        auto str() const -> std::string;\n    };\n\n    // StdErr has two constituent streams in C++, std::cerr and std::clog\n    // This means that we need to redirect 2 streams into 1 to keep proper\n    // order of writes\n    class RedirectedStdErr {\n        ReusableStringStream m_rss;\n        RedirectedStream m_cerr;\n        RedirectedStream m_clog;\n    public:\n        RedirectedStdErr();\n        auto str() const -> std::string;\n    };\n\n    class RedirectedStreams {\n    public:\n        RedirectedStreams(RedirectedStreams const&) = delete;\n        RedirectedStreams& operator=(RedirectedStreams const&) = delete;\n        RedirectedStreams(RedirectedStreams&&) = delete;\n        RedirectedStreams& operator=(RedirectedStreams&&) = delete;\n\n        RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);\n        ~RedirectedStreams();\n    private:\n        std::string& m_redirectedCout;\n        std::string& m_redirectedCerr;\n        RedirectedStdOut m_redirectedStdOut;\n        RedirectedStdErr m_redirectedStdErr;\n    };\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n\n    // Windows's implementation of std::tmpfile is terrible (it tries\n    // to create a file inside system folder, thus requiring elevated\n    // privileges for the binary), so we have to use tmpnam(_s) and\n    // create the file ourselves there.\n    class TempFile {\n    public:\n        TempFile(TempFile const&) = delete;\n        TempFile& operator=(TempFile const&) = delete;\n        TempFile(TempFile&&) = delete;\n        TempFile& operator=(TempFile&&) = delete;\n\n        TempFile();\n        ~TempFile();\n\n        std::FILE* getFile();\n        std::string getContents();\n\n    private:\n        std::FILE* m_file = nullptr;\n    #if defined(_MSC_VER)\n        char m_buffer[L_tmpnam] = { 0 };\n    #endif\n    };\n\n    class OutputRedirect {\n    public:\n        OutputRedirect(OutputRedirect const&) = delete;\n        OutputRedirect& operator=(OutputRedirect const&) = delete;\n        OutputRedirect(OutputRedirect&&) = delete;\n        OutputRedirect& operator=(OutputRedirect&&) = delete;\n\n        OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);\n        ~OutputRedirect();\n\n    private:\n        int m_originalStdout = -1;\n        int m_originalStderr = -1;\n        TempFile m_stdoutFile;\n        TempFile m_stderrFile;\n        std::string& m_stdoutDest;\n        std::string& m_stderrDest;\n    };\n\n#endif\n\n} // end namespace Catch\n\n#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H\n// end catch_output_redirect.h\n#include <cstdio>\n#include <cstring>\n#include <fstream>\n#include <sstream>\n#include <stdexcept>\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n    #if defined(_MSC_VER)\n    #include <io.h>      //_dup and _dup2\n    #define dup _dup\n    #define dup2 _dup2\n    #define fileno _fileno\n    #else\n    #include <unistd.h>  // dup and dup2\n    #endif\n#endif\n\nnamespace Catch {\n\n    RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )\n    :   m_originalStream( originalStream ),\n        m_redirectionStream( redirectionStream ),\n        m_prevBuf( m_originalStream.rdbuf() )\n    {\n        m_originalStream.rdbuf( m_redirectionStream.rdbuf() );\n    }\n\n    RedirectedStream::~RedirectedStream() {\n        m_originalStream.rdbuf( m_prevBuf );\n    }\n\n    RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}\n    auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }\n\n    RedirectedStdErr::RedirectedStdErr()\n    :   m_cerr( Catch::cerr(), m_rss.get() ),\n        m_clog( Catch::clog(), m_rss.get() )\n    {}\n    auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }\n\n    RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)\n    :   m_redirectedCout(redirectedCout),\n        m_redirectedCerr(redirectedCerr)\n    {}\n\n    RedirectedStreams::~RedirectedStreams() {\n        m_redirectedCout += m_redirectedStdOut.str();\n        m_redirectedCerr += m_redirectedStdErr.str();\n    }\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n\n#if defined(_MSC_VER)\n    TempFile::TempFile() {\n        if (tmpnam_s(m_buffer)) {\n            CATCH_RUNTIME_ERROR(\"Could not get a temp filename\");\n        }\n        if (fopen_s(&m_file, m_buffer, \"w+\")) {\n            char buffer[100];\n            if (strerror_s(buffer, errno)) {\n                CATCH_RUNTIME_ERROR(\"Could not translate errno to a string\");\n            }\n            CATCH_RUNTIME_ERROR(\"Could not open the temp file: '\" << m_buffer << \"' because: \" << buffer);\n        }\n    }\n#else\n    TempFile::TempFile() {\n        m_file = std::tmpfile();\n        if (!m_file) {\n            CATCH_RUNTIME_ERROR(\"Could not create a temp file.\");\n        }\n    }\n\n#endif\n\n    TempFile::~TempFile() {\n         // TBD: What to do about errors here?\n         std::fclose(m_file);\n         // We manually create the file on Windows only, on Linux\n         // it will be autodeleted\n#if defined(_MSC_VER)\n         std::remove(m_buffer);\n#endif\n    }\n\n    FILE* TempFile::getFile() {\n        return m_file;\n    }\n\n    std::string TempFile::getContents() {\n        std::stringstream sstr;\n        char buffer[100] = {};\n        std::rewind(m_file);\n        while (std::fgets(buffer, sizeof(buffer), m_file)) {\n            sstr << buffer;\n        }\n        return sstr.str();\n    }\n\n    OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :\n        m_originalStdout(dup(1)),\n        m_originalStderr(dup(2)),\n        m_stdoutDest(stdout_dest),\n        m_stderrDest(stderr_dest) {\n        dup2(fileno(m_stdoutFile.getFile()), 1);\n        dup2(fileno(m_stderrFile.getFile()), 2);\n    }\n\n    OutputRedirect::~OutputRedirect() {\n        Catch::cout() << std::flush;\n        fflush(stdout);\n        // Since we support overriding these streams, we flush cerr\n        // even though std::cerr is unbuffered\n        Catch::cerr() << std::flush;\n        Catch::clog() << std::flush;\n        fflush(stderr);\n\n        dup2(m_originalStdout, 1);\n        dup2(m_originalStderr, 2);\n\n        m_stdoutDest += m_stdoutFile.getContents();\n        m_stderrDest += m_stderrFile.getContents();\n    }\n\n#endif // CATCH_CONFIG_NEW_CAPTURE\n\n} // namespace Catch\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n    #if defined(_MSC_VER)\n    #undef dup\n    #undef dup2\n    #undef fileno\n    #endif\n#endif\n// end catch_output_redirect.cpp\n// start catch_polyfills.cpp\n\n#include <cmath>\n\nnamespace Catch {\n\n#if !defined(CATCH_CONFIG_POLYFILL_ISNAN)\n    bool isnan(float f) {\n        return std::isnan(f);\n    }\n    bool isnan(double d) {\n        return std::isnan(d);\n    }\n#else\n    // For now we only use this for embarcadero\n    bool isnan(float f) {\n        return std::_isnan(f);\n    }\n    bool isnan(double d) {\n        return std::_isnan(d);\n    }\n#endif\n\n} // end namespace Catch\n// end catch_polyfills.cpp\n// start catch_random_number_generator.cpp\n\nnamespace Catch {\n\nnamespace {\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4146) // we negate uint32 during the rotate\n#endif\n        // Safe rotr implementation thanks to John Regehr\n        uint32_t rotate_right(uint32_t val, uint32_t count) {\n            const uint32_t mask = 31;\n            count &= mask;\n            return (val >> count) | (val << (-count & mask));\n        }\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n}\n\n    SimplePcg32::SimplePcg32(result_type seed_) {\n        seed(seed_);\n    }\n\n    void SimplePcg32::seed(result_type seed_) {\n        m_state = 0;\n        (*this)();\n        m_state += seed_;\n        (*this)();\n    }\n\n    void SimplePcg32::discard(uint64_t skip) {\n        // We could implement this to run in O(log n) steps, but this\n        // should suffice for our use case.\n        for (uint64_t s = 0; s < skip; ++s) {\n            static_cast<void>((*this)());\n        }\n    }\n\n    SimplePcg32::result_type SimplePcg32::operator()() {\n        // prepare the output value\n        const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);\n        const auto output = rotate_right(xorshifted, m_state >> 59u);\n\n        // advance state\n        m_state = m_state * 6364136223846793005ULL + s_inc;\n\n        return output;\n    }\n\n    bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {\n        return lhs.m_state == rhs.m_state;\n    }\n\n    bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {\n        return lhs.m_state != rhs.m_state;\n    }\n}\n// end catch_random_number_generator.cpp\n// start catch_registry_hub.cpp\n\n// start catch_test_case_registry_impl.h\n\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <ios>\n\nnamespace Catch {\n\n    class TestCase;\n    struct IConfig;\n\n    std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );\n\n    bool isThrowSafe( TestCase const& testCase, IConfig const& config );\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );\n\n    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );\n\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );\n\n    class TestRegistry : public ITestCaseRegistry {\n    public:\n        virtual ~TestRegistry() = default;\n\n        virtual void registerTest( TestCase const& testCase );\n\n        std::vector<TestCase> const& getAllTests() const override;\n        std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;\n\n    private:\n        std::vector<TestCase> m_functions;\n        mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;\n        mutable std::vector<TestCase> m_sortedFunctions;\n        std::size_t m_unnamedCount = 0;\n        std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class TestInvokerAsFunction : public ITestInvoker {\n        void(*m_testAsFunction)();\n    public:\n        TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;\n\n        void invoke() const override;\n    };\n\n    std::string extractClassName( StringRef const& classOrQualifiedMethodName );\n\n    ///////////////////////////////////////////////////////////////////////////\n\n} // end namespace Catch\n\n// end catch_test_case_registry_impl.h\n// start catch_reporter_registry.h\n\n#include <map>\n\nnamespace Catch {\n\n    class ReporterRegistry : public IReporterRegistry {\n\n    public:\n\n        ~ReporterRegistry() override;\n\n        IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;\n\n        void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );\n        void registerListener( IReporterFactoryPtr const& factory );\n\n        FactoryMap const& getFactories() const override;\n        Listeners const& getListeners() const override;\n\n    private:\n        FactoryMap m_factories;\n        Listeners m_listeners;\n    };\n}\n\n// end catch_reporter_registry.h\n// start catch_tag_alias_registry.h\n\n// start catch_tag_alias.h\n\n#include <string>\n\nnamespace Catch {\n\n    struct TagAlias {\n        TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);\n\n        std::string tag;\n        SourceLineInfo lineInfo;\n    };\n\n} // end namespace Catch\n\n// end catch_tag_alias.h\n#include <map>\n\nnamespace Catch {\n\n    class TagAliasRegistry : public ITagAliasRegistry {\n    public:\n        ~TagAliasRegistry() override;\n        TagAlias const* find( std::string const& alias ) const override;\n        std::string expandAliases( std::string const& unexpandedTestSpec ) const override;\n        void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );\n\n    private:\n        std::map<std::string, TagAlias> m_registry;\n    };\n\n} // end namespace Catch\n\n// end catch_tag_alias_registry.h\n// start catch_startup_exception_registry.h\n\n#include <vector>\n#include <exception>\n\nnamespace Catch {\n\n    class StartupExceptionRegistry {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n    public:\n        void add(std::exception_ptr const& exception) noexcept;\n        std::vector<std::exception_ptr> const& getExceptions() const noexcept;\n    private:\n        std::vector<std::exception_ptr> m_exceptions;\n#endif\n    };\n\n} // end namespace Catch\n\n// end catch_startup_exception_registry.h\n// start catch_singletons.hpp\n\nnamespace Catch {\n\n    struct ISingleton {\n        virtual ~ISingleton();\n    };\n\n    void addSingleton( ISingleton* singleton );\n    void cleanupSingletons();\n\n    template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>\n    class Singleton : SingletonImplT, public ISingleton {\n\n        static auto getInternal() -> Singleton* {\n            static Singleton* s_instance = nullptr;\n            if( !s_instance ) {\n                s_instance = new Singleton;\n                addSingleton( s_instance );\n            }\n            return s_instance;\n        }\n\n    public:\n        static auto get() -> InterfaceT const& {\n            return *getInternal();\n        }\n        static auto getMutable() -> MutableInterfaceT& {\n            return *getInternal();\n        }\n    };\n\n} // namespace Catch\n\n// end catch_singletons.hpp\nnamespace Catch {\n\n    namespace {\n\n        class RegistryHub : public IRegistryHub, public IMutableRegistryHub,\n                            private NonCopyable {\n\n        public: // IRegistryHub\n            RegistryHub() = default;\n            IReporterRegistry const& getReporterRegistry() const override {\n                return m_reporterRegistry;\n            }\n            ITestCaseRegistry const& getTestCaseRegistry() const override {\n                return m_testCaseRegistry;\n            }\n            IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {\n                return m_exceptionTranslatorRegistry;\n            }\n            ITagAliasRegistry const& getTagAliasRegistry() const override {\n                return m_tagAliasRegistry;\n            }\n            StartupExceptionRegistry const& getStartupExceptionRegistry() const override {\n                return m_exceptionRegistry;\n            }\n\n        public: // IMutableRegistryHub\n            void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {\n                m_reporterRegistry.registerReporter( name, factory );\n            }\n            void registerListener( IReporterFactoryPtr const& factory ) override {\n                m_reporterRegistry.registerListener( factory );\n            }\n            void registerTest( TestCase const& testInfo ) override {\n                m_testCaseRegistry.registerTest( testInfo );\n            }\n            void registerTranslator( const IExceptionTranslator* translator ) override {\n                m_exceptionTranslatorRegistry.registerTranslator( translator );\n            }\n            void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {\n                m_tagAliasRegistry.add( alias, tag, lineInfo );\n            }\n            void registerStartupException() noexcept override {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n                m_exceptionRegistry.add(std::current_exception());\n#else\n                CATCH_INTERNAL_ERROR(\"Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!\");\n#endif\n            }\n            IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {\n                return m_enumValuesRegistry;\n            }\n\n        private:\n            TestRegistry m_testCaseRegistry;\n            ReporterRegistry m_reporterRegistry;\n            ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;\n            TagAliasRegistry m_tagAliasRegistry;\n            StartupExceptionRegistry m_exceptionRegistry;\n            Detail::EnumValuesRegistry m_enumValuesRegistry;\n        };\n    }\n\n    using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;\n\n    IRegistryHub const& getRegistryHub() {\n        return RegistryHubSingleton::get();\n    }\n    IMutableRegistryHub& getMutableRegistryHub() {\n        return RegistryHubSingleton::getMutable();\n    }\n    void cleanUp() {\n        cleanupSingletons();\n        cleanUpContext();\n    }\n    std::string translateActiveException() {\n        return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();\n    }\n\n} // end namespace Catch\n// end catch_registry_hub.cpp\n// start catch_reporter_registry.cpp\n\nnamespace Catch {\n\n    ReporterRegistry::~ReporterRegistry() = default;\n\n    IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {\n        auto it =  m_factories.find( name );\n        if( it == m_factories.end() )\n            return nullptr;\n        return it->second->create( ReporterConfig( config ) );\n    }\n\n    void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {\n        m_factories.emplace(name, factory);\n    }\n    void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {\n        m_listeners.push_back( factory );\n    }\n\n    IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {\n        return m_factories;\n    }\n    IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {\n        return m_listeners;\n    }\n\n}\n// end catch_reporter_registry.cpp\n// start catch_result_type.cpp\n\nnamespace Catch {\n\n    bool isOk( ResultWas::OfType resultType ) {\n        return ( resultType & ResultWas::FailureBit ) == 0;\n    }\n    bool isJustInfo( int flags ) {\n        return flags == ResultWas::Info;\n    }\n\n    ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {\n        return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );\n    }\n\n    bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }\n    bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }\n\n} // end namespace Catch\n// end catch_result_type.cpp\n// start catch_run_context.cpp\n\n#include <cassert>\n#include <algorithm>\n#include <sstream>\n\nnamespace Catch {\n\n    namespace Generators {\n        struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {\n            GeneratorBasePtr m_generator;\n\n            GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )\n            :   TrackerBase( nameAndLocation, ctx, parent )\n            {}\n            ~GeneratorTracker();\n\n            static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {\n                std::shared_ptr<GeneratorTracker> tracker;\n\n                ITracker& currentTracker = ctx.currentTracker();\n                // Under specific circumstances, the generator we want\n                // to acquire is also the current tracker. If this is\n                // the case, we have to avoid looking through current\n                // tracker's children, and instead return the current\n                // tracker.\n                // A case where this check is important is e.g.\n                //     for (int i = 0; i < 5; ++i) {\n                //         int n = GENERATE(1, 2);\n                //     }\n                //\n                // without it, the code above creates 5 nested generators.\n                if (currentTracker.nameAndLocation() == nameAndLocation) {\n                    auto thisTracker = currentTracker.parent().findChild(nameAndLocation);\n                    assert(thisTracker);\n                    assert(thisTracker->isGeneratorTracker());\n                    tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);\n                } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {\n                    assert( childTracker );\n                    assert( childTracker->isGeneratorTracker() );\n                    tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );\n                } else {\n                    tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );\n                    currentTracker.addChild( tracker );\n                }\n\n                if( !tracker->isComplete() ) {\n                    tracker->open();\n                }\n\n                return *tracker;\n            }\n\n            // TrackerBase interface\n            bool isGeneratorTracker() const override { return true; }\n            auto hasGenerator() const -> bool override {\n                return !!m_generator;\n            }\n            void close() override {\n                TrackerBase::close();\n                // If a generator has a child (it is followed by a section)\n                // and none of its children have started, then we must wait\n                // until later to start consuming its values.\n                // This catches cases where `GENERATE` is placed between two\n                // `SECTION`s.\n                // **The check for m_children.empty cannot be removed**.\n                // doing so would break `GENERATE` _not_ followed by `SECTION`s.\n                const bool should_wait_for_child = [&]() {\n                    // No children -> nobody to wait for\n                    if ( m_children.empty() ) {\n                        return false;\n                    }\n                    // If at least one child started executing, don't wait\n                    if ( std::find_if(\n                             m_children.begin(),\n                             m_children.end(),\n                             []( TestCaseTracking::ITrackerPtr tracker ) {\n                                 return tracker->hasStarted();\n                             } ) != m_children.end() ) {\n                        return false;\n                    }\n\n                    // No children have started. We need to check if they _can_\n                    // start, and thus we should wait for them, or they cannot\n                    // start (due to filters), and we shouldn't wait for them\n                    auto* parent = m_parent;\n                    // This is safe: there is always at least one section\n                    // tracker in a test case tracking tree\n                    while ( !parent->isSectionTracker() ) {\n                        parent = &( parent->parent() );\n                    }\n                    assert( parent &&\n                            \"Missing root (test case) level section\" );\n\n                    auto const& parentSection =\n                        static_cast<SectionTracker&>( *parent );\n                    auto const& filters = parentSection.getFilters();\n                    // No filters -> no restrictions on running sections\n                    if ( filters.empty() ) {\n                        return true;\n                    }\n\n                    for ( auto const& child : m_children ) {\n                        if ( child->isSectionTracker() &&\n                             std::find( filters.begin(),\n                                        filters.end(),\n                                        static_cast<SectionTracker&>( *child )\n                                            .trimmedName() ) !=\n                                 filters.end() ) {\n                            return true;\n                        }\n                    }\n                    return false;\n                }();\n\n                // This check is a bit tricky, because m_generator->next()\n                // has a side-effect, where it consumes generator's current\n                // value, but we do not want to invoke the side-effect if\n                // this generator is still waiting for any child to start.\n                if ( should_wait_for_child ||\n                     ( m_runState == CompletedSuccessfully &&\n                       m_generator->next() ) ) {\n                    m_children.clear();\n                    m_runState = Executing;\n                }\n            }\n\n            // IGeneratorTracker interface\n            auto getGenerator() const -> GeneratorBasePtr const& override {\n                return m_generator;\n            }\n            void setGenerator( GeneratorBasePtr&& generator ) override {\n                m_generator = std::move( generator );\n            }\n        };\n        GeneratorTracker::~GeneratorTracker() {}\n    }\n\n    RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)\n    :   m_runInfo(_config->name()),\n        m_context(getCurrentMutableContext()),\n        m_config(_config),\n        m_reporter(std::move(reporter)),\n        m_lastAssertionInfo{ StringRef(), SourceLineInfo(\"\",0), StringRef(), ResultDisposition::Normal },\n        m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )\n    {\n        m_context.setRunner(this);\n        m_context.setConfig(m_config);\n        m_context.setResultCapture(this);\n        m_reporter->testRunStarting(m_runInfo);\n    }\n\n    RunContext::~RunContext() {\n        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));\n    }\n\n    void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {\n        m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));\n    }\n\n    void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {\n        m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));\n    }\n\n    Totals RunContext::runTest(TestCase const& testCase) {\n        Totals prevTotals = m_totals;\n\n        std::string redirectedCout;\n        std::string redirectedCerr;\n\n        auto const& testInfo = testCase.getTestCaseInfo();\n\n        m_reporter->testCaseStarting(testInfo);\n\n        m_activeTestCase = &testCase;\n\n        ITracker& rootTracker = m_trackerContext.startRun();\n        assert(rootTracker.isSectionTracker());\n        static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());\n        do {\n            m_trackerContext.startCycle();\n            m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));\n            runCurrentTest(redirectedCout, redirectedCerr);\n        } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());\n\n        Totals deltaTotals = m_totals.delta(prevTotals);\n        if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {\n            deltaTotals.assertions.failed++;\n            deltaTotals.testCases.passed--;\n            deltaTotals.testCases.failed++;\n        }\n        m_totals.testCases += deltaTotals.testCases;\n        m_reporter->testCaseEnded(TestCaseStats(testInfo,\n                                  deltaTotals,\n                                  redirectedCout,\n                                  redirectedCerr,\n                                  aborting()));\n\n        m_activeTestCase = nullptr;\n        m_testCaseTracker = nullptr;\n\n        return deltaTotals;\n    }\n\n    IConfigPtr RunContext::config() const {\n        return m_config;\n    }\n\n    IStreamingReporter& RunContext::reporter() const {\n        return *m_reporter;\n    }\n\n    void RunContext::assertionEnded(AssertionResult const & result) {\n        if (result.getResultType() == ResultWas::Ok) {\n            m_totals.assertions.passed++;\n            m_lastAssertionPassed = true;\n        } else if (!result.isOk()) {\n            m_lastAssertionPassed = false;\n            if( m_activeTestCase->getTestCaseInfo().okToFail() )\n                m_totals.assertions.failedButOk++;\n            else\n                m_totals.assertions.failed++;\n        }\n        else {\n            m_lastAssertionPassed = true;\n        }\n\n        // We have no use for the return value (whether messages should be cleared), because messages were made scoped\n        // and should be let to clear themselves out.\n        static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));\n\n        if (result.getResultType() != ResultWas::Warning)\n            m_messageScopes.clear();\n\n        // Reset working state\n        resetAssertionInfo();\n        m_lastResult = result;\n    }\n    void RunContext::resetAssertionInfo() {\n        m_lastAssertionInfo.macroName = StringRef();\n        m_lastAssertionInfo.capturedExpression = \"{Unknown expression after the reported line}\"_sr;\n    }\n\n    bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {\n        ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));\n        if (!sectionTracker.isOpen())\n            return false;\n        m_activeSections.push_back(&sectionTracker);\n\n        m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;\n\n        m_reporter->sectionStarting(sectionInfo);\n\n        assertions = m_totals.assertions;\n\n        return true;\n    }\n    auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {\n        using namespace Generators;\n        GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,\n                                                              TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );\n        m_lastAssertionInfo.lineInfo = lineInfo;\n        return tracker;\n    }\n\n    bool RunContext::testForMissingAssertions(Counts& assertions) {\n        if (assertions.total() != 0)\n            return false;\n        if (!m_config->warnAboutMissingAssertions())\n            return false;\n        if (m_trackerContext.currentTracker().hasChildren())\n            return false;\n        m_totals.assertions.failed++;\n        assertions.failed++;\n        return true;\n    }\n\n    void RunContext::sectionEnded(SectionEndInfo const & endInfo) {\n        Counts assertions = m_totals.assertions - endInfo.prevAssertions;\n        bool missingAssertions = testForMissingAssertions(assertions);\n\n        if (!m_activeSections.empty()) {\n            m_activeSections.back()->close();\n            m_activeSections.pop_back();\n        }\n\n        m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));\n        m_messages.clear();\n        m_messageScopes.clear();\n    }\n\n    void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {\n        if (m_unfinishedSections.empty())\n            m_activeSections.back()->fail();\n        else\n            m_activeSections.back()->close();\n        m_activeSections.pop_back();\n\n        m_unfinishedSections.push_back(endInfo);\n    }\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    void RunContext::benchmarkPreparing(std::string const& name) {\n        m_reporter->benchmarkPreparing(name);\n    }\n    void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {\n        m_reporter->benchmarkStarting( info );\n    }\n    void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {\n        m_reporter->benchmarkEnded( stats );\n    }\n    void RunContext::benchmarkFailed(std::string const & error) {\n        m_reporter->benchmarkFailed(error);\n    }\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    void RunContext::pushScopedMessage(MessageInfo const & message) {\n        m_messages.push_back(message);\n    }\n\n    void RunContext::popScopedMessage(MessageInfo const & message) {\n        m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());\n    }\n\n    void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {\n        m_messageScopes.emplace_back( builder );\n    }\n\n    std::string RunContext::getCurrentTestName() const {\n        return m_activeTestCase\n            ? m_activeTestCase->getTestCaseInfo().name\n            : std::string();\n    }\n\n    const AssertionResult * RunContext::getLastResult() const {\n        return &(*m_lastResult);\n    }\n\n    void RunContext::exceptionEarlyReported() {\n        m_shouldReportUnexpected = false;\n    }\n\n    void RunContext::handleFatalErrorCondition( StringRef message ) {\n        // First notify reporter that bad things happened\n        m_reporter->fatalErrorEncountered(message);\n\n        // Don't rebuild the result -- the stringification itself can cause more fatal errors\n        // Instead, fake a result data.\n        AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );\n        tempResult.message = static_cast<std::string>(message);\n        AssertionResult result(m_lastAssertionInfo, tempResult);\n\n        assertionEnded(result);\n\n        handleUnfinishedSections();\n\n        // Recreate section for test case (as we will lose the one that was in scope)\n        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);\n\n        Counts assertions;\n        assertions.failed = 1;\n        SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);\n        m_reporter->sectionEnded(testCaseSectionStats);\n\n        auto const& testInfo = m_activeTestCase->getTestCaseInfo();\n\n        Totals deltaTotals;\n        deltaTotals.testCases.failed = 1;\n        deltaTotals.assertions.failed = 1;\n        m_reporter->testCaseEnded(TestCaseStats(testInfo,\n                                  deltaTotals,\n                                  std::string(),\n                                  std::string(),\n                                  false));\n        m_totals.testCases.failed++;\n        testGroupEnded(std::string(), m_totals, 1, 1);\n        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));\n    }\n\n    bool RunContext::lastAssertionPassed() {\n         return m_lastAssertionPassed;\n    }\n\n    void RunContext::assertionPassed() {\n        m_lastAssertionPassed = true;\n        ++m_totals.assertions.passed;\n        resetAssertionInfo();\n        m_messageScopes.clear();\n    }\n\n    bool RunContext::aborting() const {\n        return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());\n    }\n\n    void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {\n        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);\n        m_reporter->sectionStarting(testCaseSection);\n        Counts prevAssertions = m_totals.assertions;\n        double duration = 0;\n        m_shouldReportUnexpected = true;\n        m_lastAssertionInfo = { \"TEST_CASE\"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };\n\n        seedRng(*m_config);\n\n        Timer timer;\n        CATCH_TRY {\n            if (m_reporter->getPreferences().shouldRedirectStdOut) {\n#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)\n                RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);\n\n                timer.start();\n                invokeActiveTestCase();\n#else\n                OutputRedirect r(redirectedCout, redirectedCerr);\n                timer.start();\n                invokeActiveTestCase();\n#endif\n            } else {\n                timer.start();\n                invokeActiveTestCase();\n            }\n            duration = timer.getElapsedSeconds();\n        } CATCH_CATCH_ANON (TestFailureException&) {\n            // This just means the test was aborted due to failure\n        } CATCH_CATCH_ALL {\n            // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions\n            // are reported without translation at the point of origin.\n            if( m_shouldReportUnexpected ) {\n                AssertionReaction dummyReaction;\n                handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );\n            }\n        }\n        Counts assertions = m_totals.assertions - prevAssertions;\n        bool missingAssertions = testForMissingAssertions(assertions);\n\n        m_testCaseTracker->close();\n        handleUnfinishedSections();\n        m_messages.clear();\n        m_messageScopes.clear();\n\n        SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);\n        m_reporter->sectionEnded(testCaseSectionStats);\n    }\n\n    void RunContext::invokeActiveTestCase() {\n        FatalConditionHandlerGuard _(&m_fatalConditionhandler);\n        m_activeTestCase->invoke();\n    }\n\n    void RunContext::handleUnfinishedSections() {\n        // If sections ended prematurely due to an exception we stored their\n        // infos here so we can tear them down outside the unwind process.\n        for (auto it = m_unfinishedSections.rbegin(),\n             itEnd = m_unfinishedSections.rend();\n             it != itEnd;\n             ++it)\n            sectionEnded(*it);\n        m_unfinishedSections.clear();\n    }\n\n    void RunContext::handleExpr(\n        AssertionInfo const& info,\n        ITransientExpression const& expr,\n        AssertionReaction& reaction\n    ) {\n        m_reporter->assertionStarting( info );\n\n        bool negated = isFalseTest( info.resultDisposition );\n        bool result = expr.getResult() != negated;\n\n        if( result ) {\n            if (!m_includeSuccessfulResults) {\n                assertionPassed();\n            }\n            else {\n                reportExpr(info, ResultWas::Ok, &expr, negated);\n            }\n        }\n        else {\n            reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );\n            populateReaction( reaction );\n        }\n    }\n    void RunContext::reportExpr(\n            AssertionInfo const &info,\n            ResultWas::OfType resultType,\n            ITransientExpression const *expr,\n            bool negated ) {\n\n        m_lastAssertionInfo = info;\n        AssertionResultData data( resultType, LazyExpression( negated ) );\n\n        AssertionResult assertionResult{ info, data };\n        assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;\n\n        assertionEnded( assertionResult );\n    }\n\n    void RunContext::handleMessage(\n            AssertionInfo const& info,\n            ResultWas::OfType resultType,\n            StringRef const& message,\n            AssertionReaction& reaction\n    ) {\n        m_reporter->assertionStarting( info );\n\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( resultType, LazyExpression( false ) );\n        data.message = static_cast<std::string>(message);\n        AssertionResult assertionResult{ m_lastAssertionInfo, data };\n        assertionEnded( assertionResult );\n        if( !assertionResult.isOk() )\n            populateReaction( reaction );\n    }\n    void RunContext::handleUnexpectedExceptionNotThrown(\n            AssertionInfo const& info,\n            AssertionReaction& reaction\n    ) {\n        handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);\n    }\n\n    void RunContext::handleUnexpectedInflightException(\n            AssertionInfo const& info,\n            std::string const& message,\n            AssertionReaction& reaction\n    ) {\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );\n        data.message = message;\n        AssertionResult assertionResult{ info, data };\n        assertionEnded( assertionResult );\n        populateReaction( reaction );\n    }\n\n    void RunContext::populateReaction( AssertionReaction& reaction ) {\n        reaction.shouldDebugBreak = m_config->shouldDebugBreak();\n        reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);\n    }\n\n    void RunContext::handleIncomplete(\n            AssertionInfo const& info\n    ) {\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );\n        data.message = \"Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE\";\n        AssertionResult assertionResult{ info, data };\n        assertionEnded( assertionResult );\n    }\n    void RunContext::handleNonExpr(\n            AssertionInfo const &info,\n            ResultWas::OfType resultType,\n            AssertionReaction &reaction\n    ) {\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( resultType, LazyExpression( false ) );\n        AssertionResult assertionResult{ info, data };\n        assertionEnded( assertionResult );\n\n        if( !assertionResult.isOk() )\n            populateReaction( reaction );\n    }\n\n    IResultCapture& getResultCapture() {\n        if (auto* capture = getCurrentContext().getResultCapture())\n            return *capture;\n        else\n            CATCH_INTERNAL_ERROR(\"No result capture instance\");\n    }\n\n    void seedRng(IConfig const& config) {\n        if (config.rngSeed() != 0) {\n            std::srand(config.rngSeed());\n            rng().seed(config.rngSeed());\n        }\n    }\n\n    unsigned int rngSeed() {\n        return getCurrentContext().getConfig()->rngSeed();\n    }\n\n}\n// end catch_run_context.cpp\n// start catch_section.cpp\n\nnamespace Catch {\n\n    Section::Section( SectionInfo const& info )\n    :   m_info( info ),\n        m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )\n    {\n        m_timer.start();\n    }\n\n    Section::~Section() {\n        if( m_sectionIncluded ) {\n            SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };\n            if( uncaught_exceptions() )\n                getResultCapture().sectionEndedEarly( endInfo );\n            else\n                getResultCapture().sectionEnded( endInfo );\n        }\n    }\n\n    // This indicates whether the section should be executed or not\n    Section::operator bool() const {\n        return m_sectionIncluded;\n    }\n\n} // end namespace Catch\n// end catch_section.cpp\n// start catch_section_info.cpp\n\nnamespace Catch {\n\n    SectionInfo::SectionInfo\n        (   SourceLineInfo const& _lineInfo,\n            std::string const& _name )\n    :   name( _name ),\n        lineInfo( _lineInfo )\n    {}\n\n} // end namespace Catch\n// end catch_section_info.cpp\n// start catch_session.cpp\n\n// start catch_session.h\n\n#include <memory>\n\nnamespace Catch {\n\n    class Session : NonCopyable {\n    public:\n\n        Session();\n        ~Session() override;\n\n        void showHelp() const;\n        void libIdentify();\n\n        int applyCommandLine( int argc, char const * const * argv );\n    #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)\n        int applyCommandLine( int argc, wchar_t const * const * argv );\n    #endif\n\n        void useConfigData( ConfigData const& configData );\n\n        template<typename CharT>\n        int run(int argc, CharT const * const argv[]) {\n            if (m_startupExceptions)\n                return 1;\n            int returnCode = applyCommandLine(argc, argv);\n            if (returnCode == 0)\n                returnCode = run();\n            return returnCode;\n        }\n\n        int run();\n\n        clara::Parser const& cli() const;\n        void cli( clara::Parser const& newParser );\n        ConfigData& configData();\n        Config& config();\n    private:\n        int runInternal();\n\n        clara::Parser m_cli;\n        ConfigData m_configData;\n        std::shared_ptr<Config> m_config;\n        bool m_startupExceptions = false;\n    };\n\n} // end namespace Catch\n\n// end catch_session.h\n// start catch_version.h\n\n#include <iosfwd>\n\nnamespace Catch {\n\n    // Versioning information\n    struct Version {\n        Version( Version const& ) = delete;\n        Version& operator=( Version const& ) = delete;\n        Version(    unsigned int _majorVersion,\n                    unsigned int _minorVersion,\n                    unsigned int _patchNumber,\n                    char const * const _branchName,\n                    unsigned int _buildNumber );\n\n        unsigned int const majorVersion;\n        unsigned int const minorVersion;\n        unsigned int const patchNumber;\n\n        // buildNumber is only used if branchName is not null\n        char const * const branchName;\n        unsigned int const buildNumber;\n\n        friend std::ostream& operator << ( std::ostream& os, Version const& version );\n    };\n\n    Version const& libraryVersion();\n}\n\n// end catch_version.h\n#include <cstdlib>\n#include <iomanip>\n#include <set>\n#include <iterator>\n\nnamespace Catch {\n\n    namespace {\n        const int MaxExitCode = 255;\n\n        IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {\n            auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);\n            CATCH_ENFORCE(reporter, \"No reporter registered with name: '\" << reporterName << \"'\");\n\n            return reporter;\n        }\n\n        IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {\n            if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {\n                return createReporter(config->getReporterName(), config);\n            }\n\n            // On older platforms, returning std::unique_ptr<ListeningReporter>\n            // when the return type is std::unique_ptr<IStreamingReporter>\n            // doesn't compile without a std::move call. However, this causes\n            // a warning on newer platforms. Thus, we have to work around\n            // it a bit and downcast the pointer manually.\n            auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);\n            auto& multi = static_cast<ListeningReporter&>(*ret);\n            auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();\n            for (auto const& listener : listeners) {\n                multi.addListener(listener->create(Catch::ReporterConfig(config)));\n            }\n            multi.addReporter(createReporter(config->getReporterName(), config));\n            return ret;\n        }\n\n        class TestGroup {\n        public:\n            explicit TestGroup(std::shared_ptr<Config> const& config)\n            : m_config{config}\n            , m_context{config, makeReporter(config)}\n            {\n                auto const& allTestCases = getAllTestCasesSorted(*m_config);\n                m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);\n                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();\n\n                if (m_matches.empty() && invalidArgs.empty()) {\n                    for (auto const& test : allTestCases)\n                        if (!test.isHidden())\n                            m_tests.emplace(&test);\n                } else {\n                    for (auto const& match : m_matches)\n                        m_tests.insert(match.tests.begin(), match.tests.end());\n                }\n            }\n\n            Totals execute() {\n                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();\n                Totals totals;\n                m_context.testGroupStarting(m_config->name(), 1, 1);\n                for (auto const& testCase : m_tests) {\n                    if (!m_context.aborting())\n                        totals += m_context.runTest(*testCase);\n                    else\n                        m_context.reporter().skipTest(*testCase);\n                }\n\n                for (auto const& match : m_matches) {\n                    if (match.tests.empty()) {\n                        m_context.reporter().noMatchingTestCases(match.name);\n                        totals.error = -1;\n                    }\n                }\n\n                if (!invalidArgs.empty()) {\n                    for (auto const& invalidArg: invalidArgs)\n                         m_context.reporter().reportInvalidArguments(invalidArg);\n                }\n\n                m_context.testGroupEnded(m_config->name(), totals, 1, 1);\n                return totals;\n            }\n\n        private:\n            using Tests = std::set<TestCase const*>;\n\n            std::shared_ptr<Config> m_config;\n            RunContext m_context;\n            Tests m_tests;\n            TestSpec::Matches m_matches;\n        };\n\n        void applyFilenamesAsTags(Catch::IConfig const& config) {\n            auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));\n            for (auto& testCase : tests) {\n                auto tags = testCase.tags;\n\n                std::string filename = testCase.lineInfo.file;\n                auto lastSlash = filename.find_last_of(\"\\\\/\");\n                if (lastSlash != std::string::npos) {\n                    filename.erase(0, lastSlash);\n                    filename[0] = '#';\n                }\n                else\n                {\n                    filename.insert(0, \"#\");\n                }\n\n                auto lastDot = filename.find_last_of('.');\n                if (lastDot != std::string::npos) {\n                    filename.erase(lastDot);\n                }\n\n                tags.push_back(std::move(filename));\n                setTags(testCase, tags);\n            }\n        }\n\n    } // anon namespace\n\n    Session::Session() {\n        static bool alreadyInstantiated = false;\n        if( alreadyInstantiated ) {\n            CATCH_TRY { CATCH_INTERNAL_ERROR( \"Only one instance of Catch::Session can ever be used\" ); }\n            CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }\n        }\n\n        // There cannot be exceptions at startup in no-exception mode.\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n        const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();\n        if ( !exceptions.empty() ) {\n            config();\n            getCurrentMutableContext().setConfig(m_config);\n\n            m_startupExceptions = true;\n            Colour colourGuard( Colour::Red );\n            Catch::cerr() << \"Errors occurred during startup!\" << '\\n';\n            // iterate over all exceptions and notify user\n            for ( const auto& ex_ptr : exceptions ) {\n                try {\n                    std::rethrow_exception(ex_ptr);\n                } catch ( std::exception const& ex ) {\n                    Catch::cerr() << Column( ex.what() ).indent(2) << '\\n';\n                }\n            }\n        }\n#endif\n\n        alreadyInstantiated = true;\n        m_cli = makeCommandLineParser( m_configData );\n    }\n    Session::~Session() {\n        Catch::cleanUp();\n    }\n\n    void Session::showHelp() const {\n        Catch::cout()\n                << \"\\nCatch v\" << libraryVersion() << \"\\n\"\n                << m_cli << std::endl\n                << \"For more detailed usage please see the project docs\\n\" << std::endl;\n    }\n    void Session::libIdentify() {\n        Catch::cout()\n                << std::left << std::setw(16) << \"description: \" << \"A Catch2 test executable\\n\"\n                << std::left << std::setw(16) << \"category: \" << \"testframework\\n\"\n                << std::left << std::setw(16) << \"framework: \" << \"Catch Test\\n\"\n                << std::left << std::setw(16) << \"version: \" << libraryVersion() << std::endl;\n    }\n\n    int Session::applyCommandLine( int argc, char const * const * argv ) {\n        if( m_startupExceptions )\n            return 1;\n\n        auto result = m_cli.parse( clara::Args( argc, argv ) );\n        if( !result ) {\n            config();\n            getCurrentMutableContext().setConfig(m_config);\n            Catch::cerr()\n                << Colour( Colour::Red )\n                << \"\\nError(s) in input:\\n\"\n                << Column( result.errorMessage() ).indent( 2 )\n                << \"\\n\\n\";\n            Catch::cerr() << \"Run with -? for usage\\n\" << std::endl;\n            return MaxExitCode;\n        }\n\n        if( m_configData.showHelp )\n            showHelp();\n        if( m_configData.libIdentify )\n            libIdentify();\n        m_config.reset();\n        return 0;\n    }\n\n#if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)\n    int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {\n\n        char **utf8Argv = new char *[ argc ];\n\n        for ( int i = 0; i < argc; ++i ) {\n            int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );\n\n            utf8Argv[ i ] = new char[ bufSize ];\n\n            WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );\n        }\n\n        int returnCode = applyCommandLine( argc, utf8Argv );\n\n        for ( int i = 0; i < argc; ++i )\n            delete [] utf8Argv[ i ];\n\n        delete [] utf8Argv;\n\n        return returnCode;\n    }\n#endif\n\n    void Session::useConfigData( ConfigData const& configData ) {\n        m_configData = configData;\n        m_config.reset();\n    }\n\n    int Session::run() {\n        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {\n            Catch::cout() << \"...waiting for enter/ return before starting\" << std::endl;\n            static_cast<void>(std::getchar());\n        }\n        int exitCode = runInternal();\n        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {\n            Catch::cout() << \"...waiting for enter/ return before exiting, with code: \" << exitCode << std::endl;\n            static_cast<void>(std::getchar());\n        }\n        return exitCode;\n    }\n\n    clara::Parser const& Session::cli() const {\n        return m_cli;\n    }\n    void Session::cli( clara::Parser const& newParser ) {\n        m_cli = newParser;\n    }\n    ConfigData& Session::configData() {\n        return m_configData;\n    }\n    Config& Session::config() {\n        if( !m_config )\n            m_config = std::make_shared<Config>( m_configData );\n        return *m_config;\n    }\n\n    int Session::runInternal() {\n        if( m_startupExceptions )\n            return 1;\n\n        if (m_configData.showHelp || m_configData.libIdentify) {\n            return 0;\n        }\n\n        CATCH_TRY {\n            config(); // Force config to be constructed\n\n            seedRng( *m_config );\n\n            if( m_configData.filenamesAsTags )\n                applyFilenamesAsTags( *m_config );\n\n            // Handle list request\n            if( Option<std::size_t> listed = list( m_config ) )\n                return (std::min) (MaxExitCode, static_cast<int>(*listed));\n\n            TestGroup tests { m_config };\n            auto const totals = tests.execute();\n\n            if( m_config->warnAboutNoTests() && totals.error == -1 )\n                return 2;\n\n            // Note that on unices only the lower 8 bits are usually used, clamping\n            // the return value to 255 prevents false negative when some multiple\n            // of 256 tests has failed\n            return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));\n        }\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n        catch( std::exception& ex ) {\n            Catch::cerr() << ex.what() << std::endl;\n            return MaxExitCode;\n        }\n#endif\n    }\n\n} // end namespace Catch\n// end catch_session.cpp\n// start catch_singletons.cpp\n\n#include <vector>\n\nnamespace Catch {\n\n    namespace {\n        static auto getSingletons() -> std::vector<ISingleton*>*& {\n            static std::vector<ISingleton*>* g_singletons = nullptr;\n            if( !g_singletons )\n                g_singletons = new std::vector<ISingleton*>();\n            return g_singletons;\n        }\n    }\n\n    ISingleton::~ISingleton() {}\n\n    void addSingleton(ISingleton* singleton ) {\n        getSingletons()->push_back( singleton );\n    }\n    void cleanupSingletons() {\n        auto& singletons = getSingletons();\n        for( auto singleton : *singletons )\n            delete singleton;\n        delete singletons;\n        singletons = nullptr;\n    }\n\n} // namespace Catch\n// end catch_singletons.cpp\n// start catch_startup_exception_registry.cpp\n\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\nnamespace Catch {\nvoid StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {\n        CATCH_TRY {\n            m_exceptions.push_back(exception);\n        } CATCH_CATCH_ALL {\n            // If we run out of memory during start-up there's really not a lot more we can do about it\n            std::terminate();\n        }\n    }\n\n    std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {\n        return m_exceptions;\n    }\n\n} // end namespace Catch\n#endif\n// end catch_startup_exception_registry.cpp\n// start catch_stream.cpp\n\n#include <cstdio>\n#include <iostream>\n#include <fstream>\n#include <sstream>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    Catch::IStream::~IStream() = default;\n\n    namespace Detail { namespace {\n        template<typename WriterF, std::size_t bufferSize=256>\n        class StreamBufImpl : public std::streambuf {\n            char data[bufferSize];\n            WriterF m_writer;\n\n        public:\n            StreamBufImpl() {\n                setp( data, data + sizeof(data) );\n            }\n\n            ~StreamBufImpl() noexcept {\n                StreamBufImpl::sync();\n            }\n\n        private:\n            int overflow( int c ) override {\n                sync();\n\n                if( c != EOF ) {\n                    if( pbase() == epptr() )\n                        m_writer( std::string( 1, static_cast<char>( c ) ) );\n                    else\n                        sputc( static_cast<char>( c ) );\n                }\n                return 0;\n            }\n\n            int sync() override {\n                if( pbase() != pptr() ) {\n                    m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );\n                    setp( pbase(), epptr() );\n                }\n                return 0;\n            }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        struct OutputDebugWriter {\n\n            void operator()( std::string const&str ) {\n                writeToDebugConsole( str );\n            }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        class FileStream : public IStream {\n            mutable std::ofstream m_ofs;\n        public:\n            FileStream( StringRef filename ) {\n                m_ofs.open( filename.c_str() );\n                CATCH_ENFORCE( !m_ofs.fail(), \"Unable to open file: '\" << filename << \"'\" );\n            }\n            ~FileStream() override = default;\n        public: // IStream\n            std::ostream& stream() const override {\n                return m_ofs;\n            }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        class CoutStream : public IStream {\n            mutable std::ostream m_os;\n        public:\n            // Store the streambuf from cout up-front because\n            // cout may get redirected when running tests\n            CoutStream() : m_os( Catch::cout().rdbuf() ) {}\n            ~CoutStream() override = default;\n\n        public: // IStream\n            std::ostream& stream() const override { return m_os; }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        class DebugOutStream : public IStream {\n            std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;\n            mutable std::ostream m_os;\n        public:\n            DebugOutStream()\n            :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),\n                m_os( m_streamBuf.get() )\n            {}\n\n            ~DebugOutStream() override = default;\n\n        public: // IStream\n            std::ostream& stream() const override { return m_os; }\n        };\n\n    }} // namespace anon::detail\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    auto makeStream( StringRef const &filename ) -> IStream const* {\n        if( filename.empty() )\n            return new Detail::CoutStream();\n        else if( filename[0] == '%' ) {\n            if( filename == \"%debug\" )\n                return new Detail::DebugOutStream();\n            else\n                CATCH_ERROR( \"Unrecognised stream: '\" << filename << \"'\" );\n        }\n        else\n            return new Detail::FileStream( filename );\n    }\n\n    // This class encapsulates the idea of a pool of ostringstreams that can be reused.\n    struct StringStreams {\n        std::vector<std::unique_ptr<std::ostringstream>> m_streams;\n        std::vector<std::size_t> m_unused;\n        std::ostringstream m_referenceStream; // Used for copy state/ flags from\n\n        auto add() -> std::size_t {\n            if( m_unused.empty() ) {\n                m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );\n                return m_streams.size()-1;\n            }\n            else {\n                auto index = m_unused.back();\n                m_unused.pop_back();\n                return index;\n            }\n        }\n\n        void release( std::size_t index ) {\n            m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state\n            m_unused.push_back(index);\n        }\n    };\n\n    ReusableStringStream::ReusableStringStream()\n    :   m_index( Singleton<StringStreams>::getMutable().add() ),\n        m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )\n    {}\n\n    ReusableStringStream::~ReusableStringStream() {\n        static_cast<std::ostringstream*>( m_oss )->str(\"\");\n        m_oss->clear();\n        Singleton<StringStreams>::getMutable().release( m_index );\n    }\n\n    auto ReusableStringStream::str() const -> std::string {\n        return static_cast<std::ostringstream*>( m_oss )->str();\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n\n#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions\n    std::ostream& cout() { return std::cout; }\n    std::ostream& cerr() { return std::cerr; }\n    std::ostream& clog() { return std::clog; }\n#endif\n}\n// end catch_stream.cpp\n// start catch_string_manip.cpp\n\n#include <algorithm>\n#include <ostream>\n#include <cstring>\n#include <cctype>\n#include <vector>\n\nnamespace Catch {\n\n    namespace {\n        char toLowerCh(char c) {\n            return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );\n        }\n    }\n\n    bool startsWith( std::string const& s, std::string const& prefix ) {\n        return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());\n    }\n    bool startsWith( std::string const& s, char prefix ) {\n        return !s.empty() && s[0] == prefix;\n    }\n    bool endsWith( std::string const& s, std::string const& suffix ) {\n        return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());\n    }\n    bool endsWith( std::string const& s, char suffix ) {\n        return !s.empty() && s[s.size()-1] == suffix;\n    }\n    bool contains( std::string const& s, std::string const& infix ) {\n        return s.find( infix ) != std::string::npos;\n    }\n    void toLowerInPlace( std::string& s ) {\n        std::transform( s.begin(), s.end(), s.begin(), toLowerCh );\n    }\n    std::string toLower( std::string const& s ) {\n        std::string lc = s;\n        toLowerInPlace( lc );\n        return lc;\n    }\n    std::string trim( std::string const& str ) {\n        static char const* whitespaceChars = \"\\n\\r\\t \";\n        std::string::size_type start = str.find_first_not_of( whitespaceChars );\n        std::string::size_type end = str.find_last_not_of( whitespaceChars );\n\n        return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();\n    }\n\n    StringRef trim(StringRef ref) {\n        const auto is_ws = [](char c) {\n            return c == ' ' || c == '\\t' || c == '\\n' || c == '\\r';\n        };\n        size_t real_begin = 0;\n        while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }\n        size_t real_end = ref.size();\n        while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }\n\n        return ref.substr(real_begin, real_end - real_begin);\n    }\n\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {\n        bool replaced = false;\n        std::size_t i = str.find( replaceThis );\n        while( i != std::string::npos ) {\n            replaced = true;\n            str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );\n            if( i < str.size()-withThis.size() )\n                i = str.find( replaceThis, i+withThis.size() );\n            else\n                i = std::string::npos;\n        }\n        return replaced;\n    }\n\n    std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {\n        std::vector<StringRef> subStrings;\n        std::size_t start = 0;\n        for(std::size_t pos = 0; pos < str.size(); ++pos ) {\n            if( str[pos] == delimiter ) {\n                if( pos - start > 1 )\n                    subStrings.push_back( str.substr( start, pos-start ) );\n                start = pos+1;\n            }\n        }\n        if( start < str.size() )\n            subStrings.push_back( str.substr( start, str.size()-start ) );\n        return subStrings;\n    }\n\n    pluralise::pluralise( std::size_t count, std::string const& label )\n    :   m_count( count ),\n        m_label( label )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {\n        os << pluraliser.m_count << ' ' << pluraliser.m_label;\n        if( pluraliser.m_count != 1 )\n            os << 's';\n        return os;\n    }\n\n}\n// end catch_string_manip.cpp\n// start catch_stringref.cpp\n\n#include <algorithm>\n#include <ostream>\n#include <cstring>\n#include <cstdint>\n\nnamespace Catch {\n    StringRef::StringRef( char const* rawChars ) noexcept\n    : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )\n    {}\n\n    auto StringRef::c_str() const -> char const* {\n        CATCH_ENFORCE(isNullTerminated(), \"Called StringRef::c_str() on a non-null-terminated instance\");\n        return m_start;\n    }\n    auto StringRef::data() const noexcept -> char const* {\n        return m_start;\n    }\n\n    auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {\n        if (start < m_size) {\n            return StringRef(m_start + start, (std::min)(m_size - start, size));\n        } else {\n            return StringRef();\n        }\n    }\n    auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {\n        return m_size == other.m_size\n            && (std::memcmp( m_start, other.m_start, m_size ) == 0);\n    }\n\n    auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {\n        return os.write(str.data(), str.size());\n    }\n\n    auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {\n        lhs.append(rhs.data(), rhs.size());\n        return lhs;\n    }\n\n} // namespace Catch\n// end catch_stringref.cpp\n// start catch_tag_alias.cpp\n\nnamespace Catch {\n    TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}\n}\n// end catch_tag_alias.cpp\n// start catch_tag_alias_autoregistrar.cpp\n\nnamespace Catch {\n\n    RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {\n        CATCH_TRY {\n            getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);\n        } CATCH_CATCH_ALL {\n            // Do not throw when constructing global objects, instead register the exception to be processed later\n            getMutableRegistryHub().registerStartupException();\n        }\n    }\n\n}\n// end catch_tag_alias_autoregistrar.cpp\n// start catch_tag_alias_registry.cpp\n\n#include <sstream>\n\nnamespace Catch {\n\n    TagAliasRegistry::~TagAliasRegistry() {}\n\n    TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {\n        auto it = m_registry.find( alias );\n        if( it != m_registry.end() )\n            return &(it->second);\n        else\n            return nullptr;\n    }\n\n    std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {\n        std::string expandedTestSpec = unexpandedTestSpec;\n        for( auto const& registryKvp : m_registry ) {\n            std::size_t pos = expandedTestSpec.find( registryKvp.first );\n            if( pos != std::string::npos ) {\n                expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +\n                                    registryKvp.second.tag +\n                                    expandedTestSpec.substr( pos + registryKvp.first.size() );\n            }\n        }\n        return expandedTestSpec;\n    }\n\n    void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {\n        CATCH_ENFORCE( startsWith(alias, \"[@\") && endsWith(alias, ']'),\n                      \"error: tag alias, '\" << alias << \"' is not of the form [@alias name].\\n\" << lineInfo );\n\n        CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,\n                      \"error: tag alias, '\" << alias << \"' already registered.\\n\"\n                      << \"\\tFirst seen at: \" << find(alias)->lineInfo << \"\\n\"\n                      << \"\\tRedefined at: \" << lineInfo );\n    }\n\n    ITagAliasRegistry::~ITagAliasRegistry() {}\n\n    ITagAliasRegistry const& ITagAliasRegistry::get() {\n        return getRegistryHub().getTagAliasRegistry();\n    }\n\n} // end namespace Catch\n// end catch_tag_alias_registry.cpp\n// start catch_test_case_info.cpp\n\n#include <cctype>\n#include <exception>\n#include <algorithm>\n#include <sstream>\n\nnamespace Catch {\n\n    namespace {\n        TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {\n            if( startsWith( tag, '.' ) ||\n                tag == \"!hide\" )\n                return TestCaseInfo::IsHidden;\n            else if( tag == \"!throws\" )\n                return TestCaseInfo::Throws;\n            else if( tag == \"!shouldfail\" )\n                return TestCaseInfo::ShouldFail;\n            else if( tag == \"!mayfail\" )\n                return TestCaseInfo::MayFail;\n            else if( tag == \"!nonportable\" )\n                return TestCaseInfo::NonPortable;\n            else if( tag == \"!benchmark\" )\n                return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );\n            else\n                return TestCaseInfo::None;\n        }\n        bool isReservedTag( std::string const& tag ) {\n            return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );\n        }\n        void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {\n            CATCH_ENFORCE( !isReservedTag(tag),\n                          \"Tag name: [\" << tag << \"] is not allowed.\\n\"\n                          << \"Tag names starting with non alphanumeric characters are reserved\\n\"\n                          << _lineInfo );\n        }\n    }\n\n    TestCase makeTestCase(  ITestInvoker* _testCase,\n                            std::string const& _className,\n                            NameAndTags const& nameAndTags,\n                            SourceLineInfo const& _lineInfo )\n    {\n        bool isHidden = false;\n\n        // Parse out tags\n        std::vector<std::string> tags;\n        std::string desc, tag;\n        bool inTag = false;\n        for (char c : nameAndTags.tags) {\n            if( !inTag ) {\n                if( c == '[' )\n                    inTag = true;\n                else\n                    desc += c;\n            }\n            else {\n                if( c == ']' ) {\n                    TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );\n                    if( ( prop & TestCaseInfo::IsHidden ) != 0 )\n                        isHidden = true;\n                    else if( prop == TestCaseInfo::None )\n                        enforceNotReservedTag( tag, _lineInfo );\n\n                    // Merged hide tags like `[.approvals]` should be added as\n                    // `[.][approvals]`. The `[.]` is added at later point, so\n                    // we only strip the prefix\n                    if (startsWith(tag, '.') && tag.size() > 1) {\n                        tag.erase(0, 1);\n                    }\n                    tags.push_back( tag );\n                    tag.clear();\n                    inTag = false;\n                }\n                else\n                    tag += c;\n            }\n        }\n        if( isHidden ) {\n            // Add all \"hidden\" tags to make them behave identically\n            tags.insert( tags.end(), { \".\", \"!hide\" } );\n        }\n\n        TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );\n        return TestCase( _testCase, std::move(info) );\n    }\n\n    void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {\n        std::sort(begin(tags), end(tags));\n        tags.erase(std::unique(begin(tags), end(tags)), end(tags));\n        testCaseInfo.lcaseTags.clear();\n\n        for( auto const& tag : tags ) {\n            std::string lcaseTag = toLower( tag );\n            testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );\n            testCaseInfo.lcaseTags.push_back( lcaseTag );\n        }\n        testCaseInfo.tags = std::move(tags);\n    }\n\n    TestCaseInfo::TestCaseInfo( std::string const& _name,\n                                std::string const& _className,\n                                std::string const& _description,\n                                std::vector<std::string> const& _tags,\n                                SourceLineInfo const& _lineInfo )\n    :   name( _name ),\n        className( _className ),\n        description( _description ),\n        lineInfo( _lineInfo ),\n        properties( None )\n    {\n        setTags( *this, _tags );\n    }\n\n    bool TestCaseInfo::isHidden() const {\n        return ( properties & IsHidden ) != 0;\n    }\n    bool TestCaseInfo::throws() const {\n        return ( properties & Throws ) != 0;\n    }\n    bool TestCaseInfo::okToFail() const {\n        return ( properties & (ShouldFail | MayFail ) ) != 0;\n    }\n    bool TestCaseInfo::expectedToFail() const {\n        return ( properties & (ShouldFail ) ) != 0;\n    }\n\n    std::string TestCaseInfo::tagsAsString() const {\n        std::string ret;\n        // '[' and ']' per tag\n        std::size_t full_size = 2 * tags.size();\n        for (const auto& tag : tags) {\n            full_size += tag.size();\n        }\n        ret.reserve(full_size);\n        for (const auto& tag : tags) {\n            ret.push_back('[');\n            ret.append(tag);\n            ret.push_back(']');\n        }\n\n        return ret;\n    }\n\n    TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}\n\n    TestCase TestCase::withName( std::string const& _newName ) const {\n        TestCase other( *this );\n        other.name = _newName;\n        return other;\n    }\n\n    void TestCase::invoke() const {\n        test->invoke();\n    }\n\n    bool TestCase::operator == ( TestCase const& other ) const {\n        return  test.get() == other.test.get() &&\n                name == other.name &&\n                className == other.className;\n    }\n\n    bool TestCase::operator < ( TestCase const& other ) const {\n        return name < other.name;\n    }\n\n    TestCaseInfo const& TestCase::getTestCaseInfo() const\n    {\n        return *this;\n    }\n\n} // end namespace Catch\n// end catch_test_case_info.cpp\n// start catch_test_case_registry_impl.cpp\n\n#include <algorithm>\n#include <sstream>\n\nnamespace Catch {\n\n    namespace {\n        struct TestHasher {\n            using hash_t = uint64_t;\n\n            explicit TestHasher( hash_t hashSuffix ):\n                m_hashSuffix{ hashSuffix } {}\n\n            uint32_t operator()( TestCase const& t ) const {\n                // FNV-1a hash with multiplication fold.\n                const hash_t prime = 1099511628211u;\n                hash_t hash = 14695981039346656037u;\n                for ( const char c : t.name ) {\n                    hash ^= c;\n                    hash *= prime;\n                }\n                hash ^= m_hashSuffix;\n                hash *= prime;\n                const uint32_t low{ static_cast<uint32_t>( hash ) };\n                const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) };\n                return low * high;\n            }\n\n        private:\n            hash_t m_hashSuffix;\n        };\n    } // end unnamed namespace\n\n    std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {\n        switch( config.runOrder() ) {\n            case RunTests::InDeclarationOrder:\n                // already in declaration order\n                break;\n\n            case RunTests::InLexicographicalOrder: {\n                std::vector<TestCase> sorted = unsortedTestCases;\n                std::sort( sorted.begin(), sorted.end() );\n                return sorted;\n            }\n\n            case RunTests::InRandomOrder: {\n                seedRng( config );\n                TestHasher h{ config.rngSeed() };\n\n                using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;\n                std::vector<hashedTest> indexed_tests;\n                indexed_tests.reserve( unsortedTestCases.size() );\n\n                for (auto const& testCase : unsortedTestCases) {\n                    indexed_tests.emplace_back(h(testCase), &testCase);\n                }\n\n                std::sort(indexed_tests.begin(), indexed_tests.end(),\n                          [](hashedTest const& lhs, hashedTest const& rhs) {\n                          if (lhs.first == rhs.first) {\n                              return lhs.second->name < rhs.second->name;\n                          }\n                          return lhs.first < rhs.first;\n                });\n\n                std::vector<TestCase> sorted;\n                sorted.reserve( indexed_tests.size() );\n\n                for (auto const& hashed : indexed_tests) {\n                    sorted.emplace_back(*hashed.second);\n                }\n\n                return sorted;\n            }\n        }\n        return unsortedTestCases;\n    }\n\n    bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {\n        return !testCase.throws() || config.allowThrows();\n    }\n\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {\n        return testSpec.matches( testCase ) && isThrowSafe( testCase, config );\n    }\n\n    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {\n        std::set<TestCase> seenFunctions;\n        for( auto const& function : functions ) {\n            auto prev = seenFunctions.insert( function );\n            CATCH_ENFORCE( prev.second,\n                    \"error: TEST_CASE( \\\"\" << function.name << \"\\\" ) already defined.\\n\"\n                    << \"\\tFirst seen at \" << prev.first->getTestCaseInfo().lineInfo << \"\\n\"\n                    << \"\\tRedefined at \" << function.getTestCaseInfo().lineInfo );\n        }\n    }\n\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {\n        std::vector<TestCase> filtered;\n        filtered.reserve( testCases.size() );\n        for (auto const& testCase : testCases) {\n            if ((!testSpec.hasFilters() && !testCase.isHidden()) ||\n                (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {\n                filtered.push_back(testCase);\n            }\n        }\n        return filtered;\n    }\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {\n        return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );\n    }\n\n    void TestRegistry::registerTest( TestCase const& testCase ) {\n        std::string name = testCase.getTestCaseInfo().name;\n        if( name.empty() ) {\n            ReusableStringStream rss;\n            rss << \"Anonymous test case \" << ++m_unnamedCount;\n            return registerTest( testCase.withName( rss.str() ) );\n        }\n        m_functions.push_back( testCase );\n    }\n\n    std::vector<TestCase> const& TestRegistry::getAllTests() const {\n        return m_functions;\n    }\n    std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {\n        if( m_sortedFunctions.empty() )\n            enforceNoDuplicateTestCases( m_functions );\n\n        if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {\n            m_sortedFunctions = sortTests( config, m_functions );\n            m_currentSortOrder = config.runOrder();\n        }\n        return m_sortedFunctions;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}\n\n    void TestInvokerAsFunction::invoke() const {\n        m_testAsFunction();\n    }\n\n    std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {\n        std::string className(classOrQualifiedMethodName);\n        if( startsWith( className, '&' ) )\n        {\n            std::size_t lastColons = className.rfind( \"::\" );\n            std::size_t penultimateColons = className.rfind( \"::\", lastColons-1 );\n            if( penultimateColons == std::string::npos )\n                penultimateColons = 1;\n            className = className.substr( penultimateColons, lastColons-penultimateColons );\n        }\n        return className;\n    }\n\n} // end namespace Catch\n// end catch_test_case_registry_impl.cpp\n// start catch_test_case_tracker.cpp\n\n#include <algorithm>\n#include <cassert>\n#include <stdexcept>\n#include <memory>\n#include <sstream>\n\n#if defined(__clang__)\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#endif\n\nnamespace Catch {\nnamespace TestCaseTracking {\n\n    NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )\n    :   name( _name ),\n        location( _location )\n    {}\n\n    ITracker::~ITracker() = default;\n\n    ITracker& TrackerContext::startRun() {\n        m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( \"{root}\", CATCH_INTERNAL_LINEINFO ), *this, nullptr );\n        m_currentTracker = nullptr;\n        m_runState = Executing;\n        return *m_rootTracker;\n    }\n\n    void TrackerContext::endRun() {\n        m_rootTracker.reset();\n        m_currentTracker = nullptr;\n        m_runState = NotStarted;\n    }\n\n    void TrackerContext::startCycle() {\n        m_currentTracker = m_rootTracker.get();\n        m_runState = Executing;\n    }\n    void TrackerContext::completeCycle() {\n        m_runState = CompletedCycle;\n    }\n\n    bool TrackerContext::completedCycle() const {\n        return m_runState == CompletedCycle;\n    }\n    ITracker& TrackerContext::currentTracker() {\n        return *m_currentTracker;\n    }\n    void TrackerContext::setCurrentTracker( ITracker* tracker ) {\n        m_currentTracker = tracker;\n    }\n\n    TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):\n        ITracker(nameAndLocation),\n        m_ctx( ctx ),\n        m_parent( parent )\n    {}\n\n    bool TrackerBase::isComplete() const {\n        return m_runState == CompletedSuccessfully || m_runState == Failed;\n    }\n    bool TrackerBase::isSuccessfullyCompleted() const {\n        return m_runState == CompletedSuccessfully;\n    }\n    bool TrackerBase::isOpen() const {\n        return m_runState != NotStarted && !isComplete();\n    }\n    bool TrackerBase::hasChildren() const {\n        return !m_children.empty();\n    }\n\n    void TrackerBase::addChild( ITrackerPtr const& child ) {\n        m_children.push_back( child );\n    }\n\n    ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {\n        auto it = std::find_if( m_children.begin(), m_children.end(),\n            [&nameAndLocation]( ITrackerPtr const& tracker ){\n                return\n                    tracker->nameAndLocation().location == nameAndLocation.location &&\n                    tracker->nameAndLocation().name == nameAndLocation.name;\n            } );\n        return( it != m_children.end() )\n            ? *it\n            : nullptr;\n    }\n    ITracker& TrackerBase::parent() {\n        assert( m_parent ); // Should always be non-null except for root\n        return *m_parent;\n    }\n\n    void TrackerBase::openChild() {\n        if( m_runState != ExecutingChildren ) {\n            m_runState = ExecutingChildren;\n            if( m_parent )\n                m_parent->openChild();\n        }\n    }\n\n    bool TrackerBase::isSectionTracker() const { return false; }\n    bool TrackerBase::isGeneratorTracker() const { return false; }\n\n    void TrackerBase::open() {\n        m_runState = Executing;\n        moveToThis();\n        if( m_parent )\n            m_parent->openChild();\n    }\n\n    void TrackerBase::close() {\n\n        // Close any still open children (e.g. generators)\n        while( &m_ctx.currentTracker() != this )\n            m_ctx.currentTracker().close();\n\n        switch( m_runState ) {\n            case NeedsAnotherRun:\n                break;\n\n            case Executing:\n                m_runState = CompletedSuccessfully;\n                break;\n            case ExecutingChildren:\n                if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )\n                    m_runState = CompletedSuccessfully;\n                break;\n\n            case NotStarted:\n            case CompletedSuccessfully:\n            case Failed:\n                CATCH_INTERNAL_ERROR( \"Illogical state: \" << m_runState );\n\n            default:\n                CATCH_INTERNAL_ERROR( \"Unknown state: \" << m_runState );\n        }\n        moveToParent();\n        m_ctx.completeCycle();\n    }\n    void TrackerBase::fail() {\n        m_runState = Failed;\n        if( m_parent )\n            m_parent->markAsNeedingAnotherRun();\n        moveToParent();\n        m_ctx.completeCycle();\n    }\n    void TrackerBase::markAsNeedingAnotherRun() {\n        m_runState = NeedsAnotherRun;\n    }\n\n    void TrackerBase::moveToParent() {\n        assert( m_parent );\n        m_ctx.setCurrentTracker( m_parent );\n    }\n    void TrackerBase::moveToThis() {\n        m_ctx.setCurrentTracker( this );\n    }\n\n    SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )\n    :   TrackerBase( nameAndLocation, ctx, parent ),\n        m_trimmed_name(trim(nameAndLocation.name))\n    {\n        if( parent ) {\n            while( !parent->isSectionTracker() )\n                parent = &parent->parent();\n\n            SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );\n            addNextFilters( parentSection.m_filters );\n        }\n    }\n\n    bool SectionTracker::isComplete() const {\n        bool complete = true;\n\n        if (m_filters.empty()\n            || m_filters[0] == \"\"\n            || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {\n            complete = TrackerBase::isComplete();\n        }\n        return complete;\n    }\n\n    bool SectionTracker::isSectionTracker() const { return true; }\n\n    SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {\n        std::shared_ptr<SectionTracker> section;\n\n        ITracker& currentTracker = ctx.currentTracker();\n        if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {\n            assert( childTracker );\n            assert( childTracker->isSectionTracker() );\n            section = std::static_pointer_cast<SectionTracker>( childTracker );\n        }\n        else {\n            section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );\n            currentTracker.addChild( section );\n        }\n        if( !ctx.completedCycle() )\n            section->tryOpen();\n        return *section;\n    }\n\n    void SectionTracker::tryOpen() {\n        if( !isComplete() )\n            open();\n    }\n\n    void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {\n        if( !filters.empty() ) {\n            m_filters.reserve( m_filters.size() + filters.size() + 2 );\n            m_filters.emplace_back(\"\"); // Root - should never be consulted\n            m_filters.emplace_back(\"\"); // Test Case - not a section filter\n            m_filters.insert( m_filters.end(), filters.begin(), filters.end() );\n        }\n    }\n    void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {\n        if( filters.size() > 1 )\n            m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );\n    }\n\n    std::vector<std::string> const& SectionTracker::getFilters() const {\n        return m_filters;\n    }\n\n    std::string const& SectionTracker::trimmedName() const {\n        return m_trimmed_name;\n    }\n\n} // namespace TestCaseTracking\n\nusing TestCaseTracking::ITracker;\nusing TestCaseTracking::TrackerContext;\nusing TestCaseTracking::SectionTracker;\n\n} // namespace Catch\n\n#if defined(__clang__)\n#    pragma clang diagnostic pop\n#endif\n// end catch_test_case_tracker.cpp\n// start catch_test_registry.cpp\n\nnamespace Catch {\n\n    auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {\n        return new(std::nothrow) TestInvokerAsFunction( testAsFunction );\n    }\n\n    NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}\n\n    AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {\n        CATCH_TRY {\n            getMutableRegistryHub()\n                    .registerTest(\n                        makeTestCase(\n                            invoker,\n                            extractClassName( classOrMethod ),\n                            nameAndTags,\n                            lineInfo));\n        } CATCH_CATCH_ALL {\n            // Do not throw when constructing global objects, instead register the exception to be processed later\n            getMutableRegistryHub().registerStartupException();\n        }\n    }\n\n    AutoReg::~AutoReg() = default;\n}\n// end catch_test_registry.cpp\n// start catch_test_spec.cpp\n\n#include <algorithm>\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    TestSpec::Pattern::Pattern( std::string const& name )\n    : m_name( name )\n    {}\n\n    TestSpec::Pattern::~Pattern() = default;\n\n    std::string const& TestSpec::Pattern::name() const {\n        return m_name;\n    }\n\n    TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )\n    : Pattern( filterString )\n    , m_wildcardPattern( toLower( name ), CaseSensitive::No )\n    {}\n\n    bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {\n        return m_wildcardPattern.matches( testCase.name );\n    }\n\n    TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )\n    : Pattern( filterString )\n    , m_tag( toLower( tag ) )\n    {}\n\n    bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {\n        return std::find(begin(testCase.lcaseTags),\n                         end(testCase.lcaseTags),\n                         m_tag) != end(testCase.lcaseTags);\n    }\n\n    TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )\n    : Pattern( underlyingPattern->name() )\n    , m_underlyingPattern( underlyingPattern )\n    {}\n\n    bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {\n        return !m_underlyingPattern->matches( testCase );\n    }\n\n    bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {\n        return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );\n    }\n\n    std::string TestSpec::Filter::name() const {\n        std::string name;\n        for( auto const& p : m_patterns )\n            name += p->name();\n        return name;\n    }\n\n    bool TestSpec::hasFilters() const {\n        return !m_filters.empty();\n    }\n\n    bool TestSpec::matches( TestCaseInfo const& testCase ) const {\n        return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );\n    }\n\n    TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const\n    {\n        Matches matches( m_filters.size() );\n        std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){\n            std::vector<TestCase const*> currentMatches;\n            for( auto const& test : testCases )\n                if( isThrowSafe( test, config ) && filter.matches( test ) )\n                    currentMatches.emplace_back( &test );\n            return FilterMatch{ filter.name(), currentMatches };\n        } );\n        return matches;\n    }\n\n    const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{\n        return  (m_invalidArgs);\n    }\n\n}\n// end catch_test_spec.cpp\n// start catch_test_spec_parser.cpp\n\nnamespace Catch {\n\n    TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}\n\n    TestSpecParser& TestSpecParser::parse( std::string const& arg ) {\n        m_mode = None;\n        m_exclusion = false;\n        m_arg = m_tagAliases->expandAliases( arg );\n        m_escapeChars.clear();\n        m_substring.reserve(m_arg.size());\n        m_patternName.reserve(m_arg.size());\n        m_realPatternPos = 0;\n\n        for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )\n          //if visitChar fails\n           if( !visitChar( m_arg[m_pos] ) ){\n               m_testSpec.m_invalidArgs.push_back(arg);\n               break;\n           }\n        endMode();\n        return *this;\n    }\n    TestSpec TestSpecParser::testSpec() {\n        addFilter();\n        return m_testSpec;\n    }\n    bool TestSpecParser::visitChar( char c ) {\n        if( (m_mode != EscapedName) && (c == '\\\\') ) {\n            escape();\n            addCharToPattern(c);\n            return true;\n        }else if((m_mode != EscapedName) && (c == ',') )  {\n            return separate();\n        }\n\n        switch( m_mode ) {\n        case None:\n            if( processNoneChar( c ) )\n                return true;\n            break;\n        case Name:\n            processNameChar( c );\n            break;\n        case EscapedName:\n            endMode();\n            addCharToPattern(c);\n            return true;\n        default:\n        case Tag:\n        case QuotedName:\n            if( processOtherChar( c ) )\n                return true;\n            break;\n        }\n\n        m_substring += c;\n        if( !isControlChar( c ) ) {\n            m_patternName += c;\n            m_realPatternPos++;\n        }\n        return true;\n    }\n    // Two of the processing methods return true to signal the caller to return\n    // without adding the given character to the current pattern strings\n    bool TestSpecParser::processNoneChar( char c ) {\n        switch( c ) {\n        case ' ':\n            return true;\n        case '~':\n            m_exclusion = true;\n            return false;\n        case '[':\n            startNewMode( Tag );\n            return false;\n        case '\"':\n            startNewMode( QuotedName );\n            return false;\n        default:\n            startNewMode( Name );\n            return false;\n        }\n    }\n    void TestSpecParser::processNameChar( char c ) {\n        if( c == '[' ) {\n            if( m_substring == \"exclude:\" )\n                m_exclusion = true;\n            else\n                endMode();\n            startNewMode( Tag );\n        }\n    }\n    bool TestSpecParser::processOtherChar( char c ) {\n        if( !isControlChar( c ) )\n            return false;\n        m_substring += c;\n        endMode();\n        return true;\n    }\n    void TestSpecParser::startNewMode( Mode mode ) {\n        m_mode = mode;\n    }\n    void TestSpecParser::endMode() {\n        switch( m_mode ) {\n        case Name:\n        case QuotedName:\n            return addNamePattern();\n        case Tag:\n            return addTagPattern();\n        case EscapedName:\n            revertBackToLastMode();\n            return;\n        case None:\n        default:\n            return startNewMode( None );\n        }\n    }\n    void TestSpecParser::escape() {\n        saveLastMode();\n        m_mode = EscapedName;\n        m_escapeChars.push_back(m_realPatternPos);\n    }\n    bool TestSpecParser::isControlChar( char c ) const {\n        switch( m_mode ) {\n            default:\n                return false;\n            case None:\n                return c == '~';\n            case Name:\n                return c == '[';\n            case EscapedName:\n                return true;\n            case QuotedName:\n                return c == '\"';\n            case Tag:\n                return c == '[' || c == ']';\n        }\n    }\n\n    void TestSpecParser::addFilter() {\n        if( !m_currentFilter.m_patterns.empty() ) {\n            m_testSpec.m_filters.push_back( m_currentFilter );\n            m_currentFilter = TestSpec::Filter();\n        }\n    }\n\n    void TestSpecParser::saveLastMode() {\n      lastMode = m_mode;\n    }\n\n    void TestSpecParser::revertBackToLastMode() {\n      m_mode = lastMode;\n    }\n\n    bool TestSpecParser::separate() {\n      if( (m_mode==QuotedName) || (m_mode==Tag) ){\n         //invalid argument, signal failure to previous scope.\n         m_mode = None;\n         m_pos = m_arg.size();\n         m_substring.clear();\n         m_patternName.clear();\n         m_realPatternPos = 0;\n         return false;\n      }\n      endMode();\n      addFilter();\n      return true; //success\n    }\n\n    std::string TestSpecParser::preprocessPattern() {\n        std::string token = m_patternName;\n        for (std::size_t i = 0; i < m_escapeChars.size(); ++i)\n            token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);\n        m_escapeChars.clear();\n        if (startsWith(token, \"exclude:\")) {\n            m_exclusion = true;\n            token = token.substr(8);\n        }\n\n        m_patternName.clear();\n        m_realPatternPos = 0;\n\n        return token;\n    }\n\n    void TestSpecParser::addNamePattern() {\n        auto token = preprocessPattern();\n\n        if (!token.empty()) {\n            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);\n            if (m_exclusion)\n                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);\n            m_currentFilter.m_patterns.push_back(pattern);\n        }\n        m_substring.clear();\n        m_exclusion = false;\n        m_mode = None;\n    }\n\n    void TestSpecParser::addTagPattern() {\n        auto token = preprocessPattern();\n\n        if (!token.empty()) {\n            // If the tag pattern is the \"hide and tag\" shorthand (e.g. [.foo])\n            // we have to create a separate hide tag and shorten the real one\n            if (token.size() > 1 && token[0] == '.') {\n                token.erase(token.begin());\n                TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(\".\", m_substring);\n                if (m_exclusion) {\n                    pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);\n                }\n                m_currentFilter.m_patterns.push_back(pattern);\n            }\n\n            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);\n\n            if (m_exclusion) {\n                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);\n            }\n            m_currentFilter.m_patterns.push_back(pattern);\n        }\n        m_substring.clear();\n        m_exclusion = false;\n        m_mode = None;\n    }\n\n    TestSpec parseTestSpec( std::string const& arg ) {\n        return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();\n    }\n\n} // namespace Catch\n// end catch_test_spec_parser.cpp\n// start catch_timer.cpp\n\n#include <chrono>\n\nstatic const uint64_t nanosecondsInSecond = 1000000000;\n\nnamespace Catch {\n\n    auto getCurrentNanosecondsSinceEpoch() -> uint64_t {\n        return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();\n    }\n\n    namespace {\n        auto estimateClockResolution() -> uint64_t {\n            uint64_t sum = 0;\n            static const uint64_t iterations = 1000000;\n\n            auto startTime = getCurrentNanosecondsSinceEpoch();\n\n            for( std::size_t i = 0; i < iterations; ++i ) {\n\n                uint64_t ticks;\n                uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();\n                do {\n                    ticks = getCurrentNanosecondsSinceEpoch();\n                } while( ticks == baseTicks );\n\n                auto delta = ticks - baseTicks;\n                sum += delta;\n\n                // If we have been calibrating for over 3 seconds -- the clock\n                // is terrible and we should move on.\n                // TBD: How to signal that the measured resolution is probably wrong?\n                if (ticks > startTime + 3 * nanosecondsInSecond) {\n                    return sum / ( i + 1u );\n                }\n            }\n\n            // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers\n            // - and potentially do more iterations if there's a high variance.\n            return sum/iterations;\n        }\n    }\n    auto getEstimatedClockResolution() -> uint64_t {\n        static auto s_resolution = estimateClockResolution();\n        return s_resolution;\n    }\n\n    void Timer::start() {\n       m_nanoseconds = getCurrentNanosecondsSinceEpoch();\n    }\n    auto Timer::getElapsedNanoseconds() const -> uint64_t {\n        return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;\n    }\n    auto Timer::getElapsedMicroseconds() const -> uint64_t {\n        return getElapsedNanoseconds()/1000;\n    }\n    auto Timer::getElapsedMilliseconds() const -> unsigned int {\n        return static_cast<unsigned int>(getElapsedMicroseconds()/1000);\n    }\n    auto Timer::getElapsedSeconds() const -> double {\n        return getElapsedMicroseconds()/1000000.0;\n    }\n\n} // namespace Catch\n// end catch_timer.cpp\n// start catch_tostring.cpp\n\n#if defined(__clang__)\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#    pragma clang diagnostic ignored \"-Wglobal-constructors\"\n#endif\n\n// Enable specific decls locally\n#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)\n#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n#endif\n\n#include <cmath>\n#include <iomanip>\n\nnamespace Catch {\n\nnamespace Detail {\n\n    const std::string unprintableString = \"{?}\";\n\n    namespace {\n        const int hexThreshold = 255;\n\n        struct Endianness {\n            enum Arch { Big, Little };\n\n            static Arch which() {\n                int one = 1;\n                // If the lowest byte we read is non-zero, we can assume\n                // that little endian format is used.\n                auto value = *reinterpret_cast<char*>(&one);\n                return value ? Little : Big;\n            }\n        };\n    }\n\n    std::string rawMemoryToString( const void *object, std::size_t size ) {\n        // Reverse order for little endian architectures\n        int i = 0, end = static_cast<int>( size ), inc = 1;\n        if( Endianness::which() == Endianness::Little ) {\n            i = end-1;\n            end = inc = -1;\n        }\n\n        unsigned char const *bytes = static_cast<unsigned char const *>(object);\n        ReusableStringStream rss;\n        rss << \"0x\" << std::setfill('0') << std::hex;\n        for( ; i != end; i += inc )\n             rss << std::setw(2) << static_cast<unsigned>(bytes[i]);\n       return rss.str();\n    }\n}\n\ntemplate<typename T>\nstd::string fpToString( T value, int precision ) {\n    if (Catch::isnan(value)) {\n        return \"nan\";\n    }\n\n    ReusableStringStream rss;\n    rss << std::setprecision( precision )\n        << std::fixed\n        << value;\n    std::string d = rss.str();\n    std::size_t i = d.find_last_not_of( '0' );\n    if( i != std::string::npos && i != d.size()-1 ) {\n        if( d[i] == '.' )\n            i++;\n        d = d.substr( 0, i+1 );\n    }\n    return d;\n}\n\n//// ======================================================= ////\n//\n//   Out-of-line defs for full specialization of StringMaker\n//\n//// ======================================================= ////\n\nstd::string StringMaker<std::string>::convert(const std::string& str) {\n    if (!getCurrentContext().getConfig()->showInvisibles()) {\n        return '\"' + str + '\"';\n    }\n\n    std::string s(\"\\\"\");\n    for (char c : str) {\n        switch (c) {\n        case '\\n':\n            s.append(\"\\\\n\");\n            break;\n        case '\\t':\n            s.append(\"\\\\t\");\n            break;\n        default:\n            s.push_back(c);\n            break;\n        }\n    }\n    s.append(\"\\\"\");\n    return s;\n}\n\n#ifdef CATCH_CONFIG_CPP17_STRING_VIEW\nstd::string StringMaker<std::string_view>::convert(std::string_view str) {\n    return ::Catch::Detail::stringify(std::string{ str });\n}\n#endif\n\nstd::string StringMaker<char const*>::convert(char const* str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::string{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\nstd::string StringMaker<char*>::convert(char* str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::string{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\n\n#ifdef CATCH_CONFIG_WCHAR\nstd::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {\n    std::string s;\n    s.reserve(wstr.size());\n    for (auto c : wstr) {\n        s += (c <= 0xff) ? static_cast<char>(c) : '?';\n    }\n    return ::Catch::Detail::stringify(s);\n}\n\n# ifdef CATCH_CONFIG_CPP17_STRING_VIEW\nstd::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {\n    return StringMaker<std::wstring>::convert(std::wstring(str));\n}\n# endif\n\nstd::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::wstring{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\nstd::string StringMaker<wchar_t *>::convert(wchar_t * str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::wstring{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\n#endif\n\n#if defined(CATCH_CONFIG_CPP17_BYTE)\n#include <cstddef>\nstd::string StringMaker<std::byte>::convert(std::byte value) {\n    return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));\n}\n#endif // defined(CATCH_CONFIG_CPP17_BYTE)\n\nstd::string StringMaker<int>::convert(int value) {\n    return ::Catch::Detail::stringify(static_cast<long long>(value));\n}\nstd::string StringMaker<long>::convert(long value) {\n    return ::Catch::Detail::stringify(static_cast<long long>(value));\n}\nstd::string StringMaker<long long>::convert(long long value) {\n    ReusableStringStream rss;\n    rss << value;\n    if (value > Detail::hexThreshold) {\n        rss << \" (0x\" << std::hex << value << ')';\n    }\n    return rss.str();\n}\n\nstd::string StringMaker<unsigned int>::convert(unsigned int value) {\n    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));\n}\nstd::string StringMaker<unsigned long>::convert(unsigned long value) {\n    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));\n}\nstd::string StringMaker<unsigned long long>::convert(unsigned long long value) {\n    ReusableStringStream rss;\n    rss << value;\n    if (value > Detail::hexThreshold) {\n        rss << \" (0x\" << std::hex << value << ')';\n    }\n    return rss.str();\n}\n\nstd::string StringMaker<bool>::convert(bool b) {\n    return b ? \"true\" : \"false\";\n}\n\nstd::string StringMaker<signed char>::convert(signed char value) {\n    if (value == '\\r') {\n        return \"'\\\\r'\";\n    } else if (value == '\\f') {\n        return \"'\\\\f'\";\n    } else if (value == '\\n') {\n        return \"'\\\\n'\";\n    } else if (value == '\\t') {\n        return \"'\\\\t'\";\n    } else if ('\\0' <= value && value < ' ') {\n        return ::Catch::Detail::stringify(static_cast<unsigned int>(value));\n    } else {\n        char chstr[] = \"' '\";\n        chstr[1] = value;\n        return chstr;\n    }\n}\nstd::string StringMaker<char>::convert(char c) {\n    return ::Catch::Detail::stringify(static_cast<signed char>(c));\n}\nstd::string StringMaker<unsigned char>::convert(unsigned char c) {\n    return ::Catch::Detail::stringify(static_cast<char>(c));\n}\n\nstd::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {\n    return \"nullptr\";\n}\n\nint StringMaker<float>::precision = 5;\n\nstd::string StringMaker<float>::convert(float value) {\n    return fpToString(value, precision) + 'f';\n}\n\nint StringMaker<double>::precision = 10;\n\nstd::string StringMaker<double>::convert(double value) {\n    return fpToString(value, precision);\n}\n\nstd::string ratio_string<std::atto>::symbol() { return \"a\"; }\nstd::string ratio_string<std::femto>::symbol() { return \"f\"; }\nstd::string ratio_string<std::pico>::symbol() { return \"p\"; }\nstd::string ratio_string<std::nano>::symbol() { return \"n\"; }\nstd::string ratio_string<std::micro>::symbol() { return \"u\"; }\nstd::string ratio_string<std::milli>::symbol() { return \"m\"; }\n\n} // end namespace Catch\n\n#if defined(__clang__)\n#    pragma clang diagnostic pop\n#endif\n\n// end catch_tostring.cpp\n// start catch_totals.cpp\n\nnamespace Catch {\n\n    Counts Counts::operator - ( Counts const& other ) const {\n        Counts diff;\n        diff.passed = passed - other.passed;\n        diff.failed = failed - other.failed;\n        diff.failedButOk = failedButOk - other.failedButOk;\n        return diff;\n    }\n\n    Counts& Counts::operator += ( Counts const& other ) {\n        passed += other.passed;\n        failed += other.failed;\n        failedButOk += other.failedButOk;\n        return *this;\n    }\n\n    std::size_t Counts::total() const {\n        return passed + failed + failedButOk;\n    }\n    bool Counts::allPassed() const {\n        return failed == 0 && failedButOk == 0;\n    }\n    bool Counts::allOk() const {\n        return failed == 0;\n    }\n\n    Totals Totals::operator - ( Totals const& other ) const {\n        Totals diff;\n        diff.assertions = assertions - other.assertions;\n        diff.testCases = testCases - other.testCases;\n        return diff;\n    }\n\n    Totals& Totals::operator += ( Totals const& other ) {\n        assertions += other.assertions;\n        testCases += other.testCases;\n        return *this;\n    }\n\n    Totals Totals::delta( Totals const& prevTotals ) const {\n        Totals diff = *this - prevTotals;\n        if( diff.assertions.failed > 0 )\n            ++diff.testCases.failed;\n        else if( diff.assertions.failedButOk > 0 )\n            ++diff.testCases.failedButOk;\n        else\n            ++diff.testCases.passed;\n        return diff;\n    }\n\n}\n// end catch_totals.cpp\n// start catch_uncaught_exceptions.cpp\n\n// start catch_config_uncaught_exceptions.hpp\n\n//              Copyright Catch2 Authors\n// Distributed under the Boost Software License, Version 1.0.\n//   (See accompanying file LICENSE_1_0.txt or copy at\n//        https://www.boost.org/LICENSE_1_0.txt)\n\n// SPDX-License-Identifier: BSL-1.0\n\n#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP\n#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP\n\n#if defined(_MSC_VER)\n#  if _MSC_VER >= 1900 // Visual Studio 2015 or newer\n#    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS\n#  endif\n#endif\n\n#include <exception>\n\n#if defined(__cpp_lib_uncaught_exceptions) \\\n    && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)\n\n#  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS\n#endif // __cpp_lib_uncaught_exceptions\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \\\n    && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \\\n    && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)\n\n#  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS\n#endif\n\n#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP\n// end catch_config_uncaught_exceptions.hpp\n#include <exception>\n\nnamespace Catch {\n    bool uncaught_exceptions() {\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n        return false;\n#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)\n        return std::uncaught_exceptions() > 0;\n#else\n        return std::uncaught_exception();\n#endif\n  }\n} // end namespace Catch\n// end catch_uncaught_exceptions.cpp\n// start catch_version.cpp\n\n#include <ostream>\n\nnamespace Catch {\n\n    Version::Version\n        (   unsigned int _majorVersion,\n            unsigned int _minorVersion,\n            unsigned int _patchNumber,\n            char const * const _branchName,\n            unsigned int _buildNumber )\n    :   majorVersion( _majorVersion ),\n        minorVersion( _minorVersion ),\n        patchNumber( _patchNumber ),\n        branchName( _branchName ),\n        buildNumber( _buildNumber )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, Version const& version ) {\n        os  << version.majorVersion << '.'\n            << version.minorVersion << '.'\n            << version.patchNumber;\n        // branchName is never null -> 0th char is \\0 if it is empty\n        if (version.branchName[0]) {\n            os << '-' << version.branchName\n               << '.' << version.buildNumber;\n        }\n        return os;\n    }\n\n    Version const& libraryVersion() {\n        static Version version( 2, 13, 10, \"\", 0 );\n        return version;\n    }\n\n}\n// end catch_version.cpp\n// start catch_wildcard_pattern.cpp\n\nnamespace Catch {\n\n    WildcardPattern::WildcardPattern( std::string const& pattern,\n                                      CaseSensitive::Choice caseSensitivity )\n    :   m_caseSensitivity( caseSensitivity ),\n        m_pattern( normaliseString( pattern ) )\n    {\n        if( startsWith( m_pattern, '*' ) ) {\n            m_pattern = m_pattern.substr( 1 );\n            m_wildcard = WildcardAtStart;\n        }\n        if( endsWith( m_pattern, '*' ) ) {\n            m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );\n            m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );\n        }\n    }\n\n    bool WildcardPattern::matches( std::string const& str ) const {\n        switch( m_wildcard ) {\n            case NoWildcard:\n                return m_pattern == normaliseString( str );\n            case WildcardAtStart:\n                return endsWith( normaliseString( str ), m_pattern );\n            case WildcardAtEnd:\n                return startsWith( normaliseString( str ), m_pattern );\n            case WildcardAtBothEnds:\n                return contains( normaliseString( str ), m_pattern );\n            default:\n                CATCH_INTERNAL_ERROR( \"Unknown enum\" );\n        }\n    }\n\n    std::string WildcardPattern::normaliseString( std::string const& str ) const {\n        return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );\n    }\n}\n// end catch_wildcard_pattern.cpp\n// start catch_xmlwriter.cpp\n\n#include <iomanip>\n#include <type_traits>\n\nnamespace Catch {\n\nnamespace {\n\n    size_t trailingBytes(unsigned char c) {\n        if ((c & 0xE0) == 0xC0) {\n            return 2;\n        }\n        if ((c & 0xF0) == 0xE0) {\n            return 3;\n        }\n        if ((c & 0xF8) == 0xF0) {\n            return 4;\n        }\n        CATCH_INTERNAL_ERROR(\"Invalid multibyte utf-8 start byte encountered\");\n    }\n\n    uint32_t headerValue(unsigned char c) {\n        if ((c & 0xE0) == 0xC0) {\n            return c & 0x1F;\n        }\n        if ((c & 0xF0) == 0xE0) {\n            return c & 0x0F;\n        }\n        if ((c & 0xF8) == 0xF0) {\n            return c & 0x07;\n        }\n        CATCH_INTERNAL_ERROR(\"Invalid multibyte utf-8 start byte encountered\");\n    }\n\n    void hexEscapeChar(std::ostream& os, unsigned char c) {\n        std::ios_base::fmtflags f(os.flags());\n        os << \"\\\\x\"\n            << std::uppercase << std::hex << std::setfill('0') << std::setw(2)\n            << static_cast<int>(c);\n        os.flags(f);\n    }\n\n    bool shouldNewline(XmlFormatting fmt) {\n        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));\n    }\n\n    bool shouldIndent(XmlFormatting fmt) {\n        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));\n    }\n\n} // anonymous namespace\n\n    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {\n        return static_cast<XmlFormatting>(\n            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |\n            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)\n        );\n    }\n\n    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {\n        return static_cast<XmlFormatting>(\n            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &\n            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)\n        );\n    }\n\n    XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )\n    :   m_str( str ),\n        m_forWhat( forWhat )\n    {}\n\n    void XmlEncode::encodeTo( std::ostream& os ) const {\n        // Apostrophe escaping not necessary if we always use \" to write attributes\n        // (see: http://www.w3.org/TR/xml/#syntax)\n\n        for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {\n            unsigned char c = m_str[idx];\n            switch (c) {\n            case '<':   os << \"&lt;\"; break;\n            case '&':   os << \"&amp;\"; break;\n\n            case '>':\n                // See: http://www.w3.org/TR/xml/#syntax\n                if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')\n                    os << \"&gt;\";\n                else\n                    os << c;\n                break;\n\n            case '\\\"':\n                if (m_forWhat == ForAttributes)\n                    os << \"&quot;\";\n                else\n                    os << c;\n                break;\n\n            default:\n                // Check for control characters and invalid utf-8\n\n                // Escape control characters in standard ascii\n                // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0\n                if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                // Plain ASCII: Write it to stream\n                if (c < 0x7F) {\n                    os << c;\n                    break;\n                }\n\n                // UTF-8 territory\n                // Check if the encoding is valid and if it is not, hex escape bytes.\n                // Important: We do not check the exact decoded values for validity, only the encoding format\n                // First check that this bytes is a valid lead byte:\n                // This means that it is not encoded as 1111 1XXX\n                // Or as 10XX XXXX\n                if (c <  0xC0 ||\n                    c >= 0xF8) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                auto encBytes = trailingBytes(c);\n                // Are there enough bytes left to avoid accessing out-of-bounds memory?\n                if (idx + encBytes - 1 >= m_str.size()) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n                // The header is valid, check data\n                // The next encBytes bytes must together be a valid utf-8\n                // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)\n                bool valid = true;\n                uint32_t value = headerValue(c);\n                for (std::size_t n = 1; n < encBytes; ++n) {\n                    unsigned char nc = m_str[idx + n];\n                    valid &= ((nc & 0xC0) == 0x80);\n                    value = (value << 6) | (nc & 0x3F);\n                }\n\n                if (\n                    // Wrong bit pattern of following bytes\n                    (!valid) ||\n                    // Overlong encodings\n                    (value < 0x80) ||\n                    (0x80 <= value && value < 0x800   && encBytes > 2) ||\n                    (0x800 < value && value < 0x10000 && encBytes > 3) ||\n                    // Encoded value out of range\n                    (value >= 0x110000)\n                    ) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                // If we got here, this is in fact a valid(ish) utf-8 sequence\n                for (std::size_t n = 0; n < encBytes; ++n) {\n                    os << m_str[idx + n];\n                }\n                idx += encBytes - 1;\n                break;\n            }\n        }\n    }\n\n    std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {\n        xmlEncode.encodeTo( os );\n        return os;\n    }\n\n    XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )\n    :   m_writer( writer ),\n        m_fmt(fmt)\n    {}\n\n    XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept\n    :   m_writer( other.m_writer ),\n        m_fmt(other.m_fmt)\n    {\n        other.m_writer = nullptr;\n        other.m_fmt = XmlFormatting::None;\n    }\n    XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {\n        if ( m_writer ) {\n            m_writer->endElement();\n        }\n        m_writer = other.m_writer;\n        other.m_writer = nullptr;\n        m_fmt = other.m_fmt;\n        other.m_fmt = XmlFormatting::None;\n        return *this;\n    }\n\n    XmlWriter::ScopedElement::~ScopedElement() {\n        if (m_writer) {\n            m_writer->endElement(m_fmt);\n        }\n    }\n\n    XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {\n        m_writer->writeText( text, fmt );\n        return *this;\n    }\n\n    XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )\n    {\n        writeDeclaration();\n    }\n\n    XmlWriter::~XmlWriter() {\n        while (!m_tags.empty()) {\n            endElement();\n        }\n        newlineIfNecessary();\n    }\n\n    XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {\n        ensureTagClosed();\n        newlineIfNecessary();\n        if (shouldIndent(fmt)) {\n            m_os << m_indent;\n            m_indent += \"  \";\n        }\n        m_os << '<' << name;\n        m_tags.push_back( name );\n        m_tagIsOpen = true;\n        applyFormatting(fmt);\n        return *this;\n    }\n\n    XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {\n        ScopedElement scoped( this, fmt );\n        startElement( name, fmt );\n        return scoped;\n    }\n\n    XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {\n        m_indent = m_indent.substr(0, m_indent.size() - 2);\n\n        if( m_tagIsOpen ) {\n            m_os << \"/>\";\n            m_tagIsOpen = false;\n        } else {\n            newlineIfNecessary();\n            if (shouldIndent(fmt)) {\n                m_os << m_indent;\n            }\n            m_os << \"</\" << m_tags.back() << \">\";\n        }\n        m_os << std::flush;\n        applyFormatting(fmt);\n        m_tags.pop_back();\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {\n        if( !name.empty() && !attribute.empty() )\n            m_os << ' ' << name << \"=\\\"\" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '\"';\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {\n        m_os << ' ' << name << \"=\\\"\" << ( attribute ? \"true\" : \"false\" ) << '\"';\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {\n        if( !text.empty() ){\n            bool tagWasOpen = m_tagIsOpen;\n            ensureTagClosed();\n            if (tagWasOpen && shouldIndent(fmt)) {\n                m_os << m_indent;\n            }\n            m_os << XmlEncode( text );\n            applyFormatting(fmt);\n        }\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {\n        ensureTagClosed();\n        if (shouldIndent(fmt)) {\n            m_os << m_indent;\n        }\n        m_os << \"<!--\" << text << \"-->\";\n        applyFormatting(fmt);\n        return *this;\n    }\n\n    void XmlWriter::writeStylesheetRef( std::string const& url ) {\n        m_os << \"<?xml-stylesheet type=\\\"text/xsl\\\" href=\\\"\" << url << \"\\\"?>\\n\";\n    }\n\n    XmlWriter& XmlWriter::writeBlankLine() {\n        ensureTagClosed();\n        m_os << '\\n';\n        return *this;\n    }\n\n    void XmlWriter::ensureTagClosed() {\n        if( m_tagIsOpen ) {\n            m_os << '>' << std::flush;\n            newlineIfNecessary();\n            m_tagIsOpen = false;\n        }\n    }\n\n    void XmlWriter::applyFormatting(XmlFormatting fmt) {\n        m_needsNewline = shouldNewline(fmt);\n    }\n\n    void XmlWriter::writeDeclaration() {\n        m_os << \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n    }\n\n    void XmlWriter::newlineIfNecessary() {\n        if( m_needsNewline ) {\n            m_os << std::endl;\n            m_needsNewline = false;\n        }\n    }\n}\n// end catch_xmlwriter.cpp\n// start catch_reporter_bases.cpp\n\n#include <cstring>\n#include <cfloat>\n#include <cstdio>\n#include <cassert>\n#include <memory>\n\nnamespace Catch {\n    void prepareExpandedExpression(AssertionResult& result) {\n        result.getExpandedExpression();\n    }\n\n    // Because formatting using c++ streams is stateful, drop down to C is required\n    // Alternatively we could use stringstream, but its performance is... not good.\n    std::string getFormattedDuration( double duration ) {\n        // Max exponent + 1 is required to represent the whole part\n        // + 1 for decimal point\n        // + 3 for the 3 decimal places\n        // + 1 for null terminator\n        const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;\n        char buffer[maxDoubleSize];\n\n        // Save previous errno, to prevent sprintf from overwriting it\n        ErrnoGuard guard;\n#ifdef _MSC_VER\n        sprintf_s(buffer, \"%.3f\", duration);\n#else\n        std::sprintf(buffer, \"%.3f\", duration);\n#endif\n        return std::string(buffer);\n    }\n\n    bool shouldShowDuration( IConfig const& config, double duration ) {\n        if ( config.showDurations() == ShowDurations::Always ) {\n            return true;\n        }\n        if ( config.showDurations() == ShowDurations::Never ) {\n            return false;\n        }\n        const double min = config.minDuration();\n        return min >= 0 && duration >= min;\n    }\n\n    std::string serializeFilters( std::vector<std::string> const& container ) {\n        ReusableStringStream oss;\n        bool first = true;\n        for (auto&& filter : container)\n        {\n            if (!first)\n                oss << ' ';\n            else\n                first = false;\n\n            oss << filter;\n        }\n        return oss.str();\n    }\n\n    TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)\n        :StreamingReporterBase(_config) {}\n\n    std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {\n        return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };\n    }\n\n    void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}\n\n    bool TestEventListenerBase::assertionEnded(AssertionStats const &) {\n        return false;\n    }\n\n} // end namespace Catch\n// end catch_reporter_bases.cpp\n// start catch_reporter_compact.cpp\n\nnamespace {\n\n#ifdef CATCH_PLATFORM_MAC\n    const char* failedString() { return \"FAILED\"; }\n    const char* passedString() { return \"PASSED\"; }\n#else\n    const char* failedString() { return \"failed\"; }\n    const char* passedString() { return \"passed\"; }\n#endif\n\n    // Colour::LightGrey\n    Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }\n\n    std::string bothOrAll( std::size_t count ) {\n        return count == 1 ? std::string() :\n               count == 2 ? \"both \" : \"all \" ;\n    }\n\n} // anon namespace\n\nnamespace Catch {\nnamespace {\n// Colour, message variants:\n// - white: No tests ran.\n// -   red: Failed [both/all] N test cases, failed [both/all] M assertions.\n// - white: Passed [both/all] N test cases (no assertions).\n// -   red: Failed N tests cases, failed M assertions.\n// - green: Passed [both/all] N tests cases with M assertions.\nvoid printTotals(std::ostream& out, const Totals& totals) {\n    if (totals.testCases.total() == 0) {\n        out << \"No tests ran.\";\n    } else if (totals.testCases.failed == totals.testCases.total()) {\n        Colour colour(Colour::ResultError);\n        const std::string qualify_assertions_failed =\n            totals.assertions.failed == totals.assertions.total() ?\n            bothOrAll(totals.assertions.failed) : std::string();\n        out <<\n            \"Failed \" << bothOrAll(totals.testCases.failed)\n            << pluralise(totals.testCases.failed, \"test case\") << \", \"\n            \"failed \" << qualify_assertions_failed <<\n            pluralise(totals.assertions.failed, \"assertion\") << '.';\n    } else if (totals.assertions.total() == 0) {\n        out <<\n            \"Passed \" << bothOrAll(totals.testCases.total())\n            << pluralise(totals.testCases.total(), \"test case\")\n            << \" (no assertions).\";\n    } else if (totals.assertions.failed) {\n        Colour colour(Colour::ResultError);\n        out <<\n            \"Failed \" << pluralise(totals.testCases.failed, \"test case\") << \", \"\n            \"failed \" << pluralise(totals.assertions.failed, \"assertion\") << '.';\n    } else {\n        Colour colour(Colour::ResultSuccess);\n        out <<\n            \"Passed \" << bothOrAll(totals.testCases.passed)\n            << pluralise(totals.testCases.passed, \"test case\") <<\n            \" with \" << pluralise(totals.assertions.passed, \"assertion\") << '.';\n    }\n}\n\n// Implementation of CompactReporter formatting\nclass AssertionPrinter {\npublic:\n    AssertionPrinter& operator= (AssertionPrinter const&) = delete;\n    AssertionPrinter(AssertionPrinter const&) = delete;\n    AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)\n        : stream(_stream)\n        , result(_stats.assertionResult)\n        , messages(_stats.infoMessages)\n        , itMessage(_stats.infoMessages.begin())\n        , printInfoMessages(_printInfoMessages) {}\n\n    void print() {\n        printSourceInfo();\n\n        itMessage = messages.begin();\n\n        switch (result.getResultType()) {\n        case ResultWas::Ok:\n            printResultType(Colour::ResultSuccess, passedString());\n            printOriginalExpression();\n            printReconstructedExpression();\n            if (!result.hasExpression())\n                printRemainingMessages(Colour::None);\n            else\n                printRemainingMessages();\n            break;\n        case ResultWas::ExpressionFailed:\n            if (result.isOk())\n                printResultType(Colour::ResultSuccess, failedString() + std::string(\" - but was ok\"));\n            else\n                printResultType(Colour::Error, failedString());\n            printOriginalExpression();\n            printReconstructedExpression();\n            printRemainingMessages();\n            break;\n        case ResultWas::ThrewException:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"unexpected exception with message:\");\n            printMessage();\n            printExpressionWas();\n            printRemainingMessages();\n            break;\n        case ResultWas::FatalErrorCondition:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"fatal error condition with message:\");\n            printMessage();\n            printExpressionWas();\n            printRemainingMessages();\n            break;\n        case ResultWas::DidntThrowException:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"expected exception, got none\");\n            printExpressionWas();\n            printRemainingMessages();\n            break;\n        case ResultWas::Info:\n            printResultType(Colour::None, \"info\");\n            printMessage();\n            printRemainingMessages();\n            break;\n        case ResultWas::Warning:\n            printResultType(Colour::None, \"warning\");\n            printMessage();\n            printRemainingMessages();\n            break;\n        case ResultWas::ExplicitFailure:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"explicitly\");\n            printRemainingMessages(Colour::None);\n            break;\n            // These cases are here to prevent compiler warnings\n        case ResultWas::Unknown:\n        case ResultWas::FailureBit:\n        case ResultWas::Exception:\n            printResultType(Colour::Error, \"** internal error **\");\n            break;\n        }\n    }\n\nprivate:\n    void printSourceInfo() const {\n        Colour colourGuard(Colour::FileName);\n        stream << result.getSourceInfo() << ':';\n    }\n\n    void printResultType(Colour::Code colour, std::string const& passOrFail) const {\n        if (!passOrFail.empty()) {\n            {\n                Colour colourGuard(colour);\n                stream << ' ' << passOrFail;\n            }\n            stream << ':';\n        }\n    }\n\n    void printIssue(std::string const& issue) const {\n        stream << ' ' << issue;\n    }\n\n    void printExpressionWas() {\n        if (result.hasExpression()) {\n            stream << ';';\n            {\n                Colour colour(dimColour());\n                stream << \" expression was:\";\n            }\n            printOriginalExpression();\n        }\n    }\n\n    void printOriginalExpression() const {\n        if (result.hasExpression()) {\n            stream << ' ' << result.getExpression();\n        }\n    }\n\n    void printReconstructedExpression() const {\n        if (result.hasExpandedExpression()) {\n            {\n                Colour colour(dimColour());\n                stream << \" for: \";\n            }\n            stream << result.getExpandedExpression();\n        }\n    }\n\n    void printMessage() {\n        if (itMessage != messages.end()) {\n            stream << \" '\" << itMessage->message << '\\'';\n            ++itMessage;\n        }\n    }\n\n    void printRemainingMessages(Colour::Code colour = dimColour()) {\n        if (itMessage == messages.end())\n            return;\n\n        const auto itEnd = messages.cend();\n        const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));\n\n        {\n            Colour colourGuard(colour);\n            stream << \" with \" << pluralise(N, \"message\") << ':';\n        }\n\n        while (itMessage != itEnd) {\n            // If this assertion is a warning ignore any INFO messages\n            if (printInfoMessages || itMessage->type != ResultWas::Info) {\n                printMessage();\n                if (itMessage != itEnd) {\n                    Colour colourGuard(dimColour());\n                    stream << \" and\";\n                }\n                continue;\n            }\n            ++itMessage;\n        }\n    }\n\nprivate:\n    std::ostream& stream;\n    AssertionResult const& result;\n    std::vector<MessageInfo> messages;\n    std::vector<MessageInfo>::const_iterator itMessage;\n    bool printInfoMessages;\n};\n\n} // anon namespace\n\n        std::string CompactReporter::getDescription() {\n            return \"Reports test results on a single line, suitable for IDEs\";\n        }\n\n        void CompactReporter::noMatchingTestCases( std::string const& spec ) {\n            stream << \"No test cases matched '\" << spec << '\\'' << std::endl;\n        }\n\n        void CompactReporter::assertionStarting( AssertionInfo const& ) {}\n\n        bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {\n            AssertionResult const& result = _assertionStats.assertionResult;\n\n            bool printInfoMessages = true;\n\n            // Drop out if result was successful and we're not printing those\n            if( !m_config->includeSuccessfulResults() && result.isOk() ) {\n                if( result.getResultType() != ResultWas::Warning )\n                    return false;\n                printInfoMessages = false;\n            }\n\n            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );\n            printer.print();\n\n            stream << std::endl;\n            return true;\n        }\n\n        void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {\n            double dur = _sectionStats.durationInSeconds;\n            if ( shouldShowDuration( *m_config, dur ) ) {\n                stream << getFormattedDuration( dur ) << \" s: \" << _sectionStats.sectionInfo.name << std::endl;\n            }\n        }\n\n        void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {\n            printTotals( stream, _testRunStats.totals );\n            stream << '\\n' << std::endl;\n            StreamingReporterBase::testRunEnded( _testRunStats );\n        }\n\n        CompactReporter::~CompactReporter() {}\n\n    CATCH_REGISTER_REPORTER( \"compact\", CompactReporter )\n\n} // end namespace Catch\n// end catch_reporter_compact.cpp\n// start catch_reporter_console.cpp\n\n#include <cfloat>\n#include <cstdio>\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch\n // Note that 4062 (not all labels are handled and default is missing) is enabled\n#endif\n\n#if defined(__clang__)\n#  pragma clang diagnostic push\n// For simplicity, benchmarking-only helpers are always enabled\n#  pragma clang diagnostic ignored \"-Wunused-function\"\n#endif\n\nnamespace Catch {\n\nnamespace {\n\n// Formatter impl for ConsoleReporter\nclass ConsoleAssertionPrinter {\npublic:\n    ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;\n    ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;\n    ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)\n        : stream(_stream),\n        stats(_stats),\n        result(_stats.assertionResult),\n        colour(Colour::None),\n        message(result.getMessage()),\n        messages(_stats.infoMessages),\n        printInfoMessages(_printInfoMessages) {\n        switch (result.getResultType()) {\n        case ResultWas::Ok:\n            colour = Colour::Success;\n            passOrFail = \"PASSED\";\n            //if( result.hasMessage() )\n            if (_stats.infoMessages.size() == 1)\n                messageLabel = \"with message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel = \"with messages\";\n            break;\n        case ResultWas::ExpressionFailed:\n            if (result.isOk()) {\n                colour = Colour::Success;\n                passOrFail = \"FAILED - but was ok\";\n            } else {\n                colour = Colour::Error;\n                passOrFail = \"FAILED\";\n            }\n            if (_stats.infoMessages.size() == 1)\n                messageLabel = \"with message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel = \"with messages\";\n            break;\n        case ResultWas::ThrewException:\n            colour = Colour::Error;\n            passOrFail = \"FAILED\";\n            messageLabel = \"due to unexpected exception with \";\n            if (_stats.infoMessages.size() == 1)\n                messageLabel += \"message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel += \"messages\";\n            break;\n        case ResultWas::FatalErrorCondition:\n            colour = Colour::Error;\n            passOrFail = \"FAILED\";\n            messageLabel = \"due to a fatal error condition\";\n            break;\n        case ResultWas::DidntThrowException:\n            colour = Colour::Error;\n            passOrFail = \"FAILED\";\n            messageLabel = \"because no exception was thrown where one was expected\";\n            break;\n        case ResultWas::Info:\n            messageLabel = \"info\";\n            break;\n        case ResultWas::Warning:\n            messageLabel = \"warning\";\n            break;\n        case ResultWas::ExplicitFailure:\n            passOrFail = \"FAILED\";\n            colour = Colour::Error;\n            if (_stats.infoMessages.size() == 1)\n                messageLabel = \"explicitly with message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel = \"explicitly with messages\";\n            break;\n            // These cases are here to prevent compiler warnings\n        case ResultWas::Unknown:\n        case ResultWas::FailureBit:\n        case ResultWas::Exception:\n            passOrFail = \"** internal error **\";\n            colour = Colour::Error;\n            break;\n        }\n    }\n\n    void print() const {\n        printSourceInfo();\n        if (stats.totals.assertions.total() > 0) {\n            printResultType();\n            printOriginalExpression();\n            printReconstructedExpression();\n        } else {\n            stream << '\\n';\n        }\n        printMessage();\n    }\n\nprivate:\n    void printResultType() const {\n        if (!passOrFail.empty()) {\n            Colour colourGuard(colour);\n            stream << passOrFail << \":\\n\";\n        }\n    }\n    void printOriginalExpression() const {\n        if (result.hasExpression()) {\n            Colour colourGuard(Colour::OriginalExpression);\n            stream << \"  \";\n            stream << result.getExpressionInMacro();\n            stream << '\\n';\n        }\n    }\n    void printReconstructedExpression() const {\n        if (result.hasExpandedExpression()) {\n            stream << \"with expansion:\\n\";\n            Colour colourGuard(Colour::ReconstructedExpression);\n            stream << Column(result.getExpandedExpression()).indent(2) << '\\n';\n        }\n    }\n    void printMessage() const {\n        if (!messageLabel.empty())\n            stream << messageLabel << ':' << '\\n';\n        for (auto const& msg : messages) {\n            // If this assertion is a warning ignore any INFO messages\n            if (printInfoMessages || msg.type != ResultWas::Info)\n                stream << Column(msg.message).indent(2) << '\\n';\n        }\n    }\n    void printSourceInfo() const {\n        Colour colourGuard(Colour::FileName);\n        stream << result.getSourceInfo() << \": \";\n    }\n\n    std::ostream& stream;\n    AssertionStats const& stats;\n    AssertionResult const& result;\n    Colour::Code colour;\n    std::string passOrFail;\n    std::string messageLabel;\n    std::string message;\n    std::vector<MessageInfo> messages;\n    bool printInfoMessages;\n};\n\nstd::size_t makeRatio(std::size_t number, std::size_t total) {\n    std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;\n    return (ratio == 0 && number > 0) ? 1 : ratio;\n}\n\nstd::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {\n    if (i > j && i > k)\n        return i;\n    else if (j > k)\n        return j;\n    else\n        return k;\n}\n\nstruct ColumnInfo {\n    enum Justification { Left, Right };\n    std::string name;\n    int width;\n    Justification justification;\n};\nstruct ColumnBreak {};\nstruct RowBreak {};\n\nclass Duration {\n    enum class Unit {\n        Auto,\n        Nanoseconds,\n        Microseconds,\n        Milliseconds,\n        Seconds,\n        Minutes\n    };\n    static const uint64_t s_nanosecondsInAMicrosecond = 1000;\n    static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;\n    static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;\n    static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;\n\n    double m_inNanoseconds;\n    Unit m_units;\n\npublic:\n    explicit Duration(double inNanoseconds, Unit units = Unit::Auto)\n        : m_inNanoseconds(inNanoseconds),\n        m_units(units) {\n        if (m_units == Unit::Auto) {\n            if (m_inNanoseconds < s_nanosecondsInAMicrosecond)\n                m_units = Unit::Nanoseconds;\n            else if (m_inNanoseconds < s_nanosecondsInAMillisecond)\n                m_units = Unit::Microseconds;\n            else if (m_inNanoseconds < s_nanosecondsInASecond)\n                m_units = Unit::Milliseconds;\n            else if (m_inNanoseconds < s_nanosecondsInAMinute)\n                m_units = Unit::Seconds;\n            else\n                m_units = Unit::Minutes;\n        }\n\n    }\n\n    auto value() const -> double {\n        switch (m_units) {\n        case Unit::Microseconds:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);\n        case Unit::Milliseconds:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);\n        case Unit::Seconds:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);\n        case Unit::Minutes:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);\n        default:\n            return m_inNanoseconds;\n        }\n    }\n    auto unitsAsString() const -> std::string {\n        switch (m_units) {\n        case Unit::Nanoseconds:\n            return \"ns\";\n        case Unit::Microseconds:\n            return \"us\";\n        case Unit::Milliseconds:\n            return \"ms\";\n        case Unit::Seconds:\n            return \"s\";\n        case Unit::Minutes:\n            return \"m\";\n        default:\n            return \"** internal error **\";\n        }\n\n    }\n    friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {\n        return os << duration.value() << ' ' << duration.unitsAsString();\n    }\n};\n} // end anon namespace\n\nclass TablePrinter {\n    std::ostream& m_os;\n    std::vector<ColumnInfo> m_columnInfos;\n    std::ostringstream m_oss;\n    int m_currentColumn = -1;\n    bool m_isOpen = false;\n\npublic:\n    TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )\n    :   m_os( os ),\n        m_columnInfos( std::move( columnInfos ) ) {}\n\n    auto columnInfos() const -> std::vector<ColumnInfo> const& {\n        return m_columnInfos;\n    }\n\n    void open() {\n        if (!m_isOpen) {\n            m_isOpen = true;\n            *this << RowBreak();\n\n\t\t\tColumns headerCols;\n\t\t\tSpacer spacer(2);\n\t\t\tfor (auto const& info : m_columnInfos) {\n\t\t\t\theaderCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));\n\t\t\t\theaderCols += spacer;\n\t\t\t}\n\t\t\tm_os << headerCols << '\\n';\n\n            m_os << Catch::getLineOfChars<'-'>() << '\\n';\n        }\n    }\n    void close() {\n        if (m_isOpen) {\n            *this << RowBreak();\n            m_os << std::endl;\n            m_isOpen = false;\n        }\n    }\n\n    template<typename T>\n    friend TablePrinter& operator << (TablePrinter& tp, T const& value) {\n        tp.m_oss << value;\n        return tp;\n    }\n\n    friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {\n        auto colStr = tp.m_oss.str();\n        const auto strSize = colStr.size();\n        tp.m_oss.str(\"\");\n        tp.open();\n        if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {\n            tp.m_currentColumn = -1;\n            tp.m_os << '\\n';\n        }\n        tp.m_currentColumn++;\n\n        auto colInfo = tp.m_columnInfos[tp.m_currentColumn];\n        auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))\n            ? std::string(colInfo.width - (strSize + 1), ' ')\n            : std::string();\n        if (colInfo.justification == ColumnInfo::Left)\n            tp.m_os << colStr << padding << ' ';\n        else\n            tp.m_os << padding << colStr << ' ';\n        return tp;\n    }\n\n    friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {\n        if (tp.m_currentColumn > 0) {\n            tp.m_os << '\\n';\n            tp.m_currentColumn = -1;\n        }\n        return tp;\n    }\n};\n\nConsoleReporter::ConsoleReporter(ReporterConfig const& config)\n    : StreamingReporterBase(config),\n    m_tablePrinter(new TablePrinter(config.stream(),\n        [&config]() -> std::vector<ColumnInfo> {\n        if (config.fullConfig()->benchmarkNoAnalysis())\n        {\n            return{\n                { \"benchmark name\", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },\n                { \"     samples\", 14, ColumnInfo::Right },\n                { \"  iterations\", 14, ColumnInfo::Right },\n                { \"        mean\", 14, ColumnInfo::Right }\n            };\n        }\n        else\n        {\n            return{\n                { \"benchmark name\", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },\n                { \"samples      mean       std dev\", 14, ColumnInfo::Right },\n                { \"iterations   low mean   low std dev\", 14, ColumnInfo::Right },\n                { \"estimated    high mean  high std dev\", 14, ColumnInfo::Right }\n            };\n        }\n    }())) {}\nConsoleReporter::~ConsoleReporter() = default;\n\nstd::string ConsoleReporter::getDescription() {\n    return \"Reports test results as plain lines of text\";\n}\n\nvoid ConsoleReporter::noMatchingTestCases(std::string const& spec) {\n    stream << \"No test cases matched '\" << spec << '\\'' << std::endl;\n}\n\nvoid ConsoleReporter::reportInvalidArguments(std::string const&arg){\n    stream << \"Invalid Filter: \" << arg << std::endl;\n}\n\nvoid ConsoleReporter::assertionStarting(AssertionInfo const&) {}\n\nbool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {\n    AssertionResult const& result = _assertionStats.assertionResult;\n\n    bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();\n\n    // Drop out if result was successful but we're not printing them.\n    if (!includeResults && result.getResultType() != ResultWas::Warning)\n        return false;\n\n    lazyPrint();\n\n    ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);\n    printer.print();\n    stream << std::endl;\n    return true;\n}\n\nvoid ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {\n    m_tablePrinter->close();\n    m_headerPrinted = false;\n    StreamingReporterBase::sectionStarting(_sectionInfo);\n}\nvoid ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {\n    m_tablePrinter->close();\n    if (_sectionStats.missingAssertions) {\n        lazyPrint();\n        Colour colour(Colour::ResultError);\n        if (m_sectionStack.size() > 1)\n            stream << \"\\nNo assertions in section\";\n        else\n            stream << \"\\nNo assertions in test case\";\n        stream << \" '\" << _sectionStats.sectionInfo.name << \"'\\n\" << std::endl;\n    }\n    double dur = _sectionStats.durationInSeconds;\n    if (shouldShowDuration(*m_config, dur)) {\n        stream << getFormattedDuration(dur) << \" s: \" << _sectionStats.sectionInfo.name << std::endl;\n    }\n    if (m_headerPrinted) {\n        m_headerPrinted = false;\n    }\n    StreamingReporterBase::sectionEnded(_sectionStats);\n}\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\nvoid ConsoleReporter::benchmarkPreparing(std::string const& name) {\n\tlazyPrintWithoutClosingBenchmarkTable();\n\n\tauto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));\n\n\tbool firstLine = true;\n\tfor (auto line : nameCol) {\n\t\tif (!firstLine)\n\t\t\t(*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();\n\t\telse\n\t\t\tfirstLine = false;\n\n\t\t(*m_tablePrinter) << line << ColumnBreak();\n\t}\n}\n\nvoid ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {\n    (*m_tablePrinter) << info.samples << ColumnBreak()\n        << info.iterations << ColumnBreak();\n    if (!m_config->benchmarkNoAnalysis())\n        (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();\n}\nvoid ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {\n    if (m_config->benchmarkNoAnalysis())\n    {\n        (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();\n    }\n    else\n    {\n        (*m_tablePrinter) << ColumnBreak()\n            << Duration(stats.mean.point.count()) << ColumnBreak()\n            << Duration(stats.mean.lower_bound.count()) << ColumnBreak()\n            << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()\n            << Duration(stats.standardDeviation.point.count()) << ColumnBreak()\n            << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()\n            << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();\n    }\n}\n\nvoid ConsoleReporter::benchmarkFailed(std::string const& error) {\n\tColour colour(Colour::Red);\n    (*m_tablePrinter)\n        << \"Benchmark failed (\" << error << ')'\n        << ColumnBreak() << RowBreak();\n}\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\nvoid ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {\n    m_tablePrinter->close();\n    StreamingReporterBase::testCaseEnded(_testCaseStats);\n    m_headerPrinted = false;\n}\nvoid ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {\n    if (currentGroupInfo.used) {\n        printSummaryDivider();\n        stream << \"Summary for group '\" << _testGroupStats.groupInfo.name << \"':\\n\";\n        printTotals(_testGroupStats.totals);\n        stream << '\\n' << std::endl;\n    }\n    StreamingReporterBase::testGroupEnded(_testGroupStats);\n}\nvoid ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {\n    printTotalsDivider(_testRunStats.totals);\n    printTotals(_testRunStats.totals);\n    stream << std::endl;\n    StreamingReporterBase::testRunEnded(_testRunStats);\n}\nvoid ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {\n    StreamingReporterBase::testRunStarting(_testInfo);\n    printTestFilters();\n}\n\nvoid ConsoleReporter::lazyPrint() {\n\n    m_tablePrinter->close();\n    lazyPrintWithoutClosingBenchmarkTable();\n}\n\nvoid ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {\n\n    if (!currentTestRunInfo.used)\n        lazyPrintRunInfo();\n    if (!currentGroupInfo.used)\n        lazyPrintGroupInfo();\n\n    if (!m_headerPrinted) {\n        printTestCaseAndSectionHeader();\n        m_headerPrinted = true;\n    }\n}\nvoid ConsoleReporter::lazyPrintRunInfo() {\n    stream << '\\n' << getLineOfChars<'~'>() << '\\n';\n    Colour colour(Colour::SecondaryText);\n    stream << currentTestRunInfo->name\n        << \" is a Catch v\" << libraryVersion() << \" host application.\\n\"\n        << \"Run with -? for options\\n\\n\";\n\n    if (m_config->rngSeed() != 0)\n        stream << \"Randomness seeded to: \" << m_config->rngSeed() << \"\\n\\n\";\n\n    currentTestRunInfo.used = true;\n}\nvoid ConsoleReporter::lazyPrintGroupInfo() {\n    if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {\n        printClosedHeader(\"Group: \" + currentGroupInfo->name);\n        currentGroupInfo.used = true;\n    }\n}\nvoid ConsoleReporter::printTestCaseAndSectionHeader() {\n    assert(!m_sectionStack.empty());\n    printOpenHeader(currentTestCaseInfo->name);\n\n    if (m_sectionStack.size() > 1) {\n        Colour colourGuard(Colour::Headers);\n\n        auto\n            it = m_sectionStack.begin() + 1, // Skip first section (test case)\n            itEnd = m_sectionStack.end();\n        for (; it != itEnd; ++it)\n            printHeaderString(it->name, 2);\n    }\n\n    SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;\n\n    stream << getLineOfChars<'-'>() << '\\n';\n    Colour colourGuard(Colour::FileName);\n    stream << lineInfo << '\\n';\n    stream << getLineOfChars<'.'>() << '\\n' << std::endl;\n}\n\nvoid ConsoleReporter::printClosedHeader(std::string const& _name) {\n    printOpenHeader(_name);\n    stream << getLineOfChars<'.'>() << '\\n';\n}\nvoid ConsoleReporter::printOpenHeader(std::string const& _name) {\n    stream << getLineOfChars<'-'>() << '\\n';\n    {\n        Colour colourGuard(Colour::Headers);\n        printHeaderString(_name);\n    }\n}\n\n// if string has a : in first line will set indent to follow it on\n// subsequent lines\nvoid ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {\n    std::size_t i = _string.find(\": \");\n    if (i != std::string::npos)\n        i += 2;\n    else\n        i = 0;\n    stream << Column(_string).indent(indent + i).initialIndent(indent) << '\\n';\n}\n\nstruct SummaryColumn {\n\n    SummaryColumn( std::string _label, Colour::Code _colour )\n    :   label( std::move( _label ) ),\n        colour( _colour ) {}\n    SummaryColumn addRow( std::size_t count ) {\n        ReusableStringStream rss;\n        rss << count;\n        std::string row = rss.str();\n        for (auto& oldRow : rows) {\n            while (oldRow.size() < row.size())\n                oldRow = ' ' + oldRow;\n            while (oldRow.size() > row.size())\n                row = ' ' + row;\n        }\n        rows.push_back(row);\n        return *this;\n    }\n\n    std::string label;\n    Colour::Code colour;\n    std::vector<std::string> rows;\n\n};\n\nvoid ConsoleReporter::printTotals( Totals const& totals ) {\n    if (totals.testCases.total() == 0) {\n        stream << Colour(Colour::Warning) << \"No tests ran\\n\";\n    } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {\n        stream << Colour(Colour::ResultSuccess) << \"All tests passed\";\n        stream << \" (\"\n            << pluralise(totals.assertions.passed, \"assertion\") << \" in \"\n            << pluralise(totals.testCases.passed, \"test case\") << ')'\n            << '\\n';\n    } else {\n\n        std::vector<SummaryColumn> columns;\n        columns.push_back(SummaryColumn(\"\", Colour::None)\n                          .addRow(totals.testCases.total())\n                          .addRow(totals.assertions.total()));\n        columns.push_back(SummaryColumn(\"passed\", Colour::Success)\n                          .addRow(totals.testCases.passed)\n                          .addRow(totals.assertions.passed));\n        columns.push_back(SummaryColumn(\"failed\", Colour::ResultError)\n                          .addRow(totals.testCases.failed)\n                          .addRow(totals.assertions.failed));\n        columns.push_back(SummaryColumn(\"failed as expected\", Colour::ResultExpectedFailure)\n                          .addRow(totals.testCases.failedButOk)\n                          .addRow(totals.assertions.failedButOk));\n\n        printSummaryRow(\"test cases\", columns, 0);\n        printSummaryRow(\"assertions\", columns, 1);\n    }\n}\nvoid ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {\n    for (auto col : cols) {\n        std::string value = col.rows[row];\n        if (col.label.empty()) {\n            stream << label << \": \";\n            if (value != \"0\")\n                stream << value;\n            else\n                stream << Colour(Colour::Warning) << \"- none -\";\n        } else if (value != \"0\") {\n            stream << Colour(Colour::LightGrey) << \" | \";\n            stream << Colour(col.colour)\n                << value << ' ' << col.label;\n        }\n    }\n    stream << '\\n';\n}\n\nvoid ConsoleReporter::printTotalsDivider(Totals const& totals) {\n    if (totals.testCases.total() > 0) {\n        std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());\n        std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());\n        std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());\n        while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)\n            findMax(failedRatio, failedButOkRatio, passedRatio)++;\n        while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)\n            findMax(failedRatio, failedButOkRatio, passedRatio)--;\n\n        stream << Colour(Colour::Error) << std::string(failedRatio, '=');\n        stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');\n        if (totals.testCases.allPassed())\n            stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');\n        else\n            stream << Colour(Colour::Success) << std::string(passedRatio, '=');\n    } else {\n        stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');\n    }\n    stream << '\\n';\n}\nvoid ConsoleReporter::printSummaryDivider() {\n    stream << getLineOfChars<'-'>() << '\\n';\n}\n\nvoid ConsoleReporter::printTestFilters() {\n    if (m_config->testSpec().hasFilters()) {\n        Colour guard(Colour::BrightYellow);\n        stream << \"Filters: \" << serializeFilters(m_config->getTestsOrTags()) << '\\n';\n    }\n}\n\nCATCH_REGISTER_REPORTER(\"console\", ConsoleReporter)\n\n} // end namespace Catch\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n#if defined(__clang__)\n#  pragma clang diagnostic pop\n#endif\n// end catch_reporter_console.cpp\n// start catch_reporter_junit.cpp\n\n#include <cassert>\n#include <sstream>\n#include <ctime>\n#include <algorithm>\n#include <iomanip>\n\nnamespace Catch {\n\n    namespace {\n        std::string getCurrentTimestamp() {\n            // Beware, this is not reentrant because of backward compatibility issues\n            // Also, UTC only, again because of backward compatibility (%z is C++11)\n            time_t rawtime;\n            std::time(&rawtime);\n            auto const timeStampSize = sizeof(\"2017-01-16T17:06:45Z\");\n\n#ifdef _MSC_VER\n            std::tm timeInfo = {};\n            gmtime_s(&timeInfo, &rawtime);\n#else\n            std::tm* timeInfo;\n            timeInfo = std::gmtime(&rawtime);\n#endif\n\n            char timeStamp[timeStampSize];\n            const char * const fmt = \"%Y-%m-%dT%H:%M:%SZ\";\n\n#ifdef _MSC_VER\n            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);\n#else\n            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);\n#endif\n            return std::string(timeStamp, timeStampSize-1);\n        }\n\n        std::string fileNameTag(const std::vector<std::string> &tags) {\n            auto it = std::find_if(begin(tags),\n                                   end(tags),\n                                   [] (std::string const& tag) {return tag.front() == '#'; });\n            if (it != tags.end())\n                return it->substr(1);\n            return std::string();\n        }\n\n        // Formats the duration in seconds to 3 decimal places.\n        // This is done because some genius defined Maven Surefire schema\n        // in a way that only accepts 3 decimal places, and tools like\n        // Jenkins use that schema for validation JUnit reporter output.\n        std::string formatDuration( double seconds ) {\n            ReusableStringStream rss;\n            rss << std::fixed << std::setprecision( 3 ) << seconds;\n            return rss.str();\n        }\n\n    } // anonymous namespace\n\n    JunitReporter::JunitReporter( ReporterConfig const& _config )\n        :   CumulativeReporterBase( _config ),\n            xml( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = true;\n            m_reporterPrefs.shouldReportAllAssertions = true;\n        }\n\n    JunitReporter::~JunitReporter() {}\n\n    std::string JunitReporter::getDescription() {\n        return \"Reports test results in an XML format that looks like Ant's junitreport target\";\n    }\n\n    void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}\n\n    void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {\n        CumulativeReporterBase::testRunStarting( runInfo );\n        xml.startElement( \"testsuites\" );\n    }\n\n    void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {\n        suiteTimer.start();\n        stdOutForSuite.clear();\n        stdErrForSuite.clear();\n        unexpectedExceptions = 0;\n        CumulativeReporterBase::testGroupStarting( groupInfo );\n    }\n\n    void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {\n        m_okToFail = testCaseInfo.okToFail();\n    }\n\n    bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {\n        if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )\n            unexpectedExceptions++;\n        return CumulativeReporterBase::assertionEnded( assertionStats );\n    }\n\n    void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        stdOutForSuite += testCaseStats.stdOut;\n        stdErrForSuite += testCaseStats.stdErr;\n        CumulativeReporterBase::testCaseEnded( testCaseStats );\n    }\n\n    void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        double suiteTime = suiteTimer.getElapsedSeconds();\n        CumulativeReporterBase::testGroupEnded( testGroupStats );\n        writeGroup( *m_testGroups.back(), suiteTime );\n    }\n\n    void JunitReporter::testRunEndedCumulative() {\n        xml.endElement();\n    }\n\n    void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {\n        XmlWriter::ScopedElement e = xml.scopedElement( \"testsuite\" );\n\n        TestGroupStats const& stats = groupNode.value;\n        xml.writeAttribute( \"name\", stats.groupInfo.name );\n        xml.writeAttribute( \"errors\", unexpectedExceptions );\n        xml.writeAttribute( \"failures\", stats.totals.assertions.failed-unexpectedExceptions );\n        xml.writeAttribute( \"tests\", stats.totals.assertions.total() );\n        xml.writeAttribute( \"hostname\", \"tbd\" ); // !TBD\n        if( m_config->showDurations() == ShowDurations::Never )\n            xml.writeAttribute( \"time\", \"\" );\n        else\n            xml.writeAttribute( \"time\", formatDuration( suiteTime ) );\n        xml.writeAttribute( \"timestamp\", getCurrentTimestamp() );\n\n        // Write properties if there are any\n        if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {\n            auto properties = xml.scopedElement(\"properties\");\n            if (m_config->hasTestFilters()) {\n                xml.scopedElement(\"property\")\n                    .writeAttribute(\"name\", \"filters\")\n                    .writeAttribute(\"value\", serializeFilters(m_config->getTestsOrTags()));\n            }\n            if (m_config->rngSeed() != 0) {\n                xml.scopedElement(\"property\")\n                    .writeAttribute(\"name\", \"random-seed\")\n                    .writeAttribute(\"value\", m_config->rngSeed());\n            }\n        }\n\n        // Write test cases\n        for( auto const& child : groupNode.children )\n            writeTestCase( *child );\n\n        xml.scopedElement( \"system-out\" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );\n        xml.scopedElement( \"system-err\" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );\n    }\n\n    void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {\n        TestCaseStats const& stats = testCaseNode.value;\n\n        // All test cases have exactly one section - which represents the\n        // test case itself. That section may have 0-n nested sections\n        assert( testCaseNode.children.size() == 1 );\n        SectionNode const& rootSection = *testCaseNode.children.front();\n\n        std::string className = stats.testInfo.className;\n\n        if( className.empty() ) {\n            className = fileNameTag(stats.testInfo.tags);\n            if ( className.empty() )\n                className = \"global\";\n        }\n\n        if ( !m_config->name().empty() )\n            className = m_config->name() + \".\" + className;\n\n        writeSection( className, \"\", rootSection, stats.testInfo.okToFail() );\n    }\n\n    void JunitReporter::writeSection( std::string const& className,\n                                      std::string const& rootName,\n                                      SectionNode const& sectionNode,\n                                      bool testOkToFail) {\n        std::string name = trim( sectionNode.stats.sectionInfo.name );\n        if( !rootName.empty() )\n            name = rootName + '/' + name;\n\n        if( !sectionNode.assertions.empty() ||\n            !sectionNode.stdOut.empty() ||\n            !sectionNode.stdErr.empty() ) {\n            XmlWriter::ScopedElement e = xml.scopedElement( \"testcase\" );\n            if( className.empty() ) {\n                xml.writeAttribute( \"classname\", name );\n                xml.writeAttribute( \"name\", \"root\" );\n            }\n            else {\n                xml.writeAttribute( \"classname\", className );\n                xml.writeAttribute( \"name\", name );\n            }\n            xml.writeAttribute( \"time\", formatDuration( sectionNode.stats.durationInSeconds ) );\n            // This is not ideal, but it should be enough to mimic gtest's\n            // junit output.\n            // Ideally the JUnit reporter would also handle `skipTest`\n            // events and write those out appropriately.\n            xml.writeAttribute( \"status\", \"run\" );\n\n            if (sectionNode.stats.assertions.failedButOk) {\n                xml.scopedElement(\"skipped\")\n                    .writeAttribute(\"message\", \"TEST_CASE tagged with !mayfail\");\n            }\n\n            writeAssertions( sectionNode );\n\n            if( !sectionNode.stdOut.empty() )\n                xml.scopedElement( \"system-out\" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );\n            if( !sectionNode.stdErr.empty() )\n                xml.scopedElement( \"system-err\" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );\n        }\n        for( auto const& childNode : sectionNode.childSections )\n            if( className.empty() )\n                writeSection( name, \"\", *childNode, testOkToFail );\n            else\n                writeSection( className, name, *childNode, testOkToFail );\n    }\n\n    void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {\n        for( auto const& assertion : sectionNode.assertions )\n            writeAssertion( assertion );\n    }\n\n    void JunitReporter::writeAssertion( AssertionStats const& stats ) {\n        AssertionResult const& result = stats.assertionResult;\n        if( !result.isOk() ) {\n            std::string elementName;\n            switch( result.getResultType() ) {\n                case ResultWas::ThrewException:\n                case ResultWas::FatalErrorCondition:\n                    elementName = \"error\";\n                    break;\n                case ResultWas::ExplicitFailure:\n                case ResultWas::ExpressionFailed:\n                case ResultWas::DidntThrowException:\n                    elementName = \"failure\";\n                    break;\n\n                // We should never see these here:\n                case ResultWas::Info:\n                case ResultWas::Warning:\n                case ResultWas::Ok:\n                case ResultWas::Unknown:\n                case ResultWas::FailureBit:\n                case ResultWas::Exception:\n                    elementName = \"internalError\";\n                    break;\n            }\n\n            XmlWriter::ScopedElement e = xml.scopedElement( elementName );\n\n            xml.writeAttribute( \"message\", result.getExpression() );\n            xml.writeAttribute( \"type\", result.getTestMacroName() );\n\n            ReusableStringStream rss;\n            if (stats.totals.assertions.total() > 0) {\n                rss << \"FAILED\" << \":\\n\";\n                if (result.hasExpression()) {\n                    rss << \"  \";\n                    rss << result.getExpressionInMacro();\n                    rss << '\\n';\n                }\n                if (result.hasExpandedExpression()) {\n                    rss << \"with expansion:\\n\";\n                    rss << Column(result.getExpandedExpression()).indent(2) << '\\n';\n                }\n            } else {\n                rss << '\\n';\n            }\n\n            if( !result.getMessage().empty() )\n                rss << result.getMessage() << '\\n';\n            for( auto const& msg : stats.infoMessages )\n                if( msg.type == ResultWas::Info )\n                    rss << msg.message << '\\n';\n\n            rss << \"at \" << result.getSourceInfo();\n            xml.writeText( rss.str(), XmlFormatting::Newline );\n        }\n    }\n\n    CATCH_REGISTER_REPORTER( \"junit\", JunitReporter )\n\n} // end namespace Catch\n// end catch_reporter_junit.cpp\n// start catch_reporter_listening.cpp\n\n#include <cassert>\n\nnamespace Catch {\n\n    ListeningReporter::ListeningReporter() {\n        // We will assume that listeners will always want all assertions\n        m_preferences.shouldReportAllAssertions = true;\n    }\n\n    void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {\n        m_listeners.push_back( std::move( listener ) );\n    }\n\n    void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {\n        assert(!m_reporter && \"Listening reporter can wrap only 1 real reporter\");\n        m_reporter = std::move( reporter );\n        m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;\n    }\n\n    ReporterPreferences ListeningReporter::getPreferences() const {\n        return m_preferences;\n    }\n\n    std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {\n        return std::set<Verbosity>{ };\n    }\n\n    void ListeningReporter::noMatchingTestCases( std::string const& spec ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->noMatchingTestCases( spec );\n        }\n        m_reporter->noMatchingTestCases( spec );\n    }\n\n    void ListeningReporter::reportInvalidArguments(std::string const&arg){\n        for ( auto const& listener : m_listeners ) {\n            listener->reportInvalidArguments( arg );\n        }\n        m_reporter->reportInvalidArguments( arg );\n    }\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    void ListeningReporter::benchmarkPreparing( std::string const& name ) {\n\t\tfor (auto const& listener : m_listeners) {\n\t\t\tlistener->benchmarkPreparing(name);\n\t\t}\n\t\tm_reporter->benchmarkPreparing(name);\n\t}\n    void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->benchmarkStarting( benchmarkInfo );\n        }\n        m_reporter->benchmarkStarting( benchmarkInfo );\n    }\n    void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->benchmarkEnded( benchmarkStats );\n        }\n        m_reporter->benchmarkEnded( benchmarkStats );\n    }\n\n\tvoid ListeningReporter::benchmarkFailed( std::string const& error ) {\n\t\tfor (auto const& listener : m_listeners) {\n\t\t\tlistener->benchmarkFailed(error);\n\t\t}\n\t\tm_reporter->benchmarkFailed(error);\n\t}\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testRunStarting( testRunInfo );\n        }\n        m_reporter->testRunStarting( testRunInfo );\n    }\n\n    void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testGroupStarting( groupInfo );\n        }\n        m_reporter->testGroupStarting( groupInfo );\n    }\n\n    void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testCaseStarting( testInfo );\n        }\n        m_reporter->testCaseStarting( testInfo );\n    }\n\n    void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->sectionStarting( sectionInfo );\n        }\n        m_reporter->sectionStarting( sectionInfo );\n    }\n\n    void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->assertionStarting( assertionInfo );\n        }\n        m_reporter->assertionStarting( assertionInfo );\n    }\n\n    // The return value indicates if the messages buffer should be cleared:\n    bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {\n        for( auto const& listener : m_listeners ) {\n            static_cast<void>( listener->assertionEnded( assertionStats ) );\n        }\n        return m_reporter->assertionEnded( assertionStats );\n    }\n\n    void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->sectionEnded( sectionStats );\n        }\n        m_reporter->sectionEnded( sectionStats );\n    }\n\n    void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testCaseEnded( testCaseStats );\n        }\n        m_reporter->testCaseEnded( testCaseStats );\n    }\n\n    void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testGroupEnded( testGroupStats );\n        }\n        m_reporter->testGroupEnded( testGroupStats );\n    }\n\n    void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testRunEnded( testRunStats );\n        }\n        m_reporter->testRunEnded( testRunStats );\n    }\n\n    void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->skipTest( testInfo );\n        }\n        m_reporter->skipTest( testInfo );\n    }\n\n    bool ListeningReporter::isMulti() const {\n        return true;\n    }\n\n} // end namespace Catch\n// end catch_reporter_listening.cpp\n// start catch_reporter_xml.cpp\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch\n                              // Note that 4062 (not all labels are handled\n                              // and default is missing) is enabled\n#endif\n\nnamespace Catch {\n    XmlReporter::XmlReporter( ReporterConfig const& _config )\n    :   StreamingReporterBase( _config ),\n        m_xml(_config.stream())\n    {\n        m_reporterPrefs.shouldRedirectStdOut = true;\n        m_reporterPrefs.shouldReportAllAssertions = true;\n    }\n\n    XmlReporter::~XmlReporter() = default;\n\n    std::string XmlReporter::getDescription() {\n        return \"Reports test results as an XML document\";\n    }\n\n    std::string XmlReporter::getStylesheetRef() const {\n        return std::string();\n    }\n\n    void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {\n        m_xml\n            .writeAttribute( \"filename\", sourceInfo.file )\n            .writeAttribute( \"line\", sourceInfo.line );\n    }\n\n    void XmlReporter::noMatchingTestCases( std::string const& s ) {\n        StreamingReporterBase::noMatchingTestCases( s );\n    }\n\n    void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {\n        StreamingReporterBase::testRunStarting( testInfo );\n        std::string stylesheetRef = getStylesheetRef();\n        if( !stylesheetRef.empty() )\n            m_xml.writeStylesheetRef( stylesheetRef );\n        m_xml.startElement( \"Catch\" );\n        if( !m_config->name().empty() )\n            m_xml.writeAttribute( \"name\", m_config->name() );\n        if (m_config->testSpec().hasFilters())\n            m_xml.writeAttribute( \"filters\", serializeFilters( m_config->getTestsOrTags() ) );\n        if( m_config->rngSeed() != 0 )\n            m_xml.scopedElement( \"Randomness\" )\n                .writeAttribute( \"seed\", m_config->rngSeed() );\n    }\n\n    void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {\n        StreamingReporterBase::testGroupStarting( groupInfo );\n        m_xml.startElement( \"Group\" )\n            .writeAttribute( \"name\", groupInfo.name );\n    }\n\n    void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {\n        StreamingReporterBase::testCaseStarting(testInfo);\n        m_xml.startElement( \"TestCase\" )\n            .writeAttribute( \"name\", trim( testInfo.name ) )\n            .writeAttribute( \"description\", testInfo.description )\n            .writeAttribute( \"tags\", testInfo.tagsAsString() );\n\n        writeSourceInfo( testInfo.lineInfo );\n\n        if ( m_config->showDurations() == ShowDurations::Always )\n            m_testCaseTimer.start();\n        m_xml.ensureTagClosed();\n    }\n\n    void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {\n        StreamingReporterBase::sectionStarting( sectionInfo );\n        if( m_sectionDepth++ > 0 ) {\n            m_xml.startElement( \"Section\" )\n                .writeAttribute( \"name\", trim( sectionInfo.name ) );\n            writeSourceInfo( sectionInfo.lineInfo );\n            m_xml.ensureTagClosed();\n        }\n    }\n\n    void XmlReporter::assertionStarting( AssertionInfo const& ) { }\n\n    bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {\n\n        AssertionResult const& result = assertionStats.assertionResult;\n\n        bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();\n\n        if( includeResults || result.getResultType() == ResultWas::Warning ) {\n            // Print any info messages in <Info> tags.\n            for( auto const& msg : assertionStats.infoMessages ) {\n                if( msg.type == ResultWas::Info && includeResults ) {\n                    m_xml.scopedElement( \"Info\" )\n                            .writeText( msg.message );\n                } else if ( msg.type == ResultWas::Warning ) {\n                    m_xml.scopedElement( \"Warning\" )\n                            .writeText( msg.message );\n                }\n            }\n        }\n\n        // Drop out if result was successful but we're not printing them.\n        if( !includeResults && result.getResultType() != ResultWas::Warning )\n            return true;\n\n        // Print the expression if there is one.\n        if( result.hasExpression() ) {\n            m_xml.startElement( \"Expression\" )\n                .writeAttribute( \"success\", result.succeeded() )\n                .writeAttribute( \"type\", result.getTestMacroName() );\n\n            writeSourceInfo( result.getSourceInfo() );\n\n            m_xml.scopedElement( \"Original\" )\n                .writeText( result.getExpression() );\n            m_xml.scopedElement( \"Expanded\" )\n                .writeText( result.getExpandedExpression() );\n        }\n\n        // And... Print a result applicable to each result type.\n        switch( result.getResultType() ) {\n            case ResultWas::ThrewException:\n                m_xml.startElement( \"Exception\" );\n                writeSourceInfo( result.getSourceInfo() );\n                m_xml.writeText( result.getMessage() );\n                m_xml.endElement();\n                break;\n            case ResultWas::FatalErrorCondition:\n                m_xml.startElement( \"FatalErrorCondition\" );\n                writeSourceInfo( result.getSourceInfo() );\n                m_xml.writeText( result.getMessage() );\n                m_xml.endElement();\n                break;\n            case ResultWas::Info:\n                m_xml.scopedElement( \"Info\" )\n                    .writeText( result.getMessage() );\n                break;\n            case ResultWas::Warning:\n                // Warning will already have been written\n                break;\n            case ResultWas::ExplicitFailure:\n                m_xml.startElement( \"Failure\" );\n                writeSourceInfo( result.getSourceInfo() );\n                m_xml.writeText( result.getMessage() );\n                m_xml.endElement();\n                break;\n            default:\n                break;\n        }\n\n        if( result.hasExpression() )\n            m_xml.endElement();\n\n        return true;\n    }\n\n    void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {\n        StreamingReporterBase::sectionEnded( sectionStats );\n        if( --m_sectionDepth > 0 ) {\n            XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResults\" );\n            e.writeAttribute( \"successes\", sectionStats.assertions.passed );\n            e.writeAttribute( \"failures\", sectionStats.assertions.failed );\n            e.writeAttribute( \"expectedFailures\", sectionStats.assertions.failedButOk );\n\n            if ( m_config->showDurations() == ShowDurations::Always )\n                e.writeAttribute( \"durationInSeconds\", sectionStats.durationInSeconds );\n\n            m_xml.endElement();\n        }\n    }\n\n    void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        StreamingReporterBase::testCaseEnded( testCaseStats );\n        XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResult\" );\n        e.writeAttribute( \"success\", testCaseStats.totals.assertions.allOk() );\n\n        if ( m_config->showDurations() == ShowDurations::Always )\n            e.writeAttribute( \"durationInSeconds\", m_testCaseTimer.getElapsedSeconds() );\n\n        if( !testCaseStats.stdOut.empty() )\n            m_xml.scopedElement( \"StdOut\" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );\n        if( !testCaseStats.stdErr.empty() )\n            m_xml.scopedElement( \"StdErr\" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );\n\n        m_xml.endElement();\n    }\n\n    void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        StreamingReporterBase::testGroupEnded( testGroupStats );\n        // TODO: Check testGroupStats.aborting and act accordingly.\n        m_xml.scopedElement( \"OverallResults\" )\n            .writeAttribute( \"successes\", testGroupStats.totals.assertions.passed )\n            .writeAttribute( \"failures\", testGroupStats.totals.assertions.failed )\n            .writeAttribute( \"expectedFailures\", testGroupStats.totals.assertions.failedButOk );\n        m_xml.scopedElement( \"OverallResultsCases\")\n            .writeAttribute( \"successes\", testGroupStats.totals.testCases.passed )\n            .writeAttribute( \"failures\", testGroupStats.totals.testCases.failed )\n            .writeAttribute( \"expectedFailures\", testGroupStats.totals.testCases.failedButOk );\n        m_xml.endElement();\n    }\n\n    void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {\n        StreamingReporterBase::testRunEnded( testRunStats );\n        m_xml.scopedElement( \"OverallResults\" )\n            .writeAttribute( \"successes\", testRunStats.totals.assertions.passed )\n            .writeAttribute( \"failures\", testRunStats.totals.assertions.failed )\n            .writeAttribute( \"expectedFailures\", testRunStats.totals.assertions.failedButOk );\n        m_xml.scopedElement( \"OverallResultsCases\")\n            .writeAttribute( \"successes\", testRunStats.totals.testCases.passed )\n            .writeAttribute( \"failures\", testRunStats.totals.testCases.failed )\n            .writeAttribute( \"expectedFailures\", testRunStats.totals.testCases.failedButOk );\n        m_xml.endElement();\n    }\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    void XmlReporter::benchmarkPreparing(std::string const& name) {\n        m_xml.startElement(\"BenchmarkResults\")\n            .writeAttribute(\"name\", name);\n    }\n\n    void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {\n        m_xml.writeAttribute(\"samples\", info.samples)\n            .writeAttribute(\"resamples\", info.resamples)\n            .writeAttribute(\"iterations\", info.iterations)\n            .writeAttribute(\"clockResolution\", info.clockResolution)\n            .writeAttribute(\"estimatedDuration\", info.estimatedDuration)\n            .writeComment(\"All values in nano seconds\");\n    }\n\n    void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {\n        m_xml.startElement(\"mean\")\n            .writeAttribute(\"value\", benchmarkStats.mean.point.count())\n            .writeAttribute(\"lowerBound\", benchmarkStats.mean.lower_bound.count())\n            .writeAttribute(\"upperBound\", benchmarkStats.mean.upper_bound.count())\n            .writeAttribute(\"ci\", benchmarkStats.mean.confidence_interval);\n        m_xml.endElement();\n        m_xml.startElement(\"standardDeviation\")\n            .writeAttribute(\"value\", benchmarkStats.standardDeviation.point.count())\n            .writeAttribute(\"lowerBound\", benchmarkStats.standardDeviation.lower_bound.count())\n            .writeAttribute(\"upperBound\", benchmarkStats.standardDeviation.upper_bound.count())\n            .writeAttribute(\"ci\", benchmarkStats.standardDeviation.confidence_interval);\n        m_xml.endElement();\n        m_xml.startElement(\"outliers\")\n            .writeAttribute(\"variance\", benchmarkStats.outlierVariance)\n            .writeAttribute(\"lowMild\", benchmarkStats.outliers.low_mild)\n            .writeAttribute(\"lowSevere\", benchmarkStats.outliers.low_severe)\n            .writeAttribute(\"highMild\", benchmarkStats.outliers.high_mild)\n            .writeAttribute(\"highSevere\", benchmarkStats.outliers.high_severe);\n        m_xml.endElement();\n        m_xml.endElement();\n    }\n\n    void XmlReporter::benchmarkFailed(std::string const &error) {\n        m_xml.scopedElement(\"failed\").\n            writeAttribute(\"message\", error);\n        m_xml.endElement();\n    }\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    CATCH_REGISTER_REPORTER( \"xml\", XmlReporter )\n\n} // end namespace Catch\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n// end catch_reporter_xml.cpp\n\nnamespace Catch {\n    LeakDetector leakDetector;\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_impl.hpp\n#endif\n\n#ifdef CATCH_CONFIG_MAIN\n// start catch_default_main.hpp\n\n#ifndef __OBJC__\n\n#ifndef CATCH_INTERNAL_CDECL\n#ifdef _MSC_VER\n#define CATCH_INTERNAL_CDECL __cdecl\n#else\n#define CATCH_INTERNAL_CDECL\n#endif\n#endif\n\n#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)\n// Standard C/C++ Win32 Unicode wmain entry point\nextern \"C\" int CATCH_INTERNAL_CDECL wmain (int argc, wchar_t * argv[], wchar_t * []) {\n#else\n// Standard C/C++ main entry point\nint CATCH_INTERNAL_CDECL main (int argc, char * argv[]) {\n#endif\n\n    return Catch::Session().run( argc, argv );\n}\n\n#else // __OBJC__\n\n// Objective-C entry point\nint main (int argc, char * const argv[]) {\n#if !CATCH_ARC_ENABLED\n    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];\n#endif\n\n    Catch::registerTestMethods();\n    int result = Catch::Session().run( argc, (char**)argv );\n\n#if !CATCH_ARC_ENABLED\n    [pool drain];\n#endif\n\n    return result;\n}\n\n#endif // __OBJC__\n\n// end catch_default_main.hpp\n#endif\n\n#if !defined(CATCH_CONFIG_IMPL_ONLY)\n\n#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED\n#  undef CLARA_CONFIG_MAIN\n#endif\n\n#if !defined(CATCH_CONFIG_DISABLE)\n//////\n// If this config identifier is defined then all CATCH macros are prefixed with CATCH_\n#ifdef CATCH_CONFIG_PREFIX_ALL\n\n#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( \"CATCH_REQUIRE\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( \"CATCH_REQUIRE_FALSE\", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n\n#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( \"CATCH_REQUIRE_THROWS\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"CATCH_REQUIRE_THROWS_AS\", exceptionType, Catch::ResultDisposition::Normal, expr )\n#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"CATCH_REQUIRE_THROWS_WITH\", Catch::ResultDisposition::Normal, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"CATCH_REQUIRE_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )\n#endif// CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"CATCH_REQUIRE_NOTHROW\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n\n#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( \"CATCH_CHECK\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( \"CATCH_CHECK_FALSE\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( \"CATCH_CHECKED_IF\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( \"CATCH_CHECKED_ELSE\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( \"CATCH_CHECK_NOFAIL\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )\n\n#define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( \"CATCH_CHECK_THROWS\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"CATCH_CHECK_THROWS_AS\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )\n#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"CATCH_CHECK_THROWS_WITH\", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"CATCH_CHECK_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"CATCH_CHECK_NOTHROW\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"CATCH_CHECK_THAT\", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )\n\n#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"CATCH_REQUIRE_THAT\", matcher, Catch::ResultDisposition::Normal, arg )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( \"CATCH_INFO\", msg )\n#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( \"CATCH_UNSCOPED_INFO\", msg )\n#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( \"CATCH_WARN\", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )\n#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), \"CATCH_CAPTURE\",__VA_ARGS__ )\n\n#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )\n#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( \"CATCH_FAIL\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( \"CATCH_FAIL_CHECK\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( \"CATCH_SUCCEED\", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n\n#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#else\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#endif\n\n#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)\n#define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ )\n#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), \"!(\" #__VA_ARGS__ \")\" ); CATCH_SUCCEED( #__VA_ARGS__ )\n#else\n#define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ )\n#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )\n#endif\n\n// \"BDD-style\" convenience wrappers\n#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n#define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( \"    Given: \" << desc )\n#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( \"And given: \" << desc )\n#define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     When: \" << desc )\n#define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \" And when: \" << desc )\n#define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     Then: \" << desc )\n#define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \"      And: \" << desc )\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n#define CATCH_BENCHMARK(...) \\\n    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))\n#define CATCH_BENCHMARK_ADVANCED(name) \\\n    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required\n#else\n\n#define REQUIRE( ... ) INTERNAL_CATCH_TEST( \"REQUIRE\", Catch::ResultDisposition::Normal, __VA_ARGS__  )\n#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( \"REQUIRE_FALSE\", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n\n#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( \"REQUIRE_THROWS\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"REQUIRE_THROWS_AS\", exceptionType, Catch::ResultDisposition::Normal, expr )\n#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"REQUIRE_THROWS_WITH\", Catch::ResultDisposition::Normal, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"REQUIRE_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"REQUIRE_NOTHROW\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n\n#define CHECK( ... ) INTERNAL_CATCH_TEST( \"CHECK\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( \"CHECK_FALSE\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( \"CHECKED_IF\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( \"CHECKED_ELSE\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( \"CHECK_NOFAIL\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )\n\n#define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( \"CHECK_THROWS\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"CHECK_THROWS_AS\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )\n#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"CHECK_THROWS_WITH\", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"CHECK_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"CHECK_NOTHROW\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"CHECK_THAT\", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )\n\n#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"REQUIRE_THAT\", matcher, Catch::ResultDisposition::Normal, arg )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define INFO( msg ) INTERNAL_CATCH_INFO( \"INFO\", msg )\n#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( \"UNSCOPED_INFO\", msg )\n#define WARN( msg ) INTERNAL_CATCH_MSG( \"WARN\", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )\n#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), \"CAPTURE\",__VA_ARGS__ )\n\n#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )\n#define FAIL( ... ) INTERNAL_CATCH_MSG( \"FAIL\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( \"FAIL_CHECK\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define SUCCEED( ... ) INTERNAL_CATCH_MSG( \"SUCCEED\", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)\n#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#else\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )\n#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#endif\n\n#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)\n#define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )\n#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), \"!(\" #__VA_ARGS__ \")\" ); SUCCEED( \"!(\" #__VA_ARGS__ \")\" )\n#else\n#define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ )\n#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )\n#endif\n\n#endif\n\n#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )\n\n// \"BDD-style\" convenience wrappers\n#define SCENARIO( ... ) TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n\n#define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( \"    Given: \" << desc )\n#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( \"And given: \" << desc )\n#define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     When: \" << desc )\n#define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \" And when: \" << desc )\n#define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     Then: \" << desc )\n#define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \"      And: \" << desc )\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n#define BENCHMARK(...) \\\n    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))\n#define BENCHMARK_ADVANCED(name) \\\n    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\nusing Catch::Detail::Approx;\n\n#else // CATCH_CONFIG_DISABLE\n\n//////\n// If this config identifier is defined then all CATCH macros are prefixed with CATCH_\n#ifdef CATCH_CONFIG_PREFIX_ALL\n\n#define CATCH_REQUIRE( ... )        (void)(0)\n#define CATCH_REQUIRE_FALSE( ... )  (void)(0)\n\n#define CATCH_REQUIRE_THROWS( ... ) (void)(0)\n#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)\n#define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif// CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)\n\n#define CATCH_CHECK( ... )         (void)(0)\n#define CATCH_CHECK_FALSE( ... )   (void)(0)\n#define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)\n#define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))\n#define CATCH_CHECK_NOFAIL( ... )  (void)(0)\n\n#define CATCH_CHECK_THROWS( ... )  (void)(0)\n#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)\n#define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_CHECK_NOTHROW( ... ) (void)(0)\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THAT( arg, matcher )   (void)(0)\n\n#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define CATCH_INFO( msg )          (void)(0)\n#define CATCH_UNSCOPED_INFO( msg ) (void)(0)\n#define CATCH_WARN( msg )          (void)(0)\n#define CATCH_CAPTURE( msg )       (void)(0)\n\n#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define CATCH_METHOD_AS_TEST_CASE( method, ... )\n#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)\n#define CATCH_SECTION( ... )\n#define CATCH_DYNAMIC_SECTION( ... )\n#define CATCH_FAIL( ... ) (void)(0)\n#define CATCH_FAIL_CHECK( ... ) (void)(0)\n#define CATCH_SUCCEED( ... ) (void)(0)\n\n#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#else\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#endif\n\n// \"BDD-style\" convenience wrappers\n#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )\n#define CATCH_GIVEN( desc )\n#define CATCH_AND_GIVEN( desc )\n#define CATCH_WHEN( desc )\n#define CATCH_AND_WHEN( desc )\n#define CATCH_THEN( desc )\n#define CATCH_AND_THEN( desc )\n\n#define CATCH_STATIC_REQUIRE( ... )       (void)(0)\n#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)\n\n// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required\n#else\n\n#define REQUIRE( ... )       (void)(0)\n#define REQUIRE_FALSE( ... ) (void)(0)\n\n#define REQUIRE_THROWS( ... ) (void)(0)\n#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)\n#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define REQUIRE_NOTHROW( ... ) (void)(0)\n\n#define CHECK( ... ) (void)(0)\n#define CHECK_FALSE( ... ) (void)(0)\n#define CHECKED_IF( ... ) if (__VA_ARGS__)\n#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))\n#define CHECK_NOFAIL( ... ) (void)(0)\n\n#define CHECK_THROWS( ... )  (void)(0)\n#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)\n#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CHECK_NOTHROW( ... ) (void)(0)\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THAT( arg, matcher ) (void)(0)\n\n#define REQUIRE_THAT( arg, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define INFO( msg ) (void)(0)\n#define UNSCOPED_INFO( msg ) (void)(0)\n#define WARN( msg ) (void)(0)\n#define CAPTURE( ... ) (void)(0)\n\n#define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define METHOD_AS_TEST_CASE( method, ... )\n#define REGISTER_TEST_CASE( Function, ... ) (void)(0)\n#define SECTION( ... )\n#define DYNAMIC_SECTION( ... )\n#define FAIL( ... ) (void)(0)\n#define FAIL_CHECK( ... ) (void)(0)\n#define SUCCEED( ... ) (void)(0)\n#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#else\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#endif\n\n#define STATIC_REQUIRE( ... )       (void)(0)\n#define STATIC_REQUIRE_FALSE( ... ) (void)(0)\n\n#endif\n\n#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )\n\n// \"BDD-style\" convenience wrappers\n#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) )\n#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )\n\n#define GIVEN( desc )\n#define AND_GIVEN( desc )\n#define WHEN( desc )\n#define AND_WHEN( desc )\n#define THEN( desc )\n#define AND_THEN( desc )\n\nusing Catch::Detail::Approx;\n\n#endif\n\n#endif // ! CATCH_CONFIG_IMPL_ONLY\n\n// start catch_reenable_warnings.h\n\n\n#ifdef __clang__\n#    ifdef __ICC // icpc defines the __clang__ macro\n#        pragma warning(pop)\n#    else\n#        pragma clang diagnostic pop\n#    endif\n#elif defined __GNUC__\n#    pragma GCC diagnostic pop\n#endif\n\n// end catch_reenable_warnings.h\n// end catch.hpp\n#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n"
  },
  {
    "path": "test/unit/makefile",
    "content": "# Build all the unit tests using GNU make and either g++ or clang\n# Should be run using mingw32-make on Windows, not nmake\n# On Windows g++ is used, on macOS clang, and on Linux G++ is used by default\n# but clang can be used by defining CLANG when invoking make\n# clang works only with libc++, not libstdc++\n# Tested with clang 9 and g++ 9\n\nCXXSTD=c++17\n\nifndef windir\nifeq ($(shell uname),Darwin)\n# On macOS always use clang as g++ is old version\nCLANG = 1\nUSELIBCPP = 1\nendif\nendif\n\nCXXFLAGS += --std=$(CXXSTD)\n\nifdef CLANG\nCXX = clang++\nifdef USELIBCPP\n# macOS, use libc++ but don't have sanitizers\nCXXFLAGS += --stdlib=libc++\nelse\n# Linux, have sanitizers\nSANITIZE = -fsanitize=address,undefined\nCXXFLAGS += $(SANITIZE)\nendif\nelse\nCXX = g++\nendif\n\nifdef windir\nDEL = del /q\nEXE = unitTest.exe\nelse\nDEL = rm -f\nEXE = unitTest\nendif\n\nvpath %.cxx ../../lexlib\n\nINCLUDEDIRS = -I ../../include -I../../lexlib -I../../../scintilla/include\n\nCPPFLAGS += $(INCLUDEDIRS)\nCXXFLAGS += -Wall -Wextra\n\n# Files in this directory containing tests\nTESTSRC=$(wildcard test*.cxx)\nTESTOBJ=$(TESTSRC:.cxx=.o)\n\n# Files being tested from lexilla/lexlib directory\nTESTEDOBJ=\\\n Accessor.o \\\n CharacterSet.o \\\n InList.o \\\n LexerBase.o \\\n LexerModule.o \\\n LexerSimple.o \\\n PropSetSimple.o \\\n WordList.o\n\nTESTS=$(EXE)\n\nall: $(TESTS)\n\ntest: $(TESTS)\n\t./$(EXE)\n\nclean:\n\t$(DEL) $(TESTS) *.o *.obj *.exe\n\n%.o: %.cxx\n\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@\n\n$(EXE): unitTest.o $(TESTOBJ) $(TESTEDOBJ)\n\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LINKFLAGS) $^ -o $@\n"
  },
  {
    "path": "test/unit/test.mak",
    "content": "# Build all the unit tests with Microsoft Visual C++ using nmake\n# Tested with Visual C++ 2022\n\nDEL = del /q\nEXE = unitTest.exe\n\nINCLUDEDIRS = /I../../include /I../../lexlib /I../../../scintilla/include\n\nCXXFLAGS = /MP /EHsc /std:c++17 /D_HAS_AUTO_PTR_ETC=1 /wd 4805 $(INCLUDEDIRS)\n\n# Files in this directory containing tests\nTESTSRC=test*.cxx\n# Files being tested from lexilla/lexlib directory\nTESTEDSRC=\\\n ../../lexlib/Accessor.cxx \\\n ../../lexlib/CharacterSet.cxx \\\n ../../lexlib/InList.cxx \\\n ../../lexlib/LexerBase.cxx \\\n ../../lexlib/LexerModule.cxx \\\n ../../lexlib/LexerSimple.cxx \\\n ../../lexlib/PropSetSimple.cxx \\\n ../../lexlib/WordList.cxx\n\nTESTS=$(EXE)\n\nall: $(TESTS)\n\ntest: $(TESTS)\n\t$(EXE)\n\nclean:\n\t$(DEL) $(TESTS) *.o *.obj *.exe\n\n$(EXE): $(TESTSRC) $(TESTEDSRC) $(@B).cxx\n\t$(CXX) $(CXXFLAGS) /Fe$@ $**\n"
  },
  {
    "path": "test/unit/testCharacterSet.cxx",
    "content": "/** @file testCharacterSet.cxx\n ** Unit Tests for Lexilla internal data structures\n **/\n\n#include <cstdlib>\n#include <cassert>\n\n#include <string_view>\n\n#include \"CharacterSet.h\"\n\n#include \"catch.hpp\"\n\nusing namespace Lexilla;\n\n// Test CharacterSet.\n\nTEST_CASE(\"CharacterSet\") {\n\n\tSECTION(\"IsEmptyInitially\") {\n\t\tCharacterSet cs;\n\t\tfor (int i=0; i<0x80; i++) {\n\t\t\tREQUIRE(!cs.Contains(i));\n\t\t}\n\t}\n\n\tSECTION(\"InitialSet\") {\n\t\tCharacterSet cs(CharacterSet::setDigits);\n\t\tfor (int i=0; i<0x80; i++) {\n\t\t\tif (i >= '0' && i <= '9')\n\t\t\t\tREQUIRE(cs.Contains(i));\n\t\t\telse\n\t\t\t\tREQUIRE(!cs.Contains(i));\n\t\t}\n\t}\n\n\tSECTION(\"Set\") {\n\t\tCharacterSet cs;\n\t\tcs.Add('a');\n\t\tfor (int i=0; i<0x80; i++) {\n\t\t\tif (i == 'a')\n\t\t\t\tREQUIRE(cs.Contains(i));\n\t\t\telse\n\t\t\t\tREQUIRE(!cs.Contains(i));\n\t\t}\n\t}\n\n\tSECTION(\"After\") {\n\t\tCharacterSet cs;\n\t\tREQUIRE(!cs.Contains(0x100));\n\t\tCharacterSet cs2(CharacterSet::setNone, \"\", 0x80, true);\n\t\tREQUIRE(cs2.Contains(0x100));\n\t}\n}\n\nTEST_CASE(\"Functions\") {\n\n\tSECTION(\"IsASpace\") {\n\t\tREQUIRE(IsASpace(' '));\n\t\tREQUIRE(!IsASpace('a'));\n\n\t\tREQUIRE(IsASpaceOrTab(' '));\n\t\tREQUIRE(!IsASpaceOrTab('a'));\n\t}\n\n\tSECTION(\"IsADigit\") {\n\t\tREQUIRE(!IsADigit(' '));\n\t\tREQUIRE(!IsADigit('a'));\n\t\tREQUIRE(IsADigit('7'));\n\n\t\tREQUIRE(IsADigit('7', 16));\n\t\tREQUIRE(IsADigit('A', 16));\n\t\tREQUIRE(IsADigit('a', 16));\n\t\tREQUIRE(!IsADigit('8', 8));\n\t}\n\n\tSECTION(\"IsASCII\") {\n\t\tREQUIRE(IsASCII(' '));\n\t\tREQUIRE(IsASCII('a'));\n\t\tREQUIRE(!IsASCII(-1));\n\t\tREQUIRE(!IsASCII(128));\n\t}\n\n\tSECTION(\"IsUpperOrLowerCase\") {\n\t\tREQUIRE(IsLowerCase('a'));\n\t\tREQUIRE(!IsLowerCase('A'));\n\n\t\tREQUIRE(!IsUpperCase('a'));\n\t\tREQUIRE(IsUpperCase('A'));\n\n\t\tREQUIRE(IsUpperOrLowerCase('a'));\n\t\tREQUIRE(IsUpperOrLowerCase('A'));\n\t\tREQUIRE(!IsUpperOrLowerCase('9'));\n\n\t\tREQUIRE(IsAlphaNumeric('9'));\n\t\tREQUIRE(IsAlphaNumeric('a'));\n\t\tREQUIRE(IsAlphaNumeric('A'));\n\t\tREQUIRE(!IsAlphaNumeric(' '));\n\t\tREQUIRE(!IsAlphaNumeric('+'));\n\t}\n\n\tSECTION(\"isoperator\") {\n\t\tREQUIRE(isspacechar(' '));\n\t\tREQUIRE(!isspacechar('a'));\n\n\t\tREQUIRE(!iswordchar(' '));\n\t\tREQUIRE(iswordchar('a'));\n\t\tREQUIRE(iswordchar('A'));\n\t\tREQUIRE(iswordchar('.'));\n\t\tREQUIRE(iswordchar('_'));\n\n\t\tREQUIRE(!iswordstart(' '));\n\t\tREQUIRE(iswordstart('a'));\n\t\tREQUIRE(iswordstart('A'));\n\t\tREQUIRE(iswordstart('_'));\n\n\t\tREQUIRE(!isoperator('a'));\n\t\tREQUIRE(isoperator('+'));\n\t}\n\n\tSECTION(\"MakeUpperCase\") {\n\t\tREQUIRE(MakeUpperCase(' ') == ' ');\n\t\tREQUIRE(MakeUpperCase('A') == 'A');\n\t\tREQUIRE(MakeUpperCase('a') == 'A');\n\n\t\tREQUIRE(MakeLowerCase(' ') == ' ');\n\t\tREQUIRE(MakeLowerCase('A') == 'a');\n\t\tREQUIRE(MakeLowerCase('a') == 'a');\n\t}\n\n\tSECTION(\"CompareCaseInsensitive\") {\n\t\tREQUIRE(CompareCaseInsensitive(\" \", \" \") == 0);\n\t\tREQUIRE(CompareCaseInsensitive(\"A\", \"A\") == 0);\n\t\tREQUIRE(CompareCaseInsensitive(\"a\", \"A\") == 0);\n\t\tREQUIRE(CompareCaseInsensitive(\"b\", \"A\") != 0);\n\t\tREQUIRE(CompareCaseInsensitive(\"aa\", \"A\") != 0);\n\n\t\tREQUIRE(CompareNCaseInsensitive(\" \", \" \", 1) == 0);\n\t\tREQUIRE(CompareNCaseInsensitive(\"b\", \"A\", 1) != 0);\n\t\tREQUIRE(CompareNCaseInsensitive(\"aa\", \"A\", 1) == 0);\n\t}\n\n\tSECTION(\"EqualCaseInsensitive\") {\n\t\tREQUIRE(EqualCaseInsensitive(\" \", \" \"));\n\t\tREQUIRE(EqualCaseInsensitive(\"A\", \"A\"));\n\t\tREQUIRE(EqualCaseInsensitive(\"a\", \"A\"));\n\t\tREQUIRE(!EqualCaseInsensitive(\"b\", \"A\"));\n\t\tREQUIRE(!EqualCaseInsensitive(\"aa\", \"A\"));\n\t\tREQUIRE(!EqualCaseInsensitive(\"a\", \"AA\"));\n\t}\n}\n"
  },
  {
    "path": "test/unit/testInList.cxx",
    "content": "/** @file testInList.cxx\n ** Unit Tests for Lexilla internal data structures\n **/\n\n#include <cstdlib>\n#include <cassert>\n\n#include <string_view>\n#include <initializer_list>\n\n#include \"InList.h\"\n\n#include \"catch.hpp\"\n\nusing namespace Lexilla;\n\n// Test InList.\n\nTEST_CASE(\"InList\") {\n\n\tSECTION(\"Basic\") {\n\t\tREQUIRE(InList(\"dog\", {\"cat\", \"dog\", \"frog\"}));\n\t\tREQUIRE(!InList(\"fly\", {\"cat\", \"dog\", \"frog\"}));\n\n\t\tREQUIRE(InListCaseInsensitive(\"DOG\", {\"cat\", \"dog\", \"frog\"}));\n\t\tREQUIRE(!InListCaseInsensitive(\"fly\", {\"cat\", \"dog\", \"frog\"}));\n\t}\n}\n"
  },
  {
    "path": "test/unit/testLexerSimple.cxx",
    "content": "/** @file testLexerSimple.cxx\n ** Unit Tests for Lexilla internal data structures\n **/\n\n#include <cassert>\n\n#include <string>\n#include <string_view>\n\n#include \"ILexer.h\"\n#include \"Scintilla.h\"\n\n#include \"PropSetSimple.h\"\n#include \"LexerModule.h\"\n#include \"LexerBase.h\"\n#include \"LexerSimple.h\"\n\n#include \"catch.hpp\"\n\nusing namespace Lexilla;\n\n// Test LexerSimple.\n\nnamespace {\n\nconstexpr const char *propertyName = \"lexer.tex.comment.process\";\nconstexpr const char *propertyValue = \"1\";\n\nvoid ColouriseDocument(Sci_PositionU, Sci_Position, int, WordList *[], Accessor &) {\n\t// Do no styling\n}\n\nLexerModule lmSimpleExample(123456, ColouriseDocument, \"simpleexample\");\n\n}\n\nTEST_CASE(\"LexerSimple\") {\n\n\tSECTION(\"Identifier\") {\n\t\tLexerSimple lexSimple(&lmSimpleExample);\n\t\tREQUIRE(lexSimple.GetIdentifier() == 123456);\n\t}\n\n\tSECTION(\"Identifier\") {\n\t\tLexerSimple lexSimple(&lmSimpleExample);\n\t\tREQUIRE_THAT(lexSimple.GetName(), Catch::Matchers::Equals(\"simpleexample\"));\n\t}\n\n\tSECTION(\"SetAndGet\") {\n\t\tLexerSimple lexSimple(&lmSimpleExample);\n\n\t\t// New setting -> 0\n\t\tconst Sci_Position pos0 = lexSimple.PropertySet(propertyName, \"8\");\n\t\tREQUIRE(pos0 == 0);\n\t\t// Changed setting -> 0\n\t\tconst Sci_Position pos1 = lexSimple.PropertySet(propertyName, propertyValue);\n\t\tREQUIRE(pos1 == 0);\n\t\t// Same setting -> -1\n\t\tconst Sci_Position pos2 = lexSimple.PropertySet(propertyName, propertyValue);\n\t\tREQUIRE(pos2 == -1);\n\n\t\tconst char *value = lexSimple.PropertyGet(propertyName);\n\t\tREQUIRE_THAT(propertyValue, Catch::Matchers::Equals(value));\n\t}\n\n}\n"
  },
  {
    "path": "test/unit/testOptionSet.cxx",
    "content": "/** @file testOptionSet.cxx\n ** Unit Tests for Lexilla internal data structures\n ** Tests OptionSet.\n **/\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n\n#include \"Scintilla.h\"\n\n#include \"OptionSet.h\"\n\n#include \"catch.hpp\"\n\nusing namespace Lexilla;\n\n// Test OptionSet.\n\nnamespace {\n\n// Simple example options structure with each type: string, bool, int\nstruct Options {\n\tstd::string so;\n\tbool bo = false;\n\tint io = 0;\n};\n\nconst char *const denseWordLists[] = {\n\t\"Keywords 1\",\n\t\"Keywords 2\",\n\t\"Keywords 3\",\n\t\"Keywords 4\",\n\tnullptr,\n};\n\nconst char *const sparseWordLists[] = {\n\t\"\",\n\t\"\",\n\t\"Keywords 1\",\n\t\"\",\n\t\"Keywords 2\",\n\tnullptr,\n};\n\n}\n\nusing Catch::Matchers::Equals;\n\nTEST_CASE(\"OptionSet\") {\n\n\tOptionSet<Options> os;\n\tOptions options;\n\n\tSECTION(\"IsEmptyInitially\") {\n\t\tREQUIRE_THAT(os.PropertyNames(), Equals(\"\"));\n\t}\n\n\tSECTION(\"MissingOption\") {\n\t\t// Check for not present option\n\t\tREQUIRE_FALSE(os.PropertyGet(\"missing\"));\n\t\tREQUIRE(SC_TYPE_BOOLEAN == os.PropertyType(\"missing\"));\n\t\tREQUIRE_FALSE(os.PropertySet(&options, \"missing\", \"1\"));\n\t}\n\n\tSECTION(\"Define\") {\n\t\tos.DefineProperty(\"string.option\", &Options::so, \"StringOption\");\n\t\tREQUIRE_THAT(os.PropertyGet(\"string.option\"), Equals(\"\"));\n\t\tREQUIRE(SC_TYPE_STRING == os.PropertyType(\"string.option\"));\n\t\tREQUIRE_THAT(os.DescribeProperty(\"string.option\"), Equals(\"StringOption\"));\n\n\t\tos.DefineProperty(\"bool.option\", &Options::bo, \"BoolOption\");\n\t\tREQUIRE_THAT(os.PropertyGet(\"bool.option\"), Equals(\"\"));\n\t\tREQUIRE(SC_TYPE_BOOLEAN == os.PropertyType(\"bool.option\"));\n\t\tREQUIRE_THAT(os.DescribeProperty(\"bool.option\"), Equals(\"BoolOption\"));\n\n\t\tos.DefineProperty(\"int.option\", &Options::io, \"IntOption\");\n\t\tREQUIRE_THAT(os.PropertyGet(\"int.option\"), Equals(\"\"));\n\t\tREQUIRE(SC_TYPE_INTEGER == os.PropertyType(\"int.option\"));\n\t\tREQUIRE_THAT(os.DescribeProperty(\"int.option\"), Equals(\"IntOption\"));\n\n\t\t// This is really a set and could be reordered but is currently in definition order\n\t\tREQUIRE_THAT(os.PropertyNames(), Equals(\"string.option\\nbool.option\\nint.option\"));\n\t}\n\n\tSECTION(\"Set\") {\n\t\tos.DefineProperty(\"string.option\", &Options::so, \"StringOption\");\n\t\tREQUIRE_THAT(os.PropertyGet(\"string.option\"), Equals(\"\"));\n\t\tREQUIRE(os.PropertySet(&options, \"string.option\", \"string\"));\n\t\tREQUIRE_THAT(os.PropertyGet(\"string.option\"), Equals(\"string\"));\n\t\t// Setting to same as before returns false\n\t\tREQUIRE_FALSE(os.PropertySet(&options, \"string.option\", \"string\"));\n\t\tREQUIRE(os.PropertySet(&options, \"string.option\", \"anotherString\"));\n\t\tREQUIRE_THAT(os.PropertyGet(\"string.option\"), Equals(\"anotherString\"));\n\n\t\tos.DefineProperty(\"bool.option\", &Options::so, \"BoolOption\");\n\t\tREQUIRE(os.PropertySet(&options, \"bool.option\", \"1\"));\n\t\tREQUIRE_THAT(os.PropertyGet(\"bool.option\"), Equals(\"1\"));\n\t\t// Setting to same as before returns false\n\t\tREQUIRE_FALSE(os.PropertySet(&options, \"bool.option\", \"1\"));\n\t\tREQUIRE(os.PropertySet(&options, \"bool.option\", \"0\"));\n\n\t\tos.DefineProperty(\"int.option\", &Options::so, \"IntOption\");\n\t\tREQUIRE(os.PropertySet(&options, \"int.option\", \"2\"));\n\t\tREQUIRE_THAT(os.PropertyGet(\"int.option\"), Equals(\"2\"));\n\t\t// Setting to same as before returns false\n\t\tREQUIRE_FALSE(os.PropertySet(&options, \"int.option\", \"2\"));\n\t\tREQUIRE(os.PropertySet(&options, \"int.option\", \"3\"));\n\t}\n\n\t// WordListSets feature is really completely separate from options\n\n\tSECTION(\"WordListSets\") {\n\t\tREQUIRE_THAT(os.DescribeWordListSets(), Equals(\"\"));\n\t\tos.DefineWordListSets(denseWordLists);\n\t\tREQUIRE_THAT(os.DescribeWordListSets(),\n\t\t\tEquals(\"Keywords 1\\nKeywords 2\\nKeywords 3\\nKeywords 4\"));\n\n\t\tOptionSet<Options> os2;\n\t\tREQUIRE_THAT(os2.DescribeWordListSets(), Equals(\"\"));\n\t\tos2.DefineWordListSets(sparseWordLists);\n\t\tREQUIRE_THAT(os2.DescribeWordListSets(),\n\t\t\tEquals(\"\\n\\nKeywords 1\\n\\nKeywords 2\"));\n\t}\n}\n"
  },
  {
    "path": "test/unit/testPropSetSimple.cxx",
    "content": "/** @file testPropSetSimple.cxx\n ** Unit Tests for Lexilla internal data structures\n **/\n\n#include <string>\n#include <string_view>\n\n#include \"PropSetSimple.h\"\n\n#include \"catch.hpp\"\n\nusing namespace Lexilla;\n\n// Test PropSetSimple.\n\nnamespace {\n\nconstexpr const char *propertyName = \"lexer.tex.comment.process\";\nconstexpr const char *propertyValue = \"1\";\n\n}\n\nTEST_CASE(\"PropSetSimple\") {\n\n\tSECTION(\"IsEmptyInitially\") {\n\t\tPropSetSimple pss;\n\t\tconst char *value = pss.Get(propertyName);\n\t\tREQUIRE_THAT(value, Catch::Matchers::Equals(\"\"));\n\t}\n\n\tSECTION(\"SetAndGet\") {\n\t\tPropSetSimple pss;\n\t\tpss.Set(propertyName, propertyValue);\n\t\tconst char *value = pss.Get(propertyName);\n\t\tREQUIRE_THAT(value, Catch::Matchers::Equals(propertyValue));\n\t}\n\n\tSECTION(\"GetInt\") {\n\t\tPropSetSimple pss;\n\t\tconst int valueStart = pss.GetInt(propertyName);\n\t\tREQUIRE(0 == valueStart);\n\t\tconst int valueDefault = pss.GetInt(propertyName, 3);\n\t\tREQUIRE(3 == valueDefault);\n\t\tpss.Set(propertyName, propertyValue);\n\t\tconst int value = pss.GetInt(propertyName);\n\t\tREQUIRE(1 == value);\n\t}\n\n}\n"
  },
  {
    "path": "test/unit/testSparseState.cxx",
    "content": "/** @file testSparseState.cxx\n ** Unit Tests for Lexilla internal data structures\n **/\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <algorithm>\n#include <memory>\n\n#include \"Sci_Position.h\"\n\n#include \"SparseState.h\"\n\n#include \"catch.hpp\"\n\nusing namespace Lexilla;\n\n// Test SparseState.\n\nTEST_CASE(\"SparseState\") {\n\n\tSparseState<int> ss;\n\n\tSECTION(\"IsEmptyInitially\") {\n\t\tREQUIRE(0u == ss.size());\n\t\tint val = ss.ValueAt(0);\n\t\tREQUIRE(0 == val);\n\t}\n\n\tSECTION(\"SimpleSetAndGet\") {\n\t\tss.Set(0, 22);\n\t\tss.Set(1, 23);\n\t\tREQUIRE(2u == ss.size());\n\t\tREQUIRE(0 == ss.ValueAt(-1));\n\t\tREQUIRE(22 == ss.ValueAt(0));\n\t\tREQUIRE(23 == ss.ValueAt(1));\n\t\tREQUIRE(23 == ss.ValueAt(2));\n\t}\n\n\tSECTION(\"RetrieveBetween\") {\n\t\tss.Set(0, 10);\n\t\tss.Set(2, 12);\n\t\tREQUIRE(2u == ss.size());\n\t\tREQUIRE(0 == ss.ValueAt(-1));\n\t\tREQUIRE(10 == ss.ValueAt(0));\n\t\tREQUIRE(10 == ss.ValueAt(1));\n\t\tREQUIRE(12 == ss.ValueAt(2));\n\t}\n\n\tSECTION(\"RetrieveBefore\") {\n\t\tss.Set(2, 12);\n\t\tREQUIRE(1u == ss.size());\n\t\tREQUIRE(0 == ss.ValueAt(-1));\n\t\tREQUIRE(0 == ss.ValueAt(0));\n\t\tREQUIRE(0 == ss.ValueAt(1));\n\t\tREQUIRE(12 == ss.ValueAt(2));\n\t}\n\n\tSECTION(\"Delete\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 32);\n\t\tss.Delete(2);\n\t\tREQUIRE(1u == ss.size());\n\t\tREQUIRE(0 == ss.ValueAt(-1));\n\t\tREQUIRE(30 == ss.ValueAt(0));\n\t\tREQUIRE(30 == ss.ValueAt(1));\n\t\tREQUIRE(30 == ss.ValueAt(2));\n\t}\n\n\tSECTION(\"DeleteBetween\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 32);\n\t\tss.Delete(1);\n\t\tREQUIRE(1u == ss.size());\n\t\tREQUIRE(0 == ss.ValueAt(-1));\n\t\tREQUIRE(30 == ss.ValueAt(0));\n\t\tREQUIRE(30 == ss.ValueAt(1));\n\t\tREQUIRE(30 == ss.ValueAt(2));\n\t}\n\n\tSECTION(\"ReplaceLast\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 31);\n\t\tss.Set(2, 32);\n\t\tREQUIRE(2u == ss.size());\n\t\tREQUIRE(0 == ss.ValueAt(-1));\n\t\tREQUIRE(30 == ss.ValueAt(0));\n\t\tREQUIRE(30 == ss.ValueAt(1));\n\t\tREQUIRE(32 == ss.ValueAt(2));\n\t\tREQUIRE(32 == ss.ValueAt(3));\n\t}\n\n\tSECTION(\"OnlyChangeAppended\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 31);\n\t\tss.Set(3, 31);\n\t\tREQUIRE(2u == ss.size());\n\t}\n\n\tSECTION(\"MergeBetween\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 32);\n\t\tss.Set(4, 34);\n\t\tREQUIRE(3u == ss.size());\n\n\t\tSparseState<int> ssAdditions(3);\n\t\tssAdditions.Set(4, 34);\n\t\tREQUIRE(1u == ssAdditions.size());\n\t\tbool mergeChanged = ss.Merge(ssAdditions,5);\n\t\tREQUIRE(false == mergeChanged);\n\n\t\tssAdditions.Set(4, 44);\n\t\tREQUIRE(1u == ssAdditions.size());\n\t\tmergeChanged = ss.Merge(ssAdditions,5);\n\t\tREQUIRE(true == mergeChanged);\n\t\tREQUIRE(3u == ss.size());\n\t\tREQUIRE(44 == ss.ValueAt(4));\n\t}\n\n\tSECTION(\"MergeAtExisting\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 32);\n\t\tss.Set(4, 34);\n\t\tREQUIRE(3u == ss.size());\n\n\t\tSparseState<int> ssAdditions(4);\n\t\tssAdditions.Set(4, 34);\n\t\tREQUIRE(1u == ssAdditions.size());\n\t\tbool mergeChanged = ss.Merge(ssAdditions,5);\n\t\tREQUIRE(false == mergeChanged);\n\n\t\tssAdditions.Set(4, 44);\n\t\tREQUIRE(1u == ssAdditions.size());\n\t\tmergeChanged = ss.Merge(ssAdditions,5);\n\t\tREQUIRE(true == mergeChanged);\n\t\tREQUIRE(3u == ss.size());\n\t\tREQUIRE(44 == ss.ValueAt(4));\n\t}\n\n\tSECTION(\"MergeWhichRemoves\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 32);\n\t\tss.Set(4, 34);\n\t\tREQUIRE(3u == ss.size());\n\n\t\tSparseState<int> ssAdditions(2);\n\t\tssAdditions.Set(2, 22);\n\t\tREQUIRE(1u == ssAdditions.size());\n\t\tREQUIRE(22 == ssAdditions.ValueAt(2));\n\t\tbool mergeChanged = ss.Merge(ssAdditions,5);\n\t\tREQUIRE(true == mergeChanged);\n\t\tREQUIRE(2u == ss.size());\n\t\tREQUIRE(22 == ss.ValueAt(2));\n\t}\n\n\tSECTION(\"MergeIgnoreSome\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 32);\n\t\tss.Set(4, 34);\n\n\t\tSparseState<int> ssAdditions(2);\n\t\tssAdditions.Set(2, 32);\n\t\tbool mergeChanged = ss.Merge(ssAdditions,3);\n\n\t\tREQUIRE(false == mergeChanged);\n\t\tREQUIRE(2u == ss.size());\n\t\tREQUIRE(32 == ss.ValueAt(2));\n\t}\n\n\tSECTION(\"MergeIgnoreSomeStart\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 32);\n\t\tss.Set(4, 34);\n\n\t\tSparseState<int> ssAdditions(2);\n\t\tssAdditions.Set(2, 32);\n\t\tbool mergeChanged = ss.Merge(ssAdditions,2);\n\n\t\tREQUIRE(false == mergeChanged);\n\t\tREQUIRE(2u == ss.size());\n\t\tREQUIRE(32 == ss.ValueAt(2));\n\t}\n\n\tSECTION(\"MergeIgnoreRepeat\") {\n\t\tss.Set(0, 30);\n\t\tss.Set(2, 32);\n\t\tss.Set(4, 34);\n\n\t\tSparseState<int> ssAdditions(5);\n\t\t// Appending same value as at end of pss.\n\t\tssAdditions.Set(5, 34);\n\t\tbool mergeChanged = ss.Merge(ssAdditions,6);\n\n\t\tREQUIRE(false == mergeChanged);\n\t\tREQUIRE(3u == ss.size());\n\t\tREQUIRE(34 == ss.ValueAt(4));\n\t}\n\n}\n\nTEST_CASE(\"SparseStateString\") {\n\n\tSparseState<std::string> ss;\n\n\tSECTION(\"IsEmptyInitially\") {\n\t\tREQUIRE(0u == ss.size());\n\t\tstd::string val = ss.ValueAt(0);\n\t\tREQUIRE(\"\" == val);\n\t}\n\n\tSECTION(\"SimpleSetAndGet\") {\n\t\tREQUIRE(0u == ss.size());\n\t\tss.Set(0, \"22\");\n\t\tss.Set(1, \"23\");\n\t\tREQUIRE(2u == ss.size());\n\t\tREQUIRE(\"\" == ss.ValueAt(-1));\n\t\tREQUIRE(\"22\" == ss.ValueAt(0));\n\t\tREQUIRE(\"23\" == ss.ValueAt(1));\n\t\tREQUIRE(\"23\" == ss.ValueAt(2));\n\t}\n\n\tSECTION(\"DeleteBetween\") {\n\t\tss.Set(0, \"30\");\n\t\tss.Set(2, \"32\");\n\t\tss.Delete(1);\n\t\tREQUIRE(1u == ss.size());\n\t\tREQUIRE(\"\" == ss.ValueAt(-1));\n\t\tREQUIRE(\"30\" == ss.ValueAt(0));\n\t\tREQUIRE(\"30\" == ss.ValueAt(1));\n\t\tREQUIRE(\"30\" == ss.ValueAt(2));\n\t}\n\n}\n"
  },
  {
    "path": "test/unit/testWordList.cxx",
    "content": "/** @file testWordList.cxx\n ** Unit Tests for Lexilla internal data structures\n ** Tests WordList, WordClassifier, and SubStyles\n **/\n\n#include <cassert>\n\n#include <string>\n#include <string_view>\n#include <vector>\n#include <map>\n\n#include \"WordList.h\"\n#include \"CharacterSet.h\"\n#include \"SubStyles.h\"\n\n#include \"catch.hpp\"\n\nusing namespace Lexilla;\n\n// Test WordList.\n\nTEST_CASE(\"WordList\") {\n\n\tWordList wl;\n\n\tSECTION(\"IsEmptyInitially\") {\n\t\tREQUIRE(0 == wl.Length());\n\t\tREQUIRE(!wl.InList(\"struct\"));\n\t}\n\n\tSECTION(\"InList\") {\n\t\twl.Set(\"else struct\");\n\t\tREQUIRE(2 == wl.Length());\n\t\tREQUIRE(wl.InList(\"struct\"));\n\t\tREQUIRE(!wl.InList(\"class\"));\n\t}\n\n\tSECTION(\"StringInList\") {\n\t\twl.Set(\"else struct\");\n\t\tstd::string sStruct = \"struct\";\n\t\tREQUIRE(wl.InList(sStruct));\n\t\tstd::string sClass = \"class\";\n\t\tREQUIRE(!wl.InList(sClass));\n\t}\n\n\tSECTION(\"StringViewInList\") {\n\t\twl.Set(\"else struct i ^gtk\");\n\t\tstd::string_view svStruct = \"struct\";\n\t\tREQUIRE(wl.InList(svStruct));\n\t\tstd::string_view svClass = \"class\";\n\t\tREQUIRE(!wl.InList(svClass));\n\n\t\t// Test single characters\n\t\tstd::string_view svI = \"i\";\n\t\tREQUIRE(wl.InList(svI));\n\t\tstd::string_view svA = \"a\";\n\t\tREQUIRE(!wl.InList(svA));\n\n\t\t// Test prefix\n\t\tstd::string_view svPrefix = \"gtk_prefix\";\n\t\tREQUIRE(wl.InList(svPrefix));\n\t}\n\n\tSECTION(\"InListUnicode\") {\n\t\t// \"cheese\" in English\n\t\t// \"kase\" ('k', 'a with diaeresis', 's', 'e') in German\n\t\t// \"syr\", ('CYRILLIC SMALL LETTER ES', 'CYRILLIC SMALL LETTER YERU', 'CYRILLIC SMALL LETTER ER') in Russian\n\t\twl.Set(\"cheese \\x6b\\xc3\\xa4\\x73\\x65 \\xd1\\x81\\xd1\\x8b\\xd1\\x80\");\n\t\tREQUIRE(3 == wl.Length());\n\t\tREQUIRE(wl.InList(\"cheese\"));\n\t\tREQUIRE(wl.InList(\"\\x6b\\xc3\\xa4\\x73\\x65\"));\n\t\tREQUIRE(wl.InList(\"\\xd1\\x81\\xd1\\x8b\\xd1\\x80\"));\n\t}\n\n\tSECTION(\"Set\") {\n\t\t// Check whether Set returns whether it has changed correctly\n\t\tconst bool changed = wl.Set(\"else struct\");\n\t\tREQUIRE(changed);\n\t\t// Changing to same thing\n\t\tconst bool changed2 = wl.Set(\"else struct\");\n\t\tREQUIRE(!changed2);\n\t\t// Changed order shouldn't be seen as a change\n\t\tconst bool changed3 = wl.Set(\"struct else\");\n\t\tREQUIRE(!changed3);\n\t\t// Removing word is a change\n\t\tconst bool changed4 = wl.Set(\"struct\");\n\t\tREQUIRE(changed4);\n\t}\n\n\tSECTION(\"WordAt\") {\n\t\twl.Set(\"else struct\");\n\t\tREQUIRE_THAT(wl.WordAt(0), Catch::Matchers::Equals(\"else\"));\n\t}\n\n\tSECTION(\"InListAbbreviated\") {\n\t\twl.Set(\"else stru~ct w~hile \\xd1\\x81~\\xd1\\x8b\\xd1\\x80\");\n\t\tREQUIRE(wl.InListAbbreviated(\"else\", '~'));\n\n\t\tREQUIRE(wl.InListAbbreviated(\"struct\", '~'));\n\t\tREQUIRE(wl.InListAbbreviated(\"stru\", '~'));\n\t\tREQUIRE(wl.InListAbbreviated(\"struc\", '~'));\n\t\tREQUIRE(!wl.InListAbbreviated(\"str\", '~'));\n\n\t\tREQUIRE(wl.InListAbbreviated(\"while\", '~'));\n\t\tREQUIRE(wl.InListAbbreviated(\"wh\", '~'));\n\t\t// TODO: Next line fails but should allow single character prefixes\n\t\t//REQUIRE(wl.InListAbbreviated(\"w\", '~'));\n\t\tREQUIRE(!wl.InListAbbreviated(\"\", '~'));\n\n\t\t// Russian syr\n\t\tREQUIRE(wl.InListAbbreviated(\"\\xd1\\x81\\xd1\\x8b\\xd1\\x80\", '~'));\n\t}\n\n\tSECTION(\"InListAbridged\") {\n\t\twl.Set(\"list w.~.active bo~k a~z ~_frozen \\xd1\\x81~\\xd1\\x80\");\n\t\tREQUIRE(wl.InListAbridged(\"list\", '~'));\n\n\t\tREQUIRE(wl.InListAbridged(\"w.front.active\", '~'));\n\t\tREQUIRE(wl.InListAbridged(\"w.x.active\", '~'));\n\t\tREQUIRE(wl.InListAbridged(\"w..active\", '~'));\n\t\tREQUIRE(!wl.InListAbridged(\"w.active\", '~'));\n\t\tREQUIRE(!wl.InListAbridged(\"w.x.closed\", '~'));\n\n\t\tREQUIRE(wl.InListAbridged(\"book\", '~'));\n\t\tREQUIRE(wl.InListAbridged(\"bok\", '~'));\n\t\tREQUIRE(!wl.InListAbridged(\"bk\", '~'));\n\n\t\tREQUIRE(wl.InListAbridged(\"a_frozen\", '~'));\n\t\tREQUIRE(wl.InListAbridged(\"_frozen\", '~'));\n\t\tREQUIRE(!wl.InListAbridged(\"frozen\", '~'));\n\n\t\tREQUIRE(wl.InListAbridged(\"abcz\", '~'));\n\t\tREQUIRE(wl.InListAbridged(\"abz\", '~'));\n\t\tREQUIRE(wl.InListAbridged(\"az\", '~'));\n\n\t\t// Russian syr\n\t\tREQUIRE(wl.InListAbridged(\"\\xd1\\x81\\xd1\\x8b\\xd1\\x80\", '~'));\n\t}\n}\n\n// Test WordClassifier.\n\nTEST_CASE(\"WordClassifier\") {\n\n\tconstexpr int base = 1;\n\tconstexpr int key = 10;\n\tconstexpr int type = 11;\n\tconstexpr int other = 40;\n\n\tWordClassifier wc(1);\n\n\tSECTION(\"Base\") {\n\t\tREQUIRE(wc.Base() == base);\n\t\twc.Allocate(key, 2);\n\t\tREQUIRE(wc.Start() == key);\n\t\tREQUIRE(wc.Last() == type);\n\t\tREQUIRE(wc.Length() == 2);\n\t\tREQUIRE(wc.IncludesStyle(key));\n\t\tREQUIRE(wc.IncludesStyle(type));\n\t\tREQUIRE(!wc.IncludesStyle(other));\n\n\t\twc.Clear();\n\t\tREQUIRE(wc.Base() == base);\n\t\tREQUIRE(wc.Start() == 0);\n\t\tREQUIRE(wc.Last() == -1);\n\t\tREQUIRE(wc.Length() == 0);\n\t}\n\n\tSECTION(\"ValueFor\") {\n\t\twc.Allocate(key, 2);\n\t\twc.SetIdentifiers(key, \"else if then\", false);\n\t\twc.SetIdentifiers(type, \"double float int long\", false);\n\t\tREQUIRE(wc.ValueFor(\"if\") == key);\n\t\tREQUIRE(wc.ValueFor(\"double\") == type);\n\t\tREQUIRE(wc.ValueFor(\"fish\") < 0);\n\t\twc.RemoveStyle(type);\n\t\tREQUIRE(wc.ValueFor(\"double\") < 0);\n\t}\n\n}\n\n// Test SubStyles.\n\nTEST_CASE(\"SubStyles\") {\n\n\tconstexpr char bases[] = \"\\002\\005\";\n\tconstexpr int base = 2;\n\tconstexpr int base2 = 5;\n\tconstexpr int styleFirst = 0x80;\n\tconstexpr int stylesAvailable = 0x40;\n\tconstexpr int distanceToSecondary = 0x40;\n\n\tSubStyles subStyles(bases, styleFirst, stylesAvailable, distanceToSecondary);\n\n\tSECTION(\"All\") {\n\t\tREQUIRE(subStyles.DistanceToSecondaryStyles() == distanceToSecondary);\n\t\t// Before allocation\n\t\tREQUIRE(subStyles.Start(base) == 0);\n\n\t\tconst int startSubStyles = subStyles.Allocate(base, 3);\n\t\tREQUIRE(startSubStyles == styleFirst);\n\t\tREQUIRE(subStyles.Start(base) == styleFirst);\n\t\tREQUIRE(subStyles.Length(base) == 3);\n\t\tREQUIRE(subStyles.BaseStyle(128) == 2);\n\n\t\t// Not a substyle so returns argument.\n\t\tREQUIRE(subStyles.BaseStyle(96) == 96);\n\n\t\tREQUIRE(subStyles.FirstAllocated() == styleFirst);\n\t\tREQUIRE(subStyles.LastAllocated() == styleFirst + 3 - 1);\n\t\tsubStyles.SetIdentifiers(styleFirst, \"int long size_t\");\n\t\tconst WordClassifier &wc = subStyles.Classifier(base);\n\t\tREQUIRE(wc.ValueFor(\"int\") == styleFirst);\n\t\tREQUIRE(wc.ValueFor(\"double\") < 0);\n\n\t\t// Add second set of substyles which shouldn't affect first\n\t\tconst int startSecondSet = subStyles.Allocate(base2, 2);\n\t\tconstexpr int expectedStylesSecond = styleFirst + 3;\n\t\tREQUIRE(startSecondSet == expectedStylesSecond);\n\t\tREQUIRE(subStyles.Start(base) == styleFirst);\n\t\tREQUIRE(subStyles.Start(base2) == expectedStylesSecond);\n\t\tREQUIRE(subStyles.LastAllocated() == styleFirst + 5 - 1);\n\n\t\t// Clear and check that earlier call no longer works\n\t\tsubStyles.Free();\n\t\tREQUIRE(subStyles.Start(base) == 0);\n\t}\n\n}\n"
  },
  {
    "path": "test/unit/unitTest.cxx",
    "content": "/** @file unitTest.cxx\n ** Unit Tests for Lexilla internal data structures\n **/\n\n/*\n    Currently tested:\n        WordList\n        SparseState\n*/\n\n#include <cstdio>\n#include <cstdarg>\n\n#include <string_view>\n#include <vector>\n#include <memory>\n\n#if defined(__GNUC__)\n// Want to avoid misleading indentation warnings in catch.hpp but the pragma\n// may not be available so protect by turning off pragma warnings\n#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n#pragma GCC diagnostic ignored \"-Wpragmas\"\n#if !defined(__clang__)\n#pragma GCC diagnostic ignored \"-Wmisleading-indentation\"\n#endif\n#endif\n\n#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file\n#include \"catch.hpp\"\n"
  },
  {
    "path": "tgzsrc",
    "content": "cd ..\nrm -f lexilla.tgz\ntar --create --exclude \\*.o --exclude \\*.obj --exclude \\*.dll --exclude \\*.so --exclude \\*.exe --exclude \\*.a lexilla/* \\\n\t| gzip -c >lexilla.tgz\n"
  },
  {
    "path": "version.txt",
    "content": "549"
  },
  {
    "path": "zipsrc.bat",
    "content": "cd ..\ndel/q lexilla.zip\nzip lexilla.zip lexilla\\*.* lexilla\\*\\*.* lexilla\\*\\*\\*.* lexilla\\*\\*\\*\\*.* lexilla\\*\\*\\*\\*\\*.* ^\n -x *.bak *.o *.obj *.iobj *.dll *.exe *.a *.lib *.res *.exp *.sarif *.pdb *.ipdb *.idb *.sbr *.ilk *.tgz ^\n **/__pycache__/* **/Debug/* **/Release/* **/x64/* **/ARM64/* **/cov-int/* **/.vs/* **/.vscode/* @\ncd lexilla\n"
  }
]