Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Math font #377

Merged
merged 34 commits into from
Mar 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

### Improve

* Let Esc exit math mode [#379](https://github.com/Riey/kime/issues/379)
* Add font style specifier for math symbols

## 2.0.1

### Improve

* Make more key to commit hangul [#373](https://github.com/Riey/kime/issues/373)

## 2.0.0
Expand Down
78 changes: 76 additions & 2 deletions src/engine/backends/math/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@ use kime_engine_backend::{
Key, KeyCode,
};
use kime_engine_backend_latin::{load_layout, LatinConfig};
use kime_engine_dict::math_symbol_key::*;

#[cfg(test)]
mod tests {
#[test]
fn test_parse_style() {
use kime_engine_dict::math_symbol_key::*;

assert_eq!(crate::parse_style("sf"), Style::SF);
assert_eq!(crate::parse_style("bf"), Style::BF);
assert_eq!(crate::parse_style("it"), Style::IT);
assert_eq!(crate::parse_style("tt"), Style::TT);
assert_eq!(crate::parse_style("bb"), Style::BB);
assert_eq!(crate::parse_style("scr"), Style::SCR);
assert_eq!(crate::parse_style("cal"), Style::CAL);
assert_eq!(crate::parse_style("frak"), Style::FRAK);
assert_eq!(crate::parse_style("fruk"), Style::NONE);
assert_eq!(crate::parse_style("bfit"), Style::BF | Style::IT);
assert_eq!(
crate::parse_style("bfsfit"),
Style::SF | Style::BF | Style::IT
);
}
}

#[derive(Clone)]
pub struct MathMode {
Expand All @@ -22,6 +46,45 @@ impl MathMode {
}
}

fn parse_style(style_str: &str) -> Style {
let mut buf: &str = style_str;
let mut style = Style::NONE;

loop {
let style_new = if buf.is_empty() {
return style;
} else if let Some(_buf) = buf.strip_prefix("sf") {
buf = _buf;
Style::SF
} else if let Some(_buf) = buf.strip_prefix("bf") {
buf = _buf;
Style::BF
} else if let Some(_buf) = buf.strip_prefix("it") {
buf = _buf;
Style::IT
} else if let Some(_buf) = buf.strip_prefix("tt") {
buf = _buf;
Style::TT
} else if let Some(_buf) = buf.strip_prefix("bb") {
buf = _buf;
Style::BB
} else if let Some(_buf) = buf.strip_prefix("scr") {
buf = _buf;
Style::SCR
} else if let Some(_buf) = buf.strip_prefix("cal") {
buf = _buf;
Style::CAL
} else if let Some(_buf) = buf.strip_prefix("frak") {
buf = _buf;
Style::FRAK
} else {
return Style::NONE;
};

style |= style_new;
}
}

impl InputEngineMode for MathMode {
fn press_key(&mut self, key: Key, commit_buf: &mut String) -> InputEngineModeResult<bool> {
if key == Key::normal(KeyCode::Backslash) {
Expand Down Expand Up @@ -58,9 +121,20 @@ impl InputEngineMode for MathMode {
}

fn clear_preedit(&mut self, commit_buf: &mut String) -> InputEngineModeResult<()> {
if let Some(symbol) = kime_engine_dict::lookup_math_symbol(&self.buf) {
commit_buf.push_str(symbol);
let mut iter = self.buf.split('.');
if let Some(first) = iter.next() {
if let Some(second) = iter.next() {
let style = parse_style(first);
if let Some(symbol) = kime_engine_dict::lookup_math_symbol(&second, style) {
commit_buf.push_str(symbol);
}
} else {
if let Some(symbol) = kime_engine_dict::lookup_math_symbol(&first, Style::NONE) {
commit_buf.push_str(symbol);
}
}
}

self.buf.clear();
self.math_mode = false;
Continue(())
Expand Down
2 changes: 1 addition & 1 deletion src/engine/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl InputEngine {
let mut processed = false;
match hotkey.behavior() {
HotkeyBehavior::Switch(category) => {
if self.category() != category {
if self.category() != category || self.engine_impl.mode.is_some() {
self.set_input_category(category);
ret |= InputResult::LANGUAGE_CHANGED;
processed = true;
Expand Down
29 changes: 29 additions & 0 deletions src/engine/core/tests/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,32 @@ fn backspace() {
(Key::normal(Backspace), "", ""),
])
}

// issue #379
#[test]
fn esc() {
test_input(&[
(MATH, "", ""),
(Key::normal(Esc), "", "PASS"),
(Key::normal(Backslash), "", "\\"),
]);
}

#[test]
fn style() {
test_input(&[
(MATH, "", ""),
(Key::normal(Backslash), "\\", ""),
(Key::normal(B), "\\b", ""),
(Key::normal(F), "\\bf", ""),
(Key::normal(I), "\\bfi", ""),
(Key::normal(T), "\\bfit", ""),
(Key::normal(Period), "\\bfit.", ""),
(Key::normal(A), "\\bfit.a", ""),
(Key::normal(L), "\\bfit.al", ""),
(Key::normal(P), "\\bfit.alp", ""),
(Key::normal(H), "\\bfit.alph", ""),
(Key::normal(A), "\\bfit.alpha", ""),
(Key::normal(Tab), "", "𝜶"),
])
}
66 changes: 55 additions & 11 deletions src/engine/dict/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#[path = "src/math_symbol_key.rs"]
mod math_symbol_key;

use itertools::Itertools;
use serde::Deserialize;
use math_symbol_key::*;
use serde::{Deserialize, Deserializer};
use std::{
collections::BTreeMap,
env,
Expand Down Expand Up @@ -41,10 +45,41 @@ struct UnicodeEntry {
tts: String,
}

impl<'de> Deserialize<'de> for Style {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
use serde::de::Error;

let styles: Vec<&str> = Deserialize::deserialize(deserializer)?;
let style = styles
.into_iter()
.map(|s| {
Ok(match s {
"sf" => Style::SF,
"bf" => Style::BF,
"it" => Style::IT,
"tt" => Style::TT,
"bb" => Style::BB,
"scr" => Style::SCR,
"cal" => Style::CAL,
"frak" => Style::FRAK,
_ => return Err(Error::custom("no matching style name")),
})
})
.fold(Ok(Style::NONE), |sty1, sty2| Ok(sty1? | sty2?));
style
}
}

#[derive(Deserialize)]
struct StySymPair<'a> {
style: Style,
symbol: &'a str,
}

#[derive(Deserialize)]
struct KeySymPair<'a> {
keyword: &'a str,
symbol: &'a str,
symbols: Vec<StySymPair<'a>>,
}

fn load_hanja_dict() -> BTreeMap<char, Vec<HanjaEntry>> {
Expand Down Expand Up @@ -133,6 +168,7 @@ fn main() {
std::fs::File::create(PathBuf::from(env::var("OUT_DIR").unwrap()).join("dict.rs")).unwrap(),
);

writeln!(out, "use crate::math_symbol_key::*;").unwrap();
writeln!(
out,
"pub static HANJA_ENTRIES: &[(char, &[(char, &str)])] = &[",
Expand All @@ -153,17 +189,25 @@ fn main() {

writeln!(out, "];").unwrap();

let symbol_map = include_str!("data/symbol_map.json");
let mut symbol_map: Vec<KeySymPair> = serde_json::from_str(symbol_map).unwrap();
symbol_map.sort_unstable_by_key(|pair| pair.keyword);

writeln!(out, "pub static MATH_SYMBOL_ENTRIES: &[(&str, &str)] = &[").unwrap();

for pair in &symbol_map {
writeln!(out, "(\"{}\", \"{}\"),", pair.keyword, pair.symbol).unwrap();
let symbol_map_data = include_str!("data/symbol_map.json");
let symbol_map_data: Vec<KeySymPair> = serde_json::from_str(symbol_map_data).unwrap();
let mut symbol_map: Vec<(SymbolKey, &str)> = Vec::new();
for key_sym_pair in &symbol_map_data {
let keyword = &key_sym_pair.keyword;
for sty_sym_pair in &key_sym_pair.symbols {
let style = sty_sym_pair.style;
let symbol = sty_sym_pair.symbol;
symbol_map.push((SymbolKey(keyword, style), symbol));
}
}
symbol_map.sort_unstable_by_key(|pair| pair.0);

writeln!(out, "];").unwrap();
writeln!(
out,
"pub static MATH_SYMBOL_ENTRIES: &[(SymbolKey, &str)] = &{:?};",
symbol_map
)
.unwrap();

writeln!(out, "#[derive(Clone, Copy, Debug)] pub struct UnicodeAnnotation {{ pub codepoint: &'static str, pub tts: &'static str, }}").unwrap();
writeln!(
Expand Down
Loading