formulens 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2026 Rajesh Das (rajeshdas.dev)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,87 @@
1
+ Metadata-Version: 2.4
2
+ Name: formulens
3
+ Version: 0.0.1
4
+ Summary: Local equation-to-LaTeX recognition with a Linux-first CLI.
5
+ Keywords: latex,equations,ocr,cli,linux,configuration
6
+ Author: Rajesh Das
7
+ Author-email: Rajesh Das <hyperoot.tech@proton.me>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
18
+ Requires-Dist: pydantic>=2.13.5
19
+ Requires-Dist: typer>=0.27.2
20
+ Requires-Dist: utilityhub-config>=0.2.7
21
+ Requires-Python: >=3.14
22
+ Project-URL: Homepage, https://formulens.hyperoot.dev/
23
+ Project-URL: Documentation, https://formulens.hyperoot.dev/
24
+ Project-URL: Repository, https://github.com/HYP3R00T/formulens
25
+ Project-URL: Issues, https://github.com/HYP3R00T/formulens/issues
26
+ Description-Content-Type: text/markdown
27
+
28
+ # Formulens
29
+
30
+ Formulens is a Linux-first CLI for a local equation-to-LaTeX workflow.
31
+
32
+ Version **0.0.1** provides configuration management through Typer and UtilityHub
33
+ Config. Equation recognition, screen capture, daemon mode, and clipboard
34
+ integration are not implemented in this release.
35
+
36
+ ## Installation
37
+
38
+ Requires Python **3.14 or newer**. After this release is published, install it with
39
+ [uv](https://docs.astral.sh/uv/):
40
+
41
+ ```bash
42
+ uv tool install formulens
43
+ ```
44
+
45
+ ## Configuration
46
+
47
+ ```bash
48
+ formulens --help
49
+ formulens config init
50
+ formulens config path
51
+ formulens config show
52
+ formulens config set notifications false
53
+ ```
54
+
55
+ Settings are stored at `~/.config/formulens/formulens.toml`:
56
+
57
+ ```toml
58
+ copy_to_clipboard = true
59
+ notifications = true
60
+ ```
61
+
62
+ `init` preserves existing configuration. `path` prints its location. `show`
63
+ displays effective settings as JSON without creating files. `set` validates and
64
+ saves an edit. These preferences are stored for future desktop integration;
65
+ they do not yet trigger clipboard output or notifications.
66
+
67
+ Environment variables such as `FORMULENS_NOTIFICATIONS=false` override saved
68
+ values. Formulens loads global TOML/YAML configuration and any `.env` inside its
69
+ configuration directory, without searching the current working directory.
70
+ `set` updates only the TOML file and does not save environment overrides.
71
+
72
+ ## Development
73
+
74
+ From a checkout of the repository:
75
+
76
+ ```bash
77
+ uv sync --all-packages
78
+ uv run formulens --help
79
+ uv run python -m unittest discover -s tests
80
+ ```
81
+
82
+ See the [project repository](https://github.com/HYP3R00T/formulens) for development
83
+ setup and documentation.
84
+
85
+ ## License
86
+
87
+ MIT. Copyright 2026 Rajesh Das. The license is included in the distribution.
@@ -0,0 +1,60 @@
1
+ # Formulens
2
+
3
+ Formulens is a Linux-first CLI for a local equation-to-LaTeX workflow.
4
+
5
+ Version **0.0.1** provides configuration management through Typer and UtilityHub
6
+ Config. Equation recognition, screen capture, daemon mode, and clipboard
7
+ integration are not implemented in this release.
8
+
9
+ ## Installation
10
+
11
+ Requires Python **3.14 or newer**. After this release is published, install it with
12
+ [uv](https://docs.astral.sh/uv/):
13
+
14
+ ```bash
15
+ uv tool install formulens
16
+ ```
17
+
18
+ ## Configuration
19
+
20
+ ```bash
21
+ formulens --help
22
+ formulens config init
23
+ formulens config path
24
+ formulens config show
25
+ formulens config set notifications false
26
+ ```
27
+
28
+ Settings are stored at `~/.config/formulens/formulens.toml`:
29
+
30
+ ```toml
31
+ copy_to_clipboard = true
32
+ notifications = true
33
+ ```
34
+
35
+ `init` preserves existing configuration. `path` prints its location. `show`
36
+ displays effective settings as JSON without creating files. `set` validates and
37
+ saves an edit. These preferences are stored for future desktop integration;
38
+ they do not yet trigger clipboard output or notifications.
39
+
40
+ Environment variables such as `FORMULENS_NOTIFICATIONS=false` override saved
41
+ values. Formulens loads global TOML/YAML configuration and any `.env` inside its
42
+ configuration directory, without searching the current working directory.
43
+ `set` updates only the TOML file and does not save environment overrides.
44
+
45
+ ## Development
46
+
47
+ From a checkout of the repository:
48
+
49
+ ```bash
50
+ uv sync --all-packages
51
+ uv run formulens --help
52
+ uv run python -m unittest discover -s tests
53
+ ```
54
+
55
+ See the [project repository](https://github.com/HYP3R00T/formulens) for development
56
+ setup and documentation.
57
+
58
+ ## License
59
+
60
+ MIT. Copyright 2026 Rajesh Das. The license is included in the distribution.
@@ -0,0 +1,48 @@
1
+ [project]
2
+ name = "formulens"
3
+ version = "0.0.1"
4
+ description = "Local equation-to-LaTeX recognition with a Linux-first CLI."
5
+ readme = "README.md"
6
+ requires-python = ">=3.14"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ keywords = [
10
+ "latex",
11
+ "equations",
12
+ "ocr",
13
+ "cli",
14
+ "linux",
15
+ "configuration",
16
+ ]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Environment :: Console",
20
+ "Intended Audience :: Science/Research",
21
+ "Operating System :: POSIX :: Linux",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3 :: Only",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Topic :: Scientific/Engineering :: Mathematics",
26
+ ]
27
+ dependencies = [
28
+ "pydantic>=2.13.5",
29
+ "typer>=0.27.2",
30
+ "utilityhub-config>=0.2.7",
31
+ ]
32
+
33
+ [[project.authors]]
34
+ name = "Rajesh Das"
35
+ email = "hyperoot.tech@proton.me"
36
+
37
+ [project.scripts]
38
+ formulens = "formulens:main"
39
+
40
+ [project.urls]
41
+ Homepage = "https://formulens.hyperoot.dev/"
42
+ Documentation = "https://formulens.hyperoot.dev/"
43
+ Repository = "https://github.com/HYP3R00T/formulens"
44
+ Issues = "https://github.com/HYP3R00T/formulens/issues"
45
+
46
+ [build-system]
47
+ requires = ["uv_build>=0.12.7,<0.13.0"]
48
+ build-backend = "uv_build"
@@ -0,0 +1,38 @@
1
+ [project]
2
+ name = "formulens"
3
+ version = "0.0.1"
4
+ description = "Local equation-to-LaTeX recognition with a Linux-first CLI."
5
+ readme = "README.md"
6
+ requires-python = ">=3.14"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ authors = [{ name = "Rajesh Das", email = "hyperoot.tech@proton.me" }]
10
+ keywords = ["latex", "equations", "ocr", "cli", "linux", "configuration"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Environment :: Console",
14
+ "Intended Audience :: Science/Research",
15
+ "Operating System :: POSIX :: Linux",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3 :: Only",
18
+ "Programming Language :: Python :: 3.14",
19
+ "Topic :: Scientific/Engineering :: Mathematics",
20
+ ]
21
+ dependencies = [
22
+ "pydantic>=2.13.5",
23
+ "typer>=0.27.2",
24
+ "utilityhub-config>=0.2.7",
25
+ ]
26
+
27
+ [project.scripts]
28
+ formulens = "formulens:main"
29
+
30
+ [project.urls]
31
+ Homepage = "https://formulens.hyperoot.dev/"
32
+ Documentation = "https://formulens.hyperoot.dev/"
33
+ Repository = "https://github.com/HYP3R00T/formulens"
34
+ Issues = "https://github.com/HYP3R00T/formulens/issues"
35
+
36
+ [build-system]
37
+ requires = ["uv_build>=0.12.7,<0.13.0"]
38
+ build-backend = "uv_build"
@@ -0,0 +1,7 @@
1
+ """Formulens command-line entry point."""
2
+
3
+
4
+ def main() -> None:
5
+ from formulens.cli import app
6
+
7
+ app()
@@ -0,0 +1,8 @@
1
+ """Assemble the Formulens CLI from its command groups."""
2
+
3
+ import typer
4
+
5
+ from formulens.commands.config import app as config_app
6
+
7
+ app = typer.Typer(help="Local equation-to-LaTeX tools.", no_args_is_help=True)
8
+ app.add_typer(config_app, name="config")
@@ -0,0 +1 @@
1
+ """CLI command groups and presentation helpers."""
@@ -0,0 +1,43 @@
1
+ """Commands for managing Formulens configuration."""
2
+
3
+ from typing import Annotated
4
+
5
+ import typer
6
+
7
+ from formulens.commands.errors import run_config_action
8
+ from formulens.configuration.storage import (
9
+ get_settings_path,
10
+ initialize_settings,
11
+ load_configuration,
12
+ set_setting,
13
+ )
14
+
15
+ app = typer.Typer(help="Manage configuration in ~/.config/formulens.", no_args_is_help=True)
16
+
17
+
18
+ @app.command("init")
19
+ def config_init() -> None:
20
+ """Create default configuration, preserving any existing settings."""
21
+ typer.echo(run_config_action(initialize_settings))
22
+
23
+
24
+ @app.command("path")
25
+ def config_path() -> None:
26
+ """Print the configuration path without creating a file."""
27
+ typer.echo(get_settings_path())
28
+
29
+
30
+ @app.command("show")
31
+ def config_show() -> None:
32
+ """Print effective settings as JSON, including environment overrides."""
33
+ settings = run_config_action(load_configuration)
34
+ typer.echo(settings.model_dump_json(indent=2))
35
+
36
+
37
+ @app.command("set")
38
+ def config_set(
39
+ key: Annotated[str, typer.Argument(help="Setting name, such as notifications.")],
40
+ value: Annotated[str, typer.Argument(help="New value: true or false.")],
41
+ ) -> None:
42
+ """Validate and save a setting in the global TOML file."""
43
+ typer.echo(run_config_action(lambda: set_setting(key, value)))
@@ -0,0 +1,16 @@
1
+ """Translate configuration failures into CLI errors."""
2
+
3
+ from collections.abc import Callable
4
+
5
+ import typer
6
+ from pydantic import ValidationError
7
+ from utilityhub_config.errors import ConfigError
8
+
9
+
10
+ def run_config_action[T](action: Callable[[], T]) -> T:
11
+ """Report configuration failures without a Python traceback."""
12
+ try:
13
+ return action()
14
+ except (ConfigError, ValidationError, OSError, ValueError, RuntimeError) as error:
15
+ typer.echo(f"Configuration error: {error}", err=True)
16
+ raise typer.Exit(code=1) from error
@@ -0,0 +1 @@
1
+ """Typed settings and persistence, independent of the CLI."""
@@ -0,0 +1,12 @@
1
+ """Validated Formulens preferences."""
2
+
3
+ from pydantic import BaseModel, ConfigDict
4
+
5
+
6
+ class Settings(BaseModel):
7
+ """Preferences for clipboard output and desktop notifications."""
8
+
9
+ model_config = ConfigDict(extra="forbid")
10
+
11
+ copy_to_clipboard: bool = True
12
+ notifications: bool = True
@@ -0,0 +1,50 @@
1
+ """Load and save user configuration through UtilityHub Config."""
2
+
3
+ import tomllib
4
+ from pathlib import Path
5
+
6
+ from utilityhub_config import ensure_config_file, get_config_path, load_settings, write_config
7
+
8
+ from formulens.configuration.schema import Settings
9
+
10
+
11
+ def get_settings_path() -> Path:
12
+ return get_config_path("formulens")
13
+
14
+
15
+ def initialize_settings() -> Path:
16
+ """Create defaults without overwriting an existing configuration."""
17
+ path = get_settings_path()
18
+ if path.exists():
19
+ read_saved_settings()
20
+ return ensure_config_file(Settings(), "formulens")
21
+
22
+
23
+ def read_saved_settings() -> Settings:
24
+ """Read only persisted values, so edits never save environment overrides."""
25
+ path = get_settings_path()
26
+ if not path.exists():
27
+ return Settings()
28
+ with path.open("rb") as stream:
29
+ return Settings.model_validate(tomllib.load(stream))
30
+
31
+
32
+ def load_configuration() -> Settings:
33
+ """Resolve settings without discovering files in the current directory."""
34
+ settings, _ = load_settings(
35
+ Settings,
36
+ app_name="formulens",
37
+ cwd=get_settings_path().parent,
38
+ env_prefix="FORMULENS",
39
+ )
40
+ return settings
41
+
42
+
43
+ def set_setting(key: str, value: str) -> Path:
44
+ """Validate a single edit before writing the saved configuration."""
45
+ if key not in Settings.model_fields:
46
+ raise ValueError(f"Unknown setting '{key}'. Choose from: {', '.join(Settings.model_fields)}")
47
+ values = read_saved_settings().model_dump()
48
+ values[key] = value
49
+ settings = Settings.model_validate(values)
50
+ return write_config(settings, "formulens")