~spacexplorer/+junk/myenv

« back to all changes in this revision

Viewing changes to vim/vim/ftplugin/latex-suite/outline.py

  • Committer: Kim Allamandola
  • Date: 2011-05-02 05:39:17 UTC
  • Revision ID: spacexplorer@gmail.com-20110502053917-x0yl2lr9ri4yskr2
InitĀ import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
# Part of Latex-Suite
 
4
#
 
5
# Copyright: Srinath Avadhanula
 
6
# Description:
 
7
#   This file implements a simple outline creation for latex documents.
 
8
 
 
9
import re
 
10
import os
 
11
import sys
 
12
import StringIO
 
13
 
 
14
# getFileContents {{{
 
15
def getFileContents(argin, ext=''):
 
16
    if type(argin) is str:
 
17
        fname = argin + ext
 
18
    else:
 
19
            fname = argin.group(3) + ext
 
20
 
 
21
    # This longish thing is to make sure that all files are converted into
 
22
    # \n seperated lines.
 
23
    contents = '\n'.join(open(fname).read().splitlines())
 
24
 
 
25
    # TODO what are all the ways in which a tex file can include another?
 
26
    pat = re.compile(r'^\\(@?)(include|input){(.*?)}', re.M)
 
27
    contents = re.sub(pat, lambda input: getFileContents(input, ext), contents)
 
28
 
 
29
    return ('%%==== FILENAME: %s' % fname) + '\n' + contents
 
30
 
 
31
# }}}
 
32
# stripComments {{{
 
33
def stripComments(contents):
 
34
    # remove all comments except those of the form
 
35
    # %%==== FILENAME: <filename.tex>
 
36
    uncomm = [re.sub('%(?!==== FILENAME: ).*', '', line) for line in contents.splitlines()]
 
37
    # also remove all only-whitespace lines.
 
38
    nonempty = [line for line in uncomm if line.strip()]
 
39
 
 
40
    return nonempty
 
41
# }}}
 
42
# addFileNameAndNumber {{{
 
43
def addFileNameAndNumber(lines):
 
44
    filename = ''
 
45
    retval = ''
 
46
    for line in lines:
 
47
        if re.match('%==== FILENAME: ', line):
 
48
            filename = line.split('%==== FILENAME: ')[1]
 
49
        else:
 
50
            retval += '<%s>%s\n' % (filename, line)
 
51
 
 
52
    return retval
 
53
# }}}
 
54
# getSectionLabels_Root {{{
 
55
def getSectionLabels_Root(lineinfo, section_prefix, label_prefix):
 
56
    prev_txt = ''
 
57
    inside_env = 0
 
58
    prev_env = ''
 
59
    outstr = StringIO.StringIO('')
 
60
    pres_depth = len(section_prefix)
 
61
 
 
62
    #print '+getSectionLabels_Root: lineinfo = [%s]' % lineinfo
 
63
    for line in lineinfo.splitlines():
 
64
        if not line:
 
65
            continue
 
66
 
 
67
        # throw away leading white-space
 
68
        m = re.search('<(.*?)>(.*)', line)
 
69
 
 
70
        fname = m.group(1)
 
71
        line = m.group(2).lstrip()
 
72
 
 
73
        # we found a label!
 
74
        m = re.search(r'\\label{(%s.*?)}' % label_prefix, line)
 
75
        if m:
 
76
            # add the current line (except the \label command) to the text
 
77
            # which will be displayed below this label
 
78
            prev_txt += re.search(r'(^.*?)\\label{', line).group(1)
 
79
 
 
80
            # for the figure environment however, just display the caption.
 
81
            # instead of everything since the \begin command.
 
82
            if prev_env == 'figure':
 
83
                cm = re.search(r'\caption(\[.*?\]\s*)?{(.*?)}', prev_txt)
 
84
                if cm:
 
85
                    prev_txt = cm.group(2)
 
86
 
 
87
            # print a nice formatted text entry like so
 
88
            #
 
89
            # >        eqn:label
 
90
            # :          e^{i\pi} + 1 = 0
 
91
            #
 
92
            # Use the current "section depth" for the leading indentation.
 
93
            print >>outstr, '>%s%s\t\t<%s>' % (' '*(2*pres_depth+2),
 
94
                    m.group(1), fname)
 
95
            print >>outstr, ':%s%s' % (' '*(2*pres_depth+4), prev_txt)
 
96
            prev_txt = ''
 
97
 
 
98
        # If we just encoutered the start or end of an environment or a
 
99
        # label, then do not remember this line. 
 
100
        # NOTE: This assumes that there is no equation text on the same
 
101
        # line as the \begin or \end command. The text on the same line as
 
102
        # the \label was already handled.
 
103
        if re.search(r'\\begin{(equation|eqnarray|align|figure)', line):
 
104
            prev_txt = ''
 
105
            prev_env = re.search(r'\\begin{(.*?)}', line).group(1)
 
106
            inside_env = 1
 
107
 
 
108
        elif re.search(r'\\label', line):
 
109
            prev_txt = ''
 
110
 
 
111
        elif re.search(r'\\end{(equation|eqnarray|align|figure)', line):
 
112
            inside_env = 0
 
113
            prev_env = ''
 
114
 
 
115
        else:
 
116
            # If we are inside an environment, then the text displayed with
 
117
            # the label is the complete text within the environment,
 
118
            # otherwise its just the previous line.
 
119
            if inside_env:
 
120
                prev_txt += line
 
121
            else:
 
122
                prev_txt = line
 
123
 
 
124
    return outstr.getvalue()
 
125
    
 
126
# }}}
 
127
# getSectionLabels {{{
 
128
def getSectionLabels(lineinfo, 
 
129
        sectypes=['chapter', 'section', 'subsection', 'subsubsection'], 
 
130
        section_prefix='', label_prefix=''):
 
131
 
 
132
    if not sectypes:
 
133
        return getSectionLabels_Root(lineinfo, section_prefix, label_prefix)
 
134
 
 
135
    ##print 'sectypes[0] = %s, section_prefix = [%s], lineinfo = [%s]' % (
 
136
    ##        sectypes[0], section_prefix, lineinfo)
 
137
 
 
138
    sections = re.split(r'(<.*?>\\%s{.*})' % sectypes[0], lineinfo)
 
139
    
 
140
    # there will 1+2n sections, the first containing the "preamble" and the
 
141
    # others containing the child sections as paris of [section_name,
 
142
    # section_text]
 
143
 
 
144
    rettext = getSectionLabels(sections[0], sectypes[1:], section_prefix, label_prefix)
 
145
    
 
146
    for i in range(1,len(sections),2):
 
147
        sec_num = (i+1)/2
 
148
        section_name = re.search(r'\\%s{(.*?)}' % sectypes[0], sections[i]).group(1)
 
149
        section_label_text = getSectionLabels(sections[i] + sections[i+1], sectypes[1:], 
 
150
                                    section_prefix+('%d.' % sec_num), label_prefix)
 
151
 
 
152
        if section_label_text:
 
153
            sec_heading = 2*' '*len(section_prefix) + section_prefix
 
154
            sec_heading += '%d. %s' % (sec_num, section_name)
 
155
            sec_heading += '<<<%d\n' % (len(section_prefix)/2+1)
 
156
 
 
157
            rettext += sec_heading + section_label_text
 
158
 
 
159
    return rettext
 
160
    
 
161
# }}}
 
162
 
 
163
# main {{{
 
164
def main(fname, label_prefix):
 
165
    [head, tail] = os.path.split(fname)
 
166
    if head:
 
167
        os.chdir(head)
 
168
 
 
169
    [root, ext] = os.path.splitext(tail)
 
170
    contents = getFileContents(root, ext)
 
171
    nonempty = stripComments(contents)
 
172
    lineinfo = addFileNameAndNumber(nonempty)
 
173
 
 
174
    return getSectionLabels(lineinfo, label_prefix=label_prefix)
 
175
# }}}
 
176
 
 
177
if __name__ == "__main__":
 
178
    if len(sys.argv) > 2:
 
179
        prefix = sys.argv[2]
 
180
    else:
 
181
        prefix = ''
 
182
 
 
183
    print main(sys.argv[1], prefix)
 
184
 
 
185
 
 
186
# vim: fdm=marker