Optimize HTML export

This commit is contained in:
kean
2023-01-14 12:36:00 -05:00
parent 697a5b42d5
commit f786e73eff
2 changed files with 51 additions and 25 deletions
+27 -15
View File
@@ -18,32 +18,44 @@ enum TextUtilities {
let data = try string.data(from: range, documentAttributes: [
.documentType: NSAttributedString.DocumentType.html
])
guard var html = String(data: data, encoding: .utf8) else {
guard let html = NSMutableString(data: data, encoding: NSUTF8StringEncoding) else {
return data
}
func insert(_ string: String, at index: String.Index) {
html.insert(contentsOf: "\n\(string)", at: index)
func getRange(of string: String) -> NSRange? {
let range = html.range(of: string)
return range.location == NSNotFound ? nil : range
}
// TODO: Use JavaScriptCore and DOM to perform these manipulations
func insert(_ string: String, at index: Int) {
html.insert("\n\(string)", at: index)
}
if let range = html.firstRange(of: "<head>") {
if let range = getRange(of: "<head>") {
insert(#"<meta name="viewport" content="width=device-width, initial-scale=1">"#, at: range.upperBound)
insert(#"<meta name="generator" content="Pulse">"#, at: range.upperBound)
}
if let range = html.firstRange(of: "<style type=\"text/css\">") {
if let range = getRange(of: "<style type=\"text/css\">") {
insert(#"span { line-height: 1.4; }"#, at: range.upperBound)
insert(#"body { word-wrap: break-word; padding: 8px; }"#, at: range.upperBound)
}
let regular = #"font-family: 'SF Pro Text', -apple-system, sans-serif"#
let mono = #"font-family: 'SF Mono', SFMono-Regular, ui-monospace, Menlo, monospace;"#
html = html.replacingOccurrences(of: #"font-family: '.SFUI-Regular'"#, with: regular)
html = html.replacingOccurrences(of: #"font-family: '.SFUI-Medium'"#, with: regular)
html = html.replacingOccurrences(of: #"font-family: '.SFUI-Semibold'"#, with: regular)
html = html.replacingOccurrences(of: #"font-family: '.AppleSystemUIFontMonospaced-Regular'"#, with: mono)
html = html.replacingOccurrences(of: #"font-family: '.AppleSystemUIFontMonospaced-Semibold'"#, with: mono)
html = html.replacingOccurrences(of: #"font-family: '.AppleSystemUIFontMonospaced-Medium'"#, with: mono)
return html.data(using: .utf8) ?? data
if let range = getRange(of: "</style>") {
let regular = #"font-family: 'SF Pro Text', -apple-system, sans-serif"#
let mono = #"font-family: 'SF Mono', SFMono-Regular, ui-monospace, Menlo, monospace;"#
do {
let regex = try NSRegularExpression(pattern: "font-family: '.SFUI-\\w*'", options: [])
regex.replaceMatches(in: html, range: NSRange(location: 0, length: range.upperBound), withTemplate: regular)
} catch {
// Should never happen
}
do {
let regex = try NSRegularExpression(pattern: "font-family: '.AppleSystemUIFontMonospaced-\\w*'", options: [])
regex.replaceMatches(in: html, range: NSRange(location: 0, length: range.upperBound), withTemplate: mono)
} catch {
// Should never happen
}
}
return html.data(using: NSUTF8StringEncoding) ?? data
}
/// Renders the given attributed string as PDF
@@ -16,16 +16,6 @@ final class TextRendererTestsTests: XCTestCase {
}
}
func testAttributedStringBigStore() throws {
let url = try XCTUnwrap(Bundle(for: TextRendererTestsTests.self).url(forResource: "bigstore", withExtension: "pulse"))
let store = try LoggerStore(storeURL: url)
let entities = try store.allMessages()
benchmark(title: "Entities -> NSAttributedString") {
let _ = TextRendererTests.share(entities)
}
}
func testPlainTextConversion() throws {
let entities = try LoggerStore.mock.allMessages()
let string = TextRendererTests.share(entities)
@@ -57,6 +47,30 @@ final class TextRendererTestsTests: XCTestCase {
}
}
#endif
// MARK: Big Store
func testBigStoreAttributedString() throws {
let url = try XCTUnwrap(Bundle(for: TextRendererTestsTests.self).url(forResource: "bigstore", withExtension: "pulse"))
let store = try LoggerStore(storeURL: url)
let entities = try store.allMessages()
benchmark(title: "Entities -> NSAttributedString") {
let _ = TextRendererTests.share(entities)
}
}
func testBigStoreHTML() throws {
let url = try XCTUnwrap(Bundle(for: TextRendererTestsTests.self).url(forResource: "bigstore", withExtension: "pulse"))
let store = try LoggerStore(storeURL: url)
let entities = try store.allMessages()
let string = TextRendererTests.share(entities)
benchmark(title: "NSAttributedString -> HTML") {
let _ = try! TextRendererTests.html(from: string)
}
}
}
@discardableResult