Use scalar instead of embedded_scm for context mod overrides.
[lilypond/mpolesky.git] / lily / text-interface.cc
blobaba3105a187bf2157cdfa4c9e24e5e5c690007c7
1 /*
2 text-interface.cc -- implement Text_interface
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 Jan Nieuwenhuizen <janneke@gnu.org>
8 */
10 #include "text-interface.hh"
12 #include "config.hh"
13 #include "font-interface.hh"
14 #include "grob.hh"
15 #include "main.hh"
16 #include "misc.hh"
17 #include "modified-font-metric.hh"
18 #include "output-def.hh"
19 #include "pango-font.hh"
20 #include "warn.hh"
22 static void
23 replace_whitespace (string *str)
25 vsize i = 0;
26 vsize n = str->size ();
28 while (i < n)
30 char cur = (*str)[i];
32 // avoid the locale-dependent isspace
33 if (cur == '\n' || cur == '\t' || cur == '\v')
34 (*str)[i] = ' ';
36 vsize char_len = utf8_char_len (cur);
38 i += char_len;
42 MAKE_SCHEME_CALLBACK (Text_interface, interpret_string, 3);
43 SCM
44 Text_interface::interpret_string (SCM layout_smob,
45 SCM props,
46 SCM markup)
48 LY_ASSERT_SMOB (Output_def, layout_smob, 1);
49 LY_ASSERT_TYPE (scm_is_string, markup, 3);
51 string str = ly_scm2string (markup);
52 Output_def *layout = unsmob_output_def (layout_smob);
53 Font_metric *fm = select_encoded_font (layout, props);
55 replace_whitespace (&str);
58 We want to use "glyph-string" in the SVG backend for all
59 music fonts (Emmentaler and Aybabtu) that pass through the
60 text interface. Here the font encoding is checked to see if
61 it matches one of the music font encodings. --pmccarty
63 SCM encoding = ly_chain_assoc_get (ly_symbol2scm ("font-encoding"),
64 props,
65 SCM_BOOL_F);
66 SCM music_encodings = ly_lily_module_constant ("all-music-font-encodings");
68 if (scm_memq (encoding, music_encodings) != SCM_BOOL_F)
69 return fm->word_stencil (str, true).smobbed_copy ();
70 else
71 return fm->word_stencil (str, false).smobbed_copy ();
74 MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Text_interface, interpret_markup, 3, 0,
75 "Convert a text markup into a stencil."
76 " Takes three arguments, @var{layout}, @var{props}, and @var{markup}.\n"
77 "\n"
78 "@var{layout} is a @code{\\layout} block; it may be obtained from a grob with"
79 " @code{ly:grob-layout}. @var{props} is an alist chain, i.e. a list of"
80 " alists. This is typically obtained with"
81 " @code{(ly:grob-alist-chain grob (ly:output-def-lookup layout 'text-font-defaults))}."
82 " @var{markup} is the markup text to be processed.");
83 SCM
84 Text_interface::interpret_markup (SCM layout_smob, SCM props, SCM markup)
86 if (scm_is_string (markup))
87 return interpret_string (layout_smob, props, markup);
88 else if (scm_is_pair (markup))
90 SCM func = scm_car (markup);
91 SCM args = scm_cdr (markup);
92 if (!is_markup (markup))
93 programming_error ("markup head has no markup signature");
95 return scm_apply_2 (func, layout_smob, props, args);
97 else
99 programming_error ("Object is not a markup. ");
100 scm_puts ("This object should be a markup: ", scm_current_error_port ());
101 scm_display (markup, scm_current_error_port ());
102 scm_puts ("\n", scm_current_error_port ());
104 Box b;
105 b[X_AXIS].set_empty ();
106 b[Y_AXIS].set_empty ();
108 Stencil s (b, SCM_EOL);
109 return s.smobbed_copy ();
113 MAKE_SCHEME_CALLBACK (Text_interface, print, 1);
115 Text_interface::print (SCM grob)
117 Grob *me = unsmob_grob (grob);
119 SCM t = me->get_property ("text");
120 SCM chain = Font_interface::text_font_alist_chain (me);
121 return interpret_markup (me->layout ()->self_scm (), chain, t);
124 /* Ugh. Duplicated from Scheme. */
125 bool
126 Text_interface::is_markup (SCM x)
128 return (scm_is_string (x)
129 || (scm_is_pair (x)
130 && SCM_BOOL_F
131 != scm_object_property (scm_car (x),
132 ly_symbol2scm ("markup-signature"))));
135 bool
136 Text_interface::is_markup_list (SCM x)
138 SCM music_list_p = ly_lily_module_constant ("markup-list?");
139 return scm_is_true (scm_call_1 (music_list_p, x));
143 ADD_INTERFACE (Text_interface,
144 "A Scheme markup text, see @ruser{Formatting text} and"
145 " @rextend{New markup command definition}.\n"
146 "\n"
147 "There are two important commands:"
148 " @code{ly:text-interface::print}, which is a"
149 " grob callback, and"
150 " @code{ly:text-interface::interpret-markup}.",
152 /* properties */
153 "baseline-skip "
154 "text "
155 "word-space "
156 "text-direction "