@@ -37,21 +37,12 @@ open class AttributedStringGenerator {
37
37
/// Customized html generator to work around limitations of the current HTML to
38
38
/// `NSAttributedString` conversion logic provided by the operating system.
39
39
open class InternalHtmlGenerator : HtmlGenerator {
40
- weak var outer : AttributedStringGenerator ?
40
+ var outer : AttributedStringGenerator ?
41
41
42
42
public init ( outer: AttributedStringGenerator ) {
43
43
self . outer = outer
44
44
}
45
45
46
- open override func generate( textFragment fragment: TextFragment ) -> String {
47
- switch fragment {
48
- case . custom( let customTextFragment) :
49
- return customTextFragment. generateHtml ( via: self , and: self . outer)
50
- default :
51
- return super. generate ( textFragment: fragment)
52
- }
53
- }
54
-
55
46
open override func generate( block: Block , tight: Bool = false ) -> String {
56
47
switch block {
57
48
case . list( _, _, _) :
@@ -121,6 +112,33 @@ open class AttributedStringGenerator {
121
112
return super. generate ( block: block, tight: tight)
122
113
}
123
114
}
115
+
116
+ open override func generate( textFragment fragment: TextFragment ) -> String {
117
+ switch fragment {
118
+ case . image( let text, let uri, let title) :
119
+ let titleAttr = title == nil ? " " : " title= \" \( title!) \" "
120
+ if let uriStr = uri {
121
+ let url = URL ( string: uriStr)
122
+ Swift . print ( " === URL0 = \( url? . absoluteString ?? " none " ) , \( url? . scheme == nil ) , \( self . outer == nil ) " )
123
+ if ( url? . scheme == nil ) || ( url? . isFileURL ?? false ) ,
124
+ let baseUrl = self . outer? . imageBaseUrl {
125
+ let url = URL ( fileURLWithPath: uriStr, relativeTo: baseUrl)
126
+ Swift . print ( " URL2 = \( url. absoluteString) " )
127
+ if url. isFileURL {
128
+ return " <img src= \" \( url. absoluteURL. path) \" " +
129
+ " alt= \" \( text. rawDescription) \" \( titleAttr) /> "
130
+ }
131
+ }
132
+ return " <img src= \" \( uriStr) \" alt= \" \( text. rawDescription) \" \( titleAttr) /> "
133
+ } else {
134
+ return self . generate ( text: text)
135
+ }
136
+ case . custom( let customTextFragment) :
137
+ return customTextFragment. generateHtml ( via: self , and: self . outer)
138
+ default :
139
+ return super. generate ( textFragment: fragment)
140
+ }
141
+ }
124
142
}
125
143
126
144
/// Default `AttributedStringGenerator` implementation.
@@ -171,6 +189,19 @@ open class AttributedStringGenerator {
171
189
/// The color of H4 headers.
172
190
public let h4Color : String
173
191
192
+ /// The maximum width of an image
193
+ public let maxImageWidth : String ?
194
+
195
+ /// The maximum height of an image
196
+ public let maxImageHeight : String ?
197
+
198
+ /// Custom CSS style
199
+ public let customStyle : String
200
+
201
+ /// If provided, this URL is used as a base URL for relative image links
202
+ public let imageBaseUrl : URL ?
203
+
204
+
174
205
/// Constructor providing customization options for the generated `NSAttributedString` markup.
175
206
public init ( fontSize: Float = 14.0 ,
176
207
fontFamily: String = " \" Times New Roman \" ,Times,serif " ,
@@ -187,7 +218,11 @@ open class AttributedStringGenerator {
187
218
h1Color: String = mdDefaultColor,
188
219
h2Color: String = mdDefaultColor,
189
220
h3Color: String = mdDefaultColor,
190
- h4Color: String = mdDefaultColor) {
221
+ h4Color: String = mdDefaultColor,
222
+ maxImageWidth: String ? = nil ,
223
+ maxImageHeight: String ? = nil ,
224
+ customStyle: String = " " ,
225
+ imageBaseUrl: URL ? = nil ) {
191
226
self . fontSize = fontSize
192
227
self . fontFamily = fontFamily
193
228
self . fontColor = fontColor
@@ -203,6 +238,10 @@ open class AttributedStringGenerator {
203
238
self . h2Color = h2Color
204
239
self . h3Color = h3Color
205
240
self . h4Color = h4Color
241
+ self . maxImageWidth = maxImageWidth
242
+ self . maxImageHeight = maxImageHeight
243
+ self . customStyle = customStyle
244
+ self . imageBaseUrl = imageBaseUrl
206
245
}
207
246
208
247
/// Generates an attributed string from the given Markdown document
@@ -266,14 +305,16 @@ open class AttributedStringGenerator {
266
305
" td.codebox { \( self . codeBoxStyle) } \n " +
267
306
" td.thematic { \( self . thematicBreakStyle) } \n " +
268
307
" td.quote { \( self . quoteStyle) } \n " +
308
+ " img { \( self . imgStyle) } \n " +
269
309
" dt { \n " +
270
310
" font-weight: bold; \n " +
271
311
" margin: 0.6em 0 0.4em 0; \n " +
272
312
" } \n " +
273
313
" dd { \n " +
274
314
" margin: 0.5em 0 1em 2em; \n " +
275
315
" padding: 0.5em 0 1em 2em; \n " +
276
- " } \n "
316
+ " } \n " +
317
+ " \( self . customStyle) \n "
277
318
}
278
319
279
320
open var bodyStyle : String {
@@ -361,6 +402,23 @@ open class AttributedStringGenerator {
361
402
" width: 0.4em; "
362
403
}
363
404
405
+ open var imgStyle : String {
406
+ if let maxWidth = self . maxImageWidth {
407
+ if let maxHeight = self . maxImageHeight {
408
+ return " max-width: \( maxWidth) ;max-height: \( maxHeight) ; " +
409
+ " !important;width: auto;height: auto; "
410
+ } else {
411
+ return " max-width: \( maxWidth) ;max-height: 100%; " +
412
+ " !important;width: auto;height: auto; "
413
+ }
414
+ } else if let maxHeight = self . maxImageHeight {
415
+ return " max-width: 100%;max-height: \( maxHeight) ; " +
416
+ " !important;width: auto;height: auto; "
417
+ } else {
418
+ return " "
419
+ }
420
+ }
421
+
364
422
open var tableStyle : String {
365
423
return " border-collapse: collapse; " +
366
424
" margin: 0.3em 0; " +
0 commit comments