]> git.lyx.org Git - lyx.git/blobdiff - lib/configure.py
Make sweave process files with the correct encoding (#6625).
[lyx.git] / lib / configure.py
index e1cbe6c4e328f29b86b52b964ba37af8d386ffbc..48cdb7de7ee3e90f5ae7723f1026f9ea8494e8cf 100644 (file)
@@ -378,7 +378,7 @@ def checkDTLtools():
 
 def checkLatex(dtl_tools):
     ''' Check latex, return lyx_check_config '''
 
 def checkLatex(dtl_tools):
     ''' Check latex, return lyx_check_config '''
-    path, LATEX = checkProg('a Latex2e program', ['latex $$i', 'platex $$i', 'latex2e $$i'])
+    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'])
     path, PPLATEX = checkProg('a DVI postprocessing program', ['pplatex $$i'])
     #-----------------------------------------------------------------
     path, PLATEX = checkProg('pLaTeX, the Japanese LaTeX', ['platex $$i'])
@@ -392,7 +392,6 @@ def checkLatex(dtl_tools):
         if cmdOutput(PLATEX + ' chklatex.ltx').find('pLaTeX2e') != -1:
             # We have the Japanese pLaTeX2e
             addToRC(r'\converter platex   dvi       "%s"   "latex"' % PLATEX)
         if cmdOutput(PLATEX + ' chklatex.ltx').find('pLaTeX2e') != -1:
             # We have the Japanese pLaTeX2e
             addToRC(r'\converter platex   dvi       "%s"   "latex"' % PLATEX)
-            LATEX = PLATEX
         else:
             PLATEX = ''
             removeFiles(['chklatex.ltx', 'chklatex.log'])
         else:
             PLATEX = ''
             removeFiles(['chklatex.ltx', 'chklatex.log'])
@@ -457,7 +456,7 @@ def checkFormatEntries(dtl_tools):
         rc_entry = [r'\Format fen        fen     FEN                    "" "%%"        "%%"    ""'])
     #
     checkViewerEditor('a SVG viewer and editor', ['inkscape'],
         rc_entry = [r'\Format fen        fen     FEN                    "" "%%"        "%%"    ""'])
     #
     checkViewerEditor('a SVG viewer and editor', ['inkscape'],
-        rc_entry = [r'\Format svg        svg    "Scalable Vector Graphics" "" "%%" "%%"        "vector"'])
+        rc_entry = [r'\Format svg        svg     SVG                    "" "%%" "%%"   "vector"'])
     #
     path, iv = checkViewerNoRC('a raster image viewer', ['xv', 'kview', 'gimp-remote', 'gimp'],
         rc_entry = [r'''\Format bmp        bmp     BMP                    "" "%s"      "%s"    ""
     #
     path, iv = checkViewerNoRC('a raster image viewer', ['xv', 'kview', 'gimp-remote', 'gimp'],
         rc_entry = [r'''\Format bmp        bmp     BMP                    "" "%s"      "%s"    ""
@@ -506,6 +505,7 @@ def checkFormatEntries(dtl_tools):
 \Format literate   nw      NoWeb                  N  ""        "%%"    "document"
 \Format sweave     Rnw    "Sweave"                S  "" "%%"    "document"
 \Format lilypond   ly     "LilyPond music"        "" ""        "%%"    "vector"
 \Format literate   nw      NoWeb                  N  ""        "%%"    "document"
 \Format sweave     Rnw    "Sweave"                S  "" "%%"    "document"
 \Format lilypond   ly     "LilyPond music"        "" ""        "%%"    "vector"
+\Format lilypond-book    lytex "LilyPond book (LaTeX)"   "" "" "%%"    "document"
 \Format latex      tex    "LaTeX (plain)"         L  ""        "%%"    "document"
 \Format pdflatex   tex    "LaTeX (pdflatex)"      "" ""        "%%"    "document"
 \Format xetex      tex    "LaTeX (XeTeX)"         "" ""        "%%"    "document"
 \Format latex      tex    "LaTeX (plain)"         L  ""        "%%"    "document"
 \Format pdflatex   tex    "LaTeX (pdflatex)"      "" ""        "%%"    "document"
 \Format xetex      tex    "LaTeX (XeTeX)"         "" ""        "%%"    "document"
@@ -516,9 +516,9 @@ def checkFormatEntries(dtl_tools):
 \Format textparagraph txt "Plain Text, Join Lines" "" ""       "%%"    "document"''' ])
  #
     path, xhtmlview = checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
 \Format textparagraph txt "Plain Text, Join Lines" "" ""       "%%"    "document"''' ])
  #
     path, xhtmlview = checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
-        rc_entry = [r'\Format xhtml      xhtml   "LyX HTML"              X "%%" ""    "document"'])
+        rc_entry = [r'\Format xhtml      xhtml   "LyXHTML"              X "%%" ""    "document"'])
     if xhtmlview == "":
     if xhtmlview == "":
-        addToRC(r'\Format xhtml      xhtml   "LyX HTML"              X "" ""  "document"')
+        addToRC(r'\Format xhtml      xhtml   "LyXHTML"              X "" ""  "document"')
  #
     checkEditor('a BibTeX editor', ['sensible-editor', 'jabref', 'JabRef', \
         'pybliographic', 'bibdesk', 'gbib', 'kbib', \
  #
     checkEditor('a BibTeX editor', ['sensible-editor', 'jabref', 'JabRef', \
         'pybliographic', 'bibdesk', 'gbib', 'kbib', \
@@ -552,8 +552,13 @@ def checkFormatEntries(dtl_tools):
     checkViewerEditor('Noteedit', ['noteedit'],
         rc_entry = [r'\Format noteedit   not     Noteedit               "" "%%"        "%%"    "vector"'])
     #
     checkViewerEditor('Noteedit', ['noteedit'],
         rc_entry = [r'\Format noteedit   not     Noteedit               "" "%%"        "%%"    "vector"'])
     #
-    checkViewerEditor('an OpenDocument viewer', ['swriter', 'oowriter'],
-        rc_entry = [r'\Format odt        odt     OpenDocument           "" "%%"        "%%"    "document,vector"'])
+    checkViewerEditor('an OpenDocument/OpenOffice viewer', ['swriter', 'oowriter', 'abiword'],
+        rc_entry = [r'''\Format odt        odt     OpenDocument           "" "%%"      "%%"    "document,vector"
+\Format sxw        sxw    "OpenOffice.Org (sxw)"  "" ""        ""      "document,vector"'''])
+    # 
+    checkViewerEditor('a Rich Text and Word viewer', ['swriter', 'oowriter', 'abiword'],
+        rc_entry = [r'''\Format rtf        rtf    "Rich Text Format"      "" ""        ""      "document,vector"
+\Format word       doc    "MS Word"               W  ""        ""      "document,vector"'''])
     #
     # entried that do not need checkProg
     addToRC(r'''\Format date       ""     "date command"          "" ""        ""      ""
     #
     # entried that do not need checkProg
     addToRC(r'''\Format date       ""     "date command"          "" ""        ""      ""
@@ -568,15 +573,13 @@ def checkFormatEntries(dtl_tools):
 \Format jlyx       cjklyx "CJK LyX 1.4.x (euc-jp)" "" ""       ""      "document"
 \Format klyx       cjklyx "CJK LyX 1.4.x (euc-kr)" "" ""       ""      "document"
 \Format lyxpreview lyxpreview "LyX Preview"       "" ""        ""      ""
 \Format jlyx       cjklyx "CJK LyX 1.4.x (euc-jp)" "" ""       ""      "document"
 \Format klyx       cjklyx "CJK LyX 1.4.x (euc-kr)" "" ""       ""      "document"
 \Format lyxpreview lyxpreview "LyX Preview"       "" ""        ""      ""
+\Format lyxpreview-lytex  lyxpreview-lytex  "LyX Preview (LilyPond book)" "" ""        ""      ""
 \Format lyxpreview-platex lyxpreview-platex "LyX Preview (pLaTeX)"       "" "" ""      ""
 \Format pdftex     pdftex_t PDFTEX                "" ""        ""      ""
 \Format program    ""      Program                "" ""        ""      ""
 \Format pstex      pstex_t PSTEX                  "" ""        ""      ""
 \Format lyxpreview-platex lyxpreview-platex "LyX Preview (pLaTeX)"       "" "" ""      ""
 \Format pdftex     pdftex_t PDFTEX                "" ""        ""      ""
 \Format program    ""      Program                "" ""        ""      ""
 \Format pstex      pstex_t PSTEX                  "" ""        ""      ""
-\Format rtf        rtf    "Rich Text Format"      "" ""        ""      "document,vector"
-\Format sxw        sxw    "OpenOffice.Org (sxw)"  ""  ""       ""      "document,vector"
 \Format wmf        wmf    "Windows Metafile"      "" ""        ""      "vector"
 \Format emf        emf    "Enhanced Metafile"     "" ""        ""      "vector"
 \Format wmf        wmf    "Windows Metafile"      "" ""        ""      "vector"
 \Format emf        emf    "Enhanced Metafile"     "" ""        ""      "vector"
-\Format word       doc    "MS Word"               W  ""        ""      "document,vector"
 \Format wordhtml   html   "HTML (MS Word)"        "" "" ""     "document"
 ''')
 
 \Format wordhtml   html   "HTML (MS Word)"        "" "" ""     "document"
 ''')
 
@@ -609,7 +612,7 @@ def checkConverterEntries():
         rc_entry = [r'''\converter literate   latex      "%%"  ""
 \converter literate   pdflatex      "%%"       ""'''])
     #
         rc_entry = [r'''\converter literate   latex      "%%"  ""
 \converter literate   pdflatex      "%%"       ""'''])
     #
-    checkProg('a Sweave -> LaTeX converter', ['R CMD Sweave $$i'],
+    checkProg('a Sweave -> LaTeX converter', ['Rscript --vanilla $$s/scripts/lyxsweave.R $$i $$e'],
         rc_entry = [r'''\converter sweave   latex      "%%"    ""
 \converter sweave   pdflatex      "%%" ""'''])
     #
         rc_entry = [r'''\converter sweave   latex      "%%"    ""
 \converter sweave   pdflatex      "%%" ""'''])
     #
@@ -619,6 +622,7 @@ def checkConverterEntries():
     #
     checkProg('an MS Word -> LaTeX converter', ['wvCleanLatex $$i $$o'],
         rc_entry = [ r'\converter word       latex      "%%"   ""' ])
     #
     checkProg('an MS Word -> LaTeX converter', ['wvCleanLatex $$i $$o'],
         rc_entry = [ r'\converter word       latex      "%%"   ""' ])
+
     # eLyXer: search as a Python module and then as an executable (elyxer.py, elyxer)
     elyxerfound = checkModule('elyxer')
     if elyxerfound:
     # eLyXer: search as a Python module and then as an executable (elyxer.py, elyxer)
     elyxerfound = checkModule('elyxer')
     if elyxerfound:
@@ -644,13 +648,36 @@ def checkConverterEntries():
       else:
         addToRC(r'''\copier    html       "python -tt $$s/scripts/ext_copy.py $$i $$o"''')
 
       else:
         addToRC(r'''\copier    html       "python -tt $$s/scripts/ext_copy.py $$i $$o"''')
 
-    # On SuSE the scripts have a .sh suffix, and on debian they are in /usr/share/tex4ht/
-    path, htmlconv = checkProg('a LaTeX -> MS Word converter', ["htlatex $$i 'html,word' 'symbol/!' '-cvalidate'", \
-        "htlatex.sh $$i 'html,word' 'symbol/!' '-cvalidate'", \
-        "/usr/share/tex4ht/htlatex $$i 'html,word' 'symbol/!' '-cvalidate'"],
-        rc_entry = [ r'\converter latex      wordhtml   "%%"   "needaux"' ])
-    if htmlconv.find('htlatex') >= 0:
-      addToRC(r'''\copier    wordhtml       "python -tt $$s/scripts/ext_copy.py -e html,png,css $$i $$o"''')
+    # Check if LyxBlogger is installed.
+    path, lyxblogger = checkProg('A LyX to WordPress Blog Publishing Tool',
+      ['lyxblogger $$i'], rc_entry = [])
+    if lyxblogger.find('lyxblogger') >= 0:
+      addToRC(r'\Format    blog       blog       "LyxBlogger"           "" "" ""  "document"')
+      addToRC(r'\converter xhtml      blog       "lyxblogger $$i"       ""')
+
+    if elyxerfound:
+      addToRC(r'''\converter lyx      wordhtml       "python -m elyxer --html --directory $$r $$i $$o" ""''')
+    else:
+      path, elyxer = checkProg('a LyX -> MS Word converter',
+        ['elyxer.py --directory $$r $$i $$o', 'elyxer --html --directory $$r $$i $$o'],
+        rc_entry = [ r'\converter lyx      wordhtml       "%%" ""' ])
+      if elyxer.find('elyxer') >= 0:
+        elyxerfound = True
+
+    if elyxerfound:
+      addToRC(r'''\copier    wordhtml       "python -tt $$s/scripts/ext_copy.py -e html,png,jpg,jpeg,css $$i $$o"''')
+    else:
+      # search for other converters than eLyXer
+      # On SuSE the scripts have a .sh suffix, and on debian they are in /usr/share/tex4ht/
+      path, htmlconv = checkProg('a LaTeX -> MS Word converter', ["htlatex $$i 'html,word' 'symbol/!' '-cvalidate'", \
+          "htlatex.sh $$i 'html,word' 'symbol/!' '-cvalidate'", \
+          "/usr/share/tex4ht/htlatex $$i 'html,word' 'symbol/!' '-cvalidate'"],
+          rc_entry = [ r'\converter latex      wordhtml   "%%" "needaux"' ])
+      if htmlconv.find('htlatex') >= 0:
+        addToRC(r'''\copier    wordhtml       "python -tt $$s/scripts/ext_copy.py -e html,png,css $$i $$o"''')
+      else:
+        addToRC(r'''\copier    wordhtml       "python -tt $$s/scripts/ext_copy.py $$i $$o"''')
+
     #
     checkProg('an OpenOffice.org -> LaTeX converter', ['w2l -clean $$i'],
         rc_entry = [ r'\converter sxw        latex      "%%"   ""' ])
     #
     checkProg('an OpenOffice.org -> LaTeX converter', ['w2l -clean $$i'],
         rc_entry = [ r'\converter sxw        latex      "%%"   ""' ])
@@ -748,8 +775,11 @@ def checkConverterEntries():
 \converter agr        ppm        "gracebat -hardcopy -printfile $$o -hdevice PNM $$i 2>/dev/null"      ""''',
             ''])
     #
 \converter agr        ppm        "gracebat -hardcopy -printfile $$o -hdevice PNM $$i 2>/dev/null"      ""''',
             ''])
     #
-    checkProg('a Dot -> PDF converter', ['dot -Tpdf $$i -o $$o'],
-        rc_entry = [ r'\converter dot        pdf        "%%"   ""'])
+    checkProg('a Dot -> Image converter', ['dot'],
+        rc_entry = [
+            r'''\converter dot        eps        "dot -Teps $$i -o $$o"        ""
+\converter dot        png        "dot -Tpng $$i -o $$o"        ""''',
+            ''])
     #
     checkProg('a Dia -> PNG converter', ['dia -e $$o -t png $$i'],
         rc_entry = [ r'\converter dia        png        "%%"   ""'])
     #
     checkProg('a Dia -> PNG converter', ['dia -e $$o -t png $$i'],
         rc_entry = [ r'\converter dia        png        "%%"   ""'])
@@ -757,15 +787,15 @@ def checkConverterEntries():
     checkProg('a Dia -> EPS converter', ['dia -e $$o -t eps $$i'],
         rc_entry = [ r'\converter dia        eps        "%%"   ""'])
     #
     checkProg('a Dia -> EPS converter', ['dia -e $$o -t eps $$i'],
         rc_entry = [ r'\converter dia        eps        "%%"   ""'])
     #
-    checkProg('a SVG -> PDF converter', ['rsvg-convert -f pdf -o $$o $$i'],
+    checkProg('a SVG -> PDF converter', ['rsvg-convert -f pdf -o $$o $$i', 'inkscape --file=$$p/$$i --export-area-drawing --without-gui --export-pdf=$$p/$$o'],
         rc_entry = [ r'\converter svg        pdf        "%%"   ""'])
     #
         rc_entry = [ r'\converter svg        pdf        "%%"   ""'])
     #
-    checkProg('a SVG -> EPS converter', ['rsvg-convert -f ps -o $$o $$i'],
+    checkProg('a SVG -> EPS converter', ['rsvg-convert -f ps -o $$o $$i', 'inkscape --file=$$p/$$i --export-area-drawing --without-gui --export-eps=$$p/$$o'],
         rc_entry = [ r'\converter svg        eps        "%%"   ""'])
         rc_entry = [ r'\converter svg        eps        "%%"   ""'])
-    #
-    checkProg('a SVG -> PNG converter', ['rsvg-convert -f png -o $$o $$i'],
+    # the PNG export via Inkscape must not have the full path ($$p) for the file
+    checkProg('a SVG -> PNG converter', ['rsvg-convert -f png -o $$o $$i', 'inkscape --without-gui --file=$$i --export-png=$$o'],
         rc_entry = [ r'\converter svg        png        "%%"   ""'])
         rc_entry = [ r'\converter svg        png        "%%"   ""'])
-    #
+    
     #
     path, lilypond = checkProg('a LilyPond -> EPS/PDF/PNG converter', ['lilypond'])
     if (lilypond != ''):
     #
     path, lilypond = checkProg('a LilyPond -> EPS/PDF/PNG converter', ['lilypond'])
     if (lilypond != ''):
@@ -778,7 +808,7 @@ def checkConverterEntries():
                 addToRC(r'''\converter lilypond   eps        "lilypond -dbackend=eps --ps $$i" ""
 \converter lilypond   png        "lilypond -dbackend=eps --png $$i"    ""''')
                 addToRC(r'\converter lilypond   pdf        "lilypond -dbackend=eps --pdf $$i"  ""')
                 addToRC(r'''\converter lilypond   eps        "lilypond -dbackend=eps --ps $$i" ""
 \converter lilypond   png        "lilypond -dbackend=eps --png $$i"    ""''')
                 addToRC(r'\converter lilypond   pdf        "lilypond -dbackend=eps --pdf $$i"  ""')
-                print '+  found LilyPond version %s.' % version_number
+                logger.info('+  found LilyPond version %s.' % version_number)
             elif int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 6):
                 addToRC(r'''\converter lilypond   eps        "lilypond -b eps --ps $$i"        ""
 \converter lilypond   png        "lilypond -b eps --png $$i"   ""''')
             elif int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 6):
                 addToRC(r'''\converter lilypond   eps        "lilypond -b eps --ps $$i"        ""
 \converter lilypond   png        "lilypond -b eps --png $$i"   ""''')
@@ -790,6 +820,38 @@ def checkConverterEntries():
         else:
             logger.info('+  found LilyPond, but could not extract version number.')
     #
         else:
             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 != ''):
+        version_string = cmdOutput("lilypond-book --version")
+        match = re.match('^(\S+)$', version_string)
+        if match:
+            version_number = match.groups()[0]
+            version = version_number.split('.')
+            if int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 1):
+                addToRC(r'\converter lyxpreview-lytex ppm "python -tt $$s/scripts/lyxpreview-lytex2bitmap.py" ""')
+                if dvipng == "dvipng":
+                    addToRC(r'\converter lyxpreview-lytex png "python -tt $$s/scripts/lyxpreview-lytex2bitmap.py" ""')
+                else:
+                    addToRC(r'\converter lyxpreview-lytex png "" ""')
+            if int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 11):
+                # Note: The --lily-output-dir flag is required because lilypond-book
+                #       does not process input again unless the input has changed,
+                #       even if the output format being requested is different. So
+                #       once a .eps file exists, lilypond-book won't create a .pdf
+                #       even when requested with --pdf. This is a problem if a user
+                #       clicks View PDF after having done a View DVI. To circumvent
+                #       this, use different output folders for eps and pdf outputs.
+                addToRC(r'\converter lilypond-book latex    "lilypond-book --lily-output-dir=ly-eps $$i"                                ""')
+                addToRC(r'\converter lilypond-book pdflatex "lilypond-book --pdf --latex-program=pdflatex --lily-output-dir=ly-pdf $$i" ""')
+                logger.info('+  found LilyPond-book version %s.' % version_number)
+            elif int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 1):
+                addToRC(r'\converter lilypond-book latex  "lilypond-book $$i"                                ""')
+                logger.info('+  found LilyPond-book version %s.' % version_number)
+            else:
+                logger.info('+  found LilyPond-book, but version %s is too old.' % version_number)
+        else:
+            logger.info('+  found LilyPond-book, but could not extract version number.')
+    #
     checkProg('a Noteedit -> LilyPond converter', ['noteedit --export-lilypond $$i'],
         rc_entry = [ r'\converter noteedit   lilypond   "%%"   ""', ''])
     #
     checkProg('a Noteedit -> LilyPond converter', ['noteedit --export-lilypond $$i'],
         rc_entry = [ r'\converter noteedit   lilypond   "%%"   ""', ''])
     #
@@ -844,7 +906,7 @@ def checkOtherEntries():
     checkProgAlternatives('BibTeX or alternative programs', ['bibtex', 'bibtex8', 'biber'],
         rc_entry = [ r'\bibtex_command "%%"' ],
         alt_rc_entry = [ r'\bibtex_alternatives "%%"' ])
     checkProgAlternatives('BibTeX or alternative programs', ['bibtex', 'bibtex8', 'biber'],
         rc_entry = [ r'\bibtex_command "%%"' ],
         alt_rc_entry = [ r'\bibtex_alternatives "%%"' ])
-    checkProg('JBibTeX, the Japanese BibTeX', ['jbibtex', 'bibtex'],
+    checkProg('a specific Japanese BibTeX variant', ['pbibtex', 'jbibtex', 'bibtex'],
         rc_entry = [ r'\jbibtex_command "%%"' ])
     checkProgAlternatives('available index processors', ['texindy', 'makeindex -c -q'],
         rc_entry = [ r'\index_command "%%"' ],
         rc_entry = [ r'\jbibtex_command "%%"' ])
     checkProgAlternatives('available index processors', ['texindy', 'makeindex -c -q'],
         rc_entry = [ r'\index_command "%%"' ],
@@ -888,10 +950,17 @@ def processLayoutFile(file, bool_docbook):
 
         we expect output:
         
 
         we expect output:
         
-        "article" "article" "article" "false"
-        "scrbook" "scrbook" "book (koma-script)" "false"
-        "svjog" "svjour" "article (Springer - svjour/jog)" "false"
+        "article" "article" "article" "false" "article.cls"
+        "scrbook" "scrbook" "book (koma-script)" "false" "scrbook.cls"
+        "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 '.' in x:
+            return x.strip() + '.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(r'\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}')
     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(r'\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}')
@@ -902,7 +971,14 @@ def processLayoutFile(file, bool_docbook):
             avai = {'LaTeX':'false', 'DocBook':bool_docbook}[classtype]
             if opt == None:
                 opt = classname
             avai = {'LaTeX':'false', 'DocBook':bool_docbook}[classtype]
             if opt == None:
                 opt = classname
-            return '"%s" "%s" "%s" "%s"\n' % (classname, opt, desc, avai)
+                prereq_latex = checkForClassExtension(classname)
+            else:
+                prereq_list = optAll[1:-1].split(',')
+                prereq_list = map(checkForClassExtension, prereq_list)
+                prereq_latex = ','.join(prereq_list)
+            prereq_docbook = {'true':'', 'false':'docbook'}[bool_docbook]
+            prereq = {'LaTeX':prereq_latex, 'DocBook':prereq_docbook}[classtype]
+            return '"%s" "%s" "%s" "%s" "%s"\n' % (classname, opt, desc, avai, prereq)
     logger.warning("Layout file " + file + " has no \DeclareXXClass line. ")
     return ""
 
     logger.warning("Layout file " + file + " has no \DeclareXXClass line. ")
     return ""
 
@@ -954,75 +1030,75 @@ def checkLatexConfig(check_config, bool_docbook):
     if not check_config:
         return None
     # the following will generate textclass.lst.tmp, and packages.lst.tmp
     if not check_config:
         return None
     # the following will generate textclass.lst.tmp, and packages.lst.tmp
-    else:
-        logger.info(msg + '\tauto')
-        removeFiles(['wrap_chkconfig.ltx', 'chkconfig.vars', \
-            'chkconfig.classes', 'chklayouts.tex'])
-        rmcopy = False
-        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)
-        # Construct the list of classes to test for.
-        # build the list of available layout files and convert it to commands
-        # for chkconfig.ltx
-        p1 = re.compile(r'\Declare(LaTeX|DocBook)Class')
-        testclasses = list()
-        for file in glob.glob( os.path.join('layouts', '*.layout') ) + \
-            glob.glob( os.path.join(srcdir, 'layouts', '*.layout' ) ) :
-            if not os.path.isfile(file):
+    logger.info(msg + '\tauto')
+    removeFiles(['wrap_chkconfig.ltx', 'chkconfig.vars', \
+        'chkconfig.classes', 'chklayouts.tex'])
+    rmcopy = False
+    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)
+    # 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(r'\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}')
+    empty = re.compile(r'^\s*$')
+    testclasses = list()
+    for file in glob.glob( os.path.join('layouts', '*.layout') ) + \
+        glob.glob( os.path.join(srcdir, 'layouts', '*.layout' ) ) :
+        if not os.path.isfile(file):
+            continue
+        classname = file.split(os.sep)[-1].split('.')[0]
+        for line in open(file).readlines():
+            if not empty.match(line) and line[0] != '#':
+                logger.error("Failed to find \Declare line for layout file `" + file + "'")
+                sys.exit(3)
+            if declare.search(line) == None:
                 continue
                 continue
-            classname = file.split(os.sep)[-1].split('.')[0]
-            for line in open(file).readlines():
-                if p1.search(line) == None:
-                    continue
-                if line[0] != '#':
-                    logger.error("Wrong input layout file with line '" + line)
-                    sys.exit(3)
-                testclasses.append("\\TestDocClass{%s}{%s}" % (classname, line[1:].strip()))
-                break
-        testclasses.sort()
-        cl = open('chklayouts.tex', 'w')
-        for line in testclasses:
-            cl.write(line + '\n')
-        cl.close()
-        #
-        # we have chklayouts.tex, then process it
-        fout = os.popen(LATEX + ' wrap_chkconfig.ltx')
-        while True:
-            line = fout.readline()
-            if not line:
-                break;
-            if re.match('^\+', line):
-                logger.info(line.strip())
-        # if the command succeeds, None will be returned
-        ret = fout.close()
-        #
-        # currently, values in chhkconfig are only used to set
-        # \font_encoding
-        values = {}
-        for line in open('chkconfig.vars').readlines():
-            key, val = re.sub('-', '_', line).split('=')
-            val = val.strip()
-            values[key] = val.strip("'")
-        # chk_fontenc may not exist 
-        try:
-            addToRC(r'\font_encoding "%s"' % values["chk_fontenc"])
-        except:
-            pass
-        if rmcopy:   # remove the copied file
-            removeFiles( [ 'chkconfig.ltx' ] )
-        # 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 os.path.isfile('packages.lst.tmp') and len(open('packages.lst.tmp').read()) > 0:
-            shutil.move('textclass.lst.tmp', 'textclass.lst')
-            shutil.move('packages.lst.tmp', 'packages.lst')
-        return ret
+            testclasses.append("\\TestDocClass{%s}{%s}" % (classname, line[1:].strip()))
+            break
+    testclasses.sort()
+    cl = open('chklayouts.tex', 'w')
+    for line in testclasses:
+        cl.write(line + '\n')
+    cl.close()
+    #
+    # we have chklayouts.tex, then process it
+    fout = os.popen(LATEX + ' wrap_chkconfig.ltx')
+    while True:
+        line = fout.readline()
+        if not line:
+            break;
+        if re.match('^\+', line):
+            logger.info(line.strip())
+    # if the command succeeds, None will be returned
+    ret = fout.close()
+    #
+    # currently, values in chhkconfig are only used to set
+    # \font_encoding
+    values = {}
+    for line in open('chkconfig.vars').readlines():
+        key, val = re.sub('-', '_', line).split('=')
+        val = val.strip()
+        values[key] = val.strip("'")
+    # chk_fontenc may not exist 
+    try:
+        addToRC(r'\font_encoding "%s"' % values["chk_fontenc"])
+    except:
+        pass
+    if rmcopy:   # remove the copied file
+        removeFiles( [ 'chkconfig.ltx' ] )
+    # 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 os.path.isfile('packages.lst.tmp') and len(open('packages.lst.tmp').read()) > 0:
+        shutil.move('textclass.lst.tmp', 'textclass.lst')
+        shutil.move('packages.lst.tmp', 'packages.lst')
+    return ret
 
 
 def checkModulesConfig():
 
 
 def checkModulesConfig():
-  removeFiles(['lyxmodules.lst'])
+  removeFiles(['lyxmodules.lst', 'chkmodules.tex'])
 
   logger.info('+checking list of modules... ')
   tx = open('lyxmodules.lst', 'w')
 
   logger.info('+checking list of modules... ')
   tx = open('lyxmodules.lst', 'w')
@@ -1062,12 +1138,12 @@ def processModuleFile(file, bool_docbook):
         We expect output:
           "ModuleName" "filename" "Description" "Packages" "Requires" "Excludes" "Category"
     '''
         We expect output:
           "ModuleName" "filename" "Description" "Packages" "Requires" "Excludes" "Category"
     '''
-    p = re.compile(r'\DeclareLyXModule\s*(?:\[([^]]*?)\])?{(.*)}')
-    r = re.compile(r'#+\s*Requires: (.*)')
-    x = re.compile(r'#+\s*Excludes: (.*)')
-    c = re.compile(r'#+\s*Category: (.*)')
-    b = re.compile(r'#+\s*DescriptionBegin\s*$')
-    e = re.compile(r'#+\s*DescriptionEnd\s*$')
+    remods = re.compile(r'\DeclareLyXModule\s*(?:\[([^]]*?)\])?{(.*)}')
+    rereqs = re.compile(r'#+\s*Requires: (.*)')
+    reexcs = re.compile(r'#+\s*Excludes: (.*)')
+    recaty = re.compile(r'#+\s*Category: (.*)')
+    redbeg = re.compile(r'#+\s*DescriptionBegin\s*$')
+    redend = re.compile(r'#+\s*DescriptionEnd\s*$')
 
     modname = desc = pkgs = req = excl = catgy = ""
     readingDescription = False
 
     modname = desc = pkgs = req = excl = catgy = ""
     readingDescription = False
@@ -1077,18 +1153,20 @@ def processModuleFile(file, bool_docbook):
 
     for line in open(file).readlines():
       if readingDescription:
 
     for line in open(file).readlines():
       if readingDescription:
-        res = e.search(line)
+        res = redend.search(line)
         if res != None:
           readingDescription = False
           desc = " ".join(descLines)
         if res != None:
           readingDescription = False
           desc = " ".join(descLines)
+          # Escape quotes.
+          desc = desc.replace('"', '\\"')
           continue
         descLines.append(line[1:].strip())
         continue
           continue
         descLines.append(line[1:].strip())
         continue
-      res = b.search(line)
+      res = redbeg.search(line)
       if res != None:
         readingDescription = True
         continue
       if res != None:
         readingDescription = True
         continue
-      res = p.search(line)
+      res = remods.search(line)
       if res != None:
           (pkgs, modname) = res.groups()
           if pkgs == None:
       if res != None:
           (pkgs, modname) = res.groups()
           if pkgs == None:
@@ -1097,26 +1175,46 @@ def processModuleFile(file, bool_docbook):
             tmp = [s.strip() for s in pkgs.split(",")]
             pkgs = ",".join(tmp)
           continue
             tmp = [s.strip() for s in pkgs.split(",")]
             pkgs = ",".join(tmp)
           continue
-      res = r.search(line)
+      res = rereqs.search(line)
       if res != None:
         req = res.group(1)
         tmp = [s.strip() for s in req.split("|")]
         req = "|".join(tmp)
         continue
       if res != None:
         req = res.group(1)
         tmp = [s.strip() for s in req.split("|")]
         req = "|".join(tmp)
         continue
-      res = x.search(line)
+      res = reexcs.search(line)
       if res != None:
         excl = res.group(1)
         tmp = [s.strip() for s in excl.split("|")]
         excl = "|".join(tmp)
         continue
       if res != None:
         excl = res.group(1)
         tmp = [s.strip() for s in excl.split("|")]
         excl = "|".join(tmp)
         continue
-      res = c.search(line)
+      res = recaty.search(line)
       if res != None:
         catgy = res.group(1)
         continue
       if res != None:
         catgy = res.group(1)
         continue
-    if modname != "":
-        return '"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, desc, pkgs, req, excl, catgy)
-    logger.warning("Module file without \DeclareLyXModule line. ")
-    return ""
+
+    if modname == "":
+      logger.warning("Module file without \DeclareLyXModule line. ")
+      return ""
+
+    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(","):
+            if "->" in pkg:
+                # this is a converter dependency: skip
+                continue
+            if pkg.endswith(".sty"):
+                pkg = pkg[:-4]
+            testpackages.append("\\TestPackage{%s}" % (pkg,))
+        cm = open('chkmodules.tex', 'a')
+        for line in testpackages:
+            cm.write(line + '\n')
+        cm.close()
+
+    return '"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, desc, pkgs, req, excl, catgy)
+    
 
 
 def checkTeXAllowSpaces():
 
 
 def checkTeXAllowSpaces():
@@ -1125,10 +1223,13 @@ def checkTeXAllowSpaces():
     if lyx_check_config:
         msg = "Checking whether TeX allows spaces in file names... "
         writeToFile('a b.tex', r'\message{working^^J}' )
     if lyx_check_config:
         msg = "Checking whether TeX allows spaces in file names... "
         writeToFile('a b.tex', r'\message{working^^J}' )
-        if os.name == 'nt':
-            latex_out = cmdOutput(LATEX + r""" "\nonstopmode\input{\"a b\"}" """)
+        if LATEX != '':
+            if os.name == 'nt':
+                latex_out = cmdOutput(LATEX + r""" "\nonstopmode\input{\"a b\"}" """)
+            else:
+                latex_out = cmdOutput(LATEX + r""" '\nonstopmode\input{"a b"}' """)
         else:
         else:
-            latex_out = cmdOutput(LATEX + r""" '\nonstopmode\input{"a b"}' """)
+            latex_out = ''
         if 'working' in latex_out:
             logger.info(msg + 'yes')
             tex_allows_spaces = 'true'
         if 'working' in latex_out:
             logger.info(msg + 'yes')
             tex_allows_spaces = 'true'
@@ -1144,7 +1245,7 @@ def removeTempFiles():
     if not lyx_keep_temps:
         removeFiles(['chkconfig.vars',  \
             'wrap_chkconfig.ltx', 'wrap_chkconfig.log', \
     if not lyx_keep_temps:
         removeFiles(['chkconfig.vars',  \
             'wrap_chkconfig.ltx', 'wrap_chkconfig.log', \
-            'chklayouts.tex', 'missfont.log', 
+            'chklayouts.tex', 'chkmodules.tex', 'missfont.log', 
             'chklatex.ltx', 'chklatex.log'])
 
 
             'chklatex.ltx', 'chklatex.log'])
 
 
@@ -1203,9 +1304,9 @@ Options:
     if windows_style_tex_paths != '':
         addToRC(r'\tex_expects_windows_paths %s' % windows_style_tex_paths)
     checkOtherEntries()
     if windows_style_tex_paths != '':
         addToRC(r'\tex_expects_windows_paths %s' % windows_style_tex_paths)
     checkOtherEntries()
+    checkModulesConfig()
     # --without-latex-config can disable lyx_check_config
     ret = checkLatexConfig(lyx_check_config and LATEX != '', bool_docbook)
     # --without-latex-config can disable lyx_check_config
     ret = checkLatexConfig(lyx_check_config and LATEX != '', bool_docbook)
-    checkModulesConfig() #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
     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