1 #include "scommands.hh"
3 #include "parseconstruct.hh"
10 maybe it's time for a "narrowing" cursor?
13 Score_commands::first(Real w
)
15 PCursor
<Command
*> pc(*this);
16 while (pc
.ok() && pc
->when
< w
)
18 if (!pc
.ok() || pc
->when
!= w
) {
19 Command
*c
= new Command(w
);
30 RETURN: pc->when == w && pc.ok
34 Score_commands::last_insertion(Real w
)
36 PCursor
<Command
*> pc(first(w
)), next(pc
);
37 while (next
.ok() && next
->when
== w
) {
41 if (pc
->priority
!= -10000) {
42 Command
*c
= new Command(w
);
54 Score_commands::add_seq(svec
<Command
> com
, bool checkbreak
)
59 Real when
= com
[0].when
;
61 PCursor
<Command
*> begin(first(when
));
62 PCursor
<Command
*> end(last_insertion(when
));
63 if (checkbreak
&& is_breakable(when
)) {
64 if (com
[0].priority
< 0)
65 while (begin
->code
!= BREAK_END
)
68 while (end
->code
!= BREAK_PRE
)
71 for (int i
= 0; i
< com
.sz(); i
++) {
72 insert_between(com
[i
], begin
, end
);
77 Score_commands::set_breakable(Real when
)
79 bool found_typeset(false);
80 PCursor
<Command
*> cc
= first(when
);
81 for (; cc
.ok() && cc
->when
== when
; cc
++) {
84 if (cc
->code
== TYPESET
)
88 assert(!found_typeset
);
96 k
.code
= BREAK_MIDDLE
;
109 Score_commands::is_breakable(Real w
)
111 PCursor
<Command
*> cc
= first(w
);
112 for (; cc
.ok() && cc
->when
== w
; cc
++) {
120 Score_commands::insert_between(Command victim
, PCursor
<Command
*> firstc
,
121 PCursor
<Command
*> last
)
123 PCursor
<Command
*> c(firstc
+1);
124 assert(last
->when
==firstc
->when
&&firstc
< last
&&last
.ok());
127 if (c
->priority
<= victim
.priority
) {
128 c
.insert(new Command(victim
));
133 last
.insert(new Command(victim
));
137 Score_commands::add_command_to_break(Command pre
, Command mid
, Command post
)
141 PCursor
<Command
*> c ( first(w
)), f(c
), l(c
);
143 while (!c
->isbreak())
146 while (!c
->isbreak())
150 insert_between(pre
, f
, l
);
152 while (!c
->isbreak())
155 insert_between(mid
, f
, l
);
157 while (!c
->isbreak())
160 assert(l
.ok() && l
->when
==w
&& l
->code
== BREAK_END
);
162 insert_between(post
, f
, l
);
166 Score_commands::parser_add(Command
*c
)
172 Score_commands::process_add(Command c
)
174 bool encapsulate
=false;
182 if (c
.code
== INTERPRET
)
184 if (c
.args
[0] == "BAR") {
185 Command
typeset(w
); // kut met peren
186 typeset
.code
= TYPESET
;
187 typeset
.args
= c
.args
;
188 typeset
.priority
= 100;
189 process_add(typeset
);
190 } else if (c
.args
[0] == "KEY") {
192 typeset
.code
= TYPESET
;
193 typeset
.args
.add("KEY");
194 typeset
.priority
= 70;
195 process_add(typeset
);
196 } else if (c
.args
[0] == "CLEF") {
198 typeset
.code
= TYPESET
;
200 typeset
.priority
= 90;
201 process_add(typeset
);
206 if (c
.code
== TYPESET
) {
207 if (c
.args
[0] == "BAR") {
212 { /* every line a currentkey. */
215 kc
.args
.add( "CURRENTKEY");
219 { /* every line a currentclef. */
222 kc
.args
.add( "CURRENTCLEF");
227 if (c
.args
[0] == "METER" && is_breakable(w
)) {
233 if( c
.args
[0] == "KEY" && is_breakable(c
.when
)) {
239 if (c
.args
[0] == "CURRENTKEY" && is_breakable(w
)) {
243 if (c
.args
[0] == "CURRENTCLEF" && is_breakable(w
)) {
247 if (c
.args
[0] == "CLEF" && is_breakable(w
)) {
256 add_command_to_break(pre
, mid
, post
);
265 first and last column should be breakable.
266 Remove any command past the last musical column.
269 Score_commands::clean(Real l
)
272 if (!is_breakable(0.0)) {
280 PCursor
<Command
*> bot(bottom());
282 while (bot
.ok() && bot
->when
> l
) {
289 if (!is_breakable(l
)) {
300 Score_commands::OK() const
302 for (PCursor
<Command
*> cc(*this); cc
.ok() && (cc
+1).ok(); cc
++) {
303 assert(cc
->when
<= (cc
+1)->when
);
304 if (cc
->when
== (cc
+1)->when
&& !cc
->isbreak() && !(cc
+1)->isbreak())
305 assert(cc
->priority
>= (cc
+1)->priority
);
310 Score_commands::print() const
312 for (PCursor
<Command
*> cc(*this); cc
.ok() ; cc
++) {
321 Score_commands::parse(Real l
) const
323 Score_commands
*nc
= new Score_commands
;
324 int beats_per_meas
=4;
325 Real measlen
= 1.0; // 4/4 by default
332 { /* all pieces should start with a breakable. */
339 for (PCursor
<Command
*> cc(*this); cc
.ok() && cc
->when
<= l
; cc
++) {
340 assert (cc
->code
==INTERPRET
);
341 if (cc
->args
[0] == "METER") {
342 beats_per_meas
= cc
->args
[1].value();
343 int one_beat
= cc
->args
[2].value();
344 measlen
= beats_per_meas
/Real(one_beat
);
345 nc
->process_add(*get_meter_command(wholes
, beats_per_meas
, one_beat
));
347 if (cc
->args
[0] == "KEY"||cc
->args
[0] == "CLEF") {
349 nc
->process_add(**cc
);
351 if (cc
->args
[0] == "SKIP") {
352 stoppos
= wholes
+ cc
->args
[1].value() * measlen
+
353 cc
->args
[2].fvalue();
354 wholes
+= (measlen
-inbar
); // skip at least 1 measure
356 while (wholes
<= stoppos
) {
357 nc
->process_add(*get_bar_command(wholes
)); // liek