diff --git a/WebsiteGenerator/Content/Element.swift b/WebsiteGenerator/Content/Element.swift index 36e0a97..e7b93e8 100644 --- a/WebsiteGenerator/Content/Element.swift +++ b/WebsiteGenerator/Content/Element.swift @@ -255,6 +255,20 @@ struct Element { extension Element { + /** + The localized html file name for a language, including a leading slash. + */ + static func htmlPagePathAddition(for language: String) -> String { + "/" + htmlPageName(for: language) + } + + /** + The localized html file name for a language, without the leading slash. + */ + static func htmlPageName(for language: String) -> String { + "\(language).html" + } + var containsElements: Bool { !elements.isEmpty } @@ -286,7 +300,30 @@ extension Element { The url of the top-level section of the element. */ func sectionUrl(for language: String) -> String { - path.components(separatedBy: "/").first! + "/\(language).html" + path.components(separatedBy: "/").first! + Element.htmlPagePathAddition(for: language) + } + + /** + Create a relative link to another page in the tree. + - Parameter pageUrl: The full page url of the target page, including localization + - Returns: The relative url from a localized page of the element to the target page. + */ + func relativePathToOtherSiteElement(pageUrl: String) -> String { + // Note: The element `path` is missing the last component + // i.e. travel/alps instead of travel/alps/en.html + let ownParts = path.components(separatedBy: "/") + let pageParts = pageUrl.components(separatedBy: "/") + + // Find the common elements of the path, which can be discarded + var index = 0 + while pageParts[index] == ownParts[index] { + index += 1 + } + // The relative path needs to go down to the first common folder, + // before going up to the target page + let allParts = [String](repeating: "..", count: ownParts.count-index) + + pageParts.dropFirst(index) + return allParts.joined(separator: "/") } /** @@ -381,7 +418,10 @@ extension Element { Returns the full path (relative to the site root for a page of the element in the given language. */ func localizedPath(for language: String) -> String { - path != "" ? "\(path)/\(language).html" : "\(language).html" + guard path != "" else { + return Element.htmlPageName(for: language) + } + return path + Element.htmlPagePathAddition(for: language) } /** diff --git a/WebsiteGenerator/Files/FileSystem.swift b/WebsiteGenerator/Files/FileSystem.swift index 5706925..b6f83f1 100644 --- a/WebsiteGenerator/Files/FileSystem.swift +++ b/WebsiteGenerator/Files/FileSystem.swift @@ -440,6 +440,10 @@ final class FileSystem { pagePaths[id] = page } + func getPage(for id: String) -> String? { + pagePaths[id] + } + // MARK: Writing files diff --git a/WebsiteGenerator/Generators/HTMLElementsGenerator.swift b/WebsiteGenerator/Generators/HTMLElementsGenerator.swift index 91b1b08..132c918 100644 --- a/WebsiteGenerator/Generators/HTMLElementsGenerator.swift +++ b/WebsiteGenerator/Generators/HTMLElementsGenerator.swift @@ -12,11 +12,11 @@ struct HTMLElementsGenerator { // - TODO: Make link relative func topBarWebsiteTitle(language: String) -> String { - "/\(language).html" + Element.htmlPagePathAddition(for: language) } func topBarLanguageButton(_ language: String) -> String { - "\(language)" + "\(language)" } func topBarNavigationLink(url: String, text: String, isActive: Bool) -> String { @@ -46,7 +46,7 @@ struct HTMLElementsGenerator { func svgImage(file: String, x: Int, y: Int, width: Int, height: Int) -> String { """ - + """ } diff --git a/WebsiteGenerator/Generators/MarkdownProcessor.swift b/WebsiteGenerator/Generators/MarkdownProcessor.swift index ac7fd89..13e7ef1 100644 --- a/WebsiteGenerator/Generators/MarkdownProcessor.swift +++ b/WebsiteGenerator/Generators/MarkdownProcessor.swift @@ -27,27 +27,49 @@ struct PageContentGenerator { return html } let linkModifier = Modifier(target: .links) { html, markdown in - let file = markdown.between("(", and: ")") - if let filePath = page.nonAbsolutePathRelativeToRootForContainedInputFile(file) { - // The target of the page link must be present after generation is complete - files.expect(file: filePath, source: page.path) - } - return html + handleLink(page: page, language: language, html: html, markdown: markdown) } let htmlModifier = Modifier(target: .html) { html, markdown in - //print("[HTML] Found in page \(page.path):") - //print(markdown) - // Thinks to check - // String { + let file = markdown.between("(", and: ")") + if file.hasPrefix("page:") { + let pageId = file.replacingOccurrences(of: "page:", with: "") + guard let pagePath = files.getPage(for: pageId) else { + log.add(warning: "Page id '\(pageId)' not found", source: page.path) + // Remove link since the page can't be found + return markdown.between("[", and: "]") + } + let fullPath = pagePath + Element.htmlPagePathAddition(for: language) + // Adjust file path to get the page url + let url = page.relativePathToOtherSiteElement(pageUrl: fullPath) + return html.replacingOccurrences(of: file, with: url) + } + + if let filePath = page.nonAbsolutePathRelativeToRootForContainedInputFile(file) { + // The target of the page link must be present after generation is complete + files.expect(file: filePath, source: page.path) + } + return html + } + + private func handleHTML(page: Element, language: String, html: String, markdown: Substring) -> String { + #warning("Check HTML code in markdown for required resources") + //print("[HTML] Found in page \(page.path):") + //print(markdown) + // Things to check: + // String { // Split the markdown ![alt](file title) // For images: ![left_title](file right_title) @@ -127,7 +149,7 @@ struct PageContentGenerator { guard let area = area else { return factory.html.svgImage(file: file) } - let parts = area.components(separatedBy: ",") + let parts = area.components(separatedBy: ",").map { $0.trimmed } guard parts.count == 4, let x = Int(parts[0]), let y = Int(parts[1]), diff --git a/WebsiteGenerator/Templates/Filled/LocalizedSiteTemplate.swift b/WebsiteGenerator/Templates/Filled/LocalizedSiteTemplate.swift index 3e15224..254e3d6 100644 --- a/WebsiteGenerator/Templates/Filled/LocalizedSiteTemplate.swift +++ b/WebsiteGenerator/Templates/Filled/LocalizedSiteTemplate.swift @@ -58,7 +58,7 @@ struct LocalizedSiteTemplate { let sections = site.sortedItems.map { PrefilledTopBarTemplate.SectionInfo( name: $0.title(for: language), - url: "\($0.path)/\(language).html") + url: $0.path + Element.htmlPagePathAddition(for: language)) } self.topBar = try .init( @@ -83,7 +83,7 @@ struct LocalizedSiteTemplate { func makeBackLink(text: String, language: String) -> String { let content: [BackNavigationTemplate.Key : String] = [ .text: text, - .url: "../\(language).html" + .url: ".." + Element.htmlPagePathAddition(for: language) ] return backNavigation.generate(content) }