brewdoc-darwin-arm64 0.0.0-stage → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (570) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -2
  3. package/binary/_internal/PIL/.dylibs/libXau.6.dylib +0 -0
  4. package/binary/_internal/PIL/.dylibs/libavif.16.4.2.dylib +0 -0
  5. package/binary/_internal/PIL/.dylibs/libbrotlicommon.1.2.0.dylib +0 -0
  6. package/binary/_internal/PIL/.dylibs/libbrotlidec.1.2.0.dylib +0 -0
  7. package/binary/_internal/PIL/.dylibs/libfreetype.6.dylib +0 -0
  8. package/binary/_internal/PIL/.dylibs/libharfbuzz.0.dylib +0 -0
  9. package/binary/_internal/PIL/.dylibs/libjpeg.62.4.0.dylib +0 -0
  10. package/binary/_internal/PIL/.dylibs/liblcms2.2.dylib +0 -0
  11. package/binary/_internal/PIL/.dylibs/liblzma.5.dylib +0 -0
  12. package/binary/_internal/PIL/.dylibs/libopenjp2.2.5.4.dylib +0 -0
  13. package/binary/_internal/PIL/.dylibs/libpng16.16.dylib +0 -0
  14. package/binary/_internal/PIL/.dylibs/libsharpyuv.0.dylib +0 -0
  15. package/binary/_internal/PIL/.dylibs/libtiff.6.dylib +0 -0
  16. package/binary/_internal/PIL/.dylibs/libwebp.7.dylib +0 -0
  17. package/binary/_internal/PIL/.dylibs/libwebpdemux.2.dylib +0 -0
  18. package/binary/_internal/PIL/.dylibs/libwebpmux.3.dylib +0 -0
  19. package/binary/_internal/PIL/.dylibs/libxcb.1.1.0.dylib +0 -0
  20. package/binary/_internal/PIL/.dylibs/libz.1.3.1.zlib-ng.dylib +0 -0
  21. package/binary/_internal/PIL/_avif.cpython-312-darwin.so +0 -0
  22. package/binary/_internal/PIL/_imaging.cpython-312-darwin.so +0 -0
  23. package/binary/_internal/PIL/_imagingcms.cpython-312-darwin.so +0 -0
  24. package/binary/_internal/PIL/_imagingft.cpython-312-darwin.so +0 -0
  25. package/binary/_internal/PIL/_imagingmath.cpython-312-darwin.so +0 -0
  26. package/binary/_internal/PIL/_imagingtk.cpython-312-darwin.so +0 -0
  27. package/binary/_internal/PIL/_webp.cpython-312-darwin.so +0 -0
  28. package/binary/_internal/_cffi_backend.cpython-312-darwin.so +0 -0
  29. package/binary/_internal/_quickjs.abi3.so +0 -0
  30. package/binary/_internal/base_library.zip +0 -0
  31. package/binary/_internal/brewdoc/_urljs/glue.js +858 -0
  32. package/binary/_internal/brewdoc/_vendor/THIRD_PARTY_NOTICES.txt +342 -0
  33. package/binary/_internal/brewdoc/_vendor/linkedom-worker.js +12650 -0
  34. package/binary/_internal/brewdoc-0.3.2.dist-info/INSTALLER +1 -0
  35. package/binary/_internal/brewdoc-0.3.2.dist-info/METADATA +157 -0
  36. package/binary/_internal/brewdoc-0.3.2.dist-info/RECORD +30 -0
  37. package/binary/_internal/brewdoc-0.3.2.dist-info/REQUESTED +0 -0
  38. package/binary/_internal/brewdoc-0.3.2.dist-info/WHEEL +4 -0
  39. package/binary/_internal/brewdoc-0.3.2.dist-info/direct_url.json +1 -0
  40. package/binary/_internal/brewdoc-0.3.2.dist-info/entry_points.txt +2 -0
  41. package/binary/_internal/brewdoc-0.3.2.dist-info/licenses/LICENSE +21 -0
  42. package/binary/_internal/brewdoc-0.3.2.dist-info/uv_cache.json +1 -0
  43. package/binary/_internal/cffi-2.1.1.dist-info/INSTALLER +1 -0
  44. package/binary/_internal/cffi-2.1.1.dist-info/METADATA +67 -0
  45. package/binary/_internal/cffi-2.1.1.dist-info/RECORD +34 -0
  46. package/binary/_internal/cffi-2.1.1.dist-info/REQUESTED +0 -0
  47. package/binary/_internal/cffi-2.1.1.dist-info/WHEEL +6 -0
  48. package/binary/_internal/cffi-2.1.1.dist-info/entry_points.txt +5 -0
  49. package/binary/_internal/cffi-2.1.1.dist-info/licenses/LICENSE +23 -0
  50. package/binary/_internal/cffi-2.1.1.dist-info/top_level.txt +2 -0
  51. package/binary/_internal/charset_normalizer/cd.cpython-312-darwin.so +0 -0
  52. package/binary/_internal/charset_normalizer/md.cpython-312-darwin.so +0 -0
  53. package/binary/_internal/charset_normalizer-3.5.2.dist-info/INSTALLER +1 -0
  54. package/binary/_internal/charset_normalizer-3.5.2.dist-info/METADATA +892 -0
  55. package/binary/_internal/charset_normalizer-3.5.2.dist-info/RECORD +24 -0
  56. package/binary/_internal/charset_normalizer-3.5.2.dist-info/REQUESTED +0 -0
  57. package/binary/_internal/charset_normalizer-3.5.2.dist-info/WHEEL +6 -0
  58. package/binary/_internal/charset_normalizer-3.5.2.dist-info/entry_points.txt +2 -0
  59. package/binary/_internal/charset_normalizer-3.5.2.dist-info/licenses/LICENSE +21 -0
  60. package/binary/_internal/charset_normalizer-3.5.2.dist-info/top_level.txt +1 -0
  61. package/binary/_internal/cryptography/hazmat/bindings/_rust.abi3.so +0 -0
  62. package/binary/_internal/cryptography-50.0.2.dist-info/INSTALLER +1 -0
  63. package/binary/_internal/cryptography-50.0.2.dist-info/METADATA +111 -0
  64. package/binary/_internal/cryptography-50.0.2.dist-info/RECORD +122 -0
  65. package/binary/_internal/cryptography-50.0.2.dist-info/REQUESTED +0 -0
  66. package/binary/_internal/cryptography-50.0.2.dist-info/WHEEL +4 -0
  67. package/binary/_internal/cryptography-50.0.2.dist-info/licenses/LICENSE +3 -0
  68. package/binary/_internal/cryptography-50.0.2.dist-info/licenses/LICENSE.APACHE +202 -0
  69. package/binary/_internal/cryptography-50.0.2.dist-info/licenses/LICENSE.BSD +27 -0
  70. package/binary/_internal/cryptography-50.0.2.dist-info/sboms/cryptography-rust.cyclonedx.json +1365 -0
  71. package/binary/_internal/cryptography-50.0.2.dist-info/sboms/sbom.json +43 -0
  72. package/binary/_internal/libXau.6.dylib +0 -0
  73. package/binary/_internal/libavif.16.4.2.dylib +0 -0
  74. package/binary/_internal/libbrotlicommon.1.2.0.dylib +0 -0
  75. package/binary/_internal/libbrotlidec.1.2.0.dylib +0 -0
  76. package/binary/_internal/libfreetype.6.dylib +0 -0
  77. package/binary/_internal/libharfbuzz.0.dylib +0 -0
  78. package/binary/_internal/libjpeg.62.4.0.dylib +0 -0
  79. package/binary/_internal/liblcms2.2.dylib +0 -0
  80. package/binary/_internal/liblzma.5.dylib +0 -0
  81. package/binary/_internal/libopenjp2.2.5.4.dylib +0 -0
  82. package/binary/_internal/libpng16.16.dylib +0 -0
  83. package/binary/_internal/libpython3.12.dylib +0 -0
  84. package/binary/_internal/libsharpyuv.0.dylib +0 -0
  85. package/binary/_internal/libtiff.6.dylib +0 -0
  86. package/binary/_internal/libwebp.7.dylib +0 -0
  87. package/binary/_internal/libwebpdemux.2.dylib +0 -0
  88. package/binary/_internal/libwebpmux.3.dylib +0 -0
  89. package/binary/_internal/libxcb.1.1.0.dylib +0 -0
  90. package/binary/_internal/libz.1.3.1.zlib-ng.dylib +0 -0
  91. package/binary/_internal/pdfminer/cmap/78-EUC-H.json.gz +0 -0
  92. package/binary/_internal/pdfminer/cmap/78-EUC-V.json.gz +0 -0
  93. package/binary/_internal/pdfminer/cmap/78-H.json.gz +0 -0
  94. package/binary/_internal/pdfminer/cmap/78-RKSJ-H.json.gz +0 -0
  95. package/binary/_internal/pdfminer/cmap/78-RKSJ-V.json.gz +0 -0
  96. package/binary/_internal/pdfminer/cmap/78-V.json.gz +0 -0
  97. package/binary/_internal/pdfminer/cmap/78ms-RKSJ-H.json.gz +0 -0
  98. package/binary/_internal/pdfminer/cmap/78ms-RKSJ-V.json.gz +0 -0
  99. package/binary/_internal/pdfminer/cmap/83pv-RKSJ-H.json.gz +0 -0
  100. package/binary/_internal/pdfminer/cmap/83pv-RKSJ-V.json.gz +0 -0
  101. package/binary/_internal/pdfminer/cmap/90ms-RKSJ-H.json.gz +0 -0
  102. package/binary/_internal/pdfminer/cmap/90ms-RKSJ-V.json.gz +0 -0
  103. package/binary/_internal/pdfminer/cmap/90msp-RKSJ-H.json.gz +0 -0
  104. package/binary/_internal/pdfminer/cmap/90msp-RKSJ-V.json.gz +0 -0
  105. package/binary/_internal/pdfminer/cmap/90pv-RKSJ-H.json.gz +0 -0
  106. package/binary/_internal/pdfminer/cmap/90pv-RKSJ-V.json.gz +0 -0
  107. package/binary/_internal/pdfminer/cmap/Add-H.json.gz +0 -0
  108. package/binary/_internal/pdfminer/cmap/Add-RKSJ-H.json.gz +0 -0
  109. package/binary/_internal/pdfminer/cmap/Add-RKSJ-V.json.gz +0 -0
  110. package/binary/_internal/pdfminer/cmap/Add-V.json.gz +0 -0
  111. package/binary/_internal/pdfminer/cmap/B5-H.json.gz +0 -0
  112. package/binary/_internal/pdfminer/cmap/B5-V.json.gz +0 -0
  113. package/binary/_internal/pdfminer/cmap/B5pc-H.json.gz +0 -0
  114. package/binary/_internal/pdfminer/cmap/B5pc-V.json.gz +0 -0
  115. package/binary/_internal/pdfminer/cmap/CNS-EUC-H.json.gz +0 -0
  116. package/binary/_internal/pdfminer/cmap/CNS-EUC-V.json.gz +0 -0
  117. package/binary/_internal/pdfminer/cmap/CNS1-H.json.gz +0 -0
  118. package/binary/_internal/pdfminer/cmap/CNS1-V.json.gz +0 -0
  119. package/binary/_internal/pdfminer/cmap/CNS2-H.json.gz +0 -0
  120. package/binary/_internal/pdfminer/cmap/CNS2-V.json.gz +0 -0
  121. package/binary/_internal/pdfminer/cmap/ETHK-B5-H.json.gz +0 -0
  122. package/binary/_internal/pdfminer/cmap/ETHK-B5-V.json.gz +0 -0
  123. package/binary/_internal/pdfminer/cmap/ETen-B5-H.json.gz +0 -0
  124. package/binary/_internal/pdfminer/cmap/ETen-B5-V.json.gz +0 -0
  125. package/binary/_internal/pdfminer/cmap/ETenms-B5-H.json.gz +0 -0
  126. package/binary/_internal/pdfminer/cmap/ETenms-B5-V.json.gz +0 -0
  127. package/binary/_internal/pdfminer/cmap/EUC-H.json.gz +0 -0
  128. package/binary/_internal/pdfminer/cmap/EUC-V.json.gz +0 -0
  129. package/binary/_internal/pdfminer/cmap/Ext-H.json.gz +0 -0
  130. package/binary/_internal/pdfminer/cmap/Ext-RKSJ-H.json.gz +0 -0
  131. package/binary/_internal/pdfminer/cmap/Ext-RKSJ-V.json.gz +0 -0
  132. package/binary/_internal/pdfminer/cmap/Ext-V.json.gz +0 -0
  133. package/binary/_internal/pdfminer/cmap/GB-EUC-H.json.gz +0 -0
  134. package/binary/_internal/pdfminer/cmap/GB-EUC-V.json.gz +0 -0
  135. package/binary/_internal/pdfminer/cmap/GB-H.json.gz +0 -0
  136. package/binary/_internal/pdfminer/cmap/GB-V.json.gz +0 -0
  137. package/binary/_internal/pdfminer/cmap/GBK-EUC-H.json.gz +0 -0
  138. package/binary/_internal/pdfminer/cmap/GBK-EUC-V.json.gz +0 -0
  139. package/binary/_internal/pdfminer/cmap/GBK2K-H.json.gz +0 -0
  140. package/binary/_internal/pdfminer/cmap/GBK2K-V.json.gz +0 -0
  141. package/binary/_internal/pdfminer/cmap/GBKp-EUC-H.json.gz +0 -0
  142. package/binary/_internal/pdfminer/cmap/GBKp-EUC-V.json.gz +0 -0
  143. package/binary/_internal/pdfminer/cmap/GBT-EUC-H.json.gz +0 -0
  144. package/binary/_internal/pdfminer/cmap/GBT-EUC-V.json.gz +0 -0
  145. package/binary/_internal/pdfminer/cmap/GBT-H.json.gz +0 -0
  146. package/binary/_internal/pdfminer/cmap/GBT-V.json.gz +0 -0
  147. package/binary/_internal/pdfminer/cmap/GBTpc-EUC-H.json.gz +0 -0
  148. package/binary/_internal/pdfminer/cmap/GBTpc-EUC-V.json.gz +0 -0
  149. package/binary/_internal/pdfminer/cmap/GBpc-EUC-H.json.gz +0 -0
  150. package/binary/_internal/pdfminer/cmap/GBpc-EUC-V.json.gz +0 -0
  151. package/binary/_internal/pdfminer/cmap/H.json.gz +0 -0
  152. package/binary/_internal/pdfminer/cmap/HKdla-B5-H.json.gz +0 -0
  153. package/binary/_internal/pdfminer/cmap/HKdla-B5-V.json.gz +0 -0
  154. package/binary/_internal/pdfminer/cmap/HKdlb-B5-H.json.gz +0 -0
  155. package/binary/_internal/pdfminer/cmap/HKdlb-B5-V.json.gz +0 -0
  156. package/binary/_internal/pdfminer/cmap/HKgccs-B5-H.json.gz +0 -0
  157. package/binary/_internal/pdfminer/cmap/HKgccs-B5-V.json.gz +0 -0
  158. package/binary/_internal/pdfminer/cmap/HKm314-B5-H.json.gz +0 -0
  159. package/binary/_internal/pdfminer/cmap/HKm314-B5-V.json.gz +0 -0
  160. package/binary/_internal/pdfminer/cmap/HKm471-B5-H.json.gz +0 -0
  161. package/binary/_internal/pdfminer/cmap/HKm471-B5-V.json.gz +0 -0
  162. package/binary/_internal/pdfminer/cmap/HKscs-B5-H.json.gz +0 -0
  163. package/binary/_internal/pdfminer/cmap/HKscs-B5-V.json.gz +0 -0
  164. package/binary/_internal/pdfminer/cmap/Hankaku-H.json.gz +0 -0
  165. package/binary/_internal/pdfminer/cmap/Hankaku-V.json.gz +0 -0
  166. package/binary/_internal/pdfminer/cmap/Hiragana-H.json.gz +0 -0
  167. package/binary/_internal/pdfminer/cmap/Hiragana-V.json.gz +0 -0
  168. package/binary/_internal/pdfminer/cmap/KSC-EUC-H.json.gz +0 -0
  169. package/binary/_internal/pdfminer/cmap/KSC-EUC-V.json.gz +0 -0
  170. package/binary/_internal/pdfminer/cmap/KSC-H.json.gz +0 -0
  171. package/binary/_internal/pdfminer/cmap/KSC-Johab-H.json.gz +0 -0
  172. package/binary/_internal/pdfminer/cmap/KSC-Johab-V.json.gz +0 -0
  173. package/binary/_internal/pdfminer/cmap/KSC-V.json.gz +0 -0
  174. package/binary/_internal/pdfminer/cmap/KSCms-UHC-H.json.gz +0 -0
  175. package/binary/_internal/pdfminer/cmap/KSCms-UHC-HW-H.json.gz +0 -0
  176. package/binary/_internal/pdfminer/cmap/KSCms-UHC-HW-V.json.gz +0 -0
  177. package/binary/_internal/pdfminer/cmap/KSCms-UHC-V.json.gz +0 -0
  178. package/binary/_internal/pdfminer/cmap/KSCpc-EUC-H.json.gz +0 -0
  179. package/binary/_internal/pdfminer/cmap/KSCpc-EUC-V.json.gz +0 -0
  180. package/binary/_internal/pdfminer/cmap/Katakana-H.json.gz +0 -0
  181. package/binary/_internal/pdfminer/cmap/Katakana-V.json.gz +0 -0
  182. package/binary/_internal/pdfminer/cmap/NWP-H.json.gz +0 -0
  183. package/binary/_internal/pdfminer/cmap/NWP-V.json.gz +0 -0
  184. package/binary/_internal/pdfminer/cmap/README.txt +79 -0
  185. package/binary/_internal/pdfminer/cmap/RKSJ-H.json.gz +0 -0
  186. package/binary/_internal/pdfminer/cmap/RKSJ-V.json.gz +0 -0
  187. package/binary/_internal/pdfminer/cmap/Roman-H.json.gz +0 -0
  188. package/binary/_internal/pdfminer/cmap/Roman-V.json.gz +0 -0
  189. package/binary/_internal/pdfminer/cmap/UniCNS-UCS2-H.json.gz +0 -0
  190. package/binary/_internal/pdfminer/cmap/UniCNS-UCS2-V.json.gz +0 -0
  191. package/binary/_internal/pdfminer/cmap/UniCNS-UTF16-H.json.gz +0 -0
  192. package/binary/_internal/pdfminer/cmap/UniCNS-UTF16-V.json.gz +0 -0
  193. package/binary/_internal/pdfminer/cmap/UniCNS-UTF32-H.json.gz +0 -0
  194. package/binary/_internal/pdfminer/cmap/UniCNS-UTF32-V.json.gz +0 -0
  195. package/binary/_internal/pdfminer/cmap/UniCNS-UTF8-H.json.gz +0 -0
  196. package/binary/_internal/pdfminer/cmap/UniCNS-UTF8-V.json.gz +0 -0
  197. package/binary/_internal/pdfminer/cmap/UniGB-UCS2-H.json.gz +0 -0
  198. package/binary/_internal/pdfminer/cmap/UniGB-UCS2-V.json.gz +0 -0
  199. package/binary/_internal/pdfminer/cmap/UniGB-UTF16-H.json.gz +0 -0
  200. package/binary/_internal/pdfminer/cmap/UniGB-UTF16-V.json.gz +0 -0
  201. package/binary/_internal/pdfminer/cmap/UniGB-UTF32-H.json.gz +0 -0
  202. package/binary/_internal/pdfminer/cmap/UniGB-UTF32-V.json.gz +0 -0
  203. package/binary/_internal/pdfminer/cmap/UniGB-UTF8-H.json.gz +0 -0
  204. package/binary/_internal/pdfminer/cmap/UniGB-UTF8-V.json.gz +0 -0
  205. package/binary/_internal/pdfminer/cmap/UniJIS-UCS2-H.json.gz +0 -0
  206. package/binary/_internal/pdfminer/cmap/UniJIS-UCS2-HW-H.json.gz +0 -0
  207. package/binary/_internal/pdfminer/cmap/UniJIS-UCS2-HW-V.json.gz +0 -0
  208. package/binary/_internal/pdfminer/cmap/UniJIS-UCS2-V.json.gz +0 -0
  209. package/binary/_internal/pdfminer/cmap/UniJIS-UTF16-H.json.gz +0 -0
  210. package/binary/_internal/pdfminer/cmap/UniJIS-UTF16-V.json.gz +0 -0
  211. package/binary/_internal/pdfminer/cmap/UniJIS-UTF32-H.json.gz +0 -0
  212. package/binary/_internal/pdfminer/cmap/UniJIS-UTF32-V.json.gz +0 -0
  213. package/binary/_internal/pdfminer/cmap/UniJIS-UTF8-H.json.gz +0 -0
  214. package/binary/_internal/pdfminer/cmap/UniJIS-UTF8-V.json.gz +0 -0
  215. package/binary/_internal/pdfminer/cmap/UniJIS2004-UTF16-H.json.gz +0 -0
  216. package/binary/_internal/pdfminer/cmap/UniJIS2004-UTF16-V.json.gz +0 -0
  217. package/binary/_internal/pdfminer/cmap/UniJIS2004-UTF32-H.json.gz +0 -0
  218. package/binary/_internal/pdfminer/cmap/UniJIS2004-UTF32-V.json.gz +0 -0
  219. package/binary/_internal/pdfminer/cmap/UniJIS2004-UTF8-H.json.gz +0 -0
  220. package/binary/_internal/pdfminer/cmap/UniJIS2004-UTF8-V.json.gz +0 -0
  221. package/binary/_internal/pdfminer/cmap/UniJISX0213-UTF32-H.json.gz +0 -0
  222. package/binary/_internal/pdfminer/cmap/UniJISX0213-UTF32-V.json.gz +0 -0
  223. package/binary/_internal/pdfminer/cmap/UniJISX02132004-UTF32-H.json.gz +0 -0
  224. package/binary/_internal/pdfminer/cmap/UniJISX02132004-UTF32-V.json.gz +0 -0
  225. package/binary/_internal/pdfminer/cmap/UniKS-UCS2-H.json.gz +0 -0
  226. package/binary/_internal/pdfminer/cmap/UniKS-UCS2-V.json.gz +0 -0
  227. package/binary/_internal/pdfminer/cmap/UniKS-UTF16-H.json.gz +0 -0
  228. package/binary/_internal/pdfminer/cmap/UniKS-UTF16-V.json.gz +0 -0
  229. package/binary/_internal/pdfminer/cmap/UniKS-UTF32-H.json.gz +0 -0
  230. package/binary/_internal/pdfminer/cmap/UniKS-UTF32-V.json.gz +0 -0
  231. package/binary/_internal/pdfminer/cmap/UniKS-UTF8-H.json.gz +0 -0
  232. package/binary/_internal/pdfminer/cmap/UniKS-UTF8-V.json.gz +0 -0
  233. package/binary/_internal/pdfminer/cmap/V.json.gz +0 -0
  234. package/binary/_internal/pdfminer/cmap/WP-Symbol-H.json.gz +0 -0
  235. package/binary/_internal/pdfminer/cmap/WP-Symbol-V.json.gz +0 -0
  236. package/binary/_internal/pdfminer/cmap/to-unicode-Adobe-CNS1.json.gz +0 -0
  237. package/binary/_internal/pdfminer/cmap/to-unicode-Adobe-GB1.json.gz +0 -0
  238. package/binary/_internal/pdfminer/cmap/to-unicode-Adobe-Japan1.json.gz +0 -0
  239. package/binary/_internal/pdfminer/cmap/to-unicode-Adobe-Korea1.json.gz +0 -0
  240. package/binary/_internal/pdfminer/py.typed +0 -0
  241. package/binary/_internal/pdfminer_six-20260107.dist-info/INSTALLER +1 -0
  242. package/binary/_internal/pdfminer_six-20260107.dist-info/METADATA +110 -0
  243. package/binary/_internal/pdfminer_six-20260107.dist-info/RECORD +191 -0
  244. package/binary/_internal/pdfminer_six-20260107.dist-info/REQUESTED +0 -0
  245. package/binary/_internal/pdfminer_six-20260107.dist-info/WHEEL +5 -0
  246. package/binary/_internal/pdfminer_six-20260107.dist-info/licenses/LICENSE +22 -0
  247. package/binary/_internal/pdfminer_six-20260107.dist-info/top_level.txt +1 -0
  248. package/binary/_internal/pdfplumber-0.11.10.dist-info/INSTALLER +1 -0
  249. package/binary/_internal/pdfplumber-0.11.10.dist-info/METADATA +617 -0
  250. package/binary/_internal/pdfplumber-0.11.10.dist-info/RECORD +30 -0
  251. package/binary/_internal/pdfplumber-0.11.10.dist-info/REQUESTED +0 -0
  252. package/binary/_internal/pdfplumber-0.11.10.dist-info/WHEEL +5 -0
  253. package/binary/_internal/pdfplumber-0.11.10.dist-info/entry_points.txt +2 -0
  254. package/binary/_internal/pdfplumber-0.11.10.dist-info/licenses/LICENSE.txt +21 -0
  255. package/binary/_internal/pdfplumber-0.11.10.dist-info/top_level.txt +1 -0
  256. package/binary/_internal/pillow-12.3.0.dist-info/INSTALLER +1 -0
  257. package/binary/_internal/pillow-12.3.0.dist-info/METADATA +180 -0
  258. package/binary/_internal/pillow-12.3.0.dist-info/RECORD +141 -0
  259. package/binary/_internal/pillow-12.3.0.dist-info/REQUESTED +0 -0
  260. package/binary/_internal/pillow-12.3.0.dist-info/WHEEL +6 -0
  261. package/binary/_internal/pillow-12.3.0.dist-info/licenses/LICENSE +1574 -0
  262. package/binary/_internal/pillow-12.3.0.dist-info/sboms/pillow-12.3.0.cdx.json +721 -0
  263. package/binary/_internal/pillow-12.3.0.dist-info/top_level.txt +1 -0
  264. package/binary/_internal/pillow-12.3.0.dist-info/zip-safe +1 -0
  265. package/binary/_internal/pycparser-3.0.dist-info/INSTALLER +1 -0
  266. package/binary/_internal/pycparser-3.0.dist-info/METADATA +244 -0
  267. package/binary/_internal/pycparser-3.0.dist-info/RECORD +15 -0
  268. package/binary/_internal/pycparser-3.0.dist-info/REQUESTED +0 -0
  269. package/binary/_internal/pycparser-3.0.dist-info/WHEEL +5 -0
  270. package/binary/_internal/pycparser-3.0.dist-info/licenses/LICENSE +27 -0
  271. package/binary/_internal/pycparser-3.0.dist-info/top_level.txt +1 -0
  272. package/binary/_internal/pypdfium2/version.json +11 -0
  273. package/binary/_internal/pypdfium2-5.13.0.dist-info/INSTALLER +1 -0
  274. package/binary/_internal/pypdfium2-5.13.0.dist-info/METADATA +1139 -0
  275. package/binary/_internal/pypdfium2-5.13.0.dist-info/RECORD +75 -0
  276. package/binary/_internal/pypdfium2-5.13.0.dist-info/REQUESTED +0 -0
  277. package/binary/_internal/pypdfium2-5.13.0.dist-info/WHEEL +5 -0
  278. package/binary/_internal/pypdfium2-5.13.0.dist-info/entry_points.txt +2 -0
  279. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/LICENSES/Apache-2.0.txt +202 -0
  280. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/LICENSES/BSD-3-Clause.txt +26 -0
  281. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/LICENSES/CC-BY-4.0.txt +317 -0
  282. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/abseil.txt +203 -0
  283. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/agg23.txt +14 -0
  284. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/fast_float.txt +27 -0
  285. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/freetype.txt +169 -0
  286. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/icu.txt +568 -0
  287. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/lcms.txt +27 -0
  288. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libjpeg_turbo.ijg +260 -0
  289. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libjpeg_turbo.md +135 -0
  290. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libopenjpeg.txt +32 -0
  291. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libpng.txt +134 -0
  292. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libtiff.txt +21 -0
  293. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/llvm-libc.txt +278 -0
  294. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/pdfium-binaries.txt +9 -0
  295. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/pdfium.txt +230 -0
  296. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/simdutf.txt +18 -0
  297. package/binary/_internal/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/zlib.txt +29 -0
  298. package/binary/_internal/pypdfium2-5.13.0.dist-info/top_level.txt +4 -0
  299. package/binary/_internal/pypdfium2_raw/libpdfium.dylib +0 -0
  300. package/binary/_internal/pypdfium2_raw/version.json +10 -0
  301. package/binary/_internal/python_calamine/_python_calamine.cpython-312-darwin.so +0 -0
  302. package/binary/_internal/python_calamine-0.8.2.dist-info/INSTALLER +1 -0
  303. package/binary/_internal/python_calamine-0.8.2.dist-info/METADATA +94 -0
  304. package/binary/_internal/python_calamine-0.8.2.dist-info/RECORD +11 -0
  305. package/binary/_internal/python_calamine-0.8.2.dist-info/REQUESTED +0 -0
  306. package/binary/_internal/python_calamine-0.8.2.dist-info/WHEEL +4 -0
  307. package/binary/_internal/python_calamine-0.8.2.dist-info/licenses/LICENSE +21 -0
  308. package/binary/_internal/python_calamine-0.8.2.dist-info/sboms/python-calamine.cyclonedx.json +1652 -0
  309. package/binary/_internal/quickjs_ng-0.17.0.1.dist-info/INSTALLER +1 -0
  310. package/binary/_internal/quickjs_ng-0.17.0.1.dist-info/METADATA +161 -0
  311. package/binary/_internal/quickjs_ng-0.17.0.1.dist-info/RECORD +9 -0
  312. package/binary/_internal/quickjs_ng-0.17.0.1.dist-info/REQUESTED +0 -0
  313. package/binary/_internal/quickjs_ng-0.17.0.1.dist-info/WHEEL +6 -0
  314. package/binary/_internal/quickjs_ng-0.17.0.1.dist-info/licenses/LICENSE +21 -0
  315. package/binary/_internal/quickjs_ng-0.17.0.1.dist-info/top_level.txt +2 -0
  316. package/binary/_internal/selectolax/base.pxi +4 -0
  317. package/binary/_internal/selectolax/lexbor/attrs.pxi +123 -0
  318. package/binary/_internal/selectolax/lexbor/fragment_lookup.pxi +52 -0
  319. package/binary/_internal/selectolax/lexbor/node.pxi +1355 -0
  320. package/binary/_internal/selectolax/lexbor/node_remove.pxi +29 -0
  321. package/binary/_internal/selectolax/lexbor/selection.pxi +251 -0
  322. package/binary/_internal/selectolax/lexbor/util.pxi +114 -0
  323. package/binary/_internal/selectolax/lexbor.c +66981 -0
  324. package/binary/_internal/selectolax/lexbor.cpython-312-darwin.so +0 -0
  325. package/binary/_internal/selectolax/lexbor.pxd +682 -0
  326. package/binary/_internal/selectolax/lexbor.pyi +1534 -0
  327. package/binary/_internal/selectolax/lexbor.pyx +1046 -0
  328. package/binary/_internal/selectolax/modest/node.pxi +976 -0
  329. package/binary/_internal/selectolax/modest/selection.pxi +199 -0
  330. package/binary/_internal/selectolax/modest/util.pxi +20 -0
  331. package/binary/_internal/selectolax/py.typed +0 -0
  332. package/binary/_internal/selectolax/utils.pxi +117 -0
  333. package/binary/_internal/selectolax-0.4.13.dist-info/INSTALLER +1 -0
  334. package/binary/_internal/selectolax-0.4.13.dist-info/METADATA +222 -0
  335. package/binary/_internal/selectolax-0.4.13.dist-info/RECORD +30 -0
  336. package/binary/_internal/selectolax-0.4.13.dist-info/REQUESTED +0 -0
  337. package/binary/_internal/selectolax-0.4.13.dist-info/WHEEL +6 -0
  338. package/binary/_internal/selectolax-0.4.13.dist-info/licenses/LICENSE +10 -0
  339. package/binary/_internal/selectolax-0.4.13.dist-info/top_level.txt +1 -0
  340. package/binary/brewdoc +0 -0
  341. package/binary/licenses/installed/brewdoc/brewdoc/_vendor/THIRD_PARTY_NOTICES.txt +342 -0
  342. package/binary/licenses/installed/brewdoc/brewdoc-0.3.2.dist-info/licenses/LICENSE +21 -0
  343. package/binary/licenses/installed/cffi/cffi-2.1.1.dist-info/licenses/LICENSE +23 -0
  344. package/binary/licenses/installed/charset-normalizer/charset_normalizer-3.5.2.dist-info/licenses/LICENSE +21 -0
  345. package/binary/licenses/installed/cryptography/cryptography-50.0.2.dist-info/licenses/LICENSE +3 -0
  346. package/binary/licenses/installed/cryptography/cryptography-50.0.2.dist-info/licenses/LICENSE.APACHE +202 -0
  347. package/binary/licenses/installed/cryptography/cryptography-50.0.2.dist-info/licenses/LICENSE.BSD +27 -0
  348. package/binary/licenses/installed/interpreter/LICENSE.txt +279 -0
  349. package/binary/licenses/installed/pdfminer.six/pdfminer_six-20260107.dist-info/licenses/LICENSE +22 -0
  350. package/binary/licenses/installed/pdfplumber/pdfplumber-0.11.10.dist-info/licenses/LICENSE.txt +21 -0
  351. package/binary/licenses/installed/pillow/pillow-12.3.0.dist-info/licenses/LICENSE +1574 -0
  352. package/binary/licenses/installed/pycparser/pycparser-3.0.dist-info/licenses/LICENSE +27 -0
  353. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/LICENSES/Apache-2.0.txt +202 -0
  354. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/LICENSES/BSD-3-Clause.txt +26 -0
  355. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/LICENSES/CC-BY-4.0.txt +317 -0
  356. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/abseil.txt +203 -0
  357. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/agg23.txt +14 -0
  358. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/fast_float.txt +27 -0
  359. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/freetype.txt +169 -0
  360. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/icu.txt +568 -0
  361. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/lcms.txt +27 -0
  362. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libjpeg_turbo.ijg +260 -0
  363. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libjpeg_turbo.md +135 -0
  364. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libopenjpeg.txt +32 -0
  365. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libpng.txt +134 -0
  366. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/libtiff.txt +21 -0
  367. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/llvm-libc.txt +278 -0
  368. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/pdfium-binaries.txt +9 -0
  369. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/pdfium.txt +230 -0
  370. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/simdutf.txt +18 -0
  371. package/binary/licenses/installed/pypdfium2/pypdfium2-5.13.0.dist-info/licenses/data/darwin_arm64/BUILD_LICENSES/zlib.txt +29 -0
  372. package/binary/licenses/installed/python-calamine/python_calamine-0.8.2.dist-info/licenses/LICENSE +21 -0
  373. package/binary/licenses/installed/quickjs-ng/quickjs_ng-0.17.0.1.dist-info/licenses/LICENSE +21 -0
  374. package/binary/licenses/installed/runtime-hooks/pyi_rth_cryptography_openssl.py +20 -0
  375. package/binary/licenses/installed/runtime-hooks/pyi_rth_inspect.py +99 -0
  376. package/binary/licenses/installed/runtime-hooks/pyi_rth_multiprocessing.py +88 -0
  377. package/binary/licenses/installed/runtime-hooks/pyi_rth_pkgutil.py +64 -0
  378. package/binary/licenses/installed/selectolax/selectolax-0.4.13.dist-info/licenses/LICENSE +10 -0
  379. package/binary/licenses/installed-manifest.json +192 -0
  380. package/binary/licenses/supplemental/openssl/3.5.9/README-copyright.txt +9 -0
  381. package/binary/licenses/supplemental/openssl/4.0.3/README-copyright.txt +9 -0
  382. package/binary/licenses/supplemental/provenance.json +2347 -0
  383. package/binary/licenses/supplemental/pyinstaller-6.22.3/COPYING.txt +648 -0
  384. package/binary/licenses/supplemental/pyinstaller-6.22.3/bootloader/waflib/LICENSE +25 -0
  385. package/binary/licenses/supplemental/pyinstaller-6.22.3/bootloader/zlib/LICENSE +22 -0
  386. package/binary/licenses/supplemental/pyinstaller-6.22.3/doc/license.rst +24 -0
  387. package/binary/licenses/supplemental/pyinstaller-hooks-contrib-2026.8/LICENSE +521 -0
  388. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE +373 -0
  389. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.bdb.txt +126 -0
  390. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.bzip2.txt +37 -0
  391. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.cpython.txt +771 -0
  392. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.expat.txt +21 -0
  393. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.libX11.txt +942 -0
  394. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.libXau.txt +21 -0
  395. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.libedit.txt +29 -0
  396. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.libffi.txt +21 -0
  397. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.liblzma.txt +13 -0
  398. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.libuuid.txt +27 -0
  399. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.libxcb.txt +30 -0
  400. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.mpdecimal.txt +24 -0
  401. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.ncurses.txt +29 -0
  402. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.openssl-1.1.txt +124 -0
  403. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.openssl-3.txt +177 -0
  404. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.sqlite.txt +23 -0
  405. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.tcl.txt +40 -0
  406. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.tix.txt +54 -0
  407. package/binary/licenses/supplemental/python-build-standalone-20260929/LICENSE.zlib.txt +21 -0
  408. package/binary/licenses/supplemental/python-calamine-0.8.2/LICENSE +21 -0
  409. package/binary/licenses/supplemental/python-calamine-0.8.2/source-identity/Cargo.lock +620 -0
  410. package/binary/licenses/supplemental/python-calamine-0.8.2/source-identity/Cargo.toml +22 -0
  411. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/LICENSE +21 -0
  412. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/cutils.h.txt +24 -0
  413. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/dtoa.c.txt +23 -0
  414. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/dtoa.h.txt +23 -0
  415. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/libregexp-opcode.h.txt +23 -0
  416. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/libregexp.c.txt +23 -0
  417. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/libregexp.h.txt +23 -0
  418. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/libunicode.c.txt +23 -0
  419. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/libunicode.h.txt +23 -0
  420. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/list.h.txt +23 -0
  421. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/quickjs-atom.h.txt +24 -0
  422. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/quickjs-opcode.h.txt +24 -0
  423. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/quickjs.c.txt +26 -0
  424. package/binary/licenses/supplemental/quickjs-ng-0.17.0.1/engine-headers/upstream-quickjs/quickjs.h.txt +26 -0
  425. package/binary/licenses/supplemental/rust-adler2-2.0.1/LICENSE-0BSD +12 -0
  426. package/binary/licenses/supplemental/rust-adler2-2.0.1/LICENSE-APACHE +201 -0
  427. package/binary/licenses/supplemental/rust-adler2-2.0.1/LICENSE-MIT +23 -0
  428. package/binary/licenses/supplemental/rust-android_system_properties-0.1.5/LICENSE-APACHE +13 -0
  429. package/binary/licenses/supplemental/rust-android_system_properties-0.1.5/LICENSE-MIT +20 -0
  430. package/binary/licenses/supplemental/rust-atoi_simd-0.18.1/LICENSE-APACHE +201 -0
  431. package/binary/licenses/supplemental/rust-atoi_simd-0.18.1/LICENSE-MIT +25 -0
  432. package/binary/licenses/supplemental/rust-autocfg-1.5.1/LICENSE-APACHE +201 -0
  433. package/binary/licenses/supplemental/rust-autocfg-1.5.1/LICENSE-MIT +25 -0
  434. package/binary/licenses/supplemental/rust-bumpalo-3.20.3/LICENSE-APACHE +201 -0
  435. package/binary/licenses/supplemental/rust-bumpalo-3.20.3/LICENSE-MIT +25 -0
  436. package/binary/licenses/supplemental/rust-byteorder-1.5.0/COPYING +3 -0
  437. package/binary/licenses/supplemental/rust-byteorder-1.5.0/LICENSE-MIT +21 -0
  438. package/binary/licenses/supplemental/rust-calamine-0.36.0/LICENSE-MIT.md +23 -0
  439. package/binary/licenses/supplemental/rust-cc-1.2.64/LICENSE-APACHE +201 -0
  440. package/binary/licenses/supplemental/rust-cc-1.2.64/LICENSE-MIT +25 -0
  441. package/binary/licenses/supplemental/rust-cfg-if-1.0.4/LICENSE-APACHE +201 -0
  442. package/binary/licenses/supplemental/rust-cfg-if-1.0.4/LICENSE-MIT +25 -0
  443. package/binary/licenses/supplemental/rust-chrono-0.4.45/LICENSE.txt +240 -0
  444. package/binary/licenses/supplemental/rust-codepage-0.1.2/COPYRIGHT +9 -0
  445. package/binary/licenses/supplemental/rust-codepage-0.1.2/LICENSE-APACHE +202 -0
  446. package/binary/licenses/supplemental/rust-codepage-0.1.2/LICENSE-MIT +25 -0
  447. package/binary/licenses/supplemental/rust-core-foundation-sys-0.8.7/LICENSE-APACHE +201 -0
  448. package/binary/licenses/supplemental/rust-core-foundation-sys-0.8.7/LICENSE-MIT +25 -0
  449. package/binary/licenses/supplemental/rust-crc32fast-1.5.0/LICENSE-APACHE +202 -0
  450. package/binary/licenses/supplemental/rust-crc32fast-1.5.0/LICENSE-MIT +21 -0
  451. package/binary/licenses/supplemental/rust-debug_unsafe-0.1.4/LICENSE-APACHE +201 -0
  452. package/binary/licenses/supplemental/rust-debug_unsafe-0.1.4/LICENSE-MIT +25 -0
  453. package/binary/licenses/supplemental/rust-encoding_rs-0.8.35/COPYRIGHT +17 -0
  454. package/binary/licenses/supplemental/rust-encoding_rs-0.8.35/LICENSE-APACHE +202 -0
  455. package/binary/licenses/supplemental/rust-encoding_rs-0.8.35/LICENSE-MIT +25 -0
  456. package/binary/licenses/supplemental/rust-encoding_rs-0.8.35/LICENSE-WHATWG +26 -0
  457. package/binary/licenses/supplemental/rust-equivalent-1.0.2/LICENSE-APACHE +201 -0
  458. package/binary/licenses/supplemental/rust-equivalent-1.0.2/LICENSE-MIT +25 -0
  459. package/binary/licenses/supplemental/rust-fast-float2-0.2.3/LICENSE-APACHE +201 -0
  460. package/binary/licenses/supplemental/rust-fast-float2-0.2.3/LICENSE-MIT +23 -0
  461. package/binary/licenses/supplemental/rust-find-msvc-tools-0.1.9/LICENSE-APACHE +201 -0
  462. package/binary/licenses/supplemental/rust-find-msvc-tools-0.1.9/LICENSE-MIT +25 -0
  463. package/binary/licenses/supplemental/rust-flate2-1.1.9/LICENSE-APACHE +201 -0
  464. package/binary/licenses/supplemental/rust-flate2-1.1.9/LICENSE-MIT +25 -0
  465. package/binary/licenses/supplemental/rust-futures-core-0.3.32/LICENSE-APACHE +202 -0
  466. package/binary/licenses/supplemental/rust-futures-core-0.3.32/LICENSE-MIT +26 -0
  467. package/binary/licenses/supplemental/rust-futures-task-0.3.32/LICENSE-APACHE +202 -0
  468. package/binary/licenses/supplemental/rust-futures-task-0.3.32/LICENSE-MIT +26 -0
  469. package/binary/licenses/supplemental/rust-futures-util-0.3.32/LICENSE-APACHE +202 -0
  470. package/binary/licenses/supplemental/rust-futures-util-0.3.32/LICENSE-MIT +26 -0
  471. package/binary/licenses/supplemental/rust-hashbrown-0.17.1/LICENSE-APACHE +201 -0
  472. package/binary/licenses/supplemental/rust-hashbrown-0.17.1/LICENSE-MIT +25 -0
  473. package/binary/licenses/supplemental/rust-heck-0.5.0/LICENSE-APACHE +201 -0
  474. package/binary/licenses/supplemental/rust-heck-0.5.0/LICENSE-MIT +25 -0
  475. package/binary/licenses/supplemental/rust-iana-time-zone-0.1.65/LICENSE-APACHE +201 -0
  476. package/binary/licenses/supplemental/rust-iana-time-zone-0.1.65/LICENSE-MIT +25 -0
  477. package/binary/licenses/supplemental/rust-iana-time-zone-haiku-0.1.2/LICENSE-APACHE +201 -0
  478. package/binary/licenses/supplemental/rust-iana-time-zone-haiku-0.1.2/LICENSE-MIT +25 -0
  479. package/binary/licenses/supplemental/rust-indexmap-2.14.0/LICENSE-APACHE +201 -0
  480. package/binary/licenses/supplemental/rust-indexmap-2.14.0/LICENSE-MIT +25 -0
  481. package/binary/licenses/supplemental/rust-js-sys-0.3.102/LICENSE-APACHE +201 -0
  482. package/binary/licenses/supplemental/rust-js-sys-0.3.102/LICENSE-MIT +25 -0
  483. package/binary/licenses/supplemental/rust-libc-0.2.186/LICENSE-APACHE +176 -0
  484. package/binary/licenses/supplemental/rust-libc-0.2.186/LICENSE-MIT +25 -0
  485. package/binary/licenses/supplemental/rust-log-0.4.32/LICENSE-APACHE +201 -0
  486. package/binary/licenses/supplemental/rust-log-0.4.32/LICENSE-MIT +25 -0
  487. package/binary/licenses/supplemental/rust-memchr-2.8.2/COPYING +3 -0
  488. package/binary/licenses/supplemental/rust-memchr-2.8.2/LICENSE-MIT +21 -0
  489. package/binary/licenses/supplemental/rust-miniz_oxide-0.8.9/LICENSE +25 -0
  490. package/binary/licenses/supplemental/rust-miniz_oxide-0.8.9/LICENSE-APACHE.md +177 -0
  491. package/binary/licenses/supplemental/rust-miniz_oxide-0.8.9/LICENSE-MIT.md +24 -0
  492. package/binary/licenses/supplemental/rust-miniz_oxide-0.8.9/LICENSE-ZLIB.md +14 -0
  493. package/binary/licenses/supplemental/rust-num-traits-0.2.19/LICENSE-APACHE +201 -0
  494. package/binary/licenses/supplemental/rust-num-traits-0.2.19/LICENSE-MIT +25 -0
  495. package/binary/licenses/supplemental/rust-once_cell-1.21.4/LICENSE-APACHE +201 -0
  496. package/binary/licenses/supplemental/rust-once_cell-1.21.4/LICENSE-MIT +23 -0
  497. package/binary/licenses/supplemental/rust-pin-project-lite-0.2.17/LICENSE-APACHE +177 -0
  498. package/binary/licenses/supplemental/rust-pin-project-lite-0.2.17/LICENSE-MIT +23 -0
  499. package/binary/licenses/supplemental/rust-portable-atomic-1.13.1/LICENSE-APACHE +177 -0
  500. package/binary/licenses/supplemental/rust-portable-atomic-1.13.1/LICENSE-MIT +23 -0
  501. package/binary/licenses/supplemental/rust-proc-macro2-1.0.106/LICENSE-APACHE +176 -0
  502. package/binary/licenses/supplemental/rust-proc-macro2-1.0.106/LICENSE-MIT +23 -0
  503. package/binary/licenses/supplemental/rust-pyo3-0.29.0/LICENSE-APACHE +178 -0
  504. package/binary/licenses/supplemental/rust-pyo3-0.29.0/LICENSE-MIT +25 -0
  505. package/binary/licenses/supplemental/rust-pyo3-0.29.0/pyo3-runtime/LICENSE-APACHE +178 -0
  506. package/binary/licenses/supplemental/rust-pyo3-0.29.0/pyo3-runtime/LICENSE-MIT +25 -0
  507. package/binary/licenses/supplemental/rust-pyo3-build-config-0.29.0/LICENSE-APACHE +178 -0
  508. package/binary/licenses/supplemental/rust-pyo3-build-config-0.29.0/LICENSE-MIT +25 -0
  509. package/binary/licenses/supplemental/rust-pyo3-ffi-0.29.0/LICENSE-APACHE +178 -0
  510. package/binary/licenses/supplemental/rust-pyo3-ffi-0.29.0/LICENSE-MIT +25 -0
  511. package/binary/licenses/supplemental/rust-pyo3-file-0.16.0/Cargo.toml +14 -0
  512. package/binary/licenses/supplemental/rust-pyo3-file-0.16.0/README.md +90 -0
  513. package/binary/licenses/supplemental/rust-pyo3-file-0.16.0/declared-license/Apache-2.0.txt +73 -0
  514. package/binary/licenses/supplemental/rust-pyo3-macros-0.29.0/LICENSE-APACHE +178 -0
  515. package/binary/licenses/supplemental/rust-pyo3-macros-0.29.0/LICENSE-MIT +25 -0
  516. package/binary/licenses/supplemental/rust-pyo3-macros-backend-0.29.0/LICENSE-APACHE +178 -0
  517. package/binary/licenses/supplemental/rust-pyo3-macros-backend-0.29.0/LICENSE-MIT +25 -0
  518. package/binary/licenses/supplemental/rust-quick-xml-0.41.0/LICENSE-MIT.md +23 -0
  519. package/binary/licenses/supplemental/rust-quote-1.0.45/LICENSE-APACHE +176 -0
  520. package/binary/licenses/supplemental/rust-quote-1.0.45/LICENSE-MIT +23 -0
  521. package/binary/licenses/supplemental/rust-rustversion-1.0.22/LICENSE-APACHE +176 -0
  522. package/binary/licenses/supplemental/rust-rustversion-1.0.22/LICENSE-MIT +23 -0
  523. package/binary/licenses/supplemental/rust-serde-1.0.228/LICENSE-APACHE +176 -0
  524. package/binary/licenses/supplemental/rust-serde-1.0.228/LICENSE-MIT +23 -0
  525. package/binary/licenses/supplemental/rust-serde_core-1.0.228/LICENSE-APACHE +176 -0
  526. package/binary/licenses/supplemental/rust-serde_core-1.0.228/LICENSE-MIT +23 -0
  527. package/binary/licenses/supplemental/rust-serde_derive-1.0.228/LICENSE-APACHE +176 -0
  528. package/binary/licenses/supplemental/rust-serde_derive-1.0.228/LICENSE-MIT +23 -0
  529. package/binary/licenses/supplemental/rust-shlex-2.0.1/LICENSE-APACHE +13 -0
  530. package/binary/licenses/supplemental/rust-shlex-2.0.1/LICENSE-MIT +21 -0
  531. package/binary/licenses/supplemental/rust-simd-adler32-0.3.9/LICENSE.md +21 -0
  532. package/binary/licenses/supplemental/rust-slab-0.4.12/LICENSE +25 -0
  533. package/binary/licenses/supplemental/rust-syn-2.0.118/LICENSE-APACHE +176 -0
  534. package/binary/licenses/supplemental/rust-syn-2.0.118/LICENSE-MIT +23 -0
  535. package/binary/licenses/supplemental/rust-target-lexicon-0.13.5/LICENSE +220 -0
  536. package/binary/licenses/supplemental/rust-typed-path-0.12.3/LICENSE-APACHE +176 -0
  537. package/binary/licenses/supplemental/rust-typed-path-0.12.3/LICENSE-MIT +23 -0
  538. package/binary/licenses/supplemental/rust-unicode-ident-1.0.24/LICENSE-APACHE +176 -0
  539. package/binary/licenses/supplemental/rust-unicode-ident-1.0.24/LICENSE-MIT +23 -0
  540. package/binary/licenses/supplemental/rust-unicode-ident-1.0.24/LICENSE-UNICODE +39 -0
  541. package/binary/licenses/supplemental/rust-wasm-bindgen-0.2.125/LICENSE-APACHE +201 -0
  542. package/binary/licenses/supplemental/rust-wasm-bindgen-0.2.125/LICENSE-MIT +25 -0
  543. package/binary/licenses/supplemental/rust-wasm-bindgen-macro-0.2.125/LICENSE-APACHE +201 -0
  544. package/binary/licenses/supplemental/rust-wasm-bindgen-macro-0.2.125/LICENSE-MIT +25 -0
  545. package/binary/licenses/supplemental/rust-wasm-bindgen-macro-support-0.2.125/LICENSE-APACHE +201 -0
  546. package/binary/licenses/supplemental/rust-wasm-bindgen-macro-support-0.2.125/LICENSE-MIT +25 -0
  547. package/binary/licenses/supplemental/rust-wasm-bindgen-shared-0.2.125/LICENSE-APACHE +201 -0
  548. package/binary/licenses/supplemental/rust-wasm-bindgen-shared-0.2.125/LICENSE-MIT +25 -0
  549. package/binary/licenses/supplemental/rust-windows-core-0.62.2/license-apache-2.0 +201 -0
  550. package/binary/licenses/supplemental/rust-windows-core-0.62.2/license-mit +21 -0
  551. package/binary/licenses/supplemental/rust-windows-implement-0.60.2/license-apache-2.0 +201 -0
  552. package/binary/licenses/supplemental/rust-windows-implement-0.60.2/license-mit +21 -0
  553. package/binary/licenses/supplemental/rust-windows-interface-0.59.3/license-apache-2.0 +201 -0
  554. package/binary/licenses/supplemental/rust-windows-interface-0.59.3/license-mit +21 -0
  555. package/binary/licenses/supplemental/rust-windows-link-0.2.1/license-apache-2.0 +201 -0
  556. package/binary/licenses/supplemental/rust-windows-link-0.2.1/license-mit +21 -0
  557. package/binary/licenses/supplemental/rust-windows-result-0.4.1/license-apache-2.0 +201 -0
  558. package/binary/licenses/supplemental/rust-windows-result-0.4.1/license-mit +21 -0
  559. package/binary/licenses/supplemental/rust-windows-strings-0.5.1/license-apache-2.0 +201 -0
  560. package/binary/licenses/supplemental/rust-windows-strings-0.5.1/license-mit +21 -0
  561. package/binary/licenses/supplemental/rust-zip-8.6.0/LICENSE +21 -0
  562. package/binary/licenses/supplemental/rust-zlib-rs-0.6.3/LICENSE +19 -0
  563. package/binary/licenses/supplemental/rust-zopfli-0.8.3/COPYING +201 -0
  564. package/binary/licenses/supplemental/selectolax-0.4.13/LICENSE +10 -0
  565. package/binary/licenses/supplemental/selectolax-0.4.13/lexbor/LICENSE +223 -0
  566. package/binary/licenses/supplemental/selectolax-0.4.13/lexbor/NOTICE +16 -0
  567. package/binary/version.json +6 -0
  568. package/native-manifest.json +4364 -0
  569. package/native-verification.json +338 -0
  570. package/package.json +24 -4
@@ -0,0 +1,1355 @@
1
+ cimport cython
2
+ from cpython.exc cimport PyErr_SetNone
3
+
4
+ import logging
5
+
6
+ logger = logging.getLogger("selectolax")
7
+
8
+ _TAG_TO_NAME = {
9
+ 0x0005: "-doctype",
10
+ 0x0002: "-text",
11
+ 0x0004: "-comment",
12
+ }
13
+ ctypedef fused str_or_LexborNode:
14
+ str
15
+ bytes
16
+ LexborNode
17
+
18
+ ctypedef fused str_or_bytes:
19
+ str
20
+ bytes
21
+
22
+ cdef inline bytes to_bytes(str_or_LexborNode value):
23
+ cdef bytes bytes_val
24
+ if isinstance(value, unicode):
25
+ bytes_val = <bytes> value.encode("utf-8")
26
+ elif isinstance(value, bytes):
27
+ bytes_val = <bytes> value
28
+ return bytes_val
29
+
30
+
31
+ @cython.final
32
+ cdef class LexborNode:
33
+ """A class that represents HTML node (element)."""
34
+
35
+ cdef void set_as_fragment_root(self):
36
+ self._is_fragment_root = 1
37
+
38
+ @staticmethod
39
+ cdef LexborNode new(lxb_dom_node_t *node, LexborHTMLParser parser):
40
+ cdef LexborNode lxbnode = LexborNode.__new__(LexborNode)
41
+ lxbnode.node = node
42
+ lxbnode.parser = parser
43
+ lxbnode._is_fragment_root = 0
44
+ return lxbnode
45
+
46
+ @property
47
+ def mem_id(self):
48
+ return <size_t> self.node
49
+
50
+ @property
51
+ def child(self):
52
+ """Alias for the `first_child` property.
53
+
54
+ **Deprecated**. Please use `first_child` instead.
55
+ """
56
+ return self.first_child
57
+
58
+ @property
59
+ def first_child(self):
60
+ """Return the first child node."""
61
+ cdef LexborNode node
62
+ if self.node.first_child:
63
+ node = LexborNode.new(<lxb_dom_node_t *> self.node.first_child, self.parser)
64
+ return node
65
+ return None
66
+
67
+ @property
68
+ def parent(self):
69
+ """Return the parent node."""
70
+ cdef LexborNode node
71
+ if self.node.parent != NULL:
72
+ node = LexborNode.new(<lxb_dom_node_t *> self.node.parent, self.parser)
73
+ return node
74
+ return None
75
+
76
+ @property
77
+ def next(self):
78
+ """Return next node."""
79
+ cdef LexborNode node
80
+ if self.node.next != NULL:
81
+ node = LexborNode.new(<lxb_dom_node_t *> self.node.next, self.parser)
82
+ return node
83
+ return None
84
+
85
+ @property
86
+ def prev(self):
87
+ """Return previous node."""
88
+ cdef LexborNode node
89
+ if self.node.prev != NULL:
90
+ node = LexborNode.new(<lxb_dom_node_t *> self.node.prev, self.parser)
91
+ return node
92
+ return None
93
+
94
+ @property
95
+ def last_child(self):
96
+ """Return last child node."""
97
+ cdef LexborNode node
98
+ if self.node.last_child != NULL:
99
+ node = LexborNode.new(<lxb_dom_node_t *> self.node.last_child, self.parser)
100
+ return node
101
+ return None
102
+
103
+ @property
104
+ def html(self):
105
+ """Return HTML representation of the current node including all its child nodes.
106
+
107
+ Returns
108
+ -------
109
+ text : str
110
+ """
111
+ cdef lexbor_str_t *lxb_str
112
+ cdef lxb_status_t status
113
+ lxb_str = lexbor_str_create()
114
+ if self._is_fragment_root:
115
+ status = serialize_fragment(self.node, lxb_str)
116
+ # status = lxb_html_serialize_tree_str(self.node, lxb_str)
117
+ else:
118
+ status = lxb_html_serialize_tree_str(self.node, lxb_str)
119
+ if status == 0:
120
+ html = lxb_str.data.decode(_ENCODING).replace('<-undef>', '')
121
+ lexbor_str_destroy(lxb_str, self.node.owner_document.text, True)
122
+ return html
123
+ lexbor_str_destroy(lxb_str, self.node.owner_document.text, True)
124
+ return None
125
+
126
+ cdef inline str _serialize_html(self, lxb_html_serialize_opt_t options, size_t indent, bint pretty):
127
+ cdef lexbor_str_t *lxb_str
128
+ cdef lxb_status_t status
129
+
130
+ lxb_str = lexbor_str_create()
131
+ if self._is_fragment_root:
132
+ if pretty:
133
+ status = serialize_fragment_pretty(self.node, lxb_str, options, indent)
134
+ else:
135
+ status = serialize_fragment(self.node, lxb_str)
136
+ else:
137
+ if pretty:
138
+ status = lxb_html_serialize_pretty_tree_str(self.node, options, indent, lxb_str)
139
+ else:
140
+ status = lxb_html_serialize_tree_str(self.node, lxb_str)
141
+
142
+ if status == 0:
143
+ html = lxb_str.data.decode(_ENCODING).replace('<-undef>', '')
144
+ lexbor_str_destroy(lxb_str, self.node.owner_document.text, True)
145
+ return html
146
+ lexbor_str_destroy(lxb_str, self.node.owner_document.text, True)
147
+ return None
148
+
149
+ cdef inline str _serialize_inner_html(self, lxb_html_serialize_opt_t options, size_t indent, bint pretty):
150
+ cdef lexbor_str_t *lxb_str
151
+ cdef lxb_status_t status
152
+
153
+ lxb_str = lexbor_str_create()
154
+ if pretty:
155
+ status = lxb_html_serialize_pretty_deep_str(self.node, options, indent, lxb_str)
156
+ else:
157
+ status = lxb_html_serialize_deep_str(self.node, lxb_str)
158
+
159
+ if status == 0 and lxb_str.data:
160
+ html = lxb_str.data.decode(_ENCODING).replace('<-undef>', '')
161
+ lexbor_str_destroy(lxb_str, self.node.owner_document.text, True)
162
+ return html
163
+ lexbor_str_destroy(lxb_str, self.node.owner_document.text, True)
164
+ return None
165
+
166
+ def html_pretty(
167
+ self,
168
+ Py_ssize_t indent=0,
169
+ bint skip_ws_nodes=False,
170
+ bint skip_comment=False,
171
+ bint raw=False,
172
+ bint without_closing=False,
173
+ bint tag_with_ns=False,
174
+ bint without_text_indent=False,
175
+ bint full_doctype=False,
176
+ bint html5test=False,
177
+ ):
178
+ """Return pretty-printed HTML for the current node.
179
+
180
+ Parameters
181
+ ----------
182
+ indent : int, optional
183
+ Initial indentation level passed to Lexbor. Defaults to ``0``.
184
+ skip_ws_nodes : bool, optional
185
+ Skip text nodes that contain only whitespace.
186
+ skip_comment : bool, optional
187
+ Exclude HTML comment nodes from the serialized output.
188
+ raw : bool, optional
189
+ Serialize text and attribute values without HTML escaping.
190
+ without_closing : bool, optional
191
+ Omit closing tags for non-void elements.
192
+ tag_with_ns : bool, optional
193
+ Include namespace prefixes in serialized tag names when available.
194
+ without_text_indent : bool, optional
195
+ Disable extra indentation added around text and comment content.
196
+ full_doctype : bool, optional
197
+ Serialize the full document type declaration when a doctype node is present.
198
+ html5test : bool, optional
199
+ Serialize using Lexbor's HTML5 test formatting mode.
200
+ """
201
+ cdef lxb_html_serialize_opt_t options
202
+ if indent < 0:
203
+ raise ValueError("indent must be greater than or equal to 0")
204
+ options = _html_pretty_options(
205
+ skip_ws_nodes,
206
+ skip_comment,
207
+ raw,
208
+ without_closing,
209
+ tag_with_ns,
210
+ without_text_indent,
211
+ full_doctype,
212
+ html5test,
213
+ )
214
+ return self._serialize_html(options, <size_t> indent, True)
215
+
216
+ def inner_html_pretty(
217
+ self,
218
+ Py_ssize_t indent=0,
219
+ bint skip_ws_nodes=False,
220
+ bint skip_comment=False,
221
+ bint raw=False,
222
+ bint without_closing=False,
223
+ bint tag_with_ns=False,
224
+ bint without_text_indent=False,
225
+ bint full_doctype=False,
226
+ bint html5test=False,
227
+ ):
228
+ """Return pretty-printed HTML representation of the child nodes.
229
+
230
+ Parameters
231
+ ----------
232
+ indent : int, optional
233
+ Initial indentation level passed to Lexbor. Defaults to ``0``.
234
+ skip_ws_nodes : bool, optional
235
+ Skip text nodes that contain only whitespace.
236
+ skip_comment : bool, optional
237
+ Exclude HTML comment nodes from the serialized output.
238
+ raw : bool, optional
239
+ Serialize text and attribute values without HTML escaping.
240
+ without_closing : bool, optional
241
+ Omit closing tags for non-void elements.
242
+ tag_with_ns : bool, optional
243
+ Include namespace prefixes in serialized tag names when available.
244
+ without_text_indent : bool, optional
245
+ Disable extra indentation added around text and comment content.
246
+ full_doctype : bool, optional
247
+ Serialize the full document type declaration when a doctype node is present.
248
+ html5test : bool, optional
249
+ Serialize using Lexbor's HTML5 test formatting mode.
250
+ """
251
+ cdef lxb_html_serialize_opt_t options
252
+ if indent < 0:
253
+ raise ValueError("indent must be greater than or equal to 0")
254
+ options = _html_pretty_options(
255
+ skip_ws_nodes,
256
+ skip_comment,
257
+ raw,
258
+ without_closing,
259
+ tag_with_ns,
260
+ without_text_indent,
261
+ full_doctype,
262
+ html5test,
263
+ )
264
+ return self._serialize_inner_html(options, <size_t> indent, True)
265
+
266
+ def __hash__(self):
267
+ return self.mem_id
268
+
269
+ def text_lexbor(self):
270
+ """Returns the text of the node including text of all its child nodes.
271
+
272
+ Uses builtin method from lexbor.
273
+ """
274
+
275
+ cdef size_t str_len = 0
276
+ cdef lxb_char_t * text
277
+ text = lxb_dom_node_text_content(self.node, &str_len)
278
+ if text == NULL or <int> str_len == 0:
279
+ return ""
280
+
281
+ unicode_text = text.decode(_ENCODING)
282
+ return unicode_text
283
+
284
+ def text(self, bool deep=True, str separator='', bool strip=False, bool skip_empty=False):
285
+ """Return concatenated text from this node.
286
+
287
+ Parameters
288
+ ----------
289
+ deep : bool, optional
290
+ When ``True`` (default), include text from all descendant nodes; when
291
+ ``False``, only include direct children.
292
+ separator : str, optional
293
+ String inserted between successive text fragments.
294
+ strip : bool, optional
295
+ If ``True``, apply ``str.strip()`` to each fragment before joining to
296
+ remove surrounding whitespace. Defaults to ``False``.
297
+ skip_empty : bool, optional
298
+ Exclude text nodes whose content is only ASCII whitespace (space,
299
+ tab, newline, form feed or carriage return) when ``True``.
300
+ Defaults to ``False``.
301
+
302
+ Returns
303
+ -------
304
+ text : str
305
+ Combined textual content assembled according to the provided options.
306
+
307
+ """
308
+ cdef unsigned char * text
309
+ cdef LexborNode start_node = self._get_node()
310
+ cdef lxb_dom_node_t * node = <lxb_dom_node_t *> start_node.node.first_child
311
+
312
+ if not deep:
313
+ container = TextContainer(separator, strip)
314
+ if _is_node_type(self.node, LXB_DOM_NODE_TYPE_TEXT):
315
+ text = <unsigned char *> lexbor_str_data_noi(&(<lxb_dom_character_data_t *> self.node).data)
316
+ if text != NULL:
317
+ if not skip_empty or not self.is_empty_text_node:
318
+ py_text = text.decode(_ENCODING)
319
+ container.append(py_text)
320
+
321
+ while node != NULL:
322
+ if _is_node_type(node, LXB_DOM_NODE_TYPE_TEXT):
323
+ text = <unsigned char *> lexbor_str_data_noi(&(<lxb_dom_character_data_t *> node).data)
324
+ if text != NULL:
325
+ if not skip_empty or not is_empty_text_node(node):
326
+ py_text = text.decode(_ENCODING)
327
+ container.append(py_text)
328
+ node = node.next
329
+ return container.text
330
+ else:
331
+ container = TextContainer(separator, strip)
332
+ if _is_node_type(self.node, LXB_DOM_NODE_TYPE_TEXT):
333
+ text = <unsigned char *> lexbor_str_data_noi(&(<lxb_dom_character_data_t *> self.node).data)
334
+ if text != NULL:
335
+ if not skip_empty or not self.is_empty_text_node:
336
+ container.append(text.decode(_ENCODING))
337
+
338
+ lxb_dom_node_simple_walk(
339
+ <lxb_dom_node_t *> start_node.node,
340
+ <lxb_dom_node_simple_walker_f> text_callback,
341
+ <void *> container
342
+ )
343
+ return container.text
344
+
345
+ cdef inline LexborNode _get_node(self):
346
+ cdef LexborNode node
347
+ if self._is_fragment_root and not _is_node_type(self.node, LXB_DOM_NODE_TYPE_TEXT):
348
+ node = self.parent
349
+ else:
350
+ node = self
351
+ return node
352
+
353
+ def css(self, str query):
354
+ """Evaluate CSS selector against current node and its child nodes.
355
+
356
+ Matches pattern `query` against HTML tree.
357
+ `CSS selectors reference <https://www.w3schools.com/cssref/css_selectors.asp>`_.
358
+
359
+ Special selectors:
360
+
361
+ - parser.css('p:lexbor-contains("awesome" i)') -- case-insensitive contains
362
+ - parser.css('p:lexbor-contains("awesome")') -- case-sensitive contains
363
+
364
+
365
+ Parameters
366
+ ----------
367
+ query : str
368
+ CSS selector (e.g. "div > :nth-child(2n+1):not(:has(a))").
369
+
370
+ Returns
371
+ -------
372
+ selector : list of `Node` objects
373
+ """
374
+ return self.parser.selector.find(query, self._get_node())
375
+
376
+ def css_first(self, str query, default=None, bool strict=False):
377
+ """Same as `css` but returns only the first match.
378
+
379
+ When `strict=False` stops at the first match. Works faster.
380
+
381
+ Parameters
382
+ ----------
383
+
384
+ query : str
385
+ default : Any, default None
386
+ Default value to return if there is no match.
387
+ strict: bool, default False
388
+ Set to True if you want to check if there is strictly only one match in the document.
389
+
390
+
391
+ Returns
392
+ -------
393
+ selector : `LexborNode` object
394
+ """
395
+ if strict:
396
+ results = self.parser.selector.find(query, self._get_node())
397
+ else:
398
+ results = self.parser.selector.find_first(query, self._get_node())
399
+ n_results = len(results)
400
+ if n_results > 0:
401
+ if strict and n_results > 1:
402
+ raise ValueError("Expected 1 match, but found %s matches" % n_results)
403
+ return results[0]
404
+ return default
405
+
406
+ def any_css_matches(self, tuple selectors):
407
+ """Returns True if any of CSS selectors matches a node"""
408
+ for selector in selectors:
409
+ if self.parser.selector.any_matches(selector, self):
410
+ return True
411
+ return False
412
+
413
+ def css_matches(self, str selector):
414
+ """Returns True if CSS selector matches a node."""
415
+ return bool(self.parser.selector.any_matches(selector, self))
416
+
417
+ def __repr__(self):
418
+ return '<LexborNode %s>' % self.tag
419
+
420
+ @property
421
+ def tag_id(self):
422
+ cdef lxb_tag_id_t tag_id = lxb_dom_node_tag_id_noi(self.node)
423
+ return tag_id
424
+
425
+ @property
426
+ def tag(self):
427
+ """Return the name of the current tag (e.g. div, p, img).
428
+
429
+ For for non-tag nodes, returns the following names:
430
+
431
+ * `-text` - text node
432
+ * `-document` - document node
433
+ * `-comment` - comment node
434
+
435
+ This
436
+
437
+ Returns
438
+ -------
439
+ text : str
440
+ """
441
+
442
+ cdef lxb_char_t *c_text
443
+ cdef size_t str_len = 0
444
+ if self.tag_id in [LXB_TAG__EM_DOCTYPE, LXB_TAG__TEXT, LXB_TAG__EM_COMMENT]:
445
+ return _TAG_TO_NAME[self.tag_id]
446
+ c_text = lxb_dom_element_qualified_name(<lxb_dom_element_t *> self.node, &str_len)
447
+ text = None
448
+ if c_text:
449
+ text = c_text.decode(_ENCODING)
450
+ return text
451
+
452
+ def decompose(self, bool recursive=True):
453
+ """Remove the current node from the tree.
454
+
455
+ Parameters
456
+ ----------
457
+ recursive : bool, default True
458
+ Whenever to delete all its child nodes
459
+
460
+ Examples
461
+ --------
462
+
463
+ >>> tree = LexborHTMLParser(html)
464
+ >>> for tag in tree.css('script'):
465
+ >>> tag.decompose()
466
+
467
+ """
468
+ if self.node == <lxb_dom_node_t *> lxb_dom_document_root(&self.parser.document.dom_document):
469
+ raise SelectolaxError("Decomposing the root node is not allowed.")
470
+
471
+ if recursive:
472
+ node_remove_deep(<lxb_dom_node_t *> self.node)
473
+ else:
474
+ lxb_dom_node_remove(<lxb_dom_node_t *> self.node)
475
+
476
+ def strip_tags(self, list tags, bool recursive = False):
477
+ """Remove specified tags from the HTML tree.
478
+
479
+ Parameters
480
+ ----------
481
+ tags : list
482
+ List of tags to remove.
483
+ recursive : bool, default True
484
+ Whenever to delete all its child nodes
485
+
486
+ Examples
487
+ --------
488
+
489
+ >>> tree = LexborHTMLParser('<html><head></head><body><script></script><div>Hello world!</div></body></html>')
490
+ >>> tags = ['head', 'style', 'script', 'xmp', 'iframe', 'noembed', 'noframes']
491
+ >>> tree.strip_tags(tags)
492
+ >>> tree.html
493
+ '<html><body><div>Hello world!</div></body></html>'
494
+
495
+ """
496
+ cdef LexborNode element
497
+ for tag in tags:
498
+ for element in self.css(tag):
499
+ element.decompose(recursive=recursive)
500
+
501
+ @property
502
+ def attributes(self):
503
+ """Get all attributes that belong to the current node.
504
+
505
+ The value of empty attributes is None.
506
+
507
+ Returns
508
+ -------
509
+ attributes : dictionary of all attributes.
510
+
511
+ Examples
512
+ --------
513
+
514
+ >>> tree = LexborHTMLParser("<div data id='my_id'></div>")
515
+ >>> node = tree.css_first('div')
516
+ >>> node.attributes
517
+ {'data': None, 'id': 'my_id'}
518
+ """
519
+ cdef lxb_dom_attr_t *attr = lxb_dom_element_first_attribute_noi(<lxb_dom_element_t *> self.node)
520
+ cdef size_t str_len = 0
521
+ attributes = dict()
522
+
523
+ if not _is_node_type(self.node, LXB_DOM_NODE_TYPE_ELEMENT):
524
+ return attributes
525
+
526
+ while attr != NULL:
527
+ key = lxb_dom_attr_local_name_noi(attr, &str_len)
528
+ value = lxb_dom_attr_value_noi(attr, &str_len)
529
+
530
+ if value:
531
+ py_value = value.decode(_ENCODING)
532
+ else:
533
+ py_value = None
534
+ attributes[key.decode(_ENCODING)] = py_value
535
+
536
+ attr = attr.next
537
+ return attributes
538
+
539
+ @property
540
+ def attrs(self):
541
+ """A dict-like object that is similar to the ``attributes`` property, but operates directly on the Node data.
542
+
543
+ .. warning:: Use ``attributes`` instead, if you don't want to modify Node attributes.
544
+
545
+ Returns
546
+ -------
547
+ attributes : Attributes mapping object.
548
+
549
+ Examples
550
+ --------
551
+
552
+ >>> tree = LexborHTMLParser("<div id='a'></div>")
553
+ >>> node = tree.css_first('div')
554
+ >>> node.attrs
555
+ <div attributes, 1 items>
556
+ >>> node.attrs['id']
557
+ 'a'
558
+ >>> node.attrs['foo'] = 'bar'
559
+ >>> del node.attrs['id']
560
+ >>> node.attributes
561
+ {'foo': 'bar'}
562
+ >>> node.attrs['id'] = 'new_id'
563
+ >>> node.html
564
+ '<div foo="bar" id="new_id"></div>'
565
+ """
566
+ if not _is_node_type(self.node, LXB_DOM_NODE_TYPE_ELEMENT):
567
+ raise TypeError("attrs is only available for element nodes")
568
+ cdef LexborAttributes attributes = LexborAttributes.create(<lxb_dom_node_t *> self.node)
569
+ return attributes
570
+
571
+ @property
572
+ def id(self):
573
+ """Get the id attribute of the node.
574
+
575
+ Returns None if id does not set.
576
+
577
+ Returns
578
+ -------
579
+ text : str
580
+ """
581
+ cdef char * key = 'id'
582
+ cdef size_t str_len
583
+ cdef lxb_dom_attr_t * attr = lxb_dom_element_attr_by_name(
584
+ <lxb_dom_element_t *> self.node,
585
+ <lxb_char_t *> key, 2
586
+ )
587
+ if attr != NULL:
588
+ value = lxb_dom_attr_value_noi(attr, &str_len)
589
+ return value.decode(_ENCODING) if value else None
590
+ return None
591
+
592
+ def iter(self, bool include_text = False, bool skip_empty = False):
593
+ """Iterate over direct children of this node.
594
+
595
+ Parameters
596
+ ----------
597
+ include_text : bool, optional
598
+ When ``True``, yield text nodes in addition to element nodes. Defaults
599
+ to ``False``.
600
+ skip_empty : bool, optional
601
+ When ``include_text`` is ``True``, ignore text nodes made up solely
602
+ of ASCII whitespace (space, tab, newline, form feed or carriage
603
+ return). Defaults to ``False``.
604
+
605
+ Yields
606
+ ------
607
+ LexborNode
608
+ Child nodes on the same tree level as this node, filtered according
609
+ to the provided options.
610
+ """
611
+
612
+ cdef LexborNode start_node = self._get_node()
613
+ cdef lxb_dom_node_t *node = start_node.node.first_child
614
+ cdef LexborNode next_node
615
+
616
+ while node != NULL:
617
+ if node.type == LXB_DOM_NODE_TYPE_TEXT and not include_text:
618
+ node = node.next
619
+ continue
620
+ if node.type == LXB_DOM_NODE_TYPE_TEXT and include_text and skip_empty and is_empty_text_node(node):
621
+ node = node.next
622
+ continue
623
+
624
+ next_node = LexborNode.new(<lxb_dom_node_t *> node, self.parser)
625
+ yield next_node
626
+ node = node.next
627
+
628
+ def __iter__(self):
629
+ return self.iter()
630
+
631
+ def __next__(self):
632
+ return self.next
633
+
634
+ def unwrap(self, bint delete_empty=False):
635
+ """Replace node with whatever is inside this node.
636
+
637
+ Does nothing if you perform unwrapping second time on the same node.
638
+
639
+ Parameters
640
+ ----------
641
+ delete_empty : bool, default False
642
+ If True, removes empty tags.
643
+
644
+ Examples
645
+ --------
646
+
647
+ >>> tree = LexborHTMLParser("<div>Hello <i>world</i>!</div>")
648
+ >>> tree.css_first('i').unwrap()
649
+ >>> tree.html
650
+ '<html><head></head><body><div>Hello world!</div></body></html>'
651
+
652
+ Note: by default, empty tags are ignored, use "delete_empty" to change this.
653
+ """
654
+ if self.node.parent == NULL:
655
+ return
656
+
657
+ if node_is_removed(<lxb_dom_node_t *> self.node) == 1:
658
+ logger.error("Attempt to unwrap removed node. Does nothing.")
659
+ return
660
+
661
+ cdef lxb_dom_node_t * current_node = self.node.first_child
662
+ cdef lxb_dom_node_t * next_node
663
+
664
+ if current_node == NULL:
665
+ if delete_empty:
666
+ lxb_dom_node_remove(<lxb_dom_node_t *> self.node)
667
+ return
668
+
669
+ while current_node != NULL:
670
+ next_node = current_node.next
671
+ lxb_dom_node_insert_before(self.node, current_node)
672
+ current_node = next_node
673
+
674
+ lxb_dom_node_remove(<lxb_dom_node_t *> self.node)
675
+
676
+ def unwrap_tags(self, list tags, bint delete_empty = False):
677
+ """Unwraps specified tags from the HTML tree.
678
+
679
+ Works the same as the ``unwrap`` method, but applied to a list of tags.
680
+
681
+ Parameters
682
+ ----------
683
+ tags : list
684
+ List of tags to remove.
685
+ delete_empty : bool, default False
686
+ If True, removes empty tags.
687
+
688
+ Examples
689
+ --------
690
+
691
+ >>> tree = LexborHTMLParser("<div><a href="">Hello</a> <i>world</i>!</div>")
692
+ >>> tree.body.unwrap_tags(['i','a'])
693
+ >>> tree.body.html
694
+ '<body><div>Hello world!</div></body>'
695
+
696
+ Note: by default, empty tags are ignored, use "delete_empty" to change this.
697
+ """
698
+ cdef LexborNode element
699
+ for tag in tags:
700
+ if self.node.parent == NULL and not _is_node_type(self.node, LXB_DOM_NODE_TYPE_DOCUMENT):
701
+ break
702
+ for element in self.css(tag):
703
+ element.unwrap(delete_empty)
704
+
705
+ def merge_text_nodes(self):
706
+ """Iterates over all text nodes and merges all text nodes that are close to each other.
707
+
708
+ This is useful for text extraction.
709
+ Use it when you need to strip HTML tags and merge "dangling" text.
710
+
711
+ Examples
712
+ --------
713
+
714
+ >>> tree = LexborHTMLParser("<div><p><strong>J</strong>ohn</p><p>Doe</p></div>")
715
+ >>> node = tree.css_first('div')
716
+ >>> tree.unwrap_tags(["strong"])
717
+ >>> tree.text(deep=True, separator=" ", strip=True)
718
+ "J ohn Doe" # Text extraction produces an extra space because the strong tag was removed.
719
+ >>> node.merge_text_nodes()
720
+ >>> tree.text(deep=True, separator=" ", strip=True)
721
+ "John Doe"
722
+ """
723
+ _merge_text_nodes(self.node)
724
+
725
+ def traverse(self, bool include_text = False, bool skip_empty = False):
726
+ """Depth-first traversal starting at the current node.
727
+
728
+ Parameters
729
+ ----------
730
+ include_text : bool, optional
731
+ When ``True``, include text nodes in the traversal sequence. Defaults
732
+ to ``False``.
733
+ skip_empty : bool, optional
734
+ Skip text nodes that contain only ASCII whitespace (space, tab,
735
+ newline, form feed or carriage return) when ``include_text`` is
736
+ ``True``. Defaults to ``False``.
737
+
738
+ Yields
739
+ ------
740
+ LexborNode
741
+ Nodes encountered in depth-first order beginning with the current
742
+ node, filtered according to the provided options.
743
+ """
744
+ cdef lxb_dom_node_t * root = self.node
745
+ cdef lxb_dom_node_t * node = root
746
+ cdef LexborNode lxb_node
747
+
748
+ while node != NULL:
749
+ if include_text or node.type != LXB_DOM_NODE_TYPE_TEXT:
750
+ if not skip_empty or not is_empty_text_node(node):
751
+ lxb_node = LexborNode.new(<lxb_dom_node_t *> node, self.parser)
752
+ yield lxb_node
753
+
754
+ if node.first_child != NULL:
755
+ node = node.first_child
756
+ else:
757
+ while node != root and node.next == NULL:
758
+ node = node.parent
759
+ if node == root:
760
+ break
761
+ node = node.next
762
+
763
+ def replace_with(self, str_or_LexborNode value):
764
+ """Replace current Node with specified value.
765
+
766
+ Parameters
767
+ ----------
768
+ value : str, bytes or Node
769
+ The text or Node instance to replace the Node with.
770
+ When a text string is passed, it's treated as text. All HTML tags will be escaped.
771
+ Convert and pass the ``Node`` object when you want to work with HTML.
772
+ Does not clone the ``Node`` object.
773
+ All future changes to the passed ``Node`` object will also be taken into account.
774
+
775
+ Examples
776
+ --------
777
+
778
+ >>> tree = LexborHTMLParser('<div>Get <img src="" alt="Laptop"></div>')
779
+ >>> img = tree.css_first('img')
780
+ >>> img.replace_with(img.attributes.get('alt', ''))
781
+ >>> tree.body.child.html
782
+ '<div>Get Laptop</div>'
783
+
784
+ >>> html_parser = LexborHTMLParser('<div>Get <span alt="Laptop"><img src="/jpg"> <div></div></span></div>')
785
+ >>> html_parser2 = LexborHTMLParser('<div>Test</div>')
786
+ >>> img_node = html_parser.css_first('img')
787
+ >>> img_node.replace_with(html_parser2.body.child)
788
+ '<div>Get <span alt="Laptop"><div>Test</div> <div></div></span></div>'
789
+ """
790
+ cdef lxb_dom_node_t * new_node
791
+
792
+ if isinstance(value, (str, bytes, unicode)):
793
+ bytes_val = to_bytes(value)
794
+ new_node = <lxb_dom_node_t *> lxb_dom_document_create_text_node(
795
+ &self.parser.document.dom_document,
796
+ <lxb_char_t *> bytes_val, len(bytes_val)
797
+ )
798
+ if new_node == NULL:
799
+ raise SelectolaxError("Can't create a new node")
800
+ lxb_dom_node_insert_before(self.node, new_node)
801
+ lxb_dom_node_remove(<lxb_dom_node_t *> self.node)
802
+ elif isinstance(value, LexborNode):
803
+ new_node = lxb_dom_document_import_node(
804
+ &self.parser.document.dom_document,
805
+ <lxb_dom_node_t *> value.node,
806
+ <bint> True
807
+ )
808
+ if new_node == NULL:
809
+ raise SelectolaxError("Can't create a new node")
810
+ lxb_dom_node_insert_before(self.node, <lxb_dom_node_t *> new_node)
811
+ lxb_dom_node_remove(<lxb_dom_node_t *> self.node)
812
+ else:
813
+ raise SelectolaxError("Expected a string or LexborNode instance, but %s found" % type(value).__name__)
814
+
815
+ def insert_before(self, str_or_LexborNode value):
816
+ """
817
+ Insert a node before the current Node.
818
+
819
+ Parameters
820
+ ----------
821
+ value : str, bytes or Node
822
+ The text or Node instance to insert before the Node.
823
+ When a text string is passed, it's treated as text. All HTML tags will be escaped.
824
+ Convert and pass the ``Node`` object when you want to work with HTML.
825
+ Does not clone the ``Node`` object.
826
+ All future changes to the passed ``Node`` object will also be taken into account.
827
+
828
+ Examples
829
+ --------
830
+
831
+ >>> tree = LexborHTMLParser('<div>Get <img src="" alt="Laptop"></div>')
832
+ >>> img = tree.css_first('img')
833
+ >>> img.insert_before(img.attributes.get('alt', ''))
834
+ >>> tree.body.child.html
835
+ '<div>Get Laptop<img src="" alt="Laptop"></div>'
836
+
837
+ >>> html_parser = LexborHTMLParser('<div>Get <span alt="Laptop"><img src="/jpg"> <div></div></span></div>')
838
+ >>> html_parser2 = LexborHTMLParser('<div>Test</div>')
839
+ >>> img_node = html_parser.css_first('img')
840
+ >>> img_node.insert_before(html_parser2.body.child)
841
+ <div>Get <span alt="Laptop"><div>Test</div><img src="/jpg"> <div></div></span></div>'
842
+ """
843
+ cdef lxb_dom_node_t * new_node
844
+
845
+ if isinstance(value, (str, bytes, unicode)):
846
+ bytes_val = to_bytes(value)
847
+ new_node = <lxb_dom_node_t *> lxb_dom_document_create_text_node(
848
+ &self.parser.document.dom_document,
849
+ <lxb_char_t *> bytes_val, len(bytes_val)
850
+ )
851
+ if new_node == NULL:
852
+ raise SelectolaxError("Can't create a new node")
853
+ lxb_dom_node_insert_before(self.node, new_node)
854
+ elif isinstance(value, LexborNode):
855
+ new_node = lxb_dom_document_import_node(
856
+ &self.parser.document.dom_document,
857
+ <lxb_dom_node_t *> value.node,
858
+ <bint> True
859
+ )
860
+ if new_node == NULL:
861
+ raise SelectolaxError("Can't create a new node")
862
+ lxb_dom_node_insert_before(self.node, <lxb_dom_node_t *> new_node)
863
+ else:
864
+ raise SelectolaxError("Expected a string or LexborNode instance, but %s found" % type(value).__name__)
865
+
866
+ def insert_after(self, str_or_LexborNode value):
867
+ """
868
+ Insert a node after the current Node.
869
+
870
+ Parameters
871
+ ----------
872
+ value : str, bytes or Node
873
+ The text or Node instance to insert after the Node.
874
+ When a text string is passed, it's treated as text. All HTML tags will be escaped.
875
+ Convert and pass the ``Node`` object when you want to work with HTML.
876
+ Does not clone the ``Node`` object.
877
+ All future changes to the passed ``Node`` object will also be taken into account.
878
+
879
+ Examples
880
+ --------
881
+
882
+ >>> tree = LexborHTMLParser('<div>Get <img src="" alt="Laptop"></div>')
883
+ >>> img = tree.css_first('img')
884
+ >>> img.insert_after(img.attributes.get('alt', ''))
885
+ >>> tree.body.child.html
886
+ '<div>Get <img src="" alt="Laptop">Laptop</div>'
887
+
888
+ >>> html_parser = LexborHTMLParser('<div>Get <span alt="Laptop"><img src="/jpg"> <div></div></span></div>')
889
+ >>> html_parser2 = LexborHTMLParser('<div>Test</div>')
890
+ >>> img_node = html_parser.css_first('img')
891
+ >>> img_node.insert_after(html_parser2.body.child)
892
+ <div>Get <span alt="Laptop"><img src="/jpg"><div>Test</div> <div></div></span></div>'
893
+ """
894
+ cdef lxb_dom_node_t * new_node
895
+
896
+ if isinstance(value, (str, bytes, unicode)):
897
+ bytes_val = to_bytes(value)
898
+ new_node = <lxb_dom_node_t *> lxb_dom_document_create_text_node(
899
+ &self.parser.document.dom_document,
900
+ <lxb_char_t *> bytes_val, len(bytes_val)
901
+ )
902
+ if new_node == NULL:
903
+ raise SelectolaxError("Can't create a new node")
904
+ lxb_dom_node_insert_after(self.node, new_node)
905
+ elif isinstance(value, LexborNode):
906
+ new_node = lxb_dom_document_import_node(
907
+ &self.parser.document.dom_document,
908
+ <lxb_dom_node_t *> value.node,
909
+ <bint> True
910
+ )
911
+ if new_node == NULL:
912
+ raise SelectolaxError("Can't create a new node")
913
+ lxb_dom_node_insert_after(self.node, <lxb_dom_node_t *> new_node)
914
+ else:
915
+ raise SelectolaxError("Expected a string or LexborNode instance, but %s found" % type(value).__name__)
916
+
917
+ def insert_child(self, str_or_LexborNode value):
918
+ """
919
+ Insert a node inside (at the end of) the current Node.
920
+
921
+ Parameters
922
+ ----------
923
+ value : str, bytes or Node
924
+ The text or Node instance to insert inside the Node.
925
+ When a text string is passed, it's treated as text. All HTML tags will be escaped.
926
+ Convert and pass the ``Node`` object when you want to work with HTML.
927
+ Does not clone the ``Node`` object.
928
+ All future changes to the passed ``Node`` object will also be taken into account.
929
+
930
+ Examples
931
+ --------
932
+
933
+ >>> tree = LexborHTMLParser('<div>Get <img src=""></div>')
934
+ >>> div = tree.css_first('div')
935
+ >>> div.insert_child('Laptop')
936
+ >>> tree.body.child.html
937
+ '<div>Get <img src="">Laptop</div>'
938
+
939
+ >>> html_parser = LexborHTMLParser('<div>Get <span alt="Laptop"> <div>Laptop</div> </span></div>')
940
+ >>> html_parser2 = LexborHTMLParser('<div>Test</div>')
941
+ >>> span_node = html_parser.css_first('span')
942
+ >>> span_node.insert_child(html_parser2.body.child)
943
+ <div>Get <span alt="Laptop"> <div>Laptop</div> <div>Test</div> </span></div>'
944
+ """
945
+ cdef lxb_dom_node_t * new_node
946
+
947
+ if isinstance(value, (str, bytes, unicode)):
948
+ bytes_val = to_bytes(value)
949
+ new_node = <lxb_dom_node_t *> lxb_dom_document_create_text_node(
950
+ &self.parser.document.dom_document,
951
+ <lxb_char_t *> bytes_val, len(bytes_val)
952
+ )
953
+ if new_node == NULL:
954
+ raise SelectolaxError("Can't create a new node")
955
+ lxb_dom_node_insert_child(self.node, new_node)
956
+ elif isinstance(value, LexborNode):
957
+ new_node = lxb_dom_document_import_node(
958
+ &self.parser.document.dom_document,
959
+ <lxb_dom_node_t *> value.node,
960
+ <bint> True
961
+ )
962
+ if new_node == NULL:
963
+ raise SelectolaxError("Can't create a new node")
964
+ lxb_dom_node_insert_child(self.node, <lxb_dom_node_t *> new_node)
965
+ else:
966
+ raise SelectolaxError("Expected a string or LexborNode instance, but %s found" % type(value).__name__)
967
+
968
+ @property
969
+ def raw_value(self):
970
+ """Return the raw (unparsed, original) value of a node.
971
+
972
+ Currently, works on text nodes only.
973
+
974
+ Returns
975
+ -------
976
+
977
+ raw_value : bytes
978
+
979
+ Examples
980
+ --------
981
+
982
+ >>> html_parser = LexborHTMLParser('<div>&#x3C;test&#x3E;</div>')
983
+ >>> selector = html_parser.css_first('div')
984
+ >>> selector.child.html
985
+ '&lt;test&gt;'
986
+ >>> selector.child.raw_value
987
+ b'&#x3C;test&#x3E;'
988
+ """
989
+ raise NotImplementedError("This features is not supported by the lexbor backend. Please use Modest backend.")
990
+
991
+ def scripts_contain(self, str query):
992
+ """Returns True if any of the script tags contain specified text.
993
+
994
+ Caches script tags on the first call to improve performance.
995
+
996
+ Parameters
997
+ ----------
998
+ query : str
999
+ The query to check.
1000
+
1001
+ """
1002
+ cdef LexborNode node
1003
+ if self.parser.cached_script_texts is None:
1004
+ nodes = self.parser.selector.find('script', self)
1005
+ text_nodes = []
1006
+ for node in nodes:
1007
+ node_text = node.text(deep=True)
1008
+ if node_text:
1009
+ text_nodes.append(node_text)
1010
+ self.parser.cached_script_texts = text_nodes
1011
+
1012
+ for text in self.parser.cached_script_texts:
1013
+ if query in text:
1014
+ return True
1015
+ return False
1016
+
1017
+ def script_srcs_contain(self, tuple queries):
1018
+ """Returns True if any of the script SRCs attributes contain on of the specified text.
1019
+
1020
+ Caches values on the first call to improve performance.
1021
+
1022
+ Parameters
1023
+ ----------
1024
+ queries : tuple of str
1025
+
1026
+ """
1027
+ cdef LexborNode node
1028
+ if self.parser.cached_script_srcs is None:
1029
+ nodes = self.parser.selector.find('script', self)
1030
+ src_nodes = []
1031
+ for node in nodes:
1032
+ node_src = node.attrs.get('src')
1033
+ if node_src:
1034
+ src_nodes.append(node_src)
1035
+ self.parser.cached_script_srcs = src_nodes
1036
+
1037
+ for text in self.parser.cached_script_srcs:
1038
+ for query in queries:
1039
+ if query in text:
1040
+ return True
1041
+ return False
1042
+
1043
+ def remove(self, bool recursive=True):
1044
+ """An alias for the decompose method."""
1045
+ self.decompose(recursive)
1046
+
1047
+ def select(self, query=None):
1048
+ """Select nodes given a CSS selector.
1049
+
1050
+ Works similarly to the the ``css`` method, but supports chained filtering and extra features.
1051
+
1052
+ Parameters
1053
+ ----------
1054
+ query : str or None
1055
+ The CSS selector to use when searching for nodes.
1056
+
1057
+ Returns
1058
+ -------
1059
+ selector : The `Selector` class.
1060
+ """
1061
+ return LexborSelector(self._get_node(), query)
1062
+
1063
+ def __eq__(self, other):
1064
+ if isinstance(other, str):
1065
+ return self.html == other
1066
+ if not isinstance(other, LexborNode):
1067
+ return False
1068
+ return self.html == other.html
1069
+
1070
+ @property
1071
+ def text_content(self):
1072
+ """Returns the text of the node if it is a text node.
1073
+
1074
+ Returns None for other nodes.
1075
+ Unlike the ``text`` method, does not include child nodes.
1076
+
1077
+ Returns
1078
+ -------
1079
+ text : str or None.
1080
+ """
1081
+ cdef unsigned char * text
1082
+ cdef lxb_dom_node_t * node = <lxb_dom_node_t *> self.node.first_child
1083
+ cdef TextContainer container
1084
+ if not _is_node_type(self.node, LXB_DOM_NODE_TYPE_TEXT):
1085
+ return None
1086
+
1087
+ text = <unsigned char *> lexbor_str_data_noi(&(<lxb_dom_character_data_t *> self.node).data)
1088
+ if text != NULL:
1089
+ container = TextContainer.new_with_defaults()
1090
+ py_text = text.decode(_ENCODING)
1091
+ container.append(py_text)
1092
+ return container.text
1093
+ return None
1094
+
1095
+ @property
1096
+ def comment_content(self) -> str | None:
1097
+ """Extract the textual content of an HTML comment node.
1098
+
1099
+ Returns
1100
+ -------
1101
+ str or None
1102
+ Comment text with surrounding whitespace removed, or ``None`` if
1103
+ the current node is not a comment or the comment markup cannot be
1104
+ parsed.
1105
+
1106
+ Examples
1107
+ --------
1108
+ >>> parse_fragment("<!-- hello -->")[0].comment_content
1109
+ 'hello'
1110
+ >>> parse_fragment("<div>not a comment</div>")[0].comment_content is None
1111
+ True
1112
+ """
1113
+ if not self.is_comment_node:
1114
+ return None
1115
+ try:
1116
+ return extract_html_comment(self.html)
1117
+ except (ValueError, AttributeError, IndexError):
1118
+ return None
1119
+
1120
+ @property
1121
+ def inner_html(self) -> str | None:
1122
+ """Return HTML representation of the child nodes.
1123
+
1124
+ Works similar to innerHTML in JavaScript.
1125
+ Unlike the `.html` property, does not include the current node.
1126
+ Can be used to set HTML as well. See the setter docstring.
1127
+
1128
+ Returns
1129
+ -------
1130
+ text : str | None
1131
+ """
1132
+
1133
+ return self._serialize_inner_html(LXB_HTML_SERIALIZE_OPT_UNDEF, 0, False)
1134
+
1135
+ @inner_html.setter
1136
+ def inner_html(self, str html) -> None:
1137
+ """Set inner HTML to the specified HTML.
1138
+
1139
+ Replaces existing data inside the node.
1140
+ Works similar to innerHTML in JavaScript.
1141
+
1142
+ Parameters
1143
+ ----------
1144
+ html : str | None
1145
+
1146
+ """
1147
+ cdef bytes bytes_val
1148
+ bytes_val = <bytes> html.encode("utf-8")
1149
+ lxb_html_element_inner_html_set(
1150
+ <lxb_html_element_t *> self.node,
1151
+ <lxb_char_t *> bytes_val, len(bytes_val)
1152
+ )
1153
+
1154
+ def clone(self) -> LexborNode:
1155
+ """Clone the current node.
1156
+
1157
+ You can use to do temporary modifications without affecting the original HTML tree.
1158
+
1159
+ It is tied to the current parser instance.
1160
+ Gets destroyed when parser instance is destroyed.
1161
+ """
1162
+ cdef lxb_dom_node_t * node
1163
+ node = lxb_dom_node_clone(<lxb_dom_node_t *> self.node, 1)
1164
+ return LexborNode.new(node, self.parser)
1165
+
1166
+ @property
1167
+ def is_element_node(self) -> bool:
1168
+ """Return True if the node represents an element node."""
1169
+ return _is_node_type(self.node, LXB_DOM_NODE_TYPE_ELEMENT)
1170
+
1171
+ @property
1172
+ def is_text_node(self) -> bool:
1173
+ """Return True if the node represents a text node."""
1174
+ return _is_node_type(self.node, LXB_DOM_NODE_TYPE_TEXT)
1175
+
1176
+ @property
1177
+ def is_comment_node(self) -> bool:
1178
+ """Return True if the node represents a comment node."""
1179
+ return _is_node_type(self.node, LXB_DOM_NODE_TYPE_COMMENT)
1180
+
1181
+ @property
1182
+ def is_document_node(self) -> bool:
1183
+ """Return True if the node represents a document node."""
1184
+ return _is_node_type(self.node, LXB_DOM_NODE_TYPE_DOCUMENT)
1185
+
1186
+ @property
1187
+ def is_empty_text_node(self) -> bool:
1188
+ """Check whether the current node is an empty text node.
1189
+
1190
+ Returns
1191
+ -------
1192
+ bool
1193
+ ``True`` when the node is a text node whose character data consists
1194
+ only of ASCII whitespace characters (space, tab, newline, form feed
1195
+ or carriage return).
1196
+ """
1197
+ return is_empty_text_node(self.node)
1198
+
1199
+
1200
+ @cython.internal
1201
+ @cython.final
1202
+ cdef class TextContainer:
1203
+ cdef list _parts
1204
+ cdef str separator
1205
+ cdef bint strip
1206
+
1207
+ @staticmethod
1208
+ cdef TextContainer new_with_defaults():
1209
+ cdef TextContainer cls = TextContainer.__new__(TextContainer)
1210
+ cls._parts = []
1211
+ cls.separator = ''
1212
+ cls.strip = False
1213
+ return cls
1214
+
1215
+ def __init__(self, str separator = '', bool strip = False):
1216
+ self._parts = []
1217
+ self.separator = separator
1218
+ self.strip = strip
1219
+
1220
+ def append(self, str node_text):
1221
+ if self.strip:
1222
+ self._parts.append(node_text.strip())
1223
+ else:
1224
+ self._parts.append(node_text)
1225
+
1226
+ @property
1227
+ def text(self):
1228
+ return self.separator.join(self._parts)
1229
+
1230
+ cdef lexbor_action_t text_callback(lxb_dom_node_t *node, void *ctx):
1231
+ cdef unsigned char *text
1232
+ cdef lxb_tag_id_t tag_id = lxb_dom_node_tag_id_noi(node)
1233
+ if tag_id != LXB_TAG__TEXT:
1234
+ return LEXBOR_ACTION_OK
1235
+
1236
+ text = <unsigned char *> lexbor_str_data_noi(&(<lxb_dom_text_t *> node).char_data.data)
1237
+ if not text:
1238
+ return LEXBOR_ACTION_OK
1239
+
1240
+ try:
1241
+ py_str = text.decode(_ENCODING, "replace")
1242
+
1243
+ except Exception as e:
1244
+ PyErr_SetNone(e)
1245
+ return LEXBOR_ACTION_STOP
1246
+
1247
+ cdef TextContainer cls
1248
+ cls = <TextContainer> ctx
1249
+ cls.append(py_str)
1250
+ return LEXBOR_ACTION_OK
1251
+
1252
+ cdef lxb_status_t serialize_fragment(lxb_dom_node_t *node, lexbor_str_t *lxb_str):
1253
+ cdef lxb_status_t status
1254
+ while node != NULL:
1255
+ status = lxb_html_serialize_tree_str(node, lxb_str)
1256
+ if status != LXB_STATUS_OK:
1257
+ return status
1258
+ node = node.next
1259
+
1260
+ return LXB_STATUS_OK
1261
+
1262
+
1263
+ cdef lxb_status_t serialize_fragment_pretty(
1264
+ lxb_dom_node_t *node,
1265
+ lexbor_str_t *lxb_str,
1266
+ lxb_html_serialize_opt_t options,
1267
+ size_t indent,
1268
+ ):
1269
+ cdef lxb_status_t status
1270
+ while node != NULL:
1271
+ status = lxb_html_serialize_pretty_tree_str(node, options, indent, lxb_str)
1272
+ if status != LXB_STATUS_OK:
1273
+ return status
1274
+ node = node.next
1275
+
1276
+ return LXB_STATUS_OK
1277
+
1278
+
1279
+ cdef inline lxb_html_serialize_opt_t _html_pretty_options(
1280
+ bint skip_ws_nodes,
1281
+ bint skip_comment,
1282
+ bint raw,
1283
+ bint without_closing,
1284
+ bint tag_with_ns,
1285
+ bint without_text_indent,
1286
+ bint full_doctype,
1287
+ bint html5test,
1288
+ ):
1289
+ cdef lxb_html_serialize_opt_t options = LXB_HTML_SERIALIZE_OPT_UNDEF
1290
+
1291
+ if skip_ws_nodes:
1292
+ options = <lxb_html_serialize_opt_t> (options | LXB_HTML_SERIALIZE_OPT_SKIP_WS_NODES)
1293
+ if skip_comment:
1294
+ options = <lxb_html_serialize_opt_t> (options | LXB_HTML_SERIALIZE_OPT_SKIP_COMMENT)
1295
+ if raw:
1296
+ options = <lxb_html_serialize_opt_t> (options | LXB_HTML_SERIALIZE_OPT_RAW)
1297
+ if without_closing:
1298
+ options = <lxb_html_serialize_opt_t> (options | LXB_HTML_SERIALIZE_OPT_WITHOUT_CLOSING)
1299
+ if tag_with_ns:
1300
+ options = <lxb_html_serialize_opt_t> (options | LXB_HTML_SERIALIZE_OPT_TAG_WITH_NS)
1301
+ if without_text_indent:
1302
+ options = <lxb_html_serialize_opt_t> (options | LXB_HTML_SERIALIZE_OPT_WITHOUT_TEXT_INDENT)
1303
+ if full_doctype:
1304
+ options = <lxb_html_serialize_opt_t> (options | LXB_HTML_SERIALIZE_OPT_FULL_DOCTYPE)
1305
+ if html5test:
1306
+ options = <lxb_html_serialize_opt_t> (options | 0x80)
1307
+
1308
+ return options
1309
+
1310
+ cdef inline bint _is_node_type(lxb_dom_node_t *node, lxb_dom_node_type_t expected_type):
1311
+ return node != NULL and node.type == expected_type
1312
+
1313
+ cdef void _merge_text_nodes(lxb_dom_node_t *root):
1314
+ if root == NULL or node_is_removed(root):
1315
+ return
1316
+
1317
+ cdef lxb_dom_node_t *node
1318
+ cdef lxb_dom_node_t *next_node
1319
+ cdef lxb_dom_text_t *new_text_node
1320
+ cdef lxb_char_t *left_text
1321
+ cdef lxb_char_t *right_text
1322
+ cdef size_t left_length, right_length
1323
+ cdef bytes combined
1324
+
1325
+ cdef bint changed = 1
1326
+ while changed:
1327
+ changed = 0
1328
+ node = root.first_child
1329
+ while node != NULL:
1330
+ next_node = node.next
1331
+ if node.type == LXB_DOM_NODE_TYPE_TEXT and next_node != NULL and next_node.type == LXB_DOM_NODE_TYPE_TEXT:
1332
+ left_text = lxb_dom_node_text_content(node, &left_length)
1333
+ right_text = lxb_dom_node_text_content(next_node, &right_length)
1334
+
1335
+ if left_text != NULL and right_text != NULL:
1336
+ combined = (<bytes>left_text[:left_length]) + (<bytes>right_text[:right_length])
1337
+ new_text_node = lxb_dom_document_create_text_node(
1338
+ root.owner_document,
1339
+ <lxb_char_t *>combined,
1340
+ len(combined)
1341
+ )
1342
+ if new_text_node != NULL:
1343
+ lxb_dom_node_insert_before(node, <lxb_dom_node_t *>new_text_node)
1344
+ lxb_dom_node_remove(node)
1345
+ lxb_dom_node_remove(next_node)
1346
+ changed = 1
1347
+ break
1348
+
1349
+ node = next_node
1350
+
1351
+ node = root.first_child
1352
+ while node != NULL:
1353
+ if node.type == LXB_DOM_NODE_TYPE_ELEMENT and node.first_child:
1354
+ _merge_text_nodes(node)
1355
+ node = node.next