X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Fdefine-markup-commands.scm;h=57e2e8893a26334a2d5af498ba518668b158ed03;hb=bf7f767457c037009f996f5b26c8f1ba49488751;hp=3fc1e573bfb3baea5838f387b15720ecd43cfba8;hpb=c39d188d28fdc84cef8cbaea7b8d6e2fb718c30f;p=lilypond.git diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm index 3fc1e573bf..57e2e8893a 100644 --- a/scm/define-markup-commands.scm +++ b/scm/define-markup-commands.scm @@ -1,6 +1,6 @@ ;;;; This file is part of LilyPond, the GNU music typesetter. ;;;; -;;;; Copyright (C) 2000--2014 Han-Wen Nienhuys +;;;; Copyright (C) 2000--2015 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen ;;;; ;;;; LilyPond is free software: you can redistribute it and/or modify @@ -115,6 +115,31 @@ empty-interval empty-interval)) (define-public point-stencil (ly:make-stencil "" '(0 . 0) '(0 . 0))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; line has to come early since it is often used implicitly from the +;; markup macro since \markup { a b c } -> \markup \line { a b c } +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define-markup-command (line layout props args) + (markup-list?) + #:category align + #:properties ((word-space) + (text-direction RIGHT)) + "Put @var{args} in a horizontal line. The property @code{word-space} +determines the space between markups in @var{args}. + +@lilypond[verbatim,quote] +\\markup { + \\line { + one two three + } +} +@end lilypond" + (let ((stencils (interpret-markup-list layout props args))) + (if (= text-direction LEFT) + (set! stencils (reverse stencils))) + (stack-stencil-line word-space stencils))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; geometric shapes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -484,6 +509,16 @@ in the PDF backend. (ly:stencil-add (ly:make-stencil link-expr xextent yextent) stil))) +(define-public (book-first-page layout props) + "Return the @code{'first-page-number} of the entire book" + (define (ancestor layout) + "Return the topmost layout ancestor" + (let ((parent (ly:output-def-parent layout))) + (if (not (ly:output-def? parent)) + layout + (ancestor parent)))) + (ly:output-def-lookup (ancestor layout) 'first-page-number)) + (define-markup-command (with-link layout props label arg) (symbol? markup?) #:category other @@ -504,18 +539,23 @@ only works in the PDF backend. (x-ext (ly:stencil-extent arg-stencil X)) (y-ext (ly:stencil-extent arg-stencil Y))) (ly:stencil-add - (ly:make-stencil - `(delay-stencil-evaluation - ,(delay (let* ((table (ly:output-def-lookup layout 'label-page-table)) - (page-number (if (list? table) - (assoc-get label table) - #f))) - (list 'page-link page-number - `(quote ,x-ext) `(quote ,y-ext))))) - x-ext - y-ext) - arg-stencil))) - + (ly:make-stencil + `(delay-stencil-evaluation + ,(delay (let* ((table (ly:output-def-lookup layout 'label-page-table)) + (table-page-number + (if (list? table) + (assoc-get label table) + #f)) + (first-page-number (book-first-page layout props)) + (current-page-number + (if table-page-number + (1+ (- table-page-number first-page-number)) + #f))) + (list 'page-link current-page-number + `(quote ,x-ext) `(quote ,y-ext))))) + x-ext + y-ext) + arg-stencil))) (define-markup-command (beam layout props width slope thickness) (number? number? number?) @@ -568,12 +608,12 @@ thickness, and @code{offset} to determine line y-offset. @end lilypond" (let* ((thick (ly:output-def-lookup layout 'line-thickness)) (underline-thick (* thickness thick)) - (markup (interpret-markup layout props arg)) - (x1 (car (ly:stencil-extent markup X))) - (x2 (cdr (ly:stencil-extent markup X))) + (m (interpret-markup layout props arg)) + (x1 (car (ly:stencil-extent m X))) + (x2 (cdr (ly:stencil-extent m X))) (y (* thick (- offset))) (line (make-line-stencil underline-thick x1 y x2 y))) - (ly:stencil-add markup line))) + (ly:stencil-add m line))) (define-markup-command (box layout props arg) (markup?) @@ -682,6 +722,7 @@ Rotate object with @var{ang} degrees around its center. (define-markup-command (whiteout layout props arg) (markup?) #:category other + #:properties ((thickness 3)) " @cindex adding a white background to text @@ -691,10 +732,34 @@ Provide a white background for @var{arg}. \\markup { \\combine \\filled-box #'(-1 . 10) #'(-3 . 4) #1 - \\whiteout whiteout + \\override #'(thickness . 1.5) \\whiteout whiteout +} +@end lilypond" + (stencil-whiteout + (interpret-markup layout props arg) + (* thickness + (ly:output-def-lookup layout 'line-thickness)))) + +(define-markup-command (whiteout-box layout props arg) + (markup?) + #:category other + #:properties ((thickness 0)) + " +@cindex adding a rectangular white background to text + +Provide a rectangular white background for @var{arg}. + +@lilypond[verbatim,quote] +\\markup { + \\combine + \\filled-box #'(-1 . 10) #'(-3 . 4) #1 + \\override #'(thickness . 1.5) \\whiteout-box whiteout-box } @end lilypond" - (stencil-whiteout (interpret-markup layout props arg))) + (stencil-whiteout-box + (interpret-markup layout props arg) + (* thickness + (ly:output-def-lookup layout 'line-thickness)))) (define-markup-command (pad-markup layout props amount arg) (number? markup?) @@ -1132,55 +1197,30 @@ the use of @code{\\simple} is unnecessary. @end lilypond" (interpret-markup layout props str)) -(define-markup-command (tied-lyric layout props str) - (string?) - #:category music - #:properties ((word-space)) - " -@cindex simple text strings with tie characters - -Like simple-markup, but use tie characters for @q{~} tilde symbols. +(define-markup-command (first-visible layout props args) + (markup-list?) + #:category other + "Use the first markup in @var{args} that yields a non-empty stencil +and ignore the rest. @lilypond[verbatim,quote] -\\markup \\column { - \\tied-lyric #\"Siam navi~all'onde~algenti Lasciate~in abbandono\" - \\tied-lyric #\"Impetuosi venti I nostri~affetti sono\" - \\tied-lyric #\"Ogni diletto~e scoglio Tutta la vita~e~un mar.\" +\\markup { + \\first-visible { + \\fromproperty #'header:composer + \\italic Unknown + } } @end lilypond" - (define (replace-ties tie str) - (if (string-contains str "~") - (let* - ((half-space (/ word-space 2)) - (parts (string-split str #\~)) - (tie-str (markup #:hspace half-space - #:musicglyph tie - #:hspace half-space)) - (joined (list-join parts tie-str))) - (make-concat-markup joined)) - str)) - - (define short-tie-regexp (make-regexp "~[^.]~")) - (define (match-short str) (regexp-exec short-tie-regexp str)) - - (define (replace-short str mkp) - (let ((match (match-short str))) - (if (not match) - (make-concat-markup (list - mkp - (replace-ties "ties.lyric.default" str))) - (let ((new-str (match:suffix match)) - (new-mkp (make-concat-markup (list - mkp - (replace-ties "ties.lyric.default" - (match:prefix match)) - (replace-ties "ties.lyric.short" - (match:substring match)))))) - (replace-short new-str new-mkp))))) - - (interpret-markup layout - props - (replace-short str (markup)))) + (define (false-if-empty stencil) + (if (ly:stencil-empty? stencil) #f stencil)) + (or + (any + (lambda (m) + (if (markup? m) + (false-if-empty (interpret-markup layout props m)) + (any false-if-empty (interpret-markup-list layout props (list m))))) + args) + empty-stencil)) (define-public empty-markup (make-simple-markup "")) @@ -1248,15 +1288,14 @@ words varies according to their relative lengths." (let* ((orig-stencils (interpret-markup-list layout props args)) (stencils (map (lambda (stc) - (if (ly:stencil-empty? stc) - point-stencil + (if (ly:stencil-empty? stc X) + (ly:make-stencil (ly:stencil-expr stc) + '(0 . 0) (ly:stencil-extent stc Y)) stc)) orig-stencils)) (text-widths (map (lambda (stc) - (if (ly:stencil-empty? stc) - 0.0 - (interval-length (ly:stencil-extent stc X)))) + (interval-length (ly:stencil-extent stc X))) stencils)) (text-width (apply + text-widths)) (word-count (length stencils)) @@ -1351,26 +1390,6 @@ space. If there are no arguments, return an empty stencil. (justify-line-helper layout props args text-direction word-space line-width #t)) -(define-markup-command (line layout props args) - (markup-list?) - #:category align - #:properties ((word-space) - (text-direction RIGHT)) - "Put @var{args} in a horizontal line. The property @code{word-space} -determines the space between markups in @var{args}. - -@lilypond[verbatim,quote] -\\markup { - \\line { - one two three - } -} -@end lilypond" - (let ((stencils (interpret-markup-list layout props args))) - (if (= text-direction LEFT) - (set! stencils (reverse stencils))) - (stack-stencil-line word-space stencils))) - (define-markup-command (concat layout props args) (markup-list?) #:category align @@ -1420,8 +1439,8 @@ equivalent to @code{\"fi\"}. "Perform simple wordwrap, return stencil of each line." (define space (if justify ;; justify only stretches lines. - (* 0.7 base-space) - base-space)) + (* 0.7 base-space) + base-space)) (define (stencil-len s) (interval-end (ly:stencil-extent s X))) (define (maybe-shift line) @@ -1721,11 +1740,7 @@ the line width, where @var{X} is the number of staff spaces. Print two markups on top of each other. Note: @code{\\combine} cannot take a list of markups enclosed in -curly braces as an argument; the follow example will not compile: - -@example -\\combine @{ a list @} -@end example +curly braces as an argument; for this purpose use @code{\\overlay} instead. @lilypond[verbatim,quote] \\markup { @@ -1740,6 +1755,27 @@ curly braces as an argument; the follow example will not compile: (s2 (interpret-markup layout props arg2))) (ly:stencil-add s1 s2))) +(define-markup-command (overlay layout props args) + (markup-list?) + #:category align + " +@cindex merging text + +Takes a list of markups combining them. + +@lilypond[verbatim,quote] +\\markup { + \\fontsize #5 + \\override #'(thickness . 2) + \\overlay { + \\draw-line #'(0 . 4) + \\arrow-head #Y #DOWN ##f + \\translate #'(0 . 4)\\arrow-head #Y #UP ##f + } +} +@end lilypond" + (apply ly:stencil-add (interpret-markup-list layout props args))) + ;; ;; TODO: should extract baseline-skip from each argument somehow.. ;; @@ -2423,7 +2459,7 @@ may be any property supported by @rinternals{font-interface}, (define-markup-command (abs-fontsize layout props size arg) (number? markup?) #:category font - "Use @var{size} as the absolute font size to display @var{arg}. + "Use @var{size} as the absolute font size (in points) to display @var{arg}. Adjusts @code{baseline-skip} and @code{word-space} accordingly. @lilypond[verbatim,quote] @@ -3041,6 +3077,56 @@ Draw @var{arg} in color specified by @var{color}. (ly:stencil-extent stil X) (ly:stencil-extent stil Y)))) +(define-markup-command (tied-lyric layout props str) + (string?) + #:category music + #:properties ((word-space)) + " +@cindex simple text strings with tie characters + +Like simple-markup, but use tie characters for @q{~} tilde symbols. + +@lilypond[verbatim,quote] +\\markup \\column { + \\tied-lyric #\"Siam navi~all'onde~algenti Lasciate~in abbandono\" + \\tied-lyric #\"Impetuosi venti I nostri~affetti sono\" + \\tied-lyric #\"Ogni diletto~e scoglio Tutta la vita~e~un mar.\" +} +@end lilypond" + (define (replace-ties tie str) + (if (string-contains str "~") + (let* + ((half-space (/ word-space 2)) + (parts (string-split str #\~)) + (tie-str (markup #:hspace half-space + #:musicglyph tie + #:hspace half-space)) + (joined (list-join parts tie-str))) + (make-concat-markup joined)) + str)) + + (define short-tie-regexp (make-regexp "~[^.]~")) + (define (match-short str) (regexp-exec short-tie-regexp str)) + + (define (replace-short str mkp) + (let ((match (match-short str))) + (if (not match) + (make-concat-markup (list + mkp + (replace-ties "ties.lyric.default" str))) + (let ((new-str (match:suffix match)) + (new-mkp (make-concat-markup (list + mkp + (replace-ties "ties.lyric.default" + (match:prefix match)) + (replace-ties "ties.lyric.short" + (match:substring match)))))) + (replace-short new-str new-mkp))))) + + (interpret-markup layout + props + (replace-short str (markup)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; glyphs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -3439,24 +3525,17 @@ Supported flag-styles are @code{default}, @code{old-straight-flag}, (thickness-offset (cons 0 (* -1 thickness dir))) (spacing (* -1 flag-spacing factor dir)) (start (cons (- half-stem-thickness) (* half-stem-thickness dir))) - ;; The points of a round-filled-polygon need to be given in - ;; clockwise order, otherwise the polygon will be enlarged by - ;; blot-size*2! - (points (if stem-up - (list start - flag-end - (offset-add flag-end thickness-offset) - (offset-add start thickness-offset)) - (list start - (offset-add start thickness-offset) - (offset-add flag-end thickness-offset) - flag-end))) + (points (list start + flag-end + (offset-add flag-end thickness-offset) + (offset-add start thickness-offset))) (stencil (ly:round-filled-polygon points half-stem-thickness)) ;; Log for 1/8 is 3, so we need to subtract 3 (flag-stencil (buildflags stencil (- log 3) stencil spacing))) flag-stencil)) - (let* ((font (ly:paper-get-font layout (cons '((font-encoding . fetaMusic)) + (let* ((font (ly:paper-get-font layout (cons '((font-encoding . fetaMusic) + (font-name . #f)) props))) (size-factor (magstep font-size)) (blot (ly:output-def-lookup layout 'blot-diameter)) @@ -3672,7 +3751,9 @@ A rest or multi-measure-rest symbol. (let* ((font (ly:paper-get-font layout - (cons '((font-encoding . fetaMusic)) props))) + (cons '((font-encoding . fetaMusic) + (font-name . #f)) + props))) (rest-glyph-name (let ((result (get-glyph-name font @@ -3880,7 +3961,7 @@ an inverted glyph. Note that within music, one would usually use the @code{\\fermata} articulation instead of a markup. @lilypond[verbatim,quote] - { c1^\\markup \\fermata d1_\\markup \\fermata } + { c''1^\\markup \\fermata d''1_\\markup \\fermata } \\markup { \\fermata \\override #`(direction . ,DOWN) \\fermata } @end lilypond @@ -4201,7 +4282,7 @@ a column containing several lines of text. } } @end lilypond" - (let* ((markup (interpret-markup layout props arg)) + (let* ((m (interpret-markup layout props arg)) (scaled-width (* size width)) (scaled-thickness (* (chain-assoc-get 'line-thickness props 0.1) @@ -4211,7 +4292,7 @@ a column containing several lines of text. (* (/ 4 3.0) scaled-width))) (padding (chain-assoc-get 'padding props half-thickness))) (parenthesize-stencil - markup half-thickness scaled-width angularity padding))) + m half-thickness scaled-width angularity padding))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -4227,7 +4308,11 @@ a column containing several lines of text. Reference to a page number. @var{label} is the label set on the referenced page (using the @code{\\label} command), @var{gauge} a markup used to estimate the maximum width of the page number, and @var{default} the value to display -when @var{label} is not found." +when @var{label} is not found. + +(If the current book or bookpart is set to use roman numerals for page numbers, +the reference will be formatted accordingly -- in which case the @var{gauge}'s +width may require additional tweaking.)" (let* ((gauge-stencil (interpret-markup layout props gauge)) (x-ext (ly:stencil-extent gauge-stencil X)) (y-ext (ly:stencil-extent gauge-stencil Y))) @@ -4240,7 +4325,10 @@ when @var{label} is not found." (page-number (if (list? table) (assoc-get label table) #f)) - (page-markup (if page-number (format #f "~a" page-number) default)) + (number-type (ly:output-def-lookup layout 'page-number-type)) + (page-markup (if page-number + (number-format number-type page-number) + default)) (page-stencil (interpret-markup layout props page-markup)) (gap (- (interval-length x-ext) (interval-length (ly:stencil-extent page-stencil X)))))