libime
pinyincorrectionprofile.cpp
1 /*
2  * SPDX-FileCopyrightText: 2024-2024 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  */
6 #include "pinyincorrectionprofile.h"
7 #include <cstddef>
8 #include <memory>
9 #include <string>
10 #include <unordered_map>
11 #include <utility>
12 #include <vector>
13 #include <fcitx-utils/macros.h>
14 #include "pinyindata.h"
15 #include "pinyinencoder.h"
16 
17 namespace libime {
18 
19 namespace {
20 
21 /*
22  * Helper function to create mapping based on keyboard rows.
23  * Function assume that the key can only be corrected to the key adjcent to it.
24  */
25 std::unordered_map<char, std::vector<char>>
26 mappingFromRows(const std::vector<std::string> &rows) {
27  std::unordered_map<char, std::vector<char>> result;
28  for (const auto &row : rows) {
29  for (size_t i = 0; i < row.size(); i++) {
30  std::vector<char> items;
31  if (i > 0) {
32  items.push_back(row[i - 1]);
33  }
34  if (i + 1 < row.size()) {
35  items.push_back(row[i + 1]);
36  }
37  result[row[i]] = std::move(items);
38  }
39  }
40  return result;
41 }
42 
43 std::unordered_map<char, std::vector<char>>
44 getProfileMapping(BuiltinPinyinCorrectionProfile profile) {
45  switch (profile) {
46  case BuiltinPinyinCorrectionProfile::Qwerty:
47  return mappingFromRows({"qwertyuiop", "asdfghjkl", "zxcvbnm"});
48  }
49 
50  return {};
51 }
52 } // namespace
53 
55 public:
56  PinyinMap pinyinMap_;
57  std::unordered_map<char, std::vector<char>> correctionMap_;
58 };
59 
61  BuiltinPinyinCorrectionProfile profile)
62  : PinyinCorrectionProfile(getProfileMapping(profile)) {}
63 
65  const std::unordered_map<char, std::vector<char>> &mapping)
66  : d_ptr(std::make_unique<PinyinCorrectionProfilePrivate>()) {
67  FCITX_D();
68  d->correctionMap_ = mapping;
69  // Fill with the original pinyin map.
70  d->pinyinMap_ = getPinyinMapV2();
71  if (mapping.empty()) {
72  return;
73  }
74  // Re-map all entry with the correction mapping.
75  std::vector<PinyinEntry> newEntries;
76  for (const auto &item : d->pinyinMap_) {
77  for (size_t i = 0; i < item.pinyin().size(); i++) {
78  auto chr = item.pinyin()[i];
79  auto swap = mapping.find(chr);
80  if (swap == mapping.end() || swap->second.empty()) {
81  continue;
82  }
83  auto newEntry = item.pinyin();
84  for (auto sub : swap->second) {
85  newEntry[i] = sub;
86  newEntries.push_back(
87  PinyinEntry(newEntry.data(), item.initial(), item.final(),
88  item.flags() | PinyinFuzzyFlag::Correction));
89  newEntry[i] = chr;
90  }
91  }
92  }
93  for (const auto &newEntry : newEntries) {
94  d->pinyinMap_.insert(newEntry);
95  }
96 }
97 
98 PinyinCorrectionProfile::~PinyinCorrectionProfile() = default;
99 
100 const PinyinMap &PinyinCorrectionProfile::pinyinMap() const {
101  FCITX_D();
102  return d->pinyinMap_;
103 }
104 
105 const std::unordered_map<char, std::vector<char>> &
107  FCITX_D();
108  return d->correctionMap_;
109 }
110 } // namespace libime
PinyinCorrectionProfile(BuiltinPinyinCorrectionProfile profile)
Construct the profile based on builtin layout.
const PinyinMap & pinyinMap() const
Return the updated pinyin map.
Class that holds updated Pinyin correction mapping based on correction mapping.
const std::unordered_map< char, std::vector< char > > & correctionMap() const
Return the correction mapping.