Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add filename variable #38

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ The main difference to your favorite image editor is that you can specify variab

Possible Variables:

* `$image` can contain only numbers (typically 1-5)
* `$language` contains every sub-folder name in your project folder (in this case `Sample Project`) excluding `backgrounds, device_frames and Export`
* `$image` can contain only numbers (typically 1-5).
* `$language` contains every sub-folder name in your project folder (in this case `Sample Project`) excluding `backgrounds, device_frames and Export`.
* `$filename` contains the current document name.

In the screenshot below the file is: `$language/iPhone SE-$image.png`. This is automatically translated to `en-US/iPhone SE-1.png` and this file is then rendered. For German this would for example be translated to `de-DE/iPhone SE-1.png`.

Expand Down Expand Up @@ -87,3 +88,4 @@ Please keep in mind that this tool was made to automate screenshots for a very s
* For better overview output is set to `Export/$language/iPhone SE-$image framed.png`

Screenshot Framer is brought to you by [IdeasOnCanvas GmbH](https://ideasoncanvas.com), the creator of [MindNode for iOS, macOS & watchOS](https://mindnode.com).
®
2 changes: 0 additions & 2 deletions Screenshot Framer CLI/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ struct ScreenshotFramer: ParsableCommand {
abstract: "A Swift command-line tool to frame localised screenshots for the AppStore",
version: "2.0.1",
subcommands: [Export.self, Website.self])

init() { }
}

ScreenshotFramer.main()
36 changes: 20 additions & 16 deletions Screenshot Framer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -360,14 +360,14 @@
isa = PBXNativeTarget;
buildConfigurationList = CD5EE04F1FCD557200AD2ED7 /* Build configuration list for PBXNativeTarget "Screenshot Framer" */;
buildPhases = (
CDAEE1FC1FED46EE00F4B1BA /* Swift Lint */,
CD5EE0381FCD557200AD2ED7 /* Sources */,
CD5EE0391FCD557200AD2ED7 /* Frameworks */,
CD5EE03A1FCD557200AD2ED7 /* Resources */,
);
buildRules = (
);
dependencies = (
CD61A6712AE8DEF1001F2DD8 /* PBXTargetDependency */,
);
name = "Screenshot Framer";
packageProductDependencies = (
Expand Down Expand Up @@ -461,6 +461,7 @@
packageReferences = (
CDD14C6E274F9C2C00D06720 /* XCRemoteSwiftPackageReference "swift-argument-parser" */,
CDD14C7D274FB60400D06720 /* XCRemoteSwiftPackageReference "SwiftSoup" */,
CD61A66F2AE8DEE7001F2DD8 /* XCRemoteSwiftPackageReference "SwiftLintPlugin" */,
);
productRefGroup = CD5EE03D1FCD557200AD2ED7 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -514,20 +515,6 @@
shellPath = /bin/sh;
shellScript = "# Swift Lint\nexec swiftlint\n";
};
CDAEE1FC1FED46EE00F4B1BA /* Swift Lint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Swift Lint";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Swift Lint\nexec swiftlint\n";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand Down Expand Up @@ -610,6 +597,10 @@
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
CD61A6712AE8DEF1001F2DD8 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
productRef = CD61A6702AE8DEF1001F2DD8 /* SwiftLint */;
};
CDFF699B1FD827B800E652EE /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = CD5EE03B1FCD557200AD2ED7 /* Screenshot Framer */;
Expand Down Expand Up @@ -906,6 +897,14 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
CD61A66F2AE8DEE7001F2DD8 /* XCRemoteSwiftPackageReference "SwiftLintPlugin" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/lukepistrol/SwiftLintPlugin.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.53.0;
};
};
CDD14C6E274F9C2C00D06720 /* XCRemoteSwiftPackageReference "swift-argument-parser" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/apple/swift-argument-parser.git";
Expand All @@ -925,6 +924,11 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
CD61A6702AE8DEF1001F2DD8 /* SwiftLint */ = {
isa = XCSwiftPackageProductDependency;
package = CD61A66F2AE8DEE7001F2DD8 /* XCRemoteSwiftPackageReference "SwiftLintPlugin" */;
productName = "plugin:SwiftLint";
};
CDD14C72274F9C3900D06720 /* ArgumentParser */ = {
isa = XCSwiftPackageProductDependency;
package = CDD14C6E274F9C2C00D06720 /* XCRemoteSwiftPackageReference "swift-argument-parser" */;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
{
"object": {
"pins": [
{
"package": "swift-argument-parser",
"repositoryURL": "https://github.com/apple/swift-argument-parser.git",
"state": {
"branch": null,
"revision": "e1465042f195f374b94f915ba8ca49de24300a0d",
"version": "1.0.2"
}
},
{
"package": "SwiftSoup",
"repositoryURL": "https://github.com/scinfu/SwiftSoup.git",
"state": {
"branch": null,
"revision": "02c63b7be50bda384f22c56c64d347231754a07e",
"version": "2.3.3"
}
"pins" : [
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
"revision" : "e1465042f195f374b94f915ba8ca49de24300a0d",
"version" : "1.0.2"
}
]
},
"version": 1
},
{
"identity" : "swiftlintplugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/lukepistrol/SwiftLintPlugin.git",
"state" : {
"revision" : "ea918d6d5988407b24c2efad7722560752b1638a",
"version" : "0.53.0"
}
},
{
"identity" : "swiftsoup",
"kind" : "remoteSourceControl",
"location" : "https://github.com/scinfu/SwiftSoup.git",
"state" : {
"revision" : "02c63b7be50bda384f22c56c64d347231754a07e",
"version" : "2.3.3"
}
}
],
"version" : 2
}
Original file line number Diff line number Diff line change
Expand Up @@ -371,14 +371,15 @@ extension ContentViewController: ExportControllerDelegate {

DispatchQueue.main.async {
progressWindowController.progress = progress
}

if progress == 1.0 {
guard let mainWindow = self.windowController?.window else { return }
guard let progressWindow = self.progressWindowController?.window else { return }
if progress == 1.0 {
guard let mainWindow = self.windowController?.window else { return }
guard let progressWindow = self.progressWindowController?.window else { return }

DispatchQueue.main.async {
mainWindow.endSheet(progressWindow, returnCode: .OK)
DispatchQueue.main.async {
mainWindow.endSheet(progressWindow, returnCode: .OK)
self.progressWindowController = nil
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import Foundation

/**
* This class stores properties that are not known on init
* projectURL ist only set after a new document is saved
* most classes need the projectURL property but not directly
* projectRoot ist only set after a new document is saved
* most classes need the projectRoot property but not directly
* on init but later eg export
*/
final class FileCapsule {

var projectURL: URL?
var projectRoot: URL?
var projectFile: URL?
}


Expand All @@ -42,7 +43,11 @@ final class FileController {
var file = object.file.replacingOccurrences(of: "$image", with: "\(viewState.imageNumber)")
file = file.replacingOccurrences(of: "$language", with: viewState.language)

let absoluteURL = self.fileCapsule.projectURL?.appendingPathComponent(file)
if let projectURL = fileCapsule.projectFile {
file = file.replacingOccurrences(of: "$filename", with: projectURL.deletingPathExtension().lastPathComponent)
}

let absoluteURL = self.fileCapsule.projectRoot?.appendingPathComponent(file)
return absoluteURL
}

Expand All @@ -55,10 +60,14 @@ final class FileController {
}

func outputURL(for layerState: LayerState, viewState: ViewState) -> URL? {
guard let base = self.fileCapsule.projectURL else { return nil }
guard let base = self.fileCapsule.projectRoot else { return nil }
var file = layerState.outputConfig.output.replacingOccurrences(of: "$image", with: "\(viewState.imageNumber)")
file = file.replacingOccurrences(of: "$language", with: viewState.language)

if let projectFile = fileCapsule.projectFile {
file = file.replacingOccurrences(of: "$filename", with: projectFile.deletingPathExtension().lastPathComponent)
}

return base.appendingPathComponent(file)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class LanguageController {

func allLanguages(prefered: String? = nil) -> [String] {
let fileManager = FileManager()
guard let projectURL = self.fileCapsule.projectURL else { return [] }
guard let projectURL = self.fileCapsule.projectRoot else { return [] }
guard let contents = try? fileManager.contentsOfDirectory(at: projectURL, includingPropertiesForKeys: nil, options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles]) else { return [] }

let allLanguages = contents.filter { file in
Expand Down
74 changes: 43 additions & 31 deletions Screenshot Framer/Document.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,21 @@ final class Document: NSDocument {
}

override func prepareSavePanel(_ savePanel: NSSavePanel) -> Bool {
let accessoryView = NSView(frame: CGRect(x: 0, y: 0, width: savePanel.frame.width, height: 60))
let detailLabel = NSTextField(labelWithString: "Screenshot Framer needs a project directory to start.\nYou will be able to access all files in this directory but no files outside of this directory")
let accessoryView = NSView(frame: .zero)
accessoryView.translatesAutoresizingMaskIntoConstraints = false
let detailLabel = NSTextField(labelWithString: "Screenshot Framer needs a project directory to start.\nYou will be able to access all files in this directory but no files outside of this directory.")
detailLabel.translatesAutoresizingMaskIntoConstraints = false

detailLabel.frame = CGRect(x: 0, y: 15, width: savePanel.frame.width, height: detailLabel.frame.height)
detailLabel.alignment = .center
detailLabel.maximumNumberOfLines = 2

accessoryView.addSubview(detailLabel)
NSLayoutConstraint.activate([
detailLabel.topAnchor.constraint(equalTo: accessoryView.topAnchor, constant: 15),
detailLabel.leadingAnchor.constraint(equalTo: accessoryView.leadingAnchor),
detailLabel.trailingAnchor.constraint(equalTo: accessoryView.trailingAnchor),
detailLabel.bottomAnchor.constraint(equalTo: accessoryView.bottomAnchor, constant: -15)
])
savePanel.accessoryView = accessoryView

return true
Expand All @@ -67,40 +74,13 @@ final class Document: NSDocument {
self.save(withDelegate: self, didSave: #selector(Document.document(_:didSave:contextInfo:)), contextInfo: nil)
}

@objc
func document(_ document: NSDocument, didSave: Bool, contextInfo: UnsafeRawPointer) {
switch didSave {
case true:
self.fileCapsule.projectURL = self.projectURL
case false:
self.close()
}
}


override func canClose(withDelegate delegate: Any, shouldClose shouldCloseSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
self.layerStateHistory.discardRedoHistory()
self.save(nil)
self.close()
self.timeTravelWindowController.close()
}


// Responder Chain

@IBAction func showTimeTravelWindow(_ sender: AnyObject?) {
self.timeTravelWindowController.window?.orderFront(self)

if sender != nil {
UserDefaults.standard.showTimeTravelWindow = true
}
}

@IBAction func discardRedoHistory(_ sender: AnyObject?) {
// Discussion: show warning
self.layerStateHistory.discardRedoHistory()
}

override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
if menuItem.action == #selector(showTimeTravelWindow) {
return self.timeTravelWindowController.window?.isVisible == false
Expand All @@ -113,6 +93,22 @@ final class Document: NSDocument {
return super.validateMenuItem(menuItem)
}

// MARK: - Responder Chain

@IBAction
func showTimeTravelWindow(_ sender: AnyObject?) {
self.timeTravelWindowController.window?.orderFront(self)

if sender != nil {
UserDefaults.standard.showTimeTravelWindow = true
}
}

@IBAction
func discardRedoHistory(_ sender: AnyObject?) {
// Discussion: show warning
self.layerStateHistory.discardRedoHistory()
}

// MARK: - Read/Write

Expand All @@ -123,7 +119,8 @@ final class Document: NSDocument {
}

override func read(from data: Data, ofType typeName: String) throws {
self.fileCapsule.projectURL = self.projectURL
self.fileCapsule.projectRoot = self.projectURL
self.fileCapsule.projectFile = self.fileURL

let decoder = JSONDecoder()
let layers = try decoder.decode([LayerState].self, from: data)
Expand All @@ -145,3 +142,18 @@ extension Document: LayerStateHistoryDelegate {
contentViewController.reloadLayout()
}
}

// MARK: - Private

private extension Document {

@objc
func document(_ document: NSDocument, didSave: Bool, contextInfo: UnsafeRawPointer) {
if didSave {
self.fileCapsule.projectRoot = self.projectURL
self.fileCapsule.projectFile = self.fileURL
} else {
self.close()
}
}
}
2 changes: 1 addition & 1 deletion Screenshot Framer/Supporting Files/Code/Sugar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ extension Array where Element == String {
var newValues: [String] = []

for element in self {
if blacklist.contains(where: { (caseSensitive ? $0 : $0.lowercased()) == (caseSensitive ? element : element.lowercased()) }) == false {
if blacklist.contains(where: { (caseSensitive ? $0 : $0.lowercased()) == (caseSensitive ? element : element.lowercased()) }) == false { // swiftlint:disable:this for_where
// No match in blacklist -> add item
newValues.append(element)
}
Expand Down