mirror of
				https://github.com/notepad-plus-plus/notepad-plus-plus.git
				synced 2025-10-31 11:34:05 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			226 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			226 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # ScintillaData.py - implemented 2013 by Neil Hodgson neilh@scintilla.org
 | |
| # Released to the public domain.
 | |
| 
 | |
| # Common code used by Scintilla and SciTE for source file regeneration.
 | |
| # The ScintillaData object exposes information about Scintilla as properties:
 | |
| # Version properties
 | |
| #     version
 | |
| #     versionDotted
 | |
| #     versionCommad
 | |
| #     
 | |
| # Date last modified
 | |
| #     dateModified
 | |
| #     yearModified
 | |
| #     mdyModified
 | |
| #     dmyModified
 | |
| #     myModified
 | |
| #     
 | |
| # Information about lexers and properties defined in lexers
 | |
| #     lexFiles
 | |
| #         sorted list of lexer files
 | |
| #     lexerModules
 | |
| #         sorted list of module names
 | |
| #     lexerProperties
 | |
| #         sorted list of lexer properties
 | |
| #     propertyDocuments
 | |
| #         dictionary of property documentation { name: document string }
 | |
| 
 | |
| # This file can be run to see the data it provides.
 | |
| # Requires Python 2.5 or later
 | |
| 
 | |
| from __future__ import with_statement
 | |
| 
 | |
| import codecs, datetime, glob, os, sys, textwrap
 | |
| 
 | |
| import FileGenerator
 | |
| 
 | |
| def FindModules(lexFile):
 | |
|     modules = []
 | |
|     with open(lexFile) as f:
 | |
|         for l in f.readlines():
 | |
|             if l.startswith("LexerModule"):
 | |
|                 l = l.replace("(", " ")
 | |
|                 modules.append(l.split()[1])
 | |
|     return modules
 | |
| 
 | |
| # Properties that start with lexer. or fold. are automatically found but there are some
 | |
| # older properties that don't follow this pattern so must be explicitly listed.
 | |
| knownIrregularProperties = [
 | |
|     "fold",
 | |
|     "styling.within.preprocessor",
 | |
|     "tab.timmy.whinge.level",
 | |
|     "asp.default.language",
 | |
|     "html.tags.case.sensitive",
 | |
|     "ps.level",
 | |
|     "ps.tokenize",
 | |
|     "sql.backslash.escapes",
 | |
|     "nsis.uservars",
 | |
|     "nsis.ignorecase"
 | |
| ]
 | |
| 
 | |
| def FindProperties(lexFile):
 | |
|     properties = {}
 | |
|     with open(lexFile) as f:
 | |
|         for l in f.readlines():
 | |
|             if ("GetProperty" in l or "DefineProperty" in l) and "\"" in l:
 | |
|                 l = l.strip()
 | |
|                 if not l.startswith("//"):	# Drop comments
 | |
|                     propertyName = l.split("\"")[1]
 | |
|                     if propertyName.lower() == propertyName:
 | |
|                         # Only allow lower case property names
 | |
|                         if propertyName in knownIrregularProperties or \
 | |
|                             propertyName.startswith("fold.") or \
 | |
|                             propertyName.startswith("lexer."):
 | |
|                             properties[propertyName] = 1
 | |
|     return properties
 | |
| 
 | |
| def FindPropertyDocumentation(lexFile):
 | |
|     documents = {}
 | |
|     with open(lexFile) as f:
 | |
|         name = ""
 | |
|         for l in f.readlines():
 | |
|             l = l.strip()
 | |
|             if "// property " in l:
 | |
|                 propertyName = l.split()[2]
 | |
|                 if propertyName.lower() == propertyName:
 | |
|                     # Only allow lower case property names
 | |
|                     name = propertyName
 | |
|                     documents[name] = ""
 | |
|             elif "DefineProperty" in l and "\"" in l:
 | |
|                 propertyName = l.split("\"")[1]
 | |
|                 if propertyName.lower() == propertyName:
 | |
|                     # Only allow lower case property names
 | |
|                     name = propertyName
 | |
|                     documents[name] = ""
 | |
|             elif name:
 | |
|                 if l.startswith("//"):
 | |
|                     if documents[name]:
 | |
|                         documents[name] += " "
 | |
|                     documents[name] += l[2:].strip()
 | |
|                 elif l.startswith("\""):
 | |
|                     l = l[1:].strip()
 | |
|                     if l.endswith(";"):
 | |
|                         l = l[:-1].strip()
 | |
|                     if l.endswith(")"):
 | |
|                         l = l[:-1].strip()
 | |
|                     if l.endswith("\""):
 | |
|                         l = l[:-1]
 | |
|                     # Fix escaped double quotes
 | |
|                     l = l.replace("\\\"", "\"")
 | |
|                     documents[name] += l
 | |
|                 else:
 | |
|                     name = ""
 | |
|     for name in list(documents.keys()):
 | |
|         if documents[name] == "":
 | |
|             del documents[name]
 | |
|     return documents
 | |
| 
 | |
| def FindCredits(historyFile):
 | |
|     credits = []
 | |
|     stage = 0
 | |
|     with codecs.open(historyFile, "r", "utf-8") as f:
 | |
|         for l in f.readlines():
 | |
|             l = l.strip()
 | |
|             if stage == 0 and l == "<table>":
 | |
|                 stage = 1
 | |
|             elif stage == 1 and l == "</table>":
 | |
|                 stage = 2
 | |
|             if stage == 1 and l.startswith("<td>"):
 | |
|                 credit = l[4:-5]
 | |
|                 if "<a" in l:
 | |
|                     title, a, rest = credit.partition("<a href=")
 | |
|                     urlplus, bracket, end = rest.partition(">")
 | |
|                     name = end.split("<")[0]
 | |
|                     url = urlplus[1:-1]
 | |
|                     credit = title.strip()
 | |
|                     if credit:
 | |
|                         credit += " "
 | |
|                     credit += name + " " + url
 | |
|                 credits.append(credit)
 | |
|     return credits
 | |
| 
 | |
| def ciCompare(a,b):
 | |
|     return cmp(a.lower(), b.lower())
 | |
| 
 | |
| def ciKey(a):
 | |
|     return a.lower()
 | |
| 
 | |
| def SortListInsensitive(l):
 | |
|     try:    # Try key function
 | |
|         l.sort(key=ciKey)
 | |
|     except TypeError:    # Earlier version of Python, so use comparison function
 | |
|         l.sort(ciCompare)
 | |
| 
 | |
| class ScintillaData:
 | |
|     def __init__(self, scintillaRoot):
 | |
|         # Discover verion information
 | |
|         with open(scintillaRoot + "version.txt") as f:
 | |
|             self.version = f.read().strip()
 | |
|         self.versionDotted = self.version[0] + '.' + self.version[1] + '.' + \
 | |
|             self.version[2]
 | |
|         self.versionCommad = self.version[0] + ', ' + self.version[1] + ', ' + \
 | |
|             self.version[2] + ', 0'
 | |
| 
 | |
|         with open(scintillaRoot + "doc/index.html") as f:
 | |
|             self.dateModified = [l for l in f.readlines() if "Date.Modified" in l]\
 | |
|                 [0].split('\"')[3]
 | |
|             # 20130602
 | |
|             # index.html, SciTE.html
 | |
|             dtModified = datetime.datetime.strptime(self.dateModified, "%Y%m%d")
 | |
|             self.yearModified = self.dateModified[0:4]
 | |
|             monthModified = dtModified.strftime("%B")
 | |
|             dayModified = "%d" % dtModified.day
 | |
|             self.mdyModified = monthModified + " " + dayModified + " " + self.yearModified
 | |
|             # May 22 2013
 | |
|             # index.html, SciTE.html
 | |
|             self.dmyModified = dayModified + " " + monthModified + " " + self.yearModified
 | |
|             # 22 May 2013
 | |
|             # ScintillaHistory.html -- only first should change
 | |
|             self.myModified = monthModified + " " + self.yearModified
 | |
| 
 | |
|         # Find all the lexer source code files
 | |
|         lexFilePaths = glob.glob(scintillaRoot + "lexers/Lex*.cxx")
 | |
|         SortListInsensitive(lexFilePaths)
 | |
|         self.lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths]
 | |
|         self.lexerModules = []
 | |
|         lexerProperties = set()
 | |
|         self.propertyDocuments = {}
 | |
|         for lexFile in lexFilePaths:
 | |
|             self.lexerModules.extend(FindModules(lexFile))
 | |
|             for k in FindProperties(lexFile).keys():
 | |
|                 lexerProperties.add(k)
 | |
|             documents = FindPropertyDocumentation(lexFile)
 | |
|             for k in documents.keys():
 | |
|                 if k not in self.propertyDocuments:
 | |
|                     self.propertyDocuments[k] = documents[k]
 | |
|         SortListInsensitive(self.lexerModules)
 | |
|         self.lexerProperties = list(lexerProperties)
 | |
|         SortListInsensitive(self.lexerProperties)
 | |
| 
 | |
|         self.credits = FindCredits(scintillaRoot + "doc/ScintillaHistory.html")
 | |
| 
 | |
| def printWrapped(text):
 | |
|     print(textwrap.fill(text, subsequent_indent="    "))
 | |
| 
 | |
| if __name__=="__main__":
 | |
|     sci = ScintillaData("../")
 | |
|     print("Version   %s   %s   %s" % (sci.version, sci.versionDotted, sci.versionCommad))
 | |
|     print("Date last modified    %s   %s   %s   %s   %s" % (
 | |
|         sci.dateModified, sci.yearModified, sci.mdyModified, sci.dmyModified, sci.myModified))
 | |
|     printWrapped(str(len(sci.lexFiles)) + " lexer files: " + ", ".join(sci.lexFiles))
 | |
|     printWrapped(str(len(sci.lexerModules)) + " lexer modules: " + ", ".join(sci.lexerModules))
 | |
|     printWrapped("Lexer properties: " + ", ".join(sci.lexerProperties))
 | |
|     print("Lexer property documentation:")
 | |
|     documentProperties = list(sci.propertyDocuments.keys())
 | |
|     SortListInsensitive(documentProperties)
 | |
|     for k in documentProperties:
 | |
|         print("    " + k)
 | |
|         print(textwrap.fill(sci.propertyDocuments[k], initial_indent="        ",
 | |
|             subsequent_indent="        "))
 | |
|     print("Credits:")
 | |
|     for c in sci.credits:
 | |
|         if sys.version_info[0] == 2:
 | |
|             print("    " + c.encode("utf-8"))
 | |
|         else:
 | |
|             sys.stdout.buffer.write(b"    " + c.encode("utf-8") + b"\n")
 |