Documention for template authors
This page contains documentation for template authors. Documentation on how to call the Murasaki API is at the start page. Documentation on how to develop in README.md.
Murasaki compiles PUG templates, adding a number of useful helper functions and mixins.
All available helper functions and mixins are listed in the menu to the left.
Example template:
h1 #{winner} vann jämn backhoppning
p #{winner} från #{territory(winner_nation)} vann backhoppningen i #{t(venue)} efter en rafflande slutstrid. Slutpoängen blev #{number(points)} poäng.
p Det återstår nu #{numberPretty(remaining)} #{pl(remaining, "tävling", "tävlingar")} i världscupen den här säsongen.
Example data:
{
winner: "Ryoyu Kobayashi",
winner_nation: "JP",
venue: "Vienna",
points: 266.6,
remaining: 2
}
Generated HTML:
<h1>Ryoyu Kobayashi vann jämn backhoppning</h1>
<p>Ryoyu Kobayashi från Japan vann backhoppningen i Wien efter en rafflande slutstrid. Slutpoängen blev 266,6 poäng.</p>
<p>Det återstår nu två tävlingar i världscupen den här säsongen.</p>
Further reading
- A Pug tutorial, for those already familiar with HTML: www.sitepoint.com/jade-tutorial-for-beginners
- Official Pug documentation (highly technical, for advanced users): www.pugjs.org
Changelog
-
11.2.0
- [NEW]
styleoption toterritory*methods, allowing e.g. both legal and common names.
- [NEW]
-
11.1.3
- [BUG] Init Options class with optionDefaults, making them work everywhere
- [INTERNAL] Cap Node version at 24, as c8 has a bug with Node 25. Only affects testing.
-
11.1.2
- [BUG] Fix PRB in optionDefaults
-
11.1.1
- [INTERNAL] Date list parsers (for e.g.
yearList()) will now raise an error if the list contains null values, to avoid harder to debug errors down the pipe. - [DOC] Various fixes
- [INTERNAL] Date list parsers (for e.g.
-
11.1.0
- [BREAKING] Default for
leveloption is nownull(was 1) - [BREAKING]
list*()methods will try to auto determine level unless explicitly set. - [NEW] All list functions will now try to respect
leveloptions - [INTERNAL] Refactored, more robust list level handling
- [BREAKING] Default for
-
11.0.0
- [MAJOR-BREAKING] We now require an explicit locale to be set when using a territory dependant methods.
To migrate change any
svtosv-SE,sv-AXorsv-FI, etc. Calling these methods without a locale will throw an error - [BREAKING]
interval*()have new behaviour for equal-ish dates.intervalMonth("2025-03-01", "2025-03-03")will now return ”March 2015” - [DATA] CLDR 48
- [NEW]
duration*Short()for abbreviated temporal durations
- [MAJOR-BREAKING] We now require an explicit locale to be set when using a territory dependant methods.
To migrate change any
-
10.10.0
- [NEW]
largeNumberChange(),millionsChange()andbillionsChange() - [NEW]
largeNumberChangeShort(),millionsChangeShort()andbillionsChangeShort()
- [NEW]
-
10.9.0
- [NEW]
largeNumberShort(),millionsShort()andbillionsShort() - [INTERNAL] Remove some unnecessary casting
- [NEW]
-
10.8.0
- [NEW]
text()method, like void but escapes<,>and&.
- [NEW]
-
10.7.1
- [NEW] Add default param support to even more date functions
- [DATA] Add soft hyphen in algorithmic Swedish demonyms
-
10.7.0
- [NEW] Add default param support to more date functions
- [NEW] missing
days*(),monthDays*(),yearMonthDays*()methods - [INTERNAL] remove some duplicated date argument parsing
-
10.6.0
- [NEW]
void()method, to trigger pre- and postprocessing - [REMOVED] Removed support for deprecated
Temporal.PlainDateTimeobjects in time functions. - [INTERNAL] Rewrite timezone handling to folow the latest Temporal proposal
- [DOC]
equalAttype
- [NEW]
-
10.5.0
- [DATA] CLDR 47, see https://cldr.unicode.org/downloads/cldr-47
- [NEW]
dayPeriodgiven a time, return e.g. ”in the evening”
-
10.4.0
- [NEW]
age*()returns an age given a birthdate and a reference date (default.today)
- [NEW]
-
10.3.1
- [DATA] "fi01" as an alias for "ax" in preparation for CLDR 47.
- Tweak territory look-up methods to make them slightly faster.
- Bundle Swedish Words 2.10
-
10.3.0
- [NEW] add
lowerFirst()
- [NEW] add
-
10.2.1
- [BUG] Include locale settings in cache key for method cache
- [BUG] Include optionDefaults in cache key for method cache
- [BUG] Exclude relative date methods from method cache
-
10.2.0
- [BREAKING]
Var().some()andVar().every()will return Var objects, likeVar().map()etc - [DATA] CLDR 46 through cldr 7.7.0
- [BREAKING]
-
10.1.2
- [DOC] Fix currencies namespace error
-
10.1.1
- [NEW] Allow some decimal digits options in currency formatting
- [BUG] Avoid an edge case pass-by-reference bug in options parsing
- [DOC] Move currency methods to its own namespace
- [INTERNAL] Unified currency code parsing
-
10.1.0
- [NEW]
currencyName()andcurrencySymbol() - [NEW]
currency()andcurrencyShort() - [DOC] More number options
- [NEW]
-
10.0.1
- [BUG] Fixed an ugly bug with
changeInteger(-0.5), introduced in 9.4.0 - [DATA] Added more sv-SE demonyms
- [BUG] Fixed an ugly bug with
-
10.0.0
- [BREAKING] Renamed option
precisionHead=>significantDigits - [NEW]: Some methods can now act as getters with a default variable. (This was previously experimentally implemented for some
territoryfunctions). E.g.territoryShortas a shortcut forterritoryShort(DefaulRegionVar) - [NEW] Make any iterable work in list arguments
- [ERRORS] Add error handling for non-valid list arguments
- [INTERNAL] Move basic number formatting to Intl (for non-algorithmic numbering systems only)
- [INTERNAL] Use intl-format-cache from format.js for Intl caching
- [INTERNAL] Partially revert Var changes from 9.2, again monkey-patching array methods.
- [BREAKING] Renamed option
-
9.4.0
- [NEW]
permille*()methods - [NEW]
percentShort*()andpercentLong*()methods for printing a whole text string, e.g. “15 percent”. Long variants use local data. - [NEW]
permilleShort*()andpermilleLong*()methods - [NEW]
changePercentShort*()andchangePermilleShort*() - [NEW]
precisionandprecisionHeadoptions now work inchange*() - [BUG] Fixed an issue where local json data could sometimes be overwritten by defaults while using subkeys
- [INTERNAL] Started migration of numberformatting to ICU Intl. All
change*()method now use Intl. There could be edge cases where behaviour around e.g. rounding and conflicting options has changed.
- [NEW]
-
9.3.0
- [NEW] Add
style: "range"toyearList*()functions, for output like “2019 and 2023-2026” - [NEW] Allow passing partial dates (
"2024"or"2024-02") to some date functions, such asyear(). This used to throw an error. - [DOC] Started adding custom types to doc, to better describe possible inputs
- Style default changed to
"default".standAloneis now an alias fordefaultin date functions. This change should be backwards compatible.
- [NEW] Add
-
9.2.1
- [DOC]
demonym()docstr fix
- [DOC]
-
9.2.0
- [NEW]
demonym(), using local data. Only available forsv - [NEW] Add missing date list methods for completeness:
dateListOr(),dayMonthListOr(),monthYearListOr()andyearListOr(). Note that these methods are deduplicating by design, and need no-Unique-variants. - [BUG] Make caching work with arrays inside Var's, and with Var's inside arrays
- [DOC] Groups
territoryList*()withterritory()methods under “text”. - [INTERNAL] New argument parser for grammatical form, e.g. case, to unify parsing across methods
- [INTERNAL]
Var()will cast primitive Array members to Var on creation, rather than in patched array methods. The following edge case will no longer work:Val([1, 2, 3]).map(v => "x" + v)[0].upper() - [INTERNAL]
Var()will return early when passed a tF Var object
- [NEW]
-
9.1.0
- [NEW]
yearList()method - [INTERNAL] Avoid crashing when trying to cache un-serializable arguments.
- [INTERNAL] Don't try to serialize
t(). We don't know what unholy objects the users might pass in...
- [NEW]
-
9.0.4
- [INTERNAL] Handle undefined arguments creating cache key
- [INTERNAL] Don't cache errors
-
9.0.3
- [INTERNAL] Use normalized cache signature in chained functions
- [INTERNAL] Revert caching on depth > 1
-
9.0.2
- [INTERNAL] Allow Cache to use user-provided cache, falling back to MethodCache
-
9.0.1
- add missing MethodCache doc
- [INTERNAL] Tweak tF initiation
- [INTERNAL] Allow method cache on depths 1 AND 2
-
9.0.0
- [NEW] Experimental support for simple method caching mechanism, using a key/value data store
- [NEW] Exposing a simple in-memory cache class as a dev/fallback cache:
MethodCache - [INTERNAL] Exclude debug method from method decoration
-
8.25.2
- [DATA] sv: Storuman compound form
-
8.25.1
- [BUG] Add grammar files missing in last release
-
8.25.0
- [NEW]
distance*()methods, for “road distances” (e.g. “fem mil”)
- [NEW]
-
8.24.0
- [BUG] Emit readable error messages on invalid input to
territory/dateList*()methods - [BREAKING] Revert 8.23 changes to negative approximations logic, and disable support alltogether. Negative number support had super-weird effects on various edge cases. Negative numbers will now throw an error in all approximate*() methods, as they are not well defined there.
- [BREAKING] largeNumber*() and friends now default to a non-breaking space in e.g. “12 millions”.
- [BUG] Emit readable error messages on invalid input to
-
8.23.0
- [DATA] CLDR v45, see https://cldr.unicode.org/downloads/cldr-45
- [NEW] largeNumber- will try to handle negative numbers
- [BREAKING] Reversed logic for negative approximations: -1010 is now ”more than minus one thousand”
-
8.22.1
- Only treat strings as naked option
-
8.22.0
- [BREAKING] Remove deprecated case option support
-
8.21.3
- [BUG] Avoid overwriting
formwith invalidcasevalues - Don't add empty arrays to allowedOptionValues
- [BUG] Avoid overwriting
-
8.21.2
- [INTERNAL] Run territory hooks for each member in territoryList arguments
-
8.21.1
- [BUG] Fix pbr bug in options alias
- [INTERNAL] Added argument type for region lists to make plugin hooks work as expected
-
8.21.0
- [NEW] Added
adjunctas a territory declination - [NEW]
territoryList(), for lists like ”Mora, Ludvika och Smedjebackens kommuner” - [NEW]
territoryListUnique() - [NEW]
territoryListOr() - [NEW]
territoryListOrUnique() - [DEPRECATION] The
caseoption used interritory*()has been renamed to the more generalform. Case is kept as an alias, but marked as deprecated - [DEPRECATION] Date list method are renamed to align with naming convention. Old names are kept as aliases, but marked as deprecated
listDates()renameddateList()listDayMonths()renameddayMonthList()listMonthYears()renamedmonthYearList()
- [DATA] Added some missing
SEterritoriy variants inen - [DATA] Added
JPterritoriy variants insv, due to inconsitencies in CLDR (for test suits) - [DATA] Added
JPterritoriy variants injafor test suits
- [NEW] Added
-
8.20.1
- Make sure to pass by refrence in
optionsBeforeParseAll
- Make sure to pass by refrence in
-
8.20.0
- Added
optionsBeforeParseAllhook for plugins
- Added
-
8.19.1
- Additional approximate*() finetuning
- Tweaks to
equalAtoption, using dynamic values (e.g.Math.log(1.3) / Math.log(val)for large numbers). - [DOC] Improved docstrings for a lot of number functions
- [DOC] Added missing
approximateMultiplier*()
-
8.19.0
- [BREAKING]
semester()renamedsemesterYear()for consistency - [NEW] Added
semester() - [NEW] Added
approximateInteger*()as an alias forapproximately(X, {decimalDigits: 1}) - Finetuned default values for
precisionin approximate*()` - approximate*() will now try and take
decimalDigitsinto account in pattern selection - [DOC] Fix approximately doc strings
- [DOC] Fix turnOfYear doc strings
- [BREAKING]
-
8.18.0
- [NEW] Added
approximateLargeNumberText()andapproximateLargePretty()variants - [BUG] Fixed a number of bugs in
approximate*()for small numbers - [BUG]
precision: 0.1and similar values are now respected - [BUG] Fixed rounding bugs in
approximateLargeNumber() - [BUG] approximateLargeNumber*() methods now respect
largeNumberLimitdefaults, as they should approximate*()now handles negative numbers like it would positive (even though that rarely makes makes). This made it possible to cleanup handling of some edge cases.- Hard coded defaults for
approximate*()precision option for small values, for more intuitive results.
- [NEW] Added
-
8.17.3
- [DATA] SE-2513 sv case fix.
-
8.17.2
- [DATA] SE-2514 sv case fix.
-
8.17.1
- [BUG] clean up unnecessary postinstall script
-
8.17.0
- [NEW] fraction- takes custom rules in the options (like approximately): {"1/2": "varannan"}
-
8.16.1
- [DATA] Fix Swedish genitive form for 'Strängnäs'
- Doc fixes
-
8.16.0
- [BREAKING] Default value for
denominatoris now"pretty" - [DEV] eslint migrated to version 9 (this is a major update)
- More explicit error messages in some places
- [BREAKING] Default value for
-
8.15.0
- [NEW] Hacky support for
approximateLargeNumber() - [NEW]
quadrimester() - [NEW]
semester() trimesteras alias forquarter- use proper year formatting in
quadrimester()andsemester(). - allow more complex
approximately*()helper functions, to prepare for future refactoring - various doc fixes
- [NEW] Hacky support for
-
8.14.0
- [NEW] Added missing
relativeMonthYear*()methods for consistency, effectively the same as addingmonth()andrelativeYear()together, following locale date patterns. - [NEW] Added
relativeLimitoption torelative*()methods, to force absolut grammar beyond a certain number of years or months (e.g. 'mars i fjol' but 'mars 1998'). See alsosince*()for a somewhat similar family of methods. Can be a number, or a dictionary of unit/number.
- [NEW] Added missing
-
8.13.1
- [BUG] Make sure
approximately*()doesn't crash on invalid options syntax.
- [BUG] Make sure
-
8.13.0
- [BREAKING]
list*()methods now cast members to string if no other formatter is assigned - We now use
String.isWellFormed()for input andString.toWellFormed()for output to ensure strings are well behaved.
- [BREAKING]
-
8.12.1
- [DATA] Swedish compound form of Bjuv is now ”Bjuvs”
-
8.12.0
- [NEW]
daysInMonth()returns, as a number, the number of days in a month
- [NEW]
-
8.11.1
- [DATA] Swedish compound form for Uppland Väsby is now Väsby-
-
8.11.0
- [BREAKING]
title()now handles all Unicode hyphens as word-boundries, so thattitle(SUNDSVALL–HÄRNASÖAND)=> ”Sundsvall–Härnösand”
- [BREAKING]
-
8.10.1
- [BUG]
duration*should not use negative numbers - [BUG]
duration*now handles 0
- [BUG]
-
8.10.0
- [EXPERIMENTAL] Getter aliases for common methods.
.territory*resolves to.territory*(region). This feature might go away in future releases if it has unwanted sideeffects. If it works, it will probably be moved to a NW-verse plugin.
- [EXPERIMENTAL] Getter aliases for common methods.
-
8.9.0
- [NEW]
denominatorhas a special valuepretty, that may in the future be the default. It will prefer a predefined subset of fractions.
- [NEW]
-
8.8.0
- [BREAKING] Requires NodeJS >=20 (up from 16!) From now on we will be on latest LTS Node versions, as we are no longer stuck with older environs in the robotwriters.
- [BREAKING] Using
list*()on an empty iterable will now throw an error, to reduce the risk of template errors. - [BREAKING] All
duration*()methods now have non breaking spaces by default - [NEW] Added
durationFromMinutes*(). - [NEW]
durationFrom()will now handle fractions, so that you can pass e.g.{hours: 2.3, minuter: 12} - [NEW] Added
day*()for day of month only - [NEW]
listDates(),listDayMonths(),listMonthYears()methods - [NEW]
list*()now has aformattersoption, taking formatters for list parts such like{default: day, start: dayMonth}, for advanced usecases where a simple.map()won't do. - [NEW] New argument type:
dateList, used bylistDate()etc. Can be any iterable, that will be converted to an array ofdate - [NEW] Added
dayMonthPretty()for completeness - [BUG] Fixed unwanted zero padding in date formatting in some edge cases
-
8.7.2
- [DATA] Swedish compound form for Östra Göinge is now Göinge-
-
8.7.1
- [BUG] Fixed single digit time fragment parsing
-
8.7.0
- [NEW]
approximateMultiplier()methods - [NEW]
timeinput can now be hour fragments or integers, e.g. 19 (treated as "19:00")
- [NEW]
-
8.6.1
- [BUG] Fix season bug affecting only(!) August 31
-
8.6.0
- [DATA] CLDR v.44, see https://cldr.unicode.org/index/downloads/cldr-44
- [NEW]
variantoption toseason() - [NEW]
yearShort() - [NEW]
turnOfYear()describes the closest year-end, e.g. “2012/13” - [NEW]
seasonYear(). Note that tha default variant may be different from theseason()default, e.g. in Swedish: “vinter”, but “vintern 2022/23” - Unified variants parsing
-
8.5.1
- [BUG] Fixed off-by-one bug in
season()
- [BUG] Fixed off-by-one bug in
-
8.5.0
- [NEW] Missing
approximatelyText/Pretty()added
- [NEW] Missing
-
8.4.0
- [BREAKING]
approximately()now works with small numbers and decimal places. This may break previous assumtions about smaller numbers always being untouched.
- [BREAKING]
-
8.3.1
- [BUG] Fixed numberparsing to handle all zeroes as positive zeroes, like the docs say we should.
-
8.3.0
- [NEW] Added missing
dateShort(),sinceShort(),sinceMonthShort()
- [NEW] Added missing
-
8.2.1
- [BUG]
.format()now works as it should with incomplete argument lists and gaps in placeholder enumeration.
- [BUG]
-
8.2.0
- [NEW]
smallestUnitoptions toduration*() - [NEW]
durationText()anddurationPretty() - [NEW] Duration methods for precalculated time spans:
durationFromSeconds(),durationFromSecondsText(),durationFromSecondsPretty(),durationFrom(),durationFromText(),durationFromPretty()
- [NEW]
-
8.1.0
- [BREAKING]
*Pretty()methods will print any decimal numbers with digits - [NEW] Added missing
millionsText(),billionsText(),millionsPretty(), andbillionsPretty() - [NEW] Added
approximateMillions*()andapproximateBillions*() - [NEW]
format()now works with output from other tF methods - [NEW] We now allow method specific, non-standard options
- [NEW]
multiplier*()for phrases like ”twice as ...” - [NEW]
dayMonthText()for completeness. This means slightly different levels of spellout in different languages, eg ”tredje november” (sv), ”一月三日” (ja), ”January 3rd” (en), etc - [NEW]
calendaroption to date methods - [NEW]
approximately()moved from Swedish plugin to core - [BUG] Respect options in date formatting in various date methods (for e.g. number formatting, calendar, ...)
- [BUG] Fixed broken parameter parsing in
season() - [BUG] Fixed pass-by-reference bug that could sometimes cause options to leak between method calls.
- [DOC] From now on, we will not copy options documentation around between methods, unless their behaviour is non-default
- [BREAKING]
-
8.0.1
- [BUG] Make
Varvocab work in chains
- [BUG] Make
-
8.0.0
- [NEW] EXPERIMENTAL support for Var-assigned vocab, to allow things like
plural(Horses)=> “hästar” - [NEW]
optionsBeforeParsefor plugins. Used byswedish-wordsto find gender, e.gnumberText(Horses)=> en”
- [NEW] EXPERIMENTAL support for Var-assigned vocab, to allow things like
-
7.1.2
- Revert to using require for loading local data, for better caching
-
7.1.1
- Swedish locative preposition för Lidingö changed from “i” to “på”
-
7.1.0
- [NEW]
fractionParts()will return a diff value as a fourth slot - [NEW]
quarternumber()for plain numerical quarter.
- [NEW]
-
7.0.5
- [BUG] Fixed broken spellout of very small fractions in Swedish (tiotusendel)
-
7.0.4
- [DATA] Upstream fix to handle more complex RBNF patterns (for e.g. much improved Russian support).
- Replaced nyc with c8 (using native V8 coverage, available since NodeJS 12) for test coverage reports.
-
7.0.3
- [BUG] Minor updates to cardinal variant parsing in
bearing*(), making e.g.bearingPrimary(-30, {variant: "norr"})(sv) work as intended (producing ”nordväst”) - Minor updates to date/time parsing
- [BUG] Minor updates to cardinal variant parsing in
-
7.0.2
- [BUG] Make non-ascii latin characters work in territory codes
- [DEV] Bundle Swedish plugin @ 2+
-
7.0.1
- [BUG] Fixed broken import of local data when used as ESM module
-
7.0.0
- [BREAKING] textFunction is now an ESM module! Use
import textFunctions from "textFunctions"to import - [BUG] Fixed error in
changeIntegerdecorators, causing argument parsing to fail
- [BREAKING] textFunction is now an ESM module! Use
-
6.9.0
- [BREAKING] Do not allow undefined arguments to be passed in. This prevents misspelled variable names in Pug templates from going undetected.
date()anddate(CurrentDate)both works, butdate(CurrentDtae)should now give an error. - [DATA] CLDR @ v43: https://cldr.unicode.org/index/downloads/cldr-43
- [BREAKING] Do not allow undefined arguments to be passed in. This prevents misspelled variable names in Pug templates from going undetected.
-
6.8.2
- [BUG] Large ordinals are now formated:
1 234:e, etc. - [DATA] Added Swedish “landskap” (historical provinces), using codes from geneology journal Svenska Antavlor.
- [DATA] Added landskap as a new territory type (
se-4x, not in OSM) - Added more flexibility to territory type rules, by allowing regexes
- [BUG] Large ordinals are now formated:
-
6.8.1
- [BUG] Make Var type variables work in
plural()
- [BUG] Make Var type variables work in
-
6.8.0
- [NEW]
territoryType()andterritoryTypeGeneric()added
- [NEW]
-
6.7.0
- [NEW]
upperFirst()will make the first letter upper-case, without touching any other letters (pre 6.6 behaviour ofcapital()).
- [NEW]
-
6.6.0
- [BREAKING]
capital()will make the tail lower-case, for consistency with Python's.capitalize(), our own.title(), and with virtually every other equivalent (and because that's the most common use case). capital()no longer touches the first letter if it is already upper case. In some edge caselower().capital()and.capital()might now produce different results.
- [BREAKING]
-
6.5.0
- [BREAKING] Optional
datetype arguments will default totodayfor consistency - [BREAKING]
todaynow uses the user assigned timezone (default: UTC)
- [BREAKING] Optional
-
6.4.0
- [BREAKING] Un-registered options will be available to all methods, to make it easier to write plugins
- [BREAKING]
todayandnoware now tF objects to allow chaining, likenow.addDays(12).month() - [DOC]
nowgrouped withtimes todayis now a getter, likenowfor consistency, and to avoid caching issues.- Unified parsing of chained values
-
6.3.1
- [DOC] Fixed JSDoc syntax error
-
6.3.0
- [NEW]
decameronMonth()anddecameronMonthYear()for producing phrases like ”end of May”
- [NEW]
-
6.2.2
- [BUG] argument parsers didn't have access to the tF object. Now they do, which should fix
timeHM[S]errors in the swedish-words plugin.
- [BUG] argument parsers didn't have access to the tF object. Now they do, which should fix
-
6.2.1
- [DATA] Added some missing sv bearing() forms.
-
6.2.0
- [BREAKING] Second argument to
bearing()is now required, to allow for unified options parsing. - [NEW] Added
bearingCardinal(),bearingPrimary()andbearingSecondary(). - [NEW] New option:
variant. Similar to style, but allows any value and allows selecting by both value and key. Used inbearing*(). - [BUG] Fixed overflow error in
bearing()affecting negative numbers near north
- [BREAKING] Second argument to
-
6.1.1
- [DOC] Docdash upgraded. It's now easier to find options and properties in the docs
- [BUG]
precisionworks as expected when combined with decimal digits precisionparsing moved from options to _number, making unparsed number visible for methods. This allowsapproximately()from swedish-words plugin to function will custom precisions
-
6.1.0
- [NEW]
bearing()converts degrees to compass courses (e.g. “northeast”) - [DATA] CLDR@v42, see https://cldr.unicode.org/index/downloads/cldr-42
- [NEW]
-
6.0.1
- [BUG]
add*()time methods now return UTC timestamps, as tF datetime strings cannot have timezone data (yet), and we want to avoid timezone errors in chaining.
- [BUG]
-
6.0.0
- [BREAKING] tzOffset options can no longer be combined with timestamps with time offsets (e.g.
19:55:14.000+01:00), as this did not make much sense anyway. There should be very little need for the tzOffset option at all, now that time functions are timezone aware. - [BREAKING] Both timepoints are now required in
duration(time2 no longer defaults to current time, as comparing to the time when a text was rendered made little sense, and this also made options parsing harder) - [NEW]
duration()can now construct strings with number of days. - [NEW]
duration()now takes options for e.g. number formatting. - [NEW] New option
largestUnitused induration(), to let template authors chose between “1 day and 2 hours”, and “26 hours”. - [NEW] textfunctions is now timezones-aware (we previously assumed UTC everywhere), and can be iniitiated with a timezone where texts are assumed to be consumed. We are using the new ES Temporal API, with a polyfill included.
- [NEW] Time methods accept Temporal objects, as well as Date objects, and date/time-parsable strings.
- [NEW]
add*()methods for times, in analogy withaddDays().
- [BREAKING] tzOffset options can no longer be combined with timestamps with time offsets (e.g.
-
5.10.2
- [DATA] More grammar fixes for Swedish and Danish municipality names in Swedish and English.
-
5.10.1
- [DATA] Fixed some broken genitive forms for Swedish long form municipality names.
-
5.10.0
- [BREAKING]
percent*(),change*()andsign()now use a new input parser,numberStrict, meaning that they will no longer accept iterables. This is to reduce errors due to bad data, as e.g. percentages of the length of an array doesn't make much sense anyway. - [NEW] list methods now have the
glueoption, to use custom binding words:list(["A", "B", "C"], {glue: "respektive"}) - [NEW]
dayMonthShort()added for consistency - [NEW]
yearMonthsPretty()added for consistency - [NEW]
changePercent()andchangePercentInteger()added for consistency - [NEW]
listOrUnique()andlistUnique()will handle de-duplication in a uniform way. This can otherwise be tricky, as all variables passed around are complex objects. - [NEW] Variable types are now included in parser related error messages, so that the end-user can differentiate between
[12]and12.
- [BREAKING]
-
5.9.4
- [BUG] Fixed rounding error in some edge cases with
integerPretty()and related methods.
- [BUG] Fixed rounding error in some edge cases with
-
5.9.3
- [DATA] Correct locative compound form for minimalDistinct: Uppsala län
-
5.9.2
- [BUG] Fix off-by-one error in named (grouped) footnotes
-
5.9.1
- [BUG] Fix bug in named (grouped) footnotes, causing numbers to be displayed NaN
-
5.9.0
- [NEW] Support for named (grouped) footnotes (Wikipedia style).
- [DATA] Fixed some broken genitive forms for long Swedish municipality names.
-
5.8.0
- [NEW]
season()method describing primary seasons by location (e.g. “spring”) - [BREAKING] default beaviour of
change()is now to write"±0". Note that this affects onlychange(), notsign(). - [DEV] swedish-words at @1.7.5
- [NEW]
-
5.7.3
- [BUG] Fixed side effects of subsequent use of
list()with thelevelparameter
- [BUG] Fixed side effects of subsequent use of
-
5.7.2
- [NEW] Added level option for use in e.g. nested lists (where a different separator might be preferred)
- [BUG] Options are now passed on to helper functions used in formatting time durations, as it should be.
-
5.7.1
- [DATA] CLDR @ v41: https://cldr.unicode.org/index/downloads/cldr-41
- [DEV] swedish-words included @1.7.4
-
5.7.0
- [BREAKING]
largeNumber*(),millions()andbillions()will now use non-breaking spaces - [DATA] Added some missing compound and locative forms for
territoryDistinct()(sv)
- [BREAKING]
-
5.6.0
- [NEW] added missing
intervalDayMonth()
- [NEW] added missing
-
5.5.0
- [BREAKING] added two different .assign() methods:
assign()andassignVar(), where only the second casts input to Var, reverting behavior of assign to that of - [BUG] Correct Swedish name for Norrtälje kommun
- Add .slice() support to Var arrays
- [BREAKING] added two different .assign() methods:
-
5.4.0
- [NEW]
breakoption. Setting {break: "neverBreak"} will replace characters that usually break text in HTML with non-breaking variants (e.g. space -> non-breaking space). Useful forlargeNumber(), etc - [BUG] Fix leaking options bug in chains
- All methods now accept options argument(s). This gives plugins full freedom to accept extra options. Exception:
t(), för backwards compatibility - Added post processing framework
- [NEW]
-
5.3.4
- [BUG] Fixed integer parsing bug
-
5.3.3
- Various fixes for Array type Var() variables
-
5.3.2
- [BUG] Make list parsing with
keyoption work when usingassign()
- [BUG] Make list parsing with
-
5.3.1
- [BUG] Fix bug where first level null values caused assign to crash
- Allow plugins to specify what languages they are allowed to work on.
-
5.3.0
- [NEW] Make
.map()and.filter()methods available on Array typeVar()variables. Things likeList.map(x => x.name).list()are now possible, as well asList.map(x => x.name)[0].upper() - [BREAKING] Cast data to
Varvariables when usingassign(). - [BREAKING] Ignore numeric input to options, to allow all methods to be used in ES
Array.map()calls. (In the future, all Var lists should have a custom map method instead.)
- [NEW] Make
-
5.2.0
- Add argumentsBeforeParse hook, to support plugin swedish-words@1.5.0
- Made territory a special input type, to centralise variable parsing, and allow plugins to add support to other territory keys.
-
5.1.1
- Fixed bug with hook calls when options are missing
-
5.1.0
- [NEW] Added
resultAfterFunctionCallhook for modifying the output from built-in methods. - [NEW] Support swedish-words@1.4+ (with
namedDay()and{style: 'article'})
- [NEW] Added
-
5.0.2
- Added missing node dep.
-
5.0.1
- Fixed packaging issues in @newsworthy/swedish-words
-
5.0.0
- This major update adds plugin support, and moves existing Swedish dictionary functionality to a new plugin: @newsworthy/swedish-words, making textfunctions truly language-agnostic again, and also simplifying word list installation and maintenance a lot.
- [NEW] Added
argumentsBeforeFunctionCallhook, to allow plugins to modify function arguments - [BREAKING] Requires NodeJS >= 16.0
- [BREAKING] Removed
gender(), as out of scope for this project - [BREAKING] Moved
form()to plugin @newsworthy/swedish-words - [BREAKING] Moved
numberOf*()to plugin @newsworthy/swedish-words - [BREAKING] Moved dictionary support in
plural()to plugin @newsworthy/swedish-words - [BREAKING]
plural()with Swedish dictionary support will accept ambiguities, if the resulting output is non-ambigous, e.g.plural(2, "vind")(as both lemmas will have the same plural forms) {@newsworthy/swedish-words} - [BREAKING]
plural()with Swedish dictionary support will now try to break up noun phrase compounds, makingplural(2, "förortskommun")work {@newsworthy/swedish-words} - [BREAKING]
form()with Swedish dictionary support will now try to break up noun phrase compounds {@newsworthy/swedish-words} - [BREAKING]
numberOf*()with Swedish dictionary support will now try to break up noun phrase compounds {@newsworthy/swedish-words} - [BREAKING] All methods with Swedish dictionary support will now try to parse multi-word noun phrases, like "varuproducerande och besöksnäringskommuner" {@newsworthy/swedish-words}
- [NEW]
form()usessgandplfor numerus (or alternatively cldrone/other). We will start usingsg/plin the dictionaries, as that's what Saldo uses at the source, butone/otherwill be kept as aliases for backwards compatibility. {@newsworthy/swedish-words} - [NEW]
numberOf*()now follows the requested word's declinations, so thatnumberOf(x, "kommuns")=> '15 kommuners' {@newsworthy/swedish-words} - [NEW] Return type can be toggled with
returnVaroption (defaults totrue). If you ever want to use this lib outside templating engines (e.g. for chart production in the robotwriter), set this to false! - [NEW]
list*()now has an extradecompoundoption when used with Swedish dictionary support, so thatlist(["skönhetsbranschen", "hälsobranschen"], "decompound")becomes 'skönhets- och hälsobranschen' {@newsworthy/swedish-words} - Refactored options system
-
4.6.0
- [DATA] Added extra Swedish territory data for nations
- [EXPERIMENTAL]
form()will now use its input to select a form, in case of ambiguity:form("kommuner", "def")=> 'kommunerna'
-
4.5.0
- Add
changeInteger()
- Add
-
4.4.5
- [DATA] Treat Gotland municipality and county as equal entities with regards to minimalDistinct name forms.
-
4.4.4
- [BUG] Fix gender errors in some methods (numberOfText, etc). These methods were not synced with the latest dictionary format.
-
4.4.3
- [BUG] Fix plural handling bug in largeNumber*()
- [BUG] Another upstream fix for the new CLDR plural syntax (node-cldr is now at 7.0.0). French plurals should now be better behaved.
-
4.4.2
- [BUG] Fix #50, where precision would not have the right behaviour for small floats.
- [BUG] Upstream fix for new plural syntax in CLDR 39, fixing issues with plurals in some languages.
-
4.4.1
- [BUG] Fix input parsing in largeNumberText and largeNumberPretty
- [BUG] Enable missing precision in integer methods
-
4.4.0
- [BREAKING] Var variables now have the length property of their contained value
- [BREAKING] largeNumber- methods will now only parse numbers above largeNumberLimit, a language specific limit.
- [BREAKING] largeNumber- methods will now parse inputs as float (previously integer)!
- [NEW] Precision option: number(9876, { precision: 1000 }) => ”10,000”
- [NEW] largeNumberText no longer requires local grammar rules. While not always perfect, you will now have a reasonable default behaviour for most languages
- [DATA] changed minimal distinct form for se-09 to “Gotland” (was “Gotlands län”)
- Remove unused (and inconsistent) parsing logic from
integer()
-
4.3.0
- [NEW] Add generative grammar rules for territories. These will allow automatic construction of some grammatical cases, making constructs like
territory(xx, "locative")more useful. - [DATA] Update CLDR data to v.39, see: http://cldr.unicode.org/index/downloads/cldr-39
- [BUG] Fix #46, where nesting date/time methods would sometimes not work.
- [NEW] Add generative grammar rules for territories. These will allow automatic construction of some grammatical cases, making constructs like
-
4.2.4
- [BUG] Don't allow null values in method arguments
- [BUG] Fix #41, where parsing of numeric arguments failed in nested method calls
-
4.2.3
- [BUG]
percent*Text/Pretty()will now use the correct gender for percentages
- [BUG]
-
4.2.2
- [DATA] Add missing short form for SE-1440
- [DATA] Add territoryDistinct form for Swedish municipalities
- [BUG] Make territoryDistinct fallback work for local data
-
4.2.1
- [BUG] Fix handling of nested function calls in plural()
-
4.2.0
- [NEW] Add
percentIntegerText()andpercentIntegerPretty() - [BUG] Var type variables now have access to all their value type's methods and properties, so that
upper("Bass").replace("SS", "ß")works as one would expect.
- [NEW] Add
-
4.1.2
- Make nested function calls work in template engines again, after being broken in 4.0.0
-
4.1.1
- Revert dictionary path test introduced in 4.0.0, as it failed on some file systems (Heroku)
-
4.1.0
- [BREAKING] Default denominator option is lowered 5, to avoid overly complex fractions.
- [BREAKING] Avoid 0 as a numerator unless forced in fraction*() methods
- [NEW]
fractionText()takes astyleoptions, for selecting special style forms.fractionText(0.5, "noun")will return 'hälften' in Swedish - [NEW] Added more grammatical cases, to be used in CLDR 39+ (adessive, allative, and many others).
- [DATA] More grammatical forms added for Nordic municipalities in local territory database.
- [BUG] Avoid crashing on very small fractions in fraction*() methods
-
4.0.0
- [NEW] Added a
Var()factory method to create chainable variables:let a = Var(12); a.numberPretty().upper() - [NEW] Dictionaries can now contain homonyms. (All dictionary methods are still experimental!)
- [BREAKING] All texts are now returned as a special object that allows chaining, removing the need for tampering with any global prototypes (this should make all features available in virtual sandboxes, and thus make it possible to expose the full library publicly through robotwriters like Murasaki). Returned variables have their
toString()andvalueOf()methods set to return the actual value. In a typical template engine, like Pug, variables are always cast to strings, meaning that the behavior should not change. However, it's likely that there will be some edge cases where e.g. chained methods now behave differently (e.g. raise an error in a different place in the chain.) See README - [BREAKING] If a grammatical case is missing, we will now fall back to nominative.
- [BREAKING] All dictionary methods can now use any word form as their starting point (like
plural() already did), allowing for easy access to homonymic lemmas. This affectscase(),numberOf*(),gender(), andform() - [BREAKING] Dictionary methods will now throw an error on ambiguous input, like
plural(n, "bok"). - [BREAKING] Dictionaries are now required to use CLDR grammatical number classes (one, two, many, other, etc). This paves the way for dictionaries in any language, not just Swedish.
- [BREAKING]
plural()andnumberOf()will immediately crash on words that do not have all numeral inflections available in the current language. A word like Swedish “kalsingar” is no longer allowed as the single argument toplural(). Use e.g.plural(underwear, "kalsipp", "kalsingar")instead. - [BREAKING] We will throw an error on setup if dictionary path is not found, closing #34
- [DATA] Changed Swedish compound form for Södermanland from Södermanlands- to Sörmlands-
- [DATA] Nordic municipalities added, as a local complement to the CLDR territories. These are fetched from WikiData, using national municipality codes (P1168 for Denmark, P1203 for Finland, P2504 for Norway, and P525 for Sweden) or local names (for Iceland and the Faroe Islands).
- [DATA] Many Nordic municipalities and counties now have locative forms in Swedish, adding the right preposition (”i Stockholm, ”på Gotland”).
- [DATA] Many Nordic municipalities and counties now have compund forms in Swedish:
territory("se2080", { compound }) + "borna"=> ”Faluborna” - [BUG] Fixed some validation issues in
form() - [BUG] Chaining no longer pollutes global protoypes, closing #27 and partly #26.
- [NEW/INTERNAL] Semi-public property
_pluralClassescontains a list of all grammatical numbers in the current language (using CLDR names) - [DEPRECATION] Dictionaries should now use CLDR gender class names (neuter, reale, etc), to allow for dictionaries in any language. Support for the old names from the Swedish dictionary is deprecated and will be removed.
- [NEW] Added a
-
3.4.1
- [BUG] Use short fallback for
territoryDistinct()
- [BUG] Use short fallback for
-
3.4.0
- [NEW]
territoryDistinct()will display the shortest non ambiguous territory name.
- [NEW]
-
3.3.1
- [BUG] Add missing data, to make
quarterText()work. Forgot to check in a file in
- [BUG] Add missing data, to make
-
3.3.0
- [NEW]
quarter*(),quarterYear*()andrelativeQuarter*()methods. - [NEW] Add
relativeWeekdayText()andrelativeWeekdayPretty(), for consistency. - Various doc fixes.
- [NEW]
-
3.2.1
- [DATA] There is now a special compound “case” for some territories, for constructs like the Swedish
${ territoryShort("se-20", "compound") }flygplatserna=> 'Dalaflygplatserna' (cmp.${ territoryShort("se-20" ") } flygplatser=> 'Dalarnas flygplatser') - [BUG] Fix broken test (test data was missing)
- [DATA] There is now a special compound “case” for some territories, for constructs like the Swedish
-
3.2.0
- [BREAKING]
title()now treats dashes (-) as word boundaries. - [BREAKING] EXPERIMENTAL dictionary support in
plural(). When given fewer words than there are plural classes in the language, we will now try and find the first word given in the dictionary, and fetch plural forms from there. This is obviously not fool-proof (there are homonyms with different declinations, for instance). Older dictionaries will no longer work!
- [BREAKING]
-
3.1.0
- [NEW] Add
percentInteger(), for completeness and consistency - [DATA] More grammar rules for largeNumber*
- [BUG] Chaining now works the same way for any return type, as stated in the docs.
- [NEW] Add
-
3.0.1
- [BUG] Make
genderoption work as intended fornumberOf*():numberOfText(1, "apelsin", "neuter")to have ”ett apelsin” (default ”en apelsin”) - Better dictionary cache error handling
- Minor doc fixes
- [BUG] Make
-
3.0.0
- [BREAKING]
translationsis now a regular options object (see README for a migration guide). - [BREAKING] Introducing ”naked” options:
number(1, "neuter")fornumber(1, {gender: "neuter"})andnumber(1, forceDecimalDigits)fornumber(1, {forceDecimalDigits})/number(1, {forceDecimalDigits: true}) - [BREAKING] Extra trailing arguments will be treated as options, making it possible to use multiple naked arguments, like
numberPretty(x, "reale", "arab"). - [BREAKING] Removed long deprecated method aliases
fractionShort()(usefraction()instead) and_format()(useformat()instead). - [BREAKING] Removed html debug markup in debug mode. This implementation was complex and buggy, and made some unsound assumptions about the end-implementation. Furthermore, markup is not really the scope of TF anyway. Markup debugging should be the job of a “robot writer”/template engine.
- [BREAKING] Required Node >= 14.0, to allow using new V8 features (like optional chaining etc)
- [NEW] Every standard method is now chainable. While chains like
number(x).upper()might look nonsensical, they could be perfectly valid in some numbering systems (like Roman numerals!). Allowing chaining across the board makes the code easier to maintain, while removing unnecessary assumptions about languages. - [NEW] The
caseoption has some shorthand aliases, like"gen"for"genitive" - [BUG] Fix an ugly bug that caused assigned context variables to sometimes leak from one method chain to another.
- [BUG] Method chains no longer fails on empty string output (that can sometimes be a valid output!)
assign()no longer rejects key collisions in user data, when supplying multiple data objects- ICU feature detection was removed as Node versions without ICU are no longer supported anyway
.nowno longer marked as experimental
- [BREAKING]
-
2.21.0
- [NEW]
caseoption for grammatical case interritory(). - [NEW]
territoryShort()for short variants (e.g. Hokkaido for Hokkaido prefecture). Limited coverage (this data is scraped from WikiData)
- [NEW]
-
2.20.0
- [DATA] Update CLDR to release 38, see http://cldr.unicode.org/index/downloads/cldr-38
- [NEW]
ordinalAdverb()behavior has changed for consistency with other numerical methods. UseordinalAdverb()for numerical output andordinalAdverbText()for textual output. Deprecation warning andfuture$ordinalAdverb()method have been removed. - [NEW] Add
relativeMonth*methods. - [NEW] Add
relativeWeek*methods. - [NEW] Add
relativeDay*methods. - [NEW]: Add relativeWeekday() method. Note that support for grammatical case is still very much WIP in CLDR, making this method somewhat limited in e.g. Finnish.
- [NEW] Add
weekNumber()for localised week numbers. Note that these can differ from ISO week numbers normally seen in computational contexts! - [NEW]
.localeTerritoryproperty will return the territory best matching the current locale; Either using explicitly stated locale tag, or using the default territories for the given language. This property is used internally to find the right week numbering algorithm. - Upstream fixes in node-cldr lib, to fix parsing errors in supplemental data.
- Options parsing is a bit less strict, and options can now be casted to a different type.
-
2.19.1
- [BUG] Fix #23, a bug affecting time input.
-
2.19.0
- [NEW]
relativeYear*()for phrases like ”last year”, ”this year”, etc. - [BUG] Fix rounding error bug in
duration(), that in some edge cases could cause weird output like ”1 hour and 60 minutes” - Methods working on numbers will now use the size of a set or map, just like they already did with arrays and objects, for consistency.
- Refactored argument parsing in preparation for a planned, bigger update. If you depend on parsing error messages, please note that some error messages shown on invalid input have changed.
- [NEW]
-
2.18.0
- [BREAKING] Support for grammatical gender in dictionary data. Test implementation in
numberOf*(). Older dictionaries will no longer work! - [NEW]
gender()method to look up the gender of a dictionary word - Various error handling related to dictionaries and their methods.
- [BREAKING] Support for grammatical gender in dictionary data. Test implementation in
-
2.17.2
- [BUG] Fix #22, where methods working on integers would parse input differently from other methods.
- [TEST] Use strict comparisons for all method tests.
-
2.17.1
- [DATA] Update CLDR to release 37, see http://cldr.unicode.org/index/downloads/cldr-37
- [DATA] Added a local override for Swedish, making “Belarus” replace “Vitryssland” for
'by', as this is now the preferred term among Swedish news media in both Sweden and Finland. - [BUG] Fix #20, and some related issues with decimal numbers in
numberOf*() - [DOC] Fix duplicated options in docs.
-
2.17.0
- [BREAKING] Integer input will now be rounded, if given as a float. This affects a number of methods, e.g.
ordinal*() - [NEW] Experimental
form()method to find a declination of a word - [NEW] Experimental
numberOf*()methods - [NEW] New numbering system
diak, for old Maldivian Dhives Akuru numbers, added with Unicode 13. - [BUG] Fixes a bug in
duration()where “1 minute and 0 seconds” was sometimes printed out, rather than “1 minute”. - [BUG] Upstream fix for a bug where
ordinal*()methods used Latin digits even for scripts with non-latin defaults. duration()andtime*()methods no longer marked as experimental- Cldr updated to 63.1, for e.g. Unicode 13
- [BREAKING] Integer input will now be rounded, if given as a float. This affects a number of methods, e.g.
-
2.16.2
- All time methods now parse timezone input correctly, and defaults to UTC, to make sure all servers handle ambiguous timestamps the same way.
- add
tzOffsetoption, for setting a time zone (in minutes).new Date().getTimezoneOffset()will give you the current local offset.
-
2.16.1
nownow contains the current timestamp (as the name would imply).
-
2.16.0
- [BREAKING] We now require NodeJS >= 13.0
- [NEW] Official recommendation: Use PascalCase or UPPER_CASE for data variables when sharing namespace with textFunctions methods, as textFunctions promises to only ever use lowerCamelCase for methods, properties and constants.
- [NEW] Experimental date/time methods and properties added:
now,duration(),timeHMS(),timeHM()andtimeH(). Everything about those may change, including their names! - [NEW] Added
styleoption to show how e.g. a month name is intended to be used:standAloneorformat(the latter for constructing e.g. a date string). - [BUG] Fixed a month name bug affecting Finnish, Catalan and possibly others, where the wrong month name style was used in full dates.
-
2.15.1
capital()now works for non-BMP characters, such as'𐑀'. Great news for anyone using Medieval Hungarian, for instance. :)- Fixed a bug where
capital()andtitle()crashed on empty input.
-
2.15.0
- Added methods
future$ordinalAdverb(),ordinalAdverbText()andordinalAdverbPretty() - Marked
ordinalAdverb()as deprecated; to be replaced byfuture$ordinalAdverb()at some point - A number of bug fixes in deprecated
ordinalAdverb.
- Added methods
-
2.14.2
- Upstreams bug fix, that addresses several bugs with decimal digits in
*Textmethods. See https://github.com/papandreou/node-cldr/issues/102
- Upstreams bug fix, that addresses several bugs with decimal digits in
-
2.14.1
- Fix documentation for
optionDefaultsproperty.
- Fix documentation for
-
2.14.0
- Allow overriding defaults through the
textfunctions.optionDefaultsobject. SettingoptionDefaults.decimalDigits = 4will make four decimal digits the default for all numeric methods. - *Text methods will now round, not truncate numbers, as one would expect, and in line with other methods.
- Allow overriding defaults through the
-
2.13.2
- Make
*Pretty-methods work for negative numbers. - Date-interval methods now use absolute numbers, because “minus eight years” doesn't make much sense.
- Minor documentation fixes
- Make
-
2.13.1
- Upgrade Cldr dependency with bug fix for packaging issue, causing installation to fail in some environments.
- Add narrow non breaking space (
nnbsp) support tochar(). plural()now works on sets and maps, just like it already did on arrays och objects:let s = new Set(["a", "b"]); plural(s, "one", "many")will return'many'- Unified handling of positive/negative zeroes (yes, JavaScript has both...) in methods taking numerical input. This should have no visible side-effects on current methods.
- Minor documentation fixes
-
2.13.0
- Add
fuzzyDate()method, for partial date strings, e.g.2018-03(March 2018). year()takes number formatting options, so thatyear("2017-12-31", {numberSystem: "roman"})returns'MMXVII'(English),'MMXVII年'(Japanese), etc.- Documentation fixes
- Add
-
2.12.0
- CLDR 36, see http://cldr.unicode.org/index/downloads/cldr-36
- fix documentation errors for
largeNumber*() - Enable decimal digits in
largeNumber*()for consistency
-
2.11.0
- added
largeNumberText()andlargeNumberPretty()
- added
-
2.10.5
- Upgrade node-cldr to 5.4.1, to fix packaging error
-
2.10.4
- Re-release to clean up node_modules
-
2.10.3
- Fix issue #13:
plural()now uses thedecimalDigitsoption, to be consistent with surrounding methods.let val = 1.0002; ${number(val)} pink ${plural(val, "dolphin", "dolphins")}will now return “1 pink dolphin”, not “1 pink dolphins” - Upgrade node-cldr to 5.4.0, for fewer dependencies
- Fix issue #13:
-
2.10.2
- Remove CLDR notes from territory names (e.g.
fridf, Île-de-France)
- Remove CLDR notes from territory names (e.g.
-
2.10.1
territory("RS-00")is now "Belgrade", not "Beograd" in English, using a local override
-
2.10.0
- Add
char()method
- Add
-
2.9.1
- Add
GR-A1as supplemental territory code forGR-I
- Add
-
2.9.0
- [BREAKING] Fixed a leap year bug in some interval methods.
months("2004-01-31", "2004-02-28")will now correctly return '0 months', whereasmonths("2003-01-31", "2003-02-28")returns '1 month', as we count only full months passed. - [BREAKING] Make
sign()behave the same as every other method with regards to positive and negative 0 (they are now all treated like 0). territory()now looks for deprecated or alternative territory codes listed in CLDR, before falling back to local last-resort, increasing the number of valid codes by 784. In some cases a deprecated code can map to multiple new. These will be passed throughlist(), so thatterritory(AN)=> 'Curaçao, Sint Maarten och Karibiska Nederländerna' (sv).territory()now removes disambiguity appendixes, like the ' (province)' in "Liège (province)". Note that this will not affect e.g. "Myanmar (Burma)", where the paranthesis serve a different purpose.- Fix issue #12: Algorithmic number systems fail for negative numbers in
numberText() - Fix issue with whole numbers in
fractionText(), where the correct default gender was not applied - Hard-code Latin digits in
change()for improved performance - Improved performance for
territory() - Various stability improvements in number formatting module
- Added list sample strings to
options.html#numberSystemdocumentation - Improved test coverage
- [BREAKING] Fixed a leap year bug in some interval methods.
-
2.8.1
- Added local fallback rules in
territory()for common or deprecated ISO codes that CLDR does not understand.territory("czst"), the code used for Středočeský in the Czech Republic until late 2018, will now work as an alias forterritory("cz20"), andterritory("SE-05"), an alternative designation for Östergötland, will work as an alias forterritory("SE-E").
- Added local fallback rules in
-
2.8.0
territory()now supports all sub-national divisions in CLDR:territory("SE-ac")=> “Västerbottens län”- [BREAKING]
territory()will now produce an error on missing or invalid locales, rather than crashing. - [BREAKING]
*Pretty()-methods will now use numerical output if there is a fractional part in the final output.
-
2.7.4
- CLDR updated to version 35, with local names for “North Macedonia”, improved support for Somali and Javanese, and much, much more: http://cldr.unicode.org/index/downloads/cldr-35
-
2.7.3
- Upstream bug-fix in node-cldr (5.0.2), to make some number systems with digits with high Unicode code-points work (e.g. the previously broken
number(123.3, {numberSystem: "ahom"}) - Upstream bug-fix in node-cldr (5.0.3), to solve issue with
numberText()for high number. Test case:numberText(1800000) - Improved number formatting module, to make more number systems and number formats work as expected
- Upstream bug-fix in node-cldr (5.0.2), to make some number systems with digits with high Unicode code-points work (e.g. the previously broken
-
2.7.2
- make
largeNumber(),millions(), andbillions()chainable - fix a bug in
superScript()andsubScript()that would make them fail for strings with high code-points Unicode characters.
- make
-
2.7.1
largeNumber()takes amagnitudeoption to force a certain unit.millions(val)is equal tolargeNumber(val, {magnitude: 6}).- Add
billions()as an alias forlargeNumber(val, {magnitude: 9})
-
2.7.0
-
Added
largeNumber()andmillions()methods -
2.6.0
- [BREAKING]
change()will now round all numbers, rather than truncating, following roughly the same internal logic asnumber*() - Make
debugData()work properly in debug mode (doh!) - Make
fractionShort()output deprecation warning in debug mode (should have been done in 2.4.0) - Updated the JSDoc skin (DocDash) to remove jQuery dependency.
- [BREAKING]
-
2.5.1
- Update in CLDR dependency fixes some RBNF rule parsing errors.
- Make
numberText()work for negative numbers. - Make
numberPretty()usenumber()as a fallback rather than crashing on missing CLDR data
-
2.5.0
- [BREAKING]
number*()will now round, rather than truncate numbers. This was always ambigous in the docs. - Added English rules for
fractionText() - Added
debugData()method for printing out debugging data in the robot writer
- [BREAKING]
-
2.4.0
- Make
fraction()use sub scripted and super scripted numbers, when available, because very few fonts fully support the Unicode fraction⁄sign. - Make
fraction()use narrow non-breaking space between whole part and fraction, in the default layout (usually 3/4 of a normal space). - Deprecate
fractionShort()again, as it is now typographically very similar tofraction(); the compound characters are not recommended by Unicode; and the method name was in-consistent with the rest of the lib anyway (*Shortnames are otherwise used for abbreviations and the like). - Add
superScript()andsubScript(). These are now used internally when composing fractions, but could also be useful when working with e.g. Mathematics or Chemistry:C${subScript(carbon)}H${subScript(oxygen)}OH=>C₂H₅OH - Improved
fractionText()support for Swedish - Documentation fixes
- Make
-
2.3.0
- Make sure failing method name is always included in error message (an issue with how internal function calls works caused it to miss out in some cases)
- Added methods
fraction(),fractionShort()andfractionText(), with limited language support. Will print things like¼,one third,1 1⁄2, and൳. Note that language specific gender and plural rules may require much more sophisticated logic than can be provided here. This is often best defined on a per-template bases (see utility methods below). - Added utility method
fractionParts(), primarily for use in template level functions - Expose previously internal, undocumented formatting method as
format(), primarily for use in template level function. Example:format("The {0} on the bus go {1} and {1}", "wheels", "round").fractionPartsandformatcould be used together to describe a statistical probability:let shareOf = x => format("{0} out of {1}", fractionParts(x, {denominator: 10}).slice(1).map(y => numberText(y)));shareOf(0.3333)=>'one out of three'. - Deprecate
_format() - Use defaults for covering up partially supported languages in local (non CLDR) language data. Methods relying on local language data will now give reasonable output in more languages.
-
2.2.0
- Make previously private, undocumented
abs()method public. - Add
percentText()andpercentPretty() *Text()methods will now use thedecimalDigitsoptions, so thatnumberText(3.141592, {decimalDigits: 2})=>'Tre komma fjorton'This should makepercentPrettymore useful.- Make
*Text()methods throw an error on negative input, rather than failing silently. - Various documentation fixes.
- Make previously private, undocumented
-
2.1.1
- Fix version number in package.json
-
2.1.0
- Enable boolean shortcuts in options.
number(2.0, {forceDecimalDigits: true})can now be written asnumber(2.0, {forceDecimalDigits}) - Better grouping of methods in docs
- Speed up
number()for Latin numbers, by hard coding digits
- Enable boolean shortcuts in options.
-
2.0.1
- Various dependency updates, notably node-cldr@5.0.0
-
2.0.0
- [REQUIREMENT] From this version we require NodeJS >= 10.0.0, jumping up from 6.0.0
- [BREAKING] The
langproperty will now contain the whole fallback chain of language tags (but not languages that are automatically deduced) - [BREAKING]
langis now read-only. Making it writable added complexity with little extra advantages. If you need to switch languages while in the middle of rendering, you should use two separate textfunctions instances, as was always the recommendation. - [BREAKING]
ordinalAdverb(),years*(),yearMonths*(),months*(), andt*()will now check for both the specific locale, and the more general tags, e.g.de-AT=>de, before moving on to the next language in the fallback chain. This is the logic that all other methods were already following. Specifying language tags of different detail level is no longer useful, or meaningful.["sv-AX", "sv"]is the same as"sv-AX". Note that specifying a macro language as a fallback could still be useful:["nn", "no"]. Try being as specific as possible in language tags. - Methods that take numerical input will now accept arrays and objects, and use their length as the value. This often makes sense semantically in a templating environment, where you can now write things like
There #{plural(new_parties, "is", "are")} #{number(new_parties)} new #{plural(new_parties, "party", "parties")} in the parliament: #{list(new_parties)}(Pug syntax). - Added a
numberSystemoption for methods with numerical output, e.g.number(x, {numberSystem: 'latn'})to force using Latin number in an Arabic text. - You can now keep multiple parallel footnote systems going, by specifying different number systems, e.g. using roman numerals for footnotes in a table, inside a longer article with footnotes using Latin numerals.
percent()andintegerPretty()got lost in the documentation in1.11.0, they are back now- Unified cache handling for easier maintenance and more consistent behavior across methods
- Make
year()use proper date formatting, most notably affecting East Asian languages - Fix bug in number formatting for patterns with repeated group markers, e.g. Indian number formats
- Removed "number-format.js" dependency
- Error handling fixes
-
1.12.3
- Further cleanup of debug output
-
1.12.2
- Fix versioning error (1.12.0 was accidentally released as 1.12.1)
-
1.12.0
- Add disjunctive lists with
listOr()(A, B, or C) andtListOr() - Various improvements in debug output
- Add disjunctive lists with
-
1.11.1
- Fix linting errors
-
1.11.0
- Fix bug in options to
numberPretty() - Remove deprecated
percentPretty()(that did not work well across languages) - Remove deprecated
percentWithSign() - Re-introduce
percent(), as an alias fornumber(x - 100) - Group documentation thematically
- Fix bug in options to
-
1.10.0
- [BREAKING] Non-allowed values in options will now return an error, rather than falling back to the default. Invalid test case:
numberText(1, {gender: "dog"}) - Added
addDays(),addMonths(), andaddYears()methods to add or subtract days, months, years. - Chaining no longer considered experimental. Now documented, and fairly well covered by tests.
- Better date formatting coverage
- Added missing test cases
- [BREAKING] Non-allowed values in options will now return an error, rather than falling back to the default. Invalid test case:
-
1.9.5
- Refactor out all Intl dependencies, to use CLDR data directly
-
1.9.4
- Remove old code that added stuff to the String prototype.
- Improved argument parsing and error messages for list arguments (affects
list()andtList()) - Changes to Intl loading, to try mitigating a bug in some date functions
-
1.9.3
- Make chaining work with multiple arguments. This also allows passing options to intermediate steps:
random(1, 2, 3).numberText({gender: "reale"}).upper() - Extended chaining support
- Print out deprecation warnings for deprecated methods in debug mode.
- Documentation fixes
- Make chaining work with multiple arguments. This also allows passing options to intermediate steps:
-
1.9.2
- Re-release with correct version number in package.json
-
1.9.1
- Make debug mode work with chained methods
- Throw error on invalid number inputs, that would previously be rendered as
NaN - Add
fn()as an alias forfootnote() - Make debug show unparsed arguments
-
1.9.0
- Fix bug in
list(), where empty lists returned nonsense. - Improved debug coverage
- Make internal
lang()method a property, and expose it - Allow changing language/locale by setting a
langproperty - Add missing
integerText(), for completeness - Unify argument parsing, making sure that all input is treated equally
- Always throw errors on invalid input
- Dates may now only be given as strings or date objects. This is what the docs always said, but in reality you could use whatever the Javascript
Date()constructor would swallow. - Experimental, partial support for chaining:
month().upper(), as an alternative toupper(month()), orrandom(1, 2, 3).numberText().upper(), as an alternative toupper(numberText(random(1, 2, 3))) random()will now always return text.
- Fix bug in
-
1.8.1
- Make
references()work in debug mode. - Clean up debug mode output
- Make
-
1.8.0
- Throw an error on missing input to
plural() - Remove deprecated percentText method that was not used by any templates
ordinalAjective()use numerals for large numbers, e.g. "222:a största" or "222.größte"- Improved number formatting in
number(), that no longer relies onIntl.NumberFormatting.forceDecimalDigitsand other options should now work as expected. - Added a debug mode with stricter warnings, and additional html mark-up
- Throw an error on missing input to
-
1.7.1
- Fix a bug where
change()would show an unwanted sign for small floats
- Fix a bug where
-
1.7.0
- Add
keyoptions totList() - Put
conjugationin the options object tot()andtList(), but with backwards compatibility fort()
- Add
-
1.6.1
- Fixed a bug in
yearMonth*(), where dates passed by reference were altered
- Fixed a bug in
-
1.6.0
- Added
months*(),years*(), andyearMonths*()methods for a few languages. - Make
ordinalAdverb()less specific when looking for rules. Bothde-DEandde-ATwill now return the same German rule set.
- Added
-
1.5.2
- Increased test coverage
- Documentation updates
-
1.5.1
- Fix JSDoc bug
-
1.5.0
- Change the call sign from
referencestoreferences(), to make it work in some edge cases - Fix an ugly caching bug in
plural()/pl() - Added PugJS tests
- Change the call sign from
-
1.4.1
- Cache unit patterns
-
1.4.0
- Add
assign()semi-private method (not for template authors)
- Add
-
1.3.0
- Add
footnote()andreferences - Add
since*methods - Add
interval*methods - Add
integer*methods - Add
weekday*methods - Remove some unused code
- Some documentation fixes
- Add
-
1.2.0
- Fix bug where
todaydid not contain the date - Make all public methods return an error message on internal exceptions. The rationale is that text function errors are of more interest to template authors, than to the server processing them.
- Report an error on invalid month numbers
- Fix bug where
-
1.1.2
- Changed the way options are parsed under the hood
- Improved jsdoc structure
-
1.1.1
- Only load Intl module when needed
- Cache list patterns, RNBF functions and plural rules
- Better test coverage
-
1.1.0
title()for title case
-
1.0.0
- First version, migrated from J++