]> git.lyx.org Git - lyx.git/blob - lib/configure.py
* src/format.[Ch]
[lyx.git] / lib / configure.py
1 #! /usr/bin/env python
2 #
3 # file configure.py
4 # This file is part of LyX, the document processor.
5 # Licence details can be found in the file COPYING.
6
7 # \author Bo Peng
8 # Full author contact details are available in file CREDITS.
9
10 # This is an experimental version of the configure script, written
11 # in Python. 
12
13 import sys, os, re, shutil, glob
14
15
16 def writeToFile(filename, lines, append = False):
17   " utility function: write or append lines to filename "
18   if append:
19     file = open(filename, 'a')
20   else:
21     file = open(filename, 'w')
22   file.write(lines)
23   file.close()
24
25
26 def addToRC(lines):
27   ''' utility function: shortcut for appending lines to outfile
28     add newline at the end of lines.
29   '''
30   if lines.strip() != '':
31     writeToFile(outfile, lines + '\n', append = True)
32
33
34 def removeFiles(filenames):
35   '''utility function: 'rm -f'
36     ignore errors when file does not exist, or is a directory.
37   '''
38   for file in filenames:
39     try:
40       os.remove(file)
41     except:
42       pass
43
44
45 def cmdOutput(cmd):
46   '''utility function: run a command and get its output as a string
47     cmd: command to run
48   '''
49   fout = os.popen(cmd)
50   output = fout.read()
51   fout.close()
52   return output.strip()
53
54
55 def setEnviron():
56   ''' I do not really know why this is useful, but we might as well keep it.
57     NLS nuisances.
58     Only set these to C if already set.  These must not be set unconditionally
59     because not all systems understand e.g. LANG=C (notably SCO).
60     Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
61     Non-C LC_CTYPE values break the ctype check.
62   '''
63   os.environ['LANG'] = os.getenv('LANG', 'C')
64   os.environ['LC'] = os.getenv('LC_ALL', 'C')
65   os.environ['LC_MESSAGE'] = os.getenv('LC_MESSAGE', 'C')
66   os.environ['LC_CTYPE'] = os.getenv('LC_CTYPE', 'C')
67
68
69 def createDirectories():
70   ''' Create the build directories if necessary '''
71   for dir in ['bind', 'clipart', 'doc', 'examples', 'images', 'kbd', \
72     'layouts', 'scripts', 'templates', 'ui' ]:
73     if not os.path.isdir( dir ):
74       try:
75         os.mkdir( dir)
76       except:
77         print "Failed to create directory ", dir
78         sys.exit(1)
79
80
81 def checkCygwinPath(srcdir):
82   ''' Adjust PATH for Win32 (Cygwin) '''
83   cygwin_path_fix = ''
84   if sys.platform == 'cygwin':
85     from tempfile import mkstemp
86     fd, tmpfname = mkstemp(suffix='.ltx', dir='/tmp')
87     os.write(fd, r'''
88 \documentstyle{article}
89 \begin{document}\end{document}
90   ''')
91     os.close(fd)
92     inpname = cmdOutput('cygpath -m ' + tmpfname)
93     # a wrapper file
94     wfd, wtmpfname = mkstemp(suffix='.ltx', dir='/tmp')
95     wtmpfname = cmdOutput('cygpath -m ' + wtmpfname)
96     os.write(wfd, r'\input{' + inpname + '}' )
97     os.close(wfd)
98     if cmdOutput('latex ' + wtmpfname).find('Error') != -1:
99       print "configure: cygwin detected; path correction is not needed"
100       cygwin_path_fix = 'false'
101     else:
102       print "configure: cygwin detected; path correction"
103       srcdir = cmdOutput('cygpath -m ' + srcdir)
104       print "srcdir = ", srcdir
105       cygwin_path_fix = 'true'
106     tmpbname,ext = os.path.splitext(os.path.basename(tmpfname))
107     wtmpbname,ext = os.path.splitext(os.path.basename(wtmpfname))
108     removeFiles( [ tmpfname, wtmpfname, tmpbname + '.log', \
109             tmpbname + '.aux', wtmpbname + '.log', wtmpbname + '.aux' ] )
110   return cygwin_path_fix
111
112
113 ## Searching some useful programs
114 def checkProg(description, progs, rc_entry = [], path = [] ):
115   '''
116     This function will search a program in $PATH plus given path
117     If found, return directory and program name (not the options).
118
119     description: description of the program
120
121     progs: check programs, for each prog, the first word is used
122       for searching but the whole string is used to replace
123       %% for a rc_entry. So, feel free to add '$$i' etc for programs.
124
125     path: additional pathes
126
127     rc_entry: entry to outfile, can be
128       1. emtpy: no rc entry will be added
129       2. one pattern: %% will be replaced by the first found program,
130          or 'none' is no program is found.
131       3. several patterns for each prog and 'none'. This is used 
132          when different programs have different usages. If you do not 
133          want 'none' entry to be added to the RC file, you can specify 
134          an entry for each prog and use '' for the 'none' entry.
135
136   '''
137   # one rc entry for each progs plus none entry
138   if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
139     print "rc entry should have one item or item for each prog and none."
140     sys.exit(2)
141   print 'checking for ' + description + '...'
142   ## print '(' + ','.join(progs) + ')',
143   for idx in range(len(progs)):
144     # ac_prog may have options, ac_word is the command name
145     ac_prog = progs[idx]
146     ac_word = ac_prog.split(' ')[0]
147     print '+checking for "' + ac_word + '"... ',
148     path = os.environ["PATH"].split(os.pathsep) + path
149     for ac_dir in path:
150       # check both ac_word and ac_word.exe (for windows system)
151       if os.path.isfile( os.path.join(ac_dir, ac_word) ) or \
152          os.path.isfile( os.path.join(ac_dir, ac_word + ".exe") ):
153         print ' yes'
154         # write rc entries for this command
155         if len(rc_entry) == 1:
156           addToRC(rc_entry[0].replace('%%', ac_prog))
157         elif len(rc_entry) > 1:
158           addToRC(rc_entry[idx].replace('%%', ac_prog))
159         return [ac_dir, ac_word]
160     # if not successful
161     print ' no'
162   # write rc entries for 'not found'
163   if len(rc_entry) > 0:  # the last one.
164     addToRC(rc_entry[-1].replace('%%', 'none'))
165   return ['', 'none']
166
167
168 def checkLatex():
169   ''' Check latex, return lyx_check_config '''
170   # Find programs! Returned path is not used now
171   path, LATEX = checkProg( 'a Latex2e program', ['pplatex $$i', 'latex $$i', 'latex2e $$i'],
172     rc_entry = [ r'\converter latex      dvi        "%%"        "latex"' ] )
173   # no latex
174   if LATEX != 'none':
175     # Check if latex is usable
176     writeToFile('chklatex.ltx', '''
177 \\nonstopmode\\makeatletter
178 \\ifx\\undefined\\documentclass\\else
179   \\message{ThisIsLaTeX2e}
180 \\fi
181 \\@@end
182 ''')
183     # run latex on chklatex.ltx and check result
184     if cmdOutput(LATEX + ' chklatex.ltx').find('ThisIsLaTeX2e') != -1:
185       # valid latex2e
186       return LATEX
187     else:
188       print "Latex not usable (not LaTeX2e) "
189     # remove temporary files
190     removeFiles(['chklatex.ltx', 'chklatex.log'])
191   return ''
192
193
194 def checkFormatEntries():  
195   ''' Check all formats (\Format entries) '''
196   checkProg('a Tgif viewer and editor', ['tgif'],
197     rc_entry = [ r'\Format tgif       obj     Tgif                   "" "%%"    "%%"    ""'])
198   #
199   checkProg('a FIG viewer and editor', ['xfig'],
200     rc_entry = [ r'\Format fig        fig     FIG                    "" "%%"    "%%"    ""'] )
201   #
202   checkProg('a Grace viewer and editor', ['xmgrace'],
203     rc_entry = [ r'\Format agr        agr     Grace                  "" "%%"    "%%"    ""'] )
204   #
205   checkProg('a FEN viewer and editor', ['xboard -lpf $$i -mode EditPosition'],
206     rc_entry = [ r'\Format fen        fen     FEN                    "" "%%"    "%%"    ""' ])
207   #
208   path, iv = checkProg('a raster image viewer', ['xv', 'kview', 'gimp'])
209   path, ie = checkProg('a raster image editor', ['gimp'])
210   addToRC(r'''\Format bmp        bmp     BMP                    "" "%s" "%s"    ""
211 \Format gif        gif     GIF                    "" "%s"       "%s"    ""
212 \Format jpg        jpg     JPEG                   "" "%s"       "%s"    ""
213 \Format pbm        pbm     PBM                    "" "%s"       "%s"    ""
214 \Format pgm        pgm     PGM                    "" "%s"       "%s"    ""
215 \Format png        png     PNG                    "" "%s"       "%s"    ""
216 \Format ppm        ppm     PPM                    "" "%s"       "%s"    ""
217 \Format tiff       tif     TIFF                   "" "%s"       "%s"    ""
218 \Format xbm        xbm     XBM                    "" "%s"       "%s"    ""
219 \Format xpm        xpm     XPM                    "" "%s"       "%s"    ""''' % \
220     (iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie) )
221   #
222   checkProg('a text editor', ['xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
223     'nedit', 'gedit', 'notepad'],
224     rc_entry = [ r'''\Format asciichess asc    "Plain text (chess output)"  "" ""       "%%"    ""
225 \Format asciiimage asc    "Plain text (image)"         "" ""    "%%"    ""
226 \Format asciixfig  asc    "Plain text (Xfig output)"   "" ""    "%%"    ""
227 \Format dateout    tmp    "date (output)"         "" "" "%%"    ""
228 \Format docbook    sgml    DocBook                B  "" "%%"    "document"
229 \Format docbook-xml xml   "Docbook (XML)"         "" "" "%%"    "document"
230 \Format literate   nw      NoWeb                  N  "" "%%"    "document"
231 \Format latex      tex    "LaTeX (plain)"         L  "" "%%"    "document"
232 \Format linuxdoc   sgml    LinuxDoc               x  "" "%%"    "document"
233 \Format pdflatex   tex    "LaTeX (pdflatex)"      "" "" "%%"    "document"
234 \Format text       txt    "Plain text"            a  "" "%%"    "document"
235 \Format textparagraph txt "Plain text (paragraphs)"    "" ""    "%%"    "document"''' ])
236   #
237   #checkProg('a Postscript interpreter', ['gs'],
238   #  rc_entry = [ r'\ps_command "%%"' ])
239   checkProg('a Postscript previewer', ['gv', 'ghostview -swap', 'kghostview'],
240     rc_entry = [ r'''\Format eps        eps     EPS                    "" "%%"  ""      ""
241 \Format ps         ps      Postscript             t  "%%"       ""      "document"''' ])
242   #
243   checkProg('a PDF previewer', ['acrobat', 'acroread', 'gv', 'ghostview', \
244               'xpdf', 'kpdf', 'kghostview'],
245     rc_entry = [ r'''\Format pdf        pdf    "PDF (ps2pdf)"          P  "%%"  ""      "document"
246 \Format pdf2       pdf    "PDF (pdflatex)"        F  "%%"       ""      "document"
247 \Format pdf3       pdf    "PDF (dvipdfm)"         m  "%%"       ""      "document"''' ])
248   #
249   checkProg('a DVI previewer', ['xdvi', 'kdvi'],
250     rc_entry = [ r'\Format dvi        dvi     DVI                    D  "%%"    ""      "document"' ])
251   #
252   checkProg('a HTML previewer', ['mozilla file://$$p$$i', 'netscape'],
253     rc_entry = [ r'\Format html       html    HTML                   H  "%%"    ""      "document"' ])
254   #
255   # entried that do not need checkProg
256   addToRC(r'''\Format date       ""     "date command"          "" ""   ""      ""
257 \Format fax        ""      Fax                    "" "" ""      "document"
258 \Format lyx        lyx     LyX                    "" "" ""      ""
259 \Format lyx13x     lyx13  "LyX 1.3.x"             "" "" ""      "document"
260 \Format lyxpreview lyxpreview "LyX Preview"       "" "" ""      ""
261 \Format pdftex     pdftex_t PDFTEX                "" "" ""      ""
262 \Format program    ""      Program                "" "" ""      ""
263 \Format pstex      pstex_t PSTEX                  "" "" ""      ""
264 \Format sxw        sxw    "OpenOffice.Org Writer" O  "" ""      "document"
265 \Format word       doc    "MS Word"               W  "" ""      "document"
266 \Format wordhtml   html   "MS Word (HTML)"        "" ""        ""       "document"
267 ''')
268
269
270 def checkConverterEntries():
271   ''' Check all converters (\converter entries) '''
272   checkProg('the pdflatex program', ['pdflatex $$i'],
273     rc_entry = [ r'\converter pdflatex   pdf2       "%%"        "latex"' ])
274   
275   ''' If we're running LyX in-place then tex2lyx will be found in
276       ../src/tex2lyx. Add this directory to the PATH temporarily and
277       search for tex2lyx.
278       Use PATH to avoid any problems with paths-with-spaces.
279   '''
280   path_orig = os.environ["PATH"]
281   os.environ["PATH"] = os.path.join('..', 'src', 'tex2lyx') + \
282     os.pathsep + path_orig
283
284   checkProg('a LaTeX -> LyX converter', ['tex2lyx -f $$i $$o', \
285     'tex2lyx' +  version_suffix + ' -f $$i $$o' ],
286     rc_entry = [ r'\converter latex      lyx        "%%"        ""' ])
287
288   os.environ["PATH"] = path_orig
289
290   #
291   checkProg('a Noweb -> LyX converter', ['noweb2lyx' + version_suffix + ' $$i $$o'], path = ['./reLyX'],
292     rc_entry = [ r'\converter literate   lyx        "%%"        ""' ])
293   #
294   checkProg('a Noweb -> LaTeX converter', ['noweave -delay -index $$i > $$o'],
295     rc_entry = [ r'\converter literate   latex      "%%"        ""' ])
296   #
297   checkProg('a HTML -> LaTeX converter', ['html2latex $$i'],
298     rc_entry = [ r'\converter html       latex      "%%"        ""' ])
299   #
300   checkProg('a MSWord -> LaTeX converter', ['wvCleanLatex $$i $$o'],
301     rc_entry = [ r'\converter word       latex      "%%"        ""' ])
302   #
303   checkProg('a LaTeX -> MS Word converter', ["htlatex $$i 'html,word' 'symbol/!' '-cvalidate'"],
304     rc_entry = [ r'\converter latex      wordhtml   "%%"        ""' ])
305   #
306   checkProg('an OpenOffice.org -> LaTeX converter', ['w2l -clean $$i'],
307     rc_entry = [ r'\converter sxw        latex      "%%"        ""' ])
308   #
309   checkProg('an LaTeX -> OpenOffice.org LaTeX converter', ['oolatex $$i', 'oolatex.sh $$i'],
310     rc_entry = [ r'\converter latex      sxw        "%%"        "latex"' ])
311   #
312   checkProg('a PS to PDF converter', ['ps2pdf13 $$i'],
313     rc_entry = [ r'\converter ps         pdf        "%%"        ""' ])
314   #
315   checkProg('a DVI to PS converter', ['dvips -o $$o $$i'],
316     rc_entry = [ r'\converter dvi        ps         "%%"        ""' ])
317   #
318   checkProg('a DVI to PDF converter', ['dvipdfm $$i'],
319     rc_entry = [ r'\converter dvi        pdf3       "%%"        ""' ])
320   #
321   path, dvipng = checkProg('dvipng', ['dvipng'])
322   if dvipng == "dvipng":
323     addToRC(r'\converter lyxpreview png        "python $$s/scripts/lyxpreview2bitmap.py"        ""')
324   else:
325     addToRC(r'\converter lyxpreview png        ""       ""')
326   #  
327   checkProg('a fax program', ['kdeprintfax $$i', 'ksendfax $$i'],
328     rc_entry = [ r'\converter ps         fax        "%%"        ""'])
329   #
330   checkProg('a FIG -> EPS/PPM converter', ['fig2dev'],
331     rc_entry = [
332       r'''\converter fig        eps        "fig2dev -L eps $$i $$o"     ""
333 \converter fig        ppm        "fig2dev -L ppm $$i $$o"       ""
334 \converter fig        png        "fig2dev -L png $$i $$o"       ""''',
335       ''])
336   #
337   checkProg('a TIFF -> PS converter', ['tiff2ps $$i > $$o'],
338     rc_entry = [ r'\converter tiff       eps        "%%"        ""', ''])
339   #
340   checkProg('a TGIF -> EPS/PPM converter', ['tgif'],
341     rc_entry = [
342       r'''\converter tgif       eps        "tgif -stdout -print -color -eps $$i > $$o"  ""
343 \converter tgif       pdf        "tgif -stdout -print -color -pdf $$i > $$o"    ""''',
344       ''])
345   #
346   checkProg('a EPS -> PDF converter', ['epstopdf'],
347     rc_entry = [ r'\converter eps        pdf        "epstopdf --outfile=$$o $$i"        ""', ''])
348   #
349   checkProg('a Grace -> Image converter', ['gracebat'],
350     rc_entry = [
351       r'''\converter agr        eps        "gracebat -hardcopy -printfile $$o -hdevice EPS $$i 2>/dev/null"     ""
352 \converter agr        png        "gracebat -hardcopy -printfile $$o -hdevice PNG $$i 2>/dev/null"       ""
353 \converter agr        jpg        "gracebat -hardcopy -printfile $$o -hdevice JPEG $$i 2>/dev/null"      ""
354 \converter agr        ppm        "gracebat -hardcopy -printfile $$o -hdevice PNM $$i 2>/dev/null"       ""''',
355       ''])
356   #
357   checkProg('a LaTeX -> HTML converter', ['htlatex $$i', 'tth  -t -e2 -L$$b < $$i > $$o', \
358     'latex2html -no_subdir -split 0 -show_section_numbers $$i', 'hevea -s $$i'],
359     rc_entry = [ r'\converter latex      html       "%%"        "originaldir,needaux"' ])
360   #
361   # FIXME: no rc_entry? comment it out
362   # checkProg('Image converter', ['convert $$i $$o'])
363   #
364   # Entried that do not need checkProg
365   addToRC(r'''\converter lyxpreview ppm        "python $$s/scripts/lyxpreview2bitmap.py"        ""
366 \converter date       dateout    "date +%d-%m-%Y > $$o" ""
367 \converter docbook    docbook-xml "cp $$i $$o"  "xml"
368 \converter fen        asciichess "python $$s/scripts/fen2ascii.py $$i $$o"      ""
369 \converter fig        pdftex     "sh $$s/scripts/fig2pdftex.sh $$i $$o" ""
370 \converter fig        pstex      "sh $$s/scripts/fig2pstex.sh $$i $$o"  ""
371 \converter lyx        lyx13x     "python $$s/lyx2lyx/lyx2lyx -t 221 $$i > $$o"  ""
372 ''')
373
374
375 def checkLinuxDoc():
376   ''' Check linuxdoc '''
377   #
378   path, LINUXDOC = checkProg('SGML-tools 1.x (LinuxDoc)', ['sgml2lyx'],
379     rc_entry = [
380     r'''\converter linuxdoc   lyx        "sgml2lyx $$i" ""
381 \converter linuxdoc   latex      "sgml2latex $$i"       ""
382 \converter linuxdoc   dvi        "sgml2latex -o dvi $$i"        ""
383 \converter linuxdoc   html       "sgml2html $$i"        ""''',
384     r'''\converter linuxdoc   lyx        "none" ""
385 \converter linuxdoc   latex      "none" ""
386 \converter linuxdoc   dvi        "none" ""
387 \converter linuxdoc   html       "none" ""''' ])
388   if LINUXDOC != 'none':
389     return ('yes', 'true', '\\def\\haslinuxdoc{yes}')
390   else:
391     return ('no', 'false', '')
392
393
394 def checkDocBook():
395   ''' Check docbook '''
396   path, DOCBOOK = checkProg('SGML-tools 2.x (DocBook) or db2x scripts', ['sgmltools', 'db2dvi'],
397     rc_entry = [
398       r'''\converter docbook    dvi        "sgmltools -b dvi $$i"       ""
399 \converter docbook    html       "sgmltools -b html $$i"        ""''',
400       r'''\converter docbook    dvi        "db2dvi $$i" ""
401 \converter docbook    html       "db2html $$i"  ""''',
402       r'''\converter docbook    dvi        "none"       ""
403 \converter docbook    html       "none" ""'''])
404   #
405   if DOCBOOK != 'none':
406     return ('yes', 'true', '\\def\\hasdocbook{yes}')
407   else:
408     return ('no', 'false', '')
409
410
411 def checkOtherEntries():
412   ''' entries other than Format and Converter '''
413   checkProg('a *roff formatter', ['groff', 'nroff'],
414     rc_entry = [
415       r'\ascii_roff_command "groff -t -Tlatin1 $$FName"',
416       r'\ascii_roff_command "tbl $$FName | nroff"',
417       r'\ascii_roff_command "none"' ])
418   checkProg('ChkTeX', ['chktex -n1 -n3 -n6 -n9 -n22 -n25 -n30 -n38'],
419     rc_entry = [ r'\chktex_command "%%"' ])
420   checkProg('a spellchecker', ['ispell'],
421     rc_entry = [ r'\spell_command "%%"' ])
422   ## FIXME: OCTAVE is not used anywhere
423   # path, OCTAVE = checkProg('Octave', ['octave'])
424   ## FIXME: MAPLE is not used anywhere
425   # path, MAPLE = checkProg('Maple', ['maple'])
426   checkProg('a spool command', ['lp', 'lpr'],
427     rc_entry = [
428       r'''\print_spool_printerprefix "-d "
429 \print_spool_command "lp"''',
430       r'''\print_spool_printerprefix "-P",
431 \print_spool_command "lpr"''',
432       ''])
433   # Add the rest of the entries (no checkProg is required)
434   addToRC(r'''\copier    fig        "sh $$s/scripts/fig_copy.sh $$i $$o"
435 \copier    pstex      "python $$s/scripts/tex_copy.py $$i $$o $$l"
436 \copier    pdftex     "python $$s/scripts/tex_copy.py $$i $$o $$l"
437 ''')
438
439
440 def processLayoutFile(file, bool_docbook, bool_linuxdoc):
441   ''' process layout file and get a line of result
442     
443     Declear line are like this: (article.layout, scrbook.layout, svjog.layout)
444     
445     \DeclareLaTeXClass{article}
446     \DeclareLaTeXClass[scrbook]{book (koma-script)}
447     \DeclareLaTeXClass[svjour,svjog.clo]{article (Springer - svjour/jog)}
448
449     we expect output:
450     
451     "article" "article" "article" "false"
452     "scrbook" "scrbook" "book (koma-script)" "false"
453     "svjog" "svjour" "article (Springer - svjour/jog)" "false"
454   '''
455   classname = file.split(os.sep)[-1].split('.')[0]
456   # return ('LaTeX', '[a,b]', 'a', ',b,c', 'article') for \DeclearLaTeXClass[a,b,c]{article}
457   p = re.compile(r'\Declare(LaTeX|DocBook|LinuxDoc)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}')
458   for line in open(file).readlines():
459     res = p.search(line)
460     if res != None:
461       (classtype, optAll, opt, opt1, desc) = res.groups()
462       avai = {'LaTeX':'false', 'DocBook':bool_docbook, 'LinuxDoc':bool_linuxdoc}[classtype]
463       if opt == None:
464         opt = classname
465       return '"%s" "%s" "%s" "%s"\n' % (classname, opt, desc, avai)
466   print "Layout file without \DeclearXXClass line. "
467   sys.exit(2)
468
469   
470 def checkLatexConfig(check_config, bool_docbook, bool_linuxdoc):
471   ''' Explore the LaTeX configuration '''
472   print 'checking LaTeX configuration... ',
473   # First, remove the files that we want to re-create
474   removeFiles(['textclass.lst', 'packages.lst', 'chkconfig.sed'])
475   #
476   if not check_config:
477     print ' default values'
478     print '+checking list of textclasses... '
479     tx = open('textclass.lst', 'w')
480     tx.write('''
481 # This file declares layouts and their associated definition files
482 # (include dir. relative to the place where this file is).
483 # It contains only default values, since chkconfig.ltx could not be run
484 # for some reason. Run ./configure if you need to update it after a
485 # configuration change.
486 ''')
487     # build the list of available layout files and convert it to commands
488     # for chkconfig.ltx
489     foundClasses = []
490     for file in glob.glob( os.path.join('layouts', '*.layout') ) + \
491       glob.glob( os.path.join(srcdir, 'layouts', '*.layout' ) ) :
492       # valid file?
493       if not os.path.isfile(file): 
494         continue
495       # get stuff between /xxxx.layout .
496       classname = file.split(os.sep)[-1].split('.')[0]
497       #  tr ' -' '__'`
498       cleanclass = classname.replace(' ', '_')
499       cleanclass = cleanclass.replace('-', '_')
500       # make sure the same class is not considered twice
501       if foundClasses.count(cleanclass) == 0: # not found before
502         foundClasses.append(cleanclass)
503         tx.write(processLayoutFile(file, bool_docbook, bool_linuxdoc))
504     tx.close()
505     print '\tdone'
506   else:
507     print '\tauto'
508     removeFiles(['wrap_chkconfig.ltx', 'chkconfig.vars', \
509       'chkconfig.classes', 'chklayouts.tex'])
510     rmcopy = False
511     if not os.path.isfile( 'chkconfig.ltx' ):
512       shutil.copy( os.path.join(srcdir, 'chkconfig.ltx'),  'chkconfig.ltx' )
513       rmcopy = True
514     writeToFile('wrap_chkconfig.ltx', '%s\n%s\n\\input{chkconfig.ltx}\n' \
515       % (linuxdoc_cmd, docbook_cmd) )
516     # Construct the list of classes to test for.
517     # build the list of available layout files and convert it to commands
518     # for chkconfig.ltx
519     p1 = re.compile(r'\Declare(LaTeX|DocBook|LinuxDoc)Class')
520     testclasses = list()
521     for file in glob.glob( os.path.join('layouts', '*.layout') ) + \
522       glob.glob( os.path.join(srcdir, 'layouts', '*.layout' ) ) :
523       if not os.path.isfile(file):
524         continue
525       classname = file.split(os.sep)[-1].split('.')[0]
526       for line in open(file).readlines():
527         if p1.search(line) == None:
528           continue
529         if line[0] != '#':
530           print "Wrong input layout file with line '" + line
531           sys.exit(3)
532         testclasses.append("\\TestDocClass{%s}{%s}" % (classname, line[1:].strip()))
533         break
534     testclasses.sort()
535     cl = open('chklayouts.tex', 'w')
536     for line in testclasses:
537       cl.write(line + '\n')
538     cl.close()
539     #
540     # we have chklayouts.tex, then process it
541     for line in cmdOutput(LATEX + ' wrap_chkconfig.ltx').splitlines():
542       if re.match('^\+', line):
543         print line
544     #
545     # currently, values in chhkconfig are only used to set
546     # \font_encoding
547     values = {}
548     for line in open('chkconfig.vars').readlines():
549       key, val = re.sub('-', '_', line).split('=')
550       val = val.strip()
551       values[key] = val.strip("'")
552     # chk_fontenc may not exist 
553     try:
554       addToRC(r'\font_encoding "%s"' % values["chk_fontenc"])
555     except:
556       pass
557     if rmcopy:   # remove the copied file
558       removeFiles( [ 'chkconfig.ltx' ] )
559
560
561 def createLaTeXConfig():
562   ''' create LaTeXConfig.lyx '''
563   # if chkconfig.sed does not exist (because LaTeX did not run),
564   # then provide a standard version.
565   if not os.path.isfile('chkconfig.sed'):
566     writeToFile('chkconfig.sed', 's!@.*@!???!g\n')
567   print "creating packages.lst"
568   # if packages.lst does not exist (because LaTeX did not run),
569   # then provide a standard version.
570   if not os.path.isfile('packages.lst'):
571     writeToFile('packages.lst', '''
572 ### This file should contain the list of LaTeX packages that have been
573 ### recognized by LyX. Unfortunately, since configure could not find
574 ### your LaTeX2e program, the tests have not been run. Run ./configure
575 ### if you need to update it after a configuration change.
576 ''')
577   print 'creating doc/LaTeXConfig.lyx'
578   #
579   # This is originally done by sed, using a
580   # tex-generated file chkconfig.sed
581   ##sed -f chkconfig.sed ${srcdir}/doc/LaTeXConfig.lyx.in
582   ##  >doc/LaTeXConfig.lyx
583   # Now, we have to do it by hand (python).
584   #
585   # add to chekconfig.sed
586   writeToFile('chkconfig.sed', '''s!@chk_linuxdoc@!%s!g
587 s!@chk_docbook@!%s!g
588   ''' % (chk_linuxdoc, chk_docbook) , append=True)
589   # process this sed file!!!!
590   lyxin = open( os.path.join(srcdir, 'doc', 'LaTeXConfig.lyx.in')).readlines()
591   # get the rules
592   p = re.compile(r's!(.*)!(.*)!g')
593   # process each sed replace.
594   for sed in open('chkconfig.sed').readlines():
595     if sed.strip() == '':
596       continue
597     try:
598       fr, to = p.match(sed).groups()
599       # if latex did not run, change all @name@ to '???'
600       if fr == '@.*@':
601         for line in range(len(lyxin)):
602           lyxin[line] = re.sub('@.*@', to, lyxin[line])
603       else:
604         for line in range(len(lyxin)):
605           lyxin[line] = lyxin[line].replace(fr, to)
606     except:  # wrong sed entry?
607       print "Wrong sed entry in chkconfig.sed: '" + sed + "'"
608       sys.exit(4)
609   # 
610   writeToFile( os.path.join('doc', 'LaTeXConfig.lyx'),
611     ''.join(lyxin))
612
613
614 def checkTeXAllowSpaces():
615   ''' Let's check whether spaces are allowed in TeX file names '''
616   tex_allows_spaces = 'false'
617   if lyx_check_config:
618     print "Checking whether TeX allows spaces in file names... ",
619     writeToFile('a b.tex', r'\message{working^^J}' )
620     # FIXME: the bsh version uses < /dev/null which is not portable.
621     # Can anyone confirm if this option (-interaction) is available
622     # at other flavor of latex as well? (MikTex/win, Web2C/linux are fine.) 
623     if ''.join(cmdOutput(LATEX + ' -interaction=nonstopmode "a b"')).find('working') != -1:
624       print 'yes'
625       tex_allows_spaces = 'true'
626     else:
627       print 'no'
628       tex_allows_spaces = 'false'
629     addToRC(r'\tex_allows_spaces ' + tex_allows_spaces)
630     removeFiles( [ 'a b.tex', 'a b.log', 'texput.log' ])
631
632
633 def removeTempFiles():
634   # Final clean-up
635   if not lyx_keep_temps:
636     removeFiles(['chkconfig.sed', 'chkconfig.vars',  \
637       'wrap_chkconfig.ltx', 'wrap_chkconfig.log', \
638       'chklayouts.tex', 'missfont.log', 
639       'chklatex.ltx', 'chklatex.log'])
640
641
642 if __name__ == '__main__':
643   lyx_check_config = True
644   outfile = 'lyxrc.defaults'
645   rc_entries = ''
646   lyx_keep_temps = False
647   version_suffix = ''
648   ## Parse the command line
649   for op in sys.argv[1:]:   # default shell/for list is $*, the options
650     if op in [ '-help', '--help', '-h' ]:
651       print '''Usage: configure [options]
652 Options:
653   --help                   show this help lines
654   --keep-temps             keep temporary files (for debug. purposes)
655   --without-latex-config   do not run LaTeX to determine configuration
656   --with-version-suffix=suffix suffix of binary installed files
657 '''
658       sys.exit(0)
659     elif op == '--without-latex-config':
660       lyx_check_config = False
661     elif op == '--keep-temps':
662       lyx_keep_temps = True
663     elif op[0:22] == '--with-version-suffix=':  # never mind if op is not long enough
664       version_suffix = op[22:]
665     else:
666       print "Unknown option", op
667       sys.exit(1)
668   #    
669   # check if we run from the right directory
670   srcdir = os.path.dirname(sys.argv[0])
671   if srcdir == '':
672     srcdir = '.'
673   if not os.path.isfile( os.path.join(srcdir, 'chkconfig.ltx') ):
674     print "configure: error: cannot find chkconfig.ltx script"
675     sys.exit(1)
676   setEnviron()
677   createDirectories()
678   cygwin_path_fix = checkCygwinPath(srcdir)
679   ## Write the first part of outfile
680   writeToFile(outfile, '''# This file has been automatically generated by LyX' lib/configure.py
681 # script. It contains default settings that have been determined by
682 # examining your system. PLEASE DO NOT MODIFY ANYTHING HERE! If you
683 # want to customize LyX, make a copy of the file LYXDIR/lyxrc as
684 # ~/.lyx/lyxrc and edit this file instead. Any setting in lyxrc will
685 # override the values given here.
686 ''')
687   # check latex
688   LATEX = checkLatex()
689   checkFormatEntries()
690   checkConverterEntries()
691   (chk_linuxdoc, bool_linuxdoc, linuxdoc_cmd) = checkLinuxDoc()
692   (chk_docbook, bool_docbook, docbook_cmd) = checkDocBook()
693   checkTeXAllowSpaces()
694   checkOtherEntries()
695   if cygwin_path_fix != '':
696     addToRC(r'\cygwin_path_fix_needed %s' % cygwin_path_fix)
697   # --without-latex-config can disable lyx_check_config
698   checkLatexConfig( lyx_check_config and LATEX != '', bool_docbook, bool_linuxdoc)
699   createLaTeXConfig()
700   removeTempFiles()