File indexing completed on 2024-04-21 15:07:47

0001 #!/usr/bin/env python3
0002 """
0003 LICENSE:
0004 SPDX-FileCopyrightText: 2020 Juraj Oravec <jurajoravec@mailo.com>
0005 SPDX-License-Identifier: MIT
0006 
0007 Configuration:
0008 - IncludeCustoms: Try to export all available settings
0009 - prefferStandAloneData: prefferdata set specifically for current datatype
0010 
0011 Usage:
0012 script.py ThemeName themefile.kateschema
0013 """
0014 
0015 from configparser import ConfigParser
0016 import json
0017 import sys
0018 
0019 
0020 settings = {
0021     "prefferStandAloneData": True,
0022     "IncludeCustoms": True
0023 }
0024 
0025 
0026 jsonConfig = {
0027     "_comments": "Created by theme_converter script"
0028 }
0029 editorColors = {
0030     "Color Background": "BackgroundColor",
0031     "Color Code Folding": "CodeFolding",
0032     "Color Current Line Number": "CurrentLineNumber",
0033     "Color Highlighted Bracket": "BracketMatching",
0034     "Color Highlighted Line": "CurrentLine",
0035     "Color Icon Bar": "IconBorder",
0036     "Color Indentation Line": "IndentationLine",
0037     "Color Line Number": "LineNumbers",
0038     "Color MarkType 1": "MarkBookmark",
0039     "Color MarkType 2": "MarkBreakpointActive",
0040     "Color MarkType 3": "MarkBreakpointReached",
0041     "Color MarkType 4": "MarkBreakpointDisabled",
0042     "Color MarkType 5": "MarkExecution",
0043     "Color MarkType 6": "MarkWarning",
0044     "Color MarkType 7": "MarkError",
0045     "Color Modified Lines": "ModifiedLines",
0046     "Color Replace Highlight": "ReplaceHighlight",
0047     "Color Saved Lines": "SavedLines",
0048     "Color Search Highlight": "SearchHighlight",
0049     "Color Selection": "TextSelection",
0050     "Color Separator": "Separator",
0051     "Color Spelling Mistake Line": "SpellChecking",
0052     "Color Tab Marker": "TabMarker",
0053     "Color Template Background": "TemplateBackground",
0054     "Color Template Editable Placeholder": "TemplatePlaceholder",
0055     "Color Template Focused Editable Placeholder": "TemplateFocusedPlaceholder",
0056     "Color Template Not Editable Placeholder": "TemplateReadOnlyPlaceholder",
0057     "Color Word Wrap Marker": "WordWrapMarker"
0058 }
0059 textStyles = {
0060     "Alert": "Alert",
0061     "Annotation": "Annotation",
0062     "Attribute": "Attribute",
0063     "Base-N Integer": "BaseN",
0064     "Built-in": "BuiltIn",
0065     "Character": "Char",
0066     "Comment": "Comment",
0067     "Comment Variable": "CommentVar",
0068     "Constant": "Constant",
0069     "Control Flow": "ControlFlow",
0070     "Data Type": "DataType",
0071     "Decimal/Value": "DecVal",
0072     "Documentation": "Documentation",
0073     "Error": "Error",
0074     "Extension": "Extension",
0075     "Floating Point": "Float",
0076     "Function": "Function",
0077     "Import": "Import",
0078     "Information": "Information",
0079     "Keyword": "Keyword",
0080     "Normal": "Normal",
0081     "Operator": "Operator",
0082     "Others": "Others",
0083     "Preprocessor": "Preprocessor",
0084     "Region Marker": "RegionMarker",
0085     "Special Character": "SpecialChar",
0086     "Special String": "SpecialString",
0087     "String": "String",
0088     "Variable": "Variable",
0089     "Verbatim String": "VerbatimString",
0090     "Warning": "Warning"
0091 }
0092 indexToStyle = {
0093     "0": "Normal",
0094     "1": "Keyword",
0095     "2": "Function",
0096     "3": "Variable",
0097     "4": "ControlFlow",
0098     "5": "Operator",
0099     "6": "BuiltIn",
0100     "7": "Extension",
0101     "8": "Preprocessor",
0102     "9": "Attribute",
0103     "10": "Char",
0104     "11": "SpecialChar",
0105     "12": "String",
0106     "13": "VerbatimString",
0107     "14": "SpecialString",
0108     "15": "Import",
0109     "16": "DataType",
0110     "17": "DecVal",
0111     "18": "BaseN",
0112     "19": "Float",
0113     "20": "Constant",
0114     "21": "Comment",
0115     "22": "Documentation",
0116     "23": "Annotation",
0117     "24": "CommentVar",
0118     "25": "RegionMarker",
0119     "26": "Information",
0120     "27": "Warning",
0121     "28": "Alert",
0122     "29": "Others",
0123     "30": "Error"
0124 }
0125 normalizedSections = {}
0126 custom_styles = {}
0127 
0128 
0129 def normalizeSections(sections: list):
0130     value: str
0131     for value in sections:
0132         normal = value
0133 
0134         if " - " in value:
0135             normal = normal.split(" - ")[0]
0136 
0137         normalizedSections[normal] = value
0138 
0139 
0140 def reEcodeColors(text: str) -> str:
0141     return "#" + text[2:]
0142 
0143 
0144 def reEncodeBool(text: str) -> bool:
0145     return True if text == "1" else False
0146 
0147 
0148 def rgb_to_hex(rgb: tuple) -> str:
0149     return '#%02x%02x%02x' % rgb
0150 
0151 
0152 def decodeTextStyle(text: str) -> dict:
0153     style = {}
0154 
0155     field = text.split(",")
0156 
0157     if len(field) == 11:
0158         styleIndex = field.pop(0)
0159         style = jsonConfig["text-styles"][indexToStyle[styleIndex]].copy()
0160 
0161     if len(field) != 10:
0162         return dict()
0163 
0164     if field[0] and len(field[0]) == 8:
0165         style["text-color"] = reEcodeColors(field[0])
0166     if field[1] and len(field[1]) == 8:
0167         style["selected-text-color"] = reEcodeColors(field[1])
0168     if field[2] and len(field[2]) == 1:
0169         style["bold"] = reEncodeBool(field[2])
0170     if field[3] and len(field[3]) == 1:
0171         style["italic"] = reEncodeBool(field[3])
0172     if field[4] and len(field[4]) == 1:
0173         style["strike-through"] = reEncodeBool(field[4])
0174     if field[5] and len(field[5]) == 1:
0175         style["underline"] = reEncodeBool(field[5])
0176     if field[6] and len(field[6]) == 8:
0177         style["background-color"] = reEcodeColors(field[6])
0178     if field[7] and len(field[7]) == 8:
0179         style["selected-text-color"] = reEcodeColors(field[7])
0180     # 8: font family > ignored
0181     # 9: --- > ignored
0182 
0183     return style
0184 
0185 
0186 def decodeColorSettings(text: str) -> str:
0187     fieldds = tuple(map(int, text.split(",")))
0188 
0189     if len(fieldds) != 3:
0190         return
0191 
0192     return rgb_to_hex(fieldds)
0193 
0194 
0195 def extractEditorColors(section: dict) -> dict:
0196     editor_colors = {}
0197 
0198     key: str
0199     value: str
0200     for key, value in section.items():
0201         editor_colors[editorColors[key]] = decodeColorSettings(value)
0202 
0203     return editor_colors
0204 
0205 
0206 def extractTextStyles(section: dict) -> dict:
0207     text_styles = {}
0208 
0209     key: str
0210     value: str
0211     for key, value in section.items():
0212         text_styles[textStyles[key]] = decodeTextStyle(value)
0213 
0214     return text_styles
0215 
0216 
0217 def extractCustomStyle(style: dict, realKey: str):
0218     global custom_styles
0219 
0220     key: str
0221     value: str
0222     for key, value in style.items():
0223         style = decodeTextStyle(value)
0224 
0225         primaryKey, SeondaryKey = key.split(":")[-2:]
0226 
0227         if primaryKey not in custom_styles:
0228             custom_styles[primaryKey] = dict()
0229 
0230         if style and SeondaryKey not in custom_styles[primaryKey]:
0231             custom_styles[primaryKey][SeondaryKey] = style
0232 
0233         if settings["prefferStandAloneData"] and style and realKey == primaryKey:
0234             custom_styles[primaryKey][SeondaryKey] = style
0235 
0236 
0237 def extractCustomStyles(config: ConfigParser) -> dict:
0238     global custom_styles
0239 
0240     key: str
0241     value: str
0242     for key, value in normalizedSections.items():
0243         if not key.startswith("Highlighting"):
0244             continue
0245 
0246         realKey = key[len("Highlighting "):]
0247 
0248         extractCustomStyle(config[value], realKey)
0249 
0250     return custom_styles
0251 
0252 
0253 def main(inputFile: str):
0254     config = ConfigParser(delimiters="=")
0255     config.optionxform = str
0256     config.read(inputFile)
0257 
0258     normalizeSections(config.sections())
0259 
0260     if "Editor Colors" in normalizedSections:
0261         jsonConfig["editor-colors"] = extractEditorColors(config[normalizedSections["Editor Colors"]])
0262     if "Default Item Styles" in normalizedSections:
0263         jsonConfig["text-styles"] = extractTextStyles(config[normalizedSections["Default Item Styles"]])
0264 
0265     if settings["IncludeCustoms"]:
0266         jsonConfig["custom-styles"] = extractCustomStyles(config)
0267 
0268     print(json.dumps(jsonConfig, indent=4, sort_keys=True))
0269 
0270 
0271 if __name__ == "__main__":
0272     if len(sys.argv) != 3:
0273         print("Usage: " + sys.argv[0] + " ThemeName Filepath.kateschema")
0274         exit()
0275 
0276     jsonConfig["metadata"] = {
0277         "name": str(sys.argv[1]),
0278         "revision": 1
0279     }
0280 
0281     main(str(sys.argv[2]))