Add GeminiFormat framework
This commit is contained in:
parent
ef03073d58
commit
a84a223c68
@ -12,8 +12,59 @@
|
|||||||
D626646324BBF1C300DF9B88 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D626646224BBF1C300DF9B88 /* Assets.xcassets */; };
|
D626646324BBF1C300DF9B88 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D626646224BBF1C300DF9B88 /* Assets.xcassets */; };
|
||||||
D626646624BBF1C300DF9B88 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D626646524BBF1C300DF9B88 /* Preview Assets.xcassets */; };
|
D626646624BBF1C300DF9B88 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D626646524BBF1C300DF9B88 /* Preview Assets.xcassets */; };
|
||||||
D626646924BBF1C300DF9B88 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D626646724BBF1C300DF9B88 /* Main.storyboard */; };
|
D626646924BBF1C300DF9B88 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D626646724BBF1C300DF9B88 /* Main.storyboard */; };
|
||||||
|
D62664B124BBF26A00DF9B88 /* GeminiFormat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */; };
|
||||||
|
D62664B824BBF26A00DF9B88 /* GeminiFormatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62664B724BBF26A00DF9B88 /* GeminiFormatTests.swift */; };
|
||||||
|
D62664BA24BBF26A00DF9B88 /* GeminiFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = D62664AA24BBF26A00DF9B88 /* GeminiFormat.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
D62664BD24BBF26A00DF9B88 /* GeminiFormat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */; };
|
||||||
|
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 */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
D626648324BBF22E00DF9B88 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = D626645A24BBF1C200DF9B88;
|
||||||
|
remoteInfo = Gemini;
|
||||||
|
};
|
||||||
|
D62664B224BBF26A00DF9B88 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = D62664A724BBF26A00DF9B88;
|
||||||
|
remoteInfo = GeminiFormat;
|
||||||
|
};
|
||||||
|
D62664B424BBF26A00DF9B88 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = D626645A24BBF1C200DF9B88;
|
||||||
|
remoteInfo = Gemini;
|
||||||
|
};
|
||||||
|
D62664BB24BBF26A00DF9B88 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = D62664A724BBF26A00DF9B88;
|
||||||
|
remoteInfo = GeminiFormat;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
D626649124BBF22E00DF9B88 /* Embed Frameworks */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 10;
|
||||||
|
files = (
|
||||||
|
D62664BE24BBF26A00DF9B88 /* GeminiFormat.framework in Embed Frameworks */,
|
||||||
|
);
|
||||||
|
name = "Embed Frameworks";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
D626645B24BBF1C200DF9B88 /* Gemini.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Gemini.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
D626645B24BBF1C200DF9B88 /* Gemini.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Gemini.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D626645E24BBF1C200DF9B88 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
D626645E24BBF1C200DF9B88 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
@ -23,6 +74,14 @@
|
|||||||
D626646824BBF1C300DF9B88 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
D626646824BBF1C300DF9B88 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
D626646A24BBF1C300DF9B88 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
D626646A24BBF1C300DF9B88 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
D626646B24BBF1C300DF9B88 /* Gemini.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Gemini.entitlements; sourceTree = "<group>"; };
|
D626646B24BBF1C300DF9B88 /* Gemini.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Gemini.entitlements; sourceTree = "<group>"; };
|
||||||
|
D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GeminiFormat.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
D62664AA24BBF26A00DF9B88 /* GeminiFormat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeminiFormat.h; sourceTree = "<group>"; };
|
||||||
|
D62664AB24BBF26A00DF9B88 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
D62664B024BBF26A00DF9B88 /* GeminiFormatTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GeminiFormatTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
D62664B724BBF26A00DF9B88 /* GeminiFormatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiFormatTests.swift; sourceTree = "<group>"; };
|
||||||
|
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>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -30,6 +89,19 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
D62664BD24BBF26A00DF9B88 /* GeminiFormat.framework in Frameworks */,
|
||||||
|
D62664A524BBF26A00DF9B88 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
D62664AD24BBF26A00DF9B88 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D62664B124BBF26A00DF9B88 /* GeminiFormat.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -40,6 +112,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D626645D24BBF1C200DF9B88 /* Gemini */,
|
D626645D24BBF1C200DF9B88 /* Gemini */,
|
||||||
|
D62664A924BBF26A00DF9B88 /* GeminiFormat */,
|
||||||
|
D62664B624BBF26A00DF9B88 /* GeminiFormatTests */,
|
||||||
D626645C24BBF1C200DF9B88 /* Products */,
|
D626645C24BBF1C200DF9B88 /* Products */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -48,6 +122,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D626645B24BBF1C200DF9B88 /* Gemini.app */,
|
D626645B24BBF1C200DF9B88 /* Gemini.app */,
|
||||||
|
D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */,
|
||||||
|
D62664B024BBF26A00DF9B88 /* GeminiFormatTests.xctest */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -74,8 +150,39 @@
|
|||||||
path = "Preview Content";
|
path = "Preview Content";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D62664A924BBF26A00DF9B88 /* GeminiFormat */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D62664AA24BBF26A00DF9B88 /* GeminiFormat.h */,
|
||||||
|
D62664AB24BBF26A00DF9B88 /* Info.plist */,
|
||||||
|
D62664C724BBF2C600DF9B88 /* Document.swift */,
|
||||||
|
D62664C524BBF27300DF9B88 /* GeminiParser.swift */,
|
||||||
|
);
|
||||||
|
path = GeminiFormat;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D62664B624BBF26A00DF9B88 /* GeminiFormatTests */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D62664B724BBF26A00DF9B88 /* GeminiFormatTests.swift */,
|
||||||
|
D62664B924BBF26A00DF9B88 /* Info.plist */,
|
||||||
|
);
|
||||||
|
path = GeminiFormatTests;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXHeadersBuildPhase section */
|
||||||
|
D62664A324BBF26A00DF9B88 /* Headers */ = {
|
||||||
|
isa = PBXHeadersBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D62664BA24BBF26A00DF9B88 /* GeminiFormat.h in Headers */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXHeadersBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
D626645A24BBF1C200DF9B88 /* Gemini */ = {
|
D626645A24BBF1C200DF9B88 /* Gemini */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
@ -88,12 +195,50 @@
|
|||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
|
D62664BC24BBF26A00DF9B88 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = Gemini;
|
name = Gemini;
|
||||||
productName = Gemini;
|
productName = Gemini;
|
||||||
productReference = D626645B24BBF1C200DF9B88 /* Gemini.app */;
|
productReference = D626645B24BBF1C200DF9B88 /* Gemini.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
|
D62664A724BBF26A00DF9B88 /* GeminiFormat */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = D62664BF24BBF26A00DF9B88 /* Build configuration list for PBXNativeTarget "GeminiFormat" */;
|
||||||
|
buildPhases = (
|
||||||
|
D62664A324BBF26A00DF9B88 /* Headers */,
|
||||||
|
D62664A424BBF26A00DF9B88 /* Sources */,
|
||||||
|
D62664A524BBF26A00DF9B88 /* Frameworks */,
|
||||||
|
D62664A624BBF26A00DF9B88 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = GeminiFormat;
|
||||||
|
productName = GeminiFormat;
|
||||||
|
productReference = D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */;
|
||||||
|
productType = "com.apple.product-type.framework";
|
||||||
|
};
|
||||||
|
D62664AF24BBF26A00DF9B88 /* GeminiFormatTests */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = D62664C224BBF26A00DF9B88 /* Build configuration list for PBXNativeTarget "GeminiFormatTests" */;
|
||||||
|
buildPhases = (
|
||||||
|
D62664AC24BBF26A00DF9B88 /* Sources */,
|
||||||
|
D62664AD24BBF26A00DF9B88 /* Frameworks */,
|
||||||
|
D62664AE24BBF26A00DF9B88 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
D62664B324BBF26A00DF9B88 /* PBXTargetDependency */,
|
||||||
|
D62664B524BBF26A00DF9B88 /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
name = GeminiFormatTests;
|
||||||
|
productName = GeminiFormatTests;
|
||||||
|
productReference = D62664B024BBF26A00DF9B88 /* GeminiFormatTests.xctest */;
|
||||||
|
productType = "com.apple.product-type.bundle.unit-test";
|
||||||
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
/* Begin PBXProject section */
|
||||||
@ -106,6 +251,14 @@
|
|||||||
D626645A24BBF1C200DF9B88 = {
|
D626645A24BBF1C200DF9B88 = {
|
||||||
CreatedOnToolsVersion = 12.0;
|
CreatedOnToolsVersion = 12.0;
|
||||||
};
|
};
|
||||||
|
D62664A724BBF26A00DF9B88 = {
|
||||||
|
CreatedOnToolsVersion = 12.0;
|
||||||
|
LastSwiftMigration = 1200;
|
||||||
|
};
|
||||||
|
D62664AF24BBF26A00DF9B88 = {
|
||||||
|
CreatedOnToolsVersion = 12.0;
|
||||||
|
TestTargetID = D626645A24BBF1C200DF9B88;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = D626645624BBF1C200DF9B88 /* Build configuration list for PBXProject "Gemini" */;
|
buildConfigurationList = D626645624BBF1C200DF9B88 /* Build configuration list for PBXProject "Gemini" */;
|
||||||
@ -122,6 +275,8 @@
|
|||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
D626645A24BBF1C200DF9B88 /* Gemini */,
|
D626645A24BBF1C200DF9B88 /* Gemini */,
|
||||||
|
D62664A724BBF26A00DF9B88 /* GeminiFormat */,
|
||||||
|
D62664AF24BBF26A00DF9B88 /* GeminiFormatTests */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
@ -137,6 +292,20 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
D62664A624BBF26A00DF9B88 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
D62664AE24BBF26A00DF9B88 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
@ -149,8 +318,43 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
D62664A424BBF26A00DF9B88 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D62664C824BBF2C600DF9B88 /* Document.swift in Sources */,
|
||||||
|
D62664C624BBF27300DF9B88 /* GeminiParser.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
D62664AC24BBF26A00DF9B88 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D62664B824BBF26A00DF9B88 /* GeminiFormatTests.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
D62664B324BBF26A00DF9B88 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = D62664A724BBF26A00DF9B88 /* GeminiFormat */;
|
||||||
|
targetProxy = D62664B224BBF26A00DF9B88 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
D62664B524BBF26A00DF9B88 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = D626645A24BBF1C200DF9B88 /* Gemini */;
|
||||||
|
targetProxy = D62664B424BBF26A00DF9B88 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
D62664BC24BBF26A00DF9B88 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = D62664A724BBF26A00DF9B88 /* GeminiFormat */;
|
||||||
|
targetProxy = D62664BB24BBF26A00DF9B88 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
D626646724BBF1C300DF9B88 /* Main.storyboard */ = {
|
D626646724BBF1C300DF9B88 /* Main.storyboard */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
@ -281,6 +485,7 @@
|
|||||||
D626646F24BBF1C300DF9B88 /* Debug */ = {
|
D626646F24BBF1C300DF9B88 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = Gemini/Gemini.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Gemini/Gemini.entitlements;
|
||||||
@ -305,6 +510,7 @@
|
|||||||
D626647024BBF1C300DF9B88 /* Release */ = {
|
D626647024BBF1C300DF9B88 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = Gemini/Gemini.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Gemini/Gemini.entitlements;
|
||||||
@ -326,6 +532,105 @@
|
|||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
D62664C024BBF26A00DF9B88 /* 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 = GeminiFormat/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.GeminiFormat;
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
D62664C124BBF26A00DF9B88 /* 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 = GeminiFormat/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.GeminiFormat;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
VERSION_INFO_PREFIX = "";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
D62664C324BBF26A00DF9B88 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEVELOPMENT_TEAM = HGYVAQA9FW;
|
||||||
|
INFOPLIST_FILE = GeminiFormatTests/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
"@loader_path/../Frameworks",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = net.shadowfacts.GeminiFormatTests;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Gemini.app/Contents/MacOS/Gemini";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
D62664C424BBF26A00DF9B88 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEVELOPMENT_TEAM = HGYVAQA9FW;
|
||||||
|
INFOPLIST_FILE = GeminiFormatTests/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
"@loader_path/../Frameworks",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = net.shadowfacts.GeminiFormatTests;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Gemini.app/Contents/MacOS/Gemini";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
@ -347,6 +652,24 @@
|
|||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
D62664BF24BBF26A00DF9B88 /* Build configuration list for PBXNativeTarget "GeminiFormat" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
D62664C024BBF26A00DF9B88 /* Debug */,
|
||||||
|
D62664C124BBF26A00DF9B88 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
D62664C224BBF26A00DF9B88 /* Build configuration list for PBXNativeTarget "GeminiFormatTests" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
D62664C324BBF26A00DF9B88 /* Debug */,
|
||||||
|
D62664C424BBF26A00DF9B88 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
};
|
};
|
||||||
rootObject = D626645324BBF1C200DF9B88 /* Project object */;
|
rootObject = D626645324BBF1C200DF9B88 /* Project object */;
|
||||||
|
@ -9,6 +9,11 @@
|
|||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>GeminiFormat.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>2</integer>
|
||||||
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
35
GeminiFormat/Document.swift
Normal file
35
GeminiFormat/Document.swift
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// Document.swift
|
||||||
|
// GeminiFormat
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 7/12/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct Document {
|
||||||
|
let url: URL
|
||||||
|
var lines: [Line]
|
||||||
|
|
||||||
|
init(url: URL, lines: [Line] = []) {
|
||||||
|
self.url = url
|
||||||
|
self.lines = lines
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Document {
|
||||||
|
enum Line: Equatable {
|
||||||
|
case text(String)
|
||||||
|
case link(URL, text: String?)
|
||||||
|
case preformattedText(String, alt: String?)
|
||||||
|
case heading(String, level: HeadingLevel)
|
||||||
|
case unorderedListItem(String)
|
||||||
|
case quote(String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Document {
|
||||||
|
enum HeadingLevel: Int {
|
||||||
|
case h1 = 1, h2 = 2, h3 = 3
|
||||||
|
}
|
||||||
|
}
|
18
GeminiFormat/GeminiFormat.h
Normal file
18
GeminiFormat/GeminiFormat.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// GeminiFormat.h
|
||||||
|
// GeminiFormat
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 7/12/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
//! Project version number for GeminiFormat.
|
||||||
|
FOUNDATION_EXPORT double GeminiFormatVersionNumber;
|
||||||
|
|
||||||
|
//! Project version string for GeminiFormat.
|
||||||
|
FOUNDATION_EXPORT const unsigned char GeminiFormatVersionString[];
|
||||||
|
|
||||||
|
// In this header, you should import all the public headers of your framework using statements like #import <GeminiFormat/PublicHeader.h>
|
||||||
|
|
||||||
|
|
110
GeminiFormat/GeminiParser.swift
Normal file
110
GeminiFormat/GeminiParser.swift
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
//
|
||||||
|
// GeminiParser.swift
|
||||||
|
// GeminiFormat
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 7/12/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct GeminiParser {
|
||||||
|
|
||||||
|
private init() {}
|
||||||
|
|
||||||
|
static func parse(text: String, baseURL: URL) -> Document {
|
||||||
|
var doc = Document(url: baseURL)
|
||||||
|
|
||||||
|
var preformattingState = PreformattingState.off
|
||||||
|
text.enumerateLines { (line, stop) in
|
||||||
|
if line.starts(with: "```") {
|
||||||
|
switch preformattingState {
|
||||||
|
case .off:
|
||||||
|
let alt: String?
|
||||||
|
if line.count > 3 {
|
||||||
|
alt = String(line[line.index(line.startIndex, offsetBy: 3)...])
|
||||||
|
} else {
|
||||||
|
alt = nil
|
||||||
|
}
|
||||||
|
preformattingState = .on(alt)
|
||||||
|
case .on(_):
|
||||||
|
preformattingState = .off
|
||||||
|
}
|
||||||
|
if case .off = preformattingState {
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if case let .on(alt) = preformattingState {
|
||||||
|
doc.lines.append(.preformattedText(line, alt: alt))
|
||||||
|
} else if line.starts(with: "=>") {
|
||||||
|
// Link line
|
||||||
|
let urlStart = line.firstNonWhitespaceIndex(after: line.index(line.startIndex, offsetBy: 2))
|
||||||
|
let urlEnd = line.firstWhitespaceIndex(after: urlStart)
|
||||||
|
let textStart = line.firstNonWhitespaceIndex(after: urlEnd)
|
||||||
|
|
||||||
|
let urlString = String(line[urlStart..<urlEnd])
|
||||||
|
// todo: if the URL initializer fails, should there be a .link line with a nil URL?
|
||||||
|
let url = URL(string: urlString, relativeTo: baseURL)!.absoluteURL
|
||||||
|
|
||||||
|
let text: String?
|
||||||
|
if textStart < line.endIndex {
|
||||||
|
text = String(line[textStart..<line.endIndex])
|
||||||
|
} else {
|
||||||
|
text = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.lines.append(.link(url, text: text))
|
||||||
|
} else if line.starts(with: "#") {
|
||||||
|
let level: Document.HeadingLevel
|
||||||
|
if line.starts(with: "###") {
|
||||||
|
level = .h3
|
||||||
|
} else if line.starts(with: "##") {
|
||||||
|
level = .h2
|
||||||
|
} else {
|
||||||
|
level = .h1
|
||||||
|
}
|
||||||
|
let headingStart = line.firstNonWhitespaceIndex(after: line.index(line.startIndex, offsetBy: level.rawValue))
|
||||||
|
let headingText = String(line[headingStart...])
|
||||||
|
doc.lines.append(.heading(headingText, level: level))
|
||||||
|
} else if line.starts(with: "* ") {
|
||||||
|
let listItemStart = line.firstNonWhitespaceIndex(after: line.index(line.startIndex, offsetBy: 2))
|
||||||
|
let listItemText = String(line[listItemStart...])
|
||||||
|
doc.lines.append(.unorderedListItem(listItemText))
|
||||||
|
} else if line.starts(with: ">") {
|
||||||
|
let quoteStartIndex = line.firstNonWhitespaceIndex(after: line.index(after: line.startIndex))
|
||||||
|
let quoteText = String(line[quoteStartIndex...])
|
||||||
|
doc.lines.append(.quote(quoteText))
|
||||||
|
} else {
|
||||||
|
doc.lines.append(.text(line))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate extension GeminiParser {
|
||||||
|
enum PreformattingState {
|
||||||
|
case off
|
||||||
|
case on(_ alt: String?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate extension String {
|
||||||
|
func firstNonWhitespaceIndex(after index: String.Index) -> String.Index {
|
||||||
|
var index = index
|
||||||
|
// using .unicodeScalars.first should be fine, since all whitespace characters are single scalars
|
||||||
|
while index < self.endIndex, CharacterSet.whitespaces.contains(self[index].unicodeScalars.first!) {
|
||||||
|
index = self.index(after: index)
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
func firstWhitespaceIndex(after index: String.Index) -> String.Index {
|
||||||
|
var index = index
|
||||||
|
// todo: could the first unicode scalar of a character be whitespace even though the whole character is not?
|
||||||
|
while index < self.endIndex, !CharacterSet.whitespaces.contains(self[index].unicodeScalars.first!) {
|
||||||
|
index = self.index(after: index)
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
}
|
22
GeminiFormat/Info.plist
Normal file
22
GeminiFormat/Info.plist
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?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>
|
114
GeminiFormatTests/GeminiFormatTests.swift
Normal file
114
GeminiFormatTests/GeminiFormatTests.swift
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
//
|
||||||
|
// GeminiFormatTests.swift
|
||||||
|
// GeminiFormatTests
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 7/12/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import GeminiFormat
|
||||||
|
|
||||||
|
class GeminiFormatTests: XCTestCase {
|
||||||
|
|
||||||
|
func assertParseLines(text: String, lines expected: [Document.Line], message: String, file: StaticString = #filePath, line: UInt = #line) {
|
||||||
|
let doc = GeminiParser.parse(text: text, baseURL: URL(string: "gemini://example.com")!)
|
||||||
|
XCTAssertEqual(doc.lines, expected, message, file: file, line: line)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testParsePlainLines() {
|
||||||
|
assertParseLines(text: "test", lines: [.text("test")], message: "parse a plain text line")
|
||||||
|
assertParseLines(text: "one\ntwo", lines: [
|
||||||
|
.text("one"),
|
||||||
|
.text("two")
|
||||||
|
], message: "parse multiple, newline delmited plain lines")
|
||||||
|
assertParseLines(text: "one\r\ntwo", lines: [
|
||||||
|
.text("one"),
|
||||||
|
.text("two")
|
||||||
|
], message: "parse multiple, CRLF delmited plain lines")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testParseLinkLines() {
|
||||||
|
assertParseLines(text: "=> gemini://blah.com", lines: [
|
||||||
|
.link(URL(string: "gemini://blah.com")!, text: nil)
|
||||||
|
], message: "parse a bare link line")
|
||||||
|
assertParseLines(text: "=> gemini://blah.com:1234/foo/bar?baz", lines: [
|
||||||
|
.link(URL(string: "gemini://blah.com:1234/foo/bar?baz")!, text: nil)
|
||||||
|
], message: "parse a more complex bare link line")
|
||||||
|
assertParseLines(text: "=> gemini://blah.com \t Link to example", lines: [
|
||||||
|
.link(URL(string: "gemini://blah.com")!, text: "Link to example")
|
||||||
|
], message: "parse a simple link line with associated text")
|
||||||
|
assertParseLines(text: "=> gemini://blah.com/foo Link to foo", lines: [
|
||||||
|
.link(URL(string: "gemini://blah.com/foo")!, text: "Link to foo")
|
||||||
|
], message: "parse a more complex link line with associated text")
|
||||||
|
assertParseLines(text: "=> https://example.com", lines: [
|
||||||
|
.link(URL(string: "https://example.com")!, text: nil)
|
||||||
|
], message: "parse a link with a different protocol")
|
||||||
|
assertParseLines(text: "=> /foo/bar/baz", lines: [
|
||||||
|
.link(URL(string: "gemini://example.com/foo/bar/baz")!, text: nil)
|
||||||
|
], message: "resolve a relative path link")
|
||||||
|
assertParseLines(text: "=>gemini://blah.com", lines: [
|
||||||
|
.link(URL(string: "gemini://blah.com")!, text: nil)
|
||||||
|
], message: "parse link without whitespace after =>")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testParseHeadingLines() {
|
||||||
|
assertParseLines(text: "# test", lines: [
|
||||||
|
.heading("test", level: .h1)
|
||||||
|
], message: "level 1 heading")
|
||||||
|
assertParseLines(text: "#test", lines: [
|
||||||
|
.heading("test", level: .h1)
|
||||||
|
], message: "level 1 heading without whitespace")
|
||||||
|
assertParseLines(text: "#test\n## two\r\n###three", lines: [
|
||||||
|
.heading("test", level: .h1),
|
||||||
|
.heading("two", level: .h2),
|
||||||
|
.heading("three", level: .h3)
|
||||||
|
], message: "multiples headings with and without whitespace")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testParseListItemLines() {
|
||||||
|
assertParseLines(text: "* test list item", lines: [
|
||||||
|
.unorderedListItem("test list item")
|
||||||
|
], message: "parse simple list item")
|
||||||
|
assertParseLines(text: "*test", lines: [
|
||||||
|
.text("*test")
|
||||||
|
], message: "don't parse list item without space after asterisk")
|
||||||
|
assertParseLines(text: "* one\n* two\n*three", lines: [
|
||||||
|
.unorderedListItem("one"),
|
||||||
|
.unorderedListItem("two"),
|
||||||
|
.text("*three")
|
||||||
|
], message: "parse multiple list items")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testParseQuoteLines() {
|
||||||
|
assertParseLines(text: "> quote", lines: [
|
||||||
|
.quote("quote")
|
||||||
|
], message: "parse quote line")
|
||||||
|
assertParseLines(text: ">quote", lines: [
|
||||||
|
.quote("quote")
|
||||||
|
], message: "parse quote line without space after >")
|
||||||
|
assertParseLines(text: ">one\n> two\n>three", lines: [
|
||||||
|
.quote("one"),
|
||||||
|
.quote("two"),
|
||||||
|
.quote("three")
|
||||||
|
], message: "parse multiple quote lines")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testParsePreformattedLines() {
|
||||||
|
assertParseLines(text: "```\nsomething\n```", lines: [
|
||||||
|
.preformattedText("something", alt: nil)
|
||||||
|
], message: "parse simple preformatted line")
|
||||||
|
assertParseLines(text: "```alt\nsomething\n```", lines: [
|
||||||
|
.preformattedText("something", alt: "alt")
|
||||||
|
], message: "parse simple preformatted line with alt")
|
||||||
|
assertParseLines(text: "```alt\nsomething\n```other", lines: [
|
||||||
|
.preformattedText("something", alt: "alt")
|
||||||
|
], message: "ignore extra text after closing ```")
|
||||||
|
assertParseLines(text: "```\n# not a heading\n* not a list item\n>not a quote\n=> /link not a link\n```", lines: [
|
||||||
|
.preformattedText("# not a heading", alt: nil),
|
||||||
|
.preformattedText("* not a list item", alt: nil),
|
||||||
|
.preformattedText(">not a quote", alt: nil),
|
||||||
|
.preformattedText("=> /link not a link", alt: nil),
|
||||||
|
], message: "don't parse special lines inside preformatted")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
GeminiFormatTests/Info.plist
Normal file
22
GeminiFormatTests/Info.plist
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?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>
|
Loading…
x
Reference in New Issue
Block a user