From d2edde5002225c74c99007f5ce08355b1e180d25 Mon Sep 17 00:00:00 2001 From: hanwen Date: Wed, 29 Jun 2005 10:55:46 +0000 Subject: [PATCH] * Documentation/topdocs/NEWS.tely (Top): refresh. * scm/define-markup-commands.scm (wordwrap-string): new function: split string in paras and words. (wordwrap-markups): new function. (wordwrap-stencils): new function. (justify): use it. (wordwrap): use it. (wordwrap-string): use it (justify-string): use it. * scm/lily-library.scm (regexp-split): new function. * scm/define-markup-commands.scm: remove encoded-simple. remove font-markup. (fontsize): remove old version of fontsize. (wordwrap): new markup function. Wrap into paragraphs. --- ChangeLog | 13 ++ Documentation/topdocs/NEWS.tely | 300 +-------------------------- input/regression/markup-word-wrap.ly | 54 +++++ scm/define-markup-commands.scm | 98 ++++++--- scm/lily-library.scm | 20 ++ 5 files changed, 163 insertions(+), 322 deletions(-) create mode 100644 input/regression/markup-word-wrap.ly diff --git a/ChangeLog b/ChangeLog index 3cb72d1278..fbf8a0d2df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2005-06-29 Han-Wen Nienhuys + * Documentation/topdocs/NEWS.tely (Top): refresh. + + * scm/define-markup-commands.scm (wordwrap-string): new function: + split string in paras and words. + (wordwrap-markups): new function. + (wordwrap-stencils): new function. + (justify): use it. + (wordwrap): use it. + (wordwrap-string): use it + (justify-string): use it. + + * scm/lily-library.scm (regexp-split): new function. + * scm/define-markup-commands.scm: remove encoded-simple. remove font-markup. (fontsize): remove old version of fontsize. diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index eff077e24d..a8310b92fb 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -28,311 +28,21 @@ See user manual, \NAME\ @node Top @top @end ifnottex -@unnumbered New features in 2.6 since 2.4 +@unnumbered New features in 2.7 since 2.6 @itemize @bullet @item -Global font styles (roman, sans, typewriter) can be defined for each -@code{\paper} block, with - -@verbatim -#(define fonts - (make-pango-font-tree - "Times New Roman" "Helvetica" "Courier" - (/ myStaffSize 20))) -@end verbatim - - -@item -Newly created staves and lyric lines, can be put in any vertical order, -by setting @code{alignBelowContext} or @code{alignAboveContext} -properties in the newly created context. An example of the use of this -is in @inputfileref{input/regression,alignment-order.ly}. - -This feature has been sponsored by Bertalan Fodor. - - -@item -Staves may be stopped and started halfway a line, e.g. - -@lilypond[relative=2,fragment,verbatim] -b4 b \stopStaff b \startStaff b -@end lilypond - -@noindent -This feature has been sponsored by Hans Forbrich. - -@item -Grid lines, vertical lines synchronized with notes, can be drawn across -staves, by adding suitable engravers. -An example is in @inputfileref{input/regression,grid-lines.ly}, - -@lilypondfile[]{grid-lines.ly} - -@item -Lines, such as glissandi or Text-spanner lines, can have arrows at the -end, e.g. - -@lilypond[verbatim,fragment] -\override Glissando #'arrow = ##t -b''2 \glissando b' -@end lilypond - -@item -Chord names may now be rendered in Italian and French. - -@item -@file{lilypond-book} now makes @file{lilypond} print line numbers -relative to the input file for every error message. - -@item -The command @code{\epsfile} allows inclusion of EPS graphics into -markup texts. - -@item -There is a music function @code{\displayMusic}, which will display a -music expression as indented Scheme code. - -@item -Automatic beaming is now specified explicitly for each moment -throughout a measure, which enables automatic beaming in compound -measures, as demonstrated in the following item. - -@item -A plus sign was added to the number font. This enables printing of -compound time signatures - -@lilypondfile[]{compound-time.ly} - -@item -A new @code{\circle} markup command allows for all kinds of circled -texts - -@lilypondfile[]{circle.ly} - -@item -String numbers are now printed on chords as well - -@lilypond[relative,relative=1,raggedright,fragment,verbatim] - -@end lilypond - -See also @inputfileref{input/regression,string-number.ly}. - -This feature was sponsored by Gunther Strube. - -@item -Notes with ledger lines will be kept at a distance, so they never -disappear. - -@item -Clefs that are below notes of other staves are now spaced according to -engraving conventions. - -@item -Markup texts can be appended to a @code{\score} block or toplevel -music expression, for example, - -@example -\relative @{ c' d e @} -\markup @{ first text @} -\markup @{ second text @} -@end example -@c FIXME, cannot use toplevel music examples in lilypond-book, -@c but it works at toplevel too, as shown. -@lilypond[quote,raggedright] -\paper { - vsize = 60\mm - hsize = 60\mm - %% FIXME? - printpagenumber = ##f -} -\header { - tagline = "" -} -\book { - \score { - \relative { c' d e } - } - \markup { first text } - \markup { second text } -} -@end lilypond - - -See @inputfileref{input/regression,score-text.ly}. - - -@item -@TeX{}'s @code{kpathsea} library is loaded dynamically, so installing -LilyPond does not require installing @TeX{} anymore. - -@item -Point and click editing is now supported in the PS/PDF backend as -well. -See -@ifhtml -@uref{../../user/out-www/lilypond/Point-and-click.html,Point and click}. -@end ifhtml -@ifnothtml -the section Point and click in he user manual. -@end ifnothtml - -@item -White mensural ligatures now conform more closely to Renaissance -usage. - - -@item -With the new @code{tieWaitForNote} property, arpeggios may be written -out using ties, for example, - -@lilypond[fragment,verbatim,relative=1,raggedright] -\set tieWaitForNote = ##t -\grace { c16[~ e~ g]~ } 4 -@end lilypond - -Thanks to Steve Doonan for funding development of this feature. - -@item -Individual objects may be assigned colors, for example, - -@lilypond[fragment,relative=1,verbatim,raggedright] - \override NoteHead #'color = #red - c4 -@end lilypond - -@item -The PostScript backend is now used by default. This backend requires -less machinery to run, and gives more consistent results. - -Ghostscript 8.x is required for PDF output. Earlier versions may hang -while converting PostScript to PDF. - -@item -Separator slashes may be inserted between systems in a score. For an -example, see @inputfileref{input/regression,system-separator.ly}: - -@item -Locations of errors in the input are now calculated more precisely. - - - -@item -LilyPond now uses Pango and FontConfig for selecting and rendering -UTF-8 input in non-@TeX{} backends. A font may be selected by using a -FontConfig name, - -@example -\override TextScript #'font-name = #"Serif" -@end example - - -@noindent -or using the classic font selection mechanism - -@example -\override TextScript #'font-family = #'roman -\override TextScript #'font-series = #'bold -@end example - -Any Type1 and TrueType font recognized by FontConfig is available in -LilyPond as well. - -@item -Metrics of blocks of text can be retrieved from (La)@TeX{} directly, -using the @code{-f texstr} output backend. This provides exact metrics -for texts, including kerning and accents. - -@item -LilyPond now uses FreeType to read the Feta font as an OpenType -font. This is a cleaner design and more robust. Recent versions of -FontForge (2004 1211 or newer) and Freetype are required. - -@item -The SVG backend is now a fully functional backend. - -@item -A new script, @code{\espressivo} has been added, for a combination of -crescendo and decrescendo on a single note. - -@item -In markups, expressions stacked with @code{\column}, -@code{\center-align}, etc, are not grouped with @code{< ... >} anymore, -but with @code{@{ ... @}}, eg: -@example -\markup \column @{ - \line @{ first line @} - \line @{ second line @} -@} -@end example - -@item -LilyPond will now avoid line breaks that cause long texts to stick -outside of the page staff. - -@item -Grace notes following a main note, used to be entered by letting the -grace notes follow a skip in a parallel expression, for example, - -@verbatim - << { d1 } - { s2 \grace { c16[ d] } } >> - c4 -@end verbatim - -@noindent -This can now be shortened by doing - -@example -\afterGrace @{ d1 @} @{ c16[ d] @} -@end example - -@item -Pagebreaks can now be forced or forbidden after title blocks. This is -achieved by setting @code{breakbefore} in the @code{\header} block to -true or false. - -@item -Shaped note heads. This feature has been sponsored by Jonathan Walther, - -@lilypond[relative=1,fragment,verbatim,raggedright] - \set shapeNoteStyles = ##(do re mi fa #f la ti) - c d e f g a b c d e f g a b c -@end lilypond - -@item -Layout for titles, page header and footer can now be entered as -@code{\markup} commands. - -@item Positioning of slurs can now be adjusted manually - -@item Grace notes are correctly quoted and formatted when using cue notes. - -@item Cue notes can now be created with - -@example -\cueDuring #@var{voice-name} #@var{direction} @{ @var{music} @} -@end example - -@noindent -This will set stem directions and put the cue notes in the @code{cue} -@code{Voice}. - -@item Stemlets, short stems over beamed rests, have been added. - -@lilypond[relative=1,verbatim,fragment,raggedright] -\override Stem #'stemlet-length = #0.75 -c8[ r8 c16 r16 c8] -@end lilypond +Markup now supports formatting of text paragraphs, using +@code{\wordwrap} and @code{\justify}. +This feature was sponsored by Sven Axelsson. @end itemize @ifhtml For older news, go to -@uref{http://lilypond.org/doc/v2.4/Documentation/topdocs/out-www/NEWS.html}. +@uref{http://lilypond.org/doc/v2.6/Documentation/topdocs/out-www/NEWS.html}. @end ifhtml @bye diff --git a/input/regression/markup-word-wrap.ly b/input/regression/markup-word-wrap.ly new file mode 100644 index 0000000000..1ae9e5d12a --- /dev/null +++ b/input/regression/markup-word-wrap.ly @@ -0,0 +1,54 @@ +\header { + + texidoc = "The markup commands @code{\wordwrap} and @code{\justify} + produce simple paragraph text." + +} + +\markup { + this is normal text + \override #'(linewidth . 60) + \wordwrap { + This is a test of the wordwrapping function. + 1 This is a test of the wordwrapping function. + 2 This is a test of the wordwrapping function. + 3 This is a test of the wordwrapping function. + 4 1a111 11111 \bold 22222 \italic 2222 + } + continuing +} + +\markup { + this is normal text + \override #'(linewidth . 40) + \justify { + This is a test of the wordwrapping function, but with justification. + 1 This is a test of the wordwrapping function, but with justification. + 2 This is a test of \fraction a b the wordwrapping function, but with justification. + 3 This is a test of the wordwrapping function, but with justification. bla bla + } + continuing +} + + +\markup { + + \override #'(linewidth . 40) + +{ \wordwrap-string #" Om mani padme hum Om mani padme hum Om mani +padme hum Om mani padme hum Om mani padme hum Om mani padme hum Om +mani padme hum Om mani padme hum. + +Gate Gate paragate Gate Gate paragate Gate Gate paragate Gate Gate +paragate Gate Gate paragate Gate Gate paragate." + + \justify-string #" Om mani padme hum Om mani padme hum Om mani +padme hum Om mani padme hum Om mani padme hum Om mani padme hum Om +mani padme hum Om mani padme hum. + +Gate Gate paragate Gate Gate paragate Gate Gate paragate Gate Gate +paragate Gate Gate paragate Gate Gate paragate." } + + + +} diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm index 66286ca643..ab0ca1eaf1 100644 --- a/scm/define-markup-commands.scm +++ b/scm/define-markup-commands.scm @@ -371,9 +371,17 @@ determines the space between each markup in @var{args}." (remove ly:stencil-empty? stencils)))) -(def-markup-command (wordwrap layout props args) (markup-list?) - "Perform simple wordwrap on @var{args}" - +(define (wordwrap-stencils stencils + justify base-space line-width + ) + + "Perform simple wordwrap, return stencil of each line." + (define space (if justify + + ;; justify only stretches lines. + (* 0.7 base-space) + base-space)) + (define (take-list width space stencils accumulator accumulated-width) "Return (head-list . tail) pair, with head-list fitting into width" @@ -383,7 +391,6 @@ determines the space between each markup in @var{args}." ((first (car stencils)) (first-wid (cdr (ly:stencil-extent (car stencils) X))) (newwid (+ space first-wid accumulated-width)) - (word-space (chain-assoc-get 'word-space props)) ) (if @@ -396,24 +403,10 @@ determines the space between each markup in @var{args}." newwid) (cons accumulator stencils)) ))) - - (let* - ((line-width (chain-assoc-get 'linewidth props)) - (justify (chain-assoc-get 'word-wrap-justify props #f)) - (base-space (chain-assoc-get 'word-space props)) - (space (if justify - - ;; justify only stretches lines. - (* 0.7 base-space) - base-space)) - - (baseline-skip (chain-assoc-get 'baseline-skip props))) (let loop ((lines '()) - (todo - (remove ly:stencil-empty? - (map (lambda (m) (interpret-markup layout props m)) args)))) + (todo stencils)) (let* ((line-break (take-list line-width space todo @@ -426,6 +419,7 @@ determines the space between each markup in @var{args}." ((not justify) space) ;; don't stretch last line of paragraph. + ;; hmmm . bug - will overstretch the last line in some case. ((null? (cdr line-break)) base-space) ((null? line-stencils) 0.0) @@ -440,21 +434,71 @@ determines the space between each markup in @var{args}." (loop (cons line lines) (cdr line-break)) - (stack-lines DOWN 0.0 baseline-skip (reverse (cons line lines))) + (reverse (cons line lines)) )) - ))) - + )) + + +(define (wordwrap-markups layout props args justify) + (let* + ((baseline-skip (chain-assoc-get 'baseline-skip props)) + (line-width (chain-assoc-get 'linewidth props)) + (word-space (chain-assoc-get 'word-space props)) + (lines (wordwrap-stencils + (remove ly:stencil-empty? + (map (lambda (m) (interpret-markup layout props m)) args)) + justify word-space line-width) + )) + (stack-lines DOWN 0.0 baseline-skip lines))) (def-markup-command (justify layout props args) (markup-list?) + "Simple wordwrap" + + (wordwrap-markups layout props args #t)) + +(def-markup-command (wordwrap layout props args) (markup-list?) "Like wordwrap, but with lines stretched to justify the margins." - - (interpret-markup layout - (prepend-alist-chain 'word-wrap-justify #t props) - (list wordwrap-markup args) - )) + (wordwrap-markups layout props args #f)) + +(define (wordwrap-string layout props justify arg) + (let* + ((baseline-skip (chain-assoc-get 'baseline-skip props)) + (line-width (chain-assoc-get 'linewidth props)) + (word-space (chain-assoc-get 'word-space props)) + (para-strings (regexp-split arg "\n[ \t\n]*\n[ \t\n]*")) + + (list-para-words (map (lambda (str) + (regexp-split str "[ \t\n]+")) + para-strings)) + (para-lines (map (lambda (words) + (let* + ((stencils + (remove + ly:stencil-empty? (map + (lambda (x) + (interpret-markup layout props x)) + words))) + (lines (wordwrap-stencils stencils + justify word-space line-width))) + + lines)) + + list-para-words))) + + (stack-lines DOWN 0.0 baseline-skip (apply append para-lines)))) + + +(def-markup-command (wordwrap-string layout props arg) (string?) + "Wordwrap a string. Paragraphs may be separated with double newlines" + (wordwrap-string layout props #f arg)) + +(def-markup-command (justify-string layout props arg) (string?) + "Justify a string. Paragraphs may be separated with double newlines" + (wordwrap-string layout props #t arg)) + (def-markup-command (combine layout props m1 m2) (markup? markup?) "Print two markups on top of each other." (let* ((s1 (interpret-markup layout props m1)) diff --git a/scm/lily-library.scm b/scm/lily-library.scm index 937564844a..5b08393b80 100644 --- a/scm/lily-library.scm +++ b/scm/lily-library.scm @@ -314,6 +314,26 @@ possibly turned off." (define-public (string-regexp-substitute a b str) (regexp-substitute/global #f a str 'pre b 'post)) + +(define (regexp-split str regex) + (define matches '()) + (define end-of-prev-match 0) + (define (notice match) + (set! matches (cons (substring (match:string match) + end-of-prev-match + (match:start match)) + matches)) + (set! end-of-prev-match (match:end match))) + + (regexp-substitute/global #f regex str notice 'post) + + (if (< end-of-prev-match (string-length str)) + (set! + matches + (cons (substring str end-of-prev-match (string-length str)) matches))) + + (reverse matches)) + ;;;;;;;;;;;;;;;; ; other (define (sign x) -- 2.39.5