]> git.lyx.org Git - lyx.git/blob - src/mathed/math_autocorrect.C
First shot at "auto correction" feature in mathed
[lyx.git] / src / mathed / math_autocorrect.C
1 #include <config.h>
2
3 #include "LString.h"
4 #include "Lsstream.h"
5 #include "debug.h"
6 #include "support/filetools.h" //  LibFileSearch
7 #include "math_data.h"
8 #include "math_inset.h"
9 #include "math_parser.h"
10
11 #include <iostream>
12 #include <fstream>
13
14 using std::ifstream;
15 using std::istream;
16 using std::ostream;
17 using std::endl;
18
19
20 namespace {
21
22 class Correction {
23 public:
24         ///
25         Correction() {}
26         ///
27         bool correct(MathAtom & at, char c) const;
28         ///
29         bool read(istream & is);
30         ///
31         void write(ostream & os) const;
32 private:
33         ///     
34         MathAtom from1_;
35         ///     
36         char from2_;
37         ///     
38         MathAtom to_;
39 };
40
41
42 bool Correction::read(istream & is)
43 {
44         string s1, s2, s3;
45         is >> s1 >> s2 >> s3;
46         if (!is)
47                 return false;
48         MathArray ar1, ar3;
49         mathed_parse_cell(ar1, s1);
50         mathed_parse_cell(ar3, s3);
51         if (ar1.size() != 1  ||  s2.size() != 1  ||  ar3.size() !=1)
52                 return false;
53         from1_ = ar1.front();
54         from2_ = s2[0];
55         to_    = ar3.front();
56         return true;
57 }
58
59
60 void Correction::write(ostream & os) const
61 {
62         os << "from: '" << from1_ << "' and '" << from2_
63            << "' to '" << to_ << "'" << endl;
64 }
65
66
67 bool Correction::correct(MathAtom & at, char c) const
68 {
69         //lyxerr[Debug::MATHED]
70         //      << "trying to correct ar: " << at << " from: '" << from1_ << "'" << endl;
71         if (from2_ != c)
72                 return false;
73         if (!at->match(from1_.nucleus()))
74                 return false;
75         lyxerr[Debug::MATHED]
76                 << "match found! subst in " << at
77                 << " from: '" << from1_ << "' to '" << to_ << "'" << endl;
78         at = to_;
79         return true;
80 }
81
82
83 istream & operator>>(istream & is, Correction & corr)
84 {
85         corr.read(is);
86         return is;
87 }
88
89
90 ostream & operator<<(ostream & os, Correction & corr)
91 {
92         corr.write(os);
93         return os;
94 }
95
96
97
98
99 class Corrections {
100 public:
101         ///     
102         typedef vector<Correction>::const_iterator const_iterator;
103         ///     
104         Corrections() {}
105         ///     
106         void insert(const Correction & corr) { data_.push_back(corr); }
107         ///
108         bool correct(MathAtom & at, char c) const;
109 private:
110         ///     
111         vector<Correction> data_;       
112 };
113
114
115 bool Corrections::correct(MathAtom & at, char c) const
116 {
117         for (const_iterator it = data_.begin(); it != data_.end(); ++it)
118                 if (it->correct(at, c))
119                         return true;
120         return false;
121 }
122
123
124 Corrections theCorrections;
125
126 void initAutoCorrect()
127 {
128         lyxerr[Debug::MATHED] << "reading autocorrect file" << endl;
129         string const file = LibFileSearch(string(), "autocorrect");
130         if (file.empty()) {
131                 lyxerr << "Could not find autocorrect file" << endl;
132                 return;
133         }
134
135         string line;
136         ifstream is(file.c_str());
137         while (getline(is, line)) {
138                 if (line.size() == 0 || line[0] == '#') {
139                         //lyxerr[Debug::MATHED] << "ignoring line '" << line << "'" << endl;
140                         continue;
141                 }
142                 istringstream il(line);
143                 //lyxerr[Debug::MATHED] << "line '" << line << "'" << endl;
144                 Correction corr;
145                 if (corr.read(il)) {
146                         //lyxerr[Debug::MATHED] << "parsed: '" << corr << "'" << endl;
147                         theCorrections.insert(corr);
148                 }
149         }
150
151         lyxerr[Debug::MATHED] << "done reading autocorrections." << endl;
152 }
153
154
155 } // namespace anon
156
157
158 bool math_autocorrect(MathAtom & at, char c)
159 {
160         static bool initialized = false;
161
162         if (!initialized) {
163                 initAutoCorrect();
164                 initialized = true;
165         }
166
167         return theCorrections.correct(at, c);
168 }