From: Nicolas Sceaux Date: Sun, 27 Apr 2008 16:56:36 +0000 (+0200) Subject: Markup command documentation: categories and properties X-Git-Tag: release/2.11.46-1~35^2~1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=79aa415228f9193801a7d31aa595a0411f19288b;p=lilypond.git Markup command documentation: categories and properties Add a category argument to define-builtin-markup-command, so that markup commands are sorted by categories in the documentation. Also add a properties argument, which is used in the markup command code to create bindings (extracting the properties from the props argument), and in the documentation to list the used properties. --- diff --git a/Documentation/user/notation-appendices.itely b/Documentation/user/notation-appendices.itely index ae85e37205..9113aff48c 100644 --- a/Documentation/user/notation-appendices.itely +++ b/Documentation/user/notation-appendices.itely @@ -212,19 +212,8 @@ The following styles may be used for note heads. @lilypondfile[noindent]{note-head-style.ly} - -@node Text markup commands -@appendixsec Text markup commands - -The following commands can all be used inside @code{\markup @{ @}}. - @include markup-commands.tely -@node Text markup list commands -@appendixsec Text markup list commands - -The following commands can all be used with @code{\markuplines}. - @include markup-list-commands.tely @node List of articulations diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm index 71fe0f5a66..d4d6784692 100644 --- a/scm/define-markup-commands.scm +++ b/scm/define-markup-commands.scm @@ -25,29 +25,28 @@ (define-builtin-markup-command (draw-line layout props dest) (number-pair?) + graphic + ((thickness 1)) " @cindex drawing lines within text -A simple line. Uses the @code{thickness} property." - (let* - ((th (* - (ly:output-def-lookup layout 'line-thickness) - (chain-assoc-get 'thickness props 1))) - (x (car dest)) - (y (cdr dest)) - (s (ly:make-stencil - `(draw-line - ,th - 0 0 - ,x ,y) - - (cons (min x 0) (max x 0)) - (cons (min y 0) (max y 0))))) - - s)) +A simple line." + (let ((th (* (ly:output-def-lookup layout 'line-thickness) + thickness)) + (x (car dest)) + (y (cdr dest))) + (ly:make-stencil + `(draw-line + ,th + 0 0 + ,x ,y) + (cons (min x 0) (max x 0)) + (cons (min y 0) (max y 0))))) (define-builtin-markup-command (draw-circle layout props radius thickness fill) (number? number? boolean?) + graphic + () " @cindex drawing circles within text @@ -59,7 +58,12 @@ optionally filled. @end lilypond" (make-circle-stencil radius thickness fill)) -(define-builtin-markup-command (triangle layout props filled) (boolean?) +(define-builtin-markup-command (triangle layout props filled) + (boolean?) + graphic + ((thickness 0.1) + (font-size 0) + (baseline-skip 2)) " @cindex drawing triangles within text @@ -68,44 +72,39 @@ A triangle, either filled or empty. @lilypond[verbatim,quote] \\markup { \\triangle ##f \\triangle ##t } @end lilypond" - (let* - ((th (chain-assoc-get 'thickness props 0.1)) - (size (chain-assoc-get 'font-size props 0)) - (ex (* (magstep size) - 0.8 - (chain-assoc-get 'baseline-skip props 2)))) - + (let ((ex (* (magstep font-size) 0.8 baseline-skip))) (ly:make-stencil `(polygon '(0.0 0.0 - ,ex 0.0 - ,(* 0.5 ex) - ,(* 0.86 ex)) - ,th - ,filled) - + ,ex 0.0 + ,(* 0.5 ex) + ,(* 0.86 ex)) + ,thickness + ,filled) (cons 0 ex) - (cons 0 (* .86 ex)) - ))) - -(define-builtin-markup-command (circle layout props arg) (markup?) + (cons 0 (* .86 ex))))) + +(define-builtin-markup-command (circle layout props arg) + (markup?) + graphic + ((thickness 1) + (font-size 0) + (circle-padding 0.2)) " @cindex circling text Draw a circle around @var{arg}. Use @code{thickness}, @code{circle-padding} and @code{font-size} properties to determine line thickness and padding around the markup." - - (let* ((th - (* (ly:output-def-lookup layout 'line-thickness) - (chain-assoc-get 'thickness props 1))) - (size (chain-assoc-get 'font-size props 0)) - (pad - (* (magstep size) - (chain-assoc-get 'circle-padding props 0.2))) - (m (interpret-markup layout props arg))) + (let ((th (* (ly:output-def-lookup layout 'line-thickness) + thickness)) + (pad (* (magstep font-size) circle-padding)) + (m (interpret-markup layout props arg))) (circle-stencil m th pad))) -(define-builtin-markup-command (with-url layout props url arg) (string? markup?) +(define-builtin-markup-command (with-url layout props url arg) + (string? markup?) + other + () " @cindex inserting URL links into text @@ -128,6 +127,8 @@ the PDF backend. (define-builtin-markup-command (beam layout props width slope thickness) (number? number? number?) + graphic + () " @cindex drawing beams within text @@ -148,43 +149,49 @@ Create a beam with the specified parameters." (cons (+ (- half) (car yext)) (+ half (cdr yext)))))) -(define-builtin-markup-command (underline layout props arg) (markup?) +(define-builtin-markup-command (underline layout props arg) + (markup?) + other + ((thickness 1)) " @cindex underlining text Underline @var{arg}. Looks at @code{thickness} to determine line thickness and y offset." - (let* ((thick (* - (ly:output-def-lookup layout 'line-thickness) - (chain-assoc-get 'thickness props 1))) - (markup (interpret-markup layout props arg)) - (x1 (car (ly:stencil-extent markup X))) - (x2 (cdr (ly:stencil-extent markup X))) - (y (* thick -2)) - (line (ly:make-stencil - `(draw-line ,thick ,x1 ,y ,x2 ,y) - (cons (min x1 0) (max x2 0)) - (cons thick thick)))) - (ly:stencil-add markup line))) - -(define-builtin-markup-command (box layout props arg) (markup?) + (let* ((thick (* (ly:output-def-lookup layout 'line-thickness) + thickness)) + (markup (interpret-markup layout props arg)) + (x1 (car (ly:stencil-extent markup X))) + (x2 (cdr (ly:stencil-extent markup X))) + (y (* thick -2)) + (line (ly:make-stencil + `(draw-line ,thick ,x1 ,y ,x2 ,y) + (cons (min x1 0) (max x2 0)) + (cons thick thick)))) + (ly:stencil-add markup line))) + +(define-builtin-markup-command (box layout props arg) + (markup?) + other + ((thickness 1) + (font-size 0) + (box-padding 0.2)) " @cindex enclosing text within a box Draw a box round @var{arg}. Looks at @code{thickness}, @code{box-padding} and @code{font-size} properties to determine line thickness and padding around the markup." - (let* ((th (* - (ly:output-def-lookup layout 'line-thickness) - (chain-assoc-get 'thickness props 1))) - (size (chain-assoc-get 'font-size props 0)) - (pad (* (magstep size) - (chain-assoc-get 'box-padding props 0.2))) - (m (interpret-markup layout props arg))) + (let* ((th (* (ly:output-def-lookup layout 'line-thickness) + thickness)) + (pad (* (magstep font-size) box-padding)) + (m (interpret-markup layout props arg))) (box-stencil m th pad))) (define-builtin-markup-command (filled-box layout props xext yext blot) (number-pair? number-pair? number?) + other + () " @cindex drawing solid boxes within text @cindex drawing boxes with rounded corners @@ -200,7 +207,13 @@ circle of diameter@tie{}0 (i.e. sharp corners)." (ly:round-filled-box xext yext blot)) -(define-builtin-markup-command (rounded-box layout props arg) (markup?) +(define-builtin-markup-command (rounded-box layout props arg) + (markup?) + other + ((thickness 1) + (corner-radius 1) + (font-size 0) + (box-padding 0.5)) "@cindex enclosing text in a bow with rounded corners @cindex drawing boxes with rounded corners around text Draw a box with rounded corners around @var{arg}. Looks at @code{thickness}, @@ -212,18 +225,17 @@ makes possible to define another shape for the corners (default is 1). c^\\markup{ \\rounded-box Overtura } c,8. c16 c4 r @end lilypond" - (let* ((th (* - (ly:output-def-lookup layout 'line-thickness) - (chain-assoc-get 'thickness props 1))) - (rad (chain-assoc-get 'corner-radius props 1)) - (size (chain-assoc-get 'font-size props 0)) - (pad (* (magstep size) - (chain-assoc-get 'box-padding props 0.5))) - (m (interpret-markup layout props arg))) - (ly:stencil-add (rounded-box-stencil m th pad rad) - m))) - -(define-builtin-markup-command (rotate layout props ang arg) (number? markup?) + (let ((th (* (ly:output-def-lookup layout 'line-thickness) + thickness)) + (pad (* (magstep font-size) box-padding)) + (m (interpret-markup layout props arg))) + (ly:stencil-add (rounded-box-stencil m th pad corner-radius) + m))) + +(define-builtin-markup-command (rotate layout props ang arg) + (number? markup?) + other + () " @cindex rotating text @@ -231,14 +243,20 @@ Rotate object with @var{ang} degrees around its center." (let* ((stil (interpret-markup layout props arg))) (ly:stencil-rotate stil ang 0 0))) -(define-builtin-markup-command (whiteout layout props arg) (markup?) +(define-builtin-markup-command (whiteout layout props arg) + (markup?) + other + () " @cindex adding a white background to text Provide a white background for @var{arg}." (stencil-whiteout (interpret-markup layout props arg))) -(define-builtin-markup-command (pad-markup layout props padding arg) (number? markup?) +(define-builtin-markup-command (pad-markup layout props padding arg) + (number? markup?) + other + () " @cindex padding text @cindex putting space around text @@ -258,7 +276,10 @@ Add space around a markup object." ;; space ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-builtin-markup-command (strut layout props) () +(define-builtin-markup-command (strut layout props) + () + other + () " @cindex creating vertical spaces in text @@ -270,7 +291,10 @@ Create a box of the same height as the space in the current font." ))) ;; todo: fix negative space -(define-builtin-markup-command (hspace layout props amount) (number?) +(define-builtin-markup-command (hspace layout props amount) + (number?) + other + () " @cindex creating horizontal spaces in text @@ -292,7 +316,10 @@ normally inserted before elements on a line." ;; importing graphics. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-builtin-markup-command (stencil layout props stil) (ly:stencil?) +(define-builtin-markup-command (stencil layout props stil) + (ly:stencil?) + other + () " @cindex importing stencils into text @@ -314,7 +341,10 @@ Use a stencil as markup." #f))) -(define-builtin-markup-command (epsfile layout props axis size file-name) (number? number? string?) +(define-builtin-markup-command (epsfile layout props axis size file-name) + (number? number? string?) + graphic + () " @cindex inlining an Encapsulated PostScript image @@ -325,7 +355,10 @@ Inline an EPS image. The image is scaled along @var{axis} to (eps-file->stencil axis size file-name) )) -(define-builtin-markup-command (postscript layout props str) (string?) +(define-builtin-markup-command (postscript layout props str) + (string?) + graphic + () " @cindex inserting PostScript directly into text @@ -364,7 +397,10 @@ grestore str)) '(0 . 0) '(0 . 0))) -(define-builtin-markup-command (score layout props score) (ly:score?) +(define-builtin-markup-command (score layout props score) + (ly:score?) + music + () " @cindex inserting music into text @@ -378,7 +414,10 @@ Inline an image of music." (ly:warning (_"no systems found in \\score markup, does it have a \\layout block?")) empty-stencil)))) -(define-builtin-markup-command (null layout props) () +(define-builtin-markup-command (null layout props) + () + other + () " @cindex creating empty text objects @@ -389,7 +428,10 @@ An empty markup with extents of a single point." ;; basic formatting. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-builtin-markup-command (simple layout props str) (string?) +(define-builtin-markup-command (simple layout props str) + (string?) + other + () " @cindex simple text strings @@ -397,7 +439,10 @@ A simple text string; @code{\\markup @{ foo @}} is equivalent with @code{\\markup @{ \\simple #\"foo\" @}}." (interpret-markup layout props str)) -(define-builtin-markup-command (tied-lyric layout props str) (string?) +(define-builtin-markup-command (tied-lyric layout props str) + (string?) + other + () " @cindex simple text strings with tie characters @@ -452,6 +497,10 @@ Like simple-markup, but use tie characters for @q{~} tilde symbols." (define-builtin-markup-command (fill-line layout props markups) (markup-list?) + align + ((text-direction RIGHT) + (word-space 1) + (line-width #f)) "Put @var{markups} in a horizontal line of width @var{line-width}. The markups are spaced or flushed to fill the entire line. If there are no arguments, return an empty stencil." @@ -469,12 +518,9 @@ If there are no arguments, return an empty stencil." (interval-length (ly:stencil-extent stc X)))) stencils)) (text-width (apply + text-widths)) - (text-dir (chain-assoc-get 'text-direction props RIGHT)) (word-count (length stencils)) - (word-space (chain-assoc-get 'word-space props 1)) (prop-line-width (chain-assoc-get 'line-width props #f)) - (line-width (if prop-line-width prop-line-width - (ly:output-def-lookup layout 'line-width))) + (line-width (or line-width (ly:output-def-lookup layout 'line-width))) (fill-space (cond ((= word-count 1) @@ -500,7 +546,7 @@ If there are no arguments, return an empty stencil." point-stencil) stencils))) - (if (= text-dir LEFT) + (if (= text-direction LEFT) (set! line-stencils (reverse line-stencils))) (if (null? (remove ly:stencil-empty? orig-stencils)) @@ -508,23 +554,24 @@ If there are no arguments, return an empty stencil." (stack-stencils-padding-list X RIGHT fill-space-normal line-stencils)))) -(define-builtin-markup-command (line layout props args) (markup-list?) +(define-builtin-markup-command (line layout props args) + (markup-list?) + align + ((word-space) + (text-direction RIGHT)) "Put @var{args} in a horizontal line. The property @code{word-space} determines the space between each markup in @var{args}." - (let* - ((stencils (interpret-markup-list layout props args)) - (space (chain-assoc-get 'word-space props)) - (text-dir (chain-assoc-get 'text-direction props RIGHT)) - ) - - (if (= text-dir LEFT) - (set! stencils (reverse stencils))) - + (let ((stencils (interpret-markup-list layout props args))) + (if (= text-direction LEFT) + (set! stencils (reverse stencils))) (stack-stencil-line - space + word-space (remove ly:stencil-empty? stencils)))) -(define-builtin-markup-command (concat layout props args) (markup-list?) +(define-builtin-markup-command (concat layout props args) + (markup-list?) + other + () " @cindex concatenating text @cindex ligatures in text @@ -553,167 +600,166 @@ equivalent to @code{\"fi\"}." (concat-string-args args))))) (define (wordwrap-stencils stencils - justify base-space line-width text-dir) + justify base-space line-width text-dir) "Perform simple wordwrap, return stencil of each line." (define space (if justify - - ;; justify only stretches lines. + ;; 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" (if (null? stencils) (cons accumulator stencils) - (let* - ((first (car stencils)) - (first-wid (cdr (ly:stencil-extent (car stencils) X))) - (newwid (+ space first-wid accumulated-width)) - ) - - (if - (or (null? accumulator) - (< newwid width)) - - (take-list width space - (cdr stencils) - (cons first accumulator) - newwid) - (cons accumulator stencils)) - ))) - - (let loop - ((lines '()) - (todo stencils)) - - (let* - ((line-break (take-list line-width space todo - '() 0.0)) + (let* ((first (car stencils)) + (first-wid (cdr (ly:stencil-extent (car stencils) X))) + (newwid (+ space first-wid accumulated-width))) + (if (or (null? accumulator) + (< newwid width)) + (take-list width space + (cdr stencils) + (cons first accumulator) + newwid) + (cons accumulator stencils))))) + (let loop ((lines '()) + (todo stencils)) + (let* ((line-break (take-list line-width space todo + '() 0.0)) (line-stencils (car line-break)) - (space-left (- line-width (apply + (map (lambda (x) (cdr (ly:stencil-extent x X))) - line-stencils)))) - - (line-word-space (cond - ((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) - ((null? (cdr line-stencils)) 0.0) - (else (/ space-left (1- (length line-stencils)))))) - - (line (stack-stencil-line - line-word-space - (if (= text-dir RIGHT) - (reverse line-stencils) - line-stencils)))) - - (if (pair? (cdr line-break)) - (loop (cons line lines) - (cdr line-break)) - - (begin - (if (= text-dir LEFT) - (set! line - (ly:stencil-translate-axis line - (- line-width (interval-end (ly:stencil-extent line X))) - X))) - (reverse (cons line lines)) - - ))) - - )) - -(define (wordwrap-markups layout props args justify) - (let* - ((prop-line-width (chain-assoc-get 'line-width props #f)) - (line-width (if prop-line-width prop-line-width - (ly:output-def-lookup layout 'line-width))) - (word-space (chain-assoc-get 'word-space props)) - (text-dir (chain-assoc-get 'text-direction props RIGHT))) - (wordwrap-stencils (remove ly:stencil-empty? - (interpret-markup-list layout props args)) - justify word-space line-width - text-dir))) - -(define-builtin-markup-command (justify layout props args) (markup-list?) + (space-left (- line-width + (apply + (map (lambda (x) (cdr (ly:stencil-extent x X))) + line-stencils)))) + (line-word-space (cond ((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) + ((null? (cdr line-stencils)) 0.0) + (else (/ space-left (1- (length line-stencils)))))) + (line (stack-stencil-line line-word-space + (if (= text-dir RIGHT) + (reverse line-stencils) + line-stencils)))) + (if (pair? (cdr line-break)) + (loop (cons line lines) + (cdr line-break)) + (begin + (if (= text-dir LEFT) + (set! line + (ly:stencil-translate-axis + line + (- line-width (interval-end (ly:stencil-extent line X))) + X))) + (reverse (cons line lines))))))) + +(define-builtin-markup-list-command (wordwrap-internal layout props justify args) + (boolean? markup-list?) + ((line-width #f) + (word-space) + (text-direction RIGHT)) + "Internal markup list command used to define @code{\\justify} and @code{\\wordwrap}." + (wordwrap-stencils (remove ly:stencil-empty? + (interpret-markup-list layout props args)) + justify + word-space + (or line-width + (ly:output-def-lookup layout 'line-width)) + text-direction)) + +(define-builtin-markup-command (justify layout props args) + (markup-list?) + align + ((baseline-skip) + wordwrap-internal-markup-list) " @cindex justifying text Like wordwrap, but with lines stretched to justify the margins. Use @code{\\override #'(line-width . @var{X})} to set the line width; @var{X}@tie{}is the number of staff spaces." - (stack-lines DOWN 0.0 (chain-assoc-get 'baseline-skip props) - (wordwrap-markups layout props args #t))) + (stack-lines DOWN 0.0 baseline-skip + (wordwrap-internal-markup-list layout props #t args))) -(define-builtin-markup-command (wordwrap layout props args) (markup-list?) +(define-builtin-markup-command (wordwrap layout props args) + (markup-list?) + align + ((baseline-skip) + wordwrap-internal-markup-list) "Simple wordwrap. Use @code{\\override #'(line-width . @var{X})} to set the line width, where @var{X} is the number of staff spaces." - (stack-lines DOWN 0.0 (chain-assoc-get 'baseline-skip props) - (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 'line-width props)) - (word-space (chain-assoc-get 'word-space props)) - - (para-strings (regexp-split - (string-regexp-substitute "\r" "\n" - (string-regexp-substitute "\r\n" "\n" arg)) - "\n[ \t\n]*\n[ \t\n]*")) - - (text-dir (chain-assoc-get 'text-direction props RIGHT)) - (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 text-dir - ))) - - lines)) - - list-para-words))) - - (stack-lines DOWN 0.0 baseline-skip (apply append para-lines)))) - -(define-builtin-markup-command (wordwrap-string layout props arg) (string?) + (stack-lines DOWN 0.0 baseline-skip + (wordwrap-internal-markup-list layout props #f args))) + +(define-builtin-markup-list-command (wordwrap-string-internal layout props justify arg) + (boolean? string?) + ((line-width) + (word-space) + (text-direction RIGHT)) + "Internal markup list command used to define @code{\\justify-string} and +@code{\\wordwrap-string}." + (let* ((para-strings (regexp-split + (string-regexp-substitute + "\r" "\n" + (string-regexp-substitute "\r\n" "\n" 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)))) + (wordwrap-stencils stencils + justify word-space + line-width text-direction))) + list-para-words))) + (apply append para-lines))) + +(define-builtin-markup-command (wordwrap-string layout props arg) + (string?) + align + ((baseline-skip) + wordwrap-string-internal-markup-list) "Wordwrap a string. Paragraphs may be separated with double newlines." - (wordwrap-string layout props #f arg)) - -(define-builtin-markup-command (justify-string layout props arg) (string?) + (stack-lines DOWN 0.0 baseline-skip + (wordwrap-string-internal-markup-list layout props #f arg))) + +(define-builtin-markup-command (justify-string layout props arg) + (string?) + align + ((baseline-skip) + wordwrap-string-internal-markup-list) "Justify a string. Paragraphs may be separated with double newlines" - (wordwrap-string layout props #t arg)) + (stack-lines DOWN 0.0 baseline-skip + (wordwrap-string-internal-markup-list layout props #t arg))) -(define-builtin-markup-command (wordwrap-field layout props symbol) (symbol?) +(define-builtin-markup-command (wordwrap-field layout props symbol) + (symbol?) + align + () "Wordwrap the data which has been assigned to @var{symbol}." (let* ((m (chain-assoc-get symbol props))) (if (string? m) - (interpret-markup layout props - (list wordwrap-string-markup m)) - empty-stencil))) + (wordwrap-string-markup layout props m) + empty-stencil))) -(define-builtin-markup-command (justify-field layout props symbol) (symbol?) +(define-builtin-markup-command (justify-field layout props symbol) + (symbol?) + align + () "Justify the data which has been assigned to @var{symbol}." (let* ((m (chain-assoc-get symbol props))) (if (string? m) - (interpret-markup layout props - (list justify-string-markup m)) - empty-stencil))) + (justify-string-markup layout props m) + empty-stencil))) -(define-builtin-markup-command (combine layout props m1 m2) (markup? markup?) +(define-builtin-markup-command (combine layout props m1 m2) + (markup? markup?) + other + () " @cindex merging text @@ -725,44 +771,50 @@ Print two markups on top of each other." ;; ;; TODO: should extract baseline-skip from each argument somehow.. ;; -(define-builtin-markup-command (column layout props args) (markup-list?) +(define-builtin-markup-command (column layout props args) + (markup-list?) + align + ((baseline-skip)) " @cindex stacking text in a column Stack the markups in @var{args} vertically. The property @code{baseline-skip} determines the space between each markup in @var{args}." - (let* - ((arg-stencils (interpret-markup-list layout props args)) - (skip (chain-assoc-get 'baseline-skip props))) - - (stack-lines - -1 0.0 skip - (remove ly:stencil-empty? arg-stencils)))) + (let ((arg-stencils (interpret-markup-list layout props args))) + (stack-lines -1 0.0 baseline-skip + (remove ly:stencil-empty? arg-stencils)))) -(define-builtin-markup-command (dir-column layout props args) (markup-list?) +(define-builtin-markup-command (dir-column layout props args) + (markup-list?) + align + ((direction) + (baseline-skip)) " @cindex changing direction of text columns Make a column of args, going up or down, depending on the setting of the @code{#'direction} layout property." - (let* ((dir (chain-assoc-get 'direction props))) - (stack-lines - (if (number? dir) dir -1) - 0.0 - (chain-assoc-get 'baseline-skip props) - (interpret-markup-list layout props args)))) - -(define-builtin-markup-command (center-align layout props args) (markup-list?) + (stack-lines (if (number? direction) direction -1) + 0.0 + baseline-skip + (interpret-markup-list layout props args))) + +(define-builtin-markup-command (center-align layout props args) + (markup-list?) + align + ((baseline-skip)) " @cindex centering a column of text Put @code{args} in a centered column." (let* ((mols (interpret-markup-list layout props args)) (cmols (map (lambda (x) (ly:stencil-aligned-to x X CENTER)) mols))) - - (stack-lines -1 0.0 (chain-assoc-get 'baseline-skip props) cmols))) + (stack-lines -1 0.0 baseline-skip cmols))) -(define-builtin-markup-command (vcenter layout props arg) (markup?) +(define-builtin-markup-command (vcenter layout props arg) + (markup?) + align + () " @cindex vertically centering text @@ -770,7 +822,10 @@ Align @code{arg} to its Y@tie{}center." (let* ((mol (interpret-markup layout props arg))) (ly:stencil-aligned-to mol Y CENTER))) -(define-builtin-markup-command (hcenter layout props arg) (markup?) +(define-builtin-markup-command (hcenter layout props arg) + (markup?) + align + () " @cindex horizontally centering text @@ -778,7 +833,10 @@ Align @code{arg} to its X@tie{}center." (let* ((mol (interpret-markup layout props arg))) (ly:stencil-aligned-to mol X CENTER))) -(define-builtin-markup-command (right-align layout props arg) (markup?) +(define-builtin-markup-command (right-align layout props arg) + (markup?) + align + () " @cindex right aligning text @@ -786,7 +844,10 @@ Align @var{arg} on its right edge." (let* ((m (interpret-markup layout props arg))) (ly:stencil-aligned-to m X RIGHT))) -(define-builtin-markup-command (left-align layout props arg) (markup?) +(define-builtin-markup-command (left-align layout props arg) + (markup?) + align + () " @cindex left aligning text @@ -794,7 +855,10 @@ Align @var{arg} on its left edge." (let* ((m (interpret-markup layout props arg))) (ly:stencil-aligned-to m X LEFT))) -(define-builtin-markup-command (general-align layout props axis dir arg) (integer? number? markup?) +(define-builtin-markup-command (general-align layout props axis dir arg) + (integer? number? markup?) + align + () " @cindex controlling general text alignment @@ -802,7 +866,10 @@ Align @var{arg} in @var{axis} direction to the @var{dir} side." (let* ((m (interpret-markup layout props arg))) (ly:stencil-aligned-to m axis dir))) -(define-builtin-markup-command (halign layout props dir arg) (number? markup?) +(define-builtin-markup-command (halign layout props dir arg) + (number? markup?) + align + () " @cindex setting horizontal text alignment @@ -812,7 +879,10 @@ alignment accordingly." (let* ((m (interpret-markup layout props arg))) (ly:stencil-aligned-to m X dir))) -(define-builtin-markup-command (with-dimensions layout props x y arg) (number-pair? number-pair? markup?) +(define-builtin-markup-command (with-dimensions layout props x y arg) + (number-pair? number-pair? markup?) + other + () " @cindex setting extent of text objects @@ -820,101 +890,108 @@ Set the dimensions of @var{arg} to @var{x} and@tie{}@var{y}." (let* ((m (interpret-markup layout props arg))) (ly:make-stencil (ly:stencil-expr m) x y))) -(define-builtin-markup-command (pad-around layout props amount arg) (number? markup?) +(define-builtin-markup-command (pad-around layout props amount arg) + (number? markup?) + other + () "Add padding @var{amount} all around @var{arg}." - (let* - ((m (interpret-markup layout props arg)) - (x (ly:stencil-extent m X)) - (y (ly:stencil-extent m Y))) - - + (let* ((m (interpret-markup layout props arg)) + (x (ly:stencil-extent m X)) + (y (ly:stencil-extent m Y))) (ly:make-stencil (ly:stencil-expr m) - (interval-widen x amount) - (interval-widen y amount)) - )) + (interval-widen x amount) + (interval-widen y amount)))) -(define-builtin-markup-command (pad-x layout props amount arg) (number? markup?) +(define-builtin-markup-command (pad-x layout props amount arg) + (number? markup?) + other + () " @cindex padding text horizontally Add padding @var{amount} around @var{arg} in the X@tie{}direction." - (let* - ((m (interpret-markup layout props arg)) - (x (ly:stencil-extent m X)) - (y (ly:stencil-extent m Y))) - - + (let* ((m (interpret-markup layout props arg)) + (x (ly:stencil-extent m X)) + (y (ly:stencil-extent m Y))) (ly:make-stencil (ly:stencil-expr m) - (interval-widen x amount) - y) - )) + (interval-widen x amount) + y))) -(define-builtin-markup-command (put-adjacent layout props arg1 axis dir arg2) (markup? integer? ly:dir? markup?) +(define-builtin-markup-command (put-adjacent layout props arg1 axis dir arg2) + (markup? integer? ly:dir? markup?) + other + () "Put @var{arg2} next to @var{arg1}, without moving @var{arg1}." - (let* ((m1 (interpret-markup layout props arg1)) - (m2 (interpret-markup layout props arg2))) - - (ly:stencil-combine-at-edge m1 axis dir m2 0.0) - )) - -(define-builtin-markup-command (transparent layout props arg) (markup?) + (let ((m1 (interpret-markup layout props arg1)) + (m2 (interpret-markup layout props arg2))) + (ly:stencil-combine-at-edge m1 axis dir m2 0.0))) + +(define-builtin-markup-command (transparent layout props arg) + (markup?) + other + () "Make the argument transparent." - (let* - ((m (interpret-markup layout props arg)) - (x (ly:stencil-extent m X)) - (y (ly:stencil-extent m Y))) - - (ly:make-stencil "" - x y))) + (let* ((m (interpret-markup layout props arg)) + (x (ly:stencil-extent m X)) + (y (ly:stencil-extent m Y))) + (ly:make-stencil "" x y))) (define-builtin-markup-command (pad-to-box layout props x-ext y-ext arg) (number-pair? number-pair? markup?) + other + () "Make @var{arg} take at least @var{x-ext}, @var{y-ext} space." - - (let* - ((m (interpret-markup layout props arg)) - (x (ly:stencil-extent m X)) - (y (ly:stencil-extent m Y))) - + (let* ((m (interpret-markup layout props arg)) + (x (ly:stencil-extent m X)) + (y (ly:stencil-extent m Y))) (ly:make-stencil (ly:stencil-expr m) - (interval-union x-ext x) - (interval-union y-ext y)))) - + (interval-union x-ext x) + (interval-union y-ext y)))) (define-builtin-markup-command (hcenter-in layout props length arg) (number? markup?) + other + () "Center @var{arg} horizontally within a box of extending @var{length}/2 to the left and right." - (interpret-markup layout props - (make-pad-to-box-markup - (cons (/ length -2) (/ length 2)) - '(0 . 0) - (make-hcenter-markup arg)))) + (make-pad-to-box-markup + (cons (/ length -2) (/ length 2)) + '(0 . 0) + (make-hcenter-markup arg)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; property ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-builtin-markup-command (fromproperty layout props symbol) (symbol?) +(define-builtin-markup-command (fromproperty layout props symbol) + (symbol?) + other + () "Read the @var{symbol} from property settings, and produce a stencil from the markup contained within. If @var{symbol} is not defined, it returns an empty markup." - (let* ((m (chain-assoc-get symbol props))) + (let ((m (chain-assoc-get symbol props))) (if (markup? m) - (interpret-markup layout props m) - empty-stencil))) + (interpret-markup layout props m) + empty-stencil))) -(define-builtin-markup-command (on-the-fly layout props procedure arg) (symbol? markup?) +(define-builtin-markup-command (on-the-fly layout props procedure arg) + (symbol? markup?) + other + () "Apply the @var{procedure} markup command to @var{arg}. @var{procedure} should take a single argument." - (let* ((anonymous-with-signature (lambda (layout props arg) (procedure layout props arg)))) + (let ((anonymous-with-signature (lambda (layout props arg) (procedure layout props arg)))) (set-object-property! anonymous-with-signature 'markup-signature (list markup?)) (interpret-markup layout props (list anonymous-with-signature arg)))) -(define-builtin-markup-command (override layout props new-prop arg) (pair? markup?) +(define-builtin-markup-command (override layout props new-prop arg) + (pair? markup?) + other + () " @cindex overriding properties within text markup @@ -931,55 +1008,68 @@ any sort of property supported by @internalsref{font-interface} and ;; files ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-builtin-markup-command (verbatim-file layout props name) (string?) +(define-builtin-markup-command (verbatim-file layout props name) + (string?) + other + () "Read the contents of a file, and include it verbatim." - - (interpret-markup - layout props - (if (ly:get-option 'safe) - "verbatim-file disabled in safe mode" - (let* - ((str (ly:gulp-file name)) - (lines (string-split str #\nl))) - - (make-typewriter-markup - (make-column-markup lines))) - ))) + (interpret-markup layout props + (if (ly:get-option 'safe) + "verbatim-file disabled in safe mode" + (let* ((str (ly:gulp-file name)) + (lines (string-split str #\nl))) + (make-typewriter-markup + (make-column-markup lines)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; fonts. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-builtin-markup-command (bigger layout props arg) (markup?) +(define-builtin-markup-command (bigger layout props arg) + (markup?) + font + () "Increase the font size relative to current setting." (interpret-markup layout props `(,fontsize-markup 1 ,arg))) -(define-builtin-markup-command (smaller layout props arg) (markup?) +(define-builtin-markup-command (smaller layout props arg) + (markup?) + font + () "Decrease the font size relative to current setting." (interpret-markup layout props `(,fontsize-markup -1 ,arg))) -(define-builtin-markup-command larger (markup?) bigger-markup) +(define-builtin-markup-command larger + (markup?) + font + bigger-markup) -(define-builtin-markup-command (finger layout props arg) (markup?) +(define-builtin-markup-command (finger layout props arg) + (markup?) + font + () "Set the argument as small numbers." (interpret-markup layout (cons '((font-size . -5) (font-encoding . fetaNumber)) props) arg)) -(define-builtin-markup-command (fontsize layout props increment arg) (number? markup?) +(define-builtin-markup-command (fontsize layout props increment arg) + (number? markup?) + font + ((font-size 0) + (baseline-skip 2)) "Add @var{increment} to the font-size. Adjust baseline skip accordingly." - - (let* ((fs (chain-assoc-get 'font-size props 0)) - (bs (chain-assoc-get 'baseline-skip props 2)) - (entries (list - (cons 'baseline-skip (* bs (magstep increment))) - (cons 'font-size (+ fs increment ))))) - + (let ((entries (list + (cons 'baseline-skip (* baseline-skip (magstep increment))) + (cons 'font-size (+ font-size increment))))) (interpret-markup layout (cons entries props) arg))) -(define-builtin-markup-command (magnify layout props sz arg) (number? markup?) +(define-builtin-markup-command (magnify layout props sz arg) + (number? markup?) + font + () " @cindex magnifying text @@ -997,54 +1087,90 @@ Use @code{\\fontsize} otherwise." (prepend-alist-chain 'font-size (magnification->font-size sz) props) arg)) -(define-builtin-markup-command (bold layout props arg) (markup?) +(define-builtin-markup-command (bold layout props arg) + (markup?) + font + () "Switch to bold font-series." (interpret-markup layout (prepend-alist-chain 'font-series 'bold props) arg)) -(define-builtin-markup-command (sans layout props arg) (markup?) +(define-builtin-markup-command (sans layout props arg) + (markup?) + font + () "Switch to the sans serif family." (interpret-markup layout (prepend-alist-chain 'font-family 'sans props) arg)) -(define-builtin-markup-command (number layout props arg) (markup?) +(define-builtin-markup-command (number layout props arg) + (markup?) + font + () "Set font family to @code{number}, which yields the font used for time signatures and fingerings. This font only contains numbers and some punctuation. It doesn't have any letters." (interpret-markup layout (prepend-alist-chain 'font-encoding 'fetaNumber props) arg)) -(define-builtin-markup-command (roman layout props arg) (markup?) +(define-builtin-markup-command (roman layout props arg) + (markup?) + font + () "Set font family to @code{roman}." (interpret-markup layout (prepend-alist-chain 'font-family 'roman props) arg)) -(define-builtin-markup-command (huge layout props arg) (markup?) +(define-builtin-markup-command (huge layout props arg) + (markup?) + font + () "Set font size to +2." (interpret-markup layout (prepend-alist-chain 'font-size 2 props) arg)) -(define-builtin-markup-command (large layout props arg) (markup?) +(define-builtin-markup-command (large layout props arg) + (markup?) + font + () "Set font size to +1." (interpret-markup layout (prepend-alist-chain 'font-size 1 props) arg)) -(define-builtin-markup-command (normalsize layout props arg) (markup?) +(define-builtin-markup-command (normalsize layout props arg) + (markup?) + font + () "Set font size to default." (interpret-markup layout (prepend-alist-chain 'font-size 0 props) arg)) -(define-builtin-markup-command (small layout props arg) (markup?) +(define-builtin-markup-command (small layout props arg) + (markup?) + font + () "Set font size to -1." (interpret-markup layout (prepend-alist-chain 'font-size -1 props) arg)) -(define-builtin-markup-command (tiny layout props arg) (markup?) +(define-builtin-markup-command (tiny layout props arg) + (markup?) + font + () "Set font size to -2." (interpret-markup layout (prepend-alist-chain 'font-size -2 props) arg)) -(define-builtin-markup-command (teeny layout props arg) (markup?) +(define-builtin-markup-command (teeny layout props arg) + (markup?) + font + () "Set font size to -3." (interpret-markup layout (prepend-alist-chain 'font-size -3 props) arg)) -(define-builtin-markup-command (fontCaps layout props arg) (markup?) +(define-builtin-markup-command (fontCaps layout props arg) + (markup?) + font + () "Set @code{font-shape} to @code{caps}." (interpret-markup layout (prepend-alist-chain 'font-shape 'caps props) arg)) ;; Poor man's caps -(define-builtin-markup-command (smallCaps layout props text) (markup?) +(define-builtin-markup-command (smallCaps layout props text) + (markup?) + font + () "Turn @code{text}, which should be a string, to small caps. @example \\markup \\smallCaps \"Text between double quotes\" @@ -1082,11 +1208,17 @@ Note: @code{\\smallCaps} does not support accented characters." (make-small-caps (string->list text) (list) #f (list)) text))) -(define-builtin-markup-command (caps layout props arg) (markup?) +(define-builtin-markup-command (caps layout props arg) + (markup?) + font + () "Emit @var{arg} as small caps." (interpret-markup layout props (make-smallCaps-markup arg))) -(define-builtin-markup-command (dynamic layout props arg) (markup?) +(define-builtin-markup-command (dynamic layout props arg) + (markup?) + font + () "Use the dynamic font. This font only contains @b{s}, @b{f}, @b{m}, @b{z}, @b{p}, and @b{r}. When producing phrases, like @q{pi@`{u}@tie{}@b{f}}, the normal words (like @q{pi@`{u}}) should be @@ -1094,33 +1226,51 @@ done in a different font. The recommended font for this is bold and italic." (interpret-markup layout (prepend-alist-chain 'font-encoding 'fetaDynamic props) arg)) -(define-builtin-markup-command (text layout props arg) (markup?) +(define-builtin-markup-command (text layout props arg) + (markup?) + font + () "Use a text font instead of music symbol or music alphabet font." ;; ugh - latin1 (interpret-markup layout (prepend-alist-chain 'font-encoding 'latin1 props) arg)) -(define-builtin-markup-command (italic layout props arg) (markup?) +(define-builtin-markup-command (italic layout props arg) + (markup?) + font + () "Use italic @code{font-shape} for @var{arg}." (interpret-markup layout (prepend-alist-chain 'font-shape 'italic props) arg)) -(define-builtin-markup-command (typewriter layout props arg) (markup?) +(define-builtin-markup-command (typewriter layout props arg) + (markup?) + font + () "Use @code{font-family} typewriter for @var{arg}." (interpret-markup layout (prepend-alist-chain 'font-family 'typewriter props) arg)) -(define-builtin-markup-command (upright layout props arg) (markup?) +(define-builtin-markup-command (upright layout props arg) + (markup?) + font + () "Set font shape to @code{upright}. This is the opposite of @code{italic}." (interpret-markup layout (prepend-alist-chain 'font-shape 'upright props) arg)) -(define-builtin-markup-command (medium layout props arg) (markup?) +(define-builtin-markup-command (medium layout props arg) + (markup?) + font + () "Switch to medium font series (in contrast to bold)." (interpret-markup layout (prepend-alist-chain 'font-series 'medium props) arg)) -(define-builtin-markup-command (normal-text layout props arg) (markup?) +(define-builtin-markup-command (normal-text layout props arg) + (markup?) + font + () "Set all font related properties (except the size) to get the default normal text font, no matter what font was used earlier." ;; ugh - latin1 @@ -1134,7 +1284,10 @@ normal text font, no matter what font was used earlier." ;; symbols. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-builtin-markup-command (doublesharp layout props) () +(define-builtin-markup-command (doublesharp layout props) + () + music + () "Draw a double sharp symbol. @c @lilypond[verbatim,quote] @@ -1142,7 +1295,10 @@ normal text font, no matter what font was used earlier." @end lilypond" (interpret-markup layout props (markup #:musicglyph (assoc-get 1 standard-alteration-glyph-name-alist "")))) -(define-builtin-markup-command (sesquisharp layout props) () +(define-builtin-markup-command (sesquisharp layout props) + () + music + () "Draw a 3/2 sharp symbol. @c @lilypond[verbatim,quote] @@ -1150,7 +1306,10 @@ normal text font, no matter what font was used earlier." @end lilypond" (interpret-markup layout props (markup #:musicglyph (assoc-get 3/4 standard-alteration-glyph-name-alist "")))) -(define-builtin-markup-command (sharp layout props) () +(define-builtin-markup-command (sharp layout props) + () + music + () "Draw a sharp symbol. @c @lilypond[verbatim,quote] @@ -1158,7 +1317,10 @@ normal text font, no matter what font was used earlier." @end lilypond" (interpret-markup layout props (markup #:musicglyph (assoc-get 1/2 standard-alteration-glyph-name-alist "")))) -(define-builtin-markup-command (semisharp layout props) () +(define-builtin-markup-command (semisharp layout props) + () + music + () "Draw a semi sharp symbol. @c @lilypond[verbatim,quote] @@ -1166,7 +1328,10 @@ normal text font, no matter what font was used earlier." @end lilypond" (interpret-markup layout props (markup #:musicglyph (assoc-get 1/4 standard-alteration-glyph-name-alist "")))) -(define-builtin-markup-command (natural layout props) () +(define-builtin-markup-command (natural layout props) + () + music + () "Draw a natural symbol. @c @lilypond[verbatim,quote] @@ -1174,7 +1339,10 @@ normal text font, no matter what font was used earlier." @end lilypond" (interpret-markup layout props (markup #:musicglyph (assoc-get 0 standard-alteration-glyph-name-alist "")))) -(define-builtin-markup-command (semiflat layout props) () +(define-builtin-markup-command (semiflat layout props) + () + music + () "Draw a semiflat symbol. @c @lilypond[verbatim,quote] @@ -1182,7 +1350,10 @@ normal text font, no matter what font was used earlier." @end lilypond" (interpret-markup layout props (markup #:musicglyph (assoc-get -1/4 standard-alteration-glyph-name-alist "")))) -(define-builtin-markup-command (flat layout props) () +(define-builtin-markup-command (flat layout props) + () + music + () "Draw a flat symbol. @c @lilypond[verbatim,quote] @@ -1190,7 +1361,10 @@ normal text font, no matter what font was used earlier." @end lilypond" (interpret-markup layout props (markup #:musicglyph (assoc-get -1/2 standard-alteration-glyph-name-alist "")))) -(define-builtin-markup-command (sesquiflat layout props) () +(define-builtin-markup-command (sesquiflat layout props) + () + music + () "Draw a 3/2 flat symbol. @c @lilypond[verbatim,quote] @@ -1198,7 +1372,10 @@ normal text font, no matter what font was used earlier." @end lilypond" (interpret-markup layout props (markup #:musicglyph (assoc-get -3/4 standard-alteration-glyph-name-alist "")))) -(define-builtin-markup-command (doubleflat layout props) () +(define-builtin-markup-command (doubleflat layout props) + () + music + () "Draw a double flat symbol. @c @lilypond[verbatim,quote] @@ -1206,13 +1383,15 @@ normal text font, no matter what font was used earlier." @end lilypond" (interpret-markup layout props (markup #:musicglyph (assoc-get -1 standard-alteration-glyph-name-alist "")))) -(define-builtin-markup-command (with-color layout props color arg) (color? markup?) +(define-builtin-markup-command (with-color layout props color arg) + (color? markup?) + other + () " @cindex coloring text Draw @var{arg} in color specified by @var{color}." - (let* ((stil (interpret-markup layout props arg))) - + (let ((stil (interpret-markup layout props arg))) (ly:make-stencil (list 'color color (ly:stencil-expr stil)) (ly:stencil-extent stil X) (ly:stencil-extent stil Y)))) @@ -1223,6 +1402,8 @@ Draw @var{arg} in color specified by @var{color}." (define-builtin-markup-command (arrow-head layout props axis direction filled) (integer? ly:dir? boolean?) + graphic + () "Produce an arrow head in specified direction and axis. Use the filled head if @var{filled} is specified." (let* @@ -1237,7 +1418,10 @@ Use the filled head if @var{filled} is specified." props)) name))) -(define-builtin-markup-command (musicglyph layout props glyph-name) (string?) +(define-builtin-markup-command (musicglyph layout props glyph-name) + (string?) + music + () "@var{glyph-name} is converted to a musical symbol; for example, @code{\\musicglyph #\"accidentals.natural\"} selects the natural sign from the music font. See @ruser{The Feta font} for a complete listing of @@ -1247,12 +1431,18 @@ the possible glyphs." props)) glyph-name)) -(define-builtin-markup-command (lookup layout props glyph-name) (string?) +(define-builtin-markup-command (lookup layout props glyph-name) + (string?) + other + () "Lookup a glyph by name." (ly:font-get-glyph (ly:paper-get-font layout props) glyph-name)) -(define-builtin-markup-command (char layout props num) (integer?) +(define-builtin-markup-command (char layout props num) + (integer?) + other + () "Produce a single character. For example, @code{\\char #65} produces the letter @q{A}." (ly:text-interface::interpret-markup layout props (ly:wide-char->utf-8 num))) @@ -1279,71 +1469,68 @@ letter @q{A}." (number->markletter-string vec (remainder n lst))) (make-string 1 (vector-ref vec n))))) -(define-builtin-markup-command (markletter layout props num) (integer?) +(define-builtin-markup-command (markletter layout props num) + (integer?) + other + () "Make a markup letter for @var{num}. The letters start with A to@tie{}Z (skipping letter@tie{}I), and continue with double letters." (ly:text-interface::interpret-markup layout props (number->markletter-string number->mark-letter-vector num))) -(define-builtin-markup-command (markalphabet layout props num) (integer?) +(define-builtin-markup-command (markalphabet layout props num) + (integer?) + other + () "Make a markup letter for @var{num}. The letters start with A to@tie{}Z and continue with double letters." (ly:text-interface::interpret-markup layout props (number->markletter-string number->mark-alphabet-vector num))) -(define-builtin-markup-command (slashed-digit layout props num) (integer?) +(define-builtin-markup-command (slashed-digit layout props num) + (integer?) + other + ((font-size 0) + (thickness 1.6)) " @cindex slashed digits A feta number, with slash. This is for use in the context of figured bass notation." - (let* - ((mag (magstep (chain-assoc-get 'font-size props 0))) - (thickness - (* mag - (ly:output-def-lookup layout 'line-thickness) - (chain-assoc-get 'thickness props 1.6))) - (dy (* mag 0.15)) - (number-stencil (interpret-markup layout - (prepend-alist-chain 'font-encoding 'fetaNumber props) - (number->string num))) - (num-x (interval-widen (ly:stencil-extent number-stencil X) - (* mag 0.2))) - (num-y (ly:stencil-extent number-stencil Y)) - (is-sane (and (interval-sane? num-x) (interval-sane? num-y))) - - (slash-stencil - (if is-sane - (ly:make-stencil - `(draw-line - ,thickness - ,(car num-x) ,(- (interval-center num-y) dy) - ,(cdr num-x) ,(+ (interval-center num-y) dy)) - num-x num-y) - #f))) - + (let* ((mag (magstep font-size)) + (thickness (* mag + (ly:output-def-lookup layout 'line-thickness) + thickness)) + (dy (* mag 0.15)) + (number-stencil (interpret-markup layout + (prepend-alist-chain 'font-encoding 'fetaNumber props) + (number->string num))) + (num-x (interval-widen (ly:stencil-extent number-stencil X) + (* mag 0.2))) + (num-y (ly:stencil-extent number-stencil Y)) + (is-sane (and (interval-sane? num-x) (interval-sane? num-y))) + (slash-stencil (if is-sane + (ly:make-stencil + `(draw-line ,thickness + ,(car num-x) ,(- (interval-center num-y) dy) + ,(cdr num-x) ,(+ (interval-center num-y) dy)) + num-x num-y) + #f))) (set! slash-stencil - (cond - ((not (ly:stencil? slash-stencil)) #f) - ((= num 5) (ly:stencil-translate slash-stencil - ;;(cons (* mag -0.05) (* mag 0.42)) - (cons (* mag -0.00) (* mag -0.07)) - - )) - ((= num 7) (ly:stencil-translate slash-stencil - ;;(cons (* mag -0.05) (* mag 0.42)) - (cons (* mag -0.00) (* mag -0.15)) - - )) - - (else slash-stencil))) - + (cond ((not (ly:stencil? slash-stencil)) #f) + ((= num 5) + (ly:stencil-translate slash-stencil + ;;(cons (* mag -0.05) (* mag 0.42)) + (cons (* mag -0.00) (* mag -0.07)))) + ((= num 7) + (ly:stencil-translate slash-stencil + ;;(cons (* mag -0.05) (* mag 0.42)) + (cons (* mag -0.00) (* mag -0.15)))) + (else slash-stencil))) (if slash-stencil - (set! number-stencil - (ly:stencil-add number-stencil slash-stencil)) - - (ly:warning "invalid number for slashed digit ~a" num)) - + (set! number-stencil + (ly:stencil-add number-stencil slash-stencil)) + (ly:warning "invalid number for slashed digit ~a" num)) number-stencil)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1352,7 +1539,11 @@ figured bass notation." ;; TODO: better syntax. -(define-builtin-markup-command (note-by-number layout props log dot-count dir) (number? number? number?) +(define-builtin-markup-command (note-by-number layout props log dot-count dir) + (number? number? number?) + music + ((font-size 0) + (style '())) " @cindex notes within text by log and dot-count @@ -1377,8 +1568,7 @@ Construct a note symbol, with stem. By using fractional values for (car cands)))) (let* ((font (ly:paper-get-font layout (cons '((font-encoding . fetaMusic)) props))) - (size-factor (magstep (chain-assoc-get 'font-size props 0))) - (style (chain-assoc-get 'style props '())) + (size-factor (magstep font-size)) (stem-length (* size-factor (max 3 (- log 1)))) (head-glyph-name (get-glyph-name font (get-glyph-name-candidates (sign dir) log style))) (head-glyph (ly:font-get-glyph font head-glyph-name)) @@ -1450,7 +1640,10 @@ Construct a note symbol, with stem. By using fractional values for (if dots (string-length dots) 0))) (ly:error (_ "not a valid duration string: ~a") duration-string)))) -(define-builtin-markup-command (note layout props duration dir) (string? number?) +(define-builtin-markup-command (note layout props duration dir) + (string? number?) + music + (note-by-number-markup) " @cindex notes within text by string @@ -1465,7 +1658,10 @@ a shortened down stem." ;; translating. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-builtin-markup-command (lower layout props amount arg) (number? markup?) +(define-builtin-markup-command (lower layout props amount arg) + (number? markup?) + other + () " @cindex lowering text @@ -1474,22 +1670,26 @@ A negative @var{amount} indicates raising; see also @code{\\raise}." (ly:stencil-translate-axis (interpret-markup layout props arg) (- amount) Y)) -(define-builtin-markup-command (translate-scaled layout props offset arg) (number-pair? markup?) +(define-builtin-markup-command (translate-scaled layout props offset arg) + (number-pair? markup?) + other + ((font-size 0)) " @cindex translating text @cindex scaling text Translate @var{arg} by @var{offset}, scaling the offset by the @code{font-size}." - (let* - ((factor (magstep (chain-assoc-get 'font-size props 0))) - (scaled (cons (* factor (car offset)) - (* factor (cdr offset))))) - - (ly:stencil-translate (interpret-markup layout props arg) - scaled))) + (let* ((factor (magstep font-size)) + (scaled (cons (* factor (car offset)) + (* factor (cdr offset))))) + (ly:stencil-translate (interpret-markup layout props arg) + scaled))) -(define-builtin-markup-command (raise layout props amount arg) (number? markup?) +(define-builtin-markup-command (raise layout props amount arg) + (number? markup?) + other + () " @cindex raising text @@ -1511,14 +1711,17 @@ and/or @code{extra-offset} properties. @end lilypond" (ly:stencil-translate-axis (interpret-markup layout props arg) amount Y)) -(define-builtin-markup-command (fraction layout props arg1 arg2) (markup? markup?) +(define-builtin-markup-command (fraction layout props arg1 arg2) + (markup? markup?) + other + ((font-size 0)) " @cindex creating text fractions Make a fraction of two markups." (let* ((m1 (interpret-markup layout props arg1)) (m2 (interpret-markup layout props arg2)) - (factor (magstep (chain-assoc-get 'font-size props 0))) + (factor (magstep font-size)) (boxdimen (cons (* factor -0.05) (* factor 0.05))) (padding (* factor 0.2)) (baseline (* factor 0.6)) @@ -1538,16 +1741,23 @@ Make a fraction of two markups." ;; empirical anyway (ly:stencil-translate-axis stack offset Y)))) -(define-builtin-markup-command (normal-size-super layout props arg) (markup?) +(define-builtin-markup-command (normal-size-super layout props arg) + (markup?) + other + ((baseline-skip)) " @cindex setting superscript in standard font size Set @var{arg} in superscript with a normal font size." (ly:stencil-translate-axis (interpret-markup layout props arg) - (* 0.5 (chain-assoc-get 'baseline-skip props)) Y)) + (* 0.5 baseline-skip) Y)) -(define-builtin-markup-command (super layout props arg) (markup?) +(define-builtin-markup-command (super layout props arg) + (markup?) + other + ((font-size 0) + (baseline-skip)) " @cindex superscript text @@ -1560,12 +1770,15 @@ Raising and lowering texts can be done with @code{\\super} and (ly:stencil-translate-axis (interpret-markup layout - (cons `((font-size . ,(- (chain-assoc-get 'font-size props 0) 3))) props) + (cons `((font-size . ,(- font-size 3))) props) arg) - (* 0.5 (chain-assoc-get 'baseline-skip props)) + (* 0.5 baseline-skip) Y)) -(define-builtin-markup-command (translate layout props offset arg) (number-pair? markup?) +(define-builtin-markup-command (translate layout props offset arg) + (number-pair? markup?) + other + () " @cindex translating text @@ -1582,7 +1795,11 @@ that." (ly:stencil-translate (interpret-markup layout props arg) offset)) -(define-builtin-markup-command (sub layout props arg) (markup?) +(define-builtin-markup-command (sub layout props arg) + (markup?) + other + ((font-size 0) + (baseline-skip)) " @cindex subscript text @@ -1590,26 +1807,32 @@ Set @var{arg} in subscript." (ly:stencil-translate-axis (interpret-markup layout - (cons `((font-size . ,(- (chain-assoc-get 'font-size props 0) 3))) props) + (cons `((font-size . ,(- font-size 3))) props) arg) - (* -0.5 (chain-assoc-get 'baseline-skip props)) + (* -0.5 baseline-skip) Y)) -(define-builtin-markup-command (normal-size-sub layout props arg) (markup?) +(define-builtin-markup-command (normal-size-sub layout props arg) + (markup?) + other + ((baseline-skip)) " @cindex setting subscript in standard font size Set @var{arg} in subscript, in a normal font size." (ly:stencil-translate-axis (interpret-markup layout props arg) - (* -0.5 (chain-assoc-get 'baseline-skip props)) + (* -0.5 baseline-skip) Y)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; brackets. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-builtin-markup-command (hbracket layout props arg) (markup?) +(define-builtin-markup-command (hbracket layout props arg) + (markup?) + other + () " @cindex placing horizontal brackets around text @@ -1618,7 +1841,10 @@ Draw horizontal brackets around @var{arg}." (m (interpret-markup layout props arg))) (bracketify-stencil m X th (* 2.5 th) th))) -(define-builtin-markup-command (bracket layout props arg) (markup?) +(define-builtin-markup-command (bracket layout props arg) + (markup?) + other + () " @cindex placing vertical brackets around text @@ -1633,6 +1859,8 @@ Draw vertical brackets around @var{arg}." (define-builtin-markup-command (page-ref layout props label gauge default) (symbol? markup? markup?) + other + () " @cindex referencing page numbers in text @@ -1670,24 +1898,34 @@ when @var{label} is not found." point-stencil))) lines)) -(define-builtin-markup-list-command (justified-lines layout props args) (markup-list?) +(define-builtin-markup-list-command (justified-lines layout props args) + (markup-list?) + ((baseline-skip) + wordwrap-internal-markup-list) " @cindex justifying lines of text Like @code{\\justify}, but return a list of lines instead of a single markup. Use @code{\\override-lines #'(line-width . @var{X})} to set the line width; @var{X}@tie{}is the number of staff spaces." - (space-lines (chain-assoc-get 'baseline-skip props) - (wordwrap-markups layout props args #t))) + (space-lines baseline-skip + (interpret-markup-list layout props + (make-wordwrap-internal-markup-list #t args)))) -(define-builtin-markup-list-command (wordwrap-lines layout props args) (markup-list?) +(define-builtin-markup-list-command (wordwrap-lines layout props args) + (markup-list?) + ((baseline-skip) + wordwrap-internal-markup-list) "Like @code{\\wordwrap}, but return a list of lines instead of a single markup. Use @code{\\override-lines #'(line-width . @var{X})} to set the line width, where @var{X} is the number of staff spaces." - (space-lines (chain-assoc-get 'baseline-skip props) - (wordwrap-markups layout props args #f))) + (space-lines baseline-skip + (interpret-markup-list layout props + (make-wordwrap-internal-markup-list #f args)))) -(define-builtin-markup-list-command (column-lines layout props args) (markup-list?) +(define-builtin-markup-list-command (column-lines layout props args) + (markup-list?) + ((baseline-skip)) "Like @code{\\column}, but return a list of lines instead of a single markup. @code{baseline-skip} determines the space between each markup in @var{args}." (space-lines (chain-assoc-get 'baseline-skip props) @@ -1695,5 +1933,6 @@ where @var{X} is the number of staff spaces." (define-builtin-markup-list-command (override-lines layout props new-prop args) (pair? markup-list?) + () "Like @code{\\override}, for markup lists." (interpret-markup-list layout (cons (list new-prop) props) args)) diff --git a/scm/document-markup.scm b/scm/document-markup.scm index 29db2bdc53..cffdf2afda 100644 --- a/scm/document-markup.scm +++ b/scm/document-markup.scm @@ -5,62 +5,110 @@ ;;;; (c) 1998--2007 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen + +(define (doc-markup-function-properties func) + (let ((properties (hashq-ref markup-functions-properties func)) + (prop-strings (list))) + (for-each (lambda (prop-spec) + (set! prop-strings + (if (list? prop-spec) + ;; either (prop value) or (prop) + (cons (if (null? (cdr prop-spec)) + (format #f "@item @code{~a}\n" (car prop-spec)) + (format #f "@item @code{~a} (~a)\n" + (car prop-spec) + (let ((default (cadr prop-spec))) + (if (and (list? default) + (null? default)) + "'()" + default)))) + prop-strings) + ;; a markup command: get its properties + ;; FIXME: avoid cyclical references + (append (doc-markup-function-properties prop-spec) + prop-strings)))) + (or properties (list))) + prop-strings)) + (define (doc-markup-function func) (let* ((doc-str (procedure-documentation func)) - (f-name (symbol->string (procedure-name func))) - (c-name (regexp-substitute/global #f "-markup(-list)?$" f-name 'pre "" 'post)) - (sig (object-property func 'markup-signature)) - (arg-names (let ((arg-list (cadr (procedure-source func)))) + (f-name (symbol->string (procedure-name func))) + (c-name (regexp-substitute/global #f "-markup(-list)?$" f-name 'pre "" 'post)) + (sig (object-property func 'markup-signature)) + (arg-names (let ((arg-list (cadr (procedure-source func)))) (if (list? arg-list) (map symbol->string (cddr arg-list)) (make-list (length sig) "arg")))) - (sig-type-names (map type-name sig)) - (signature-str - (string-join - (map (lambda (x) (string-append - "@var{" (car x) "} (" (cadr x) ")" )) - (zip arg-names sig-type-names)) - " " ))) + (sig-type-names (map type-name sig)) + (signature-str + (string-join + (map (lambda (x) (string-append + "@var{" (car x) "} (" (cadr x) ")" )) + (zip arg-names sig-type-names)) + " " ))) (string-append "\n\n@item @code{\\" c-name "} " signature-str - "\n@findex \\" f-name "\n" -;; "\n@cindex @code{" c-name "}\n" (if (string? doc-str) - doc-str - "")))) + doc-str + "") + (let ((prop-strings (doc-markup-function-properties func))) + (if (null? prop-strings) + "\n" + (string-append "\n\n\nUsed properties:\n@itemize\n" + (apply string-append prop-strings) + "@end itemize\n")))))) (define (markup-functionstring (procedure-name a)) (symbol->string (procedure-name b)))) - -(define (markup-doc-string) - (string-append - - "@table @asis" - (apply string-append - - (map doc-markup-function - (sort markup-function-list markup-functionstring category)) + (match (string-match "-" category-string)) + (category-name (string-capitalize + (if match + (regexp-substitute #f match 'pre " " 'post) + category-string))) + (markup-functions (hashq-ref markup-functions-by-category + category))) + (make + #:name category-name + #:desc "" + #:text (string-append + "@table @asis" + (apply string-append + (map doc-markup-function + (sort markup-functions markup-function - #:name "Markup functions" - #:desc "Definitions of the markup functions." - #:text (markup-doc-string))) + #:name "Text markup commands" + #:desc "" + #:text "The following commands can all be used inside @code{\\markup @{ @}}." + #:children (let ((categories (sort (hash-fold (lambda (category function+properties categories) + (cons category categories)) + (list) + markup-functions-by-category) + (lambda (c1 c2) + (stringstring c1) + (symbol->string c2)))))) + (map markup-category-doc-node categories)))) (define (markup-list-doc-node) (make - #:name "Markup list functions" - #:desc "Definitions of the markup list functions." - #:text (markup-list-doc-string))) + #:name "Text markup list commands" + #:desc "" + #:text (string-append + "The following commands can all be used with @code{\\markuplines}.\n" + (markup-list-doc-string)))) diff --git a/scm/documentation-generate.scm b/scm/documentation-generate.scm index d137ae1b1d..874b3abbe6 100644 --- a/scm/documentation-generate.scm +++ b/scm/documentation-generate.scm @@ -30,13 +30,17 @@ (slot-ref (all-scheme-functions-doc) 'text) (open-output-file "scheme-functions.tely")) -(display - (markup-doc-string) - (open-output-file "markup-commands.tely")) +;;(display +;; (markup-doc-string) +;; (open-output-file "markup-commands.tely")) -(display - (markup-list-doc-string) - (open-output-file "markup-list-commands.tely")) +(call-with-output-file "markup-commands.tely" + (lambda (port) + (dump-node (markup-doc-node) port 2 #t))) + +(call-with-output-file "markup-list-commands.tely" + (lambda (port) + (dump-node (markup-list-doc-node) port 2 #t))) (display (identifiers-doc-string) diff --git a/scm/documentation-lib.scm b/scm/documentation-lib.scm index 4cf5f390e3..24d94215fa 100644 --- a/scm/documentation-lib.scm +++ b/scm/documentation-lib.scm @@ -21,13 +21,16 @@ (node-name x) (node-desc x))) -(define (dump-node node port level) +(define* (dump-node node port level #:optional (appendix #f)) (display (string-append "\n@node " (node-name node) "\n\n" - (texi-section-command level) " " + (if appendix + (texi-appendix-section-command level) + (texi-section-command level)) + " " (node-name node) "\n\n" (node-text node) @@ -38,7 +41,7 @@ (node-children node))) "")) port) - (map (lambda (x) (dump-node x port (+ 1 level))) + (map (lambda (x) (dump-node x port (+ 1 level) appendix)) (node-children node))) (define (processing name) @@ -65,6 +68,14 @@ (4 . "@unnumberedsubsubsec") (5 . "@unnumberedsubsubsec"))))) +(define (texi-appendix-section-command level) + (cdr (assoc level '((0 . "@top") + (1 . "@appendix") + (2 . "@appendixsec") + (3 . "@appendixsubsec") + (4 . "@appendixsubsubsec") + (5 . "@appendixsubsubsec"))))) + (define (one-item->texi label-desc-pair) "Document one (LABEL . DESC); return empty string if LABEL is empty string." (if (eq? (car label-desc-pair) "") diff --git a/scm/fret-diagrams.scm b/scm/fret-diagrams.scm index a133d189af..7618b91c8e 100644 --- a/scm/fret-diagrams.scm +++ b/scm/fret-diagrams.scm @@ -408,9 +408,20 @@ Line thickness is given by @var{th}, fret & string spacing by (ly:stencil-translate-axis (sans-serif-stencil layout props (* size label-font-mag) label-text) (* size (+ 1 label-vertical-offset)) X)))) - + (define-builtin-markup-command (fret-diagram-verbose layout props marking-list) (list?) + fret-diagram + ((size 1.0) ; needed for everything + (string-count 6) ; needed for everything + (fret-count 4) ; needed for everything + (orientation 'normal) ; needed for everything + (finger-code 'none) ; needed for both draw-dots and draw-barre + (thickness 0.5) ; needed for both draw-frets and draw-strings + (align-dir -0.4) ; needed only here + (label-dir RIGHT) + (dot-radius) + (dot-position)) "Make a fret diagram containing the symbols indicated in @var{marking-list}. For example, @@ -447,79 +458,65 @@ changed by setting the value of the variable @var{dot-color}. If the variable @var{finger-code}. There is no limit to the number of fret indications per string. @end table" - (make-fret-diagram layout props marking-list)) - -(define (make-fret-diagram layout props marking-list) -" Make a fret diagram markup" - (let* ( - ; note: here we get items from props that are needed in this routine, or that are needed in more than one - ; of the procedures called from this routine. If they're only used in one of the sub-procedure, they're - ; obtained in that procedure - - (size (chain-assoc-get 'size props 1.0)) ; needed for everything -;TODO -- get string-count directly from length of stringTunings; requires FretDiagram engraver, which is not yet available -;TODO -- adjust padding for fret label? it appears to be too close to dots - (string-count (chain-assoc-get 'string-count props 6)) ; needed for everything - (fret-count (chain-assoc-get 'fret-count props 4)) ; needed for everything - (orientation (chain-assoc-get 'orientation props 'normal)) ; needed for everything - (finger-code (chain-assoc-get 'finger-code props 'none)) ; needed for both draw-dots and draw-barre + (let* (;; note: here we get items from props that are needed in this routine, or that are needed in more than one + ;; of the procedures called from this routine. If they're only used in one of the sub-procedure, they're + ;; obtained in that procedure + ;;TODO -- get string-count directly from length of stringTunings; requires FretDiagram engraver, which is not yet available + ;;TODO -- adjust padding for fret label? it appears to be too close to dots (default-dot-radius (if (eq? finger-code 'in-dot) 0.425 0.25)) ; bigger dots if labeled (default-dot-position (if (eq? finger-code 'in-dot) (- 0.95 default-dot-radius) 0.6)) ; move up to make room for bigger if labeled (dot-radius (chain-assoc-get 'dot-radius props default-dot-radius)) ; needed for both draw-dots and draw-barre (dot-position (chain-assoc-get 'dot-position props default-dot-position)) ; needed for both draw-dots and draw-barre (th (* (ly:output-def-lookup layout 'line-thickness) - (chain-assoc-get 'thickness props 0.5))) ; needed for both draw-frets and draw-strings - - (alignment (chain-assoc-get 'align-dir props -0.4)) ; needed only here -; (xo-padding (* th (chain-assoc-get 'padding props 2))) ; needed only here + thickness)) ; needed for both draw-frets and draw-strings + ;; (xo-padding (* th (chain-assoc-get 'padding props 2))) ; needed only here (label-space (* 0.25 size)) (xo-padding (* th size 5)) - (label-dir (chain-assoc-get 'label-dir props RIGHT)) (parameters (fret-parse-marking-list marking-list fret-count)) (dot-list (cdr (assoc 'dot-list parameters))) (xo-list (cdr (assoc 'xo-list parameters))) (fret-range (cdr (assoc 'fret-range parameters))) (barre-list (cdr (assoc 'barre-list parameters))) (fret-diagram-stencil (ly:stencil-add - (draw-strings string-count fret-range th size orientation) - (draw-frets layout props fret-range string-count th size orientation)))) - (if (not (null? barre-list)) - (set! fret-diagram-stencil (ly:stencil-add + (draw-strings string-count fret-range th size orientation) + (draw-frets layout props fret-range string-count th size orientation)))) + (if (not (null? barre-list)) + (set! fret-diagram-stencil (ly:stencil-add (draw-barre layout props string-count fret-range size finger-code dot-position dot-radius barre-list orientation) fret-diagram-stencil))) - (if (not (null? dot-list)) - (set! fret-diagram-stencil (ly:stencil-add + (if (not (null? dot-list)) + (set! fret-diagram-stencil (ly:stencil-add fret-diagram-stencil (draw-dots layout props string-count fret-count fret-range size finger-code - dot-position dot-radius th dot-list orientation)))) - (if (= (car fret-range) 1) - (set! fret-diagram-stencil - (if (eq? orientation 'normal) - (ly:stencil-combine-at-edge fret-diagram-stencil Y UP - (draw-thick-zero-fret props string-count th size orientation)) - (ly:stencil-combine-at-edge fret-diagram-stencil X LEFT - (draw-thick-zero-fret props string-count th size orientation))))) - (if (not (null? xo-list)) - (set! fret-diagram-stencil - (if (eq? orientation 'normal) - (ly:stencil-combine-at-edge fret-diagram-stencil Y UP - (draw-xo layout props string-count fret-range size xo-list orientation) xo-padding ) - (ly:stencil-combine-at-edge fret-diagram-stencil X LEFT - (draw-xo layout props string-count fret-range size xo-list orientation) xo-padding)))) - (if (> (car fret-range) 1) - (set! fret-diagram-stencil - (if (eq? orientation 'normal) - (ly:stencil-combine-at-edge fret-diagram-stencil X label-dir - (label-fret layout props string-count fret-range size orientation) label-space) - (ly:stencil-combine-at-edge fret-diagram-stencil Y label-dir - (label-fret layout props string-count fret-range size orientation) label-space)))) - - (ly:stencil-aligned-to fret-diagram-stencil X alignment) - )) - + dot-position dot-radius th dot-list orientation)))) + (if (= (car fret-range) 1) + (set! fret-diagram-stencil + (if (eq? orientation 'normal) + (ly:stencil-combine-at-edge fret-diagram-stencil Y UP + (draw-thick-zero-fret props string-count th size orientation)) + (ly:stencil-combine-at-edge fret-diagram-stencil X LEFT + (draw-thick-zero-fret props string-count th size orientation))))) + (if (not (null? xo-list)) + (set! fret-diagram-stencil + (if (eq? orientation 'normal) + (ly:stencil-combine-at-edge fret-diagram-stencil Y UP + (draw-xo layout props string-count fret-range size xo-list orientation) xo-padding ) + (ly:stencil-combine-at-edge fret-diagram-stencil X LEFT + (draw-xo layout props string-count fret-range size xo-list orientation) xo-padding)))) + (if (> (car fret-range) 1) + (set! fret-diagram-stencil + (if (eq? orientation 'normal) + (ly:stencil-combine-at-edge fret-diagram-stencil X label-dir + (label-fret layout props string-count fret-range size orientation) label-space) + (ly:stencil-combine-at-edge fret-diagram-stencil Y label-dir + (label-fret layout props string-count fret-range size orientation) label-space)))) + (ly:stencil-aligned-to fret-diagram-stencil X align-dir))) + (define-builtin-markup-command (fret-diagram layout props definition-string) (string?) + fret-diagram + (fret-diagram-verbose-markup) "Make a (guitar) fret diagram. For example, say @example @@ -588,8 +585,8 @@ by the @code{f:} code. @item Note: There is no limit to the number of fret indications per string. @end itemize" - (let ((definition-list (fret-parse-definition-string props definition-string))) - (make-fret-diagram layout (car definition-list) (cdr definition-list)))) + (let ((definition-list (fret-parse-definition-string props definition-string))) + (fret-diagram-verbose-markup layout (car definition-list) (cdr definition-list)))) (define (fret-parse-definition-string props definition-string) "parse a fret diagram string and return a pair containing: @@ -660,6 +657,8 @@ Note: There is no limit to the number of fret indications per string. (define-builtin-markup-command (fret-diagram-terse layout props definition-string) (string?) + fret-diagram + (fret-diagram-verbose-markup) "Make a fret diagram markup using terse string-based syntax. Here an example @@ -702,9 +701,9 @@ Where a barre indicator is desired, follow the fret (or fingering) symbol with @code{-(} to start a barre and @code{-)} to end the barre. @end itemize" -;TODO -- change syntax to fret\string-finger - (let ((definition-list (fret-parse-terse-definition-string props definition-string))) - (make-fret-diagram layout (car definition-list) (cdr definition-list)))) + ;; TODO -- change syntax to fret\string-finger + (let ((definition-list (fret-parse-terse-definition-string props definition-string))) + (fret-diagram-verbose-markup layout (car definition-list) (cdr definition-list)))) (define (fret-parse-terse-definition-string props definition-string) "parse a fret diagram string that uses terse syntax; return a pair containing: diff --git a/scm/markup.scm b/scm/markup.scm index 5daba8d932..81614a6883 100644 --- a/scm/markup.scm +++ b/scm/markup.scm @@ -37,25 +37,45 @@ The command is now available in markup mode, e.g. ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; markup definer utilities -(define-macro (define-builtin-markup-command command-and-args signature . body) +;; For documentation purposes +;; category -> markup functions +(define-public markup-functions-by-category (make-hash-table 150)) +;; markup function -> used properties +(define-public markup-functions-properties (make-hash-table 150)) +;; List of markup list functions +(define-public markup-list-function-list (list)) + +(define-macro (define-builtin-markup-command command-and-args signature + category properties-or-copied-function . body) " * Define a COMMAND-markup function after command-and-args and body, register COMMAND-markup and its signature, -* add COMMAND-markup to markup-function-list, +* add COMMAND-markup to markup-functions-by-category, * sets COMMAND-markup markup-signature and markup-keyword object properties, * define a make-COMMAND-markup function. Syntax: - (define-builtin-markup-command (COMMAND layout props arg1 arg2 ...) - (arg1-type? arg2-type? ...) + (define-builtin-markup-command (COMMAND layout props . arguments) + argument-types + category + properties \"documentation string\" ...command body...) or: - (define-builtin-markup-command COMMAND (arg1-type? arg2-type? ...) - function) + (define-builtin-markup-command COMMAND + argument-types + category + function) + +where: + argument-types is a list of type predicates for arguments + category is either a symbol or a symbol list + properties a list of (property default-value) lists or COMMANDx-markup elements + (when a COMMANDx-markup is found, the properties of the said commandx are + added instead). No check is performed against cyclical references! " (let* ((command (if (pair? command-and-args) (car command-and-args) command-and-args)) (args (if (pair? command-and-args) (cdr command-and-args) '())) @@ -64,51 +84,111 @@ Syntax: `(begin ;; define the COMMAND-markup function ,(if (pair? args) - `(define-public (,command-name ,@args) - ,@body) + (let ((documentation (car body)) + (real-body (cdr body)) + (properties properties-or-copied-function)) + `(define-public (,command-name ,@args) + ,documentation + (let ,(filter identity + (map (lambda (prop-spec) + (if (pair? prop-spec) + (let ((prop (car prop-spec)) + (default-value (if (null? (cdr prop-spec)) + #f + (cadr prop-spec))) + (props (cadr args))) + `(,prop (chain-assoc-get ',prop ,props ,default-value))) + #f)) + properties)) + ,@real-body))) (let ((args (gensym "args")) - (markup-command (car body))) - `(define-public (,command-name . ,args) - ,(format #f "Copy of the ~a command." markup-command) - (apply ,markup-command ,args)))) + (markup-command properties-or-copied-function)) + `(define-public (,command-name . ,args) + ,(format #f "Copy of the ~a command." markup-command) + (apply ,markup-command ,args)))) (set! (markup-command-signature ,command-name) (list ,@signature)) - ;; add the command to markup-function-list, for markup documentation - (if (not (member ,command-name markup-function-list)) - (set! markup-function-list (cons ,command-name markup-function-list))) + ;; Register the new function, for markup documentation + ,@(map (lambda (category) + `(hashq-set! markup-functions-by-category ',category + (cons ,command-name + (or (hashq-ref markup-functions-by-category ',category) + (list))))) + (if (list? category) category (list category))) + ;; Used properties, for markup documentation + (hashq-set! markup-functions-properties + ,command-name + (list ,@(map (lambda (prop-spec) + (cond ((symbol? prop-spec) + prop-spec) + ((not (null? (cdr prop-spec))) + `(list ',(car prop-spec) ,(cadr prop-spec))) + (else + `(list ',(car prop-spec))))) + (if (pair? args) + properties-or-copied-function + (list))))) ;; define the make-COMMAND-markup function (define-public (,make-markup-name . args) (let ((sig (list ,@signature))) (make-markup ,command-name ,(symbol->string make-markup-name) sig args)))))) -(define-macro (define-builtin-markup-list-command command-and-args signature . body) +(define-macro (define-builtin-markup-list-command command-and-args signature + properties . body) "Same as `define-builtin-markup-command, but defines a command that, when interpreted, returns a list of stencils instead os a single one" (let* ((command (if (pair? command-and-args) (car command-and-args) command-and-args)) - (args (if (pair? command-and-args) (cdr command-and-args) '())) - (command-name (string->symbol (format #f "~a-markup-list" command))) - (make-markup-name (string->symbol (format #f "make-~a-markup-list" command)))) + (args (if (pair? command-and-args) (cdr command-and-args) '())) + (command-name (string->symbol (format #f "~a-markup-list" command))) + (make-markup-name (string->symbol (format #f "make-~a-markup-list" command)))) `(begin ;; define the COMMAND-markup-list function ,(if (pair? args) - `(define-public (,command-name ,@args) - ,@body) - (let ((args (gensym "args")) - (markup-command (car body))) - `(define-public (,command-name . ,args) - ,(format #f "Copy of the ~a command." markup-command) - (apply ,markup-command ,args)))) + (let ((documentation (car body)) + (real-body (cdr body))) + `(define-public (,command-name ,@args) + ,documentation + (let ,(filter identity + (map (lambda (prop-spec) + (if (pair? prop-spec) + (let ((prop (car prop-spec)) + (default-value (if (null? (cdr prop-spec)) + #f + (cadr prop-spec))) + (props (cadr args))) + `(,prop (chain-assoc-get ',prop ,props ,default-value))) + #f)) + properties)) + ,@body))) + (let ((args (gensym "args")) + (markup-command (car body))) + `(define-public (,command-name . ,args) + ,(format #f "Copy of the ~a command." markup-command) + (apply ,markup-command ,args)))) (set! (markup-command-signature ,command-name) (list ,@signature)) ;; add the command to markup-list-function-list, for markup documentation (if (not (member ,command-name markup-list-function-list)) - (set! markup-list-function-list (cons ,command-name - markup-list-function-list))) + (set! markup-list-function-list (cons ,command-name + markup-list-function-list))) + ;; Used properties, for markup documentation + (hashq-set! markup-functions-properties + ,command-name + (list ,@(map (lambda (prop-spec) + (cond ((symbol? prop-spec) + prop-spec) + ((not (null? (cdr prop-spec))) + `(list ',(car prop-spec) ,(cadr prop-spec))) + (else + `(list ',(car prop-spec))))) + (if (pair? args) + properties + (list))))) ;; it's a markup-list command: (set-object-property! ,command-name 'markup-list-command #t) ;; define the make-COMMAND-markup-list function (define-public (,make-markup-name . args) - (let ((sig (list ,@signature))) - (list (make-markup ,command-name - ,(symbol->string make-markup-name) sig args))))))) + (let ((sig (list ,@signature))) + (list (make-markup ,command-name + ,(symbol->string make-markup-name) sig args))))))) (define-public (make-markup markup-function make-name signature args) " Construct a markup object from MARKUP-FUNCTION and ARGS. Typecheck @@ -291,10 +371,6 @@ Use `markup*' in a \\notemode context." (make-procedure-with-setter markup-command-signature-ref markup-command-signature-set!)) -;; For documentation purposes -(define-public markup-function-list (list)) -(define-public markup-list-function-list (list)) - (define-public (markup-signature-to-keyword sig) " (A B C) -> a0-b1-c2 " (if (null? sig)