Javier Cicchelli 9bcdaa697b [Setup] Basic project structure (#1)
This PR contains all the work related to setting up this project as required to implement the [Assignment](https://repo.rock-n-code.com/rock-n-code/deep-linking-assignment/wiki/Assignment) on top, as intended.

To summarise this work:
- [x] created a new **Xcode** project;
- [x] cloned the `Wikipedia` app and inserted it into the **Xcode** project;
- [x] created the `Locations` app and also, its `Libraries` package;
- [x] created the `Shared` package to share dependencies between the apps;
- [x] added a `Makefile` file and implemented some **environment** and **help** commands.

Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Reviewed-on: rock-n-code/deep-linking-assignment#1
2023-04-08 18:37:13 +00:00

137 lines
5.1 KiB
Swift

/// Detect Wiki namespace in strings. For example, detect that "/wiki/Talk:Dog" is a talk page and "/wiki/Special:ApiSandbox" is a special page
extension String {
static let namespaceRegex = try! NSRegularExpression(pattern: "^(.+?)_*:_*(.*)$")
// Assumes the input is the remainder of a /wiki/ path
func namespaceOfWikiResourcePath(with languageCode: String) -> PageNamespace {
guard let namespaceString = String.namespaceRegex.firstReplacementString(in: self) else {
return .main
}
return WikipediaURLTranslations.commonNamespace(for: namespaceString, in: languageCode) ?? .main
}
public func namespaceAndTitleOfWikiResourcePath(with languageCode: String) -> (namespace: PageNamespace, title: String) {
guard let result = String.namespaceRegex.firstMatch(in: self) else {
return (.main, self)
}
let namespaceString = String.namespaceRegex.replacementString(for: result, in: self, offset: 0, template: "$1")
guard let namespace = WikipediaURLTranslations.commonNamespace(for: namespaceString, in: languageCode) else {
return (.main, self)
}
let title = String.namespaceRegex.replacementString(for: result, in: self, offset: 0, template: "$2")
return (namespace, title)
}
static let wikiResourceRegex = try! NSRegularExpression(pattern: "^/wiki/(.+)$", options: .caseInsensitive)
var wikiResourcePath: String? {
return String.wikiResourceRegex.firstReplacementString(in: self)
}
static let wResourceRegex = try! NSRegularExpression(pattern: "^/w/(.+)$", options: .caseInsensitive)
public var wResourcePath: String? {
return String.wResourceRegex.firstReplacementString(in: self)
}
public var fullRange: NSRange {
return NSRange(startIndex..<endIndex, in: self)
}
public func extractingArticleTitleFromTalkPage(languageCode: String) -> String? {
if let namespaceString = String.namespaceRegex.firstReplacementString(in: self) {
let namespaceStringWithColon = "\(namespaceString):"
if namespaceOfWikiResourcePath(with: languageCode) == .talk {
return replacingOccurrences(of: namespaceStringWithColon, with: "")
}
}
return nil
}
}
/// Page title transformation
public extension String {
var percentEncodedPageTitleForPathComponents: String? {
return denormalizedPageTitle?.addingPercentEncoding(withAllowedCharacters: .encodeURIComponentAllowed)
}
var normalizedPageTitle: String? {
return replacingOccurrences(of: "_", with: " ").precomposedStringWithCanonicalMapping
}
var denormalizedPageTitle: String? {
return replacingOccurrences(of: " ", with: "_").precomposedStringWithCanonicalMapping
}
var asTalkPageFragment: String? {
let denormalizedName = replacingOccurrences(of: " ", with: "_")
let unlinkedName = denormalizedName.replacingOccurrences(of: "[[", with: "").replacingOccurrences(of: "]]", with: "")
return unlinkedName.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.wmf_encodeURIComponentAllowed())
}
// assumes string is already normalized
var googleFormPercentEncodedPageTitle: String? {
return googleFormPageTitle?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
}
var googleFormPageTitle: String? {
return replacingOccurrences(of: " ", with: "+").precomposedStringWithCanonicalMapping
}
var unescapedNormalizedPageTitle: String? {
return removingPercentEncoding?.normalizedPageTitle
}
var isReferenceFragment: Bool {
return contains("ref_")
}
var isCitationFragment: Bool {
return contains("cite_note")
}
var isEndNoteFragment: Bool {
return contains("endnote_")
}
}
@objc extension NSString {
/// Deprecated - use namespace methods
@objc var wmf_isWikiResource: Bool {
return (self as String).wikiResourcePath != nil
}
/// Deprecated - use swift methods
@objc var wmf_pathWithoutWikiPrefix: String? {
return (self as String).wikiResourcePath
}
/// Deprecated - use swift methods
@objc var wmf_denormalizedPageTitle: String? {
return (self as String).denormalizedPageTitle
}
/// Deprecated - use swift methods
@objc var wmf_normalizedPageTitle: String? {
return (self as String).normalizedPageTitle
}
/// Deprecated - use swift methods
@objc var wmf_unescapedNormalizedPageTitle: String? {
return (self as String).unescapedNormalizedPageTitle
}
/// Deprecated - use swift methods
@objc var wmf_isReferenceFragment: Bool {
return (self as String).isReferenceFragment
}
/// Deprecated - use swift methods
@objc var wmf_isCitationFragment: Bool {
return (self as String).isCitationFragment
}
/// Deprecated - use swift methods
@objc var wmf_isEndNoteFragment: Bool {
return (self as String).isEndNoteFragment
}
}