Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,50 @@

/* Begin PBXBuildFile section */
A10000010000000000000001 /* EnrichedMarkdownExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000001 /* EnrichedMarkdownExampleApp.swift */; };
A10000010000000000000002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000002 /* ContentView.swift */; };
A10000010000000000000003 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000003 /* Assets.xcassets */; };
A10000010000000000000004 /* EnrichedMarkdown in Frameworks */ = {isa = PBXBuildFile; productRef = A10000050000000000000001 /* EnrichedMarkdown */; };
A10000010000000000000010 /* AppShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000010 /* AppShell.swift */; };
A10000010000000000000011 /* ExampleRoute.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000011 /* ExampleRoute.swift */; };
A10000010000000000000012 /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000012 /* HomeScreen.swift */; };
A10000010000000000000013 /* HomeScreenButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000013 /* HomeScreenButton.swift */; };
A10000010000000000000014 /* TextScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000014 /* TextScreen.swift */; };
A10000010000000000000015 /* PlaygroundScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000015 /* PlaygroundScreen.swift */; };
A10000010000000000000016 /* ExampleMarkdownStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000016 /* ExampleMarkdownStyles.swift */; };
A10000010000000000000017 /* ExampleFontRegistrar.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000017 /* ExampleFontRegistrar.swift */; };
A10000010000000000000020 /* sample_markdown.md in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000020 /* sample_markdown.md */; };
A10000010000000000000021 /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000021 /* logo.png */; };
A10000010000000000000022 /* logo_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000022 /* logo_icon.png */; };
A10000010000000000000030 /* Montserrat-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000030 /* Montserrat-Regular.ttf */; };
A10000010000000000000031 /* Montserrat-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000031 /* Montserrat-Bold.ttf */; };
A10000010000000000000032 /* Montserrat-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000032 /* Montserrat-SemiBold.ttf */; };
A10000010000000000000033 /* Montserrat-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000033 /* Montserrat-Medium.ttf */; };
A10000010000000000000034 /* Montserrat-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000034 /* Montserrat-Italic.ttf */; };
A10000010000000000000036 /* Montserrat-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000036 /* Montserrat-BoldItalic.ttf */; };
A10000010000000000000035 /* CourierPrime-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A10000020000000000000035 /* CourierPrime-Regular.ttf */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
A10000020000000000000001 /* EnrichedMarkdownExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnrichedMarkdownExampleApp.swift; sourceTree = "<group>"; };
A10000020000000000000002 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
A10000020000000000000003 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
A10000020000000000000004 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A10000020000000000000010 /* AppShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppShell.swift; sourceTree = "<group>"; };
A10000020000000000000011 /* ExampleRoute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleRoute.swift; sourceTree = "<group>"; };
A10000020000000000000012 /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = "<group>"; };
A10000020000000000000013 /* HomeScreenButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenButton.swift; sourceTree = "<group>"; };
A10000020000000000000014 /* TextScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextScreen.swift; sourceTree = "<group>"; };
A10000020000000000000015 /* PlaygroundScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaygroundScreen.swift; sourceTree = "<group>"; };
A10000020000000000000016 /* ExampleMarkdownStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleMarkdownStyles.swift; sourceTree = "<group>"; };
A10000020000000000000017 /* ExampleFontRegistrar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleFontRegistrar.swift; sourceTree = "<group>"; };
A10000020000000000000020 /* sample_markdown.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = sample_markdown.md; sourceTree = "<group>"; };
A10000020000000000000021 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = "<group>"; };
A10000020000000000000022 /* logo_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo_icon.png; sourceTree = "<group>"; };
A10000020000000000000030 /* Montserrat-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Montserrat-Regular.ttf"; sourceTree = "<group>"; };
A10000020000000000000031 /* Montserrat-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Montserrat-Bold.ttf"; sourceTree = "<group>"; };
A10000020000000000000032 /* Montserrat-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Montserrat-SemiBold.ttf"; sourceTree = "<group>"; };
A10000020000000000000033 /* Montserrat-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Montserrat-Medium.ttf"; sourceTree = "<group>"; };
A10000020000000000000034 /* Montserrat-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Montserrat-Italic.ttf"; sourceTree = "<group>"; };
A10000020000000000000036 /* Montserrat-BoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Montserrat-BoldItalic.ttf"; sourceTree = "<group>"; };
A10000020000000000000035 /* CourierPrime-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "CourierPrime-Regular.ttf"; sourceTree = "<group>"; };
A10000030000000000000001 /* EnrichedMarkdownExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EnrichedMarkdownExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -45,7 +79,15 @@
isa = PBXGroup;
children = (
A10000020000000000000001 /* EnrichedMarkdownExampleApp.swift */,
A10000020000000000000002 /* ContentView.swift */,
A10000020000000000000010 /* AppShell.swift */,
A10000020000000000000011 /* ExampleRoute.swift */,
A10000020000000000000012 /* HomeScreen.swift */,
A10000020000000000000013 /* HomeScreenButton.swift */,
A10000020000000000000014 /* TextScreen.swift */,
A10000020000000000000015 /* PlaygroundScreen.swift */,
A10000020000000000000016 /* ExampleMarkdownStyles.swift */,
A10000020000000000000017 /* ExampleFontRegistrar.swift */,
A10000060000000000000004 /* Resources */,
A10000020000000000000003 /* Assets.xcassets */,
A10000020000000000000004 /* Info.plist */,
);
Expand All @@ -60,6 +102,31 @@
name = Products;
sourceTree = "<group>";
};
A10000060000000000000004 /* Resources */ = {
isa = PBXGroup;
children = (
A10000060000000000000005 /* Fonts */,
A10000020000000000000020 /* sample_markdown.md */,
A10000020000000000000021 /* logo.png */,
A10000020000000000000022 /* logo_icon.png */,
);
path = Resources;
sourceTree = "<group>";
};
A10000060000000000000005 /* Fonts */ = {
isa = PBXGroup;
children = (
A10000020000000000000030 /* Montserrat-Regular.ttf */,
A10000020000000000000031 /* Montserrat-Bold.ttf */,
A10000020000000000000032 /* Montserrat-SemiBold.ttf */,
A10000020000000000000033 /* Montserrat-Medium.ttf */,
A10000020000000000000034 /* Montserrat-Italic.ttf */,
A10000020000000000000036 /* Montserrat-BoldItalic.ttf */,
A10000020000000000000035 /* CourierPrime-Regular.ttf */,
);
path = Fonts;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -125,6 +192,16 @@
buildActionMask = 2147483647;
files = (
A10000010000000000000003 /* Assets.xcassets in Resources */,
A10000010000000000000020 /* sample_markdown.md in Resources */,
A10000010000000000000021 /* logo.png in Resources */,
A10000010000000000000022 /* logo_icon.png in Resources */,
A10000010000000000000030 /* Montserrat-Regular.ttf in Resources */,
A10000010000000000000031 /* Montserrat-Bold.ttf in Resources */,
A10000010000000000000032 /* Montserrat-SemiBold.ttf in Resources */,
A10000010000000000000033 /* Montserrat-Medium.ttf in Resources */,
A10000010000000000000034 /* Montserrat-Italic.ttf in Resources */,
A10000010000000000000036 /* Montserrat-BoldItalic.ttf in Resources */,
A10000010000000000000035 /* CourierPrime-Regular.ttf in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -136,7 +213,14 @@
buildActionMask = 2147483647;
files = (
A10000010000000000000001 /* EnrichedMarkdownExampleApp.swift in Sources */,
A10000010000000000000002 /* ContentView.swift in Sources */,
A10000010000000000000010 /* AppShell.swift in Sources */,
A10000010000000000000011 /* ExampleRoute.swift in Sources */,
A10000010000000000000012 /* HomeScreen.swift in Sources */,
A10000010000000000000013 /* HomeScreenButton.swift in Sources */,
A10000010000000000000014 /* TextScreen.swift in Sources */,
A10000010000000000000015 /* PlaygroundScreen.swift in Sources */,
A10000010000000000000016 /* ExampleMarkdownStyles.swift in Sources */,
A10000010000000000000017 /* ExampleFontRegistrar.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -161,7 +245,7 @@
"DEBUG=1",
"$(inherited)",
);
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand All @@ -182,7 +266,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import EnrichedMarkdown
import SwiftUI

struct AppShell: View {
@State private var route: ExampleRoute = .home
@State private var unavailableRouteName: String?
@State private var sampleMarkdown = ""

private var navigationTitle: String {
switch route {
case .home:
return "Enriched Markdown Examples"
case .playground:
return "Playground"
case .text:
return "Text"
case .input, .stream, .storybook:
return routeName(route)
}
}

var body: some View {
NavigationStack {
Group {
switch route {
case .home:
HomeScreen(onNavigate: handleNavigate)
case .playground:
PlaygroundScreen()
case .text:
TextScreen(markdown: sampleMarkdown)
case .input, .stream, .storybook:
EmptyView()
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.navigationTitle(navigationTitle)
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(AppColors.toolbarBackground, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.toolbarColorScheme(.light, for: .navigationBar)
.toolbar {
if route != .home {
ToolbarItem(placement: .navigationBarLeading) {
Button("Back") {
route = .home
}
.foregroundStyle(AppColors.toolbarForeground)
}
}
}
}
.tint(AppColors.toolbarForeground)
.onAppear {
if sampleMarkdown.isEmpty {
sampleMarkdown = BundleLoader.sampleMarkdown
}
}
.alert(
unavailableRouteName.map { "\($0) is not available on iOS yet" } ?? "",
isPresented: Binding(
get: { unavailableRouteName != nil },
set: { if !$0 { unavailableRouteName = nil } }
)
) {
Button("OK", role: .cancel) {}
}
}

private func handleNavigate(_ target: ExampleRoute) {
switch target {
case .playground, .text:
route = target
case .input, .stream, .storybook:
unavailableRouteName = routeName(target)
case .home:
route = .home
}
}

private func routeName(_ route: ExampleRoute) -> String {
switch route {
case .home: return "Home"
case .playground: return "Playground"
case .text: return "Text"
case .input: return "Input"
case .stream: return "Stream"
case .storybook: return "Storybook"
}
}
}

private enum AppColors {
static let toolbarBackground = Color(red: 190 / 255, green: 235 / 255, blue: 208 / 255)
static let toolbarForeground = Color(red: 0 / 255, green: 26 / 255, blue: 114 / 255)
}

private enum BundleLoader {
static var sampleMarkdown: String {
guard
let url = Bundle.main.url(forResource: "sample_markdown", withExtension: "md"),
let content = try? String(contentsOf: url, encoding: .utf8)
else {
return ""
}
return content
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import SwiftUI

@main
struct EnrichedMarkdownExampleApp: App {
init() {
ExampleFontRegistrar.registerBundledFonts()
}

var body: some Scene {
WindowGroup {
ContentView()
AppShell()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import CoreText
import UIKit

enum ExampleFontRegistrar {
private static let fontFilenames = [
"Montserrat-Regular",
"Montserrat-Bold",
"Montserrat-SemiBold",
"Montserrat-Medium",
"Montserrat-Italic",
"Montserrat-BoldItalic",
"CourierPrime-Regular",
]

/// Registers example fonts from the app bundle before any markdown is rendered.
static func registerBundledFonts() {
var registeredCount = 0
for filename in fontFilenames where registerFont(filename: filename) {
registeredCount += 1
}

#if DEBUG
if registeredCount == 0 {
assertionFailure(
"""
No bundled fonts were found in EnrichedMarkdownExample.app.
Delete the app from the simulator, Product > Clean Build Folder, then run again.
"""
)
} else if registeredCount < fontFilenames.count {
print("ExampleFontRegistrar: registered \(registeredCount)/\(fontFilenames.count) fonts")
}
#endif
}

@discardableResult
private static func registerFont(filename: String) -> Bool {
guard let url = fontURL(for: filename) else { return false }

var error: Unmanaged<CFError>?
let didRegister = CTFontManagerRegisterFontsForURL(url as CFURL, .process, &error)
if !didRegister, let error {
#if DEBUG
print("ExampleFontRegistrar: failed to register \(filename): \(error.takeRetainedValue())")
#endif
}
return didRegister
}

private static func fontURL(for filename: String) -> URL? {
Bundle.main.url(forResource: filename, withExtension: "ttf", subdirectory: "Fonts")
?? Bundle.main.url(forResource: filename, withExtension: "ttf")
}
}
Loading
Loading