]> git.lyx.org Git - lyx.git/blob - lib/scripts/clean_dvi.py
Check path of Qt tools if qtchooser is detected
[lyx.git] / lib / scripts / clean_dvi.py
1 '''
2 file clean_dvi.py
3 This file is part of LyX, the document processor.
4 Licence details can be found in the file COPYING
5 or at http://www.lyx.org/about/licence.php
6
7 author Angus Leeming
8 Full author contact details are available in the file CREDITS
9 or at http://www.lyx.org/about/credits.php
10
11 Usage:
12     python clean_dvi.py infile.dvi outfile.dvi
13
14 clean_dvi modifies the input .dvi file so that
15 dvips and yap (a dvi viewer on Windows) can find
16 any embedded PostScript files whose names are protected
17 with "-quotes.
18
19 It works by:
20 1 translating the machine readable .dvi file to human
21   readable .dtl form,
22 2 manipulating any references to external files
23 3 translating the .dtl file back to .dvi format.
24
25 It requires dv2dt and dt2dv from the DTL dviware package
26 http://www.ctan.org/tex-archive/dviware/dtl/
27 '''
28
29 import os, re, subprocess, sys
30
31 def usage(prog_name):
32     return 'Usage: %s in.dvi out.dvi\n' \
33            % os.path.basename(prog_name)
34
35
36 def warning(message):
37     sys.stderr.write(message + '\n')
38
39
40 def error(message):
41     sys.stderr.write(message + '\n')
42     sys.exit(1)
43
44
45 def manipulated_dtl(data):
46     psfile_re = re.compile(r'(special1 +)([0-9]+)( +\'PSfile=")(.*)(" llx=.*)')
47
48     lines = data.split('\n')
49     for i in range(len(lines)):
50         line = lines[i]
51         match = psfile_re.match(line)
52         if match != None:
53             file = match.group(4)
54             filelen = len(file)
55             file = file.replace('"', '')
56             # Don't forget to update the length of the string too...
57             strlen = int(match.group(2)) - (filelen - len(file))
58
59             lines[i] = '%s%d%s%s%s' \
60                        % ( match.group(1), strlen, match.group(3),
61                            file, match.group(5) )
62
63     return '\n'.join(lines)
64
65
66 def main(argv):
67     # First establish that the expected information has
68     # been input on the command line and whether the
69     # required executables exist.
70     if len(argv) != 3:
71         error(usage(argv[0]))
72
73     infile  = argv[1]
74     outfile = argv[2]
75
76     if not os.path.exists(infile):
77         error('Unable to read "%s"\n' % infile)
78
79     # Convert the input .dvi file to .dtl format.
80     if os.name == 'nt':
81         unix = False
82     else:
83         unix = True
84     dv2dt_call = 'dv2dt "%s"' % infile
85     dv2dt_pipe = subprocess.Popen(dv2dt_call, universal_newlines=True, \
86         stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, \
87         shell=unix, close_fds=unix)
88     (dv2dt_stdin, dv2dt_stdout, dv2dt_stderr) = \
89         (dv2dt_pipe.stdin, dv2dt_pipe.stdout, dv2dt_pipe.stderr)
90
91     dv2dt_stdin.close()
92     dv2dt_data   = dv2dt_stdout.read()
93     dv2dt_status = dv2dt_stdout.close()
94
95     if dv2dt_status != None or len(dv2dt_data) == 0:
96         dv2dt_err = dv2dt_stderr.read()
97         error("Failed: %s\n%s\n" % ( dv2dt_call, dv2dt_err) )
98
99     # Manipulate the .dtl file.
100     dtl_data = manipulated_dtl(dv2dt_data)
101     if dtl_data == None:
102         error("Failed to manipulate the dtl file")
103
104     # Convert this .dtl file back to .dvi format.
105     dt2dv_call = 'dt2dv -si "%s"' % outfile
106     dt2dv_stdin = os.popen(dt2dv_call, 'w')
107     dt2dv_stdin.write(dtl_data)
108
109
110 if __name__ == "__main__":
111     main(sys.argv)