/tags/2.4/tags/parser/charge.inc
PHP | 233 lines | 175 code | 31 blank | 27 comment | 48 complexity | c5d3a67d1fe95a155389b797b40dfb4c MD5 | raw file
- <?php /* Copyright 2010 Karl R. Wilcox
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License. */
- function adjacent(&$node, $found_between = false) {
- global $dom;
- static $adjacent_charge = array (
- array ( true, 'between', 'between' ),
- array ( true, 'within', 'within' ),
- array ( true, 'above', 'above' ),
- array ( true, 'below', 'below' ),
- array ( true, 'with', 'below' ),
- );
- // Does this charge go "between/above/below" some others?
- if ( $found_between )
- $position = 'between';
- elseif (( $match = search_match($adjacent_charge)) != null )
- $position = $match[2];
- else
- return;
- $adj_mod = make_mod($position);
- if ( $position == 'within' ) { // could be charge or ordinary
- if ( (($adj_charge = charge()) == null) and (($adj_charge = ordinary()) == null) ){
- $adj_charge = $dom->createElement('missing');
- parser_message('blazon', 'Nothing to go within');
- }
- } else { // 'between' can only be a charge
- if ( ($adj_charge = charge()) == null ) {
- $adj_charge = $dom->createElement('missing');
- parser_message('blazon', 'Nothing to go between');
- }
- }
- $adj_mod->appendChild ( $adj_charge);
- $node->appendChild($adj_mod);
- // keep looking for more of the same
- while ( !semicolon() and andd() and (($adj_charge = charge()) != null ) ) {
- $adj_mod = make_mod($position);
- $adj_mod->appendChild($adj_charge);
- $node->appendChild($adj_mod);
- }
- }
- function bundle ( &$node ) {
- static $bundle_words = array (
- array ( 'bundle', '(sheaf|sheave|bundle|tuft)s?', 3 ),
- array ( 'bundle', 'pair', 2), // just to demonstrate different defaults really....
- );
- static $of_words = array (
- array ( true, 'of', ),
- );
- if ( ($match = search_match($bundle_words)) != null ) {
- $num = 0;
- if ( search_match($of_words) != null ) $num = number();
- if ( $num < 1) $num = $match[2];
- $node->appendChild( make_mod ( $match[0], "$num" ));
- }
- }
- function demi() {
- $prefix_words = array (
- array ( null, 'demi|half' ),
- );
- return search_match($prefix_words);
- }
- function get_feature_tinc($node) {
- foreach ( $node->childNodes as $child ) {
- if ( $child->nodeName == 'feature' ) {
- if ( ($tinc = get_child($child, 'tincture')) != null )
- return deep_copy($tinc);
- }
- }
- return null;
- }
- function simple_charge( $assume_num = false, $allow_arr_pos = false ) {
- global $dom;
- global $flag_list;
- global $charge_list;
- global $modifier_list;
- global $pending_items;
- $specific_features = null;
- $flags = array();
- $state = save();
- // Look for a number
- if ( ($num = number()) == null) {
- if ( $assume_num ) {
- if ( is_int($assume_num) )
- $num = $assume_num;
- else
- $num = 1;
- } else {
- restore($state);
- return null;
- }
- }
- $node = $dom->createElement('charge');
- // Look for grouping words (bundle of etc.)
- bundle( $node );
- if ( demi() ) $node->appendChild(make_mod('demi'));
- if ( (($match = either('charge')) == null) and (($match = search_match($charge_list)) == null ) ) {
- restore($state);
- return null;
- }
- // We have a charge
- $type = $match[2];
- $subtype = $match[0];
- $node->setAttribute('type', $type);
- $node->setAttribute('subtype', $subtype);
- $node->setAttribute('tokens',tokens());
- $node->setAttribute('number',"$num");
- $a_key = 'c:' . $subtype;
- // Get the set of features and flags, (if any)
- if ( array_key_exists($a_key, $modifier_list ))
- $specific_features = $modifier_list[$a_key];
- if ( array_key_exists($a_key, $flag_list ))
- $flags = $flag_list[$a_key];
- // Sometimes we want to just get the next word as a string
- if ( array_key_exists('get_item', $flags))
- $node->appendChild( make_mod('item',get_tokens($flags['get_item'])));
- // Look for grouping words again
- bundle( $node );
- $mod_set = array ('simple_charge', 'rows', $specific_features);
- if ( $allow_arr_pos ) $mod_set[] = 'arr_pos';
- get_features ( $mod_set, $node );
- // Have we found a tincture yet?
- if ( ($tinc = get_child($node, 'tincture')) == null ) {
- if ( array_key_exists('always_proper', $flags) ) {
- $tinc = $dom->createElement('tincture');
- $proper = $dom->createElement('proper');
- $tinc->setAttribute('index','1');
- $tinc->setAttribute('origin','proper');
- $tinc->appendChild($proper);
- } elseif ( array_key_exists('default_colour', $flags)) {
- $tinc = make_colour($flags['default_colour']);
- $tinc->setAttribute('index','1');
- $tinc->setAttribute('origin','default');
- } elseif ( ($tinc = get_feature_tinc($node)) != null ) { // or it could be because the tincture was consumed by a feature
- // Don't need to do anything else
- } else { // Not proper, and no default
- $tinc = $dom->createElement('tincture');
- $tinc->setAttribute('origin','pending');
- $tinc->setAttribute('index','1');
- $pending_items[] = $tinc;
- }
- $node->appendChild($tinc);
- } else {
- $tinc->setAttribute('origin','given');
- }
- return $node;
- }
- function charge( $assume_num = false ) {
- global $dom;
- $on_charge = array (
- array ( true, 'charged with' ),
- array ( true, 'on each' ),
- array ( true, 'surmounted by' ),
- );
- $on_prefix = array (
- array ( true, 'on' ),
- );
- $state = save();
- $allow_arr_pos = true;
- // In case of "in chief, three whatever...
- $temp = $dom->createElement('charge');
- $arr_pos = get_features( array ( 'arr_pos', 'charge_prefix'), $temp );
- if ( is_int($arr_pos) ) {
- $assume_num = $arr_pos;
- $allow_arr_pos = false;
- }
- $found_on = search_match($on_prefix);
- // Look for the charge itself
- if ( ($node = simple_charge( $assume_num, $allow_arr_pos )) == null ) {
- restore($state);
- return null;
- }
- // Copy over anything found earlier
- foreach ($temp->childNodes as $child )
- $node->appendChild($child);
- // Is there anything else "on" this charge?
- if ( $found_on or search_match($on_charge) != null ) {
- $on_mod = make_mod('on');
- if ( ($on_charge = simple_charge( true )) == null ) {
- $on_charge = $dom->createElement('missing');
- parser_message('blazon', 'Nothing for charge to go on');
- }
- $on_mod->appendChild($on_charge);
- $node->appendChild($on_mod);
- }
- if ( !semicolon() ) {
- adjacent($node);
- // If there is an explicit position, a following "between" is redundant (e.g. issue 173)
- search_match( array ( array ( null, 'between' )));
- }
- return $node;
- }
- ?>