X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fcontext-property.cc;h=4d1de2403460d631be0eeb4ef752ede71f3c2feb;hb=e5cc39a9a82b3c05156553173a8513db4152b1f9;hp=5234d1113fccc00ccd1b9421697609bb72ea5f13;hpb=c790b5919ec06fb292e380a2d3d7856e86f16417;p=lilypond.git diff --git a/lily/context-property.cc b/lily/context-property.cc index 5234d1113f..4d1de24034 100644 --- a/lily/context-property.cc +++ b/lily/context-property.cc @@ -1,10 +1,20 @@ /* - context-property.cc -- implement manipulation of immutable Grob - property lists. + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 2004--2011 Han-Wen Nienhuys - (c) 2004--2007 Han-Wen Nienhuys + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ #include "context.hh" @@ -16,13 +26,15 @@ #include "spanner.hh" #include "warn.hh" - +/* + like execute_general_pushpop_property(), but typecheck + grob_property_path and context_property. +*/ void general_pushpop_property (Context *context, SCM context_property, SCM grob_property_path, - SCM new_value - ) + SCM new_value) { if (!scm_is_symbol (context_property) || !scm_is_symbol (scm_car (grob_property_path))) @@ -32,25 +44,22 @@ general_pushpop_property (Context *context, assert (false); } - execute_general_pushpop_property (context, context_property, - grob_property_path, new_value); + sloppy_general_pushpop_property (context, context_property, + grob_property_path, new_value); } /* - Grob descriptions (ie. alists with layout properties) are represented as a (ALIST . BASED-ON) pair, where BASED-ON is the alist defined in a parent context. BASED-ON should always be a tail of ALIST. - Push or pop (depending on value of VAL) a single entry entry from a + Push or pop (depending on value of VAL) a single entry from a translator property list by name of PROP. GROB_PROPERTY_PATH indicates nested alists, eg. '(beamed-stem-lengths details) - -*/ - +*/ void execute_override_property (Context *context, SCM context_property, @@ -58,7 +67,7 @@ execute_override_property (Context *context, SCM new_value) { SCM current_context_val = SCM_EOL; - + Context *where = context->where_defined (context_property, ¤t_context_val); @@ -83,19 +92,26 @@ execute_override_property (Context *context, SCM target_alist = scm_car (current_context_val); + /* + If the car is a list, the property path comes from a nested override + using list syntax inside a \context block + */ + if (scm_is_pair (scm_car (grob_property_path))) + grob_property_path = scm_car (grob_property_path); + SCM symbol = scm_car (grob_property_path); if (scm_is_pair (scm_cdr (grob_property_path))) { - new_value = nested_property_alist (ly_assoc_get (symbol, target_alist, + new_value = nested_property_alist (ly_assoc_get (symbol, target_alist, SCM_EOL), scm_cdr (grob_property_path), new_value); } - // it's tempting to replace the head of the list if it's the same - // property. However, we have to keep this info around, in case we have to - // \revert back to it. - + /* it's tempting to replace the head of the list if it's the same + property. However, we have to keep this info around, in case we have to + \revert back to it. + */ target_alist = scm_acons (symbol, new_value, target_alist); bool ok = true; @@ -115,37 +131,35 @@ execute_override_property (Context *context, } } +/* + do a pop (indicated by new_value==SCM_UNDEFINED) or push + */ void -execute_revert_property (Context *context, - SCM context_property, - SCM grob_property_path); - -void -execute_general_pushpop_property (Context *context, - SCM context_property, - SCM grob_property_path, - SCM new_value - ) +sloppy_general_pushpop_property (Context *context, + SCM context_property, + SCM grob_property_path, + SCM new_value) { - if (new_value != SCM_UNDEFINED) + if (new_value == SCM_UNDEFINED) + execute_revert_property (context, context_property, + grob_property_path); + else execute_override_property (context, context_property, grob_property_path, new_value); - else - execute_revert_property (context, context_property, - grob_property_path); } +/* + Revert the property given by property_path. +*/ void execute_revert_property (Context *context, SCM context_property, SCM grob_property_path) { - /* - revert. - */ SCM current_context_val = SCM_EOL; - if (context->where_defined (context_property, ¤t_context_val) == context) + if (context->where_defined (context_property, ¤t_context_val) + == context) { SCM current_alist = scm_car (current_context_val); SCM daddy = scm_cdr (current_context_val); @@ -156,14 +170,15 @@ execute_revert_property (Context *context, programming_error ("Grob property path should be list of symbols."); return; } - - SCM symbol = scm_car (grob_property_path); + SCM symbol = scm_car (grob_property_path); if (scm_is_pair (scm_cdr (grob_property_path))) { SCM current_sub_alist = ly_assoc_get (symbol, current_alist, SCM_EOL); - SCM new_val = nested_property_revert_alist (current_sub_alist, scm_cdr (grob_property_path)); - + SCM new_val + = nested_property_revert_alist (current_sub_alist, + scm_cdr (grob_property_path)); + if (scm_is_pair (current_alist) && scm_caar (current_alist) == symbol && current_alist != daddy) @@ -175,27 +190,30 @@ execute_revert_property (Context *context, else { SCM new_alist = evict_from_alist (symbol, current_alist, daddy); - + if (new_alist == daddy) context->unset_property (context_property); else - context->set_property (context_property, scm_cons (new_alist, daddy)); + context->set_property (context_property, + scm_cons (new_alist, daddy)); } } } - +/* + Convenience: a push/pop grob property using a single grob_property + as argument. +*/ void execute_pushpop_property (Context *context, SCM context_property, SCM grob_property, - SCM new_value - ) + SCM new_value) { general_pushpop_property (context, context_property, scm_list_1 (grob_property), new_value); } - + /* PRE_INIT_OPS is in the order specified, and hence must be reversed. */ @@ -214,14 +232,14 @@ apply_property_operations (Context *tg, SCM pre_init_ops) SCM context_prop = scm_car (entry); SCM val = scm_cadr (entry); SCM grob_prop_path = scm_cddr (entry); - execute_general_pushpop_property (tg, context_prop, grob_prop_path, val); + sloppy_general_pushpop_property (tg, context_prop, grob_prop_path, val); } else if (type == ly_symbol2scm ("pop")) { SCM context_prop = scm_car (entry); SCM val = SCM_UNDEFINED; SCM grob_prop_path = scm_cdr (entry); - execute_general_pushpop_property (tg, context_prop, grob_prop_path, val); + sloppy_general_pushpop_property (tg, context_prop, grob_prop_path, val); } else if (type == ly_symbol2scm ("assign")) tg->set_property (scm_car (entry), scm_cadr (entry));