* lily/parser.yy (scalar): allow \markup { } as property value.
* scm/chord-name.scm: complete new markup usage
* scm/grob-description.scm (all-grob-descriptions): use new markup
texts by default
2002-12-24 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ * Documentation/user/refman.itely (Text markup): rewrite manual section.
+
+ * lily/parser.yy (scalar): allow \markup { } as property value.
+
* scm/chord-name.scm: complete new markup usage
* scm/grob-description.scm (all-grob-descriptions): use new markup
@lilypond[verbatim,singleline]
-#(define text-flat
- '((font-relative-size . -2 ) (music "accidentals--1")))
-
-\score { \notes {
- \property Staff.instrument = #`((kern . 0.5) (lines
- "2 Clarinetti" (columns " (B" ,text-flat ")")))
- c'' 4 }
+\score {
+ \notes \context Staff = treble {
+ \property Staff.instrument
+ = \markup { \column << "Clarinetti" { "in B" \smaller \musicglyph #"accidentals--1" } >> }
+ { c''1 }
+ }
+ \paper { linewidth= 8.0\cm }
}
@end lilypond
@cindex text markup
@cindex markup text
-LilyPond has an internal mechanism to typeset texts. You can
-form text markup expressions by composing scheme expressions
-in the following way.
-
-@lilypond[verbatim, singleline]
- \relative c' {
- \fatText
- a^#"upright"
- b_#'(bold "bold")
- c^#'(italic "italic")
- d_#'((bold italic) "ff")
- e^#'(dynamic "ff")
- f_#'(lines "one" (bold "two"))
- g^#'(music "noteheads-2" ((raise . 2.4) "flags-u3"))
- }
+
+@cindex typeset text
+
+LilyPond has an internal mechanism to typeset texts. You can access it
+with the keyword @code{\markup}. Within markup mode, you can enter texts
+similar to lyrics: simply enter them, surrounded by spaces.
+@cindex markup
+
+@lilypond[verbatim,fragment,relative=1]
+ c1^\markup { hello }
+ c1_\markup { hi there }
+ c1^\markup { hi \bold there, is \italic anyone home? }
@end lilypond
-Normally, the Scheme markup text is stored in the @code{text} property
-of a object. Formally, it is defined as follows:
+@cindex font switching
+The line of the example demonstrates font switching commands. Notice
+that the command only apply to the first following word; enclose a set
+of texts with braces to apply a command to more words.
@example
-text: string | (head? text+)
-head: markup | (markup+)
-markup-item: property | abbrev
-property: (@var{key} . @var{value})
-abbrev: @code{columns lines roman music bold italic named super sub}
- @code{overstrike text finger volta timesig mmrest mark script}
- @code{large Large dynamic}
+ \markup { \bold { hi there } }
@end example
+For clarity, you can also do this for single arguments, e.g.
+@example
+ \markup { is \italic { anyone } home }
+@end example
+
+@cindex font size, texts
+
-The markup is broken down and converted into a list of object properties,
-which are prepended to the property list. The @var{key}-@var{value}
-pair is a object property. A list of properties available is included in
-the generated documentation for @internalsref{text-interface}.
+The following size commands set abolute sizes
+
+@cindex \teeny
+@cindex \tiny
+@cindex \small
+@cindex \large
+@cindex \huge
-The following abbreviations are defined:
@table @code
-@item columns
- horizontal mode: set all text on one line (default)
-@item lines
- vertical mode: set every text on a new line
-@item roman
- select roman font
-@item music
- selects the Feta font (the standard font for music notation glyphs),
-and uses named lookup
-
-@item bold
- select bold series
-@item italic
- select italic shape
-@item named
- lookup by character name
-@item text
- plain text lookup (by character value)
-@item super
- superscript
-@item sub
- subscript
-@item overstrike
- the next text or character overstrikes this one
-@item finger
- select fingering number fontstyle
-@item volta
- select volta number fontstyle
-@item timesig
- select time signature number fontstyle
-@item mmrest
- select multi measure rest number fontstyle
-@item mark
- select mark number fontstyle
-@item script
- select scriptsize roman fontstyle
-@item large
- select large roman fontstyle
-@item Large
- select Large roman fontstyle
-@item dynamic
- select dynamics fontstyle
+@item \teeny
+@item \tiny
+@item \small
+@item \large
+@item \huge
+@end \itemize
+You can also make letter larger or smaller relative to their neighbors,
+with the commands @code{\larger} and @code{\smaller}.
+@cindex smaller
+@cindex larger
+
+@cindex font style, for texts
+@cindex \bold
+@cindex \dynamic
+@cindex \number
+@cindex \italic
+
+The following font change commands are defined:
+@table @code
+@item \dynamic
+This changes to the font used for dynamic signs. Note that this font
+doesn't contain all characters of the alphabet.
+@item \number
+This changes to the font used for time signatures. It only contains
+numbers and a few punctuation marks.
+@item \italic
+@item \bold
@end table
+@cindex raising text
+@cindex lowering text
+@cindex moving text
+@cindex translating text
+
+@cindex \sub
+@cindex \super
+
+Raising and lowering texts can be done with @code{\super} and
+@code{\sub}.
+
+@lilypond[verbatim,fragment,relative=1]
+ c1^\markup { E "=" mc \super "2" }
+@end lilypond
+
+@cindex \raise
+
+If you want to give an explicit amount for lowering or raising, use
+@code{\raise}. This command takes a Scheme valued argument,
+@lilypond[verbatim,fragment,relative=1]
+ c1^\markup { C \small \raise #1.0 { "9/7+" }}
+@end lilypond
+The argument to @code{\raise} is the vertical displacement amount,
+measured in (global) staff spaces.
+
+Other commands taking single arguments include
+@table @code
+
+@item \musicglyph
+@cindex \musicglyph
+ This is converted to a musical symbol, e.g. @code{\musicglyph
+#"accidentals-0"} will select the natural sign from the music font.
+See @ref{The Feta font} for a complete listing of the possible glyphs.
+@item \char
+This produces a single character, e.g. @code{\char #65} produces the
+letter 'A'.
+
+@item \hspace #@var{amount}
+@cindex \hspace
+This produces a invisible object taking horizontal space.
+@example
+\markup { A \hspace #2.0 B }
+@end example
+will put extra space between A and B. Note that lilypond
+inserts space before and after @code{\hspace}.
+
+@item \fontsize #@var{size}
+@cindex \fontsize
+This sets the relative font size, eg.
+@example
+A \fontsize #2 { B C } D
+@end example
+
+This will enlarge the B and the C by two steps.
+@item \translate #(cons @var{x} @var{y})
+@cindex \translate
+This translates an object. It's first argument is a cons of numbers
+@example
+A \translate #(cons 2 -3) { B C } D
+@end example
+This moves `B C' 2 spaces to the right, and 3 down.
+
+@item \magnify #@var{mag}
+@cindex \magnify
+This sets the font magnification for the its argument. In the following
+example, the middle A will be 10% larger.
+@example
+A \magnify #1.1 { A } A
+@end example
+
+
+@item \override #(@var{key} . @var{value})
+@cindex \override
+This overrides a formatting property for its argument. The argument
+should be a key/value pair, e.g.
+@example
+m \override #'(font-family . math) m m
+@end example
+@end table
+
+
+In markup mode you can compose expressions, similar to mathematical
+expressions, XML documents and music expressions. The braces group
+notes into horizontal lines. Other types of lists also exist: you can
+stack expressions grouped with @code{<<}, and @code{>>} vertically with
+the command @code{\column}. The @code{@{} and @code{@}} produce
+@code{\line} commands:
+
+@lilypond[verbatim,fragment,relative=1]
+ c1^\markup { \column << a b c >> }
+ c1^\markup { \line << a b c >> }
+@end lilypond
+
+The markup mechanism is very flexible and extensible. Refer to
+@file{scm/new-markup.scm} for more information.
+
@cindex metronome mark
marking:
@lilypond[verbatim]
-#(define note '(columns
- (music "noteheads-2" ((kern . -0.1) "flags-stem"))))
-#(define eight-note `(columns ,note ((kern . -0.1)
- (music ((raise . 3.5) "flags-u3")))))
-#(define dotted-eight-note
- `(columns ,eight-note (music "dots-dot")))
+eigthStem = \markup \combine
+ \musicglyph #"flags-stem"
+ \translate #'(0.0 . 3.5) \musicglyph #"flags-u3"
+eighthNote = \markup
+ \override #'(word-space . 0.0)
+ { \musicglyph #"noteheads-2"
+ \translate #'(-0.05 . 0.1) \eigthStem }
\score {
\notes\relative c'' {
- a1^#`((columns (font-relative-size . -1))
- ,dotted-eight-note " = 64")
- }
- \paper {
- linewidth = -1.
- \translator{
- \ScoreContext
- TextScript \override #'font-shape = #'upright
- }
+ a1^\markup { \magnify #0.9 \eighthNote " = 64" }
}
}
-@end lilypond
-
@refbugs
-The syntax and semantics of markup texts are not clean, and both
-syntax and semantics are slated for a rewrite.
-
-LilyPond does not do kerning, and there generally spaces texts
-slightly too wide.
+LilyPond account for kerning in its text formatting engine, so it spaces
+texts slightly too wide.
+Syntax errors for markup mode are confusing.
@node Global layout
\version "1.7.6"
\header {texidoc="Stacking of markup scripts."}
\paper { linewidth=-1. }
-\score { \notes { c''^\markup { "a" \column < "1" \bold "2" "3" > } } }
+\score { \notes { c''^\markup { "a" \column << "1" \bold "2" "3" >> } } }
%% new-chords-done %%
\property Voice.TextScript \set #'molecule-callback = #brew-new-markup-molecule
f'-\markup { foo
\raise #0.2 \bold bar
- \override #'(baseline-skip . 4) \column < baz bazr bla >
+ \override #'(baseline-skip . 4) \column << baz bazr bla >>
\hspace #2.0
\override #'(font-family . music) {
\lookup #"noteheads-0"
\char #53
}
-
+ \musicglyph #"accidentals--1"
\combine "X" "+"
\combine "o" "/"
"$\\emptyset$"
+\header {
+texidoc = "Instrument names are
+set with Staff.instrument and Staff.instr"
+}
+
+
\version "1.7.6"
\score {
+ \notes \context Staff = treble {
+ \property Staff.instrument
+ = \markup { \column << "Clarinetti" { "in B" \smaller \musicglyph #"accidentals--1" } >> }
+ \property Staff.instr
+ = \markup { \smaller { "Cl(B" \smaller \musicglyph #"accidentals--1" ")" } }
- \notes \context Staff = treble {
- \property Staff.instrument = "instr " { c''4 }}
+ { c''1 \break c'' }
-\paper {
-linewidth=-1.0
-\translator { \StaffContext \consists "Instrument_name_engraver" }
-}}
+ }
+ \paper { linewidth= 8.0\cm }
+}
%% new-chords-done %%
% Warning
%
% This is not a feature, it is a hack. If you change anything,
-% it will probably break (that's because scm markup text is a
-% bit broken and needs fixing). Chances are, it's already
-% broken by the time you read this. Don't complain.
-%
+% it will probably break
+
% FIXME: put in an item, and typeset by an engraver.
eigthStem = \markup \combine
{
header_ = SCM_EOL;
global_input_file = this;
- ly_set_point_and_click_x (SCM_BOOL_F);
+ ly_set_point_and_click (SCM_BOOL_F);
sources_.set_path (&global_path);
yylval.scm = sval;
return SCM_T;
}
-<INITIAL,notes>{
+<INITIAL,notes,markup>{
\<\< {
return CHORD_OPEN;
}
string { $$ = $1; }
| bare_int { $$ = gh_int2scm ($1); }
| embedded_scm { $$ = $1; }
+ | full_markup { $$ = $1; }
;
;
markup_list:
- '<' markup_list_body '>' { $$ = scm_reverse_x ($2, SCM_EOL); }
+ CHORD_OPEN markup_list_body CHORD_CLOSE { $$ = scm_reverse_x ($2, SCM_EOL); }
;
markup_line:
(ice-9 string-fun)
)
+
+;; debugging.
+(define (mydisplay x) (display x) x)
+
+
"
TODO:
-- Use lilypond Pitch objects -- SCM pitch objects leads to duplication.
+- Use lilypond Pitch objects -- SCM pitch objects lead to
+duplication. LilyPond pitch objects force meaningful names
+(i.e. (ly:pitch-octave PITCH) )
+
- Pitches are musical objects. The pitches -> markup step should
happen earlier (during interpreting), brew-molecule () should only
"
+
;; pitch = (octave notename alteration)
;;
;; note = (notename . alteration)
(append
`(
; C iso C.no3.no5
- (((0 . 0)) . (,simple-markup ""))
+ (((0 . 0)) . ,empty-markup)
; C iso C.no5
- (((0 . 0) (2 . 0)) . (,simple-markup ""))
+ (((0 . 0) (2 . 0)) . ,empty-markup)
; Cm iso Cm.no5
(((0 . 0) (2 . -1)) . (,simple-markup "m"))
; C2 iso C2.no3
(define (accidental-markup acc)
"ACC is an int, return a markup making an accidental."
(if (= acc 0)
- `(,simple-markup "")
+ empty-markup
`(,smaller-markup (,musicglyph-markup ,(string-append "accidentals-" (number->string acc))))
))
(define (pitch->markup pitch)
- (list line-markup
- (list
- (list simple-markup
- (make-string 1 (integer->char (+ (modulo (+ (cadr pitch) 2) 7) 65))))
- (list normal-size-superscript-markup
- (accidental-markup (caddr pitch))))))
+ `(,line-markup
+ (
+ (,simple-markup
+ ,(make-string 1 (integer->char (+ (modulo (+ (cadr pitch) 2) 7) 65))))
+ (,normal-size-superscript-markup
+ ,(accidental-markup (caddr pitch))))))
;;; Hooks to override chord names and note names,
;;; see input/tricks/german-chords.ly
(define (step->markup pitch)
(string-append
- (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))
- (case (caddr pitch)
+ (number->string (+ (cadr pitch) (if (= (car pitch) 0) 1 8)))
+ (case (caddr pitch)
((-2) "--")
((-1) "-")
((0) "")
((2) "++"))))
(define (step->markup-banter pitch)
- (list simple-markup
+ (list simple-markup
(if (= (cadr pitch) 6)
(case (caddr pitch)
((-2) "7-")
step))
(chord::additions->markup-banter (cdr additions) subtractions)))
- (list simple-markup "")
-
+ empty-markup
))
(define (chord::subtractions->markup-banter subtractions)
(if (pair? subtractions)
- (list line-markup
- (list simple-markup "no")
- (let ((step (step->markup-jazz (car subtractions))))
- (if (pair? (cdr subtractions))
- (list line-markup (list step (list simple-markup "/")))
- step))
- (chord::subtractions->markup-banter (cdr subtractions)))
- (list simple-markup "")
+ `(,line-markup
+ ((,simple-markup "no")
+ ,(let ((step (step->markup-jazz (car subtractions))))
+ (if (pair? (cdr subtractions))
+ `(,line-markup (,step (,simple-markup "/")))
+ step))
+ ,(chord::subtractions->markup-banter (cdr subtractions))))
+ empty-markup
))
(define (chord::bass-and-inversion->markup-banter bass-and-inversion)
(if (and (pair? bass-and-inversion)
(or (car bass-and-inversion)
(cdr bass-and-inversion)))
- (list
- line-markup
- (list
- (list simple-markup "/")
- (pitch->note-name-markup-banter
- (if (car bass-and-inversion)
- (car bass-and-inversion)
- (cdr bass-and-inversion)))
- ))
- (list simple-markup "")
+ `(,line-markup
+ (
+ (,simple-markup "/")
+ ,(pitch->note-name-markup-banter
+ (if (car bass-and-inversion)
+ (car bass-and-inversion)
+ (cdr bass-and-inversion)))
+ ))
+ empty-markup
))
;; FIXME: merge this function with inner-name-jazz, -american
"
(let* ((tonic-markup (pitch->chord-name-markup-banter tonic steps))
- (except-markup exception-part)
+ (except-markup
+
+ ;; see below.
+ (if exception-part exception-part `(,simple-markup "fixme")))
(sep-markup (list simple-markup
(if (and (string-match "super" (format "~s" except-markup))
(or (pair? additions)
(adds-markup (chord::additions->markup-banter additions subtractions))
(subs-markup (chord::subtractions->markup-banter subtractions))
(b+i-markup (chord::bass-and-inversion->markup-banter bass-and-inversion)))
-
+
`(,line-markup
(,tonic-markup
,except-markup
(string-append (symbol->string name)
(symbol->string style)))))
-;; check exceptions-alist for biggest matching part of try-steps
-;; return (MATCHED-EXCEPTION . UNMATCHED-STEPS)
+
+;; this is unintelligible.
+;;
+
+;
+; - what's a helper, and why isn't it inside another function?
+;
+; what is going out, what is coming in, howcome it produces #f
+; in some cases?
+;
+
(define (chord::exceptions-lookup-helper
exceptions-alist try-steps unmatched-steps exception-part)
+ "
+
+ check exceptions-alist for biggest matching part of try-steps
+ return (MATCHED-EXCEPTION . UNMATCHED-STEPS)
+
+"
(if (pair? try-steps)
;; FIXME: junk '(0 . 0) from exceptions lists?
;; if so: how to handle first '((0 . 0) . #f) entry?
(cons (car r) unmatched-steps) #f))))
(cons exception-part unmatched-steps)))
-;; return (MATCHED-EXCEPTION . BASE-CHORD-WITH-UNMATCHED-STEPS)
-;; BASE-CHORD-WITH-UNMATCHED-STEPS always includes (tonic 3 5)
+;; see above.
+
(define (chord::exceptions-lookup style steps)
+ "
+ return (MATCHED-EXCEPTION . BASE-CHORD-WITH-UNMATCHED-STEPS)
+ BASE-CHORD-WITH-UNMATCHED-STEPS always includes (tonic 3 5)
+
+"
+
(let* ((result (chord::exceptions-lookup-helper
(chord::restyle 'chord::names-alist- style)
steps '() #f))
(exception-part (car lookup))
(unmatched-steps (cadr lookup))
(func (chord::restyle 'chord::name- style))
-
)
(cdr pitches))
'())))
- (chord::name->markup style (car pitches) steps bass-and-inversion)
+ (chord::name->markup style (car pitches) steps bass-and-inversion)
))
;;;
(,simple-markup " 7"))))
(((0 . 0) (2 . 0) (4 . 1) (6 . -1)) . (,simple-markup "aug7"))
(((0 . 0) (2 . 0) (4 . -1) (6 . 0))
- . (line-markup
+ . (,line-markup
((,simple-markup "maj7")
(,small-markup (,raise-markup 0.2 ,(accidental-markup -1)))
(,simple-markup "5"))))
(((0 . 0) (2 . 0) (4 . -1) (6 . -1)) .
- (line-markup
+ (,line-markup
((,simple-markup "7")
(,small-markup (,raise-markup 0.2 ,(accidental-markup -1)))
(,simple-markup "5"))))
)
chord::names-alist-american))
-
;; American style chordnames use no "no",
;; but otherwise very similar to banter for now
(define-public (chord::name-american tonic exception-part unmatched-steps
(chord::inner-name-banter tonic exception-part additions subtractions
bass-and-inversion steps)))
-
-
;;;
;;; Jazz style
;;;
;; shouldn't this be a filled black triange, like this: ? --jcn
;;(((0 . 0) (2 . -1) (4 . 0) (6 . 0)) . (columns ("m") ((raise . 0.5)((font-family . math) "N"))))
(((0 . 0) (2 . -1) (4 . 0) (6 . 0)) .
- (,line-markup (,simple-markup "m") ,mathm-markup-object))
+ (,line-markup ((,simple-markup "m") ,mathm-markup-object)))
; minor seventh chord = m7
(((0 . 0) (2 . -1) (4 . 0) (6 . -1)) . ,(mraise-arg "7"))
; minor sixth nine chord = m6/9
(if (pair? sus)
`(,line-markup ((,simple-markup "sus")
,(step->markup-jazz (car sus))))
- `(,simple-markup "")))
- )
+ empty-markup)
+ ))
(define (chord::additions>5->markup-jazz additions subtractions)
(define chord::names-alist-jazz
(append
`(
- (((0 . 0) (2 . -1)) . ("m"))
+ (((0 . 0) (2 . -1)) . (,simple-markup "m"))
;; some fixups -- jcn
; major seventh chord = triangle
. (
(molecule-callback . ,brew-bass-figure)
(Y-offset-callbacks . (,Self_alignment_interface::aligned_on_self))
- (direction . 0)
+ (direction . 1)
(font-family . number)
(font-relative-size . -3)
(padding . 0.1)
+
+"
+Internally markup is stored as lists, whose head is a function.
+
+ (FUNCTION ARG1 ARG2 ... )
+
+When it is applied, then FUNCTION is called as follows
+
+ (FUNCTION GROB PROPS ARG1 ARG2 ... )
+
+The function should return a molecule (i.e. a formatted, ready to
+print object).
+
+To add a function,
+
+1. It should be named COMMAND-markup
+
+2. It should have an object property set that describes it's
+signature. This is to allow the parser to figure out how many
+arguments to expect:
+
+ (set-object-property! COMMAND-markup scm0-markup1)
+
+3. The command is now available in markup mode, e.g.
+
+
+ \markup { .... \COMMAND #1 argument ... }
+
+
+BUGS:
+
+At present, markup functions must be defined in this
+file. Implementing user-access for markup functions is an excercise
+for the reader.
+
+
+
+
+"
+
(define-public (simple-markup grob props . rest)
(Text_item::text_to_molecule grob props (car rest))
)
(set-object-property! (car x) 'markup-signature (cdr x))
)
(list
- (cons bold-markup 'markup0)
+
+ ;; abs size
(cons teeny-markup 'markup0)
(cons tiny-markup 'markup0)
(cons small-markup 'markup0)
- (cons smaller-markup 'markup0)
- (cons bigger-markup 'markup0)
- (cons italic-markup 'markup0)
(cons dynamic-markup 'markup0)
(cons large-markup 'markup0)
- (cons huge-markup 'markup0)
+ (cons huge-markup 'markup0)
+
+ ;; size
+ (cons smaller-markup 'markup0)
+ (cons bigger-markup 'markup0)
+
+ ;;
(cons sub-markup 'markup0)
(cons super-markup 'markup0)
+
+ (cons bold-markup 'markup0)
+ (cons italic-markup 'markup0)
+
(cons number-markup 'markup0)
+
(cons column-markup 'markup-list0)
(cons line-markup 'markup-list0)
+
(cons combine-markup 'markup0-markup1)
(cons simple-markup 'markup0)
(cons musicglyph-markup 'scm0)
+
(cons translate-markup 'scm0-markup1)
(cons override-markup 'scm0-markup1)
- (cons lookup-markup 'scm0)
- (cons raise-markup 'scm0-markup1)
(cons char-markup 'scm0)
+ (cons lookup-markup 'scm0)
+
+
(cons hspace-markup 'scm0)
+
+ (cons raise-markup 'scm0-markup1)
(cons magnify-markup 'scm0-markup1)
(cons fontsize-markup 'scm0-markup1)
(cons translate-markup 'scm0-markup1)