Publish v1.0
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit
Reviewed-on: #1
This commit is contained in:
@ -0,0 +1,56 @@
|
||||
//
|
||||
// FileManagerExtensions.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension FileManager {
|
||||
func getAllRegularFileIn(directory: String) -> [String] {
|
||||
var files = [String]()
|
||||
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
||||
let error = ImagesError.unknown("Cannot enumerate file in \(directory)")
|
||||
print(error.localizedDescription)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
|
||||
for case let fileURL as URL in enumerator {
|
||||
do {
|
||||
let fileAttributes = try fileURL.resourceValues(forKeys:[.isRegularFileKey])
|
||||
if fileAttributes.isRegularFile! {
|
||||
files.append(fileURL.relativePath)
|
||||
}
|
||||
} catch {
|
||||
let error = ImagesError.getFileAttributed(fileURL.relativePath, error.localizedDescription)
|
||||
print(error.localizedDescription)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
func getAllImageSetFolderIn(directory: String) -> [String] {
|
||||
var files = [String]()
|
||||
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isDirectoryKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
||||
let error = ImagesError.unknown("Cannot enumerate imageset directory in \(directory)")
|
||||
print(error.localizedDescription)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
|
||||
for case let fileURL as URL in enumerator {
|
||||
do {
|
||||
let fileAttributes = try fileURL.resourceValues(forKeys:[.isDirectoryKey])
|
||||
if fileAttributes.isDirectory! && fileURL.lastPathComponent.hasSuffix(".imageset") {
|
||||
files.append(fileURL.lastPathComponent)
|
||||
}
|
||||
} catch {
|
||||
let error = ImagesError.getFileAttributed(fileURL.relativePath, error.localizedDescription)
|
||||
print(error.localizedDescription)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
}
|
||||
return files
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
//
|
||||
// ImageExtensionGenerator.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 14/02/2022.
|
||||
//
|
||||
|
||||
import ToolCore
|
||||
import Foundation
|
||||
|
||||
class ImageExtensionGenerator {
|
||||
|
||||
// MARK: - pragm
|
||||
|
||||
static func generateExtensionFile(images: [ParsedImage],
|
||||
staticVar: Bool,
|
||||
inputFilename: String,
|
||||
extensionName: String,
|
||||
extensionFilePath: String) {
|
||||
// Create extension conten1t
|
||||
let extensionContent = Self.getExtensionContent(images: images,
|
||||
staticVar: staticVar,
|
||||
extensionName: extensionName,
|
||||
inputFilename: inputFilename)
|
||||
|
||||
// Write content
|
||||
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
||||
do {
|
||||
try extensionContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
||||
} catch (let error) {
|
||||
let error = ImagesError.writeFile(extensionFilePath, error.localizedDescription)
|
||||
print(error.localizedDescription)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Extension content
|
||||
|
||||
static func getExtensionContent(images: [ParsedImage], staticVar: Bool, extensionName: String, inputFilename: String) -> String {
|
||||
[
|
||||
Self.getHeader(inputFilename: inputFilename, extensionClassname: extensionName),
|
||||
Self.getProperties(images: images, staticVar: staticVar),
|
||||
Self.getFooter()
|
||||
]
|
||||
.joined(separator: "\n")
|
||||
}
|
||||
|
||||
// MARK: - Extension part
|
||||
|
||||
private static func getHeader(inputFilename: String, extensionClassname: String) -> String {
|
||||
"""
|
||||
// Generated by ResgenSwift.\(Images.toolName) \(ResgenSwiftVersion)
|
||||
// Images from \(inputFilename)
|
||||
|
||||
import UIKit
|
||||
|
||||
extension \(extensionClassname) {
|
||||
"""
|
||||
}
|
||||
|
||||
private static func getProperties(images: [ParsedImage], staticVar: Bool) -> String {
|
||||
if staticVar {
|
||||
return images
|
||||
.map { "\n\($0.getStaticImageProperty())" }
|
||||
.joined(separator: "\n")
|
||||
}
|
||||
return images
|
||||
.map { "\n\($0.getImageProperty())" }
|
||||
.joined(separator: "\n")
|
||||
}
|
||||
|
||||
private static func getFooter() -> String {
|
||||
"""
|
||||
}
|
||||
"""
|
||||
}
|
||||
}
|
171
Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift
Normal file
171
Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift
Normal file
@ -0,0 +1,171 @@
|
||||
//
|
||||
// XcassetsGenerator.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ToolCore
|
||||
|
||||
class XcassetsGenerator {
|
||||
|
||||
static let outputImageExtension = "png"
|
||||
|
||||
let forceGeneration: Bool
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
init(forceGeneration: Bool) {
|
||||
self.forceGeneration = forceGeneration
|
||||
}
|
||||
|
||||
// MARK: - Assets generation
|
||||
|
||||
func generateXcassets(inputPath: String, imagesToGenerate: [ParsedImage], xcassetsPath: String) {
|
||||
let fileManager = FileManager()
|
||||
let svgConverter = Images.getSvgConverterPath()
|
||||
let allSubFiles = fileManager.getAllRegularFileIn(directory: inputPath)
|
||||
|
||||
var generatedAssetsPaths = [String]()
|
||||
|
||||
// Generate new assets
|
||||
imagesToGenerate.forEach { parsedImage in
|
||||
// Get image path
|
||||
let imageData: (path: String, ext: String) = {
|
||||
for subfile in allSubFiles {
|
||||
if subfile.hasSuffix("/" + parsedImage.name + ".svg") {
|
||||
return (subfile, "svg")
|
||||
}
|
||||
if subfile.hasSuffix("/" + parsedImage.name + ".png") {
|
||||
return (subfile, "png")
|
||||
}
|
||||
if subfile.hasSuffix("/" + parsedImage.name + ".jpg") {
|
||||
return (subfile, "jpg")
|
||||
}
|
||||
if subfile.hasSuffix("/" + parsedImage.name + ".jepg") {
|
||||
return (subfile, "jepg")
|
||||
}
|
||||
}
|
||||
let error = ImagesError.unknownImageExtension(parsedImage.name)
|
||||
print(error.localizedDescription)
|
||||
Images.exit(withError: error)
|
||||
}()
|
||||
|
||||
// Create imageset folder name
|
||||
let imagesetName = "\(parsedImage.name).imageset"
|
||||
let imagesetPath = "\(xcassetsPath)/\(imagesetName)"
|
||||
|
||||
// Store managed images path
|
||||
generatedAssetsPaths.append(imagesetName)
|
||||
|
||||
// Generate output images path
|
||||
let output1x = "\(imagesetPath)/\(parsedImage.name).\(XcassetsGenerator.outputImageExtension)"
|
||||
let output2x = "\(imagesetPath)/\(parsedImage.name)@2x.\(XcassetsGenerator.outputImageExtension)"
|
||||
let output3x = "\(imagesetPath)/\(parsedImage.name)@3x.\(XcassetsGenerator.outputImageExtension)"
|
||||
|
||||
// Check if we need to convert image
|
||||
guard self.shouldGenerate(inputImagePath: imageData.path, xcassetImagePath: output1x) else {
|
||||
//print("\(parsedImage.name) -> Not regenerating")
|
||||
return
|
||||
}
|
||||
|
||||
// Create imageset folder
|
||||
if fileManager.fileExists(atPath: imagesetPath) == false {
|
||||
do {
|
||||
try fileManager.createDirectory(atPath: imagesetPath,
|
||||
withIntermediateDirectories: true)
|
||||
} catch {
|
||||
let error = ImagesError.createAssetFolder(imagesetPath)
|
||||
print(error.localizedDescription)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
}
|
||||
|
||||
// Convert image
|
||||
let convertArguments = parsedImage.convertArguments
|
||||
if imageData.ext == "svg" {
|
||||
// /usr/local/bin/rsvg-convert path/to/image.png -w 200 -h 300 -o path/to/output.png
|
||||
// /usr/local/bin/rsvg-convert path/to/image.png -w 200 -o path/to/output.png
|
||||
// /usr/local/bin/rsvg-convert path/to/image.png -h 300 -o path/to/output.png
|
||||
var command1x = ["\(svgConverter)", "\(imageData.path)"]
|
||||
var command2x = ["\(svgConverter)", "\(imageData.path)"]
|
||||
var command3x = ["\(svgConverter)", "\(imageData.path)"]
|
||||
|
||||
self.addConvertArgument(command: &command1x, convertArgument: convertArguments.x1)
|
||||
self.addConvertArgument(command: &command2x, convertArgument: convertArguments.x2)
|
||||
self.addConvertArgument(command: &command3x, convertArgument: convertArguments.x3)
|
||||
|
||||
command1x.append(contentsOf: ["-o", output1x])
|
||||
command2x.append(contentsOf: ["-o", output2x])
|
||||
command3x.append(contentsOf: ["-o", output3x])
|
||||
|
||||
Shell.shell(command1x)
|
||||
Shell.shell(command2x)
|
||||
Shell.shell(command3x)
|
||||
} else {
|
||||
// convert path/to/image.png -resize 200x300 path/to/output.png
|
||||
// convert path/to/image.png -resize 200x path/to/output.png
|
||||
// convert path/to/image.png -resize x300 path/to/output.png
|
||||
Shell.shell(["convert", "\(imageData.path)",
|
||||
"-resize", "\(convertArguments.x1.width ?? "")x\(convertArguments.x1.height ?? "")",
|
||||
output1x])
|
||||
Shell.shell(["convert", "\(imageData.path)",
|
||||
"-resize", "\(convertArguments.x2.width ?? "")x\(convertArguments.x2.height ?? "")",
|
||||
output2x])
|
||||
Shell.shell(["convert", "\(imageData.path)",
|
||||
"-resize", "\(convertArguments.x3.width ?? "")x\(convertArguments.x3.height ?? "")",
|
||||
output3x])
|
||||
}
|
||||
|
||||
// Write Content.json
|
||||
let imagesetContentJson = parsedImage.contentJson
|
||||
let contentJsonFilePath = "\(imagesetPath)/Contents.json"
|
||||
|
||||
let contentJsonFilePathURL = URL(fileURLWithPath: contentJsonFilePath)
|
||||
try! imagesetContentJson.write(to: contentJsonFilePathURL, atomically: false, encoding: .utf8)
|
||||
|
||||
print("\(parsedImage.name) -> Generated")
|
||||
}
|
||||
|
||||
// Success info
|
||||
let generatedAssetsCount = generatedAssetsPaths.count
|
||||
print("Images generated: \(generatedAssetsCount)")
|
||||
|
||||
// Delete old assets
|
||||
let allImagesetName = Set(fileManager.getAllImageSetFolderIn(directory: xcassetsPath))
|
||||
let imagesetToRemove = allImagesetName.subtracting(Set(generatedAssetsPaths))
|
||||
|
||||
imagesetToRemove.forEach {
|
||||
print("Will remove: \($0)")
|
||||
}
|
||||
|
||||
imagesetToRemove.forEach { itemToRemove in
|
||||
try! fileManager.removeItem(atPath: "\(xcassetsPath)/\(itemToRemove)")
|
||||
}
|
||||
print("Removed \(imagesetToRemove.count) images")
|
||||
}
|
||||
|
||||
// MARK: - Helpers: SVG command
|
||||
|
||||
private func addConvertArgument(command: inout [String], convertArgument: ConvertArgument) {
|
||||
if let width = convertArgument.width, width.isEmpty == false {
|
||||
command.append("-w")
|
||||
command.append("\(width)")
|
||||
}
|
||||
if let height = convertArgument.height, height.isEmpty == false {
|
||||
command.append("-h")
|
||||
command.append("\(height)")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helpers: bypass generation
|
||||
|
||||
private func shouldGenerate(inputImagePath: String, xcassetImagePath: String) -> Bool {
|
||||
if forceGeneration {
|
||||
return true
|
||||
}
|
||||
|
||||
return GeneratorChecker.isFile(inputImagePath, moreRecenThan: xcassetImagePath)
|
||||
}
|
||||
}
|
108
Sources/ResgenSwift/Images/Images.swift
Normal file
108
Sources/ResgenSwift/Images/Images.swift
Normal file
@ -0,0 +1,108 @@
|
||||
//
|
||||
// Images.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import ToolCore
|
||||
import Foundation
|
||||
import ArgumentParser
|
||||
|
||||
struct Images: ParsableCommand {
|
||||
|
||||
// MARK: - CommandConfiguration
|
||||
|
||||
static var configuration = CommandConfiguration(
|
||||
abstract: "A utility for generate images and an extension to access them easily.",
|
||||
version: ResgenSwiftVersion
|
||||
)
|
||||
|
||||
// MARK: - Static
|
||||
|
||||
static let toolName = "Images"
|
||||
static let defaultExtensionName = "UIImage"
|
||||
|
||||
// MARK: - Command Options
|
||||
|
||||
@OptionGroup var options: ImagesOptions
|
||||
|
||||
// MARK: - Run
|
||||
|
||||
mutating func run() {
|
||||
print("[\(Self.toolName)] Starting images generation")
|
||||
print("[\(Self.toolName)] Will use inputFile \(options.inputFile) to generate images in xcassets \(options.xcassetsPath)")
|
||||
|
||||
// Check requirements
|
||||
guard checkRequirements() else { return }
|
||||
|
||||
print("[\(Self.toolName)] Will generate images")
|
||||
|
||||
// Parse input file
|
||||
let imagesToGenerate = ImageFileParser.parse(options.inputFile, platform: PlatormTag.ios)
|
||||
|
||||
// Generate xcassets files
|
||||
let inputFolder = URL(fileURLWithPath: options.inputFile)
|
||||
.deletingLastPathComponent()
|
||||
.relativePath
|
||||
|
||||
let xcassetsGenerator = XcassetsGenerator(forceGeneration: options.forceExecutionAndGeneration)
|
||||
xcassetsGenerator.generateXcassets(inputPath: inputFolder,
|
||||
imagesToGenerate: imagesToGenerate,
|
||||
xcassetsPath: options.xcassetsPath)
|
||||
|
||||
// Generate extension
|
||||
ImageExtensionGenerator.generateExtensionFile(images: imagesToGenerate,
|
||||
staticVar: options.staticMembers,
|
||||
inputFilename: options.inputFilenameWithoutExt,
|
||||
extensionName: options.extensionName,
|
||||
extensionFilePath: options.extensionFilePath)
|
||||
|
||||
|
||||
print("[\(Self.toolName)] Images generated")
|
||||
}
|
||||
|
||||
// MARK: - Requirements
|
||||
|
||||
private func checkRequirements() -> Bool {
|
||||
guard options.forceExecutionAndGeneration == false else {
|
||||
return true
|
||||
}
|
||||
|
||||
let fileManager = FileManager()
|
||||
|
||||
// Input file
|
||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||
let error = ImagesError.fileNotExists(options.inputFile)
|
||||
print(error.localizedDescription)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
|
||||
// RSVG-Converter
|
||||
_ = Images.getSvgConverterPath()
|
||||
|
||||
// Check if needed to regenerate
|
||||
guard GeneratorChecker.shouldGenerate(force: options.forceExecution,
|
||||
inputFilePath: options.inputFile,
|
||||
extensionFilePath: options.extensionFilePath) else {
|
||||
print("[\(Self.toolName)] Images are already up to date :) ")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
@discardableResult
|
||||
static func getSvgConverterPath() -> String {
|
||||
let taskSvgConverter = Shell.shell(["which", "rsvg-convert"])
|
||||
if taskSvgConverter.terminationStatus == 0 {
|
||||
return taskSvgConverter.output!.removeCharacters(from: CharacterSet.whitespacesAndNewlines)
|
||||
}
|
||||
|
||||
let error = ImagesError.rsvgConvertNotFound
|
||||
print(error.localizedDescription)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
}
|
47
Sources/ResgenSwift/Images/ImagesError.swift
Normal file
47
Sources/ResgenSwift/Images/ImagesError.swift
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// ImagesError.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ImagesError: Error {
|
||||
case inputFolderNotFound(String)
|
||||
case fileNotExists(String)
|
||||
case unknownImageExtension(String)
|
||||
case getFileAttributed(String, String)
|
||||
case rsvgConvertNotFound
|
||||
case writeFile(String, String)
|
||||
case createAssetFolder(String)
|
||||
case unknown(String)
|
||||
|
||||
var localizedDescription: String {
|
||||
switch self {
|
||||
case .inputFolderNotFound(let inputFolder):
|
||||
return " error:[\(Images.toolName)] Input folder not found: \(inputFolder)"
|
||||
|
||||
case .fileNotExists(let filename):
|
||||
return " error:[\(Images.toolName)] File \(filename) does not exists"
|
||||
|
||||
case .unknownImageExtension(let filename):
|
||||
return " error:[\(Images.toolName)] File \(filename) have an unhandled file extension. Cannot generate image."
|
||||
|
||||
case .getFileAttributed(let filename, let errorDescription):
|
||||
return " error:[\(Images.toolName)] Getting file attributes of \(filename) failed with error: \(errorDescription)"
|
||||
|
||||
case .rsvgConvertNotFound:
|
||||
return " error:[\(Images.toolName)] Can't find rsvg-convert (can be installed with 'brew remove imagemagick && brew install imagemagick --with-librsvg')"
|
||||
|
||||
case .writeFile(let subErrorDescription, let filename):
|
||||
return " error:[\(Images.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
||||
|
||||
case .createAssetFolder(let folder):
|
||||
return "error:[\(Colors.toolName)] An error occured while creating folder `\(folder)`"
|
||||
|
||||
case .unknown(let errorDescription):
|
||||
return " error:[\(Images.toolName)] Unknown error: \(errorDescription)"
|
||||
}
|
||||
}
|
||||
}
|
56
Sources/ResgenSwift/Images/ImagesOptions.swift
Normal file
56
Sources/ResgenSwift/Images/ImagesOptions.swift
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// ImagiumOptions.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ArgumentParser
|
||||
|
||||
struct ImagesOptions: ParsableArguments {
|
||||
@Flag(name: .customShort("f"), help: "Should force script execution")
|
||||
var forceExecution = false
|
||||
|
||||
@Flag(name: .customShort("F"), help: "Regenerate all images")
|
||||
var forceExecutionAndGeneration = false
|
||||
|
||||
@Argument(help: "Input files where strings ared defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||
var inputFile: String
|
||||
|
||||
@Option(help: "Xcassets path where to generate images.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||
var xcassetsPath: String
|
||||
|
||||
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||
var extensionOutputPath: String
|
||||
|
||||
@Option(help: "Tell if it will generate static properties or not")
|
||||
var staticMembers: Bool = false
|
||||
|
||||
@Option(help: "Extension name. If not specified, it will generate an UIImage extension. Using default extension name will generate static property.")
|
||||
var extensionName: String = Images.defaultExtensionName
|
||||
|
||||
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Image{extensionSuffix}.swift")
|
||||
var extensionSuffix: String?
|
||||
}
|
||||
|
||||
// MARK: - Computed var
|
||||
|
||||
extension ImagesOptions {
|
||||
var extensionFileName: String {
|
||||
if let extensionSuffix = extensionSuffix {
|
||||
return "\(extensionName)+\(extensionSuffix).swift"
|
||||
}
|
||||
return "\(extensionName).swift"
|
||||
}
|
||||
|
||||
var extensionFilePath: String {
|
||||
"\(extensionOutputPath)/\(extensionFileName)"
|
||||
}
|
||||
|
||||
var inputFilenameWithoutExt: String {
|
||||
URL(fileURLWithPath: inputFile)
|
||||
.deletingPathExtension()
|
||||
.lastPathComponent
|
||||
}
|
||||
}
|
13
Sources/ResgenSwift/Images/Model/ConvertArgument.swift
Normal file
13
Sources/ResgenSwift/Images/Model/ConvertArgument.swift
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// ConvertArgument.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct ConvertArgument {
|
||||
let width: String?
|
||||
let height: String?
|
||||
}
|
90
Sources/ResgenSwift/Images/Model/ParsedImage.swift
Normal file
90
Sources/ResgenSwift/Images/Model/ParsedImage.swift
Normal file
@ -0,0 +1,90 @@
|
||||
//
|
||||
// ParsedImage.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct ParsedImage {
|
||||
let name: String
|
||||
let tags: String
|
||||
let width: Int
|
||||
let height: Int
|
||||
|
||||
// MARK: - Convert
|
||||
|
||||
var convertArguments: (x1: ConvertArgument, x2: ConvertArgument, x3: ConvertArgument) {
|
||||
var width1x = ""
|
||||
var height1x = ""
|
||||
var width2x = ""
|
||||
var height2x = ""
|
||||
var width3x = ""
|
||||
var height3x = ""
|
||||
|
||||
if width != -1 {
|
||||
width1x = "\(width)"
|
||||
width2x = "\(width * 2)"
|
||||
width3x = "\(width * 3)"
|
||||
}
|
||||
|
||||
if height != -1 {
|
||||
height1x = "\(height)"
|
||||
height2x = "\(height * 2)"
|
||||
height3x = "\(height * 3)"
|
||||
}
|
||||
|
||||
return (x1: ConvertArgument(width: width1x, height: height1x),
|
||||
x2: ConvertArgument(width: width2x, height: height2x),
|
||||
x3: ConvertArgument(width: width3x, height: height3x))
|
||||
}
|
||||
|
||||
// MARK: - Assets
|
||||
|
||||
var contentJson: String {
|
||||
"""
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "\(name).\(XcassetsGenerator.outputImageExtension)"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "\(name)@2x.\(XcassetsGenerator.outputImageExtension)"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "\(name)@3x.\(XcassetsGenerator.outputImageExtension)"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "ResgenSwift-Imagium"
|
||||
}
|
||||
}
|
||||
"""
|
||||
}
|
||||
|
||||
// MARK: - Extension property
|
||||
|
||||
func getImageProperty() -> String {
|
||||
"""
|
||||
var \(name): UIImage {
|
||||
UIImage(named: "\(name)")!
|
||||
}
|
||||
"""
|
||||
}
|
||||
|
||||
func getStaticImageProperty() -> String {
|
||||
"""
|
||||
static var \(name): UIImage {
|
||||
UIImage(named: "\(name)")!
|
||||
}
|
||||
"""
|
||||
}
|
||||
}
|
13
Sources/ResgenSwift/Images/Model/PlatormTag.swift
Normal file
13
Sources/ResgenSwift/Images/Model/PlatormTag.swift
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// PlatormTag.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 29/08/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum PlatormTag: String {
|
||||
case droid = "d"
|
||||
case ios = "i"
|
||||
}
|
50
Sources/ResgenSwift/Images/Parser/ImageFileParser.swift
Normal file
50
Sources/ResgenSwift/Images/Parser/ImageFileParser.swift
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// ImageFileParser.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class ImageFileParser {
|
||||
|
||||
static func parse(_ inputFile: String, platform: PlatormTag) -> [ParsedImage] {
|
||||
let inputFileContent = try! String(contentsOfFile: inputFile, encoding: .utf8)
|
||||
let stringsByLines = inputFileContent.components(separatedBy: .newlines)
|
||||
|
||||
return Self.parseLines(stringsByLines, platform: platform)
|
||||
}
|
||||
|
||||
static func parseLines(_ lines: [String], platform: PlatormTag) -> [ParsedImage] {
|
||||
var imagesToGenerate = [ParsedImage]()
|
||||
|
||||
lines.forEach {
|
||||
guard $0.removeLeadingTrailingWhitespace().isEmpty == false, $0.first != "#" else {
|
||||
return
|
||||
}
|
||||
|
||||
let splittedLine = $0.split(separator: " ")
|
||||
|
||||
let width: Int = {
|
||||
if splittedLine[2] == "?" {
|
||||
return -1
|
||||
}
|
||||
return Int(splittedLine[2])!
|
||||
}()
|
||||
let height: Int = {
|
||||
if splittedLine[3] == "?" {
|
||||
return -1
|
||||
}
|
||||
return Int(splittedLine[3])!
|
||||
}()
|
||||
|
||||
let image = ParsedImage(name: String(splittedLine[1]), tags: String(splittedLine[0]), width: width, height: height)
|
||||
imagesToGenerate.append(image)
|
||||
}
|
||||
|
||||
return imagesToGenerate.filter {
|
||||
$0.tags.contains(platform.rawValue)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user