]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/define-markup-commands.scm
*** empty log message ***
[lilypond.git] / scm / define-markup-commands.scm
index 21186cd074395f4875e0cddff7b2e3463e198caf..eee2783965a94cc0b9afdebcfe931b1b9df8f43e 100644 (file)
@@ -2,7 +2,7 @@
 ;;;;
 ;;;;  source file of the GNU LilyPond music typesetter
 ;;;; 
-;;;; (c) 2000--2005  Han-Wen Nienhuys <hanwen@cs.uu.nl>
+;;;; (c) 2000--2006  Han-Wen Nienhuys <hanwen@cs.uu.nl>
 ;;;;                  Jan Nieuwenhuizen <janneke@gnu.org>
 
 
 
 (use-modules (ice-9 regex))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; utility functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (define-public empty-stencil (ly:make-stencil '() '(1 . -1) '(1 . -1)))
 (define-public point-stencil (ly:make-stencil "" '(0 . 0) '(0 . 0)))
 
-(def-markup-command (stencil layout props stil) (ly:stencil?)
-  "Stencil as markup"
-  stil)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; geometric shapes
@@ -81,19 +82,22 @@ the PDF backend."
         (half (/ thickness 2)))
 
     (ly:make-stencil
-     (list 'beam width
-          slope
-          thickness
-          (ly:output-def-lookup layout 'blotdiameter))
+     `(polygon ',(list 
+                 0 (/ thickness -2)
+                   width (+ (* width slope)  (/ thickness -2))
+                   width (+ (* width slope)  (/ thickness 2))
+                   0 (/ thickness 2))
+              ,(ly:output-def-lookup layout 'blot-diameter)
+              #t)
      (cons 0 width)
      (cons (+ (- half) (car yext))
           (+ half (cdr yext))))))
 
-
 (def-markup-command (box layout props arg) (markup?)
   "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 (chain-assoc-get 'thickness props  0.1))
         (size (chain-assoc-get 'font-size props 0))
         (pad (* (magstep size)
@@ -101,8 +105,6 @@ thickness and padding around the markup."
         (m (interpret-markup layout props arg)))
     (box-stencil m th pad)))
 
-
-
 (def-markup-command (filled-box layout props xext yext blot)
   (number-pair? number-pair? number?)
   "Draw a box with rounded corners of dimensions @var{xext} and @var{yext}."
@@ -124,6 +126,19 @@ thickness and padding around the markup."
 
     (ly:stencil-add white stil)))
 
+(def-markup-command (pad-markup layout props padding arg) (number? markup?)
+  "Add space around a markup object."
+
+  (let*
+      ((stil (interpret-markup layout props arg))
+       (xext (ly:stencil-extent stil X))
+       (yext (ly:stencil-extent stil Y)))
+
+    (ly:make-stencil
+     (ly:stencil-expr stil)
+     (interval-widen xext padding)
+     (interval-widen yext padding))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; space
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -131,10 +146,11 @@ thickness and padding around the markup."
 ;;FIXME: is this working? 
 (def-markup-command (strut layout props) ()
   "Create a box of the same height as the space in the current font."
-  (let ((m (Text_interface::interpret_markup layout props " ")))
+  (let ((m (ly:text-interface::interpret-markup layout props " ")))
     (ly:make-stencil (ly:stencil-expr m)
+                    '(1000 . -1000)
                     (ly:stencil-extent m X)
-                    '(1000 . -1000))))
+                    )))
 
 
 ;; todo: fix negative space
@@ -155,9 +171,12 @@ normally inserted before elements on a line.
 ;; importing graphics.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+(def-markup-command (stencil layout props stil) (ly:stencil?)
+  "Stencil as markup"
+  stil)
 
 (define bbox-regexp
-  (make-regexp "%%BoundingBox: ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)"))
+  (make-regexp "%%BoundingBox:[ \t]+([0-9-]+)[ \t]+([0-9-]+)[ \t]+([0-9-]+)[ \t]+([0-9-]+)"))
 
 (define (get-postscript-bbox string)
   "Extract the bbox from STRING, or return #f if not present."
@@ -171,44 +190,14 @@ normally inserted before elements on a line.
             
        #f)))
 
-(def-markup-command (epsfile layout props file-name) (string?)
-  "Inline an EPS image. The image is scaled such that 10 PS units is
-one staff-space."
+(def-markup-command (epsfile layout props axis size file-name) (number? number? string?)
+  "Inline an EPS image. The image is scaled along @var{axis} to
+@var{size}."
 
   (if (ly:get-option 'safe)
-      (interpret-markup layout props "not allowed in safe") 
-      (let*
-         ((contents (ly:gulp-file file-name))
-          (bbox (get-postscript-bbox contents))
-          (scaled-bbox
-           (if bbox
-               (map (lambda (x) (/ x 10)) bbox)
-               (begin
-                 (ly:warn (_ "can't find bounding box of `~a'")
-                          file-name)
-                 '()))))
-       
-
-       (if bbox
-           
-           (ly:make-stencil
-            (list
-             'embedded-ps
-             (string-append
-
-              ; adobe 5002.
-              "BeginEPSF "
-              "0.1 0.1 scale "
-              (format "\n%%BeginDocument: ~a\n" file-name)
-              contents
-              "%%EndDocument\n"
-              "EndEPSF\n"
-              ))
-            (cons (list-ref scaled-bbox 0) (list-ref scaled-bbox 2))
-            (cons (list-ref scaled-bbox 1) (list-ref scaled-bbox 3)))
-           
-           (ly:make-stencil "" '(0 . 0) '(0 . 0))))))  
-
+      (interpret-markup layout props "not allowed in safe")
+      (eps-file->stencil axis size file-name)
+      ))
 
 (def-markup-command (postscript layout props str) (string?)
   "This inserts @var{str} directly into the output as a PostScript
@@ -249,12 +238,17 @@ gsave /ecrm10 findfont
   (let* ((output (ly:score-embedded-format score layout)))
 
     (if (ly:music-output? output)
-       (ly:paper-system-stencil
+       (paper-system-stencil
         (vector-ref (ly:paper-score-paper-systems output) 0))
        (begin
          (ly:warning (_"no systems found in \\score markup, does it have a \\layout block?"))
          empty-stencil))))
 
+(def-markup-command (null layout props) ()
+  "An empty markup with extents of a single point"
+
+  point-stencil)
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; basic formatting.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -272,17 +266,9 @@ gsave /ecrm10 findfont
 (define-public empty-markup
   (make-simple-markup ""))
 
-
-(def-markup-command (fill-line layout props markups)
-  (markup-list?)
-  "Put @var{markups} in a horizontal line of width @var{line-width}.
-   The markups are spaced/flushed to fill the entire line.
-   If there are no arguments, return an empty stencil.
-"
-
-
-  (define (get-fill-space word-count line-width text-widths)
-    "Calculate the necessary paddings between each two adjacent texts.
+;; helper for justifying lines.
+(define (get-fill-space word-count line-width text-widths)
+  "Calculate the necessary paddings between each two adjacent texts.
        The lengths of all texts are stored in @var{text-widths}.
        The normal formula for the padding between texts a and b is:
        padding = line-width/(word-count - 1) - (length(a) + length(b))/2
@@ -290,26 +276,31 @@ gsave /ecrm10 findfont
        whole length of the first or last text.
        Return a list of paddings.
 "
-    (cond
-     ((null? text-widths) '())
-    
-     ;; special case first padding
-     ((= (length text-widths) word-count)
-      (cons 
-       (- (- (/ line-width (1- word-count)) (car text-widths))
-         (/ (car (cdr text-widths)) 2))
-       (get-fill-space word-count line-width (cdr text-widths))))
-     ;; special case last padding
-     ((= (length text-widths) 2)
-      (list (- (/ line-width (1- word-count))
-              (+ (/ (car text-widths) 2) (car (cdr text-widths)))) 0))
-     (else
-      (cons 
-       (- (/ line-width (1- word-count))
-         (/ (+ (car text-widths) (car (cdr text-widths))) 2))
-       (get-fill-space word-count line-width (cdr text-widths))))))
-
+  (cond
+   ((null? text-widths) '())
+   
+   ;; special case first padding
+   ((= (length text-widths) word-count)
+    (cons 
+     (- (- (/ line-width (1- word-count)) (car text-widths))
+       (/ (car (cdr text-widths)) 2))
+     (get-fill-space word-count line-width (cdr text-widths))))
+   ;; special case last padding
+   ((= (length text-widths) 2)
+    (list (- (/ line-width (1- word-count))
+            (+ (/ (car text-widths) 2) (car (cdr text-widths)))) 0))
+   (else
+    (cons 
+     (- (/ line-width (1- word-count))
+       (/ (+ (car text-widths) (car (cdr text-widths))) 2))
+     (get-fill-space word-count line-width (cdr text-widths))))))
 
+(def-markup-command (fill-line layout props markups)
+  (markup-list?)
+  "Put @var{markups} in a horizontal line of width @var{line-width}.
+   The markups are spaced/flushed to fill the entire line.
+   If there are no arguments, return an empty stencil."
   (let* ((orig-stencils
          (map (lambda (x) (interpret-markup layout props x))
               markups))
@@ -318,16 +309,17 @@ gsave /ecrm10 findfont
                 (if (ly:stencil-empty? stc)
                     point-stencil
                     stc)) orig-stencils))
-     (text-widths
-       (map (lambda (stc)
-               (if (ly:stencil-empty? stc)
-                       0.0
-                               (interval-length (ly:stencil-extent stc X))))
-                       stencils))
-     (text-width (apply + text-widths))
+        (text-widths
+         (map (lambda (stc)
+                (if (ly:stencil-empty? stc)
+                    0.0
+                    (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))
-        (line-width (chain-assoc-get 'linewidth props))
+        (line-width (chain-assoc-get 'line-width props))
         (fill-space
                (cond
                        ((= word-count 1) 
@@ -339,12 +331,12 @@ gsave /ecrm10 findfont
                                        (- line-width text-width)))
                        (else 
                                (get-fill-space word-count line-width text-widths))))
-     (fill-space-normal
-       (map (lambda (x)
-               (if (< x word-space)
-                       word-space
-                               x))
-                       fill-space))
+        (fill-space-normal
+         (map (lambda (x)
+                (if (< x word-space)
+                    word-space
+                    x))
+              fill-space))
                                        
         (line-stencils (if (= word-count 1)
                            (list
@@ -353,20 +345,195 @@ gsave /ecrm10 findfont
                             point-stencil)
                            stencils)))
 
+    (if (= text-dir LEFT)
+       (set! line-stencils (reverse line-stencils)))
+
     (if (null? (remove ly:stencil-empty? orig-stencils))
        empty-stencil
-       (stack-stencils-padding-list X RIGHT fill-space-normal line-stencils))))
+       (stack-stencils-padding-list X
+                                    RIGHT fill-space-normal line-stencils))))
        
 (def-markup-command (line layout props args) (markup-list?)
   "Put @var{args} in a horizontal line.  The property @code{word-space}
 determines the space between each markup in @var{args}."
   (let*
       ((stencils (map (lambda (m) (interpret-markup layout props m)) args))
-       (space    (chain-assoc-get 'word-space props)))
+       (space    (chain-assoc-get 'word-space props))
+       (text-dir (chain-assoc-get 'text-direction props RIGHT)) 
+       )
+
+    (if (= text-dir LEFT)
+       (set! stencils (reverse stencils)))
+    
+
+    (stack-stencil-line
+     space
+     (remove ly:stencil-empty? stencils))))
 
-  (stack-stencil-line
-   space
-   (remove ly:stencil-empty? stencils))))
+
+(define (wordwrap-stencils stencils
+                          justify base-space line-width text-dir)
+  
+  "Perform simple wordwrap, return stencil of each line."
+  
+  (define space (if justify
+                   
+                   ;; justify only stretches lines.
+                   (* 0.7 base-space)
+                   base-space))
+       
+  (define (take-list width space stencils
+                    accumulator accumulated-width)
+    "Return (head-list . tail) pair, with head-list fitting into width"
+    (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))
+          (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*
+      ((baseline-skip (chain-assoc-get 'baseline-skip props))
+       (line-width (chain-assoc-get 'line-width props))
+       (word-space (chain-assoc-get 'word-space props))
+       (text-dir (chain-assoc-get 'text-direction props RIGHT)) 
+       (lines (wordwrap-stencils
+              (remove ly:stencil-empty?
+                      (map (lambda (m) (interpret-markup layout props m)) args))
+              justify word-space line-width
+              text-dir)
+              ))
+
+    (stack-lines DOWN 0.0 baseline-skip lines)))
+
+(def-markup-command (justify layout props args) (markup-list?)
+  "Like wordwrap, but with lines stretched to justify the margins.
+Use @code{\\override #'(line-width . X)} to set line-width, where X
+is the number of staff spaces."
+
+  (wordwrap-markups layout props args #t))
+
+(def-markup-command (wordwrap layout props args) (markup-list?)
+  "Simple wordwrap.  Use @code{\\override #'(line-width . X)} to set
+line-width, where X is the number of staff spaces."
+
+  (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))))
+
+
+(def-markup-command (wordwrap-string layout props arg) (string?)
+  "Wordwrap a string. Paragraphs may be separated with double newlines"
+  (wordwrap-string layout props  #f arg))
+  
+(def-markup-command (justify-string layout props arg) (string?)
+  "Justify a string. Paragraphs may be separated with double newlines"
+  (wordwrap-string layout props #t arg))
+
+
+(def-markup-command (wordwrap-field layout props symbol) (symbol?)
+   (let* ((m (chain-assoc-get symbol props)))
+     (if (string? m)
+      (interpret-markup layout props
+       (list wordwrap-string-markup m))
+      (ly:make-stencil '()  '(1 . -1) '(1 . -1)))))
+
+(def-markup-command (justify-field layout props symbol) (symbol?)
+-   (let* ((m (chain-assoc-get symbol props)))
+     (if (string? m)
+      (interpret-markup layout props
+       (list justify-string-markup m))
+      (ly:make-stencil '()  '(1 . -1) '(1 . -1)))))
 
 
 
@@ -382,10 +549,16 @@ determines the space between each markup in @var{args}."
 (def-markup-command (column layout props args) (markup-list?)
   "Stack the markups in @var{args} vertically.  The property
 @code{baseline-skip} determines the space between each markup in @var{args}."
-  (stack-lines
-   -1 0.0 (chain-assoc-get 'baseline-skip props)
-   (remove ly:stencil-empty?
-          (map (lambda (m) (interpret-markup layout props m)) args))))
+
+  (let*
+      ((arg-stencils (map (lambda (m) (interpret-markup layout props m)) args))
+       (skip (chain-assoc-get 'baseline-skip props)))
+
+    
+    (stack-lines
+     -1 0.0 skip
+     (remove ly:stencil-empty? arg-stencils))))
+
 
 (def-markup-command (dir-column layout props args) (markup-list?)
   "Make a column of args, going up or down, depending on the setting
@@ -401,6 +574,7 @@ of the @code{#'direction} layout property."
   "Put @code{args} in a centered column. "
   (let* ((mols (map (lambda (x) (interpret-markup layout props x)) 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)))
 
 (def-markup-command (vcenter layout props arg) (markup?)
@@ -436,6 +610,82 @@ alignment accordingly."
     (ly:stencil-aligned-to m X dir)))
 
 
+
+(def-markup-command (with-dimensions layout props x y arg) (number-pair? number-pair? markup?)
+  "Set the dimensions of @var{arg} to @var{x} and @var{y}."
+  
+  (let* ((m (interpret-markup layout props arg)))
+    (ly:make-stencil (ly:stencil-expr m) x y)))
+
+
+(def-markup-command (pad-around layout props amount arg) (number? markup?)
+
+  "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)))
+    
+       
+    (ly:make-stencil (ly:stencil-expr m)
+                    (interval-widen x amount)
+                    (interval-widen y amount))
+   ))
+
+
+(def-markup-command (pad-x layout props amount arg) (number? markup?)
+
+  "Add padding @var{amount} around @var{arg} in the X-direction. "
+  (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)
+   ))
+
+
+(def-markup-command (put-adjacent layout props arg1 axis dir arg2) (markup? integer? ly:dir?  markup?)
+
+  "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 0.0)
+  ))
+
+(def-markup-command (transparent layout props arg) (markup?)
+  "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)))
+
+
+(def-markup-command (pad-to-box layout props x-ext y-ext arg) (number-pair? number-pair? markup?)
+  "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)))
+
+    (ly:make-stencil (ly:stencil-expr m)
+                    (interval-union x-ext x)
+                    (interval-union y-ext y))))
+
+
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; property
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -473,6 +723,25 @@ any sort of property supported by @internalsref{font-interface} and
 "
   (interpret-markup layout (cons (list new-prop) props) arg))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; files
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(def-markup-command (verbatim-file layout props name) (string?)
+  "Read the contents of a file, and include verbatimly"
+
+  (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.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -571,10 +840,6 @@ some punctuation. It doesn't have any letters.  "
   "Set @code{font-shape} to @code{caps}."
   (interpret-markup layout (prepend-alist-chain 'font-shape 'caps props) arg))
 
-;(def-markup-command (latin-i layout props arg) (markup?)
-;  "TEST latin1 encoding."
-;  (interpret-markup layout (prepend-alist-chain 'font-shape 'latin1 props) arg))
-
 (def-markup-command (dynamic layout props arg) (markup?)
   "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 ``pi@`{u} @b{f}'', the
@@ -583,6 +848,14 @@ recommend font for this is bold and italic"
   (interpret-markup
    layout (prepend-alist-chain 'font-encoding 'fetaDynamic props) arg))
 
+(def-markup-command (text layout props arg) (markup?)
+  "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))
+
+
 (def-markup-command (italic layout props arg) (markup?)
   "Use italic @code{font-shape} for @var{arg}. "
   (interpret-markup layout (prepend-alist-chain 'font-shape 'italic props) arg))
@@ -593,10 +866,23 @@ recommend font for this is bold and italic"
    layout (prepend-alist-chain 'font-family 'typewriter props) arg))
 
 (def-markup-command (upright layout props arg) (markup?)
-  "Set font shape to @code{upright}."
+  "Set font shape to @code{upright}.  This is the opposite of @code{italic}."
   (interpret-markup
    layout (prepend-alist-chain 'font-shape 'upright props) arg))
 
+(def-markup-command (medium layout props arg) (markup?)
+  "Switch to medium font-series (in contrast to bold)."
+  (interpret-markup layout (prepend-alist-chain 'font-series 'medium props)
+                   arg))
+
+(def-markup-command (normal-text layout props arg) (markup?)
+  "Set all font related properties (except the size) to get the default normal text font, no matter what font was used earlier."
+  ;; ugh - latin1
+  (interpret-markup layout
+                    (cons '((font-family . roman) (font-shape . upright)
+                           (font-series . medium) (font-encoding . latin1))
+                         props)
+                    arg))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; symbols.
@@ -648,11 +934,27 @@ recommend font for this is bold and italic"
                     (ly:stencil-extent stil X)
                     (ly:stencil-extent stil Y))))
 
-
+\f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; glyphs
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+
+(def-markup-command (arrow-head layout props axis direction filled)
+  (integer? ly:dir? boolean?)
+  "produce an arrow head in specified direction and axis. Use the filled head if @var{filled} is  specified."
+  (let*
+      ((name (format "arrowheads.~a.~a~a"
+                    (if filled
+                        "close"
+                        "open")
+                    axis
+                    direction)))
+    (ly:font-get-glyph
+     (ly:paper-get-font layout (cons '((font-encoding . fetaMusic))
+                                    props))
+     name)))
+
 (def-markup-command (musicglyph layout props glyph-name) (string?)
   "This is converted to a musical symbol, e.g. @code{\\musicglyph
 #\"accidentals.0\"} will select the natural sign from the music font.
@@ -698,15 +1000,57 @@ letter 'A'."
 (def-markup-command (markletter layout props num) (integer?)
   "Make a markup letter for @var{num}.  The letters start with A to Z
  (skipping I), and continues with double letters."
-  (Text_interface::interpret_markup layout props
+  (ly:text-interface::interpret-markup layout props
     (number->markletter-string number->mark-letter-vector num)))
 
 (def-markup-command (markalphabet layout props num) (integer?)
    "Make a markup letter for @var{num}.  The letters start with A to Z
  and continues with double letters."
-   (Text_interface::interpret_markup layout props
+   (ly:text-interface::interpret-markup layout props
      (number->markletter-string number->mark-alphabet-vector num)))
 
+
+
+(def-markup-command (slashed-digit layout props num) (integer?)
+  "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
+          (chain-assoc-get 'thickness props 0.16)))
+       (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))
+       (slash-stencil 
+       (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
+        )))
+
+    (ly:stencil-add number-stencil
+                   (cond
+                    ((= 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)))
+    ))
+\f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; the note command.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -795,6 +1139,7 @@ a shortened down stem."
   (let ((parsed (parse-simple-duration duration)))
     (note-by-number-markup layout props (car parsed) (cadr parsed) dir)))
 
+\f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; translating.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -802,7 +1147,7 @@ a shortened down stem."
 (def-markup-command (lower layout props amount arg) (number? markup?)
   "
 Lower @var{arg}, by the distance @var{amount}.
-A negative @var{amount} indicates raising, see also @code{\raise}.
+A negative @var{amount} indicates raising, see also @code{\\raise}.
 "
   (ly:stencil-translate-axis (interpret-markup layout props arg)
                             (- amount) Y))
@@ -912,7 +1257,7 @@ that.
    (interpret-markup layout props arg)
    (* -0.5 (chain-assoc-get 'baseline-skip props))
    Y))
-
+\f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; brackets.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -932,7 +1277,13 @@ that.
 (def-markup-command (bracketed-y-column layout props indices args)
   (list? markup-list?)
   "Make a column of the markups in @var{args}, putting brackets around
-the elements marked in @var{indices}, which is a list of numbers."
+the elements marked in @var{indices}, which is a list of numbers.
+
+"
+;;
+;; DROPME? This command is a relic from the old figured bass implementation.
+;;
+  
   (define (sublist lst start stop)
     (take (drop lst start) (- (1+ stop) start)))
 
@@ -941,12 +1292,13 @@ the elements marked in @var{indices}, which is a list of numbers."
      (apply min (map (lambda (x) (car (ly:stencil-extent x axis))) ss))
      (apply max (map (lambda (x) (cdr (ly:stencil-extent x axis))) ss))))
   
-  (define (stack-stencils stencils bskip last-stencil)
+
+  (define (stack-stencils-vertically stencils bskip last-stencil)
     (cond
      ((null? stencils) '())
      ((not (ly:stencil? last-stencil))
       (cons (car stencils)
-           (stack-stencils (cdr stencils) bskip (car stencils))))
+           (stack-stencils-vertically (cdr stencils) bskip (car stencils))))
      (else
       (let* ((orig (car stencils))
             (dir (chain-assoc-get 'direction  props DOWN))
@@ -954,7 +1306,7 @@ the elements marked in @var{indices}, which is a list of numbers."
                                            orig
                                            0.1 bskip)))
 
-       (cons new (stack-stencils (cdr stencils) bskip new))))))
+       (cons new (stack-stencils-vertically (cdr stencils) bskip new))))))
 
   (define (make-brackets stencils indices acc)
     (if (and stencils
@@ -989,9 +1341,15 @@ the elements marked in @var{indices}, which is a list of numbers."
                  x)) args))
         (leading
          (chain-assoc-get 'baseline-skip props))
-        (stacked (stack-stencils
+        (stacked (stack-stencils-vertically
                   (remove ly:stencil-empty? stencils) 1.25 #f))
         (brackets (make-brackets stacked indices '())))
 
     (apply ly:stencil-add
           (append stacked brackets))))
+\f
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; size indications arrow
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+