skylighting-core 0.7.6 → 0.7.7
raw patch · 4 files changed
+48/−571 lines, 4 files
Files
- changelog.md +12/−0
- skylighting-core.cabal +1/−2
- src/Skylighting/Parser.hs +35/−13
- xml/language.dtd +0/−556
changelog.md view
@@ -1,5 +1,17 @@ # Revision history for skylighting-core +## 0.7.7 -- 2019-02-27++ * Add parseSyntaxDefinitionFromString [API change].+ * Fix parseSyntaxDefinition so that language.dtd no longer needed.+ We strip out the SYSTEM "language.dtd" part of the doctype+ if present, leaving any inline entity definitions.+ This applies to both parseSyntaxDefinition and+ parseSyntaxDefinitionFromString.+ * Revised documentation of bootstrap build.+ * Makefile - fix bootstrap target.+ * Use FilePath instead of String for path (#64, anchpop).+ ## 0.7.6 -- 2019-02-08 * Update xml definitions for C, CPP, D, Haskell, Maxima, PHP,
skylighting-core.cabal view
@@ -1,5 +1,5 @@ name: skylighting-core-version: 0.7.6+version: 0.7.7 synopsis: syntax highlighting library description: Skylighting is a syntax highlighting library. It derives its tokenizers from XML syntax@@ -27,7 +27,6 @@ extra-source-files: README.md changelog.md xml/*.xml- xml/language.dtd test/default.theme test/cases/abc.ada test/cases/abc.agda
src/Skylighting/Parser.hs view
@@ -1,10 +1,12 @@ {-# LANGUAGE Arrows #-} module Skylighting.Parser ( parseSyntaxDefinition+ , parseSyntaxDefinitionFromString , addSyntaxDefinition , missingIncludes ) where -import Data.ByteString.UTF8 (fromString)+import Data.ByteString.UTF8 (fromString, toString)+import qualified Data.ByteString as BS import Data.Char (isAlphaNum, toUpper) import qualified Data.Map as Map import Data.Maybe (fromMaybe)@@ -64,22 +66,42 @@ _ -> defaultVal -- | Parses a file containing a Kate XML syntax definition--- into a 'Syntax' description.-parseSyntaxDefinition :: String -> IO (Either String Syntax)-parseSyntaxDefinition xml = do- res <- runX (application xml)+-- into a 'Syntax' description. Note that if the DOCTYPE contains+-- a reference to the now-obsolete language.dtd, we remove it.+parseSyntaxDefinition :: FilePath -> IO (Either String Syntax)+parseSyntaxDefinition fp = do+ xml <- toString <$> BS.readFile fp+ parseSyntaxDefinitionFromString fp xml++-- | Parses a string containing a Kate XML syntax definition+-- into a 'Syntax' description. Note that if the DOCTYPE contains+-- a reference to the now-obsolete language.dtd, we remove it.+parseSyntaxDefinitionFromString :: FilePath -- ^ used for short name+ -> String+ -> IO (Either String Syntax)+parseSyntaxDefinitionFromString fp xml = do+ res <- runX ( readString [withValidate no]+ (removeLanguageDTD . removeBOM $ xml)+ >>>+ application fp ) case res of [s] -> return $ Right s- _ -> return $ Left $ "Could not parse syntax definition " ++ xml+ _ -> return $ Left $ "Could not parse syntax definition " ++ fp -application :: String -> IOSArrow b Syntax-application fp@(_:':':'\\':_) =- -- Windows C:/, so HXT doesn't interpret as a URI scheme.- application ("file:///" ++ map (\c -> if c == '\\' then '/' else c) fp)+removeBOM :: String -> String+removeBOM ('\xFEFF':xs) = xs+removeBOM xs = xs++removeLanguageDTD :: String -> String+removeLanguageDTD ('S':'Y':'S':'T':'E':'M':' ':xs) =+ removeLanguageDTD $ dropWhile (\c -> c /= '[' && c /= '>') xs+removeLanguageDTD xs@('<':'l':'a':'n':'g':_) = xs+removeLanguageDTD (x:xs) = x : removeLanguageDTD xs+removeLanguageDTD [] = []++application :: FilePath -> IOSArrow XmlTree Syntax application fp- = readDocument [withValidate no, withInputEncoding utf8] fp- >>>- multi (hasName "language")+ = multi (hasName "language") >>> extractSyntaxDefinition (takeFileName fp)
− xml/language.dtd
@@ -1,556 +0,0 @@-<!--- Copyright (c) 2001 Joseph Wenninger <jowenn@kde.org>- modified (c) 2002 Anders Lund <anders@alweb.dk>- modified (c) 2003 Simon Huerlimann <simon.huerlimann@access.unizh.ch>- modified (c) 2005 Dominik Haumann <dhdev@gmx.de>- modified (c) 2008 Wilbert Berendsen <info@wilbertberendsen.nl>-- This file describes the XML format used for syntax highlight descriptions- for the Kate text editor (http://kate.kde.org), which is part of the KDE- desktop environment (http://www.kde.org).- You'll find the "Writing a Kate Highlighting XML File HOWTO" at- http://kate.kde.org/doc/hlhowto.php-- This format is identified using the SYSTEM identifier- SYSTEM "language.dtd"-- Files using this format should include a DOCTYPE declaration like this:- <!DOCTYPE language SYSTEM "language.dtd">-- You can validate your syntax files using checkXML from the development- package of kdelibs:- checkXML yourSyntax.xml- If you see any 'validity error' lines, you should fix them. If you get- a lot of 'No template matches' lines, everything's just fine. You've- produced a valid syntax file!-- It's also possible to use the (much faster) xmllint which comes with the- GNOME (oops:-) XML Library libxml2:-- xmllint - -dtdvalid language.dtd yourSyntax.xml- (don't use a space between the two - That's just because XML- comments don't allow that:-(-- To use your syntax file, copy it to .kde/share/apps/katepart/syntax/ in- your home directory. You have to open a new instance of kwrite/kate to use- the new syntax file.--TODO- - find a more readable way for the - -dtdvalid stuff, it's just annoying- xml comments don't allow it.--->--<!-- Entity declarations- You can use '&per;' instead of '.'. This seems to be useful in <item> elements.--TODO- - Are there any more such pre-defined entities?--->-<!ENTITY per "." >--<!-- Boolean type- Attributes that are of type boolean allow the following values:- 'true', 'TRUE' and '1' all meaning true,- 'false', FALSE' and '0' all meaning false.-- It is encouraged to use 'true' and 'false' instead of the alternatives.--->-<!ENTITY % boolean "true|false|TRUE|FALSE|0|1">--<!-- Default Styles- Allowed predefined default styles for itemData, available are:- - dsNormal, used for normal text- - dsKeyword, used for keywords- - dsDataType, used for data types- - dsDecVal, used for decimal values- - dsBaseN, used for values with a base other than 10- - dsFloat, used for float values- - dsChar, used for a character- - dsString, used for strings- - dsComment, used for comments- - dsOthers, used for 'other' things- - dsAlert, used for warning messages- - dsFunction, used for function calls- - dsRegionMarker, used for region markers- - dsError, used for error highlighting.--->-<!ENTITY % defStyles "dsNormal|dsKeyword|dsDataType|dsDecVal|dsBaseN|dsFloat|dsChar|dsString|dsComment|dsOthers|dsAlert|dsFunction|dsRegionMarker|dsError">--<!-- Language specification- name: The name of this syntax description. Used in the Highlightning Mode menu- section: The logical group to which this syntax description belongs. Used for sub menus- extensions: A file glob or pattern to decide for which documents to use this syntax description- style: Attribute style that this highlighter provides to kate scripts [optional]- mimetype: A list of mimetypes to decide for which documents to use this syntax description [optional]- version: Version number of this syntax description [optional]- kateversion: Kate version required for using this file [optional]- casesensitive: Whether text is matched case sensitive. [boolean, optional, default=true] FIXME: This is not implemented yet- priority: Priority of this language, if more than one are usable for the file [optional]- author: Name of author of this hl file [optional]- license: License for this hl file [optional]- indenter: Name of the Indenter to use for this highlighting mode per default, like "cstyle" [optional]- hidden: Should it be hidden in menu [boolean, optional, default=false]--TODO- - Which matches are affected by casesensitive? keyword, RegExpr, StringDetect, WordDetect...?--WARNING: due to helper scripts, the language opening tag must be on a-*single line* and *cannot* be split in multiple lines.---->-<!ELEMENT language (highlighting, general?, spellchecking?)>-<!ATTLIST language- name CDATA #REQUIRED- section NMTOKEN #REQUIRED- extensions CDATA #REQUIRED- version CDATA #REQUIRED- kateversion CDATA #REQUIRED- style CDATA #IMPLIED- mimetype CDATA #IMPLIED- casesensitive (%boolean;) #IMPLIED- priority CDATA #IMPLIED- author CDATA #IMPLIED- license CDATA #IMPLIED- indenter CDATA #IMPLIED- hidden (%boolean;) #IMPLIED->--<!-- General options -->-<!ELEMENT general (folding|comments|keywords|indentation|emptyLines)*>--<!-- List of folding- indentationsensitive: If true, the code folding is indentation based.--->-<!ELEMENT folding EMPTY>-<!ATTLIST folding- indentationsensitive (%boolean;) #IMPLIED->--<!-- List of comments -->-<!ELEMENT comments (comment)+>--<!-- Comment specification- name: Type of this comment. Allowed are 'singleLine' and 'multiLine'- start: The comment starts with this string- end: The comment ends with this string [optional]- region: The region name of the foldable multiline comment. If you have- beginRegion="Comment" ... endRegion="Comment" you should use- region="Comment". This way uncomment works even if you do not- select all the text of the multiline comment.- position: only availalbe for type singleLine. Default is column0, to insert- the single line comment characters after the whitespaces- (= before the first non space) set position to "afterwhitespace"--->-<!ELEMENT comment EMPTY>-<!ATTLIST comment- name (singleLine|multiLine) #REQUIRED- start CDATA #REQUIRED- end CDATA #IMPLIED- region CDATA #IMPLIED- position (afterwhitespace) #IMPLIED->--<!-- Keyword options- casesensitive: Whether keywords are matched case sensitive. [boolean, optional, default=true]- weakDeliminator: Add weak deliminators [optional, default: ""]- additionalDeliminator: Add deliminators [optional]- wordWrapDeliminator: characters that are used to wrap long lines [optional]---->-<!ELEMENT keywords EMPTY>-<!ATTLIST keywords- casesensitive (%boolean;) #IMPLIED- weakDeliminator CDATA #IMPLIED- additionalDeliminator CDATA #IMPLIED- wordWrapDeliminator CDATA #IMPLIED->--<!-- Indentation options- mode: indentation mode to use--TODO- - Explain (weak) deliminators--->-<!ELEMENT indentation EMPTY>-<!ATTLIST indentation- mode CDATA #IMPLIED->--<!-- Treat lines that match a given regular expression as empty line. This is- needed for example in Python for comments (#...), as then the indentation- based folding should ignore the line.- This is only implemented for indentation based folding. If the folding- is not indentation based, the emptyLines are not used.--->-<!ELEMENT emptyLines (emptyLine*)>--<!-- One empty line regular expression.- regexpr: The regular expression, example from python: ^\s*#.*$- casesensitive: Sets, whether the regular expression match is performed case sesitive--->-<!ELEMENT emptyLine EMPTY>-<!ATTLIST emptyLine- regexpr CDATA #REQUIRED- casesensitive (%boolean;) #IMPLIED->---<!-- Highlighting specification -->-<!ELEMENT highlighting (list*, contexts, itemDatas)>-<!ATTLIST highlighting->--<!-- List of items- name: Name of this list--->-<!ELEMENT list (item)*>-<!ATTLIST list- name CDATA #REQUIRED->--<!-- List item- contains string used in <keyword>--->-<!ELEMENT item (#PCDATA)>--<!-- List of contexts -->-<!ELEMENT contexts (context)+>--<!-- context specification- name: The name of this context specification. Used in '*Context' attributes [optional]- attribute: The name of the ItemData to be used for matching text- lineEndContext: Next context if end of line is encountered- lineBeginContext: Next context if begin of line is encountered [optional]- fallthrough: Use a fallthrough context [optional]- fallthroughContext: Fall through to this context [optional]- dynamic: Dynamic context [boolean, optional]- noIndentationBasedFolding: Python uses indentation based folding. However, Python has parts where- it does not use indentation based folding (e.g. for """ strings). In this case- switch to an own context and set this attribute to true. Then the indentation- based folding will ignore this parts and not change folding markers. [optional]--TODO:- - Explain fallthrough.- - Do we need fallthrough at all? It could be true, if fallthroughContext is set, false otherwise.- - Make lineEndContext optional, defaults to '#stay'. Reasonable?--->-<!ELEMENT context (keyword | Float | HlCOct | HlCHex | HlCFloat | Int | DetectChar | Detect2Chars | AnyChar | StringDetect | WordDetect | RegExpr | LineContinue | HlCStringChar | RangeDetect | HlCChar | IncludeRules | DetectSpaces | DetectIdentifier)*>-<!ATTLIST context- name CDATA #IMPLIED- attribute CDATA #REQUIRED- lineEndContext CDATA #REQUIRED- lineBeginContext CDATA #IMPLIED- fallthrough (%boolean;) #IMPLIED- fallthroughContext CDATA #IMPLIED- dynamic (%boolean;) #IMPLIED- noIndentationBasedFolding (%boolean;) #IMPLIED->--<!-- Common attributes- attribute: The name of the ItemData to be used for matching text- context: The name of the context to go to when this rule matches- beginRegion: Begin a region of type beginRegion [optional]- endRegion: End a region of type endRegion [optional]- firstNonSpace: should this rule only match at first non-space char in line?- column: should this rule only match at given column in line (column == count of chars in front)--->-<!ENTITY % commonAttributes- "attribute CDATA #IMPLIED- context CDATA #IMPLIED- beginRegion CDATA #IMPLIED- endRegion CDATA #IMPLIED- lookAhead (%boolean;) #IMPLIED- firstNonSpace (%boolean;) #IMPLIED- column CDATA #IMPLIED"->--<!-- Detect members of a keyword list- commonAttributes: Common attributes- insensitive: Is this list case-insensitive? [boolean, optional, see note]- String: Name of the list- weakDelimiter: Use weak deliminator-- By default, case sensitivity is determined from <keywords casesensitive> in- <general> (default=true), but can be overridden per-list with 'insensitive'.--TODO:- - Should be weakDeliminator- - Explain deliminator- - Doesn't seem to be supported in highligh.cpp--->-<!ELEMENT keyword EMPTY>-<!ATTLIST keyword- %commonAttributes;- insensitive CDATA #IMPLIED- String CDATA #REQUIRED- weakDelimiter CDATA #IMPLIED->--<!-- Detect a floating point number- commonAttributes: Common attributes- AnyChar is allowed as a child rule. TODO: The source code allows- *all* rules to be child rules, shall we change the DTD in some way?--->-<!ELEMENT Float (AnyChar)*>-<!ATTLIST Float- %commonAttributes;->--<!-- Detect an octal number- commonAttributes: Common attributes--->-<!ELEMENT HlCOct EMPTY>-<!ATTLIST HlCOct- %commonAttributes;->--<!-- Detect a hexadecimal number- commonAttributes: Common attributes--->-<!ELEMENT HlCHex EMPTY>-<!ATTLIST HlCHex- %commonAttributes;->--<!-- Detect a C-style floating point number- commonAttributes: Common attributes--->-<!ELEMENT HlCFloat EMPTY>-<!ATTLIST HlCFloat- %commonAttributes;->--<!-- Detect C-style character- commonAttributes: Common attributes--TODO- - Did I get this right?--->-<!ELEMENT HlCChar EMPTY>-<!ATTLIST HlCChar- %commonAttributes;->--<!-- Detect an integer number- commonAttributes: Common attributes- StringDetect is allowed as a child rule. TODO: The source code allows- *all* rules to be child rules, shall we change the DTD in some way?--->-<!ELEMENT Int (StringDetect)*>-<!ATTLIST Int- %commonAttributes;->--<!-- Detect a single character- commonAttributes: Common attributes- char: The character to look for- dynamic: Uses 0 ... 9 as placeholders for dynamic arguments (in fact, first char of arg...) [boolean, optional, default=false]--->-<!ELEMENT DetectChar EMPTY>-<!ATTLIST DetectChar- %commonAttributes;- char CDATA #REQUIRED- dynamic (%boolean;) #IMPLIED->--<!-- Detect two characters- commonAttributes: Common attributes- char: The first character- char1: The second character- dynamic: Uses 0 ... 9 as placeholders for dynamic arguments (in fact, first char of arg...) [boolean, optional, default=false]--->-<!ELEMENT Detect2Chars EMPTY>-<!ATTLIST Detect2Chars- %commonAttributes;- char CDATA #REQUIRED- char1 CDATA #REQUIRED- dynamic (%boolean;) #IMPLIED->--<!-- Detect any group of characters- commonAttributes: Common attributes- String: A string representing the characters to look for--TODO- - Description is not descriptive enough, I'm not sure what it exactly does:-(--->-<!ELEMENT AnyChar EMPTY>-<!ATTLIST AnyChar- %commonAttributes;- String CDATA #REQUIRED->--<!-- Detect a string- commonAttributes: Common attributes- String: The string to look for- insensitive: Whether the string is matched case INsensitive. [boolean, optional, default=false]- dynamic: Uses %0 ... %9 as placeholders for dynamic arguments [boolean, optional, default=false]--TODO- - What's default of insensitive? I'm not sure...--->-<!ELEMENT StringDetect EMPTY>-<!ATTLIST StringDetect- %commonAttributes;- String CDATA #REQUIRED- insensitive (%boolean;) #IMPLIED- dynamic (%boolean;) #IMPLIED->--<!-- Detect a word, i.e. a string at word boundaries- commonAttributes: Common attributes- String: The string to look for- insensitive: Whether the string is matched case INsensitive. [boolean, optional, default=false]- dynamic: Uses %0 ... %9 as placeholders for dynamic arguments [boolean, optional, default=false]--TODO- - What's default of insensitive? I'm not sure...--->-<!ELEMENT WordDetect EMPTY>-<!ATTLIST WordDetect- %commonAttributes;- String CDATA #REQUIRED- insensitive (%boolean;) #IMPLIED- dynamic (%boolean;) #IMPLIED->--<!-- Detect a match of a regular expression- commonAttributes: Common attributes- String: The regular expression pattern- insensitive: Whether the text is matched case INsensitive. [boolean, optional, default=false]- minimal: Wheather to use minimal matching for wild cards in the pattern [boolean, optional, default='false']- dynamic: Uses %0 ... %9 as placeholders for dynamic arguments [boolean, optional, default=false]--->-<!ELEMENT RegExpr EMPTY>-<!ATTLIST RegExpr- %commonAttributes;- String CDATA #REQUIRED- insensitive (%boolean;) #IMPLIED- minimal (%boolean;) #IMPLIED- dynamic (%boolean;) #IMPLIED->--<!-- Detect a line continuation- commonAttributes: Common attributes--->-<!ELEMENT LineContinue EMPTY>-<!ATTLIST LineContinue- %commonAttributes;->--<!-- Detect a C-style escaped character- commonAttributes: Common attributes--TODO:- - Did I get this right? Only one character, or a string?--->-<!ELEMENT HlCStringChar EMPTY>-<!ATTLIST HlCStringChar- %commonAttributes;->--<!-- Detect a range of characters- commonAttributes: Common attributes- char: The character starting the range- char1: The character terminating the range--->-<!ELEMENT RangeDetect EMPTY>-<!ATTLIST RangeDetect- %commonAttributes;- char CDATA #REQUIRED- char1 CDATA #REQUIRED->--<!-- Include Rules of another context- context: The name of the context to include- includeAttrib: If this is true, the host context of the IncludeRules- will be given the attribute of the source context--->-<!ELEMENT IncludeRules EMPTY>-<!ATTLIST IncludeRules- context CDATA #REQUIRED- includeAttrib (%boolean;) #IMPLIED->--<!-- Detect all following Spaces--->-<!ELEMENT DetectSpaces EMPTY>-<!ATTLIST DetectSpaces- %commonAttributes;->--<!-- Detect an Identifier ( == LETTER(LETTER|NUMBER|_)*)- -->-<!ELEMENT DetectIdentifier EMPTY>-<!ATTLIST DetectIdentifier- %commonAttributes;->--<!-- List of attributes -->-<!ELEMENT itemDatas (itemData)+>-<!ATTLIST itemDatas->--<!-- Attribute specification- name CDATA #REQUIRED The name of this attribute- defStyleNum CDATA #REQUIRED The index of the default style to use- color CDATA #IMPLIED Color for this style, either a hex triplet, a name or some other format recognized by Qt [optional]- selColor CDATA #IMPLIED The color for this style when text is selected [optional]- italic CDATA #IMPLIED Whether this attribute should be rendered using an italic typeface [optional, boolean, default=false]- bold CDATA #IMPLIED Whether this attribute should be renederd using a bold typeface [optional, boolean, default=false]- underline CDATA #IMPLIED Whether this attribute should be underlined [optional, boolean, default=false]- strikeOut CDATA #IMPLIED Whether this attribute should be striked out [optional, boolean, default=false]- backgroundColor CDATA #IMPLIED The background color for this style [optional]- selBackgroundColor CDATA #IMPLIED The background color for this style when text is selected [optional]- spellChecking CDATA #IMPLIED Whether this attribute should be spell checked [optional, boolean, default=true]--->-<!ELEMENT itemData EMPTY>-<!ATTLIST itemData- name CDATA #REQUIRED- defStyleNum (%defStyles;) #REQUIRED- color CDATA #IMPLIED- selColor CDATA #IMPLIED- italic (%boolean;) #IMPLIED- bold (%boolean;) #IMPLIED- underline (%boolean;) #IMPLIED- strikeOut (%boolean;) #IMPLIED- backgroundColor CDATA #IMPLIED- selBackgroundColor CDATA #IMPLIED- spellChecking (%boolean;) #IMPLIED->--<!-- encodingPolicy type- Attributes that are of type 'encodingPolicy' allow the following values:- 'EncodeAlways', 'EncodeWhenPresent' and 'EncodeNever'--->-<!ENTITY % encodingPolicy "EncodeAlways|EncodeWhenPresent|EncodeNever">--<!-- Spellchecking specification -->-<!ELEMENT spellchecking (configuration?, encodings?)>-<!ATTLIST spellchecking->--<!-- List of character encodings -->-<!ELEMENT encodings (encoding)+>-<!ATTLIST encodings->--<!-- Encoding specification- sequence CDATA #REQUIRED Character sequence of the encoding; must not contain new-line characters, i.e. \n or \r- character CDATA #IMPLIED Encoded character; must be of length 1- ignored (%boolean;) #IMPLIED If true, then the encoding sequence is ignored for spellchecking--->-<!ELEMENT encoding EMPTY>-<!ATTLIST encoding- string CDATA #REQUIRED- char CDATA #IMPLIED- ignored (%boolean;) #IMPLIED->--<!-- Spellchecking configuration- encodingReplacementPolicy (%encodingPolicy;) #IMPLIED Policy for replacing encoded characters in replacements for misspelled words--->-<!ELEMENT configuration EMPTY>-<!ATTLIST configuration- encodingReplacementPolicy (%encodingPolicy;) #IMPLIED->