aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lexers/LexOthers.cxx112
-rw-r--r--lexers/LexPO.cxx150
-rw-r--r--src/Catalogue.cxx2
-rw-r--r--win32/scintilla.mak3
-rw-r--r--win32/scintilla_vc6.mak3
5 files changed, 157 insertions, 113 deletions
diff --git a/lexers/LexOthers.cxx b/lexers/LexOthers.cxx
index fb8c97b31..d27c83545 100644
--- a/lexers/LexOthers.cxx
+++ b/lexers/LexOthers.cxx
@@ -614,117 +614,6 @@ static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Ac
} while (static_cast<int>(startPos) + length > curLineStart);
}
-// see https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files for the syntax reference
-// some details are taken from the GNU msgfmt behavior (like that indent is allows in front of lines)
-static void ColourisePoDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
- StyleContext sc(startPos, length, initStyle, styler);
- bool escaped = false;
- int curLine = styler.GetLine(startPos);
- // the line state holds the last state on or before the line that isn't the default style
- int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : SCE_PO_DEFAULT;
-
- for (; sc.More(); sc.Forward()) {
- // whether we should leave a state
- switch (sc.state) {
- case SCE_PO_COMMENT:
- case SCE_PO_PROGRAMMER_COMMENT:
- case SCE_PO_REFERENCE:
- case SCE_PO_FLAGS:
- case SCE_PO_FUZZY:
- if (sc.atLineEnd)
- sc.SetState(SCE_PO_DEFAULT);
- else if (sc.state == SCE_PO_FLAGS && sc.Match("fuzzy"))
- // here we behave like the previous parser, but this should probably be highlighted
- // on its own like a keyword rather than changing the whole flags style
- sc.ChangeState(SCE_PO_FUZZY);
- break;
-
- case SCE_PO_MSGCTXT:
- case SCE_PO_MSGID:
- case SCE_PO_MSGSTR:
- if (isspacechar(sc.ch))
- sc.SetState(SCE_PO_DEFAULT);
- break;
-
- case SCE_PO_ERROR:
- if (sc.atLineEnd)
- sc.SetState(SCE_PO_DEFAULT);
- break;
-
- case SCE_PO_MSGCTXT_TEXT:
- case SCE_PO_MSGID_TEXT:
- case SCE_PO_MSGSTR_TEXT:
- if (sc.atLineEnd) { // invalid inside a string
- if (sc.state == SCE_PO_MSGCTXT_TEXT)
- sc.ChangeState(SCE_PO_MSGCTXT_TEXT_EOL);
- else if (sc.state == SCE_PO_MSGID_TEXT)
- sc.ChangeState(SCE_PO_MSGID_TEXT_EOL);
- else if (sc.state == SCE_PO_MSGSTR_TEXT)
- sc.ChangeState(SCE_PO_MSGSTR_TEXT_EOL);
- sc.SetState(SCE_PO_DEFAULT);
- escaped = false;
- } else {
- if (escaped)
- escaped = false;
- else if (sc.ch == '\\')
- escaped = true;
- else if (sc.ch == '"')
- sc.ForwardSetState(SCE_PO_DEFAULT);
- }
- break;
- }
-
- // whether we should enter a new state
- if (sc.state == SCE_PO_DEFAULT) {
- // forward to the first non-white character on the line
- bool atLineStart = sc.atLineStart;
- if (atLineStart) {
- while (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch))
- sc.Forward();
- }
-
- if (atLineStart && sc.ch == '#') {
- if (sc.chNext == '.')
- sc.SetState(SCE_PO_PROGRAMMER_COMMENT);
- else if (sc.chNext == ':')
- sc.SetState(SCE_PO_REFERENCE);
- else if (sc.chNext == ',')
- sc.SetState(SCE_PO_FLAGS);
- else if (sc.chNext == '|')
- sc.SetState(SCE_PO_COMMENT); // previous untranslated string, no special style yet
- else
- sc.SetState(SCE_PO_COMMENT);
- } else if (atLineStart && sc.Match("msgid")) { // includes msgid_plural
- sc.SetState(SCE_PO_MSGID);
- } else if (atLineStart && sc.Match("msgstr")) { // includes [] suffixes
- sc.SetState(SCE_PO_MSGSTR);
- } else if (atLineStart && sc.Match("msgctxt")) {
- sc.SetState(SCE_PO_MSGCTXT);
- } else if (sc.ch == '"') {
- if (curLineState == SCE_PO_MSGCTXT || curLineState == SCE_PO_MSGCTXT_TEXT)
- sc.SetState(SCE_PO_MSGCTXT_TEXT);
- else if (curLineState == SCE_PO_MSGID || curLineState == SCE_PO_MSGID_TEXT)
- sc.SetState(SCE_PO_MSGID_TEXT);
- else if (curLineState == SCE_PO_MSGSTR || curLineState == SCE_PO_MSGSTR_TEXT)
- sc.SetState(SCE_PO_MSGSTR_TEXT);
- else
- sc.SetState(SCE_PO_ERROR);
- } else if (! isspacechar(sc.ch))
- sc.SetState(SCE_PO_ERROR);
-
- if (sc.state != SCE_PO_DEFAULT)
- curLineState = sc.state;
- }
-
- if (sc.atLineEnd) {
- // Update the line state, so it can be seen by next line
- curLine = styler.GetLine(sc.currentPos);
- styler.SetLineState(curLine, curLineState);
- }
- }
- sc.Complete();
-}
-
static inline bool isassignchar(unsigned char ch) {
return (ch == '=') || (ch == ':');
}
@@ -1537,7 +1426,6 @@ static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[
LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
-LexerModule lmPo(SCLEX_PO, ColourisePoDoc, "po", 0, emptyWordListDesc);
LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);
LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
diff --git a/lexers/LexPO.cxx b/lexers/LexPO.cxx
new file mode 100644
index 000000000..d1ccda394
--- /dev/null
+++ b/lexers/LexPO.cxx
@@ -0,0 +1,150 @@
+// Scintilla source code edit control
+/** @file LexPO.cxx
+ ** Lexer for GetText Translation (PO) files.
+ **/
+// Copyright 2012 by Colomban Wendling <ban@herbesfolles.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// see https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files for the syntax reference
+// some details are taken from the GNU msgfmt behavior (like that indent is allows in front of lines)
+
+// TODO:
+// * add keywords for flags (fuzzy, c-format, ...)
+// * highlight formats inside c-format strings (%s, %d, etc.)
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static void ColourisePODoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
+ StyleContext sc(startPos, length, initStyle, styler);
+ bool escaped = false;
+ int curLine = styler.GetLine(startPos);
+ // the line state holds the last state on or before the line that isn't the default style
+ int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : SCE_PO_DEFAULT;
+
+ for (; sc.More(); sc.Forward()) {
+ // whether we should leave a state
+ switch (sc.state) {
+ case SCE_PO_COMMENT:
+ case SCE_PO_PROGRAMMER_COMMENT:
+ case SCE_PO_REFERENCE:
+ case SCE_PO_FLAGS:
+ case SCE_PO_FUZZY:
+ if (sc.atLineEnd)
+ sc.SetState(SCE_PO_DEFAULT);
+ else if (sc.state == SCE_PO_FLAGS && sc.Match("fuzzy"))
+ // here we behave like the previous parser, but this should probably be highlighted
+ // on its own like a keyword rather than changing the whole flags style
+ sc.ChangeState(SCE_PO_FUZZY);
+ break;
+
+ case SCE_PO_MSGCTXT:
+ case SCE_PO_MSGID:
+ case SCE_PO_MSGSTR:
+ if (isspacechar(sc.ch))
+ sc.SetState(SCE_PO_DEFAULT);
+ break;
+
+ case SCE_PO_ERROR:
+ if (sc.atLineEnd)
+ sc.SetState(SCE_PO_DEFAULT);
+ break;
+
+ case SCE_PO_MSGCTXT_TEXT:
+ case SCE_PO_MSGID_TEXT:
+ case SCE_PO_MSGSTR_TEXT:
+ if (sc.atLineEnd) { // invalid inside a string
+ if (sc.state == SCE_PO_MSGCTXT_TEXT)
+ sc.ChangeState(SCE_PO_MSGCTXT_TEXT_EOL);
+ else if (sc.state == SCE_PO_MSGID_TEXT)
+ sc.ChangeState(SCE_PO_MSGID_TEXT_EOL);
+ else if (sc.state == SCE_PO_MSGSTR_TEXT)
+ sc.ChangeState(SCE_PO_MSGSTR_TEXT_EOL);
+ sc.SetState(SCE_PO_DEFAULT);
+ escaped = false;
+ } else {
+ if (escaped)
+ escaped = false;
+ else if (sc.ch == '\\')
+ escaped = true;
+ else if (sc.ch == '"')
+ sc.ForwardSetState(SCE_PO_DEFAULT);
+ }
+ break;
+ }
+
+ // whether we should enter a new state
+ if (sc.state == SCE_PO_DEFAULT) {
+ // forward to the first non-white character on the line
+ bool atLineStart = sc.atLineStart;
+ if (atLineStart) {
+ while (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch))
+ sc.Forward();
+ }
+
+ if (atLineStart && sc.ch == '#') {
+ if (sc.chNext == '.')
+ sc.SetState(SCE_PO_PROGRAMMER_COMMENT);
+ else if (sc.chNext == ':')
+ sc.SetState(SCE_PO_REFERENCE);
+ else if (sc.chNext == ',')
+ sc.SetState(SCE_PO_FLAGS);
+ else if (sc.chNext == '|')
+ sc.SetState(SCE_PO_COMMENT); // previous untranslated string, no special style yet
+ else
+ sc.SetState(SCE_PO_COMMENT);
+ } else if (atLineStart && sc.Match("msgid")) { // includes msgid_plural
+ sc.SetState(SCE_PO_MSGID);
+ } else if (atLineStart && sc.Match("msgstr")) { // includes [] suffixes
+ sc.SetState(SCE_PO_MSGSTR);
+ } else if (atLineStart && sc.Match("msgctxt")) {
+ sc.SetState(SCE_PO_MSGCTXT);
+ } else if (sc.ch == '"') {
+ if (curLineState == SCE_PO_MSGCTXT || curLineState == SCE_PO_MSGCTXT_TEXT)
+ sc.SetState(SCE_PO_MSGCTXT_TEXT);
+ else if (curLineState == SCE_PO_MSGID || curLineState == SCE_PO_MSGID_TEXT)
+ sc.SetState(SCE_PO_MSGID_TEXT);
+ else if (curLineState == SCE_PO_MSGSTR || curLineState == SCE_PO_MSGSTR_TEXT)
+ sc.SetState(SCE_PO_MSGSTR_TEXT);
+ else
+ sc.SetState(SCE_PO_ERROR);
+ } else if (! isspacechar(sc.ch))
+ sc.SetState(SCE_PO_ERROR);
+
+ if (sc.state != SCE_PO_DEFAULT)
+ curLineState = sc.state;
+ }
+
+ if (sc.atLineEnd) {
+ // Update the line state, so it can be seen by next line
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, curLineState);
+ }
+ }
+ sc.Complete();
+}
+
+static const char *const poWordListDesc[] = {
+ 0
+};
+
+LexerModule lmPO(SCLEX_PO, ColourisePODoc, "po", 0, poWordListDesc);
diff --git a/src/Catalogue.cxx b/src/Catalogue.cxx
index 2f752472b..cd69d814b 100644
--- a/src/Catalogue.cxx
+++ b/src/Catalogue.cxx
@@ -152,7 +152,7 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmPerl);
LINK_LEXER(lmPHPSCRIPT);
LINK_LEXER(lmPLM);
- LINK_LEXER(lmPo);
+ LINK_LEXER(lmPO);
LINK_LEXER(lmPOV);
LINK_LEXER(lmPowerPro);
LINK_LEXER(lmPowerShell);
diff --git a/win32/scintilla.mak b/win32/scintilla.mak
index e57da3c71..d7d8d3a30 100644
--- a/win32/scintilla.mak
+++ b/win32/scintilla.mak
@@ -146,6 +146,7 @@ LEXOBJS=\
$(DIR_O)\LexPB.obj \
$(DIR_O)\LexPerl.obj \
$(DIR_O)\LexPLM.obj \
+ $(DIR_O)\LexPO.obj \
$(DIR_O)\LexPOV.obj \
$(DIR_O)\LexPowerPro.obj \
$(DIR_O)\LexPowerShell.obj \
@@ -408,6 +409,8 @@ $(DIR_O)\LexPerl.obj: ..\lexers\LexPerl.cxx $(LEX_HEADERS)
$(DIR_O)\LexPLM.obj: ..\lexers\LexPLM.cxx $(LEX_HEADERS)
+$(DIR_O)\LexPO.obj: ..\lexers\LexPO.cxx $(LEX_HEADERS)
+
$(DIR_O)\LexPOV.obj: ..\lexers\LexPOV.cxx $(LEX_HEADERS)
$(DIR_O)\LexPowerPro.obj: ..\lexers\LexPowerPro.cxx $(LEX_HEADERS)
diff --git a/win32/scintilla_vc6.mak b/win32/scintilla_vc6.mak
index 2f900ab01..bfc9e6f18 100644
--- a/win32/scintilla_vc6.mak
+++ b/win32/scintilla_vc6.mak
@@ -143,6 +143,7 @@ LEXOBJS=\
$(DIR_O)\LexPB.obj \
$(DIR_O)\LexPerl.obj \
$(DIR_O)\LexPLM.obj \
+ $(DIR_O)\LexPO.obj \
$(DIR_O)\LexPOV.obj \
$(DIR_O)\LexPowerPro.obj \
$(DIR_O)\LexPowerShell.obj \
@@ -402,6 +403,8 @@ $(DIR_O)\LexPerl.obj: ..\lexers\LexPerl.cxx $(LEX_HEADERS)
$(DIR_O)\LexPLM.obj: ..\lexers\LexPLM.cxx $(LEX_HEADERS)
+$(DIR_O)\LexPO.obj: ..\lexers\LexPO.cxx $(LEX_HEADERS)
+
$(DIR_O)\LexPOV.obj: ..\lexers\LexPOV.cxx $(LEX_HEADERS)
$(DIR_O)\LexPowerPro.obj: ..\lexers\LexPowerPro.cxx $(LEX_HEADERS)