From: Pavel Sanda Date: Tue, 21 Sep 2010 16:34:30 +0000 (+0000) Subject: Add lilypond-book module and add support for instant preview. X-Git-Tag: 2.0.0~2528 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=e7dd1bf9dd571bbefb99a2fc5f9a1382e68a4a0d;p=features.git Add lilypond-book module and add support for instant preview. Patch by Julien Rioux. http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg162042.html git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@35472 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/lib/Makefile.am b/lib/Makefile.am index a67c6f77a2..ca2b1c08e9 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -257,6 +257,7 @@ dist_examples_DATA = \ examples/iecc12.fen \ examples/instant_preview.lyx \ examples/landslide.lyx \ + examples/lilypond.lyx \ examples/linguistics.lyx \ examples/listerrors.lyx \ examples/modernCV.lyx \ @@ -1100,6 +1101,7 @@ dist_layouts_DATA =\ layouts/kluwer.layout \ layouts/latex8.layout \ layouts/letter.layout \ + layouts/lilypond.module \ layouts/linguistics.module \ layouts/literate-article.layout \ layouts/literate-book.layout \ @@ -1209,6 +1211,7 @@ dist_scripts_PYTHON = \ scripts/legacy_lyxpreview2ppm.py \ scripts/listerrors \ scripts/lyxpreview2bitmap.py \ + scripts/lyxpreview-lytex2bitmap.py \ scripts/lyxpreview-platex2bitmap.py \ scripts/lyxpreview_tools.py \ scripts/tex_copy.py diff --git a/lib/configure.py b/lib/configure.py index bf36fb7c95..ce6fe328be 100644 --- a/lib/configure.py +++ b/lib/configure.py @@ -505,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 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" @@ -572,6 +573,7 @@ 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 lyxpreview-lytex lyxpreview-lytex "LyX Preview (LilyPond book)" "" "" "" "" \Format lyxpreview-platex lyxpreview-platex "LyX Preview (pLaTeX)" "" "" "" "" \Format pdftex pdftex_t PDFTEX "" "" "" "" \Format program "" Program "" "" "" "" @@ -807,7 +809,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" ""') - 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" ""''') @@ -819,6 +821,38 @@ def checkConverterEntries(): 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 "%%" ""', '']) # diff --git a/lib/examples/lilypond.lyx b/lib/examples/lilypond.lyx new file mode 100644 index 0000000000..2ad978c0a0 --- /dev/null +++ b/lib/examples/lilypond.lyx @@ -0,0 +1,2020 @@ +#LyX 2.0.0svn created this file. For more info see http://www.lyx.org/ +\lyxformat 401 +\begin_document +\begin_header +\textclass article +\begin_preamble +\date{} +\end_preamble +\use_default_options true +\begin_modules +lilypond +\end_modules +\maintain_unincluded_children false +\language english +\inputencoding utf8 +\fontencoding global +\font_roman default +\font_sans default +\font_typewriter default +\font_default_family default +\use_xetex false +\font_sc false +\font_osf false +\font_sf_scale 100 +\font_tt_scale 100 + +\graphics default +\default_output_format default +\output_sync 0 +\bibtex_command default +\index_command default +\paperfontsize 12 +\spacing single +\use_hyperref false +\papersize default +\use_geometry true +\use_amsmath 1 +\use_esint 1 +\use_mhchem 1 +\use_mathdots 1 +\cite_engine basic +\use_bibtopic false +\use_indices false +\paperorientation portrait +\suppress_date false +\index Index +\shortcut idx +\color #008000 +\end_index +\leftmargin 2cm +\topmargin 2cm +\rightmargin 2cm +\bottommargin 2cm +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation skip +\defskip smallskip +\quotes_language english +\papercolumns 1 +\papersides 1 +\paperpagestyle default +\tracking_changes false +\output_changes false +\html_math_output 0 +\html_be_strict true +\end_header + +\begin_body + +\begin_layout Title +LilyPond-book + LyX +\end_layout + +\begin_layout Abstract +This is an example file demonstrating the use of LilyPond music notation + with LyX. +\end_layout + +\begin_layout Section +Using LilyPond code within LyX +\end_layout + +\begin_layout Standard +Support for LilyPond constructs (LilyPond code) within LyX is enabled by + adding the LilyPond module to your document. + This is done from the menu Document \SpecialChar \menuseparator + Settings..., then selecting LilyPond + in the list of modules. + You can use any LaTeX-based LyX layout and use the regular preview and + export mechanism; LyX will take care of processing the LaTeX code through + LilyPond-book for you. + LilyPond-book can also handle DocBook documents but LilyPond-DocBook support + in LyX is missing at the moment. +\end_layout + +\begin_layout Subsection +Requirements +\end_layout + +\begin_layout List +\labelwidthstring 00.00.0000 +LaTeX +\begin_inset space ~ +\end_inset + +support: LilyPond-book version 2.1 +\end_layout + +\begin_layout List +\labelwidthstring 00.00.0000 +PDFLaTeX +\begin_inset space ~ +\end_inset + +support: LilyPond-book version 2.11 +\end_layout + +\begin_layout Paragraph +Notes: +\end_layout + +\begin_layout Standard +LilyPond-book supports LaTeX output since version 2.1. + PDFLaTeX requires LilyPond-book version 2.9 or older, but there are bugs + in those early versions. + We require version 2.11 and older because we use the - +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +-lily-output-dir flag. +\end_layout + +\begin_layout Subsection +Integration +\end_layout + +\begin_layout Standard +The module provides a LilyPond inset which you insert from the menu Insert + \SpecialChar \menuseparator + Custom Insets. + This inset is for typing the LilyPond code which will be typeset into your + musical notes. + First, let's try a simple scale: +\end_layout + +\begin_layout Standard +\begin_inset Flex LilyPond +status open + +\begin_layout Plain Layout + + +\backslash +relative c'' { +\end_layout + +\begin_layout Plain Layout + + g a b c +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The previous LyX inset produces the following LaTeX-lookalike code: +\end_layout + +\begin_layout LyX-Code + +\backslash +begin{lilypond} +\end_layout + +\begin_layout LyX-Code + +\backslash +relative c'' { +\end_layout + +\begin_layout LyX-Code + g a b c +\end_layout + +\begin_layout LyX-Code +} +\end_layout + +\begin_layout LyX-Code + +\backslash +end{lilypond} +\end_layout + +\begin_layout Standard +This code is not, in fact, processed by LaTeX, but is preprocessed by LilyPond-b +ook, which creates the graphics files and include them in the LaTeX document + by replacing the above with +\family typewriter + +\backslash +includegraphics{\SpecialChar \ldots{} +} +\family default +. +\end_layout + +\begin_layout Standard +Thus, the conversion toolchain is as follow: LyX\SpecialChar \menuseparator +LilyPond-book\SpecialChar \menuseparator +LaTeX. + Every step of the toolchain obeys your spacing, so whether you put the + musical extract inline or in its own paragraph, centered or left-aligned, + etc., what you see in the LyX window should be respected in the final format. + An example of inline use may be to display a chord name, such as +\begin_inset Flex LilyPond +status open + +\begin_layout Plain Layout + + +\backslash +markup { +\backslash +concat {B +\backslash +super +\backslash +flat } } +\end_layout + +\end_inset + +, or perhaps a very short snippet. +\end_layout + +\begin_layout Subsection +Previews +\end_layout + +\begin_layout Standard +It is possible to have a direct feedback of what the music notation looks + like from within LyX. + To do this, wrap a LilyPond inset inside a Preview inset, which you find + from the menu Insert \SpecialChar \menuseparator + Preview. + This only affects the display within LyX, not the output: +\end_layout + +\begin_layout Standard +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status open + +\begin_layout Plain Layout + + +\backslash +relative c'' { +\end_layout + +\begin_layout Plain Layout + + ais a g ges +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Unfortunately, you might find that the preview isn't exactly instantaneous. + You need to move the cursor out of the Preview inset to start compilation, + and processing time can take a few seconds. +\end_layout + +\begin_layout Subsection +Gotchas +\end_layout + +\begin_layout Standard +LilyPond-book searches for a +\family typewriter + +\backslash +score +\family default + or +\family typewriter + +\backslash +relative +\family default + command when it decides if the code is only a fragment. + It is possible to include no LilyPond command at all, but in that case + {surrounding braces} are required. + Thus, in the following code, +\end_layout + +\begin_layout LyX-Code + +\backslash +begin{lilypond} +\end_layout + +\begin_layout LyX-Code + ais' f'' g' e'' % no +\backslash +score given +\end_layout + +\begin_layout LyX-Code + +\backslash +end{lilypond} +\end_layout + +\begin_layout Standard +LilyPond-book gets confused: +\end_layout + +\begin_layout LyX-Code +error: syntax error, unexpected NOTENAME_PITCH +\end_layout + +\begin_layout LyX-Code +ais' f'' g' e'' % no +\backslash +score given +\end_layout + +\begin_layout Standard +With surrounding braces, all is well: +\end_layout + +\begin_layout Standard +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status open + +\begin_layout Plain Layout + +{ais' f'' g' e''} % no +\backslash +score given +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +LilyPond examples +\end_layout + +\begin_layout Standard +Example +\begin_inset CommandInset ref +LatexCommand ref +reference "sub:Editorial-headword" + +\end_inset + + shows that any valid LilyPond construct can be handled, no matter how complicat +ed. + Example +\begin_inset CommandInset ref +LatexCommand ref +reference "sub:Positioning-of-markup" + +\end_inset + + shows how you can mix LilyPond code with tables to display the fingering + of guitar chords. + And Example +\begin_inset CommandInset ref +LatexCommand ref +reference "sub:Tablatures-template" + +\end_inset + + shows yet another LilyPond output for guitarists. +\end_layout + +\begin_layout Subsection +Editorial headword +\begin_inset CommandInset label +LatexCommand label +name "sub:Editorial-headword" + +\end_inset + + +\end_layout + +\begin_layout Standard +NR 1.7 Editorial annotations Beethoven, Op. + 31, No. + 3 Piano sonata 18, Movt II, Scherzo Measures 9--14. +\end_layout + +\begin_layout Standard +\noindent +\align center +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status collapsed + +\begin_layout Plain Layout + + +\backslash +new PianoStaff << +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + % RH Staff +\end_layout + +\begin_layout Plain Layout + + +\backslash +new Staff { +\end_layout + +\begin_layout Plain Layout + + +\backslash +clef treble +\end_layout + +\begin_layout Plain Layout + + +\backslash +key aes +\backslash +major +\end_layout + +\begin_layout Plain Layout + + +\backslash +time 2/4 +\end_layout + +\begin_layout Plain Layout + + +\backslash +set Staff.fingeringOrientations = #'(up) +\end_layout + +\begin_layout Plain Layout + + +\backslash +set Score.currentBarNumber = #9 +\end_layout + +\begin_layout Plain Layout + + +\backslash +partial 8 +\end_layout + +\begin_layout Plain Layout + + 8 +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + | +\end_layout + +\begin_layout Plain Layout + + +\backslash +set doubleSlurs = ##t +\end_layout + +\begin_layout Plain Layout + + 4( +\end_layout + +\begin_layout Plain Layout + + 8 +\backslash +staccato) +\end_layout + +\begin_layout Plain Layout + + +\backslash +noBeam +\end_layout + +\begin_layout Plain Layout + + c''8-5 +\backslash +staccato +\backslash +pp +\end_layout + +\begin_layout Plain Layout + + | +\end_layout + +\begin_layout Plain Layout + + +\backslash +unset doubleSlurs +\end_layout + +\begin_layout Plain Layout + + bes'8..( +\end_layout + +\begin_layout Plain Layout + + aes'32 +\end_layout + +\begin_layout Plain Layout + + g'8) +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + f'8 +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + | +\end_layout + +\begin_layout Plain Layout + + e'4-2 +\end_layout + +\begin_layout Plain Layout + + r8 +\end_layout + +\begin_layout Plain Layout + + +\backslash +once +\backslash +override Script #'script-priority = #-100 +\end_layout + +\begin_layout Plain Layout + + +\backslash +afterGrace +\end_layout + +\begin_layout Plain Layout + + f'8( +\backslash +trill^ +\backslash +markup { +\backslash +finger "3-2" } +\end_layout + +\begin_layout Plain Layout + + { e'16[ f'16] } +\end_layout + +\begin_layout Plain Layout + + | +\end_layout + +\begin_layout Plain Layout + + g'8..-3 +\end_layout + +\begin_layout Plain Layout + + f'32 +\end_layout + +\begin_layout Plain Layout + + e'8-1) +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + d'8-2 +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + | +\end_layout + +\begin_layout Plain Layout + + c'4 +\end_layout + +\begin_layout Plain Layout + + r4 +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + % LH Staff +\end_layout + +\begin_layout Plain Layout + + +\backslash +new Staff { +\end_layout + +\begin_layout Plain Layout + + +\backslash +key aes +\backslash +major +\end_layout + +\begin_layout Plain Layout + + +\backslash +clef treble +\end_layout + +\begin_layout Plain Layout + + +\backslash +override Fingering #'direction = #down +\end_layout + +\begin_layout Plain Layout + + +\backslash +set Staff.fingeringOrientations = #'(down) +\end_layout + +\begin_layout Plain Layout + + +\backslash +partial 8 +\end_layout + +\begin_layout Plain Layout + + 8 +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + +\backslash +set doubleSlurs = ##t +\end_layout + +\begin_layout Plain Layout + + 4( +\end_layout + +\begin_layout Plain Layout + + 8) +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + +\backslash +noBeam +\end_layout + +\begin_layout Plain Layout + + +\backslash +clef bass +\end_layout + +\begin_layout Plain Layout + + c'8-1 +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + | +\end_layout + +\begin_layout Plain Layout + + +\backslash +set doubleSlurs = ##f +\end_layout + +\begin_layout Plain Layout + + bes8..( +\end_layout + +\begin_layout Plain Layout + + aes32 +\end_layout + +\begin_layout Plain Layout + + g8-1) +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + f8 +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + | +\end_layout + +\begin_layout Plain Layout + + e4 +\end_layout + +\begin_layout Plain Layout + + r8 +\end_layout + +\begin_layout Plain Layout + + +\backslash +afterGrace +\end_layout + +\begin_layout Plain Layout + + f8( +\backslash +trill_ +\backslash +markup { +\backslash +finger "2-1" } +\end_layout + +\begin_layout Plain Layout + + { e16[ f16] } +\end_layout + +\begin_layout Plain Layout + + | +\end_layout + +\begin_layout Plain Layout + + g8..-1 +\end_layout + +\begin_layout Plain Layout + + f32 +\end_layout + +\begin_layout Plain Layout + + e8) +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + d8 +\backslash +staccato +\end_layout + +\begin_layout Plain Layout + + | +\end_layout + +\begin_layout Plain Layout + + c4 +\end_layout + +\begin_layout Plain Layout + + r4 +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + +>> +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +[from +\begin_inset Flex URL +status collapsed + +\begin_layout Plain Layout + +http://lsr.dsi.unimi.it/LSR/Item?id=627 +\end_layout + +\end_inset + +] +\end_layout + +\begin_layout Subsection +Positioning of markup elements +\begin_inset CommandInset label +LatexCommand label +name "sub:Positioning-of-markup" + +\end_inset + + +\end_layout + +\begin_layout Standard +Tabular arrangement of elements +\end_layout + +\begin_layout Standard +\noindent +\align center +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout +Ignatzek +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Alternative +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Diagram +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +C +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +C +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status collapsed + +\begin_layout Plain Layout + + +\backslash +markup { +\backslash +fret-diagram #"6-x;5-3-3;4-2-2;3-o;2-1-1;1-o;" } +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +Cm +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status collapsed + +\begin_layout Plain Layout + + +\backslash +markup { +\backslash +concat { C +\backslash +super { +\backslash +flat 5 } } } +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status collapsed + +\begin_layout Plain Layout + + +\backslash +markup { +\backslash +fret-diagram #"6-x;5-1-1;4-3-3;3-3-4;2-2-2;1-1-1;c:5-1-1;" } +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +C+ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status collapsed + +\begin_layout Plain Layout + + +\backslash +markup { +\backslash +concat { C +\backslash +super { +\backslash +sharp 5 } } } +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status collapsed + +\begin_layout Plain Layout + + +\backslash +markup { +\backslash +fret-diagram #"6-x;5-x;4-2-2;3-1-1;2-1-1;1-4-4;c:2-3-1;" } +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Standard +Musical notation with each element placed by hand +\end_layout + +\begin_layout Standard +\noindent +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status open + +\begin_layout Plain Layout + +%{ +\end_layout + +\begin_layout Plain Layout + +Snippet for overlay markup command - absolute positioning of items +\end_layout + +\begin_layout Plain Layout + +Defines a new markup command +\backslash +overlay which takes a list of markup elements and positions them all at + the same point. +\end_layout + +\begin_layout Plain Layout + + By translating each markup element, you can gain control of the + absolute position of each. +\end_layout + +\begin_layout Plain Layout + +%} +\end_layout + +\begin_layout Plain Layout + +#(define-public (stack-stencil-overlay stencils) +\end_layout + +\begin_layout Plain Layout + + "Recursive function to add stencils together" +\end_layout + +\begin_layout Plain Layout + + (if (and (pair? stencils) +\end_layout + +\begin_layout Plain Layout + + (ly:stencil? (car stencils))) +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + (if (and (pair? (cdr stencils)) +\end_layout + +\begin_layout Plain Layout + + (ly:stencil? (cadr stencils))) +\end_layout + +\begin_layout Plain Layout + + (let ((tail (stack-stencil-overlay (cdr stencils))) +\end_layout + +\begin_layout Plain Layout + + (head (car stencils))) +\end_layout + +\begin_layout Plain Layout + + (ly:stencil-add head tail)) +\end_layout + +\begin_layout Plain Layout + + (car stencils)) +\end_layout + +\begin_layout Plain Layout + + point-stencil)) +\end_layout + +\begin_layout Plain Layout + +#(define-markup-command (overlay layout props args) +\end_layout + +\begin_layout Plain Layout + + (markup-list?) +\end_layout + +\begin_layout Plain Layout + + "Overlay arguments one on top of the next" +\end_layout + +\begin_layout Plain Layout + + (let ((stencils (interpret-markup-list layout props args))) +\end_layout + +\begin_layout Plain Layout + + (stack-stencil-overlay +\end_layout + +\begin_layout Plain Layout + + (remove ly:stencil-empty? stencils)))) +\end_layout + +\begin_layout Plain Layout + + +\backslash +markup { +\end_layout + +\begin_layout Plain Layout + + +\backslash +overlay { +\end_layout + +\begin_layout Plain Layout + +% +\backslash +translate #'(0 . + 7) +\end_layout + +\begin_layout Plain Layout + +% +\backslash +justify-string #"Musical notation with each element placed by hand" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(0 . + -3) +\backslash +fontsize #2 "1" +\end_layout + +\begin_layout Plain Layout + + +\backslash +postscript #" +\end_layout + +\begin_layout Plain Layout + + 0.15 setlinewidth +\end_layout + +\begin_layout Plain Layout + + 4 0 moveto 74 0 lineto stroke +\end_layout + +\begin_layout Plain Layout + + 4 -1 moveto 74 -1 lineto stroke +\end_layout + +\begin_layout Plain Layout + + 4 -2 moveto 74 -2 lineto stroke +\end_layout + +\begin_layout Plain Layout + + 4 -3 moveto 74 -3 lineto stroke +\end_layout + +\begin_layout Plain Layout + + 4 -4 moveto 74 -4 lineto stroke +\end_layout + +\begin_layout Plain Layout + + 11.6 -5 moveto 13.6 -5 lineto stroke +\end_layout + +\begin_layout Plain Layout + + 42.6 -5 moveto 44.6 -5 lineto stroke +\end_layout + +\begin_layout Plain Layout + + 17.6 -5 moveto 0 0 2 -1 7 -1 9 0 rcurveto stroke +\end_layout + +\begin_layout Plain Layout + + 48.6 -5 moveto 0 0 2 -1 7 -1 9 0 rcurveto stroke +\end_layout + +\begin_layout Plain Layout + + 0.3 setlinewidth +\end_layout + +\begin_layout Plain Layout + + 73.85 0 moveto 73.85 -4 lineto stroke +\end_layout + +\begin_layout Plain Layout + + " +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(4 . + 2) "Präludium" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(5 . + -3) +\backslash +musicglyph #"clefs.G_change" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(8 . + -2) +\backslash +musicglyph #"timesig.C44" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(12 . + -5) +\backslash +note-by-number #1 #0 #DOWN +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(12 . + -2) +\backslash +musicglyph #"rests.4" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(12 . + 0) +\backslash +musicglyph #"rests.3" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(16 . + -4) +\backslash +note-by-number #3 #0 #DOWN +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(17.4 . + -4.4) +\backslash +musicglyph #"dots.dot" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(19 . + -3) +\backslash +note-by-number #2 #0 #UP +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(23 . + -1.5) +\backslash +note-by-number #2 #0 #1.2 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(20.25 . + 0) +\backslash +beam #4 #0.5 #0.40 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(20.25 . + -1) +\backslash +beam #4 #0.5 #0.40 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(27 . + -4) +\backslash +note-by-number #2 #0 #DOWN +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(27 . + -0.5) +\backslash +note-by-number #2 #0 #UP +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(31 . + -3) +\backslash +note-by-number #2 #0 #1.7 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(35 . + -1.5) +\backslash +note-by-number #2 #0 #1.3 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(39 . + -0.5) +\backslash +note-by-number #2 #0 #UP +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(28.25 . + 2.25) +\backslash +beam #12 #0 #0.4 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(28.25 . + 1.35) +\backslash +beam #12 #0 #0.4 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(43 . + -5) +\backslash +note-by-number #1 #0 #DOWN +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(43 . + -2) +\backslash +musicglyph #"rests.4" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(43 . + 0) +\backslash +musicglyph #"rests.3" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(47 . + -4) +\backslash +note-by-number #3 #0 #DOWN +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(48.4 . + -4.4) +\backslash +musicglyph #"dots.dot" +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(50 . + -3) +\backslash +note-by-number #2 #0 #UP +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(54 . + -1.5) +\backslash +note-by-number #2 #0 #1.2 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(51.25 . + 0) +\backslash +beam #4 #0.5 #0.40 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(51.25 . + -1) +\backslash +beam #4 #0.5 #0.40 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(58 . + -4) +\backslash +note-by-number #2 #0 #DOWN +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(58 . + -0.5) +\backslash +note-by-number #2 #0 #UP +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(62 . + -3) +\backslash +note-by-number #2 #0 #1.7 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(66 . + -1.5) +\backslash +note-by-number #2 #0 #1.3 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(70 . + -0.5) +\backslash +note-by-number #2 #0 #UP +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(59.25 . + 2.25) +\backslash +beam #12 #0 #0.40 +\end_layout + +\begin_layout Plain Layout + + +\backslash +translate #'(59.25 . + 1.35) +\backslash +beam #12 #0 #0.40 +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +[adapted from +\begin_inset Flex URL +status collapsed + +\begin_layout Plain Layout + +http://lsr.dsi.unimi.it/LSR/Item?id=628 +\end_layout + +\end_inset + +] +\end_layout + +\begin_layout Subsection +Tablatures template +\begin_inset CommandInset label +LatexCommand label +name "sub:Tablatures-template" + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Preview + +\begin_layout Standard +\begin_inset Flex LilyPond +status collapsed + +\begin_layout Plain Layout + +upper= +\backslash +relative c' { +\end_layout + +\begin_layout Plain Layout + + c4. + g4 g c +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\begin_layout Plain Layout + +lower= +\backslash +relative c { +\end_layout + +\begin_layout Plain Layout + + c4 e g, e' +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\begin_layout Plain Layout + + +\backslash +score { +\end_layout + +\begin_layout Plain Layout + + +\backslash +new StaffGroup << +\end_layout + +\begin_layout Plain Layout + + +\backslash +new Staff = "guitar" << +\end_layout + +\begin_layout Plain Layout + + +\backslash +context Voice = "upper guitar" { +\backslash +clef "G_8" +\backslash +voiceOne +\backslash +upper } +\end_layout + +\begin_layout Plain Layout + + +\backslash +context Voice = "lower guitar" { +\backslash +clef "G_8" +\backslash +voiceTwo +\backslash +lower } +\end_layout + +\begin_layout Plain Layout + + >> +\end_layout + +\begin_layout Plain Layout + + +\backslash +new TabStaff = "tab" << +\end_layout + +\begin_layout Plain Layout + + +\backslash +context TabVoice = "upper tab" { +\backslash +clef "moderntab" +\backslash +voiceOne +\backslash +upper } +\end_layout + +\begin_layout Plain Layout + + +\backslash +context TabVoice = "lower tab" { +\backslash +clef "moderntab" +\backslash +voiceTwo +\backslash +lower } +\end_layout + +\begin_layout Plain Layout + + >> +\end_layout + +\begin_layout Plain Layout + + >> +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +[from +\begin_inset Flex URL +status collapsed + +\begin_layout Plain Layout + +http://lsr.dsi.unimi.it/LSR/Item?id=634 +\end_layout + +\end_inset + +] +\end_layout + +\end_body +\end_document diff --git a/lib/layouts/lilypond.module b/lib/layouts/lilypond.module new file mode 100644 index 0000000000..0c8eb5b5a6 --- /dev/null +++ b/lib/layouts/lilypond.module @@ -0,0 +1,32 @@ +#\DeclareLyXModule[lilypond-book->latex]{LilyPond Book} +#DescriptionBegin +#This module adds an inset to enter LilyPond code directly into LyX. +#It will be processed in the output. See the lilypond.lyx example file. +#DescriptionEnd + +# Author: Julien Rioux + +Format 27 +OutputFormat lilypond-book + +InsetLayout LilyPond + LabelString LilyPond + LaTeXType Environment + LaTeXName lilypond + LyXType Custom + Decoration Classic + Font + Color latex + Family typewriter + EndFont + LabelFont + Color latex + Size Small + EndFont + MultiPar true + CustomPars false + ForcePlain true + FreeSpacing true + PassThru true + ForceLTR true +End diff --git a/lib/scripts/lyxpreview-lytex2bitmap.py b/lib/scripts/lyxpreview-lytex2bitmap.py new file mode 100755 index 0000000000..f19ffb9692 --- /dev/null +++ b/lib/scripts/lyxpreview-lytex2bitmap.py @@ -0,0 +1,250 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +# file lyxpreview-lytex2bitmap.py +# This file is part of LyX, the document processor. +# Licence details can be found in the file COPYING. + +# author Angus Leeming +# with much advice from members of the preview-latex project: +# David Kastrup, dak@gnu.org and +# Jan-Åke Larsson, jalar@mai.liu.se. + +# Full author contact details are available in file CREDITS + +# This script takes a LaTeX file and generates a collection of +# png or ppm image files, one per previewed snippet. + +# Pre-requisites: +# * A latex executable; +# * preview.sty; +# * dvipng; +# * pngtoppm (if outputing ppm format images). + +# preview.sty and dvipng are part of the preview-latex project +# http://preview-latex.sourceforge.net/ + +# preview.sty can alternatively be obtained from +# CTAN/support/preview-latex/ + +# Example usage: +# lyxpreview-lytex2bitmap.py png 0lyxpreview.tex 128 000000 faf0e6 + +# This script takes six arguments: +# FORMAT: The desired output format. Either 'png' or 'ppm'. +# TEXFILE: the name of the .tex file to be converted. +# DPI: a scale factor, used to ascertain the resolution of the +# generated image which is then passed to gs. +# FG_COLOR: the foreground color as a hexadecimal string, eg '000000'. +# BG_COLOR: the background color as a hexadecimal string, eg 'faf0e6'. +# CONVERTER: the converter (optional). Default is latex. + +# Decomposing TEXFILE's name as DIR/BASE.tex, this script will, +# if executed successfully, leave in DIR: +# * a (possibly large) number of image files with names +# like BASE[0-9]+.png +# * a file BASE.metrics, containing info needed by LyX to position +# the images correctly on the screen. + +import glob, os, re, shutil, string, sys + +from legacy_lyxpreview2ppm import legacy_conversion, \ + legacy_conversion_step2 + +from lyxpreview_tools import copyfileobj, error, find_exe, \ + find_exe_or_terminate, make_texcolor, mkstemp, run_command, warning + + +# Pre-compiled regular expressions. +latex_file_re = re.compile("\.tex$") + + +def usage(prog_name): + return "Usage: %s \n"\ + "\twhere the colors are hexadecimal strings, eg 'faf0e6'"\ + % prog_name + + +def extract_metrics_info(dvipng_stdout, metrics_file): + metrics = open(metrics_file, 'w') +# "\[[0-9]+" can match two kinds of numbers: page numbers from dvipng +# and glyph numbers from mktexpk. The glyph numbers always match +# "\[[0-9]+\]" while the page number never is followed by "\]". Thus: + page_re = re.compile("\[([0-9]+)[^]]"); + metrics_re = re.compile("depth=(-?[0-9]+) height=(-?[0-9]+)") + + success = 0 + page = "" + pos = 0 + while 1: + match = page_re.search(dvipng_stdout, pos) + if match == None: + break + page = match.group(1) + pos = match.end() + match = metrics_re.search(dvipng_stdout, pos) + if match == None: + break + success = 1 + + # Calculate the 'ascent fraction'. + descent = string.atof(match.group(1)) + ascent = string.atof(match.group(2)) + + frac = 0.5 + if ascent >= 0 or descent >= 0: + if abs(ascent + descent) > 0.1: + frac = ascent / (ascent + descent) + + # Sanity check + if frac < 0: + frac = 0.5 + + metrics.write("Snippet %s %f\n" % (page, frac)) + pos = match.end() + 2 + + return success + + +def color_pdf(latex_file, bg_color): + use_preview_pdf_re = re.compile("(\s*\\\\usepackage\[[^]]+)(pdftex\]{preview})") + + tmp = mkstemp() + + success = 0 + try: + for line in open(latex_file, 'r').readlines(): + match = use_preview_pdf_re.match(line) + if match == None: + tmp.write(line) + continue + success = 1 + tmp.write(" \\usepackage{color}\n" \ + " \\pagecolor[rgb]{%s}\n" \ + "%s\n" \ + % (bg_color, match.group())) + continue + + except: + # Unable to open the file, but do nothing here because + # the calling function will act on the value of 'success'. + warning('Warning in color_pdf! Unable to open "%s"' % latex_file) + warning(`sys.exc_type` + ',' + `sys.exc_value`) + + if success: + copyfileobj(tmp, open(latex_file,"wb"), 1) + + return success + + +def convert_to_ppm_format(pngtopnm, basename): + png_file_re = re.compile("\.png$") + + for png_file in glob.glob("%s*.png" % basename): + ppm_file = png_file_re.sub(".ppm", png_file) + + p2p_cmd = '%s "%s"' % (pngtopnm, png_file) + p2p_status, p2p_stdout = run_command(p2p_cmd) + if p2p_status != None: + error("Unable to convert %s to ppm format" % png_file) + + ppm = open(ppm_file, 'w') + ppm.write(p2p_stdout) + os.remove(png_file) + + +def main(argv): + # Parse and manipulate the command line arguments. + if len(argv) != 6 and len(argv) != 7: + error(usage(argv[0])) + + output_format = string.lower(argv[1]) + + dir, latex_file = os.path.split(argv[2]) + if len(dir) != 0: + os.chdir(dir) + + dpi = string.atoi(argv[3]) + fg_color = make_texcolor(argv[4], False) + bg_color = make_texcolor(argv[5], False) + + bg_color_gr = make_texcolor(argv[5], True) + + # External programs used by the script. + path = string.split(os.environ["PATH"], os.pathsep) + if len(argv) == 7: + latex = argv[6] + else: + latex = find_exe_or_terminate(["latex", "pplatex", "platex", "latex2e"], path) + + lilypond_book = find_exe_or_terminate(["lilypond-book"], path) + + # Make a copy of the latex file + lytex_file = latex_file_re.sub(".lytex", latex_file) + shutil.copyfile(latex_file, lytex_file) + + # Preprocess the latex file through lilypond-book. + lytex_call = '%s --latex-program=%s "%s"' % (lilypond_book, latex, lytex_file) + lytex_status, lytex_stdout = run_command(lytex_call) + if lytex_status != None: + warning("%s failed to compile %s" \ + % (os.path.basename(lilypond_book), lytex_file)) + warning(lytex_stdout) + + # This can go once dvipng becomes widespread. + dvipng = find_exe(["dvipng"], path) + if dvipng == None: + # The data is input to legacy_conversion in as similar + # as possible a manner to that input to the code used in + # LyX 1.3.x. + vec = [ argv[0], argv[2], argv[3], argv[1], argv[4], argv[5], latex ] + return legacy_conversion(vec) + + pngtopnm = "" + if output_format == "ppm": + pngtopnm = find_exe_or_terminate(["pngtopnm"], path) + + # Move color information for PDF into the latex file. + if not color_pdf(latex_file, bg_color_gr): + error("Unable to move color info into the latex file") + + # Compile the latex file. + latex_call = '%s "%s"' % (latex, latex_file) + + latex_status, latex_stdout = run_command(latex_call) + if latex_status != None: + warning("%s failed to compile %s" \ + % (os.path.basename(latex), latex_file)) + warning(latex_stdout) + + if latex == "xelatex": + warning("Using XeTeX") + # FIXME: skip unnecessary dvips trial in legacy_conversion_step2 + return legacy_conversion_step2(latex_file, dpi, output_format) + + # Run the dvi file through dvipng. + dvi_file = latex_file_re.sub(".dvi", latex_file) + dvipng_call = '%s -Ttight -depth -height -D %d -fg "%s" -bg "%s" "%s"' \ + % (dvipng, dpi, fg_color, bg_color, dvi_file) + + dvipng_status, dvipng_stdout = run_command(dvipng_call) + if dvipng_status != None: + warning("%s failed to generate images from %s ... looking for PDF" \ + % (os.path.basename(dvipng), dvi_file)) + # FIXME: skip unnecessary dvips trial in legacy_conversion_step2 + return legacy_conversion_step2(latex_file, dpi, output_format) + + # Extract metrics info from dvipng_stdout. + metrics_file = latex_file_re.sub(".metrics", latex_file) + if not extract_metrics_info(dvipng_stdout, metrics_file): + error("Failed to extract metrics info from dvipng") + + # Convert images to ppm format if necessary. + if output_format == "ppm": + convert_to_ppm_format(pngtopnm, latex_file_re.sub("", latex_file)) + + return 0 + + +if __name__ == "__main__": + main(sys.argv) diff --git a/src/graphics/PreviewLoader.cpp b/src/graphics/PreviewLoader.cpp index e1435ea720..4ff60ca5e9 100644 --- a/src/graphics/PreviewLoader.cpp +++ b/src/graphics/PreviewLoader.cpp @@ -388,12 +388,12 @@ namespace graphics { PreviewLoader::Impl::Impl(PreviewLoader & p, Buffer const & b) : parent_(p), buffer_(b) { - if (!pconverter_){ - if (b.params().encoding().package() == Encoding::japanese) - pconverter_ = setConverter("lyxpreview-platex"); - else - pconverter_ = setConverter("lyxpreview"); - } + if (b.bufferFormat() == "lilypond-book") + pconverter_ = setConverter("lyxpreview-lytex"); + else if (b.params().encoding().package() == Encoding::japanese) + pconverter_ = setConverter("lyxpreview-platex"); + else + pconverter_ = setConverter("lyxpreview"); }