Converter Plugin — Design Spec
Date: 2026-03-26
Status: Draft
Goal: Create an owlry plugin for unit and currency conversion with natural speech input.
1. Overview
A dynamic plugin that converts between units of measurement and currencies. Users type natural expressions like 102F to C or > 50 kg in lb and see conversion results inline.
Key UX decisions:
- Trigger prefix
> for explicit conversion, plus auto-detection
- Accepts
to and in as connector words
- No space required between number and unit (
102F works)
- When no target unit specified, shows the most common conversions for that category
- Currency rates from ECB (free, no API key, ~30 fiat currencies, daily)
- Case-insensitive matching with generous aliases
2. Plugin Identity
| Field |
Value |
| Plugin ID |
converter |
| Provider ID |
converter |
| Type ID |
conv |
| Provider Kind |
Dynamic |
| Trigger prefix |
> |
| Search prefix |
:conv |
| Position |
Normal |
| Priority |
9000 |
| Icon |
accessories-text-editor (or edit-find-replace) |
| Crate |
owlry-plugin-converter |
| Repo |
owlry-plugins |
3. Query Parsing
Input patterns
All of these are valid and must parse correctly:
Parser rules
- Strip prefix
> if present (and trim whitespace)
- Extract number: integer or decimal at start of input (
102, 3.5, .5, 0.25)
- Extract source unit: immediately adjacent to number OR space-separated. Match against known unit aliases (case-insensitive, longest match first)
- If remaining input contains
to or in (case-insensitive, word boundary), extract target unit from what follows
- If no connector word and remaining text after source unit is non-empty, try to parse it as a target unit anyway (handles
100 km miles)
Auto-detection
The plugin's query() is called for every keystroke. To avoid false positives:
- Only match if the input starts with a number
- Only match if the text after the number resolves to a known unit alias
- Minimum input length: 2 characters (number + unit)
- Don't match if the text after the number is not a unit alias (e.g.,
100x, 102nd)
Ambiguity resolution
| Input |
Resolves to |
Why |
oz |
Ounce (weight) |
More common than fluid ounce |
fl oz, floz |
Fluid ounce |
Explicit |
ton |
Metric ton (1000 kg) |
International default |
short_ton, ton_us |
US short ton (907 kg) |
Explicit |
gal |
US gallon |
More common globally in software |
gal_uk, imp_gal |
Imperial gallon |
Explicit |
4. Unit System Architecture
Conversion model
Each category has a base unit. Every unit defines a conversion factor relative to the base:
For most units this is a simple multiply/divide by factor. Temperature uses offset formulas.
Unit definition
Base units per category
| Category |
Base unit |
Rationale |
| Temperature |
Kelvin |
Standard SI, no negative zero issues |
| Length |
Meter |
SI |
| Weight |
Kilogram |
SI |
| Volume |
Liter |
Practical |
| Speed |
m/s |
SI |
| Area |
m² |
SI |
| Data |
Byte |
Fundamental |
| Time |
Second |
SI |
| Pressure |
Pascal |
SI |
| Energy |
Joule |
SI |
| Currency |
EUR |
ECB reports rates relative to EUR |
Temperature conversions (special case)
5. Unit Table
Temperature
| Unit |
Symbol |
Aliases |
Factor/Conversion |
| Celsius |
°C |
c, °c, celsius, degc, centigrade |
Custom |
| Fahrenheit |
°F |
f, °f, fahrenheit, degf |
Custom |
| Kelvin |
K |
k, kelvin |
Base |
Length
| Unit |
Symbol |
Aliases |
Factor (to meters) |
| Millimeter |
mm |
mm, millimeter, millimeters, millimetre |
0.001 |
| Centimeter |
cm |
cm, centimeter, centimeters, centimetre |
0.01 |
| Meter |
m |
m, meter, meters, metre, metres |
1.0 (base) |
| Kilometer |
km |
km, kms, kilometer, kilometers, kilometre |
1000.0 |
| Inch |
in |
in, inch, inches, " |
0.0254 |
| Foot |
ft |
ft, foot, feet, ' |
0.3048 |
| Yard |
yd |
yd, yard, yards |
0.9144 |
| Mile |
mi |
mi, mile, miles |
1609.344 |
| Nautical mile |
nmi |
nmi, nautical_mile, nautical_miles |
1852.0 |
Weight/Mass
| Unit |
Symbol |
Aliases |
Factor (to kg) |
| Milligram |
mg |
mg, milligram, milligrams |
0.000001 |
| Gram |
g |
g, gram, grams |
0.001 |
| Kilogram |
kg |
kg, kilogram, kilograms, kilo, kilos |
1.0 (base) |
| Metric ton |
t |
t, ton, tons, tonne, tonnes, metric_ton |
1000.0 |
| US short ton |
short_ton |
short_ton, ton_us |
907.185 |
| Ounce |
oz |
oz, ounce, ounces |
0.0283495 |
| Pound |
lb |
lb, lbs, pound, pounds |
0.453592 |
| Stone |
st |
st, stone, stones |
6.35029 |
Volume
| Unit |
Symbol |
Aliases |
Factor (to liters) |
| Milliliter |
ml |
ml, milliliter, milliliters, millilitre |
0.001 |
| Liter |
l |
l, liter, liters, litre, litres |
1.0 (base) |
| US gallon |
gal |
gal, gallon, gallons |
3.78541 |
| Imperial gallon |
imp_gal |
imp_gal, gal_uk, imperial_gallon |
4.54609 |
| Quart |
qt |
qt, quart, quarts |
0.946353 |
| Pint |
pt |
pt, pint, pints |
0.473176 |
| Cup |
cup |
cup, cups |
0.236588 |
| Fluid ounce |
fl oz |
floz, fl_oz, fluid_ounce, fluid_ounces |
0.0295735 |
| Tablespoon |
tbsp |
tbsp, tablespoon, tablespoons |
0.0147868 |
| Teaspoon |
tsp |
tsp, teaspoon, teaspoons |
0.00492892 |
Speed
| Unit |
Symbol |
Aliases |
Factor (to m/s) |
| m/s |
m/s |
m/s, mps, meters_per_second |
1.0 (base) |
| km/h |
km/h |
km/h, kmh, kph, kilometers_per_hour |
0.277778 |
| mph |
mph |
mph, miles_per_hour |
0.44704 |
| Knot |
kn |
kn, kt, knot, knots |
0.514444 |
| ft/s |
ft/s |
ft/s, fps, feet_per_second |
0.3048 |
Area
| Unit |
Symbol |
Aliases |
Factor (to m²) |
| mm² |
mm² |
mm2, sqmm, square_millimeter |
0.000001 |
| cm² |
cm² |
cm2, sqcm, square_centimeter |
0.0001 |
| m² |
m² |
m2, sqm, square_meter, square_meters |
1.0 (base) |
| km² |
km² |
km2, sqkm, square_kilometer |
1000000.0 |
| ft² |
ft² |
ft2, sqft, square_foot, square_feet |
0.092903 |
| Acre |
ac |
ac, acre, acres |
4046.86 |
| Hectare |
ha |
ha, hectare, hectares |
10000.0 |
Data
| Unit |
Symbol |
Aliases |
Factor (to bytes) |
| Byte |
B |
b, byte, bytes |
1.0 (base) |
| Kilobyte |
KB |
kb, kilobyte, kilobytes |
1000.0 |
| Megabyte |
MB |
mb, megabyte, megabytes |
1000000.0 |
| Gigabyte |
GB |
gb, gigabyte, gigabytes |
1000000000.0 |
| Terabyte |
TB |
tb, terabyte, terabytes |
1000000000000.0 |
| Kibibyte |
KiB |
kib, kibibyte, kibibytes |
1024.0 |
| Mebibyte |
MiB |
mib, mebibyte, mebibytes |
1048576.0 |
| Gibibyte |
GiB |
gib, gibibyte, gibibytes |
1073741824.0 |
| Tebibyte |
TiB |
tib, tebibyte, tebibytes |
1099511627776.0 |
Time
| Unit |
Symbol |
Aliases |
Factor (to seconds) |
| Second |
s |
s, sec, second, seconds |
1.0 (base) |
| Minute |
min |
min, minute, minutes |
60.0 |
| Hour |
h |
h, hr, hour, hours |
3600.0 |
| Day |
d |
d, day, days |
86400.0 |
| Week |
wk |
wk, week, weeks |
604800.0 |
| Month |
mo |
mo, month, months |
2592000.0 (30 days) |
| Year |
yr |
yr, year, years |
31536000.0 (365 days) |
Pressure
| Unit |
Symbol |
Aliases |
Factor (to Pa) |
| Pascal |
Pa |
pa, pascal, pascals |
1.0 (base) |
| Hectopascal |
hPa |
hpa, hectopascal |
100.0 |
| Kilopascal |
kPa |
kpa, kilopascal |
1000.0 |
| Bar |
bar |
bar, bars |
100000.0 |
| Millibar |
mbar |
mbar, millibar |
100.0 |
| PSI |
psi |
psi, pounds_per_square_inch |
6894.76 |
| Atmosphere |
atm |
atm, atmosphere, atmospheres |
101325.0 |
| mmHg |
mmHg |
mmhg, torr |
133.322 |
Energy
| Unit |
Symbol |
Aliases |
Factor (to Joules) |
| Joule |
J |
j, joule, joules |
1.0 (base) |
| Kilojoule |
kJ |
kj, kilojoule, kilojoules |
1000.0 |
| Calorie |
cal |
cal, calorie, calories |
4.184 |
| Kilocalorie |
kcal |
kcal, kilocalorie, kilocalories |
4184.0 |
| Watt-hour |
Wh |
wh, watt_hour |
3600.0 |
| Kilowatt-hour |
kWh |
kwh, kilowatt_hour |
3600000.0 |
| BTU |
BTU |
btu, british_thermal_unit |
1055.06 |
6. Currency
Data source
ECB daily reference rates: https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
Returns ~30 currencies with rates relative to EUR.
Caching
- Cache file:
~/.cache/owlry/ecb_rates.json
- Format:
{ "date": "2026-03-26", "rates": { "USD": 1.0832, "GBP": 0.8345, ... } }
- Refresh when cache is older than 24 hours
- If fetch fails, use cached rates silently (stale rates > no rates)
- If no cache exists and fetch fails, currency conversions return no results
Currency aliases
Each currency accepts ISO code, lowercase, full name, and common symbol:
| Currency |
Aliases |
| EUR |
eur, euro, euros, € |
| USD |
usd, dollar, dollars, $, us_dollar |
| GBP |
gbp, pound_sterling, £, british_pound |
| JPY |
jpy, yen, ¥, japanese_yen |
| CHF |
chf, swiss_franc, francs |
| CAD |
cad, canadian_dollar, c$ |
| AUD |
aud, australian_dollar, a$ |
| CNY |
cny, yuan, renminbi, rmb |
| SEK |
sek, swedish_krona, kronor |
| NOK |
nok, norwegian_krone |
| DKK |
dkk, danish_krone |
| PLN |
pln, zloty, złoty |
| CZK |
czk, czech_koruna |
| HUF |
huf, forint |
| TRY |
try, turkish_lira, lira |
| (others) |
ISO code + lowercase |
Conversion
EUR is the base. To convert A→B: result = value / rate_A * rate_B
(EUR rate is implicitly 1.0 since ECB reports everything relative to EUR.)
7. Result Display
With target unit specified
One result:
Without target unit
Up to 5 results showing common conversions for that category:
Common conversions per category
| Category |
Show (excluding source unit) |
| Temperature |
°C, °F, K |
| Length |
m, km, ft, mi, in |
| Weight |
kg, lb, oz, g, st |
| Volume |
l, gal, ml, cup, fl oz |
| Speed |
km/h, mph, m/s, kn |
| Area |
m², ft², acres, ha, km² |
| Data |
MB, GB, MiB, GiB, TB |
| Time |
s, min, h, days, weeks |
| Pressure |
bar, psi, atm, hPa, mmHg |
| Energy |
kJ, kcal, kWh, BTU, Wh |
| Currency |
USD, EUR, GBP, JPY, CNY |
Number formatting
- Up to 4 decimal places, trailing zeros stripped
- Large numbers get thousand separators:
1,000,000
- Very small numbers use scientific notation if < 0.0001
- Currency always shows 2 decimal places
8. File Structure
Dependencies
9. Out of Scope
- Cryptocurrency (future addition)
- Compound units (
km/h² to m/s²)
- Math expressions in conversion (
2 * 50 kg to lb)
- Configurable default targets per category
- Locale-aware number formatting (use
. as decimal separator always)
- Offline currency rate bundling (rely on cache)