Conversation
|
got it. I'm trying to finish up a translation pr too. I'm taking a different, more invasive approach. I'll try to get it polished off today or tomorrow so I can post it and we can compare. |
|
i don't think we need to bother with .mo files. our translation foot print is very small. I can do some performance testing, but i suspect that it's going to be one to two milis even if i 10x what we think we'll see. |
|
How can I help? Would you like me to test? Would you like a formal review? Do you want to discuss? If you want to help me refine #2736 you could build it locally and review the DE translation. Follow TRANSLATING.md, edit a PO file in Poedit, and see the result locally. I think it is ready to go, but I'd like to get a set of eyes on it before we waste Simon's time, partcularly because I am taking a different approach than what he had in mind, so I could use some puch back :). |
|
I think it is ready to go, but I'd like to get a set of eyes on it before we waste Simon's time, partcularly because I > am taking a different approach than what he had in mind, so I could use some puch back :).
You two never waste my time. ❤️
But it does take a fair bit of brain space to digest all this and give an opinion, and there's lots to do. I hope to try both/all PRs out soon, certainly before the next preview release.
Slightly related: we are in the last two weeks of the 6 month AI credit provided by Anthropic. After this I plan to tap the brakes on AI assistance, at least for a bit, to reflect and digest.
So this week and next, I feel a little bit of pressure to spend my hacking time on my list of tasks where AI would be particularly helpful. (More ideas welcome, by the way.) I know one of those tasks could be "help review the open PRs". I did a little of that, which informed my first response. But of course I don't want to be an AI maxxer.
Right now, the more time I spend doing AI-assisted dev, the more features (tested, high quality features) pour in. I'm getting things I wished for for many years. Also, they start to feel a bit less consequential, less valuable..
All this is very weird, isn't it.
…On Fri, Sep 18, 2026, at 06:37, Arthur Cinader wrote:
*acinader* left a comment (hledgerorg/hledger#2735) <#2735 (comment)>
How can I help? Would you like me to test? Would you like a formal review? Do you want to discuss?
If you want to help me refine #2736 <#2736> you could build it locally and review the DE translation. Follow TRANSLATING.md <https://github.com/acinader/hledger/blob/i18n-poc/doc/TRANSLATING.md>, edit a PO file in Poedit <https://poedit.net/>, and see the result locally.
I think it is ready to go, but I'd like to get a set of eyes on it before we waste Simon's time, partcularly because I am taking a different approach than what he had in mind, so I could use some puch back :).
—
Reply to this email directly, view it on GitHub <#2735?email_source=notifications&email_token=AAACPIBUS6RSIDU4GIUWWET5PVQGBA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNZTGMYTAMJWHE22M4TFMFZW63VKON2WE43DOJUWEZLEUVSXMZLOOSWGM33PORSXEX3DNRUWG2Y#issuecomment-5733101695>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAACPIDAHD2I2Y52RP55KIT5PVQGBAVCNFSNUABDKJSXA33TNF2G64TZHM4TGMBRGQYTIO2JONZXKZJ3GU2DSMBUHA3DSNZSUF3AE>.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS <https://github.com/notifications/mobile/ios/AAACPIGL4B3MXA3MPXBUJUL5PVQGBA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNZTGMYTAMJWHE22M4TFMFZW63VKON2WE43DOJUWEZLEUVSXMZLOOSVGM33PORSXEX3JN5ZQ> and Android <https://github.com/notifications/mobile/android/AAACPIA5YFB7KXZSD6EHY435PVQGBA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNZTGMYTAMJWHE22M4TFMFZW63VKON2WE43DOJUWEZLEUVSXMZLOOSXGM33PORSXEX3BNZSHE33JMQ>. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Simon, I will happily cover your Anthropic subscription when the promotion is over. I will petition them to extend it for you, but if they won't, I'll increase my sponsorship to cover it. Well worth the money. heldger2 is an ideal tool for agents to use for accounting. My codex project uses hledger1.99 to obtain, categorize, and book all of my transactions. I use hledger-web for review and reporting during accounting sessions. It's amazing. I haven't fully fleshed out lot-level tracking, asset allocation, and performance reporting, or what the gap is for hledger-web yet, so there's a lot to do. Along those lines, my follow-on to translations would be to add skills to help a first-time translator use an agent to prepare a translation. #2006 would be another super high value add that I'd like to get to. Working without a coding agent would be like trying to code without online documentation(!), google, or stackoverflow. You could, but why? |
|
I added an attempt to perform inflection of interval names without the need to translate every combination individually. The idea is to query the genus of report names and then to query inflected interval names, accordingly. This will work for some languages, however, in order to account for different word order, I think we also need to change, say, "Income Statemnt" to "{interval} Income Statement" and use text interpolation for constructing localized texts. |
This comment was marked as low quality.
This comment was marked as low quality.
| balancesheetSpec = CompoundBalanceCommandSpec { | ||
| cbcdoc = $(embedFileRelative "Hledger/Cli/Commands/Balancesheet.txt"), | ||
| cbctitle = Msg.BalanceSheet, | ||
| cbctitle = Msg.Noun Msg.BalanceSheet, |
There was a problem hiding this comment.
Two relevant links from the gettext manual
po
msgctxt "balance-sheet interval"
msgid "Monthly"
msgstr "Monatliche"
hs
trc t "balance-sheet interval" "Monthly"
There was a problem hiding this comment.
Would you be interested in implementing a context-based approach in #2736 using cbctitle and cbcintervalcontext or something like that?
For example:
cbctitle = i18n "Balance Sheet"
cbcintervalcontext = "balance-sheet interval"|
On Fri, 18 Sep 2026, Arthur Cinader wrote:
@acinader commented on this pull request.
______________________________________________________________________________________________________________________
In hledger/Hledger/Cli/Commands/Balancesheet.hs:
> @@ -21,7 +21,7 @@ import Hledger.Cli.CompoundBalanceCommand
balancesheetSpec = CompoundBalanceCommandSpec {
cbcdoc = $(embedFileRelative "Hledger/Cli/Commands/Balancesheet.txt"),
- cbctitle = Msg.BalanceSheet,
+ cbctitle = Msg.Noun Msg.BalanceSheet,
Two relevant links from the gettext manual
Context
Context and ambiguities
po
msgctxt "balance-sheet interval"
msgid "Monthly"
msgstr "Monatliche"
hs
trc t "balance-sheet interval" "Monthly"
If we have to translate every interval for every report type, we could as
well translate all combinations of interval and report type.
However, my idea was to reduce the translation work by determining the
genus of the report name and inflect the interval name accordingly. In
German it happens that all report names have feminine genus. So we only
need inflections for one of three genders.
That said, I might turn genders into contexts. This might be more in the
spirit of gettext.
|
|
Just a drive by comment, but special heuristics that work for one or two languages will really limit us as we add more languages.
|
|
Where I'm coming from: I would rather ship a smaller slower-growing number of translations with perfect grammar & spelling, than a large fast-growing number of sloppy translations. I guess that's my inner perfectionist. Also shipping imperfect unfinished translations, or translations with different capabilities, sounds like it would create more maintenance work.
Of course, fast and cheap is probably the better strategy for growth. But I'd like it least to be *possible* to achieve perfect translations when we want to. I feel pretty sure that in general, when you consider how different languages can be, and given our need to present static and dynamic text seamlessly combined, this is going to require custom logic in many places, ie programming.
It's possible, but I don't know if worthwhile/manageable in practice, we could combine multiple techniques.
|
|
On Sat, 19 Sep 2026, Simon Michael wrote:
[10144?s=20&v=4] simonmichael left a comment (hledgerorg/hledger#2735)
Message ID: ***@***.***>
Just a drive by comment, but special heuristics that work for one or two
languages will really limit us as we add more languages.
My approach is no limitation, only an optimization for German and, I
expect, many other languages. It shall prevent the translator from
translating all combinations of "interval" and "report name" individually.
If that does not work for your language, you can choose a fake "gender"
that is specific to each report and then do an individual translation of
the intervals for every single report.
|
|
On Sat, 19 Sep 2026, thielema wrote:
On Sat, 19 Sep 2026, Simon Michael wrote:
> [10144?s=20&v=4] simonmichael left a comment (hledgerorg/hledger#2735)
> Message ID: ***@***.***>
> Just a drive by comment, but special heuristics that work for one or two
> languages will really limit us as we add more languages.
My approach is no limitation, only an optimization for German and, I expect,
many other languages. It shall prevent the translator from translating all
combinations of "interval" and "report name" individually. If that does not
work for your language, you can choose a fake "gender" that is specific to
each report and then do an individual translation of the intervals for every
single report.
In order to make this work in every case however, we need to define a
translation of the universal interval, that is, a text for the case that
there is no interval specification.
|
|
https://www.gnu.org/software/gettext/manual/html_node/Entire-sentences.html Here's my concrete suggestion for a plan we should adopt: For our first translation, let’s defer additional grammar-handling logic and add the Haskell and PO entries needed to make the German translation complete and correct. The guiding principle should be to prefer more translation entries in the PO file over more grammar-handling logic in Haskell. I think if we focus our efforts, we could get a correct, shippable German translation very quickly. We have i18n scaffolding in #2736, including a tag extraction script, documentation, and test coverage. It works right now and is ready for a translator to iterate on the PO file while reviewing the UI. The missing piece is the first l10n, which you already have a good start on, but it will require more Haskell work to accommodate a gendered language. Can you do this work? I'd appreciate it if you could review my PR and share your thoughts from a translator's perspective. I think you'll like it. You could start with the PR README and translation doc. Ask me any questions. In the meantime, I will pull your web-balance-report branch and run it so I can give you feedback. |
"Monthly Balance Sheet" was an interval word plus a report name, joined by a space in the code. One adjective form had to fit every report, and the space could not be dropped. Now each compound report lists its own title per interval, so a translator renders the whole phrase as the language needs, with no grammar logic in Haskell. The German catalog grows from 14 to 44 title entries. English output is unchanged. this should bring hledgerorg@8ddb03f changes into hledgerorg#2736 should bring hledgerorg#2736 upto parity with hledgerorg#2735 AI usage: drafted with Claude Code, reviewed and edited by the author. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"Monthly Balance Sheet" was an interval word plus a report name, joined by a space in the code. One adjective form had to fit every report, and the space could not be dropped. Now each compound report lists its own title per interval, so a translator renders the whole phrase as the language needs, with no grammar logic in Haskell. The German catalog grows from 14 to 44 title entries. English output is unchanged. this should bring hledgerorg@8ddb03f changes into hledgerorg#2736 should bring hledgerorg#2736 upto parity with hledgerorg#2735 AI usage: drafted with Claude Code, reviewed and edited by the author. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Agree. Adding a translation to the distribution adds a real comittment that has the potential to slow down any development that touches the ui. In order to add a locale, we'd have to have some level of confidence that there is a contributor that is repared to own it in the face of changes that require additional translations. |
|
After thinking about it some more, it is probably best to release only i18n, the extraction script, and documentation. We should not contemplate releasing a localized PO file in the near term. A limited release focused on the internationalization (i18n) machinery would let any user copy the template .POT to make their own PO to localize their own hledger. This would be an invitation for potential contributors to open issues where there are translation problems that they can't fix with the current template which would require a code change and a new extraction of the template. If, after some time, a mature locale has worked through the necessary Haskell changes to support localization (l10n), then it could be part of the distribution. How does that sound to you? |
"Monthly Balance Sheet" was an interval word plus a report name, joined by a space in the code. One adjective form had to fit every report, and the space could not be dropped. Now each compound report lists its own title per interval, so a translator renders the whole phrase as the language needs, with no grammar logic in Haskell. The German catalog grows from 14 to 44 title entries. English output is unchanged. this should bring hledgerorg@8ddb03f changes into hledgerorg#2736 should bring hledgerorg#2736 upto parity with hledgerorg#2735 AI usage: drafted with Claude Code, reviewed and edited by the author.
"Monthly Balance Sheet" was an interval word plus a report name, joined by a space in the code. One adjective form had to fit every report, and the space could not be dropped. Now each compound report lists its own title per interval, so a translator renders the whole phrase as the language needs, with no grammar logic in Haskell. The German catalog grows from 14 to 44 title entries. English output is unchanged. this should bring hledgerorg@8ddb03f changes into hledgerorg#2736 should bring hledgerorg#2736 upto parity with hledgerorg#2735 AI usage: drafted with Claude Code, reviewed and edited by the author.
4e35893 to
31c9947
Compare
…y ago" "Biannual" means twice a year; the title of a report with a two-year interval now says "Biennial". And stats no longer says "1 days ago". The interval word is about to become a translation key, and every later change to an English string invalidates its translations, so it is fixed first; the stats wording is fixed while looking at it. AI usage: drafted with Claude Code, reviewed and edited by the author. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G2VXnprjHmXZR8tgWPV3vz
Cli.Message.getGenus, getInflected
This is a very rough draft.
I translate some report texts using
haskell-gettext.haskell-gettextis a pure Haskell implementation ofgettextthat does not rely on a global variable for the text dictionary.I define an enumeration of all translatable texts in
Hledger.Cli.Message.I do not use the original English strings as keys,
because sometimes the same English string needs different treatment.
E.g. I have
AverageandRightAverage, see below.You can run it like so:
Currently the tests will fail because of missing English Catalog.
Problems I found:
Hledger.Cli.Commands.Incomestatementdefine aCompoundBalanceCommandSpecbut at this stage we have noCatalogand cannot translate. Thus I turnedTexttype intoMessage. However,CompoundBalanceCommandSpecis defined inhledger-lib, where theMessagetype is not yet available. Thus I added a type parametermsg. I think the other two already existing type parameters serve the same purpose.--catalog. Currently I loadCatalogincompoundBalanceCommandWithCatalogandbalance. Maybe there is a more central place.ToDo:
*.pofiles to*.mofiles usingmsgfmtin Shake.hsReportOpts.catalog_ :: Maybe Catalog. I prefer to embed the English catalog in the Hledger executable and use this as default, such that we can turnMaybe CatalogintoCatalog.