feat: better supported hybrid units
This commit is contained in:
parent
93837aaf20
commit
bac7a14f95
4 changed files with 273 additions and 8 deletions
|
|
@ -7,7 +7,7 @@
|
|||
* Toggle: imperial units, expanded times
|
||||
*/
|
||||
|
||||
const { findAllMeasurements } = require('./matcher');
|
||||
const { findAllMeasurements, unitType } = require('./matcher');
|
||||
|
||||
// ─── Number Formatting ──────────────────────────────────
|
||||
|
||||
|
|
@ -204,6 +204,105 @@ function computeScaleData(measurement) {
|
|||
};
|
||||
}
|
||||
|
||||
// ─── Hybrid (Weight+Volume) Detection ───────────────────
|
||||
|
||||
function getHybridVolumeData(measurement) {
|
||||
if (measurement.type !== 'weight') return null;
|
||||
|
||||
const { alt, intermediate } = measurement;
|
||||
|
||||
if (intermediate && alt) {
|
||||
const intType = unitType(intermediate.unit);
|
||||
const altType = unitType(alt.unit);
|
||||
if (intType === 'volume' || altType === 'volume') {
|
||||
return {
|
||||
metricSource: intType === 'volume' ? intermediate : alt,
|
||||
imperialSource: altType === 'volume' ? alt : intermediate,
|
||||
hasIntermediate: true,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (alt) {
|
||||
if (unitType(alt.unit) === 'volume') {
|
||||
return { metricSource: alt, imperialSource: alt, hasIntermediate: false };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function generateHybridVolumeTexts(measurement, hybridData) {
|
||||
const { metricSource, imperialSource, hasIntermediate } = hybridData;
|
||||
const approximate = measurement.approximate;
|
||||
const prefix = approximate ? '~' : '';
|
||||
|
||||
if (hasIntermediate) {
|
||||
const metric = toMetricValue(metricSource.amount.value, metricSource.unit);
|
||||
const imperial = toImperialValue(imperialSource.amount.value, imperialSource.unit);
|
||||
return {
|
||||
volumeDefault: prefix + formatValueUnit(metric.value, metric.unit),
|
||||
volumeAlt: prefix + formatValueUnit(imperial.value, imperial.unit),
|
||||
};
|
||||
}
|
||||
|
||||
const { amount, unit } = metricSource;
|
||||
|
||||
if (amount.min !== undefined) {
|
||||
const mMin = toMetricValue(amount.min.value, unit);
|
||||
const mMax = toMetricValue(amount.max.value, unit);
|
||||
const iMin = toImperialValue(amount.min.value, unit);
|
||||
const iMax = toImperialValue(amount.max.value, unit);
|
||||
const rPrefix = (approximate || amount.min.approximate) ? '~' : '';
|
||||
|
||||
let volumeDefault, volumeAlt;
|
||||
|
||||
if (mMin.unit === mMax.unit) {
|
||||
const space = NO_SPACE_UNITS.has(mMin.unit) ? '' : ' ';
|
||||
volumeDefault = rPrefix + formatNumber(mMin.value) + '-' + formatNumber(mMax.value) + space + unitLabel(mMin.unit, mMax.value !== 1);
|
||||
} else {
|
||||
volumeDefault = rPrefix + formatValueUnit(mMin.value, mMin.unit) + '-' + formatValueUnit(mMax.value, mMax.unit);
|
||||
}
|
||||
|
||||
if (iMin.unit === iMax.unit) {
|
||||
const space = NO_SPACE_UNITS.has(iMin.unit) ? '' : ' ';
|
||||
volumeAlt = rPrefix + formatNumber(iMin.value) + '-' + formatNumber(iMax.value) + space + unitLabel(iMin.unit, iMax.value !== 1);
|
||||
} else {
|
||||
volumeAlt = rPrefix + formatValueUnit(iMin.value, iMin.unit) + '-' + formatValueUnit(iMax.value, iMax.unit);
|
||||
}
|
||||
|
||||
return { volumeDefault, volumeAlt };
|
||||
}
|
||||
|
||||
const metric = toMetricValue(amount.value, unit);
|
||||
const imperial = toImperialValue(amount.value, unit);
|
||||
return {
|
||||
volumeDefault: prefix + formatValueUnit(metric.value, metric.unit),
|
||||
volumeAlt: prefix + formatValueUnit(imperial.value, imperial.unit),
|
||||
};
|
||||
}
|
||||
|
||||
function computeHybridVolumeScaleData(measurement, hybridData) {
|
||||
const source = hybridData.metricSource;
|
||||
const approximate = measurement.approximate;
|
||||
|
||||
if (source.amount.min !== undefined) {
|
||||
return {
|
||||
base: [toBaseMl(source.amount.min.value, source.unit), toBaseMl(source.amount.max.value, source.unit)],
|
||||
type: 'volume',
|
||||
approx: approximate || source.amount.min.approximate || false,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
base: toBaseMl(source.amount.value, source.unit),
|
||||
type: 'volume',
|
||||
approx: approximate || false,
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Time Formatting ────────────────────────────────────
|
||||
|
||||
function toMinutes(value, unit) {
|
||||
|
|
@ -421,6 +520,20 @@ function replaceMeasurementsInToken(token, Token, inToolsSection) {
|
|||
}
|
||||
}
|
||||
|
||||
// Add hybrid data attributes for weight measurements with volume alternatives
|
||||
const hybridData = getHybridVolumeData(m);
|
||||
if (hybridData) {
|
||||
const { volumeDefault, volumeAlt } = generateHybridVolumeTexts(m, hybridData);
|
||||
open.attrSet('data-hybrid', 'true');
|
||||
open.attrSet('data-volume-default', volumeDefault);
|
||||
open.attrSet('data-volume-alt', volumeAlt);
|
||||
|
||||
const volumeScaleData = computeHybridVolumeScaleData(m, hybridData);
|
||||
if (volumeScaleData) {
|
||||
open.attrSet('data-volume-scalable', JSON.stringify(volumeScaleData));
|
||||
}
|
||||
}
|
||||
|
||||
newTokens.push(open);
|
||||
|
||||
// Display metric-normalized text by default
|
||||
|
|
@ -505,4 +618,6 @@ module.exports.toMetricValue = toMetricValue;
|
|||
module.exports.toImperialValue = toImperialValue;
|
||||
module.exports.generateTexts = generateTexts;
|
||||
module.exports.collapsedTime = collapsedTime;
|
||||
module.exports.expandedTime = expandedTime;
|
||||
module.exports.expandedTime = expandedTime;
|
||||
module.exports.getHybridVolumeData = getHybridVolumeData;
|
||||
module.exports.generateHybridVolumeTexts = generateHybridVolumeTexts;
|
||||
Loading…
Add table
Add a link
Reference in a new issue