PageRenderTime 24ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/2.4/tags/trunk/parser/features.inc

http://drawshield.googlecode.com/
PHP | 269 lines | 239 code | 14 blank | 16 comment | 21 complexity | cd9cff7aa9f09540f4afaf154c0c7600 MD5 | raw file
  1. <?php /* Copyright 2010 Karl R. Wilcox
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License. */
  11. function get_features ( $feature_sets, &$node ) {
  12. global $dom;
  13. global $pending_items;
  14. static $position_mods = array (
  15. array ( null, 'sinister', 'mod', 'sinister' ),
  16. array ( null, 'reversed', 'mod', 'reversed' ),
  17. array ( null, '(rompu|fracted)', 'mod', 'fracted' ), // Not really a position, but syntactically it fits in here
  18. array ( null, 'double dancetty', 'mod', 'fracted' ),
  19. array ( null, 'dexter', 'mod', 'dexter', ),
  20. array ( null, 'inverted', 'mod', 'inverted', ),
  21. array ( null, 'enhanced', 'mod', 'enhanced', ),
  22. array ( null, '(abased|abaisse)', 'mod', 'abased', ),
  23. );
  24. static $shape_mods = array (
  25. array ( null, 'voided', 'shape', 'voided' ),
  26. array ( null, '(fimbriated|edged)', 'shape', 'fimbriated', ),
  27. array ( '1', '(cotised|cotticed|endorsed)', 'shape', 'cotised', ),
  28. array ( '1', 'between # cott?ices', 'shape', 'cotised', ),
  29. array ( '2', 'double (cotised|cotticed)', 'shape', 'cotised', ),
  30. array ( '3', '(triple|treble) (cotised|cotticed)', 'shape', 'cotised', ),
  31. );
  32. static $charge_prefix = array (
  33. array ( 'infirst', 'in ?the (first|1st|i) ?quarter', 'mod', 'position' ),
  34. array ( 'insecond', 'in ?the (second|2nd|ii) ?quarter', 'mod', 'position' ),
  35. array ( 'inthird', 'in ?the (third|3rd|iii) ?quarter', 'mod', 'position' ),
  36. array ( 'infourth', 'in ?the (fourth|4th|iv) ?quarter', 'mod', 'position' ),
  37. );
  38. static $simple_charge = array (
  39. array ( null, 'con?joined', 'mod', 'conjoin' ),
  40. array ( null, 'inverted', 'mod', 'inverted' ),
  41. array ( null, 'reversed', 'mod', 'reversed' ),
  42. array ( null, '(entire|firme)', 'mod', 'entire' ),
  43. array ( null, 'en soleil', 'mod', 'ensoleil'),
  44. array ( 'in', 'respecting each other', 'mod', 'facing' ),
  45. array ( 'in', 'counter rampant', 'mod', 'facing' ),
  46. array ( 'in', '(confronting|affrontant|combatant)', 'mod', 'facing' ),
  47. array ( 'out','addorsed', 'mod', 'facing' ),
  48. array ( 'bendsinwise', 'bendw(ise|ays) sinister' , 'mod', 'orientation' ),
  49. array ( 'bendwise', 'bendw(ise|ays)', 'mod', 'orientation' ),
  50. array ( 'fesswise', 'fessw(ise|ays)', 'mod', 'orientation' ),
  51. array ( 'palewise', 'palew(ise|ays)', 'mod', 'orientation' ),
  52. array ( null, 'arranged', 'ignore' ),
  53. array ( null, '(lying|laying)', 'ignore' ),
  54. );
  55. static $linetype_mods = array (
  56. array ( 'battled-embattled', '(battled|double) (e?m?battled|crenn?ell?e?y?)', 'mod', 'linetype',), // two levels of battlements, on upper surface only
  57. array ( 'battled-embattled', '(em)?battled grady', 'mod', 'linetype', ),
  58. array ( 'battled-brettesse', '(em)?battled brett?ess?e?y?', 'mod', 'linetype', ), // both sides, same pattern
  59. array ( 'battled-counter', '(e?m?battled|crenn?ell?e?y?) counter (e?m?battled|crenn?ell?e?y?)', 'mod', 'linetype', ), // both sides, opposite pattern
  60. array ( 'embattled', '?super (e?m?battled|crenn?ell?e?y?)', 'mod', 'linetype', ), // top only
  61. array ( 'embattled-round', '(e?m?battled|crenn?ell?e?y?) arrondi', 'mod', 'linetype', ), // top only, round crenelles
  62. array ( 'angled', 'angled', 'mod', 'linetype', ),
  63. array ( 'arched', '(en)?arched', 'mod', 'linetype', ),
  64. array ( 'bevilled', 'bevill?ed', 'mod', 'linetype', ),
  65. array ( 'bevilled', 'bevill?y', 'mod', 'linetype', ),
  66. array ( 'dancetty-floretty', 'dau?ncett(e|y) flor(y|etty)' , 'mod', 'linetype',),
  67. array ( 'dancetty', 'dau?ncetty', 'mod', 'linetype', ),
  68. array ( 'double-arched', 'double (en)?arched', 'mod', 'linetype', ),
  69. array ( 'double-arched', '(en)?arched double', 'mod', 'linetype', ),
  70. array ( 'dovetailed','dovetailed', 'mod', 'linetype', ),
  71. array ( 'engrailed', 'engrailed', 'mod', 'linetype', ),
  72. array ( 'escartelly', 'escartelly', 'mod', 'linetype', ),
  73. array ( 'indented', 'indented', 'mod', 'linetype', ),
  74. array ( 'invected', 'invected', 'mod', 'linetype', ),
  75. array ( 'nebuly', 'nebuly', 'mod', 'linetype', ),
  76. array ( 'nowy' , 'nowy', 'mod', 'linetype', ),
  77. array ( 'none', 'plain', 'mod', 'linetype', ),
  78. array ( 'potenty', 'potenty', 'mod', 'linetype', ),
  79. array ( 'raguly', 'raguly', 'mod', 'linetype', ),
  80. array ( 'rayonny', '(rayonny|radiant)', 'mod', 'linetype', ),
  81. array ( 'wavy', '(wavy|undy)', 'mod', 'linetype', ),
  82. array ( 'urdy' , '(urdy|urde|champaine|champion)', 'mod', 'linetype', ),
  83. );
  84. static $arr_pos_mods = array (
  85. array ( 'inpale', 'in ?the pale' , 'mod', 'arrangement' ,3 ),
  86. array ( 'inpalethrough', 'in ?the pale throughout' , 'mod', 'arrangement' ,3 ),
  87. array ( 'inpall', 'in ?the pall' , 'mod', 'arrangement' ,3 ),
  88. array ( 'infess', 'in ?the fesse?' , 'mod', 'arrangement',3 ),
  89. array ( 'infessthrough', 'in ?the fesse? throughout' , 'mod', 'arrangement' ,3 ),
  90. array ( 'inbendsin', 'in ?the bend sinister' , 'mod', 'arrangement',3 ),
  91. array ( 'inbend', 'in ?the bend ?dexter' , 'mod', 'arrangement',3 ),
  92. array ( 'inchevron', 'in ?the chevron', 'mod', 'arrangement',3 ),
  93. array ( 'inpile', 'in ?the pile' , 'mod', 'arrangement',3 ),
  94. array ( 'inorle', 'in ?an orle' , 'mod', 'arrangement', 12 ),
  95. array ( 'inorle', 'in ?the orle' , 'mod', 'arrangement', 12 ),
  96. array ( 'insaltire', 'in ?the saltire' , 'mod', 'arrangement',3 ),
  97. array ( 'incross', 'in ?the cross' , 'mod', 'arrangement', 5),
  98. array ( 'counter-passant', '?in counter passant' , 'mod', 'arrangement', 4),
  99. array ( 'pilewise', 'pilewise', 'mod', 'arrangement', 3),
  100. array ( 'inbar', '?in (bar|barwise)', 'mod', 'arrangement'),
  101. array ( 'inflank', 'in ?the (flanks?|flaunche?s?)', 'mod', 'arrangement position',3 ),
  102. array ( 'inchief', 'in ?the chief' , 'mod', 'arrangement position',3 ),
  103. array ( 'inchiefthrough','in ?the chief throughout' , 'mod', 'arrangement position',3 ),
  104. array ( 'inbase', 'in ?the base' , 'mod', 'arrangement position',3 ),
  105. array ( 'indexside', 'in ?the dexter side' , 'mod', 'position', 1 ),
  106. array ( 'insinside', 'in ?the sinister side' , 'mod', 'position', 1 ),
  107. array ( 'indexchief', 'in ?the dexter chief' , 'mod', 'position', 1 ),
  108. array ( 'insinchief', 'in ?the sinister chief' , 'mod', 'position', 1 ),
  109. array ( 'inmidchief', 'in ?the middle chief' , 'mod', 'position', 1 ),
  110. array ( 'inhonpoint', 'in ?the honour point' , 'mod', 'position', 1 ),
  111. array ( 'infesspoint', 'in ?the fesse? point' , 'mod', 'position', 1 ),
  112. array ( 'indexbase', 'in ?the dexter base' , 'mod', 'position', 1 ),
  113. array ( 'insinbase', 'in ?the sinister base' , 'mod', 'position', 1 ),
  114. array ( 'inmidbase', 'in ?the middle base' , 'mod', 'position', 1 ),
  115. array ( 'innombril', 'in ?the nombril' , 'mod', 'position', 1 ),
  116. array ( 'innombril', 'in ?the navel point' , 'mod', 'position', 1 ),
  117. array ( 'quadrangle', 'in ?a quadrangle', 'mod', 'arrangement', 4 ),
  118. );
  119. $retval = null;
  120. $look_for_rows = false;
  121. $look_for_tinc = true;
  122. $features = array();
  123. foreach ( $feature_sets as $feature_set ) {
  124. if (is_array($feature_set)) $features = array_merge($features, $feature_set);
  125. elseif (is_string($feature_set)) {
  126. switch ($feature_set) { // replace this with string -> varname conversion
  127. case 'position':
  128. $features = array_merge($features, $position_mods);
  129. break;
  130. case 'shape':
  131. $features = array_merge($features, $shape_mods);
  132. break;
  133. case 'linetype':
  134. $features = array_merge($features, $linetype_mods);
  135. break;
  136. case 'simple_charge':
  137. $features = array_merge($features, $simple_charge);
  138. break;
  139. case 'charge_prefix':
  140. $features = array_merge($features, $charge_prefix);
  141. break;
  142. case 'arr_pos':
  143. $features = array_merge($features, $arr_pos_mods);
  144. break;
  145. case 'rows':
  146. $look_for_rows = true;
  147. break;
  148. case 'no_tinc':
  149. $look_for_tinc = false;
  150. break;
  151. default:
  152. parser_message('internal', "Unknown feature group - $feature_set");
  153. break;
  154. }
  155. }
  156. }
  157. $tinc_index = 1;
  158. comma();
  159. andd();
  160. // Get any additional features
  161. while ( true ) {
  162. $state = save();
  163. if ( $features and ($match = search_match($features)) != null) {
  164. switch ( $match[2] ) {
  165. case 'shape':
  166. $shape_mod = make_mod($match[3], $match[0], tokens());
  167. get_features(array('linetype','no_tinc'), $shape_mod);
  168. if ( ($tinc = tincture()) != null ) $shape_mod->appendChild($tinc);
  169. $node->appendChild($shape_mod);
  170. break;
  171. case 'addlinetype':
  172. $linemod = make_mod( $match[3], $match[0], tokens() );
  173. get_features(array('linetype'), $linemod);
  174. $node->appendChild($linemod);
  175. break;
  176. case 'feature':
  177. $feature = $dom->createElement('feature');
  178. $feature->setAttribute( 'name', $match[0]);
  179. $feature->setAttribute('tokens',tokens());
  180. $feature->appendChild(tincture(true));
  181. $node->appendChild($feature);
  182. break;
  183. case 'mod':
  184. foreach ( explode ( ' ', $match[3] ) as $match3 )
  185. $node->appendChild(make_mod ( $match3, $match[0], tokens() ));
  186. // the presence of argument 4 tells 2 things SO BE CAREFUL
  187. // 1. The default number of charges, if none is given
  188. // 2. The fact that a position has been found and we should not look again.
  189. if ( isset ( $match[4] ) ) $retval = $match[4];
  190. break;
  191. case 'mod+1tinc':
  192. $mod = make_mod ( $match[3], $match[0], tokens() );
  193. $mod->appendChild(tincture(true));
  194. $node->appendChild($mod);
  195. break;
  196. case 'mod+tinc':
  197. $mod = make_mod ( $match[3], $match[0], tokens() );
  198. $tinc = tincture(true);
  199. $tinc->setAttribute('index','2'); // don't know of any ords that need 3 tincs...
  200. $node->appendChild($tinc);
  201. $node->appendChild($mod);
  202. break;
  203. case 'mod+charge':
  204. $mod = make_mod ( $match[3], $match[0], tokens() );
  205. if ( ($charge = charge(true)) == null ) {
  206. $charge = $dom->createElement('missing');
  207. parser_message('blazon', 'expected charge in modifier');
  208. } else {
  209. if ( $match[0] )
  210. $charge->setAttribute('number', $match[0] );
  211. }
  212. $mod->appendChild($charge);
  213. $node->appendChild($mod);
  214. break;
  215. case 'warn':
  216. parser_message('warning', 'Can\'t draw feature - ' . tokens());
  217. $node->appendChild(make_mod ( $match[3], $match[0], tokens() ));
  218. break;
  219. case 'ignore':
  220. break;
  221. }
  222. } elseif ( $look_for_tinc and (($tinc = tincture(false)) != null) ) {
  223. $tinc->setAttribute('index',"$tinc_index" );
  224. $tinc_index++;
  225. $node->appendChild($tinc);
  226. } elseif ( $look_for_rows and (($num = number( true )) != null ) ) {
  227. comma();
  228. andd();
  229. $rows = array($num);
  230. $count = 1;
  231. while ( ($num = number( true )) != null ) {
  232. $count += 1;
  233. $rows[] = $num;
  234. if ( semicolon()) break;
  235. comma();
  236. andd();
  237. }
  238. if ( $count == 1 ) {
  239. restore($state);
  240. break;
  241. } elseif ( $count > 1 ) {
  242. $node->appendChild(make_mod ( 'rows', implode(',',$rows) ));
  243. }
  244. } else {
  245. break;
  246. }
  247. comma();
  248. andd();
  249. }
  250. return $retval; // usually ignored, but see arr_pos above
  251. }
  252. ?>