diff --git a/src/lib/Form.svelte b/src/lib/Form.svelte
index 1aa5b0b..8f2e892 100644
--- a/src/lib/Form.svelte
+++ b/src/lib/Form.svelte
@@ -14,7 +14,6 @@
} from "$lib/stores"
import { frac } from "$lib/frac"
import FracInput from "$lib/FracInput.svelte"
- import FracRange from "$lib/FracRange.svelte"
Inputs
@@ -27,7 +26,7 @@
-
-
-
+
diff --git a/src/lib/FracRange.svelte b/src/lib/FracRange.svelte
deleted file mode 100644
index 4701be7..0000000
--- a/src/lib/FracRange.svelte
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/src/lib/PartList.svelte b/src/lib/PartList.svelte
index 468257c..6ea7efc 100644
--- a/src/lib/PartList.svelte
+++ b/src/lib/PartList.svelte
@@ -52,7 +52,7 @@
{#each $parts as part}
{part.count} |
- {frac(part.width)}" × {frac(part.length)}" |
+ {frac(part.width)} × {frac(part.length)} |
{part.material.name} |
{/each}
diff --git a/src/lib/frac.test.ts b/src/lib/frac.test.ts
index 9d4592f..885798f 100644
--- a/src/lib/frac.test.ts
+++ b/src/lib/frac.test.ts
@@ -3,19 +3,19 @@ import { frac, parseFrac } from "$lib/frac"
describe("frac renders numbers as mixed fractions", () => {
const cases: [number, string][] = [
- [-1 - 3 / 8, "-1\u20093⁄8"],
- [-1, "-1"],
- [0, "0"],
- [1, "1"],
- [1.5, "1\u20091⁄2"],
- [12.25, "12\u20091⁄4"],
- [-6.125, "-6\u20091⁄8"],
- [1 / 4, "1⁄4"],
- [7 / 8, "7⁄8"],
- [15 / 16, "15⁄16"],
- [1 + 17 / 32, "1\u200917⁄32"],
- [23 / 32, "23⁄32"],
- [3 + 61.5 / 64, "3\u200931⁄32"],
+ [-1 - 3 / 8, '-1\u20093⁄8"'],
+ [-1, '-1"'],
+ [0, '0"'],
+ [1, '1"'],
+ [1.5, '1\u20091⁄2"'],
+ [12.25, '12\u20091⁄4"'],
+ [-6.125, '-6\u20091⁄8"'],
+ [1 / 4, '1⁄4"'],
+ [7 / 8, '7⁄8"'],
+ [15 / 16, '15⁄16"'],
+ [1 + 17 / 32, '1\u200917⁄32"'],
+ [23 / 32, '23⁄32"'],
+ [3 + 61.5 / 64, '3\u200931⁄32"'],
]
test.for(cases)("renders %d as %s", ([n, s]) => {
expect(frac(n)).toEqual(s)
@@ -57,6 +57,20 @@ describe("parseFrac converts strings to numbers", () => {
[" 123", NaN],
["123 ", NaN],
["1/2.3", NaN],
+ // " is allowed following the number
+ ['8"', 8],
+ ['8" 1/2"', 8.5],
+ ['6" + 1/2" - 0.25 + 1/2"', 6.75],
+ ['1"/2', NaN],
+ // ' following the number multiplies by 12 (feet to inches)
+ ["1'", 12],
+ ["1'2", 14], // No whitespace necessary
+ ["1' 2", 14],
+ ["1' 2\"", 14],
+ ["1' + 2", 14],
+ ["1'+2\"", 14],
+ ["1/2' +12\"", 18],
+ ["3'4'5'6'1/2'", (3 + 4 + 5 + 6 + 0.5) * 12],
]
test.for(cases)("parses %j as %d", ([s, n]) => {
expect(parseFrac(s)).toEqual(n)
diff --git a/src/lib/frac.ts b/src/lib/frac.ts
index b25db95..46d78de 100644
--- a/src/lib/frac.ts
+++ b/src/lib/frac.ts
@@ -1,5 +1,5 @@
/**
- * Present a number as a mixed fraction.
+ * Present a number as a mixed fraction, in inches.
*
* The value is rounded to the nearest 1⁄32nd, and the
* denominator is one of 32, 16, 8, or 4, as on a measuring tape.
@@ -35,7 +35,7 @@ export function frac(n: number): string {
s += `${num}\u2044${denom}`
}
- return s
+ return s + '"'
}
/**
@@ -44,7 +44,7 @@ export function frac(n: number): string {
export function parseFrac(s: string): number {
const matches = [
...s.matchAll(
- /((?:[+-]\s*)?)(\.\d+|\d+(?:\.\d*)?)(?:[/\u2044](\d+))?(\s+|$|(?=[+-]))/dg
+ /((?:[+-]\s*)?)(\.\d+|\d+(?:\.\d*)?)(?:[/\u2044](\d+))?(["']?)(\s+|$|(?=[+-])|(?<=["'])(?=\d))/dg
),
]
if (matches.length === 0 || matches[0].index !== 0) {
@@ -58,9 +58,13 @@ export function parseFrac(s: string): number {
let sign = m[1].substring(0, 1)
let v = parseFloat(m[2])
const denom = m[3]
+ const unit = m[4]
if (denom) {
v /= parseFloat(denom)
}
+ if (unit === "'") {
+ v *= 12 // Feet to inches
+ }
if (!sign) {
sign = lastSign
}
@@ -73,7 +77,7 @@ export function parseFrac(s: string): number {
}
}
- const [lastStart] = matches[matches.length - 1].indices![4]
+ const [lastStart] = matches[matches.length - 1].indices![5]
if (lastStart !== s.length) {
// Failure to match, or trailing whitespace or other gunk.
return NaN
diff --git a/tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png b/tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png
index 193b7fe..12d4f8a 100644
--- a/tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png
+++ b/tests/test.ts-snapshots/calculator-layout-1-Desktop-linux.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0594ac4a1d3d8c2cfa1e1b63572eb1a344b84ff3f0d5d76a6d555efdc2b8adeb
-size 270068
+oid sha256:d00cacbf2d99f80e8e23294917fe9efdead8e3796b611e7ddd8c42eafdb16f5d
+size 268973
diff --git a/tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png b/tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png
index c6d8e30..d3d201d 100644
--- a/tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png
+++ b/tests/test.ts-snapshots/calculator-layout-1-Phone-linux.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9330f7f857549c4fbb91913df9a067b5f14dbf4e3dc917987d6684dafa163aa1
-size 472836
+oid sha256:5f7742dd60e9dfdfa870a966f96c5e114cc0c013a86c0d4587ce98bddaa5e09e
+size 470080
diff --git a/tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png b/tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png
index 13f6b4f..95a976e 100644
--- a/tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png
+++ b/tests/test.ts-snapshots/calculator-layout-1-Tablet-linux.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:eec4456ef2c21e7be3049d6a2e227190598202242f32537420d437048d555869
-size 556609
+oid sha256:6631193c4e647106cb7878701827001cc7da369cceff12e978d2e3d57fc3a1de
+size 558625