fastlane-plugin-wpmreleasetoolkit 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/an_localize_libs_action.rb +8 -3
  3. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_betabuild_prechecks.rb +8 -2
  4. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_release.rb +11 -4
  5. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_codefreeze_prechecks.rb +10 -4
  6. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/buildkite_trigger_build_action.rb +90 -0
  7. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/comment_on_pr.rb +89 -0
  8. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_release_action.rb +2 -0
  9. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/gp_downloadmetadata_action.rb +1 -1
  10. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_betabuild_prechecks.rb +8 -2
  11. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_bump_version_release.rb +10 -5
  12. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_codefreeze_prechecks.rb +10 -4
  13. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_download_strings_files_from_glotpress.rb +113 -0
  14. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_generate_strings_file_from_code.rb +115 -0
  15. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_lint_localizations.rb +5 -5
  16. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_localize_project.rb +6 -7
  17. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_merge_strings_files.rb +75 -0
  18. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_git_helper.rb +0 -20
  19. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_localize_helper.rb +8 -0
  20. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb +3 -0
  21. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +48 -8
  22. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/interactive_prompt_reminder.rb +93 -0
  23. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_git_helper.rb +3 -2
  24. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_l10n_helper.rb +108 -173
  25. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_l10n_linter_helper.rb +207 -0
  26. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/promo_screenshots_helper.rb +3 -3
  27. data/lib/fastlane/plugin/wpmreleasetoolkit/models/file_reference.rb +1 -4
  28. data/lib/fastlane/plugin/wpmreleasetoolkit/version.rb +1 -1
  29. metadata +26 -39
  30. data/bin/drawText +0 -20
  31. data/ext/drawText/drawText/Assets/style.css +0 -1
  32. data/ext/drawText/drawText/CoreTextStack.swift +0 -113
  33. data/ext/drawText/drawText/Helpers/CommandLineHelpers.swift +0 -36
  34. data/ext/drawText/drawText/Helpers/Extensions.swift +0 -27
  35. data/ext/drawText/drawText/Helpers/FileSystemHelper.swift +0 -24
  36. data/ext/drawText/drawText/Stylesheet.swift +0 -48
  37. data/ext/drawText/drawText/TextImage.swift +0 -100
  38. data/ext/drawText/drawText/main.swift +0 -61
  39. data/ext/drawText/drawText Tests/DigitParsingTests.swift +0 -21
  40. data/ext/drawText/drawText Tests/ExtensionsTests.swift +0 -5
  41. data/ext/drawText/drawText Tests/Info.plist +0 -22
  42. data/ext/drawText/drawText Tests/StylesheetTests.swift +0 -31
  43. data/ext/drawText/drawText Tests/Test Cases/default-stylesheet.txt +0 -10
  44. data/ext/drawText/drawText Tests/Test Cases/external-styles-sample.css +0 -3
  45. data/ext/drawText/drawText Tests/Test Cases/external-styles-test.txt +0 -13
  46. data/ext/drawText/drawText Tests/Test Cases/large-text-block.txt +0 -1
  47. data/ext/drawText/drawText Tests/Test Cases/regular-text-block.txt +0 -2
  48. data/ext/drawText/drawText Tests/Test Cases/rtl-text-block.txt +0 -2
  49. data/ext/drawText/drawText Tests/Test Cases/text-size-adjustment-test.txt +0 -10
  50. data/ext/drawText/drawText Tests/TextImageTests.swift +0 -99
  51. data/ext/drawText/drawText Tests/drawText_Tests.swift +0 -14
  52. data/ext/drawText/drawText.xcodeproj/project.pbxproj +0 -508
  53. data/ext/drawText/drawText.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  54. data/ext/drawText/drawText.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  55. data/ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText Tests.xcscheme +0 -57
  56. data/ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText.xcscheme +0 -109
  57. data/ext/drawText/extconf.rb +0 -36
  58. data/ext/drawText/makefile.example +0 -8
  59. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_merge_translators_strings.rb +0 -106
  60. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_update_metadata.rb +0 -52
  61. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_merge_translators_strings.rb +0 -93
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-wpmreleasetoolkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorenzo Mattei
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-20 00:00:00.000000000 Z
11
+ date: 2022-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diffy
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '4.18'
55
+ - !ruby/object:Gem::Dependency
56
+ name: buildkit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.4'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.4'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: git
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -340,43 +354,12 @@ dependencies:
340
354
  version: '1.10'
341
355
  description:
342
356
  email: lore.mattei@gmail.com
343
- executables:
344
- - drawText
345
- extensions:
346
- - ext/drawText/extconf.rb
357
+ executables: []
358
+ extensions: []
347
359
  extra_rdoc_files: []
348
360
  files:
349
361
  - LICENSE
350
362
  - README.md
351
- - bin/drawText
352
- - ext/drawText/drawText Tests/DigitParsingTests.swift
353
- - ext/drawText/drawText Tests/ExtensionsTests.swift
354
- - ext/drawText/drawText Tests/Info.plist
355
- - ext/drawText/drawText Tests/StylesheetTests.swift
356
- - ext/drawText/drawText Tests/Test Cases/default-stylesheet.txt
357
- - ext/drawText/drawText Tests/Test Cases/external-styles-sample.css
358
- - ext/drawText/drawText Tests/Test Cases/external-styles-test.txt
359
- - ext/drawText/drawText Tests/Test Cases/large-text-block.txt
360
- - ext/drawText/drawText Tests/Test Cases/regular-text-block.txt
361
- - ext/drawText/drawText Tests/Test Cases/rtl-text-block.txt
362
- - ext/drawText/drawText Tests/Test Cases/text-size-adjustment-test.txt
363
- - ext/drawText/drawText Tests/TextImageTests.swift
364
- - ext/drawText/drawText Tests/drawText_Tests.swift
365
- - ext/drawText/drawText.xcodeproj/project.pbxproj
366
- - ext/drawText/drawText.xcodeproj/project.xcworkspace/contents.xcworkspacedata
367
- - ext/drawText/drawText.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
368
- - ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText Tests.xcscheme
369
- - ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText.xcscheme
370
- - ext/drawText/drawText/Assets/style.css
371
- - ext/drawText/drawText/CoreTextStack.swift
372
- - ext/drawText/drawText/Helpers/CommandLineHelpers.swift
373
- - ext/drawText/drawText/Helpers/Extensions.swift
374
- - ext/drawText/drawText/Helpers/FileSystemHelper.swift
375
- - ext/drawText/drawText/Stylesheet.swift
376
- - ext/drawText/drawText/TextImage.swift
377
- - ext/drawText/drawText/main.swift
378
- - ext/drawText/extconf.rb
379
- - ext/drawText/makefile.example
380
363
  - lib/fastlane/plugin/wpmreleasetoolkit.rb
381
364
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/README.md
382
365
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/android/an_localize_libs_action.rb
@@ -400,14 +383,14 @@ files:
400
383
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_app_version.rb
401
384
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_release_version.rb
402
385
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_hotifx_prechecks.rb
403
- - lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_merge_translators_strings.rb
404
386
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_tag_build.rb
405
- - lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_update_metadata.rb
406
387
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_update_release_notes.rb
388
+ - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/buildkite_trigger_build_action.rb
407
389
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/check_for_toolkit_updates_action.rb
408
390
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/check_translation_progress.rb
409
391
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/circleci_trigger_job_action.rb
410
392
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/close_milestone_action.rb
393
+ - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/comment_on_pr.rb
411
394
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb
412
395
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_release_action.rb
413
396
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/extract_release_notes_for_version_action.rb
@@ -437,15 +420,17 @@ files:
437
420
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_codefreeze_prechecks.rb
438
421
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_completecodefreeze_prechecks.rb
439
422
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_current_branch_is_hotfix.rb
423
+ - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_download_strings_files_from_glotpress.rb
440
424
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_final_tag.rb
441
425
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_finalize_prechecks.rb
426
+ - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_generate_strings_file_from_code.rb
442
427
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_get_app_version.rb
443
428
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_get_build_version.rb
444
429
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_get_store_app_sizes.rb
445
430
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_hotifx_prechecks.rb
446
431
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_lint_localizations.rb
447
432
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_localize_project.rb
448
- - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_merge_translators_strings.rb
433
+ - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_merge_strings_files.rb
449
434
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_tag_build.rb
450
435
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_update_metadata.rb
451
436
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_update_metadata_source.rb
@@ -462,9 +447,11 @@ files:
462
447
  - lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb
463
448
  - lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb
464
449
  - lib/fastlane/plugin/wpmreleasetoolkit/helper/glotpress_helper.rb
450
+ - lib/fastlane/plugin/wpmreleasetoolkit/helper/interactive_prompt_reminder.rb
465
451
  - lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_adc_app_sizes_helper.rb
466
452
  - lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_git_helper.rb
467
453
  - lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_l10n_helper.rb
454
+ - lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_l10n_linter_helper.rb
468
455
  - lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_version_helper.rb
469
456
  - lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata_download_helper.rb
470
457
  - lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata_update_helper.rb
@@ -492,7 +479,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
492
479
  - !ruby/object:Gem::Version
493
480
  version: '0'
494
481
  requirements: []
495
- rubygems_version: 3.0.3
482
+ rubygems_version: 3.1.6
496
483
  signing_key:
497
484
  specification_version: 4
498
485
  summary: GitHub helper functions
data/bin/drawText DELETED
@@ -1,20 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rake'
4
- require 'os'
5
- require 'pathname'
6
-
7
- abort 'Fatal Error: `drawText` can only be run on macOS.' unless OS.mac?
8
-
9
- plugin_path = Pathname(__FILE__).dirname.parent
10
- executable_path = plugin_path + 'lib/drawText'
11
-
12
- # Run the script
13
- allArgs = ARGV.map do |arg|
14
- argParts = arg.split('=')
15
- argParts[1] = '"' + argParts[1] + '"'
16
-
17
- argParts.join('=')
18
- end.join(' ')
19
-
20
- exec("#{executable_path} #{allArgs}")
@@ -1 +0,0 @@
1
-
@@ -1,113 +0,0 @@
1
- import Cocoa
2
- import CoreGraphics
3
-
4
- struct CoreTextStack {
5
-
6
- let layoutManager: NSLayoutManager
7
- let textContainer: NSTextContainer
8
- var textStorage: NSTextStorage
9
-
10
- let frameSize: CGSize
11
- var alignment: NSTextAlignment
12
-
13
- enum Errors: Error {
14
- case unableToInitializeTextStorage
15
- }
16
-
17
- init(html: Data, size: CGSize, alignment: NSTextAlignment = .natural) throws {
18
-
19
- guard let textStorage = NSTextStorage(html: html, documentAttributes: nil) else {
20
- throw Errors.unableToInitializeTextStorage
21
- }
22
-
23
- ///Storage
24
- self.textStorage = textStorage
25
- self.textContainer = NSTextContainer(size: size)
26
- self.layoutManager = NSLayoutManager()
27
- self.frameSize = size
28
- self.alignment = alignment
29
-
30
- /// Setup
31
- layoutManager.addTextContainer(textContainer)
32
- textStorage.addLayoutManager(layoutManager)
33
-
34
- /// Configuration
35
- textContainer.lineFragmentPadding = 0
36
- textContainer.lineBreakMode = .byWordWrapping
37
- layoutManager.usesFontLeading = true
38
- layoutManager.typesetter.lineFragmentPadding = 0
39
-
40
- applyParagraphStyles()
41
- }
42
-
43
- func setFontSize(_ size: CGFloat) {
44
-
45
- /// Process each attribute run separately so that if the first word is bold,
46
- /// it doesn't make all of the words bold.
47
- textStorage.attributeRuns.forEach {
48
-
49
- let range = NSRange(location: 0, length: $0.length)
50
-
51
- $0.font = NSFont(name: $0.font!.fontName, size: size)
52
- $0.edited(.editedAttributes, range: range, changeInLength: 0)
53
- $0.fixAttributes(in: range)
54
- }
55
-
56
- applyParagraphStyles()
57
- }
58
-
59
- mutating func setAlignment(_ alignment: NSTextAlignment) {
60
- self.alignment = alignment
61
- applyParagraphStyles()
62
- }
63
-
64
- func applyParagraphStyles() {
65
-
66
- let paragraphStyle = NSMutableParagraphStyle()
67
- paragraphStyle.paragraphSpacingBefore = 0
68
- paragraphStyle.paragraphSpacing = 0
69
- paragraphStyle.alignment = self.alignment
70
-
71
- textStorage.addAttributes([
72
- NSAttributedString.Key.paragraphStyle: paragraphStyle
73
- ], range: range)
74
- textStorage.edited(.editedAttributes, range: range, changeInLength: 0)
75
- textStorage.fixAttributes(in: range)
76
- }
77
-
78
- func draw(inContext context: NSGraphicsContext) throws -> CGImage {
79
- NSGraphicsContext.saveGraphicsState()
80
-
81
- /// Without the transform, text is drawn upside down and backwards because of
82
- /// macOS' flipped coordinate system.
83
- NSGraphicsContext.current = NSGraphicsContext(cgContext: context.cgContext, flipped: true)
84
- let transform = NSAffineTransform()
85
- transform.scaleX(by: 1, yBy: -1)
86
- transform.translateX(by: 0, yBy: frameSize.height * -1)
87
- transform.concat()
88
-
89
- layoutManager.drawGlyphs(forGlyphRange: range, at: .zero)
90
-
91
- guard let image = context.cgContext.makeImage() else {
92
- throw TextImageProcessingError(kind: .unableToDrawImage)
93
- }
94
- NSGraphicsContext.restoreGraphicsState()
95
-
96
- return image
97
- }
98
-
99
- /// `fits` is used to determine whether we should shrink the font size in order to fit the text in
100
- /// a smaller box. Turns out the best way to do that is to check whether all the characters fit into
101
- /// the textContainer, rather than trying to measure the drawing area.
102
- var fits: Bool {
103
-
104
- let textStorageLength = textStorage.length
105
- let textContainerRange = layoutManager.glyphRange(for: textContainer)
106
-
107
- return textStorageLength == textContainerRange.length
108
- }
109
-
110
- var range: NSRange {
111
- return layoutManager.glyphRange(for: textContainer)
112
- }
113
- }
@@ -1,36 +0,0 @@
1
- import Foundation
2
-
3
- func readCommandLineArguments() -> [String : String] {
4
-
5
- return CommandLine.arguments
6
- .filter{ $0.contains("=") }
7
- .reduce([String : String](), { (dictionary, argument) -> [String : String] in
8
-
9
- var dictionary = dictionary //shadow for mutability
10
-
11
- var parts = argument.split(separator: "=")
12
- dictionary[String(parts.remove(at: 0))] = parts.joined(separator: "=")
13
-
14
- return dictionary
15
- })
16
- }
17
-
18
- func printUsageAndExit() -> Never {
19
- print("""
20
- Usage: ./draw-text
21
- html={file path or quotes-enclosed HTML string [required]}
22
- maxWidth={ integer [required] }
23
- maxHeight={ integer [required] }
24
- fontSize={ CSS-size compatible string [default = 12px }
25
- color={ color or hex code [default = white] }
26
- align={ CSS text-alignment value [default = center] }
27
- stylesheet={ File Path to a custom stylesheet [default = none] }
28
- """)
29
- exit(1)
30
- }
31
-
32
- func printError(_ string: String) {
33
- let redColor = "\u{001B}[0;31m"
34
- let endColor = "\u{001B}[0;m"
35
- fputs("\(redColor)Error: \(string)\(endColor)\n", stderr)
36
- }
@@ -1,27 +0,0 @@
1
- import Foundation
2
- import Cocoa
3
-
4
- extension String {
5
- var digits: Int? {
6
- let digits = self
7
- .components(separatedBy: CharacterSet.decimalDigits.inverted)
8
- .joined()
9
-
10
- return Int(digits)
11
- }
12
-
13
- var withNewlinesConvertedToBreakTags: String {
14
- return self.replacingOccurrences(of: "\n", with: "<br />")
15
- }
16
- }
17
-
18
- extension NSTextAlignment {
19
- static func fromString(_ string: String) -> NSTextAlignment {
20
- switch string.lowercased() {
21
- case "left": return .left
22
- case "center": return .center
23
- case "right": return .right
24
- default: return .natural
25
- }
26
- }
27
- }
@@ -1,24 +0,0 @@
1
- import Foundation
2
- import Cocoa
3
-
4
- struct File {
5
-
6
- static func write(image: CGImage, toFileAtPath path: String) {
7
-
8
- /// Turn it into a `png`
9
- let rep = NSBitmapImageRep(cgImage: image)
10
- let pngData = rep.representation(using: .png, properties: [:])
11
-
12
- /// Then write it out to the provided path
13
- do {
14
- let pathString = NSString(string: path).expandingTildeInPath
15
- let output = NSURL(fileURLWithPath: pathString)
16
-
17
- try pngData?.write(to: output as URL)
18
- }
19
- catch let err {
20
- printError("Unable to write image to \(path): \(err.localizedDescription)")
21
- exit(6)
22
- }
23
- }
24
- }
@@ -1,48 +0,0 @@
1
- import Cocoa
2
-
3
- struct Stylesheet {
4
-
5
- var contents: String = ""
6
- var externalStyles = "/* EXTERNAL STYLES */"
7
-
8
- private let color: String
9
-
10
- init(color: String, fontSize: Int) {
11
- self.fontSize = fontSize
12
- self.color = color
13
-
14
- update()
15
- }
16
-
17
- mutating func updateWith(filePath: String) {
18
-
19
- guard
20
- FileManager.default.fileExists(atPath: filePath),
21
- let fileContents = FileManager.default.contents(atPath: filePath),
22
- let externalStyles = String(bytes: fileContents, encoding: .utf8) else {
23
- return
24
- }
25
-
26
- self.externalStyles = externalStyles
27
- update()
28
- }
29
-
30
- var fontSize: Int {
31
- didSet { update() }
32
- }
33
-
34
- fileprivate mutating func update() {
35
- self.contents = """
36
- <style>
37
- * {
38
- padding: 0;
39
- margin: 0;
40
- color: \(color);
41
- font-size: \(fontSize)px;
42
- }
43
-
44
- \(externalStyles)
45
- </style>
46
- """.trimmingCharacters(in: .whitespacesAndNewlines)
47
- }
48
- }
@@ -1,100 +0,0 @@
1
- import Foundation
2
- import Cocoa
3
- import CoreText
4
-
5
- class TextImage {
6
-
7
- var color = "white"
8
- var fontSize = 12 {
9
- didSet {
10
- stylesheet.fontSize = self.fontSize
11
- }
12
- }
13
- var alignment: NSTextAlignment = .natural
14
-
15
- lazy var stylesheet = Stylesheet(color: self.color, fontSize: self.fontSize)
16
-
17
- internal var html: String = ""
18
-
19
- internal let drawingOptions: NSString.DrawingOptions = [
20
- .usesLineFragmentOrigin,
21
- .usesFontLeading
22
- ]
23
-
24
- init(string: String) throws {
25
-
26
- if isValidFilePath(path: string) {
27
- html = try contentsOfFile(at: string).trimmingCharacters(in: .whitespacesAndNewlines)
28
- }
29
- else {
30
- html = string
31
- }
32
- }
33
-
34
- func draw(inSize size: CGSize) throws -> CGImage? {
35
- let coreTextStack = try CoreTextStack(html: self.getHTMLData(), size: size, alignment: alignment)
36
- var fontSize = stylesheet.fontSize
37
-
38
- while(!coreTextStack.fits) {
39
- fontSize -= 1
40
- coreTextStack.setFontSize(CGFloat(fontSize))
41
- }
42
-
43
- return try coreTextStack.draw(inContext: try self.graphicsContext(forSize: size))
44
- }
45
-
46
- internal func getHTMLData(withConvertedNewlines: Bool = true) -> Data {
47
- let html = withConvertedNewlines ? self.html.withNewlinesConvertedToBreakTags : self.html
48
- let fullString = stylesheet.contents + html
49
- return fullString.data(using: .utf16)!
50
- }
51
-
52
- func isValidFilePath(path: String) -> Bool {
53
- return FileManager.default.fileExists(atPath: path)
54
- }
55
-
56
- private func contentsOfFile(at path: String) throws -> String {
57
- return try String(contentsOfFile: path, encoding: .utf8)
58
- }
59
-
60
- private func graphicsContext(forSize size: CGSize) throws -> NSGraphicsContext {
61
-
62
- let canvas = NSBitmapImageRep(
63
- bitmapDataPlanes: nil,
64
- pixelsWide: Int(size.width),
65
- pixelsHigh: Int(size.height),
66
- bitsPerSample: 8,
67
- samplesPerPixel: 4,
68
- hasAlpha: true,
69
- isPlanar: false,
70
- colorSpaceName: .calibratedRGB,
71
- bitmapFormat: .alphaFirst,
72
- bytesPerRow: 0,
73
- bitsPerPixel: 0
74
- )!
75
-
76
- /// Set up the graphics context
77
- guard let context = NSGraphicsContext(bitmapImageRep: canvas) else {
78
- throw TextImageProcessingError(kind: .unableToInitializeGraphicsContext)
79
- }
80
-
81
- return context
82
- }
83
- }
84
-
85
- struct TextImageProcessingError: Error {
86
- enum ErrorKind: Int {
87
- case unableToInitializeGraphicsContext
88
- case unableToDrawImage
89
- case unableToReadHTMLString
90
- }
91
-
92
- let kind: ErrorKind
93
- var localizedDescription: String {
94
- switch self.kind {
95
- case .unableToInitializeGraphicsContext: return "Unable to initialize graphics context"
96
- case .unableToDrawImage: return "Unable to draw image"
97
- case .unableToReadHTMLString: return "Unable to read input HTML string. It may not be valid HTML"
98
- }
99
- }
100
- }
@@ -1,61 +0,0 @@
1
- import Foundation
2
- import Cocoa
3
-
4
- let args = readCommandLineArguments()
5
-
6
- // Read the HTML string out of the args. This can either be raw HTML, or a path to an HTML file
7
- guard let htmlString = args["html"] else {
8
- printError("Unable to read HTML string")
9
- printUsageAndExit()
10
- }
11
-
12
- guard let maxWidthString = args["maxWidth"] else {
13
- printError("Missing maxWidth argument")
14
- printUsageAndExit()
15
- }
16
-
17
- guard let maxHeightString = args["maxHeight"] else {
18
- printError("Missing maxHeight argument")
19
- printUsageAndExit()
20
- }
21
-
22
- guard let maxWidth = Int(maxWidthString) else {
23
- printError("maxWidth must be an integer")
24
- printUsageAndExit()
25
- }
26
-
27
- guard let maxHeight = Int(maxHeightString) else {
28
- printError("maxHeight must be an integer")
29
- printUsageAndExit()
30
- }
31
-
32
- do {
33
- let textImage = try TextImage(string: htmlString)
34
-
35
- if let color = args["color"] {
36
- textImage.color = color
37
- }
38
-
39
- if let fontSize = args["fontSize"]?.digits {
40
- textImage.fontSize = fontSize
41
- }
42
-
43
- if let alignment = args["alignment"] {
44
- textImage.alignment = NSTextAlignment.fromString(alignment)
45
- }
46
-
47
- if let stylesheetPath = args["stylesheet"] {
48
- textImage.stylesheet.updateWith(filePath: stylesheetPath)
49
- }
50
-
51
- let outputPath = args["output"] ?? "output.png"
52
-
53
- let size = CGSize(width: maxWidth, height: maxHeight)
54
- let image = try textImage.draw(inSize: size)!
55
-
56
- File.write(image: image, toFileAtPath: outputPath)
57
- }
58
- catch let err {
59
- print(err.localizedDescription)
60
- exit(1)
61
- }
@@ -1,21 +0,0 @@
1
- import XCTest
2
-
3
- class DigitParsingTests: XCTestCase {
4
-
5
- func testThatParsingMixedContentWorks() {
6
- XCTAssert("$10".digits == 10)
7
- }
8
-
9
- func testThatParsingUnmixedContentWorks() {
10
- XCTAssert("10".digits == 10)
11
- }
12
-
13
- // Yes, this is kinda weird, but CSS + decimal numbers is generally a bad idea anyway
14
- func testThatParsingDecimalContentWorks() {
15
- XCTAssert("10.0".digits == 100)
16
- }
17
-
18
- func testThatParsingNonDigitContentWorks() {
19
- XCTAssert("Foo".digits == nil)
20
- }
21
- }
@@ -1,5 +0,0 @@
1
- import XCTest
2
-
3
- class ExtensionsTests: DrawTextTest {
4
-
5
- }
@@ -1,22 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>CFBundleDevelopmentRegion</key>
6
- <string>$(DEVELOPMENT_LANGUAGE)</string>
7
- <key>CFBundleExecutable</key>
8
- <string>$(EXECUTABLE_NAME)</string>
9
- <key>CFBundleIdentifier</key>
10
- <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11
- <key>CFBundleInfoDictionaryVersion</key>
12
- <string>6.0</string>
13
- <key>CFBundleName</key>
14
- <string>$(PRODUCT_NAME)</string>
15
- <key>CFBundlePackageType</key>
16
- <string>BNDL</string>
17
- <key>CFBundleShortVersionString</key>
18
- <string>1.0</string>
19
- <key>CFBundleVersion</key>
20
- <string>1</string>
21
- </dict>
22
- </plist>
@@ -1,31 +0,0 @@
1
- import XCTest
2
-
3
- class StylesheetTests: DrawTextTest {
4
-
5
- func testThatDefaultStylesheetProducesValidOutput() {
6
- let stylesheet = Stylesheet(color: "black", fontSize: 10)
7
- XCTAssert(stylesheet.contents == getTestCase(named: "default-stylesheet"))
8
- }
9
-
10
- func testThatStylesheetCanChangeFontSizes() {
11
- var stylesheet = Stylesheet(color: "black", fontSize: 10)
12
- stylesheet.fontSize -= 1
13
- XCTAssert(stylesheet.contents == getTestCase(named: "text-size-adjustment-test"))
14
- }
15
-
16
- func testThatStylesheetExternalStylesCanBeUpdated() {
17
- var stylesheet = Stylesheet(color: "black", fontSize: 10)
18
- stylesheet.updateWith(filePath: getTestCaseURLForAsset(named: "external-styles-sample", extension: "css").path)
19
- XCTAssert(stylesheet.contents == getTestCase(named: "external-styles-test"))
20
- }
21
-
22
- func testThatUpdatingExternalStylesWithAnInvalidPathProducesAValidStylesheet() {
23
- var stylesheet = Stylesheet(color: "black", fontSize: 10)
24
- stylesheet.updateWith(filePath: "/this-is-a-fake-path-that-should-never-exist")
25
-
26
- debugPrint(stylesheet.contents, getTestCase(named: "default-stylesheet"))
27
-
28
-
29
- XCTAssert(stylesheet.contents == getTestCase(named: "default-stylesheet"))
30
- }
31
- }
@@ -1,10 +0,0 @@
1
- <style>
2
- * {
3
- padding: 0;
4
- margin: 0;
5
- color: black;
6
- font-size: 10px;
7
- }
8
-
9
- /* EXTERNAL STYLES */
10
- </style>
@@ -1,3 +0,0 @@
1
- strong {
2
- font-wight: bold;
3
- }