diff --git a/go.mod b/go.mod index 3844230..8944643 100644 --- a/go.mod +++ b/go.mod @@ -6,25 +6,22 @@ require ( github.com/anthonynsimon/bild v0.13.0 github.com/fatih/color v1.16.0 github.com/stretchr/powerwalk v0.0.0-20151124150408-bceb9d014549 - github.com/urfave/cli v1.22.5 - github.com/xyproto/env/v2 v2.2.4 + github.com/urfave/cli v1.22.14 + github.com/xyproto/env/v2 v2.2.5 github.com/xyproto/heic v1.0.0 ) require ( - github.com/antchfx/xmlquery v1.3.8 // indirect - github.com/antchfx/xpath v1.2.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect + github.com/antchfx/xmlquery v1.3.18 // indirect + github.com/antchfx/xpath v1.2.5 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/russross/blackfriday/v2 v2.0.1 // indirect - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect - github.com/stretchr/testify v1.4.0 // indirect - golang.org/x/image v0.13.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.13.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - howett.net/plist v0.0.0-20201203080718-1454fab16a06 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + golang.org/x/image v0.15.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/text v0.14.0 // indirect + howett.net/plist v1.0.1 // indirect ) diff --git a/go.sum b/go.sum index 1abe28b..d6f3e64 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,12 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/antchfx/xmlquery v1.3.8 h1:dRnBQM3Vk5BVJFvFwsHOLAox+mEiNw5ZusaUNCrEdoU= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/antchfx/xmlquery v1.3.8/go.mod h1:wojC/BxjEkjJt6dPiAqUzoXO5nIMWtxHS8PD8TmN4ks= -github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8= +github.com/antchfx/xmlquery v1.3.18 h1:FSQ3wMuphnPPGJOFhvc+cRQ2CT/rUj4cyQXkJcjOwz0= +github.com/antchfx/xmlquery v1.3.18/go.mod h1:Afkq4JIeXut75taLSuI31ISJ/zeq+3jG7TunF7noreA= github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= +github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= +github.com/antchfx/xpath v1.2.5 h1:hqZ+wtQ+KIOV/S3bGZcIhpgYC26um2bZYP2KVGcR7VY= +github.com/antchfx/xpath v1.2.5/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= github.com/anthonynsimon/bild v0.13.0 h1:mN3tMaNds1wBWi1BrJq0ipDBhpkooYfu7ZFSMhXt1C8= github.com/anthonynsimon/bild v0.13.0/go.mod h1:tpzzp0aYkAsMi1zmfhimaDyX1xjn2OUc1AJZK/TF0AE= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -11,9 +15,9 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -47,10 +51,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -58,17 +60,21 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/powerwalk v0.0.0-20151124150408-bceb9d014549 h1:zjTKDjwZy1IVyLos+s70iYMwL/ZVojUbIDX5kghHa1Q= github.com/stretchr/powerwalk v0.0.0-20151124150408-bceb9d014549/go.mod h1:RhJzAYfVBD/ULOCeUUaTn0CHDRQBYHjDY7yYpSt6+4M= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= -github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= +github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xyproto/env/v2 v2.2.4 h1:Eysqz8rlZRBjKwH0a+oxyFj4WMDBaezKNHLx2S5f8go= -github.com/xyproto/env/v2 v2.2.4/go.mod h1:F81ZEzu15s3TWUZJ1uzBl9iNeq9zcfHvxMkQJaLZUl0= +github.com/xyproto/env/v2 v2.2.5 h1:FNrp56sptc7ebC2QpM8lqKSGEb3UoYUJZZFl4bmcrPs= +github.com/xyproto/env/v2 v2.2.5/go.mod h1:F81ZEzu15s3TWUZJ1uzBl9iNeq9zcfHvxMkQJaLZUl0= github.com/xyproto/heic v1.0.0 h1:42G/y7vACJbMvMfZmT7RmD9tbNixpLJ3Fc8zXOm6N7E= github.com/xyproto/heic v1.0.0/go.mod h1:L/7tNatbi076v65zr94V5vGy96T9RusaMfjCS0dFQiU= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -76,10 +82,10 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg= -golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk= +golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= +golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -89,9 +95,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20211111160137-58aab5ef257a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -110,22 +117,22 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -133,9 +140,13 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -howett.net/plist v0.0.0-20201203080718-1454fab16a06 h1:QDxUo/w2COstK1wIBYpzQlHX/NqaQTcf9jyz347nI58= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= howett.net/plist v0.0.0-20201203080718-1454fab16a06/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= +howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= +howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= diff --git a/vendor/github.com/antchfx/xmlquery/README.md b/vendor/github.com/antchfx/xmlquery/README.md index bae7fc3..11fafde 100644 --- a/vendor/github.com/antchfx/xmlquery/README.md +++ b/vendor/github.com/antchfx/xmlquery/README.md @@ -15,26 +15,13 @@ data or evaluate from XML documents with an XPath expression. XPATH query strings. Enabling caching can avoid recompile XPath expression for each query. -Change Logs -=== - -2020-08-?? -- Add XML stream loading and parsing support. +You can visit this page to learn about the supported XPath(1.0/2.0) syntax. https://github.com/antchfx/xpath -2019-11-11 -- Add XPath query caching. +[htmlquery](https://github.com/antchfx/htmlquery) - Package for the HTML document query. -2019-10-05 -- Add new methods compatible with invalid XPath expression error: `QueryAll` and `Query`. -- Add `QuerySelector` and `QuerySelectorAll` methods, support for reused query objects. -- PR [#12](https://github.com/antchfx/xmlquery/pull/12) (Thanks @FrancescoIlario) -- PR [#11](https://github.com/antchfx/xmlquery/pull/11) (Thanks @gjvnq) +[xmlquery](https://github.com/antchfx/xmlquery) - Package for the XML document query. -2018-12-23 -- Added XML output including comment nodes. [#9](https://github.com/antchfx/xmlquery/issues/9) - -2018-12-03 -- Added support to attribute name with namespace prefix and XML output. [#6](https://github.com/antchfx/xmlquery/issues/6) +[jsonquery](https://github.com/antchfx/jsonquery) - Package for the JSON document query. Installation ==== @@ -42,6 +29,52 @@ Installation $ go get github.com/antchfx/xmlquery ``` + +Quick Starts +=== + +```go +import ( + "github.com/antchfx/xmlquery" +) + +func main(){ + s := ` + + + W3Schools Home Page + https://www.w3schools.com + Free web building tutorials + + RSS Tutorial + https://www.w3schools.com/xml/xml_rss.asp + New RSS tutorial on W3Schools + + + XML Tutorial + https://www.w3schools.com/xml + New XML tutorial on W3Schools + + +` + + doc, err := xmlquery.Parse(strings.NewReader(s)) + if err != nil { + panic(err) + } + channel := xmlquery.FindOne(doc, "//channel") + if n := channel.SelectElement("title"); n != nil { + fmt.Printf("title: %s\n", n.InnerText()) + } + if n := channel.SelectElement("link"); n != nil { + fmt.Printf("link: %s\n", n.InnerText()) + } + for i, n := range xmlquery.Find(doc, "//item/title") { + fmt.Printf("#%d %s\n", i, n.InnerText()) + } +} +``` + Getting Started === @@ -77,7 +110,7 @@ doc, err := xmlquery.Parse(f) #### Parse an XML in a stream fashion (simple case without elements filtering). ```go -f, err := os.Open("../books.xml") +f, _ := os.Open("../books.xml") p, err := xmlquery.CreateStreamParser(f, "/bookstore/book") for { n, err := p.Read() @@ -85,15 +118,18 @@ for { break } if err != nil { - ... + panic(err) } + fmt.Println(n) } ``` +Notes: `CreateStreamParser()` used for saving memory if your had a large XML file to parse. + #### Parse an XML in a stream fashion (simple case advanced element filtering). ```go -f, err := os.Open("../books.xml") +f, _ := os.Open("../books.xml") p, err := xmlquery.CreateStreamParser(f, "/bookstore/book", "/bookstore/book[price>=10]") for { n, err := p.Read() @@ -101,8 +137,9 @@ for { break } if err != nil { - ... + panic(err) } + fmt.Println(n) } ``` @@ -153,24 +190,49 @@ expr, err := xpath.Compile("count(//book)") price := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64) ``` -FAQ +Advanced Features ==== -#### `Find()` vs `QueryAll()`, which is better? - -`Find` and `QueryAll` both do the same thing: searches all of matched XML nodes. -`Find` panics if provided with an invalid XPath query, while `QueryAll` returns -an error. +### Parse `UTF-16` XML file with `ParseWithOptions()`. -#### Can I save my query expression object for the next query? +```go +f, _ := os.Open(`UTF-16.XML`) +// Convert UTF-16 XML to UTF-8 +utf16ToUtf8Transformer := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewDecoder() +utf8Reader := transform.NewReader(f, utf16ToUtf8Transformer) +// Sets `CharsetReader` +options := xmlquery.ParserOptions{ + Decoder: &xmlquery.DecoderOptions{ + CharsetReader: func(charset string, input io.Reader) (io.Reader, error) { + return input, nil + }, + }, +} +doc, err := xmlquery.ParseWithOptions(utf8Reader, options) +``` -Yes, you can. We provide `QuerySelector` and `QuerySelectorAll` methods; they -accept your query expression object. +### Query with custom namespace prefix. -Caching a query expression object avoids recompiling the XPath query -expression, improving query performance. +```go +s := ` + + +RequestReplyActivity +OpClientReqActivity +300 +80 + +` +nsMap := map[string]string{ + "q": "http://xmlns.xyz.com/process/2003", + "r": "http://www.w3.org/1999/XSL/Transform", + "s": "http://www.w3.org/2001/XMLSchema", +} +expr, _ := xpath.CompileWithNS("//q:activity", nsMap) +node := xmlquery.QuerySelector(doc, expr) +``` -#### Create XML document. +#### Create XML document without call `xml.Marshal`. ```go doc := &xmlquery.Node{ @@ -200,63 +262,34 @@ title_text := &xmlquery.Node{ } title.FirstChild = title_text channel.FirstChild = title + fmt.Println(doc.OutputXML(true)) -// W3Schools Home Page +fmt.Println(doc.OutputXMLWithOptions(WithOutputSelf())) ``` -Quick Tutorial -=== +Output: -```go -import ( - "github.com/antchfx/xmlquery" -) +```xml +W3Schools Home Page +``` -func main(){ - s := ` - - - W3Schools Home Page - https://www.w3schools.com - Free web building tutorials - - RSS Tutorial - https://www.w3schools.com/xml/xml_rss.asp - New RSS tutorial on W3Schools - - - XML Tutorial - https://www.w3schools.com/xml - New XML tutorial on W3Schools - - -` +FAQ +==== - doc, err := xmlquery.Parse(strings.NewReader(s)) - if err != nil { - panic(err) - } - channel := xmlquery.FindOne(doc, "//channel") - if n := channel.SelectElement("title"); n != nil { - fmt.Printf("title: %s\n", n.InnerText()) - } - if n := channel.SelectElement("link"); n != nil { - fmt.Printf("link: %s\n", n.InnerText()) - } - for i, n := range xmlquery.Find(doc, "//item/title") { - fmt.Printf("#%d %s\n", i, n.InnerText()) - } -} -``` +#### `Find()` vs `QueryAll()`, which is better? -List of supported XPath query packages -=== -| Name | Description | -| ------------------------------------------------- | ----------------------------------------- | -| [htmlquery](https://github.com/antchfx/htmlquery) | XPath query package for HTML documents | -| [xmlquery](https://github.com/antchfx/xmlquery) | XPath query package for XML documents | -| [jsonquery](https://github.com/antchfx/jsonquery) | XPath query package for JSON documents | +`Find` and `QueryAll` both do the same thing: searches all of matched XML nodes. +`Find` panics if provided with an invalid XPath query, while `QueryAll` returns +an error. + +#### Can I save my query expression object for the next query? + +Yes, you can. We provide `QuerySelector` and `QuerySelectorAll` methods; they +accept your query expression object. + +Caching a query expression object avoids recompiling the XPath query +expression, improving query performance. - Questions +Questions === Please let me know if you have any questions diff --git a/vendor/github.com/antchfx/xmlquery/node.go b/vendor/github.com/antchfx/xmlquery/node.go index be6e31a..207892a 100644 --- a/vendor/github.com/antchfx/xmlquery/node.go +++ b/vendor/github.com/antchfx/xmlquery/node.go @@ -1,9 +1,9 @@ package xmlquery import ( - "bytes" "encoding/xml" "fmt" + "html" "strings" ) @@ -49,24 +49,74 @@ type Node struct { level int // node level in the tree } +type outputConfiguration struct { + printSelf bool + preserveSpaces bool + emptyElementTagSupport bool + skipComments bool +} + +type OutputOption func(*outputConfiguration) + +// WithOutputSelf configures the Node to print the root node itself +func WithOutputSelf() OutputOption { + return func(oc *outputConfiguration) { + oc.printSelf = true + } +} + +// WithEmptyTagSupport empty tags should be written as and +// not as +func WithEmptyTagSupport() OutputOption { + return func(oc *outputConfiguration) { + oc.emptyElementTagSupport = true + } +} + +// WithoutComments will skip comments in output +func WithoutComments() OutputOption { + return func(oc *outputConfiguration) { + oc.skipComments = true + } +} + +// WithPreserveSpace will preserve spaces in output +func WithPreserveSpace() OutputOption { + return func(oc *outputConfiguration) { + oc.preserveSpaces = true + } +} + +func newXMLName(name string) xml.Name { + if i := strings.IndexByte(name, ':'); i > 0 { + return xml.Name{ + Space: name[:i], + Local: name[i+1:], + } + } + return xml.Name{ + Local: name, + } +} + // InnerText returns the text between the start and end tags of the object. func (n *Node) InnerText() string { - var output func(*bytes.Buffer, *Node) - output = func(buf *bytes.Buffer, n *Node) { + var output func(*strings.Builder, *Node) + output = func(b *strings.Builder, n *Node) { switch n.Type { case TextNode, CharDataNode: - buf.WriteString(n.Data) + b.WriteString(n.Data) case CommentNode: default: for child := n.FirstChild; child != nil; child = child.NextSibling { - output(buf, child) + output(b, child) } } } - var buf bytes.Buffer - output(&buf, n) - return buf.String() + var b strings.Builder + output(&b, n) + return b.String() } func (n *Node) sanitizedData(preserveSpaces bool) string { @@ -85,92 +135,141 @@ func calculatePreserveSpaces(n *Node, pastValue bool) bool { return pastValue } -func outputXML(buf *bytes.Buffer, n *Node, preserveSpaces bool) { +func outputXML(b *strings.Builder, n *Node, preserveSpaces bool, config *outputConfiguration) { preserveSpaces = calculatePreserveSpaces(n, preserveSpaces) switch n.Type { case TextNode: - xml.EscapeText(buf, []byte(n.sanitizedData(preserveSpaces))) + b.WriteString(html.EscapeString(n.sanitizedData(preserveSpaces))) return case CharDataNode: - buf.WriteString("") + b.WriteString("") return case CommentNode: - buf.WriteString("") + if !config.skipComments { + b.WriteString("") + } return case DeclarationNode: - buf.WriteString("") + b.WriteString("?>") } else { - buf.WriteString(">") + if n.FirstChild != nil || !config.emptyElementTagSupport { + b.WriteString(">") + } else { + b.WriteString("/>") + return + } } for child := n.FirstChild; child != nil; child = child.NextSibling { - outputXML(buf, child, preserveSpaces) + outputXML(b, child, preserveSpaces, config) } if n.Type != DeclarationNode { if n.Prefix == "" { - buf.WriteString(fmt.Sprintf("", n.Data)) + fmt.Fprintf(b, "", n.Data) } else { - buf.WriteString(fmt.Sprintf("", n.Prefix, n.Data)) + fmt.Fprintf(b, "", n.Prefix, n.Data) } } } // OutputXML returns the text that including tags name. func (n *Node) OutputXML(self bool) string { + + config := &outputConfiguration{ + printSelf: true, + emptyElementTagSupport: false, + } preserveSpaces := calculatePreserveSpaces(n, false) - var buf bytes.Buffer - if self { - outputXML(&buf, n, preserveSpaces) + var b strings.Builder + if self && n.Type != DocumentNode { + outputXML(&b, n, preserveSpaces, config) } else { for n := n.FirstChild; n != nil; n = n.NextSibling { - outputXML(&buf, n, preserveSpaces) + outputXML(&b, n, preserveSpaces, config) } } - return buf.String() + return b.String() } -// AddAttr adds a new attribute specified by 'key' and 'val' to a node 'n'. -func AddAttr(n *Node, key, val string) { - var attr Attr - if i := strings.Index(key, ":"); i > 0 { - attr = Attr{ - Name: xml.Name{Space: key[:i], Local: key[i+1:]}, - Value: val, - } +// OutputXMLWithOptions returns the text that including tags name. +func (n *Node) OutputXMLWithOptions(opts ...OutputOption) string { + + config := &outputConfiguration{} + // Set the options + for _, opt := range opts { + opt(config) + } + pastPreserveSpaces := config.preserveSpaces + preserveSpaces := calculatePreserveSpaces(n, pastPreserveSpaces) + var b strings.Builder + if config.printSelf && n.Type != DocumentNode { + outputXML(&b, n, preserveSpaces, config) } else { - attr = Attr{ - Name: xml.Name{Local: key}, - Value: val, + for n := n.FirstChild; n != nil; n = n.NextSibling { + outputXML(&b, n, preserveSpaces, config) } } + return b.String() +} + +// AddAttr adds a new attribute specified by 'key' and 'val' to a node 'n'. +func AddAttr(n *Node, key, val string) { + attr := Attr{ + Name: newXMLName(key), + Value: val, + } n.Attr = append(n.Attr, attr) } +// SetAttr allows an attribute value with the specified name to be changed. +// If the attribute did not previously exist, it will be created. +func (n *Node) SetAttr(key, value string) { + name := newXMLName(key) + for i, attr := range n.Attr { + if attr.Name == name { + n.Attr[i].Value = value + return + } + } + AddAttr(n, key, value) +} + +// RemoveAttr removes the attribute with the specified name. +func (n *Node) RemoveAttr(key string) { + name := newXMLName(key) + for i, attr := range n.Attr { + if attr.Name == name { + n.Attr = append(n.Attr[:i], n.Attr[i+1:]...) + return + } + } +} + // AddChild adds a new node 'n' to a node 'parent' as its last child. func AddChild(parent, n *Node) { n.Parent = parent diff --git a/vendor/github.com/antchfx/xmlquery/options.go b/vendor/github.com/antchfx/xmlquery/options.go index f3e2f99..6b902d2 100644 --- a/vendor/github.com/antchfx/xmlquery/options.go +++ b/vendor/github.com/antchfx/xmlquery/options.go @@ -2,9 +2,10 @@ package xmlquery import ( "encoding/xml" + "io" ) -type ParserOptions struct{ +type ParserOptions struct { Decoder *DecoderOptions } @@ -17,14 +18,16 @@ func (options ParserOptions) apply(parser *parser) { // DecoderOptions implement the very same options than the standard // encoding/xml package. Please refer to this documentation: // https://golang.org/pkg/encoding/xml/#Decoder -type DecoderOptions struct{ - Strict bool - AutoClose []string - Entity map[string]string +type DecoderOptions struct { + Strict bool + AutoClose []string + Entity map[string]string + CharsetReader func(charset string, input io.Reader) (io.Reader, error) } func (options DecoderOptions) apply(decoder *xml.Decoder) { decoder.Strict = options.Strict decoder.AutoClose = options.AutoClose decoder.Entity = options.Entity + decoder.CharsetReader = options.CharsetReader } diff --git a/vendor/github.com/antchfx/xmlquery/parse.go b/vendor/github.com/antchfx/xmlquery/parse.go index 810eb73..fe3de99 100644 --- a/vendor/github.com/antchfx/xmlquery/parse.go +++ b/vendor/github.com/antchfx/xmlquery/parse.go @@ -3,7 +3,6 @@ package xmlquery import ( "bufio" "encoding/xml" - "errors" "fmt" "io" "net/http" @@ -53,7 +52,6 @@ func ParseWithOptions(r io.Reader, options ParserOptions) (*Node, error) { type parser struct { decoder *xml.Decoder doc *Node - space2prefix map[string]string level int prev *Node streamElementXPath *xpath.Expr // Under streaming mode, this specifies the xpath to the target element node(s). @@ -66,24 +64,26 @@ type parser struct { func createParser(r io.Reader) *parser { reader := newCachedReader(bufio.NewReader(r)) p := &parser{ - decoder: xml.NewDecoder(reader), - doc: &Node{Type: DocumentNode}, - space2prefix: make(map[string]string), - level: 0, - reader: reader, + decoder: xml.NewDecoder(reader), + doc: &Node{Type: DocumentNode}, + level: 0, + reader: reader, + } + if p.decoder.CharsetReader == nil { + p.decoder.CharsetReader = charset.NewReaderLabel } - // http://www.w3.org/XML/1998/namespace is bound by definition to the prefix xml. - p.space2prefix["http://www.w3.org/XML/1998/namespace"] = "xml" - p.decoder.CharsetReader = charset.NewReaderLabel p.prev = p.doc return p } func (p *parser) parse() (*Node, error) { var streamElementNodeCounter int + space2prefix := map[string]string{"http://www.w3.org/XML/1998/namespace": "xml"} for { + p.reader.StartCaching() tok, err := p.decoder.Token() + p.reader.StopCaching() if err != nil { return nil, err } @@ -92,30 +92,40 @@ func (p *parser) parse() (*Node, error) { case xml.StartElement: if p.level == 0 { // mising XML declaration - node := &Node{Type: DeclarationNode, Data: "xml", level: 1} + attributes := make([]Attr, 1) + attributes[0].Name = xml.Name{Local: "version"} + attributes[0].Value = "1.0" + node := &Node{ + Type: DeclarationNode, + Data: "xml", + Attr: attributes, + level: 1, + } AddChild(p.prev, node) p.level = 1 p.prev = node } - // https://www.w3.org/TR/xml-names/#scoping-defaulting + for _, att := range tok.Attr { if att.Name.Local == "xmlns" { - p.space2prefix[att.Value] = "" + space2prefix[att.Value] = "" // reset empty if exist the default namespace + // defaultNamespaceURL = att.Value } else if att.Name.Space == "xmlns" { - p.space2prefix[att.Value] = att.Name.Local + // maybe there are have duplicate NamespaceURL? + space2prefix[att.Value] = att.Name.Local } } - if tok.Name.Space != "" { - if _, found := p.space2prefix[tok.Name.Space]; !found { - return nil, errors.New("xmlquery: invalid XML document, namespace is missing") + if space := tok.Name.Space; space != "" { + if _, found := space2prefix[space]; !found && p.decoder.Strict { + return nil, fmt.Errorf("xmlquery: invalid XML document, namespace %s is missing", space) } } attributes := make([]Attr, len(tok.Attr)) for i, att := range tok.Attr { name := att.Name - if prefix, ok := p.space2prefix[name.Space]; ok { + if prefix, ok := space2prefix[name.Space]; ok { name.Space = prefix } attributes[i] = Attr{ @@ -128,7 +138,6 @@ func (p *parser) parse() (*Node, error) { node := &Node{ Type: ElementNode, Data: tok.Name.Local, - Prefix: p.space2prefix[tok.Name.Space], NamespaceURI: tok.Name.Space, Attr: attributes, level: p.level, @@ -144,6 +153,15 @@ func (p *parser) parse() (*Node, error) { } AddSibling(p.prev.Parent, node) } + + if node.NamespaceURI != "" { + if v, ok := space2prefix[node.NamespaceURI]; ok { + cached := string(p.reader.Cache()) + if strings.HasPrefix(cached, fmt.Sprintf("%s:%s", v, node.Data)) || strings.HasPrefix(cached, fmt.Sprintf("<%s:%s", v, node.Data)) { + node.Prefix = v + } + } + } // If we're in the streaming mode, we need to remember the node if it is the target node // so that when we finish processing the node's EndElement, we know how/what to return to // caller. Also we need to remove the target node from the tree upon next Read() call so @@ -161,7 +179,6 @@ func (p *parser) parse() (*Node, error) { } p.prev = node p.level++ - p.reader.StartCaching() case xml.EndElement: p.level-- // If we're in streaming mode, and we already have a potential streaming @@ -198,11 +215,10 @@ func (p *parser) parse() (*Node, error) { } } case xml.CharData: - p.reader.StopCaching() // First, normalize the cache... cached := strings.ToUpper(string(p.reader.Cache())) nodeType := TextNode - if strings.HasPrefix(cached, " p.prev.level { AddChild(p.prev, node) + } else if p.level < p.prev.level { + for i := p.prev.level - p.level; i > 1; i-- { + p.prev = p.prev.Parent + } + AddSibling(p.prev.Parent, node) } p.prev = node case xml.Directive: @@ -307,7 +327,7 @@ type StreamParser struct { // streamElementFilter, if provided, cannot be successfully parsed and compiled // into a valid xpath query. func CreateStreamParser(r io.Reader, streamElementXPath string, streamElementFilter ...string) (*StreamParser, error) { - return CreateStreamParserWithOptions(r, ParserOptions{}, streamElementXPath, streamElementFilter...) + return CreateStreamParserWithOptions(r, ParserOptions{}, streamElementXPath, streamElementFilter...) } // CreateStreamParserWithOptions is like CreateStreamParser, but with custom options diff --git a/vendor/github.com/antchfx/xmlquery/query.go b/vendor/github.com/antchfx/xmlquery/query.go index 0bd45dd..9f2493f 100644 --- a/vendor/github.com/antchfx/xmlquery/query.go +++ b/vendor/github.com/antchfx/xmlquery/query.go @@ -28,14 +28,9 @@ func (n *Node) SelectAttr(name string) string { } return "" } - var local, space string - local = name - if i := strings.Index(name, ":"); i > 0 { - space = name[:i] - local = name[i+1:] - } + xmlName := newXMLName(name) for _, attr := range n.Attr { - if attr.Name.Local == local && attr.Name.Space == space { + if attr.Name == xmlName { return attr.Value } } diff --git a/vendor/github.com/antchfx/xpath/README.md b/vendor/github.com/antchfx/xpath/README.md index 9a58a9f..d1e3a3c 100644 --- a/vendor/github.com/antchfx/xpath/README.md +++ b/vendor/github.com/antchfx/xpath/README.md @@ -49,7 +49,7 @@ Supported Features - `a/b` : For each node matching a, add the nodes matching b to the result. -- `a//b` : For each node matching a, add the descendant nodes matching b to the result. +- `a//b` : For each node matching a, add the descendant nodes matching b to the result. - `//b` : Returns elements in the entire document matching b. @@ -57,8 +57,9 @@ Supported Features - `(a, b, c)` : Evaluates each of its operands and concatenates the resulting sequences, in order, into a single result sequence +- `(a/b)` : Selects all matches nodes as grouping set. -#### Node Axes +#### Node Axes - `child::*` : The child axis selects children of the current node. @@ -72,9 +73,9 @@ Supported Features - `preceding-sibling::*` : Selects nodes before the current node. -- `following::*` : Selects the first matching node following in document order, excluding descendants. +- `following::*` : Selects the first matching node following in document order, excluding descendants. -- `preceding::*` : Selects the first matching node preceding in document order, excluding ancestors. +- `preceding::*` : Selects the first matching node preceding in document order, excluding ancestors. - `parent::*` : Selects the parent if it matches. The '..' pattern from the core is equivalent to 'parent::node()'. @@ -150,6 +151,7 @@ Supported Features `round()`| ✓ | `starts-with()`| ✓ | `string()`| ✓ | +`string-join()`[^1]| ✓ | `string-length()`| ✓ | `substring()`| ✓ | `substring-after()`| ✓ | @@ -160,14 +162,4 @@ Supported Features `true()`| ✓ | `unparsed-entity-url()` | ✗ | -Changelogs -=== - -2019-03-19 -- optimize XPath `|` operation performance. [#33](https://github.com/antchfx/xpath/issues/33). Tips: suggest split into multiple subquery if you have a lot of `|` operations. - -2019-01-29 -- improvement `normalize-space` function. [#32](https://github.com/antchfx/xpath/issues/32) - -2018-12-07 -- supports XPath 2.0 Sequence expressions. [#30](https://github.com/antchfx/xpath/pull/30) by [@minherz](https://github.com/minherz). \ No newline at end of file +[^1]: XPath-2.0 expression \ No newline at end of file diff --git a/vendor/github.com/antchfx/xpath/build.go b/vendor/github.com/antchfx/xpath/build.go index 58d8f31..2977bbc 100644 --- a/vendor/github.com/antchfx/xpath/build.go +++ b/vendor/github.com/antchfx/xpath/build.go @@ -42,8 +42,14 @@ func axisPredicate(root *axisNode) func(NodeNavigator) bool { } nametest := root.LocalName != "" || root.Prefix != "" predicate := func(n NodeNavigator) bool { - if typ == n.NodeType() || typ == allNode || typ == TextNode { + if typ == n.NodeType() || typ == allNode { if nametest { + type namespaceURL interface { + NamespaceURL() string + } + if ns, ok := n.(namespaceURL); ok && root.hasNamespaceURI { + return root.LocalName == n.LocalName() && root.namespaceURI == ns.NamespaceURL() + } if root.LocalName == n.LocalName() && root.Prefix == n.Prefix() { return true } @@ -88,7 +94,10 @@ func (b *builder) processAxisNode(root *axisNode) (query, error) { } return v } - qyOutput = &descendantQuery{Input: qyGrandInput, Predicate: filter, Self: true} + // fix `//*[contains(@id,"food")]//*[contains(@id,"food")]`, see https://github.com/antchfx/htmlquery/issues/52 + // Skip the current node(Self:false) for the next descendants nodes. + _, ok := qyGrandInput.(*contextQuery) + qyOutput = &descendantQuery{Input: qyGrandInput, Predicate: filter, Self: ok} return qyOutput, nil } } @@ -209,6 +218,12 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) { if arg2, err = b.processNode(root.Args[1]); err != nil { return nil, err } + // Issue #92, testing the regular expression before. + if q, ok := arg2.(*constantQuery); ok { + if _, err = getRegexp(q.Val.(string)); err != nil { + return nil, fmt.Errorf("matches() got error. %v", err) + } + } qyOutput = &functionQuery{Input: b.firstInput, Func: matchesFunc(arg1, arg2)} case "substring": //substring( string , start [, length] ) @@ -347,7 +362,15 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) { }, } case "last": - qyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc} + switch typ := b.firstInput.(type) { + case *groupQuery, *filterQuery: + // https://github.com/antchfx/xpath/issues/76 + // https://github.com/antchfx/xpath/issues/78 + qyOutput = &lastQuery{Input: typ} + default: + qyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc} + } + case "position": qyOutput = &functionQuery{Input: b.firstInput, Func: positionFunc} case "boolean", "number", "string": @@ -433,6 +456,19 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) { return nil, err } qyOutput = &transformFunctionQuery{Input: argQuery, Func: reverseFunc} + case "string-join": + if len(root.Args) != 2 { + return nil, fmt.Errorf("xpath: string-join(node-sets, separator) function requires node-set and argument") + } + argQuery, err := b.processNode(root.Args[0]) + if err != nil { + return nil, err + } + arg1, err := b.processNode(root.Args[1]) + if err != nil { + return nil, err + } + qyOutput = &functionQuery{Input: argQuery, Func: stringJoinFunc(arg1)} default: return nil, fmt.Errorf("not yet support this function %s()", root.FuncName) } @@ -511,6 +547,7 @@ func (b *builder) processNode(root node) (q query, err error) { b.firstInput = q case nodeFilter: q, err = b.processFilterNode(root.(*filterNode)) + b.firstInput = q case nodeFunction: q, err = b.processFunctionNode(root.(*functionNode)) case nodeOperator: @@ -521,12 +558,13 @@ func (b *builder) processNode(root node) (q query, err error) { return } q = &groupQuery{Input: q} + b.firstInput = q } return } // build builds a specified XPath expressions expr. -func build(expr string) (q query, err error) { +func build(expr string, namespaces map[string]string) (q query, err error) { defer func() { if e := recover(); e != nil { switch x := e.(type) { @@ -539,7 +577,7 @@ func build(expr string) (q query, err error) { } } }() - root := parse(expr) + root := parse(expr, namespaces) b := &builder{} return b.processNode(root) } diff --git a/vendor/github.com/antchfx/xpath/func.go b/vendor/github.com/antchfx/xpath/func.go index fd4187b..4131bfd 100644 --- a/vendor/github.com/antchfx/xpath/func.go +++ b/vendor/github.com/antchfx/xpath/func.go @@ -122,17 +122,19 @@ func asNumber(t iterator, o interface{}) float64 { return typ case string: v, err := strconv.ParseFloat(typ, 64) - if err != nil { - panic(errors.New("ceiling() function argument type must be a node-set or number")) + if err == nil { + return v } - return v } - return 0 + return math.NaN() } // ceilingFunc is a XPath Node Set functions ceiling(node-set). func ceilingFunc(q query, t iterator) interface{} { val := asNumber(t, functionArgs(q).Evaluate(t)) + // if math.IsNaN(val) { + // panic(errors.New("ceiling() function argument type must be a valid number")) + // } return math.Ceil(val) } @@ -612,3 +614,34 @@ func reverseFunc(q query, t iterator) func() NodeNavigator { return node } } + +// string-join is a XPath Node Set functions string-join(node-set, separator). +func stringJoinFunc(arg1 query) func(query, iterator) interface{} { + return func(q query, t iterator) interface{} { + var separator string + switch v := functionArgs(arg1).Evaluate(t).(type) { + case string: + separator = v + case query: + node := v.Select(t) + if node != nil { + separator = node.Value() + } + } + + q = functionArgs(q) + test := predicate(q) + var parts []string + switch v := q.Evaluate(t).(type) { + case string: + return v + case query: + for node := v.Select(t); node != nil; node = v.Select(t) { + if test(node) { + parts = append(parts, node.Value()) + } + } + } + return strings.Join(parts, separator) + } +} diff --git a/vendor/github.com/antchfx/xpath/func_go110.go b/vendor/github.com/antchfx/xpath/func_go110.go index 6df30d3..d6ca451 100644 --- a/vendor/github.com/antchfx/xpath/func_go110.go +++ b/vendor/github.com/antchfx/xpath/func_go110.go @@ -11,6 +11,6 @@ func round(f float64) int { return int(math.Round(f)) } -func newStringBuilder() stringBuilder{ +func newStringBuilder() stringBuilder { return &strings.Builder{} } diff --git a/vendor/github.com/antchfx/xpath/operator.go b/vendor/github.com/antchfx/xpath/operator.go index 8c2f31f..eb38ac6 100644 --- a/vendor/github.com/antchfx/xpath/operator.go +++ b/vendor/github.com/antchfx/xpath/operator.go @@ -165,15 +165,28 @@ func cmpNodeSetString(t iterator, op string, m, n interface{}) bool { func cmpNodeSetNodeSet(t iterator, op string, m, n interface{}) bool { a := m.(query) b := n.(query) - x := a.Select(t) - if x == nil { - return false - } - y := b.Select(t) - if y == nil { - return false + for { + x := a.Select(t) + if x == nil { + return false + } + + y := b.Select(t) + if y == nil { + return false + } + + for { + if cmpStringStringF(op, x.Value(), y.Value()) { + return true + } + if y = b.Select(t); y == nil { + break + } + } + // reset + b.Evaluate(t) } - return cmpStringStringF(op, x.Value(), y.Value()) } func cmpStringNumeric(t iterator, op string, m, n interface{}) bool { diff --git a/vendor/github.com/antchfx/xpath/parse.go b/vendor/github.com/antchfx/xpath/parse.go index acb0db9..cbd289a 100644 --- a/vendor/github.com/antchfx/xpath/parse.go +++ b/vendor/github.com/antchfx/xpath/parse.go @@ -69,8 +69,9 @@ const ( ) type parser struct { - r *scanner - d int + r *scanner + d int + namespaces map[string]string } // newOperatorNode returns new operator node OperatorNode. @@ -84,8 +85,8 @@ func newOperandNode(v interface{}) node { } // newAxisNode returns new axis node AxisNode. -func newAxisNode(axeTyp, localName, prefix, prop string, n node) node { - return &axisNode{ +func newAxisNode(axeTyp, localName, prefix, prop string, n node, opts ...func(p *axisNode)) node { + a := axisNode{ nodeType: nodeAxis, LocalName: localName, Prefix: prefix, @@ -93,6 +94,10 @@ func newAxisNode(axeTyp, localName, prefix, prop string, n node) node { Prop: prop, Input: n, } + for _, o := range opts { + o(&a) + } + return &a } // newVariableNode returns new variable node VariableNode. @@ -469,7 +474,16 @@ func (p *parser) parseNodeTest(n node, axeTyp string) (opnd node) { if p.r.name == "*" { name = "" } - opnd = newAxisNode(axeTyp, name, prefix, "", n) + opnd = newAxisNode(axeTyp, name, prefix, "", n, func(a *axisNode) { + if prefix != "" && p.namespaces != nil { + if ns, ok := p.namespaces[prefix]; ok { + a.hasNamespaceURI = true + a.namespaceURI = ns + } else { + panic(fmt.Sprintf("prefix %s not defined.", prefix)) + } + } + }) } case itemStar: opnd = newAxisNode(axeTyp, "", "", "", n) @@ -531,11 +545,11 @@ func (p *parser) parseMethod(n node) node { } // Parse parsing the XPath express string expr and returns a tree node. -func parse(expr string) node { +func parse(expr string, namespaces map[string]string) node { r := &scanner{text: expr} r.nextChar() r.nextItem() - p := &parser{r: r} + p := &parser{r: r, namespaces: namespaces} return p.parseExpression(nil) } @@ -563,11 +577,13 @@ func (o *operatorNode) String() string { // axisNode holds a location step. type axisNode struct { nodeType - Input node - Prop string // node-test name.[comment|text|processing-instruction|node] - AxeType string // name of the axes.[attribute|ancestor|child|....] - LocalName string // local part name of node. - Prefix string // prefix name of node. + Input node + Prop string // node-test name.[comment|text|processing-instruction|node] + AxeType string // name of the axes.[attribute|ancestor|child|....] + LocalName string // local part name of node. + Prefix string // prefix name of node. + namespaceURI string // namespace URI of node + hasNamespaceURI bool // if namespace URI is set (can be "") } func (a *axisNode) String() string { diff --git a/vendor/github.com/antchfx/xpath/query.go b/vendor/github.com/antchfx/xpath/query.go index 6e99ce5..4e6c634 100644 --- a/vendor/github.com/antchfx/xpath/query.go +++ b/vendor/github.com/antchfx/xpath/query.go @@ -56,7 +56,7 @@ func (c *contextQuery) Evaluate(iterator) interface{} { } func (c *contextQuery) Clone() query { - return &contextQuery{count: 0, Root: c.Root} + return &contextQuery{Root: c.Root} } // ancestorQuery is an XPath ancestor node query.(ancestor::*|ancestor-self::*) @@ -558,8 +558,8 @@ func (f *filterQuery) do(t iterator) bool { pt := getNodePosition(f.Input) return int(val.Float()) == pt default: - if q, ok := f.Predicate.(query); ok { - return q.Select(t) != nil + if f.Predicate != nil { + return f.Predicate.Select(t) != nil } } return false @@ -577,7 +577,7 @@ func (f *filterQuery) Select(t iterator) NodeNavigator { node := f.Input.Select(t) if node == nil { - return node + return nil } node = node.Copy() @@ -676,14 +676,12 @@ type groupQuery struct { } func (g *groupQuery) Select(t iterator) NodeNavigator { - for { - node := g.Input.Select(t) - if node == nil { - return nil - } - g.posit++ - return node.Copy() + node := g.Input.Select(t) + if node == nil { + return nil } + g.posit++ + return node } func (g *groupQuery) Evaluate(t iterator) interface{} { @@ -691,7 +689,7 @@ func (g *groupQuery) Evaluate(t iterator) interface{} { } func (g *groupQuery) Clone() query { - return &groupQuery{Input: g.Input} + return &groupQuery{Input: g.Input.Clone()} } func (g *groupQuery) position() int { @@ -820,6 +818,8 @@ func (b *booleanQuery) Select(t iterator) NodeNavigator { } func (b *booleanQuery) Evaluate(t iterator) interface{} { + n := t.Current().Copy() + m := b.Left.Evaluate(t) left := asBool(t, m) if b.IsOr && left { @@ -827,6 +827,8 @@ func (b *booleanQuery) Evaluate(t iterator) interface{} { } else if !b.IsOr && !left { return false } + + t.Current().MoveTo(n) m = b.Right.Evaluate(t) return asBool(t, m) } @@ -892,6 +894,35 @@ func (u *unionQuery) Clone() query { return &unionQuery{Left: u.Left.Clone(), Right: u.Right.Clone()} } +type lastQuery struct { + buffer []NodeNavigator + counted bool + + Input query +} + +func (q *lastQuery) Select(t iterator) NodeNavigator { + return nil +} + +func (q *lastQuery) Evaluate(t iterator) interface{} { + if !q.counted { + for { + node := q.Input.Select(t) + if node == nil { + break + } + q.buffer = append(q.buffer, node.Copy()) + } + q.counted = true + } + return float64(len(q.buffer)) +} + +func (q *lastQuery) Clone() query { + return &lastQuery{Input: q.Input.Clone()} +} + func getHashCode(n NodeNavigator) uint64 { var sb bytes.Buffer switch n.NodeType() { diff --git a/vendor/github.com/antchfx/xpath/xpath.go b/vendor/github.com/antchfx/xpath/xpath.go index 5f6aa89..1c0a5a2 100644 --- a/vendor/github.com/antchfx/xpath/xpath.go +++ b/vendor/github.com/antchfx/xpath/xpath.go @@ -141,7 +141,7 @@ func Compile(expr string) (*Expr, error) { if expr == "" { return nil, errors.New("expr expression is nil") } - qy, err := build(expr) + qy, err := build(expr, nil) if err != nil { return nil, err } @@ -159,3 +159,18 @@ func MustCompile(expr string) *Expr { } return exp } + +// CompileWithNS compiles an XPath expression string, using given namespaces map. +func CompileWithNS(expr string, namespaces map[string]string) (*Expr, error) { + if expr == "" { + return nil, errors.New("expr expression is nil") + } + qy, err := build(expr, namespaces) + if err != nil { + return nil, err + } + if qy == nil { + return nil, fmt.Errorf(fmt.Sprintf("undeclared variable in XPath expression: %s", expr)) + } + return &Expr{s: expr, q: qy}, nil +} diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go index b480056..42bf32a 100644 --- a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go +++ b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go @@ -9,6 +9,8 @@ func Render(doc []byte) []byte { renderer := NewRoffRenderer() return blackfriday.Run(doc, - []blackfriday.Option{blackfriday.WithRenderer(renderer), - blackfriday.WithExtensions(renderer.GetExtensions())}...) + []blackfriday.Option{ + blackfriday.WithRenderer(renderer), + blackfriday.WithExtensions(renderer.GetExtensions()), + }...) } diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go index 0668a66..4b19188 100644 --- a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go +++ b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go @@ -1,6 +1,7 @@ package md2man import ( + "bytes" "fmt" "io" "os" @@ -15,7 +16,7 @@ type roffRenderer struct { extensions blackfriday.Extensions listCounters []int firstHeader bool - defineTerm bool + firstDD bool listDepth int } @@ -34,15 +35,16 @@ const ( hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n" linkTag = "\n\\[la]" linkCloseTag = "\\[ra]" - codespanTag = "\\fB\\fC" + codespanTag = "\\fB" codespanCloseTag = "\\fR" - codeTag = "\n.PP\n.RS\n\n.nf\n" - codeCloseTag = "\n.fi\n.RE\n" + codeTag = "\n.EX\n" + codeCloseTag = "\n.EE\n" quoteTag = "\n.PP\n.RS\n" quoteCloseTag = "\n.RE\n" listTag = "\n.RS\n" listCloseTag = "\n.RE\n" - arglistTag = "\n.TP\n" + dtTag = "\n.TP\n" + dd2Tag = "\n" tableStart = "\n.TS\nallbox;\n" tableEnd = ".TE\n" tableCellStart = "T{\n" @@ -85,12 +87,11 @@ func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) { // RenderNode is called for each node in a markdown document; based on the node // type the equivalent roff output is sent to the writer func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { - - var walkAction = blackfriday.GoToNext + walkAction := blackfriday.GoToNext switch node.Type { case blackfriday.Text: - r.handleText(w, node, entering) + escapeSpecialChars(w, node.Literal) case blackfriday.Softbreak: out(w, crTag) case blackfriday.Hardbreak: @@ -108,9 +109,16 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering out(w, strongCloseTag) } case blackfriday.Link: - if !entering { - out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag) + // Don't render the link text for automatic links, because this + // will only duplicate the URL in the roff output. + // See https://daringfireball.net/projects/markdown/syntax#autolink + if !bytes.Equal(node.LinkData.Destination, node.FirstChild.Literal) { + out(w, string(node.FirstChild.Literal)) } + // Hyphens in a link must be escaped to avoid word-wrap in the rendered man page. + escapedLink := strings.ReplaceAll(string(node.LinkData.Destination), "-", "\\-") + out(w, linkTag+escapedLink+linkCloseTag) + walkAction = blackfriday.SkipChildren case blackfriday.Image: // ignore images walkAction = blackfriday.SkipChildren @@ -150,40 +158,26 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering out(w, codeCloseTag) case blackfriday.Table: r.handleTable(w, node, entering) - case blackfriday.TableCell: - r.handleTableCell(w, node, entering) case blackfriday.TableHead: case blackfriday.TableBody: case blackfriday.TableRow: // no action as cell entries do all the nroff formatting return blackfriday.GoToNext + case blackfriday.TableCell: + r.handleTableCell(w, node, entering) + case blackfriday.HTMLSpan: + // ignore other HTML tags + case blackfriday.HTMLBlock: + if bytes.HasPrefix(node.Literal, []byte("