rdfa_parser 0.1.0

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 (373) hide show
  1. data/.gitignore +7 -0
  2. data/History.txt +47 -0
  3. data/README.rdoc +61 -0
  4. data/Rakefile +52 -0
  5. data/VERSION +1 -0
  6. data/bin/rdfa_parser +55 -0
  7. data/lib/rdfa_parser.rb +35 -0
  8. data/lib/rdfa_parser/bnode.rb +92 -0
  9. data/lib/rdfa_parser/exceptions.rb +11 -0
  10. data/lib/rdfa_parser/graph.rb +222 -0
  11. data/lib/rdfa_parser/literal.rb +375 -0
  12. data/lib/rdfa_parser/namespace.rb +91 -0
  13. data/lib/rdfa_parser/rdfa_parser.rb +415 -0
  14. data/lib/rdfa_parser/triple.rb +100 -0
  15. data/lib/rdfa_parser/uriref.rb +94 -0
  16. data/script/console +10 -0
  17. data/script/destroy +14 -0
  18. data/script/generate +14 -0
  19. data/spec/bnode_spec.rb +51 -0
  20. data/spec/graph_spec.rb +230 -0
  21. data/spec/literal_spec.rb +282 -0
  22. data/spec/matchers.rb +134 -0
  23. data/spec/namespace_spec.rb +61 -0
  24. data/spec/rdfa_helper.rb +127 -0
  25. data/spec/rdfa_parser_spec.rb +119 -0
  26. data/spec/spec.opts +1 -0
  27. data/spec/spec_helper.rb +23 -0
  28. data/spec/triple_spec.rb +145 -0
  29. data/spec/uriref_spec.rb +117 -0
  30. data/spec/xhtml1-testcases/.sparql +13 -0
  31. data/spec/xhtml1-testcases/0001.nt +1 -0
  32. data/spec/xhtml1-testcases/0001.sparql +3 -0
  33. data/spec/xhtml1-testcases/0001.xhtml +11 -0
  34. data/spec/xhtml1-testcases/0002.sparql +3 -0
  35. data/spec/xhtml1-testcases/0003.sparql +3 -0
  36. data/spec/xhtml1-testcases/0006.nt +2 -0
  37. data/spec/xhtml1-testcases/0006.sparql +8 -0
  38. data/spec/xhtml1-testcases/0006.xhtml +16 -0
  39. data/spec/xhtml1-testcases/0007.nt +3 -0
  40. data/spec/xhtml1-testcases/0007.sparql +5 -0
  41. data/spec/xhtml1-testcases/0007.xhtml +16 -0
  42. data/spec/xhtml1-testcases/0008.nt +1 -0
  43. data/spec/xhtml1-testcases/0008.sparql +3 -0
  44. data/spec/xhtml1-testcases/0008.xhtml +16 -0
  45. data/spec/xhtml1-testcases/0009.nt +1 -0
  46. data/spec/xhtml1-testcases/0009.sparql +3 -0
  47. data/spec/xhtml1-testcases/0009.xhtml +14 -0
  48. data/spec/xhtml1-testcases/0010.nt +2 -0
  49. data/spec/xhtml1-testcases/0010.sparql +4 -0
  50. data/spec/xhtml1-testcases/0010.xhtml +13 -0
  51. data/spec/xhtml1-testcases/0011.nt +3 -0
  52. data/spec/xhtml1-testcases/0011.sparql +17 -0
  53. data/spec/xhtml1-testcases/0011.xhtml +14 -0
  54. data/spec/xhtml1-testcases/0012.nt +1 -0
  55. data/spec/xhtml1-testcases/0012.sparql +3 -0
  56. data/spec/xhtml1-testcases/0012.xhtml +12 -0
  57. data/spec/xhtml1-testcases/0013.nt +1 -0
  58. data/spec/xhtml1-testcases/0013.sparql +3 -0
  59. data/spec/xhtml1-testcases/0013.xhtml +12 -0
  60. data/spec/xhtml1-testcases/0014.nt +1 -0
  61. data/spec/xhtml1-testcases/0014.sparql +3 -0
  62. data/spec/xhtml1-testcases/0014.xhtml +15 -0
  63. data/spec/xhtml1-testcases/0015.nt +2 -0
  64. data/spec/xhtml1-testcases/0015.sparql +4 -0
  65. data/spec/xhtml1-testcases/0015.xhtml +13 -0
  66. data/spec/xhtml1-testcases/0017.nt +3 -0
  67. data/spec/xhtml1-testcases/0017.sparql +6 -0
  68. data/spec/xhtml1-testcases/0017.xhtml +16 -0
  69. data/spec/xhtml1-testcases/0018.nt +1 -0
  70. data/spec/xhtml1-testcases/0018.sparql +3 -0
  71. data/spec/xhtml1-testcases/0018.xhtml +17 -0
  72. data/spec/xhtml1-testcases/0019.nt +1 -0
  73. data/spec/xhtml1-testcases/0019.sparql +3 -0
  74. data/spec/xhtml1-testcases/0019.xhtml +14 -0
  75. data/spec/xhtml1-testcases/0020.nt +1 -0
  76. data/spec/xhtml1-testcases/0020.sparql +3 -0
  77. data/spec/xhtml1-testcases/0020.xhtml +17 -0
  78. data/spec/xhtml1-testcases/0021.nt +1 -0
  79. data/spec/xhtml1-testcases/0021.sparql +3 -0
  80. data/spec/xhtml1-testcases/0021.xhtml +17 -0
  81. data/spec/xhtml1-testcases/0023.nt +1 -0
  82. data/spec/xhtml1-testcases/0023.sparql +3 -0
  83. data/spec/xhtml1-testcases/0023.xhtml +16 -0
  84. data/spec/xhtml1-testcases/0025.nt +2 -0
  85. data/spec/xhtml1-testcases/0025.sparql +4 -0
  86. data/spec/xhtml1-testcases/0025.xhtml +19 -0
  87. data/spec/xhtml1-testcases/0026.nt +1 -0
  88. data/spec/xhtml1-testcases/0026.sparql +3 -0
  89. data/spec/xhtml1-testcases/0026.xhtml +16 -0
  90. data/spec/xhtml1-testcases/0027.nt +1 -0
  91. data/spec/xhtml1-testcases/0027.sparql +3 -0
  92. data/spec/xhtml1-testcases/0027.xhtml +17 -0
  93. data/spec/xhtml1-testcases/0029.nt +1 -0
  94. data/spec/xhtml1-testcases/0029.sparql +3 -0
  95. data/spec/xhtml1-testcases/0029.xhtml +17 -0
  96. data/spec/xhtml1-testcases/0030.nt +1 -0
  97. data/spec/xhtml1-testcases/0030.sparql +3 -0
  98. data/spec/xhtml1-testcases/0030.xhtml +16 -0
  99. data/spec/xhtml1-testcases/0031.nt +1 -0
  100. data/spec/xhtml1-testcases/0031.sparql +3 -0
  101. data/spec/xhtml1-testcases/0031.xhtml +14 -0
  102. data/spec/xhtml1-testcases/0032.nt +1 -0
  103. data/spec/xhtml1-testcases/0032.sparql +3 -0
  104. data/spec/xhtml1-testcases/0032.xhtml +15 -0
  105. data/spec/xhtml1-testcases/0033.nt +2 -0
  106. data/spec/xhtml1-testcases/0033.sparql +5 -0
  107. data/spec/xhtml1-testcases/0033.xhtml +19 -0
  108. data/spec/xhtml1-testcases/0034.nt +1 -0
  109. data/spec/xhtml1-testcases/0034.sparql +3 -0
  110. data/spec/xhtml1-testcases/0034.xhtml +14 -0
  111. data/spec/xhtml1-testcases/0035.nt +1 -0
  112. data/spec/xhtml1-testcases/0035.sparql +3 -0
  113. data/spec/xhtml1-testcases/0035.xhtml +17 -0
  114. data/spec/xhtml1-testcases/0036.nt +1 -0
  115. data/spec/xhtml1-testcases/0036.sparql +3 -0
  116. data/spec/xhtml1-testcases/0036.xhtml +17 -0
  117. data/spec/xhtml1-testcases/0037.nt +1 -0
  118. data/spec/xhtml1-testcases/0037.sparql +3 -0
  119. data/spec/xhtml1-testcases/0037.xhtml +18 -0
  120. data/spec/xhtml1-testcases/0038.nt +1 -0
  121. data/spec/xhtml1-testcases/0038.sparql +3 -0
  122. data/spec/xhtml1-testcases/0038.xhtml +14 -0
  123. data/spec/xhtml1-testcases/0039.nt +1 -0
  124. data/spec/xhtml1-testcases/0039.sparql +3 -0
  125. data/spec/xhtml1-testcases/0039.xhtml +17 -0
  126. data/spec/xhtml1-testcases/0040.nt +1 -0
  127. data/spec/xhtml1-testcases/0040.sparql +3 -0
  128. data/spec/xhtml1-testcases/0040.xhtml +16 -0
  129. data/spec/xhtml1-testcases/0041.nt +1 -0
  130. data/spec/xhtml1-testcases/0041.sparql +3 -0
  131. data/spec/xhtml1-testcases/0041.xhtml +18 -0
  132. data/spec/xhtml1-testcases/0042.nt +0 -0
  133. data/spec/xhtml1-testcases/0042.sparql +4 -0
  134. data/spec/xhtml1-testcases/0042.xhtml +15 -0
  135. data/spec/xhtml1-testcases/0046.nt +3 -0
  136. data/spec/xhtml1-testcases/0046.sparql +6 -0
  137. data/spec/xhtml1-testcases/0046.xhtml +13 -0
  138. data/spec/xhtml1-testcases/0047.nt +3 -0
  139. data/spec/xhtml1-testcases/0047.sparql +6 -0
  140. data/spec/xhtml1-testcases/0047.xhtml +13 -0
  141. data/spec/xhtml1-testcases/0048.nt +3 -0
  142. data/spec/xhtml1-testcases/0048.sparql +6 -0
  143. data/spec/xhtml1-testcases/0048.xhtml +14 -0
  144. data/spec/xhtml1-testcases/0049.nt +2 -0
  145. data/spec/xhtml1-testcases/0049.sparql +4 -0
  146. data/spec/xhtml1-testcases/0049.xhtml +14 -0
  147. data/spec/xhtml1-testcases/0050.nt +2 -0
  148. data/spec/xhtml1-testcases/0050.sparql +5 -0
  149. data/spec/xhtml1-testcases/0050.xhtml +14 -0
  150. data/spec/xhtml1-testcases/0051.nt +2 -0
  151. data/spec/xhtml1-testcases/0051.sparql +4 -0
  152. data/spec/xhtml1-testcases/0051.xhtml +12 -0
  153. data/spec/xhtml1-testcases/0052.nt +1 -0
  154. data/spec/xhtml1-testcases/0052.sparql +3 -0
  155. data/spec/xhtml1-testcases/0052.xhtml +13 -0
  156. data/spec/xhtml1-testcases/0053.nt +2 -0
  157. data/spec/xhtml1-testcases/0053.sparql +4 -0
  158. data/spec/xhtml1-testcases/0053.xhtml +13 -0
  159. data/spec/xhtml1-testcases/0054.nt +2 -0
  160. data/spec/xhtml1-testcases/0054.sparql +4 -0
  161. data/spec/xhtml1-testcases/0054.xhtml +14 -0
  162. data/spec/xhtml1-testcases/0055.nt +2 -0
  163. data/spec/xhtml1-testcases/0055.sparql +4 -0
  164. data/spec/xhtml1-testcases/0055.xhtml +16 -0
  165. data/spec/xhtml1-testcases/0056.nt +3 -0
  166. data/spec/xhtml1-testcases/0056.sparql +5 -0
  167. data/spec/xhtml1-testcases/0056.xhtml +13 -0
  168. data/spec/xhtml1-testcases/0057.nt +4 -0
  169. data/spec/xhtml1-testcases/0057.sparql +6 -0
  170. data/spec/xhtml1-testcases/0057.xhtml +14 -0
  171. data/spec/xhtml1-testcases/0058.nt +6 -0
  172. data/spec/xhtml1-testcases/0058.sparql +9 -0
  173. data/spec/xhtml1-testcases/0058.xhtml +14 -0
  174. data/spec/xhtml1-testcases/0059.nt +6 -0
  175. data/spec/xhtml1-testcases/0059.sparql +8 -0
  176. data/spec/xhtml1-testcases/0059.xhtml +16 -0
  177. data/spec/xhtml1-testcases/0060.nt +2 -0
  178. data/spec/xhtml1-testcases/0060.sparql +4 -0
  179. data/spec/xhtml1-testcases/0060.xhtml +14 -0
  180. data/spec/xhtml1-testcases/0061.nt +1 -0
  181. data/spec/xhtml1-testcases/0061.sparql +3 -0
  182. data/spec/xhtml1-testcases/0061.xhtml +11 -0
  183. data/spec/xhtml1-testcases/0062.nt +1 -0
  184. data/spec/xhtml1-testcases/0062.sparql +3 -0
  185. data/spec/xhtml1-testcases/0062.xhtml +12 -0
  186. data/spec/xhtml1-testcases/0063.nt +1 -0
  187. data/spec/xhtml1-testcases/0063.sparql +3 -0
  188. data/spec/xhtml1-testcases/0063.xhtml +11 -0
  189. data/spec/xhtml1-testcases/0064.nt +1 -0
  190. data/spec/xhtml1-testcases/0064.sparql +4 -0
  191. data/spec/xhtml1-testcases/0064.xhtml +13 -0
  192. data/spec/xhtml1-testcases/0065.nt +3 -0
  193. data/spec/xhtml1-testcases/0065.sparql +6 -0
  194. data/spec/xhtml1-testcases/0065.xhtml +22 -0
  195. data/spec/xhtml1-testcases/0066.nt +1 -0
  196. data/spec/xhtml1-testcases/0066.sparql +3 -0
  197. data/spec/xhtml1-testcases/0066.xhtml +11 -0
  198. data/spec/xhtml1-testcases/0067.nt +1 -0
  199. data/spec/xhtml1-testcases/0067.sparql +3 -0
  200. data/spec/xhtml1-testcases/0067.xhtml +11 -0
  201. data/spec/xhtml1-testcases/0068.nt +1 -0
  202. data/spec/xhtml1-testcases/0068.sparql +3 -0
  203. data/spec/xhtml1-testcases/0068.xhtml +14 -0
  204. data/spec/xhtml1-testcases/0069.nt +1 -0
  205. data/spec/xhtml1-testcases/0069.sparql +3 -0
  206. data/spec/xhtml1-testcases/0069.xhtml +14 -0
  207. data/spec/xhtml1-testcases/0070.nt +1 -0
  208. data/spec/xhtml1-testcases/0070.sparql +3 -0
  209. data/spec/xhtml1-testcases/0070.xhtml +13 -0
  210. data/spec/xhtml1-testcases/0071.nt +1 -0
  211. data/spec/xhtml1-testcases/0071.sparql +3 -0
  212. data/spec/xhtml1-testcases/0071.xhtml +16 -0
  213. data/spec/xhtml1-testcases/0072.nt +1 -0
  214. data/spec/xhtml1-testcases/0072.sparql +3 -0
  215. data/spec/xhtml1-testcases/0072.xhtml +16 -0
  216. data/spec/xhtml1-testcases/0073.nt +1 -0
  217. data/spec/xhtml1-testcases/0073.sparql +3 -0
  218. data/spec/xhtml1-testcases/0073.xhtml +16 -0
  219. data/spec/xhtml1-testcases/0074.nt +1 -0
  220. data/spec/xhtml1-testcases/0074.sparql +3 -0
  221. data/spec/xhtml1-testcases/0074.xhtml +16 -0
  222. data/spec/xhtml1-testcases/0075.nt +1 -0
  223. data/spec/xhtml1-testcases/0075.sparql +3 -0
  224. data/spec/xhtml1-testcases/0075.xhtml +16 -0
  225. data/spec/xhtml1-testcases/0076.nt +23 -0
  226. data/spec/xhtml1-testcases/0076.sparql +70 -0
  227. data/spec/xhtml1-testcases/0076.xhtml +35 -0
  228. data/spec/xhtml1-testcases/0077.nt +23 -0
  229. data/spec/xhtml1-testcases/0077.sparql +70 -0
  230. data/spec/xhtml1-testcases/0077.xhtml +58 -0
  231. data/spec/xhtml1-testcases/0078.nt +6 -0
  232. data/spec/xhtml1-testcases/0078.sparql +7 -0
  233. data/spec/xhtml1-testcases/0078.xhtml +15 -0
  234. data/spec/xhtml1-testcases/0079.nt +3 -0
  235. data/spec/xhtml1-testcases/0079.sparql +6 -0
  236. data/spec/xhtml1-testcases/0079.xhtml +15 -0
  237. data/spec/xhtml1-testcases/0080.nt +1 -0
  238. data/spec/xhtml1-testcases/0080.sparql +3 -0
  239. data/spec/xhtml1-testcases/0080.xhtml +13 -0
  240. data/spec/xhtml1-testcases/0081.nt +6 -0
  241. data/spec/xhtml1-testcases/0081.sparql +9 -0
  242. data/spec/xhtml1-testcases/0081.xhtml +15 -0
  243. data/spec/xhtml1-testcases/0082.nt +8 -0
  244. data/spec/xhtml1-testcases/0082.sparql +11 -0
  245. data/spec/xhtml1-testcases/0082.xhtml +15 -0
  246. data/spec/xhtml1-testcases/0083.nt +6 -0
  247. data/spec/xhtml1-testcases/0083.sparql +9 -0
  248. data/spec/xhtml1-testcases/0083.xhtml +15 -0
  249. data/spec/xhtml1-testcases/0084.nt +8 -0
  250. data/spec/xhtml1-testcases/0084.sparql +11 -0
  251. data/spec/xhtml1-testcases/0084.xhtml +18 -0
  252. data/spec/xhtml1-testcases/0085.nt +4 -0
  253. data/spec/xhtml1-testcases/0085.sparql +6 -0
  254. data/spec/xhtml1-testcases/0085.xhtml +17 -0
  255. data/spec/xhtml1-testcases/0086.nt +0 -0
  256. data/spec/xhtml1-testcases/0086.sparql +4 -0
  257. data/spec/xhtml1-testcases/0086.xhtml +13 -0
  258. data/spec/xhtml1-testcases/0087.nt +23 -0
  259. data/spec/xhtml1-testcases/0087.sparql +70 -0
  260. data/spec/xhtml1-testcases/0087.xhtml +35 -0
  261. data/spec/xhtml1-testcases/0088.nt +3 -0
  262. data/spec/xhtml1-testcases/0088.sparql +6 -0
  263. data/spec/xhtml1-testcases/0088.xhtml +14 -0
  264. data/spec/xhtml1-testcases/0089.nt +1 -0
  265. data/spec/xhtml1-testcases/0089.sparql +3 -0
  266. data/spec/xhtml1-testcases/0089.xhtml +13 -0
  267. data/spec/xhtml1-testcases/0090.nt +1 -0
  268. data/spec/xhtml1-testcases/0090.sparql +3 -0
  269. data/spec/xhtml1-testcases/0090.xhtml +16 -0
  270. data/spec/xhtml1-testcases/0091.nt +3 -0
  271. data/spec/xhtml1-testcases/0091.sparql +6 -0
  272. data/spec/xhtml1-testcases/0091.xhtml +16 -0
  273. data/spec/xhtml1-testcases/0092.nt +3 -0
  274. data/spec/xhtml1-testcases/0092.sparql +16 -0
  275. data/spec/xhtml1-testcases/0092.xhtml +15 -0
  276. data/spec/xhtml1-testcases/0093.nt +2 -0
  277. data/spec/xhtml1-testcases/0093.sparql +4 -0
  278. data/spec/xhtml1-testcases/0093.xhtml +15 -0
  279. data/spec/xhtml1-testcases/0094.nt +3 -0
  280. data/spec/xhtml1-testcases/0094.sparql +16 -0
  281. data/spec/xhtml1-testcases/0094.xhtml +15 -0
  282. data/spec/xhtml1-testcases/0099.nt +1 -0
  283. data/spec/xhtml1-testcases/0099.sparql +3 -0
  284. data/spec/xhtml1-testcases/0099.xhtml +20 -0
  285. data/spec/xhtml1-testcases/0100.nt +3 -0
  286. data/spec/xhtml1-testcases/0100.sparql +15 -0
  287. data/spec/xhtml1-testcases/0100.xhtml +16 -0
  288. data/spec/xhtml1-testcases/0101.nt +3 -0
  289. data/spec/xhtml1-testcases/0101.sparql +15 -0
  290. data/spec/xhtml1-testcases/0101.xhtml +16 -0
  291. data/spec/xhtml1-testcases/0102.nt +1 -0
  292. data/spec/xhtml1-testcases/0102.sparql +15 -0
  293. data/spec/xhtml1-testcases/0102.xhtml +16 -0
  294. data/spec/xhtml1-testcases/0103.nt +1 -0
  295. data/spec/xhtml1-testcases/0103.sparql +15 -0
  296. data/spec/xhtml1-testcases/0103.xhtml +15 -0
  297. data/spec/xhtml1-testcases/0104.nt +3 -0
  298. data/spec/xhtml1-testcases/0104.sparql +5 -0
  299. data/spec/xhtml1-testcases/0104.xhtml +18 -0
  300. data/spec/xhtml1-testcases/0105.nt +1 -0
  301. data/spec/xhtml1-testcases/0105.sparql +7 -0
  302. data/spec/xhtml1-testcases/0105.xhtml +13 -0
  303. data/spec/xhtml1-testcases/0106.nt +1 -0
  304. data/spec/xhtml1-testcases/0106.sparql +7 -0
  305. data/spec/xhtml1-testcases/0106.xhtml +13 -0
  306. data/spec/xhtml1-testcases/0107.nt +0 -0
  307. data/spec/xhtml1-testcases/0107.sparql +4 -0
  308. data/spec/xhtml1-testcases/0107.xhtml +11 -0
  309. data/spec/xhtml1-testcases/0108.nt +1 -0
  310. data/spec/xhtml1-testcases/0108.sparql +3 -0
  311. data/spec/xhtml1-testcases/0108.xhtml +14 -0
  312. data/spec/xhtml1-testcases/0109.nt +1 -0
  313. data/spec/xhtml1-testcases/0109.sparql +3 -0
  314. data/spec/xhtml1-testcases/0109.xhtml +15 -0
  315. data/spec/xhtml1-testcases/0110.nt +1 -0
  316. data/spec/xhtml1-testcases/0110.sparql +4 -0
  317. data/spec/xhtml1-testcases/0110.xhtml +12 -0
  318. data/spec/xhtml1-testcases/0111.nt +2 -0
  319. data/spec/xhtml1-testcases/0111.sparql +5 -0
  320. data/spec/xhtml1-testcases/0111.xhtml +14 -0
  321. data/spec/xhtml1-testcases/0112.nt +1 -0
  322. data/spec/xhtml1-testcases/0112.sparql +3 -0
  323. data/spec/xhtml1-testcases/0112.xhtml +16 -0
  324. data/spec/xhtml1-testcases/0113.nt +2 -0
  325. data/spec/xhtml1-testcases/0113.sparql +4 -0
  326. data/spec/xhtml1-testcases/0113.xhtml +12 -0
  327. data/spec/xhtml1-testcases/0114.nt +3 -0
  328. data/spec/xhtml1-testcases/0114.sparql +5 -0
  329. data/spec/xhtml1-testcases/0114.xhtml +15 -0
  330. data/spec/xhtml1-testcases/0115.nt +4 -0
  331. data/spec/xhtml1-testcases/0115.sparql +14 -0
  332. data/spec/xhtml1-testcases/0115.xhtml +17 -0
  333. data/spec/xhtml1-testcases/0116.nt +2 -0
  334. data/spec/xhtml1-testcases/0116.sparql +6 -0
  335. data/spec/xhtml1-testcases/0116.xhtml +10 -0
  336. data/spec/xhtml1-testcases/0117.nt +2 -0
  337. data/spec/xhtml1-testcases/0117.sparql +4 -0
  338. data/spec/xhtml1-testcases/0117.xhtml +15 -0
  339. data/spec/xhtml1-testcases/0118.nt +1 -0
  340. data/spec/xhtml1-testcases/0118.sparql +5 -0
  341. data/spec/xhtml1-testcases/0118.xhtml +16 -0
  342. data/spec/xhtml1-testcases/0119.nt +1 -0
  343. data/spec/xhtml1-testcases/0119.sparql +5 -0
  344. data/spec/xhtml1-testcases/0119.xhtml +19 -0
  345. data/spec/xhtml1-testcases/0120.nt +1 -0
  346. data/spec/xhtml1-testcases/0120.sparql +5 -0
  347. data/spec/xhtml1-testcases/0120.xhtml +17 -0
  348. data/spec/xhtml1-testcases/0121.nt +2 -0
  349. data/spec/xhtml1-testcases/0121.sparql +4 -0
  350. data/spec/xhtml1-testcases/0121.xhtml +24 -0
  351. data/spec/xhtml1-testcases/0122.nt +1 -0
  352. data/spec/xhtml1-testcases/0122.sparql +4 -0
  353. data/spec/xhtml1-testcases/0122.xhtml +16 -0
  354. data/spec/xhtml1-testcases/0123.nt +3 -0
  355. data/spec/xhtml1-testcases/0123.sparql +5 -0
  356. data/spec/xhtml1-testcases/0123.xhtml +18 -0
  357. data/spec/xhtml1-testcases/0124.nt +4 -0
  358. data/spec/xhtml1-testcases/0124.sparql +6 -0
  359. data/spec/xhtml1-testcases/0124.xhtml +14 -0
  360. data/spec/xhtml1-testcases/0125.nt +1 -0
  361. data/spec/xhtml1-testcases/0125.sparql +5 -0
  362. data/spec/xhtml1-testcases/0125.xhtml +16 -0
  363. data/spec/xhtml1-testcases/0126.nt +3 -0
  364. data/spec/xhtml1-testcases/0126.sparql +5 -0
  365. data/spec/xhtml1-testcases/0126.xhtml +15 -0
  366. data/spec/xhtml1-testcases/1001.nt +6 -0
  367. data/spec/xhtml1-testcases/1001.sparql +8 -0
  368. data/spec/xhtml1-testcases/1001.xhtml +20 -0
  369. data/spec/xhtml1-testcases/9999.nt +3 -0
  370. data/spec/xhtml1-testcases/9999.xhtml +14 -0
  371. data/spec/xhtml1-testcases/rdfa-xhtml1-test-manifest.rdf +1303 -0
  372. data/tasks/rspec.rake +21 -0
  373. metadata +485 -0
@@ -0,0 +1,415 @@
1
+ ##
2
+ # An RDFa parser in Ruby
3
+ #
4
+ # Based on processing rules described here: http://www.w3.org/TR/rdfa-syntax/#s_model
5
+ #
6
+ # Ben Adida
7
+ # 2008-05-07
8
+ # Gregg Kellogg
9
+ # 2009-08-04
10
+
11
+ module RdfaParser
12
+ # a new RDFa Parser MUST be instantiated for every parsed document
13
+ class RdfaParser
14
+ attr_reader :debug
15
+ attr_reader :graph
16
+ attr_reader :namespace
17
+
18
+ # The Recursive Baggage
19
+ class EvaluationContext # :nodoc: all
20
+ attr :base, true
21
+ attr :parent_subject, true
22
+ attr :parent_object, true
23
+ attr :uri_mappings, true
24
+ attr :incomplete_triples, true
25
+ attr :language, true
26
+
27
+ def initialize(base)
28
+ # Initialize the evaluation context, [5.1]
29
+ @base = base
30
+ @parent_subject = @base
31
+ @parent_object = nil
32
+ @uri_mappings = {}
33
+ @incomplete_triples = []
34
+ @language = nil
35
+ end
36
+
37
+ def initialize_copy(from)
38
+ # clone the evaluation context correctly
39
+ @uri_mappings = from.uri_mappings.clone
40
+ @incomplete_triples = from.incomplete_triples.clone
41
+ end
42
+
43
+ def inspect
44
+ v = %w(base parent_subject parent_object language).map {|a| "#{a}='#{self.send(a).nil? ? 'nil' : self.send(a)}'"}
45
+ v << "uri_mappings[#{uri_mappings.keys.length}]"
46
+ v << "incomplete_triples[#{incomplete_triples.length}]"
47
+ v.join(",")
48
+ end
49
+ end
50
+
51
+ # Create new parser instance. Options:
52
+ # _graph_:: Graph to parse into, otherwie a new RdfaParser::Graph instance is created
53
+ def initialize(options = {})
54
+ options = {:graph => Graph.new}.merge(options)
55
+ @debug = []
56
+ BNode.reset # Start sequence anew
57
+
58
+ # initialize the triplestore
59
+ @graph = options[:graph]
60
+ end
61
+
62
+ # Parse XHRML+RDFa document from a string or input stream to closure or graph.
63
+ # _base_ indicates the base URI of the document.
64
+ #
65
+ # Optionally, the stream may be a Nokogiri::HTML::Document or Nokogiri::XML::Document
66
+ # With a block, yeilds each statement with URIRef, BNode or Literal elements
67
+ #
68
+ # The namespace for the HTML is intuited from the encoding. This code supports the following
69
+ # XHTML1:: http://www.w3.org/1999/xhtml This can also be determined by <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
70
+ # HTML4::
71
+ # HTML5::
72
+ # Options:
73
+ # profile:: One of _xhtml1_, _html4_, or _html5_ to override intuition
74
+ #
75
+ # Raises RdfaParser::RdfaException or subclass
76
+ def parse(stream, base, options = {}, &block) # :yields: triple
77
+ @doc = case stream
78
+ when Nokogiri::HTML::Document then stream
79
+ when Nokogiri::XML::Document then stream
80
+ else Nokogiri::XML.parse(stream, base)
81
+ end
82
+ @base = base.to_s
83
+ raise ParserException, "Empty document" if @doc.nil?
84
+ @callback = block
85
+
86
+ # If the doc has a default, use that as "html"
87
+ ns = @doc.namespaces["xmlns"]
88
+ ns ||= "http://www.w3.org/1999/xhtml" # FIXME: intuite from DOCTYPE, or however
89
+ @namespace = Namespace.new(ns, "html") if ns
90
+
91
+ # parse
92
+ parse_whole_document(@doc, @base)
93
+
94
+ @graph
95
+ end
96
+
97
+ protected
98
+
99
+ # add a triple, object can be literal or URI or bnode
100
+ def add_triple(node, subject, predicate, object)
101
+ add_debug(node, "triple: #{subject}, #{predicate}, #{object}")
102
+ triple = Triple.new(subject, predicate, object)
103
+ if @callback
104
+ @callback.call(triple) # Perform yield to saved block
105
+ else
106
+ @graph << triple
107
+ end
108
+ triple
109
+ end
110
+
111
+ # Parsing an RDFa document (this is *not* the recursive method)
112
+ def parse_whole_document(doc, base)
113
+ # find if the document has a base element
114
+ base_el = doc.xpath('/html:html/html:head/html:base', @namespace.xmlns_hash).first
115
+ if (base_el)
116
+ base = base_el.attributes['href']
117
+ # Strip any fragment from base
118
+ base = base.to_s.split("#").first
119
+ add_debug(base_el, "parse_whole_doc: base='#{base}'")
120
+ end
121
+
122
+ # initialize the evaluation context with the appropriate base
123
+ evaluation_context= EvaluationContext.new(base)
124
+
125
+ self.traverse(doc.root, evaluation_context)
126
+ end
127
+
128
+ # Extract the XMLNS mappings from an element
129
+ def extract_mappings(element)
130
+ mappings = {}
131
+
132
+ # look for xmlns
133
+ element.namespaces.each do |attr_name,attr_value|
134
+ abbr, suffix = attr_name.split(":")
135
+ mappings[suffix] = @graph.namespace(attr_value, suffix) if abbr == "xmlns"
136
+ end
137
+
138
+ add_debug(element, "mappings: #{mappings.keys.join(", ")}")
139
+ mappings
140
+ end
141
+
142
+ def node_path(node)
143
+ node.is_a?(Nokogiri::XML::Element) ? "#{node_path(node.parent)}/#{node.name}" : ""
144
+ end
145
+
146
+ def add_debug(node, message)
147
+ puts "#{node_path(node)}: #{message}" if $DEBUG
148
+ @debug << "#{node_path(node)}: #{message}"
149
+ end
150
+
151
+ # The recursive helper function
152
+ def traverse(element, evaluation_context)
153
+ raise ParserException, "Can't parse nil element" if element.nil?
154
+
155
+ # local variables [5.5 Step 1]
156
+ recurse = true
157
+ skip = false
158
+ new_subject = nil
159
+ current_object_resource = nil
160
+ uri_mappings = evaluation_context.uri_mappings.clone
161
+ incomplete_triples = []
162
+ language = evaluation_context.language
163
+
164
+ # shortcut
165
+ attrs = element.attributes
166
+
167
+ about = attrs['about']
168
+ src = attrs['src']
169
+ resource = attrs['resource']
170
+ href = attrs['href']
171
+
172
+ # Pull out the attributes needed for the skip test.
173
+ property = attrs['property'].to_s if attrs['property']
174
+ typeof = attrs['typeof'].to_s if attrs['typeof']
175
+ datatype = attrs['datatype'].to_s if attrs['datatype']
176
+ content = attrs['content'].to_s if attrs['content']
177
+ rel = attrs['rel'].to_s if attrs['rel']
178
+ rev = attrs['rev'].to_s if attrs['rev']
179
+
180
+ # SPEC CONFUSION: not sure what to initialize this value to
181
+ current_object_literal = nil
182
+
183
+ # XMLNS mappings [5.5 Step 2]
184
+ uri_mappings.merge!(extract_mappings(element))
185
+
186
+ # Language information [5.5 Step 3]
187
+ add_debug(element, "traverse, lang: #{attrs['lang']}") if attrs['lang']
188
+ language = attrs['lang'] || language
189
+
190
+ # rels and revs
191
+ rels = parse_curies(rel, uri_mappings, evaluation_context.base, true)
192
+ revs = parse_curies(rev, uri_mappings, evaluation_context.base, true)
193
+ valid_rel_or_rev = !(rel.nil? && rev.nil?)
194
+
195
+ add_debug(element, "traverse, ec: #{evaluation_context.inspect}")
196
+ add_debug(element, "traverse, about: #{about.nil? ? 'nil' : about}, src: #{src.nil? ? 'nil' : src}, resource: #{resource.nil? ? 'nil' : resource}, href: #{href.nil? ? 'nil' : href}")
197
+ add_debug(element, "traverse, property: #{property.nil? ? 'nil' : property}, typeof: #{typeof.nil? ? 'nil' : typeof}, datatype: #{datatype.nil? ? 'nil' : datatype}, content: #{content.nil? ? 'nil' : content}")
198
+ add_debug(element, "traverse, rels: #{rels.join(" ")}, revs: #{revs.join(" ")}")
199
+
200
+ if not valid_rel_or_rev
201
+ # Establishing a new subject if no valid rel/rev [5.5 Step 4]
202
+ if about
203
+ new_subject = uri_or_safe_curie(about, evaluation_context, uri_mappings)
204
+ elsif src
205
+ new_subject = URIRef.new(src, evaluation_context.base)
206
+ elsif resource
207
+ new_subject = uri_or_safe_curie(resource, evaluation_context, uri_mappings)
208
+ elsif href
209
+ new_subject = URIRef.new(href, evaluation_context.base)
210
+ end
211
+
212
+ # SPEC CONFUSION: not sure what "If no URI is provided by a resource attribute" means, I assume
213
+ # it means that new_subject is still null
214
+ if new_subject.nil?
215
+ if element.name =~ /^(head|body)$/
216
+ new_subject = URIRef.new(evaluation_context.base)
217
+ elsif element.attributes['typeof']
218
+ new_subject = BNode.new
219
+ else
220
+ # if it's null, it's null and nothing changes
221
+ new_subject = evaluation_context.parent_object
222
+ skip = true unless property
223
+ end
224
+ end
225
+ add_debug(element, "new_subject: #{new_subject}, skip = #{skip}")
226
+ else
227
+ # Establish both new subject and current object resource [5.5 Step 5]
228
+
229
+ if about
230
+ new_subject = uri_or_safe_curie(about, evaluation_context, uri_mappings)
231
+ elsif src
232
+ new_subject = uri_or_safe_curie(src, evaluation_context, uri_mappings)
233
+ end
234
+
235
+ # If no URI is provided then the first match from the following rules will apply
236
+ if new_subject.nil?
237
+ if element.name =~ /^(head|body)$/
238
+ new_subject = URIRef.new(evaluation_context.base)
239
+ elsif element.attributes['typeof']
240
+ new_subject = BNode.new
241
+ else
242
+ # if it's null, it's null and nothing changes
243
+ new_subject = evaluation_context.parent_object
244
+ # no skip flag set this time
245
+ end
246
+ end
247
+
248
+ if resource
249
+ current_object_resource = uri_or_safe_curie(resource, evaluation_context, uri_mappings)
250
+ elsif href
251
+ current_object_resource = URIRef.new(href, evaluation_context.base)
252
+ end
253
+
254
+ add_debug(element, "new_subject: #{new_subject}, current_object_resource = #{current_object_resource.nil? ? 'nil' : current_object_resource}")
255
+ end
256
+
257
+ # Process @typeof if there is a subject [Step 6]
258
+ if new_subject and typeof
259
+ types = parse_curies(typeof, uri_mappings, evaluation_context.base, false)
260
+ add_debug(element, "typeof: #{typeof}")
261
+ types.each do |one_type|
262
+ add_triple(element, new_subject, RDF_TYPE, one_type)
263
+ end
264
+ end
265
+
266
+ # Generate triples with given object [Step 7]
267
+ if current_object_resource
268
+ rels.each do |rel|
269
+ add_triple(element, new_subject, rel, current_object_resource)
270
+ end
271
+
272
+ revs.each do |rev|
273
+ add_triple(element, current_object_resource, rev, new_subject)
274
+ end
275
+ else
276
+ # Incomplete triples and bnode creation [Step 8]
277
+ add_debug(element, "step 8: valid: #{valid_rel_or_rev}, rels: #{rels}, revs: #{revs}")
278
+ current_object_resource = BNode.new if valid_rel_or_rev
279
+
280
+ rels.each do |rel|
281
+ # SPEC CONFUSION: we don't store the subject here?
282
+ incomplete_triples << {:predicate => rel, :direction => :forward}
283
+ end
284
+
285
+ revs.each do |rev|
286
+ # SPEC CONFUSION: we don't store the object here?
287
+ incomplete_triples << {:predicate => rev, :direction => :reverse}
288
+ end
289
+
290
+ end
291
+
292
+ # Establish current object literal [Step 9]
293
+ if property
294
+ properties = parse_curies(property, uri_mappings, evaluation_context.base, false)
295
+
296
+ # get the literal datatype
297
+ type = datatype
298
+ children_node_types = element.children.collect{|c| c.class}.uniq
299
+
300
+ # the following 3 IF clauses should be mutually exclusive. Written as is to prevent extensive indentation.
301
+
302
+ # SPEC CONFUSION: have to special case XML Literal, not clear right away.
303
+ # SPEC CONFUSION: specify that the conditions are in order of priority
304
+ type_resource = curie_to_resource_or_bnode(type, uri_mappings, evaluation_context.base) if type
305
+ if type and !type.empty? and (type_resource.to_s != XML_LITERAL.to_s)
306
+ # typed literal
307
+ add_debug(element, "typed literal")
308
+ current_object_literal = Literal.typed(content || element.inner_text, type_resource, :language => language)
309
+ elsif content or (children_node_types == [Nokogiri::XML::Text]) or (element.children.length == 0) or (type == '')
310
+ # plain literal
311
+ add_debug(element, "plain literal")
312
+ current_object_literal = Literal.untyped(content || element.inner_text, language)
313
+ elsif children_node_types != [Nokogiri::XML::Text] and (type == nil or type_resource.to_s == XML_LITERAL.to_s)
314
+ # XML Literal
315
+ add_debug(element, "XML Literal: #{element.inner_html}")
316
+ current_object_literal = Literal.typed(element.inner_html, XML_LITERAL, :language => language, :namespaces => uri_mappings)
317
+ recurse = false
318
+ end
319
+
320
+ # add each property
321
+ properties.each do |property|
322
+ add_triple(element, new_subject, property, current_object_literal)
323
+ end
324
+
325
+ # SPEC CONFUSION: "the triple has been created" ==> there may be more than one
326
+ # set the recurse flag above in the IF about xmlliteral, as it is the only place that can happen
327
+ end
328
+
329
+ # Complete the incomplete triples from the evaluation context [Step 10]
330
+ add_debug(element, "10: skip=#{skip}, new_subject=#{new_subject}")
331
+ if not skip and new_subject
332
+ evaluation_context.incomplete_triples.each do |trip|
333
+ if trip[:direction] == :forward
334
+ add_triple(element, evaluation_context.parent_subject, trip[:predicate], new_subject)
335
+ elsif trip[:direction] == :reverse
336
+ add_triple(element, new_subject, trip[:predicate], evaluation_context.parent_subject)
337
+ end
338
+ end
339
+ end
340
+
341
+ # Create a new evaluation context and proceed recursively [Step 11]
342
+ if recurse
343
+ # SPEC CONFUSION: new evaluation context for each child? Probably not necessary,
344
+ # but maybe needs to be pointed out?
345
+
346
+ if skip
347
+ new_ec = evaluation_context.clone
348
+ new_ec.language = language
349
+ new_ec.uri_mappings = uri_mappings
350
+ add_debug(element, "skip: cloned ec: #{evaluation_context.inspect}")
351
+ else
352
+ # create a new evaluation context
353
+ new_ec = EvaluationContext.new(evaluation_context.base)
354
+ new_ec.parent_subject = new_subject || evaluation_context.parent_subject
355
+ new_ec.parent_object = current_object_resource || new_subject || evaluation_context.parent_subject
356
+ new_ec.uri_mappings = uri_mappings
357
+ new_ec.incomplete_triples = incomplete_triples
358
+ new_ec.language = language
359
+ #add_debug(element, "new ec: #{new_ec.inspect}")
360
+ end
361
+
362
+ element.children.each do |child|
363
+ # recurse only if it's an element
364
+ self.traverse(child, new_ec) if child.class == Nokogiri::XML::Element
365
+ end
366
+ end
367
+ end
368
+
369
+ # space-separated CURIEs or Link Types
370
+ def parse_curies(value, uri_mappings, base, with_link_types=false)
371
+ return [] unless value
372
+ resource_array = []
373
+ value.to_s.split(' ').each do |curie|
374
+ if curie.include?(":")
375
+ resource_array << curie_to_resource_or_bnode(curie, uri_mappings, base)
376
+ elsif with_link_types
377
+ link_type_curie = curie_to_resource_or_bnode(":#{value}", XH_MAPPING, base) if LINK_TYPES.include?(value.to_s)
378
+ resource_array << link_type_curie if link_type_curie
379
+ end
380
+ end
381
+ resource_array
382
+ end
383
+
384
+ def curie_to_resource_or_bnode(curie, uri_mappings, subject)
385
+ # URI mappings for CURIEs default to XH_MAPPING, rather than the default doc namespace
386
+ uri_mappings = uri_mappings.merge(XH_MAPPING)
387
+ prefix, suffix = curie.to_s.split(":")
388
+
389
+ # consider the bnode situation
390
+ if prefix == "_"
391
+ # we force a non-nil name, otherwise it generates a new name
392
+ BNode.new(suffix || "")
393
+ elsif curie.to_s.empty?
394
+ @debug << "curie_to_resource_or_bnode #{URIRef.new(subject)}"
395
+ # Empty curie resolves to current subject
396
+ URIRef.new(subject)
397
+ else
398
+ ns = uri_mappings[prefix.to_s]
399
+ raise ParserException, "No namespace mapping for #{prefix}" unless ns
400
+ ns + suffix
401
+ end
402
+ end
403
+
404
+ def uri_or_safe_curie(value, evaluation_context, uri_mappings)
405
+ return nil if value.nil?
406
+
407
+ # check if the value is [foo:bar]
408
+ if value.to_s.match(/^\[(.*)\]$/)
409
+ curie_to_resource_or_bnode($1, uri_mappings, evaluation_context.parent_subject)
410
+ else
411
+ URIRef.new(value, evaluation_context.base)
412
+ end
413
+ end
414
+ end
415
+ end
@@ -0,0 +1,100 @@
1
+ module RdfaParser
2
+ # Triple from Reddy, to aid it merger
3
+ class Triple
4
+ attr_accessor :subject, :object, :predicate
5
+
6
+ ##
7
+ # Creates a new triple directly from the intended subject, predicate, and object.
8
+ #
9
+ # ==== Example
10
+ # Triple.new(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new) # => results in the creation of a new triple and returns it
11
+ #
12
+ # @param [URIRef, BNode] s the subject of the triple
13
+ # @param [URIRef] p the predicate of the triple
14
+ # @param [URIRef, BNode, Literal, TypedLiteral] o the object of the triple
15
+ #
16
+ # ==== Returns
17
+ #
18
+ # @return [Triple] An array of the triples (leaky abstraction? consider returning the graph instead)
19
+ #
20
+ # @raise [Error] Checks parameter types and raises if they are incorrect.
21
+ # @author Tom Morris
22
+ def initialize (subject, predicate, object)
23
+ @subject = self.class.coerce_subject(subject)
24
+ @predicate = self.class.coerce_predicate(predicate)
25
+ @object = self.class.coerce_object(object)
26
+ end
27
+
28
+ def to_ntriples
29
+ @subject.to_ntriples + " " + @predicate.to_ntriples + " " + @object.to_ntriples + " ."
30
+ end
31
+
32
+ def to_s; self.to_ntriples; end
33
+
34
+ def inspect
35
+ [@subject, @predicate, @object].inspect
36
+ end
37
+
38
+ def is_type?
39
+ @predicate.to_s == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
40
+ end
41
+
42
+ def eql? (other)
43
+ other.is_a?(self.class) &&
44
+ other.subject == self.subject &&
45
+ other.predicate == self.predicate &&
46
+ other.object == self.object
47
+ end
48
+
49
+ alias_method :==, :eql?
50
+
51
+ protected
52
+
53
+ def self.coerce_subject(subject)
54
+ case subject
55
+ when Addressable::URI
56
+ URIRef.new(subject.to_s)
57
+ when URIRef, BNode
58
+ subject
59
+ when String
60
+ if subject =~ /\S+\/\/\S+/ # does it smell like a URI?
61
+ URIRef.new subject
62
+ else
63
+ BNode.new subject
64
+ end
65
+ else
66
+ raise InvalidSubject, "Subject is not of a known class (#{subject.class}: #{subject.inspect})"
67
+ end
68
+ end
69
+
70
+ def self.coerce_predicate(uri_or_string)
71
+ case uri_or_string
72
+ when URIRef
73
+ uri_or_string
74
+ when String
75
+ URIRef.new uri_or_string
76
+ else
77
+ raise InvalidPredicate, "Predicate should be a URI"
78
+ end
79
+ rescue UriRelativeException => e
80
+ raise InvalidPredicate, "Couldn't make a URIRef: #{e.message}"
81
+ end
82
+
83
+ def self.coerce_object(object)
84
+ case object
85
+ when Addressable::URI
86
+ URIRef.new(object.to_s)
87
+ when String, Integer, Float
88
+ if object.to_s =~ /\S+\/\/\S+/ # does it smell like a URI?
89
+ URIRef.new(object.to_s)
90
+ else
91
+ Literal.new(object, nil, nil)
92
+ end
93
+ when URIRef, BNode, Literal
94
+ object
95
+ else
96
+ raise InvalidObject, "#{object.class}: #{object.inspect} is not a valid object"
97
+ end
98
+ end
99
+ end
100
+ end