1 /***************************************************************************
2                           hebSegment.h - Hebrew substring handling
3                              -------------------
4     begin                : Thu Mar  1 13:15:18 IST 2001
5     copyright            : (C) 2001 by Arie Tal
6     email                : tal_arie@yahoo.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef __hebSegment_h__
19 #define __hebSegment_h__
20 
21 #include "Locations.h"
22 #include "Screen.h"
23 #include "aString.h"
24 #include <string.h>
25 /*
26   The kind of segments we want to deal with are those of LaXeT, meaning
27   a segment is of the form
28   \\[LR]\{...\}
29   or
30   \\[a-zA-Z_*+#\[\]\-\\]+(\{...\})?
31 
32   where ...   indicates free form text, including internal segments
33 
34   We will use a simple implementation of recursive descent parsing.
35 */
36 
37 #define MAX_LANGUAGE_DEPTH 80
38 
39 #define INITIAL_LANGUAGE_DEPTH 4
40 
41 #define LATEX_COMMAND_START 4096
42 #define HEBREW_SEGMENT_START 4097
43 #define ENGLISH_SEGMENT_START 4098
44 #define SEGMENT_START 4099
45 #define SEGMENT_END 4100
46 #define LATEX_COMMAND 4101
47 #define MATH_SEGMENT  4102
48 #define MATH_SEGMENT_START 4103
49 #define MATH_SEGMENT_START2 4105
50 #define MATH_SEGMENT_END 4104
51 #define MATH_SEGMENT_END2 4106
52 
53 #define MARGIN_FIX -2
54 
55 struct  modeStackElement {
56    int location ;
57    char left[10] ;
58    short mode ;
59    short mathmode, lang_change ;
modeStackElementmodeStackElement60    modeStackElement() {
61       strcpy(left,"") ;
62    }
63    modeStackElement operator =(modeStackElement &a) {
64      location=a.location ;// left = a.left ;
65      mode=a.mode ; mathmode = a.mathmode ;
66      lang_change=a.lang_change ;
67      strcpy(left, a.left) ;
68      return *this ; }
isEqualmodeStackElement69    int isEqual(modeStackElement &a) {
70      return (location==a.location)&&(mode==a.mode)&&(mathmode==a.mathmode) &&
71             (lang_change == a.lang_change) ; // && !strcmp(left, a.left);
72             }
73 } ;
74 
75 class modeStack {
76     modeStackElement *data ;
77     int stackPointer ;
78     int real_size ;
asMode(short x)79     hebStringMode asMode(short x) { return (x==0) ? StrEnglish : StrHebrew ; }
asShort(hebStringMode m)80     short asShort(hebStringMode m) { return (m == StrEnglish) ? 0 : 1 ; }
81     aString empty ;
_expand_size(int factor)82     void _expand_size(int factor) { // PORT: void
83        real_size *= factor ;
84        modeStackElement *tmp = new modeStackElement[real_size] ;
85        for (int i=0; i < stackPointer ; i++ ) {
86           tmp[i] = data[i] ;
87        } /* endfor */
88        delete data ;
89        data = tmp ;
90     }
91 public:
modeStack()92     modeStack() : stackPointer(0), real_size(INITIAL_LANGUAGE_DEPTH)  {
93       data = new modeStackElement[real_size] ;
94     } ;
~modeStack()95     ~modeStack() { delete data ; }
topMode()96     hebStringMode topMode() {
97       return (stackPointer >0)?asMode(data[stackPointer-1].mode) : StrEnglish ; }
topLocation()98     int topLocation() { return (stackPointer > 0)?data[stackPointer-1].location : 0 ; }
99 //    aString topLeft() { return (stackPointer > 0)?data[stackPointer-1].left : empty ; }
topMath()100     short topMath() { return (stackPointer > 0)?data[stackPointer-1].mathmode : 0; }
topLangChange()101     short topLangChange() { return (stackPointer > 0)?
102                              data[stackPointer-1].lang_change: 0; }
topLeft()103     const char* topLeft() { return (stackPointer >0)?(data[stackPointer-1].left) : 0 ; }
peekMode(int depth)104     hebStringMode peekMode(int depth) {
105       return (stackPointer > depth)?asMode(data[stackPointer-(depth+1)].mode):
106         StrEnglish ; }
107 //    aString peekLeft(int depth) {
108 //      return (stackPointer > depth)?data[stackPointer-(depth+1)].left:
109 //      empty ; }
majorMode()110     hebStringMode majorMode() {
111       return (stackPointer > 0) ? asMode(data[0].mode) : StrEnglish ; }
112     void push(hebStringMode mode, char *left, int location, int math=0,
113                  short lang_change = 0) {
114       if (stackPointer >= real_size) {
115          _expand_size(2) ;
116       } /* endif */
117       data[stackPointer].mode = asShort(mode) ;
118       data[stackPointer].location = location ;
119       data[stackPointer].mathmode = math ;
120       data[stackPointer].lang_change = lang_change ;
121       strcpy(data[stackPointer++].left,left) ;
122       }
pop()123     void pop() { if (stackPointer>0) --stackPointer ; }
depth()124     int depth() { return stackPointer ; }
125     void copy(modeStack& stack) ;
126     int isEqual(modeStack& stack) ;
clear()127     void clear() { stackPointer = 0 ; } // for mode changers
128 } ;
129 
130 
131 class HebrewEditor ;
132 
133 class hebSegment : public aString {
134    HebrewEditor *he ;
135    int wrongSpelling ;
136    char buffer[MAX_SCREEN_WIDTH] ;
137    char reverse_buffer[2] ;
138    int _separate_command ;
139    int   _processLatexCommand(char *buffer, char **str, modeStack &stack) ;
140    int   _getNextToken(char **str, modeStack &stack) ;
141    int _areAllWhiteSpaces(char *from, char *to) ;
142    int _findCommentStart(char *from, char *to) ;
143    char *reverse(char *s) ;
144    int _length ;
145    Locations *_locations ;
146    hebStringMode modeChange ;
147    int modeChanged ;
148    int _margin ;
149    int _comment ;
150    modeStack last_mode_stack ;
151    int last_length_limit ;
152    int activeSpelling ;
153 public:
getWrongSpelling()154     int getWrongSpelling() { return wrongSpelling ; }
155     hebSegment(HebrewEditor *he, const char *t,int from, int startHebrew,
156                Screen &scr, int margin,  int comment, int lenght_limit, modeStack &stack,
157                int show_line_end_marks=1, int activeSpelling = 0) ;
~hebSegment()158     ~hebSegment() { (aString &)(*this) = "" ; delete _locations ; }
159 
length()160     int length() { return _length ; } // return the actual length of the segment
getLocations()161     Locations *getLocations() {  return _locations ; }
getModeChange()162     hebStringMode getModeChange() { return modeChange ; }
getModeChanged()163     int getModeChanged() { return modeChanged ; }
getMargin()164     int getMargin() { return _margin ; }
getComment()165     int getComment() { return _comment ; }
166 
getMinLocation()167     int getMinLocation() { return _locations->getMinVal() ; }
getMaxLocation()168     int getMaxLocation() { return _locations->getMaxVal() ; }
setMinLocation(int m)169     void setMinLocation(int m) { _locations->setMinVal(m) ; }
updateMinLocation(int u)170     void updateMinLocation(int u)  { _locations->setMinVal( _locations->getMinVal() + u ) ; }
noNeedToRecompile(int from,int margin,int length_limit,modeStack & stack)171     int noNeedToRecompile(int from, int margin, int length_limit, modeStack &stack) {
172       return (last_mode_stack.isEqual(stack)) &&
173         (from == _locations->getMinVal()) &&
174         (last_length_limit == length_limit) &&
175         (_margin == margin) ; }
getLastModeStack()176     modeStack& getLastModeStack() { return last_mode_stack ; }
177 } ;
178 
179 #endif
180