Process post content as markdown
This commit is contained in:
parent
a29e6229c1
commit
d41c54d174
@ -44,6 +44,8 @@
|
|||||||
E229904E2D13535C009F8D77 /* SecurityBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = E229904D2D135349009F8D77 /* SecurityBookmark.swift */; };
|
E229904E2D13535C009F8D77 /* SecurityBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = E229904D2D135349009F8D77 /* SecurityBookmark.swift */; };
|
||||||
E24252012C50E0A40029FF16 /* HighlightedTextEditor in Frameworks */ = {isa = PBXBuildFile; productRef = E24252002C50E0A40029FF16 /* HighlightedTextEditor */; };
|
E24252012C50E0A40029FF16 /* HighlightedTextEditor in Frameworks */ = {isa = PBXBuildFile; productRef = E24252002C50E0A40029FF16 /* HighlightedTextEditor */; };
|
||||||
E242520A2C52C9260029FF16 /* ContentLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24252092C52C9260029FF16 /* ContentLanguage.swift */; };
|
E242520A2C52C9260029FF16 /* ContentLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24252092C52C9260029FF16 /* ContentLanguage.swift */; };
|
||||||
|
E2521DFC2D5020BE00C56662 /* PostContentGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2521DFB2D501DAE00C56662 /* PostContentGenerator.swift */; };
|
||||||
|
E2521E002D50BB6E00C56662 /* ItemLinkResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2521DFF2D50BB6E00C56662 /* ItemLinkResults.swift */; };
|
||||||
E2581DED2C75202400F1F079 /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2581DEC2C75202400F1F079 /* Tag.swift */; };
|
E2581DED2C75202400F1F079 /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2581DEC2C75202400F1F079 /* Tag.swift */; };
|
||||||
E25DA5092CFD964E00AEF16D /* TagContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25DA5082CFD964E00AEF16D /* TagContentView.swift */; };
|
E25DA5092CFD964E00AEF16D /* TagContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25DA5082CFD964E00AEF16D /* TagContentView.swift */; };
|
||||||
E25DA50B2CFD988100AEF16D /* PageTagAssignmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25DA50A2CFD988100AEF16D /* PageTagAssignmentView.swift */; };
|
E25DA50B2CFD988100AEF16D /* PageTagAssignmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25DA50A2CFD988100AEF16D /* PageTagAssignmentView.swift */; };
|
||||||
@ -298,6 +300,8 @@
|
|||||||
E229904B2D10BE59009F8D77 /* InitialSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitialSetupView.swift; sourceTree = "<group>"; };
|
E229904B2D10BE59009F8D77 /* InitialSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitialSetupView.swift; sourceTree = "<group>"; };
|
||||||
E229904D2D135349009F8D77 /* SecurityBookmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityBookmark.swift; sourceTree = "<group>"; };
|
E229904D2D135349009F8D77 /* SecurityBookmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityBookmark.swift; sourceTree = "<group>"; };
|
||||||
E24252092C52C9260029FF16 /* ContentLanguage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentLanguage.swift; sourceTree = "<group>"; };
|
E24252092C52C9260029FF16 /* ContentLanguage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentLanguage.swift; sourceTree = "<group>"; };
|
||||||
|
E2521DFB2D501DAE00C56662 /* PostContentGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostContentGenerator.swift; sourceTree = "<group>"; };
|
||||||
|
E2521DFF2D50BB6E00C56662 /* ItemLinkResults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemLinkResults.swift; sourceTree = "<group>"; };
|
||||||
E2581DEC2C75202400F1F079 /* Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tag.swift; sourceTree = "<group>"; };
|
E2581DEC2C75202400F1F079 /* Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tag.swift; sourceTree = "<group>"; };
|
||||||
E25A0B882CE4021400F33674 /* LocalizedPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedPage.swift; sourceTree = "<group>"; };
|
E25A0B882CE4021400F33674 /* LocalizedPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedPage.swift; sourceTree = "<group>"; };
|
||||||
E25DA5082CFD964E00AEF16D /* TagContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagContentView.swift; sourceTree = "<group>"; };
|
E25DA5082CFD964E00AEF16D /* TagContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagContentView.swift; sourceTree = "<group>"; };
|
||||||
@ -575,7 +579,6 @@
|
|||||||
E25DA5222CFF6C2600AEF16D /* ImageGenerator.swift */,
|
E25DA5222CFF6C2600AEF16D /* ImageGenerator.swift */,
|
||||||
E22990412D107A94009F8D77 /* ImageVersion.swift */,
|
E22990412D107A94009F8D77 /* ImageVersion.swift */,
|
||||||
E2FE0F182D2723E3002963B7 /* ImageSet.swift */,
|
E2FE0F182D2723E3002963B7 /* ImageSet.swift */,
|
||||||
E25DA5792D01C63E00AEF16D /* PageContentGenerator.swift */,
|
|
||||||
);
|
);
|
||||||
path = Generator;
|
path = Generator;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -945,6 +948,7 @@
|
|||||||
E2FE0F072D2689DC002963B7 /* Post Lists */ = {
|
E2FE0F072D2689DC002963B7 /* Post Lists */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E2521DFB2D501DAE00C56662 /* PostContentGenerator.swift */,
|
||||||
E2FE0F0C2D268A09002963B7 /* PostListPageGeneratorSource.swift */,
|
E2FE0F0C2D268A09002963B7 /* PostListPageGeneratorSource.swift */,
|
||||||
E2FE0F0A2D2689FF002963B7 /* FeedGeneratorSource.swift */,
|
E2FE0F0A2D2689FF002963B7 /* FeedGeneratorSource.swift */,
|
||||||
E2FE0F082D2689F0002963B7 /* TagPageGeneratorSource.swift */,
|
E2FE0F082D2689F0002963B7 /* TagPageGeneratorSource.swift */,
|
||||||
@ -957,8 +961,9 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
E2FE0F1D2D281ACE002963B7 /* TagOverviewGenerator.swift */,
|
E2FE0F1D2D281ACE002963B7 /* TagOverviewGenerator.swift */,
|
||||||
E25DA5982D02401A00AEF16D /* PageGenerator.swift */,
|
|
||||||
E2B85F3C2C4293F80047CD0C /* FeedPageGenerator.swift */,
|
E2B85F3C2C4293F80047CD0C /* FeedPageGenerator.swift */,
|
||||||
|
E25DA5792D01C63E00AEF16D /* PageContentGenerator.swift */,
|
||||||
|
E25DA5982D02401A00AEF16D /* PageGenerator.swift */,
|
||||||
);
|
);
|
||||||
path = "Page Generators";
|
path = "Page Generators";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1002,6 +1007,7 @@
|
|||||||
E2FE0F442D2BC76C002963B7 /* Markdown */ = {
|
E2FE0F442D2BC76C002963B7 /* Markdown */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E2521DFF2D50BB6E00C56662 /* ItemLinkResults.swift */,
|
||||||
E2FE0F102D268E78002963B7 /* MarkdownCodeProcessor.swift */,
|
E2FE0F102D268E78002963B7 /* MarkdownCodeProcessor.swift */,
|
||||||
E2FE0F4A2D2BCCA5002963B7 /* MarkdownHeadlineProcessor.swift */,
|
E2FE0F4A2D2BCCA5002963B7 /* MarkdownHeadlineProcessor.swift */,
|
||||||
E2FE0F452D2BC772002963B7 /* MarkdownImageProcessor.swift */,
|
E2FE0F452D2BC772002963B7 /* MarkdownImageProcessor.swift */,
|
||||||
@ -1237,8 +1243,10 @@
|
|||||||
E2FD1D2E2D37180900B48627 /* GeneralSettings.swift in Sources */,
|
E2FD1D2E2D37180900B48627 /* GeneralSettings.swift in Sources */,
|
||||||
E2FD1D542D46577700B48627 /* HtmlProducer.swift in Sources */,
|
E2FD1D542D46577700B48627 /* HtmlProducer.swift in Sources */,
|
||||||
E2FE0F0D2D268A09002963B7 /* PostListPageGeneratorSource.swift in Sources */,
|
E2FE0F0D2D268A09002963B7 /* PostListPageGeneratorSource.swift in Sources */,
|
||||||
|
E2521E002D50BB6E00C56662 /* ItemLinkResults.swift in Sources */,
|
||||||
E2FE0F402D2B45D3002963B7 /* SwiftBlock.swift in Sources */,
|
E2FE0F402D2B45D3002963B7 /* SwiftBlock.swift in Sources */,
|
||||||
E25DA58B2D020C9500AEF16D /* PageImage.swift in Sources */,
|
E25DA58B2D020C9500AEF16D /* PageImage.swift in Sources */,
|
||||||
|
E2521DFC2D5020BE00C56662 /* PostContentGenerator.swift in Sources */,
|
||||||
E21850232CF10C850090B18B /* TagSelectionView.swift in Sources */,
|
E21850232CF10C850090B18B /* TagSelectionView.swift in Sources */,
|
||||||
E2A21C332CB5BCAC0060935B /* PageContentView.swift in Sources */,
|
E2A21C332CB5BCAC0060935B /* PageContentView.swift in Sources */,
|
||||||
E22990402D0F95EC009F8D77 /* FolderOnDiskPropertyView.swift in Sources */,
|
E22990402D0F95EC009F8D77 /* FolderOnDiskPropertyView.swift in Sources */,
|
||||||
|
18
CHDataManagement/Generator/Markdown/ItemLinkResults.swift
Normal file
18
CHDataManagement/Generator/Markdown/ItemLinkResults.swift
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
protocol ItemLinkResults {
|
||||||
|
|
||||||
|
func externalLink(to url: String)
|
||||||
|
|
||||||
|
func missing(page: String, source: String)
|
||||||
|
|
||||||
|
func linked(to page: Page)
|
||||||
|
|
||||||
|
func missing(tag: String, source: String)
|
||||||
|
|
||||||
|
func linked(to tag: Tag)
|
||||||
|
|
||||||
|
func missing(file: String, source: String)
|
||||||
|
|
||||||
|
func require(file: FileResource)
|
||||||
|
}
|
||||||
|
|
@ -1,84 +1,110 @@
|
|||||||
import Ink
|
import Ink
|
||||||
|
|
||||||
|
extension PageGenerationResults: ItemLinkResults {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct MarkdownLinkProcessor: MarkdownProcessor {
|
struct MarkdownLinkProcessor: MarkdownProcessor {
|
||||||
|
|
||||||
static let modifier: Modifier.Target = .links
|
static let modifier: Modifier.Target = .links
|
||||||
|
|
||||||
private let content: Content
|
private let content: Content
|
||||||
|
|
||||||
private let results: PageGenerationResults
|
private let results: ItemLinkResults
|
||||||
|
|
||||||
private let language: ContentLanguage
|
private let language: ContentLanguage
|
||||||
|
|
||||||
|
init(content: Content, results: ItemLinkResults, language: ContentLanguage) {
|
||||||
|
self.content = content
|
||||||
|
self.results = results
|
||||||
|
self.language = language
|
||||||
|
}
|
||||||
|
|
||||||
init(content: Content, results: PageGenerationResults, language: ContentLanguage) {
|
init(content: Content, results: PageGenerationResults, language: ContentLanguage) {
|
||||||
self.content = content
|
self.content = content
|
||||||
self.results = results
|
self.results = results
|
||||||
self.language = language
|
self.language = language
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func process(html: String, markdown: Substring) -> String {
|
||||||
|
let markdownUrl = markdown.between("(", and: ")")
|
||||||
|
guard let (textToReplace, url) = convert(markdownUrl: markdownUrl) else {
|
||||||
|
// Keep original code, no changes needed
|
||||||
|
return html
|
||||||
|
}
|
||||||
|
guard let convertedUrl = url else {
|
||||||
|
// Remove link since the target can't be found
|
||||||
|
return markdown.between("[", and: "]")
|
||||||
|
}
|
||||||
|
return html.replacingOccurrences(of: textToReplace, with: convertedUrl)
|
||||||
|
}
|
||||||
|
|
||||||
private let pageLinkMarker = "page:"
|
private let pageLinkMarker = "page:"
|
||||||
|
|
||||||
private let tagLinkMarker = "tag:"
|
private let tagLinkMarker = "tag:"
|
||||||
|
|
||||||
private let fileLinkMarker = "file:"
|
private let fileLinkMarker = "file:"
|
||||||
|
|
||||||
func process(html: String, markdown: Substring) -> String {
|
func convert(markdownUrl: String) -> (textToChange: String, url: String?)? {
|
||||||
let url = markdown.between("(", and: ")")
|
if let result = handle(prefix: pageLinkMarker, in: markdownUrl, handler: convert(inlinePageLink:)) {
|
||||||
if url.hasPrefix(pageLinkMarker) {
|
return result
|
||||||
return handleInlinePageLink(url: url, html: html, markdown: markdown)
|
|
||||||
}
|
}
|
||||||
if url.hasPrefix(tagLinkMarker) {
|
if let result = handle(prefix: tagLinkMarker, in: markdownUrl, handler: convert(inlineTagLink:)) {
|
||||||
return handleInlineTagLink(url: url, html: html, markdown: markdown)
|
return result
|
||||||
}
|
}
|
||||||
if url.hasPrefix(fileLinkMarker) {
|
if let result = handle(prefix: fileLinkMarker, in: markdownUrl, handler: convert(inlineFileLink:)) {
|
||||||
return handleInlineFileLink(url: url, html: html, markdown: markdown)
|
return result
|
||||||
}
|
}
|
||||||
results.externalLink(to: url)
|
results.externalLink(to: markdownUrl)
|
||||||
return html
|
// No need to change anything
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleInlinePageLink(url: String, html: String, markdown: Substring) -> String {
|
private func handle(prefix: String, in markdownUrl: String, handler: (String) -> String?) -> (textToChange: String, url: String?)? {
|
||||||
// Retain links pointing to elements within a page
|
guard markdownUrl.hasPrefix(prefix) else {
|
||||||
let textToChange = url.dropAfterFirst("#")
|
// Continue search
|
||||||
let pageId = textToChange.replacingOccurrences(of: pageLinkMarker, with: "")
|
return nil
|
||||||
|
}
|
||||||
|
let inlineLink = markdownUrl.replacingOccurrences(of: prefix, with: "")
|
||||||
|
let itemId = inlineLink.dropAfterFirst("#")
|
||||||
|
let url = handler(itemId)
|
||||||
|
return (textToChange: prefix + itemId, url: url)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func convert(inlinePageLink pageId: String) -> String? {
|
||||||
guard let page = content.page(pageId) else {
|
guard let page = content.page(pageId) else {
|
||||||
results.missing(page: pageId, source: "Inline page link")
|
results.missing(page: pageId, source: "Inline page link")
|
||||||
// Remove link since the page can't be found
|
// Remove link since the page can't be found
|
||||||
return markdown.between("[", and: "]")
|
return nil
|
||||||
}
|
}
|
||||||
guard !page.isDraft else {
|
// Note link even for draft pages
|
||||||
return markdown.between("[", and: "]")
|
|
||||||
}
|
|
||||||
|
|
||||||
results.linked(to: page)
|
results.linked(to: page)
|
||||||
let pagePath = page.absoluteUrl(in: language)
|
|
||||||
return html.replacingOccurrences(of: textToChange, with: pagePath)
|
guard !page.isDraft else {
|
||||||
|
// TODO: Report links to draft pages
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return page.absoluteUrl(in: language)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleInlineTagLink(url: String, html: String, markdown: Substring) -> String {
|
private func convert(inlineTagLink: String) -> String? {
|
||||||
// Retain links pointing to elements within a page
|
let tagId = inlineTagLink.dropAfterFirst("#")
|
||||||
let textToChange = url.dropAfterFirst("#")
|
|
||||||
let tagId = textToChange.replacingOccurrences(of: tagLinkMarker, with: "")
|
|
||||||
guard let tag = content.tag(tagId) else {
|
guard let tag = content.tag(tagId) else {
|
||||||
results.missing(tag: tagId, source: "Inline tag link")
|
results.missing(tag: tagId, source: "Inline tag link")
|
||||||
// Remove link since the tag can't be found
|
// Remove link since the tag can't be found
|
||||||
return markdown.between("[", and: "]")
|
return nil
|
||||||
}
|
}
|
||||||
results.linked(to: tag)
|
results.linked(to: tag)
|
||||||
let tagPath = tag.absoluteUrl(in: language)
|
return tag.absoluteUrl(in: language)
|
||||||
return html.replacingOccurrences(of: textToChange, with: tagPath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleInlineFileLink(url: String, html: String, markdown: Substring) -> String {
|
private func convert(inlineFileLink fileId: String) -> String? {
|
||||||
// Retain links pointing to elements within a page
|
|
||||||
let fileId = url.replacingOccurrences(of: fileLinkMarker, with: "")
|
|
||||||
guard let file = content.file(fileId) else {
|
guard let file = content.file(fileId) else {
|
||||||
results.missing(file: fileId, source: "Inline file link")
|
results.missing(file: fileId, source: "Inline file link")
|
||||||
// Remove link since the file can't be found
|
// Remove link since the file can't be found
|
||||||
return markdown.between("[", and: "]")
|
return nil
|
||||||
}
|
}
|
||||||
results.require(file: file)
|
results.require(file: file)
|
||||||
let filePath = file.absoluteUrl
|
return file.absoluteUrl
|
||||||
return html.replacingOccurrences(of: url, with: filePath)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
import Foundation
|
||||||
|
import Ink
|
||||||
|
|
||||||
|
struct PostContentGenerator {
|
||||||
|
|
||||||
|
private let content: Content
|
||||||
|
|
||||||
|
private let results: PageGenerationResults
|
||||||
|
|
||||||
|
private let language: ContentLanguage
|
||||||
|
|
||||||
|
private let post: Post
|
||||||
|
|
||||||
|
init(content: Content, results: PageGenerationResults, language: ContentLanguage, post: Post) {
|
||||||
|
self.content = content
|
||||||
|
self.results = results
|
||||||
|
self.language = language
|
||||||
|
self.post = post
|
||||||
|
}
|
||||||
|
|
||||||
|
func generate() -> String {
|
||||||
|
let parser = MarkdownParser(modifiers: [
|
||||||
|
Modifier(target: .images, closure: handleImage),
|
||||||
|
Modifier(target: .codeBlocks, closure: handleCode),
|
||||||
|
Modifier(target: .links, closure: handleLink)
|
||||||
|
])
|
||||||
|
return parser.html(from: post.localized(in: language).text)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleImage(
|
||||||
|
html: String,
|
||||||
|
markdown: Substring
|
||||||
|
) -> String {
|
||||||
|
results.warning("Image in \(postDescription)")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleCode(
|
||||||
|
html: String,
|
||||||
|
markdown: Substring
|
||||||
|
) -> String {
|
||||||
|
results.warning("Code in \(postDescription)")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
private var postDescription: String {
|
||||||
|
"content of post \(post.id) (\(language.shortText))"
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleLink(
|
||||||
|
html: String,
|
||||||
|
markdown: Substring
|
||||||
|
) -> String {
|
||||||
|
let converter = MarkdownLinkProcessor(content: content, results: self, language: language)
|
||||||
|
let markdownUrl = markdown.between("(", and: ")")
|
||||||
|
let text = markdown.between("[", and: "]")
|
||||||
|
guard let url = converter.convert(markdownUrl: markdownUrl)?.url else {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
return "<span class='link' onclick=\"location.href='\(url)'; event.stopPropagation();\">\(text)</span>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PostContentGenerator: ItemLinkResults {
|
||||||
|
|
||||||
|
func externalLink(to url: String) {
|
||||||
|
results.externalLink(to: url)
|
||||||
|
}
|
||||||
|
|
||||||
|
func missing(page: String, source: String) {
|
||||||
|
results.missing(page: page, source: postDescription)
|
||||||
|
}
|
||||||
|
|
||||||
|
func linked(to page: Page) {
|
||||||
|
results.linked(to: page)
|
||||||
|
}
|
||||||
|
|
||||||
|
func missing(tag: String, source: String) {
|
||||||
|
results.missing(tag: tag, source: postDescription)
|
||||||
|
}
|
||||||
|
|
||||||
|
func linked(to tag: Tag) {
|
||||||
|
results.linked(to: tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func missing(file: String, source: String) {
|
||||||
|
results.missing(file: file, source: postDescription)
|
||||||
|
}
|
||||||
|
|
||||||
|
func require(file: FileResource) {
|
||||||
|
results.require(file: file)
|
||||||
|
}
|
||||||
|
}
|
@ -58,7 +58,7 @@ final class PostListPageGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makePostData(post: Post) -> FeedEntryData {
|
private func makePostData(post: Post, results: PageGenerationResults) -> FeedEntryData {
|
||||||
let localized: LocalizedPost = post.localized(in: language)
|
let localized: LocalizedPost = post.localized(in: language)
|
||||||
|
|
||||||
let linkUrl: FeedEntryData.Link? = post.linkedPage.map {
|
let linkUrl: FeedEntryData.Link? = post.linkedPage.map {
|
||||||
@ -88,6 +88,12 @@ final class PostListPageGenerator {
|
|||||||
media = nil
|
media = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let text = PostContentGenerator(
|
||||||
|
content: source.content,
|
||||||
|
results: source.results,
|
||||||
|
language: language,
|
||||||
|
post: post).generate()
|
||||||
|
|
||||||
return FeedEntryData(
|
return FeedEntryData(
|
||||||
entryId: post.id,
|
entryId: post.id,
|
||||||
title: localized.title,
|
title: localized.title,
|
||||||
@ -95,13 +101,12 @@ final class PostListPageGenerator {
|
|||||||
link: linkUrl,
|
link: linkUrl,
|
||||||
tags: tags,
|
tags: tags,
|
||||||
labels: localized.labels,
|
labels: localized.labels,
|
||||||
text: localized.text.components(separatedBy: "\n\n"),
|
text: text,
|
||||||
media: media)
|
media: media)
|
||||||
#warning("Treat post text as markdown")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createPostFeedPage(_ pageIndex: Int, pageCount: Int, posts: ArraySlice<Post>) {
|
private func createPostFeedPage(_ pageIndex: Int, pageCount: Int, posts: ArraySlice<Post>) {
|
||||||
let posts: [FeedEntryData] = posts.map(makePostData)
|
let posts: [FeedEntryData] = posts.map { makePostData(post: $0, results: source.results) }
|
||||||
|
|
||||||
let feedPageGenerator = FeedPageGenerator(content: source.content, results: source.results)
|
let feedPageGenerator = FeedPageGenerator(content: source.content, results: source.results)
|
||||||
|
|
||||||
|
@ -35,9 +35,7 @@ struct FeedEntry: HtmlProducer {
|
|||||||
TagList(tags: data.tags).populate(&result)
|
TagList(tags: data.tags).populate(&result)
|
||||||
ContentLabels(labels: data.labels).populate(&result)
|
ContentLabels(labels: data.labels).populate(&result)
|
||||||
|
|
||||||
for paragraph in data.text {
|
result += data.text
|
||||||
result += "<p>\(paragraph)</p>"
|
|
||||||
}
|
|
||||||
if let url = data.link {
|
if let url = data.link {
|
||||||
result += "<div class='link-center'><div class='link'>\(url.text)</div></div>"
|
result += "<div class='link-center'><div class='link'>\(url.text)</div></div>"
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,11 @@ struct FeedEntryData {
|
|||||||
|
|
||||||
let labels: [ContentLabel]
|
let labels: [ContentLabel]
|
||||||
|
|
||||||
let text: [String]
|
let text: String
|
||||||
|
|
||||||
let media: Media?
|
let media: Media?
|
||||||
|
|
||||||
init(entryId: String, title: String?, textAboveTitle: String, link: Link?, tags: [Tag], labels: [ContentLabel], text: [String], media: Media?) {
|
init(entryId: String, title: String?, textAboveTitle: String, link: Link?, tags: [Tag], labels: [ContentLabel], text: String, media: Media?) {
|
||||||
self.entryId = entryId
|
self.entryId = entryId
|
||||||
self.title = title
|
self.title = title
|
||||||
self.textAboveTitle = textAboveTitle
|
self.textAboveTitle = textAboveTitle
|
||||||
|
Loading…
x
Reference in New Issue
Block a user