]> git.lyx.org Git - lyx.git/blob - src/mathed/MathAutoCorrect.cpp
Proper GUI feedback for leqno option
[lyx.git] / src / mathed / MathAutoCorrect.cpp
1 /**
2  * \file MathAutoCorrect.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "MathAutoCorrect.h"
14 #include "MathData.h"
15 #include "InsetMath.h"
16 #include "MathSupport.h"
17 #include "MathParser.h"
18
19 #include "support/debug.h"
20 #include "support/FileName.h"
21 #include "support/filetools.h" //  LibFileSearch
22 #include "support/docstream.h"
23
24 #include <fstream>
25 #include <sstream>
26
27 using namespace std;
28
29 namespace lyx {
30
31 using support::libFileSearch;
32
33 namespace {
34
35 class Correction {
36 public:
37         ///
38         /// \brief Correction
39         Correction() : from2_(0) {}
40         ///
41         bool correct(MathAtom & at, char_type c) const;
42         ///
43         bool read(idocstream & is);
44         ///
45         void write(odocstream & os) const;
46 private:
47         ///
48         MathAtom from1_;
49         ///
50         char_type from2_;
51         ///
52         MathAtom to_;
53 };
54
55
56 bool Correction::read(idocstream & is)
57 {
58         docstring s1, s2, s3;
59         is >> s1 >> s2 >> s3;
60         if (!is)
61                 return false;
62         if (s2.size() != 1)
63                 return false;
64         MathData ar1, ar3;
65         mathed_parse_cell(ar1, s1);
66         mathed_parse_cell(ar3, s3);
67         if (ar1.size() != 1 || ar3.size() != 1)
68                 return false;
69         from1_ = ar1.front();
70         from2_ = s2[0];
71         to_    = ar3.front();
72         return true;
73 }
74
75
76 bool Correction::correct(MathAtom & at, char_type c) const
77 {
78         //LYXERR(Debug::MATHED,
79         //      "trying to correct ar: " << at << " from: '" << from1_ << '\'');
80         if (from2_ != c)
81                 return false;
82         if (asString(at) != asString(from1_))
83                 return false;
84         LYXERR(Debug::MATHED, "match found! subst in " << at
85                 << " from: '" << from1_ << "' to '" << to_ << '\'');
86         at = to_;
87         return true;
88 }
89
90
91 #if 0
92 void Correction::write(odocstream & os) const
93 {
94         os << "from: '" << from1_ << "' and '" << from2_
95            << "' to '" << to_ << '\'' << endl;
96 }
97
98
99 idocstream & operator>>(idocstream & is, Correction & corr)
100 {
101         corr.read(is);
102         return is;
103 }
104
105
106 odocstream & operator<<(odocstream & os, Correction & corr)
107 {
108         corr.write(os);
109         return os;
110 }
111 #endif
112
113
114
115 class Corrections {
116 public:
117         ///
118         typedef vector<Correction>::const_iterator const_iterator;
119         ///
120         Corrections() {}
121         ///
122         void insert(const Correction & corr) { data_.push_back(corr); }
123         ///
124         bool correct(MathAtom & at, char_type c) const;
125 private:
126         ///
127         vector<Correction> data_;
128 };
129
130
131 bool Corrections::correct(MathAtom & at, char_type c) const
132 {
133         for (const_iterator it = data_.begin(); it != data_.end(); ++it)
134                 if (it->correct(at, c))
135                         return true;
136         return false;
137 }
138
139
140 Corrections theCorrections;
141
142 void initAutoCorrect()
143 {
144         LYXERR(Debug::MATHED, "reading autocorrect file");
145         support::FileName const file = libFileSearch(string(), "autocorrect");
146         if (file.empty()) {
147                 lyxerr << "Could not find autocorrect file" << endl;
148                 return;
149         }
150
151         string line;
152         ifstream is(file.toFilesystemEncoding().c_str());
153         while (getline(is, line)) {
154                 if (line.empty() || line[0] == '#') {
155                         //LYXERR(Debug::MATHED, "ignoring line '" << line << '\'');
156                         continue;
157                 }
158                 idocstringstream il(from_utf8(line));
159
160                 //LYXERR(Debug::MATHED, "line '" << line << '\'');
161                 Correction corr;
162                 if (corr.read(il)) {
163                         //LYXERR(Debug::MATHED, "parsed: '" << corr << '\'');
164                         theCorrections.insert(corr);
165                 }
166         }
167
168         LYXERR(Debug::MATHED, "done reading autocorrections.");
169 }
170
171
172 } // namespace anon
173
174
175 bool math_autocorrect(MathAtom & at, char_type c)
176 {
177         static bool initialized = false;
178
179         if (!initialized) {
180                 initAutoCorrect();
181                 initialized = true;
182         }
183
184         return theCorrections.correct(at, c);
185 }
186
187
188 } // namespace lyx