Compare commits

..

No commits in common. "7da0368758bd6700f0bf21fe473b17e516fd2c84" and "229c6478a523ed9ab6fda637a2130a5e03aae64e" have entirely different histories.

18 changed files with 25 additions and 833 deletions

View File

@ -31,19 +31,6 @@
D62664BE24BBF26A00DF9B88 /* GeminiFormat.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
D62664C624BBF27300DF9B88 /* GeminiParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62664C524BBF27300DF9B88 /* GeminiParser.swift */; };
D62664C824BBF2C600DF9B88 /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62664C724BBF2C600DF9B88 /* Document.swift */; };
D62664D724BC081B00DF9B88 /* GeminiRenderer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D62664CE24BC081B00DF9B88 /* GeminiRenderer.framework */; };
D62664DE24BC081B00DF9B88 /* GeminiRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62664DD24BC081B00DF9B88 /* GeminiRendererTests.swift */; };
D62664E024BC081B00DF9B88 /* GeminiRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = D62664D024BC081B00DF9B88 /* GeminiRenderer.h */; settings = {ATTRIBUTES = (Public, ); }; };
D62664E324BC081B00DF9B88 /* GeminiRenderer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D62664CE24BC081B00DF9B88 /* GeminiRenderer.framework */; };
D62664E424BC081B00DF9B88 /* GeminiRenderer.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D62664CE24BC081B00DF9B88 /* GeminiRenderer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
D62664EC24BC0B4D00DF9B88 /* DocumentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62664EB24BC0B4D00DF9B88 /* DocumentView.swift */; };
D62664EE24BC0BCE00DF9B88 /* MaybeLazyVStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62664ED24BC0BCE00DF9B88 /* MaybeLazyVStack.swift */; };
D62664F024BC0D7700DF9B88 /* GeminiFormat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */; };
D62664F124BC0D7700DF9B88 /* GeminiFormat.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
D62664FA24BC12BC00DF9B88 /* DocumentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62664F924BC12BC00DF9B88 /* DocumentTests.swift */; };
D664673624BD07F700B0B741 /* RenderingBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = D664673524BD07F700B0B741 /* RenderingBlock.swift */; };
D664673824BD086F00B0B741 /* RenderingBlockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D664673724BD086F00B0B741 /* RenderingBlockView.swift */; };
D664673A24BD0B8E00B0B741 /* Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = D664673924BD0B8E00B0B741 /* Fonts.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -89,34 +76,6 @@
remoteGlobalIDString = D62664A724BBF26A00DF9B88;
remoteInfo = GeminiFormat;
};
D62664D824BC081B00DF9B88 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
proxyType = 1;
remoteGlobalIDString = D62664CD24BC081B00DF9B88;
remoteInfo = GeminiRenderer;
};
D62664DA24BC081B00DF9B88 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
proxyType = 1;
remoteGlobalIDString = D626645A24BBF1C200DF9B88;
remoteInfo = Gemini;
};
D62664E124BC081B00DF9B88 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
proxyType = 1;
remoteGlobalIDString = D62664CD24BC081B00DF9B88;
remoteInfo = GeminiRenderer;
};
D62664F224BC0D7700DF9B88 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
proxyType = 1;
remoteGlobalIDString = D62664A724BBF26A00DF9B88;
remoteInfo = GeminiFormat;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@ -126,24 +85,12 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
D62664E424BC081B00DF9B88 /* GeminiRenderer.framework in Embed Frameworks */,
D62664BE24BBF26A00DF9B88 /* GeminiFormat.framework in Embed Frameworks */,
D626648D24BBF22E00DF9B88 /* GeminiProtocol.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
D62664F424BC0D7700DF9B88 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
D62664F124BC0D7700DF9B88 /* GeminiFormat.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
@ -176,18 +123,6 @@
D62664B924BBF26A00DF9B88 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D62664C524BBF27300DF9B88 /* GeminiParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiParser.swift; sourceTree = "<group>"; };
D62664C724BBF2C600DF9B88 /* Document.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Document.swift; sourceTree = "<group>"; };
D62664CE24BC081B00DF9B88 /* GeminiRenderer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GeminiRenderer.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D62664D024BC081B00DF9B88 /* GeminiRenderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeminiRenderer.h; sourceTree = "<group>"; };
D62664D124BC081B00DF9B88 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D62664D624BC081B00DF9B88 /* GeminiRendererTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GeminiRendererTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
D62664DD24BC081B00DF9B88 /* GeminiRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiRendererTests.swift; sourceTree = "<group>"; };
D62664DF24BC081B00DF9B88 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D62664EB24BC0B4D00DF9B88 /* DocumentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentView.swift; sourceTree = "<group>"; };
D62664ED24BC0BCE00DF9B88 /* MaybeLazyVStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MaybeLazyVStack.swift; sourceTree = "<group>"; };
D62664F924BC12BC00DF9B88 /* DocumentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentTests.swift; sourceTree = "<group>"; };
D664673524BD07F700B0B741 /* RenderingBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenderingBlock.swift; sourceTree = "<group>"; };
D664673724BD086F00B0B741 /* RenderingBlockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenderingBlockView.swift; sourceTree = "<group>"; };
D664673924BD0B8E00B0B741 /* Fonts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fonts.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -195,7 +130,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D62664E324BC081B00DF9B88 /* GeminiRenderer.framework in Frameworks */,
D62664BD24BBF26A00DF9B88 /* GeminiFormat.framework in Frameworks */,
D626648C24BBF22E00DF9B88 /* GeminiProtocol.framework in Frameworks */,
);
@ -231,22 +165,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
D62664CB24BC081B00DF9B88 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D62664F024BC0D7700DF9B88 /* GeminiFormat.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D62664D324BC081B00DF9B88 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D62664D724BC081B00DF9B88 /* GeminiRenderer.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@ -258,10 +176,7 @@
D626648524BBF22E00DF9B88 /* GeminiProtocolTests */,
D62664A924BBF26A00DF9B88 /* GeminiFormat */,
D62664B624BBF26A00DF9B88 /* GeminiFormatTests */,
D62664CF24BC081B00DF9B88 /* GeminiRenderer */,
D62664DC24BC081B00DF9B88 /* GeminiRendererTests */,
D626645C24BBF1C200DF9B88 /* Products */,
D62664EF24BC0D7700DF9B88 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -273,8 +188,6 @@
D626647F24BBF22E00DF9B88 /* GeminiProtocolTests.xctest */,
D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */,
D62664B024BBF26A00DF9B88 /* GeminiFormatTests.xctest */,
D62664CE24BC081B00DF9B88 /* GeminiRenderer.framework */,
D62664D624BC081B00DF9B88 /* GeminiRendererTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@ -340,43 +253,12 @@
D62664B624BBF26A00DF9B88 /* GeminiFormatTests */ = {
isa = PBXGroup;
children = (
D62664F924BC12BC00DF9B88 /* DocumentTests.swift */,
D62664B724BBF26A00DF9B88 /* GeminiParserTests.swift */,
D62664B924BBF26A00DF9B88 /* Info.plist */,
);
path = GeminiFormatTests;
sourceTree = "<group>";
};
D62664CF24BC081B00DF9B88 /* GeminiRenderer */ = {
isa = PBXGroup;
children = (
D62664D024BC081B00DF9B88 /* GeminiRenderer.h */,
D62664D124BC081B00DF9B88 /* Info.plist */,
D664673524BD07F700B0B741 /* RenderingBlock.swift */,
D664673924BD0B8E00B0B741 /* Fonts.swift */,
D62664ED24BC0BCE00DF9B88 /* MaybeLazyVStack.swift */,
D62664EB24BC0B4D00DF9B88 /* DocumentView.swift */,
D664673724BD086F00B0B741 /* RenderingBlockView.swift */,
);
path = GeminiRenderer;
sourceTree = "<group>";
};
D62664DC24BC081B00DF9B88 /* GeminiRendererTests */ = {
isa = PBXGroup;
children = (
D62664DD24BC081B00DF9B88 /* GeminiRendererTests.swift */,
D62664DF24BC081B00DF9B88 /* Info.plist */,
);
path = GeminiRendererTests;
sourceTree = "<group>";
};
D62664EF24BC0D7700DF9B88 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -396,14 +278,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
D62664C924BC081B00DF9B88 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
D62664E024BC081B00DF9B88 /* GeminiRenderer.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
@ -421,7 +295,6 @@
dependencies = (
D626648B24BBF22E00DF9B88 /* PBXTargetDependency */,
D62664BC24BBF26A00DF9B88 /* PBXTargetDependency */,
D62664E224BC081B00DF9B88 /* PBXTargetDependency */,
);
name = Gemini;
productName = Gemini;
@ -502,45 +375,6 @@
productReference = D62664B024BBF26A00DF9B88 /* GeminiFormatTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
D62664CD24BC081B00DF9B88 /* GeminiRenderer */ = {
isa = PBXNativeTarget;
buildConfigurationList = D62664E524BC081B00DF9B88 /* Build configuration list for PBXNativeTarget "GeminiRenderer" */;
buildPhases = (
D62664C924BC081B00DF9B88 /* Headers */,
D62664CA24BC081B00DF9B88 /* Sources */,
D62664CB24BC081B00DF9B88 /* Frameworks */,
D62664CC24BC081B00DF9B88 /* Resources */,
D62664F424BC0D7700DF9B88 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
D62664F324BC0D7700DF9B88 /* PBXTargetDependency */,
);
name = GeminiRenderer;
productName = GeminiRenderer;
productReference = D62664CE24BC081B00DF9B88 /* GeminiRenderer.framework */;
productType = "com.apple.product-type.framework";
};
D62664D524BC081B00DF9B88 /* GeminiRendererTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = D62664E824BC081B00DF9B88 /* Build configuration list for PBXNativeTarget "GeminiRendererTests" */;
buildPhases = (
D62664D224BC081B00DF9B88 /* Sources */,
D62664D324BC081B00DF9B88 /* Frameworks */,
D62664D424BC081B00DF9B88 /* Resources */,
);
buildRules = (
);
dependencies = (
D62664D924BC081B00DF9B88 /* PBXTargetDependency */,
D62664DB24BC081B00DF9B88 /* PBXTargetDependency */,
);
name = GeminiRendererTests;
productName = GeminiRendererTests;
productReference = D62664D624BC081B00DF9B88 /* GeminiRendererTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@ -569,14 +403,6 @@
CreatedOnToolsVersion = 12.0;
TestTargetID = D626645A24BBF1C200DF9B88;
};
D62664CD24BC081B00DF9B88 = {
CreatedOnToolsVersion = 12.0;
LastSwiftMigration = 1200;
};
D62664D524BC081B00DF9B88 = {
CreatedOnToolsVersion = 12.0;
TestTargetID = D626645A24BBF1C200DF9B88;
};
};
};
buildConfigurationList = D626645624BBF1C200DF9B88 /* Build configuration list for PBXProject "Gemini" */;
@ -597,8 +423,6 @@
D626647E24BBF22E00DF9B88 /* GeminiProtocolTests */,
D62664A724BBF26A00DF9B88 /* GeminiFormat */,
D62664AF24BBF26A00DF9B88 /* GeminiFormatTests */,
D62664CD24BC081B00DF9B88 /* GeminiRenderer */,
D62664D524BC081B00DF9B88 /* GeminiRendererTests */,
);
};
/* End PBXProject section */
@ -642,20 +466,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
D62664CC24BC081B00DF9B88 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D62664D424BC081B00DF9B88 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@ -703,31 +513,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D62664FA24BC12BC00DF9B88 /* DocumentTests.swift in Sources */,
D62664B824BBF26A00DF9B88 /* GeminiParserTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D62664CA24BC081B00DF9B88 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D664673624BD07F700B0B741 /* RenderingBlock.swift in Sources */,
D664673A24BD0B8E00B0B741 /* Fonts.swift in Sources */,
D62664EE24BC0BCE00DF9B88 /* MaybeLazyVStack.swift in Sources */,
D62664EC24BC0B4D00DF9B88 /* DocumentView.swift in Sources */,
D664673824BD086F00B0B741 /* RenderingBlockView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D62664D224BC081B00DF9B88 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D62664DE24BC081B00DF9B88 /* GeminiRendererTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@ -761,26 +550,6 @@
target = D62664A724BBF26A00DF9B88 /* GeminiFormat */;
targetProxy = D62664BB24BBF26A00DF9B88 /* PBXContainerItemProxy */;
};
D62664D924BC081B00DF9B88 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D62664CD24BC081B00DF9B88 /* GeminiRenderer */;
targetProxy = D62664D824BC081B00DF9B88 /* PBXContainerItemProxy */;
};
D62664DB24BC081B00DF9B88 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D626645A24BBF1C200DF9B88 /* Gemini */;
targetProxy = D62664DA24BC081B00DF9B88 /* PBXContainerItemProxy */;
};
D62664E224BC081B00DF9B88 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D62664CD24BC081B00DF9B88 /* GeminiRenderer */;
targetProxy = D62664E124BC081B00DF9B88 /* PBXContainerItemProxy */;
};
D62664F324BC0D7700DF9B88 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D62664A724BBF26A00DF9B88 /* GeminiFormat */;
targetProxy = D62664F224BC0D7700DF9B88 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@ -1158,105 +927,6 @@
};
name = Release;
};
D62664E624BC081B00DF9B88 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = HGYVAQA9FW;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = GeminiRenderer/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
PRODUCT_BUNDLE_IDENTIFIER = net.shadowfacts.GeminiRenderer;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
D62664E724BC081B00DF9B88 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = HGYVAQA9FW;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = GeminiRenderer/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
PRODUCT_BUNDLE_IDENTIFIER = net.shadowfacts.GeminiRenderer;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
D62664E924BC081B00DF9B88 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = HGYVAQA9FW;
INFOPLIST_FILE = GeminiRendererTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = net.shadowfacts.GeminiRendererTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Gemini.app/Contents/MacOS/Gemini";
};
name = Debug;
};
D62664EA24BC081B00DF9B88 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = HGYVAQA9FW;
INFOPLIST_FILE = GeminiRendererTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = net.shadowfacts.GeminiRendererTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Gemini.app/Contents/MacOS/Gemini";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@ -1314,24 +984,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D62664E524BC081B00DF9B88 /* Build configuration list for PBXNativeTarget "GeminiRenderer" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D62664E624BC081B00DF9B88 /* Debug */,
D62664E724BC081B00DF9B88 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D62664E824BC081B00DF9B88 /* Build configuration list for PBXNativeTarget "GeminiRendererTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D62664E924BC081B00DF9B88 /* Debug */,
D62664EA24BC081B00DF9B88 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = D626645324BBF1C200DF9B88 /* Project object */;

View File

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D62664A724BBF26A00DF9B88"
BuildableName = "GeminiFormat.framework"
BlueprintName = "GeminiFormat"
ReferencedContainer = "container:Gemini.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D62664A724BBF26A00DF9B88"
BuildableName = "GeminiFormat.framework"
BlueprintName = "GeminiFormat"
ReferencedContainer = "container:Gemini.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -12,25 +12,12 @@
<key>GeminiFormat.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>2</integer>
</dict>
<key>GeminiProtocol.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>GeminiRenderer.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>D62664A724BBF26A00DF9B88</key>
<dict>
<key>primary</key>
<true/>
<integer>1</integer>
</dict>
</dict>
</dict>

View File

@ -7,15 +7,12 @@
import Cocoa
import SwiftUI
import GeminiProtocol
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
var connection: GeminiConnection!
let url = URL(string: "gemini://localhost:1965/overview.gmi")!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Create the SwiftUI view that provides the window contents.
@ -30,40 +27,13 @@ class AppDelegate: NSObject, NSApplicationDelegate {
window.center()
window.setFrameAutosaveName("Main Window")
window.contentView = NSHostingView(rootView: contentView)
window.title = "Gemini"
window.makeKeyAndOrderFront(nil)
connection = GeminiConnection(endpoint: .url(url), delegate: self)
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
var alreadyReceived = false
}
extension AppDelegate: GeminiConnectionDelegate {
func connectionReady(_ connection: GeminiConnection) {
print("!! Ready")
let req = try! GeminiRequest(url: url)
connection.sendRequest(req)
}
func connection(_ connection: GeminiConnection, receivedData data: Data?, header: GeminiResponseHeader) {
if !alreadyReceived {
alreadyReceived = true
print("!! Status: \(header.status)")
print("!! Meta: '\(header.meta)'")
}
if let data = data {
print(String(data: data, encoding: .utf8)!)
}
}
func connectionCompleted(_ connection: GeminiConnection) {
print("!! completed")
}
}

View File

@ -2,11 +2,9 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>
</plist>

View File

@ -8,19 +8,19 @@
import Foundation
import Network
public protocol GeminiConnectionDelegate: class {
protocol GeminiConnectionDelegate: class {
func connectionReady(_ connection: GeminiConnection)
func connection(_ connection: GeminiConnection, receivedData data: Data?, header: GeminiResponseHeader)
func connectionCompleted(_ connection: GeminiConnection)
}
public class GeminiConnection {
class GeminiConnection {
public weak var delegate: GeminiConnectionDelegate?
weak var delegate: GeminiConnectionDelegate?
private var connection: NWConnection?
public init(endpoint: NWEndpoint, delegate: GeminiConnectionDelegate? = nil) {
init(endpoint: NWEndpoint, delegate: GeminiConnectionDelegate? = nil) {
self.connection = NWConnection(to: endpoint, using: .gemini)
self.delegate = delegate
@ -49,7 +49,7 @@ public class GeminiConnection {
var report: NWConnection.PendingDataTransferReport!
public func sendRequest(_ request: GeminiRequest) {
func sendRequest(_ request: GeminiRequest) {
guard let connection = connection else { return }
let message = NWProtocolFramer.Message(geminiRequest: request)

View File

@ -7,10 +7,10 @@
import Foundation
public struct GeminiRequest {
public let url: URL
struct GeminiRequest {
let url: URL
public init(url: URL) throws {
init(url: URL) throws {
if url.absoluteString.count > 1024 {
throw Error.urlTooLong
}
@ -24,7 +24,7 @@ public struct GeminiRequest {
}
}
public extension GeminiRequest {
extension GeminiRequest {
enum Error: Swift.Error {
case urlTooLong
}

View File

@ -8,14 +8,11 @@
import Foundation
import UniformTypeIdentifiers
public struct GeminiResponse {
public let status: StatusCode
public let meta: String
public let body: Data?
struct GeminiResponse {
let status: StatusCode
let meta: String
let body: Data?
}
public extension GeminiResponse {
// Helpers
var rawMimeType: String? {
guard status.isSuccess else { return nil }
@ -56,7 +53,7 @@ public extension GeminiResponse {
}
}
public extension GeminiResponse {
extension GeminiResponse {
enum StatusCode: Int {
// All statuses and subtypes
case input = 10
@ -92,7 +89,7 @@ public extension GeminiResponse {
}
extension GeminiResponse.StatusCode: CustomStringConvertible {
public var description: String {
var description: String {
switch self {
case .input:
return "input"

View File

@ -7,7 +7,7 @@
import Foundation
public struct GeminiResponseHeader {
public let status: GeminiResponse.StatusCode
public let meta: String
struct GeminiResponseHeader {
let status: GeminiResponse.StatusCode
let meta: String
}

View File

@ -1,47 +0,0 @@
//
// DocumentView.swift
// GeminiRenderer
//
// Created by Shadowfacts on 7/12/20.
//
import SwiftUI
import GeminiFormat
public struct DocumentView: View {
private let document: Document
private let blocks: [RenderingBlock]
public init(document: Document) {
self.document = document
self.blocks = document.renderingBlocks
}
public var body: some View {
ScrollView(.vertical) {
MaybeLazyVStack(alignment: .leading) {
ForEach(blocks.indices) { (index) in
RenderingBlockView(block: blocks[index])
}
}.padding()
}
}
}
struct DocumentView_Previews: PreviewProvider {
static var doc: Document {
Document(url: URL(string: "gemini://example.com")!, lines: [
.heading("Hello World", level: .h1),
.text("Some text"),
.preformattedToggle(alt: "blah"),
.preformattedText("test"),
.preformattedToggle(alt: nil),
.quote("whatever"),
.unorderedListItem("something")
])
}
static var previews: some View {
DocumentView(document: doc)
}
}

View File

@ -1,41 +0,0 @@
//
// Fonts.swift
// GeminiRenderer
//
// Created by Shadowfacts on 7/13/20.
//
import SwiftUI
import GeminiFormat
extension Document.HeadingLevel {
var font: Font {
let style: Font.TextStyle
switch self {
case .h1:
style = .title
case .h2:
if #available(macOS 10.16, iOS 14.0, *) {
style = .title2
} else {
style = .headline
}
case .h3:
if #available(macOS 10.16, iOS 14.0, *) {
style = .title3
} else {
style = .subheadline
}
}
return .system(style, design: .serif)
}
}
extension Font {
static var documentBody: Font {
.system(.body, design: .serif)
}
static var documentBodyPreformatted: Font {
.system(.body, design: .monospaced)
}
}

View File

@ -1,18 +0,0 @@
//
// GeminiRenderer.h
// GeminiRenderer
//
// Created by Shadowfacts on 7/12/20.
//
#import <Foundation/Foundation.h>
//! Project version number for GeminiRenderer.
FOUNDATION_EXPORT double GeminiRendererVersionNumber;
//! Project version string for GeminiRenderer.
FOUNDATION_EXPORT const unsigned char GeminiRendererVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <GeminiRenderer/PublicHeader.h>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
</plist>

View File

@ -1,40 +0,0 @@
//
// MaybeLazyVStack.swift
// GeminiRenderer
//
// Created by Shadowfacts on 7/12/20.
//
import SwiftUI
struct MaybeLazyVStack<Content: View>: View {
private let alignment: HorizontalAlignment
private let spacing: CGFloat?
private let content: Content
init(alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content) {
self.alignment = alignment
self.spacing = spacing
self.content = content()
}
@ViewBuilder
var body: some View {
if #available(macOS 16.0, iOS 14.0, *) {
LazyVStack(alignment: alignment, spacing: spacing) {
content
}
} else {
VStack(alignment: alignment, spacing: spacing) {
content
}
}
}
}
struct MaybeLazyVStack_Previews: PreviewProvider {
static var previews: some View {
// MaybeLazyVStack()
EmptyView()
}
}

View File

@ -1,56 +0,0 @@
//
// RenderingBlock.swift
// GeminiRenderer
//
// Created by Shadowfacts on 7/12/20.
//
import Foundation
import GeminiFormat
enum RenderingBlock: Equatable {
case text(String)
case link(URL, text: String?)
case preformatted(String, alt: String?)
case heading(String, level: Document.HeadingLevel)
case unorderedListItem(String)
case quote(String)
}
extension Document {
var renderingBlocks: [RenderingBlock] {
var blocks = [RenderingBlock]()
var currentPreformatted: (text: String, alt: String?)?
for line in self.lines {
switch line {
case let .preformattedToggle(alt: alt):
if let (text, alt) = currentPreformatted {
// drop last trailing newline
let realText = String(text.dropLast(1))
blocks.append(.preformatted(realText, alt: alt))
currentPreformatted = nil
} else {
currentPreformatted = ("", alt: alt)
}
case let .preformattedText(text):
currentPreformatted!.text += text
currentPreformatted!.text += "\n"
case let .text(text):
blocks.append(.text(text))
case let .link(url, text: text):
blocks.append(.link(url, text: text))
case let .heading(text, level: level):
blocks.append(.heading(text, level: level))
case let .unorderedListItem(text):
blocks.append(.unorderedListItem(text))
case let .quote(text):
blocks.append(.quote(text))
}
}
return blocks
}
}

View File

@ -1,66 +0,0 @@
//
// RenderingBlockView.swift
// GeminiRenderer
//
// Created by Shadowfacts on 7/13/20.
//
import SwiftUI
import GeminiFormat
struct RenderingBlockView: View {
let block: RenderingBlock
@ViewBuilder
var body: some View {
switch block {
case let .text(text):
Text(verbatim: text)
.font(.documentBody)
.frame(maxWidth: .infinity, alignment: .leading)
case let .link(url, text: linkText):
let text = linkText ?? url.absoluteString
Text(verbatim: text)
.font(.documentBody)
.foregroundColor(.blue)
.underline()
.frame(maxWidth: .infinity, alignment: .leading)
case let .preformatted(text, alt: _):
ScrollView(.horizontal) {
Text(verbatim: text)
.font(.documentBodyPreformatted)
.frame(maxWidth: .infinity, alignment: .leading)
}
case let .heading(text, level: level):
Text(verbatim: text)
.font(level.font)
.frame(maxWidth: .infinity, alignment: .leading)
case let .unorderedListItem(text):
// todo: should this be .firstTextBaseline?
HStack(alignment: .top, spacing: 4) {
Text(verbatim: "\u{2022}")
Text(verbatim: text)
.font(.documentBody)
Spacer()
}.frame(maxWidth: .infinity, alignment: .leading)
case let .quote(text):
HStack(spacing: 4) {
Color.gray
.frame(width: 4)
Text(verbatim: text)
.font(Font.documentBody.italic())
.foregroundColor(.gray)
Spacer()
}.frame(maxWidth: .infinity, alignment: .leading)
}
}
}
struct RenderingBlockView_Previews: PreviewProvider {
static var previews: some View {
Group {
RenderingBlockView(block: .text("Some Text"))
RenderingBlockView(block: .quote("A Quote"))
}
}
}

View File

@ -1,33 +0,0 @@
//
// GeminiRendererTests.swift
// GeminiRendererTests
//
// Created by Shadowfacts on 7/12/20.
//
import XCTest
@testable import GeminiRenderer
class GeminiRendererTests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() throws {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>