@@ -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,12 @@ 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
+ // TODO
336
+ ////case xml.SelfClosingTagToken:
337
+ //// h.handler.OnSelfClosingTagToken(token)
335
338
336
- case xhtml . TextToken :
337
- h .handler .OnTextTagToken (token )
339
+ case xml. CharData :
340
+ h .handler .OnTextTagToken (v )
338
341
}
339
342
340
343
return nil
@@ -344,11 +347,11 @@ type baseTokenHandler struct {
344
347
w stringWriter
345
348
}
346
349
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 )
350
+ func (e * baseTokenHandler ) OnStartTagToken (token xml. StartElement ) htmlTokenHandler { return nil }
351
+ func (e * baseTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {}
352
+ func (e * baseTokenHandler ) OnSelfClosingTagToken (token xml .Token ) {}
353
+ func (e * baseTokenHandler ) OnTextTagToken (token xml. CharData ) {
354
+ e .w .WriteString (string ( token ) )
352
355
}
353
356
354
357
type blockTokenHandler struct {
@@ -372,27 +375,27 @@ func newBlockTokenHandler(w stringWriter) *blockTokenHandler {
372
375
},
373
376
}
374
377
}
375
- func (e * blockTokenHandler ) OnStartTagToken (token xhtml. Token ) htmlTokenHandler {
378
+ func (e * blockTokenHandler ) OnStartTagToken (token xml. StartElement ) htmlTokenHandler {
376
379
e .started = true
377
380
if e .newlineBeforeNextBlock {
378
381
e .w .WriteString ("\n " )
379
382
e .newlineBeforeNextBlock = false
380
383
}
381
384
382
- switch token .DataAtom {
383
- case atom . A :
385
+ switch token .Name . Local {
386
+ case "a" :
384
387
return newLinkTokenHandler (e .w , token )
385
- case atom . Ul :
388
+ case "ul" :
386
389
e .w .WriteString ("\n " )
387
390
e .newlineBeforeNextBlock = true
388
391
return newListTokenHandler (e .w )
389
392
390
- case atom . Div , atom . Dt , atom . P , atom . H1 , atom . H2 , atom . H3 , atom . H4 , atom . H5 , atom . H6 :
393
+ case "div" , "dt" , "p" , "h1" , "h2" , "h3" , "h4" , "h5" , "h6" :
391
394
e .w .WriteString ("\n " )
392
395
e .newlineBeforeNextBlock = true
393
396
return newBlockTokenHandler (e .w )
394
397
395
- case atom . Pre , atom . Code :
398
+ case "pre" , "code" :
396
399
if e .rootBlock {
397
400
e .w .WriteString ("\n " )
398
401
e .w .WriteString (indent )
@@ -403,7 +406,7 @@ func (e *blockTokenHandler) OnStartTagToken(token xhtml.Token) htmlTokenHandler
403
406
404
407
return nil
405
408
}
406
- func (e * blockTokenHandler ) OnEndTagToken (token xhtml .Token , blockClosing bool ) {
409
+ func (e * blockTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {
407
410
if ! blockClosing {
408
411
return
409
412
}
@@ -417,34 +420,34 @@ func (e *blockTokenHandler) OnEndTagToken(token xhtml.Token, blockClosing bool)
417
420
e .strBuilder .Reset ()
418
421
}
419
422
420
- func (e * blockTokenHandler ) OnTextTagToken (token xhtml. Token ) {
423
+ func (e * blockTokenHandler ) OnTextTagToken (token xml. CharData ) {
421
424
if e .newlineBeforeNextBlock {
422
425
e .w .WriteString ("\n " )
423
426
e .newlineBeforeNextBlock = false
424
427
}
425
428
if ! e .started {
426
- token . Data = strings .TrimLeft (token . Data , " \t \n " )
429
+ token = xml . CharData ( strings .TrimLeft (string ( token ) , " \t \n " ) )
427
430
}
428
- if len (token . Data ) != 0 {
431
+ if len (token ) != 0 {
429
432
e .started = true
430
433
}
431
434
e .baseTokenHandler .OnTextTagToken (token )
432
435
}
433
436
434
437
type linkTokenHandler struct {
435
438
baseTokenHandler
436
- linkToken xhtml. Token
439
+ linkToken xml. StartElement
437
440
}
438
441
439
- func newLinkTokenHandler (w stringWriter , token xhtml. Token ) * linkTokenHandler {
442
+ func newLinkTokenHandler (w stringWriter , token xml. StartElement ) * linkTokenHandler {
440
443
return & linkTokenHandler {
441
444
baseTokenHandler : baseTokenHandler {
442
445
w : w ,
443
446
},
444
447
linkToken : token ,
445
448
}
446
449
}
447
- func (e * linkTokenHandler ) OnEndTagToken (token xhtml .Token , blockClosing bool ) {
450
+ func (e * linkTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {
448
451
if ! blockClosing {
449
452
return
450
453
}
@@ -467,9 +470,9 @@ func newListTokenHandler(w stringWriter) *listTokenHandler {
467
470
},
468
471
}
469
472
}
470
- func (e * listTokenHandler ) OnStartTagToken (token xhtml. Token ) htmlTokenHandler {
471
- switch token .DataAtom {
472
- case atom . Li :
473
+ func (e * listTokenHandler ) OnStartTagToken (token xml. StartElement ) htmlTokenHandler {
474
+ switch token .Name . Local {
475
+ case "li" :
473
476
if e .items >= 1 {
474
477
e .w .WriteString ("\n \n " )
475
478
}
@@ -479,7 +482,7 @@ func (e *listTokenHandler) OnStartTagToken(token xhtml.Token) htmlTokenHandler {
479
482
return nil
480
483
}
481
484
482
- func (e * listTokenHandler ) OnTextTagToken (token xhtml. Token ) {
485
+ func (e * listTokenHandler ) OnTextTagToken (token xml. CharData ) {
483
486
// Squash whitespace between list and items
484
487
}
485
488
@@ -500,14 +503,14 @@ func newListItemTokenHandler(w stringWriter) *listItemTokenHandler {
500
503
},
501
504
}
502
505
}
503
- func (e * listItemTokenHandler ) OnStartTagToken (token xhtml. Token ) htmlTokenHandler {
504
- switch token .DataAtom {
505
- case atom . P :
506
+ func (e * listItemTokenHandler ) OnStartTagToken (token xml. StartElement ) htmlTokenHandler {
507
+ switch token .Name . Local {
508
+ case "p" :
506
509
return newBlockTokenHandler (e .w )
507
510
}
508
511
return nil
509
512
}
510
- func (e * listItemTokenHandler ) OnEndTagToken (token xhtml .Token , blockClosing bool ) {
513
+ func (e * listItemTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {
511
514
if ! blockClosing {
512
515
return
513
516
}
@@ -533,18 +536,18 @@ func newTrimSpaceTokenHandler(w stringWriter) *trimSpaceTokenHandler {
533
536
},
534
537
}
535
538
}
536
- func (e * trimSpaceTokenHandler ) OnEndTagToken (token xhtml .Token , blockClosing bool ) {
539
+ func (e * trimSpaceTokenHandler ) OnEndTagToken (token xml .Token , blockClosing bool ) {
537
540
if ! blockClosing {
538
541
return
539
542
}
540
543
541
544
e .origWriter .WriteString (strings .TrimSpace (e .strBuilder .String ()))
542
545
}
543
546
544
- func getHTMLTokenAttr (attr []xhtml. Attribute , name string ) (string , bool ) {
547
+ func getHTMLTokenAttr (attr []xml. Attr , name string ) (string , bool ) {
545
548
for _ , a := range attr {
546
- if strings .EqualFold (a .Key , name ) {
547
- return a .Val , true
549
+ if strings .EqualFold (a .Name . Local , name ) {
550
+ return a .Value , true
548
551
}
549
552
}
550
553
return "" , false
0 commit comments