Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 26 additions & 0 deletions packages/number-to-words-nl/0.1.0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Number to words NL

**Number to words NL** is an [Espanso](https://espanso.org/) package that enables you to convert numbers directly to full written currencies from your Espanso extension.

This is the same functionality as https://www.zegge.nu/ and also based on that code
## Features

- Easily convert numbers to full written out currencies, e.g.
Comment on lines +3 to +8
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor wording issue: “convert numbers directly to full written currencies” is grammatically off/unclear. Consider rephrasing to “convert numbers to fully written-out currency amounts” (or similar).

Suggested change
**Number to words NL** is an [Espanso](https://espanso.org/) package that enables you to convert numbers directly to full written currencies from your Espanso extension.
This is the same functionality as https://www.zegge.nu/ and also based on that code
## Features
- Easily convert numbers to full written out currencies, e.g.
**Number to words NL** is an [Espanso](https://espanso.org/) package that enables you to convert numbers to fully written-out currency amounts from your Espanso extension.
This provides the same functionality as https://www.zegge.nu/ and is also based on that code.
## Features
- Easily convert numbers to fully written-out currency amounts, e.g.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Picky, but I agree.

- 150 becomes honderdvijftig euro
- 1 009 123,50 becomes een miljoen negenduizend honderddrieëntwintig euro en vijftig eurocent

## Requirements

- **Python** must be installed on your system.

## Installation

To install from espanso hub:

```
espanso install number-to-words
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The install command uses espanso install number-to-words, but this package’s manifest name/directory is number-to-words-nl, so the command as written won’t install this package from the hub. Update the README to use the correct package name.

Suggested change
espanso install number-to-words
espanso install number-to-words-nl

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

@smeech smeech Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or remove the installation instructions entirely - if you look at the Hub entries you'll see these are generated automatically and placed towards the top-right of each package's landing page anyway.

```

## Usage

Type `:nr` and see what's happening.
7 changes: 7 additions & 0 deletions packages/number-to-words-nl/0.1.0/_manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: "number-to-words-nl"
title: "Number to Words (Dutch)"
description: Converts numbers to their Dutch word representation
homepage: "https://github.com/brentgees"
version: 0.1.0
author: Brent Gees, zegge.nu
tags: ["Dutch", "Numbers", "Converter", "Utility]
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tags has invalid YAML due to a missing closing quote on Utility (it currently reads "Utility]). This will prevent the manifest from parsing.

Suggested change
tags: ["Dutch", "Numbers", "Converter", "Utility]
tags: ["Dutch", "Numbers", "Converter", "Utility"]

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

@smeech smeech Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That needs fixing.

99 changes: 99 additions & 0 deletions packages/number-to-words-nl/0.1.0/package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
matches:
- trigger: ":nr"
replace: "{{output}}"
vars:
- name: "form1"
type: form
params:
layout: "Bedrag: [[getal]]"

- name: output
type: script
params:
args:
- python
- -c
- |
# -*- coding: utf-8 -*-
import sys
Comment on lines +13 to +18
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Python logic is fairly large to inline under python -c in YAML, which makes it harder to maintain and increases the chance of quoting/templating bugs. Consider moving the converter into a dedicated .py file within the package and invoking it from args (as done in e.g. packages/ask-airia/0.1.0/package.yml:36-38).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore.

import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

getal = '{{form1.getal}}'

Comment on lines +20 to +23
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User-provided form input is interpolated directly into the Python source (getal = '{{form1.getal}}'). If the input contains a single quote/newline it can break the string literal and inject arbitrary Python code. Pass the value as a separate argv argument (or encode via JSON) and read it from sys.argv instead of templating it into the script.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not overly concerned about this - all data entered is going to come locally from the user. If they want to try and inject arbitrary Python code that's up to them.

eenheden = ['', 'een', 'twee', 'drie', 'vier', 'vijf', 'zes', 'zeven', 'acht', 'negen']
tien_tot_twintig = ['tien', 'elf', 'twaalf', 'dertien', 'veertien', 'vijftien', 'zestien', 'zeventien', 'achttien', 'negentien']
tientallen = ['', '', 'twintig', 'dertig', 'veertig', 'vijftig', 'zestig', 'zeventig', 'tachtig', 'negentig']
grootheden = ['', 'duizend', 'miljoen', 'miljard', 'biljoen', 'biljard', 'triljoen']

def tot_honderd(n):
if n == 0: return ''
elif n < 10: return eenheden[n]
elif n < 20: return tien_tot_twintig[n - 10]
else:
tien, een = n // 10, n % 10
if een == 0: return tientallen[tien]
result = f'{eenheden[een]}en{tientallen[tien]}'
return result.replace('eeen', 'eeën').replace('ieen', 'ieën')

def tot_duizend(n):
if n == 0: return ''
honderd, rest = n // 100, n % 100
result = ''
if honderd > 0:
if honderd == 1:
result = 'honderd'
else:
result = f'{eenheden[honderd]}honderd'
rest_text = tot_honderd(rest) if rest > 0 else ''
return result + rest_text

def converteer(num_str):
if not num_str or num_str == '0': return 'nul'
num = int(num_str.replace(' ', '').replace('.', ''))
if num == 0: return 'nul'
result, groep_index = '', 0
while num > 0:
groep = num % 1000
if groep > 0:
groep_tekst = tot_duizend(groep)
if groep_index > 0:
if groep_index == 1:
groep_tekst = f'{groep_tekst}{grootheden[groep_index]}'
else:
groep_tekst = f'{groep_tekst} {grootheden[groep_index]}'
result = f'{groep_tekst} {result}' if result else groep_tekst
num //= 1000
groep_index += 1
result = result.strip()
if result.startswith('eenduizend'): result = 'duizend' + result[10:]
return result

getal_str = getal.replace(' ', '')

# Zoek het laatste scheidingsteken (. of ,)
laatste_punt = getal_str.rfind('.')
laatste_komma = getal_str.rfind(',')
laatste_scheiding = max(laatste_punt, laatste_komma)

if laatste_scheiding > 0:
# Controleer of er 1 of 2 cijfers na het laatste scheidingsteken staan
na_scheiding = getal_str[laatste_scheiding + 1:]
if len(na_scheiding) <= 2 and na_scheiding.isdigit():
# Dit is het decimaalteken
hoofdgetal = getal_str[:laatste_scheiding].replace('.', '').replace(',', '')
decimalen = (na_scheiding + '00')[:2]
else:
# Geen decimalen, alles is hoofdgetal
hoofdgetal = getal_str.replace('.', '').replace(',', '')
decimalen = ''
else:
hoofdgetal = getal_str
decimalen = ''

uitvoer = converteer(hoofdgetal) + ' euro'
if decimalen and decimalen != '00':
cent_tekst = converteer(decimalen)
uitvoer += f' en {cent_tekst} eurocent'

print(uitvoer)
Loading