Format numbers as words
Many contracts included numbers, which are also spelled out in words. IANAL so I can't speak to why this is important, but it is commonplace. I have seen several contracts recently where the number and the words are actually out of sync, which created considerable confusion!
E.g.
"within ten (15) days of the Effective Date"
Which should presumably have been:
"within ten (10) days of the Effective Date"
Describe the solution you'd like Support a formula that can be used to spell a number out as English language words.
Describe alternatives you've considered A TemplateMark formatting instruction to format numbers as words.
Additional context
- https://www.npmjs.com/package/to-words
- https://www.gentrylawgroup.com/writing-out-numbers-in-contracts/
- https://www.quora.com/Why-are-numbers-expressed-in-legal-documents-in-both-numeric-and-written-form
- https://weagree.com/drafting-principles/6-typical-drafting-habits-and-legalese/6-3-numbers-and-formulae/a-best-practice-rules-on-drafting-numbers/
Q: Would we want to support parsing of those (e.g., as an alternative to the digit-based syntax) or would this behave more like an Ergo formula?
My initial instinct was that this should behave like a formula, but then I read: https://weagree.com/drafting-principles/6-typical-drafting-habits-and-legalese/6-3-numbers-and-formulae/a-best-practice-rules-on-drafting-numbers/
Which makes the case for drafting small numbers as words, and occasionally including both the number and the word form. Perhaps we can raise this question to the lawyers in the group?
Some consider it unnecessary and bad form to state the same thing twice. However, imo, it is a fairly common practice and unlikely to go away soon.
Often there are mismatches like this is due to: (1) suggested changes in certain editors that are not persisted in the document, and certain changes are accepted and others are not; or (2) a value is changed multiple times and tracked changes become unwieldy, raising the same issue.
There is no reason the written value and the numerical value should differ.
My $0.02 is that it should be left up to the drafter as to when and how they want to use dual representations of a value (i.e. one form is not mandated), but that an error is raised when parenthesis are used after one representation and the values do not correlate. For example:
10 (ten) is valid.
15 (ten) is invalid.
ten (10) is valid.
fifteen (10) is invalid.
Perhaps this could be a specified type like DateTime?
@peterhunn Thanks for the insights. Very useful.
Perhaps this could be a specified type like
DateTime?
That's an interesting idea. This could be an extension to the format (e.g., WWWW or NNNN for long-worded numbers)
One more question: do you sometimes have only the words but not the corresponding number? (e.g., in the amount of ten thousands dollars.
One more question: do you sometimes have only the words but not the corresponding number? (e.g.,
in the amount of ten thousands dollars.
Yes, some best practices are to use words for small numbers only. The link has some examples.
One more question: do you sometimes have only the words but not the corresponding number? (e.g.,
in the amount of ten thousands dollars.Yes, some best practices are to use words for small numbers only. The link has some examples.
That means very weird (possibly difficult) parsing. Who decides what a small number is? Do we need that feature?
I think we can start with a formula that renders a number as words. I suspect that will solve 90% of the problem... We can then wait and see if additional requirements arrive.
I think we can start with a formula that renders a number as words. I suspect that will solve 90% of the problem... We can then wait and see if additional requirements arrive.
Two questions:
- Do we really need this feature? This does not feel like a priority
- I like @peterhunn 's proposal to do it as a formatting option for the amount. This means you do not have to add this kind of functionality to the Ergo compiler (and down the road support it in WASM, etc) -- at least initially.
-
I frequently run into contracts that spell out numeric amounts in words. I'd guess that 50% of the contracts I see have it somewhere, so it's definitely something people have to manually keep in sync right now. How much it bothers people to do that manually (keeping a
Double/Integer/Longvariable in sync with aStringvariable) I am not sure. -
Not sure I understand this. If it becomes an
asformatting option on the{{variable}}in TemplateMark then I'd expect it to parse as well as draft for consistency. Are you referring to something else?
- I frequently run into contracts that spell out numeric amounts in words. I'd guess that 50% of the contracts I see have it somewhere, so it's definitely something people have to manually keep in sync right now.
- Not sure I understand this. If it becomes an
asformatting option on the{{variable}}in TemplateMark then I'd expect it to parse as well as draft for consistency. Are you referring to something else?
I was thinking the format could make the number itself mandatory. so e.g., WWWW 0,0.00 would be valid but not WWWW so you can always parse from the number and check that it is consistent with the words.
But I could certainly add it to the new Ergo compiler after we've merged it in if we feel this is where it should be.
Discussed during a Tech WG call. This reference is interesting:
https://www.delawarelitigation.com/2019/01/articles/chancery-court-updates/words-prevail-over-conflicting-numbers-in-contract/#:~:text=A%20recent%20Delaware%20Court%20of,that%20is%20inconsistent%20and%20contradictory.
@jeromesimeon Is this issue still available for work.I would like to work as well share my ideas upon this issue.
@jeromesimeon Is this issue still available for work.I would like to work as well share my ideas upon this issue.
Sounds great @Cronus1007
Would be great if there was a library we can use for this?
@jeromesimeon The plan that I intend to follow to resolve this issue :-
- [ ] NPM package to be used this
- [ ] Files where the desired changes need to be done (Will need a little bit of help for this step)
- [ ] Little instance of code to be written
// Require Statement
const { ToWords } = require('to-words');
// Config for package
const toWords = new ToWords({
localeCode: 'en-US',
converterOptions: {
currency: true,
ignoreDecimal: true,
ignoreZeroCurrency: false,
}
let words = toWords.convert(123);
});
@jeromesimeon The plan that I intend to follow to resolve this issue :-
- [ ] NPM package to be used this
- [ ] Files where the desired changes need to be done (Will need a little bit of help for this step)
- [ ] Little instance of code to be written
// Require Statement const { ToWords } = require('to-words'); // Config for package const toWords = new ToWords({ localeCode: 'en-US', converterOptions: { currency: true, ignoreDecimal: true, ignoreZeroCurrency: false, } let words = toWords.convert(123); });
Looks good! One of the challenges we have in AP is that we also parse contract text. Not sure how to make that feature work with this. Maybe @dselman will have some thoughts.
@jeromesimeon Sure lets wait for @dselman inputs and then I shall create a draft pr for maintainers to have a look.
@jeromesimeon Can you plzz refer me the files that parse contract text and shall I start implementing this feature?
@jeromesimeon Can you plzz refer me the files that parse contract text and shall I start implementing this feature?
hi @Cronus1007 The parser is actually located in the markdown-transform project. More specifically the parsing for natural numbers (Integer) is in this place https://github.com/accordproject/markdown-transform/tree/master/packages/markdown-template/lib/plugins/Integer
Yet it still feels like a pretty ambitious thing to try and parse numbers written in English format (I'd be happy to be wrong of course). I would be interested to get further feedback on this from e.g., @dselman @mttrbrts or @peterhunn who created this issue before sending you on this journey :)
[ I believe this is discussion is the reason this specific issue is labelled as "Challenging" ]
@jeromesimeon Okk so first shall I give a mock of the code in here only and then will start implementing this issue.
Reading through a little bit, we might want to offer a "format" for numbers that lets you add an English form. Here is the corresponding part of the documentation for monetary amounts and dates https://docs.accordproject.org/docs/markup-templatemark.html#formatted-variables
Maybe something along those lines would make sense?
Reading through a little bit, we might want to offer a "format" for numbers that lets you add an English form. Here is the corresponding part of the documentation for monetary amounts and dates https://docs.accordproject.org/docs/markup-templatemark.html#formatted-variables
Maybe something along those lines would make sense?
😊 This was, I think, what @peterhunn was suggesting here. I just forgot!
@irmerk @jeromesimeon @dselman @mttrbrts @DianaLease @Michael-Grover @peterhunn @algomaster99 Implementation idea for this since it handles formation of integers
const { ToWords } = require('to-words');
/**
* Creates config Options for to-words package
*/
// This config is just a mock for cuurency but can be handled for percentages,months,days
const toWords = new ToWords({
localeCode: 'en-US',
converterOptions: {
currency: true,
ignoreDecimal: false,
ignoreZeroCurrency: false,
}
});
function draftInteger(value) {
return '(' + toWords.convert(value) + ') ' + value;
}
toWords.convert(value) The required changes to implement this feature.
Few things that we should follow while making this change:-
- [ ] The integer can't be bigger than 10^18.(Overflow Problem)
- [ ] For numbers greater than 1000 like 1234 (my opinion) text displayed (One Thousand) i.e. Representing the Most Significant Digit
- [ ] If the user updated a number the functionality will make the text updated as well.(Can be tested via writing few unit test cases for this)
@dselman Thanks for sharing this document.This could help a lot in formation of guidelines. https://weagree.com/drafting-principles/6-typical-drafting-habits-and-legalese/6-3-numbers-and-formulae/a-best-practice-rules-on-drafting-numbers/
15 (ten)is invalid.fifteen (10)is invalid.Perhaps this could be a specified type like
DateTime?
These cases can't arise with this implementation since if the user changes the value then draftInteger functions gets triggered and inherited use of toWords in the function will make to automatically change the written text as well.
@jeromesimeon The clause will look something like this.This change has only been made for integers not for double, long and Monetary Amount.
