]> git.lyx.org Git - lyx.git/blobdiff - lib/configure.py
fix r33152 - part 1
[lyx.git] / lib / configure.py
index 2a3d9e4f9ae2f3eed956ac7fefa0639e85ae8763..cc4e0ce29e351d1551b58c56c8874c8e711d3f76 100644 (file)
@@ -178,9 +178,190 @@ def checkProg(description, progs, rc_entry = [], path = [], not_found = ''):
     return ['', not_found]
 
 
     return ['', not_found]
 
 
+def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [], path = [], not_found = ''):
+    ''' 
+        The same as checkProg, but additionally, all found programs will be added
+        as alt_rc_entries
+    '''
+    # one rc entry for each progs plus not_found entry
+    if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
+        logger.error("rc entry should have one item or item for each prog and not_found.")
+        sys.exit(2)
+    logger.info('checking for ' + description + '...')
+    ## print '(' + ','.join(progs) + ')',
+    found_prime = False
+    real_ac_dir = ''
+    real_ac_word = not_found
+    for idx in range(len(progs)):
+        # ac_prog may have options, ac_word is the command name
+        ac_prog = progs[idx]
+        ac_word = ac_prog.split(' ')[0]
+        msg = '+checking for "' + ac_word + '"... '
+        path = os.environ["PATH"].split(os.pathsep) + path
+        extlist = ['']
+        if os.environ.has_key("PATHEXT"):
+            extlist = extlist + os.environ["PATHEXT"].split(os.pathsep)
+        found_alt = False
+        for ac_dir in path:
+            for ext in extlist:
+                if os.path.isfile( os.path.join(ac_dir, ac_word + ext) ):
+                    logger.info(msg + ' yes')
+                    pr = re.compile(r'(\\\S+)(.*)$')
+                    m = None
+                    # write rc entries for this command
+                    if found_prime == False:
+                        if len(rc_entry) == 1:
+                            addToRC(rc_entry[0].replace('%%', ac_prog))
+                        elif len(rc_entry) > 1:
+                            addToRC(rc_entry[idx].replace('%%', ac_prog))
+                        real_ac_dir = ac_dir
+                        real_ac_word = ac_word
+                        found_prime = True
+                    if len(alt_rc_entry) == 1:
+                        alt_rc = alt_rc_entry[0]
+                        if alt_rc == "":
+                            # if no explicit alt_rc is given, construct one
+                            m = pr.match(rc_entry[0])
+                            if m:
+                                alt_rc = m.group(1) + "_alternatives" + m.group(2)
+                        addToRC(alt_rc.replace('%%', ac_prog))
+                    elif len(alt_rc_entry) > 1:
+                        alt_rc = alt_rc_entry[idx]
+                        if alt_rc == "":
+                            # if no explicit alt_rc is given, construct one
+                            m = pr.match(rc_entry[idx])
+                            if m:
+                                alt_rc = m.group(1) + "_alternatives" + m.group(2)
+                        addToRC(alt_rc.replace('%%', ac_prog))
+                    found_alt = True
+                    break
+            if found_alt:
+                break
+        if found_alt == False:
+            # if not successful
+            logger.info(msg + ' no')
+    if found_prime:
+        return [real_ac_dir, real_ac_word]
+    # write rc entries for 'not found'
+    if len(rc_entry) > 0:  # the last one.
+        addToRC(rc_entry[-1].replace('%%', not_found))
+    return ['', not_found]
+
+
+def addViewerAlternatives(rcs):
+    r = re.compile(r'\\Format (\S+).*$')
+    m = None
+    alt = ''
+    for idxx in range(len(rcs)):
+        if len(rcs) == 1:
+            m = r.match(rcs[0])
+            if m:
+                alt = r'\viewer_alternatives ' + m.group(1) + " %%"
+        elif len(rcs) > 1:
+            m = r.match(rcs[idxx])
+            if m:
+                if idxx > 0:
+                    alt += '\n'
+                alt += r'\viewer_alternatives ' + m.group(1) + " %%"
+    return alt
+
+
+def addEditorAlternatives(rcs):
+    r = re.compile(r'\\Format (\S+).*$')
+    m = None
+    alt = ''
+    for idxx in range(len(rcs)):
+        if len(rcs) == 1:
+            m = r.match(rcs[0])
+            if m:
+                alt = r'\editor_alternatives ' + m.group(1) + " %%"
+        elif len(rcs) > 1:
+            m = r.match(rcs[idxx])
+            if m:
+                if idxx > 0:
+                    alt += '\n'
+                alt += r'\editor_alternatives ' + m.group(1) + " %%"
+    return alt
+
+
 def checkViewer(description, progs, rc_entry = [], path = []):
 def checkViewer(description, progs, rc_entry = [], path = []):
-    ''' The same as checkProg, but for viewers and editors '''
-    return checkProg(description, progs, rc_entry, path, not_found = 'auto')
+    ''' The same as checkProgAlternatives, but for viewers '''
+    if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
+        logger.error("rc entry should have one item or item for each prog and not_found.")
+        sys.exit(2)
+    alt_rc_entry = []
+    for idx in range(len(progs)):
+        if len(rc_entry) == 1:
+            rcs = rc_entry[0].split('\n')
+            alt = addViewerAlternatives(rcs)
+            alt_rc_entry.insert(0, alt)
+        elif len(rc_entry) > 1:
+            rcs = rc_entry[idx].split('\n')
+            alt = addViewerAlternatives(rcs)
+            alt_rc_entry.insert(idx, alt)
+    return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto')
+
+
+def checkEditor(description, progs, rc_entry = [], path = []):
+    ''' The same as checkProgAlternatives, but for editors '''
+    if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
+        logger.error("rc entry should have one item or item for each prog and not_found.")
+        sys.exit(2)
+    alt_rc_entry = []
+    for idx in range(len(progs)):
+        if len(rc_entry) == 1:
+            rcs = rc_entry[0].split('\n')
+            alt = addEditorAlternatives(rcs)
+            alt_rc_entry.insert(0, alt)
+        elif len(rc_entry) > 1:
+            rcs = rc_entry[idx].split('\n')
+            alt = addEditorAlternatives(rcs)
+            alt_rc_entry.insert(idx, alt)
+    return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto')
+
+
+def checkViewerNoRC(description, progs, rc_entry = [], path = []):
+    ''' The same as checkViewer, but do not add rc entry '''
+    if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
+        logger.error("rc entry should have one item or item for each prog and not_found.")
+        sys.exit(2)
+    alt_rc_entry = []
+    for idx in range(len(progs)):
+        if len(rc_entry) == 1:
+            rcs = rc_entry[0].split('\n')
+            alt = addViewerAlternatives(rcs)
+            alt_rc_entry.insert(0, alt)
+        elif len(rc_entry) > 1:
+            rcs = rc_entry[idx].split('\n')
+            alt = addViewerAlternatives(rcs)
+            alt_rc_entry.insert(idx, alt)
+    rc_entry = []
+    return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto')
+
+
+def checkEditorNoRC(description, progs, rc_entry = [], path = []):
+    ''' The same as checkViewer, but do not add rc entry '''
+    if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
+        logger.error("rc entry should have one item or item for each prog and not_found.")
+        sys.exit(2)
+    alt_rc_entry = []
+    for idx in range(len(progs)):
+        if len(rc_entry) == 1:
+            rcs = rc_entry[0].split('\n')
+            alt = addEditorAlternatives(rcs)
+            alt_rc_entry.insert(0, alt)
+        elif len(rc_entry) > 1:
+            rcs = rc_entry[idx].split('\n')
+            alt = addEditorAlternatives(rcs)
+            alt_rc_entry.insert(idx, alt)
+    rc_entry = []
+    return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto')
+
+
+def checkViewerEditor(description, progs, rc_entry = [], path = []):
+    ''' The same as checkProgAlternatives, but for viewers and editors '''
+    checkEditorNoRC(description, progs, rc_entry, path)
+    return checkViewer(description, progs, rc_entry, path)
 
 
 def checkDTLtools():
 
 
 def checkDTLtools():
@@ -246,25 +427,60 @@ def checkLatex(dtl_tools):
     return ''
 
 
     return ''
 
 
+def checkModule(module):
+    ''' Check for a Python module, return the status '''
+    msg = 'checking for "' + module + ' module"... '
+    try:
+      __import__(module)
+      logger.info(msg + ' yes')
+      return True
+    except ImportError:
+      logger.info(msg + ' no')
+      return False
+
+
 def checkFormatEntries(dtl_tools):  
     ''' Check all formats (\Format entries) '''
 def checkFormatEntries(dtl_tools):  
     ''' Check all formats (\Format entries) '''
-    checkViewer('a Tgif viewer and editor', ['tgif'],
+    checkViewerEditor('a Tgif viewer and editor', ['tgif'],
         rc_entry = [r'\Format tgif       obj     Tgif                   "" "%%"        "%%"    "vector"'])
     #
         rc_entry = [r'\Format tgif       obj     Tgif                   "" "%%"        "%%"    "vector"'])
     #
-    checkViewer('a FIG viewer and editor', ['xfig', 'jfig3-itext.jar', 'jfig3.jar'],
+    checkViewerEditor('a FIG viewer and editor', ['xfig', 'jfig3-itext.jar', 'jfig3.jar'],
         rc_entry = [r'\Format fig        fig     FIG                    "" "%%"        "%%"    "vector"'])
     #
         rc_entry = [r'\Format fig        fig     FIG                    "" "%%"        "%%"    "vector"'])
     #
-    checkViewer('a Dia viewer and editor', ['dia'],
+    checkViewerEditor('a Dia viewer and editor', ['dia'],
         rc_entry = [r'\Format dia        dia     DIA                    "" "%%"        "%%"    "vector"'])
     #
         rc_entry = [r'\Format dia        dia     DIA                    "" "%%"        "%%"    "vector"'])
     #
-    checkViewer('a Grace viewer and editor', ['xmgrace'],
+    checkViewerEditor('a Grace viewer and editor', ['xmgrace'],
         rc_entry = [r'\Format agr        agr     Grace                  "" "%%"        "%%"    "vector"'])
     #
         rc_entry = [r'\Format agr        agr     Grace                  "" "%%"        "%%"    "vector"'])
     #
-    checkViewer('a FEN viewer and editor', ['xboard -lpf $$i -mode EditPosition'],
+    checkViewerEditor('a FEN viewer and editor', ['xboard -lpf $$i -mode EditPosition'],
         rc_entry = [r'\Format fen        fen     FEN                    "" "%%"        "%%"    ""'])
     #
         rc_entry = [r'\Format fen        fen     FEN                    "" "%%"        "%%"    ""'])
     #
-    path, iv = checkViewer('a raster image viewer', ['xv', 'kview', 'gimp-remote', 'gimp'])
-    path, ie = checkViewer('a raster image editor', ['gimp-remote', 'gimp'])
+    checkViewerEditor('a SVG viewer and editor', ['inkscape'],
+        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"    ""
+\Format gif        gif     GIF                    "" "%s"      "%s"    ""
+\Format jpg        jpg     JPEG                   "" "%s"      "%s"    ""
+\Format pbm        pbm     PBM                    "" "%s"      "%s"    ""
+\Format pgm        pgm     PGM                    "" "%s"      "%s"    ""
+\Format png        png     PNG                    "" "%s"      "%s"    ""
+\Format ppm        ppm     PPM                    "" "%s"      "%s"    ""
+\Format tiff       tif     TIFF                   "" "%s"      "%s"    ""
+\Format xbm        xbm     XBM                    "" "%s"      "%s"    ""
+\Format xpm        xpm     XPM                    "" "%s"      "%s"    ""'''])
+    path, ie = checkEditorNoRC('a raster image editor', ['gimp-remote', 'gimp'],
+        rc_entry = [r'''\Format bmp        bmp     BMP                    "" "%s"      "%s"    ""
+\Format gif        gif     GIF                    "" "%s"      "%s"    ""
+\Format jpg        jpg     JPEG                   "" "%s"      "%s"    ""
+\Format pbm        pbm     PBM                    "" "%s"      "%s"    ""
+\Format pgm        pgm     PGM                    "" "%s"      "%s"    ""
+\Format png        png     PNG                    "" "%s"      "%s"    ""
+\Format ppm        ppm     PPM                    "" "%s"      "%s"    ""
+\Format tiff       tif     TIFF                   "" "%s"      "%s"    ""
+\Format xbm        xbm     XBM                    "" "%s"      "%s"    ""
+\Format xpm        xpm     XPM                    "" "%s"      "%s"    ""'''])
     addToRC(r'''\Format bmp        bmp     BMP                    "" "%s"      "%s"    ""
 \Format gif        gif     GIF                    "" "%s"      "%s"    ""
 \Format jpg        jpg     JPEG                   "" "%s"      "%s"    ""
     addToRC(r'''\Format bmp        bmp     BMP                    "" "%s"      "%s"    ""
 \Format gif        gif     GIF                    "" "%s"      "%s"    ""
 \Format jpg        jpg     JPEG                   "" "%s"      "%s"    ""
@@ -277,7 +493,7 @@ def checkFormatEntries(dtl_tools):
 \Format xpm        xpm     XPM                    "" "%s"      "%s"    ""''' % \
         (iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie) )
     #
 \Format xpm        xpm     XPM                    "" "%s"      "%s"    ""''' % \
         (iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie) )
     #
-    checkViewer('a text editor', ['sensible-editor', 'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
+    checkViewerEditor('a text editor', ['sensible-editor', 'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
         'nedit', 'gedit', 'notepad'],
         rc_entry = [r'''\Format asciichess asc    "Plain text (chess output)"  "" ""   "%%"    ""
 \Format asciiimage asc    "Plain text (image)"         "" ""   "%%"    ""
         'nedit', 'gedit', 'notepad'],
         rc_entry = [r'''\Format asciichess asc    "Plain text (chess output)"  "" ""   "%%"    ""
 \Format asciiimage asc    "Plain text (image)"         "" ""   "%%"    ""
@@ -288,6 +504,7 @@ def checkFormatEntries(dtl_tools):
 \Format dot        dot    "Graphviz Dot"          "" ""        "%%"    "vector"
 \Format platex     tex    "LaTeX (pLaTeX)"        "" "" "%%"    "document"
 \Format literate   nw      NoWeb                  N  ""        "%%"    "document"
 \Format dot        dot    "Graphviz Dot"          "" ""        "%%"    "vector"
 \Format platex     tex    "LaTeX (pLaTeX)"        "" "" "%%"    "document"
 \Format literate   nw      NoWeb                  N  ""        "%%"    "document"
+\Format sweave     Rnw    "Sweave"                S  "" "%%"    "document"
 \Format lilypond   ly     "LilyPond music"        "" ""        "%%"    "vector"
 \Format latex      tex    "LaTeX (plain)"         L  ""        "%%"    "document"
 \Format pdflatex   tex    "LaTeX (pdflatex)"      "" ""        "%%"    "document"
 \Format lilypond   ly     "LilyPond music"        "" ""        "%%"    "vector"
 \Format latex      tex    "LaTeX (plain)"         L  ""        "%%"    "document"
 \Format pdflatex   tex    "LaTeX (pdflatex)"      "" ""        "%%"    "document"
@@ -298,7 +515,12 @@ def checkFormatEntries(dtl_tools):
 \Format text4      txt    "Plain text (catdvi)"   "" ""        "%%"    "document"
 \Format textparagraph txt "Plain Text, Join Lines" "" ""       "%%"    "document"''' ])
  #
 \Format text4      txt    "Plain text (catdvi)"   "" ""        "%%"    "document"
 \Format textparagraph txt "Plain Text, Join Lines" "" ""       "%%"    "document"''' ])
  #
-    checkViewer('a BibTeX editor', ['sensible-editor', 'jabref', 'JabRef', \
+    path, xhtmlview = checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
+        rc_entry = [r'\Format xhtml      xhtml   "LyXHTML"              X "%%" ""    "document"'])
+    if xhtmlview == "":
+        addToRC(r'\Format xhtml      xhtml   "LyXHTML"              X "" ""  "document"')
+ #
+    checkEditor('a BibTeX editor', ['sensible-editor', 'jabref', 'JabRef', \
         'pybliographic', 'bibdesk', 'gbib', 'kbib', \
         'kbibtex', 'sixpack', 'bibedit', 'tkbibtex' \
         'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
         'pybliographic', 'bibdesk', 'gbib', 'kbib', \
         'kbibtex', 'sixpack', 'bibedit', 'tkbibtex' \
         'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
@@ -310,7 +532,7 @@ def checkFormatEntries(dtl_tools):
     checkViewer('a Postscript previewer', ['kghostview', 'okular', 'evince', 'gv', 'ghostview -swap'],
         rc_entry = [r'''\Format eps        eps     EPS                    "" "%%"      ""      "vector"
 \Format ps         ps      Postscript             t  "%%"      ""      "document,vector"'''])
     checkViewer('a Postscript previewer', ['kghostview', 'okular', 'evince', 'gv', 'ghostview -swap'],
         rc_entry = [r'''\Format eps        eps     EPS                    "" "%%"      ""      "vector"
 \Format ps         ps      Postscript             t  "%%"      ""      "document,vector"'''])
-    #
+    # for xdg-open issues look here: http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg151818.html
     checkViewer('a PDF previewer', ['kpdf', 'okular', 'evince', 'kghostview', 'xpdf', 'acrobat', 'acroread', \
                    'gv', 'ghostview'],
         rc_entry = [r'''\Format pdf        pdf    "PDF (ps2pdf)"          P  "%%"      ""      "document,vector"
     checkViewer('a PDF previewer', ['kpdf', 'okular', 'evince', 'kghostview', 'xpdf', 'acrobat', 'acroread', \
                    'gv', 'ghostview'],
         rc_entry = [r'''\Format pdf        pdf    "PDF (ps2pdf)"          P  "%%"      ""      "document,vector"
@@ -318,7 +540,7 @@ def checkFormatEntries(dtl_tools):
 \Format pdf3       pdf    "PDF (dvipdfm)"         m  "%%"      ""      "document,vector"
 \Format pdf4       pdf    "PDF (XeTeX)"           X  "%%"      ""      "document,vector"'''])
     #
 \Format pdf3       pdf    "PDF (dvipdfm)"         m  "%%"      ""      "document,vector"
 \Format pdf4       pdf    "PDF (XeTeX)"           X  "%%"      ""      "document,vector"'''])
     #
-    checkViewer('a DVI previewer', ['xdvi', 'kdvi', 'okular'],
+    checkViewer('a DVI previewer', ['xdvi', 'kdvi', 'okular', 'yap', 'dviout -Set=!m'],
         rc_entry = [r'\Format dvi        dvi     DVI                    D  "%%"        ""      "document,vector"'])
     if dtl_tools:
         # Windows only: DraftDVI
         rc_entry = [r'\Format dvi        dvi     DVI                    D  "%%"        ""      "document,vector"'])
     if dtl_tools:
         # Windows only: DraftDVI
@@ -327,11 +549,16 @@ def checkFormatEntries(dtl_tools):
     checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
         rc_entry = [r'\Format html       html    HTML                   H  "%%"        ""      "document"'])
     #
     checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
         rc_entry = [r'\Format html       html    HTML                   H  "%%"        ""      "document"'])
     #
-    checkViewer('Noteedit', ['noteedit'],
+    checkViewerEditor('Noteedit', ['noteedit'],
         rc_entry = [r'\Format noteedit   not     Noteedit               "" "%%"        "%%"    "vector"'])
     #
         rc_entry = [r'\Format noteedit   not     Noteedit               "" "%%"        "%%"    "vector"'])
     #
-    checkViewer('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"          "" ""        ""      ""
@@ -350,12 +577,9 @@ def checkFormatEntries(dtl_tools):
 \Format pdftex     pdftex_t PDFTEX                "" ""        ""      ""
 \Format program    ""      Program                "" ""        ""      ""
 \Format pstex      pstex_t PSTEX                  "" ""        ""      ""
 \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"
 ''')
 
 
 ''')
 
 
@@ -386,6 +610,10 @@ def checkConverterEntries():
     checkProg('a Noweb -> LaTeX converter', ['noweave -delay -index $$i > $$o'],
         rc_entry = [r'''\converter literate   latex      "%%"  ""
 \converter literate   pdflatex      "%%"       ""'''])
     checkProg('a Noweb -> LaTeX converter', ['noweave -delay -index $$i > $$o'],
         rc_entry = [r'''\converter literate   latex      "%%"  ""
 \converter literate   pdflatex      "%%"       ""'''])
+    #
+    checkProg('a Sweave -> LaTeX converter', ['R CMD Sweave $$i'],
+        rc_entry = [r'''\converter sweave   latex      "%%"    ""
+\converter sweave   pdflatex      "%%" ""'''])
     #
     checkProg('an HTML -> LaTeX converter', ['html2latex $$i', 'gnuhtml2latex $$i', \
         'htmltolatex -input $$i -output $$o', 'java -jar htmltolatex.jar -input $$i -output $$o'],
     #
     checkProg('an HTML -> LaTeX converter', ['html2latex $$i', 'gnuhtml2latex $$i', \
         'htmltolatex -input $$i -output $$o', 'java -jar htmltolatex.jar -input $$i -output $$o'],
@@ -393,20 +621,35 @@ 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      "%%"   ""' ])
-    # On SuSE the scripts have a .sh suffix, and on debian they are in /usr/share/tex4ht/
-    path, htmlconv = checkProg('a LaTeX -> HTML converter', ['htlatex $$i', 'htlatex.sh $$i', \
-        '/usr/share/tex4ht/htlatex $$i', 'tth  -t -e2 -L$$b < $$i > $$o', \
-        'latex2html -no_subdir -split 0 -show_section_numbers $$i', 'hevea -s $$i'],
-        rc_entry = [ r'\converter latex      html       "%%"   "needaux"' ])
-    if htmlconv.find('htlatex') >= 0 or htmlconv == 'latex2html':
-      addToRC(r'''\copier    html       "python -tt $$s/scripts/ext_copy.py -e html,png,css $$i $$o"''')
+    # eLyXer: search as a Python module and then as an executable (elyxer.py, elyxer)
+    elyxerfound = checkModule('elyxer')
+    if elyxerfound:
+      addToRC(r'''\converter lyx      html       "python -m elyxer --directory $$r $$i $$o"    ""''')
     else:
     else:
-      addToRC(r'''\copier    html       "python -tt $$s/scripts/ext_copy.py $$i $$o"''')
+      path, elyxer = checkProg('a LyX -> HTML converter',
+        ['elyxer.py --directory $$r $$i $$o', 'elyxer --directory $$r $$i $$o'],
+        rc_entry = [ r'\converter lyx      html       "%%"     ""' ])
+      if elyxer.find('elyxer') >= 0:
+        elyxerfound = True
+
+    if elyxerfound:
+      addToRC(r'''\copier    html       "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 -> HTML converter', ['htlatex $$i', 'htlatex.sh $$i', \
+          '/usr/share/tex4ht/htlatex $$i', 'tth  -t -e2 -L$$b < $$i > $$o', \
+          'latex2html -no_subdir -split 0 -show_section_numbers $$i', 'hevea -s $$i'],
+          rc_entry = [ r'\converter latex      html       "%%" "needaux"' ])
+      if htmlconv.find('htlatex') >= 0 or htmlconv == 'latex2html':
+        addToRC(r'''\copier    html       "python -tt $$s/scripts/ext_copy.py -e html,png,css $$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'", \
 
     # 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'"],
+        "/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"''')
         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"''')
@@ -466,7 +709,7 @@ def checkConverterEntries():
     else:
         addToRC(r'\converter lyxpreview png        ""  ""')
     #  
     else:
         addToRC(r'\converter lyxpreview png        ""  ""')
     #  
-    checkProg('a fax program', ['kdeprintfax $$i', 'ksendfax $$i'],
+    checkProg('a fax program', ['kdeprintfax $$i', 'ksendfax $$i', 'hylapex $$i'],
         rc_entry = [ r'\converter ps         fax        "%%"   ""'])
     #
     checkProg('a FIG -> EPS/PPM converter', ['fig2dev'],
         rc_entry = [ r'\converter ps         fax        "%%"   ""'])
     #
     checkProg('a FIG -> EPS/PPM converter', ['fig2dev'],
@@ -516,6 +759,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', 'inkscape --file=$$p/$$i --export-area-drawing --without-gui --export-pdf=$$p/$$o'],
+        rc_entry = [ r'\converter svg        pdf        "%%"   ""'])
+    #
+    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        "%%"   ""'])
+    # 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        "%%"   ""'])
+    
     #
     path, lilypond = checkProg('a LilyPond -> EPS/PDF/PNG converter', ['lilypond'])
     if (lilypond != ''):
     #
     path, lilypond = checkProg('a LilyPond -> EPS/PDF/PNG converter', ['lilypond'])
     if (lilypond != ''):
@@ -591,16 +843,21 @@ def checkOtherEntries():
     ''' entries other than Format and Converter '''
     checkProg('ChkTeX', ['chktex -n1 -n3 -n6 -n9 -n22 -n25 -n30 -n38'],
         rc_entry = [ r'\chktex_command "%%"' ])
     ''' entries other than Format and Converter '''
     checkProg('ChkTeX', ['chktex -n1 -n3 -n6 -n9 -n22 -n25 -n30 -n38'],
         rc_entry = [ r'\chktex_command "%%"' ])
-    checkProg('BibTeX', ['bibtex'],
-        rc_entry = [ r'\bibtex_command "%%"' ])
+    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'],
         rc_entry = [ r'\jbibtex_command "%%"' ])
     checkProg('JBibTeX, the Japanese BibTeX', ['jbibtex', 'bibtex'],
         rc_entry = [ r'\jbibtex_command "%%"' ])
-    checkProg('an index processor', ['texindy', 'makeindex -c -q'],
-        rc_entry = [ r'\index_command "%%"' ])
-    checkProg('an index processor appropriate to Japanese', ['mendex -c -q', 'makeindex -c -q'],
+    checkProgAlternatives('available index processors', ['texindy', 'makeindex -c -q'],
+        rc_entry = [ r'\index_command "%%"' ],
+        alt_rc_entry = [ r'\index_alternatives "%%"' ])
+    checkProg('an index processor appropriate to Japanese', ['mendex -c -q', 'jmakeindex -c -q', 'makeindex -c -q'],
         rc_entry = [ r'\jindex_command "%%"' ])
         rc_entry = [ r'\jindex_command "%%"' ])
-    checkProg('the splitindex processor', ['splitindex.pl', 'java splitindex', 'splitindex'],
+    path, splitindex = checkProg('the splitindex processor', ['splitindex.pl', 'splitindex'],
         rc_entry = [ r'\splitindex_command "%%"' ])
         rc_entry = [ r'\splitindex_command "%%"' ])
+    if splitindex == '':
+        checkProg('the splitindex processor (java version)', ['splitindex.class'],
+            rc_entry = [ r'\splitindex_command "java splitindex"' ])
     checkProg('a nomenclature processor', ['makeindex'],
         rc_entry = [ r'\nomencl_command "makeindex -s nomencl.ist"' ])
     ## FIXME: OCTAVE is not used anywhere
     checkProg('a nomenclature processor', ['makeindex'],
         rc_entry = [ r'\nomencl_command "makeindex -s nomencl.ist"' ])
     ## FIXME: OCTAVE is not used anywhere
@@ -699,75 +956,74 @@ 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
+    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):
+            continue
+        classname = file.split(os.sep)[-1].split('.')[0]
+        for line in open(file).readlines():
+            if p1.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
+            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
 
 
 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')
@@ -775,6 +1031,7 @@ def checkModulesConfig():
 ## It has been automatically generated by configure
 ## Use "Options/Reconfigure" if you need to update it after a
 ## configuration change. 
 ## 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"
 ''')
   # build the list of available modules
   foundClasses = []
 ''')
   # build the list of available modules
   foundClasses = []
@@ -796,22 +1053,24 @@ def processModuleFile(file, bool_docbook):
 
         The top of a module file should look like this:
           #\DeclareLyXModule[LaTeX Packages]{ModuleName}
 
         The top of a module file should look like this:
           #\DeclareLyXModule[LaTeX Packages]{ModuleName}
-          #BeginDescription
+          #DescriptionBegin
           #...body of description...
           #...body of description...
-          #EndDescription
+          #DescriptionEnd
           #Requires: [list of required modules]
           #Excludes: [list of excluded modules]
           #Requires: [list of required modules]
           #Excludes: [list of excluded modules]
-        The last two lines are optional
+          #Category: [category name]
+        The last three lines are optional (though do give a category).
         We expect output:
         We expect output:
-          "ModuleName" "filename" "Description" "Packages" "Requires" "Excludes"
+          "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: (.*)')
     '''
     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*$')
 
     b = re.compile(r'#+\s*DescriptionBegin\s*$')
     e = re.compile(r'#+\s*DescriptionEnd\s*$')
 
-    modname = desc = pkgs = req = excl = ""
+    modname = desc = pkgs = req = excl = catgy = ""
     readingDescription = False
     descLines = []
     filename = file.split(os.sep)[-1]
     readingDescription = False
     descLines = []
     filename = file.split(os.sep)[-1]
@@ -851,8 +1110,28 @@ def processModuleFile(file, bool_docbook):
         tmp = [s.strip() for s in excl.split("|")]
         excl = "|".join(tmp)
         continue
         tmp = [s.strip() for s in excl.split("|")]
         excl = "|".join(tmp)
         continue
+      res = c.search(line)
+      if res != None:
+        catgy = res.group(1)
+        continue
     if modname != "":
     if modname != "":
-        return '"%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, desc, pkgs, req, excl)
+        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)
     logger.warning("Module file without \DeclareLyXModule line. ")
     return ""
 
     logger.warning("Module file without \DeclareLyXModule line. ")
     return ""
 
@@ -882,7 +1161,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'])
 
 
@@ -941,9 +1220,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