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