Reads lengths written as text (30", 2'-6 1/2", 762 mm) into millimeters and writes sizes back as short labels.
How the precision is kept
Lengths are parsed to millimeters with the defined unit factors (25.4 mm per inch, 304.8 mm per foot). Feet, inches and a fraction are added first and multiplied by 25.4 once. Parsing does not round; pipe sizes and preview labels are rounded to the nearest eighth of an inch or whole millimeter as text.
Open item. Keep a pipe size that is not a whole number of eighths as it was given.
Calculations under this policy
5 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
in 25.4; ft 304.8; yd 914.4; mi 1 609 344; mil 0.0254; µm 0.001
The factors are the defined values, none of them rounded. The whole-number factors are exact in binary; 25.4, 304.8, 914.4, 0.0254 and 0.001 are each the nearest 64-bit number to that decimal.
with a unit: n × factor; feet and inches: (feet × 12 + inches + a ÷ b) × 25.4; bare number: n × mm per unit
Feet, whole inches and the fraction are added first and multiplied by 25.4 once at the end. A fraction with a zero denominator gives Infinity, which the callers in this file reject with Number.isFinite. Nothing is rounded here.
libitem.js
lines 1087 to 1100
CadCraft 0.8.2
/** "30", 30" , 2'-6", 2' 6 1/2", 762 mm, 76.2 cm, 0.76 m → mm (bare numbers × mmPerUnit). NaN if not a length. */
export function parseLength(s, mmPerUnit = 1) {
const t = String(s ?? '').trim().replace(/[\u2032\u2019]/g, "'").replace(/[\u2033\u201d]/g, '"').toLowerCase();
if (!t) return NaN;
let m = t.match(/^(-?\d+(?:\.\d+)?)\s*(mm|cm|m|in|ft)$/);
if (m) return Number(m[1]) * UNIT_MM[m[2]];
m = t.match(/^(?:(\d+(?:\.\d+)?)\s*'\s*-?\s*)?(?:(\d+(?:\.\d+)?)(?:\s+(\d+)\/(\d+))?|(\d+)\/(\d+))?\s*(?:"|in)?$/);
if (m && (m[1] || m[2] || m[5]) && /['"]/.test(t)) {
const ft = Number(m[1] || 0), inch = Number(m[2] || 0) + (m[3] ? Number(m[3]) / Number(m[4]) : 0) + (m[5] ? Number(m[5]) / Number(m[6]) : 0);
return (ft * 12 + inch) * 25.4;
}
if (/^-?\d+(\.\d+)?$/.test(t)) return Number(t) * mmPerUnit;
return NaN;
}
Drawing units
Exact
The millimeters per drawing unit of a DWG or DXF file.
The file's INSUNITS code picks a factor from the same table. When the file does not say, millimeters or inches is assumed from its MEASUREMENT setting and a note says so.
libitem.js
lines 1457 to 1468
CadCraft 0.8.2
/** Drawing units → mm per unit, the key, and a note when the drawing does not say. */
export function drawingUnits(db, override) {
if (override) {
if (!UNIT_MM[override]) throw new Error(msg('libitem.units.unknown', { units: override, list: Object.keys(UNIT_MM).join(', ') }));
return { key: override, mm: UNIT_MM[override], note: null };
}
const key = INSUNITS[db.header?.INSUNITS ?? 0];
if (key) return { key, mm: UNIT_MM[key], note: null };
const metric = Number(db.header?.MEASUREMENT) === 1;
const k = metric ? 'mm' : 'in';
return { key: k, mm: UNIT_MM[k], note: msg(metric ? 'libitem.units.assumed_mm' : 'libitem.units.assumed_in') };
}
Pipe size in eighths of an inch
64-bit
A decimal inch size written as a fraction, such as 1 1/2".
eighths = round((n − ⌊n⌋) × 8)
The fraction is rounded to the nearest eighth with Math.round and the result is stored as text. A size that is not a whole number of eighths is changed: 0.3125 (5/16) becomes 3/8".
libitem.js
lines 1078 to 1085
CadCraft 0.8.2
function inches(v) {
const n = Number(v);
if (!Number.isFinite(n) || n <= 0) return v;
const whole = Math.floor(n), eighths = Math.round((n - whole) * 8);
if (eighths === 8) return (whole + 1) + '"';
const f = eighths ? ['', '1/8', '1/4', '3/8', '1/2', '5/8', '3/4', '7/8'][eighths] : '';
return (whole ? whole + (f ? ' ' : '') : '') + f + '"';
}
Size label on the preview
64-bit
The overall width and depth printed on an item's preview picture.