📄 qc2html.py
字号:
#!/usr/local/bin/python
##
##
## QC2HTML Copyright (c) 1996, Olivier Montanuy
## Version 1.0, August 1st, 1996
##
##
## Run this Python program in a directory, with no arguments.
## It will look for file "progs.src", read it, and then process all
## .QC (Quake C) files into HTML, with anchors for functions.
## It assumes that file builtin.htm exists, and contains definitions
## for the Quake C buit-in types, variables, functions.
##
## About Python:
## see http://www.python.org/
## Basically it's a (slow) scripting language, that can run on
## Unix, Linux, Windows 95 (I recommend PythonWin there).
##
## Technical info:
## This program isn't a true Quake C analyser. It works with regular
## expressions,so it's slow as hell, and might bug in some cases.
## Go rewrite it in CAML or C (yacc) if you have time to waste.
##
## Disclaimer:
## Use at your own risk. No liabilities. None at all. Even toward *you*.
## Don't try to understand that code. You have been warned. If your brain
## fries, or you die laughting, I'm not feeling concerned.
##
## bugs: fileds are not tagged correctly
## file where the list of files shall be found
ProgsSrc = "progs.src"
## Pattern of the files to transform
## <anything>.qc
TransPattern = "\(\w[a-zA-Z0-9_]*[.]qc\)"
## Quake-C keywords
KeywordList = [ 'do', 'else', 'for', 'if', 'local', 'return', 'while' ]
##
## Built-in Required functions, or documented function:
##
## use a tag <a name="f_xxxx">xxxx</a> to define
## them, where xxxx is the name of the function.
## qc2html will look for that tag in the KnownAnchor
## files, and link the function definition to it.
## That's an easy way to document your functions.
##
##
## Declare all the files that contain known anchors
## Those anchors will be found according to pattern <a name="...">
## To define anchors not to be referenced by quake-C, use <A NAME="...">
#KnownAnchors = [ ... , "manual.htm" ]
KnownAnchors = ["qc-mdl.htm", "qc-types.htm", "qc-defs.htm", "qc-vars.htm", "qc-enty.htm",
"qc-glob.htm", "qc-built.htm", "qc-netf.htm", "qc-net.htm", ]
#
##
## User defined functions
##
# TransTableAdd(expc.group(1)) #add to translation table
# declare expc.group(1) as an anchor location
def UNewAnchor1(expc, infos):
infos.Anchs.Declare( expc.group(1))
return ""
## declare a variable
def UVariable123(expc, infos):
space = expc.group(1)
if space == None: space = ""
typ= expc.group(2)
name = expc.group(3)
# this is a hack, because return val; is confused with a declaration
if typ == "return":
return expc.group(0) #everything
# check if variable is known
if infos.Anchs.IsKnown(typ):
typ = infos.Anchs.Href( typ, typ )
if infos.Anchs.IsKnown(name):
name = infos.Anchs.Href( name, name)
else:
infos.Anchs.Declare(name)
name = "<a name=\"" + name + "\">" + name + "</a>"
return space + typ + " <b>" + name + "</b>;"
## declare a constant
def UConstant1234(expc, infos):
space = expc.group(1)
if space == None: space = ""
typ= expc.group(2)
name = expc.group(3)
value = expc.group(4)
if not infos.Anchs.IsKnown(name):
infos.Anchs.Declare(name)
name = "<a name=\"" + name + "\">" + name + "</a>"
if infos.Anchs.IsKnown(typ):
typ = infos.Anchs.Href( typ, typ )
return space + typ + " <b>" + name + "</b> = " + value + ";"
## transform expc.group(1)
def UToken1(expc, infos):
token = expc.group(1)
if infos.Keys.IsKeyword(token):
return "<b>"+token+"</b>"
elif infos.Anchs.IsKnown(token):
return infos.Anchs.Href(token, token)
return token
## define a new function
def UFunction1(expc, infos):
token = expc.group(1)
infos.Anchs.Declare(token) # declare function
# required functions have anchor = "f_xxxx"
fname = "f_"+token
if infos.Anchs.Required.has_key(fname): #required
func = infos.Anchs.Href(fname, token)
else: # normal function
func = token
return ") <b>"+ func + "</b><a name=\""+token+"\">=</a>"
## pre-declare a new function
def UFDeclare1(expc, infos):
token = expc.group(1)
infos.Anchs.PreDeclare(token) # pre-declare function
func = infos.Anchs.Href(token, token) # point to function
return ") " + func + ";"
# declare a ".xxxx" stuff
def UDotField12(expc, infos):
field = expc.group(1)
paren = expc.group(2)
if paren == None: paren = ""
hack = "dot_" + field
if infos.Anchs.IsKnown(hack):
field = infos.Anchs.Href(hack, field)
return "." + field + paren
# declare a new dollar definition (for models)
def UDollar12(expc, infos):
token = expc.group(1) # definition
data = expc.group(2) # data of definition
hack = "s_"+token # anchor is s_xxxx
anchor = infos.Anchs.Href(hack, token) # anchor "$"
return "<b>$</b>" + anchor + " <b>" + data + "</b>"
##
## Translation table = [ (Exp, Sub ,FFun), ... ]
##
## Exp = regular expression to be matched, with groups
## Sub = substituted regular expression, with groups
## FFun = None or User-defined function to execute on expression
##
TransDef = [
# Strings: anything in quotes, is highlighted
( "\"\(.*\)\"",
"<b>\"\\1\"</b>", None ),
# Comments:
# ex: // anything
( "//\(.*\)\n",
"<i>//\\1</i>\n", None),
# Comments
# ex: /* anything */
( "/[*]\([^*]*\)[*]/",
"<i>/*\\1*/</i>\n", None),
# < and >
( "<", "<", None),
( ">", ">", None),
( "&", "&", None),
# dot field
( "[.]\([a-zA-Z_][a-zA-Z0-9_]*\)\([ \t]*()\)?",
None, UDotField12),
# builtin function definition
# ex: ") scv_xxx = #"
( ")[ _t]*\(\w[a-zA-Z0-9_]*\)[ \t]*=[ \t]*#[ \t]*\([0-9]+\)[ \t]*;",
") <b>\\1</b> = #<b>\\2</b>;", None),
# function definition
# ex: ") boss_missile ="
( ")[ \t]*\(\w[a-zA-Z0-9_]*\)[ \t]*=",
None, UFunction1),
# function declaration
# ex: ") movetarget_f;"
( ")[ \t]*\(\w[a-zA-Z0-9_]*\)[ \t]*;",
None, UFDeclare1),
# variable declaration
# ex: "float current_yaw;"
( "^\([ \t]*\)\(\w[a-zA-Z0-9_]*\)[ \t]+\(\w[a-zA-Z0-9_]*\)[ \t]*;",
None, UVariable123),
# constant declaration
# ex: "float ATTN_STATIC = 3;"
( "^\([ \t]*\)\(\w[a-zA-Z0-9_]*\)[ \t]+\(\w[a-zA-Z0-9_]*\)[ \t]*=[ \t]*\(.*\);",
None, UConstant1234),
# definition
# ex: $skin skin
( "^$\(\w[a-zA-Z0-9_]*\)[ \t]+\(.*\)",
None, UDollar12),
# token
( "\\b\([a-zA-Z0-9_][a-zA-Z0-9_---]*\)\\b",
None, UToken1) ]
## RegExp
## "\w+" = one or more word characters
## "\(\w+\)" = a word in a group (group(1), group(2), etc...)
## "\\b" = a word boundary
## " *" = zero or more spaces
#
# Html Header
#
def TransHtmlHead(fileName):
res = "<html><head><title>" + fileName + "</title></head>"
res = res + "<body bgcolor=\"#C0F0D0\">\n"
res = res + "<base target=examine>\n<pre>\n"
return res
#
# Html Trailer
#
def TransHtmlTrail(fileName):
return "\n</pre></body></html>"
######################################################################
# Do not edit after this line
######################################################################
import regex
import regsub
import string
import fnmatch
import os
##
## Save a file
## info = (file, txt)
def FileWrite(info):
try:
(file, txt) = info
fp = open(file,"w")
fp.write(txt)
fp.close()
return info
except:
print "Can't write file ", file
return None
##
## Read a file
## file = filename
def FileRead(file):
try:
fp=open(file,"r")
txt=fp.read() #
fp.close()
return txt
except:
print "Can't read file ", file
return None
#
# convert extension of file name to .html
#
def FileHtml(file):
(root,ext)=os.path.splitext(file)
return root + ".htm"
##
## KeyWords
##
class KeyWords:
# IsKeyword(self, token)
Keys= {}
def __init__(self, keylist):
self.Keys= {}
for k in keylist:
self.Keys[k] = "" # declare all keywords
return
# return 1 if token exists
def IsKeyword(self, token):
if self.Keys.has_key(token):
return 1
return 0
##
## Modules
##
class Modules:
# Declaration of the paths of the modules
# m = Modules() # create an instance of class Modules
# mod = m.DeclarePath(file) # declare new module file, return module name
# m.DeclareBasePath(path) # set base path
# file = m.GetFile(mod) # get root file of a given module (no extension)
# Inquiries about module usage:
# m.NoneUsed() # clear off module used
# m.Used(mod) # declare module is used in the current file
# bool = m.IsUsed(mod) # return 1 if module exists
# Hidden variables:
# self._mods = { "moduleName":"modulePath", ...}
# self._curr ={ "moduleName":1, ...}
# self._base = "basePathForAllModules"
##
## m = Modules()
##
def __init__(self):
self._mods = {} # dictionary of known modules
self._curr = {} # dictionary of current modules
self._base = ""
return
##
## m.DeclarePath( file)
## file = "/directory/file.ext"
def DeclarePath(self, file):
(root, ext) = os.path.splitext(file) # get extension
(path, mod) = os.path.split(root) # get path
self._mods[mod]= path # declare
return mod # return module name
##
## m.DeclareBasePath( file)
## path = "/directory/"
def DeclareBasePath(self,file):
( self._base, name) = os.path.split(file)
return
##
## file= m.GetFile(mod)
## file = "/directory/file" no extension
def GetFile(self, mod):
if not self._mods.has_key(mod):
return ""
path= os.path.join(self._base,self._mods[mod])
return os.path.join(path, mod)
# m.NoneUsed()
# declare no modules are used yet
def NoneUsed(self):
self._curr = {}
return
# m.Used(mod)
# declare that module is used
def Used(self, mod):
self._curr[mod] = 1
# m.IsUsed(mod)
# check if module is used
def IsUsed(self, mod):
return self._curr.has_key(token)
##
## Anchors
##
class Anchors:
# a =Anchors(KnownAnchors)
# a.DeclareModule(mod) # declare name of current module
# a.Declare(anchor) # declare an achor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -