Use libmagic for file format detection if available.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40789 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2012-02-21 20:29:44 +00:00
parent 9f58d50944
commit 26e5f1a8ec
16 changed files with 370 additions and 140 deletions

View File

@ -68,7 +68,10 @@ into the tarball.
New external programs and libraries: New external programs and libraries:
------------------------------------ ------------------------------------
- - LyX links now against libmagic (http://www.darwinsys.com/file/) if it is
available at compile time. This improves the file format detection of
included graphics and other files. The old builtin format detection code
is used if libmagic is not available.
Known issues in version 2.1.0 Known issues in version 2.1.0

View File

@ -115,6 +115,16 @@ AC_CHECK_HEADERS(zlib.h,
[AC_CHECK_LIB(z, gzopen, [LIBS="$LIBS -lz"], LYX_LIB_ERROR(libz,zlib))], [AC_CHECK_LIB(z, gzopen, [LIBS="$LIBS -lz"], LYX_LIB_ERROR(libz,zlib))],
[LYX_LIB_ERROR(zlib.h,zlib)]) [LYX_LIB_ERROR(zlib.h,zlib)])
### check for file magic support (currently optional)
AC_CHECK_HEADERS(magic.h,
[AC_CHECK_LIB(magic, magic_open, [LIBS="$LIBS -lmagic"],
LYX_WARNING([Cannot find limagic. Please check that the libmagic library
is correctly installed on your system.
Falling back to builtin file format detection.]))],
[LYX_WARNING([Cannot find magic.h. Please check that the libmagic library
is correctly installed on your system.
Falling back to builtin file format detection.])])
### check which frontend we want to use ### check which frontend we want to use

View File

@ -480,36 +480,36 @@ def checkModule(module):
def checkFormatEntries(dtl_tools): def checkFormatEntries(dtl_tools):
''' Check all formats (\Format entries) ''' ''' Check all formats (\Format entries) '''
checkViewerEditor('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, tgo" Tgif "" "%%" "%%" "vector" "application/x-tgif"'])
# #
checkViewerEditor('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" "application/x-xfig"'])
# #
checkViewerEditor('a Dia viewer and editor', ['dia'], checkViewerEditor('a Dia viewer and editor', ['dia'],
rc_entry = [r'\Format dia dia DIA "" "%%" "%%" "vector,zipped=native"']) rc_entry = [r'\Format dia dia DIA "" "%%" "%%" "vector,zipped=native", "application/x-dia-diagram"'])
# #
checkViewerEditor('an OpenOffice drawing viewer and editor', ['libreoffice', 'lodraw', 'ooffice', 'oodraw', 'soffice'], checkViewerEditor('an OpenOffice drawing viewer and editor', ['libreoffice', 'lodraw', 'ooffice', 'oodraw', 'soffice'],
rc_entry = [r'\Format odg "odg, sxd" "OpenOffice drawing" "" "%%" "%%" "vector,zipped=native"']) rc_entry = [r'\Format odg "odg, sxd" "OpenOffice drawing" "" "%%" "%%" "vector,zipped=native" "application/vnd.oasis.opendocument.graphics"'])
# #
checkViewerEditor('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" ""'])
# #
checkViewerEditor('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 "" "%%" "%%" "" ""'])
# #
checkViewerEditor('a SVG viewer and editor', ['inkscape'], checkViewerEditor('a SVG viewer and editor', ['inkscape'],
rc_entry = [r'\Format svg svg SVG "" "%%" "%%" "vector"']) rc_entry = [r'\Format svg svg SVG "" "%%" "%%" "vector" "image/svg+xml"'])
# #
imageformats = r'''\Format bmp bmp BMP "" "%s" "%s" "" imageformats = r'''\Format bmp bmp BMP "" "%s" "%s" "" "image/x-bmp"
\Format gif gif GIF "" "%s" "%s" "" \Format gif gif GIF "" "%s" "%s" "" "image/gif"
\Format jpg "jpg, jpeg" JPEG "" "%s" "%s" "" \Format jpg "jpg, jpeg" JPEG "" "%s" "%s" "" "image/jpeg"
\Format pbm pbm PBM "" "%s" "%s" "" \Format pbm pbm PBM "" "%s" "%s" "" "image/x-portable-bitmap"
\Format pgm pgm PGM "" "%s" "%s" "" \Format pgm pgm PGM "" "%s" "%s" "" "image/x-portable-graymap"
\Format png png PNG "" "%s" "%s" "" \Format png png PNG "" "%s" "%s" "" "image/x-png"
\Format ppm ppm PPM "" "%s" "%s" "" \Format ppm ppm PPM "" "%s" "%s" "" "image/x-portable-pixmap"
\Format tiff tif TIFF "" "%s" "%s" "" \Format tiff tif TIFF "" "%s" "%s" "" "image/tiff"
\Format xbm xbm XBM "" "%s" "%s" "" \Format xbm xbm XBM "" "%s" "%s" "" "image/x-xbitmap"
\Format xpm xpm XPM "" "%s" "%s" ""''' \Format xpm xpm XPM "" "%s" "%s" "" "image/x-xpixmap"'''
path, iv = checkViewerNoRC('a raster image viewer', ['xv', 'kview', 'gimp-remote', 'gimp'], rc_entry = [imageformats]) path, iv = checkViewerNoRC('a raster image viewer', ['xv', 'kview', 'gimp-remote', 'gimp'], rc_entry = [imageformats])
path, ie = checkEditorNoRC('a raster image editor', ['gimp-remote', 'gimp'], rc_entry = [imageformats]) path, ie = checkEditorNoRC('a raster image editor', ['gimp-remote', 'gimp'], rc_entry = [imageformats])
addToRC(imageformats % \ addToRC(imageformats % \
@ -517,102 +517,102 @@ def checkFormatEntries(dtl_tools):
# #
checkViewerEditor('a text editor', ['xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \ checkViewerEditor('a text editor', ['xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
'nedit', 'gedit', 'notepad'], 'nedit', 'gedit', 'notepad'],
rc_entry = [r'''\Format asciichess asc "Plain text (chess output)" "" "" "%%" "" rc_entry = [r'''\Format asciichess asc "Plain text (chess output)" "" "" "%%" "" ""
\Format asciiimage asc "Plain text (image)" "" "" "%%" "" \Format asciiimage asc "Plain text (image)" "" "" "%%" "" ""
\Format asciixfig asc "Plain text (Xfig output)" "" "" "%%" "" \Format asciixfig asc "Plain text (Xfig output)" "" "" "%%" "" ""
\Format dateout tmp "date (output)" "" "" "%%" "" \Format dateout tmp "date (output)" "" "" "%%" "" ""
\Format docbook sgml DocBook B "" "%%" "document,menu=export" \Format docbook sgml DocBook B "" "%%" "document,menu=export" ""
\Format docbook-xml xml "DocBook (XML)" "" "" "%%" "document,menu=export" \Format docbook-xml xml "DocBook (XML)" "" "" "%%" "document,menu=export" "application/docbook+xml"
\Format dot dot "Graphviz Dot" "" "" "%%" "vector" \Format dot dot "Graphviz Dot" "" "" "%%" "vector" "text/vnd.graphviz"
\Format dviluatex tex "LaTeX (dviluatex)" "" "" "%%" "document,menu=export" \Format dviluatex tex "LaTeX (dviluatex)" "" "" "%%" "document,menu=export" ""
\Format platex tex "LaTeX (pLaTeX)" "" "" "%%" "document,menu=export" \Format platex tex "LaTeX (pLaTeX)" "" "" "%%" "document,menu=export" ""
\Format literate nw NoWeb N "" "%%" "document,menu=export" \Format literate nw NoWeb N "" "%%" "document,menu=export" ""
\Format sweave Rnw "Sweave" S "" "%%" "document,menu=export" \Format sweave Rnw "Sweave" S "" "%%" "document,menu=export" ""
\Format r R "R/S code" "" "" "%%" "document,menu=export" \Format r R "R/S code" "" "" "%%" "document,menu=export" ""
\Format knitr Rnw "Rnw (knitr)" "" "" "%%" "document,menu=export" \Format knitr Rnw "Rnw (knitr)" "" "" "%%" "document,menu=export" ""
\Format lilypond ly "LilyPond music" "" "" "%%" "vector" \Format lilypond ly "LilyPond music" "" "" "%%" "vector" "text/x-lilypond"
\Format lilypond-book lytex "LilyPond book (LaTeX)" "" "" "%%" "document,menu=export" \Format lilypond-book lytex "LilyPond book (LaTeX)" "" "" "%%" "document,menu=export" ""
\Format latex tex "LaTeX (plain)" L "" "%%" "document,menu=export" \Format latex tex "LaTeX (plain)" L "" "%%" "document,menu=export" "text/x-tex"
\Format luatex tex "LaTeX (LuaTeX)" "" "" "%%" "document,menu=export" \Format luatex tex "LaTeX (LuaTeX)" "" "" "%%" "document,menu=export" ""
\Format pdflatex tex "LaTeX (pdflatex)" "" "" "%%" "document,menu=export" \Format pdflatex tex "LaTeX (pdflatex)" "" "" "%%" "document,menu=export" ""
\Format xetex tex "LaTeX (XeTeX)" "" "" "%%" "document,menu=export" \Format xetex tex "LaTeX (XeTeX)" "" "" "%%" "document,menu=export" ""
\Format text txt "Plain text" a "" "%%" "document,menu=export" \Format text txt "Plain text" a "" "%%" "document,menu=export" "text/plain"
\Format text2 txt "Plain text (pstotext)" "" "" "%%" "document" \Format text2 txt "Plain text (pstotext)" "" "" "%%" "document" ""
\Format text3 txt "Plain text (ps2ascii)" "" "" "%%" "document" \Format text3 txt "Plain text (ps2ascii)" "" "" "%%" "document" ""
\Format text4 txt "Plain text (catdvi)" "" "" "%%" "document" \Format text4 txt "Plain text (catdvi)" "" "" "%%" "document" ""
\Format textparagraph txt "Plain Text, Join Lines" "" "" "%%" "document"''' ]) \Format textparagraph txt "Plain Text, Join Lines" "" "" "%%" "document" ""''' ])
#Spreadsheets using ssconvert from gnumeric #Spreadsheets using ssconvert from gnumeric
checkViewer('gnumeric spreadsheet software', ['gnumeric'], checkViewer('gnumeric spreadsheet software', ['gnumeric'],
rc_entry = [r'''\Format gnumeric gnumeric "Gnumeric spreadsheet" "" "" "%%" "document" rc_entry = [r'''\Format gnumeric gnumeric "Gnumeric spreadsheet" "" "" "%%" "document" "application/x-gnumeric"
\Format excel xls "Excel spreadsheet" "" "" "%%" "document" \Format excel xls "Excel spreadsheet" "" "" "%%" "document" "application/vnd.ms-excel"
\Format oocalc ods "OpenOffice spreadsheet" "" "" "%%" "document"''']) \Format oocalc ods "OpenOffice spreadsheet" "" "" "%%" "document" "application/vnd.oasis.opendocument.spreadsheet"'''])
# #
checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'], checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
rc_entry = [r'\Format xhtml xhtml "LyXHTML" y "%%" "" "document,menu=export"']) rc_entry = [r'\Format xhtml xhtml "LyXHTML" y "%%" "" "document,menu=export" "application/xhtml+xml"'])
# #
checkEditor('a BibTeX editor', ['jabref', 'JabRef', \ checkEditor('a BibTeX editor', ['jabref', 'JabRef', \
'pybliographic', 'bibdesk', 'gbib', 'kbib', \ 'pybliographic', 'bibdesk', 'gbib', 'kbib', \
'kbibtex', 'sixpack', 'bibedit', 'tkbibtex' \ 'kbibtex', 'sixpack', 'bibedit', 'tkbibtex' \
'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \ 'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
'nedit', 'gedit', 'notepad'], 'nedit', 'gedit', 'notepad'],
rc_entry = [r'''\Format bibtex bib "BibTeX" "" "" "%%" ""''' ]) rc_entry = [r'''\Format bibtex bib "BibTeX" "" "" "%%" "" "text/x-bibtex"''' ])
# #
#checkProg('a Postscript interpreter', ['gs'], #checkProg('a Postscript interpreter', ['gs'],
# rc_entry = [ r'\ps_command "%%"' ]) # rc_entry = [ r'\ps_command "%%"' ])
checkViewer('a Postscript previewer', ['kghostview', 'okular', 'evince', 'gv', 'ghostview -swap'], checkViewer('a Postscript previewer', ['kghostview', 'okular', 'evince', 'gv', 'ghostview -swap'],
rc_entry = [r'''\Format eps eps EPS "" "%%" "" "vector" rc_entry = [r'''\Format eps eps EPS "" "%%" "" "vector" "image/x-eps"
\Format eps2 eps "EPS (uncropped)" "" "%%" "" "vector" \Format eps2 eps "EPS (uncropped)" "" "%%" "" "vector" ""
\Format ps ps Postscript t "%%" "" "document,vector,menu=export"''']) \Format ps ps Postscript t "%%" "" "document,vector,menu=export" "application/postscript"'''])
# for xdg-open issues look here: http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg151818.html # 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', \ checkViewer('a PDF previewer', ['kpdf', 'okular', 'evince', 'kghostview', 'xpdf', 'acrobat', 'acroread', \
'gv', 'ghostview'], 'gv', 'ghostview'],
rc_entry = [r'''\Format pdf pdf "PDF (ps2pdf)" P "%%" "" "document,vector,menu=export" rc_entry = [r'''\Format pdf pdf "PDF (ps2pdf)" P "%%" "" "document,vector,menu=export" "application/pdf"
\Format pdf2 pdf "PDF (pdflatex)" F "%%" "" "document,vector,menu=export" \Format pdf2 pdf "PDF (pdflatex)" F "%%" "" "document,vector,menu=export" ""
\Format pdf3 pdf "PDF (dvipdfm)" m "%%" "" "document,vector,menu=export" \Format pdf3 pdf "PDF (dvipdfm)" m "%%" "" "document,vector,menu=export" ""
\Format pdf4 pdf "PDF (XeTeX)" X "%%" "" "document,vector,menu=export" \Format pdf4 pdf "PDF (XeTeX)" X "%%" "" "document,vector,menu=export" ""
\Format pdf5 pdf "PDF (LuaTeX)" u "%%" "" "document,vector,menu=export"''']) \Format pdf5 pdf "PDF (LuaTeX)" u "%%" "" "document,vector,menu=export" ""'''])
# #
checkViewer('a DVI previewer', ['xdvi', 'kdvi', 'okular', 'yap', 'dviout -Set=!m'], checkViewer('a DVI previewer', ['xdvi', 'kdvi', 'okular', 'yap', 'dviout -Set=!m'],
rc_entry = [r'''\Format dvi dvi DVI D "%%" "" "document,vector,menu=export" rc_entry = [r'''\Format dvi dvi DVI D "%%" "" "document,vector,menu=export" "application/x-dvi"
\Format dvi3 dvi "DVI (LuaTeX)" V "%%" "" "document,vector,menu=export"''']) \Format dvi3 dvi "DVI (LuaTeX)" V "%%" "" "document,vector,menu=export" ""'''])
if dtl_tools: if dtl_tools:
# Windows only: DraftDVI # Windows only: DraftDVI
addToRC(r'\Format dvi2 dvi DraftDVI "" "" "" "vector"') addToRC(r'\Format dvi2 dvi DraftDVI "" "" "" "vector" ""')
# #
checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'], checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
rc_entry = [r'\Format html "html, htm" HTML H "%%" "" "document,menu=export"']) rc_entry = [r'\Format html "html, htm" HTML H "%%" "" "document,menu=export" "text/html"'])
# #
checkViewerEditor('Noteedit', ['noteedit'], checkViewerEditor('Noteedit', ['noteedit'],
rc_entry = [r'\Format noteedit not Noteedit "" "%%" "%%" "vector"']) rc_entry = [r'\Format noteedit not Noteedit "" "%%" "%%" "vector" ""'])
# #
checkViewerEditor('an OpenDocument/OpenOffice viewer', ['libreoffice', 'lwriter', 'swriter', 'oowriter', 'abiword'], checkViewerEditor('an OpenDocument/OpenOffice viewer', ['libreoffice', 'lwriter', 'swriter', 'oowriter', 'abiword'],
rc_entry = [r'''\Format odt odt OpenDocument "" "%%" "%%" "document,vector,menu=export" rc_entry = [r'''\Format odt odt OpenDocument "" "%%" "%%" "document,vector,menu=export" "application/vnd.oasis.opendocument.text"
\Format sxw sxw "OpenOffice.Org (sxw)" "" "" "" "document,vector"''']) \Format sxw sxw "OpenOffice.Org (sxw)" "" "" "" "document,vector" "application/vnd.sun.xml.writer"'''])
# #
checkViewerEditor('a Rich Text and Word viewer', ['libreoffice', 'lwriter', 'swriter', 'oowriter', 'abiword'], checkViewerEditor('a Rich Text and Word viewer', ['libreoffice', 'lwriter', 'swriter', 'oowriter', 'abiword'],
rc_entry = [r'''\Format rtf rtf "Rich Text Format" "" "%%" "%%" "document,vector,menu=export" rc_entry = [r'''\Format rtf rtf "Rich Text Format" "" "%%" "%%" "document,vector,menu=export" "application/rtf"
\Format word doc "MS Word" W "%%" "%%" "document,vector,menu=export"''']) \Format word doc "MS Word" W "%%" "%%" "document,vector,menu=export" "application/msword"'''])
# #
# entries that do not need checkProg # entries that do not need checkProg
addToRC(r'''\Format date "" "date command" "" "" "" "" addToRC(r'''\Format date "" "date command" "" "" "" "" ""
\Format csv csv "Table (CSV)" "" "" "" "document" \Format csv csv "Table (CSV)" "" "" "" "document" "text/csv"
\Format fax "" Fax "" "" "" "document" \Format fax "" Fax "" "" "" "document" ""
\Format lyx lyx LyX "" "" "" "" \Format lyx lyx LyX "" "" "" "" "application/x-lyx"
\Format lyx13x 13.lyx "LyX 1.3.x" "" "" "" "document" \Format lyx13x 13.lyx "LyX 1.3.x" "" "" "" "document" ""
\Format lyx14x 14.lyx "LyX 1.4.x" "" "" "" "document" \Format lyx14x 14.lyx "LyX 1.4.x" "" "" "" "document" ""
\Format lyx15x 15.lyx "LyX 1.5.x" "" "" "" "document" \Format lyx15x 15.lyx "LyX 1.5.x" "" "" "" "document" ""
\Format lyx16x 16.lyx "LyX 1.6.x" "" "" "" "document,menu=export" \Format lyx16x 16.lyx "LyX 1.6.x" "" "" "" "document,menu=export" ""
\Format lyx20x 20.lyx "LyX 2.0.x" "" "" "" "document,menu=export" \Format lyx20x 20.lyx "LyX 2.0.x" "" "" "" "document,menu=export" ""
\Format clyx cjklyx "CJK LyX 1.4.x (big5)" "" "" "" "document" \Format clyx cjklyx "CJK LyX 1.4.x (big5)" "" "" "" "document" ""
\Format jlyx cjklyx "CJK LyX 1.4.x (euc-jp)" "" "" "" "document" \Format jlyx cjklyx "CJK LyX 1.4.x (euc-jp)" "" "" "" "document" ""
\Format klyx cjklyx "CJK LyX 1.4.x (euc-kr)" "" "" "" "document" \Format klyx cjklyx "CJK LyX 1.4.x (euc-kr)" "" "" "" "document" ""
\Format lyxpreview lyxpreview "LyX Preview" "" "" "" "" \Format lyxpreview lyxpreview "LyX Preview" "" "" "" "" ""
\Format pdftex pdftex_t PDFTEX "" "" "" "" \Format pdftex pdftex_t PDFTEX "" "" "" "" ""
\Format program "" Program "" "" "" "" \Format program "" Program "" "" "" "" ""
\Format pstex pstex_t PSTEX "" "" "" "" \Format pstex pstex_t PSTEX "" "" "" "" ""
\Format wmf wmf "Windows Metafile" "" "" "" "vector" \Format wmf wmf "Windows Metafile" "" "" "" "vector" "image/x-wmf"
\Format emf emf "Enhanced Metafile" "" "" "" "vector" \Format emf emf "Enhanced Metafile" "" "" "" "vector" "image/x-emf"
\Format wordhtml "html, htm" "HTML (MS Word)" "" "" "" "document" \Format wordhtml "html, htm" "HTML (MS Word)" "" "" "" "document" ""
''') ''')
@ -903,10 +903,10 @@ def checkConverterEntries():
# So, we configure the appropriate version according to the platform. # So, we configure the appropriate version according to the platform.
cmd = r'\converter lyx %s "python -tt $$s/scripts/lyxpak.py $$r/$$f" ""' cmd = r'\converter lyx %s "python -tt $$s/scripts/lyxpak.py $$r/$$f" ""'
if os.name == 'nt': if os.name == 'nt':
addToRC(r'\Format lyxzip zip "LyX Archive (zip)" "" "" "" "document,menu=export"') addToRC(r'\Format lyxzip zip "LyX Archive (zip)" "" "" "" "document,menu=export" ""')
addToRC(cmd % "lyxzip") addToRC(cmd % "lyxzip")
else: else:
addToRC(r'\Format lyxgz gz "LyX Archive (tar.gz)" "" "" "" "document,menu=export"') addToRC(r'\Format lyxgz gz "LyX Archive (tar.gz)" "" "" "" "document,menu=export" ""')
addToRC(cmd % "lyxgz") addToRC(cmd % "lyxgz")
# #
@ -1315,7 +1315,7 @@ def removeTempFiles():
if __name__ == '__main__': if __name__ == '__main__':
lyx_check_config = True lyx_check_config = True
outfile = 'lyxrc.defaults' outfile = 'lyxrc.defaults'
lyxrc_fileformat = 3 lyxrc_fileformat = 7
rc_entries = '' rc_entries = ''
lyx_keep_temps = False lyx_keep_temps = False
version_suffix = '' version_suffix = ''

View File

@ -126,11 +126,12 @@ End
\papercolumns 1 \papercolumns 1
\papersides 2 \papersides 2
\paperpagestyle headings \paperpagestyle headings
\tracking_changes false \tracking_changes true
\output_changes false \output_changes false
\html_math_output 0 \html_math_output 0
\html_css_as_file 0 \html_css_as_file 0
\html_be_strict true \html_be_strict true
\author -195340706 "Georg Baum"
\end_header \end_header
\begin_body \begin_body
@ -1461,6 +1462,43 @@ Edit externally
in the appearing context menu. in the appearing context menu.
\end_layout \end_layout
\begin_layout Standard
\change_inserted -195340706 1329851811
The
\begin_inset Flex MenuItem
status collapsed
\begin_layout Plain Layout
MIME
\end_layout
\end_inset
type of a format is optional, but if it is specified, it must be unique
across all formats.
It is used to detect files of this format from the file contents.
For some important file formats there is no MIME type officially registered
with the
\begin_inset CommandInset href
LatexCommand href
name "IANA"
target "http://www.iana.org/assignments/media-types/"
\end_inset
.
Therefore LyX uses the extended list of MIME types as specified by
\begin_inset CommandInset href
LatexCommand href
name "freedesktop.org"
target "http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec"
\end_inset
.
\end_layout
\begin_layout Standard \begin_layout Standard
The The
\begin_inset Flex MenuItem \begin_inset Flex MenuItem

View File

@ -36,13 +36,41 @@
# Add use_qimage option. # Add use_qimage option.
# No conversion necessary. # No conversion necessary.
import re # Incremented to format 7, r40789 by gb
# Add mime type to file format
import re
########################################################### ###########################################################
# #
# Conversion chain # Conversion chain
def get_format(line):
entries = []
i = 0
while i < len(line):
if line[i] == '"':
beg = i + 1
i = i + 1
while i < len(line) and line[i] != '"':
if line[i] == '\\' and i < len(line) - 1 and line[i+1] == '"':
# convert \" to "
i = i + 1
i = i + 1
end = i
entries.append(line[beg:end].replace('\\"', '"'))
elif line[i] == '#':
return entries
elif not line[i].isspace():
beg = i
while not line[i].isspace():
i = i + 1
end = i
entries.append(line[beg:end])
i = i + 1
return entries
def simple_renaming(line, old, new): def simple_renaming(line, old, new):
i = line.lower().find(old.lower()) i = line.lower().find(old.lower())
if i == -1: if i == -1:
@ -135,6 +163,59 @@ def remove_default_papersize(line):
return no_match return no_match
return (True, "") return (True, "")
def add_mime_types(line):
if not line.lower().startswith("\\format"):
return no_match
entries = get_format(line)
converted = line
i = len(entries)
while i < 7:
converted = converted + ' ""'
i = i + 1
formats = {'tgif':'application/x-tgif', \
'fig':'application/x-xfig', \
'dia':'application/x-dia-diagram', \
'odg':'application/vnd.oasis.opendocument.graphics', \
'svg':'image/svg+xml', \
'bmp':'image/x-bmp', \
'gif':'image/gif', \
'jpg':'image/jpeg', \
'pbm':'image/x-portable-bitmap', \
'pgm':'image/x-portable-graymap', \
'png':'image/x-png', \
'ppm':'image/x-portable-pixmap', \
'tiff':'image/tiff', \
'xbm':'image/x-xbitmap', \
'xpm':'image/x-xpixmap', \
'docbook-xml':'application/docbook+xml', \
'dot':'text/vnd.graphviz', \
'ly':'text/x-lilypond', \
'latex':'text/x-tex', \
'text':'text/plain', \
'gnumeric':'application/x-gnumeric', \
'excel':'application/vnd.ms-excel', \
'oocalc':'application/vnd.oasis.opendocument.spreadsheet', \
'xhtml':'application/xhtml+xml', \
'bib':'text/x-bibtex', \
'eps':'image/x-eps', \
'ps':'application/postscript', \
'pdf':'application/pdf', \
'dvi':'application/x-dvi', \
'html':'text/html', \
'odt':'application/vnd.oasis.opendocument.text', \
'sxw':'application/vnd.sun.xml.writer', \
'rtf':'application/rtf', \
'doc':'application/msword', \
'csv':'text/csv', \
'lyx':'application/x-lyx', \
'wmf':'image/x-wmf', \
'emf':'image/x-emf'}
if entries[1] in formats.keys():
converted = converted + ' "' + formats[entries[1]] + '"'
else:
converted = converted + ' ""'
return (True, converted)
######################## ########################
@ -152,4 +233,5 @@ conversions = [
[ 4, [ remove_default_papersize ]], [ 4, [ remove_default_papersize ]],
[ 5, []], [ 5, []],
[ 6, []], [ 6, []],
[ 7, [add_mime_types]],
] ]

View File

@ -1002,7 +1002,7 @@ Buffer::ReadStatus Buffer::readFile(FileName const & fn)
d->file_fully_loaded = true; d->file_fully_loaded = true;
d->read_only = !d->filename.isWritable(); d->read_only = !d->filename.isWritable();
params().compressed = d->filename.isZippedFile(); params().compressed = formats.isZippedFile(d->filename);
saveCheckSum(); saveCheckSum();
return ReadSuccess; return ReadSuccess;
} }

View File

@ -37,6 +37,10 @@
#include "support/linkback/LinkBackProxy.h" #include "support/linkback/LinkBackProxy.h"
#endif #endif
#ifdef HAVE_MAGIC_H
#include <magic.h>
#endif
using namespace std; using namespace std;
using namespace lyx::support; using namespace lyx::support;
@ -78,6 +82,21 @@ private:
}; };
class FormatMimeEqual : public unary_function<Format, bool> {
public:
FormatMimeEqual(string const & mime)
: mime_(mime) {}
bool operator()(Format const & f) const
{
// The test for empty mime strings is needed since we allow
// formats with empty mime types.
return f.mime() == mime_ && !mime_.empty();
}
private:
string mime_;
};
class FormatPrettyNameEqual : public unary_function<Format, bool> { class FormatPrettyNameEqual : public unary_function<Format, bool> {
public: public:
FormatPrettyNameEqual(string const & prettyname) FormatPrettyNameEqual(string const & prettyname)
@ -101,9 +120,9 @@ bool operator<(Format const & a, Format const & b)
Format::Format(string const & n, string const & e, string const & p, Format::Format(string const & n, string const & e, string const & p,
string const & s, string const & v, string const & ed, string const & s, string const & v, string const & ed,
int flags) string const & m, int flags)
: name_(n), prettyname_(p), shortcut_(s), viewer_(v), : name_(n), prettyname_(p), shortcut_(s), viewer_(v),
editor_(ed), flags_(flags) editor_(ed), mime_(m), flags_(flags)
{ {
extension_list_ = getVectorFromString(e, ","); extension_list_ = getVectorFromString(e, ",");
LYXERR(Debug::GRAPHICS, "New Format: n=" << n << ", flags=" << flags); LYXERR(Debug::GRAPHICS, "New Format: n=" << n << ", flags=" << flags);
@ -168,10 +187,39 @@ string Formats::getFormatFromFile(FileName const & filename) const
if (filename.empty()) if (filename.empty())
return string(); return string();
#ifdef HAVE_MAGIC_H
magic_t magic_cookie = magic_open(MAGIC_MIME);
if (magic_cookie) {
string format;
if (magic_load(magic_cookie, NULL) != 0) {
LYXERR(Debug::GRAPHICS, "Formats::getFormatFromFile\n"
<< "\tCouldn't load magic database - "
<< magic_error(magic_cookie));
} else {
string mime = magic_file(magic_cookie,
filename.toFilesystemEncoding().c_str());
mime = token(mime, ';', 0);
// we need our own ps/eps detection
if (mime != "application/postscript") {
Formats::const_iterator cit =
find_if(formatlist.begin(), formatlist.end(),
FormatMimeEqual(mime));
if (cit != formats.end()) {
LYXERR(Debug::GRAPHICS, "\tgot format from MIME type: "
<< mime << " -> " << cit->name());
format = cit->name();
}
}
}
magic_close(magic_cookie);
if (!format.empty())
return format;
}
#endif
string const format = filename.guessFormatFromContents(); string const format = filename.guessFormatFromContents();
string const ext = getExtension(filename.absFileName()); string const ext = getExtension(filename.absFileName());
if ((format == "gzip" || format == "zip" || format == "compress") if (isZippedFileFormat(format) && !ext.empty()) {
&& !ext.empty()) {
string const & fmt_name = formats.getFormatFromExtension(ext); string const & fmt_name = formats.getFormatFromExtension(ext);
if (!fmt_name.empty()) { if (!fmt_name.empty()) {
Format const * p_format = formats.getFormat(fmt_name); Format const * p_format = formats.getFormat(fmt_name);
@ -244,6 +292,17 @@ bool Formats::isZippedFile(support::FileName const & filename) const {
} }
bool Formats::isZippedFileFormat(string const & format)
{
return contains("gzip zip compress", format) && !format.empty();
}
bool Formats::isPostScriptFileFormat(string const & format)
{
return format == "ps" || format == "eps";
}
static string fixCommand(string const & cmd, string const & ext, static string fixCommand(string const & cmd, string const & ext,
os::auto_open_mode mode) os::auto_open_mode mode)
{ {
@ -291,24 +350,24 @@ void Formats::add(string const & name)
{ {
if (!getFormat(name)) if (!getFormat(name))
add(name, name, name, string(), string(), string(), add(name, name, name, string(), string(), string(),
Format::document); string(), Format::document);
} }
void Formats::add(string const & name, string const & extensions, void Formats::add(string const & name, string const & extensions,
string const & prettyname, string const & shortcut, string const & prettyname, string const & shortcut,
string const & viewer, string const & editor, string const & viewer, string const & editor,
int flags) string const & mime, int flags)
{ {
FormatList::iterator it = FormatList::iterator it =
find_if(formatlist.begin(), formatlist.end(), find_if(formatlist.begin(), formatlist.end(),
FormatNamesEqual(name)); FormatNamesEqual(name));
if (it == formatlist.end()) if (it == formatlist.end())
formatlist.push_back(Format(name, extensions, prettyname, formatlist.push_back(Format(name, extensions, prettyname,
shortcut, viewer, editor, flags)); shortcut, viewer, editor, mime, flags));
else else
*it = Format(name, extensions, prettyname, shortcut, viewer, *it = Format(name, extensions, prettyname, shortcut, viewer,
editor, flags); editor, mime, flags);
} }

View File

@ -43,7 +43,7 @@ public:
/// ///
Format(std::string const & n, std::string const & e, std::string const & p, Format(std::string const & n, std::string const & e, std::string const & p,
std::string const & s, std::string const & v, std::string const & ed, std::string const & s, std::string const & v, std::string const & ed,
int); std::string const & m, int);
/// ///
bool dummy() const; bool dummy() const;
/// Is \p ext a valid filename extension for this format? /// Is \p ext a valid filename extension for this format?
@ -83,6 +83,10 @@ public:
/// ///
void setEditor(std::string const & v) { editor_ = v; } void setEditor(std::string const & v) { editor_ = v; }
/// ///
std::string const & mime() const { return mime_; }
///
void setMime(std::string const & m) { mime_ = m; }
///
bool documentFormat() const { return flags_ & document; } bool documentFormat() const { return flags_ & document; }
/// ///
bool vectorFormat() const { return flags_ & vector; } bool vectorFormat() const { return flags_ & vector; }
@ -111,6 +115,14 @@ private:
std::string viewer_; std::string viewer_;
/// Editor for this format. \sa viewer_. /// Editor for this format. \sa viewer_.
std::string editor_; std::string editor_;
/*!
* Full MIME type, e.g. "text/x-tex".
* Only types listed by the shared MIME database of freedesktop.org
* should be added.
* This field may be empty, but it must be unique across all formats
* if it is set.
*/
std::string mime_;
/// ///
int flags_; int flags_;
}; };
@ -148,6 +160,10 @@ public:
** @note For natively zipped formats, such as dia/odg, this returns false. ** @note For natively zipped formats, such as dia/odg, this returns false.
**/ **/
bool isZippedFile(support::FileName const & filename) const; bool isZippedFile(support::FileName const & filename) const;
/// check for zipped file format
static bool isZippedFileFormat(std::string const & format);
/// check for PostScript file format
static bool isPostScriptFileFormat(std::string const & format);
/// Set editor and/or viewer to "auto" for formats that can be /// Set editor and/or viewer to "auto" for formats that can be
/// opened by the OS. /// opened by the OS.
void setAutoOpen(); void setAutoOpen();
@ -159,7 +175,7 @@ public:
void add(std::string const & name, std::string const & extensions, void add(std::string const & name, std::string const & extensions,
std::string const & prettyname, std::string const & shortcut, std::string const & prettyname, std::string const & shortcut,
std::string const & viewer, std::string const & editor, std::string const & viewer, std::string const & editor,
int flags); std::string const & mime, int flags);
/// ///
void erase(std::string const & name); void erase(std::string const & name);
/// ///

View File

@ -14,6 +14,7 @@
#include <config.h> #include <config.h>
#include "Lexer.h" #include "Lexer.h"
#include "Format.h"
#include "support/convert.h" #include "support/convert.h"
#include "support/debug.h" #include "support/debug.h"
@ -237,10 +238,14 @@ void Lexer::Pimpl::popTable()
bool Lexer::Pimpl::setFile(FileName const & filename) bool Lexer::Pimpl::setFile(FileName const & filename)
{ {
#ifdef TEX2LYX
// tex2lyx does not read lyxrc and therefore can't really check for
// zipped formats.
if (false) {
#else
// Check the format of the file. // Check the format of the file.
string const format = filename.guessFormatFromContents(); if (formats.isZippedFile(filename)) {
#endif
if (format == "gzip" || format == "zip" || format == "compress") {
LYXERR(Debug::LYXLEX, "lyxlex: compressed"); LYXERR(Debug::LYXLEX, "lyxlex: compressed");
// The check only outputs a debug message, because it triggers // The check only outputs a debug message, because it triggers
// a bug in compaq cxx 6.2, where is_open() returns 'true' for // a bug in compaq cxx 6.2, where is_open() returns 'true' for

View File

@ -55,7 +55,7 @@ namespace os = support::os;
namespace { namespace {
static unsigned int const LYXRC_FILEFORMAT = 6; // younes: add use_qimage option static unsigned int const LYXRC_FILEFORMAT = 7; // gb: add mime types
// when adding something to this array keep it sorted! // when adding something to this array keep it sorted!
LexerKeyword lyxrcTags[] = { LexerKeyword lyxrcTags[] = {
@ -1085,28 +1085,29 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
break; break;
} }
case RC_FILEFORMAT: { case RC_FILEFORMAT: {
bool ok = true;
string format, extensions, prettyname, shortcut; string format, extensions, prettyname, shortcut;
lexrc >> format >> extensions >> prettyname >> shortcut; if (!(lexrc >> format >> extensions))
ok = false;
if (ok && lexrc.next(true))
prettyname = lexrc.getString();
else
ok = false;
if (ok)
if(!(lexrc >> shortcut))
ok = false;
string viewer, editor; string viewer, editor;
if (lexrc.next(true)) if (ok && lexrc.next(true))
viewer = lexrc.getString(); viewer = lexrc.getString();
if (lexrc.next(true)) else
ok = false;
if (ok && lexrc.next(true))
editor = lexrc.getString(); editor = lexrc.getString();
string flags; else
// Hack to ensure compatibility with versions older ok = false;
// than 1.5.0 string flags, mime;
int le = lexrc.lex(); if (!(lexrc >> flags >> mime))
if (le != Lexer::LEX_FEOF && le != Lexer::LEX_UNDEF) { ok = false;
flags = lexrc.getString();
if (le != Lexer::LEX_DATA) {
// We have got a known token.
// Therefore this is an old style
// format definition without
// flags.
lexrc.pushToken(flags);
flags.erase();
}
}
int flgs = Format::none; int flgs = Format::none;
while (!flags.empty()) { while (!flags.empty()) {
string flag; string flag;
@ -1124,14 +1125,16 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
<< flag << "' for format `" << flag << "' for format `"
<< format << "'."); << format << "'.");
} }
if (prettyname.empty()) { if (!ok)
LYXERR0("Syntax error in format " << format);
else if (prettyname.empty()) {
if (theConverters().formatIsUsed(format)) if (theConverters().formatIsUsed(format))
LYXERR0("Can't delete format " << format); LYXERR0("Can't delete format " << format);
else else
formats.erase(format); formats.erase(format);
} else { } else {
formats.add(format, extensions, prettyname, formats.add(format, extensions, prettyname,
shortcut, viewer, editor, flgs); shortcut, viewer, editor, mime, flgs);
} }
break; break;
} }
@ -2711,7 +2714,8 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
format->editor() != cit->editor() || format->editor() != cit->editor() ||
format->documentFormat() != cit->documentFormat() || format->documentFormat() != cit->documentFormat() ||
format->vectorFormat() != cit->vectorFormat() || format->vectorFormat() != cit->vectorFormat() ||
format->inExportMenu() != cit->inExportMenu()) { format->inExportMenu() != cit->inExportMenu() ||
format->mime() != cit->mime()) {
os << "\\format \"" << cit->name() << "\" \"" os << "\\format \"" << cit->name() << "\" \""
<< cit->extensions() << "\" \"" << cit->extensions() << "\" \""
<< cit->prettyname() << "\" \"" << cit->prettyname() << "\" \""
@ -2729,7 +2733,7 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
flags.push_back("menu=export"); flags.push_back("menu=export");
os << getStringFromVector(flags); os << getStringFromVector(flags);
os << "\"\n"; os << "\" \"" << cit->mime() << "\"\n";
} }
} }
@ -2738,7 +2742,7 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
cit != system_formats.end(); ++cit) cit != system_formats.end(); ++cit)
if (!formats.getFormat(cit->name())) if (!formats.getFormat(cit->name()))
os << "\\format \"" << cit->name() os << "\\format \"" << cit->name()
<< "\" \"\" \"\" \"\" \"\" \"\" \"\"\n"; << "\" \"\" \"\" \"\" \"\" \"\" \"\" \"\"\n";
if (tag != RC_LAST) if (tag != RC_LAST)
break; break;
case RC_VIEWER_ALTERNATIVES: { case RC_VIEWER_ALTERNATIVES: {

View File

@ -1983,6 +1983,7 @@ void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
formatED->setText(toqstr(f.name())); formatED->setText(toqstr(f.name()));
copierED->setText(toqstr(form_->movers().command(f.name()))); copierED->setText(toqstr(form_->movers().command(f.name())));
extensionsED->setText(toqstr(f.extensions())); extensionsED->setText(toqstr(f.extensions()));
mimeED->setText(toqstr(f.mime()));
shortcutED->setText( shortcutED->setText(
toqstr(l10n_shortcut(f.prettyname(), f.shortcut()))); toqstr(l10n_shortcut(f.prettyname(), f.shortcut())));
documentCB->setChecked((f.documentFormat())); documentCB->setChecked((f.documentFormat()));
@ -2038,6 +2039,13 @@ void PrefFileformats::on_editorED_textEdited(const QString & s)
} }
void PrefFileformats::on_mimeED_textEdited(const QString & s)
{
currentFormat().setMime(fromqstr(s));
changed();
}
void PrefFileformats::on_shortcutED_textEdited(const QString & s) void PrefFileformats::on_shortcutED_textEdited(const QString & s)
{ {
string const new_shortcut = fromqstr(s); string const new_shortcut = fromqstr(s);
@ -2195,7 +2203,7 @@ Format & PrefFileformats::currentFormat()
void PrefFileformats::on_formatNewPB_clicked() void PrefFileformats::on_formatNewPB_clicked()
{ {
form_->formats().add("", "", "", "", "", "", Format::none); form_->formats().add("", "", "", "", "", "", "", Format::none);
updateView(); updateView();
formatsCB->setCurrentIndex(0); formatsCB->setCurrentIndex(0);
formatsCB->setFocus(Qt::OtherFocusReason); formatsCB->setFocus(Qt::OtherFocusReason);

View File

@ -358,6 +358,7 @@ private Q_SLOTS:
void on_extensionsED_textEdited(const QString &); void on_extensionsED_textEdited(const QString &);
void on_viewerED_textEdited(const QString &); void on_viewerED_textEdited(const QString &);
void on_editorED_textEdited(const QString &); void on_editorED_textEdited(const QString &);
void on_mimeED_textEdited(const QString &);
void on_shortcutED_textEdited(const QString &); void on_shortcutED_textEdited(const QString &);
void on_formatED_editingFinished(); void on_formatED_editingFinished();
void on_formatED_textChanged(const QString &); void on_formatED_textChanged(const QString &);

View File

@ -103,6 +103,19 @@
<item row="5" column="1" colspan="2" > <item row="5" column="1" colspan="2" >
<widget class="QLineEdit" name="extensionsED" /> <widget class="QLineEdit" name="extensionsED" />
</item> </item>
<item row="6" column="0" >
<widget class="QLabel" name="mimeLA" >
<property name="text" >
<string>&amp;MIME:</string>
</property>
<property name="buddy" >
<cstring>mimeED</cstring>
</property>
</widget>
</item>
<item row="6" column="1" >
<widget class="QLineEdit" name="mimeED" />
</item>
<item row="7" column="0" > <item row="7" column="0" >
<widget class="QLabel" name="shortcutLA" > <widget class="QLabel" name="shortcutLA" >
<property name="text" > <property name="text" >
@ -239,6 +252,7 @@
<tabstop>editorED</tabstop> <tabstop>editorED</tabstop>
<tabstop>viewerCO</tabstop> <tabstop>viewerCO</tabstop>
<tabstop>viewerED</tabstop> <tabstop>viewerED</tabstop>
<tabstop>mimeED</tabstop>
<tabstop>copierED</tabstop> <tabstop>copierED</tabstop>
</tabstops> </tabstops>
<includes> <includes>

View File

@ -46,11 +46,11 @@ string const readBB_from_PSFile(FileName const & file)
// end of the file. Than we have in the header: // end of the file. Than we have in the header:
// %%BoundingBox: (atend) // %%BoundingBox: (atend)
// In this case we must check the end. // In this case we must check the end.
bool zipped = file.isZippedFile(); bool const zipped = formats.isZippedFile(file);
FileName const file_ = zipped ? unzipFile(file) : file; FileName const file_ = zipped ? unzipFile(file) : file;
string const format = file_.guessFormatFromContents(); string const format = formats.getFormatFromFile(file_);
if (format != "eps" && format != "ps") { if (!Formats::isPostScriptFileFormat(format)) {
LYXERR(Debug::GRAPHICS, "[readBB_from_PSFile] no(e)ps-format"); LYXERR(Debug::GRAPHICS, "[readBB_from_PSFile] no(e)ps-format");
if (zipped) if (zipped)
file_.removeFile(); file_.removeFile();

View File

@ -948,13 +948,6 @@ string FileName::guessFormatFromContents() const
} }
bool FileName::isZippedFile() const
{
string const type = guessFormatFromContents();
return contains("gzip zip compress", type) && !type.empty();
}
docstring const FileName::relPath(string const & path) const docstring const FileName::relPath(string const & path) const
{ {
// FIXME UNICODE // FIXME UNICODE

View File

@ -175,9 +175,6 @@ public:
*/ */
std::string guessFormatFromContents() const; std::string guessFormatFromContents() const;
/// check for zipped file
bool isZippedFile() const;
static FileName fromFilesystemEncoding(std::string const & name); static FileName fromFilesystemEncoding(std::string const & name);
/// (securely) create a temporary file with the given mask. /// (securely) create a temporary file with the given mask.
/// \p mask must be in filesystem encoding, if it contains a /// \p mask must be in filesystem encoding, if it contains a