Finds scale notations in a PDF sheet's text and picks the listed scale to offer for the sheet.
How the precision is kept
A notation is turned into a ratio of real inches to paper inches in 64-bit arithmetic, rounded to 3 decimals, and used only to look up one of the app's listed scales. What comes back is the listed scale's key, never a scale computed from the text. A notation that matches no listed scale is ignored. When a sheet shows several scales the most frequent wins and the others are reported.
Calculations under this policy
3 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.
Reads a fraction, a mixed number or a decimal as inches.
1-1/2 → 1 + 1 ÷ 2; 1/4 → 1 ÷ 4
The whole part plus numerator over denominator in 64-bit arithmetic. A zero denominator gives NaN or Infinity; the caller then finds no listed scale for it.
scaletext.js
lines 24 to 31
TakeoffCraft 0.8.1
/** "1/4" → 0.25, "1-1/2" / "1 1/2" → 1.5, "0.25" → 0.25 */
function inches(s) {
const m = /^(\d+)\s*[- ]\s*(\d+)\s*\/\s*(\d+)$/.exec(s.trim());
if (m) return +m[1] + +m[2] / +m[3];
const f = /^(\d+)\s*\/\s*(\d+)$/.exec(s.trim());
if (f) return +f[2] ? +f[1] / +f[2] : NaN;
return Number(s.trim());
}
Ratio of a notation and its listed scale
64-bit
Every scale notation in the text, each matched to a listed scale.
ratio = (feet × 12 + inches) ÷ paper inches, rounded to 3 decimals
The ratio is rounded with Math.round(r × 1000) ÷ 1000 and joined to a text key, so after rounding it must equal a listed ratio exactly. A metric notation uses the whole number after 1: as its key. The result is the listed scale's key and label, not a computed scale.
scaletext.js
lines 38 to 57
TakeoffCraft 0.8.1
export function scalesInText(text) {
const s = String(text || '');
const out = [];
const before = (i) => /\bscale\b\s*[:=]?\s*$/i.test(s.slice(Math.max(0, i - 16), i));
for (const m of s.matchAll(IMPERIAL)) {
const paper = inches(m[1]), real = +m[2] * 12 + (m[3] ? +m[3] : 0);
if (!(paper > 0) || !(real > 0)) continue;
const ratio = Math.round(real / paper * 1000) / 1000;
const p = byRatio.get('i' + ratio);
if (!p || p.group === 'Metric') continue;
// 1" = 1'-0" is architectural (12); 1" = 10' and up engineering — both are imperial presets by ratio
out.push({ preset: p.key, label: p.label, index: m.index, scaleWord: before(m.index) });
}
for (const m of s.matchAll(METRIC)) {
const p = byRatio.get('m' + +m[1]);
if (!p) continue;
out.push({ preset: p.key, label: p.label, index: m.index, scaleWord: before(m.index) });
}
return out.sort((a, b) => a.index - b.index);
}
Which scale a sheet gets
Exact
The most frequent scale on the sheet, and the other scales found.
Whole-number votes: 2 for a notation right after the word scale, 1 otherwise. A tie goes to the scale that appears first in the text.
Regular expressions for imperial notations (paper inches = feet and inches) and metric ones (1:n). ratio = (feet × 12 + inches) ÷ paper inches. Lookup by ratio among the listed scales, then a vote in which a notation written right after the word scale counts double.
Number types
64-bit numbers for the ratio; whole-number votes.
Tolerances
The ratio is rounded to 3 decimals, then must equal a listed ratio exactly.
Limits
Only scales in the app's list are recognized. The result depends on the sheet's text: the function cannot tell a wrong scale note from a right one.
Approach: 64-bit, stated limit
The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.