The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OSISLaTeX Class Reference

#include <osislatex.h>

+ Inheritance diagram for OSISLaTeX:
+ Collaboration diagram for OSISLaTeX:

Classes

class  MyUserData
 
class  TagStack
 

Public Member Functions

virtual const char * getHeader () const
 
 OSISLaTeX ()
 
virtual char processText (SWBuf &text, const SWKey *key=0, const SWModule *module=0)
 
void setMorphFirst (bool val=true)
 
void setRenderNoteNumbers (bool val=true)
 

Protected Member Functions

void addAllowedEscapeString (const char *findString)
 
void addEscapeStringSubstitute (const char *findString, const char *replaceString)
 
void addTokenSubstitute (const char *findString, const char *replaceString)
 
void appendEscapeString (SWBuf &buf, const char *escString)
 
virtual BasicFilterUserDatacreateUserData (const SWModule *module, const SWKey *key)
 
virtual bool handleEscapeString (SWBuf &buf, const char *escString, BasicFilterUserData *userData)
 
virtual bool handleNumericEscapeString (SWBuf &buf, const char *escString)
 
virtual bool handleToken (SWBuf &buf, const char *token, BasicFilterUserData *userData)
 
bool passAllowedEscapeString (SWBuf &buf, const char *escString)
 
virtual bool processStage (char, SWBuf &, char *&, BasicFilterUserData *)
 
void removeAllowedEscapeString (const char *findString)
 
void removeEscapeStringSubstitute (const char *findString)
 
void removeTokenSubstitute (const char *findString)
 
void setEscapeEnd (const char *escEnd)
 
void setEscapeStart (const char *escStart)
 
void setEscapeStringCaseSensitive (bool val)
 
void setPassThruNumericEscapeString (bool val)
 
void setPassThruUnknownEscapeString (bool val)
 
void setPassThruUnknownToken (bool val)
 
virtual void setStageProcessing (char stages)
 
void setTokenCaseSensitive (bool val)
 
void setTokenEnd (const char *tokenEnd)
 
void setTokenStart (const char *tokenStart)
 
bool substituteEscapeString (SWBuf &buf, const char *escString)
 
bool substituteToken (SWBuf &buf, const char *token)
 

Static Protected Attributes

static const char FINALIZE = 8
 
static const char INITIALIZE = 1
 
static const char POSTCHAR = 4
 
static const char PRECHAR = 2
 

Private Attributes

bool morphFirst
 
bool renderNoteNumbers
 

Detailed Description

this filter converts OSIS text to LaTeX

Definition at line 33 of file osislatex.h.

Constructor & Destructor Documentation

OSISLaTeX::OSISLaTeX ( )

Definition at line 159 of file osislatex.cpp.

159  {
160  setTokenStart("<");
161  setTokenEnd(">");
162 
163  setEscapeStart("&");
164  setEscapeEnd(";");
165 
168 
169  addAllowedEscapeString("quot");
170  addAllowedEscapeString("apos");
171  addAllowedEscapeString("amp");
174 
175  setTokenCaseSensitive(true);
176 
177  // addTokenSubstitute("lg", "<br />");
178  // addTokenSubstitute("/lg", "<br />");
179 
180  morphFirst = false;
181  renderNoteNumbers = false;
182 }
void setTokenEnd(const char *tokenEnd)
void addAllowedEscapeString(const char *findString)
bool renderNoteNumbers
Definition: osislatex.h:36
void setTokenCaseSensitive(bool val)
void setEscapeStart(const char *escStart)
void setTokenStart(const char *tokenStart)
void setPassThruNumericEscapeString(bool val)
void setEscapeStringCaseSensitive(bool val)
void setEscapeEnd(const char *escEnd)
bool morphFirst
Definition: osislatex.h:35

Member Function Documentation

void SWBasicFilter::addAllowedEscapeString ( const char *  findString)
protectedinherited

Registers an esc control sequence that can pass unchanged

Definition at line 156 of file swbasicfilter.cpp.

156  {
157  char *buf = 0;
158 
159  if (!escStringCaseSensitive) {
160  stdstr(&buf, findString);
161  toupperstr(buf);
162  p->escPassSet.insert(StringSet::value_type(buf));
163  delete [] buf;
164  }
165  else p->escPassSet.insert(StringSet::value_type(findString));
166 }
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
bool escStringCaseSensitive
Definition: swbasicfilter.h:74
char * toupperstr(char *t, unsigned int max=0)
Definition: stringmgr.h:107
Private * p
Definition: swbasicfilter.h:82
void SWBasicFilter::addEscapeStringSubstitute ( const char *  findString,
const char *  replaceString 
)
protectedinherited

Registers an esc control sequence

Definition at line 176 of file swbasicfilter.cpp.

176  {
177  char *buf = 0;
178 
179  if (!escStringCaseSensitive) {
180  stdstr(&buf, findString);
181  toupperstr(buf);
182  p->escSubMap.insert(DualStringMap::value_type(buf, replaceString));
183  delete [] buf;
184  }
185  else p->escSubMap.insert(DualStringMap::value_type(findString, replaceString));
186 }
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
bool escStringCaseSensitive
Definition: swbasicfilter.h:74
char * toupperstr(char *t, unsigned int max=0)
Definition: stringmgr.h:107
Private * p
Definition: swbasicfilter.h:82
void SWBasicFilter::addTokenSubstitute ( const char *  findString,
const char *  replaceString 
)
protectedinherited

Registers a simple token substitutions. Usually called from the c-tor of a subclass

Definition at line 136 of file swbasicfilter.cpp.

136  {
137  char *buf = 0;
138 
139  if (!tokenCaseSensitive) {
140  stdstr(&buf, findString);
141  toupperstr(buf);
142  p->tokenSubMap[buf] = replaceString;
143  delete [] buf;
144  }
145  else p->tokenSubMap[findString] = replaceString;
146 }
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
bool tokenCaseSensitive
Definition: swbasicfilter.h:75
DualStringMap tokenSubMap
char * toupperstr(char *t, unsigned int max=0)
Definition: stringmgr.h:107
Private * p
Definition: swbasicfilter.h:82
void SWBasicFilter::appendEscapeString ( SWBuf buf,
const char *  escString 
)
protectedinherited

This appends escString to buf as an entity

Definition at line 216 of file swbasicfilter.cpp.

216  {
217  buf += escStart;
218  buf += escString;
219  buf += escEnd;
220 }
BasicFilterUserData * OSISLaTeX::createUserData ( const SWModule module,
const SWKey key 
)
protectedvirtual

Reimplemented from SWBasicFilter.

Definition at line 154 of file osislatex.cpp.

154  {
155  return new MyUserData(module, key);
156 }
SWORD_NAMESPACE_START const char * OSISLaTeX::getHeader ( ) const
virtual

This method can supply a header associated with the processing done with this filter. A typical example is a suggested CSS style block for classed containers.

Reimplemented from SWFilter.

Definition at line 36 of file osislatex.cpp.

36  {
37 // can be used to return static start-up info, like packages to load. Not sure yet if I want to retain it.
38 
39  const static char *header = "\
40  \\LoadClass[11pt,a4paper,twoside,headinclude=true,footinclude=true,BCOR=0mm,DIV=calc]{scrbook}\n\
41  \\LoadClass[11pt,a4paper,twoside,headinclude=true,footinclude=true,BCOR=0mm,DIV=calc]{scrbook}\n\
42  \\NeedsTeXFormat{LaTeX2e}\n\
43  \\ProvidesClass{sword}[2015/03/29 CrossWire LaTeX class for Biblical texts]\n\
44  %\\sworddiclink{%s}{%s}{\n\
45  %\\sworddictref{%s}{%s}{\n\
46  %\\sworddict{%s}{\n\
47  %\\sworddivinename}{%s}{\n\
48  %\\swordfont{\n\
49  %\\swordfootnote[%c]{%s}{%s}{%s}{%s}{\n\
50  %\\swordfootnote{%s}{%s}{%s}{\n\
51  %\\swordfootnote{%s}{%s}{%s}{%s}{\n\
52  %\\swordmorph{\n\
53  %\\swordmorph[Greek]{%s}\n\
54  %\\swordmorph[lemma]{%s}\n\
55  %\\swordmorph{%s}\n\
56  %\\swordpoetryline{\n\
57  %\\swordquote{\n\
58  %\\swordref{%s}{%s}{\n\
59  %\\swordsection{\n\
60  %\\swordsection{}{\n\
61  %\\swordsection{book}{\n\
62  %\\swordsection{sechead}{\n\
63  %\\swordstrong[Greek]{\n\
64  %\\swordstrong[Greektense]{\n\
65  %\\swordstrong[Hebrew]{\n\
66  %\\swordstrong[Hebrewtense]{\n\
67  %\\swordstrong[%s]{%s}{\n\
68  %\\swordstrong{%s}{%s}\n\
69  %\\swordtitle{\n\
70  %\\swordtranschange{supplied}{\n\
71  %\\swordtranschange{tense}{\n\
72  %\\swordwoj{\n\
73  %\\swordxref{\n\
74  %\\swordxref{%s}{\n\
75  %\\swordxref{%s}{%s}{\n\
76  ";
77  return header;
78 }
bool SWBasicFilter::handleEscapeString ( SWBuf buf,
const char *  escString,
BasicFilterUserData userData 
)
protectedvirtualinherited

This function is called for every escape sequence encountered in the input text.

Parameters
bufthe output buffer
escStringthe escape sequence (e.g. "amp" for &amp;)
userDatauser storage space for data transient to 1 full buffer parse
Returns
false if was not handled and should be handled in
subclasses should return true if they handled the esc seq, or false if they did not.

Definition at line 286 of file swbasicfilter.cpp.

286  {
287  return substituteEscapeString(buf, escString);
288 }
bool substituteEscapeString(SWBuf &buf, const char *escString)
bool SWBasicFilter::handleNumericEscapeString ( SWBuf buf,
const char *  escString 
)
protectedvirtualinherited

This function is called for all numeric escape sequences. If passThrough

Parameters
bufthe output buffer
escStringthe escape sequence (e.g. "#235" for &235;)
Returns
subclasses should return true if they handled the esc seq, or false if they did not.

Definition at line 244 of file swbasicfilter.cpp.

244  {
245  if (passThruNumericEsc) {
246  appendEscapeString(buf, escString);
247  return true;
248  }
249  return false;
250 }
bool passThruNumericEsc
Definition: swbasicfilter.h:78
void appendEscapeString(SWBuf &buf, const char *escString)
bool OSISLaTeX::handleToken ( SWBuf buf,
const char *  token,
BasicFilterUserData userData 
)
protectedvirtual

This function is called for every token encountered in the input text.

Parameters
bufthe output buffer
tokenthe token (e.g. "p align='left'"
userDatauser storage space for data transient to 1 full buffer parse
Returns
subclasses should return true if they handled the token, or false if they did not.

Reimplemented from SWBasicFilter.

Definition at line 210 of file osislatex.cpp.

210  {
211  MyUserData *u = (MyUserData *)userData;
212  SWBuf scratch;
213 
214  bool sub = (u->suspendTextPassThru) ? substituteToken(scratch, token) : substituteToken(buf, token);
215  if (!sub) {
216  // manually process if it wasn't a simple substitution
217  XMLTag tag(token);
218 
219  // <w> tag
220  if (!strcmp(tag.getName(), "w")) {
221 
222  // start <w> tag
223  if ((!tag.isEmpty()) && (!tag.isEndTag())) {
224  u->w = token;
225  }
226 
227  // end or empty <w> tag
228  else {
229  bool endTag = tag.isEndTag();
230  SWBuf lastText;
231  //bool show = true; // to handle unplaced article in kjv2003-- temporary till combined
232 
233  if (endTag) {
234  tag = u->w.c_str();
235  lastText = u->lastTextNode.c_str();
236  }
237  else lastText = "stuff";
238 
239  const char *attrib;
240  const char *val;
241  if ((attrib = tag.getAttribute("xlit"))) {
242  val = strchr(attrib, ':');
243  val = (val) ? (val + 1) : attrib;
244  outText(" ", buf, u);
245  outText(val, buf, u);
246  }
247  if ((attrib = tag.getAttribute("gloss"))) {
248  // I'm sure this is not the cleanest way to do it, but it gets the job done
249  // for rendering ruby chars properly ^_^
250  buf -= lastText.length();
251 
252  outText("\\ruby{", buf, u);
253  outText(lastText, buf, u);
254  outText("}{", buf, u);
255  outText(attrib, buf, u);
256  outText("}", buf, u);
257  }
258  if (!morphFirst) {
259  processLemma(u->suspendTextPassThru, tag, buf);
260  processMorph(u->suspendTextPassThru, tag, buf);
261  }
262  else {
263  processMorph(u->suspendTextPassThru, tag, buf);
264  processLemma(u->suspendTextPassThru, tag, buf);
265  }
266  if ((attrib = tag.getAttribute("POS"))) {
267  val = strchr(attrib, ':');
268  val = (val) ? (val + 1) : attrib;
269  outText(" ", buf, u);
270  outText(val, buf, u);
271  }
272 
273 
274  }
275  }
276 
277  // <note> tag
278 
279  else if (!strcmp(tag.getName(), "note")) {
280  if (!tag.isEndTag()) {
281  SWBuf type = tag.getAttribute("type");
282  bool strongsMarkup = (type == "x-strongsMarkup" || type == "strongsMarkup"); // the latter is deprecated
283  if (strongsMarkup) {
284  tag.setEmpty(false); // handle bug in KJV2003 module where some note open tags were <note ... />
285  }
286 
287  if (!tag.isEmpty()) {
288 
289  if (!strongsMarkup) { // leave strong's markup notes out, in the future we'll probably have different option filters to turn different note types on or off
290  SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
291  SWBuf footnoteBody = "";
292  if (u->module){
293  footnoteBody += u->module->getEntryAttributes()["Footnote"][footnoteNumber]["body"];
294  }
295  SWBuf noteName = tag.getAttribute("n");
296 
297  u->inXRefNote = true; // Why this change? Ben Morgan: Any note can have references in, so we need to set this to true for all notes
298 // u->inXRefNote = (ch == 'x');
299 
300  if (u->vkey) {
301  //printf("URL = %s\n",URL::encode(u->vkey->getText()).c_str());
302  buf.appendFormatted("\\swordfootnote{%s}{%s}{%s}{%s}{%s}{",
303 
304  footnoteNumber.c_str(),
305  u->version.c_str(),
306  u->vkey->getText(),
307  tag.getAttribute("type"),
308  (renderNoteNumbers ? noteName.c_str() : ""));
309  if (u->module) {
310  outText( u->module->renderText(footnoteBody).c_str(), buf, u);
311  }
312  }
313  else {
314  buf.appendFormatted("\\swordfootnote{%s}{%s}{%s}{%s}{%s}{",
315  footnoteNumber.c_str(),
316  u->version.c_str(),
317  u->key->getText(),
318  tag.getAttribute("type"),
319  (renderNoteNumbers ? noteName.c_str() : ""));
320  if (u->module) {
321  outText( u->module->renderText(footnoteBody).c_str(), buf, u);
322  }
323  }
324  }
325  }
326  u->suspendTextPassThru = (++u->suspendLevel);
327  }
328  if (tag.isEndTag()) {
329  u->suspendTextPassThru = (--u->suspendLevel);
330  u->inXRefNote = false;
331  u->lastSuspendSegment = ""; // fix/work-around for nasb divineName in note bug
332  outText("}", buf, u);
333  }
334  }
335 
336  // <p> paragraph and <lg> linegroup tags
337  else if (!strcmp(tag.getName(), "p") || !strcmp(tag.getName(), "lg")) {
338  if ((!tag.isEndTag()) && (!tag.isEmpty())) { // non-empty start tag
339  u->outputNewline(buf);
340  }
341  else if (tag.isEndTag()) { // end tag
342  u->outputNewline(buf);
343  }
344  else { // empty paragraph break marker
345  u->outputNewline(buf);
346  }
347  }
348 
349  // Milestoned paragraphs, created by osis2mod
350  // <div type="paragraph" sID.../>
351  // <div type="paragraph" eID.../>
352  else if (tag.isEmpty() && !strcmp(tag.getName(), "div") && tag.getAttribute("type") && (!strcmp(tag.getAttribute("type"), "x-p") || !strcmp(tag.getAttribute("type"), "paragraph"))) {
353  // <div type="paragraph" sID... />
354  if (tag.getAttribute("sID")) { // non-empty start tag
355  u->outputNewline(buf);
356  }
357  // <div type="paragraph" eID... />
358  else if (tag.getAttribute("eID")) {
359  u->outputNewline(buf);
360  }
361  }
362 
363  // <reference> tag
364  else if (!strcmp(tag.getName(), "reference")) {
365  if (!u->inXRefNote) { // only show these if we're not in an xref note
366  if (!tag.isEndTag()) {
367  SWBuf target;
368  SWBuf work;
369  SWBuf ref;
370  bool is_scripRef = false;
371 
372  target = tag.getAttribute("osisRef");
373  const char* the_ref = strchr(target, ':');
374 
375  if(!the_ref) {
376  // No work
377  ref = target;
378  is_scripRef = true;
379  }
380  else {
381  // Compensate for starting :
382  ref = the_ref + 1;
383 
384  int size = (int)(target.size() - ref.size() - 1);
385  work.setSize(size);
386  strncpy(work.getRawData(), target, size);
387 
388  // For Bible:Gen.3.15 or Bible.vulgate:Gen.3.15
389  if(!strncmp(work, "Bible", 5))
390  is_scripRef = true;
391  }
392 
393  if(is_scripRef)
394  {
395  buf.appendFormatted("\\swordxref{%s}{",
396  ref.c_str()
397 // (work.size()) ? URL::encode(work.c_str()).c_str() : "")
398  );
399  }
400  else
401  {
402  // Dictionary link, or something
403  buf.appendFormatted("\\sworddiclink{%s}{%s}{", // work, entry
404  work.c_str(),
405  ref.c_str()
406  );
407  }
408  }
409  else {
410  outText("}", buf, u);
411  }
412  }
413  }
414 
415  // <l> poetry, etc
416  else if (!strcmp(tag.getName(), "l")) {
417  // start line marker
418  if (tag.getAttribute("sID") || (!tag.isEndTag() && !tag.isEmpty())) {
419  // nested lines plus if the line itself has an x-indent type attribute value
420  outText("\\swordpoetryline{", buf, u);
421  u->lineStack->push(tag.toString());
422  }
423  // end line marker
424  else if (tag.getAttribute("eID") || tag.isEndTag()) {
425  outText("}", buf, u);
426  u->outputNewline(buf);
427  if (u->lineStack->size()) u->lineStack->pop();
428  }
429  // <l/> without eID or sID
430  // Note: this is improper osis. This should be <lb/>
431  else if (tag.isEmpty() && !tag.getAttribute("sID")) {
432  u->outputNewline(buf);
433  }
434  }
435 
436  // <lb.../>
437  else if (!strcmp(tag.getName(), "lb") && (!tag.getAttribute("type") || strcmp(tag.getAttribute("type"), "x-optional"))) {
438  u->outputNewline(buf);
439  }
440  // <milestone type="line"/>
441  // <milestone type="x-p"/>
442  // <milestone type="cQuote" marker="x"/>
443  else if ((!strcmp(tag.getName(), "milestone")) && (tag.getAttribute("type"))) {
444  if (!strcmp(tag.getAttribute("type"), "line")) {
445  u->outputNewline(buf);
446  if (tag.getAttribute("subType") && !strcmp(tag.getAttribute("subType"), "x-PM")) {
447  u->outputNewline(buf);
448  }
449  }
450  else if (!strcmp(tag.getAttribute("type"),"x-p")) {
451  if (tag.getAttribute("marker"))
452  outText(tag.getAttribute("marker"), buf, u);
453  else outText("<!p>", buf, u);
454  }
455  else if (!strcmp(tag.getAttribute("type"), "cQuote")) {
456  const char *tmp = tag.getAttribute("marker");
457  bool hasMark = tmp;
458  SWBuf mark = tmp;
459  tmp = tag.getAttribute("level");
460  int level = (tmp) ? atoi(tmp) : 1;
461 
462  // first check to see if we've been given an explicit mark
463  if (hasMark)
464  outText(mark, buf, u);
465  // finally, alternate " and ', if config says we should supply a mark
466  else if (u->osisQToTick)
467  outText((level % 2) ? '\"' : '\'', buf, u);
468  }
469  }
470 
471  // <title>
472 
473  else if (!strcmp(tag.getName(), "title")) {
474  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
475  const char *tmp = tag.getAttribute("type");
476  bool hasType = tmp;
477  SWBuf type = tmp;
478 
479  outText("\n\\swordtitle{", buf, u);
480  outText(u->divLevel, buf, u);
481  outText("}{", buf, u);
482 
483  if (hasType) outText(type, buf, u);
484  else outText("", buf, u);
485 
486  outText("}{", buf, u);
487  }
488  else if (tag.isEndTag()) {
489  outText( "}", buf, u);
490  ++u->consecutiveNewlines;
491  u->supressAdjacentWhitespace = true;
492  }
493  }
494 
495  // <list>
496  else if (!strcmp(tag.getName(), "list")) {
497  if((!tag.isEndTag()) && (!tag.isEmpty())) {
498  outText("\n\\begin{itemize}", buf, u);
499  }
500  else if (tag.isEndTag()) {
501  outText("\n\\end{itemize}", buf, u);
502  ++u->consecutiveNewlines;
503  u->supressAdjacentWhitespace = true;
504  }
505  }
506 
507  // <item>
508  else if (!strcmp(tag.getName(), "item")) {
509  if((!tag.isEndTag()) && (!tag.isEmpty())) {
510  outText("\n\\item ", buf, u);
511  }
512  else if (tag.isEndTag()) {
513  ++u->consecutiveNewlines;
514  u->supressAdjacentWhitespace = true;
515  }
516  }
517  // <catchWord> & <rdg> tags (italicize)
518  else if (!strcmp(tag.getName(), "rdg") || !strcmp(tag.getName(), "catchWord")) {
519  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
520  outText("\\emph{", buf, u);
521  }
522  else if (tag.isEndTag()) {
523  outText("}", buf, u);
524  }
525  }
526 
527  // divineName
528  else if (!strcmp(tag.getName(), "divineName")) {
529  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
530  outText( "\\sworddivinename{", buf, u);
531  u->suspendTextPassThru = (++u->suspendLevel);
532  }
533  else if (tag.isEndTag()) {
534  SWBuf lastText = u->lastSuspendSegment.c_str();
535  u->suspendTextPassThru = (--u->suspendLevel);
536  if (lastText.size()) {
537  scratch.setFormatted("%s}", lastText.c_str());
538  outText(scratch.c_str(), buf, u);
539  }
540  }
541  }
542 
543  // <hi> text highlighting
544  else if (!strcmp(tag.getName(), "hi")) {
545  SWBuf type = tag.getAttribute("type");
546 
547  // handle tei rend attribute if type doesn't exist
548  if (!type.length()) type = tag.getAttribute("rend");
549 
550  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
551  if (type == "bold" || type == "b" || type == "x-b") {
552  outText("\\textbold{", buf, u);
553  }
554 
555  // there is no officially supported OSIS overline attribute,
556  // thus either TEI overline or OSIS x-overline would be best,
557  // but we have used "ol" in the past, as well. Once a valid
558  // OSIS overline attribute is made available, these should all
559  // eventually be deprecated and never documented that they are supported.
560  else if (type == "ol" || type == "overline" || type == "x-overline") {
561  outText("\\textoverline{", buf, u);
562  }
563 
564  else if (type == "super") {
565  outText("\\textsuperscript{", buf, u);
566  }
567  else if (type == "sub") {
568  outText("\\textsubscript{", buf, u);
569  }
570  else { // all other types
571  outText("\\emph {", buf, u);
572  }
573  u->hiStack->push(tag.toString());
574  }
575  else if (tag.isEndTag()) {
576  outText("}", buf, u);
577  }
578  }
579 
580  // <q> quote
581  // Rules for a quote element:
582  // If the tag is empty with an sID or an eID then use whatever it specifies for quoting.
583  // Note: empty elements without sID or eID are ignored.
584  // If the tag is <q> then use it's specifications and push it onto a stack for </q>
585  // If the tag is </q> then use the pushed <q> for specification
586  // If there is a marker attribute, possibly empty, this overrides osisQToTick.
587  // If osisQToTick, then output the marker, using level to determine the type of mark.
588  else if (!strcmp(tag.getName(), "q")) {
589  SWBuf type = tag.getAttribute("type");
590  SWBuf who = tag.getAttribute("who");
591  const char *tmp = tag.getAttribute("level");
592  int level = (tmp) ? atoi(tmp) : 1;
593  tmp = tag.getAttribute("marker");
594  bool hasMark = tmp;
595  SWBuf mark = tmp;
596 
597  // open <q> or <q sID... />
598  if ((!tag.isEmpty() && !tag.isEndTag()) || (tag.isEmpty() && tag.getAttribute("sID"))) {
599  // if <q> then remember it for the </q>
600  if (!tag.isEmpty()) {
601  u->quoteStack->push(tag.toString());
602  }
603 
604  // Do this first so quote marks are included as WoC
605  if (who == "Jesus")
606  outText(u->wordsOfChristStart, buf, u);
607 
608  // first check to see if we've been given an explicit mark
609  if (hasMark)
610  outText(mark, buf, u);
611  //alternate " and '
612  else if (u->osisQToTick)
613  outText((level % 2) ? '\"' : '\'', buf, u);
614  }
615  // close </q> or <q eID... />
616  else if ((tag.isEndTag()) || (tag.isEmpty() && tag.getAttribute("eID"))) {
617  // if it is </q> then pop the stack for the attributes
618  if (tag.isEndTag() && !u->quoteStack->empty()) {
619  XMLTag qTag(u->quoteStack->top());
620  if (u->quoteStack->size()) u->quoteStack->pop();
621 
622  type = qTag.getAttribute("type");
623  who = qTag.getAttribute("who");
624  tmp = qTag.getAttribute("level");
625  level = (tmp) ? atoi(tmp) : 1;
626  tmp = qTag.getAttribute("marker");
627  hasMark = tmp;
628  mark = tmp;
629  }
630 
631  // first check to see if we've been given an explicit mark
632  if (hasMark)
633  outText(mark, buf, u);
634  // finally, alternate " and ', if config says we should supply a mark
635  else if (u->osisQToTick)
636  outText((level % 2) ? '\"' : '\'', buf, u);
637 
638  // Do this last so quote marks are included as WoC
639  if (who == "Jesus")
640  outText(u->wordsOfChristEnd, buf, u);
641  }
642  }
643 
644  // <transChange>
645  else if (!strcmp(tag.getName(), "transChange")) {
646  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
647  SWBuf type = tag.getAttribute("type");
648  u->lastTransChange = type;
649 
650  // just do all transChange tags this way for now
651  if ((type == "added") || (type == "supplied"))
652  outText("\\swordtranschange{supplied}{", buf, u);
653  else if (type == "tenseChange")
654  outText( "\\swordtranschange{tense}{", buf, u);
655  }
656  else if (tag.isEndTag()) {
657  outText("}", buf, u);
658  }
659  else { // empty transChange marker?
660  }
661  }
662 
663  // image
664  else if (!strcmp(tag.getName(), "figure")) {
665  const char *src = tag.getAttribute("src");
666  if (src) { // assert we have a src attribute
667  SWBuf filepath;
668  if (userData->module) {
669  filepath = userData->module->getConfigEntry("AbsoluteDataPath");
670  if ((filepath.size()) && (filepath[filepath.size()-1] != '/') && (src[0] != '/'))
671  filepath += '/';
672  }
673  filepath += src;
674 
675  outText("\\figure{", buf, u);
676  outText("\\includegraphics{", buf, u);
677  outText(filepath.c_str(), buf, u);
678  outText("}}", buf, u);
679 
680  }
681  }
682 
683  // ok to leave these in
684  else if (!strcmp(tag.getName(), "div")) {
685  SWBuf type = tag.getAttribute("type");
686  if (type == "module") {
687  u->divLevel = type;
688  outText("\n", buf, u);
689  }
690  else if (type == "testament") {
691  u->divLevel = type;
692  outText("\n", buf, u);
693  }
694  else if (type == "bookGroup") {
695  u->divLevel = type;
696  outText("\n", buf, u);
697  }
698  else if (type == "book") {
699  u->divLevel = type;
700  outText("\n", buf, u);
701  }
702  else if (type == "majorSection") {
703  u->divLevel = type;
704  outText("\n", buf, u);
705  }
706  else if (type == "section") {
707  u->divLevel = type;
708  outText("\n", buf, u);
709  }
710  else if (type == "paragraph") {
711  u->divLevel = type;
712  outText("\n", buf, u);
713  }
714  }
715  else if (!strcmp(tag.getName(), "span")) {
716  outText( "", buf, u);
717  }
718  else if (!strcmp(tag.getName(), "br")) {
719  outText( "\\", buf, u);
720  }
721  else if (!strcmp(tag.getName(), "table")) {
722  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
723  outText( "\n\\begin{tabular}", buf, u);
724  }
725  else if (tag.isEndTag()) {
726  outText( "\n\\end{tabular}", buf, u);
727  ++u->consecutiveNewlines;
728  u->supressAdjacentWhitespace = true;
729  }
730 
731  }
732  else if (!strcmp(tag.getName(), "row")) {
733  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
734  outText( "\n", buf, u);
735  u->firstCell = true;
736  }
737  else if (tag.isEndTag()) {
738  outText( "//", buf, u);
739  u->firstCell = false;
740  }
741 
742  }
743  else if (!strcmp(tag.getName(), "cell")) {
744  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
745  if (u->firstCell == false) {
746  outText( " & ", buf, u);
747  }
748  else {
749  u->firstCell = false;
750  }
751  }
752  else if (tag.isEndTag()) {
753  outText( "", buf, u);
754  }
755  }
756  else {
757  if (!u->supressAdjacentWhitespace) u->consecutiveNewlines = 0;
758  return false; // we still didn't handle token
759  }
760  }
761  if (!u->supressAdjacentWhitespace) u->consecutiveNewlines = 0;
762  return true;
763 }
SWBuf & appendFormatted(const char *format,...)
Definition: swbuf.cpp:81
Definition: swbuf.h:47
unsigned long length() const
Definition: swbuf.h:197
virtual const char * getConfigEntry(const char *key) const
Definition: swmodule.cpp:1159
bool renderNoteNumbers
Definition: osislatex.h:36
const SWModule * module
Definition: swbasicfilter.h:42
Definition: utilxml.h:38
bool substituteToken(SWBuf &buf, const char *token)
void processLemma(bool suspendTextPassThru, XMLTag &tag, SWBuf &buf)
char * getRawData()
Definition: swbuf.h:379
const char * c_str() const
Definition: swbuf.h:158
static void outText(const char *t, SWBuf &o, BasicFilterUserData *u)
void processMorph(bool suspendTextPassThru, XMLTag &tag, SWBuf &buf)
unsigned long size() const
Definition: swbuf.h:185
int size
Definition: regex.c:5043
SWBuf & setFormatted(const char *format,...)
Definition: swbuf.cpp:50
bool morphFirst
Definition: osislatex.h:35
void setSize(unsigned long len)
Definition: swbuf.h:255
bool SWBasicFilter::passAllowedEscapeString ( SWBuf buf,
const char *  escString 
)
protectedinherited

This passes allowed escapeStrings

Definition at line 223 of file swbasicfilter.cpp.

223  {
224  StringSet::iterator it;
225 
226  if (!escStringCaseSensitive) {
227  char *tmp = 0;
228  stdstr(&tmp, escString);
229  toupperstr(tmp);
230  it = p->escPassSet.find(tmp);
231  delete [] tmp;
232  } else
233  it = p->escPassSet.find(escString);
234 
235  if (it != p->escPassSet.end()) {
236  appendEscapeString(buf, escString);
237  return true;
238  }
239 
240  return false;
241 }
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
bool escStringCaseSensitive
Definition: swbasicfilter.h:74
char * toupperstr(char *t, unsigned int max=0)
Definition: stringmgr.h:107
Private * p
Definition: swbasicfilter.h:82
void appendEscapeString(SWBuf &buf, const char *escString)
virtual bool SWBasicFilter::processStage ( char  ,
SWBuf ,
char *&  ,
BasicFilterUserData  
)
inlineprotectedvirtualinherited

Reimplemented in OSISPlain.

Definition at line 185 of file swbasicfilter.h.

185 { return false; }
char SWBasicFilter::processText ( SWBuf text,
const SWKey key = 0,
const SWModule module = 0 
)
virtualinherited

This method processes and appropriately modifies the text given it for a particular filter task

Parameters
textThe text to be filtered/converted
keyCurrent key That was used.
moduleCurrent module.
Returns
0

Implements SWFilter.

Reimplemented in ThMLRTF, OSISOSIS, and OSISRTF.

Definition at line 315 of file swbasicfilter.cpp.

315  {
316  char *from;
317  char token[4096];
318  int tokpos = 0;
319  bool intoken = false;
320  bool inEsc = false;
321  int escStartPos = 0, escEndPos = 0;
322  int tokenStartPos = 0, tokenEndPos = 0;
323  SWBuf lastTextNode;
324  BasicFilterUserData *userData = createUserData(module, key);
325 
326  SWBuf orig = text;
327  from = orig.getRawData();
328  text = "";
329 
330  if (processStages & INITIALIZE) {
331  if (processStage(INITIALIZE, text, from, userData)) { // processStage handled it all
332  delete userData;
333  return 0;
334  }
335  }
336 
337  for (;*from; from++) {
338 
339  if (processStages & PRECHAR) {
340  if (processStage(PRECHAR, text, from, userData)) // processStage handled this char
341  continue;
342  }
343 
344  if (*from == tokenStart[tokenStartPos]) {
345  if (tokenStartPos == (tokenStartLen - 1)) {
346  intoken = true;
347  tokpos = 0;
348  token[0] = 0;
349  token[1] = 0;
350  token[2] = 0;
351  inEsc = false;
352  }
353  else tokenStartPos++;
354  continue;
355  }
356 
357  if (*from == escStart[escStartPos]) {
358  if (escStartPos == (escStartLen - 1)) {
359  intoken = true;
360  tokpos = 0;
361  token[0] = 0;
362  token[1] = 0;
363  token[2] = 0;
364  inEsc = true;
365  }
366  else escStartPos++;
367  continue;
368  }
369 
370  if (inEsc) {
371  if (*from == escEnd[escEndPos]) {
372  if (escEndPos == (escEndLen - 1)) {
373  intoken = inEsc = false;
374  userData->lastTextNode = lastTextNode;
375 
376  if (!userData->suspendTextPassThru) { //if text through is disabled no tokens should pass, too
377  if ((!handleEscapeString(text, token, userData)) && (passThruUnknownEsc)) {
378  appendEscapeString(text, token);
379  }
380  }
381  escEndPos = escStartPos = tokenEndPos = tokenStartPos = 0;
382  lastTextNode = "";
383  continue;
384  }
385  }
386  }
387 
388  if (!inEsc) {
389  if (*from == tokenEnd[tokenEndPos]) {
390  if (tokenEndPos == (tokenEndLen - 1)) {
391  intoken = false;
392  userData->lastTextNode = lastTextNode;
393  if ((!handleToken(text, token, userData)) && (passThruUnknownToken)) {
394  text += tokenStart;
395  text += token;
396  text += tokenEnd;
397  }
398  escEndPos = escStartPos = tokenEndPos = tokenStartPos = 0;
399  lastTextNode = "";
400  if (!userData->suspendTextPassThru) {
401  userData->lastSuspendSegment.size(0);
402  }
403  continue;
404  }
405  }
406  }
407 
408  if (intoken) {
409  if (tokpos < 4090) {
410  token[tokpos++] = *from;
411  token[tokpos+2] = 0;
412  }
413  }
414  else {
415  if ((!userData->supressAdjacentWhitespace) || (*from != ' ')) {
416  if (!userData->suspendTextPassThru) {
417  text.append(*from);
418  }
419  else userData->lastSuspendSegment.append(*from);
420  lastTextNode.append(*from);
421  }
422  userData->supressAdjacentWhitespace = false;
423  }
424 
425  if (processStages & POSTCHAR)
426  processStage(POSTCHAR, text, from, userData);
427 
428  }
429 
430  if (processStages & FINALIZE)
431  processStage(FINALIZE, text, from, userData);
432 
433  delete userData;
434  return 0;
435 }
static const char PRECHAR
Definition: swbasicfilter.h:97
Definition: swbuf.h:47
static const char POSTCHAR
Definition: swbasicfilter.h:98
char * tokenStart
Definition: swbasicfilter.h:64
virtual bool handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData)
bool passThruUnknownEsc
Definition: swbasicfilter.h:77
virtual bool handleEscapeString(SWBuf &buf, const char *escString, BasicFilterUserData *userData)
bool passThruUnknownToken
Definition: swbasicfilter.h:76
static const char FINALIZE
Definition: swbasicfilter.h:99
char * getRawData()
Definition: swbuf.h:379
SWBuf & append(const char *str, long max=-1)
Definition: swbuf.h:274
virtual bool processStage(char, SWBuf &, char *&, BasicFilterUserData *)
virtual BasicFilterUserData * createUserData(const SWModule *module, const SWKey *key)
Definition: swbasicfilter.h:91
unsigned long size() const
Definition: swbuf.h:185
static const char INITIALIZE
Definition: swbasicfilter.h:96
void appendEscapeString(SWBuf &buf, const char *escString)
void SWBasicFilter::removeAllowedEscapeString ( const char *  findString)
protectedinherited

Unregisters an esc control sequence that can pass unchanged

Definition at line 169 of file swbasicfilter.cpp.

169  {
170  if (p->escPassSet.find(findString) != p->escPassSet.end()) {
171  p->escPassSet.erase( p->escPassSet.find(findString) );
172  }
173 }
Private * p
Definition: swbasicfilter.h:82
void SWBasicFilter::removeEscapeStringSubstitute ( const char *  findString)
protectedinherited

Unregisters an esc control sequence

Definition at line 189 of file swbasicfilter.cpp.

189  {
190  if (p->escSubMap.find(findString) != p->escSubMap.end()) {
191  p->escSubMap.erase( p->escSubMap.find(findString) );
192  }
193 }
Private * p
Definition: swbasicfilter.h:82
void SWBasicFilter::removeTokenSubstitute ( const char *  findString)
protectedinherited

Unregisters a simple token substitute

Definition at line 149 of file swbasicfilter.cpp.

149  {
150  if (p->tokenSubMap.find(findString) != p->tokenSubMap.end()) {
151  p->tokenSubMap.erase( p->tokenSubMap.find(findString) );
152  }
153 }
DualStringMap tokenSubMap
Private * p
Definition: swbasicfilter.h:82
void SWBasicFilter::setEscapeEnd ( const char *  escEnd)
protectedinherited

Sets the end of escape sequence (by default ";").

Definition at line 297 of file swbasicfilter.cpp.

297  {
298  stdstr(&(this->escEnd), escEnd);
299  escEndLen = strlen(escEnd);
300 }
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
void SWBasicFilter::setEscapeStart ( const char *  escStart)
protectedinherited

Sets the beginning of escape sequence (by default "&").

Definition at line 291 of file swbasicfilter.cpp.

291  {
292  stdstr(&(this->escStart), escStart);
293  escStartLen = strlen(escStart);
294 }
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
void SWBasicFilter::setEscapeStringCaseSensitive ( bool  val)
protectedinherited

Are escapeStrings case sensitive or not? Call this function before addEscapeStingSubstitute()

Definition at line 131 of file swbasicfilter.cpp.

131  {
133 }
bool escStringCaseSensitive
Definition: swbasicfilter.h:74
void OSISLaTeX::setMorphFirst ( bool  val = true)
inline

Definition at line 72 of file osislatex.h.

72 { morphFirst = val; }
bool morphFirst
Definition: osislatex.h:35
void SWBasicFilter::setPassThruNumericEscapeString ( bool  val)
protectedinherited

Sets whether to pass thru a numeric escape sequence unchanged or allow it to be handled otherwise. Default is false.

Definition at line 121 of file swbasicfilter.cpp.

121  {
122  passThruUnknownEsc = val;
123 }
bool passThruUnknownEsc
Definition: swbasicfilter.h:77
void SWBasicFilter::setPassThruUnknownEscapeString ( bool  val)
protectedinherited

Sets whether to pass thru an unknown escape sequence unchanged or just remove it. Default is false.

Definition at line 116 of file swbasicfilter.cpp.

116  {
117  passThruUnknownEsc = val;
118 }
bool passThruUnknownEsc
Definition: swbasicfilter.h:77
void SWBasicFilter::setPassThruUnknownToken ( bool  val)
protectedinherited

Sets whether to pass thru an unknown token unchanged or just remove it. Default is false.

Definition at line 111 of file swbasicfilter.cpp.

111  {
112  passThruUnknownToken = val;
113 }
bool passThruUnknownToken
Definition: swbasicfilter.h:76
void OSISLaTeX::setRenderNoteNumbers ( bool  val = true)
inline

Definition at line 73 of file osislatex.h.

73 { renderNoteNumbers = val; }
bool renderNoteNumbers
Definition: osislatex.h:36
virtual void SWBasicFilter::setStageProcessing ( char  stages)
inlineprotectedvirtualinherited

Definition at line 186 of file swbasicfilter.h.

186 { processStages = stages; } // see STATICs up above
void SWBasicFilter::setTokenCaseSensitive ( bool  val)
protectedinherited

Are tokens case sensitive (like in GBF) or not? Call this function before addTokenSubstitute()

Definition at line 126 of file swbasicfilter.cpp.

126  {
127  tokenCaseSensitive = val;
128 }
bool tokenCaseSensitive
Definition: swbasicfilter.h:75
void SWBasicFilter::setTokenEnd ( const char *  tokenEnd)
protectedinherited

Sets the end of token start sequence (by default ">").

Definition at line 309 of file swbasicfilter.cpp.

309  {
310  stdstr(&(this->tokenEnd), tokenEnd);
311  tokenEndLen = strlen(tokenEnd);
312 }
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
void SWBasicFilter::setTokenStart ( const char *  tokenStart)
protectedinherited

Sets the beginning of token start sequence (by default "<").

Definition at line 303 of file swbasicfilter.cpp.

303  {
304  stdstr(&(this->tokenStart), tokenStart);
305  tokenStartLen = strlen(tokenStart);
306 }
char * tokenStart
Definition: swbasicfilter.h:64
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
bool SWBasicFilter::substituteEscapeString ( SWBuf buf,
const char *  escString 
)
protectedinherited

This function performs the substitution of escapeStrings

Definition at line 253 of file swbasicfilter.cpp.

253  {
254  DualStringMap::iterator it;
255 
256  if (*escString == '#') {
257  return handleNumericEscapeString(buf, escString);
258  }
259 
260  if (passAllowedEscapeString(buf, escString)) {
261  return true;
262  }
263 
264  if (!escStringCaseSensitive) {
265  char *tmp = 0;
266  stdstr(&tmp, escString);
267  toupperstr(tmp);
268  it = p->escSubMap.find(tmp);
269  delete [] tmp;
270  } else
271  it = p->escSubMap.find(escString);
272 
273  if (it != p->escSubMap.end()) {
274  buf += it->second.c_str();
275  return true;
276  }
277  return false;
278 }
virtual bool handleNumericEscapeString(SWBuf &buf, const char *escString)
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
const char * c_str() const
Definition: swbuf.h:158
bool escStringCaseSensitive
Definition: swbasicfilter.h:74
bool passAllowedEscapeString(SWBuf &buf, const char *escString)
char * toupperstr(char *t, unsigned int max=0)
Definition: stringmgr.h:107
Private * p
Definition: swbasicfilter.h:82
bool SWBasicFilter::substituteToken ( SWBuf buf,
const char *  token 
)
protectedinherited

This function performs the substitution of tokens

Definition at line 196 of file swbasicfilter.cpp.

196  {
197  DualStringMap::iterator it;
198 
199  if (!tokenCaseSensitive) {
200  char *tmp = 0;
201  stdstr(&tmp, token);
202  toupperstr(tmp);
203  it = p->tokenSubMap.find(tmp);
204  delete [] tmp;
205  } else
206  it = p->tokenSubMap.find(token);
207 
208  if (it != p->tokenSubMap.end()) {
209  buf += it->second.c_str();
210  return true;
211  }
212  return false;
213 }
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
const char * c_str() const
Definition: swbuf.h:158
bool tokenCaseSensitive
Definition: swbasicfilter.h:75
DualStringMap tokenSubMap
char * toupperstr(char *t, unsigned int max=0)
Definition: stringmgr.h:107
Private * p
Definition: swbasicfilter.h:82

Member Data Documentation

const char SWBasicFilter::FINALIZE = 8
staticprotectedinherited

Definition at line 99 of file swbasicfilter.h.

const char SWBasicFilter::INITIALIZE = 1
staticprotectedinherited

Definition at line 96 of file swbasicfilter.h.

bool OSISLaTeX::morphFirst
private

Definition at line 35 of file osislatex.h.

const char SWBasicFilter::POSTCHAR = 4
staticprotectedinherited

Definition at line 98 of file swbasicfilter.h.

const char SWBasicFilter::PRECHAR = 2
staticprotectedinherited

Definition at line 97 of file swbasicfilter.h.

bool OSISLaTeX::renderNoteNumbers
private

Definition at line 36 of file osislatex.h.


The documentation for this class was generated from the following files: