├── MDText
├── Assets.xcassets
│ ├── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
├── ContentView.swift
├── AppDelegate.swift
├── Base.lproj
│ └── LaunchScreen.storyboard
├── Info.plist
└── SceneDelegate.swift
├── MDTextTestApp
├── MDTextTestApp
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── ContentView.swift
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ └── SceneDelegate.swift
└── MDTextTestApp.xcodeproj
│ ├── xcshareddata
│ └── xcschemes
│ │ └── MDTextTestApp.xcscheme
│ └── project.pbxproj
├── MDText.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
├── xcuserdata
│ └── andrecarrera.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── MDText_Info.plist
├── xcshareddata
│ └── xcschemes
│ │ └── MDText-Package.xcscheme
└── project.pbxproj
├── Package.swift
├── README.md
├── LICENSE
├── .gitignore
└── Sources
└── MDText
└── MDText.swift
/MDText/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/MDText/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/MDText.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
--------------------------------------------------------------------------------
/MDText.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MDText.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MDText.xcodeproj/xcuserdata/andrecarrera.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MDText-Package.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
2 | import PackageDescription
3 |
4 | let package = Package(
5 | name: "MDText",
6 | platforms: [
7 | .iOS(.v13),
8 | .macOS(.v10_15),
9 | .tvOS(.v13)
10 | ],
11 | products: [
12 | .library(
13 | name: "MDText",
14 | targets: ["MDText"]),
15 | ],
16 | dependencies: [],
17 | targets: [
18 | .target(
19 | name: "MDText",
20 | dependencies: []),
21 | ]
22 | )
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MDText
2 |
3 | MDText is a markdown render library built in and for SwiftUI
4 |
5 |
6 | ## Usage:
7 | ```swift
8 | import MDText
9 | struct ContentView: View {
10 | var markdown =
11 | """
12 | ** Hello MDText **
13 | """
14 |
15 | var body: some View {
16 | MDText(markdown: markdown)
17 | }
18 | }
19 | ```
20 |
21 | ## Features:
22 | - header
23 | - link
24 | - bold
25 | - hyperlink
26 | - emphasis
27 |
28 |
29 | ## Planned:
30 |
31 | del, quote, inline, ul, ol, blockquotes
32 |
33 | ## Installation
34 | Using Xcode 11
35 |
36 | ```
37 | menu > file > Swift Packages > Add package dependency...
38 | ```
39 |
40 | enter package url: https://github.com/Lambdo-Labs/MDText
41 |
42 |
--------------------------------------------------------------------------------
/MDText.xcodeproj/MDText_Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundleDevelopmentRegion
5 | en
6 | CFBundleExecutable
7 | $(EXECUTABLE_NAME)
8 | CFBundleIdentifier
9 | $(PRODUCT_BUNDLE_IDENTIFIER)
10 | CFBundleInfoDictionaryVersion
11 | 6.0
12 | CFBundleName
13 | $(PRODUCT_NAME)
14 | CFBundlePackageType
15 | FMWK
16 | CFBundleShortVersionString
17 | 1.0
18 | CFBundleSignature
19 | ????
20 | CFBundleVersion
21 | $(CURRENT_PROJECT_VERSION)
22 | NSPrincipalClass
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Lambdo-Labs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MDText/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // MDText
4 | //
5 | // Created by Andre Carrera on 10/9/19.
6 | // Copyright © 2019 Lambdo. All rights reserved.
7 | //
8 | import SwiftUI
9 | import MDText
10 |
11 | struct ContentView_Previews: PreviewProvider {
12 |
13 | static let string =
14 | #"""
15 | # hello, This is Markdown Live Preview
16 |
17 | ----
18 | ## what is Markdown?
19 | see [Wikipedia](https://en.wikipedia.org/wiki/Markdown)
20 |
21 | > Markdown is a lightweight markup language, originally created by John Gruber and Aaron Swartz allowing people "to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML)".
22 |
23 | ----
24 | ## usage
25 | 1. Write markdown text in this textarea.
26 | 2. Click 'HTML Preview' button.
27 |
28 | ----
29 | ## markdown quick reference
30 | # headers
31 |
32 | *emphasis*
33 |
34 | **strong**
35 |
36 | * list
37 |
38 | >block quote
39 |
40 | code (4 spaces indent)
41 | [links](https://wikipedia.org)
42 |
43 | ----
44 | ## changelog
45 | * 17-Feb-2013 re-design
46 |
47 | ----
48 | ## thanks
49 | * [markdown-js](https://github.com/evilstreak/markdown-js)
50 | """#
51 | static var previews: some View {
52 | // Group {
53 | ScrollView {
54 | VStack {
55 | MDText(markdown: ContentView_Previews.string)
56 |
57 | }
58 | .padding(.horizontal)
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/MDText/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // MDText
4 | //
5 | // Created by Andre Carrera on 10/9/19.
6 | // Copyright © 2019 Lambdo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // MDTextTestApp
4 | //
5 | // Created by Andre Carrera on 10/9/19.
6 | // Copyright © 2019 Lambdo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // MDTextTestApp
4 | //
5 | // Created by Andre Carrera on 10/9/19.
6 | // Copyright © 2019 Lambdo. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 | import MDText
11 |
12 | struct ContentView: View {
13 | @State var markdown =
14 | #"""
15 | Combine the Digestive Blend, Turmeric, and Yarrow Pom in an empty capsule and take it 3x daily on an empty stomach.
16 |
17 | Apply a drop of each oil to the upper abdomen 3x daily at the same time as the capsule is taken.
18 |
19 | Take 2 Digestive Blend Softgels with food.
20 |
21 | Suggested Duration: 3-6 months
22 |
23 | **Additional Support: Probiotic Complex (take 2 capsules 2x daily on an empty stomach), Digestive Enzymes (take 1 capsule with each meal)**
24 | """#
25 | var body: some View {
26 | ScrollView {
27 | VStack(alignment: .leading) {
28 | HStack {
29 | Spacer()
30 | }
31 | // Text("Description")
32 | // .font(.headline)
33 | MDText(markdown: markdown)
34 | // .multilineTextAlignment(.leading)
35 |
36 |
37 | // MDText(markdown: markdown)
38 | }
39 | .padding(.horizontal)
40 | }
41 | .onAppear(perform: onLoad)
42 | }
43 |
44 | func onLoad() {
45 | // self.markdown =
46 | // """
47 | //here is a **preview** and is very *long* !ssd
48 | //that is multiple lines
49 | //"""
50 | }
51 | }
52 |
53 | struct ContentView_Previews: PreviewProvider {
54 | static var previews: some View {
55 | ContentView()
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/MDText/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/MDText/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/MDText/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/MDText.xcodeproj/xcshareddata/xcschemes/MDText-Package.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | # Packages/
41 | # Package.pins
42 | # Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | # .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | # Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # Accio dependency management
70 | Dependencies/
71 | .accio/
72 |
73 | # fastlane
74 | #
75 | # It is recommended to not store the screenshots in the git repo.
76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
77 | # For more information about the recommended setup visit:
78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
79 |
80 | fastlane/report.xml
81 | fastlane/Preview.html
82 | fastlane/screenshots/**/*.png
83 | fastlane/test_output
84 |
85 | # Code Injection
86 | #
87 | # After new code Injection tools there's a generated folder /iOSInjectionProject
88 | # https://github.com/johnno1962/injectionforxcode
89 |
90 | iOSInjectionProject/
91 |
--------------------------------------------------------------------------------
/MDText/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // MDText
4 | //
5 | // Created by Andre Carrera on 10/9/19.
6 | // Copyright © 2019 Lambdo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = MDText(markdown: "")
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // MDTextTestApp
4 | //
5 | // Created by Andre Carrera on 10/9/19.
6 | // Copyright © 2019 Lambdo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp.xcodeproj/xcshareddata/xcschemes/MDTextTestApp.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/MDText.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | OBJ_20 /* MDText.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* MDText.swift */; };
11 | OBJ_27 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; };
12 | /* End PBXBuildFile section */
13 |
14 | /* Begin PBXContainerItemProxy section */
15 | 3C50D55F234E5B3F001A76D4 /* PBXContainerItemProxy */ = {
16 | isa = PBXContainerItemProxy;
17 | containerPortal = 3C50D55B234E5B3E001A76D4 /* MDTextTestApp.xcodeproj */;
18 | proxyType = 2;
19 | remoteGlobalIDString = 3C50D544234E5B3E001A76D4;
20 | remoteInfo = MDTextTestApp;
21 | };
22 | /* End PBXContainerItemProxy section */
23 |
24 | /* Begin PBXFileReference section */
25 | 3C50D55B234E5B3E001A76D4 /* MDTextTestApp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MDTextTestApp.xcodeproj; path = MDTextTestApp/MDTextTestApp.xcodeproj; sourceTree = SOURCE_ROOT; };
26 | "MDText::MDText::Product" /* MDText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MDText.framework; sourceTree = BUILT_PRODUCTS_DIR; };
27 | OBJ_13 /* MDText */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MDText; sourceTree = SOURCE_ROOT; };
28 | OBJ_14 /* MDTextTestApp */ = {isa = PBXFileReference; lastKnownFileType = text; path = MDTextTestApp; sourceTree = SOURCE_ROOT; };
29 | OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; };
30 | OBJ_9 /* MDText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MDText.swift; sourceTree = ""; };
31 | /* End PBXFileReference section */
32 |
33 | /* Begin PBXFrameworksBuildPhase section */
34 | OBJ_21 /* Frameworks */ = {
35 | isa = PBXFrameworksBuildPhase;
36 | buildActionMask = 0;
37 | files = (
38 | );
39 | runOnlyForDeploymentPostprocessing = 0;
40 | };
41 | /* End PBXFrameworksBuildPhase section */
42 |
43 | /* Begin PBXGroup section */
44 | 3C50D55C234E5B3E001A76D4 /* Products */ = {
45 | isa = PBXGroup;
46 | children = (
47 | 3C50D560234E5B3F001A76D4 /* MDTextTestApp.app */,
48 | );
49 | name = Products;
50 | sourceTree = "";
51 | };
52 | OBJ_10 /* Tests */ = {
53 | isa = PBXGroup;
54 | children = (
55 | );
56 | name = Tests;
57 | sourceTree = SOURCE_ROOT;
58 | };
59 | OBJ_11 /* Products */ = {
60 | isa = PBXGroup;
61 | children = (
62 | "MDText::MDText::Product" /* MDText.framework */,
63 | );
64 | name = Products;
65 | sourceTree = BUILT_PRODUCTS_DIR;
66 | };
67 | OBJ_5 /* */ = {
68 | isa = PBXGroup;
69 | children = (
70 | OBJ_6 /* Package.swift */,
71 | OBJ_7 /* Sources */,
72 | OBJ_10 /* Tests */,
73 | OBJ_11 /* Products */,
74 | OBJ_13 /* MDText */,
75 | OBJ_14 /* MDTextTestApp */,
76 | );
77 | name = "";
78 | sourceTree = "";
79 | };
80 | OBJ_7 /* Sources */ = {
81 | isa = PBXGroup;
82 | children = (
83 | OBJ_8 /* MDText */,
84 | );
85 | name = Sources;
86 | sourceTree = SOURCE_ROOT;
87 | };
88 | OBJ_8 /* MDText */ = {
89 | isa = PBXGroup;
90 | children = (
91 | 3C50D55B234E5B3E001A76D4 /* MDTextTestApp.xcodeproj */,
92 | OBJ_9 /* MDText.swift */,
93 | );
94 | name = MDText;
95 | path = Sources/MDText;
96 | sourceTree = SOURCE_ROOT;
97 | };
98 | /* End PBXGroup section */
99 |
100 | /* Begin PBXNativeTarget section */
101 | "MDText::MDText" /* MDText */ = {
102 | isa = PBXNativeTarget;
103 | buildConfigurationList = OBJ_16 /* Build configuration list for PBXNativeTarget "MDText" */;
104 | buildPhases = (
105 | OBJ_19 /* Sources */,
106 | OBJ_21 /* Frameworks */,
107 | );
108 | buildRules = (
109 | );
110 | dependencies = (
111 | );
112 | name = MDText;
113 | productName = MDText;
114 | productReference = "MDText::MDText::Product" /* MDText.framework */;
115 | productType = "com.apple.product-type.framework";
116 | };
117 | "MDText::SwiftPMPackageDescription" /* MDTextPackageDescription */ = {
118 | isa = PBXNativeTarget;
119 | buildConfigurationList = OBJ_23 /* Build configuration list for PBXNativeTarget "MDTextPackageDescription" */;
120 | buildPhases = (
121 | OBJ_26 /* Sources */,
122 | );
123 | buildRules = (
124 | );
125 | dependencies = (
126 | );
127 | name = MDTextPackageDescription;
128 | productName = MDTextPackageDescription;
129 | productType = "com.apple.product-type.framework";
130 | };
131 | /* End PBXNativeTarget section */
132 |
133 | /* Begin PBXProject section */
134 | OBJ_1 /* Project object */ = {
135 | isa = PBXProject;
136 | attributes = {
137 | LastSwiftMigration = 9999;
138 | LastUpgradeCheck = 9999;
139 | };
140 | buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "MDText" */;
141 | compatibilityVersion = "Xcode 3.2";
142 | developmentRegion = en;
143 | hasScannedForEncodings = 0;
144 | knownRegions = (
145 | en,
146 | );
147 | mainGroup = OBJ_5 /* */;
148 | productRefGroup = OBJ_11 /* Products */;
149 | projectDirPath = "";
150 | projectReferences = (
151 | {
152 | ProductGroup = 3C50D55C234E5B3E001A76D4 /* Products */;
153 | ProjectRef = 3C50D55B234E5B3E001A76D4 /* MDTextTestApp.xcodeproj */;
154 | },
155 | );
156 | projectRoot = "";
157 | targets = (
158 | "MDText::MDText" /* MDText */,
159 | "MDText::SwiftPMPackageDescription" /* MDTextPackageDescription */,
160 | );
161 | };
162 | /* End PBXProject section */
163 |
164 | /* Begin PBXReferenceProxy section */
165 | 3C50D560234E5B3F001A76D4 /* MDTextTestApp.app */ = {
166 | isa = PBXReferenceProxy;
167 | fileType = wrapper.application;
168 | path = MDTextTestApp.app;
169 | remoteRef = 3C50D55F234E5B3F001A76D4 /* PBXContainerItemProxy */;
170 | sourceTree = BUILT_PRODUCTS_DIR;
171 | };
172 | /* End PBXReferenceProxy section */
173 |
174 | /* Begin PBXSourcesBuildPhase section */
175 | OBJ_19 /* Sources */ = {
176 | isa = PBXSourcesBuildPhase;
177 | buildActionMask = 0;
178 | files = (
179 | OBJ_20 /* MDText.swift in Sources */,
180 | );
181 | runOnlyForDeploymentPostprocessing = 0;
182 | };
183 | OBJ_26 /* Sources */ = {
184 | isa = PBXSourcesBuildPhase;
185 | buildActionMask = 0;
186 | files = (
187 | OBJ_27 /* Package.swift in Sources */,
188 | );
189 | runOnlyForDeploymentPostprocessing = 0;
190 | };
191 | /* End PBXSourcesBuildPhase section */
192 |
193 | /* Begin XCBuildConfiguration section */
194 | OBJ_17 /* Debug */ = {
195 | isa = XCBuildConfiguration;
196 | buildSettings = {
197 | ENABLE_TESTABILITY = YES;
198 | FRAMEWORK_SEARCH_PATHS = (
199 | "$(inherited)",
200 | "$(PLATFORM_DIR)/Developer/Library/Frameworks",
201 | );
202 | HEADER_SEARCH_PATHS = "$(inherited)";
203 | INFOPLIST_FILE = MDText.xcodeproj/MDText_Info.plist;
204 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
205 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
206 | MACOSX_DEPLOYMENT_TARGET = 10.15;
207 | OTHER_CFLAGS = "$(inherited)";
208 | OTHER_LDFLAGS = "$(inherited)";
209 | OTHER_SWIFT_FLAGS = "$(inherited)";
210 | PRODUCT_BUNDLE_IDENTIFIER = MDText;
211 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
212 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
213 | SKIP_INSTALL = YES;
214 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
215 | SWIFT_VERSION = 5.0;
216 | TARGET_NAME = MDText;
217 | TVOS_DEPLOYMENT_TARGET = 13.0;
218 | WATCHOS_DEPLOYMENT_TARGET = 2.0;
219 | };
220 | name = Debug;
221 | };
222 | OBJ_18 /* Release */ = {
223 | isa = XCBuildConfiguration;
224 | buildSettings = {
225 | ENABLE_TESTABILITY = YES;
226 | FRAMEWORK_SEARCH_PATHS = (
227 | "$(inherited)",
228 | "$(PLATFORM_DIR)/Developer/Library/Frameworks",
229 | );
230 | HEADER_SEARCH_PATHS = "$(inherited)";
231 | INFOPLIST_FILE = MDText.xcodeproj/MDText_Info.plist;
232 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
233 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
234 | MACOSX_DEPLOYMENT_TARGET = 10.15;
235 | OTHER_CFLAGS = "$(inherited)";
236 | OTHER_LDFLAGS = "$(inherited)";
237 | OTHER_SWIFT_FLAGS = "$(inherited)";
238 | PRODUCT_BUNDLE_IDENTIFIER = MDText;
239 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
240 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
241 | SKIP_INSTALL = YES;
242 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
243 | SWIFT_VERSION = 5.0;
244 | TARGET_NAME = MDText;
245 | TVOS_DEPLOYMENT_TARGET = 13.0;
246 | WATCHOS_DEPLOYMENT_TARGET = 2.0;
247 | };
248 | name = Release;
249 | };
250 | OBJ_24 /* Debug */ = {
251 | isa = XCBuildConfiguration;
252 | buildSettings = {
253 | LD = /usr/bin/true;
254 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -package-description-version 5.1";
255 | SWIFT_VERSION = 5.0;
256 | };
257 | name = Debug;
258 | };
259 | OBJ_25 /* Release */ = {
260 | isa = XCBuildConfiguration;
261 | buildSettings = {
262 | LD = /usr/bin/true;
263 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -package-description-version 5.1";
264 | SWIFT_VERSION = 5.0;
265 | };
266 | name = Release;
267 | };
268 | OBJ_3 /* Debug */ = {
269 | isa = XCBuildConfiguration;
270 | buildSettings = {
271 | CLANG_ENABLE_OBJC_ARC = YES;
272 | COMBINE_HIDPI_IMAGES = YES;
273 | COPY_PHASE_STRIP = NO;
274 | DEBUG_INFORMATION_FORMAT = dwarf;
275 | DYLIB_INSTALL_NAME_BASE = "@rpath";
276 | ENABLE_NS_ASSERTIONS = YES;
277 | GCC_OPTIMIZATION_LEVEL = 0;
278 | GCC_PREPROCESSOR_DEFINITIONS = (
279 | "$(inherited)",
280 | "SWIFT_PACKAGE=1",
281 | "DEBUG=1",
282 | );
283 | MACOSX_DEPLOYMENT_TARGET = 10.10;
284 | ONLY_ACTIVE_ARCH = YES;
285 | OTHER_SWIFT_FLAGS = "$(inherited) -DXcode";
286 | PRODUCT_NAME = "$(TARGET_NAME)";
287 | SDKROOT = macosx;
288 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
289 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE DEBUG";
290 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
291 | USE_HEADERMAP = NO;
292 | };
293 | name = Debug;
294 | };
295 | OBJ_4 /* Release */ = {
296 | isa = XCBuildConfiguration;
297 | buildSettings = {
298 | CLANG_ENABLE_OBJC_ARC = YES;
299 | COMBINE_HIDPI_IMAGES = YES;
300 | COPY_PHASE_STRIP = YES;
301 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
302 | DYLIB_INSTALL_NAME_BASE = "@rpath";
303 | GCC_OPTIMIZATION_LEVEL = s;
304 | GCC_PREPROCESSOR_DEFINITIONS = (
305 | "$(inherited)",
306 | "SWIFT_PACKAGE=1",
307 | );
308 | MACOSX_DEPLOYMENT_TARGET = 10.10;
309 | OTHER_SWIFT_FLAGS = "$(inherited) -DXcode";
310 | PRODUCT_NAME = "$(TARGET_NAME)";
311 | SDKROOT = macosx;
312 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
313 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE";
314 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
315 | USE_HEADERMAP = NO;
316 | };
317 | name = Release;
318 | };
319 | /* End XCBuildConfiguration section */
320 |
321 | /* Begin XCConfigurationList section */
322 | OBJ_16 /* Build configuration list for PBXNativeTarget "MDText" */ = {
323 | isa = XCConfigurationList;
324 | buildConfigurations = (
325 | OBJ_17 /* Debug */,
326 | OBJ_18 /* Release */,
327 | );
328 | defaultConfigurationIsVisible = 0;
329 | defaultConfigurationName = Release;
330 | };
331 | OBJ_2 /* Build configuration list for PBXProject "MDText" */ = {
332 | isa = XCConfigurationList;
333 | buildConfigurations = (
334 | OBJ_3 /* Debug */,
335 | OBJ_4 /* Release */,
336 | );
337 | defaultConfigurationIsVisible = 0;
338 | defaultConfigurationName = Release;
339 | };
340 | OBJ_23 /* Build configuration list for PBXNativeTarget "MDTextPackageDescription" */ = {
341 | isa = XCConfigurationList;
342 | buildConfigurations = (
343 | OBJ_24 /* Debug */,
344 | OBJ_25 /* Release */,
345 | );
346 | defaultConfigurationIsVisible = 0;
347 | defaultConfigurationName = Release;
348 | };
349 | /* End XCConfigurationList section */
350 | };
351 | rootObject = OBJ_1 /* Project object */;
352 | }
353 |
--------------------------------------------------------------------------------
/Sources/MDText/MDText.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MDText.swift
3 | // MDText
4 | //
5 | // Created by Andre Carrera on 10/9/19.
6 | // Copyright © 2019 Lambdo. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 | import Combine
11 | #if os(iOS)
12 | import UIKit
13 | #elseif os(macOS)
14 | import AppKit
15 | #endif
16 |
17 | protocol MarkdownRule {
18 | var id: String { get }
19 | var regex: RegexMarkdown { get }
20 | // func replace(_ text: String) -> Text
21 | }
22 |
23 | struct MDTextGroup {
24 | var string: String
25 | var rules: [MarkdownRule]
26 | var applicableRules: [MarkdownRule] {
27 | rules.filter{$0.regex != BaseMarkdownRules.none.regex}
28 | }
29 | var text: Text {
30 | guard let firstRule = applicableRules.first else { return rules[0].regex.output(for: string) }
31 | return applicableRules.dropFirst().reduce(firstRule.regex.output(for: string)) { $1.regex.strategy($0) }
32 | }
33 |
34 | var viewType: MDViewType {
35 | applicableRules.contains(where: { $0.id == BaseMarkdownRules.link.id || $0.id == BaseMarkdownRules.hyperlink.id }) ?
36 | .link(self) : .text(self.text)
37 | }
38 |
39 | var urlStr: String {
40 | RegexMarkdown.url(for: string)
41 | }
42 |
43 | }
44 |
45 | enum MDViewType {
46 | case text(Text), link(MDTextGroup)
47 | }
48 |
49 | struct MDViewGroup: Identifiable {
50 | let id = UUID()
51 | var type: MDViewType
52 | var view: some View {
53 | switch type {
54 | case .link(let group):
55 | return Button(action: {self.onLinkTap(urlStr: group.urlStr)}, label: {group.text})
56 | .ereaseToAnyView()
57 | case .text(let text):
58 | return text.ereaseToAnyView()
59 | }
60 | }
61 |
62 | func onLinkTap(urlStr: String) {
63 | print(urlStr)
64 | guard let url = URL(string: urlStr) else { return }
65 | #if os(iOS)
66 | UIApplication.shared.open(url, options: [:])
67 | #elseif os(macOS)
68 | NSWorkspace.shared.open(url)
69 | #endif
70 | }
71 | }
72 |
73 |
74 | struct RegexMarkdown: Equatable {
75 | static func == (lhs: RegexMarkdown, rhs: RegexMarkdown) -> Bool {
76 | lhs.matchIn == rhs.matchIn && lhs.matchOut == rhs.matchOut
77 | }
78 |
79 | var matchIn: String
80 | var matchOut: String
81 | var strategy: (Text) -> Text
82 | func output(for string: String) -> Text {
83 | let result = outputString(for: string)
84 | let text = Text(result)
85 | return strategy(text)
86 | }
87 |
88 | func outputString(for string: String) -> String {
89 | guard !matchIn.isEmpty else {
90 | return string
91 | }
92 | return string.replacingOccurrences(of: self.matchIn, with: self.matchOut, options: .regularExpression)
93 | }
94 |
95 | static func url(for string: String) -> String {
96 | let matcher = try! NSRegularExpression(pattern: #"((http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*))"#)
97 | guard let match = matcher.firstMatch(in: string, range: NSRange(location: 0, length: string.utf16.count)) else { return ""}
98 | let result = string[Range(match.range, in: string)!]
99 | print(result)
100 | return String(result)
101 | }
102 | }
103 |
104 | extension RegexMarkdown {
105 | private var matcher: NSRegularExpression {
106 | return try! NSRegularExpression(pattern: self.matchIn)
107 |
108 | }
109 | func match(string: String, options: NSRegularExpression.MatchingOptions = .init()) -> Bool {
110 | return self.matcher.numberOfMatches(in: string, options: options, range: NSMakeRange(0, string.utf16.count)) != 0
111 | }
112 | }
113 |
114 | enum BaseMarkdownRules: String, CaseIterable, MarkdownRule {
115 |
116 |
117 | case none, header, link, bold, hyperlink, emphasis
118 | var id: String { self.rawValue }
119 | //
120 | // , , del, quote, inline, ul, ol, blockquotes
121 |
122 | var regex: RegexMarkdown {
123 | switch self {
124 | case .header:
125 | return .init(matchIn: #"(#+)(.*)"#, matchOut: "$2", strategy: self.header(_:))
126 | case .link:
127 | return .init(matchIn: #"\[([^\[]+)\]\(([^\)]+)\)"#, matchOut: "$1", strategy: self.link(_:))
128 | case .bold:
129 | return .init(matchIn: #"(\*\*|__)(.*?)\1"#, matchOut: "$2", strategy: self.bold(_:))
130 | case .hyperlink:
131 | return .init(matchIn: "<((?i)https?://(?:www\\.)?\\S+(?:/|\\b))>", matchOut: "$1", strategy: self.link(_:))
132 | case .emphasis:
133 | return .init(matchIn: #"(\s)(\*|_)(.+?)\2"#, matchOut: "$1$3", strategy: self.emphasis(_:))
134 | case .none:
135 | return .init(matchIn: "", matchOut: "", strategy: {$0})
136 | }
137 | }
138 |
139 | func header(_ text: Text) -> Text {
140 | return text.font(.headline)
141 | }
142 |
143 | func link(_ text: Text) -> Text {
144 | return text.foregroundColor(.blue)
145 | }
146 |
147 | func bold(_ text: Text) -> Text {
148 | return text.bold()
149 | }
150 |
151 | func emphasis(_ text: Text) -> Text {
152 | return text.italic()
153 | }
154 | }
155 |
156 | func onTapLink(url: String) {
157 |
158 | }
159 |
160 |
161 | // var rules: [String : ((String) -> AnyView))] {
162 | // [
163 | // #"/(#+)(.*)/"# -> self.header, // headers
164 | // #"/\[([^\[]+)\]\(([^\)]+)\)/"# -> '\1', // links
165 | // #"/(\*\*|__)(.*?)\1/"# -> '\2', // bold
166 | // #"/(\*|_)(.*?)\1/"# -> '\2', // emphasis
167 | // #"/\~\~(.*?)\~\~/"# -> '\1', // del
168 | // #"/\:\"(.*?)\"\:/"# -> '\1
', // quote
169 | // #"/`(.*?)`/"# -> '\1', // inline code
170 | // #"/\n\*(.*)/"# -> 'self::ul_list', // ul lists
171 | // #"/\n[0-9]+\.(.*)/"# -> 'self::ol_list', // ol lists
172 | // #"/\n(>|\>)(.*)/"# -> 'self::blockquote ', // blockquotes
173 | // #"/\n-{5,}/"# -> "\n
", // horizontal rule
174 | // #"/\n([^\n]+)\n/"# -> 'self::para', // add paragraphs
175 | // #"/<\/ul>\s?/"# -> '', // fix extra ul
176 | // #"/<\/ol>\s?/"# -> '', // fix extra ol
177 | // #"/<\/blockquote>/"# -> "\n" // fix extra blockquote
178 | // ]
179 | // }
180 |
181 | final class MDTextVM: ObservableObject {
182 |
183 | @Published var finalText = Text("")
184 |
185 | var cancellable: Cancellable? = nil { didSet{ oldValue?.cancel() } }
186 |
187 | func parse(string: String, for markdownRules: [MarkdownRule]) {
188 | let firstGroup = MDTextGroup(string: string, rules: [BaseMarkdownRules.none])
189 | cancellable = Just(markdownRules)
190 | .map{ rules -> [MDTextGroup] in
191 | rules.reduce([firstGroup]) { (result, rule) -> [MDTextGroup] in
192 | return result.flatMap{ self.replace(group: $0, for: rule)}
193 | }
194 | }
195 | .map { textGroups in
196 | textGroups.map{ $0.text}.reduce(Text(""), +)
197 | }
198 | .receive(on: RunLoop.main)
199 | .assign(to: \.finalText, on: self)
200 | }
201 |
202 | func parseText(string: String, for markdownRules: [MarkdownRule]) -> Text {
203 | let firstGroup = MDTextGroup(string: string, rules: [BaseMarkdownRules.none])
204 | let textGroups = markdownRules.reduce([firstGroup]) { (result, rule) -> [MDTextGroup] in
205 | return result.flatMap{ self.replace(group: $0, for: rule)}
206 | }
207 | return textGroups.map{ $0.text}.reduce(Text(""), +)
208 | }
209 |
210 | func parseViews(string: String, for markdownRules: [MarkdownRule]) -> [MDViewGroup] {
211 | let firstGroup = MDTextGroup(string: string, rules: [BaseMarkdownRules.none])
212 | let textGroups = markdownRules.reduce([firstGroup]) { (result, rule) -> [MDTextGroup] in
213 | return result.flatMap{ self.replace(group: $0, for: rule)}
214 | }
215 |
216 | guard let firstViewGroup = textGroups.first?.viewType else { return [] }
217 |
218 | let allViewGroups = textGroups.dropFirst().reduce([MDViewGroup(type: firstViewGroup)]) { (viewGroups, textGroup) -> [MDViewGroup] in
219 | let previous = viewGroups.last!
220 | if case .text(let previousText) = previous.type, case .text(let currentText) = textGroup.viewType {
221 | let updatedText = previousText + currentText
222 | return viewGroups.dropLast() + [MDViewGroup(type: .text(updatedText))]
223 | } else {
224 | return viewGroups + [MDViewGroup(type: textGroup.viewType)]
225 | }
226 | // if previous is just text
227 | }
228 | return allViewGroups
229 | }
230 |
231 | func replaceLInk(for textGroup: MDTextGroup) -> AnyView {
232 | return Button(action: {
233 | guard let url = URL(string: textGroup.string) else { return }
234 | #if os(iOS)
235 | UIApplication.shared.open(url, options: [:])
236 | #elseif os(macOS)
237 | NSWorkspace.shared.open(url)
238 | #endif
239 | }, label: {textGroup.text})
240 | .ereaseToAnyView()
241 | //
242 | // return textGroup.text.onTapGesture {
243 | // guard let url = URL(string: textGroup.string) else { return }
244 | // UIApplication.shared.open(url, options: [:])
245 | // }.ereaseToAnyView()
246 | }
247 |
248 | func replace(group: MDTextGroup, for rule: MarkdownRule) -> [MDTextGroup] {
249 | let string = group.string
250 | guard let regex = try? NSRegularExpression(pattern: rule.regex.matchIn)
251 | else {
252 | return [group]
253 | }
254 | let matches = regex.matches(in: string, range: NSRange(0.. [MDTextGroup] in
262 | let lowerBound = String.Index(utf16Offset: 0, in: string)
263 | let upperBound = String.Index(utf16Offset: range.lowerBound, in: string)
264 |
265 | let nonMatchStr = String(string[lowerBound.. [MDTextGroup] in
270 | guard let range = Range(current, in: string) else { return [] }
271 | let matchStr = String(string[range])
272 |
273 | let lowerBound = String.Index(utf16Offset: current.upperBound, in: string)
274 | let upperBound = String.Index(utf16Offset: next.lowerBound, in: string)
275 |
276 | let nonMatchStr = String(string[lowerBound.. [MDTextGroup] in
282 | guard let index = Range(range, in: string) else { return [] }
283 | let matchStr = String(string[index])
284 | return [MDTextGroup(string: matchStr, rules: group.rules + [rule])]
285 | } ?? []
286 |
287 | let afterMatchesGroup = ranges.last.flatMap { range -> [MDTextGroup] in
288 | let lowerBound = String.Index(utf16Offset: range.upperBound, in: string)
289 | let upperBound = string.endIndex
290 |
291 | if upperBound <= lowerBound { // basically if it ends with a match.
292 | return []
293 | }
294 |
295 | let nonMatchStr = String(string[lowerBound.. Bool {
312 | lhs.markdown == rhs.markdown
313 | }
314 |
315 | var markdown: String
316 | var alignment: HorizontalAlignment
317 |
318 | var rules: [MarkdownRule] = BaseMarkdownRules.allCases
319 |
320 | @ObservedObject var vm = MDTextVM()
321 |
322 | public init(markdown: String, alignment: HorizontalAlignment = .leading) {
323 | self.markdown = markdown
324 | self.alignment = alignment
325 | }
326 |
327 | var views: [MDViewGroup] {
328 | vm.parseViews(string: markdown, for: rules)
329 | }
330 |
331 | public var body: some View {
332 | VStack(alignment: alignment) {
333 | HStack { Spacer() }
334 | // vm.parseText(string: markdown, for: rules)
335 | ForEach(self.views, id: \.id) { viewGroup in
336 | viewGroup.view
337 | }
338 | }
339 | // .onAppear(perform: parse)
340 | }
341 |
342 | // func parse() {
343 | // vm.parse(string: markdown, for: rules)
344 | // }
345 | }
346 |
347 | extension View {
348 | func ereaseToAnyView() -> AnyView {
349 | AnyView(self)
350 | }
351 | }
352 |
--------------------------------------------------------------------------------
/MDTextTestApp/MDTextTestApp.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3C4A2D2F234E5D9C00502BAA /* MDText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C4A2D2E234E5D9C00502BAA /* MDText.framework */; };
11 | 3C4A2D30234E5D9C00502BAA /* MDText.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3C4A2D2E234E5D9C00502BAA /* MDText.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
12 | 3C50D548234E5B3E001A76D4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C50D547234E5B3E001A76D4 /* AppDelegate.swift */; };
13 | 3C50D54A234E5B3E001A76D4 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C50D549234E5B3E001A76D4 /* SceneDelegate.swift */; };
14 | 3C50D54C234E5B3E001A76D4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C50D54B234E5B3E001A76D4 /* ContentView.swift */; };
15 | 3C50D54E234E5B3E001A76D4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3C50D54D234E5B3E001A76D4 /* Assets.xcassets */; };
16 | 3C50D551234E5B3E001A76D4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3C50D550234E5B3E001A76D4 /* Preview Assets.xcassets */; };
17 | 3C50D554234E5B3E001A76D4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3C50D552234E5B3E001A76D4 /* LaunchScreen.storyboard */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXCopyFilesBuildPhase section */
21 | 3C4A2D31234E5D9C00502BAA /* Embed Frameworks */ = {
22 | isa = PBXCopyFilesBuildPhase;
23 | buildActionMask = 2147483647;
24 | dstPath = "";
25 | dstSubfolderSpec = 10;
26 | files = (
27 | 3C4A2D30234E5D9C00502BAA /* MDText.framework in Embed Frameworks */,
28 | );
29 | name = "Embed Frameworks";
30 | runOnlyForDeploymentPostprocessing = 0;
31 | };
32 | /* End PBXCopyFilesBuildPhase section */
33 |
34 | /* Begin PBXFileReference section */
35 | 3C4A2D2E234E5D9C00502BAA /* MDText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MDText.framework; sourceTree = BUILT_PRODUCTS_DIR; };
36 | 3C50D544234E5B3E001A76D4 /* MDTextTestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MDTextTestApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
37 | 3C50D547234E5B3E001A76D4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
38 | 3C50D549234E5B3E001A76D4 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
39 | 3C50D54B234E5B3E001A76D4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
40 | 3C50D54D234E5B3E001A76D4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
41 | 3C50D550234E5B3E001A76D4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
42 | 3C50D553234E5B3E001A76D4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
43 | 3C50D555234E5B3E001A76D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
44 | /* End PBXFileReference section */
45 |
46 | /* Begin PBXFrameworksBuildPhase section */
47 | 3C50D541234E5B3E001A76D4 /* Frameworks */ = {
48 | isa = PBXFrameworksBuildPhase;
49 | buildActionMask = 2147483647;
50 | files = (
51 | 3C4A2D2F234E5D9C00502BAA /* MDText.framework in Frameworks */,
52 | );
53 | runOnlyForDeploymentPostprocessing = 0;
54 | };
55 | /* End PBXFrameworksBuildPhase section */
56 |
57 | /* Begin PBXGroup section */
58 | 3C4A2D2D234E5D9C00502BAA /* Frameworks */ = {
59 | isa = PBXGroup;
60 | children = (
61 | 3C4A2D2E234E5D9C00502BAA /* MDText.framework */,
62 | );
63 | name = Frameworks;
64 | sourceTree = "";
65 | };
66 | 3C50D53B234E5B3D001A76D4 = {
67 | isa = PBXGroup;
68 | children = (
69 | 3C50D546234E5B3E001A76D4 /* MDTextTestApp */,
70 | 3C50D545234E5B3E001A76D4 /* Products */,
71 | 3C4A2D2D234E5D9C00502BAA /* Frameworks */,
72 | );
73 | sourceTree = "";
74 | };
75 | 3C50D545234E5B3E001A76D4 /* Products */ = {
76 | isa = PBXGroup;
77 | children = (
78 | 3C50D544234E5B3E001A76D4 /* MDTextTestApp.app */,
79 | );
80 | name = Products;
81 | sourceTree = "";
82 | };
83 | 3C50D546234E5B3E001A76D4 /* MDTextTestApp */ = {
84 | isa = PBXGroup;
85 | children = (
86 | 3C50D547234E5B3E001A76D4 /* AppDelegate.swift */,
87 | 3C50D549234E5B3E001A76D4 /* SceneDelegate.swift */,
88 | 3C50D54B234E5B3E001A76D4 /* ContentView.swift */,
89 | 3C50D54D234E5B3E001A76D4 /* Assets.xcassets */,
90 | 3C50D552234E5B3E001A76D4 /* LaunchScreen.storyboard */,
91 | 3C50D555234E5B3E001A76D4 /* Info.plist */,
92 | 3C50D54F234E5B3E001A76D4 /* Preview Content */,
93 | );
94 | path = MDTextTestApp;
95 | sourceTree = "";
96 | };
97 | 3C50D54F234E5B3E001A76D4 /* Preview Content */ = {
98 | isa = PBXGroup;
99 | children = (
100 | 3C50D550234E5B3E001A76D4 /* Preview Assets.xcassets */,
101 | );
102 | path = "Preview Content";
103 | sourceTree = "";
104 | };
105 | /* End PBXGroup section */
106 |
107 | /* Begin PBXNativeTarget section */
108 | 3C50D543234E5B3E001A76D4 /* MDTextTestApp */ = {
109 | isa = PBXNativeTarget;
110 | buildConfigurationList = 3C50D558234E5B3E001A76D4 /* Build configuration list for PBXNativeTarget "MDTextTestApp" */;
111 | buildPhases = (
112 | 3C50D540234E5B3E001A76D4 /* Sources */,
113 | 3C50D541234E5B3E001A76D4 /* Frameworks */,
114 | 3C50D542234E5B3E001A76D4 /* Resources */,
115 | 3C4A2D31234E5D9C00502BAA /* Embed Frameworks */,
116 | );
117 | buildRules = (
118 | );
119 | dependencies = (
120 | );
121 | name = MDTextTestApp;
122 | productName = MDTextTestApp;
123 | productReference = 3C50D544234E5B3E001A76D4 /* MDTextTestApp.app */;
124 | productType = "com.apple.product-type.application";
125 | };
126 | /* End PBXNativeTarget section */
127 |
128 | /* Begin PBXProject section */
129 | 3C50D53C234E5B3D001A76D4 /* Project object */ = {
130 | isa = PBXProject;
131 | attributes = {
132 | LastSwiftUpdateCheck = 1110;
133 | LastUpgradeCheck = 1110;
134 | ORGANIZATIONNAME = Lambdo;
135 | TargetAttributes = {
136 | 3C50D543234E5B3E001A76D4 = {
137 | CreatedOnToolsVersion = 11.1;
138 | };
139 | };
140 | };
141 | buildConfigurationList = 3C50D53F234E5B3D001A76D4 /* Build configuration list for PBXProject "MDTextTestApp" */;
142 | compatibilityVersion = "Xcode 9.3";
143 | developmentRegion = en;
144 | hasScannedForEncodings = 0;
145 | knownRegions = (
146 | en,
147 | Base,
148 | );
149 | mainGroup = 3C50D53B234E5B3D001A76D4;
150 | productRefGroup = 3C50D545234E5B3E001A76D4 /* Products */;
151 | projectDirPath = "";
152 | projectRoot = "";
153 | targets = (
154 | 3C50D543234E5B3E001A76D4 /* MDTextTestApp */,
155 | );
156 | };
157 | /* End PBXProject section */
158 |
159 | /* Begin PBXResourcesBuildPhase section */
160 | 3C50D542234E5B3E001A76D4 /* Resources */ = {
161 | isa = PBXResourcesBuildPhase;
162 | buildActionMask = 2147483647;
163 | files = (
164 | 3C50D554234E5B3E001A76D4 /* LaunchScreen.storyboard in Resources */,
165 | 3C50D551234E5B3E001A76D4 /* Preview Assets.xcassets in Resources */,
166 | 3C50D54E234E5B3E001A76D4 /* Assets.xcassets in Resources */,
167 | );
168 | runOnlyForDeploymentPostprocessing = 0;
169 | };
170 | /* End PBXResourcesBuildPhase section */
171 |
172 | /* Begin PBXSourcesBuildPhase section */
173 | 3C50D540234E5B3E001A76D4 /* Sources */ = {
174 | isa = PBXSourcesBuildPhase;
175 | buildActionMask = 2147483647;
176 | files = (
177 | 3C50D548234E5B3E001A76D4 /* AppDelegate.swift in Sources */,
178 | 3C50D54A234E5B3E001A76D4 /* SceneDelegate.swift in Sources */,
179 | 3C50D54C234E5B3E001A76D4 /* ContentView.swift in Sources */,
180 | );
181 | runOnlyForDeploymentPostprocessing = 0;
182 | };
183 | /* End PBXSourcesBuildPhase section */
184 |
185 | /* Begin PBXVariantGroup section */
186 | 3C50D552234E5B3E001A76D4 /* LaunchScreen.storyboard */ = {
187 | isa = PBXVariantGroup;
188 | children = (
189 | 3C50D553234E5B3E001A76D4 /* Base */,
190 | );
191 | name = LaunchScreen.storyboard;
192 | sourceTree = "";
193 | };
194 | /* End PBXVariantGroup section */
195 |
196 | /* Begin XCBuildConfiguration section */
197 | 3C50D556234E5B3E001A76D4 /* Debug */ = {
198 | isa = XCBuildConfiguration;
199 | buildSettings = {
200 | ALWAYS_SEARCH_USER_PATHS = NO;
201 | CLANG_ANALYZER_NONNULL = YES;
202 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
203 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
204 | CLANG_CXX_LIBRARY = "libc++";
205 | CLANG_ENABLE_MODULES = YES;
206 | CLANG_ENABLE_OBJC_ARC = YES;
207 | CLANG_ENABLE_OBJC_WEAK = YES;
208 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
209 | CLANG_WARN_BOOL_CONVERSION = YES;
210 | CLANG_WARN_COMMA = YES;
211 | CLANG_WARN_CONSTANT_CONVERSION = YES;
212 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
213 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
214 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
215 | CLANG_WARN_EMPTY_BODY = YES;
216 | CLANG_WARN_ENUM_CONVERSION = YES;
217 | CLANG_WARN_INFINITE_RECURSION = YES;
218 | CLANG_WARN_INT_CONVERSION = YES;
219 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
220 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
221 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
222 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
223 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
224 | CLANG_WARN_STRICT_PROTOTYPES = YES;
225 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
226 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
227 | CLANG_WARN_UNREACHABLE_CODE = YES;
228 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
229 | COPY_PHASE_STRIP = NO;
230 | DEBUG_INFORMATION_FORMAT = dwarf;
231 | ENABLE_STRICT_OBJC_MSGSEND = YES;
232 | ENABLE_TESTABILITY = YES;
233 | GCC_C_LANGUAGE_STANDARD = gnu11;
234 | GCC_DYNAMIC_NO_PIC = NO;
235 | GCC_NO_COMMON_BLOCKS = YES;
236 | GCC_OPTIMIZATION_LEVEL = 0;
237 | GCC_PREPROCESSOR_DEFINITIONS = (
238 | "DEBUG=1",
239 | "$(inherited)",
240 | );
241 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
242 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
243 | GCC_WARN_UNDECLARED_SELECTOR = YES;
244 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
245 | GCC_WARN_UNUSED_FUNCTION = YES;
246 | GCC_WARN_UNUSED_VARIABLE = YES;
247 | IPHONEOS_DEPLOYMENT_TARGET = 13.1;
248 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
249 | MTL_FAST_MATH = YES;
250 | ONLY_ACTIVE_ARCH = YES;
251 | SDKROOT = iphoneos;
252 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
253 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
254 | };
255 | name = Debug;
256 | };
257 | 3C50D557234E5B3E001A76D4 /* Release */ = {
258 | isa = XCBuildConfiguration;
259 | buildSettings = {
260 | ALWAYS_SEARCH_USER_PATHS = NO;
261 | CLANG_ANALYZER_NONNULL = YES;
262 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
263 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
264 | CLANG_CXX_LIBRARY = "libc++";
265 | CLANG_ENABLE_MODULES = YES;
266 | CLANG_ENABLE_OBJC_ARC = YES;
267 | CLANG_ENABLE_OBJC_WEAK = YES;
268 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
269 | CLANG_WARN_BOOL_CONVERSION = YES;
270 | CLANG_WARN_COMMA = YES;
271 | CLANG_WARN_CONSTANT_CONVERSION = YES;
272 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
273 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
274 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
275 | CLANG_WARN_EMPTY_BODY = YES;
276 | CLANG_WARN_ENUM_CONVERSION = YES;
277 | CLANG_WARN_INFINITE_RECURSION = YES;
278 | CLANG_WARN_INT_CONVERSION = YES;
279 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
280 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
281 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
282 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
283 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
284 | CLANG_WARN_STRICT_PROTOTYPES = YES;
285 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
286 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
287 | CLANG_WARN_UNREACHABLE_CODE = YES;
288 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
289 | COPY_PHASE_STRIP = NO;
290 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
291 | ENABLE_NS_ASSERTIONS = NO;
292 | ENABLE_STRICT_OBJC_MSGSEND = YES;
293 | GCC_C_LANGUAGE_STANDARD = gnu11;
294 | GCC_NO_COMMON_BLOCKS = YES;
295 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
296 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
297 | GCC_WARN_UNDECLARED_SELECTOR = YES;
298 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
299 | GCC_WARN_UNUSED_FUNCTION = YES;
300 | GCC_WARN_UNUSED_VARIABLE = YES;
301 | IPHONEOS_DEPLOYMENT_TARGET = 13.1;
302 | MTL_ENABLE_DEBUG_INFO = NO;
303 | MTL_FAST_MATH = YES;
304 | SDKROOT = iphoneos;
305 | SWIFT_COMPILATION_MODE = wholemodule;
306 | SWIFT_OPTIMIZATION_LEVEL = "-O";
307 | VALIDATE_PRODUCT = YES;
308 | };
309 | name = Release;
310 | };
311 | 3C50D559234E5B3E001A76D4 /* Debug */ = {
312 | isa = XCBuildConfiguration;
313 | buildSettings = {
314 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
315 | CODE_SIGN_STYLE = Automatic;
316 | DEVELOPMENT_ASSET_PATHS = "\"MDTextTestApp/Preview Content\"";
317 | DEVELOPMENT_TEAM = C2P78ME6KC;
318 | ENABLE_PREVIEWS = YES;
319 | INFOPLIST_FILE = MDTextTestApp/Info.plist;
320 | LD_RUNPATH_SEARCH_PATHS = (
321 | "$(inherited)",
322 | "@executable_path/Frameworks",
323 | );
324 | PRODUCT_BUNDLE_IDENTIFIER = com.lambdo.MDTextTestApp;
325 | PRODUCT_NAME = "$(TARGET_NAME)";
326 | SWIFT_VERSION = 5.0;
327 | TARGETED_DEVICE_FAMILY = "1,2";
328 | };
329 | name = Debug;
330 | };
331 | 3C50D55A234E5B3E001A76D4 /* Release */ = {
332 | isa = XCBuildConfiguration;
333 | buildSettings = {
334 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
335 | CODE_SIGN_STYLE = Automatic;
336 | DEVELOPMENT_ASSET_PATHS = "\"MDTextTestApp/Preview Content\"";
337 | DEVELOPMENT_TEAM = C2P78ME6KC;
338 | ENABLE_PREVIEWS = YES;
339 | INFOPLIST_FILE = MDTextTestApp/Info.plist;
340 | LD_RUNPATH_SEARCH_PATHS = (
341 | "$(inherited)",
342 | "@executable_path/Frameworks",
343 | );
344 | PRODUCT_BUNDLE_IDENTIFIER = com.lambdo.MDTextTestApp;
345 | PRODUCT_NAME = "$(TARGET_NAME)";
346 | SWIFT_VERSION = 5.0;
347 | TARGETED_DEVICE_FAMILY = "1,2";
348 | };
349 | name = Release;
350 | };
351 | /* End XCBuildConfiguration section */
352 |
353 | /* Begin XCConfigurationList section */
354 | 3C50D53F234E5B3D001A76D4 /* Build configuration list for PBXProject "MDTextTestApp" */ = {
355 | isa = XCConfigurationList;
356 | buildConfigurations = (
357 | 3C50D556234E5B3E001A76D4 /* Debug */,
358 | 3C50D557234E5B3E001A76D4 /* Release */,
359 | );
360 | defaultConfigurationIsVisible = 0;
361 | defaultConfigurationName = Release;
362 | };
363 | 3C50D558234E5B3E001A76D4 /* Build configuration list for PBXNativeTarget "MDTextTestApp" */ = {
364 | isa = XCConfigurationList;
365 | buildConfigurations = (
366 | 3C50D559234E5B3E001A76D4 /* Debug */,
367 | 3C50D55A234E5B3E001A76D4 /* Release */,
368 | );
369 | defaultConfigurationIsVisible = 0;
370 | defaultConfigurationName = Release;
371 | };
372 | /* End XCConfigurationList section */
373 | };
374 | rootObject = 3C50D53C234E5B3D001A76D4 /* Project object */;
375 | }
376 |
--------------------------------------------------------------------------------