]> git.donarmstrong.com Git - lilypond.git/commitdiff
Markup command documentation: categories and properties
authorNicolas Sceaux <nicolas.sceaux@free.fr>
Sun, 27 Apr 2008 16:56:36 +0000 (18:56 +0200)
committerNicolas Sceaux <nicolas.sceaux@free.fr>
Sun, 27 Apr 2008 16:56:36 +0000 (18:56 +0200)
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.

Documentation/user/notation-appendices.itely
scm/define-markup-commands.scm
scm/document-markup.scm
scm/documentation-generate.scm
scm/documentation-lib.scm
scm/fret-diagrams.scm
scm/markup.scm

index ae85e37205bcf472981690bc332284f248eed5f5..9113aff48c51b72056d60e9c99c1d5832e7f1b7b 100644 (file)
@@ -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
index 71fe0f5a663db963f2b44001c745e470054db24f..d4d6784692e4022da6c5116c2a12555f37313e60 100644 (file)
 
 (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))
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -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))
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; 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))
index 29db2bdc532e83b375ab8e4d37cda5a666820bb4..cffdf2afda238cac9da1d14a85db6ac3efa1c6d5 100644 (file)
 ;;;; (c) 1998--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
 ;;;;                 Jan Nieuwenhuizen <janneke@gnu.org>
 
+
+(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-function<? a b)
   (string<? (symbol->string (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-function<?)))
-   "\n@end table"))
+(define (markup-category-doc-node category)
+  (let* ((category-string (symbol->string 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 <texi-node>
+      #:name category-name
+      #:desc ""
+      #:text (string-append
+              "@table @asis"
+              (apply string-append
+                     (map doc-markup-function
+                          (sort markup-functions markup-function<?)))
+              "\n@end table"))))
 
 (define (markup-list-doc-string)
   (string-append
    "@table @asis"
    (apply string-append
-         (map doc-markup-function
-              (sort markup-list-function-list markup-function<?)))
+          (map doc-markup-function
+               (sort markup-list-function-list markup-function<?)))
    "\n@end table"))
 
 (define (markup-doc-node)
   (make <texi-node>
-    #: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)
+                                         (string<? (symbol->string c1)
+                                                   (symbol->string c2))))))
+                 (map markup-category-doc-node categories))))
 
 (define (markup-list-doc-node)
   (make <texi-node>
-    #: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))))
index d137ae1b1d27456d167725fff8e3c4ec6967415b..874b3abbe641f1116a8888d90c908952b514be36 100644 (file)
  (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)
index 4cf5f390e32be50ac65092a69ba17330f0df08f2..24d94215fa19c00ae70b3e5fa808f79aad2d9ed2 100644 (file)
    (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)
                      (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) "")
index a133d189af8e3e477272c236a1776e948e3cf072..7618b91c8eed04bad62901863dcdeed58a32f058 100644 (file)
@@ -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:
index 5daba8d9321a38166355d78a457b91a8b1965313..81614a68839fcddf458fd105d841fc4301ccd2dc 100644 (file)
@@ -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)