X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=lib%2Fconfigure.py;h=152844fac9a6e5468a98e3d3a59d52b1a3965695;hb=8d0d3ea0905172b4a1fba7fbfadba83ff61671c6;hp=bd5eb44a5521eb5a7397ad56bbc418daf27b8b5a;hpb=f5e6db717167ecbe9e5934c937467bf0fca90ba1;p=lyx.git diff --git a/lib/configure.py b/lib/configure.py index bd5eb44a55..152844fac9 100644 --- a/lib/configure.py +++ b/lib/configure.py @@ -11,6 +11,11 @@ from __future__ import print_function import glob, logging, os, errno, re, shutil, subprocess, sys, stat +if sys.version_info[0] < 3: + import codecs + open = codecs.open + + # set up logging logging.basicConfig(level = logging.DEBUG, format = '%(levelname)s: %(message)s', # ignore application name @@ -46,7 +51,7 @@ def addToRC(lines): ''' utility function: shortcut for appending lines to outfile add newline at the end of lines. ''' - if lines.strip() != '': + if lines.strip(): writeToFile(outfile, lines + '\n', append = True) logger.debug('Add to RC:\n' + lines + '\n\n') @@ -212,7 +217,7 @@ def checkTeXPaths(): if sys.version_info[0] < 3: inpname = shortPath(unicode(tmpfname, encoding)).replace('\\', '/') else: - inpname = shortPath(tmpfname).replace('\\', '/') + inpname = shortPath(tmpfname).replace('\\', '/') else: inpname = cmdOutput('cygpath -m ' + tmpfname) logname = os.path.basename(re.sub("(?i).ltx", ".log", inpname)) @@ -525,22 +530,46 @@ def checkInkscape(): try: aKey = winreg.OpenKey(aReg, r"inkscape.svg\DefaultIcon") val = winreg.QueryValueEx(aKey, "") - return str(val[0]).split('"')[1] + valentry = str(val[0]) + if valentry.find('"') > 0: + return valentry.split('"')[1] + elif valentry.find(',') > 0: + return valentry.split(',')[0] + else: + return 'inkscape' except EnvironmentError: try: - aKey = winreg.OpenKey(aReg, r"Applications\inkscape.exe\shell\open\command") + aKey = winreg.OpenKey(aReg, r"inkscape.SVG\shell\open\command") val = winreg.QueryValueEx(aKey, "") return str(val[0]).split('"')[1] except EnvironmentError: - return 'inkscape' + try: + aKey = winreg.OpenKey(aReg, r"Applications\inkscape.exe\shell\open\command") + val = winreg.QueryValueEx(aKey, "") + return str(val[0]).split('"')[1] + except EnvironmentError: + return 'inkscape' + + +def checkInkscapeStable(): + ''' Check whether we use Inkscape >= 1.0 ''' + inkscape_bin = inkscape_cl + if os.name == 'nt': + # Windows needs the full path, quoted if it contains spaces + inkscape_bin = quoteIfSpace(os.path.join(inkscape_path, inkscape_cl)) + version_string = cmdOutput(inkscape_bin + " --version") + if version_string.find(' 0.') > 0: + return False + else: + return True + def checkLatex(dtl_tools): ''' Check latex, return lyx_check_config ''' path, LATEX = checkProg('a Latex2e program', ['latex $$i', 'latex2e $$i']) - path, PPLATEX = checkProg('a DVI postprocessing program', ['pplatex $$i']) #----------------------------------------------------------------- path, PLATEX = checkProg('pLaTeX, the Japanese LaTeX', ['platex $$i']) - if PLATEX != '': + if PLATEX: # check if PLATEX is pLaTeX2e writeToFile('chklatex.ltx', r'\nonstopmode\makeatletter\@@end') # run platex on chklatex.ltx and check result @@ -551,17 +580,14 @@ def checkLatex(dtl_tools): PLATEX = '' removeFiles(['chklatex.ltx', 'chklatex.log']) #----------------------------------------------------------------- - # use LATEX to convert from latex to dvi if PPLATEX is not available - if PPLATEX == '': - PPLATEX = LATEX if dtl_tools: # Windows only: DraftDVI addToRC(r'''\converter latex dvi2 "%s" "latex,hyperref-driver=dvips" -\converter dvi2 dvi "python -tt $$s/scripts/clean_dvi.py $$i $$o" ""''' % PPLATEX) +\converter dvi2 dvi "python -tt $$s/scripts/clean_dvi.py $$i $$o" ""''' % LATEX) else: - addToRC(r'\converter latex dvi "%s" "latex,hyperref-driver=dvips"' % PPLATEX) + addToRC(r'\converter latex dvi "%s" "latex,hyperref-driver=dvips"' % LATEX) # no latex - if LATEX != '': + if LATEX: # Check if latex is usable writeToFile('chklatex.ltx', r''' \nonstopmode @@ -586,9 +612,9 @@ def checkLuatex(): ''' Check if luatex is there ''' path, LUATEX = checkProg('LuaTeX', ['lualatex $$i']) path, DVILUATEX = checkProg('LuaTeX (DVI)', ['dvilualatex $$i']) - if LUATEX != '': + if LUATEX: addToRC(r'\converter luatex pdf5 "%s" "latex=lualatex"' % LUATEX) - if DVILUATEX != '': + if DVILUATEX: addToRC(r'\converter dviluatex dvi3 "%s" "latex=dvilualatex"' % DVILUATEX) @@ -654,8 +680,7 @@ def checkFormatEntries(dtl_tools): # checkViewerEditor('a text editor', texteditors, rc_entry = [r'''\Format asciichess asc "Plain text (chess output)" "" "" "%%" "" "" -\Format docbook sgml DocBook B "" "%%" "document,menu=export" "" -\Format docbook-xml xml "DocBook (XML)" "" "" "%%" "document,menu=export" "application/docbook+xml" +\Format docbook5 xml "DocBook 5" "" "" "%%" "document,menu=export" "application/docbook+xml" \Format dot dot "Graphviz Dot" "" "" "%%" "vector" "text/vnd.graphviz" \Format dviluatex tex "LaTeX (dviluatex)" "" "" "%%" "document,menu=export" "" \Format platex tex "LaTeX (pLaTeX)" "" "" "%%" "document,menu=export" "" @@ -671,7 +696,7 @@ def checkFormatEntries(dtl_tools): \Format luatex tex "LaTeX (LuaTeX)" "" "" "%%" "document,menu=export" "" \Format pdflatex tex "LaTeX (pdflatex)" "" "" "%%" "document,menu=export" "" \Format xetex tex "LaTeX (XeTeX)" "" "" "%%" "document,menu=export" "" -\Format latexclipboard tex "LaTeX (clipboard)" "" "" "%%" "" "" +\Format latexclipboard tex "LaTeX (clipboard)" "" "" "%%" "menu=none" "" \Format text txt "Plain text" a "" "%%" "document,menu=export" "text/plain" \Format text2 txt "Plain text (pstotext)" "" "" "%%" "document" "" \Format text3 txt "Plain text (ps2ascii)" "" "" "%%" "document" "" @@ -687,7 +712,8 @@ def checkFormatEntries(dtl_tools): rc_entry = [r'''\Format gnumeric gnumeric "Gnumeric spreadsheet" "" "" "%%" "document" "application/x-gnumeric" \Format excel xls "Excel spreadsheet" "" "" "%%" "document" "application/vnd.ms-excel" \Format excel2 xlsx "MS Excel Office Open XML" "" "" "%%" "document" "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" -\Format html_table html "HTML Table (for spreadsheets)" "" "" "%%" "document" "text/html" +\Format xhtml_table xhtml "XHTML Table (for spreadsheets)" "" "" "%%" "document" "" +\Format html_table html "HTML Table (for spreadsheets)" "" "" "%%" "document" "" \Format oocalc ods "OpenDocument spreadsheet" "" "" "%%" "document" "application/vnd.oasis.opendocument.spreadsheet"''']) # checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'], @@ -724,7 +750,8 @@ def checkFormatEntries(dtl_tools): \Format pdf5 pdf "PDF (LuaTeX)" u "%%" "" "document,vector,menu=export" "" \Format pdf6 pdf "PDF (graphics)" "" "%%" "" "vector" "application/pdf" \Format pdf7 pdf "PDF (cropped)" "" "%%" "" "document,vector" "" -\Format pdf8 pdf "PDF (lower resolution)" "" "%%" "" "document,vector" ""''']) +\Format pdf8 pdf "PDF (lower resolution)" "" "%%" "" "document,vector" "" +\Format pdf9 pdf "PDF (DocBook)" "" "%%" "" "document,vector,menu=export" ""''']) # checkViewer('a DVI previewer', ['xdvi', 'kdvi', 'okular', 'evince', 'xreader', @@ -905,6 +932,9 @@ def checkConverterEntries(): checkProg('an Open Document (Pandoc) -> LaTeX converter', ['pandoc -s -f odt -o $$o -t latex $$i'], rc_entry = [ r'\converter odt3 latex "%%" ""' ]) # + checkProg('DocBook converter -> PDF (docbook)', ['pandoc -f docbook -t latex --latex-engine=lualatex --toc -o $$o $$i'], + rc_entry = [ r'\converter docbook5 pdf9 "%%" ""' ]) + # checkProg('a MS Word Office Open XML converter -> LaTeX', ['pandoc -s -f docx -o $$o -t latex $$i'], rc_entry = [ r'\converter word2 latex "%%" ""' ]) # Only define a converter to pdf6, otherwise the odt format could be @@ -918,7 +948,7 @@ def checkConverterEntries(): # On SuSE the scripts have a .sh suffix, and on debian they are in /usr/share/tex4ht/ # Both SuSE and debian have oolatex checkProg('a LaTeX -> Open Document (tex4ht) converter', [ - 'oolatex $$i', 'mk4ht oolatex $$i', 'oolatex.sh $$i', '/usr/share/tex4ht/oolatex $$i', + 'oolatex $$i', 'make4ht -f odt $$i', 'oolatex.sh $$i', '/usr/share/tex4ht/oolatex $$i', 'htlatex $$i \'xhtml,ooffice\' \'ooffice/! -cmozhtf\' \'-coo\' \'-cvalidate\''], rc_entry = [ r'\converter latex odt "%%" "needaux"' ]) # On windows it is called latex2rt.exe @@ -1005,13 +1035,22 @@ def checkConverterEntries(): \converter fig pdftex "python -tt $$s/scripts/fig2pdftex.py $$i $$o" "" \converter fig pstex "python -tt $$s/scripts/fig2pstex.py $$i $$o" ""''') # - checkProg('a SVG -> PDFTeX converter', [inkscape_cl], - rc_entry = [ r'\converter svg pdftex "python -tt $$s/scripts/svg2pdftex.py %% $$p$$i $$p$$o" ""'], - path = [inkscape_path]) - # - checkProg('a SVG -> PSTeX converter', [inkscape_cl], - rc_entry = [ r'\converter svg pstex "python -tt $$s/scripts/svg2pstex.py %% $$p$$i $$p$$o" ""'], - path = [inkscape_path]) + if inkscape_stable: + checkProg('a SVG -> PDFTeX converter', [inkscape_cl], + rc_entry = [ r'\converter svg pdftex "python -tt $$s/scripts/svg2pdftex.py %% $$p$$i $$p$$o" ""'], + path = [inkscape_path]) + # + checkProg('a SVG -> PSTeX converter', [inkscape_cl], + rc_entry = [ r'\converter svg pstex "python -tt $$s/scripts/svg2pstex.py %% $$p$$i $$p$$o" ""'], + path = [inkscape_path]) + else: + checkProg('a SVG -> PDFTeX converter', [inkscape_cl], + rc_entry = [ r'\converter svg pdftex "python -tt $$s/scripts/svg2pdftex.py --unstable %% $$p$$i $$p$$o" ""'], + path = [inkscape_path]) + # + checkProg('a SVG -> PSTeX converter', [inkscape_cl], + rc_entry = [ r'\converter svg pstex "python -tt $$s/scripts/svg2pstex.py --unstable %% $$p$$i $$p$$o" ""'], + path = [inkscape_path]) # checkProg('a TIFF -> PS converter', ['tiff2ps $$i > $$o'], rc_entry = [ r'\converter tiff eps "%%" ""']) @@ -1022,19 +1061,31 @@ def checkConverterEntries(): \converter tgif png "tgif -print -color -png -o $$d $$i" "" \converter tgif pdf6 "tgif -print -color -pdf -stdout $$i > $$o" ""''']) # - checkProg('a WMF -> EPS converter', ['metafile2eps $$i $$o', 'wmf2eps -o $$o $$i', inkscape_cl + ' --file=%s$$i --export-area-drawing --without-gui --export-eps=%s$$o' - % (inkscape_fileprefix, inkscape_fileprefix)], - rc_entry = [ r'\converter wmf eps "%%" ""']) - # - checkProg('an EMF -> EPS converter', ['metafile2eps $$i $$o', inkscape_cl + ' --file=%s$$i --export-area-drawing --without-gui --export-eps=%s$$o' - % (inkscape_fileprefix, inkscape_fileprefix)], - rc_entry = [ r'\converter emf eps "%%" ""']) - # - checkProg('a WMF -> PDF converter', [inkscape_cl + ' --file=%s$$i --export-area-drawing --without-gui --export-pdf=%s$$o' % (inkscape_fileprefix, inkscape_fileprefix)], - rc_entry = [ r'\converter wmf pdf6 "%%" ""']) - # - checkProg('an EMF -> PDF converter', [inkscape_cl + ' --file=%s$$i --export-area-drawing --without-gui --export-pdf=%s$$o' % (inkscape_fileprefix, inkscape_fileprefix)], - rc_entry = [ r'\converter emf pdf6 "%%" ""']) + # inkscape 1.0 has changed cl options + if inkscape_stable: + checkProg('a WMF -> EPS converter', ['metafile2eps $$i $$o', 'wmf2eps -o $$o $$i', inkscape_cl + ' $$i --export-area-drawing --export-filename=$$o'], + rc_entry = [ r'\converter wmf eps "%%" ""']) + # + checkProg('an EMF -> EPS converter', ['metafile2eps $$i $$o', inkscape_cl + ' $$i --export-area-drawing --export-filename=$$o'], + rc_entry = [ r'\converter emf eps "%%" ""']) + # + checkProg('a WMF -> PDF converter', [inkscape_cl + ' $$i --export-area-drawing --export-filename=$$o'], + rc_entry = [ r'\converter wmf pdf6 "%%" ""']) + # + checkProg('an EMF -> PDF converter', [inkscape_cl + ' $$i --export-area-drawing --export-filename=$$o'], + rc_entry = [ r'\converter emf pdf6 "%%" ""']) + else: + checkProg('a WMF -> EPS converter', ['metafile2eps $$i $$o', 'wmf2eps -o $$o $$i', inkscape_cl + ' --file=$$i --export-area-drawing --without-gui --export-eps=$$o'], + rc_entry = [ r'\converter wmf eps "%%" ""']) + # + checkProg('an EMF -> EPS converter', ['metafile2eps $$i $$o', inkscape_cl + ' --file=$$i --export-area-drawing --without-gui --export-eps=$$o'], + rc_entry = [ r'\converter emf eps "%%" ""']) + # + checkProg('a WMF -> PDF converter', [inkscape_cl + ' --file=$$i --export-area-drawing --without-gui --export-pdf=$$o'], + rc_entry = [ r'\converter wmf pdf6 "%%" ""']) + # + checkProg('an EMF -> PDF converter', [inkscape_cl + ' --file=$$i --export-area-drawing --without-gui --export-pdf=$$o'], + rc_entry = [ r'\converter emf pdf6 "%%" ""']) # Only define a converter to pdf6 for graphics checkProg('an EPS -> PDF converter', ['epstopdf'], rc_entry = [ r'\converter eps pdf6 "epstopdf --outfile=$$o $$i" ""']) @@ -1079,25 +1130,39 @@ def checkConverterEntries(): rc_entry = [ r'\converter svg svgz "%%" ""']) # Only define a converter to pdf6 for graphics # Prefer rsvg-convert over inkscape since it is faster (see http://www.lyx.org/trac/ticket/9891) - checkProg('a SVG -> PDF converter', ['rsvg-convert -f pdf -o $$o $$i', inkscape_cl + ' --file=%s$$i --export-area-drawing --without-gui --export-pdf=%s$$o' - % (inkscape_fileprefix, inkscape_fileprefix)], - rc_entry = [ r'''\converter svg pdf6 "%%" "" + # inkscape 1.0 has changed cl options + if inkscape_stable: + checkProg('a SVG -> PDF converter', ['rsvg-convert -f pdf -o $$o $$i', inkscape_cl + ' $$i --export-area-drawing --export-filename=$$o'], + rc_entry = [ r'''\converter svg pdf6 "%%" "" \converter svgz pdf6 "%%" ""'''], - path = ['', inkscape_path]) - # - checkProg('a SVG -> EPS converter', ['rsvg-convert -f ps -o $$o $$i', inkscape_cl + ' --file=%s$$i --export-area-drawing --without-gui --export-eps=%s$$o' - % (inkscape_fileprefix, inkscape_fileprefix)], - rc_entry = [ r'''\converter svg eps "%%" "" + path = ['', inkscape_path]) + # + checkProg('a SVG -> EPS converter', ['rsvg-convert -f ps -o $$o $$i', inkscape_cl + ' $$i --export-area-drawing --export-filename=$$o'], + rc_entry = [ r'''\converter svg eps "%%" "" \converter svgz eps "%%" ""'''], - path = ['', inkscape_path]) - # - checkProg('a SVG -> PNG converter', ['rsvg-convert -f png -o $$o $$i', inkscape_cl + ' --without-gui --file=%s$$i --export-png=%s$$o' - % (inkscape_fileprefix, inkscape_fileprefix)], - rc_entry = [ r'''\converter svg png "%%" "", + path = ['', inkscape_path]) + # + checkProg('a SVG -> PNG converter', ['rsvg-convert -f png -o $$o $$i', inkscape_cl + ' $$i --export-filename=$$o'], + rc_entry = [ r'''\converter svg png "%%" "", \converter svgz png "%%" ""'''], - path = ['', inkscape_path]) + path = ['', inkscape_path]) + else: + checkProg('a SVG -> PDF converter', ['rsvg-convert -f pdf -o $$o $$i', inkscape_cl + ' --file=$$i --export-area-drawing --without-gui --export-pdf=$$o'], + rc_entry = [ r'''\converter svg pdf6 "%%" "" +\converter svgz pdf6 "%%" ""'''], + path = ['', inkscape_path]) + # + checkProg('a SVG -> EPS converter', ['rsvg-convert -f ps -o $$o $$i', inkscape_cl + ' --file=$$i --export-area-drawing --without-gui --export-eps=$$o'], + rc_entry = [ r'''\converter svg eps "%%" "" +\converter svgz eps "%%" ""'''], + path = ['', inkscape_path]) + # + checkProg('a SVG -> PNG converter', ['rsvg-convert -f png -o $$o $$i', inkscape_cl + ' --without-gui --file=$$i --export-png=$$o'], + rc_entry = [ r'''\converter svg png "%%" "", +\converter svgz png "%%" ""'''], + path = ['', inkscape_path]) # - checkProg('Gnuplot', ['gnuplot'], + checkProg('Gnuplot', ['gnuplot'], rc_entry = [ r'''\Format gnuplot "gp, gnuplot" "Gnuplot" "" "" "" "vector" "text/plain" \converter gnuplot pdf6 "python -tt $$s/scripts/gnuplot2pdf.py $$i $$o" "needauth"''' ]) # @@ -1111,10 +1176,14 @@ def checkConverterEntries(): \converter oocalc html_table "ssconvert --export-type=Gnumeric_html:html40frag $$i $$o" "" \converter excel html_table "ssconvert --export-type=Gnumeric_html:html40frag $$i $$o" "" \converter excel2 html_table "ssconvert --export-type=Gnumeric_html:html40frag $$i $$o" "" +\converter gnumeric xhtml_table "python $$s/scripts/spreadsheet_to_docbook.py $$i $$o" "" +\converter oocalc xhtml_table "python $$s/scripts/spreadsheet_to_docbook.py $$i $$o" "" +\converter excel xhtml_table "python $$s/scripts/spreadsheet_to_docbook.py $$i $$o" "" +\converter excel2 xhtml_table "python $$s/scripts/spreadsheet_to_docbook.py $$i $$o" "" ''']) path, lilypond = checkProg('a LilyPond -> EPS/PDF/PNG converter', ['lilypond']) - if (lilypond != ''): + if (lilypond): version_string = cmdOutput("lilypond --version") match = re.match('GNU LilyPond (\S+)', version_string) if match: @@ -1137,7 +1206,7 @@ def checkConverterEntries(): logger.info('+ found LilyPond, but could not extract version number.') # path, lilypond_book = checkProg('a LilyPond book (LaTeX) -> LaTeX converter', ['lilypond-book']) - if (lilypond_book != ''): + if (lilypond_book): version_string = cmdOutput("lilypond-book --version") match = re.match('(\S+)$', version_string) if match: @@ -1184,7 +1253,6 @@ def checkConverterEntries(): # Entries that do not need checkProg addToRC(r''' \converter csv lyx "python -tt $$s/scripts/csv2lyx.py $$i $$o" "" -\converter docbook docbook-xml "cp $$i $$o" "xml" \converter fen asciichess "python -tt $$s/scripts/fen2ascii.py $$i $$o" "" \converter lyx lyx13x "python -tt $$s/lyx2lyx/lyx2lyx -V 1.3 -o $$o $$i" "" \converter lyx lyx14x "python -tt $$s/lyx2lyx/lyx2lyx -V 1.4 -o $$o $$i" "" @@ -1202,29 +1270,10 @@ def checkConverterEntries(): \converter klyx lyx "python -tt $$s/lyx2lyx/lyx2lyx -c euc_kr -o $$o $$i" "" \converter lyxpreview png "python -tt $$s/scripts/lyxpreview2bitmap.py --png" "" \converter lyxpreview ppm "python -tt $$s/scripts/lyxpreview2bitmap.py --ppm" "" +\converter docbook docbook5 "cp $$i $$o" "xml" ''') -def checkDocBook(): - ''' Check docbook ''' - path, DOCBOOK = checkProg('SGML-tools 2.x (DocBook), db2x scripts or xsltproc', ['sgmltools', 'db2dvi', 'xsltproc'], - rc_entry = [ - r'''\converter docbook dvi "sgmltools -b dvi $$i" "" -\converter docbook html "sgmltools -b html $$i" "" -\converter docbook ps "sgmltools -b ps $$i" ""''', - r'''\converter docbook dvi "db2dvi $$i" "" -\converter docbook html "db2html $$i" ""''', - r'''\converter docbook dvi "" "" -\converter docbook html "" ""''', - r'''\converter docbook dvi "" "" -\converter docbook html "" ""''']) - # - if DOCBOOK != '': - return ('yes', 'true', '\\def\\hasdocbook{yes}') - else: - return ('no', 'false', '') - - def checkOtherEntries(): ''' entries other than Format and Converter ''' checkProg('ChkTeX', ['chktex -n1 -n3 -n6 -n9 -n22 -n25 -n30 -n38'], @@ -1238,7 +1287,7 @@ def checkOtherEntries(): rc_entry = [ r'\jbibtex_command "automatic"' ], alt_rc_entry = [ r'\jbibtex_alternatives "%%"' ]) checkProgAlternatives('available index processors', - ['texindy', 'makeindex -c -q', 'xindy'], + ['texindy $$x -t $$b.ilg', 'xindex -l $$lcode', 'makeindex -c -q', 'xindy -M texindy $$x -t $$b.ilg'], rc_entry = [ r'\index_command "%%"' ], alt_rc_entry = [ r'\index_alternatives "%%"' ]) checkProg('an index processor appropriate to Japanese', @@ -1255,15 +1304,23 @@ def checkOtherEntries(): ## FIXME: MAPLE is not used anywhere # path, MAPLE = checkProg('Maple', ['maple']) # Add the rest of the entries (no checkProg is required) + addToRC(r'''\citation_search_view "python -tt $$s/scripts/lyxpaperview.py"''') addToRC(r'''\copier fig "python -tt $$s/scripts/fig_copy.py $$i $$o" \copier pstex "python -tt $$s/scripts/tex_copy.py $$i $$o $$l" \copier pdftex "python -tt $$s/scripts/tex_copy.py $$i $$o $$l" \copier program "python -tt $$s/scripts/ext_copy.py $$i $$o" ''') +def _checkForClassExtension(x): + '''if the extension for a latex class is not + provided, add .cls to the classname''' + if not '.' in x: + return x.strip() + '.cls' + else: + return x.strip() -def processLayoutFile(file, bool_docbook): - ''' process layout file and get a line of result +def processLayoutFile(file): + """ process layout file and get a line of result Declare lines look like this: @@ -1288,50 +1345,40 @@ def processLayoutFile(file, bool_docbook): "article" "article" "article" "false" "article.cls" "Articles" "scrbook" "scrbook" "book (koma-script)" "false" "scrbook.cls" "Books" "svjog" "svjour" "article (Springer - svjour/jog)" "false" "svjour.cls,svjog.clo" "" - ''' - def checkForClassExtension(x): - '''if the extension for a latex class is not - provided, add .cls to the classname''' - if not b'.' in x: - return x.strip() + b'.cls' - else: - return x.strip() + """ classname = file.split(os.sep)[-1].split('.')[0] - # return ('LaTeX', '[a,b]', 'a', ',b,c', 'article') for \DeclareLaTeXClass[a,b,c]{article} - p = re.compile(b'\s*#\s*\\\\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}\s*$') - q = re.compile(b'\s*#\s*\\\\DeclareCategory{(.*)}\s*$') - classdeclaration = b"" - categorydeclaration = b'""' - for line in open(file, 'rb').readlines(): + # return ('[a,b]', 'a', ',b,c', 'article') for \DeclareLaTeXClass[a,b,c]{article} + p = re.compile('\s*#\s*\\\\DeclareLaTeXClass\s*(\[([^,]*)(,.*)*])*\s*{(.*)}\s*$') + q = re.compile('\s*#\s*\\\\DeclareCategory{(.*)}\s*$') + classdeclaration = "" + categorydeclaration = '""' + for line in open(file, 'r', encoding='utf8').readlines(): res = p.match(line) qres = q.match(line) - if res != None: - (classtype, optAll, opt, opt1, desc) = res.groups() - avai = {b'LaTeX':b'false', b'DocBook':bool_docbook.encode('ascii')}[classtype] - if opt == None: - opt = classname.encode('ascii') - prereq_latex = checkForClassExtension(classname.encode('ascii')) + if res is not None: + (optAll, opt, opt1, desc) = res.groups() + if opt is None: + opt = classname + prereq = _checkForClassExtension(classname) else: - prereq_list = optAll[1:-1].split(b',') - prereq_list = list(map(checkForClassExtension, prereq_list)) - prereq_latex = b','.join(prereq_list) - prereq_docbook = {'true':b'', 'false':b'docbook'}[bool_docbook] - prereq = {b'LaTeX':prereq_latex, b'DocBook':prereq_docbook}[classtype] - classdeclaration = (b'"%s" "%s" "%s" "%s" "%s"' - % (classname, opt, desc, avai, prereq)) - if categorydeclaration != b'""': - return classdeclaration + b" " + categorydeclaration - if qres != None: - categorydeclaration = b'"%s"' % (qres.groups()[0]) - if classdeclaration != b"": - return classdeclaration + b" " + categorydeclaration - if classdeclaration != b"": - return classdeclaration + b" " + categorydeclaration - logger.warning("Layout file " + file + " has no \DeclareXXClass line. ") - return b"" - - -def checkLatexConfig(check_config, bool_docbook): + prereq_list = optAll[1:-1].split(',') + prereq_list = list(map(_checkForClassExtension, prereq_list)) + prereq = ','.join(prereq_list) + classdeclaration = ('"%s" "%s" "%s" "%s" "%s"' + % (classname, opt, desc, 'false', prereq)) + if categorydeclaration != '""': + return classdeclaration + " " + categorydeclaration + if qres is not None: + categorydeclaration = '"%s"' % (qres.groups()[0]) + if classdeclaration: + return classdeclaration + " " + categorydeclaration + if classdeclaration: + return classdeclaration + " " + categorydeclaration + logger.warning("Layout file " + file + " has no \\DeclareLaTeXClass line. ") + return "" + + +def checkLatexConfig(check_config): ''' Explore the LaTeX configuration Return None (will be passed to sys.exit()) for success. ''' @@ -1346,8 +1393,8 @@ def checkLatexConfig(check_config, bool_docbook): # fails, we still have something to start lyx. logger.info(msg + ' default values') logger.info('+checking list of textclasses... ') - tx = open('textclass.lst', 'wb') - tx.write(b''' + tx = open('textclass.lst', 'w', encoding='utf8') + tx.write(''' # This file declares layouts and their associated definition files # (include dir. relative to the place where this file is). # It contains only default values, since chkconfig.ltx could not be run @@ -1365,20 +1412,19 @@ def checkLatexConfig(check_config, bool_docbook): # get stuff between /xxxx.layout . classname = file.split(os.sep)[-1].split('.')[0] # tr ' -' '__'` - cleanclass = classname.replace(' ', '_') - cleanclass = cleanclass.replace('-', '_') + cleanclass = classname.replace(' ', '_').replace('-', '_') # make sure the same class is not considered twice if foundClasses.count(cleanclass) == 0: # not found before foundClasses.append(cleanclass) - retval = processLayoutFile(file, bool_docbook) - if retval != b"": + retval = processLayoutFile(file) + if retval: tx.write(retval + os.linesep) tx.close() logger.info('\tdone') if not os.path.isfile('packages.lst') or not check_config: logger.info('+generating default list of packages... ') removeFiles(['packages.lst']) - tx = open('packages.lst', 'w') + tx = open('packages.lst', 'w', encoding='utf8') tx.close() logger.info('\tdone') if not check_config: @@ -1391,13 +1437,13 @@ def checkLatexConfig(check_config, bool_docbook): if not os.path.isfile( 'chkconfig.ltx' ): shutil.copyfile( os.path.join(srcdir, 'chkconfig.ltx'), 'chkconfig.ltx' ) rmcopy = True - writeToFile('wrap_chkconfig.ltx', '%s\n\\input{chkconfig.ltx}\n' % docbook_cmd) + writeToFile('wrap_chkconfig.ltx', '\\def\\hasdocbook{yes}\n\\input{chkconfig.ltx}\n') # Construct the list of classes to test for. # build the list of available layout files and convert it to commands # for chkconfig.ltx - declare = re.compile(b'\\s*#\\s*\\\\Declare(LaTeX|DocBook)Class\\s*(\[([^,]*)(,.*)*\])*\\s*{(.*)}\\s*$') - category = re.compile(b'\\s*#\\s*\\\\DeclareCategory{(.*)}\\s*$') - empty = re.compile(b'\\s*$') + declare = re.compile('\\s*#\\s*\\\\DeclareLaTeXClass\\s*(\[([^,]*)(,.*)*\])*\\s*{(.*)}\\s*$') + category = re.compile('\\s*#\\s*\\\\DeclareCategory{(.*)}\\s*$') + empty = re.compile('\\s*$') testclasses = list() for file in (glob.glob( os.path.join('layouts', '*.layout') ) + glob.glob( os.path.join(srcdir, 'layouts', '*.layout' ) ) ): @@ -1405,34 +1451,41 @@ def checkLatexConfig(check_config, bool_docbook): if not os.path.isfile(file): continue classname = file.split(os.sep)[-1].split('.')[0] - decline = b"" - catline = b"" - for line in open(file, 'rb').readlines(): - if not empty.match(line) and line[0] != b'#'[0]: - if decline == b"": - logger.warning("Failed to find valid \Declare line " - "for layout file `%s'.\n\t=> Skipping this file!" % file) - nodeclaration = True - # A class, but no category declaration. Just break. + decline = "" + catline = "" + try: + for line in open(file, 'r', encoding='utf8').readlines(): + if not empty.match(line) and line[0] != '#'[0]: + if decline == "": + logger.warning("Failed to find valid \Declare line " + "for layout file `%s'.\n\t=> Skipping this file!" % file) + nodeclaration = True + # A class, but no category declaration. Just break. + break + if declare.match(line) is not None: + decline = "\\TestDocClass{%s}{%s}" % (classname, line[1:].strip()) + testclasses.append(decline) + elif category.match(line) is not None: + catline = ("\\DeclareCategory{%s}{%s}" + % (classname, category.match(line).groups()[0])) + testclasses.append(catline) + if catline == "" or decline == "": + continue break - if declare.match(line) != None: - decline = b"\\TestDocClass{%s}{%s}" \ - % (classname.encode('ascii'), line[1:].strip()) - testclasses.append(decline) - elif category.match(line) != None: - catline = (b"\\DeclareCategory{%s}{%s}" - % (classname.encode('ascii'), - category.match(line).groups()[0])) - testclasses.append(catline) - if catline == b"" or decline == b"": + if nodeclaration: continue - break - if nodeclaration: + except UnicodeDecodeError: + logger.warning("**************************************************\n" + "Layout file '%s'\n" + "cannot be decoded in utf-8.\n" + "Please check if the file has the correct encoding.\n" + "Skipping this file!\n" + "**************************************************" % file) continue testclasses.sort() - cl = open('chklayouts.tex', 'wb') + cl = open('chklayouts.tex', 'w', encoding='utf8') for line in testclasses: - cl.write(line + b'\n') + cl.write(line + '\n') cl.close() # # we have chklayouts.tex, then process it @@ -1460,9 +1513,9 @@ def checkLatexConfig(check_config, bool_docbook): # if configure successed, move textclass.lst.tmp to textclass.lst # and packages.lst.tmp to packages.lst if (os.path.isfile('textclass.lst.tmp') - and len(open('textclass.lst.tmp').read()) > 0 + and len(open('textclass.lst.tmp', encoding='utf8').read()) > 0 and os.path.isfile('packages.lst.tmp') - and len(open('packages.lst.tmp').read()) > 0): + and len(open('packages.lst.tmp', encoding='utf8').read()) > 0): shutil.move('textclass.lst.tmp', 'textclass.lst') shutil.move('packages.lst.tmp', 'packages.lst') return ret @@ -1472,12 +1525,12 @@ def checkModulesConfig(): removeFiles(['lyxmodules.lst', 'chkmodules.tex']) logger.info('+checking list of modules... ') - tx = open('lyxmodules.lst', 'wb') - tx.write(b'''## This file declares modules and their associated definition files. + tx = open('lyxmodules.lst', 'w', encoding='utf8') + tx.write('''## This file declares modules and their associated definition files. ## It has been automatically generated by configure ## Use "Options/Reconfigure" if you need to update it after a ## configuration change. -## "ModuleName" "filename" "Description" "Packages" "Requires" "Excludes" "Category" +## "ModuleName" "filename" "Description" "Packages" "Requires" "Excludes" "Category" "Local" ''') # build the list of available modules @@ -1497,14 +1550,22 @@ def checkModulesConfig(): continue seen.append(filename) - retval = processModuleFile(file, filename.encode('ascii'), bool_docbook) - if retval != b"": - tx.write(retval) + try: + retval = processModuleFile(file, filename) + if retval: + tx.write(retval) + except UnicodeDecodeError: + logger.warning("**************************************************\n" + "Module file '%s'\n" + "cannot be decoded in utf-8.\n" + "Please check if the file has the correct encoding.\n" + "Skipping this file!\n" + "**************************************************" % filename) tx.close() logger.info('\tdone') -def processModuleFile(file, filename, bool_docbook): +def processModuleFile(file, filename): ''' process module file and get a line of result The top of a module file should look like this: @@ -1519,25 +1580,25 @@ def processModuleFile(file, filename, bool_docbook): We expect output: "ModuleName" "filename" "Description" "Packages" "Requires" "Excludes" "Category" ''' - remods = re.compile(b'\s*#\s*\\\\DeclareLyXModule\s*(?:\[([^]]*?)\])?{(.*)}') - rereqs = re.compile(b'\s*#+\s*Requires: (.*)') - reexcs = re.compile(b'\s*#+\s*Excludes: (.*)') - recaty = re.compile(b'\s*#+\s*Category: (.*)') - redbeg = re.compile(b'\s*#+\s*DescriptionBegin\s*$') - redend = re.compile(b'\s*#+\s*DescriptionEnd\s*$') - - modname = desc = pkgs = req = excl = catgy = b"" + remods = re.compile('\s*#\s*\\\\DeclareLyXModule\s*(?:\[([^]]*?)\])?{(.*)}') + rereqs = re.compile('\s*#+\s*Requires: (.*)') + reexcs = re.compile('\s*#+\s*Excludes: (.*)') + recaty = re.compile('\\s*#\\s*\\\\DeclareCategory{(.*)}\\s*$') + redbeg = re.compile('\s*#+\s*DescriptionBegin\s*$') + redend = re.compile('\s*#+\s*DescriptionEnd\s*$') + + modname = desc = pkgs = req = excl = catgy = "" readingDescription = False descLines = [] - for line in open(file, 'rb').readlines(): + for line in open(file, 'r', encoding='utf8').readlines(): if readingDescription: res = redend.match(line) if res != None: readingDescription = False - desc = b" ".join(descLines) + desc = " ".join(descLines) # Escape quotes. - desc = desc.replace(b'"', b'\\"') + desc = desc.replace('"', '\\"') continue descLines.append(line[1:].strip()) continue @@ -1549,59 +1610,62 @@ def processModuleFile(file, filename, bool_docbook): if res != None: (pkgs, modname) = res.groups() if pkgs == None: - pkgs = b"" + pkgs = "" else: - tmp = [s.strip() for s in pkgs.split(b",")] - pkgs = b",".join(tmp) + tmp = [s.strip() for s in pkgs.split(",")] + pkgs = ",".join(tmp) continue res = rereqs.match(line) if res != None: req = res.group(1) - tmp = [s.strip() for s in req.split(b"|")] - req = b"|".join(tmp) + tmp = [s.strip() for s in req.split("|")] + req = "|".join(tmp) continue res = reexcs.match(line) if res != None: excl = res.group(1) - tmp = [s.strip() for s in excl.split(b"|")] - excl = b"|".join(tmp) + tmp = [s.strip() for s in excl.split("|")] + excl = "|".join(tmp) continue res = recaty.match(line) if res != None: catgy = res.group(1) continue - if modname == b"": + if modname == "": logger.warning("Module file without \DeclareLyXModule line. ") - return b"" + return "" - if pkgs != b"": + if pkgs: # this module has some latex dependencies: # append the dependencies to chkmodules.tex, # which is \input'ed by chkconfig.ltx testpackages = list() - for pkg in pkgs.split(b","): - if b"->" in pkg: + for pkg in pkgs.split(","): + if "->" in pkg: # this is a converter dependency: skip continue - if pkg.endswith(b".sty"): + if pkg.endswith(".sty"): pkg = pkg[:-4] - testpackages.append("\\TestPackage{%s}" % (pkg.decode('ascii'),)) - cm = open('chkmodules.tex', 'a') + testpackages.append("\\TestPackage{%s}" % pkg) + cm = open('chkmodules.tex', 'a', encoding='utf8') for line in testpackages: cm.write(line + '\n') cm.close() - return (b'"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' - % (modname, filename, desc, pkgs, req, excl, catgy)) + local = "true" + if (file.startswith(srcdir)): + local = "false" + return ('"%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' + % (modname, filename, desc, pkgs, req, excl, catgy, local)) def checkCiteEnginesConfig(): removeFiles(['lyxciteengines.lst', 'chkciteengines.tex']) logger.info('+checking list of cite engines... ') - tx = open('lyxciteengines.lst', 'wb') - tx.write(b'''## This file declares cite engines and their associated definition files. + tx = open('lyxciteengines.lst', 'w', encoding='utf8') + tx.write('''## This file declares cite engines and their associated definition files. ## It has been automatically generated by configure ## Use "Options/Reconfigure" if you need to update it after a ## configuration change. @@ -1625,14 +1689,14 @@ def checkCiteEnginesConfig(): continue seen.append(filename) - retval = processCiteEngineFile(file, filename.encode('ascii'), bool_docbook) - if retval != b"": + retval = processCiteEngineFile(file, filename) + if retval: tx.write(retval) tx.close() logger.info('\tdone') -def processCiteEngineFile(file, filename, bool_docbook): +def processCiteEngineFile(file, filename): ''' process cite engines file and get a line of result The top of a cite engine file should look like this: @@ -1643,25 +1707,25 @@ def processCiteEngineFile(file, filename, bool_docbook): We expect output: "CiteEngineName" "filename" "CiteEngineType" "CiteFramework" "DefaultBiblio" "Description" "Packages" ''' - remods = re.compile(b'\s*#\s*\\\\DeclareLyXCiteEngine\s*(?:\[([^]]*?)\])?{(.*)}') - redbeg = re.compile(b'\s*#+\s*DescriptionBegin\s*$') - redend = re.compile(b'\s*#+\s*DescriptionEnd\s*$') - recet = re.compile(b'\s*CiteEngineType\s*(.*)') - redb = re.compile(b'\s*DefaultBiblio\s*(.*)') - resfm = re.compile(b'\s*CiteFramework\s*(.*)') + remods = re.compile('\s*#\s*\\\\DeclareLyXCiteEngine\s*(?:\[([^]]*?)\])?{(.*)}') + redbeg = re.compile('\s*#+\s*DescriptionBegin\s*$') + redend = re.compile('\s*#+\s*DescriptionEnd\s*$') + recet = re.compile('\s*CiteEngineType\s*(.*)') + redb = re.compile('\s*DefaultBiblio\s*(.*)') + resfm = re.compile('\s*CiteFramework\s*(.*)') modname = desc = pkgs = cet = db = cfm = "" readingDescription = False descLines = [] - for line in open(file, 'rb').readlines(): + for line in open(file, 'r', encoding='utf8').readlines(): if readingDescription: res = redend.match(line) if res != None: readingDescription = False - desc = b" ".join(descLines) + desc = " ".join(descLines) # Escape quotes. - desc = desc.replace(b'"', b'\\"') + desc = desc.replace('"', '\\"') continue descLines.append(line[1:].strip()) continue @@ -1673,10 +1737,10 @@ def processCiteEngineFile(file, filename, bool_docbook): if res != None: (pkgs, modname) = res.groups() if pkgs == None: - pkgs = b"" + pkgs = "" else: - tmp = [s.strip() for s in pkgs.split(b",")] - pkgs = b",".join(tmp) + tmp = [s.strip() for s in pkgs.split(",")] + pkgs = ",".join(tmp) continue res = recet.match(line) if res != None: @@ -1691,35 +1755,36 @@ def processCiteEngineFile(file, filename, bool_docbook): cfm = res.group(1) continue - if modname == b"": + if modname == "": logger.warning("Cite Engine File file without \DeclareLyXCiteEngine line. ") - return b"" + return "" - if pkgs != b"": + if pkgs: # this cite engine has some latex dependencies: # append the dependencies to chkciteengines.tex, # which is \input'ed by chkconfig.ltx testpackages = list() - for pkg in pkgs.split(b","): - if b"->" in pkg: + for pkg in pkgs.split(","): + if "->" in pkg: # this is a converter dependency: skip continue - if pkg.endswith(b".sty"): + if pkg.endswith(".sty"): pkg = pkg[:-4] - testpackages.append("\\TestPackage{%s}" % (pkg.decode('ascii'),)) - cm = open('chkciteengines.tex', 'a') + testpackages.append("\\TestPackage{%s}" % pkg) + cm = open('chkciteengines.tex', 'a', encoding='utf8') for line in testpackages: cm.write(line + '\n') cm.close() - return (b'"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, cet, cfm, db, desc, pkgs)) + return ('"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' + % (modname, filename, cet, cfm, db, desc, pkgs)) def checkXTemplates(): removeFiles(['xtemplates.lst']) logger.info('+checking list of external templates... ') - tx = open('xtemplates.lst', 'w') + tx = open('xtemplates.lst', 'w', encoding='utf8') tx.write('''## This file lists external templates. ## It has been automatically generated by configure ## Use "Options/Reconfigure" if you need to update it after a @@ -1742,7 +1807,7 @@ def checkXTemplates(): continue seen.append(filename) - if filename != "": + if filename: tx.write(filename + "\n") tx.close() logger.info('\tdone') @@ -1754,7 +1819,7 @@ def checkTeXAllowSpaces(): if lyx_check_config: msg = "Checking whether TeX allows spaces in file names... " writeToFile('a b.tex', r'\message{working^^J}' ) - if LATEX != '': + if LATEX: if os.name == 'nt' or sys.platform == 'cygwin': latex_out = cmdOutput(LATEX + r""" "\nonstopmode\input{\"a b\"}\makeatletter\@@end" """) else: @@ -1798,11 +1863,12 @@ if __name__ == '__main__': lyx_check_config = True lyx_kpsewhich = True outfile = 'lyxrc.defaults' - lyxrc_fileformat = 29 + lyxrc_fileformat = 34 rc_entries = '' lyx_keep_temps = False version_suffix = '' lyx_binary_dir = '' + logger.info("+Running LyX configure with Python %s.%s.%s", sys.version_info[0], sys.version_info[1], sys.version_info[2]) ## Parse the command line for op in sys.argv[1:]: # default shell/for list is $*, the options if op in [ '-help', '--help', '-h' ]: @@ -1864,17 +1930,12 @@ Format %i inkscape_cl = inkscape_gui if os.name == 'nt': inkscape_cl = inkscape_gui.replace('.exe', '.com') - # On MacOSX, Inkscape requires full path file arguments. This - # is not needed on Linux and Win and even breaks the latter. - inkscape_fileprefix = "" - if sys.platform == 'darwin': - inkscape_fileprefix = "$$p" + inkscape_stable = checkInkscapeStable() checkFormatEntries(dtl_tools) checkConverterEntries() - (chk_docbook, bool_docbook, docbook_cmd) = checkDocBook() checkTeXAllowSpaces() windows_style_tex_paths = checkTeXPaths() - if windows_style_tex_paths != '': + if windows_style_tex_paths: addToRC(r'\tex_expects_windows_paths %s' % windows_style_tex_paths) checkOtherEntries() if lyx_kpsewhich: @@ -1883,7 +1944,7 @@ Format %i checkCiteEnginesConfig() checkXTemplates() # --without-latex-config can disable lyx_check_config - ret = checkLatexConfig(lyx_check_config and LATEX != '', bool_docbook) + ret = checkLatexConfig(lyx_check_config and LATEX) removeTempFiles() # The return error code can be 256. Because most systems expect an error code # in the range 0-127, 256 can be interpretted as 'success'. Because we expect