File: extract-file-magic.py

package info (click to toggle)
gwyddion 2.62-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 51,952 kB
  • sloc: ansic: 398,486; python: 7,877; sh: 5,492; makefile: 4,723; xml: 3,883; cpp: 1,969; pascal: 418; perl: 154; ruby: 130
file content (153 lines) | stat: -rwxr-xr-x 5,373 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/python2
# vim: fileencoding=utf-8 sw=4 ts=4 et :
# Written by Yeti <yeti@gwyddion.net>. Public domain.
import sys, os, re

# The global mapping between footnote ids (as they appear in the guide) and
# their texts.  This is used to compactify footnotes with an identical text.
footnotes = {}

def format_userguide(module, body):
    DESCRIPTION, EXTENSIONS, SUPPORTS, NOTES = range(4)
    parsesupport = re.compile(r'(?P<name>\w+)'
                              r'(?::(?P<alias>\w+))?'
                              r'(?:\[(?P<note>\w+)\])?').match
    parsenotes = re.compile(r'(?ms)\[(?P<note>\w+)\]\s*(?P<text>[^[]*)')
    entry = '  <entry>%s</entry>'

    # Return the local mapping for a footnote (i.e. between [1] in the comment
    # in source code and the text that should go to the user guide).
    def register_note(footnotes, note):
        key, text = note.group('note'), note.group('text').strip()
        for fnkey, entry in footnotes.items():
            fntext, label = entry
            if text == fntext:
                fmttext = '<footnoteref linkend="%s" label="%s"/>' \
                          % (fnkey, label)
                return key, fmttext
        fnkey = 'table-file-formats-fn%d' % (len(footnotes) + 1)
        label = chr(ord('a') + len(footnotes))
        fmttext = '<footnote id="%s" label="%s"><para>%s</para></footnote>' \
                  % (fnkey, label, text)
        footnotes[fnkey] = (text, label)
        return key, fmttext

    def fmtsup(supported, noterefs, what):
        yes = 'Yes'
        for x in supported:
            name = x['name']
            if name in what:
                if x['alias']:
                    yes = x['alias']
                if x['note']:
                    yes += noterefs[x['note']]
                return yes
        return '—'

    module = re.sub(r'\.cc?$', '', module)
    out = ['<row>']
    lines = body.split('\n')[:NOTES]
    noterefs = {}
    for note in parsenotes.finditer('\n'.join(body.split('\n')[NOTES:])):
        key, text = register_note(footnotes, note)
        noterefs[key] = text
    out.append(entry % lines[DESCRIPTION])
    out.append(entry % lines[EXTENSIONS])
    out.append(entry % module)
    supinfo = [parsesupport(x).groupdict() for x in lines[SUPPORTS].split()]
    out.append(entry % fmtsup(supinfo, noterefs, ('Read',)))
    out.append(entry % fmtsup(supinfo, noterefs, ('Save', 'Export')))
    out.append(entry % fmtsup(supinfo, noterefs, ('SPS',)))
    out.append(entry % fmtsup(supinfo, noterefs, ('Volume',)))
    out.append('</row>')
    for i, x in enumerate(out):
        out[i] = '    ' + x
    return '\n'.join(out)

mclasses = {
    'FREEDESKTOP': {
        'comment': '<!-- %s -->',
        'header': '''<?xml version="1.0"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>''',
        'footer': '</mime-info>'
    },
    'FILEMAGIC': {
        'comment': '# %s',
    },
    'USERGUIDE': {
        'comment': '    <!-- %s -->',
        'header': '''<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE book PUBLIC '-//OASIS//DTD DocBook XML V4.5//EN'
               'http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd'>
<informaltable id='table-file-formats'>
  <indexterm>
    <primary>file</primary>
    <primary>supported formats</primary>
  </indexterm>
  <tgroup cols='6' align='left'>
    <?dblatex XXlcccc?>
    <thead>
      <row>
        <entry>File Format</entry>
        <entry>Extensions</entry>
        <entry>Module</entry>
        <entry>Read</entry>
        <entry>Write</entry>
        <entry>SPS</entry>
        <entry>Volume</entry>
      </row>
    </thead>
    <tbody>''',
        'footer': '''    </tbody>
  </tgroup>
</informaltable>''',
        'formatter': format_userguide,
     },
}

try:
    magic = mclasses[sys.argv[1]]
except KeyError:
    sys.stderr.write('Unknown magic class %s\n' % sys.argv[1])
    sys.exit(1)
except IndexError:
    print 'Usage: %s CLASS [FILES...]' % sys.argv[0]
    print 'Available classes: %s' % ' '.join(mclasses.keys())
    sys.exit(0)

magic_block_re = re.compile(r'(?m)^/\*\*\n \* '
                            + r'\[FILE-MAGIC-' + sys.argv[1] + r'\]\n'
                            + r'(?P<body>(?: \* .*\n)+) \*\*/$')
output = []

if magic.has_key('header'):
    output.append(magic['header'])

# Keep the `GENERATED' string split to prevent match here
output.append(magic['comment'] % ('This is a ' + 'GENERATED' + ' file.'))

for filename in sys.argv[2:]:
    base = os.path.basename(filename)
    try:
        # output From module... comment only if something is found
        comment = magic['comment'] % ('From module ' + base)
        for m in magic_block_re.finditer(file(filename).read()):
            if comment:
                output.append(comment)
                comment = None
            body = re.sub(r'(?m)^ \* ', '', m.group('body'))
            if 'formatter' in magic:
                body = magic['formatter'](base, body)
            output.append(body)
        # and when nothing is found, note it
        if comment:
            comment = magic['comment'] % ('Module %s contains no magic.' % base)
            output.append(comment)
    except OSError:
        sys.stderr.write('Cannot read %s\n' % filename)
        sys.exit(1)

if magic.has_key('footer'):
    output.append(magic['footer'])

print '\n'.join(output)