@@ -6,16 +6,14 @@ package api
6
6
import (
7
7
"bufio"
8
8
"encoding/json"
9
+ "encoding/xml"
9
10
"fmt"
10
11
"html"
11
12
"io"
12
13
"log"
13
14
"os"
14
15
"regexp"
15
16
"strings"
16
-
17
- xhtml "golang.org/x/net/html"
18
- "golang.org/x/net/html/atom"
19
17
)
20
18
21
19
type apiDocumentation struct {
@@ -225,12 +223,17 @@ func getLeadingWhitespace(v string) string {
225
223
226
224
// generateDoc will generate the proper doc string for html encoded or plain text doc entries.
227
225
func generateDoc (htmlSrc string ) string {
228
- tokenizer := xhtml .NewTokenizer (strings .NewReader (htmlSrc ))
226
+ tokenizer := xml .NewDecoder (strings .NewReader (htmlSrc ))
227
+ tokenizer .Strict = false
228
+ tokenizer .AutoClose = xml .HTMLAutoClose
229
+ tokenizer .Entity = xml .HTMLEntity
230
+
231
+ // Some service docstrings are hopelessly malformed. Rather than throwing
232
+ // up our hands, the converter will map over as much as it can. If it
233
+ // returns an error, we stop there and go with whatever it was able to
234
+ // produce.
229
235
var builder strings.Builder
230
- if err := encodeHTMLToText (& builder , tokenizer ); err != nil {
231
- panic (fmt .Sprintf ("failed to generated docs, %v" , err ))
232
- }
233
-
236
+ encodeHTMLToText (& builder , tokenizer )
234
237
return wrap (strings .Trim (builder .String (), "\n " ), 72 )
235
238
}
236
239
@@ -241,31 +244,30 @@ type stringWriter interface {
241
244
WriteString (string ) (int , error )
242
245
}
243
246
244
- func encodeHTMLToText (w stringWriter , z * xhtml. Tokenizer ) error {
247
+ func encodeHTMLToText (w stringWriter , z * xml. Decoder ) error {
245
248
encoder := newHTMLTokenEncoder (w )
246
249
defer encoder .Flush ()
247
250
248
251
for {
249
- tt := z .Next ()
250
- if tt == xhtml .ErrorToken {
251
- if err := z .Err (); err == io .EOF {
252
- return nil
253
- } else if err != nil {
254
- return err
255
- }
252
+ tt , err := z .Token ()
253
+ if err == io .EOF {
254
+ return nil
255
+ }
256
+ if err != nil {
257
+ return err
256
258
}
257
259
258
- if err := encoder .Encode (z . Token () ); err != nil {
260
+ if err := encoder .Encode (tt ); err != nil {
259
261
return err
260
262
}
261
263
}
262
264
}
263
265
264
266
type htmlTokenHandler interface {
265
- OnStartTagToken (xhtml. Token ) htmlTokenHandler
266
- OnEndTagToken (xhtml .Token , bool )
267
- OnSelfClosingTagToken (xhtml .Token )
268
- OnTextTagToken (xhtml. Token )
267
+ OnStartTagToken (xml. StartElement ) htmlTokenHandler
268
+ OnEndTagToken (xml .Token , bool )
269
+ OnSelfClosingTagToken (xml .Token )
270
+ OnTextTagToken (xml. CharData )
269
271
}
270
272
271
273
type htmlTokenEncoder struct {
@@ -293,29 +295,29 @@ func newHTMLTokenEncoder(w stringWriter) *htmlTokenEncoder {
293
295
}
294
296
295
297
func (e * htmlTokenEncoder ) Flush () error {
296
- e .baseHandler .handler .OnEndTagToken (xhtml. Token { Type : xhtml . TextToken } , true )
298
+ e .baseHandler .handler .OnEndTagToken (xml . CharData ([] byte {}) , true )
297
299
return nil
298
300
}
299
301
300
- func (e * htmlTokenEncoder ) Encode (token xhtml .Token ) error {
302
+ func (e * htmlTokenEncoder ) Encode (token xml .Token ) error {
301
303
h := e .baseHandler
302
304
if len (e .handlers ) != 0 {
303
305
h = e .handlers [len (e .handlers )- 1 ]
304
306
}
305
307
306
- switch token .Type {
307
- case xhtml . StartTagToken :
308
+ switch v := token .( type ) {
309
+ case xml. StartElement :
308
310
e .depth ++
309
311
310
- next := h .handler .OnStartTagToken (token )
312
+ next := h .handler .OnStartTagToken (v )
311
313
if next != nil {
312
314
e .handlers = append (e .handlers , tokenHandlerItem {
313
315
handler : next ,
314
316
depth : e .depth ,
315
317
})
316
318
}
317
319
318
- case xhtml . EndTagToken :
320
+ case xml. EndElement :
319
321
handlerBlockClosing := e .depth == h .depth
320
322
321
323
h .handler .OnEndTagToken (token , handlerBlockClosing )
@@ -330,11 +332,8 @@ func (e *htmlTokenEncoder) Encode(token xhtml.Token) error {
330
332
e .depth = 0
331
333
}
332
334
333
- case xhtml .SelfClosingTagToken :
334
- h .handler .OnSelfClosingTagToken (token )
335
-
336
- case xhtml .TextToken :
337
- h .handler .OnTextTagToken (token )
335
+ case xml.CharData :
336
+ h .handler .OnTextTagToken (v )
338
337
}
339
338
340
339
return nil
@@ -344,11 +343,11 @@ type baseTokenHandler struct {
344
343
w stringWriter
345
344
}
346
345
347
- func (e * baseTokenHandler ) OnStartTagToken (token xhtml. Token ) htmlTokenHandler { return nil }
348
- func (e * baseTokenHandler ) OnEndTagToken (token xhtml .Token , blockClosing bool ) {}
349
- func (e * baseTokenHandler ) OnSelfClosingTagToken (token xhtml .Token ) {}
350
- func (e * baseTokenHandler ) OnTextTagToken (token xhtml. Token ) {
351
- e .w .WriteString (token . Data )
346
+ func (e * baseTokenHandler ) OnStartTagToken (token xml. StartElement ) htmlTokenHandler { return nil }
347
+ func (e * baseTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {}
348
+ func (e * baseTokenHandler ) OnSelfClosingTagToken (token xml .Token ) {}
349
+ func (e * baseTokenHandler ) OnTextTagToken (token xml. CharData ) {
350
+ e .w .WriteString (string ( token ) )
352
351
}
353
352
354
353
type blockTokenHandler struct {
@@ -372,27 +371,27 @@ func newBlockTokenHandler(w stringWriter) *blockTokenHandler {
372
371
},
373
372
}
374
373
}
375
- func (e * blockTokenHandler ) OnStartTagToken (token xhtml. Token ) htmlTokenHandler {
374
+ func (e * blockTokenHandler ) OnStartTagToken (token xml. StartElement ) htmlTokenHandler {
376
375
e .started = true
377
376
if e .newlineBeforeNextBlock {
378
377
e .w .WriteString ("\n " )
379
378
e .newlineBeforeNextBlock = false
380
379
}
381
380
382
- switch token .DataAtom {
383
- case atom . A :
381
+ switch token .Name . Local {
382
+ case "a" :
384
383
return newLinkTokenHandler (e .w , token )
385
- case atom . Ul :
384
+ case "ul" :
386
385
e .w .WriteString ("\n " )
387
386
e .newlineBeforeNextBlock = true
388
387
return newListTokenHandler (e .w )
389
388
390
- case atom . Div , atom . Dt , atom . P , atom . H1 , atom . H2 , atom . H3 , atom . H4 , atom . H5 , atom . H6 :
389
+ case "div" , "dt" , "p" , "h1" , "h2" , "h3" , "h4" , "h5" , "h6" :
391
390
e .w .WriteString ("\n " )
392
391
e .newlineBeforeNextBlock = true
393
392
return newBlockTokenHandler (e .w )
394
393
395
- case atom . Pre , atom . Code :
394
+ case "pre" , "code" :
396
395
if e .rootBlock {
397
396
e .w .WriteString ("\n " )
398
397
e .w .WriteString (indent )
@@ -403,7 +402,7 @@ func (e *blockTokenHandler) OnStartTagToken(token xhtml.Token) htmlTokenHandler
403
402
404
403
return nil
405
404
}
406
- func (e * blockTokenHandler ) OnEndTagToken (token xhtml .Token , blockClosing bool ) {
405
+ func (e * blockTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {
407
406
if ! blockClosing {
408
407
return
409
408
}
@@ -417,34 +416,34 @@ func (e *blockTokenHandler) OnEndTagToken(token xhtml.Token, blockClosing bool)
417
416
e .strBuilder .Reset ()
418
417
}
419
418
420
- func (e * blockTokenHandler ) OnTextTagToken (token xhtml. Token ) {
419
+ func (e * blockTokenHandler ) OnTextTagToken (token xml. CharData ) {
421
420
if e .newlineBeforeNextBlock {
422
421
e .w .WriteString ("\n " )
423
422
e .newlineBeforeNextBlock = false
424
423
}
425
424
if ! e .started {
426
- token . Data = strings .TrimLeft (token . Data , " \t \n " )
425
+ token = xml . CharData ( strings .TrimLeft (string ( token ) , " \t \n " ) )
427
426
}
428
- if len (token . Data ) != 0 {
427
+ if len (token ) != 0 {
429
428
e .started = true
430
429
}
431
430
e .baseTokenHandler .OnTextTagToken (token )
432
431
}
433
432
434
433
type linkTokenHandler struct {
435
434
baseTokenHandler
436
- linkToken xhtml. Token
435
+ linkToken xml. StartElement
437
436
}
438
437
439
- func newLinkTokenHandler (w stringWriter , token xhtml. Token ) * linkTokenHandler {
438
+ func newLinkTokenHandler (w stringWriter , token xml. StartElement ) * linkTokenHandler {
440
439
return & linkTokenHandler {
441
440
baseTokenHandler : baseTokenHandler {
442
441
w : w ,
443
442
},
444
443
linkToken : token ,
445
444
}
446
445
}
447
- func (e * linkTokenHandler ) OnEndTagToken (token xhtml .Token , blockClosing bool ) {
446
+ func (e * linkTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {
448
447
if ! blockClosing {
449
448
return
450
449
}
@@ -467,9 +466,9 @@ func newListTokenHandler(w stringWriter) *listTokenHandler {
467
466
},
468
467
}
469
468
}
470
- func (e * listTokenHandler ) OnStartTagToken (token xhtml. Token ) htmlTokenHandler {
471
- switch token .DataAtom {
472
- case atom . Li :
469
+ func (e * listTokenHandler ) OnStartTagToken (token xml. StartElement ) htmlTokenHandler {
470
+ switch token .Name . Local {
471
+ case "li" :
473
472
if e .items >= 1 {
474
473
e .w .WriteString ("\n \n " )
475
474
}
@@ -479,7 +478,7 @@ func (e *listTokenHandler) OnStartTagToken(token xhtml.Token) htmlTokenHandler {
479
478
return nil
480
479
}
481
480
482
- func (e * listTokenHandler ) OnTextTagToken (token xhtml. Token ) {
481
+ func (e * listTokenHandler ) OnTextTagToken (token xml. CharData ) {
483
482
// Squash whitespace between list and items
484
483
}
485
484
@@ -500,14 +499,14 @@ func newListItemTokenHandler(w stringWriter) *listItemTokenHandler {
500
499
},
501
500
}
502
501
}
503
- func (e * listItemTokenHandler ) OnStartTagToken (token xhtml. Token ) htmlTokenHandler {
504
- switch token .DataAtom {
505
- case atom . P :
502
+ func (e * listItemTokenHandler ) OnStartTagToken (token xml. StartElement ) htmlTokenHandler {
503
+ switch token .Name . Local {
504
+ case "p" :
506
505
return newBlockTokenHandler (e .w )
507
506
}
508
507
return nil
509
508
}
510
- func (e * listItemTokenHandler ) OnEndTagToken (token xhtml .Token , blockClosing bool ) {
509
+ func (e * listItemTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {
511
510
if ! blockClosing {
512
511
return
513
512
}
@@ -533,18 +532,18 @@ func newTrimSpaceTokenHandler(w stringWriter) *trimSpaceTokenHandler {
533
532
},
534
533
}
535
534
}
536
- func (e * trimSpaceTokenHandler ) OnEndTagToken (token xhtml .Token , blockClosing bool ) {
535
+ func (e * trimSpaceTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {
537
536
if ! blockClosing {
538
537
return
539
538
}
540
539
541
540
e .origWriter .WriteString (strings .TrimSpace (e .strBuilder .String ()))
542
541
}
543
542
544
- func getHTMLTokenAttr (attr []xhtml. Attribute , name string ) (string , bool ) {
543
+ func getHTMLTokenAttr (attr []xml. Attr , name string ) (string , bool ) {
545
544
for _ , a := range attr {
546
- if strings .EqualFold (a .Key , name ) {
547
- return a .Val , true
545
+ if strings .EqualFold (a .Name . Local , name ) {
546
+ return a .Value , true
548
547
}
549
548
}
550
549
return "" , false
0 commit comments