From 041a0f49832365df11d46af9ecfdc24b5ec42e7c Mon Sep 17 00:00:00 2001 From: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> Date: Thu, 11 Jun 2026 18:32:06 +0300 Subject: [PATCH] add Russian translations for README and ARCHITECTURE --- ARCHITECTURE.ru.md | 120 ++++++++++++++++++++++++++++++++++++++++ README.md | 2 + README.ru.md | 133 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+) create mode 100644 ARCHITECTURE.ru.md create mode 100644 README.ru.md diff --git a/ARCHITECTURE.ru.md b/ARCHITECTURE.ru.md new file mode 100644 index 0000000..cfd9c14 --- /dev/null +++ b/ARCHITECTURE.ru.md @@ -0,0 +1,120 @@ +# Архитектура + +[English](ARCHITECTURE.md) + +Приложение состоит из двух частей: **движок вычислений на TypeScript + UI** в WebView2 +и тонкая **оболочка на Rust** (Tauri 2) для всего, что касается ОС. + +``` +src/ + engine/ сам калькулятор (чистый TS, без DOM) + lexer.ts строка → сырые лексемы (числа, слова, символы) + vocab-data.ts таблицы слов en+ru: единицы, валюты, операторы + vocab.ts объединённый поиск по таблицам + unitdata.ts коэффициенты конвертации (базовые единицы на измерение) + extraunits.ts скорость/давление/энергия/мощность/частота/топливо + крипто + registry.ts фраза → токен; строится один раз при запуске + tokenizer.ts лексемы + реестр → семантические токены + parser.ts токены → AST (Pratt-парсер, терпимый к «мусору») + evaluator.ts AST + контекст документа → значения с единицами + formatter.ts значения → строки для отображения + datetime.ts карта часовых поясов, календарная арифметика + index.ts фасад SumEngine + API расширений + итоги листа + ui/ + editor.ts обвязка CodeMirror 6: подсветка, оверлей результатов, копирование + app.css темы (светлая/тёмная через CSS-переменные) + main.ts запуск приложения: документы, настройки, строка статуса, dnd + storage.ts команды Tauri / запасной вариант на localStorage + extensions.ts запускает пользовательские .js-файлы через движок + i18n.ts строки интерфейса (en/ru) +src-tauri/ + src/main.rs трей, скрытие в трей, команды хранилища, загрузка курсов + (open.er-api.com + CoinGecko) с кэшем, резервные копии, + миграция папки данных, открытие файлов +``` + +## Как строка превращается в результат + +1. **Lexer** разбивает `"5 дюймов в см"` на лексемы: `5`, `дюймов`, `в`, `см`. + Тот же lexer сегментирует фразы из словаря, чтобы совпадение было последовательным. +2. **Registry** хранит все фразы, которые понимает движок, по первой лексеме. + Побеждает наиболее длинное совпадение; регистрозависимые записи (`m` vs `M`, `kB`) + проверяются раньше регистронезависимых, а неоднозначная нижняя форма (`mm` vs `Mm`) + просто не получает нечувствительный к регистру запасной вариант. +3. **Tokenizer** проходит по лексемам, спрашивает реестр и выдаёт типизированные токены. + Несколько контекстных хаков: например, `in` сразу после числа в конце строки + означает дюймы (`6 ft 3 in`). +4. **Parser** — Pratt-парсер, терпимый к шуму: неизвестные слова отбрасываются + до разбора (поэтому `потратил 20 на пиццу плюс 5` работает) — кроме слов + сразу после оператора конвертации, которые могут называть часовой пояс. + Приоритет от наименьшего к наибольшему: конвертации на уровне строки → + поразрядные → аддитивные → мультипликативные (включая `20% от x`) → + унарные → постфиксные (единицы, `%`, `!`, `^`) → первичные. +5. **Evaluator** вычисляет тройки `{ value: Decimal, unit }`. Операнды одного + измерения конвертируются через базовые единицы (`toBase`/`fromBase`); + температуры несут смещение, единицы расхода топлива могут быть обратными + (mpg ↔ л/100км). Контекст документа предоставляет переменные и результаты + предыдущих строк для `сумма`/`avg`/`prev`. +6. **Formatter** отображает значение в формате единицы, с точностью и группировкой + из настроек, или в hex/binary/дроби/римских цифрах и т.д. + +Числа — `decimal.js` везде, никаких артефактов двоичной арифметики. + +## Как добавлять вещи + +**Единицу** — добавь строку в `UNIT_DATA` в `unitdata.ts` (id, измерение, коэффициент +к базовой единице измерения) и её названия в `vocab-data.ts` в соответствующей +категории (`"myunit.variants": "name,names,имя"`, `"myunit.format": "sym"`). +Для совершенно нового измерения расширь объединение `Dimension` в `types.ts` +и используй `extraunits.ts` — фразы живут прямо там. + +**Валюту** — фиатные коды берутся из таблицы `Currency` в `vocab-data.ts`; +крипто идёт в `CRYPTO` в `extraunits.ts` (код, id CoinGecko, фразы, снимок цены) +плюс зеркальный список в `src-tauri/src/main.rs`. + +**Оператор/функцию** — зарегистрируй фразу в `buildRegistry()` (`registry.ts`), +добавь токен/узел AST если нужен новый синтаксис, реализуй в `evaluator.ts`. +Большинство слов-операторов — это данные, а не код. + +**Город часового пояса** — одна строка в карте `Z` в `datetime.ts`. + +## Подводные камни движка + +- Конфликты фраз реальны: одиночные буквы регистрозависимы по замыслу + (`m` метр / `M` миллион, `k` тысяча / `K` кельвин). Генерация префиксов + фильтруется там, где пересекается со словами — например, секунды получают + только ms/µs/ns/ps, потому что символ «аттосекунды» затенил бы слово `as`. +- `и`/`или` двойного назначения: `и` складывает (`5 и 3` = 8), `или` — побитовое. + `от/без/на` работают только с процентом в левой части; иначе это просто текст. +- Курсы валют — «единиц за 1 USD»; соотношение единицы валюты вычисляется при + токенизации из текущей карты курсов, поэтому обновление курсов пересчитывает + всё при следующей оценке. +- Реестр не пересобирается никогда; расширения мутируют его (добавляют фразы/функции) + при запуске. + +## Особенности UI + +- CodeMirror встраивает свою базовую тему во время выполнения *после* `app.css`, + поэтому всё, что должно побеждать (отступ контента для колонки результатов, + цвет курсора), живёт в расширении `EditorView.theme(...)`, а не в стилях. +- Колонка результатов — абсолютно позиционированный оверлей; каждый результат + размещается по координатам `view.lineBlockAt(...)` и перерисовывается при + прокрутке/изменении геометрии. Клик для копирования читает `data-value`. +- Оценка движка синхронная на каждое нажатие клавиши — полный разбор листа + занимает менее миллисекунды, поэтому нет дебаунса и воркеров. + +## Хранилище + +- `settings.json` всегда находится в `%APPDATA%/app.summarum.calc`. +- `documents.json` (все листы) + `backups/` живут либо там, либо в папке данных, + выбранной пользователем (путь хранится в настройках). +- Ежедневный снимок при запуске (`backups/documents-YYYY-MM-DD.json`, хранится 14); + удалённые листы становятся `.numi`-файлами в `backups/deleted/` и удаляются по возрасту. + Сохранение откладывается на 400 мс. + +## Тесты + +`npm test` запускает ~94 vitest-кейса по движку (`src/engine/*.test.ts`): +все классы выражений, оба языка, детерминированные инжектированные курсы, +плюс набор регрессий по всем известным исправленным багам. +UI проверяется вручную; движок — там где живёт вся сложность. diff --git a/README.md b/README.md index c54932d..fb59d64 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Summarum +[Русский](README.ru.md) + **A calculator that works like a notepad.** Type what you're thinking — every line gets a live answer in the right column. No buttons, no formula syntax, just text. diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 0000000..ab3d50f --- /dev/null +++ b/README.ru.md @@ -0,0 +1,133 @@ +# Summarum + +[English](README.md) + +**Калькулятор, который работает как блокнот.** Пишешь что думаешь — каждая строка сразу даёт ответ в правой колонке. Никаких кнопок, никакого синтаксиса формул, просто текст. + +``` +# Поездка в Лиссабон +билеты $420 +отель $95 * 4 ночи +еда 30€ в день * 4 дня и музеи 25€ +итого → $1,066.97 + +5 дюймов в см → 12.7 cm +100 км/ч в миль/ч → 62.14 mph +$2000 в рублях → 144,060 ₽ +скидка 20% от 1500 → 1,200 +сегодня + 6 недель → 22 Июля 2026 +время в Токио → 14:25 +``` + +Работает на **английском и русском одновременно**: `5 метров в см`, `20$ в евро`, `сумма` — переключать язык не нужно. + +## Установка + +Скачай последний `Summarum_*_x64-setup.exe` из [Releases](../../releases), запусти — готово. Весь установщик около 2 МБ. + +Требования: + +- **Windows 10 (1803+) или Windows 11**, 64-бит. +- **[WebView2 Runtime](https://developer.microsoft.com/en-us/microsoft-edge/webview2/)** — + уже встроен в Windows 11 и большинство обновлённых Windows 10; если отсутствует, + установщик скачает его автоматически. +- Интернет нужен только для живых курсов валют — всё остальное работает офлайн + (курсы берутся из кэша или встроенного снимка). + +## Что понимает + +**Обычная математика** — `2 + 2`, `8 / (45 - 20%)`, скобки, `^`, `sqrt`, `sin`, +факториалы. Точная десятичная арифметика: `0.1 + 0.2` это `0.3`, а не `0.30000000000000004`. + +**Слова как операторы** — `12 плюс 4`, `20 делить на 4`, `5 и 3`. Текст вокруг +математики игнорируется: `потратил 20 на пиццу и 5 на кофе` даст 25. + +**Единицы** — длина, масса, объём, площадь, температура, время, углы, данные +(`1 ГиБ в МБ`), CSS px/em, скорость, давление, энергия, мощность, частота, расход топлива: + +``` +6 футов в метрах 1 атм в мм рт.ст. 8 л/100км в mpg +2 часа 30 мин в мин 150 л.с. в кВт 32 px в em +``` + +**Деньги** — ~150 валют и топ-20 криптовалют с живыми курсами +(обновляются раз в час, кэшируются для офлайна). `$100 + 20%`, `5 eth в USD`, +`9800 рублей в долларах`. + +**Проценты по-человечески** — `20% от 80`, `скидка 20% от 1500`, `5 это сколько % от 25`, +`20% от какого числа равно 30`. + +**Даты и время** — `сегодня + 2 недели`, `завтра - сегодня`, `время в Нью-Йорке`, +`сейчас в unix`, `1750000000 как дата`. + +**Для программистов** — `0xFF & 0x0F`, `1 << 4`, `255 в hex`, `в binary`, +плюс `в дроби` (0.75 → 3/4) и `в roman` (2026 → MMXXVI). + +**Листы с переменными** — переменные (`аренда = $500`), нарастающие итоги +(`сумма`, `avg`, `prev`), заголовки `#`, комментарии `//`. Строка статуса всегда +показывает итог листа; выдели несколько строк — увидишь их сумму. + +## Удобные мелочи + +- **Ctrl+Alt+N** (настраивается — поле в настройках записывает нажатые клавиши) + показывает/скрывает окно из любого места. Закрытие прячет в трей. +- **Клик по результату** копирует его. Копирование строки копирует её *вместе с ответом* + (`аренда * 3 = $1,500`). **Ctrl+Shift+C** копирует весь лист с ответами. +- **Потяни разделитель** чтобы изменить ширину колонки результатов. +- **Брось файл `.numi`, `.sum`, `.txt` или `.md`** в окно — откроется как лист. +- **Резервные копии автоматические**: ежедневный снимок всех листов (хранятся 14 дней), + удалённые листы лежат в корзине 14 дней (настраивается) — верни перетащив обратно. + Настройки → Backups откроет папку. +- **Папка данных настраивается** — укажи OneDrive/Dropbox и листы синхронизируются + между машинами. +- Светлая/тёмная тема, интерфейс en/ru, настраиваемая точность и разделители. + +## Расширения + +Брось `.js`-файл в папку расширений (Настройки → Extensions folder) и перезапусти. +API совместим с расширениями Numi: + +```js +numi.setVariable("ндс", { double: 20 }); +numi.addUnit({ id: "этаж", phrases: "этаж,этажей", baseUnitId: "meter", + format: "эт", ratio: 3 }); +numi.addFunction({ id: "гипот", phrases: "гипот" }, + (v) => ({ double: Math.hypot(v[0].double, v[1].double) })); +``` + +Тогда `5 этажей в метрах` → `15 m` и `гипот(3; 4)` → `5`. + +## Баги и идеи + +Открой [issue](../../issues). Строка того что написал и что ожидал увидеть — достаточно. + +## Для разработчиков + +Устройство движка, структура проекта и как добавлять единицы/валюты: +см. [ARCHITECTURE.ru.md](ARCHITECTURE.ru.md). + +```bash +npm install +npm test # тесты движка +npm run tauri dev # запустить приложение +npm run tauri build # собрать установщик +``` + +Для сборки нужны: + +- [Node.js](https://nodejs.org/) 22.6 или новее +- [Rust](https://rustup.rs/) (stable, MSVC toolchain) +- [Visual Studio Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) + с компонентом «Desktop development with C++» (нужен линковщик MSVC) +- Если что-то не собирается — см. [Tauri prerequisites](https://tauri.app/start/prerequisites/) + +Стек: [Tauri 2](https://tauri.app) + TypeScript + CodeMirror 6. + +## Благодарности + +Вдохновлён отличным [Numi](https://numi.app) от Дмитрия Николаева — +если ты на macOS, купи его. Summarum — независимый проект, написанный с нуля для Windows. + +## Лицензия + +[MIT](LICENSE)