clwiki 2.4.0 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +19 -9
- data/app/controllers/cl_wiki/application_controller.rb +34 -1
- data/app/controllers/cl_wiki/page_controller.rb +53 -38
- data/app/controllers/cl_wiki/sessions_controller.rb +41 -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 +136 -118
- 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 +40450 -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/0D/0DBWc4mmZE_dxtKcI5zwuwFah928eWto3S4tV-h1qUY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/0k/0ktSefuSiZXp-1v5uXwST57lRoAF2HvHzclO4Gtftgo.cache +2 -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/28/28R8437OhGS51UlWKpnAZIJ3qJWxLaA1BJtFIEjW9aw.cache +0 -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/2v/2vD9gOomeGZ1sPMc23Aqsbr95WAu7fDeShhuZuf62cY.cache +1 -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/8d/8d2c1LpTZA9uuWml5O7SZIziW2o693h9gykizTBPBqw.cache +0 -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/92/92txvq5_0oqyi4tKR-CTpu_hucsOQk4gSa_Soq_XIlc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/95/9501Slgi11UyN1aBXNCu4pxOpaRKyBcmSmiqPPJanmw.cache +0 -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/CA/CA9tJ74jTtOpYcNWZPrQLc26SkJdAu1BLuwFsWqiFX0.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/CY/CYGZRzrr6e2EOdwxmPLy_tYjneXGrr_uhTMALX2jyGY.cache +1 -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/Fz/FzgTyTGCIlSZyXn77nSzsYhiD2AFBrNiMOwNeBtmV8Y.cache +0 -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/ID/IDb8KoiLtmLZLuTayZZRFbZN0JILZeJejeUyYRRGeAA.cache +0 -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/J2/J2LffQpwOiS012wB_C4iABoBukTOT8hmHKFwpxPfYLQ.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/KY/KYIakAXVeKvIhu5WQ8kwH9RU6xpV8HJfKrBqHy00VvE.cache +1 -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/P1/P1WYRlLMdpqE0KcFDUng5g9am4POfcOwowV2amR4tZ0.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/Sb/Sb57Q81kn_46c151CSeuOFI2UarVIlevJHmB_glTpfI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Si/SiS4qKkPGbaIXzg2rpGa3SepickBkHi53MjRZreIVyw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/TF/TFylLOF6Be_hud-nZYcvvbD3NeyRKE8NUvv_JsuJ4cY.cache +0 -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/VW/VWjUCUH0gfcamZHDpILUcC_1PnGFykHGk0wh8NpIRbQ.cache +0 -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/VnE9ctuz42Ux3gd7YEwAa86NxA52PDCfU82OvtlrlX8.cache +1 -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/Ww/WwRKzl7ldAfUY6mvA4pcF6CJPsqgy9_yparRsi8cmpY.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/Wy/WyWAl1y93bbTZWLS767hNEj7IMJ8fUXatNCS-25hJXE.cache +1 -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/_E/_E-Bix511H4RJnJUAkPWvnNw4IThIvS9CEAku1gsVcg.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/a5/a5uFYzSt5Xm8ZjP5N42LcV7y94YTaEkIep8jBUeErBc.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/aq/aqNor7ePvH9sS4jPTBqDuXgPIzCEYDmzv6OL8nFaBfc.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/b5/B5yawfIgrEUdQrBwKkk65ra3p7vzQakH5rHh61IUCGQ.cache +0 -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/eO/eOhX0bq10_h3P-ISuztuJ9tqU9WI-YU21LY8uIKWjCI.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/ec/ec5x3WtYVdBZAlGgRklnM5CWLyA6JeDBJT_1HOhXF4g.cache +1 -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/fC/fCGqdV7zjLjwzE_j81Q26V2av1OhelK9ekz-obYezyM.cache +1 -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/gQ/gQzw0n2XxT1vPdv-JNlsvC4baxnQXS_my3g0GHgk2DM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/gc/gcwevUTNs8bX7r0PgMxjPfBObyrl1oUiYzRUtDwso20.cache +1 -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/hc/hcXm7DBIrn3OjXXbh6UkevkxWDcflOZ9csWRVYgjSac.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/hj/hje-P0mJOOD6UQ7CsJ7BNZBSdKcCkvwHijuCCtQDWMw.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/lL/lLUIzpNuP0NYh0_joJRWkVJ0OF9W3CyzdFBfs3818Lc.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/oW/oWo9dphQsanmdoiEL4YOq-nygJy3mBHxuB-V0YKtqKg.cache +0 -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/ot/otpWM-gZogHCGUHAd2Xu_B_U36zeJ9dAR2xKLiDheVE.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/p5/p5Qqrs_bvLEarcHNwiFMoZXaTWvShlq8KdaiIXvi7g4.cache +1 -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/pS/pSLY6X9P48cnC-drvpZwa1ubJu-hjpiaTx_7Bj45riY.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/qW/Qwu_HFjM_p33h0ukEd8eZtvuDh1Zw5x1w77CDlTopH8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/qW/qWlVTm6ozTv1T_Rvda-EsADQdVTcmfAesyZAq5Y4Ht4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/qY/QYP6D7Cl8GTs3LFfMQg5vYyDceeOpPLwxvPpYiKHzIU.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/qY/qy4PIHHAIEUKVx3kHjiN5YyIrun3jtvdSX5yXMkB2PQ.cache +0 -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/rP/rPrNeVrYtj3sM9uesyX26XheSoRwAHJAmshFxNu9Bjg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/rP/rp52ANh-KNLY9IZY1lxAbAsbbtpE0S41_F9fq3W6bq4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/s4/s4tbhiIn_CLebHU0ldR1hjB8M4TebDv0UHjWrn41K1c.cache +0 -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/sv/svHBVuxn5XQE6HEBJ4AWbdxsIDZHr5qjwrGP-UVLxk4.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/t_/t_ltg5_gjc0TqJfse-jdOUGwQu5AiK0znzxmaWt05x8.cache +0 -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/v4/V4ZL0hYAfHe81zfd7otsIeeWkSiHQ26MT8zObK74mSA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v4.0.0/v4/v4pe2JlWkzR-IW0F4Bhw4WEAwHNgeT9Df5rOmKYSwAI.cache +1 -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 +2 -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/BaaRamEwe.txt +5 -0
- data/test/dummy/tmp/testrep/BarFoo.txt +5 -0
- data/test/dummy/tmp/testrep/BazQuux.txt +5 -0
- data/test/dummy/tmp/testrep/FooBar.txt +5 -0
- data/test/dummy/tmp/testrep/NewEncryptedPage.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 +91 -56
- data/test/lib/clwiki/memory_index_test.rb +61 -0
- data/test/lib/clwiki/page_test.rb +72 -148
- data/test/lib/clwiki/test_base.rb +19 -19
- data/test/test_helper.rb +7 -5
- metadata +498 -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[0-9]*[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
|