Skip to content

Commit 47e1441

Browse files
committed
Update for 1.6.3 release
1 parent 970e3d0 commit 47e1441

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+7839
-72
lines changed

CHANGELOG.md

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,81 @@
11
# Change Log
22

3+
## [1.6.3](https://github.com/nicklockwood/ShapeScript/releases/tag/1.6.3) (2023-01-31)
4+
5+
- iOS Viewer now supports editing `.shape` files directly inside the app
6+
- Added `Edit > Select Shape` and `Clear Selection` menus in macOS viewer
7+
- Added selection hotkeys and VoiceOver support for macOS viewer
8+
- Fixed selection being cleared whenever geometry is refreshed
9+
- Fixed dynamic dark mode updates on iOS viewer
10+
- Fixed iOS split view bounds crash
11+
- Fixed bug where camera hotkeys failed after reload
12+
- Fixed error overlay translucency
13+
- Fixed various member type bugs
14+
315
## [1.6.2](https://github.com/nicklockwood/ShapeScript/releases/tag/1.6.2) (2023-01-16)
416

517
- Improved info panel display
618
- Fixed twisted extrusion offset
7-
- Fixed roundrect detail level (previously 4x higher than intended)
19+
- Fixed `roundrect` detail level (previously 4x higher than intended)
820
- Fixed incorrect output when intersecting groups of meshes
921
- Empty scenes are no longer hidden if they contain debug geometry
1022
- Scene now conforms to Equatable protocol
1123
- Fixed misleading error message for excess color arguments
1224
- Fixed spurious forward declaration error for options that shadow global define
13-
- Added automatic casting of hex strings to color (useful for JSON data(
14-
- Made polygon members available on all geometries, not just manually-created meshes
25+
- Added automatic casting of hex strings to colors (useful for JSON data)
26+
- Made `.polygon` members available on all geometries, not just manually-created meshes
1527
- Excluded source location from Geometry equality comparisons
1628
- Fixed vector member access on tuples containing string elements
1729
- Fixed vector member access on nested numeric tuples
1830
- Fixed color member access on tuples and strings
1931
- Fixed polygon member lookup on meshes
20-
- Fixed handling of blocks with optional children (e.g. polygon)
32+
- Fixed handling of blocks with optional children (e.g. `polygon`)
2133
- Improved symbol lookup performance
2234
- Bumped Euclid to version 0.6.8
2335

2436
## [1.6.1](https://github.com/nicklockwood/ShapeScript/releases/tag/1.6.1) (2023-01-02)
2537

26-
- Added twist option to extrude command
27-
- Fixed inconsistent view menu options when switching between open documents
38+
- Added `twist` option to `extrude` command
39+
- Fixed inconsistent View menu options when switching between open documents
2840
- Bumped Euclid to version 0.6.7
2941

3042
## [1.6.0](https://github.com/nicklockwood/ShapeScript/releases/tag/1.6.0) (2022-12-27)
3143

3244
- Added hull command for creating convex hulls from points, paths or other meshes
3345
- Added mesh command for manually creating meshes from individual polygons
34-
- Added axisAligned property for controlling extrusion along paths
46+
- Added `axisAligned` property for controlling extrusion along paths
3547
- Added support for importing plain text files as a string and JSON files as a tuple
3648
- Added modulo operator for calculating remainder of division
3749
- Significantly overhauled type system to support lists, unions and objects
3850
- Improved static analysis, allowing type errors to be caught earlier
3951
- Improved handling of background property scope
4052
- The min and max functions are now variadic (accept any number of arguments)
41-
- Added split(), join() and trim() functions for working with strings
53+
- Added `split()`, `join()` and `trim()` functions for working with strings
4254
- Added automatic conversion of strings to numbers or boolean values where applicable
43-
- Added string.lines, .words and .characters members
44-
- Added tuple.count, .last, .allButFirst and .allButLast members
55+
- Added `string.lines`, `.words` and `.characters` members
56+
- Added `tuple.count`, `.last`, `.allButFirst` and `.allButLast` members
4557
- Fixed member lookup on numeric literals
4658
- Fixed bug where material of imported shapes could not be overridden
4759
- Background and texture can now be cleared by setting them to an empty string
4860
- Logging geometry values to console now produces more useful output
4961
- Added proper logging for bounds and point values
50-
- Added fileTimedOut and circularImport errors
62+
- Added `fileTimedOut` and `circularImport` errors
5163
- Refactored and improved error handling
52-
- Renamed ImportError to ProgramError
64+
- Renamed `ImportError` to `ProgramError`
5365
- Raised minimum Euclid version to 0.6.6
5466
- Added Spirals example
5567

5668
## [1.5.14](https://github.com/nicklockwood/ShapeScript/releases/tag/1.5.14) (2022-12-18)
5769

58-
- Added support for C-style block comments using /* ... */ syntax
70+
- Added support for C-style block comments using `/* ... */` syntax
5971
- Fixed bug where source file could incorrectly be inferred as UTF-7, causing parsing errors
6072
- Fixed issue where error messages would sometimes suggest the same identifier you already used
6173
- Improved script execution performance by making source location lookup lazy
6274
- Bumped Euclid to version 0.6.6
6375

6476
## [1.5.13](https://github.com/nicklockwood/ShapeScript/releases/tag/1.5.13) (2022-12-08)
6577

66-
- Fixed crash when importing external .shape files
78+
- Fixed crash when importing external `.shape` files
6779
- When error occurs in imported file, Cmd-E now opens that file instead of the main file
6880
- Bumped Euclid to version 0.6.5
6981

@@ -85,7 +97,7 @@
8597
## [1.5.10](https://github.com/nicklockwood/ShapeScript/releases/tag/1.5.10) (2022-10-29)
8698

8799
- Improved documentation for strings and trigonometry functions
88-
- Fixed empty bounds returned for lathe, fill, extrude and loft shapes
100+
- Fixed empty bounds returned for `lathe`, `fill`, `extrude` and `loft` shapes
89101
- Fixed runtime warning about postscript font names
90102
- Fixed range bug in error formatting logic
91103
- Fixed inconsistent handling of functions that return tuples
@@ -471,7 +483,7 @@
471483

472484
## [1.1.3](https://github.com/nicklockwood/ShapeScript/releases/tag/1.1.3) (2021-07-10)
473485

474-
- Fixed assertion failure if a parsing error occurs at the last character in the .shape file
486+
- Fixed assertion failure if a parsing error occurs at the last character in the `.shape` file
475487
- Fixed bug in Path plane calculation that could result in corrupted extrusion shapes
476488
- Fixed a tessellation bug affecting anti-clockwise polygons
477489

ShapeScript.podspec.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ShapeScript",
3-
"version": "1.6.2",
3+
"version": "1.6.3",
44
"license": {
55
"type": "MIT",
66
"file": "LICENSE.md"
@@ -10,7 +10,7 @@
1010
"authors": "Nick Lockwood",
1111
"source": {
1212
"git": "https://github.com/nicklockwood/ShapeScript.git",
13-
"tag": "1.6.2"
13+
"tag": "1.6.3"
1414
},
1515
"source_files": ["ShapeScript", "LRUCache/Sources", "SVGPath/Sources"],
1616
"requires_arc": true,

ShapeScript.xcodeproj/project.pbxproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@
11311131
"$(inherited)",
11321132
"@executable_path/../Frameworks",
11331133
);
1134-
MARKETING_VERSION = 1.6.2;
1134+
MARKETING_VERSION = 1.6.3;
11351135
PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.ShapeScriptViewer;
11361136
PRODUCT_MODULE_NAME = Viewer;
11371137
PRODUCT_NAME = "ShapeScript Viewer";
@@ -1159,7 +1159,7 @@
11591159
"$(inherited)",
11601160
"@executable_path/../Frameworks",
11611161
);
1162-
MARKETING_VERSION = 1.6.2;
1162+
MARKETING_VERSION = 1.6.3;
11631163
PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.ShapeScriptViewer;
11641164
PRODUCT_MODULE_NAME = Viewer;
11651165
PRODUCT_NAME = "ShapeScript Viewer";
@@ -1189,7 +1189,7 @@
11891189
"$(inherited)",
11901190
"@executable_path/Frameworks",
11911191
);
1192-
MARKETING_VERSION = 1.6.2;
1192+
MARKETING_VERSION = 1.6.3;
11931193
PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.ShapeScriptViewer;
11941194
PRODUCT_MODULE_NAME = Viewer;
11951195
PRODUCT_NAME = ShapeScript;
@@ -1221,7 +1221,7 @@
12211221
"$(inherited)",
12221222
"@executable_path/Frameworks",
12231223
);
1224-
MARKETING_VERSION = 1.6.2;
1224+
MARKETING_VERSION = 1.6.3;
12251225
PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.ShapeScriptViewer;
12261226
PRODUCT_MODULE_NAME = Viewer;
12271227
PRODUCT_NAME = ShapeScript;
@@ -1384,7 +1384,7 @@
13841384
"@executable_path/../Frameworks",
13851385
"@loader_path/Frameworks",
13861386
);
1387-
MARKETING_VERSION = 1.6.2;
1387+
MARKETING_VERSION = 1.6.3;
13881388
PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.ShapeScriptLib;
13891389
PRODUCT_NAME = ShapeScript;
13901390
SKIP_INSTALL = YES;
@@ -1415,7 +1415,7 @@
14151415
"@executable_path/../Frameworks",
14161416
"@loader_path/Frameworks",
14171417
);
1418-
MARKETING_VERSION = 1.6.2;
1418+
MARKETING_VERSION = 1.6.3;
14191419
PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.ShapeScriptLib;
14201420
PRODUCT_NAME = ShapeScript;
14211421
SKIP_INSTALL = YES;

ShapeScript/Interpreter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Foundation
1111

1212
// MARK: Public interface
1313

14-
public let version = "1.6.2"
14+
public let version = "1.6.3"
1515

1616
public protocol EvaluationDelegate: AnyObject {
1717
func resolveURL(for path: String) -> URL

ShapeScriptTests/MetadataTests.swift

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,35 @@
99
@testable import ShapeScript
1010
import XCTest
1111

12-
private let projectDirectory = URL(fileURLWithPath: #file)
12+
private let projectDirectory: URL = URL(fileURLWithPath: #file)
1313
.deletingLastPathComponent().deletingLastPathComponent()
1414

1515
private let changelogURL = projectDirectory
1616
.appendingPathComponent("CHANGELOG.md")
1717

18-
private let podspecURL = projectDirectory
18+
private let podspecURL: URL = projectDirectory
1919
.appendingPathComponent("ShapeScript.podspec.json")
2020

21-
private let projectURL = projectDirectory
21+
private let projectURL: URL = projectDirectory
2222
.appendingPathComponent("ShapeScript.xcodeproj")
2323
.appendingPathComponent("project.pbxproj")
2424

25-
private let helpDirectory = projectDirectory
25+
private let helpDirectory: URL = projectDirectory
2626
.appendingPathComponent("docs")
2727

28-
private let helpSourceDirectory = helpDirectory
28+
private let helpSourceDirectory: URL = helpDirectory
2929
.appendingPathComponent("src")
3030

31-
private let helpIndexURL = helpSourceDirectory
31+
private let helpIndexURL: URL = helpSourceDirectory
3232
.appendingPathComponent("index.md")
3333

34-
private let imagesDirectory = helpDirectory
34+
private let imagesDirectory: URL = helpDirectory
3535
.appendingPathComponent("images")
3636

37-
private let examplesDirectory = projectDirectory
37+
private let examplesDirectory: URL = projectDirectory
3838
.appendingPathComponent("Examples")
3939

40-
private let exampleURLs = try! FileManager.default
40+
private let exampleURLs: [URL] = try! FileManager.default
4141
.contentsOfDirectory(atPath: examplesDirectory.path)
4242
.map { URL(fileURLWithPath: $0, relativeTo: examplesDirectory) }
4343
.filter { $0.pathExtension == "shape" }
@@ -56,12 +56,12 @@ private func findHeadings(in string: String) -> [String] {
5656
.map { String($0.dropFirst(3)) }
5757
}
5858

59-
private let headerLinks = [
59+
private let headerLinks: [(String, String)] = [
6060
("Getting Started", "getting-started.md"),
6161
("Camera Control", "camera-control.md"),
6262
]
6363

64-
private let geometryLinks = [
64+
private let geometryLinks: [(String, String)] = [
6565
("Primitives", "primitives.md"),
6666
("Options", "options.md"),
6767
("Materials", "materials.md"),
@@ -77,7 +77,7 @@ private let geometryLinks = [
7777
("Cameras", "cameras.md"),
7878
]
7979

80-
private let syntaxLinks = [
80+
private let syntaxLinks: [(String, String)] = [
8181
("Comments", "comments.md"),
8282
("Literals", "literals.md"),
8383
("Symbols", "symbols.md"),
@@ -91,21 +91,33 @@ private let syntaxLinks = [
9191
("Import", "import.md"),
9292
]
9393

94-
private let footerLinks = [
94+
private let footerLinks: [(String, String)] = [
9595
("Examples", "examples.md"),
9696
("Glossary", "glossary.md"),
9797
]
9898

99+
private let versions: [String] = {
100+
let fm = FileManager.default
101+
var versions = Set([shapeScriptVersion])
102+
let files = try! fm.contentsOfDirectory(atPath: helpDirectory.path)
103+
for file in files where file.hasPrefix("1.") {
104+
versions.insert(file)
105+
}
106+
return versions.sorted(by: {
107+
$0.localizedStandardCompare($1) == .orderedAscending
108+
})
109+
}()
110+
99111
private extension URL {
100112
func hasSuffix(_ suffix: String) -> Bool {
101-
deletingPathExtension().lastPathComponent.hasSuffix("-" + suffix)
113+
deletingPathExtension().lastPathComponent.hasSuffix(suffix)
102114
}
103115

104-
func withSuffix(_ suffix: String) -> URL {
116+
func appendingSuffix(_ suffix: String) -> URL {
105117
let name = deletingPathExtension().lastPathComponent
106118
return deletingPathExtension()
107119
.deletingLastPathComponent()
108-
.appendingPathComponent(name + "-" + suffix)
120+
.appendingPathComponent(name + suffix)
109121
.appendingPathExtension(pathExtension)
110122
}
111123

@@ -116,7 +128,7 @@ private extension URL {
116128
let name = deletingPathExtension().lastPathComponent
117129
return deletingPathExtension()
118130
.deletingLastPathComponent()
119-
.appendingPathComponent(String(name.dropLast(suffix.count + 1)))
131+
.appendingPathComponent(String(name.dropLast(suffix.count)))
120132
.appendingPathExtension(pathExtension)
121133
}
122134
}
@@ -207,7 +219,7 @@ class MetadataTests: XCTestCase {
207219

208220
for (index, url) in [
209221
(indexMac, helpIndexURL),
210-
(indexIOS, helpIndexURL.withSuffix("ios")),
222+
(indexIOS, helpIndexURL.appendingSuffix("-ios")),
211223
] {
212224
let existing = try String(contentsOf: url)
213225
XCTAssertEqual(existing, index)
@@ -342,7 +354,7 @@ class MetadataTests: XCTestCase {
342354
let enumerator = try XCTUnwrap(fm.enumerator(atPath: helpSourceDirectory.path))
343355
for case let file as String in enumerator {
344356
let fileURL = helpSourceDirectory.appendingPathComponent(file)
345-
guard fileURL.pathExtension == "md", !fileURL.hasSuffix("ios") else {
357+
guard fileURL.pathExtension == "md", !fileURL.hasSuffix("-ios") else {
346358
enumerator.skipDescendants()
347359
continue
348360
}
@@ -365,12 +377,9 @@ class MetadataTests: XCTestCase {
365377
enumerator.skipDescendants()
366378
continue
367379
}
368-
if fileURL.hasSuffix("ios") {
369-
file = String(fileURL
370-
.deletingPathExtension()
371-
.lastPathComponent
372-
.dropLast(4)) + ".md"
373-
} else if fm.fileExists(atPath: fileURL.withSuffix("ios").path) {
380+
if fileURL.hasSuffix("-ios") {
381+
file = fileURL.deletingSuffix("-ios").lastPathComponent
382+
} else if fm.fileExists(atPath: fileURL.appendingSuffix("-ios").path) {
374383
continue
375384
}
376385
let text = try XCTUnwrap(String(contentsOf: fileURL))
@@ -387,18 +396,25 @@ class MetadataTests: XCTestCase {
387396
else {
388397
continue
389398
}
390-
if !url.hasSuffix("ios") {
391-
let isMac = url.hasSuffix("mac")
399+
if url.pathExtension == "png" {
400+
let isMac = url.hasSuffix("-mac")
392401
if isMac {
393-
url = url.deletingSuffix("mac")
402+
url = url.deletingSuffix("-mac")
403+
}
404+
if !url.hasSuffix("-ios") {
405+
let iosURL = url.appendingSuffix("-ios")
406+
let absoluteURL = URL(fileURLWithPath: iosURL.path, relativeTo: fileURL)
407+
if fm.fileExists(atPath: absoluteURL.path) {
408+
url = iosURL
409+
}
394410
}
395-
let iosURL = url.withSuffix("ios")
396-
let absoluteURL = URL(fileURLWithPath: iosURL.path, relativeTo: fileURL)
397-
if url.pathExtension == "png", fm.fileExists(atPath: absoluteURL.path) {
398-
url = iosURL
399-
} else if isMac {
400-
let macFile = url.withSuffix("mac").lastPathComponent
401-
XCTFail("File '\(macFile)' has no iOS equivalent")
411+
for version in versions.reversed() {
412+
let iosURL = url.appendingSuffix("-\(version)")
413+
let absoluteURL = URL(fileURLWithPath: iosURL.path, relativeTo: fileURL)
414+
if fm.fileExists(atPath: absoluteURL.path) {
415+
url = iosURL
416+
break
417+
}
402418
}
403419
nsText.replaceCharacters(in: range, with: url.absoluteString)
404420
}

0 commit comments

Comments
 (0)