@@ -38,10 +38,22 @@ import Cocoa
3838/// values.
3939internal class Renderer : ObservableObject {
4040
41- // MARK: Public properties
41+ // MARK: Types
42+
43+ /// A set of values used to create an array of parsed component blocks.
44+ struct ParsingSource : Equatable {
45+
46+ /// The LaTeX input.
47+ let latex : String
48+
49+ /// Whether or not the HTML should be unencoded.
50+ let unencodeHTML : Bool
51+
52+ /// The parsing mode.
53+ let parsingMode : LaTeX . ParsingMode
54+ }
4255
43- /// The view's input string.
44- let latex : String
56+ // MARK: Public properties
4557
4658 /// Whether or not the view's blocks have been rendered.
4759 @MainActor @Published var rendered : Bool = false
@@ -57,18 +69,12 @@ internal class Renderer: ObservableObject {
5769 /// The LaTeX input's parsed blocks.
5870 private var _parsedBlocks : [ ComponentBlock ] ? = nil
5971
72+ /// The set of values used to create the parsed blocks.
73+ private var _parsingSource : ParsingSource ? = nil
74+
6075 /// Semaphore for thread-safe access to `_parsedBlocks`.
6176 private var _parsedBlocksSemaphore = DispatchSemaphore ( value: 1 )
6277
63- // MARK: Initializers
64-
65- /// Initializes a render state with an input string.
66- ///
67- /// - Parameter latex: The view's input string.
68- init ( latex: String ) {
69- self . latex = latex
70- }
71-
7278}
7379
7480// MARK: Public methods
@@ -78,14 +84,15 @@ extension Renderer {
7884 /// Returns whether the view's components are cached.
7985 ///
8086 /// - Parameters:
87+ /// - latex: The LaTeX input string.
8188 /// - unencodeHTML: The `unencodeHTML` environment variable.
8289 /// - parsingMode: The `parsingMode` environment variable.
8390 /// - processEscapes: The `processEscapes` environment variable.
8491 /// - errorMode: The `errorMode` environment variable.
8592 /// - font: The `font environment` variable.
8693 /// - displayScale: The `displayScale` environment variable.
87- /// - texOptions: The `texOptions` environment variable.
8894 func isCached(
95+ latex: String ,
8996 unencodeHTML: Bool ,
9097 parsingMode: LaTeX . ParsingMode ,
9198 processEscapes: Bool ,
@@ -95,7 +102,7 @@ extension Renderer {
95102 ) -> Bool {
96103 let texOptions = TeXInputProcessorOptions ( processEscapes: processEscapes, errorMode: errorMode)
97104 return blocksExistInCache (
98- parsedBlocks ( unencodeHTML: unencodeHTML, parsingMode: parsingMode) ,
105+ parsedBlocks ( latex : latex , unencodeHTML: unencodeHTML, parsingMode: parsingMode) ,
99106 font: font,
100107 displayScale: displayScale,
101108 texOptions: texOptions)
@@ -104,14 +111,15 @@ extension Renderer {
104111 /// Renders the view's components synchronously.
105112 ///
106113 /// - Parameters:
114+ /// - latex: The LaTeX input string.
107115 /// - unencodeHTML: The `unencodeHTML` environment variable.
108116 /// - parsingMode: The `parsingMode` environment variable.
109117 /// - processEscapes: The `processEscapes` environment variable.
110118 /// - errorMode: The `errorMode` environment variable.
111119 /// - font: The `font environment` variable.
112120 /// - displayScale: The `displayScale` environment variable.
113- /// - texOptions: The `texOptions` environment variable.
114121 func renderSync(
122+ latex: String ,
115123 unencodeHTML: Bool ,
116124 parsingMode: LaTeX . ParsingMode ,
117125 processEscapes: Bool ,
@@ -121,7 +129,7 @@ extension Renderer {
121129 ) -> [ ComponentBlock ] {
122130 let texOptions = TeXInputProcessorOptions ( processEscapes: processEscapes, errorMode: errorMode)
123131 return render (
124- blocks: parsedBlocks ( unencodeHTML: unencodeHTML, parsingMode: parsingMode) ,
132+ blocks: parsedBlocks ( latex : latex , unencodeHTML: unencodeHTML, parsingMode: parsingMode) ,
125133 font: font,
126134 displayScale: displayScale,
127135 texOptions: texOptions)
@@ -130,14 +138,15 @@ extension Renderer {
130138 /// Renders the view's components asynchronously.
131139 ///
132140 /// - Parameters:
141+ /// - latex: The LaTeX input string.
133142 /// - unencodeHTML: The `unencodeHTML` environment variable.
134143 /// - parsingMode: The `parsingMode` environment variable.
135144 /// - processEscapes: The `processEscapes` environment variable.
136145 /// - errorMode: The `errorMode` environment variable.
137146 /// - font: The `font environment` variable.
138147 /// - displayScale: The `displayScale` environment variable.
139- /// - texOptions: The `texOptions` environment variable.
140148 func render(
149+ latex: String ,
141150 unencodeHTML: Bool ,
142151 parsingMode: LaTeX . ParsingMode ,
143152 processEscapes: Bool ,
@@ -156,7 +165,7 @@ extension Renderer {
156165
157166 let texOptions = TeXInputProcessorOptions ( processEscapes: processEscapes, errorMode: errorMode)
158167 let renderedBlocks = await render (
159- blocks: parsedBlocks ( unencodeHTML: unencodeHTML, parsingMode: parsingMode) ,
168+ blocks: parsedBlocks ( latex : latex , unencodeHTML: unencodeHTML, parsingMode: parsingMode) ,
160169 font: font,
161170 displayScale: displayScale,
162171 texOptions: texOptions)
@@ -313,21 +322,26 @@ extension Renderer {
313322 /// Gets the LaTeX input's parsed blocks.
314323 ///
315324 /// - Parameters:
325+ /// - latex: The LaTeX input string.
316326 /// - unencodeHTML: The `unencodeHTML` environment variable.
317327 /// - parsingMode: The `parsingMode` environment variable.
318328 /// - Returns: The parsed blocks.
319329 private func parsedBlocks(
330+ latex: String ,
320331 unencodeHTML: Bool ,
321332 parsingMode: LaTeX . ParsingMode
322333 ) -> [ ComponentBlock ] {
323334 _parsedBlocksSemaphore. wait ( )
324335 defer { _parsedBlocksSemaphore. signal ( ) }
325- if let _parsedBlocks {
336+
337+ let currentSource = ParsingSource ( latex: latex, unencodeHTML: unencodeHTML, parsingMode: parsingMode)
338+ if let _parsedBlocks, _parsingSource == currentSource {
326339 return _parsedBlocks
327340 }
328341
329342 let blocks = Parser . parse ( unencodeHTML ? latex. htmlUnescape ( ) : latex, mode: parsingMode)
330343 _parsedBlocks = blocks
344+ _parsingSource = currentSource
331345 return blocks
332346 }
333347
0 commit comments