1
22 package org.crosswire.jsword.book.filter.gbf;
23
24 import java.util.LinkedList;
25
26 import org.crosswire.common.util.ClassUtil;
27 import org.crosswire.common.xml.XMLUtil;
28 import org.crosswire.jsword.book.Book;
29 import org.crosswire.jsword.book.DataPolice;
30 import org.crosswire.jsword.book.OSISUtil;
31 import org.crosswire.jsword.book.OSISUtil.OSISFactory;
32 import org.crosswire.jsword.passage.Key;
33 import org.crosswire.jsword.passage.NoSuchKeyException;
34 import org.crosswire.jsword.passage.Passage;
35 import org.jdom.Content;
36 import org.jdom.Element;
37 import org.jdom.Text;
38
39
47 public final class GBFTags {
48
51 private GBFTags() {
52 }
53
54
57 public static final class DefaultEndTag extends AbstractTag {
58
61 public DefaultEndTag(String name) {
62 super(name);
63 }
64
65 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
66 if (stack.isEmpty()) {
67 DataPolice.report(book, key, "Ignoring end tag without corresponding start tag: " + getName());
68 return;
69 }
70 stack.removeFirst();
71 }
72 }
73
74
77 public static final class BoldStartTag extends AbstractTag {
78
81 public BoldStartTag(String name) {
82 super(name);
83 }
84
85 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
86 Element ele = OSIS_FACTORY.createHI();
87 ele.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.HI_BOLD);
88 GBFTags.updateOsisStack(book, key, stack, ele);
89 }
90 }
91
92
95 public static final class CrossRefStartTag extends AbstractTag {
96 public CrossRefStartTag(String name) {
97 super(name);
98 }
99
100 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
101 Element ele = OSIS_FACTORY.createReference();
102
103 String refstr = getName().substring(2);
104 try {
105 Passage ref = (Passage) book.getKey(refstr);
106 ele.setAttribute(OSISUtil.OSIS_ATTR_REF, ref.getOsisRef());
107 } catch (NoSuchKeyException ex) {
108 DataPolice.report(book, key, "unable to parse reference: " + refstr);
109 }
110 GBFTags.updateOsisStack(book, key, stack, ele);
111 }
112 }
113
114
117 public static final class EOLTag extends AbstractTag {
118
121 public EOLTag(String name) {
122 super(name);
123 }
124
125 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
126
127 Element p = OSIS_FACTORY.createLB();
128 if (stack.isEmpty()) {
129 stack.addFirst(p);
130 } else {
131 Content top = stack.get(0);
132 if (top instanceof Element) {
133 Element current = (Element) top;
134 current.addContent(p);
135 }
136 }
137 }
138 }
139
140
143 public static final class FootnoteStartTag extends AbstractTag {
144
147 public FootnoteStartTag(String name) {
148 super(name);
149 }
150
151 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
152 Element ele = OSIS_FACTORY.createNote();
153 ele.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.NOTETYPE_STUDY);
154 GBFTags.updateOsisStack(book, key, stack, ele);
155 }
156 }
157
158
161 public static final class FootnoteEndTag extends AbstractTag {
162
165 public FootnoteEndTag(String name) {
166 super(name);
167 }
168
169 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
170 if (stack.isEmpty()) {
171 DataPolice.report(book, key, "Ignoring end tag without corresponding start tag: " + getName());
172 return;
173 }
174
175 Object pop = stack.removeFirst();
176 if (!(pop instanceof Element)) {
177 DataPolice.report(book, key, "expected to pop a Note, but found " + ClassUtil.getShortClassName(pop.getClass()));
178 return;
179 }
180
181 Element note = (Element) pop;
182 if (note.getContentSize() < 1) {
183 Content top = stack.get(0);
184 if (top instanceof Element) {
185 Element ele = (Element) top;
186 ele.removeContent(note);
187 }
188 }
189 }
190 }
191
192
195 public static final class HeaderStartTag extends AbstractTag {
196
199 public HeaderStartTag(String name) {
200 super(name);
201 }
202
203 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
204 GBFTags.updateOsisStack(book, key, stack, OSIS_FACTORY.createTitle());
205 }
206 }
207
208
211 public static final class IgnoredTag extends AbstractTag {
212
215 public IgnoredTag(String name) {
216 super(name);
217 }
218
219 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
220 }
221 }
222
223
226 public static final class ItalicStartTag extends AbstractTag {
227
230 public ItalicStartTag(String name) {
231 super(name);
232 }
233
234 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
235 Element ele = OSIS_FACTORY.createHI();
236 ele.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.HI_ITALIC);
237 GBFTags.updateOsisStack(book, key, stack, ele);
238 }
239 }
240
241
244 public static final class JustifyRightTag extends AbstractTag {
245
248 public JustifyRightTag(String name) {
249 super(name);
250 }
251
252 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
253 Element ele = OSIS_FACTORY.createSeg();
255 ele.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.SEG_JUSTIFYRIGHT);
256 GBFTags.updateOsisStack(book, key, stack, ele);
257 }
258 }
259
260
263 public static final class JustifyLeftTag extends AbstractTag {
264
267 public JustifyLeftTag(String name) {
268 super(name);
269 }
270
271 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
272 Element ele = OSIS_FACTORY.createSeg();
273 ele.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.SEG_JUSTIFYLEFT);
274 GBFTags.updateOsisStack(book, key, stack, ele);
275 }
276 }
277
278
281 public static final class OTQuoteStartTag extends AbstractTag {
282
285 public OTQuoteStartTag(String name) {
286 super(name);
287 }
288
289 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
290 GBFTags.updateOsisStack(book, key, stack, OSIS_FACTORY.createQ());
291 }
292 }
293
294
297 public static final class ParagraphTag extends AbstractTag {
298
301 public ParagraphTag(String name) {
302 super(name);
303 }
304
305 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
306
307 if (stack.isEmpty()) {
308 Element p = OSIS_FACTORY.createLB();
309 stack.addFirst(p);
310 } else {
311 Element p = OSIS_FACTORY.createP();
312 Content top = stack.get(0);
313 if (top instanceof Element) {
314 Element current = (Element) top;
315 current.addContent(p);
316 }
317 }
318 }
319 }
320
321
324 public static final class PoetryStartTag extends AbstractTag {
325
328 public PoetryStartTag(String name) {
329 super(name);
330 }
331
332 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
333 GBFTags.updateOsisStack(book, key, stack, OSIS_FACTORY.createLG());
334 }
335 }
336
337
340 public static final class PsalmStartTag extends AbstractTag {
341
344 public PsalmStartTag(String name) {
345 super(name);
346 }
347
348 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
349 GBFTags.updateOsisStack(book, key, stack, OSIS_FACTORY.createTitle());
350 }
351 }
352
353
356 public static final class RedLetterStartTag extends AbstractTag {
357
360 public RedLetterStartTag(String name) {
361 super(name);
362 }
363
364 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
365 Element ele = OSIS_FACTORY.createQ();
366 ele.setAttribute(OSISUtil.ATTRIBUTE_Q_WHO, "Jesus");
367 GBFTags.updateOsisStack(book, key, stack, ele);
368 }
369 }
370
371
374 public static final class StrongsMorphTag extends AbstractTag {
375 public StrongsMorphTag(String name) {
376 super(name);
377 }
378
379 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
380 String name = getName().trim();
381
382 Content top = stack.get(0);
383 if (top instanceof Element) {
384 Element ele = (Element) top;
385 int size = ele.getContentSize();
386 if (size == 0) {
387 DataPolice.report(book, key, "No content to attach word to: <" + name + ">.");
388 return;
389 }
390
391 int lastIndex = size - 1;
392 Content prevObj = ele.getContent(lastIndex);
393 Element word = null;
394
395 if (prevObj instanceof Text) {
396 word = OSIS_FACTORY.createW();
397 ele.removeContent(prevObj);
398 word.addContent(prevObj);
399 ele.addContent(word);
400 } else if (prevObj instanceof Element) {
401 word = (Element) prevObj;
402 } else {
403 DataPolice.report(book, key, "No words to attach word to: <" + name + ">.");
404 return;
405 }
406
407 String existingMorph = word.getAttributeValue(OSISUtil.ATTRIBUTE_W_MORPH);
408 StringBuilder newMorph = new StringBuilder();
409
410 if (existingMorph != null && existingMorph.length() > 0) {
411 newMorph.append(existingMorph).append('|');
412 }
413 newMorph.append(OSISUtil.MORPH_STRONGS).append(name.substring(2));
414 word.setAttribute(OSISUtil.ATTRIBUTE_W_MORPH, newMorph.toString());
415 }
416 }
417 }
418
419
422 public static final class StrongsWordTag extends AbstractTag {
423
426 public StrongsWordTag(String name) {
427 super(name);
428 }
429
430 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
431 String name = getName().trim();
432
433 Content top = stack.get(0);
434 if (top instanceof Element) {
435 Element ele = (Element) top;
436 int size = ele.getContentSize();
437 if (size == 0) {
438 DataPolice.report(book, key, "No content to attach word to: <" + name + ">.");
439 return;
440 }
441
442 int lastIndex = size - 1;
443 Content prevObj = ele.getContent(lastIndex);
444 Element word = null;
445
446 if (prevObj instanceof Text) {
447 Text textItem = (Text) prevObj;
448 word = OSIS_FACTORY.createW();
449 ele.removeContent(textItem);
450 word.addContent(textItem);
451 ele.addContent(word);
452 } else if (prevObj instanceof Element) {
453 word = (Element) prevObj;
454 } else {
455 DataPolice.report(book, key, "No words to attach word to: <" + name + ">.");
456 return;
457 }
458
459 String existingLemma = word.getAttributeValue(OSISUtil.ATTRIBUTE_W_LEMMA);
460 StringBuilder newLemma = new StringBuilder();
461
462 if (existingLemma != null && existingLemma.length() > 0) {
464 newLemma.append(existingLemma).append(' ');
465 }
466
467 newLemma.append(OSISUtil.LEMMA_STRONGS).append(name.substring(1));
469 word.setAttribute(OSISUtil.ATTRIBUTE_W_LEMMA, newLemma.toString());
470 }
471 }
472 }
473
474
477 public static final class TextFootnoteTag extends AbstractTag {
478
481 public TextFootnoteTag(String name) {
482 super(name);
483 }
484
485 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
486 Element ele = OSIS_FACTORY.createNote();
487 ele.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.NOTETYPE_STUDY);
488 GBFTags.updateOsisStack(book, key, stack, ele);
489 }
490 }
491
492
495 public static final class TextTag extends AbstractTag {
496
499 public TextTag(String name) {
500 super(name);
501 }
502
503 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
504 String text = XMLUtil.escape(getName());
506 if (stack.isEmpty()) {
507 stack.addFirst(new Text(text));
508 } else {
509 Content top = stack.get(0);
510 if (top instanceof Element) {
511 Element ele = (Element) top;
512 ele.addContent(text);
513 }
514 }
515 }
516 }
517
518
521 public static final class TitleStartTag extends AbstractTag {
522
525 public TitleStartTag(String name) {
526 super(name);
527 }
528
529 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
530 GBFTags.updateOsisStack(book, key, stack, OSIS_FACTORY.createTitle());
531 }
532 }
533
534
537 public static final class UnderlineStartTag extends AbstractTag {
538
541 public UnderlineStartTag(String name) {
542 super(name);
543 }
544
545 public void updateOsisStack(Book book, Key key, LinkedList<Content> stack) {
546 Element ele = OSIS_FACTORY.createHI();
547 ele.setAttribute(OSISUtil.OSIS_ATTR_TYPE, OSISUtil.HI_UNDERLINE);
548 GBFTags.updateOsisStack(book, key, stack, ele);
549 }
550 }
551
552 static void updateOsisStack(Book book, Key key, LinkedList<Content> stack, Content content) {
553 Content top = stack.get(0);
554 if (top instanceof Element) {
555 Element current = (Element) top;
556 current.addContent(content);
557 stack.addFirst(content);
558 }
559 }
560
561
564 static final OSISFactory OSIS_FACTORY = OSISUtil.factory();
565 }
566