chore: bump scintilla and lexilla version
This commit is contained in:
309
3rdparty/lexilla545/lexilla/lexers/LexBibTeX.cxx
vendored
Normal file
309
3rdparty/lexilla545/lexilla/lexers/LexBibTeX.cxx
vendored
Normal file
@ -0,0 +1,309 @@
|
||||
// Copyright 2008-2010 Sergiu Dotenco. The License.txt file describes the
|
||||
// conditions under which this software may be distributed.
|
||||
|
||||
/**
|
||||
* @file LexBibTeX.cxx
|
||||
* @brief General BibTeX coloring scheme.
|
||||
* @author Sergiu Dotenco
|
||||
* @date April 18, 2009
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
using namespace Lexilla;
|
||||
|
||||
namespace {
|
||||
bool IsAlphabetic(unsigned int ch)
|
||||
{
|
||||
return IsASCII(ch) && std::isalpha(ch) != 0;
|
||||
}
|
||||
bool IsAlphaNumeric(char ch)
|
||||
{
|
||||
return IsASCII(ch) && std::isalnum(ch);
|
||||
}
|
||||
|
||||
bool EqualCaseInsensitive(const char* a, const char* b)
|
||||
{
|
||||
return CompareCaseInsensitive(a, b) == 0;
|
||||
}
|
||||
|
||||
bool EntryWithoutKey(const char* name)
|
||||
{
|
||||
return EqualCaseInsensitive(name,"string");
|
||||
}
|
||||
|
||||
char GetClosingBrace(char openbrace)
|
||||
{
|
||||
char result = openbrace;
|
||||
|
||||
switch (openbrace) {
|
||||
case '(': result = ')'; break;
|
||||
case '{': result = '}'; break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsEntryStart(char prev, char ch)
|
||||
{
|
||||
return prev != '\\' && ch == '@';
|
||||
}
|
||||
|
||||
bool IsEntryStart(const StyleContext& sc)
|
||||
{
|
||||
return IsEntryStart(sc.chPrev, sc.ch);
|
||||
}
|
||||
|
||||
void ColorizeBibTeX(Sci_PositionU start_pos, Sci_Position length, int /*init_style*/, WordList* keywordlists[], Accessor& styler)
|
||||
{
|
||||
WordList &EntryNames = *keywordlists[0];
|
||||
bool fold_compact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
|
||||
std::string buffer;
|
||||
buffer.reserve(25);
|
||||
|
||||
// We always colorize a section from the beginning, so let's
|
||||
// search for the @ character which isn't escaped, i.e. \@
|
||||
while (start_pos > 0 && !IsEntryStart(styler.SafeGetCharAt(start_pos - 1),
|
||||
styler.SafeGetCharAt(start_pos))) {
|
||||
--start_pos; ++length;
|
||||
}
|
||||
|
||||
styler.StartAt(start_pos);
|
||||
styler.StartSegment(start_pos);
|
||||
|
||||
Sci_Position current_line = styler.GetLine(start_pos);
|
||||
int prev_level = styler.LevelAt(current_line) & SC_FOLDLEVELNUMBERMASK;
|
||||
int current_level = prev_level;
|
||||
int visible_chars = 0;
|
||||
|
||||
bool in_comment = false ;
|
||||
StyleContext sc(start_pos, length, SCE_BIBTEX_DEFAULT, styler);
|
||||
|
||||
bool going = sc.More(); // needed because of a fuzzy end of file state
|
||||
char closing_brace = 0;
|
||||
bool collect_entry_name = false;
|
||||
|
||||
for (; going; sc.Forward()) {
|
||||
if (!sc.More())
|
||||
going = false; // we need to go one behind the end of text
|
||||
|
||||
if (in_comment) {
|
||||
if (sc.atLineEnd) {
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT);
|
||||
in_comment = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Found @entry
|
||||
if (IsEntryStart(sc)) {
|
||||
sc.SetState(SCE_BIBTEX_UNKNOWN_ENTRY);
|
||||
sc.Forward();
|
||||
++current_level;
|
||||
|
||||
buffer.clear();
|
||||
collect_entry_name = true;
|
||||
}
|
||||
else if ((sc.state == SCE_BIBTEX_ENTRY || sc.state == SCE_BIBTEX_UNKNOWN_ENTRY)
|
||||
&& (sc.ch == '{' || sc.ch == '(')) {
|
||||
// Entry name colorization done
|
||||
// Found either a { or a ( after entry's name, e.g. @entry(...) @entry{...}
|
||||
// Closing counterpart needs to be stored.
|
||||
closing_brace = GetClosingBrace(sc.ch);
|
||||
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize { (
|
||||
|
||||
// @string doesn't have any key
|
||||
if (EntryWithoutKey(buffer.c_str()))
|
||||
sc.ForwardSetState(SCE_BIBTEX_PARAMETER);
|
||||
else
|
||||
sc.ForwardSetState(SCE_BIBTEX_KEY); // Key/label colorization
|
||||
}
|
||||
|
||||
// Need to handle the case where entry's key is empty
|
||||
// e.g. @book{,...}
|
||||
if (sc.state == SCE_BIBTEX_KEY && sc.ch == ',') {
|
||||
// Key/label colorization done
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize the ,
|
||||
sc.ForwardSetState(SCE_BIBTEX_PARAMETER); // Parameter colorization
|
||||
}
|
||||
else if (sc.state == SCE_BIBTEX_PARAMETER && sc.ch == '=') {
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize the =
|
||||
sc.ForwardSetState(SCE_BIBTEX_VALUE); // Parameter value colorization
|
||||
|
||||
Sci_Position start = sc.currentPos;
|
||||
|
||||
// We need to handle multiple situations:
|
||||
// 1. name"one two {three}"
|
||||
// 2. name={one {one two {two}} three}
|
||||
// 3. year=2005
|
||||
|
||||
// Skip ", { until we encounter the first alphanumerical character
|
||||
while (sc.More() && !(IsAlphaNumeric(sc.ch) || sc.ch == '"' || sc.ch == '{'))
|
||||
sc.Forward();
|
||||
|
||||
if (sc.More()) {
|
||||
// Store " or {
|
||||
char ch = sc.ch;
|
||||
|
||||
// Not interested in alphanumerical characters
|
||||
if (IsAlphaNumeric(ch))
|
||||
ch = 0;
|
||||
|
||||
int skipped = 0;
|
||||
|
||||
if (ch) {
|
||||
// Skip preceding " or { such as in name={{test}}.
|
||||
// Remember how many characters have been skipped
|
||||
// Make sure that empty values, i.e. "" are also handled correctly
|
||||
while (sc.More() && (sc.ch == ch && (ch != '"' || skipped < 1))) {
|
||||
sc.Forward();
|
||||
++skipped;
|
||||
}
|
||||
}
|
||||
|
||||
// Closing counterpart for " is the same character
|
||||
if (ch == '{')
|
||||
ch = '}';
|
||||
|
||||
// We have reached the parameter value
|
||||
// In case the open character was a alnum char, skip until , is found
|
||||
// otherwise until skipped == 0
|
||||
while (sc.More() && (skipped > 0 || (!ch && !(sc.ch == ',' || sc.ch == closing_brace)))) {
|
||||
// Make sure the character isn't escaped
|
||||
if (sc.chPrev != '\\') {
|
||||
// Parameter value contains a { which is the 2nd case described above
|
||||
if (sc.ch == '{')
|
||||
++skipped; // Remember it
|
||||
else if (sc.ch == '}')
|
||||
--skipped;
|
||||
else if (skipped == 1 && sc.ch == ch && ch == '"') // Don't ignore cases like {"o}
|
||||
skipped = 0;
|
||||
}
|
||||
|
||||
sc.Forward();
|
||||
}
|
||||
}
|
||||
|
||||
// Don't colorize the ,
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT);
|
||||
|
||||
// Skip until the , or entry's closing closing_brace is found
|
||||
// since this parameter might be the last one
|
||||
while (sc.More() && !(sc.ch == ',' || sc.ch == closing_brace))
|
||||
sc.Forward();
|
||||
|
||||
int state = SCE_BIBTEX_PARAMETER; // The might be more parameters
|
||||
|
||||
// We've reached the closing closing_brace for the bib entry
|
||||
// in case no " or {} has been used to enclose the value,
|
||||
// as in 3rd case described above
|
||||
if (sc.ch == closing_brace) {
|
||||
--current_level;
|
||||
// Make sure the text between entries is not colored
|
||||
// using parameter's style
|
||||
state = SCE_BIBTEX_DEFAULT;
|
||||
}
|
||||
|
||||
Sci_Position end = sc.currentPos;
|
||||
current_line = styler.GetLine(end);
|
||||
|
||||
// We have possibly skipped some lines, so the folding levels
|
||||
// have to be adjusted separately
|
||||
for (Sci_Position i = styler.GetLine(start); i <= styler.GetLine(end); ++i)
|
||||
styler.SetLevel(i, prev_level);
|
||||
|
||||
sc.ForwardSetState(state);
|
||||
}
|
||||
|
||||
if (sc.state == SCE_BIBTEX_PARAMETER && sc.ch == closing_brace) {
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT);
|
||||
--current_level;
|
||||
}
|
||||
|
||||
// Non escaped % found which represents a comment until the end of the line
|
||||
if (sc.chPrev != '\\' && sc.ch == '%') {
|
||||
in_comment = true;
|
||||
sc.SetState(SCE_BIBTEX_COMMENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc.state == SCE_BIBTEX_UNKNOWN_ENTRY || sc.state == SCE_BIBTEX_ENTRY) {
|
||||
if (!IsAlphabetic(sc.ch) && collect_entry_name)
|
||||
collect_entry_name = false;
|
||||
|
||||
if (collect_entry_name) {
|
||||
buffer += static_cast<char>(tolower(sc.ch));
|
||||
if (EntryNames.InList(buffer.c_str()))
|
||||
sc.ChangeState(SCE_BIBTEX_ENTRY);
|
||||
else
|
||||
sc.ChangeState(SCE_BIBTEX_UNKNOWN_ENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc.atLineEnd) {
|
||||
int level = prev_level;
|
||||
|
||||
if (visible_chars == 0 && fold_compact)
|
||||
level |= SC_FOLDLEVELWHITEFLAG;
|
||||
|
||||
if ((current_level > prev_level))
|
||||
level |= SC_FOLDLEVELHEADERFLAG;
|
||||
// else if (current_level < prev_level)
|
||||
// level |= SC_FOLDLEVELBOXFOOTERFLAG; // Deprecated
|
||||
|
||||
if (level != styler.LevelAt(current_line)) {
|
||||
styler.SetLevel(current_line, level);
|
||||
}
|
||||
|
||||
++current_line;
|
||||
prev_level = current_level;
|
||||
visible_chars = 0;
|
||||
}
|
||||
|
||||
if (!isspacechar(sc.ch))
|
||||
++visible_chars;
|
||||
}
|
||||
|
||||
sc.Complete();
|
||||
|
||||
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
|
||||
int flagsNext = styler.LevelAt(current_line) & ~SC_FOLDLEVELNUMBERMASK;
|
||||
styler.SetLevel(current_line, prev_level | flagsNext);
|
||||
}
|
||||
}
|
||||
static const char * const BibTeXWordLists[] = {
|
||||
"Entry Names",
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
extern const LexerModule lmBibTeX(SCLEX_BIBTEX, ColorizeBibTeX, "bib", 0, BibTeXWordLists);
|
||||
|
||||
// Entry Names
|
||||
// article, book, booklet, conference, inbook,
|
||||
// incollection, inproceedings, manual, mastersthesis,
|
||||
// misc, phdthesis, proceedings, techreport, unpublished,
|
||||
// string, url
|
||||
|
Reference in New Issue
Block a user