+(def-markup-command (justify layout props args) (markup-list?)
+ "Simple wordwrap"
+
+ (wordwrap-markups layout props args #t))
+
+(def-markup-command (wordwrap layout props args) (markup-list?)
+ "Like wordwrap, but with lines stretched to justify the margins."
+
+ (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 'linewidth props))
+ (word-space (chain-assoc-get 'word-space props))
+ (para-strings (regexp-split 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)))
+ (lines (wordwrap-stencils stencils
+ justify word-space line-width)))
+
+ 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 (combine layout props m1 m2) (markup? markup?)
+ "Print two markups on top of each other."
+ (let* ((s1 (interpret-markup layout props m1))
+ (s2 (interpret-markup layout props m2)))
+ (ly:stencil-add s1 s2)))
+
+;;
+;; TODO: should extract baseline-skip from each argument somehow..
+;;
+(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))))
+
+(def-markup-command (dir-column layout props args) (markup-list?)
+ "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)
+ (map (lambda (x) (interpret-markup layout props x)) args))))
+
+(def-markup-command (center-align layout props args) (markup-list?)
+ "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?)
+ "Align @code{arg} to its Y center. "
+ (let* ((mol (interpret-markup layout props arg)))
+ (ly:stencil-aligned-to mol Y CENTER)))
+
+(def-markup-command (hcenter layout props arg) (markup?)
+ "Align @code{arg} to its X center. "
+ (let* ((mol (interpret-markup layout props arg)))
+ (ly:stencil-aligned-to mol X CENTER)))
+
+(def-markup-command (right-align layout props arg) (markup?)
+ "Align @var{arg} on its right edge. "
+ (let* ((m (interpret-markup layout props arg)))
+ (ly:stencil-aligned-to m X RIGHT)))
+
+(def-markup-command (left-align layout props arg) (markup?)
+ "Align @var{arg} on its left edge. "
+ (let* ((m (interpret-markup layout props arg)))
+ (ly:stencil-aligned-to m X LEFT)))
+
+(def-markup-command (general-align layout props axis dir arg) (integer? number? markup?)
+ "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)))
+
+(def-markup-command (halign layout props dir arg) (number? markup?)
+ "Set horizontal alignment. If @var{dir} is @code{-1}, then it is
+left-aligned, while @code{+1} is right. Values in between interpolate
+alignment accordingly."
+ (let* ((m (interpret-markup layout props arg)))
+ (ly:stencil-aligned-to m X dir)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; property
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(def-markup-command (fromproperty layout props symbol) (symbol?)
+ "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)))