11using System . Buffers ;
2+ using System . Diagnostics ;
23using System . Net ;
34using System . Xml . Linq ;
45using AngleSharp . Dom ;
@@ -120,41 +121,46 @@ protected internal override bool TryResolveHref(string href, string sourceDir, o
120121 {
121122 titleEn = null ;
122123
123- if ( ! href . StartsWith ( '/' ) && Uri . IsWellFormedUriString ( href , UriKind . Relative ) )
124+ var parts = new UrlParts ( href ) ;
125+
126+ if ( parts . IsAbosolute || href . StartsWith ( '/' ) || href . StartsWith ( '#' ) )
124127 {
125- var fullPath = Path . GetFullPath ( href , sourceDir ) ;
126- if ( fullPath . StartsWith ( SourceFolder )
127- && Path . GetDirectoryName ( Path . GetDirectoryName ( Path . GetDirectoryName ( fullPath . AsSpan ( ) ) ) ) is { IsEmpty : false } targetBookDirContainer )
128- {
129- var targetFile = WebUtility . UrlDecode ( fullPath [ ( targetBookDirContainer . Length + 1 ) ..] . Replace ( '\\ ' , '/' ) ) ;
128+ result = href ;
129+ return true ;
130+ }
130131
131- if ( PageLinks . TryGetValue ( targetFile , out var link )
132- || ( MovedPages . TryGetValue ( targetFile , out var movedToFile ) && PageLinks . TryGetValue ( movedToFile , out link ) ) )
132+ var path = parts is { Query . Length : 0 , Hash . Length : 0 } ? href : parts . Path . ToString ( ) ;
133+ Debug . Assert ( ! path . IsEmpty ) ;
134+
135+ var fullPath = Path . GetFullPath ( path , sourceDir ) ;
136+ if ( fullPath . StartsWith ( SourceFolder )
137+ && Path . GetDirectoryName ( Path . GetDirectoryName ( Path . GetDirectoryName ( fullPath . AsSpan ( ) ) ) ) is { IsEmpty : false } targetBookDirContainer )
138+ {
139+ var targetFile = WebUtility . UrlDecode ( fullPath [ ( targetBookDirContainer . Length + 1 ) ..] . Replace ( '\\ ' , '/' ) ) ;
140+
141+ if ( PageLinks . TryGetValue ( targetFile , out var link )
142+ || ( MovedPages . TryGetValue ( targetFile , out var movedToFile ) && PageLinks . TryGetValue ( movedToFile , out link ) ) )
143+ {
144+ if ( Language == "en" )
133145 {
134- if ( Language == "en" )
135- {
136- result = '/' . TrySurroundEach ( link . book , link . url ) ;
137- }
138- else
139- {
140- result = '/' . TrySurroundEach ( link . book , link . url , Language ) ;
141- }
146+ result = '/' . TrySurroundEach ( link . book , link . url ) ;
147+ }
148+ else
149+ {
150+ result = '/' . TrySurroundEach ( link . book , link . url , Language ) ;
151+ }
142152
143- titleEn = link . titleEn ;
144- return true ;
153+ if ( ! parts . Query . IsEmpty || ! parts . Hash . IsEmpty )
154+ {
155+ result = $ "{ result } { parts . Query } { parts . Hash } ";
145156 }
146- }
147157
148- result = "Unknown href mapping" ;
149- return false ;
150- }
151- else if ( href . StartsWith ( "mailto:" ) || href . StartsWith ( "javascript:" ) || Uri . IsWellFormedUriString ( href , UriKind . Absolute ) )
152- {
153- result = href ;
154- return true ;
158+ titleEn = link . titleEn ;
159+ return true ;
160+ }
155161 }
156162
157- result = "Unrecognized href pattern " ;
163+ result = "Unknown href mapping " ;
158164 return false ;
159165 }
160166
@@ -163,93 +169,106 @@ protected override string GetSharedImageSrc(string path, string fileName)
163169
164170 protected internal override bool TryResolveSrc ( string src , string sourceDir , out string result , out ( string src , string dst ) ? copy )
165171 {
166- if ( src . StartsWith ( "../images/" ) )
172+ var parts = new UrlParts ( src ) ;
173+
174+ if ( parts . IsAbosolute || src . StartsWith ( '/' ) )
167175 {
168- var srcImg = new FileInfo ( Path . GetFullPath ( src , sourceDir ) ) ;
169- var needsCopy = true ;
176+ result = src ;
177+ copy = null ;
178+ return true ;
179+ }
170180
171- var fileName = Path . GetFileName ( src ) ;
172- if ( SharedImages . TryGetValue ( fileName , out result ! ) )
173- {
174- needsCopy = false ;
175- }
176- else if ( srcImg . Exists )
177- {
178- result = '/' . TryPrefixEach ( BookUrlName , Language , src [ "../" . Length ..] ) ;
181+ var path = parts is { Query . Length : 0 , Hash . Length : 0 } ? src : parts . Path . ToString ( ) ;
182+ Debug . Assert ( ! path . IsEmpty ) ;
179183
180- if ( Language == "en" )
184+ var indexOfImages = path . IndexOf ( "images/" ) ;
185+ Debug . Assert ( indexOfImages > - 1 ) ;
186+
187+ var srcImg = new FileInfo ( Path . GetFullPath ( path , sourceDir ) ) ;
188+ var needsCopy = true ;
189+
190+ var fileName = Path . GetFileName ( path ) ;
191+ if ( SharedImages . TryGetValue ( fileName , out result ! ) )
192+ {
193+ needsCopy = false ;
194+ }
195+ else if ( srcImg . Exists )
196+ {
197+ result = '/' . TryPrefixEach ( BookUrlName , Language , path [ indexOfImages ..] ) ;
198+
199+ if ( Language == "en" )
200+ {
201+ if ( ! EnglishImages . TryGetValue ( path , out var visited ) )
181202 {
182- if ( ! EnglishImages . TryGetValue ( src , out var visited ) )
183- {
184- var size = srcImg . Length ;
185- var hash = FileHash . UInt64FromFile ( srcImg . FullName ) ;
203+ var size = srcImg . Length ;
204+ var hash = FileHash . UInt64FromFile ( srcImg . FullName ) ;
186205
187- EnglishImages . Add ( src , ( size , hash , result ) ) ;
188- }
189- else
190- {
191- result = visited . url ;
192- needsCopy = false ;
193- }
206+ EnglishImages . Add ( path , ( size , hash , result ) ) ;
194207 }
195208 else
196209 {
197- if ( VisitedImages . TryGetValue ( src , out var prevUrl ) )
198- {
199- result = prevUrl ;
200- needsCopy = false ;
201- }
202- else
203- {
204- VisitedImages . Add ( src , result ) ;
205-
206- if ( EnglishImages . TryGetValue ( src , out var visited ) && srcImg . Length == visited . size && FileHash . UInt64FromFile ( srcImg . FullName ) == visited . hash )
207- {
208- result = VisitedImages [ src ] = visited . url ;
209- needsCopy = false ;
210- }
211- }
210+ result = visited . url ;
211+ needsCopy = false ;
212212 }
213213 }
214214 else
215215 {
216- var srcImgEn = $ "{ SourceFolderEn } { srcImg . FullName . AsSpan ( SourceFolderEn . Length ) } ";
217-
218- if ( ! File . Exists ( srcImgEn ) )
216+ if ( VisitedImages . TryGetValue ( path , out var prevUrl ) )
219217 {
220- result = "Image src not found" ;
221- copy = null ;
222- return false ;
218+ result = prevUrl ;
219+ needsCopy = false ;
223220 }
221+ else
222+ {
223+ VisitedImages . Add ( path , result ) ;
224224
225- result = '/' . TryPrefixEach ( BookUrlName , "en" , src [ "../" . Length ..] ) ;
226- needsCopy = false ;
227- }
228-
229- if ( UseWebp )
230- {
231- var resultDir = Path . GetDirectoryName ( result . AsSpan ( ) ) ;
232- var resultFileName = Path . GetFileNameWithoutExtension ( result . AsSpan ( ) ) ;
233-
234- result = $ "{ resultDir } /{ resultFileName } .webp";
225+ if ( EnglishImages . TryGetValue ( path , out var visited ) && srcImg . Length == visited . size && FileHash . UInt64FromFile ( srcImg . FullName ) == visited . hash )
226+ {
227+ result = VisitedImages [ path ] = visited . url ;
228+ needsCopy = false ;
229+ }
230+ }
235231 }
232+ }
233+ else
234+ {
235+ var srcImgEn = $ "{ SourceFolderEn } { srcImg . FullName . AsSpan ( SourceFolderEn . Length ) } ";
236236
237- if ( ! needsCopy )
237+ if ( ! File . Exists ( srcImgEn ) )
238238 {
239+ result = "Image src not found" ;
239240 copy = null ;
240- }
241- else
242- {
243- var dstImg = Path . Combine ( OutputFolder , Language , src [ "../" . Length ..] ) ;
244- copy = ( srcImg . FullName , dstImg ) ;
241+ return false ;
245242 }
246243
247- return true ;
244+ result = '/' . TryPrefixEach ( BookUrlName , "en" , path [ indexOfImages ..] ) ;
245+ needsCopy = false ;
248246 }
249247
250- result = "Unrecognized src" ;
251- copy = null ;
252- return false ;
248+ if ( UseWebp )
249+ {
250+ var resultDir = Path . GetDirectoryName ( result . AsSpan ( ) ) ;
251+ var resultFileName = Path . GetFileNameWithoutExtension ( result . AsSpan ( ) ) ;
252+
253+ result = $ "{ resultDir } /{ resultFileName } .webp";
254+ }
255+
256+ if ( ! needsCopy )
257+ {
258+ copy = null ;
259+ }
260+ else
261+ {
262+ var dstImg = Path . Combine ( OutputFolder , Language , path [ indexOfImages ..] ) ;
263+ copy = ( srcImg . FullName , dstImg ) ;
264+ }
265+
266+ if ( ! parts . Query . IsEmpty )
267+ {
268+ result = $ "{ result } { parts . Query } ";
269+ }
270+
271+ return true ;
253272 }
254273
255274 protected override IHtmlElement ? TransformImage ( IHtmlDocument document , IHtmlImageElement img , string sourceFile , string sourceDir )
0 commit comments