clwiki 2.4.0 → 3.0.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.
- checksums.yaml +4 -4
- data/Rakefile +19 -9
- data/app/controllers/cl_wiki/application_controller.rb +29 -1
- data/app/controllers/cl_wiki/page_controller.rb +52 -38
- data/app/controllers/cl_wiki/sessions_controller.rb +30 -0
- data/app/helpers/cl_wiki/application_helper.rb +3 -1
- data/app/models/cl_wiki/user.rb +89 -0
- data/app/views/cl_wiki/page/edit.html.erb +5 -1
- data/app/views/cl_wiki/page/recent.html.erb +1 -1
- data/app/views/cl_wiki/page/recent.rss.builder +10 -8
- data/app/views/cl_wiki/sessions/new.html.erb +10 -0
- data/config/clwiki.yml +16 -30
- data/config/initializers/clwiki.rb +4 -3
- data/config/routes.rb +9 -0
- data/lib/cl_wiki.rb +5 -1
- data/lib/cl_wiki/configuration.rb +28 -137
- data/lib/cl_wiki/engine.rb +3 -1
- data/lib/cl_wiki/file.rb +140 -117
- data/lib/cl_wiki/format/format.blockquote.rb +8 -6
- data/lib/cl_wiki/format/format.graphviz.digraph.rb +8 -7
- data/lib/cl_wiki/format/format.opml.rb +11 -9
- data/lib/cl_wiki/format/format.pre.blockquote.rb +8 -6
- data/lib/cl_wiki/format/format.simpletable.rb +10 -8
- data/lib/cl_wiki/memory_index.rb +102 -0
- data/lib/cl_wiki/page.rb +129 -257
- data/lib/cl_wiki/public_user.rb +9 -0
- data/lib/cl_wiki/user_base.rb +25 -0
- data/lib/cl_wiki/version.rb +3 -1
- data/lib/cl_wiki_lib.rb +9 -0
- data/lib/tasks/index.rake +4 -4
- data/test/dummy/app/assets/config/manifest.js +3 -0
- data/test/dummy/config/application.rb +1 -0
- data/test/dummy/config/environments/development.rb +2 -0
- data/test/dummy/config/initializers/clwiki.rb +3 -0
- data/test/dummy/config/routes.rb +3 -0
- data/test/dummy/log/development.log +5909 -0
- data/test/dummy/log/test.log +33349 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/-8/-8X-3n5w3EAS5uiBS2GQxjMlqD43Qout1GsSJUU6e4k.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/-P/-Pa1BPD1Ps1OvnKPyrGE4MiUEnlzMEccXN8CzzxSRjM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/0k/0ktSefuSiZXp-1v5uXwST57lRoAF2HvHzclO4Gtftgo.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/1V/1VmPI9-8O9Y8OP-JxSXl7-yNRMZHqapeh2drmkXiRGE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/2W/2WKPDryRtGzZO6Uedw4RNjnI5M9YVH-IbFg5GvLvTTQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/3G/3GuA3P7RM10Vv7NgdH65pwfAH7gMHlJ_xBUO74i-ZjM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/3S/3SzCkB81tc9XbtFdEYxCeR3If141gvhEnHchU_C6hHs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/41/41dY2GtQJAt3CmkQn8IDa9B3clQaUT6XymanCfFZR2o.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/46/46WEPovJzlkEgsdG0aV08HiNsRkf0L8Txt1SWLi4atg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/4I/4Ir0PJhTRUd9iGlSu6n2AREP-_amedFe4-1fKwB2wvg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/5L/5LXSsjTcB5Un8FHlrhi6AOjxwgzWoXeWBhU_hi1gdcg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/67/67V_0cxwrU68Onen7N2Lb9bTd1jLulH06F9zh1VgZ0U.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/6A/6AXD3XLczHK8MPb5e10-7sLcS45ZrP7Iwgyo9xle0nU.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/6D/6D8TdXG6KyMkGDvPbv87qUCDz9_6gRZbNAohojB484w.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/7L/7LVfTxjfHpOSp2FeG-uhloqIUqIZ7uE3nT40dqhoqY8.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/7b/7bceaEE3qsyoVjeou6RR-V9w2Wgzraq0OI2erU4s9ew.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/7h/7hRfgp9EsoD33qh0aNXeyg9qdGapPlUT6FmcL8xztY4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/8c/8cq-JtJ9Zwg4F0bFdkqaGHjdB7a9JBmfDO_sczTWycI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/8h/8hO7EIQ5iOa2rL6ZlP318Lrk0unB2CfhHCI0TrUr-Oo.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/8x/8x0PXM3vatUzVGk-vKi80S7LXrGb6bE-3EzEj54VNak.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/9v/9vfh8eoLcnq3s_rolIXPs15SPTQWGxJrrjpJ3PoABek.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/9w/9w-0hdVYmxONDHQlpGn7DFzlRA3oXqpW4x3t9LBUU6M.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/B3/B385Es3x0hpGSQNWzSjiDcExPuEV9m1dUZWlEp5zGbw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/BR/BRBOvy22uVEx9Z5Aal_0BfPilVYEQl6AYXG2u8yBqBg.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/BX/BXdNycvZI2UN7cgqvk6P4MQCc1PH2bTwa9i9vP-s-jk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/CO/CO-z80mMyQGRy-BwknxOV5bI2IFbcMMNc05j7v8Nqso.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Cg/CgPqTXtSkCxEox0z95JfY89MndA2GhTTQK39fjKk6QU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Ct/CtQeoxqXfctXd_NvChnCVaJ_cCjNuXJMv3LBXhswU6A.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Dc/DcZ_YfpX7rLYFw-u7jSJCRp_z0iIyB7XKOcwm1cQexk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Ex/Exqg59Ton1SZt_QH4hMa7wUFOAuIQnCan8B9578NzIg.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/F5/F5c-QANC5X3kApAecuyiMZEme0NT_UUB6SjxKvb0ALg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Fd/FdwPBPhLtL4s8RSPhJ53YoYoFdRkNxANV_zQYw-KsVc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/GK/GKrbCoxDofzkQCmA17lE84OT6RW_6NKm7jwyZ4n2T6s.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Gh/GhVuWwPtbWpQY_Ny4MyilnH9iUqCPxTDzOonAXM4od8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Gv/GvQrSgGYXiR-rgsPHFZq1oJ5zCkDK54muqIw6KW2GyA.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Gw/Gwhhfk9vS7QWmHsW90WtAt0_Rp_7AIM-ZcHmEqLf_Rg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/H5/H5Yxi2VJxpyMb-cbgwBNua8O2zZ03Jk4ByV6yhIzAsQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/I0/I0OpFIfCc595P02GZa3LUD1uD-Payl41dWaW3oZSK7g.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/IQ/IQoDS19BmJjvixXd16O_7P6DB-GRUEZgdNJexJ88fIc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/I_/I_zDBUxxL4b2Wk9_qqVs56Abw1jGccc4FgvKwuscswQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Ig/IgcuJMmmdeYrq2F3D721tC7ficyRm92HIrLkim5DCxQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/JI/JITjXC3hXUPgOQhDYsVjhPNjtTISt0j5uz2bjfoiSHI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/KL/KL75rsyvMJSIkYkXRijxh8cs7V1wtfLPjuodISQK5vc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Kw/KwqVMeMNxvnaSP-a-H5nkYyxloW_xoqR5JhEnqJ9puQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/L1/L1KghIbeezpqVDyhAbCDc4pG11ElC5JpUl319-ZlZn8.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Lh/LhI7QMLwiVavmyvwYzdc_t_V9OATXaBO8aCB2swJFCk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Lh/LhqYyoCtzXpfZq6UOhmZuZLSaAwZRX44sHfwPvPqezc.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Lo/Lovn2yBpV04WnAQwZeM3hLL015H5syYBH2ufgIc6qCM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Lz/LznMZWa43whMHpqnPRsbUfREY3y_fiXQKaiKVEYW4fw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/MC/MC7GYdrSShtV64GB3hoINaYL3vCRZKq9KvwcwrJAdQo.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/MU/MU6iF1YPAQqpVK_kVAtiJPtbHaYpYdOcO0g5bJ9exj8.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Md/MdIg3XLcnbFsMXC-6xslVtmBvWH7Q21BSt9l5pm305o.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Mw/Mwfi5Xeky61jhIuc6ooo4439CHOyz1hS48_taMRSlKM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Ni/Ni5yuK9FFnhLe5HciROve12UIYstBdESWm0LfdcuVVs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Nz/Nz3hkLq4WlqgoHg_ChdHSXbP7fVmCWCTw0lH0jkMmDg.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/O3/O38OvSNrhXKbxauuC8GOBBnKrt2-rPaDmfyrXScgHcA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/OS/OSm-zAlxXS63lBjvzJeSWfqq5d3D9fu-_nBVFWyQ4j0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Oa/Oazc9AJ4e_67dU0aArJeCNEeWJKMIFPtAJtxTJoUKcs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/PV/PVDpEMY_ha4kHETTb3QvjOBoBUP4PMjNDNcIAgmDy2I.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Pl/PldDxSvU1o_UFPYTE0GJmUS9mHQXH88zEw5HN6GtlRE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Pu/PuU5S_LPnhAX43U1VVN3qP_sv0ph4stXSGo7I0e_jOw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/QJ/QJ6RPZNUkui_k3wTkb62zo8wczYY7q0B174GfSJjjWE.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/QX/QXCyCL-Eeb3uHm9iOvs4anspZqeFbQnNyzDfIsXgzC8.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/R1/R1F4Qf-kXTMH0fTLahalFTHtNBvgDfkOkrPyW8zeN_E.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/R1/R1__Y-gz4zkDYrXWyCf6YTkvXO0RZlrpK6ynGGVuvnM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/R2/R2Xqb6eAeUW2xTaTaTjlkyUCirkb1qfYgW2CyY80VjM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/RM/RMXouh7GkRuhy8S6jnpxFD27HRVT0LEHj9iR53ps4o4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/RV/RVmt1mCn0tykR8xyBylvh-Hvi-Am87neA2IEkYHjg-g.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Tg/TgTXCuKAEg1DI5zjHO8tGMGuQGC9BRt9vgDZj2FdSa8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/UI/UIyRfqj_T27DnyWJiZK9BdUGTIDTQ9M953ArtrYz5fM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/U_/U_F-o3fo7oUYyn0O5KBlt3jOF53X_-4UuZb-_alPZPk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/U_/U_KCsVrX_QoGJ_FpUpCNU3XMT36CThwu8_0HYj_2k4w.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/U_/U_ie5WwVJPItNZrqfbIrnZpaRokYT5klrYU92QSugd8.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Ub/Ub-oUCoAiliSW8ohVsmtsflc4nPeiBvcjzgNbPLYQRc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Ud/UdvIJcVNQ_08Vaoyx4KuRGNjazpB9-qjOtDMTud8R0Y.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Uz/UzEG5I_EszWbaSVnk497D0KfuIzsgHoPLVQd7e3mlQg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/V-/V-F9X0mrPgfTELxk9xdYnb27trOmB6nBDL973YWeOfU.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/VA/VAOOXmbiiPy1jqpQQCDVrhkByG3pdeJoZCOvVkp-XVY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/VV/VVIuIm_HUOaEdZfXt-CmFQZb3ycoiXeeI-FV7nwkr0Y.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/VX/VXHQHhwOUBuWlKPY6smpXG1xjASw927lyjUKBXBh3e0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Vn/VnMqvZo9nqGF_5tt3gNbMyoG8jJVm0K0r1fANEBjfkw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/W1/W1YuEAoPMZTXfbxg_xWV9o2RP60SAKs5bhk7teKdL2g.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/W2/W2ZyYMlYmyA7_1WcpiWhYUJa6wfPCZ5kZj_-Nuw31yM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Wg/WgwI9C5-mh_smtsTGVmH4y76T5ifM4M_hKL1fn-K8iw.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/X5/X5GHIj6tnz-w7d-60OaYcbzJczzkTBtm24BOxzoSDdo.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/X6/X6jU4SPOD_b1ks9tCApsvWRa7q8cBYCjw3gI6Dwvr34.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/X8/X88lT-cwuuj8gqiNY83uVqXFgeLcaHMc9Xh2X4Iux6k.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/XQ/XQ0aFc1cceisG4P8qUPhW8z1H3I71pMguVRRMgJ66cs.cache +5 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Xh/XhXLVYOEEwpzOBAWDdiCEpTMz7vC8wnlBHYHJkySh-0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/YB/YBJNyX7HNPq78obeHYRGnJKSVl9EtRPbcGD253-ia34.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Yu/YupDX89OAJ6u3BHBW-UJgO3nDfi7hwlpf_JHlnM8b6k.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/ZH/ZHN5sHdNMxUCl3Ese5T5_AzQbD9WHqpgBL4PBOrgXJY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/ZP/ZPRvYWthjzuQ0tqk5AdgQbeTUqhDboF8bvTtdrmg4Jo.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/ZV/ZVu2Ed9wpdsPLKStP971oLEJBwgJQHLInXIiQkIWC04.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Zb/ZbnyIl6znMAVquD2ZD5OYA9SPXmQJYWU7V8F2Hgp3Uc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Zj/ZjALwFkjfG3uebsyy_CeJp5VQMJLE03zxPxkNp-sZDA.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/_F/_Fu404i1O4mKpjPluBsq-3FZQnyQvla_6jDnH03Lpw8.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/a-/a-t90hz_PZnc6ImKhk-cIh_WBB9vi_rChKzLv4hMBqw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/a5/a5cnzGcRAu4dPakq4_DHH9GanK42Ov5O1F62oeJR4Zo.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/aJ/aJK2kxoM9CsnZpxiFvP6RoP0sxHBiix9X1P6Mhy9Dcg.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/aO/aOU10S2QEOBHcdKwGRfXqqHdYshmYD20LYiJIGMzIa0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/aZ/aZEdK7dgijyjIs26V_QbKsDgO5JxeYXiT0Sl28M0e-U.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/aq/aqBnFJWuQ-xmdUL8_asWtElNRrMr0W60LVdDqpt43L8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/b5/b5KTv2Hrf5faN7X4XahT1s8L5t-EANtcFKrMEsGm3lw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/bF/bFemYCjG73k2_Ys77S7qNyW7CYcyw4bngyc0OGneI-s.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/bG/bGdy8gJL8acOmxK8AbkYbxNuakf4LlMZ-zPBkyL0E-0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/bK/bKm8sxC3i0ycUMXr6pnD61MdwytUWfpNOJlBY6qJaWg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/dA/dA1M22RMQvVwb74tbFg-_237SferZuCI10s4R0zx8NI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/dF/dFOzXjFeRtB5bukRI9wGrh2O_GkOeBPnrJRMiv8_ZbM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/dw/dwbXKkD4yllXOeD4T7BKoGvLS26j9lxMkjMiIxfyt6E.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/eT/eTgN8O1TgsFV61pclFzCmmJ9qT7MgyGvtQrmRtJoNeg.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/eu/eu6Xg0psMCuHIWG0WjCo9wwNOlWs-Z5OH4SyGEmdTNQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/fC/fC-TBNdh4rVupPn2ObyZeIx6OSlpBSBQZfIzywI6xx0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/fR/fRIbNtGTaNqdwIDyusrUmllglSGMNnqnw7VOLvf5D_k.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/fq/fq7SFxQSEFZCuS7jQj0n-BQfbJ5mpLpmJQsd9mJVq68.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/gG/gGBN3yxvq8azMjDv3hsSw_zLUj9KLuqHPDXZK8x8pFc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/gd/gd3J0EmNeiTh2GzxcAKItmtUnUay9NG4Sm2vkiLKvmA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/gj/gjXteWe57D8FaBOQUw29N_mwHCeTQW8oLjyv8fu3wNw.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/gt/gtFeEhjHn0G9WhgiMKaNtXVgNYW9s_wBLE0VGegeAN8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/hA/hA4-M5cp310ZkSe59_BWszdgXy7mmYagSRCfelGBA9o.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/iC/iC3FCadetljjEIeMWfeqqDoMxhJi6rI20BpiVxtvgS4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/iV/iV16_jyEayI_vLgHw3HFhtJAiVOCIlzFho0Yt7a4v_Y.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/j6/j62KRIr4T81zq1Ujpg7AJRQdI0ry9HGKPt4nK6fRt1g.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/jR/jRg0Zbr59-UMtrWO5t2VWNI3GqU7XWOUsE44dX5cPyk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/jj/jj9HUpCSrLEyONEZNLLkgJ8hJmxOCLpcVJeiBa0KDsE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/jq/jqnMk9arxuef2cdSQuxj3WOQuAfGKup3H2pjO7x1DOg.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/k1/k14rvggyKI9dk-yVjn-Lk0p8qU360H_JuVG9aZ4q0OM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/kb/Kb8Z49kajAX1vyy5d4-gA8StHhQp5yOUs0wtdZ7m8Hc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/kb/kbEMkrgp2k0pezn_gFfMqA142QwoJYBKMj7cEkE-Hag.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/lD/lDpZHp5gBhRdNHdj1TwWq1_LZ_a56lxeksxqaEs2efA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/mE/mEfGHxLvdPQrcbpjLw4q_wOPirMzrR4z58KgozQ1zNY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/mM/mMZ3DR5b7kx70JtEg-ImWOa_V1jnHcWgHqNqapxIMXk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/mX/mXCT6vriuTtwLaKGnTa5hwXSrwGtAmP6pV5lmjbHaYM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/mZ/mZjIy4zRS4hbS4vWHpdKd7jeZgLatEx_nlFqv_KSCrs.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/mg/mge36-9r2gGuKcPoghbLDM72AV4gIVTl6gQDbk7hrkg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/nK/nKZaLuUqTl9pf5Nb1oVuabxd74q4oN8YTBeo6bNd-Vk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/nP/nPbHGaYfJSLZ2K3YTROe7T1RPqKoBQJwawQtZ_FN1-I.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/o9/o9KyTznHG0ZIHDI7kTg1Jp78qaga7gJqouXSKdocEjA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/oB/oBupyQ9cW436mBji6Rp7TtHE6CX_r8iq2sCBo0LNbc8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/oN/oN3TypgxDDLqcxy0Funa4RVCYXS-7qn6D56wgBiUT2Q.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/om/omGcA_eTFAFIH3RJaPOpEW3yz0074cob3hozQFLOAxk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/p0/p0WHrZZBaXbPaNj5XmQGTli4mi08Rv8DidQfwj28a6w.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/pA/pAvUFBt71eJx7E7oQbIxrEZ8YcMo9kboyGxjk73ZWrI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/pB/pBwzUQUu-GcmLiQwn6KnbbDP0ipnVHzVaeArqdpqi98.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/pC/pCePfKbmTQ6s2Tl7ki3oBput2ruhpCzpa6Vvejbb5xg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/q6/q6BYa32YJF11eGVapO4ouNl6gayPIsARgMavlzZmoi0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/qY/qY78GTTnufmP1eP2CE16x833zGfQ0F5EVCFtUTMQ7Mw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/qm/qmZZzCnL9PLIyZ0iBu6Alr69AUfHHI1fKdNRRgG04yg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/s5/s5yv3jYvjyKZJ8SMzpj94eMKEuX46lAWV1ApHF-6bsM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/sO/sOBPF_p4Te56V9vdLV0Ywn6djNbmdPSIzvgYNPnAXYc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/sv/sv0a_JAC4GSc_cK-2OUAzhFwm_K3qzSfDefwpcqOCk4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/sw/sw2EAksRkslJNoJJCTS2FPOfHWCYvsS86AxmRMPjens.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/t1/t1cv6bP9cTAIs82lyIsnXGeAwB1KNVY5_5rgUvelr04.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/tO/To1SPyNegqysLIqhSzrNQPh1VKKj19MespjJediCde4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/tO/tOPkZNrO9FRDhSlCf7VWOexxRq2CE2X4_6KjyxJkq2A.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/tR/tRoxwnX8bACHK5pW9tIi4ILY4XuYTIpueH0fGr2t0rc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/t_/t_bP70PmOB70862dwKmCTkmZuzTqCreOzNYW4Yn2n6A.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/uj/ujdE_ewC5UIxr6uw5F7YRfKKWiu8-15wzBlOjYHsnkQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/ut/ut8uBMdgxX8_wfU0l6kGew6H8TLXAj74kFnaI252F3k.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/ut/utQEOZtBKQK_bUUDeZX4Mgk00L4AOMVyq6zrKAoo1Xw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/vm/vmjBl9ZCF5hj4sG4e2nid94GcRQYmsOsu-_Q3Zlud5c.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/vz/vzBoVc4GQWi4UFp-4dBJnzrhyUuokPV8SCOxsdpOht8.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/wM/wMWxmf8BN_NAJRCyardukpfDMwts44Bz2a8doi-49Rg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/x7/x7KkTV3ibfIEysLB_ug5bfmnn2VLV_BldukPR3EoPBk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/x7/x7iSOdqAIVmVpn9ujTwJ_C7EqUgmMSri5vjjHdRIX10.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/xY/xYdD9O1JRIfpVj9Kw_b3JTUBQZLI_dcy-bf9uXEp-jg.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/xx/xxkulLgT-tkVeDC50gUXRGGMou47BUdlYOwgs0j5muY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/yn/yn_3aZZwyjcI0O6fwisZ7zvcu4Gq5bV31g3tHFxfQNg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/yq/yqwjyepbYY4ctoMOySWiOIWUYwzl_BczAmXqJ5DPvb0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/z9/z9HQmzff5j_6CFyk6eQ52nYt9cPLXsxDQY0Yep1Hz-0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/zM/zMvcc87IG1SRbqwUNtWQfHgeWr5XN36OU8vg-v3rUus.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/zn/znjQpjNzh1iUAe9DljeFghnStRvqNIr1GuOTibVcEJQ.cache +0 -0
- data/test/dummy/tmp/testrep/BazQuux.txt +5 -0
- data/test/dummy/tmp/testrep/FooBar.txt +5 -0
- data/test/dummy/tmp/testrep/NewPage.txt +5 -0
- data/test/dummy/tmp/testrep/users/testy.json +1 -0
- data/test/dummy/tmp/wikirep/FrontPage.txt +5 -0
- data/test/dummy/tmp/wikirep/users/chrismo.json +1 -0
- data/test/dummy/wikirep/EncryptedPage.txt +0 -0
- data/test/dummy/wikirep/FrontPage.txt +11 -4
- data/test/dummy/wikirep/users/chrismo.json +1 -0
- data/test/helpers/wiki_helper_test.rb +2 -0
- data/test/lib/clwiki/clwiki_test_helper.rb +19 -2
- data/test/lib/clwiki/file_owner_test.rb +58 -0
- data/test/lib/clwiki/file_test.rb +85 -56
- data/test/lib/clwiki/memory_index_test.rb +61 -0
- data/test/lib/clwiki/page_test.rb +71 -148
- data/test/lib/clwiki/test_base.rb +19 -19
- data/test/test_helper.rb +7 -5
- metadata +398 -23
- data/lib/cl_wiki/find_in_file.rb +0 -33
- data/lib/cl_wiki/index.rb +0 -458
- data/lib/cl_wiki/tools/cron.reminders.rb +0 -241
- data/lib/cl_wiki/tools/movepages.rb +0 -27
- data/lib/cl_wiki/tools/pagestomove.txt +0 -56
- data/lib/cl_wiki/tools/rublog/clWiki.rb +0 -62
- data/lib/cl_wiki/tools/rublog/readme.txt +0 -2
- data/lib/cl_wiki/tools/singlepage.rb +0 -58
- data/lib/cl_wiki/tools/test/singlepagetest.rb +0 -9
- data/lib/cl_wiki/tools/thunderbird.rb +0 -23
- data/test/lib/clwiki/find_in_file_test.rb +0 -111
- data/test/lib/clwiki/index_test.rb +0 -32
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class FormatBlockquote < ClWiki::CustomFormatter
|
2
|
-
def
|
3
|
-
|
4
|
+
def self.match_re
|
5
|
+
%r{\[\].*\[/\]}m
|
4
6
|
end
|
5
|
-
|
6
|
-
def
|
7
|
+
|
8
|
+
def self.format_content(content, page)
|
7
9
|
if content
|
8
|
-
content.gsub!(/\[\]/,
|
9
|
-
content.gsub!(/\
|
10
|
+
content.gsub!(/\[\]/, '<blockquote>')
|
11
|
+
content.gsub!(%r{\[/\]}, '</blockquote>')
|
10
12
|
content
|
11
13
|
end
|
12
14
|
end
|
@@ -1,14 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class FormatGraphVizDiGraph < ClWiki::CustomFormatter
|
2
|
-
def
|
4
|
+
def self.match_re
|
3
5
|
/digraph.*\}/m
|
4
6
|
end
|
5
|
-
|
6
|
-
def
|
7
|
+
|
8
|
+
def self.format_content(content, page)
|
7
9
|
content.sub!(/digraph.*\}/m,
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
)
|
10
|
+
"<a href=\"dot.rb?fn=#{page.file_full_path_and_name}\">
|
11
|
+
<img src=\"dot.rb?fn=#{page.file_full_path_and_name}\">
|
12
|
+
</a>")
|
12
13
|
content
|
13
14
|
end
|
14
15
|
end
|
@@ -1,16 +1,18 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if $PROGRAM_NAME == __FILE__
|
4
|
+
$LOAD_PATH << '..'
|
3
5
|
require 'clwikipage'
|
4
6
|
end
|
5
|
-
|
7
|
+
|
6
8
|
class FormatOPML < ClWiki::CustomFormatter
|
7
|
-
def
|
8
|
-
|
9
|
+
def self.match_re
|
10
|
+
%r{<opml.*?>.*?</opml>}m
|
9
11
|
end
|
10
|
-
|
11
|
-
def
|
12
|
+
|
13
|
+
def self.format_content(content, page)
|
12
14
|
out = ['<NoWikiLinks>']
|
13
|
-
content.grep(
|
15
|
+
content.grep(%r{<outline.*?>|</outline>}).each do |ln|
|
14
16
|
title = ln.scan(/title=\"(.*?)\"/).compact
|
15
17
|
html = ln.scan(/htmlUrl=\"(.*?)\"/).compact
|
16
18
|
xml = ln.scan(/xmlUrl=\"(.*?)\"/).compact
|
@@ -31,7 +33,7 @@ end
|
|
31
33
|
|
32
34
|
ClWiki::CustomFormatters.instance.register(FormatOPML)
|
33
35
|
|
34
|
-
if
|
36
|
+
if $PROGRAM_NAME == __FILE__
|
35
37
|
sample_opml = <<-OPMLTEXT
|
36
38
|
<opml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
37
39
|
<head>
|
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'cgi'
|
2
4
|
|
3
5
|
class FormatPreBlockquote < ClWiki::CustomFormatter
|
4
|
-
def
|
5
|
-
|
6
|
+
def self.match_re
|
7
|
+
%r{\[p\].*?\[/p\]}mi
|
6
8
|
end
|
7
|
-
|
8
|
-
def
|
9
|
+
|
10
|
+
def self.format_content(content, page)
|
9
11
|
content = CGI.escapeHTML(content)
|
10
|
-
content.gsub!(/\[p\]/i,
|
11
|
-
content.gsub!(
|
12
|
+
content.gsub!(/\[p\]/i, '<blockquote><pre>')
|
13
|
+
content.gsub!(%r{\[/p\]}i, '</pre></blockquote>')
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
@@ -1,24 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class FormatSimpleTable < ClWiki::CustomFormatter
|
2
|
-
def
|
3
|
-
|
4
|
+
def self.match_re
|
5
|
+
%r{<simpletable.*?>.*?</simpletable>}m
|
4
6
|
end
|
5
|
-
|
6
|
-
def
|
7
|
+
|
8
|
+
def self.format_content(content, page = nil)
|
7
9
|
table_attr = content.scan(/<simpletable(.*?)>/m).to_s.strip
|
8
10
|
table_attr = 'border="1"' if table_attr.empty?
|
9
11
|
content.gsub!(/<simpletable.*?>/m, '')
|
10
|
-
content.gsub!(
|
12
|
+
content.gsub!(%r{</simpletable>}m, '')
|
11
13
|
content.strip!
|
12
14
|
lines = content.split("\n")
|
13
15
|
lines.collect! do |ln|
|
14
16
|
ln.gsub!(/\t/, ' ')
|
15
17
|
'<tr><td>' + ln.gsub(/ +/, '</td><td>') + '</td></tr>'
|
16
18
|
end
|
17
|
-
lines.collect!
|
19
|
+
lines.collect! { |ln| ln.gsub(%r{<td>\s*?</td>}, '<td> </td>') }
|
18
20
|
|
19
21
|
# if you do a .join("\n"), then the \n will be converted to <br>
|
20
|
-
# ... so don't do that
|
21
|
-
"<table #{table_attr}>\n
|
22
|
+
# ... so don't do that
|
23
|
+
"<table #{table_attr}>\n#{lines.join('')}</table>"
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
gem 'clindex'
|
4
|
+
require 'index'
|
5
|
+
|
6
|
+
module ClWiki
|
7
|
+
class MemoryIndexer
|
8
|
+
attr_reader :index, :pages
|
9
|
+
|
10
|
+
WAIT = true
|
11
|
+
|
12
|
+
def self.instance(page_owner: PublicUser.new)
|
13
|
+
@instance ||= self.new(page_owner: page_owner)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(page_owner: PublicUser.new)
|
17
|
+
@page_owner = page_owner
|
18
|
+
|
19
|
+
@wiki_conf = $wiki_conf
|
20
|
+
@root_dir = @wiki_conf.wiki_path
|
21
|
+
|
22
|
+
@index = ClIndex.new
|
23
|
+
@recent = ClIndex.new
|
24
|
+
@pages = ClIndex.new
|
25
|
+
|
26
|
+
build
|
27
|
+
end
|
28
|
+
|
29
|
+
def recent(top = -1, text: '')
|
30
|
+
pages_desc_mtime = @recent.do_read(WAIT) do
|
31
|
+
hash = @recent.index
|
32
|
+
hash.sort { |a, b| b[0] <=> a[0] }
|
33
|
+
end.map { |_, page_names| page_names }.flatten
|
34
|
+
|
35
|
+
if text && !text.empty?
|
36
|
+
hit_page_names = search(text)
|
37
|
+
pages_desc_mtime &= hit_page_names
|
38
|
+
end
|
39
|
+
|
40
|
+
pages_desc_mtime[0..top]
|
41
|
+
end
|
42
|
+
|
43
|
+
def search(text, titles_only: false)
|
44
|
+
terms = text.split(' ')
|
45
|
+
all_hits = []
|
46
|
+
terms.each do |term|
|
47
|
+
term_hits = []
|
48
|
+
@index.search(term, term_hits, WAIT)
|
49
|
+
term_hits.flatten!
|
50
|
+
all_hits = all_hits.empty? ? term_hits : all_hits & term_hits
|
51
|
+
end
|
52
|
+
all_hits.flatten!
|
53
|
+
all_hits.uniq!
|
54
|
+
all_hits.sort!
|
55
|
+
all_hits.delete_if { |name| name !~ /#{text}/i } if titles_only
|
56
|
+
all_hits
|
57
|
+
end
|
58
|
+
|
59
|
+
def page_exists?(full_name)
|
60
|
+
@pages.term_exists?(full_name, WAIT)
|
61
|
+
end
|
62
|
+
|
63
|
+
def reindex_page(page_name)
|
64
|
+
remove_page_from_index(page_name)
|
65
|
+
index_page(page_name)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def build
|
71
|
+
files = Dir[::File.join(@root_dir, '**/*' + ClWiki::FILE_EXT)]
|
72
|
+
files.each do |fn|
|
73
|
+
next unless ::File.file?(fn)
|
74
|
+
|
75
|
+
page_name = ::File.basename(fn, ClWiki::FILE_EXT)
|
76
|
+
index_page(page_name)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def index_page(page_name)
|
81
|
+
pg = ClWiki::Page.new(page_name, wiki_path: @root_dir, owner: @page_owner)
|
82
|
+
pg.read_raw_content
|
83
|
+
formatter = ClWiki::PageFormatter.new(pg.raw_content, page_name)
|
84
|
+
formatter.format_links { |word| @index.add(word.downcase, page_name, WAIT) }
|
85
|
+
|
86
|
+
add_to_indexes(pg)
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_to_indexes(page)
|
90
|
+
@index.add(page.page_name, page.page_name, WAIT)
|
91
|
+
@pages.add(page.page_name, nil, WAIT)
|
92
|
+
|
93
|
+
@recent.remove(page.page_name, WAIT)
|
94
|
+
@recent.add(page.mtime.strftime('%Y-%m-%dT%H:%M:%S'), page.page_name, WAIT)
|
95
|
+
end
|
96
|
+
|
97
|
+
def remove_page_from_index(page_name)
|
98
|
+
@index.remove(page_name, WAIT)
|
99
|
+
@recent.remove(page_name, WAIT)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/cl_wiki/page.rb
CHANGED
@@ -1,99 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'cgi'
|
2
4
|
require 'singleton'
|
3
5
|
|
4
|
-
require File.dirname(__FILE__) + '/file'
|
5
|
-
require File.dirname(__FILE__) + '/find_in_file'
|
6
|
-
|
7
|
-
$FIND_PAGE_NAME = "Find"
|
8
|
-
$FIND_RESULTS_NAME = "Find Results"
|
9
|
-
|
10
6
|
module ClWiki
|
11
7
|
class Page
|
12
|
-
attr_reader :content, :mtime, :name, :
|
13
|
-
:
|
14
|
-
|
15
|
-
@@wikiIndexClient = nil
|
8
|
+
attr_reader :content, :mtime, :name, :page_name, :raw_content,
|
9
|
+
:file_full_path_and_name
|
16
10
|
|
17
|
-
|
18
|
-
|
11
|
+
def initialize(page_name, wiki_path: $wiki_conf.wiki_path, owner: PublicUser.new)
|
12
|
+
raise "Fix this - no slashes! #{page_name}" if %r{/}.match?(page_name)
|
19
13
|
|
20
|
-
|
21
|
-
# ClWiki must know it, and it should be storage independent
|
22
|
-
def initialize(fullName, wiki_path=$wiki_path)
|
23
|
-
@full_name = fullName
|
14
|
+
@page_name = page_name
|
24
15
|
@wiki_path = wiki_path
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@name = @
|
16
|
+
@owner = owner
|
17
|
+
@wiki_file = ClWiki::File.new(@page_name, @wiki_path, owner: @owner)
|
18
|
+
@name = @wiki_file.name
|
28
19
|
end
|
29
20
|
|
30
|
-
# <pre> text in 1.13.2 had extra line feeds, because the \n were xformed to
|
31
|
-
# <br>\n, which results in two line feeds when rendered by Mozilla.
|
32
|
-
# The change a few versions ago inside convert_newline_to_br which started
|
33
|
-
# converting \n to <br>\n is the culprit here. I did this for more readable
|
34
|
-
# html, but that does screw up <pre> sections, so it's put back now.
|
35
21
|
def convert_newline_to_br
|
36
|
-
new_content =
|
37
|
-
|
22
|
+
new_content = ''
|
23
|
+
inside_html_tags = false
|
38
24
|
@content.each_line do |substr|
|
39
|
-
|
40
|
-
|
41
|
-
if (
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
25
|
+
inside_html_tags = true if /<html>/.match?(substr)
|
26
|
+
inside_html_tags = false if /<\/html>/.match?(substr)
|
27
|
+
new_content += if (!ClWiki::PageFormatter.only_html(substr) || (substr == "\n")) && !inside_html_tags
|
28
|
+
substr.gsub(/\n/, '<br>')
|
29
|
+
else
|
30
|
+
substr
|
31
|
+
end
|
46
32
|
end
|
47
33
|
@content = new_content
|
48
34
|
end
|
49
35
|
|
50
|
-
def
|
51
|
-
|
52
|
-
@@wikiIndexClient
|
36
|
+
def is_new?
|
37
|
+
@wiki_file.has_default_content?
|
53
38
|
end
|
54
39
|
|
55
40
|
def read_raw_content
|
56
|
-
@raw_content = @
|
41
|
+
@raw_content = @wiki_file.content
|
57
42
|
read_page_attributes
|
58
|
-
ClWiki::Page.wikiIndexClient.add_hit(@full_name) if $wiki_conf.access_log_index
|
59
|
-
end
|
60
|
-
|
61
|
-
def content_never_edited?
|
62
|
-
@wikiFile.content_is_default?
|
63
43
|
end
|
64
44
|
|
65
45
|
def delete
|
66
|
-
@
|
46
|
+
@wiki_file.delete
|
67
47
|
end
|
68
48
|
|
69
|
-
def
|
70
|
-
wiki_file =
|
71
|
-
wiki_file.
|
49
|
+
def read_page_attributes
|
50
|
+
wiki_file = @wiki_file
|
51
|
+
@mtime = wiki_file.mod_time_at_last_read
|
52
|
+
|
53
|
+
# TODO: kill this - not needed except in graphviz renderer?
|
54
|
+
@file_full_path_and_name = wiki_file.full_path_and_name
|
72
55
|
end
|
73
56
|
|
74
|
-
def
|
75
|
-
|
76
|
-
@mtime = wikiFile.modTimeAtLastRead
|
77
|
-
@fileFullPathAndName = wikiFile.fullPathAndName
|
57
|
+
def content_encrypted?
|
58
|
+
@wiki_file.content_encrypted?
|
78
59
|
end
|
79
60
|
|
80
61
|
def read_raw_content_with_forwarding(full_page_name)
|
81
62
|
stack = []
|
82
63
|
history = []
|
83
|
-
content =
|
64
|
+
content = String.new
|
84
65
|
final_page_name = full_page_name
|
85
66
|
stack.push(full_page_name)
|
86
|
-
|
67
|
+
until stack.empty?
|
87
68
|
this_pg_name = stack.pop
|
88
69
|
if history.index(this_pg_name)
|
89
70
|
pg_content = '-= CIRCULAR FORWARDING DETECTED =-'
|
90
71
|
else
|
91
|
-
pg = ClWiki::Page.new(this_pg_name)
|
72
|
+
pg = ClWiki::Page.new(this_pg_name, owner: @owner)
|
92
73
|
pg.read_raw_content
|
93
74
|
pg_content = pg.raw_content
|
94
75
|
fwd_full_page_name = get_forward_ref(pg_content)
|
95
76
|
if fwd_full_page_name
|
96
|
-
pg_content = "Auto forwarded from #{this_pg_name
|
77
|
+
pg_content = "Auto forwarded from #{this_pg_name}<br><br>#{fwd_full_page_name}<br><br>"
|
97
78
|
stack.push fwd_full_page_name
|
98
79
|
else
|
99
80
|
final_page_name = this_pg_name
|
@@ -105,24 +86,22 @@ module ClWiki
|
|
105
86
|
[content, final_page_name]
|
106
87
|
end
|
107
88
|
|
108
|
-
def read_content(include_header_and_footer=true, include_diff=false)
|
89
|
+
def read_content(include_header_and_footer = true, include_diff = false)
|
109
90
|
read_page_attributes
|
110
|
-
@content, final_page_name = read_raw_content_with_forwarding(@
|
91
|
+
@content, final_page_name = read_raw_content_with_forwarding(@page_name)
|
111
92
|
process_custom_renderers
|
112
93
|
convert_newline_to_br
|
113
94
|
f = ClWiki::PageFormatter.new(@content, final_page_name)
|
114
|
-
@content = "<div class='wikiBody'>#{f.
|
115
|
-
if include_header_and_footer
|
116
|
-
|
117
|
-
end
|
118
|
-
@content = CLabs::WikiDiffFormatter.format_diff(@wikiFile.diff) + @content if include_diff
|
95
|
+
@content = "<div class='wikiBody'>#{f.format_links}</div>"
|
96
|
+
@content = get_header + @content + get_footer if include_header_and_footer
|
97
|
+
@content = CLabs::WikiDiffFormatter.format_diff(@wiki_file.diff) + @content if include_diff
|
119
98
|
@content
|
120
99
|
end
|
121
100
|
|
122
101
|
def process_custom_renderers
|
123
102
|
root_dirs = [::File.join(::File.dirname(__FILE__), 'format')] + $wiki_conf.custom_formatter_load_path
|
124
103
|
root_dirs.each do |root_dir|
|
125
|
-
Dir[::File.join(root_dir, 'format.*')].each do |fn|
|
104
|
+
Dir[::File.join(root_dir, 'format.*')].sort.each do |fn|
|
126
105
|
require fn
|
127
106
|
end
|
128
107
|
end
|
@@ -131,91 +110,77 @@ module ClWiki
|
|
131
110
|
end
|
132
111
|
|
133
112
|
def get_header
|
134
|
-
|
135
|
-
f.header(@full_name, self)
|
113
|
+
ClWiki::PageFormatter.new(nil, @page_name).header(@page_name, self)
|
136
114
|
end
|
137
115
|
|
138
116
|
def get_footer
|
139
|
-
|
140
|
-
f.footer(self)
|
117
|
+
ClWiki::PageFormatter.new(nil, @page_name).footer(self)
|
141
118
|
end
|
142
119
|
|
143
120
|
def get_forward_ref(content)
|
144
121
|
content_ary = content.split("\n")
|
145
122
|
res = (content_ary.collect { |ln| ln.strip.empty? ? nil : ln }.compact.length == 1)
|
146
|
-
if res
|
147
|
-
res = content_ary[0] =~ /^see (.*)/i
|
148
|
-
end
|
123
|
+
res = content_ary[0] =~ /^see (.*)/i if res
|
149
124
|
|
150
125
|
if res
|
151
|
-
page_name =
|
152
|
-
f = ClWiki::PageFormatter.new(content, @
|
126
|
+
page_name = Regexp.last_match(1)
|
127
|
+
f = ClWiki::PageFormatter.new(content, @page_name)
|
153
128
|
res = f.is_wiki_name?(page_name)
|
154
|
-
if res
|
155
|
-
res = ClWiki::Page.page_exists?(page_name)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
if res
|
159
|
-
page_name
|
160
|
-
else
|
161
|
-
nil
|
129
|
+
res = ClWiki::Page.page_exists?(page_name) if res
|
162
130
|
end
|
131
|
+
page_name if res
|
163
132
|
end
|
164
133
|
|
165
|
-
def update_content(
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
wikiIndexClient = ClWiki::IndexClient.new
|
171
|
-
wikiIndexClient.reindex_page_and_save_async(@full_name)
|
172
|
-
end
|
134
|
+
def update_content(new_content, mtime, encrypt = false)
|
135
|
+
@wiki_file.client_last_read_mod_time = mtime
|
136
|
+
encrypt ? @wiki_file.encrypt_content! : @wiki_file.do_not_encrypt_content!
|
137
|
+
@wiki_file.content = new_content
|
138
|
+
ClWiki::MemoryIndexer.instance(page_owner: @owner).reindex_page(@page_name)
|
173
139
|
end
|
174
140
|
|
141
|
+
# TODO: if this is the 1st time the index is instantiated, it won't have owner.
|
142
|
+
# and this will blow up waaay down the stack as it tries to do all of the indexing
|
143
|
+
# without an owner.
|
144
|
+
#
|
145
|
+
# For this query, however, it doesn't need owner, since it's just looking for
|
146
|
+
# existence. Hmmm. The index could be lazy-loaded, with names and metadata
|
147
|
+
# first, and not content if owner doesn't match. But ... I dunno.
|
175
148
|
def self.page_exists?(page_name)
|
176
|
-
|
177
|
-
($wiki_conf.useIndexForPageExists)
|
178
|
-
res = ClWiki::Page.wikiIndexClient.page_exists?(page_name)
|
179
|
-
else
|
180
|
-
wiki_file = ClWiki::File.new(page_name, $wiki_path, $wikiPageExt, false)
|
181
|
-
res = wiki_file.file_exists?
|
182
|
-
end
|
183
|
-
res
|
149
|
+
ClWiki::MemoryIndexer.instance.page_exists?(page_name)
|
184
150
|
end
|
185
151
|
end
|
186
152
|
|
187
153
|
class PageFormatter
|
154
|
+
FIND_PAGE_NAME = 'Find'
|
155
|
+
FIND_RESULTS_NAME = 'Find Results'
|
156
|
+
|
157
|
+
attr_reader :full_name
|
188
158
|
attr_accessor :content
|
189
159
|
|
190
|
-
def initialize(content=nil,
|
160
|
+
def initialize(content = nil, full_name = nil)
|
191
161
|
@content = content
|
192
|
-
self.
|
193
|
-
@
|
162
|
+
self.full_name = full_name
|
163
|
+
@wiki_index = nil
|
194
164
|
end
|
195
165
|
|
196
|
-
def
|
166
|
+
def full_name=(value)
|
197
167
|
@full_name = value
|
198
168
|
if @full_name
|
199
169
|
@full_name = @full_name[1..-1] if @full_name[0..1] == '//'
|
200
170
|
end
|
201
171
|
end
|
202
172
|
|
203
|
-
def fullName
|
204
|
-
@full_name
|
205
|
-
end
|
206
|
-
|
207
173
|
def header(full_page_name, page = nil)
|
208
174
|
search_text = ::File.basename(full_page_name)
|
209
175
|
page_path, page_name = ::File.split(full_page_name)
|
210
176
|
page_path = '/' if page_path == '.'
|
211
177
|
dirs = page_path.split('/')
|
212
178
|
dirs = dirs[1..-1] if !dirs.empty? && dirs[0].empty?
|
213
|
-
full_dirs = (0..dirs.length-1).each { |i| full_dirs[i] = ('/' + dirs[0..i].join('/')) }
|
214
|
-
head = '<div class=\'wikiHeader\'>'
|
215
|
-
if (full_page_name
|
216
|
-
|
217
|
-
|
218
|
-
(full_page_name != $wiki_conf.stats_name)
|
179
|
+
full_dirs = (0..dirs.length - 1).each { |i| full_dirs[i] = ('/' + dirs[0..i].join('/')) }
|
180
|
+
head = String.new('<div class=\'wikiHeader\'>')
|
181
|
+
if [FIND_PAGE_NAME, FIND_RESULTS_NAME].include?(full_page_name)
|
182
|
+
head << "<span class='pageName'>#{full_page_name}</span>"
|
183
|
+
else
|
219
184
|
head << "<span class='pageName'><a href='find?search_text=#{search_text}'>#{page_name}</a></span><br/>"
|
220
185
|
full_dirs.each do |dir|
|
221
186
|
head << '<span class=\'pageTag\'>'
|
@@ -223,8 +188,6 @@ module ClWiki
|
|
223
188
|
end
|
224
189
|
head << '<br/>'
|
225
190
|
head << "<span class='wikiPageData'>#{page_update_time(page)}</span><br/>" if page
|
226
|
-
else
|
227
|
-
head << '<span class=\'pageName\'>' + full_page_name + '</span>'
|
228
191
|
end
|
229
192
|
head << '</div>'
|
230
193
|
end
|
@@ -240,7 +203,7 @@ module ClWiki
|
|
240
203
|
end
|
241
204
|
|
242
205
|
def process_custom_footers(page)
|
243
|
-
Dir[::File.dirname(__FILE__)
|
206
|
+
Dir["#{::File.dirname(__FILE__)}/footer/footer.*"].sort.each do |fn|
|
244
207
|
require fn
|
245
208
|
end
|
246
209
|
|
@@ -248,102 +211,70 @@ module ClWiki
|
|
248
211
|
end
|
249
212
|
|
250
213
|
def footer(page)
|
251
|
-
return
|
214
|
+
return String.new unless page.is_a? ClWiki::Page
|
252
215
|
|
253
216
|
custom_footer = process_custom_footers(page)
|
254
217
|
|
255
|
-
wiki_name = page.
|
218
|
+
wiki_name = page.page_name
|
256
219
|
|
257
220
|
# refactor string constants
|
258
|
-
footer = "<div class='wikiFooter'>"
|
259
|
-
footer <<
|
260
|
-
if
|
261
|
-
|
262
|
-
|
263
|
-
(wiki_name != $wiki_conf.stats_name)
|
264
|
-
if $wiki_conf.editable
|
265
|
-
footer << ("<li><span class='wikiAction'><a href='" + wiki_name.strip_slash_prefix + "/edit'>Edit</a></span></li>")
|
221
|
+
footer = String.new("<div class='wikiFooter'>")
|
222
|
+
footer << '<ul>'
|
223
|
+
if $wiki_conf.editable
|
224
|
+
unless [FIND_PAGE_NAME, FIND_RESULTS_NAME].include?(wiki_name)
|
225
|
+
footer << "<li><span class='wikiAction'><a href='#{wiki_name}/edit'>Edit</a></span></li>"
|
266
226
|
end
|
267
227
|
end
|
268
228
|
footer << "<li><span class='wikiAction'><a href='find'>Find</a></span></li>"
|
269
229
|
footer << "<li><span class='wikiAction'><a href='recent'>Recent</a></span></li>"
|
270
|
-
|
271
|
-
|
272
|
-
return custom_footer << footer
|
230
|
+
footer << '</ul></div>'
|
231
|
+
custom_footer << footer
|
273
232
|
end
|
274
233
|
|
275
234
|
def src_url
|
276
235
|
"file://#{ClWiki::Page.read_file_full_path_and_name(@full_name)}"
|
277
236
|
end
|
278
237
|
|
279
|
-
def reload_url(with_global_edit_links=false)
|
238
|
+
def reload_url(with_global_edit_links = false)
|
280
239
|
result = "#{full_url}?page=#{@full_name}"
|
281
|
-
|
282
|
-
result << "&globaledits=true"
|
283
|
-
else
|
284
|
-
result << "&globaledits=false"
|
285
|
-
end
|
240
|
+
result << (with_global_edit_links ? '&globaledits=true' : '&globaledits=false')
|
286
241
|
end
|
287
242
|
|
288
243
|
def mailto_url
|
289
244
|
"mailto:?Subject=wikifyi:%20#{@full_name}&Body=#{reload_url}"
|
290
245
|
end
|
291
246
|
|
292
|
-
def
|
293
|
-
@content.gsub(
|
294
|
-
end
|
295
|
-
|
296
|
-
def convert_relative_wikinames_to_absolute
|
297
|
-
# do not go ahead without testing here
|
298
|
-
#formatLinks do |word|
|
299
|
-
# if isWikiName?(word)
|
300
|
-
#end
|
301
|
-
|
302
|
-
# problem here is we should obey the NoWikiLinks and Html tag rules,
|
303
|
-
# and those variables aren't being yielded right now. If we change
|
304
|
-
# how the yield works, it affects the indexer. And we can't just
|
305
|
-
# tack on additional yield params and have existing code that only
|
306
|
-
# pays attention to the first keep working:
|
307
|
-
#
|
308
|
-
# irb(main):001:0> def test
|
309
|
-
# irb(main):002:1> yield 1,2,3
|
310
|
-
# irb(main):003:1> end
|
311
|
-
# nil
|
312
|
-
# irb(main):004:0> test do |a|
|
313
|
-
# irb(main):005:1* puts a
|
314
|
-
# irb(main):006:1> end
|
315
|
-
# 1
|
316
|
-
# 2
|
317
|
-
# 3
|
247
|
+
def gsub_words
|
248
|
+
@content.gsub(%r{<.+?>|</.+?>|\w+}) { |word| yield word }
|
318
249
|
end
|
319
250
|
|
320
|
-
def
|
251
|
+
def format_links
|
321
252
|
no_wiki_link_in_effect = false
|
322
253
|
inside_html_tags = false
|
323
254
|
|
324
|
-
|
325
|
-
if (word[0, 1] == '<')
|
255
|
+
gsub_words do |word|
|
256
|
+
if (word[0, 1] == '<') && (word[-1, 1] == '>')
|
326
257
|
# refactor to class,local constant, instead of global
|
327
|
-
if
|
258
|
+
if /<NoWikiLinks>/i.match?(word)
|
328
259
|
no_wiki_link_in_effect = true
|
329
260
|
word = ''
|
330
261
|
# refactor to class,local constant, instead of global
|
331
|
-
elsif
|
262
|
+
elsif /<\/NoWikiLinks>/i.match?(word)
|
332
263
|
no_wiki_link_in_effect = false
|
333
264
|
word = ''
|
334
265
|
end
|
335
266
|
|
336
|
-
if
|
267
|
+
if /<html>/i.match?(word)
|
337
268
|
inside_html_tags = true
|
338
269
|
word = ''
|
339
|
-
elsif
|
270
|
+
elsif /<\/html>/i.match?(word)
|
340
271
|
inside_html_tags = false
|
341
272
|
word = ''
|
342
273
|
end
|
343
274
|
elsif is_wiki_name?(word)
|
344
|
-
if !no_wiki_link_in_effect
|
275
|
+
if !no_wiki_link_in_effect && !inside_html_tags
|
345
276
|
# code smell here y'all
|
346
|
-
word =
|
277
|
+
word = convert_to_link(word) unless block_given?
|
347
278
|
end
|
348
279
|
end
|
349
280
|
if block_given?
|
@@ -355,9 +286,9 @@ module ClWiki
|
|
355
286
|
end
|
356
287
|
|
357
288
|
def self.only_html(str)
|
358
|
-
|
359
|
-
|
360
|
-
(str =~
|
289
|
+
only_one_tag = /\A[^<]*<[^<>]*>[^>]*\z/
|
290
|
+
header_tag_line = %r{\A\s*<h.>.*</h.>\s*\z}
|
291
|
+
(str =~ only_one_tag) || (str =~ header_tag_line)
|
361
292
|
# str.scan(/<.*>/).to_s == str.chomp
|
362
293
|
end
|
363
294
|
|
@@ -366,38 +297,30 @@ module ClWiki
|
|
366
297
|
end
|
367
298
|
|
368
299
|
def cgifn
|
369
|
-
$wiki_conf
|
300
|
+
$wiki_conf&.cgifn
|
370
301
|
end
|
371
302
|
|
372
303
|
def full_url
|
373
304
|
($wiki_conf.url_prefix + cgifn) if $wiki_conf
|
374
305
|
end
|
375
306
|
|
376
|
-
def
|
307
|
+
def convert_to_link(page_name)
|
377
308
|
if ClWiki::Page.page_exists?(page_name)
|
378
|
-
"<a href='#{page_name
|
309
|
+
"<a href='#{page_name}'>#{page_name}</a>"
|
379
310
|
else
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
result = page_name
|
394
|
-
when 1
|
395
|
-
result = "<a href='#{hits[0]}'>#{page_name}</a>"
|
396
|
-
else
|
397
|
-
result = "<a href='find?search_text=#{page_name}'>#{page_name}</a>"
|
398
|
-
end
|
399
|
-
|
400
|
-
if ($wiki_conf.editable) && ((hits.length == 0) || ($wiki_conf.global_edits))
|
311
|
+
@wiki_index ||= ClWiki::MemoryIndexer.instance
|
312
|
+
hits = @wiki_index.search(page_name, titles_only: true)
|
313
|
+
|
314
|
+
result = case hits.length
|
315
|
+
when 0
|
316
|
+
page_name
|
317
|
+
when 1
|
318
|
+
"<a href='#{hits[0]}'>#{page_name}</a>"
|
319
|
+
else
|
320
|
+
"<a href='find?search_text=#{page_name}'>#{page_name}</a>"
|
321
|
+
end
|
322
|
+
|
323
|
+
if $wiki_conf.editable && (hits.empty? || $wiki_conf.global_edits)
|
401
324
|
result << "<a href='#{page_name}/edit'>?</a>"
|
402
325
|
end
|
403
326
|
result
|
@@ -405,36 +328,12 @@ module ClWiki
|
|
405
328
|
end
|
406
329
|
|
407
330
|
def is_wiki_name?(string)
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
# if first character is a slash, then split puts an empty string into names[0]
|
412
|
-
names.delete_if { |name| name.empty? }
|
413
|
-
all_wiki_names = false if names.empty?
|
414
|
-
names.each do |name|
|
415
|
-
all_wiki_names =
|
416
|
-
(
|
417
|
-
all_wiki_names and
|
418
|
-
|
419
|
-
# the number of all capitals followed by a lowercase is greater than 1
|
420
|
-
(name.scan(/[A-Z][a-z]/).length > 1) and
|
421
|
-
|
422
|
-
# the first letter is capitalized or slash
|
423
|
-
(
|
424
|
-
(name[0, 1] == name[0, 1].capitalize) or (name[0, 1] == '/') or (name[0, 1] == "\\")
|
425
|
-
) and
|
426
|
-
|
427
|
-
# there are no non-word characters in the string (count is 0)
|
428
|
-
# ^[\w|\\|\/] is read:
|
429
|
-
# _____________[_____ _^_ ____\w_________ _| __\\______ _| ___\/________]
|
430
|
-
# characters that are not word characters or back-slash or forward-slash
|
431
|
-
# (the not negates the *whole* character set (stuff in brackets))
|
432
|
-
(name.scan(/[^\w\\\/]/).length == 0)
|
433
|
-
)
|
434
|
-
end
|
435
|
-
return all_wiki_names
|
331
|
+
return false if string.empty?
|
332
|
+
|
333
|
+
/\A[A-Z][a-z]\w*?[A-Z][a-z]\w*\z/.match?(string)
|
436
334
|
end
|
437
335
|
end
|
336
|
+
|
438
337
|
class CustomFooters
|
439
338
|
include Singleton
|
440
339
|
|
@@ -444,11 +343,11 @@ module ClWiki
|
|
444
343
|
end
|
445
344
|
|
446
345
|
def process_footers(page)
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
346
|
+
String.new.tap do |content|
|
347
|
+
@footers&.each do |f|
|
348
|
+
content << f.footer_html(page)
|
349
|
+
end
|
350
|
+
end
|
452
351
|
end
|
453
352
|
end
|
454
353
|
|
@@ -470,11 +369,11 @@ module ClWiki
|
|
470
369
|
end
|
471
370
|
|
472
371
|
def process_formatters(content, page)
|
473
|
-
@formatters
|
474
|
-
if content
|
372
|
+
@formatters&.each do |f|
|
373
|
+
if content&.match?(f.match_re)
|
475
374
|
content.gsub!(f.match_re) { |match| f.format_content(match, page) }
|
476
375
|
end
|
477
|
-
end
|
376
|
+
end
|
478
377
|
end
|
479
378
|
end
|
480
379
|
|
@@ -482,39 +381,12 @@ module ClWiki
|
|
482
381
|
# directory and imitate.
|
483
382
|
class CustomFormatter
|
484
383
|
end
|
485
|
-
|
486
|
-
class GlobalHitReducer
|
487
|
-
def GlobalHitReducer.reduce_to_exact_if_exists(term, hits)
|
488
|
-
reduced = hits.dup
|
489
|
-
reduced.delete_if do |hit|
|
490
|
-
parts = hit.split('/')
|
491
|
-
exact = (parts[-1] =~ /^#{term}$/i)
|
492
|
-
!exact
|
493
|
-
end
|
494
|
-
|
495
|
-
if !reduced.empty?
|
496
|
-
reduced
|
497
|
-
else
|
498
|
-
hits
|
499
|
-
end
|
500
|
-
end
|
501
|
-
end
|
502
384
|
end
|
503
385
|
|
504
386
|
module CLabs
|
505
387
|
class WikiDiffFormatter
|
506
|
-
def
|
388
|
+
def self.format_diff(diff)
|
507
389
|
"<b>Diff</b><br><pre>\n#{CGI.escapeHTML(diff)}\n</pre><br><hr=width\"50%\">"
|
508
390
|
end
|
509
391
|
end
|
510
392
|
end
|
511
|
-
|
512
|
-
class String
|
513
|
-
def ensure_slash_prefix
|
514
|
-
self[0..0] != '/' ? "/#{self}" : self
|
515
|
-
end
|
516
|
-
|
517
|
-
def strip_slash_prefix
|
518
|
-
self.gsub(/^\//, '')
|
519
|
-
end
|
520
|
-
end
|