Provide greater consistency for badges related to versions. Fix #1181. - the `version` function in `color-formatters` was previously returning the colour of the badge, but also its text with a leading _v_. It was broken down into two separate functions and the text formatting part was moved to `text-formatters`, where it really belongs. - unit tests were added for these two functions in `color-formatters.spec` and `text-formatters.spec`, using Sazerac. - as discussed in #1181, the leading _v_ was omitted for _xxxx-yy-zz_ date patterns. Any future exceptions can easily be added to the `ignoredVersionPatterns` pattern. - the badge colour was previously switched to orange if a hyphen was found in the version string. This didn't seem ideal, instead pattern matching is done to find keywords such as `beta`, `alpha` or `snapshot`. Of course, this list can easily be extended. - all badges related to versions now use the `versionText` and `versionColor` functions. There are a few rare exceptions, for instance in cases where the data returned by the service's API allows to figure things out without relying on any parsing/pattern matching (eg. `badgeData.colorscheme = prerelease ? 'orange' : 'blue';`, where `prerelease` is determined from an API's response).
110 lines
2.7 KiB
JavaScript
110 lines
2.7 KiB
JavaScript
/**
|
|
* Commonly-used functions for formatting text in badge labels. Includes
|
|
* ordinal numbers, currency codes, star ratings, versions, etc.
|
|
*/
|
|
'use strict';
|
|
|
|
const moment = require('moment');
|
|
moment().format();
|
|
|
|
function starRating(rating) {
|
|
const flooredRating = Math.floor(rating);
|
|
let stars = '';
|
|
while (stars.length < flooredRating) { stars += '★'; }
|
|
const decimal = rating - flooredRating;
|
|
if (decimal >= 0.875) { stars += '★'; }
|
|
else if (decimal >= 0.625) { stars += '¾'; }
|
|
else if (decimal >= 0.375) { stars += '½'; }
|
|
else if (decimal >= 0.125) { stars += '¼'; }
|
|
while (stars.length < 5) { stars += '☆'; }
|
|
return stars;
|
|
}
|
|
|
|
// Convert ISO 4217 code to unicode string.
|
|
function currencyFromCode(code) {
|
|
return ({
|
|
CNY: '¥',
|
|
EUR: '€',
|
|
GBP: '₤',
|
|
USD: '$',
|
|
})[code] || code;
|
|
}
|
|
|
|
function ordinalNumber(n) {
|
|
const s=['ᵗʰ','ˢᵗ','ⁿᵈ','ʳᵈ'], v=n%100;
|
|
return n+(s[(v-20)%10]||s[v]||s[0]);
|
|
}
|
|
|
|
// Given a number, string with appropriate unit in the metric system, SI.
|
|
// Note: numbers beyond the peta- cannot be represented as integers in JS.
|
|
const metricPrefix = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
|
|
const metricPower = metricPrefix
|
|
.map(function(a, i) { return Math.pow(1000, i + 1); });
|
|
function metric(n) {
|
|
for (let i = metricPrefix.length - 1; i >= 0; i--) {
|
|
const limit = metricPower[i];
|
|
if (n >= limit) {
|
|
n = Math.round(n / limit);
|
|
if (n < 1000) {
|
|
return '' + n + metricPrefix[i];
|
|
} else {
|
|
return '1' + metricPrefix[i + 1];
|
|
}
|
|
}
|
|
}
|
|
return '' + n;
|
|
}
|
|
|
|
// Remove the starting v in a string.
|
|
function omitv(version) {
|
|
if (version.charCodeAt(0) === 118) {
|
|
return version.slice(1);
|
|
}
|
|
return version;
|
|
}
|
|
|
|
// Add a starting v to the version unless:
|
|
// - it does not start with a digit
|
|
// - it is a date (yyyy-mm-dd)
|
|
const ignoredVersionPatterns = /^[^0-9]|[0-9]{4}-[0-9]{2}-[0-9]{2}/;
|
|
function addv(version) {
|
|
if (version.startsWith('v') || ignoredVersionPatterns.test(version)) {
|
|
return version;
|
|
} else {
|
|
return `v${version}`;
|
|
}
|
|
}
|
|
|
|
function maybePluralize(singular, countable, plural) {
|
|
plural = plural || `${singular}s`;
|
|
|
|
if (countable && countable.length === 1) {
|
|
return singular;
|
|
} else {
|
|
return plural;
|
|
}
|
|
}
|
|
|
|
function formatDate(d) {
|
|
const date = moment(d);
|
|
const dateString = date.calendar(null, {
|
|
lastDay: '[yesterday]',
|
|
sameDay: '[today]',
|
|
lastWeek: '[last] dddd',
|
|
sameElse: 'MMMM YYYY'
|
|
});
|
|
// Trim current year from date string
|
|
return dateString.replace(` ${moment().year()}`, '').toLowerCase();
|
|
}
|
|
|
|
module.exports = {
|
|
starRating,
|
|
currencyFromCode,
|
|
ordinalNumber,
|
|
metric,
|
|
omitv,
|
|
addv,
|
|
maybePluralize,
|
|
formatDate
|
|
};
|