From 93b474262143bb8959cda23d00dea3e11229be76 Mon Sep 17 00:00:00 2001 From: Bruno Date: Mon, 21 Jan 2019 15:39:56 +0000 Subject: [PATCH 1/5] Added Pods to have Alamofire in order to have an example with possibility of internet fetched use cases. --- Example/MarkdownKitViewModel.swift | 45 ++++++++ MarkdownKit.xcodeproj/project.pbxproj | 105 ++++++++++++++++++ .../contents.xcworkspacedata | 10 ++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ Podfile | 12 ++ Podfile.lock | 16 +++ 6 files changed, 196 insertions(+) create mode 100644 Example/MarkdownKitViewModel.swift create mode 100644 MarkdownKit.xcworkspace/contents.xcworkspacedata create mode 100644 MarkdownKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Podfile create mode 100644 Podfile.lock diff --git a/Example/MarkdownKitViewModel.swift b/Example/MarkdownKitViewModel.swift new file mode 100644 index 0000000..dbcd4d1 --- /dev/null +++ b/Example/MarkdownKitViewModel.swift @@ -0,0 +1,45 @@ +// +// MarkdownKitViewModel.swift +// Example +// +// Created by Bruno Oliveira on 21/01/2019. +// Copyright © 2019 Ivan Bruel. All rights reserved. +// + +import Foundation +import MarkdownKit +import Alamofire + +class MarkdownKitViewModel { + + let markdownParser: MarkdownParser + + fileprivate let testingURL: String + + var markdownAttributedStringChanged: ((NSAttributedString?, Error?) -> ())? = nil + + init(markdownParser: MarkdownParser, + testingURL: String = "https://raw.githubusercontent.com/apple/swift-evolution/master/proposals/0240-ordered-collection-diffing.md") { + self.markdownParser = markdownParser + self.testingURL = testingURL + } +} + +extension MarkdownKitViewModel { + func parseString(markdownString: String) { + markdownAttributedStringChanged?(markdownParser.parse(markdownString), nil) + } + + func requestTestPage() { + AF.request(testingURL).responseString { [weak self]response in + if let error = response.error { + self?.markdownAttributedStringChanged?(nil, error) + return + } + + response.result.withValue { [weak self]markdownString in + self?.parseString(markdownString: markdownString) + } + } + } +} diff --git a/MarkdownKit.xcodeproj/project.pbxproj b/MarkdownKit.xcodeproj/project.pbxproj index f0dd0fb..bff83a4 100644 --- a/MarkdownKit.xcodeproj/project.pbxproj +++ b/MarkdownKit.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 6CBBF757D7C5F868299202E2 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2009DA929218EA48384D9545 /* Pods_Example.framework */; }; + B06D95C41727E6744BAFB130 /* Pods_MarkdownKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9BB616C620AA78CC178349EA /* Pods_MarkdownKit.framework */; }; B62C1BEB21EF7D8D00308C8C /* String+HTMLDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62C1BE221EF7D8C00308C8C /* String+HTMLDecode.swift */; }; B62C1BEC21EF7D8D00308C8C /* MarkdownSubreddit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62C1BE321EF7D8C00308C8C /* MarkdownSubreddit.swift */; }; B62C1BEE21EF7D8D00308C8C /* Product Sans Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B62C1BE521EF7D8C00308C8C /* Product Sans Regular.ttf */; }; @@ -38,9 +40,14 @@ B672002C21EF8A96008649E1 /* MarkdownLevelElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = B672001821EF8A96008649E1 /* MarkdownLevelElement.swift */; }; B672002D21EF8A96008649E1 /* MarkdownElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = B672001921EF8A96008649E1 /* MarkdownElement.swift */; }; B672002E21EF8A96008649E1 /* MarkdownStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B672001A21EF8A96008649E1 /* MarkdownStyle.swift */; }; + B695DA0E21F5E60300FC6FCD /* MarkdownKitViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B695DA0D21F5E60300FC6FCD /* MarkdownKitViewModel.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 2009DA929218EA48384D9545 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 71F56393B2792188BC560048 /* Pods-MarkdownKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MarkdownKit.release.xcconfig"; path = "Target Support Files/Pods-MarkdownKit/Pods-MarkdownKit.release.xcconfig"; sourceTree = ""; }; + 7D049EC64593E526238AC045 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; }; + 9BB616C620AA78CC178349EA /* Pods_MarkdownKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MarkdownKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B62C1BAD21EF7C8000308C8C /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; B62C1BE221EF7D8C00308C8C /* String+HTMLDecode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+HTMLDecode.swift"; sourceTree = ""; }; B62C1BE321EF7D8C00308C8C /* MarkdownSubreddit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkdownSubreddit.swift; sourceTree = ""; }; @@ -75,6 +82,9 @@ B672001821EF8A96008649E1 /* MarkdownLevelElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkdownLevelElement.swift; sourceTree = ""; }; B672001921EF8A96008649E1 /* MarkdownElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkdownElement.swift; sourceTree = ""; }; B672001A21EF8A96008649E1 /* MarkdownStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkdownStyle.swift; sourceTree = ""; }; + B695DA0D21F5E60300FC6FCD /* MarkdownKitViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkdownKitViewModel.swift; sourceTree = ""; }; + D541903D4B863D139D52AF42 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = ""; }; + E0F59E3C6A539A19D874DE27 /* Pods-MarkdownKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MarkdownKit.debug.xcconfig"; path = "Target Support Files/Pods-MarkdownKit/Pods-MarkdownKit.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -83,6 +93,7 @@ buildActionMask = 2147483647; files = ( B672000021EF8825008649E1 /* MarkdownKit.framework in Frameworks */, + 6CBBF757D7C5F868299202E2 /* Pods_Example.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -90,12 +101,25 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B06D95C41727E6744BAFB130 /* Pods_MarkdownKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 9958FA90ED0DF60AFA5C69DA /* Pods */ = { + isa = PBXGroup; + children = ( + D541903D4B863D139D52AF42 /* Pods-Example.debug.xcconfig */, + 7D049EC64593E526238AC045 /* Pods-Example.release.xcconfig */, + E0F59E3C6A539A19D874DE27 /* Pods-MarkdownKit.debug.xcconfig */, + 71F56393B2792188BC560048 /* Pods-MarkdownKit.release.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; B62C1BA421EF7C8000308C8C = { isa = PBXGroup; children = ( @@ -103,6 +127,7 @@ B62C1C0021EF7EED00308C8C /* MarkdownKit */, B62C1BAE21EF7C8000308C8C /* Products */, B672FFFF21EF8825008649E1 /* Frameworks */, + 9958FA90ED0DF60AFA5C69DA /* Pods */, ); sourceTree = ""; }; @@ -124,6 +149,7 @@ B688EF9F21EF8519003FF4AC /* Extensions */, B688EF9E21EF850B003FF4AC /* Fonts */, B688EF9D21EF84D6003FF4AC /* Resources */, + B695DA0D21F5E60300FC6FCD /* MarkdownKitViewModel.swift */, ); path = Example; sourceTree = ""; @@ -208,6 +234,8 @@ B672FFFF21EF8825008649E1 /* Frameworks */ = { isa = PBXGroup; children = ( + 2009DA929218EA48384D9545 /* Pods_Example.framework */, + 9BB616C620AA78CC178349EA /* Pods_MarkdownKit.framework */, ); name = Frameworks; sourceTree = ""; @@ -258,9 +286,11 @@ isa = PBXNativeTarget; buildConfigurationList = B62C1BCA21EF7C8100308C8C /* Build configuration list for PBXNativeTarget "Example" */; buildPhases = ( + E8D1545A32A10AFAFF88C956 /* [CP] Check Pods Manifest.lock */, B62C1BA921EF7C8000308C8C /* Sources */, B62C1BAA21EF7C8000308C8C /* Frameworks */, B62C1BAB21EF7C8000308C8C /* Resources */, + 52B210B76D0B5A10B67EBBEE /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -275,6 +305,7 @@ isa = PBXNativeTarget; buildConfigurationList = B62C1C1021EF7EED00308C8C /* Build configuration list for PBXNativeTarget "MarkdownKit" */; buildPhases = ( + 30227220D940239A6198465A /* [CP] Check Pods Manifest.lock */, B62C1BFA21EF7EED00308C8C /* Headers */, B62C1BFB21EF7EED00308C8C /* Sources */, B62C1BFC21EF7EED00308C8C /* Frameworks */, @@ -350,6 +381,75 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 30227220D940239A6198465A /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-MarkdownKit-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 52B210B76D0B5A10B67EBBEE /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + E8D1545A32A10AFAFF88C956 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Example-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ B62C1BA921EF7C8000308C8C /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -357,6 +457,7 @@ files = ( B62C1BEF21EF7D8D00308C8C /* AppDelegate.swift in Sources */, B62C1BEB21EF7D8D00308C8C /* String+HTMLDecode.swift in Sources */, + B695DA0E21F5E60300FC6FCD /* MarkdownKitViewModel.swift in Sources */, B62C1BF121EF7D8D00308C8C /* ViewController.swift in Sources */, B62C1BEC21EF7D8D00308C8C /* MarkdownSubreddit.swift in Sources */, ); @@ -529,6 +630,7 @@ }; B62C1BCB21EF7C8100308C8C /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D541903D4B863D139D52AF42 /* Pods-Example.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -548,6 +650,7 @@ }; B62C1BCC21EF7C8100308C8C /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 7D049EC64593E526238AC045 /* Pods-Example.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -566,6 +669,7 @@ }; B62C1C1121EF7EED00308C8C /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E0F59E3C6A539A19D874DE27 /* Pods-MarkdownKit.debug.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; @@ -595,6 +699,7 @@ }; B62C1C1221EF7EED00308C8C /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 71F56393B2792188BC560048 /* Pods-MarkdownKit.release.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; diff --git a/MarkdownKit.xcworkspace/contents.xcworkspacedata b/MarkdownKit.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..6fd33ed --- /dev/null +++ b/MarkdownKit.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/MarkdownKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/MarkdownKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/MarkdownKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..f22ef4c --- /dev/null +++ b/Podfile @@ -0,0 +1,12 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '10.0' + +target 'Example' do + use_frameworks! + pod 'Alamofire', '~> 5.0.0.beta.1' +end + +target 'MarkdownKit' do + use_frameworks! + +end diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..c8337f7 --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - Alamofire (5.0.0.beta.1) + +DEPENDENCIES: + - Alamofire (~> 5.0.0.beta.1) + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - Alamofire + +SPEC CHECKSUMS: + Alamofire: 2ef6d6c984c5d21c366e9b41a9ae7dfee2b67a44 + +PODFILE CHECKSUM: 056fb12cb831c84165a65378ddd59f3ad8c252bd + +COCOAPODS: 1.6.0.beta.2 From 6999a224a1e355a1be2316ba04e144b8c7e9751b Mon Sep 17 00:00:00 2001 From: Bruno Date: Mon, 21 Jan 2019 15:40:31 +0000 Subject: [PATCH 2/5] Refactored ViewController to have a fetcher from the internet. --- Example/Resources/Base.lproj/Main.storyboard | 32 +++++++- Example/ViewController.swift | 77 +++++++++++++++++--- 2 files changed, 94 insertions(+), 15 deletions(-) diff --git a/Example/Resources/Base.lproj/Main.storyboard b/Example/Resources/Base.lproj/Main.storyboard index d51c65f..84cbf5b 100644 --- a/Example/Resources/Base.lproj/Main.storyboard +++ b/Example/Resources/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -12,7 +12,7 @@ - + @@ -22,7 +22,7 @@ - + Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. @@ -33,16 +33,40 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/ViewController.swift b/Example/ViewController.swift index b5d9f11..f205b14 100644 --- a/Example/ViewController.swift +++ b/Example/ViewController.swift @@ -10,33 +10,87 @@ import UIKit import MarkdownKit class ViewController: UIViewController { - @IBOutlet fileprivate weak var textView: UITextView! { didSet { textView.delegate = self + textView.isScrollEnabled = false } } - // Example with custom font - // fileprivate let markdownParser = MarkdownParser(font: UIFont(name: "Product Sans", size: UIFont.systemFontSize)!) + fileprivate lazy var attributedStringFromResources: String = { + return NSLocalizedString("Markdown", comment: "").stringByDecodingHTMLEntities + }() + + fileprivate lazy var viewModel: MarkdownKitViewModel = { + // Example with custom font + // fileprivate let markdownParser = MarkdownParser(font: UIFont(name: "Product Sans", size: UIFont.systemFontSize)!) + let parser = MarkdownParser() + parser.addCustomElement(MarkdownSubreddit()) + + let viewModel = MarkdownKitViewModel(markdownParser: parser) + viewModel.markdownAttributedStringChanged = { [weak self](attributtedString, error) in + if let error = error { + NSLog("Error requesting -> \(error)") + return + } + + guard let attributedText = attributtedString else { + NSLog("No error nor string found") + return + } + + self?.textView.attributedText = attributedText + } + + return viewModel + }() + + fileprivate var resourcesAction: UIAlertAction { + return UIAlertAction(title: "Resources", + style: .default, + handler: { [unowned self]_ in + self.viewModel.parseString(markdownString: self.attributedStringFromResources) + }) + } + + fileprivate var internetAction: UIAlertAction { + return UIAlertAction(title: "Internet", + style: .default, + handler: { [unowned self]_ in + self.viewModel.requestTestPage() + }) + } + + fileprivate var actionSheetController: UIAlertController { + let alert = UIAlertController(title: "Choose the Markdown source", message: nil, preferredStyle: .actionSheet) + alert.addAction(resourcesAction) + alert.addAction(internetAction) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in + alert.dismiss(animated: true, completion: nil) + })) + return alert + } - fileprivate let markdownParser = MarkdownParser() override func viewDidLoad() { super.viewDidLoad() - markdownParser.addCustomElement(MarkdownSubreddit()) - textView.attributedText = markdownParser.parse(NSLocalizedString("Markdown", comment: "").stringByDecodingHTMLEntities) - // Do any additional setup after loading the view, typically from a nib. + self.navigationItem.title = "MarkdownKit" + viewModel.parseString(markdownString: attributedStringFromResources) } - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + if (!textView.isScrollEnabled) { + textView.isScrollEnabled = true + textView.setContentOffset(.zero, animated: false) + } } + @IBAction func userDidTapSwitch(_ sender: Any) { + present(actionSheetController, animated: true, completion: nil) + } } extension ViewController: UITextViewDelegate { - func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool { UIApplication.shared.open(URL, options: [:]) @@ -45,3 +99,4 @@ extension ViewController: UITextViewDelegate { } } + From 6051cf0a3475d2302548902f862e00f15a02cf1d Mon Sep 17 00:00:00 2001 From: Bruno Date: Mon, 21 Jan 2019 15:40:51 +0000 Subject: [PATCH 3/5] Hot fix for character decoding --- MarkdownKit/Sources/Extensions/String+UTF16.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MarkdownKit/Sources/Extensions/String+UTF16.swift b/MarkdownKit/Sources/Extensions/String+UTF16.swift index 65b9e71..29c9717 100644 --- a/MarkdownKit/Sources/Extensions/String+UTF16.swift +++ b/MarkdownKit/Sources/Extensions/String+UTF16.swift @@ -21,6 +21,12 @@ extension String { /// Converts each 4 digit characters to its String form (e.g. "0048" -> "H") func unescapeUTF16() -> String? { + + //This is an hot fix for the crash when a regular string is passed here. + guard count % 4 == 0 else { + return self + } + var utf16Array = [UInt16]() stride(from: 0, to: count, by: 4).forEach { let startIndex = index(self.startIndex, offsetBy: $0) From ef9386ef3b44f9d9a7c5db5ad1d7f16ab4278d32 Mon Sep 17 00:00:00 2001 From: Bruno Date: Mon, 21 Jan 2019 16:10:04 +0000 Subject: [PATCH 4/5] Improved regex readability of code regex --- MarkdownKit/Sources/Elements/MarkdownCode.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MarkdownKit/Sources/Elements/MarkdownCode.swift b/MarkdownKit/Sources/Elements/MarkdownCode.swift index c1cee99..81f96d6 100644 --- a/MarkdownKit/Sources/Elements/MarkdownCode.swift +++ b/MarkdownKit/Sources/Elements/MarkdownCode.swift @@ -10,7 +10,7 @@ import UIKit open class MarkdownCode: MarkdownCommonElement { - fileprivate static let regex = "(.?|^)(\\`+)(.+?)(\\2)" + fileprivate static let regex = "(.?|^)(\\`{1,3})(.+?)(\\2)" open var font: UIFont? open var color: UIColor? From 0f6e7ff31d1e485a97592ea16629e0203188ccd3 Mon Sep 17 00:00:00 2001 From: Bruno Date: Mon, 21 Jan 2019 16:14:06 +0000 Subject: [PATCH 5/5] Bump to version 1.4 -- Changes: - Fixed a bug parsing code elements with UTFDecoding see Issue #35 - Improved readability of code regex and limited until 3 ``` - Refactored Example project to support internet markdowns --- MarkdownKit.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MarkdownKit.podspec b/MarkdownKit.podspec index 268310c..1289532 100644 --- a/MarkdownKit.podspec +++ b/MarkdownKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "MarkdownKit" - s.version = "1.3" + s.version = "1.4" s.summary = "MarkdownKit is a customizable and extensible Markdown parser for iOS." s.description = <<-DESC MarkdownKit is a customizable and extensible Markdown parser for iOS.