qwik2md 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (335) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/README.md +36 -0
  6. data/Rakefile +10 -0
  7. data/bin/console +14 -0
  8. data/bin/setup +8 -0
  9. data/exe/qwik2md +17 -0
  10. data/lib/qwik2md/version.rb +3 -0
  11. data/lib/qwik2md.rb +39 -0
  12. data/qwik2md.gemspec +30 -0
  13. data/vendor/qwik/AUTHORS +10 -0
  14. data/vendor/qwik/COPYING +340 -0
  15. data/vendor/qwik/COPYRIGHT +346 -0
  16. data/vendor/qwik/lib/qwik/Makefile +63 -0
  17. data/vendor/qwik/lib/qwik/Rakefile +17 -0
  18. data/vendor/qwik/lib/qwik/act-aa.rb +83 -0
  19. data/vendor/qwik/lib/qwik/act-archive.rb +386 -0
  20. data/vendor/qwik/lib/qwik/act-attach.rb +304 -0
  21. data/vendor/qwik/lib/qwik/act-backup.rb +236 -0
  22. data/vendor/qwik/lib/qwik/act-basic.rb +325 -0
  23. data/vendor/qwik/lib/qwik/act-book.rb +161 -0
  24. data/vendor/qwik/lib/qwik/act-calc.rb +371 -0
  25. data/vendor/qwik/lib/qwik/act-charset.rb +251 -0
  26. data/vendor/qwik/lib/qwik/act-christel.rb +112 -0
  27. data/vendor/qwik/lib/qwik/act-chronology.rb +149 -0
  28. data/vendor/qwik/lib/qwik/act-code.rb +155 -0
  29. data/vendor/qwik/lib/qwik/act-comment.rb +554 -0
  30. data/vendor/qwik/lib/qwik/act-config.rb +49 -0
  31. data/vendor/qwik/lib/qwik/act-counter.rb +125 -0
  32. data/vendor/qwik/lib/qwik/act-day.rb +96 -0
  33. data/vendor/qwik/lib/qwik/act-describe.rb +135 -0
  34. data/vendor/qwik/lib/qwik/act-diary.rb +109 -0
  35. data/vendor/qwik/lib/qwik/act-edit.rb +317 -0
  36. data/vendor/qwik/lib/qwik/act-embed-html.rb +296 -0
  37. data/vendor/qwik/lib/qwik/act-emode.rb +150 -0
  38. data/vendor/qwik/lib/qwik/act-event.rb +187 -0
  39. data/vendor/qwik/lib/qwik/act-file.rb +303 -0
  40. data/vendor/qwik/lib/qwik/act-files.rb +771 -0
  41. data/vendor/qwik/lib/qwik/act-getpass.rb +295 -0
  42. data/vendor/qwik/lib/qwik/act-history.rb +136 -0
  43. data/vendor/qwik/lib/qwik/act-html.rb +204 -0
  44. data/vendor/qwik/lib/qwik/act-httpauth.rb +147 -0
  45. data/vendor/qwik/lib/qwik/act-include.rb +142 -0
  46. data/vendor/qwik/lib/qwik/act-interwiki.rb +189 -0
  47. data/vendor/qwik/lib/qwik/act-isearch.rb +109 -0
  48. data/vendor/qwik/lib/qwik/act-keywords.rb +137 -0
  49. data/vendor/qwik/lib/qwik/act-lang.rb +81 -0
  50. data/vendor/qwik/lib/qwik/act-license.rb +63 -0
  51. data/vendor/qwik/lib/qwik/act-list.rb +287 -0
  52. data/vendor/qwik/lib/qwik/act-login.rb +410 -0
  53. data/vendor/qwik/lib/qwik/act-logout.rb +60 -0
  54. data/vendor/qwik/lib/qwik/act-mail.rb +159 -0
  55. data/vendor/qwik/lib/qwik/act-map.rb +292 -0
  56. data/vendor/qwik/lib/qwik/act-md5.rb +42 -0
  57. data/vendor/qwik/lib/qwik/act-mdlb.rb +741 -0
  58. data/vendor/qwik/lib/qwik/act-media.rb +416 -0
  59. data/vendor/qwik/lib/qwik/act-member.rb +157 -0
  60. data/vendor/qwik/lib/qwik/act-menu.rb +142 -0
  61. data/vendor/qwik/lib/qwik/act-metadata.rb +323 -0
  62. data/vendor/qwik/lib/qwik/act-mlsubmitform.rb +49 -0
  63. data/vendor/qwik/lib/qwik/act-monitor.rb +167 -0
  64. data/vendor/qwik/lib/qwik/act-new.rb +418 -0
  65. data/vendor/qwik/lib/qwik/act-pagelist.rb +248 -0
  66. data/vendor/qwik/lib/qwik/act-password.rb +145 -0
  67. data/vendor/qwik/lib/qwik/act-plan.rb +210 -0
  68. data/vendor/qwik/lib/qwik/act-povray.rb +230 -0
  69. data/vendor/qwik/lib/qwik/act-presen.rb +380 -0
  70. data/vendor/qwik/lib/qwik/act-redirect.rb +133 -0
  71. data/vendor/qwik/lib/qwik/act-ring.rb +1071 -0
  72. data/vendor/qwik/lib/qwik/act-rrefs.rb +255 -0
  73. data/vendor/qwik/lib/qwik/act-ruby.rb +116 -0
  74. data/vendor/qwik/lib/qwik/act-sample.rb +170 -0
  75. data/vendor/qwik/lib/qwik/act-save.rb +295 -0
  76. data/vendor/qwik/lib/qwik/act-schedule.rb +374 -0
  77. data/vendor/qwik/lib/qwik/act-search.rb +180 -0
  78. data/vendor/qwik/lib/qwik/act-searchwords.rb +51 -0
  79. data/vendor/qwik/lib/qwik/act-sendpass.rb +83 -0
  80. data/vendor/qwik/lib/qwik/act-site.rb +89 -0
  81. data/vendor/qwik/lib/qwik/act-sitebackup.rb +419 -0
  82. data/vendor/qwik/lib/qwik/act-sitelog.rb +118 -0
  83. data/vendor/qwik/lib/qwik/act-smil.rb +299 -0
  84. data/vendor/qwik/lib/qwik/act-status.rb +220 -0
  85. data/vendor/qwik/lib/qwik/act-style.rb +608 -0
  86. data/vendor/qwik/lib/qwik/act-table.rb +263 -0
  87. data/vendor/qwik/lib/qwik/act-tableform.rb +241 -0
  88. data/vendor/qwik/lib/qwik/act-tag.rb +103 -0
  89. data/vendor/qwik/lib/qwik/act-text.rb +70 -0
  90. data/vendor/qwik/lib/qwik/act-textarea.rb +164 -0
  91. data/vendor/qwik/lib/qwik/act-theme.rb +346 -0
  92. data/vendor/qwik/lib/qwik/act-toc.rb +112 -0
  93. data/vendor/qwik/lib/qwik/act-typekey.rb +198 -0
  94. data/vendor/qwik/lib/qwik/act-under-const.rb +94 -0
  95. data/vendor/qwik/lib/qwik/act-webservice.rb +321 -0
  96. data/vendor/qwik/lib/qwik/act-wema.rb +558 -0
  97. data/vendor/qwik/lib/qwik/act-wysiwyg.rb +238 -0
  98. data/vendor/qwik/lib/qwik/action.rb +325 -0
  99. data/vendor/qwik/lib/qwik/autoreload.rb +98 -0
  100. data/vendor/qwik/lib/qwik/bench-bench.rb +28 -0
  101. data/vendor/qwik/lib/qwik/bench-emode.rb +47 -0
  102. data/vendor/qwik/lib/qwik/bench-format-xml.rb +70 -0
  103. data/vendor/qwik/lib/qwik/bench-large-table.rb +62 -0
  104. data/vendor/qwik/lib/qwik/bench-md5.rb +14 -0
  105. data/vendor/qwik/lib/qwik/bench-module-session.rb +19 -0
  106. data/vendor/qwik/lib/qwik/bench-page.rb +50 -0
  107. data/vendor/qwik/lib/qwik/bench-s-md5.rb +28 -0
  108. data/vendor/qwik/lib/qwik/bench-session.rb +25 -0
  109. data/vendor/qwik/lib/qwik/bench-textformat.rb +31 -0
  110. data/vendor/qwik/lib/qwik/catalog-factory.rb +91 -0
  111. data/vendor/qwik/lib/qwik/catalog-ja.rb +479 -0
  112. data/vendor/qwik/lib/qwik/catalog-ml-ja.rb +145 -0
  113. data/vendor/qwik/lib/qwik/check-act-monitor.rb +112 -0
  114. data/vendor/qwik/lib/qwik/check-act-monitor2.rb +46 -0
  115. data/vendor/qwik/lib/qwik/check-act-theme.rb +27 -0
  116. data/vendor/qwik/lib/qwik/check-event.rb +112 -0
  117. data/vendor/qwik/lib/qwik/check-event2.rb +55 -0
  118. data/vendor/qwik/lib/qwik/check-htree-rexml.rb +77 -0
  119. data/vendor/qwik/lib/qwik/check-htree.rb +51 -0
  120. data/vendor/qwik/lib/qwik/check-libxml.rb +135 -0
  121. data/vendor/qwik/lib/qwik/check-many-pages.rb +47 -0
  122. data/vendor/qwik/lib/qwik/check-monitor.rb +33 -0
  123. data/vendor/qwik/lib/qwik/check-observer.rb +67 -0
  124. data/vendor/qwik/lib/qwik/check-server.rb +61 -0
  125. data/vendor/qwik/lib/qwik/check-uuencode.rb +33 -0
  126. data/vendor/qwik/lib/qwik/check-webdav.rb +65 -0
  127. data/vendor/qwik/lib/qwik/check-xml-xpath.rb +27 -0
  128. data/vendor/qwik/lib/qwik/common-backtrace.rb +94 -0
  129. data/vendor/qwik/lib/qwik/common-basic.rb +111 -0
  130. data/vendor/qwik/lib/qwik/common-condition.rb +142 -0
  131. data/vendor/qwik/lib/qwik/common-error.rb +48 -0
  132. data/vendor/qwik/lib/qwik/common-gettext.rb +50 -0
  133. data/vendor/qwik/lib/qwik/common-javascript.rb +45 -0
  134. data/vendor/qwik/lib/qwik/common-notice.rb +132 -0
  135. data/vendor/qwik/lib/qwik/common-plain.rb +105 -0
  136. data/vendor/qwik/lib/qwik/common-plugin.rb +111 -0
  137. data/vendor/qwik/lib/qwik/common-res.rb +76 -0
  138. data/vendor/qwik/lib/qwik/common-resolve.rb +92 -0
  139. data/vendor/qwik/lib/qwik/common-send.rb +171 -0
  140. data/vendor/qwik/lib/qwik/common-session.rb +139 -0
  141. data/vendor/qwik/lib/qwik/common-surface.rb +261 -0
  142. data/vendor/qwik/lib/qwik/common-url.rb +90 -0
  143. data/vendor/qwik/lib/qwik/compat/Makefile +12 -0
  144. data/vendor/qwik/lib/qwik/compat/add_load_path.rb +1 -0
  145. data/vendor/qwik/lib/qwik/config.rb +299 -0
  146. data/vendor/qwik/lib/qwik/db-b-backup.rb +142 -0
  147. data/vendor/qwik/lib/qwik/db-backup.rb +184 -0
  148. data/vendor/qwik/lib/qwik/db-berkeley.rb +306 -0
  149. data/vendor/qwik/lib/qwik/db-filesystem.rb +305 -0
  150. data/vendor/qwik/lib/qwik/db-indexer.rb +154 -0
  151. data/vendor/qwik/lib/qwik/db-searchwords.rb +238 -0
  152. data/vendor/qwik/lib/qwik/description-ja.rb +267 -0
  153. data/vendor/qwik/lib/qwik/description.rb +256 -0
  154. data/vendor/qwik/lib/qwik/dev-add-copyright.rb +23 -0
  155. data/vendor/qwik/lib/qwik/dev-backup.rb +24 -0
  156. data/vendor/qwik/lib/qwik/dev-bench.rb +175 -0
  157. data/vendor/qwik/lib/qwik/dev-calctime.rb +52 -0
  158. data/vendor/qwik/lib/qwik/dev-css-compressor.rb +60 -0
  159. data/vendor/qwik/lib/qwik/dev-extract-catalog.rb +102 -0
  160. data/vendor/qwik/lib/qwik/dev-js-compressor.rb +73 -0
  161. data/vendor/qwik/lib/qwik/dev-release.rb +235 -0
  162. data/vendor/qwik/lib/qwik/dev-replace.rb +353 -0
  163. data/vendor/qwik/lib/qwik/dev-sendmail.rb +25 -0
  164. data/vendor/qwik/lib/qwik/farm.rb +283 -0
  165. data/vendor/qwik/lib/qwik/gettext.rb +56 -0
  166. data/vendor/qwik/lib/qwik/group-cond.rb +157 -0
  167. data/vendor/qwik/lib/qwik/group-config.rb +247 -0
  168. data/vendor/qwik/lib/qwik/group-confirm.rb +147 -0
  169. data/vendor/qwik/lib/qwik/group-db.rb +326 -0
  170. data/vendor/qwik/lib/qwik/group-mail.rb +195 -0
  171. data/vendor/qwik/lib/qwik/group-member.rb +307 -0
  172. data/vendor/qwik/lib/qwik/group-sendmail.rb +231 -0
  173. data/vendor/qwik/lib/qwik/group-site.rb +374 -0
  174. data/vendor/qwik/lib/qwik/group-sweep.rb +63 -0
  175. data/vendor/qwik/lib/qwik/group.rb +157 -0
  176. data/vendor/qwik/lib/qwik/helper.rb +6 -0
  177. data/vendor/qwik/lib/qwik/html-generator.rb +104 -0
  178. data/vendor/qwik/lib/qwik/html-to-wabisabi.rb +148 -0
  179. data/vendor/qwik/lib/qwik/htree-diff.rb +87 -0
  180. data/vendor/qwik/lib/qwik/htree-format-xml.rb +57 -0
  181. data/vendor/qwik/lib/qwik/htree-generator.rb +144 -0
  182. data/vendor/qwik/lib/qwik/htree-get.rb +251 -0
  183. data/vendor/qwik/lib/qwik/htree-html-generator.rb +179 -0
  184. data/vendor/qwik/lib/qwik/htree-template.rb +263 -0
  185. data/vendor/qwik/lib/qwik/htree-to-wabisabi.rb +171 -0
  186. data/vendor/qwik/lib/qwik/loadlib.rb +79 -0
  187. data/vendor/qwik/lib/qwik/logger.rb +115 -0
  188. data/vendor/qwik/lib/qwik/mail-body.rb +171 -0
  189. data/vendor/qwik/lib/qwik/mail-header.rb +474 -0
  190. data/vendor/qwik/lib/qwik/mail-multipart.rb +193 -0
  191. data/vendor/qwik/lib/qwik/mail-parse.rb +147 -0
  192. data/vendor/qwik/lib/qwik/mail.rb +341 -0
  193. data/vendor/qwik/lib/qwik/mailaddress.rb +83 -0
  194. data/vendor/qwik/lib/qwik/mdlb-model.rb +81 -0
  195. data/vendor/qwik/lib/qwik/mdlb-sample.rb +324 -0
  196. data/vendor/qwik/lib/qwik/ml-catalog-factory.rb +27 -0
  197. data/vendor/qwik/lib/qwik/ml-exception.rb +15 -0
  198. data/vendor/qwik/lib/qwik/ml-generator.rb +28 -0
  199. data/vendor/qwik/lib/qwik/ml-gettext.rb +137 -0
  200. data/vendor/qwik/lib/qwik/ml-logger.rb +82 -0
  201. data/vendor/qwik/lib/qwik/ml-memory.rb +65 -0
  202. data/vendor/qwik/lib/qwik/ml-msg-validator.rb +86 -0
  203. data/vendor/qwik/lib/qwik/ml-processor.rb +609 -0
  204. data/vendor/qwik/lib/qwik/ml-quickml-server.rb +122 -0
  205. data/vendor/qwik/lib/qwik/ml-sendmail.rb +0 -0
  206. data/vendor/qwik/lib/qwik/ml-server.rb +107 -0
  207. data/vendor/qwik/lib/qwik/ml-session.rb +348 -0
  208. data/vendor/qwik/lib/qwik/ml-sweeper.rb +101 -0
  209. data/vendor/qwik/lib/qwik/mock-logger.rb +65 -0
  210. data/vendor/qwik/lib/qwik/mock-sendmail.rb +78 -0
  211. data/vendor/qwik/lib/qwik/mock-socket.rb +82 -0
  212. data/vendor/qwik/lib/qwik/modulobe.rb +406 -0
  213. data/vendor/qwik/lib/qwik/mongrel-server.rb +72 -0
  214. data/vendor/qwik/lib/qwik/page-files.rb +249 -0
  215. data/vendor/qwik/lib/qwik/page-generate.rb +82 -0
  216. data/vendor/qwik/lib/qwik/page-get.rb +262 -0
  217. data/vendor/qwik/lib/qwik/page-images.rb +168 -0
  218. data/vendor/qwik/lib/qwik/page-put.rb +128 -0
  219. data/vendor/qwik/lib/qwik/page-rrefs.rb +154 -0
  220. data/vendor/qwik/lib/qwik/page-title.rb +0 -0
  221. data/vendor/qwik/lib/qwik/page-wikidb.rb +234 -0
  222. data/vendor/qwik/lib/qwik/page.rb +67 -0
  223. data/vendor/qwik/lib/qwik/pages.rb +444 -0
  224. data/vendor/qwik/lib/qwik/parse-plugin.rb +249 -0
  225. data/vendor/qwik/lib/qwik/parser-emode.rb +116 -0
  226. data/vendor/qwik/lib/qwik/parser-inline.rb +272 -0
  227. data/vendor/qwik/lib/qwik/parser.rb +349 -0
  228. data/vendor/qwik/lib/qwik/password.rb +183 -0
  229. data/vendor/qwik/lib/qwik/periodic.rb +79 -0
  230. data/vendor/qwik/lib/qwik/qp.rb +56 -0
  231. data/vendor/qwik/lib/qwik/qwik-service.rb +341 -0
  232. data/vendor/qwik/lib/qwik/qwik.rb +5 -0
  233. data/vendor/qwik/lib/qwik/qwikweb-adduser.rb +34 -0
  234. data/vendor/qwik/lib/qwik/qwikweb-catalog-validator.rb +110 -0
  235. data/vendor/qwik/lib/qwik/qwikweb-incgen.rb +28 -0
  236. data/vendor/qwik/lib/qwik/qwikweb-makesite.rb +41 -0
  237. data/vendor/qwik/lib/qwik/qwikweb-server.rb +44 -0
  238. data/vendor/qwik/lib/qwik/qwikweb-showpassword.rb +26 -0
  239. data/vendor/qwik/lib/qwik/qwikweb-watchlog.rb +67 -0
  240. data/vendor/qwik/lib/qwik/request-path.rb +304 -0
  241. data/vendor/qwik/lib/qwik/request-ua.rb +76 -0
  242. data/vendor/qwik/lib/qwik/request-webrick.rb +81 -0
  243. data/vendor/qwik/lib/qwik/request.rb +91 -0
  244. data/vendor/qwik/lib/qwik/resolve-tdiary.rb +292 -0
  245. data/vendor/qwik/lib/qwik/resolve.rb +121 -0
  246. data/vendor/qwik/lib/qwik/response.rb +228 -0
  247. data/vendor/qwik/lib/qwik/server-memory.rb +57 -0
  248. data/vendor/qwik/lib/qwik/server-webrick.rb +102 -0
  249. data/vendor/qwik/lib/qwik/server.rb +252 -0
  250. data/vendor/qwik/lib/qwik/site-config.rb +149 -0
  251. data/vendor/qwik/lib/qwik/site-db.rb +136 -0
  252. data/vendor/qwik/lib/qwik/site-event.rb +162 -0
  253. data/vendor/qwik/lib/qwik/site-files.rb +86 -0
  254. data/vendor/qwik/lib/qwik/site-group.rb +103 -0
  255. data/vendor/qwik/lib/qwik/site-index.rb +47 -0
  256. data/vendor/qwik/lib/qwik/site-log.rb +64 -0
  257. data/vendor/qwik/lib/qwik/site-member.rb +230 -0
  258. data/vendor/qwik/lib/qwik/site-monitor.rb +97 -0
  259. data/vendor/qwik/lib/qwik/site-pages.rb +62 -0
  260. data/vendor/qwik/lib/qwik/site-plan.rb +139 -0
  261. data/vendor/qwik/lib/qwik/site-report.rb +282 -0
  262. data/vendor/qwik/lib/qwik/site-resolve.rb +230 -0
  263. data/vendor/qwik/lib/qwik/site-rrefs.rb +18 -0
  264. data/vendor/qwik/lib/qwik/site-search.rb +180 -0
  265. data/vendor/qwik/lib/qwik/site-timeline.rb +153 -0
  266. data/vendor/qwik/lib/qwik/site-url.rb +189 -0
  267. data/vendor/qwik/lib/qwik/site.rb +76 -0
  268. data/vendor/qwik/lib/qwik/smil-time.rb +105 -0
  269. data/vendor/qwik/lib/qwik/smtp-session.rb +331 -0
  270. data/vendor/qwik/lib/qwik/template-generator.rb +149 -0
  271. data/vendor/qwik/lib/qwik/template.rb +85 -0
  272. data/vendor/qwik/lib/qwik/test-common.rb +10 -0
  273. data/vendor/qwik/lib/qwik/test-ml-info.rb +225 -0
  274. data/vendor/qwik/lib/qwik/test-module-ml.rb +142 -0
  275. data/vendor/qwik/lib/qwik/test-module-path.rb +110 -0
  276. data/vendor/qwik/lib/qwik/test-module-public.rb +70 -0
  277. data/vendor/qwik/lib/qwik/test-module-server.rb +98 -0
  278. data/vendor/qwik/lib/qwik/test-module-session.rb +264 -0
  279. data/vendor/qwik/lib/qwik/test-module-suite.rb +91 -0
  280. data/vendor/qwik/lib/qwik/test-ms-applemail.rb +59 -0
  281. data/vendor/qwik/lib/qwik/test-ms-attach.rb +174 -0
  282. data/vendor/qwik/lib/qwik/test-ms-basic.rb +40 -0
  283. data/vendor/qwik/lib/qwik/test-ms-close.rb +35 -0
  284. data/vendor/qwik/lib/qwik/test-ms-confirm.rb +75 -0
  285. data/vendor/qwik/lib/qwik/test-ms-ignore-spam.rb +57 -0
  286. data/vendor/qwik/lib/qwik/test-ms-japanese.rb +97 -0
  287. data/vendor/qwik/lib/qwik/test-ms-jfilename.rb +82 -0
  288. data/vendor/qwik/lib/qwik/test-ms-large.rb +58 -0
  289. data/vendor/qwik/lib/qwik/test-ms-member.rb +103 -0
  290. data/vendor/qwik/lib/qwik/test-ms-multipart.rb +84 -0
  291. data/vendor/qwik/lib/qwik/test-ms-org.rb +129 -0
  292. data/vendor/qwik/lib/qwik/test-ms-plan.rb +130 -0
  293. data/vendor/qwik/lib/qwik/test-ms-post.rb +53 -0
  294. data/vendor/qwik/lib/qwik/test-ms-quopri.rb +76 -0
  295. data/vendor/qwik/lib/qwik/test-sub-quopri.rb +45 -0
  296. data/vendor/qwik/lib/qwik/test-submit-base64.rb +59 -0
  297. data/vendor/qwik/lib/qwik/test-submit-forward.rb +61 -0
  298. data/vendor/qwik/lib/qwik/test-submit-html-mail.rb +52 -0
  299. data/vendor/qwik/lib/qwik/test-submit-japanese.rb +135 -0
  300. data/vendor/qwik/lib/qwik/test-submit-jfilename.rb +144 -0
  301. data/vendor/qwik/lib/qwik/test-submit-uuencode.rb +71 -0
  302. data/vendor/qwik/lib/qwik/test-suite-all.rb +8 -0
  303. data/vendor/qwik/lib/qwik/test-suite-basic.rb +9 -0
  304. data/vendor/qwik/lib/qwik/test-suite-ml.rb +9 -0
  305. data/vendor/qwik/lib/qwik/test-typekey.rb +64 -0
  306. data/vendor/qwik/lib/qwik/testunit.rb +45 -0
  307. data/vendor/qwik/lib/qwik/tokenizer-inline.rb +288 -0
  308. data/vendor/qwik/lib/qwik/tokenizer.rb +331 -0
  309. data/vendor/qwik/lib/qwik/typekey.rb +160 -0
  310. data/vendor/qwik/lib/qwik/util-basic.rb +135 -0
  311. data/vendor/qwik/lib/qwik/util-charset.rb +331 -0
  312. data/vendor/qwik/lib/qwik/util-css.rb +56 -0
  313. data/vendor/qwik/lib/qwik/util-csv-tokenizer.rb +113 -0
  314. data/vendor/qwik/lib/qwik/util-filename.rb +112 -0
  315. data/vendor/qwik/lib/qwik/util-pathname.rb +202 -0
  316. data/vendor/qwik/lib/qwik/util-pid.rb +58 -0
  317. data/vendor/qwik/lib/qwik/util-safe.rb +67 -0
  318. data/vendor/qwik/lib/qwik/util-sendmail.rb +273 -0
  319. data/vendor/qwik/lib/qwik/util-string.rb +202 -0
  320. data/vendor/qwik/lib/qwik/util-time.rb +125 -0
  321. data/vendor/qwik/lib/qwik/util-webrick.rb +176 -0
  322. data/vendor/qwik/lib/qwik/version.rb +11 -0
  323. data/vendor/qwik/lib/qwik/wabisabi-basic.rb +163 -0
  324. data/vendor/qwik/lib/qwik/wabisabi-diff.rb +130 -0
  325. data/vendor/qwik/lib/qwik/wabisabi-format-xml.rb +310 -0
  326. data/vendor/qwik/lib/qwik/wabisabi-generator.rb +262 -0
  327. data/vendor/qwik/lib/qwik/wabisabi-index.rb +174 -0
  328. data/vendor/qwik/lib/qwik/wabisabi-table.rb +212 -0
  329. data/vendor/qwik/lib/qwik/wabisabi-template.rb +295 -0
  330. data/vendor/qwik/lib/qwik/wabisabi-to-htree.rb +111 -0
  331. data/vendor/qwik/lib/qwik/wabisabi-to-wiki.rb +690 -0
  332. data/vendor/qwik/lib/qwik/wabisabi-traverse.rb +207 -0
  333. data/vendor/qwik/lib/qwik/wabisabi-validator.rb +116 -0
  334. data/vendor/qwik/lib/qwik/wabisabi.rb +5 -0
  335. metadata +492 -0
@@ -0,0 +1,474 @@
1
+ # -*- coding: shift_jis -*-
2
+ #
3
+ # Copyright (C) 2002-2004 Satoru Takabayashi <satoru@namazu.org>
4
+ # Copyright (C) 2003-2006 Kouichirou Eto
5
+ # All rights reserved.
6
+ # This is free software with ABSOLUTELY NO WARRANTY.
7
+ #
8
+ # You can redistribute it and/or modify it under the terms of
9
+ # the GNU General Public License version 2.
10
+ #
11
+
12
+ $LOAD_PATH.unshift '..' unless $LOAD_PATH.include? '..'
13
+ require 'qwik/mail'
14
+ require 'qwik/mailaddress'
15
+ require 'qwik/mail-multipart'
16
+ require 'qwik/util-charset'
17
+
18
+ module QuickML
19
+ class Mail
20
+ # ==================== Basic header methods.
21
+ def header
22
+ return nil if ! $test # Only for test.
23
+ return @header
24
+ end
25
+
26
+ def []=(key, value)
27
+ return nil if ! $test # Only for test.
28
+ field = @header.find {|field|
29
+ key.downcase == field.first.downcase
30
+ }
31
+ if field
32
+ field[1] = value
33
+ else
34
+ @header << [key, value]
35
+ end
36
+ return nil
37
+ end
38
+
39
+ def [] (key)
40
+ field = @header.find {|field|
41
+ key.downcase == field.first.downcase
42
+ }
43
+ return '' if field.nil?
44
+ return field.last
45
+ end
46
+
47
+ # ml-session.rb:214: mail.unshift_field('Received', received_field)
48
+ def unshift_field (key, value)
49
+ # Use Array for preserving order of the header
50
+ @header.unshift([key, value])
51
+ end
52
+
53
+ # group.rb:265: mail.each_field {|key, value|
54
+ # mail-body.rb:18: self.each_field {|key, value|
55
+ def each_field
56
+ @header.each {|field|
57
+ yield(field.first, field.last)
58
+ }
59
+ end
60
+
61
+ # ==================== Get value.
62
+ def get_unified_subject(name)
63
+ return Mail.get_unified_subject(self['Subject'], name)
64
+ end
65
+
66
+ # ml-processor.rb:37: if @mail.looping?
67
+ def looping?
68
+ return ! self['X-QuickML'].empty?
69
+ end
70
+
71
+ # ==================== Address methods.
72
+ def from
73
+ address = @mail_from
74
+ address = Mail.collect_address(self['From'])[0] if ! self['From'].empty?
75
+ address = 'unknown' if address.nil? || address.empty?
76
+ address = MailAddress.normalize(address)
77
+ return address
78
+ end
79
+
80
+ def valid?
81
+ return (! @recipients.empty?) && !!@mail_from
82
+ end
83
+
84
+ def add_recipient (address)
85
+ @recipients.push(MailAddress.normalize(address))
86
+ end
87
+
88
+ def clear_recipients
89
+ @recipients = []
90
+ end
91
+
92
+ def collect_to
93
+ return Mail.collect_address(self['To']) if self['To']
94
+ return []
95
+ end
96
+
97
+ def collect_cc
98
+ return Mail.collect_address(self['Cc']) if self['Cc']
99
+ return []
100
+ end
101
+
102
+ # ==================== Class methods.
103
+ def self.collect_address (field)
104
+ address_regex =
105
+ /(("?)[-0-9a-zA-Z_.+?\/]+\2@[-0-9a-zA-Z]+\.[-0-9a-zA-Z.]+)/ #/
106
+ addresses = []
107
+ parts = Mail.remove_comment_in_field(field).split(',')
108
+ parts.each {|part|
109
+ if (/<(.*?)>/ =~ part) || (address_regex =~ part)
110
+ addresses.push(MailAddress.normalize($1))
111
+ end
112
+ }
113
+ return addresses.uniq
114
+ end
115
+
116
+ def self.get_unified_subject(s, name)
117
+ s = Mail.clean_subject(s, name)
118
+ s.sub!(/(?:Re:\s*)+/i, '')
119
+ s.sub!(/\A\s+/, '')
120
+ s.sub!(/\s+\z/, '')
121
+ s.gsub!(/\s+/, ' ') # Thanks to Mr. Atsushi SHICHI.
122
+ return s
123
+ end
124
+
125
+ def self.remove_comment_in_field (field)
126
+ field = field.tosjis
127
+ true while field.sub!(/\([^()]*?\)/, '')
128
+ return field
129
+ end
130
+
131
+ def self.get_charset(contenttype)
132
+ return $2.downcase if /charset=("?)([-\w]+)\1/ =~ contenttype
133
+ return nil
134
+ end
135
+
136
+ def self.get_content_type(contenttype)
137
+ return $1.downcase if /([-\w]+\/[-\w]+)/ =~ contenttype
138
+ return nil
139
+ end
140
+
141
+ def self.encode_field (field)
142
+ field.gsub(Regexp.new("[\x81\x40-\xef\xf7]\\S*\\s*", nil, 's')) {|x|
143
+ x.scan(Regexp.new('.{1,10}', nil, 's')).map {|y|
144
+ '=?ISO-2022-JP?B?' + y.tojis.to_a.pack('m').chomp + '?='
145
+ }.join("\n ")
146
+ }
147
+ end
148
+
149
+ def self.decode_subject(s)
150
+ s = join_lines(s) if multiline?(s)
151
+ s = SubjectDecoder.decode(s)
152
+ s.tosjis
153
+ end
154
+
155
+ def self.multiline?(s)
156
+ /\n/ =~ s
157
+ end
158
+
159
+ def self.join_lines(s)
160
+ result = s.dup
161
+ result.gsub!(/\?=\s*\n\s+=\?/, '?==?')
162
+ result.gsub!(/\n\s+/, ' ')
163
+ result.gsub!(/\n/, '')
164
+ return result
165
+ end
166
+
167
+ def self.clean_subject(s, name)
168
+ s = Mail.decode_subject(s)
169
+ s.gsub!(/(?:\[#{Regexp.quote(name)}:\d+\])/, '')
170
+ s.sub!(/(?:Re:\s*)+/i, 'Re: ')
171
+ return s
172
+ end
173
+
174
+ def self.rewrite_subject (s, name, count)
175
+ s = Mail.clean_subject(s, name)
176
+ s = "[#{name}:#{count}] " + s
177
+ return Mail.encode_field(s)
178
+ end
179
+
180
+ def self.address_of_domain? (address, domain)
181
+ re = '[.@]' + Regexp.quote(domain) + '$'
182
+ domainpat = Regexp.new(re, Regexp::IGNORECASE)
183
+ return true if domainpat =~ address
184
+ return false
185
+ end
186
+
187
+ def self.content_type(default_content_type, charset)
188
+ return default_content_type + "; charset=#{charset}" if charset
189
+ return default_content_type
190
+ end
191
+
192
+ end
193
+
194
+ class SubjectDecoder
195
+ ENCODED_WORDS = /=\?(iso-2022-jp|euc-jp|shift_jis|cp932)\?([QB])\?([^?]+)\?=/i
196
+ def self.decode(str)
197
+ str.gsub(ENCODED_WORDS) {|s|
198
+ charset = $1.downcase
199
+ encoding = $2.upcase
200
+ contents = $3
201
+ decoder = self.new(charset, encoding, contents)
202
+ decoder.decode
203
+ }
204
+ end
205
+
206
+ def initialize(charset, encoding, contents)
207
+ @charset = charset
208
+ @encoding = encoding
209
+ @contents = contents
210
+ end
211
+
212
+ def decode
213
+ return @contents if @charset.nil? and @encoding.nil?
214
+ decode_encoding!
215
+ convert_charset!
216
+ return @contents
217
+ end
218
+
219
+ def decode_encoding!
220
+ result = @contents
221
+ case @encoding
222
+ when "B"
223
+ result = @contents.unpack("m").first
224
+ when "Q"
225
+ result = @contents.unpack("M").first
226
+ result.gsub!("_", " ")
227
+ end
228
+ @contents = result
229
+ end
230
+
231
+ def convert_charset!
232
+ case @charset
233
+ when "iso-2022-jp"
234
+ @contents = @contents.jistosjis
235
+ when "euc-jp"
236
+ @contents = @contents.euctosjis
237
+ when "shift_jis", "cp932"
238
+ :do_nothing
239
+ when "utf-8"
240
+ @contents = @contents.u8tosjis
241
+ end
242
+ end
243
+
244
+ end
245
+ end
246
+
247
+ if $0 == __FILE__
248
+ require 'qwik/testunit'
249
+ $test = true
250
+ end
251
+
252
+ if defined?($test) && $test
253
+ class TestSubjectDecoder < Test::Unit::TestCase
254
+ def test_usascii_none
255
+ input = "test"
256
+ expected = "test"
257
+ actual = QuickML::SubjectDecoder.decode(input)
258
+ ok_eq(expected, actual)
259
+ end
260
+
261
+ def test_cp932_quotedprintable
262
+ input = "=?CP932?B?gqAg?="
263
+ expected = "\202\240 "
264
+ actual = QuickML::SubjectDecoder.decode(input)
265
+ ok_eq(expected, actual)
266
+ end
267
+
268
+ def test_iso2022jp_base64
269
+ input = '=?iso-2022-jp?B?GyRCJCIbKEI=?= '
270
+ expected = "\202\240 "
271
+ actual = QuickML::SubjectDecoder.decode(input)
272
+ ok_eq(expected, actual)
273
+ end
274
+
275
+ def test_1
276
+ input = "[smd:30] =?ISO-2022-JP?B?GyRCRnxLXDhsJTUlViU4JSclLyVIGyhC?="
277
+ expected = "[smd:30] 日本語サブジェクト"
278
+ actual = QuickML::SubjectDecoder.decode(input)
279
+ ok_eq(expected, actual)
280
+ end
281
+
282
+ def test_2
283
+ input = "=?ISO-2022-JP?B?UmU6IFtzbWQ6MzA=?==?ISO-2022-JP?B?XSAbJEJGfEtcOGwlNSVWJTglJyUvJUgbKEI=?="
284
+ expected = "Re: [smd:30] 日本語サブジェクト"
285
+ actual = QuickML::SubjectDecoder.decode(input)
286
+ ok_eq(expected, actual)
287
+ end
288
+
289
+ def test_3
290
+ input = "[smd:31] Re: =?ISO-2022-JP?B?GyRCRnxLXDhsJTUlViU4JSclLyVIGyhC?="
291
+ expected = "[smd:31] Re: 日本語サブジェクト"
292
+ actual = QuickML::SubjectDecoder.decode(input)
293
+ ok_eq(expected, actual)
294
+ end
295
+
296
+ def test_4
297
+ input = "[smd:32] =?CP932?Q?Re: __=93=FA=96{=8C=EA=83T=83u=83W=83F=83N=83g?="
298
+ expected = "[smd:32] Re: 日本語サブジェクト"
299
+ actual = QuickML::SubjectDecoder.decode(input)
300
+ ok_eq(expected, actual)
301
+ end
302
+
303
+ def test_5
304
+ input = "=?ISO-2022-JP?B?UmU6IFtzbWQ6MzBdIBskQkZ8S1w4bCU1JVYlOBsoQg==?==?ISO-2022-JP?B?GyRCJSclLyVIGyhC?="
305
+ expected = "Re: [smd:30] 日本語サブジェクト"
306
+ actual = QuickML::SubjectDecoder.decode(input)
307
+ ok_eq(expected, actual)
308
+ end
309
+
310
+ end
311
+
312
+ class TestMailHeader < Test::Unit::TestCase
313
+ def test_all
314
+ mail = QuickML::Mail.new
315
+
316
+ # test_header
317
+ ok_eq([], mail.header)
318
+
319
+ # test_[]=
320
+ mail['k'] = 'v'
321
+
322
+ # test_[]
323
+ ok_eq('v', mail['k'])
324
+
325
+ # test_unshift_field
326
+ mail.unshift_field('k2', 'v2')
327
+ ok_eq([['k2', 'v2'], ['k', 'v']], mail.header)
328
+
329
+ # test_each_field
330
+ mail.each_field {|k, v|
331
+ # do nothing.
332
+ }
333
+
334
+ # test_get_unified_subject
335
+ mail['Subject'] = 'Re: [t:1] s'
336
+ ok_eq('s', mail.get_unified_subject('t'))
337
+
338
+ # test_looping?
339
+ ok_eq(false, mail.looping?)
340
+ mail['X-QuickML'] = 'true'
341
+ ok_eq(true, mail.looping?)
342
+ end
343
+
344
+ def test_address
345
+ mail = QuickML::Mail.new
346
+
347
+ # test_from
348
+ ok_eq('unknown', mail.from)
349
+ mail['From'] = 'a@e.com'
350
+ ok_eq('a@e.com', mail.from)
351
+
352
+ # test_valid?
353
+ ok_eq(false, mail.valid?)
354
+
355
+ # test_add_recipient
356
+ mail.add_recipient('b@e.com')
357
+ ok_eq(false, mail.valid?)
358
+
359
+ # test_clear_recipients
360
+ mail.clear_recipients
361
+
362
+ # test_collect_to
363
+ ok_eq([], mail.collect_to)
364
+ mail['To'] = 't@e.com'
365
+ ok_eq(['t@e.com'], mail.collect_to)
366
+
367
+ # test_collect_cc
368
+ ok_eq([], mail.collect_cc)
369
+ mail['Cc'] = 'c@e.com'
370
+ ok_eq(['c@e.com'], mail.collect_cc)
371
+ end
372
+
373
+ def test_class_method
374
+ c = QuickML::Mail
375
+
376
+ # test_collect_address
377
+ ok_eq(['a@example.net'], c.collect_address('a@example.net'))
378
+
379
+ # test_get_unified_subject
380
+ ok_eq('t', c.get_unified_subject('t', 'test'))
381
+ ok_eq('t', c.get_unified_subject('Re: t', 'test'))
382
+ ok_eq('t', c.get_unified_subject(' t', 'test'))
383
+ ok_eq('t', c.get_unified_subject('t ', 'test'))
384
+ ok_eq('t t', c.get_unified_subject('t t', 'test'))
385
+ ok_eq('t t', c.get_unified_subject('t t', 'test'))
386
+ ok_eq('t t t', c.get_unified_subject('t t t', 'test'))
387
+ ok_eq('t t t', c.get_unified_subject('t t t', 'test'))
388
+ ok_eq('Test Mail', c.get_unified_subject('Re: [test:1] Test Mail', 'test'))
389
+ ok_eq('テスト', c.get_unified_subject('Re: [test:1] テスト ', 'test'))
390
+
391
+ # test_remove_comment_in_field
392
+ ok_eq('', c.remove_comment_in_field(''))
393
+ ok_eq('ac', c.remove_comment_in_field('a(b)c'))
394
+ ok_eq('ace', c.remove_comment_in_field('a(b)c(d)e'))
395
+
396
+ # test_get_charset
397
+ ok_eq(nil, c.get_charset(''))
398
+ ok_eq('ascii', c.get_charset('text/plain; charset="ascii"'))
399
+ ok_eq('iso-2022-jp', c.get_charset('text/plain; charset=ISO-2022-JP'))
400
+ ok_eq('shift_jis', c.get_charset('text/plain; charset=Shift_JIS'))
401
+
402
+ # test_get_contenttype
403
+ ok_eq(nil, c.get_content_type(''))
404
+ ok_eq('text/plain',
405
+ c.get_content_type('text/plain; charset="ascii"'))
406
+ ok_eq('multipart/mixed',
407
+ c.get_content_type("multipart/mixed; boundary='boundary'"))
408
+ ok_eq('multipart/alternative',
409
+ c.get_content_type("multipart/alternative; boundary='b'"))
410
+
411
+ # test_encode_field
412
+ ok_eq("\201@", ' ')
413
+ ok_eq("\352\242", '瑤')
414
+ ok_eq('t', c.encode_field('t'))
415
+ ok_eq('=?ISO-2022-JP?B?GyRCJCIbKEI=?=', c.encode_field('あ'))
416
+ ok_eq('=?ISO-2022-JP?B?GyRCJCIkJBsoQg==?=', c.encode_field('あい'))
417
+ ok_eq('=?ISO-2022-JP?B?GyRCJCIkJCQmJCgkKiQrJC0kLyQxJDMbKEI=?=
418
+ =?ISO-2022-JP?B?GyRCJDUkNyQ5JDskPRsoQg==?=',
419
+ c.encode_field('あいうえおかきくけこさしすせそ'))
420
+ ok_eq('[test:1] Re: =?ISO-2022-JP?B?GyRCJUYlOSVIGyhCICA=?=',
421
+ c.encode_field('[test:1] Re: テスト '))
422
+ ok_eq('[test:1] Re: =?ISO-2022-JP?B?GyRCJUYlOSVIGyhCIA==?=',
423
+ c.encode_field('[test:1] Re: テスト '))
424
+ ok_eq('[test:1] Re: =?ISO-2022-JP?B?GyRCJCIbKEI=?=',
425
+ c.encode_field('[test:1] Re: あ'))
426
+
427
+ # test_decode_subject
428
+ ok_eq('t', c.decode_subject('t'))
429
+ ok_eq('st', c.decode_subject("s\nt"))
430
+ ok_eq('s t', c.decode_subject("s\n t"))
431
+ ok_eq("\202\240 ", c.decode_subject('=?iso-2022-jp?B?GyRCJCIbKEI=?= '))
432
+ ok_eq( '[test:33] とてもとてもとてもとてもとてもとても長い長い長い長い長い長い長い長い長いとてもとてもとてもとてもとてもとても長い長い長い長い長い長い長い長い長い日本語サブジェクトのテスト',
433
+ c.decode_subject('[test:33] =?ISO-2022-JP?B?GyRCJEgkRiRiJEgkRiRiJEgkRiRiJEgbKEI=?=
434
+ =?ISO-2022-JP?B?GyRCJEYkYiRIJEYkYiRIJEYkYkQ5JCQbKEI=?=
435
+ =?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkRDkkJEQ5JCQbKEI=?=
436
+ =?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkJEgkRiRiJEgbKEI=?=
437
+ =?ISO-2022-JP?B?GyRCJEYkYiRIJEYkYiRIJEYkYiRIJEYbKEI=?=
438
+ =?ISO-2022-JP?B?GyRCJGIkSCRGJGJEOSQkRDkkJEQ5JCQbKEI=?=
439
+ =?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkRDkkJEQ5JCQbKEI=?=
440
+ =?ISO-2022-JP?B?GyRCRDkkJEZ8S1w4bCU1JVYlOCUnJS8bKEI=?=
441
+ =?ISO-2022-JP?B?GyRCJUgkTiVGJTklSBsoQg==?=
442
+ '))
443
+ ok_eq('[test:34] very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long なサブジェクトのテスト',
444
+ c.decode_subject('[test:34] very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long =?ISO-2022-JP?B?GyRCJEolNSVWJTglJyUvJUgkTiVGJTkbKEI=?=
445
+ =?ISO-2022-JP?B?GyRCJUgbKEI=?=
446
+ '))
447
+
448
+ # test_clean_subject
449
+ ok_eq('t', c.clean_subject('t', 'test'))
450
+ ok_eq(' Re: Test ', c.clean_subject('[test:1] Re: Test ', 'test'))
451
+ ok_eq('Re: テスト ', c.clean_subject('Re: [test:1] テスト ', 'test'))
452
+ ok_eq('[hoge:2] てすと ', c.clean_subject('[hoge:2] てすと ', 'test'))
453
+ ok_eq('[ttt:3] てすと ', c.clean_subject('[ttt:3] てすと ', 'test'))
454
+
455
+ # test_rewrite_subject
456
+ ok_eq('[n:2] t', c.rewrite_subject('t', 'n', '2'))
457
+ ok_eq('[test:2] [t:3] test', c.rewrite_subject('[t:3] test', 'test', '2'))
458
+ ok_eq('[test:2] Re: Test Mail',
459
+ c.rewrite_subject('Re: [test:1] Test Mail', 'test', 2))
460
+ ok_eq('[test:2] Re: =?ISO-2022-JP?B?GyRCJUYlOSVIGyhCIA==?=',
461
+ c.rewrite_subject('Re: [test:1] テスト ', 'test', 2))
462
+
463
+ # test_address_of_domain?
464
+ ok_eq(true, c.address_of_domain?('user@example.net', 'example.net'))
465
+ ok_eq(false, c.address_of_domain?('user@example.com', 'example.net'))
466
+ ok_eq(false, c.address_of_domain?('user', 'example.net'))
467
+
468
+ # test_content_type
469
+ ok_eq('text/plain', c.content_type('text/plain', nil))
470
+ ok_eq('text/plain; charset=iso-2022-jp',
471
+ c.content_type('text/plain', 'iso-2022-jp'))
472
+ end
473
+ end
474
+ end
@@ -0,0 +1,193 @@
1
+ #
2
+ # Copyright (C) 2002-2004 Satoru Takabayashi <satoru@namazu.org>
3
+ # Copyright (C) 2003-2006 Kouichirou Eto
4
+ # All rights reserved.
5
+ # This is free software with ABSOLUTELY NO WARRANTY.
6
+ #
7
+ # You can redistribute it and/or modify it under the terms of
8
+ # the GNU General Public License version 2.
9
+ #
10
+
11
+ $LOAD_PATH.unshift '..' unless $LOAD_PATH.include? '..'
12
+ require 'qwik/mail'
13
+
14
+ module QuickML
15
+ class Mail
16
+ # ==================== Multipart methods.
17
+ def multipart?
18
+ return !!boundary
19
+ end
20
+
21
+ def boundary
22
+ return Mail.boundary(self['Content-Type'])
23
+ end
24
+
25
+ def filename
26
+ return Mail.get_filename(self['Content-Disposition'])
27
+ end
28
+
29
+ def parts
30
+ return Mail.split_body(self.body, self.boundary)
31
+ end
32
+
33
+ def nuparts
34
+ boundary = self.boundary
35
+ return [self.body] if boundary.nil? || boundary.empty?
36
+ parts = @body.split(/^--#{Regexp.escape(boundary)}-*\n/)
37
+ parts.shift # Remove the first empty string.
38
+ return parts
39
+ end
40
+
41
+ def each_part(&block)
42
+ if multipart?
43
+ self.parts.each {|str|
44
+ submail = Mail.new
45
+ submail.read(str)
46
+ submail.each_part(&block) # Recursive.
47
+ }
48
+ else
49
+ yield(self)
50
+ end
51
+ end
52
+
53
+ # ==================== class method
54
+ def self.boundary(ct)
55
+ #if /^multipart\/\w+;\s*boundary=("?)(.*)\1/i =~ ct
56
+ if /^multipart\/\w+;/i =~ ct and /[\s;]boundary=("?)(.*)\1/i =~ ct
57
+ return $2
58
+ end
59
+ return nil
60
+ end
61
+
62
+ def self.split_body(body, boundary)
63
+ return [body] if boundary.nil? || boundary.empty?
64
+ parts = body.split(/^--#{Regexp.escape(boundary)}-*\n/)
65
+ parts.shift # Remove the first empty string.
66
+ parts.pop if /\A\s*\z/ =~ parts.last
67
+ return parts
68
+ end
69
+
70
+ def self.get_filename(disp)
71
+ return nil if disp.nil?
72
+ type, fdesc = disp.split(';', 2)
73
+ return nil if fdesc.nil?
74
+ fdesc = fdesc.strip
75
+ if /\Afilename=/ =~ fdesc
76
+ fdesc.sub!(/\Afilename=/, '')
77
+ fdesc.sub!(/\A\"/, '')
78
+ fdesc.sub!(/\"\z/, '')
79
+
80
+ # FIXME: It is not sure that the filename is encoded in JIS.
81
+ # FIXME: It is using nkf for decode MIME encode.
82
+ str = fdesc.set_mail_charset.to_page_charset
83
+ str = str.to_filename_charset
84
+
85
+ return str
86
+ end
87
+ return nil
88
+ end
89
+
90
+ end
91
+ end
92
+
93
+ if $0 == __FILE__
94
+ require 'qwik/testunit'
95
+ $test = true
96
+ end
97
+
98
+ if defined?($test) && $test
99
+ class TestMailMultipart < Test::Unit::TestCase
100
+ def test_class_method
101
+ c = QuickML::Mail
102
+
103
+ # test_boundary
104
+ ok_eq('b', c.boundary("multipart/mixed; boundary=\"b\""))
105
+ # ref. https://www.codeblog.org/blog/ryu/?date=20060112#p01
106
+ # Thanks to Mr. Sato.
107
+ ok_eq('b', c.boundary("multipart/signed; protocol=\"TYPE/STYPE\";
108
+ micalg=\"MICALG\"; boundary=\"b\""))
109
+
110
+ # test_split_body
111
+ ok_eq(['body'], c.split_body('body', ''))
112
+ ok_eq(["a\n", "b\n"], c.split_body('
113
+ --t
114
+ a
115
+ --t
116
+ b
117
+ ', 't'))
118
+
119
+ ok_eq(["a\n", "b\n"], c.split_body('
120
+ --t
121
+ a
122
+ --t
123
+ b
124
+ --t--
125
+ ', 't'))
126
+
127
+ ok_eq(["a\n", "b\n"], c.split_body('
128
+ --t
129
+ a
130
+ --t
131
+ b
132
+ --t--
133
+
134
+ ', 't'))
135
+
136
+ # example.
137
+ ok_eq(["a\n", "b\n"], c.split_body('
138
+ This is a multi-part message in MIME format.
139
+
140
+ ------=_NextPart_000_006A_01C5C34A.53A389F0
141
+ a
142
+ ------=_NextPart_000_006A_01C5C34A.53A389F0
143
+ b
144
+ ------=_NextPart_000_006A_01C5C34A.53A389F0--
145
+
146
+ ', '----=_NextPart_000_006A_01C5C34A.53A389F0'))
147
+
148
+ # test_get_filename
149
+ ok_eq("\e$B$\"\e(B", 'あ'.set_sourcecode_charset.to_mail_charset)
150
+ ok_eq('t', c.get_filename("Content-Disposition: attachment; filename=\"t\""))
151
+ ok_eq("\343\201\202", c.get_filename("Content-Disposition: attachment; filename=\"\e$B$\"\e(B\""))
152
+ ok_eq('sounds.zip', c.get_filename("Content-Disposition: attachment;
153
+ filename=sounds.zip"))
154
+ # $KCODE = 's'
155
+ ok_eq('17fy予算コードの指定について.doc'.set_sourcecode_charset.to_filename_charset,
156
+ c.get_filename('Content-Disposition: attachment;
157
+ filename="=?ISO-2022-JP?B?MTdmeRskQk09OzslMyE8JUkkTjtYRGokSxsoQg==?=
158
+ =?ISO-2022-JP?B?GyRCJEQkJCRGGyhCLmRvYw==?="'))
159
+ ok_eq('情報流デザイングループ.xls'.set_sourcecode_charset.to_filename_charset,
160
+ c.get_filename('Content-Disposition: attachment;
161
+ filename="=?ISO-2022-JP?B?GyRCPnBKc04uJUclNiUkJXMlMCVrITwlVxsoQg==?=
162
+ =?ISO-2022-JP?B?Lnhscw==?="'))
163
+ end
164
+
165
+ def test_all
166
+ mail = QuickML::Mail.new
167
+
168
+ # test_plain
169
+ mail.body = 'body'
170
+ ok_eq(['body'], mail.parts) # test_parts
171
+ ok_eq(false, mail.multipart?) # test_multipart?
172
+
173
+ # test_multi_part
174
+ mail['Content-Type'] = "multipart/mixed; boundary=\"b\""
175
+ ok_eq(true, mail.multipart?) # test_multipart?
176
+ ok_eq('b', mail.boundary) # test_boundary
177
+ ok_eq([], mail.parts) # test_parts
178
+
179
+ mail.body = '--b
180
+ 1
181
+ --b
182
+ 2
183
+ --b-
184
+ '
185
+ ok_eq(["1\n", "2\n"], mail.parts) # test_parts
186
+
187
+ # test_each_part
188
+ mail.each_part {|mail|
189
+ assert_match(/\A\d\n\z/, mail.bare)
190
+ }
191
+ end
192
+ end
193
+ end