1
###############################################################################
3
# Purpose: Generate Tags for Php documents #
4
# Author: Cody Precord <cprecord@editra.org> #
5
# Copyright: (c) 2008 Cody Precord <staff@editra.org> #
6
# License: wxWindows License #
7
###############################################################################
14
Generate a DocStruct object that captures the structure of a Php document.
15
Currently it supports parsing for Classes, Class Variables, Class Methods, and
20
__author__ = "Cody Precord <cprecord@editra.org>"
21
__svnid__ = "$Id: phptags.py 60797 2009-05-29 22:41:06Z CJP $"
22
__revision__ = "$Revision: 60797 $"
24
#--------------------------------------------------------------------------#
29
#--------------------------------------------------------------------------#
31
def GenerateTags(buff):
32
"""Create a DocStruct object that represents a Php Script
33
@param buff: a file like buffer object (StringIO)
36
rtags = taglib.DocStruct()
38
# Setup document structure
39
rtags.SetElementDescription('function', "Function Definitions")
41
inphp = False # Are we in a php section or not
42
inclass = False # Inside a class defintion
43
incomment = False # Inside a comment
44
infundef = False # Inside a function definition
48
openb = 0 # Keep track of open brackets
50
for lnum, line in enumerate(buff):
54
while idx < len(line):
56
idx = parselib.SkipWhitespace(line, idx)
58
# Walk through strings ignoring contents
59
if instring or line[idx] in (u"'", u'"'):
60
idx, instring = parselib.FindStringEnd(line[idx:], idx)
61
# For multiline strings
65
# Check if in a <?php ?> block or not
66
if line[idx:].startswith(u'<?'):
68
if line[idx:].startswith(u'php'):
71
elif line[idx:].startswith(u'?>'):
75
# Skip anything not in side of a php section
81
if line[idx:].startswith(u'/*'):
84
elif line[idx:].startswith(u'//') or line[idx:].startswith(u'#'):
85
break # go to next line
86
elif line[idx:].startswith(u'*/'):
97
elif line[idx] == u'{':
100
# Class name must be followed by a {
101
if not inclass and lastclass is not None:
103
rtags.AddClass(lastclass)
104
elif lastfun is not None:
109
elif line[idx] == u'}':
112
if inclass and openb == 0:
115
elif infundef and inclass and openb == 1:
117
elif infundef and openb == 0:
122
elif not infundef and parselib.IsToken(line, idx, u'class'):
124
idx = parselib.SkipWhitespace(line, idx + 5)
125
name = parselib.GetFirstIdentifier(line[idx:])
127
idx += len(name) # Move past the class name
128
lastclass = taglib.Class(name, lnum)
129
elif parselib.IsToken(line, idx, u'function'):
131
idx = parselib.SkipWhitespace(line, idx + 8)
132
name = parselib.GetFirstIdentifier(line[idx:])
136
idx = parselib.SkipWhitespace(line, idx + len(name))
138
if line[idx] != u'(':
141
if inclass and lastclass is not None:
142
lastclass.AddMethod(taglib.Method(name, lnum, lastclass.GetName()))
144
rtags.AddFunction(taglib.Function(name, lnum))
145
elif inclass and parselib.IsToken(line, idx, u'var'):
146
# Look for class variables
148
parts = line[idx:].split()
149
if len(parts) and parts[0].startswith(u'$'):
150
name = parselib.GetFirstIdentifier(parts[0][1:])
151
if name is not None and lastclass is not None:
153
lastclass.AddVariable(taglib.Variable(name, lnum, lastclass.GetName()))
160
#-----------------------------------------------------------------------------#
163
if __name__ == '__main__':
167
fhandle = open(sys.argv[1])
170
tags = GenerateTags(StringIO.StringIO(txt))
171
print "\n\nElements:"
173
def printElements(elements):
174
for element in elements:
175
print "\n%s:" % element.keys()[0]
176
for val in element.values()[0]:
177
print "%s [%d]" % (val.GetName(), val.GetLine())
178
if isinstance(val, taglib.Scope):
180
printElements(val.GetElements())
182
elements = tags.GetElements()
183
printElements(elements)